diff --git a/Modules/ado/personal/_/_graph.ado b/Modules/ado/personal/_/_graph.ado new file mode 100644 index 0000000..a2ab97e --- /dev/null +++ b/Modules/ado/personal/_/_graph.ado @@ -0,0 +1,100 @@ +capture program drop _graph +program _graph +syntax varlist, PARTition(numlist integer >0) [SCOrename(string)] calcmethod(string) + +qui set autotabgraphs on + +local P:word count `partition' + +if "`scorename'" == "" { + local nname + forvalues i = 1/`P' { + local name "Dim`i'" + local scorename `scorename' `name' + } +} + +local i = 1 +foreach x in `varlist' { + local var`i' = "`x'" + local `++i' +} + +*capture calcscore `varlist', partition(`partition') scorename(`scorename') calcmethod(`calcmethod') + + +if "`calcmethod'" == "stand" local w = 10 +if "`calcmethod'" == "sum" local b = 10 +if "`calcmethod'" == "mean" local w = 0.5 + +set graphics off +foreach s in `scorename' { + qui hist `s', name("`s'",replace) percent fcolor(emidblue) lcolor(none) width(`w') bin(`b') +} +set graphics on + +gr combine `scorename', name("Histograms_scores",replace) + +qui biplot `scorename', name("Biplot_dimensions",replace) norow std title("") xtitle("") ytitle("") + +qui biplot `varlist', name("temp",replace) norow std nograph + +mat a = r(V) + +tempvar a1 a2 +mat colnames a = `a1' `a2' +svmat a, names(col) + +tempvar mina1 mina2 maxa1 maxa2 +egen `mina1' = min(`a1') +egen `mina2' = min(`a2') +egen `maxa1' = max(`a1') +egen `maxa2' = max(`a2') +local mina1 = `mina1' +local mina2 = `mina2' +local maxa1 = `maxa1'+1.4 +local maxa1x = `maxa1'+0.3 +local maxa2 = `maxa2' + +local colors = "red blue black green ebblue mint erose orange maroon magenta mint gray teal navy olive sienna" +local i = 1 +foreach c in `colors' { + local col`i' = "`c'" + local `++i' +} + +local i = 1 +local y = 1 +local c = 1 +local bas = `maxa2'+0.2 +local droite = max(`maxa1',0.2) + +foreach x in `partition' { + tokenize `scorename' + if `i' == 1 local s = `x' + else local s = `s' +`x' + + *local r = round(runiform()*255) + *local g = round(runiform()*255) + *local b = round(runiform()*255) + + forvalues j=`y'/`s' { + local a = `a1'[`j'] + local b = `a2'[`j'] + local call `call' || pcarrowi 0 0 `b' `a' "`var`j''", mlabcolor(`col`i'') color(`col`i'') head + } + local bas = `bas'-0.2 + *local droite = `droite' + local call `call' text(`bas' `droite' "``i''", size(3) color(`col`i'')) /*`bas' `droite' "``i''", mlabcolor("`r' `g' `b'")*/ + local `++i' + local y = `s'+1 + local `++c' +} + +qui twoway `call' name("Biplot_items",replace) legend(off) xscale(range(`mina1' `maxa1x')) yscale(range(`mina2' `maxa2')) xtitle("") ytitle("") + + +end + +*_graph x1-x40, partition(5 5 5 5 5 5 5 5) scorename(HAaaaaa PSE W BCC AC AE LI MOC) +*_graph ioc1-ioc37, partition(4 4 7 3 3 4 7 5) scorename(HA PSE W BCC AC AE LI MOC) calcmethod(stand) diff --git a/Modules/ado/personal/a/anaoption.ado b/Modules/ado/personal/a/anaoption.ado new file mode 100644 index 0000000..46e436a --- /dev/null +++ b/Modules/ado/personal/a/anaoption.ado @@ -0,0 +1,48 @@ +*! version 1 27may2007 +*! Jean-Benoit Hardouin +* +************************************************************************************************************ +* Stata program : anaoption +* +* Historic +* Version 1 (2007-05-27): Jean-Benoit Hardouin +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2007 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define anaoption ,rclas +version 7.0 +syntax [, DETails minvi(real .03) siglevel(real 0.05) minsize(real 0)] + +return scalar minvi=`minvi' +return scalar siglevel=`siglevel' +return scalar minsize=`minsize' +return local details `details' + + +end + diff --git a/Modules/ado/personal/a/anares.ado b/Modules/ado/personal/a/anares.ado new file mode 100644 index 0000000..ead6c30 --- /dev/null +++ b/Modules/ado/personal/a/anares.ado @@ -0,0 +1,36 @@ +program define raschres,rclass +syntax varlist [, resname(string)] + +tempname diff theta +matrix `diff'=r(beta) +matrix `theta'=r(theta) + +if "`resname'"=="" { + local resname=res +} + +tokenize `varlist' +local nbitems: word count `varlist' +tempname score lt +genscore `varlist',score(`score') +gen `lt'=. + +forvalues i=0/`nbitems' { + replace `lt'=`theta'[1,`i'] if `score'==`i' +} + +forvalues i=1/`nbitems'{ + tempname p`i' res`i' + gen `p`i''=exp(`lt'-`diff'[1,`i'])/(1+exp(`lt'-`diff'[1,`i']) + gen `resname'`i'=(1-`p`i'')/sqrt(`p`i''*(1-`p`i'')) +} +pca `resname'* + + + + + + + + +end \ No newline at end of file diff --git a/Modules/ado/personal/b/backrasch.ado b/Modules/ado/personal/b/backrasch.ado new file mode 100644 index 0000000..08e958b --- /dev/null +++ b/Modules/ado/personal/b/backrasch.ado @@ -0,0 +1,171 @@ +*! version 3 11june2014 +************************************************************************************************************ +* Backrasch : Backward procedure under a Rasch model +* +* Historic +* Version 1 (2004-02-13) : Jean-Benoit Hardouin +* Version 2 (2005-05-23) : Jean-Benoit Hardouin +* Version 3 (2014-06-11) : Jean-Benoit Hardouin /*id for raschtest*/ +* +* Needed modules : +* raschtestv7 version 7.2.1 (http://freeirt.free.fr) +* gammasym version 2.1 (http://freeirt.free.fr) +* gausshermite version 1 (http://freeirt.free.fr) +* geekel2d version 4.1 (http://freeirt.free.fr) +* ghquadm (findit ghquadm) +* gllamm version 2.3.10 (ssc describe gllamm) +* gllapred version 2.3.2 (ssc describe gllapred) +* elapse (ssc describe elapse) +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@orscentre.org +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2004-2005, 2014 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define backrasch , rclass +version 8.0 +syntax varlist(min=3 numeric) , [p(real 0.05) Method(string) Test(string) NBSCales(integer 1) nodetail noAUTOGroup] +local nbitems : word count `varlist' +tokenize `varlist' +preserve + + +tempfile saveraschtest +qui save `saveraschtest' + +local autogroup2 +if "`autogroup'"=="" { + local autogroup2 autogroup +} +if "`method'"=="" { + local method cml +} +if "`test'"=="" { + local test R +} + +tempname select +matrix `select'=J(1,`nbitems',0) +local dim=1 +local less3items=0 + +while `dim'<=`nbscales'&`less3items'!=1 { + di + di in green _col(25) "subscale : " in yellow `dim' + di in green _col(25) "{hline 12}" + local nobaditem=0 + while `nobaditem'!=1 { + local varlistscale + local nbitemsscale=0 + forvalues i=1/`nbitems' { + if `select'[1,`i']==0 { + local nbitemsscale=`nbitemsscale'+1 + local ssitem`nbitemsscale'=`i' + local varlistscale `varlistscale' ``i'' + } + } + + if `nbitemsscale'<3 { + if "`detail'"=="" { + di in green "The " in yellow "`dim'th " in green "sub-scale can not be created, because there is less than three items remaining" + } + local `less3items'=1 + local dim=`dim'-1 + continue, break + } + else { + tempvar tmp + capture gen `tmp'=_n + qui raschtestv7 `varlistscale',m(`method') t(`test') `autogroup2' id(`tmp') + tempname itemFit + matrix `itemFit'=r(itemFit) + local minp=`p' + local deleteitem + local nobaditem=1 + forvalues i=1/`nbitemsscale' { + if `itemFit'[`i',3]<`minp' { + local minp=`itemFit'[`i',3] + local deleitem=`i' + local rowdeleteitem=`ssitem`i'' + local nobaditem=0 + } + } + if `nobaditem'==1 { + if "`detail'"=="" { + di in green "No more item to remove of the scale " in yellow "`dim'" + } + continue, break + } + else { + if "`detail'"=="" { + di in green "The item " in yellow "``rowdeleteitem'' " in green "is removed of the scale " in yellow "`dim'" in green " (p=" in yellow %6.4f `minp' in green ")" + } + matrix `select'[1,`rowdeleteitem']=-1 + } + } + } + + if `nbitemsscale'>=3 { + forvalues i=1/`nbitems' { + if `select'[1,`i']==0 { + matrix `select'[1,`i']==`dim' + } + if `select'[1,`i']==-1 { + matrix `select'[1,`i']==0 + } + } + local scale`dim' + forvalues i=1/`nbitems' { + if `select'[1,`i']==`dim' { + local scale`dim' "`scale`dim'' ``i''" + } + } + if "`scale`dim''"!="" { + di + di in green _col(4) "Number of selected items : " in yellow "`nbitemsscale'" + tempvar tmp2 + capture gen `tmp2'=_n + raschtestv7 `scale`dim'',m(`method') t(`test') `autogroup2' id(`tmp2') + di + di _dup(70) "-" + } + + + local dim=`dim'+1 + } + if `nbitemsscale'<3{ + forvalues i=1/`nbitems' { + if `select'[1,`i']==-1 { + matrix `select'[1,`i']==0 + } + } + continue, break + } + +} + +matrix colnames `select'=`varlist' +matrix rownames `select'=scale + +return matrix selection `select' +end + diff --git a/Modules/ado/personal/b/backrasch.hlp b/Modules/ado/personal/b/backrasch.hlp new file mode 100644 index 0000000..1046692 --- /dev/null +++ b/Modules/ado/personal/b/backrasch.hlp @@ -0,0 +1,54 @@ +{smcl} +{* 23may2005}{...} +{hline} +help for {hi:backrasch} +{hline} + +{title:Backward procedure on a Rasch model} + +{p 8 14 2}{cmd:backrasch} {it:varlist} {cmd:,} [{cmdab:m:ethod}({it:keyword}) +{cmdab:t:est}({it:keyword}) {cmdab:nodetail} +{cmdab:p}({it:#.###}) {cmdab:nbsc:ales}({it:#}) +{cmdab:noautog:roup}] + +{title:Description} + +{p 4 8 2}{cmd:backward} realizes a Backward procedure on a Rasch model: the +items are removed one per one if they have a bad fit to the Rasch model. The +fit of the items is valuated by a first-order statistics (test R1c, R1m or Q1) +It is possible to build several sub-scales of items, the second sub-scale is +build with the items unselected in the first sub-scales, the third one +with the items unselected in the two first sub-scales, and so on... By default, +the parameters of the Rasch model are estimated by conditional maximum +likelihood (CML), but it is possible to estimate them by marginal maximum +likelihood (MML) or generalized estimating equations (GEE). + +{title:Options} + +{p 4 8 2}{cmd:method}({it:cml/mml/gee}) defines the method of estimation of the difficulty parameters among conditional maximum likelihood (cml - by default), marginal maximum likelihood (mml) or generalized estimating equations (gee). + +{p 4 8 2}{cmd:test}({it:R/Q}) defines the first order statistics to use between R-type test (R1c or R1m - by default) or the Q1 test of Van den Wollenberg. + +{p 4 8 2}{cmd:nodetail} does not display the description of the algorithm. + +{p 4 8 2}{cmd:p}({it:#.###}) defines the level of signification who define a significantly bad fitted item (0.05 by default). + +{p 4 8 2}{cmd:nbscales}({it:#}) defines the maximal number of sub-scales to build. By default, the program builds only one sub-scale. + +{p 4 8 2}{cmd:noautograoup} forces the program to compute the first order fit statistics with the groups defined by the value of the score. by default, the scores are grouped to obtained groups of 30 individuals or more. + +{title:Examples} + +{p 4 8 2}{cmd:. backrasch item1 item2 item3 item4} /*estimation by CML, test R1c, only one scale is built*/ + +{p 4 8 2}{cmd:. backrasch item1 item2 item3 item4 , p(0.2) method(mml) nodetail} /*estimation by MML, test R1m, only one scale*/ + +{p 4 8 2}{cmd:. backrasch item1 item2 item3 item4 , p(0.1) nbsc(5) noautog} /*CLM estimation, R1c tests, 5 scales will be build*/ + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, Regional Health Observatory (ORS) - 1, rue Porte +Madeleine - BP 2439 - 45032 Orleans Cedex 1 - France. You can contact the author at +{browse "mailto:jean-benoit.hardouin@orscentre.org":jean-benoit.hardouin@orscentre.org} +and visit the websites {browse "http://anaqol.free.fr":AnaQol} and +{browse "http://freeirt.free.fr":FreeIRT} diff --git a/Modules/ado/personal/b/biplotvlab.ado b/Modules/ado/personal/b/biplotvlab.ado new file mode 100644 index 0000000..cc09ac5 --- /dev/null +++ b/Modules/ado/personal/b/biplotvlab.ado @@ -0,0 +1,74 @@ +*! version 1.0.1 30sep2005 +*! The first version of this module has been wroten by Ken Higbee (StataCorp) +*! Improvements by Jean-Benoit Hardouin + +program biplotvlab + + version 9 + + syntax varlist(numeric min=2) [if] [in] [, LABdes(string) stretch(int 1) *] + + // run biplot quietly (and nograph) so we can get r(V) + qui biplot `varlist' `if' `in' , `options' nograph + tempname V + mat `V' = r(V) + local nbvar:word count `varlist' + tokenize `varlist' + + // build the -text()- option + local topt "text(" + local i 0 + local miny=`V'[1,2] + local maxy=`V'[1,2] + local minx=`V'[1,1] + local maxx=`V'[1,1] + forvalues i=1/`nbvar' { + local miny=min(`V'[`i',2],`miny') + local maxy=max(`V'[`i',2],`maxy') + local minx=min(`V'[`i',1],`minx') + local maxx=max(`V'[`i',1],`maxx') + } + if `maxx'*`minx'>0 { + local coefx=max(abs(`maxx'),abs(`minx')) + local coefx=`coefx'/20 + } + else { + local coefx=abs(`maxx'-`minx')/20 + } + if `maxx'*`minx'>0 { + local coefy=max(abs(`maxy'),abs(`miny')) + local coefy=`coefy'/20 + } + else { + local coefy=abs(`maxy'-`miny')/20 + } + forvalues i=1/`nbvar' { + // y value + if `V'[`i',2]>0 { + local topt `"`topt' `= (`V'[`i',2]+`coefy')*`stretch''"' + } + else { + local topt `"`topt' `= (`V'[`i',2]-`coefy')*`stretch''"' + } + // x value + if `V'[`i',1]<0 { + local topt `"`topt' `= (`V'[`i',1]-`coefx')*`stretch''"' + } + else { + local topt `"`topt' `= (`V'[`i',1]+`coefx')*`stretch''"' + } + // variable label + local lab: var label ``i'' + if "`lab'"=="" { + local lab ``i'' + } + local topt `"`topt' `"`lab'"' "' + } + if "`labdes'"=="" { + local labdes size(vsmall) + } + local topt `"`topt',`labdes')"' + + // call with -colopts(nolabel)- and -text()- just built + biplot `varlist' `if' `in', `options' colopts(nolabel) `topt' stretch(`stretch') +end diff --git a/Modules/ado/personal/b/biplotvlab.hlp b/Modules/ado/personal/b/biplotvlab.hlp new file mode 100644 index 0000000..5eef3de --- /dev/null +++ b/Modules/ado/personal/b/biplotvlab.hlp @@ -0,0 +1,38 @@ +{smcl} +{* 30sept2005}{...} +{hline} +help for {hi:biplotvlab}{right:Jean-benoit Hardouin} +{hline} + +{title:Biplot with variable labels} + +{p 8 14 2}{cmd:biplotvlab} {it:varlist} [{cmd:,} {cmdab:lab:des}({help textbox_options}) {help biplot:biplot_options}) + +{title:Description} + +{p 4 8 2}{cmd:biplotvlab} allows displaying on a biplot graph the labels of the +variables instead of the names of the variables. If none label is defined for one +or several variables, the names of these variables are displayed instead. +{cmd:biplotvlab} replaces the official {cmd:biplot} command. + +{title:Options} + +{p 4 8 2}{cmd:labdes} defines the options to apply to the labels (color, size...). + +{title:Examples} + +{p 4 8 2}{cmd:. biplotvlab turn trunk mpg,norow} + +{p 4 8 2}{cmd:. biplotvlab turn trunk mpg,labdes(size(vsmall) color(blue))} + +{p 4 8 2}{cmd:. biplotvlab turn trunk mpg, stretch(12)} + +{title:Authors} + +{p 4 8 2}Ken Higbee (StataCorp) has wroten the first version of this module. + +{p 4 8 2}Improvements by Jean-Benoit Hardouin, Regional Health Observatory (ORS) - 1, rue Porte +Madeleine - BP 2439 - 45032 Orleans Cedex 1 - France. You can contact the author at +{browse "mailto:jean-benoit.hardouin@orscentre.org":jean-benoit.hardouin@orscentre.org} +and visit the websites {browse "http://anaqol.free.fr":AnaQol} and +{browse "http://freeirt.free.fr":FreeIRT} diff --git a/Modules/ado/personal/bidon b/Modules/ado/personal/bidon new file mode 160000 index 0000000..bdcabcb --- /dev/null +++ b/Modules/ado/personal/bidon @@ -0,0 +1 @@ +Subproject commit bdcabcbde5043d31555d7d58758441d90f92f235 diff --git a/Modules/ado/personal/c/calcscore.ado b/Modules/ado/personal/c/calcscore.ado new file mode 100644 index 0000000..c43587c --- /dev/null +++ b/Modules/ado/personal/c/calcscore.ado @@ -0,0 +1,155 @@ +capture program drop calcscore +program calcscore,rclass +syntax varlist, PARTition(numlist integer >0) [CALCmethod(string) SCOrename(string)] + +local y = 1 + +*di "{bf:Calculs des scores}" + +local C = 0 +foreach z in `partition' { + local C = `C' + `z' +} + +local nbvars : word count `varlist' +if `C' != `nbvars' { + di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist" + exit +} + +if "`scorename'" != "" { + local P:word count `partition' + local S:word count `scorename' + if `P'!=`S' { + di in red "The number of score names given is different from the number of dimensions in the partition option" + exit 119 + } + foreach sco in `scorename' { + capture confirm variable `sco' + if !_rc { + di in red "`sco' is a variable of the dataset. Choose another name" + exit 119 + } + } +} + +/* +local cpt = 0 +if "`sum'" != "" { + local cpt `cpt' + 1 +} +if "`mean'" != "" { + local cpt `cpt' + 1 +} +if "`stand'" != "" { + local cpt `cpt' + 1 +} +if `cpt'>1 { + di in red "You must choose between mean, sum or stand (the options are exclusive)" + exit 119 +} +*/ + +local i = 1 +foreach x in `partition' { + tokenize `varlist' + if `i' == 1 local s = `x' + else local s = `s' +`x' + + local liste = "" + forvalues w = `y'/`s' { + local liste `liste' ``w'' + } + + tempvar nonmiss + qui egen `nonmiss' = rownonmiss(`liste') + + if "`scorename'" != "" { + tokenize `scorename' + local sc = "``i''" + } + else local sc = "Dim`i'" + +/* if "`calc_method'" == "" { + local calc_method = "mean" + } + + if "`calc_method'" != "sum" & "`calc_method'" != "mean" { + di in red "The calc_method option is invalid. Choose mean or sum." + exit 119 + } + + if "`calc_method'" == "sum" { + qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2 + if "`calc_stand'" != "" { + local maxs = 0 + foreach var in `liste' { + qui levelsof `var', local(levels) + local max = 0 + foreach l in `levels' { + if `l'>`max' local max = `l' + } + local maxs = `maxs' + `max' + } + di "`sc' : `maxs'" + qui replace `sc' = `sc'*`nonmiss'*100/`maxs' + } + else qui replace `sc' = `sc'*`nonmiss' + } + else if "`calc_method'" == "mean" { + qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2 + } +*/ + if "`calcmethod'" == "" local calcmethod = "mean" + + if "`calcmethod'" != "mean" & "`calcmethod'" != "sum" & "`calcmethod'" != "stand" { + di in red "option calcmethod incorrectly specified (choose among mean, sum and stand)" + error 198 + } + + if "`calcmethod'" == "sum" { + qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2 + qui replace `sc' = `sc'*`nonmiss' + } + + else if "`calcmethod'" == "stand" { + + qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2 + qui replace `sc' = `sc'*`nonmiss' + + tempvar min max + egen `min' = min(`sc') + egen `max' = max(`sc') + + + /* + foreach var in `liste' { + /*qui levelsof `var', local(levels) + local max = 0 + foreach l in `levels' { + if `l'>`max' local max = `l' + } + local maxs = `maxs' + `max'*/ + + local max = max(`levels') + } + + */ + *di "max : "`max' + *di "min : "`min' + + qui replace `sc' = (`sc'-`min')/(`max'-`min')*100 + } + + else { + qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2 + } + +local `i++' +local y = `s'+1 +} +end + +*calcscore ioc1-ioc37, partition(4 4 7 3 3 4 7 5) scorename(HA PSE W BCC AC AE LI MOC) calcmethod(stand) +*calcscore x1-x40, partition(5 5 5 5 5 5 5 5) calcmethod(stand) +*calcscore sf36_3q_intenses sf36_3q_moderees sf36_3q_soulever sf36_3q_etages sf36_3q_etage sf36_3q_pencher sf36_3q_15km sf36_3q_500m sf36_3q_100m sf36_3q_douche sf36_4q_limite_temps_travail sf36_4q_moins_choses sf36_4q_type_travail sf36_4q_effort sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques sf36_1q sf36_11q_malade sf36_11q_porte_bien sf36_11q_degrade sf36_11q_excellente_sante sf36_9q_enthousiaste sf36_9q_energie sf36_9q_epuise sf36_9q_fatigue sf36_6q_vie_sociale sf36_10q_etat_mental sf36_5q_limite_temps_travail sf36_5q_moins_choses sf36_5q_accomplies_soigneusement sf36_9q_nerveux sf36_9q_triste sf36_9q_calme sf36_9q_maussade sf36_9q_heureux, partition(10 4 2 5 4 2 3 5) scorename(PF RP BP GH VT SF RE MH) calcmethod(mean) diff --git a/Modules/ado/personal/c/calcul.ado b/Modules/ado/personal/c/calcul.ado new file mode 100644 index 0000000..a1e15eb --- /dev/null +++ b/Modules/ado/personal/c/calcul.ado @@ -0,0 +1,395 @@ +*program drop calcul +program define calcul +syntax, s10(numlist) + +matrix define deces=J(140,6,0) +local j=0 +tcm, s10(`s10') anneepop(1989) annees(1988/1990) sexe(1) +matrix essai=r(donnees) +local TCMH89=r(TCM) +matrix deces[1,1]=essai[2..19,4] +matrix deces[25,1]=`TCMH89' +tcm, s10(`s10') anneepop(1989) annees(1988/1990) sexe(2) +matrix essai=r(donnees) +local TCMF89=r(TCM) +matrix deces[1,2]=essai[2..19,4] +matrix deces[25,2]=`TCMF89' +tcm, s10(`s10') anneepop(1982) annees(1981/1983) sexe(1) +matrix essai=r(donnees) +local TCMH82=r(TCM) +matrix deces[1,3]=essai[2..19,4] +matrix deces[20,1]=`TCMH82' +tcm, s10(`s10') anneepop(1982) annees(1981/1983) sexe(2) +matrix essai=r(donnees) +local TCMF82=r(TCM) +matrix deces[1,4]=essai[2..19,4] +matrix deces[20,2]=`TCMF82' + + + +tcm, s10(`s10') anneepop(1983) annees(1982/1984) sexe(1) +matrix essai=r(donnees) +local TCMH=r(TCM) +matrix deces[21,1]=`TCMH' +tcm, s10(`s10') anneepop(1983) annees(1982/1984) sexe(2) +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[21,2]=`TCMF' + +tcm, s10(`s10') anneepop(1984) annees(1983/1985) sexe(1) +matrix essai=r(donnees) +local TCMH=r(TCM) +matrix deces[22,1]=`TCMH' +tcm, s10(`s10') anneepop(1984) annees(1983/1985) sexe(2) +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[22,2]=`TCMF' + +tcm, s10(`s10') anneepop(1985) annees(1984/1986) sexe(1) +matrix essai=r(donnees) +local TCMH=r(TCM) +matrix deces[23,1]=`TCMH' +tcm, s10(`s10') anneepop(1985) annees(1984/1986) sexe(2) +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[23,2]=`TCMF' + +tcm, s10(`s10') anneepop(1986) annees(1985/1987) sexe(1) +matrix essai=r(donnees) +local TCMH=r(TCM) +matrix deces[24,1]=`TCMH' +tcm, s10(`s10') anneepop(1986) annees(1985/1987) sexe(2) +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[24,2]=`TCMF' + +tcm, s10(`s10') anneepop(1992) annees(1991/1993) sexe(1) +matrix essai=r(donnees) +local TCMH=r(TCM) +matrix deces[26,1]=`TCMH' +tcm, s10(`s10') anneepop(1992) annees(1991/1993) sexe(2) +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[26,2]=`TCMF' + +tcm, s10(`s10') anneepop(1993) annees(1992/1994) sexe(1) +matrix essai=r(donnees) +local TCMH=r(TCM) +matrix deces[27,1]=`TCMH' +tcm, s10(`s10') anneepop(1993) annees(1992/1994) sexe(2) +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[27,2]=`TCMF' + +tcm, s10(`s10') anneepop(1994) annees(1993/1995) sexe(1) +matrix essai=r(donnees) +local TCMH=r(TCM) +matrix deces[28,1]=`TCMH' +tcm, s10(`s10') anneepop(1994) annees(1993/1995) sexe(2) +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[28,2]=`TCMF' + +tcm, s10(`s10') anneepop(1995) annees(1994/1996) sexe(1) +matrix essai=r(donnees) +local TCMH=r(TCM) +matrix deces[29,1]=`TCMH' +tcm, s10(`s10') anneepop(1995) annees(1994/1996) sexe(2) +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[29,2]=`TCMF' + +tcm, s10(`s10') anneepop(1996) annees(1995/1997) sexe(1) +matrix essai=r(donnees) +local TCMH=r(TCM) +matrix deces[30,1]=`TCMH' +tcm, s10(`s10') anneepop(1996) annees(1995/1997) sexe(2) +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[30,2]=`TCMF' + +tcm, s10(`s10') anneepop(1997) annees(1996/1998) sexe(1) +matrix essai=r(donnees) +local TCMH=r(TCM) +matrix deces[31,1]=`TCMH' +tcm, s10(`s10') anneepop(1997) annees(1996/1998) sexe(2) +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[31,2]=`TCMF' + +tcm, s10(`s10') anneepop(1998) annees(1997/1999) sexe(1) +matrix essai=r(donnees) +local TCMH=r(TCM) +matrix deces[32,1]=`TCMH' +tcm, s10(`s10') anneepop(1998) annees(1997/1999) sexe(2) +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[32,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) +matrix essai=r(donnees) +local TCMH=r(TCM) +local TCMH9800reg=r(TCM) +matrix deces[33,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) +matrix essai=r(donnees) +local TCMF=r(TCM) +local TCMF9800reg=r(TCM) +matrix deces[33,2]=`TCMF' + + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(18) tcmcomp(`TCMH9800reg') +matrix essai=r(donnees) +local TCMH18=r(TCM) +matrix deces[35,1]=essai[2..19,2] +matrix deces[53,1]=r(TCM) +matrix deces[54,1]=r(pvalue) + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(18) tcmcomp(`TCMF9800reg') +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[56,1]=essai[2..19,2] +matrix deces[74,1]=r(TCM) +matrix deces[75,1]=r(pvalue) + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(28) tcmcomp(`TCMH9800reg') +matrix essai=r(donnees) +local TCMH18=r(TCM) +matrix deces[35,2]=essai[2..19,2] +matrix deces[53,2]=r(TCM) +matrix deces[54,2]=r(pvalue) + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(28) tcmcomp(`TCMF9800reg') +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[56,2]=essai[2..19,2] +matrix deces[74,2]=r(TCM) +matrix deces[75,2]=r(pvalue) + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(36) tcmcomp(`TCMH9800reg') +matrix essai=r(donnees) +local TCMH18=r(TCM) +matrix deces[35,3]=essai[2..19,2] +matrix deces[53,3]=r(TCM) +matrix deces[54,3]=r(pvalue) + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(36) tcmcomp(`TCMF9800reg') +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[56,3]=essai[2..19,2] +matrix deces[74,3]=r(TCM) +matrix deces[75,3]=r(pvalue) + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(37) tcmcomp(`TCMH9800reg') +matrix essai=r(donnees) +local TCMH18=r(TCM) +matrix deces[35,4]=essai[2..19,2] +matrix deces[53,4]=r(TCM) +matrix deces[54,4]=r(pvalue) + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(37) tcmcomp(`TCMF9800reg') +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[56,4]=essai[2..19,2] +matrix deces[74,4]=r(TCM) +matrix deces[75,4]=r(pvalue) + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(41) tcmcomp(`TCMH9800reg') +matrix essai=r(donnees) +local TCMH18=r(TCM) +matrix deces[35,5]=essai[2..19,2] +matrix deces[53,5]=r(TCM) +matrix deces[54,5]=r(pvalue) + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(41) tcmcomp(`TCMF9800reg') +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[56,5]=essai[2..19,2] +matrix deces[74,5]=r(TCM) +matrix deces[75,5]=r(pvalue) + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(45) tcmcomp(`TCMH9800reg') +matrix essai=r(donnees) +local TCMH18=r(TCM) +matrix deces[35,6]=essai[2..19,2] +matrix deces[53,6]=r(TCM) +matrix deces[54,6]=r(pvalue) + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(45) tcmcomp(`TCMF9800reg') +matrix essai=r(donnees) +local TCMF=r(TCM) +matrix deces[56,6]=essai[2..19,2] +matrix deces[74,6]=r(TCM) +matrix deces[75,6]=r(pvalue) + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2411) +local TCMH=r(TCM) +matrix deces[77,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2411) +local TCMF=r(TCM) +matrix deces[77,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2412) +local TCMH=r(TCM) +matrix deces[78,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2412) +local TCMF=r(TCM) +matrix deces[78,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2413) +local TCMH=r(TCM) +matrix deces[79,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2413) +local TCMF=r(TCM) +matrix deces[79,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2414) +local TCMH=r(TCM) +matrix deces[80,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2414) +local TCMF=r(TCM) +matrix deces[80,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2421) +local TCMH=r(TCM) +matrix deces[81,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2421) +local TCMF=r(TCM) +matrix deces[81,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2422) +local TCMH=r(TCM) +matrix deces[82,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2422) +local TCMF=r(TCM) +matrix deces[82,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2423) +local TCMH=r(TCM) +matrix deces[83,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2423) +local TCMF=r(TCM) +matrix deces[83,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2424) +local TCMH=r(TCM) +matrix deces[84,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2424) +local TCMF=r(TCM) +matrix deces[84,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2431) +local TCMH=r(TCM) +matrix deces[85,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2431) +local TCMF=r(TCM) +matrix deces[85,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2432) +local TCMH=r(TCM) +matrix deces[86,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2432) +local TCMF=r(TCM) +matrix deces[86,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2433) +local TCMH=r(TCM) +matrix deces[87,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2433) +local TCMF=r(TCM) +matrix deces[87,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2434) +local TCMH=r(TCM) +matrix deces[88,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2434) +local TCMF=r(TCM) +matrix deces[88,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2441) +local TCMH=r(TCM) +matrix deces[89,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2441) +local TCMF=r(TCM) +matrix deces[89,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2442) +local TCMH=r(TCM) +matrix deces[90,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2442) +local TCMF=r(TCM) +matrix deces[90,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2443) +local TCMH=r(TCM) +matrix deces[91,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2443) +local TCMF=r(TCM) +matrix deces[91,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2444) +local TCMH=r(TCM) +matrix deces[92,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2444) +local TCMF=r(TCM) +matrix deces[92,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2451) +local TCMH=r(TCM) +matrix deces[93,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2451) +local TCMF=r(TCM) +matrix deces[93,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2452) +local TCMH=r(TCM) +matrix deces[94,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2452) +local TCMF=r(TCM) +matrix deces[94,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2453) +local TCMH=r(TCM) +matrix deces[95,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2453) +local TCMF=r(TCM) +matrix deces[95,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2461) +local TCMH=r(TCM) +matrix deces[96,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2461) +local TCMF=r(TCM) +matrix deces[96,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2462) +local TCMH=r(TCM) +matrix deces[97,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2462) +local TCMF=r(TCM) +matrix deces[97,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2463) +local TCMH=r(TCM) +matrix deces[98,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2463) +local TCMF=r(TCM) +matrix deces[98,2]=`TCMF' + +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(1) codegeo(2464) +local TCMH=r(TCM) +matrix deces[99,1]=`TCMH' +tcm, s10(`s10') anneepop(1999) annees(1998/2000) sexe(2) codegeo(2464) +local TCMF=r(TCM) +matrix deces[99,2]=`TCMF' + +use "C:\ado\personal\files\dccentre8000reduit.dta", clear +tab annee deptdom if S10==`s10' & sexe==1 , matcell(nbH) +matrix deces[101,1]=nbH +tab annee deptdom if S10==`s10' & sexe==2 , matcell(nbF) +matrix deces[121,1]=nbF + +matrix list deces + + +end diff --git a/Modules/ado/personal/c/cfa.ado b/Modules/ado/personal/c/cfa.ado new file mode 100644 index 0000000..006cbf4 --- /dev/null +++ b/Modules/ado/personal/c/cfa.ado @@ -0,0 +1,363 @@ +capture program drop cfa +program cfa,rclass +syntax varlist, PARTition(numlist integer >0) [SCOrename(string) CFAMethod(string) CFAStand] + + +local C = 0 +foreach z in `partition' { + local C = `C' + `z' +} + +local nbvars : word count `varlist' +if `C' != `nbvars' { + di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist" + exit +} + +local P:word count `partition' +if "`scorename'" !="" { + local S:word count `scorename' + if `P'!=`S' { + di in red "The number of score names given is different from the number of dimensions in the partition option" + exit + } +} + +local i = 1 +foreach x in `varlist' { + local var`i' = "`x'" + local `++i' +} + +local name +local nname +if "`scorename'"=="" { + forvalues i = 1/`P' { + local name "Dim`i'" + local nname `nname' `name' + } +local scorename = "`nname'" +} + +local upscorename = upper("`scorename'") + +*capture calcscore `varlist', scorename(`upscorename') partition(`partition') + +local i = 0 +local y = 1 +tokenize `upscorename' +foreach x in `partition' { + local `i++' + if `i' == 1 local s = `x' + else local s = `s' +`x' + + local liste = "" + forvalues w = `y'/`s' { + local liste `liste' `var`w'' + } + + local a = "(``i'' -> `liste')" + local z `z' `a' + + local y = `s'+1 +} +/* +local cpt = 0 +if "`cfa_ml'" != "" { + local method = "ml" + local cpt `cpt' + 1 +} +if "`cfa_mlmv'" != "" { + local method = "mlmv" + local cpt `cpt' + 1 +} +if "`cfa_adf'" != "" { + local method = "adf" + local cpt `cpt' + 1 +} +else local method = "ml" +if `cpt'>1 { + di in red "You must choose between cfa_ml, cfa_mlmv or cfa_adf (the options are exclusive)" + exit 119 +} +*/ + + +if "`cfamethod'" == "" local cfamethod = "ml" + +if "`cfamethod'" != "ml" & "`cfamethod'" != "mlmv" & "`cfamethod'" != "adf" { + di "`cfamethod'" + di in red "option cfamethod incorrectly specified (choose among ml, mlmv and adf)" + error 198 +} + + +if "`cfastand'" != "" local cfastand = "stand" + +di as result "{hline}" +di "{bf:Confirmatory factor analysis}" +di as result "{hline}" +di + +qui sem `z', method(`cfamethod') `cfastand' + +/* +sem (HA -> ioc1-ioc4) (PSE -> ioc5-ioc8) (W -> ioc9-ioc15) /// +(BCC -> ioc16-ioc18) (AC -> ioc19-ioc21) (AE -> ioc22-ioc25) /// +(LI -> ioc26-ioc32) (MOC -> ioc33-ioc37) +,stand +cov(e.ioc36*e.ioc37 +e.ioc28*e.ioc29 e.ioc14*e.ioc15 e.ioc23*e.ioc25 e.ioc33*e.ioc34 /// +e.ioc9*e.ioc10 e.ioc6*e.ioc8 e.ioc5*e.ioc7) // method(mlmv) +*/ + +/* factor loadings */ + +matrix r = r(table) +matrix r = r[1,1...] +matrix r = r' +local n = `nbvars'*2 + +matrix a = r[1,1] +forvalues i=3(2)`n' { + matrix b = r[`i',1] + matrix a = a\b +} + +/* standard error */ + +matrix r = r(table) +matrix r = r[2,1...] +matrix r = r' +local n = `nbvars'*2 + +matrix se = r[1,1] +forvalues i=3(2)`n' { + matrix b = r[`i',1] + matrix se = se\b +} + + +/* intercepts */ + +matrix r = r(table) +matrix r = r[1,1...] +matrix r = r' +local n = `nbvars'*2 + +matrix a2 = r[2,1] +forvalues i=4(2)`n' { + matrix b = r[`i',1] + matrix a2 = a2\b +} + +/* variances des erreurs */ + +local m = `n'+1 +matrix r = r(table) +matrix r = r[1,`m'...] +matrix r = r' + +matrix a3 = r[1,1] +forvalues i=2/`nbvars' { + matrix b = r[`i',1] + matrix a3 = a3\b +} + +/* variance des dimensions*/ + +matrix r = r(table) +local n = `nbvars'*3+1 +matrix r = r[1,`n'...] +matrix r = r' + +matrix var = r[1,1] +forvalues i=2/`P' { + matrix b = r[`i',1] + matrix var = var\b +} + + +local i = 1 +foreach v in `varlist' { + local var`i' = abbrev("`v'",10) + local `++i' +} + + +local i = 1 +foreach s in `scorename' { + local s`i' = abbrev("`s'",10) + local sc `sc' `s`i'' + local `++i' + +} + +local max = 10 +local dec = `max'+5 + +local max2 = 10 + +local dec2 = `dec'+`max2'+5 + +local a = e(N) +di "{text:Number of used individuals: `a'}" +di +di _col(`=`dec2'+17+4') "{bf:Estimation:}" + + +di as result "{bf:Item}" _c +di _col(`dec') "{bf:Dimension}" _c +*local col = `dec'+17 +di _col(`dec2') "{bf:Factor}" _c +*local col = `dec2'+17 +di _col(`=`dec2'+14') "{bf:Standard}" _c +*local col = `col'+17 +di _col(`=`dec2'+28') "{bf:Intercept}" _c +*local col = `col'+13 + + +if "`cfastand'" == "" { + di _col(`=`dec2'+42') "{bf:Variance of}" _c + di _col(`=`dec2'+56') "{bf:Variance of}" + + di _col(`dec2') "{bf:loading}" _c + *local col = `dec2'+17 + di _col(`=`dec2'+14') "{bf:error}" _c + *local col = `col'+30 + + di _col(`=`dec2'+42') "{bf:error}" _c + di _col(`=`dec2'+56') "{bf:dimension}" + local h = `dec2'+66 +} +else { + di _col(`=`dec2'+42') "{bf:Variance of}" + + di _col(`dec2') "{bf:loading}" _c + *local col = `dec2'+17 + di _col(`=`dec2'+14') "{bf:error}" _c + *local col = `col'+30 + + di _col(`=`dec2'+42') "{bf:errors}" + local h = `dec2'+52 +} + + +di "{hline `h'}" + +local i = 1 +local y = 1 +foreach x in `partition' { + if `i' == 1 local s = `x' + else local s = `s' +`x' + + forvalues z = `y'/`s' { + tokenize `sc' + di "{bf:`var`z''}"_c + di _col(`dec') "{bf:``i''}" _c + local t = a[`z',1] + local t : di %7.2f `t' + *local col = `dec'+17 + di _col(`dec2') "{text:`t'}" _c + + local t = se[`z',1] + local t : di %8.2f `t' + *local col = `dec2'+9 + di _col(`=`dec2'+14') "{text:`t'}" _c + + local t = a2[`z',1] + local t : di %9.2f `t' + *local col = `col'+17 + di _col(`=`dec2'+28') "{text:`t'}" _c + + local t = a3[`z',1] + local t : di %11.2f `t' + *local col = `col'+13 + + + if "`cfastand'" == "" & `z' == `y'{ + di _col(`=`dec2'+42') "{text:`t'}" _c + local t = var[`i',1] + local t : di %11.2f `t' + *local col = `dec2'+17+17+13+14 + di _col(`=`dec2'+56') "{text:`t'}" + } + else di _col(`=`dec2'+42') "{text:`t'}" + } + di + local `i++' + local y = `s'+1 +} + +qui estat gof, stats(all) + +local chi2 = r(chi2_ms) +local p = r(p_ms) +local ddl = r(df_ms) +local ratio = `chi2'/`ddl' +local rmsea = r(rmsea) +local lb = r(lb90_rmsea) +local ub = r(ub90_rmsea) +local nfi = 1-(r(chi2_ms)/r(chi2_bs)) +local rni = 1-(r(chi2_ms)-r(df_ms))/(r(chi2_bs)-r(df_bs)) +local cfi = r(cfi) +local ifi = (r(chi2_bs)-r(chi2_ms))/(r(chi2_bs)-r(df_ms)) +local mci = exp(-0.5*((r(chi2_ms)-r(df_ms))/(e(N)-1))) +local srmr = r(srmr) + +di +di "{bf:Goodness of fit}" +di + +di as result _col(4) "chi2" _c +di as result _col(20) "ddl" _c +di as result _col(28) "chi2/ddl" _c +di as result _col(42) "RMSEA [90% CI]" _c +di as result _col(64) "SRMR" _c +di as result _col(74) "NFI" _c +di as result _col(84) "RNI" _c +di as result _col(94) "CFI" _c +di as result _col(104) "IFI" _c +di as result _col(114) "MCI" + +*di as result "`P' dimensions" _c + +local t : di %7.2f `chi2' +di "{text:`t'}" _c +local t : di %3.0f `ddl' +di _col(20) "{text:`t'}" _c +local t : di %7.1f `ratio' +di _col(29) "{text:`t'}" _c +local t : di %5.3f `rmsea' +local l : di %5.3f `lb' +local u : di %5.3f `up' +di _col(40) "{text:`t' [`l' ; `u']}" _c +local t : di %5.3f `srmr' +di _col(63) "{text:`t'}" _c +local t : di %5.3f `nfi' +di _col(72) "{text:`t'}" _c +local t : di %5.3f `rni' +di _col(82) "{text:`t'}" _c +local t : di %5.3f `cfi' +di _col(92) "{text:`t'}" _c +local t : di %5.3f `ifi' +di _col(102) "{text:`t'}" _c +local t : di %5.3f `mci' +di _col(112) "{text:`t'}" +local p : di %5.3f `p' +di "{text:(p-value = `p')}" +di as result + + +/* +matrix ind = (`chi2',`ddl',`ratio',`rmsea',`nfi',`rni',`cfi',`ifi',`srmr') +matrix colnames ind = "chi2" "ddl" "chi2/ddl" "RMSEA" "NFI" "RNI" "CFI" "IFI" "SRMR" +matrix rownames ind = "" +di +di "{bf:Goodness of fit}" +matrix list ind, format(%6.3f) noheader +*/ +end + +*cfa ioc1-ioc37, partition(4 4 7 3 3 4 7 5) scorename(HAaaaaaaaaaaaaaaaaaaaaaaaaaz PSE W BCC AC AE LI MOC) cfamethod(ml) //cfastand +*cfa x1-x40, partition(5 5 5 5 5 5 5 5) cfastand diff --git a/Modules/ado/personal/c/checkfor2.ado b/Modules/ado/personal/c/checkfor2.ado new file mode 100644 index 0000000..a5e40ff --- /dev/null +++ b/Modules/ado/personal/c/checkfor2.ado @@ -0,0 +1,168 @@ +*!Version 1.1 +*!Data management utility: check for existence of variables in a dataset. +*!Authors: Amadou Bassirou DIALLO (World Bank) and Jean-Benoit Hardouin (Regional Health Observatory of Orléans) + +program checkfor2 , rclass +version 8 +syntax anything [if] [in] [, noList Tolerance(real 0) TAble noSUm GENMiss(namelist min=1 max=1) MISsing(string)] + +marksample touse +tempname rat +local av +local unav +local manymissings +local avnum + +quietly count if `touse' +local tot = r(N) + +qui isvar `anything' +local badlist `r(badlist)' +local varlist `r(varlist)' + +di _n +if "`table'"!="" { + if "`badlist'"!="" { + di _col(4) in green "{hline 39}" + di _col(4)in green "Unavailable variables: " + foreach i of local badlist { + di _col(4) in ye "`i'" + } + di _col(4) in green "{hline 39}" + di + } + di _col(4) in green "{hline 39}" + display _col(4) in gr "Existing" _col(15) in gr "Rate of" + display _col(4) in gr "Variable" _col(14) "missings" _col(26) "Type" _col(34) "Available" + di _col(4) in green "{hline 39}" +} + +tokenize `varlist' +local nbvar : word count `varlist' + +forvalues i=1/`nbvar' { + capture assert missing(``i'') if `touse' + local ty: type ``i'' + local tty = substr("`ty'", 1, 3) + if !_rc { + if "`table'"=="" { + display in ye "``i''" in gr " is empty in the database." in ye " ``i''" in gr " is not added to the available list." + } + else { + display _col(4) in gr "`=abbrev("``i''",8)'" _col(15) in ye "100.00%" _col(26) "`ty'" + } + local manymissings `manymissings' ``i'' + } + else { + if "`table'"=="" { + display in ye "``i''" in gr " exists and is not empty." + } + *Consider type + if "`tty'" == "str" { + qui count if (``i'' == ""|``i''=="`missing'") & `touse' + local num = r(N) + scalar `rat' = (`num'/`tot')*100 + } + else { + local avnum `avnum' ``i'' + capture confirm number `missing' + if _rc!=0 { + quietly count if ``i'' >= . & `touse' + } + else { + quietly count if (``i'' >= .|``i''==`missing') & `touse' + } + local num = r(N) + scalar `rat' = (`num'/`tot')*100 + } + if "`table'"=="" { + display in ye "``i''" in gr " has " in ye r(N) in gr " missings." + display in gr "Ratio number of missings of" in ye " ``i''" in gr " to total number of observations: " in ye %6.2f `rat' "%" + } + + if `rat' <= `tolerance' { + local av `av' ``i'' + if "`table'"=="" { + display in ye "``i''" in gr " is added to the available list." + } + else { + display _col(4) in gr "`=abbrev("``i''",8)'" in ye _col(15) %6.2f `rat' "%" _col(26) "`ty'" _col(34) "X" + } + } + else { + local manymissings `manymissings' ``i'' + if "`table'"=="" { + display in ye "``i''" in gr " has too many missings, compared to the tolerance level." + display in ye "``i''" in gr " is not added to the available list." + } + else { + display _col(4) in gr "`=abbrev("``i''",8)'" _col(15) in ye %6.2f `rat' "%" _col(26) "`ty'" + } + } + } + if "`table'"=="" { + di + } +} + +if "`table'"!="" { + di _col(4) in green "{hline 39}" +} + +return local available `av' +return local unavailable `badlist' +return local manymissings `manymissings' + +if "`avnum'" ~= ""&"`sum'"=="" { + display _newline + display in ye _col(14) "Unweighted summary statistics for available variables:" _n + capture confirm number `missing' + if _rc!=0 { + summarize `avnum' if `touse' + } + else { + foreach i of local avnum { + summarize `i' if `touse'&`i'!=`missing' + } + } +} + +if "`list'"== "" { + display _newline + display in ye _d(97) "_" + display _newline + if "`badlist'"~="" { + display in gr "Unavailable variables: " in ye _col(45) "`badlist'" _n + } + if "`av'"~="" { + display in gr "Available variables: " in ye _col(45) "`av'" _n + } + if "`manymissings'"~="" { + display in gr "Available variables but with too missings: " in ye _col(45) "`manymissings'" _n + } + display in ye _d(97) "_" +} + +if "`genmiss'" !="" { + capture confirm variable `genmiss' + if _rc!=0 { + qui gen `genmiss' = 0 + local nbav : word count `av' + tokenize `av' + forvalues i=1/`nbav' { + local ty: type ``i'' + local tty = substr("`ty'", 1, 3) + if "`tty'" == "str" { + qui replace `genmiss'=`genmiss'+1 if ``i''=="." + } + else { + qui replace `genmiss'=`genmiss'+1 if ``i''>=. + } + } + } + else { + di in green "The variable" in ye " `genmiss' " in green "already exists". + } +} + +end diff --git a/Modules/ado/personal/c/checkfor2.hlp b/Modules/ado/personal/c/checkfor2.hlp new file mode 100644 index 0000000..462848f --- /dev/null +++ b/Modules/ado/personal/c/checkfor2.hlp @@ -0,0 +1,88 @@ +{smcl} +{hline} +help for {cmd:checkfor2} {right:Amadou B. DIALLO} + {right:Jean-Benoit HARDOUIN} +{hline} + +{title:Allows checking whether a variable exists or not in a dataset.} + +{p 4 8 2}{cmd:checkfor2} {it:anything} [{cmd:,} + {cmdab:t:olerance}({it:#}) {cmdab:ta:ble} {cmdab:nol:ist} {cmdab:nosu:m} + {cmdab:genm:iss}({it:newvarname}) {cmdab:mis:sing}({it:string})] + +{title:Description} + +{p 4 4 2}{cmd:checkfor2} is a data management routine to check for existence of variables +within a (usually big) data set. + +{p 4 4 2}{cmd:checkfor2} searchs through the data whether each variable exists. +The variables are clustered between unavailable variables, available variables with +a little amount of missing values and available variables with too many missing values. + +{p 4 4 2}{cmd:isvar} must be installed ({stata ssc install isvar:ssc install isvar}). + +{title:Options} + +{p 4 4 2}{it:anything} is composed of variable names or lists of variables, + +{p 4 4 2}{cmd:tolerance} is the tolerance level (in percentage) to consider a variable as available, with default 0, + +{p 4 4 2}{cmd:nolist} avoids displaying availability status at the end of the process, + +{p 4 4 2}{cmd:nosum} avoids displaying summary statistics of available variables, + +{p 4 4 2}{cmd:table} displays the results in a table (instead as text), + +{p 4 4 2}{cmd:genmiss} creates a new variable containing the number of missing values among the available variables, + +{p 4 4 2}{cmd:missing} defines a specific value or string considered as a missing value. + + +{title:Saved results} + +{p 4 4 2} {cmd:r(unavailable)} names of unavailable variables.{p_end} + +{p 4 4 2} {cmd:r(available)} names of available variables with a small amount of missing values.{p_end} + +{p 4 4 2} {cmd:r(manymissings)} names of variables present but with too missings.{p_end} + +{title:Examples} + +{p 4 4 2}{cmd:. use mydata, clear }{p_end} + +{p 4 4 2}{cmd:. checkfor2 x y z , mis(99) genmiss(countmiss) }{p_end} + +{p 4 4 2}{cmd:. su `r(available)' }{p_end} + +{p 4 4 2}{cmd:. tab countmiss }{p_end} + +{p 4 4 2}{cmd:. u bigdataset in 1/100, clear // Big data set}{p_end} + +{p 4 4 2}{cmd:. checkfor2 v1 v2 v3 xx yy , nosum tol(5) tab}{p_end} + +{p 4 4 2}{cmd:. use `r(available)' using bigdataset, clear }{p_end} + +{title:Remarks} + +{p 4 4 2}{cmd:checkfor2} and its primary version ({cmd:checkfor}) have been primarily written for comparable surveys such as the Demography and +Health Surveys (DHS) or the Multiple Indicator Cluster Surveys (MICS). But this could easily applied +to any other survey. + +{title:Authors} + +{p 4 4 2}Amadou Bassirou DIALLO. +Poverty and Health Division, PREM, The World Bank.{p_end} +{p 4 4 2}Email: {browse "mailto:adiallo5@worldbank.org":adiallo5@worldbank.org} + +{p 4 4 2}Jean-Benoit HARDOUIN. +Regional Health Observatory of Orléans, France.{p_end} +{p 4 4 2}Email: {browse "mailto:jean-benoit.hardouin@orscentre.org":jean-benoit.hardouin@orscentre.org} + +{title:Aknowledgements} + +{p 4 4 2}We would like to thank Christophe Rockmore and also Nick Cox +and Kit Baum for their comments. + +{title:Also see} + +{p 4 13 2}Online: help for {help checkfor}, {help isvar}, {help nmissing}, {help npresent}, {help missing} and {help dropmiss} if installed.{p_end} diff --git a/Modules/ado/personal/c/checkvars.ado b/Modules/ado/personal/c/checkvars.ado new file mode 100644 index 0000000..787c343 --- /dev/null +++ b/Modules/ado/personal/c/checkvars.ado @@ -0,0 +1,133 @@ +*!Version 1.1 +*!Data management utility: check for existence of variables in a dataset. +*!Authors: Amadou Bassirou DIALLO (World Bank) and Jean-Benoit Hardouin (Regional Health Observatory of Orléans) + +program checkvars, rclass +version 8 +syntax anything [if] [in] [, noList Tolerance(real 0) TAble noSUm GENMiss(namelist min=1 max=1)] + +marksample touse +tempname rat +local av +local unav +local manymissings + +quietly count if `touse' +local tot = r(N) + +qui isvar `anything' +local badlist `r(badlist)' +local varlist `r(varlist)' + +if "`table'"!="" { + if "`badlist'"!="" { + di _col(4)in green "Unavailable variables: " in ye "`badlist'" + di + } + di _col(4) in green "{hline 29}" + display _col(4) in gr "Existing" _col(15) in gr "Rate of" + display _col(4) in gr "Variable" _col(14) "missings" _col(24) "Available" + di _col(4) in green "{hline 29}" +} + +tokenize `varlist' +local nbvar:word count `varlist' + +forvalues i=1/`nbvar' { + capture assert missing(``i'') if `touse' + if !_rc { + if "`table'"=="" { + display in ye "``i''" in gr " is empty in the database." in ye " ``i''" in gr /// + " is not added to the available list" + } + else { + display _col(4) in gr "``i''" _col(14) "100.00%" + } + } + else { + if "`table'"=="" { + display in ye "``i''" in gr " exists and is not empty." + } + *if "`available'"~= "" { + quietly count if ``i'' >= . & `touse' + local num = r(N) + scalar `rat' = (`num'/`tot')*100 + if "`table'"=="" { + display in ye "``i''" in gr " has " in ye r(N) in gr " missings." + display in gr "Ratio number of missings of" in ye " ``i''" in gr /// + " to total number of observations: " in ye %6.2f `rat' "%" + } + if `rat' <= `tolerance' { + local av `av' ``i'' + if "`table'"=="" { + display in ye "``i''" in gr " is added to the available list." + } + else { + display _col(4) in gr "``i''" in ye _col(15) %6.2f `rat' "%" _col(32) "X" + } + } + else { + local manymissings `manymissings' ``i'' + if "`table'"=="" { + display in ye "``i''" in gr " has too many missings, compared to the tolerance level." + display in ye "``i''" in gr " is not added to the available list." + } + else { + display _col(4) in gr "``i''" _col(15) in ye %6.2f `rat' "%" + } + } + *} + } + if "`table'"=="" { + di + } +} +if "`table'"!="" { + di _col(4) in green "{hline 29}" +} + +return local available `av' +return local unavailable `badlist' +return local manymissings `manymissings' + +if "`av'" ~= ""&"`sum'"=="" { + display _newline + display in ye _col(14) "Unweighted summary statistics for available variables:" _n + summarize `av' if `touse' +} + + +if "`list'"== "" { + display _newline + display in ye _d(97) "_" + display _newline + if "`badlist'"~="" { + display in gr "Unavailable variables: " in ye _col(45) "`badlist'" _n + } + if "`av'"~="" { + display in gr "Available variables: " in ye _col(45) "`av'" _n + } + if "`manymissings'"~="" { + display in gr "Available variables but with too missings: " in ye _col(45) "`manymissings'" _n + } + display in ye _d(97) "_" +} + +if "`genmiss'" !="" { + capture confirm variable `genmiss' + if _rc!=0 { + qui gen `genmiss'=0 + local nbav:word count `av' + tokenize `av' + forvalues i=1/`nbav' { + qui replace `genmiss'=`genmiss'+1 if ``i''>=. + } + } + else { + di in green "The variable" in ye " `genmiss' " in green "already exists". + } + +} + + +end diff --git a/Modules/ado/personal/c/checkvars.hlp b/Modules/ado/personal/c/checkvars.hlp new file mode 100644 index 0000000..fc4d646 --- /dev/null +++ b/Modules/ado/personal/c/checkvars.hlp @@ -0,0 +1,90 @@ +{smcl} +{hline} +help for {cmd:checkvars} {right:Amadou B. DIALLO} + {right:Jean-Benoit HARDOUIN} +{hline} + +{title:Allows checking whether a variable exists or not in a dataset.} + + +{p 4 8 2}{cmd:checkvars} {it:anything} [{cmd:,} + {cmdab:t:olerance}({it:#}) {cmdab:ta:ble} {cmdab:nol:ist} {cmdab:nosu:m} + {cmdab:genm:iss}({it:newvarname})] + +{title:Description} + +{p 4 4 2}{cmd:checkvars} is a routine to check for existence of variables +within a (usually big) data set. + +{p 4 4 2}{cmd:checkvars} searchs through the data whether each variable exists. +The variables are clustered between unavailable variables, available variables with +a little amount of missing values and available variables with too many missing values. + +{p 4 4 2}{cmd:isvar} must be installed ({stata ssc install isvar:ssc install isvar}). + +{title:Options} + +{p 4 4 2}{it:anything} is composed of variable names or lists of variables, + +{p 4 4 2}{cmd:tolerance} is the tolerance level (in percentage) to consider a variable as available, with default 0, + +{p 4 4 2}{cmd:nolist} avoids displaying availability status at the end of the process, + +{p 4 4 2}{cmd:nosum} avoids displaying summary statistics of available variables, + +{p 4 4 2}{cmd:table} displays the results in a table (instead as text), + +{p 4 4 2}{cmd:genmiss} creates a new variable containing the number of missing values among the available variables. + + + +{title:Saved results} + +{p 4 4 2} {cmd:r(unavailable)} names of unavailable variables.{p_end} + +{p 4 4 2} {cmd:r(available)} names of available variables with a small amount of missing values.{p_end} + +{p 4 4 2} {cmd:r(manymissings)} names of variables but with too missings.{p_end} + +{title:Examples} + +{p 4 4 2}{cmd:. use mydata, clear }{p_end} + +{p 4 4 2}{cmd:. checkvars x y z ,genmiss(countmiss) }{p_end} + +{p 4 4 2}{cmd:. su `r(available)' }{p_end} + +{p 4 4 2}{cmd:. tab countmiss }{p_end} + +{p 4 4 2}{cmd:. u bigdataset in 1/100, clear // Big data set}{p_end} + +{p 4 4 2}{cmd:. checkvars v1 v2 v3 xx yy , nosum tol(5) tab}{p_end} + +{p 4 4 2}{cmd:. use `r(available)' using bigdataset, clear }{p_end} + +{title:Remarks} + +{p 4 4 2}{cmd:checkvars} and its primary versions ({cmd:checkfor} and {cmd:checkfor2}) have been primarily written for comparable surveys such as the Demography and +Health Surveys (DHS) or the Multiple Indicator Cluster Surveys (MICS). But this could easily applied +to any other survey. + +{title:Authors} + +{p 4 4 2}Amadou Bassirou DIALLO. +Poverty and Health Specialist. AFTPM, The World Bank.{p_end} +{p 4 4 2}Email: {browse "mailto:adiallo5@worldbank.org":adiallo5@worldbank.org} + +{p 4 4 2}Jean-Benoit HARDOUIN. +Regional Health Observatory of Orléans, France.{p_end} +{p 4 4 2}Email: {browse "mailto:jean-benoit.hardouin@orscentre.org":jean-benoit.hardouin@orscentre.org} + +{title:Aknowledgements} + +{p 4 4 2}We would like to thank Christophe Rockmore and also Nick Cox +and Kit Baum for their comments. + +{title:Also see} + +{p 4 13 2}Online: help for {help checkfor}, {help checkfor2}, {help isvar}, {help nmissing}, {help npresent}, {help missing} and {help dropmiss} if installed.{p_end} + + diff --git a/Modules/ado/personal/c/clv.ado b/Modules/ado/personal/c/clv.ado new file mode 100644 index 0000000..3804708 --- /dev/null +++ b/Modules/ado/personal/c/clv.ado @@ -0,0 +1,957 @@ +*! Version 2.17 10July2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : clv +* Clustering of variables around latent variables +* Version 2.14 : May 20th, 2010 /*dim and std options for biplots*/ +* +* Historic +* Version 1 (2005-06-11): Jean-Benoit Hardouin +* Version 1.1 (2005-07-07): Jean-Benoit Hardouin /*small bug in the consolidation process with cluster of only one variable*/ +* Version 1.2 (2005-07-08): Jean-Benoit Hardouin /*Bug in the consolidation procedure when there is negative correlation*/ +* Version 2 (2005-09-03): Jean-Benoit Hardouin /*Horizontal dendrograms (with Stata 9)*/ +* Version 2.1 (2005-09-08): Jean-Benoit Hardouin /*More flexibility to abbreviate the names of the variables (with Stata 9)*/ +* Version 2.1.1 (2005-09-08): Jean-Benoit Hardouin /*Integration of some requests of Ronan Conroy*/ +* Version 2.1.2 (2005-09-08): Jean-Benoit Hardouin /*Possibility to give a title and an X/Y caption*/ +* Version 2.2 (2005-09-11): Jean-Benoit Hardouin /*Kernel option*/ +* Version 2.3 (2005-09-12): Jean-Benoit Hardouin /*Polychoric option*/ +* Version 2.4 (2005-09-13): Jean-Benoit Hardouin /*v2 option*/ +* Version 2.5 (2005-09-21): Jean-Benoit Hardouin /*corrections*/ +* Version 2.6 (2005-10-02): Jean-Benoit Hardouin /*centroid method, biplot*/ +* Version 2.7 (2005-10-06): Jean-Benoit Hardouin /*return, multiple graphs, polychoric+consolidation*/ +* Version 2.8 (2005-10-06): Jean-Benoit Hardouin /*fweights*/ +* Version 2.9 (2006-01-26): Jean-Benoit Hardouin /*save the latent variables*/ +* Version 2.10 (2006-07-10): Jean-Benoit Hardouin /*2nd order relative variation of the T criterion*/ +* Version 2.11 (2006-10-09): Jean-Benoit Hardouin /*Size of the text in the dendrogram*/ +* Version 2.12 (2006-12-01): Jean-Benoit Hardouin /*savedendro option*/ +* Version 2.13 (2010-05-12): Jean-Benoit Hardouin /*corrections of bugs in KERNEL option and with METHOD(centroid)*/ +* Version 2.14 (2010-05-20): Jean-Benoit Hardouin /*DIM and STD options for biplots*/ +* Version 2.15 (2014-04-14): Jean-Benoit Hardouin /*save and use options*/ +* Version 2.16 (2014-04-30): Jean-Benoit Hardouin, Bastien Perrot /*HTML option*/ +* Version 2.17 (2019-07-10): Jean-Benoit Hardouin /*filesave and dirsave options*/ +* +* Jean-benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://anaqol.sphere-nantes.fr +* +* Copyright 2005-2006, 2010, 2014, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ +program define clv,rclass +version 10 +syntax [varlist(default=none)] [if] [in] [fweight] [, CUTnumber(int 40) bar CONSolidation(int 0) noDENdro SAVEDendro(string) noSTANDardized deltaT HORizontal SHOWcount ABBrev(int 14) TITle(string) CAPtion(string) KERnel(numlist) METHod(string) noBIPlot ADDvar genlv(string) replace TEXTSize(string) std dim(string) save(string) use(string) FILESave DIRSave(string)] +preserve +tempfile clvfile +tempvar id +gen `id'=_n +qui save `clvfile',replace +local matsize=c(matsize) +local none=0 +if "`varlist'"==""&"`use'"=="" { + capture confirm matrix r(vp) + if _rc==0 { + capture confirm matrix r(matclus) + if _rc ==0 { + local none=1 + } + } + if `none'==0 { + di in red "You cannot use the {hi:clv} command without {hi:varlist} if you have not already run {hi:clv}" + error 198 + exit + } +} + +if "`filesave'"!="" { + if "`dirsave'"=="" { + local dirsave `c(pwd)' + } + local fsb saving(`dirsave'//bar,replace) + local fsd saving(`dirsave'//dendrogram,replace) + local fsbi saving(`dirsave'//biplot,replace) +} +tempname matclus vp indexes + +/*********TESTS**********/ + +if "`use'"!="" { + local error=0 + capture matrix `vp'=`use'_vp + if _rc!=0 { + local error=_rc + } + capture matrix `matclus'=`use'_matclus + if _rc!=0 { + local error=_rc + } + local varlist $`use'_varlist + local method $`use'_method + local kernel $`use'_kernel + if "`varlist'"==""|"`method'"=="" { + local error=1 + } + if `error'!=0 { + di in red "You cannot use the {hi:use} option without a preliminary use of the {hi:save} option" + error 198 + exit + } +} +if `none'==1 { + matrix `vp'=r(vp) + matrix `matclus'=r(matclus) + local varlist `r(varlist)' + tokenize `varlist' + local nbitems=rowsof(`matclus') + if "`method'"!="" { + di in green "The {hi:method} option can not be modified without specification of the varlist. {hi:method} is omitted." + } + local method `r(method)' + local kernel `r(kernel)' +} +if "`method'"=="" { + local method classical +} +if ("`method'"=="polychoric"|"`method'"=="polychoricv2")&"`standardized'"!="" { + di in green "Initial variables are used with the {hi:polychoric} methods" + di in green "But the procedure is based on the matrix of the polychoric correlations" + di +} +if "`method'"!="classical"&"`method'"!="v2"&"`method'"!="centroid"&"`method'"!="polychoric"&"`method'"!="polychoricv2" { + di in red "The {hi:method} `method' is unknown" + error 198 + exit +} + +tokenize `varlist' +local nbitems : word count `varlist' +marksample touse +qui keep if `touse' + +local mat=max(`matsize',`=`nbitems'*2') +qui set matsize `mat' + +if `nbitems'<3&`none'!=1 { + di in red "You need at least 3 variables" + error 198 + exit +} + + +/*******DEFINES THE LABELS AND STANDARDIZED THE VARIABLES (IF NECESSARY)*******/ +forvalues i=1/`nbitems'{ + local label`i':variable label ``i'' + if "`label`i''"=="" { + local label`i' ``i'' + } + if "`method'"!="polychoric"&"`method'"!="polychoricv2" { + qui su ``i'' [`weight'`exp'] + local mean=r(mean) + if "`standardized'"=="" { + local sd=r(sd) + } + else { + local sd=1 + } + qui replace ``i''=(``i''-`mean')/`sd' + } +} + +tempfile clvfiletmp +qui save `clvfiletmp',replace + +qui su `1' [`weight'`exp'] +local nbind=r(sum_w) + + +local cons=`consolidation' + +/*COMPUTES THE TOTAL VARIANCE*/ + +if "`method'"!="polychoric"&"`method'"!="polychoricv2" { + local totvar=0 + forvalues i=1/`nbitems' { + qui su ``i'' [`weight'`exp'] + local totvar=`totvar'+`r(Var)' + } +} +else { + local totvar `nbitems' +} +local nbkerk=0 +local nbkerg=0 + +/***** DEFINES THE KERNEL IF NECESSARY ********/ + +if "`kernel'"!="" { + local nbkerg:word count `kernel' + local fin0=0 + forvalues i=1/`nbkerg' { + local nbi`i':word `i' of `kernel' + local nbkerk=`nbkerk'+`nbi`i'' + local deb`i'=`fin`=`i'-1''+1 + local fin`i'=`deb`i''+`nbi`i''-1 + local list`i' + forvalues j=`deb`i''/`fin`i'' { + local list`i' `list`i'' ``j'' + } + } + tempname kerclus + matrix `kerclus'=J(`=`nbkerk'-`nbkerg'',3,0) + local ligne=1 + forvalues g=1/`nbkerg' { + matrix `kerclus'[`ligne',1]=`nbitems'+`ligne' + matrix `kerclus'[`ligne',2]=`deb`g'' + matrix `kerclus'[`ligne',3]=`deb`g''+1 + local clus`g'=`nbitems'+`ligne' + local ligne=`ligne'+1 + if `nbi`g''>2 { + forvalues i=2/`=`nbi`g''-1' { + matrix `kerclus'[`ligne',1]=`nbitems'+`ligne' + matrix `kerclus'[`ligne',2]=`deb`g''+`i' + matrix `kerclus'[`ligne',3]=`nbitems'+`ligne'-1 + local clus`g'=`nbitems'+`ligne' + local ligne=`ligne'+1 + } + } + local eigen2=0 + } +} +if `nbitems'<`nbkerk' { + di in red "You cannot define more variables in the {hi:kernel} option than items in the {hi:varlist}" + error 198 + exit +} + +/*******DISPLAY THE FIRST RESULTS *******/ + +di +di in green "{hline 32}" +di in green "TOTAL VARIANCE: " in ye %16.5f `totvar' +di in green "NUMBER OF INDIVIDUALS: " in ye %9.0f `nbind' +di in green "METHOD:" in ye _col(`=33-length("`method'")') "`=upper("`method'")'" +di in green "{hline 32}" +di + +if "`kernel'"!="" { + forvalues i=1/`nbkerg' { + di in green "The kernel numbered " in ye `clus`i'' in green " is composed of `nbi`i'' variables: " in ye "`list`i''" + di + } +} +else { + local nbkerk=0 + local nbkerg=0 +} + +/******** CLASSIFICATION PROCEDURE*******/ + +tempname Ev +if `none'!=1 { + matrix `matclus'=J(`nbitems',`nbitems',0) + matrix `vp'=J(`=2*`nbitems'-1',12,0) + matrix `indexes'=J(`nbitems',8,0) + forvalues i=1/`nbitems' { + matrix `matclus'[`i',1]=`i' + if "`method'"!="polychoric"&"`method'"!="polychoric" { + qui su ``i'' [`weight'`exp'] + matrix `vp'[`i',10]=r(Var) + } + else { + matrix `vp'[`i',10]=1 + } + matrix `vp'[`i',1]=`i' + matrix `vp'[`i',2]=`nbitems' + matrix `vp'[`i',8]=`totvar' + matrix `vp'[`i',9]=100 + } + matrix `vp'[`nbitems',5]=`nbitems' + if "`method'"=="centroid" { + local crit G + di in green "{hline 101}" + di in green _col(93) "2nd order" + di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(82) "Relative" _col(94) "Relative" + di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Variation" _col(93) "Variation" + di in green "{hline 101}" + } + else { + local crit T + di in green "{hline 111}" + if "`method'"=="v2"|"`method'"=="polychoricv2" { + di in green _col(84) "Maximal" _col(103) "2nd order" + } + else { + di in green _col(84) "Current" _col(103) "2nd order" + } + di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(85) "Second" _col(93) "Relative" _col(104) "Relative" + di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Eigenvalue" _col(92) "Variation" _col(103) "Variation" + di in green "{hline 111}" + } + tempname threshold + matrix `threshold'=J(`nbitems',3,0) + forvalues i=1/`=`nbitems'-1' { + local clus=`nbitems'+`i' + local minegenval=999999 + local minegenval2=999999 + forvalues k=1/`=`clus'-1' { + local list`k' + local numlist`k' + forvalues j=1/`clus' { + if (`matclus'[`j',`i']==`k') { + local list`k' `list`k'' ``j'' + local numlist`k' `numlist`k'' `j' + } + } + } + if `clus'>`nbitems'+`nbkerk'-`nbkerg' { + if "`method'"=="centroid" { + tempname centrj centrk diffjk + } + forvalues j=1/`clus' { + local nblistj:word count `list`j'' + forvalues k=`=`j'+1'/`clus' { + local nblistk:word count `list`k'' + if `nblistj'!=0&`nblistk'!=0 { + if "`method'"=="centroid" { + qui genscore `list`j'',score(`centrj') mean + qui su `centrj' [`weight'`exp'] + local Varj=r(Var) + qui genscore `list`k'',score(`centrk') mean + qui su `centrk' [`weight'`exp'] + local Vark=r(Var) + qui gen `diffjk'=`centrk'-`centrj' + qui su `diffjk' [`weight'`exp'] + local Varjk=r(Var) + drop `centrj' `centrk' `diffjk' + local ev=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`Varjk' + if `ev'<`minegenval' { + local minegenval=`ev' + local minj `j' + local mink `k' + local eigen=0 + local eigen2=0 + } + } + else { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`j'' `list`k'' [`weight'`exp'] ,cov + matrix `Ev'=e(Ev) + } + else if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + qui polychoricpca `list`j'' `list`k'' [`weight'`exp'] + matrix `Ev'=r(eigenvalues) + } + local lambda1=`Ev'[1,1] + local lambda2=`Ev'[1,2] + local ev=`vp'[`j',10]+`vp'[`k',10]-`lambda1' + local ev2=max(`vp'[`j',11],`vp'[`k',11],`lambda2') + if ("`method'"=="v2"|"`method'"=="polychoricv2")&`ev'<`minegenval' { + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`lambda2' + } + else if ("`method'"=="classical"|"`method'"=="polychoric")&`ev2'<`minegenval2' { + local minegenval=`ev' + local minegenval2=`ev2' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`ev2' + } + } + } + } + } + } + else { + local ligne=`clus'-`nbitems' + local j=`kerclus'[`ligne',2] + local k=`kerclus'[`ligne',3] + if "`method'"!="centroid" { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`j'' `list`k'' [`weight'`exp'],cov + matrix `Ev'=e(Ev) + } + else if "`method'"=="polychoric"|"`method'"=="polychoricv2"{ + qui polychoricpca `list`j'' `list`k'' [`weight'`exp'] + matrix `Ev'=r(eigenvalues) + } + local lambda1=`Ev'[1,1] + local lambda2=`Ev'[1,2] + local ev=`vp'[`j',10]+`vp'[`k',10]-`lambda1' + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`lambda2' + } + else if "`method'"=="centroid" { + local nblistj:word count `list`j'' + local nblistk:word count `list`k'' + tempname v1 v2 v12 + qui genscore `list`j'',score(`v1') mean + qui genscore `list`k'',score(`v2') mean + qui gen `v12'=`v1'-`v2' + qui su `v12' [`weight'`exp'] + local varj=r(Var) + local minegenval=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`varj' + local minj `j' + local mink `k' + } + } + if `minj'<=`nbitems' { + local nomj=abbrev("``minj''",14) + } + else { + local nomj `minj' + } + if `mink'<=`nbitems' { + local nomk=abbrev("``mink''",14) + } + else { + local nomk `mink' + } + forvalues j=1/`nbitems' { + matrix `matclus'[`j',`=`i'+1']=`matclus'[`j',`i'] + } + matrix `vp'[`clus',1]=`nbitems'+`i' /*PARENT*/ + matrix `vp'[`clus',2]=`=`nbitems'-`i'' /*NUMBER OF CLUSTERS*/ + matrix `vp'[`clus',3]=`minj' /*CHILD 1*/ + matrix `vp'[`clus',4]=`mink' /*CHILD 2*/ + matrix `vp'[`clus',6]=`minegenval' /*VARIATION OF THE T or G CRITERION*/ + matrix `vp'[`clus',5]=`vp'[`=`clus'-1',5]-`vp'[`clus',6] /*T or G CRITERION*/ + matrix `vp'[`clus',7]=(`vp'[`clus',6]-`vp'[`=`clus'-1',6])/`vp'[`=`clus'-1',6] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + matrix `vp'[`clus',8]=`vp'[`=`clus'-1',8]-`minegenval' /*EXPLAINED VARIANCE*/ + matrix `vp'[`clus',9]=`vp'[`clus',8]/`totvar'*100 /*% OF EXPLAINED VARIANCE*/ + if "`method'"!="centroid" { + matrix `vp'[`clus',10]=`eigen' /*FIRST EIGEN VALUE OF THE NEW CLUSTER*/ + matrix `vp'[`clus',11]=`eigen2' /*SECOND EIGEN VALUE OF THE NEW CLUSTER*/ + } + if `vp'[`=`clus'-1',7]!=0 { + matrix `vp'[`clus',12]=(`vp'[`clus',7]-`vp'[`=`clus'-1',7])/abs(`vp'[`=`clus'-1',7]) /*2ND ORDER RELATIVE VARIATION OF THE T or G CRITERION*/ + } + matrix `indexes'[`i',1]=`i' /*PARENT*/ + matrix `indexes'[`i',2]=`nbitems'-`i' /*NUMBER OF CLUSTERS*/ + matrix `indexes'[`i',3]=`minegenval' /*VARIATION OF THE T or G CRITERION*/ + matrix `indexes'[`i',4]=`vp'[`clus',7] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + matrix `indexes'[`i',5]=max(`eigen2',`indexes'[`=`i'-1',5]) /*MAXIMUM SECOND EIGENVALUE*/ + matrix `indexes'[`i',7]=`vp'[`clus',12] /*2nd order RELATIVE VARIATION OF THE T OR G CRITERION*/ + foreach j of numlist `numlist`minj'' `numlist`mink'' { + matrix `matclus'[`j',`=`i'+1']=`clus' + } + local varlistgen + local nbvarlistgen + forvalues j=1/`=`nbitems'+`i'' { + local varlist`j' + forvalues k=1/`nbitems' { + if `matclus'[`k',`=`i'+1']==`j' { + local varlist`j' `varlist`j'' ``k'' + } + } + local nbvarlist`j': word count `varlist`j'' + local varlistgen `varlistgen' `varlist`j'' + local nbvarlistgen `nbvarlistgen' `nbvarlist`j'' + } + local newlist + foreach m in `nbvarlistgen' { + if `m'!=0 { + local newlist `newlist' `m' + } + } + if "`kernel'"!=""&`i'==`=`nbkerk'-`nbkerg'+1' { + local T=`vp'[`=`clus'-1',8] + di _col(0) in ye "init" _col(12) %4.0f `=`nbitems'-`nbkerk'+`nbkerg'' _col(52) %8.4f `T' _col(62) %8.4f `=`totvar'-`T'' _col(72) %7.3f `=`T'/`totvar'*100' "%" + } + if `clus'>`nbitems'+`nbkerk'-`nbkerg' { + matrix `threshold'[`=`nbitems'-`i'+1',3]=`minegenval' + if `clus'==`nbitems'+`nbkerk'-`nbkerg'+1 { + local relv + local percent + local relv2 + } + else { + local relv=`indexes'[`i',4]*100 + local percent % + if `indexes'[`i',7]!=. { + local relv2=`indexes'[`i',7]*100 + } + else { + local relv2=0 + } + matrix `threshold'[`=`nbitems'-`i'+1',1]=`relv' + matrix `threshold'[`=`nbitems'-`i'+1',2]=`relv2' + } + if "`method'"=="centroid" { + di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',8] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',9] "%" _col(83) _col(84) %5.2f `relv' "`percent'" _col(93) %8.2f `relv2' "`percent'" + } + else { + di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',8] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',9] "%" _col(83) %8.4f `vp'[`clus',11] _col(94) %6.2f `relv' "`percent'" _col(103) %8.2f `relv2' "`percent'" + } + } + } + matrix `indexes'[`nbitems',3]=`vp'[`=2*`nbitems'-1',5] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + matrix `indexes'[`nbitems',7]=`indexes'[`nbitems',3]/`indexes'[`=`nbitems'-1',3] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + local i=2*`nbitems'-1 + matrix `threshold'[1,1]=`vp'[`i',5]/`vp'[`i',6]*100-100 + matrix `threshold'[1,2]=(`threshold'[1,1]-`threshold'[2,1])/abs(`threshold'[2,1])*100 + matrix `threshold'[1,3]=`vp'[`i',5] + if "`method'"=="centroid" { + di in ye _col(62) %8.4f `threshold'[1,3] _col(83) %6.2f `threshold'[1,1] "`percent'" _col(93) %8.2f `threshold'[1,2] "`percent'" + } + else { + di in ye _col(62) %8.4f `threshold'[1,3] _col(94) %6.2f `threshold'[1,1] "`percent'" _col(103) %8.2f `threshold'[1,2] "`percent'" + } + local best=0 + local maxbest=0 + local best2=0 + local maxbest2=0 + local demipart=int(`nbitems'/2)+1 + forvalues i=1/`demipart' { + if `threshold'[`i',3]>`maxbest2' { + if `threshold'[`i',3]>`maxbest' { + local maxbest2=`maxbest' + local best2=`best' + local maxbest=`threshold'[`i',3] + local best=`i' + } + else { + local maxbest2=`threshold'[`i',3] + local best2=`i' + } + } + } + di in green "{hline 111}" + di + di in green "{hline 60}" + di in green "PROPOSED BEST PARTITIONS (AMONG THE `demipart' SMALLER PARTITIONS)" + di in green "{hline 60}" + di + di in yellow _col(4) "Based on the variation of the T criterion: " _col(60) in gr "Partitions in " in ye `best' " or " `best2' in gr " clusters" + return local bestvariation `best' `best2' + local bestt=0 + local bestt2=0 + local var=0 + local var2=0 + forvalues i=1/`nbitems' { + if `threshold'[`i',1]>`var2'&`i'<`demipart' { + if `threshold'[`i',1]>`var' { + local bestt2=`bestt' + local var2=`var' + local var=`threshold'[`i',1] + local bestt=`i' + } + else { + local var2=`threshold'[`i',1] + local bestt2=`i' + } + } + } + di in yellow _col(4) "Based on the research of a threshold: " _col(60) in gr "Partitions in " in ye `bestt' " or " `bestt2' in gr " clusters" + forvalues i=`=`nbitems'+1'/`=`nbitems'+`nbkerk'-`nbkerg'' { + matrix `vp'[`i',6]=`totvar'-`T' + matrix `vp'[`i',8]=`T' + matrix `vp'[`i',9]=`T'/`nbitems'*100 + } + return local bestthresold `bestt' `bestt2' + forvalues i=1/`nbitems' { + if `threshold'[`i',2]>`var2'&`i'<`demipart' { + if `threshold'[`i',2]>`var' { + local bestt2=`bestt' + local var2=`var' + local var=`threshold'[`i',2] + local bestt=`i' + } + else { + local var2=`threshold'[`i',2] + local bestt2=`i' + } + } + } + di in yellow _col(4) "Based on the research of a threshold (second order): " _col(60) in gr "Partitions in " in ye `bestt' " or " `bestt2' in gr " clusters" + return local bestthresold2 `bestt' `bestt2' +} +/******BAR CHART *******/ +if "`bar'"!="" { + drop _all + qui set obs `nbitems' + qui svmat `indexes' ,names(v) + qui gen id=`nbitems'-_n + qui replace v7=. in 1 + qui drop if id>`nbitems'-`nbkerk'+`nbkerg'-1 + label variable id "Number of clusters" + label variable v3 "T variation" + qui su v3 if id!=0 + local maxv3=ceil(r(max)*5)/5 + local minv3=floor(r(min)*5)/5 + label variable v4 "Relative T variation" + label variable v7 "Relative T variation order 2" + qui graph twoway (bar v3 id, name(bar,replace) `fsb' vert yaxis(1))(line v4 id,yaxis(2))/*(line v6 id,yaxis(3))(line v5 id,yaxis(4))*/(line v7 id,yaxis(5)) if id!=0,ylabel(`minv3'(0.2)`maxv3') xlabel(1(1)`=`nbitems'-`nbkerk'+`nbkerg'-1') +} +/****** DENDROGRAM********/ + drop _all + qui set obs `nbitems' + qui svmat `matclus' ,names(v) + local listorder + forvalues i=`nbitems'(-1)1 { + local listorder `listorder' v`i' + } + qui gen id=_n + qui sort `listorder' + + capture cluster delete clv,zap + qui cluster complete v* ,name(clv) + + qui replace clv_id=_n + qui replace clv_ord=id + qui replace clv_hgt=. + + qui gen fait=0 + qui gen clus=0 + forvalues i=2/`nbitems' { + local ligne=`nbitems'+`i'-1 + if (`vp'[`ligne',3]<=`nbitems') { + local first=`vp'[`ligne',3] + gsort +fait -v`i' +clv_id + } + else { + local first=`vp'[`ligne',4] + gsort +fait -v`i' +clv_id + } + if "`deltaT'"!="" { + qui replace clv_hgt=`vp'[`ligne',6] in 1 + } + else { + qui replace clv_hgt=100-`vp'[`ligne',9] in 1 + } + qui replace fait=1 in 1 + qui replace clus=`vp'[`ligne',1] in 1 + } +if "`dendro'"=="" { + qui gen label="" + forvalues i=1/`nbitems' { + qui replace label=abbrev("`label`i''",`abbrev') if clv_id==`i' + } + sort clv_id + if `nbitems'>`cutnumber' { + local var "Groups of variables" + local cut cutnumber(`cutnumber') /*labcutn*/ + } + else { + local var "Variables" + local cut label(label) + } + qui su clv_hgt + local tmp=r(max) + local max=floor(`tmp')+.5 + if `tmp'>`max' { + local max=`max'+.5 + } + local maxvar=`max'+5 + if "`title'"=="" { + local title "Clustering around Latent Variables (CLV)" + } + if "`caption'"!="" { + local var "`caption'" + } + if "`deltaT'"!="" { + local titleL "Variation of the T criterion" + local yl "0(.5)`max'" + } + else { + local titleL "% Unexplained Variance" + local yl "0(25)`maxvar'" + } + if "`textsize'"=="" { + local textsize: word `=min(int(`nbitems'/15)+1,5)' of medium medsmall small vsmall tiny + } + if "`horizontal'"!="" { + *matrix list clv + qui cluster dendro clv, name (dendrogram,replace) `fsd' hor ytitle("`var'") `showcount' xtitle("`titleL'") title("`title'",span) xlabel(`yl') ylabel(,angle(0) labsize(`textsize')) `cut' + } + else { + qui cluster dendro clv, name(dendrogram,replace) `fsd' xtitle("`var'") `showcount' ytitle("`titleL'") title("`title'",span) ylabel(`yl') xlabel(,labsize(`textsize')) `cut' + } + if "`savedendro'"!="" { + qui graph save dendrogram `savedendro' + } +} + +/***** END DENDROGRAM*****/ + +/**** TEST ********/ +if `cons'>`nbitems'-`nbkerk'+`nbkerg' { + di in ye "The {hi:consolidation} is not possible for a number of clusters superior to the initial number of clusters" + local cons=0 +} + + +/***** CONSOLIDATION PROCEDURE ********/ +if `cons'!=0 { + sort v`=`nbitems'-`cons'+1' + gen cut`cons'=1 + local g=1 + forvalues i=2/`nbitems' { + if v`=`nbitems'-`cons'+1'[`i']!=v`=`nbitems'-`cons'+1'[`=`i'-1'] { + local g=`g'+1 + } + qui replace cut`cons'=`g' in `i' + } + sort id + tempname group + mkmat cut`cons',matrix(`group') + + use `clvfiletmp',replace + + local n=1 + local env=1 + while (`env'==1) { + forvalues g=1/`cons' { + local list`g' + forvalues i=1/`nbitems' { + if `group'[`i',1]==`g' { + local list`g' `list`g'' ``i'' + } + } + } + di + if `n'==1 { + di in green "{hline 30}" + di in green "PARTITION BEFORE CONSOLIDATION" + di in green "{hline 30}" + } + di + local col=13 + local max=0 + local critT=0 + forvalues g=1/`cons' { + di _col(`col') in green "CLUSTER " %2.0f `g' _c + local col=`col'+12 + local tmp`g':word count `list`g'' + if `tmp`g''>`max' { + local max `tmp`g'' + } + tempvar f1`g' + if "`method'"=="centroid" { + qui genscore `list`g'',score(`f1`g'') mean + qui su `f1`g'' [`weight'`exp'] + local var=r(Var) + local critT=`critT'+`tmp`g''*`var' + qui pca `list`g'' [`weight'`exp'] ,cov + local trace=e(trace) + local explained`g'=`tmp`g''*`var'/`trace' + } + else { + if `tmp`g''>1 { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`g'' [`weight'`exp'] ,cov + matrix `Ev'=e(Ev) + local trace=e(trace) + qui predict `f1`g'' + } + else if "`method'"=="polychoric"|"`method'"=="polychoric" { + qui polychoricpca `list`g'' [`weight'`exp'] ,score(`f1`g'') nscore(1) + matrix `Ev'=r(eigenvalues) + local trace=0 + forvalues m=1/`tmp`g''{ + local trace =`trace'+`r(lambda`m')' + } + rename `f1`g''1 `f1`g'' + } + local lambda1=`Ev'[1,1] + local explained`g'=`lambda1'/`trace' + local critT=`critT'+`lambda1' + } + else { + local explained`g'=1 + qui gen `f1`g''=`list`g'' + if "`standardized'"=="" { + local critT=`critT'+1 + } + else { + qui su [`weight'`exp'] + local critT=`critT'+`r(Var)' + } + } + } + } + di + di _col(1) in green "ITEMS :" _c + forvalues i=1/`max' { + local col=15 + forvalues g=1/`cons' { + local tmpv:word `i' of `list`g'' + local tmpv=abbrev("`tmpv'",8) + di _col(`col') in ye %8s "`tmpv'" _c + local col= `col'+12 + } + di + } + local col=16 + di _col(1) in green "Expl. Var:" _c + forvalues g=1/`cons' { + di _col(`col') in ye %6.2f `=`explained`g''*100' in green "%" _c + local col= `col'+12 + } + di + di + di in green "Variance Explained : " in ye %6.3f `=`critT'/`totvar'*100' in green "%" + di in green "T criterion : " in ye %6.4f `critT' + di + di in green "{hline 21}" + di in green "CONSOLIDATION: STEP `n'" + di in green "{hline 21}" + local n=`n'+1 + local env=0 + if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + local command polychoric + } + else { + local command corr + } + forvalues i=1/`nbitems' { + local env`i'=0 + local gr=`group'[`i',1] + qui `command' ``i'' `f1`gr'' [`weight'`exp'] + local corr`i'=r(rho) + local corrs`i'=r(rho) + forvalues g=1/`cons' { + qui `command' ``i'' `f1`g'' [`weight'`exp'] + local tmpcorr=r(rho) + if `g'!=`gr'&(((`corr`i'')<(`tmpcorr')&"`method'"=="centroid")|((`corr`i'')^2<(`tmpcorr')^2& "`method'"!="centroid")) { + local env=1 + local env`i'=1 + matrix `group'[`i',1]=`g' + local corr`i'=`tmpcorr' + } + } + if `env`i''==1 { + local g=`group'[`i',1] + di in green "The variable " in ye "``i'' " in green "is assigned to the `g'th group" _c + if "`method'"!="centroid" { + di in green " (corr^2=" %6.4f in ye (`corr`i'')^2 in green " vs " in ye %6.4f (`corrs`i'')^2 in green ")" + } + else { + di in green " (corr=" %6.4f in ye (`corr`i'') in green " vs " in ye %6.4f (`corrs`i'') in green ")" + } + + } + } + if `env'==0 { + local latent + forvalues g=1/`cons' { + label variable `f1`g'' "Latent variable `g'" + if "`genlv'"!="" { + if "`replace'"!=""{ + capture drop `genlv'`g' + } + gen `genlv'`g'=`f1`g'' + } + local latent `latent' `f1`g'' + return local cluster`g' `list`g'' + } + matrix `group'=`group'' + matrix colnames `group'=`varlist' + return matrix affect=`group' + di in ye "Stability of the partition is achieved" + if `cons'<=7 { + di + di in green "{hline 42}" + di in green "CORRELATION MATRIX OF THE LATENT VARIABLES" + di in green "{hline 42}" + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+23') in green "Latent" _c + } + di + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+19') in green "variable `g'" _c + } + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di in green "Latent variable `g'" _c + forvalues h=1/`g' { + local loc=13*`h'+10 + qui corr `f1`g'' `f1`h'' [`weight'`exp'] + local rho=r(rho) + di _col(`loc') in ye %6.4f `rho' _c + } + di + } + di in green "{hline `=(`cons')*13+15'}" + di + } + if `nbind'<=800&"`biplot'"==""&"`weight'"=="" { + local max=max(`matsize',`nbind') + qui set matsize `max' + if "`addvar'"!="" { + local add `varlist' + } + if "`dim'"=="" { + local dim 1 2 + } + qui qui biplotvlab `latent' `add', name(biplot,replace) `fsbi' norow colopts(name(latent variables)) alpha(0) title(Biplot of the latent variables) labdes(size(vsmall) color(blue)) stretch(1) `std' dim(`dim') + } + else if `nbind'>800&"`biplot'"==""&"`weight'"==""{ + di in green "There is more than 800 individuals, so the {hi:biplot} option is disabled" + } + else if "`weight'"!=""&&"`biplot'"==""{ + di in green "The {hi:biplot} option is disabled because you use weights" + } + } + forvalues g=1/`cons' { + drop `f1`g'' + } + } +} +/***** END OF THE CONSOLIDATION PROCEDURE********/ + +qui set matsize `matsize' +if "`genlv'"!="" { + qui keep `id' `genlv'1-`genlv'`cons' + tempfile lvfile + qui sort `id' + qui save `lvfile',replace +} +use `clvfile',replace +if "`genlv'"!="" { + qui sort `id' + qui merge `id' using `lvfile' +} +qui drop `id' +capture drop _merge +capture cluster delete clv,zap +matrix colnames `vp'="Parent" "Number of clusters" "Child 1" "Child 2" "T" "DeltaT" "deltaT" "Explained Variance" "Explained Variance (%)" "First eigenvalue" "Second Eigenvalue" "2nd order deltaT" +if "`save'"!="" { + qui matrix `save'_vp=`vp' + qui matrix `save'_matclus=`matclus' + qui global `save'_varlist `varlist' + qui global `save'_method `method' + qui global `save'_kernel `kernel' +} + +return matrix vp=`vp' +return matrix matclus=`matclus' +return local varlist `varlist' +return local method `method' +return local kernel `kernel' +restore,not +end diff --git a/Modules/ado/personal/c/clv.sthlp b/Modules/ado/personal/c/clv.sthlp new file mode 100644 index 0000000..e402a26 --- /dev/null +++ b/Modules/ado/personal/c/clv.sthlp @@ -0,0 +1,122 @@ +{smcl} +{* 29 juillet 2019}{* version 2.17}{...} +{hline} +help for {hi:clv}{right:Jean-Benoit Hardouin} +{hline} + +{title:Clustering around latent variables } + +{p 8 14 2}{cmd:clv} [{it:varlist}] [{cmd:if} {it:exp}] [{cmd:in} {it:range}] [{cmd:weight}] +[{cmd:,} {cmdab:nostand:ardized} {cmdab:ker:nel}({it:numlist}) {cmdab:meth:od}({it:keyword}) {cmdab:cons:olidation}({it:#}) {cmd:genlv}(string) {cmdab:rep:lace} +{cmdab:noden:dro} {cmdab:saved:endro}({it:filename}[,replace]) {cmdab:cut:number}({it:#}) {cmdab:show:count} {cmdab:texts:ize}({it:string}) {cmdab:deltaT} +{cmdab:hor:izontal} {cmdab:abb:rev}({it:#}) {cmdab:tit:le}({it:string}) {cmdab:cap:tion}({it:string}) +{cmdab:bar} {cmdab:nobip:lot} {cmdab:add:var} {cmd:std} {cmd:dim}({it:string}) {cmdab:files:ave} {cmdab:dirs:ave}({it:string})] + + + + +{title:Description} + +{p 4 8 2}{cmd:clv} clusters variables around latent components. The variables are clustered by +seeking to minimize at each step the decrease of the T criterion, computed as the sum of the +first eigenvalues of the matrices of data of all the clusters. A hierarchical cluster analysis +based on this criterion is performed. A iterative consolidation procedure can be subsequently run which +allows each variable to be assigned to the latent component it is the most correlated with. + +{title:Options} + +{p 0 8 2}{cmd:Options concerning the method CLV} + +{p 4 8 2}{cmd:nostandardized} uses centered variables instead of standardized variables. + +{p 4 8 2}{cmd:kernel} defines one or several kernels of variables (variables which are clustered together in an initial step). The first number #k1 indicates that the first #k1 variables are clustered together, the second number #k2 indicates that the following #k2 variables are clustered together... + +{p 4 8 2}{cmd:method} indicates the method to cluster the variables among {it:classical} (by default) for the method described by Vigneau and Qannari, + {it:polychoric} for a use of the matrix of polychoric coefficients of correlation (instead of Pearson coefficients of correlation), {it:v2} for a modified + algorithm wich search to minimize the maximum second eigenvalue among the clusters of 2 variables and more, {it:polychoricv2} which correspond to the {it:v2} + option with the matrix of polychoric coefficients of correlation, and {it:centroid} which is defined by Vigneau and Qannari as an adaptation of CLV when + the sign of the correlation coefficients between the variables is important. + +{p 4 8 2}{cmd:consolidation} performs a consolidation procedure with the obtained partition into the specified number of clusters (by default, no consolidation procedure is performed). + +{p 4 8 2}{cmd:genlv} saves the latent variables in new variables with the defined string as prefix (followed by a number). This option must be used in conjonction with the {cmd:consolidation} option. + +{p 4 8 2}{cmd:replace} allows replacing the created variables with the {cmd:genlv} option if they already exist. + +{p 0 8 2}{cmd:Options concerning the drawing of the dendrogram} + +{p 4 8 2}{cmd:nodendro} avoids to display of the dendrogram. + +{p 4 8 2}{cmd:savedendro} saves the dendrogram in the file defined by this option. If this file already exists, it is possible to replace it with the {cmd:replace} option. + +{p 4 8 2}{cmd:cutnumber} defines the maximal number of clusters displayed in the dendrogram (40 by default). + +{p 4 8 2}{cmd:showcount} displays the number of variables in each cluster (useful with the {cmd:cutnumber} option). + +{p 4 8 2}{cmd:textsize} defines the size of the labels of the variables on the dendrogram (see {help textsizestyle}). + +{p 4 8 2}{cmd:deltaT} uses the variation of the T criterion as height variable for the dendrogram. + +{p 4 8 2}{cmd:horizontal} displays an horizontal (instead a vertical) dendrogram. + +{p 4 8 2}{cmd:abbrev} defines the length of the variables labels on the dendrogram (15 characters by default). + +{p 4 8 2}{cmd:title} defines the title of the dendrogram. + +{p 4 8 2}{cmd:caption} defines the caption of the axis of the dendrogram which indicates the names of the variables. + +{p 0 8 2}{cmd:Options concerning the others graphs} + +{p 4 8 2}{cmd:bar} displays a chart of the decrease in the T criterion at each step. + +{p 4 8 2}{cmd:nobiplot} avoids to display a biplot of the latent variables with the {cmd:consolidation} option. + +{p 4 8 2}{cmd:addvar} allows drawing the items on the graphical representation on the biplot. + +{p 4 8 2}{cmd:std} allows standardizing the latent variables for the graphical representation on the biplot. + +{p 4 8 2}{cmd:dim}({it:string}) allows choosing the axes represented on the biplot. + +{p 4 8 2}{cmd:filesave} allows saving the graphs in gph files on the default directory or on the directory defined by the {cmd:dirsave} option. + +{p 4 8 2}{cmd:dirsave}({it:string}) allows determining the directory to save the graphs (usefull with the {cmd:filesave} option). + +{p 4 8 2} If no {it:varlist} is indicated, the procedure uses the varlist from the last {cmd:clv} procedure, but does not perform the hierarchical cluster analysis. + +{title:Notes} + +{p 4 8 2} The classifications around latent variables (CLV) is defined by its authors (Vigneau and Qannari, 2003) only for continuous variables. Results with binary or ordinal variables must be interpreted with precautions. + +{p 4 8 2} Only {cmd:fweights} are allowed. The biplots are disabled if weights are used. + +{p 4 8 2} In this procedure, all the individuals with at least one missing value are omitted. + +{p 4 8 2} With the {it:polychoric} and {it:polychoricv2} methods, the {cmd:nostandardized} option is disabled. + +{p 4 8 2} This module uses the following modules downloadable on SSC: {stata ssc describe polychoric}, {stata ssc describe biplotvlab} and {stata ssc describe genscore} + +{title:Example} + + {p 4 8 2}{cmd:. clv var1-var15} /*performs the HCA procedure*/ + + {p 4 8 2}{cmd:. clv var1-var15, cons(6) bar nodendro meth(centroid)} /* performs the HCA procedure based on the centroid method followed by a consolidation procedure with 6 clusters*/ + + {p 4 8 2}{cmd:. clv, cons(3) addvar} /*performs only the consolidation procedure with 3 clusters, based on the preceeding HCA procedure*/ + +{title:Aknowledgements} + +{p 4 8 2} The author thanks Ronan Conroy for all the propositions of improvements. + +{title:Reference} + +{p 4 8 2} Vigneau E. and Qannari E. M. Clustering of variables around latent components. Communications in Statistics - Simulation and Computation. 32(4): 1131-1150, 2003. + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end} +{p 4 8 2}INSERM UMR 1246-SPHERE "MethodS in Patients-centered outcomes and HEalth ResEarch"{p_end} +{p 4 8 2}Nantes University - University of Tours{p_end} +{p 4 8 2}Institute for Research in Health 2 (IRS2), Nantes, France{p_end} +{p 4 8 2}Email: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 4 8 2}Website {browse "http://www.anaqol.org":AnaQol} diff --git a/Modules/ado/personal/c/clv212.ado b/Modules/ado/personal/c/clv212.ado new file mode 100644 index 0000000..35d7f79 --- /dev/null +++ b/Modules/ado/personal/c/clv212.ado @@ -0,0 +1,907 @@ +*! Version 2.12 1December2006 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : clv +* Clustering of variables around latent variables +* Version 2.12 : December 1st, 2006 /*savedendro option*/ +* +* Historic +* Version 1 (2005-06-11): Jean-Benoit Hardouin +* Version 1.1 (2005-07-07): Jean-Benoit Hardouin /*small bug in the consolidation process with cluster of only one variable*/ +* Version 1.2 (2005-07-08): Jean-Benoit Hardouin /*Bug in the consolidation procedure when there is negative correlation*/ +* Version 2 (2005-09-03): Jean-Benoit Hardouin /*Horizontal dendrograms (with Stata 9)*/ +* Version 2.1 (2005-09-08): Jean-Benoit Hardouin /*More flexibility to abbreviate the names of the variables (with Stata 9)*/ +* Version 2.1.1 (2005-09-08): Jean-Benoit Hardouin /*Integration of some requests of Ronan Conroy*/ +* Version 2.1.2 (2005-09-08): Jean-Benoit Hardouin /*Possibility to give a title and an X/Y caption*/ +* Version 2.2 (2005-09-11): Jean-Benoit Hardouin /*Kernel option*/ +* Version 2.3 (2005-09-12): Jean-Benoit Hardouin /*Polychoric option*/ +* Version 2.4 (2005-09-13): Jean-Benoit Hardouin /*v2 option*/ +* Version 2.5 (2005-09-21): Jean-Benoit Hardouin /*corrections*/ +* Version 2.6 (2005-10-02): Jean-Benoit Hardouin /*centroid method, biplot*/ +* Version 2.7 (2005-10-06): Jean-Benoit Hardouin /*return, multiple graphs, polychoric+consolidation*/ +* Version 2.8 (2005-10-06): Jean-Benoit Hardouin /*fweights*/ +* Version 2.9 (2006-01-26): Jean-Benoit Hardouin /*save the latent variables*/ +* Version 2.10 (2006-07-10): Jean-Benoit Hardouin /*2nd order relative variation of the T criterion*/ +* Version 2.11 (2006-10-09): Jean-Benoit Hardouin /*Size of the text in the dendrogram*/ +* Version 2.12 (2006-12-01): Jean-Benoit Hardouin /*savedendro option*/ +* +* Jean-benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences +* Department of Biostatistics - France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2005-2006 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ +program define clv,rclass +version 9.0 +syntax [varlist(default=none)] [if] [in] [fweight] [, CUTnumber(int 40) bar CONSolidation(int 0) noDENdro SAVEDendro(string) noSTANDardized deltaT HORizontal SHOWcount ABBrev(int 14) TITle(string) CAPtion(string) KERnel(numlist) METHod(string) noBIPlot ADDvar genlv(string) replace TEXTSize(string)] +preserve +tempfile clvfile +tempvar id +gen `id'=_n +qui save `clvfile',replace +local matsize=c(matsize) +local none=0 +if "`varlist'"=="" { + capture confirm matrix r(vp) + if _rc==0 { + capture confirm matrix r(matclus) + if _rc ==0 { + local none=1 + } + } + if `none'==0 { + di in red "You cannot use the {hi:clv} command without {hi:varlist} if you have not already run {hi:clv}" + error 198 + exit + } +} + +tempname matclus vp indexes + +/*********TESTS**********/ + +if `none'==1 { + matrix `vp'=r(vp) + matrix `matclus'=r(matclus) + local varlist `r(varlist)' + tokenize `varlist' + local nbitems=rowsof(`matclus') + if "`method'"!="" { + di in green "The {hi:method} option can not be modified without specification of the varlist. {hi:method} is omitted." + } + local method `r(method)' + local kernel `r(kernel)' +} +if "`method'"=="" { + local method classical +} +if ("`method'"=="polychoric"|"`method'"=="polychoricv2")&"`standardized'"!="" { + di in green "Initial variables are used with the {hi:polychoric} methods" + di in green "But the procedure is based on the matrix of the polychoric correlations" + di +} +if "`method'"!="classical"&"`method'"!="v2"&"`method'"!="centroid"&"`method'"!="polychoric"&"`method'"!="polychoricv2" { + di in red "The {hi:method} `method' is unknown" + error 198 + exit +} + +tokenize `varlist' +local nbitems : word count `varlist' +marksample touse +qui keep if `touse' + +local mat=max(`matsize',`=`nbitems'*2') +qui set matsize `mat' + +if `nbitems'<3&`none'!=1 { + di in red "You need at least 3 variables" + error 198 + exit +} + + +/*******DEFINES THE LABELS AND STANDARDIZED THE VARIABLES (IF NECESSARY)*******/ +forvalues i=1/`nbitems'{ + local label`i':variable label ``i'' + if "`label`i''"=="" { + local label`i' ``i'' + } + if "`method'"!="polychoric"&"`method'"!="polychoricv2" { + qui su ``i'' [`weight'`exp'] + local mean=r(mean) + if "`standardized'"=="" { + local sd=r(sd) + } + else { + local sd=1 + } + qui replace ``i''=(``i''-`mean')/`sd' + } +} + +tempfile clvfiletmp +qui save `clvfiletmp',replace + +qui su `1' [`weight'`exp'] +local nbind=r(sum_w) + + +local cons=`consolidation' + +/*COMPUTES THE TOTAL VARIANCE*/ + +if "`method'"!="polychoric"&"`method'"!="polychoricv2" { + local totvar=0 + forvalues i=1/`nbitems' { + qui su ``i'' [`weight'`exp'] + local totvar=`totvar'+`r(Var)' + } +} +else { + local totvar `nbitems' +} +local nbkerk=0 +local nbkerg=0 + +/***** DEFINES THE KERNEL IF NECESSARY ********/ + +if "`kernel'"!="" { + local nbkerg:word count `kernel' + local fin0=0 + forvalues i=1/`nbkerg' { + local nbi`i':word `i' of `kernel' + local nbkerk=`nbkerk'+`nbi`i'' + local deb`i'=`fin`=`i'-1''+1 + local fin`i'=`deb`i''+`nbi`i''-1 + local list`i' + forvalues j=`deb`i''/`fin`i'' { + local list`i' `list`i'' ``j'' + } + } + tempname kerclus + matrix `kerclus'=J(`=`nbkerk'-`nbkerg'',3,0) + local ligne=1 + forvalues g=1/`nbkerg' { + matrix `kerclus'[`ligne',1]=`nbitems'+`ligne' + matrix `kerclus'[`ligne',2]=`deb`g'' + matrix `kerclus'[`ligne',3]=`deb`g''+1 + local clus`g'=`nbitems'+`ligne' + local ligne=`ligne'+1 + if `nbi`g''>2 { + forvalues i=2/`=`nbi`g''-1' { + matrix `kerclus'[`ligne',1]=`nbitems'+`ligne' + matrix `kerclus'[`ligne',2]=`deb`g''+`i' + matrix `kerclus'[`ligne',3]=`nbitems'+`ligne'-1 + local clus`g'=`nbitems'+`ligne' + local ligne=`ligne'+1 + } + } + } +} +if `nbitems'<`nbkerk' { + di in red "You cannot define more variables in the {hi:kernel} option than items in the {hi:varlist}" + error 198 + exit +} + +/*******DISPLAY THE FIRST RESULTS *******/ + +di +di in green "{hline 32}" +di in green "TOTAL VARIANCE: " in ye %16.5f `totvar' +di in green "NUMBER OF INDIVIDUALS: " in ye %9.0f `nbind' +di in green "METHOD:" in ye _col(`=33-length("`method'")') "`=upper("`method'")'" +di in green "{hline 32}" +di + +if "`kernel'"!="" { + forvalues i=1/`nbkerg' { + di in green "The kernel numbered " in ye `clus`i'' in green " is composed of `nbi`i'' variables: " in ye "`list`i''" + di + } +} +else { + local nbkerk=0 + local nbkerg=0 +} + +/******** CLASSIFICATION PROCEDURE*******/ + +tempname Ev +if `none'!=1 { + matrix `matclus'=J(`nbitems',`nbitems',0) + matrix `vp'=J(`=2*`nbitems'-1',12,0) + matrix `indexes'=J(`nbitems',8,0) + forvalues i=1/`nbitems' { + matrix `matclus'[`i',1]=`i' + if "`method'"!="polychoric"&"`method'"!="polychoric" { + qui su ``i'' [`weight'`exp'] + matrix `vp'[`i',10]=r(Var) + } + else { + matrix `vp'[`i',10]=1 + } + matrix `vp'[`i',1]=`i' + matrix `vp'[`i',2]=`nbitems' + matrix `vp'[`i',8]=`totvar' + matrix `vp'[`i',9]=100 + } + matrix `vp'[`nbitems',5]=`nbitems' + if "`method'"=="centroid" { + local crit G + di in green "{hline 101}" + di in green _col(93) "2nd order" + di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(82) "Relative" _col(94) "Relative" + di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Variation" _col(93) "Variation" + di in green "{hline 101}" + } + else { + local crit T + di in green "{hline 111}" + if "`method'"=="v2"|"`method'"=="polychoricv2" { + di in green _col(84) "Maximal" _col(103) "2nd order" + } + else { + di in green _col(84) "Current" _col(103) "2nd order" + } + di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(85) "Second" _col(93) "Relative" _col(104) "Relative" + di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Eigenvalue" _col(92) "Variation" _col(103) "Variation" + di in green "{hline 111}" + } + tempname threshold + matrix `threshold'=J(`nbitems',3,0) + forvalues i=1/`=`nbitems'-1' { + local clus=`nbitems'+`i' + local minegenval=999999 + local minegenval2=999999 + forvalues k=1/`=`clus'-1' { + local list`k' + local numlist`k' + forvalues j=1/`clus' { + if (`matclus'[`j',`i']==`k') { + local list`k' `list`k'' ``j'' + local numlist`k' `numlist`k'' `j' + } + } + } + if `clus'>`nbitems'+`nbkerk'-`nbkerg' { + if "`method'"=="centroid" { + tempname centrj centrk diffjk + } + forvalues j=1/`clus' { + local nblistj:word count `list`j'' + forvalues k=`=`j'+1'/`clus' { + local nblistk:word count `list`k'' + if `nblistj'!=0&`nblistk'!=0 { + if "`method'"=="centroid" { + qui genscore `list`j'',score(`centrj') mean + qui su `centrj' [`weight'`exp'] + local Varj=r(Var) + qui genscore `list`k'',score(`centrk') mean + qui su `centrk' [`weight'`exp'] + local Vark=r(Var) + qui gen `diffjk'=`centrk'-`centrj' + qui su `diffjk' [`weight'`exp'] + local Varjk=r(Var) + drop `centrj' `centrk' `diffjk' + local ev=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`Varjk' + if `ev'<`minegenval' { + local minegenval=`ev' + local minj `j' + local mink `k' + local eigen=0 + local eigen2=0 + } + } + else { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`j'' `list`k'' [`weight'`exp'] ,cov + matrix `Ev'=e(Ev) + } + else if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + qui polychoricpca `list`j'' `list`k'' [`weight'`exp'] + matrix `Ev'=r(eigenvalues) + } + local lambda1=`Ev'[1,1] + local lambda2=`Ev'[1,2] + local ev=`vp'[`j',10]+`vp'[`k',10]-`lambda1' + local ev2=max(`vp'[`j',11],`vp'[`k',11],`lambda2') + if ("`method'"=="v2"|"`method'"=="polychoricv2")&`ev'<`minegenval' { + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`lambda2' + } + else if ("`method'"=="classical"|"`method'"=="polychoric")&`ev2'<`minegenval2' { + local minegenval=`ev' + local minegenval2=`ev2' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`ev2' + } + } + } + } + } + } + else { + local ligne=`clus'-`nbitems' + local j=`kerclus'[`ligne',2] + local k=`kerclus'[`ligne',3] + if "`method'"!="centroid" { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`j'' `list`k'' [`weight'`exp'],cov + matrix `Ev'=e(Ev) + } + else if "`method'"=="polychoric"|"`method'"=="polychoricv2"{ + qui polychoricpca `list`j'' `list`k'' [`weight'`exp'] + matrix `Ev'=r(eigenvalues) + } + local lambda1=`Ev'[1,1] + local lambda2=`Ev'[1,2] + local ev=`vp'[`j',10]+`vp'[`k',10]-`lambda1' + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`lambda2' + } + else if "`method'"=="centroid" { + local nblistj:word count `list`j'' + local nblistk:word count `list`k'' + tempname v1 v2 v12 + qui genscore `list`j'',score(`v1') mean + qui genscore `list`k'',score(`v2') mean + qui gen `v12'=`v1'-`v2' + qui su `v12' [`weight'`exp'] + local varj=r(Var) + local minegenval=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`varj' + local minj `j' + local mink `k' + } + } + if `minj'<=`nbitems' { + local nomj=abbrev("``minj''",14) + } + else { + local nomj `minj' + } + if `mink'<=`nbitems' { + local nomk=abbrev("``mink''",14) + } + else { + local nomk `mink' + } + forvalues j=1/`nbitems' { + matrix `matclus'[`j',`=`i'+1']=`matclus'[`j',`i'] + } + matrix `vp'[`clus',1]=`nbitems'+`i' /*PARENT*/ + matrix `vp'[`clus',2]=`=`nbitems'-`i'' /*NUMBER OF CLUSTERS*/ + matrix `vp'[`clus',3]=`minj' /*CHILD 1*/ + matrix `vp'[`clus',4]=`mink' /*CHILD 2*/ + matrix `vp'[`clus',6]=`minegenval' /*VARIATION OF THE T or G CRITERION*/ + matrix `vp'[`clus',5]=`vp'[`=`clus'-1',5]-`vp'[`clus',6] /*T or G CRITERION*/ + matrix `vp'[`clus',7]=(`vp'[`clus',6]-`vp'[`=`clus'-1',6])/`vp'[`=`clus'-1',6] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + matrix `vp'[`clus',8]=`vp'[`=`clus'-1',8]-`minegenval' /*EXPLAINED VARIANCE*/ + matrix `vp'[`clus',9]=`vp'[`clus',8]/`totvar'*100 /*% OF EXPLAINED VARIANCE*/ + if "`method'"!="centroid" { + matrix `vp'[`clus',10]=`eigen' /*FIRST EIGEN VALUE OF THE NEW CLUSTER*/ + matrix `vp'[`clus',11]=`eigen2' /*SECOND EIGEN VALUE OF THE NEW CLUSTER*/ + } + if `vp'[`=`clus'-1',7]!=0 { + matrix `vp'[`clus',12]=(`vp'[`clus',7]-`vp'[`=`clus'-1',7])/abs(`vp'[`=`clus'-1',7]) /*2ND ORDER RELATIVE VARIATION OF THE T or G CRITERION*/ + } + matrix `indexes'[`i',1]=`i' /*PARENT*/ + matrix `indexes'[`i',2]=`nbitems'-`i' /*NUMBER OF CLUSTERS*/ + matrix `indexes'[`i',3]=`minegenval' /*VARIATION OF THE T or G CRITERION*/ + matrix `indexes'[`i',4]=`vp'[`clus',7] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + matrix `indexes'[`i',5]=max(`eigen2',`indexes'[`=`i'-1',5]) /*MAXIMUM SECOND EIGENVALUE*/ + matrix `indexes'[`i',7]=`vp'[`clus',12] /*2nd order RELATIVE VARIATION OF THE T OR G CRITERION*/ + foreach j of numlist `numlist`minj'' `numlist`mink'' { + matrix `matclus'[`j',`=`i'+1']=`clus' + } + local varlistgen + local nbvarlistgen + forvalues j=1/`=`nbitems'+`i'' { + local varlist`j' + forvalues k=1/`nbitems' { + if `matclus'[`k',`=`i'+1']==`j' { + local varlist`j' `varlist`j'' ``k'' + } + } + local nbvarlist`j': word count `varlist`j'' + local varlistgen `varlistgen' `varlist`j'' + local nbvarlistgen `nbvarlistgen' `nbvarlist`j'' + } + local newlist + foreach m in `nbvarlistgen' { + if `m'!=0 { + local newlist `newlist' `m' + } + } + if "`kernel'"!=""&`i'==`=`nbkerk'-`nbkerg'+1' { + local T=`vp'[`=`clus'-1',8] + di _col(0) in ye "init" _col(12) %4.0f `=`nbitems'-`nbkerk'+`nbkerg'' _col(52) %8.4f `T' _col(62) %8.4f `=`totvar'-`T'' _col(72) %7.3f `=`T'/`totvar'*100' "%" + } + if `clus'>`nbitems'+`nbkerk'-`nbkerg' { + matrix `threshold'[`=`nbitems'-`i'+1',3]=`minegenval' + if `clus'==`nbitems'+`nbkerk'-`nbkerg'+1 { + local relv + local percent + local relv2 + } + else { + local relv=`indexes'[`i',4]*100 + local percent % + if `indexes'[`i',7]!=. { + local relv2=`indexes'[`i',7]*100 + } + else { + local relv2=0 + } + matrix `threshold'[`=`nbitems'-`i'+1',1]=`relv' + matrix `threshold'[`=`nbitems'-`i'+1',2]=`relv2' + } + if "`method'"=="centroid" { + di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',8] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',9] "%" _col(83) _col(84) %5.2f `relv' "`percent'" _col(93) %8.2f `relv2' "`percent'" + } + else { + di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',8] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',9] "%" _col(83) %8.4f `vp'[`clus',11] _col(94) %6.2f `relv' "`percent'" _col(103) %8.2f `relv2' "`percent'" + } + } + } + matrix `indexes'[`nbitems',3]=`vp'[`=2*`nbitems'-1',5] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + matrix `indexes'[`nbitems',7]=`indexes'[`nbitems',3]/`indexes'[`=`nbitems'-1',3] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + local i=2*`nbitems'-1 + matrix `threshold'[1,1]=`vp'[`i',5]/`vp'[`i',6]*100-100 + matrix `threshold'[1,2]=(`threshold'[1,1]-`threshold'[2,1])/abs(`threshold'[2,1])*100 + matrix `threshold'[1,3]=`vp'[`i',5] + if "`method'"=="centroid" { + di in ye _col(62) %8.4f `threshold'[1,3] _col(83) %6.2f `threshold'[1,1] "`percent'" _col(93) %8.2f `threshold'[1,2] "`percent'" + } + else { + di in ye _col(62) %8.4f `threshold'[1,3] _col(94) %6.2f `threshold'[1,1] "`percent'" _col(103) %8.2f `threshold'[1,2] "`percent'" + } + local best=0 + local maxbest=0 + local best2=0 + local maxbest2=0 + local demipart=int(`nbitems'/2)+1 + forvalues i=1/`demipart' { + if `threshold'[`i',3]>`maxbest2' { + if `threshold'[`i',3]>`maxbest' { + local maxbest2=`maxbest' + local best2=`best' + local maxbest=`threshold'[`i',3] + local best=`i' + } + else { + local maxbest2=`threshold'[`i',3] + local best2=`i' + } + } + } + di in green "{hline 111}" + di + di in green "{hline 60}" + di in green "PROPOSED BEST PARTITIONS (AMONG THE `demipart' SMALLER PARTITIONS)" + di in green "{hline 60}" + di + di in yellow _col(4) "Based on the variation of the T criterion: " _col(60) in gr "Partitions in " in ye `best' " or " `best2' in gr " clusters" + return local bestvariation `best' `best2' + local bestt=0 + local bestt2=0 + local var=0 + local var2=0 + forvalues i=1/`nbitems' { + if `threshold'[`i',1]>`var2'&`i'<`demipart' { + if `threshold'[`i',1]>`var' { + local bestt2=`bestt' + local var2=`var' + local var=`threshold'[`i',1] + local bestt=`i' + } + else { + local var2=`threshold'[`i',1] + local bestt2=`i' + } + } + } + di in yellow _col(4) "Based on the research of a threshold: " _col(60) in gr "Partitions in " in ye `bestt' " or " `bestt2' in gr " clusters" + forvalues i=`=`nbitems'+1'/`=`nbitems'+`nbkerk'-`nbkerg'' { + matrix `vp'[`i',6]=`totvar'-`T' + matrix `vp'[`i',8]=`T' + matrix `vp'[`i',9]=`T'/`nbitems'*100 + } + return local bestthresold `bestt' `bestt2' + forvalues i=1/`nbitems' { + if `threshold'[`i',2]>`var2'&`i'<`demipart' { + if `threshold'[`i',2]>`var' { + local bestt2=`bestt' + local var2=`var' + local var=`threshold'[`i',2] + local bestt=`i' + } + else { + local var2=`threshold'[`i',2] + local bestt2=`i' + } + } + } + di in yellow _col(4) "Based on the research of a threshold (second order): " _col(60) in gr "Partitions in " in ye `bestt' " or " `bestt2' in gr " clusters" + return local bestthresold2 `bestt' `bestt2' +} +/******BAR CHART *******/ +if "`bar'"!="" { + drop _all + qui set obs `nbitems' + qui svmat `indexes' ,names(v) + qui gen id=`nbitems'-_n + qui replace v7=. in 1 + qui drop if id>`nbitems'-`nbkerk'+`nbkerg'-1 + label variable id "Number of clusters" + label variable v3 "T variation" + qui su v3 if id!=0 + local maxv3=ceil(r(max)*5)/5 + local minv3=floor(r(min)*5)/5 + label variable v4 "Relative T variation" + label variable v7 "Relative T variation order 2" + graph twoway (bar v3 id, name(bar,replace) vert yaxis(1))(line v4 id,yaxis(2))/*(line v6 id,yaxis(3))(line v5 id,yaxis(4))*/(line v7 id,yaxis(5)) if id!=0,ylabel(`minv3'(0.2)`maxv3') xlabel(1(1)`=`nbitems'-`nbkerk'+`nbkerg'-1') +} +/****** DENDROGRAM********/ + drop _all + qui set obs `nbitems' + qui svmat `matclus' ,names(v) + local listorder + forvalues i=`nbitems'(-1)1 { + local listorder `listorder' v`i' + } + qui gen id=_n + qui sort `listorder' + + capture cluster delete clv,zap + qui cluster complete v* ,name(clv) + + qui replace clv_id=_n + qui replace clv_ord=id + qui replace clv_hgt=. + + qui gen fait=0 + qui gen clus=0 + forvalues i=2/`nbitems' { + local ligne=`nbitems'+`i'-1 + if (`vp'[`ligne',3]<=`nbitems') { + local first=`vp'[`ligne',3] + gsort +fait -v`i' +clv_id + } + else { + local first=`vp'[`ligne',4] + gsort +fait -v`i' +clv_id + } + if "`deltaT'"!="" { + qui replace clv_hgt=`vp'[`ligne',6] in 1 + } + else { + qui replace clv_hgt=100-`vp'[`ligne',9] in 1 + } + qui replace fait=1 in 1 + qui replace clus=`vp'[`ligne',1] in 1 + } +if "`dendro'"=="" { + qui gen label="" + forvalues i=1/`nbitems' { + qui replace label=abbrev("`label`i''",`abbrev') if clv_id==`i' + } + sort clv_id + if `nbitems'>`cutnumber' { + local var "Groups of variables" + local cut cutnumber(`cutnumber') /*labcutn*/ + } + else { + local var "Variables" + local cut label(label) + } + qui su clv_hgt + local tmp=r(max) + local max=floor(`tmp')+.5 + if `tmp'>`max' { + local max=`max'+.5 + } + local maxvar=`max'+5 + if "`title'"=="" { + local title "Clustering around Latent Variables (CLV)" + } + if "`caption'"!="" { + local var "`caption'" + } + if "`deltaT'"!="" { + local titleL "Variation of the T criterion" + local yl "0(.5)`max'" + } + else { + local titleL "% Unexplained Variance" + local yl "0(25)`maxvar'" + } + if "`textsize'"=="" { + local textsize: word `=min(int(`nbitems'/15)+1,5)' of medium medsmall small vsmall tiny + } + if "`horizontal'"!="" { + cluster dendro clv, name (dendrogram,replace) hor ytitle("`var'") `showcount' xtitle("`titleL'") title("`title'",span) xlabel(`yl') ylabel(,angle(0) labsize(`textsize')) `cut' + } + else { + cluster dendro clv, name(dendrogram,replace) xtitle("`var'") `showcount' ytitle("`titleL'") title("`title'",span) ylabel(`yl') xlabel(,labsize(`textsize')) `cut' + } + if "`savedendro'"!="" { + graph save dendrogram `savedendro' + } +} + +/***** END DENDROGRAM*****/ + +/**** TEST ********/ +if `cons'>`nbitems'-`nbkerk'+`nbkerg' { + di in ye "The {hi:consolidation} is not possible for a number of clusters superior to the initial number of clusters" + local cons=0 +} + + +/***** CONSOLIDATION PROCEDURE ********/ +if `cons'!=0 { + sort v`=`nbitems'-`cons'+1' + gen cut`cons'=1 + local g=1 + forvalues i=2/`nbitems' { + if v`=`nbitems'-`cons'+1'[`i']!=v`=`nbitems'-`cons'+1'[`=`i'-1'] { + local g=`g'+1 + } + qui replace cut`cons'=`g' in `i' + } + sort id + tempname group + mkmat cut`cons',matrix(`group') + + use `clvfiletmp',replace + + local n=1 + local env=1 + while (`env'==1) { + forvalues g=1/`cons' { + local list`g' + forvalues i=1/`nbitems' { + if `group'[`i',1]==`g' { + local list`g' `list`g'' ``i'' + } + } + } + di + if `n'==1 { + di in green "{hline 30}" + di in green "PARTITION BEFORE CONSOLIDATION" + di in green "{hline 30}" + } + di + local col=13 + local max=0 + local critT=0 + forvalues g=1/`cons' { + di _col(`col') in green "CLUSTER " %2.0f `g' _c + local col=`col'+12 + local tmp`g':word count `list`g'' + if `tmp`g''>`max' { + local max `tmp`g'' + } + tempvar f1`g' + if "`method'"=="centroid" { + qui genscore `list`g'',score(`f1`g'') mean + qui su `f1`g'' [`weight'`exp'] + local var=r(Var) + local critT=`critT'+`tmp`g''*`var' + } + else { + if `tmp`g''>1 { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`g'' [`weight'`exp'] ,cov + matrix `Ev'=e(Ev) + local trace=e(trace) + qui predict `f1`g'' + } + else if "`method'"=="polychoric"|"`method'"=="polychoric" { + qui polychoricpca `list`g'' [`weight'`exp'] ,score(`f1`g'') nscore(1) + matrix `Ev'=r(eigenvalues) + local trace=0 + forvalues m=1/`tmp`g''{ + local trace =`trace'+`r(lambda`m')' + } + rename `f1`g''1 `f1`g'' + } + local lambda1=`Ev'[1,1] + local explained`g'=`lambda1'/`trace' + local critT=`critT'+`lambda1' + } + else { + local explained`g'=1 + qui gen `f1`g''=`list`g'' + if "`standardized'"=="" { + local critT=`critT'+1 + } + else { + qui su [`weight'`exp'] + local critT=`critT'+`r(Var)' + } + } + } + } + di + di _col(1) in green "ITEMS :" _c + forvalues i=1/`max' { + local col=15 + forvalues g=1/`cons' { + local tmpv:word `i' of `list`g'' + local tmpv=abbrev("`tmpv'",8) + di _col(`col') in ye %8s "`tmpv'" _c + local col= `col'+12 + } + di + } + local col=16 + di _col(1) in green "Expl. Var:" _c + forvalues g=1/`cons' { + di _col(`col') in ye %6.2f `=`explained`g''*100' in green "%" _c + local col= `col'+12 + } + di + di + di in green "Variance Explained : " in ye %6.3f `=`critT'/`totvar'*100' in green "%" + di in green "T criterion : " in ye %6.4f `critT' + di + di in green "{hline 21}" + di in green "CONSOLIDATION: STEP `n'" + di in green "{hline 21}" + local n=`n'+1 + local env=0 + if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + local command polychoric + } + else { + local command corr + } + forvalues i=1/`nbitems' { + local env`i'=0 + local gr=`group'[`i',1] + qui `command' ``i'' `f1`gr'' [`weight'`exp'] + local corr`i'=r(rho) + local corrs`i'=r(rho) + forvalues g=1/`cons' { + qui `command' ``i'' `f1`g'' [`weight'`exp'] + local tmpcorr=r(rho) + if `g'!=`gr'&(((`corr`i'')<(`tmpcorr')&"`method'"=="centroid")|((`corr`i'')^2<(`tmpcorr')^2& "`method'"!="centroid")) { + local env=1 + local env`i'=1 + matrix `group'[`i',1]=`g' + local corr`i'=`tmpcorr' + } + } + if `env`i''==1 { + local g=`group'[`i',1] + di in green "The variable " in ye "``i'' " in green "is assigned to the `g'th group" _c + if "`method'"!="centroid" { + di in green " (corr^2=" %6.4f in ye (`corr`i'')^2 in green " vs " in ye %6.4f (`corrs`i'')^2 in green ")" + } + else { + di in green " (corr=" %6.4f in ye (`corr`i'') in green " vs " in ye %6.4f (`corrs`i'') in green ")" + } + + } + } + if `env'==0 { + local latent + forvalues g=1/`cons' { + label variable `f1`g'' "Latent variable `g'" + if "`genlv'"!="" { + if "`replace'"!=""{ + capture drop `genlv'`g' + } + gen `genlv'`g'=`f1`g'' + } + local latent `latent' `f1`g'' + return local cluster`g' `list`g'' + } + matrix `group'=`group'' + matrix colnames `group'=`varlist' + return matrix affect=`group' + di in ye "Stability of the partition is achieved" + if `cons'<=7 { + di + di in green "{hline 42}" + di in green "CORRELATION MATRIX OF THE LATENT VARIABLES" + di in green "{hline 42}" + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+23') in green "Latent" _c + } + di + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+19') in green "variable `g'" _c + } + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di in green "Latent variable `g'" _c + forvalues h=1/`g' { + local loc=13*`h'+10 + qui corr `f1`g'' `f1`h'' [`weight'`exp'] + local rho=r(rho) + di _col(`loc') in ye %6.4f `rho' _c + } + di + } + di in green "{hline `=(`cons')*13+15'}" + di + } + if `nbind'<=800&"`biplot'"==""&"`weight'"=="" { + local max=max(`matsize',`nbind') + set matsize `max' + if "`addvar'"!="" { + local add `varlist' + } + qui biplotvlab `latent' `add', name(biplot,replace) norow colopts(name(latent variables)) alpha(0) title(Biplot of the latent variables) labdes(size(vsmall) color(blue)) stretch(1) + } + else if `nbind'>800&"`biplot'"==""&"`weight'"==""{ + di in green "There is more than 800 individuals, so the {hi:biplot} option is disabled" + } + else if "`weight'"!=""&&"`biplot'"==""{ + di in green "The {hi:biplot} option is disabled because you use weights" + } + } + forvalues g=1/`cons' { + drop `f1`g'' + } + } +} +/***** END OF THE CONSOLIDATION PROCEDURE********/ + +set matsize `matsize' +if "`genlv'"!="" { + qui keep `id' `genlv'1-`genlv'`cons' + tempfile lvfile + qui sort `id' + qui save `lvfile',replace +} +use `clvfile',replace +if "`genlv'"!="" { + qui sort `id' + qui merge `id' using `lvfile' +} +qui drop `id' +capture drop _merge +capture cluster delete clv,zap +matrix colnames `vp'="Parent" "Number of clusters" "Child 1" "Child 2" "T" "DeltaT" "deltaT" "Explained Variance" "Explained Variance (%)" "First eigenvalue" "Second Eigenvalue" "2nd order deltaT" +return matrix vp=`vp' +return matrix matclus=`matclus' +return local varlist `varlist' +return local method `method' +return local kernel `kernel' +restore,not +end diff --git a/Modules/ado/personal/c/clv214.ado b/Modules/ado/personal/c/clv214.ado new file mode 100644 index 0000000..bcb4db5 --- /dev/null +++ b/Modules/ado/personal/c/clv214.ado @@ -0,0 +1,916 @@ +*! Version 2.14 20May2010 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : clv +* Clustering of variables around latent variables +* Version 2.14 : May 20th, 2010 /*dim and std options for biplots*/ +* +* Historic +* Version 1 (2005-06-11): Jean-Benoit Hardouin +* Version 1.1 (2005-07-07): Jean-Benoit Hardouin /*small bug in the consolidation process with cluster of only one variable*/ +* Version 1.2 (2005-07-08): Jean-Benoit Hardouin /*Bug in the consolidation procedure when there is negative correlation*/ +* Version 2 (2005-09-03): Jean-Benoit Hardouin /*Horizontal dendrograms (with Stata 9)*/ +* Version 2.1 (2005-09-08): Jean-Benoit Hardouin /*More flexibility to abbreviate the names of the variables (with Stata 9)*/ +* Version 2.1.1 (2005-09-08): Jean-Benoit Hardouin /*Integration of some requests of Ronan Conroy*/ +* Version 2.1.2 (2005-09-08): Jean-Benoit Hardouin /*Possibility to give a title and an X/Y caption*/ +* Version 2.2 (2005-09-11): Jean-Benoit Hardouin /*Kernel option*/ +* Version 2.3 (2005-09-12): Jean-Benoit Hardouin /*Polychoric option*/ +* Version 2.4 (2005-09-13): Jean-Benoit Hardouin /*v2 option*/ +* Version 2.5 (2005-09-21): Jean-Benoit Hardouin /*corrections*/ +* Version 2.6 (2005-10-02): Jean-Benoit Hardouin /*centroid method, biplot*/ +* Version 2.7 (2005-10-06): Jean-Benoit Hardouin /*return, multiple graphs, polychoric+consolidation*/ +* Version 2.8 (2005-10-06): Jean-Benoit Hardouin /*fweights*/ +* Version 2.9 (2006-01-26): Jean-Benoit Hardouin /*save the latent variables*/ +* Version 2.10 (2006-07-10): Jean-Benoit Hardouin /*2nd order relative variation of the T criterion*/ +* Version 2.11 (2006-10-09): Jean-Benoit Hardouin /*Size of the text in the dendrogram*/ +* Version 2.12 (2006-12-01): Jean-Benoit Hardouin /*savedendro option*/ +* Version 2.13 (2010-05-12): Jean-Benoit Hardouin /*corrections of bugs in KERNEL option and with METHOD(centroid)*/ +* Version 2.14 (2010-05-20): Jean-Benoit Hardouin /*DIM and STD options for biplots*/ +* +* Jean-benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences +* Department of Biostatistics - France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2005-2006, 2010 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ +program define clv,rclass +version 9.0 +syntax [varlist(default=none)] [if] [in] [fweight] [, CUTnumber(int 40) bar CONSolidation(int 0) noDENdro SAVEDendro(string) noSTANDardized deltaT HORizontal SHOWcount ABBrev(int 14) TITle(string) CAPtion(string) KERnel(numlist) METHod(string) noBIPlot ADDvar genlv(string) replace TEXTSize(string) std dim(string)] +preserve +tempfile clvfile +tempvar id +gen `id'=_n +qui save `clvfile',replace +local matsize=c(matsize) +local none=0 +if "`varlist'"=="" { + capture confirm matrix r(vp) + if _rc==0 { + capture confirm matrix r(matclus) + if _rc ==0 { + local none=1 + } + } + if `none'==0 { + di in red "You cannot use the {hi:clv} command without {hi:varlist} if you have not already run {hi:clv}" + error 198 + exit + } +} + +tempname matclus vp indexes + +/*********TESTS**********/ + +if `none'==1 { + matrix `vp'=r(vp) + matrix `matclus'=r(matclus) + local varlist `r(varlist)' + tokenize `varlist' + local nbitems=rowsof(`matclus') + if "`method'"!="" { + di in green "The {hi:method} option can not be modified without specification of the varlist. {hi:method} is omitted." + } + local method `r(method)' + local kernel `r(kernel)' +} +if "`method'"=="" { + local method classical +} +if ("`method'"=="polychoric"|"`method'"=="polychoricv2")&"`standardized'"!="" { + di in green "Initial variables are used with the {hi:polychoric} methods" + di in green "But the procedure is based on the matrix of the polychoric correlations" + di +} +if "`method'"!="classical"&"`method'"!="v2"&"`method'"!="centroid"&"`method'"!="polychoric"&"`method'"!="polychoricv2" { + di in red "The {hi:method} `method' is unknown" + error 198 + exit +} + +tokenize `varlist' +local nbitems : word count `varlist' +marksample touse +qui keep if `touse' + +local mat=max(`matsize',`=`nbitems'*2') +qui set matsize `mat' + +if `nbitems'<3&`none'!=1 { + di in red "You need at least 3 variables" + error 198 + exit +} + + +/*******DEFINES THE LABELS AND STANDARDIZED THE VARIABLES (IF NECESSARY)*******/ +forvalues i=1/`nbitems'{ + local label`i':variable label ``i'' + if "`label`i''"=="" { + local label`i' ``i'' + } + if "`method'"!="polychoric"&"`method'"!="polychoricv2" { + qui su ``i'' [`weight'`exp'] + local mean=r(mean) + if "`standardized'"=="" { + local sd=r(sd) + } + else { + local sd=1 + } + qui replace ``i''=(``i''-`mean')/`sd' + } +} + +tempfile clvfiletmp +qui save `clvfiletmp',replace + +qui su `1' [`weight'`exp'] +local nbind=r(sum_w) + + +local cons=`consolidation' + +/*COMPUTES THE TOTAL VARIANCE*/ + +if "`method'"!="polychoric"&"`method'"!="polychoricv2" { + local totvar=0 + forvalues i=1/`nbitems' { + qui su ``i'' [`weight'`exp'] + local totvar=`totvar'+`r(Var)' + } +} +else { + local totvar `nbitems' +} +local nbkerk=0 +local nbkerg=0 + +/***** DEFINES THE KERNEL IF NECESSARY ********/ + +if "`kernel'"!="" { + local nbkerg:word count `kernel' + local fin0=0 + forvalues i=1/`nbkerg' { + local nbi`i':word `i' of `kernel' + local nbkerk=`nbkerk'+`nbi`i'' + local deb`i'=`fin`=`i'-1''+1 + local fin`i'=`deb`i''+`nbi`i''-1 + local list`i' + forvalues j=`deb`i''/`fin`i'' { + local list`i' `list`i'' ``j'' + } + } + tempname kerclus + matrix `kerclus'=J(`=`nbkerk'-`nbkerg'',3,0) + local ligne=1 + forvalues g=1/`nbkerg' { + matrix `kerclus'[`ligne',1]=`nbitems'+`ligne' + matrix `kerclus'[`ligne',2]=`deb`g'' + matrix `kerclus'[`ligne',3]=`deb`g''+1 + local clus`g'=`nbitems'+`ligne' + local ligne=`ligne'+1 + if `nbi`g''>2 { + forvalues i=2/`=`nbi`g''-1' { + matrix `kerclus'[`ligne',1]=`nbitems'+`ligne' + matrix `kerclus'[`ligne',2]=`deb`g''+`i' + matrix `kerclus'[`ligne',3]=`nbitems'+`ligne'-1 + local clus`g'=`nbitems'+`ligne' + local ligne=`ligne'+1 + } + } + local eigen2=0 + } +} +if `nbitems'<`nbkerk' { + di in red "You cannot define more variables in the {hi:kernel} option than items in the {hi:varlist}" + error 198 + exit +} + +/*******DISPLAY THE FIRST RESULTS *******/ + +di +di in green "{hline 32}" +di in green "TOTAL VARIANCE: " in ye %16.5f `totvar' +di in green "NUMBER OF INDIVIDUALS: " in ye %9.0f `nbind' +di in green "METHOD:" in ye _col(`=33-length("`method'")') "`=upper("`method'")'" +di in green "{hline 32}" +di + +if "`kernel'"!="" { + forvalues i=1/`nbkerg' { + di in green "The kernel numbered " in ye `clus`i'' in green " is composed of `nbi`i'' variables: " in ye "`list`i''" + di + } +} +else { + local nbkerk=0 + local nbkerg=0 +} + +/******** CLASSIFICATION PROCEDURE*******/ + +tempname Ev +if `none'!=1 { + matrix `matclus'=J(`nbitems',`nbitems',0) + matrix `vp'=J(`=2*`nbitems'-1',12,0) + matrix `indexes'=J(`nbitems',8,0) + forvalues i=1/`nbitems' { + matrix `matclus'[`i',1]=`i' + if "`method'"!="polychoric"&"`method'"!="polychoric" { + qui su ``i'' [`weight'`exp'] + matrix `vp'[`i',10]=r(Var) + } + else { + matrix `vp'[`i',10]=1 + } + matrix `vp'[`i',1]=`i' + matrix `vp'[`i',2]=`nbitems' + matrix `vp'[`i',8]=`totvar' + matrix `vp'[`i',9]=100 + } + matrix `vp'[`nbitems',5]=`nbitems' + if "`method'"=="centroid" { + local crit G + di in green "{hline 101}" + di in green _col(93) "2nd order" + di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(82) "Relative" _col(94) "Relative" + di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Variation" _col(93) "Variation" + di in green "{hline 101}" + } + else { + local crit T + di in green "{hline 111}" + if "`method'"=="v2"|"`method'"=="polychoricv2" { + di in green _col(84) "Maximal" _col(103) "2nd order" + } + else { + di in green _col(84) "Current" _col(103) "2nd order" + } + di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(85) "Second" _col(93) "Relative" _col(104) "Relative" + di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Eigenvalue" _col(92) "Variation" _col(103) "Variation" + di in green "{hline 111}" + } + tempname threshold + matrix `threshold'=J(`nbitems',3,0) + forvalues i=1/`=`nbitems'-1' { + local clus=`nbitems'+`i' + local minegenval=999999 + local minegenval2=999999 + forvalues k=1/`=`clus'-1' { + local list`k' + local numlist`k' + forvalues j=1/`clus' { + if (`matclus'[`j',`i']==`k') { + local list`k' `list`k'' ``j'' + local numlist`k' `numlist`k'' `j' + } + } + } + if `clus'>`nbitems'+`nbkerk'-`nbkerg' { + if "`method'"=="centroid" { + tempname centrj centrk diffjk + } + forvalues j=1/`clus' { + local nblistj:word count `list`j'' + forvalues k=`=`j'+1'/`clus' { + local nblistk:word count `list`k'' + if `nblistj'!=0&`nblistk'!=0 { + if "`method'"=="centroid" { + qui genscore `list`j'',score(`centrj') mean + qui su `centrj' [`weight'`exp'] + local Varj=r(Var) + qui genscore `list`k'',score(`centrk') mean + qui su `centrk' [`weight'`exp'] + local Vark=r(Var) + qui gen `diffjk'=`centrk'-`centrj' + qui su `diffjk' [`weight'`exp'] + local Varjk=r(Var) + drop `centrj' `centrk' `diffjk' + local ev=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`Varjk' + if `ev'<`minegenval' { + local minegenval=`ev' + local minj `j' + local mink `k' + local eigen=0 + local eigen2=0 + } + } + else { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`j'' `list`k'' [`weight'`exp'] ,cov + matrix `Ev'=e(Ev) + } + else if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + qui polychoricpca `list`j'' `list`k'' [`weight'`exp'] + matrix `Ev'=r(eigenvalues) + } + local lambda1=`Ev'[1,1] + local lambda2=`Ev'[1,2] + local ev=`vp'[`j',10]+`vp'[`k',10]-`lambda1' + local ev2=max(`vp'[`j',11],`vp'[`k',11],`lambda2') + if ("`method'"=="v2"|"`method'"=="polychoricv2")&`ev'<`minegenval' { + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`lambda2' + } + else if ("`method'"=="classical"|"`method'"=="polychoric")&`ev2'<`minegenval2' { + local minegenval=`ev' + local minegenval2=`ev2' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`ev2' + } + } + } + } + } + } + else { + local ligne=`clus'-`nbitems' + local j=`kerclus'[`ligne',2] + local k=`kerclus'[`ligne',3] + if "`method'"!="centroid" { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`j'' `list`k'' [`weight'`exp'],cov + matrix `Ev'=e(Ev) + } + else if "`method'"=="polychoric"|"`method'"=="polychoricv2"{ + qui polychoricpca `list`j'' `list`k'' [`weight'`exp'] + matrix `Ev'=r(eigenvalues) + } + local lambda1=`Ev'[1,1] + local lambda2=`Ev'[1,2] + local ev=`vp'[`j',10]+`vp'[`k',10]-`lambda1' + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`lambda2' + } + else if "`method'"=="centroid" { + local nblistj:word count `list`j'' + local nblistk:word count `list`k'' + tempname v1 v2 v12 + qui genscore `list`j'',score(`v1') mean + qui genscore `list`k'',score(`v2') mean + qui gen `v12'=`v1'-`v2' + qui su `v12' [`weight'`exp'] + local varj=r(Var) + local minegenval=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`varj' + local minj `j' + local mink `k' + } + } + if `minj'<=`nbitems' { + local nomj=abbrev("``minj''",14) + } + else { + local nomj `minj' + } + if `mink'<=`nbitems' { + local nomk=abbrev("``mink''",14) + } + else { + local nomk `mink' + } + forvalues j=1/`nbitems' { + matrix `matclus'[`j',`=`i'+1']=`matclus'[`j',`i'] + } + matrix `vp'[`clus',1]=`nbitems'+`i' /*PARENT*/ + matrix `vp'[`clus',2]=`=`nbitems'-`i'' /*NUMBER OF CLUSTERS*/ + matrix `vp'[`clus',3]=`minj' /*CHILD 1*/ + matrix `vp'[`clus',4]=`mink' /*CHILD 2*/ + matrix `vp'[`clus',6]=`minegenval' /*VARIATION OF THE T or G CRITERION*/ + matrix `vp'[`clus',5]=`vp'[`=`clus'-1',5]-`vp'[`clus',6] /*T or G CRITERION*/ + matrix `vp'[`clus',7]=(`vp'[`clus',6]-`vp'[`=`clus'-1',6])/`vp'[`=`clus'-1',6] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + matrix `vp'[`clus',8]=`vp'[`=`clus'-1',8]-`minegenval' /*EXPLAINED VARIANCE*/ + matrix `vp'[`clus',9]=`vp'[`clus',8]/`totvar'*100 /*% OF EXPLAINED VARIANCE*/ + if "`method'"!="centroid" { + matrix `vp'[`clus',10]=`eigen' /*FIRST EIGEN VALUE OF THE NEW CLUSTER*/ + matrix `vp'[`clus',11]=`eigen2' /*SECOND EIGEN VALUE OF THE NEW CLUSTER*/ + } + if `vp'[`=`clus'-1',7]!=0 { + matrix `vp'[`clus',12]=(`vp'[`clus',7]-`vp'[`=`clus'-1',7])/abs(`vp'[`=`clus'-1',7]) /*2ND ORDER RELATIVE VARIATION OF THE T or G CRITERION*/ + } + matrix `indexes'[`i',1]=`i' /*PARENT*/ + matrix `indexes'[`i',2]=`nbitems'-`i' /*NUMBER OF CLUSTERS*/ + matrix `indexes'[`i',3]=`minegenval' /*VARIATION OF THE T or G CRITERION*/ + matrix `indexes'[`i',4]=`vp'[`clus',7] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + matrix `indexes'[`i',5]=max(`eigen2',`indexes'[`=`i'-1',5]) /*MAXIMUM SECOND EIGENVALUE*/ + matrix `indexes'[`i',7]=`vp'[`clus',12] /*2nd order RELATIVE VARIATION OF THE T OR G CRITERION*/ + foreach j of numlist `numlist`minj'' `numlist`mink'' { + matrix `matclus'[`j',`=`i'+1']=`clus' + } + local varlistgen + local nbvarlistgen + forvalues j=1/`=`nbitems'+`i'' { + local varlist`j' + forvalues k=1/`nbitems' { + if `matclus'[`k',`=`i'+1']==`j' { + local varlist`j' `varlist`j'' ``k'' + } + } + local nbvarlist`j': word count `varlist`j'' + local varlistgen `varlistgen' `varlist`j'' + local nbvarlistgen `nbvarlistgen' `nbvarlist`j'' + } + local newlist + foreach m in `nbvarlistgen' { + if `m'!=0 { + local newlist `newlist' `m' + } + } + if "`kernel'"!=""&`i'==`=`nbkerk'-`nbkerg'+1' { + local T=`vp'[`=`clus'-1',8] + di _col(0) in ye "init" _col(12) %4.0f `=`nbitems'-`nbkerk'+`nbkerg'' _col(52) %8.4f `T' _col(62) %8.4f `=`totvar'-`T'' _col(72) %7.3f `=`T'/`totvar'*100' "%" + } + if `clus'>`nbitems'+`nbkerk'-`nbkerg' { + matrix `threshold'[`=`nbitems'-`i'+1',3]=`minegenval' + if `clus'==`nbitems'+`nbkerk'-`nbkerg'+1 { + local relv + local percent + local relv2 + } + else { + local relv=`indexes'[`i',4]*100 + local percent % + if `indexes'[`i',7]!=. { + local relv2=`indexes'[`i',7]*100 + } + else { + local relv2=0 + } + matrix `threshold'[`=`nbitems'-`i'+1',1]=`relv' + matrix `threshold'[`=`nbitems'-`i'+1',2]=`relv2' + } + if "`method'"=="centroid" { + di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',8] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',9] "%" _col(83) _col(84) %5.2f `relv' "`percent'" _col(93) %8.2f `relv2' "`percent'" + } + else { + di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',8] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',9] "%" _col(83) %8.4f `vp'[`clus',11] _col(94) %6.2f `relv' "`percent'" _col(103) %8.2f `relv2' "`percent'" + } + } + } + matrix `indexes'[`nbitems',3]=`vp'[`=2*`nbitems'-1',5] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + matrix `indexes'[`nbitems',7]=`indexes'[`nbitems',3]/`indexes'[`=`nbitems'-1',3] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + local i=2*`nbitems'-1 + matrix `threshold'[1,1]=`vp'[`i',5]/`vp'[`i',6]*100-100 + matrix `threshold'[1,2]=(`threshold'[1,1]-`threshold'[2,1])/abs(`threshold'[2,1])*100 + matrix `threshold'[1,3]=`vp'[`i',5] + if "`method'"=="centroid" { + di in ye _col(62) %8.4f `threshold'[1,3] _col(83) %6.2f `threshold'[1,1] "`percent'" _col(93) %8.2f `threshold'[1,2] "`percent'" + } + else { + di in ye _col(62) %8.4f `threshold'[1,3] _col(94) %6.2f `threshold'[1,1] "`percent'" _col(103) %8.2f `threshold'[1,2] "`percent'" + } + local best=0 + local maxbest=0 + local best2=0 + local maxbest2=0 + local demipart=int(`nbitems'/2)+1 + forvalues i=1/`demipart' { + if `threshold'[`i',3]>`maxbest2' { + if `threshold'[`i',3]>`maxbest' { + local maxbest2=`maxbest' + local best2=`best' + local maxbest=`threshold'[`i',3] + local best=`i' + } + else { + local maxbest2=`threshold'[`i',3] + local best2=`i' + } + } + } + di in green "{hline 111}" + di + di in green "{hline 60}" + di in green "PROPOSED BEST PARTITIONS (AMONG THE `demipart' SMALLER PARTITIONS)" + di in green "{hline 60}" + di + di in yellow _col(4) "Based on the variation of the T criterion: " _col(60) in gr "Partitions in " in ye `best' " or " `best2' in gr " clusters" + return local bestvariation `best' `best2' + local bestt=0 + local bestt2=0 + local var=0 + local var2=0 + forvalues i=1/`nbitems' { + if `threshold'[`i',1]>`var2'&`i'<`demipart' { + if `threshold'[`i',1]>`var' { + local bestt2=`bestt' + local var2=`var' + local var=`threshold'[`i',1] + local bestt=`i' + } + else { + local var2=`threshold'[`i',1] + local bestt2=`i' + } + } + } + di in yellow _col(4) "Based on the research of a threshold: " _col(60) in gr "Partitions in " in ye `bestt' " or " `bestt2' in gr " clusters" + forvalues i=`=`nbitems'+1'/`=`nbitems'+`nbkerk'-`nbkerg'' { + matrix `vp'[`i',6]=`totvar'-`T' + matrix `vp'[`i',8]=`T' + matrix `vp'[`i',9]=`T'/`nbitems'*100 + } + return local bestthresold `bestt' `bestt2' + forvalues i=1/`nbitems' { + if `threshold'[`i',2]>`var2'&`i'<`demipart' { + if `threshold'[`i',2]>`var' { + local bestt2=`bestt' + local var2=`var' + local var=`threshold'[`i',2] + local bestt=`i' + } + else { + local var2=`threshold'[`i',2] + local bestt2=`i' + } + } + } + di in yellow _col(4) "Based on the research of a threshold (second order): " _col(60) in gr "Partitions in " in ye `bestt' " or " `bestt2' in gr " clusters" + return local bestthresold2 `bestt' `bestt2' +} +/******BAR CHART *******/ +if "`bar'"!="" { + drop _all + qui set obs `nbitems' + qui svmat `indexes' ,names(v) + qui gen id=`nbitems'-_n + qui replace v7=. in 1 + qui drop if id>`nbitems'-`nbkerk'+`nbkerg'-1 + label variable id "Number of clusters" + label variable v3 "T variation" + qui su v3 if id!=0 + local maxv3=ceil(r(max)*5)/5 + local minv3=floor(r(min)*5)/5 + label variable v4 "Relative T variation" + label variable v7 "Relative T variation order 2" + graph twoway (bar v3 id, name(bar,replace) vert yaxis(1))(line v4 id,yaxis(2))/*(line v6 id,yaxis(3))(line v5 id,yaxis(4))*/(line v7 id,yaxis(5)) if id!=0,ylabel(`minv3'(0.2)`maxv3') xlabel(1(1)`=`nbitems'-`nbkerk'+`nbkerg'-1') +} +/****** DENDROGRAM********/ + drop _all + qui set obs `nbitems' + qui svmat `matclus' ,names(v) + local listorder + forvalues i=`nbitems'(-1)1 { + local listorder `listorder' v`i' + } + qui gen id=_n + qui sort `listorder' + + capture cluster delete clv,zap + qui cluster complete v* ,name(clv) + + qui replace clv_id=_n + qui replace clv_ord=id + qui replace clv_hgt=. + + qui gen fait=0 + qui gen clus=0 + forvalues i=2/`nbitems' { + local ligne=`nbitems'+`i'-1 + if (`vp'[`ligne',3]<=`nbitems') { + local first=`vp'[`ligne',3] + gsort +fait -v`i' +clv_id + } + else { + local first=`vp'[`ligne',4] + gsort +fait -v`i' +clv_id + } + if "`deltaT'"!="" { + qui replace clv_hgt=`vp'[`ligne',6] in 1 + } + else { + qui replace clv_hgt=100-`vp'[`ligne',9] in 1 + } + qui replace fait=1 in 1 + qui replace clus=`vp'[`ligne',1] in 1 + } +if "`dendro'"=="" { + qui gen label="" + forvalues i=1/`nbitems' { + qui replace label=abbrev("`label`i''",`abbrev') if clv_id==`i' + } + sort clv_id + if `nbitems'>`cutnumber' { + local var "Groups of variables" + local cut cutnumber(`cutnumber') /*labcutn*/ + } + else { + local var "Variables" + local cut label(label) + } + qui su clv_hgt + local tmp=r(max) + local max=floor(`tmp')+.5 + if `tmp'>`max' { + local max=`max'+.5 + } + local maxvar=`max'+5 + if "`title'"=="" { + local title "Clustering around Latent Variables (CLV)" + } + if "`caption'"!="" { + local var "`caption'" + } + if "`deltaT'"!="" { + local titleL "Variation of the T criterion" + local yl "0(.5)`max'" + } + else { + local titleL "% Unexplained Variance" + local yl "0(25)`maxvar'" + } + if "`textsize'"=="" { + local textsize: word `=min(int(`nbitems'/15)+1,5)' of medium medsmall small vsmall tiny + } + if "`horizontal'"!="" { + cluster dendro clv, name (dendrogram,replace) hor ytitle("`var'") `showcount' xtitle("`titleL'") title("`title'",span) xlabel(`yl') ylabel(,angle(0) labsize(`textsize')) `cut' + } + else { + cluster dendro clv, name(dendrogram,replace) xtitle("`var'") `showcount' ytitle("`titleL'") title("`title'",span) ylabel(`yl') xlabel(,labsize(`textsize')) `cut' + } + if "`savedendro'"!="" { + graph save dendrogram `savedendro' + } +} + +/***** END DENDROGRAM*****/ + +/**** TEST ********/ +if `cons'>`nbitems'-`nbkerk'+`nbkerg' { + di in ye "The {hi:consolidation} is not possible for a number of clusters superior to the initial number of clusters" + local cons=0 +} + + +/***** CONSOLIDATION PROCEDURE ********/ +if `cons'!=0 { + sort v`=`nbitems'-`cons'+1' + gen cut`cons'=1 + local g=1 + forvalues i=2/`nbitems' { + if v`=`nbitems'-`cons'+1'[`i']!=v`=`nbitems'-`cons'+1'[`=`i'-1'] { + local g=`g'+1 + } + qui replace cut`cons'=`g' in `i' + } + sort id + tempname group + mkmat cut`cons',matrix(`group') + + use `clvfiletmp',replace + + local n=1 + local env=1 + while (`env'==1) { + forvalues g=1/`cons' { + local list`g' + forvalues i=1/`nbitems' { + if `group'[`i',1]==`g' { + local list`g' `list`g'' ``i'' + } + } + } + di + if `n'==1 { + di in green "{hline 30}" + di in green "PARTITION BEFORE CONSOLIDATION" + di in green "{hline 30}" + } + di + local col=13 + local max=0 + local critT=0 + forvalues g=1/`cons' { + di _col(`col') in green "CLUSTER " %2.0f `g' _c + local col=`col'+12 + local tmp`g':word count `list`g'' + if `tmp`g''>`max' { + local max `tmp`g'' + } + tempvar f1`g' + if "`method'"=="centroid" { + qui genscore `list`g'',score(`f1`g'') mean + qui su `f1`g'' [`weight'`exp'] + local var=r(Var) + local critT=`critT'+`tmp`g''*`var' + qui pca `list`g'' [`weight'`exp'] ,cov + local trace=e(trace) + local explained`g'=`tmp`g''*`var'/`trace' + } + else { + if `tmp`g''>1 { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`g'' [`weight'`exp'] ,cov + matrix `Ev'=e(Ev) + local trace=e(trace) + qui predict `f1`g'' + } + else if "`method'"=="polychoric"|"`method'"=="polychoric" { + qui polychoricpca `list`g'' [`weight'`exp'] ,score(`f1`g'') nscore(1) + matrix `Ev'=r(eigenvalues) + local trace=0 + forvalues m=1/`tmp`g''{ + local trace =`trace'+`r(lambda`m')' + } + rename `f1`g''1 `f1`g'' + } + local lambda1=`Ev'[1,1] + local explained`g'=`lambda1'/`trace' + local critT=`critT'+`lambda1' + } + else { + local explained`g'=1 + qui gen `f1`g''=`list`g'' + if "`standardized'"=="" { + local critT=`critT'+1 + } + else { + qui su [`weight'`exp'] + local critT=`critT'+`r(Var)' + } + } + } + } + di + di _col(1) in green "ITEMS :" _c + forvalues i=1/`max' { + local col=15 + forvalues g=1/`cons' { + local tmpv:word `i' of `list`g'' + local tmpv=abbrev("`tmpv'",8) + di _col(`col') in ye %8s "`tmpv'" _c + local col= `col'+12 + } + di + } + local col=16 + di _col(1) in green "Expl. Var:" _c + forvalues g=1/`cons' { + di _col(`col') in ye %6.2f `=`explained`g''*100' in green "%" _c + local col= `col'+12 + } + di + di + di in green "Variance Explained : " in ye %6.3f `=`critT'/`totvar'*100' in green "%" + di in green "T criterion : " in ye %6.4f `critT' + di + di in green "{hline 21}" + di in green "CONSOLIDATION: STEP `n'" + di in green "{hline 21}" + local n=`n'+1 + local env=0 + if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + local command polychoric + } + else { + local command corr + } + forvalues i=1/`nbitems' { + local env`i'=0 + local gr=`group'[`i',1] + qui `command' ``i'' `f1`gr'' [`weight'`exp'] + local corr`i'=r(rho) + local corrs`i'=r(rho) + forvalues g=1/`cons' { + qui `command' ``i'' `f1`g'' [`weight'`exp'] + local tmpcorr=r(rho) + if `g'!=`gr'&(((`corr`i'')<(`tmpcorr')&"`method'"=="centroid")|((`corr`i'')^2<(`tmpcorr')^2& "`method'"!="centroid")) { + local env=1 + local env`i'=1 + matrix `group'[`i',1]=`g' + local corr`i'=`tmpcorr' + } + } + if `env`i''==1 { + local g=`group'[`i',1] + di in green "The variable " in ye "``i'' " in green "is assigned to the `g'th group" _c + if "`method'"!="centroid" { + di in green " (corr^2=" %6.4f in ye (`corr`i'')^2 in green " vs " in ye %6.4f (`corrs`i'')^2 in green ")" + } + else { + di in green " (corr=" %6.4f in ye (`corr`i'') in green " vs " in ye %6.4f (`corrs`i'') in green ")" + } + + } + } + if `env'==0 { + local latent + forvalues g=1/`cons' { + label variable `f1`g'' "Latent variable `g'" + if "`genlv'"!="" { + if "`replace'"!=""{ + capture drop `genlv'`g' + } + gen `genlv'`g'=`f1`g'' + } + local latent `latent' `f1`g'' + return local cluster`g' `list`g'' + } + matrix `group'=`group'' + matrix colnames `group'=`varlist' + return matrix affect=`group' + di in ye "Stability of the partition is achieved" + if `cons'<=7 { + di + di in green "{hline 42}" + di in green "CORRELATION MATRIX OF THE LATENT VARIABLES" + di in green "{hline 42}" + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+23') in green "Latent" _c + } + di + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+19') in green "variable `g'" _c + } + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di in green "Latent variable `g'" _c + forvalues h=1/`g' { + local loc=13*`h'+10 + qui corr `f1`g'' `f1`h'' [`weight'`exp'] + local rho=r(rho) + di _col(`loc') in ye %6.4f `rho' _c + } + di + } + di in green "{hline `=(`cons')*13+15'}" + di + } + if `nbind'<=800&"`biplot'"==""&"`weight'"=="" { + local max=max(`matsize',`nbind') + qui set matsize `max' + if "`addvar'"!="" { + local add `varlist' + } + if "`dim'"=="" { + local dim 1 2 + } + qui biplotvlab `latent' `add', name(biplot,replace) norow colopts(name(latent variables)) alpha(0) title(Biplot of the latent variables) labdes(size(vsmall) color(blue)) stretch(1) `std' dim(`dim') + } + else if `nbind'>800&"`biplot'"==""&"`weight'"==""{ + di in green "There is more than 800 individuals, so the {hi:biplot} option is disabled" + } + else if "`weight'"!=""&&"`biplot'"==""{ + di in green "The {hi:biplot} option is disabled because you use weights" + } + } + forvalues g=1/`cons' { + drop `f1`g'' + } + } +} +/***** END OF THE CONSOLIDATION PROCEDURE********/ + +qui set matsize `matsize' +if "`genlv'"!="" { + qui keep `id' `genlv'1-`genlv'`cons' + tempfile lvfile + qui sort `id' + qui save `lvfile',replace +} +use `clvfile',replace +if "`genlv'"!="" { + qui sort `id' + qui merge `id' using `lvfile' +} +qui drop `id' +capture drop _merge +capture cluster delete clv,zap +matrix colnames `vp'="Parent" "Number of clusters" "Child 1" "Child 2" "T" "DeltaT" "deltaT" "Explained Variance" "Explained Variance (%)" "First eigenvalue" "Second Eigenvalue" "2nd order deltaT" +return matrix vp=`vp' +return matrix matclus=`matclus' +return local varlist `varlist' +return local method `method' +return local kernel `kernel' +restore,not +end diff --git a/Modules/ado/personal/c/clv215.ado b/Modules/ado/personal/c/clv215.ado new file mode 100644 index 0000000..8839023 --- /dev/null +++ b/Modules/ado/personal/c/clv215.ado @@ -0,0 +1,946 @@ +*! Version 2.15 14April2014 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : clv +* Clustering of variables around latent variables +* Version 2.14 : May 20th, 2010 /*dim and std options for biplots*/ +* +* Historic +* Version 1 (2005-06-11): Jean-Benoit Hardouin +* Version 1.1 (2005-07-07): Jean-Benoit Hardouin /*small bug in the consolidation process with cluster of only one variable*/ +* Version 1.2 (2005-07-08): Jean-Benoit Hardouin /*Bug in the consolidation procedure when there is negative correlation*/ +* Version 2 (2005-09-03): Jean-Benoit Hardouin /*Horizontal dendrograms (with Stata 9)*/ +* Version 2.1 (2005-09-08): Jean-Benoit Hardouin /*More flexibility to abbreviate the names of the variables (with Stata 9)*/ +* Version 2.1.1 (2005-09-08): Jean-Benoit Hardouin /*Integration of some requests of Ronan Conroy*/ +* Version 2.1.2 (2005-09-08): Jean-Benoit Hardouin /*Possibility to give a title and an X/Y caption*/ +* Version 2.2 (2005-09-11): Jean-Benoit Hardouin /*Kernel option*/ +* Version 2.3 (2005-09-12): Jean-Benoit Hardouin /*Polychoric option*/ +* Version 2.4 (2005-09-13): Jean-Benoit Hardouin /*v2 option*/ +* Version 2.5 (2005-09-21): Jean-Benoit Hardouin /*corrections*/ +* Version 2.6 (2005-10-02): Jean-Benoit Hardouin /*centroid method, biplot*/ +* Version 2.7 (2005-10-06): Jean-Benoit Hardouin /*return, multiple graphs, polychoric+consolidation*/ +* Version 2.8 (2005-10-06): Jean-Benoit Hardouin /*fweights*/ +* Version 2.9 (2006-01-26): Jean-Benoit Hardouin /*save the latent variables*/ +* Version 2.10 (2006-07-10): Jean-Benoit Hardouin /*2nd order relative variation of the T criterion*/ +* Version 2.11 (2006-10-09): Jean-Benoit Hardouin /*Size of the text in the dendrogram*/ +* Version 2.12 (2006-12-01): Jean-Benoit Hardouin /*savedendro option*/ +* Version 2.13 (2010-05-12): Jean-Benoit Hardouin /*corrections of bugs in KERNEL option and with METHOD(centroid)*/ +* Version 2.14 (2010-05-20): Jean-Benoit Hardouin /*DIM and STD options for biplots*/ +* Version 2.15 (2014-04-14): Jean-Benoit Hardouin /*save and use options*/ +* +* Jean-benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences +* Department of Biostatistics - France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://anaqol.sphere-nantes.fr +* +* Copyright 2005-2006, 2010, 2014 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ +program define clv215,rclass +version 9.0 +syntax [varlist(default=none)] [if] [in] [fweight] [, CUTnumber(int 40) bar CONSolidation(int 0) noDENdro SAVEDendro(string) noSTANDardized deltaT HORizontal SHOWcount ABBrev(int 14) TITle(string) CAPtion(string) KERnel(numlist) METHod(string) noBIPlot ADDvar genlv(string) replace TEXTSize(string) std dim(string) save(string) use(string)] +preserve +tempfile clvfile +tempvar id +gen `id'=_n +qui save `clvfile',replace +local matsize=c(matsize) +local none=0 +if "`varlist'"==""&"`use'"=="" { + capture confirm matrix r(vp) + if _rc==0 { + capture confirm matrix r(matclus) + if _rc ==0 { + local none=1 + } + } + if `none'==0 { + di in red "You cannot use the {hi:clv} command without {hi:varlist} if you have not already run {hi:clv}" + error 198 + exit + } +} + +tempname matclus vp indexes + +/*********TESTS**********/ + +if "`use'"!="" { + local error=0 + capture matrix `vp'=`use'_vp + if _rc!=0 { + local error=_rc + } + capture matrix `matclus'=`use'_matclus + if _rc!=0 { + local error=_rc + } + local varlist $`use'_varlist + local method $`use'_method + local kernel $`use'_kernel + if "`varlist'"==""|"`method'"=="" { + local error=1 + } + if `error'!=0 { + di in red "You cannot use the {hi:use} option without a preliminary use of the {hi:save} option" + error 198 + exit + } +} +if `none'==1 { + matrix `vp'=r(vp) + matrix `matclus'=r(matclus) + local varlist `r(varlist)' + tokenize `varlist' + local nbitems=rowsof(`matclus') + if "`method'"!="" { + di in green "The {hi:method} option can not be modified without specification of the varlist. {hi:method} is omitted." + } + local method `r(method)' + local kernel `r(kernel)' +} +if "`method'"=="" { + local method classical +} +if ("`method'"=="polychoric"|"`method'"=="polychoricv2")&"`standardized'"!="" { + di in green "Initial variables are used with the {hi:polychoric} methods" + di in green "But the procedure is based on the matrix of the polychoric correlations" + di +} +if "`method'"!="classical"&"`method'"!="v2"&"`method'"!="centroid"&"`method'"!="polychoric"&"`method'"!="polychoricv2" { + di in red "The {hi:method} `method' is unknown" + error 198 + exit +} + +tokenize `varlist' +local nbitems : word count `varlist' +marksample touse +qui keep if `touse' + +local mat=max(`matsize',`=`nbitems'*2') +qui set matsize `mat' + +if `nbitems'<3&`none'!=1 { + di in red "You need at least 3 variables" + error 198 + exit +} + + +/*******DEFINES THE LABELS AND STANDARDIZED THE VARIABLES (IF NECESSARY)*******/ +forvalues i=1/`nbitems'{ + local label`i':variable label ``i'' + if "`label`i''"=="" { + local label`i' ``i'' + } + if "`method'"!="polychoric"&"`method'"!="polychoricv2" { + qui su ``i'' [`weight'`exp'] + local mean=r(mean) + if "`standardized'"=="" { + local sd=r(sd) + } + else { + local sd=1 + } + qui replace ``i''=(``i''-`mean')/`sd' + } +} + +tempfile clvfiletmp +qui save `clvfiletmp',replace + +qui su `1' [`weight'`exp'] +local nbind=r(sum_w) + + +local cons=`consolidation' + +/*COMPUTES THE TOTAL VARIANCE*/ + +if "`method'"!="polychoric"&"`method'"!="polychoricv2" { + local totvar=0 + forvalues i=1/`nbitems' { + qui su ``i'' [`weight'`exp'] + local totvar=`totvar'+`r(Var)' + } +} +else { + local totvar `nbitems' +} +local nbkerk=0 +local nbkerg=0 + +/***** DEFINES THE KERNEL IF NECESSARY ********/ + +if "`kernel'"!="" { + local nbkerg:word count `kernel' + local fin0=0 + forvalues i=1/`nbkerg' { + local nbi`i':word `i' of `kernel' + local nbkerk=`nbkerk'+`nbi`i'' + local deb`i'=`fin`=`i'-1''+1 + local fin`i'=`deb`i''+`nbi`i''-1 + local list`i' + forvalues j=`deb`i''/`fin`i'' { + local list`i' `list`i'' ``j'' + } + } + tempname kerclus + matrix `kerclus'=J(`=`nbkerk'-`nbkerg'',3,0) + local ligne=1 + forvalues g=1/`nbkerg' { + matrix `kerclus'[`ligne',1]=`nbitems'+`ligne' + matrix `kerclus'[`ligne',2]=`deb`g'' + matrix `kerclus'[`ligne',3]=`deb`g''+1 + local clus`g'=`nbitems'+`ligne' + local ligne=`ligne'+1 + if `nbi`g''>2 { + forvalues i=2/`=`nbi`g''-1' { + matrix `kerclus'[`ligne',1]=`nbitems'+`ligne' + matrix `kerclus'[`ligne',2]=`deb`g''+`i' + matrix `kerclus'[`ligne',3]=`nbitems'+`ligne'-1 + local clus`g'=`nbitems'+`ligne' + local ligne=`ligne'+1 + } + } + local eigen2=0 + } +} +if `nbitems'<`nbkerk' { + di in red "You cannot define more variables in the {hi:kernel} option than items in the {hi:varlist}" + error 198 + exit +} + +/*******DISPLAY THE FIRST RESULTS *******/ + +di +di in green "{hline 32}" +di in green "TOTAL VARIANCE: " in ye %16.5f `totvar' +di in green "NUMBER OF INDIVIDUALS: " in ye %9.0f `nbind' +di in green "METHOD:" in ye _col(`=33-length("`method'")') "`=upper("`method'")'" +di in green "{hline 32}" +di + +if "`kernel'"!="" { + forvalues i=1/`nbkerg' { + di in green "The kernel numbered " in ye `clus`i'' in green " is composed of `nbi`i'' variables: " in ye "`list`i''" + di + } +} +else { + local nbkerk=0 + local nbkerg=0 +} + +/******** CLASSIFICATION PROCEDURE*******/ + +tempname Ev +if `none'!=1 { + matrix `matclus'=J(`nbitems',`nbitems',0) + matrix `vp'=J(`=2*`nbitems'-1',12,0) + matrix `indexes'=J(`nbitems',8,0) + forvalues i=1/`nbitems' { + matrix `matclus'[`i',1]=`i' + if "`method'"!="polychoric"&"`method'"!="polychoric" { + qui su ``i'' [`weight'`exp'] + matrix `vp'[`i',10]=r(Var) + } + else { + matrix `vp'[`i',10]=1 + } + matrix `vp'[`i',1]=`i' + matrix `vp'[`i',2]=`nbitems' + matrix `vp'[`i',8]=`totvar' + matrix `vp'[`i',9]=100 + } + matrix `vp'[`nbitems',5]=`nbitems' + if "`method'"=="centroid" { + local crit G + di in green "{hline 101}" + di in green _col(93) "2nd order" + di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(82) "Relative" _col(94) "Relative" + di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Variation" _col(93) "Variation" + di in green "{hline 101}" + } + else { + local crit T + di in green "{hline 111}" + if "`method'"=="v2"|"`method'"=="polychoricv2" { + di in green _col(84) "Maximal" _col(103) "2nd order" + } + else { + di in green _col(84) "Current" _col(103) "2nd order" + } + di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(85) "Second" _col(93) "Relative" _col(104) "Relative" + di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Eigenvalue" _col(92) "Variation" _col(103) "Variation" + di in green "{hline 111}" + } + tempname threshold + matrix `threshold'=J(`nbitems',3,0) + forvalues i=1/`=`nbitems'-1' { + local clus=`nbitems'+`i' + local minegenval=999999 + local minegenval2=999999 + forvalues k=1/`=`clus'-1' { + local list`k' + local numlist`k' + forvalues j=1/`clus' { + if (`matclus'[`j',`i']==`k') { + local list`k' `list`k'' ``j'' + local numlist`k' `numlist`k'' `j' + } + } + } + if `clus'>`nbitems'+`nbkerk'-`nbkerg' { + if "`method'"=="centroid" { + tempname centrj centrk diffjk + } + forvalues j=1/`clus' { + local nblistj:word count `list`j'' + forvalues k=`=`j'+1'/`clus' { + local nblistk:word count `list`k'' + if `nblistj'!=0&`nblistk'!=0 { + if "`method'"=="centroid" { + qui genscore `list`j'',score(`centrj') mean + qui su `centrj' [`weight'`exp'] + local Varj=r(Var) + qui genscore `list`k'',score(`centrk') mean + qui su `centrk' [`weight'`exp'] + local Vark=r(Var) + qui gen `diffjk'=`centrk'-`centrj' + qui su `diffjk' [`weight'`exp'] + local Varjk=r(Var) + drop `centrj' `centrk' `diffjk' + local ev=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`Varjk' + if `ev'<`minegenval' { + local minegenval=`ev' + local minj `j' + local mink `k' + local eigen=0 + local eigen2=0 + } + } + else { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`j'' `list`k'' [`weight'`exp'] ,cov + matrix `Ev'=e(Ev) + } + else if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + qui polychoricpca `list`j'' `list`k'' [`weight'`exp'] + matrix `Ev'=r(eigenvalues) + } + local lambda1=`Ev'[1,1] + local lambda2=`Ev'[1,2] + local ev=`vp'[`j',10]+`vp'[`k',10]-`lambda1' + local ev2=max(`vp'[`j',11],`vp'[`k',11],`lambda2') + if ("`method'"=="v2"|"`method'"=="polychoricv2")&`ev'<`minegenval' { + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`lambda2' + } + else if ("`method'"=="classical"|"`method'"=="polychoric")&`ev2'<`minegenval2' { + local minegenval=`ev' + local minegenval2=`ev2' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`ev2' + } + } + } + } + } + } + else { + local ligne=`clus'-`nbitems' + local j=`kerclus'[`ligne',2] + local k=`kerclus'[`ligne',3] + if "`method'"!="centroid" { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`j'' `list`k'' [`weight'`exp'],cov + matrix `Ev'=e(Ev) + } + else if "`method'"=="polychoric"|"`method'"=="polychoricv2"{ + qui polychoricpca `list`j'' `list`k'' [`weight'`exp'] + matrix `Ev'=r(eigenvalues) + } + local lambda1=`Ev'[1,1] + local lambda2=`Ev'[1,2] + local ev=`vp'[`j',10]+`vp'[`k',10]-`lambda1' + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`lambda2' + } + else if "`method'"=="centroid" { + local nblistj:word count `list`j'' + local nblistk:word count `list`k'' + tempname v1 v2 v12 + qui genscore `list`j'',score(`v1') mean + qui genscore `list`k'',score(`v2') mean + qui gen `v12'=`v1'-`v2' + qui su `v12' [`weight'`exp'] + local varj=r(Var) + local minegenval=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`varj' + local minj `j' + local mink `k' + } + } + if `minj'<=`nbitems' { + local nomj=abbrev("``minj''",14) + } + else { + local nomj `minj' + } + if `mink'<=`nbitems' { + local nomk=abbrev("``mink''",14) + } + else { + local nomk `mink' + } + forvalues j=1/`nbitems' { + matrix `matclus'[`j',`=`i'+1']=`matclus'[`j',`i'] + } + matrix `vp'[`clus',1]=`nbitems'+`i' /*PARENT*/ + matrix `vp'[`clus',2]=`=`nbitems'-`i'' /*NUMBER OF CLUSTERS*/ + matrix `vp'[`clus',3]=`minj' /*CHILD 1*/ + matrix `vp'[`clus',4]=`mink' /*CHILD 2*/ + matrix `vp'[`clus',6]=`minegenval' /*VARIATION OF THE T or G CRITERION*/ + matrix `vp'[`clus',5]=`vp'[`=`clus'-1',5]-`vp'[`clus',6] /*T or G CRITERION*/ + matrix `vp'[`clus',7]=(`vp'[`clus',6]-`vp'[`=`clus'-1',6])/`vp'[`=`clus'-1',6] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + matrix `vp'[`clus',8]=`vp'[`=`clus'-1',8]-`minegenval' /*EXPLAINED VARIANCE*/ + matrix `vp'[`clus',9]=`vp'[`clus',8]/`totvar'*100 /*% OF EXPLAINED VARIANCE*/ + if "`method'"!="centroid" { + matrix `vp'[`clus',10]=`eigen' /*FIRST EIGEN VALUE OF THE NEW CLUSTER*/ + matrix `vp'[`clus',11]=`eigen2' /*SECOND EIGEN VALUE OF THE NEW CLUSTER*/ + } + if `vp'[`=`clus'-1',7]!=0 { + matrix `vp'[`clus',12]=(`vp'[`clus',7]-`vp'[`=`clus'-1',7])/abs(`vp'[`=`clus'-1',7]) /*2ND ORDER RELATIVE VARIATION OF THE T or G CRITERION*/ + } + matrix `indexes'[`i',1]=`i' /*PARENT*/ + matrix `indexes'[`i',2]=`nbitems'-`i' /*NUMBER OF CLUSTERS*/ + matrix `indexes'[`i',3]=`minegenval' /*VARIATION OF THE T or G CRITERION*/ + matrix `indexes'[`i',4]=`vp'[`clus',7] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + matrix `indexes'[`i',5]=max(`eigen2',`indexes'[`=`i'-1',5]) /*MAXIMUM SECOND EIGENVALUE*/ + matrix `indexes'[`i',7]=`vp'[`clus',12] /*2nd order RELATIVE VARIATION OF THE T OR G CRITERION*/ + foreach j of numlist `numlist`minj'' `numlist`mink'' { + matrix `matclus'[`j',`=`i'+1']=`clus' + } + local varlistgen + local nbvarlistgen + forvalues j=1/`=`nbitems'+`i'' { + local varlist`j' + forvalues k=1/`nbitems' { + if `matclus'[`k',`=`i'+1']==`j' { + local varlist`j' `varlist`j'' ``k'' + } + } + local nbvarlist`j': word count `varlist`j'' + local varlistgen `varlistgen' `varlist`j'' + local nbvarlistgen `nbvarlistgen' `nbvarlist`j'' + } + local newlist + foreach m in `nbvarlistgen' { + if `m'!=0 { + local newlist `newlist' `m' + } + } + if "`kernel'"!=""&`i'==`=`nbkerk'-`nbkerg'+1' { + local T=`vp'[`=`clus'-1',8] + di _col(0) in ye "init" _col(12) %4.0f `=`nbitems'-`nbkerk'+`nbkerg'' _col(52) %8.4f `T' _col(62) %8.4f `=`totvar'-`T'' _col(72) %7.3f `=`T'/`totvar'*100' "%" + } + if `clus'>`nbitems'+`nbkerk'-`nbkerg' { + matrix `threshold'[`=`nbitems'-`i'+1',3]=`minegenval' + if `clus'==`nbitems'+`nbkerk'-`nbkerg'+1 { + local relv + local percent + local relv2 + } + else { + local relv=`indexes'[`i',4]*100 + local percent % + if `indexes'[`i',7]!=. { + local relv2=`indexes'[`i',7]*100 + } + else { + local relv2=0 + } + matrix `threshold'[`=`nbitems'-`i'+1',1]=`relv' + matrix `threshold'[`=`nbitems'-`i'+1',2]=`relv2' + } + if "`method'"=="centroid" { + di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',8] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',9] "%" _col(83) _col(84) %5.2f `relv' "`percent'" _col(93) %8.2f `relv2' "`percent'" + } + else { + di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',8] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',9] "%" _col(83) %8.4f `vp'[`clus',11] _col(94) %6.2f `relv' "`percent'" _col(103) %8.2f `relv2' "`percent'" + } + } + } + matrix `indexes'[`nbitems',3]=`vp'[`=2*`nbitems'-1',5] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + matrix `indexes'[`nbitems',7]=`indexes'[`nbitems',3]/`indexes'[`=`nbitems'-1',3] /*RELATIVE VARIATION OF THE T OR G CRITERION*/ + local i=2*`nbitems'-1 + matrix `threshold'[1,1]=`vp'[`i',5]/`vp'[`i',6]*100-100 + matrix `threshold'[1,2]=(`threshold'[1,1]-`threshold'[2,1])/abs(`threshold'[2,1])*100 + matrix `threshold'[1,3]=`vp'[`i',5] + if "`method'"=="centroid" { + di in ye _col(62) %8.4f `threshold'[1,3] _col(83) %6.2f `threshold'[1,1] "`percent'" _col(93) %8.2f `threshold'[1,2] "`percent'" + } + else { + di in ye _col(62) %8.4f `threshold'[1,3] _col(94) %6.2f `threshold'[1,1] "`percent'" _col(103) %8.2f `threshold'[1,2] "`percent'" + } + local best=0 + local maxbest=0 + local best2=0 + local maxbest2=0 + local demipart=int(`nbitems'/2)+1 + forvalues i=1/`demipart' { + if `threshold'[`i',3]>`maxbest2' { + if `threshold'[`i',3]>`maxbest' { + local maxbest2=`maxbest' + local best2=`best' + local maxbest=`threshold'[`i',3] + local best=`i' + } + else { + local maxbest2=`threshold'[`i',3] + local best2=`i' + } + } + } + di in green "{hline 111}" + di + di in green "{hline 60}" + di in green "PROPOSED BEST PARTITIONS (AMONG THE `demipart' SMALLER PARTITIONS)" + di in green "{hline 60}" + di + di in yellow _col(4) "Based on the variation of the T criterion: " _col(60) in gr "Partitions in " in ye `best' " or " `best2' in gr " clusters" + return local bestvariation `best' `best2' + local bestt=0 + local bestt2=0 + local var=0 + local var2=0 + forvalues i=1/`nbitems' { + if `threshold'[`i',1]>`var2'&`i'<`demipart' { + if `threshold'[`i',1]>`var' { + local bestt2=`bestt' + local var2=`var' + local var=`threshold'[`i',1] + local bestt=`i' + } + else { + local var2=`threshold'[`i',1] + local bestt2=`i' + } + } + } + di in yellow _col(4) "Based on the research of a threshold: " _col(60) in gr "Partitions in " in ye `bestt' " or " `bestt2' in gr " clusters" + forvalues i=`=`nbitems'+1'/`=`nbitems'+`nbkerk'-`nbkerg'' { + matrix `vp'[`i',6]=`totvar'-`T' + matrix `vp'[`i',8]=`T' + matrix `vp'[`i',9]=`T'/`nbitems'*100 + } + return local bestthresold `bestt' `bestt2' + forvalues i=1/`nbitems' { + if `threshold'[`i',2]>`var2'&`i'<`demipart' { + if `threshold'[`i',2]>`var' { + local bestt2=`bestt' + local var2=`var' + local var=`threshold'[`i',2] + local bestt=`i' + } + else { + local var2=`threshold'[`i',2] + local bestt2=`i' + } + } + } + di in yellow _col(4) "Based on the research of a threshold (second order): " _col(60) in gr "Partitions in " in ye `bestt' " or " `bestt2' in gr " clusters" + return local bestthresold2 `bestt' `bestt2' +} +/******BAR CHART *******/ +if "`bar'"!="" { + drop _all + qui set obs `nbitems' + qui svmat `indexes' ,names(v) + qui gen id=`nbitems'-_n + qui replace v7=. in 1 + qui drop if id>`nbitems'-`nbkerk'+`nbkerg'-1 + label variable id "Number of clusters" + label variable v3 "T variation" + qui su v3 if id!=0 + local maxv3=ceil(r(max)*5)/5 + local minv3=floor(r(min)*5)/5 + label variable v4 "Relative T variation" + label variable v7 "Relative T variation order 2" + graph twoway (bar v3 id, name(bar,replace) vert yaxis(1))(line v4 id,yaxis(2))/*(line v6 id,yaxis(3))(line v5 id,yaxis(4))*/(line v7 id,yaxis(5)) if id!=0,ylabel(`minv3'(0.2)`maxv3') xlabel(1(1)`=`nbitems'-`nbkerk'+`nbkerg'-1') +} +/****** DENDROGRAM********/ + drop _all + qui set obs `nbitems' + qui svmat `matclus' ,names(v) + local listorder + forvalues i=`nbitems'(-1)1 { + local listorder `listorder' v`i' + } + qui gen id=_n + qui sort `listorder' + + capture cluster delete clv,zap + qui cluster complete v* ,name(clv) + + qui replace clv_id=_n + qui replace clv_ord=id + qui replace clv_hgt=. + + qui gen fait=0 + qui gen clus=0 + forvalues i=2/`nbitems' { + local ligne=`nbitems'+`i'-1 + if (`vp'[`ligne',3]<=`nbitems') { + local first=`vp'[`ligne',3] + gsort +fait -v`i' +clv_id + } + else { + local first=`vp'[`ligne',4] + gsort +fait -v`i' +clv_id + } + if "`deltaT'"!="" { + qui replace clv_hgt=`vp'[`ligne',6] in 1 + } + else { + qui replace clv_hgt=100-`vp'[`ligne',9] in 1 + } + qui replace fait=1 in 1 + qui replace clus=`vp'[`ligne',1] in 1 + } +if "`dendro'"=="" { + qui gen label="" + forvalues i=1/`nbitems' { + qui replace label=abbrev("`label`i''",`abbrev') if clv_id==`i' + } + sort clv_id + if `nbitems'>`cutnumber' { + local var "Groups of variables" + local cut cutnumber(`cutnumber') /*labcutn*/ + } + else { + local var "Variables" + local cut label(label) + } + qui su clv_hgt + local tmp=r(max) + local max=floor(`tmp')+.5 + if `tmp'>`max' { + local max=`max'+.5 + } + local maxvar=`max'+5 + if "`title'"=="" { + local title "Clustering around Latent Variables (CLV)" + } + if "`caption'"!="" { + local var "`caption'" + } + if "`deltaT'"!="" { + local titleL "Variation of the T criterion" + local yl "0(.5)`max'" + } + else { + local titleL "% Unexplained Variance" + local yl "0(25)`maxvar'" + } + if "`textsize'"=="" { + local textsize: word `=min(int(`nbitems'/15)+1,5)' of medium medsmall small vsmall tiny + } + if "`horizontal'"!="" { + cluster dendro clv, name (dendrogram,replace) hor ytitle("`var'") `showcount' xtitle("`titleL'") title("`title'",span) xlabel(`yl') ylabel(,angle(0) labsize(`textsize')) `cut' + } + else { + cluster dendro clv, name(dendrogram,replace) xtitle("`var'") `showcount' ytitle("`titleL'") title("`title'",span) ylabel(`yl') xlabel(,labsize(`textsize')) `cut' + } + if "`savedendro'"!="" { + graph save dendrogram `savedendro' + } +} + +/***** END DENDROGRAM*****/ + +/**** TEST ********/ +if `cons'>`nbitems'-`nbkerk'+`nbkerg' { + di in ye "The {hi:consolidation} is not possible for a number of clusters superior to the initial number of clusters" + local cons=0 +} + + +/***** CONSOLIDATION PROCEDURE ********/ +if `cons'!=0 { + sort v`=`nbitems'-`cons'+1' + gen cut`cons'=1 + local g=1 + forvalues i=2/`nbitems' { + if v`=`nbitems'-`cons'+1'[`i']!=v`=`nbitems'-`cons'+1'[`=`i'-1'] { + local g=`g'+1 + } + qui replace cut`cons'=`g' in `i' + } + sort id + tempname group + mkmat cut`cons',matrix(`group') + + use `clvfiletmp',replace + + local n=1 + local env=1 + while (`env'==1) { + forvalues g=1/`cons' { + local list`g' + forvalues i=1/`nbitems' { + if `group'[`i',1]==`g' { + local list`g' `list`g'' ``i'' + } + } + } + di + if `n'==1 { + di in green "{hline 30}" + di in green "PARTITION BEFORE CONSOLIDATION" + di in green "{hline 30}" + } + di + local col=13 + local max=0 + local critT=0 + forvalues g=1/`cons' { + di _col(`col') in green "CLUSTER " %2.0f `g' _c + local col=`col'+12 + local tmp`g':word count `list`g'' + if `tmp`g''>`max' { + local max `tmp`g'' + } + tempvar f1`g' + if "`method'"=="centroid" { + qui genscore `list`g'',score(`f1`g'') mean + qui su `f1`g'' [`weight'`exp'] + local var=r(Var) + local critT=`critT'+`tmp`g''*`var' + qui pca `list`g'' [`weight'`exp'] ,cov + local trace=e(trace) + local explained`g'=`tmp`g''*`var'/`trace' + } + else { + if `tmp`g''>1 { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`g'' [`weight'`exp'] ,cov + matrix `Ev'=e(Ev) + local trace=e(trace) + qui predict `f1`g'' + } + else if "`method'"=="polychoric"|"`method'"=="polychoric" { + qui polychoricpca `list`g'' [`weight'`exp'] ,score(`f1`g'') nscore(1) + matrix `Ev'=r(eigenvalues) + local trace=0 + forvalues m=1/`tmp`g''{ + local trace =`trace'+`r(lambda`m')' + } + rename `f1`g''1 `f1`g'' + } + local lambda1=`Ev'[1,1] + local explained`g'=`lambda1'/`trace' + local critT=`critT'+`lambda1' + } + else { + local explained`g'=1 + qui gen `f1`g''=`list`g'' + if "`standardized'"=="" { + local critT=`critT'+1 + } + else { + qui su [`weight'`exp'] + local critT=`critT'+`r(Var)' + } + } + } + } + di + di _col(1) in green "ITEMS :" _c + forvalues i=1/`max' { + local col=15 + forvalues g=1/`cons' { + local tmpv:word `i' of `list`g'' + local tmpv=abbrev("`tmpv'",8) + di _col(`col') in ye %8s "`tmpv'" _c + local col= `col'+12 + } + di + } + local col=16 + di _col(1) in green "Expl. Var:" _c + forvalues g=1/`cons' { + di _col(`col') in ye %6.2f `=`explained`g''*100' in green "%" _c + local col= `col'+12 + } + di + di + di in green "Variance Explained : " in ye %6.3f `=`critT'/`totvar'*100' in green "%" + di in green "T criterion : " in ye %6.4f `critT' + di + di in green "{hline 21}" + di in green "CONSOLIDATION: STEP `n'" + di in green "{hline 21}" + local n=`n'+1 + local env=0 + if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + local command polychoric + } + else { + local command corr + } + forvalues i=1/`nbitems' { + local env`i'=0 + local gr=`group'[`i',1] + qui `command' ``i'' `f1`gr'' [`weight'`exp'] + local corr`i'=r(rho) + local corrs`i'=r(rho) + forvalues g=1/`cons' { + qui `command' ``i'' `f1`g'' [`weight'`exp'] + local tmpcorr=r(rho) + if `g'!=`gr'&(((`corr`i'')<(`tmpcorr')&"`method'"=="centroid")|((`corr`i'')^2<(`tmpcorr')^2& "`method'"!="centroid")) { + local env=1 + local env`i'=1 + matrix `group'[`i',1]=`g' + local corr`i'=`tmpcorr' + } + } + if `env`i''==1 { + local g=`group'[`i',1] + di in green "The variable " in ye "``i'' " in green "is assigned to the `g'th group" _c + if "`method'"!="centroid" { + di in green " (corr^2=" %6.4f in ye (`corr`i'')^2 in green " vs " in ye %6.4f (`corrs`i'')^2 in green ")" + } + else { + di in green " (corr=" %6.4f in ye (`corr`i'') in green " vs " in ye %6.4f (`corrs`i'') in green ")" + } + + } + } + if `env'==0 { + local latent + forvalues g=1/`cons' { + label variable `f1`g'' "Latent variable `g'" + if "`genlv'"!="" { + if "`replace'"!=""{ + capture drop `genlv'`g' + } + gen `genlv'`g'=`f1`g'' + } + local latent `latent' `f1`g'' + return local cluster`g' `list`g'' + } + matrix `group'=`group'' + matrix colnames `group'=`varlist' + return matrix affect=`group' + di in ye "Stability of the partition is achieved" + if `cons'<=7 { + di + di in green "{hline 42}" + di in green "CORRELATION MATRIX OF THE LATENT VARIABLES" + di in green "{hline 42}" + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+23') in green "Latent" _c + } + di + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+19') in green "variable `g'" _c + } + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di in green "Latent variable `g'" _c + forvalues h=1/`g' { + local loc=13*`h'+10 + qui corr `f1`g'' `f1`h'' [`weight'`exp'] + local rho=r(rho) + di _col(`loc') in ye %6.4f `rho' _c + } + di + } + di in green "{hline `=(`cons')*13+15'}" + di + } + if `nbind'<=800&"`biplot'"==""&"`weight'"=="" { + local max=max(`matsize',`nbind') + qui set matsize `max' + if "`addvar'"!="" { + local add `varlist' + } + if "`dim'"=="" { + local dim 1 2 + } + qui biplotvlab `latent' `add', name(biplot,replace) norow colopts(name(latent variables)) alpha(0) title(Biplot of the latent variables) labdes(size(vsmall) color(blue)) stretch(1) `std' dim(`dim') + } + else if `nbind'>800&"`biplot'"==""&"`weight'"==""{ + di in green "There is more than 800 individuals, so the {hi:biplot} option is disabled" + } + else if "`weight'"!=""&&"`biplot'"==""{ + di in green "The {hi:biplot} option is disabled because you use weights" + } + } + forvalues g=1/`cons' { + drop `f1`g'' + } + } +} +/***** END OF THE CONSOLIDATION PROCEDURE********/ + +qui set matsize `matsize' +if "`genlv'"!="" { + qui keep `id' `genlv'1-`genlv'`cons' + tempfile lvfile + qui sort `id' + qui save `lvfile',replace +} +use `clvfile',replace +if "`genlv'"!="" { + qui sort `id' + qui merge `id' using `lvfile' +} +qui drop `id' +capture drop _merge +capture cluster delete clv,zap +matrix colnames `vp'="Parent" "Number of clusters" "Child 1" "Child 2" "T" "DeltaT" "deltaT" "Explained Variance" "Explained Variance (%)" "First eigenvalue" "Second Eigenvalue" "2nd order deltaT" +if "`save'"!="" { + qui matrix `save'_vp=`vp' + qui matrix `save'_matclus=`matclus' + qui global `save'_varlist `varlist' + qui global `save'_method `method' + qui global `save'_kernel `kernel' +} + +return matrix vp=`vp' +return matrix matclus=`matclus' +return local varlist `varlist' +return local method `method' +return local kernel `kernel' +restore,not +end diff --git a/Modules/ado/personal/c/clv216.ado b/Modules/ado/personal/c/clv216.ado new file mode 100644 index 0000000..d4fb838 --- /dev/null +++ b/Modules/ado/personal/c/clv216.ado @@ -0,0 +1,1005 @@ +*! Version 2.16 30April2014 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : clv +* Clustering of variables around latent variables +* Version 2.14 : May 20th, 2010 /*dim and std options for biplots*/ +* +* Historic +* Version 1 (2005-06-11): Jean-Benoit Hardouin +* Version 1.1 (2005-07-07): Jean-Benoit Hardouin /*small bug in the consolidation process with cluster of only one variable*/ +* Version 1.2 (2005-07-08): Jean-Benoit Hardouin /*Bug in the consolidation procedure when there is negative correlation*/ +* Version 2 (2005-09-03): Jean-Benoit Hardouin /*Horizontal dendrograms (with Stata 9)*/ +* Version 2.1 (2005-09-08): Jean-Benoit Hardouin /*More flexibility to abbreviate the names of the variables (with Stata 9)*/ +* Version 2.1.1 (2005-09-08): Jean-Benoit Hardouin /*Integration of some requests of Ronan Conroy*/ +* Version 2.1.2 (2005-09-08): Jean-Benoit Hardouin /*Possibility to give a title and an X/Y caption*/ +* Version 2.2 (2005-09-11): Jean-Benoit Hardouin /*Kernel option*/ +* Version 2.3 (2005-09-12): Jean-Benoit Hardouin /*Polychoric option*/ +* Version 2.4 (2005-09-13): Jean-Benoit Hardouin /*v2 option*/ +* Version 2.5 (2005-09-21): Jean-Benoit Hardouin /*corrections*/ +* Version 2.6 (2005-10-02): Jean-Benoit Hardouin /*centroid method, biplot*/ +* Version 2.7 (2005-10-06): Jean-Benoit Hardouin /*return, multiple graphs, polychoric+consolidation*/ +* Version 2.8 (2005-10-06): Jean-Benoit Hardouin /*fweights*/ +* Version 2.9 (2006-01-26): Jean-Benoit Hardouin /*save the latent variables*/ +* Version 2.10 (2006-07-10): Jean-Benoit Hardouin /*2nd order relative variation of the T criterion*/ +* Version 2.11 (2006-10-09): Jean-Benoit Hardouin /*Size of the text in the dendrogram*/ +* Version 2.12 (2006-12-01): Jean-Benoit Hardouin /*savedendro option*/ +* Version 2.13 (2010-05-12): Jean-Benoit Hardouin /*corrections of bugs in KERNEL option and with METHOD(centroid)*/ +* Version 2.14 (2010-05-20): Jean-Benoit Hardouin /*DIM and STD options for biplots*/ +* Version 2.15 (2014-04-14): Jean-Benoit Hardouin /*save and use options*/ +* Version 2.16 (2014-04-30): Jean-Benoit Hardouin, Bastien Perrot /*HTML option*/ +* +* Jean-benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences +* Department of Biostatistics - France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://anaqol.sphere-nantes.fr +* +* Copyright 2005-2006, 2010, 2014 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ +program define clv216,rclass +version 9.0 +syntax [varlist(default=none)] [if] [in] [fweight] [, CUTnumber(int 40) bar CONSolidation(int 0) noDENdro SAVEDendro(string) noSTANDardized deltaT HORizontal SHOWcount ABBrev(int 14) TITle(string) CAPtion(string) KERnel(numlist) METHod(string) noBIPlot ADDvar genlv(string) replace TEXTSize(string) std dim(string) save(string) use(string) HTML(string)] +preserve +tempfile clvfile +tempvar id +gen `id'=_n +qui save `clvfile',replace + +if "`if'"!="" { + qui keep `if' +} + +local matsize=c(matsize) +local none=0 +if "`varlist'"==""&"`use'"=="" { + capture confirm matrix r(vp) + if _rc==0 { + capture confirm matrix r(matclus) + if _rc ==0 { + local none=1 + } + } + if `none'==0 { + di in red "You cannot use the {hi:clv} command without {hi:varlist} if you have not already run {hi:clv}" + error 198 + exit + } +} + +if "`html'"!="" { + //set scheme sj + //local htmlregion "graphregion(fcolor(white) ifcolor(white))" + di "" + di "
"
+}
+
+
+tempname matclus vp indexes
+
+/*********TESTS**********/
+
+if "`use'"!="" {
+   local error=0
+   capture matrix `vp'=`use'_vp
+   if _rc!=0 {
+      local error=_rc
+   }
+   capture matrix `matclus'=`use'_matclus
+   if _rc!=0 {
+      local error=_rc
+   }
+   local varlist $`use'_varlist
+   local method $`use'_method
+   local kernel $`use'_kernel
+   if "`varlist'"==""|"`method'"=="" {
+      local error=1
+   }
+   if `error'!=0 {
+      di in red "You cannot use the {hi:use} option without a preliminary use of the {hi:save} option"
+      error 198
+      exit
+   }
+}
+if `none'==1 {
+   matrix `vp'=r(vp)
+   matrix `matclus'=r(matclus)
+   local varlist `r(varlist)'
+   tokenize `varlist'
+   local nbitems=rowsof(`matclus')
+   if "`method'"!="" {
+      di in green "The {hi:method} option can not be modified without specification of the varlist. {hi:method} is omitted."
+   }
+   local method `r(method)'
+   local kernel `r(kernel)'
+}
+if "`method'"=="" {
+   local method classical
+}
+if ("`method'"=="polychoric"|"`method'"=="polychoricv2")&"`standardized'"!="" {
+   di in green "Initial variables are used with the {hi:polychoric} methods"
+   di in green "But the procedure is based on the matrix of the polychoric correlations"
+   di
+}
+if "`method'"!="classical"&"`method'"!="v2"&"`method'"!="centroid"&"`method'"!="polychoric"&"`method'"!="polychoricv2" {
+   di in red "The {hi:method} `method' is unknown"
+   error 198
+   exit
+}
+
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse
+qui keep if `touse'
+
+local mat=max(`matsize',`=`nbitems'*2')
+qui set matsize `mat'
+
+if `nbitems'<3&`none'!=1 {
+   di in red "You need at least 3 variables"
+   error 198
+   exit
+}
+
+
+/*******DEFINES THE LABELS AND STANDARDIZED THE VARIABLES (IF NECESSARY)*******/
+forvalues i=1/`nbitems'{
+   local label`i':variable label ``i''
+   if "`label`i''"=="" {
+      local label`i' ``i''
+   }
+   if "`method'"!="polychoric"&"`method'"!="polychoricv2" {
+      qui su ``i'' [`weight'`exp']
+      local mean=r(mean)
+      if "`standardized'"=="" {
+         local sd=r(sd)
+      }
+      else {
+         local sd=1
+      }
+      qui replace ``i''=(``i''-`mean')/`sd'
+   }
+}
+
+tempfile clvfiletmp
+qui save `clvfiletmp',replace
+
+qui su `1' [`weight'`exp']
+local nbind=r(sum_w)
+
+
+local cons=`consolidation'
+
+/*COMPUTES THE TOTAL VARIANCE*/
+
+if "`method'"!="polychoric"&"`method'"!="polychoricv2" {
+   local totvar=0
+   forvalues i=1/`nbitems' {
+      qui su ``i'' [`weight'`exp']
+      local totvar=`totvar'+`r(Var)'
+   }
+}
+else {
+   local totvar `nbitems'
+}
+local nbkerk=0
+local nbkerg=0
+
+/***** DEFINES THE KERNEL IF NECESSARY ********/
+
+if "`kernel'"!="" {
+   local nbkerg:word count `kernel'
+   local fin0=0
+   forvalues i=1/`nbkerg' {
+      local nbi`i':word `i' of `kernel'
+      local nbkerk=`nbkerk'+`nbi`i''
+      local deb`i'=`fin`=`i'-1''+1
+      local fin`i'=`deb`i''+`nbi`i''-1
+      local list`i'
+      forvalues j=`deb`i''/`fin`i'' {
+         local list`i' `list`i'' ``j''
+      }
+   }
+   tempname kerclus
+   matrix `kerclus'=J(`=`nbkerk'-`nbkerg'',3,0)
+   local ligne=1
+   forvalues g=1/`nbkerg' {
+       matrix `kerclus'[`ligne',1]=`nbitems'+`ligne'
+       matrix `kerclus'[`ligne',2]=`deb`g''
+       matrix `kerclus'[`ligne',3]=`deb`g''+1
+       local clus`g'=`nbitems'+`ligne'
+       local ligne=`ligne'+1
+       if `nbi`g''>2 {
+          forvalues i=2/`=`nbi`g''-1' {
+             matrix `kerclus'[`ligne',1]=`nbitems'+`ligne'
+             matrix `kerclus'[`ligne',2]=`deb`g''+`i'
+             matrix `kerclus'[`ligne',3]=`nbitems'+`ligne'-1
+             local clus`g'=`nbitems'+`ligne'
+             local ligne=`ligne'+1
+          }
+      }
+      local eigen2=0
+   }
+}
+if `nbitems'<`nbkerk' {
+   di in red "You cannot define more variables in the {hi:kernel} option than items in the {hi:varlist}"
+   error 198
+   exit
+}
+
+/*******DISPLAY THE FIRST RESULTS *******/
+
+di
+di in green "{hline 32}"
+di in green "TOTAL VARIANCE: " in ye %16.5f `totvar'
+di in green "NUMBER OF INDIVIDUALS: " in ye %9.0f `nbind'
+di in green "METHOD:" in ye _col(`=33-length("`method'")') "`=upper("`method'")'"
+di in green "{hline 32}"
+di
+
+if "`kernel'"!="" {
+   forvalues i=1/`nbkerg' {
+      di in green "The kernel numbered " in ye `clus`i'' in green " is composed of `nbi`i'' variables: " in ye "`list`i''"
+      di
+   }
+}
+else {
+   local nbkerk=0
+   local nbkerg=0
+}
+
+/******** CLASSIFICATION PROCEDURE*******/
+
+tempname Ev
+if `none'!=1 {
+   matrix `matclus'=J(`nbitems',`nbitems',0)
+   matrix `vp'=J(`=2*`nbitems'-1',12,0)
+   matrix `indexes'=J(`nbitems',8,0)
+   forvalues i=1/`nbitems' {
+      matrix `matclus'[`i',1]=`i'
+      if "`method'"!="polychoric"&"`method'"!="polychoric" {
+         qui su ``i'' [`weight'`exp']
+         matrix `vp'[`i',10]=r(Var)
+      }
+      else {
+         matrix `vp'[`i',10]=1
+      }
+      matrix `vp'[`i',1]=`i'
+      matrix `vp'[`i',2]=`nbitems'
+      matrix `vp'[`i',8]=`totvar'
+      matrix `vp'[`i',9]=100
+   }
+   matrix `vp'[`nbitems',5]=`nbitems'
+   if "`method'"=="centroid" {
+      local crit G
+      di in green "{hline 101}"
+      di in green _col(93) "2nd order"
+      di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(82) "Relative" _col(94) "Relative"
+      di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance"  _col(81) "Variation" _col(93) "Variation"
+      di in green "{hline 101}"
+   }
+   else {
+      local crit T
+      di in green "{hline 111}"
+      if "`method'"=="v2"|"`method'"=="polychoricv2" {
+         di in green _col(84) "Maximal" _col(103) "2nd order"
+      }
+      else {
+         di in green _col(84) "Current" _col(103) "2nd order"
+      }
+      di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(85) "Second" _col(93) "Relative" _col(104) "Relative"
+      di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Eigenvalue" _col(92) "Variation" _col(103) "Variation"
+      di in green "{hline 111}"
+   }
+   tempname threshold
+   matrix `threshold'=J(`nbitems',3,0)
+   forvalues i=1/`=`nbitems'-1' {
+      local clus=`nbitems'+`i'
+      local minegenval=999999
+      local minegenval2=999999
+      forvalues k=1/`=`clus'-1' {
+         local list`k'
+         local numlist`k'
+         forvalues j=1/`clus' {
+            if (`matclus'[`j',`i']==`k') {
+               local list`k' `list`k'' ``j''
+               local numlist`k' `numlist`k'' `j'
+            }
+         }
+      }
+      if `clus'>`nbitems'+`nbkerk'-`nbkerg' {
+         if "`method'"=="centroid" {
+            tempname centrj centrk diffjk
+         }
+         forvalues j=1/`clus' {
+            local nblistj:word count `list`j''
+            forvalues k=`=`j'+1'/`clus' {
+               local nblistk:word count `list`k''
+               if `nblistj'!=0&`nblistk'!=0 {
+                  if "`method'"=="centroid" {
+                     qui genscore `list`j'',score(`centrj') mean
+                     qui su `centrj' [`weight'`exp']
+                     local Varj=r(Var)
+                     qui genscore `list`k'',score(`centrk') mean
+                     qui su `centrk' [`weight'`exp']
+                     local Vark=r(Var)
+                     qui gen `diffjk'=`centrk'-`centrj'
+                     qui su `diffjk' [`weight'`exp']
+                     local Varjk=r(Var)
+                     drop `centrj' `centrk' `diffjk'
+                     local ev=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`Varjk'
+                     if `ev'<`minegenval' {
+                        local minegenval=`ev'
+                        local minj `j'
+                        local mink `k'
+                        local eigen=0
+                        local eigen2=0
+                     }
+                  }
+                  else {
+                     if "`method'"=="classical"|"`method'"=="v2" {
+                        qui pca `list`j'' `list`k'' [`weight'`exp'] ,cov
+                        matrix `Ev'=e(Ev)
+                     }
+                     else if "`method'"=="polychoric"|"`method'"=="polychoricv2" {
+                        qui polychoricpca `list`j'' `list`k'' [`weight'`exp']
+                        matrix `Ev'=r(eigenvalues)
+                     }
+                     local lambda1=`Ev'[1,1]
+                     local lambda2=`Ev'[1,2]
+                     local ev=`vp'[`j',10]+`vp'[`k',10]-`lambda1'
+                     local ev2=max(`vp'[`j',11],`vp'[`k',11],`lambda2')
+                     if ("`method'"=="v2"|"`method'"=="polychoricv2")&`ev'<`minegenval' {
+                        local minegenval=`ev'
+                        local eigen=`lambda1'
+                        local minj `j'
+                        local mink `k'
+                        local eigen2=`lambda2'
+                     }
+                     else if ("`method'"=="classical"|"`method'"=="polychoric")&`ev2'<`minegenval2' {
+                        local minegenval=`ev'
+                        local minegenval2=`ev2'
+                        local eigen=`lambda1'
+                        local minj `j'
+                        local mink `k'
+                        local eigen2=`ev2'
+                     }
+                  }
+               }
+            }
+         }
+      }
+      else {
+         local ligne=`clus'-`nbitems'
+         local j=`kerclus'[`ligne',2]
+         local k=`kerclus'[`ligne',3]
+         if "`method'"!="centroid" {
+            if "`method'"=="classical"|"`method'"=="v2" {
+               qui pca `list`j'' `list`k'' [`weight'`exp'],cov
+               matrix `Ev'=e(Ev)
+            }
+            else if "`method'"=="polychoric"|"`method'"=="polychoricv2"{
+               qui polychoricpca `list`j'' `list`k''  [`weight'`exp']
+               matrix `Ev'=r(eigenvalues)
+            }
+            local lambda1=`Ev'[1,1]
+            local lambda2=`Ev'[1,2]
+            local ev=`vp'[`j',10]+`vp'[`k',10]-`lambda1'
+            local minegenval=`ev'
+            local eigen=`lambda1'
+            local minj `j'
+            local mink `k'
+            local eigen2=`lambda2'
+         }
+         else if "`method'"=="centroid" {
+            local nblistj:word count `list`j''
+            local nblistk:word count `list`k''
+            tempname v1 v2 v12
+            qui genscore `list`j'',score(`v1') mean
+            qui genscore `list`k'',score(`v2') mean
+            qui gen `v12'=`v1'-`v2'
+            qui su `v12' [`weight'`exp']
+            local varj=r(Var)
+            local minegenval=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`varj'
+            local minj `j'
+            local mink `k'
+         }
+      }
+      if `minj'<=`nbitems' {
+         local nomj=abbrev("``minj''",14)
+      }
+      else {
+         local nomj `minj'
+      }
+      if `mink'<=`nbitems' {
+         local nomk=abbrev("``mink''",14)
+      }
+      else {
+         local nomk `mink'
+      }
+      forvalues j=1/`nbitems' {
+         matrix `matclus'[`j',`=`i'+1']=`matclus'[`j',`i']
+      }
+      matrix `vp'[`clus',1]=`nbitems'+`i'                      /*PARENT*/
+      matrix `vp'[`clus',2]=`=`nbitems'-`i''                   /*NUMBER OF CLUSTERS*/
+      matrix `vp'[`clus',3]=`minj'                             /*CHILD 1*/
+      matrix `vp'[`clus',4]=`mink'                             /*CHILD 2*/
+      matrix `vp'[`clus',6]=`minegenval'                       /*VARIATION OF THE T or G CRITERION*/
+      matrix `vp'[`clus',5]=`vp'[`=`clus'-1',5]-`vp'[`clus',6] /*T or G CRITERION*/
+      matrix `vp'[`clus',7]=(`vp'[`clus',6]-`vp'[`=`clus'-1',6])/`vp'[`=`clus'-1',6] /*RELATIVE VARIATION OF THE T OR G CRITERION*/
+      matrix `vp'[`clus',8]=`vp'[`=`clus'-1',8]-`minegenval'   /*EXPLAINED VARIANCE*/
+      matrix `vp'[`clus',9]=`vp'[`clus',8]/`totvar'*100        /*% OF EXPLAINED VARIANCE*/
+      if "`method'"!="centroid" {
+         matrix `vp'[`clus',10]=`eigen'                        /*FIRST EIGEN VALUE OF THE NEW CLUSTER*/
+         matrix `vp'[`clus',11]=`eigen2'                       /*SECOND EIGEN VALUE OF THE NEW CLUSTER*/
+      }
+      if `vp'[`=`clus'-1',7]!=0 {
+         matrix `vp'[`clus',12]=(`vp'[`clus',7]-`vp'[`=`clus'-1',7])/abs(`vp'[`=`clus'-1',7]) /*2ND ORDER RELATIVE VARIATION OF THE T or G CRITERION*/
+      }
+      matrix `indexes'[`i',1]=`i'                              /*PARENT*/
+      matrix `indexes'[`i',2]=`nbitems'-`i'                    /*NUMBER OF CLUSTERS*/
+      matrix `indexes'[`i',3]=`minegenval'                     /*VARIATION OF THE T or G CRITERION*/
+      matrix `indexes'[`i',4]=`vp'[`clus',7]                   /*RELATIVE VARIATION OF THE T OR G CRITERION*/
+      matrix `indexes'[`i',5]=max(`eigen2',`indexes'[`=`i'-1',5]) /*MAXIMUM SECOND EIGENVALUE*/
+      matrix `indexes'[`i',7]=`vp'[`clus',12]                     /*2nd order RELATIVE VARIATION OF THE T OR G CRITERION*/
+      foreach j of numlist `numlist`minj'' `numlist`mink''  {
+         matrix `matclus'[`j',`=`i'+1']=`clus'
+      }
+      local varlistgen
+      local nbvarlistgen
+      forvalues j=1/`=`nbitems'+`i'' {
+         local varlist`j'
+         forvalues k=1/`nbitems' {
+             if `matclus'[`k',`=`i'+1']==`j' {
+                local varlist`j' `varlist`j'' ``k''
+             }
+         }
+         local nbvarlist`j': word count `varlist`j''
+         local varlistgen `varlistgen' `varlist`j''
+         local nbvarlistgen `nbvarlistgen' `nbvarlist`j''
+      }
+      local newlist
+      foreach m in `nbvarlistgen' {
+          if `m'!=0 {
+              local newlist `newlist' `m'
+          }
+      }
+      if "`kernel'"!=""&`i'==`=`nbkerk'-`nbkerg'+1' {
+         local T=`vp'[`=`clus'-1',8]
+         di _col(0) in ye "init" _col(12) %4.0f `=`nbitems'-`nbkerk'+`nbkerg'' _col(52) %8.4f `T' _col(62) %8.4f `=`totvar'-`T'' _col(72) %7.3f `=`T'/`totvar'*100' "%"
+      }
+      if `clus'>`nbitems'+`nbkerk'-`nbkerg' {
+         matrix `threshold'[`=`nbitems'-`i'+1',3]=`minegenval'
+         if  `clus'==`nbitems'+`nbkerk'-`nbkerg'+1 {
+            local relv
+            local percent
+            local relv2
+         }
+         else {
+            local relv=`indexes'[`i',4]*100
+            local percent %
+            if `indexes'[`i',7]!=. {
+               local relv2=`indexes'[`i',7]*100
+            }
+            else {
+               local relv2=0
+            }
+            matrix `threshold'[`=`nbitems'-`i'+1',1]=`relv'
+            matrix `threshold'[`=`nbitems'-`i'+1',2]=`relv2'
+         }
+         if "`method'"=="centroid" {
+            di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',8] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',9] "%" _col(83) _col(84) %5.2f `relv' "`percent'" _col(93) %8.2f `relv2' "`percent'"
+         }
+         else {
+            di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',8] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',9] "%" _col(83) %8.4f `vp'[`clus',11] _col(94) %6.2f `relv' "`percent'" _col(103) %8.2f `relv2' "`percent'"
+         }
+      }
+   }
+   matrix `indexes'[`nbitems',3]=`vp'[`=2*`nbitems'-1',5] /*RELATIVE VARIATION OF THE T OR G CRITERION*/
+   matrix `indexes'[`nbitems',7]=`indexes'[`nbitems',3]/`indexes'[`=`nbitems'-1',3] /*RELATIVE VARIATION OF THE T OR G CRITERION*/
+   local i=2*`nbitems'-1
+   matrix `threshold'[1,1]=`vp'[`i',5]/`vp'[`i',6]*100-100
+   matrix `threshold'[1,2]=(`threshold'[1,1]-`threshold'[2,1])/abs(`threshold'[2,1])*100
+   matrix `threshold'[1,3]=`vp'[`i',5]
+   if "`method'"=="centroid" {
+      di in ye _col(62) %8.4f `threshold'[1,3] _col(83) %6.2f `threshold'[1,1] "`percent'" _col(93) %8.2f `threshold'[1,2] "`percent'"
+   }
+   else {
+      di in ye _col(62) %8.4f `threshold'[1,3] _col(94) %6.2f `threshold'[1,1] "`percent'" _col(103) %8.2f `threshold'[1,2] "`percent'"
+   }
+   local best=0
+   local maxbest=0
+   local best2=0
+   local maxbest2=0
+   local demipart=int(`nbitems'/2)+1
+   forvalues i=1/`demipart' {
+      if `threshold'[`i',3]>`maxbest2' {
+         if `threshold'[`i',3]>`maxbest' {
+            local maxbest2=`maxbest'
+            local best2=`best'
+            local maxbest=`threshold'[`i',3]
+            local best=`i'
+         }
+         else {
+            local maxbest2=`threshold'[`i',3]
+            local best2=`i'
+         }
+      }
+   }
+   di in green "{hline 111}"
+   di
+   di in green "{hline 60}"
+   di in green "PROPOSED BEST PARTITIONS (AMONG THE `demipart' SMALLER PARTITIONS)"
+   di in green "{hline 60}"
+   di
+   di in yellow _col(4) "Based on the variation of the T criterion: " _col(60) in gr "Partitions in " in ye `best' " or " `best2' in gr " clusters"
+   return local bestvariation `best' `best2'
+   local bestt=0
+   local bestt2=0
+   local var=0
+   local var2=0
+   forvalues i=1/`nbitems' {
+       if `threshold'[`i',1]>`var2'&`i'<`demipart' {
+           if `threshold'[`i',1]>`var' {
+              local bestt2=`bestt'
+              local var2=`var'
+              local var=`threshold'[`i',1]
+              local bestt=`i'
+           }
+           else {
+              local var2=`threshold'[`i',1]
+              local bestt2=`i'
+           }
+       }
+   }
+   di in yellow _col(4) "Based on the research of a threshold: " _col(60) in gr "Partitions in "  in ye `bestt' " or " `bestt2' in gr " clusters"
+   forvalues i=`=`nbitems'+1'/`=`nbitems'+`nbkerk'-`nbkerg'' {
+      matrix `vp'[`i',6]=`totvar'-`T'
+      matrix `vp'[`i',8]=`T'
+      matrix `vp'[`i',9]=`T'/`nbitems'*100
+   }
+   return local bestthresold `bestt' `bestt2'
+   forvalues i=1/`nbitems' {
+       if `threshold'[`i',2]>`var2'&`i'<`demipart' {
+           if `threshold'[`i',2]>`var' {
+              local bestt2=`bestt'
+              local var2=`var'
+              local var=`threshold'[`i',2]
+              local bestt=`i'
+           }
+           else {
+              local var2=`threshold'[`i',2]
+              local bestt2=`i'
+           }
+       }
+   }
+   di in yellow _col(4) "Based on the research of a threshold (second order): " _col(60) in gr "Partitions in " in ye `bestt' " or " `bestt2' in gr " clusters"
+   return local bestthresold2 `bestt' `bestt2'
+}
+/******BAR CHART *******/
+if "`bar'"!="" {
+   drop _all
+   qui set obs `nbitems'
+   qui svmat `indexes' ,names(v)
+   qui gen id=`nbitems'-_n
+   qui replace v7=. in 1
+   qui drop if id>`nbitems'-`nbkerk'+`nbkerg'-1
+   label variable id "Number of clusters"
+   label variable v3 "T variation"
+   qui su v3 if id!=0
+   local maxv3=ceil(r(max)*5)/5
+   local minv3=floor(r(min)*5)/5
+   label variable v4 "Relative T variation"
+   label variable v7 "Relative T variation order 2"
+   
+   if "`html'" != "" {
+		qui local saving "saving(`c(tmpdir)'/`html'_bar,replace) nodraw"
+		qui graph twoway (bar v3 id, name(bar,replace) vert yaxis(1))(line v4 id,yaxis(2))/*(line v6 id,yaxis(3))(line v5 id,yaxis(4))*/(line v7 id,yaxis(5)) if id!=0,ylabel(`minv3'(0.2)`maxv3') xlabel(1(1)`=`nbitems'-`nbkerk'+`nbkerg'-1') `saving'
+		qui graph use `c(tmpdir)'/`html'_bar.gph
+		qui graph export `c(tmpdir)'/`html'_bar.eps, replace
+		di "
" + di " _char(34) " + } + else { + graph twoway (bar v3 id, name(bar,replace) vert yaxis(1))(line v4 id,yaxis(2))/*(line v6 id,yaxis(3))(line v5 id,yaxis(4))*/(line v7 id,yaxis(5)) if id!=0,ylabel(`minv3'(0.2)`maxv3') xlabel(1(1)`=`nbitems'-`nbkerk'+`nbkerg'-1') + } + } +/****** DENDROGRAM********/ + drop _all + qui set obs `nbitems' + qui svmat `matclus' ,names(v) + local listorder + forvalues i=`nbitems'(-1)1 { + local listorder `listorder' v`i' + } + qui gen id=_n + qui sort `listorder' + + capture cluster delete clv,zap + qui cluster complete v* ,name(clv) + + qui replace clv_id=_n + qui replace clv_ord=id + qui replace clv_hgt=. + + qui gen fait=0 + qui gen clus=0 + forvalues i=2/`nbitems' { + local ligne=`nbitems'+`i'-1 + if (`vp'[`ligne',3]<=`nbitems') { + local first=`vp'[`ligne',3] + gsort +fait -v`i' +clv_id + } + else { + local first=`vp'[`ligne',4] + gsort +fait -v`i' +clv_id + } + if "`deltaT'"!="" { + qui replace clv_hgt=`vp'[`ligne',6] in 1 + } + else { + qui replace clv_hgt=100-`vp'[`ligne',9] in 1 + } + qui replace fait=1 in 1 + qui replace clus=`vp'[`ligne',1] in 1 + } +if "`dendro'"=="" { + qui gen label="" + forvalues i=1/`nbitems' { + qui replace label=abbrev("`label`i''",`abbrev') if clv_id==`i' + } + sort clv_id + if `nbitems'>`cutnumber' { + local var "Groups of variables" + local cut cutnumber(`cutnumber') /*labcutn*/ + } + else { + local var "Variables" + local cut label(label) + } + qui su clv_hgt + local tmp=r(max) + local max=floor(`tmp')+.5 + if `tmp'>`max' { + local max=`max'+.5 + } + local maxvar=`max'+5 + if "`title'"=="" { + local title "Clustering around Latent Variables (CLV)" + } + if "`caption'"!="" { + local var "`caption'" + } + if "`deltaT'"!="" { + local titleL "Variation of the T criterion" + local yl "0(.5)`max'" + } + else { + local titleL "% Unexplained Variance" + local yl "0(25)`maxvar'" + } + if "`textsize'"=="" { + local textsize: word `=min(int(`nbitems'/15)+1,5)' of medium medsmall small vsmall tiny + } + if "`horizontal'"!="" { + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_dendrogram,replace) nodraw" + qui cluster dendro clv, name (dendrogram,replace) hor ytitle("`var'") `showcount' xtitle("`titleL'") title("`title'",span) xlabel(`yl') ylabel(,angle(0) labsize(`textsize')) `cut' `saving' + qui graph use `c(tmpdir)'/`html'_dendrogram.gph + qui graph export `c(tmpdir)'/`html'_dendrogram.eps, replace + di "
" + di " _char(34) " + } + else { + cluster dendro clv, name (dendrogram,replace) hor ytitle("`var'") `showcount' xtitle("`titleL'") title("`title'",span) xlabel(`yl') ylabel(,angle(0) labsize(`textsize')) `cut' + } + } + else { + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_dendrogram,replace) nodraw" + qui cluster dendro clv, name(dendrogram,replace) xtitle("`var'") `showcount' ytitle("`titleL'") title("`title'",span) ylabel(`yl') xlabel(,labsize(`textsize')) `cut' `saving' + qui graph use `c(tmpdir)'/`html'_dendrogram.gph + qui graph export `c(tmpdir)'/`html'_dendrogram.eps, replace + di "
" + di " _char(34) " + } + else { + cluster dendro clv, name(dendrogram,replace) xtitle("`var'") `showcount' ytitle("`titleL'") title("`title'",span) ylabel(`yl') xlabel(,labsize(`textsize')) `cut' + } + } + if "`savedendro'"!="" { + graph save dendrogram `savedendro' + } +} + +/***** END DENDROGRAM*****/ + +/**** TEST ********/ +if `cons'>`nbitems'-`nbkerk'+`nbkerg' { + di in ye "The {hi:consolidation} is not possible for a number of clusters superior to the initial number of clusters" + local cons=0 +} + + +/***** CONSOLIDATION PROCEDURE ********/ +if `cons'!=0 { + sort v`=`nbitems'-`cons'+1' + gen cut`cons'=1 + local g=1 + forvalues i=2/`nbitems' { + if v`=`nbitems'-`cons'+1'[`i']!=v`=`nbitems'-`cons'+1'[`=`i'-1'] { + local g=`g'+1 + } + qui replace cut`cons'=`g' in `i' + } + sort id + tempname group + mkmat cut`cons',matrix(`group') + + use `clvfiletmp',replace + + local n=1 + local env=1 + while (`env'==1) { + forvalues g=1/`cons' { + local list`g' + forvalues i=1/`nbitems' { + if `group'[`i',1]==`g' { + local list`g' `list`g'' ``i'' + } + } + } + di + if `n'==1 { + di in green "{hline 30}" + di in green "PARTITION BEFORE CONSOLIDATION" + di in green "{hline 30}" + } + di + local col=13 + local max=0 + local critT=0 + forvalues g=1/`cons' { + di _col(`col') in green "CLUSTER " %2.0f `g' _c + local col=`col'+12 + local tmp`g':word count `list`g'' + if `tmp`g''>`max' { + local max `tmp`g'' + } + tempvar f1`g' + if "`method'"=="centroid" { + qui genscore `list`g'',score(`f1`g'') mean + qui su `f1`g'' [`weight'`exp'] + local var=r(Var) + local critT=`critT'+`tmp`g''*`var' + qui pca `list`g'' [`weight'`exp'] ,cov + local trace=e(trace) + local explained`g'=`tmp`g''*`var'/`trace' + } + else { + if `tmp`g''>1 { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`g'' [`weight'`exp'] ,cov + matrix `Ev'=e(Ev) + local trace=e(trace) + qui predict `f1`g'' + } + else if "`method'"=="polychoric"|"`method'"=="polychoric" { + qui polychoricpca `list`g'' [`weight'`exp'] ,score(`f1`g'') nscore(1) + matrix `Ev'=r(eigenvalues) + local trace=0 + forvalues m=1/`tmp`g''{ + local trace =`trace'+`r(lambda`m')' + } + rename `f1`g''1 `f1`g'' + } + local lambda1=`Ev'[1,1] + local explained`g'=`lambda1'/`trace' + local critT=`critT'+`lambda1' + } + else { + local explained`g'=1 + qui gen `f1`g''=`list`g'' + if "`standardized'"=="" { + local critT=`critT'+1 + } + else { + qui su [`weight'`exp'] + local critT=`critT'+`r(Var)' + } + } + } + } + di + di _col(1) in green "ITEMS :" _c + forvalues i=1/`max' { + local col=15 + forvalues g=1/`cons' { + local tmpv:word `i' of `list`g'' + local tmpv=abbrev("`tmpv'",8) + di _col(`col') in ye %8s "`tmpv'" _c + local col= `col'+12 + } + di + } + local col=16 + di _col(1) in green "Expl. Var:" _c + forvalues g=1/`cons' { + di _col(`col') in ye %6.2f `=`explained`g''*100' in green "%" _c + local col= `col'+12 + } + di + di + di in green "Variance Explained : " in ye %6.3f `=`critT'/`totvar'*100' in green "%" + di in green "T criterion : " in ye %6.4f `critT' + di + di in green "{hline 21}" + di in green "CONSOLIDATION: STEP `n'" + di in green "{hline 21}" + local n=`n'+1 + local env=0 + if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + local command polychoric + } + else { + local command corr + } + forvalues i=1/`nbitems' { + local env`i'=0 + local gr=`group'[`i',1] + qui `command' ``i'' `f1`gr'' [`weight'`exp'] + local corr`i'=r(rho) + local corrs`i'=r(rho) + forvalues g=1/`cons' { + qui `command' ``i'' `f1`g'' [`weight'`exp'] + local tmpcorr=r(rho) + if `g'!=`gr'&(((`corr`i'')<(`tmpcorr')&"`method'"=="centroid")|((`corr`i'')^2<(`tmpcorr')^2& "`method'"!="centroid")) { + local env=1 + local env`i'=1 + matrix `group'[`i',1]=`g' + local corr`i'=`tmpcorr' + } + } + if `env`i''==1 { + local g=`group'[`i',1] + di in green "The variable " in ye "``i'' " in green "is assigned to the `g'th group" _c + if "`method'"!="centroid" { + di in green " (corr^2=" %6.4f in ye (`corr`i'')^2 in green " vs " in ye %6.4f (`corrs`i'')^2 in green ")" + } + else { + di in green " (corr=" %6.4f in ye (`corr`i'') in green " vs " in ye %6.4f (`corrs`i'') in green ")" + } + + } + } + if `env'==0 { + local latent + forvalues g=1/`cons' { + label variable `f1`g'' "Latent variable `g'" + if "`genlv'"!="" { + if "`replace'"!=""{ + capture drop `genlv'`g' + } + gen `genlv'`g'=`f1`g'' + } + local latent `latent' `f1`g'' + return local cluster`g' `list`g'' + } + matrix `group'=`group'' + matrix colnames `group'=`varlist' + return matrix affect=`group' + di in ye "Stability of the partition is achieved" + if `cons'<=7 { + di + di in green "{hline 42}" + di in green "CORRELATION MATRIX OF THE LATENT VARIABLES" + di in green "{hline 42}" + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+23') in green "Latent" _c + } + di + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+19') in green "variable `g'" _c + } + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di in green "Latent variable `g'" _c + forvalues h=1/`g' { + local loc=13*`h'+10 + qui corr `f1`g'' `f1`h'' [`weight'`exp'] + local rho=r(rho) + di _col(`loc') in ye %6.4f `rho' _c + } + di + } + di in green "{hline `=(`cons')*13+15'}" + di + } + if `nbind'<=800&"`biplot'"==""&"`weight'"=="" { + local max=max(`matsize',`nbind') + qui set matsize `max' + if "`addvar'"!="" { + local add `varlist' + } + if "`dim'"=="" { + local dim 1 2 + } + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_biplot,replace) nodraw" + qui biplotvlab `latent' `add', name(biplot,replace) norow colopts(name(latent variables)) alpha(0) title(Biplot of the latent variables) labdes(size(vsmall) color(blue)) stretch(1) `std' dim(`dim') `saving' + qui graph use `c(tmpdir)'/`html'_biplot.gph + qui graph export `c(tmpdir)'/`html'_biplot.eps, replace + di "
" + di " _char(34) " + } + else { + qui biplotvlab `latent' `add', name(biplot,replace) norow colopts(name(latent variables)) alpha(0) title(Biplot of the latent variables) labdes(size(vsmall) color(blue)) stretch(1) `std' dim(`dim') + } + } + else if `nbind'>800&"`biplot'"==""&"`weight'"==""{ + di in green "There is more than 800 individuals, so the {hi:biplot} option is disabled" + } + else if "`weight'"!=""&&"`biplot'"==""{ + di in green "The {hi:biplot} option is disabled because you use weights" + } + } + forvalues g=1/`cons' { + drop `f1`g'' + } + } +} +/***** END OF THE CONSOLIDATION PROCEDURE********/ + +qui set matsize `matsize' +if "`genlv'"!="" { + qui keep `id' `genlv'1-`genlv'`cons' + tempfile lvfile + qui sort `id' + qui save `lvfile',replace +} +use `clvfile',replace +if "`genlv'"!="" { + qui sort `id' + qui merge `id' using `lvfile' +} +qui drop `id' +capture drop _merge +capture cluster delete clv,zap +matrix colnames `vp'="Parent" "Number of clusters" "Child 1" "Child 2" "T" "DeltaT" "deltaT" "Explained Variance" "Explained Variance (%)" "First eigenvalue" "Second Eigenvalue" "2nd order deltaT" +if "`save'"!="" { + qui matrix `save'_vp=`vp' + qui matrix `save'_matclus=`matclus' + qui global `save'_varlist `varlist' + qui global `save'_method `method' + qui global `save'_kernel `kernel' +} + +return matrix vp=`vp' +return matrix matclus=`matclus' +return local varlist `varlist' +return local method `method' +return local kernel `kernel' +restore,not +end diff --git a/Modules/ado/personal/c/clv27.ado b/Modules/ado/personal/c/clv27.ado new file mode 100644 index 0000000..2b29ea0 --- /dev/null +++ b/Modules/ado/personal/c/clv27.ado @@ -0,0 +1,806 @@ +*! Version 2.7 6October2005 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : clv +* Clustering of variables around latent variables +* Version 2.7 : October 6, 2005 /*return, multiple graphs, polychoric+consolidation*/ +* +* Historic +* Version 1 (2005-06-11): Jean-Benoit Hardouin +* Version 1.1 (2005-07-07): Jean-Benoit Hardouin /*small bug in the consolidation process with cluster of only one variable*/ +* Version 1.2 (2005-07-08): Jean-Benoit Hardouin /*Bug in the consolidation procedure when there is negative correlation*/ +* Version 2 (2005-09-03): Jean-Benoit Hardouin /*Horizontal dendrograms (with Stata 9)*/ +* Version 2.1 (2005-09-08): Jean-Benoit Hardouin /*More flexibility to abbreviate the names of the variables (with Stata 9)*/ +* Version 2.1.1 (2005-09-08): Jean-Benoit Hardouin /*Integration of some requests of Ronan Conroy*/ +* Version 2.1.2 (2005-09-08): Jean-Benoit Hardouin /*Possibility to give a title and an X/Y caption*/ +* Version 2.2 (2005-09-11): Jean-Benoit Hardouin /*Kernel option*/ +* Version 2.3 (2005-09-12): Jean-Benoit Hardouin /*Polychoric option*/ +* Version 2.4 (2005-09-13): Jean-Benoit Hardouin /*v2 option*/ +* Version 2.5 (2005-09-21): Jean-Benoit Hardouin /*corrections*/ +* Version 2.6 (2005-10-02): Jean-Benoit Hardouin /*centroid method, biplot*/ +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@orscentre.org +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2005 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ +program define clv,rclass +version 9.0 +syntax [varlist(default=none)] [if] [in] [, CUTnumber(int 30) bar CONSolidation(int 0) noDENdro noSTANDardized deltaT HORizontal SHOWcount ABBrev(int 14) TITle(string) CAPtion(string) KERnel(numlist) METHod(string) noBIPlot ADDvar] +preserve +tempfile clvfile +qui save `clvfile',replace +local matsize=c(matsize) +local none=0 +if "`varlist'"=="" { +*set trace on + capture confirm matrix r(vp) + if _rc==0 { + capture confirm matrix r(matclus) + if _rc ==0 { + local none=1 + } + } + if `none'==0 { + di in red "You cannot use the {hi:clv} command without {hi:varlist} if you have not already run {hi:clv}" + error 198 + exit + } +} + +tempname matclus vp + +if `none'==1 { + matrix `vp'=r(vp) + matrix `matclus'=r(matclus) + local varlist `r(varlist)' + tokenize `varlist' + local nbitems=rowsof(`matclus') + if "`method'"!="" { + di in green "The {hi:method} option can not be modified without specification of the varlist. {hi:method} is omitted." + } + local method `r(method)' + local kernel `r(kernel)' +/* + if "`method'"=="polychoric" { + di in red "The {hi:consolidation} is not possible with the {hi:polychoric} option" + error 198 + exit + } +*/ +} +if "`method'"=="" { + local method classical +} +if ("`method'"=="polychoric"|"`method'"=="polychoricv2")&"`standardized'"!="" { + di in green "Initial variables are used with the {hi:polychoric} methods" + di in green "But the procedure is based on the matrix of the polychoric correlations" + di +} +if "`method'"!="classical"&"`method'"!="v2"&"`method'"!="centroid"&"`method'"!="polychoric"&"`method'"!="polychoricv2" { + di in red "The {hi:method} `method' is unknown" + error 198 + exit +} + +tokenize `varlist' +local nbitems : word count `varlist' +marksample touse +qui keep if `touse' + +local mat=max(`matsize',`=`nbitems'*2') +qui set matsize `mat' + +if `nbitems'<3&`none'!=1 { + di in red "You need at least 3 variables" + error 198 + exit +} +forvalues i=1/`nbitems'{ + local label`i':variable label ``i'' + if "`label`i''"=="" { + local label`i' ``i'' + } + if "`method'"!="polychoric"&"`method'"!="polychoricv2" { + qui su ``i'' + local mean=r(mean) + if "`standardized'"=="" { + local sd=r(sd) + } + else { + local sd=1 + } + qui replace ``i''=(``i''-`mean')/`sd' + } +} + +tempfile clvfiletmp +qui save `clvfiletmp',replace + +qui count +local nbind=r(N) + +local cons=`consolidation' + +if "`method'"!="polychoric"&"`method'"!="polychoricv2" { + local totvar=0 + forvalues i=1/`nbitems' { + qui su ``i'' + local totvar=`totvar'+`r(Var)' + } +} +else { + local totvar `nbitems' +} +local nbkerk=0 +local nbkerg=0 + +if "`kernel'"!="" { + local nbkerg:word count `kernel' + local fin0=0 + forvalues i=1/`nbkerg' { + local nbi`i':word `i' of `kernel' + local nbkerk=`nbkerk'+`nbi`i'' + local deb`i'=`fin`=`i'-1''+1 + local fin`i'=`deb`i''+`nbi`i''-1 + local list`i' + forvalues j=`deb`i''/`fin`i'' { + local list`i' `list`i'' ``j'' + } + } + tempname kerclus + matrix `kerclus'=J(`=`nbkerk'-`nbkerg'',3,0) + local ligne=1 + forvalues g=1/`nbkerg' { + matrix `kerclus'[`ligne',1]=`nbitems'+`ligne' + matrix `kerclus'[`ligne',2]=`deb`g'' + matrix `kerclus'[`ligne',3]=`deb`g''+1 + local clus`g'=`nbitems'+`ligne' + local ligne=`ligne'+1 + if `nbi`g''>2 { + forvalues i=2/`=`nbi`g''-1' { + matrix `kerclus'[`ligne',1]=`nbitems'+`ligne' + matrix `kerclus'[`ligne',2]=`deb`g''+`i' + matrix `kerclus'[`ligne',3]=`nbitems'+`ligne'-1 + local clus`g'=`nbitems'+`ligne' + local ligne=`ligne'+1 + } + } + } +} +if `nbitems'<`nbkerk' { + di in red "You cannot define more variables in the {hi:kernel} option than items in the {hi:varlist}" + error 198 + exit +} +di +di in green "{hline 30}" +di in green "TOTAL VARIANCE: " in ye %14.3f `totvar' +di in green "NUMBER OF INDIVIDUALS: " in ye %7.0f `nbind' +di in green "METHOD:" in ye _col(`=31-length("`method'")') "`=upper("`method'")'" +di in green "{hline 30}" +di +if "`kernel'"!="" { + forvalues i=1/`nbkerg' { + di in green "The kernel numbered " in ye `clus`i'' in green " is composed of `nbi`i'' variables: " in ye "`list`i''" + di + } +} +else { + local nbkerk=0 + local nbkerg=0 +} +tempname Ev +if `none'!=1 { + matrix `matclus'=J(`nbitems',`nbitems',0) + matrix `vp'=J(`=2*`nbitems'-1',10,0) + forvalues i=1/`nbitems' { + matrix `matclus'[`i',1]=`i' + if "`method'"!="polychoric"&"`method'"!="polychoric" { + qui su ``i'' + matrix `vp'[`i',1]=r(Var) + } + else { + matrix `vp'[`i',1]=1 + } + matrix `vp'[`i',8]=`i' + matrix `vp'[`i',9]=`totvar' + matrix `vp'[`i',10]=100 + } + matrix `vp'[`nbitems',3]=`nbitems' + if "`method'"=="centroid" { + local crit G + di in green "{hline 89}" + di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(82) "Relative" + di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Variation" + di in green "{hline 89}" + } + else { + local crit T + di in green "{hline 100}" + if "`method'"=="v2"|"`method'"=="polychoricv2" { + di in green _col(84) "Maximal" + } + else { + di in green _col(84) "Current" + } + di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(85) "Second" _col(93) "Relative" + di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Eigenvalue" _col(92) "Variation" + di in green "{hline 100}" + } + tempname threshold + matrix `threshold'=J(`nbitems',3,0) + forvalues i=1/`=`nbitems'-1' { + local clus=`nbitems'+`i' + local minegenval=999999 + local minegenval2=999999 + forvalues k=1/`=`clus'-1' { + local list`k' + local numlist`k' + forvalues j=1/`clus' { + if (`matclus'[`j',`i']==`k') { + local list`k' `list`k'' ``j'' + local numlist`k' `numlist`k'' `j' + } + } + } + if `clus'>`nbitems'+`nbkerk'-`nbkerg' { + if "`method'"=="centroid" { + tempname centrj centrk diffjk + } + forvalues j=1/`clus' { + local nblistj:word count `list`j'' + forvalues k=`=`j'+1'/`clus' { + local nblistk:word count `list`k'' + if `nblistj'!=0&`nblistk'!=0 { + if "`method'"=="centroid" { + qui genscore `list`j'',score(`centrj') mean + qui su `centrj' + local Varj=r(Var) + qui genscore `list`k'',score(`centrk') mean + qui su `centrk' + local Vark=r(Var) + qui gen `diffjk'=`centrk'-`centrj' + qui su `diffjk' + local Varjk=r(Var) + drop `centrj' `centrk' `diffjk' + local ev=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`Varjk' + if `ev'<`minegenval' { + local minegenval=`ev' + local minj `j' + local mink `k' + local eigen=0 + local eigen2=0 + } + } + else { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`j'' `list`k'',cov + matrix `Ev'=e(Ev) + } + else if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + qui polychoricpca `list`j'' `list`k'' + matrix `Ev'=r(eigenvalues) + } + local lambda1=`Ev'[1,1] + local lambda2=`Ev'[1,2] + local ev=`vp'[`j',1]+`vp'[`k',1]-`lambda1' +/* + local t1=`vp'[`j',1] + local t2=`vp'[`k',1] + di "`ev'=`t1'+`t2'-`lambda1'" +*/ + local ev2=max(`vp'[`j',5],`vp'[`k',5],`lambda2') + if ("`method'"=="v2"|"`method'"=="polychoricv2")&`ev'<`minegenval' { + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`lambda2' + } + else if ("`method'"=="classical"|"`method'"=="polychoric")&`ev2'<`minegenval2' { + local minegenval=`ev' + local minegenval2=`ev2' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`ev2' + } + } + } + } + } + } + else { + local ligne=`clus'-`nbitems' + local j=`kerclus'[`ligne',2] + local k=`kerclus'[`ligne',3] + if "`method'"!="centroid" { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`j'' `list`k'',cov + matrix `Ev'=e(Ev) + } + else if "`method'"=="polychoric"|"`method'"=="polychoricv2"{ + qui polychoricpca `list`j'' `list`k'' + matrix `Ev'=r(eigenvalues) + } + local lambda1=`Ev'[1,1] + local lambda2=`Ev'[1,2] + local ev=`vp'[`j',1]+`vp'[`k',1]-`lambda1' + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`lambda2' + } + else if "`method'"=="centroid" { + local nblistj:word count `list`j'' + local nblistk:word count `list`k'' + tempname v1 v2 v12 + qui genscore `list`j'',score(`v1') mean + qui genscore `list`k'',score(`v2') mean + qui gen `v12'=`v1'-`v2' + qui su `v12' + local varj=r(Var) + local minegenval=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`varj' + local minj `j' + local mink `k' + } + } + if `minj'<=`nbitems' { + local nomj=abbrev("``minj''",14) + } + else { + local nomj `minj' + } + *set trace off + if `mink'<=`nbitems' { + local nomk=abbrev("``mink''",14) + } + else { + local nomk `mink' + } + forvalues j=1/`nbitems' { + matrix `matclus'[`j',`=`i'+1']=`matclus'[`j',`i'] + } + if "`method'"!="centroid" { + matrix `vp'[`clus',1]=`eigen' /*FIRST EIGEN VALUE OF THE NEW CLUSTER*/ + matrix `vp'[`clus',2]=`minegenval' /*VARIATION OF THE T CRITERION*/ + matrix `vp'[`clus',3]=`vp'[`=`clus'-1',3]-`vp'[`clus',2] /*T CRITERION*/ + matrix `vp'[`clus',4]=`vp'[`clus',2]/`vp'[`=`clus'-1',3] /*RELATIVE VARIATION OF THE T CRITERION*/ + matrix `vp'[`clus',5]=`eigen2' /*SECOND EIGEN VALUE OF THE NEW CLUSTER*/ + matrix `vp'[`clus',6]=`minj' /*CHILD 1*/ + matrix `vp'[`clus',7]=`mink' /*CHILD 2*/ + matrix `vp'[`clus',8]=`nbitems'+`i' /*NUMBER OF THE NEW CLUSTER*/ + matrix `vp'[`clus',9]=`vp'[`=`clus'-1',9]-`minegenval' /*EXPLAINED VARIANCE*/ + matrix `vp'[`clus',10]=`vp'[`clus',9]/`totvar'*100 /*% OF EXPLAINED VARIANCE*/ + } + else { + matrix `vp'[`clus',1]=0 /*FIRST EIGEN VALUE OF THE NEW CLUSTER*/ + matrix `vp'[`clus',2]=`minegenval' /*VARIATION OF THE G CRITERION*/ + matrix `vp'[`clus',3]=`vp'[`=`clus'-1',3]-`vp'[`clus',2] /*G CRITERION*/ + matrix `vp'[`clus',4]=`vp'[`clus',2]/`vp'[`=`clus'-1',3] /*RELATIVE VARIATION OF THE T CRITERION*/ + matrix `vp'[`clus',5]=0 /*SECOND EIGEN VALUE OF THE NEW CLUSTER*/ + matrix `vp'[`clus',6]=`minj' /*CHILD 1*/ + matrix `vp'[`clus',7]=`mink' /*CHILD 2*/ + matrix `vp'[`clus',8]=`nbitems'+`i' /*NUMBER OF THE NEW CLUSTER*/ + matrix `vp'[`clus',9]=`vp'[`=`clus'-1',9]-`minegenval' /*EXPLAINED VARIANCE*/ + matrix `vp'[`clus',10]=`vp'[`clus',9]/`totvar'*100 /*% OF EXPLAINED VARIANCE*/ + } + foreach j of numlist `numlist`minj'' `numlist`mink'' { + matrix `matclus'[`j',`=`i'+1']=`clus' + } + if "`kernel'"!=""&`i'==`=`nbkerk'-`nbkerg'+1' { + local T=`vp'[`=`clus'-1',9] + di _col(0) in ye "init" _col(12) %4.0f `=`nbitems'-`nbkerk'+`nbkerg'' _col(52) %8.4f `T' _col(62) %8.4f `=`totvar'-`T'' _col(72) %7.3f `=`T'/`totvar'*100' "%" + } + if `clus'>`nbitems'+`nbkerk'-`nbkerg' { + if `clus'==`nbitems'+`nbkerk'-`nbkerg'+1 { + local relv + local percent + } + else { + local relv=(`minegenval'-`vp'[`=`clus'-1',2])/`vp'[`=`clus'-1',3]*100 + local percent % + matrix `threshold'[`=`nbitems'-`i'+1',1]=`relv' + matrix `threshold'[`=`nbitems'-`i'+1',3]=`minegenval' + if `i'>1 { + matrix `threshold'[`=`nbitems'-`i'+1',2]=`relv'-`threshold'[`=`nbitems'-`i'+2',1] + } + } + if "`method'"=="centroid" { + di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',9] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',10] "%" _col(83) _col(84) %5.2f `relv' "`percent'" + } + else { + di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',9] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',10] "%" _col(83) %8.4f `vp'[`clus',5] _col(95) %5.2f `relv' "`percent'" + } + } + } + local i=2*`nbitems'-1 + local relv=(`vp'[`i',3]-`vp'[`i',2])/`vp'[`i',3]*100 + if "`method'"=="centroid" { + di in ye _col(84) %5.2f `relv' "`percent'" + } + else { + di in ye _col(95) %5.2f `relv' "`percent'" + } + matrix `threshold'[1,1]=`relv' + matrix `threshold'[1,2]=`relv'-`threshold'[2,1] + matrix `threshold'[1,3]=`vp'[`i',3] + *matrix list `threshold' + local best=0 + local maxbest=0 + local best2=0 + local maxbest2=0 + forvalues i=1/`nbitems' { + if `threshold'[`i',3]>`maxbest2' { + if `threshold'[`i',3]>`maxbest' { + local maxbest2=`maxbest' + local best2=`best' + local maxbest=`threshold'[`i',3] + local best=`i' + } + else { + local maxbest2=`threshold'[`i',3] + local best2=`i' + } + } + } + di in green "{hline 100}" + di in green "Proposed best partitions: " + di in green "Based on the variation of the T criterion" + di in green _col(10) "1. Partitions in " in ye `best' in green " clusters" + di in green _col(10) "2. Partitions in " in ye `best2' in green " clusters" + return local bestvariation `best' `best2' + local bestt=0 + local bestt2=0 + local var=0 + local var2=0 + forvalues i=1/`nbitems' { + if `threshold'[`i',2]>`var2'&`i'<`nbitems'-1 { + if `threshold'[`i',2]>`var' { + local bestt2=`bestt' + local var2=`var' + local var=`threshold'[`i',2] + local bestt=`i' + } + else { + local var2=`threshold'[`i',2] + local bestt2=`i' + } + } + } + di in green "Based on a research of a threshold" + di in green _col(10) "1. Partitions in " in ye `bestt' in green " clusters" + di in green _col(10) "2. Partitions in " in ye `bestt2' in green " clusters" + forvalues i=`=`nbitems'+1'/`=`nbitems'+`nbkerk'-`nbkerg'' { + matrix `vp'[`i',2]=`totvar'-`T' + matrix `vp'[`i',9]=`T' + matrix `vp'[`i',10]=`T'/`nbitems'*100 + } + return local bestthresold `bestt' `bestt2' +} + +if "`bar'"!="" { + drop _all + qui set obs `nbitems' + qui svmat `vp' ,names(v) + qui drop in 1/`nbitems' + qui gen id=`nbitems'-_n + qui drop if id>`nbitems'-`nbkerk'+`nbkerg'-1 + label variable id "Number of clusters" + label variable v2 "T variation" + graph twoway bar v2 id, name(bar,replace) vert ,ylabel(0(0.5)2) xlabel(1(1)`=`nbitems'-`nbkerk'+`nbkerg'-1') +} + +drop _all +qui set obs `nbitems' +qui svmat `matclus' ,names(v) +local listorder +forvalues i=`nbitems'(-1)1 { + local listorder `listorder' v`i' +} +qui gen id=_n +qui sort `listorder' + +capture cluster delete clv,zap +qui cluster complete v* ,name(clv) + +qui replace clv_id=_n +qui replace clv_ord=id +qui replace clv_hgt=. + +qui gen fait=0 +qui gen clus=0 +forvalues i=2/`nbitems' { + local ligne=`nbitems'+`i'-1 + if (`vp'[`ligne',6]<=`nbitems') { + local first=`vp'[`ligne',6] + gsort +fait -v`i' +clv_id + } + else { + local first=`vp'[`ligne',7] + gsort +fait -v`i' +clv_id + } + if "`deltaT'"!="" { + qui replace clv_hgt=`vp'[`ligne',2] in 1 + } + else { + qui replace clv_hgt=100-`vp'[`ligne',10] in 1 + } + qui replace fait=1 in 1 + qui replace clus=`vp'[`ligne',8] in 1 +} +qui gen label="" +forvalues i=1/`nbitems' { + qui replace label=abbrev("`label`i''",`abbrev') if clv_id==`i' +} +sort clv_id +if `nbitems'>`cutnumber' { + local var "Groups of variables" + local cut cutnumber(`cutnumber') /*labcutn*/ +} +else { + local var "Variables" + local cut label(label) +} +qui su clv_hgt +local tmp=r(max) +local max=floor(`tmp')+.5 +if `tmp'>`max' { + local max=`max'+.5 +} +local maxvar=`max'+5 +if "`dendro'"=="" { + if "`title'"=="" { + local title "Clustering around Latent Variables (CLV)" + } + if "`caption'"!="" { + local var "`caption'" + } + if "`deltaT'"!="" { + local titleL "Variation of the T criterion" + local yl "0(.5)`max'" + } + else { + local titleL "% Unexplained Variance" + local yl "0(25)`maxvar'" + } + if "`horizontal'"!="" { + cluster dendro clv, name (dendrogram,replace) hor ytitle("`var'") `showcount' xtitle("`titleL'") title("`title'",span) xlabel(`yl') ylabel(,angle(0)) `cut' + } + else { + cluster dendro clv, name(dendrogram,replace) xtitle("`var'") `showcount' ytitle("`titleL'") title("`title'",span) ylabel(`yl') `cut' + } +} + +if `cons'>`nbitems'-`nbkerk'+`nbkerg' { + di in ye "The {hi:consolidation} is not possible for a number of clusters superior to the initial number of clusters" + local cons=0 +} + +/* +if `cons'!=0&("`method'"=="polychoric"|"`method'"=="polychoricv2") { + di in ye "The {hi:consolidation} is not possible with the {hi:polychoric} methods" + local cons=0 +} +*/ + +if `cons'!=0 { + sort v`=`nbitems'-`cons'+1' + gen cut`cons'=1 + local g=1 + forvalues i=2/`nbitems' { + if v`=`nbitems'-`cons'+1'[`i']!=v`=`nbitems'-`cons'+1'[`=`i'-1'] { + local g=`g'+1 + } + qui replace cut`cons'=`g' in `i' + } + sort id + tempname group + mkmat cut`cons',matrix(`group') + + *cluster generate cut = groups(2/9) , name(clv) + use `clvfiletmp',replace + + local n=1 + local env=1 + while (`env'==1) { + forvalues g=1/`cons' { + local list`g' + forvalues i=1/`nbitems' { + if `group'[`i',1]==`g' { + local list`g' `list`g'' ``i'' + } + } + } + di + if `n'==1 { + di in green "{hline 30}" + di in green "PARTITION BEFORE CONSOLIDATION" + di in green "{hline 30}" + } + di + local col=1 + local max=0 + *set trace on + local critT=0 + forvalues g=1/`cons' { + di _col(`col') in green "GROUP " %2.0f `g' _c + local col=`col'+10 + local tmp`g':word count `list`g'' + if `tmp`g''>`max' { + local max `tmp`g'' + } + tempvar f1`g' + if "`method'"=="centroid" { + qui genscore `list`g'',score(`f1`g'') mean + qui su `f1`g'' + local var=r(Var) + local critT=`critT'+`tmp`g''*`var' + } + else { + if `tmp`g''>1 { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`g'',cov + matrix `Ev'=e(Ev) + qui predict `f1`g'' + } + else if "`method'"=="polychoric"|"`method'"=="polychoric" { + qui polychoricpca `list`g'',score(`f1`g'') nscore(1) + matrix `Ev'=r(eigenvalues) + rename `f1`g''1 `f1`g'' + } + local lambda1=`Ev'[1,1] + local critT=`critT'+`lambda1' + } + else { + qui gen `f1`g''=`list`g'' + if "`standardized'"=="" { + local critT=`critT'+1 + } + else { + qui su + local critT=`critT'+`r(Var)' + } + } + } + } + di + forvalues i=1/`max' { + local col=1 + forvalues g=1/`cons' { + local tmpv:word `i' of `list`g'' + local tmpv=abbrev("`tmpv'",8) + di _col(`col') in ye %8s "`tmpv'" _c + local col= `col'+10 + } + di + } + di + di in green "Variance Explained : " in ye %6.3f `=`critT'/`totvar'*100' in green "%" + di in green "T criterion : " in ye %6.4f `critT' + di + di in green "{hline 21}" + di in green "CONSOLIDATION: STEP `n'" + di in green "{hline 21}" + local n=`n'+1 + local env=0 + if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + local command polychoric + } + else { + local command corr + } + forvalues i=1/`nbitems' { + local env`i'=0 + local gr=`group'[`i',1] + qui `command' ``i'' `f1`gr'' + local corr`i'=r(rho) + local corrs`i'=r(rho) + forvalues g=1/`cons' { + qui `command' ``i'' `f1`g'' + local tmpcorr=r(rho) + if ((`corr`i'')<(`tmpcorr')&"`method'"=="centroid")|((`corr`i'')^2<(`tmpcorr')^2& "`method'"!="centroid") { + local env=1 + local env`i'=1 + matrix `group'[`i',1]=`g' + local corr`i'=`tmpcorr' + } + } + if `env`i''==1 { + local g=`group'[`i',1] + di in green "The variable " in ye "``i'' " in green "is assigned to the `g'th group" _c + if "`method'"!="centroid" { + di in green " (corr^2=" %6.4f in ye (`corr`i'')^2 in green " vs " in ye %6.4f (`corrs`i'')^2 in green ")" + } + else { + di in green " (corr=" %6.4f in ye (`corr`i'') in green " vs " in ye %6.4f (`corrs`i'') in green ")" + } + + } + } + if `env'==0 { + local latent + forvalues g=1/`cons' { + label variable `f1`g'' "Latent variable `g'" + local latent `latent' `f1`g'' + return local cluster`g' `list`g'' + } + matrix `group'=`group'' + matrix colnames `group'=`varlist' + return matrix affect=`group' + di in ye "Stability of the partition is achieved" + if `cons'<=7 { + di + di in green "{hline 42}" + di in green "CORRELATION MATRIX OF THE LATENT VARIABLES" + di in green "{hline 42}" + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+23') in green "Latent" _c + } + di + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+19') in green "variable `g'" _c + } + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di in green "Latent variable `g'" _c + forvalues h=1/`cons' { + local loc=13*`h'+10 + qui corr `f1`g'' `f1`h'' + local rho=r(rho) + di _col(`loc') in ye %6.4f `rho' _c + } + di + } + di in green "{hline `=(`cons')*13+15'}" + di + } + if `nbind'<=800&"`biplot'"=="" { + local max=max(`matsize',`nbind') + set matsize `max' + if "`addvar'"!="" { + local add `varlist' + } + qui biplotvlab `latent' `add', name(biplot,replace) norow colopts(name(latent variables)) alpha(0) title(Biplot of the latent variables) labdes(size(vsmall) color(blue)) stretch(1) + } + else { + di in green "There is more than 800 individuals, so the {hi:biplot} is disabled" + } + } + forvalues g=1/`cons' { + drop `f1`g'' + } + } +} +set matsize `matsize' +use `clvfile',replace +capture cluster delete clv,zap +return matrix vp=`vp' +return matrix matclus=`matclus' +return local varlist `varlist' +return local method `method' +return local kernel `kernel' +end diff --git a/Modules/ado/personal/c/clv29.ado b/Modules/ado/personal/c/clv29.ado new file mode 100644 index 0000000..4a9180b --- /dev/null +++ b/Modules/ado/personal/c/clv29.ado @@ -0,0 +1,798 @@ +*! Version 2.9 9December2005 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : clv +* Clustering of variables around latent variables +* Version 2.9 : December 9, 2005 /*save the latent variables*/ +* +* Historic +* Version 1 (2005-06-11): Jean-Benoit Hardouin +* Version 1.1 (2005-07-07): Jean-Benoit Hardouin /*small bug in the consolidation process with cluster of only one variable*/ +* Version 1.2 (2005-07-08): Jean-Benoit Hardouin /*Bug in the consolidation procedure when there is negative correlation*/ +* Version 2 (2005-09-03): Jean-Benoit Hardouin /*Horizontal dendrograms (with Stata 9)*/ +* Version 2.1 (2005-09-08): Jean-Benoit Hardouin /*More flexibility to abbreviate the names of the variables (with Stata 9)*/ +* Version 2.1.1 (2005-09-08): Jean-Benoit Hardouin /*Integration of some requests of Ronan Conroy*/ +* Version 2.1.2 (2005-09-08): Jean-Benoit Hardouin /*Possibility to give a title and an X/Y caption*/ +* Version 2.2 (2005-09-11): Jean-Benoit Hardouin /*Kernel option*/ +* Version 2.3 (2005-09-12): Jean-Benoit Hardouin /*Polychoric option*/ +* Version 2.4 (2005-09-13): Jean-Benoit Hardouin /*v2 option*/ +* Version 2.5 (2005-09-21): Jean-Benoit Hardouin /*corrections*/ +* Version 2.6 (2005-10-02): Jean-Benoit Hardouin /*centroid method, biplot*/ +* Version 2.7 (2005-10-06): Jean-Benoit Hardouin /*return, multiple graphs, polychoric+consolidation*/ +* Version 2.8 (2005-10-06): Jean-Benoit Hardouin /*fweights*/ +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@orscentre.org +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2005 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ +program define clv,rclass +version 9.0 +syntax [varlist(default=none)] [if] [in] [fweight] [, CUTnumber(int 30) bar CONSolidation(int 0) noDENdro noSTANDardized deltaT HORizontal SHOWcount ABBrev(int 14) TITle(string) CAPtion(string) KERnel(numlist) METHod(string) noBIPlot ADDvar genlv(string)] +preserve +tempfile clvfile +qui save `clvfile',replace +local matsize=c(matsize) +local none=0 +if "`varlist'"=="" { + capture confirm matrix r(vp) + if _rc==0 { + capture confirm matrix r(matclus) + if _rc ==0 { + local none=1 + } + } + if `none'==0 { + di in red "You cannot use the {hi:clv} command without {hi:varlist} if you have not already run {hi:clv}" + error 198 + exit + } +} + +tempname matclus vp + +if `none'==1 { + matrix `vp'=r(vp) + matrix `matclus'=r(matclus) + local varlist `r(varlist)' + tokenize `varlist' + local nbitems=rowsof(`matclus') + if "`method'"!="" { + di in green "The {hi:method} option can not be modified without specification of the varlist. {hi:method} is omitted." + } + local method `r(method)' + local kernel `r(kernel)' +} +if "`method'"=="" { + local method classical +} +if ("`method'"=="polychoric"|"`method'"=="polychoricv2")&"`standardized'"!="" { + di in green "Initial variables are used with the {hi:polychoric} methods" + di in green "But the procedure is based on the matrix of the polychoric correlations" + di +} +if "`method'"!="classical"&"`method'"!="v2"&"`method'"!="centroid"&"`method'"!="polychoric"&"`method'"!="polychoricv2" { + di in red "The {hi:method} `method' is unknown" + error 198 + exit +} + +tokenize `varlist' +local nbitems : word count `varlist' +marksample touse +qui keep if `touse' + +local mat=max(`matsize',`=`nbitems'*2') +qui set matsize `mat' + +if `nbitems'<3&`none'!=1 { + di in red "You need at least 3 variables" + error 198 + exit +} +forvalues i=1/`nbitems'{ + local label`i':variable label ``i'' + if "`label`i''"=="" { + local label`i' ``i'' + } + if "`method'"!="polychoric"&"`method'"!="polychoricv2" { + qui su ``i'' [`weight'`exp'] + local mean=r(mean) + if "`standardized'"=="" { + local sd=r(sd) + } + else { + local sd=1 + } + qui replace ``i''=(``i''-`mean')/`sd' + } +} + +tempfile clvfiletmp +qui save `clvfiletmp',replace + +qui su `1' [`weight'`exp'] +local nbind=r(sum_w) + + +local cons=`consolidation' + +if "`method'"!="polychoric"&"`method'"!="polychoricv2" { + local totvar=0 + forvalues i=1/`nbitems' { + qui su ``i'' [`weight'`exp'] + local totvar=`totvar'+`r(Var)' + } +} +else { + local totvar `nbitems' +} +local nbkerk=0 +local nbkerg=0 + +if "`kernel'"!="" { + local nbkerg:word count `kernel' + local fin0=0 + forvalues i=1/`nbkerg' { + local nbi`i':word `i' of `kernel' + local nbkerk=`nbkerk'+`nbi`i'' + local deb`i'=`fin`=`i'-1''+1 + local fin`i'=`deb`i''+`nbi`i''-1 + local list`i' + forvalues j=`deb`i''/`fin`i'' { + local list`i' `list`i'' ``j'' + } + } + tempname kerclus + matrix `kerclus'=J(`=`nbkerk'-`nbkerg'',3,0) + local ligne=1 + forvalues g=1/`nbkerg' { + matrix `kerclus'[`ligne',1]=`nbitems'+`ligne' + matrix `kerclus'[`ligne',2]=`deb`g'' + matrix `kerclus'[`ligne',3]=`deb`g''+1 + local clus`g'=`nbitems'+`ligne' + local ligne=`ligne'+1 + if `nbi`g''>2 { + forvalues i=2/`=`nbi`g''-1' { + matrix `kerclus'[`ligne',1]=`nbitems'+`ligne' + matrix `kerclus'[`ligne',2]=`deb`g''+`i' + matrix `kerclus'[`ligne',3]=`nbitems'+`ligne'-1 + local clus`g'=`nbitems'+`ligne' + local ligne=`ligne'+1 + } + } + } +} +if `nbitems'<`nbkerk' { + di in red "You cannot define more variables in the {hi:kernel} option than items in the {hi:varlist}" + error 198 + exit +} +di +di in green "{hline 30}" +di in green "TOTAL VARIANCE: " in ye %14.3f `totvar' +di in green "NUMBER OF INDIVIDUALS: " in ye %7.0f `nbind' +di in green "METHOD:" in ye _col(`=31-length("`method'")') "`=upper("`method'")'" +di in green "{hline 30}" +di +if "`kernel'"!="" { + forvalues i=1/`nbkerg' { + di in green "The kernel numbered " in ye `clus`i'' in green " is composed of `nbi`i'' variables: " in ye "`list`i''" + di + } +} +else { + local nbkerk=0 + local nbkerg=0 +} +tempname Ev +if `none'!=1 { + matrix `matclus'=J(`nbitems',`nbitems',0) + matrix `vp'=J(`=2*`nbitems'-1',10,0) + forvalues i=1/`nbitems' { + matrix `matclus'[`i',1]=`i' + if "`method'"!="polychoric"&"`method'"!="polychoric" { + qui su ``i'' [`weight'`exp'] + matrix `vp'[`i',1]=r(Var) + } + else { + matrix `vp'[`i',1]=1 + } + matrix `vp'[`i',8]=`i' + matrix `vp'[`i',9]=`totvar' + matrix `vp'[`i',10]=100 + } + matrix `vp'[`nbitems',3]=`nbitems' + if "`method'"=="centroid" { + local crit G + di in green "{hline 89}" + di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(82) "Relative" + di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Variation" + di in green "{hline 89}" + } + else { + local crit T + di in green "{hline 100}" + if "`method'"=="v2"|"`method'"=="polychoricv2" { + di in green _col(84) "Maximal" + } + else { + di in green _col(84) "Current" + } + di in green _col(7) "Number of" _col(69) "`crit'" _col(71) "Explained" _col(85) "Second" _col(93) "Relative" + di in green "Step" _col(8) "clusters" _col(20) "Child 1" _col(33) "Child 2" _col(46) "Parent" _col(53) "`crit' value" _col(61) "variation" _col(72) "Variance" _col(81) "Eigenvalue" _col(92) "Variation" + di in green "{hline 100}" + } + tempname threshold + matrix `threshold'=J(`nbitems',3,0) + forvalues i=1/`=`nbitems'-1' { + local clus=`nbitems'+`i' + local minegenval=999999 + local minegenval2=999999 + forvalues k=1/`=`clus'-1' { + local list`k' + local numlist`k' + forvalues j=1/`clus' { + if (`matclus'[`j',`i']==`k') { + local list`k' `list`k'' ``j'' + local numlist`k' `numlist`k'' `j' + } + } + } + if `clus'>`nbitems'+`nbkerk'-`nbkerg' { + if "`method'"=="centroid" { + tempname centrj centrk diffjk + } + forvalues j=1/`clus' { + local nblistj:word count `list`j'' + forvalues k=`=`j'+1'/`clus' { + local nblistk:word count `list`k'' + if `nblistj'!=0&`nblistk'!=0 { + if "`method'"=="centroid" { + qui genscore `list`j'',score(`centrj') mean + qui su `centrj' [`weight'`exp'] + local Varj=r(Var) + qui genscore `list`k'',score(`centrk') mean + qui su `centrk' [`weight'`exp'] + local Vark=r(Var) + qui gen `diffjk'=`centrk'-`centrj' + qui su `diffjk' [`weight'`exp'] + local Varjk=r(Var) + drop `centrj' `centrk' `diffjk' + local ev=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`Varjk' + if `ev'<`minegenval' { + local minegenval=`ev' + local minj `j' + local mink `k' + local eigen=0 + local eigen2=0 + } + } + else { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`j'' `list`k'' [`weight'`exp'] ,cov + matrix `Ev'=e(Ev) + } + else if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + qui polychoricpca `list`j'' `list`k'' [`weight'`exp'] + matrix `Ev'=r(eigenvalues) + } + local lambda1=`Ev'[1,1] + local lambda2=`Ev'[1,2] + local ev=`vp'[`j',1]+`vp'[`k',1]-`lambda1' + local ev2=max(`vp'[`j',5],`vp'[`k',5],`lambda2') + if ("`method'"=="v2"|"`method'"=="polychoricv2")&`ev'<`minegenval' { + local eigen2=`lambda2' + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + } + else if ("`method'"=="classical"|"`method'"=="polychoric")&`ev2'<`minegenval2' { + local minegenval2=`ev2' + local eigen2=`ev2' + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + } + } + } + } + } + } + else { + local ligne=`clus'-`nbitems' + local j=`kerclus'[`ligne',2] + local k=`kerclus'[`ligne',3] + if "`method'"!="centroid" { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`j'' `list`k'' [`weight'`exp'],cov + matrix `Ev'=e(Ev) + } + else if "`method'"=="polychoric"|"`method'"=="polychoricv2"{ + qui polychoricpca `list`j'' `list`k'' [`weight'`exp'] + matrix `Ev'=r(eigenvalues) + } + local lambda1=`Ev'[1,1] + local lambda2=`Ev'[1,2] + local ev=`vp'[`j',1]+`vp'[`k',1]-`lambda1' + local minegenval=`ev' + local eigen=`lambda1' + local minj `j' + local mink `k' + local eigen2=`lambda2' + } + else if "`method'"=="centroid" { + local nblistj:word count `list`j'' + local nblistk:word count `list`k'' + tempname v1 v2 v12 + qui genscore `list`j'',score(`v1') mean + qui genscore `list`k'',score(`v2') mean + qui gen `v12'=`v1'-`v2' + qui su `v12' [`weight'`exp'] + local varj=r(Var) + local minegenval=(`nblistj'*`nblistk')/(`nblistj'+`nblistk')*`varj' + local minj `j' + local mink `k' + } + } + if `minj'<=`nbitems' { + local nomj=abbrev("``minj''",14) + } + else { + local nomj `minj' + } + *set trace off + if `mink'<=`nbitems' { + local nomk=abbrev("``mink''",14) + } + else { + local nomk `mink' + } + forvalues j=1/`nbitems' { + matrix `matclus'[`j',`=`i'+1']=`matclus'[`j',`i'] + } + if "`method'"!="centroid" { + matrix `vp'[`clus',1]=`eigen' /*FIRST EIGEN VALUE OF THE NEW CLUSTER*/ + matrix `vp'[`clus',2]=`minegenval' /*VARIATION OF THE T CRITERION*/ + matrix `vp'[`clus',3]=`vp'[`=`clus'-1',3]-`vp'[`clus',2] /*T CRITERION*/ + matrix `vp'[`clus',4]=`vp'[`clus',2]/`vp'[`=`clus'-1',3] /*RELATIVE VARIATION OF THE T CRITERION*/ + matrix `vp'[`clus',5]=`eigen2' /*SECOND EIGEN VALUE OF THE NEW CLUSTER*/ + matrix `vp'[`clus',6]=`minj' /*CHILD 1*/ + matrix `vp'[`clus',7]=`mink' /*CHILD 2*/ + matrix `vp'[`clus',8]=`nbitems'+`i' /*NUMBER OF THE NEW CLUSTER*/ + matrix `vp'[`clus',9]=`vp'[`=`clus'-1',9]-`minegenval' /*EXPLAINED VARIANCE*/ + matrix `vp'[`clus',10]=`vp'[`clus',9]/`totvar'*100 /*% OF EXPLAINED VARIANCE*/ + } + else { + matrix `vp'[`clus',1]=0 /*FIRST EIGEN VALUE OF THE NEW CLUSTER*/ + matrix `vp'[`clus',2]=`minegenval' /*VARIATION OF THE G CRITERION*/ + matrix `vp'[`clus',3]=`vp'[`=`clus'-1',3]-`vp'[`clus',2] /*G CRITERION*/ + matrix `vp'[`clus',4]=`vp'[`clus',2]/`vp'[`=`clus'-1',3] /*RELATIVE VARIATION OF THE T CRITERION*/ + matrix `vp'[`clus',5]=0 /*SECOND EIGEN VALUE OF THE NEW CLUSTER*/ + matrix `vp'[`clus',6]=`minj' /*CHILD 1*/ + matrix `vp'[`clus',7]=`mink' /*CHILD 2*/ + matrix `vp'[`clus',8]=`nbitems'+`i' /*NUMBER OF THE NEW CLUSTER*/ + matrix `vp'[`clus',9]=`vp'[`=`clus'-1',9]-`minegenval' /*EXPLAINED VARIANCE*/ + matrix `vp'[`clus',10]=`vp'[`clus',9]/`totvar'*100 /*% OF EXPLAINED VARIANCE*/ + } + foreach j of numlist `numlist`minj'' `numlist`mink'' { + matrix `matclus'[`j',`=`i'+1']=`clus' + } + if "`kernel'"!=""&`i'==`=`nbkerk'-`nbkerg'+1' { + local T=`vp'[`=`clus'-1',9] + di _col(0) in ye "init" _col(12) %4.0f `=`nbitems'-`nbkerk'+`nbkerg'' _col(52) %8.4f `T' _col(62) %8.4f `=`totvar'-`T'' _col(72) %7.3f `=`T'/`totvar'*100' "%" + } + if `clus'>`nbitems'+`nbkerk'-`nbkerg' { + if `clus'==`nbitems'+`nbkerk'-`nbkerg'+1 { + local relv + local percent + } + else { + local relv=(`minegenval'-`vp'[`=`clus'-1',2])/`vp'[`=`clus'-1',3]*100 + local percent % + matrix `threshold'[`=`nbitems'-`i'+1',1]=`relv' + matrix `threshold'[`=`nbitems'-`i'+1',3]=`minegenval' + if `i'>1 { + matrix `threshold'[`=`nbitems'-`i'+1',2]=`relv'-`threshold'[`=`nbitems'-`i'+2',1] + } + } + if "`method'"=="centroid" { + di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',9] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',10] "%" _col(83) _col(84) %5.2f `relv' "`percent'" + } + else { + di _col(0) in ye %4.0f `=`i'-`nbkerk'+`nbkerg'' _col(12) %4.0f `=`nbitems'-`i'' _col(20) "`nomj'" _col(33) "`nomk'" _col(45) %7.0f `=`i'+`nbitems'' _col(52) %8.4f `vp'[`clus',9] _col(62) %8.4f `minegenval' _col(72) %7.3f `vp'[`clus',10] "%" _col(83) %8.4f `vp'[`clus',5] _col(95) %5.2f `relv' "`percent'" + } + } + } + local i=2*`nbitems'-1 + local relv=(`vp'[`i',3]-`vp'[`i',2])/`vp'[`i',3]*100 + if "`method'"=="centroid" { + di in ye _col(84) %5.2f `relv' "`percent'" + } + else { + di in ye _col(95) %5.2f `relv' "`percent'" + } + matrix `threshold'[1,1]=`relv' + matrix `threshold'[1,2]=`relv'-`threshold'[2,1] + matrix `threshold'[1,3]=`vp'[`i',3] + *matrix list `threshold' + local best=0 + local maxbest=0 + local best2=0 + local maxbest2=0 + forvalues i=1/`nbitems' { + if `threshold'[`i',3]>`maxbest2' { + if `threshold'[`i',3]>`maxbest' { + local maxbest2=`maxbest' + local best2=`best' + local maxbest=`threshold'[`i',3] + local best=`i' + } + else { + local maxbest2=`threshold'[`i',3] + local best2=`i' + } + } + } + di in green "{hline 100}" + di + di in green "{hline 24}" + di in green "PROPOSED BEST PARTITIONS" + di in green "{hline 24}" + di + di in yellow _col(4) "Based on the variation of the T criterion" + di in green _col(10) "1. Partitions in " in ye `best' in green " clusters" + di in green _col(10) "2. Partitions in " in ye `best2' in green " clusters" + return local bestvariation `best' `best2' + local bestt=0 + local bestt2=0 + local var=0 + local var2=0 + forvalues i=1/`nbitems' { + if `threshold'[`i',2]>`var2'&`i'<`nbitems'-1 { + if `threshold'[`i',2]>`var' { + local bestt2=`bestt' + local var2=`var' + local var=`threshold'[`i',2] + local bestt=`i' + } + else { + local var2=`threshold'[`i',2] + local bestt2=`i' + } + } + } + di in yellow _col(4) "Based on the research of a threshold" + di in green _col(10) "1. Partitions in " in ye `bestt' in green " clusters" + di in green _col(10) "2. Partitions in " in ye `bestt2' in green " clusters" + forvalues i=`=`nbitems'+1'/`=`nbitems'+`nbkerk'-`nbkerg'' { + matrix `vp'[`i',2]=`totvar'-`T' + matrix `vp'[`i',9]=`T' + matrix `vp'[`i',10]=`T'/`nbitems'*100 + } + return local bestthresold `bestt' `bestt2' +} + +if "`bar'"!="" { + drop _all + qui set obs `nbitems' + qui svmat `vp' ,names(v) + qui drop in 1/`nbitems' + qui gen id=`nbitems'-_n + qui drop if id>`nbitems'-`nbkerk'+`nbkerg'-1 + label variable id "Number of clusters" + label variable v2 "T variation" + graph twoway bar v2 id, name(bar,replace) vert ,ylabel(0(0.5)2) xlabel(1(1)`=`nbitems'-`nbkerk'+`nbkerg'-1') +} + +drop _all +qui set obs `nbitems' +qui svmat `matclus' ,names(v) +local listorder +forvalues i=`nbitems'(-1)1 { + local listorder `listorder' v`i' +} +qui gen id=_n +qui sort `listorder' + +capture cluster delete clv,zap +qui cluster complete v* ,name(clv) + +qui replace clv_id=_n +qui replace clv_ord=id +qui replace clv_hgt=. + +qui gen fait=0 +qui gen clus=0 +forvalues i=2/`nbitems' { + local ligne=`nbitems'+`i'-1 + if (`vp'[`ligne',6]<=`nbitems') { + local first=`vp'[`ligne',6] + gsort +fait -v`i' +clv_id + } + else { + local first=`vp'[`ligne',7] + gsort +fait -v`i' +clv_id + } + if "`deltaT'"!="" { + qui replace clv_hgt=`vp'[`ligne',2] in 1 + } + else { + qui replace clv_hgt=100-`vp'[`ligne',10] in 1 + } + qui replace fait=1 in 1 + qui replace clus=`vp'[`ligne',8] in 1 +} +qui gen label="" +forvalues i=1/`nbitems' { + qui replace label=abbrev("`label`i''",`abbrev') if clv_id==`i' +} +sort clv_id +if `nbitems'>`cutnumber' { + local var "Groups of variables" + local cut cutnumber(`cutnumber') /*labcutn*/ +} +else { + local var "Variables" + local cut label(label) +} +qui su clv_hgt +local tmp=r(max) +local max=floor(`tmp')+.5 +if `tmp'>`max' { + local max=`max'+.5 +} +local maxvar=`max'+5 +if "`dendro'"=="" { + if "`title'"=="" { + local title "Clustering around Latent Variables (CLV)" + } + if "`caption'"!="" { + local var "`caption'" + } + if "`deltaT'"!="" { + local titleL "Variation of the T criterion" + local yl "0(.5)`max'" + } + else { + local titleL "% Unexplained Variance" + local yl "0(25)`maxvar'" + } + if "`horizontal'"!="" { + cluster dendro clv, name (dendrogram,replace) hor ytitle("`var'") `showcount' xtitle("`titleL'") title("`title'",span) xlabel(`yl') ylabel(,angle(0)) `cut' + } + else { + cluster dendro clv, name(dendrogram,replace) xtitle("`var'") `showcount' ytitle("`titleL'") title("`title'",span) ylabel(`yl') `cut' + } +} + +if `cons'>`nbitems'-`nbkerk'+`nbkerg' { + di in ye "The {hi:consolidation} is not possible for a number of clusters superior to the initial number of clusters" + local cons=0 +} + +if `cons'!=0 { + sort v`=`nbitems'-`cons'+1' + gen cut`cons'=1 + local g=1 + forvalues i=2/`nbitems' { + if v`=`nbitems'-`cons'+1'[`i']!=v`=`nbitems'-`cons'+1'[`=`i'-1'] { + local g=`g'+1 + } + qui replace cut`cons'=`g' in `i' + } + sort id + tempname group + mkmat cut`cons',matrix(`group') + + *cluster generate cut = groups(2/9) , name(clv) + use `clvfiletmp',replace + + local n=1 + local env=1 + while (`env'==1) { + forvalues g=1/`cons' { + local list`g' + forvalues i=1/`nbitems' { + if `group'[`i',1]==`g' { + local list`g' `list`g'' ``i'' + } + } + } + di + if `n'==1 { + di in green "{hline 30}" + di in green "PARTITION BEFORE CONSOLIDATION" + di in green "{hline 30}" + } + di + local col=1 + local max=0 + local critT=0 + forvalues g=1/`cons' { + di _col(`col') in green "GROUP " %2.0f `g' _c + local col=`col'+10 + local tmp`g':word count `list`g'' + if `tmp`g''>`max' { + local max `tmp`g'' + } + tempvar f1`g' + if "`method'"=="centroid" { + qui genscore `list`g'',score(`f1`g'') mean + qui su `f1`g'' [`weight'`exp'] + local var=r(Var) + local critT=`critT'+`tmp`g''*`var' + } + else { + if `tmp`g''>1 { + if "`method'"=="classical"|"`method'"=="v2" { + qui pca `list`g'' [`weight'`exp'] ,cov + matrix `Ev'=e(Ev) + qui predict `f1`g'' + } + else if "`method'"=="polychoric"|"`method'"=="polychoric" { + qui polychoricpca `list`g'' [`weight'`exp'] ,score(`f1`g'') nscore(1) + matrix `Ev'=r(eigenvalues) + rename `f1`g''1 `f1`g'' + } + local lambda1=`Ev'[1,1] + local critT=`critT'+`lambda1' + } + else { + qui gen `f1`g''=`list`g'' + if "`standardized'"=="" { + local critT=`critT'+1 + } + else { + qui su [`weight'`exp'] + local critT=`critT'+`r(Var)' + } + } + } + } + di + forvalues i=1/`max' { + local col=1 + forvalues g=1/`cons' { + local tmpv:word `i' of `list`g'' + local tmpv=abbrev("`tmpv'",8) + di _col(`col') in ye %8s "`tmpv'" _c + local col= `col'+10 + } + di + } + di + di in green "Variance Explained : " in ye %6.3f `=`critT'/`totvar'*100' in green "%" + di in green "T criterion : " in ye %6.4f `critT' + di + di in green "{hline 21}" + di in green "CONSOLIDATION: STEP `n'" + di in green "{hline 21}" + local n=`n'+1 + local env=0 + if "`method'"=="polychoric"|"`method'"=="polychoricv2" { + local command polychoric + } + else { + local command corr + } + forvalues i=1/`nbitems' { + local env`i'=0 + local gr=`group'[`i',1] + qui `command' ``i'' `f1`gr'' [`weight'`exp'] + local corr`i'=r(rho) + local corrs`i'=r(rho) + forvalues g=1/`cons' { + qui `command' ``i'' `f1`g'' [`weight'`exp'] + local tmpcorr=r(rho) + if `g'!=`gr'&(((`corr`i'')<(`tmpcorr')&"`method'"=="centroid")|((`corr`i'')^2<(`tmpcorr')^2& "`method'"!="centroid")) { + local env=1 + local env`i'=1 + matrix `group'[`i',1]=`g' + local corr`i'=`tmpcorr' + } + } + if `env`i''==1 { + local g=`group'[`i',1] + di in green "The variable " in ye "``i'' " in green "is assigned to the `g'th group" _c + if "`method'"!="centroid" { + di in green " (corr^2=" %6.4f in ye (`corr`i'')^2 in green " vs " in ye %6.4f (`corrs`i'')^2 in green ")" + } + else { + di in green " (corr=" %6.4f in ye (`corr`i'') in green " vs " in ye %6.4f (`corrs`i'') in green ")" + } + + } + } + if `env'==0 { + local latent + forvalues g=1/`cons' { + label variable `f1`g'' "Latent variable `g'" + if "`genlv'"!="" { + gen `genlv'`g'=`f1`g'' + } + local latent `latent' `f1`g'' + return local cluster`g' `list`g'' + } + matrix `group'=`group'' + matrix colnames `group'=`varlist' + return matrix affect=`group' + di in ye "Stability of the partition is achieved" + if `cons'<=7 { + di + di in green "{hline 42}" + di in green "CORRELATION MATRIX OF THE LATENT VARIABLES" + di in green "{hline 42}" + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+23') in green "Latent" _c + } + di + forvalues g=1/`cons' { + di _col(`=13*(`g'-1)+19') in green "variable `g'" _c + } + di + di in green "{hline `=(`cons')*13+15'}" + forvalues g=1/`cons' { + di in green "Latent variable `g'" _c + forvalues h=1/`g' { + local loc=13*`h'+10 + qui corr `f1`g'' `f1`h'' [`weight'`exp'] + local rho=r(rho) + di _col(`loc') in ye %6.4f `rho' _c + } + di + } + di in green "{hline `=(`cons')*13+15'}" + di + } + if `nbind'<=800&"`biplot'"==""&"`weight'"=="" { + local max=max(`matsize',`nbind') + set matsize `max' + if "`addvar'"!="" { + local add `varlist' + } + qui biplotvlab `latent' `add', name(biplot,replace) norow colopts(name(latent variables)) alpha(0) title(Biplot of the latent variables) labdes(size(vsmall) color(blue)) stretch(1) + } + else if `nbind'>800&"`biplot'"==""&"`weight'"==""{ + di in green "There is more than 800 individuals, so the {hi:biplot} option is disabled" + } + else if "`weight'"!=""&&"`biplot'"==""{ + di in green "The {hi:biplot} option is disabled because you use weights" + } + } + forvalues g=1/`cons' { + drop `f1`g'' + } + } +} +set matsize `matsize' +use `clvfile',replace +capture cluster delete clv,zap +return matrix vp=`vp' +return matrix matclus=`matclus' +return local varlist `varlist' +return local method `method' +return local kernel `kernel' +end diff --git a/Modules/ado/personal/c/compart.ado b/Modules/ado/personal/c/compart.ado new file mode 100644 index 0000000..a74c88d --- /dev/null +++ b/Modules/ado/personal/c/compart.ado @@ -0,0 +1,291 @@ +program define compart,rclass +version 8 +syntax varlist [if] [in] [fweight iweight] [,part(numlist) Matrix(string) type(string) DETails noSTANDardized VARiables SQUare] + +preserve +unab varlist:`varlist' +di "`varlist'" +tokenize `varlist' +marksample touse +local nbvar:word count `varlist' +qui count +local nbind=r(N) +tempname p +qui gen `p'=1 +qui su `p' [`weight'`exp'] if `touse' +local nbind=r(N) +if "`square'"=="" { + local quad=1 +} +else { + local quad=2 +} + +if "`type'"!=""&"`type'"!="polychoric" { + di in red "The type of the matrix is not authorized. Please correct your {hi:type} option." + error 198 +} +if "`type'"!=""&"`matrix'"!="" { + di in red "You cannot define in the same time the {hi:type} and the {hi:matrix} options" + error 198 +} + +/* DEFINITION OF THE PARTITION OF THE VARIABLES*/ + +local newpart +foreach i in `part' { + if `i'!=0 { + local newpart `newpart' `i' + } +} +local part `newpart' +local meme=0 +local diff=0 +local nbpart:word count `part' +forvalues i=1/`nbpart' { + local iti:word `i' of `part' + local meme=`meme'+`iti'*(`iti'-1)/2 + forvalues j=`=`i'+1'/`nbpart' { + local itj:word `j' of `part' + local diff=`diff'+`iti'*`itj' + } +} + +local perc=`meme'/(`meme'+`diff') +di "meme: `meme' ; diff: `diff' ; perc: `perc'" + + +local test=0 +local last0=0 +forvalues i=1/`nbpart' { + local first`i'=`last`=`i'-1''+1 + local size`i':word `i' of `part' + local last`i'=`first`i''+`size`i''-1 + local test=`test'+`size`i'' + local list`i' + forvalues j=`first`i''/`last`i'' { + local list`i' `list`i'' ``j'' + } +} +if `test'!=`nbvar' { + di in red "{p}The described partition of the variables is composed of a number of variables different of the number of variables of varlist.{p_end}" + exit 198 +} + +/* BY DEFAULT, STANDARDIZATION*/ +if "`standardized'"=="" { + forvalues i=1/`nbvar' { + qui su ``i'' [`weight'`exp'] + qui replace ``i''=(``i''-r(mean))/r(sd) + } +} + +tempname Cov W +if "`matrix'"==""&"`type'"!="polychoric" { + /* COVARIANCE OR CORRELATION MATRIX*/ + qui matrix accum `Cov'=`varlist' [`weight'`exp'],nocons dev + qui matrix `Cov'=`Cov'/(`nbind'-1) +} +else if "`type'"=="polychoric" { + qui polychoric `varlist' + qui matrix `Cov'=r(R) +} +else { + qui matrix `Cov'=`matrix' +} + /* WE SAVE THE MATRIX AND WE COMPUTE THE AVERAGE COVARIANCE */ +qui matrix `W'=`Cov' +local sum=0 +forvalues i=1/`nbvar' { + forvalues j=`=`i'+1'/`nbvar' { + local sum=`sum'+ `W'[`i',`j']^`quad' + } +} + +/* WE SAVE THE DATA AND WE COMPUTES THE USED PERCENTILES OF THE COVARIANCE*/ + +tempfile compartfile +qui save `compartfile',replace + +drop _all +set obs `=`nbvar'*(`nbvar'-1)' +local n=1 +qui gen i=. +qui gen j=. +qui gen corr=. +forvalues i=1/`nbvar' { + forvalues j=`=`i'+1'/`nbvar' { + qui replace i=`i' in `n' + qui replace j=`j' in `n' + qui replace corr=`W'[`i',`j']^`quad' in `n' + local ++n + } +} +matrix list `W' +su corr +sort corr +centile corr,centile(`=100-`perc'*100') +local centile=r(c_1) +if `diff'!=0 { + local perc2=(`meme'+1)/(`meme'+`diff') + centile corr,centile(`=100-`perc2'*100') + local centile2=r(c_1) + local centile=(`centile'+`centile2')/2 +} +qui use `compartfile',clear + +/***************************************************/ + +if `nbpart'==1 { + local mean=0 +* local mean=(2*`sum')/(`nbvar'*(`nbvar'-1)) +} +else { + local mean=(2*`sum')/(`nbvar'*(`nbvar'-1)) + local mean=0 + *local mean=`centile' +} + +/*THE MATRIX IS CENTERED*/ + +forvalues i=1/`nbvar' { + matrix `W'[`i',`i']=0 + forvalues j=`=`i'+1'/`nbvar' { + matrix `W'[`i',`j']=(`W'[`i',`j']^`quad'-`mean') + matrix `W'[`j',`i']=`W'[`i',`j'] + } +} + +/*WE COMPUTE THE INDEX D*/ +local C=0 +local C1=0 +local C2=0 +local minrho=2 +local summeme=0 +local sumdiff=0 +if "`square'"!="" { + local maxrho=0 +} +else { + local maxrho=-2 +} +*set trace on +forvalues i=1/`nbpart' { + forvalues j=1/`nbpart' { + forvalues k=`first`i''/`last`i'' { + forvalues l=`first`j''/`last`j'' { + if `i'!=`j' { + if `k'>`l' { + local sumdiff=`sumdiff'+`Cov'[`k',`l'] + } + if (`Cov'[`k',`l'])^`quad'>(`maxrho')^`quad' { + local maxrho=(`Cov'[`k',`l']) + } + matrix `W'[`k',`l']=-(`W'[`k',`l']) + } + else if (`Cov'[`k',`l'])^`quad'<(`minrho')^`quad'&`k'!=`l' { + local minrho=`Cov'[`k',`l'] + } + if `i'==`j'&`k'>`l' { + local summeme=`summeme'+`Cov'[`k',`l'] + } + local C=`C'+`W'[`k',`l'] + local C1=`C1'+abs(`W'[`k',`l']) + if `W'[`k',`l']>+0 { + local ++C2 + } + } + } + } +} +if `meme'!=0 { + local summeme=`summeme'/`meme' +} +if `diff'!=0 { + local sumdiff=`sumdiff'/`diff' +} +local diffsum=`summeme'-`sumdiff' +set trace off +di "Summeme: `summeme' ; Sumdiff: `sumdiff'" + +local minrho=(`minrho')^(`quad') +local maxrho=(`maxrho')^(`quad') + +local C=sign(`C')*(abs(`C'))^(1/`quad')/(`nbvar'*(`nbvar'-1))+`mean' +local C1=(`C1')^(1/`quad')/(`nbvar'*(`nbvar'-1)) +local C2=(`C2')/(`nbvar'*(`nbvar'-1))*100 +return local Pcov=`=`C'/`C1'' +return local Pel=`=`C2'/100' + +if `nbpart'==1 { + local C=`C'*(`nbvar'+1)/`nbvar' +} + +*di "C:" `C' " C1: " `C1' " C2: " `C2' +if `nbpart'==1 { + local maxrho=0 +} +if `nbpart'==`nbvar' { + local minrho=0 +} +di " C=(`meme'*`minrho'-`diff'*`maxrho')/(`meme'+`diff')" +local C=(`meme'*`minrho'-`diff'*`maxrho')/(`meme'+`diff') +di in green "{hline 80}" +di in green "Number of individuals: " _col(71) in ye %8.0f `nbind' +di in green "Number of variables: " _col(71) in ye %8.0f `nbvar' +di in green "COMPART index: " _col(71) in ye %8.6f `C' +di in green "Proportion of the covariances explained by the COMPART index: " _col(73) in ye %6.2f `=abs(`C')/`C1'*100' "%" +di in green "Proportion of positive elements in the matrix: " _col(73) in ye %6.2f `C2' "%" +di in green "Minimum correlation coefficient for 2 variables of the same group: " _col(74) in ye %5.2f `minrho' +di in green "Maximum correlation coefficient for 2 variables of two different groups: " _col(74) in ye %5.2f `maxrho' +di in green "Average correlation coefficient: " _col(74) in ye %5.2f `mean' +di in green "{hline 80}" +di +if "`details'"!="" { + di in green "Matrix of the coefficients" + di in green "{hline 26}" + matrix list `W' ,noheader format(%7.4f) + di +} +if "`variables'"!="" { + di in green "Details for each variable" + di in green "{hline 26}" + di + di in green "{hline 80}" + di in green "Items" _col(17) "COMPART" _col(26) "Problematic items" + di in green "{hline 80}" + tempname Cvar + matrix `Cvar'=J(1,`nbvar',0) + forvalues i=1/`nbvar' { + local C`i'=0 + local pourri`i' + forvalues j=1/`nbvar' { + local C`i'=`C`i''+`W'[`i',`j'] + if `W'[`i',`j']<0 { + local pourri`i' `pourri`i'' ``j'' + } + } + local C`i'=`C`i''/(`nbvar'-1) + matrix `Cvar'[1,`i']=`C`i'' + di in ye abbrev("``i''",14) _col(15) %9.6f `C`i'' _c + if "`pourri`i''"!="" { + di in ye _col(26) "`pourri`i''" + } + else { + di + } + } + di in green "{hline 80}" + matrix colnames `Cvar'=`varlist' + matrix rownames `Cvar'=Compart + return matrix Cvar=`Cvar' +} +local test=`maxrho'-`minrho' +local diffsum=(`summeme'*`meme'-`diff'*`sumdiff')/(`meme'+`diff') +local diffsum=`summeme'/*-`sumdiff'*/ +return local compart `C' +return local mean `mean' +return local list `varlist' +return local part `part' +restore +end diff --git a/Modules/ado/personal/c/compart2.ado b/Modules/ado/personal/c/compart2.ado new file mode 100644 index 0000000..725b35e --- /dev/null +++ b/Modules/ado/personal/c/compart2.ado @@ -0,0 +1,120 @@ +program define compart2,rclass +version 9 +syntax varlist [if] [in] [fweight iweight] [,part(numlist) type(string)] + +preserve +unab varlist:`varlist' +di "`varlist'" +tokenize `varlist' +marksample touse +local nbvar:word count `varlist' +qui count +local nbind=r(N) +tempname p +qui gen `p'=1 +qui su `p' [`weight'`exp'] if `touse' +local nbind=r(N) +if "`square'"=="" { + local quad=1 +} +else { + local quad=2 +} + +if "`type'"=="" { + local type classical +} +if "`type'"!="classical"&"`type'"!="centroid"&"`type'"!="polychoric" { + di in red "The type of the matrix is not authorized. Please correct your {hi:type} option." + error 198 +} + +/* DEFINITION OF THE PARTITION OF THE VARIABLES*/ + +local newpart +foreach i in `part' { + if `i'!=0 { + local newpart `newpart' `i' + } +} +local part `newpart' +local meme=0 +local diff=0 +local nbpart:word count `part' +forvalues i=1/`nbpart' { + local iti:word `i' of `part' + local meme=`meme'+`iti'*(`iti'-1)/2 + forvalues j=`=`i'+1'/`nbpart' { + local itj:word `j' of `part' + local diff=`diff'+`iti'*`itj' + } +} + +local perc=`meme'/(`meme'+`diff') +di "meme: `meme' ; diff: `diff' ; perc: `perc'" + + +local test=0 +local last0=0 +forvalues i=1/`nbpart' { + local first`i'=`last`=`i'-1''+1 + local size`i':word `i' of `part' + local last`i'=`first`i''+`size`i''-1 + local test=`test'+`size`i'' + local list`i' + forvalues j=`first`i''/`last`i'' { + local list`i' `list`i'' ``j'' + } +} +if `test'!=`nbvar' { + di in red "{p}The described partition of the variables is composed of a number of variables different of the number of variables of varlist.{p_end}" + exit 198 +} + +forvalues g=1/`nbpart' { + tempname f1`g' + if `size`g''>1 { + if "`type'"=="classical" { + qui pca `list`g'',cov + qui predict `f1`g'' + } + else if "`type'"=="polychoric" { + qui polychoricpca `list`g'',score(`f1`g'') nscore(1) + rename `f1`g''1 `f1`g'' + } + else if "`type'"=="centroid" { + qui genscore `list`g'', score(`f1`g'') mean + } + } + else if `size`g''==1 { + qui gen `f1`g''=`list`g'' + } +} +local minrho=2 +local maxrho=-2 +forvalue i=1/`nbvar' { + forvalues g=1/`nbpart' { + qui corr ``i'' `f1`g'' + if `i'>=`first`g''&`i'<=`last`g'' { + if r(rho)<`minrho' { + local minrho=r(rho) + } + } + else if r(rho)>`maxrho' { + local maxrho=r(rho) + } + } +} + +di "C=(`meme'*`minrho'-`diff'*`maxrho')/(`meme'+`diff')" +local C=(`meme'*`minrho'-`diff'*`maxrho')/(`meme'+`diff') +local C=(`meme'*`minrho'-`diff'*`maxrho')/(`meme'+`diff') +*local C=`minrho' +di "C= `C' min=`minrho' max=`maxrho'" + +return local compart `C' +*return local mean `mean' +*return local list `varlist' +return local part `part' +restore +end diff --git a/Modules/ado/personal/c/conc.ado b/Modules/ado/personal/c/conc.ado new file mode 100644 index 0000000..7c5c377 --- /dev/null +++ b/Modules/ado/personal/c/conc.ado @@ -0,0 +1,81 @@ +capture program drop conc +program conc,rclass +syntax varlist, comp(varlist) [tconc(real 0.4)] + +di as result "{hline}" +di "{bf:Concurrent validity}" +di as result "{hline}" +di + +local n : word count `varlist' +local p : word count `comp' + +matrix m = J(`n',`p',.) +matrix rownames m = `varlist' +matrix colnames m = `comp' +local r = 1 + +foreach i in `varlist' { + local c = 1 + foreach j in `comp' { + qui corr `i' `j' + mat e = r(C) + local f = e[2,1] + mat m[`r',`c'] = `f' + local `++c' + } + local `++r' +} + +*mat li m, format(%3.2f) noheader + +tokenize `varlist' +local maxv = length("`1'") +forvalues i=1/`n' { + local lenv = length("``i''") + if `lenv' > `maxv' local maxv = `lenv' +} + +local decv = `maxv'+6 + +tokenize `comp' +local maxc = length("`1'") +forvalues i=1/`p' { + local lenc = length("``i''") + if `lenc' > `maxc' local maxc = `lenc' +} + +local decc = `maxc'+4 + +local col = `decv' +foreach c in `comp' { + di as result _col(`col') "`c'" _c + local col = `col'+`decc' +} +di + +local i = 1 +foreach x in `varlist' { + local var`i' = "`x'" + local `++i' +} + + +forvalues i=1/`n' { + di as result "`var`i''" _c + local col = `decv' + forvalues j=1/`p' { + local t = m[`i',`j'] + if `t' > `tconc' | `t' < -`tconc' { + di as result _col(`=`col'-1') %5.2f `t' _c + } + else di as text _col(`=`col'-1') %5.2f `t' _c + local col = `col'+`decc' + } + di +} + +end + +*conc HA-MOC, comp(ioc1 ioc2) tconc(0.4) +*conc x1-x40, comp(x1 x2) tconc(0.4) diff --git a/Modules/ado/personal/c/convdiv.ado b/Modules/ado/personal/c/convdiv.ado new file mode 100644 index 0000000..1e71a7c --- /dev/null +++ b/Modules/ado/personal/c/convdiv.ado @@ -0,0 +1,298 @@ +capture program drop convdiv +program convdiv +syntax varlist, PARTition(numlist integer >0) [SCOrename(string) TCONVdiv(real 0.4) convdivboxplots] +preserve + +qui set autotabgraphs on + +local C = 0 +foreach z in `partition' { + local C = `C' + `z' +} + +local nbvars : word count `varlist' +if `C' != `nbvars' { + di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist" + exit 119 +} + +local P:word count `partition' +if "`scorename'" !="" { + local S:word count `scorename' + if `P'!=`S' { + di in red "The number of score names given is different from the number of dimensions in the partition option" + exit 119 + } +} + +qui detect `varlist', partition(`partition') + +matrix A = r(Corrrestscores) +matrix B = r(Corrscores) + +local i = 1 +local y = 1 + +foreach x in `partition' { + if `i' == 1 local s = `x' + else local s = `s' +`x' + + forvalues z = `y'/`s' { + matrix B[`z',`i'] = A[`z',`i'] + } + local `i++' + local y = `s'+1 +} + +if "`scorename'"!="" { + matrix colnames B = `scorename' +} +else { + local name + local nname + forvalues i = 1/`P' { + local name "Dim`i'" + local nname `nname' `name' + } +local scorename = "`nname'" +matrix colnames B = `scorename' +} + +/* coupure noms des scores */ +/* +local i = 1 +foreach s in `scorename' { + local len = length("`s'") + if `len' > 5 { + local c = substr("`s'",1,4) + local d = substr("`s'",-1,1) + local s`i' "`c'" "~" "`d'" + } + else local s`i' = "`s'" + local sc `sc' `s`i'' + local `++i' +} +*/ + +/* coupure noms des items */ +/* +local i = 1 +foreach s in `varlist' { + local len = length("`s'") + if `len' > 10 { + local c = substr("`s'",1,9) + local d = substr("`s'",-1,1) + local var`i' "`c'" "~" "`d'" + } + else local var`i' = "`s'" + local `++i' +} +*/ + +local i = 1 +foreach v in `varlist' { + local var`i' = abbrev("`v'",10) + local `++i' +} + +local i = 1 +foreach s in `scorename' { + local s`i' = abbrev("`s'",7) + local sc `sc' `s`i'' + local `++i' +} + +di as result "{hline}" +di "{bf:Correlation matrix}" +di "{hline}" +di + +/* +local i = 1 +foreach x in `varlist' { + local var`i' = "`x'" + local `++i' +} +*/ + /* +tokenize `sc' +local max = 3 + +forvalues j=1/`P' { + local len`j' = length("`s`j''") + if `len`j'' > `max' local max = `len`j'' +} + + +local maxit = 1 + +forvalues i=1/`nbvars' { + local len = length("`var`i''") + if `len' > `maxit' local maxit = `len' +} +*/ +local dec = 10 +local col = `dec' + +local decit = 14 +local colit = `decit' + + +local col1 = `decit' +forvalues i=1/`P' { + di _col(`col1') "{bf:`s`i''}" _c + local col1 = `col1' + `dec' +} + +di +local h = (`P'-1)*`dec'+`decit'+4 +di "{hline `h'}" + +local i = 1 +local j = 1 +local y = 1 + +foreach p in `partition' { + if `j' == 1 local s = `p' + else local s = `s' +`p' + + forvalues z = `y'/`s' { + di as text "{bf:`var`z''}" _c + local col = `decit'-1 + + local dd = `z' // [counting cptdiv (one per item)] + + forvalues k = 1/`P' { + + local t = B[`z',`k'] + local t : di %6.3f `t' + if `k' == `i' { + if `t' < `tconvdiv' { + di in red _col(`col') "{bf:`t'}" _c + local cptconv = `cptconv'+1 + local col = `col' + `dec' + } + else { + di _col(`col') "{bf:`t'}" _c + local col = `col' + `dec' + } + } + else { + + if B[`z',`k'] > B[`z',`i'] { + di in red _col(`col') "`t'" _c + if `dd' == `z' local cptdiv = `cptdiv'+1 // [one per item] + local dd = 0 + local col = `col' + `dec' + } + else { + di as text _col(`col') "{text:`t'}"_c + local col = `col' + `dec' + } + } + } + di + } + di "{dup `h':-}" + local `i++' + local `j++' + local y = `s'+1 +} + +local y = 1 +local h = 1 +local np : word count `partition' + +foreach p in `partition' { + if `h' == 1 local s = `p' + else local s = `s' +`p' + + forvalues j = 1/`np' { + mat C_`h'_`j' = B[`y'..`s',`j'] + + tempvar tp_`h'_`j' + mat colnames C_`h'_`j' = `tp_`h'_`j'' + + svmat C_`h'_`j', names(col) + *rename C_`h'_`j' + *mat li C_`h'_`j' + } + + local `++h' + local y = `s'+1 +} + +if "`convdivboxplots'" != "" { + forvalues h = 1/`np' { + tokenize `scorename' + local call = "" + local callbox = "" + local callleg = "" + + forvalues j = 1/`np' { + *rename C_`h'_`j' _``j'' + *di "`tp_`h'_`j''" + local call `call' /*_``j''*/ `tp_`h'_`j'' + *if `h' == `j' local color = "blue" + *else local color = "" + local callbox `callbox' box(`j',fcolor(`color') lcolor(`color')) marker(`j', mcolor(`color')) + + local lab = "``j''" + local lab = `"`lab'"' + local callleg `callleg' `j' "`lab'" + *di `"`callleg'"' + *di "`call'" + + } + graph box `call', name("Conv_div_``h''",replace) `callbox' legend(order(`"`callleg'"') stack rows(1) size(small)) title(Correlations between items of ``h'' and dimensions) yline(`tconvdiv', lpattern(dot) lcolor(black)) + qui set autotabgraphs on + *drop `call' + } +} + +/* +foreach var of varlist ioc1 ioc2 ioc3 { + loc varlab `""`:var l `var''""' + loc varlabs `"`varlabs'`varlab'"' + di "`varlab'" +} +*/ + +/* +svmat B + +local y = 1 +local h = 1 +qui gen d = 0 +foreach p in `partition' { + if `h' == 1 local s = `p' + else local s = `s' +`p' + + replace d = `h' in `y'/`s' + + local `++h' + local y = `s'+1 +} + +twoway (scatter B1 d) +*/ +local t : di %5.3f `tconvdiv' +local p1 = (`nbvars'-`cptconv')/`nbvars'*100 +local p1 : di %4.1f `p1' +local p2 = (`nbvars'-`cptdiv')/`nbvars'*100 +local p2 : di %4.1f `p2' + +di +di as result "Convergent validity:" _c +di as text " `=`nbvars'-`cptconv''/`nbvars' items (`p1'%) have a correlation coefficient with the score of " +di _col(22) "their own dimension greater than `t'" +di +di as result "Divergent validity:" _c +di as text " `=`nbvars'-`cptdiv''/`nbvars' items (`p2'%) have a correlation coefficient with the score" +di _col(22) "of their own dimension greater than those computed with other scores." + + +end + +*convdiv ioc1-ioc37, partition(4 4 7 3 3 4 7 5) scorename(Hddfdfdffda PSE W BCC Afdfdfererdfc AE LI MOC) tconvdiv(0.4) // convdivboxplots +*convdiv x1-x40, partition(5 5 5 5 5 5 5 5) scorename(Hdfda PSE W BCC Afdfdfererdfc AE LI MOC) tconvdiv(0.4) // convdivboxplots diff --git a/Modules/ado/personal/d/dege.ado b/Modules/ado/personal/d/dege.ado new file mode 100644 index 0000000..c21030b --- /dev/null +++ b/Modules/ado/personal/d/dege.ado @@ -0,0 +1,16 @@ +program define dege +syntax anything [, i(string)] +preserve +if "`i'"=="" { + local i ind +} +qui reshape long `anything',i(`i') j(item) +qui rename `anything' response +qui inspect item +local nbvalues=r(N_unique) +forvalues j=1/`nbvalues' { + qui gen `anything'`j'=item==`j' + qui replace `anything'`j'=-`anything'`j' +} +restore,not +end diff --git a/Modules/ado/personal/d/delta.ado b/Modules/ado/personal/d/delta.ado new file mode 100644 index 0000000..5f431bf --- /dev/null +++ b/Modules/ado/personal/d/delta.ado @@ -0,0 +1,108 @@ +*! Delta version 1.5 - 5 March 2008 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* DELTA: delta coefficient +* Version 1.5: March 5, 2008 +* +* Historic +* Version 1 (2007-05-21): Jean-Benoit Hardouin +* Version 1.1 (2007-05-22): Jean-Benoit Hardouin /* if in and possibility to use the score*/ +* Version 1.2 (2007-05-22): Jean-Benoit Hardouin /*bug when a score is missing*/ +* Version 1.3 (2007-06-16): Jean-Benoit Hardouin /*change in the options*/ +* Version 1.4 (2007-07-03): Jean-Benoit Hardouin /*correct a bug in the options*/ +* Version 1.5 (2008-03-05): Jean-Benoit Hardouin /*correct a bug in the ci option*/ +* +* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2007-2008 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define delta , rclass +version 7.0 +syntax varlist(min=1 numeric) [if] [in] [,ci(integer 0) noDots MINscore(int 0) MAXscore(int 0)] + +preserve +tempfile deltafile +qui save `deltafile' +if "`if'"!=""|"`in'"!="" { + qui keep `if' `in' +} + +local nbitems:word count `varlist' +tokenize `varlist' + +local scoremin=`minscore' +local scoremax=`maxscore' + + + +tempvar score +if `nbitems'==1&`scoremax'==0 { + di in red "If you indicate only the score variable, you must define the {cmd:scoremax} option" + error 198 +} +else if `nbitems'==1&`scoremax'!=0 { + qui gen `score'=`varlist' +} +else { + qui genscore `varlist',score(`score') +} +qui drop if `score'==. +qui count +local nbind=r(N) + +if `scoremax'==0 { + qui su `score' + local scoremax=r(max) +} + +tempname error +gen `error'=`score'<`scoremin'|`score'>`scoremax' +qui count if `error'==1 +local err=r(N) +if `err'!=0 { + di in red "`err' individuals has(have) a score inferior to `scoremin' or superior to `scoremax'" + error 198 +} + +local sumsqscore=0 +forvalues i=`scoremin'/`scoremax' { + qui count if `score'==`i' + local score`i'=r(N) + local sumsqscore=`sumsqscore'+`score`i''^2 +} +local delta=(1+`scoremax')*(`nbind'^2-`sumsqscore')/(`nbind'^2*`scoremax') + +di in green "Range of the scores : " in ye `scoremin' in gr "/" in ye `scoremax' +di in green "Number of used individuals : " in ye `nbind' + +if `ci'!=0 { + bootstrap delta=r(delta), reps(`ci') nowarn noheader nolegend `dots': delta `varlist' ,minscore(`scoremin') maxscore(`scoremax') +} +else { + display in green "Delta= " in yellow %8.6f `delta' +} +return scalar delta=`delta' +qui use `deltafile',clear +restore,not + +end diff --git a/Modules/ado/personal/d/descitems.ado b/Modules/ado/personal/d/descitems.ado new file mode 100644 index 0000000..283b29e --- /dev/null +++ b/Modules/ado/personal/d/descitems.ado @@ -0,0 +1,250 @@ +capture program drop descitems +program descitems +syntax varlist, PARTition(numlist integer >0) +local i = 1 + +local C = 0 +foreach z in `partition' { + local C = `C' + `z' +} + +local nbvars : word count `varlist' + +if `C' != `nbvars' { + di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist" + exit 119 +} + + +local i = 1 +foreach x in `varlist' { + local var`i' = "`x'" + local `++i' +} + +/* +qui su `var1' +local min = r(min) +local max = r(max) + +forvalue i=2/`nbvars' { + qui su `var`i'' + local minloc = r(min) + local maxloc = r(max) + if `minloc'<`min' local min = `minloc' + if `maxloc'>`max' local max = `maxloc' +} +*/ + +foreach var in `varlist' { + qui replace `var' = round(`var') +} + +local lev = "" +foreach var in `varlist' { + qui levelsof `var', local(levels) + foreach l in `levels' { + if strpos("`lev'","`l'") == 0 { + local lev `lev' `l' + } + } +} + +_qsort_index `lev' +local lev = r(slist1) + +local i = 1 +matrix d = J(`nbvars',4,.) + +foreach var in `varlist'{ + qui count if missing(`var') + local ct=r(N) + + local tx`i'=`ct'/_N + matrix d[`i',1] = `tx`i'' + local `i++' +} + +matrix rownames d = `varlist' +matrix colnames d = "missing" "alpha" "Hj" + +local i = 1 +local y = 1 +foreach x in `partition' { + + if `i' == 1 local s = `x' + else local s = `s' +`x' + + local liste = "" + forvalues w = `y'/`s' { + local liste `liste' `var`w'' + } + + qui capture alpha `liste', asi item std + + mat a = r(Alpha) + mat at = a' + + qui capture loevh `liste', pairwise + matrix e = r(loevHj) + matrix et = e' + matrix ns = r(nbHjkNS) + matrix nst = ns' + + local k = 0 + forvalues j = `y'/`s' { + local k = `k'+1 + matrix d[`j',2] = at[`k',1] + matrix d[`j',3] = et[`k',1] + matrix d[`j',4] = nst[`k',1] + + } + local `i++' + local y = `s'+1 +} + +/* coupure noms des items */ +/* +local i = 1 +foreach s in `varlist' { + local len = length("`s'") + if `len' > 10 { + local c = substr("`s'",1,9) + local d = substr("`s'",-1,1) + local var`i' "`c'" "~" "`d'" + } + else local var`i' = "`s'" + *local v `v' `var`i'' + local `++i' +} + + +local max = 3 +forvalues i=1/`nbvars' { + local len = length("`var`i''") + if `len' > `max' local max = `len' +} +*/ + +local i = 1 +foreach v in `varlist' { + local var`i' = abbrev("`v'",8) + local `++i' +} + +local dec = 10 +local col = `dec' +local b : word count `lev' + +local i = 1 +local j = 1 +local y = 1 +di in blue _col(`dec') "{bf:Missing}" _c +local col = `col'+11 +di in blue _col(`=`col'+2') "{bf:N}" _c + +local col = `col'+9 +di _col(`col') "{bf:Response categories}" _c +local col = `dec'+18+8*`b' +di _col(`col') "{bf:Alpha}" _c +local col = `col'+9 +di _col(`col') "{bf:Loevinger}" _c +local col = `col'+12 +di _col(`col') "{bf:Number of}" + +local col = `dec'-1 +di _col(`col') "{bf:data rate}" _c +local col = `dec'+18 +foreach m in `lev' { + di _col(`=`col'+2') "`m'" _c + local col = `col'+8 +} +local col = `dec'+17+8*`b' +di as result _col(`col') "- item" _c +local col = `col'+10 +di as result _col(`col') "Hj coeff" _c +local col = `col'+12 +di as result _col(`col') "NS Hjk" + + + +local ch = `dec'+18+8*`b'+29 +di "{hline `ch'}" + +local i = 1 +foreach x in `varlist' { + local varo`i' = "`x'" + local `++i' +} + + +local y = 1 +foreach p in `partition' { + + if `j' == 1 local s = `p' + else local s = `s' +`p' + + forvalues z = `y'/`s' { + local col = `dec' + di "{bf:`var`z''}" _c + local t = d[`z',1] + local t : di %8.2f `t' + di _col(`col') "{text:`t'}" _c + qui count if missing(`varo`z'') + local m = r(N) + local N = _N-`m' + local N : di %4.0f `N' + local col = `col'+10 + di _col(`col') "{text:`N'}" _c + + local col = `col'+8 + foreach m in `lev' { + + local f = 0 + qui levelsof `varo`z'', local(levels) + foreach l in `levels' { + if strpos("`levels'","`m'") == 0 { + local f = 1 + } + } + /*if `f' == 1 { + di _col(`=`col'+2') "_" _c + }*/ + *else { + qui count if round(`varo`z'') == `m' + local n = r(N) + qui count if `varo`z'' != . + local d = r(N) + local e = `n'/`d' + local e : di %4.2f `e' + if `e' != 0 di _col(`=`col'-1')"{text:`e'}" _c + else di _col(`=`col'-1')"{text: -}" _c + + *} + local col = `col'+8 + } + local col = `dec'+18+8*`b' + local a = d[`z',2] + local a : di %4.2f `a' + di _col(`=`col'+1') "{text:`a'}" _c + local h = d[`z',3] + local h : di %5.2f `h' + local col = `col'+10 + di _col(`=`col'+3') "{text:`h'}" _c + local ns = d[`z',4] + local ns : di %1.0f `ns' + local col = `col'+12 + di _col(`=`col'+7') "{text:`ns'}" + + + } + local `i++' + local `j++' + local y = `s'+1 + di "{dup `ch':-}" +} +end + +*descitems iociociociociocicocio1-ioc37, part(4 4 7 3 3 4 7 5) +*descitems ptgi1-peur16, part(4 4 7 3 3 4 7 5) +*descitems x1-x30, part(5 5 5 5 5 4 1) diff --git a/Modules/ado/personal/d/descscale.ado b/Modules/ado/personal/d/descscale.ado new file mode 100644 index 0000000..a3f1829 --- /dev/null +++ b/Modules/ado/personal/d/descscale.ado @@ -0,0 +1,293 @@ +*! Version 1.2 29 August 2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : descscale +* Description of a scale and covariates +* Release 1.1 : June 4, 2019 +* +* +* Historic : +* Version 1 (April 12, 2019) [Jean-Benoit Hardouin] +* Version 1.1 (June 4, 2019) [Jean-Benoit Hardouin] +* Version 1.2 (August 29, 2019) [Jean-Benoit Hardouin] /*correction of bugs*/ +* +* Jean-benoit Hardouin, PhD, Assistant Professor +* Team of Methods in Patient Centered Outcomes and Health Research (INSERM U1246-SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* +* News about this program :http://www.anaqol.org +* +* Copyright 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** +program define descscale , rclass +version 8.2 +syntax varlist [if] [in] [,MIN(int 0) CONTinuous(varlist) CATegorical(varlist) All PARTition(numlist) Large MEAN MAXlevels(int 20)] + +preserve +marksample touse,novarlist +label variable `touse' "selection" + +tokenize `varlist' +local nbitems: word count `varlist' +if "`partition'"=="" { + local partition `nbitems' +} +local nbdim:word count `partition' +forvalues i=1/`nbdim' { + local nbitemsdim`i': word `i' of `partition' +} +qui count if `touse' +local N=r(N) +local maxr=0 +forvalues i=1/`nbitems' { + qui levelsof ``i'' if `touse' + local r`i'=r(r) + qui su ``i'' if `touse' + local max`i'=r(max) + local mean`i'=r(mean) + qui count if ``i''!=0&``i''!=1&``i''!=2&``i''!=3&``i''!=4&``i''!=5&``i''!=6&``i''!=7&``i''!=8&``i''!=9&``i''!=10&``i''!=. + local ninc=r(N) + local ok`i'=1 + if `r`i''>11&"`large'"=="" { + di in red "The number of answer categories to the items ``i'' is large (>11). Use the -large- option or correct the list of items." + local ok`i'=0 + exit + } + if `ninc'>0 { + di in red "The variable ``i'' has incompatible values with an items (integers between 0 and 10)." + local ok`i'=0 + exit + } + if `max`i''>`maxr' { + local maxr `max`i'' + } +} +di "maxr=`maxr'" +di +di in green "Number of individuals : " as result `N' + +di +di in green "Description of the items" +local long=(`maxr'+1-`min')*8+40 +di in green "{hline `long'}" + +di in green "Items" _col(23) "Obs" _c +local col=33 +forvalues j=`min'/`maxr' { + di _col(`col') "`j'" _c + local col=`col'+8 +} +di _col(`col') "." _col(`=`col'+4') "Mean" +di in green "{hline `long'}" + +local deb=1 +forvalues d=1/`nbdim' { + local loi`d' + *di "local fin=`deb'+`nbitemsdim`d''-1" + local fin=`deb'+`nbitemsdim`d''-1 + forvalues i=`deb'/`fin' { + if `ok`i''==1 { + local loi`d' `loi`d'' ``i'' + qui count if `touse'&``i''!=. + local k=abbrev("``i''",20) + di in green "`k'" _col(22) as result %4.0f `r(N)' _c + local col=28 + forvalues j=`min'/`maxr' { + qui count if `touse'&``i''==`j' + local per=round(`r(N)'/`N'*100, 0.1) + di _col(`col') %5.1f `per' "%" _c + local col=`col'+8 + } + qui count if `touse'&``i''==. + local per=round(`r(N)'/`N'*100,0.1) + di _col(`col') %5.1f `per' "%" _col(`=`col'+9') %4.2f `mean`i'' + } + } + if `d'!=`nbdim' { + di in green "{dup `long':-}" + } + local deb=`fin'+1 +} +di in green "{hline `long'}" + +di +di in green "Description of the scores" +local long2=72 +di in green "{hline `long2'}" +di in green "Scores" _col(22) "Obs" _col(33) "Mean" _col(40) "Std. Dev." _col(58) "Min" _col(70) "Max" +di in green "{hline `long2'}" + +forvalues d=1/`nbdim' { + tempname score`d' + genscore `loi`d'' if `touse', score(`score`d'') `mean' `standardized' + qui su `score`d'' if `touse' + di in green "score`d'" _col(20) as result %5.0f `r(N)' _col(30) %7.2f `r(mean)' _col(42) %7.2f `r(sd)' _col(54) %7.2f `r(min)' _col(66) %7.2f `r(max)' +} +di in green "{hline `long2'}" + + +if "`continuous'"!="" { + local continuous2 + foreach i of varlist `continuous' { + local candidate=1 + forvalues j=1/`nbitems' { + if "`i'"=="``j''" { + local candidate=0 + } + } + local type : type `i' + local type=substr("`type'",1,3) + if "`type'"=="str" { + local candidate=0 + } + if `candidate'==1 { + qui levelsof `i' if `touse' + local r=r(r) + local continuous2 `continuous2' `i' + } + } + local continuous `continuous2' +} +if "`categorical'"!="" { + local categorical2 + foreach i of varlist `categorical' { + local candidate=1 + forvalues j=1/`nbitems' { + if "`i'"=="``j''" { + local candidate=0 + } + } + if `candidate'==1 { + qui levelsof `i' if `touse' + local r=r(r) + local categorical2 `categorical2' `i' + } + } + local categorical `categorical2' +} + +if "`all'"!="" { + *local continuous + *local categorial + foreach i of varlist * { + local candidate=1 + forvalues j=1/`nbitems' { + if "`i'"=="``j''" { + local candidate=0 + } + } + local type : type `i' + local type=substr("`type'",1,3) + if "`type'"=="str" { + local candidate=0 + } + qui levelsof `i' if `touse' + local r=r(r) + if `r'>7&`candidate'==1 { + local continuous `continuous' `i' + } + else { + local categorical `categorical' `i' + } + } +} + +*di "CONTINUOUS : `continuous'" +*di "CATEGORICAL : `categorical'" + +if "`continuous'"!="" { + di + di "Descriptive analysis of continuous covariates" + local long2=72 + di in green "{hline `long2'}" + di in green "Variables" _col(22) "Obs" _col(33) "Mean" _col(40) "Std. Dev." _col(58) "Min" _col(70) "Max" + di in green "{hline `long2'}" + foreach i of varlist `continuous' { + qui su `i' if `touse' + local k=abbrev("`i'",18) + *di in green "`k'" _c + di in green "`k'" _col(20) as result %5.0f `r(N)' _col(30) %7.2f `r(mean)' _col(42) %7.2f `r(sd)' _col(54) %7.2f `r(min)' _col(66) %7.2f `r(max)' + } + di in green "{hline `long2'}" +} +if "`categorical'"!="" { + di + *set trace on + di "Descriptive analysis of categorical covariates" + local long2=55 + di in green "{hline `long2'}" + di in green "Variables" _col(25) "Levels" _col(37) "Freq." _col(49) "Percent" + di in green "{hline `long2'}" + local nbc: word count `categorical' + local m=1 + local nonret + foreach i of varlist `categorical' { + local type : type `i' + local type=substr("`type'",1,3) + qui levelsof `i' + local lev "`r(levels)'" + local nblev=r(r) + if (`maxlevels'>=`nblev') { + local k=abbrev("`i'",20) + di in green "`k'" _c + if "`type'"=="str" { + foreach j in `lev' { + qui count if `touse'&`i'=="`j'" + local k=abbrev("`j'",10) + di _col(21) %10s in green "`k'" as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%" + } + qui count if `touse'&`i'=="" + if `r(N)'!=0 { + di as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%" + } + } + else { + foreach j in `lev' { + qui count if `touse'&`i'==`j' + di _col(21) %10s in green "`j'" as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%" + } + qui count if `touse'&`i'==. + if `r(N)'!=0 { + di as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%" + } + } + if `m'==`nbc' { + di in green "{hline `long2'}" + } + else { + di in green "{dup `long2':-}" + } + } + else { + local nonret `nonret' `i' + *di "local nonret `nonret' `i'" + *di "non retenu `i'" + if `m'==`nbc' { + di in green "{hline `long2'}" + } + } + local ++m + } + if "`nonret'"!="" { + di in green "Not described variables (too more levels) : " as result "`nonret'" + } +} +end diff --git a/Modules/ado/personal/d/descscalev1.1.ado b/Modules/ado/personal/d/descscalev1.1.ado new file mode 100644 index 0000000..6508346 --- /dev/null +++ b/Modules/ado/personal/d/descscalev1.1.ado @@ -0,0 +1,290 @@ +*! Version 1.1 4 June 2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : descscale +* Description of a scale and covariates +* Release 1.1 : June 4, 2019 +* +* +* Historic : +* Version 1 (April 12, 2019) [Jean-Benoit Hardouin] +* Version 1.1 (June 4, 2019) [Jean-Benoit Hardouin] +* +* Jean-benoit Hardouin, PhD, Assistant Professor +* Team of Methods in Patient Centered Outcomes and Health Research (INSERM U1246-SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* +* News about this program :http://www.anaqol.org +* +* Copyright 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** +program define descscale , rclass +version 8.2 +syntax varlist [if] [in] [,MIN(int 0) CONTinuous(varlist) CATegorical(varlist) All PARTition(numlist) Large MEAN MAXlevels(int 20)] + +preserve +marksample touse,novarlist +label variable `touse' "selection" + +tokenize `varlist' +local nbitems: word count `varlist' +if "`partition'"=="" { + local partition `nbitems' +} +local nbdim:word count `partition' +forvalues i=1/`nbdim' { + local nbitemsdim`i': word `i' of `partition' +} +qui count if `touse' +local N=r(N) +local maxr=0 +forvalues i=1/`nbitems' { + qui levelsof ``i'' if `touse' + local r`i'=r(r) + qui su ``i'' if `touse' + local max`i'=r(max) + local mean`i'=r(mean) + qui count if ``i''!=0&``i''!=1&``i''!=2&``i''!=3&``i''!=4&``i''!=5&``i''!=6&``i''!=7&``i''!=8&``i''!=9&``i''!=10&``i''!=. + local ninc=r(N) + local ok`i'=1 + if `r`i''>11&"`large'"=="" { + di in red "The number of answer categories to the items ``i'' is large (>11). Use the -large- option or correct the list of items." + local ok`i'=0 + exit + } + if `ninc'>0 { + di in red "The variable ``i'' has incompatible values with an items (integers between 0 and 10)." + local ok`i'=0 + exit + } + if `r`i''>`maxr' { + local maxr `r`i'' + } +} +*di "maxr=`maxr'" +di +di in green "Number of individuals : " as result `N' + +di +di in green "Decription of the items" +local long=(`maxr'+1-`min')*8+40 +di in green "{hline `long'}" + +di in green "Items" _col(23) "Obs" _c +local col=33 +forvalues j=`min'/`maxr' { + di _col(`col') "`j'" _c + local col=`col'+8 +} +di _col(`col') "." _col(`=`col'+4') "Mean" +di in green "{hline `long'}" + +local deb=1 +forvalues d=1/`nbdim' { + local loi`d' + *di "local fin=`deb'+`nbitemsdim`d''-1" + local fin=`deb'+`nbitemsdim`d''-1 + forvalues i=`deb'/`fin' { + if `ok`i''==1 { + local loi`d' `loi`d'' ``i'' + qui count if `touse'&``i''!=. + local k=abbrev("``i''",20) + di in green "`k'" _col(22) as result %4.0f `r(N)' _c + local col=28 + forvalues j=`min'/`maxr' { + qui count if `touse'&``i''==`j' + local per=round(`r(N)'/`N'*100, 0.1) + di _col(`col') %5.1f `per' "%" _c + local col=`col'+8 + } + qui count if `touse'&``i''==. + local per=round(`r(N)'/`N'*100,0.1) + di _col(`col') %5.1f `per' "%" _col(`=`col'+9') %4.2f `mean`i'' + } + } + if `d'!=`nbdim' { + di in green "{dup `long':-}" + } + local deb=`fin'+1 +} +di in green "{hline `long'}" + +di +di in green "Decription of the scores" +local long2=72 +di in green "{hline `long2'}" +di in green "Scores" _col(22) "Obs" _col(33) "Mean" _col(40) "Std. Dev." _col(58) "Min" _col(70) "Max" +di in green "{hline `long2'}" + +forvalues d=1/`nbdim' { + tempname score`d' + genscore `loi`d'' if `touse', score(`score`d'') `mean' `standardized' + qui su `score`d'' if `touse' + di in green "score`d'" _col(20) as result %5.0f `r(N)' _col(30) %7.2f `r(mean)' _col(42) %7.2f `r(sd)' _col(54) %7.2f `r(min)' _col(66) %7.2f `r(max)' +} +di in green "{hline `long2'}" + + +if "`continuous'"!=""|"`categorical'"!="" { + local continuous2 + foreach i of varlist `continuous' { + local candidate=1 + forvalues j=1/`nbitems' { + if "`i'"=="``j''" { + local candidate=0 + } + } + local type : type `i' + local type=substr("`type'",1,3) + if "`type'"=="str" { + local candidate=0 + } + if `candidate'==1 { + qui levelsof `i' if `touse' + local r=r(r) + local continuous2 `continuous2' `i' + } + } + local continuous `continuous2' + local categorical2 + foreach i of varlist `categorical' { + local candidate=1 + forvalues j=1/`nbitems' { + if "`i'"=="``j''" { + local candidate=0 + } + } + if `candidate'==1 { + qui levelsof `i' if `touse' + local r=r(r) + local categorical2 `categorical2' `i' + } + } + local categorical `categorical2' +} + +if "`all'"!="" { + *local continuous + *local categorial + foreach i of varlist * { + local candidate=1 + forvalues j=1/`nbitems' { + if "`i'"=="``j''" { + local candidate=0 + } + } + local type : type `i' + local type=substr("`type'",1,3) + if "`type'"=="str" { + local candidate=0 + } + qui levelsof `i' if `touse' + local r=r(r) + if `r'>7&`candidate'==1 { + local continuous `continuous' `i' + } + else { + local categorical `categorical' `i' + } + } +} + +*di "CONTINUOUS : `continuous'" +*di "CATEGORICAL : `categorical'" + +if "`continuous'"!="" { + di + di "Descriptive analysis of continuous covariates" + local long2=72 + di in green "{hline `long2'}" + di in green "Variables" _col(22) "Obs" _col(33) "Mean" _col(40) "Std. Dev." _col(58) "Min" _col(70) "Max" + di in green "{hline `long2'}" + foreach i of varlist `continuous' { + qui su `i' if `touse' + local k=abbrev("`i'",18) + *di in green "`k'" _c + di in green "`k'" _col(20) as result %5.0f `r(N)' _col(30) %7.2f `r(mean)' _col(42) %7.2f `r(sd)' _col(54) %7.2f `r(min)' _col(66) %7.2f `r(max)' + } + di in green "{hline `long2'}" +} +if "`categorical'"!="" { + di + *set trace on + di "Descriptive analysis of categorical covariates" + local long2=55 + di in green "{hline `long2'}" + di in green "Variables" _col(25) "Levels" _col(37) "Freq." _col(49) "Percent" + di in green "{hline `long2'}" + local nbc: word count `categorical' + local m=1 + local nonret + foreach i of varlist `categorical' { + local type : type `i' + local type=substr("`type'",1,3) + qui levelsof `i' + local lev "`r(levels)'" + local nblev=r(r) + if (`maxlevels'>=`nblev') { + local k=abbrev("`i'",20) + di in green "`k'" _c + if "`type'"=="str" { + foreach j in `lev' { + qui count if `touse'&`i'=="`j'" + local k=abbrev("`j'",10) + di _col(21) %10s in green "`k'" as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%" + } + qui count if `touse'&`i'=="" + if `r(N)'!=0 { + di as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%" + } + } + else { + foreach j in `lev' { + qui count if `touse'&`i'==`j' + di _col(21) %10s in green "`j'" as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%" + } + qui count if `touse'&`i'==. + if `r(N)'!=0 { + di as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%" + } + } + if `m'==`nbc' { + di in green "{hline `long2'}" + } + else { + di in green "{dup `long2':-}" + } + } + else { + local nonret `nonret' `i' + *di "local nonret `nonret' `i'" + *di "non retenu `i'" + if `m'==`nbc' { + di in green "{hline `long2'}" + } + } + local ++m + } + if "`nonret'"!="" { + di in green "Not described variables (too more levels) : " as result "`nonret'" + } +} +end diff --git a/Modules/ado/personal/d/descscalev1.ado b/Modules/ado/personal/d/descscalev1.ado new file mode 100644 index 0000000..8c842a1 --- /dev/null +++ b/Modules/ado/personal/d/descscalev1.ado @@ -0,0 +1,279 @@ +*! Version 1 11 April 2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : descscale +* Description of a scale and covariates +* Release 1 : April 12, 2019 +* +* +* Historic : +* Version 1 (April 12, 2019) [Jean-Benoit Hardouin] +* +* Jean-benoit Hardouin, PhD, Assistant Professor +* Team of Methods in Patient Centered Outcomes and Health Research (INSERM U1246-SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* +* News about this program :http://www.anaqol.org +* +* Copyright 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** +program define descscale , rclass +version 8.2 +syntax varlist [if] [in] [,MIN(int 0) CONTinuous(varlist) CATegorical(varlist) All PARTition(numlist) Large MEAN MAXlevels(int 20)] + +preserve +marksample touse,novarlist +label variable `touse' "selection" + +tokenize `varlist' +local nbitems: word count `varlist' +if "`partition'"=="" { + local partition `nbitems' +} +local nbdim:word count `partition' +forvalues i=1/`nbdim' { + local nbitemsdim`i': word `i' of `partition' +} +qui count if `touse' +local N=r(N) +local maxr=0 +forvalues i=1/`nbitems' { + qui levelsof ``i'' if `touse' + local r`i'=r(r) + qui su ``i'' if `touse' + local max`i'=r(max) + local mean`i'=r(mean) + if `r`i''>11&"`large'"=="" { + di in red "The number of answer categories to the items is large (>11). Use the -large- option or correct the list of items." + exit + } + if `r`i''>`maxr' { + local maxr `r`i'' + } +} +*di "maxr=`maxr'" +di +di in green "Number of individuals : " as result `N' + +di +di in green "Decription of the items" +local long=(`maxr'+1-`min')*8+40 +di in green "{hline `long'}" + +di in green "Items" _col(23) "Obs" _c +local col=33 +forvalues j=`min'/`maxr' { + di _col(`col') "`j'" _c + local col=`col'+8 +} +di _col(`col') "." _col(`=`col'+4') "Mean" +di in green "{hline `long'}" + +local deb=1 +forvalues d=1/`nbdim' { + local loi`d' + *di "local fin=`deb'+`nbitemsdim`d''-1" + local fin=`deb'+`nbitemsdim`d''-1 + forvalues i=`deb'/`fin' { + local loi`d' `loi`d'' ``i'' + qui count if `touse'&``i''!=. + local k=abbrev("``i''",20) + di in green "`k'" _c + di in green "`k'" _col(22) as result %4.0f `r(N)' _c + local col=28 + forvalues j=`min'/`maxr' { + qui count if `touse'&``i''==`j' + local per=round(`r(N)'/`N'*100, 0.1) + di _col(`col') %5.1f `per' "%" _c + local col=`col'+8 + } + qui count if `touse'&``i''==. + local per=round(`r(N)'/`N'*100,0.1) + di _col(`col') %5.1f `per' "%" _col(`=`col'+9') %4.2f `mean`i'' + } + if `d'!=`nbdim' { + di in green "{dup `long':-}" + } + local deb=`fin'+1 +} +di in green "{hline `long'}" + +di +di in green "Decription of the scores" +local long2=72 +di in green "{hline `long2'}" +di in green "Scores" _col(22) "Obs" _col(33) "Mean" _col(40) "Std. Dev." _col(58) "Min" _col(70) "Max" +di in green "{hline `long2'}" + +forvalues d=1/`nbdim' { + tempname score`d' + genscore `loi`d'' if `touse', score(`score`d'') `mean' `standardized' + qui su `score`d'' if `touse' + di in green "score`d'" _col(20) as result %5.0f `r(N)' _col(30) %7.2f `r(mean)' _col(42) %7.2f `r(sd)' _col(54) %7.2f `r(min)' _col(66) %7.2f `r(max)' +} +di in green "{hline `long2'}" + + +if "`continuous'"!=""|"`categorical'"!="" { + local continuous2 + foreach i of varlist `continuous' { + local candidate=1 + forvalues j=1/`nbitems' { + if "`i'"=="``j''" { + local candidate=0 + } + } + local type : type `i' + local type=substr("`type'",1,3) + if "`type'"=="str" { + local candidate=0 + } + if `candidate'==1 { + qui levelsof `i' if `touse' + local r=r(r) + local continuous2 `continuous2' `i' + } + } + local continuous `continuous2' + local categorical2 + foreach i of varlist `categorical' { + local candidate=1 + forvalues j=1/`nbitems' { + if "`i'"=="``j''" { + local candidate=0 + } + } + if `candidate'==1 { + qui levelsof `i' if `touse' + local r=r(r) + local categorical2 `categorical2' `i' + } + } + local categorical `categorical2' +} + +if "`all'"!="" { + *local continuous + *local categorial + foreach i of varlist * { + local candidate=1 + forvalues j=1/`nbitems' { + if "`i'"=="``j''" { + local candidate=0 + } + } + local type : type `i' + local type=substr("`type'",1,3) + if "`type'"=="str" { + local candidate=0 + } + qui levelsof `i' if `touse' + local r=r(r) + if `r'>7&`candidate'==1 { + local continuous `continuous' `i' + } + else { + local categorical `categorical' `i' + } + } +} + +*di "CONTINUOUS : `continuous'" +*di "CATEGORICAL : `categorical'" + +if "`continuous'"!="" { + di + di "Descriptive analysis of continuous covariates" + local long2=72 + di in green "{hline `long2'}" + di in green "Variables" _col(22) "Obs" _col(33) "Mean" _col(40) "Std. Dev." _col(58) "Min" _col(70) "Max" + di in green "{hline `long2'}" + foreach i of varlist `continuous' { + qui su `i' if `touse' + local k=abbrev("`i'",18) + *di in green "`k'" _c + di in green "`k'" _col(20) as result %5.0f `r(N)' _col(30) %7.2f `r(mean)' _col(42) %7.2f `r(sd)' _col(54) %7.2f `r(min)' _col(66) %7.2f `r(max)' + } + di in green "{hline `long2'}" +} +if "`categorical'"!="" { + di + *set trace on + di "Descriptive analysis of continuous covariates" + local long2=55 + di in green "{hline `long2'}" + di in green "Variables" _col(25) "Levels" _col(37) "Freq." _col(49) "Percent" + di in green "{hline `long2'}" + local nbc: word count `categorical' + local m=1 + local nonret + foreach i of varlist `categorical' { + local type : type `i' + local type=substr("`type'",1,3) + qui levelsof `i' + local lev "`r(levels)'" + local nblev=r(r) + if (`maxlevels'>=`nblev') { + local k=abbrev("`i'",20) + di in green "`k'" _c + if "`type'"=="str" { + foreach j in `lev' { + qui count if `touse'&`i'=="`j'" + local k=abbrev("`j'",10) + di _col(21) %10s in green "`k'" as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%" + } + qui count if `touse'&`i'=="" + if `r(N)'!=0 { + di as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%" + } + } + else { + foreach j in `lev' { + qui count if `touse'&`i'==`j' + di _col(21) %10s in green "`j'" as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%" + } + qui count if `touse'&`i'==. + if `r(N)'!=0 { + di as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%" + } + } + if `m'==`nbc' { + di in green "{hline `long2'}" + } + else { + di in green "{dup `long2':-}" + } + } + else { + local nonret `nonret' `i' + *di "local nonret `nonret' `i'" + *di "non retenu `i'" + if `m'==`nbc' { + di in green "{hline `long2'}" + } + } + local ++m + } + if "`nonret'"!="" { + di in green "Not described variables (too more levels) : " as result "`nonret'" + } +} +end diff --git a/Modules/ado/personal/d/detect.ado b/Modules/ado/personal/d/detect.ado new file mode 100644 index 0000000..6162a4a --- /dev/null +++ b/Modules/ado/personal/d/detect.ado @@ -0,0 +1,302 @@ +************************************************************************************************************ +* DETECT: detect, Iss and R indexes +* Version 3.1: May 13, 2004 +* +* Historic +* Version 1 (2003-06-20): Jean-Benoit Hardouin +* Version 2 (2004-01-18): Jean-Benoit Hardouin +* Version 3 (2004-01-26): Jean-Benoit Hardouin +* Version 3.1 (2004-05-13): Jean-Benoit Hardouin +* Version 4 (2009-11-24): Jean-Benoit Hardouin /*corrections*/ +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@neuf.fr +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2003, 2004 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define detect , rclass +version 7.0 +syntax varlist(min=2 numeric), PARTition(numlist integer >0) [noSCOres noRESTscores] + +local nbitemstest=0 +tokenize `partition' +local Q:word count `partition' +local firstitem=0 +local dim0=1 +forvalues i=1/`Q' { + local dim`i'=``i'' + local firstitem`i'=`firstitem`=`i'-1''+`dim`=`i'-1'' + local nbitemstest=`nbitemstest'+`dim`i'' + tempvar score`i' + qui gen `score`i''=0 + forvalues j=`firstitem`i''/`=`firstitem`i''+`dim`i''-1' { + local item`j': word `j' of `varlist' + qui replace `score`i''=`score`i''+`item`j'' + } +} + + + +local nbitems:word count `varlist' +tokenize `varlist' + +if `nbitems'!=`nbitemstest' { + di in red "The sum of the numbers of items in all the dimensions is different of the total number of items precised in varlist" +exit +} + +tempname Corrscores Corrrestscores + +matrix define `Corrscores'=J(`nbitems',`Q',0) +matrix define `Corrrestscores'=J(`nbitems',`Q',0) + + +forvalues i=1/`nbitems' { + forvalues j=1/`Q' { + tempvar restscore`i's`j' + qui gen `restscore`i's`j''=`score`j''-``i'' + qui corr ``i'' `score`j'' + local corr`i's`j'=r(rho) + qui corr ``i'' `restscore`i's`j'' + local corr`i'rs`j'=r(rho) + matrix `Corrscores'[`i',`j']=`corr`i's`j'' + matrix `Corrrestscores'[`i',`j']=`corr`i'rs`j'' + } +} + + +qui count +local nbind=r(N) + +tempvar score +qui gen `score'=0 +forvalues i=1/`nbitems' { + qui replace `score'=`score'+``i'' +} + +forvalues i=1/`nbitems' { + local tmp=`i'+1 + forvalues j=`tmp'/`nbitems' { + tempvar restscorei`i'j`j' + qui gen `restscorei`i'j`j''=`score'-``i''-``j'' + } +} + +forvalues k=0/`nbitems'{ + tempname Tcov`k' + qui count if `score'==`k' + local n`k'=r(N) + if `n`k''>1 { + qui matrix accum `Tcov`k''=`varlist' if `score'==`k',nocons dev + } + else { + matrix `Tcov`k''=J(`nbitems',`nbitems',0) + } + if `n`k''!=0 { + matrix `Tcov`k''=`Tcov`k''/`n`k'' + } +} + + +forvalues i=1/`nbitems'{ + local tmp=`i'+1 + forvalues j=`tmp'/`nbitems' { + local tmp=`nbitems'-2 + forvalues k=0/`tmp' { + tempname Rcovi`i'j`j'k`k' + qui count if `restscorei`i'j`j''==`k' + local ni`i'j`j'k`k'=r(N) + if `ni`i'j`j'k`k''>1 { + qui matrix accum `Rcovi`i'j`j'k`k''=`varlist' if `restscorei`i'j`j''==`k',nocons dev + } + else { + matrix `Rcovi`i'j`j'k`k''=J(`nbitems',`nbitems',0) + } + if `ni`i'j`j'k`k''!=0 { + matrix `Rcovi`i'j`j'k`k''=`Rcovi`i'j`j'k`k''/`ni`i'j`j'k`k'' + } + } + } +} + + +tempname delta +matrix `delta'=J(`nbitems',`nbitems',-1) + +local debut=1 +local fin=0 +forvalues i=1/`Q' { + local fin=`fin'+`dim`i'' + forvalues j=`debut'/`fin' { + forvalues k=`debut'/`fin' { + matrix `delta'[`j',`k']=1 + } + } + local debut=`debut'+`dim`i'' +} + +tempname Tcov Rcov Covfin Issm Abscov + +matrix `Tcov'=J(`nbitems',`nbitems',0) +matrix `Rcov'=J(`nbitems',`nbitems',0) +forvalues k=0/`nbitems' { + matrix `Tcov'=`Tcov'+`Tcov`k''*`n`k'' +} +forvalues i=1/`nbitems'{ + local tmp=`i'+1 + forvalues j=`tmp'/`nbitems' { + local tmp=`nbitems'-2 + forvalues k=0/`tmp' { + matrix `Rcov'[`i',`j']=`Rcov'[`i',`j']+`Rcovi`i'j`j'k`k''[`i',`j']*`ni`i'j`j'k`k'' + matrix `Rcov'[`j',`i']=`Rcov'[`i',`j'] + } + } +} + + +matrix `Covfin'=J(`nbitems',`nbitems',0) +matrix `Issm'=J(`nbitems',`nbitems',0) +matrix `Abscov'=J(`nbitems',`nbitems',0) +forvalues i=1/`nbitems' { + forvalues j=1/`nbitems' { + matrix `Covfin'[`i',`j']=(`Tcov'[`i',`j']+`Rcov'[`i',`j'])/2*`delta'[`i',`j'] + matrix `Issm'[`i',`j']=sign(`Tcov'[`i',`j']+`Rcov'[`i',`j'])*`delta'[`i',`j'] + matrix `Abscov'[`i',`j']=abs(`Tcov'[`i',`j']+`Rcov'[`i',`j'])/2 + } +} + +local somme=0 +local Iss=0 +local R=0 +forvalues i=1/`nbitems' { + local tmp=`i'+1 + forvalues j=`tmp'/`nbitems' { + local somme=`somme'+`Covfin'[`i',`j'] + local Iss=`Iss'+`Issm'[`i',`j'] + local R=`R'+`Abscov'[`i',`j'] + } +} +local DETECT=`somme'/(`nbind'*`nbitems'*(`nbitems'-1)) +local DETECT=`somme'/(`nbitems'*(`nbitems'-1)) +local Iss=`Iss'*2/(`nbitems'*(`nbitems'-1)) +*local R=`DETECT'/(`R'/(`nbind'*`nbitems'*(`nbitems'-1))) +local R=`DETECT'/(`R'/(`nbitems'*(`nbitems'-1))) + + +di +di in green _col(20) "DETECT : " as result %5.4f `DETECT' +di in green _col(23) "Iss : " as result %5.4f `Iss' +di in green _col(25) "R : " as result %5.4f `R' + +di + +if "`scores'"=="" { + di _col(5) in green "Correlations Items-Scores" + di in green _col(5) "{hline 25}" + di + di in green _col(5) "Items" _continue + local col=10 + forvalues q=1/`Q' { + local col=`col'+10 + di in green _col(`col') "dim `q'" _continue + } + di + local length=`Q'*10+10 + di in green _col(5) "{hline `length'}" + forvalues i=1/`nbitems' { + forvalues q=2/`Q' { + if `i'==`firstitem`q'' { + di _col(5) in green _dup(`length') "-" + } + } + di in green _col(5) "``i''" _continue + local col=5 + forvalues q=1/`Q' { + local col=`col'+10 + di in yellow _col(`col') %10.4f `corr`i's`q'' _continue + } + di + } + di in green _col(5) "{hline `length'}" + di +} + + +if "`restscore'"=="" { + di _col(5) in green "Correlations Items-Rest-Scores" + di in green _col(5) "{hline 30}" + di + di in green _col(5) "Items" _continue + local col=10 + forvalues q=1/`Q' { + local col=`col'+10 + di in green _col(`col') "dim `q'" _continue + } + di + local length=`Q'*10+10 + di in green _col(5) "{hline `length'}" + forvalues i=1/`nbitems' { + forvalues q=2/`Q' { + if `i'==`firstitem`q'' { + di _col(5) in green _dup(`length') "-" + } + } + di in green _col(5) "``i''" _continue + local col=5 + forvalues q=1/`Q' { + local col=`col'+10 + di in yellow _col(`col') %10.4f `corr`i'rs`q'' _continue + } + di + } + di in green _col(5) "{hline `length'}" + di +} + +local namesdim +forvalues q=1/`Q' { + local namesdim "`namesdim' dim`q'" +} + +matrix rownames `Tcov'=`varlist' +matrix rownames `Rcov'= `varlist' +matrix rownames `Covfin'= `varlist' +matrix rownames `Corrscores'= `varlist' +matrix rownames `Corrrestscores'= `varlist' +matrix colnames `Tcov'= `varlist' +matrix colnames `Rcov' =`varlist' +matrix colnames `Covfin'= `varlist' +matrix colnames `Corrscores'= `namesdim' +matrix colnames `Corrrestscores'= `namesdim' + + +return scalar DETECT=`DETECT' +return scalar Iss=`Iss' +return scalar R=`R' +return matrix Tcov `Tcov' +return matrix Rcov `Rcov' +return matrix Covfin `Covfin' +return matrix Corrscores `Corrscores' +return matrix Corrrestscores `Corrrestscores' + + +end diff --git a/Modules/ado/personal/d/detect.hlp b/Modules/ado/personal/d/detect.hlp new file mode 100644 index 0000000..b94f0df --- /dev/null +++ b/Modules/ado/personal/d/detect.hlp @@ -0,0 +1,48 @@ +{smcl} +{* 26jan2004}{...} +{hline} +help for {hi:detect} +{hline} + +{title:DETECT Index} + +{p 8 14 2}{cmd:detect} {it:varlist} {cmd:,} {cmdab:part:ition}({it:numlist}) [{cmdab:nosco:res} {cmdab:norest:scores}] + + +{p 4 4 2}{it:varlist} is a list of two existing dichotomous variables (items) or more. The first items of this list compose the first dimension, the following items define the second dimension, as so on. + +{p 4 4 2}{cmd:partition} permit to define the number of items in each dimension. The user must precise in the {it:numlist} the number of items in each dimension. + +{Options} + +{p 4 4 2}{cmd:noscores} permit to remove the table of the correlations between the items and the scores + +{p 4 4 2}{cmd:norestscores} permit to remove the table of the correlations between the items and the rest-scores + + +{title:Description} + +{p 4 4 2}{cmd:detect} permit to compute the DETECT index (Dimensionality Evaluation to Enumerate Contributing Traits), as the Iss (Approximate Simple Structure Index) and the R indexes defined by Zhang and Stout (1999). + + +{title:Remarks} + +{p 4 4 2}For detailed information on the DETECT, Iss and R indexes, see Zhang and Stout (1999). + +{p 4 4 2}{cmd:detect} don't permit the use of polytomous items. + +{title:Example} + + {cmd:. detect item1 item2 item3 item4 , partition(2 2) nosco norest} + + {cmd:. detect item1 item2 item3 item4 item 5 item6 item7 , partition(3 2 2)} + + +{title:References} + +{p 4 4 2}Zhang J. and Stout W., The theorical DETECT index of dimensionality and its application to approximate simple structure, {it: Psychometrika}, vol.64(2), 1999, pp. 213-249. + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, Regional Health Observatory (ORS) - 1, rue Porte Madeleine - BP 2439 - 45032 Orleans Cedex 1 - France. +You can contact the author at {browse "mailto:jean-benoit.hardouin@neuf.fr":jean-benoit.hardouin@neuf.fr} and visit the websites {browse "http://anaqol.free.fr":AnaQol} and {browse "http://freeirt.free.fr":FreeIRT} diff --git a/Modules/ado/personal/d/detect2.ado b/Modules/ado/personal/d/detect2.ado new file mode 100644 index 0000000..d2510d4 --- /dev/null +++ b/Modules/ado/personal/d/detect2.ado @@ -0,0 +1,68 @@ +************************************************************************************************************ +* based on the command "detect" by Jean-Benoit Hardouin +************************************************************************************************************ +program define detect2 , rclass +version 7.0 +syntax varlist(min=2 numeric), PARTition(numlist integer >0) [noSCOres noRESTscores] + +local nbitemstest=0 +tokenize `partition' +local Q:word count `partition' +local firstitem=0 +local dim0=1 +forvalues i=1/`Q' { + local dim`i'=``i'' + local firstitem`i'=`firstitem`=`i'-1''+`dim`=`i'-1'' + local nbitemstest=`nbitemstest'+`dim`i'' + tempvar score`i' + qui gen `score`i''=0 + forvalues j=`firstitem`i''/`=`firstitem`i''+`dim`i''-1' { + local item`j': word `j' of `varlist' + qui replace `score`i''=`score`i''+`item`j'' + } +} + + + +local nbitems:word count `varlist' +tokenize `varlist' + +if `nbitems'!=`nbitemstest' { + di in red "The sum of the numbers of items in all the dimensions is different of the total number of items precised in varlist" +exit +} + + +tempname Corrscores Corrrestscores + +matrix define `Corrscores'=J(`nbitems',`Q',0) +matrix define `Corrrestscores'=J(`nbitems',`Q',0) + + +forvalues i=1/`nbitems' { + forvalues j=1/`Q' { + tempvar restscore`i's`j' + qui gen `restscore`i's`j''=`score`j''-``i'' + qui corr ``i'' `score`j'' + local corr`i's`j'=r(rho) + qui corr ``i'' `restscore`i's`j'' + local corr`i'rs`j'=r(rho) + matrix `Corrscores'[`i',`j']=`corr`i's`j'' + matrix `Corrrestscores'[`i',`j']=`corr`i'rs`j'' + } +} + + + +local namesdim +forvalues q=1/`Q' { + local namesdim "`namesdim' dim`q'" +} + +matrix colnames `Corrscores'= `namesdim' +matrix colnames `Corrrestscores'= `namesdim' +return matrix Corrscores `Corrscores' +return matrix Corrrestscores `Corrrestscores' + + +end diff --git a/Modules/ado/personal/d/dropmissing.ado b/Modules/ado/personal/d/dropmissing.ado new file mode 100644 index 0000000..15f3a77 --- /dev/null +++ b/Modules/ado/personal/d/dropmissing.ado @@ -0,0 +1,23 @@ +program define dropmissing +syntax varlist [, missing(string) delete] + +tokenize `varlist' +local nbitems:word count `varlist' +if "`missing'"=="" { + local missing="." +} + +local nbmissing:word count `missing' + +forvalues i=1/`nbitems' { + forvalues j=1/`nbmissing' { + local miss:word `j' of `missing' + if "`delete'"!="" { + drop if ``i''==`miss' + } + else { + replace ``i'=. if ``i''==`miss' + } + } +} +end diff --git a/Modules/ado/personal/e/estpop.ado b/Modules/ado/personal/e/estpop.ado new file mode 100644 index 0000000..9cf9453 --- /dev/null +++ b/Modules/ado/personal/e/estpop.ado @@ -0,0 +1,344 @@ +************************************************************************************************************ +* Estpop : Estimation de la population d'une commune, d'un canton, d'un département de la région Centre +* (ou de la région Centre toute entière) +* +* Version 2.1: 7 décembre 2004 +* Version 2: 2 décembre 2004 +* Version 1.5: 2 décembre 2004 +* Version 1.4: 21 octobre 2004 +* Version 1.3: 16 aout 2004 +* Version 1.2: 20 juillet 2004 +* Version 1.1: 16 juillet 2004 +* Version 1: 16 juillet 2004 +* +* Jean-benoit Hardouin, Observatoire Régional de la Santé du Centre - Orléans - France +* jean-benoit.hardouin@neuf.fr +* +* Copyright 2004 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define estpop,rclass +version 7.0 +syntax , [annee(int 1999) codegeo(int 1) sexe(int 0) quinq juillet] +capture su * +if _rc==0 { + tempfile saveestpop + qui save `saveestpop',replace +} +preserve + +if `annee'>=1900&`annee'<2000 { + local annee=`annee'-1900 +} +local sannee=1900+`annee' +if `sannee'<1982 { + local `sannee'=`sannee'+100 +} + + +if `annee'<82|`annee'>99 { + di in red "Vous devez indiquer une annee entre 1982 et 1999 (ou entre 82 et 99)" + exit +} + +if `sexe'==0 { + local sexel hf +} +else if `sexe'==1 { + local sexel h +} +else if `sexe'==2 { + local sexel f +} +else { + di in red "Vous devez indiquer un sexe parmi 0 (2 sexes confondus), 1 (hommes) et 2 (femmes)" + exit +} + +if `codegeo'>100 {/*SI COMMUNE OU ZE OU CANTON */ + use "C:\ado\personal\files\rp`sexel'829099.dta", clear + sort codecom + merge codecom using "C:\ado\personal\files\nais8002.dta" + + if `sexe'!=0 { + foreach i of numlist 80/99 00/02 { + if `sexe'==1 { + local ratio=1.05/2.05 + } + else if `sexe'==2 { + local ratio=1/2.05 + } + if `i'<10 { + qui replace naiss0`i'=naiss0`i'*`ratio' + } + else if `i'>=10 { + qui replace naiss`i'=naiss`i'*`ratio' + } + } + } + + tempvar flag + gen `flag'=0 + + + if `codegeo'==0 { + qui replace `flag'=1 if codecom==0 + } + if `codegeo'==1 { + qui replace `flag'=1 if codecom!=0 + } + if `codegeo'<100 { + qui replace `flag'=1 if dep==`codegeo' + } + if `codegeo'<1000&`codegeo'>100 { + qui replace `flag'=1 if arr==`codegeo' + } + if `codegeo'<10000&`codegeo'>1000&int(`codegeo'/100)!=24 { + qui replace `flag'=1 if pct==`codegeo' + } + if int(`codegeo'/100)==24 { + qui replace `flag'=1 if ze94==`codegeo' + } + if `codegeo'<100000&`codegeo'>10000 { + qui replace `flag'=1 if codecom==`codegeo' + } + qui keep if `flag'==1 + + + if `annee'==82|`annee'==90|`annee'==99 { + forvalues i=1/95 { + qui su rp`annee'`sexel'`i' + local popr`i'=r(sum) + return scalar popr`i'=`popr`i'' + } + } + if (`annee'>90&`annee'<99)|(`annee'>82&`annee'<90) { + if `annee'>90&`annee'<99 { + local first=`annee'-90 + local last=98-`annee' + local anc=90 + local suiv=99 + local nbans=9 + } + if `annee'>82&`annee'<90 { + local first=`annee'-82 + local last=89-`annee' + local anc=82 + local suiv=90 + local nbans=8 + } + + forvalues i=1/`first' { + local tmp=`suiv'-`annee'+`i' + local tmp2=`suiv'-`annee'+1 + tempvar rp`annee'`sexel'`i' + qui gen `rp`annee'`sexel'`i''=naiss`=`annee'-`i''+`i'*(rp`suiv'`sexel'`tmp'-naiss`=`annee'-`i'')/`tmp' + qui su `rp`annee'`sexel'`i'' + local popr`i'=r(sum) + return scalar popr`i'=`popr`i'' + } + local rp`annee'`sexel'94 rp`annee'`sexel'95 + forvalues i=`=`anc'+1'/`=`suiv'-1' { + tempname rp`i'`sexel'94 rp`i'`sexel'95 + qui gen `rp`i'`sexel'94'=rp`anc'`sexel'94+(rp`suiv'`sexel'94-rp`anc'`sexel'94)/`nbans'*(`i'-`anc') + qui gen `rp`i'`sexel'95'=rp`anc'`sexel'95+(rp`suiv'`sexel'95-rp`anc'`sexel'95)/`nbans'*(`i'-`anc') + } + qui su `rp`annee'`sexel'94' + local popr94=r(sum) + return scalar popr94=`popr94' + qui su `rp`annee'`sexel'95' + local popr95=r(sum) + return scalar popr95=`popr95' + forvalues i=`=`first'+1'/`=95-`nbans'' { + tempvar rp`annee'`sexel'`i' + local tmp=`anc'+`i'-`annee' + local tmp2=`suiv'+`i'-`annee' + qui gen `rp`annee'`sexel'`i''=rp`anc'`sexel'`tmp'+(`annee'-`anc')*(rp`suiv'`sexel'`tmp2'-rp`anc'`sexel'`tmp')/`nbans' + qui su `rp`annee'`sexel'`i'' + local popr`i'=r(sum) + return scalar popr`i'=`popr`i'' + } + forvalues i=`=95-`nbans'+1'/93 { + tempvar rp`annee'`sexel'`i' + local tmp=`anc'+`i'-`annee' + local tmp2=94-`i'+`annee' + qui gen `rp`annee'`sexel'`i''=rp`anc'`sexel'`tmp'+`=`annee'-`anc''*(`rp`tmp2'`sexel'94'-rp`anc'`sexel'`tmp')/`=`tmp2'-`anc'' + qui su `rp`annee'`sexel'`i'' + local popr`i'=r(sum) + return scalar popr`i'=`popr`i'' + } + /*qui su naiss`annee' + local popr0=r(sum) + return scalar popr0=`popr0'*/ + + } + qui su naiss`annee' + local popr0=r(sum) + + return scalar popr0=`popr0' +}/*FIN SI COMMUNE ZE OU CANTON OU ANNEE<1990*/ + + +else if `codegeo'<100 { /*FRANCE, REGION OU DEPT*/ + use "C:\ado\personal\files\popfrregdept8201.dta", clear + if `sexe'==0 { + replace sexe=0 + } + if "`juillet'"=="" { + forvalues i=0/95 { + qui su age`i' if annee==`sannee'&codegeo==`codegeo'&sexe==`sexe' + local popr`i'=r(sum) + return scalar popr`i'=`popr`i'' + } + } + else if "`juillet'"!="" { + local pannee=`sannee'+1 + forvalues i=0/95 { + qui su age`i' if annee==`pannee'&codegeo==`codegeo'&sexe==`sexe' + local poppr`i'=r(sum) + qui su age`i' if annee==`sannee'&codegeo==`codegeo'&sexe==`sexe' + local popsr`i'=r(sum) + local popr`i'=(`poppr`i''+`popsr`i'')/2 + return scalar popr`i'=`popr`i'' + } + } +}/*FIN FRANCE, REGION OU DEPT ET ANNEE>=1990*/ + + +local popr=0 +forvalues i=0/95 { + local popr=`popr'+`popr`i'' +} + +return scalar popr=`popr' +local poprq1=`popr1'+`popr2'+`popr3'+`popr4' +return scalar poprq1=`poprq1' + +foreach i of numlist 5(5)90 { + local poprq`i'=`popr`i''+`popr`=`i'+1''+`popr`=`i'+2''+`popr`=`i'+3''+`popr`=`i'+4'' + return scalar poprq`i'=`poprq`i'' +} +return scalar poprq0=`popr0' +return scalar poprq95=`popr95' + + +if `codegeo'==0 { + local libgeo France metropolitaine +} +else if `codegeo'==1 { + local libgeo Region Centre +} +else if `codegeo'==18 { + local libgeo Cher +} +else if `codegeo'==28 { + local libgeo Eure-et-Loir +} +else if `codegeo'==36 { + local libgeo Indre +} +else if `codegeo'==37 { + local libgeo Indre-et-Loire +} +else if `codegeo'==41 { + local libgeo Loir-et-Cher +} +else if `codegeo'==45 { + local libgeo Loiret +} +else { + qui trouve `codegeo' + local libgeo=r(trouve`codegeo') +} +di +if `codegeo'>1000&`codegeo'<10000 { + di in green "Niveau geographique : Canton de " in yellow "`libgeo'" +} +else if `codegeo'>10000&`codegeo'<100000 { + di in green "Niveau geographique : Commune de " in yellow "`libgeo'" +} +else { + di in green "Niveau geographique : " in yellow "`libgeo'" +} +if `sexe'==0 { + local libsexe Deux sexes +} +else if `sexe'==1 { + local libsexe Hommes +} +else if `sexe'==2 { + local libsexe Femmes +} +if "`juillet'"==""&`codegeo'<100{ + local comm="Estimation au 1er janvier" +} +else if "`juillet'"!=""&`codegeo'<100{ + local comm="Estimation au 1er juillet" +} +else if `codegeo'>100 { + local comm="Retropolation entre deux recensements pour" +} + +di in green "Sexe : " in yellow "`libsexe'" +di in green "Annee : " in yellow "`comm' `=`annee'+1900'" + + +di +di in green _col(4) "{hline 22}" +di in green _col(4) "Age" _col(16) "Population" +di in green _col(4) "{hline 22}" +if "`quinq'"=="" { + forvalues i=0/95 { + if `i'<2 { + di in green _col(4) "`i' an" _col(18) in yellow %8.0f `popr`i'' + } + else if `i'==95 { + di in green _col(4) "95 ans et plus" _col(18) in yellow %8.0f `popr`i'' + } + else { + di in green _col(4) "`i' ans" _col(18) in yellow %8.0f `popr`i'' + } + } +} +else { + di in green _col(4) "0 an" _col(18) in yellow %8.0f `popr0' + di in green _col(4) "1-4 ans" _col(18) in yellow %8.0f `poprq1' + + foreach i of numlist 5(5)90 { + di in green _col(4) "`i'-`=`i'+4' ans" _col(18) in yellow %8.0f `poprq`i'' + } + di in green _col(4) "95 ans et plus" _col(18) in yellow %8.0f `popr95' +} + +di in green _col(4) "{hline 22}" +di in green _col(4) "Total" _col(18) in yellow %8.0f `popr' + +restore , not +qui drop _all +if "`saveestpop'"!="" { + qui use `saveestpop' +} + +end + + + + + + + diff --git a/Modules/ado/personal/files/Pop8204Dep.dta b/Modules/ado/personal/files/Pop8204Dep.dta new file mode 100644 index 0000000..d4c046b Binary files /dev/null and b/Modules/ado/personal/files/Pop8204Dep.dta differ diff --git a/Modules/ado/personal/files/cantons.dta b/Modules/ado/personal/files/cantons.dta new file mode 100644 index 0000000..97f2d8f Binary files /dev/null and b/Modules/ado/personal/files/cantons.dta differ diff --git a/Modules/ado/personal/files/commpct.dta b/Modules/ado/personal/files/commpct.dta new file mode 100644 index 0000000..fd0a54d Binary files /dev/null and b/Modules/ado/personal/files/commpct.dta differ diff --git a/Modules/ado/personal/files/communes.dta b/Modules/ado/personal/files/communes.dta new file mode 100644 index 0000000..dabb6f2 Binary files /dev/null and b/Modules/ado/personal/files/communes.dta differ diff --git a/Modules/ado/personal/files/commze.dta b/Modules/ado/personal/files/commze.dta new file mode 100644 index 0000000..1597219 Binary files /dev/null and b/Modules/ado/personal/files/commze.dta differ diff --git a/Modules/ado/personal/files/dccentre8002.dta b/Modules/ado/personal/files/dccentre8002.dta new file mode 100644 index 0000000..15639ec Binary files /dev/null and b/Modules/ado/personal/files/dccentre8002.dta differ diff --git a/Modules/ado/personal/files/dcfrance8002.dta b/Modules/ado/personal/files/dcfrance8002.dta new file mode 100644 index 0000000..cdfa54f Binary files /dev/null and b/Modules/ado/personal/files/dcfrance8002.dta differ diff --git a/Modules/ado/personal/files/nais8003.dta b/Modules/ado/personal/files/nais8003.dta new file mode 100644 index 0000000..5fcdccc Binary files /dev/null and b/Modules/ado/personal/files/nais8003.dta differ diff --git a/Modules/ado/personal/files/rpf829099.dta b/Modules/ado/personal/files/rpf829099.dta new file mode 100644 index 0000000..9739edb Binary files /dev/null and b/Modules/ado/personal/files/rpf829099.dta differ diff --git a/Modules/ado/personal/files/rph829099.dta b/Modules/ado/personal/files/rph829099.dta new file mode 100644 index 0000000..b629089 Binary files /dev/null and b/Modules/ado/personal/files/rph829099.dta differ diff --git a/Modules/ado/personal/files/rphf829099.dta b/Modules/ado/personal/files/rphf829099.dta new file mode 100644 index 0000000..fb4ac01 Binary files /dev/null and b/Modules/ado/personal/files/rphf829099.dta differ diff --git a/Modules/ado/personal/g/gammasym.ado b/Modules/ado/personal/g/gammasym.ado new file mode 100644 index 0000000..961de2c --- /dev/null +++ b/Modules/ado/personal/g/gammasym.ado @@ -0,0 +1,113 @@ +*! version 2.2 09march2007 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Gammasym : Symmetric gamma function +* +* Historic: +* Version 1 (2004-01-29): Jean-Benoit Hardouin +* Version 2 (2004-02-01): Jean-Benoit Hardouin +* Version 2.1 (2005-04-04) : Jean-benoit Hardouin +* Version 2.2 (2007-03-09) : Jean-benoit Hardouin /*Weights*/ +* +* Jean-benoit Hardouin, University of Nantes - France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2004-2007 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + + +program define gammasym,rclass +version 7 +syntax anything [, Weight(string) DISplay] + +local B `weight' + +if "`B'"!="" { + numlist "`B'" + local B=r(numlist) + local nbw:word count `B' + local score=0 + forvalues i=1/`nbw' { + local B`i':word `i' of `B' + local score=`score'+`B`i'' + } +} + +local nbgroups:word count `anything' +if "`B'"=="" { + forvalues i=1/`nbgroups' { + local B`i'=1 + } + local nbw=`nbgroups' + local score=`nbgroups' +} +if `nbgroups'!=`nbw' { + di in red "There is not the same number of values and of weights. Please correct that." + error +} + + + +tokenize `anything' +local list +forvalues i=1/`nbgroups' { + local tmp=``i'' + local list "`list' `tmp'" +} + +tokenize `list' + +tempname G +matrix `G'=J(`=`score'+4',`nbgroups',0) + +local poids=`score'+2 +local epsilon=`score'+3 +local max=`score'+4 + +forvalues j=1/`nbgroups' { + matrix `G'[`poids',`j']=`B`j'' + matrix `G'[`epsilon',`j']=exp(-``j'')^`B`j'' + if `j'!=1 { + matrix `G'[`max',`j']=`G'[`max',`=`j'-1']+`B`j'' + } + matrix `G'[1,`j']=1 +} +matrix `G'[`=`B1'+1',1]=exp(-`1')^`B1' + +forvalues j=2/`nbgroups' { + local w=`B`j'' + forvalues s=2/`=`score'+1' { + matrix `G'[`s',`j']=`G'[`s',`j']+`G'[`s',`=`j'-1'] + } + forvalues s=`=`w'+1'/`=`score'+1' { + matrix `G'[`s',`j']=`G'[`s',`j']+exp(-``j'')^`w'*`G'[`=`s'-`w'',`=`j'-1'] + } +} +forvalues r=0/`score' { + if "`display'"!="" { + display in green "Level: " in ye `r' in green _col(25) " Gamma=" in ye %10.5f `G'[`=`r'+1',`nbgroups'] + } + return scalar gamma`r'= `G'[`=`r'+1',`nbgroups'] +} +*return matrix G=`G' +end + + diff --git a/Modules/ado/personal/g/gammasym.hlp b/Modules/ado/personal/g/gammasym.hlp new file mode 100644 index 0000000..46fc637 --- /dev/null +++ b/Modules/ado/personal/g/gammasym.hlp @@ -0,0 +1,40 @@ +{smcl} +{* 9march2007}{...} +{hline} +help for {hi:gammasym}{right:Jean-Benoit Hardouin} +{hline} + +{title:The symmetric gamma function} + +{p 8 14 2}{cmd:gamma} {it:list} [,{cmdab:w:eight}({it:string}) {cmdab:dis:play}] + + +{p 4 4 2}{it:list} is a list of the values to use. + +{title:Description} + +{p 4 4 2}{cmd:gammasym} compute the values of the symmetric gamma function for all the possible level. + +{title:Options} + +{p 4 4 2}{cmd:weight} defines weights for each value (by default, all the values have a weight of 1) + +{p 4 4 2}{cmd:display} displays the value of the symmetric gamma function for each level. + +{title:Example} + + {cmd:. gammasym -2.1 -1.5 -.7 -.6 1.1 1.00024 2.232447} + + {cmd:. gammasym .3 .4 -.1 -.5 0 .6 , weight(1 2 1 1 2 1)} + + {cmd:. gammasym 1 1 1 1 1 , w(1 2 3 4 5)} + + +{title:Outputs} + +{p 4 4 2}{cmd:r(gamma#)} return the value of the symmetric gamma function at the level #. + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, Regional Health Observatory (ORS) - 1, rue Porte Madeleine - BP 2439 - 45032 Orleans Cedex 1 - France. +You can contact the author at {browse "mailto:jean-benoit.hardouin@neuf.fr":jean-benoit.hardouin@neuf.fr} and visit the websites {browse "http://anaqol.free.fr":AnaQol} and {browse "http://freeirt.free.fr":FreeIRT} diff --git a/Modules/ado/personal/g/gausshermite.ado b/Modules/ado/personal/g/gausshermite.ado new file mode 100644 index 0000000..e277a17 --- /dev/null +++ b/Modules/ado/personal/g/gausshermite.ado @@ -0,0 +1,181 @@ +*! version 2 15jan2013 +************************************************************************************************************ +* gausshermite : Estimate an integral of the form |f(x)g(x/mu,sigma)dx or f(x,y)g(x,y/mu,Sigma)dxdy where g(x/mu,sigma) is the distribution function +* of the gaussian distribution of mean mu and variance sigma^2 and g(x,y/mu,Sigma) is the distribution function +* of the bivariate normal distribution of mean mu and covariance matrix Sigma by Gauss Hermite quadratures +* +* Version 1 : May 5, 2005 (Jean-Benoit Hardouin) +* Version 1.1: June 14, 2012 /*name option*/ (Jean-Benoit Hardouin) +* Version 2: January 15, 2013 /*bivariate normal distribution*/ (Jean-Benoit Hardouin, Mohand-Larbi Feddag, Myriam Blanchin) +* +* Jean-Benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health" +* Faculty of Pharmaceutical Sciences - University of Nantes - France +* http://www.sphere-nantes.org +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2005, 2013 Jean-Benoit Hardouin, Mohand-Larbi Feddag, Myriam Blanchin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + + +program define gausshermite,rclass +version 7 +syntax anything [, Sigma(real -1) Var(string) MU(string) Nodes(integer 12) Display Name(string)] +tempfile gauss +qui capture save `gauss',replace +local save=0 +if _rc==0 { + qui save `gauss',replace + local save=1 +} + +tokenize `anything' +drop _all +tempname mean variance C + +qui set obs `=`nodes'*`nodes'' +if "`name'"=="" { + if `sigma'!=-1{ + if "`var'"==""{ + local name x + local nb=1 + } + else{ + di in red "{p}Please fill in the {hi:name} option{p_end}" + error 198 + exit + } + } + else{ + if "`var'"!=""{ + local name1 x1 + local name2 x2 + local nb=2 + } + else{ + di in red "{p}Please fill in the {hi:name} option{p_end}" + error 198 + exit + } + } +} +else { + local nb=wordcount("`name'") + if `nb'==2{ + local name1=word("`name'",1) + local name2=word("`name'",2) + } +} + + +if `nb'==2{ + capture confirm matrix `var' + if !_rc{ + if colsof(`var')==2 & rowsof(`var')==2{ + matrix `C'=cholesky(`var') + } + else{ + di in red "{p}The covariance matrix in the {hi:var} option should be a 2x2 matrix for a bivariate distribution{p_end}" + error 198 + exit + } + } + else{ + matrix `variance'=(1,0\0,1) + matrix `C'=cholesky(`variance') + } +} +else{ + if `sigma'==-1{ + local sig=1 + } + else{ + local sig=`sigma' + } +} + +capture confirm matrix `mu' +if !_rc{ + if colsof(`mu')==1 & rowsof(`mu')==1{ + local `mean'=`mu'[1,1] + } + else{ + matrix `mean'=`mu' + } +} +else{ + if "`mu'"==""{ + if `nb'==1{ + local `mean'=0 + } + else{ + matrix `mean'=(0,0) + } + } + else{ + local `mean'=`mu' + } +} + +tempname noeuds poids +qui ghquadm `nodes' `noeuds' `poids' + +if `nb'==1{ + qui gen `name'=. + qui gen poids=. + forvalues i=1/`nodes' { + qui replace `name'=`noeuds'[1,`i'] in `i' + qui replace poids=`poids'[1,`i'] in `i' + } + qui replace `name'=`name'*(sqrt(2)*`sig')+``mean'' + qui gen f=poids/sqrt(_pi)*(`1') + *list `name' poids f in 1/5 +} +else{ + forvalues i=1/`nb'{ + qui gen `name`i''=. + qui gen poids`i'=. + } + local line=1 + forvalues i=1/`nodes' { + forvalues j=1/`nodes' { + qui replace `name1'=`noeuds'[1,`i'] *(sqrt(2)*`C'[1,1])+`mean'[1,1] in `line' + qui replace `name2'=`noeuds'[1,`i'] *(sqrt(2)*`C'[2,1])+`noeuds'[1,`j'] *(sqrt(2)*`C'[2,2])+`mean'[1,2] in `line' + qui replace poids1=`poids'[1,`i'] in `line' + qui replace poids2=`poids'[1,`j'] in `line' + local ++line + } + } + qui gen f=poids1*poids2*(`1')/(_pi) + *list `name1' `name2' poids1 poids2 f in 10/20 +} + +qui su f +return scalar int=r(sum) +if "`display'"!="" { + di in green "int_R (`1')g(`name'/sigma=`sig')d`name'=" in yellow %12.8f `r(sum)' +} +drop _all +if `save'==1 { + qui use `gauss',clear +} +end + + diff --git a/Modules/ado/personal/g/gausshermite.hlp b/Modules/ado/personal/g/gausshermite.hlp new file mode 100644 index 0000000..1884439 --- /dev/null +++ b/Modules/ado/personal/g/gausshermite.hlp @@ -0,0 +1,43 @@ +{smcl} +{* 5may2005}{...} +{hline} +help for {hi:gausshermite}{right:Jean-Benoit Hardouin} +{hline} + +{title:Estimation of integrals using Gauss Hermite quadratures} + +{p 8 14 2}{cmd:gausshermite} {it:function} , {cmdab:s:igma}({it:#}) {cmd:mu}({it:#}) {cmdab:n:odes}({it:#}) {cmdab:d:isplay} + +{title:Description} + +{p 4 4 2}{cmd:gausshermite} approximates the integrals of the form f(x)g(x/mu,sigma) on all the reals where g(x/mu,sigma) is the gaussian distribution function with mean mu and variance sigma^2. + +{title:Options} + +{p 4 4 2}{it:function} defines f(x). For example, if f(x)=x^2, {it:function} is x^2. It is necessary to use x for the variable of integration. + +{p 4 4 2}{cmd:mu} defines the mean of x (0 by default). + +{p 4 4 2}{cmd:sigma} defines the standard deviation of x (1 by default). + +{p 4 4 2}{cmd:nodes} defines the number of quadrature nodes (12 by default). + +{p 4 4 2}{cmd:display} allows automatically displaying the estimation. + +{p 4 4 2}Note that the quadrature nodes and the associated weights are computed using the {cmd:ghquadm} Stata command. Find this command with {stata findit ghquadm:findit ghquadm}. + +{title:Example} + + {cmd:. gausshermite x^2} + + {cmd:. gausshermite x^4+exp(x)-2, sigma(1.5) mu(-.4) d n(10)} + + +{title:Outputs} + +{p 4 4 2}The estimated value of the integral is saved in {cmd:r(int)}. + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, Regional Health Observatory (ORS) - 1, rue Porte Madeleine - BP 2439 - 45032 Orleans Cedex 1 - France. +You can contact the author at {browse "mailto:jean-benoit.hardouin@orscentre.org":jean-benoit.hardouin@orscentre.org} and visit the websites {browse "http://anaqol.free.fr":AnaQol} and {browse "http://freeirt.free.fr":FreeIRT} diff --git a/Modules/ado/personal/g/gausshermite1.ado b/Modules/ado/personal/g/gausshermite1.ado new file mode 100644 index 0000000..5d46cf3 --- /dev/null +++ b/Modules/ado/personal/g/gausshermite1.ado @@ -0,0 +1,72 @@ +*! version 1 5may2005 +************************************************************************************************************ +* gausshermite : Estimate an integral of the form |f(x)g(x/mu,sigma)dx where g(x/mu,sigma) is the distribution function +* of the gaussian distribution of mean mu and variance sigma^2 by Gauss Hermite quadratures +* +* Version 1: May 5, 2005 +* +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@orscentre.org +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2005 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + + +program define gausshermite,rclass +version 7 +syntax anything [, Sigma(real 1) MU(real 0) Nodes(integer 12) Display] +tempfile gauss +qui capture save `gauss',replace +local save=0 +if _rc==0 { + qui save `gauss',replace + local save=1 +} + +tokenize `anything' + +drop _all +qui set obs 100 +tempname noeuds poids +qui ghquadm `nodes' `noeuds' `poids' +qui gen x=. +qui gen poids=. +forvalues i=1/`nodes' { + qui replace x=`noeuds'[1,`i'] in `i' + qui replace poids=`poids'[1,`i'] in `i' +} +qui replace x=x*(sqrt(2)*`sigma')+`mu' + +qui gen f=poids/sqrt(_pi)*(`1') +qui su f +return scalar int=r(sum) + +if "`display'"!="" { + di in green "int_R (`1')g(x/sigma=`sigma')dx=" in yellow %12.8f `r(sum)' +} +drop _all +if `save'==1 { + qui use `gauss',clear +} +end + + diff --git a/Modules/ado/personal/g/gausshermite2.ado b/Modules/ado/personal/g/gausshermite2.ado new file mode 100644 index 0000000..2548679 --- /dev/null +++ b/Modules/ado/personal/g/gausshermite2.ado @@ -0,0 +1,104 @@ +*! version 1 03 January 2012 +************************************************************************************************************ +* gausshermite2 : Estimate an integral of the form : f(x,y)g(x,y/mu,Sigma)dxdy where g(x,y/mu,Sigma) is the distribution function +* of the bivariate normal distribution of mean mu and covariance matrix Sigma by Gauss Hermite quadratures +* +* Version 1: 03 January 2012 +* +* +* Mohand Feddag, University of Nantes - France +* Mohand-Larbi.Feddag@univ-nantes.fr * +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2012 Mohand Feddag +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define gausshermite2,rclass +version 11 +syntax anything [, Mu(string) Sigma(string) Nodes(integer 12) Display] +tempfile gauss2 +qui capture save `gauss2',replace +local save=0 +if _rc==0 { + qui save `gauss2',replace + local save=1 +} +if "`mu'"=="" { + tempname mu + matrix `mu'=[0,0] +} +if "`sigma'"=="" { + tempname sigma + matrix `sigma'=[1,0\0,1] +} +tokenize `anything' + +drop _all +qui set obs `=`nodes'*`nodes'' +tempname noeuds poids +qui ghquadm `nodes' `noeuds' `poids' + +* Cholesky transformation for the covariance matrix sigma + +matrix C=cholesky(`sigma') +*matrix list C +local line=1 +qui gen x1=. +qui gen x2=. +qui gen poids1=. +qui gen poids2=. +forvalues i=1/`nodes' { + forvalues j=1/`nodes' { + qui replace x1=`noeuds'[1,`i'] *(sqrt(2)*C[1,1])+`mu'[1,1] in `line' + qui replace x2=`noeuds'[1,`i'] *(sqrt(2)*C[2,1])+`noeuds'[1,`j'] *(sqrt(2)*C[2,2])+`mu'[1,2] in `line' + qui replace poids1=`poids'[1,`i'] in `line' + qui replace poids2=`poids'[1,`j'] in `line' + local ++line + } +} + +* Double somme du produit poids[i]*poids[j]*f(x1,x2) qui est affecté a la variable sum + +qui gen f=poids1*poids2*(`1')/(_pi) +*list x1 x2 poids1 f (sqrt(2)*_pi) +qui su f +local sum=r(sum) + return scalar int=`sum' + + if "`display'"!="" { + di in green "int_R^2 (`1')g(x1,x2/mu=`mu',Sigma=`Sigma')dx1dx2=" in yellow %12.8f `sum' +} +drop _all +if `save'==1 { + qui use `gauss2',clear +} +end + + + + + + + + + + + + + diff --git a/Modules/ado/personal/g/gausshermite3.ado b/Modules/ado/personal/g/gausshermite3.ado new file mode 100644 index 0000000..c31540f --- /dev/null +++ b/Modules/ado/personal/g/gausshermite3.ado @@ -0,0 +1,134 @@ +*! version 2 11dec2012 +************************************************************************************************************ +* gausshermite : Estimate an integral of the form |f(x)g(x/mu,sigma)dx or f(x,y)g(x,y/mu,Sigma)dxdy where g(x/mu,sigma) is the distribution function +* of the gaussian distribution of mean mu and variance sigma^2 and g(x,y/mu,Sigma) is the distribution function +* of the bivariate normal distribution of mean mu and covariance matrix Sigma by Gauss Hermite quadratures +* +* Version 1: May 5, 2005 +* Version 1.1: June 14, 2012 /*name option*/ +* Version 2: December 11, 2012 /*bivariate normal distribution*/ +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@orscentre.org +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2005, 2012 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + + +program define gausshermite3,rclass +version 7 +syntax anything [, Sigma(string) MU(string) Nodes(integer 12) Display Name(string)] +tempfile gauss +qui capture save `gauss',replace +local save=0 +if _rc==0 { + qui save `gauss',replace + local save=1 +} + +tokenize `anything' + +drop _all +qui set obs `=`nodes'*`nodes'' +if "`name'"=="" { + local name x + local nb=1 +} +else { + local nb=wordcount("`name'") + if `nb'==2{ + di word("`name'",1) + local name1=word("`name'",1) + local name2=word("`name'",2) + } +} + +capture confirm matrix `sigma' +if !_rc{ + if colsof(`sigma')==1 & rowsof(`sigma')==1{ + local sig=`sigma'[1,1] + } + else{ + matrix C=cholesky(`sigma') + } +} +else{ + local sig=`sigma' +} + +capture confirm matrix `mu' +if !_rc{ + if colsof(`mu')==1 & rowsof(`mu')==1{ + local mean=`mu'[1,1] + } + else{ + matrix mean=`mu' + } +} +else{ + local mean=`mu' +} + +tempname noeuds poids +qui ghquadm `nodes' `noeuds' `poids' + +if `nb'==1{ + qui gen `name'=. + qui gen poids=. + forvalues i=1/`nodes' { + qui replace `name'=`noeuds'[1,`i'] in `i' + qui replace poids=`poids'[1,`i'] in `i' + } + qui replace `name'=`name'*(sqrt(2)*`sig')+`mean' + qui gen f=poids/sqrt(_pi)*(`1') + *list `name' poids f in 1/5 +} +else{ + forvalues i=1/`nb'{ + qui gen `name`i''=. + qui gen poids`i'=. + } + local line=1 + forvalues i=1/`nodes' { + forvalues j=1/`nodes' { + qui replace `name1'=`noeuds'[1,`i'] *(sqrt(2)*C[1,1])+mean[1,1] in `line' + qui replace `name2'=`noeuds'[1,`i'] *(sqrt(2)*C[2,1])+`noeuds'[1,`j'] *(sqrt(2)*C[2,2])+mean[1,2] in `line' + qui replace poids1=`poids'[1,`i'] in `line' + qui replace poids2=`poids'[1,`j'] in `line' + local ++line + } + } + qui gen f=poids1*poids2*(`1')/(_pi) + *list `name1' `name2' poids1 poids2 f in 10/20 +} + +qui su f +return scalar int=r(sum) +if "`display'"!="" { + di in green "int_R (`1')g(`name'/sigma=`sigma')d`name'=" in yellow %12.8f `r(sum)' +} +drop _all +if `save'==1 { + qui use `gauss',clear +} +end + + diff --git a/Modules/ado/personal/g/geekel2d.ado b/Modules/ado/personal/g/geekel2d.ado new file mode 100644 index 0000000..12f3c03 --- /dev/null +++ b/Modules/ado/personal/g/geekel2d.ado @@ -0,0 +1,503 @@ +*! version 4.3 18january2006 +************************************************************************************************************ +* GEEkel2d: GEE for estimation of unidimensional or 2-dimensional Latent Trait models (Kelderman and Rijkes 1994) +* +* Version 4.3: January 18, 2006 /*Faster version*/ +* +* Historic: +* Version 1 (2003-06-23): Jean-Benoit Hardouin +* Version 2 (2003-08-13): Jean-Benoit Hardouin +* version 3 (2003-11-06): Jean-Benoit Hardouin +* Version 4 (2004-06-08): Jean-Benoit Hardouin +* Version 4.1 (2005-04-02): Jean-Benoit Hardouin +* Version 4.2 (2005-07-02): Jean-Benoit Hardouin +* +* Use the ghquadm program (findit ghquadm) +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@neuf.fr +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2003-2006 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************* + +program define geekel2d ,rclass +version 7.0 +syntax varlist(min=2 numeric) [, coef(string) novar ll nbit(integer 30) critconv(real 1e-15) quad(integer 12) ] + +preserve +local nbitems: word count `varlist' +tokenize `varlist' + +qui count +local N=r(N) + +forvalues i=1/`nbitems' { + qui drop if ``i''==. +} + +qui count +local Naf=r(N) + +di _col(3) in green "Initial step (N=" in yellow `Naf' in green ")" +di _col(3) in yellow `=`N'-`Naf'' in green " observations are not used for missing values" +di + +qui count +local N=r(N) +tempname B Q +if "`coef'"!="" { + matrix `B'=`coef' +} +else { + matrix `B'=J(`nbitems',1,1) +} + +scalar `Q'=colsof(`B') + +/* CALCUL INITIAUX DES PARAMETRES DELTA ET SIGMA ET DE LA MATRICE BETA*/ + +local sigmath11=0.25 + +if `Q'==2 { + local sigmath22=.25 + local sigmath12=0.125 +} + +tempname beta +matrix `beta'=J(`nbitems'+`Q'*(`Q'+1)/2,1,0) +forvalues i=1/`nbitems' { + qui count if ``i''==1 + local si`i'=r(N) + local delta``i''=-log(`si`i''/(`N'-`si`i'')) + matrix `beta'[`i',1]=`delta``i''' + forvalues j=`i'/`nbitems' { + quiet count if ``j''==1&``i''==1 + local si`i'j`j'=r(N) + local si`j'j`i'=r(N) + if "`var'"=="" { + forvalues k=`j'/`nbitems' { + quiet count if ``i''==1&``j''==1&``k''==1 + local si`i'j`j'k`k'=r(N) + local si`i'j`k'k`j'=r(N) + local si`j'j`i'k`k'=r(N) + local si`j'j`k'k`i'=r(N) + local si`k'j`i'k`j'=r(N) + local si`k'j`j'k`i'=r(N) + forvalues l=`k'/`nbitems' { + quiet count if ``i''==1&``j''==1&``k''==1&``l''==1 + local si`i'j`j'k`k'l`l'=r(N) + local si`i'j`j'k`l'l`k'=r(N) + local si`i'j`k'k`j'l`l'=r(N) + local si`i'j`k'k`l'l`j'=r(N) + local si`i'j`l'k`j'l`k'=r(N) + local si`i'j`l'k`k'l`j'=r(N) + + local si`j'j`i'k`k'l`l'=r(N) + local si`j'j`i'k`l'l`k'=r(N) + local si`j'j`k'k`i'l`l'=r(N) + local si`j'j`k'k`l'l`i'=r(N) + local si`j'j`l'k`i'l`k'=r(N) + local si`j'j`l'k`k'l`i'=r(N) + + local si`k'j`i'k`j'l`l'=r(N) + local si`k'j`i'k`l'l`j'=r(N) + local si`k'j`j'k`i'l`l'=r(N) + local si`k'j`j'k`l'l`i'=r(N) + local si`k'j`l'k`i'l`j'=r(N) + local si`k'j`l'k`j'l`i'=r(N) + + local si`l'j`i'k`j'l`k'=r(N) + local si`l'j`i'k`k'l`j'=r(N) + local si`l'j`j'k`i'l`k'=r(N) + local si`l'j`j'k`k'l`i'=r(N) + local si`l'j`k'k`i'l`j'=r(N) + local si`l'j`k'k`j'l`i'=r(N) + } + } + } + } +} + +local l=`nbitems'+1 +matrix `beta'[`l',1]=`sigmath11' + +if `Q'==2 { + local l=`nbitems'+2 + matrix `beta'[`l',1]=`sigmath22' + local l=`nbitems'+3 + matrix `beta'[`l',1]=`sigmath12' +} + +tempname variat V11 V12 V21 V22 D11 D12 D21 D22 V D +matrix `variat'=(1) +local compteur=0 +local conv=1 + + +/*********ITERATIONS******************/ + + + +while (`variat'[1,1]>`critconv'&`compteur'<=`nbit'&`conv'==1) { + if `compteur'==0{ + di in green _col(3) "First iteration" + } + else { + di in green _col(3) "iteration:" in yellow _col(14) "`compteur'" in green _col(25) "Convergence index:" in yellow _col(44) %10.7e "`macrovariat'" + } + local compteur=`compteur'+1 + + forvalues j=1/`nbitems' { + + /* CALCUL DES DERIVEES 1 A 6 POUR CHAQUE ITEM*/ + local l1``j''=1/(1+exp(`beta'[`j',1])) + local l2``j''=exp(`beta'[`j',1])/(1+exp(`beta'[`j',1]))^2 + local l3``j''=exp(`beta'[`j',1])*(exp(`beta'[`j',1])-1)/(1+exp(`beta'[`j',1]))^3 + local l4``j''=exp(`beta'[`j',1])*(exp(2*`beta'[`j',1])-4*exp(`beta'[`j',1])+1)/(1+exp(`beta'[`j',1]))^4 + local l5``j''=exp(`beta'[`j',1])*(exp(3*`beta'[`j',1])-11*exp(2*`beta'[`j',1])+11*exp(`beta'[`j',1])-1)/(1+exp(`beta'[`j',1]))^5 + local l6``j''=exp(`beta'[`j',1])*(exp(4*`beta'[`j',1])-26*exp(3*`beta'[`j',1])+66*exp(2*`beta'[`j',1])-26*exp(`beta'[`j',1])+1)/(1+exp(`beta'[`j',1]))^6 + + if `Q'==2 { + local H2i`j'=`B'[`j',1]^2*`sigmath11'+`B'[`j',1]*`B'[`j',2]*`sigmath12'+`B'[`j',2]^2*`sigmath22' + local H4i`j'=3*`B'[`j',1]^4*`sigmath11'^2+12*`B'[`j',1]^3*`B'[`j',2]*`sigmath11'*`sigmath12'+6*`B'[`j',1]^2*`B'[`j',2]^2*(`sigmath11'*`sigmath22'+2*`sigmath12'^2)+12*`B'[`j',1]*`B'[`j',2]^3*`sigmath22'*`sigmath12'+3*`B'[`j',2]^4*`sigmath22'^2 + } + else if `Q'==1 { + local H2i`j'=`B'[`j',1]^2*`sigmath11' + local H4i`j'=3*`B'[`j',1]^4*`sigmath11'^2 + } + + /* CALCUL DES MOMENTS D'ORDRE 1 ET 2 ET DE LA MATRICE V11*/ + local mui`j'=`l1``j'''+`H2i`j''/2*`l3``j'''+`H4i`j''/24*`l5``j''' + local sigmai`j'j`j'=`l2``j'''+`H2i`j''/2*(`l3``j'''-2*`l1``j'''*`l3``j''')+`H4i`j''/24*(`l5``j'''-2*(`l3``j''')^2-2*`l1``j'''*`l5``j''') + } + + + matrix `V11'=J(`nbitems',`nbitems',0) + + forvalues j=1/`nbitems' { + matrix `V11'[`j',`j']=`sigmai`j'j`j'' + forvalues l=`=`j'+1'/`nbitems' { + if `Q'==2 { + local H2i`j'j`l'=`B'[`j',1]*`B'[`l',1]*`sigmath11'+(`B'[`j',1]*`B'[`l',2]+`B'[`j',2]*`B'[`l',1])*`sigmath12'+`B'[`j',2]*`B'[`l',2]*`sigmath22' + local H4i`j'1j`l'3=3*`B'[`j',1]*`B'[`l',1]^3*`sigmath11'^2+3*(3*`B'[`j',1]*`B'[`l',1]^2*`B'[`l',2]+`B'[`j',2]*`B'[`l',1]^3)*`sigmath11'*`sigmath12'+(3*`B'[`j',1]*`B'[`l',1]*`B'[`l',2]^2+3*`B'[`j',2]*`B'[`l',1]^2*`B'[`l',2])*(`sigmath11'*`sigmath22'+2*`sigmath12'^2)+3*(`B'[`j',1]*`B'[`l',2]^3+3*`B'[`j',2]*`B'[`l',1]*`B'[`l',2]^2)*`sigmath22'*`sigmath12'+3*`B'[`j',2]*`B'[`l',2]^3*`sigmath22'^2 + local H4i`j'2j`l'2=3*`B'[`j',1]^2*`B'[`l',1]^2*`sigmath11'^2+6*(`B'[`j',1]^2*`B'[`l',1]*`B'[`l',2]+`B'[`j',1]*`B'[`j',2]*`B'[`l',1]^2)*`sigmath11'*`sigmath12'+(`B'[`j',1]^2*`B'[`l',2]^2+4*`B'[`j',1]*`B'[`j',2]*`B'[`l',1]*`B'[`l',2]+`B'[`j',2]^2*`B'[`l',1]^2)*(`sigmath11'*`sigmath22'+2*`sigmath12'^2)+6*(`B'[`j',1]*`B'[`j',2]*`B'[`l',2]^2+`B'[`j',2]^2*`B'[`l',1]*`B'[`l',2])*`sigmath22'*`sigmath12'+3*`B'[`j',2]^2*`B'[`l',2]^2*`sigmath22'^2 + local H4i`j'3j`l'1=3*`B'[`l',1]*`B'[`j',1]^3*`sigmath11'^2+3*(3*`B'[`l',1]*`B'[`j',1]^2*`B'[`j',2]+`B'[`l',2]*`B'[`j',1]^3)*`sigmath11'*`sigmath12'+(3*`B'[`l',1]*`B'[`j',1]*`B'[`j',2]^2+3*`B'[`l',2]*`B'[`j',1]^2*`B'[`j',2])*(`sigmath11'*`sigmath22'+2*`sigmath12'^2)+3*(`B'[`l',1]*`B'[`j',2]^3+3*`B'[`l',2]*`B'[`j',1]*`B'[`j',2]^2)*`sigmath22'*`sigmath12'+3*`B'[`l',2]*`B'[`j',2]^3*`sigmath22'^2 + } + else if `Q'==1 { + local H2i`j'j`l'=`B'[`j',1]*`B'[`l',1]*`sigmath11' + local H4i`j'1j`l'3=3*`B'[`j',1]*`B'[`l',1]^3*`sigmath11'^2 + local H4i`j'2j`l'2=3*`B'[`j',1]^2*`B'[`l',1]^2*`sigmath11'^2 + local H4i`j'3j`l'1=3*`B'[`l',1]*`B'[`j',1]^3*`sigmath11'^2 + } + local H2i`l'j`j'=`H2i`j'j`l'' + local H4i`l'1j`j'3=`H4i`j'1j`l'3' + local H4i`l'2j`j'2=`H4i`j'2j`l'2' + local H4i`l'3j`j'1=`H4i`j'3j`l'1' + local sigmai`j'j`l'=`H2i`j'j`l''*(`l2``j'''*`l2``l''')+`H4i`j'1j`l'3'/6*`l2``j'''*`l4``l'''+`H4i`j'3j`l'1'/6*`l4``j'''*`l2``l'''+(`H4i`j'2j`l'2'-`H2i`j''*`H2i`l'')/4*`l3``j'''*`l3``l''' + } + } + + /* DEFINITION DE LA MATRICE COMPOCARRE*/ + tempname compocarre m + local carre=`nbitems'*(`nbitems'-1)/2 + matrix `compocarre'=J(2,`carre',0) + + local m=0 + forvalues j=1/`nbitems' { + forvalues l=`=`j'+1'/`nbitems' { + local m=`m'+1 + matrix `compocarre'[1,`m']=`j' + matrix `compocarre'[2,`m']=`l' + } + } + + /* CALCUL DE LA MATRICE V22*/ + matrix `V22'=J(`carre',`carre',0) + forvalues k=1/`carre' { + local j=`compocarre'[1,`k'] + local l=`compocarre'[2,`k'] + matrix `V22'[`k',`k']=(1-2*`mui`j'')*(1-2*`mui`l'')*`sigmai`j'j`l''+`sigmai`j'j`j''*`sigmai`l'j`l''-`sigmai`j'j`l''^2 + } + + /* CALCUL DES MATRICES V12, V21 ET V*/ + matrix `V12'=J(`nbitems',`carre',0) + forvalues k=1/`carre' { + local j=`compocarre'[1,`k'] + local l=`compocarre'[2,`k'] + matrix `V12'[`j',`k']=(1-2*`mui`j'')*`sigmai`j'j`l'' + matrix `V12'[`l',`k']=(1-2*`mui`l'')*`sigmai`j'j`l'' + } + matrix `V21'=`V12' ' + matrix `V'=(`V11',`V12' \ `V21',`V22') + + /*CALCUL DES MATRICES D11*/ + matrix `D11'=J(`nbitems',`nbitems',0) + matrix `D12'=J(`nbitems',`Q'*(`Q'+1)/2,0) + + forvalues j=1/`nbitems' { + matrix `D11'[`j',`j']=-`l2``j'''-`H2i`j''/2*`l4``j'''-`H4i`j''/24*`l6``j''' + + if `Q'==2 { + matrix `D12'[`j',1]=`B'[`j',1]^2*`l3``j'''/2+(`B'[`j',1]^4*`sigmath11'+2*`B'[`j',1]^3*`B'[`j',2]*`sigmath12'+`B'[`j',1]^2*`B'[`j',2]^2*`sigmath22')/4*`l5``j''' + matrix `D12'[`j',2]=`B'[`j',2]^2*`l3``j'''/2+(`B'[`j',2]^4*`sigmath22'+2*`B'[`j',2]^3*`B'[`j',1]*`sigmath12'+`B'[`j',2]^2*`B'[`j',1]^2*`sigmath11')/4*`l5``j''' + matrix `D12'[`j',3]=`B'[`j',1]*`B'[`j',2]*`l3``j'''+(`B'[`j',1]^3*`B'[`j',2]*`sigmath11'+2*`B'[`j',1]^2*`B'[`j',2]^2*`sigmath12'+`B'[`j',1]*`B'[`j',2]^3*`sigmath22')/2*`l5``j''' + } + else if `Q'==1 { + matrix `D12'[`j',1]=`B'[`j',1]^2*`l3``j'''/2+`B'[`j',1]^4*`sigmath11'/4*`l5``j''' + } + } + + /*CALCUL DES MATRICES D21, D22 et D*/ + matrix `D21'=J(`carre',`nbitems',0) + matrix `D22'=J(`carre',`Q'*(`Q'+1)/2,0) + + forvalues k=1/`carre' { + local j=`compocarre'[1,`k'] + local l=`compocarre'[2,`k'] + matrix `D21'[`k',`j']=-`H2i`j'j`l''*`l3``j'''*`l2``l'''-`H4i`j'1j`l'3'/6*`l3``j'''*`l4``l'''-`H4i`j'3j`l'1'/6*`l5``j'''*`l2``l'''-(`H4i`j'2j`l'2'-`H2i`j''*`H2i`l'')/4*`l4``j'''*`l3``l''' + matrix `D21'[`k',`l']=-`H2i`j'j`l''*`l2``j'''*`l3``l'''-`H4i`j'3j`l'1'/6*`l4``j'''*`l3``l'''-`H4i`j'1j`l'3'/6*`l2``j'''*`l5``l'''-(`H4i`j'2j`l'2'-`H2i`j''*`H2i`l'')/4*`l3``j'''*`l4``l''' + + tempname tmp1 tmp2 tmp3 + if `Q'==2 { + scalar `tmp1'=`B'[`j',1]*`B'[`l',1]*`l2``j'''*`l2``l'''+(2*`B'[`j',1]*`B'[`l',1]^3*`sigmath11'+(3*`B'[`j',1]*`B'[`l',1]^2*`B'[`l',2]+`B'[`j',2]*`B'[`l',1]^3)*`sigmath12'+(`B'[`j',1]*`B'[`l',1]*`B'[`l',2]^2+`B'[`j',2]*`B'[`l',1]^2*`B'[`l',2])*`sigmath22')/2*`l2``j'''*`l4``l''' + scalar `tmp2'=(2*`B'[`j',1]^3*`B'[`l',1]*`sigmath11'+(3*`B'[`j',1]^2*`B'[`j',2]*`B'[`l',1]+`B'[`j',1]^3*`B'[`l',2])*`sigmath12'+(`B'[`j',1]*`B'[`j',2]^2*`B'[`l',1]+`B'[`j',1]^2*`B'[`j',2]*`B'[`l',2])*`sigmath22')/2*`l4``j'''*`l2``l''' + scalar `tmp3'=(`B'[`j',1]^2*`B'[`l',1]^2*`sigmath11'+(`B'[`j',1]^2*`B'[`l',1]*`B'[`l',2]+`B'[`j',1]*`B'[`j',2]*`B'[`l',1]^2)*`sigmath12'+`B'[`j',1]*`B'[`j',2]*`B'[`l',1]*`B'[`l',2]*`sigmath22')*`l3``j'''*`l3``l''' + matrix `D22'[`k',1]=`tmp1'+`tmp2'+`tmp3' + scalar `tmp1'=`B'[`j',2]*`B'[`l',2]*`l2``j'''*`l2``l'''+(2*`B'[`j',2]*`B'[`l',2]^3*`sigmath22'+(3*`B'[`j',2]*`B'[`l',2]^2*`B'[`l',1]+`B'[`j',1]*`B'[`l',2]^3)*`sigmath12'+(`B'[`j',2]*`B'[`l',2]*`B'[`l',1]^2+`B'[`j',1]*`B'[`l',2]^2*`B'[`l',1])*`sigmath11')/2*`l2``j'''*`l4``l''' + scalar `tmp2'=(2*`B'[`j',2]^3*`B'[`l',2]*`sigmath22'+(3*`B'[`j',2]^2*`B'[`j',1]*`B'[`l',2]+`B'[`j',2]^3*`B'[`l',1])*`sigmath12'+(`B'[`j',2]*`B'[`j',1]^2*`B'[`l',2]+`B'[`j',2]^2*`B'[`j',1]*`B'[`l',1])*`sigmath11')/2*`l4``j'''*`l2``l''' + scalar `tmp3'=(`B'[`j',1]^2*`B'[`l',1]^2*`sigmath22'+(`B'[`j',1]^2*`B'[`l',1]*`B'[`l',2]+`B'[`j',1]*`B'[`j',2]*`B'[`l',1]^2)*`sigmath12'+`B'[`j',1]*`B'[`j',2]*`B'[`l',1]*`B'[`l',2]*`sigmath11')*`l3``j'''*`l3``l''' + matrix `D22'[`k',2]=`tmp1'+`tmp2'+`tmp3' + scalar `tmp1'=(`B'[`j',1]*`B'[`l',2]+`B'[`j',2]*`B'[`l',1])*`l2``j'''*`l2``l'''+((3*`B'[`j',1]*`B'[`l',1]^2*`B'[`l',2]+`B'[`j',2]*`B'[`l',1]^3)*`sigmath11'+4*(`B'[`j',1]*`B'[`l',1]*`B'[`l',2]^2+`B'[`j',2]*`B'[`l',1]^2*`B'[`l',2])*`sigmath12'+(`B'[`j',1]*`B'[`l',2]^3+3*`B'[`j',2]*`B'[`l',1]*`B'[`l',2]^2)*`sigmath22')/2*`l2``j'''*`l4``l''' + scalar `tmp2'=((3*`B'[`j',1]^2*`B'[`j',2]*`B'[`l',1]+`B'[`j',1]^3*`B'[`l',2])*`sigmath11'+4*(`B'[`j',1]*`B'[`j',2]^2*`B'[`l',1]+`B'[`j',1]^2*`B'[`j',2]*`B'[`l',2])*`sigmath12'+(`B'[`j',2]^3*`B'[`l',1]+3*`B'[`j',1]*`B'[`j',2]^2*`B'[`l',2])*`sigmath22')/2*`l4``j'''*`l2``l''' + scalar `tmp3'=((`B'[`j',1]^2*`B'[`l',1]*`B'[`l',2]+`B'[`j',1]*`B'[`j',2]*`B'[`l',2]^2)*`sigmath11'+(`B'[`j',1]^2*`B'[`l',2]^2+2*`B'[`j',1]*`B'[`j',2]*`B'[`l',1]*`B'[`l',2]+`B'[`j',2]^2*`B'[`l',1]^2)*`sigmath12'+(`B'[`j',1]*`B'[`j',2]*`B'[`l',2]^2+`B'[`j',2]^2*`B'[`l',1]*`B'[`l',2])*`sigmath22')*`l3``j'''*`l3``l''' + matrix `D22'[`k',3]=`tmp1'+`tmp2'+`tmp3' + } + else if `Q'==1 { + scalar `tmp1'=`B'[`j',1]*`B'[`l',1]*`l2``j'''*`l2``l'''+(2*`B'[`j',1]*`B'[`l',1]^3*`sigmath11')/2*`l2``j'''*`l4``l''' + scalar `tmp2'=(2*`B'[`j',1]^3*`B'[`l',1]*`sigmath11')/2*`l4``j'''*`l2``l''' + scalar `tmp3'=(`B'[`j',1]^2*`B'[`l',1]^2*`sigmath11')*`l3``j'''*`l3``l''' + matrix `D22'[`k',1]=`tmp1'+`tmp2'+`tmp3' + } + } + matrix `D'=(`D11',`D12' \ `D21',`D22') + + /*CALCUL DE LA MATRICE CHSI*/ + + tempname chsi + matrix `chsi'=J(`nbitems'+`carre',1,0) + + forvalues j=1/`nbitems' { + matrix `chsi'[`j',1]=(`si`j''-`N'*`mui`j'')/`N' + } + forvalues k=1/`carre' { + local j=`compocarre'[1,`k'] + local l=`compocarre'[2,`k'] + local tmp=`nbitems'+`k' + matrix `chsi'[`tmp',1]=(`si`j'j`l''-`si`j''*`mui`l''-`si`l''*`mui`j''+`N'*`mui`j''*`mui`l''-`N'*`sigmai`j'j`l'')/`N' + } + + /*CALCUL DE L'ETAPE k*/ + tempname betaold + matrix `betaold'=`beta' + matrix `beta'=`betaold'+inv(`D''*inv(`V')*`D')*`D''*inv(`V')*`chsi' + + local l=`nbitems'+1 + local sigmath11=`beta'[`l',1] + local l=`nbitems'+2 + local sigmath22=`beta'[`l',1] + local l=`nbitems'+3 + local sigmath12=`beta'[`l',1] + + tempname epsilon variatold + scalar `variatold'=`variat'[1,1] + matrix `epsilon'=`betaold'-`beta' + matrix `variat'=(`epsilon''*`epsilon') + + if `variat'[1,1]>`variatold' { + matrix `beta'=`betaold' + local l=`nbitems'+1 + local sigm ath11=`beta'[`l',1] + if `Q'==2 { + local l=`nbitems'+2 + local sigmath22=`beta'[`l',1] + local l=`nbitems'+3 + local sigmath12=`beta'[`l',1] + } + local conv=0 + } + else { + local macrovariat=`variat'[1,1] + } +} + +/*************************CALCUL des STANDARDS ERRORS DES PARAMETRES *********************/ + +if "`var'"==""{ + tempname xicarreA xicarreB xicarreC xicarre + matrix `xicarreA'=J(`nbitems',`nbitems',0) + matrix `xicarreB'=J(`nbitems',`carre',0) + matrix `xicarreC'=J(`carre',`carre',0) + forvalues i=1/`nbitems' { + forvalues j=`=`i'+1'/`nbitems' { + matrix `xicarreA'[`i',`j']=`si`i'j`j''-`si`i''*`mui`j''-`si`j''*`mui`i''+`N'*`mui`i''*`mui`j'' + matrix `xicarreA'[`i',`j']=`xicarreA'[`j',`i'] + } + forvalues col=1/`carre' { + local j=`compocarre'[1,`col'] + local k=`compocarre'[2,`col'] + matrix `xicarreB'[`i',`col']=`si`i'j`j'k`k''-`mui`i''*`si`j'j`k''-`mui`j''*`si`i'j`k''-`mui`k''*`si`i'j`j''+`mui`i''*`mui`j''*`si`k''+`mui`i''*`mui`k''*`si`j''+`mui`j''*`mui`k''*`si`i''-`N'*`mui`i''*`mui`j''*`mui`k''-`sigmai`j'j`k''*`si`i''+`N'*`mui`i''*`sigmai`j'j`k''' + } + } + forvalues row=1/`carre' { + forvalues col=`row'/`carre' { + local i=`compocarre'[1,`row'] + local j=`compocarre'[2,`row'] + local k=`compocarre'[1,`col'] + local l=`compocarre'[2,`col'] + matrix `xicarreC'[`row',`col']=`si`i'j`j'k`k'l`l''-`mui`i''*`si`j'j`k'l`l''-`mui`j''*`si`i'j`k'k`l''-`mui`k''*`si`i'j`j'k`l''-`mui`l''*`si`i'j`j'k`k''+`mui`i''*`mui`j''*`si`k'j`l''+`mui`i''*`mui`k''*`si`j'j`l''+`mui`i''*`mui`l''*`si`j'j`k''+`mui`j''*`mui`k''*`si`i'j`l''+`mui`j''*`mui`l''*`si`i'j`k''+`mui`k''*`mui`l''*`si`i'j`j''-`mui`i''*`mui`j''*`mui`k''*`si`l''-`mui`i''*`mui`j''*`mui`l''*`si`k''-`mui`i''*`mui`k''*`mui`l''*`si`j''-`mui`j''*`mui`k''*`mui`l''*`si`i''-`sigmai`i'j`j''*`si`k'j`l''-`sigmai`k'j`l''*`si`i'j`j''+`sigmai`i'j`j''*`mui`k''*`si`l''+`sigmai`i'j`j''*`mui`l''*`si`k''+`sigmai`k'j`l''*`mui`i''*`si`j''+`sigmai`k'j`l''*`mui`j''*`si`i''+`N'*`mui`i''*`mui`j''*`mui`k''*`mui`l''-`N'*`sigmai`i'j`j''*`mui`k''*`mui`l''-`N'*`sigmai`k'j`l''*`mui`i''*`mui`j''+`N'*`sigmai`i'j`j''*`sigmai`k'j`l'' + matrix `xicarreC'[`col',`row']=`xicarreC'[`row',`col'] + } + } + matrix `xicarre'=(`xicarreA',`xicarreB' \ `xicarreB' ',`xicarreC') + tempname A1 A2 W + matrix `A1'=`D' '*inv(`V')*`D' + matrix `A2'=`D' '*inv(`V')*`xicarre'*inv(`V')*`D' + matrix `W'=1/`N'^2*inv(`A1')*`A2'*inv(`A1') +} + +/*****************************DISPLAY THE RESULTS***************************************/ + + +local compteur=`compteur'-1 +di "" +di "" +if `compteur'==0 { + noi di in red _col(8) "The algorithm does not converge" + return scalar error=1 + exit +} +if `variat'[1,1]<=`critconv'&`compteur'>0 { + noi di in green _col(8) "The algorithm converges at the `compteur'th iteration" +} +if `compteur'==`nbit'&`variat'[1,1]>`critconv' { + noi di in green _col(8) "The algorithm is stopped at the `compteur'th iteration" +} +if `conv'==0&`compteur'>0 { + noi di in green _col(8) "The algorithm no more converges after the `compteur'th iteration" +} +di "" +if "`var'"=="" { + noi di in green _col(30) "Parameters" in green _col(43) "Standard errors" + forvalues j=1/`nbitems' { + noi di in green _col(20) "``j'': " in yellow _col(30) %10.6f `beta'[`j',1] in yellow _col(50) %8.6f sqrt(`W'[`j',`j']) + } + di "" + noi di in green _col(20) "var1: " in yellow _col(30) %10.6f `beta'[`nbitems'+1,1] in yellow _col(50) %8.6f sqrt(`W'[`nbitems'+1,`nbitems'+1]) + if `Q'==2 { + noi di in green _col(20) "var2: " in yellow _col(30) %10.6f `beta'[`nbitems'+2,1] in yellow _col(50) %8.6f sqrt(`W'[`nbitems'+2,`nbitems'+2]) + tempname rho + scalar `rho'=`beta'[`nbitems'+3,1]/sqrt(`beta'[`nbitems'+1,1]*`beta'[`nbitems'+2,1]) + noi di in green _col(20) "covar: " in yellow _col(30) %10.6f `beta'[`nbitems'+3,1] in yellow _col(50) %8.6f sqrt(`W'[`nbitems'+3,`nbitems'+3]) " (rho=" %5.4f `rho' ")" + } +} +else { + noi di in green _col(30) "Parameters" + forvalues j=1/`nbitems' { + noi di in green _col(20) "``j'': " in yellow _col(30) %10.6f `beta'[`j',1] + } + di "" + noi di in green _col(20) "var1: " in yellow _col(30) %10.6f `beta'[`nbitems'+1,1] + if `Q'==2 { + noi di in green _col(20) "var2: " in yellow _col(30) %10.6f `beta'[`nbitems'+2,1] + tempname rho + scalar `rho'=`beta'[`nbitems'+3,1]/sqrt(`beta'[`nbitems'+1,1]*`beta'[`nbitems'+2,1]) + noi di in green _col(20) "covar: " in yellow _col(30) %10.6f `beta'[`nbitems'+3,1] + } +} +di "" +if "`ll'"!="" { + tempname noeuds poids + ghquadm `quad' `noeuds' `poids' + tempvar vrais logvrais P + qui gen `P'=0 + qui gen `vrais'=0 + if `Q'==1 { + forvalues u=1/`quad'{ + tempvar vrais`u' + qui gen `vrais`u''=1/sqrt(_pi) + forvalues j=1/`nbitems' { + qui replace `P'=exp(`B'[`j',1]*sqrt(2*`beta'[`nbitems'+1,1])*`noeuds'[1,`u']-`beta'[`j',1])/(1+exp(`B'[`j',1]*sqrt(2*`beta'[`nbitems'+1,1])*`noeuds'[1,`u']-`beta'[`j',1])) + qui replace `P'=1-`P' if ``j''==0 + qui replace `vrais`u''=`vrais`u''*`P' + } + qui replace `vrais'=`vrais'+`poids'[1,`u']*`vrais`u'' + } + gen `logvrais'=log(`vrais') + qui su `logvrais' + local ll=r(N)*r(mean) + noi di in green _col(20) "ll: " in yellow _col(30) %12.4f `ll' + local AIC=-2*`ll'+2*(`nbitems'+1) + noi di in green _col(20) "AIC: " in yellow _col(30) %12.4f `AIC' + } + + if `Q'==2 { + tempname sigma + matrix `sigma'=(`beta'[`nbitems'+1,1],`beta'[`nbitems'+3,1] \ `beta'[`nbitems'+3,1],`beta'[`nbitems'+2,1]) + forvalues u=1/`quad'{ + forvalues v=1/`quad'{ + tempvar vraisu`u'v`v' + qui gen `vraisu`u'v`v''=1/_pi + forvalues j=1/`nbitems' { + local A1`u'tilde=sqrt(`beta'[`nbitems'+2,1]/(2*det(`sigma')))*`noeuds'[1,`u'] + local A2`v'tilde=(`noeuds'[1,`v']-`beta'[`nbitems'+3,1]/sqrt(det(`sigma'))*`noeuds'[1,`u'])/(2*`beta'[`nbitems'+2,1]) + qui replace `P'=exp(`B'[`j',1]*`A1`u'tilde'+`B'[`j',2]*`A2`v'tilde'-`beta'[`j',1])/(1+exp(`B'[`j',1]*`A1`u'tilde'+`B'[`j',2]*`A2`v'tilde'-`beta'[`j',1])) + qui replace `P'=1-`P' if ``j''==0 + qui replace `vraisu`u'v`v''=`vraisu`u'v`v''*`P' + } + qui replace `vrais'=`vrais'+`poids'[1,`u']*`poids'[1,`v']*`vraisu`u'v`v'' + } + } + qui gen `logvrais'=log(`vrais') + qui su `logvrais' + local ll=r(N)*r(mean) + noi di in green _col(20) "ll: " in yellow _col(27) %12.4f `ll' + local AIC=-2*`ll'+2*(`nbitems'+3) + noi di in green _col(20) "AIC: " in yellow _col(27) %12.4f `AIC' + } +} +if "`var'"=="" { + return matrix V `W' +} +matrix `beta'=`beta'' +return matrix b= `beta' + +if "`ll'"!="" { + return scalar ll= `ll' + return scalar AIC= `AIC' +} + +return scalar J= `nbitems' +return scalar N= `N' +return scalar error=0 + +restore +end + diff --git a/Modules/ado/personal/g/geekel2d.hlp b/Modules/ado/personal/g/geekel2d.hlp new file mode 100644 index 0000000..925e689 --- /dev/null +++ b/Modules/ado/personal/g/geekel2d.hlp @@ -0,0 +1,78 @@ +{smcl} +{* 2july2005}{...} +{hline} +help for {hi:geekel2d}{right:Jean-Benoit Hardouin} +{hline} + +{title:Estimation of the parameters of undimensional and bidimensional IRT models} + +{p 8 14 12}{cmd:geekel2d} {it:varlist} [{cmd:,} {cmdab:coef}({it:matrixname}) {cmdab:nbit}({it:#}) {cmdab:critconv}({it:#}) {cmdab:ll} {cmdab:quad}({it:#}) {cmdab:novar}] + +{p 8 14 12}{it:varlist} is a list of two existing dichotomous variables or more. + +{title:Description} + +{p 4 8 2}{cmd:geekel2d} estimates, by Generalized Estimating +Equations (GEE), the parameters of the model defined by Kelderman (1994) with +one or two dimensions and dichotomic items. This model includes the Rasch model +and the One Parameter Logistic Model (OPLM) for the unidimensional models, the +Multidimensional Generalized Rasch Model (MGRM) and the Multidimensional +Completely Sufficient Rasch Model (MMSRM) for the two-dimensional models. + +{title:Options} + +{p 4 8 2}{cmd:coef} is the name of a matrix which contains the coeficients B. This +matrix relies the items and the latent traits. Each row represents an item and +there is as many colmuns than the supposed number of latent traits (one or two). +The coefficients are choosen, in general, among the first intergers, but +{cmd:geekel2d} allows using real coefficients. By default, the Rasch model is +supposed (the matrix {cmd: coef} is a vector of 1). + +{p 4 8 2}{cmd:nbit} defines the maximal number of iterations in the estimation +algorithm. By default, this number is fixed to 30. + +{p 4 8 2}{cmd:critconv} is the value of the convergence criterion, calculated +as the square of the cross-product of the vector containing the difference +between two successive iterations of the parameters estimations. By default, +this criterion is fixed to 1e-15. + +{p 4 8 2}{cmd:ll} estimates the marginal log-likelihood and the Akaike +Information Criterion (AIC) by Gauss-Hermite quadratures. + +{p 4 8 2}{cmd:quad} defines the number of nodes of quadratures. + +{p 4 8 2}{cmd:novar} avoids to compute the standards errors of the estimators (faster). + +{title:Remarks} + +{p 4 8 2}For detailed informations on the Kelderman model, see Kelderman and +Rijkes (1994) or Adams and al. (1997). + +{p 4 8 2}{cmd:geekel2d} don't allows using of polytomous items. + +{p 4 8 2}The {cmd:ghquadm} Stata module is needed (use {cmd:findit ghquadm} to obtain it). + + +{title:Example} + +{p 4 8 2}{cmd:. geekel2d item1 item2 item3 item4} /*Rasch model*/ + +{p 4 8 2}{cmd:. matrix B=(1,0\1,0\0,1\0,1)} + +{p 4 8 2}{cmd:. geekel2d item1 item2 item3 item4 , coef(B) nbit(50) critconv(1e-30)} + + +{title:References} + +{p 4 8 2}Kelderman H. and Rijkes C. P. M., Loglinear multidimensional IRT models for polytomously scored items. {it:Psychometrika}, 1994, {it:59}, 149-176. + +{p 4 8 2}Adams R. J., Wilson M. R. and Wang W., The multidimensional random coefficient multinomial logit model. {it:Applied Psychological Measurement}, 1997, {it:21}, 1-23. + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, Regional Health Observatory (ORS) - 1, rue Porte +Madeleine - BP 2439 - 45032 Orleans Cedex 1 - France. You can contact the +author at +{browse "mailto:jean-benoit.hardouin@orscentre.org":jean-benoit.hardouin@orscentre.org} +and visit the websites {browse "http://anaqol.free.fr":AnaQol} +and {browse "http://freeirt.free.fr":FreeIRT} diff --git a/Modules/ado/personal/g/geekel2d4.ado b/Modules/ado/personal/g/geekel2d4.ado new file mode 100644 index 0000000..22d4adf --- /dev/null +++ b/Modules/ado/personal/g/geekel2d4.ado @@ -0,0 +1,534 @@ +************************************************************************************************************ +* GEEkel2d: GEE for estimation of unidimensional or 2-dimensional Latent Trait models (Kelderman and Rijkes 1994) +* Version 4 : June 8, 2004 +* +* Historic: +* Version 1 (2003-06-23): Jean-Benoit Hardouin +* Version 2 (2003-08-13): Jean-Benoit Hardouin +* version 3 (2003-11-06): Jean-Benoit Hardouin +* +* Use the ghquadm program (findit ghquadm) +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@neuf.fr +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2003, 2004 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************* + +program define GEEkel2d ,rclass +version 7.0 +syntax varlist(min=2 numeric) [, coef(string) novar ll nbit(integer 30) critconv(real 1e-15) quad(integer 12)] + +preserve +local nbitems: word count `varlist' +tokenize `varlist' + +qui count +local N=r(N) + +forvalues i=1/`nbitems' { +qui drop if ``i''==. +} + +qui count +local Naf=r(N) + +di _col(3) in green "Initial step (N=" in yellow `Naf' in green ")" +di _col(3) in yellow `=`N'-`Naf'' in green " observations are not used for missing values" +di + +qui count +local N=r(N) +tempname B Q +if "`coef'"!="" { +matrix `B'=`coef' +} +else { +matrix `B'=J(`nbitems',1,1) +} + +scalar `Q'=colsof(`B') + +/* CALCUL INITIAUX DES PARAMETRES DELTA ET SIGMA ET DE LA MATRICE BETA*/ + +local sigmath11=.25 + +if `Q'==2 { +local sigmath22=.25 +local sigmath12=0.125 +} + +tempname beta +matrix `beta'=J(`nbitems'+`Q'*(`Q'+1)/2,1,0) +forvalues j=1/`nbitems' { +qui count if ``j''==1 +local s``j''=r(N) +local delta``j''=-log(`s``j'''/(`N'-`s``j''')) +matrix `beta'[`j',1]=`delta``j''' +} + + +forvalues j=1/`nbitems' { +forvalues l=1/`nbitems' { +quiet count if ``j''==1&``l''==1 +local s``j''``l''=r(N) +} +} + +if "`var'"==""{ +forvalues i=1/`nbitems' { +forvalues j=1/`nbitems' { +forvalues k=1/`nbitems' { +quiet count if ``i''==1&``j''==1&``k''==1 +local s``i''``j''``k''=r(N) +} +} +} + +forvalues i=1/`nbitems' { +forvalues j=1/`nbitems' { +forvalues k=1/`nbitems' { +forvalues l=1/`nbitems' { +quiet count if ``i''==1&``j''==1&``k''==1&``l''==1 +local s``i''``j''``k''``l''=r(N) +} +} +} +} + +} + +local l=`nbitems'+1 +matrix `beta'[`l',1]=`sigmath11' + +if `Q'==2 { +local l=`nbitems'+2 +matrix `beta'[`l',1]=`sigmath22' + +local l=`nbitems'+3 +matrix `beta'[`l',1]=`sigmath12' +} + + + +tempname variat V11 V12 V21 V22 D11 D12 D21 D22 V D +matrix `variat'=(1) + +local compteur=0 +local conv=1 + + +/*********ITERATIONS******************/ + + + +while (`variat'[1,1]>`critconv'&`compteur'<=`nbit'&`conv'==1) { + +if `compteur'==0{ +di in green _col(3) "First iteration" +} +else { +di in green _col(3) "iteration:" in yellow _col(14) "`compteur'" in green _col(25) "Convergence index:" in yellow _col(44) %10.7e "`macrovariat'" +} + +local compteur=`compteur'+1 + + +forvalues j=1/`nbitems' { + +/* CALCUL DES DERIVEES 1 A 6 POUR CHAQUE ITEM*/ + +local l1``j''=1/(1+exp(`beta'[`j',1])) +local l2``j''=exp(`beta'[`j',1])/(1+exp(`beta'[`j',1]))^2 +local l3``j''=exp(`beta'[`j',1])*(exp(`beta'[`j',1])-1)/(1+exp(`beta'[`j',1]))^3 +local l4``j''=exp(`beta'[`j',1])*(exp(2*`beta'[`j',1])-4*exp(`beta'[`j',1])+1)/(1+exp(`beta'[`j',1]))^4 +local l5``j''=exp(`beta'[`j',1])*(exp(3*`beta'[`j',1])-11*exp(2*`beta'[`j',1])+11*exp(`beta'[`j',1])-1)/(1+exp(`beta'[`j',1]))^5 +local l6``j''=exp(`beta'[`j',1])*(exp(4*`beta'[`j',1])-26*exp(3*`beta'[`j',1])+66*exp(2*`beta'[`j',1])-26*exp(`beta'[`j',1])+1)/(1+exp(`beta'[`j',1]))^6 + +if `Q'==2 { +local H2``j''=`B'[`j',1]^2*`sigmath11'+`B'[`j',1]*`B'[`j',2]*`sigmath12'+`B'[`j',2]^2*`sigmath22' +local H4``j''=3*`B'[`j',1]^4*`sigmath11'^2+12*`B'[`j',1]^3*`B'[`j',2]*`sigmath11'*`sigmath12'+6*`B'[`j',1]^2*`B'[`j',2]^2*(`sigmath11'*`sigmath22'+2*`sigmath12'^2)+12*`B'[`j',1]*`B'[`j',2]^3*`sigmath22'*`sigmath12'+3*`B'[`j',2]^4*`sigmath22'^2 +} +if `Q'==1 { +local H2``j''=`B'[`j',1]^2*`sigmath11' +local H4``j''=3*`B'[`j',1]^4*`sigmath11'^2 +} + + +/* CALCUL DES MOMENTS D'ORDRE 1 ET 2 ET DE LA MATRICE V11*/ + +local mu``j''=`l1``j'''+`H2``j'''/2*`l3``j'''+`H4``j'''/24*`l5``j''' +local sigma``j''``j''=`l2``j'''+`H2``j'''/2*(`l3``j'''-2*`l1``j'''*`l3``j''')+`H4``j'''/24*(`l5``j'''-2*(`l3``j''')^2-2*`l1``j'''*`l5``j''') +} + + +matrix `V11'=J(`nbitems',`nbitems',0) + +forvalue j=1/`nbitems' { +forvalue l=`j'/`nbitems' { + +if `j'!=`l' { +if `Q'==2 { +local H2``j''``l''=`B'[`j',1]*`B'[`l',1]*`sigmath11'+(`B'[`j',1]*`B'[`l',2]+`B'[`j',2]*`B'[`l',1])*`sigmath12'+`B'[`j',2]*`B'[`l',2]*`sigmath22' +local H4``j''1``l''3=3*`B'[`j',1]*`B'[`l',1]^3*`sigmath11'^2+3*(3*`B'[`j',1]*`B'[`l',1]^2*`B'[`l',2]+`B'[`j',2]*`B'[`l',1]^3)*`sigmath11'*`sigmath12'+(3*`B'[`j',1]*`B'[`l',1]*`B'[`l',2]^2+3*`B'[`j',2]*`B'[`l',1]^2*`B'[`l',2])*(`sigmath11'*`sigmath22'+2*`sigmath12'^2)+3*(`B'[`j',1]*`B'[`l',2]^3+3*`B'[`j',2]*`B'[`l',1]*`B'[`l',2]^2)*`sigmath22'*`sigmath12'+3*`B'[`j',2]*`B'[`l',2]^3*`sigmath22'^2 +local H4``j''2``l''2=3*`B'[`j',1]^2*`B'[`l',1]^2*`sigmath11'^2+6*(`B'[`j',1]^2*`B'[`l',1]*`B'[`l',2]+`B'[`j',1]*`B'[`j',2]*`B'[`l',1]^2)*`sigmath11'*`sigmath12'+(`B'[`j',1]^2*`B'[`l',2]^2+4*`B'[`j',1]*`B'[`j',2]*`B'[`l',1]*`B'[`l',2]+`B'[`j',2]^2*`B'[`l',1]^2)*(`sigmath11'*`sigmath22'+2*`sigmath12'^2)+6*(`B'[`j',1]*`B'[`j',2]*`B'[`l',2]^2+`B'[`j',2]^2*`B'[`l',1]*`B'[`l',2])*`sigmath22'*`sigmath12'+3*`B'[`j',2]^2*`B'[`l',2]^2*`sigmath22'^2 +local H4``j''3``l''1=3*`B'[`l',1]*`B'[`j',1]^3*`sigmath11'^2+3*(3*`B'[`l',1]*`B'[`j',1]^2*`B'[`j',2]+`B'[`l',2]*`B'[`j',1]^3)*`sigmath11'*`sigmath12'+(3*`B'[`l',1]*`B'[`j',1]*`B'[`j',2]^2+3*`B'[`l',2]*`B'[`j',1]^2*`B'[`j',2])*(`sigmath11'*`sigmath22'+2*`sigmath12'^2)+3*(`B'[`l',1]*`B'[`j',2]^3+3*`B'[`l',2]*`B'[`j',1]*`B'[`j',2]^2)*`sigmath22'*`sigmath12'+3*`B'[`l',2]*`B'[`j',2]^3*`sigmath22'^2 +} +if `Q'==1 { +local H2``j''``l''=`B'[`j',1]*`B'[`l',1]*`sigmath11' +local H4``j''1``l''3=3*`B'[`j',1]*`B'[`l',1]^3*`sigmath11'^2 +local H4``j''2``l''2=3*`B'[`j',1]^2*`B'[`l',1]^2*`sigmath11'^2 +local H4``j''3``l''1=3*`B'[`l',1]*`B'[`j',1]^3*`sigmath11'^2 +} + + +local sigma``j''``l''=`H2``j''``l'''*(`l2``j'''*`l2``l''')+`H4``j''1``l''3'/6*`l2``j'''*`l4``l'''+`H4``j''3``l''1'/6*`l4``j'''*`l2``l'''+(`H4``j''2``l''2'-`H2``j'''*`H2``l''')/4*`l3``j'''*`l3``l''' + + +} + +matrix `V11'[`j',`l']=`sigma``j''``l''' +matrix `V11'[`l',`j']=`sigma``j''``l''' +} +} + +/* DEFINITION DE LA MATRICE COMPOCARRE*/ + +tempname compocarre m +local carre=`nbitems'*(`nbitems'-1)/2 +matrix `compocarre'=J(2,`carre',0) + +scalar `m'=0 +forvalue j=1/`nbitems' { +local lbis=`j'+1 +forvalue l=`lbis'/`nbitems' { +scalar `m'=`m'+1 +matrix `compocarre'[1,`m']=`j' +matrix `compocarre'[2,`m']=`l' +} +} + +/* CALCUL DE LA MATRICE V22*/ + +matrix `V22'=J(`carre',`carre',0) +forvalue k=1/`carre' { +local j=`compocarre'[1,`k'] +local l=`compocarre'[2,`k'] + +matrix `V22'[`k',`k']=(1-2*`mu``j''')*(1-2*`mu``l''')*`sigma``j''``l'''+`sigma``j''``j'''*`sigma``l''``l'''-`sigma``j''``l'''^2 +} + +/* CALCUL DES MATRICES V12, V21 ET V*/ + +matrix `V12'=J(`nbitems',`carre',0) +forvalue k=1/`carre' { +local j=`compocarre'[1,`k'] +local l=`compocarre'[2,`k'] + +matrix `V12'[`j',`k']=(1-2*`mu``j''')*`sigma``j''``l''' +matrix `V12'[`l',`k']=(1-2*`mu``l''')*`sigma``j''``l''' +} +matrix `V21'=`V12' ' +matrix `V'=(`V11',`V12' \ `V21',`V22') + + +/*CALCUL DES MATRICES D11*/ + +matrix `D11'=J(`nbitems',`nbitems',0) +matrix `D12'=J(`nbitems',`Q'*(`Q'+1)/2,0) + +forvalue j=1/`nbitems' { +matrix `D11'[`j',`j']=-`l2``j'''-`H2``j'''/2*`l4``j'''-`H4``j'''/24*`l6``j''' + +if `Q'==2 { +matrix `D12'[`j',1]=`B'[`j',1]^2*`l3``j'''/2+(`B'[`j',1]^4*`sigmath11'+2*`B'[`j',1]^3*`B'[`j',2]*`sigmath12'+`B'[`j',1]^2*`B'[`j',2]^2*`sigmath22')/4*`l5``j''' +matrix `D12'[`j',2]=`B'[`j',2]^2*`l3``j'''/2+(`B'[`j',2]^4*`sigmath22'+2*`B'[`j',2]^3*`B'[`j',1]*`sigmath12'+`B'[`j',2]^2*`B'[`j',1]^2*`sigmath11')/4*`l5``j''' +matrix `D12'[`j',3]=`B'[`j',1]*`B'[`j',2]*`l3``j'''+(`B'[`j',1]^3*`B'[`j',2]*`sigmath11'+2*`B'[`j',1]^2*`B'[`j',2]^2*`sigmath12'+`B'[`j',1]*`B'[`j',2]^3*`sigmath22')/2*`l5``j''' +} +if `Q'==1 { +matrix `D12'[`j',1]=`B'[`j',1]^2*`l3``j'''/2+`B'[`j',1]^4*`sigmath11'/4*`l5``j''' +} +} + +/*CALCUL DES MATRICES D21, D22 et D*/ + + +matrix `D21'=J(`carre',`nbitems',0) +matrix `D22'=J(`carre',`Q'*(`Q'+1)/2,0) + +forvalue k=1/`carre' { +local j=`compocarre'[1,`k'] +local l=`compocarre'[2,`k'] + +matrix `D21'[`k',`j']=-`H2``j''``l'''*`l3``j'''*`l2``l'''-`H4``j''1``l''3'/6*`l3``j'''*`l4``l'''-`H4``j''3``l''1'/6*`l5``j'''*`l2``l'''-(`H4``j''2``l''2'-`H2``j'''*`H2``l''')/4*`l4``j'''*`l3``l''' +matrix `D21'[`k',`l']=-`H2``j''``l'''*`l2``j'''*`l3``l'''-`H4``j''3``l''1'/6*`l4``j'''*`l3``l'''-`H4``j''1``l''3'/6*`l2``j'''*`l5``l'''-(`H4``j''2``l''2'-`H2``j'''*`H2``l''')/4*`l3``j'''*`l4``l''' + +if `Q'==2 { +scalar tmp1=`B'[`j',1]*`B'[`l',1]*`l2``j'''*`l2``l'''+(2*`B'[`j',1]*`B'[`l',1]^3*`sigmath11'+(3*`B'[`j',1]*`B'[`l',1]^2*`B'[`l',2]+`B'[`j',2]*`B'[`l',1]^3)*`sigmath12'+(`B'[`j',1]*`B'[`l',1]*`B'[`l',2]^2+`B'[`j',2]*`B'[`l',1]^2*`B'[`l',2])*`sigmath22')/2*`l2``j'''*`l4``l''' +scalar tmp2=(2*`B'[`j',1]^3*`B'[`l',1]*`sigmath11'+(3*`B'[`j',1]^2*`B'[`j',2]*`B'[`l',1]+`B'[`j',1]^3*`B'[`l',2])*`sigmath12'+(`B'[`j',1]*`B'[`j',2]^2*`B'[`l',1]+`B'[`j',1]^2*`B'[`j',2]*`B'[`l',2])*`sigmath22')/2*`l4``j'''*`l2``l''' +scalar tmp3=(`B'[`j',1]^2*`B'[`l',1]^2*`sigmath11'+(`B'[`j',1]^2*`B'[`l',1]*`B'[`l',2]+`B'[`j',1]*`B'[`j',2]*`B'[`l',1]^2)*`sigmath12'+`B'[`j',1]*`B'[`j',2]*`B'[`l',1]*`B'[`l',2]*`sigmath22')*`l3``j'''*`l3``l''' + +matrix `D22'[`k',1]=tmp1+tmp2+tmp3 + +scalar tmp1=`B'[`j',2]*`B'[`l',2]*`l2``j'''*`l2``l'''+(2*`B'[`j',2]*`B'[`l',2]^3*`sigmath22'+(3*`B'[`j',2]*`B'[`l',2]^2*`B'[`l',1]+`B'[`j',1]*`B'[`l',2]^3)*`sigmath12'+(`B'[`j',2]*`B'[`l',2]*`B'[`l',1]^2+`B'[`j',1]*`B'[`l',2]^2*`B'[`l',1])*`sigmath11')/2*`l2``j'''*`l4``l''' +scalar tmp2=(2*`B'[`j',2]^3*`B'[`l',2]*`sigmath22'+(3*`B'[`j',2]^2*`B'[`j',1]*`B'[`l',2]+`B'[`j',2]^3*`B'[`l',1])*`sigmath12'+(`B'[`j',2]*`B'[`j',1]^2*`B'[`l',2]+`B'[`j',2]^2*`B'[`j',1]*`B'[`l',1])*`sigmath11')/2*`l4``j'''*`l2``l''' +scalar tmp3=(`B'[`j',1]^2*`B'[`l',1]^2*`sigmath22'+(`B'[`j',1]^2*`B'[`l',1]*`B'[`l',2]+`B'[`j',1]*`B'[`j',2]*`B'[`l',1]^2)*`sigmath12'+`B'[`j',1]*`B'[`j',2]*`B'[`l',1]*`B'[`l',2]*`sigmath11')*`l3``j'''*`l3``l''' + +matrix `D22'[`k',2]=tmp1+tmp2+tmp3 + +scalar tmp1=(`B'[`j',1]*`B'[`l',2]+`B'[`j',2]*`B'[`l',1])*`l2``j'''*`l2``l'''+((3*`B'[`j',1]*`B'[`l',1]^2*`B'[`l',2]+`B'[`j',2]*`B'[`l',1]^3)*`sigmath11'+4*(`B'[`j',1]*`B'[`l',1]*`B'[`l',2]^2+`B'[`j',2]*`B'[`l',1]^2*`B'[`l',2])*`sigmath12'+(`B'[`j',1]*`B'[`l',2]^3+3*`B'[`j',2]*`B'[`l',1]*`B'[`l',2]^2)*`sigmath22')/2*`l2``j'''*`l4``l''' +scalar tmp2=((3*`B'[`j',1]^2*`B'[`j',2]*`B'[`l',1]+`B'[`j',1]^3*`B'[`l',2])*`sigmath11'+4*(`B'[`j',1]*`B'[`j',2]^2*`B'[`l',1]+`B'[`j',1]^2*`B'[`j',2]*`B'[`l',2])*`sigmath12'+(`B'[`j',2]^3*`B'[`l',1]+3*`B'[`j',1]*`B'[`j',2]^2*`B'[`l',2])*`sigmath22')/2*`l4``j'''*`l2``l''' +scalar tmp3=((`B'[`j',1]^2*`B'[`l',1]*`B'[`l',2]+`B'[`j',1]*`B'[`j',2]*`B'[`l',2]^2)*`sigmath11'+(`B'[`j',1]^2*`B'[`l',2]^2+2*`B'[`j',1]*`B'[`j',2]*`B'[`l',1]*`B'[`l',2]+`B'[`j',2]^2*`B'[`l',1]^2)*`sigmath12'+(`B'[`j',1]*`B'[`j',2]*`B'[`l',2]^2+`B'[`j',2]^2*`B'[`l',1]*`B'[`l',2])*`sigmath22')*`l3``j'''*`l3``l''' + +matrix `D22'[`k',3]=tmp1+tmp2+tmp3 +} +if `Q'==1 { +scalar tmp1=`B'[`j',1]*`B'[`l',1]*`l2``j'''*`l2``l'''+(2*`B'[`j',1]*`B'[`l',1]^3*`sigmath11')/2*`l2``j'''*`l4``l''' +scalar tmp2=(2*`B'[`j',1]^3*`B'[`l',1]*`sigmath11')/2*`l4``j'''*`l2``l''' +scalar tmp3=(`B'[`j',1]^2*`B'[`l',1]^2*`sigmath11')*`l3``j'''*`l3``l''' + +matrix `D22'[`k',1]=tmp1+tmp2+tmp3 +} +} + +matrix `D'=(`D11',`D12' \ `D21',`D22') + +/*CALCUL DE LA MATRICE CHSI*/ + +tempname chsi +matrix `chsi'=J(`nbitems'+`carre',1,0) + +forvalue j=1/`nbitems' { +matrix `chsi'[`j',1]=(`s``j'''-`N'*`mu``j''')/`N' +} + + +forvalue k=1/`carre' { +local j=`compocarre'[1,`k'] +local l=`compocarre'[2,`k'] +local tmp=`nbitems'+`k' + +matrix `chsi'[`tmp',1]=(`s``j''``l'''-`s``j'''*`mu``l'''-`s``l'''*`mu``j'''+`N'*`mu``j'''*`mu``l'''-`N'*`sigma``j''``l''')/`N' +} + +/*CALCUL DE L'ETAPE k*/ +tempname betaold +matrix `betaold'=`beta' +matrix `beta'=`betaold'+inv(`D''*inv(`V')*`D')*`D''*inv(`V')*`chsi' + +local l=`nbitems'+1 +local sigmath11=`beta'[`l',1] +local l=`nbitems'+2 +local sigmath22=`beta'[`l',1] +local l=`nbitems'+3 +local sigmath12=`beta'[`l',1] + +tempname epsilon variatold +scalar `variatold'=`variat'[1,1] +matrix `epsilon'=`betaold'-`beta' + +matrix `variat'=(`epsilon''*`epsilon') + +if `variat'[1,1]>`variatold' { +matrix `beta'=`betaold' +local l=`nbitems'+1 +local sigmath11=`beta'[`l',1] +local l=`nbitems'+2 +local sigmath22=`beta'[`l',1] +local l=`nbitems'+3 +local sigmath12=`beta'[`l',1] +local conv=0 +} +else { +local macrovariat=`variat'[1,1] +} + +} + +/*************************CALCUL des STANDARDS ERRORS DES PARAMETRES *********************/ + +if "`var'"==""{ +tempname xicarreA xicarreB xicarreC xicarre +matrix `xicarreA'=J(`nbitems',`nbitems',0) +matrix `xicarreB'=J(`nbitems',`carre',0) +matrix `xicarreC'=J(`carre',`carre',0) +forvalues i=1/`nbitems' { +forvalues j=1/`nbitems' { +matrix `xicarreA'[`i',`j']=`s``i''``j'''-`s``i'''*`mu``j'''-`s``j'''*`mu``i'''+`N'*`mu``i'''*`mu``j''' +} +} + +forvalues i=1/`nbitems' { +forvalues col=1/`carre' { +local j=`compocarre'[1,`col'] +local k=`compocarre'[2,`col'] +matrix `xicarreB'[`i',`col']=`s``i''``j''``k'''-`mu``i'''*`s``j''``k'''-`mu``j'''*`s``i''``k'''-`mu``k'''*`s``i''``j'''+`mu``i'''*`mu``j'''*`s``k'''+`mu``i'''*`mu``k'''*`s``j'''+`mu``j'''*`mu``k'''*`s``i'''-`N'*`mu``i'''*`mu``j'''*`mu``k'''-`sigma``j''``k'''*`s``i'''+`N'*`mu``i'''*`sigma``j''``k''' +} +} + +forvalues row=1/`carre' { +forvalues col=1/`carre' { +local i=`compocarre'[1,`row'] +local j=`compocarre'[2,`row'] +local k=`compocarre'[1,`col'] +local l=`compocarre'[2,`col'] +matrix `xicarreC'[`row',`col']=`s``i''``j''``k''``l'''-`mu``i'''*`s``j''``k''``l'''-`mu``j'''*`s``i''``k''``l'''-`mu``k'''*`s``i''``j''``l'''-`mu``l'''*`s``i''``j''``k'''+`mu``i'''*`mu``j'''*`s``k''``l'''+`mu``i'''*`mu``k'''*`s``j''``l'''+`mu``i'''*`mu``l'''*`s``j''``k'''+`mu``j'''*`mu``k'''*`s``i''``l'''+`mu``j'''*`mu``l'''*`s``i''``k'''+`mu``k'''*`mu``l'''*`s``i''``j'''-`mu``i'''*`mu``j'''*`mu``k'''*`s``l'''-`mu``i'''*`mu``j'''*`mu``l'''*`s``k'''-`mu``i'''*`mu``k'''*`mu``l'''*`s``j'''-`mu``j'''*`mu``k'''*`mu``l'''*`s``i'''-`sigma``i''``j'''*`s``k''``l'''-`sigma``k''``l'''*`s``i''``j'''+`sigma``i''``j'''*`mu``k'''*`s``l'''+`sigma``i''``j'''*`mu``l'''*`s``k'''+`sigma``k''``l'''*`mu``i'''*`s``j'''+`sigma``k''``l'''*`mu``j'''*`s``i'''+`N'*`mu``i'''*`mu``j'''*`mu``k'''*`mu``l'''-`N'*`sigma``i''``j'''*`mu``k'''*`mu``l'''-`N'*`sigma``k''``l'''*`mu``i'''*`mu``j'''+`N'*`sigma``i''``j'''*`sigma``k''``l''' +} +} + + +matrix `xicarre'=(`xicarreA',`xicarreB' \ `xicarreB' ',`xicarreC') + +tempname A1 A2 W +matrix `A1'=`D' '*inv(`V')*`D' +matrix `A2'=`D' '*inv(`V')*`xicarre'*inv(`V')*`D' +matrix `W'=1/`N'^2*inv(`A1')*`A2'*inv(`A1') + +} + +/*****************************DISPLAY THE RESULTS***************************************/ + + +local compteur=`compteur'-1 +di "" +di "" +if `compteur'==0 { +noi di in red _col(8) "The algorithm can not converge" +return scalar error=1 +exit +} +if `variat'[1,1]<=`critconv'&`compteur'>0 { +noi di in green _col(8) "The algorithm converge at the `compteur'th iteration" +} +if `compteur'==`nbit'&`variat'[1,1]>`critconv' { +noi di in green _col(8) "The algorithm is stopped at the `compteur'th iteration" +} +if `conv'==0&`compteur'>0 { +noi di in green _col(8) "The algorithm converge no more after the `compteur'th iteration" +} +di "" +if "`var'"=="" { +noi di in green _col(30) "Parameters" in green _col(43) "Standard errors" +forvalue j=1/`nbitems' { +noi di in green _col(20) "``j'': " in yellow _col(30) %10.6f `beta'[`j',1] in yellow _col(50) %8.6f sqrt(`W'[`j',`j']) +} +di "" +noi di in green _col(20) "var1: " in yellow _col(30) %10.6f `beta'[`nbitems'+1,1] in yellow _col(50) %8.6f sqrt(`W'[`nbitems'+1,`nbitems'+1]) +if `Q'==2 { +noi di in green _col(20) "var2: " in yellow _col(30) %10.6f `beta'[`nbitems'+2,1] in yellow _col(50) %8.6f sqrt(`W'[`nbitems'+2,`nbitems'+2]) +scalar rho=`beta'[`nbitems'+3,1]/sqrt(`beta'[`nbitems'+1,1]*`beta'[`nbitems'+2,1]) +noi di in green _col(20) "covar: " in yellow _col(30) %10.6f `beta'[`nbitems'+3,1] in yellow _col(50) %8.6f sqrt(`W'[`nbitems'+3,`nbitems'+3]) " (rho=" %5.4f rho ")" +} +} +else { +noi di in green _col(30) "Parameters" +forvalue j=1/`nbitems' { +noi di in green _col(20) "``j'': " in yellow _col(30) %10.6f `beta'[`j',1] +} +di "" +noi di in green _col(20) "var1: " in yellow _col(30) %10.6f `beta'[`nbitems'+1,1] +if `Q'==2 { +noi di in green _col(20) "var2: " in yellow _col(30) %10.6f `beta'[`nbitems'+2,1] +scalar rho=`beta'[`nbitems'+3,1]/sqrt(`beta'[`nbitems'+1,1]*`beta'[`nbitems'+2,1]) +noi di in green _col(20) "covar: " in yellow _col(30) %10.6f `beta'[`nbitems'+3,1] +} +} +di "" + + + +if "`ll'"!="" { +if `Q'==1 { +tempname noeuds poids +ghquadm `quad' `noeuds' `poids' +tempvar vrais logvrais +qui gen `vrais'=0 +forvalues u=1/`quad'{ +tempvar vrais`u' +qui gen `vrais`u''=1/sqrt(_pi) +forvalues j=1/`nbitems' { +tempvar Pu`u'j`j' +qui gen `Pu`u'j`j''=exp(`B'[`j',1]*sqrt(2*`beta'[`nbitems'+1,1])*`noeuds'[1,`u']-`beta'[`j',1])/(1+exp(`B'[`j',1]*sqrt(2*`beta'[`nbitems'+1,1])*`noeuds'[1,`u']-`beta'[`j',1])) +qui replace `Pu`u'j`j''=1-`Pu`u'j`j'' if ``j''==0 +qui replace `vrais`u''=`vrais`u''*`Pu`u'j`j'' +} +qui replace `vrais'=`vrais'+`poids'[1,`u']*`vrais`u'' +} +gen `logvrais'=log(`vrais') +qui su `logvrais' +local ll=r(N)*r(mean) +noi di in green _col(20) "ll: " in yellow _col(30) %12.4f `ll' +local AIC=-2*`ll'+2*(`nbitems'+1) +noi di in green _col(20) "AIC: " in yellow _col(30) %12.4f `AIC' +} + +if `Q'==2 { + +tempname noeuds poids +ghquadm `quad' `noeuds' `poids' +tempvar vrais logvrais +qui gen `vrais'=0 +matrix sigma=(`beta'[`nbitems'+1,1],`beta'[`nbitems'+3,1] \ `beta'[`nbitems'+3,1],`beta'[`nbitems'+2,1]) +forvalues u=1/`quad'{ +forvalues v=1/`quad'{ +tempvar vraisu`u'v`v' +qui gen `vraisu`u'v`v''=1/_pi +forvalues j=1/`nbitems' { +tempvar Pu`u'v`v'j`j' +local A1`u'tilde=sqrt(`beta'[`nbitems'+2,1]/(2*det(sigma)))*`noeuds'[1,`u'] +local A2`v'tilde=(`noeuds'[1,`v']-`beta'[`nbitems'+3,1]/sqrt(det(sigma))*`noeuds'[1,`u'])/(2*`beta'[`nbitems'+2,1]) +qui gen `Pu`u'v`v'j`j''=exp(`B'[`j',1]*`A1`u'tilde'+`B'[`j',2]*`A2`v'tilde'-`beta'[`j',1])/(1+exp(`B'[`j',1]*`A1`u'tilde'+`B'[`j',2]*`A2`v'tilde'-`beta'[`j',1])) +qui replace `Pu`u'v`v'j`j''=1-`Pu`u'v`v'j`j'' if ``j''==0 +qui replace `vraisu`u'v`v''=`vraisu`u'v`v''*`Pu`u'v`v'j`j'' +} +qui replace `vrais'=`vrais'+`poids'[1,`u']*`poids'[1,`v']*`vraisu`u'v`v'' +} +} +qui gen `logvrais'=log(`vrais') +qui su `logvrais' +local ll=r(N)*r(mean) +noi di in green _col(20) "ll: " in yellow _col(27) %12.4f `ll' +local AIC=-2*`ll'+2*(`nbitems'+3) +noi di in green _col(20) "AIC: " in yellow _col(27) %12.4f `AIC' +} +} + +if "`var'"=="" { +return matrix W= `W' +} +return matrix beta= `beta' + +if "`ll'"!="" { +return scalar ll= `ll' +return scalar AIC= `AIC' +} + +return scalar J= `nbitems' +return scalar N= `N' + +return scalar error=0 + +restore + + + +end + diff --git a/Modules/ado/personal/g/gengroup.ado b/Modules/ado/personal/g/gengroup.ado new file mode 100644 index 0000000..c4d8e02 --- /dev/null +++ b/Modules/ado/personal/g/gengroup.ado @@ -0,0 +1,158 @@ +*! version 1.3 1 June 2013 +*! Jean-Benoit Hardouin +* +************************************************************************************************************ +* Stata program : genscore +* Generate groups of individals based on the values of an ordinal or continuous variable +* +* Historic +* Version 1 (2007-05-27): Jean-Benoit Hardouin +* Version 1.1 (2007-06-21): Jean-Benoit Hardouin /*Correction of a bug without -if- */ +* Version 1.2 (2009-10-28): Jean-Benoit Hardouin /*-continuous- option*/ +* Version 1.3 (2013-06-01): Jean-Benoit Hardouin /*Correction in presence of missing values*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* EA4275 - SPHERE +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program :http://www.anaqol.org +* +* Copyright 2007, 2009, 2013 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define gengroup ,rclas +version 7.0 +syntax varlist(numeric min=1 max=1) [if/] [in] [, NEWvariable(namelist min=1 max=1) REPlace MINsize(integer 30) DETails CONTinuous] +tempvar sort +qui gen `sort'=_n + +if "`if'"!="" { + local if2="if `if'" + local if3="&(`if')" +} + +marksample touse +if "`newvariable'"=="" { + local newvariable group +} + +capture confirm new variable `newvariable' +if _rc!=0&"`replace'"=="" { + di in red "The variable {hi:`newvariable'} is already defined" + exit 198 +} +else if _rc!=0&"`replace"!="" { + qui drop `newvariable' +} + +if "`continuous'"=="" { + qui gen `newvariable'=`varlist' `if2' `in' + + qui su `newvariable' `if2' `in' + local min=r(min) + local max=r(max) + + local groupmin=`min' + local groupmax=`min'-1 + local numgroup=1 + local recode + local list + + while (`groupmin'<`max'+1) { + local n=0 + while (`n'<`minsize') { + local groupmax=`groupmax'+1 + qui count if `newvariable'>=`groupmin'&`newvariable'<=`groupmax'`if3' `in' + local n=r(N) + if `groupmax'>`max' { + local n=`minsize'+1 + local numgr + } + } + if `groupmax'<`max' { + local list `list' `groupmax' + } + local recode `recode' `groupmin'/`groupmax'=`numgroup' + if "`details'"!="" { + di in gr "Group " in ye `numgroup' in gr ": Values " in ye `groupmin' in gr " to " in ye `groupmax' + } + local groupmin=`groupmax'+1 + local groupmax=`groupmin'-1 + local numgroup=`numgroup'+1 + } + + qui recode `newvariable' `recode' `if2' `in' + qui count if `newvariable'==`numgroup'-1`if3' `in' + local dernier=r(N) + if `dernier'<`minsize' { + qui recode `newvariable' `=`numgroup'-1'=`=`numgroup'-2' `if2' `in' + if "`details'"!="" { + di in gr "The group " in ye `=`numgroup'-1' in gr " is recoded in " in ye `=`numgroup'-2' + } + local list2 + forvalues i=1/`=`numgroup'-3' { + local w:word `i' of `list' + local list2 `list2' `w' + } + local list `list2' + } +} +else { + local list + qui sort `varlist' + qui tempvar sort2 + qui gen `sort2'=_n + qui gen `newvariable'=0 `if2' `in' + qui replace `newvariable'=. if `varlist'==. + qui count if `varlist'!=.`if3' `in' + local nbind=r(N) + local tmpgp=floor(`nbind'/`minsize') + local minsize=floor(`nbind'/`tmpgp') + local nbused=0 + tempvar used + qui gen `used'=0 `if2' `in' + local num=1 + while (`=`nbused'+`minsize''<`nbind'+1) { + qui su `varlist' if `sort2'==`=`nbused'+`minsize''`if3' `in' + local mean=r(mean) + local list `list' `mean' + local mean=round(`mean',0.0000001)+0.0000001 + if "`details'"!="" { + di in gr "The values inferior to " in ye `mean' in gr " are recoded in " in ye `num' + } + qui replace `newvariable'=`num' if `varlist'<=`mean'&`used'==0 + qui replace `used'=1 if `newvariable'!=0&`newvariable'!=. + qui count if `used'==1 + local nbused=`r(N)' + local num=`num'+1 + } + qui replace `newvariable'=`num'-1 if `newvariable'==0 + if "`details'"!="" { + qui su `varlist' + local max=r(max) + if `max'>`mean' { + di in gr "Individuals between " in ye `mean' in gr "and " in ye `max' " are recoded in " in ye `=`num'-1' + } + } + qui sort `sort' +} +return local list `list' +end diff --git a/Modules/ado/personal/g/gengroup.hlp b/Modules/ado/personal/g/gengroup.hlp new file mode 100644 index 0000000..6df3377 --- /dev/null +++ b/Modules/ado/personal/g/gengroup.hlp @@ -0,0 +1,51 @@ +{smcl} +{* 6May2013}{...} +{hline} +help for {hi:gengroup}{right:Jean-benoit Hardouin} +{hline} + +{title:Module to generate group of individuals based on a ordinal or continuous variable} + +{p 8 14 2}{cmd:gengroup} {it:varname} [{cmd:if} {it:exp}] [{cmd:in} {it:range}] [{cmd:,} {cmdab:new:variable}({it:newvarname}) {cmdab:rep:lace} {cmdab:min:size}(#) {cmdab:det:ails} {cmdab:cont:inuous}] + +{title:Description} + +{p 4 8 2}{cmd:gengroup} creates groups of individuals by using the values of an ordinal or continuous variable. +The module creates groups by recoding several adjacent values of the variable, until obtaining groups with more than individuals than the number defined in the {cmd:minsize} option. + + +{title:Options} + +{p 4 8 2}{cmd:newvariable} defines the name of the new variable ({it:group} by default). + +{p 4 8 2}{cmd:replace} replaces the variable defined in the {cmd:newvariable} option if it already exists. + +{p 4 8 2}{cmd:minsize} defines the minimal number of individuals in each group (30 by default). + +{p 4 8 2}{cmd:details} diplays the composition of each group. + +{p 4 8 2}{cmd:continuous} allows handling a continuous variable. + +{title:Examples} + +{p 4 8 2}{inp:. gengroup score} + +{p 4 8 2}{inp:. gengroup score, newvariable(grouptocreate) replace minsize(80)} + +{p 4 8 2}{inp:. gengroup score, details} + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end} +{p 4 8 2}Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences{p_end} +{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end} +{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end} +{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end} +{p 4 8 2}Email: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 4 8 2}Website {browse "http://www.anaqol.org":AnaQol} + +{title:Also see} + +{p 4 13 2}Online: help for {help egen}, {help generate} and {help genscore} if installed.{p_end} + diff --git a/Modules/ado/personal/g/gengutt.ado b/Modules/ado/personal/g/gengutt.ado new file mode 100644 index 0000000..476f5d5 --- /dev/null +++ b/Modules/ado/personal/g/gengutt.ado @@ -0,0 +1,133 @@ +*! Version 1.1 24 March 2015 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : gengutt +* Generation of Guttman's error per individuals +* Release 1.1 : March 24, 2015 /*no required -order- option*/ +* +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* Release 1 : March 20, 2015 /*initial version with only -order- option*/ +* +* News about this program :http://www.anaqol.org +* +* Copyright 2015 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** + +program define gengutt , rclass +syntax varlist(min=2 numeric) [if] , Gen(string) [ Replace Order(string) PAIRWise] /*[,PAIRWise PAIR ppp pmm noADJust GENERror(string) REPlace GRaph MONOtonicity(string) NIRESTscore(string) NIPmatrix(string) HTML(string)]*/ +preserve + +tokenize `varlist' +local nbitems : word count `varlist' +local nbs=0 +forvalues i=1/`nbitems' { + qui su ``i'' + local modamax`i'=r(max) + local nbs=`nbs'+`modamax`i'' + local testmodamax`i'=0 + local ordermax`i'=0 +} +if "`order'"=="" { + tempname mattmp + matrix `mattmp'=J(3,`nbs',0) + local col=1 + forvalues i=1/`nbitems' { + forvalues s=1/`modamax`i'' { + qui count if ``i''>=`s' + matrix `mattmp'[3,`col']=r(N) + matrix `mattmp'[1,`col']=`i' + matrix `mattmp'[2,`col']=`s' + local ++col + } + } + local list + forvalues j=1/`nbs' { + local max=0 + local col=0 + local item=0 + forvalues i=1/`nbs' { + if `mattmp'[3,`i']>`max' { + local max=`mattmp'[3,`i'] + local col=`i' + local item=`mattmp'[1,`i'] + } + } + local list `list' `item' + matrix `mattmp'[3,`col']=0 + } + local order `list' +} +local nbsteps: word count `order' +tempname matorder +matrix `matorder'=J(3,`nbsteps',0) +local defordre=1 +forvalues i=1/`nbsteps' { + local tmp: word `i' of `order' + local ++testmodamax`tmp' + matrix `matorder'[1,`i']=`tmp' + local ordermax`tmp'=`ordermax`tmp''+1 + matrix `matorder'[2,`i']=`ordermax`tmp'' + local i`tmp'_m`ordermax`tmp''=`defordre' + local s`defordre' i`tmp'_m`ordermax`tmp'' + tempname `s`defordre'' + qui gen ``s`defordre'''=``tmp''>=`ordermax`tmp'' + local ++defordre +} +local error=0 +forvalues i=1/`nbitems' { + if `modamax`i''>`testmodamax`i'' { + di in red "The item `i' presents more answer categories than defined in the -order- option " + local error=1 + } +} +if `error'!=0 { + error 198 +} +if "`replace'"!="" { + qui capture drop `gen' +} +qui gen `gen'=0 +forvalues i=1/`nbitems' { + if "`replace'"!="" { + qui capture drop `gen'_``i'' + } + qui gen `gen'_``i''=0 +} +forvalues i=1/`nbsteps' { + forvalues j=`=`i'+1'/`nbsteps' { + qui replace `gen'=`gen'+1 if ``s`i'''<``s`j'''&``s`i'''!=.&``s`j'''!=. + local iti=`matorder'[1,`i'] + local itj=`matorder'[1,`j'] + qui replace `gen'_``iti''=`gen'_``iti''+1 if ``s`i'''<``s`j'''&``s`i'''!=.&``s`j'''!=. + qui replace `gen'_``itj''=`gen'_``itj''+1 if ``s`i'''<``s`j'''&``s`i'''!=.&``s`j'''!=. + } +} +if "`replace'"!="" { + capture drop `gen'_gp +} +egen `gen'_gp=concat(``s1''-``s`nbsteps''') + +capture restore, not +end + diff --git a/Modules/ado/personal/g/genscore.ado b/Modules/ado/personal/g/genscore.ado new file mode 100644 index 0000000..e3164e4 --- /dev/null +++ b/Modules/ado/personal/g/genscore.ado @@ -0,0 +1,86 @@ +*! version 1.4 27december2005 +*! Jean-Benoit Hardouin +* +************************************************************************************************************ +* Stata program : genscore +* Generate scores from a list of variables +* Version 1.4 : December 27, 2005 /*corrects a bug with the mean option*/ +* +* Historic +* Version 1.2 (2005-10-01): Jean-Benoit Hardouin +* Version 1.3 (2005-12-09): Jean-Benoit Hardouin /*centered and standardized options*/ +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@orscentre.org +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2005 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define genscore +version 7.0 +syntax varlist(min=1) [if] [in] [fweight] [, SCore(namelist min=1 max=1) CENTered STAndardized MEan MIssing(string) REPlace] + +marksample touse +if "`score'"=="" { + local score score +} + +local nbitems:word count `varlist' +tokenize `varlist' + +if "`missing'"=="" { + local missing . +} +capture confirm new variable `score' +quietly { + if _rc!=0&"`replace"=="" { + di in red "The variable {hi:`score'} already defined" + exit 198 + } + else if _rc!=0&"`replace"!="" { + drop `score' + } + forvalues i=1/`nbitems' { + tempname var`i' + local sd=1 + local moy=0 + if "`standardized'"!=""|"`centered'"!="" { + su ``i'' [`weight'`exp'] + local moy=r(mean) + local sd=r(sd) + if "`standardized'"=="" { + local sd=1 + } + } + gen `var`i''=(``i''-`moy')/`sd' + } + gen `score'=0 if `touse' + forvalues i=1/`nbitems' { + replace `score'=`score'+`var`i'' if `touse' + replace `score'=. if `touse'&``i''==`missing'&``i''>=. + } + if "`mean'"!="" { + replace `score'=`score'/`nbitems' if `touse' + } +} + +end + diff --git a/Modules/ado/personal/g/genscore.hlp b/Modules/ado/personal/g/genscore.hlp new file mode 100644 index 0000000..182da15 --- /dev/null +++ b/Modules/ado/personal/g/genscore.hlp @@ -0,0 +1,54 @@ +{smcl} +{* 9december2005}{...} +{hline} +help for {hi:genscore}{right:Jean-benoit Hardouin} +{hline} + +{title:Module to generate a score} + +{p 8 14 2}{cmd:genscore} {it:varlist} [{cmd:if} {it:exp}] [{cmd:in} {it:range}] [{it:weights}] [{cmd:,} {cmdab:sc:ore}({it:newvarname}) {cmdab:me:an} {cmdab:cent:ered} {cmdab:sta:ndardized} {cmdab:mi:ssing}(string) {cmdab:rep:lace}] + +{title:Description} + +{p 4 8 2}{cmd:genscore} allows creating a new variable containing the score +computed as the sum (or the mean) of the responses to the variables defined in +{it:varlist}. Variables of {it:varlist} can be centered or standardized. The new +variable will contain a missing value for each individual with at least one +missing values among the variables of {it:varlist}. + +{p 4 8 2}Only {cmd:fweights} are allowed, and the weights have an influence only with +the {cmd:centered} or {cmd:standardized} options. + +{title:Options} + +{p 4 8 2}{cmd:score} defines the name of the new variable ({it:score} by default). + +{p 4 8 2}{cmd:mean} allows obtaining a mean score (the sum of the responses is divided by the number of variables). + +{p 4 8 2}{cmd:centered} computes the scores with centered variables. + +{p 4 8 2}{cmd:standardized} computes the scores with standardized variables. + +{p 4 8 2}{cmd:missing} defines a specific modality of the variables which can be considered as a missing value. + +{p 4 8 2}{cmd:replace} allows replacing the variable defined in the {cmd:score} option if it already exists. + +{title:Examples} + +{p 4 8 2}{cmd:. genscore turn trunk mpg [fweight=w],standardized mean} + +{p 4 8 2}{cmd:. genscore item1-item20, score(totscore) missing(9)} + +{p 4 8 2}{cmd:. genscore var*, score(scorevar) replace} + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, Regional Health Observatory (ORS) - 1, rue Porte +Madeleine - BP 2439 - 45032 Orleans Cedex 1 - France. You can contact the author at +{browse "mailto:jean-benoit.hardouin@orscentre.org":jean-benoit.hardouin@orscentre.org} +and visit the websites {browse "http://anaqol.free.fr":AnaQol} and +{browse "http://freeirt.free.fr":FreeIRT} + +{title:Also see} + +{p 4 8 2}Online: help for {help egen}, {help generate} and {help mvdecode}{p_end} diff --git a/Modules/ado/personal/g/guttmax.ado b/Modules/ado/personal/g/guttmax.ado new file mode 100644 index 0000000..ed75ab6 --- /dev/null +++ b/Modules/ado/personal/g/guttmax.ado @@ -0,0 +1,181 @@ +*! Version 1 19 November 2008 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : guttmax +* Research of the maximal number of Guttman Errors for a specific score +* +* Historic : +* Version 1 (November 19, 2008) [Jean-Benoit Hardouin] +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences (UPRES EA 4275) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* Requiered Stata modules: +* -anaoption- (version 1) +* -traces- (version 3.2) +* -gengroup- (version 1) +* +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2008 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** + +program define guttmax , rclass +version 10 +syntax anything [,Score(real -1) Response(string)] + +if `score'!=-1&"`response'"!="" { + di in red "You cannot defined in the same time the score and the response options"; + error 198 +} + + +local step:word count `anything' +local nbitems=0 +forvalues i=1/`step' { + local step`i':word `i' of `anything' + if `step`i''>`nbitems' { + local nbitems=`step`i'' + } +} +di in green "Number of steps: " in ye `step' +di in green "Number of items: " in ye `nbitems' +tempname mate +matrix `mate'=J(1,`step',0) + + +if `score'!=-1 { + if `score'>`step' { + di in red "You cannot defined a score greater to the maximal possible score"; + error 198 + } + di in green "Score: " in ye `score' + local maxstep=0 + forvalues i=1/`nbitems' { + local nstep`i'=0 + forvalues j=1/`step' { + if `step`j''==`i' { + local ++nstep`i' + if `nstep`i''>`maxstep' { + local maxstep=`nstep`i'' + } + } + } + } + + tempname calcul + matrix `calcul'=J(`nbitems',`maxstep',0) + *matrix list `calcul' + forvalues i=1/`nbitems' { + *di "item `i'" + local n=1 + forvalues j=1/`step' { + if `step`j''==`i' { + forvalues s=`n'/`nstep`i'' { + matrix `calcul'[`i',`s']=`calcul'[`i',`s']+`j' + matrix list `calcul' + } + local ++n + } + } + forvalues j=2/`nstep`i'' { + matrix `calcul'[`i',`j']=`calcul'[`i',`j']/`j' + di "j=`j'" + matrix list `calcul' + } + } + *matrix list `calcul' + + while (`score'>0) { + local max=0 + forvalues i=1/`nbitems' { + local s=min(`score',`nstep`i'') + *di "forvalues j=1/`s' {" + forvalues j=1/`s' { + if `calcul'[`i',`j']>`max' { + local maxi=`i' + local maxj=`j' + local max=`calcul'[`i',`j'] + } + } + } + *di "maxi=`maxi' maxj=`maxj'" + local d=0 + forvalues l=1/`step' { + if `step`l''==`maxi'&`mate'[1,`l']==0&`d'<=`maxj' { + matrix `mate'[1,`l']=1 + local ++d + } + } + forvalues l=1/`maxj' { + matrix `calcul'[`maxi',`l']=0 + } + local score=`score'-`maxj' + *matrix list `calcul' + } +} +else { /*if reponse*/ + local nbrep: word count `response' + if `nbrep'!=`nbitems' { + di in red "You cannot defined a number of responses different of the number of items"; + error 198 + } + + tempname cpt + qui matrix `cpt'=J(`nbitems',1,0) + forvalues i=1/`nbitems' { + local rep`i':word `i' of `response' + qui matrix `cpt'[`i',1]=`rep`i'' + } + forvalues i=1/`step' { + if `cpt'[`step`i'',1]>0 { + qui matrix `mate'[1,`i']=1 + qui matrix `cpt'[`step`i'',1]=`cpt'[`step`i'',1]-1 + } + else { + qui matrix `mate'[1,`i']=0 + } + } +} +local emax=0 + +forvalue i=1/`step' { + forvalues j=`=`i'+1'/`step' { + if `mate'[1,`i']==0&`mate'[1,`j']==1 { + local ++emax + } + } +} + + +if `score'!=-1 { + di in green "Responses profile generating the most important number of Guttman error" + matrix list `mate' ,noheader nonames + di in green "Max number of Guttman errors : " in ye `emax' +} +else { + di in green "Responses profile" + matrix list `mate' ,noheader nonames + di in green "Number of Guttman errors : " in ye `emax' +} +return scalar maxegutt =`emax' +end diff --git a/Modules/ado/personal/g/guttmax1.ado b/Modules/ado/personal/g/guttmax1.ado new file mode 100644 index 0000000..5f8a3a1 --- /dev/null +++ b/Modules/ado/personal/g/guttmax1.ado @@ -0,0 +1,136 @@ +*! Version 1 19 November 2008 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : guttmax +* Research of the maximal number of Guttman Errors for a specific score +* +* Historic : +* Version 1 (November 19, 2008) [Jean-Benoit Hardouin] +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences (UPRES EA 4275) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* Requiered Stata modules: +* -anaoption- (version 1) +* -traces- (version 3.2) +* -gengroup- (version 1) +* +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2008 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** + +program define guttmax1 , rclass +version 10 +syntax anything [,Score(int 0)] + + +local step:word count `anything' +local nbitems=0 +forvalues i=1/`step' { + local step`i':word `i' of `anything' + if `step`i''>`nbitems' { + local nbitems=`step`i'' + } +} +di in green "Number of steps: " in ye `step' +di in green "Number of items: " in ye `nbitems' +di in green "Score: " in ye `score' + +tempname mate +matrix `mate'=J(1,`step',0) + +local maxstep=0 +forvalues i=1/`nbitems' { + local nstep`i'=0 + forvalues j=1/`step' { + if `step`j''==`i' { + local ++nstep`i' + if `nstep`i''>`maxstep' { + local maxstep=`nstep`i'' + } + } + } +} + +tempname calcul +matrix `calcul'=J(`nbitems',`maxstep',0) +*matrix list `calcul' +forvalues i=1/`nbitems' { +*di "item `i'" + local n=1 + forvalues j=1/`step' { + if `step`j''==`i' { + forvalues s=`n'/`nstep`i'' { + matrix `calcul'[`i',`s']=`calcul'[`i',`s']+`j' + } + local ++n + } + } + forvalues j=2/`nstep`i'' { + matrix `calcul'[`i',`j']=`calcul'[`i',`j']/`j' + } +} +*matrix list `calcul' + +while (`score'>0) { + local max=0 + forvalues i=1/`nbitems' { + local s=min(`score',`nstep`i'') + *di "forvalues j=1/`s' {" + forvalues j=1/`s' { + if `calcul'[`i',`j']>`max' { + local maxi=`i' + local maxj=`j' + local max=`calcul'[`i',`j'] + } + } + } + *di "maxi=`maxi' maxj=`maxj'" + local d=0 + forvalues l=1/`step' { + if `step`l''==`maxi'&`mate'[1,`l']==0&`d'<=`maxj' { + matrix `mate'[1,`l']=1 + local ++d + } + } + forvalues l=1/`maxj' { + matrix `calcul'[`maxi',`l']=0 + } + local score=`score'-`maxj' + *matrix list `calcul' +} +local emax=0 +forvalue i=1/`step' { + forvalues j=`=`i'+1'/`step' { + if `mate'[1,`i']==0&`mate'[1,`j']==1 { + local ++emax + } + } +} + + +di in green "Responses profile generating the most important number of Guttman error" +matrix list `mate' ,noheader nonames +di in green "Max number of Guttman errors : " in ye `emax' +return scalar maxegutt =`emax' +end diff --git a/Modules/ado/personal/grec/r.grec b/Modules/ado/personal/grec/r.grec new file mode 100644 index 0000000..6adc2c8 --- /dev/null +++ b/Modules/ado/personal/grec/r.grec @@ -0,0 +1,25 @@ +StataFileTM:00001:01100:GREC: : +00008:00008:00001: +*! classname: twowaygraph_g +*! family: twoway +*! date: 8 Jul 2023 +*! time: 23:18:16 +*! graph_scheme: stcolor +*! naturallywhite: 1 +*! end + +// File created by Graph Editor Recorder. +// Edit only if you know what you are doing. + +.plotregion1.AddTextBox added_text editor -39.54864687610738 -1.346531835179192 +.plotregion1.added_text_new = 1 +.plotregion1.added_text_rec = 2 +.plotregion1.added_text[2].style.editstyle angle(default) size( sztype(relative) val(3.4722) allow_pct(1)) color(black) horizontal(left) vertical(middle) margin( gleft( sztype(relative) val(0) allow_pct(1)) gright( sztype(relative) val(0) allow_pct(1)) gtop( sztype(relative) val(0) allow_pct(1)) gbottom( sztype(relative) val(0) allow_pct(1))) linegap( sztype(relative) val(0) allow_pct(1)) drawbox(no) boxmargin( gleft( sztype(relative) val(0) allow_pct(1)) gright( sztype(relative) val(0) allow_pct(1)) gtop( sztype(relative) val(0) allow_pct(1)) gbottom( sztype(relative) val(0) allow_pct(1))) fillcolor(bluishgray) linestyle( width( sztype(relative) val(.2) allow_pct(1)) color(black) pattern(solid) align(inside)) box_alignment(east) editcopy +.plotregion1.added_text[2].text = {} +.plotregion1.added_text[2].text.Arrpush 1 +// editor text[2] edits + +// editor text[2] edits + + +// diff --git a/Modules/ado/personal/h/hcaccprox.ado b/Modules/ado/personal/h/hcaccprox.ado new file mode 100644 index 0000000..698610b --- /dev/null +++ b/Modules/ado/personal/h/hcaccprox.ado @@ -0,0 +1,501 @@ +************************************************************************************************************ +* hcaccprox: Hierachical Clusters Analysis/CCPROX +* Version 1: May 12, 2004 +* Add-on: Partition version 2 (2004-04-10) +* +* Use the Detect Stata program (http://freeirt.free.fr) +* +* Historic : +* Version 1 [2004-01-18], Jean-Benoit Hardouin +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@neuf.fr +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2004 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + + +program define hcaccprox , rclass +version 8.0 +syntax varlist(min=2 numeric) [,PROX(string) METHod(string) PARTition(numlist) MEASures DETails DETect(integer 0)] + +local nbpart:word count `partition' +tokenize `partition' +forvalues k=1/`nbpart' { + local part`k'=``k'' +} + +local nbitems : word count `varlist' +tokenize `varlist' + +tempname proximity whereitems + +matrix define `proximity'=J(`nbitems',`nbitems',0) +matrix define `whereitems'=J(`=`nbitems'-1',`nbitems',0) + +if `detect'>`nbitems' { + di _col(3) in green "The number of partitions analyzed by the DETECT criterion must be inferior to the number of possible partitions" + di _col(3) in green "This number of possible partitions is `=`nbitems'-1', so your detect option is put to this number" + local detect=`nbitems'-1 + di +} + +if "`prox'"!="a"&"`prox'"!="ad"&"`prox'"!="cor"&"`prox'"!="ccov"&"`prox'"!="ccor"&"`prox'"!="mh" { + if "`prox'"=="" { + local prox="ccov" + } + else { + di in red "You must define an existing measure of proximity (a, ad, cor, ccov, ccor, mh)." + di in red "Please correct your prox option." + exit + } +} + +if "`method'"!="UPGMA"&"`method'"!="single"&"`method'"!="complete" { + if "`method'"=="" { + local method="UPGMA" + } + else { + di in red "Tou must define an existing method to define the proximity between two clusters of items:" + di in red _col(10) "- UPGMA: Unweighted Pair-Group Method of Average" + di in red _col(10) "- single: single linkage" + di in red _col(10) "- complete: complete linkage " + di in red "Please correct your method option" + exit + } +} + +forvalues i=1/`nbitems' { + matrix `whereitems'[1,`i']=`i' + if "`details'"!="" { + di in green _col(3) "The item " _col(13) in yellow "``i''" in green " correspond to the node " in yellow "`i'" + } +} + +tempvar score +egen `score'=rmean(`varlist') +qui replace `score'=`score'*`nbitems' +forvalues k=0/`nbitems' { + qui count if `score'==`k' + local nk`k'=r(N) +} + +qui count +local N=r(N) + +if "`prox'"=="ccov"|"`prox'"=="mh" { + local proxmin=0 +} + +/*************************Measure of proximities*********************************/ + +forvalues i=1/`nbitems' { + forvalues j=`=`i'+1'/`nbitems' { + /***********************************Proximity A**************************/ + if "`prox'"=="a" { + qui count if ``i''==1&``j''==1 + local tmp11=r(N) + qui count if ``i''==0&``j''==0 + local tmp00=r(N) + + matrix `proximity'[`i',`j']=sqrt(1-`tmp11'/(`N'-`tmp00')) + matrix `proximity'[`j',`i']=`proximity'[`i',`j'] + } + + /***********************************Proximity AD*************************/ + if "`prox'"=="ad" { + qui count if ``i''==1&``j''==1 + local tmp11=r(N) + qui count if ``i''==0&``j''==0 + local tmp00=r(N) + + matrix `proximity'[`i',`j']=sqrt(1-(`tmp11'+`tmp00')/`N') + matrix `proximity'[`j',`i']=`proximity'[`i',`j'] + } + + /**********************************Proximity COR*************************/ + if "`prox'"=="cor" { + qui count if ``i''==1&``j''==1 + local tmp11=r(N) + qui count if ``i''==0&``j''==0 + local tmp00=r(N) + qui count if ``i''==1&``j''==0 + local tmp10=r(N) + qui count if ``i''==0&``j''==1 + local tmp01=r(N) + + matrix `proximity'[`i',`j']=sqrt(2*(1-(`tmp11'*`tmp00'-`tmp10'*`tmp01')/(sqrt((`tmp11'+`tmp10')*(`tmp11'+`tmp01')*(`tmp00'+`tmp10')*(`tmp00'+`tmp01'))))) + matrix `proximity'[`j',`i']=`proximity'[`i',`j'] + } + + /***********************************Proximity CCOV**********************/ + if "`prox'"=="ccov" { + local dij=0 + forvalues k=1/`=`nbitems'-1' { + if `nk`k''!=0 { + qui corr ``i'' ``j'',cov + local covi`i'j`j'k`k'=r(cov_12) + local dij=`dij'+`covi`i'j`j'k`k''*`nk`k'' + } + } + + matrix `proximity'[`i',`j']=-`dij'/`N' + matrix `proximity'[`j',`i']=`proximity'[`i',`j'] + if `proxmin'<`dij'/`N' { + local proxmin=`dij'/`N' + } + } + + /***********************************Proximity CCOR**********************/ + + if "`prox'"=="ccor" { + local dij=0 + forvalues k=1/`=`nbitems'-1' { + if `nk`k''!=0 { + qui corr ``i'' ``j'' + local cori`i'j`j'k`k'=r(rho) + local dij=`dij'+`cori`i'j`j'k`k''*`nk`k'' + } + } + + matrix `proximity'[`i',`j']=sqrt(2*(1-`dij'/`N')) + matrix `proximity'[`j',`i']=`proximity'[`i',`j'] + } + + + /***********************************Proximity MH************************/ + + if "`prox'"=="mh" { + local numij=0 + local denom=0 + forvalues k=1/`=`nbitems'-1' { + if `nk`k''!=0 { + qui count if ``i''==1&``j''==1 + local A=r(N) + qui count if ``i''==0&``j''==1 + local B=r(N) + qui count if ``i''==1&``j''==0 + local C=r(N) + qui count if ``i''==0&``j''==0 + local D=r(N) + + if `B'!=0&`C'!=0 { + local numij=`numij'+`A'*`D'/`nk`k'' + local denomij=`denomij'+`B'*`C'/`nk`k'' + } + } + } + + matrix `proximity'[`i',`j']=-log(`numij'/`denomij') + matrix `proximity'[`j',`i']=`proximity'[`i',`j'] + if `proxmin'`currentprox'[`i',`j'] { + local distmin=`currentprox'[`i',`j'] + local cl1=`i' + local cl2=`j' + } + } + } + + local linescl1=`conclinesnodes'[1,`cl1'] + local nbitemscl1=`nodes'[1,`linescl1'] + matrix `nodes'[2,`linescl1']=0 + local linescl2=`conclinesnodes'[1,`cl2'] + local nbitemscl2=`nodes'[1,`linescl2'] + matrix `nodes'[2,`linescl2']=0 + matrix `nodes'[1,`=`nbitems'+`k'']=`nbitemscl1'+`nbitemscl2' + matrix `nodes'[2,`=`nbitems'+`k'']=1 + matrix `nodes'[3,`=`nbitems'+`k'']=`linescl1' + matrix `nodes'[4,`=`nbitems'+`k'']=`linescl2' + if "`details'"!="" { + di in green _col(3) "The nodes" _col(13) in yellow "`linescl1'" _col(17) in green "and" _col(21) in yellow "`linescl2'" _col(25) in green "are been aggregated to form the node " in yellow "`=`nbitems'+`k''" + } + + forvalues i=5/`=`nbitemscl1'+4' { + local item=`nodes'[`i',`linescl1'] + matrix `nodes'[`i',`=`nbitems'+`k'']=`item' + matrix `whereitems'[`k',`item']=`=`nbitems'+`k'' + } + forvalues i=5/`=`nbitemscl2'+4' { + local item=`nodes'[`i',`linescl2'] + matrix `nodes'[`=`i'+`nbitemscl1'',`=`nbitems'+`k'']=`item' + matrix `whereitems'[`k',`item']=`=`nbitems'+`k'' + } + + local tmp=1 + forvalues i=1/`=`nbitems'+`k'' { + if `nodes'[2,`i']==1 { + matrix `mempart'[`tmp',`k']=`i' + local tmp=`tmp'+1 + } + } + + + + if `detect'>=`=`nbitems'-`k'' { + local partdetect + local compteur=1 + local scaledetect + forvalues i=1/`=`nbitems'-`k'' { + local scaledetect`i' + } + forvalues i=1/`=`nbitems'+`k'' { + if `nodes'[2,`i']==1{ + local tmp=`nodes'[1,`i'] + local partdetect `partdetect' `tmp' + local tmp2=4+`tmp' + forvalues j=5/`tmp2' { + local tmp3=`nodes'[`j',`i'] + local scaledetect`compteur' `scaledetect`compteur'' ``tmp3'' + } + local scaledetect `scaledetect' `scaledetect`compteur'' + local compteur=`compteur'+1 + } + } + qui detect `scaledetect' , partition(`partdetect') + local detect`=`nbclusters'-1'=r(DETECT) + local R`=`nbclusters'-1'=r(R) + local Iss`=`nbclusters'-1'=r(Iss) + } + + + matrix drop `currentprox' + matrix define `currentprox'=J(`=`nbclusters'-1',`=`nbclusters'-1',0) + matrix drop `conclinesnodes' + matrix define `conclinesnodes'=J(1,`=`nbclusters'-1',0) + + local tmp=1 + forvalues i=1/`=`nbitems'+`k'' { + if `nodes'[2,`i']==1 { + matrix `conclinesnodes'[1,`tmp']=`i' + local tmp=`tmp'+1 + } + } + forvalues i=1/`=`nbclusters'-1' { + forvalues j=`=`i'+1'/`=`nbclusters'-1' { + if "`method'"=="UPGMA" { + local moy=0 + local linescl1=`conclinesnodes'[1,`i'] + local nbitemscl1=`nodes'[1,`linescl1'] + local linescl2=`conclinesnodes'[1,`j'] + local nbitemscl2=`nodes'[1,`linescl2'] + forvalues l=5/`=`nbitemscl1'+4' { + forvalues m=5/`=`nbitemscl2'+4' { + local item1=`nodes'[`l',`linescl1'] + local item2=`nodes'[`m',`linescl2'] + local tmp=`proximity'[`item1',`item2'] + local moy=`moy'+`tmp' + } + } + matrix `currentprox'[`i',`j']=`moy'/(`nbitemscl1'*`nbitemscl2') + matrix `currentprox'[`j',`i']=`moy'/(`nbitemscl1'*`nbitemscl2') + } + if "`method'"=="single" { + local moy=0 + local linescl1=`conclinesnodes'[1,`i'] + local nbitemscl1=`nodes'[1,`linescl1'] + local linescl2=`conclinesnodes'[1,`j'] + local nbitemscl2=`nodes'[1,`linescl2'] + forvalues l=5/`=`nbitemscl1'+4' { + forvalues m=5/`=`nbitemscl2'+4' { + local item1=`nodes'[`l',`linescl1'] + local item2=`nodes'[`m',`linescl2'] + if `l'==5&`m'==5 { + local distmin=`proximity'[`item1',`item2'] + } + else { + if `distmin'>`proximity'[`item1',`item2'] { + local distmin=`proximity'[`item1',`item2'] + } + } + } + } + matrix `currentprox'[`i',`j']=`distmin' + matrix `currentprox'[`j',`i']=`distmin' + } + if "`method'"=="complete" { + local moy=0 + local linescl1=`conclinesnodes'[1,`i'] + local nbitemscl1=`nodes'[1,`linescl1'] + local linescl2=`conclinesnodes'[1,`j'] + local nbitemscl2=`nodes'[1,`linescl2'] + local distmax=0 + forvalues l=5/`=`nbitemscl1'+4' { + forvalues m=5/`=`nbitemscl2'+4' { + local item1=`nodes'[`l',`linescl1'] + local item2=`nodes'[`m',`linescl2'] + if `distmax'<`proximity'[`item1',`item2'] { + local distmax=`proximity'[`item1',`item2'] + } + } + } + matrix `currentprox'[`i',`j']=`distmax' + matrix `currentprox'[`j',`i']=`distmax' + } + } + } +} + +if `detect'!=0 { + tempname indexes + matrix define `indexes'=J(`detect',4,0) + matrix colnames `indexes'=Clusters DETECT Iss R + di "" + di in green _col(7) "Indexes to test the `detect' latest partitions of the items" + di "" + di in green _col(29) "DETECT" _col(43) "Iss" _col(56) "R" + di _col(5) in green "Only one cluster:" _col(27) in yellow %8.5f `detect1' _col(38) %8.5f `Iss1' _col(49) %8.5f `R1' + matrix `indexes'[1,1]=1 + matrix `indexes'[1,2]=`detect1' + matrix `indexes'[1,3]=`Iss1' + matrix `indexes'[1,4]=`R1' + forvalues k=2/`detect' { + matrix `indexes'[`k',1]=`k' + matrix `indexes'[`k',2]=`detect`k'' + matrix `indexes'[`k',3]=`Iss`k'' + matrix `indexes'[`k',4]=`R`k'' + di _col(5) in green "`k' clusters:" _col(27) in yellow %8.5f `detect`k'' _col(38) %8.5f `Iss`k'' _col(49) %8.5f `R`k'' + } + return matrix indexes=`indexes' +} + + +forvalues k=1/`nbpart' { + di "" + local rowmempart=`nbitems'-`part`k'' + di in green _col(8) "Number of clusters : `part`k''" + tempname affect`part`k'' + matrix define `affect`part`k'''=J(1,`nbitems',0) + forvalues i=1/`part`k'' { + di + di in green _col(12) "Cluster `i':" + local rownodes=`mempart'[`i',`rowmempart'] + local itemsinthecluster=`nodes'[1,`rownodes'] + forvalues j=5/`=4+`itemsinthecluster'' { + local tmp=`nodes'[`j',`rownodes'] + matrix `affect`part`k'''[1,`tmp']=`i' + di in yellow _col(13)"``tmp''" + } + } + matrix colnames `affect`part`k'''=`varlist' + return matrix affect`part`k''=`affect`part`k''' +} + +return matrix mempart `mempart' +return matrix nodes `nodes' +return local nbitems=`nbitems' +return local varlist `varlist' +end + +/********************************************************* +*Partition +*Version 2 (May 10, 2004) +* +*Historic +*Version 1 (January 18, 2004) +***********************************************************/ + +program define partition +version 8.0 +syntax anything(name=partition) + +local nbitems=r(nbitems) +tempname mempart nodes +matrix `mempart'=r(mempart) +matrix `nodes'=r(nodes) +local varlist "`r(varlist)'" + +local nbpart:word count `partition' +tokenize `partition' + +forvalues k=1/`nbpart' { + local part`k'=``k'' +} +tokenize `varlist' + +forvalues k=1/`nbpart' { + di "" + local rowmempart=`nbitems'-`part`k'' + di in green _col(8) "Number of clusters : `part`k''" + forvalues i=1/`part`k'' { + di + di in green _col(12) "Cluster `i':" + local rownodes=`mempart'[`i',`rowmempart'] + local itemsinthecluster=`nodes'[1,`rownodes'] + forvalues j=5/`=4+`itemsinthecluster'' { + local tmp=`nodes'[`j',`rownodes'] + di in yellow _col(13)"``tmp''" + } + } +} +end + diff --git a/Modules/ado/personal/h/hcaccprox.hlp b/Modules/ado/personal/h/hcaccprox.hlp new file mode 100644 index 0000000..2daca3b --- /dev/null +++ b/Modules/ado/personal/h/hcaccprox.hlp @@ -0,0 +1,90 @@ +{smcl} +{* 12may2004}{...} +{hline} +help for {hi:hcaccprox} +{hline} + +{title:Hierarchical Clusters Analysis with conditional proximity measures} + +{p 8 14 2}{cmd:hcaccprox} {it:varlist} +[{cmd:,} {cmdab:prox:(}{it:keyword}{cmd:)} {cmdab:meth:od(}{it:keyword}{cmd:)} {cmdab:part:ition(}{it:numlist}{cmd:)} + {cmdab:meas:ures} {cmdab:det:ails} {cmdab:det:ect:(}{it:#}{cmd:)} ] + +{p 8 14 2}{cmd:partition} {it:numlist} + +{title:Description} + +{p 4 8 2} +{cmd:hcaccprox} realize a Hierarchical Clusters Analysis on dichotomoux items +based on specific measures of proximity as conditional proximity measures. The program +permit to obtain indexes to test the obtained partition (the {help detect} program is +necessary in this case). + +{p 4 8 2} +{cmd:partition} permit, after a {cmd:hcaccprox} step to obtain +the composition of some specific partitions of the items. + +{title:Options} + +{p 4 8 2}{cmd:prox:(}{it:keyword}{cmd:)} define the method to compute the proximity between the items. +Six measures are possible. The three first ones are unconditional measures named {it:a}, {it:ad} and {it:cor}. +The three last ones are conditional measures named {it:ccov}, {it:ccor} and {it:mh}. See Roussos, Stout and Marden (1998) +for details of these six measures. By default, the {it:ccov} option is used. + +{p 4 8 2}{cmd:method} define the method to aggregate two clusters, {it:single} for a single linkage, {it:complete} for a complete +linkage, and {it:UPGMA} for the Unweighted Pair-Group Method of Average. By default, the {it:UPGMA} option is used. + +{p 4 8 2}{cmd:partition(}{it:numlist}{cmd:)} lists the partitions to detail by the program. List like {it:(2 4 6)} or {it:(2(2)6)} +are authorized. + +{p 4 8 2}{cmd:measures} display the used proximity measures between the items. + +{p 4 8 2}{cmd:details} display the results of the algorithm of aggregation. + +{p 4 8 2}{cmd:detect(}{it:#}{cmd:)} specifies for all the partitions with a number of clusters inferior or equal to {it:#} +to compute the DETECT, Iss and R indexes. + +{p 4 8 2}{it:numlist}, for the {cmd:partition} program, define the partitions with the number of clusters indicated in the {it:numlist} +to detail. + +{title:Examples} + +{p 4 8 2}{cmd:. hcaccprox q1-q10} + +{p 4 8 2}{cmd:. partition 3 5 6} + +{p 4 8 2}{cmd:. hcaccprox item1-item9 dotest1-dotest6, detect(6) measures} + +{p 4 8 2}{cmd:. hcaccprox c1 c2 c3 c4 c5 c6 c7, prox(a) method(single)} + +{title:Outputs} + +{p 4 8 2}{cmd:. r(varlist)} is a macro who contain {it:varlist} + +{p 4 8 2}{cmd:. r(nbitems)} is a macro who contain the number of items + +{p 4 8 2}{cmd:. r(nodes)} is a matrix who contain all the informations about all the possible clusters of items. Each column represent a node (the first ones represent each item of {it:varlist}, and the following columns represent each +aggregation of clusters), the first line represent the number of items in each cluster, the third and the fourth lines represent the two cluster who are aggregated to form the new cluster, and the following lines represent the list of +items composing each cluster + +{p 4 8 2}{cmd:. r(mempart)} list the number of cluster composing each possible partition : the last column is the partition in only one cluster, the preceeding column represent the partition in two cluster, and so on + +{p 4 8 2}{cmd:. r(affect#)} is obtained with the {it:partition} option. In this vector, the number of the cluster (of the partition in # clusters) is associated to each item + +{p 4 8 2}{cmd:. r(indexes)} is obtained with the {it:detect} option. This matrix contain the DETECT, Iss and R indexes associated to each partition with a number of clusters inferior to the number defined in the {it:detect} option + + +{title:Reference} + +{p 4 8 2}{cmd:Roussos L. A, Stout W. F. and Marden J. I.}, {it:Using new proximity measures with hierarchical cluster analysis to detect multidimensionality}. Journal of Educational Measurement, {cmd:35}(1), pp 1-30, 1998. + +{p 4 8 2}{cmd:Zhang J. and Stout W. F.}, {it:The theorical DETECT index of dimensionality and its application to approximate simple structure}. Psychometrika, {cmd:64}(2), pp 213-249, 1999. + +{title:Also see} + +{p 4 13 2} help for {help detect} + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, Regional Health Observatory (ORS) - 1, rue Porte Madeleine - BP 2439 - 45032 Orleans Cedex 1 - France. +You can contact the author at {browse "mailto:jean-benoit.hardouin@neuf.fr":jean-benoit.hardouin@neuf.fr} and visit the websites {browse "http://anaqol.free.fr":AnaQol} and {browse "http://freeirt.free.fr":FreeIRT} diff --git a/Modules/ado/personal/h/hcavar.ado b/Modules/ado/personal/h/hcavar.ado new file mode 100644 index 0000000..888ffe8 --- /dev/null +++ b/Modules/ado/personal/h/hcavar.ado @@ -0,0 +1,509 @@ +*! Version 3.6 19 July 2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* hcavar: Hierachical Clusters Analysis (HCA) of variables +* Version 3.5 [2014-05-26], Jean-Benoit Hardouin /* dirsave and filesave options */ +* +* Use the Detect Stata program (ssc install detect) +* +* Historic : +* Under the name of -hcaccprox- +* Version 1 [2004-01-18], Jean-Benoit Hardouin +* Version 2 [2004-05-12], Jean-Benoit Hardouin +* Version 3 [2005-12-31], Jean-Benoit Hardouin +* Version 3.1 [2006-01-15], Jean-Benoit Hardouin /* correction if there is only one individual with a given score*/ +* Version 3.2 [2010-04-15], Jean-Benoit Hardouin /* Possibility to use Polytomous Items with CCOR, CCOV and MH*/ +* Version 3.3 [2014-05-07], Jean-Benoit Hardouin, Bastien Perrot /* HTML option, if option*/ +* Version 3.4 [2014-05-26], Jean-Benoit Hardouin, Bastien Perrot /* DETECT option available for polytomous items */ +* Version 3.5 [2019-07-18], Jean-Benoit Hardouin /* dirsave and filesave options */ +* Version 3.6 [2019-07-19], Jean-Benoit Hardouin /* loevH proximity */ +* +* Jean-benoit Hardouin - University of Nantes - France +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program :http://www.anaqol.org +* +* Copyright 2004-2006, 2010, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + + +program define hcavar, rclass +version 9 +syntax varlist(min=2 numeric) [if] [in] [,PROX(string) METHod(string) PARTition(numlist) MEASures DETect MATrix(string) noDENDROgram HTML(string) DIRSave(string) FILESave] + +tempfile hcaccproxfile +qui save `hcaccproxfile',replace +preserve + +if "`if'"!="" { + qui keep `if' +} + +if "`html'"!="" { + //set scheme sj + //local htmlregion "graphregion(fcolor(white) ifcolor(white))" + di "" + di "
"
+}
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+local type=0
+forvalues i=1/`nbitems' {
+   qui drop if ``i''==.
+   qui inspect ``i''
+   if r(N_unique)>`type'&r(N_unique)!=. {
+      local type=r(N_unique)
+   }
+   else if r(N_unique)>`type'&r(N_unique)==. {
+      local type "100"
+   }
+}
+if `type'==100 {
+   local type ">99"
+}
+
+tempname proximity whereitems
+
+local prox=lower("`prox'")
+local method=lower("`method'")
+matrix define `proximity'=J(`nbitems',`nbitems',0)
+matrix define `whereitems'=J(`=`nbitems'-1',`nbitems',0)
+
+/**************************PROXIMITIES MEASURES DESCRIPTION************************/
+
+if "`matrix'"!="" {
+   local desprox="Defined by the user"
+}
+if "`prox'"=="" {
+   local prox="pearson"
+}
+else if "`prox'"=="a" {
+   local prox="jaccard"
+}
+else if "`prox'"=="ad" {
+   local prox="matching"
+}
+else if "`prox'"=="corr" {
+   local prox="pearson"
+}
+if "`type'">"2"&"`prox'"!="pearson"&"`prox'"!="ccov"&"`prox'"!="ccor"&"`prox'"!="mh"&"`prox'"!="loevh"  {
+   di in red "Only the {hi:pearson}, {hi:ccov}, {hi:ccor}, {hi:mh} and {hi:loevh} measures of proximity are available with ordinal or numerous variables"
+   di in red "Please correct your {hi:prox} option."
+   exit
+}
+
+if "`partition'"==""&"`detect'"!=""  {
+   di in ye "option partition() required"
+   error 198
+}
+local existmeas=0
+foreach i in jaccard matching pearson russel dice ccor mh ccov loevh {
+   if "`prox'"=="`i'" {
+      local existmeas=1
+   }
+}
+if `existmeas'==0 {
+   di in red "You must define an existing measure of proximity (jaccard(a), matching(ad), pearson(cor), russel, dice, ccov, ccor, mh, loevh)."
+   di in red "Please correct your {hi:prox} option."
+   exit
+}
+if "`prox'"=="ccov"|"`prox'"=="mh" {
+   local proxmin=0
+}
+
+if "`prox'"=="matching" {
+   local desprox="Matching"
+}
+else if "`prox'"=="jaccard" {
+   local desprox="Jaccard"
+}
+else if "`prox'"=="russel" {
+   local desprox="Russel"
+}
+else if "`prox'"=="dice" {
+   local desprox="Dice"
+}
+else if "`prox'"=="pearson" {
+   local desprox="Pearson"
+}
+else if "`prox'"=="ccov" {
+   local desprox="Conditional covariances"
+}
+else if "`prox'"=="ccor" {
+   local desprox="Conditional correlations"
+}
+else if "`prox'"=="mh" {
+   local desprox="Mantel Hanzel"
+}
+
+/**************************PROXIMITIES MEASURES DESCRIPTION************************/
+
+if "`method'"=="upgma"|"`method'"=="" {
+   local method="average"
+}
+if "`method'"=="wpgma"|"`method'"=="" {
+   local method="waverage"
+}
+local vermethod=0
+foreach i in average waverage single centroid median complete wards {
+   if "`method'"=="`i'" {
+      local vermethod=1
+   }
+ }
+
+if `vermethod'==0 {
+   di in red "You must define an existing method to define the proximity between two clusters of items:"
+   di in red _col(10) "- single: single linkage"
+   di in red _col(10) "- complete: complete linkage "
+   di in red _col(10) "- average(UPGMA): Unweighted Pair-Group Method of Average"
+   di in red _col(10) "- waverage(WPGMA): Unweighted Pair-Group Method of Average"
+   di in red _col(10) "- wards: Ward's linkage"
+   di in red "Please correct your method option"
+   exit
+}
+if "`method'"=="single"|"`method'"=="singlelinkage" {
+   local method single
+   local desmethod="Single linkage"
+}
+else if "`method'"=="complete"|"`method'"=="completelinkage" {
+   local desmethod="Complete linkage"
+}
+else if "`method'"=="median"|"`method'"=="medianlinkage" {
+   local desmethod="Median linkage (no dendrogram)"
+}
+else if "`method'"=="centroid"|"`method'"=="centroidlinkage" {
+   local desmethod="Centroid linkage (no dendrogram)"
+}
+else if "`method'"=="average"|"`method'"=="averagelinkage" {
+   local desmethod="Unweighted Pair-Group Method of Average"
+}
+else if "`method'"=="waverage"|"`method'"=="waveragelinkage" {
+   local desmethod="Weighted Pair-Group Method of Average"
+}
+else if "`method'"=="wards"|"`method'"=="wardslinkage" {
+   local desmethod="Ward's linkage"
+}
+
+forvalues i=1/`nbitems' {
+	matrix `whereitems'[1,`i']=`i'
+}
+
+tempvar score
+genscore `varlist',score(`score')
+qui su `score'
+local maxscore=r(max)
+forvalues k=0/`maxscore' {
+	qui count if `score'==`k'
+	local nk`k'=r(N)
+}
+
+qui count
+local N=r(N)
+
+
+di in green "{hline 80}"
+di in green "Number of individuals with none missing values: " in ye `N'
+di in green "Maximal number of modalities for a variable: " in ye "`type'"
+di in green "Proximity measures: " in ye "`desprox'"
+di in green "Method to aggregate clusters: " in ye "`desmethod'"
+di in green "{hline 80}"
+di
+di
+
+
+/*************************Measure of proximities*********************************/
+if "`matrix'"=="" {
+	if "`prox'"=="loevh" {
+		qui loevh `varlist', pairw pair 
+		matrix `proximity'=r(loevHjk) 
+	}
+
+    forvalues i=1/`nbitems' {
+		forvalues j=`=`i'+1'/`nbitems' {
+			/***********************************Proximity AD*************************/
+			if "`prox'"=="matching" {  /*ad*/
+				qui count if ``i''==1&``j''==1
+				local tmp11=r(N)
+				qui count if ``i''==0&``j''==0
+				local tmp00=r(N)
+
+				matrix `proximity'[`i',`j']=sqrt(1-(`tmp11'+`tmp00')/`N')
+				matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+			}
+
+			/***********************************Proximity A**************************/
+			else if "`prox'"=="jaccard" {   /*a*/
+				qui count if ``i''==1&``j''==1
+				local tmp11=r(N)
+				qui count if ``i''==0&``j''==0
+				local tmp00=r(N)
+
+				matrix `proximity'[`i',`j']=sqrt(1-`tmp11'/(`N'-`tmp00'))
+				matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+			}
+
+			/***********************************Proximity Russel**************************/
+			else if "`prox'"=="russel" {
+				qui count if ``i''==1&``j''==1
+				local tmp11=r(N)
+
+				matrix `proximity'[`i',`j']=sqrt(1-`tmp11'/`N')
+				matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+			}
+
+			/***********************************Proximity A**************************/
+			else if "`prox'"=="dice" {
+				qui count if ``i''==1&``j''==1
+				local tmp11=r(N)
+				qui count if ``i''==0&``j''==0
+				local tmp00=r(N)
+
+				matrix `proximity'[`i',`j']=sqrt(1-2*`tmp11'/(`N'+`tmp11'-`tmp00'))
+				matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+			}
+
+			/**********************************Proximity COR*************************/
+					else if "`prox'"=="pearson" {   /*corr*/
+				qui corr ``i'' ``j''
+				matrix `proximity'[`i',`j']=sqrt(2*(1-r(rho)))
+				matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+			}
+
+			/***********************************Proximity CCOV**********************/
+			else if "`prox'"=="ccov" {
+				local dij=0
+				local Ntemp=`N'
+				forvalues k=1/`=`maxscore'-1' {
+					if `nk`k''!=0 {
+					   if `nk`k''>1 {
+						  qui corr ``i'' ``j'' if `score'==`k',cov
+										  local covi`i'j`j'k`k'=r(cov_12)
+					   }
+					   else if `nk`k''==1 {
+						  local Ntemp=`Ntemp'-1
+										  local covi`i'j`j'k`k'=0
+									   }
+					   else {
+										  local covi`i'j`j'k`k'=0
+					   }
+					   local dij=`dij'+`covi`i'j`j'k`k''*`nk`k''
+					}
+				}
+
+				matrix `proximity'[`i',`j']=-`dij'/`Ntemp'
+				matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+				if `proxmin'<`dij'/`Ntemp' {
+					local proxmin=`dij'/`Ntemp'
+				}
+			}
+
+			/***********************************Proximity CCOR**********************/
+
+			else if "`prox'"=="ccor" {
+				local dij=0
+				local nnull=0
+				local Ntemp=`N'
+				forvalues k=1/`=`maxscore'-1' {
+					if `nk`k''!=0 {
+					   if `nk`k''>1 {
+										  qui corr ``i'' ``j''  if `score'==`k'
+						  local cori`i'j`j'k`k'=r(rho)
+								   }
+								   else if `nk`k''==1 {
+										  local Ntemp=`Ntemp'-1
+							  local cori`i'j`j'k`k'=0
+								   }
+								   else {
+							  local cori`i'j`j'k`k'=0
+								   }
+					   if `cori`i'j`j'k`k''!=. {
+						local dij=`dij'+`cori`i'j`j'k`k''*`nk`k''
+					   }
+					   else if `cori`i'j`j'k`k''==. {
+						  local nnull=`nnull'+`nk`k''
+									   }
+					}
+				}
+
+				matrix `proximity'[`i',`j']=sqrt(2*(1-`dij'/(`Ntemp'-`nnull')))
+				matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+			}
+
+
+			/***********************************Proximity MH************************/
+
+			else if "`prox'"=="mh" {
+				local numij=0
+				local denom=0
+				forvalues k=1/`=`maxscore'-1' {
+					if `nk`k''!=0 {
+						qui count if ``i''==1&``j''==1&`score'==`k'
+						local A=r(N)
+						qui count if ``i''==0&``j''==1&`score'==`k'
+						local B=r(N)
+						qui count if ``i''==1&``j''==0&`score'==`k'
+						local C=r(N)
+						qui count if ``i''==0&``j''==0&`score'==`k'
+						local D=r(N)
+						local numij=`numij'+`A'*`D'/`nk`k''
+						local denomij=`denomij'+`B'*`C'/`nk`k''
+					}
+				}
+
+				matrix `proximity'[`i',`j']=-log(`numij'/`denomij')
+				matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+				if `proxmin'"
+		di " _char(34) "
+	}
+	else {
+	   if "`filesave'"!="" {
+	      qui local saving "saving(`dirsave'//dendrogram,replace) nodraw"
+	   }
+	   else {
+		  qui local saving	
+	   }
+	   qui cluster dendro ,labels(name) hor ylabel(,angle(0)) title("Hierarchical Cluster Analysis on variables") subtitle("`desmethod'") xtitle("`desprox' proximities") `saving'
+	}
+}
+
+if "`partition'"!="" {
+   foreach i of numlist `partition' {
+      qui cluster gen cluster`i'=group(`i')
+   }
+   tempname clusters
+   mkmat cluster* ,mat(`clusters')
+   matrix rownames `clusters'=`varlist'
+   local compteur=0
+   foreach i of numlist `partition' {
+      local ++compteur
+      di
+      di in green "{hline 30}"
+      di in green "Partition in `i' cluster(s)"
+      di in green "{hline 30}"
+      di
+      forvalues j=1/`i' {
+         local cluster`i'_`j'
+         local nbi`i'_`j'=0
+         forvalues k=1/`nbitems' {
+            if `clusters'[`k',`compteur']==`j' {
+               local cluster`i'_`j' `cluster`i'_`j'' ``k''
+               local ++nbi`i'_`j'
+            }
+         }
+         di in green "Cluster `j': " in ye "`cluster`i'_`j''"
+      }
+   }
+   return matrix clusters=`clusters'
+}
+
+/**********************DETECT OPTION **************************************************/
+
+use `hcaccproxfile',clear
+if "`detect'"!=""&"`partition'"!="" {
+        foreach i of numlist `partition' {
+           local liste
+           local part
+           forvalues j=1/`i' {
+              local liste "`liste' `cluster`i'_`j''"
+              local part "`part' `nbi`i'_`j''"
+           }
+           qui detect `liste',part(`part')
+           local detect`i'=r(DETECT)
+           local Iss`i'=r(Iss)
+           local R`i'=r(R)
+        }
+        tempname indexes
+        matrix define `indexes'=J(`compteur',4,0)
+        matrix colnames `indexes'=Clusters DETECT Iss R
+	di ""
+	di in green "{hline 50}"
+	di in green "Indexes to compare the partitions of the items"
+	di in green "{hline 50}"
+	di ""
+	di in green _col(29) "DETECT" _col(43) "Iss" _col(56) "R"
+	local compteur=0
+        foreach k of numlist `partition' {
+                local ++compteur
+	        matrix  `indexes'[`compteur',1]=`k'
+	        matrix  `indexes'[`compteur',2]=`detect`k''
+	        matrix  `indexes'[`compteur',3]=`Iss`k''
+	        matrix  `indexes'[`compteur',4]=`R`k''
+		di  _col(5) in green "`k' cluster(s):" _col(27) in yellow %8.5f `detect`k'' _col(38) %8.5f  `Iss`k'' _col(49) %8.5f `R`k''
+	}
+        return matrix indexes=`indexes'
+}
+return local nbvar=`nbitems'
+return matrix measures=`proximity'
+restore, not
+*use `hcaccproxfile',clear
+
+end
diff --git a/Modules/ado/personal/h/hcavar.hlp b/Modules/ado/personal/h/hcavar.hlp
new file mode 100644
index 0000000..dec6ad1
--- /dev/null
+++ b/Modules/ado/personal/h/hcavar.hlp
@@ -0,0 +1,100 @@
+{smcl}
+{* 6december2012}{...}
+{hline}
+help for {hi:hcavar}{right:Jean-Benoit Hardouin}
+{hline}
+
+{title:Hierarchical Clusters Analysis of variables}
+
+{p 8 14 2}{cmd:hcavar} {it:varlist}
+[{cmd:,} {cmdab:prox}{it:(keyword)} {cmdab:mat:rix}{it:(matrix)} {cmdab:meth:od}{it:(keyword)}
+{cmdab:part:ition}{it:(numlist)} {cmdab:meas:ures} {cmdab:det:ect} {cmdab:nodendro:gram}]
+
+{title:Description}
+
+{p 4 8 2}
+{cmd:hcavar} is the new name of the old {cmd:hcaccprox} module.
+
+{p 4 8 2}
+{cmd:hcavar} realizes a Hierarchical Clusters Analysis on variables.
+The variables can be numerous, ordinal or binary. The distances (dissimilarity
+measures for binary variables) between two variables are computed as the squared
+root of 2 times one minus the Pearson correlation. For binary variables, it is 
+possible to use other similarity coefficients as Matching, Jaccard, Russel or Dice
+(See {help measure option} for more details). The distance matrix is computed as 
+the squared root of one minus the value of these coefficients.
+In the field of Item Response Theory, it is possible to define conditional measures 
+to the score as defined by Roussos, Stout and Marden (1998): conditional correlations,
+conditional covariance, or Mantel-Haenszel measures of similarity. In the same field,
+it is possible to compute, for a set of obtained partition of the items, the DETECT,
+Iss and R indexes defined by Zhang and Stout (1999).
+
+{title:Options}
+
+{p 4 8 2}{cmd:prox} defines the proximity measures to use : {it:jaccard} 
+(alias {it:a}), {it: russel}, {it:dice}, {it:matching} (alias {it:ad}), {it:pearson}
+(alias {it:corr}), conditional covariance ({it:ccov}), conditional correlation
+({it:ccor}), or Mantel Haenszel ({it:mh}). By default, this option is put to
+{it:pearson}. {it:pearson} is the only one option available with ordinal or numerous 
+variables.
+
+{p 4 8 2}{cmd:matrix} allows using a matrix as distance matrix.
+
+{p 4 8 2}{cmd:method} defines the method to aggregate two clusters. See {help cluster}
+for more details about these methods. The complete name of the method 
+must be indicated (with or without "linkage"), none abbreviation is allowed. 
+{it:waveragelinkage} is used by default.
+
+{p 4 8 2}{cmd:partition} lists the partitions of variables to detail by
+the program.
+
+{p 4 8 2}{cmd:measures} displays the used proximity measures matrix between
+the variables.
+
+{p 4 8 2}{cmd:detect} computes the DETECT, Iss and R indexes
+for the partitions indicated in the {cmd:partitions} option.
+
+{p 4 8 2}{cmdnodendrogram} enables the displaying of th dendrogram.
+
+{title:Examples}
+
+{p 4 8 2}{cmd:. hcavar var1-var10} /*displays only the dendrogram*/
+
+{p 4 8 2}{cmd:. hcavar var*, partition(1/6) measures method(single)} /*Single linkage, details of 6 partitions*/
+
+{p 4 8 2}{cmd:. hcavar itemA1-itemA7 itemB1-itemB7, prox(ccor) method(single) detect part(1/4)} /*details of 4 partitions, conditional correlations*/
+
+{title:Outputs}
+
+{p 4 8 2}{cmd:. r(nbvar)} contains the number of variables
+
+{p 4 8 2}{cmd:. r(measures)} is the distances measures matrix between the variables
+
+{p 4 8 2}{cmd:. r(clusters)} is a matrix obtained with the {cmd:partition} option
+containing the composition of the partitions defined with this option.
+
+{p 4 8 2}{cmd:. r(indexes)} is obtained with the {cmd:detect} option.
+This matrix contain the DETECT, Iss and R indexes associated to each partition 
+defined with the {cmd:partition} option.
+
+
+{title:Reference}
+
+{p 4 8 2}{cmd:Roussos L. A, Stout W. F. and Marden J. I.}, {it:Using new proximity measures with hierarchical cluster analysis to detect multidimensionality}. Journal of Educational Measurement, {cmd:35}(1), pp 1-30, 1998.
+
+{p 4 8 2}{cmd:Zhang J. and Stout W. F.}, {it:The theorical DETECT index of dimensionality and its application to approximate simple structure}. Psychometrika, {cmd:64}(2), pp 213-249, 1999.
+
+{title:Also see}
+
+{p 4 13 2} help for {help cluster}, help for {help detect} (if installed)
+
+{title:Author}
+
+{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
+{p 4 8 2}EA 4275 SPHERE "Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences"{p_end}
+{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end}
+{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end}
+{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end}
+{p 4 8 2}Email:
+{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end}
+{p 4 8 2}Website {browse "http://www.anaqol.org":AnaQol}
diff --git a/Modules/ado/personal/h/hcavar3.2.ado b/Modules/ado/personal/h/hcavar3.2.ado
new file mode 100644
index 0000000..2c7078d
--- /dev/null
+++ b/Modules/ado/personal/h/hcavar3.2.ado
@@ -0,0 +1,464 @@
+*! Version 3.2 15 April 2010
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* hcavar: Hierachical Clusters Analysis (HCA) of variables
+* Version 3.2: April 15, 2010  /* Possibility to use Polytomous Items with CCOR, CCOV and MH*/
+*
+* Use the Detect Stata program (ssc install detect)
+*
+* Historic :
+* Under the name of -hcaccprox-
+* Version 1 [2004-01-18], Jean-Benoit Hardouin
+* Version 2 [2004-05-12], Jean-Benoit Hardouin
+* Version 3 [2005-12-31], Jean-Benoit Hardouin
+* Version 3.1 [2006-01-15], Jean-Benoit Hardouin  /* correction if there is only one individual with a given score*/
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program :http://www.anaqol.org
+*
+* Copyright 2004-2006, 2010 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+************************************************************************************************************
+
+
+program define hcavar , rclass
+version 9
+syntax varlist(min=2 numeric) [,PROX(string) METHod(string) PARTition(numlist) MEASures  DETect MATrix(string) noDENDROgram]
+
+tempfile hcaccproxfile
+qui save `hcaccproxfile',replace
+preserve
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+local type=0
+forvalues i=1/`nbitems' {
+   qui drop if ``i''==.
+   qui inspect ``i''
+   if r(N_unique)>`type'&r(N_unique)!=. {
+      local type=r(N_unique)
+   }
+   else if r(N_unique)>`type'&r(N_unique)==. {
+      local type "100"
+   }
+}
+if `type'==100 {
+   local type ">99"
+}
+
+tempname proximity whereitems
+
+local prox=lower("`prox'")
+local method=lower("`method'")
+matrix define `proximity'=J(`nbitems',`nbitems',0)
+matrix define `whereitems'=J(`=`nbitems'-1',`nbitems',0)
+
+/**************************PROXIMITIES MEASURES DESCRIPTION************************/
+
+if "`matrix'"!="" {
+   local desprox="Defined by the user"
+}
+if "`prox'"=="" {
+   local prox="pearson"
+}
+else if "`prox'"=="a" {
+   local prox="jaccard"
+}
+else if "`prox'"=="ad" {
+   local prox="matching"
+}
+else if "`prox'"=="corr" {
+   local prox="pearson"
+}
+if "`type'">"2"&"`prox'"!="pearson"&"`prox'"!="ccov"&"`prox'"!="ccor"&"`prox'"!="mh"  {
+   di in red "Only the {hi:pearson}, {hi:ccov} and {hi:ccor} measures of proximity are available with ordinal or numerous variables"
+   di in red "Please correct your {hi:prox} option."
+   exit
+}
+if "`type'">"2"&"`detect'"!=""  {
+   di in ye "The {hi:detect} option is available only with binary variables. This option is disabled."
+   local detect
+   di
+}
+local existmeas=0
+foreach i in jaccard matching pearson russel dice ccor mh ccov {
+   if "`prox'"=="`i'" {
+      local existmeas=1
+   }
+}
+if `existmeas'==0 {
+   di in red "You must define an existing measure of proximity (jaccard(a), matching(ad), pearson(cor), russel, dice, ccov, ccor, mh)."
+   di in red "Please correct your {hi:prox} option."
+   exit
+}
+if "`prox'"=="ccov"|"`prox'"=="mh" {
+   local proxmin=0
+}
+
+if "`prox'"=="matching" {
+   local desprox="Matching"
+}
+else if "`prox'"=="jaccard" {
+   local desprox="Jaccard"
+}
+else if "`prox'"=="russel" {
+   local desprox="Russel"
+}
+else if "`prox'"=="dice" {
+   local desprox="Dice"
+}
+else if "`prox'"=="pearson" {
+   local desprox="Pearson"
+}
+else if "`prox'"=="ccov" {
+   local desprox="Conditional covariances"
+}
+else if "`prox'"=="ccor" {
+   local desprox="Conditional correlations"
+}
+else if "`prox'"=="mh" {
+   local desprox="Mantel Hanzel"
+}
+
+/**************************PROXIMITIES MEASURES DESCRIPTION************************/
+
+if "`method'"=="upgma"|"`method'"=="" {
+   local method="average"
+}
+if "`method'"=="wpgma"|"`method'"=="" {
+   local method="waverage"
+}
+local vermethod=0
+foreach i in average waverage single centroid median complete wards {
+   if "`method'"=="`i'" {
+      local vermethod=1
+   }
+ }
+
+if `vermethod'==0 {
+   di in red "You must define an existing method to define the proximity between two clusters of items:"
+   di in red _col(10) "- single: single linkage"
+   di in red _col(10) "- complete: complete linkage "
+   di in red _col(10) "- average(UPGMA): Unweighted Pair-Group Method of Average"
+   di in red _col(10) "- waverage(WPGMA): Unweighted Pair-Group Method of Average"
+   di in red _col(10) "- wards: Ward's linkage"
+   di in red "Please correct your method option"
+   exit
+}
+if "`method'"=="single"|"`method'"=="singlelinkage" {
+   local method single
+   local desmethod="Single linkage"
+}
+else if "`method'"=="complete"|"`method'"=="completelinkage" {
+   local desmethod="Complete linkage"
+}
+else if "`method'"=="median"|"`method'"=="medianlinkage" {
+   local desmethod="Median linkage (no dendrogram)"
+}
+else if "`method'"=="centroid"|"`method'"=="centroidlinkage" {
+   local desmethod="Centroid linkage (no dendrogram)"
+}
+else if "`method'"=="average"|"`method'"=="averagelinkage" {
+   local desmethod="Unweighted Pair-Group Method of Average"
+}
+else if "`method'"=="waverage"|"`method'"=="waveragelinkage" {
+   local desmethod="Weighted Pair-Group Method of Average"
+}
+else if "`method'"=="wards"|"`method'"=="wardslinkage" {
+   local desmethod="Ward's linkage"
+}
+
+forvalues i=1/`nbitems' {
+	matrix `whereitems'[1,`i']=`i'
+}
+
+tempvar score
+genscore `varlist',score(`score')
+qui su `score'
+local maxscore=r(max)
+forvalues k=0/`maxscore' {
+	qui count if `score'==`k'
+	local nk`k'=r(N)
+}
+
+qui count
+local N=r(N)
+
+
+di in green "{hline 80}"
+di in green "Number of individuals with none missing values: " in ye `N'
+di in green "Maximal number of modalities for a variable: " in ye "`type'"
+di in green "Proximity measures: " in ye "`desprox'"
+di in green "Method to aggregate clusters: " in ye "`desmethod'"
+di in green "{hline 80}"
+di
+di
+
+/*************************Measure of proximities*********************************/
+if "`matrix'"=="" {
+   forvalues i=1/`nbitems' {
+	forvalues j=`=`i'+1'/`nbitems' {
+		/***********************************Proximity AD*************************/
+		if "`prox'"=="matching" {  /*ad*/
+			qui count if ``i''==1&``j''==1
+			local tmp11=r(N)
+			qui count if ``i''==0&``j''==0
+			local tmp00=r(N)
+
+			matrix `proximity'[`i',`j']=sqrt(1-(`tmp11'+`tmp00')/`N')
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/***********************************Proximity A**************************/
+		else if "`prox'"=="jaccard" {   /*a*/
+			qui count if ``i''==1&``j''==1
+			local tmp11=r(N)
+			qui count if ``i''==0&``j''==0
+			local tmp00=r(N)
+
+			matrix `proximity'[`i',`j']=sqrt(1-`tmp11'/(`N'-`tmp00'))
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/***********************************Proximity Russel**************************/
+		else if "`prox'"=="russel" {
+			qui count if ``i''==1&``j''==1
+			local tmp11=r(N)
+
+			matrix `proximity'[`i',`j']=sqrt(1-`tmp11'/`N')
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/***********************************Proximity A**************************/
+		else if "`prox'"=="dice" {
+			qui count if ``i''==1&``j''==1
+			local tmp11=r(N)
+			qui count if ``i''==0&``j''==0
+			local tmp00=r(N)
+
+			matrix `proximity'[`i',`j']=sqrt(1-2*`tmp11'/(`N'+`tmp11'-`tmp00'))
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/**********************************Proximity COR*************************/
+                else if "`prox'"=="pearson" {   /*corr*/
+			qui corr ``i'' ``j''
+			matrix `proximity'[`i',`j']=sqrt(2*(1-r(rho)))
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/***********************************Proximity CCOV**********************/
+		else if "`prox'"=="ccov" {
+			local dij=0
+			local Ntemp=`N'
+			forvalues k=1/`=`maxscore'-1' {
+				if `nk`k''!=0 {
+				   if `nk`k''>1 {
+				      qui corr ``i'' ``j'' if `score'==`k',cov
+                                      local covi`i'j`j'k`k'=r(cov_12)
+				   }
+				   else if `nk`k''==1 {
+				      local Ntemp=`Ntemp'-1
+                                      local covi`i'j`j'k`k'=0
+                                   }
+				   else {
+                                      local covi`i'j`j'k`k'=0
+				   }
+				   local dij=`dij'+`covi`i'j`j'k`k''*`nk`k''
+				}
+			}
+
+			matrix `proximity'[`i',`j']=-`dij'/`Ntemp'
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+			if `proxmin'<`dij'/`Ntemp' {
+				local proxmin=`dij'/`Ntemp'
+			}
+		}
+
+		/***********************************Proximity CCOR**********************/
+
+		else if "`prox'"=="ccor" {
+			local dij=0
+			local nnull=0
+			local Ntemp=`N'
+			forvalues k=1/`=`maxscore'-1' {
+				if `nk`k''!=0 {
+				   if `nk`k''>1 {
+                                      qui corr ``i'' ``j''  if `score'==`k'
+				      local cori`i'j`j'k`k'=r(rho)
+	                           }
+	                           else if `nk`k''==1 {
+                                      local Ntemp=`Ntemp'-1
+      				      local cori`i'j`j'k`k'=0
+	                           }
+	                           else {
+      				      local cori`i'j`j'k`k'=0
+	                           }
+				   if `cori`i'j`j'k`k''!=. {
+					local dij=`dij'+`cori`i'j`j'k`k''*`nk`k''
+				   }
+				   else if `cori`i'j`j'k`k''==. {
+				      local nnull=`nnull'+`nk`k''
+                                   }
+				}
+			}
+
+			matrix `proximity'[`i',`j']=sqrt(2*(1-`dij'/(`Ntemp'-`nnull')))
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+
+		/***********************************Proximity MH************************/
+
+		else if "`prox'"=="mh" {
+			local numij=0
+			local denom=0
+			forvalues k=1/`=`maxscore'-1' {
+				if `nk`k''!=0 {
+					qui count if ``i''==1&``j''==1&`score'==`k'
+					local A=r(N)
+					qui count if ``i''==0&``j''==1&`score'==`k'
+					local B=r(N)
+					qui count if ``i''==1&``j''==0&`score'==`k'
+					local C=r(N)
+					qui count if ``i''==0&``j''==0&`score'==`k'
+					local D=r(N)
+					local numij=`numij'+`A'*`D'/`nk`k''
+					local denomij=`denomij'+`B'*`C'/`nk`k''
+				}
+			}
+
+			matrix `proximity'[`i',`j']=-log(`numij'/`denomij')
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+			if `proxmin'"
+   di "
"
+}
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+local type=0
+forvalues i=1/`nbitems' {
+   qui drop if ``i''==.
+   qui inspect ``i''
+   if r(N_unique)>`type'&r(N_unique)!=. {
+      local type=r(N_unique)
+   }
+   else if r(N_unique)>`type'&r(N_unique)==. {
+      local type "100"
+   }
+}
+if `type'==100 {
+   local type ">99"
+}
+
+tempname proximity whereitems
+
+local prox=lower("`prox'")
+local method=lower("`method'")
+matrix define `proximity'=J(`nbitems',`nbitems',0)
+matrix define `whereitems'=J(`=`nbitems'-1',`nbitems',0)
+
+/**************************PROXIMITIES MEASURES DESCRIPTION************************/
+
+if "`matrix'"!="" {
+   local desprox="Defined by the user"
+}
+if "`prox'"=="" {
+   local prox="pearson"
+}
+else if "`prox'"=="a" {
+   local prox="jaccard"
+}
+else if "`prox'"=="ad" {
+   local prox="matching"
+}
+else if "`prox'"=="corr" {
+   local prox="pearson"
+}
+if "`type'">"2"&"`prox'"!="pearson"&"`prox'"!="ccov"&"`prox'"!="ccor"&"`prox'"!="mh"  {
+   di in red "Only the {hi:pearson}, {hi:ccov} and {hi:ccor} measures of proximity are available with ordinal or numerous variables"
+   di in red "Please correct your {hi:prox} option."
+   exit
+}
+if "`type'">"2"&"`detect'"!=""  {
+   di in ye "The {hi:detect} option is available only with binary variables. This option is disabled."
+   local detect
+   di
+}
+local existmeas=0
+foreach i in jaccard matching pearson russel dice ccor mh ccov {
+   if "`prox'"=="`i'" {
+      local existmeas=1
+   }
+}
+if `existmeas'==0 {
+   di in red "You must define an existing measure of proximity (jaccard(a), matching(ad), pearson(cor), russel, dice, ccov, ccor, mh)."
+   di in red "Please correct your {hi:prox} option."
+   exit
+}
+if "`prox'"=="ccov"|"`prox'"=="mh" {
+   local proxmin=0
+}
+
+if "`prox'"=="matching" {
+   local desprox="Matching"
+}
+else if "`prox'"=="jaccard" {
+   local desprox="Jaccard"
+}
+else if "`prox'"=="russel" {
+   local desprox="Russel"
+}
+else if "`prox'"=="dice" {
+   local desprox="Dice"
+}
+else if "`prox'"=="pearson" {
+   local desprox="Pearson"
+}
+else if "`prox'"=="ccov" {
+   local desprox="Conditional covariances"
+}
+else if "`prox'"=="ccor" {
+   local desprox="Conditional correlations"
+}
+else if "`prox'"=="mh" {
+   local desprox="Mantel Hanzel"
+}
+
+/**************************PROXIMITIES MEASURES DESCRIPTION************************/
+
+if "`method'"=="upgma"|"`method'"=="" {
+   local method="average"
+}
+if "`method'"=="wpgma"|"`method'"=="" {
+   local method="waverage"
+}
+local vermethod=0
+foreach i in average waverage single centroid median complete wards {
+   if "`method'"=="`i'" {
+      local vermethod=1
+   }
+ }
+
+if `vermethod'==0 {
+   di in red "You must define an existing method to define the proximity between two clusters of items:"
+   di in red _col(10) "- single: single linkage"
+   di in red _col(10) "- complete: complete linkage "
+   di in red _col(10) "- average(UPGMA): Unweighted Pair-Group Method of Average"
+   di in red _col(10) "- waverage(WPGMA): Unweighted Pair-Group Method of Average"
+   di in red _col(10) "- wards: Ward's linkage"
+   di in red "Please correct your method option"
+   exit
+}
+if "`method'"=="single"|"`method'"=="singlelinkage" {
+   local method single
+   local desmethod="Single linkage"
+}
+else if "`method'"=="complete"|"`method'"=="completelinkage" {
+   local desmethod="Complete linkage"
+}
+else if "`method'"=="median"|"`method'"=="medianlinkage" {
+   local desmethod="Median linkage (no dendrogram)"
+}
+else if "`method'"=="centroid"|"`method'"=="centroidlinkage" {
+   local desmethod="Centroid linkage (no dendrogram)"
+}
+else if "`method'"=="average"|"`method'"=="averagelinkage" {
+   local desmethod="Unweighted Pair-Group Method of Average"
+}
+else if "`method'"=="waverage"|"`method'"=="waveragelinkage" {
+   local desmethod="Weighted Pair-Group Method of Average"
+}
+else if "`method'"=="wards"|"`method'"=="wardslinkage" {
+   local desmethod="Ward's linkage"
+}
+
+forvalues i=1/`nbitems' {
+	matrix `whereitems'[1,`i']=`i'
+}
+
+tempvar score
+genscore `varlist',score(`score')
+qui su `score'
+local maxscore=r(max)
+forvalues k=0/`maxscore' {
+	qui count if `score'==`k'
+	local nk`k'=r(N)
+}
+
+qui count
+local N=r(N)
+
+
+di in green "{hline 80}"
+di in green "Number of individuals with none missing values: " in ye `N'
+di in green "Maximal number of modalities for a variable: " in ye "`type'"
+di in green "Proximity measures: " in ye "`desprox'"
+di in green "Method to aggregate clusters: " in ye "`desmethod'"
+di in green "{hline 80}"
+di
+di
+
+/*************************Measure of proximities*********************************/
+if "`matrix'"=="" {
+   forvalues i=1/`nbitems' {
+	forvalues j=`=`i'+1'/`nbitems' {
+		/***********************************Proximity AD*************************/
+		if "`prox'"=="matching" {  /*ad*/
+			qui count if ``i''==1&``j''==1
+			local tmp11=r(N)
+			qui count if ``i''==0&``j''==0
+			local tmp00=r(N)
+
+			matrix `proximity'[`i',`j']=sqrt(1-(`tmp11'+`tmp00')/`N')
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/***********************************Proximity A**************************/
+		else if "`prox'"=="jaccard" {   /*a*/
+			qui count if ``i''==1&``j''==1
+			local tmp11=r(N)
+			qui count if ``i''==0&``j''==0
+			local tmp00=r(N)
+
+			matrix `proximity'[`i',`j']=sqrt(1-`tmp11'/(`N'-`tmp00'))
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/***********************************Proximity Russel**************************/
+		else if "`prox'"=="russel" {
+			qui count if ``i''==1&``j''==1
+			local tmp11=r(N)
+
+			matrix `proximity'[`i',`j']=sqrt(1-`tmp11'/`N')
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/***********************************Proximity A**************************/
+		else if "`prox'"=="dice" {
+			qui count if ``i''==1&``j''==1
+			local tmp11=r(N)
+			qui count if ``i''==0&``j''==0
+			local tmp00=r(N)
+
+			matrix `proximity'[`i',`j']=sqrt(1-2*`tmp11'/(`N'+`tmp11'-`tmp00'))
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/**********************************Proximity COR*************************/
+                else if "`prox'"=="pearson" {   /*corr*/
+			qui corr ``i'' ``j''
+			matrix `proximity'[`i',`j']=sqrt(2*(1-r(rho)))
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/***********************************Proximity CCOV**********************/
+		else if "`prox'"=="ccov" {
+			local dij=0
+			local Ntemp=`N'
+			forvalues k=1/`=`maxscore'-1' {
+				if `nk`k''!=0 {
+				   if `nk`k''>1 {
+				      qui corr ``i'' ``j'' if `score'==`k',cov
+                                      local covi`i'j`j'k`k'=r(cov_12)
+				   }
+				   else if `nk`k''==1 {
+				      local Ntemp=`Ntemp'-1
+                                      local covi`i'j`j'k`k'=0
+                                   }
+				   else {
+                                      local covi`i'j`j'k`k'=0
+				   }
+				   local dij=`dij'+`covi`i'j`j'k`k''*`nk`k''
+				}
+			}
+
+			matrix `proximity'[`i',`j']=-`dij'/`Ntemp'
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+			if `proxmin'<`dij'/`Ntemp' {
+				local proxmin=`dij'/`Ntemp'
+			}
+		}
+
+		/***********************************Proximity CCOR**********************/
+
+		else if "`prox'"=="ccor" {
+			local dij=0
+			local nnull=0
+			local Ntemp=`N'
+			forvalues k=1/`=`maxscore'-1' {
+				if `nk`k''!=0 {
+				   if `nk`k''>1 {
+                                      qui corr ``i'' ``j''  if `score'==`k'
+				      local cori`i'j`j'k`k'=r(rho)
+	                           }
+	                           else if `nk`k''==1 {
+                                      local Ntemp=`Ntemp'-1
+      				      local cori`i'j`j'k`k'=0
+	                           }
+	                           else {
+      				      local cori`i'j`j'k`k'=0
+	                           }
+				   if `cori`i'j`j'k`k''!=. {
+					local dij=`dij'+`cori`i'j`j'k`k''*`nk`k''
+				   }
+				   else if `cori`i'j`j'k`k''==. {
+				      local nnull=`nnull'+`nk`k''
+                                   }
+				}
+			}
+
+			matrix `proximity'[`i',`j']=sqrt(2*(1-`dij'/(`Ntemp'-`nnull')))
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+
+		/***********************************Proximity MH************************/
+
+		else if "`prox'"=="mh" {
+			local numij=0
+			local denom=0
+			forvalues k=1/`=`maxscore'-1' {
+				if `nk`k''!=0 {
+					qui count if ``i''==1&``j''==1&`score'==`k'
+					local A=r(N)
+					qui count if ``i''==0&``j''==1&`score'==`k'
+					local B=r(N)
+					qui count if ``i''==1&``j''==0&`score'==`k'
+					local C=r(N)
+					qui count if ``i''==0&``j''==0&`score'==`k'
+					local D=r(N)
+					local numij=`numij'+`A'*`D'/`nk`k''
+					local denomij=`denomij'+`B'*`C'/`nk`k''
+				}
+			}
+
+			matrix `proximity'[`i',`j']=-log(`numij'/`denomij')
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+			if `proxmin'"
+		di " _char(34) "
+	}
+	else {
+	   qui cluster dendro ,labels(name) hor ylabel(,angle(0)) title("Hierarchical Cluster Analysis on variables") subtitle("`desmethod'") xtitle("`desprox' proximities")
+	}
+}
+
+if "`partition'"!="" {
+   foreach i of numlist `partition' {
+      qui cluster gen cluster`i'=group(`i')
+   }
+   tempname clusters
+   mkmat cluster* ,mat(`clusters')
+   matrix rownames `clusters'=`varlist'
+   local compteur=0
+   foreach i of numlist `partition' {
+      local ++compteur
+      di
+      di in green "{hline 30}"
+      di in green "Partition in `i' cluster(s)"
+      di in green "{hline 30}"
+      di
+      forvalues j=1/`i' {
+         local cluster`i'_`j'
+         local nbi`i'_`j'=0
+         forvalues k=1/`nbitems' {
+            if `clusters'[`k',`compteur']==`j' {
+               local cluster`i'_`j' `cluster`i'_`j'' ``k''
+               local ++nbi`i'_`j'
+            }
+         }
+         di in green "Cluster `j': " in ye "`cluster`i'_`j''"
+      }
+   }
+   return matrix clusters=`clusters'
+}
+
+/**********************DETECT OPTION **************************************************/
+
+use `hcaccproxfile',clear
+if "`detect'"!="" {
+        foreach i of numlist `partition' {
+           local liste
+           local part
+           forvalues j=1/`i' {
+              local liste "`liste' `cluster`i'_`j''"
+              local part "`part' `nbi`i'_`j''"
+           }
+           qui detect `liste',part(`part')
+           local detect`i'=r(DETECT)
+           local Iss`i'=r(Iss)
+           local R`i'=r(R)
+        }
+        tempname indexes
+        matrix define `indexes'=J(`compteur',4,0)
+        matrix colnames `indexes'=Clusters DETECT Iss R
+	di ""
+	di in green "{hline 50}"
+	di in green "Indexes to compare the partitions of the items"
+	di in green "{hline 50}"
+	di ""
+	di in green _col(29) "DETECT" _col(43) "Iss" _col(56) "R"
+	local compteur=0
+        foreach k of numlist `partition' {
+                local ++compteur
+	        matrix  `indexes'[`compteur',1]=`k'
+	        matrix  `indexes'[`compteur',2]=`detect`k''
+	        matrix  `indexes'[`compteur',3]=`Iss`k''
+	        matrix  `indexes'[`compteur',4]=`R`k''
+		di  _col(5) in green "`k' cluster(s):" _col(27) in yellow %8.5f `detect`k'' _col(38) %8.5f  `Iss`k'' _col(49) %8.5f `R`k''
+	}
+        return matrix indexes=`indexes'
+}
+return local nbvar=`nbitems'
+return matrix measures=`proximity'
+restore, not
+*use `hcaccproxfile',clear
+
+end
diff --git a/Modules/ado/personal/h/hcavar3.4.ado b/Modules/ado/personal/h/hcavar3.4.ado
new file mode 100644
index 0000000..8067c4c
--- /dev/null
+++ b/Modules/ado/personal/h/hcavar3.4.ado
@@ -0,0 +1,489 @@
+*! Version 3.4 26 May 2014
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* hcavar: Hierachical Clusters Analysis (HCA) of variables
+* Version 3.4: May 26, 2014  /* DETECT option available for polytomous items */
+*
+* Use the Detect Stata program (ssc install detect)
+*
+* Historic :
+* Under the name of -hcaccprox-
+* Version 1 [2004-01-18], Jean-Benoit Hardouin
+* Version 2 [2004-05-12], Jean-Benoit Hardouin
+* Version 3 [2005-12-31], Jean-Benoit Hardouin
+* Version 3.1 [2006-01-15], Jean-Benoit Hardouin  /* correction if there is only one individual with a given score*/
+* Version 3.2 [2010-04-15], Jean-Benoit Hardouin  /* Possibility to use Polytomous Items with CCOR, CCOV and MH*/
+* Version 3.3 [2014-05-07], Jean-Benoit Hardouin, Bastien Perrot  /* HTML option, if option*/
+* Version 3.4 [2014-05-26], Jean-Benoit Hardouin, Bastien Perrot  /* DETECT option available for polytomous items */
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program :http://www.anaqol.org
+*
+* Copyright 2004-2006, 2010 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+************************************************************************************************************
+
+
+program define hcavar34, rclass
+version 9
+syntax varlist(min=2 numeric) [if] [in] [,PROX(string) METHod(string) PARTition(numlist) MEASures  DETect MATrix(string) noDENDROgram HTML(string)]
+
+tempfile hcaccproxfile
+qui save `hcaccproxfile',replace
+preserve
+
+if "`if'"!="" {
+   qui keep `if'
+}
+
+if "`html'"!="" {
+   //set scheme sj
+   //local htmlregion  "graphregion(fcolor(white) ifcolor(white))"
+   di ""
+   di "
"
+}
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+local type=0
+forvalues i=1/`nbitems' {
+   qui drop if ``i''==.
+   qui inspect ``i''
+   if r(N_unique)>`type'&r(N_unique)!=. {
+      local type=r(N_unique)
+   }
+   else if r(N_unique)>`type'&r(N_unique)==. {
+      local type "100"
+   }
+}
+if `type'==100 {
+   local type ">99"
+}
+
+tempname proximity whereitems
+
+local prox=lower("`prox'")
+local method=lower("`method'")
+matrix define `proximity'=J(`nbitems',`nbitems',0)
+matrix define `whereitems'=J(`=`nbitems'-1',`nbitems',0)
+
+/**************************PROXIMITIES MEASURES DESCRIPTION************************/
+
+if "`matrix'"!="" {
+   local desprox="Defined by the user"
+}
+if "`prox'"=="" {
+   local prox="pearson"
+}
+else if "`prox'"=="a" {
+   local prox="jaccard"
+}
+else if "`prox'"=="ad" {
+   local prox="matching"
+}
+else if "`prox'"=="corr" {
+   local prox="pearson"
+}
+if "`type'">"2"&"`prox'"!="pearson"&"`prox'"!="ccov"&"`prox'"!="ccor"&"`prox'"!="mh"  {
+   di in red "Only the {hi:pearson}, {hi:ccov} and {hi:ccor} measures of proximity are available with ordinal or numerous variables"
+   di in red "Please correct your {hi:prox} option."
+   exit
+}
+
+if "`partition'"==""&"`detect'"!=""  {
+   di in ye "option partition() required"
+   error 198
+}
+local existmeas=0
+foreach i in jaccard matching pearson russel dice ccor mh ccov {
+   if "`prox'"=="`i'" {
+      local existmeas=1
+   }
+}
+if `existmeas'==0 {
+   di in red "You must define an existing measure of proximity (jaccard(a), matching(ad), pearson(cor), russel, dice, ccov, ccor, mh)."
+   di in red "Please correct your {hi:prox} option."
+   exit
+}
+if "`prox'"=="ccov"|"`prox'"=="mh" {
+   local proxmin=0
+}
+
+if "`prox'"=="matching" {
+   local desprox="Matching"
+}
+else if "`prox'"=="jaccard" {
+   local desprox="Jaccard"
+}
+else if "`prox'"=="russel" {
+   local desprox="Russel"
+}
+else if "`prox'"=="dice" {
+   local desprox="Dice"
+}
+else if "`prox'"=="pearson" {
+   local desprox="Pearson"
+}
+else if "`prox'"=="ccov" {
+   local desprox="Conditional covariances"
+}
+else if "`prox'"=="ccor" {
+   local desprox="Conditional correlations"
+}
+else if "`prox'"=="mh" {
+   local desprox="Mantel Hanzel"
+}
+
+/**************************PROXIMITIES MEASURES DESCRIPTION************************/
+
+if "`method'"=="upgma"|"`method'"=="" {
+   local method="average"
+}
+if "`method'"=="wpgma"|"`method'"=="" {
+   local method="waverage"
+}
+local vermethod=0
+foreach i in average waverage single centroid median complete wards {
+   if "`method'"=="`i'" {
+      local vermethod=1
+   }
+ }
+
+if `vermethod'==0 {
+   di in red "You must define an existing method to define the proximity between two clusters of items:"
+   di in red _col(10) "- single: single linkage"
+   di in red _col(10) "- complete: complete linkage "
+   di in red _col(10) "- average(UPGMA): Unweighted Pair-Group Method of Average"
+   di in red _col(10) "- waverage(WPGMA): Unweighted Pair-Group Method of Average"
+   di in red _col(10) "- wards: Ward's linkage"
+   di in red "Please correct your method option"
+   exit
+}
+if "`method'"=="single"|"`method'"=="singlelinkage" {
+   local method single
+   local desmethod="Single linkage"
+}
+else if "`method'"=="complete"|"`method'"=="completelinkage" {
+   local desmethod="Complete linkage"
+}
+else if "`method'"=="median"|"`method'"=="medianlinkage" {
+   local desmethod="Median linkage (no dendrogram)"
+}
+else if "`method'"=="centroid"|"`method'"=="centroidlinkage" {
+   local desmethod="Centroid linkage (no dendrogram)"
+}
+else if "`method'"=="average"|"`method'"=="averagelinkage" {
+   local desmethod="Unweighted Pair-Group Method of Average"
+}
+else if "`method'"=="waverage"|"`method'"=="waveragelinkage" {
+   local desmethod="Weighted Pair-Group Method of Average"
+}
+else if "`method'"=="wards"|"`method'"=="wardslinkage" {
+   local desmethod="Ward's linkage"
+}
+
+forvalues i=1/`nbitems' {
+	matrix `whereitems'[1,`i']=`i'
+}
+
+tempvar score
+genscore `varlist',score(`score')
+qui su `score'
+local maxscore=r(max)
+forvalues k=0/`maxscore' {
+	qui count if `score'==`k'
+	local nk`k'=r(N)
+}
+
+qui count
+local N=r(N)
+
+
+di in green "{hline 80}"
+di in green "Number of individuals with none missing values: " in ye `N'
+di in green "Maximal number of modalities for a variable: " in ye "`type'"
+di in green "Proximity measures: " in ye "`desprox'"
+di in green "Method to aggregate clusters: " in ye "`desmethod'"
+di in green "{hline 80}"
+di
+di
+
+/*************************Measure of proximities*********************************/
+if "`matrix'"=="" {
+   forvalues i=1/`nbitems' {
+	forvalues j=`=`i'+1'/`nbitems' {
+		/***********************************Proximity AD*************************/
+		if "`prox'"=="matching" {  /*ad*/
+			qui count if ``i''==1&``j''==1
+			local tmp11=r(N)
+			qui count if ``i''==0&``j''==0
+			local tmp00=r(N)
+
+			matrix `proximity'[`i',`j']=sqrt(1-(`tmp11'+`tmp00')/`N')
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/***********************************Proximity A**************************/
+		else if "`prox'"=="jaccard" {   /*a*/
+			qui count if ``i''==1&``j''==1
+			local tmp11=r(N)
+			qui count if ``i''==0&``j''==0
+			local tmp00=r(N)
+
+			matrix `proximity'[`i',`j']=sqrt(1-`tmp11'/(`N'-`tmp00'))
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/***********************************Proximity Russel**************************/
+		else if "`prox'"=="russel" {
+			qui count if ``i''==1&``j''==1
+			local tmp11=r(N)
+
+			matrix `proximity'[`i',`j']=sqrt(1-`tmp11'/`N')
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/***********************************Proximity A**************************/
+		else if "`prox'"=="dice" {
+			qui count if ``i''==1&``j''==1
+			local tmp11=r(N)
+			qui count if ``i''==0&``j''==0
+			local tmp00=r(N)
+
+			matrix `proximity'[`i',`j']=sqrt(1-2*`tmp11'/(`N'+`tmp11'-`tmp00'))
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/**********************************Proximity COR*************************/
+                else if "`prox'"=="pearson" {   /*corr*/
+			qui corr ``i'' ``j''
+			matrix `proximity'[`i',`j']=sqrt(2*(1-r(rho)))
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+		/***********************************Proximity CCOV**********************/
+		else if "`prox'"=="ccov" {
+			local dij=0
+			local Ntemp=`N'
+			forvalues k=1/`=`maxscore'-1' {
+				if `nk`k''!=0 {
+				   if `nk`k''>1 {
+				      qui corr ``i'' ``j'' if `score'==`k',cov
+                                      local covi`i'j`j'k`k'=r(cov_12)
+				   }
+				   else if `nk`k''==1 {
+				      local Ntemp=`Ntemp'-1
+                                      local covi`i'j`j'k`k'=0
+                                   }
+				   else {
+                                      local covi`i'j`j'k`k'=0
+				   }
+				   local dij=`dij'+`covi`i'j`j'k`k''*`nk`k''
+				}
+			}
+
+			matrix `proximity'[`i',`j']=-`dij'/`Ntemp'
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+			if `proxmin'<`dij'/`Ntemp' {
+				local proxmin=`dij'/`Ntemp'
+			}
+		}
+
+		/***********************************Proximity CCOR**********************/
+
+		else if "`prox'"=="ccor" {
+			local dij=0
+			local nnull=0
+			local Ntemp=`N'
+			forvalues k=1/`=`maxscore'-1' {
+				if `nk`k''!=0 {
+				   if `nk`k''>1 {
+                                      qui corr ``i'' ``j''  if `score'==`k'
+				      local cori`i'j`j'k`k'=r(rho)
+	                           }
+	                           else if `nk`k''==1 {
+                                      local Ntemp=`Ntemp'-1
+      				      local cori`i'j`j'k`k'=0
+	                           }
+	                           else {
+      				      local cori`i'j`j'k`k'=0
+	                           }
+				   if `cori`i'j`j'k`k''!=. {
+					local dij=`dij'+`cori`i'j`j'k`k''*`nk`k''
+				   }
+				   else if `cori`i'j`j'k`k''==. {
+				      local nnull=`nnull'+`nk`k''
+                                   }
+				}
+			}
+
+			matrix `proximity'[`i',`j']=sqrt(2*(1-`dij'/(`Ntemp'-`nnull')))
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+		}
+
+
+		/***********************************Proximity MH************************/
+
+		else if "`prox'"=="mh" {
+			local numij=0
+			local denom=0
+			forvalues k=1/`=`maxscore'-1' {
+				if `nk`k''!=0 {
+					qui count if ``i''==1&``j''==1&`score'==`k'
+					local A=r(N)
+					qui count if ``i''==0&``j''==1&`score'==`k'
+					local B=r(N)
+					qui count if ``i''==1&``j''==0&`score'==`k'
+					local C=r(N)
+					qui count if ``i''==0&``j''==0&`score'==`k'
+					local D=r(N)
+					local numij=`numij'+`A'*`D'/`nk`k''
+					local denomij=`denomij'+`B'*`C'/`nk`k''
+				}
+			}
+
+			matrix `proximity'[`i',`j']=-log(`numij'/`denomij')
+			matrix `proximity'[`j',`i']=`proximity'[`i',`j']
+			if `proxmin'"
+		di " _char(34) "
+	}
+	else {
+	   qui cluster dendro ,labels(name) hor ylabel(,angle(0)) title("Hierarchical Cluster Analysis on variables") subtitle("`desmethod'") xtitle("`desprox' proximities")
+	}
+}
+
+if "`partition'"!="" {
+   foreach i of numlist `partition' {
+      qui cluster gen cluster`i'=group(`i')
+   }
+   tempname clusters
+   mkmat cluster* ,mat(`clusters')
+   matrix rownames `clusters'=`varlist'
+   local compteur=0
+   foreach i of numlist `partition' {
+      local ++compteur
+      di
+      di in green "{hline 30}"
+      di in green "Partition in `i' cluster(s)"
+      di in green "{hline 30}"
+      di
+      forvalues j=1/`i' {
+         local cluster`i'_`j'
+         local nbi`i'_`j'=0
+         forvalues k=1/`nbitems' {
+            if `clusters'[`k',`compteur']==`j' {
+               local cluster`i'_`j' `cluster`i'_`j'' ``k''
+               local ++nbi`i'_`j'
+            }
+         }
+         di in green "Cluster `j': " in ye "`cluster`i'_`j''"
+      }
+   }
+   return matrix clusters=`clusters'
+}
+
+/**********************DETECT OPTION **************************************************/
+
+use `hcaccproxfile',clear
+if "`detect'"!="" {
+        foreach i of numlist `partition' {
+           local liste
+           local part
+           forvalues j=1/`i' {
+              local liste "`liste' `cluster`i'_`j''"
+              local part "`part' `nbi`i'_`j''"
+           }
+           qui detect `liste',part(`part')
+           local detect`i'=r(DETECT)
+           local Iss`i'=r(Iss)
+           local R`i'=r(R)
+        }
+        tempname indexes
+        matrix define `indexes'=J(`compteur',4,0)
+        matrix colnames `indexes'=Clusters DETECT Iss R
+	di ""
+	di in green "{hline 50}"
+	di in green "Indexes to compare the partitions of the items"
+	di in green "{hline 50}"
+	di ""
+	di in green _col(29) "DETECT" _col(43) "Iss" _col(56) "R"
+	local compteur=0
+        foreach k of numlist `partition' {
+                local ++compteur
+	        matrix  `indexes'[`compteur',1]=`k'
+	        matrix  `indexes'[`compteur',2]=`detect`k''
+	        matrix  `indexes'[`compteur',3]=`Iss`k''
+	        matrix  `indexes'[`compteur',4]=`R`k''
+		di  _col(5) in green "`k' cluster(s):" _col(27) in yellow %8.5f `detect`k'' _col(38) %8.5f  `Iss`k'' _col(49) %8.5f `R`k''
+	}
+        return matrix indexes=`indexes'
+}
+return local nbvar=`nbitems'
+return matrix measures=`proximity'
+restore, not
+*use `hcaccproxfile',clear
+
+end
diff --git a/Modules/ado/personal/i/imputeitems - Copie.ado b/Modules/ado/personal/i/imputeitems - Copie.ado
new file mode 100644
index 0000000..4760f0f
--- /dev/null
+++ b/Modules/ado/personal/i/imputeitems - Copie.ado	
@@ -0,0 +1,193 @@
+*! version 2.4 3 May 2013
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* imputeitems: Imputation of missing data of binary items
+*
+* Version 1 : November 25, 2006 (Jean-Benoit Hardouin) /*Dichotomous data*/
+* Version 1.1 : January 26, 2007 (Jean-Benoit Hardouin) /*Correction of a bug with the BIL method*/
+* Version 1.2 : March 9, 2007 (Jean-Benoit Hardouin) /*IF*/
+* Version 2 : June 30, 2008 (Jean-Benoit Hardouin) /*new names of the methods, MAX option*/
+* Version 2.1 : December 3, 2008 (Jean-Benoit Hardouin) /*correction of a bug with the MAX option*/
+* Version 2.2 : January 28, 2013 (Jean-Benoit Hardouin) /*noround option*/
+* Version 2.3 : February 19, 2013 (Jean-Benoit Hardouin) /*polytomous items with PMS method*/
+* Version 2.4 : May 3, 2013 (Jean-Benoit Hardouin) /*minor correction*/
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences  (UPRES EA 4275 SPHERE)
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* News about this program :http://www.anaqol.org
+*
+* Copyright 2006-2008,2013 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define imputeitems
+version 9
+syntax varlist(min=2 numeric) [if/] [, PREFix(string) METHod(string) RANDom max(int -1) noround]
+
+if "`if'"=="" {
+   local if=1
+   local ifif
+}
+else {
+   local ifif if `if'
+}
+
+*di "IF : `if' `ifif'"
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+
+if `max'==-1 {
+   local max=`nbitems'
+}
+
+if "`method'"=="" {
+   local method pms
+}
+forvalues i=1/`nbitems' {
+   qui su ``i'' `ifif'
+   if `r(min)'!=0&(`r(max)'!=1&"`method'"!="pms") {
+       di in red "The {hi:imputeqol} command runs only with dichotomous items"
+       error
+   }
+   local p`i'=r(mean)
+}
+
+if "`method'"!="pms"&"`method'"!="ims"&"`method'"!="cim"&"`method'"!="ics"&"`method'"!="bip"&"`method'"!="bil"&"`method'"!="bic"&"`method'"!="bii"&"`method'"!="log"&"`method'"!="worst" {
+   di in red "The method option is unknow (choose among pms, ims, cim, ics, log and worst)"
+   error
+}
+forvalues i=1/`nbitems'{
+   qui su ``i'' `ifif'
+   local mean`i'=r(mean)
+}
+
+if "`method'"=="pms"&"`random'"!="" {
+   local method bip
+}
+else if "`method'"=="ims"&"`random'"!="" {
+   local method bii
+}
+else if "`method'"=="log"&"`random'"!="" {
+   local method bil
+}
+else if "`method'"=="cim"&"`random'"!="" {
+   local method bic
+}
+else if ("`method'"=="ics"|"`method'"=="worst")&"`random'"!="" {
+   di in green "The random process is not available with the {hi:ics} or {hi:worst} methods. The {hi:random} option is ignored."
+   local random
+}
+
+
+forvalues i=1/`nbitems' {
+   tempvar imp`i' tmp`i'
+   if "`method'"=="pms"|"`method'"=="bip"|"`method'"=="cim"|"`method'"=="bic" {
+      qui egen `imp`i''=rowtotal(`varlist') `ifif'
+      qui egen `tmp`i''=rownonmiss(`varlist') `ifif'
+      qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif'
+      qui replace `imp`i''=``i'' if ``i''!=.&`if'
+      if "`method'"=="pms"&"`round'"=="" {
+          qui replace `imp`i''=round(`imp`i'') `ifif'
+      }
+      else if "`method'"=="bip" {
+          qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+      }
+      else if "`method'"=="cim"|"`method'"=="bic"{
+         qui replace `imp`i''=`imp`i''*`tmp`i''*`mean`i'' `ifif'
+         qui replace `tmp`i''=0 `ifif'
+         forvalues j=1/`nbitems' {
+            qui replace `tmp`i''=`tmp`i''+`mean`j'' if ``j''!=.&`if'
+         }
+         qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif'
+         qui replace `imp`i''=1 if `imp`i''>1&`imp`i''!=.&`if'
+         qui replace `imp`i''=0 if `imp`i''<0&`imp`i''!=.&`if'
+         if "`method'"=="cim"&"`round'"=="" {
+             qui replace `imp`i''=round(`imp`i'') `ifif'
+         }
+         else if "`method'"=="bic" {
+             qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+         }
+      }
+   }
+   else if "`method'"=="ims"|"`method'"=="bii" {
+      qui gen `imp`i''=`mean`i'' `ifif'
+      if "`method'"=="ims"&"`round'"=="" {
+         qui replace `imp`i''=round(`imp`i'') `ifif'
+      }
+      else if "`method'"=="bii" {
+         qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+      }
+   }
+   else if "`method'"=="ics" {
+      local item=0
+      local corrmax=-2
+      forvalues j=1/`nbitems' {
+         if `i'!=`j' {
+            qui corr ``i'' ``j'' `ifif'
+            if r(rho)>`corrmax'&r(rho)!=. {
+               local item `j'
+               local corrmax=r(rho)
+            }
+         }
+      }
+      di "A missing value for the item ``i'' is replaced by the value of the item `item'"
+      qui gen `imp`i''=``i'' `ifif'
+      qui replace `imp`i''=``item'' if ``i''==.&`if'
+   }
+   else if "`method'"=="log"|"`method'"=="bil" {
+      local liste`i'
+      forvalues j=1/`nbitems' {
+         if `i'!=`j' {
+            local liste`i' `liste`i'' ``j''
+         }
+      }
+      qui sw ,pr(0.05): logit ``i'' `liste`i'' `ifif'
+      *local select  :colnames e(b)
+      local select=substr("`:colnames e(b)'",1,length("`:colnames e(b)'")-5)
+      qui logit ``i'' `select' `ifif'
+      qui predict `imp`i'' `ifif'
+      if "`method'"=="log"&"`round'"=="" {
+          qui replace `imp`i''=round(`imp`i'') if `imp`i''!=.&`if'
+      }
+      else if "`method'"=="bil" {
+          qui replace `imp`i''=uniform()<`imp`i'' if `imp`i''!=.&`if'
+      }
+   }
+   else if "`method'"=="worst" {
+      qui gen `imp`i''=0  `ifif'
+   }
+}
+forvalues i=1/`nbitems' {
+   qui replace `imp`i''=``i'' if ``i''!=.&`if'
+   if "`prefix'"=="" {
+      local prefix imp
+   }
+   qui gen `prefix'``i''=`imp`i'' `ifif'
+}
+
+tempvar miss
+qui egen `miss'=rowmiss(`varlist')
+forvalues i=1/`nbitems' {
+   qui replace `prefix'``i''=. if ``i''==.&`miss'>`max'
+}
+
+end
diff --git a/Modules/ado/personal/i/imputeitems v2.4.ado b/Modules/ado/personal/i/imputeitems v2.4.ado
new file mode 100644
index 0000000..4760f0f
--- /dev/null
+++ b/Modules/ado/personal/i/imputeitems v2.4.ado	
@@ -0,0 +1,193 @@
+*! version 2.4 3 May 2013
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* imputeitems: Imputation of missing data of binary items
+*
+* Version 1 : November 25, 2006 (Jean-Benoit Hardouin) /*Dichotomous data*/
+* Version 1.1 : January 26, 2007 (Jean-Benoit Hardouin) /*Correction of a bug with the BIL method*/
+* Version 1.2 : March 9, 2007 (Jean-Benoit Hardouin) /*IF*/
+* Version 2 : June 30, 2008 (Jean-Benoit Hardouin) /*new names of the methods, MAX option*/
+* Version 2.1 : December 3, 2008 (Jean-Benoit Hardouin) /*correction of a bug with the MAX option*/
+* Version 2.2 : January 28, 2013 (Jean-Benoit Hardouin) /*noround option*/
+* Version 2.3 : February 19, 2013 (Jean-Benoit Hardouin) /*polytomous items with PMS method*/
+* Version 2.4 : May 3, 2013 (Jean-Benoit Hardouin) /*minor correction*/
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences  (UPRES EA 4275 SPHERE)
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* News about this program :http://www.anaqol.org
+*
+* Copyright 2006-2008,2013 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define imputeitems
+version 9
+syntax varlist(min=2 numeric) [if/] [, PREFix(string) METHod(string) RANDom max(int -1) noround]
+
+if "`if'"=="" {
+   local if=1
+   local ifif
+}
+else {
+   local ifif if `if'
+}
+
+*di "IF : `if' `ifif'"
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+
+if `max'==-1 {
+   local max=`nbitems'
+}
+
+if "`method'"=="" {
+   local method pms
+}
+forvalues i=1/`nbitems' {
+   qui su ``i'' `ifif'
+   if `r(min)'!=0&(`r(max)'!=1&"`method'"!="pms") {
+       di in red "The {hi:imputeqol} command runs only with dichotomous items"
+       error
+   }
+   local p`i'=r(mean)
+}
+
+if "`method'"!="pms"&"`method'"!="ims"&"`method'"!="cim"&"`method'"!="ics"&"`method'"!="bip"&"`method'"!="bil"&"`method'"!="bic"&"`method'"!="bii"&"`method'"!="log"&"`method'"!="worst" {
+   di in red "The method option is unknow (choose among pms, ims, cim, ics, log and worst)"
+   error
+}
+forvalues i=1/`nbitems'{
+   qui su ``i'' `ifif'
+   local mean`i'=r(mean)
+}
+
+if "`method'"=="pms"&"`random'"!="" {
+   local method bip
+}
+else if "`method'"=="ims"&"`random'"!="" {
+   local method bii
+}
+else if "`method'"=="log"&"`random'"!="" {
+   local method bil
+}
+else if "`method'"=="cim"&"`random'"!="" {
+   local method bic
+}
+else if ("`method'"=="ics"|"`method'"=="worst")&"`random'"!="" {
+   di in green "The random process is not available with the {hi:ics} or {hi:worst} methods. The {hi:random} option is ignored."
+   local random
+}
+
+
+forvalues i=1/`nbitems' {
+   tempvar imp`i' tmp`i'
+   if "`method'"=="pms"|"`method'"=="bip"|"`method'"=="cim"|"`method'"=="bic" {
+      qui egen `imp`i''=rowtotal(`varlist') `ifif'
+      qui egen `tmp`i''=rownonmiss(`varlist') `ifif'
+      qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif'
+      qui replace `imp`i''=``i'' if ``i''!=.&`if'
+      if "`method'"=="pms"&"`round'"=="" {
+          qui replace `imp`i''=round(`imp`i'') `ifif'
+      }
+      else if "`method'"=="bip" {
+          qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+      }
+      else if "`method'"=="cim"|"`method'"=="bic"{
+         qui replace `imp`i''=`imp`i''*`tmp`i''*`mean`i'' `ifif'
+         qui replace `tmp`i''=0 `ifif'
+         forvalues j=1/`nbitems' {
+            qui replace `tmp`i''=`tmp`i''+`mean`j'' if ``j''!=.&`if'
+         }
+         qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif'
+         qui replace `imp`i''=1 if `imp`i''>1&`imp`i''!=.&`if'
+         qui replace `imp`i''=0 if `imp`i''<0&`imp`i''!=.&`if'
+         if "`method'"=="cim"&"`round'"=="" {
+             qui replace `imp`i''=round(`imp`i'') `ifif'
+         }
+         else if "`method'"=="bic" {
+             qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+         }
+      }
+   }
+   else if "`method'"=="ims"|"`method'"=="bii" {
+      qui gen `imp`i''=`mean`i'' `ifif'
+      if "`method'"=="ims"&"`round'"=="" {
+         qui replace `imp`i''=round(`imp`i'') `ifif'
+      }
+      else if "`method'"=="bii" {
+         qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+      }
+   }
+   else if "`method'"=="ics" {
+      local item=0
+      local corrmax=-2
+      forvalues j=1/`nbitems' {
+         if `i'!=`j' {
+            qui corr ``i'' ``j'' `ifif'
+            if r(rho)>`corrmax'&r(rho)!=. {
+               local item `j'
+               local corrmax=r(rho)
+            }
+         }
+      }
+      di "A missing value for the item ``i'' is replaced by the value of the item `item'"
+      qui gen `imp`i''=``i'' `ifif'
+      qui replace `imp`i''=``item'' if ``i''==.&`if'
+   }
+   else if "`method'"=="log"|"`method'"=="bil" {
+      local liste`i'
+      forvalues j=1/`nbitems' {
+         if `i'!=`j' {
+            local liste`i' `liste`i'' ``j''
+         }
+      }
+      qui sw ,pr(0.05): logit ``i'' `liste`i'' `ifif'
+      *local select  :colnames e(b)
+      local select=substr("`:colnames e(b)'",1,length("`:colnames e(b)'")-5)
+      qui logit ``i'' `select' `ifif'
+      qui predict `imp`i'' `ifif'
+      if "`method'"=="log"&"`round'"=="" {
+          qui replace `imp`i''=round(`imp`i'') if `imp`i''!=.&`if'
+      }
+      else if "`method'"=="bil" {
+          qui replace `imp`i''=uniform()<`imp`i'' if `imp`i''!=.&`if'
+      }
+   }
+   else if "`method'"=="worst" {
+      qui gen `imp`i''=0  `ifif'
+   }
+}
+forvalues i=1/`nbitems' {
+   qui replace `imp`i''=``i'' if ``i''!=.&`if'
+   if "`prefix'"=="" {
+      local prefix imp
+   }
+   qui gen `prefix'``i''=`imp`i'' `ifif'
+}
+
+tempvar miss
+qui egen `miss'=rowmiss(`varlist')
+forvalues i=1/`nbitems' {
+   qui replace `prefix'``i''=. if ``i''==.&`miss'>`max'
+}
+
+end
diff --git a/Modules/ado/personal/i/imputeitems.ado b/Modules/ado/personal/i/imputeitems.ado
new file mode 100644
index 0000000..a90a9d3
--- /dev/null
+++ b/Modules/ado/personal/i/imputeitems.ado
@@ -0,0 +1,193 @@
+*! version 2.5 17 December 2021
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* imputeitems: Imputation of missing data of binary items
+*
+* Version 1 : November 25, 2006 (Jean-Benoit Hardouin) /*Dichotomous data*/
+* Version 1.1 : January 26, 2007 (Jean-Benoit Hardouin) /*Correction of a bug with the BIL method*/
+* Version 1.2 : March 9, 2007 (Jean-Benoit Hardouin) /*IF*/
+* Version 2 : June 30, 2008 (Jean-Benoit Hardouin) /*new names of the methods, MAX option*/
+* Version 2.1 : December 3, 2008 (Jean-Benoit Hardouin) /*correction of a bug with the MAX option*/
+* Version 2.2 : January 28, 2013 (Jean-Benoit Hardouin) /*noround option*/
+* Version 2.3 : February 19, 2013 (Jean-Benoit Hardouin) /*polytomous items with PMS method*/
+* Version 2.4 : May 3, 2013 (Jean-Benoit Hardouin) /*minor correction*/
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences  (UPRES EA 4275 SPHERE)
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* News about this program :http://www.anaqol.org
+*
+* Copyright 2006-2008,2013 2021 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define imputeitems
+version 9
+syntax varlist(min=2 numeric) [if/] [, PREFix(string) METHod(string) RANDom max(int -1) noround]
+
+if "`if'"=="" {
+   local if=1
+   local ifif
+}
+else {
+   local ifif if `if'
+}
+
+*di "IF : `if' `ifif'"
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+
+if `max'==-1 {
+   local max=`nbitems'
+}
+
+if "`method'"=="" {
+   local method pms
+}
+forvalues i=1/`nbitems' {
+   qui su ``i'' `ifif'
+   if "`r(min)'"!="0"&("`r(max)'"!="1"&"`method'"!="pms") {
+       di in red "The {hi:imputeqol} command runs only with dichotomous items"
+       error
+   }
+   local p`i'=r(mean)
+}
+
+if "`method'"!="pms"&"`method'"!="ims"&"`method'"!="cim"&"`method'"!="ics"&"`method'"!="bip"&"`method'"!="bil"&"`method'"!="bic"&"`method'"!="bii"&"`method'"!="log"&"`method'"!="worst" {
+   di in red "The method option is unknow (choose among pms, ims, cim, ics, log and worst)"
+   error
+}
+forvalues i=1/`nbitems'{
+   qui su ``i'' `ifif'
+   local mean`i'=r(mean)
+}
+
+if "`method'"=="pms"&"`random'"!="" {
+   local method bip
+}
+else if "`method'"=="ims"&"`random'"!="" {
+   local method bii
+}
+else if "`method'"=="log"&"`random'"!="" {
+   local method bil
+}
+else if "`method'"=="cim"&"`random'"!="" {
+   local method bic
+}
+else if ("`method'"=="ics"|"`method'"=="worst")&"`random'"!="" {
+   di in green "The random process is not available with the {hi:ics} or {hi:worst} methods. The {hi:random} option is ignored."
+   local random
+}
+
+
+forvalues i=1/`nbitems' {
+   tempvar imp`i' tmp`i'
+   if "`method'"=="pms"|"`method'"=="bip"|"`method'"=="cim"|"`method'"=="bic" {
+      qui egen `imp`i''=rowtotal(`varlist') `ifif'
+      qui egen `tmp`i''=rownonmiss(`varlist') `ifif'
+      qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif'
+      qui replace `imp`i''=``i'' if ``i''!=.&`if'
+      if "`method'"=="pms"&"`round'"=="" {
+          qui replace `imp`i''=round(`imp`i'') `ifif'
+      }
+      else if "`method'"=="bip" {
+          qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+      }
+      else if "`method'"=="cim"|"`method'"=="bic"{
+         qui replace `imp`i''=`imp`i''*`tmp`i''*`mean`i'' `ifif'
+         qui replace `tmp`i''=0 `ifif'
+         forvalues j=1/`nbitems' {
+            qui replace `tmp`i''=`tmp`i''+`mean`j'' if ``j''!=.&`if'
+         }
+         qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif'
+         qui replace `imp`i''=1 if `imp`i''>1&`imp`i''!=.&`if'
+         qui replace `imp`i''=0 if `imp`i''<0&`imp`i''!=.&`if'
+         if "`method'"=="cim"&"`round'"=="" {
+             qui replace `imp`i''=round(`imp`i'') `ifif'
+         }
+         else if "`method'"=="bic" {
+             qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+         }
+      }
+   }
+   else if "`method'"=="ims"|"`method'"=="bii" {
+      qui gen `imp`i''=`mean`i'' `ifif'
+      if "`method'"=="ims"&"`round'"=="" {
+         qui replace `imp`i''=round(`imp`i'') `ifif'
+      }
+      else if "`method'"=="bii" {
+         qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+      }
+   }
+   else if "`method'"=="ics" {
+      local item=0
+      local corrmax=-2
+      forvalues j=1/`nbitems' {
+         if `i'!=`j' {
+            qui corr ``i'' ``j'' `ifif'
+            if r(rho)>`corrmax'&r(rho)!=. {
+               local item `j'
+               local corrmax=r(rho)
+            }
+         }
+      }
+      di "A missing value for the item ``i'' is replaced by the value of the item `item'"
+      qui gen `imp`i''=``i'' `ifif'
+      qui replace `imp`i''=``item'' if ``i''==.&`if'
+   }
+   else if "`method'"=="log"|"`method'"=="bil" {
+      local liste`i'
+      forvalues j=1/`nbitems' {
+         if `i'!=`j' {
+            local liste`i' `liste`i'' ``j''
+         }
+      }
+      qui sw ,pr(0.05): logit ``i'' `liste`i'' `ifif'
+      *local select  :colnames e(b)
+      local select=substr("`:colnames e(b)'",1,length("`:colnames e(b)'")-5)
+      qui logit ``i'' `select' `ifif'
+      qui predict `imp`i'' `ifif'
+      if "`method'"=="log"&"`round'"=="" {
+          qui replace `imp`i''=round(`imp`i'') if `imp`i''!=.&`if'
+      }
+      else if "`method'"=="bil" {
+          qui replace `imp`i''=uniform()<`imp`i'' if `imp`i''!=.&`if'
+      }
+   }
+   else if "`method'"=="worst" {
+      qui gen `imp`i''=0  `ifif'
+   }
+}
+forvalues i=1/`nbitems' {
+   qui replace `imp`i''=``i'' if ``i''!=.&`if'
+   if "`prefix'"=="" {
+      local prefix imp
+   }
+   qui gen `prefix'``i''=`imp`i'' `ifif'
+}
+
+tempvar miss
+qui egen `miss'=rowmiss(`varlist')
+forvalues i=1/`nbitems' {
+   qui replace `prefix'``i''=. if ``i''==.&`miss'>`max'
+}
+
+end
diff --git a/Modules/ado/personal/i/imputeitems.hlp b/Modules/ado/personal/i/imputeitems.hlp
new file mode 100644
index 0000000..a75c9aa
--- /dev/null
+++ b/Modules/ado/personal/i/imputeitems.hlp
@@ -0,0 +1,70 @@
+{smcl}
+{* 6May2013}{...}
+{hline}
+help for {hi:imputeitems}{right:Jean-Benoit Hardouin}
+{hline}
+
+{title:Imputation of missing item responses}
+
+{p 8 14 2}{cmd:imputeitems} {it:varlist} [{it:if}] [,{cmdab:pref:ix}({it:string}) {cmdab:meth:od}({it:string}) {cmdab:rand:om} {cmdab:max}({it:#})]
+
+
+{title:Description}
+
+{p 4 4 2}{cmd:imputeitems} imputes missing item responses by different ways : Item Mean Substitution (IMS), Person Mean Substitution (PMS), Corrected Item Mean Substiutution (CIM), Interitem Correlation Substitution (ICS), logistic model (LOG) and Worst Case (WORST). A random process can be added to several methods.
+
+{title:Options}
+
+{p 4 8 2}{cmd:prefix} defines the prefix to use to name the imputted variables (this prefix is followed by the name of the initial variable). By default, this prefix is "imp".
+
+{p 4 8 2}{cmd:method} defines the method to impute missing data :
+
+{p 8 8 2}{it:pms} computes the proportion of positive response of each individual on non missing items, and impute a deterministic result (if p<.5 then 0, else 1),
+
+{p 8 8 2}{it:ims} computes the proportion of positive response to each items, and impute a deterministic result (if p<.5 then 0, else 1),
+
+{p 8 8 2}{it:cim} computes the proportion of positive response to each items, corrected by the ability of the individual and impute a deterministic result (if p<.5 then 0, else 1),
+
+{p 8 8 2}{it:ics} searchs for each item the more correlated item and replaces a missing data by the data of this more correlated item (if the other response is missing too, there is no imputation),
+
+{p 8 8 2}{it:log} explains the responses of each item by a logistic model where the independent variables are the responses to the others items. Only significant variables are rettained (5%). These methods impute a deterministic result (if p<.5 then 0, else 1) [{it:log}] to missing responses (if the response to an independant variable is missing, there is no imputation),
+
+{p 8 8 2}{it:worst} replaces the missing data by a 0.
+
+{p 4 8 2}{cmd:random} adds a random effect to the imputation process (available only with {it:pms}, {it:ims}, {it:cim} or {it:log}). In these cases, the imputed value is randomly drawed from a binomial distribution using the parameter p.
+
+{p 4 8 2}{cmd:noround} avoids to round the imputed values to the nearest integer.
+
+{p 4 8 2}{cmd:max} allows imputing missing values only for individuals with a maximal number of missing values defined with this option.
+
+{p 4 8 2}By default, {it:pms} method is working.
+
+{p 4 8 2}Old names of methods ({it:bip}, {bii}, {it:bic} and {it:bil} continues to run. They actually correspond to the add of the {cmd:random} option to the {it:pms}, {it:ims}, {it:cim} and {it:log} methods.
+
+
+{title:Example}
+
+	{cmd:. imputeitems itemA*} /*PMS method, IMP prefix*/
+
+	{cmd:. imputeitems itemA*, prefix(cim) method(cim)}
+
+	{cmd:. imputeitems itemA*, method(log) random}
+
+
+{title:Reference}
+
+{p 4 8 2}{cmd:Huisman M.} (2000), Imputation of missing item responses: some simple techniques. {it: Quality & Quantity}, {cmd:34}, 331-351.
+
+
+{title:Author}
+
+{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
+{p 4 8 2}EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"{p_end}
+{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end}
+{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end}
+{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end}
+{p 4 8 2}Email:
+{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end}
+{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol}
+and {browse "http://www.freeirt.org":FreeIRT}
+
diff --git a/Modules/ado/personal/i/imputeitems.txt b/Modules/ado/personal/i/imputeitems.txt
new file mode 100644
index 0000000..15d21a7
--- /dev/null
+++ b/Modules/ado/personal/i/imputeitems.txt
@@ -0,0 +1,190 @@
+*! version 2.3 19 February 2013
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* imputeitems: Imputation of missing data of binary items
+*
+* Version 1 : November 25, 2006 (Jean-Benoit Hardouin) /*Dichotomous data*/
+* Version 1.1 : January 26, 2007 (Jean-Benoit Hardouin) /*Correction of a bug with the BIL method*/
+* Version 1.2 : March 9, 2007 (Jean-Benoit Hardouin) /*IF*/
+* Version 2 : June 30, 2008 (Jean-Benoit Hardouin) /*new names of the methods, MAX option*/
+* Version 2.1 : December 3, 2008 (Jean-Benoit Hardouin) /*correction of a bug with the MAX option*/
+* Version 2.2 : January 28, 2013 (Jean-Benoit Hardouin) /*noround option*/
+* Version 2.3 : February 19, 2013 (Jean-Benoit Hardouin) /*polytomous items with PMS method*/
+*
+* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2006-2008,2013 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define imputeitems
+version 9
+syntax varlist(min=2 numeric) [if/] [, PREFix(string) METHod(string) RANDom max(int 0) noround]
+
+if "`if'"=="" {
+   local if=1
+   local ifif
+}
+else {
+   local ifif if `if'
+}
+
+*di "IF : `if' `ifif'"
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+
+if `max'==0 {
+   local max=`nbitems'
+}
+
+if "`method'"=="" {
+   local method pms
+}
+forvalues i=1/`nbitems' {
+   qui su ``i'' `ifif'
+   if `r(min)'!=0&(`r(max)'!=1&"`method"!="pms") {
+       di in red "The {hi:imputeqol} command runs only with dichotomous items"
+       error
+   }
+   local p`i'=r(mean)
+}
+
+if "`method'"!="pms"&"`method'"!="ims"&"`method'"!="cim"&"`method'"!="ics"&"`method'"!="bip"&"`method'"!="bil"&"`method'"!="bic"&"`method'"!="bii"&"`method'"!="log"&"`method'"!="worst" {
+   di in red "The method option is unknow (choose among pms, ims, cim, ics, log and worst)"
+   error
+}
+forvalues i=1/`nbitems'{
+   qui su ``i'' `ifif'
+   local mean`i'=r(mean)
+}
+
+if "`method'"=="pms"&"`random'"!="" {
+   local method bip
+}
+else if "`method'"=="ims"&"`random'"!="" {
+   local method bii
+}
+else if "`method'"=="log"&"`random'"!="" {
+   local method bil
+}
+else if "`method'"=="cim"&"`random'"!="" {
+   local method bic
+}
+else if ("`method'"=="ics"|"`method'"=="worst")&"`random'"!="" {
+   di in green "The random process is not available with the {hi:ics} or {hi:worst} methods. The {hi:random} option is ignored."
+   local random
+}
+
+
+forvalues i=1/`nbitems' {
+   tempvar imp`i' tmp`i'
+   if "`method'"=="pms"|"`method'"=="bip"|"`method'"=="cim"|"`method'"=="bic" {
+      qui egen `imp`i''=rowtotal(`varlist') `ifif'
+      qui egen `tmp`i''=rownonmiss(`varlist') `ifif'
+      qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif'
+      qui replace `imp`i''=``i'' if ``i''!=.&`if'
+      if "`method'"=="pms"&"`round'"=="" {
+          qui replace `imp`i''=round(`imp`i'') `ifif'
+      }
+      else if "`method'"=="bip" {
+          qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+      }
+      else if "`method'"=="cim"|"`method'"=="bic"{
+         qui replace `imp`i''=`imp`i''*`tmp`i''*`mean`i'' `ifif'
+         qui replace `tmp`i''=0 `ifif'
+         forvalues j=1/`nbitems' {
+            qui replace `tmp`i''=`tmp`i''+`mean`j'' if ``j''!=.&`if'
+         }
+         qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif'
+         qui replace `imp`i''=1 if `imp`i''>1&`imp`i''!=.&`if'
+         qui replace `imp`i''=0 if `imp`i''<0&`imp`i''!=.&`if'
+         if "`method'"=="cim"&"`round'"=="" {
+             qui replace `imp`i''=round(`imp`i'') `ifif'
+         }
+         else if "`method'"=="bic" {
+             qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+         }
+      }
+   }
+   else if "`method'"=="ims"|"`method'"=="bii" {
+      qui gen `imp`i''=`mean`i'' `ifif'
+      if "`method'"=="ims"&"`round'"=="" {
+         qui replace `imp`i''=round(`imp`i'') `ifif'
+      }
+      else if "`method'"=="bii" {
+         qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+      }
+   }
+   else if "`method'"=="ics" {
+      local item=0
+      local corrmax=-2
+      forvalues j=1/`nbitems' {
+         if `i'!=`j' {
+            qui corr ``i'' ``j'' `ifif'
+            if r(rho)>`corrmax'&r(rho)!=. {
+               local item `j'
+               local corrmax=r(rho)
+            }
+         }
+      }
+      di "A missing value for the item ``i'' is replaced by the value of the item `item'"
+      qui gen `imp`i''=``i'' `ifif'
+      qui replace `imp`i''=``item'' if ``i''==.&`if'
+   }
+   else if "`method'"=="log"|"`method'"=="bil" {
+      local liste`i'
+      forvalues j=1/`nbitems' {
+         if `i'!=`j' {
+            local liste`i' `liste`i'' ``j''
+         }
+      }
+      qui sw ,pr(0.05): logit ``i'' `liste`i'' `ifif'
+      *local select  :colnames e(b)
+      local select=substr("`:colnames e(b)'",1,length("`:colnames e(b)'")-5)
+      qui logit ``i'' `select' `ifif'
+      qui predict `imp`i'' `ifif'
+      if "`method'"=="log"&"`round'"=="" {
+          qui replace `imp`i''=round(`imp`i'') if `imp`i''!=.&`if'
+      }
+      else if "`method'"=="bil" {
+          qui replace `imp`i''=uniform()<`imp`i'' if `imp`i''!=.&`if'
+      }
+   }
+   else if "`method'"=="worst" {
+      qui gen `imp`i''=0  `ifif'
+   }
+}
+forvalues i=1/`nbitems' {
+   qui replace `imp`i''=``i'' if ``i''!=.&`if'
+   if "`prefix'"=="" {
+      local prefix imp
+   }
+   qui gen `prefix'``i''=`imp`i'' `ifif'
+}
+
+tempvar miss
+qui egen `miss'=rowmiss(`varlist')
+forvalues i=1/`nbitems' {
+   qui replace `prefix'``i''=. if ``i''==.&`miss'>`max'
+}
+
+end
diff --git a/Modules/ado/personal/i/imputeitems2.ado b/Modules/ado/personal/i/imputeitems2.ado
new file mode 100644
index 0000000..042e8f8
--- /dev/null
+++ b/Modules/ado/personal/i/imputeitems2.ado
@@ -0,0 +1,201 @@
+*! version 2.3 19 February 2013
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* imputeitems: Imputation of missing data of binary items
+*
+* Version 1 : November 25, 2006 (Jean-Benoit Hardouin) /*Dichotomous data*/
+* Version 1.1 : January 26, 2007 (Jean-Benoit Hardouin) /*Correction of a bug with the BIL method*/
+* Version 1.2 : March 9, 2007 (Jean-Benoit Hardouin) /*IF*/
+* Version 2 : June 30, 2008 (Jean-Benoit Hardouin) /*new names of the methods, MAX option*/
+* Version 2.1 : December 3, 2008 (Jean-Benoit Hardouin) /*correction of a bug with the MAX option*/
+* Version 2.2 : January 28, 2013 (Jean-Benoit Hardouin) /*noround option*/
+* Version 2.3 : February 19, 2013 (Jean-Benoit Hardouin) /*polytomous items with PMS method*/
+*
+* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2006-2008,2013 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define imputeitems2
+version 9
+syntax varlist(min=2 numeric) [if/] [, PREFix(string) METHod(string) RANDom max(int 0) noround replace]
+
+
+
+if "`noround'" != "" di "noround"
+if "`round'" != "" di "round"
+
+
+
+if "`if'"=="" {
+   local if=1
+   local ifif
+}
+else {
+   local ifif if `if'
+}
+
+*di "IF : `if' `ifif'"
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+
+if `max'==0 {
+   local max=`nbitems'
+}
+
+if "`method'"=="" {
+   local method pms
+}
+forvalues i=1/`nbitems' {
+   qui su ``i'' `ifif'
+   if `r(min)'!=0&(`r(max)'!=1&"`method'"!="pms") {
+       di in red "The {hi:imputeqol} command runs only with dichotomous items"
+       error
+   }
+   local p`i'=r(mean)
+}
+
+if "`method'"!="pms"&"`method'"!="ims"&"`method'"!="cim"&"`method'"!="ics"&"`method'"!="bip"&"`method'"!="bil"&"`method'"!="bic"&"`method'"!="bii"&"`method'"!="log"&"`method'"!="worst" {
+   di in red "The method option is unknow (choose among pms, ims, cim, ics, log and worst)"
+   error
+}
+forvalues i=1/`nbitems'{
+   qui su ``i'' `ifif'
+   local mean`i'=r(mean)
+}
+
+if "`method'"=="pms"&"`random'"!="" {
+   local method bip
+}
+else if "`method'"=="ims"&"`random'"!="" {
+   local method bii
+}
+else if "`method'"=="log"&"`random'"!="" {
+   local method bil
+}
+else if "`method'"=="cim"&"`random'"!="" {
+   local method bic
+}
+else if ("`method'"=="ics"|"`method'"=="worst")&"`random'"!="" {
+   di in green "The random process is not available with the {hi:ics} or {hi:worst} methods. The {hi:random} option is ignored."
+   local random
+}
+
+
+forvalues i=1/`nbitems' {
+   tempvar imp`i' tmp`i'
+   if "`method'"=="pms"|"`method'"=="bip"|"`method'"=="cim"|"`method'"=="bic" {
+      qui egen `imp`i''=rowtotal(`varlist') `ifif'
+      qui egen `tmp`i''=rownonmiss(`varlist') `ifif'
+      qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif'
+      qui replace `imp`i''=``i'' if ``i''!=.&`if'
+      if "`method'"=="pms"&"`round'"=="" {
+          qui replace `imp`i''=round(`imp`i'') `ifif'
+      }
+      else if "`method'"=="bip" {
+          qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+      }
+      else if "`method'"=="cim"|"`method'"=="bic"{
+         qui replace `imp`i''=`imp`i''*`tmp`i''*`mean`i'' `ifif'
+         qui replace `tmp`i''=0 `ifif'
+         forvalues j=1/`nbitems' {
+            qui replace `tmp`i''=`tmp`i''+`mean`j'' if ``j''!=.&`if'
+         }
+         qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif'
+         qui replace `imp`i''=1 if `imp`i''>1&`imp`i''!=.&`if'
+         qui replace `imp`i''=0 if `imp`i''<0&`imp`i''!=.&`if'
+         if "`method'"=="cim"&"`round'"=="" {
+             qui replace `imp`i''=round(`imp`i'') `ifif'
+         }
+         else if "`method'"=="bic" {
+             qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+         }
+      }
+   }
+   else if "`method'"=="ims"|"`method'"=="bii" {
+      qui gen `imp`i''=`mean`i'' `ifif'
+      if "`method'"=="ims"&"`round'"=="" {
+         qui replace `imp`i''=round(`imp`i'') `ifif'
+      }
+      else if "`method'"=="bii" {
+         qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+      }
+   }
+   else if "`method'"=="ics" {
+      local item=0
+      local corrmax=-2
+      forvalues j=1/`nbitems' {
+         if `i'!=`j' {
+            qui corr ``i'' ``j'' `ifif'
+            if r(rho)>`corrmax'&r(rho)!=. {
+               local item `j'
+               local corrmax=r(rho)
+            }
+         }
+      }
+      di "A missing value for the item ``i'' is replaced by the value of the item `item'"
+      qui gen `imp`i''=``i'' `ifif'
+      qui replace `imp`i''=``item'' if ``i''==.&`if'
+   }
+   else if "`method'"=="log"|"`method'"=="bil" {
+      local liste`i'
+      forvalues j=1/`nbitems' {
+         if `i'!=`j' {
+            local liste`i' `liste`i'' ``j''
+         }
+      }
+      qui sw ,pr(0.05): logit ``i'' `liste`i'' `ifif'
+      *local select  :colnames e(b)
+      local select=substr("`:colnames e(b)'",1,length("`:colnames e(b)'")-5)
+      qui logit ``i'' `select' `ifif'
+      qui predict `imp`i'' `ifif'
+      if "`method'"=="log"&"`round'"=="" {
+          qui replace `imp`i''=round(`imp`i'') if `imp`i''!=.&`if'
+      }
+      else if "`method'"=="bil" {
+          qui replace `imp`i''=uniform()<`imp`i'' if `imp`i''!=.&`if'
+      }
+   }
+   else if "`method'"=="worst" {
+      qui gen `imp`i''=0  `ifif'
+   }
+}
+forvalues i=1/`nbitems' {
+   qui replace `imp`i''=``i'' if ``i''!=.&`if'
+   if "`prefix'"=="" {
+      local prefix imp
+   }
+   tempvar `prefix'``i''
+   
+   *di "`prefix'``i''"
+   qui gen ``prefix'``i'''=`imp`i'' `ifif'
+   replace ``i'' = ``prefix'``i'''
+}
+
+tempvar miss
+qui egen `miss'=rowmiss(`varlist')
+forvalues i=1/`nbitems' {
+   qui replace ``prefix'``i'''=. if ``i''==.&`miss'>`max'
+}
+
+end
diff --git a/Modules/ado/personal/i/imputeitems_1.ado b/Modules/ado/personal/i/imputeitems_1.ado
new file mode 100644
index 0000000..4760f0f
--- /dev/null
+++ b/Modules/ado/personal/i/imputeitems_1.ado
@@ -0,0 +1,193 @@
+*! version 2.4 3 May 2013
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* imputeitems: Imputation of missing data of binary items
+*
+* Version 1 : November 25, 2006 (Jean-Benoit Hardouin) /*Dichotomous data*/
+* Version 1.1 : January 26, 2007 (Jean-Benoit Hardouin) /*Correction of a bug with the BIL method*/
+* Version 1.2 : March 9, 2007 (Jean-Benoit Hardouin) /*IF*/
+* Version 2 : June 30, 2008 (Jean-Benoit Hardouin) /*new names of the methods, MAX option*/
+* Version 2.1 : December 3, 2008 (Jean-Benoit Hardouin) /*correction of a bug with the MAX option*/
+* Version 2.2 : January 28, 2013 (Jean-Benoit Hardouin) /*noround option*/
+* Version 2.3 : February 19, 2013 (Jean-Benoit Hardouin) /*polytomous items with PMS method*/
+* Version 2.4 : May 3, 2013 (Jean-Benoit Hardouin) /*minor correction*/
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences  (UPRES EA 4275 SPHERE)
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* News about this program :http://www.anaqol.org
+*
+* Copyright 2006-2008,2013 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define imputeitems
+version 9
+syntax varlist(min=2 numeric) [if/] [, PREFix(string) METHod(string) RANDom max(int -1) noround]
+
+if "`if'"=="" {
+   local if=1
+   local ifif
+}
+else {
+   local ifif if `if'
+}
+
+*di "IF : `if' `ifif'"
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+
+if `max'==-1 {
+   local max=`nbitems'
+}
+
+if "`method'"=="" {
+   local method pms
+}
+forvalues i=1/`nbitems' {
+   qui su ``i'' `ifif'
+   if `r(min)'!=0&(`r(max)'!=1&"`method'"!="pms") {
+       di in red "The {hi:imputeqol} command runs only with dichotomous items"
+       error
+   }
+   local p`i'=r(mean)
+}
+
+if "`method'"!="pms"&"`method'"!="ims"&"`method'"!="cim"&"`method'"!="ics"&"`method'"!="bip"&"`method'"!="bil"&"`method'"!="bic"&"`method'"!="bii"&"`method'"!="log"&"`method'"!="worst" {
+   di in red "The method option is unknow (choose among pms, ims, cim, ics, log and worst)"
+   error
+}
+forvalues i=1/`nbitems'{
+   qui su ``i'' `ifif'
+   local mean`i'=r(mean)
+}
+
+if "`method'"=="pms"&"`random'"!="" {
+   local method bip
+}
+else if "`method'"=="ims"&"`random'"!="" {
+   local method bii
+}
+else if "`method'"=="log"&"`random'"!="" {
+   local method bil
+}
+else if "`method'"=="cim"&"`random'"!="" {
+   local method bic
+}
+else if ("`method'"=="ics"|"`method'"=="worst")&"`random'"!="" {
+   di in green "The random process is not available with the {hi:ics} or {hi:worst} methods. The {hi:random} option is ignored."
+   local random
+}
+
+
+forvalues i=1/`nbitems' {
+   tempvar imp`i' tmp`i'
+   if "`method'"=="pms"|"`method'"=="bip"|"`method'"=="cim"|"`method'"=="bic" {
+      qui egen `imp`i''=rowtotal(`varlist') `ifif'
+      qui egen `tmp`i''=rownonmiss(`varlist') `ifif'
+      qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif'
+      qui replace `imp`i''=``i'' if ``i''!=.&`if'
+      if "`method'"=="pms"&"`round'"=="" {
+          qui replace `imp`i''=round(`imp`i'') `ifif'
+      }
+      else if "`method'"=="bip" {
+          qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+      }
+      else if "`method'"=="cim"|"`method'"=="bic"{
+         qui replace `imp`i''=`imp`i''*`tmp`i''*`mean`i'' `ifif'
+         qui replace `tmp`i''=0 `ifif'
+         forvalues j=1/`nbitems' {
+            qui replace `tmp`i''=`tmp`i''+`mean`j'' if ``j''!=.&`if'
+         }
+         qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif'
+         qui replace `imp`i''=1 if `imp`i''>1&`imp`i''!=.&`if'
+         qui replace `imp`i''=0 if `imp`i''<0&`imp`i''!=.&`if'
+         if "`method'"=="cim"&"`round'"=="" {
+             qui replace `imp`i''=round(`imp`i'') `ifif'
+         }
+         else if "`method'"=="bic" {
+             qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+         }
+      }
+   }
+   else if "`method'"=="ims"|"`method'"=="bii" {
+      qui gen `imp`i''=`mean`i'' `ifif'
+      if "`method'"=="ims"&"`round'"=="" {
+         qui replace `imp`i''=round(`imp`i'') `ifif'
+      }
+      else if "`method'"=="bii" {
+         qui replace `imp`i''=uniform()<`imp`i'' `ifif'
+      }
+   }
+   else if "`method'"=="ics" {
+      local item=0
+      local corrmax=-2
+      forvalues j=1/`nbitems' {
+         if `i'!=`j' {
+            qui corr ``i'' ``j'' `ifif'
+            if r(rho)>`corrmax'&r(rho)!=. {
+               local item `j'
+               local corrmax=r(rho)
+            }
+         }
+      }
+      di "A missing value for the item ``i'' is replaced by the value of the item `item'"
+      qui gen `imp`i''=``i'' `ifif'
+      qui replace `imp`i''=``item'' if ``i''==.&`if'
+   }
+   else if "`method'"=="log"|"`method'"=="bil" {
+      local liste`i'
+      forvalues j=1/`nbitems' {
+         if `i'!=`j' {
+            local liste`i' `liste`i'' ``j''
+         }
+      }
+      qui sw ,pr(0.05): logit ``i'' `liste`i'' `ifif'
+      *local select  :colnames e(b)
+      local select=substr("`:colnames e(b)'",1,length("`:colnames e(b)'")-5)
+      qui logit ``i'' `select' `ifif'
+      qui predict `imp`i'' `ifif'
+      if "`method'"=="log"&"`round'"=="" {
+          qui replace `imp`i''=round(`imp`i'') if `imp`i''!=.&`if'
+      }
+      else if "`method'"=="bil" {
+          qui replace `imp`i''=uniform()<`imp`i'' if `imp`i''!=.&`if'
+      }
+   }
+   else if "`method'"=="worst" {
+      qui gen `imp`i''=0  `ifif'
+   }
+}
+forvalues i=1/`nbitems' {
+   qui replace `imp`i''=``i'' if ``i''!=.&`if'
+   if "`prefix'"=="" {
+      local prefix imp
+   }
+   qui gen `prefix'``i''=`imp`i'' `ifif'
+}
+
+tempvar miss
+qui egen `miss'=rowmiss(`varlist')
+forvalues i=1/`nbitems' {
+   qui replace `prefix'``i''=. if ``i''==.&`miss'>`max'
+}
+
+end
diff --git a/Modules/ado/personal/i/imputemok.ado b/Modules/ado/personal/i/imputemok.ado
new file mode 100644
index 0000000..93d5ece
--- /dev/null
+++ b/Modules/ado/personal/i/imputemok.ado
@@ -0,0 +1,135 @@
+*! version 2.1 24 November 2008
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* impmok: Imputation of missing data by a Mokken model
+*
+* Version 1 : November 25, 2006 (Jean-Benoit Hardouin) /*Dichotomous data*/
+* Version 2 : June 30, 2008 (Jean-Benoit Hardouin) /*MAX option*/
+* Version 2.1 : November 24, 2008 (Jean-Benoit Hardouin) /*correction of a bug with the MAX option*/
+*
+* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://anaqol.free.fr
+* FreeIRT Project : http://freeirt.free.fr
+*
+* Copyright 2006, 2008 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define imputemok , rclass
+version 9
+syntax varlist(min=2 numeric) [, PREFix(string) max(int 0)]
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+if `max'==0 {
+   local max=`nbitems'
+}
+
+
+
+tempname p
+matrix `p'=J(3,`nbitems',0)
+forvalues i=1/`nbitems' {
+   qui su ``i''
+   if `r(min)'!=0&`r(max)'!=1 {
+       di in red "The -impmok- command runs only with dichotomous items"
+       error
+   }
+   local p`i'=r(mean)
+   matrix `p'[1,`i']=`i'
+}
+
+forvalues place=1/`nbitems' {
+   local pmax=0
+   local itemax=0
+   forvalues i=1/`nbitems' {
+      local t=`p'[1,`i']
+      if `p`i''>`pmax'&`t'!=0 {
+         local pmax=`p`i''
+         local itemax=`i'
+      }
+   }
+   matrix `p'[1,`itemax']=0
+   matrix `p'[2,`place']=`itemax'
+   matrix `p'[3,`place']=`pmax'
+}
+local liste
+forvalues i=1/`nbitems' {
+   local t=`p'[2,`i']
+   local liste "`liste' ``t''"
+   tempname imp`i'
+   qui gen `imp`i''`i'=``i''
+}
+forvalues j=`=`nbitems'-1'(-1)1 {
+   local i=`p'[2,`j']
+   local suiv=`p'[2,`=`j'+1']
+   qui replace `imp`i''`i'=1 if `imp`suiv''`suiv'==1&`imp`i''`i'==.
+}
+forvalues j=2/`nbitems'{
+   local i=`p'[2,`j']
+   local prec=`p'[2,`=`j'-1']
+   qui replace `imp`i''`i'=0 if `imp`prec''`prec'==0&`imp`i''`i'==.
+}
+forvalues j=1/`nbitems' {
+   local i=`p'[2,`j']
+   local suiv=`p'[2,`=`j'+1']
+   local prec=`p'[2,`=`j'-1']
+   tempname prec0`i' prec1`i'
+   qui gen `prec0`i''=0
+   qui gen `prec1`i''=0
+   if `j'!=1 {
+      qui replace `prec0`i''=`prec0`prec''+1 if `imp`prec''`prec'==0
+      qui replace `prec0`i''=`prec0`prec'' if `imp`prec''`prec'!=0
+      qui replace `prec1`i''=`prec1`prec''+1 if `imp`prec''`prec'==1
+      qui replace `prec1`i''=`prec1`prec'' if `imp`prec''`prec'!=1
+      qui replace `imp`i''`i'=0 if `prec0`i''!=0&`prec0`i''>=`prec1`i''&`imp`i''`i'==.
+   }
+}
+forvalues j=`nbitems'(-1)1 {
+   local i=`p'[2,`j']
+   local suiv=`p'[2,`=`j'+1']
+   local prec=`p'[2,`=`j'-1']
+   tempname suiv0`i' suiv1`i'
+   qui gen `suiv0`i''=0
+   qui gen `suiv1`i''=0
+   if `j'!=`nbitems' {
+      qui replace `suiv0`i''=`suiv0`suiv''+1 if `imp`suiv''`suiv'==0
+      qui replace `suiv0`i''=`suiv0`suiv'' if `imp`suiv''`suiv'!=0
+      qui replace `suiv1`i''=`suiv1`suiv''+1 if `imp`suiv''`suiv'==1
+      qui replace `suiv1`i''=`suiv1`suiv'' if `imp`suiv''`suiv'!=1
+      qui replace `imp`i''`i'=1 if `suiv0`i''<=`suiv1`i''&`suiv1`i''!=0&`imp`i''`i'==.
+   }
+}
+forvalues j=1/`nbitems' {
+   local i=`p'[2,`j']
+   qui replace `imp`i''`i'=uniform()<=`p`i'' if `imp`i''`i'==.
+   if "`prefix'"=="" {
+      local prefix imp
+   }
+   qui gen `prefix'``i''=`imp`i''`i'
+}
+
+
+tempvar miss
+qui egen `miss'=rowmiss(`varlist')
+forvalues i=1/`nbitems' {
+    qui replace `prefix'``i''=. if ``i''==.&`miss'>`max'
+}
+
+end
diff --git a/Modules/ado/personal/i/imputemok.hlp b/Modules/ado/personal/i/imputemok.hlp
new file mode 100644
index 0000000..a4f96d9
--- /dev/null
+++ b/Modules/ado/personal/i/imputemok.hlp
@@ -0,0 +1,58 @@
+{smcl}
+{* 30June2008}{...}
+{hline}
+help for {hi:imputemok}{right:Jean-Benoit Hardouin}
+{hline}
+
+{title:Imputation of missing item responses with the Mokken scaling}
+
+{p 8 14 2}{cmd:imputemok} {it:varlist} [,{cmdab:pref:ix}({it:string}) {cmdab:max}({it:#})]
+
+
+{title:Description}
+
+{p 4 4 2}{cmd:imputemok} imputes missing item responses with the Mokken scaling as defined in Huisman and Molenaar (2001). This module runs only with dichotomous items.
+
+{p 4 4 2}The following algorithm is used:
+
+{p 8 4 2}First, the items are ordered according to the percentage of positive responses (in a decreasing order).
+
+{p 8 4 2}For each individual, if a positive response follows a missing response, it is imputed to 1.
+
+{p 8 4 2}Else if a negative response precedes a missing response, it is imputed to 0.
+
+{p 8 4 2}Else we count the number of positive and negative responses preceding a missing response and if the number of negative response is larger or equal than the number of positive responses, the missing value is imputed to 0.
+
+{p 8 4 2}Else we count the number of positive and negative responses following a missing response and if the number of positive response is larger or equal than the number of negative responses, the missing value is imputed to 1.
+
+{p 8 4 2}Else, the missing value is imputed by drawing a random number based on the observed proportion of positive responses to the item.
+
+{title:Options}
+
+{p 4 8 2}{cmd:prefix} defines the prefix to use to name the imputted variables (this prefix is followed by the name of the initial variable). By default, this prefix is "imp".
+
+{p 4 8 2}{cmd:max} allows imputing missing values only for individuals with a maximal number of missing values defined with this option.
+
+{title:Example}
+
+	{cmd:. imputemok itemA*}
+
+	{cmd:. imputemok itemA*,prefix(new)}
+
+
+{title:Reference}
+
+{p 4 8 2}{cmd:Huisman M. and Molenaar I. W.}, {it:Imputation of missing scale data with item response models}. In A. Boomsma, M.A.J. van Duijn, & T.A.B. Snijders (Eds.), {it: Essays on item response theory} (pp. 221-244).
+New York: Springer-Verlag, 2001.
+
+{title:Author}
+
+{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
+{p 4 8 2}EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"{p_end}
+{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end}
+{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end}
+{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end}
+{p 4 8 2}Email:
+{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end}
+{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol}
+and {browse "http://www.freeirt.org":FreeIRT}
diff --git a/Modules/ado/personal/i/imputerasch.ado b/Modules/ado/personal/i/imputerasch.ado
new file mode 100644
index 0000000..704e30a
--- /dev/null
+++ b/Modules/ado/personal/i/imputerasch.ado
@@ -0,0 +1,146 @@
+*! version 2 30 June 2008
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* imputerasch: Imputation of missing data by a Rasch model
+*
+* Version 1 : November 25, 2006 (Jean-Benoit Hardouin) /*Dichotomous data*/
+* Version 1.1 : January 26, 2007 (Jean-Benoit Hardouin) /*Correction of a bug with the Binomial option*/
+* Version 2 : June 30, 2008 (Jean-Benoit Hardouin) /*norandom option, max option*/
+*
+* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2006-2008 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define imputerasch
+version 9
+syntax varlist(min=2 numeric) [, PREFix(string) noBINomial noRANDom SAVEProba(string) NBITeration(integer 1) DETails MAX(int 0) ]
+preserve
+qui ds
+local order=r(varlist)
+local nbitems : word count `varlist'
+tokenize `varlist'
+
+if `max'==0 {
+   local max=`nbitems'
+}
+
+if "`random'"!="" {
+   local binomial nobinomial
+}
+
+if "`binomial'"==""&`nbiteration'!=1 {
+   local binomial nobinomial
+   di in green "You must use the {hi:norandom} option when you use iterative process. This option is assumed."
+}
+
+if `nbiteration'!=1 {
+   di in ye  "Iteration : 1"
+}
+
+tempvar lt0 lt1 score id item lt name
+qui gen `id'=_n
+qui egen `score'=rowtotal(`varlist')
+forvalues i=1/`nbitems' {
+   qui rename ``i'' `name'`i'
+}
+
+qui reshape  long `name' ,i(`id') j(`item')
+forvalues i=1/`nbitems' {
+   qui gen ``i''=`item'==`i'
+}
+qui gllamm  `name' `varlist' ,family(bin) nocons link(logit) i(`id') it(1)
+qui gllapred `lt' ,u
+qui bysort `id':egen `lt'=min(`lt'm1)
+drop `lt's1 `lt'm1
+tempname diff
+matrix `diff'=e(b)
+drop `varlist'
+qui reshape  wide `name' ,i(`id') j(`item')
+forvalues i=1/`nbitems' {
+   qui rename `name'`i' ``i''
+   tempvar imp`i'
+   local diff`i'=`diff'[1,`i']
+   qui gen `imp`i''=exp(`lt'-`diff`i'')/(1+exp(`lt'-`diff`i''))
+   if "`saveproba'"!="" {
+      qui gen `saveproba'``i''=`imp`i''
+   }
+   if "`binomial'"!="" {
+       qui replace `imp`i''=round(`imp`i'')
+   }
+   else {
+       qui replace `imp`i''=uniform()<`imp`i''
+   }
+}
+
+
+restore,not
+forvalues i=1/`nbitems' {
+   qui replace `imp`i''=``i'' if ``i''!=.
+   if "`prefix'"=="" {
+      local prefix imp
+   }
+   qui gen `prefix'``i''=`imp`i''
+}
+
+if "`details'"!="" {
+  forvalues i=1/`nbitems' {
+     qui count if ``i''==.
+     local nbmiss`i'=r(N)
+     di in ye "``i'':" in gr " Number of missing data: " in ye "`nbmiss`i''"
+  }
+}
+if `nbiteration'>1 {
+   local flag=0
+   local it=2
+   tempname p new
+   while `flag'!=1&`it'<=`nbiteration' {
+      di in ye "Iteration : `it'"
+      imputerasch `prefix'`1'-`prefix'``nbitems'', savep(`p') prefix(`new') nobin
+      local flag=1
+      forvalues i=1/`nbitems' {
+         qui replace `new'`prefix'``i''=round(`p'`prefix'``i'') if ``i''==.
+         qui corr `prefix'``i'' `new'`prefix'``i''
+         local rho=round(r(rho)*1000000)
+         qui count if `prefix'``i''==`new'`prefix'``i''&``i''==.
+         qui count if ``i''==.
+         local nbmiss`i'=r(N)
+         local coher=r(N)
+         local txcoher=`coher'/`nbmiss`i''*100
+         di in ye "``i'':" in gr " Coherence rate between iterations `it' and `=`it'-1': " in ye %6.2f `txcoher' in gr "%"
+         if int(`txcoher')!=100 {
+            local flag=0
+         }
+         qui replace `prefix'``i''=`new'`prefix'``i''
+      }
+      drop `p'`prefix'`1'-`p'`prefix'``nbitems'' `new'`prefix'`1'-`new'`prefix'``nbitems''
+      local ++it
+   }
+}
+
+tempvar miss
+qui egen `miss'=rowmiss(`varlist')
+forvalues i=1/`nbitems' {
+   qui replace `prefix'``i''=. if ``i''==.&`miss'>`max'
+}
+
+end
diff --git a/Modules/ado/personal/i/imputerasch.hlp b/Modules/ado/personal/i/imputerasch.hlp
new file mode 100644
index 0000000..8e38e21
--- /dev/null
+++ b/Modules/ado/personal/i/imputerasch.hlp
@@ -0,0 +1,63 @@
+{smcl}
+{* 30june2008}{...}
+{hline}
+help for {hi:imputerasch}{right:Jean-Benoit Hardouin}
+{hline}
+
+{title:Imputation of missing binary variables by a Rasch model}
+
+{p 8 14 2}{cmd:imputerasch} {it:varlist} [{cmd:,} {cmdab:pref:ix}({it:string}) {cmdab:noran:dom} {cmdab:savep:roba}({it:string}) {cmdab:nbit:eration}({it:#}) {cmdab:det:ails} {cmdab:max}({it:#})]
+
+{p 8 14 2}{it:varlist} is a list of two or more existing dichotomous variables.
+
+{title:Description}
+
+{p 4 8 2}{cmd:imputerasch} imputes missing binary data by a Rasch model. 
+The parameters of the Rasch model are estimated on complete data, then the missing data are imputed from the  estimated probability 
+for each individual to response to each item.
+By default, the imputed value is a result of a random draw within a Bernouilli random variable with this probability used like 
+parameter, but it is possible to affect more deterministically the value of the missing data (0 if p<0.5 and 1 if p>=.5) with 
+the {cmd:norandom} option.
+ An iterative procedure can be run in a second time by estimating parameters of the Rasch model on existing and imputing data, 
+ and by eventually correcting missing data at each step (see the {cmd:nbiteration} option).
+ This procedure is stopped as soon the allowed maximal number of iterations is attained, or as soon the imputed values are stable.
+
+{title:Options}
+
+{p 4 8 2}{cmd:prefix}. The former variables (with missing data) are keeped. New variables are created by imputing new values to missing data. 
+The name of these new variables are the names of the former variables preeceded by the prefix defined in this option. By default, this prefix is "imp".
+
+{p 4 8 2}{cmd:norandom} avoids to randomly draw the value of imputation (by default). A deterministic process is used : if the expected probability is <0.5, imputed value is 0, else imputed value is 1 
+(the old name of this option, {cmd:nobinomial}, continues to run).
+
+{p 4 8 2}{cmd:saveproba} allows saving the expected probability in variables whose the names begin by the string defined in this option.
+
+{p 4 8 2}{cmd:nbiteration} realizes an iterative procedure which is stopped as soon as the maximal number of iterations is attained, or as soon as the imputed data are stable.
+
+{p 4 8 2}{cmd:details} gives details on the imputation.
+
+{p 4 8 2}{cmd:max} allows imputing missing values only for individuals with a maximal number of missing values defined with this option.
+
+
+
+{title:Example}
+
+	{inp:. imputerasch item*}
+
+	{inp:. imputerasch item*, norandom saveproba(p) prefix(dataimputed) max(4)}
+
+	{inp:. imputerasch item1-item5, nbiteration(5) details}
+
+
+{title:Author}
+
+{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
+{p 4 8 2}EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"{p_end}
+{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end}
+{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end}
+{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end}
+{p 4 8 2}Email:
+{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end}
+{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol}
+and {browse "http://www.freeirt.org":FreeIRT}
+
diff --git a/Modules/ado/personal/i/irtpoly.ado b/Modules/ado/personal/i/irtpoly.ado
new file mode 100644
index 0000000..ce56d30
--- /dev/null
+++ b/Modules/ado/personal/i/irtpoly.ado
@@ -0,0 +1,414 @@
+program define irtpoly,eclass
+version 11.0
+syntax varlist(min=3 numeric) [if] [in]  [,test Graph group(string) latent(string) REPlace Fixed(string) FIXEDVar(real -1) rsm rasch Last SASOUTput long Covariables(varlist) Covariablemean(varname) noCentered Project(string)]
+preserve
+
+
+capture mkdir "c:/data/irtpoly//`project'/"
+if !_rc {
+   di in green "The directory c:/data/irtpoly//`project' has been created"
+}
+
+local dir="c:/data/irtpoly//`project'/"
+local savegroup=1
+if "`group'"=="" {
+   tempname group
+   local savegroup=0
+}
+local savelatent=1
+if "`latent'"=="" {
+   tempname latent
+   local savelatent=0
+}
+tempvar order
+gen `order'=_n
+tempfile pcmsasfile
+qui save `pcmsasfile'
+qui count `if' `in'
+local nbind=r(N)
+tokenize `varlist'
+local nbitems:word count `varlist'
+local max=0
+forvalues i=1/`nbitems' {
+   qui su ``i''
+   local max`i'=r(max)
+   if `max`i''>`max' {
+      local max=`max`i''
+   }
+}
+tempname freq
+contract `varlist' `covariables' `covariablemean', freq(`freq')
+qui sort `varlist'
+qui outsheet `varlist' `covariables' `covariablemean' `freq' using "`dir'irtpoly_data.txt",replace
+
+drop _all
+if "`fixed'"!="" {
+   capture confirm matrix `fixed'
+   if _rc {
+      di as error "The {hi:`fixed'} matrix does not exist"
+	  error 198
+   }
+   tempname matfix
+   matrix `matfix'=`fixed''
+   qui svmat `matfix'
+   qui rename `matfix'1 estimate
+   qui gen parameter=""
+   order parameter estimate
+   local l=1
+   forvalues j=1/`nbitems' {
+      forvalues m=1/`max`j'' {
+	  	  if "`rasch'"=="" {
+                      qui replace parameter="beta``j''_`m'" in `l'
+	  	  }
+                  else {
+                      qui replace parameter="beta``j''" in `l'
+		  }
+                  local ++l
+	  }
+   }
+   qui outsheet using "`dir'/irtpoly_fixedparameters.txt",replace
+
+}
+drop _all
+qui set obs 1000
+qui generate str txt="%include 'C:\ado\macros SAS\anaqolv48.sas';" in 1
+qui replace txt="%include 'C:\Documents and Settings\Jean-Benoit Hardouin\Mes documents\Boulot JB\Enseignement\ENSAI\2009-2010\macros\gammasymv1.sas';" in 2
+qui replace txt="PROC IMPORT OUT=WORK.data DATAFILE='`dir'irtpoly_data.txt' DBMS=TAB REPLACE;GETNAMES=YES;DATAROW=2; RUN;" in 3
+if "`fixed'"!="" {
+   qui replace txt="PROC IMPORT OUT=WORK.fixed DATAFILE='`dir'irtpoly_fixedparameters.txt' DBMS=TAB REPLACE;GETNAMES=YES;DATAROW=2; RUN;" in 4
+}
+local txt="%anaqol(DATASET=data,ITEMS=`varlist',DETAILS=yes,WEIGHT=`freq',MODEL="
+if "`rsm'"==""&"`rasch'"=="" {
+   local txt `txt'pcm
+}
+else if "`rasch'"!="" {
+   local txt `txt'rasch, TEST=no
+}
+else {
+   local txt `txt'rsm
+}
+if "`fixed'"!="" {
+   local txt `txt',FIXED=fixed
+}
+if `fixedvar'>0 {
+   local txt `txt',FIXEDVAR=`fixedvar'
+}
+if "`fixed'"!=""&"`fixedvar'"!="" {
+   local centered  nocentered
+}
+if "`centered'"!="" {
+   local txt `txt',CENTERED=yes
+}
+if "`covariables'"!="" {
+   local txt `txt',COVARIABLES=`covariables'
+}
+if "`covariablemean'"!="" {
+   local txt `txt',COVARIABLEMEAN=`covariablemean'
+}
+local txt `txt');
+qui replace txt="`txt'" in 10
+qui replace txt="PROC EXPORT DATA= WORK.Out_parameters OUTFILE='`dir'irtpoly_parameters.txt' DBMS=TAB REPLACE;RUN;" in 11
+qui replace txt="PROC EXPORT DATA= WORK.Out_latent OUTFILE='`dir'irtpoly_latent.txt' DBMS=TAB REPLACE;RUN;" in 12
+qui replace txt="PROC EXPORT DATA= WORK.Out_rep OUTFILE='`dir'irtpoly_rep.txt' DBMS=TAB REPLACE;RUN;" in 13
+qui replace txt="PROC EXPORT DATA= WORK.Out_fit OUTFILE='`dir'irtpoly_fit.txt' DBMS=TAB REPLACE;RUN;" in 14
+
+qui outsheet txt using "`dir'irtpoly_pgmsas.txt", replace  nonames noquote
+
+if "`last'"=="" {
+   /*local date=c(current_date)
+   local jour=substr("`date'",1,2)
+   local mois=substr("`date'",4,3)
+   local an=substr("`date'",8,4)
+   if "`mois'"=="Jan" {local moisd 01}
+   if "`mois'"=="Feb" {local moisd 02}
+   if "`mois'"=="Mar" {local moisd 03}
+   if "`mois'"=="Apr" {local moisd 04}
+   if "`mois'"=="May" {local moisd 05}
+   if "`mois'"=="Jun" {local moisd 06}
+   if "`mois'"=="Jul" {local moisd 07}
+   if "`mois'"=="Aug" {local moisd 08}
+   if "`mois'"=="Sep" {local moisd 09}
+   if "`mois'"=="Oct" {local moisd 10}
+   if "`mois'"=="Nov" {local moisd 11}
+   if "`mois'"=="Dec" {local moisd 12}
+   di "`jour' `mois' `an' `moisd'"
+   shell "date" "01/01/2009"
+   */
+   if "`long'"!=""{
+      local cmd winexec
+   }
+   else {
+      local cmd shell
+   }
+   `cmd' "C:\Program Files\SAS\SAS 9.2\SASFoundation\9.2\sas.exe" "`dir'irtpoly_pgmsas.txt" -print "`dir'irtpoly_pgmsas.lst" -nolog
+   *shell "cmd.exe" "date `jour'/`moid'/`an'"
+   if "`long'"!="" {
+      exit
+   }
+   
+}
+if "`sasoutput'"!="" {
+   view "`dir'irtpoly_pgmsas.lst"
+}
+*set trace on
+
+*set trace on
+drop _all
+qui insheet using "`dir'irtpoly_fit.txt"
+qui su value if descr=="-2 Log Likelihood"
+local m2ll=r(mean)
+local ll=-`m2ll'/2
+qui su value if descr=="AIC (smaller is better)"
+local aic=r(mean)
+qui su value if descr=="BIC (smaller is better)"
+local bic=r(mean)
+
+drop _all
+qui insheet using "`dir'irtpoly_parameters.txt"
+tempname parameters separameters
+qui su estimate if parameter=="var"
+local variance=r(mean)
+qui su standarderror if parameter=="var"
+local sevariance=r(mean)
+*set trace on
+local nbcov:word count `covariables'
+forvalues i=1/`nbcov' {
+   local cov`i':word `i' of `covariables'
+   qui su estimate if parameter=="beta`cov`i''"
+   local betacov`i'=r(mean)
+   qui su standarderror if parameter=="beta`cov`i''"
+   local secov`i'=r(mean)
+}   
+*set trace off
+*su
+di in gr "Number of individuals: " in ye `nbind'
+di in gr "Number of items: " in ye `nbitems'
+di in gr "log-likelihood: " in ye %10.4f `ll'
+di in gr "AIC: " in ye %10.4f `aic'
+di in gr "BIC: " in ye %10.4f `bic'
+di
+di
+if "`rsm'"=="" {
+   matrix `parameters'=J(`nbitems',`max',0)
+   matrix `separameters'=J(`nbitems',`max',0)
+   local l=1
+   
+   forvalues i=1/`nbitems' {
+       forvalues j=1/`max`i'' {
+	      if "`fixed'"=="" {
+		     qui su estimate if parameter=="beta``i''_`j'"
+	         matrix `parameters'[`i',`j']=r(mean)
+	         qui su standarderror if parameter=="beta``i''_`j'"
+	         matrix `separameters'[`i',`j']=r(mean)
+		  }
+		  else {
+		     matrix `parameters'[`i',`j']=`fixed'[1,`l']
+		  }
+	      local ++l
+	   }
+   }
+   di in gr "{hline 52}"
+   di in gr "Items" _col(18) "Modality" _col(30) "Estimate" _col(39) "Standard error"
+   di in gr "{hline 52}"
+   forvalues j=1/`nbitems' {
+      di in gr "``j''" _c
+      forvalues m=1/`max`i'' {
+         di _col(25) in gr `m' _col(30) %8.4f in ye `parameters'[`j',`m'] _col(45) %8.4f in ye `separameters'[`j',`m'] 
+      }
+   }
+}
+else {
+   matrix `parameters'=J(`=`nbitems'+`max'-1',1,0)
+   matrix `separameters'=J(`=`nbitems'+`max'-1',1,0)
+   local l=1
+   if "`fixed'"=="" {
+      forvalues i=1/`nbitems' {
+         qui su estimate if parameter=="beta``i''"
+         matrix `parameters'[`i',1]=r(mean)
+         qui su standarderror if parameter=="beta``i''"
+         matrix `separameters'[`i',1]=r(mean)
+         local ++l
+      }
+      forvalues l=`=`nbitems'+1'/`=`nbitems'+`max'-1' {
+         local m=`l'-`nbitems'+1
+         qui su estimate if parameter=="t`m'"
+         matrix `parameters'[`l',1]=r(mean)
+	     local tau`m'=r(mean)
+         qui su standarderror if parameter=="t`m'"
+         matrix `separameters'[`l',1]=r(mean)
+      }
+   }
+   else {
+      matrix `parameters'=`fixed'
+   }	     
+   di in gr "{hline 52}"
+   di in gr "Items" _col(30) "Estimate" _col(39) "Standard error"
+   di in gr "{hline 52}"
+   forvalues j=1/`nbitems' {
+      di in gr "``j''"   _col(30) %8.4f in ye `parameters'[`j',1] _col(45) %8.4f in ye `separameters'[`j',1] 
+   }
+   forvalues l=`=`nbitems'+1'/`=`nbitems'+`max'-1' {
+      di in gr "tau`=`l'-`nbitems''"   _col(30) %8.4f in ye `parameters'[`l',1] _col(45) %8.4f in ye `separameters'[`l',1] 
+   }
+}
+di in gr "{hline 52}"
+di in gr "Variance"   _col(30) %8.4f in ye `variance' _col(45) %8.4f in ye `sevariance' 
+di in gr "{hline 52}"
+forvalues i=1/`nbcov' {
+   di in gr "`cov`i''"   _col(30) %8.4f in ye `betacov`i'' _col(45) %8.4f in ye `secov`i'' 
+}
+if "`covariables'"!="" {
+   di in gr "{hline 52}"
+}
+*matrix list `parameters'
+*fdsjklgvsjf
+
+*set trace on
+
+drop _all
+qui insheet using "`dir'irtpoly_rep.txt"
+qui sort anaqol_id
+qui sort `varlist' `covariables'  `covariablemean'
+qui tempfile pcmsas
+qui rename theta `latent'
+qui rename stderrpred	se`latent'
+qui save `pcmsas',replace
+qui use `pcmsasfile', clear
+qui sort `varlist'
+qui gen anaqol_id=_n
+qui sort anaqol_id
+qui sort `varlist' `covariables' `covariablemean'
+
+/***********************************************
+qui merge 1:1 anaqol_id using "`pcmsas'",nogen
+***********************************************/
+qui merge m:1 `varlist' `covariables' `covariablemean' using "`pcmsas'",nogen
+
+*tempvar group
+*set trace on
+forvalues i=1/`nbcov' {
+   qui replace `latent'=`latent'+`betacov`i''*`cov`i''
+}
+*qui save `latent' using c:\latent.dta
+qui gengroup `latent', det replace continuous newvariable(`group')
+qui su `group'
+local nbgroup=r(max)
+forvalues g=1/`nbgroup' {
+   qui count if `group'==`g'
+   local group`g'=r(N)
+}
+forvalues i=1/`nbitems' {
+   *set trace on
+   tempname freq`i'
+   qui tab  `group' ``i'',matcell(`freq`i'') row nofreq m
+   *matrix list `freq`i''
+   forvalues g=1/`nbgroup' {
+      qui count if `group'==`g'&``i''!=.
+	  local freq`g'_`i'=r(N)
+      forvalues j=0/`max`i'' {
+         matrix `freq`i''[`g',`=`j'+1']=`freq`i''[`g',`=`j'+1']/`freq`g'_`i''
+      }
+   }
+   local D`i'=0
+   forvalues j=0/`max`i'' {
+      local D`i'_`j' exp(`j'*`latent'
+	  forvalues l=1/`j' {
+	      if "`rsm'"=="" {
+		     local D`i'_`j' `D`i'_`j''-`parameters'[`i',`l']
+		  }
+		  else {
+		     local D`i'_`j' `D`i'_`j''-`parameters'[`i',1]
+		  }
+      }
+      if "`rsm'"!="" {
+	     forvalues m=2/`j' {
+    	     local D`i'_`j' `D`i'_`j''-`tau`m''
+     	 }
+	  }
+	  local D`i'_`j' `D`i'_`j'')
+	  local D`i' `D`i''+`D`i'_`j''
+   }
+ }
+ tempvar theta2
+ qui gen `theta2'=0
+ forvalues g=1/`nbgroup' {
+    qui su `latent' if  `group'==`g'
+	local thetag`g'=r(mean)
+	qui replace `theta2'=`thetag`g'' if `group'==`g'
+}
+local colors="blue red green gray pink purple"
+
+*local chi2=0
+forvalues i=1/`nbitems' {
+   local line`i'
+   local scatter`i'
+   tempvar propE``i'' propO``i''
+   qui gen `propE``i'''=0
+   qui gen `propO``i'''=0
+   forvalues j=0/`max`i'' {
+      local color:word `=`j'+1' of `colors'
+      tempvar propE``i''_`j' propO``i''_`j'
+	  *matrix list `parameters'
+      *di "qui gen `propE``i''_`j''=`D`i'_`j''/(`D`i'')"
+      qui gen `propE``i''_`j''=`D`i'_`j''/(`D`i'')
+      *su `propE``i''_`j''
+	  label variable `propE``i''_`j'' "Expected values / modality `j'"
+	  local line`i' `line`i'' (line `propE``i''_`j'' `latent', lcolor(`color') lwidth(thick))
+      qui gen `propO``i''_`j''=0
+	  forvalues g=1/`nbgroup' {
+		  local tmp=`freq`i''[`g',`=`j'+1']
+	      qui replace `propO``i''_`j''=`tmp' if `group'==`g'
+	  }
+	  label variable `propO``i''_`j'' "Observed values / modality `j'"
+	  qui replace `propO``i'''=`propO``i'''+`j'*`propO``i''_`j''
+	  qui replace `propE``i'''=`propE``i'''+`j'*`propE``i''_`j''
+	  local scatter`i' `scatter`i'' (scatter `propO``i''_`j'' `theta2', mcolor(`color'))
+   }
+   qui sort `latent'
+   if "`graph'"!="" {
+      twoway `line`i'' `scatter`i'',name(``i'', replace)
+   }
+   label variable `propE``i''' "Expected values"
+   label variable `propO``i''' "Observed values"
+   if "`graph'"!="" {
+      twoway (line `propE``i''' `latent', lcolor(green) lwidth(thick)) (scatter `propO``i''' `theta2',mcolor(green)),name(``i''2, replace)
+   }
+*set trace on
+if "`test'"!="" {
+local chi2=0
+forvalues g=1/`nbgroup' {
+   qui ttest `propE``i'''=`propO``i''' if `group'==`g'
+   local t`g'=r(t)
+   qui count if `group'==`g'
+   local nb`g'=r(N)
+   di "local chi2=`chi2'+/*`nb`g''**/(`t`g'')^2"
+   local chi2=`chi2'+/*`nb`g''**/(`t`g'')^2
+}
+di "Chi-square statistics: " %8.4f `chi2'
+local pchi2=chi2(`=`nbgroup'-1',`chi2')
+di "p-values: " %8.4f `pchi2'
+}
+}
+*set trace on
+tempfile saveu
+qui keep `order' `latent' se`latent' `group' 
+if `savegroup'==0 {
+    drop `group'
+}
+if `savelatent'==0 {
+    drop `latent'
+    drop se`latent'
+}
+sort `order'
+qui save `saveu' ,replace
+
+restore
+qui gen `order'=_n
+qui sort `order'
+if "`replace'"!="" {
+   capture drop `group'
+   capture drop `latent'
+   capture drop se`latent'
+}
+qui merge 1:1 `order' using `saveu',nogen 
+end
diff --git a/Modules/ado/personal/i/isvar.ado b/Modules/ado/personal/i/isvar.ado
new file mode 100644
index 0000000..bf43346
--- /dev/null
+++ b/Modules/ado/personal/i/isvar.ado
@@ -0,0 +1,27 @@
+*! NJC 1.0.0 19 Sept 2005 
+program isvar, rclass  
+	version 8 
+	syntax anything 
+	
+	foreach v of local anything { 
+		capture unab V : `v' 
+		if _rc == 0 local varlist `varlist' `V' 
+		else        local badlist `badlist' `v'  
+	}
+
+	di 
+
+	if "`varlist'" != "" { 
+		local n : word count `varlist' 
+		local what = plural(`n', "variable") 
+		di as txt "{p}`what': `varlist'{p_end}" 
+		return local varlist "`varlist'" 
+	}	
+	
+	if "`badlist'" != "" {
+		local n : word count `badlist' 
+		local what = plural(`n', "not variable") 
+		di as txt "{p}`what': `badlist'{p_end}" 
+		return local badlist "`badlist'" 
+	}	
+end 
diff --git a/Modules/ado/personal/k/kapci.ado b/Modules/ado/personal/k/kapci.ado
new file mode 100644
index 0000000..baf1a18
--- /dev/null
+++ b/Modules/ado/personal/k/kapci.ado
@@ -0,0 +1,495 @@
+* version 1.0.5 23set2004  MER  version 8.0
+capture program drop kapci
+program define kapci, rclass byable(recall)
+	version 8.0
+
+
+	if "`1'" == "" {
+		di _n in gr "  Syntax is:" _n
+		di    in wh "     kapci " in gr "[varlist] [if] [in] , [ " 		_c
+		di    in wh "est" in gr "im(" in wh "an bc p n bsall" in gr ") "
+		di    in wh _col(22) "w" in gr "gt" 					_c
+                di    in gr "(" in wh "w w2 any_wgt" in gr ") " 			_c
+                di    in wh "r" in gr "eps(" in wh "#" in gr ") " 			_c
+                di    in wh "si" in gr "ze(" in wh "#" in gr ") "		
+		di    in wh _col(22) "se" in gr "ed(" in wh "#" in gr ") "		_c
+		di    in wh "ev" in gr "ery(" in wh "#" in gr ") "			_c		
+		di    in wh "le" in gr "vel(" in wh "#" in gr ") " 			_c
+		di    in wh "t" in gr "ab " in wh "w" in gr "ide"			
+  		di    in wh _col(22) "sa" in gr "ving(" in wh "filename" in gr ") " 	_c
+  		di    in wh "replace nom" in gr "sg ]"
+	exit
+	}
+
+
+* Setup
+
+	version 8
+	syntax varlist [if] [in] [ , Reps(numlist) SIze(numlist) SEed(numlist)  	///
+		EVery(numlist) Wgt(str) ESTim(str) Level(integer $S_level) 		///
+	        SAving(str) REPLACE Tab WIDE NOMsg ]
+
+
+	if "`options'" ~= "" { 
+		local options = ", `options'" 
+	}
+	tokenize "`varlist'"
+	marksample touse
+
+	preserve
+
+    	if "`if'"!="" {
+       		keep `if'
+    	} 
+    	if ("`in'"!="") {
+       		keep `in'
+    	}
+
+
+* Level value, etc.
+
+	global zsc = invnorm(1-(1-`level'/100)/2)
+	global N = _N
+
+
+* Checking if estim=an is compatible with data
+
+		qui inspect `1'
+		local numlev `r(N_unique)'
+		local nummeas : word count `varlist'	
+		if `numlev' < 3  & `nummeas' < 3 { 
+			local bs 0 
+		}
+			else local bs 1
+
+	if "`estim'" == "an" & `bs' == 1 { 
+		di in gr "  "
+		di in gr "Note: Option " in wh "estim(an) " in gr "is only suitable for 2x2 data."
+		di in wh "      bs " in gr " will be used."
+	}
+
+* Defaults
+
+	if ("`estim'" == "") & (`bs' == 0) {
+		local estim "an" 
+	}
+	if ("`estim'" == "") & (`bs' == 1) { 
+		local estim "bc" 
+	}	 
+	
+
+*************************************
+* Displaying table if it is requested
+*************************************
+
+	if "`wide'" ~= "" {
+		local wide_str ", wrap"
+	}
+	if "`wide'" == "" {
+		local wide_str ""
+	}	
+
+	if ("`tab'" ~= "") & (`nummeas' < 3) {
+		tab `varlist' if `touse' `wide_str'
+	}
+	if ("`tab'" ~= "") & (`nummeas' >= 3) {
+		tab2 `varlist'if `touse' `wide_str'
+	}
+
+
+****************************************************
+* Calculating analytical CI for kappa when estim=an
+****************************************************
+
+if (`bs' == 0) & ("`estim'" == "an") {		/*  Start of no bs situation */
+
+
+* First ... extracting effective sample size used (noting byable!)
+
+	qui summ `varlist' if `touse'
+	local N = `r(N)'
+
+	
+* Call kappa and get midpoints
+
+	qui kap `varlist' if `touse' `options'
+
+
+* Saving scalars from kap as locals for return list
+
+	local prop_e = r(prop_e)
+	local prop_o = r(prop_o)
+
+
+* Working macro ...
+
+	local k = r(kappa)
+
+
+* Extract table data 
+
+	tempname tab2x2 a b c d agrN
+	qui tab2 `varlist' , matcell(`tab2x2')
+
+	scalar `a'=`tab2x2'[1,1]
+	scalar `b'=`tab2x2'[1,2]
+	scalar `c'=`tab2x2'[2,1]
+	scalar `d'=`tab2x2'[2,2]
+	scalar `agrN'=`a'+`b'+`c'+`d'
+
+
+* Locals - marginals
+
+	local p1 = (`a'+`b')/`agrN' 
+	local p2 = (`a'+`c')/`agrN' 
+
+
+* Quantity Q based on Fleiss, (1981), equations 13.15 - 13.18
+
+
+ 	local Q = ( ( ( (-1 + `k' ) * ( (-2*`k' *`p1' ) +          	/*    
+*/	  	    ((`k' ^2)*`p1' ) + (4*`k' *(`p1'^2)) -        	/*
+*/	  	    (2*(`k'^2)*(`p1'^2)) - (2*`k' *`p2' ) +     	/*
+*/	  	    ((`k'^2)*`p2' ) - (4*`p1' *`p2' ) +           	/*
+*/	  	    (8*`k' *`p1' *`p2' ) - (6*(`k'^2)*`p1' *`p2' ) +	/*
+*/	  	    (4*(`p1'^2)*`p2' ) - (12*`k' *(`p1'^2)*`p2' ) +  	/*
+*/	  	    (8*(`k'^2)*(`p1'^2)*`p2' ) + (4*`k' *(`p2'^2)) - 	/*
+*/	  	    (2*(`k'^2)*(`p2'^2)) + (4*`p1' *(`p2'^2)) -     	/*
+*/	  	    (12*`k' *`p1' *(`p2'^2)) +                       	/*
+*/	  	    (8*(`k'^2)*`p1' *(`p2'^2)) -                   	/*
+*/	  	    (4*(`p1'^2)*(`p2'^2)) +                        	/*
+*/	  	    (12*`k' *(`p1'^2)*(`p2'^2)) -                  	/*
+*/	  	    (8*(`k'^2)*(`p1'^2)*(`p2'^2)))                   	/*
+*/	  	    ) /  ( (`p1'  + `p2'  - (2*`p1' *`p2' ) )^2 ) ) )
+
+
+* Standard error, given kappa estimate  k_hat=`k' 
+
+	local sek = (sqrt(`Q')) / (sqrt(`agrN') )
+
+
+* CI
+
+	local klow = `k'-($zsc*`sek')
+	local kup = `k'+($zsc*`sek')
+
+	if `kup' >= 1 {
+		local kup = 1
+	}
+	if `klow' < -1 {
+		local klow = -1
+	}
+
+
+* Display 
+
+   	local type "analytical "
+	local typeab "A"
+
+	di _n in gr _col(42) "N=" `N' 
+	di    in gr "{hline 48}" 
+   	di    in gr " Kappa (" %2.0f `level' "% CI) = " in ye  %5.3f `k'	_c
+   	di    in gr _col(24) " ("  in ye %5.3f `klow' in gr " - "  in ye %5.3f `kup' in gr ")" _c
+   	di    in gr _col(44) "(" "`typeab'" ")"
+        di    in gr "{hline 48}"  	
+        di    in gr _col(2) "`typeab'" " = " "`type'"	
+
+
+* Return list
+
+	return scalar   N = `agrN'
+	return scalar   z = $zsc
+	return scalar   se = `sek'
+	return scalar   prop_o = `prop_o'	
+	return scalar   prop_e = `prop_e'	
+	return scalar   ub_an = `kup'
+	return scalar   lb_an = `klow'
+	return scalar	kappa = `k'
+
+		
+} 	/* End of no bs situation */
+
+
+
+*****************************************************
+* Calculating analytical CI for kappa when estim!=an
+*****************************************************
+
+if (`bs' == 1)  | ((`bs' == 0) & ("`estim'" ~= "an")) {		/*  Start of bs situation */
+ 
+      if "`estim'" ~= "an" {
+	if "`estim'" ~= "" {
+	  if "`estim'" ~= "bc" {
+	    if "`estim'" ~= "n" {
+	      if "`estim'" ~= "p" {
+                if "`estim'" ~= "bsall" {
+		     local estim "bc"
+		     di in bl " "
+		     di in bl "Note: Unknown bs CI type specified." 
+		     di in wh "      bc " in gr "will be used." 
+	        }
+	      }
+	    }
+	  }
+	}
+      }
+      if "`estim'" == "an" { 
+      	  local estim "bc" 
+      }
+      
+
+* Preparing ...
+
+  tempfile mainfile 		
+  qui save `mainfile', replace
+  qui use `mainfile', clear
+  
+  tempfile tmpsave0 tmpsave1
+  local byindex = _byindex()
+
+  *----------------------------------------------------------------------------
+  if ("`saving'" ~= "") & (_by()==1) { 
+  	local sa_str "saving(`tmpsave1')" 
+  }
+  if ("`saving'" ~= "") & (_by()==0) { 
+  	local sa_str "saving(`tmpsave0')" 
+  }
+  if "`saving'" == ""  & (_by()==0) { 
+  	local sa_str "" 
+  }
+  *----------------------------------------------------------------------------
+  if "`wgt'" ~= "" { 
+  	local wgt_str "wgt(`wgt')"
+   }
+  local n : word count `varlist'
+  if `n' > 2 & "`wgt'" ~= "" { 
+	di _n in gr "Note: wgt() not allowed if varlist > 2. Option ignored." 
+	local wgt_str ""
+  }
+  if "`wgt'" == "" { 
+  	local wgt_str "" 
+  }
+  *----------------------------------------------------------------------------
+  if "`reps'" ~= "" { 
+  	local reps_str "reps(`reps')" 
+  }
+  if "`reps'" == "" { 
+  	local reps_str "reps(5)" 
+  	local reps 5
+  	di _n in gr "Note: default number of bootstrap replications "		_c
+	di    in gr "has been  						
+  	di    in gr "      set to " in wh "5 " in gr "for syntax testing only."	_c
+  	di    in wh "reps() " in gr "needs to "
+  	di    in gr "      be increased when analysing real data." 		_n					
+  }
+  *----------------------------------------------------------------------------
+  if "`seed'" ~= "" { 
+  	set seed `seed' 
+  	local seed_str "seed(`seed')"
+  }
+  *----------------------------------------------------------------------------
+  if "`size'" ~= "" { 
+  	if `size' < 5 { 
+  		di in gr "Note: size() set to N"
+  		local size $N
+  	}
+  	local size_str "size(`size')"
+  }
+  if "`size'" == "" { 
+  	local size_str "" 
+  	local size $N
+  }
+  *----------------------------------------------------------------------------
+  if "`every'" ~= "" { 
+  	local every_str "every(`every')" 
+  }
+  if "`every'" == "" { 
+  	local every_str ""
+  }
+  *----------------------------------------------------------------------------
+   if _by()==0 {
+   	local first "kap `varlist' , `wgt_str'"
+   }
+   if _by()==1 {
+   	local first "kap `varlist' if `touse' , `wgt_str'"
+   }
+
+
+* Calling bs
+	
+   if `reps' > 100 & "`nomsg'" == "" { 
+  	di _n in gr "This may take quite a long time. Please wait ..." 
+   }
+
+   qui bs " `first' " r(kappa), `reps_str' `sa_str' level(`level') `size_str' `every_str' nowarn
+
+   if ("`saving'" ~= "") & (_by()==0) {
+  	qui use `tmpsave0'
+	qui label data "kapci: varlist is `varlist'"
+	qui rename _bs_1 _kapci_bs
+	label var _kapci_bs "Options: `wgt_str' `reps_str' `seed_str' `size_str' `every_str'" 
+	qui save `saving', `replace'
+	restore
+   }
+
+      if ("`saving'" ~= "") & (_by()==1) {
+  	qui use `tmpsave1'
+	qui label data "kapci: varlist is `varlist'; byvars is `_byvars'; by-group is (`byindex')"
+	qui rename _bs_1 _kapci_bs__`byindex'
+	label var _kapci_bs__`byindex' "Options: `wgt_str' `reps_str' `seed_str' `size_str' `every_str'" 
+	qui save `saving'`byindex', `replace'
+	restore
+   }
+
+
+* Extracting sample size used (noting byable !)
+
+   qui summ `varlist' if `touse'
+   local N = `r(N)'
+
+
+* Matrix extraction
+
+   matrix tmp_mtx = e(b)
+   local k = tmp_mtx[1,1]
+
+   matrix tmp_mtx = e(ci_bc)
+   local klow_bc = tmp_mtx[1,1]
+   local kup_bc = tmp_mtx[2,1]   
+
+   matrix tmp_mtx = e(ci_percentile)
+   local klow_p = tmp_mtx[1,1]
+   local kup_p = tmp_mtx[2,1]    
+
+   matrix tmp_mtx = e(ci_normal)
+   local klow_n = tmp_mtx[1,1]
+   local kup_n = tmp_mtx[2,1]  
+
+   matrix tmp_mtx = e(reps)
+   local numreps = tmp_mtx[1,1]   
+
+   matrix tmp_mtx = e(bias)
+   local bias = tmp_mtx[1,1]
+
+   matrix tmp_mtx = e(se)
+   local se = tmp_mtx[1,1]
+   matrix drop tmp_mtx
+
+   
+* Display 
+
+   local dotdot "{hline 48}" 
+   local col1 "_col(34)"
+   local col2 "_col(43)"
+
+   if "`estim'" ~= "bsall" {
+
+	if "`estim'" == "bc" {
+		local klow = `klow_bc'
+		local kup  = `kup_bc'
+	}
+	
+	if "`estim'" == "n" {	
+		local klow = `klow_n'
+		local kup  = `kup_n' 
+	}
+
+	if "`estim'" == "p" {	
+		local klow = `klow_p'
+		local kup  = `kup_p' 
+	}
+
+	if (`kup' >= 1) & (`kup' ~= .) {
+		local kup = 1
+	}
+	if (`klow' < -1) & (`klow' ~= .) {
+		local klow = -1
+	}
+
+   	if "`estim'" == "bc" { 
+   		local type "bias corrected " 
+   		local typeab "BC"
+   		}
+
+     	if "`estim'" == "n" { 
+   		local type "normal " 
+   		local typeab "N"
+   		}
+
+   	if "`estim'" == "p"  { 
+   		local type "percentile " 
+   		local typeab "P"
+   		}
+
+
+	di _n in gr _col(34) "B=" `numreps' _col(42) "N=" `N' 
+	di    in gr "{hline 48}" 
+   	di    in gr " Kappa (" %2.0f `level' "% CI) = " in ye  %5.3f `k'	_c
+   	di    in gr _col(24) " ("  in ye %5.3f `klow' in gr " - "  in ye %5.3f `kup' in gr ")" _c
+   	di    in gr _col(44) "(" "`typeab'" ")"
+        di    in gr "{hline 48}"  	
+        di    in gr _col(2) "`typeab'" " = " "`type'"
+
+   }
+
+
+
+   if "`estim'" == "bsall" {
+
+	if `kup_n' >= 1 {
+		local kup_n = 1
+	}
+	if `klow_n' < -1 {
+		local klow_n = -1
+	}
+
+	local type1 "bias corrected" 
+	local typeab1 "BC"
+   	local type2 "percentile" 
+	local typeab2 "P"
+ 	local type3 "normal"
+ 	local typeab3 "N" 
+
+
+	di _n in gr _col(34) "B=" `numreps' _col(42) "N=" `N' 
+	di    in gr "{hline 48}" 
+   	di    in gr " Kappa (" %2.0f `level' "% CI) = " in ye  %5.3f `k'	_c
+   	di    in gr _col(24) " ("  in ye %5.3f `klow_bc' in gr " - " in ye %5.3f `kup_bc' in gr ")"  _c
+   	di    in gr _col(44) "(" "`typeab1'" ")"
+   	di    in gr _col(24) " ("  in ye %5.3f `klow_p' in gr " - " in ye %5.3f `kup_p' in gr ")"    _c
+   	di    in gr _col(44) "(" "`typeab2'" ")"  
+   	di    in gr _col(24) " ("  in ye %5.3f `klow_n' in gr " - " in ye %5.3f `kup_n' in gr ")"    _c
+   	di    in gr _col(44) "(" "`typeab3'" ")" 
+        di    in gr "{hline 48}"  	
+        di    in gr _col(2) "`typeab1'" " = " "`type1'" ", "					     _c
+        di    in gr "`typeab2'" " = " "`type2'" ", "						     _c
+        di    in gr "`typeab3'" " = " "`type3'"
+
+   }   
+
+* Return list
+
+	return scalar   N_bs = `size'
+	return scalar   N = $N
+	return scalar   z = $zsc
+	return scalar   reps = `numreps' 
+	return scalar   bias = `bias' 
+	return scalar   se = `se'   
+	return scalar   lb_n = `klow_n' 
+	return scalar   ub_n = `kup_n' 
+	return scalar   lb_p = `klow_p' 
+	return scalar   ub_p = `kup_p' 
+	return scalar   lb_bc = `klow_bc'
+	return scalar   ub_bc = `kup_bc'
+	return scalar   kappa = `k'   
+
+}	/*  End of no bs situation */
+
+
+* Cleaning up
+
+   macro drop zsc 
+   macro drop N
+
+end
+
diff --git a/Modules/ado/personal/k/kgv.ado b/Modules/ado/personal/k/kgv.ado
new file mode 100644
index 0000000..e46be43
--- /dev/null
+++ b/Modules/ado/personal/k/kgv.ado
@@ -0,0 +1,212 @@
+capture program drop kgv
+program kgv,rclass
+syntax varlist, categ(varlist) [KGVBoxplots KGVGroupboxplots]
+	
+local i = 1
+local j = 1	
+local k = 0
+local max = 0
+local a : word count `categ'
+local nb:word count `varlist'
+
+di as result "{hline}"
+di "{bf:Known-groups validity}"
+di as result "{hline}"
+di
+	
+foreach sco in `varlist' {
+	foreach cat in `categ' {
+		local nblev = 0
+		local maxlen`j' = 0
+		qui anova `sco' `cat'
+		local p`i'_`j' =  Ftail(e(df_m), e(df_r), e(F))
+		qui levelsof `cat', local(levels) 
+		local lbe : value label `cat'
+			
+		foreach l of local levels {
+			qui count if `sco' !=. & `cat' == `l'
+			local `++k'
+			local eff`i'_`j'_`k' = r(N)
+			
+			if "`lbe'" != "" {
+				local ll`j'_`k' : label `lbe' `l'
+				local len = length("`ll`j'_`k''")
+				if `len' > 10 {
+					local c = substr("`ll`j'_`k''",1,9)
+					local d = substr("`ll`j'_`k''",-1,1)
+					local ll`j'_`k' "`c'" "~" "`d'" 
+				}
+				local w = length("`ll`j'_`k''")
+				if `w' > `maxlen`j'' local maxlen`j' = `w'
+			}
+			else {
+				local ll`j'_`k' = `l'
+				local len = length("`ll`j'_`k''")
+				if `len' > 10 {
+					local c = substr("`ll`j'_`k''",1,9)
+					local d = substr("`ll`j'_`k''",-1,1)
+					local ll`j'_`k' "`c'" "~" "`d'" 
+				}
+				local w = length("`ll`j'_`k''")
+				if `w' > `maxlen`j'' local maxlen`j' = `w'
+			}
+			qui su `sco' if `cat' == `l'
+			local m`i'_`j'_`k' = r(mean)
+			local s`i'_`j'_`k' = r(sd)
+			local nblev = `nblev' + 1
+		}
+		if `nblev' > `max' local max = `nblev'
+		local `++j'
+		local k = 0
+	}
+	local `++i'
+	local j = 1
+}
+
+
+/* coupure noms des scores */
+/*
+local i = 1
+foreach s in `varlist' {
+	local len = length("`s'")
+	if `len' > 10 {
+		local c = substr("`s'",1,9)
+		local d = substr("`s'",-1,1)
+		local s`i' "`c'" "~" "`d'" 
+	}
+	else local s`i' = "`s'"
+	local sc `sc' `s`i''
+	local `++i'
+}
+*/
+local i = 1
+foreach s in `varlist' {
+	local s`i' = abbrev("`s'",7)
+	local sc `sc' `s`i''
+	local `++i'
+}
+
+/*
+local max = 0
+foreach s in `scorename' {
+	local len = length("`s'")
+	if `len' > `max' local max = `len'
+}
+*/
+
+local maxs = 0
+forvalues j=1/`nb' {
+	local len`j' = length("`s`j''")
+	if `len`j'' > `maxs' local maxs = `len`j''
+}
+
+local i = 1
+local k = 0
+local j = 2
+
+foreach cat in `categ'{
+	local `++k'
+	tokenize `categ'
+	local c`k' = "``i'' ``j''"
+	local i = `i' + 2 
+	local j = `j' + 2 
+}
+
+
+local d = 1
+local f = 2
+forvalues h = 1/`a' {
+	if `f' > `a' local f = `f'-1
+	local j = 1
+	local col =  `maxs'+6
+	foreach cat in `c`h'' {
+		di _col(`col') "{bf:`cat'}" _c
+		local col = `col' + `maxlen`j'' + 5 + 40
+		local `++j'
+	}
+	di
+
+	local j = `d'
+	local col = `maxs'+6
+	foreach cat in `c`h'' {
+		di _col(`=`col'+`maxlen`j''+5') "{bf:      mean    }" _c
+		di "{bf:standard    }" _c
+		di "{bf:p-value}" _c
+		    
+		local col = `col' + `maxlen`j'' + 5 + 40
+		local `++j'
+	}
+	di
+	
+	local j = `d'
+	local col = `maxs'+6
+
+	foreach cat in `c`h'' {
+		di _col(`=`col'+`maxlen`j''+6') "{bf:             error}"_c 
+		local col = `col' + `maxlen`j'' + 5 + 40
+		local `++j'
+	}
+	
+	
+	di
+	di
+	local i = 1
+	local col = `maxs'+6
+
+	forvalues g = 1/`nb' {
+		
+		di "{bf:`s`g''}" _c
+		forvalues k = 1/`max' {
+			forvalues j = `d'/`f' {
+			
+				di _col(`col') "{bf:`ll`j'_`k''} " _c
+				if "`eff`i'_`j'_`k''" != "" di as text "(n=`eff`i'_`j'_`k'')" _c
+				local m : di %6.2f `m`i'_`j'_`k''
+				di _col(`=`col'+`maxlen`j''+10') "{text:`m'}  " _c
+					
+				local s : di %8.2f `s`i'_`j'_`k''
+				di "{text: `s'}  " _c
+					
+				if `k' == 1 {
+					local p : di %8.3f `p`i'_`j''
+					di _col(`=`col'+31') "{text:`p'}  " _c
+				}
+				local col = `col' + `maxlen`j'' + 5 + 40
+			}
+			di
+			local col = `maxs'+6
+		
+		}
+		di 
+		
+	local `++i'
+
+	}
+	local d = `d'+2
+	local f = `f'+2
+	if `d' > `a' continue, break
+	di
+}
+
+if "`kgvboxplots'" != "" {
+	*qui set autotabgraphs on
+	if "`kgvgroupboxplots'" != "" {
+		foreach c in `categ' {
+			foreach s in `varlist' {
+				graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c'") nodraw
+				local g `g' `s'_`c' 
+			}
+		}
+		gr combine `g', name(Known_groups_validity,replace)
+	}
+	else {
+		foreach c in `categ' {
+			foreach s in `varlist' {
+				graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c'")
+				local g `g' `s'_`c' 
+			}
+		}
+	}
+}
+end
+*kgv HA-MOC, categ(radio chim) //kgvboxplots kgvgroupboxplots // radio_01 etud_01 actu_01)
diff --git a/Modules/ado/personal/l/loevH7.ado b/Modules/ado/personal/l/loevH7.ado
new file mode 100644
index 0000000..b8574d4
--- /dev/null
+++ b/Modules/ado/personal/l/loevH7.ado
@@ -0,0 +1,1168 @@
+*! Version 7 14 June 2007
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Stata program : LoevH
+* Loevinger H indexes, Mokken Analysis
+* Release 7: June 21, 2007  /*Check of  monotonicity and Non intersection via P matrices*/
+*
+* dedication for Stefan Thau - Interuniversity Centre for Social Science Theory and Methodology - University of Groningen
+*
+* Historic :
+* Version 1 (August 20, 2002) [Jean-Benoit Hardouin]
+* Version 2 (June 22, 2003) [Jean-Benoit Hardouin]
+* Version 3 (December 1, 2003) [Jean-Benoit Hardouin]
+* Version 4 (January 20, 2004) [Jean-Benoit Hardouin]
+* Version 5 (March 22, 2004) [Jean-Benoit Hardouin]
+* Version 6 (July 3, 2004) [Jean-Benoit Hardouin]
+* Version 6.1 (September 19, 2005) [Jean-Benoit Hardouin]
+* Version 6.2 (January 31, 2006) [Jean-Benoit Hardouin]
+* Release 6.3 (March 20, 2006) [Jean-Benoit Hardouin]  /*A bug with temporary files */
+* Release 6.4 (January 19, 2007) [Jean-Benoit Hardouin]  /*Tests to compare Loevinger coefficients to 0 identical to the MSP software (dichotomous and polytomous case)*/
+* Release 6.5 (January 22, 2007) [Jean-Benoit Hardouin]  /*Correction of a bug concerning the p-values with the pair option*/
+* Release 6.6 (Februar 16, 2007) [Jean-Benoit Hardouin]  /*Correction of a bug with the displaying of Easyness with polytomous items, option graph, option generror, improvements*/
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* Requiered Stata modules:
+* -anaoption- (version 1)
+* -traces- (version 3.2)
+* -gengroup- (version 1)
+*
+* News about this program :http://www.anaqol.org
+* FreeIRT Project website : http://www.freeirt.org
+*
+* Copyright 2002-2007 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+***********************************************************************************************************
+
+program define loevH , rclass
+version 8.2
+syntax varlist(min=2 numeric) [if] [,PAIRWise PAIR ppp pmm noADJust GENERror(string) REPlace GRaph MONOtonicity(string) NIRESTscore(string) NIPmatrix(string)]
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+tempname corr cov P1 P0 P11 P00 H1jk vHjk zHjk chi2Hjk dfHjk pvalHjk H1j vHj zHj pvalHj H1 vH zH pvalH Obs eGuttjk eGuttjk0 loevHjk eGuttj eGuttj0 loevHj eGutt eGutt0 loevH e1 e2
+tempfile loevHfile
+qui save "`loevHfile'"
+
+if "`if'"!="" {
+   qui keep `if'
+}
+
+if "`adjust'"!="" {
+   local adj=0
+}
+else {
+   local adj=1
+}
+
+preserve
+forvalues j=1/`nbitems' {
+   qui drop if ``j''==.
+   qui count
+   local nbtotindnm=r(N)
+}
+if "`pairwise'"!="" {
+   restore
+}
+
+qui count
+local nbobs=r(N)
+matrix define `eGuttjk'=J(`nbitems',`nbitems',0)
+matrix define `eGuttjk0'=J(`nbitems',`nbitems',0)
+matrix define `loevHjk'=J(`nbitems',`nbitems',0)
+matrix define `eGuttj'=J(1,`nbitems',0)
+matrix define `eGuttj0'=J(1,`nbitems',0)
+matrix define `loevHj'=J(1,`nbitems',0)
+scalar define `eGutt'=0
+scalar define `eGutt0'=0
+scalar define `loevH'=0
+matrix define `Obs'=J(`nbitems',`nbitems',0)
+matrix define `P00'=J(`nbitems',`nbitems',0)
+
+tempname modamax
+scalar `modamax'=0
+local scoremax=0
+forvalues j=1/`nbitems' {
+     qui su ``j''
+     local m`j'=r(max)
+     local scoremax=`scoremax'+`m`j''
+     if r(max)>`modamax' {
+        scalar `modamax'=r(max)
+     }
+     local nbHjkNS`j'=0
+}
+
+if "`generror'"!=""&`modamax'!=1 {
+   di in ye "It is not possible to define the {cmd:generror} option with polytomous items"
+   local generror
+}
+
+matrix define `cov'=J(`nbitems',`nbitems',0)
+matrix define `corr'=J(`nbitems',`nbitems',0)
+matrix define `P11'=J(`nbitems',`nbitems',0)
+matrix define `H1jk'=J(`nbitems',`nbitems',0)
+matrix define `vHjk'=J(`nbitems',`nbitems',0)
+matrix define `zHjk'=J(`nbitems',`nbitems',0)
+matrix define `pvalHjk'=J(`nbitems',`nbitems',0)
+matrix define `P1'=J(1,`nbitems',0)
+matrix define `P0'=J(1,`nbitems',0)
+matrix define `H1j'=J(1,`nbitems',0)
+matrix define `vHj'=J(1,`nbitems',0)
+matrix define `zHj'=J(1,`nbitems',0)
+matrix define `pvalHj'=J(1,`nbitems',0)
+
+forvalues j=1/`nbitems' {
+    qui su ``j''
+    matrix `cov'[`j',`j']=r(Var)
+    matrix `corr'[`j',`j']=1
+    local tmp=`j'+1
+    qui count if ``j''!=.
+    matrix `Obs'[`j',`j']=r(N)
+    forvalues k=`tmp'/`nbitems' {
+        qui count if ``j''!=.&``k''!=.
+        matrix `Obs'[`j',`k']=r(N)
+        matrix `Obs'[`k',`j']=r(N)
+        qui corr ``j'' ``k'',cov
+        matrix `cov'[`j',`k']=r(cov_12)
+        matrix `cov'[`k',`j']=r(cov_12)
+        qui corr ``j'' ``k''
+        matrix `corr'[`j',`k']=r(rho)
+        matrix `corr'[`k',`j']=r(rho)
+        matrix `zHjk'[`j',`k']=`corr'[`j',`k']*(`Obs'[`j',`k']-`adj')^.5
+        matrix `zHjk'[`k',`j']=`H1jk'[`j',`k']
+        matrix `pvalHjk'[`j',`k']=1-norm(`zHjk'[`j',`k'])
+        matrix `pvalHjk'[`k',`j']=`pvalHjk'[`j',`k']
+        if `pvalHjk'[`j',`k']>0.05 {
+           local nbHjkNS`j'=`nbHjkNS`j''+1
+           local nbHjkNS`k'=`nbHjkNS`k''+1
+        }
+        forvalues mod1=1/`m`j'' {
+            forvalues mod2=1/`m`k'' {
+                qui count if ``j''<`mod1'&``k''>=`mod2'&``j''!=.&``k''!=.
+                scalar `e1'=r(N)
+                qui count if ``j''>=`mod1'&``k''<`mod2'&``j''!=.&``k''!=.
+                scalar `e2'=r(N)
+                matrix `eGuttjk'[`j',`k']=`eGuttjk'[`j',`k']+min(`e1',`e2')
+                qui count if ``j''<`mod1'&``j''!=.&``k''!=.
+                local t1=r(N)
+                qui count if ``k''<`mod2'&``j''!=.&``k''!=.
+                local t2=r(N)
+                qui count if ``j''>=`mod1'&``j''!=.&``k''!=.
+                local t3=r(N)
+                qui count if ``k''>=`mod2'&``j''!=.&``k''!=.
+                local t4=r(N)
+                if min(`e1',`e2')==`e1' {
+                    matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t1'*`t4'/`Obs'[`j',`k']
+                }
+                else {
+                    matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t2'*`t3'/`Obs'[`j',`k']
+                }
+
+            }
+        }
+        qui count if ``j''==0&``k''==0
+        matrix `P00'[`j',`k']=r(N)/`Obs'[`j',`k']
+        matrix `P00'[`k',`j']=r(N)/`Obs'[`k',`j']
+        if `modamax'==1 {
+           qui count if ``j''==1&``k''==1
+           matrix `P11'[`j',`k']=r(N)/`Obs'[`j',`k']
+           matrix `P11'[`k',`j']=r(N)/`Obs'[`k',`j']
+        }
+
+        matrix `eGuttjk'[`k',`j']=`eGuttjk'[`j',`k']
+        matrix `eGuttj'[1,`j']=`eGuttj'[1,`j']+`eGuttjk'[`j',`k']
+        matrix `eGuttj'[1,`k']=`eGuttj'[1,`k']+`eGuttjk'[`j',`k']
+        matrix `eGuttjk0'[`k',`j']=`eGuttjk0'[`j',`k']
+        matrix `eGuttj0'[1,`j']=`eGuttj0'[1,`j']+`eGuttjk0'[`j',`k']
+        matrix `eGuttj0'[1,`k']=`eGuttj0'[1,`k']+`eGuttjk0'[`j',`k']
+
+        matrix `loevHjk'[`j',`k']=1-`eGuttjk'[`j',`k']/`eGuttjk0'[`j',`k']
+        matrix `loevHjk'[`k',`j']=`loevHjk'[`j',`k']
+
+    }
+    qui count if ``j''!=.
+    local tmp=r(N)
+    qui count if ``j''==1
+    matrix `P1'[1,`j']=r(N)/`tmp'
+    qui count if ``j''==0
+    matrix `P0'[1,`j']=r(N)/`tmp'
+    matrix `loevHj'[1,`j']=1-`eGuttj'[1,`j']/`eGuttj0'[1,`j']
+    scalar `eGutt'=`eGutt'+`eGuttj'[1,`j']/2
+    scalar `eGutt0'=`eGutt0'+`eGuttj0'[1,`j']/2
+}
+scalar `H1'=0
+scalar `vH'=0
+scalar `zH'=0
+forvalues j=1/`nbitems'{
+   forvalues k=1/`nbitems' {
+      if `j'!=`k' {
+         matrix `zHj'[1,`j']=`zHj'[1,`j']+`cov'[`j',`k']
+         matrix `vHj'[1,`j']=`vHj'[1,`j']+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj')
+      }
+      if `j'<`k' {
+         scalar `zH'=`zH'+`cov'[`j',`k']
+         scalar `vH'=`vH'+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj')
+      }
+   }
+   matrix `zHj'[1,`j']=`zHj'[1,`j']/sqrt(`vHj'[1,`j'])
+   matrix `pvalHj'[1,`j']=1-norm(`zHj'[1,`j'])
+}
+scalar `zH'=`zH'/sqrt(`vH')
+scalar `pvalH'=1-norm(`zH')
+scalar `loevH'=1-`eGutt'/`eGutt0'
+
+if `modamax'==1 {
+   local text="Easyness"
+   local value=1
+   local col=23
+}
+else {
+   local text="Difficulty"
+   local value=0
+   local col=21
+}
+
+
+di in green _col(35) "Observed" _col(47) "Expected" _col(93) "Number"
+di in green _col(`col') "`text'" _col(36) "Guttman" _col(48) "Guttman" _col(59) "Loevinger" _col(83) "H0: Hj<=0" _col(94) "of NS"
+di in green "Item"  _col(15) "Obs" _col(24) "P(Xj=`value')" _col(37) "errors" _col(49) "errors" _col(61) "H coeff" _col(73) "z-stat." _col(85) "p-value" _col(96) "Hjk"
+di in green "{hline 99}"
+forvalues j=1/`nbitems' {
+     di in green "``j''" in yellow _col(15) `Obs'[`j',`j'] _col(25) %6.4f `P`value''[1,`j'] _col(38) %5.0f `eGuttj'[1,`j'] _col(47) %8.2f `eGuttj0'[1,`j'] _col(61) %7.5f `loevHj'[1,`j'] _col(72) %8.4f `zHj'[1,`j'] _col(85) %7.5f `pvalHj'[1,`j'] _col(97) %2.0f `nbHjkNS`j''
+}
+di in green "{hline 99}"
+if "`pairwise'"=="" {
+   local nb=`nbtotindnm'
+}
+else {
+   local nb=`nbobs'
+}
+di in green "Scale" in yellow _col(15) `nb' _col(38) %5.0f `eGutt' _col(47) %8.2f `eGutt0' _col(61) %-8.5f `loevH' _col(71) %9.4f `zH' _col(85) %7.5f `pvalH'
+
+if "`pair'"!="" {
+   di
+   di in green _col(45) "Observed" _col(57) "Expected"
+   di in green _col(`=`col'+10') "`text'" _col(46) "Guttman" _col(58) "Guttman" _col(69) "Loevinger" _col(92) "H0: Hjk<=0"
+   di in green "Items"  _col(25) "Obs" _col(29) "P(Xj=`value',Xk=`value')" _col(47) "errors" _col(59) "errors" _col(71) "H coeff" _col(83) "z-stat." _col(95) "p-value"
+   di in green "{hline 101}"
+   forvalues j=1/`nbitems' {
+      forvalues k=`=`j'+1'/`nbitems' {
+         qui count if ``j''!=.
+         local obs=r(N)
+         di in green "``j''" _col(10) "``k''" in yellow _col(25) `Obs'[`j',`k'] _col(35) %6.4f `P`value'`value''[`j',`k'] _col(48) %5.0f `eGuttjk'[`j',`k'] _col(57) %8.2f `eGuttjk0'[`j',`k'] _col(70) %8.5f `loevHjk'[`j',`k'] _col(81) %9.4f `zHjk'[`j',`k'] _col(95) %7.5f `pvalHjk'[`j',`k']
+      }
+   }
+   di in green "{hline 101}"
+}
+/*if `modamax'>1&"`ppp'"!="" {
+   di in green "It is not possible to obtain the P++ diagnostics with polytomous items"
+   local ppp
+}
+if `modamax'>1&"`pmm'"!="" {
+   di in green "It is not possible to obtain the P-- diagnostics with polytomous items"
+   local pmm
+} */
+
+tempname P11g P00g item id id2 p1 monlabel
+
+/*if "`monotonicity'"!=""&`modamax'>1 {
+   di in green "It is not possible to obtain the latent monotonicity diagnostics with polytomous items"
+   local monotonicity
+}  */
+
+if  "`monotonicity'"!="" {
+*set trace on
+   if "`monotonicity'"=="*" {
+      anaoption
+   }
+   else {
+      anaoption,`monotonicity'
+   }
+   local minvi=r(minvi)
+   local siglevel=r(siglevel)
+   local minsize=r(minsize)
+   local details `r(details)'
+   if `minsize'==0 {
+      if `nbobs'>500 {
+         local minsize=round(`nbobs'/10)
+      }
+      else if `nbobs'>250 {
+         local minsize=round(`nbobs'/5)
+      }
+      else {
+         local minsize=max(50,round(`nbobs'/3))
+      }
+   }
+
+*set trace on
+   tempname score
+   qui genscore `varlist',score(`score')
+   di
+   di in green _col(10) "Summary per item for check of monotonicity"
+   di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel'
+   di
+   di in green "Items"  _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax"  _col(84) "#zsig"  _col(93) "Crit"
+   di in green "{hline 97}"
+*set trace on
+   local vi=0
+   local ac=0
+   local sumvi=0
+   local maxvi=0
+   local zmaxvi=0
+   local nbzvi=0
+   forvalues i=1/`nbitems' {
+      tempname restscore`i'
+      qui gen `restscore`i''=`score'-``i''
+      local restscoremax`i'=`scoremax'-`m`i''
+      tempname restgroup`i'
+      qui gengroup `restscore`i'',newvariable(`restgroup`i'') minsize(`minsize')
+      local list`i'=r(list)
+      qui su `restgroup`i''
+      local nbgroups`i'=r(max)
+      forvalues j=0/`nbgroups`i'' {
+         qui count if `restgroup`i''==`j'
+         local rgroup`j'=r(N)
+      }
+      local vi`i'=0
+      local ac`i'=0
+      local sumvi`i'=0
+      local maxvi`i'=0
+      local zmaxvi`i'=0
+      local nbzvi`i'=0
+      forvalues l=1/`m`i'' {
+         local vi`i'_m`l'=0
+         local ac`i'_m`l'=0
+         local sumvi`i'_m`l'=0
+         local maxvi`i'_m`l'=0
+         local zmaxvi`i'_m`l'=0
+         local nbzvi`i'_m`l'=0
+      }
+      forvalues l=1/`m`i'' {
+         local vi`i'_`l'=0
+         local ac`i'_`l'=0
+         local sumvi`i'_`l'=0
+         local maxvi`i'_`l'=0
+         local zmaxvi`i'_`l'=0
+         local nbzvi`i'_`l'=0
+         forvalues j=1/`nbgroups`i'' {
+            qui count if `restgroup`i''==`j'&``i''>=`l'
+            local nbitem`i'rgroup`j'_`l'=r(N)
+            forvalues k=1/`=`j'-1' {
+               local diff=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j''
+               if `nbitem`i'rgroup`j'_`l''!=`rgroup`j''&`nbitem`i'rgroup`k'_`l''!=0 {
+                  local ac`i'_`l'=`ac`i'_`l''+1
+                  if `diff'>`minvi' {
+                     local vi`i'_`l'=`vi`i'_`l''+1
+                     local sumvi`i'_`l'=`sumvi`i'_`l''+`diff'
+                     if `diff'>`maxvi`i'_`l'' {
+                        local maxvi`i'_`l'=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j''
+                     }
+                     local p=(`nbitem`i'rgroup`k'_`l''+`nbitem`i'rgroup`j'_`l'')/(`rgroup`j''+`rgroup`k'')
+                     *local z=`diff'/sqrt(`p'*(1-`p')*(1/`rgroup`j''+1/`rgroup`k''))
+                     *di "local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1))      "
+                     local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1))
+                     *di "=`z'"
+                     if `z'>`=invnorm(1-`siglevel')' {
+                        local nbzvi`i'_`l'=`nbzvi`i'_`l''+1
+                     }
+                     if `z'>`zmaxvi`i'_`l'' {
+                        local zmaxvi`i'_`l'=`z'
+                     }
+                  }
+               }
+            }
+            if `j'==`nbgroups`i'' {
+               local vi`i'_m`l'=`vi`i'_`l''
+               local ac`i'_m`l'=`ac`i'_`l''
+               local sumvi`i'_m`l'=`sumvi`i'_`l''
+               local maxvi`i'_m`l'=`maxvi`i'_`l''
+               local zmaxvi`i'_m`l'=`zmaxvi`i'_`l''
+               local nbzvi`i'_m`l'=`nbzvi`i'_`l''
+            }
+         }
+         local vi`i'=`vi`i''+`vi`i'_`l''
+         local ac`i'=`ac`i''+`ac`i'_`l''
+         local sumvi`i'=`sumvi`i''+`sumvi`i'_`l''
+         local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l''
+         if `maxvi`i''<`maxvi`i'_`l'' {
+            local maxvi`i'=`maxvi`i'_`l''
+         }
+         if `zmaxvi`i''<`zmaxvi`i'_`l'' {
+            local zmaxvi`i'=`zmaxvi`i'_`l''
+         }
+      }
+
+      if "`details'"!=""&`m`i''!=1 {
+         forvalues l=1/`m`i'' {
+            if `vi`i'_m`l''!=0 {
+               di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l''
+            }
+            else {
+               di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l''
+            }
+         }
+         di in green "{dup 97:-}"
+      }
+      local vi=`vi'+`vi`i''
+      local ac=`ac'+`ac`i''
+      local sumvi=`sumvi'+`sumvi`i''
+      local nbzvi=`nbzvi'+`nbzvi`i''
+      if `maxvi'<`maxvi`i'' {
+         local maxvi=`maxvi`i''
+      }
+      if `zmaxvi'<`zmaxvi`i'' {
+         local zmaxvi=`zmaxvi`i''
+      }
+      *set trace on
+      local t=`loevHj'[1,`i']
+      local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i''
+      if `vi`i''!=0 {
+         di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata  traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}"
+      }
+      else {
+         di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i''  _col(93) %4.0f `crit`i'' _col(99) "{stata  traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}"
+      }
+      if "`details'"!=""&`i'!=`nbitems' {
+         di in green "{dup 97:-}"
+      }
+      local ac=`ac'+`ac`i''
+      local vi=`vi'+`vi`i''
+   }
+   di in green "{hline 97}"
+      di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi'
+   di in green "{hline 97}"
+}
+/*if  "`nirestscore'"!="" {
+*set trace on
+   if "`nirestscore'"=="*" {
+      anaoption
+   }
+   else {
+      anaoption,`nirestscore'
+   }
+   local minvi=r(minvi)
+   local siglevel=r(siglevel)
+   local minsize=r(minsize)
+   local details `r(details)'
+   if `minsize'==0 {
+      if `nbobs'>500 {
+         local minsize=round(`nbobs'/10)
+      }
+      else if `nbobs'>250 {
+         local minsize=round(`nbobs'/5)
+      }
+      else {
+         local minsize=max(50,round(`nbobs'/3))
+      }
+   }
+
+*set trace on
+   tempname score
+   qui genscore `varlist',score(`score')
+   di
+   di in green _col(10) "Summary per item for check of Non-Intersection via Rest-score"
+   di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel'
+   di
+   di in green "Items"  _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax"  _col(84) "#zsig"  _col(93) "Crit"
+   di in green "{hline 97}"
+*set trace on
+   local vi=0
+   local ac=0
+   local sumvi=0
+   local maxvi=0
+   local zmaxvi=0
+   local nbzvi=0
+   forvalues i=1/`nbitems' {
+      local vi`i'`j'=0
+      local ac`i'=0
+      local sumvi`i'=0
+      local maxvi`i'=0
+      local zmaxvi`i'=0
+      local nbzvi`i'=0
+      forvalues l=1/`m`i'' {
+         local vi`i'_m`l'=0
+         local ac`i'_m`l'=0
+         local sumvi`i'_m`l'=0
+         local maxvi`i'_m`l'=0
+         local zmaxvi`i'_m`l'=0
+         local nbzvi`i'_m`l'=0
+         local vi`i'_`l'=0
+         local ac`i'_`l'=0
+         local sumvi`i'_`l'=0
+         local maxvi`i'_`l'=0
+         local zmaxvi`i'_`l'=0
+      }
+      forvalues j=1/`nbitems' {
+         if `j'!=`i' {
+            tempname restscorei`i'j`j'
+            qui gen `restscorei`i'j`j''=`score'-``i''-``j''
+            local restscoremax`i'=`scoremax'-`m`i''
+            tempname restgroupi`i'j`j'
+            qui gengroup `restscorei`i'j`j'',newvariable(`restgroupi`i'j`j'') minsize(`minsize')
+            local listi`i'j`j'=r(list)
+            qui su `restgroupi`i'j`j''
+            local nbgroupsi`i'j`j'=r(max)
+            forvalues k=0/`nbgroupsi`i'j`j'' {
+               qui count if `restgroupi`i'j`j''==`k'
+               local rgroup`k'=r(N)
+            }
+            forvalues l=1/`m`i'' {
+               forvalues k=1/`m`j'' {
+                  forvalues m=1/`nbgroupsi`i'j`j'' {
+                      qui count if `restgroupi`i'j`j''==`m'&``i''>=`l'&``j''>=`k'
+                      local nbitemi`i'j`j'rgroup`m'_`l'_`k'=r(N)
+                      forvalues n=1/`=`m'-1' {
+                         local diff=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''
+                         if `nbitemi`i'j`j'rgroup`m'_`l'_`k''!=`rgroup`m''&`nbitemi`i'j`j'rgroup`m'_`l'_`k''!=0 {
+                         local ac`i'_`l'=`ac`i'_`l''+1
+                         if `diff'>`minvi' {
+                            local vi`i'_`l'=`vi`i'_`l''+1
+                            local sumvi`i'_`l'=`sumvi`i'_`l''+`diff'
+                            if `diff'>`maxvi`i'_`l'' {
+                               local maxvi`i'_`l'=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''
+                            }
+                            local p=(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+`nbitemi`i'j`j'rgroup`m'_`l'_`k'')/(`rgroup`m''+`rgroup`n'')
+                            local z=abs(2*(sqrt(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)*sqrt(`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)-sqrt((`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k'')*`nbitemi`i'j`j'rgroup`m'_`l'_`k''))/sqrt(`rgroup`m''+`rgroup`n''-1))
+                            if `z'>`=invnorm(1-`siglevel')' {
+                               local nbzvi`i'_`l'=`nbzvi`i'_`l''+1
+                            }
+                            if `z'>`zmaxvi`i'_`l'' {
+                               local zmaxvi`i'_`l'=`z'
+                            }
+                         }
+                      }
+                      if `m'==`nbgroupsi`i'j`j'' {
+                         local vi`i'_m`l'=`vi`i'_`l''
+                         local ac`i'_m`l'=`ac`i'_`l''
+                         local sumvi`i'_m`l'=`sumvi`i'_`l''
+                         local maxvi`i'_m`l'=`maxvi`i'_`l''
+                         local zmaxvi`i'_m`l'=`zmaxvi`i'_`l''
+                         *local nbzvi`i'_m`l'=`nbzvi`i'_`l''
+                      }
+                  }
+               }
+               local vi`i'=`vi`i''+`vi`i'_`l''
+               local ac`i'=`ac`i''+`ac`i'_`l''
+               local sumvi`i'=`sumvi`i''+`sumvi`i'_`l''
+               *local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l''
+               if `maxvi`i''<`maxvi`i'_`l'' {
+                  local maxvi`i'=`maxvi`i'_`l''
+               }
+               if `zmaxvi`i''<`zmaxvi`i'_`l'' {
+                  local zmaxvi`i'=`zmaxvi`i'_`l''
+               }
+            }
+         }
+      }
+      if "`details'"!=""&`m`i''!=1 {
+         forvalues l=1/`m`i'' {
+            if `vi`i'_m`l''!=0 {
+               di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l''
+            }
+            else {
+               di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l''
+            }
+         }
+         di in green "{dup 97:-}"
+      }
+      local vi=`vi'+`vi`i''
+      local ac=`ac'+`ac`i''
+      local sumvi=`sumvi'+`sumvi`i''
+      local nbzvi=`nbzvi'+`nbzvi`i''
+      if `maxvi'<`maxvi`i'' {
+         local maxvi=`maxvi`i''
+      }
+      if `zmaxvi'<`zmaxvi`i'' {
+         local zmaxvi=`zmaxvi`i''
+      }
+      *set trace on
+      local t=`loevHj'[1,`i']
+      local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i''
+      if `vi`i''!=0 {
+         di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata  traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}"
+      }
+      else {
+         di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i''  _col(93) %4.0f `crit`i'' _col(99) "{stata  traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}"
+      }
+      if "`details'"!=""&`i'!=`nbitems' {
+         di in green "{dup 97:-}"
+      }
+      local ac=`ac'+`ac`i''
+      local vi=`vi'+`vi`i''
+   }
+   di in green "{hline 97}"
+      di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi'
+   di in green "{hline 97}"
+}    */
+
+if "`ppp'"!=""|"pmm"!=""|"`nipmatrix'"!="" {
+    local list
+    local listv
+    forvalues i=1/`nbitems' {
+       forvalues l=1/`m`i'' {
+          tempname item`i'_`l'
+          qui gen `item`i'_`l''=``i''>=`l' if ``i''!=.
+          local list `list' ``i''_`l'
+          local listv `listv' `item`i'_`l''
+       }
+    }
+    tempname matppp matpmm
+    matrix `matppp'=J(`=`scoremax'',`=`scoremax'+2',0)
+    matrix `matpmm'=J(`=`scoremax'',`=`scoremax'+2',0)
+    local row=1
+    forvalues i=1/`nbitems' {
+       forvalues k=1/`m`i'' {
+          local col=1
+          forvalues j=1/`nbitems' {
+             forvalues l=1/`m`j'' {
+                if `i'!=`j' {
+                   qui count if `item`i'_`k''!=.&`item`j'_`l''!=.
+                   local denom=r(N)
+                   qui count if `item`i'_`k''==1&`item`j'_`l''==1
+                   local pos=r(N)
+                   matrix `matppp'[`row',`col']=`=`pos'/`denom''
+                   qui count if `item`i'_`k''==0&`item`j'_`l''==0
+                   local pos=r(N)
+                   matrix `matpmm'[`row',`col']=`=`pos'/`denom''
+                }
+                else {
+                   matrix `matppp'[`row',`col']=-1
+                   matrix `matpmm'[`row',`col']=-1
+                }
+                local col=`col'+1
+             }
+          }
+          qui count if `item`i'_`k''!=.
+          local denom=r(N)
+          qui count if `item`i'_`k''==1
+          local pos=r(N)
+          matrix `matppp'[`row',`col']=`=`pos'/`denom''
+          qui count if `item`i'_`k''==0
+          local pos=r(N)
+          matrix `matpmm'[`row',`col']=`=`pos'/`denom''
+          matrix `matppp'[`row',`=`scoremax'+2']=`i'
+          matrix `matpmm'[`row',`=`scoremax'+2']=`i'
+          local row=`row'+1
+       }
+    }
+    matrix colnames `matppp'=`list' p1 item
+    matrix rownames `matppp'=`list'
+    matrix colnames `matpmm'=`list' p1 item
+    matrix rownames `matpmm'=`list'
+    if "`nipmatrix'"!="" {
+       if "`nipmatrix'"=="*" {
+          anaoption
+       }
+       else {
+          anaoption,`nipmatrix'
+       }
+       local minvi=`r(minvi)'
+       local siglevel=`r(siglevel)'
+       local minsize=`r(minsize)'
+       local details `r(details)'
+       if `minsize'==0 {
+          if `nbobs'>500 {
+             local minsize=round(`nbobs'/10)
+          }
+          else if `nbobs'>250 {
+             local minsize=round(`nbobs'/5)
+          }
+          else {
+             local minsize=max(50,round(`nbobs'/3))
+          }
+       }
+       forvalues i=1/`nbitems' {
+          local nbacpp`i'=0
+          local nbvipp`i'=0
+          local maxvipp`i'=0
+          local sumvipp`i'=0
+          local zmaxpp`i'=0
+          local nbsigzpp`i'=0
+          local nbacmm`i'=0
+          local nbvimm`i'=0
+          local maxvimm`i'=0
+          local sumvimm`i'=0
+          local zmaxmm`i'=0
+          local nbsigzmm`i'=0
+       }
+    }
+
+}
+tempfile temporaryfile
+qui save `temporaryfile'
+
+if "`ppp'"!=""|"`nipmatrix'"!="" {
+    drop *
+    qui svmat `matppp',names(col)
+    qui recode `list' (-1=.)
+    qui gen `id'=_n
+    qui gen str9 `item'=""
+    local connect "l"
+    local list2
+    local listw2
+    sort p1
+    qui set obs `=`scoremax'+1'
+    local listitem
+    forvalues i=1/`scoremax' {
+        local t=item[`i']
+        local listitem `listitem' `t'
+        local w:word `i' of `list'
+        qui replace `item'="`w'" if `id'==`i'
+        qui replace `w'=. if `id'==`i'
+        local connect "`connect' l"
+        local z=regexr("`w'","_",">=")
+        label define `monlabel' `i' "`z'", add
+        label variable `w' "`z'"
+        qui su p1 if `id'==`i'
+        local prop=r(mean)
+        qui replace `w'=`prop' in `=`scoremax'+1'
+    }
+    forvalues i=1/`scoremax' {
+        local v=`item'[`i']
+        local list2 `list2' `v'
+        local v=`id'[`i']
+        local listw2 `listw2' `v'
+    }
+    label define `monlabel' `=`scoremax'+1' "Prop",add
+    order `list2'
+    qui gen `id2'=_n
+    label value `id2' `monlabel'
+    label variable `id2' " "
+    if "`graph'"!="" {
+       twoway conn `list' `id2' in 1/`scoremax',connect(`connect') ytitle("") title("P++ diagnostics") name(ppp,replace)
+    }
+    format `list' %5.3f
+    label variable `id' "Item"
+    rename `id' Item
+    label value Item `monlabel'
+    qui replace Item=`=`scoremax'+1' in `=`scoremax'+1'
+    tempname matpp
+    matrix define `matpp'=J(`scoremax',`scoremax',0)
+    forvalues i=1/`scoremax' {
+       forvalues j=1/`scoremax' {
+          local ti:word `i' of `listv'
+          local tj:word `j' of `listv'
+          local t:word `j' of `list2'
+          matrix `matpp'[`i',`j']=`t'[`i']
+       }
+    }
+    matrix colnames `matpp'=`list2'
+    matrix rownames `matpp'=`list2'
+    if "`ppp'"!="" {
+       di
+       di in green _col(10) "P++ values per items pair (The values should be increasing in each column)"
+
+       matrix list `matpp',format(%5.3f)  nohalf   noheader
+    }
+    label drop `monlabel'
+    *set trace on
+    qui use "`temporaryfile'",clear
+    if "`nipmatrix'"!="" {
+       forvalues i=1/`scoremax' {
+          forvalues j=1/`scoremax' {
+             forvalues k=`=`j'+1'/`scoremax' {
+*di "`listv' `listw2'"
+                local ti:word `i' of `listitem'
+                local tj:word `j' of `listitem'
+                local tk:word `k' of `listitem'
+                if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ {
+                   local ++nbacpp`ti'
+                   *local ++nbacmm`tk'
+                   local diff=`matpp'[`j',`i']-`matpp'[`k',`i']
+                   if `diff'>`minvi'&`diff'!=. {
+                      local ++nbvipp`tj'
+                      local ++nbvipp`tk'
+                      local sumvipp`tj'=`sumvipp`tj''+`diff'
+                      local sumvipp`tk'=`sumvipp`tk''+`diff'
+                      if `diff'>`maxvipp`tj'' {
+                         local maxvipp`tj'=`diff'
+                      }
+                      if `diff'>`maxvipp`tk'' {
+                         local maxvipp`tk'=`diff'
+                      }
+                      local wi:word `i' of `listw2'
+                      local wj:word `j' of `listw2'
+                      local wk:word `k' of `listw2'
+                      local li:word `wi' of `listv'
+                      local lj:word `wj' of `listv'
+                      local lk:word `wk' of `listv'
+                      local ii:word `wi' of `list'
+                      local ij:word `wj' of `list'
+                      local ik:word `wk' of `list'
+*                      di "`list'"
+*                      di "`li', `lj', `lk', `ii' `ij' `ik'"
+                      qui count if `li'==0&`lj'==1&`lk'==0
+                      local a=r(N)
+                      qui count if `li'==0&`lj'==0&`lk'==1
+                      local b=r(N)
+*di "                      local z=abs(2*min(`a',`b')-(`a'+`b'))/sqrt(`a'+`b')"
+                      local z=abs(2*min(`a',`b')-(`a'+`b'))/sqrt(`a'+`b')
+
+*di "                      if `z'>`=invnorm(1-`siglevel')'&`z'!=. {"
+
+                      if `z'>`=invnorm(1-`siglevel')'&`z'!=. {
+                         local ++nbsigzpp`tj'
+                         if `z'>`zmaxpp`tj'' {
+                            local zmaxpp`tj'=`z'
+                         }
+                         local ++nbsigzpp`tk'
+                         if `z'>`zmaxpp`tk'' {
+                            local zmaxpp`tk'=`z'
+                         }
+                      }
+                   }
+                }
+             }
+          }
+       }
+    }
+/*    if "`nipmatrix'"!="" {
+       forvalues i=1/`scoremax' {
+          forvalues j=1/`scoremax' {
+             forvalues k=`=`j'+1'/`scoremax' {
+                local ti:word `i' of `listitem'
+                local tj:word `j' of `listitem'
+                local tk:word `k' of `listitem'
+                if `tj'!= `tk'&`ti'!=`tk'&`ti'!=`tj' {
+                   local ++nbacpp`ti'
+                   local diff=`matpp'[`j',`i']-`matpp'[`k',`i']
+                   if `diff'>`minsize'&`diff'!=. {
+                      local ++nbvipp`tj'
+                      local ++nbvipp`tk'
+                      local sumvipp`tj'=`sumvipp`tj''+`diff'
+                      local sumvipp`tk'=`sumvipp`tk''+`diff'
+                      if `diff'>`maxvipp`tj'' {
+                         local maxvipp`tj'=`diff'
+                      }
+                      if `diff'>`maxvipp`tk'' {
+                         local maxvipp`tk'=`diff'
+                      }
+                   }
+                }
+             }
+          }
+       }
+    }
+*/
+}
+if "`pmm'"!=""|"`nipmatrix'"!="" {
+    drop _all
+    qui svmat `matpmm',names(col)
+    qui recode `list' (-1=.)
+    qui gen `id'=_n
+    qui gen str9 `item'=""
+    local connect "l"
+    local list2
+    local listw2
+    gsort -p1
+    qui set obs `=`scoremax'+1'
+    forvalues i=1/`scoremax' {
+        local w:word `i' of `list'
+        qui replace `item'="`w'" if `id'==`i'
+        qui replace `w'=. if `id'==`i'
+        local connect "`connect' l"
+        local z=regexr("`w'","_",">=")
+        label define `monlabel' `i' "`z'", add
+        label variable `w' "`z'"
+        qui su p1 if `id'==`i'
+        local prop=r(mean)
+        qui replace `w'=`prop' in `=`scoremax'+1'
+    }
+    forvalues i=1/`scoremax' {
+        local v=`item'[`i']
+        local list2 `list2' `v'
+        local v=`id'[`i']
+        local listw2 `listw2' `v'
+    }
+    label define `monlabel' `=`scoremax'+1' "Prop",add
+    order `list2'
+    qui gen `id2'=_n
+    label value `id2' `monlabel'
+    label variable `id2' " "
+    if "`graph'"!="" {
+       twoway conn `list' `id2' in 1/`scoremax',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace)
+    }
+    format `list' %5.3f
+    label variable `id' "Item"
+    rename `id' Item
+    label value Item `monlabel'
+    qui replace Item=`=`scoremax'+1' in `=`scoremax'+1'
+    tempname matmm
+    matrix define `matmm'=J(`scoremax',`scoremax',0)
+    forvalues i=1/`scoremax' {
+       forvalues j=1/`scoremax' {
+          local t:word `j' of `list2'
+          matrix `matmm'[`i',`j']=`t'[`i']
+       }
+    }
+    matrix colnames `matmm'=`list2'
+    matrix rownames `matmm'=`list2'
+    if "`pmm'"!="" {
+       di
+       di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)"
+       matrix list `matmm',format(%5.3f)  nohalf   noheader
+    }
+    label drop `monlabel'
+    qui use "`temporaryfile'",clear
+    if "`nipmatrix'"!="" {
+       forvalues i=1/`scoremax' {
+          forvalues j=1/`scoremax' {
+             forvalues k=`=`j'+1'/`scoremax' {
+*di "`listv' `listw2'"
+                local ti:word `i' of `listitem'
+                local tj:word `j' of `listitem'
+                local tk:word `k' of `listitem'
+                if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ {
+                   local ++nbacmm`ti'
+                   *local ++nbacmm`tk'
+                   local diff=`matmm'[`k',`i']-`matmm'[`j',`i']
+                   if `diff'>`minvi'&`diff'!=. {
+                      local ++nbvimm`tj'
+                      local ++nbvimm`tk'
+                      local sumvimm`tj'=`sumvimm`tj''+`diff'
+                      local sumvimm`tk'=`sumvimm`tk''+`diff'
+                      if `diff'>`maxvimm`tj'' {
+                         local maxvimm`tj'=`diff'
+                      }
+                      if `diff'>`maxvimm`tk'' {
+                         local maxvimm`tk'=`diff'
+                      }
+                      local wi:word `i' of `listw2'
+                      local wj:word `j' of `listw2'
+                      local wk:word `k' of `listw2'
+                      local li:word `wi' of `listv'
+                      local lj:word `wj' of `listv'
+                      local lk:word `wk' of `listv'
+                      local ii:word `wi' of `list'
+                      local ij:word `wj' of `list'
+                      local ik:word `wk' of `list'
+*                      di "`list'"
+*                      di "`li', `lj', `lk', `ii' `ij' `ik'"
+                      qui count if `li'==0&`lj'==1&`lk'==0
+                      local a=r(N)
+                      qui count if `li'==0&`lj'==0&`lk'==1
+                      local b=r(N)
+*di "                      local z=abs(2*min(`a',`b')-(`a'+`b'))/sqrt(`a'+`b')"
+                      local z=abs(2*min(`a',`b')-(`a'+`b'))/sqrt(`a'+`b')
+
+*di "                      if `z'>`=invnorm(1-`siglevel')'&`z'!=. {"
+
+                      if `z'>`=invnorm(1-`siglevel')'&`z'!=. {
+                         local ++nbsigzmm`tj'
+                         if `z'>`zmaxmm`tj'' {
+                            local zmaxmm`tj'=`z'
+                         }
+                         local ++nbsigzmm`tk'
+                         if `z'>`zmaxmm`tk'' {
+                            local zmaxmm`tk'=`z'
+                         }
+                      }
+                   }
+                }
+             }
+          }
+       }
+    }
+}
+if "`nipmatrix'"!="" {
+   *set trace on
+   di
+   di in green _col(10) "Summary per item for check of non-Intersection via Pmatrix"
+   di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel'
+   di
+   di in green "Items"  _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax"  _col(84) "#zsig"  _col(93) "Crit"
+   di in green "{hline 97}"
+   forvalues i=1/`nbitems' {
+      local nbac`i'=`nbacpp`i''+`nbacmm`i''
+      local nbvi`i'=`nbvipp`i''+`nbvimm`i''
+      local maxvi`i'=max(`maxvipp`i'',`maxvimm`i'')
+      local sumvi`i'=`sumvipp`i''+`sumvimm`i''
+      local zmaxvi`i'=max(`zmaxpp`i'',`zmaxmm`i'')
+
+      local nbzsig`i'=`nbsigzpp`i''+`nbsigzmm`i''
+      local zmax`i'=0
+      *local nbsigz`i'=0
+      local t=`loevHj'[1,`i']
+*      di "local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmax`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i''     "
+      local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmaxvi`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i''
+
+      *di `nbac`i'' "   " `nbvi`i'' "   " `sumvi`i''
+      if `nbvi`i''!=0 {
+         di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(33) %6.4f `=`nbvi`i''/`nbac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`nbac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzsig`i'' _col(93) %4.0f `crit`i''
+      }
+      else {
+         di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i''  _col(93) %4.0f `crit`i''
+      }
+   }
+}
+
+/*if "`pmm'"!="" {
+    drop _all
+    matrix `P00g'=`P00',`P1''
+    matrix colnames `P00g'=`varlist' `p1'
+    matrix rownames `P00g'=`varlist'
+    qui svmat `P00g' , names(col)
+    qui gen `id'=_n
+    qui gen str9 `item'=""
+    local connect "l"
+    forvalues i=1/`nbitems' {
+        qui replace `item'="``i''" if `id'==`i'
+        qui replace ``i''=. if `id'==`i'
+        local connect "`connect' l"
+        label define `monlabel' `i' "``i''", add
+    }
+    sort `p1'
+    qui gen `id2'=_n
+    label value `id2' `monlabel'
+    label variable `id2' " "
+    if "`graph'"!="" {
+       twoway connected `varlist' `id2',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace)
+    }
+    format `varlist' %5.3f
+    label variable `id' "Item"
+    label value `id' `monlabel'
+    di
+    di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)"
+    list `id' `varlist' , table compress separator(`nbitems') noobs divider
+    label drop `monlabel'
+}
+
+
+
+if "`pairwise'"=="" {
+   restore, not
+}*/
+
+
+qui use "`loevHfile'",clear
+*set trace on
+if "`generror'"!="" {
+   if "`replace'"!="" {
+      capture drop `generror' `generror'_0 `generror'_H
+   }
+   qui gen `generror'=0
+   qui gen `generror'_0=`eGutt0'/`nb'
+   forvalues i=1/`nbitems' {
+      if "`pairwise'"=="" {
+         qui replace `generror'=. if ``i''==.
+         qui replace `generror'_0=. if ``i''==.
+      }
+      forvalues j=1/`nbitems' {
+         qui replace `generror'=`generror'+1 if `P1'[1,`i']<`P1'[1,`j']&``i''==1&``j''==0
+         qui replace `generror'=`generror'+.5 if `P1'[1,`i']==`P1'[1,`j']&``i''==1&``j''==0
+      }
+   }
+   tempvar flag
+   qui gen `flag'=0
+   qui replace `flag'=1 `if'
+   qui replace `generror'=. if `flag'==0
+   qui replace `generror'_0=.  if `flag'==0
+   qui gen `generror'_H=1-`generror'/`generror'_0
+   label variable `generror' "Number of Guttman errors per individual"
+   label variable `generror'_H "H indice per individual"
+   if "`graph'"!="" {
+      qui histogram `generror',discrete freq name(errors,replace)
+      qui histogram `generror'_H,discrete freq name(H,replace)
+   }
+   di
+   di in green "Number of Guttman errors by individual"
+   qui su `generror'
+   di in green "            Mean number: " in ye %7.2f r(mean)
+   di in green "         Maximal number: " in ye %7.2f `=int(`nbitems'^2/4)'
+   di in green "Expected Guttman errors: " in ye %7.2f `=`eGutt0'/`nb''
+   qui count if `generror'_H<0
+   di in green "            Rate of H<0: " in ye %7.2f `=r(N)/`nb'*100' "%"
+
+}
+
+matrix colnames `loevHj'=`varlist'
+matrix rownames `loevHj'=Hj
+return matrix loevHj `loevHj'
+
+matrix colnames `loevHjk'=`varlist'
+matrix rownames `loevHjk'=`varlist'
+return matrix loevHjk `loevHjk'
+
+matrix colnames `eGuttj'=`varlist'
+matrix rownames `eGuttj'=ej
+return matrix eGuttj `eGuttj'
+
+matrix colnames `eGuttjk'=`varlist'
+matrix rownames `eGuttjk'=`varlist'
+return matrix eGuttjk `eGuttjk'
+
+matrix colnames `eGuttj0'=`varlist'
+matrix rownames `eGuttj0'=ejk
+return matrix eGuttj0 `eGuttj0'
+
+matrix colnames `eGuttjk0'=`varlist'
+matrix rownames `eGuttjk0'=`varlist'
+return matrix eGuttjk0 `eGuttjk0'
+
+return scalar loevH=`loevH'
+return scalar eGutt =`eGutt'
+return scalar eGutt0 =`eGutt0'
+
+if `modamax'==1 {
+   matrix colnames `P11'=`varlist'
+   matrix rownames `P11'=`varlist'
+   return matrix P11 `P11'
+}
+
+matrix colnames `P00'=`varlist'
+matrix rownames `P00'=`varlist'
+return matrix P00 `P00'
+
+if "`ppp'"!=""|"`nipmatrix'"!="" {
+   return matrix ppp=`matpp'
+}
+if "`pmm'"!=""|"`nipmatrix'"!="" {
+   return matrix pmm=`matmm'
+}
+
+matrix colnames `zHj'=`varlist'
+matrix rownames `zHj'=zHj
+return matrix zHj `zHj'
+
+matrix colnames `pvalHj'=`varlist'
+matrix rownames `pvalHj'=pval
+return matrix pvalHj `pvalHj'
+
+return scalar zH=`zH'
+return scalar pvalH=`pvalH'
+if "`pair'"!="" {
+    matrix colnames `zHjk'=`varlist'
+    matrix rownames `zHjk'=`varlist'
+    return matrix zHjk `zHjk'
+
+    matrix colnames `pvalHjk'=`varlist'
+    matrix rownames `pvalHjk'=`varlist'
+    return matrix pvalHjk `pvalHjk'
+}
+
+matrix colnames `Obs'=`varlist'
+matrix rownames `Obs'=`varlist'
+return matrix Obs `Obs'
+
+capture restore, not
+
+end
diff --git a/Modules/ado/personal/l/loevH72.ado b/Modules/ado/personal/l/loevH72.ado
new file mode 100644
index 0000000..8532dc1
--- /dev/null
+++ b/Modules/ado/personal/l/loevH72.ado
@@ -0,0 +1,1231 @@
+*! Version 7.2 19 November 2008
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Stata program : LoevH
+* Loevinger H indexes, Mokken Analysis
+* Release 7.2: November 19, 2008  /*Implementation of the GPN indexes*/
+*
+* dedication for Stefan Thau - Interuniversity Centre for Social Science Theory and Methodology - University of Groningen
+*
+* Historic :
+* Version 1 (August 20, 2002) [Jean-Benoit Hardouin]
+* Version 2 (June 22, 2003) [Jean-Benoit Hardouin]
+* Version 3 (December 1, 2003) [Jean-Benoit Hardouin]
+* Version 4 (January 20, 2004) [Jean-Benoit Hardouin]
+* Version 5 (March 22, 2004) [Jean-Benoit Hardouin]
+* Version 6 (July 3, 2004) [Jean-Benoit Hardouin]
+* Version 6.1 (September 19, 2005) [Jean-Benoit Hardouin]
+* Version 6.2 (January 31, 2006) [Jean-Benoit Hardouin]
+* Release 6.3 (March 20, 2006) [Jean-Benoit Hardouin]  /*A bug with temporary files */
+* Release 6.4 (January 19, 2007) [Jean-Benoit Hardouin]  /*Tests to compare Loevinger coefficients to 0 identical to the MSP software (dichotomous and polytomous case)*/
+* Release 6.5 (January 22, 2007) [Jean-Benoit Hardouin]  /*Correction of a bug concerning the p-values with the pair option*/
+* Release 6.6 (Februar 16, 2007) [Jean-Benoit Hardouin]  /*Correction of a bug with the displaying of Easyness with polytomous items, option graph, option generror, improvements*/
+* Release 7: June 21, 2007  /*Check of  monotonicity and Non intersection via P matrices*/
+* Release 7.1: November 6, 2008  /*Correction for the z-tests for the check of non intersection via P matrices*/
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences  (UPRES EA 4275)
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* Requiered Stata modules:
+* -anaoption- (version 1)
+* -traces- (version 3.2)
+* -gengroup- (version 1)
+* -guttmax- (version 1)
+*
+* News about this program :http://www.anaqol.org
+* FreeIRT Project website : http://www.freeirt.org
+*
+* Copyright 2002-2008 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+***********************************************************************************************************
+
+program define loevH , rclass
+version 8.2
+syntax varlist(min=2 numeric) [if] [,PAIRWise PAIR ppp pmm noADJust GENERror(string) REPlace GRaph MONOtonicity(string) NIRESTscore(string) NIPmatrix(string)]
+preserve
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+tempname corr cov P1 P0 P11 P00 H1jk vHjk zHjk chi2Hjk dfHjk pvalHjk H1j vHj zHj pvalHj H1 vH zH pvalH Obs eGuttjk eGuttjk0 loevHjk eGuttj eGuttj0 loevHj eGutt eGutt0 loevH e1 e2
+tempfile loevHfile
+qui save "`loevHfile'"
+
+if "`if'"!="" {
+   qui keep `if'
+}
+
+if "`adjust'"!="" {
+   local adj=0
+}
+else {
+   local adj=1
+}
+
+qui count
+local nbobs=r(N)
+
+forvalues j=1/`nbitems' {
+   if "`pairwise'"=="" {
+       qui drop if ``j''==.
+   }
+}
+qui count
+local nbtotindnm=r(N)
+
+matrix define `eGuttjk'=J(`nbitems',`nbitems',0)
+matrix define `eGuttjk0'=J(`nbitems',`nbitems',0)
+matrix define `loevHjk'=J(`nbitems',`nbitems',0)
+matrix define `eGuttj'=J(1,`nbitems',0)
+matrix define `eGuttj0'=J(1,`nbitems',0)
+matrix define `loevHj'=J(1,`nbitems',0)
+scalar define `eGutt'=0
+scalar define `eGutt0'=0
+scalar define `loevH'=0
+matrix define `Obs'=J(`nbitems',`nbitems',0)
+matrix define `P00'=J(`nbitems',`nbitems',0)
+
+tempname modamax
+scalar `modamax'=0
+local scoremax=0
+forvalues j=1/`nbitems' {
+     qui su ``j''
+     local m`j'=r(max)
+     local scoremax=`scoremax'+`m`j''
+     if r(max)>`modamax' {
+        scalar `modamax'=r(max)
+     }
+     local nbHjkNS`j'=0
+}
+
+/*if "`generror'"!=""&`modamax'!=1 {
+   di in ye "It is not possible to define the {cmd:generror} option with polytomous items"
+   local generror
+} */
+*di "scoremax `scoremax'"
+if "`graph'"!=""&`scoremax'>19 {
+   di in ye "The {cmd:graph} option is disabled because of a large number of possible scores (>20)"
+   local graph
+}
+
+matrix define `cov'=J(`nbitems',`nbitems',0)
+matrix define `corr'=J(`nbitems',`nbitems',0)
+matrix define `P11'=J(`nbitems',`nbitems',0)
+matrix define `H1jk'=J(`nbitems',`nbitems',0)
+matrix define `vHjk'=J(`nbitems',`nbitems',0)
+matrix define `zHjk'=J(`nbitems',`nbitems',0)
+matrix define `pvalHjk'=J(`nbitems',`nbitems',0)
+matrix define `P1'=J(1,`nbitems',0)
+matrix define `P0'=J(1,`nbitems',0)
+matrix define `H1j'=J(1,`nbitems',0)
+matrix define `vHj'=J(1,`nbitems',0)
+matrix define `zHj'=J(1,`nbitems',0)
+matrix define `pvalHj'=J(1,`nbitems',0)
+
+forvalues j=1/`nbitems' {
+    qui su ``j''
+    matrix `cov'[`j',`j']=r(Var)
+    matrix `corr'[`j',`j']=1
+    local tmp=`j'+1
+    qui count if ``j''!=.
+    matrix `Obs'[`j',`j']=r(N)
+    forvalues k=`tmp'/`nbitems' {
+        qui count if ``j''!=.&``k''!=.
+        matrix `Obs'[`j',`k']=r(N)
+        matrix `Obs'[`k',`j']=r(N)
+        qui corr ``j'' ``k'',cov
+        matrix `cov'[`j',`k']=r(cov_12)
+        matrix `cov'[`k',`j']=r(cov_12)
+        qui corr ``j'' ``k''
+        matrix `corr'[`j',`k']=r(rho)
+        matrix `corr'[`k',`j']=r(rho)
+        matrix `zHjk'[`j',`k']=`corr'[`j',`k']*(`Obs'[`j',`k']-`adj')^.5
+        matrix `zHjk'[`k',`j']=`H1jk'[`j',`k']
+        matrix `pvalHjk'[`j',`k']=1-norm(`zHjk'[`j',`k'])
+        matrix `pvalHjk'[`k',`j']=`pvalHjk'[`j',`k']
+        if `pvalHjk'[`j',`k']>0.05 {
+           local nbHjkNS`j'=`nbHjkNS`j''+1
+           local nbHjkNS`k'=`nbHjkNS`k''+1
+        }
+        forvalues mod1=1/`m`j'' {
+            forvalues mod2=1/`m`k'' {
+                qui count if ``j''<`mod1'&``k''>=`mod2'&``j''!=.&``k''!=.
+                scalar `e1'=r(N)
+                qui count if ``j''>=`mod1'&``k''<`mod2'&``j''!=.&``k''!=.
+                scalar `e2'=r(N)
+                matrix `eGuttjk'[`j',`k']=`eGuttjk'[`j',`k']+min(`e1',`e2')
+                qui count if ``j''<`mod1'&``j''!=.&``k''!=.
+                local t1=r(N)
+                qui count if ``k''<`mod2'&``j''!=.&``k''!=.
+                local t2=r(N)
+                qui count if ``j''>=`mod1'&``j''!=.&``k''!=.
+                local t3=r(N)
+                qui count if ``k''>=`mod2'&``j''!=.&``k''!=.
+                local t4=r(N)
+                if min(`e1',`e2')==`e1' {
+                    matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t1'*`t4'/`Obs'[`j',`k']
+                }
+                else {
+                    matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t2'*`t3'/`Obs'[`j',`k']
+                }
+
+            }
+        }
+        qui count if ``j''==0&``k''==0
+        matrix `P00'[`j',`k']=r(N)/`Obs'[`j',`k']
+        matrix `P00'[`k',`j']=r(N)/`Obs'[`k',`j']
+        if `modamax'==1 {
+           qui count if ``j''==1&``k''==1
+           matrix `P11'[`j',`k']=r(N)/`Obs'[`j',`k']
+           matrix `P11'[`k',`j']=r(N)/`Obs'[`k',`j']
+        }
+
+        matrix `eGuttjk'[`k',`j']=`eGuttjk'[`j',`k']
+        matrix `eGuttj'[1,`j']=`eGuttj'[1,`j']+`eGuttjk'[`j',`k']
+        matrix `eGuttj'[1,`k']=`eGuttj'[1,`k']+`eGuttjk'[`j',`k']
+        matrix `eGuttjk0'[`k',`j']=`eGuttjk0'[`j',`k']
+        matrix `eGuttj0'[1,`j']=`eGuttj0'[1,`j']+`eGuttjk0'[`j',`k']
+        matrix `eGuttj0'[1,`k']=`eGuttj0'[1,`k']+`eGuttjk0'[`j',`k']
+
+        matrix `loevHjk'[`j',`k']=1-`eGuttjk'[`j',`k']/`eGuttjk0'[`j',`k']
+        matrix `loevHjk'[`k',`j']=`loevHjk'[`j',`k']
+
+    }
+    qui count if ``j''!=.
+    local tmp=r(N)
+    qui count if ``j''==1
+    matrix `P1'[1,`j']=r(N)/`tmp'
+    qui count if ``j''==0
+    matrix `P0'[1,`j']=r(N)/`tmp'
+    matrix `loevHj'[1,`j']=1-`eGuttj'[1,`j']/`eGuttj0'[1,`j']
+    scalar `eGutt'=`eGutt'+`eGuttj'[1,`j']/2
+    scalar `eGutt0'=`eGutt0'+`eGuttj0'[1,`j']/2
+}
+scalar `H1'=0
+scalar `vH'=0
+scalar `zH'=0
+forvalues j=1/`nbitems'{
+   forvalues k=1/`nbitems' {
+      if `j'!=`k' {
+         matrix `zHj'[1,`j']=`zHj'[1,`j']+`cov'[`j',`k']
+         matrix `vHj'[1,`j']=`vHj'[1,`j']+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj')
+      }
+      if `j'<`k' {
+         scalar `zH'=`zH'+`cov'[`j',`k']
+         scalar `vH'=`vH'+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj')
+      }
+   }
+   matrix `zHj'[1,`j']=`zHj'[1,`j']/sqrt(`vHj'[1,`j'])
+   matrix `pvalHj'[1,`j']=1-norm(`zHj'[1,`j'])
+}
+scalar `zH'=`zH'/sqrt(`vH')
+scalar `pvalH'=1-norm(`zH')
+scalar `loevH'=1-`eGutt'/`eGutt0'
+
+if `modamax'==1 {
+   local text="Easyness"
+   local value=1
+   local col=23
+}
+else {
+   local text="Difficulty"
+   local value=0
+   local col=21
+}
+
+
+di in green _col(35) "Observed" _col(47) "Expected" _col(93) "Number"
+di in green _col(`col') "`text'" _col(36) "Guttman" _col(48) "Guttman" _col(59) "Loevinger" _col(83) "H0: Hj<=0" _col(94) "of NS"
+di in green "Item"  _col(15) "Obs" _col(24) "P(Xj=`value')" _col(37) "errors" _col(49) "errors" _col(61) "H coeff" _col(73) "z-stat." _col(85) "p-value" _col(96) "Hjk"
+di in green "{hline 99}"
+forvalues j=1/`nbitems' {
+     di in green "``j''" in yellow _col(15) `Obs'[`j',`j'] _col(25) %6.4f `P`value''[1,`j'] _col(38) %5.0f `eGuttj'[1,`j'] _col(47) %8.2f `eGuttj0'[1,`j'] _col(61) %7.5f `loevHj'[1,`j'] _col(72) %8.4f `zHj'[1,`j'] _col(85) %7.5f `pvalHj'[1,`j'] _col(97) %2.0f `nbHjkNS`j''
+}
+di in green "{hline 99}"
+if "`pairwise'"=="" {
+   local nb=`nbtotindnm'
+}
+else {
+   local nb=`nbobs'
+}
+di in green "Scale" in yellow _col(15) `nb' _col(38) %5.0f `eGutt' _col(47) %8.2f `eGutt0' _col(61) %-8.5f `loevH' _col(71) %9.4f `zH' _col(85) %7.5f `pvalH'
+
+if "`pair'"!="" {
+   di
+   di in green _col(45) "Observed" _col(57) "Expected"
+   di in green _col(`=`col'+10') "`text'" _col(46) "Guttman" _col(58) "Guttman" _col(69) "Loevinger" _col(92) "H0: Hjk<=0"
+   di in green "Items"  _col(25) "Obs" _col(29) "P(Xj=`value',Xk=`value')" _col(47) "errors" _col(59) "errors" _col(71) "H coeff" _col(83) "z-stat." _col(95) "p-value"
+   di in green "{hline 101}"
+   forvalues j=1/`nbitems' {
+      forvalues k=`=`j'+1'/`nbitems' {
+         qui count if ``j''!=.
+         local obs=r(N)
+         di in green "``j''" _col(10) "``k''" in yellow _col(25) `Obs'[`j',`k'] _col(35) %6.4f `P`value'`value''[`j',`k'] _col(48) %5.0f `eGuttjk'[`j',`k'] _col(57) %8.2f `eGuttjk0'[`j',`k'] _col(70) %8.5f `loevHjk'[`j',`k'] _col(81) %9.4f `zHjk'[`j',`k'] _col(95) %7.5f `pvalHjk'[`j',`k']
+      }
+   }
+   di in green "{hline 101}"
+}
+/*if `modamax'>1&"`ppp'"!="" {
+   di in green "It is not possible to obtain the P++ diagnostics with polytomous items"
+   local ppp
+}
+if `modamax'>1&"`pmm'"!="" {
+   di in green "It is not possible to obtain the P-- diagnostics with polytomous items"
+   local pmm
+} */
+
+tempname P11g P00g item id id2 p1 monlabel
+
+/*if "`monotonicity'"!=""&`modamax'>1 {
+   di in green "It is not possible to obtain the latent monotonicity diagnostics with polytomous items"
+   local monotonicity
+}  */
+
+if  "`monotonicity'"!="" {
+*set trace on
+   if "`monotonicity'"=="*" {
+      anaoption
+   }
+   else {
+      anaoption,`monotonicity'
+   }
+   local minvi=r(minvi)
+   local siglevel=r(siglevel)
+   local minsize=r(minsize)
+   local details `r(details)'
+   if `minsize'==0 {
+      if `nbobs'>500 {
+         local minsize=round(`nbobs'/10)
+      }
+      else if `nbobs'>250 {
+         local minsize=round(`nbobs'/5)
+      }
+      else {
+         local minsize=max(50,round(`nbobs'/3))
+      }
+   }
+
+*set trace on
+   tempname score
+   qui genscore `varlist',score(`score')
+   di
+   di in green _col(10) "Summary per item for check of monotonicity"
+   di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel'
+   di
+   di in green "Items"  _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax"  _col(84) "#zsig"  _col(93) "Crit"
+   di in green "{hline 97}"
+*set trace on
+   local vi=0
+   local ac=0
+   local sumvi=0
+   local maxvi=0
+   local zmaxvi=0
+   local nbzvi=0
+   forvalues i=1/`nbitems' {
+      tempname restscore`i'
+      qui gen `restscore`i''=`score'-``i''
+      local restscoremax`i'=`scoremax'-`m`i''
+      tempname restgroup`i'
+      qui gengroup `restscore`i'',newvariable(`restgroup`i'') minsize(`minsize')
+      local list`i'=r(list)
+      qui su `restgroup`i''
+      local nbgroups`i'=r(max)
+      forvalues j=0/`nbgroups`i'' {
+         qui count if `restgroup`i''==`j'
+         local rgroup`j'=r(N)
+      }
+      local vi`i'=0
+      local ac`i'=0
+      local sumvi`i'=0
+      local maxvi`i'=0
+      local zmaxvi`i'=0
+      local nbzvi`i'=0
+      forvalues l=1/`m`i'' {
+         local vi`i'_m`l'=0
+         local ac`i'_m`l'=0
+         local sumvi`i'_m`l'=0
+         local maxvi`i'_m`l'=0
+         local zmaxvi`i'_m`l'=0
+         local nbzvi`i'_m`l'=0
+      }
+      forvalues l=1/`m`i'' {
+         local vi`i'_`l'=0
+         local ac`i'_`l'=0
+         local sumvi`i'_`l'=0
+         local maxvi`i'_`l'=0
+         local zmaxvi`i'_`l'=0
+         local nbzvi`i'_`l'=0
+         forvalues j=1/`nbgroups`i'' {
+            qui count if `restgroup`i''==`j'&``i''>=`l'
+            local nbitem`i'rgroup`j'_`l'=r(N)
+            forvalues k=1/`=`j'-1' {
+               local diff=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j''
+               if `nbitem`i'rgroup`j'_`l''!=`rgroup`j''&`nbitem`i'rgroup`k'_`l''!=0 {
+                  local ac`i'_`l'=`ac`i'_`l''+1
+                  if `diff'>`minvi' {
+                     local vi`i'_`l'=`vi`i'_`l''+1
+                     local sumvi`i'_`l'=`sumvi`i'_`l''+`diff'
+                     if `diff'>`maxvi`i'_`l'' {
+                        local maxvi`i'_`l'=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j''
+                     }
+                     local p=(`nbitem`i'rgroup`k'_`l''+`nbitem`i'rgroup`j'_`l'')/(`rgroup`j''+`rgroup`k'')
+                     *local z=`diff'/sqrt(`p'*(1-`p')*(1/`rgroup`j''+1/`rgroup`k''))
+                     *di "local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1))      "
+                     local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1))
+                     *di "=`z'"
+                     if `z'>`=invnorm(1-`siglevel')' {
+                        local nbzvi`i'_`l'=`nbzvi`i'_`l''+1
+                     }
+                     if `z'>`zmaxvi`i'_`l'' {
+                        local zmaxvi`i'_`l'=`z'
+                     }
+                  }
+               }
+            }
+            if `j'==`nbgroups`i'' {
+               local vi`i'_m`l'=`vi`i'_`l''
+               local ac`i'_m`l'=`ac`i'_`l''
+               local sumvi`i'_m`l'=`sumvi`i'_`l''
+               local maxvi`i'_m`l'=`maxvi`i'_`l''
+               local zmaxvi`i'_m`l'=`zmaxvi`i'_`l''
+               local nbzvi`i'_m`l'=`nbzvi`i'_`l''
+            }
+         }
+         local vi`i'=`vi`i''+`vi`i'_`l''
+         local ac`i'=`ac`i''+`ac`i'_`l''
+         local sumvi`i'=`sumvi`i''+`sumvi`i'_`l''
+         local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l''
+         if `maxvi`i''<`maxvi`i'_`l'' {
+            local maxvi`i'=`maxvi`i'_`l''
+         }
+         if `zmaxvi`i''<`zmaxvi`i'_`l'' {
+            local zmaxvi`i'=`zmaxvi`i'_`l''
+         }
+      }
+
+      if "`details'"!=""&`m`i''!=1 {
+         forvalues l=1/`m`i'' {
+            if `vi`i'_m`l''!=0 {
+               di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l''
+            }
+            else {
+               di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l''
+            }
+         }
+         di in green "{dup 97:-}"
+      }
+      local vi=`vi'+`vi`i''
+      local ac=`ac'+`ac`i''
+      local sumvi=`sumvi'+`sumvi`i''
+      local nbzvi=`nbzvi'+`nbzvi`i''
+      if `maxvi'<`maxvi`i'' {
+         local maxvi=`maxvi`i''
+      }
+      if `zmaxvi'<`zmaxvi`i'' {
+         local zmaxvi=`zmaxvi`i''
+      }
+      *set trace on
+      local t=`loevHj'[1,`i']
+      local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i''
+      if `vi`i''!=0 {
+         di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata  traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}"
+      }
+      else {
+         di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i''  _col(93) %4.0f `crit`i'' _col(99) "{stata  traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}"
+      }
+      if "`details'"!=""&`i'!=`nbitems' {
+         di in green "{dup 97:-}"
+      }
+      local ac=`ac'+`ac`i''
+      local vi=`vi'+`vi`i''
+   }
+   di in green "{hline 97}"
+      di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi'
+   di in green "{hline 97}"
+}
+/*if  "`nirestscore'"!="" {
+*set trace on
+   if "`nirestscore'"=="*" {
+      anaoption
+   }
+   else {
+      anaoption,`nirestscore'
+   }
+   local minvi=r(minvi)
+   local siglevel=r(siglevel)
+   local minsize=r(minsize)
+   local details `r(details)'
+   if `minsize'==0 {
+      if `nbobs'>500 {
+         local minsize=round(`nbobs'/10)
+      }
+      else if `nbobs'>250 {
+         local minsize=round(`nbobs'/5)
+      }
+      else {
+         local minsize=max(50,round(`nbobs'/3))
+      }
+   }
+
+*set trace on
+   tempname score
+   qui genscore `varlist',score(`score')
+   di
+   di in green _col(10) "Summary per item for check of Non-Intersection via Rest-score"
+   di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel'
+   di
+   di in green "Items"  _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax"  _col(84) "#zsig"  _col(93) "Crit"
+   di in green "{hline 97}"
+*set trace on
+   local vi=0
+   local ac=0
+   local sumvi=0
+   local maxvi=0
+   local zmaxvi=0
+   local nbzvi=0
+   forvalues i=1/`nbitems' {
+      local vi`i'`j'=0
+      local ac`i'=0
+      local sumvi`i'=0
+      local maxvi`i'=0
+      local zmaxvi`i'=0
+      local nbzvi`i'=0
+      forvalues l=1/`m`i'' {
+         local vi`i'_m`l'=0
+         local ac`i'_m`l'=0
+         local sumvi`i'_m`l'=0
+         local maxvi`i'_m`l'=0
+         local zmaxvi`i'_m`l'=0
+         local nbzvi`i'_m`l'=0
+         local vi`i'_`l'=0
+         local ac`i'_`l'=0
+         local sumvi`i'_`l'=0
+         local maxvi`i'_`l'=0
+         local zmaxvi`i'_`l'=0
+      }
+      forvalues j=1/`nbitems' {
+         if `j'!=`i' {
+            tempname restscorei`i'j`j'
+            qui gen `restscorei`i'j`j''=`score'-``i''-``j''
+            local restscoremax`i'=`scoremax'-`m`i''
+            tempname restgroupi`i'j`j'
+            qui gengroup `restscorei`i'j`j'',newvariable(`restgroupi`i'j`j'') minsize(`minsize')
+            local listi`i'j`j'=r(list)
+            qui su `restgroupi`i'j`j''
+            local nbgroupsi`i'j`j'=r(max)
+            forvalues k=0/`nbgroupsi`i'j`j'' {
+               qui count if `restgroupi`i'j`j''==`k'
+               local rgroup`k'=r(N)
+            }
+            forvalues l=1/`m`i'' {
+               forvalues k=1/`m`j'' {
+                  forvalues m=1/`nbgroupsi`i'j`j'' {
+                      qui count if `restgroupi`i'j`j''==`m'&``i''>=`l'&``j''>=`k'
+                      local nbitemi`i'j`j'rgroup`m'_`l'_`k'=r(N)
+                      forvalues n=1/`=`m'-1' {
+                         local diff=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''
+                         if `nbitemi`i'j`j'rgroup`m'_`l'_`k''!=`rgroup`m''&`nbitemi`i'j`j'rgroup`m'_`l'_`k''!=0 {
+                         local ac`i'_`l'=`ac`i'_`l''+1
+                         if `diff'>`minvi' {
+                            local vi`i'_`l'=`vi`i'_`l''+1
+                            local sumvi`i'_`l'=`sumvi`i'_`l''+`diff'
+                            if `diff'>`maxvi`i'_`l'' {
+                               local maxvi`i'_`l'=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''
+                            }
+                            local p=(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+`nbitemi`i'j`j'rgroup`m'_`l'_`k'')/(`rgroup`m''+`rgroup`n'')
+                            local z=abs(2*(sqrt(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)*sqrt(`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)-sqrt((`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k'')*`nbitemi`i'j`j'rgroup`m'_`l'_`k''))/sqrt(`rgroup`m''+`rgroup`n''-1))
+                            if `z'>`=invnorm(1-`siglevel')' {
+                               local nbzvi`i'_`l'=`nbzvi`i'_`l''+1
+                            }
+                            if `z'>`zmaxvi`i'_`l'' {
+                               local zmaxvi`i'_`l'=`z'
+                            }
+                         }
+                      }
+                      if `m'==`nbgroupsi`i'j`j'' {
+                         local vi`i'_m`l'=`vi`i'_`l''
+                         local ac`i'_m`l'=`ac`i'_`l''
+                         local sumvi`i'_m`l'=`sumvi`i'_`l''
+                         local maxvi`i'_m`l'=`maxvi`i'_`l''
+                         local zmaxvi`i'_m`l'=`zmaxvi`i'_`l''
+                         *local nbzvi`i'_m`l'=`nbzvi`i'_`l''
+                      }
+                  }
+               }
+               local vi`i'=`vi`i''+`vi`i'_`l''
+               local ac`i'=`ac`i''+`ac`i'_`l''
+               local sumvi`i'=`sumvi`i''+`sumvi`i'_`l''
+               *local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l''
+               if `maxvi`i''<`maxvi`i'_`l'' {
+                  local maxvi`i'=`maxvi`i'_`l''
+               }
+               if `zmaxvi`i''<`zmaxvi`i'_`l'' {
+                  local zmaxvi`i'=`zmaxvi`i'_`l''
+               }
+            }
+         }
+      }
+      if "`details'"!=""&`m`i''!=1 {
+         forvalues l=1/`m`i'' {
+            if `vi`i'_m`l''!=0 {
+               di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l''
+            }
+            else {
+               di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l''
+            }
+         }
+         di in green "{dup 97:-}"
+      }
+      local vi=`vi'+`vi`i''
+      local ac=`ac'+`ac`i''
+      local sumvi=`sumvi'+`sumvi`i''
+      local nbzvi=`nbzvi'+`nbzvi`i''
+      if `maxvi'<`maxvi`i'' {
+         local maxvi=`maxvi`i''
+      }
+      if `zmaxvi'<`zmaxvi`i'' {
+         local zmaxvi=`zmaxvi`i''
+      }
+      *set trace on
+      local t=`loevHj'[1,`i']
+      local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i''
+      if `vi`i''!=0 {
+         di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata  traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}"
+      }
+      else {
+         di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i''  _col(93) %4.0f `crit`i'' _col(99) "{stata  traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}"
+      }
+      if "`details'"!=""&`i'!=`nbitems' {
+         di in green "{dup 97:-}"
+      }
+      local ac=`ac'+`ac`i''
+      local vi=`vi'+`vi`i''
+   }
+   di in green "{hline 97}"
+      di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi'
+   di in green "{hline 97}"
+}    */
+
+if "`ppp'"!=""|"pmm"!=""|"`nipmatrix'"!=""|"`generror'"!="" {
+    local list
+    local listi
+    local listm
+    local listv
+    forvalues i=1/`nbitems' {
+       forvalues l=1/`m`i'' {
+          tempname item`i'_`l'
+          qui gen `item`i'_`l''=``i''>=`l' if ``i''!=.
+          local list `list' ``i''_`l'
+          local listi `listi' ``i''
+          local listm `listm' `l'
+          local listv `listv' `item`i'_`l''
+       }
+    }
+    tempname matppp matpmm
+    matrix `matppp'=J(`=`scoremax'',`=`scoremax'+2',0)
+    matrix `matpmm'=J(`=`scoremax'',`=`scoremax'+2',0)
+    local row=1
+    forvalues i=1/`nbitems' {
+       forvalues k=1/`m`i'' {
+          local col=1
+          forvalues j=1/`nbitems' {
+             forvalues l=1/`m`j'' {
+                if `i'!=`j' {
+                   qui count if `item`i'_`k''!=.&`item`j'_`l''!=.
+                   local denom=r(N)
+                   qui count if `item`i'_`k''==1&`item`j'_`l''==1
+                   local pos=r(N)
+                   matrix `matppp'[`row',`col']=`=`pos'/`denom''
+                   qui count if `item`i'_`k''==0&`item`j'_`l''==0
+                   local pos=r(N)
+                   matrix `matpmm'[`row',`col']=`=`pos'/`denom''
+                }
+                else {
+                   matrix `matppp'[`row',`col']=-1
+                   matrix `matpmm'[`row',`col']=-1
+                }
+                local col=`col'+1
+             }
+          }
+          qui count if `item`i'_`k''!=.
+          local denom=r(N)
+          qui count if `item`i'_`k''==1
+          local pos=r(N)
+          matrix `matppp'[`row',`col']=`=`pos'/`denom''
+          qui count if `item`i'_`k''==0
+          local pos=r(N)
+          matrix `matpmm'[`row',`col']=`=`pos'/`denom''
+          matrix `matppp'[`row',`=`scoremax'+2']=`i'
+          matrix `matpmm'[`row',`=`scoremax'+2']=`i'
+          local row=`row'+1
+       }
+    }
+    matrix colnames `matppp'=`list' p1 item
+    matrix rownames `matppp'=`list'
+    matrix colnames `matpmm'=`list' p1 item
+    matrix rownames `matpmm'=`list'
+    if "`nipmatrix'"!="" {
+       if "`nipmatrix'"=="*" {
+          anaoption
+       }
+       else {
+          anaoption,`nipmatrix'
+       }
+       local minvi=`r(minvi)'
+       local siglevel=`r(siglevel)'
+       local minsize=`r(minsize)'
+       local details `r(details)'
+       if `minsize'==0 {
+          if `nbobs'>500 {
+             local minsize=round(`nbobs'/10)
+          }
+          else if `nbobs'>250 {
+             local minsize=round(`nbobs'/5)
+          }
+          else {
+             local minsize=max(50,round(`nbobs'/3))
+          }
+       }
+       forvalues i=1/`nbitems' {
+          local nbacpp`i'=0
+          local nbvipp`i'=0
+          local maxvipp`i'=0
+          local sumvipp`i'=0
+          local zmaxpp`i'=0
+          local nbsigzpp`i'=0
+          local nbacmm`i'=0
+          local nbvimm`i'=0
+          local maxvimm`i'=0
+          local sumvimm`i'=0
+          local zmaxmm`i'=0
+          local nbsigzmm`i'=0
+       }
+    }
+
+}
+tempfile temporaryfile
+qui save `temporaryfile'
+
+if "`ppp'"!=""|"`nipmatrix'"!=""|"`generror'"!="" {
+    drop *
+    qui svmat `matppp',names(col)
+    qui recode `list' (-1=.)
+    qui gen `id'=_n
+    qui gen str9 `item'=""
+    local connect "l"
+    local list2
+    local listw2
+    sort p1
+    qui set obs `=`scoremax'+1'
+    local listitem
+    forvalues i=1/`scoremax' {
+        local t=item[`i']
+        local listitem `listitem' `t'
+        local w:word `i' of `list'
+        qui replace `item'="`w'" if `id'==`i'
+        qui replace `w'=. if `id'==`i'
+        local connect "`connect' l"
+        local z=regexr("`w'","_",">=")
+        label define `monlabel' `i' "`z'", add
+        label variable `w' "`z'"
+        qui su p1 if `id'==`i'
+        local prop=r(mean)
+        qui replace `w'=`prop' in `=`scoremax'+1'
+    }
+    forvalues i=1/`scoremax' {
+        local v=`item'[`i']
+        local list2 `list2' `v'
+        local v=`id'[`i']
+        local listw2 `listw2' `v'
+    }
+    label define `monlabel' `=`scoremax'+1' "Prop",add
+    order `list2'
+    qui gen `id2'=_n
+    label value `id2' `monlabel'
+    label variable `id2' " "
+    if "`graph'"!="" {
+       twoway conn `list' `id2' in 1/`scoremax',connect(`connect') ytitle("") title("P++ diagnostics") name(ppp,replace)
+    }
+    format `list' %5.3f
+    label variable `id' "Item"
+    rename `id' Item
+    label value Item `monlabel'
+    qui replace Item=`=`scoremax'+1' in `=`scoremax'+1'
+    tempname matpp
+    matrix define `matpp'=J(`scoremax',`scoremax',0)
+    forvalues i=1/`scoremax' {
+       forvalues j=1/`scoremax' {
+          local ti:word `i' of `listv'
+          local tj:word `j' of `listv'
+          local t:word `j' of `list2'
+          matrix `matpp'[`i',`j']=`t'[`i']
+       }
+    }
+    matrix colnames `matpp'=`list2'
+    matrix rownames `matpp'=`list2'
+    if "`ppp'"!="" {
+       di
+       di in green _col(10) "P++ values per items pair (The values should be increasing in each column)"
+
+       matrix list `matpp',format(%5.3f)  nohalf   noheader
+    }
+    label drop `monlabel'
+    *set trace on
+    qui use "`temporaryfile'",clear
+    if "`nipmatrix'"!="" {
+       forvalues i=1/`scoremax' {
+          forvalues j=1/`scoremax' {
+             forvalues k=`=`j'+1'/`scoremax' {
+*di "`listv' `listw2'"
+                local ti:word `i' of `listitem'
+                local tj:word `j' of `listitem'
+                local tk:word `k' of `listitem'
+                if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ {
+                   local ++nbacpp`ti'
+                   *local ++nbacmm`tk'
+                   local diff=`matpp'[`j',`i']-`matpp'[`k',`i']
+                   if `diff'>`minvi'&`diff'!=. {
+                      local ++nbvipp`tj'
+                      local ++nbvipp`tk'
+                      local sumvipp`tj'=`sumvipp`tj''+`diff'
+                      local sumvipp`tk'=`sumvipp`tk''+`diff'
+                      if `diff'>`maxvipp`tj'' {
+                         local maxvipp`tj'=`diff'
+                      }
+                      if `diff'>`maxvipp`tk'' {
+                         local maxvipp`tk'=`diff'
+                      }
+                      local wi:word `i' of `listw2'
+                      local wj:word `j' of `listw2'
+                      local wk:word `k' of `listw2'
+                      local li:word `wi' of `listv'
+                      local lj:word `wj' of `listv'
+                      local lk:word `wk' of `listv'
+                      local ii:word `wi' of `list'
+                      local ij:word `wj' of `list'
+                      local ik:word `wk' of `list'
+
+                      qui count if `li'==1&`lj'==1&`lk'==0
+                      local a=r(N)
+                      qui count if `li'==1&`lj'==0&`lk'==1
+                      local b=r(N)
+                      local n=`a'+`b'
+                      local k=`b'
+                      local b=((2*`k'+1-`n')^2-10*`n')/(12*`n')
+                      local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b')
+                      *di "++ `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'"
+
+                      if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. {
+                         local ++nbsigzpp`tj'
+                         if abs(`z')>`zmaxpp`tj'' {
+                            local zmaxpp`tj'=abs(`z')
+                         }
+                         local ++nbsigzpp`tk'
+                         if abs(`z')>`zmaxpp`tk'' {
+                            local zmaxpp`tk'=abs(`z')
+                         }
+                      }
+                   }
+                }
+             }
+          }
+       }
+    }
+/*    if "`nipmatrix'"!="" {
+       forvalues i=1/`scoremax' {
+          forvalues j=1/`scoremax' {
+             forvalues k=`=`j'+1'/`scoremax' {
+                local ti:word `i' of `listitem'
+                local tj:word `j' of `listitem'
+                local tk:word `k' of `listitem'
+                if `tj'!= `tk'&`ti'!=`tk'&`ti'!=`tj' {
+                   local ++nbacpp`ti'
+                   local diff=`matpp'[`j',`i']-`matpp'[`k',`i']
+                   if `diff'>`minsize'&`diff'!=. {
+                      local ++nbvipp`tj'
+                      local ++nbvipp`tk'
+                      local sumvipp`tj'=`sumvipp`tj''+`diff'
+                      local sumvipp`tk'=`sumvipp`tk''+`diff'
+                      if `diff'>`maxvipp`tj'' {
+                         local maxvipp`tj'=`diff'
+                      }
+                      if `diff'>`maxvipp`tk'' {
+                         local maxvipp`tk'=`diff'
+                      }
+                   }
+                }
+             }
+          }
+       }
+    }
+*/
+}
+if "`pmm'"!=""|"`nipmatrix'"!="" {
+    drop _all
+    qui svmat `matpmm',names(col)
+    qui recode `list' (-1=.)
+    qui gen `id'=_n
+    qui gen str9 `item'=""
+    local connect "l"
+    local list2
+    local listw2
+    gsort -p1
+    qui set obs `=`scoremax'+1'
+    forvalues i=1/`scoremax' {
+        local w:word `i' of `list'
+        qui replace `item'="`w'" if `id'==`i'
+        qui replace `w'=. if `id'==`i'
+        local connect "`connect' l"
+        local z=regexr("`w'","_",">=")
+        label define `monlabel' `i' "`z'", add
+        label variable `w' "`z'"
+        qui su p1 if `id'==`i'
+        local prop=r(mean)
+        qui replace `w'=`prop' in `=`scoremax'+1'
+    }
+    forvalues i=1/`scoremax' {
+        local v=`item'[`i']
+        local list2 `list2' `v'
+        local v=`id'[`i']
+        local listw2 `listw2' `v'
+    }
+    label define `monlabel' `=`scoremax'+1' "Prop",add
+    order `list2'
+    qui gen `id2'=_n
+    label value `id2' `monlabel'
+    label variable `id2' " "
+    if "`graph'"!="" {
+       twoway conn `list' `id2' in 1/`scoremax',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace)
+    }
+    format `list' %5.3f
+    label variable `id' "Item"
+    rename `id' Item
+    label value Item `monlabel'
+    qui replace Item=`=`scoremax'+1' in `=`scoremax'+1'
+    tempname matmm
+    matrix define `matmm'=J(`scoremax',`scoremax',0)
+    forvalues i=1/`scoremax' {
+       forvalues j=1/`scoremax' {
+          local t:word `j' of `list2'
+          matrix `matmm'[`i',`j']=`t'[`i']
+       }
+    }
+    matrix colnames `matmm'=`list2'
+    matrix rownames `matmm'=`list2'
+    if "`pmm'"!="" {
+       di
+       di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)"
+       matrix list `matmm',format(%5.3f)  nohalf   noheader
+    }
+    label drop `monlabel'
+    qui use "`temporaryfile'",clear
+    if "`nipmatrix'"!="" {
+       forvalues i=1/`scoremax' {
+          forvalues j=1/`scoremax' {
+             forvalues k=`=`j'+1'/`scoremax' {
+*di "`listv' `listw2'"
+                local ti:word `i' of `listitem'
+                local tj:word `j' of `listitem'
+                local tk:word `k' of `listitem'
+                if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ {
+                   local ++nbacmm`ti'
+                   *local ++nbacmm`tk'
+                   local diff=`matmm'[`k',`i']-`matmm'[`j',`i']
+                   if `diff'>`minvi'&`diff'!=. {
+                      local ++nbvimm`tj'
+                      local ++nbvimm`tk'
+                      local sumvimm`tj'=`sumvimm`tj''+`diff'
+                      local sumvimm`tk'=`sumvimm`tk''+`diff'
+                      if `diff'>`maxvimm`tj'' {
+                         local maxvimm`tj'=`diff'
+                      }
+                      if `diff'>`maxvimm`tk'' {
+                         local maxvimm`tk'=`diff'
+                      }
+                      local wi:word `i' of `listw2'
+                      local wj:word `j' of `listw2'
+                      local wk:word `k' of `listw2'
+                      local li:word `wi' of `listv'
+                      local lj:word `wj' of `listv'
+                      local lk:word `wk' of `listv'
+                      local ii:word `wi' of `list'
+                      local ij:word `wj' of `list'
+                      local ik:word `wk' of `list'
+
+                      qui count if `li'==0&`lj'==1&`lk'==0
+                      local a=r(N)
+                      qui count if `li'==0&`lj'==0&`lk'==1
+                      local b=r(N)
+                      local n=`a'+`b'
+                      local k=`b'
+                      local b=((2*`k'+1-`n')^2-10*`n')/(12*`n')
+                      local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b')
+                      *di "-- `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'"
+
+                      if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. {
+                         local ++nbsigzmm`tj'
+                         if abs(`z')>`zmaxmm`tj'' {
+                            local zmaxmm`tj'=abs(`z')
+                         }
+                         local ++nbsigzmm`tk'
+                         if abs(`z')>`zmaxmm`tk'' {
+                            local zmaxmm`tk'=abs(`z')
+                         }
+                      }
+                   }
+                }
+             }
+          }
+       }
+    }
+}
+if "`nipmatrix'"!="" {
+   *set trace on
+   di
+   di in green _col(10) "Summary per item for check of non-Intersection via Pmatrix"
+   di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) /*in green "Minsize=" in ye %5.0f `minsize' _col(40)*/ in green "Alpha=" in ye %5.3f `siglevel'
+   di
+   di in green "Items"  _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax"  _col(84) "#zsig"  _col(93) "Crit"
+   di in green "{hline 97}"
+   forvalues i=1/`nbitems' {
+      local nbac`i'=`nbacpp`i''+`nbacmm`i''
+      local nbvi`i'=`nbvipp`i''+`nbvimm`i''
+      local maxvi`i'=max(`maxvipp`i'',`maxvimm`i'')
+      local sumvi`i'=`sumvipp`i''+`sumvimm`i''
+      local zmaxvi`i'=max(`zmaxpp`i'',`zmaxmm`i'')
+
+      local nbzsig`i'=`nbsigzpp`i''+`nbsigzmm`i''
+      local zmax`i'=0
+      *local nbsigz`i'=0
+      local t=`loevHj'[1,`i']
+*      di "local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmax`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i''     "
+      local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmaxvi`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i''
+
+      *di `nbac`i'' "   " `nbvi`i'' "   " `sumvi`i''
+      if `nbvi`i''!=0 {
+         di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(33) %6.4f `=`nbvi`i''/`nbac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`nbac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzsig`i'' _col(93) %4.0f `crit`i''
+      }
+      else {
+         di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i''  _col(93) %4.0f `crit`i''
+      }
+   }
+}
+
+/*if "`pmm'"!="" {
+    drop _all
+    matrix `P00g'=`P00',`P1''
+    matrix colnames `P00g'=`varlist' `p1'
+    matrix rownames `P00g'=`varlist'
+    qui svmat `P00g' , names(col)
+    qui gen `id'=_n
+    qui gen str9 `item'=""
+    local connect "l"
+    forvalues i=1/`nbitems' {
+        qui replace `item'="``i''" if `id'==`i'
+        qui replace ``i''=. if `id'==`i'
+        local connect "`connect' l"
+        label define `monlabel' `i' "``i''", add
+    }
+    sort `p1'
+    qui gen `id2'=_n
+    label value `id2' `monlabel'
+    label variable `id2' " "
+    if "`graph'"!="" {
+       twoway connected `varlist' `id2',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace)
+    }
+    format `varlist' %5.3f
+    label variable `id' "Item"
+    label value `id' `monlabel'
+    di
+    di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)"
+    list `id' `varlist' , table compress separator(`nbitems') noobs divider
+    label drop `monlabel'
+}
+
+
+
+if "`pairwise'"=="" {
+   restore, not
+}*/
+
+
+*di "listw2:`listw2'"
+*di "listv:`listv'"
+*di "list:`list'"
+*di "listi:`listi'"
+*di "listm:`listm'"
+*di "listitem:`listitem'"
+
+
+qui use "`loevHfile'",clear
+*set trace on
+if "`generror'"!="" {
+   if "`replace'"!="" {
+      capture drop `generror'_0
+      capture drop `generror'_H
+      capture drop `generror'_max
+      capture drop `generror'_GPN
+      capture drop `generror'
+   }
+   qui gen `generror'=0
+   *forvalues i=1/`nbitems' {
+   *   qui gen `generror'_``i''=0
+   *}
+   qui gen `generror'_0=`eGutt0'/`nb'
+   local nbsteps:word count `listitem'
+   if "`pairwise'"=="" {
+      forvalues i=1/`nbitems' {
+         qui replace `generror'=. if ``i''==.
+         qui replace `generror'_0=. if ``i''==.
+      }
+   }
+   forvalues i=0/`nbsteps' {
+       qui guttmax `listitem', score(`i')
+       local errmax`i'=r(maxegutt)
+   }
+*   matrix list `P0'
+   forvalues i=1/`nbsteps' {
+      forvalues j=`=`i'+1'/`nbsteps' {
+         local w2i:word `i' of `listw2'
+         local w2j:word `j' of `listw2'
+         local itemi:word `w2i' of `listi'
+         local modai:word `w2i' of `listm'
+         local itemj:word `w2j' of `listi'
+         local modaj:word `w2j' of `listm'
+         qui replace `generror'=`generror'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.
+         *qui replace `generror'_`itemi'=`generror'_`itemi'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.
+         *qui replace `generror'_`itemj'=`generror'_`itemj'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.
+*         qui replace `generror'=`generror'+.5 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.&`P1'[1,`i']==`P1'[1,`j']
+         *qui replace `generror'=`generror'+.5 if `P1'[1,`i']==`P1'[1,`j']&``i''==1&``j''==0
+      }
+   }
+*   set trace on
+   tempvar flag
+   qui gen `flag'=0
+   qui replace `flag'=1 `if'
+   qui replace `generror'=. if `flag'==0
+   qui replace `generror'_0=.  if `flag'==0
+   qui gen `generror'_H=1-`generror'/`generror'_0
+   tempvar score
+   qui genscore `varlist' `if',score(`score')
+   qui gen `generror'_max=.
+   forvalues i=1/`nbsteps' {
+      qui replace `generror'_max=`errmax`i'' if `score'==`i'
+   }
+   qui gen `generror'_GPN=`generror'/`generror'_max
+   label variable `generror' "Number of Guttman errors per individual"
+   label variable `generror'_H "H indice per individual"
+   if "`graph'"!="" {
+      qui histogram `generror',discrete freq name(errors,replace)
+      qui histogram `generror'_H,discrete freq name(H,replace)
+   }
+   qui su `generror'  ,det
+   local meane=r(mean)
+   local mede=r(p50)
+   local mine=r(min)
+   local maxe=r(max)
+   qui su `generror'_GPN  ,det
+   local meanGPN=r(mean)
+   local medGPN=r(p50)
+   local minGPN=r(min)
+   local maxGPN=r(max)
+   di
+   di in green "Number of Guttman errors by individual"        _col(50) in green "Normalized number of Guttamn errors by individual"
+   di in green "            Mean number: " in ye %7.2f `meane' _col(50) in green "            Mean number: " in ye %7.2f `meanGPN'
+   di in green "          Median number: " in ye %7.2f `mede'  _col(50) in green "          Median number: " in ye %7.2f `medGPN'
+   di in green "         Minimal number: " in ye %7.2f `mine'  _col(50) in green "         Minimal number: " in ye %7.2f `minGPN'
+   di in green "         Maximal number: " in ye %7.2f `maxe'  _col(50) in green "         Maximal number: " in ye %7.2f `maxGPN'
+   di in green "Expected Guttman errors: " in ye %7.2f `=`eGutt0'/`nb''
+   qui count if `generror'_H<0
+   di in green "           Rate of Hn<0: " in ye %7.2f `=r(N)/`nb'*100' "%"
+
+}
+
+matrix colnames `loevHj'=`varlist'
+matrix rownames `loevHj'=Hj
+return matrix loevHj `loevHj'
+
+matrix colnames `loevHjk'=`varlist'
+matrix rownames `loevHjk'=`varlist'
+return matrix loevHjk `loevHjk'
+
+matrix colnames `eGuttj'=`varlist'
+matrix rownames `eGuttj'=ej
+return matrix eGuttj `eGuttj'
+
+matrix colnames `eGuttjk'=`varlist'
+matrix rownames `eGuttjk'=`varlist'
+return matrix eGuttjk `eGuttjk'
+
+matrix colnames `eGuttj0'=`varlist'
+matrix rownames `eGuttj0'=ejk
+return matrix eGuttj0 `eGuttj0'
+
+matrix colnames `eGuttjk0'=`varlist'
+matrix rownames `eGuttjk0'=`varlist'
+return matrix eGuttjk0 `eGuttjk0'
+
+return scalar loevH=`loevH'
+return scalar eGutt =`eGutt'
+return scalar eGutt0 =`eGutt0'
+
+if `modamax'==1 {
+   matrix colnames `P11'=`varlist'
+   matrix rownames `P11'=`varlist'
+   return matrix P11 `P11'
+}
+
+matrix colnames `P00'=`varlist'
+matrix rownames `P00'=`varlist'
+return matrix P00 `P00'
+
+if "`ppp'"!=""|"`nipmatrix'"!="" {
+   return matrix ppp=`matpp'
+}
+if "`pmm'"!=""|"`nipmatrix'"!="" {
+   return matrix pmm=`matmm'
+}
+
+matrix colnames `zHj'=`varlist'
+matrix rownames `zHj'=zHj
+return matrix zHj `zHj'
+
+matrix colnames `pvalHj'=`varlist'
+matrix rownames `pvalHj'=pval
+return matrix pvalHj `pvalHj'
+
+return scalar zH=`zH'
+return scalar pvalH=`pvalH'
+if "`pair'"!="" {
+    matrix colnames `zHjk'=`varlist'
+    matrix rownames `zHjk'=`varlist'
+    return matrix zHjk `zHjk'
+
+    matrix colnames `pvalHjk'=`varlist'
+    matrix rownames `pvalHjk'=`varlist'
+    return matrix pvalHjk `pvalHjk'
+}
+
+matrix colnames `Obs'=`varlist'
+matrix rownames `Obs'=`varlist'
+return matrix Obs `Obs'
+
+capture restore, not
+
+end
diff --git a/Modules/ado/personal/l/loevH73.ado b/Modules/ado/personal/l/loevH73.ado
new file mode 100644
index 0000000..4d3b65a
--- /dev/null
+++ b/Modules/ado/personal/l/loevH73.ado
@@ -0,0 +1,1234 @@
+*! Version 7.3 15 August 2009
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Stata program : LoevH
+* Loevinger H indexes, Mokken Analysis
+* Release 7.3: August 15, 2009  /*Print the difficulties of the items instead of P(X=0)*/
+*
+*
+* Historic :
+* Version 1 (August 20, 2002) [Jean-Benoit Hardouin]
+* Version 2 (June 22, 2003) [Jean-Benoit Hardouin]
+* Version 3 (December 1, 2003) [Jean-Benoit Hardouin]
+* Version 4 (January 20, 2004) [Jean-Benoit Hardouin]
+* Version 5 (March 22, 2004) [Jean-Benoit Hardouin]
+* Version 6 (July 3, 2004) [Jean-Benoit Hardouin]
+* Version 6.1 (September 19, 2005) [Jean-Benoit Hardouin]
+* Version 6.2 (January 31, 2006) [Jean-Benoit Hardouin]
+* Release 6.3 (March 20, 2006) [Jean-Benoit Hardouin]  /*A bug with temporary files */
+* Release 6.4 (January 19, 2007) [Jean-Benoit Hardouin]  /*Tests to compare Loevinger coefficients to 0 identical to the MSP software (dichotomous and polytomous case)*/
+* Release 6.5 (January 22, 2007) [Jean-Benoit Hardouin]  /*Correction of a bug concerning the p-values with the pair option*/
+* Release 6.6 (Februar 16, 2007) [Jean-Benoit Hardouin]  /*Correction of a bug with the displaying of Easyness with polytomous items, option graph, option generror, improvements*/
+* Release 7: June 21, 2007  /*Check of  monotonicity and Non intersection via P matrices*/
+* Release 7.1: November 6, 2008  /*Correction for the z-tests for the check of non intersection via P matrices*/
+* Release 7.2: November 19, 2008  /*Implementation of the GPN indexes*/
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences  (UPRES EA 4275)
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* Requiered Stata modules:
+* -anaoption- (version 1)
+* -traces- (version 3.2)
+* -gengroup- (version 1)
+* -guttmax- (version 1)
+*
+* News about this program :http://www.anaqol.org
+* FreeIRT Project website : http://www.freeirt.org
+*
+* Copyright 2002-2008 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+***********************************************************************************************************
+
+program define loevH , rclass
+version 8.2
+syntax varlist(min=2 numeric) [if] [,PAIRWise PAIR ppp pmm noADJust GENERror(string) REPlace GRaph MONOtonicity(string) NIRESTscore(string) NIPmatrix(string)]
+preserve
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+tempname corr cov P1 P0 diff P11 P00 H1jk vHjk zHjk chi2Hjk dfHjk pvalHjk H1j vHj zHj pvalHj H1 vH zH pvalH Obs eGuttjk eGuttjk0 loevHjk eGuttj eGuttj0 loevHj eGutt eGutt0 loevH e1 e2
+tempfile loevHfile
+qui save "`loevHfile'"
+
+if "`if'"!="" {
+   qui keep `if'
+}
+
+if "`adjust'"!="" {
+   local adj=0
+}
+else {
+   local adj=1
+}
+
+qui count
+local nbobs=r(N)
+
+forvalues j=1/`nbitems' {
+   if "`pairwise'"=="" {
+       qui drop if ``j''==.
+   }
+}
+qui count
+local nbtotindnm=r(N)
+
+matrix define `eGuttjk'=J(`nbitems',`nbitems',0)
+matrix define `eGuttjk0'=J(`nbitems',`nbitems',0)
+matrix define `loevHjk'=J(`nbitems',`nbitems',0)
+matrix define `eGuttj'=J(1,`nbitems',0)
+matrix define `eGuttj0'=J(1,`nbitems',0)
+matrix define `loevHj'=J(1,`nbitems',0)
+scalar define `eGutt'=0
+scalar define `eGutt0'=0
+scalar define `loevH'=0
+matrix define `Obs'=J(`nbitems',`nbitems',0)
+matrix define `P00'=J(`nbitems',`nbitems',0)
+
+tempname modamax
+scalar `modamax'=0
+local scoremax=0
+forvalues j=1/`nbitems' {
+     qui su ``j''
+     local m`j'=r(max)
+     local scoremax=`scoremax'+`m`j''
+     if r(max)>`modamax' {
+        scalar `modamax'=r(max)
+     }
+     local nbHjkNS`j'=0
+}
+
+/*if "`generror'"!=""&`modamax'!=1 {
+   di in ye "It is not possible to define the {cmd:generror} option with polytomous items"
+   local generror
+} */
+*di "scoremax `scoremax'"
+if "`graph'"!=""&`scoremax'>19 {
+   di in ye "The {cmd:graph} option is disabled because of a large number of possible scores (>20)"
+   local graph
+}
+
+matrix define `cov'=J(`nbitems',`nbitems',0)
+matrix define `corr'=J(`nbitems',`nbitems',0)
+matrix define `P11'=J(`nbitems',`nbitems',0)
+matrix define `H1jk'=J(`nbitems',`nbitems',0)
+matrix define `vHjk'=J(`nbitems',`nbitems',0)
+matrix define `zHjk'=J(`nbitems',`nbitems',0)
+matrix define `pvalHjk'=J(`nbitems',`nbitems',0)
+matrix define `P1'=J(1,`nbitems',0)
+matrix define `P0'=J(1,`nbitems',0)
+matrix define `diff'=J(1,`nbitems',0)
+matrix define `H1j'=J(1,`nbitems',0)
+matrix define `vHj'=J(1,`nbitems',0)
+matrix define `zHj'=J(1,`nbitems',0)
+matrix define `pvalHj'=J(1,`nbitems',0)
+
+forvalues j=1/`nbitems' {
+    qui su ``j''
+    matrix `cov'[`j',`j']=r(Var)
+    matrix `corr'[`j',`j']=1
+    local tmp=`j'+1
+    qui count if ``j''!=.
+    matrix `Obs'[`j',`j']=r(N)
+    forvalues k=`tmp'/`nbitems' {
+        qui count if ``j''!=.&``k''!=.
+        matrix `Obs'[`j',`k']=r(N)
+        matrix `Obs'[`k',`j']=r(N)
+        qui corr ``j'' ``k'',cov
+        matrix `cov'[`j',`k']=r(cov_12)
+        matrix `cov'[`k',`j']=r(cov_12)
+        qui corr ``j'' ``k''
+        matrix `corr'[`j',`k']=r(rho)
+        matrix `corr'[`k',`j']=r(rho)
+        matrix `zHjk'[`j',`k']=`corr'[`j',`k']*(`Obs'[`j',`k']-`adj')^.5
+        matrix `zHjk'[`k',`j']=`H1jk'[`j',`k']
+        matrix `pvalHjk'[`j',`k']=1-norm(`zHjk'[`j',`k'])
+        matrix `pvalHjk'[`k',`j']=`pvalHjk'[`j',`k']
+        if `pvalHjk'[`j',`k']>0.05 {
+           local nbHjkNS`j'=`nbHjkNS`j''+1
+           local nbHjkNS`k'=`nbHjkNS`k''+1
+        }
+        forvalues mod1=1/`m`j'' {
+            forvalues mod2=1/`m`k'' {
+                qui count if ``j''<`mod1'&``k''>=`mod2'&``j''!=.&``k''!=.
+                scalar `e1'=r(N)
+                qui count if ``j''>=`mod1'&``k''<`mod2'&``j''!=.&``k''!=.
+                scalar `e2'=r(N)
+                matrix `eGuttjk'[`j',`k']=`eGuttjk'[`j',`k']+min(`e1',`e2')
+                qui count if ``j''<`mod1'&``j''!=.&``k''!=.
+                local t1=r(N)
+                qui count if ``k''<`mod2'&``j''!=.&``k''!=.
+                local t2=r(N)
+                qui count if ``j''>=`mod1'&``j''!=.&``k''!=.
+                local t3=r(N)
+                qui count if ``k''>=`mod2'&``j''!=.&``k''!=.
+                local t4=r(N)
+                if min(`e1',`e2')==`e1' {
+                    matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t1'*`t4'/`Obs'[`j',`k']
+                }
+                else {
+                    matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t2'*`t3'/`Obs'[`j',`k']
+                }
+
+            }
+        }
+        qui count if ``j''==0&``k''==0
+        matrix `P00'[`j',`k']=r(N)/`Obs'[`j',`k']
+        matrix `P00'[`k',`j']=r(N)/`Obs'[`k',`j']
+        if `modamax'==1 {
+           qui count if ``j''==1&``k''==1
+           matrix `P11'[`j',`k']=r(N)/`Obs'[`j',`k']
+           matrix `P11'[`k',`j']=r(N)/`Obs'[`k',`j']
+        }
+
+        matrix `eGuttjk'[`k',`j']=`eGuttjk'[`j',`k']
+        matrix `eGuttj'[1,`j']=`eGuttj'[1,`j']+`eGuttjk'[`j',`k']
+        matrix `eGuttj'[1,`k']=`eGuttj'[1,`k']+`eGuttjk'[`j',`k']
+        matrix `eGuttjk0'[`k',`j']=`eGuttjk0'[`j',`k']
+        matrix `eGuttj0'[1,`j']=`eGuttj0'[1,`j']+`eGuttjk0'[`j',`k']
+        matrix `eGuttj0'[1,`k']=`eGuttj0'[1,`k']+`eGuttjk0'[`j',`k']
+
+        matrix `loevHjk'[`j',`k']=1-`eGuttjk'[`j',`k']/`eGuttjk0'[`j',`k']
+        matrix `loevHjk'[`k',`j']=`loevHjk'[`j',`k']
+
+    }
+    qui count if ``j''!=.
+    local tmp=r(N)
+    qui count if ``j''==1
+    matrix `P1'[1,`j']=r(N)/`tmp'
+    qui count if ``j''==0
+    matrix `P0'[1,`j']=r(N)/`tmp'
+    qui su ``j''
+    matrix `diff'[1,`j']=r(mean)
+    matrix `loevHj'[1,`j']=1-`eGuttj'[1,`j']/`eGuttj0'[1,`j']
+    scalar `eGutt'=`eGutt'+`eGuttj'[1,`j']/2
+    scalar `eGutt0'=`eGutt0'+`eGuttj0'[1,`j']/2
+}
+scalar `H1'=0
+scalar `vH'=0
+scalar `zH'=0
+forvalues j=1/`nbitems'{
+   forvalues k=1/`nbitems' {
+      if `j'!=`k' {
+         matrix `zHj'[1,`j']=`zHj'[1,`j']+`cov'[`j',`k']
+         matrix `vHj'[1,`j']=`vHj'[1,`j']+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj')
+      }
+      if `j'<`k' {
+         scalar `zH'=`zH'+`cov'[`j',`k']
+         scalar `vH'=`vH'+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj')
+      }
+   }
+   matrix `zHj'[1,`j']=`zHj'[1,`j']/sqrt(`vHj'[1,`j'])
+   matrix `pvalHj'[1,`j']=1-norm(`zHj'[1,`j'])
+}
+scalar `zH'=`zH'/sqrt(`vH')
+scalar `pvalH'=1-norm(`zH')
+scalar `loevH'=1-`eGutt'/`eGutt0'
+
+if `modamax'==1 {
+   local text="Easyness"
+   local value=1
+   local col=23
+}
+else {
+   local text="Difficulty"
+   local value=0
+   local col=21
+}
+
+
+di in green  _col(35) "Observed" _col(47) "Expected" _col(93) "Number"
+di in green _col(27) "Mean" _col(36) "Guttman" _col(48) "Guttman" _col(59) "Loevinger" _col(83) "H0: Hj<=0" _col(94) "of NS"
+di in green "Item"  _col(15) "Obs" _col(26) "Score" _col(37) "errors" _col(49) "errors" _col(61) "H coeff" _col(73) "z-stat." _col(85) "p-value" _col(96) "Hjk"
+di in green "{hline 99}"
+forvalues j=1/`nbitems' {
+     di in green "``j''" in yellow _col(15) `Obs'[`j',`j'] _col(25) %6.4f `diff'[1,`j'] _col(38) %5.0f `eGuttj'[1,`j'] _col(47) %8.2f `eGuttj0'[1,`j'] _col(61) %7.5f `loevHj'[1,`j'] _col(72) %8.4f `zHj'[1,`j'] _col(85) %7.5f `pvalHj'[1,`j'] _col(97) %2.0f `nbHjkNS`j''
+}
+di in green "{hline 99}"
+if "`pairwise'"=="" {
+   local nb=`nbtotindnm'
+}
+else {
+   local nb=`nbobs'
+}
+di in green "Scale" in yellow _col(15) `nb' _col(38) %5.0f `eGutt' _col(47) %8.2f `eGutt0' _col(61) %-8.5f `loevH' _col(71) %9.4f `zH' _col(85) %7.5f `pvalH'
+
+if "`pair'"!="" {
+   di
+   di in green _col(45) "Observed" _col(57) "Expected"
+   di in green _col(`=`col'+10') "`text'" _col(46) "Guttman" _col(58) "Guttman" _col(69) "Loevinger" _col(92) "H0: Hjk<=0"
+   di in green "Items"  _col(25) "Obs" _col(29) "P(Xj=`value',Xk=`value')" _col(47) "errors" _col(59) "errors" _col(71) "H coeff" _col(83) "z-stat." _col(95) "p-value"
+   di in green "{hline 101}"
+   forvalues j=1/`nbitems' {
+      forvalues k=`=`j'+1'/`nbitems' {
+         qui count if ``j''!=.
+         local obs=r(N)
+         di in green "``j''" _col(10) "``k''" in yellow _col(25) `Obs'[`j',`k'] _col(35) %6.4f `P`value'`value''[`j',`k'] _col(48) %5.0f `eGuttjk'[`j',`k'] _col(57) %8.2f `eGuttjk0'[`j',`k'] _col(70) %8.5f `loevHjk'[`j',`k'] _col(81) %9.4f `zHjk'[`j',`k'] _col(95) %7.5f `pvalHjk'[`j',`k']
+      }
+   }
+   di in green "{hline 101}"
+}
+/*if `modamax'>1&"`ppp'"!="" {
+   di in green "It is not possible to obtain the P++ diagnostics with polytomous items"
+   local ppp
+}
+if `modamax'>1&"`pmm'"!="" {
+   di in green "It is not possible to obtain the P-- diagnostics with polytomous items"
+   local pmm
+} */
+
+tempname P11g P00g item id id2 p1 monlabel
+
+/*if "`monotonicity'"!=""&`modamax'>1 {
+   di in green "It is not possible to obtain the latent monotonicity diagnostics with polytomous items"
+   local monotonicity
+}  */
+
+if  "`monotonicity'"!="" {
+*set trace on
+   if "`monotonicity'"=="*" {
+      anaoption
+   }
+   else {
+      anaoption,`monotonicity'
+   }
+   local minvi=r(minvi)
+   local siglevel=r(siglevel)
+   local minsize=r(minsize)
+   local details `r(details)'
+   if `minsize'==0 {
+      if `nbobs'>500 {
+         local minsize=round(`nbobs'/10)
+      }
+      else if `nbobs'>250 {
+         local minsize=round(`nbobs'/5)
+      }
+      else {
+         local minsize=max(50,round(`nbobs'/3))
+      }
+   }
+
+*set trace on
+   tempname score
+   qui genscore `varlist',score(`score')
+   di
+   di in green _col(10) "Summary per item for check of monotonicity"
+   di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel'
+   di
+   di in green "Items"  _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax"  _col(84) "#zsig"  _col(93) "Crit"
+   di in green "{hline 97}"
+*set trace on
+   local vi=0
+   local ac=0
+   local sumvi=0
+   local maxvi=0
+   local zmaxvi=0
+   local nbzvi=0
+   forvalues i=1/`nbitems' {
+      tempname restscore`i'
+      qui gen `restscore`i''=`score'-``i''
+      local restscoremax`i'=`scoremax'-`m`i''
+      tempname restgroup`i'
+      qui gengroup `restscore`i'',newvariable(`restgroup`i'') minsize(`minsize')
+      local list`i'=r(list)
+      qui su `restgroup`i''
+      local nbgroups`i'=r(max)
+      forvalues j=0/`nbgroups`i'' {
+         qui count if `restgroup`i''==`j'
+         local rgroup`j'=r(N)
+      }
+      local vi`i'=0
+      local ac`i'=0
+      local sumvi`i'=0
+      local maxvi`i'=0
+      local zmaxvi`i'=0
+      local nbzvi`i'=0
+      forvalues l=1/`m`i'' {
+         local vi`i'_m`l'=0
+         local ac`i'_m`l'=0
+         local sumvi`i'_m`l'=0
+         local maxvi`i'_m`l'=0
+         local zmaxvi`i'_m`l'=0
+         local nbzvi`i'_m`l'=0
+      }
+      forvalues l=1/`m`i'' {
+         local vi`i'_`l'=0
+         local ac`i'_`l'=0
+         local sumvi`i'_`l'=0
+         local maxvi`i'_`l'=0
+         local zmaxvi`i'_`l'=0
+         local nbzvi`i'_`l'=0
+         forvalues j=1/`nbgroups`i'' {
+            qui count if `restgroup`i''==`j'&``i''>=`l'
+            local nbitem`i'rgroup`j'_`l'=r(N)
+            forvalues k=1/`=`j'-1' {
+               local diff=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j''
+               if `nbitem`i'rgroup`j'_`l''!=`rgroup`j''&`nbitem`i'rgroup`k'_`l''!=0 {
+                  local ac`i'_`l'=`ac`i'_`l''+1
+                  if `diff'>`minvi' {
+                     local vi`i'_`l'=`vi`i'_`l''+1
+                     local sumvi`i'_`l'=`sumvi`i'_`l''+`diff'
+                     if `diff'>`maxvi`i'_`l'' {
+                        local maxvi`i'_`l'=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j''
+                     }
+                     local p=(`nbitem`i'rgroup`k'_`l''+`nbitem`i'rgroup`j'_`l'')/(`rgroup`j''+`rgroup`k'')
+                     *local z=`diff'/sqrt(`p'*(1-`p')*(1/`rgroup`j''+1/`rgroup`k''))
+                     *di "local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1))      "
+                     local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1))
+                     *di "=`z'"
+                     if `z'>`=invnorm(1-`siglevel')' {
+                        local nbzvi`i'_`l'=`nbzvi`i'_`l''+1
+                     }
+                     if `z'>`zmaxvi`i'_`l'' {
+                        local zmaxvi`i'_`l'=`z'
+                     }
+                  }
+               }
+            }
+            if `j'==`nbgroups`i'' {
+               local vi`i'_m`l'=`vi`i'_`l''
+               local ac`i'_m`l'=`ac`i'_`l''
+               local sumvi`i'_m`l'=`sumvi`i'_`l''
+               local maxvi`i'_m`l'=`maxvi`i'_`l''
+               local zmaxvi`i'_m`l'=`zmaxvi`i'_`l''
+               local nbzvi`i'_m`l'=`nbzvi`i'_`l''
+            }
+         }
+         local vi`i'=`vi`i''+`vi`i'_`l''
+         local ac`i'=`ac`i''+`ac`i'_`l''
+         local sumvi`i'=`sumvi`i''+`sumvi`i'_`l''
+         local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l''
+         if `maxvi`i''<`maxvi`i'_`l'' {
+            local maxvi`i'=`maxvi`i'_`l''
+         }
+         if `zmaxvi`i''<`zmaxvi`i'_`l'' {
+            local zmaxvi`i'=`zmaxvi`i'_`l''
+         }
+      }
+
+      if "`details'"!=""&`m`i''!=1 {
+         forvalues l=1/`m`i'' {
+            if `vi`i'_m`l''!=0 {
+               di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l''
+            }
+            else {
+               di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l''
+            }
+         }
+         di in green "{dup 97:-}"
+      }
+      local vi=`vi'+`vi`i''
+      local ac=`ac'+`ac`i''
+      local sumvi=`sumvi'+`sumvi`i''
+      local nbzvi=`nbzvi'+`nbzvi`i''
+      if `maxvi'<`maxvi`i'' {
+         local maxvi=`maxvi`i''
+      }
+      if `zmaxvi'<`zmaxvi`i'' {
+         local zmaxvi=`zmaxvi`i''
+      }
+      *set trace on
+      local t=`loevHj'[1,`i']
+      local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i''
+      if `vi`i''!=0 {
+         di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata  traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}"
+      }
+      else {
+         di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i''  _col(93) %4.0f `crit`i'' _col(99) "{stata  traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}"
+      }
+      if "`details'"!=""&`i'!=`nbitems' {
+         di in green "{dup 97:-}"
+      }
+      local ac=`ac'+`ac`i''
+      local vi=`vi'+`vi`i''
+   }
+   di in green "{hline 97}"
+      di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi'
+   di in green "{hline 97}"
+}
+/*if  "`nirestscore'"!="" {
+*set trace on
+   if "`nirestscore'"=="*" {
+      anaoption
+   }
+   else {
+      anaoption,`nirestscore'
+   }
+   local minvi=r(minvi)
+   local siglevel=r(siglevel)
+   local minsize=r(minsize)
+   local details `r(details)'
+   if `minsize'==0 {
+      if `nbobs'>500 {
+         local minsize=round(`nbobs'/10)
+      }
+      else if `nbobs'>250 {
+         local minsize=round(`nbobs'/5)
+      }
+      else {
+         local minsize=max(50,round(`nbobs'/3))
+      }
+   }
+
+*set trace on
+   tempname score
+   qui genscore `varlist',score(`score')
+   di
+   di in green _col(10) "Summary per item for check of Non-Intersection via Rest-score"
+   di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel'
+   di
+   di in green "Items"  _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax"  _col(84) "#zsig"  _col(93) "Crit"
+   di in green "{hline 97}"
+*set trace on
+   local vi=0
+   local ac=0
+   local sumvi=0
+   local maxvi=0
+   local zmaxvi=0
+   local nbzvi=0
+   forvalues i=1/`nbitems' {
+      local vi`i'`j'=0
+      local ac`i'=0
+      local sumvi`i'=0
+      local maxvi`i'=0
+      local zmaxvi`i'=0
+      local nbzvi`i'=0
+      forvalues l=1/`m`i'' {
+         local vi`i'_m`l'=0
+         local ac`i'_m`l'=0
+         local sumvi`i'_m`l'=0
+         local maxvi`i'_m`l'=0
+         local zmaxvi`i'_m`l'=0
+         local nbzvi`i'_m`l'=0
+         local vi`i'_`l'=0
+         local ac`i'_`l'=0
+         local sumvi`i'_`l'=0
+         local maxvi`i'_`l'=0
+         local zmaxvi`i'_`l'=0
+      }
+      forvalues j=1/`nbitems' {
+         if `j'!=`i' {
+            tempname restscorei`i'j`j'
+            qui gen `restscorei`i'j`j''=`score'-``i''-``j''
+            local restscoremax`i'=`scoremax'-`m`i''
+            tempname restgroupi`i'j`j'
+            qui gengroup `restscorei`i'j`j'',newvariable(`restgroupi`i'j`j'') minsize(`minsize')
+            local listi`i'j`j'=r(list)
+            qui su `restgroupi`i'j`j''
+            local nbgroupsi`i'j`j'=r(max)
+            forvalues k=0/`nbgroupsi`i'j`j'' {
+               qui count if `restgroupi`i'j`j''==`k'
+               local rgroup`k'=r(N)
+            }
+            forvalues l=1/`m`i'' {
+               forvalues k=1/`m`j'' {
+                  forvalues m=1/`nbgroupsi`i'j`j'' {
+                      qui count if `restgroupi`i'j`j''==`m'&``i''>=`l'&``j''>=`k'
+                      local nbitemi`i'j`j'rgroup`m'_`l'_`k'=r(N)
+                      forvalues n=1/`=`m'-1' {
+                         local diff=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''
+                         if `nbitemi`i'j`j'rgroup`m'_`l'_`k''!=`rgroup`m''&`nbitemi`i'j`j'rgroup`m'_`l'_`k''!=0 {
+                         local ac`i'_`l'=`ac`i'_`l''+1
+                         if `diff'>`minvi' {
+                            local vi`i'_`l'=`vi`i'_`l''+1
+                            local sumvi`i'_`l'=`sumvi`i'_`l''+`diff'
+                            if `diff'>`maxvi`i'_`l'' {
+                               local maxvi`i'_`l'=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''
+                            }
+                            local p=(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+`nbitemi`i'j`j'rgroup`m'_`l'_`k'')/(`rgroup`m''+`rgroup`n'')
+                            local z=abs(2*(sqrt(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)*sqrt(`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)-sqrt((`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k'')*`nbitemi`i'j`j'rgroup`m'_`l'_`k''))/sqrt(`rgroup`m''+`rgroup`n''-1))
+                            if `z'>`=invnorm(1-`siglevel')' {
+                               local nbzvi`i'_`l'=`nbzvi`i'_`l''+1
+                            }
+                            if `z'>`zmaxvi`i'_`l'' {
+                               local zmaxvi`i'_`l'=`z'
+                            }
+                         }
+                      }
+                      if `m'==`nbgroupsi`i'j`j'' {
+                         local vi`i'_m`l'=`vi`i'_`l''
+                         local ac`i'_m`l'=`ac`i'_`l''
+                         local sumvi`i'_m`l'=`sumvi`i'_`l''
+                         local maxvi`i'_m`l'=`maxvi`i'_`l''
+                         local zmaxvi`i'_m`l'=`zmaxvi`i'_`l''
+                         *local nbzvi`i'_m`l'=`nbzvi`i'_`l''
+                      }
+                  }
+               }
+               local vi`i'=`vi`i''+`vi`i'_`l''
+               local ac`i'=`ac`i''+`ac`i'_`l''
+               local sumvi`i'=`sumvi`i''+`sumvi`i'_`l''
+               *local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l''
+               if `maxvi`i''<`maxvi`i'_`l'' {
+                  local maxvi`i'=`maxvi`i'_`l''
+               }
+               if `zmaxvi`i''<`zmaxvi`i'_`l'' {
+                  local zmaxvi`i'=`zmaxvi`i'_`l''
+               }
+            }
+         }
+      }
+      if "`details'"!=""&`m`i''!=1 {
+         forvalues l=1/`m`i'' {
+            if `vi`i'_m`l''!=0 {
+               di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l''
+            }
+            else {
+               di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l''
+            }
+         }
+         di in green "{dup 97:-}"
+      }
+      local vi=`vi'+`vi`i''
+      local ac=`ac'+`ac`i''
+      local sumvi=`sumvi'+`sumvi`i''
+      local nbzvi=`nbzvi'+`nbzvi`i''
+      if `maxvi'<`maxvi`i'' {
+         local maxvi=`maxvi`i''
+      }
+      if `zmaxvi'<`zmaxvi`i'' {
+         local zmaxvi=`zmaxvi`i''
+      }
+      *set trace on
+      local t=`loevHj'[1,`i']
+      local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i''
+      if `vi`i''!=0 {
+         di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata  traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}"
+      }
+      else {
+         di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i''  _col(93) %4.0f `crit`i'' _col(99) "{stata  traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}"
+      }
+      if "`details'"!=""&`i'!=`nbitems' {
+         di in green "{dup 97:-}"
+      }
+      local ac=`ac'+`ac`i''
+      local vi=`vi'+`vi`i''
+   }
+   di in green "{hline 97}"
+      di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi'
+   di in green "{hline 97}"
+}    */
+
+if "`ppp'"!=""|"pmm"!=""|"`nipmatrix'"!=""|"`generror'"!="" {
+    local list
+    local listi
+    local listm
+    local listv
+    forvalues i=1/`nbitems' {
+       forvalues l=1/`m`i'' {
+          tempname item`i'_`l'
+          qui gen `item`i'_`l''=``i''>=`l' if ``i''!=.
+          local list `list' ``i''_`l'
+          local listi `listi' ``i''
+          local listm `listm' `l'
+          local listv `listv' `item`i'_`l''
+       }
+    }
+    tempname matppp matpmm
+    matrix `matppp'=J(`=`scoremax'',`=`scoremax'+2',0)
+    matrix `matpmm'=J(`=`scoremax'',`=`scoremax'+2',0)
+    local row=1
+    forvalues i=1/`nbitems' {
+       forvalues k=1/`m`i'' {
+          local col=1
+          forvalues j=1/`nbitems' {
+             forvalues l=1/`m`j'' {
+                if `i'!=`j' {
+                   qui count if `item`i'_`k''!=.&`item`j'_`l''!=.
+                   local denom=r(N)
+                   qui count if `item`i'_`k''==1&`item`j'_`l''==1
+                   local pos=r(N)
+                   matrix `matppp'[`row',`col']=`=`pos'/`denom''
+                   qui count if `item`i'_`k''==0&`item`j'_`l''==0
+                   local pos=r(N)
+                   matrix `matpmm'[`row',`col']=`=`pos'/`denom''
+                }
+                else {
+                   matrix `matppp'[`row',`col']=-1
+                   matrix `matpmm'[`row',`col']=-1
+                }
+                local col=`col'+1
+             }
+          }
+          qui count if `item`i'_`k''!=.
+          local denom=r(N)
+          qui count if `item`i'_`k''==1
+          local pos=r(N)
+          matrix `matppp'[`row',`col']=`=`pos'/`denom''
+          qui count if `item`i'_`k''==0
+          local pos=r(N)
+          matrix `matpmm'[`row',`col']=`=`pos'/`denom''
+          matrix `matppp'[`row',`=`scoremax'+2']=`i'
+          matrix `matpmm'[`row',`=`scoremax'+2']=`i'
+          local row=`row'+1
+       }
+    }
+    matrix colnames `matppp'=`list' p1 item
+    matrix rownames `matppp'=`list'
+    matrix colnames `matpmm'=`list' p1 item
+    matrix rownames `matpmm'=`list'
+    if "`nipmatrix'"!="" {
+       if "`nipmatrix'"=="*" {
+          anaoption
+       }
+       else {
+          anaoption,`nipmatrix'
+       }
+       local minvi=`r(minvi)'
+       local siglevel=`r(siglevel)'
+       local minsize=`r(minsize)'
+       local details `r(details)'
+       if `minsize'==0 {
+          if `nbobs'>500 {
+             local minsize=round(`nbobs'/10)
+          }
+          else if `nbobs'>250 {
+             local minsize=round(`nbobs'/5)
+          }
+          else {
+             local minsize=max(50,round(`nbobs'/3))
+          }
+       }
+       forvalues i=1/`nbitems' {
+          local nbacpp`i'=0
+          local nbvipp`i'=0
+          local maxvipp`i'=0
+          local sumvipp`i'=0
+          local zmaxpp`i'=0
+          local nbsigzpp`i'=0
+          local nbacmm`i'=0
+          local nbvimm`i'=0
+          local maxvimm`i'=0
+          local sumvimm`i'=0
+          local zmaxmm`i'=0
+          local nbsigzmm`i'=0
+       }
+    }
+
+}
+tempfile temporaryfile
+qui save `temporaryfile'
+
+if "`ppp'"!=""|"`nipmatrix'"!=""|"`generror'"!="" {
+    drop *
+    qui svmat `matppp',names(col)
+    qui recode `list' (-1=.)
+    qui gen `id'=_n
+    qui gen str9 `item'=""
+    local connect "l"
+    local list2
+    local listw2
+    sort p1
+    qui set obs `=`scoremax'+1'
+    local listitem
+    forvalues i=1/`scoremax' {
+        local t=item[`i']
+        local listitem `listitem' `t'
+        local w:word `i' of `list'
+        qui replace `item'="`w'" if `id'==`i'
+        qui replace `w'=. if `id'==`i'
+        local connect "`connect' l"
+        local z=regexr("`w'","_",">=")
+        label define `monlabel' `i' "`z'", add
+        label variable `w' "`z'"
+        qui su p1 if `id'==`i'
+        local prop=r(mean)
+        qui replace `w'=`prop' in `=`scoremax'+1'
+    }
+    forvalues i=1/`scoremax' {
+        local v=`item'[`i']
+        local list2 `list2' `v'
+        local v=`id'[`i']
+        local listw2 `listw2' `v'
+    }
+    label define `monlabel' `=`scoremax'+1' "Prop",add
+    order `list2'
+    qui gen `id2'=_n
+    label value `id2' `monlabel'
+    label variable `id2' " "
+    if "`graph'"!="" {
+       twoway conn `list' `id2' in 1/`scoremax',connect(`connect') ytitle("") title("P++ diagnostics") name(ppp,replace)
+    }
+    format `list' %5.3f
+    label variable `id' "Item"
+    rename `id' Item
+    label value Item `monlabel'
+    qui replace Item=`=`scoremax'+1' in `=`scoremax'+1'
+    tempname matpp
+    matrix define `matpp'=J(`scoremax',`scoremax',0)
+    forvalues i=1/`scoremax' {
+       forvalues j=1/`scoremax' {
+          local ti:word `i' of `listv'
+          local tj:word `j' of `listv'
+          local t:word `j' of `list2'
+          matrix `matpp'[`i',`j']=`t'[`i']
+       }
+    }
+    matrix colnames `matpp'=`list2'
+    matrix rownames `matpp'=`list2'
+    if "`ppp'"!="" {
+       di
+       di in green _col(10) "P++ values per items pair (The values should be increasing in each column)"
+
+       matrix list `matpp',format(%5.3f)  nohalf   noheader
+    }
+    label drop `monlabel'
+    *set trace on
+    qui use "`temporaryfile'",clear
+    if "`nipmatrix'"!="" {
+       forvalues i=1/`scoremax' {
+          forvalues j=1/`scoremax' {
+             forvalues k=`=`j'+1'/`scoremax' {
+*di "`listv' `listw2'"
+                local ti:word `i' of `listitem'
+                local tj:word `j' of `listitem'
+                local tk:word `k' of `listitem'
+                if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ {
+                   local ++nbacpp`ti'
+                   *local ++nbacmm`tk'
+                   local diff=`matpp'[`j',`i']-`matpp'[`k',`i']
+                   if `diff'>`minvi'&`diff'!=. {
+                      local ++nbvipp`tj'
+                      local ++nbvipp`tk'
+                      local sumvipp`tj'=`sumvipp`tj''+`diff'
+                      local sumvipp`tk'=`sumvipp`tk''+`diff'
+                      if `diff'>`maxvipp`tj'' {
+                         local maxvipp`tj'=`diff'
+                      }
+                      if `diff'>`maxvipp`tk'' {
+                         local maxvipp`tk'=`diff'
+                      }
+                      local wi:word `i' of `listw2'
+                      local wj:word `j' of `listw2'
+                      local wk:word `k' of `listw2'
+                      local li:word `wi' of `listv'
+                      local lj:word `wj' of `listv'
+                      local lk:word `wk' of `listv'
+                      local ii:word `wi' of `list'
+                      local ij:word `wj' of `list'
+                      local ik:word `wk' of `list'
+
+                      qui count if `li'==1&`lj'==1&`lk'==0
+                      local a=r(N)
+                      qui count if `li'==1&`lj'==0&`lk'==1
+                      local b=r(N)
+                      local n=`a'+`b'
+                      local k=`b'
+                      local b=((2*`k'+1-`n')^2-10*`n')/(12*`n')
+                      local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b')
+                      *di "++ `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'"
+
+                      if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. {
+                         local ++nbsigzpp`tj'
+                         if abs(`z')>`zmaxpp`tj'' {
+                            local zmaxpp`tj'=abs(`z')
+                         }
+                         local ++nbsigzpp`tk'
+                         if abs(`z')>`zmaxpp`tk'' {
+                            local zmaxpp`tk'=abs(`z')
+                         }
+                      }
+                   }
+                }
+             }
+          }
+       }
+    }
+/*    if "`nipmatrix'"!="" {
+       forvalues i=1/`scoremax' {
+          forvalues j=1/`scoremax' {
+             forvalues k=`=`j'+1'/`scoremax' {
+                local ti:word `i' of `listitem'
+                local tj:word `j' of `listitem'
+                local tk:word `k' of `listitem'
+                if `tj'!= `tk'&`ti'!=`tk'&`ti'!=`tj' {
+                   local ++nbacpp`ti'
+                   local diff=`matpp'[`j',`i']-`matpp'[`k',`i']
+                   if `diff'>`minsize'&`diff'!=. {
+                      local ++nbvipp`tj'
+                      local ++nbvipp`tk'
+                      local sumvipp`tj'=`sumvipp`tj''+`diff'
+                      local sumvipp`tk'=`sumvipp`tk''+`diff'
+                      if `diff'>`maxvipp`tj'' {
+                         local maxvipp`tj'=`diff'
+                      }
+                      if `diff'>`maxvipp`tk'' {
+                         local maxvipp`tk'=`diff'
+                      }
+                   }
+                }
+             }
+          }
+       }
+    }
+*/
+}
+if "`pmm'"!=""|"`nipmatrix'"!="" {
+    drop _all
+    qui svmat `matpmm',names(col)
+    qui recode `list' (-1=.)
+    qui gen `id'=_n
+    qui gen str9 `item'=""
+    local connect "l"
+    local list2
+    local listw2
+    gsort -p1
+    qui set obs `=`scoremax'+1'
+    forvalues i=1/`scoremax' {
+        local w:word `i' of `list'
+        qui replace `item'="`w'" if `id'==`i'
+        qui replace `w'=. if `id'==`i'
+        local connect "`connect' l"
+        local z=regexr("`w'","_",">=")
+        label define `monlabel' `i' "`z'", add
+        label variable `w' "`z'"
+        qui su p1 if `id'==`i'
+        local prop=r(mean)
+        qui replace `w'=`prop' in `=`scoremax'+1'
+    }
+    forvalues i=1/`scoremax' {
+        local v=`item'[`i']
+        local list2 `list2' `v'
+        local v=`id'[`i']
+        local listw2 `listw2' `v'
+    }
+    label define `monlabel' `=`scoremax'+1' "Prop",add
+    order `list2'
+    qui gen `id2'=_n
+    label value `id2' `monlabel'
+    label variable `id2' " "
+    if "`graph'"!="" {
+       twoway conn `list' `id2' in 1/`scoremax',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace)
+    }
+    format `list' %5.3f
+    label variable `id' "Item"
+    rename `id' Item
+    label value Item `monlabel'
+    qui replace Item=`=`scoremax'+1' in `=`scoremax'+1'
+    tempname matmm
+    matrix define `matmm'=J(`scoremax',`scoremax',0)
+    forvalues i=1/`scoremax' {
+       forvalues j=1/`scoremax' {
+          local t:word `j' of `list2'
+          matrix `matmm'[`i',`j']=`t'[`i']
+       }
+    }
+    matrix colnames `matmm'=`list2'
+    matrix rownames `matmm'=`list2'
+    if "`pmm'"!="" {
+       di
+       di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)"
+       matrix list `matmm',format(%5.3f)  nohalf   noheader
+    }
+    label drop `monlabel'
+    qui use "`temporaryfile'",clear
+    if "`nipmatrix'"!="" {
+       forvalues i=1/`scoremax' {
+          forvalues j=1/`scoremax' {
+             forvalues k=`=`j'+1'/`scoremax' {
+*di "`listv' `listw2'"
+                local ti:word `i' of `listitem'
+                local tj:word `j' of `listitem'
+                local tk:word `k' of `listitem'
+                if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ {
+                   local ++nbacmm`ti'
+                   *local ++nbacmm`tk'
+                   local diff=`matmm'[`k',`i']-`matmm'[`j',`i']
+                   if `diff'>`minvi'&`diff'!=. {
+                      local ++nbvimm`tj'
+                      local ++nbvimm`tk'
+                      local sumvimm`tj'=`sumvimm`tj''+`diff'
+                      local sumvimm`tk'=`sumvimm`tk''+`diff'
+                      if `diff'>`maxvimm`tj'' {
+                         local maxvimm`tj'=`diff'
+                      }
+                      if `diff'>`maxvimm`tk'' {
+                         local maxvimm`tk'=`diff'
+                      }
+                      local wi:word `i' of `listw2'
+                      local wj:word `j' of `listw2'
+                      local wk:word `k' of `listw2'
+                      local li:word `wi' of `listv'
+                      local lj:word `wj' of `listv'
+                      local lk:word `wk' of `listv'
+                      local ii:word `wi' of `list'
+                      local ij:word `wj' of `list'
+                      local ik:word `wk' of `list'
+
+                      qui count if `li'==0&`lj'==1&`lk'==0
+                      local a=r(N)
+                      qui count if `li'==0&`lj'==0&`lk'==1
+                      local b=r(N)
+                      local n=`a'+`b'
+                      local k=`b'
+                      local b=((2*`k'+1-`n')^2-10*`n')/(12*`n')
+                      local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b')
+                      *di "-- `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'"
+
+                      if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. {
+                         local ++nbsigzmm`tj'
+                         if abs(`z')>`zmaxmm`tj'' {
+                            local zmaxmm`tj'=abs(`z')
+                         }
+                         local ++nbsigzmm`tk'
+                         if abs(`z')>`zmaxmm`tk'' {
+                            local zmaxmm`tk'=abs(`z')
+                         }
+                      }
+                   }
+                }
+             }
+          }
+       }
+    }
+}
+if "`nipmatrix'"!="" {
+   *set trace on
+   di
+   di in green _col(10) "Summary per item for check of non-Intersection via Pmatrix"
+   di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) /*in green "Minsize=" in ye %5.0f `minsize' _col(40)*/ in green "Alpha=" in ye %5.3f `siglevel'
+   di
+   di in green "Items"  _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax"  _col(84) "#zsig"  _col(93) "Crit"
+   di in green "{hline 97}"
+   forvalues i=1/`nbitems' {
+      local nbac`i'=`nbacpp`i''+`nbacmm`i''
+      local nbvi`i'=`nbvipp`i''+`nbvimm`i''
+      local maxvi`i'=max(`maxvipp`i'',`maxvimm`i'')
+      local sumvi`i'=`sumvipp`i''+`sumvimm`i''
+      local zmaxvi`i'=max(`zmaxpp`i'',`zmaxmm`i'')
+
+      local nbzsig`i'=`nbsigzpp`i''+`nbsigzmm`i''
+      local zmax`i'=0
+      *local nbsigz`i'=0
+      local t=`loevHj'[1,`i']
+*      di "local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmax`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i''     "
+      local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmaxvi`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i''
+
+      *di `nbac`i'' "   " `nbvi`i'' "   " `sumvi`i''
+      if `nbvi`i''!=0 {
+         di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(33) %6.4f `=`nbvi`i''/`nbac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`nbac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzsig`i'' _col(93) %4.0f `crit`i''
+      }
+      else {
+         di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i''  _col(93) %4.0f `crit`i''
+      }
+   }
+}
+
+/*if "`pmm'"!="" {
+    drop _all
+    matrix `P00g'=`P00',`P1''
+    matrix colnames `P00g'=`varlist' `p1'
+    matrix rownames `P00g'=`varlist'
+    qui svmat `P00g' , names(col)
+    qui gen `id'=_n
+    qui gen str9 `item'=""
+    local connect "l"
+    forvalues i=1/`nbitems' {
+        qui replace `item'="``i''" if `id'==`i'
+        qui replace ``i''=. if `id'==`i'
+        local connect "`connect' l"
+        label define `monlabel' `i' "``i''", add
+    }
+    sort `p1'
+    qui gen `id2'=_n
+    label value `id2' `monlabel'
+    label variable `id2' " "
+    if "`graph'"!="" {
+       twoway connected `varlist' `id2',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace)
+    }
+    format `varlist' %5.3f
+    label variable `id' "Item"
+    label value `id' `monlabel'
+    di
+    di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)"
+    list `id' `varlist' , table compress separator(`nbitems') noobs divider
+    label drop `monlabel'
+}
+
+
+
+if "`pairwise'"=="" {
+   restore, not
+}*/
+
+
+*di "listw2:`listw2'"
+*di "listv:`listv'"
+*di "list:`list'"
+*di "listi:`listi'"
+*di "listm:`listm'"
+*di "listitem:`listitem'"
+
+
+qui use "`loevHfile'",clear
+*set trace on
+if "`generror'"!="" {
+   if "`replace'"!="" {
+      capture drop `generror'_0
+      capture drop `generror'_H
+      capture drop `generror'_max
+      capture drop `generror'_GPN
+      capture drop `generror'
+   }
+   qui gen `generror'=0
+   *forvalues i=1/`nbitems' {
+   *   qui gen `generror'_``i''=0
+   *}
+   qui gen `generror'_0=`eGutt0'/`nb'
+   local nbsteps:word count `listitem'
+   if "`pairwise'"=="" {
+      forvalues i=1/`nbitems' {
+         qui replace `generror'=. if ``i''==.
+         qui replace `generror'_0=. if ``i''==.
+      }
+   }
+   forvalues i=0/`nbsteps' {
+       qui guttmax `listitem', score(`i')
+       local errmax`i'=r(maxegutt)
+   }
+*   matrix list `P0'
+   forvalues i=1/`nbsteps' {
+      forvalues j=`=`i'+1'/`nbsteps' {
+         local w2i:word `i' of `listw2'
+         local w2j:word `j' of `listw2'
+         local itemi:word `w2i' of `listi'
+         local modai:word `w2i' of `listm'
+         local itemj:word `w2j' of `listi'
+         local modaj:word `w2j' of `listm'
+         qui replace `generror'=`generror'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.
+         *qui replace `generror'_`itemi'=`generror'_`itemi'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.
+         *qui replace `generror'_`itemj'=`generror'_`itemj'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.
+*         qui replace `generror'=`generror'+.5 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.&`P1'[1,`i']==`P1'[1,`j']
+         *qui replace `generror'=`generror'+.5 if `P1'[1,`i']==`P1'[1,`j']&``i''==1&``j''==0
+      }
+   }
+*   set trace on
+   tempvar flag
+   qui gen `flag'=0
+   qui replace `flag'=1 `if'
+   qui replace `generror'=. if `flag'==0
+   qui replace `generror'_0=.  if `flag'==0
+   qui gen `generror'_H=1-`generror'/`generror'_0
+   tempvar score
+   qui genscore `varlist' `if',score(`score')
+   qui gen `generror'_max=.
+   forvalues i=1/`nbsteps' {
+      qui replace `generror'_max=`errmax`i'' if `score'==`i'
+   }
+   qui gen `generror'_GPN=`generror'/`generror'_max
+   label variable `generror' "Number of Guttman errors per individual"
+   label variable `generror'_H "H indice per individual"
+   if "`graph'"!="" {
+      qui histogram `generror',discrete freq name(errors,replace)
+      qui histogram `generror'_H,discrete freq name(H,replace)
+   }
+   qui su `generror'  ,det
+   local meane=r(mean)
+   local mede=r(p50)
+   local mine=r(min)
+   local maxe=r(max)
+   qui su `generror'_GPN  ,det
+   local meanGPN=r(mean)
+   local medGPN=r(p50)
+   local minGPN=r(min)
+   local maxGPN=r(max)
+   di
+   di in green "Number of Guttman errors by individual"        _col(50) in green "Normalized number of Guttamn errors by individual"
+   di in green "            Mean number: " in ye %7.2f `meane' _col(50) in green "            Mean number: " in ye %7.2f `meanGPN'
+   di in green "          Median number: " in ye %7.2f `mede'  _col(50) in green "          Median number: " in ye %7.2f `medGPN'
+   di in green "         Minimal number: " in ye %7.2f `mine'  _col(50) in green "         Minimal number: " in ye %7.2f `minGPN'
+   di in green "         Maximal number: " in ye %7.2f `maxe'  _col(50) in green "         Maximal number: " in ye %7.2f `maxGPN'
+   di in green "Expected Guttman errors: " in ye %7.2f `=`eGutt0'/`nb''
+   qui count if `generror'_H<0
+   di in green "           Rate of Hn<0: " in ye %7.2f `=r(N)/`nb'*100' "%"
+
+}
+
+matrix colnames `loevHj'=`varlist'
+matrix rownames `loevHj'=Hj
+return matrix loevHj `loevHj'
+
+matrix colnames `loevHjk'=`varlist'
+matrix rownames `loevHjk'=`varlist'
+return matrix loevHjk `loevHjk'
+
+matrix colnames `eGuttj'=`varlist'
+matrix rownames `eGuttj'=ej
+return matrix eGuttj `eGuttj'
+
+matrix colnames `eGuttjk'=`varlist'
+matrix rownames `eGuttjk'=`varlist'
+return matrix eGuttjk `eGuttjk'
+
+matrix colnames `eGuttj0'=`varlist'
+matrix rownames `eGuttj0'=ejk
+return matrix eGuttj0 `eGuttj0'
+
+matrix colnames `eGuttjk0'=`varlist'
+matrix rownames `eGuttjk0'=`varlist'
+return matrix eGuttjk0 `eGuttjk0'
+
+return scalar loevH=`loevH'
+return scalar eGutt =`eGutt'
+return scalar eGutt0 =`eGutt0'
+
+if `modamax'==1 {
+   matrix colnames `P11'=`varlist'
+   matrix rownames `P11'=`varlist'
+   return matrix P11 `P11'
+}
+
+matrix colnames `P00'=`varlist'
+matrix rownames `P00'=`varlist'
+return matrix P00 `P00'
+
+if "`ppp'"!=""|"`nipmatrix'"!="" {
+   return matrix ppp=`matpp'
+}
+if "`pmm'"!=""|"`nipmatrix'"!="" {
+   return matrix pmm=`matmm'
+}
+
+matrix colnames `zHj'=`varlist'
+matrix rownames `zHj'=zHj
+return matrix zHj `zHj'
+
+matrix colnames `pvalHj'=`varlist'
+matrix rownames `pvalHj'=pval
+return matrix pvalHj `pvalHj'
+
+return scalar zH=`zH'
+return scalar pvalH=`pvalH'
+if "`pair'"!="" {
+    matrix colnames `zHjk'=`varlist'
+    matrix rownames `zHjk'=`varlist'
+    return matrix zHjk `zHjk'
+
+    matrix colnames `pvalHjk'=`varlist'
+    matrix rownames `pvalHjk'=`varlist'
+    return matrix pvalHjk `pvalHjk'
+}
+
+matrix colnames `Obs'=`varlist'
+matrix rownames `Obs'=`varlist'
+return matrix Obs `Obs'
+
+capture restore, not
+
+end
diff --git a/Modules/ado/personal/l/loevH73.hlp b/Modules/ado/personal/l/loevH73.hlp
new file mode 100644
index 0000000..988d156
--- /dev/null
+++ b/Modules/ado/personal/l/loevH73.hlp
@@ -0,0 +1,103 @@
+{smcl}
+{* 6november2004}{...}
+{hline}
+help for {hi:loevH}{right:Jean-Benoit Hardouin}
+{hline}
+
+{title:Loevinger's H coefficients and non parametric Item Responses Models}
+
+{p 8 14 2}{cmd:loevH} {it:varlist} [{cmd:,} {cmdab:pairw:ise} {cmdab:pair} {cmdab:ppp} {cmdab:pmm} {cmdab:noadj:ust} {cmdab:gener:ror}({it:newvar}) {cmdab:rep:lace} {cmdab:gr:aph} {cmdab:mono:tonicity}({it:string}) {cmdab:nip:matrix}({it:string})]
+
+{p 8 14 2}{it:varlist} is a list of two or more existing dichotomous ou polytomous variables.
+
+{title:Description}
+
+{p 4 8 2}{cmd:loevH} allows verifying the fit of data to the Monotonely Homogeneous Mokken Model or to the Doubly Monotone Mokken Model.
+It computes the Loevinger H scalability coefficients, and several indexes in the field of the Non parametric Item Response Theory.
+
+{title:Options}
+
+{p 4 8 2}{cmd:pairwise}. By default, all the individuals with one or more missing values are omitted. {cmd:pairwise} allows to use the complete information by pair of items.
+
+{p 4 8 2}{cmd:pair} displays statistics and the value of the Loevinger H coefficient for each pair of items.
+
+{p 4 8 2}{cmd:ppp} displays the P++ matrix.
+
+{p 4 8 2}{cmd:pmm} displays the P-- matrix.
+
+{p 4 8 2}{cmd:noadjust} approximates the tests statistics like the MSP software (Molenaar et al. (2000)).
+
+{p 4 8 2}{cmd:generror} creates a new variable containing the number of Guttman errors produced by each individual.
+
+{p 4 8 2}{cmd:replace} allows replacing the variable defined by the {cmd:generror} option.
+
+{p 4 8 2}{cmd:graph} displays graphs (only with the {cmd:ppp}, {cmd:pmm} and {cmd:generror} options).
+
+{p 4 8 2}{cmd:monotonicity} displays indexes in order to check the monotonicity of the data (Monotone Homogeneity Mokken Model). This option produces outputs similar to the MSP software.
+The string contains several suboptions: {cmd:minvi}, {cmd:minsize}, {cmd:siglevel} and {cmd:details}. If you want use all the default values, type *.{p_end}
+{p 10 12 10}{cmd:minvi} defines the minimal size of a violation of monotonicity (0.03 by default){p_end}
+{p 10 12 10}{cmd:minsize} defines the minimum size of groups of patients to check the monotonicity (by default, the number of individuals divided by 10 with more than 500 individuals, the same number divided by 5 with more than 250 individuals, and the same number divided by 3 for a smaller number, with a minimum of 50){p_end}
+{p 10 12 10}{cmd:siglevel} defines the significance level for the tests (0.05 by default){p_end}
+{p 10 12 10}{cmd:details} displays more details with polytomous items
+
+{p 4 8 2}{cmd:nipmatrix} display indexes in order to check the non-intersection (Doubly Monotone Mokken Model). This option produces outputs similar to the MSP software. 
+The string contains several suboptions: {cmd:minvi} and {cmd:siglevel}. If you want use all the default values, type *.{p_end}
+{p 10 12 10}{cmd:minvi} defines the minimal size of a violation of non-intersection (0.03 by default){p_end}
+{p 10 12 10}{cmd:siglevel} defines the significance level for the tests (0.05 by default){p_end}
+
+
+{title:Remarks}
+
+{p 4 8 2}For detailed informations on the Loevinger's H coefficients, see Loevinger (1948) or Hemker and al. (1995). For details about the analysis of non parametric Mokken models, see for example the MSP 5.0 manual.
+
+
+{title:Example}
+
+	{p 8 8}{inp:. loevH itemA1-itemA7}
+
+	{p 8 8}{inp:. loevH itemA*, pair monotonicity(*) ppp pmm nipmatrix(minvi(0.05) siglevel(0.01))}
+
+	{p 8 8}{inp:. loevH item*, pairwise generror(error) graph}
+
+{title:Results}
+
+{p 4 8 2}The Loevinger's H coefficients between all the pairs of items, for each item with respect of all the others items and for the set of items are respectively saved in the matrices {it:r(loevHjk)}, {it:r(loevHj)}
+and in the scalar {it:r(loevH)}.
+
+{p 4 8 2}The empirical Guttman errors between all the pairs of items, associated to each item and relied to the scale are respectively saved in the matrices {it:r(eGuttjk)}, {it:r(eGuttj)} and in the scalar {it:e(Gutt)}.
+
+{p 4 8 2}The theorical Guttman errors between all the pairs of items, associated to each item and relied to the scale are respectively saved in the matrices {it:r(eGuttjk0)}, {it:r(eGuttj0)} and in the scalar {it:e(Gutt0)}.
+
+{p 4 8 2}The values of the Z statistics and the corresponding p-values associated to the Loevinger H coefficients are respectively saved in the matrices {it:r(zHjk)}, {it:r(pvalHjk)}, {it:r(zHj)}, {it:r(pvalHj)}
+and in the scalars {it:e(zH)} and {it:r(pvalH)}.
+
+{p 4 8 2}The P++ and P-- matrices are saved in {it:r(ppp)} and {it:r(pmm)}.
+
+{p 4 8 2}The used number of individuals per items pair is saved in {it:r(Obs)}.
+
+
+{title:References}
+
+{p 4 8 2}Hemker B. T., Sijtsma K. and Molenaar I. W., Selection of unidimensional scales from a multidimensional item bank in the polytomous Mokken IRT
+model, {it: Applied Psychological Measurement}, vol.19(4), 1995, pp. 337-352.
+
+{p 4 8 2}Loevinger J., The technique of homogeneous tests compared with some aspects of "scale analysis" and factor analysis. {it:Psychological bulletin},
+vol. 45, 1948, pp. 507-530.
+
+{p 4 8 2}Molenaar I. W., Sijtsma K. and Boer P. {it:MSP5 for Windows - User's Manual}, 2000, 105 pages.
+
+{title:Author}
+
+{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
+{p 4 8 2}EA 4275 "Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences"{p_end}
+{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end}
+{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end}
+{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end}
+{p 4 8 2}Email:
+{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end}
+{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol}
+and {browse "http://www.freeirt.org":FreeIRT}
+
+{title:Also see}
+
+{p 4 13 2}Online: help for {help traces}, {help msp}, {help gengroup}, {help mokken} if installed.{p_end}
diff --git a/Modules/ado/personal/l/loevHv1.hlp b/Modules/ado/personal/l/loevHv1.hlp
new file mode 100644
index 0000000..bab6a1a
--- /dev/null
+++ b/Modules/ado/personal/l/loevHv1.hlp
@@ -0,0 +1,71 @@
+{smcl}
+{* 31Aug2002}{...}
+{hline}
+help for {hi:loevH}
+{hline}
+
+{title:Loevinger's H coefficients}
+
+{p 8 14}{cmd:loevH} {it:varlist} [{cmd:,} {cmdab:h} {cmdab:hj} {cmdab:hjk}
+{cmdab:e} {cmdab:ej} {cmdab:ejk} {cmdab:e0} {cmdab:ej0} {cmdab:ejk0}]
+
+
+{p}{it:varlist} is a list of two existing dichotomous variables or more.
+
+{title:Options}
+
+{p 0 4}{cmd:h} display the Loevinger H coefficient for all the items of the scale.
+
+{p 0 4}{cmd:hj} display the Loevinger H coefficient for each item of the scale with respect of all the others items.
+
+{p 0 4}{cmd:hjk} display the Loevinger H coefficient for each pair of items of the scale.
+
+{p 0 4}{cmd:e} display the sum of the number of Guttman errors between all the pairs of items.
+
+{p 0 4}{cmd:ej} display the sum of the number of Guttman errors for each item of the scale.
+
+{p 0 4}{cmd:ejk} display the sum of the number of Guttman errors fror each pair of items of the scale.
+
+{p 0 4}{cmd:e0} display the sum of the number of expected Guttman errors between all the pairs of items.
+
+{p 0 4}{cmd:ej0} display the sum of the number of expected Guttman errors for each item of the scale.
+
+{p 0 4}{cmd:ejk0} display the sum of the number of expected Guttman errors fror each pair of items of the scale.
+
+
+{title:Description}
+
+{p}{cmd:loevH} calculate the Loevinger's H coefficient between all the pairs of items of {it:varlist}, and compute the Loevinger's Hj coefficient for each item of {it:varlist} with respect of all the others items and the Loevinger's H coefficient for the set of items of {it:varlist}.
+
+
+{title:Remarks} 
+
+For detailed information on the Loevinger's H coefficients, see Loevinger (1948) or Hemker and al. (1995).
+
+{cmd:loevH} display none result by default. {cmd:loevH} don't permit the use of polytomous items. 
+
+
+{title:Example}
+
+	{inp:. loevH item1 item2 item3 item4}
+
+{title:Results}
+
+The Loevinger's H coefficients between all the pais of items are saved in the matrix r(loevHjk).
+
+The Loevinger's H coefficients for each item with respect of all the others items are saved in the matrix r(loevHj).
+
+The Loevinger's H coefficient for the set of items is saved in the scalar r(loevH).
+
+{title:References}
+
+Hemker B. T., Sijtsma K. and Molenaar I. W., Selection of unidimensional scales from a multidimensional item bank in the polytomous Mokken IRT 
+model, {it: Applied Psychological Measurement}, vol.19(4), 1995, pp. 337-352. 
+
+Loevinger J., The technique of homogeneous tests compared with some aspects of "scale analysis" and factor analysis. {it:Psychological bulletin},
+vol. 45, 1948, pp. 507-530.
+
+{title:Author}
+
+{p 4 8 2}Jean-Benoit Hardouin, Regional Health Observatory (ORS) - 1, rue Porte Madeleine - BP 2439 - 45032 Orleans Cedex 1 - France.
+You can contact the author at {browse "mailto:jean-benoit.hardouin@neuf.fr":jean-benoit.hardouin@neuf.fr} and visit the websites {browse "http://anaqol.free.fr":AnaQol} and {browse "http://freeirt.free.fr":FreeIRT}
diff --git a/Modules/ado/personal/l/loevh - Copie au 17 juin 2017.ado b/Modules/ado/personal/l/loevh - Copie au 17 juin 2017.ado
new file mode 100644
index 0000000..40e741d
--- /dev/null
+++ b/Modules/ado/personal/l/loevh - Copie au 17 juin 2017.ado	
@@ -0,0 +1,1393 @@
+*! Version 8.1.5 23 March 2015
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Stata program : loevh
+* Loevinger H indexes, Mokken Analysis
+* Release 8.1.3 : March 23, 2015  /*minor correction for displaying results*/
+*
+*
+* Historic :
+* Version 1 (August 20, 2002) [Jean-Benoit Hardouin]
+* Version 2 (June 22, 2003) [Jean-Benoit Hardouin]
+* Version 3 (December 1, 2003) [Jean-Benoit Hardouin]
+* Version 4 (January 20, 2004) [Jean-Benoit Hardouin]
+* Version 5 (March 22, 2004) [Jean-Benoit Hardouin]
+* Version 6 (July 3, 2004) [Jean-Benoit Hardouin]
+* Version 6.1 (September 19, 2005) [Jean-Benoit Hardouin]
+* Version 6.2 (January 31, 2006) [Jean-Benoit Hardouin]
+* Release 6.3 (March 20, 2006) [Jean-Benoit Hardouin]  /*A bug with temporary files */
+* Release 6.4 (January 19, 2007) [Jean-Benoit Hardouin]  /*Tests to compare Loevinger coefficients to 0 identical to the MSP software (dichotomous and polytomous case)*/
+* Release 6.5 (January 22, 2007) [Jean-Benoit Hardouin]  /*Correction of a bug concerning the p-values with the pair option*/
+* Release 6.6 (Februar 16, 2007) [Jean-Benoit Hardouin]  /*Correction of a bug with the displaying of Easyness with polytomous items, option graph, option generror, improvements*/
+* Release 7: June 21, 2007  /*Check of  monotonicity and Non intersection via P matrices*/
+* Release 7.1: November 6, 2008  /*Correction for the z-tests for the check of non intersection via P matrices*/
+* Release 7.2: November 19, 2008  /*Implementation of the GPN indexes*/
+* Release 7.3: August 15, 2009  /*Print the difficulties of the items instead of P(X=0)*/
+* Release 8: December 8, 2010  /*loevH is renamed loevh*/
+* Release 8.1: October 19, 2012  /*html option*/
+* Release 8.1.1 : November 20, 2012  /*graphs with the html option*/
+* Release 8.1.2 : December 7, 2012  /*minor correction*/
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences  (UPRES EA 4275 SPHERE)
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* Requiered Stata modules:
+* -anaoption- (version 1)
+* -traces- (version 3.2)
+* -gengroup- (version 1)
+* -guttmax- (version 1)
+*
+* News about this program :http://www.anaqol.org
+*
+* Copyright 2002-2015 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+***********************************************************************************************************
+
+program define loevh , rclass
+version 8.2
+syntax varlist(min=2 numeric) [if] [,PAIRWise PAIR ppp pmm noADJust GENERror(string) REPlace GRaph MONOtonicity(string) NIRESTscore(string) NIPmatrix(string) HTML(string)]
+preserve
+
+if "`html'" != "" {
+   set scheme sj
+   local htmlregion  "graphregion(fcolor(white) ifcolor(white))"
+   di in gr ""
+}
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+tempname corr cov P1 P0 diff P11 P00 H1jk vHjk zHjk chi2Hjk dfHjk pvalHjk H1j vHj zHj pvalHj H1 vH zH pvalH Obs eGuttjk eGuttjk0 loevHjk eGuttj eGuttj0 loevHj eGutt eGutt0 loevH e1 e2
+tempfile loevHfile
+qui save "`loevHfile'"
+
+if "`if'"!="" {
+   qui keep `if'
+}
+
+if "`adjust'"!="" {
+   local adj=0
+}
+else {
+   local adj=1
+}
+
+qui count
+local nbobs=r(N)
+
+forvalues j=1/`nbitems' {
+   if "`pairwise'"=="" {
+       qui drop if ``j''==.
+   }
+}
+qui count
+local nbtotindnm=r(N)
+
+matrix define `eGuttjk'=J(`nbitems',`nbitems',0)
+matrix define `eGuttjk0'=J(`nbitems',`nbitems',0)
+matrix define `loevHjk'=J(`nbitems',`nbitems',0)
+matrix define `eGuttj'=J(1,`nbitems',0)
+matrix define `eGuttj0'=J(1,`nbitems',0)
+matrix define `loevHj'=J(1,`nbitems',0)
+scalar define `eGutt'=0
+scalar define `eGutt0'=0
+scalar define `loevH'=0
+matrix define `Obs'=J(`nbitems',`nbitems',0)
+matrix define `P00'=J(`nbitems',`nbitems',0)
+
+tempname modamax
+scalar `modamax'=0
+local scoremax=0
+forvalues j=1/`nbitems' {
+     qui su ``j''
+     local m`j'=r(max)
+     local scoremax=`scoremax'+`m`j''
+     if r(max)>`modamax' {
+        scalar `modamax'=r(max)
+     }
+     local nbHjkNS`j'=0
+}
+
+/*if "`generror'"!=""&`modamax'!=1 {
+   di in ye "It is not possible to define the {cmd:generror} option with polytomous items"
+   local generror
+} */
+*di "scoremax `scoremax'"
+if "`graph'"!=""&`scoremax'>19 {
+   di in ye "The {cmd:graph} option is disabled because of a large number of possible scores (>20)"
+   local graph
+}
+
+matrix define `cov'=J(`nbitems',`nbitems',0)
+matrix define `corr'=J(`nbitems',`nbitems',0)
+matrix define `P11'=J(`nbitems',`nbitems',0)
+matrix define `H1jk'=J(`nbitems',`nbitems',0)
+matrix define `vHjk'=J(`nbitems',`nbitems',0)
+matrix define `zHjk'=J(`nbitems',`nbitems',0)
+matrix define `pvalHjk'=J(`nbitems',`nbitems',0)
+matrix define `P1'=J(1,`nbitems',0)
+matrix define `P0'=J(1,`nbitems',0)
+matrix define `diff'=J(1,`nbitems',0)
+matrix define `H1j'=J(1,`nbitems',0)
+matrix define `vHj'=J(1,`nbitems',0)
+matrix define `zHj'=J(1,`nbitems',0)
+matrix define `pvalHj'=J(1,`nbitems',0)
+
+forvalues j=1/`nbitems' {
+    qui su ``j''
+    matrix `cov'[`j',`j']=r(Var)
+    matrix `corr'[`j',`j']=1
+    local tmp=`j'+1
+    qui count if ``j''!=.
+    matrix `Obs'[`j',`j']=r(N)
+    forvalues k=`tmp'/`nbitems' {
+        qui count if ``j''!=.&``k''!=.
+        matrix `Obs'[`j',`k']=r(N)
+        matrix `Obs'[`k',`j']=r(N)
+        qui corr ``j'' ``k'',cov
+        matrix `cov'[`j',`k']=r(cov_12)
+        matrix `cov'[`k',`j']=r(cov_12)
+        qui corr ``j'' ``k''
+        matrix `corr'[`j',`k']=r(rho)
+        matrix `corr'[`k',`j']=r(rho)
+        matrix `zHjk'[`j',`k']=`corr'[`j',`k']*(`Obs'[`j',`k']-`adj')^.5
+        matrix `zHjk'[`k',`j']=`H1jk'[`j',`k']
+        matrix `pvalHjk'[`j',`k']=1-norm(`zHjk'[`j',`k'])
+        matrix `pvalHjk'[`k',`j']=`pvalHjk'[`j',`k']
+        if `pvalHjk'[`j',`k']>0.05 {
+           local nbHjkNS`j'=`nbHjkNS`j''+1
+           local nbHjkNS`k'=`nbHjkNS`k''+1
+        }
+        forvalues mod1=1/`m`j'' {
+            forvalues mod2=1/`m`k'' {
+                qui count if ``j''<`mod1'&``k''>=`mod2'&``j''!=.&``k''!=.
+                scalar `e1'=r(N)
+                qui count if ``j''>=`mod1'&``k''<`mod2'&``j''!=.&``k''!=.
+                scalar `e2'=r(N)
+                matrix `eGuttjk'[`j',`k']=`eGuttjk'[`j',`k']+min(`e1',`e2')
+                qui count if ``j''<`mod1'&``j''!=.&``k''!=.
+                local t1=r(N)
+                qui count if ``k''<`mod2'&``j''!=.&``k''!=.
+                local t2=r(N)
+                qui count if ``j''>=`mod1'&``j''!=.&``k''!=.
+                local t3=r(N)
+                qui count if ``k''>=`mod2'&``j''!=.&``k''!=.
+                local t4=r(N)
+                if min(`e1',`e2')==`e1' {
+                    matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t1'*`t4'/`Obs'[`j',`k']
+                }
+                else {
+                    matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t2'*`t3'/`Obs'[`j',`k']
+                }
+
+            }
+        }
+        qui count if ``j''==0&``k''==0
+        matrix `P00'[`j',`k']=r(N)/`Obs'[`j',`k']
+        matrix `P00'[`k',`j']=r(N)/`Obs'[`k',`j']
+        if `modamax'==1 {
+           qui count if ``j''==1&``k''==1
+           matrix `P11'[`j',`k']=r(N)/`Obs'[`j',`k']
+           matrix `P11'[`k',`j']=r(N)/`Obs'[`k',`j']
+        }
+
+        matrix `eGuttjk'[`k',`j']=`eGuttjk'[`j',`k']
+        matrix `eGuttj'[1,`j']=`eGuttj'[1,`j']+`eGuttjk'[`j',`k']
+        matrix `eGuttj'[1,`k']=`eGuttj'[1,`k']+`eGuttjk'[`j',`k']
+        matrix `eGuttjk0'[`k',`j']=`eGuttjk0'[`j',`k']
+        matrix `eGuttj0'[1,`j']=`eGuttj0'[1,`j']+`eGuttjk0'[`j',`k']
+        matrix `eGuttj0'[1,`k']=`eGuttj0'[1,`k']+`eGuttjk0'[`j',`k']
+
+        matrix `loevHjk'[`j',`k']=1-`eGuttjk'[`j',`k']/`eGuttjk0'[`j',`k']
+        matrix `loevHjk'[`k',`j']=`loevHjk'[`j',`k']
+
+    }
+    qui count if ``j''!=.
+    local tmp=r(N)
+    qui count if ``j''==1
+    matrix `P1'[1,`j']=r(N)/`tmp'
+    qui count if ``j''==0
+    matrix `P0'[1,`j']=r(N)/`tmp'
+    qui su ``j''
+    matrix `diff'[1,`j']=r(mean)
+    matrix `loevHj'[1,`j']=1-`eGuttj'[1,`j']/`eGuttj0'[1,`j']
+    scalar `eGutt'=`eGutt'+`eGuttj'[1,`j']/2
+    scalar `eGutt0'=`eGutt0'+`eGuttj0'[1,`j']/2
+}
+scalar `H1'=0
+scalar `vH'=0
+scalar `zH'=0
+forvalues j=1/`nbitems'{
+   forvalues k=1/`nbitems' {
+      if `j'!=`k' {
+         matrix `zHj'[1,`j']=`zHj'[1,`j']+`cov'[`j',`k']
+         matrix `vHj'[1,`j']=`vHj'[1,`j']+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj')
+      }
+      if `j'<`k' {
+         scalar `zH'=`zH'+`cov'[`j',`k']
+         scalar `vH'=`vH'+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj')
+      }
+   }
+   matrix `zHj'[1,`j']=`zHj'[1,`j']/sqrt(`vHj'[1,`j'])
+   matrix `pvalHj'[1,`j']=1-norm(`zHj'[1,`j'])
+}
+scalar `zH'=`zH'/sqrt(`vH')
+scalar `pvalH'=1-norm(`zH')
+scalar `loevH'=1-`eGutt'/`eGutt0'
+local loevH=1-`eGutt'/`eGutt0'
+
+if `modamax'==1 {
+   local text="Easyness"
+   local value=1
+   local col=23
+}
+else {
+   local text="Difficulty"
+   local value=0
+   local col=21
+}
+
+if "`html'" == "" {
+	di in green  _col(35) "Observed" _col(47) "Expected" _col(93) "Number"
+	di in green _col(27) "Mean" _col(36) "Guttman" _col(48) "Guttman" _col(59) "Loevinger" _col(83) "H0: Hj<=0" _col(94) "of NS"
+	di in green "Item"  _col(15) "Obs" _col(26) "Score" _col(37) "errors" _col(49) "errors" _col(61) "H coeff" _col(73) "z-stat." _col(85) "p-value" _col(96) "Hjk"
+	di in green "{hline 99}"
+	forvalues j=1/`nbitems' {
+     		di in green "``j''" in yellow _col(15) `Obs'[`j',`j'] _col(25) %6.4f `diff'[1,`j'] _col(36) %7.0f `eGuttj'[1,`j'] _col(45) %10.2f `eGuttj0'[1,`j'] _col(61) %7.5f `loevHj'[1,`j'] _col(72) %8.4f `zHj'[1,`j'] _col(85) %7.5f `pvalHj'[1,`j'] _col(97) %2.0f `nbHjkNS`j''
+	}
+	di in green "{hline 99}"
+}
+else {
+	di in gr ""
+	di in gr ""
+	di in gr  ""
+	di in gr ""
+	di in gr ""
+	forvalues j=1/`nbitems' {
+     		di in green ""
+	}
+}
+
+if "`pairwise'"=="" {
+   local nb=`nbtotindnm'
+}
+else {
+   local nb=`nbobs'
+}
+if "`html'" == "" {
+	di in green "Scale" in yellow _col(15) `nb' _col(36) %7.0f `eGutt' _col(45) %10.2f `eGutt0' _col(61) %-8.5f `loevH' _col(71) %9.4f `zH' _col(85) %7.5f `pvalH'
+}
+else {
+	di in green ""
+	di in gr "
ItemObsMean
Score
Observed
Guttman
Errors
Expected
Guttman
Errors
Loevinger
H coeff
z-stat.H0: Hj ≤ 0
p-value
Number of
NS Hjk
``j''" `Obs'[`j',`j'] "" %6.4f `diff'[1,`j'] "" %5.0f `eGuttj'[1,`j'] "" %8.2f `eGuttj0'[1,`j'] "" %7.5f `loevHj'[1,`j'] "" %8.4f `zHj'[1,`j'] "" %7.5f `pvalHj'[1,`j'] "" %2.0f `nbHjkNS`j'' "
Scale" `nb' "" %5.0f `eGutt' "" %8.2f `eGutt0' "" %-8.5f `loevH' "" %9.4f `zH' "" %7.5f `pvalH' "
" +} + +if "`pair'"!="" { + if "`html'" == "" { + di + di in green _col(45) "Observed" _col(57) "Expected" + di in green _col(`=`col'+10') "`text'" _col(46) "Guttman" _col(58) "Guttman" _col(69) "Loevinger" _col(92) "H0: Hjk<=0" + di in green "Items" _col(25) "Obs" _col(29) "P(Xj=`value',Xk=`value')" _col(47) "errors" _col(59) "errors" _col(71) "H coeff" _col(83) "z-stat." _col(95) "p-value" + di in green "{hline 101}" + forvalues j=1/`nbitems' { + forvalues k=`=`j'+1'/`nbitems' { + qui count if ``j''!=. + local obs=r(N) + di in green "``j''" _col(10) "``k''" in yellow _col(25) `Obs'[`j',`k'] _col(35) %6.4f `P`value'`value''[`j',`k'] _col(48) %5.0f `eGuttjk'[`j',`k'] _col(57) %8.2f `eGuttjk0'[`j',`k'] _col(70) %8.5f `loevHjk'[`j',`k'] _col(81) %9.4f `zHjk'[`j',`k'] _col(95) %7.5f `pvalHjk'[`j',`k'] + } + } + di in green "{hline 101}" + } + else { + di in gr "" + di in gr "" + di in green "" + di in gr "" + forvalues j=1/`nbitems' { + forvalues k=`=`j'+1'/`nbitems' { + qui count if ``j''!=. + local obs=r(N) + di in green "" + } + } + di in green "
Summary of results by items pairs
Items" "`text'" "
Obs P(Xj=`value',Xk=`value')
Observed
Guttman
Errors
Expected
Guttman
Errors
Loevinger
H coeff
z-stat.H0: Hjk ≤ 0
p-value
" "``j''" "" "``k''" "" `Obs'[`j',`k'] "" %6.4f `P`value'`value''[`j',`k'] "" %5.0f `eGuttjk'[`j',`k'] "" %8.2f `eGuttjk0'[`j',`k'] "" %8.5f `loevHjk'[`j',`k'] "" %9.4f `zHjk'[`j',`k'] "" %7.5f `pvalHjk'[`j',`k'] "
" + } +} + +/*if `modamax'>1&"`ppp'"!="" { + di in green "It is not possible to obtain the P++ diagnostics with polytomous items" + local ppp +} +if `modamax'>1&"`pmm'"!="" { + di in green "It is not possible to obtain the P-- diagnostics with polytomous items" + local pmm +} */ + +tempname P11g P00g item id id2 p1 monlabel + +/*if "`monotonicity'"!=""&`modamax'>1 { + if "`html'" == "" { + di in green "It is not possible to obtain the latent monotonicity diagnostics with polytomous items" + } + else { + di in green "

It is not possible to obtain the latent monotonicity diagnostics with polytomous items

" + } + local monotonicity +} */ + +if "`monotonicity'"!="" { +*set trace on + if "`monotonicity'"=="*" { + anaoption + } + else { + anaoption,`monotonicity' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + +*set trace on + tempname score + qui genscore `varlist',score(`score') + if "`html'" == "" { + di + di in green _col(10) "Summary per item for check of monotonicity" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + } + else { + di in gr "" + di in gr "" + di in gr "" + } +*set trace on + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + tempname restscore`i' + qui gen `restscore`i''=`score'-``i'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroup`i' + qui gengroup `restscore`i'',newvariable(`restgroup`i'') minsize(`minsize') + local list`i'=r(list) + qui su `restgroup`i'' + local nbgroups`i'=r(max) + forvalues j=0/`nbgroups`i'' { + qui count if `restgroup`i''==`j' + local rgroup`j'=r(N) + } + local vi`i'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + } + forvalues l=1/`m`i'' { + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + local nbzvi`i'_`l'=0 + forvalues j=1/`nbgroups`i'' { + qui count if `restgroup`i''==`j'&``i''>=`l' + local nbitem`i'rgroup`j'_`l'=r(N) + forvalues k=1/`=`j'-1' { + local diff=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + if `nbitem`i'rgroup`j'_`l''!=`rgroup`j''&`nbitem`i'rgroup`k'_`l''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + } + local p=(`nbitem`i'rgroup`k'_`l''+`nbitem`i'rgroup`j'_`l'')/(`rgroup`j''+`rgroup`k'') + *local z=`diff'/sqrt(`p'*(1-`p')*(1/`rgroup`j''+1/`rgroup`k'')) + *di "local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) " + local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) + *di "=`z'" + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + } + if `j'==`nbgroups`i'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + if "`html'" == "" { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in gr "" + } + } + else { + if "`html'" == "" { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + else { + di in gr "" + } + } + } + if "`html'" == "" { + di in green "{dup 97:-}" + } + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + *set trace on + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + if `vi`i''!=0 { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in green "" + } + } + else { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in gr "" + } + + } + if "`details'"!=""&`i'!=`nbitems' { + if "`html'" == "" { + di in green "{dup 97:-}" + } + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + if "`html'" == "" { + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" + } + else { + di in green "
Summary per item for check of monotonicity
Items#ac#vi#vi / #acmaxvisumsum / #aczmax#zsigCrit
``i''>=`l'" %8.0f `ac`i'_m`l'' "" %8.0f `vi`i'_m`l'' "" %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' "" %6.4f `maxvi`i'_m`l'' "" %6.4f `sumvi`i'_m`l'' "" %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' "" %6.4f `zmaxvi`i'_m`l'' "" %8.0f `nbzvi`i'_m`l'' "
``i''>=`l'" %8.0f `ac`i'_m`l'' "" %8.0f `vi`i'_m`l'' "
``i''" %8.0f `ac`i'' "" %8.0f `vi`i'' "" %6.4f `=`vi`i''/`ac`i''' "" %6.4f `maxvi`i'' "" %6.4f `sumvi`i'' "" %6.4f `=`sumvi`i''/`ac`i''' "" %6.4f `zmaxvi`i'' "" %8.0f `nbzvi`i'' "" %4.0f `crit`i'' "
``i''" %8.0f `ac`i'' "" %8.0f `vi`i'' "" %4.0f `crit`i'' "
Total" `ac' "" %8.0f `vi' "" %6.4f `=`vi'/`ac'' "" %6.4f `maxvi' "" %6.4f `sumvi' "" %6.4f `=`sumvi'/`ac'' "" %6.4f `zmaxvi' "" %8.0f `nbzvi' "
" + } +} +/*if "`nirestscore'"!="" { +*set trace on + if "`nirestscore'"=="*" { + anaoption + } + else { + anaoption,`nirestscore' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + +*set trace on + tempname score + qui genscore `varlist',score(`score') + di + di in green _col(10) "Summary per item for check of Non-Intersection via Rest-score" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" +*set trace on + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + local vi`i'`j'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + } + forvalues j=1/`nbitems' { + if `j'!=`i' { + tempname restscorei`i'j`j' + qui gen `restscorei`i'j`j''=`score'-``i''-``j'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroupi`i'j`j' + qui gengroup `restscorei`i'j`j'',newvariable(`restgroupi`i'j`j'') minsize(`minsize') + local listi`i'j`j'=r(list) + qui su `restgroupi`i'j`j'' + local nbgroupsi`i'j`j'=r(max) + forvalues k=0/`nbgroupsi`i'j`j'' { + qui count if `restgroupi`i'j`j''==`k' + local rgroup`k'=r(N) + } + forvalues l=1/`m`i'' { + forvalues k=1/`m`j'' { + forvalues m=1/`nbgroupsi`i'j`j'' { + qui count if `restgroupi`i'j`j''==`m'&``i''>=`l'&``j''>=`k' + local nbitemi`i'j`j'rgroup`m'_`l'_`k'=r(N) + forvalues n=1/`=`m'-1' { + local diff=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m'' + if `nbitemi`i'j`j'rgroup`m'_`l'_`k''!=`rgroup`m''&`nbitemi`i'j`j'rgroup`m'_`l'_`k''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m'' + } + local p=(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+`nbitemi`i'j`j'rgroup`m'_`l'_`k'')/(`rgroup`m''+`rgroup`n'') + local z=abs(2*(sqrt(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)*sqrt(`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)-sqrt((`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k'')*`nbitemi`i'j`j'rgroup`m'_`l'_`k''))/sqrt(`rgroup`m''+`rgroup`n''-1)) + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + if `m'==`nbgroupsi`i'j`j'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + *local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + *local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + } + } + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + } + di in green "{dup 97:-}" + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + *set trace on + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + if `vi`i''!=0 { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + if "`details'"!=""&`i'!=`nbitems' { + di in green "{dup 97:-}" + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" +} */ + +if "`ppp'"!=""|"pmm"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + local list + local listi + local listm + local listv + forvalues i=1/`nbitems' { + forvalues l=1/`m`i'' { + tempname item`i'_`l' + qui gen `item`i'_`l''=``i''>=`l' if ``i''!=. + local list `list' ``i''_`l' + local listi `listi' ``i'' + local listm `listm' `l' + local listv `listv' `item`i'_`l'' + } + } + tempname matppp matpmm + matrix `matppp'=J(`=`scoremax'',`=`scoremax'+2',0) + matrix `matpmm'=J(`=`scoremax'',`=`scoremax'+2',0) + local row=1 + forvalues i=1/`nbitems' { + forvalues k=1/`m`i'' { + local col=1 + forvalues j=1/`nbitems' { + forvalues l=1/`m`j'' { + if `i'!=`j' { + qui count if `item`i'_`k''!=.&`item`j'_`l''!=. + local denom=r(N) + qui count if `item`i'_`k''==1&`item`j'_`l''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0&`item`j'_`l''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + } + else { + matrix `matppp'[`row',`col']=-1 + matrix `matpmm'[`row',`col']=-1 + } + local col=`col'+1 + } + } + qui count if `item`i'_`k''!=. + local denom=r(N) + qui count if `item`i'_`k''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + matrix `matppp'[`row',`=`scoremax'+2']=`i' + matrix `matpmm'[`row',`=`scoremax'+2']=`i' + local row=`row'+1 + } + } + matrix colnames `matppp'=`list' p1 item + matrix rownames `matppp'=`list' + matrix colnames `matpmm'=`list' p1 item + matrix rownames `matpmm'=`list' + if "`nipmatrix'"!="" { + if "`nipmatrix'"=="*" { + anaoption + } + else { + anaoption,`nipmatrix' + } + local minvi=`r(minvi)' + local siglevel=`r(siglevel)' + local minsize=`r(minsize)' + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + forvalues i=1/`nbitems' { + local nbacpp`i'=0 + local nbvipp`i'=0 + local maxvipp`i'=0 + local sumvipp`i'=0 + local zmaxpp`i'=0 + local nbsigzpp`i'=0 + local nbacmm`i'=0 + local nbvimm`i'=0 + local maxvimm`i'=0 + local sumvimm`i'=0 + local zmaxmm`i'=0 + local nbsigzmm`i'=0 + } + } + +} +tempfile temporaryfile +qui save `temporaryfile' + +if "`ppp'"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + drop * + qui svmat `matppp',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + sort p1 + qui set obs `=`scoremax'+1' + local listitem + forvalues i=1/`scoremax' { + local t=item[`i'] + local listitem `listitem' `t' + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + + if "`graph'"!="" { + if "`html'"!="" { + qui local saving "saving(`c(tmpdir)'/`html'_ppp,replace) nodraw" + } + qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P++ diagnostics") name(ppp,replace) `saving' xsize(2) ysize(2) + if "`html'"!="" { + qui graph use `c(tmpdir)'/`html'_ppp.gph + qui graph export `c(tmpdir)'/`html'_ppp.eps, replace + } + } + + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matpp + matrix define `matpp'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local ti:word `i' of `listv' + local tj:word `j' of `listv' + local t:word `j' of `list2' + matrix `matpp'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matpp'=`list2' + matrix rownames `matpp'=`list2' + + if "`ppp'"!="" { + if "`html'" == "" { + di + di in green _col(10) "P++ values per items pair (The values should be increasing in each column)" + matrix list `matpp',format(%5.3f) nohalf noheader + } + else { + di "" + di "" + di "" + matrixlisthtml `matpp' "%5.3f" + di "
P++ values per items pair
(The values should be increasing in each column)
" + if ("`graph'" != "") { + di "" + } + } + } + + label drop `monlabel' + *set trace on + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { +*di "`listv' `listw2'" + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacpp`ti' + *local ++nbacmm`tk' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==1&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==1&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "++ `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzpp`tj' + if abs(`z')>`zmaxpp`tj'' { + local zmaxpp`tj'=abs(`z') + } + local ++nbsigzpp`tk' + if abs(`z')>`zmaxpp`tk'' { + local zmaxpp`tk'=abs(`z') + } + } + } + } + } + } + } + } +/* if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!= `tk'&`ti'!=`tk'&`ti'!=`tj' { + local ++nbacpp`ti' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minsize'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + } + } + } + } + } + } +*/ +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + drop _all + qui svmat `matpmm',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + gsort -p1 + qui set obs `=`scoremax'+1' + forvalues i=1/`scoremax' { + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + if "`html'"!="" { + qui local saving "saving(`c(tmpdir)'/`html'_pmm,replace) nodraw" + *qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) `saving' + *graph use `c(tmpdir)'/`html'_pmm.gph + *qui graph export `c(tmpdir)'/`html'_pmm.eps, replace + } + *else { + qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) `saving' + *} + if "`html'"!="" { + qui graph use `c(tmpdir)'/`html'_pmm.gph + qui graph export `c(tmpdir)'/`html'_pmm.eps, replace + } + } + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matmm + matrix define `matmm'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local t:word `j' of `list2' + matrix `matmm'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matmm'=`list2' + matrix rownames `matmm'=`list2' + if "`pmm'"!="" { + if "`html'" == "" { + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + matrix list `matmm',format(%5.3f) nohalf noheader + } + else { + di "" + di "" + di "" + matrixlisthtml `matmm' "%5.3f" + di "
P-- values per items pair
(The values should be decreasing in each column)
" + if ("`graph'" != "") { + di "" + } + } + } + label drop `monlabel' + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { +*di "`listv' `listw2'" + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacmm`ti' + *local ++nbacmm`tk' + local diff=`matmm'[`k',`i']-`matmm'[`j',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvimm`tj' + local ++nbvimm`tk' + local sumvimm`tj'=`sumvimm`tj''+`diff' + local sumvimm`tk'=`sumvimm`tk''+`diff' + if `diff'>`maxvimm`tj'' { + local maxvimm`tj'=`diff' + } + if `diff'>`maxvimm`tk'' { + local maxvimm`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==0&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==0&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "-- `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzmm`tj' + if abs(`z')>`zmaxmm`tj'' { + local zmaxmm`tj'=abs(`z') + } + local ++nbsigzmm`tk' + if abs(`z')>`zmaxmm`tk'' { + local zmaxmm`tk'=abs(`z') + } + } + } + } + } + } + } + } +} + +if "`nipmatrix'" !="" { + *set trace on + if "`html'" == "" { + di + di in green _col(10) "Summary per item for check of non-Intersection via Pmatrix" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) /*in green "Minsize=" in ye %5.0f `minsize' _col(40)*/ in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + } + else { + di in gr "" + di in gr "" + di in gr "" + di in gr "" + } + forvalues i=1/`nbitems' { + local nbac`i'=`nbacpp`i''+`nbacmm`i'' + local nbvi`i'=`nbvipp`i''+`nbvimm`i'' + local maxvi`i'=max(`maxvipp`i'',`maxvimm`i'') + local sumvi`i'=`sumvipp`i''+`sumvimm`i'' + local zmaxvi`i'=max(`zmaxpp`i'',`zmaxmm`i'') + + local nbzsig`i'=`nbsigzpp`i''+`nbsigzmm`i'' + local zmax`i'=0 + *local nbsigz`i'=0 + local t=`loevHj'[1,`i'] +* di "local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmax`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' " + local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmaxvi`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' + + *di `nbac`i'' " " `nbvi`i'' " " `sumvi`i'' + if `nbvi`i''!=0 { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(33) %6.4f `=`nbvi`i''/`nbac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`nbac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzsig`i'' _col(93) %4.0f `crit`i'' + } + else { + di in green "" + } + } + else { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(93) %4.0f `crit`i'' + } + else { + di in green "" + } + } + } + if "`html'" != "" { + di in green "
Summary per item for check of non-Intersection via Pmatrix
" + di in gr "Minvi=" in ye %5.3f `minvi' "      Alpha=" in ye %5.3f `siglevel' "
Items#ac#vi#vi / #acmaxvisumsum / #aczmax#zsigCrit
" "``i''" "" %8.0f `nbac`i'' "" %8.0f `nbvi`i'' "" %6.4f `=`nbvi`i''/`nbac`i''' "" %6.4f `maxvi`i'' "" %6.4f `sumvi`i'' "" %6.4f `=`sumvi`i''/`nbac`i''' "" %6.4f `zmaxvi`i'' "" %8.0f `nbzsig`i'' "" %4.0f `crit`i'' "
" "``i''" "" %8.0f `nbac`i'' "" %8.0f `nbvi`i'' "" %4.0f `crit`i'' "
" + } +} + +/*if "`pmm'"!="" { + drop _all + matrix `P00g'=`P00',`P1'' + matrix colnames `P00g'=`varlist' `p1' + matrix rownames `P00g'=`varlist' + qui svmat `P00g' , names(col) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + forvalues i=1/`nbitems' { + qui replace `item'="``i''" if `id'==`i' + qui replace ``i''=. if `id'==`i' + local connect "`connect' l" + label define `monlabel' `i' "``i''", add + } + sort `p1' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + twoway connected `varlist' `id2',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) + } + format `varlist' %5.3f + label variable `id' "Item" + label value `id' `monlabel' + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + list `id' `varlist' , table compress separator(`nbitems') noobs divider + label drop `monlabel' +} + + + +if "`pairwise'"=="" { + restore, not +}*/ + + +*di "listw2:`listw2'" +*di "listv:`listv'" +*di "list:`list'" +*di "listi:`listi'" +*di "listm:`listm'" +*di "listitem:`listitem'" + + +qui use "`loevHfile'",clear +*set trace on +if "`generror'"!="" { + if "`replace'"!="" { + capture drop `generror'_0 + capture drop `generror'_H + capture drop `generror'_max + capture drop `generror'_GPN + capture drop `generror' + } + qui gen `generror'=0 + *forvalues i=1/`nbitems' { + * qui gen `generror'_``i''=0 + *} + qui gen `generror'_0=`eGutt0'/`nb' + local nbsteps:word count `listitem' + if "`pairwise'"=="" { + forvalues i=1/`nbitems' { + qui replace `generror'=. if ``i''==. + qui replace `generror'_0=. if ``i''==. + } + } + forvalues i=0/`nbsteps' { + di "qui guttmax `listitem', score(`i')" + qui guttmax `listitem', score(`i') + local errmax`i'=r(maxegutt) + } +* matrix list `P0' + forvalues i=1/`nbsteps' { + forvalues j=`=`i'+1'/`nbsteps' { + local w2i:word `i' of `listw2' + local w2j:word `j' of `listw2' + local itemi:word `w2i' of `listi' + local modai:word `w2i' of `listm' + local itemj:word `w2j' of `listi' + local modaj:word `w2j' of `listm' + qui replace `generror'=`generror'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + *qui replace `generror'_`itemi'=`generror'_`itemi'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + *qui replace `generror'_`itemj'=`generror'_`itemj'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. +* qui replace `generror'=`generror'+.5 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.&`P1'[1,`i']==`P1'[1,`j'] + *qui replace `generror'=`generror'+.5 if `P1'[1,`i']==`P1'[1,`j']&``i''==1&``j''==0 + } + } +* set trace on + tempvar flag + qui gen `flag'=0 + qui replace `flag'=1 `if' + qui replace `generror'=. if `flag'==0 + qui replace `generror'_0=. if `flag'==0 + qui gen `generror'_H=1-`generror'/`generror'_0 + tempvar score + qui genscore `varlist' `if',score(`score') + qui gen `generror'_max=. + forvalues i=1/`nbsteps' { + qui replace `generror'_max=`errmax`i'' if `score'==`i' + } + qui gen `generror'_GPN=`generror'/`generror'_max + label variable `generror' "Number of Guttman errors per individual" + label variable `generror'_H "H indice per individual" + if "`graph'"!="" { + qui histogram `generror',discrete freq name(errors,replace) + qui histogram `generror'_H,discrete freq name(H,replace) + } + qui su `generror' ,det + local meane=r(mean) + local mede=r(p50) + local mine=r(min) + local maxe=r(max) + qui su `generror'_GPN ,det + local meanGPN=r(mean) + local medGPN=r(p50) + local minGPN=r(min) + local maxGPN=r(max) + di + di in green "Number of Guttman errors by individual" _col(50) in green "Normalized number of Guttamn errors by individual" + di in green " Mean number: " in ye %7.2f `meane' _col(50) in green " Mean number: " in ye %7.2f `meanGPN' + di in green " Median number: " in ye %7.2f `mede' _col(50) in green " Median number: " in ye %7.2f `medGPN' + di in green " Minimal number: " in ye %7.2f `mine' _col(50) in green " Minimal number: " in ye %7.2f `minGPN' + di in green " Maximal number: " in ye %7.2f `maxe' _col(50) in green " Maximal number: " in ye %7.2f `maxGPN' + di in green "Expected Guttman errors: " in ye %7.2f `=`eGutt0'/`nb'' + qui count if `generror'_H<0 + di in green " Rate of Hn<0: " in ye %7.2f `=r(N)/`nb'*100' "%" + +} + +matrix colnames `loevHj'=`varlist' +matrix rownames `loevHj'=Hj +return matrix loevHj `loevHj' + +matrix colnames `loevHjk'=`varlist' +matrix rownames `loevHjk'=`varlist' +return matrix loevHjk `loevHjk' + +matrix colnames `eGuttj'=`varlist' +matrix rownames `eGuttj'=ej +return matrix eGuttj `eGuttj' + +matrix colnames `eGuttjk'=`varlist' +matrix rownames `eGuttjk'=`varlist' +return matrix eGuttjk `eGuttjk' + +matrix colnames `eGuttj0'=`varlist' +matrix rownames `eGuttj0'=ejk +return matrix eGuttj0 `eGuttj0' + +matrix colnames `eGuttjk0'=`varlist' +matrix rownames `eGuttjk0'=`varlist' +return matrix eGuttjk0 `eGuttjk0' + +return scalar loevH=`loevH' +return scalar eGutt =`eGutt' +return scalar eGutt0 =`eGutt0' + +if `modamax'==1 { + matrix colnames `P11'=`varlist' + matrix rownames `P11'=`varlist' + return matrix P11 `P11' +} + +matrix colnames `P00'=`varlist' +matrix rownames `P00'=`varlist' +return matrix P00 `P00' + +if "`ppp'"!=""|"`nipmatrix'"!="" { + return matrix ppp=`matpp' +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + return matrix pmm=`matmm' +} + +matrix colnames `zHj'=`varlist' +matrix rownames `zHj'=zHj +return matrix zHj `zHj' + +matrix colnames `pvalHj'=`varlist' +matrix rownames `pvalHj'=pval +return matrix pvalHj `pvalHj' + +return scalar zH=`zH' +return scalar pvalH=`pvalH' +if "`pair'"!="" { + matrix colnames `zHjk'=`varlist' + matrix rownames `zHjk'=`varlist' + return matrix zHjk `zHjk' + + matrix colnames `pvalHjk'=`varlist' + matrix rownames `pvalHjk'=`varlist' + return matrix pvalHjk `pvalHjk' +} + +matrix colnames `Obs'=`varlist' +matrix rownames `Obs'=`varlist' +return matrix Obs `Obs' + +capture restore, not + +end + diff --git a/Modules/ado/personal/l/loevh v8.2.ado b/Modules/ado/personal/l/loevh v8.2.ado new file mode 100644 index 0000000..0615c18 --- /dev/null +++ b/Modules/ado/personal/l/loevh v8.2.ado @@ -0,0 +1,1068 @@ +*! Version 8.2 13 July 2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : loevh +* Loevinger H indexes, Mokken Analysis +* +* +* Historic : +* Version 1 (August 20, 2002) [Jean-Benoit Hardouin] +* Version 2 (June 22, 2003) [Jean-Benoit Hardouin] +* Version 3 (December 1, 2003) [Jean-Benoit Hardouin] +* Version 4 (January 20, 2004) [Jean-Benoit Hardouin] +* Version 5 (March 22, 2004) [Jean-Benoit Hardouin] +* Version 6 (July 3, 2004) [Jean-Benoit Hardouin] +* Version 6.1 (September 19, 2005) [Jean-Benoit Hardouin] +* Version 6.2 (January 31, 2006) [Jean-Benoit Hardouin] +* Release 6.3 (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */ +* Release 6.4 (January 19, 2007) [Jean-Benoit Hardouin] /*Tests to compare Loevinger coefficients to 0 identical to the MSP software (dichotomous and polytomous case)*/ +* Release 6.5 (January 22, 2007) [Jean-Benoit Hardouin] /*Correction of a bug concerning the p-values with the pair option*/ +* Release 6.6 (Februar 16, 2007) [Jean-Benoit Hardouin] /*Correction of a bug with the displaying of Easyness with polytomous items, option graph, option generror, improvements*/ +* Release 7: June 21, 2007 [Jean-Benoit Hardouin] /*Check of monotonicity and Non intersection via P matrices*/ +* Release 7.1: November 6, 2008 [Jean-Benoit Hardouin] /*Correction for the z-tests for the check of non intersection via P matrices*/ +* Release 7.2: November 19, 2008 [Jean-Benoit Hardouin] /*Implementation of the GPN indexes*/ +* Release 7.3: August 15, 2009 [Jean-Benoit Hardouin] /*Print the difficulties of the items instead of P(X=0)*/ +* Release 8: December 8, 2010 [Jean-Benoit Hardouin] /*loevH is renamed loevh*/ +* Release 8.1: October 19, 2012 [Jean-Benoit Hardouin] /*html option*/ +* Release 8.1.1 : November 20, 2012 [Jean-Benoit Hardouin] /*graphs with the html option*/ +* Release 8.1.2 : December 7, 2012 [Jean-Benoit Hardouin] /*minor correction*/ +* Release 8.1.3 : March 23, 2015 [Jean-Benoit Hardouin] /*minor correction for displaying results*/ +* Release 8.2 : July 13, 2019 [Jean-Benoit Hardouin] /*correction for the displaying and the saving of the graphs, deletion of the html option*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* INSERM UMR 1246-SPHERE +* Nantes University - University of Tours +* France +* jean-benoit.hardouin@anaqol.org +* +* Requiered Stata modules: +* -anaoption- (version 1) +* -traces- (version 3.2) +* -gengroup- (version 1) +* -guttmax- (version 1) +* +* News about this program :http://www.anaqol.org +* +* Copyright 2002-2015, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** + +program define loevh , rclass +version 8.2 +syntax varlist(min=2 numeric) [if] [,PAIRWise PAIR ppp pmm noADJust GENERror(string) REPlace GRaph MONOtonicity(string) NIRESTscore(string) NIPmatrix(string) HTML(string) filesave dirsave(string) pro] +preserve + +/*********************************************************************************************************** +TESTS INITIAUX +***********************************************************************************************************/ +local nbitems : word count `varlist' +tokenize `varlist' +tempname corr cov P1 P0 diff P11 P00 H1jk vHjk zHjk chi2Hjk dfHjk pvalHjk H1j vHj zHj pvalHj H1 vH zH pvalH Obs eGuttjk eGuttjk0 loevHjk eGuttj eGuttj0 loevHj eGutt eGutt0 loevH e1 e2 +tempfile loevHfile +qui save "`loevHfile'" + +if "`if'"!="" { + qui keep `if' +} + +if "`adjust'"!="" { + local adj=0 +} +else { + local adj=1 +} + +if "`filesave'"!=""&"`dirsave'"=="" { + local dirsave `c(pwd)' +} + +qui count +local nbobs=r(N) + +forvalues j=1/`nbitems' { + if "`pairwise'"=="" { + qui drop if ``j''==. + } +} +qui count +local nbtotindnm=r(N) + +matrix define `eGuttjk'=J(`nbitems',`nbitems',0) +matrix define `eGuttjk0'=J(`nbitems',`nbitems',0) +matrix define `loevHjk'=J(`nbitems',`nbitems',0) +matrix define `eGuttj'=J(1,`nbitems',0) +matrix define `eGuttj0'=J(1,`nbitems',0) +matrix define `loevHj'=J(1,`nbitems',0) +scalar define `eGutt'=0 +scalar define `eGutt0'=0 +scalar define `loevH'=0 +matrix define `Obs'=J(`nbitems',`nbitems',0) +matrix define `P00'=J(`nbitems',`nbitems',0) + +tempname modamax +scalar `modamax'=0 +local scoremax=0 +forvalues j=1/`nbitems' { + qui su ``j'' + local m`j'=r(max) + local scoremax=`scoremax'+`m`j'' + if r(max)>`modamax' { + scalar `modamax'=r(max) + } + local nbHjkNS`j'=0 +} + +/*if "`graph'"!=""&`scoremax'>19 { + di in ye "The {cmd:graph} option is disabled because of a large number of possible scores (>20)" + local graph +}*/ + +matrix define `cov'=J(`nbitems',`nbitems',0) +matrix define `corr'=J(`nbitems',`nbitems',0) +matrix define `P11'=J(`nbitems',`nbitems',0) +matrix define `H1jk'=J(`nbitems',`nbitems',0) +matrix define `vHjk'=J(`nbitems',`nbitems',0) +matrix define `zHjk'=J(`nbitems',`nbitems',0) +matrix define `pvalHjk'=J(`nbitems',`nbitems',0) +matrix define `P1'=J(1,`nbitems',0) +matrix define `P0'=J(1,`nbitems',0) +matrix define `diff'=J(1,`nbitems',0) +matrix define `H1j'=J(1,`nbitems',0) +matrix define `vHj'=J(1,`nbitems',0) +matrix define `zHj'=J(1,`nbitems',0) +matrix define `pvalHj'=J(1,`nbitems',0) + + +/*********************************************************************************************************** +CALCUL DES ERREURS DE GUTTMAN ET COEFFICIENTS DE LOEVINGER +***********************************************************************************************************/ + +forvalues j=1/`nbitems' { + qui su ``j'' + matrix `cov'[`j',`j']=r(Var) + matrix `corr'[`j',`j']=1 + local tmp=`j'+1 + qui count if ``j''!=. + matrix `Obs'[`j',`j']=r(N) + forvalues k=`tmp'/`nbitems' { + qui count if ``j''!=.&``k''!=. + matrix `Obs'[`j',`k']=r(N) + matrix `Obs'[`k',`j']=r(N) + qui corr ``j'' ``k'',cov + matrix `cov'[`j',`k']=r(cov_12) + matrix `cov'[`k',`j']=r(cov_12) + qui corr ``j'' ``k'' + matrix `corr'[`j',`k']=r(rho) + matrix `corr'[`k',`j']=r(rho) + matrix `zHjk'[`j',`k']=`corr'[`j',`k']*(`Obs'[`j',`k']-`adj')^.5 + matrix `zHjk'[`k',`j']=`H1jk'[`j',`k'] + matrix `pvalHjk'[`j',`k']=1-norm(`zHjk'[`j',`k']) + matrix `pvalHjk'[`k',`j']=`pvalHjk'[`j',`k'] + if `pvalHjk'[`j',`k']>0.05 { + local nbHjkNS`j'=`nbHjkNS`j''+1 + local nbHjkNS`k'=`nbHjkNS`k''+1 + } + forvalues mod1=1/`m`j'' { + forvalues mod2=1/`m`k'' { + qui count if ``j''<`mod1'&``k''>=`mod2'&``j''!=.&``k''!=. + scalar `e1'=r(N) + qui count if ``j''>=`mod1'&``k''<`mod2'&``j''!=.&``k''!=. + scalar `e2'=r(N) + matrix `eGuttjk'[`j',`k']=`eGuttjk'[`j',`k']+min(`e1',`e2') + qui count if ``j''<`mod1'&``j''!=.&``k''!=. + local t1=r(N) + qui count if ``k''<`mod2'&``j''!=.&``k''!=. + local t2=r(N) + qui count if ``j''>=`mod1'&``j''!=.&``k''!=. + local t3=r(N) + qui count if ``k''>=`mod2'&``j''!=.&``k''!=. + local t4=r(N) + if min(`e1',`e2')==`e1' { + matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t1'*`t4'/`Obs'[`j',`k'] + } + else { + matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t2'*`t3'/`Obs'[`j',`k'] + } + + } + } + qui count if ``j''==0&``k''==0 + matrix `P00'[`j',`k']=r(N)/`Obs'[`j',`k'] + matrix `P00'[`k',`j']=r(N)/`Obs'[`k',`j'] + if `modamax'==1 { + qui count if ``j''==1&``k''==1 + matrix `P11'[`j',`k']=r(N)/`Obs'[`j',`k'] + matrix `P11'[`k',`j']=r(N)/`Obs'[`k',`j'] + } + + matrix `eGuttjk'[`k',`j']=`eGuttjk'[`j',`k'] + matrix `eGuttj'[1,`j']=`eGuttj'[1,`j']+`eGuttjk'[`j',`k'] + matrix `eGuttj'[1,`k']=`eGuttj'[1,`k']+`eGuttjk'[`j',`k'] + matrix `eGuttjk0'[`k',`j']=`eGuttjk0'[`j',`k'] + matrix `eGuttj0'[1,`j']=`eGuttj0'[1,`j']+`eGuttjk0'[`j',`k'] + matrix `eGuttj0'[1,`k']=`eGuttj0'[1,`k']+`eGuttjk0'[`j',`k'] + + matrix `loevHjk'[`j',`k']=1-`eGuttjk'[`j',`k']/`eGuttjk0'[`j',`k'] + matrix `loevHjk'[`k',`j']=`loevHjk'[`j',`k'] + + } + qui count if ``j''!=. + local tmp=r(N) + qui count if ``j''==1 + matrix `P1'[1,`j']=r(N)/`tmp' + qui count if ``j''==0 + matrix `P0'[1,`j']=r(N)/`tmp' + qui su ``j'' + matrix `diff'[1,`j']=r(mean) + matrix `loevHj'[1,`j']=1-`eGuttj'[1,`j']/`eGuttj0'[1,`j'] + scalar `eGutt'=`eGutt'+`eGuttj'[1,`j']/2 + scalar `eGutt0'=`eGutt0'+`eGuttj0'[1,`j']/2 +} +scalar `H1'=0 +scalar `vH'=0 +scalar `zH'=0 +forvalues j=1/`nbitems'{ + forvalues k=1/`nbitems' { + if `j'!=`k' { + matrix `zHj'[1,`j']=`zHj'[1,`j']+`cov'[`j',`k'] + matrix `vHj'[1,`j']=`vHj'[1,`j']+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj') + } + if `j'<`k' { + scalar `zH'=`zH'+`cov'[`j',`k'] + scalar `vH'=`vH'+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj') + } + } + matrix `zHj'[1,`j']=`zHj'[1,`j']/sqrt(`vHj'[1,`j']) + matrix `pvalHj'[1,`j']=1-norm(`zHj'[1,`j']) +} +scalar `zH'=`zH'/sqrt(`vH') +scalar `pvalH'=1-norm(`zH') +scalar `loevH'=1-`eGutt'/`eGutt0' +local loevH=1-`eGutt'/`eGutt0' + +if `modamax'==1 { + local text="Easyness" + local value=1 + local col=23 +} +else { + local text="Difficulty" + local value=0 + local col=21 +} + +/*********************************************************************************************************** +AFFICHAGE DES PREMIERS RESULTATS +***********************************************************************************************************/ + + +di in green _col(35) "Observed" _col(47) "Expected" _col(93) "Number" +di in green _col(27) "Mean" _col(36) "Guttman" _col(48) "Guttman" _col(59) "Loevinger" _col(83) "H0: Hj<=0" _col(94) "of NS" +di in green "Item" _col(15) "Obs" _col(26) "Score" _col(37) "errors" _col(49) "errors" _col(61) "H coeff" _col(73) "z-stat." _col(85) "p-value" _col(96) "Hjk" +di in green "{hline 99}" +forvalues j=1/`nbitems' { + di in green "``j''" in yellow _col(15) `Obs'[`j',`j'] _col(25) %6.4f `diff'[1,`j'] _col(36) %7.0f `eGuttj'[1,`j'] _col(45) %10.2f `eGuttj0'[1,`j'] _col(61) %7.5f `loevHj'[1,`j'] _col(72) %8.4f `zHj'[1,`j'] _col(85) %7.5f `pvalHj'[1,`j'] _col(97) %2.0f `nbHjkNS`j'' +} +di in green "{hline 99}" + +if "`pairwise'"=="" { + local nb=`nbtotindnm' +} +else { + local nb=`nbobs' +} +di in green "Scale" in yellow _col(15) `nb' _col(36) %7.0f `eGutt' _col(45) %10.2f `eGutt0' _col(61) %-8.5f `loevH' _col(71) %9.4f `zH' _col(85) %7.5f `pvalH' + +if "`pair'"!="" { + di + di in green _col(45) "Observed" _col(57) "Expected" + di in green _col(`=`col'+10') "`text'" _col(46) "Guttman" _col(58) "Guttman" _col(69) "Loevinger" _col(92) "H0: Hjk<=0" + di in green "Items" _col(25) "Obs" _col(29) "P(Xj=`value',Xk=`value')" _col(47) "errors" _col(59) "errors" _col(71) "H coeff" _col(83) "z-stat." _col(95) "p-value" + di in green "{hline 101}" + forvalues j=1/`nbitems' { + forvalues k=`=`j'+1'/`nbitems' { + qui count if ``j''!=. + local obs=r(N) + di in green "``j''" _col(10) "``k''" in yellow _col(25) `Obs'[`j',`k'] _col(35) %6.4f `P`value'`value''[`j',`k'] _col(48) %5.0f `eGuttjk'[`j',`k'] _col(57) %8.2f `eGuttjk0'[`j',`k'] _col(70) %8.5f `loevHjk'[`j',`k'] _col(81) %9.4f `zHjk'[`j',`k'] _col(95) %7.5f `pvalHjk'[`j',`k'] + } + } + di in green "{hline 101}" +} + + +tempname P11g P00g item id id2 p1 monlabel + +/*********************************************************************************************************** +MONOTONICITY +***********************************************************************************************************/ + + +if "`monotonicity'"!="" { + if "`monotonicity'"=="*" { + anaoption + } + else { + anaoption,`monotonicity' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + + tempname score + qui genscore `varlist',score(`score') + di + di in green _col(10) "Summary per item for check of monotonicity" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + tempname restscore`i' + qui gen `restscore`i''=`score'-``i'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroup`i' + qui gengroup `restscore`i'',newvariable(`restgroup`i'') minsize(`minsize') + local list`i'=r(list) + qui su `restgroup`i'' + local nbgroups`i'=r(max) + forvalues j=0/`nbgroups`i'' { + qui count if `restgroup`i''==`j' + local rgroup`j'=r(N) + } + local vi`i'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + } + forvalues l=1/`m`i'' { + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + local nbzvi`i'_`l'=0 + forvalues j=1/`nbgroups`i'' { + qui count if `restgroup`i''==`j'&``i''>=`l' + local nbitem`i'rgroup`j'_`l'=r(N) + forvalues k=1/`=`j'-1' { + local diff=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + if `nbitem`i'rgroup`j'_`l''!=`rgroup`j''&`nbitem`i'rgroup`k'_`l''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + } + local p=(`nbitem`i'rgroup`k'_`l''+`nbitem`i'rgroup`j'_`l'')/(`rgroup`j''+`rgroup`k'') + local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + } + if `j'==`nbgroups`i'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + } + di in green "{dup 97:-}" + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + *set trace on + if `vi`i''!=0 { + if "`pro'"=="" { + local graph1 "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + local graph1 + } + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "`graph1'" + } + else { + if "`pro'"=="" { + local graph1 "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + local graph1 + } + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "`graph1'" + } + if "`details'"!=""&`i'!=`nbitems' { + di in green "{dup 97:-}" + } + if "`pro'"!=""&"`filesave'"!="" { + qui traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i'') filesave dirsave(`dirsave') + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" +} + + +/*********************************************************************************************************** +PPP et PMM MATRICES +***********************************************************************************************************/ + + +if "`ppp'"!=""|"pmm"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + local list + local listi + local listm + local listv + forvalues i=1/`nbitems' { + forvalues l=1/`m`i'' { + tempname item`i'_`l' + qui gen `item`i'_`l''=``i''>=`l' if ``i''!=. + local list `list' ``i''_`l' + local listi `listi' ``i'' + local listm `listm' `l' + local listv `listv' `item`i'_`l'' + } + } + tempname matppp matpmm + matrix `matppp'=J(`=`scoremax'',`=`scoremax'+2',0) + matrix `matpmm'=J(`=`scoremax'',`=`scoremax'+2',0) + local row=1 + forvalues i=1/`nbitems' { + forvalues k=1/`m`i'' { + local col=1 + forvalues j=1/`nbitems' { + forvalues l=1/`m`j'' { + if `i'!=`j' { + qui count if `item`i'_`k''!=.&`item`j'_`l''!=. + local denom=r(N) + qui count if `item`i'_`k''==1&`item`j'_`l''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0&`item`j'_`l''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + } + else { + matrix `matppp'[`row',`col']=-1 + matrix `matpmm'[`row',`col']=-1 + } + local col=`col'+1 + } + } + qui count if `item`i'_`k''!=. + local denom=r(N) + qui count if `item`i'_`k''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + matrix `matppp'[`row',`=`scoremax'+2']=`i' + matrix `matpmm'[`row',`=`scoremax'+2']=`i' + local row=`row'+1 + } + } + matrix colnames `matppp'=`list' p1 item + matrix rownames `matppp'=`list' + matrix colnames `matpmm'=`list' p1 item + matrix rownames `matpmm'=`list' + if "`nipmatrix'"!="" { + if "`nipmatrix'"=="*" { + anaoption + } + else { + anaoption,`nipmatrix' + } + local minvi=`r(minvi)' + local siglevel=`r(siglevel)' + local minsize=`r(minsize)' + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + forvalues i=1/`nbitems' { + local nbacpp`i'=0 + local nbvipp`i'=0 + local maxvipp`i'=0 + local sumvipp`i'=0 + local zmaxpp`i'=0 + local nbsigzpp`i'=0 + local nbacmm`i'=0 + local nbvimm`i'=0 + local maxvimm`i'=0 + local sumvimm`i'=0 + local zmaxmm`i'=0 + local nbsigzmm`i'=0 + } + } + +} +tempfile temporaryfile +qui save `temporaryfile' + +if "`ppp'"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + drop * + qui svmat `matppp',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + sort p1 + qui set obs `=`scoremax'+1' + local listitem + forvalues i=1/`scoremax' { + local t=item[`i'] + local listitem `listitem' `t' + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + + if "`graph'"!="" { + if "`filesave'"=="" { + qui local saving + } + else { + qui local saving saving(`dirsave'//ppp,replace) + } + if `scoremax'<20 { + qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P++ diagnostics") name(ppp,replace) `saving' + } + } + + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matpp + matrix define `matpp'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local ti:word `i' of `listv' + local tj:word `j' of `listv' + local t:word `j' of `list2' + matrix `matpp'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matpp'=`list2' + matrix rownames `matpp'=`list2' + + if "`ppp'"!="" { + di + di in green _col(10) "P++ values per items pair (The values should be increasing in each column)" + matrix list `matpp',format(%5.3f) nohalf noheader + } + + label drop `monlabel' + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacpp`ti' + *local ++nbacmm`tk' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==1&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==1&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "++ `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzpp`tj' + if abs(`z')>`zmaxpp`tj'' { + local zmaxpp`tj'=abs(`z') + } + local ++nbsigzpp`tk' + if abs(`z')>`zmaxpp`tk'' { + local zmaxpp`tk'=abs(`z') + } + } + } + } + } + } + } + } +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + drop _all + qui svmat `matpmm',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + gsort -p1 + qui set obs `=`scoremax'+1' + forvalues i=1/`scoremax' { + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + if "`filesave'"=="" { + qui local saving + } + else { + qui local saving saving(`dirsave'//pmm,replace) + } + if `scoremax'<20 { + qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) `saving' + } + } + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matmm + matrix define `matmm'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local t:word `j' of `list2' + matrix `matmm'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matmm'=`list2' + matrix rownames `matmm'=`list2' + if "`pmm'"!="" { + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + matrix list `matmm',format(%5.3f) nohalf noheader + } + label drop `monlabel' + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacmm`ti' + *local ++nbacmm`tk' + local diff=`matmm'[`k',`i']-`matmm'[`j',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvimm`tj' + local ++nbvimm`tk' + local sumvimm`tj'=`sumvimm`tj''+`diff' + local sumvimm`tk'=`sumvimm`tk''+`diff' + if `diff'>`maxvimm`tj'' { + local maxvimm`tj'=`diff' + } + if `diff'>`maxvimm`tk'' { + local maxvimm`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==0&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==0&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "-- `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzmm`tj' + if abs(`z')>`zmaxmm`tj'' { + local zmaxmm`tj'=abs(`z') + } + local ++nbsigzmm`tk' + if abs(`z')>`zmaxmm`tk'' { + local zmaxmm`tk'=abs(`z') + } + } + } + } + } + } + } + } +} +if `scoremax'>19&("`ppp'"!=""|"`pmm'"!="")&"`graph'"!="" { + di + di "Due to the total number of possibles scores (`=`scoremax'+1'), the P++ and P-- graphical representations cannot be displayed" +} + +/*********************************************************************************************************** +NIPMATRIX +***********************************************************************************************************/ + + +if "`nipmatrix'" !="" { + di + di in green _col(10) "Summary per item for check of non-Intersection via Pmatrix" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) /*in green "Minsize=" in ye %5.0f `minsize' _col(40)*/ in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + forvalues i=1/`nbitems' { + local nbac`i'=`nbacpp`i''+`nbacmm`i'' + local nbvi`i'=`nbvipp`i''+`nbvimm`i'' + local maxvi`i'=max(`maxvipp`i'',`maxvimm`i'') + local sumvi`i'=`sumvipp`i''+`sumvimm`i'' + local zmaxvi`i'=max(`zmaxpp`i'',`zmaxmm`i'') + + local nbzsig`i'=`nbsigzpp`i''+`nbsigzmm`i'' + local zmax`i'=0 + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmaxvi`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' + + if `nbvi`i''!=0 { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(33) %6.4f `=`nbvi`i''/`nbac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`nbac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzsig`i'' _col(93) %4.0f `crit`i'' + } + else { + di in green "" "``i''" "" %8.0f `nbac`i'' "" %8.0f `nbvi`i'' "" %6.4f `=`nbvi`i''/`nbac`i''' "" %6.4f `maxvi`i'' "" %6.4f `sumvi`i'' "" %6.4f `=`sumvi`i''/`nbac`i''' "" %6.4f `zmaxvi`i'' "" %8.0f `nbzsig`i'' "" %4.0f `crit`i'' "" + } + } + else { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(93) %4.0f `crit`i'' + } + } +} + + +qui use "`loevHfile'",clear + + +/*********************************************************************************************************** +GENERATION DE NOUVELLES VARIABLES +***********************************************************************************************************/ + + +if "`generror'"!="" { + if "`replace'"!="" { + capture drop `generror'_0 + capture drop `generror'_H + capture drop `generror'_max + capture drop `generror'_GPN + capture drop `generror' + } + qui gen `generror'=0 + forvalues i=1/`nbitems' { + capture drop `generror'_``i'' + qui gen `generror'_``i''=0 + } + qui gen `generror'_0=`eGutt0'/`nb' + local nbsteps:word count `listitem' + if "`pairwise'"=="" { + forvalues i=1/`nbitems' { + qui replace `generror'=. if ``i''==. + qui replace `generror'_0=. if ``i''==. + } + } + forvalues i=0/`nbsteps' { + *di "qui guttmax `listitem', score(`i')" + qui guttmax `listitem', score(`i') + local errmax`i'=r(maxegutt) + } + forvalues i=1/`nbsteps' { + forvalues j=`=`i'+1'/`nbsteps' { + local w2i:word `i' of `listw2' + local w2j:word `j' of `listw2' + local itemi:word `w2i' of `listi' + local modai:word `w2i' of `listm' + local itemj:word `w2j' of `listi' + local modaj:word `w2j' of `listm' + qui replace `generror'=`generror'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + qui replace `generror'_`itemi'=`generror'_`itemi'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + qui replace `generror'_`itemj'=`generror'_`itemj'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + } + } + tempvar flag + qui gen `flag'=0 + qui replace `flag'=1 `if' + qui replace `generror'=. if `flag'==0 + qui replace `generror'_0=. if `flag'==0 + qui gen `generror'_H=1-`generror'/`generror'_0 + tempvar score + qui genscore `varlist' `if',score(`score') + qui gen `generror'_max=. + forvalues i=1/`nbsteps' { + qui replace `generror'_max=`errmax`i'' if `score'==`i' + } + qui gen `generror'_GPN=`generror'/`generror'_max + label variable `generror' "Number of Guttman errors per individual" + label variable `generror'_H "H indice per individual" + if "`graph'"!="" { + if "`filesave'"=="" { + local saving1 + local saving2 + local saving3 + } + else { + local saving1 saving(`dirsave'//`generror', replace) + local saving2 saving(`dirsave'//`generror'_H, replace) + local saving3 saving(`dirsave'//`generror'_box, replace) + } + qui histogram `generror',discrete freq name(errors,replace) `saving1' + qui graph box `generror',name(errors_box,replace) `saving3' + qui histogram `generror'_H,discrete freq name(H,replace) `saving2' + } + qui su `generror' ,det + local meane=r(mean) + local mede=r(p50) + local mine=r(min) + local maxe=r(max) + qui su `generror'_GPN ,det + local meanGPN=r(mean) + local medGPN=r(p50) + local minGPN=r(min) + local maxGPN=r(max) + di + di in green "Number of Guttman errors by individual" _col(50) in green "Normalized number of Guttamn errors by individual" + di in green " Mean number: " in ye %7.2f `meane' _col(50) in green " Mean number: " in ye %7.2f `meanGPN' + di in green " Median number: " in ye %7.2f `mede' _col(50) in green " Median number: " in ye %7.2f `medGPN' + di in green " Minimal number: " in ye %7.2f `mine' _col(50) in green " Minimal number: " in ye %7.2f `minGPN' + di in green " Maximal number: " in ye %7.2f `maxe' _col(50) in green " Maximal number: " in ye %7.2f `maxGPN' + di in green "Expected Guttman errors: " in ye %7.2f `=`eGutt0'/`nb'' + qui count if `generror'_H<0 + di in green " Rate of Hn<0: " in ye %7.2f `=r(N)/`nb'*100' "%" + +} + +matrix colnames `loevHj'=`varlist' +matrix rownames `loevHj'=Hj +return matrix loevHj `loevHj' + +matrix colnames `loevHjk'=`varlist' +matrix rownames `loevHjk'=`varlist' +return matrix loevHjk `loevHjk' + +matrix colnames `eGuttj'=`varlist' +matrix rownames `eGuttj'=ej +return matrix eGuttj `eGuttj' + +matrix colnames `eGuttjk'=`varlist' +matrix rownames `eGuttjk'=`varlist' +return matrix eGuttjk `eGuttjk' + +matrix colnames `eGuttj0'=`varlist' +matrix rownames `eGuttj0'=ejk +return matrix eGuttj0 `eGuttj0' + +matrix colnames `eGuttjk0'=`varlist' +matrix rownames `eGuttjk0'=`varlist' +return matrix eGuttjk0 `eGuttjk0' + +return scalar loevH=`loevH' +return scalar eGutt =`eGutt' +return scalar eGutt0 =`eGutt0' + +if `modamax'==1 { + matrix colnames `P11'=`varlist' + matrix rownames `P11'=`varlist' + return matrix P11 `P11' +} + +matrix colnames `P00'=`varlist' +matrix rownames `P00'=`varlist' +return matrix P00 `P00' + +if "`ppp'"!=""|"`nipmatrix'"!="" { + return matrix ppp=`matpp' +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + return matrix pmm=`matmm' +} + +matrix colnames `zHj'=`varlist' +matrix rownames `zHj'=zHj +return matrix zHj `zHj' + +matrix colnames `pvalHj'=`varlist' +matrix rownames `pvalHj'=pval +return matrix pvalHj `pvalHj' + +return scalar zH=`zH' +return scalar pvalH=`pvalH' +if "`pair'"!="" { + matrix colnames `zHjk'=`varlist' + matrix rownames `zHjk'=`varlist' + return matrix zHjk `zHjk' + + matrix colnames `pvalHjk'=`varlist' + matrix rownames `pvalHjk'=`varlist' + return matrix pvalHjk `pvalHjk' +} + +matrix colnames `Obs'=`varlist' +matrix rownames `Obs'=`varlist' +return matrix Obs `Obs' + +capture restore, not + +end + diff --git a/Modules/ado/personal/l/loevh.ado b/Modules/ado/personal/l/loevh.ado new file mode 100644 index 0000000..0145ad2 --- /dev/null +++ b/Modules/ado/personal/l/loevh.ado @@ -0,0 +1,1069 @@ +*! Version 8.3 29 August 2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : loevh +* Loevinger H indexes, Mokken Analysis +* +* +* Historic : +* Version 1 (August 20, 2002) [Jean-Benoit Hardouin] +* Version 2 (June 22, 2003) [Jean-Benoit Hardouin] +* Version 3 (December 1, 2003) [Jean-Benoit Hardouin] +* Version 4 (January 20, 2004) [Jean-Benoit Hardouin] +* Version 5 (March 22, 2004) [Jean-Benoit Hardouin] +* Version 6 (July 3, 2004) [Jean-Benoit Hardouin] +* Version 6.1 (September 19, 2005) [Jean-Benoit Hardouin] +* Version 6.2 (January 31, 2006) [Jean-Benoit Hardouin] +* Release 6.3 (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */ +* Release 6.4 (January 19, 2007) [Jean-Benoit Hardouin] /*Tests to compare Loevinger coefficients to 0 identical to the MSP software (dichotomous and polytomous case)*/ +* Release 6.5 (January 22, 2007) [Jean-Benoit Hardouin] /*Correction of a bug concerning the p-values with the pair option*/ +* Release 6.6 (Februar 16, 2007) [Jean-Benoit Hardouin] /*Correction of a bug with the displaying of Easyness with polytomous items, option graph, option generror, improvements*/ +* Release 7: June 21, 2007 [Jean-Benoit Hardouin] /*Check of monotonicity and Non intersection via P matrices*/ +* Release 7.1: November 6, 2008 [Jean-Benoit Hardouin] /*Correction for the z-tests for the check of non intersection via P matrices*/ +* Release 7.2: November 19, 2008 [Jean-Benoit Hardouin] /*Implementation of the GPN indexes*/ +* Release 7.3: August 15, 2009 [Jean-Benoit Hardouin] /*Print the difficulties of the items instead of P(X=0)*/ +* Release 8: December 8, 2010 [Jean-Benoit Hardouin] /*loevH is renamed loevh*/ +* Release 8.1: October 19, 2012 [Jean-Benoit Hardouin] /*html option*/ +* Release 8.1.1 : November 20, 2012 [Jean-Benoit Hardouin] /*graphs with the html option*/ +* Release 8.1.2 : December 7, 2012 [Jean-Benoit Hardouin] /*minor correction*/ +* Release 8.1.3 : March 23, 2015 [Jean-Benoit Hardouin] /*minor correction for displaying results*/ +* Release 8.2 : July 13, 2019 [Jean-Benoit Hardouin] /*correction for the displaying and the saving of the graphs, deletion of the html option*/ +* Release 8.3 : August 29, 2019 [Jean-Benoit Hardouin] /*correction of a bug with the graph and generror options*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* INSERM UMR 1246-SPHERE +* Nantes University - University of Tours +* France +* jean-benoit.hardouin@anaqol.org +* +* Requiered Stata modules: +* -anaoption- (version 1) +* -traces- (version 3.2) +* -gengroup- (version 1) +* -guttmax- (version 1) +* +* News about this program :http://www.anaqol.org +* +* Copyright 2002-2015, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** + +program define loevh , rclass +version 8.2 +syntax varlist(min=2 numeric) [if] [,PAIRWise PAIR ppp pmm noADJust GENERror(string) REPlace GRaph MONOtonicity(string) NIRESTscore(string) NIPmatrix(string) HTML(string) filesave dirsave(string) pro] +preserve + +/*********************************************************************************************************** +TESTS INITIAUX +***********************************************************************************************************/ +local nbitems : word count `varlist' +tokenize `varlist' +tempname corr cov P1 P0 diff P11 P00 H1jk vHjk zHjk chi2Hjk dfHjk pvalHjk H1j vHj zHj pvalHj H1 vH zH pvalH Obs eGuttjk eGuttjk0 loevHjk eGuttj eGuttj0 loevHj eGutt eGutt0 loevH e1 e2 +tempfile loevHfile +qui save "`loevHfile'" + +if "`if'"!="" { + qui keep `if' +} + +if "`adjust'"!="" { + local adj=0 +} +else { + local adj=1 +} + +if "`filesave'"!=""&"`dirsave'"=="" { + local dirsave `c(pwd)' +} + +qui count +local nbobs=r(N) + +forvalues j=1/`nbitems' { + if "`pairwise'"=="" { + qui drop if ``j''==. + } +} +qui count +local nbtotindnm=r(N) + +matrix define `eGuttjk'=J(`nbitems',`nbitems',0) +matrix define `eGuttjk0'=J(`nbitems',`nbitems',0) +matrix define `loevHjk'=J(`nbitems',`nbitems',0) +matrix define `eGuttj'=J(1,`nbitems',0) +matrix define `eGuttj0'=J(1,`nbitems',0) +matrix define `loevHj'=J(1,`nbitems',0) +scalar define `eGutt'=0 +scalar define `eGutt0'=0 +scalar define `loevH'=0 +matrix define `Obs'=J(`nbitems',`nbitems',0) +matrix define `P00'=J(`nbitems',`nbitems',0) + +tempname modamax +scalar `modamax'=0 +local scoremax=0 +forvalues j=1/`nbitems' { + qui su ``j'' + local m`j'=r(max) + local scoremax=`scoremax'+`m`j'' + if r(max)>`modamax' { + scalar `modamax'=r(max) + } + local nbHjkNS`j'=0 +} + +/*if "`graph'"!=""&`scoremax'>19 { + di in ye "The {cmd:graph} option is disabled because of a large number of possible scores (>20)" + local graph +}*/ + +matrix define `cov'=J(`nbitems',`nbitems',0) +matrix define `corr'=J(`nbitems',`nbitems',0) +matrix define `P11'=J(`nbitems',`nbitems',0) +matrix define `H1jk'=J(`nbitems',`nbitems',0) +matrix define `vHjk'=J(`nbitems',`nbitems',0) +matrix define `zHjk'=J(`nbitems',`nbitems',0) +matrix define `pvalHjk'=J(`nbitems',`nbitems',0) +matrix define `P1'=J(1,`nbitems',0) +matrix define `P0'=J(1,`nbitems',0) +matrix define `diff'=J(1,`nbitems',0) +matrix define `H1j'=J(1,`nbitems',0) +matrix define `vHj'=J(1,`nbitems',0) +matrix define `zHj'=J(1,`nbitems',0) +matrix define `pvalHj'=J(1,`nbitems',0) + + +/*********************************************************************************************************** +CALCUL DES ERREURS DE GUTTMAN ET COEFFICIENTS DE LOEVINGER +***********************************************************************************************************/ + +forvalues j=1/`nbitems' { + qui su ``j'' + matrix `cov'[`j',`j']=r(Var) + matrix `corr'[`j',`j']=1 + local tmp=`j'+1 + qui count if ``j''!=. + matrix `Obs'[`j',`j']=r(N) + forvalues k=`tmp'/`nbitems' { + qui count if ``j''!=.&``k''!=. + matrix `Obs'[`j',`k']=r(N) + matrix `Obs'[`k',`j']=r(N) + qui corr ``j'' ``k'',cov + matrix `cov'[`j',`k']=r(cov_12) + matrix `cov'[`k',`j']=r(cov_12) + qui corr ``j'' ``k'' + matrix `corr'[`j',`k']=r(rho) + matrix `corr'[`k',`j']=r(rho) + matrix `zHjk'[`j',`k']=`corr'[`j',`k']*(`Obs'[`j',`k']-`adj')^.5 + matrix `zHjk'[`k',`j']=`H1jk'[`j',`k'] + matrix `pvalHjk'[`j',`k']=1-norm(`zHjk'[`j',`k']) + matrix `pvalHjk'[`k',`j']=`pvalHjk'[`j',`k'] + if `pvalHjk'[`j',`k']>0.05 { + local nbHjkNS`j'=`nbHjkNS`j''+1 + local nbHjkNS`k'=`nbHjkNS`k''+1 + } + forvalues mod1=1/`m`j'' { + forvalues mod2=1/`m`k'' { + qui count if ``j''<`mod1'&``k''>=`mod2'&``j''!=.&``k''!=. + scalar `e1'=r(N) + qui count if ``j''>=`mod1'&``k''<`mod2'&``j''!=.&``k''!=. + scalar `e2'=r(N) + matrix `eGuttjk'[`j',`k']=`eGuttjk'[`j',`k']+min(`e1',`e2') + qui count if ``j''<`mod1'&``j''!=.&``k''!=. + local t1=r(N) + qui count if ``k''<`mod2'&``j''!=.&``k''!=. + local t2=r(N) + qui count if ``j''>=`mod1'&``j''!=.&``k''!=. + local t3=r(N) + qui count if ``k''>=`mod2'&``j''!=.&``k''!=. + local t4=r(N) + if min(`e1',`e2')==`e1' { + matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t1'*`t4'/`Obs'[`j',`k'] + } + else { + matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t2'*`t3'/`Obs'[`j',`k'] + } + + } + } + qui count if ``j''==0&``k''==0 + matrix `P00'[`j',`k']=r(N)/`Obs'[`j',`k'] + matrix `P00'[`k',`j']=r(N)/`Obs'[`k',`j'] + if `modamax'==1 { + qui count if ``j''==1&``k''==1 + matrix `P11'[`j',`k']=r(N)/`Obs'[`j',`k'] + matrix `P11'[`k',`j']=r(N)/`Obs'[`k',`j'] + } + + matrix `eGuttjk'[`k',`j']=`eGuttjk'[`j',`k'] + matrix `eGuttj'[1,`j']=`eGuttj'[1,`j']+`eGuttjk'[`j',`k'] + matrix `eGuttj'[1,`k']=`eGuttj'[1,`k']+`eGuttjk'[`j',`k'] + matrix `eGuttjk0'[`k',`j']=`eGuttjk0'[`j',`k'] + matrix `eGuttj0'[1,`j']=`eGuttj0'[1,`j']+`eGuttjk0'[`j',`k'] + matrix `eGuttj0'[1,`k']=`eGuttj0'[1,`k']+`eGuttjk0'[`j',`k'] + + matrix `loevHjk'[`j',`k']=1-`eGuttjk'[`j',`k']/`eGuttjk0'[`j',`k'] + matrix `loevHjk'[`k',`j']=`loevHjk'[`j',`k'] + + } + qui count if ``j''!=. + local tmp=r(N) + qui count if ``j''==1 + matrix `P1'[1,`j']=r(N)/`tmp' + qui count if ``j''==0 + matrix `P0'[1,`j']=r(N)/`tmp' + qui su ``j'' + matrix `diff'[1,`j']=r(mean) + matrix `loevHj'[1,`j']=1-`eGuttj'[1,`j']/`eGuttj0'[1,`j'] + scalar `eGutt'=`eGutt'+`eGuttj'[1,`j']/2 + scalar `eGutt0'=`eGutt0'+`eGuttj0'[1,`j']/2 +} +scalar `H1'=0 +scalar `vH'=0 +scalar `zH'=0 +forvalues j=1/`nbitems'{ + forvalues k=1/`nbitems' { + if `j'!=`k' { + matrix `zHj'[1,`j']=`zHj'[1,`j']+`cov'[`j',`k'] + matrix `vHj'[1,`j']=`vHj'[1,`j']+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj') + } + if `j'<`k' { + scalar `zH'=`zH'+`cov'[`j',`k'] + scalar `vH'=`vH'+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj') + } + } + matrix `zHj'[1,`j']=`zHj'[1,`j']/sqrt(`vHj'[1,`j']) + matrix `pvalHj'[1,`j']=1-norm(`zHj'[1,`j']) +} +scalar `zH'=`zH'/sqrt(`vH') +scalar `pvalH'=1-norm(`zH') +scalar `loevH'=1-`eGutt'/`eGutt0' +local loevH=1-`eGutt'/`eGutt0' + +if `modamax'==1 { + local text="Easyness" + local value=1 + local col=23 +} +else { + local text="Difficulty" + local value=0 + local col=21 +} + +/*********************************************************************************************************** +AFFICHAGE DES PREMIERS RESULTATS +***********************************************************************************************************/ + + +di in green _col(35) "Observed" _col(47) "Expected" _col(93) "Number" +di in green _col(27) "Mean" _col(36) "Guttman" _col(48) "Guttman" _col(59) "Loevinger" _col(83) "H0: Hj<=0" _col(94) "of NS" +di in green "Item" _col(15) "Obs" _col(26) "Score" _col(37) "errors" _col(49) "errors" _col(61) "H coeff" _col(73) "z-stat." _col(85) "p-value" _col(96) "Hjk" +di in green "{hline 99}" +forvalues j=1/`nbitems' { + di in green "``j''" in yellow _col(15) `Obs'[`j',`j'] _col(25) %6.4f `diff'[1,`j'] _col(36) %7.0f `eGuttj'[1,`j'] _col(45) %10.2f `eGuttj0'[1,`j'] _col(61) %7.5f `loevHj'[1,`j'] _col(72) %8.4f `zHj'[1,`j'] _col(85) %7.5f `pvalHj'[1,`j'] _col(97) %2.0f `nbHjkNS`j'' +} +di in green "{hline 99}" + +if "`pairwise'"=="" { + local nb=`nbtotindnm' +} +else { + local nb=`nbobs' +} +di in green "Scale" in yellow _col(15) `nb' _col(36) %7.0f `eGutt' _col(45) %10.2f `eGutt0' _col(61) %-8.5f `loevH' _col(71) %9.4f `zH' _col(85) %7.5f `pvalH' + +if "`pair'"!="" { + di + di in green _col(45) "Observed" _col(57) "Expected" + di in green _col(`=`col'+10') "`text'" _col(46) "Guttman" _col(58) "Guttman" _col(69) "Loevinger" _col(92) "H0: Hjk<=0" + di in green "Items" _col(25) "Obs" _col(29) "P(Xj=`value',Xk=`value')" _col(47) "errors" _col(59) "errors" _col(71) "H coeff" _col(83) "z-stat." _col(95) "p-value" + di in green "{hline 101}" + forvalues j=1/`nbitems' { + forvalues k=`=`j'+1'/`nbitems' { + qui count if ``j''!=. + local obs=r(N) + di in green "``j''" _col(10) "``k''" in yellow _col(25) `Obs'[`j',`k'] _col(35) %6.4f `P`value'`value''[`j',`k'] _col(48) %5.0f `eGuttjk'[`j',`k'] _col(57) %8.2f `eGuttjk0'[`j',`k'] _col(70) %8.5f `loevHjk'[`j',`k'] _col(81) %9.4f `zHjk'[`j',`k'] _col(95) %7.5f `pvalHjk'[`j',`k'] + } + } + di in green "{hline 101}" +} + + +tempname P11g P00g item id id2 p1 monlabel + +/*********************************************************************************************************** +MONOTONICITY +***********************************************************************************************************/ + + +if "`monotonicity'"!="" { + if "`monotonicity'"=="*" { + anaoption + } + else { + anaoption,`monotonicity' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + + tempname score + qui genscore `varlist',score(`score') + di + di in green _col(10) "Summary per item for check of monotonicity" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + tempname restscore`i' + qui gen `restscore`i''=`score'-``i'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroup`i' + qui gengroup `restscore`i'',newvariable(`restgroup`i'') minsize(`minsize') + local list`i'=r(list) + qui su `restgroup`i'' + local nbgroups`i'=r(max) + forvalues j=0/`nbgroups`i'' { + qui count if `restgroup`i''==`j' + local rgroup`j'=r(N) + } + local vi`i'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + } + forvalues l=1/`m`i'' { + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + local nbzvi`i'_`l'=0 + forvalues j=1/`nbgroups`i'' { + qui count if `restgroup`i''==`j'&``i''>=`l' + local nbitem`i'rgroup`j'_`l'=r(N) + forvalues k=1/`=`j'-1' { + local diff=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + if `nbitem`i'rgroup`j'_`l''!=`rgroup`j''&`nbitem`i'rgroup`k'_`l''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + } + local p=(`nbitem`i'rgroup`k'_`l''+`nbitem`i'rgroup`j'_`l'')/(`rgroup`j''+`rgroup`k'') + local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + } + if `j'==`nbgroups`i'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + } + di in green "{dup 97:-}" + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + *set trace on + if `vi`i''!=0 { + if "`pro'"=="" { + local graph1 "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + local graph1 + } + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "`graph1'" + } + else { + if "`pro'"=="" { + local graph1 "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + local graph1 + } + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "`graph1'" + } + if "`details'"!=""&`i'!=`nbitems' { + di in green "{dup 97:-}" + } + if "`pro'"!=""&"`filesave'"!="" { + qui traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i'') filesave dirsave(`dirsave') + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" +} + + +/*********************************************************************************************************** +PPP et PMM MATRICES +***********************************************************************************************************/ + + +if "`ppp'"!=""|"pmm"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + local list + local listi + local listm + local listv + forvalues i=1/`nbitems' { + forvalues l=1/`m`i'' { + tempname item`i'_`l' + qui gen `item`i'_`l''=``i''>=`l' if ``i''!=. + local list `list' ``i''_`l' + local listi `listi' ``i'' + local listm `listm' `l' + local listv `listv' `item`i'_`l'' + } + } + tempname matppp matpmm + matrix `matppp'=J(`=`scoremax'',`=`scoremax'+2',0) + matrix `matpmm'=J(`=`scoremax'',`=`scoremax'+2',0) + local row=1 + forvalues i=1/`nbitems' { + forvalues k=1/`m`i'' { + local col=1 + forvalues j=1/`nbitems' { + forvalues l=1/`m`j'' { + if `i'!=`j' { + qui count if `item`i'_`k''!=.&`item`j'_`l''!=. + local denom=r(N) + qui count if `item`i'_`k''==1&`item`j'_`l''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0&`item`j'_`l''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + } + else { + matrix `matppp'[`row',`col']=-1 + matrix `matpmm'[`row',`col']=-1 + } + local col=`col'+1 + } + } + qui count if `item`i'_`k''!=. + local denom=r(N) + qui count if `item`i'_`k''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + matrix `matppp'[`row',`=`scoremax'+2']=`i' + matrix `matpmm'[`row',`=`scoremax'+2']=`i' + local row=`row'+1 + } + } + matrix colnames `matppp'=`list' p1 item + matrix rownames `matppp'=`list' + matrix colnames `matpmm'=`list' p1 item + matrix rownames `matpmm'=`list' + if "`nipmatrix'"!="" { + if "`nipmatrix'"=="*" { + anaoption + } + else { + anaoption,`nipmatrix' + } + local minvi=`r(minvi)' + local siglevel=`r(siglevel)' + local minsize=`r(minsize)' + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + forvalues i=1/`nbitems' { + local nbacpp`i'=0 + local nbvipp`i'=0 + local maxvipp`i'=0 + local sumvipp`i'=0 + local zmaxpp`i'=0 + local nbsigzpp`i'=0 + local nbacmm`i'=0 + local nbvimm`i'=0 + local maxvimm`i'=0 + local sumvimm`i'=0 + local zmaxmm`i'=0 + local nbsigzmm`i'=0 + } + } + +} +tempfile temporaryfile +qui save `temporaryfile' + +if "`ppp'"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + drop * + qui svmat `matppp',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + sort p1 + qui set obs `=`scoremax'+1' + local listitem + forvalues i=1/`scoremax' { + local t=item[`i'] + local listitem `listitem' `t' + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + + if "`graph'"!="" { + if "`filesave'"=="" { + qui local saving + } + else { + qui local saving saving(`dirsave'//ppp,replace) + } + if `scoremax'<20&"`ppp'"!="" { + qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P++ diagnostics") name(ppp,replace) `saving' + } + } + + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matpp + matrix define `matpp'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local ti:word `i' of `listv' + local tj:word `j' of `listv' + local t:word `j' of `list2' + matrix `matpp'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matpp'=`list2' + matrix rownames `matpp'=`list2' + + if "`ppp'"!="" { + di + di in green _col(10) "P++ values per items pair (The values should be increasing in each column)" + matrix list `matpp',format(%5.3f) nohalf noheader + } + + label drop `monlabel' + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacpp`ti' + *local ++nbacmm`tk' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==1&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==1&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "++ `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzpp`tj' + if abs(`z')>`zmaxpp`tj'' { + local zmaxpp`tj'=abs(`z') + } + local ++nbsigzpp`tk' + if abs(`z')>`zmaxpp`tk'' { + local zmaxpp`tk'=abs(`z') + } + } + } + } + } + } + } + } +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + drop _all + qui svmat `matpmm',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + gsort -p1 + qui set obs `=`scoremax'+1' + forvalues i=1/`scoremax' { + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + if "`filesave'"=="" { + qui local saving + } + else { + qui local saving saving(`dirsave'//pmm,replace) + } + if `scoremax'<20 { + qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) `saving' + } + } + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matmm + matrix define `matmm'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local t:word `j' of `list2' + matrix `matmm'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matmm'=`list2' + matrix rownames `matmm'=`list2' + if "`pmm'"!="" { + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + matrix list `matmm',format(%5.3f) nohalf noheader + } + label drop `monlabel' + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacmm`ti' + *local ++nbacmm`tk' + local diff=`matmm'[`k',`i']-`matmm'[`j',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvimm`tj' + local ++nbvimm`tk' + local sumvimm`tj'=`sumvimm`tj''+`diff' + local sumvimm`tk'=`sumvimm`tk''+`diff' + if `diff'>`maxvimm`tj'' { + local maxvimm`tj'=`diff' + } + if `diff'>`maxvimm`tk'' { + local maxvimm`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==0&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==0&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "-- `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzmm`tj' + if abs(`z')>`zmaxmm`tj'' { + local zmaxmm`tj'=abs(`z') + } + local ++nbsigzmm`tk' + if abs(`z')>`zmaxmm`tk'' { + local zmaxmm`tk'=abs(`z') + } + } + } + } + } + } + } + } +} +if `scoremax'>19&("`ppp'"!=""|"`pmm'"!="")&"`graph'"!="" { + di + di "Due to the total number of possibles scores (`=`scoremax'+1'), the P++ and P-- graphical representations cannot be displayed" +} + +/*********************************************************************************************************** +NIPMATRIX +***********************************************************************************************************/ + + +if "`nipmatrix'" !="" { + di + di in green _col(10) "Summary per item for check of non-Intersection via Pmatrix" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) /*in green "Minsize=" in ye %5.0f `minsize' _col(40)*/ in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + forvalues i=1/`nbitems' { + local nbac`i'=`nbacpp`i''+`nbacmm`i'' + local nbvi`i'=`nbvipp`i''+`nbvimm`i'' + local maxvi`i'=max(`maxvipp`i'',`maxvimm`i'') + local sumvi`i'=`sumvipp`i''+`sumvimm`i'' + local zmaxvi`i'=max(`zmaxpp`i'',`zmaxmm`i'') + + local nbzsig`i'=`nbsigzpp`i''+`nbsigzmm`i'' + local zmax`i'=0 + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmaxvi`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' + + if `nbvi`i''!=0 { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(33) %6.4f `=`nbvi`i''/`nbac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`nbac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzsig`i'' _col(93) %4.0f `crit`i'' + } + else { + di in green "" "``i''" "" %8.0f `nbac`i'' "" %8.0f `nbvi`i'' "" %6.4f `=`nbvi`i''/`nbac`i''' "" %6.4f `maxvi`i'' "" %6.4f `sumvi`i'' "" %6.4f `=`sumvi`i''/`nbac`i''' "" %6.4f `zmaxvi`i'' "" %8.0f `nbzsig`i'' "" %4.0f `crit`i'' "" + } + } + else { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(93) %4.0f `crit`i'' + } + } +} + + +qui use "`loevHfile'",clear + + +/*********************************************************************************************************** +GENERATION DE NOUVELLES VARIABLES +***********************************************************************************************************/ + + +if "`generror'"!="" { + if "`replace'"!="" { + capture drop `generror'_0 + capture drop `generror'_H + capture drop `generror'_max + capture drop `generror'_GPN + capture drop `generror' + } + qui gen `generror'=0 + forvalues i=1/`nbitems' { + capture drop `generror'_``i'' + qui gen `generror'_``i''=0 + } + qui gen `generror'_0=`eGutt0'/`nb' + local nbsteps:word count `listitem' + if "`pairwise'"=="" { + forvalues i=1/`nbitems' { + qui replace `generror'=. if ``i''==. + qui replace `generror'_0=. if ``i''==. + } + } + forvalues i=0/`nbsteps' { + *di "qui guttmax `listitem', score(`i')" + qui guttmax `listitem', score(`i') + local errmax`i'=r(maxegutt) + } + forvalues i=1/`nbsteps' { + forvalues j=`=`i'+1'/`nbsteps' { + local w2i:word `i' of `listw2' + local w2j:word `j' of `listw2' + local itemi:word `w2i' of `listi' + local modai:word `w2i' of `listm' + local itemj:word `w2j' of `listi' + local modaj:word `w2j' of `listm' + qui replace `generror'=`generror'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + qui replace `generror'_`itemi'=`generror'_`itemi'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + qui replace `generror'_`itemj'=`generror'_`itemj'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + } + } + tempvar flag + qui gen `flag'=0 + qui replace `flag'=1 `if' + qui replace `generror'=. if `flag'==0 + qui replace `generror'_0=. if `flag'==0 + qui gen `generror'_H=1-`generror'/`generror'_0 + tempvar score + qui genscore `varlist' `if',score(`score') + qui gen `generror'_max=. + forvalues i=1/`nbsteps' { + qui replace `generror'_max=`errmax`i'' if `score'==`i' + } + qui gen `generror'_GPN=`generror'/`generror'_max + label variable `generror' "Number of Guttman errors per individual" + label variable `generror'_H "H indice per individual" + if "`graph'"!="" { + if "`filesave'"=="" { + local saving1 + local saving2 + local saving3 + } + else { + local saving1 saving(`dirsave'//`generror', replace) + local saving2 saving(`dirsave'//`generror'_H, replace) + local saving3 saving(`dirsave'//`generror'_box, replace) + } + qui histogram `generror',discrete freq name(errors,replace) `saving1' + qui graph box `generror',name(errors_box,replace) `saving3' + qui histogram `generror'_H,discrete freq name(H,replace) `saving2' + } + qui su `generror' ,det + local meane=r(mean) + local mede=r(p50) + local mine=r(min) + local maxe=r(max) + qui su `generror'_GPN ,det + local meanGPN=r(mean) + local medGPN=r(p50) + local minGPN=r(min) + local maxGPN=r(max) + di + di in green "Number of Guttman errors by individual" _col(50) in green "Normalized number of Guttamn errors by individual" + di in green " Mean number: " in ye %7.2f `meane' _col(50) in green " Mean number: " in ye %7.2f `meanGPN' + di in green " Median number: " in ye %7.2f `mede' _col(50) in green " Median number: " in ye %7.2f `medGPN' + di in green " Minimal number: " in ye %7.2f `mine' _col(50) in green " Minimal number: " in ye %7.2f `minGPN' + di in green " Maximal number: " in ye %7.2f `maxe' _col(50) in green " Maximal number: " in ye %7.2f `maxGPN' + di in green "Expected Guttman errors: " in ye %7.2f `=`eGutt0'/`nb'' + qui count if `generror'_H<0 + di in green " Rate of Hn<0: " in ye %7.2f `=r(N)/`nb'*100' "%" + +} + +matrix colnames `loevHj'=`varlist' +matrix rownames `loevHj'=Hj +return matrix loevHj `loevHj' + +matrix colnames `loevHjk'=`varlist' +matrix rownames `loevHjk'=`varlist' +return matrix loevHjk `loevHjk' + +matrix colnames `eGuttj'=`varlist' +matrix rownames `eGuttj'=ej +return matrix eGuttj `eGuttj' + +matrix colnames `eGuttjk'=`varlist' +matrix rownames `eGuttjk'=`varlist' +return matrix eGuttjk `eGuttjk' + +matrix colnames `eGuttj0'=`varlist' +matrix rownames `eGuttj0'=ejk +return matrix eGuttj0 `eGuttj0' + +matrix colnames `eGuttjk0'=`varlist' +matrix rownames `eGuttjk0'=`varlist' +return matrix eGuttjk0 `eGuttjk0' + +return scalar loevH=`loevH' +return scalar eGutt =`eGutt' +return scalar eGutt0 =`eGutt0' + +if `modamax'==1 { + matrix colnames `P11'=`varlist' + matrix rownames `P11'=`varlist' + return matrix P11 `P11' +} + +matrix colnames `P00'=`varlist' +matrix rownames `P00'=`varlist' +return matrix P00 `P00' + +if "`ppp'"!=""|"`nipmatrix'"!="" { + return matrix ppp=`matpp' +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + return matrix pmm=`matmm' +} + +matrix colnames `zHj'=`varlist' +matrix rownames `zHj'=zHj +return matrix zHj `zHj' + +matrix colnames `pvalHj'=`varlist' +matrix rownames `pvalHj'=pval +return matrix pvalHj `pvalHj' + +return scalar zH=`zH' +return scalar pvalH=`pvalH' +if "`pair'"!="" { + matrix colnames `zHjk'=`varlist' + matrix rownames `zHjk'=`varlist' + return matrix zHjk `zHjk' + + matrix colnames `pvalHjk'=`varlist' + matrix rownames `pvalHjk'=`varlist' + return matrix pvalHjk `pvalHjk' +} + +matrix colnames `Obs'=`varlist' +matrix rownames `Obs'=`varlist' +return matrix Obs `Obs' + +capture restore, not + +end + diff --git a/Modules/ado/personal/l/loevh.hlp b/Modules/ado/personal/l/loevh.hlp new file mode 100644 index 0000000..3dec6e7 --- /dev/null +++ b/Modules/ado/personal/l/loevh.hlp @@ -0,0 +1,103 @@ +{smcl} +{* 8december2010}{...} +{hline} +help for {hi:loevh}{right:Jean-Benoit Hardouin} +{hline} + +{title:Loevinger's H coefficients and non parametric Item Responses Models} + +{p 8 14 2}{cmd:loevh} {it:varlist} [{cmd:,} {cmdab:pairw:ise} {cmdab:pair} {cmdab:ppp} {cmdab:pmm} {cmdab:noadj:ust} {cmdab:gener:ror}({it:newvar}) {cmdab:rep:lace} {cmdab:gr:aph} {cmdab:mono:tonicity}({it:string}) {cmdab:nip:matrix}({it:string})] + +{p 8 14 2}{it:varlist} is a list of two or more existing dichotomous ou polytomous variables. + +{title:Description} + +{p 4 8 2}{cmd:loevh} allows verifying the fit of data to the Monotonely Homogeneous Mokken Model or to the Doubly Monotone Mokken Model. +It computes the Loevinger H scalability coefficients, and several indexes in the field of the Non parametric Item Response Theory. + +{title:Options} + +{p 4 8 2}{cmd:pairwise}. By default, all the individuals with one or more missing values are omitted. {cmd:pairwise} allows to use the complete information by pair of items. + +{p 4 8 2}{cmd:pair} displays statistics and the value of the Loevinger H coefficient for each pair of items. + +{p 4 8 2}{cmd:ppp} displays the P++ matrix. + +{p 4 8 2}{cmd:pmm} displays the P-- matrix. + +{p 4 8 2}{cmd:noadjust} approximates the tests statistics like the MSP software (Molenaar et al. (2000)). + +{p 4 8 2}{cmd:generror} creates a new variable containing the number of Guttman errors produced by each individual. + +{p 4 8 2}{cmd:replace} allows replacing the variable defined by the {cmd:generror} option. + +{p 4 8 2}{cmd:graph} displays graphs (only with the {cmd:ppp}, {cmd:pmm} and {cmd:generror} options). + +{p 4 8 2}{cmd:monotonicity} displays indexes in order to check the monotonicity of the data (Monotone Homogeneity Mokken Model). This option produces outputs similar to the MSP software. +The string contains several suboptions: {cmd:minvi}, {cmd:minsize}, {cmd:siglevel} and {cmd:details}. If you want use all the default values, type *.{p_end} +{p 10 12 10}{cmd:minvi} defines the minimal size of a violation of monotonicity (0.03 by default){p_end} +{p 10 12 10}{cmd:minsize} defines the minimum size of groups of patients to check the monotonicity (by default, the number of individuals divided by 10 with more than 500 individuals, the same number divided by 5 with more than 250 individuals, and the same number divided by 3 for a smaller number, with a minimum of 50){p_end} +{p 10 12 10}{cmd:siglevel} defines the significance level for the tests (0.05 by default){p_end} +{p 10 12 10}{cmd:details} displays more details with polytomous items + +{p 4 8 2}{cmd:nipmatrix} display indexes in order to check the non-intersection (Doubly Monotone Mokken Model). This option produces outputs similar to the MSP software. +The string contains several suboptions: {cmd:minvi} and {cmd:siglevel}. If you want use all the default values, type *.{p_end} +{p 10 12 10}{cmd:minvi} defines the minimal size of a violation of non-intersection (0.03 by default){p_end} +{p 10 12 10}{cmd:siglevel} defines the significance level for the tests (0.05 by default){p_end} + + +{title:Remarks} + +{p 4 8 2}For detailed informations on the Loevinger's H coefficients, see Loevinger (1948) or Hemker and al. (1995). For details about the analysis of non parametric Mokken models, see for example the MSP 5.0 manual. + + +{title:Example} + + {p 8 8}{inp:. loevh itemA1-itemA7} + + {p 8 8}{inp:. loevh itemA*, pair monotonicity(*) ppp pmm nipmatrix(minvi(0.05) siglevel(0.01))} + + {p 8 8}{inp:. loevh item*, pairwise generror(error) graph} + +{title:Results} + +{p 4 8 2}The Loevinger's H coefficients between all the pairs of items, for each item with respect of all the others items and for the set of items are respectively saved in the matrices {it:r(loevHjk)}, {it:r(loevHj)} +and in the scalar {it:r(loevh)}. + +{p 4 8 2}The empirical Guttman errors between all the pairs of items, associated to each item and relied to the scale are respectively saved in the matrices {it:r(eGuttjk)}, {it:r(eGuttj)} and in the scalar {it:e(Gutt)}. + +{p 4 8 2}The theorical Guttman errors between all the pairs of items, associated to each item and relied to the scale are respectively saved in the matrices {it:r(eGuttjk0)}, {it:r(eGuttj0)} and in the scalar {it:e(Gutt0)}. + +{p 4 8 2}The values of the Z statistics and the corresponding p-values associated to the Loevinger H coefficients are respectively saved in the matrices {it:r(zHjk)}, {it:r(pvalHjk)}, {it:r(zHj)}, {it:r(pvalHj)} +and in the scalars {it:e(zH)} and {it:r(pvalH)}. + +{p 4 8 2}The P++ and P-- matrices are saved in {it:r(ppp)} and {it:r(pmm)}. + +{p 4 8 2}The used number of individuals per items pair is saved in {it:r(Obs)}. + + +{title:References} + +{p 4 8 2}Hemker B. T., Sijtsma K. and Molenaar I. W., Selection of unidimensional scales from a multidimensional item bank in the polytomous Mokken IRT +model, {it: Applied Psychological Measurement}, vol.19(4), 1995, pp. 337-352. + +{p 4 8 2}Loevinger J., The technique of homogeneous tests compared with some aspects of "scale analysis" and factor analysis. {it:Psychological bulletin}, +vol. 45, 1948, pp. 507-530. + +{p 4 8 2}Molenaar I. W., Sijtsma K. and Boer P. {it:MSP5 for Windows - User's Manual}, 2000, 105 pages. + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end} +{p 4 8 2}EA 4275 "Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences"{p_end} +{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end} +{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end} +{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end} +{p 4 8 2}Email: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol} +and {browse "http://www.freeirt.org":FreeIRT} + +{title:Also see} + +{p 4 13 2}Online: help for {help traces}, {help msp}, {help gengroup}, {help mokken} if installed.{p_end} diff --git a/Modules/ado/personal/l/loevh8-1-3.ado b/Modules/ado/personal/l/loevh8-1-3.ado new file mode 100644 index 0000000..00a2a00 --- /dev/null +++ b/Modules/ado/personal/l/loevh8-1-3.ado @@ -0,0 +1,1393 @@ +*! Version 8.1.5 23 March 2015 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : loevh +* Loevinger H indexes, Mokken Analysis +* Release 8.1.3 : March 23, 2015 /*minor correction for displaying results*/ +* +* +* Historic : +* Version 1 (August 20, 2002) [Jean-Benoit Hardouin] +* Version 2 (June 22, 2003) [Jean-Benoit Hardouin] +* Version 3 (December 1, 2003) [Jean-Benoit Hardouin] +* Version 4 (January 20, 2004) [Jean-Benoit Hardouin] +* Version 5 (March 22, 2004) [Jean-Benoit Hardouin] +* Version 6 (July 3, 2004) [Jean-Benoit Hardouin] +* Version 6.1 (September 19, 2005) [Jean-Benoit Hardouin] +* Version 6.2 (January 31, 2006) [Jean-Benoit Hardouin] +* Release 6.3 (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */ +* Release 6.4 (January 19, 2007) [Jean-Benoit Hardouin] /*Tests to compare Loevinger coefficients to 0 identical to the MSP software (dichotomous and polytomous case)*/ +* Release 6.5 (January 22, 2007) [Jean-Benoit Hardouin] /*Correction of a bug concerning the p-values with the pair option*/ +* Release 6.6 (Februar 16, 2007) [Jean-Benoit Hardouin] /*Correction of a bug with the displaying of Easyness with polytomous items, option graph, option generror, improvements*/ +* Release 7: June 21, 2007 /*Check of monotonicity and Non intersection via P matrices*/ +* Release 7.1: November 6, 2008 /*Correction for the z-tests for the check of non intersection via P matrices*/ +* Release 7.2: November 19, 2008 /*Implementation of the GPN indexes*/ +* Release 7.3: August 15, 2009 /*Print the difficulties of the items instead of P(X=0)*/ +* Release 8: December 8, 2010 /*loevH is renamed loevh*/ +* Release 8.1: October 19, 2012 /*html option*/ +* Release 8.1.1 : November 20, 2012 /*graphs with the html option*/ +* Release 8.1.2 : December 7, 2012 /*minor correction*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* Requiered Stata modules: +* -anaoption- (version 1) +* -traces- (version 3.2) +* -gengroup- (version 1) +* -guttmax- (version 1) +* +* News about this program :http://www.anaqol.org +* +* Copyright 2002-2015 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** + +program define loevh , rclass +version 8.2 +syntax varlist(min=2 numeric) [if] [,PAIRWise PAIR ppp pmm noADJust GENERror(string) REPlace GRaph MONOtonicity(string) NIRESTscore(string) NIPmatrix(string) HTML(string)] +preserve + +if "`html'" != "" { + set scheme sj + local htmlregion "graphregion(fcolor(white) ifcolor(white))" + di in gr "" +} + +local nbitems : word count `varlist' +tokenize `varlist' +tempname corr cov P1 P0 diff P11 P00 H1jk vHjk zHjk chi2Hjk dfHjk pvalHjk H1j vHj zHj pvalHj H1 vH zH pvalH Obs eGuttjk eGuttjk0 loevHjk eGuttj eGuttj0 loevHj eGutt eGutt0 loevH e1 e2 +tempfile loevHfile +qui save "`loevHfile'" + +if "`if'"!="" { + qui keep `if' +} + +if "`adjust'"!="" { + local adj=0 +} +else { + local adj=1 +} + +qui count +local nbobs=r(N) + +forvalues j=1/`nbitems' { + if "`pairwise'"=="" { + qui drop if ``j''==. + } +} +qui count +local nbtotindnm=r(N) + +matrix define `eGuttjk'=J(`nbitems',`nbitems',0) +matrix define `eGuttjk0'=J(`nbitems',`nbitems',0) +matrix define `loevHjk'=J(`nbitems',`nbitems',0) +matrix define `eGuttj'=J(1,`nbitems',0) +matrix define `eGuttj0'=J(1,`nbitems',0) +matrix define `loevHj'=J(1,`nbitems',0) +scalar define `eGutt'=0 +scalar define `eGutt0'=0 +scalar define `loevH'=0 +matrix define `Obs'=J(`nbitems',`nbitems',0) +matrix define `P00'=J(`nbitems',`nbitems',0) + +tempname modamax +scalar `modamax'=0 +local scoremax=0 +forvalues j=1/`nbitems' { + qui su ``j'' + local m`j'=r(max) + local scoremax=`scoremax'+`m`j'' + if r(max)>`modamax' { + scalar `modamax'=r(max) + } + local nbHjkNS`j'=0 +} + +/*if "`generror'"!=""&`modamax'!=1 { + di in ye "It is not possible to define the {cmd:generror} option with polytomous items" + local generror +} */ +*di "scoremax `scoremax'" +if "`graph'"!=""&`scoremax'>19 { + di in ye "The {cmd:graph} option is disabled because of a large number of possible scores (>20)" + local graph +} + +matrix define `cov'=J(`nbitems',`nbitems',0) +matrix define `corr'=J(`nbitems',`nbitems',0) +matrix define `P11'=J(`nbitems',`nbitems',0) +matrix define `H1jk'=J(`nbitems',`nbitems',0) +matrix define `vHjk'=J(`nbitems',`nbitems',0) +matrix define `zHjk'=J(`nbitems',`nbitems',0) +matrix define `pvalHjk'=J(`nbitems',`nbitems',0) +matrix define `P1'=J(1,`nbitems',0) +matrix define `P0'=J(1,`nbitems',0) +matrix define `diff'=J(1,`nbitems',0) +matrix define `H1j'=J(1,`nbitems',0) +matrix define `vHj'=J(1,`nbitems',0) +matrix define `zHj'=J(1,`nbitems',0) +matrix define `pvalHj'=J(1,`nbitems',0) + +forvalues j=1/`nbitems' { + qui su ``j'' + matrix `cov'[`j',`j']=r(Var) + matrix `corr'[`j',`j']=1 + local tmp=`j'+1 + qui count if ``j''!=. + matrix `Obs'[`j',`j']=r(N) + forvalues k=`tmp'/`nbitems' { + qui count if ``j''!=.&``k''!=. + matrix `Obs'[`j',`k']=r(N) + matrix `Obs'[`k',`j']=r(N) + qui corr ``j'' ``k'',cov + matrix `cov'[`j',`k']=r(cov_12) + matrix `cov'[`k',`j']=r(cov_12) + qui corr ``j'' ``k'' + matrix `corr'[`j',`k']=r(rho) + matrix `corr'[`k',`j']=r(rho) + matrix `zHjk'[`j',`k']=`corr'[`j',`k']*(`Obs'[`j',`k']-`adj')^.5 + matrix `zHjk'[`k',`j']=`H1jk'[`j',`k'] + matrix `pvalHjk'[`j',`k']=1-norm(`zHjk'[`j',`k']) + matrix `pvalHjk'[`k',`j']=`pvalHjk'[`j',`k'] + if `pvalHjk'[`j',`k']>0.05 { + local nbHjkNS`j'=`nbHjkNS`j''+1 + local nbHjkNS`k'=`nbHjkNS`k''+1 + } + forvalues mod1=1/`m`j'' { + forvalues mod2=1/`m`k'' { + qui count if ``j''<`mod1'&``k''>=`mod2'&``j''!=.&``k''!=. + scalar `e1'=r(N) + qui count if ``j''>=`mod1'&``k''<`mod2'&``j''!=.&``k''!=. + scalar `e2'=r(N) + matrix `eGuttjk'[`j',`k']=`eGuttjk'[`j',`k']+min(`e1',`e2') + qui count if ``j''<`mod1'&``j''!=.&``k''!=. + local t1=r(N) + qui count if ``k''<`mod2'&``j''!=.&``k''!=. + local t2=r(N) + qui count if ``j''>=`mod1'&``j''!=.&``k''!=. + local t3=r(N) + qui count if ``k''>=`mod2'&``j''!=.&``k''!=. + local t4=r(N) + if min(`e1',`e2')==`e1' { + matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t1'*`t4'/`Obs'[`j',`k'] + } + else { + matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t2'*`t3'/`Obs'[`j',`k'] + } + + } + } + qui count if ``j''==0&``k''==0 + matrix `P00'[`j',`k']=r(N)/`Obs'[`j',`k'] + matrix `P00'[`k',`j']=r(N)/`Obs'[`k',`j'] + if `modamax'==1 { + qui count if ``j''==1&``k''==1 + matrix `P11'[`j',`k']=r(N)/`Obs'[`j',`k'] + matrix `P11'[`k',`j']=r(N)/`Obs'[`k',`j'] + } + + matrix `eGuttjk'[`k',`j']=`eGuttjk'[`j',`k'] + matrix `eGuttj'[1,`j']=`eGuttj'[1,`j']+`eGuttjk'[`j',`k'] + matrix `eGuttj'[1,`k']=`eGuttj'[1,`k']+`eGuttjk'[`j',`k'] + matrix `eGuttjk0'[`k',`j']=`eGuttjk0'[`j',`k'] + matrix `eGuttj0'[1,`j']=`eGuttj0'[1,`j']+`eGuttjk0'[`j',`k'] + matrix `eGuttj0'[1,`k']=`eGuttj0'[1,`k']+`eGuttjk0'[`j',`k'] + + matrix `loevHjk'[`j',`k']=1-`eGuttjk'[`j',`k']/`eGuttjk0'[`j',`k'] + matrix `loevHjk'[`k',`j']=`loevHjk'[`j',`k'] + + } + qui count if ``j''!=. + local tmp=r(N) + qui count if ``j''==1 + matrix `P1'[1,`j']=r(N)/`tmp' + qui count if ``j''==0 + matrix `P0'[1,`j']=r(N)/`tmp' + qui su ``j'' + matrix `diff'[1,`j']=r(mean) + matrix `loevHj'[1,`j']=1-`eGuttj'[1,`j']/`eGuttj0'[1,`j'] + scalar `eGutt'=`eGutt'+`eGuttj'[1,`j']/2 + scalar `eGutt0'=`eGutt0'+`eGuttj0'[1,`j']/2 +} +scalar `H1'=0 +scalar `vH'=0 +scalar `zH'=0 +forvalues j=1/`nbitems'{ + forvalues k=1/`nbitems' { + if `j'!=`k' { + matrix `zHj'[1,`j']=`zHj'[1,`j']+`cov'[`j',`k'] + matrix `vHj'[1,`j']=`vHj'[1,`j']+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj') + } + if `j'<`k' { + scalar `zH'=`zH'+`cov'[`j',`k'] + scalar `vH'=`vH'+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj') + } + } + matrix `zHj'[1,`j']=`zHj'[1,`j']/sqrt(`vHj'[1,`j']) + matrix `pvalHj'[1,`j']=1-norm(`zHj'[1,`j']) +} +scalar `zH'=`zH'/sqrt(`vH') +scalar `pvalH'=1-norm(`zH') +scalar `loevH'=1-`eGutt'/`eGutt0' +local loevH=1-`eGutt'/`eGutt0' + +if `modamax'==1 { + local text="Easyness" + local value=1 + local col=23 +} +else { + local text="Difficulty" + local value=0 + local col=21 +} + +if "`html'" == "" { + di in green _col(35) "Observed" _col(47) "Expected" _col(93) "Number" + di in green _col(27) "Mean" _col(36) "Guttman" _col(48) "Guttman" _col(59) "Loevinger" _col(83) "H0: Hj<=0" _col(94) "of NS" + di in green "Item" _col(15) "Obs" _col(26) "Score" _col(37) "errors" _col(49) "errors" _col(61) "H coeff" _col(73) "z-stat." _col(85) "p-value" _col(96) "Hjk" + di in green "{hline 99}" + forvalues j=1/`nbitems' { + di in green "``j''" in yellow _col(15) `Obs'[`j',`j'] _col(25) %6.4f `diff'[1,`j'] _col(36) %7.0f `eGuttj'[1,`j'] _col(45) %10.2f `eGuttj0'[1,`j'] _col(61) %7.5f `loevHj'[1,`j'] _col(72) %8.4f `zHj'[1,`j'] _col(85) %7.5f `pvalHj'[1,`j'] _col(97) %2.0f `nbHjkNS`j'' + } + di in green "{hline 99}" +} +else { + di in gr "" + di in gr "" + di in gr "" + di in gr "" + di in gr "" + forvalues j=1/`nbitems' { + di in green "" + } +} + +if "`pairwise'"=="" { + local nb=`nbtotindnm' +} +else { + local nb=`nbobs' +} +if "`html'" == "" { + di in green "Scale" in yellow _col(15) `nb' _col(36) %7.0f `eGutt' _col(45) %10.2f `eGutt0' _col(61) %-8.5f `loevH' _col(71) %9.4f `zH' _col(85) %7.5f `pvalH' +} +else { + di in green "" + di in gr "
ItemObsMean
Score
Observed
Guttman
Errors
Expected
Guttman
Errors
Loevinger
H coeff
z-stat.H0: Hj ≤ 0
p-value
Number of
NS Hjk
``j''" `Obs'[`j',`j'] "" %6.4f `diff'[1,`j'] "" %5.0f `eGuttj'[1,`j'] "" %8.2f `eGuttj0'[1,`j'] "" %7.5f `loevHj'[1,`j'] "" %8.4f `zHj'[1,`j'] "" %7.5f `pvalHj'[1,`j'] "" %2.0f `nbHjkNS`j'' "
Scale" `nb' "" %5.0f `eGutt' "" %8.2f `eGutt0' "" %-8.5f `loevH' "" %9.4f `zH' "" %7.5f `pvalH' "
" +} + +if "`pair'"!="" { + if "`html'" == "" { + di + di in green _col(45) "Observed" _col(57) "Expected" + di in green _col(`=`col'+10') "`text'" _col(46) "Guttman" _col(58) "Guttman" _col(69) "Loevinger" _col(92) "H0: Hjk<=0" + di in green "Items" _col(25) "Obs" _col(29) "P(Xj=`value',Xk=`value')" _col(47) "errors" _col(59) "errors" _col(71) "H coeff" _col(83) "z-stat." _col(95) "p-value" + di in green "{hline 101}" + forvalues j=1/`nbitems' { + forvalues k=`=`j'+1'/`nbitems' { + qui count if ``j''!=. + local obs=r(N) + di in green "``j''" _col(10) "``k''" in yellow _col(25) `Obs'[`j',`k'] _col(35) %6.4f `P`value'`value''[`j',`k'] _col(48) %5.0f `eGuttjk'[`j',`k'] _col(57) %8.2f `eGuttjk0'[`j',`k'] _col(70) %8.5f `loevHjk'[`j',`k'] _col(81) %9.4f `zHjk'[`j',`k'] _col(95) %7.5f `pvalHjk'[`j',`k'] + } + } + di in green "{hline 101}" + } + else { + di in gr "" + di in gr "" + di in green "" + di in gr "" + forvalues j=1/`nbitems' { + forvalues k=`=`j'+1'/`nbitems' { + qui count if ``j''!=. + local obs=r(N) + di in green "" + } + } + di in green "
Summary of results by items pairs
Items" "`text'" "
Obs P(Xj=`value',Xk=`value')
Observed
Guttman
Errors
Expected
Guttman
Errors
Loevinger
H coeff
z-stat.H0: Hjk ≤ 0
p-value
" "``j''" "" "``k''" "" `Obs'[`j',`k'] "" %6.4f `P`value'`value''[`j',`k'] "" %5.0f `eGuttjk'[`j',`k'] "" %8.2f `eGuttjk0'[`j',`k'] "" %8.5f `loevHjk'[`j',`k'] "" %9.4f `zHjk'[`j',`k'] "" %7.5f `pvalHjk'[`j',`k'] "
" + } +} + +/*if `modamax'>1&"`ppp'"!="" { + di in green "It is not possible to obtain the P++ diagnostics with polytomous items" + local ppp +} +if `modamax'>1&"`pmm'"!="" { + di in green "It is not possible to obtain the P-- diagnostics with polytomous items" + local pmm +} */ + +tempname P11g P00g item id id2 p1 monlabel + +/*if "`monotonicity'"!=""&`modamax'>1 { + if "`html'" == "" { + di in green "It is not possible to obtain the latent monotonicity diagnostics with polytomous items" + } + else { + di in green "

It is not possible to obtain the latent monotonicity diagnostics with polytomous items

" + } + local monotonicity +} */ + +if "`monotonicity'"!="" { +*set trace on + if "`monotonicity'"=="*" { + anaoption + } + else { + anaoption,`monotonicity' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + +*set trace on + tempname score + qui genscore `varlist',score(`score') + if "`html'" == "" { + di + di in green _col(10) "Summary per item for check of monotonicity" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + } + else { + di in gr "" + di in gr "" + di in gr "" + } +*set trace on + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + tempname restscore`i' + qui gen `restscore`i''=`score'-``i'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroup`i' + qui gengroup `restscore`i'',newvariable(`restgroup`i'') minsize(`minsize') + local list`i'=r(list) + qui su `restgroup`i'' + local nbgroups`i'=r(max) + forvalues j=0/`nbgroups`i'' { + qui count if `restgroup`i''==`j' + local rgroup`j'=r(N) + } + local vi`i'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + } + forvalues l=1/`m`i'' { + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + local nbzvi`i'_`l'=0 + forvalues j=1/`nbgroups`i'' { + qui count if `restgroup`i''==`j'&``i''>=`l' + local nbitem`i'rgroup`j'_`l'=r(N) + forvalues k=1/`=`j'-1' { + local diff=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + if `nbitem`i'rgroup`j'_`l''!=`rgroup`j''&`nbitem`i'rgroup`k'_`l''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + } + local p=(`nbitem`i'rgroup`k'_`l''+`nbitem`i'rgroup`j'_`l'')/(`rgroup`j''+`rgroup`k'') + *local z=`diff'/sqrt(`p'*(1-`p')*(1/`rgroup`j''+1/`rgroup`k'')) + *di "local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) " + local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) + *di "=`z'" + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + } + if `j'==`nbgroups`i'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + if "`html'" == "" { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in gr "" + } + } + else { + if "`html'" == "" { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + else { + di in gr "" + } + } + } + if "`html'" == "" { + di in green "{dup 97:-}" + } + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + *set trace on + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + if `vi`i''!=0 { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in green "" + } + } + else { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in gr "" + } + + } + if "`details'"!=""&`i'!=`nbitems' { + if "`html'" == "" { + di in green "{dup 97:-}" + } + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + if "`html'" == "" { + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" + } + else { + di in green "
Summary per item for check of monotonicity
Items#ac#vi#vi / #acmaxvisumsum / #aczmax#zsigCrit
``i''>=`l'" %8.0f `ac`i'_m`l'' "" %8.0f `vi`i'_m`l'' "" %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' "" %6.4f `maxvi`i'_m`l'' "" %6.4f `sumvi`i'_m`l'' "" %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' "" %6.4f `zmaxvi`i'_m`l'' "" %8.0f `nbzvi`i'_m`l'' "
``i''>=`l'" %8.0f `ac`i'_m`l'' "" %8.0f `vi`i'_m`l'' "
``i''" %8.0f `ac`i'' "" %8.0f `vi`i'' "" %6.4f `=`vi`i''/`ac`i''' "" %6.4f `maxvi`i'' "" %6.4f `sumvi`i'' "" %6.4f `=`sumvi`i''/`ac`i''' "" %6.4f `zmaxvi`i'' "" %8.0f `nbzvi`i'' "" %4.0f `crit`i'' "
``i''" %8.0f `ac`i'' "" %8.0f `vi`i'' "" %4.0f `crit`i'' "
Total" `ac' "" %8.0f `vi' "" %6.4f `=`vi'/`ac'' "" %6.4f `maxvi' "" %6.4f `sumvi' "" %6.4f `=`sumvi'/`ac'' "" %6.4f `zmaxvi' "" %8.0f `nbzvi' "
" + } +} +/*if "`nirestscore'"!="" { +*set trace on + if "`nirestscore'"=="*" { + anaoption + } + else { + anaoption,`nirestscore' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + +*set trace on + tempname score + qui genscore `varlist',score(`score') + di + di in green _col(10) "Summary per item for check of Non-Intersection via Rest-score" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" +*set trace on + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + local vi`i'`j'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + } + forvalues j=1/`nbitems' { + if `j'!=`i' { + tempname restscorei`i'j`j' + qui gen `restscorei`i'j`j''=`score'-``i''-``j'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroupi`i'j`j' + qui gengroup `restscorei`i'j`j'',newvariable(`restgroupi`i'j`j'') minsize(`minsize') + local listi`i'j`j'=r(list) + qui su `restgroupi`i'j`j'' + local nbgroupsi`i'j`j'=r(max) + forvalues k=0/`nbgroupsi`i'j`j'' { + qui count if `restgroupi`i'j`j''==`k' + local rgroup`k'=r(N) + } + forvalues l=1/`m`i'' { + forvalues k=1/`m`j'' { + forvalues m=1/`nbgroupsi`i'j`j'' { + qui count if `restgroupi`i'j`j''==`m'&``i''>=`l'&``j''>=`k' + local nbitemi`i'j`j'rgroup`m'_`l'_`k'=r(N) + forvalues n=1/`=`m'-1' { + local diff=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m'' + if `nbitemi`i'j`j'rgroup`m'_`l'_`k''!=`rgroup`m''&`nbitemi`i'j`j'rgroup`m'_`l'_`k''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m'' + } + local p=(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+`nbitemi`i'j`j'rgroup`m'_`l'_`k'')/(`rgroup`m''+`rgroup`n'') + local z=abs(2*(sqrt(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)*sqrt(`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)-sqrt((`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k'')*`nbitemi`i'j`j'rgroup`m'_`l'_`k''))/sqrt(`rgroup`m''+`rgroup`n''-1)) + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + if `m'==`nbgroupsi`i'j`j'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + *local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + *local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + } + } + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + } + di in green "{dup 97:-}" + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + *set trace on + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + if `vi`i''!=0 { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + if "`details'"!=""&`i'!=`nbitems' { + di in green "{dup 97:-}" + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" +} */ + +if "`ppp'"!=""|"pmm"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + local list + local listi + local listm + local listv + forvalues i=1/`nbitems' { + forvalues l=1/`m`i'' { + tempname item`i'_`l' + qui gen `item`i'_`l''=``i''>=`l' if ``i''!=. + local list `list' ``i''_`l' + local listi `listi' ``i'' + local listm `listm' `l' + local listv `listv' `item`i'_`l'' + } + } + tempname matppp matpmm + matrix `matppp'=J(`=`scoremax'',`=`scoremax'+2',0) + matrix `matpmm'=J(`=`scoremax'',`=`scoremax'+2',0) + local row=1 + forvalues i=1/`nbitems' { + forvalues k=1/`m`i'' { + local col=1 + forvalues j=1/`nbitems' { + forvalues l=1/`m`j'' { + if `i'!=`j' { + qui count if `item`i'_`k''!=.&`item`j'_`l''!=. + local denom=r(N) + qui count if `item`i'_`k''==1&`item`j'_`l''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0&`item`j'_`l''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + } + else { + matrix `matppp'[`row',`col']=-1 + matrix `matpmm'[`row',`col']=-1 + } + local col=`col'+1 + } + } + qui count if `item`i'_`k''!=. + local denom=r(N) + qui count if `item`i'_`k''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + matrix `matppp'[`row',`=`scoremax'+2']=`i' + matrix `matpmm'[`row',`=`scoremax'+2']=`i' + local row=`row'+1 + } + } + matrix colnames `matppp'=`list' p1 item + matrix rownames `matppp'=`list' + matrix colnames `matpmm'=`list' p1 item + matrix rownames `matpmm'=`list' + if "`nipmatrix'"!="" { + if "`nipmatrix'"=="*" { + anaoption + } + else { + anaoption,`nipmatrix' + } + local minvi=`r(minvi)' + local siglevel=`r(siglevel)' + local minsize=`r(minsize)' + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + forvalues i=1/`nbitems' { + local nbacpp`i'=0 + local nbvipp`i'=0 + local maxvipp`i'=0 + local sumvipp`i'=0 + local zmaxpp`i'=0 + local nbsigzpp`i'=0 + local nbacmm`i'=0 + local nbvimm`i'=0 + local maxvimm`i'=0 + local sumvimm`i'=0 + local zmaxmm`i'=0 + local nbsigzmm`i'=0 + } + } + +} +tempfile temporaryfile +qui save `temporaryfile' + +if "`ppp'"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + drop * + qui svmat `matppp',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + sort p1 + qui set obs `=`scoremax'+1' + local listitem + forvalues i=1/`scoremax' { + local t=item[`i'] + local listitem `listitem' `t' + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + + if "`graph'"!="" { + if "`html'"!="" { + qui local saving "saving(`c(tmpdir)'/`html'_ppp,replace) nodraw" + } + qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P++ diagnostics") name(ppp,replace) `saving' xsize(2) ysize(2) + if "`html'"!="" { + qui graph use `c(tmpdir)'/`html'_ppp.gph + qui graph export `c(tmpdir)'/`html'_ppp.eps, replace + } + } + + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matpp + matrix define `matpp'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local ti:word `i' of `listv' + local tj:word `j' of `listv' + local t:word `j' of `list2' + matrix `matpp'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matpp'=`list2' + matrix rownames `matpp'=`list2' + + if "`ppp'"!="" { + if "`html'" == "" { + di + di in green _col(10) "P++ values per items pair (The values should be increasing in each column)" + matrix list `matpp',format(%5.3f) nohalf noheader + } + else { + di "" + di "" + di "" + matrixlisthtml `matpp' "%5.3f" + di "
P++ values per items pair
(The values should be increasing in each column)
" + if ("`graph'" != "") { + di "" + } + } + } + + label drop `monlabel' + *set trace on + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { +*di "`listv' `listw2'" + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacpp`ti' + *local ++nbacmm`tk' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==1&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==1&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "++ `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzpp`tj' + if abs(`z')>`zmaxpp`tj'' { + local zmaxpp`tj'=abs(`z') + } + local ++nbsigzpp`tk' + if abs(`z')>`zmaxpp`tk'' { + local zmaxpp`tk'=abs(`z') + } + } + } + } + } + } + } + } +/* if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!= `tk'&`ti'!=`tk'&`ti'!=`tj' { + local ++nbacpp`ti' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minsize'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + } + } + } + } + } + } +*/ +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + drop _all + qui svmat `matpmm',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + gsort -p1 + qui set obs `=`scoremax'+1' + forvalues i=1/`scoremax' { + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + if "`html'"!="" { + qui local saving "saving(`c(tmpdir)'/`html'_pmm,replace) nodraw" + *qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) `saving' + *graph use `c(tmpdir)'/`html'_pmm.gph + *qui graph export `c(tmpdir)'/`html'_pmm.eps, replace + } + *else { + qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) `saving' + *} + if "`html'"!="" { + qui graph use `c(tmpdir)'/`html'_pmm.gph + qui graph export `c(tmpdir)'/`html'_pmm.eps, replace + } + } + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matmm + matrix define `matmm'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local t:word `j' of `list2' + matrix `matmm'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matmm'=`list2' + matrix rownames `matmm'=`list2' + if "`pmm'"!="" { + if "`html'" == "" { + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + matrix list `matmm',format(%5.3f) nohalf noheader + } + else { + di "" + di "" + di "" + matrixlisthtml `matmm' "%5.3f" + di "
P-- values per items pair
(The values should be decreasing in each column)
" + if ("`graph'" != "") { + di "" + } + } + } + label drop `monlabel' + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { +*di "`listv' `listw2'" + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacmm`ti' + *local ++nbacmm`tk' + local diff=`matmm'[`k',`i']-`matmm'[`j',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvimm`tj' + local ++nbvimm`tk' + local sumvimm`tj'=`sumvimm`tj''+`diff' + local sumvimm`tk'=`sumvimm`tk''+`diff' + if `diff'>`maxvimm`tj'' { + local maxvimm`tj'=`diff' + } + if `diff'>`maxvimm`tk'' { + local maxvimm`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==0&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==0&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "-- `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzmm`tj' + if abs(`z')>`zmaxmm`tj'' { + local zmaxmm`tj'=abs(`z') + } + local ++nbsigzmm`tk' + if abs(`z')>`zmaxmm`tk'' { + local zmaxmm`tk'=abs(`z') + } + } + } + } + } + } + } + } +} + +if "`nipmatrix'" !="" { + *set trace on + if "`html'" == "" { + di + di in green _col(10) "Summary per item for check of non-Intersection via Pmatrix" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) /*in green "Minsize=" in ye %5.0f `minsize' _col(40)*/ in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + } + else { + di in gr "" + di in gr "" + di in gr "" + di in gr "" + } + forvalues i=1/`nbitems' { + local nbac`i'=`nbacpp`i''+`nbacmm`i'' + local nbvi`i'=`nbvipp`i''+`nbvimm`i'' + local maxvi`i'=max(`maxvipp`i'',`maxvimm`i'') + local sumvi`i'=`sumvipp`i''+`sumvimm`i'' + local zmaxvi`i'=max(`zmaxpp`i'',`zmaxmm`i'') + + local nbzsig`i'=`nbsigzpp`i''+`nbsigzmm`i'' + local zmax`i'=0 + *local nbsigz`i'=0 + local t=`loevHj'[1,`i'] +* di "local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmax`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' " + local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmaxvi`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' + + *di `nbac`i'' " " `nbvi`i'' " " `sumvi`i'' + if `nbvi`i''!=0 { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(33) %6.4f `=`nbvi`i''/`nbac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`nbac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzsig`i'' _col(93) %4.0f `crit`i'' + } + else { + di in green "" + } + } + else { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(93) %4.0f `crit`i'' + } + else { + di in green "" + } + } + } + if "`html'" != "" { + di in green "
Summary per item for check of non-Intersection via Pmatrix
" + di in gr "Minvi=" in ye %5.3f `minvi' "      Alpha=" in ye %5.3f `siglevel' "
Items#ac#vi#vi / #acmaxvisumsum / #aczmax#zsigCrit
" "``i''" "" %8.0f `nbac`i'' "" %8.0f `nbvi`i'' "" %6.4f `=`nbvi`i''/`nbac`i''' "" %6.4f `maxvi`i'' "" %6.4f `sumvi`i'' "" %6.4f `=`sumvi`i''/`nbac`i''' "" %6.4f `zmaxvi`i'' "" %8.0f `nbzsig`i'' "" %4.0f `crit`i'' "
" "``i''" "" %8.0f `nbac`i'' "" %8.0f `nbvi`i'' "" %4.0f `crit`i'' "
" + } +} + +/*if "`pmm'"!="" { + drop _all + matrix `P00g'=`P00',`P1'' + matrix colnames `P00g'=`varlist' `p1' + matrix rownames `P00g'=`varlist' + qui svmat `P00g' , names(col) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + forvalues i=1/`nbitems' { + qui replace `item'="``i''" if `id'==`i' + qui replace ``i''=. if `id'==`i' + local connect "`connect' l" + label define `monlabel' `i' "``i''", add + } + sort `p1' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + twoway connected `varlist' `id2',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) + } + format `varlist' %5.3f + label variable `id' "Item" + label value `id' `monlabel' + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + list `id' `varlist' , table compress separator(`nbitems') noobs divider + label drop `monlabel' +} + + + +if "`pairwise'"=="" { + restore, not +}*/ + + +*di "listw2:`listw2'" +*di "listv:`listv'" +*di "list:`list'" +*di "listi:`listi'" +*di "listm:`listm'" +*di "listitem:`listitem'" + + +qui use "`loevHfile'",clear +*set trace on +if "`generror'"!="" { + if "`replace'"!="" { + capture drop `generror'_0 + capture drop `generror'_H + capture drop `generror'_max + capture drop `generror'_GPN + capture drop `generror' + } + qui gen `generror'=0 + forvalues i=1/`nbitems' { + qui gen `generror'_``i''=0 + } + qui gen `generror'_0=`eGutt0'/`nb' + local nbsteps:word count `listitem' + if "`pairwise'"=="" { + forvalues i=1/`nbitems' { + qui replace `generror'=. if ``i''==. + qui replace `generror'_0=. if ``i''==. + } + } + forvalues i=0/`nbsteps' { + di "qui guttmax `listitem', score(`i')" + qui guttmax `listitem', score(`i') + local errmax`i'=r(maxegutt) + } +* matrix list `P0' + forvalues i=1/`nbsteps' { + forvalues j=`=`i'+1'/`nbsteps' { + local w2i:word `i' of `listw2' + local w2j:word `j' of `listw2' + local itemi:word `w2i' of `listi' + local modai:word `w2i' of `listm' + local itemj:word `w2j' of `listi' + local modaj:word `w2j' of `listm' + qui replace `generror'=`generror'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + qui replace `generror'_`itemi'=`generror'_`itemi'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + qui replace `generror'_`itemj'=`generror'_`itemj'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. +* qui replace `generror'=`generror'+.5 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.&`P1'[1,`i']==`P1'[1,`j'] + *qui replace `generror'=`generror'+.5 if `P1'[1,`i']==`P1'[1,`j']&``i''==1&``j''==0 + } + } +* set trace on + tempvar flag + qui gen `flag'=0 + qui replace `flag'=1 `if' + qui replace `generror'=. if `flag'==0 + qui replace `generror'_0=. if `flag'==0 + qui gen `generror'_H=1-`generror'/`generror'_0 + tempvar score + qui genscore `varlist' `if',score(`score') + qui gen `generror'_max=. + forvalues i=1/`nbsteps' { + qui replace `generror'_max=`errmax`i'' if `score'==`i' + } + qui gen `generror'_GPN=`generror'/`generror'_max + label variable `generror' "Number of Guttman errors per individual" + label variable `generror'_H "H indice per individual" + if "`graph'"!="" { + qui histogram `generror',discrete freq name(errors,replace) + qui histogram `generror'_H,discrete freq name(H,replace) + } + qui su `generror' ,det + local meane=r(mean) + local mede=r(p50) + local mine=r(min) + local maxe=r(max) + qui su `generror'_GPN ,det + local meanGPN=r(mean) + local medGPN=r(p50) + local minGPN=r(min) + local maxGPN=r(max) + di + di in green "Number of Guttman errors by individual" _col(50) in green "Normalized number of Guttamn errors by individual" + di in green " Mean number: " in ye %7.2f `meane' _col(50) in green " Mean number: " in ye %7.2f `meanGPN' + di in green " Median number: " in ye %7.2f `mede' _col(50) in green " Median number: " in ye %7.2f `medGPN' + di in green " Minimal number: " in ye %7.2f `mine' _col(50) in green " Minimal number: " in ye %7.2f `minGPN' + di in green " Maximal number: " in ye %7.2f `maxe' _col(50) in green " Maximal number: " in ye %7.2f `maxGPN' + di in green "Expected Guttman errors: " in ye %7.2f `=`eGutt0'/`nb'' + qui count if `generror'_H<0 + di in green " Rate of Hn<0: " in ye %7.2f `=r(N)/`nb'*100' "%" + +} + +matrix colnames `loevHj'=`varlist' +matrix rownames `loevHj'=Hj +return matrix loevHj `loevHj' + +matrix colnames `loevHjk'=`varlist' +matrix rownames `loevHjk'=`varlist' +return matrix loevHjk `loevHjk' + +matrix colnames `eGuttj'=`varlist' +matrix rownames `eGuttj'=ej +return matrix eGuttj `eGuttj' + +matrix colnames `eGuttjk'=`varlist' +matrix rownames `eGuttjk'=`varlist' +return matrix eGuttjk `eGuttjk' + +matrix colnames `eGuttj0'=`varlist' +matrix rownames `eGuttj0'=ejk +return matrix eGuttj0 `eGuttj0' + +matrix colnames `eGuttjk0'=`varlist' +matrix rownames `eGuttjk0'=`varlist' +return matrix eGuttjk0 `eGuttjk0' + +return scalar loevH=`loevH' +return scalar eGutt =`eGutt' +return scalar eGutt0 =`eGutt0' + +if `modamax'==1 { + matrix colnames `P11'=`varlist' + matrix rownames `P11'=`varlist' + return matrix P11 `P11' +} + +matrix colnames `P00'=`varlist' +matrix rownames `P00'=`varlist' +return matrix P00 `P00' + +if "`ppp'"!=""|"`nipmatrix'"!="" { + return matrix ppp=`matpp' +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + return matrix pmm=`matmm' +} + +matrix colnames `zHj'=`varlist' +matrix rownames `zHj'=zHj +return matrix zHj `zHj' + +matrix colnames `pvalHj'=`varlist' +matrix rownames `pvalHj'=pval +return matrix pvalHj `pvalHj' + +return scalar zH=`zH' +return scalar pvalH=`pvalH' +if "`pair'"!="" { + matrix colnames `zHjk'=`varlist' + matrix rownames `zHjk'=`varlist' + return matrix zHjk `zHjk' + + matrix colnames `pvalHjk'=`varlist' + matrix rownames `pvalHjk'=`varlist' + return matrix pvalHjk `pvalHjk' +} + +matrix colnames `Obs'=`varlist' +matrix rownames `Obs'=`varlist' +return matrix Obs `Obs' + +capture restore, not + +end + diff --git a/Modules/ado/personal/l/loevh8.ado b/Modules/ado/personal/l/loevh8.ado new file mode 100644 index 0000000..5788472 --- /dev/null +++ b/Modules/ado/personal/l/loevh8.ado @@ -0,0 +1,1235 @@ +*! Version 8 8 December 2010 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : loevh +* Loevinger H indexes, Mokken Analysis +* Release 8: December 8, 2010 /*loevH is renamed loevh*/ +* +* +* Historic : +* Version 1 (August 20, 2002) [Jean-Benoit Hardouin] +* Version 2 (June 22, 2003) [Jean-Benoit Hardouin] +* Version 3 (December 1, 2003) [Jean-Benoit Hardouin] +* Version 4 (January 20, 2004) [Jean-Benoit Hardouin] +* Version 5 (March 22, 2004) [Jean-Benoit Hardouin] +* Version 6 (July 3, 2004) [Jean-Benoit Hardouin] +* Version 6.1 (September 19, 2005) [Jean-Benoit Hardouin] +* Version 6.2 (January 31, 2006) [Jean-Benoit Hardouin] +* Release 6.3 (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */ +* Release 6.4 (January 19, 2007) [Jean-Benoit Hardouin] /*Tests to compare Loevinger coefficients to 0 identical to the MSP software (dichotomous and polytomous case)*/ +* Release 6.5 (January 22, 2007) [Jean-Benoit Hardouin] /*Correction of a bug concerning the p-values with the pair option*/ +* Release 6.6 (Februar 16, 2007) [Jean-Benoit Hardouin] /*Correction of a bug with the displaying of Easyness with polytomous items, option graph, option generror, improvements*/ +* Release 7: June 21, 2007 /*Check of monotonicity and Non intersection via P matrices*/ +* Release 7.1: November 6, 2008 /*Correction for the z-tests for the check of non intersection via P matrices*/ +* Release 7.2: November 19, 2008 /*Implementation of the GPN indexes*/ +* Release 7.3: August 15, 2009 /*Print the difficulties of the items instead of P(X=0)*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences (UPRES EA 4275) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* Requiered Stata modules: +* -anaoption- (version 1) +* -traces- (version 3.2) +* -gengroup- (version 1) +* -guttmax- (version 1) +* +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2002-2008 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** + +program define loevh , rclass +version 8.2 +syntax varlist(min=2 numeric) [if] [,PAIRWise PAIR ppp pmm noADJust GENERror(string) REPlace GRaph MONOtonicity(string) NIRESTscore(string) NIPmatrix(string)] +preserve + +local nbitems : word count `varlist' +tokenize `varlist' +tempname corr cov P1 P0 diff P11 P00 H1jk vHjk zHjk chi2Hjk dfHjk pvalHjk H1j vHj zHj pvalHj H1 vH zH pvalH Obs eGuttjk eGuttjk0 loevHjk eGuttj eGuttj0 loevHj eGutt eGutt0 loevH e1 e2 +tempfile loevHfile +qui save "`loevHfile'" + +if "`if'"!="" { + qui keep `if' +} + +if "`adjust'"!="" { + local adj=0 +} +else { + local adj=1 +} + +qui count +local nbobs=r(N) + +forvalues j=1/`nbitems' { + if "`pairwise'"=="" { + qui drop if ``j''==. + } +} +qui count +local nbtotindnm=r(N) + +matrix define `eGuttjk'=J(`nbitems',`nbitems',0) +matrix define `eGuttjk0'=J(`nbitems',`nbitems',0) +matrix define `loevHjk'=J(`nbitems',`nbitems',0) +matrix define `eGuttj'=J(1,`nbitems',0) +matrix define `eGuttj0'=J(1,`nbitems',0) +matrix define `loevHj'=J(1,`nbitems',0) +scalar define `eGutt'=0 +scalar define `eGutt0'=0 +scalar define `loevH'=0 +matrix define `Obs'=J(`nbitems',`nbitems',0) +matrix define `P00'=J(`nbitems',`nbitems',0) + +tempname modamax +scalar `modamax'=0 +local scoremax=0 +forvalues j=1/`nbitems' { + qui su ``j'' + local m`j'=r(max) + local scoremax=`scoremax'+`m`j'' + if r(max)>`modamax' { + scalar `modamax'=r(max) + } + local nbHjkNS`j'=0 +} + +/*if "`generror'"!=""&`modamax'!=1 { + di in ye "It is not possible to define the {cmd:generror} option with polytomous items" + local generror +} */ +*di "scoremax `scoremax'" +if "`graph'"!=""&`scoremax'>19 { + di in ye "The {cmd:graph} option is disabled because of a large number of possible scores (>20)" + local graph +} + +matrix define `cov'=J(`nbitems',`nbitems',0) +matrix define `corr'=J(`nbitems',`nbitems',0) +matrix define `P11'=J(`nbitems',`nbitems',0) +matrix define `H1jk'=J(`nbitems',`nbitems',0) +matrix define `vHjk'=J(`nbitems',`nbitems',0) +matrix define `zHjk'=J(`nbitems',`nbitems',0) +matrix define `pvalHjk'=J(`nbitems',`nbitems',0) +matrix define `P1'=J(1,`nbitems',0) +matrix define `P0'=J(1,`nbitems',0) +matrix define `diff'=J(1,`nbitems',0) +matrix define `H1j'=J(1,`nbitems',0) +matrix define `vHj'=J(1,`nbitems',0) +matrix define `zHj'=J(1,`nbitems',0) +matrix define `pvalHj'=J(1,`nbitems',0) + +forvalues j=1/`nbitems' { + qui su ``j'' + matrix `cov'[`j',`j']=r(Var) + matrix `corr'[`j',`j']=1 + local tmp=`j'+1 + qui count if ``j''!=. + matrix `Obs'[`j',`j']=r(N) + forvalues k=`tmp'/`nbitems' { + qui count if ``j''!=.&``k''!=. + matrix `Obs'[`j',`k']=r(N) + matrix `Obs'[`k',`j']=r(N) + qui corr ``j'' ``k'',cov + matrix `cov'[`j',`k']=r(cov_12) + matrix `cov'[`k',`j']=r(cov_12) + qui corr ``j'' ``k'' + matrix `corr'[`j',`k']=r(rho) + matrix `corr'[`k',`j']=r(rho) + matrix `zHjk'[`j',`k']=`corr'[`j',`k']*(`Obs'[`j',`k']-`adj')^.5 + matrix `zHjk'[`k',`j']=`H1jk'[`j',`k'] + matrix `pvalHjk'[`j',`k']=1-norm(`zHjk'[`j',`k']) + matrix `pvalHjk'[`k',`j']=`pvalHjk'[`j',`k'] + if `pvalHjk'[`j',`k']>0.05 { + local nbHjkNS`j'=`nbHjkNS`j''+1 + local nbHjkNS`k'=`nbHjkNS`k''+1 + } + forvalues mod1=1/`m`j'' { + forvalues mod2=1/`m`k'' { + qui count if ``j''<`mod1'&``k''>=`mod2'&``j''!=.&``k''!=. + scalar `e1'=r(N) + qui count if ``j''>=`mod1'&``k''<`mod2'&``j''!=.&``k''!=. + scalar `e2'=r(N) + matrix `eGuttjk'[`j',`k']=`eGuttjk'[`j',`k']+min(`e1',`e2') + qui count if ``j''<`mod1'&``j''!=.&``k''!=. + local t1=r(N) + qui count if ``k''<`mod2'&``j''!=.&``k''!=. + local t2=r(N) + qui count if ``j''>=`mod1'&``j''!=.&``k''!=. + local t3=r(N) + qui count if ``k''>=`mod2'&``j''!=.&``k''!=. + local t4=r(N) + if min(`e1',`e2')==`e1' { + matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t1'*`t4'/`Obs'[`j',`k'] + } + else { + matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t2'*`t3'/`Obs'[`j',`k'] + } + + } + } + qui count if ``j''==0&``k''==0 + matrix `P00'[`j',`k']=r(N)/`Obs'[`j',`k'] + matrix `P00'[`k',`j']=r(N)/`Obs'[`k',`j'] + if `modamax'==1 { + qui count if ``j''==1&``k''==1 + matrix `P11'[`j',`k']=r(N)/`Obs'[`j',`k'] + matrix `P11'[`k',`j']=r(N)/`Obs'[`k',`j'] + } + + matrix `eGuttjk'[`k',`j']=`eGuttjk'[`j',`k'] + matrix `eGuttj'[1,`j']=`eGuttj'[1,`j']+`eGuttjk'[`j',`k'] + matrix `eGuttj'[1,`k']=`eGuttj'[1,`k']+`eGuttjk'[`j',`k'] + matrix `eGuttjk0'[`k',`j']=`eGuttjk0'[`j',`k'] + matrix `eGuttj0'[1,`j']=`eGuttj0'[1,`j']+`eGuttjk0'[`j',`k'] + matrix `eGuttj0'[1,`k']=`eGuttj0'[1,`k']+`eGuttjk0'[`j',`k'] + + matrix `loevHjk'[`j',`k']=1-`eGuttjk'[`j',`k']/`eGuttjk0'[`j',`k'] + matrix `loevHjk'[`k',`j']=`loevHjk'[`j',`k'] + + } + qui count if ``j''!=. + local tmp=r(N) + qui count if ``j''==1 + matrix `P1'[1,`j']=r(N)/`tmp' + qui count if ``j''==0 + matrix `P0'[1,`j']=r(N)/`tmp' + qui su ``j'' + matrix `diff'[1,`j']=r(mean) + matrix `loevHj'[1,`j']=1-`eGuttj'[1,`j']/`eGuttj0'[1,`j'] + scalar `eGutt'=`eGutt'+`eGuttj'[1,`j']/2 + scalar `eGutt0'=`eGutt0'+`eGuttj0'[1,`j']/2 +} +scalar `H1'=0 +scalar `vH'=0 +scalar `zH'=0 +forvalues j=1/`nbitems'{ + forvalues k=1/`nbitems' { + if `j'!=`k' { + matrix `zHj'[1,`j']=`zHj'[1,`j']+`cov'[`j',`k'] + matrix `vHj'[1,`j']=`vHj'[1,`j']+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj') + } + if `j'<`k' { + scalar `zH'=`zH'+`cov'[`j',`k'] + scalar `vH'=`vH'+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj') + } + } + matrix `zHj'[1,`j']=`zHj'[1,`j']/sqrt(`vHj'[1,`j']) + matrix `pvalHj'[1,`j']=1-norm(`zHj'[1,`j']) +} +scalar `zH'=`zH'/sqrt(`vH') +scalar `pvalH'=1-norm(`zH') +scalar `loevH'=1-`eGutt'/`eGutt0' + +if `modamax'==1 { + local text="Easyness" + local value=1 + local col=23 +} +else { + local text="Difficulty" + local value=0 + local col=21 +} + + +di in green _col(35) "Observed" _col(47) "Expected" _col(93) "Number" +di in green _col(27) "Mean" _col(36) "Guttman" _col(48) "Guttman" _col(59) "Loevinger" _col(83) "H0: Hj<=0" _col(94) "of NS" +di in green "Item" _col(15) "Obs" _col(26) "Score" _col(37) "errors" _col(49) "errors" _col(61) "H coeff" _col(73) "z-stat." _col(85) "p-value" _col(96) "Hjk" +di in green "{hline 99}" +forvalues j=1/`nbitems' { + di in green "``j''" in yellow _col(15) `Obs'[`j',`j'] _col(25) %6.4f `diff'[1,`j'] _col(38) %5.0f `eGuttj'[1,`j'] _col(47) %8.2f `eGuttj0'[1,`j'] _col(61) %7.5f `loevHj'[1,`j'] _col(72) %8.4f `zHj'[1,`j'] _col(85) %7.5f `pvalHj'[1,`j'] _col(97) %2.0f `nbHjkNS`j'' +} +di in green "{hline 99}" +if "`pairwise'"=="" { + local nb=`nbtotindnm' +} +else { + local nb=`nbobs' +} +di in green "Scale" in yellow _col(15) `nb' _col(38) %5.0f `eGutt' _col(47) %8.2f `eGutt0' _col(61) %-8.5f `loevH' _col(71) %9.4f `zH' _col(85) %7.5f `pvalH' + +if "`pair'"!="" { + di + di in green _col(45) "Observed" _col(57) "Expected" + di in green _col(`=`col'+10') "`text'" _col(46) "Guttman" _col(58) "Guttman" _col(69) "Loevinger" _col(92) "H0: Hjk<=0" + di in green "Items" _col(25) "Obs" _col(29) "P(Xj=`value',Xk=`value')" _col(47) "errors" _col(59) "errors" _col(71) "H coeff" _col(83) "z-stat." _col(95) "p-value" + di in green "{hline 101}" + forvalues j=1/`nbitems' { + forvalues k=`=`j'+1'/`nbitems' { + qui count if ``j''!=. + local obs=r(N) + di in green "``j''" _col(10) "``k''" in yellow _col(25) `Obs'[`j',`k'] _col(35) %6.4f `P`value'`value''[`j',`k'] _col(48) %5.0f `eGuttjk'[`j',`k'] _col(57) %8.2f `eGuttjk0'[`j',`k'] _col(70) %8.5f `loevHjk'[`j',`k'] _col(81) %9.4f `zHjk'[`j',`k'] _col(95) %7.5f `pvalHjk'[`j',`k'] + } + } + di in green "{hline 101}" +} +/*if `modamax'>1&"`ppp'"!="" { + di in green "It is not possible to obtain the P++ diagnostics with polytomous items" + local ppp +} +if `modamax'>1&"`pmm'"!="" { + di in green "It is not possible to obtain the P-- diagnostics with polytomous items" + local pmm +} */ + +tempname P11g P00g item id id2 p1 monlabel + +/*if "`monotonicity'"!=""&`modamax'>1 { + di in green "It is not possible to obtain the latent monotonicity diagnostics with polytomous items" + local monotonicity +} */ + +if "`monotonicity'"!="" { +*set trace on + if "`monotonicity'"=="*" { + anaoption + } + else { + anaoption,`monotonicity' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + +*set trace on + tempname score + qui genscore `varlist',score(`score') + di + di in green _col(10) "Summary per item for check of monotonicity" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" +*set trace on + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + tempname restscore`i' + qui gen `restscore`i''=`score'-``i'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroup`i' + qui gengroup `restscore`i'',newvariable(`restgroup`i'') minsize(`minsize') + local list`i'=r(list) + qui su `restgroup`i'' + local nbgroups`i'=r(max) + forvalues j=0/`nbgroups`i'' { + qui count if `restgroup`i''==`j' + local rgroup`j'=r(N) + } + local vi`i'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + } + forvalues l=1/`m`i'' { + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + local nbzvi`i'_`l'=0 + forvalues j=1/`nbgroups`i'' { + qui count if `restgroup`i''==`j'&``i''>=`l' + local nbitem`i'rgroup`j'_`l'=r(N) + forvalues k=1/`=`j'-1' { + local diff=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + if `nbitem`i'rgroup`j'_`l''!=`rgroup`j''&`nbitem`i'rgroup`k'_`l''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + } + local p=(`nbitem`i'rgroup`k'_`l''+`nbitem`i'rgroup`j'_`l'')/(`rgroup`j''+`rgroup`k'') + *local z=`diff'/sqrt(`p'*(1-`p')*(1/`rgroup`j''+1/`rgroup`k'')) + *di "local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) " + local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) + *di "=`z'" + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + } + if `j'==`nbgroups`i'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + } + di in green "{dup 97:-}" + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + *set trace on + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + if `vi`i''!=0 { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + if "`details'"!=""&`i'!=`nbitems' { + di in green "{dup 97:-}" + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" +} +/*if "`nirestscore'"!="" { +*set trace on + if "`nirestscore'"=="*" { + anaoption + } + else { + anaoption,`nirestscore' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + +*set trace on + tempname score + qui genscore `varlist',score(`score') + di + di in green _col(10) "Summary per item for check of Non-Intersection via Rest-score" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" +*set trace on + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + local vi`i'`j'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + } + forvalues j=1/`nbitems' { + if `j'!=`i' { + tempname restscorei`i'j`j' + qui gen `restscorei`i'j`j''=`score'-``i''-``j'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroupi`i'j`j' + qui gengroup `restscorei`i'j`j'',newvariable(`restgroupi`i'j`j'') minsize(`minsize') + local listi`i'j`j'=r(list) + qui su `restgroupi`i'j`j'' + local nbgroupsi`i'j`j'=r(max) + forvalues k=0/`nbgroupsi`i'j`j'' { + qui count if `restgroupi`i'j`j''==`k' + local rgroup`k'=r(N) + } + forvalues l=1/`m`i'' { + forvalues k=1/`m`j'' { + forvalues m=1/`nbgroupsi`i'j`j'' { + qui count if `restgroupi`i'j`j''==`m'&``i''>=`l'&``j''>=`k' + local nbitemi`i'j`j'rgroup`m'_`l'_`k'=r(N) + forvalues n=1/`=`m'-1' { + local diff=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m'' + if `nbitemi`i'j`j'rgroup`m'_`l'_`k''!=`rgroup`m''&`nbitemi`i'j`j'rgroup`m'_`l'_`k''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m'' + } + local p=(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+`nbitemi`i'j`j'rgroup`m'_`l'_`k'')/(`rgroup`m''+`rgroup`n'') + local z=abs(2*(sqrt(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)*sqrt(`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)-sqrt((`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k'')*`nbitemi`i'j`j'rgroup`m'_`l'_`k''))/sqrt(`rgroup`m''+`rgroup`n''-1)) + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + if `m'==`nbgroupsi`i'j`j'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + *local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + *local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + } + } + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + } + di in green "{dup 97:-}" + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + *set trace on + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + if `vi`i''!=0 { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + if "`details'"!=""&`i'!=`nbitems' { + di in green "{dup 97:-}" + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" +} */ + +if "`ppp'"!=""|"pmm"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + local list + local listi + local listm + local listv + forvalues i=1/`nbitems' { + forvalues l=1/`m`i'' { + tempname item`i'_`l' + qui gen `item`i'_`l''=``i''>=`l' if ``i''!=. + local list `list' ``i''_`l' + local listi `listi' ``i'' + local listm `listm' `l' + local listv `listv' `item`i'_`l'' + } + } + tempname matppp matpmm + matrix `matppp'=J(`=`scoremax'',`=`scoremax'+2',0) + matrix `matpmm'=J(`=`scoremax'',`=`scoremax'+2',0) + local row=1 + forvalues i=1/`nbitems' { + forvalues k=1/`m`i'' { + local col=1 + forvalues j=1/`nbitems' { + forvalues l=1/`m`j'' { + if `i'!=`j' { + qui count if `item`i'_`k''!=.&`item`j'_`l''!=. + local denom=r(N) + qui count if `item`i'_`k''==1&`item`j'_`l''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0&`item`j'_`l''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + } + else { + matrix `matppp'[`row',`col']=-1 + matrix `matpmm'[`row',`col']=-1 + } + local col=`col'+1 + } + } + qui count if `item`i'_`k''!=. + local denom=r(N) + qui count if `item`i'_`k''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + matrix `matppp'[`row',`=`scoremax'+2']=`i' + matrix `matpmm'[`row',`=`scoremax'+2']=`i' + local row=`row'+1 + } + } + matrix colnames `matppp'=`list' p1 item + matrix rownames `matppp'=`list' + matrix colnames `matpmm'=`list' p1 item + matrix rownames `matpmm'=`list' + if "`nipmatrix'"!="" { + if "`nipmatrix'"=="*" { + anaoption + } + else { + anaoption,`nipmatrix' + } + local minvi=`r(minvi)' + local siglevel=`r(siglevel)' + local minsize=`r(minsize)' + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + forvalues i=1/`nbitems' { + local nbacpp`i'=0 + local nbvipp`i'=0 + local maxvipp`i'=0 + local sumvipp`i'=0 + local zmaxpp`i'=0 + local nbsigzpp`i'=0 + local nbacmm`i'=0 + local nbvimm`i'=0 + local maxvimm`i'=0 + local sumvimm`i'=0 + local zmaxmm`i'=0 + local nbsigzmm`i'=0 + } + } + +} +tempfile temporaryfile +qui save `temporaryfile' + +if "`ppp'"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + drop * + qui svmat `matppp',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + sort p1 + qui set obs `=`scoremax'+1' + local listitem + forvalues i=1/`scoremax' { + local t=item[`i'] + local listitem `listitem' `t' + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + twoway conn `list' `id2' in 1/`scoremax',connect(`connect') ytitle("") title("P++ diagnostics") name(ppp,replace) + } + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matpp + matrix define `matpp'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local ti:word `i' of `listv' + local tj:word `j' of `listv' + local t:word `j' of `list2' + matrix `matpp'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matpp'=`list2' + matrix rownames `matpp'=`list2' + if "`ppp'"!="" { + di + di in green _col(10) "P++ values per items pair (The values should be increasing in each column)" + + matrix list `matpp',format(%5.3f) nohalf noheader + } + label drop `monlabel' + *set trace on + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { +*di "`listv' `listw2'" + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacpp`ti' + *local ++nbacmm`tk' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==1&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==1&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "++ `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzpp`tj' + if abs(`z')>`zmaxpp`tj'' { + local zmaxpp`tj'=abs(`z') + } + local ++nbsigzpp`tk' + if abs(`z')>`zmaxpp`tk'' { + local zmaxpp`tk'=abs(`z') + } + } + } + } + } + } + } + } +/* if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!= `tk'&`ti'!=`tk'&`ti'!=`tj' { + local ++nbacpp`ti' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minsize'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + } + } + } + } + } + } +*/ +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + drop _all + qui svmat `matpmm',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + gsort -p1 + qui set obs `=`scoremax'+1' + forvalues i=1/`scoremax' { + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + twoway conn `list' `id2' in 1/`scoremax',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) + } + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matmm + matrix define `matmm'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local t:word `j' of `list2' + matrix `matmm'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matmm'=`list2' + matrix rownames `matmm'=`list2' + if "`pmm'"!="" { + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + matrix list `matmm',format(%5.3f) nohalf noheader + } + label drop `monlabel' + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { +*di "`listv' `listw2'" + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacmm`ti' + *local ++nbacmm`tk' + local diff=`matmm'[`k',`i']-`matmm'[`j',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvimm`tj' + local ++nbvimm`tk' + local sumvimm`tj'=`sumvimm`tj''+`diff' + local sumvimm`tk'=`sumvimm`tk''+`diff' + if `diff'>`maxvimm`tj'' { + local maxvimm`tj'=`diff' + } + if `diff'>`maxvimm`tk'' { + local maxvimm`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==0&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==0&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "-- `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzmm`tj' + if abs(`z')>`zmaxmm`tj'' { + local zmaxmm`tj'=abs(`z') + } + local ++nbsigzmm`tk' + if abs(`z')>`zmaxmm`tk'' { + local zmaxmm`tk'=abs(`z') + } + } + } + } + } + } + } + } +} +if "`nipmatrix'"!="" { + *set trace on + di + di in green _col(10) "Summary per item for check of non-Intersection via Pmatrix" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) /*in green "Minsize=" in ye %5.0f `minsize' _col(40)*/ in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + forvalues i=1/`nbitems' { + local nbac`i'=`nbacpp`i''+`nbacmm`i'' + local nbvi`i'=`nbvipp`i''+`nbvimm`i'' + local maxvi`i'=max(`maxvipp`i'',`maxvimm`i'') + local sumvi`i'=`sumvipp`i''+`sumvimm`i'' + local zmaxvi`i'=max(`zmaxpp`i'',`zmaxmm`i'') + + local nbzsig`i'=`nbsigzpp`i''+`nbsigzmm`i'' + local zmax`i'=0 + *local nbsigz`i'=0 + local t=`loevHj'[1,`i'] +* di "local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmax`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' " + local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmaxvi`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' + + *di `nbac`i'' " " `nbvi`i'' " " `sumvi`i'' + if `nbvi`i''!=0 { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(33) %6.4f `=`nbvi`i''/`nbac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`nbac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzsig`i'' _col(93) %4.0f `crit`i'' + } + else { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(93) %4.0f `crit`i'' + } + } +} + +/*if "`pmm'"!="" { + drop _all + matrix `P00g'=`P00',`P1'' + matrix colnames `P00g'=`varlist' `p1' + matrix rownames `P00g'=`varlist' + qui svmat `P00g' , names(col) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + forvalues i=1/`nbitems' { + qui replace `item'="``i''" if `id'==`i' + qui replace ``i''=. if `id'==`i' + local connect "`connect' l" + label define `monlabel' `i' "``i''", add + } + sort `p1' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + twoway connected `varlist' `id2',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) + } + format `varlist' %5.3f + label variable `id' "Item" + label value `id' `monlabel' + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + list `id' `varlist' , table compress separator(`nbitems') noobs divider + label drop `monlabel' +} + + + +if "`pairwise'"=="" { + restore, not +}*/ + + +*di "listw2:`listw2'" +*di "listv:`listv'" +*di "list:`list'" +*di "listi:`listi'" +*di "listm:`listm'" +*di "listitem:`listitem'" + + +qui use "`loevHfile'",clear +*set trace on +if "`generror'"!="" { + if "`replace'"!="" { + capture drop `generror'_0 + capture drop `generror'_H + capture drop `generror'_max + capture drop `generror'_GPN + capture drop `generror' + } + qui gen `generror'=0 + *forvalues i=1/`nbitems' { + * qui gen `generror'_``i''=0 + *} + qui gen `generror'_0=`eGutt0'/`nb' + local nbsteps:word count `listitem' + if "`pairwise'"=="" { + forvalues i=1/`nbitems' { + qui replace `generror'=. if ``i''==. + qui replace `generror'_0=. if ``i''==. + } + } + forvalues i=0/`nbsteps' { + qui guttmax `listitem', score(`i') + local errmax`i'=r(maxegutt) + } +* matrix list `P0' + forvalues i=1/`nbsteps' { + forvalues j=`=`i'+1'/`nbsteps' { + local w2i:word `i' of `listw2' + local w2j:word `j' of `listw2' + local itemi:word `w2i' of `listi' + local modai:word `w2i' of `listm' + local itemj:word `w2j' of `listi' + local modaj:word `w2j' of `listm' + qui replace `generror'=`generror'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + *qui replace `generror'_`itemi'=`generror'_`itemi'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + *qui replace `generror'_`itemj'=`generror'_`itemj'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. +* qui replace `generror'=`generror'+.5 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.&`P1'[1,`i']==`P1'[1,`j'] + *qui replace `generror'=`generror'+.5 if `P1'[1,`i']==`P1'[1,`j']&``i''==1&``j''==0 + } + } +* set trace on + tempvar flag + qui gen `flag'=0 + qui replace `flag'=1 `if' + qui replace `generror'=. if `flag'==0 + qui replace `generror'_0=. if `flag'==0 + qui gen `generror'_H=1-`generror'/`generror'_0 + tempvar score + qui genscore `varlist' `if',score(`score') + qui gen `generror'_max=. + forvalues i=1/`nbsteps' { + qui replace `generror'_max=`errmax`i'' if `score'==`i' + } + qui gen `generror'_GPN=`generror'/`generror'_max + label variable `generror' "Number of Guttman errors per individual" + label variable `generror'_H "H indice per individual" + if "`graph'"!="" { + qui histogram `generror',discrete freq name(errors,replace) + qui histogram `generror'_H,discrete freq name(H,replace) + } + qui su `generror' ,det + local meane=r(mean) + local mede=r(p50) + local mine=r(min) + local maxe=r(max) + qui su `generror'_GPN ,det + local meanGPN=r(mean) + local medGPN=r(p50) + local minGPN=r(min) + local maxGPN=r(max) + di + di in green "Number of Guttman errors by individual" _col(50) in green "Normalized number of Guttamn errors by individual" + di in green " Mean number: " in ye %7.2f `meane' _col(50) in green " Mean number: " in ye %7.2f `meanGPN' + di in green " Median number: " in ye %7.2f `mede' _col(50) in green " Median number: " in ye %7.2f `medGPN' + di in green " Minimal number: " in ye %7.2f `mine' _col(50) in green " Minimal number: " in ye %7.2f `minGPN' + di in green " Maximal number: " in ye %7.2f `maxe' _col(50) in green " Maximal number: " in ye %7.2f `maxGPN' + di in green "Expected Guttman errors: " in ye %7.2f `=`eGutt0'/`nb'' + qui count if `generror'_H<0 + di in green " Rate of Hn<0: " in ye %7.2f `=r(N)/`nb'*100' "%" + +} + +matrix colnames `loevHj'=`varlist' +matrix rownames `loevHj'=Hj +return matrix loevHj `loevHj' + +matrix colnames `loevHjk'=`varlist' +matrix rownames `loevHjk'=`varlist' +return matrix loevHjk `loevHjk' + +matrix colnames `eGuttj'=`varlist' +matrix rownames `eGuttj'=ej +return matrix eGuttj `eGuttj' + +matrix colnames `eGuttjk'=`varlist' +matrix rownames `eGuttjk'=`varlist' +return matrix eGuttjk `eGuttjk' + +matrix colnames `eGuttj0'=`varlist' +matrix rownames `eGuttj0'=ejk +return matrix eGuttj0 `eGuttj0' + +matrix colnames `eGuttjk0'=`varlist' +matrix rownames `eGuttjk0'=`varlist' +return matrix eGuttjk0 `eGuttjk0' + +return scalar loevH=`loevH' +return scalar eGutt =`eGutt' +return scalar eGutt0 =`eGutt0' + +if `modamax'==1 { + matrix colnames `P11'=`varlist' + matrix rownames `P11'=`varlist' + return matrix P11 `P11' +} + +matrix colnames `P00'=`varlist' +matrix rownames `P00'=`varlist' +return matrix P00 `P00' + +if "`ppp'"!=""|"`nipmatrix'"!="" { + return matrix ppp=`matpp' +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + return matrix pmm=`matmm' +} + +matrix colnames `zHj'=`varlist' +matrix rownames `zHj'=zHj +return matrix zHj `zHj' + +matrix colnames `pvalHj'=`varlist' +matrix rownames `pvalHj'=pval +return matrix pvalHj `pvalHj' + +return scalar zH=`zH' +return scalar pvalH=`pvalH' +if "`pair'"!="" { + matrix colnames `zHjk'=`varlist' + matrix rownames `zHjk'=`varlist' + return matrix zHjk `zHjk' + + matrix colnames `pvalHjk'=`varlist' + matrix rownames `pvalHjk'=`varlist' + return matrix pvalHjk `pvalHjk' +} + +matrix colnames `Obs'=`varlist' +matrix rownames `Obs'=`varlist' +return matrix Obs `Obs' + +capture restore, not + +end diff --git a/Modules/ado/personal/l/loevh81.ado b/Modules/ado/personal/l/loevh81.ado new file mode 100644 index 0000000..b94814a --- /dev/null +++ b/Modules/ado/personal/l/loevh81.ado @@ -0,0 +1,1346 @@ +*! Version 8.1 19 October 2012 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : loevh +* Loevinger H indexes, Mokken Analysis +* Release 8.1: October 19, 2012 /*html option*/ +* +* +* Historic : +* Version 1 (August 20, 2002) [Jean-Benoit Hardouin] +* Version 2 (June 22, 2003) [Jean-Benoit Hardouin] +* Version 3 (December 1, 2003) [Jean-Benoit Hardouin] +* Version 4 (January 20, 2004) [Jean-Benoit Hardouin] +* Version 5 (March 22, 2004) [Jean-Benoit Hardouin] +* Version 6 (July 3, 2004) [Jean-Benoit Hardouin] +* Version 6.1 (September 19, 2005) [Jean-Benoit Hardouin] +* Version 6.2 (January 31, 2006) [Jean-Benoit Hardouin] +* Release 6.3 (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */ +* Release 6.4 (January 19, 2007) [Jean-Benoit Hardouin] /*Tests to compare Loevinger coefficients to 0 identical to the MSP software (dichotomous and polytomous case)*/ +* Release 6.5 (January 22, 2007) [Jean-Benoit Hardouin] /*Correction of a bug concerning the p-values with the pair option*/ +* Release 6.6 (Februar 16, 2007) [Jean-Benoit Hardouin] /*Correction of a bug with the displaying of Easyness with polytomous items, option graph, option generror, improvements*/ +* Release 7: June 21, 2007 /*Check of monotonicity and Non intersection via P matrices*/ +* Release 7.1: November 6, 2008 /*Correction for the z-tests for the check of non intersection via P matrices*/ +* Release 7.2: November 19, 2008 /*Implementation of the GPN indexes*/ +* Release 7.3: August 15, 2009 /*Print the difficulties of the items instead of P(X=0)*/ +* Release 8: December 8, 2010 /*loevH is renamed loevh*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences (UPRES EA 4275) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* Requiered Stata modules: +* -anaoption- (version 1) +* -traces- (version 3.2) +* -gengroup- (version 1) +* -guttmax- (version 1) +* +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2002-2008 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** + +program define loevh , rclass +version 8.2 +syntax varlist(min=2 numeric) [if] [,PAIRWise PAIR ppp pmm noADJust GENERror(string) REPlace GRaph MONOtonicity(string) NIRESTscore(string) NIPmatrix(string) HTML(string)] +preserve + +if "`html'" != "" { + di in gr "" +} + +local nbitems : word count `varlist' +tokenize `varlist' +tempname corr cov P1 P0 diff P11 P00 H1jk vHjk zHjk chi2Hjk dfHjk pvalHjk H1j vHj zHj pvalHj H1 vH zH pvalH Obs eGuttjk eGuttjk0 loevHjk eGuttj eGuttj0 loevHj eGutt eGutt0 loevH e1 e2 +tempfile loevHfile +qui save "`loevHfile'" + +if "`if'"!="" { + qui keep `if' +} + +if "`adjust'"!="" { + local adj=0 +} +else { + local adj=1 +} + +qui count +local nbobs=r(N) + +forvalues j=1/`nbitems' { + if "`pairwise'"=="" { + qui drop if ``j''==. + } +} +qui count +local nbtotindnm=r(N) + +matrix define `eGuttjk'=J(`nbitems',`nbitems',0) +matrix define `eGuttjk0'=J(`nbitems',`nbitems',0) +matrix define `loevHjk'=J(`nbitems',`nbitems',0) +matrix define `eGuttj'=J(1,`nbitems',0) +matrix define `eGuttj0'=J(1,`nbitems',0) +matrix define `loevHj'=J(1,`nbitems',0) +scalar define `eGutt'=0 +scalar define `eGutt0'=0 +scalar define `loevH'=0 +matrix define `Obs'=J(`nbitems',`nbitems',0) +matrix define `P00'=J(`nbitems',`nbitems',0) + +tempname modamax +scalar `modamax'=0 +local scoremax=0 +forvalues j=1/`nbitems' { + qui su ``j'' + local m`j'=r(max) + local scoremax=`scoremax'+`m`j'' + if r(max)>`modamax' { + scalar `modamax'=r(max) + } + local nbHjkNS`j'=0 +} + +/*if "`generror'"!=""&`modamax'!=1 { + di in ye "It is not possible to define the {cmd:generror} option with polytomous items" + local generror +} */ +*di "scoremax `scoremax'" +if "`graph'"!=""&`scoremax'>19 { + di in ye "The {cmd:graph} option is disabled because of a large number of possible scores (>20)" + local graph +} + +matrix define `cov'=J(`nbitems',`nbitems',0) +matrix define `corr'=J(`nbitems',`nbitems',0) +matrix define `P11'=J(`nbitems',`nbitems',0) +matrix define `H1jk'=J(`nbitems',`nbitems',0) +matrix define `vHjk'=J(`nbitems',`nbitems',0) +matrix define `zHjk'=J(`nbitems',`nbitems',0) +matrix define `pvalHjk'=J(`nbitems',`nbitems',0) +matrix define `P1'=J(1,`nbitems',0) +matrix define `P0'=J(1,`nbitems',0) +matrix define `diff'=J(1,`nbitems',0) +matrix define `H1j'=J(1,`nbitems',0) +matrix define `vHj'=J(1,`nbitems',0) +matrix define `zHj'=J(1,`nbitems',0) +matrix define `pvalHj'=J(1,`nbitems',0) + +forvalues j=1/`nbitems' { + qui su ``j'' + matrix `cov'[`j',`j']=r(Var) + matrix `corr'[`j',`j']=1 + local tmp=`j'+1 + qui count if ``j''!=. + matrix `Obs'[`j',`j']=r(N) + forvalues k=`tmp'/`nbitems' { + qui count if ``j''!=.&``k''!=. + matrix `Obs'[`j',`k']=r(N) + matrix `Obs'[`k',`j']=r(N) + qui corr ``j'' ``k'',cov + matrix `cov'[`j',`k']=r(cov_12) + matrix `cov'[`k',`j']=r(cov_12) + qui corr ``j'' ``k'' + matrix `corr'[`j',`k']=r(rho) + matrix `corr'[`k',`j']=r(rho) + matrix `zHjk'[`j',`k']=`corr'[`j',`k']*(`Obs'[`j',`k']-`adj')^.5 + matrix `zHjk'[`k',`j']=`H1jk'[`j',`k'] + matrix `pvalHjk'[`j',`k']=1-norm(`zHjk'[`j',`k']) + matrix `pvalHjk'[`k',`j']=`pvalHjk'[`j',`k'] + if `pvalHjk'[`j',`k']>0.05 { + local nbHjkNS`j'=`nbHjkNS`j''+1 + local nbHjkNS`k'=`nbHjkNS`k''+1 + } + forvalues mod1=1/`m`j'' { + forvalues mod2=1/`m`k'' { + qui count if ``j''<`mod1'&``k''>=`mod2'&``j''!=.&``k''!=. + scalar `e1'=r(N) + qui count if ``j''>=`mod1'&``k''<`mod2'&``j''!=.&``k''!=. + scalar `e2'=r(N) + matrix `eGuttjk'[`j',`k']=`eGuttjk'[`j',`k']+min(`e1',`e2') + qui count if ``j''<`mod1'&``j''!=.&``k''!=. + local t1=r(N) + qui count if ``k''<`mod2'&``j''!=.&``k''!=. + local t2=r(N) + qui count if ``j''>=`mod1'&``j''!=.&``k''!=. + local t3=r(N) + qui count if ``k''>=`mod2'&``j''!=.&``k''!=. + local t4=r(N) + if min(`e1',`e2')==`e1' { + matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t1'*`t4'/`Obs'[`j',`k'] + } + else { + matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t2'*`t3'/`Obs'[`j',`k'] + } + + } + } + qui count if ``j''==0&``k''==0 + matrix `P00'[`j',`k']=r(N)/`Obs'[`j',`k'] + matrix `P00'[`k',`j']=r(N)/`Obs'[`k',`j'] + if `modamax'==1 { + qui count if ``j''==1&``k''==1 + matrix `P11'[`j',`k']=r(N)/`Obs'[`j',`k'] + matrix `P11'[`k',`j']=r(N)/`Obs'[`k',`j'] + } + + matrix `eGuttjk'[`k',`j']=`eGuttjk'[`j',`k'] + matrix `eGuttj'[1,`j']=`eGuttj'[1,`j']+`eGuttjk'[`j',`k'] + matrix `eGuttj'[1,`k']=`eGuttj'[1,`k']+`eGuttjk'[`j',`k'] + matrix `eGuttjk0'[`k',`j']=`eGuttjk0'[`j',`k'] + matrix `eGuttj0'[1,`j']=`eGuttj0'[1,`j']+`eGuttjk0'[`j',`k'] + matrix `eGuttj0'[1,`k']=`eGuttj0'[1,`k']+`eGuttjk0'[`j',`k'] + + matrix `loevHjk'[`j',`k']=1-`eGuttjk'[`j',`k']/`eGuttjk0'[`j',`k'] + matrix `loevHjk'[`k',`j']=`loevHjk'[`j',`k'] + + } + qui count if ``j''!=. + local tmp=r(N) + qui count if ``j''==1 + matrix `P1'[1,`j']=r(N)/`tmp' + qui count if ``j''==0 + matrix `P0'[1,`j']=r(N)/`tmp' + qui su ``j'' + matrix `diff'[1,`j']=r(mean) + matrix `loevHj'[1,`j']=1-`eGuttj'[1,`j']/`eGuttj0'[1,`j'] + scalar `eGutt'=`eGutt'+`eGuttj'[1,`j']/2 + scalar `eGutt0'=`eGutt0'+`eGuttj0'[1,`j']/2 +} +scalar `H1'=0 +scalar `vH'=0 +scalar `zH'=0 +forvalues j=1/`nbitems'{ + forvalues k=1/`nbitems' { + if `j'!=`k' { + matrix `zHj'[1,`j']=`zHj'[1,`j']+`cov'[`j',`k'] + matrix `vHj'[1,`j']=`vHj'[1,`j']+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj') + } + if `j'<`k' { + scalar `zH'=`zH'+`cov'[`j',`k'] + scalar `vH'=`vH'+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj') + } + } + matrix `zHj'[1,`j']=`zHj'[1,`j']/sqrt(`vHj'[1,`j']) + matrix `pvalHj'[1,`j']=1-norm(`zHj'[1,`j']) +} +scalar `zH'=`zH'/sqrt(`vH') +scalar `pvalH'=1-norm(`zH') +scalar `loevH'=1-`eGutt'/`eGutt0' + +if `modamax'==1 { + local text="Easyness" + local value=1 + local col=23 +} +else { + local text="Difficulty" + local value=0 + local col=21 +} + +if "`html'" == "" { + di in green _col(35) "Observed" _col(47) "Expected" _col(93) "Number" + di in green _col(27) "Mean" _col(36) "Guttman" _col(48) "Guttman" _col(59) "Loevinger" _col(83) "H0: Hj<=0" _col(94) "of NS" + di in green "Item" _col(15) "Obs" _col(26) "Score" _col(37) "errors" _col(49) "errors" _col(61) "H coeff" _col(73) "z-stat." _col(85) "p-value" _col(96) "Hjk" + di in green "{hline 99}" + forvalues j=1/`nbitems' { + di in green "``j''" in yellow _col(15) `Obs'[`j',`j'] _col(25) %6.4f `diff'[1,`j'] _col(38) %5.0f `eGuttj'[1,`j'] _col(47) %8.2f `eGuttj0'[1,`j'] _col(61) %7.5f `loevHj'[1,`j'] _col(72) %8.4f `zHj'[1,`j'] _col(85) %7.5f `pvalHj'[1,`j'] _col(97) %2.0f `nbHjkNS`j'' + } + di in green "{hline 99}" +} +else { + di in gr "" + di in gr "" + di in gr "" + di in gr "" + di in gr "" + forvalues j=1/`nbitems' { + di in green "" + } +} + +if "`pairwise'"=="" { + local nb=`nbtotindnm' +} +else { + local nb=`nbobs' +} +if "`html'" == "" { + di in green "Scale" in yellow _col(15) `nb' _col(38) %5.0f `eGutt' _col(47) %8.2f `eGutt0' _col(61) %-8.5f `loevH' _col(71) %9.4f `zH' _col(85) %7.5f `pvalH' +} +else { + di in green "" + di in gr "
ItemObsMean
Score
Observed
Guttman
Errors
Expected
Guttman
Errors
Loevinger
H coeff
z-stat.H0: Hj ≤ 0
p-value
Number of
NS Hjk
``j''" `Obs'[`j',`j'] "" %6.4f `diff'[1,`j'] "" %5.0f `eGuttj'[1,`j'] "" %8.2f `eGuttj0'[1,`j'] "" %7.5f `loevHj'[1,`j'] "" %8.4f `zHj'[1,`j'] "" %7.5f `pvalHj'[1,`j'] "" %2.0f `nbHjkNS`j'' "
Scale" `nb' "" %5.0f `eGutt' "" %8.2f `eGutt0' "" %-8.5f `loevH' "" %9.4f `zH' "" %7.5f `pvalH' "
" +} + +if "`pair'"!="" { + if "`html'" == "" { + di + di in green _col(45) "Observed" _col(57) "Expected" + di in green _col(`=`col'+10') "`text'" _col(46) "Guttman" _col(58) "Guttman" _col(69) "Loevinger" _col(92) "H0: Hjk<=0" + di in green "Items" _col(25) "Obs" _col(29) "P(Xj=`value',Xk=`value')" _col(47) "errors" _col(59) "errors" _col(71) "H coeff" _col(83) "z-stat." _col(95) "p-value" + di in green "{hline 101}" + forvalues j=1/`nbitems' { + forvalues k=`=`j'+1'/`nbitems' { + qui count if ``j''!=. + local obs=r(N) + di in green "``j''" _col(10) "``k''" in yellow _col(25) `Obs'[`j',`k'] _col(35) %6.4f `P`value'`value''[`j',`k'] _col(48) %5.0f `eGuttjk'[`j',`k'] _col(57) %8.2f `eGuttjk0'[`j',`k'] _col(70) %8.5f `loevHjk'[`j',`k'] _col(81) %9.4f `zHjk'[`j',`k'] _col(95) %7.5f `pvalHjk'[`j',`k'] + } + } + di in green "{hline 101}" + } + else { + di in gr "" + di in gr "" + di in green "" + di in gr "" + forvalues j=1/`nbitems' { + forvalues k=`=`j'+1'/`nbitems' { + qui count if ``j''!=. + local obs=r(N) + di in green "" + } + } + di in green "
Summary of results by items pairs
Items" "`text'" "
Obs P(Xj=`value',Xk=`value')
Observed
Guttman
Errors
Expected
Guttman
Errors
Loevinger
H coeff
z-stat.H0: Hjk ≤ 0
p-value
" "``j''" "" "``k''" "" `Obs'[`j',`k'] "" %6.4f `P`value'`value''[`j',`k'] "" %5.0f `eGuttjk'[`j',`k'] "" %8.2f `eGuttjk0'[`j',`k'] "" %8.5f `loevHjk'[`j',`k'] "" %9.4f `zHjk'[`j',`k'] "" %7.5f `pvalHjk'[`j',`k'] "
" + } +} + +/*if `modamax'>1&"`ppp'"!="" { + di in green "It is not possible to obtain the P++ diagnostics with polytomous items" + local ppp +} +if `modamax'>1&"`pmm'"!="" { + di in green "It is not possible to obtain the P-- diagnostics with polytomous items" + local pmm +} */ + +tempname P11g P00g item id id2 p1 monlabel + +/*if "`monotonicity'"!=""&`modamax'>1 { + if "`html'" == "" { + di in green "It is not possible to obtain the latent monotonicity diagnostics with polytomous items" + } + else { + di in green "

It is not possible to obtain the latent monotonicity diagnostics with polytomous items

" + } + local monotonicity +} */ + +if "`monotonicity'"!="" { +*set trace on + if "`monotonicity'"=="*" { + anaoption + } + else { + anaoption,`monotonicity' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + +*set trace on + tempname score + qui genscore `varlist',score(`score') + if "`html'" == "" { + di + di in green _col(10) "Summary per item for check of monotonicity" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + } + else { + di in gr "" + di in gr "" + di in gr "" + } +*set trace on + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + tempname restscore`i' + qui gen `restscore`i''=`score'-``i'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroup`i' + qui gengroup `restscore`i'',newvariable(`restgroup`i'') minsize(`minsize') + local list`i'=r(list) + qui su `restgroup`i'' + local nbgroups`i'=r(max) + forvalues j=0/`nbgroups`i'' { + qui count if `restgroup`i''==`j' + local rgroup`j'=r(N) + } + local vi`i'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + } + forvalues l=1/`m`i'' { + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + local nbzvi`i'_`l'=0 + forvalues j=1/`nbgroups`i'' { + qui count if `restgroup`i''==`j'&``i''>=`l' + local nbitem`i'rgroup`j'_`l'=r(N) + forvalues k=1/`=`j'-1' { + local diff=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + if `nbitem`i'rgroup`j'_`l''!=`rgroup`j''&`nbitem`i'rgroup`k'_`l''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + } + local p=(`nbitem`i'rgroup`k'_`l''+`nbitem`i'rgroup`j'_`l'')/(`rgroup`j''+`rgroup`k'') + *local z=`diff'/sqrt(`p'*(1-`p')*(1/`rgroup`j''+1/`rgroup`k'')) + *di "local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) " + local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) + *di "=`z'" + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + } + if `j'==`nbgroups`i'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + if "`html'" == "" { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in gr "" + } + } + else { + if "`html'" == "" { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + else { + di in gr "" + } + } + } + if "`html'" == "" { + di in green "{dup 97:-}" + } + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + *set trace on + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + if `vi`i''!=0 { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in green "" + } + } + else { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in gr "" + } + + } + if "`details'"!=""&`i'!=`nbitems' { + if "`html'" == "" { + di in green "{dup 97:-}" + } + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + if "`html'" == "" { + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" + } + else { + di in green "
Summary per item for check of monotonicity
Items#ac#vi#vi / #acmaxvisumsum / #aczmax#zsigCrit
``i''>=`l'" %8.0f `ac`i'_m`l'' "" %8.0f `vi`i'_m`l'' "" %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' "" %6.4f `maxvi`i'_m`l'' "" %6.4f `sumvi`i'_m`l'' "" %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' "" %6.4f `zmaxvi`i'_m`l'' "" %8.0f `nbzvi`i'_m`l'' "
``i''>=`l'" %8.0f `ac`i'_m`l'' "" %8.0f `vi`i'_m`l'' "
``i''" %8.0f `ac`i'' "" %8.0f `vi`i'' "" %6.4f `=`vi`i''/`ac`i''' "" %6.4f `maxvi`i'' "" %6.4f `sumvi`i'' "" %6.4f `=`sumvi`i''/`ac`i''' "" %6.4f `zmaxvi`i'' "" %8.0f `nbzvi`i'' "" %4.0f `crit`i'' "
``i''" %8.0f `ac`i'' "" %8.0f `vi`i'' "" %4.0f `crit`i'' "
Total" `ac' "" %8.0f `vi' "" %6.4f `=`vi'/`ac'' "" %6.4f `maxvi' "" %6.4f `sumvi' "" %6.4f `=`sumvi'/`ac'' "" %6.4f `zmaxvi' "" %8.0f `nbzvi' "
" + } +} +/*if "`nirestscore'"!="" { +*set trace on + if "`nirestscore'"=="*" { + anaoption + } + else { + anaoption,`nirestscore' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + +*set trace on + tempname score + qui genscore `varlist',score(`score') + di + di in green _col(10) "Summary per item for check of Non-Intersection via Rest-score" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" +*set trace on + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + local vi`i'`j'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + } + forvalues j=1/`nbitems' { + if `j'!=`i' { + tempname restscorei`i'j`j' + qui gen `restscorei`i'j`j''=`score'-``i''-``j'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroupi`i'j`j' + qui gengroup `restscorei`i'j`j'',newvariable(`restgroupi`i'j`j'') minsize(`minsize') + local listi`i'j`j'=r(list) + qui su `restgroupi`i'j`j'' + local nbgroupsi`i'j`j'=r(max) + forvalues k=0/`nbgroupsi`i'j`j'' { + qui count if `restgroupi`i'j`j''==`k' + local rgroup`k'=r(N) + } + forvalues l=1/`m`i'' { + forvalues k=1/`m`j'' { + forvalues m=1/`nbgroupsi`i'j`j'' { + qui count if `restgroupi`i'j`j''==`m'&``i''>=`l'&``j''>=`k' + local nbitemi`i'j`j'rgroup`m'_`l'_`k'=r(N) + forvalues n=1/`=`m'-1' { + local diff=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m'' + if `nbitemi`i'j`j'rgroup`m'_`l'_`k''!=`rgroup`m''&`nbitemi`i'j`j'rgroup`m'_`l'_`k''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m'' + } + local p=(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+`nbitemi`i'j`j'rgroup`m'_`l'_`k'')/(`rgroup`m''+`rgroup`n'') + local z=abs(2*(sqrt(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)*sqrt(`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)-sqrt((`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k'')*`nbitemi`i'j`j'rgroup`m'_`l'_`k''))/sqrt(`rgroup`m''+`rgroup`n''-1)) + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + if `m'==`nbgroupsi`i'j`j'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + *local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + *local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + } + } + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + } + di in green "{dup 97:-}" + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + *set trace on + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + if `vi`i''!=0 { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + if "`details'"!=""&`i'!=`nbitems' { + di in green "{dup 97:-}" + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" +} */ + +if "`ppp'"!=""|"pmm"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + local list + local listi + local listm + local listv + forvalues i=1/`nbitems' { + forvalues l=1/`m`i'' { + tempname item`i'_`l' + qui gen `item`i'_`l''=``i''>=`l' if ``i''!=. + local list `list' ``i''_`l' + local listi `listi' ``i'' + local listm `listm' `l' + local listv `listv' `item`i'_`l'' + } + } + tempname matppp matpmm + matrix `matppp'=J(`=`scoremax'',`=`scoremax'+2',0) + matrix `matpmm'=J(`=`scoremax'',`=`scoremax'+2',0) + local row=1 + forvalues i=1/`nbitems' { + forvalues k=1/`m`i'' { + local col=1 + forvalues j=1/`nbitems' { + forvalues l=1/`m`j'' { + if `i'!=`j' { + qui count if `item`i'_`k''!=.&`item`j'_`l''!=. + local denom=r(N) + qui count if `item`i'_`k''==1&`item`j'_`l''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0&`item`j'_`l''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + } + else { + matrix `matppp'[`row',`col']=-1 + matrix `matpmm'[`row',`col']=-1 + } + local col=`col'+1 + } + } + qui count if `item`i'_`k''!=. + local denom=r(N) + qui count if `item`i'_`k''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + matrix `matppp'[`row',`=`scoremax'+2']=`i' + matrix `matpmm'[`row',`=`scoremax'+2']=`i' + local row=`row'+1 + } + } + matrix colnames `matppp'=`list' p1 item + matrix rownames `matppp'=`list' + matrix colnames `matpmm'=`list' p1 item + matrix rownames `matpmm'=`list' + if "`nipmatrix'"!="" { + if "`nipmatrix'"=="*" { + anaoption + } + else { + anaoption,`nipmatrix' + } + local minvi=`r(minvi)' + local siglevel=`r(siglevel)' + local minsize=`r(minsize)' + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + forvalues i=1/`nbitems' { + local nbacpp`i'=0 + local nbvipp`i'=0 + local maxvipp`i'=0 + local sumvipp`i'=0 + local zmaxpp`i'=0 + local nbsigzpp`i'=0 + local nbacmm`i'=0 + local nbvimm`i'=0 + local maxvimm`i'=0 + local sumvimm`i'=0 + local zmaxmm`i'=0 + local nbsigzmm`i'=0 + } + } + +} +tempfile temporaryfile +qui save `temporaryfile' + +if "`ppp'"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + drop * + qui svmat `matppp',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + sort p1 + qui set obs `=`scoremax'+1' + local listitem + forvalues i=1/`scoremax' { + local t=item[`i'] + local listitem `listitem' `t' + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + if "`html'"!="" { + local saving "saving(`c(tmpdir)'/`html'_ppp.jpg,replace) nodraw" + } + twoway conn `list' `id2' in 1/`scoremax',connect(`connect') ytitle("") title("P++ diagnostics") name(ppp,replace) `saving' + } + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matpp + matrix define `matpp'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local ti:word `i' of `listv' + local tj:word `j' of `listv' + local t:word `j' of `list2' + matrix `matpp'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matpp'=`list2' + matrix rownames `matpp'=`list2' + if "`ppp'"!="" { + di + di in green _col(10) "P++ values per items pair (The values should be increasing in each column)" + + matrix list `matpp',format(%5.3f) nohalf noheader + } + label drop `monlabel' + *set trace on + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { +*di "`listv' `listw2'" + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacpp`ti' + *local ++nbacmm`tk' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==1&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==1&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "++ `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzpp`tj' + if abs(`z')>`zmaxpp`tj'' { + local zmaxpp`tj'=abs(`z') + } + local ++nbsigzpp`tk' + if abs(`z')>`zmaxpp`tk'' { + local zmaxpp`tk'=abs(`z') + } + } + } + } + } + } + } + } +/* if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!= `tk'&`ti'!=`tk'&`ti'!=`tj' { + local ++nbacpp`ti' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minsize'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + } + } + } + } + } + } +*/ +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + drop _all + qui svmat `matpmm',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + gsort -p1 + qui set obs `=`scoremax'+1' + forvalues i=1/`scoremax' { + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + if "`html'"!="" { + local saving "saving(`c(tmpdir)'/`html'_pmm.jpg,replace) nodraw" + } + twoway conn `list' `id2' in 1/`scoremax',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) `saving' + } + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matmm + matrix define `matmm'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local t:word `j' of `list2' + matrix `matmm'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matmm'=`list2' + matrix rownames `matmm'=`list2' + if "`pmm'"!="" { + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + matrix list `matmm',format(%5.3f) nohalf noheader + } + label drop `monlabel' + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { +*di "`listv' `listw2'" + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacmm`ti' + *local ++nbacmm`tk' + local diff=`matmm'[`k',`i']-`matmm'[`j',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvimm`tj' + local ++nbvimm`tk' + local sumvimm`tj'=`sumvimm`tj''+`diff' + local sumvimm`tk'=`sumvimm`tk''+`diff' + if `diff'>`maxvimm`tj'' { + local maxvimm`tj'=`diff' + } + if `diff'>`maxvimm`tk'' { + local maxvimm`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==0&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==0&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "-- `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzmm`tj' + if abs(`z')>`zmaxmm`tj'' { + local zmaxmm`tj'=abs(`z') + } + local ++nbsigzmm`tk' + if abs(`z')>`zmaxmm`tk'' { + local zmaxmm`tk'=abs(`z') + } + } + } + } + } + } + } + } +} + +if "`nipmatrix'" !="" { + *set trace on + if "`html'" == "" { + di + di in green _col(10) "Summary per item for check of non-Intersection via Pmatrix" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) /*in green "Minsize=" in ye %5.0f `minsize' _col(40)*/ in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + } + else { + di in gr "" + di in gr "" + di in gr "" + di in gr "" + } + forvalues i=1/`nbitems' { + local nbac`i'=`nbacpp`i''+`nbacmm`i'' + local nbvi`i'=`nbvipp`i''+`nbvimm`i'' + local maxvi`i'=max(`maxvipp`i'',`maxvimm`i'') + local sumvi`i'=`sumvipp`i''+`sumvimm`i'' + local zmaxvi`i'=max(`zmaxpp`i'',`zmaxmm`i'') + + local nbzsig`i'=`nbsigzpp`i''+`nbsigzmm`i'' + local zmax`i'=0 + *local nbsigz`i'=0 + local t=`loevHj'[1,`i'] +* di "local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmax`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' " + local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmaxvi`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' + + *di `nbac`i'' " " `nbvi`i'' " " `sumvi`i'' + if `nbvi`i''!=0 { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(33) %6.4f `=`nbvi`i''/`nbac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`nbac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzsig`i'' _col(93) %4.0f `crit`i'' + } + else { + di in green "" + } + } + else { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(93) %4.0f `crit`i'' + } + else { + di in green "" + } + } + } + if "`html'" != "" { + di in green "
Summary per item for check of non-Intersection via Pmatrix
" + di in gr "Minvi=" in ye %5.3f `minvi' "      Alpha=" in ye %5.3f `siglevel' "
Items#ac#vi#vi / #acmaxvisumsum / #aczmax#zsigCrit
" "``i''" "" %8.0f `nbac`i'' "" %8.0f `nbvi`i'' "" %6.4f `=`nbvi`i''/`nbac`i''' "" %6.4f `maxvi`i'' "" %6.4f `sumvi`i'' "" %6.4f `=`sumvi`i''/`nbac`i''' "" %6.4f `zmaxvi`i'' "" %8.0f `nbzsig`i'' "" %4.0f `crit`i'' "
" "``i''" "" %8.0f `nbac`i'' "" %8.0f `nbvi`i'' "" %4.0f `crit`i'' "
" + } +} + +/*if "`pmm'"!="" { + drop _all + matrix `P00g'=`P00',`P1'' + matrix colnames `P00g'=`varlist' `p1' + matrix rownames `P00g'=`varlist' + qui svmat `P00g' , names(col) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + forvalues i=1/`nbitems' { + qui replace `item'="``i''" if `id'==`i' + qui replace ``i''=. if `id'==`i' + local connect "`connect' l" + label define `monlabel' `i' "``i''", add + } + sort `p1' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + twoway connected `varlist' `id2',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) + } + format `varlist' %5.3f + label variable `id' "Item" + label value `id' `monlabel' + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + list `id' `varlist' , table compress separator(`nbitems') noobs divider + label drop `monlabel' +} + + + +if "`pairwise'"=="" { + restore, not +}*/ + + +*di "listw2:`listw2'" +*di "listv:`listv'" +*di "list:`list'" +*di "listi:`listi'" +*di "listm:`listm'" +*di "listitem:`listitem'" + + +qui use "`loevHfile'",clear +*set trace on +if "`generror'"!="" { + if "`replace'"!="" { + capture drop `generror'_0 + capture drop `generror'_H + capture drop `generror'_max + capture drop `generror'_GPN + capture drop `generror' + } + qui gen `generror'=0 + *forvalues i=1/`nbitems' { + * qui gen `generror'_``i''=0 + *} + qui gen `generror'_0=`eGutt0'/`nb' + local nbsteps:word count `listitem' + if "`pairwise'"=="" { + forvalues i=1/`nbitems' { + qui replace `generror'=. if ``i''==. + qui replace `generror'_0=. if ``i''==. + } + } + forvalues i=0/`nbsteps' { + qui guttmax `listitem', score(`i') + local errmax`i'=r(maxegutt) + } +* matrix list `P0' + forvalues i=1/`nbsteps' { + forvalues j=`=`i'+1'/`nbsteps' { + local w2i:word `i' of `listw2' + local w2j:word `j' of `listw2' + local itemi:word `w2i' of `listi' + local modai:word `w2i' of `listm' + local itemj:word `w2j' of `listi' + local modaj:word `w2j' of `listm' + qui replace `generror'=`generror'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + *qui replace `generror'_`itemi'=`generror'_`itemi'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + *qui replace `generror'_`itemj'=`generror'_`itemj'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. +* qui replace `generror'=`generror'+.5 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.&`P1'[1,`i']==`P1'[1,`j'] + *qui replace `generror'=`generror'+.5 if `P1'[1,`i']==`P1'[1,`j']&``i''==1&``j''==0 + } + } +* set trace on + tempvar flag + qui gen `flag'=0 + qui replace `flag'=1 `if' + qui replace `generror'=. if `flag'==0 + qui replace `generror'_0=. if `flag'==0 + qui gen `generror'_H=1-`generror'/`generror'_0 + tempvar score + qui genscore `varlist' `if',score(`score') + qui gen `generror'_max=. + forvalues i=1/`nbsteps' { + qui replace `generror'_max=`errmax`i'' if `score'==`i' + } + qui gen `generror'_GPN=`generror'/`generror'_max + label variable `generror' "Number of Guttman errors per individual" + label variable `generror'_H "H indice per individual" + if "`graph'"!="" { + qui histogram `generror',discrete freq name(errors,replace) + qui histogram `generror'_H,discrete freq name(H,replace) + } + qui su `generror' ,det + local meane=r(mean) + local mede=r(p50) + local mine=r(min) + local maxe=r(max) + qui su `generror'_GPN ,det + local meanGPN=r(mean) + local medGPN=r(p50) + local minGPN=r(min) + local maxGPN=r(max) + di + di in green "Number of Guttman errors by individual" _col(50) in green "Normalized number of Guttamn errors by individual" + di in green " Mean number: " in ye %7.2f `meane' _col(50) in green " Mean number: " in ye %7.2f `meanGPN' + di in green " Median number: " in ye %7.2f `mede' _col(50) in green " Median number: " in ye %7.2f `medGPN' + di in green " Minimal number: " in ye %7.2f `mine' _col(50) in green " Minimal number: " in ye %7.2f `minGPN' + di in green " Maximal number: " in ye %7.2f `maxe' _col(50) in green " Maximal number: " in ye %7.2f `maxGPN' + di in green "Expected Guttman errors: " in ye %7.2f `=`eGutt0'/`nb'' + qui count if `generror'_H<0 + di in green " Rate of Hn<0: " in ye %7.2f `=r(N)/`nb'*100' "%" + +} + +matrix colnames `loevHj'=`varlist' +matrix rownames `loevHj'=Hj +return matrix loevHj `loevHj' + +matrix colnames `loevHjk'=`varlist' +matrix rownames `loevHjk'=`varlist' +return matrix loevHjk `loevHjk' + +matrix colnames `eGuttj'=`varlist' +matrix rownames `eGuttj'=ej +return matrix eGuttj `eGuttj' + +matrix colnames `eGuttjk'=`varlist' +matrix rownames `eGuttjk'=`varlist' +return matrix eGuttjk `eGuttjk' + +matrix colnames `eGuttj0'=`varlist' +matrix rownames `eGuttj0'=ejk +return matrix eGuttj0 `eGuttj0' + +matrix colnames `eGuttjk0'=`varlist' +matrix rownames `eGuttjk0'=`varlist' +return matrix eGuttjk0 `eGuttjk0' + +return scalar loevH=`loevH' +return scalar eGutt =`eGutt' +return scalar eGutt0 =`eGutt0' + +if `modamax'==1 { + matrix colnames `P11'=`varlist' + matrix rownames `P11'=`varlist' + return matrix P11 `P11' +} + +matrix colnames `P00'=`varlist' +matrix rownames `P00'=`varlist' +return matrix P00 `P00' + +if "`ppp'"!=""|"`nipmatrix'"!="" { + return matrix ppp=`matpp' +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + return matrix pmm=`matmm' +} + +matrix colnames `zHj'=`varlist' +matrix rownames `zHj'=zHj +return matrix zHj `zHj' + +matrix colnames `pvalHj'=`varlist' +matrix rownames `pvalHj'=pval +return matrix pvalHj `pvalHj' + +return scalar zH=`zH' +return scalar pvalH=`pvalH' +if "`pair'"!="" { + matrix colnames `zHjk'=`varlist' + matrix rownames `zHjk'=`varlist' + return matrix zHjk `zHjk' + + matrix colnames `pvalHjk'=`varlist' + matrix rownames `pvalHjk'=`varlist' + return matrix pvalHjk `pvalHjk' +} + +matrix colnames `Obs'=`varlist' +matrix rownames `Obs'=`varlist' +return matrix Obs `Obs' + +capture restore, not + +end diff --git a/Modules/ado/personal/l/loevh812.zip b/Modules/ado/personal/l/loevh812.zip new file mode 100644 index 0000000..a47962d Binary files /dev/null and b/Modules/ado/personal/l/loevh812.zip differ diff --git a/Modules/ado/personal/l/loevh813.ado b/Modules/ado/personal/l/loevh813.ado new file mode 100644 index 0000000..170220a --- /dev/null +++ b/Modules/ado/personal/l/loevh813.ado @@ -0,0 +1,1403 @@ +*! Version 8.1.3 April 14, 2014 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : loevh +* Loevinger H indexes, Mokken Analysis +* Release 8.1.3 : April 14, 2014 /*minor correction*/ +* +* +* Historic : +* Version 1 (August 20, 2002) [Jean-Benoit Hardouin] +* Version 2 (June 22, 2003) [Jean-Benoit Hardouin] +* Version 3 (December 1, 2003) [Jean-Benoit Hardouin] +* Version 4 (January 20, 2004) [Jean-Benoit Hardouin] +* Version 5 (March 22, 2004) [Jean-Benoit Hardouin] +* Version 6 (July 3, 2004) [Jean-Benoit Hardouin] +* Version 6.1 (September 19, 2005) [Jean-Benoit Hardouin] +* Version 6.2 (January 31, 2006) [Jean-Benoit Hardouin] +* Release 6.3 (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */ +* Release 6.4 (January 19, 2007) [Jean-Benoit Hardouin] /*Tests to compare Loevinger coefficients to 0 identical to the MSP software (dichotomous and polytomous case)*/ +* Release 6.5 (January 22, 2007) [Jean-Benoit Hardouin] /*Correction of a bug concerning the p-values with the pair option*/ +* Release 6.6 (Februar 16, 2007) [Jean-Benoit Hardouin] /*Correction of a bug with the displaying of Easyness with polytomous items, option graph, option generror, improvements*/ +* Release 7: June 21, 2007 /*Check of monotonicity and Non intersection via P matrices*/ +* Release 7.1: November 6, 2008 /*Correction for the z-tests for the check of non intersection via P matrices*/ +* Release 7.2: November 19, 2008 /*Implementation of the GPN indexes*/ +* Release 7.3: August 15, 2009 /*Print the difficulties of the items instead of P(X=0)*/ +* Release 8: December 8, 2010 /*loevH is renamed loevh*/ +* Release 8.1: October 19, 2012 /*html option*/ +* Release 8.1.1 : November 20, 2012 /*graphs with the html option*/ +* Release 8.1.2 : December 7, 2012 /*minor correction*/ +* Release 8.1.3 : April 14, 2014 [Jean-Benoit Hardouin, Bastien Perrot] /*generror graph with the html option*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* Requiered Stata modules: +* -anaoption- (version 1) +* -traces- (version 3.2) +* -gengroup- (version 1) +* -guttmax- (version 1) +* +* News about this program :http://www.anaqol.org +* +* Copyright 2002-2012 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** + +program define loevh813 , rclass +version 8.2 +syntax varlist(min=2 numeric) [if] [,PAIRWise PAIR ppp pmm noADJust GENERror(string) REPlace GRaph MONOtonicity(string) NIRESTscore(string) NIPmatrix(string) HTML(string)] +preserve + +if "`html'" != "" { + set scheme sj + local htmlregion "graphregion(fcolor(white) ifcolor(white))" + di in gr "" +} + +local nbitems : word count `varlist' +tokenize `varlist' +tempname corr cov P1 P0 diff P11 P00 H1jk vHjk zHjk chi2Hjk dfHjk pvalHjk H1j vHj zHj pvalHj H1 vH zH pvalH Obs eGuttjk eGuttjk0 loevHjk eGuttj eGuttj0 loevHj eGutt eGutt0 loevH e1 e2 +tempfile loevHfile +qui save "`loevHfile'" + +if "`if'"!="" { + qui keep `if' +} + +if "`adjust'"!="" { + local adj=0 +} +else { + local adj=1 +} + +qui count +local nbobs=r(N) + +forvalues j=1/`nbitems' { + if "`pairwise'"=="" { + qui drop if ``j''==. + } +} +qui count +local nbtotindnm=r(N) + +matrix define `eGuttjk'=J(`nbitems',`nbitems',0) +matrix define `eGuttjk0'=J(`nbitems',`nbitems',0) +matrix define `loevHjk'=J(`nbitems',`nbitems',0) +matrix define `eGuttj'=J(1,`nbitems',0) +matrix define `eGuttj0'=J(1,`nbitems',0) +matrix define `loevHj'=J(1,`nbitems',0) +scalar define `eGutt'=0 +scalar define `eGutt0'=0 +scalar define `loevH'=0 +matrix define `Obs'=J(`nbitems',`nbitems',0) +matrix define `P00'=J(`nbitems',`nbitems',0) + +tempname modamax +scalar `modamax'=0 +local scoremax=0 +forvalues j=1/`nbitems' { + qui su ``j'' + local m`j'=r(max) + local scoremax=`scoremax'+`m`j'' + if r(max)>`modamax' { + scalar `modamax'=r(max) + } + local nbHjkNS`j'=0 +} + +/*if "`generror'"!=""&`modamax'!=1 { + di in ye "It is not possible to define the {cmd:generror} option with polytomous items" + local generror +} */ +*di "scoremax `scoremax'" +if "`graph'"!=""&`scoremax'>19 { + di in ye "The {cmd:graph} option is disabled because of a large number of possible scores (>20)" + local graph +} + +matrix define `cov'=J(`nbitems',`nbitems',0) +matrix define `corr'=J(`nbitems',`nbitems',0) +matrix define `P11'=J(`nbitems',`nbitems',0) +matrix define `H1jk'=J(`nbitems',`nbitems',0) +matrix define `vHjk'=J(`nbitems',`nbitems',0) +matrix define `zHjk'=J(`nbitems',`nbitems',0) +matrix define `pvalHjk'=J(`nbitems',`nbitems',0) +matrix define `P1'=J(1,`nbitems',0) +matrix define `P0'=J(1,`nbitems',0) +matrix define `diff'=J(1,`nbitems',0) +matrix define `H1j'=J(1,`nbitems',0) +matrix define `vHj'=J(1,`nbitems',0) +matrix define `zHj'=J(1,`nbitems',0) +matrix define `pvalHj'=J(1,`nbitems',0) + +forvalues j=1/`nbitems' { + qui su ``j'' + matrix `cov'[`j',`j']=r(Var) + matrix `corr'[`j',`j']=1 + local tmp=`j'+1 + qui count if ``j''!=. + matrix `Obs'[`j',`j']=r(N) + forvalues k=`tmp'/`nbitems' { + qui count if ``j''!=.&``k''!=. + matrix `Obs'[`j',`k']=r(N) + matrix `Obs'[`k',`j']=r(N) + qui corr ``j'' ``k'',cov + matrix `cov'[`j',`k']=r(cov_12) + matrix `cov'[`k',`j']=r(cov_12) + qui corr ``j'' ``k'' + matrix `corr'[`j',`k']=r(rho) + matrix `corr'[`k',`j']=r(rho) + matrix `zHjk'[`j',`k']=`corr'[`j',`k']*(`Obs'[`j',`k']-`adj')^.5 + matrix `zHjk'[`k',`j']=`H1jk'[`j',`k'] + matrix `pvalHjk'[`j',`k']=1-norm(`zHjk'[`j',`k']) + matrix `pvalHjk'[`k',`j']=`pvalHjk'[`j',`k'] + if `pvalHjk'[`j',`k']>0.05 { + local nbHjkNS`j'=`nbHjkNS`j''+1 + local nbHjkNS`k'=`nbHjkNS`k''+1 + } + forvalues mod1=1/`m`j'' { + forvalues mod2=1/`m`k'' { + qui count if ``j''<`mod1'&``k''>=`mod2'&``j''!=.&``k''!=. + scalar `e1'=r(N) + qui count if ``j''>=`mod1'&``k''<`mod2'&``j''!=.&``k''!=. + scalar `e2'=r(N) + matrix `eGuttjk'[`j',`k']=`eGuttjk'[`j',`k']+min(`e1',`e2') + qui count if ``j''<`mod1'&``j''!=.&``k''!=. + local t1=r(N) + qui count if ``k''<`mod2'&``j''!=.&``k''!=. + local t2=r(N) + qui count if ``j''>=`mod1'&``j''!=.&``k''!=. + local t3=r(N) + qui count if ``k''>=`mod2'&``j''!=.&``k''!=. + local t4=r(N) + if min(`e1',`e2')==`e1' { + matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t1'*`t4'/`Obs'[`j',`k'] + } + else { + matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t2'*`t3'/`Obs'[`j',`k'] + } + + } + } + qui count if ``j''==0&``k''==0 + matrix `P00'[`j',`k']=r(N)/`Obs'[`j',`k'] + matrix `P00'[`k',`j']=r(N)/`Obs'[`k',`j'] + if `modamax'==1 { + qui count if ``j''==1&``k''==1 + matrix `P11'[`j',`k']=r(N)/`Obs'[`j',`k'] + matrix `P11'[`k',`j']=r(N)/`Obs'[`k',`j'] + } + + matrix `eGuttjk'[`k',`j']=`eGuttjk'[`j',`k'] + matrix `eGuttj'[1,`j']=`eGuttj'[1,`j']+`eGuttjk'[`j',`k'] + matrix `eGuttj'[1,`k']=`eGuttj'[1,`k']+`eGuttjk'[`j',`k'] + matrix `eGuttjk0'[`k',`j']=`eGuttjk0'[`j',`k'] + matrix `eGuttj0'[1,`j']=`eGuttj0'[1,`j']+`eGuttjk0'[`j',`k'] + matrix `eGuttj0'[1,`k']=`eGuttj0'[1,`k']+`eGuttjk0'[`j',`k'] + + matrix `loevHjk'[`j',`k']=1-`eGuttjk'[`j',`k']/`eGuttjk0'[`j',`k'] + matrix `loevHjk'[`k',`j']=`loevHjk'[`j',`k'] + + } + qui count if ``j''!=. + local tmp=r(N) + qui count if ``j''==1 + matrix `P1'[1,`j']=r(N)/`tmp' + qui count if ``j''==0 + matrix `P0'[1,`j']=r(N)/`tmp' + qui su ``j'' + matrix `diff'[1,`j']=r(mean) + matrix `loevHj'[1,`j']=1-`eGuttj'[1,`j']/`eGuttj0'[1,`j'] + scalar `eGutt'=`eGutt'+`eGuttj'[1,`j']/2 + scalar `eGutt0'=`eGutt0'+`eGuttj0'[1,`j']/2 +} +scalar `H1'=0 +scalar `vH'=0 +scalar `zH'=0 +forvalues j=1/`nbitems'{ + forvalues k=1/`nbitems' { + if `j'!=`k' { + matrix `zHj'[1,`j']=`zHj'[1,`j']+`cov'[`j',`k'] + matrix `vHj'[1,`j']=`vHj'[1,`j']+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj') + } + if `j'<`k' { + scalar `zH'=`zH'+`cov'[`j',`k'] + scalar `vH'=`vH'+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj') + } + } + matrix `zHj'[1,`j']=`zHj'[1,`j']/sqrt(`vHj'[1,`j']) + matrix `pvalHj'[1,`j']=1-norm(`zHj'[1,`j']) +} +scalar `zH'=`zH'/sqrt(`vH') +scalar `pvalH'=1-norm(`zH') +scalar `loevH'=1-`eGutt'/`eGutt0' + +if `modamax'==1 { + local text="Easyness" + local value=1 + local col=23 +} +else { + local text="Difficulty" + local value=0 + local col=21 +} + +if "`html'" == "" { + di in green _col(35) "Observed" _col(47) "Expected" _col(93) "Number" + di in green _col(27) "Mean" _col(36) "Guttman" _col(48) "Guttman" _col(59) "Loevinger" _col(83) "H0: Hj<=0" _col(94) "of NS" + di in green "Item" _col(15) "Obs" _col(26) "Score" _col(37) "errors" _col(49) "errors" _col(61) "H coeff" _col(73) "z-stat." _col(85) "p-value" _col(96) "Hjk" + di in green "{hline 99}" + forvalues j=1/`nbitems' { + di in green "``j''" in yellow _col(15) `Obs'[`j',`j'] _col(25) %6.4f `diff'[1,`j'] _col(38) %5.0f `eGuttj'[1,`j'] _col(47) %8.2f `eGuttj0'[1,`j'] _col(61) %7.5f `loevHj'[1,`j'] _col(72) %8.4f `zHj'[1,`j'] _col(85) %7.5f `pvalHj'[1,`j'] _col(97) %2.0f `nbHjkNS`j'' + } + di in green "{hline 99}" +} +else { + di in gr "" + di in gr "" + di in gr "" + di in gr "" + di in gr "" + forvalues j=1/`nbitems' { + di in green "" + } +} + +if "`pairwise'"=="" { + local nb=`nbtotindnm' +} +else { + local nb=`nbobs' +} +if "`html'" == "" { + di in green "Scale" in yellow _col(15) `nb' _col(38) %5.0f `eGutt' _col(47) %8.2f `eGutt0' _col(61) %-8.5f `loevH' _col(71) %9.4f `zH' _col(85) %7.5f `pvalH' +} +else { + di in green "" + di in gr "
ItemObsMean
Score
Observed
Guttman
Errors
Expected
Guttman
Errors
Loevinger
H coeff
z-stat.H0: Hj ≤ 0
p-value
Number of
NS Hjk
``j''" `Obs'[`j',`j'] "" %6.4f `diff'[1,`j'] "" %5.0f `eGuttj'[1,`j'] "" %8.2f `eGuttj0'[1,`j'] "" %7.5f `loevHj'[1,`j'] "" %8.4f `zHj'[1,`j'] "" %7.5f `pvalHj'[1,`j'] "" %2.0f `nbHjkNS`j'' "
Scale" `nb' "" %5.0f `eGutt' "" %8.2f `eGutt0' "" %-8.5f `loevH' "" %9.4f `zH' "" %7.5f `pvalH' "
" +} + +if "`pair'"!="" { + if "`html'" == "" { + di + di in green _col(45) "Observed" _col(57) "Expected" + di in green _col(`=`col'+10') "`text'" _col(46) "Guttman" _col(58) "Guttman" _col(69) "Loevinger" _col(92) "H0: Hjk<=0" + di in green "Items" _col(25) "Obs" _col(29) "P(Xj=`value',Xk=`value')" _col(47) "errors" _col(59) "errors" _col(71) "H coeff" _col(83) "z-stat." _col(95) "p-value" + di in green "{hline 101}" + forvalues j=1/`nbitems' { + forvalues k=`=`j'+1'/`nbitems' { + qui count if ``j''!=. + local obs=r(N) + di in green "``j''" _col(10) "``k''" in yellow _col(25) `Obs'[`j',`k'] _col(35) %6.4f `P`value'`value''[`j',`k'] _col(48) %5.0f `eGuttjk'[`j',`k'] _col(57) %8.2f `eGuttjk0'[`j',`k'] _col(70) %8.5f `loevHjk'[`j',`k'] _col(81) %9.4f `zHjk'[`j',`k'] _col(95) %7.5f `pvalHjk'[`j',`k'] + } + } + di in green "{hline 101}" + } + else { + di in gr "" + di in gr "" + di in green "" + di in gr "" + forvalues j=1/`nbitems' { + forvalues k=`=`j'+1'/`nbitems' { + qui count if ``j''!=. + local obs=r(N) + di in green "" + } + } + di in green "
Summary of results by items pairs
Items" "`text'" "
Obs P(Xj=`value',Xk=`value')
Observed
Guttman
Errors
Expected
Guttman
Errors
Loevinger
H coeff
z-stat.H0: Hjk ≤ 0
p-value
" "``j''" "" "``k''" "" `Obs'[`j',`k'] "" %6.4f `P`value'`value''[`j',`k'] "" %5.0f `eGuttjk'[`j',`k'] "" %8.2f `eGuttjk0'[`j',`k'] "" %8.5f `loevHjk'[`j',`k'] "" %9.4f `zHjk'[`j',`k'] "" %7.5f `pvalHjk'[`j',`k'] "
" + } +} + +/*if `modamax'>1&"`ppp'"!="" { + di in green "It is not possible to obtain the P++ diagnostics with polytomous items" + local ppp +} +if `modamax'>1&"`pmm'"!="" { + di in green "It is not possible to obtain the P-- diagnostics with polytomous items" + local pmm +} */ + +tempname P11g P00g item id id2 p1 monlabel + +/*if "`monotonicity'"!=""&`modamax'>1 { + if "`html'" == "" { + di in green "It is not possible to obtain the latent monotonicity diagnostics with polytomous items" + } + else { + di in green "

It is not possible to obtain the latent monotonicity diagnostics with polytomous items

" + } + local monotonicity +} */ + +if "`monotonicity'"!="" { +*set trace on + if "`monotonicity'"=="*" { + anaoption + } + else { + anaoption,`monotonicity' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + +*set trace on + tempname score + qui genscore `varlist',score(`score') + if "`html'" == "" { + di + di in green _col(10) "Summary per item for check of monotonicity" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + } + else { + di in gr "" + di in gr "" + di in gr "" + } +*set trace on + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + tempname restscore`i' + qui gen `restscore`i''=`score'-``i'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroup`i' + qui gengroup `restscore`i'',newvariable(`restgroup`i'') minsize(`minsize') + local list`i'=r(list) + qui su `restgroup`i'' + local nbgroups`i'=r(max) + forvalues j=0/`nbgroups`i'' { + qui count if `restgroup`i''==`j' + local rgroup`j'=r(N) + } + local vi`i'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + } + forvalues l=1/`m`i'' { + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + local nbzvi`i'_`l'=0 + forvalues j=1/`nbgroups`i'' { + qui count if `restgroup`i''==`j'&``i''>=`l' + local nbitem`i'rgroup`j'_`l'=r(N) + forvalues k=1/`=`j'-1' { + local diff=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + if `nbitem`i'rgroup`j'_`l''!=`rgroup`j''&`nbitem`i'rgroup`k'_`l''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + } + local p=(`nbitem`i'rgroup`k'_`l''+`nbitem`i'rgroup`j'_`l'')/(`rgroup`j''+`rgroup`k'') + *local z=`diff'/sqrt(`p'*(1-`p')*(1/`rgroup`j''+1/`rgroup`k'')) + *di "local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) " + local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) + *di "=`z'" + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + } + if `j'==`nbgroups`i'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + if "`html'" == "" { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in gr "" + } + } + else { + if "`html'" == "" { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + else { + di in gr "" + } + } + } + if "`html'" == "" { + di in green "{dup 97:-}" + } + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + *set trace on + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + if `vi`i''!=0 { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in green "" + } + } + else { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in gr "" + } + + } + if "`details'"!=""&`i'!=`nbitems' { + if "`html'" == "" { + di in green "{dup 97:-}" + } + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + if "`html'" == "" { + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" + } + else { + di in green "
Summary per item for check of monotonicity
Items#ac#vi#vi / #acmaxvisumsum / #aczmax#zsigCrit
``i''>=`l'" %8.0f `ac`i'_m`l'' "" %8.0f `vi`i'_m`l'' "" %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' "" %6.4f `maxvi`i'_m`l'' "" %6.4f `sumvi`i'_m`l'' "" %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' "" %6.4f `zmaxvi`i'_m`l'' "" %8.0f `nbzvi`i'_m`l'' "
``i''>=`l'" %8.0f `ac`i'_m`l'' "" %8.0f `vi`i'_m`l'' "
``i''" %8.0f `ac`i'' "" %8.0f `vi`i'' "" %6.4f `=`vi`i''/`ac`i''' "" %6.4f `maxvi`i'' "" %6.4f `sumvi`i'' "" %6.4f `=`sumvi`i''/`ac`i''' "" %6.4f `zmaxvi`i'' "" %8.0f `nbzvi`i'' "" %4.0f `crit`i'' "
``i''" %8.0f `ac`i'' "" %8.0f `vi`i'' "" %4.0f `crit`i'' "
Total" `ac' "" %8.0f `vi' "" %6.4f `=`vi'/`ac'' "" %6.4f `maxvi' "" %6.4f `sumvi' "" %6.4f `=`sumvi'/`ac'' "" %6.4f `zmaxvi' "" %8.0f `nbzvi' "
" + } +} +/*if "`nirestscore'"!="" { +*set trace on + if "`nirestscore'"=="*" { + anaoption + } + else { + anaoption,`nirestscore' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + +*set trace on + tempname score + qui genscore `varlist',score(`score') + di + di in green _col(10) "Summary per item for check of Non-Intersection via Rest-score" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" +*set trace on + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + local vi`i'`j'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + } + forvalues j=1/`nbitems' { + if `j'!=`i' { + tempname restscorei`i'j`j' + qui gen `restscorei`i'j`j''=`score'-``i''-``j'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroupi`i'j`j' + qui gengroup `restscorei`i'j`j'',newvariable(`restgroupi`i'j`j'') minsize(`minsize') + local listi`i'j`j'=r(list) + qui su `restgroupi`i'j`j'' + local nbgroupsi`i'j`j'=r(max) + forvalues k=0/`nbgroupsi`i'j`j'' { + qui count if `restgroupi`i'j`j''==`k' + local rgroup`k'=r(N) + } + forvalues l=1/`m`i'' { + forvalues k=1/`m`j'' { + forvalues m=1/`nbgroupsi`i'j`j'' { + qui count if `restgroupi`i'j`j''==`m'&``i''>=`l'&``j''>=`k' + local nbitemi`i'j`j'rgroup`m'_`l'_`k'=r(N) + forvalues n=1/`=`m'-1' { + local diff=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m'' + if `nbitemi`i'j`j'rgroup`m'_`l'_`k''!=`rgroup`m''&`nbitemi`i'j`j'rgroup`m'_`l'_`k''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m'' + } + local p=(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+`nbitemi`i'j`j'rgroup`m'_`l'_`k'')/(`rgroup`m''+`rgroup`n'') + local z=abs(2*(sqrt(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)*sqrt(`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)-sqrt((`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k'')*`nbitemi`i'j`j'rgroup`m'_`l'_`k''))/sqrt(`rgroup`m''+`rgroup`n''-1)) + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + if `m'==`nbgroupsi`i'j`j'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + *local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + *local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + } + } + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + } + di in green "{dup 97:-}" + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + *set trace on + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + if `vi`i''!=0 { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + if "`details'"!=""&`i'!=`nbitems' { + di in green "{dup 97:-}" + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" +} */ + +if "`ppp'"!=""|"pmm"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + local list + local listi + local listm + local listv + forvalues i=1/`nbitems' { + forvalues l=1/`m`i'' { + tempname item`i'_`l' + qui gen `item`i'_`l''=``i''>=`l' if ``i''!=. + local list `list' ``i''_`l' + local listi `listi' ``i'' + local listm `listm' `l' + local listv `listv' `item`i'_`l'' + } + } + tempname matppp matpmm + matrix `matppp'=J(`=`scoremax'',`=`scoremax'+2',0) + matrix `matpmm'=J(`=`scoremax'',`=`scoremax'+2',0) + local row=1 + forvalues i=1/`nbitems' { + forvalues k=1/`m`i'' { + local col=1 + forvalues j=1/`nbitems' { + forvalues l=1/`m`j'' { + if `i'!=`j' { + qui count if `item`i'_`k''!=.&`item`j'_`l''!=. + local denom=r(N) + qui count if `item`i'_`k''==1&`item`j'_`l''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0&`item`j'_`l''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + } + else { + matrix `matppp'[`row',`col']=-1 + matrix `matpmm'[`row',`col']=-1 + } + local col=`col'+1 + } + } + qui count if `item`i'_`k''!=. + local denom=r(N) + qui count if `item`i'_`k''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + matrix `matppp'[`row',`=`scoremax'+2']=`i' + matrix `matpmm'[`row',`=`scoremax'+2']=`i' + local row=`row'+1 + } + } + matrix colnames `matppp'=`list' p1 item + matrix rownames `matppp'=`list' + matrix colnames `matpmm'=`list' p1 item + matrix rownames `matpmm'=`list' + if "`nipmatrix'"!="" { + if "`nipmatrix'"=="*" { + anaoption + } + else { + anaoption,`nipmatrix' + } + local minvi=`r(minvi)' + local siglevel=`r(siglevel)' + local minsize=`r(minsize)' + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + forvalues i=1/`nbitems' { + local nbacpp`i'=0 + local nbvipp`i'=0 + local maxvipp`i'=0 + local sumvipp`i'=0 + local zmaxpp`i'=0 + local nbsigzpp`i'=0 + local nbacmm`i'=0 + local nbvimm`i'=0 + local maxvimm`i'=0 + local sumvimm`i'=0 + local zmaxmm`i'=0 + local nbsigzmm`i'=0 + } + } + +} +tempfile temporaryfile +qui save `temporaryfile' + +if "`ppp'"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + drop * + qui svmat `matppp',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + sort p1 + qui set obs `=`scoremax'+1' + local listitem + forvalues i=1/`scoremax' { + local t=item[`i'] + local listitem `listitem' `t' + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + + if "`graph'"!="" { + if "`html'"!="" { + qui local saving "saving(`c(tmpdir)'/`html'_ppp,replace) nodraw" + } + qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P++ diagnostics") name(ppp,replace) `saving' xsize(2) ysize(2) + if "`html'"!="" { + qui graph use `c(tmpdir)'/`html'_ppp.gph + qui graph export `c(tmpdir)'/`html'_ppp.eps, replace + } + } + + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matpp + matrix define `matpp'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local ti:word `i' of `listv' + local tj:word `j' of `listv' + local t:word `j' of `list2' + matrix `matpp'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matpp'=`list2' + matrix rownames `matpp'=`list2' + + if "`ppp'"!="" { + if "`html'" == "" { + di + di in green _col(10) "P++ values per items pair (The values should be increasing in each column)" + matrix list `matpp',format(%5.3f) nohalf noheader + } + else { + di "" + di "" + di "" + matrixlisthtml `matpp' "%5.3f" + di "
P++ values per items pair
(The values should be increasing in each column)
" + if ("`graph'" != "") { + di "" + } + } + } + + label drop `monlabel' + *set trace on + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { +*di "`listv' `listw2'" + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacpp`ti' + *local ++nbacmm`tk' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==1&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==1&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "++ `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzpp`tj' + if abs(`z')>`zmaxpp`tj'' { + local zmaxpp`tj'=abs(`z') + } + local ++nbsigzpp`tk' + if abs(`z')>`zmaxpp`tk'' { + local zmaxpp`tk'=abs(`z') + } + } + } + } + } + } + } + } +/* if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!= `tk'&`ti'!=`tk'&`ti'!=`tj' { + local ++nbacpp`ti' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minsize'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + } + } + } + } + } + } +*/ +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + drop _all + qui svmat `matpmm',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + gsort -p1 + qui set obs `=`scoremax'+1' + forvalues i=1/`scoremax' { + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + if "`html'"!="" { + qui local saving "saving(`c(tmpdir)'/`html'_pmm,replace) nodraw" + *qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) `saving' + *graph use `c(tmpdir)'/`html'_pmm.gph + *qui graph export `c(tmpdir)'/`html'_pmm.eps, replace + } + *else { + qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) `saving' + *} + if "`html'"!="" { + qui graph use `c(tmpdir)'/`html'_pmm.gph + qui graph export `c(tmpdir)'/`html'_pmm.eps, replace + } + } + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matmm + matrix define `matmm'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local t:word `j' of `list2' + matrix `matmm'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matmm'=`list2' + matrix rownames `matmm'=`list2' + if "`pmm'"!="" { + if "`html'" == "" { + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + matrix list `matmm',format(%5.3f) nohalf noheader + } + else { + di "" + di "" + di "" + matrixlisthtml `matmm' "%5.3f" + di "
P-- values per items pair
(The values should be decreasing in each column)
" + if ("`graph'" != "") { + di "" + } + } + } + label drop `monlabel' + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { +*di "`listv' `listw2'" + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacmm`ti' + *local ++nbacmm`tk' + local diff=`matmm'[`k',`i']-`matmm'[`j',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvimm`tj' + local ++nbvimm`tk' + local sumvimm`tj'=`sumvimm`tj''+`diff' + local sumvimm`tk'=`sumvimm`tk''+`diff' + if `diff'>`maxvimm`tj'' { + local maxvimm`tj'=`diff' + } + if `diff'>`maxvimm`tk'' { + local maxvimm`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==0&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==0&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "-- `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzmm`tj' + if abs(`z')>`zmaxmm`tj'' { + local zmaxmm`tj'=abs(`z') + } + local ++nbsigzmm`tk' + if abs(`z')>`zmaxmm`tk'' { + local zmaxmm`tk'=abs(`z') + } + } + } + } + } + } + } + } +} + +if "`nipmatrix'" !="" { + *set trace on + if "`html'" == "" { + di + di in green _col(10) "Summary per item for check of non-Intersection via Pmatrix" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) /*in green "Minsize=" in ye %5.0f `minsize' _col(40)*/ in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + } + else { + di in gr "" + di in gr "" + di in gr "" + di in gr "" + } + forvalues i=1/`nbitems' { + local nbac`i'=`nbacpp`i''+`nbacmm`i'' + local nbvi`i'=`nbvipp`i''+`nbvimm`i'' + local maxvi`i'=max(`maxvipp`i'',`maxvimm`i'') + local sumvi`i'=`sumvipp`i''+`sumvimm`i'' + local zmaxvi`i'=max(`zmaxpp`i'',`zmaxmm`i'') + + local nbzsig`i'=`nbsigzpp`i''+`nbsigzmm`i'' + local zmax`i'=0 + *local nbsigz`i'=0 + local t=`loevHj'[1,`i'] +* di "local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmax`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' " + local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmaxvi`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' + + *di `nbac`i'' " " `nbvi`i'' " " `sumvi`i'' + if `nbvi`i''!=0 { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(33) %6.4f `=`nbvi`i''/`nbac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`nbac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzsig`i'' _col(93) %4.0f `crit`i'' + } + else { + di in green "" + } + } + else { + if "`html'" == "" { + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(93) %4.0f `crit`i'' + } + else { + di in green "" + } + } + } + if "`html'" != "" { + di in green "
Summary per item for check of non-Intersection via Pmatrix
" + di in gr "Minvi=" in ye %5.3f `minvi' "      Alpha=" in ye %5.3f `siglevel' "
Items#ac#vi#vi / #acmaxvisumsum / #aczmax#zsigCrit
" "``i''" "" %8.0f `nbac`i'' "" %8.0f `nbvi`i'' "" %6.4f `=`nbvi`i''/`nbac`i''' "" %6.4f `maxvi`i'' "" %6.4f `sumvi`i'' "" %6.4f `=`sumvi`i''/`nbac`i''' "" %6.4f `zmaxvi`i'' "" %8.0f `nbzsig`i'' "" %4.0f `crit`i'' "
" "``i''" "" %8.0f `nbac`i'' "" %8.0f `nbvi`i'' "" %4.0f `crit`i'' "
" + } +} + +/*if "`pmm'"!="" { + drop _all + matrix `P00g'=`P00',`P1'' + matrix colnames `P00g'=`varlist' `p1' + matrix rownames `P00g'=`varlist' + qui svmat `P00g' , names(col) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + forvalues i=1/`nbitems' { + qui replace `item'="``i''" if `id'==`i' + qui replace ``i''=. if `id'==`i' + local connect "`connect' l" + label define `monlabel' `i' "``i''", add + } + sort `p1' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + twoway connected `varlist' `id2',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) + } + format `varlist' %5.3f + label variable `id' "Item" + label value `id' `monlabel' + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + list `id' `varlist' , table compress separator(`nbitems') noobs divider + label drop `monlabel' +} + + + +if "`pairwise'"=="" { + restore, not +}*/ + + +*di "listw2:`listw2'" +*di "listv:`listv'" +*di "list:`list'" +*di "listi:`listi'" +*di "listm:`listm'" +*di "listitem:`listitem'" + + +qui use "`loevHfile'",clear +*set trace on +if "`generror'"!="" { + if "`replace'"!="" { + capture drop `generror'_0 + capture drop `generror'_H + capture drop `generror'_max + capture drop `generror'_GPN + capture drop `generror' + } + qui gen `generror'=0 + *forvalues i=1/`nbitems' { + * qui gen `generror'_``i''=0 + *} + qui gen `generror'_0=`eGutt0'/`nb' + local nbsteps:word count `listitem' + if "`pairwise'"=="" { + forvalues i=1/`nbitems' { + qui replace `generror'=. if ``i''==. + qui replace `generror'_0=. if ``i''==. + } + } + forvalues i=0/`nbsteps' { + di "qui guttmax `listitem', score(`i')" + qui guttmax `listitem', score(`i') + local errmax`i'=r(maxegutt) + } +* matrix list `P0' + forvalues i=1/`nbsteps' { + forvalues j=`=`i'+1'/`nbsteps' { + local w2i:word `i' of `listw2' + local w2j:word `j' of `listw2' + local itemi:word `w2i' of `listi' + local modai:word `w2i' of `listm' + local itemj:word `w2j' of `listi' + local modaj:word `w2j' of `listm' + qui replace `generror'=`generror'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + *qui replace `generror'_`itemi'=`generror'_`itemi'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + *qui replace `generror'_`itemj'=`generror'_`itemj'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. +* qui replace `generror'=`generror'+.5 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.&`P1'[1,`i']==`P1'[1,`j'] + *qui replace `generror'=`generror'+.5 if `P1'[1,`i']==`P1'[1,`j']&``i''==1&``j''==0 + } + } +* set trace on + tempvar flag + qui gen `flag'=0 + qui replace `flag'=1 `if' + qui replace `generror'=. if `flag'==0 + qui replace `generror'_0=. if `flag'==0 + qui gen `generror'_H=1-`generror'/`generror'_0 + tempvar score + qui genscore `varlist' `if',score(`score') + qui gen `generror'_max=. + forvalues i=1/`nbsteps' { + qui replace `generror'_max=`errmax`i'' if `score'==`i' + } + qui gen `generror'_GPN=`generror'/`generror'_max + label variable `generror' "Number of Guttman errors per individual" + label variable `generror'_H "H indice per individual" + if "`graph'"!="" { + qui histogram `generror',discrete freq name(errors,replace) + qui histogram `generror'_H,discrete freq name(H,replace) + } + if "`graph'" != "" & "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_errors,replace) nodraw" + qui histogram `generror',discrete freq name(errors,replace) title("Number of Guttman errors per individual") `saving' + qui graph use `c(tmpdir)'/`html'_errors.gph + qui graph export `c(tmpdir)'/`html'_errors.eps, replace + di " _char(34) " + } + + qui su `generror' ,det + local meane=r(mean) + local mede=r(p50) + local mine=r(min) + local maxe=r(max) + qui su `generror'_GPN ,det + local meanGPN=r(mean) + local medGPN=r(p50) + local minGPN=r(min) + local maxGPN=r(max) + di + di in green "Number of Guttman errors by individual" _col(50) in green "Normalized number of Guttamn errors by individual" + di in green " Mean number: " in ye %7.2f `meane' _col(50) in green " Mean number: " in ye %7.2f `meanGPN' + di in green " Median number: " in ye %7.2f `mede' _col(50) in green " Median number: " in ye %7.2f `medGPN' + di in green " Minimal number: " in ye %7.2f `mine' _col(50) in green " Minimal number: " in ye %7.2f `minGPN' + di in green " Maximal number: " in ye %7.2f `maxe' _col(50) in green " Maximal number: " in ye %7.2f `maxGPN' + di in green "Expected Guttman errors: " in ye %7.2f `=`eGutt0'/`nb'' + qui count if `generror'_H<0 + di in green " Rate of Hn<0: " in ye %7.2f `=r(N)/`nb'*100' "%" + +} + +matrix colnames `loevHj'=`varlist' +matrix rownames `loevHj'=Hj +return matrix loevHj `loevHj' + +matrix colnames `loevHjk'=`varlist' +matrix rownames `loevHjk'=`varlist' +return matrix loevHjk `loevHjk' + +matrix colnames `eGuttj'=`varlist' +matrix rownames `eGuttj'=ej +return matrix eGuttj `eGuttj' + +matrix colnames `eGuttjk'=`varlist' +matrix rownames `eGuttjk'=`varlist' +return matrix eGuttjk `eGuttjk' + +matrix colnames `eGuttj0'=`varlist' +matrix rownames `eGuttj0'=ejk +return matrix eGuttj0 `eGuttj0' + +matrix colnames `eGuttjk0'=`varlist' +matrix rownames `eGuttjk0'=`varlist' +return matrix eGuttjk0 `eGuttjk0' + +return scalar loevH=`loevH' +return scalar eGutt =`eGutt' +return scalar eGutt0 =`eGutt0' + +if `modamax'==1 { + matrix colnames `P11'=`varlist' + matrix rownames `P11'=`varlist' + return matrix P11 `P11' +} + +matrix colnames `P00'=`varlist' +matrix rownames `P00'=`varlist' +return matrix P00 `P00' + +if "`ppp'"!=""|"`nipmatrix'"!="" { + return matrix ppp=`matpp' +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + return matrix pmm=`matmm' +} + +matrix colnames `zHj'=`varlist' +matrix rownames `zHj'=zHj +return matrix zHj `zHj' + +matrix colnames `pvalHj'=`varlist' +matrix rownames `pvalHj'=pval +return matrix pvalHj `pvalHj' + +return scalar zH=`zH' +return scalar pvalH=`pvalH' +if "`pair'"!="" { + matrix colnames `zHjk'=`varlist' + matrix rownames `zHjk'=`varlist' + return matrix zHjk `zHjk' + + matrix colnames `pvalHjk'=`varlist' + matrix rownames `pvalHjk'=`varlist' + return matrix pvalHjk `pvalHjk' +} + +matrix colnames `Obs'=`varlist' +matrix rownames `Obs'=`varlist' +return matrix Obs `Obs' + + +capture restore, not + +end + diff --git a/Modules/ado/personal/l/loevh82.ado b/Modules/ado/personal/l/loevh82.ado new file mode 100644 index 0000000..2605c8d --- /dev/null +++ b/Modules/ado/personal/l/loevh82.ado @@ -0,0 +1,1347 @@ +*! Version 8.2 May 23, 2014 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : loevh +* Loevinger H indexes, Mokken Analysis +* Release 8.2 : May 23, 2014 /*remove html tags*/ +* +* +* Historic : +* Version 1 (August 20, 2002) [Jean-Benoit Hardouin] +* Version 2 (June 22, 2003) [Jean-Benoit Hardouin] +* Version 3 (December 1, 2003) [Jean-Benoit Hardouin] +* Version 4 (January 20, 2004) [Jean-Benoit Hardouin] +* Version 5 (March 22, 2004) [Jean-Benoit Hardouin] +* Version 6 (July 3, 2004) [Jean-Benoit Hardouin] +* Version 6.1 (September 19, 2005) [Jean-Benoit Hardouin] +* Version 6.2 (January 31, 2006) [Jean-Benoit Hardouin] +* Release 6.3 (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */ +* Release 6.4 (January 19, 2007) [Jean-Benoit Hardouin] /*Tests to compare Loevinger coefficients to 0 identical to the MSP software (dichotomous and polytomous case)*/ +* Release 6.5 (January 22, 2007) [Jean-Benoit Hardouin] /*Correction of a bug concerning the p-values with the pair option*/ +* Release 6.6 (Februar 16, 2007) [Jean-Benoit Hardouin] /*Correction of a bug with the displaying of Easyness with polytomous items, option graph, option generror, improvements*/ +* Release 7: June 21, 2007 /*Check of monotonicity and Non intersection via P matrices*/ +* Release 7.1: November 6, 2008 /*Correction for the z-tests for the check of non intersection via P matrices*/ +* Release 7.2: November 19, 2008 /*Implementation of the GPN indexes*/ +* Release 7.3: August 15, 2009 /*Print the difficulties of the items instead of P(X=0)*/ +* Release 8: December 8, 2010 /*loevH is renamed loevh*/ +* Release 8.1: October 19, 2012 /*html option*/ +* Release 8.1.1 : November 20, 2012 /*graphs with the html option*/ +* Release 8.1.2 : December 7, 2012 /*minor correction*/ +* Release 8.1.3 : April 14, 2014 [Jean-Benoit Hardouin, Bastien Perrot] /*generror graph with the html option*/ +* Release 8.2 : May 23, 2014 [Jean-Benoit Hardouin, Bastien Perrot] /*remove html tags*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* Requiered Stata modules: +* -anaoption- (version 1) +* -traces- (version 3.2) +* -gengroup- (version 1) +* -guttmax- (version 1) +* +* News about this program :http://www.anaqol.org +* +* Copyright 2002-2012 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** + +program define loevh82, rclass +version 8.2 +syntax varlist(min=2 numeric) [if] [,PAIRWise PAIR ppp pmm noADJust GENERror(string) REPlace GRaph MONOtonicity(string) NIRESTscore(string) NIPmatrix(string) HTML(string)] +preserve + +if "`html'" != "" { + set scheme sj + local htmlregion "graphregion(fcolor(white) ifcolor(white))" + di in gr "" + di "
"
+}
+
+local nbitems : word count `varlist'
+tokenize `varlist'
+tempname corr cov P1 P0 diff P11 P00 H1jk vHjk zHjk chi2Hjk dfHjk pvalHjk H1j vHj zHj pvalHj H1 vH zH pvalH Obs eGuttjk eGuttjk0 loevHjk eGuttj eGuttj0 loevHj eGutt eGutt0 loevH e1 e2
+tempfile loevHfile
+qui save "`loevHfile'"
+
+if "`if'"!="" {
+   qui keep `if'
+}
+
+if "`adjust'"!="" {
+   local adj=0
+}
+else {
+   local adj=1
+}
+
+qui count
+local nbobs=r(N)
+
+forvalues j=1/`nbitems' {
+   if "`pairwise'"=="" {
+       qui drop if ``j''==.
+   }
+}
+qui count
+local nbtotindnm=r(N)
+
+matrix define `eGuttjk'=J(`nbitems',`nbitems',0)
+matrix define `eGuttjk0'=J(`nbitems',`nbitems',0)
+matrix define `loevHjk'=J(`nbitems',`nbitems',0)
+matrix define `eGuttj'=J(1,`nbitems',0)
+matrix define `eGuttj0'=J(1,`nbitems',0)
+matrix define `loevHj'=J(1,`nbitems',0)
+scalar define `eGutt'=0
+scalar define `eGutt0'=0
+scalar define `loevH'=0
+matrix define `Obs'=J(`nbitems',`nbitems',0)
+matrix define `P00'=J(`nbitems',`nbitems',0)
+
+tempname modamax
+scalar `modamax'=0
+local scoremax=0
+forvalues j=1/`nbitems' {
+     qui su ``j''
+     local m`j'=r(max)
+     local scoremax=`scoremax'+`m`j''
+     if r(max)>`modamax' {
+        scalar `modamax'=r(max)
+     }
+     local nbHjkNS`j'=0
+}
+
+/*if "`generror'"!=""&`modamax'!=1 {
+   di in ye "It is not possible to define the {cmd:generror} option with polytomous items"
+   local generror
+} */
+*di "scoremax `scoremax'"
+
+if "`graph'"!="" & "`generror'"!=""{
+   local graph2 = "graph"
+}
+
+if "`graph'"!=""&`scoremax'>19 {
+   di in ye "The {cmd:graph} option is disabled because of a large number of possible scores (>20)"
+   local graph
+}
+
+matrix define `cov'=J(`nbitems',`nbitems',0)
+matrix define `corr'=J(`nbitems',`nbitems',0)
+matrix define `P11'=J(`nbitems',`nbitems',0)
+matrix define `H1jk'=J(`nbitems',`nbitems',0)
+matrix define `vHjk'=J(`nbitems',`nbitems',0)
+matrix define `zHjk'=J(`nbitems',`nbitems',0)
+matrix define `pvalHjk'=J(`nbitems',`nbitems',0)
+matrix define `P1'=J(1,`nbitems',0)
+matrix define `P0'=J(1,`nbitems',0)
+matrix define `diff'=J(1,`nbitems',0)
+matrix define `H1j'=J(1,`nbitems',0)
+matrix define `vHj'=J(1,`nbitems',0)
+matrix define `zHj'=J(1,`nbitems',0)
+matrix define `pvalHj'=J(1,`nbitems',0)
+
+forvalues j=1/`nbitems' {
+    qui su ``j''
+    matrix `cov'[`j',`j']=r(Var)
+    matrix `corr'[`j',`j']=1
+    local tmp=`j'+1
+    qui count if ``j''!=.
+    matrix `Obs'[`j',`j']=r(N)
+    forvalues k=`tmp'/`nbitems' {
+        qui count if ``j''!=.&``k''!=.
+        matrix `Obs'[`j',`k']=r(N)
+        matrix `Obs'[`k',`j']=r(N)
+        qui corr ``j'' ``k'',cov
+        matrix `cov'[`j',`k']=r(cov_12)
+        matrix `cov'[`k',`j']=r(cov_12)
+        qui corr ``j'' ``k''
+        matrix `corr'[`j',`k']=r(rho)
+        matrix `corr'[`k',`j']=r(rho)
+        matrix `zHjk'[`j',`k']=`corr'[`j',`k']*(`Obs'[`j',`k']-`adj')^.5
+        matrix `zHjk'[`k',`j']=`H1jk'[`j',`k']
+        matrix `pvalHjk'[`j',`k']=1-norm(`zHjk'[`j',`k'])
+        matrix `pvalHjk'[`k',`j']=`pvalHjk'[`j',`k']
+        if `pvalHjk'[`j',`k']>0.05 {
+           local nbHjkNS`j'=`nbHjkNS`j''+1
+           local nbHjkNS`k'=`nbHjkNS`k''+1
+        }
+        forvalues mod1=1/`m`j'' {
+            forvalues mod2=1/`m`k'' {
+                qui count if ``j''<`mod1'&``k''>=`mod2'&``j''!=.&``k''!=.
+                scalar `e1'=r(N)
+                qui count if ``j''>=`mod1'&``k''<`mod2'&``j''!=.&``k''!=.
+                scalar `e2'=r(N)
+                matrix `eGuttjk'[`j',`k']=`eGuttjk'[`j',`k']+min(`e1',`e2')
+                qui count if ``j''<`mod1'&``j''!=.&``k''!=.
+                local t1=r(N)
+                qui count if ``k''<`mod2'&``j''!=.&``k''!=.
+                local t2=r(N)
+                qui count if ``j''>=`mod1'&``j''!=.&``k''!=.
+                local t3=r(N)
+                qui count if ``k''>=`mod2'&``j''!=.&``k''!=.
+                local t4=r(N)
+                if min(`e1',`e2')==`e1' {
+                    matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t1'*`t4'/`Obs'[`j',`k']
+                }
+                else {
+                    matrix `eGuttjk0'[`j',`k']=`eGuttjk0'[`j',`k']+`t2'*`t3'/`Obs'[`j',`k']
+                }
+
+            }
+        }
+        qui count if ``j''==0&``k''==0
+        matrix `P00'[`j',`k']=r(N)/`Obs'[`j',`k']
+        matrix `P00'[`k',`j']=r(N)/`Obs'[`k',`j']
+        if `modamax'==1 {
+           qui count if ``j''==1&``k''==1
+           matrix `P11'[`j',`k']=r(N)/`Obs'[`j',`k']
+           matrix `P11'[`k',`j']=r(N)/`Obs'[`k',`j']
+        }
+
+        matrix `eGuttjk'[`k',`j']=`eGuttjk'[`j',`k']
+        matrix `eGuttj'[1,`j']=`eGuttj'[1,`j']+`eGuttjk'[`j',`k']
+        matrix `eGuttj'[1,`k']=`eGuttj'[1,`k']+`eGuttjk'[`j',`k']
+        matrix `eGuttjk0'[`k',`j']=`eGuttjk0'[`j',`k']
+        matrix `eGuttj0'[1,`j']=`eGuttj0'[1,`j']+`eGuttjk0'[`j',`k']
+        matrix `eGuttj0'[1,`k']=`eGuttj0'[1,`k']+`eGuttjk0'[`j',`k']
+
+        matrix `loevHjk'[`j',`k']=1-`eGuttjk'[`j',`k']/`eGuttjk0'[`j',`k']
+        matrix `loevHjk'[`k',`j']=`loevHjk'[`j',`k']
+
+    }
+    qui count if ``j''!=.
+    local tmp=r(N)
+    qui count if ``j''==1
+    matrix `P1'[1,`j']=r(N)/`tmp'
+    qui count if ``j''==0
+    matrix `P0'[1,`j']=r(N)/`tmp'
+    qui su ``j''
+    matrix `diff'[1,`j']=r(mean)
+    matrix `loevHj'[1,`j']=1-`eGuttj'[1,`j']/`eGuttj0'[1,`j']
+    scalar `eGutt'=`eGutt'+`eGuttj'[1,`j']/2
+    scalar `eGutt0'=`eGutt0'+`eGuttj0'[1,`j']/2
+}
+scalar `H1'=0
+scalar `vH'=0
+scalar `zH'=0
+forvalues j=1/`nbitems'{
+   forvalues k=1/`nbitems' {
+      if `j'!=`k' {
+         matrix `zHj'[1,`j']=`zHj'[1,`j']+`cov'[`j',`k']
+         matrix `vHj'[1,`j']=`vHj'[1,`j']+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj')
+      }
+      if `j'<`k' {
+         scalar `zH'=`zH'+`cov'[`j',`k']
+         scalar `vH'=`vH'+`cov'[`j',`j']*`cov'[`k',`k']/(`Obs'[`j',`k']-`adj')
+      }
+   }
+   matrix `zHj'[1,`j']=`zHj'[1,`j']/sqrt(`vHj'[1,`j'])
+   matrix `pvalHj'[1,`j']=1-norm(`zHj'[1,`j'])
+}
+scalar `zH'=`zH'/sqrt(`vH')
+scalar `pvalH'=1-norm(`zH')
+scalar `loevH'=1-`eGutt'/`eGutt0'
+
+if `modamax'==1 {
+   local text="Easyness"
+   local value=1
+   local col=23
+}
+else {
+   local text="Difficulty"
+   local value=0
+   local col=21
+}
+
+
+	di in green  _col(35) "Observed" _col(47) "Expected" _col(93) "Number"
+	di in green _col(27) "Mean" _col(36) "Guttman" _col(48) "Guttman" _col(59) "Loevinger" _col(83) "H0: Hj<=0" _col(94) "of NS"
+	di in green "Item"  _col(15) "Obs" _col(26) "Score" _col(37) "errors" _col(49) "errors" _col(61) "H coeff" _col(73) "z-stat." _col(85) "p-value" _col(96) "Hjk"
+	di in green "{hline 99}"
+	forvalues j=1/`nbitems' {
+     		di in green "``j''" in yellow _col(15) `Obs'[`j',`j'] _col(25) %6.4f `diff'[1,`j'] _col(38) %5.0f `eGuttj'[1,`j'] _col(47) %8.2f `eGuttj0'[1,`j'] _col(61) %7.5f `loevHj'[1,`j'] _col(72) %8.4f `zHj'[1,`j'] _col(85) %7.5f `pvalHj'[1,`j'] _col(97) %2.0f `nbHjkNS`j''
+	}
+	di in green "{hline 99}"
+
+
+
+if "`pairwise'"=="" {
+   local nb=`nbtotindnm'
+}
+else {
+   local nb=`nbobs'
+}
+
+	di in green "Scale" in yellow _col(15) `nb' _col(38) %5.0f `eGutt' _col(47) %8.2f `eGutt0' _col(61) %-8.5f `loevH' _col(71) %9.4f `zH' _col(85) %7.5f `pvalH'
+
+
+if "`pair'"!="" {
+	
+		di
+		di in green _col(45) "Observed" _col(57) "Expected"
+		di in green _col(`=`col'+10') "`text'" _col(46) "Guttman" _col(58) "Guttman" _col(69) "Loevinger" _col(92) "H0: Hjk<=0"
+		di in green "Items"  _col(25) "Obs" _col(29) "P(Xj=`value',Xk=`value')" _col(47) "errors" _col(59) "errors" _col(71) "H coeff" _col(83) "z-stat." _col(95) "p-value"
+		di in green "{hline 101}"
+		forvalues j=1/`nbitems' {
+		   forvalues k=`=`j'+1'/`nbitems' {
+		      qui count if ``j''!=.
+		      local obs=r(N)
+		      di in green "``j''" _col(10) "``k''" in yellow _col(25) `Obs'[`j',`k'] _col(35) %6.4f `P`value'`value''[`j',`k'] _col(48) %5.0f `eGuttjk'[`j',`k'] _col(57) %8.2f `eGuttjk0'[`j',`k'] _col(70) %8.5f `loevHjk'[`j',`k'] _col(81) %9.4f `zHjk'[`j',`k'] _col(95) %7.5f `pvalHjk'[`j',`k']
+		   }
+		}
+	   di in green "{hline 101}"
+	
+}
+
+/*if `modamax'>1&"`ppp'"!="" {
+   di in green "It is not possible to obtain the P++ diagnostics with polytomous items"
+   local ppp
+}
+if `modamax'>1&"`pmm'"!="" {
+   di in green "It is not possible to obtain the P-- diagnostics with polytomous items"
+   local pmm
+} */
+
+tempname P11g P00g item id id2 p1 monlabel
+
+/*if "`monotonicity'"!=""&`modamax'>1 {
+	if "`html'" == "" {
+		di in green "It is not possible to obtain the latent monotonicity diagnostics with polytomous items"
+	}
+	else {
+		di in green "

It is not possible to obtain the latent monotonicity diagnostics with polytomous items

" + } + local monotonicity +} */ + +if "`monotonicity'"!="" { +*set trace on + if "`monotonicity'"=="*" { + anaoption + } + else { + anaoption,`monotonicity' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + +*set trace on + tempname score + qui genscore `varlist',score(`score') + + di + di in green _col(10) "Summary per item for check of monotonicity" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + + +*set trace on + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + tempname restscore`i' + qui gen `restscore`i''=`score'-``i'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroup`i' + qui gengroup `restscore`i'',newvariable(`restgroup`i'') minsize(`minsize') + local list`i'=r(list) + qui su `restgroup`i'' + local nbgroups`i'=r(max) + forvalues j=0/`nbgroups`i'' { + qui count if `restgroup`i''==`j' + local rgroup`j'=r(N) + } + local vi`i'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + } + forvalues l=1/`m`i'' { + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + local nbzvi`i'_`l'=0 + forvalues j=1/`nbgroups`i'' { + qui count if `restgroup`i''==`j'&``i''>=`l' + local nbitem`i'rgroup`j'_`l'=r(N) + forvalues k=1/`=`j'-1' { + local diff=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + if `nbitem`i'rgroup`j'_`l''!=`rgroup`j''&`nbitem`i'rgroup`k'_`l''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitem`i'rgroup`k'_`l''/`rgroup`k''-`nbitem`i'rgroup`j'_`l''/`rgroup`j'' + } + local p=(`nbitem`i'rgroup`k'_`l''+`nbitem`i'rgroup`j'_`l'')/(`rgroup`j''+`rgroup`k'') + *local z=`diff'/sqrt(`p'*(1-`p')*(1/`rgroup`j''+1/`rgroup`k'')) + *di "local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) " + local z=abs(2*(sqrt(`nbitem`i'rgroup`j'_`l''+1)*sqrt(`rgroup`k''-`nbitem`i'rgroup`k'_`l''+1)-sqrt((`rgroup`j''-`nbitem`i'rgroup`j'_`l'')*`nbitem`i'rgroup`k'_`l''))/sqrt(`rgroup`j''+`rgroup`k''-1)) + *di "=`z'" + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + } + if `j'==`nbgroups`i'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + + } + else { + + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + + } + } + if "`html'" == "" { + di in green "{dup 97:-}" + } + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + *set trace on + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + if `vi`i''!=0 { + + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + + + } + else { + + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + + + } + if "`details'"!=""&`i'!=`nbitems' { + if "`html'" == "" { + di in green "{dup 97:-}" + } + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" + +} +/*if "`nirestscore'"!="" { +*set trace on + if "`nirestscore'"=="*" { + anaoption + } + else { + anaoption,`nirestscore' + } + local minvi=r(minvi) + local siglevel=r(siglevel) + local minsize=r(minsize) + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + +*set trace on + tempname score + qui genscore `varlist',score(`score') + di + di in green _col(10) "Summary per item for check of Non-Intersection via Rest-score" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) in green "Minsize=" in ye %5.0f `minsize' _col(40) in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" +*set trace on + local vi=0 + local ac=0 + local sumvi=0 + local maxvi=0 + local zmaxvi=0 + local nbzvi=0 + forvalues i=1/`nbitems' { + local vi`i'`j'=0 + local ac`i'=0 + local sumvi`i'=0 + local maxvi`i'=0 + local zmaxvi`i'=0 + local nbzvi`i'=0 + forvalues l=1/`m`i'' { + local vi`i'_m`l'=0 + local ac`i'_m`l'=0 + local sumvi`i'_m`l'=0 + local maxvi`i'_m`l'=0 + local zmaxvi`i'_m`l'=0 + local nbzvi`i'_m`l'=0 + local vi`i'_`l'=0 + local ac`i'_`l'=0 + local sumvi`i'_`l'=0 + local maxvi`i'_`l'=0 + local zmaxvi`i'_`l'=0 + } + forvalues j=1/`nbitems' { + if `j'!=`i' { + tempname restscorei`i'j`j' + qui gen `restscorei`i'j`j''=`score'-``i''-``j'' + local restscoremax`i'=`scoremax'-`m`i'' + tempname restgroupi`i'j`j' + qui gengroup `restscorei`i'j`j'',newvariable(`restgroupi`i'j`j'') minsize(`minsize') + local listi`i'j`j'=r(list) + qui su `restgroupi`i'j`j'' + local nbgroupsi`i'j`j'=r(max) + forvalues k=0/`nbgroupsi`i'j`j'' { + qui count if `restgroupi`i'j`j''==`k' + local rgroup`k'=r(N) + } + forvalues l=1/`m`i'' { + forvalues k=1/`m`j'' { + forvalues m=1/`nbgroupsi`i'j`j'' { + qui count if `restgroupi`i'j`j''==`m'&``i''>=`l'&``j''>=`k' + local nbitemi`i'j`j'rgroup`m'_`l'_`k'=r(N) + forvalues n=1/`=`m'-1' { + local diff=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m'' + if `nbitemi`i'j`j'rgroup`m'_`l'_`k''!=`rgroup`m''&`nbitemi`i'j`j'rgroup`m'_`l'_`k''!=0 { + local ac`i'_`l'=`ac`i'_`l''+1 + if `diff'>`minvi' { + local vi`i'_`l'=`vi`i'_`l''+1 + local sumvi`i'_`l'=`sumvi`i'_`l''+`diff' + if `diff'>`maxvi`i'_`l'' { + local maxvi`i'_`l'=`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''/`rgroup`m'' + } + local p=(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+`nbitemi`i'j`j'rgroup`m'_`l'_`k'')/(`rgroup`m''+`rgroup`n'') + local z=abs(2*(sqrt(`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)*sqrt(`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k''+1)-sqrt((`rgroup`m''-`nbitemi`i'j`j'rgroup`m'_`l'_`k'')*`nbitemi`i'j`j'rgroup`m'_`l'_`k''))/sqrt(`rgroup`m''+`rgroup`n''-1)) + if `z'>`=invnorm(1-`siglevel')' { + local nbzvi`i'_`l'=`nbzvi`i'_`l''+1 + } + if `z'>`zmaxvi`i'_`l'' { + local zmaxvi`i'_`l'=`z' + } + } + } + if `m'==`nbgroupsi`i'j`j'' { + local vi`i'_m`l'=`vi`i'_`l'' + local ac`i'_m`l'=`ac`i'_`l'' + local sumvi`i'_m`l'=`sumvi`i'_`l'' + local maxvi`i'_m`l'=`maxvi`i'_`l'' + local zmaxvi`i'_m`l'=`zmaxvi`i'_`l'' + *local nbzvi`i'_m`l'=`nbzvi`i'_`l'' + } + } + } + local vi`i'=`vi`i''+`vi`i'_`l'' + local ac`i'=`ac`i''+`ac`i'_`l'' + local sumvi`i'=`sumvi`i''+`sumvi`i'_`l'' + *local nbzvi`i'=`nbzvi`i''+`nbzvi`i'_`l'' + if `maxvi`i''<`maxvi`i'_`l'' { + local maxvi`i'=`maxvi`i'_`l'' + } + if `zmaxvi`i''<`zmaxvi`i'_`l'' { + local zmaxvi`i'=`zmaxvi`i'_`l'' + } + } + } + } + if "`details'"!=""&`m`i''!=1 { + forvalues l=1/`m`i'' { + if `vi`i'_m`l''!=0 { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' _col(33) %6.4f `=`vi`i'_m`l''/`ac`i'_m`l''' _col(43) %6.4f `maxvi`i'_m`l'' _col(53) %6.4f `sumvi`i'_m`l'' _col(63) %6.4f `=`sumvi`i'_m`l''/`ac`i'_m`l''' _col(73) %6.4f `zmaxvi`i'_m`l'' _col(81) %8.0f `nbzvi`i'_m`l'' + } + else { + di in green "``i''>=`l'" in yellow _col(15) %8.0f `ac`i'_m`l'' _col(23) %8.0f `vi`i'_m`l'' + } + } + di in green "{dup 97:-}" + } + local vi=`vi'+`vi`i'' + local ac=`ac'+`ac`i'' + local sumvi=`sumvi'+`sumvi`i'' + local nbzvi=`nbzvi'+`nbzvi`i'' + if `maxvi'<`maxvi`i'' { + local maxvi=`maxvi`i'' + } + if `zmaxvi'<`zmaxvi`i'' { + local zmaxvi=`zmaxvi`i'' + } + *set trace on + local t=`loevHj'[1,`i'] + local crit`i'=50*(.3-`t')+sqrt(`vi`i'')+100*`vi`i''/`ac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`ac`i''+5*`zmaxvi`i''+10*sqrt(`nbzvi`i'')+100*`nbzvi`i''/`ac`i'' + if `vi`i''!=0 { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(33) %6.4f `=`vi`i''/`ac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`ac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzvi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + else { + di in green "``i''" in yellow _col(15) %8.0f `ac`i'' _col(23) %8.0f `vi`i'' _col(93) %4.0f `crit`i'' _col(99) "{stata traces `varlist',rest nodrawcomb cumulative onlyone(``i'') thres(`list`i''):graph}" + } + if "`details'"!=""&`i'!=`nbitems' { + di in green "{dup 97:-}" + } + local ac=`ac'+`ac`i'' + local vi=`vi'+`vi`i'' + } + di in green "{hline 97}" + di in green "Total" in yellow _col(15) %8.0f `ac' _col(23) %8.0f `vi' _col(33) %6.4f `=`vi'/`ac'' _col(43) %6.4f `maxvi' _col(53) %6.4f `sumvi' _col(63) %6.4f `=`sumvi'/`ac'' _col(73) %6.4f `zmaxvi' _col(81) %8.0f `nbzvi' + di in green "{hline 97}" +} */ + +if "`ppp'"!=""|"pmm"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + local list + local listi + local listm + local listv + forvalues i=1/`nbitems' { + forvalues l=1/`m`i'' { + tempname item`i'_`l' + qui gen `item`i'_`l''=``i''>=`l' if ``i''!=. + local list `list' ``i''_`l' + local listi `listi' ``i'' + local listm `listm' `l' + local listv `listv' `item`i'_`l'' + } + } + tempname matppp matpmm + matrix `matppp'=J(`=`scoremax'',`=`scoremax'+2',0) + matrix `matpmm'=J(`=`scoremax'',`=`scoremax'+2',0) + local row=1 + forvalues i=1/`nbitems' { + forvalues k=1/`m`i'' { + local col=1 + forvalues j=1/`nbitems' { + forvalues l=1/`m`j'' { + if `i'!=`j' { + qui count if `item`i'_`k''!=.&`item`j'_`l''!=. + local denom=r(N) + qui count if `item`i'_`k''==1&`item`j'_`l''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0&`item`j'_`l''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + } + else { + matrix `matppp'[`row',`col']=-1 + matrix `matpmm'[`row',`col']=-1 + } + local col=`col'+1 + } + } + qui count if `item`i'_`k''!=. + local denom=r(N) + qui count if `item`i'_`k''==1 + local pos=r(N) + matrix `matppp'[`row',`col']=`=`pos'/`denom'' + qui count if `item`i'_`k''==0 + local pos=r(N) + matrix `matpmm'[`row',`col']=`=`pos'/`denom'' + matrix `matppp'[`row',`=`scoremax'+2']=`i' + matrix `matpmm'[`row',`=`scoremax'+2']=`i' + local row=`row'+1 + } + } + matrix colnames `matppp'=`list' p1 item + matrix rownames `matppp'=`list' + matrix colnames `matpmm'=`list' p1 item + matrix rownames `matpmm'=`list' + if "`nipmatrix'"!="" { + if "`nipmatrix'"=="*" { + anaoption + } + else { + anaoption,`nipmatrix' + } + local minvi=`r(minvi)' + local siglevel=`r(siglevel)' + local minsize=`r(minsize)' + local details `r(details)' + if `minsize'==0 { + if `nbobs'>500 { + local minsize=round(`nbobs'/10) + } + else if `nbobs'>250 { + local minsize=round(`nbobs'/5) + } + else { + local minsize=max(50,round(`nbobs'/3)) + } + } + forvalues i=1/`nbitems' { + local nbacpp`i'=0 + local nbvipp`i'=0 + local maxvipp`i'=0 + local sumvipp`i'=0 + local zmaxpp`i'=0 + local nbsigzpp`i'=0 + local nbacmm`i'=0 + local nbvimm`i'=0 + local maxvimm`i'=0 + local sumvimm`i'=0 + local zmaxmm`i'=0 + local nbsigzmm`i'=0 + } + } + +} +tempfile temporaryfile +qui save `temporaryfile' + +if "`ppp'"!=""|"`nipmatrix'"!=""|"`generror'"!="" { + drop * + qui svmat `matppp',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + sort p1 + qui set obs `=`scoremax'+1' + local listitem + forvalues i=1/`scoremax' { + local t=item[`i'] + local listitem `listitem' `t' + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + + if "`graph'"!="" { + if "`html'"!="" { + qui local saving "saving(`c(tmpdir)'/`html'_ppp,replace) nodraw" + } + qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P++ diagnostics") name(ppp,replace) `saving' xsize(2) ysize(2) + if "`html'"!="" { + qui graph use `c(tmpdir)'/`html'_ppp.gph + qui graph export `c(tmpdir)'/`html'_ppp.eps, replace + } + } + + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matpp + matrix define `matpp'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local ti:word `i' of `listv' + local tj:word `j' of `listv' + local t:word `j' of `list2' + matrix `matpp'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matpp'=`list2' + matrix rownames `matpp'=`list2' + + if "`ppp'"!="" { + + di + di in green _col(10) "P++ values per items pair (The values should be increasing in each column)" + matrix list `matpp',format(%5.3f) nohalf noheader + + if "`html'" != "" { + + //matrixlisthtml `matpp' "%5.3f" + + if ("`graph'" != "") { + di "" + } + } + } + + label drop `monlabel' + *set trace on + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { +*di "`listv' `listw2'" + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacpp`ti' + *local ++nbacmm`tk' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==1&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==1&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "++ `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzpp`tj' + if abs(`z')>`zmaxpp`tj'' { + local zmaxpp`tj'=abs(`z') + } + local ++nbsigzpp`tk' + if abs(`z')>`zmaxpp`tk'' { + local zmaxpp`tk'=abs(`z') + } + } + } + } + } + } + } + } +/* if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!= `tk'&`ti'!=`tk'&`ti'!=`tj' { + local ++nbacpp`ti' + local diff=`matpp'[`j',`i']-`matpp'[`k',`i'] + if `diff'>`minsize'&`diff'!=. { + local ++nbvipp`tj' + local ++nbvipp`tk' + local sumvipp`tj'=`sumvipp`tj''+`diff' + local sumvipp`tk'=`sumvipp`tk''+`diff' + if `diff'>`maxvipp`tj'' { + local maxvipp`tj'=`diff' + } + if `diff'>`maxvipp`tk'' { + local maxvipp`tk'=`diff' + } + } + } + } + } + } + } +*/ +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + drop _all + qui svmat `matpmm',names(col) + qui recode `list' (-1=.) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + local list2 + local listw2 + gsort -p1 + qui set obs `=`scoremax'+1' + forvalues i=1/`scoremax' { + local w:word `i' of `list' + qui replace `item'="`w'" if `id'==`i' + qui replace `w'=. if `id'==`i' + local connect "`connect' l" + local z=regexr("`w'","_",">=") + label define `monlabel' `i' "`z'", add + label variable `w' "`z'" + qui su p1 if `id'==`i' + local prop=r(mean) + qui replace `w'=`prop' in `=`scoremax'+1' + } + forvalues i=1/`scoremax' { + local v=`item'[`i'] + local list2 `list2' `v' + local v=`id'[`i'] + local listw2 `listw2' `v' + } + label define `monlabel' `=`scoremax'+1' "Prop",add + order `list2' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + if "`html'"!="" { + qui local saving "saving(`c(tmpdir)'/`html'_pmm,replace) nodraw" + *qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) `saving' + *graph use `c(tmpdir)'/`html'_pmm.gph + *qui graph export `c(tmpdir)'/`html'_pmm.eps, replace + } + *else { + qui twoway conn `list' `id2' in 1/`scoremax',`htmlregion' connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) `saving' + *} + if "`html'"!="" { + qui graph use `c(tmpdir)'/`html'_pmm.gph + qui graph export `c(tmpdir)'/`html'_pmm.eps, replace + } + } + format `list' %5.3f + label variable `id' "Item" + rename `id' Item + label value Item `monlabel' + qui replace Item=`=`scoremax'+1' in `=`scoremax'+1' + tempname matmm + matrix define `matmm'=J(`scoremax',`scoremax',0) + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + local t:word `j' of `list2' + matrix `matmm'[`i',`j']=`t'[`i'] + } + } + matrix colnames `matmm'=`list2' + matrix rownames `matmm'=`list2' + if "`pmm'"!="" { + + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + matrix list `matmm',format(%5.3f) nohalf noheader + + if "`html'" != "" { + //matrixlisthtml `matmm' "%5.3f" + + if ("`graph'" != "") { + di "" + } + } + } + label drop `monlabel' + qui use "`temporaryfile'",clear + if "`nipmatrix'"!="" { + forvalues i=1/`scoremax' { + forvalues j=1/`scoremax' { + forvalues k=`=`j'+1'/`scoremax' { +*di "`listv' `listw2'" + local ti:word `i' of `listitem' + local tj:word `j' of `listitem' + local tk:word `k' of `listitem' + if `tj'!=`tk'&`tj'!=`ti'&`ti'!=`tk'/*`matmm'[`k',`i']!=.&`matmm'[`j',`i']!=.*/ { + local ++nbacmm`ti' + *local ++nbacmm`tk' + local diff=`matmm'[`k',`i']-`matmm'[`j',`i'] + if `diff'>`minvi'&`diff'!=. { + local ++nbvimm`tj' + local ++nbvimm`tk' + local sumvimm`tj'=`sumvimm`tj''+`diff' + local sumvimm`tk'=`sumvimm`tk''+`diff' + if `diff'>`maxvimm`tj'' { + local maxvimm`tj'=`diff' + } + if `diff'>`maxvimm`tk'' { + local maxvimm`tk'=`diff' + } + local wi:word `i' of `listw2' + local wj:word `j' of `listw2' + local wk:word `k' of `listw2' + local li:word `wi' of `listv' + local lj:word `wj' of `listv' + local lk:word `wk' of `listv' + local ii:word `wi' of `list' + local ij:word `wj' of `list' + local ik:word `wk' of `list' + + qui count if `li'==0&`lj'==1&`lk'==0 + local a=r(N) + qui count if `li'==0&`lj'==0&`lk'==1 + local b=r(N) + local n=`a'+`b' + local k=`b' + local b=((2*`k'+1-`n')^2-10*`n')/(12*`n') + local z=sqrt(2*`k'+2+`b')-sqrt(2*`n'-2*`k'+`b') + *di "-- `li', `lj', `lk', `ii', `ij', `ik' : `n', `k', `z'" + + if abs(`z')>`=invnorm(1-`siglevel')'&`z'!=. { + local ++nbsigzmm`tj' + if abs(`z')>`zmaxmm`tj'' { + local zmaxmm`tj'=abs(`z') + } + local ++nbsigzmm`tk' + if abs(`z')>`zmaxmm`tk'' { + local zmaxmm`tk'=abs(`z') + } + } + } + } + } + } + } + } +} + +if "`nipmatrix'" !="" { + *set trace on + + di + di in green _col(10) "Summary per item for check of non-Intersection via Pmatrix" + di in green _col(10) "Minvi=" in ye %5.3f `minvi' _col(25) /*in green "Minsize=" in ye %5.0f `minsize' _col(40)*/ in green "Alpha=" in ye %5.3f `siglevel' + di + di in green "Items" _col(20) "#ac" _col(28) "#vi" _col(32) "#vi/#ac" _col(44) "maxvi" _col(56) "sum" _col(62) "sum/#ac" _col(75) "zmax" _col(84) "#zsig" _col(93) "Crit" + di in green "{hline 97}" + + + forvalues i=1/`nbitems' { + local nbac`i'=`nbacpp`i''+`nbacmm`i'' + local nbvi`i'=`nbvipp`i''+`nbvimm`i'' + local maxvi`i'=max(`maxvipp`i'',`maxvimm`i'') + local sumvi`i'=`sumvipp`i''+`sumvimm`i'' + local zmaxvi`i'=max(`zmaxpp`i'',`zmaxmm`i'') + + local nbzsig`i'=`nbsigzpp`i''+`nbsigzmm`i'' + local zmax`i'=0 + *local nbsigz`i'=0 + local t=`loevHj'[1,`i'] +* di "local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmax`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' " + local crit`i'=50*(.3-`t')+sqrt(`nbvi`i'')+100*`nbvi`i''/`nbac`i''+100*`maxvi`i''+10*sqrt(`sumvi`i'')+1000*`sumvi`i''/`nbac`i''+5*`zmaxvi`i''+10*sqrt(`nbzsig`i'')+100*`nbzsig`i''/`nbac`i'' + + *di `nbac`i'' " " `nbvi`i'' " " `sumvi`i'' + if `nbvi`i''!=0 { + + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(33) %6.4f `=`nbvi`i''/`nbac`i''' _col(43) %6.4f `maxvi`i'' _col(53) %6.4f `sumvi`i'' _col(63) %6.4f `=`sumvi`i''/`nbac`i''' _col(73) %6.4f `zmaxvi`i'' _col(81) %8.0f `nbzsig`i'' _col(93) %4.0f `crit`i'' + + } + else { + + di in green "``i''" in yellow _col(15) %8.0f `nbac`i'' _col(23) %8.0f `nbvi`i'' _col(93) %4.0f `crit`i'' + + } + } + +} + +/*if "`pmm'"!="" { + drop _all + matrix `P00g'=`P00',`P1'' + matrix colnames `P00g'=`varlist' `p1' + matrix rownames `P00g'=`varlist' + qui svmat `P00g' , names(col) + qui gen `id'=_n + qui gen str9 `item'="" + local connect "l" + forvalues i=1/`nbitems' { + qui replace `item'="``i''" if `id'==`i' + qui replace ``i''=. if `id'==`i' + local connect "`connect' l" + label define `monlabel' `i' "``i''", add + } + sort `p1' + qui gen `id2'=_n + label value `id2' `monlabel' + label variable `id2' " " + if "`graph'"!="" { + twoway connected `varlist' `id2',connect(`connect') ytitle("") title("P-- diagnostics") name(pmm,replace) + } + format `varlist' %5.3f + label variable `id' "Item" + label value `id' `monlabel' + di + di in green _col(10) "P-- values per items pair (The values should be decreasing in each column)" + list `id' `varlist' , table compress separator(`nbitems') noobs divider + label drop `monlabel' +} + + + +if "`pairwise'"=="" { + restore, not +}*/ + + +*di "listw2:`listw2'" +*di "listv:`listv'" +*di "list:`list'" +*di "listi:`listi'" +*di "listm:`listm'" +*di "listitem:`listitem'" + + +qui use "`loevHfile'",clear +*set trace on +if "`generror'"!="" { + if "`replace'"!="" { + capture drop `generror'_0 + capture drop `generror'_H + capture drop `generror'_max + capture drop `generror'_GPN + capture drop `generror' + } + qui gen `generror'=0 + *forvalues i=1/`nbitems' { + * qui gen `generror'_``i''=0 + *} + qui gen `generror'_0=`eGutt0'/`nb' + local nbsteps:word count `listitem' + if "`pairwise'"=="" { + forvalues i=1/`nbitems' { + qui replace `generror'=. if ``i''==. + qui replace `generror'_0=. if ``i''==. + } + } + forvalues i=0/`nbsteps' { + //di "qui guttmax `listitem', score(`i')" + qui guttmax `listitem', score(`i') + local errmax`i'=r(maxegutt) + } +* matrix list `P0' + forvalues i=1/`nbsteps' { + forvalues j=`=`i'+1'/`nbsteps' { + local w2i:word `i' of `listw2' + local w2j:word `j' of `listw2' + local itemi:word `w2i' of `listi' + local modai:word `w2i' of `listm' + local itemj:word `w2j' of `listi' + local modaj:word `w2j' of `listm' + qui replace `generror'=`generror'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + *qui replace `generror'_`itemi'=`generror'_`itemi'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. + *qui replace `generror'_`itemj'=`generror'_`itemj'+1 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=. +* qui replace `generror'=`generror'+.5 if `itemi'>=`modai'&`itemj'<`modaj'&`itemi'!=.&`itemj'!=.&`P1'[1,`i']==`P1'[1,`j'] + *qui replace `generror'=`generror'+.5 if `P1'[1,`i']==`P1'[1,`j']&``i''==1&``j''==0 + } + } +* set trace on + tempvar flag + qui gen `flag'=0 + qui replace `flag'=1 `if' + qui replace `generror'=. if `flag'==0 + qui replace `generror'_0=. if `flag'==0 + qui gen `generror'_H=1-`generror'/`generror'_0 + tempvar score + qui genscore `varlist' `if',score(`score') + qui gen `generror'_max=. + forvalues i=1/`nbsteps' { + qui replace `generror'_max=`errmax`i'' if `score'==`i' + } + qui gen `generror'_GPN=`generror'/`generror'_max + label variable `generror' "Number of Guttman errors per individual" + label variable `generror'_H "H indice per individual" + if "`graph2'"!="" { + qui histogram `generror',discrete width(0.5) freq name(errors,replace) + qui histogram `generror'_H,discrete freq name(H,replace) + } + if "`html'" != "" { + di + qui local saving "saving(`c(tmpdir)'/`html'_errors,replace) nodraw" + qui histogram `generror',discrete width(0.5) freq name(errors,replace) title("Number of Guttman errors per individual") `saving' + qui graph use `c(tmpdir)'/`html'_errors.gph + qui graph export `c(tmpdir)'/`html'_errors.eps, replace + di " _char(34) " + } + + qui su `generror' ,det + local meane=r(mean) + local mede=r(p50) + local mine=r(min) + local maxe=r(max) + qui su `generror'_GPN ,det + local meanGPN=r(mean) + local medGPN=r(p50) + local minGPN=r(min) + local maxGPN=r(max) + di + di in green "Number of Guttman errors by individual" _col(50) in green "Normalized number of Guttamn errors by individual" + di in green " Mean number: " in ye %7.2f `meane' _col(50) in green " Mean number: " in ye %7.2f `meanGPN' + di in green " Median number: " in ye %7.2f `mede' _col(50) in green " Median number: " in ye %7.2f `medGPN' + di in green " Minimal number: " in ye %7.2f `mine' _col(50) in green " Minimal number: " in ye %7.2f `minGPN' + di in green " Maximal number: " in ye %7.2f `maxe' _col(50) in green " Maximal number: " in ye %7.2f `maxGPN' + di in green "Expected Guttman errors: " in ye %7.2f `=`eGutt0'/`nb'' + qui count if `generror'_H<0 + di in green " Rate of Hn<0: " in ye %7.2f `=r(N)/`nb'*100' "%" + +} + +matrix colnames `loevHj'=`varlist' +matrix rownames `loevHj'=Hj +return matrix loevHj `loevHj' + +matrix colnames `loevHjk'=`varlist' +matrix rownames `loevHjk'=`varlist' +return matrix loevHjk `loevHjk' + +matrix colnames `eGuttj'=`varlist' +matrix rownames `eGuttj'=ej +return matrix eGuttj `eGuttj' + +matrix colnames `eGuttjk'=`varlist' +matrix rownames `eGuttjk'=`varlist' +return matrix eGuttjk `eGuttjk' + +matrix colnames `eGuttj0'=`varlist' +matrix rownames `eGuttj0'=ejk +return matrix eGuttj0 `eGuttj0' + +matrix colnames `eGuttjk0'=`varlist' +matrix rownames `eGuttjk0'=`varlist' +return matrix eGuttjk0 `eGuttjk0' + +return scalar loevH=`loevH' +return scalar eGutt =`eGutt' +return scalar eGutt0 =`eGutt0' + +if `modamax'==1 { + matrix colnames `P11'=`varlist' + matrix rownames `P11'=`varlist' + return matrix P11 `P11' +} + +matrix colnames `P00'=`varlist' +matrix rownames `P00'=`varlist' +return matrix P00 `P00' + +if "`ppp'"!=""|"`nipmatrix'"!="" { + return matrix ppp=`matpp' +} +if "`pmm'"!=""|"`nipmatrix'"!="" { + return matrix pmm=`matmm' +} + +matrix colnames `zHj'=`varlist' +matrix rownames `zHj'=zHj +return matrix zHj `zHj' + +matrix colnames `pvalHj'=`varlist' +matrix rownames `pvalHj'=pval +return matrix pvalHj `pvalHj' + +return scalar zH=`zH' +return scalar pvalH=`pvalH' +if "`pair'"!="" { + matrix colnames `zHjk'=`varlist' + matrix rownames `zHjk'=`varlist' + return matrix zHjk `zHjk' + + matrix colnames `pvalHjk'=`varlist' + matrix rownames `pvalHjk'=`varlist' + return matrix pvalHjk `pvalHjk' +} + +matrix colnames `Obs'=`varlist' +matrix rownames `Obs'=`varlist' +return matrix Obs `Obs' + + +capture restore, not + +end + diff --git a/Modules/ado/personal/l/lstrfun.ado b/Modules/ado/personal/l/lstrfun.ado new file mode 100644 index 0000000..14a9ccd --- /dev/null +++ b/Modules/ado/personal/l/lstrfun.ado @@ -0,0 +1,368 @@ +*! lstrfun Version 1.2 dan_blanchette@unc.edu 09Aug2011 +*! the carolina population center, unc-ch +* -Nick Cox let me know that the regular expersion functions were available in Stata 9.2 +* but were just not documented +* lstrfun Version 1.1 dan_blanchette@unc.edu 22Jul2011 +** -it now can run regexr(), regexm() and regexs() +** lstrfun Version 1.0 dan_blanchette@unc.edu 09Aug2010 +** Center for Entrepreneurship and Innovation Duke University's Fuqua School of Business +* modify long local macros with mata string functions + +program define lstrfun +version 9.2 + +syntax [namelist(local)] [, lower(string asis) upper(string asis) proper(string asis) /// + ltrim(string asis) itrim(string asis) rtrim(string asis) trim(string asis) /// + substr(string asis) subinstr(string asis) subinword(string asis) /// + reverse(string asis) strdup(string asis) soundex(string asis) soundex_nara(string asis) /// + strlen(string asis) strpos(string asis) _substr(string asis) indexnot(string asis) /// + strmatch(string asis) regexr(string asis) regexm(string asis) regexms(string asis) /// + ] + +if missing(`"`namelist'"') { + display as error "need to specify a local macro variable name to modify or create" + exit 198 +} +local n_locals : word count `namelist' +if `n_locals' > 1 { + display as error "only one local macro variable name can be submitted" + exit 198 +} + +// local m1= !missing(`"`macval(lower)'"' +// says "too few quotes" when a fairly long macro submitted but only inside a program +// using short macro names and no spaces to make it even shoerter +local m1=`"`macval(lower)'"'!="" +local m2=`"`macval(proper)'"'!="" +local m3=`"`macval(upper)'"'!="" +local m4=`"`macval(ltrim)'"'!="" +local m5=`"`macval(itrim)'"'!="" +local m6=`"`macval(rtrim)'"'!="" +local m7=`"`macval(trim)'"'!="" +local m8=`"`macval(substr)'"'!="" +local m9=`"`macval(subinstr)'"'!="" +local m10=`"`macval(subinword)'"'!="" +local m11=`"`macval(strdup)'"'!="" +local m12=`"`macval(reverse)'"'!="" +local m13=`"`macval(soundex)'"'!="" +local m14=`"`macval(soundex_nara)'"'!="" +local m15=`"`macval(strlen)'"'!="" +local m16=`"`macval(strpos)'"'!="" +local m17=`"`macval(_substr)'"'!="" +local m18=`"`macval(indexnot)'"'!="" +local m19=`"`macval(strmatch)'"'!="" +local m20=`"`macval(regexr)'"'!="" +local m21=`"`macval(regexm)'"'!="" +local m22=`"`macval(regexms)'"'!="" + + +if `m1' /// + + `m2' /// + + `m3' /// + + `m4' /// + + `m5' /// + + `m6' /// + + `m7' /// + + `m8' /// + + `m9' /// + + `m10' /// + + `m11' /// + + `m12' /// + + `m13' /// + + `m14' /// + + `m15' /// + + `m16' /// + + `m17' /// + + `m18' /// + + `m19' /// + + `m20' /// + + `m21' > 1 { + display as error "you can only specify 1 option in {helpb lstrfun:lstrfun}" + exit 198 + } + +if `m1' == 1 { + mata: long_lower(`macval(lower)') + c_local `namelist' `"`macval(lower)'"' +} +else if `m2' == 1 { + mata: long_proper(`macval(proper)') + c_local `namelist' `"`macval(proper)'"' +} +else if `m3' == 1 { + mata: long_upper(`macval(upper)') + c_local `namelist' `"`macval(upper)'"' +} +else if `m4' == 1 { + mata: long_ltrim(`macval(ltrim)') + c_local `namelist' `"`macval(ltrim)'"' +} +else if `m5' == 1 { + mata: long_itrim(`macval(itrim)') + c_local `namelist' `"`macval(itrim)'"' +} +else if `m6' == 1 { + mata: long_rtrim(`macval(rtrim)') + c_local `namelist' `"`macval(rtrim)'"' +} +else if `m7' == 1 { + mata: long_trim(`macval(trim)') + c_local `namelist' `"`macval(trim)'"' +} +else if `m8' == 1 { + mata: long_substr(`macval(substr)') + c_local `namelist' `"`macval(substr)'"' +} +else if `m9' == 1 { + mata: long_subinstr(`macval(subinstr)') + c_local `namelist' `"`macval(subinstr)'"' +} +else if `m10' == 1 { + mata: long_subinword(`macval(subinword)') + c_local `namelist' `"`macval(subinword)'"' +} +else if `m11' == 1 { + mata: long_strdup(`macval(strdup)') + local len_strdup : length local strdup + if `len_strdup' < `len_m_var' { + local clen_m_var= string(`len_m_var',"%11.0gc") + if c(SE) & c(maxvar) < 32767 & `len_m_var' <= 1081511 { + display as error "{cmd:strdup()} generated a string that has `clen_m_var' characters which is more than Stata can handle" /// + " when {helpb maxvar:maxvar} is set to `c(maxvar)'." + display as error "Increase your {helpb maxvar:maxvar} setting higher and try again." + exit 149 + } + else { + display as error "{cmd:strdup()} generated a string that has `clen_m_var' characters (which is more than Stata can handle)" + exit 149 + } + } + c_local `namelist' `"`macval(strdup)'"' +} +else if `m12' == 1 { + mata: long_reverse(`macval(reverse)') + c_local `namelist' `"`macval(reverse)'"' +} +else if `m13' == 1 { + mata: long_soundex(`macval(soundex)') + c_local `namelist' `"`macval(soundex)'"' +} +else if `m14' == 1 { + mata: long_soundex_nara(`macval(soundex_nara)') + c_local `namelist' `"`macval(soundex_nara)'"' +} +else if `m15' == 1 { + mata: long_strlen(`macval(strlen)') + c_local `namelist' `"`macval(strlen)'"' +} +else if `m16' == 1 { + mata: long_strpos(`macval(strpos)') + c_local `namelist' `"`macval(strpos)'"' +} +else if `m17' == 1 { + mata: long__substr(`macval(_substr)') + c_local `namelist' `"`macval(_substr)'"' +} +else if `m18' == 1 { + mata: long_indexnot(`macval(indexnot)') + c_local `namelist' `"`macval(indexnot)'"' +} +else if `m19' == 1 { + mata: long_strmatch(`macval(strmatch)') + c_local `namelist' `"`macval(strmatch)'"' +} +else if `m20' == 1 { + mata: long_regexr(`macval(regexr)') + c_local `namelist' `"`macval(regexr)'"' +} +else if `m21' == 1 { + mata: long_regexm(`macval(regexm)') + c_local `namelist' `"`macval(regexm)'"' +} +else if `m22' == 1 { + mata: long_regexms(`macval(regexms)') + c_local `namelist' `"`macval(regexms)'"' +} +else { + display as error "need to specify an option in {helpb lstrfun:lstrfun}" + exit 198 +} + + +end + + +mata: +void long_lower(string scalar lstring) +{ + string scalar m_var + m_var= strlower(lstring) + st_local("lower",m_var) +} + +void long_proper(string scalar lstring) +{ + string scalar m_var + m_var= strproper(lstring) + st_local("proper",m_var) +} + +void long_upper(string scalar lstring) +{ + string scalar m_var + m_var= strupper(lstring) + st_local("upper",m_var) +} + +void long_ltrim(string scalar lstring) +{ + string scalar m_var + m_var= strltrim(lstring) + st_local("ltrim",m_var) +} + +void long_itrim(string scalar lstring) +{ + string scalar m_var + m_var= stritrim(lstring) + st_local("itrim",m_var) +} + +void long_rtrim(string scalar lstring) +{ + string scalar m_var + m_var= strrtrim(lstring) + st_local("rtrim",m_var) +} + +void long_trim(string scalar lstring) +{ + string scalar m_var + m_var= strtrim(lstring) + st_local("trim",m_var) +} + +void long_substr(string scalar lstring, real scalar start, real scalar length) +{ + string scalar m_var + m_var= substr(lstring,start,length) + st_local("substr",m_var) +} + +void long_subinstr(string scalar lstring, string scalar old, string scalar snew, real scalar cnt) +{ + string scalar m_var + m_var= subinstr(lstring,old,snew,cnt) + st_local("subinstr",m_var) +} + +void long_subinword(string scalar lstring, string scalar old, string scalar snew, real scalar cnt) +{ + string scalar m_var + m_var= subinword(lstring,old,snew,cnt) + st_local("subinword",m_var) +} + +void long_strdup(string scalar lstring, real scalar n) +{ + string scalar m_var + m_var= n*lstring + real scalar len_lstring + len_lstring= n * strlen(lstring) + real scalar len_m_var + len_m_var= strlen(m_var) + string scalar slen_m_var + slen_m_var= strofreal(len_m_var) + st_local("len_m_var",slen_m_var) + st_local("strdup",m_var) +} + +void long_reverse(string scalar lstring) +{ + string scalar m_var + m_var= strreverse(lstring) + st_local("reverse",m_var) +} + +void long_soundex(string scalar lstring) +{ + string scalar m_var + m_var= soundex(lstring) + st_local("soundex",m_var) +} + +void long_soundex_nara(string scalar lstring) +{ + string scalar m_var + m_var= soundex_nara(lstring) + st_local("soundex_nara",m_var) +} + +void long_strlen(string scalar lstring) +{ + string scalar m_var + real scalar nm_var + nm_var= strlen(lstring) + m_var= strofreal(nm_var) + st_local("strlen",m_var) +} + +void long_strpos(string scalar lstring, string scalar needle) +{ + string scalar m_var + real scalar nm_var + nm_var= strpos(lstring,needle) + m_var= strofreal(nm_var) + st_local("strpos",m_var) +} + +void long__substr(string scalar lstring, string scalar tosub, real scalar pos) +{ + _substr(lstring, tosub, pos) + st_local("_substr",lstring) +} + +void long_indexnot(string scalar lstring, string scalar needle) +{ + string scalar m_var + real scalar nm_var + nm_var= indexnot(lstring,needle) + m_var= strofreal(nm_var) + st_local("indexnot",m_var) +} + +void long_strmatch(string scalar lstring, string scalar pattern) +{ + string scalar m_var + real scalar nm_var + nm_var= strmatch(lstring,pattern) + m_var= strofreal(nm_var) + st_local("strmatch",m_var) +} + +void long_regexr(string scalar lstring, string scalar pattern, string scalar rep) +{ + string scalar m_var + m_var= regexr(lstring,pattern,rep) + st_local("regexr",m_var) +} + +void long_regexm(string scalar lstring, string scalar pattern) +{ + string scalar m_var + real scalar nm_var + nm_var= regexm(lstring,pattern) + m_var= strofreal(nm_var) + st_local("regexm",m_var) +} + +void long_regexms(string scalar lstring, string scalar pattern, real scalar ss) +{ + string scalar m_var + if (regexm(lstring,pattern)) { + m_var= regexs(ss) + } + st_local("regexms",m_var) +} + +end diff --git a/Modules/ado/personal/m/Multirsoort_indicefit.ado b/Modules/ado/personal/m/Multirsoort_indicefit.ado new file mode 100644 index 0000000..6bf538b --- /dev/null +++ b/Modules/ado/personal/m/Multirsoort_indicefit.ado @@ -0,0 +1,1530 @@ +*! version 1.4 29January2014 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* rsoort: Response Shift detection with the Oort procedure +* +* Historic: +* Version 1 (2013-02-25): Jean-Benoit Hardouin +* Version 1.1 (2013-06-03): Jean-Benoit Hardouin /*some improvements*/ +* Version 1.2 (2013-06-03): Jean-Benoit Hardouin /*model1 model2 model3 and covariances options*/ +* Version 1.3 (2013-06-03): Jean-Benoit Hardouin /**/ +* Version 1.4 (2014-01-29): Jean-Benoit Hardouin /*add an iterate option on model 1*/ +* +* +* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France +* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam" +* jean-benoit.hardouin@univ-nantes.fr +* +* Copyright 2013-2014 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*************************************************************************** +MODIFICATIONS ALICE +- précedemment, boucles pour les différents cas THA, qui permettent le test général, la hiérarchie et l'ajustement. +- avant l'été 2015, modification pour l'amélioration du fit des modèles 1 et 4 +- (22/09/2015): modification dans l'ajout pour l'amélioration du fit avec le fichier déposé en temporaire +-(12/2015): modification, dans les cas sans hierarchie, programme recodé pour la boucle typeRS=2 car pb dans les contraintes +-(01/2016) : modification de l'étape 4, lorsque la procédure entre dans la boucle pour les covariances, M4 modifié (car il était équivalent au M1 donc faux) + réinitialisation de arret_covfit avant modele 4 + +*****************************************************************************************/ + + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + + +program define Multirsoort_indicefit,rclass + +syntax varlist(min=2 numeric) [if] [in] [,METHod(string) nocov12 UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPrioritization(varlist) noSearch html(string) model1 model2 model4 COVariances(string) MATrixrs(string) Cas(string)] +tempfile saveMultirsoort_indicefit +qui save `saveMultirsoort_indicefit',replace +preserve + +if "`matrixrs'"!="" { + if "`uniformrecalibration'"!="" { + di in red "You cannot use the {bf:matrixrs} and the {bf:uniformrecalibration} options in the same time" + error + } + if "`nonuniformrecalibration'"!="" { + di in red "You cannot use the {bf:matrixrs} and the {bf:nonuniformrecalibration} options in the same time" + error + } + if "`reprioritization'"!="" { + di in red "You cannot use the {bf:matrixrs} and the {bf:reprioritization} options in the same time" + error + } +} + + +if "`html'" != "" { + di "" +} + + +if "`if'"!=""|"`in'"!="" { + qui keep `if' `in' +} + +tokenize `varlist' +local nbitems:word count `varlist' +local mod=mod(`nbitems',2) +if `mod'!=0 { + di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2" + error +} + +if "`method'"=="" { + local method "ml" +} +local nbitems=`nbitems'/2 + +if "`html'"== "" { + di _col(20) "{hline 30}" + di _col(20) in gr "Time 1" _col(40) "Time 2" + di _col(20) "{hline 30}" + forvalues i=1/`nbitems' { + di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''" + } + di _col(20) "{hline 30}" +} +else { + di "" + di "" + di "" + di "" + forvalues i=1/`nbitems' { + di "" + } + di "
Time 1Time2
``i''``=`i'+`nbitems'''
" +} + +/************************************************************************************************************** +Model 1 +***************************************************************************************************************/ + +if "`model1'"=="" { + local qui qui +} +else { + local qui +} +local cov12b +forvalues i=1/`nbitems' { + local cov12b `cov12b' e.``i''*e.``=`i'+`nbitems''' +} +if "`cov12'"!="" { + local cov12b +} + +/*if ("`cas'"=="cas3" | "`cas'"=="cas4" | "`cas'"=="cas5" | "`cas'"=="cas6" ) {*/ + +`qui' sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method') cov(`cov12b' `covariances') iterate(100) +tempname b +matrix `b'=r(table) + +estat gof +local rmsea1=r(rmsea) + + +local covfit +local r =999 +local arret_covfit=999 + +while `rmsea1' >0.08 { + +di"`rmsea1'" +tempfile data +save `data', replace +di "`data'" +/*on récupère les indices de modifs*/ +estat mindice +matrix indice = r(mindices) +clear +/* on ajoute dans une colonne le nom des items concernés*/ +svmat2 indice , r(nomcol) full + +/*on controle l'ajout de covariances uniquement sur un même temps*/ +gen tmp=substr(nomcol,1,3) +drop if tmp!="cov" + +gen tmp1=substr(nomcol,11,1) +gen tmp2=substr(nomcol,20,1) +drop if tmp1 != tmp2 + +matrix list indice + +/*On vérifie qu'il reste des lignes de covariances à ajouter*/ +local vide = indice1[1] +if "`vide'" == "." { +local covfit= "`covfit'" +local arret_covfit=1 +local rmsea1=0 +use "`data'",clear + +} +else { +/*on trie par ordre croissant pour ajouter les covariances les plus influentes*/ +local arret_covfit=0 +gsort - indice1 + +local tmp3=nomcol[1] +lstrfun e, subinstr("`tmp3'","cov(","",.) +lstrfun e, subinstr("`e'",")","",.) +lstrfun e, subinstr("`e'",":_cons","",.) +lstrfun e, subinstr("`e'",",","*",.) + + +local covfit= "`covfit' `e'" +use "`data'", clear + + +`qui' sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method') cov(`cov12b' `covariances' `covfit') iterate(100) +tempname b +matrix `b'=r(table) + +estat gof +local rmsea1=r(rmsea) + +di "`covfit'" + +local tmp4="`covfit'" +lstrfun r, subinstr("`tmp4'","e.itemA","0",.) +lstrfun r, subinstr("`r'","e.itemB","1",.) +lstrfun r, subinstr("`r'","*","",.) +lstrfun r, subinstr("`r'"," ","",.) +} +} + + +/*return list +ereturn list*/ + +estat gof +qui estat gof, stat(all) +tempname iter1 V +local iter1=e(ic) +local tli1=r(tli) +local cfi1=r(cfi) +local srmr1=r(srmr) +local rmsea1=r(rmsea) +local ubrmsea1=r(ub90_rmsea) +local lbrmsea1=r(lb90_rmsea) +local pclose1= r(pclose) +local chi21=r(chi2_ms) +local df1=r(df_ms) +local dfc1=6*`nbitems'+1 +local p1=r(p_ms) +local bic1=r(bic) +local convergence1=e(converged) +local cov_fit1="`r'" +local arret_covfit1=`arret_covfit' + + +return matrix b1=`b' +return scalar iter1=`iter1' +return scalar tli1=`tli1' +return scalar cfi1=`cfi1' +return scalar srmr1=`srmr1' +return scalar rmsea1=`rmsea1' +return scalar ubrmsea1=`ubrmsea1' +return scalar lbrmsea1=`lbrmsea1' +return scalar pclose1=`pclose1' +return scalar chi21=`chi21' +return scalar df1=`df1' +return scalar dfc1=`dfc1' +return scalar p1=`p1' +return scalar bic1=`bic1' +return scalar convergence1=`convergence1' +return local cov_fit1 = "`cov_fit1'" +return scalar arret_covfit1 =`arret_covfit1' +/*}*/ + + +*di +*di in green " ***********************************Model 1********************************************" +*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI" +*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1' + +/************************************************************************************************************** +Model 2 +***************************************************************************************************************/ + +local sem +local var +forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local sem `sem' `sem`i'' + local var `var' `var`i'' +} + +if "`model2'"=="" { + local qui qui +} +else { + local qui +} + +`qui' sem `sem',var(T1@1) var(T2@1) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances' `covfit') +di "`sem'" +di"`var'" +tempname b V +matrix `b'=r(table) +matrix `V'=e(V) +local truechange2=`b'[1,`=`nbitems'*4+1'] +local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1'] + + +estat gof +qui estat gof, stat(all) +local iter2=e(ic) +local tli2=r(tli) +local cfi2=r(cfi) +local srmr2=r(srmr) +local rmsea2=r(rmsea) +local ubrmsea2=r(ub90_rmsea) +local lbrmsea2=r(lb90_rmsea) +local pclose2=r(pclose) +local chi22=r(chi2_ms) +local df2=r(df_ms) +local dfc2=3*`nbitems'+3 +local p2=r(p_ms) +local bic2=r(bic) +local convergence2=e(converged) + +return matrix b2=`b' +return scalar iter2=`iter2' +return scalar tli2=`tli2' +return scalar cfi2=`cfi2' +return scalar srmr2=`srmr2' +return scalar rmsea2=`rmsea2' +return scalar ubrmsea2=`ubrmsea2' +return scalar lbrmsea2=`lbrmsea2' +return scalar pclose2=`pclose2' +return scalar chi22=`chi22' +return scalar df2=`df2' +return scalar dfc2=`dfc2' +return scalar p2=`p2' +return scalar bic2=`bic2' +return scalar convergence2=`convergence2' +return scalar truechange2=`truechange2' +return scalar setruechange2=`=sqrt(`Vtruechange2')' +return scalar ztruechange2=`=`truechange2'/sqrt(`Vtruechange2')' +return scalar ptruechange2=`=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))' + + +if "`html'" != "" { + di "" + di "" + *di "" + di "" + di "" + di "" + di "" + di "
Test of global Response-ShiftComparison with model 1
ModelsChi-squaredfp-valueBIC
Model 1" %8.2f `chi21' "" %4.0f `df1' "" %6.4f `p1' "" %7.2f `bic1' "
Model 2" %8.2f `chi22' "" %4.0f `df2' "" %6.4f `p2' "" %7.2f `bic2' "
" +} +else { + di "{hline 51}" + di in gr /*_col(39) "Test of global Response-Shift " _col(79) "Comparison with model 1"*/ + di in gr "Models" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" /*_col(39) "Chi-square" _col(54) "df" _col(59) "p-value" *_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 51}" + di in gr "Model 1" _col(20) %8.2f in ye `chi21' _col(30) %4.0f `df1' _col(37) %6.4f `p1' _col(45) %7.2f `bic1' + di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(30) %4.0f `df2' _col(37) %6.4f `p2' _col(45) %7.2f `bic2' /*_col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' *_col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'*/ + di "{hline 51}" +} + + +if "`cas'"=="cas3" | "`cas'"=="cas4" | "`cas'"=="cas5" | "`cas'"=="cas6"{ +local chi221=abs(`chi21'-`chi22') +local df21=`df2'-`df1' +local p21=1-chi2(`df21',`chi221') + +if (`p21'>0.05) { +local search="nosearch" +} + +return scalar pvaleurM1M2=`p21' + +} + + +/************************************************************************************************************** +Model 3 +***************************************************************************************************************/ + +/************************************************************************************************************** +HIERARCHIE +***************************************************************************************************************/ +if "`cas'"=="cas1" | "`cas'"=="cas2" | "`cas'"=="cas3" | "`cas'"=="cas4" { +/************************************************************************************************************** +Model 3 / Non uniform recalibration +***************************************************************************************************************/ + +tempname RS RSprec +qui matrix `RS'=J(`nbitems',3,0) +qui matrix `RSprec'=J(`nbitems',3,0) +local df3=`dfc2' + +*set trace on + +forvalues j=1/`nbitems' { + local unav_nonunif`j'=. +} + +if "`matrixrs'"=="" { + forvalues i=1/`nbitems' { + local nbUR:word count `uniformrecalibration' + forvalues j=1/`nbUR' { + local itemj: word `j' of `uniformrecalibration' + if "``i''"=="`itemj'" { + matrix `RS'[`i',2]=1 + } + } + local nbNUR:word count `nonuniformrecalibration' + forvalues j=1/`nbNUR' { + local itemj: word `j' of `nonuniformrecalibration' + if "``i''"=="`itemj'" { + matrix `RS'[`i',1]=1 + } + } + local nbR:word count `reprioritization' + forvalues j=1/`nbR' { + local itemj: word `j' of `reprioritization' + if "``i''"=="`itemj'" { + matrix `RS'[`i',3]=1 + } + } + } +} +else { + matrix `RS'=`matrixrs' +} +*matrix list `RS' + +if "`search'"=="" { + + if "`html'"=="" { + di + di "{hline 88}" + di in green _col(40) "Model 3" + di "{hline 88}" + di + di in white _col(10) "Non uniform Recalibration" + } + else { + di "


Model 3

" + di "" + di "" + } + local continue=1 + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + } + local prec_chi2=`chi22' + local testNU_varchi2=0 + local testNU_p=1 + + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + while (`continue') { + local cpt=0 + local testNU_varchi2_temp=0 + local testNU_p_temp=0 + local testNU_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + local var + forvalues j=1/`nbitems' { + local sem + local var + local already=0 + forvalues i=1/`nbitems' { + if `RS'[`i',1]==0&`i'!=`j' { + local sem `sem' `sem`i'' + local var `var' `var`i'' + } + if `RS'[`i',1]==1&`i'!=`j' { + local sem `sem' `sem`i'' + local var `var' `varrecNU`i'' + } + else if `i'==`j'&`RS'[`j',1]==0 { + local sem `sem' `sem`i'' + local var `var' `varrecNU`i'' + } + else if `i'==`j'&`RS'[`j',1]==1 { + local sem `sem' `sem`i'' + local var `var' `varrecNU`i'' + local already=1 + } + } + /*di "`covfit'"*/ + /* di "`sem'" + di"`var'"*/ + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2@1) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances' `covfit') + di "`sem'" + di"`var'" + qui estat gof + + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + + if "`cas'"=="cas4" | "`cas'"=="cas2" { + local nbtest=1-(0.05/(`nbitems'-`cpt')) + } + if "`cas'"=="cas1" | "`cas'"=="cas3" { + local nbtest=0.95 + } + + + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,`nbtest')&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') { + local continue=1 + local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp') + local testNU_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + } + if ( `chi2encours'<`prec_chi2') { + local unav_nonunif`j'=0 + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + } + else { + local unav_nonunif`j'=1 + if "`html'" != "" { + di "" + + } + else { + di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable" + } + } + local ++cpt + return scalar unav_nonunif`j'= `unav_nonunif`j'' + } + } + if (`testNU_item_temp'!=0) { + matrix `RS'[`testNU_item_temp',1]=1 + local ++df3 + local testNU_varchi2=`testNU_varchi2_temp' + local testNU_p=`testNU_p_temp' + local testNU_item_temp=0 + local prec_chi2=`tmp' + } + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Non uniform Recalibration
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "
``j''Unavailable

" + } + + + + /************************************************************************************************************** + Model 3 / Uniform recalibration + ***************************************************************************************************************/ +forvalues j=1/`nbitems' { + local unav_unif`j'=. +} + + if "`html'"=="" { + di + di in white _col(10) "Uniform Recalibration" + } + else { + di "" + di "" + } + local continue=1 + local var + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + } + local testU_varchi2=0 + local testU_p=1 + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + while (`continue') { + local cpt=0 + local testU_varchi2_temp=0 + local testU_p_temp=0 + local testU_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + forvalues j=1/`nbitems' { + local sem + local already=0 + forvalues i=1/`nbitems' { + if `RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `sem`i'' + } + if `RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecU`i'' + } + else if `i'==`j'&`RS'[`j',2]==0 { + local sem `sem' `semrecU`i'' + } + else if `i'==`j'&`RS'[`j',2]==1 { + local sem `sem' `semrecU`i'' + local already=1 + } + } + + /* di "`sem'" + di"`var'"*/ + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2@1) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances' `covfit') + di "`sem'" + di"`var'" + qui estat gof + + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + + if "`cas'"=="cas4" | "`cas'"=="cas2" { + local nbtest=1-(0.05/(`nbitems'-`cpt')) + } + if "`cas'"=="cas1" | "`cas'"=="cas3" { + local nbtest=0.95 + } + + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,`nbtest')&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') { + local continue=1 + local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local testU_p_temp =1-chi2(1,`testU_varchi2_temp') + local testU_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + } + + if ( `chi2encours'<`prec_chi2') { + local unav_unif`j'=0 + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + } + else { + local unav_unif`j'=1 + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable" + } + } + local ++cpt + return scalar unav_unif`j'= `unav_unif`j'' + } + } + if (`testU_item_temp'!=0) { + matrix `RS'[`testU_item_temp',2]=1 + local ++df3 + local testU_varchi2=`testU_varchi2_temp' + local testU_p=`testU_p_temp' + local testU_item_temp=0 + local prec_chi2=`tmp' + } + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Uniform Recalibration
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "
``j''Unavailable

" + } + + + + + /************************************************************************************************************** + Model 3 / Reprioritization + ***************************************************************************************************************/ +forvalues j=1/`nbitems' { + local unav_reprio`j'=. +} + + if "`html'"=="" { + di + di in white _col(10) "Reprioritization" + } + else { + di "" + di "" + } + + local continue=1 + local var + local sem + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + } + local testU_varchi2=0 + local testU_p=1 + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + while (`continue') { + local cpt=0 + local testR_varchi2_temp=0 + local testR_p_temp=0 + local testR_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + forvalues j=1/`nbitems' { + local sem + local already=0 + forvalues i=1/`nbitems' { + if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `sem`i'' + } + else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecU`i'' + } + else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `semrep`i'' + } + else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecUrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 { + local sem `sem' `semrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 { + local sem `sem' `semrecUrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 { + local already=1 + } + else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 { + local sem `sem' `semrep`i'' + local already=1 + } + else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 { + local sem `sem' `semrecUrep`i'' + local already=1 + } + } + di "`sem'" + di"`var'" + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2@1) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances' `covfit') + di "`sem'" + di"`var'" + qui estat gof + + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + + if "`cas'"=="cas4" | "`cas'"=="cas2" { + local nbtest=1-(0.05/(`nbitems'-`cpt')) + } + if "`cas'"=="cas1" | "`cas'"=="cas3" { + local nbtest=0.95 + } + + + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,`nbtest')&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') { + local continue=1 + local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local testR_p_temp =1-chi2(1,`testR_varchi2_temp') + local testR_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + } + if ( `chi2encours'<`prec_chi2') { + local unav_reprio`j'= 0 + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + } + else { + local unav_reprio`j'= 1 + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable" + } + } + local ++cpt + return scalar unav_reprio`j'= `unav_reprio`j'' + } + } + if (`testR_item_temp'!=0) { + matrix `RS'[`testR_item_temp',3]=1 + local ++df3 + local testR_varchi2=`testR_varchi2_temp' + local testR_p=`testR_p_temp' + local testR_item_temp=0 + local prec_chi2=`tmp' + } + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Reprioritization
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "
``j''Unavailable

" + } +} + + + +} + + + +/************************************************************************************************************** +PAS DE HIERARCHIE +***************************************************************************************************************/ + +if "`cas'"=="cas5" | "`cas'"=="cas6" | "`cas'"=="cas7" | "`cas'"=="cas8" { + + + +/************************************************************************************************************** +Model 3 / Type of Response Shift +***************************************************************************************************************/ +forvalues nbpass=0/63 { + forvalues j=1/`nbitems' { + forvalues typeRS=1/3{ + local unav`=`nbpass'`j'`typeRS''=. + } + } +} + +tempname RS RSprec +qui matrix `RS'=J(`nbitems',3,0) +qui matrix `RSprec'=J(`nbitems',3,0) +local df3=`dfc2' + +if "`matrixrs'"=="" { + forvalues i=1/`nbitems' { + local nbUR:word count `uniformrecalibration' + forvalues j=1/`nbUR' { + local itemj: word `j' of `uniformrecalibration' + if "``i''"=="`itemj'" { + matrix `RS'[`i',2]=1 + } + } + local nbNUR:word count `nonuniformrecalibration' + forvalues j=1/`nbNUR' { + local itemj: word `j' of `nonuniformrecalibration' + if "``i''"=="`itemj'" { + matrix `RS'[`i',1]=1 + } + } + local nbR:word count `reprioritization' + forvalues j=1/`nbR' { + local itemj: word `j' of `reprioritization' + if "``i''"=="`itemj'" { + matrix `RS'[`i',3]=1 + } + } + } +} +else { + matrix `RS'=`matrixrs' +} +*matrix list `RS' + +if "`search'"=="" { + + + if "`html'"=="" { + di + di "{hline 88}" + di in green _col(40) "Model 3" + di "{hline 88}" + di + di in white _col(10) "Type of response shift" + } + else { + di "


Model 3

" + di "" + di "" + } + local continue=1 + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + } + local prec_chi2=`chi22' + local test_varchi2=0 + local test_p=1 + + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + + local nbpass=0 + local ajust=0 + while (`continue') { + + local cpt=0 + local test_varchi2_temp=0 + local test_p_temp=0 + local test_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + local var + forvalues typeRS=1/3{ + + + forvalues v=1/`nbitems' { + if `RS'[`v',2]==1&`RS'[`v',1]==1 { + local ajust=1 + } + } + + + forvalues j=1/`nbitems' { + local sem + local var + local already=0 + + forvalues i=1/`nbitems' { + + if `typeRS'==1 { + if `RS'[`i',2]==0 & `RS'[`i',3]==0 { + local sem "`sem' `sem`i''" + } + if `RS'[`i',2]==0 & `RS'[`i',3]==1 { + local sem "`sem' `semrep`i''" + } + if `RS'[`i',2]==1 & `RS'[`i',3]==0{ + local sem "`sem' `semrecU`i''" + } + if `RS'[`i',2]==1 & `RS'[`i',3]==1{ + local sem "`sem' `semrecUrep`i''" + } + + + + if `RS'[`i',1]==0&`i'!=`j' { + local var `var' `var`i'' + } + if `RS'[`i',1]==1&`i'!=`j' { + local var `var' `varrecNU`i'' + } + else if `i'==`j'&`RS'[`j',1]==0 { + local var `var' `varrecNU`i'' + } + else if `i'==`j'&`RS'[`j',1]==1 { + local var `var' `varrecNU`i'' + local already=1 + } + + } + + if `typeRS'==2 { + /*matrix list `RS'*/ + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + + if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `sem`i'' + } + else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecU`i'' + } + else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `semrep`i'' + } + else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecUrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 { + local sem `sem' `semrecU`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1 { + local already=1 + } + else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 { + local sem `sem' `semrecUrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 { + local sem `sem' `semrecUrep`i'' + local already=1 + } + + } + + + if `typeRS'==3 { + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + + if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `sem`i'' + } + else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecU`i'' + } + else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `semrep`i'' + } + else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecUrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 { + local sem `sem' `semrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 { + local sem `sem' `semrecUrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 { + local already=1 + } + else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 { + local sem `sem' `semrep`i'' + local already=1 + } + else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 { + local sem `sem' `semrecUrep`i'' + local already=1 + } + + + } + + } + + + /*set trace off*/ + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2@1) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances' `covfit') + di "`sem' " + di "`var' " + qui estat gof + + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + if "`cas'"=="cas6" | "`cas'"=="cas8" { + local nbtest=1-(0.05/(`nbitems'*3-(`=`cpt'+`nbpass'+`ajust''))) + } + if "`cas'"=="cas5" | "`cas'"=="cas7" { + local nbtest=0.95 + } + + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,`nbtest')&abs(`chi2encours'-`prec_chi2')>`test_varchi2_temp'&`chi2encours'<`prec_chi2') { + local continue=1 + local test_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local test_p_temp =1-chi2(1,`test_varchi2_temp') + local test_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + local typeRS_encours=`typeRS' + } + + if ( `chi2encours'<`prec_chi2') { + local unav`=`nbpass'`j'`typeRS''=0 + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + } + else { + local unav`=`nbpass'`j'`typeRS''=1 + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable" + } + } + return scalar unav`=`nbpass'`j'`typeRS''= `unav`=`nbpass'`j'`typeRS''' + + local ++cpt + + + + } + } + + } + + if (`test_item_temp'!=0) { + if `typeRS_encours'==1 { + matrix `RS'[`test_item_temp',1]=1 + } + if `typeRS_encours'==2 { + matrix `RS'[`test_item_temp',2]=1 + } + if `typeRS_encours'==3 { + matrix `RS'[`test_item_temp',3]=1 + } + + /*matrix list `RS'*/ + local ++df3 + local test_varchi2=`test_varchi2_temp' + local test_p=`test_p_temp' + local test_item_temp=0 + local prec_chi2=`tmp' + + + } + local ++nbpass + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Non uniform Recalibration
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "
``j''Unavailable

" + } +} + + + +} + + +/************************************************************************************************************** +Model 3 Final +***************************************************************************************************************/ + +di +local continue=1 +local var +local sem +forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + if `RS'[`i',2]==0&`RS'[`i',3]==0 { + local sem "`sem' `sem`i''" + } + if `RS'[`i',2]==0&`RS'[`i',3]==1 { + local sem "`sem' `semrep`i''" + } + if `RS'[`i',2]==1&`RS'[`i',3]==0 { + local sem "`sem' `semrecU`i''" + } + if `RS'[`i',2]==1&`RS'[`i',3]==1 { + local sem "`sem' `semrecUrep`i''" + } +} + +qui sem `sem',var(T1@1) var(T2@1) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances' `covfit') +di "`sem'" +di"`var'" +tempname b V +matrix `b'=r(table) +matrix `V'=e(V) +local truechange=`b'[1,`=`nbitems'*4+1'] +local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1'] +qui estat gof +local iter3=e(ic) +local tli3=r(tli) +local cfi3=r(cfi) +local srmr3=r(srmr) +local rmsea3=r(rmsea) +local ubrmsea3=r(ub90_rmsea) +local lbrmsea3=r(lb90_rmsea) +local pclose3=r(pclose) +local chi23=r(chi2_ms) +local dfc3=`df3' +local p3=r(p_ms) +local bic3=r(bic) +local convergence3= e(converged) + + +return matrix b3=`b' +return scalar iter3=`iter3' +return scalar tli3=`tli3' +return scalar cfi3=`cfi3' +return scalar srmr3=`srmr3' +return scalar rmsea3=`rmsea3' +return scalar ubrmsea3=`ubrmsea3' +return scalar lbrmsea3=`lbrmsea3' +return scalar pclose3=`pclose3' +return scalar chi23=`chi23' +return scalar df3=`df3' +return scalar dfc3=`dfc3' +return scalar p3=`p3' +return scalar bic3=`bic3' +return scalar convergence3=`convergence3' + +/************************************************************************************************************** +Bilan +***************************************************************************************************************/ + +if "`html'"=="" { + di + di "{hline 74}" + di in gr _col(22) "Non uniform" _col(46) "Uniform" + di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(58) "Reprioritization" + di "{hline 74}" +} +else { + di "" + di "" + di "" + di "" +} +forvalues i=1/`nbitems' { + local recNU + local recU + local rep + if (`RS'[`i',1]==1) { + local recNU "*" + } + if (`RS'[`i',2]==1) { + local recU "*" + } + if (`RS'[`i',3]==1) { + local rep "*" + } + if "`html'"=="" { + di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'" + } + else { + di "" + } +} +if "`html'"=="" { + di "{hline 74}" +} +else { + di "
ItemsNon-uniform
Recalibration
Uniform
Recalibration

Repriorisation
``i''`recNU'`recU'`rep'
" +} + + +/************************************************************************************************************** +Model 4 +***************************************************************************************************************/ + +if "`model4'"=="" { + local qui qui +} +else { + local qui +} +local arret_covfit=999 + + +`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) cov(`cov12b' `covariances' `covfit') method(`method') +di "`sem'" +di"`var'" +tempname b +matrix `b'=r(table) + +estat gof +local rmsea4=r(rmsea) + +*set trace on + +while `rmsea4' >0.08 { + +di"`rmsea4'" +tempfile data +save `data', replace +/*on récupère les indices de modifs*/ +estat mindice +matrix indice = r(mindices) +clear +/* on ajoute dans une colonne le nom des items concernés*/ +svmat2 indice , r(nomcol) full +/*on controle l'ajout de covariances uniquement sur un même temps*/ +gen tmp=substr(nomcol,1,3) +drop if tmp!="cov" + +gen tmp1=substr(nomcol,11,1) +gen tmp2=substr(nomcol,20,1) +drop if tmp1 != tmp2 + +/*On vérifie qu'il reste des lignes de covariances à ajouter*/ +local vide = indice1[1] +if "`vide'" == "." { +local covfit= "`covfit'" +local arret_covfit=1 +local rmsea4=0 +use "`data'", clear +} +else { +/*on trie par ordre croissant pour ajouter les covariances les plus influentes*/ +local arret_covfit=0 +gsort - indice1 + +local tmp3=nomcol[1] +lstrfun e, subinstr("`tmp3'","cov(","",.) +lstrfun e, subinstr("`e'",")","",.) +lstrfun e, subinstr("`e'",":_cons","",.) +lstrfun e, subinstr("`e'",",","*",.) + +/*matrix list indice */ + +local covfit= "`covfit' `e'" +di "`covfit'" + +use "`data'", clear +di "`data'" + + +`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) cov(`cov12b' `covariances' `covfit') method(`method') +di "`sem'" +di"`var'" +tempname b +matrix `b'=r(table) + +estat gof +local rmsea4=r(rmsea) + + +local tmp4="`covfit'" +lstrfun r, subinstr("`tmp4'","e.itemA","0",.) +lstrfun r, subinstr("`r'","e.itemB","1",.) +lstrfun r, subinstr("`r'","*","",.) +lstrfun r, subinstr("`r'"," ","",.) +} +} + + + + +di "`covfit'" +tempname V +matrix `V'=e(V) +local truechange=`b'[1,`=`nbitems'*4+1'] +local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1'] + +qui estat gof,stat(all) +local iter4=e(ic) +local tli4=r(tli) +local cfi4=r(cfi) +local srmr4=r(srmr) +local rmsea4=r(rmsea) +local ubrmsea4=r(ub90_rmsea) +local lbrmsea4=r(lb90_rmsea) +local pclose4=r(pclose) +local chi24=r(chi2_ms) +local df4=r(df_ms) +local dfc4=`df3'+1 +local p4=r(p_ms) +local chi2encours=r(chi2_ms) +local bic4=r(bic) +local convergence4=e(converged) +local cov_fit4="`r'" +local arret_covfit4=`arret_covfit' +local z=`truechange'/sqrt(`Vtruechange') + + +return matrix b4=`b' +return scalar iter4=e(ic) +return scalar tli4=`tli4' +return scalar cfi4=`cfi4' +return scalar srmr4=`srmr4' +return scalar rmsea4=`rmsea4' +return scalar ubrmsea4=`ubrmsea4' +return scalar lbrmsea4=`lbrmsea4' +return scalar pclose4=`pclose4' +return scalar chi24=`chi24' +return scalar df4=`df4' +return scalar dfc4=`dfc4' +return scalar p4=`p4' +return scalar bic4=`bic4' +return scalar convergence4=`convergence4' +return local cov_fit4 = "`cov_fit4'" +return scalar arret_covfit4 = `arret_covfit4' +return scalar truechange=`truechange' +return scalar setruechange=`=sqrt(`Vtruechange')' +return scalar ztruechange=`=`truechange'/sqrt(`Vtruechange')' +return scalar ptruechange=`=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))' + + + + + +if "`html'" != "" { + di "" + di "" + di "" + di "" + di "" + di "" + di "" + di "
Modelschi2dfpBICRMSEAIC90%(RMSEA)SRMRCFITLI
Model 1" %8.2f `chi21' "" %4.0f `df1' "" %7.2f `bic1' "" %6.4f `p1' "" %6.4f `rmsea1' "" %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' "" %6.4f `srmr1' "" %6.2f `cfi1' "" %6.2f `tli1' "
Model 2" %8.2f `chi22' "" %4.0f `df2' "" %7.2f `bic2' "" %6.4f `p2' "" %6.4f `rmsea2' "" %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' "" %6.4f `srmr2' "" %6.2f `cfi2' "" %6.2f `tli2' "
Model 4" %8.2f `chi24' "" %4.0f `df4' "" %7.2f `bic4' "" %6.4f `p4' "" %6.4f `rmsea4' "" %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' "" %6.4f `srmr4' "" %6.2f `cfi4' "" %6.2f `tli4' "
" +} +else { + di + di "{hline 95}" + di in gr "Models" _col(14) "chi2" _col(22) "df" _col(31) "p" _col(40) "BIC" _col(47) "RMSEA" _col(55) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI" + di "{hline 95}" + di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `df1' _col(26) %6.4f `p1' _col(36) %7.2f `bic1' _col(46) %6.4f `rmsea1' _col(54) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1' + di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `df2' _col(26) %6.4f `p2' _col(36) %7.2f `bic2' _col(46) %6.4f `rmsea2' _col(54) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2' + *di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3' _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3' + di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `df4' _col(26) %6.4f `p4' _col(36) %7.2f `bic4' _col(46) %6.4f `rmsea4' _col(54) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4' + di "{hline 95}" +} + + +if "`html'" != "" { + di "" + di "" + di "" + di "" + di "" + di "" + di "
Estimations.e.zp-value
True change (Model 2)" %8.4f `truechange2' "" %8.4f `=sqrt(`Vtruechange2')' "" %6.2f `=`truechange2'/sqrt(`Vtruechange2')' "" %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))' "
True change (Model 4)" %8.4f `truechange' "" %8.4f `=sqrt(`Vtruechange')' "" %6.2f `=`truechange'/sqrt(`Vtruechange')' "" %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))' "
" +} +else { + di + di "{hline 77}" + di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value" + di "{hline 77}" + di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))' + di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))' + di "{hline 77}" + di +} +qui use `saveMultirsoort_indicefit',clear + + + +end diff --git a/Modules/ado/personal/m/matrixlisthtml.ado b/Modules/ado/personal/m/matrixlisthtml.ado new file mode 100644 index 0000000..12c1988 --- /dev/null +++ b/Modules/ado/personal/m/matrixlisthtml.ado @@ -0,0 +1,24 @@ +program define matrixlisthtml +args matrixname precision +*mat li `matrixname' +local rownames: rown `matrixname' +local colnames: coln `matrixname' + +di "" +foreach mycol in `colnames' { + di "" as text "`mycol'" "" +} +di "" + +local rowindex=1 + +forvalues rowptr=1/`=rowsof(`matrixname')' { + local rowname: word `rowindex' of `rownames' + di "" "`rowname'" "" + forvalues colptr=1/`=colsof(`matrixname')' { + di "" `precision' `matrixname'[`rowptr', `colptr'] "" + } + di "" + local ++rowindex +} +end diff --git a/Modules/ado/personal/m/mdreplace.ado b/Modules/ado/personal/m/mdreplace.ado new file mode 100644 index 0000000..e6e9256 --- /dev/null +++ b/Modules/ado/personal/m/mdreplace.ado @@ -0,0 +1,57 @@ +*! version 1 19september2018 +*! Jean-Benoit Hardouin +* +************************************************************************************************************ +* Stata program : mdreplace +* Missing data handling in a dataset +* +* Historic +* Version 1 (2018-09-19): Jean-Benoit Hardouin +* +* Jean-benoit Hardouin, Plateforme de MĂ©thodologie et de Biostatistique - DRCi - CHU de Nantes - France +* jean-benoit.hardouin@univ-nantes.fr +* +* Copyright 2018 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define mdreplace +version 7.0 +syntax varlist(min=1) , list(string) + +if "`list'"=="" { + di in red "Please indicate in the list option the strings to replace by missing data" +} + +foreach i of varlist `varlist' { + foreach e in `list' { + *di "variable : `i' code : `e'" + + capture replace `i'="." if `i'=="`e'" + if (_rc==0) { + qui replace `i'="" if `i'=="`e'" + } + } + capture destring `i', replace + if (_rc==0) { + qui destring `i', replace + } +} + + +end + diff --git a/Modules/ado/personal/m/mi_twoway.ado b/Modules/ado/personal/m/mi_twoway.ado new file mode 100644 index 0000000..06c9183 --- /dev/null +++ b/Modules/ado/personal/m/mi_twoway.ado @@ -0,0 +1,210 @@ +program define mi_twoway,rclass +syntax varlist [, SCorename(string) REPlace ADD(int 10) STyle(string) clear DA ITerate(int 10)] +qui{ +tempfile bddini +save `bddini', replace +if "`scorename'"==""{ + local scorename score +} +capture tab `scorename' +if _rc==0{ + if "`replace'"!=""{ + drop `scorename' + } + else{ + noi di in red "variable `scorename' already exists" + use `bddini',replace + error 100 + } +} +local nombase "" +if wordcount("`style'")==0{ + local style mlong +} +else if wordcount("`style'")==1{ + if "`=word("`style'", 1)'"=="ml" | "`=word("`style'", 1)'"=="mlo" | "`=word("`style'", 1)'"=="mlon" | "`=word("`style'", 1)'"=="mlong" | "`=word("`style'", 1)'"=="fl" | "`=word("`style'", 1)'"=="flo" | "`=word("`style'", 1)'"=="flon" | "`=word("`style'", 1)'"=="flong" | "`=word("`style'", 1)'"=="w" | "`=word("`style'", 1)'"=="wi" | "`=word("`style'", 1)'"=="wid" | "`=word("`style'", 1)'"=="wide"{ + local style `style' + } + else{ + noi di in red "option {it:style} improperly fulfilled" + noi di in red " Only {it:mlong}, {it:flong}, {it:wide} and {it:flongsep} are available" + noi di in red " A database name must be proposed if the style {it:flongsep} is selected (see mi_styles)" + use `bddini',replace + error 100 + } +} +else if wordcount("`style'")==2{ + if "`=word("`style'", 1)'"=="flongs" | "`=word("`style'", 1)'"=="flongse" | "`=word("`style'", 1)'"=="flongsep"{ + local nombase `=word("`style'", 2)' + local style `=word("`style'", 1)' + } + else{ + noi di in red "option {it:style} improperly fulfilled" + noi di in red " Only {it:mlong}, {it:flong}, {it:wide} and {it:flongsep} are available" + noi di in red " A database name must be proposed if the style {it:flongsep} is selected (see mi_styles)" + use `bddini',replace + error 100 + } +} + + + + +tempvar var + +local M `_dta[_mi_M]' +if "`M'"!=""{ + if "`clear'"==""{ + noi di in red "no; data are mi set" + noi di in red " Use {it:clear} option to replace imputed values using mi_twoway, or" + noi di in red " other MI commands (like {it:mi extract})" + use `bddini',replace + error 100 + } + else{ + mi extract 0, clear + } +} + + + + + +gen `var'id=_n +sort `var'id +save `bddini'_bis, replace +tokenize `varlist' +if `add'==.{ + local add==10 +} +if `iterate'==.{ + local iterate==10 +} + +egen keep=rowmean(`varlist') +keep if keep!=. +drop keep +local Nb=_N +local nbit: word count `varlist' +egen `var'i=rowmean(`varlist') +forvalues j=1/`nbit'{ + gen it_`var'_`j'=``j'' +} +keep it_`var'_* `var'id `var'i +reshape long it_`var'_, i(`var'id) j(it) +rename it_`var'_ it_`var' +bysort it: egen Mj=mean(it_`var') +su it_`var' +local MM=r(mean) +gen Me=`var'i+Mj-`MM' +gen Dif2=(Me-it_`var')^2 +su Dif2 +local Var=r(sum)/(r(N)-1) +gen __miss=it_`var'==. +forvalues it=1/`add'{ + gen _`it'_`var'=it_`var' + replace _`it'_`var'=rnormal(Me, `=sqrt(`Var')') if __miss==1 +} +/* Data augmentation */ + + +if "`da'"!=""{ + + gen `var'present=1-__miss + bysort `var'id: egen `var'Cpre=total(`var'present) + bysort it: egen `var'CItpre=total(`var'present) + su `var'present + local Nobs=r(sum) + gen `var'Pre=_1_`var' + su `var'Pre + local mu=r(mean) + bysort it: egen `var'Be=mean(`var'Pre) + replace `var'Be=`var'Be-`mu' + bysort `var'id: egen `var'Al=mean(`var'Pre) + gen `var'sigInt=(`var'Pre-`var'Be-`var'Al)^2 + su `var'sigInt + local sigma2=r(sum)/(`nbit'-1)/(`Nb'-1) + gen `var'tauInt=(`var'Al-`mu')^2 + su `var'tauInt if it==1 + local tau2=r(sum)/(`Nb'-1) + forvalues it=1/`add'{ + forvalues g=1/`iterate'{ +/* noi di "it = `g'"*/ + /* RedĂ©finition alpha */ + capture drop A2 `var'A2 `var'A2V B2 `var'Be2 Vbe2 S2 TAU + gen A2=(it_`var'-`var'Be)/`sigma2' + bysort `var'id: egen `var'A2=total(A2) + replace `var'A2=(`var'A2+`mu'/`tau2')/(1/`tau2' + `var'Cpre/`sigma2') + gen `var'A2V=sqrt(1/(1/`tau2'+`var'Cpre/`sigma2')) + replace `var'Al=rnormal(`var'A2, `var'A2V) + + /* RedĂ©finition beta */ + gen B2=(it_`var'-`var'Al) + bysort it: egen `var'Be2=mean(B2) + gen Vbe2=sqrt(`sigma2'/`var'CItpre) + replace `var'Be=rnormal(`var'Be2, Vbe2) + + /* Redefinition Sigma */ + gen S2=(it_`var'-`var'Al-`var'Be)^2 + su S2 + local sigma2b=`=r(N)'*`r(mean)'/rchi2(`=r(N)') + if `sigma2b'!=0{ + local sigma2=`sigma2b' + } + + + + + /* Redefinition mu */ + su `var'Al if it==1 + local mu=rnormal(`=r(mean)', `=sqrt(`tau2'/r(N))') + + /* Redefinition tau2 */ + gen TAU=(`var'Al-`mu')^2 + su TAU if it==1 + local tau2b=`=r(N)'*`r(mean)'/rchi2(`=r(N)') + /* 1/(rgamma(`=r(N)/2', `=2/r(N)/r(mean)')) OU `=r(N)'*`r(mean)'/rchi2(`=r(N)')*/ + if `tau2b'!=0{ + local tau2=`tau2b' + } + /*noi di "mu: `mu' tau2: `tau2' sigma2: `sigma2'" + noi su `var'Al `var'Be*/ + + } + replace _`it'_`var'=rnormal(`mu',`=sqrt(`tau2')')+`var'Be+rnormal(0,`=sqrt(`sigma2')') if __miss==1 + } + +} +/* Fin de data augmentation */ +bysort `var'id: egen _mi_miss=max(__miss) +drop Mj Me Dif2 `var'i __miss +keep *_`var' `var'id it _mi_miss +reshape wide *_`var', i(`var'id) j(it) +egen `scorename'=rowtotal(it_`var'*) +replace `scorename'=. if _mi_miss==1 +forvalues j=1/`add'{ + egen _`j'_`scorename'=rowtotal(_`j'_*), missing +} +forvalues i=1/`nbit'{ + rename it_`var'`i' ``i'' + forvalues j=1/`add'{ + rename _`j'_`var'`i' _`j'_``i'' + label variable _`j'_``i'' "" + } +} +drop `varlist' +order `scorename' _mi_miss, first +sort `var'id +save `bddini'_ter, replace +use `bddini'_bis +merge `var'id using `bddini'_ter +drop _merge `var'id +char _dta[_mi_pvars] `scorename' +char _dta[_mi_M] `add' +char _dta[_mi_ivars] `varlist' +char _dta[_mi_style] wide +char _dta[_mi_marker] _mi_ds_1 +char _dta[_miTW] TW +mi convert `style' `nombase', clear +} +end diff --git a/Modules/ado/personal/m/mi_twoway.hlp b/Modules/ado/personal/m/mi_twoway.hlp new file mode 100644 index 0000000..506e63c --- /dev/null +++ b/Modules/ado/personal/m/mi_twoway.hlp @@ -0,0 +1,97 @@ +{smcl} +{hline} + +{hline} +help for {hi:mi_twoway}{right:Jean-François HAMEL} +{hline} + +{title:Two-way imputations: estimating missing item responses in questionnaires for computing scores} + +{p 8 14 2}{cmd:mi_twoway} {it:varlist}, [{cmdab:sc:orename}({it:newvarname}) +{cmdab:rep:lace} +{cmdab:add:}({it:#}) +{cmdab:st:yle}({it:keyword}) +{cmdab:clear} +{cmdab:da} +{cmdab:it:erate}({it:#})] + +{title:Description} + +{p 8 14 2}{cmd:mi_twoway} is an implementation of multiple imputation methods for tests and questionnaires +based on a two-way ANOVA model of persons by items.{p_end} +{p 14 14 2}Two methods are available: imputations based on a fixed effects two-way ANOVA, and imputations +generated using data augmentation based on a mixed effect two-way ANOVA (with a random person effect +assumed to follow a Norma distribution and a fixed item effect.{p_end} +{p 14 14 2}{cmd:mi_twoway} is compatible with the Sata {help mi} procedures. The data is {help mi_set:set} +and {help mi_impute:imputed} using {cmd:mi_twoway}, but all the estimations using multiple imputations are +performed using the standard mi {help mi_estimate:estimate} procedures. + +{p 4 8 2}{it:varlist} is the list of the variables containing the item responses of the questionnaire +(with possible missing data). + +{title:Options} + +{p 4 14 2}{cmd:scorename} specifies the name of the new variable containing, for each individual, the value of the +score computed as the sum of the item responses. {it:scorename} is missing for each individual with at least one item +missing response. + +{p 4 14 2}{cmd:replace} allows to replace individual scores in existing variables + +{p 4 14 2}{cmd:add} specifies the number of imputations to add; required with no imputations + +{p 4 14 2}{cmd:style} specifies in which style should be recorded the data: wide, mlong, flong, + or flongsep; see {help mi_styles:[MI] styles}. + +{p 4 14 2}{cmd:clear} allows performing new imputations by remouving the previous one. + +{p 4 14 2}{cmd:da} generates imputations using data augmentation based on a mixed effect two-way +ANOVA (with a random person effect and a fixed item effect. By default, imputations are generated +using a fixed effects two-way ANOVA. + +{p 4 14 2}{cmd:iterate} defines the number of iterations of the data augmentation algorithm. +By default, this number is fixed to 10. + +{marker example}{...} +{title:Example} + +{pstd} +Simulation of the data (using {help simirt}): + + {cmd:. simirt, nbobs(200) dim(5) group(0.5) deltagroup(0.4) clear}{right:(1) } + +{pstd} +Creating the missing data, with a non-response rate of 10%: + + . {cmd:set more off }{right:(2) } + . {cmd:forvalues i=1/200{c -(} }{right:(3) } + 2. {cmd:forvalues j=1/5{c -(}}{right:(4) } + 3. {cmd:replace item`j'=. if runiform()<0.1 & id==`i'}{right:(5) } + 4. {cmd:{c )-}}{right:(6) } + 5. {cmd:{c )-}}{right:(7) } + +{pstd} +Generating 10 multiple imputations using a fixed effects two-way ANOVA: + + . {cmd:mi_twoway item*, scorename(score) add(10) style(wide)}{right:(8) } + +{pstd} +Modeling score depending on {it:group} covariate using multiple imputations estimates ({help mi_estimate}): + + . {cmd:mi estimate: regress score i.group}{right:(9) } + +{pstd} +Changing the way to impute data, using data augmentation based on a mixed effect two-way ANOVA: + + . {cmd:mi_twoway item*, scorename(score) replace add(10) style(wide) da clear}{right:(10) } + +{pstd} +Changing the style of the data from {it:wide} to {it:mlong} ({help mi_convert}): + + . {cmd:mi convert mlong}{right:(11) } + +{pstd} +Removal of the multiple imputations ({help mi_set##unset:mi_unset}): + + . {cmd:mi extract 0, clear}{right:(12) } + + diff --git a/Modules/ado/personal/m/mmsrm.ado b/Modules/ado/personal/m/mmsrm.ado new file mode 100644 index 0000000..3ee196f --- /dev/null +++ b/Modules/ado/personal/m/mmsrm.ado @@ -0,0 +1,320 @@ +*! Version 4 7December2012 +************************************************************************************************************ +* Stata program : mmsrm +* Estimate the parameters of the Multidimensional Marginally Sufficient Rasch Model (MMSRM) +* Version 4 : December 7, 2012 /* id option*/ +* +* Historic : +* Version 1 (May 14, 2004) [Jean-Benoit Hardouin] +* Version 2 (May 26, 2004) [Jean-Benoit Hardouin] +* Version 3 (July 3, 2005) [Jean-Benoit Hardouin] +* Version 3.1 : July 8, 2010 /* correction of a bug for the name of the items */ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* Use the Stata programs raschtest and gammasym who can be download on http://anaqol.free.fr +* Use the Stata program gllamm who can be obtained by : ssc install gllamm +* News about this program :http://anaqol.free.fr +* +* Copyright 2004-2005, 2010, 2012 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + + +program define mmsrm,eclass +version 8.0 +syntax varlist(min=3 numeric) [if] [in] , id(varname) [PARTition(numlist) NODETails TRAce ITerate(int 30) ADapt METHod(string)] +preserve +tempfile mmsrmfile +qui save `mmsrmfile',replace + +/******************************************************************************* +INTRODUCTION AND TESTS +********************************************************************************/ + +marksample touse +qui keep if `touse' + +local nbitems : word count `varlist' +if "`partition'"=="" { + local partition=`nbitems' +} +if "`method'"=="" { + local method mml +} +local method=lower("`method'") +local nbpart:word count `partition' + +if `nbpart'>3 { + di in red "{p}The mmsrm module cannot estimate the parameters of the models with more than three dimensions.{p_end}" + error 198 + exit +} +else if `nbpart'==3&"`method'"=="gee" { + di in red "{p}You cannot estimate the parameters of a MMSRM with 3 dimension and the GEE method.{p_end}" + error 198 + exit +} + +if "`adapt'"!=""&"`method'"!="mml" { + di in green "{p}the {cmd:adapt} option is ignored with GEE.{p_end}" +} + +local comptitems=0 +tokenize `varlist' +forvalues i=1/`nbpart' { + local firstpart`i'=`comptitems'+1 + local part`i': word `i' of `partition' + local set`i' + local comptitems=`comptitems'+`part`i'' + forvalues j=`firstpart`i''/`comptitems' { + local set`i' "`set`i'' ``j''" + } +} + +if `comptitems'<`nbitems' { + di in error "{p}Your {cmd:partition} describes less items than the number of items defined in the {it:varlist}.{p_end}" + error 198 + exit +} +if `comptitems'>`nbitems' { + di in error "{p}Your {cmd:partition} describes more items than the number of items defined in the {it:varlist}.{p_end}" + error 198 + exit +} + +/******************************************************************************* +FORMATING AND ESTIMATION (with MML) +********************************************************************************/ +if `nbpart'== 1 { + raschtestv7 `varlist', test(none) method(`method') id(`id') + local ll=r(ll) + tempname beta1 Varbeta1 M + matrix `beta1'=r(beta) + matrix `Varbeta1'=r(Varbeta) + local sigma1=r(sigma) + matrix `M'=(`sigma1'^2) +} +else if "`method'"=="mml" { + forvalues i=1/`nbpart' { + if "`details'"=="" { + di in green "{p}Estimation of the difficulty parameters of the dimension `i'.{p_end}" + } + *set trace on + if `part`i''>1 { + qui raschtestv7 `set`i'',meth(`method') test(none) id(`id') + tempname beta`i' Varbeta`i' + matrix `beta`i''=r(beta) + matrix `Varbeta`i''=r(Varbeta) + local sigma`i'=r(sigma) + forvalues j=1/`part`i'' { + local parambeta`=`firstpart`i''+`j'-1'=`beta`i''[1,`j'] + } + } + else { + qui count + local N=r(N) + qui count if ``firstpart`i'''==1 + local pos=r(N) + local parambeta`firstpart`i''=-log(`pos'/(`N'-`pos')) + local sigma`i'=0 + } + } + + if "`details'"=="" { + di + di in green "{p}Estimation of the parameters of the distribution of the multidimensional latent trait.{p_end}" + di in green "{p}This process could be long to run. Be patient !{p_end}" + } + + keep `varlist' + + tempname rep id item offset + forvalues i=1/`nbitems' { + rename ``i'' `rep'`i' + } + + gen `id'=_n + qui reshape long `rep', i(`id') j(`item') + + gen `offset'=0 + label variable `offset' "offset" + + forvalues i=1/`nbitems' { + qui replace `offset'=-`parambeta`i'' if `item'==`i' + } + + local eqs + forvalues i=1/`nbpart' { + tempname B`i' + gen `B`i''=0 + eq sc`i':`B`i'' + local eqs `eqs' sc`i' + forvalues j=`firstpart`i''/`=`firstpart`i''+`part`i''-1' { + qui replace `B`i''=1 if `item'==`j' + } + } + + label variable `rep' "response" + label variable `id' "identifiant" + + tempname first + local four=substr("`id'",1,3) + matrix define `first'=(0,`sigma1',0,`sigma2') + matrix colnames `first'=`rep':_cons `four'1_1:`B1' `four'1_2:`B2' `four'1_2_1:_cons + + if "`trace'"!="" { + local quigllamm + } + else { + local quigllamm qui + } + + `quigllamm' gllamm `rep', from(`first') link(logit) fam(bin) i(`id') offset(`offset') nrf(`nbpart') eqs(`eqs') nip(6) dots `trace' `adapt' iterate(`iterate') + local ll=e(ll) + tempname cosig varsig L M + matrix `cosig'=e(b) + matrix `varsig'=e(V) + matrix `L'=e(chol) + matrix `M'=`L'*`L'' +} +/******************************************************************************* +FORMATING AND ESTIMATION (with GEE) +********************************************************************************/ +else if "`method'"=="gee" { + tempname coef + matrix `coef'=J(`nbitems',`nbpart',0) + forvalues i=1/`nbpart' { + forvalues j=`firstpart`i''/`=`firstpart`i''+`part`i''-1' { + matrix `coef'[`j',`i']=1 + } + } + if "`trace'"!="" { + local quigee + } + else { + local quigee quietly + } + `quigee' geekel2d `varlist',coef(`coef') ll nbit(`iterate') + local ll=r(ll) + tempname cosig varsig M + matrix `cosig'=r(b) + matrix `M'=J(2,2,0) + matrix `M'[1,1]=`cosig'[1,`=`nbitems'+1'] + matrix `M'[2,2]=`cosig'[1,`=`nbitems'+2'] + matrix `M'[1,2]=`cosig'[1,`=`nbitems'+3'] + matrix `M'[2,1]=`cosig'[1,`=`nbitems'+3'] + matrix `cosig'=`cosig'[1,1..`nbitems'] + matrix `varsig'=r(V) + matrix `varsig'=`varsig'[1..`nbitems',1..`nbitems'] + forvalues i=1/`nbpart' { + tempname beta`i' Varbeta`i' + matrix `beta`i''=`cosig'[1,`firstpart`i''..`=`firstpart`i''+`part`i''-1'] + matrix `Varbeta`i''=`varsig'[`firstpart`i''..`=`firstpart`i''+`part`i''-1',`firstpart`i''..`=`firstpart`i''+`part`i''-1'] + if `part`i''==1 { + local parambeta`firstpart`i''=`cosig'[1,`firstpart`i''] + } + } +} + +/******************************************************************************* +DISPLAYING OF THE RESULTS +********************************************************************************/ + +local AIC=-2*`ll'+2*(`nbitems'+`nbpart'*(`nbpart'+1)/2) + +if `nbpart'>1 { + forvalues i=1/`nbpart' { + local var`i'=`M'[`i',`i'] + forvalues j=`=`i'+1'/`nbpart' { + local cov`i'`j'=`M'[`i',`j'] + } + } + di + di in green _col(4) "Log-likelihood:" in yellow %-12.4f `ll' + di + noi di in green _col(4) "Items" _col(16) "Parameters" _col(29) "std Err." + di in green _col(4) "{hline 33}" + forvalues p=1/`nbpart' { + forvalues i=1/`part`p'' { + local name:word `i' of `set`p'' + if `part`p''!=1 { + noi di in yellow _col(4) "`name'" _col(18) %8.5f `beta`p''[1,`i'] _col(30) %6.5f sqrt(`Varbeta`p''[`i',`i']) + } + else { + noi di in yellow _col(4) "`name'" _col(18) %8.5f `parambeta`firstpart`p''' _col(30) "." + } + } + } + di in green _col(4) "{hline 33}" + + forvalues i=1/`nbpart' { + noi di in yellow _col(4) "Var`i'" _col(18) %8.5f `var`i'' + } + + forvalues i=1/`nbpart' { + forvalues j=`=`i'+1'/`nbpart' { + di in green _col(4) in yellow "cov`i'`j'" _col(18) %8.5f `cov`i'`j'' + } + } + di in green _col(4) "{hline 33}" +} +if "`trace'"==""&"`details'"=="" { + di in green "{p}Add the -trace- option to obtain the standard errors of the elements of the covariance matrix of the latent traits.{p_end}" +} + +/******************************************************************************* +OUTPUTS +********************************************************************************/ + +ereturn clear +ereturn scalar AIC=`AIC' +ereturn scalar ll=`ll' +ereturn scalar dimension=`nbpart' +forvalues i=1/`nbpart' { + ereturn scalar nbitems`i'=`part`i'' + ereturn local set`i' `set`i'' + if `part`i''>1 { + matrix colnames `beta`i''=`set`i'' + matrix rownames `beta`i''=beta + ereturn matrix beta`i'=`beta`i'' + matrix colnames `Varbeta`i''=`set`i'' + matrix rownames `Varbeta`i''=`set`i'' + ereturn matrix Varbeta`i' `Varbeta`i'' + } + else { + ereturn scalar beta`i'=`parambeta`firstpart`i''' + } +} + +tempname matrixsigma +matrix `matrixsigma'=`M' +local list +forvalues i=1/`nbpart' { + local list `list' latenttrait`i' +} +matrix colnames `matrixsigma'=`list' +matrix rownames `matrixsigma'=`list' +ereturn matrix covar=`matrixsigma' + +drop _all +qui use `mmsrmfile' +end diff --git a/Modules/ado/personal/m/mmsrm.hlp b/Modules/ado/personal/m/mmsrm.hlp new file mode 100644 index 0000000..f3f07d1 --- /dev/null +++ b/Modules/ado/personal/m/mmsrm.hlp @@ -0,0 +1,72 @@ +{smcl} +{* 5may2013}{...} +{hline} +help for {hi:mmsrm} +{hline} + +{title:Estimation of the parameters of a Multidimensional Marginally Sufficient Rasch Model (MMSRM)} + +{p 8 14 2}{cmd:mmsrm} {it:varlist} {cmd:id}({it:varname}) [{cmd:,} {cmdab:part:ition}({it:numlist}) {cmdab:nodet:ails} {cmdab:trac:e} {cmdab:it:erate}({it:#}) {cmdab:ad:apt} {cmdab:meth:od}({it:mml/gee})] + +{p 8 14 2}{it:varlist} is a list of two existing binary variables or more. + +{title:Description} + +{p 4 8 2}{cmd:mmsrm} estimates by marginal maximum likelihood (MML) or +generalized estimating equations (GEE) the parameters of the Multidimensional +Marginally Sufficient Rasch Model (MMSRM) defined by Hardouin and Mesbah (2004). +This model is an Item Response Model (IRM) with one or several latent traits. +This is a particular multidimensionnal extension of the Rasch model. In this +model, the items are separated in Q groups and each group of items is linked to +one and only one latent trait. Each group fits a Rasch model relatively to the +corresponding latent trait, so the score computed in each group of item is a +sufficient statistics of this latent trait (to a specific value of this score +is associated only one value for the latent trait). The program allows +computing the parameter of a MMSRM with less than 4 latent traits. +To improve the time of computing, the difficulty parameters are estimated in +each unidimensional Rasch model and used as an offset variable to estimate the +parameters of the distribution of the multidimensional latent trait. This model +allows estimating the correlations between different latent traits measured by +Rasch models. + +{title:Options} + +{p 4 8 2}{cmd:id} defines an identifiant variable of the individuals. + +{p 4 8 2}{cmd:partition} allows defining the number of items relied to each +latent trait. The sum of the numbers indicated in the {it:numlist} must be +equal to the total number of items. The number of elements indicates the number of +latent traits. The items are taken in the same order than this one of {it:varlist}. +By default, only one latent trait is assumed (Rasch model). The number of elements of +{cmd:partition} must be inferior or equal to 3. + +{p 4 8 2}{cmd:method} defines the estimation method between the marginal maximum +likelihood ({it:mml} - by default) and the generalized estimating equations ({it:gee}). +You cannot estimate the parameters of a MMSRM with 3 dimensions with the GEE method. + +{p 4 8 2}{cmd:nodetails} deletes the details about the procedure. + +{p 4 8 2}{cmd:trace} displays details about the estimation algorithm. + +{p 4 8 2}{cmd:iterate} defines the maximal number of iterations of the estimation algorithm + (30 by default). + +{p 4 8 2}{cmd:adapt} allows using the adaptive quadrature if you use the MML method of estimation. This option +is useless if you use GEE. + +{title:Example} + +{p 16 22 2} {inp:. mmsrm item1-item9 , part(4 5) trace method(gee)} + +{p 16 22 2} {inp:. mmsrm item1 item2 item3 item4 /*Rasch model*/} + +{p 16 22 2} {inp:. mmsrm c1-c9 , part(3 3 3) nodetails adapt iterate(10)} + +{title:References} + +{p 4 8 2}Hardouin J.-B. and Mesbah M. Clustering binary variables in subscales using an extended Rasch model and Akaike Information Criterion. {it:Communications in Statistics - Theory and Methods}, {cmd:33}(6), pp. 1277-1294, (2004). + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, Regional Health Observatory (ORS) - 1, rue Porte Madeleine - BP 2439 - 45032 Orleans Cedex 1 - France. +You can contact the author at {browse "mailto:jean-benoit.hardouin@neuf.fr":jean-benoit.hardouin@neuf.fr} and visit the websites {browse "http://anaqol.free.fr":AnaQol} and {browse "http://freeirt.free.fr":FreeIRT} diff --git a/Modules/ado/personal/m/mmsrm2.ado b/Modules/ado/personal/m/mmsrm2.ado new file mode 100644 index 0000000..e0e3499 --- /dev/null +++ b/Modules/ado/personal/m/mmsrm2.ado @@ -0,0 +1,241 @@ +************************************************************************************************************ +* Stata program : mmsrm +* Estimate the parameters of the Multidimensional Marginally Sufficient Rasch Model (MMSRM) +* Release 2 : May 26, 2004 +* +* Historic : +* Version 1 (May 14, 2004) [Jean-Benoit Hardouin] +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@neuf.fr +* +* Use the Stata programs raschtest and gammasym who can be download on http://anaqol.free.fr +* Use the Stata program gllamm who can be obtained by : ssc install gllamm +* News about this program :http://anaqol.free.fr +* +* All the necessary programs on the FreeIRT Project website : http://freeirt.free.fr +* +* Copyright 2004 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + + +program define mmsrm,eclass +version 8.0 +syntax varlist(min=3 numeric) [, PARTition(numlist) NODETails TRAce] +preserve + +local nbitems : word count `varlist' +if "`part'"=="" { + local part=`nbitems' +} +local nbpart:word count `partition' + +if `nbpart'== 1 { + raschtest `varlist', notest mml +} +else if `nbpart'>2 { + di in red "The mmsrm module do not run models with more than two dimensions for the moment." +} +if `nbpart'!=2 { + exit +} + +local comptitems=0 +tokenize `varlist' +forvalues i=1/`nbpart' { + local firstpart`i'=`comptitems'+1 + local part`i': word `i' of `partition' + local set`i' + local comptitems=`comptitems'+`part`i'' + forvalues j=`firstpart`i''/`comptitems' { + local set`i' "`set`i'' ``j''" + } +} + +if `comptitems'<`nbitems' { + di in error "Your partition describe less items than the number of items defined in the varlist." + di in error "Correct your code." + exit +} +if `comptitems'>`nbitems' { + di in error "Your partition describe more items than the number of items defined in the varlist." + di in error "Correct your code." + exit +} + + +forvalues i=1/`nbpart' { + if "`details'"=="" { + di in green "Estimation of the difficulty parameters of the dimension `i'." + } + *set trace on + if `part`i''>1 { + qui raschtest `set`i'',mml notest + tempname beta`i' Varbeta`i' + matrix `beta`i''=e(beta) + matrix `Varbeta`i''=e(Varbeta) + local sigma`i'=e(sigma) + forvalues j=1/`part`i'' { + local parambeta`=`firstpart`i''+`j'-1'=`beta`i''[1,`j'] + } + } + else { + qui count + local N=r(N) + qui count if ``firstpart`i'''==1 + local pos=r(N) + local parambeta`firstpart`i''=-log(`pos'/(`N'-`pos')) + local sigma`i'=0 + } +} + + +if "`details'"=="" { + di + di in green "Estimation of the parameters of the distribution of the multidimensional latent trait." + di in green "This process could be long to run. Be patient !" +} + +*set trace on +tempfile savemmsrm +qui save `savemmsrm' +keep `varlist' + +tempname rep id item offset +forvalues i=1/`nbitems' { + rename ``i'' `rep'`i' +} + +gen `id'=_n +qui reshape long `rep', i(`id') j(`item') + +gen `offset'=0 +label variable `offset' "offset" + +forvalues i=1/`nbitems' { + qui replace `offset'=-`parambeta`i'' if `item'==`i' +} + +local eqs +forvalues i=1/`nbpart' { + tempname B`i' + gen `B`i''=0 + eq sc`i':`B`i'' + local eqs `eqs' sc`i' + forvalues j=`firstpart`i''/`=`firstpart`i''+`part`i''-1' { + qui replace `B`i''=1 if `item'==`j' + } +} + +label variable `rep' "response" +label variable `id' "identifiant" + +tempname first +local four=substr("`id'",1,3) +matrix define `first'=(0,`sigma1',`sigma2',0) +matrix colnames `first'=`rep':_cons `four'1_1:`B1' `four'1_2:`B2' `four'1_2_1:_cons + +if "`trace'"!="" { + local quigllamm +} +else { + local quigllamm qui +} + +`quigllamm' gllamm `rep', from(`first') link(logit) fam(bin) i(`id') offset(`offset') nrf(`nbpart') eqs(`eqs') nip(5) dots `trace' +local AIC=-2*e(ll)+2*(`nbitems'+`nbpart'*(`nbpart'+1)/2) +local ll=e(ll) +tempname cosig varsig L M +matrix `cosig'=e(b) +matrix `varsig'=e(V) +matrix `L'=e(chol) +matrix `M'=`L'*`L'' + +forvalues i=1/`nbpart'{ +} + +if `nbpart'==2 { + local var1=`M'[1,1] + local var2=`M'[2,2] + local sevar1=(sqrt(`varsig'[2,2])*2*sqrt(`var1')) + local sevar2=. + + local cov12=`M'[1,2] + local secov=. + +di +di in green _col(4) "Log-likelihood:" in yellow %-12.4f `ll' +di +noi di in green _col(4) "Items" _col(16) "Parameters" _col(29) "std Err." +di in green _col(4) "{hline 33}" +forvalues i=1/`part1' { + if `part1'!=1 { + noi di in yellow _col(4) "``i''" _col(18) %8.5f `beta1'[1,`i'] _col(30) %6.5f sqrt(`Varbeta1'[`i',`i']) + } + else { + noi di in yellow _col(4) "``i''" _col(18) %8.5f `parambeta`firstpart1'' _col(30) "." + } +} +di in green _col(4) "{hline 33}" +forvalues i=`firstpart2'/`=`part1'+`part2'' { + if `part2'!=1 { + noi di in yellow _col(4) "``i''" _col(18) %8.5f `beta2'[1,`=`i'-`part1''] _col(30) %6.5f sqrt(`Varbeta2'[`=`i'-`part1'',`=`i'-`part1'']) + } + else { + noi di in yellow _col(4) "``i''" _col(18) %8.5f `parambeta`firstpart2'' _col(30) "." + } +} +di in green _col(4) "{hline 33}" +forvalues i=1/`nbpart' { + noi di in yellow _col(4) "Var`i'" _col(18) %8.5f `var`i'' /*_col(30) %6.5f `sevar`i''*/ +} +di in green _col(4) in yellow "cov12" _col(18) %8.5f `cov12' /*_col(30) %6.5f `secov'*/ +di in green _col(4) "{hline 33}" +} +if "`trace'"=="" { + di in green "Add the trace option to obtain the standard errors of the elements" + di in green "of the covariance matrix of the latent traits" +} + +ereturn clear +ereturn scalar AIC=`AIC' +ereturn scalar ll=`ll' +ereturn scalar dimension=`nbpart' +forvalues i=1/`nbpart' { + ereturn scalar nbitems`i'=`part`i'' + ereturn local set`i' `set`i'' + if `part`i''>1 { + ereturn matrix beta`i'=`beta`i'' + ereturn matrix Varbeta`i' `Varbeta`i'' + } + else { + ereturn scalar beta`i'=`parambeta`firstpart`i''' + } +} + +*ereturn matrix cosig=`cosig' +*ereturn matrix varsig=`varsig' + +tempname matrixsigma +matrix `matrixsigma'=(`sigma1',`sigma2',`cov12') +matrix colnames `matrixsigma'= sigma1 sigma2 cov12 +ereturn matrix sigma=`matrixsigma' + +drop _all +qui use `savemmsrm' +end diff --git a/Modules/ado/personal/m/msp.ado b/Modules/ado/personal/m/msp.ado new file mode 100644 index 0000000..eef143a --- /dev/null +++ b/Modules/ado/personal/m/msp.ado @@ -0,0 +1,454 @@ +*! Version 8.1.1 26 September 2013 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : msp +* Mokken Scale Procedure +* Release 8.1.1: (September 26, 2013) [Jean-Benoit Hardouin] /*correction of a rare bug */ +* +* Historic : +* Version 1 - lose version (August 20, 2002) [Jean-Benoit Hardouin] +* Version 2 (September 25, 2002) [Jean-Benoit Hardouin] +* Version 3 (December 1, 2003) [Jean-Benoit Hardouin] +* Version 4 (January 20, 2004) [Jean-Benoit Hardouin] +* Version 5 (March 22, 2004) [Jean-Benoit Hardouin] +* Version 5.1 (May 1st, 2004) [Jean-Benoit Hardouin] +* Version 6 : (July 5, 2004) [Jean-Benoit Hardouin] +* Version 6.1 : (September 5, 2004) [Jean-Benoit Hardouin] +* Version 6.2 : (January 22, 2006) [Jean-Benoit Hardouin] /*English improvements*/ +* Release 6.3 : (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */ +* Release 6.6: (Februar 16, 2007) [Jean-Benoit Hardouin] /*Tests of the loevinger H indices, adaptation for loevH 6.6, noadjust option, improvements*/ +* Release 8: (December 8, 2010) [Jean-Benoit Hardouin] /*Adaptation for loevh version 8*/ +* Release 8.1: (December 19, 2012) [Jean-Benoit Hardouin] /*correction of a bug with the notest option*/ +* Release 8.1.1: (September 26, 2013) [Jean-Benoit Hardouin] /*correction of a rare bug */ +* +* Jean-benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences +* Department of Biostatistics - France +* jean-benoit.hardouin@anaqol.org +* +* The Stata program loevh is needed. It can be downloaded on http://www.anaqol.org +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2002-2007, 2010, 2012 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define msp , rclass +version 7.0 +syntax varlist(min=2 numeric) [,c(real 0.3) noDETails KERnel(integer 0) noTEst p(real 0.05) PAIRWise MINValue(real 0) noBon noADJust] +local nbitems : word count `varlist' +tokenize `varlist' +tempfile mspfile +qui save "`mspfile'" + +if "`pairwise'"=="" { + forvalues j=1/`nbitems' { + qui drop if ``j''==. + } +} +if "`test'"!="" { + local p=1 + local minvalue=-99 + local bon nobon +} + + + +qui loevh `varlist',`pairwise' pair `adjust' +tempname pvalHjk loevHjk loevHjks loevHj loevH Hjk stopscale stop dim plusitems Hjkmax Hjmax Hmax nbitemsel +matrix `loevHjk'=r(loevHjk) +matrix `loevHjks'=r(loevHjk) +matrix `pvalHjk'=r(pvalHjk) +matrix `loevHj'=r(loevHj) +scalar `loevH'=r(loevH) +matrix `Hjk'=`loevHjk' + +matrix define `dim'=J(1,`nbitems',0) + +global scale=0 +scalar `stopscale'=0 + +while `stopscale'!=1 { /*WHILE IT IS POSSIBLE TO CONSTRUCT SCALES*/ + global scale=$scale+1 + local dimension=$scale + local scaletmp="scale$scale" + local scaletmpnum="scalenum$scale" + global `scaletmp' + global `scaletmpnum' + if "`details'"=="" { + di + di in yellow "Scale: $scale" + di "{hline 10}" + } + +/********************************************************************************************************** +BEGINING OF THE INITIAL STEP +**********************************************************************************************************/ + +/****NONE KERNEL OR NOT THE FIRST SCALE****/ + if $scale>1|`kernel'==0 { + scalar `plusitems'=0 + scalar `Hjkmax'=-99 + local nbitemsbon=0 + forvalues j1=1/`nbitems' { + if `dim'[1,`j1']==0 { + local nbitemsbon=`nbitemsbon'+1 + } + } + if `nbitemsbon'<=1 { + local nbitemsbon=2 + } + local kbon=`nbitemsbon'*(`nbitemsbon'-1)/2 + if "`bon'"==""&"`test'"=="" { + local pbon=`p'/`kbon' + } + else { + local pbon=`p' + } + if "`test'"!="" { + local pbon=1 + local p=1 + } + if "`details'"==""&"`test'"=="" { + di in green "Significance level: " in yellow %8.6f `pbon' + } + forvalues j1=1/`nbitems' { /*WE SEARCH THE BEST PAIR OF ITEMS*/ + if `dim'[1,`j1']==0 { + scalar `plusitems'=1 + forvalues j2=`=`j1'+1'/`nbitems' { + if `dim'[1,`j2']==0 { + if `Hjk'[`j1',`j2']>`Hjkmax'&`pvalHjk'[`j1',`j2']<=`pbon' { + scalar `Hjkmax'=`Hjk'[`j1',`j2'] + global j1max=`j1' + global j2max=`j2' + } + } + } + } + } + + if `Hjkmax'==-99 { /*IF NONE PAIR OF ITEM VERIFY Hjk>0*/ + if `plusitems'==0 { + if "`details'"=="" { + di in green "{p}There is no more items remaining.{p_end}" + } + } + else { + if "`details'"=="" { + di as green "{p}None pair of items has a significantly positive Hjk coefficient.{p_end}" + } + } + continue, break + } + + if `Hjkmax'<=`c' { /*IF NONE PAIR OF ITEM VERIFY Hjk>c*/ + if $scale==1 { + if "`details'"=="" { + di as green "{p}None pair of items verifies Hjk>`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed.{p_end}" + } + } + else { + if "`details'"=="" { + di as green "{p}None new scale can be constructed because none pair of items, among the remaining items, verifies Hjk>`c'{p_end}" + } + } + scalar `stop'=1 + scalar `stopscale'=1 + continue, break + } + else { /*IF THERE IS AT LEAST ONE PAIR OF ITEM WHO VERIFY Hjk>c*/ + matrix `dim'[1,$j1max]=$scale + matrix `dim'[1,$j2max]=$scale + local scaletmp="scale$scale" + local scaletmpnum="scalenum$scale" + global `scaletmp' "`$j1max' `$j2max'" + global `scaletmpnum' "$j1max $j2max" + if "`details'"=="" { + di in green "{p}The two first items selected in the scale " in yellow "$scale " in green "are " in yellow "`$j1max' " in green "and " in yellow "`$j2max'" in green " (Hjk=" in yellow %6.4f `Hjkmax' in green "){p_end}" + } + scalar `nbitemsel'=2 + } + forvalues i=1/`nbitems' { /*WE EXCLUDE THE ITEMS WHICH VERIFY Hjk<0 WITH THE TWO SELECTED ITEMS*/ + if ((`loevHjks'[`i',$j1max]<`minvalue'|`pvalHjk'[`i',$j1max]>`p')&`dim'[1,`i']==0) { + matrix `dim'[1,`i']=-1 + } + if ((`loevHjks'[`i',$j2max]<`minvalue'|`pvalHjk'[`i',$j2max]>`p')&`dim'[1,`i']==0) { + matrix `dim'[1,`i']=-1 + } + } + } +/****FIRST SCALE, KERNEL OF ONE ITEM****/ + if $scale==1&`kernel'==1 { + global j1max=1 + scalar `plusitems'=0 + scalar `Hjkmax'=-99 + if "`details'"=="" { + di in green "The item " in yellow "`1'" in green " is the kernel of the first scale" + } + local nbitemsbon=0 + forvalues i=2/`nbitems' { /*WE EXCLUDE THE ITEM WHICH VERIFY Hjk<0 WITH THE ITEM OF THE KERNEL*/ + if (`loevHjks'[`i',$j1max]<`minvalue'|`pvalHjk'[`i',$j1max]>`p')&`dim'[1,`i']==0) { + matrix `dim'[1,`i']=-1 + } + if `dim'[1,`i']==0 { + local nbitemsbon=`nbitemsbon'+1 + } + } + local kbon=`nbitemsbon' + if "`bon'"==""&"`test'"=="" { + local pbon=`p'/`kbon' + } + else { + local pbon=`p' + } + if "`details'"==""&"`test'"=="" { + di in green "Significance level: " in yellow %8.6f `pbon' + } + forvalues j2=2/`nbitems' {/*WE SEARCH THE BEST ITEM TO SELECT WITH THE KERNEL*/ + if `Hjk'[`j2',1]>`Hjkmax'&`pvalHjk'[`j2',1]<`pbon' { + scalar `Hjkmax'=`Hjk'[`j2',1] + global j2max=`j2' + } + } + + if `Hjkmax'==-99 {/*IF NONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk<*/ + if "`details'"=="" { + di as green "{p}None item associated to the item " in yellow "$j1 " in green "allows obtaining a significantly positive value for the Hjk coefficient.{p_end}" + } + continue, break + } + + if `Hjkmax'<=`c' { /*IF NONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed.{p_end}" + } + scalar `stop'=1 + scalar `stopscale'=1 + continue, break + } + else { /* IF AT LEAST ONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk>c*/ + matrix `dim'[1,$j1max]=$scale + matrix `dim'[1,$j2max]=$scale + local scaletmp="scale$scale" + local scaletmpnum="scalenum$scale" + global `scaletmp' "`$j2max' `$j1max'" + global `scaletmpnum' "$j2max $j1max" + if "`details'"=="" { + di in green "The second item selected in the first scale is " in yellow "`$j2max' " in green "(Hjk=" in yellow %6.4f `Hjkmax' in green")" + } + scalar `nbitemsel'=2 + } + forvalues i=1/`nbitems' { /*WE EXCLUDE THE ITEM WHICH VERIFY Hjk<0 WITH THE NEW SELECTED ITEM*/ + if (`loevHjks'[`i',$j2max]<`minvalue'|`pvalHjk'[`i',$j2max]>`p')&`dim'[1,`i']==0 { + matrix `dim'[1,`i']=-1 + } + } + } +/****FIRST SCALE, KERNEL OF SEVERAL ITEMS****/ + if $scale==1&`kernel'>=2 { + global scale1 + local scalenum1 + local kbon=1 + local pbon=`p' + if "`details'"==""&"`test'"=="" { + di in green "Significance level: " in yellow %8.6f `pbon' + } + forvalues j2=1/`kernel' { + global scale1 ``j2'' $scale1 + global scalenum1 $scalenum1 `j2' + matrix `dim'[1,`j2']=1 + } + if "`details'"=="" { + di in green "{p}The kernel of the first scale is composed of the items " in yellow "$scale1{p_end}" + } + scalar `nbitemsel'=`kernel' + forvalues j=1/`kernel' { + forvalues i=1/`nbitems' { /* WE EXCLUDE THE ITEMS WHICH VERIFY Hjk<0 WITH THE ITEMS OF THE KERNEL*/ + if (`loevHjks'[`i',`j']<`minvalue'|`pvalHjk'[`i',`j']>`p')&`dim'[1,`i']==0 { + matrix `dim'[1,`i']=-1 + } + } + } + } + local excluded + forvalues i=1/`nbitems' { + if `dim'[1,`i']==-1 { + local excluded `excluded' ``i'' + matrix `dim'[1,`i']=-2 + } + } + if "`excluded'"!=""&"`details'"=="" { + di in green "The following items are excluded at this step: " in yellow "`excluded'" + } + scalar `stop'=0 + +/********************************************************************************************************** +END OF THE INITIAL STEP +**********************************************************************************************************/ + + while `stop'!=1 { /*WHILE THE PROCEDURE TO CONSTRUCT THE ACTUAL SCALE IS NOT STOPPED*/ + + scalar `Hjmax'=-99 + scalar `Hmax'=-99 + global jmax=0 + + global stopmax=0 + local nbitemsbon=0 + forvalues i=1/`nbitems' { + if `dim'[1,`i']==0 { + local nbitemsbon=`nbitemsbon'+1 + } + } + local kbon=`kbon'+`nbitemsbon' + if "`bon'"=="" { + local pbon=`p'/`kbon' + } + else { + local pbon=`p' + } + if "`details'"==""&"`test'"=="" { + di in green "Significance level: " in yellow %8.6f `pbon' + } + + + forvalues j0=1/`nbitems' { + if `dim'[1,`j0']==0 {/*IF THE ITEM J0 IS UNSELECTED*/ + global stopmax=1 + local scaletmp="scale$scale" + local scaletmpnum="scalenum$scale" + qui loevh ``j0'' $`scaletmp' ,`pairwise' pair `adjust' + tempname pvalHj0 + matrix `pvalHj0'=r(pvalHj) + scalar `pvalHj0'=`pvalHj0'[1,1] + matrix `loevHjk'=r(loevHjk) + matrix `loevHj'=r(loevHj) + scalar `loevH'=r(loevH) + + local nbitsc : word count $`scaletmp' + local nbitsc=`nbitsc'+1 + if `loevHj'[1,1]>`c'&`pvalHj0'<`pbon' {/*IF THE ITEM J0 CAN BE SELECTED*/ + if `loevH'>`Hmax' {/*AND IF IT IS THE BEST ITEM (COMPARED TO THE PRECEEDING ITEMS)*/ + scalar `Hjmax'=`loevHj'[1,1] + scalar `Hmax'=`loevH' + global j="``j0''" + global j0=`j0' + } + } + } + } + + if $stopmax==1&`Hjmax'==-99 { /*IF THERE IS ITEMS REMAINING BUT NONE OF THEM CAN BE SELECTED*/ + + if "`details'"=="" { + di in green "{p}None new item can be selected in the scale $scale because all the Hj are lesser than `c' or none new item has all the related Hjk coefficients significantly greater than 0{p_end}." + } + scalar `stop'=1 + continue,break + } + if $stopmax==0 { /*IF THERE IS NO MORE ITEM REMAINING*/ + if "`details'"=="" { + di in green "{p}There is no more items remaining.{p_end}" + } + scalar `stopscale'=1 + scalar `stop'=1 + forvalues i=1/`nbitems' { + if `dim'[1,`i']<0 { + scalar `stopscale'=0 + } + } + *global scale=$scale-1 + continue,break + } + + + if `stop'!=1 { /*IF THE PROCEDURE IS NOT STOPPED*/ + matrix `dim'[1,$j0]=$scale + local `scaletmp'="scale$scale" + local `scaletmpnum'="scalenum$scale" + global `scaletmp' $j $`scaletmp' + global `scaletmpnum' $j0 $`scaletmpnum' + if "`details'"=="" { + di in green "The item " in yellow "`$j0' " in green "is selected in the scale " in yellow "$scale" _col(50) in green "Hj=" in yellow %6.4f `Hjmax' _col(65) in green "H=" in yellow %6.4f `Hmax' "" + } + local excluded + forvalues i=1/`nbitems' { + if `dim'[1,`i']==-1 { + matrix `dim'[1,`i']=-2 + } + if `dim'[1,`i']==0 { /*WE EXCLUDE ITEMS WHO HAVE A NEGATIVE Hjk WITH THE NEW SELECTED ITEM*/ + if `loevHjks'[`i',$j0]<`minvalue'|`pvalHjk'[`i',$j0]>`p' { + matrix `dim'[1,`i']=-1 + local excluded `excluded' ``i'' + } + } + } + if "`excluded'"!=""&"`details'"=="" { + di in green "The following items are excluded at this step: " in yellow "`excluded'" + } + } + } + di + local scaleencours="scale$scale" + local scalenumencours="scalenum$scale" + local nbitemscale : word count $`scaleencours' + return scalar nbitems`dimension'=`nbitemscale' + if `nbitemscale'>0 { /* IF AT LEAST TWO ITEMS HAVE BEEN SELECTED*/ + if "`details'"!="" { + di + di in yellow "Scale: $scale" + di "{hline 10}" + } + loevh $`scaleencours',`pairwise' `adjust' + matrix `loevHjk'=r(loevHjk) + matrix `loevHj'=r(loevHj) + scalar `loevH'=r(loevH) + + return scalar H`dimension'=`loevH' + return local scale`dimension' $`scaleencours' + return local scalenum`dimension' $`scalenumencours' + local j=`nbitemscale' + di + } + forvalues i=1/`nbitems' { + if `dim'[1,`i']<0 { + matrix `dim'[1,`i']=0 + } + } + + local restnbitems=0 + forvalues j0=1/`nbitems' { + if `dim'[1,`j0']==0 { + local restnbitems=`restnbitems'+1 + local restitem ``j0'' + } + } + + if `restnbitems'==1 { /*IF THERE IS ONLY ONE ITEM REMAINING*/ + di + di in green "{p}There is only one item remaining (" in yellow "`restitem'" in green ").{p_end}" + local stopscale=1 + return local lastitem "`restitem'" + } + +} + +return scalar dim=$scale +matrix colnames `dim'=`varlist' +return matrix selection=`dim' + +qui use "`mspfile'",clear +end diff --git a/Modules/ado/personal/m/msp.hlp b/Modules/ado/personal/m/msp.hlp new file mode 100644 index 0000000..7a51eb4 --- /dev/null +++ b/Modules/ado/personal/m/msp.hlp @@ -0,0 +1,94 @@ +{smcl} +{* 8december2010}{...} +{hline} +help for {hi:msp} +{hline} + +{title:Mokken Scale Procedure} + +{p 8 14 2}{cmd:msp} {it:varlist} [{cmd:,} {cmdab:nodet:ails} +{cmdab:ker:nel}({it:#}) {cmdab:c}({it:#}) {cmdab:note:st} {cmdab:p}({it:#}) +{cmdab:pairw:ise} {cmdab:minv:alue}({it:#}) {cmdab:nob:on} {cmdab:noadj:ust}] + + +{p 8 14 2}{it:varlist} is a list of two existing dichotomous or polytomous variables or more. + +{title:Description} + +{p 4 8 2}{cmd:msp} selects scales of dichotomous or polytomous items with the Mokken Scale Procedure (MSP) defined by Mokken (1971) and by Hemker and al. (1995). + +{title:Options} + +{p 4 8 2}{cmd:nodetails} does not display informations during the algorithm of selection. + +{p 4 8 2}{cmd:kernel} defines a kernel for the first scale, defined as the first # items of {it:varlist}. + +{p 4 8 2}{cmd:c} defines the level of the threshold {it:c}. The level of {it:c} is fixed, by default, at 0.3. + +{p 4 8 2}{cmd:notest} selects the scales whithout tests among the Loevinger H coefficient (Hjk>0): the new item with the maximal value for Hj>c is always selected. + +{p 4 8 2}{cmd:p} defines the significance level for the tests. The level of {it:p} is fixed, by default, at 0.05. + +{p 4 8 2}{cmd:pairwise} does no more delete all the individuals who have one or more missing values among all the items of {it:varlist} but, only these ones who have, for each pair of items, one or more missing values to these two items. + +{p 4 8 2}{cmd:minvalue} defines the minimum value of the coefficient Hjk for a pair of item composing a scale. This minimal value is fixed by default to 0. + +{p 4 8 2}{cmd:nobon} does no more correct the significance level of the test by the Bonferroni correction. + +{p 4 8 2}{cmd:noadjust} approximates the tests statistics like the MSP program (Molenaar et al. (2000)). + +{title:Remarks} + +{p 4 8 2}For detailed informations on the Mokken scale procedure, see Mokken (1971), Hemker and al. (1995) or the manual of the MSP software (2000). + +{p 4 8 2}{cmd:msp} runs with dichotomous or polytomous items. + +{p 4 8 2}{cmd:msp} necessitates the program {help loevh} to compute. + +{title:Results} + +{p 4 8 2}{it:r(dim)} saves the number of built scales. + +{p 4 8 2}{it:r(selection)} saves a vector which contains, for each item, the scale where it is selected (0 if the item is unselected). + +{p 4 8 2}{it:r(H#)} saves the Loevinger's H coefficient of the #th scale. + +{p 4 8 2}{it:r(nbitems#)} saves the number of items selected in the #th scale. + +{p 4 8 2}{it:r(scale#)} saves the names of the items selected in the #th scale. + +{p 4 8 2}{it:r(scalenum#)} saves the numbers of the items selected in the #th scale. + +{title:Example} + + {inp:. msp itemA1-itemA7} + + {inp:. msp itemA* itemB* , nodetails kernel(2)} + + {inp:. msp item* , c(0.2) nob pairwise} + + +{title:References} + +{p 4 8 2}Hemker B. T., Sijtsma K. and Molenaar I. W., Selection of unidimensional scales from a multidimensional item bank in the polytomous Mokken IRT +model, {it: Applied Psychological Measurement}, vol.19(4), 1995, pp. 337-352. + +{p 4 8 2}Mokken R. J., A theory and procedure of scale analysis. New-York/Berlin : De Guyter, 1971. + +{p 4 8 2}Molenaar I. W., Sijtsma K. and Boer P. User's manual of MSP5 for Windows. Groningen (The Netherlands): iec ProGAMMA, 2000. + +{title:Also see} + +{p 4 13 2} help for {help loevh} (if installed), help for {help mokken} (if installed) + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end} +{p 4 8 2}EA 4275 "Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences"{p_end} +{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end} +{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end} +{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end} +{p 4 8 2}Email: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol} +and {browse "http://www.freeirt.org":FreeIRT} diff --git a/Modules/ado/personal/m/msp66.ado b/Modules/ado/personal/m/msp66.ado new file mode 100644 index 0000000..23cb1fc --- /dev/null +++ b/Modules/ado/personal/m/msp66.ado @@ -0,0 +1,447 @@ +*! Version 6.6 16 Februar 2007 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : msp +* Mokken Scale Procedure +* Release 6.6: Februar 16, 2007 /*Tests of the loevinger H indices, adaptation for loevH 6.6, noadjust option, improvements*/ +* +* Historic : +* Version 1 - lose version (August 20, 2002) [Jean-Benoit Hardouin] +* Version 2 (September 25, 2002) [Jean-Benoit Hardouin] +* Version 3 (December 1, 2003) [Jean-Benoit Hardouin] +* Version 4 (January 20, 2004) [Jean-Benoit Hardouin] +* Version 5 (March 22, 2004) [Jean-Benoit Hardouin] +* Version 5.1 (May 1st, 2004) [Jean-Benoit Hardouin] +* Version 6 : (July 5, 2004) [Jean-Benoit Hardouin] +* Version 6.1 : (September 5, 2004) [Jean-Benoit Hardouin] +* Version 6.2 : (January 22, 2006) [Jean-Benoit Hardouin] /*English improvements*/ +* Release 6.3 : (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */ +* +* Jean-benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences +* Department of Biostatistics - France +* jean-benoit.hardouin@anaqol.org +* +* The Stata program loevH is needed. It can be downloaded on http://www.anaqol.org +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2002-2007 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define msp , rclass +version 7.0 +syntax varlist(min=2 numeric) [,c(real 0.3) noDETails KERnel(integer 0) noTEst p(real 0.05) PAIRWise MINValue(real 0) noBon noADJust] +local nbitems : word count `varlist' +tokenize `varlist' +tempfile mspfile +qui save "`mspfile'" + +if "`pairwise'"=="" { + forvalues j=1/`nbitems' { + qui drop if ``j''==. + } +} +if "`test'"!="" { + local p=1 + local minvalue=-99 + local bon nobon +} + + + +qui loevH `varlist',`pairwise' pair `adjust' +tempname pvalHjk loevHjk loevHjks loevHj loevH Hjk stopscale stop dim plusitems Hjkmax Hjmax Hmax nbitemsel +matrix `loevHjk'=r(loevHjk) +matrix `loevHjks'=r(loevHjk) +matrix `pvalHjk'=r(pvalHjk) +matrix `loevHj'=r(loevHj) +scalar `loevH'=r(loevH) +matrix `Hjk'=`loevHjk' + +matrix define `dim'=J(1,`nbitems',0) + +global scale=0 +scalar `stopscale'=0 + +while `stopscale'!=1 { /*WHILE IT IS POSSIBLE TO CONSTRUCT SCALES*/ + global scale=$scale+1 + local dimension=$scale + local scaletmp="scale$scale" + local scaletmpnum="scalenum$scale" + global `scaletmp' + global `scaletmpnum' + if "`details'"=="" { + di + di in yellow "Scale: $scale" + di "{hline 10}" + } + + +/********************************************************************************************************** +BEGINING OF THE INITIAL STEP +**********************************************************************************************************/ + +/****NONE KERNEL OR NOT THE FIRST SCALE****/ + if $scale>1|`kernel'==0 { + scalar `plusitems'=0 + scalar `Hjkmax'=-99 + local nbitemsbon=0 + forvalues j1=1/`nbitems' { + if `dim'[1,`j1']==0 { + local nbitemsbon=`nbitemsbon'+1 + } + } + if `nbitemsbon'<=1 { + local nbitemsbon=2 + } + local kbon=`nbitemsbon'*(`nbitemsbon'-1)/2 + if "`bon'"=="" { + local pbon=`p'/`kbon' + } + else { + local pbon=`p' + } + if "`details'"==""&"`test'"=="" { + di in green "Significance level: " in yellow %8.6f `pbon' + } + forvalues j1=1/`nbitems' { /*WE SEARCH THE BEST PAIR OF ITEMS*/ + if `dim'[1,`j1']==0 { + scalar `plusitems'=1 + forvalues j2=`=`j1'+1'/`nbitems' { + if `dim'[1,`j2']==0 { + if `Hjk'[`j1',`j2']>`Hjkmax'&`pvalHjk'[`j1',`j2']<=`pbon' { + scalar `Hjkmax'=`Hjk'[`j1',`j2'] + global j1max=`j1' + global j2max=`j2' + } + } + } + } + } + + if `Hjkmax'==-99 { /*IF NONE PAIR OF ITEM VERIFY Hjk>0*/ + if `plusitems'==0 { + if "`details'"=="" { + di in green "{p}There is no more items remaining.{p_end}" + } + } + else { + if "`details'"=="" { + di as green "{p}None pair of items has a significantly positive Hjk coefficient.{p_end}" + } + } + continue, break + } + + if `Hjkmax'<=`c' { /*IF NONE PAIR OF ITEM VERIFY Hjk>c*/ + if $scale==1 { + if "`details'"=="" { + di as green "{p}None pair of items verifies Hjk>`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed.{p_end}" + } + } + else { + if "`details'"=="" { + di as green "{p}None new scale can be constructed because none pair of items, among the remaining items, verifies Hjk>`c'{p_end}" + } + } + scalar `stop'=1 + scalar `stopscale'=1 + continue, break + } + else { /*IF THERE IS AT LEAST ONE PAIR OF ITEM WHO VERIFY Hjk>c*/ + matrix `dim'[1,$j1max]=$scale + matrix `dim'[1,$j2max]=$scale + local scaletmp="scale$scale" + local scaletmpnum="scalenum$scale" + global `scaletmp' "`$j1max' `$j2max'" + global `scaletmpnum' "$j1max $j2max" + if "`details'"=="" { + di in green "{p}The two first items selected in the scale " in yellow "$scale " in green "are " in yellow "`$j1max' " in green "and " in yellow "`$j2max'" in green " (Hjk=" in yellow %6.4f `Hjkmax' in green "){p_end}" + } + scalar `nbitemsel'=2 + } + forvalues i=1/`nbitems' { /*WE EXCLUDE THE ITEMS WHICH VERIFY Hjk<0 WITH THE TWO SELECTED ITEMS*/ + if (`loevHjks'[`i',$j1max]<`minvalue'|`pvalHjk'[`i',$j1max]>.05)&`dim'[1,`i']==0 { + matrix `dim'[1,`i']=-1 + } + if (`loevHjks'[`i',$j2max]<`minvalue'|`pvalHjk'[`i',$j2max]>.05)&`dim'[1,`i']==0 { + matrix `dim'[1,`i']=-1 + } + } + } +/****FIRST SCALE, KERNEL OF ONE ITEM****/ + if $scale==1&`kernel'==1 { + global j1max=1 + scalar `plusitems'=0 + scalar `Hjkmax'=-99 + if "`details'"=="" { + di in green "The item " in yellow "`1'" in green " is the kernel of the first scale" + } + local nbitemsbon=0 + forvalues i=2/`nbitems' { /*WE EXCLUDE THE ITEM WHICH VERIFY Hjk<0 WITH THE ITEM OF THE KERNEL*/ + if (`loevHjks'[`i',$j1max]<`minvalue'|`pvalHjk'[`i',$j1max]>.05)&`dim'[1,`i']==0 { + matrix `dim'[1,`i']=-1 + } + if `dim'[1,`i']==0 { + local nbitemsbon=`nbitemsbon'+1 + } + } + local kbon=`nbitemsbon' + if "`bon'"=="" { + local pbon=`p'/`kbon' + } + else { + local pbon=`p' + } + if "`details'"==""&"`test'"=="" { + di in green "Significance level: " in yellow %8.6f `pbon' + } + forvalues j2=2/`nbitems' {/*WE SEARCH THE BEST ITEM TO SELECT WITH THE KERNEL*/ + if `Hjk'[`j2',1]>`Hjkmax'&`pvalHjk'[`j2',1]<`pbon' { + scalar `Hjkmax'=`Hjk'[`j2',1] + global j2max=`j2' + } + } + + if `Hjkmax'==-99 {/*IF NONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk<*/ + if "`details'"=="" { + di as green "{p}None item associated to the item " in yellow "$j1 " in green "allows obtaining a significantly positive value for the Hjk coefficient.{p_end}" + } + continue, break + } + + if `Hjkmax'<=`c' { /*IF NONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed.{p_end}" + } + scalar `stop'=1 + scalar `stopscale'=1 + continue, break + } + else { /* IF AT LEAST ONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk>c*/ + matrix `dim'[1,$j1max]=$scale + matrix `dim'[1,$j2max]=$scale + local scaletmp="scale$scale" + local scaletmpnum="scalenum$scale" + global `scaletmp' "`$j2max' `$j1max'" + global `scaletmpnum' "$j2max $j1max" + if "`details'"=="" { + di in green "The second item selected in the first scale is " in yellow "`$j2max' " in green "(Hjk=" in yellow %6.4f `Hjkmax' in green")" + } + scalar `nbitemsel'=2 + } + forvalues i=1/`nbitems' { /*WE EXCLUDE THE ITEM WHICH VERIFY Hjk<0 WITH THE NEW SELECTED ITEM*/ + if (`loevHjks'[`i',$j2max]<`minvalue'|`pvalHjk'[`i',$j2max]>.05)&`dim'[1,`i']==0 { + matrix `dim'[1,`i']=-1 + } + } + } +/****FIRST SCALE, KERNEL OF SEVERAL ITEMS****/ + if $scale==1&`kernel'>=2 { + global scale1 + local scalenum1 + local kbon=1 + local pbon=`p' + if "`details'"==""&"`test'"=="" { + di in green "Significance level: " in yellow %8.6f `pbon' + } + forvalues j2=1/`kernel' { + global scale1 ``j2'' $scale1 + global scalenum1 $scalenum1 `j2' + matrix `dim'[1,`j2']=1 + } + if "`details'"=="" { + di in green "{p}The kernel of the first scale is composed of the items " in yellow "$scale1{p_end}" + } + scalar `nbitemsel'=`kernel' + forvalues j=1/`kernel' { + forvalues i=1/`nbitems' { /* WE EXCLUDE THE ITEMS WHICH VERIFY Hjk<0 WITH THE ITEMS OF THE KERNEL*/ + if (`loevHjks'[`i',`j']<`minvalue'|`pvalHjk'[`i',`j']>.05)&`dim'[1,`i']==0 { + matrix `dim'[1,`i']=-1 + } + } + } + } + local excluded + forvalues i=1/`nbitems' { + if `dim'[1,`i']==-1 { + local excluded `excluded' ``i'' + matrix `dim'[1,`i']=-2 + } + } + if "`excluded'"!=""&"`details'"=="" { + di in green "The following items are excluded at this step: " in yellow "`excluded'" + } + scalar `stop'=0 + +/********************************************************************************************************** +END OF THE INITIAL STEP +**********************************************************************************************************/ + + while `stop'!=1 { /*WHILE THE PROCEDURE TO CONSTRUCT THE ACTUAL SCALE IS NOT STOPPED*/ + + scalar `Hjmax'=-99 + scalar `Hmax'=-99 + global jmax=0 + + global stopmax=0 + local nbitemsbon=0 + forvalues i=1/`nbitems' { + if `dim'[1,`i']==0 { + local nbitemsbon=`nbitemsbon'+1 + } + } + local kbon=`kbon'+`nbitemsbon' + if "`bon'"=="" { + local pbon=`p'/`kbon' + } + else { + local pbon=`p' + } + if "`details'"==""&"`test'"=="" { + di in green "Significance level: " in yellow %8.6f `pbon' + } + + + forvalues j0=1/`nbitems' { + if `dim'[1,`j0']==0 {/*IF THE ITEM J0 IS UNSELECTED*/ + global stopmax=1 + local scaletmp="scale$scale" + local scaletmpnum="scalenum$scale" + qui loevH ``j0'' $`scaletmp' ,`pairwise' pair `adjust' + tempname pvalHj0 + matrix `pvalHj0'=r(pvalHj) + scalar `pvalHj0'=`pvalHj0'[1,1] + matrix `loevHjk'=r(loevHjk) + matrix `loevHj'=r(loevHj) + scalar `loevH'=r(loevH) + + local nbitsc : word count $`scaletmp' + local nbitsc=`nbitsc'+1 + if `loevHj'[1,1]>`c'&`pvalHj0'<`pbon' {/*IF THE ITEM J0 CAN BE SELECTED*/ + if `loevH'>`Hmax' {/*AND IF IT IS THE BEST ITEM (COMPARED TO THE PRECEEDING ITEMS)*/ + scalar `Hjmax'=`loevHj'[1,1] + scalar `Hmax'=`loevH' + global j="``j0''" + global j0=`j0' + } + } + } + } + + if $stopmax==1&`Hjmax'==-99 { /*IF THERE IS ITEMS REMAINING BUT NONE OF THEM CAN BE SELECTED*/ + + if "`details'"=="" { + di in green "{p}None new item can be selected in the scale $scale because all the Hj are lesser than `c' or none new item has all the related Hjk coefficients significantly greater than 0{p_end}." + } + scalar `stop'=1 + continue,break + } + if $stopmax==0 { /*IF THERE IS NO MORE ITEM REMAINING*/ + if "`details'"=="" { + di in green "{p}There is no more items remaining.{p_end}" + } + scalar `stopscale'=1 + scalar `stop'=1 + forvalues i=1/`nbitems' { + if `dim'[1,`i']<0 { + scalar `stopscale'=0 + } + } + *global scale=$scale-1 + continue,break + } + + + if `stop'!=1 { /*IF THE PROCEDURE IS NOT STOPPED*/ + matrix `dim'[1,$j0]=$scale + local `scaletmp'="scale$scale" + local `scaletmpnum'="scalenum$scale" + global `scaletmp' $j $`scaletmp' + global `scaletmpnum' $j0 $`scaletmpnum' + if "`details'"=="" { + di in green "The item " in yellow "`$j0' " in green "is selected in the scale " in yellow "$scale" _col(50) in green "Hj=" in yellow %6.4f `Hjmax' _col(65) in green "H=" in yellow %6.4f `Hmax' "" + } + local excluded + forvalues i=1/`nbitems' { + if `dim'[1,`i']==-1 { + matrix `dim'[1,`i']=-2 + } + if `dim'[1,`i']==0 { /*WE EXCLUDE ITEMS WHO HAVE A NEGATIVE Hjk WITH THE NEW SELECTED ITEM*/ + if `loevHjks'[`i',$j0]<`minvalue'|`pvalHjk'[`i',$j0]>.05 { + matrix `dim'[1,`i']=-1 + local excluded `excluded' ``i'' + } + } + } + if "`excluded'"!=""&"`details'"=="" { + di in green "The following items are excluded at this step: " in yellow "`excluded'" + } + } + } + di + local scaleencours="scale$scale" + local scalenumencours="scalenum$scale" + local nbitemscale : word count $`scaleencours' + return scalar nbitems`dimension'=`nbitemscale' + if `nbitemscale'>0 { /* IF AT LEAST TWO ITEMS HAVE BEEN SELECTED*/ + if "`details'"!="" { + di + di in yellow "Scale: $scale" + di "{hline 10}" + } + loevH $`scaleencours',`pairwise' `adjust' + matrix `loevHjk'=r(loevHjk) + matrix `loevHj'=r(loevHj) + scalar `loevH'=r(loevH) + + return scalar H`dimension'=`loevH' + return local scale`dimension' $`scaleencours' + return local scalenum`dimension' $`scalenumencours' + local j=`nbitemscale' + di + } + forvalues i=1/`nbitems' { + if `dim'[1,`i']<0 { + matrix `dim'[1,`i']=0 + } + } + + local restnbitems=0 + forvalues j0=1/`nbitems' { + if `dim'[1,`j0']==0 { + local restnbitems=`restnbitems'+1 + local restitem ``j0'' + } + } + + if `restnbitems'==1 { /*IF THERE IS ONLY ONE ITEM REMAINING*/ + di + di in green "{p}There is only one item remaining (" in yellow "`restitem'" in green ").{p_end}" + local stopscale=1 + return local lastitem "`restitem'" + } + +} + +return scalar dim=$scale +matrix colnames `dim'=`varlist' +return matrix selection=`dim' + +qui use "`mspfile'",clear +end diff --git a/Modules/ado/personal/m/msp66.hlp b/Modules/ado/personal/m/msp66.hlp new file mode 100644 index 0000000..de2a171 --- /dev/null +++ b/Modules/ado/personal/m/msp66.hlp @@ -0,0 +1,91 @@ +{smcl} +{* 22january2006}{...} +{hline} +help for {hi:msp} +{hline} + +{title:Mokken Scale Procedure} + +{p 8 14 2}{cmd:msp} {it:varlist} [{cmd:,} {cmdab:nodet:ails} +{cmdab:ker:nel}({it:#}) {cmdab:c}({it:#}) {cmdab:note:st} {cmdab:p}({it:#}) +{cmdab:pairw:ise} {cmdab:minv:alue}({it:#}) {cmdab:nob:on} {cmdab:noadj:ust}] + + +{p 8 14 2}{it:varlist} is a list of two existing dichotomous or polytomous variables or more. + +{title:Description} + +{p 4 8 2}{cmd:msp} selects scales of dichotomous or polytomous items with the Mokken Scale Procedure (MSP) defined by Mokken (1971) and by Hemker and al. (1995). + +{title:Options} + +{p 4 8 2}{cmd:nodetails} does not display informations during the algorithm of selection. + +{p 4 8 2}{cmd:kernel} defines a kernel for the first scale, defined as the first # items of {it:varlist}. + +{p 4 8 2}{cmd:c} defines the level of the threshold {it:c}. The level of {it:c} is fixed, by default, at 0.3. + +{p 4 8 2}{cmd:notest} selects the scales whithout tests among the Loevinger H coefficient (Hjk>0): the new item with the maximal value for Hj>c is always selected. + +{p 4 8 2}{cmd:p} defines the significance level for the tests. The level of {it:p} is fixed, by default, at 0.05. + +{p 4 8 2}{cmd:pairwise} does no more delete all the individuals who have one or more missing values among all the items of {it:varlist} but, only these ones who have, for each pair of items, one or more missing values to these two items. + +{p 4 8 2}{cmd:minvalue} defines the minimum value of the coefficient Hjk for a pair of item composing a scale. This minimal value is fixed by default to 0. + +{p 4 8 2}{cmd:nobon} does no more correct the significance level of the test by the Bonferroni correction. + +{p 4 8 2}{cmd:noadjust} approximates the tests statistics like the MSP program (Molenaar et al. (2000)). + +{title:Remarks} + +{p 4 8 2}For detailed informations on the Mokken scale procedure, see Mokken (1971), Hemker and al. (1995) or the manual of the MSP software (2000). + +{p 4 8 2}{cmd:msp} runs with dichotomous or polytomous items. + +{p 4 8 2}{cmd:msp} necessitates the program {help loevH} to compute. + +{title:Results} + +{p 4 8 2}{it:r(dim)} saves the number of built scales. + +{p 4 8 2}{it:r(selection)} saves a vector which contains, for each item, the scale where it is selected (0 if the item is unselected). + +{p 4 8 2}{it:r(H#)} saves the Loevinger's H coefficient of the #th scale. + +{p 4 8 2}{it:r(nbitems#)} saves the number of items selected in the #th scale. + +{p 4 8 2}{it:r(scale#)} saves the names of the items selected in the #th scale. + +{p 4 8 2}{it:r(scalenum#)} saves the numbers of the items selected in the #th scale. + +{title:Example} + + {inp:. msp itemA1-itemA7} + + {inp:. msp itemA* itemB* , nodetails kernel(2)} + + {inp:. msp item* , c(0.2) nob pairwise} + + +{title:References} + +{p 4 8 2}Hemker B. T., Sijtsma K. and Molenaar I. W., Selection of unidimensional scales from a multidimensional item bank in the polytomous Mokken IRT +model, {it: Applied Psychological Measurement}, vol.19(4), 1995, pp. 337-352. + +{p 4 8 2}Mokken R. J., A theory and procedure of scale analysis. New-York/Berlin : De Guyter, 1971. + +{p 4 8 2}Molenaar I. W., Sijtsma K. and Boer P. User's manual of MSP5 for Windows. Groningen (The Netherlands): iec ProGAMMA, 2000. + +{title:Also see} + +{p 4 13 2} help for {help loevh} (if installed), help for {help mokken} (if installed) + +{title:Author} + +{p 4 8 2} Jean-Benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences - +Department of Biostatistics. 1, rue Gaston Veil - BP 53508 - 44035 Nantes Cedex 1 - FRANCE. You can contact the +author at +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr} +and visit the websites {browse "http://www.anaqol.org":AnaQol} +and {browse "http://www.freeirt.org":FreeIRT} diff --git a/Modules/ado/personal/m/msp82.ado b/Modules/ado/personal/m/msp82.ado new file mode 100644 index 0000000..fa76381 --- /dev/null +++ b/Modules/ado/personal/m/msp82.ado @@ -0,0 +1,516 @@ +*! Version 8.2 April 30, 2014 +*! Jean-Benoit Hardouin, Bastien Perrot +************************************************************************************************************ +* Stata program : msp +* Mokken Scale Procedure +* Release 8.2: (April 30, 2014) [Jean-Benoit Hardouin, Bastien Perrot] /*HTML option, correction of a bug when kernel=1, IF option */ +* +* Historic : +* Version 1 - lose version (August 20, 2002) [Jean-Benoit Hardouin] +* Version 2 (September 25, 2002) [Jean-Benoit Hardouin] +* Version 3 (December 1, 2003) [Jean-Benoit Hardouin] +* Version 4 (January 20, 2004) [Jean-Benoit Hardouin] +* Version 5 (March 22, 2004) [Jean-Benoit Hardouin] +* Version 5.1 (May 1st, 2004) [Jean-Benoit Hardouin] +* Version 6 : (July 5, 2004) [Jean-Benoit Hardouin] +* Version 6.1 : (September 5, 2004) [Jean-Benoit Hardouin] +* Version 6.2 : (January 22, 2006) [Jean-Benoit Hardouin] /*English improvements*/ +* Release 6.3 : (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */ +* Release 6.6: (Februar 16, 2007) [Jean-Benoit Hardouin] /*Tests of the loevinger H indices, adaptation for loevH 6.6, noadjust option, improvements*/ +* Release 8: (December 8, 2010) [Jean-Benoit Hardouin] /*Adaptation for loevh version 8*/ +* Release 8.1: (December 19, 2012) [Jean-Benoit Hardouin] /*correction of a bug with the notest option*/ +* Release 8.1.1: (September 26, 2013) [Jean-Benoit Hardouin] /*correction of a rare bug */ +* Release 8.2: (April 30, 2014) [Jean-Benoit Hardouin, Bastien Perrot] /*HTML option, correction of a bug when kernel=1, IF option */ +* +* Jean-benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences +* Department of Biostatistics - France +* jean-benoit.hardouin@anaqol.org +* +* The Stata program loevh is needed. It can be downloaded on http://www.anaqol.org +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2002-2007, 2010, 2012 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define msp82 , rclass +version 7.0 +syntax varlist(min=2 numeric) [if] [,c(real 0.3) noDETails KERnel(integer 0) noTEst p(real 0.05) PAIRWise MINValue(real 0) noBon noADJust HTML(string)] +local nbitems : word count `varlist' +tokenize `varlist' +tempfile mspfile +qui save "`mspfile'" + +if "`if'"!="" { + qui keep `if' +} + +if "`pairwise'"=="" { + forvalues j=1/`nbitems' { + qui drop if ``j''==. + } +} +if "`test'"!="" { + local p=1 + local minvalue=-99 + local bon nobon +} + +if "`html'"!="" { + di "" + di "
"
+}
+
+
+qui loevh `varlist',`pairwise' pair `adjust' html(`html')
+tempname pvalHjk loevHjk loevHjks loevHj loevH Hjk stopscale stop dim  plusitems Hjkmax Hjmax Hmax nbitemsel
+matrix `loevHjk'=r(loevHjk)
+matrix `loevHjks'=r(loevHjk)
+matrix `pvalHjk'=r(pvalHjk)
+matrix `loevHj'=r(loevHj)
+scalar `loevH'=r(loevH)
+matrix `Hjk'=`loevHjk'
+
+matrix define `dim'=J(1,`nbitems',0)
+
+global scale=0
+scalar `stopscale'=0
+
+while `stopscale'!=1  { /*WHILE IT IS POSSIBLE TO CONSTRUCT SCALES*/
+	global scale=$scale+1
+	local dimension=$scale
+	local scaletmp="scale$scale"
+	local scaletmpnum="scalenum$scale"
+	global `scaletmp'
+	global `scaletmpnum'
+	if "`details'"=="" {
+		di
+		di in yellow "Scale: $scale"
+		di "{hline 10}"
+	}
+
+/**********************************************************************************************************
+BEGINING OF THE INITIAL STEP
+**********************************************************************************************************/
+
+/****NONE KERNEL OR NOT THE FIRST SCALE****/
+	if $scale>1|`kernel'==0 {
+		scalar `plusitems'=0
+		scalar `Hjkmax'=-99
+		local nbitemsbon=0
+		forvalues j1=1/`nbitems' {
+       	      		  if `dim'[1,`j1']==0 {
+	           	     	local nbitemsbon=`nbitemsbon'+1
+      	        	  }
+		}
+		if `nbitemsbon'<=1 {
+		   	  local nbitemsbon=2
+		}
+		local kbon=`nbitemsbon'*(`nbitemsbon'-1)/2
+		if "`bon'"==""&"`test'"=="" {
+		          local pbon=`p'/`kbon'
+	        }
+	        else {
+	              	  local pbon=`p'
+	        }
+	        if "`test'"!="" {
+	              	  local pbon=1
+	              	  local p=1
+	        }
+		if "`details'"==""&"`test'"=="" {
+	   	        di in green "Significance level: " in yellow %8.6f `pbon'
+		}
+		forvalues j1=1/`nbitems' { /*WE SEARCH THE BEST PAIR OF ITEMS*/
+			if `dim'[1,`j1']==0 {
+				scalar `plusitems'=1
+				forvalues j2=`=`j1'+1'/`nbitems' {
+					if `dim'[1,`j2']==0 {
+						if `Hjk'[`j1',`j2']>`Hjkmax'&`pvalHjk'[`j1',`j2']<=`pbon' {
+							scalar `Hjkmax'=`Hjk'[`j1',`j2']
+							global j1max=`j1'
+							global j2max=`j2'
+						}
+						 	       		 							}
+				}
+			}
+		}
+
+		if `Hjkmax'==-99 { /*IF NONE PAIR OF ITEM VERIFY Hjk>0*/
+			if `plusitems'==0 {
+				if "`details'"=="" {
+					if "`html" == "" {
+						di in green "{p}There is no more items remaining.{p_end}"
+					} 
+					else {
+						di in green "There is no more items remaining."
+					}
+				}
+			}
+			else {
+				if "`details'"=="" {
+					if "`html" == "" {
+						di as green "{p}None pair of items has a significantly positive Hjk coefficient.{p_end}"
+					}
+					else {
+						di as green "None pair of items has a significantly positive Hjk coefficient."
+					}
+				}
+			}
+		continue, break
+		}
+
+		if `Hjkmax'<=`c' { /*IF NONE PAIR OF ITEM VERIFY Hjk>c*/
+			if $scale==1 {
+				if "`details'"=="" {
+					if "`html'" == "" {
+						di as green "{p}None pair of items verifies Hjk>`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed.{p_end}"
+					}
+					else {
+						di as green "None pair of items verifies Hjk>`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed."
+					}
+				}
+			}
+			else {
+				if "`details'"=="" {
+					if "`html'" == "" {
+						di as green  "{p}None new scale can be constructed because none pair of items, among the remaining items, verifies Hjk>`c'{p_end}"
+					}
+					else {
+						di as green  "None new scale can be constructed because none pair of items, among the remaining items, verifies Hjk>`c'"
+					}
+				}
+			}
+			scalar `stop'=1
+			scalar `stopscale'=1
+			continue, break
+		}
+		else { /*IF THERE IS AT LEAST ONE PAIR OF ITEM WHO VERIFY Hjk>c*/
+			matrix `dim'[1,$j1max]=$scale
+			matrix `dim'[1,$j2max]=$scale
+			local scaletmp="scale$scale"
+			local scaletmpnum="scalenum$scale"
+			global `scaletmp' "`$j1max' `$j2max'"
+			global `scaletmpnum' "$j1max $j2max"
+			if "`details'"=="" {
+				if "`html'" == "" {
+					di in green "{p}The two first items selected in the scale " in yellow "$scale " in green "are " in yellow "`$j1max' " in green "and " in yellow "`$j2max'" in green " (Hjk=" in yellow %6.4f `Hjkmax' in green "){p_end}"
+				}
+				else {
+					di in green "The two first items selected in the scale " in yellow "$scale " in green "are " in yellow "`$j1max' " in green "and " in yellow "`$j2max'" in green " (Hjk=" in yellow %6.4f `Hjkmax' in green ")"
+				}
+			}
+			scalar `nbitemsel'=2
+		}
+		forvalues i=1/`nbitems' { /*WE EXCLUDE THE ITEMS WHICH VERIFY Hjk<0 WITH THE TWO SELECTED ITEMS*/
+			if ((`loevHjks'[`i',$j1max]<`minvalue'|`pvalHjk'[`i',$j1max]>`p')&`dim'[1,`i']==0) {
+			       matrix `dim'[1,`i']=-1
+			}
+			if ((`loevHjks'[`i',$j2max]<`minvalue'|`pvalHjk'[`i',$j2max]>`p')&`dim'[1,`i']==0) {
+			       matrix `dim'[1,`i']=-1
+			}
+		}
+	}
+/****FIRST SCALE, KERNEL OF ONE ITEM****/
+	if $scale==1&`kernel'==1 {
+		global j1max=1
+		scalar `plusitems'=0
+		scalar `Hjkmax'=-99
+		if "`details'"=="" {
+			di in green "The item " in yellow "`1'" in green " is the kernel of the first scale"
+		}
+		local nbitemsbon=0
+		forvalues i=2/`nbitems' {  /*WE EXCLUDE THE ITEM WHICH VERIFY Hjk<0 WITH THE ITEM OF THE KERNEL*/
+			if ((`loevHjks'[`i',$j1max]<`minvalue'|`pvalHjk'[`i',$j1max]>`p')&`dim'[1,`i']==0) {
+			       matrix `dim'[1,`i']=-1
+			}
+			if `dim'[1,`i']==0 {
+			       local nbitemsbon=`nbitemsbon'+1
+			}
+		}
+		local kbon=`nbitemsbon'
+		if "`bon'"==""&"`test'"=="" {
+		          local pbon=`p'/`kbon'
+	        }
+	        else {
+	              	  local pbon=`p'
+	        }
+		if "`details'"==""&"`test'"=="" {
+	   	        di in green "Significance level: " in yellow %8.6f `pbon'
+		}
+		forvalues j2=2/`nbitems' {/*WE SEARCH THE BEST ITEM TO SELECT WITH THE KERNEL*/
+			if `Hjk'[`j2',1]>`Hjkmax'&`pvalHjk'[`j2',1]<`pbon' {
+				scalar `Hjkmax'=`Hjk'[`j2',1]
+				global j2max=`j2'
+			}
+		}
+
+		if `Hjkmax'==-99 {/*IF NONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk<*/
+			if "`details'"=="" {
+				if "`html'" == "" {
+					di as green "{p}None item associated to the item " in yellow "$j1 " in green "allows obtaining a significantly positive value for the Hjk coefficient.{p_end}"
+				}
+				else {
+					di as green "None item associated to the item " in yellow "$j1 " in green "allows obtaining a significantly positive value for the Hjk coefficient."
+				}
+			}
+			continue, break
+		}
+
+		if `Hjkmax'<=`c' { /*IF NONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed.{p_end}"
+				}
+				else {
+					di "None index Hjk associated to the item "  in yellow "$j1 " in green "verifies Hjk>`c', the maximum value"
+					di "of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed."
+				}
+			}
+			scalar `stop'=1
+			scalar `stopscale'=1
+			continue, break
+		}
+		else { /* IF AT LEAST ONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk>c*/
+			matrix `dim'[1,$j1max]=$scale
+			matrix `dim'[1,$j2max]=$scale
+			local scaletmp="scale$scale"
+			local scaletmpnum="scalenum$scale"
+			global `scaletmp' "`$j2max' `$j1max'"
+			global `scaletmpnum' "$j2max $j1max"
+			if "`details'"=="" {
+				di in green "The second item selected in the first scale is " in yellow "`$j2max' " in green "(Hjk=" in yellow %6.4f `Hjkmax' in green")"
+			}
+			scalar `nbitemsel'=2
+		}
+		forvalues i=1/`nbitems' {  /*WE EXCLUDE THE ITEM WHICH VERIFY Hjk<0 WITH THE NEW SELECTED ITEM*/
+                        if (`loevHjks'[`i',$j2max]<`minvalue'|`pvalHjk'[`i',$j2max]>`p')&`dim'[1,`i']==0 {
+			       matrix `dim'[1,`i']=-1
+			}
+		}
+	}
+/****FIRST SCALE, KERNEL OF SEVERAL ITEMS****/
+	if $scale==1&`kernel'>=2 {
+		global scale1
+		local scalenum1
+		local kbon=1
+		local pbon=`p'
+		if "`details'"==""&"`test'"=="" {
+	   	        di in green "Significance level: " in yellow %8.6f `pbon'
+		}
+		forvalues j2=1/`kernel' {
+			global scale1 ``j2'' $scale1
+			global scalenum1 $scalenum1 `j2'
+			matrix `dim'[1,`j2']=1
+		}
+		if "`details'"=="" {
+			if "`html'" == "" {
+				di in green "{p}The kernel of the first scale is composed of the items " in yellow "$scale1{p_end}"
+			}
+			else {
+				di in green "The kernel of the first scale is composed of the items " in yellow "$scale1"
+			}
+		}
+		scalar `nbitemsel'=`kernel'
+		forvalues j=1/`kernel' {
+			forvalues i=1/`nbitems' { /* WE EXCLUDE THE ITEMS WHICH VERIFY Hjk<0 WITH THE ITEMS OF THE KERNEL*/
+				if (`loevHjks'[`i',`j']<`minvalue'|`pvalHjk'[`i',`j']>`p')&`dim'[1,`i']==0 {
+				       matrix `dim'[1,`i']=-1
+				}
+			}
+		}
+	}
+	local excluded
+	forvalues i=1/`nbitems' {
+		  if `dim'[1,`i']==-1 {
+		        local excluded `excluded' ``i''
+		        matrix `dim'[1,`i']=-2
+		  }
+	}
+	if "`excluded'"!=""&"`details'"=="" {
+	   	 di in green "The following items are excluded at this step: " in yellow "`excluded'"
+	}
+	scalar `stop'=0
+
+/**********************************************************************************************************
+END OF THE INITIAL STEP
+**********************************************************************************************************/
+
+	while `stop'!=1 { /*WHILE THE PROCEDURE TO CONSTRUCT THE ACTUAL SCALE IS NOT STOPPED*/
+
+		scalar `Hjmax'=-99
+		scalar `Hmax'=-99
+		global jmax=0
+
+		global stopmax=0
+		local nbitemsbon=0
+		forvalues i=1/`nbitems' {
+			if `dim'[1,`i']==0 {
+				local nbitemsbon=`nbitemsbon'+1
+			}
+		}
+                local kbon=`kbon'+`nbitemsbon'
+		if "`bon'"=="" {
+		          local pbon=`p'/`kbon'
+	        }
+	        else {
+	              	  local pbon=`p'
+	        }
+                if "`details'"==""&"`test'"=="" {
+	   	          di in green "Significance level: " in yellow %8.6f `pbon'
+	  	}
+
+
+		forvalues j0=1/`nbitems' {
+			if `dim'[1,`j0']==0 {/*IF THE ITEM J0 IS UNSELECTED*/
+				global stopmax=1
+				local scaletmp="scale$scale"
+				local scaletmpnum="scalenum$scale"
+				qui loevh  ``j0'' $`scaletmp'  ,`pairwise' pair `adjust' html(`html')
+				tempname pvalHj0
+			        matrix `pvalHj0'=r(pvalHj)
+  			        scalar `pvalHj0'=`pvalHj0'[1,1]
+				matrix `loevHjk'=r(loevHjk)
+				matrix `loevHj'=r(loevHj)
+				scalar `loevH'=r(loevH)
+
+				local nbitsc : word count $`scaletmp'
+				local nbitsc=`nbitsc'+1
+				if `loevHj'[1,1]>`c'&`pvalHj0'<`pbon' {/*IF THE ITEM J0 CAN BE SELECTED*/
+					if `loevH'>`Hmax' {/*AND IF IT IS THE BEST ITEM (COMPARED TO THE PRECEEDING ITEMS)*/
+						scalar `Hjmax'=`loevHj'[1,1]
+						scalar `Hmax'=`loevH'
+						global j="``j0''"
+						global j0=`j0'
+					}
+				}
+			}
+		}
+
+		if $stopmax==1&`Hjmax'==-99 { /*IF THERE IS ITEMS REMAINING BUT NONE OF THEM CAN BE SELECTED*/
+
+			if "`details'"=="" {
+				if "`html'" == "" {
+					di in green "{p}None new item can be selected in the scale $scale because all the Hj are less than `c' or none new item has all the related Hjk coefficients significantly greater than 0{p_end}."
+				}
+				else {
+					di "None new item can be selected in the scale $scale because all the Hj are less than `c' or none new item" 
+					di "has all the related Hjk coefficients significantly greater than 0."
+				}
+			}
+			scalar `stop'=1
+			continue,break
+		}
+		if $stopmax==0 {  /*IF THERE IS NO MORE ITEM REMAINING*/
+			if "`details'"=="" {
+				di in green "{p}There is no more items remaining.{p_end}"
+			}
+			scalar `stopscale'=1
+			scalar `stop'=1
+			forvalues i=1/`nbitems' {
+			   if `dim'[1,`i']<0 {
+		              scalar `stopscale'=0
+			   }
+                        }
+			*global scale=$scale-1
+			continue,break
+		}
+
+
+		if `stop'!=1 {  /*IF THE PROCEDURE IS NOT STOPPED*/
+			matrix `dim'[1,$j0]=$scale
+			local `scaletmp'="scale$scale"
+			local `scaletmpnum'="scalenum$scale"
+			global `scaletmp' $j $`scaletmp'
+			global `scaletmpnum' $j0 $`scaletmpnum'
+			if "`details'"=="" {
+				di in green "The item " in yellow  "`$j0' " in green "is selected in the scale " in yellow "$scale" _col(50) in green "Hj=" in yellow %6.4f `Hjmax' _col(65) in green "H=" in yellow %6.4f `Hmax' ""
+			}
+			local excluded
+			forvalues i=1/`nbitems' {
+		  	    if `dim'[1,`i']==-1 {
+		                matrix `dim'[1,`i']=-2
+		            }
+		            if `dim'[1,`i']==0 {  /*WE EXCLUDE ITEMS WHO HAVE A NEGATIVE Hjk WITH THE NEW SELECTED ITEM*/
+		                if `loevHjks'[`i',$j0]<`minvalue'|`pvalHjk'[`i',$j0]>`p' {
+		                     matrix `dim'[1,`i']=-1
+		                     local excluded `excluded' ``i''
+		                }
+			    }
+	                }
+			if "`excluded'"!=""&"`details'"=="" {
+	   	 	    di in green "The following items are excluded at this step: " in yellow "`excluded'"
+			}
+		}
+	}
+	di
+	local scaleencours="scale$scale"
+	local scalenumencours="scalenum$scale"
+	local nbitemscale : word count $`scaleencours'
+	return scalar nbitems`dimension'=`nbitemscale'
+	if `nbitemscale'>0 {   /* IF AT LEAST TWO ITEMS HAVE BEEN SELECTED*/
+        	if "`details'"!="" {
+		   di
+		   di in yellow "Scale: $scale"
+		   di "{hline 10}"
+		}
+		
+                loevh $`scaleencours',`pairwise' `adjust' html(`html')
+		matrix `loevHjk'=r(loevHjk)
+		matrix `loevHj'=r(loevHj)
+		scalar `loevH'=r(loevH)
+
+		return scalar H`dimension'=`loevH'
+		return local scale`dimension' $`scaleencours'
+		return local scalenum`dimension' $`scalenumencours'
+		local j=`nbitemscale'
+		di
+	}
+        forvalues i=1/`nbitems' {
+		if `dim'[1,`i']<0 {
+		   	matrix `dim'[1,`i']=0
+		}
+	}
+
+	local restnbitems=0
+	forvalues j0=1/`nbitems' {
+		if `dim'[1,`j0']==0 {
+			local restnbitems=`restnbitems'+1
+			local restitem ``j0''
+		}
+	}
+
+	if `restnbitems'==1 { /*IF THERE IS ONLY ONE ITEM REMAINING*/
+		di
+		if "`html'" == ""{
+			di in green "{p}There is only one item remaining (" in yellow "`restitem'" in green ").{p_end}"
+		}
+		else {
+			di in green "There is only one item remaining (" in yellow "`restitem'" in green ")."
+		}
+		local stopscale=1
+		return local lastitem "`restitem'"
+	}
+
+}
+
+return scalar dim=$scale
+matrix colnames `dim'=`varlist'
+return matrix selection=`dim'
+
+qui use "`mspfile'",clear
+end
diff --git a/Modules/ado/personal/n/nbmiss.ado b/Modules/ado/personal/n/nbmiss.ado
new file mode 100644
index 0000000..6e52e41
--- /dev/null
+++ b/Modules/ado/personal/n/nbmiss.ado
@@ -0,0 +1,18 @@
+program define nbmiss
+version 8.0
+syntax varlist(min=1) [, nbmiss(string)]
+
+if "`nbmiss'"=="" {
+local nbmiss nbmiss
+}
+
+local nbitems:word count `varlist'
+tokenize `varlist'
+
+qui gen `nbmiss'=0
+
+forvalues i=1/`nbitems' {
+qui replace `nbmiss'=`nbmiss'+1 if ``i''==.
+}
+end
+
diff --git a/Modules/ado/personal/n/nbvalues.ado b/Modules/ado/personal/n/nbvalues.ado
new file mode 100644
index 0000000..0e44651
--- /dev/null
+++ b/Modules/ado/personal/n/nbvalues.ado
@@ -0,0 +1,15 @@
+/*version au 17 juillet 2015 : ajout de if*/
+
+capture program drop nbvalues
+program define nbvalues,rclass
+version 7.0
+syntax varlist(min=1 max=1) [if]
+
+qui tabulate `varlist' `if',matrow(nbvalues)
+
+local nrow=rowsof(nbvalues)
+
+di "la variable `varlist' contient `nrow' valeurs differentes"
+return scalar nrow=`nrow'
+end
+
diff --git a/Modules/ado/personal/n/nopalera.ado b/Modules/ado/personal/n/nopalera.ado
new file mode 100644
index 0000000..9a241d8
--- /dev/null
+++ b/Modules/ado/personal/n/nopalera.ado
@@ -0,0 +1,703 @@
+*! Version 3.2 15January2020
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* nopalera : NOPALERA algorithm
+*
+* Historic:
+* Version 1 (2015-07-20): Jean-Benoit Hardouin /*ICC; rsbynpirt module*/
+* Version 1.1 (2015-10-24): Jean-Benoit Hardouin /*NOPALERA module, ISOQOL 2015*/
+* Version 2 (2015-10-24): Jean-Benoit Hardouin /*NOPALERA module, ISOQOL 2015*/
+* Version 2.1 (2017-12-13): Jean-Benoit Hardouin /*Improvement*/
+* Version 3 (2018-07-11): Jean-Benoit Hardouin /*Improvement for paper*/
+* Version 3.1 (2019-07-24): Jean-Benoit Hardouin /*Improvement*/
+* Version 3.2 (2020-01-10): Jean-Benoit Hardouin /*outputs for simulations*/
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* INSERM UMR 1246-SPHERE
+* MethodS in Patients-centered outcomes and HEalth ResEarches
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* News about this program: http://www.anaqol.org
+*
+* Copyright 2015,2017-2020 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+************************************************************************************************************
+
+program define nopalera, rclass 
+version 8.0
+syntax varlist(numeric min=4) [, nobsauc nobsaabc noGraph  corr(numlist) NBAUCbs(int 10) NBAABCbs(int 20)  noRESTscore GRAPHBYGroup ] /*corr est la correction Ă  appliquer pour corriger le RS unif*/
+
+set more off
+tempfile file1 file2 file3
+qui save `file1', replace
+preserve
+local nbitems : word count `varlist'
+qui count
+local nind=r(N)
+tokenize `varlist'
+if mod(`nbitems',2)!=0 {
+   di in red "You must indicate an even number of items"
+   exit
+}
+else {
+   local nbitems=`nbitems'/2
+}
+if "`corr'"=="" {
+  forvalues i=1/`nbitems'{
+     local corr "`corr' 0"
+  }
+}
+local listofitems1
+local listofitems2
+forvalues i=1/`nbitems' {
+   local listofitems1 `listofitems1' ``i''
+   local listofitems2 `listofitems2' ``=`i'+`nbitems'''
+}
+tempname matnopalera matAUC matAABC
+matrix `matnopalera'=J(`nbitems',3,0)
+matrix `matAUC'=J(`nbitems',4,0)
+matrix `matAABC'=J(`nbitems',4,0)
+
+
+di "NOPALERA: an algorithm to detect Response-shift at items level using non parametric IRT"
+di "Number of individuals: `nind'"
+di "Number of items: `nbitems'"
+di "Number of Boostrap replications for AUC: `nbaucbs'" 
+di "Number of Boostrap replications for AABC: `nbaabcbs'" 
+
+/*******************************************************************************
+Une boucle pour calculer le score, définir le score maximum par item et global
+*******************************************************************************/
+
+tempvar varscore1 varscore2 
+qui gen `varscore1'=0
+qui gen `varscore2'=0
+label variable `varscore1' "Total score time 1"
+label variable `varscore2' "Total score time 2"
+local scoremax=0
+local flag=0
+
+
+local modamax=0
+
+forvalues i=1/`nbitems' {
+   local corr`i': word `i' of `corr'
+   qui replace ``=`i'+`nbitems'''=``=`i'+`nbitems'''+`corr`i''
+   qui replace `varscore1'=`varscore1'+``i''
+   qui replace `varscore2'=`varscore2'+``=`i'+`nbitems'''
+   local list1 `list1' ``i''
+   local list2 `list2' ``=`i'+`nbitems'''
+
+   qui su ``i''
+   local modamax`i'=r(max)
+   qui su ``=`i'+`nbitems'''
+   local modamax`i'=r(max)
+   if r(min)!=0 {
+      local flag=1
+   }
+   local scoremax=`scoremax'+`modamax`i''
+      if `modamax`i''!=1 {
+      local flagbin=0
+   }
+   if `modamax`i''>`modamax' {
+      local modamax=`modamax`i''
+   }
+}
+
+/*******************************************************************************
+On va calculer maintenant les rest-score de chaque item Ă  chaque temps
+*******************************************************************************/
+
+forvalues i=1/`nbitems'{
+    tempvar rscore1``i'' rscore2``i'' vargroup1``i'' vargroup2``i'' vargroup2b``i'' 
+	if "`restscore'"=="" {
+	   qui gen `rscore1``i'''=`varscore1'-``i''
+	   qui gen `rscore2``i'''=`varscore2'-``=`i'+`nbitems'''
+    }
+	else {
+	   qui gen `rscore1``i'''=`varscore1'
+	   qui gen `rscore2``i'''=`varscore2'
+    }
+	qui gengroup `rscore1``i''' , new(`vargroup1``i''') det
+	local seuil1=r(list)
+    *di "rscore1 et group1 item ``i''"
+	*tab `rscore1``i''' `vargroup1``i'''
+    local seuil1 "`seuil1' max"
+    local nbseuil1: word count  `seuil1'
+    qui gen `vargroup2b``i'''=`rscore2``i'''
+	local t
+    forvalues j=1/`nbseuil1' {
+		if `j'==1 {
+		    local seuilmin=0
+		}
+		else { 
+            local seuilmin : word `=`j'-1' of `seuil1'
+			local seuilmin=`seuilmin'+1
+			local seuilmin=`seuilmax'+1
+        }
+		
+		local seuilmax : word `j' of `seuil1'
+        if "`seuilmax'"!="max" {
+            if `seuilmax'<`seuilmin' {
+	    	    local seuilmax `seuilmin'
+			}
+		}
+		local t `t' (`seuilmin'/`seuilmax'=`j')
+    }
+	di "recode vargroup2b``i'' `t'"
+	qui recode `vargroup2b``i''' `t'
+    *di "rscore2 et group2 item ``i'' avant regroupage"
+	*tab `rscore2``i''' `vargroup2b``i'''
+    qui gengroup `vargroup2b``i''',new(`vargroup2``i''') det replace
+    local seuil2=r(list)
+    *di "rscore2 et group2 item ``i'' aprĂšs regroupage"
+	*tab `rscore2``i''' `vargroup2``i'''
+    local seuil2 "`seuil2' max"
+    *di "``i'' seuil2 : `seuil2'"
+	local nbseuil2: word count  `seuil2'
+	local t
+    forvalues j=1/`nbseuil2' {
+		if `j'==1 {
+		    local seuilmin=1
+		}
+		else { 
+            local seuilmin : word `=`j'-1' of `seuil2'
+			local seuilmin=`seuilmin'+1
+		    local seuilmin=`seuilmax'+1
+        }
+		local seuilmax : word `j' of `seuil1'
+        if "`seuilmax'"!="max" {
+            if `seuilmax'<`seuilmin' {
+	    	    local seuilmax `seuilmin'
+			}
+		}
+        local t `t' (`seuilmin'/`seuilmax'=`j')
+    }
+	*di "recode vargroup1``i'' `t'"
+	qui recode `vargroup1``i''' `t'
+    *di "rscore1 et group1 item ``i'' aprĂšs regroupage"
+	*tab `rscore1``i''' `vargroup1``i'''
+
+}
+*tab `vargroup1itemA1' `vargroup2itemA1' 
+*exit
+qui save `file3', replace
+
+*exit
+/*******************************************************************************
+Quelques tests de conformité
+*******************************************************************************/
+
+qui su `varscore1'
+local maxscore=r(max)
+qui su `varscore2'
+if `r(max)'>`maxscore' {
+   local maxscore=r(max)
+}
+forvalues i=1/`nbitems' {
+    qui su `vargroup1``i'''
+    local maxgroup``i''=r(max)
+}
+
+
+/* sauvegarde des données */
+tempfile rsbynpirtfile rsbynpirtfile1 rsbynpirtfile2
+tempvar score
+qui save `rsbynpirtfile', replace
+
+/*******************************************************************************
+Représentation graphique des tracelines
+*******************************************************************************/
+
+
+forvalues i=1/`nbitems' {
+    tempfile file4
+	tempname mat``i''
+	matrix `mat``i'''=J(`=`maxgroup``i'''+2',9,0)
+	forvalues j=1/`maxgroup``i''' {
+	     local k=`j'+1
+	     matrix `mat``i'''[`k',1]=`j'
+		 *tab `vargroup1``i
+		 qui count if `vargroup1``i'''==`j'
+		 if `r(N)'==0 {
+		    local bsauc nobsauc
+			local bsaabc nobsaabc
+	        matrix `mat``i'''[`k',2]=.
+	        matrix `mat``i'''[`k',4]=.
+			matrix `mat``i'''[`k',6]=.
+		 }
+		 else {
+		    qui su ``i'' if `vargroup1``i'''==`j'
+	        matrix `mat``i'''[`k',2]=`r(mean)'
+	        matrix `mat``i'''[`k',4]=`r(N)'
+			qui su `rscore1``i''' if `vargroup1``i'''==`j'
+			matrix `mat``i'''[`k',6]=`r(mean)'
+		 }
+		 local temp=`i'+`nbitems'
+		 qui count if `vargroup2``i'''==`j'
+		 if `r(N)'==0 {
+		    local bsauc nobsauc
+			local bsaabc nobsaabc
+			matrix `mat``i'''[`k',3]=.
+			matrix `mat``i'''[`k',5]=.
+			matrix `mat``i'''[`k',7]=.
+		 }
+		 else {
+			qui su ``temp'' if `vargroup2``i'''==`j'
+			matrix `mat``i'''[`k',3]=`r(mean)'
+			matrix `mat``i'''[`k',5]=`r(N)'
+			qui su `rscore2``i''' if `vargroup2``i'''==`j'
+			matrix `mat``i'''[`k',7]=`r(mean)'
+		 }
+	}	 
+	local j=`maxgroup``i'''+2
+	matrix `mat``i'''[`j',1]=`maxgroup``i'''+1 /*numero du group*/
+	matrix `mat``i'''[`j',2]=`modamax`i'' /*mean item 1*/
+	matrix `mat``i'''[`j',3]=`modamax`i'' /*mean item 2*/
+	matrix `mat``i'''[`j',4]=0 /*frequency 1*/
+	matrix `mat``i'''[`j',5]=0 /*frequency 2*/
+	if "`restscore'"=="" {
+	   local maxi=`scoremax'-`modamax`i''
+	}
+	else {
+	   local maxi=`scoremax'
+	}
+    matrix `mat``i'''[`j',6]=`maxi' /*mean rest-score 1*/
+    matrix `mat``i'''[`j',7]=`maxi' /*mean rest-score 2*/
+	label values `vargroup1``i''' lblvarscore``i''
+	qui sort `vargroup1``i''' `vargroup2``i'''
+	qui save `file4',replace
+    forvalues j=1/`maxgroup``i''' {
+        qui count if `vargroup1``i'''==`j'
+	    local n1=r(N)
+	    qui su `rscore1``i''' if `vargroup1``i'''==`j'
+	    local min1=r(min)
+	    local max1=r(max)
+        qui count if `vargroup2``i'''==`j'
+	    local n2=r(N)
+	    qui su `rscore2``i''' if `vargroup2``i'''==`j'
+	    local min2=r(min)
+	    local max2=r(max)
+	    local min=min(`min1',`min2')
+	    local max=max(`max1',`max2')
+	    label define lblvarscore``i'' `j' `""Scores `min'/`max'" "(n1=`n1';n2=`n2')""', add
+    }
+
+	label define lblvarscore``i'' 0 "Min", add
+    label define lblvarscore``i'' `=`maxgroup``i'''+1' "Max", add
+    qui drop _all
+	qui svmat `mat``i'''
+	qui rename `mat``i'''1 group
+	qui rename `mat``i'''2 e1
+	qui rename `mat``i'''3 e2 
+	qui rename `mat``i'''6 rs1
+	qui rename `mat``i'''7 rs2 
+    qui sort group
+	label values group lblvarscore``i''
+	label variable group "Groups of scores"
+	if "`graph'"=="" {
+	    if "`graphbygroup'"!="" { 
+	        graph twoway (line e1 group ) (line e2 group ), title("Traceline of item ``i''") xtitle("") ytitle("Expected value of item ``i''", size(small)) ylabel(0(1)`modamax') xlabel(0(1)`=`maxgroup``i'''+1',valuelabel labsize(small) /*alternate*/) name("``i''", replace) legend(off)
+	    }
+		else {
+		    if "`restscore'"=="" {
+			     local xtitle="Rest-score"
+				 qui su rs1
+				 local max=r(max)
+				 qui su rs2
+				 if `r(max)'>`max' {
+				     local max=r(max)
+				 }
+				 
+		    }
+			else {
+			     local xtitle="Score"
+				 local max `maxscore'
+		    }
+		    graph twoway (line e1 rs1 ) (line e2 rs2 ), title("Traceline of item ``i''") xtitle("`xtitle'") ytitle("Expected value of item ``i''", size(small)) ylabel(0(1)`modamax') xlabel(0(1)`max',valuelabel labsize(small) /*alternate*/) name("auc``i''", replace) legend(off)
+		}	
+	}
+	qui use `file4', replace
+}
+
+/*******************************************************************************
+Calcul des AUC 
+*******************************************************************************/
+
+local tests
+forvalues i=1/`nbitems' {
+    local auc1`i'=0
+    local auc2`i'=0
+    forvalues g=1/`=`maxgroup``i'''+1' {
+        local k=`g'+1
+	    local auc=(`mat``i'''[`g',2]+`mat``i'''[`k',2])/2*(`mat``i'''[`k',6]-`mat``i'''[`g',6])
+		local auc1`i'=`auc1`i''+`auc'
+	    matrix `mat``i'''[`k',8]= `auc'
+	    local auc=(`mat``i'''[`g',3]+`mat``i'''[`k',3])/2*(`mat``i'''[`k',7]-`mat``i'''[`g',7])
+		local auc2`i'=`auc2`i''+`auc'
+	    matrix `mat``i'''[`k',9]= `auc'
+	}
+    local AUC``i''=`auc1`i''
+    local AUC``=`i'+`nbitems'''=`auc2`i''
+    local diffAUC``i''=`=`AUC``i'''-`AUC``=`i'+`nbitems'''''
+    return scalar AUC``i''=`auc1`i''
+    return scalar AUC``=`i'+`nbitems'''=`auc2`i''
+    matrix `matAUC'[`i',1]=`AUC``i'''
+    matrix `matAUC'[`i',2]=`AUC``=`i'+`nbitems''''
+    matrix `matAUC'[`i',3]=`diffAUC``i'''
+	
+	local tests `tests' b``i''=(r(AUC``=`i'+`nbitems''')-r(AUC``i''))
+}
+
+/*******************************************************************************
+Calcul des standard errors des AUC par bootstrap 
+*******************************************************************************/
+
+*local abc=0
+if "`bsauc'"=="" {
+    *di "on lance le bootstrap sur les AUC"
+	*set trace on
+	tempfile file2
+    qui save `file2', replace
+    qui use `file1', clear
+    capture qui bootstrap `tests' , rep(`nbaucbs') nol noh nodots : nopalera `varlist', nograph  `restscore' nobsaabc nobsauc
+	local n=1
+	while (_rc!=0&`n'<10) {
+		di "`n'. The boostrap to obtain IC of the AUC has not been correctly performed, it is run again"
+		local ++n
+		capture qui bootstrap `tests' , rep(`nbaucbs') nol noh nodots : nopalera `varlist', nograph  `restscore' nobsaabc nobsauc
+	}
+    tempname mbootstrap
+	matrix `mbootstrap'=r(table)
+    qui use `file2', clear
+
+	/*Création de la matrice p qui va permettre de décaler les ICC*/
+	tempname p
+	matrix `p'=J(`=(`scoremax'+1)*(`nbitems'+1)',`=`nbitems'*3+1',.)
+	forvalues s=0/`scoremax' {
+	   matrix `p'[`=`s'+1',1]=`s'
+	   forvalues i=1/`nbitems' {
+		  matrix `p'[`=`s'+1',`=3*`i'-1']=`s'
+	   }
+	}
+	forvalues i=1/`nbitems' {
+	   forvalues s=0/`scoremax' {
+		  qui su ``i'' if `varscore1'==`s'
+		  matrix `p'[`=`s'+1',`=3*`i'']=r(mean)
+	   }
+	   forvalues s=0/`scoremax' {
+		  qui su ``=`i'+`nbitems''' if `varscore2'==`s'
+		  if `mbootstrap'[4,`i']>=0.05 {
+			 matrix `p'[`=`s'+1',`=3*`i'+1']=r(mean)
+			 local prec=1
+			 local prec=0.01 /*pas d'arrondi*/
+		  }
+		  else {
+		     if `nind'/`scoremax'>20 {
+			    local prec=0.5
+			    local prec=1
+			    local prec=0.01 /*pas d'arrondi*/
+			 }
+			 else {
+			    local prec=1
+			    local prec=0.01 /*pas d'arrondi*/
+			 }
+			 matrix `p'[`=`i'*(`scoremax'+1)+`s'+1',`=3*`i'-1']=round(`s'+`mbootstrap'[1,`i']/(`modamax`i''),`prec')
+			 matrix `p'[`=`i'*(`scoremax'+1)+`s'+1',`=3*`i'+1']=r(mean)
+		  }
+	   }
+	}
+	di
+	di "Research of uniform recalibration at item-level"
+	di
+	di "{hline 105}"
+	di                                                               _col(45) "Bootstrap"                               _col(78) "  Normal-based"
+	di "Items" _col(18) "AUC t1" _col(28) "AUC t2" _col(38) "VarAUC" _col(45) "Std. Err." _col(63) "z" _col(70) "P>|z|" _col(78) "[95% Conf. Int.]" _col(96) "Correction"
+	di "{hline 105}"
+    forvalues i=1/`nbitems' {
+	   local corr``i''=round(`mbootstrap'[1,`i']/(`modamax`i''),`prec')
+	   di "``i''/``=`i'+`nbitems'''" _col(19) %5.2f `AUC``i''' _col(29) %5.2f `AUC``=`i'+`nbitems'''' _col(39) %5.2f `diffAUC``i''' _col(49) %5.2f `mbootstrap'[2,`i'] _col(59) %5.2f `mbootstrap'[3,`i'] _col(69) %5.4f `mbootstrap'[4,`i'] _col(79) %5.2f `mbootstrap'[5,`i'] _col(89) %5.2f `mbootstrap'[6,`i'] _col(100) %6.2f `corr``i'''
+	   matrix `matAUC'[`i',4]=`mbootstrap'[2,`i']
+	}
+	di "{hline 105}"
+	local abc=1
+}
+else {
+    *di "pas de bootstrap AUC"
+	di
+	di "Research of uniform recalibration at item-level"
+	di
+	di "{hline 105}"
+	di "Items" _col(48) "AUC t1" _col(58) "AUC t2" 
+	di "{hline 105}"
+    forvalues i=1/`nbitems' {
+*	   local corr``i''=round(`mbootstrap'[1,`i']/(`modamax`i''),`prec')
+	   di "``i''/``=`i'+`nbitems'''" _col(49) %5.2f `AUC``i''' _col(59) %5.2f `AUC``=`i'+`nbitems'''' 
+	}
+	di "{hline 105}"
+	local abc=1
+}
+
+*di "abc:`abc' bsAUC : `bsauc'"
+*return matrix AUC=`matAUC'
+
+/*******************************************************************************
+Calcul des AABC et de leurs intervalles de confiance par boostrap 
+*******************************************************************************/
+*set trace on
+if `abc'==1 {
+   *di "on lance les AABC"
+   local testsb
+   forvalues i=1/`nbitems' {
+       if "`bsauc'"!="" { /*si pas de bootstrap pour AUC*/
+	      *di "m1"
+		  local sigAUC``i''=0
+          local rdiffAUC``i''=0
+	   }
+	   else if `mbootstrap'[4,`i']<0.05 { /* si bootstrap et significatif*/
+	      *di "m2"
+	      local sigAUC``i''=1
+		  local rdiffAUC``i''=-`corr``i'''
+		  di "The item ``i'' traceline is corrected of `corr``i'''"
+       }
+       else { /* si bootstrap et NS*/
+	      *di "m3"
+	      local sigAUC``i''=0
+          local rdiffAUC``i''=0
+       } 
+	   tempname mat2``i''
+	   local nbl=`=`maxgroup``i'''*4+7'
+       matrix `mat2``i'''=J(`nbl',4,.)
+	   matrix `mat2``i'''[1,2]=0
+	   matrix `mat2``i'''[1,3]=0
+	   matrix `mat2``i'''[`nbl',2]=`modamax`i''
+	   matrix `mat2``i'''[`nbl',3]=`modamax`i''
+	   local col1=1
+	   local col2=1
+	   local line=1
+       while (`line'<=`=`maxgroup``i'''*4+7') {
+	      local t1=`mat``i'''[`col1',6]
+		  local t2=`mat``i'''[`col2',7]-`rdiffAUC``i'''
+          local m2=`mat``i'''[`col1',2]
+		  local m3=`mat``i'''[`col2',3]
+		  if (`t1'<`t2'|(`t1'==`t2'&`m2'<`m3')) {
+		      *di "m2 car `m2'<`m3'"
+		      matrix `mat2``i'''[`line',1]=`t1'
+		      matrix `mat2``i'''[`line',2]=`mat``i'''[`col1',2]
+			  local ++col1
+          }
+		  else {
+		      *di "m3 car `m2'>`m3'"
+		      matrix `mat2``i'''[`line',1]=`t2'
+		      matrix `mat2``i'''[`line',3]=`mat``i'''[`col2',3]
+			  local ++col2
+		  }
+	      local line=`line'+2
+	   }
+	   *matrix list `mat2``i'''
+	   local j=1
+	   while (`j'<=`nbl') {
+	       foreach c in 2 3 {
+	          if `mat2``i'''[`j',`c']==. {
+                   local prec=`j'-2	
+				   local m=`mat2``i'''[`prec',`c']
+                   while (`m'==.&`prec'>=0) {
+				       local prec=`prec'-2
+               		   local m=`mat2``i'''[`prec',`c'] 
+					   *di "prec:`prec' m: `m'"
+				   }
+                   local suiv=`j'+2		
+				   local m=`mat2``i'''[`suiv',`c']
+                   while (`m'==.&`suiv'<=`nbl') {
+				       local suiv=`suiv'+2
+					   local m=`mat2``i'''[`suiv',`c']
+					   *di "suiv:`suiv' m: `m'"
+				   }
+				   local yprec=`mat2``i'''[`prec',`c']
+				   local ysuiv=`mat2``i'''[`suiv',`c']
+				   local xprec=`mat2``i'''[`prec',1]
+				   local xsuiv=`mat2``i'''[`suiv',1]
+				   local x=`mat2``i'''[`j',1]
+				   if (`xsuiv'!=`xprec') {
+				       *di "matrix `mat2``i'''[`j',`c']=`yprec'+(`x'-`xprec')/(`xsuiv'-`xprec')*(`ysuiv'-`yprec')"
+				       matrix `mat2``i'''[`j',`c']=`yprec'+(`x'-`xprec')/(`xsuiv'-`xprec')*(`ysuiv'-`yprec')
+				   }
+				   else {
+				       matrix `mat2``i'''[`j',`c']=`mat2``i'''[`prec',`c']
+				   }
+		      }
+		   }
+		   local j=`j'+2
+	   }
+	   local j=2
+	   *matrix list `mat2``i'''
+	   while (`j'<`nbl') {
+	       local prec=`j'-1 
+	       local suiv=`j'+1
+		   local sign=(`mat2``i'''[`prec',2]-`mat2``i'''[`prec',3])*(`mat2``i'''[`suiv',2]-`mat2``i'''[`suiv',3])
+		   *di "item ``i'', ligne `j', sign `sign'"
+		   if (`sign'<0&`sign'!=.) {
+		      local p1=(`mat2``i'''[`suiv',2]-`mat2``i'''[`prec',2])/(`mat2``i'''[`suiv',1]-`mat2``i'''[`prec',1])
+		      local p2=(`mat2``i'''[`suiv',3]-`mat2``i'''[`prec',3])/(`mat2``i'''[`suiv',1]-`mat2``i'''[`prec',1])
+			  if (`p1'==`p2') {
+			      local cint=`mat2``i'''[`prec',1]
+			  }
+			  else  {
+			      local cint=`mat2``i'''[`prec',1]+(`mat2``i'''[`prec',3]-`mat2``i'''[`prec',2])/(`p1'-`p2')
+			  }
+			  matrix `mat2``i'''[`j',1]=`cint'
+              foreach c in 2 3 {
+			     local yprec=`mat2``i'''[`prec',`c']
+			     local ysuiv=`mat2``i'''[`suiv',`c']
+			     local xprec=`mat2``i'''[`prec',1]
+			     local xsuiv=`mat2``i'''[`suiv',1]
+			     local x=`cint'
+				 if (`xsuiv'==`xprec') {
+				     matrix `mat2``i'''[`j',`c']=`mat2``i'''[`prec',`c']
+				 }
+				 else {
+		             *di "matrix `mat2``i'''[`j',`c']=`yprec'+(`x'-`xprec')/(`xsuiv'-`xprec')*(`ysuiv'-`yprec')"
+		             matrix `mat2``i'''[`j',`c']=`yprec'+(`x'-`xprec')/(`xsuiv'-`xprec')*(`ysuiv'-`yprec')
+				 }
+			  }
+		   }
+		   else {
+		      local prec=`j'-1
+			  forvalues c=1/3 {
+			      matrix `mat2``i'''[`j',`c']=`mat2``i'''[`prec',`c']
+			  }
+		   }
+		   local j=`j'+2
+	   }
+	   *matrix list `mat2``i'''
+	   local aabc``i''=0
+	   *set trace on
+	   forvalues j=2/`nbl' {
+	      local prec=`j'-1
+		  local x=`mat2``i'''[`j',1]
+		  local xprec=`mat2``i'''[`prec',1]
+		  local y2=`mat2``i'''[`j',2]
+		  local y3=`mat2``i'''[`j',3]
+		  local yprec2=`mat2``i'''[`prec',2]
+		  local yprec3=`mat2``i'''[`prec',3]
+	      local aabc=(abs(`y2'-`y3')+abs(`yprec2'-`yprec3'))/2*abs(`x'-`xprec')
+	      matrix `mat2``i'''[`j',4]=`aabc'
+		  local aabc``i''=`aabc``i'''+`aabc'
+	   }
+       return scalar AABC``i''=`aabc``i'''
+	   matrix `matAABC'[`i',1]=`aabc``i'''
+       *set trace off
+	   
+	   local testsb `testsb' c``i''=r(AABC``i'')
+	   *matrix list `mat2``i'''
+       *di "return scalar AABC``i''=`aabc``i'''"
+	   *matrix list `mat2``i'''
+    }
+	*set trace on
+	if "`bsaabc'"=="" {
+	    *di "on lance le bootstrap AABC"
+		tempfile file3
+		qui save `file3', replace
+		qui use `file1', clear
+		*di "bootstrap `testsb' , rep(`nbbootstrap') nol noh nodots saving(C:\Users\jean-\Documents\tmp\essai.dta, replace) : nopalera `varlist', fin nograph `restscore' nobsauc nobsaabc "
+		*set trace on
+		*set tracedepth 2
+		tempfile filebsaabc
+		*di "hello c'est l'heure du BS"
+		*qui bootstrap `testsb' , rep(`nbaabcbs') nol noh nodots saving("`filebsaabc'", replace) trace : nopalera `varlist', nograph `restscore' nobsauc nobsaabc
+		capture qui bootstrap `testsb' , rep(`nbaabcbs') saving("`filebsaabc'", replace)  : nopalera `varlist', nograph `restscore' nobsauc nobsaabc
+		local n=1
+		while (_rc!=0&`n'<50) {
+		    di "`n'. The boostrap to obtain IC of the AABC has not been correctly performed, it is run again"
+      		local ++n
+			capture qui bootstrap `testsb' , rep(`nbaabcbs') saving("`filebsaabc'", replace)  : nopalera `varlist', nograph `restscore' nobsauc nobsaabc
+		}
+		*return list
+		tempname mbootstrapb
+		matrix `mbootstrapb'=r(table)
+		*di "MATRIX mbootstrapb  `mbootstrapb'"
+		*matrix list `mbootstrapb'
+        qui use "`filebsaabc'", replace
+		*su
+		local thres=`nbaabcbs'-ceil(`nbaabcbs'/20)
+		forvalues i=1/`nbitems' {
+		   sort c``i''
+		   qui su c``i'' in `thres'
+		   local upper``i''=r(mean)
+		   *di "Upper ``i'' : `upper``i'''"
+		}
+		di
+		di "Research of non-uniform recalibration at item-level"
+		di
+		di "{hline 103}"
+		di                                _col(36) "Bootstrap"       _col(56) "Uniform"      _col(72) "Non-uniform" 
+		di "Items" _col(23) "AABC" _col(29) "[95% Conf. Int.]" _col(50) "Recalibration"    _col(70) "Recalibration"  _col(88) "Reprioritization"
+		di "{hline 103}"
+		forvalues i=1/`nbitems' {
+		   local xur=""
+		   local xnur=""
+		   local xrep=""
+		   if `mbootstrap'[4,`i']<=0.05 {
+		       local xur="X"
+			   matrix `matnopalera'[`i',1]=1
+		   }
+		   if (`aabc``i'''>`upper``i'''&"`xur'"=="X") {
+		       local xnur="X"
+			   matrix `matnopalera'[`i',2]=1
+		   }
+		   if (`aabc``i'''>`upper``i'''&"`xur'"=="") {
+		       local xrep="X"
+			   matrix `matnopalera'[`i',3]=1
+		   }
+		   matrix `matAABC'[`i',2]=`upper``i'''
+		   
+		   di "``i''/``=`i'+`nbitems'''" _col(23) %5.2f `aabc``i''' _col(36) "[" %1.0f  0 "-" %5.2f `upper``i''' "]" _col(62) "`xur'" _col(82) "`xnur'" _col(102) "`xrep'"
+		}
+		di "{hline 103}"
+		local abc=1
+	}
+	if "`graph'"=="" {
+	    forvalues i=1/`nbitems' {
+			qui drop _all
+			qui svmat `mat2``i'''
+			qui rename `mat2``i'''1 score
+			qui rename `mat2``i'''2 t1
+			qui rename `mat2``i'''3 at2 
+			qui sort score
+			if "`restscore'"=="" {
+					 local xtitle="Rest-score"
+					 qui su score
+					 local max=r(max)
+			}
+			else {
+					 local xtitle="Score"
+					 local max `maxscore'
+			}
+			list *
+			graph twoway (line t1 score ) (line at2 score ) if score>0&score<=`maxscore', title("Traceline of item ``i''") xtitle("`xtitle'") ytitle("Expected value of item ``i''", size(small)) ylabel(0(1)`modamax') xlabel(0(1)`max',valuelabel labsize(small) /*alternate*/) name("aabc``i''", replace) legend(off)
+		}
+	}
+}
+return matrix matnopalera=`matnopalera'
+return matrix AUC=`matAUC'
+return matrix AABC=`matAABC'
+qui restore , preserve
+end
+
+
diff --git a/Modules/ado/personal/n/nopalerav2.1.ado b/Modules/ado/personal/n/nopalerav2.1.ado
new file mode 100644
index 0000000..9685a39
--- /dev/null
+++ b/Modules/ado/personal/n/nopalerav2.1.ado
@@ -0,0 +1,322 @@
+*! Version 2.1 13December2017
+************************************************************************************************************
+* nopalera : NOPALERA algorithm
+* Version 2: October 24, 2015 
+*
+* Historic:
+* Version 1 (2015-07-20): Jean-Benoit Hardouin /*ICC; rsbynpirt module*/
+* Version 1.1 (2015-10-24): Jean-Benoit Hardouin /*NOPALERA module, ISOQOL 2015*/
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* INSERM UMR 1246-SPHERE
+* MethodS in Patients-centered outcomes and HEalth ResEarches
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* News about this program: http://www.anaqol.org
+*
+* Copyright 2015,2017 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+************************************************************************************************************
+
+program define nopalera, rclass 
+version 8.0
+syntax varlist(numeric min=4) [,  noGraph noBootstrap corr(numlist) NBBootstrap(int 10)]
+
+set more off
+tempfile file1 file3
+qui save `file1', replace
+preserve
+local nbitems : word count `varlist'
+qui count
+local nind=r(N)
+tokenize `varlist'
+if mod(`nbitems',2)!=0 {
+   di in red "You must indicate an even number of items"
+   exit
+}
+else {
+   local nbitems=`nbitems'/2
+}
+if "`corr'"=="" {
+  forvalues i=1/`nbitems'{
+     local corr "`corr' 0"
+  }
+}
+local listofitems1
+local listofitems2
+forvalues i=1/`nbitems' {
+   local listofitems1 `listofitems1' ``i''
+   local listofitems2 `listofitems2' ``=`i'+`nbitems'''
+}
+
+di "NOPALERA: an algorithm to detect Response-shift at items level using non parametric IRT"
+di "Number of individuals: `nind'"
+di "Number of items: `nbitems'"
+di "Number of Boostrap replications: `nbbootstrap'" 
+
+/*******************************************************************************
+Une boucle pour calculer le score, définir le score maximum par item et global
+*******************************************************************************/
+tempvar varscore1 varscore2
+qui gen `varscore1'=0
+qui gen `varscore2'=0
+label variable `varscore1' "Total score time 1"
+label variable `varscore2' "Total score time 2"
+local scoremax=0
+local flag=0
+
+
+local modamax=0
+forvalues i=1/`nbitems' {
+   local corr`i': word `i' of `corr'
+   qui replace ``=`i'+`nbitems'''=``=`i'+`nbitems'''+`corr`i''
+   qui replace `varscore1'=`varscore1'+``i''
+   qui replace `varscore2'=`varscore2'+``=`i'+`nbitems'''
+   qui su ``i''
+   local modamax`i'=r(max)
+   qui su ``=`i'+`nbitems'''
+   local modamax`i'=r(max)
+   if r(min)!=0 {
+      local flag=1
+   }
+   local scoremax=`scoremax'+`modamax`i''
+      if `modamax`i''!=1 {
+      local flagbin=0
+   }
+   if `modamax`i''>`modamax' {
+      local modamax=`modamax`i''
+   }
+}
+qui save `file3', replace
+
+/*******************************************************************************
+Quelques tests de conformité
+*******************************************************************************/
+if `flag'==1 {
+   *di as error "The lower answer category of each item must be 0"
+   *exit
+}
+
+qui su `varscore1'
+local maxscore=r(max)
+qui su `varscore1'
+if `r(max)'>`maxscore' {
+   local maxscore=r(max)
+}
+
+/* sauvegarde des données */
+tempfile rsbynpirtfile rsbynpirtfile1 rsbynpirtfile2
+tempvar score
+qui save `rsbynpirtfile', replace
+
+/*On récupÚre les données des ICC au temps 1 puis au temps 2*/
+qui traces `listofitems1', nograph icc saveicc
+qui drop _all
+tempname mat1
+qui matrix `mat1'=r(matscore)
+qui svmat `mat1', names(t1item)
+forvalues i=1/`nbitems' {
+   local j: word `i' of `listofitems1'
+   qui rename t1item`i' `j'
+}
+qui rename t1item`=`nbitems'+1' `score'
+qui contract `score' `listofitems1'
+qui sort `score'
+qui save `rsbynpirtfile1', replace
+
+qui use `rsbynpirtfile', clear
+qui traces `listofitems2', nograph icc saveicc
+qui drop _all
+tempname mat2
+qui matrix `mat2'=r(matscore)
+qui svmat `mat2', names(t2item)
+
+/*puis on fait un seul fichier avec les deux jeux de données*/
+forvalues i=1/`nbitems' {
+   local j: word `i' of `listofitems2'
+   qui rename t2item`i' `j'
+}
+qui rename t2item`=`nbitems'+1' `score'
+qui contract `score' `listofitems2'
+qui sort `score'
+qui merge 1:1 `score' using `rsbynpirtfile1'
+
+/*représentation simultanée des ICC aux deux temps pour chaque item*/
+if "`graph'"=="" {
+   forvalues i=1/`nbitems' {
+      twoway (line ``i'' `score') (line ``=`i'+`nbitems''' `score'), name(``i'',replace)
+   }
+}
+qui drop if `score'==0|`score'==`scoremax'
+
+/*calcul des deux AUC pour chaque item*/
+local tests
+forvalues i=1/`nbitems' {
+   qui su ``i'' 
+   local AUC``i''=r(mean)
+   local AUC``i''=(`AUC``i'''*`scoremax')
+   qui su ``=`i'+`nbitems''' 
+   local AUC`=`i'+`nbitems''=r(mean)
+   local AUC`=`i'+`nbitems''=(`AUC`=`i'+`nbitems'''*`scoremax')
+   tempname diff``i''
+   gen `diff``i'''=abs(``i''-``=`i'+`nbitems''')
+   qui su `diff``i'''
+   local d``i''=`r(sum)'/(`scoremax'*`modamax`i'')*100
+   local var``i''=`r(sd)'*100
+   return scalar AUC``i''=`AUC``i'''
+   return scalar AUC``=`i'+`nbitems'''=`AUC`=`i'+`nbitems'''
+   local tests `tests' b``i''=(r(AUC``=`i'+`nbitems''')-r(AUC``i''))
+}
+
+local abc=0
+
+
+/* 10 bootstrap pour estimer les intervalles de confiance des différences entre les deux AUC*/
+if "`bootstrap'"=="" {
+    tempfile file2
+    qui save `file2', replace
+    qui use `file1', clear
+    qui bootstrap `tests' , rep(`nbbootstrap') nol noh nodots : nopalera `varlist', nograph nobootstrap 
+    tempname mbootstrap
+	matrix `mbootstrap'=r(table)
+	*matrix list `mbootstrap'
+    qui use `file3', clear
+    *set trace on
+	set tracedepth 1
+
+	/*Création de la matrice p qui va permettre de décaler les ICC*/
+	tempname p
+	matrix `p'=J(`=(`scoremax'+1)*(`nbitems'+1)',`=`nbitems'*3+1',.)
+	forvalues s=0/`scoremax' {
+	   matrix `p'[`=`s'+1',1]=`s'
+	   forvalues i=1/`nbitems' {
+		  matrix `p'[`=`s'+1',`=3*`i'-1']=`s'
+	   }
+	}
+	forvalues i=1/`nbitems' {
+	   forvalues s=0/`scoremax' {
+		  qui su ``i'' if `varscore1'==`s'
+		  matrix `p'[`=`s'+1',`=3*`i'']=r(mean)
+	   }
+	   forvalues s=0/`scoremax' {
+		  qui su ``=`i'+`nbitems''' if `varscore2'==`s'
+		  *di "qui su ``=`i'+`nbitems''' if `varscore2'==`s'"
+		  if `mbootstrap'[4,`i']>=0.05 {
+			 matrix `p'[`=`s'+1',`=3*`i'+1']=r(mean)
+			 local prec=1
+			 local prec=0.01 /*pas d'arrondi*/
+		  }
+		  else {
+		     if `nind'/`scoremax'>20 {
+			    local prec=0.5
+			    local prec=1
+			    local prec=0.01 /*pas d'arrondi*/
+			 }
+			 else {
+			    local prec=1
+			    local prec=0.01 /*pas d'arrondi*/
+			 }
+			 matrix `p'[`=`i'*(`scoremax'+1)+`s'+1',`=3*`i'-1']=round(`s'+`mbootstrap'[1,`i']/(`modamax`i''),`prec')
+			 matrix `p'[`=`i'*(`scoremax'+1)+`s'+1',`=3*`i'+1']=r(mean)
+		  }
+	   }
+	}
+	*matrix list `p'
+	*matrix list `p'
+	di
+	di "Research of uniform recalibration at item-level"
+	di
+	di "{hline 105}"
+	di                                                               _col(45) "Bootstrap"                               _col(78) "  Normal-based"
+	di "Items" _col(18) "AUC t1" _col(28) "AUC t2" _col(38) "VarAUC" _col(45) "Std. Err." _col(63) "z" _col(70) "P>|z|" _col(78) "[95% Conf. Int.]" _col(96) "Correction"
+	di "{hline 105}"
+	forvalues i=1/`nbitems' {
+	   di "``i''/``=`i'+`nbitems'''" _col(19) %5.2f `AUC``i''' _col(29) %5.2f `AUC`=`i'+`nbitems''' _col(39) %5.2f `=`AUC``i'''-`AUC`=`i'+`nbitems'''' _col(49) %5.2f `mbootstrap'[2,`i'] _col(59) %5.2f `mbootstrap'[3,`i'] _col(69) %5.4f `mbootstrap'[4,`i'] _col(79) %5.2f `mbootstrap'[5,`i'] _col(89) %5.2f `mbootstrap'[6,`i'] _col(100) %6.2f round(`mbootstrap'[1,`i']/(`modamax`i''),`prec')
+	}
+	di "{hline 105}"
+	local abc=1
+}
+if `abc'==1 {
+	drop _all
+	qui svmat `p'  
+	qui rename `p'1 score
+	local testsb
+	forvalues i=1/`nbitems' {
+	     qui rename `p'`=`i'*3-1' score``i''
+	     qui rename `p'`=`i'*3' t1``i''
+	     qui rename `p'`=`i'*3+1' t2``i''
+		 /*interpolation linéaire et nouvelles ICC corrigées*/
+    	 qui ipolate t2``i'' score``i'' , generate(t2adj``i'')
+		 forvalues j=0/`=floor(round(`mbootstrap'[1,`i']/(`modamax`i''),`prec'))' {
+		      qui replace t2adj``i''=0 if score``i''==`j'&t2adj``i''==.
+	     }
+		 forvalues j=`=`scoremax'+floor(round(`mbootstrap'[1,`i']/(`modamax`i''),`prec'))'/`scoremax' {
+		      qui replace t2adj``i''=1 if score``i''==`j'&t2adj``i''==.
+	     }
+		 qui gen diff``i''=abs(t2adj``i''-t1``i'')
+		 qui su diff``i''
+		 local ABC``i''=`r(mean)'*`scoremax'
+		 return scalar ABC``i''=`ABC``i'''
+		 if "`graph'"=="" { 
+		    qui sort score``i''
+			qui gen scoreunadj``i''=score``i''-round(`mbootstrap'[1,`i']/(`modamax`i''),`prec')
+			*twoway (line t1``i'' score``i'')(line t2``i'' score``i'')(line t2adj``i'' score``i'') ,name(``i''c,replace)
+			twoway (line t1``i'' score``i'')(line t2``i'' scoreunadj``i'')(line t2adj``i'' score``i'') ,name(``i''c,replace)
+		    *di "twoway (line t1``i'' score``i'')(line t2``i'' score``i'')(line t2adj``i'' score``i'') ,name(``i''c,replace)"
+			*su
+		 }
+		 local testsb `testsb' c``i''=(r(ABC``i''))
+
+    }
+	
+	/* 10 bootstrap pour estimer les intervalles de confiance des ABC*/
+	if "`bootstrap'"=="" {
+		tempfile file3
+		qui save `file3', replace
+		qui use `file1', clear
+		qui bootstrap `tests' , rep(`nbbootstrap') nol noh nodots : nopalera `varlist', nograph nobootstrap 
+		tempname mbootstrapb
+		matrix `mbootstrapb'=r(table)
+		*matrix list `mbootstrapb'
+		di
+		di "Research of non-uniform recalibration at item-level"
+		di
+		di "{hline 77}"
+		di                        _col(29) "Bootstrap"                               _col(62) "  Normal-based"
+		di "Items" _col(24) "ABC" _col(29) "Std. Err." _col(47) "z" _col(54) "P>|z|" _col(62) "[95% Conf. Int.]"
+		di "{hline 77}"
+		forvalues i=1/`nbitems' {
+		   local z`i'=`ABC``i'''/`mbootstrapb'[2,`i']
+		   local p`i'=2*(1-normal(abs(`z`i'')))
+		   di "``i''/``=`i'+`nbitems'''" _col(23) %5.2f `ABC``i''' _col(33) %5.2f `mbootstrapb'[2,`i'] _col(43) %5.2f `z`i'' _col(53) %5.4f `p`i'' _col(63) %5.2f `=`ABC``i'''-1.96*`mbootstrapb'[2,`i']' _col(73) %5.2f `=`ABC``i'''+1.96*`mbootstrapb'[2,`i']'
+		}
+		di "{hline 77}"
+		local abc=1
+	}	
+	
+	
+}
+
+if "`bootstrap'"=="" {
+   return matrix p=`p'
+}
+qui restore , preserve
+end
+
+
diff --git a/Modules/ado/personal/n/nopalerav3.ado b/Modules/ado/personal/n/nopalerav3.ado
new file mode 100644
index 0000000..2e5b9d2
--- /dev/null
+++ b/Modules/ado/personal/n/nopalerav3.ado
@@ -0,0 +1,653 @@
+*! Version 3 11July2018
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* nopalera : NOPALERA algorithm
+*
+* Historic:
+* Version 1 (2015-07-20): Jean-Benoit Hardouin /*ICC; rsbynpirt module*/
+* Version 1.1 (2015-10-24): Jean-Benoit Hardouin /*NOPALERA module, ISOQOL 2015*/
+* Version 2 (2015-10-24): Jean-Benoit Hardouin /*NOPALERA module, ISOQOL 2015*/
+* Version 2.1 (2017-12-13): Jean-Benoit Hardouin /*Improvement*/
+* Version 3 (2018-07-11): Jean-Benoit Hardouin /*Improvement for paper*/
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* INSERM UMR 1246-SPHERE
+* MethodS in Patients-centered outcomes and HEalth ResEarches
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* News about this program: http://www.anaqol.org
+*
+* Copyright 2015,2017,2018 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+************************************************************************************************************
+
+program define nopalera, rclass 
+version 8.0
+syntax varlist(numeric min=4) [, nobsauc nobsaabc noGraph  corr(numlist) NBAUCbs(int 10) NBAABCbs(int 20)  noRESTscore GRAPHBYGroup ] /*corr est la correction Ă  appliquer pour corriger le RS unif*/
+
+set more off
+tempfile file1 file2 file3
+qui save `file1', replace
+preserve
+local nbitems : word count `varlist'
+qui count
+local nind=r(N)
+tokenize `varlist'
+if mod(`nbitems',2)!=0 {
+   di in red "You must indicate an even number of items"
+   exit
+}
+else {
+   local nbitems=`nbitems'/2
+}
+if "`corr'"=="" {
+  forvalues i=1/`nbitems'{
+     local corr "`corr' 0"
+  }
+}
+local listofitems1
+local listofitems2
+forvalues i=1/`nbitems' {
+   local listofitems1 `listofitems1' ``i''
+   local listofitems2 `listofitems2' ``=`i'+`nbitems'''
+}
+
+di "NOPALERA: an algorithm to detect Response-shift at items level using non parametric IRT"
+di "Number of individuals: `nind'"
+di "Number of items: `nbitems'"
+di "Number of Boostrap replications for AUC: `nbaucbs'" 
+di "Number of Boostrap replications for AABC: `nbaabcbs'" 
+
+/*******************************************************************************
+Une boucle pour calculer le score, définir le score maximum par item et global
+*******************************************************************************/
+
+tempvar varscore1 varscore2 
+qui gen `varscore1'=0
+qui gen `varscore2'=0
+label variable `varscore1' "Total score time 1"
+label variable `varscore2' "Total score time 2"
+local scoremax=0
+local flag=0
+
+
+local modamax=0
+
+forvalues i=1/`nbitems' {
+   local corr`i': word `i' of `corr'
+   qui replace ``=`i'+`nbitems'''=``=`i'+`nbitems'''+`corr`i''
+   qui replace `varscore1'=`varscore1'+``i''
+   qui replace `varscore2'=`varscore2'+``=`i'+`nbitems'''
+   local list1 `list1' ``i''
+   local list2 `list2' ``=`i'+`nbitems'''
+
+   qui su ``i''
+   local modamax`i'=r(max)
+   qui su ``=`i'+`nbitems'''
+   local modamax`i'=r(max)
+   if r(min)!=0 {
+      local flag=1
+   }
+   local scoremax=`scoremax'+`modamax`i''
+      if `modamax`i''!=1 {
+      local flagbin=0
+   }
+   if `modamax`i''>`modamax' {
+      local modamax=`modamax`i''
+   }
+}
+
+/*******************************************************************************
+On va calculer maintenant les rest-score de chaque item Ă  chaque temps
+*******************************************************************************/
+
+forvalues i=1/`nbitems'{
+    tempvar rscore1``i'' rscore2``i'' vargroup1``i'' vargroup2``i'' vargroup2b``i'' 
+	if "`restscore'"=="" {
+	   qui gen `rscore1``i'''=`varscore1'-``i''
+	   qui gen `rscore2``i'''=`varscore2'-``=`i'+`nbitems'''
+    }
+	else {
+	   qui gen `rscore1``i'''=`varscore1'
+	   qui gen `rscore2``i'''=`varscore2'
+    }
+	qui gengroup `rscore1``i''' , new(`vargroup1``i''') det
+	local seuil1=r(list)
+    *di "rscore1 et group1 item ``i''"
+	*tab `rscore1``i''' `vargroup1``i'''
+    local seuil1 "`seuil1' max"
+    local nbseuil1: word count  `seuil1'
+    qui gen `vargroup2b``i'''=`rscore2``i'''
+	local t
+    forvalues j=1/`nbseuil1' {
+		if `j'==1 {
+		    local seuilmin=0
+		}
+		else { 
+            local seuilmin : word `=`j'-1' of `seuil1'
+			local seuilmin=`seuilmin'+1
+			local seuilmin=`seuilmax'+1
+        }
+		
+		local seuilmax : word `j' of `seuil1'
+        if "`seuilmax'"!="max" {
+            if `seuilmax'<`seuilmin' {
+	    	    local seuilmax `seuilmin'
+			}
+		}
+		local t `t' (`seuilmin'/`seuilmax'=`j')
+    }
+	*di "recode vargroup2b``i'' `t'"
+	qui recode `vargroup2b``i''' `t'
+    *di "rscore2 et group2 item ``i'' avant regroupage"
+	*tab `rscore2``i''' `vargroup2b``i'''
+    qui gengroup `vargroup2b``i''',new(`vargroup2``i''') det replace
+    local seuil2=r(list)
+    *di "rscore2 et group2 item ``i'' aprĂšs regroupage"
+	*tab `rscore2``i''' `vargroup2``i'''
+    local seuil2 "`seuil2' max"
+    *di "``i'' seuil2 : `seuil2'"
+	local nbseuil2: word count  `seuil2'
+	local t
+    forvalues j=1/`nbseuil2' {
+		if `j'==1 {
+		    local seuilmin=1
+		}
+		else { 
+            local seuilmin : word `=`j'-1' of `seuil2'
+			local seuilmin=`seuilmin'+1
+		    local seuilmin=`seuilmax'+1
+        }
+		local seuilmax : word `j' of `seuil1'
+        if "`seuilmax'"!="max" {
+            if `seuilmax'<`seuilmin' {
+	    	    local seuilmax `seuilmin'
+			}
+		}
+        local t `t' (`seuilmin'/`seuilmax'=`j')
+    }
+	*di "recode vargroup1``i'' `t'"
+	qui recode `vargroup1``i''' `t'
+    *di "rscore1 et group1 item ``i'' aprĂšs regroupage"
+	*tab `rscore1``i''' `vargroup1``i'''
+
+}
+*tab `vargroup1itemA1' `vargroup2itemA1' 
+*exit
+qui save `file3', replace
+
+*exit
+/*******************************************************************************
+Quelques tests de conformité
+*******************************************************************************/
+
+qui su `varscore1'
+local maxscore=r(max)
+qui su `varscore2'
+if `r(max)'>`maxscore' {
+   local maxscore=r(max)
+}
+forvalues i=1/`nbitems' {
+    qui su `vargroup1``i'''
+    local maxgroup``i''=r(max)
+}
+
+
+/* sauvegarde des données */
+tempfile rsbynpirtfile rsbynpirtfile1 rsbynpirtfile2
+tempvar score
+qui save `rsbynpirtfile', replace
+
+/*******************************************************************************
+Représentation graphique des tracelines
+*******************************************************************************/
+
+
+forvalues i=1/`nbitems' {
+    tempfile file4
+	tempname mat``i''
+	matrix `mat``i'''=J(`=`maxgroup``i'''+2',9,0)
+	forvalues j=1/`maxgroup``i''' {
+	     local k=`j'+1
+	     matrix `mat``i'''[`k',1]=`j'
+		 *tab `vargroup1``i'''
+		 qui su ``i'' if `vargroup1``i'''==`j'
+	     matrix `mat``i'''[`k',2]=`r(mean)'
+	     matrix `mat``i'''[`k',4]=`r(N)'
+		 local temp=`i'+`nbitems'
+		 *tab `vargroup2``i''' `vargroup1``i'''
+		 tab ``temp'' if `vargroup2``i'''==`j',m
+		 qui su ``temp'' if `vargroup2``i'''==`j'
+	     matrix `mat``i'''[`k',3]=`r(mean)'
+	     matrix `mat``i'''[`k',5]=`r(N)'
+		 qui su `rscore1``i''' if `vargroup1``i'''==`j'
+	     matrix `mat``i'''[`k',6]=`r(mean)'
+		 qui su `rscore2``i''' if `vargroup2``i'''==`j'
+	     matrix `mat``i'''[`k',7]=`r(mean)'
+	}	 
+	local j=`maxgroup``i'''+2
+	matrix `mat``i'''[`j',1]=`maxgroup``i'''+1 /*numero du group*/
+	matrix `mat``i'''[`j',2]=`modamax`i'' /*mean item 1*/
+	matrix `mat``i'''[`j',3]=`modamax`i'' /*mean item 2*/
+	matrix `mat``i'''[`j',4]=0 /*frequency 1*/
+	matrix `mat``i'''[`j',5]=0 /*frequency 2*/
+	if "`restscore'"=="" {
+	   local maxi=`scoremax'-`modamax`i''
+	}
+	else {
+	   local maxi=`scoremax'
+	}
+    matrix `mat``i'''[`j',6]=`maxi' /*mean rest-score 1*/
+    matrix `mat``i'''[`j',7]=`maxi' /*mean rest-score 2*/
+	label values `vargroup1``i''' lblvarscore``i''
+	qui sort `vargroup1``i''' `vargroup2``i'''
+	qui save `file4',replace
+    forvalues j=1/`maxgroup``i''' {
+        qui count if `vargroup1``i'''==`j'
+	    local n1=r(N)
+	    qui su `rscore1``i''' if `vargroup1``i'''==`j'
+	    local min1=r(min)
+	    local max1=r(max)
+        qui count if `vargroup2``i'''==`j'
+	    local n2=r(N)
+	    qui su `rscore2``i''' if `vargroup2``i'''==`j'
+	    local min2=r(min)
+	    local max2=r(max)
+	    local min=min(`min1',`min2')
+	    local max=max(`max1',`max2')
+	    label define lblvarscore``i'' `j' `""Scores `min'/`max'" "(n1=`n1';n2=`n2')""', add
+    }
+
+	label define lblvarscore``i'' 0 "Min", add
+    label define lblvarscore``i'' `=`maxgroup``i'''+1' "Max", add
+    qui drop _all
+	qui svmat `mat``i'''
+	qui rename `mat``i'''1 group
+	qui rename `mat``i'''2 e1
+	qui rename `mat``i'''3 e2 
+	qui rename `mat``i'''6 rs1
+	qui rename `mat``i'''7 rs2 
+    qui sort group
+	label values group lblvarscore``i''
+	label variable group "Groups of scores"
+	if "`graph'"=="" {
+	    if "`graphbygroup'"!="" { 
+	        graph twoway (line e1 group ) (line e2 group ), title("Traceline of item ``i''") xtitle("") ytitle("Expected value of item ``i''", size(small)) ylabel(0(1)`modamax') xlabel(0(1)`=`maxgroup``i'''+1',valuelabel labsize(small) /*alternate*/) name("``i''", replace) legend(off)
+	    }
+		else {
+		    if "`restscore'"=="" {
+			     local xtitle="Rest-score"
+				 qui su rs1
+				 local max=r(max)
+				 qui su rs2
+				 if `r(max)'>`max' {
+				     local max=r(max)
+				 }
+				 
+		    }
+			else {
+			     local xtitle="Score"
+				 local max `maxscore'
+		    }
+		    graph twoway (line e1 rs1 ) (line e2 rs2 ), title("Traceline of item ``i''") xtitle("`xtitle'") ytitle("Expected value of item ``i''", size(small)) ylabel(0(1)`modamax') xlabel(0(1)`max',valuelabel labsize(small) /*alternate*/) name("auc``i''", replace) legend(off)
+		}	
+	}
+	qui use `file4', replace
+}
+
+/*******************************************************************************
+Calcul des AUC 
+*******************************************************************************/
+
+local tests
+forvalues i=1/`nbitems' {
+    local auc1`i'=0
+    local auc2`i'=0
+    forvalues g=1/`=`maxgroup``i'''+1' {
+        local k=`g'+1
+	    local auc=(`mat``i'''[`g',2]+`mat``i'''[`k',2])/2*(`mat``i'''[`k',6]-`mat``i'''[`g',6])
+		local auc1`i'=`auc1`i''+`auc'
+	    matrix `mat``i'''[`k',8]= `auc'
+	    local auc=(`mat``i'''[`g',3]+`mat``i'''[`k',3])/2*(`mat``i'''[`k',7]-`mat``i'''[`g',7])
+		local auc2`i'=`auc2`i''+`auc'
+	    matrix `mat``i'''[`k',9]= `auc'
+	}
+    local AUC``i''=`auc1`i''
+    local AUC``=`i'+`nbitems'''=`auc2`i''
+    local diffAUC``i''=`=`AUC``i'''-`AUC``=`i'+`nbitems'''''
+    return scalar AUC``i''=`auc1`i''
+    return scalar AUC``=`i'+`nbitems'''=`auc2`i''
+    local tests `tests' b``i''=(r(AUC``=`i'+`nbitems''')-r(AUC``i''))
+}
+
+/*******************************************************************************
+Calcul des standard errors des AUC par bootstrap 
+*******************************************************************************/
+
+*local abc=0
+if "`bsauc'"=="" {
+    *di "on lance le bootstrap sur les AUC"
+	*set trace on
+	tempfile file2
+    qui save `file2', replace
+    qui use `file1', clear
+    capture qui bootstrap `tests' , rep(`nbaucbs') nol noh nodots : nopalera `varlist', nograph  `restscore' nobsaabc nobsauc
+	local n=1
+	while (_rc!=0) {
+		di "`n'. The boostrap to obtain IC of the AUC has not been correctly performed, it is run again"
+		local ++n
+		capture qui bootstrap `tests' , rep(`nbaucbs') nol noh nodots : nopalera `varlist', nograph  `restscore' nobsaabc nobsauc
+	}
+    tempname mbootstrap
+	matrix `mbootstrap'=r(table)
+    qui use `file2', clear
+
+	/*Création de la matrice p qui va permettre de décaler les ICC*/
+	tempname p
+	matrix `p'=J(`=(`scoremax'+1)*(`nbitems'+1)',`=`nbitems'*3+1',.)
+	forvalues s=0/`scoremax' {
+	   matrix `p'[`=`s'+1',1]=`s'
+	   forvalues i=1/`nbitems' {
+		  matrix `p'[`=`s'+1',`=3*`i'-1']=`s'
+	   }
+	}
+	forvalues i=1/`nbitems' {
+	   forvalues s=0/`scoremax' {
+		  qui su ``i'' if `varscore1'==`s'
+		  matrix `p'[`=`s'+1',`=3*`i'']=r(mean)
+	   }
+	   forvalues s=0/`scoremax' {
+		  qui su ``=`i'+`nbitems''' if `varscore2'==`s'
+		  if `mbootstrap'[4,`i']>=0.05 {
+			 matrix `p'[`=`s'+1',`=3*`i'+1']=r(mean)
+			 local prec=1
+			 local prec=0.01 /*pas d'arrondi*/
+		  }
+		  else {
+		     if `nind'/`scoremax'>20 {
+			    local prec=0.5
+			    local prec=1
+			    local prec=0.01 /*pas d'arrondi*/
+			 }
+			 else {
+			    local prec=1
+			    local prec=0.01 /*pas d'arrondi*/
+			 }
+			 matrix `p'[`=`i'*(`scoremax'+1)+`s'+1',`=3*`i'-1']=round(`s'+`mbootstrap'[1,`i']/(`modamax`i''),`prec')
+			 matrix `p'[`=`i'*(`scoremax'+1)+`s'+1',`=3*`i'+1']=r(mean)
+		  }
+	   }
+	}
+	di
+	di "Research of uniform recalibration at item-level"
+	di
+	di "{hline 105}"
+	di                                                               _col(45) "Bootstrap"                               _col(78) "  Normal-based"
+	di "Items" _col(18) "AUC t1" _col(28) "AUC t2" _col(38) "VarAUC" _col(45) "Std. Err." _col(63) "z" _col(70) "P>|z|" _col(78) "[95% Conf. Int.]" _col(96) "Correction"
+	di "{hline 105}"
+    forvalues i=1/`nbitems' {
+	   local corr``i''=round(`mbootstrap'[1,`i']/(`modamax`i''),`prec')
+	   di "``i''/``=`i'+`nbitems'''" _col(19) %5.2f `AUC``i''' _col(29) %5.2f `AUC``=`i'+`nbitems'''' _col(39) %5.2f `diffAUC``i''' _col(49) %5.2f `mbootstrap'[2,`i'] _col(59) %5.2f `mbootstrap'[3,`i'] _col(69) %5.4f `mbootstrap'[4,`i'] _col(79) %5.2f `mbootstrap'[5,`i'] _col(89) %5.2f `mbootstrap'[6,`i'] _col(100) %6.2f `corr``i'''
+	}
+	di "{hline 105}"
+	local abc=1
+}
+else {
+    *di "pas de bootstrap AUC"
+	local abc=1
+}
+
+*di "abc:`abc' bsAUC : `bsauc'"
+
+/*******************************************************************************
+Calcul des AABC et de leurs intervalles de confiance par boostrap 
+*******************************************************************************/
+*set trace on
+if `abc'==1 {
+   *di "on lance les AABC"
+   local testsb
+   forvalues i=1/`nbitems' {
+       if "`bsauc'"!="" { /*si pas de bootstrap pour AUC*/
+	      *di "m1"
+		  local sigAUC``i''=0
+          local rdiffAUC``i''=0
+	   }
+	   else if `mbootstrap'[4,`i']<0.05 { /* si bootstrap et significatif*/
+	      *di "m2"
+	      local sigAUC``i''=1
+		  local rdiffAUC``i''=-`corr``i'''
+		  di "The item ``i'' traceline is corrected of `corr``i'''"
+       }
+       else { /* si bootstrap et NS*/
+	      *di "m3"
+	      local sigAUC``i''=0
+          local rdiffAUC``i''=0
+       } 
+	   tempname mat2``i''
+	   local nbl=`=`maxgroup``i'''*4+7'
+       matrix `mat2``i'''=J(`nbl',4,.)
+	   matrix `mat2``i'''[1,2]=0
+	   matrix `mat2``i'''[1,3]=0
+	   matrix `mat2``i'''[`nbl',2]=`modamax`i''
+	   matrix `mat2``i'''[`nbl',3]=`modamax`i''
+	   local col1=1
+	   local col2=1
+	   local line=1
+       while (`line'<=`=`maxgroup``i'''*4+7') {
+	      local t1=`mat``i'''[`col1',6]
+		  local t2=`mat``i'''[`col2',7]-`rdiffAUC``i'''
+          local m2=`mat``i'''[`col1',2]
+		  local m3=`mat``i'''[`col2',3]
+		  if (`t1'<`t2'|(`t1'==`t2'&`m2'<`m3')) {
+		      *di "m2 car `m2'<`m3'"
+		      matrix `mat2``i'''[`line',1]=`t1'
+		      matrix `mat2``i'''[`line',2]=`mat``i'''[`col1',2]
+			  local ++col1
+          }
+		  else {
+		      *di "m3 car `m2'>`m3'"
+		      matrix `mat2``i'''[`line',1]=`t2'
+		      matrix `mat2``i'''[`line',3]=`mat``i'''[`col2',3]
+			  local ++col2
+		  }
+	      local line=`line'+2
+	   }
+	   *matrix list `mat2``i'''
+	   local j=1
+	   while (`j'<=`nbl') {
+	       foreach c in 2 3 {
+	          if `mat2``i'''[`j',`c']==. {
+                   local prec=`j'-2	
+				   local m=`mat2``i'''[`prec',`c']
+                   while (`m'==.&`prec'>=0) {
+				       local prec=`prec'-2
+               		   local m=`mat2``i'''[`prec',`c'] 
+					   *di "prec:`prec' m: `m'"
+				   }
+                   local suiv=`j'+2		
+				   local m=`mat2``i'''[`suiv',`c']
+                   while (`m'==.&`suiv'<=`nbl') {
+				       local suiv=`suiv'+2
+					   local m=`mat2``i'''[`suiv',`c']
+					   *di "suiv:`suiv' m: `m'"
+				   }
+				   local yprec=`mat2``i'''[`prec',`c']
+				   local ysuiv=`mat2``i'''[`suiv',`c']
+				   local xprec=`mat2``i'''[`prec',1]
+				   local xsuiv=`mat2``i'''[`suiv',1]
+				   local x=`mat2``i'''[`j',1]
+				   if (`xsuiv'!=`xprec') {
+				       *di "matrix `mat2``i'''[`j',`c']=`yprec'+(`x'-`xprec')/(`xsuiv'-`xprec')*(`ysuiv'-`yprec')"
+				       matrix `mat2``i'''[`j',`c']=`yprec'+(`x'-`xprec')/(`xsuiv'-`xprec')*(`ysuiv'-`yprec')
+				   }
+				   else {
+				       matrix `mat2``i'''[`j',`c']=`mat2``i'''[`prec',`c']
+				   }
+		      }
+		   }
+		   local j=`j'+2
+	   }
+	   local j=2
+	   *matrix list `mat2``i'''
+	   while (`j'<`nbl') {
+	       local prec=`j'-1 
+	       local suiv=`j'+1
+		   local sign=(`mat2``i'''[`prec',2]-`mat2``i'''[`prec',3])*(`mat2``i'''[`suiv',2]-`mat2``i'''[`suiv',3])
+		   *di "item ``i'', ligne `j', sign `sign'"
+		   if (`sign'<0&`sign'!=.) {
+		      local p1=(`mat2``i'''[`suiv',2]-`mat2``i'''[`prec',2])/(`mat2``i'''[`suiv',1]-`mat2``i'''[`prec',1])
+		      local p2=(`mat2``i'''[`suiv',3]-`mat2``i'''[`prec',3])/(`mat2``i'''[`suiv',1]-`mat2``i'''[`prec',1])
+			  if (`p1'==`p2') {
+			      local cint=`mat2``i'''[`prec',1]
+			  }
+			  else  {
+			      local cint=`mat2``i'''[`prec',1]+(`mat2``i'''[`prec',3]-`mat2``i'''[`prec',2])/(`p1'-`p2')
+			  }
+			  matrix `mat2``i'''[`j',1]=`cint'
+              foreach c in 2 3 {
+			     local yprec=`mat2``i'''[`prec',`c']
+			     local ysuiv=`mat2``i'''[`suiv',`c']
+			     local xprec=`mat2``i'''[`prec',1]
+			     local xsuiv=`mat2``i'''[`suiv',1]
+			     local x=`cint'
+				 if (`xsuiv'==`xprec') {
+				     matrix `mat2``i'''[`j',`c']=`mat2``i'''[`prec',`c']
+				 }
+				 else {
+		             *di "matrix `mat2``i'''[`j',`c']=`yprec'+(`x'-`xprec')/(`xsuiv'-`xprec')*(`ysuiv'-`yprec')"
+		             matrix `mat2``i'''[`j',`c']=`yprec'+(`x'-`xprec')/(`xsuiv'-`xprec')*(`ysuiv'-`yprec')
+				 }
+			  }
+		   }
+		   else {
+		      local prec=`j'-1
+			  forvalues c=1/3 {
+			      matrix `mat2``i'''[`j',`c']=`mat2``i'''[`prec',`c']
+			  }
+		   }
+		   local j=`j'+2
+	   }
+	   *matrix list `mat2``i'''
+	   local aabc``i''=0
+	   *set trace on
+	   forvalues j=2/`nbl' {
+	      local prec=`j'-1
+		  local x=`mat2``i'''[`j',1]
+		  local xprec=`mat2``i'''[`prec',1]
+		  local y2=`mat2``i'''[`j',2]
+		  local y3=`mat2``i'''[`j',3]
+		  local yprec2=`mat2``i'''[`prec',2]
+		  local yprec3=`mat2``i'''[`prec',3]
+	      local aabc=(abs(`y2'-`y3')+abs(`yprec2'-`yprec3'))/2*abs(`x'-`xprec')
+	      matrix `mat2``i'''[`j',4]=`aabc'
+		  local aabc``i''=`aabc``i'''+`aabc'
+	   }
+       return scalar AABC``i''=`aabc``i'''
+       *set trace off
+	   
+	   local testsb `testsb' c``i''=r(AABC``i'')
+	   *matrix list `mat2``i'''
+       *di "return scalar AABC``i''=`aabc``i'''"
+	   *matrix list `mat2``i'''
+    }
+	*set trace on
+	if "`bsaabc'"=="" {
+	    *di "on lance le bootstrap AABC"
+		tempfile file3
+		qui save `file3', replace
+		qui use `file1', clear
+		*di "bootstrap `testsb' , rep(`nbbootstrap') nol noh nodots saving(C:\Users\jean-\Documents\tmp\essai.dta, replace) : nopalera `varlist', fin nograph `restscore' nobsauc nobsaabc "
+		*set trace on
+		*set tracedepth 2
+		tempfile filebsaabc
+		*di "hello c'est l'heure du BS"
+		*qui bootstrap `testsb' , rep(`nbaabcbs') nol noh nodots saving("`filebsaabc'", replace) trace : nopalera `varlist', nograph `restscore' nobsauc nobsaabc
+		capture qui bootstrap `testsb' , rep(`nbaabcbs') saving("`filebsaabc'", replace)  : nopalera `varlist', nograph `restscore' nobsauc nobsaabc
+		local n=1
+		while (_rc!=0) {
+		    di "`n'. The boostrap to obtain IC of the AABC has not been correctly performed, it is run again"
+      		local ++n
+			capture qui bootstrap `testsb' , rep(`nbaabcbs') saving("`filebsaabc'", replace)  : nopalera `varlist', nograph `restscore' nobsauc nobsaabc
+		}
+		*return list
+		tempname mbootstrapb
+		matrix `mbootstrapb'=r(table)
+		*di "MATRIX mbootstrapb  `mbootstrapb'"
+		*matrix list `mbootstrapb'
+        qui use "`filebsaabc'", replace
+		*su
+		local thres=`nbaabcbs'-ceil(`nbaabcbs'/20)
+		forvalues i=1/`nbitems' {
+		   sort c``i''
+		   qui su c``i'' in `thres'
+		   local upper``i''=r(mean)
+		   *di "Upper ``i'' : `upper``i'''"
+		}
+		di
+		di "Research of non-uniform recalibration at item-level"
+		di
+		di "{hline 103}"
+		di                                _col(36) "Bootstrap"       _col(56) "Uniform"      _col(72) "Non-uniform" 
+		di "Items" _col(23) "AABC" _col(29) "[95% Conf. Int.]" _col(50) "Recalibration"    _col(70) "Recalibration"  _col(88) "Reprioritization"
+		di "{hline 103}"
+		forvalues i=1/`nbitems' {
+		   local xur=""
+		   local xnur=""
+		   local xrep=""
+		   if `mbootstrap'[4,`i']<=0.05 {
+		       local xur="X"
+		   }
+		   if (`aabc``i'''>`upper``i'''&"`xur'"=="X") {
+		       local xnur="X"
+		   }
+		   if (`aabc``i'''>`upper``i'''&"`xur'"=="") {
+		       local xrep="X"
+		   }
+		   
+		   di "``i''/``=`i'+`nbitems'''" _col(23) %5.2f `aabc``i''' _col(36) "[" %1.0f  0 "-" %5.2f `upper``i''' "]" _col(62) "`xur'" _col(82) "`xnur'" _col(102) "`xrep'"
+		}
+		di "{hline 103}"
+		local abc=1
+	}
+	if "`graph'"=="" {
+	    forvalues i=1/`nbitems' {
+			qui drop _all
+			qui svmat `mat2``i'''
+			qui rename `mat2``i'''1 score
+			qui rename `mat2``i'''2 t1
+			qui rename `mat2``i'''3 at2 
+			qui sort score
+			if "`restscore'"=="" {
+					 local xtitle="Rest-score"
+					 qui su score
+					 local max=r(max)
+			}
+			else {
+					 local xtitle="Score"
+					 local max `maxscore'
+			}
+			list *
+			graph twoway (line t1 score ) (line at2 score ) if score>0&score<=`maxscore', title("Traceline of item ``i''") xtitle("`xtitle'") ytitle("Expected value of item ``i''", size(small)) ylabel(0(1)`modamax') xlabel(0(1)`max',valuelabel labsize(small) /*alternate*/) name("aabc``i''", replace) legend(off)
+		}
+	}
+}
+qui restore , preserve
+end
+
+
diff --git a/Modules/ado/personal/p/pcm - Copie.ado b/Modules/ado/personal/p/pcm - Copie.ado
new file mode 100644
index 0000000..14de336
--- /dev/null
+++ b/Modules/ado/personal/p/pcm - Copie.ado	
@@ -0,0 +1,2115 @@
+*! Version 5.2 16July2023
+*! Jean-Benoit Hardouin, Myriam Blanchin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
+* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
+* Version 4.1: September 15th, 2019 [Jean-Benoit Hardouin]: correction of a small bug in the outputs
+* Version 4.2: September 27th, 2019 [Jean-Benoit Hardouin] : EQUATING
+* Version 4.3: November 8th, 2019 [Jean-Benoit Hardouin] : add a constant when difficulty parameters are fixed
+* Version 5: August 2nd, 2022 [Jean-Benoit Hardouin] : New MAP graph, corrected estimation of the latent trait
+* Version 5.1: July 8th, 2023 [Jean-Benoit Hardouin] : Correction of the MAP graph (histogram) and residuals graphs
+* Version 5.2: July 16th, 2023 [Jean-Benoit Hardouin] : Add of new graphs for Equating
+*
+*
+* Jean-benoit Hardouin, Myriam Blanchin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr, myriam.blanchin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019, 2022, 2023 Jean-Benoit Hardouin, Myriam Blanchin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [if] [in] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) VARiance(real -1) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(string) GENINF(string) REPlace postpce visit(varname) id(varname) eqset1(varlist) eqset2(varlist) eqset1name(string) eqset2name(string) EQGraph eqaddset1(real 0) eqaddset2(real 0) eqmultset1(real 1) eqmultset2(real 1) eqwithic eqgenscore(string)  DIMname(string) minsize(int 30)]
+
+preserve
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+/*************************************************************************************************************
+QUELQUES TESTS
+*************************************************************************************************************/
+
+if `variance'!=-1&`variance'<=0 {
+	di in red "The -variance- option cannot be negative"
+	exit 198
+}
+if `variance'!=-1&"`visit'"!="" {
+	di in red "The -variance- and -visit- options cannot be used simultaneously."*
+	exit 198
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' `genlt'_se `geninf' `genlt'_corr `genlt'_opt `genlt'_opt_se 
+	if _rc!=0&"`replace'"=="" {
+	    di in red "The variables `genlt', `genlt'_se, `genlt'_corr, `genlt'_opt, `genlt'_opt_se and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+	if _rc!=0&"`replace'"!="" {
+	    qui capture drop `genlt' 
+		qui capture drop `genlt'_se 
+		qui capture drop `geninf' 
+		qui capture drop `genlt'_corr
+		qui capture drop `genlt'_opt
+		qui capture drop `genlt'_opt_se
+	}
+}
+if ("`eqset1'"!=""&"`eqset2'"=="")|("`eqset1'"==""&"`eqset2'"!="") {
+    di in red "The two options -eqset1- and -eqset2- must be used simultaneously"
+	exit 198
+}
+if ("`eqset1'"!=""&"`graphs'"!="") {
+    di in red "The two options -eqset1- and -graph- cannot be used simultaneously"
+	exit 198
+}
+
+
+
+
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+if "`visit'"!=""{
+	if "`id'"==""{
+		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
+		exit 198
+	}
+	qui levelsof `visit'
+	local levelsofv `r(levels)'
+	local nbvisits=r(r)
+	local timemin: word 1 of `levelsofv'
+	local timemax: word `nbvisits' of `levelsofv'
+	if `timemax'>5{
+		di as error "You must use a discrete time variable (-visit- option) with less than 5 measurement occasions"
+		error 198
+	}
+	if `timemin'!=1{
+		di as error "You must use a -visit- variable coded at 1 for the first visit"
+		error 198
+	}
+	qui reshape wide `varlist', i(`id') j(`visit')
+	local multivisit=1
+}
+else {
+	local timemax=1
+	foreach i in `varlist' {
+	   *rename `i' `i'1
+	}
+	local multivisit
+}
+qui count if `touse'
+local nbobs=r(N)
+
+local timelist
+forvalues t=1/`timemax'{
+	local timelist `timelist' T`t'
+}
+
+local modcont
+local premodcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local premodcont (`modcont'->T1)
+	local modcont (`modcont'->`timelist')
+}
+
+local modcat
+local premodcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local premodcat (`modcat'->T1)
+	local modcat (`modcat'->`timelist')
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+local scoremax=0
+forvalues i=1/`nbitems' {
+	local modamax`i'=1
+	local modamax``i''=1
+	if `timemax'>1 {
+		forvalues t=1/`timemax'{
+			 *qui replace ``i'`t''=``i'`t''-`min' 
+			 qui su ``i''`t' if `touse'
+			 if `r(min)'!=`modamin' {
+				 local modamin=r(min)
+				 local pbmin `pbmin' ``i'`t''
+			 }
+			 if `r(max)'>`modamax' {
+				 local modamax=r(max)
+			 }
+			 if `r(max)'>`modamax`i'' {
+				local modamax`i'=r(max)
+			}
+		}
+	}
+	else {
+		*di "i: `i' ``i''"
+		qui su ``i'' if `touse'
+		if `r(min)'!=`modamin' {
+		    local modamin=r(min)
+			local pbmin `pbmin' ``i''
+		}
+		if `r(max)'>`modamax' {
+			local modamax=r(max)
+		}
+		if `r(max)'>`modamax`i'' {
+			local modamax`i'=r(max)
+			local modamax``i''=r(max)
+		}
+	}
+	*di "local scoremax=`scoremax'+`modamax`i''"
+	local scoremax=`scoremax'+`modamax`i''
+	if "`rsm'"=="" {
+		local nbdiff=`nbdiff'+`modamax`i''
+	}
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count if `touse'
+local nbind=r(N)
+*set trace on
+local code
+local precode
+if `timemax'>1 {
+	forvalues k=1/`modamax' {
+	   forvalues t=1/`timemax'{
+			local code`k'
+		   forvalues i=1/`nbitems' {
+			   if `k'<=`modamax`i'' {
+				  local code`k' `code`k'' `k'.``i''`t'
+			   }
+		   }
+		   local code`k' (`code`k''<-T`t'@`k')
+		   if `t'==1{
+				local precode `precode' `code`k''
+		   }
+		   local code `code' `code`k''
+		}
+	}
+}
+else {
+	forvalues k=1/`modamax' {
+		local code`k'
+		forvalues i=1/`nbitems' {
+			if `k'<=`modamax`i'' {
+				local code`k' `code`k'' `k'.``i''
+			}
+		}
+		local code`k' (`code`k''<-T1@`k')
+		local precode `precode' `code`k''
+		local code `code' `code`k''
+	}
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist' if `touse'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist' if `touse', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+local t=1
+local constraints
+local codemean
+local codevar
+local codecov
+forvalues j=2/`timemax'{
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			qui constraint `t' [`k'.``i''`j']_cons=[`k'.``i''`multivisit']_cons
+			local constraints `constraints' `t'
+			local ++t
+			
+		}
+	}	
+	if "`continuous'"=="" &  "`categorical'"==""{
+		local codemean `codemean' T`j'@m`j'
+		local codevar `codevar' T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' T`l'*T`j'@cov`l'`j'
+		}
+	}
+	else{
+		local codevar `codevar' e.T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
+		}	
+	}
+}
+if `timemax'>1{
+	if "`continuous'"=="" &  "`categorical'"==""{	
+		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
+	}
+	else{
+		local codelg var(e.T1@v1 `codevar') cov(`codecov')
+	}
+}
+else {
+    local constrvar
+    if `variance'>0 {
+		if "`continuous'"=="" &  "`categorical'"==""{	
+			local constrvar var(T1@`variance') 
+		}
+		else{ 
+			*local constrvar var(e.T1@`variance') 
+		}
+	}
+}
+
+local fixedmean
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				qui constraint `t' [`k'.``i''`multivisit']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+	if "`continuous'"=="" &  "`categorical'"=="" {	
+		local fixedmean mean(T1) 
+	}
+	else{
+		local fixedmean 
+	}
+}
+
+
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+if "`rsm'"!="" {
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       qui constraint `t'   [`=`k'-1'.``i''`multivisit']_cons-[`k'.``i''`multivisit']_cons+[1.``i''`multivisit']_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
+if "`model'"!="" {
+    local qui
+}
+else {
+	local qui qui
+}
+if `timemax'==1{
+   *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'"
+   `qui' gsem `code' `modcont' `modcat' if `touse' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+   *qui gen un=1
+   *`qui' gsem `code' (i.group un->T) ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+}
+else{
+    *di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
+    `qui' gsem `precode' `premodcont' `premodcat' if `touse',iterate(`iterate') tol(`tolerance') constraint(`constraints') 
+     matrix esti_B = e(b)
+    *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)"
+    `qui' gsem `code' `modcont' `modcat' if `touse',iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
+}
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2 miss
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent'* if `touse',latent se(`selatent'*)
+*di "latent=`latent' "
+*su
+*set trace on
+
+if "`genlt'"!="" {
+	if `timemax'==1 {
+		qui gen `genlt'=`latent'1 if `touse'
+		qui gen `genlt'_se=`selatent'1 if `touse'
+	}
+	forvalues t=2/`timemax' {
+		qui gen `genlt'`t'=`latent'`t' if `touse'
+		qui gen `genlt'`t'_se=`selatent'`t' if `touse'
+	}
+}
+
+set seed 123456
+if `timemax'>1 {
+	forvalues t=1/`timemax'{
+		qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t' if `touse'
+		local listit 
+		forvalues i=1/`nbitems' {
+			local listit `listit' ``i''`t'
+		}
+		qui genscore `listit' if `touse',score(`score'`t')
+		qui gengroup `latent'`t' if `touse',newvariable(`group'`t') continuous minsize(`minsize')
+	}
+}
+else {
+	qui gen `latent2'=`latent'1+invnorm(uniform())*`selatent'1 if `touse'
+	local listit 
+	forvalues i=1/`nbitems' {
+		local listit `listit' ``i''
+	}
+	qui genscore `listit' if `touse',score(`score')
+	qui gengroup `latent'1 if `touse',newvariable(`group') continuous minsize(`minsize')
+}
+forvalues s=0/`scoremax' {
+    qui count if `score'==`s'&`touse'
+	local effscore`s'=r(N)
+}
+
+
+/*time 1 only*/
+qui levelsof `group'`multivisit' if `touse'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+6',.)
+forvalues g=1/`nbgroups' {
+	matrix `groups'[`g',`=`nbitems'+3']=0
+	qui count if `group'`multivisit'==`g'&`touse'
+	local effgroup`g'=r(N)
+	forvalues i=1/`nbitems' {
+			qui count if ``i''`multivisit'!=.&`group'`multivisit'==`g'&`touse'
+			local n=r(N)
+			if `n'>0 {
+				qui su ``i''`multivisit' if `group'`multivisit'==`g'&`touse'
+				matrix `groups'[`g',`i']=r(mean)
+				matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+			}
+			else {
+				matrix `groups'[`g',`i']=.
+				matrix `groups'[`g',`=`nbitems'+3']=.
+			}		
+	}
+	qui su `latent'1 if `group'`multivisit'==`g'&`touse'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'`multivisit'==`g'&`touse'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+	qui su `score' if `group'`multivisit'==`g'&`score'!=.&`touse'
+	matrix `groups'[`g',`=`nbitems'+4']=r(min)
+	matrix `groups'[`g',`=`nbitems'+5']=r(max)	
+}
+
+/*number of non-missing on all time points*/
+egen `miss'=rowmiss(`score'*) if `touse'
+qui count if `miss'==0&`touse'
+local nbobsssmd=r(N)
+drop `miss'	
+
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i''`multivisit':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i''`multivisit':_cons]
+	qui lincom -_b[1.``i''`multivisit':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+	local rn `rn' 1.``i''`multivisit'
+	local ++t
+	local sum _b[1.``i''`multivisit':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax`i'' {
+			local sum "_b[`k'.``i''`multivisit':_cons]-(`sum')"
+			*di "``i''`multivisit' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i''`multivisit':_cons]-_b[`k'.``i''`multivisit':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''`multivisit'
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1'`multivisit':_cons]-_b[`k'.`1'`multivisit':_cons]+_b[1.`1'`multivisit':_cons] /*``i'' instead of `i'?*/
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
+*************************************************************************************************************/
+tempname covariates
+local nbcov=0
+forvalues j=2/`timemax'{
+	local nbcov=`nbcov'+`j'-1
+}
+qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)
+
+*set trace on
+local t=1
+
+
+forvalues j=1/`=`timemax'-1'{
+	forvalues k=`=`j'+1'/`timemax'{
+		if "`categorical'"=="" & "`continuous'"=="" {
+			if `j'==1{
+				qui lincom [/]mean(T`k')
+			}
+			else{
+				qui lincom [/]mean(T`k')-[/]mean(T`j')
+			}
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+		else{
+			if "`categorical'"!=""{
+				local first=0 
+				foreach l in `levelsof`cat1'' {
+					if `first'==0 {
+						local ++first
+					}
+					else{
+						if `first'==1 {
+							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
+							qui matrix `covariates'[`t',1]=`r(estimate)'
+							qui matrix `covariates'[`t',2]=`r(se)'
+							qui matrix `covariates'[`t',3]=`r(z)'
+							qui matrix `covariates'[`t',4]=`r(p)'
+							qui matrix `covariates'[`t',5]=`r(lb)'
+							qui matrix `covariates'[`t',6]=`r(ub)'
+							local ++t
+							local ++first
+						}
+					}
+				}
+			}
+			else{
+				qui lincom [T`k']`cont1'-[T`j']`cont1'
+				qui matrix `covariates'[`t',1]=`r(estimate)'
+				qui matrix `covariates'[`t',2]=`r(se)'
+				qui matrix `covariates'[`t',3]=`r(z)'
+				qui matrix `covariates'[`t',4]=`r(p)'
+				qui matrix `covariates'[`t',5]=`r(lb)'
+				qui matrix `covariates'[`t',6]=`r(ub)'
+				local ++t
+			}		
+		}
+	}
+}	
+		
+forvalues j=1/`timemax'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		qui lincom _b[/var(e.T`j')]
+	}
+	else {
+		qui lincom _b[/var(T`j')]
+	}
+	qui matrix `covariates'[`t',1]=`r(estimate)'
+	qui matrix `covariates'[`t',2]=`r(se)'
+	qui matrix `covariates'[`t',3]=`r(z)'
+	qui matrix `covariates'[`t',4]=`r(p)'
+	qui matrix `covariates'[`t',5]=`r(lb)'
+	qui matrix `covariates'[`t',6]=`r(ub)'
+	local ++t
+}
+forvalues j=1/`=`timemax'-1'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(e.T`j',e.T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+	else{
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(T`j',T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+}
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+*matrix list `covariates'
+
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 83}"
+	di  as text _col(70) "<--95% IC -->"
+	di   _col(70) "Lower" _col(78) "Upper"
+	di "Items" _col(22) "Threshold" _col(35) "Estimate" _col(47) "s.e." _col(58) "z" _col(66) "p" _col(69) " Bound" _col(78) "Bound"
+	di "{hline 83}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax`i'' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %5.2f `diff'[`t',3] _col(62) %5.2f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %5.2f `diff'[`t',3] _col(62) %5.2f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 83}"
+	local t=1
+	local listmoy
+	local listvar
+	local listcov
+	forvalues j=1/`timemax'{
+		local listvar `listvar' Variance_T`j'
+		forvalues k=`=`j'+1'/`timemax'{
+			local listcov `listcov' Cov_T`j'_T`k'
+		}
+		forvalues k=`=`j'+1'/`timemax'{
+			local listmoy `listmoy' Mean_diff_T`j'_T`k'
+		}
+	}
+	local n: word count `listmoy' `listvar' `listcov' `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of `listmoy' `listvar' `listcov' `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %5.2f `covariates'[`t',3] _col(62) %5.2f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %5.2f `covariates'[`t',3] _col(62) %5.2f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		*local ++t
+	}
+	di as text "{hline 83}"
+	if "`visit'"==""{
+		di
+		qui su `latent'1 if `touse'
+		*qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])+(`r(sd)')^2)
+		*di as text "Variance of the estimated latent variable: " as result %4.2f `=(`r(sd)')^2'
+        tempvar se2latent
+		qui gen `se2latent'=(`selatent'1)^2 if `touse'
+		qui su `se2latent' if `touse'
+		local resvar=r(mean)
+		di as text "Mean squared std error of the latent variable: " as result %4.2f `resvar'
+		di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`resvar'))'
+		local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`resvar'))
+		di as text "PSI: " as result %4.2f `PSI' _c
+		if "`continuous'"!=""|"`categorical'"!="" {
+		    di as text " (without adjustment on covariates)"
+	    }
+		else {
+		    di
+		}
+		di
+		return scalar PSI=`PSI'
+
+	}
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+if "`visit'"==""{
+	tempname fit
+	qui matrix `fit'=J(`nbitems',4,.)
+	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+	matrix rownames `fit'=`varlist'
+	*matrix list `fit'
+
+	tempvar Tcum TInf cum
+	qui gen `Tcum'=0 if `touse'
+	qui gen `TInf'=0 if `touse'
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text _col(60) "<---  Standardized   --->"
+		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+		di as text "{hline 90}"
+		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "{hline 90}"
+	}
+	*set trace on
+	local chi2=0
+	local chi2_old=0
+	forvalues g=1/`nbgroups' {
+	   local chi2_g`g'=0
+	   local chi2_old_g`g'=0
+	}
+	forvalues i=1/`nbitems' {
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+		local d=1
+		local d_old=1
+		qui gen `cum``i'''=0 if `touse'
+		qui gen `cum_old``i'''=0 if `touse'
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+			local d_old `d_old'+exp(`k'*`latent'1-`diffmat2'[`i',`k'])
+		}
+		qui gen `c0_``i'''=1/(`d') if `touse' 
+		qui gen `c_old0_``i'''=1/(`d_old') if `touse'
+		forvalues k=1/`mm' {
+			tempvar c`k'_``i'' c_old`k'_``i''
+			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d') if `touse'
+			qui gen `c_old`k'_``i'''=exp(`k'*`latent'1-`diffmat2'[`i',`k'])/(`d') if `touse'
+			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k' if `touse'
+			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k' if `touse'
+		}
+		qui gen `Inf``i'''=0 if `touse'
+		qui gen `Inf_old``i'''=0 if `touse'
+		qui gen `C``i'''=0 if `touse'
+		forvalues k=0/`mm' {
+			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i''' if `touse'
+			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i''' if `touse'
+			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i''' if `touse'
+		}
+		qui count if ``i''!=.&`touse'
+		local n``i''=r(N)
+		
+		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2) if `touse'
+		qui su `C2``i''' if `touse'
+		local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2 if `touse'
+		qui su `C3``i'''
+		local n=r(sum)
+		qui su `Inf``i''' if `touse'
+		local d=r(sum)
+		local q2i``i''=`n'/((`d')^2)
+		
+		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+		
+		qui replace `Tcum'=`Tcum'+`cum``i''' if `touse'
+		qui replace `TInf'=`TInf'+`Inf``i''' if `touse'
+		qui gen `y``i'''=``i''-`cum``i''' if `touse'
+		qui gen `y_old``i'''=``i''-`cum_old``i''' if `touse'
+		qui gen `y2``i'''=(`y``i''')^2 if `touse'
+		qui gen `y2_old``i'''=(`y_old``i''')^2 if `touse'
+		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i''')) if `touse'
+		local chi2_``i''=0
+		local chi2_old_``i''=0
+		forvalues g=1/`nbgroups' {
+			qui su `y2``i''' if `group'==`g'&`touse'
+			local n=r(sum)
+			qui su ``i'' if `group'==`g'&`touse'
+			local n1=r(sum)
+			qui su `cum``i''' if `group'==`g'&`touse'
+			local n2=r(sum)
+			qui su `Inf``i''' if `group'==`g'&`touse'
+			local d=r(sum)
+			*qui count if `group'==`g'
+			*local eff=r(N)
+			*di "chi2_`g'_``i''=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')"
+			local chi2=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_``i''=`chi2_``i'''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_g`g'=`chi2_g`g''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			qui su `y2_old``i''' if `group'==`g'&`touse'
+			local n_old=r(sum)
+			qui su ``i'' if `group'==`g'&`touse'
+			local n1_old=r(sum)
+			qui su `cum_old``i''' if `group'==`g'&`touse'
+			local n2_old=r(sum)
+			qui su `Inf_old``i''' if `group'==`g'&`touse'
+			local d_old=r(sum)
+			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+		}
+		*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+		*su `z``i'''
+		label variable `z``i''' "Standardized residuals associated to ``i''"
+		label variable `latent'1 "Latent trait"
+		*set trace on
+		if  "`graphs'"!=""&"`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fs saving("`dirsave'//residuals_``i''",replace)
+			}
+			tempvar id``i''
+			qui gen `id``i'''=_n if abs(`z``i''')>2.57*sqrt(`covariates'[1,1])&`touse'
+			qui tostring `id``i''',replace
+			qui replace `id``i'''="" if `id``i'''=="."&`touse'
+			qui su `z``i''' if `touse'
+			local min=r(min)
+			local max=r(max)
+			local min=floor(min(`min',`=-2*sqrt(`covariates'[1,1])'))
+			local max=ceil(max(`max',`=2*sqrt(`covariates'[1,1])'))
+			
+			qui graph twoway scatter `z``i''' `latent' if `touse', yscale(range(`min'(1)`max')) yline(`=-2.57*sqrt(`covariates'[1,1])' `=2.57*sqrt(`covariates'[1,1])',lcolor(blue)) mlabel(`id``i''') name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+		}
+		*set trace off 
+		qui gen `z2``i'''=(`z``i''')^2 if `touse'
+		qui su `z2``i''' if `touse'
+		local OUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',1]=`OUTFIT``i'''
+		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `Inf``i''' if ``i''!=.&`touse'
+		local sumw``i''=r(sum)
+		qui gen `i``i'''=`Inf``i'''*`z2``i''' if `touse' 
+		qui su `i``i''' if ``i''!=.&`touse'
+		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+		qui matrix `fit'[`i',2]=`INFIT``i'''
+		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		qui matrix `fit'[`i',4]=`INFITs``i'''
+		if "`postpce'"=="" {
+			di "``i''" _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+		}
+	}
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text "*: As suggested by Wright (Smith, 1998)"
+		di as text "**: As suggested by Bond and Fox (2007)"
+	}
+	if "`geninf'"!="" {
+	    gen `geninf'=`TInf' if `touse'
+	}
+}
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Iteration `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1') if `touse'
+		`qui' pcm `varlist' [iweight=`sinf'] if `touse',diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1') if `touse'
+		qui su `ecart_`it'' if `touse'
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+/*************************************************************************************************************
+ESTIMATION OF THE CORRECTED VALUES OF THE LT ESTIMATORS (values of lt that explained the best the score)
+**************************************************************************************************************/
+*set trace on
+tempfile savefile
+qui save `savefile'
+
+qui drop _all
+		
+qui set obs 2000
+qui gen u=(_n-1000)/200*`=sqrt(`covariates'[1,1])'
+qui gen Tcum=0
+qui gen TInf=0
+forvalues i=1/`nbitems' {
+		local d=1
+		qui gen cum``i''=0
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+		}
+		qui gen c0_``i''=1/(`d')
+		forvalues k=1/`mm' {
+			qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+			qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+		}
+		qui gen Inf``i''=0
+		forvalues k=1/`mm' {
+			qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+		}
+		*set trace on
+		qui replace Tcum=Tcum+cum``i''
+		qui replace TInf=TInf+Inf``i''	
+	    local scoremax=0
+		forvalues l=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`l''
+	    }
+		qui gen ecart=.
+		forvalues l=0/`scoremax' {
+		    if `l'==0 {  
+			   local j=0.25
+			}
+			else if `l'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`l'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`l'=`r(mean)'
+			*qui su TInf if round(ecart, 0.01)==round(`tmp',0.01)
+			*local setlt`l'=sqrt(1/`r(mean)')
+		}
+		qui drop ecart
+}
+qui use `savefile', clear
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+if "`visit'"==""{
+*set trace on
+    tempname matscorelt matgroupscorelt
+	*di "qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)"
+	qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)
+	qui matrix `matgroupscorelt'=J(`=`nbitems'*`modamax'+1'+2*`nbgroups'',7,.)
+	qui matrix colnames `matgroupscorelt'="Group" "Score" "Frequency" "Estimation of latent trait" "s.e. of latent trait" "Expected score" "Corrected latent trait"
+	
+	local row=1
+	di
+	di as text "{hline 71}"
+	di _col(32) "Latent Trait" _col(50) "Expected" _col(63) "Corrected"
+	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score" _col(60) "latent trait"
+	di as text "{hline 71}"
+	forvalues g=1/`nbgroups' {
+		local sumuc=0
+		local sumc=0
+		qui count if `group'`multivisit'==`g'&`touse'
+		local eff`g'=r(N)
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'!=.&`touse'
+		local effcompleted`g'=r(N)
+		qui count if `score'`multivisit'!=.&`group'`multivisit'==`g'&`touse'
+		local n=r(N)
+		di as text "`g' (n=" as result `eff`g'' as text ")" _c
+		if `n'>0 {
+			qui su `score'`multivisit' if `group'`multivisit'==`g'&`touse'
+			local scoremin`g'=`r(min)'
+			local scoremax`g'=`r(max)'
+			forvalues s=`scoremin`g''/`scoremax`g'' {
+				qui count if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local eff=r(N)
+				local effscore`s'=r(N)
+				if `eff'!=0 {
+					qui su `latent'1 if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+					local mean=r(mean)
+					*di "local ltscore`s'=`=ceil(`r(mean)'*100)/100'"
+					local ltscore`s'=`=ceil(`r(mean)'*100)/100'
+					*di "local sumc=`sumc'+(`eff')*(`estlt`s'')"
+					*di "local sumuc=`sumuc'+(`eff')*(`mean')"
+				    local sumuc=(`sumuc'+((`eff')*(`mean')))
+				    local sumc=(`sumc'+((`eff')*(`estlt`s'')))
+				}
+				qui su `selatent'1 if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local se=r(mean)
+				qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local exp=r(mean)
+				if `eff'>0 {
+				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp' _col(66) %6.3f `estlt`s''  `setlt`s''
+				}
+				*set trace on
+				*matrix list `matscorelt'
+				qui matrix `matscorelt'[`=`s'+1',1]=`eff'
+				qui matrix `matscorelt'[`=`s'+1',2]=`mean'
+				qui matrix `matscorelt'[`=`s'+1',3]=`se'
+				qui matrix `matgroupscorelt'[`row',1]=`g'
+				qui matrix `matgroupscorelt'[`row',2]=`s'
+				qui matrix `matgroupscorelt'[`row',3]=`eff'
+				qui matrix `matgroupscorelt'[`row',4]=`mean'
+				qui matrix `matgroupscorelt'[`row',5]=`se'
+				qui matrix `matgroupscorelt'[`row',6]=`exp'
+				qui matrix `matgroupscorelt'[`row',7]=`estlt`s''
+				local ++row
+				*set trace off
+			}
+			
+		}
+		*set trace on
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+		local eff=r(N)
+		local eff_md_`g'=r(N)
+		if `eff'!=0 {
+			qui su `latent'1 if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local mean=r(mean)
+			local lt_md_`g'=r(mean)
+			local sumuc=(`sumuc'+((`eff')*(`mean')))
+			qui su `selatent'1 if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local se=r(mean)
+			qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local exp=r(mean)
+			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) /*%5.2f `exp'*/
+			qui matrix `matgroupscorelt'[`row',1]=`g'
+			*qui matrix `matgroupscorelt'[`row',2]=`s'
+			qui matrix `matgroupscorelt'[`row',3]=`eff'
+			qui matrix `matgroupscorelt'[`row',4]=`mean'
+			qui matrix `matgroupscorelt'[`row',5]=`se'
+			qui matrix `matgroupscorelt'[`row',6]=`exp'
+			*qui matrix `matgroupscorelt'[`row',7]=`estlt`s''
+			local ++row
+		}
+		*set trace off
+		*di "local lt`g'=`sumuc'/`eff`g''"		
+		*di "local clt`g'=`sumc'/`effcompleted`g''"
+		local lt`g'=(`sumuc')/(`eff`g'')
+		local clt`g'=(`sumc')/(`effcompleted`g'')
+		matrix `groups'[`g',`=`nbitems'+6']=`clt`g''
+		*di "group `g' est=`lt`g'' corrected est=`clt`g''"
+		di as text "         " "{dup 62:-}"
+		if "`scoremin`g''"=="" {
+			local scoremin`g' "."
+		}
+		if "`scoremax`g''"=="" {
+			local scoremax`g' "."
+		}
+		di  as text _col(10) "`scoremin`g''/`scoremax`g''" as result _col(20) %4.0f `eff`g'' _col(30) %6.3f `lt`g''  _col(66) %6.3f `clt`g''
+		di as text "{hline 71}"
+		qui matrix `matgroupscorelt'[`row',1]=`g'
+		*qui matrix `matgroupscorelt'[`row',2]="`scoremin`g''/`scoremax`g''"
+		qui matrix `matgroupscorelt'[`row',3]=`eff`g''
+		qui matrix `matgroupscorelt'[`row',4]=`lt`g''
+		qui matrix `matgroupscorelt'[`row',5]=`se'
+		*qui matrix `matgroupscorelt'[`row',6]=`exp'
+		qui matrix `matgroupscorelt'[`row',7]=`clt`g''
+		local ++row
+	}
+	local nbrowmat=`row'-1
+	qui matrix `matgroupscorelt'=`matgroupscorelt'[1..`nbrowmat',1..7]
+	*matrix list `matscorelt'
+}	
+
+*set trace on
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+*set trace on
+if "`visit'"==""{
+	if "`graphs'"!=""|"`graphs'"=="" {
+
+		tempfile savefile
+		qui save `savefile'
+
+		*qui clear
+		qui drop _all
+		local pas=1000*round(`=sqrt(`covariates'[1,1])',0.001)
+		qui set obs `pas'
+		qui gen u=round((_n-`pas'/2)/(`pas'/10)*`=sqrt(`covariates'[1,1])',0.01)
+		*list u
+		qui gen Tcum=0
+		qui gen TInf=0
+		qui gen ecartcum=.
+		forvalues i=1/`nbitems' {
+		   local scatteri`i' 
+		   local scatteric`i' 
+		   forvalues g=1/`nbgroups' {
+			  local x=`groups'[`g',`=`nbitems'+1']
+			  local xc=`groups'[`g',`=`nbitems'+6']
+			  local y=`groups'[`g',`i']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			  local scatteric`i' `scatteric`i'' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off)
+			*set trace off
+			}
+			local d=1
+			qui gen cum``i''=0
+			*set trace on
+			if "`rsm'"=="" {
+				local mm=`modamax`i''
+			}
+			else {
+				local mm `modamax'
+			}	
+			forvalues k=1/`mm' {
+				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+			}
+			qui gen c0_``i''=1/(`d')
+			label variable c0_``i'' "Pr(``i''=0)"
+			forvalues k=1/`mm' {
+				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+				label variable c`k'_``i'' "Pr(``i''=`k')"
+			}
+			forvalues k=0/`mm' {
+			    if `k'==0 {
+				   local l=0.25
+				}
+				else if `k'==`mm' {
+				   local l=`k'-0.25
+				}
+				else {
+				   local l=`k'
+				}
+				qui replace ecartcum=abs(cum``i''-`l')
+				qui su ecartcum
+				qui su u if round(ecartcum,0.01)==round(`r(min)',0.01)
+				local bestest``i''_`k'=r(mean)
+				*di "item ``i'' cat `k' : est=`bestest``i''_`k''"
+			}
+			qui gen Inf``i''=0
+			forvalues k=0/`mm' {
+				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+			}
+			if "`graphitems'"=="" {
+				if "`filesave'"!="" {
+					local fsc saving("`dirsave'//CCC_``i''",replace)
+					local fsi saving("`dirsave'//ICC_``i''",replace)
+				}
+				if "`graphs'"!="" {
+					qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+					qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+					qui graph twoway line cum``i'' u, name(ICCc``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Corrected latent trait") `scatteric`i'' `fsi'
+				}
+			}
+			qui replace Tcum=Tcum+cum``i''
+			*tab Tcum
+			qui replace TInf=TInf+Inf``i''	
+			label variable Inf``i'' "``i''"
+		}
+	    local scoremax=0
+		forvalues i=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`i''
+	    }
+		qui gen ecart=.
+		forvalues i=0/`scoremax' {
+		    if `i'==0 {  
+			   local j=0.25
+			}
+			else if `i'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`i'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`i'=`r(mean)'
+			*di "score `i' : `r(mean)'"
+		}
+		if "`filesave'"!="" {
+			local fst saving("`dirsave'//TCC",replace)
+			local fsteo saving("`dirsave'//TCCeo",replace)
+			local fsi saving("`dirsave'//ICC",replace)
+			local fsti saving("`dirsave'//TIC",replace)
+			local fsm saving("`dirsave'//map",replace)
+		}
+		if "`graphs'"!="" {
+*qui save "C:\temp\info\info",replace
+			qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+			qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+			qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+		}
+		local scatteri
+		local scatteric
+		forvalues g=1/`nbgroups' {
+			local x=`groups'[`g',`=`nbitems'+1']
+			local xc=`groups'[`g',`=`nbitems'+6']
+			local y=`groups'[`g',`=`nbitems'+3']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			local scatteric `scatteric' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off)
+		}
+		if "`graphs'"!="" {
+			qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+			qui graph twoway line Tcum u , name(TCCceo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Corrrected latent trait") `scatteric' `fsteo'
+		}
+	}
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+	*set trace on
+	if "`graphs'"!=""|"eqset1"!="" {
+		gen eff=0
+		gen eff_md=0
+		local effmax=0
+			*gen uround=round(u,0.01)
+			*list uround
+		/*le bloc suivant Ă©tait pour avoir des batons par groupe*/
+		/*forvalues g=1/`nbgroups' {
+			local eff=`groups'[`g',`=`nbitems'+2']
+			if `groups'[`g',`=`nbitems'+2']>`effmax' {
+			   local effmax=`groups'[`g',`=`nbitems'+2']
+			}
+			local lat=round(`groups'[`g',`=`nbitems'+1'],0.01)
+			*di "replace eff=`eff' if round(u,0.01)==`lat'"
+			qui replace eff=`eff' if round(u,0.01)==`lat'
+		}*/
+		/*le bloc suivant est pour avoir des batons par score*/
+		qui gen uceil=ceil(u*100)/100
+		forvalues s=0/`scoremax' {
+			if `effscore`s''>`effmax' {
+			   local effmax=`effscore`s''
+			}
+			*di "`s' qui replace eff=`effscore`s'' if ceil(u*100)/100==`=round(`ltscore`s'',0.01)'"
+			qui replace eff=`effscore`s'' if round(u,0.01)==round(`ltscore`s'',0.01)
+		}
+		forvalues g=1/`nbgroups' {
+			*di "if `eff_md_`g''>`effmax' { (`lt_md_`g'')"
+			if `eff_md_`g''>`effmax' {
+			   local effmax=`eff_md_`g''
+			}
+			qui replace eff_md=`eff_md_`g'' if round(u,0.01)==round(`lt_md_`g'',0.01)
+		}
+
+		gen density=normalden(u)*sqrt(`covariates'[1,1])
+		label variable eff "Frequencies"
+		label variable u "Latent trait"
+		label variable TInf "Information curve"
+		label variable density "Density function of the latent trait"
+		local scatteri
+		local scatterj
+		local color 
+		qui su u if eff!=0|eff_md!=0
+		*set trace on
+		*set tracedepth 1
+		*if eff!=0|eff_md!=0 {
+			local floor=floor(`r(min)')
+			local ceil=ceil(`r(max)')
+		*}
+		*else  {
+		*	local floor=-10
+		*	local ceil=10
+		*}
+		local sep
+		local ylbl
+		forvalues i=1/`nbitems' {
+		   local color`i':word `i' of `color'
+		   local unit=round(`effmax'/`nbitems',1)
+		   local y=-`i'*`unit'             
+		   loca staritem
+		   local legend `"3 "1" "'
+		   forvalues l=1/`modamax' {
+			   if `l'>=2 {
+			      local legend `" `legend' `=2*`l'+1' "`l'" "'
+			   }			   
+			   local x=`diffmat'[`i',`l']
+			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+			   if `l'==1 {
+			      local xant=`x'
+			   }
+			   else {
+			      local xant=`diffmat'[`i',`=`l'-1']
+			   }
+			   if `xant'>`x' {
+				  local star *
+				  local staritem *
+			   }
+			   else {
+			      local star
+			   }
+			   local scatterj `" `scatterj' `sep' scatteri `y' `x'   , pstyle(p`l') || pci `y' `xant' `y' `x', pstyle(p1) color(black)"'
+			   local sep ||
+			   if `x'<`floor' {
+				  local floor=floor(`x')
+			   }
+			   if `x'>`ceil'&`x'!=. {
+				  local ceil=ceil(`x')
+			   }
+		   }
+   		   local ylbl `ylbl' `=-`i'*`unit'' "``i''`staritem'"
+		   local scatteri `scatteri' || scatteri `y' `=`floor'-2' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+		}
+		qui su eff
+		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+		qui su eff_md
+		local maxe_md=ceil(`=(floor(`r(max)'/10)+1)*10')
+		local maxe=max(`maxe',`maxe_md')
+		qui su TInf
+		local maxi=1.2*ceil(`r(max)')
+		qui su density
+		local maxd=round(`r(max)', 0.01)+0.01
+		qui drop if u<`floor'|u>`ceil'
+		*di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(0(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3)) `scatterj'   , name(map,replace) ytitle(Frequencies)  ylabel(0(`=`maxi'/5')`maxi' ,axis(2)) ylabel(0(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title(Individuals/items representations (Map)) xsize(12) ysize(9) note(Red line: Information curve - Green line : Density of the latent trait) xtitle(Latent trait) `fsm'"
+		*graph combine TIC IIC,  col(1)
+		*graph save "map" "map.gph", replace
+		*discard
+		*qui graph twoway line TInf u , name(map,replace)
+		*qui graph twoway `scatterj'  , name(map2,replace) ytitle("")   ylabel(`ylbl', grid angle(0))  legend(off) xsize(12) ysize(9) 
+		*su
+*list eff u if eff!=0
+*browse
+		if "`eqset1'"==""&"`graphs'"!="" {
+		    *list eff u uceil if eff!=0&eff!=.
+			*save tmp, replace
+			qui graph twoway (bar eff u,  barwidth(.1) yaxis(1) xlabel(`floor'(1)`ceil') color(erose) ) (line TInf u,yaxis(2) lwidth(medthick)) (line density u,yaxis(3) lwidth(medthick) lcolo(green) ) (bar eff_md u,  barwidth(.05) yaxis(1) xlabel(`floor'(1)`ceil') color(stred) )  `scatterj'   , xline(0, lcolor(black)) legend(on position(6) cols(`modamax') rows(1) order(`"`legend'"')  subtitle(Threshold parameters) size(small)) name(map,replace) ytitle("                           Frequencies")  ylabel(0(`=`maxi'/5')`maxi' `maxi'(`maxi')`=`maxi'*2' ,axis(2)) yscale(axis(2) off) yscale(axis(3) off)  ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) yline(0,lwidth(medium) lpattern(solid) lcolor(black))  ylabel(`ylbl',/*noticks*/ grid angle(0) axis(1)) ylabel(`ylbl' 0(`=`maxe'/5')`maxe', grid angle(0) axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait - * : dysfunctioning items") xtitle("Latent trait") `fsm'
+		}
+		else if "`eqset1'"!="" {
+			qui su eff
+	        local ceil=ceil(ceil(`r(max)'/10)*10)
+
+            qui tempfile equating
+			qui save `equating', replace
+		}
+	}
+	qui use `savefile', clear
+}
+		 
+
+
+/*************************************************************************************************************
+Best estimates by category 
+*************************************************************************************************************/
+
+tempname bestest
+matrix `bestest'=J(`nbitems',`=`modamax'+1',.)
+di
+local long=`modamax'*8+33
+di
+di "Best estimates by answer category" 
+di "{hline `long'}"
+di "Item" _col(29) "Cat 0"  _c
+forvalues j=1/`modamax' {
+     local col=29+`j'*8 
+	 di _col(`col') "Cat `j'"     _c
+}
+di
+di "{hline `long'}"
+forvalues i=1/`nbitems' {
+    di "``i''" _c
+	forvalues j=0/`modamax`i'' {
+	    di _col(`=28+`j'*8') %6.3f round(`bestest``i''_`j'', 0.001) _c
+		matrix `bestest'[`i',`=`j'+1']=`bestest``i''_`j''
+	}
+	di
+}
+di "{hline `long'}"
+		
+
+
+/*************************************************************************************************************
+EQUATING
+*************************************************************************************************************/
+if "`eqset1'"!="" {
+    if "`eqgenscore'"!="" {
+	   local tmp1 `=ustrlen("`eqgenscore'`eqset1name'")'
+	   local tmp2 `=ustrlen("`eqgenscore'`eqset2name'")'
+	   local mlength=max(`tmp1',`tmp2')
+	   if `mlength'>27 {
+			di as error "The number of characters containing in the strings eqgenscore+eqset1name or eqgenscore+eqset2name must be lesser than 27"
+			di as error "eqgenscore+eqset1name : `tmp1' characters"
+			di as error "eqgenscore+eqset2name : `tmp2' characters"
+			error 130
+			*exit
+		}
+	}
+	if "`eqset1name'"=="" {
+	   local eqset1name="Set 1"
+	}
+	if "`eqset2name'"=="" {
+	   local eqset2name="Set 2"
+	}
+	local eqset1name `=regexreplaceall("`eqset1name'"," ","_",.)'
+	local eqset2name `=regexreplaceall("`eqset2name'"," ","_",.)'
+	*di "set1:`eqset1name' set2:`eqset2name'"  
+
+    tokenize `eqset1'
+	local nbset1: word count `eqset1'
+	forvalues i=1/`nbset1' {
+	   local eq1_`i':word `i' of `eqset1'
+	}
+    tokenize `eqset2'
+	local nbset2: word count  `eqset2'
+	forvalues i=1/`nbset2' {
+	   local eq2_`i':word `i' of `eqset2'
+	}	
+
+
+
+	tempfile fileeq
+	qui save `fileeq',replace
+	forvalues t=1/2{
+		local scoremaxset`t'=0
+		forvalues i=1/`nbset`t'' {
+			local scoremaxset`t'=`scoremaxset`t''+`modamax`eq`t'_`i'''
+		}
+	}
+	drop _all
+	qui set obs `=(`scoremaxset1'+`scoremaxset2'+2)*3'
+	forvalues t=1/2 {
+		qui gen scoreset`t'=.
+		qui gen scoreset`t'm=.
+		qui gen scoreset`t'p=.	
+	}
+	forvalues i=0/`scoremaxset1' {
+	    qui replace scoreset1=`i' in `=`i'+1'
+	    qui replace scoreset1m=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset1p=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	forvalues i=`=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2' {
+	    qui replace scoreset2=`i'-`scoremaxset1'-2 in `i'
+	    qui replace scoreset2m=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset2p=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	local s=0
+	local eqset1b
+	foreach i in `eqset1' {
+		qui gen s1_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s1_`i'_`m'=0 in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'_`m'=1 if scoreset1>`s' in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'=s1_`i'+s1_`i'_`m'
+		   local ++s
+		}
+	    local eqset1b `eqset1b' s1_`i'
+	}
+	local s=0
+	local eqset2b
+	foreach i in `eqset2' {
+		qui gen s2_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s2_`i'_`m'=0 in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'_`m'=1 if scoreset2>`s' in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'=s2_`i'+s2_`i'_`m'
+		   local ++s
+		}
+		local eqset2b `eqset2b' s2_`i'
+	}
+	tokenize `varlist'
+	tempname diffset1 diffset2
+	forvalues t=1/2 {
+		qui matrix `diffset`t''=J(`nbset`t'',`modamax',.)
+		local n=1
+		local listset`t'
+		foreach j in `eqset`t'' {
+			forvalues i=1/`nbitems' {
+				if "`j'"=="``i''" {
+					local listset`t' `listset`t'' `i'
+					forvalues m=1/`modamax' {
+						qui matrix `diffset`t''[`n',`m']=`diffmat'[`i',`m']
+					}
+					local ++n						
+				}
+			}
+		}
+	}
+	local var=`covariates'[1,1]
+	qui gen lt=.
+	forvalues t=1/2 {
+		tempname matscorelt`t'
+		qui pcm `eqset`t'b', diff(`diffset`t'') var(`var') minsize(1)
+		qui matrix `matscorelt`t''=r(matscorelt)
+		forvalues i=0/`scoremaxset`t'' {
+			qui replace lt=`matscorelt`t''[`=`i'+1',2] if scoreset`t'==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]+1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'p==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]-1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'm==`i'
+		}
+		qui ipolate scoreset`t' lt, gen(score`t') epolate
+	}
+	qui ipolate scoreset1 lt, gen(score1bis) epolate
+
+
+	forvalues t=1/2 {
+		qui replace score`t'=scoreset`t'm if scoreset`t'm!=.
+		qui replace score`t'=scoreset`t'p if scoreset`t'p!=.
+		qui replace score1=score1bis if score1==.
+		qui replace score`t'=0 if score`t'<0
+		qui replace score`t'=`scoremaxset`t'' if score`t'>`scoremaxset`t''
+	}
+	local pciset1
+	local pciset2
+	*set trace on
+	local minimini=0
+	local maximaxi=0
+	forvalues t=1/2 {
+        qui gen adjscore`t'=(score`t'+`eqaddset`t'')*`eqmultset`t''
+	    qui gen adjscore`=3-`t''=(score`=3-`t''+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''
+		tempname matscore`t'
+		qui matrix `matscore`t''=J(`=`scoremaxset`t''+1',7,.)
+		*set trace on
+		forvalues s=0/`scoremaxset`t'' {
+		    qui matrix `matscore`t''[`=`s'+1',1]=`s'
+			qui su lt if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',2]=r(mean)
+			if `ceil'==0 {
+				local ceil=1
+			}
+			if "`eqwithic'"=="" {
+				local pciset`t'  `pciset`t'' scatteri `=-`ceil'/5*`t'' `r(mean)' (12) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , mlabsize(tiny) mcolor(black) mlabcolor(black)||
+			}
+			local mean=r(mean)
+			qui su lt if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',3]=r(mean)
+			local moins=r(mean)
+			if `moins'<`minimini' {
+				*di "local minimini=floor(`moins')"
+				local minimini=floor(`moins')
+			}
+			qui su lt if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',4]=r(mean)
+			local plus=r(mean)
+			if `plus'>`maximaxi' {
+				*di "local maximaxi=ceil(`plus')"
+				local maximaxi=ceil(`plus')
+			}
+
+			if "`eqwithic'"!="" {
+				local y=-`ceil'/5*((2.5*`t'-2)+2*(`s'/`scoremaxset`t''))
+				*local pciset`t'  `pciset`t'' scatteri `y' `mean' (12) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , mlabsize(tiny) mcolor(black) mlabcolor(black)|| pci `y' `moins' `y' `plus',pstyle(p1) color(black)||
+				local pciset`t'  `pciset`t'' scatteri `y' `mean'  , mlabsize(tiny) mcolor(black) mlabcolor(black)|| scatteri `y' `moins' (9) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , msize(0) mlabsize(tiny) mcolor(black) mlabcolor(black)|| pci `y' `moins' `y' `plus',pstyle(p1) color(black)||
+			}
+			qui su score`=3-`t'' if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',5]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',6]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',7]=r(mean)
+		}
+		matrix colnames `matscore`t'' =score`t' lt lt- lt+ score`=3-`t'' score`=3-`t''- score`=3-`t''+
+		di as text
+		di as text "{hline 78}"
+		di as text "EQUATING `eqset`t'name' TO `eqset`=3-`t''name'"
+		di as text "{hline 78}"
+		di "`eqset`t'name' : `eqset`t''"
+		di "`eqset`=3-`t''name' : `eqset`=3-`t'''"
+		local eqset`t'namea=abbrev("`eqset`t'name'",18)
+		local eqset`=3-`t''namea=abbrev("`eqset`=3-`t''name'",12)
+		di "{hline 78}"
+		di "Score"           _col(20) "<----- Latent trait ----->" _col(52) "<- Score `eqset`=3-`t''namea'" _col(77) "->"
+		di "`eqset`t'namea'" _col(20) "Estimated" _col(39) "[95%IC]" _col(52) "Estimated" _col(72) "[95%IC]"
+		di "{hline 78}"
+		forvalues s=0/`scoremaxset`t'' {
+		    local min=min(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+		    local max=max(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+			
+			di %4.0f `=(`matscore`t''[`=`s'+1',1]+`eqaddset`t'')*`eqmultset`t''' _col(24) %5.2f `matscore`t''[`=`s'+1',2] _col(33) "[" %5.2f `matscore`t''[`=`s'+1',3] ";" %5.2f `matscore`t''[`=`s'+1',4] "]" _col(56) %5.2f `=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''' _col(66) "[" %5.2f `min' ";" %5.2f `max' "]"			
+		}
+		di "{hline 78}"
+		if "`eqgraph'"!="" {
+		    *set trace on
+			if `eqmultset`=3-`t'''>0 {
+				local xlabel 	"`=`eqaddset`=3-`t'''*`eqmultset`=3-`t''''(`=ceil((`scoremaxset`=3-`t'''*`eqmultset`=3-`t''')/20)')`=(`scoremaxset`=3-`t'''+`eqaddset`=3-`t''')*`eqmultset`=3-`t''''"
+			}
+			else {
+				local xlabel 	"`=(`scoremaxset`=3-`t'''+`eqaddset`=3-`t''')*`eqmultset`=3-`t''''(`=ceil((-`scoremaxset`=3-`t'''*`eqmultset`=3-`t''')/20)')`=`eqaddset`=3-`t'''*`eqmultset`=3-`t''''"
+			}
+			if `eqmultset`t''>0 {
+				local ylabel 	"`=`eqaddset`t''*`eqmultset`t'''(`=ceil((`scoremaxset`t''*`eqmultset`t'')/20)')`=(`scoremaxset`t''+`eqaddset`t'')*`eqmultset`t'''"
+			}
+			else {
+				local ylabel 	"`=(`scoremaxset`t''+`eqaddset`t'')*`eqmultset`t'''(`=ceil((-`scoremaxset`t''*`eqmultset`t'')/20)')`=`eqaddset`t''*`eqmultset`t'''"
+			}
+			*set trace off
+			*di "xlabel : `xlabel'"
+			*di "subtitle=`subtitle'"
+			twoway (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''!=.,lcolor(black) lpattern(solid) lwidth(thick)) (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''m!=.,lcolor(black) lpattern(dash) lwidth(thin)) (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''p!=.,lcolor(black) lpattern(dash) lwidth(thin)), title("Equating score of `eqset`=3-`t''name' to `eqset`t'name' ") ytitle("Score `eqset`t'name'") xtitle("Score `eqset`=3-`t''name'") ylabel(`ylabel') xlabel(`xlabel') name(eq`t'to`=3-`t'') legend(order(1 2) label(1 "Estimated") label(2 "95%IC") position(6)) subtitle("`dimname'") 
+		}
+		qui drop adjscore`t' adjscore`=3-`t''
+	}
+	
+	if "`eqgraph'"!="" {
+		qui use "`equating'",clear
+	    qui su u
+	    local flooru=floor(`r(min)')
+	    local ceilu=ceil(`r(max)')
+		qui su eff
+	    local ceil=ceil(ceil(`r(max)'/10)*10)
+		if `ceil'==0 {
+		   local ceil=1
+		}
+
+		local title "Equating"
+		if "`eqset1name'"!=""&"`eqset2name'"!=""{
+		   local title "Equating between `eqset1name' and `eqset2name'"
+		}
+		if "`eqwithic'"=="" {
+		   local ylabel1=-`ceil'/5
+		   local ylabel2=-2*`ceil'/5
+		   local gapu=ceil((`ceilu'-`flooru')/15)
+		}
+		else {
+		    local ylabel1=-0.5*`ceil'/5
+		    local ylabel2=-3*`ceil'/5
+		   	local flooru=min(`flooru',`minimini')
+			local ceilu=max(`ceilu',`maximaxi')
+			local gapu=ceil((`ceilu'-`flooru')/15)
+		}
+	    *di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`flooru'(1)`ceilu') color(erose)) || `pciset1' `pciset2'  , yline(0, lcolor(black)) legend(off) name(equating,replace) ytitle(                           Frequencies)    ylabel(`=-`ceil'/5*2' `eqset1name' `=-`ceil'/5' `eqset2name' 0(`=`ceil'/5')`ceil', grid angle(0) axis(1)) title(Equating) xsize(12) ysize(9)  xtitle(Latent trait) "
+	    qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`flooru'(`gapu')`ceilu') color(erose)) || `pciset1' `pciset2'  , yline(0, lcolor(black)) legend(off) name(equating,replace) ytitle("                           Frequencies")    /*ylabel(`ylbl', grid angle(0) axis(1))*/ ylabel(`ylabel1' "`eqset1name'" `ylabel2' "`eqset2name'" 0(`=`ceil'/5')`ceil', grid angle(0) axis(1)) title("`title'") subtitle("`dimname'") xsize(12) ysize(9)  xtitle("Latent trait") 
+	}
+	qui use `fileeq',clear
+	*set trace on
+	tempname scoreset1 scoreset2
+	forvalues t=1/2 {
+		qui genscore `eqset`t'' if `touse',score(`scoreset`t'')
+	 	qui su `scoreset`t'' if `touse'
+		local maxscoreset=r(max)
+		*qui matrix list `matscore`t''
+		if "`eqgenscore'"!="" {
+			local eqgenscore `=regexreplaceall("`eqgenscore'"," ","_")'
+			*di "eqgenscore : `eqgenscore'"
+			foreach k in mean min max alea {
+				capture confirm  variable `eqgenscore'_`k'_`eqset`=3-`t''name'
+				if _rc==0&"`replace'"!="" {
+					qui replace `eqgenscore'_`k'_`eqset`=3-`t''name'=. if `touse'
+				}
+				else if _rc==0&"`replace'"!="" {
+					di as error "The variable `eqgenscore'_`k'_`eqset`=3-`t''name' already exists"
+					error 198
+				}
+				else {
+					qui gen `eqgenscore'_`k'_`eqset`=3-`t''name'=. if `touse'
+				}
+			}
+			*tab `scoreset`t''
+			forvalues s=0/`maxscoreset' {
+				*di "qui replace `eqgenscore'_`eqset`=3-`t''name'=`=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''' if `scoreset`t''==`s'"
+				local min=min(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+				local max=max(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+				qui replace `eqgenscore'_mean_`eqset`=3-`t''name'=round(`=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_min_`eqset`=3-`t''name'=round(`min',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_max_`eqset`=3-`t''name'=round(`max',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_alea_`eqset`=3-`t''name'=round(uniform()*(`max'-`min')+`min',1) if round(`scoreset`t'',1)==`s'&`touse'
+			}
+		}
+		return matrix score`t'_to_`=3-`t''=`matscore`t''
+	}
+	
+}
+
+
+/*************************************************************************************************************
+RETOUR AU FICHIER INITIAL ET SAUVEGARDE DES NOUVELLES VARIABLES
+*************************************************************************************************************/
+*set trace on
+if "`visit'"!="" {
+	tempfile sauv
+	*set trace on
+	*tempname corrlatent corrbilatent
+	qui keep `latent'* `selatent'* `id' `visit' 
+    qui reshape wide , i(`id') j(`visit')
+	qui sort `id'	
+	qui save `sauv', replace
+	restore,preserve
+	if "`replace'"!=""&("`genlt'"!=""|"`geninf'"!="") {
+    	capture drop `genlt' 
+    	capture drop `genlt'_se 
+    	capture drop `geninf' 
+    	capture drop `genlt'_corr
+    	capture drop `genlt'_opt
+    	capture drop `genlt'_opt_se
+    }
+	*su
+	tempname idorder
+	qui gen `idorder'=_n 
+	qui sort `id'
+	qui merge 1:1 `id' using `sauv'
+	
+	qui sort `idorder'
+    qui drop `idorder'	
+}
+else {
+*set trace on
+*set tracedepth 1
+    if "`genlt'"!="" {
+		qui gen `genlt'_corr=. if `touse'
+		forvalues s=0/`scoremax' {
+			qui replace `genlt'_corr=`estlt`s'' if `score'==`s'&`touse'
+		}
+		forvalues g=1/`nbgroups' {
+			qui replace `genlt'_corr=`clt`g'' if `group'==`g'&`genlt'_corr==.&`touse'
+		}
+		tempvar tmpitem mean nbnonmiss
+		forvalues i=1/`nbitems' {
+			qui gen `tmpitem'_`i'=. if `touse'
+			forvalues k=0/`modamax' {
+				qui replace `tmpitem'_`i'=`bestest'[`i',`=`k'+1'] if ``i''==`k'&`touse'
+			}
+		}
+		*su
+		qui egen `genlt'_opt=rowmean(`tmpitem'_*) if `touse'
+		qui egen `genlt'_opt_se=rowsd(`tmpitem'_*) if `touse'
+		qui egen `nbnonmiss'=rownonmiss(`tmpitem'_*) if `touse'
+		qui replace `genlt'_opt_se=sqrt((`genlt'_opt_se^2+`resvar')/`nbnonmiss') if `touse'
+ 	}
+	restore,not
+}
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin, footer(fall_report)
+	putdocx table hdr = (1, 3), border(all, nil) tofooter(fall_report)
+	if "`rsm'"=="" {
+		putdocx table hdr(1, 1) = ("Partial Credit Model")
+	}
+	else {
+		putdocx table hdr(1, 1) = ("Rating Scale Model")
+	}
+	putdocx table hdr(1, 2) = ("`dimname'"), halign(center)
+	putdocx table hdr(1, 3) = ("Page "), pagenumber
+	putdocx table hdr(1, 3) = ("/"), totalpages append
+	putdocx table hdr(1, 3), halign(right)
+	putdocx paragraph ,style(Title)
+	putdocx text ("General informations") ,
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("Names of the dimension: `dimname'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph, style(Title)
+	putdocx text ("Estimation of the parameters") , 
+	local paramname
+	forvalues j=1/`nbitems' {
+		forvalues k=1/`modamax' {
+		     if `k'<=`modamax`j'' {
+			     local paramname `paramname' "``j''_`k'"
+			 }
+	    }
+	}
+	*di "matrix colnames `diff'=`paramname'"
+	matrix rownames `diff'=`paramname'
+    putdocx table table1 = matrix(`diff') , nformat(%9.3f) rownames colnames  border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil) headerrow(1)  halign(center)
+    putdocx table table1(.,1), halign(left) 
+    putdocx table table1(.,2/7), halign(right) 
+    putdocx table table1(1,.), halign(right) border(top) border(bottom)
+	
+	
+	qui putdocx table table2 = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)  headerrow(1)
+    putdocx table table2(.,1), halign(left) 
+    putdocx table table2(.,2/7), halign(right) 
+    putdocx table table2(1,.), halign(right) border(top) border(bottom)
+
+
+
+	
+	putdocx paragraph,style(Title)
+	putdocx text ("Fit indexes for items") , /*bold underline font(,14) smallcaps*/
+	qui putdocx table table3 = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)    headerrow(1)
+    putdocx table table3(.,1), halign(left) 
+    putdocx table table3(.,2/5), halign(right) 
+    putdocx table table3(1,.), halign(right) border(top) border(bottom)
+
+
+
+	putdocx paragraph, style(Title)
+	putdocx text ("Estimation per group/score")
+	*putdocx text ("Estimation per group/score") , bold underline font(,14) smallcaps
+	*set trace on
+	putdocx table tbl = (`=`nbrowmat'+1',7), border(all,nil) width(7) halign(center) note(EAP: Expected A Posteriori ; BE: Best Estimates) headerrow(1)
+    putdocx table tbl(1,.), halign(right) border(top) border(bottom)
+	putdocx table tbl(1,1) = ("Group"), halign(right) 
+	putdocx table tbl(1,2) = ("score"), halign(right) 
+	putdocx table tbl(1,3) = ("Frequency"), halign(right) 
+	putdocx table tbl(1,4) = ("EAP Mean"), halign(right) 
+	putdocx table tbl(1,5) = ("EAP s.e."), halign(right) 
+	putdocx table tbl(1,6) = ("Exp score"), halign(right) 
+	putdocx table tbl(1,7) = ("BE Mean"), halign(right) 
+	local fin=1
+	forvalues row=1/`nbrowmat' {
+	    local row2=`row'+1
+		local g: di %9.0f `matgroupscorelt'[`row',1]
+		local gh=`matgroupscorelt'[`row',1]
+		if `fin'==1 {
+			putdocx table tbl(`row2',1) = ("`g'"), halign(right) 
+		}
+		if `matgroupscorelt'[`row',2]!=.|`matgroupscorelt'[`row',7]==. {
+		    local s: di %9.0f `matgroupscorelt'[`row',2]
+			local fin=0
+		}
+		else {
+			local s "`scoremin`gh''/`scoremax`gh''"
+			local fin=1
+			*local fin "border(top) border(bottom)"
+			*di "c'est la fin"
+			putdocx table tbl(`row2',.),  border(bottom) border(top, dashed)
+			putdocx table tbl(`row2',1), border(top, nil)
+		}
+		local eff: di %9.0f `matgroupscorelt'[`row',3]
+		local lt: di %9.3f `matgroupscorelt'[`row',4]
+		local se: di %9.3f `matgroupscorelt'[`row',5]
+		local exp: di %9.2f `matgroupscorelt'[`row',6]
+		local clt: di %9.3f `matgroupscorelt'[`row',7]
+		*putdocx table tbl(`row',.), addrows(7)
+		putdocx table tbl(`row2',2) = ("`s'"), halign(right) 
+		putdocx table tbl(`row2',3) = ("`eff'"), halign(right) 
+		putdocx table tbl(`row2',4) = ("`lt'"), halign(right) 
+		putdocx table tbl(`row2',5) = ("`se'"), halign(right) 
+		putdocx table tbl(`row2',6) = ("`exp'"), halign(right) 
+		putdocx table tbl(`row2',7) = ("`clt'"), halign(right) 
+
+	}
+
+/*
+		qui matrix `matgroupscorelt'[`row',1]=`g'
+		*qui matrix `matgroupscorelt'[`row',2]="`scoremin`g''/`scoremax`g''"
+		qui matrix `matgroupscorelt'[`row',3]=`eff`g''
+		qui matrix `matgroupscorelt'[`row',4]=`lt`g''
+		qui matrix `matgroupscorelt'[`row',5]=`se'
+		*qui matrix `matgroupscorelt'[`row',6]=`exp'
+		qui matrix `matgroupscorelt'[`row',7]=`clt`g''
+		local ++row
+	}
+	local nbrowmat=`row'-1
+
+
+local row 1
+local vari 1
+foreach x in gear_ratio turn foreign _cons {
+putdocx table tbl5(`row',.), addrows(2)
+local b: display %9.3f rtable[`vari',1]
+local se: display %9.3f rtable[`vari',2]
+local ++vari
+local ++row
+putdocx table tbl5(`row',1) = ("`x'"), halign(right)
+putdocx table tbl5(`row',2) = ("`b'"), halign(right)
+local ++row
+local se = strtrim("`se'")
+putdocx table tbl5(`row',2) = ("(`se')"), halign(right)
+}*/
+	
+	*qui putdocx table tablename = matrix(`matgroupscorelt') , nformat(%9.3f) /*rownames*/ colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+*set trace on
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+return matrix matscorelt=`matscorelt'
+return matrix matgroupscorelt=`matgroupscorelt'
+return matrix bestest=`bestest'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm 3.4.ado b/Modules/ado/personal/p/pcm 3.4.ado
new file mode 100644
index 0000000..f6b1bd3
--- /dev/null
+++ b/Modules/ado/personal/p/pcm 3.4.ado	
@@ -0,0 +1,986 @@
+*! Version 3.4 23August2019
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+*
+*
+*
+* Jean-benoit Hardouin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(name) GENINF(name) postpce]
+
+qui count
+local nbobs=r(N)
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+local modcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local modcont (`modcont'->T)
+}
+
+local modcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local modcat (`modcat'->T)
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' se`genlt' `geninf'
+	if _rc!=0 {
+	    di in red "The variables `genlt', se`genlt' and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+forvalues i=1/`nbitems' {
+     qui su ``i''
+	 if `r(min)'!=`modamin' {
+	     local modamin=r(min)
+		 local pbmin `pbmin' ``i''
+	 }
+	 if `r(max)'>`modamax' {
+	     local modamax=r(max)
+	 }
+	 local modamax``i''=r(max)
+	 if "`rsm'"=="" {
+	    local nbdiff=`nbdiff'+`modamax``i'''
+	 }
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count
+local nbind=r(N)
+*set trace on
+local code
+forvalues k=1/`modamax' {
+   local code`k'
+   forvalues i=1/`nbitems' {
+       if `k'<=`modamax``i''' {
+	      local code`k' `code`k'' `k'.``i''
+	   }
+   }
+   local code`k' (`code`k''<-T@`k')
+   local code `code' `code`k''
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	local t=1
+	local constraints
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax``i''' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				constraint `t' [`k'.``i'']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+}
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+
+if "`rsm'"!="" {
+   local t=1
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       constraint `t'   [`=`k'-1'.``i'']_cons-[`k'.``i'']_cons+[1.``i'']_cons=[`=`k'-1'.`1']_cons-[`k'.`1']_cons+[1.`1']_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')"
+local qui qui
+if "`model'"!="" {
+   local qui
+}
+`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent',latent se(`selatent')
+if "`genlt'"!="" {
+    gen `genlt'=`latent'
+	gen se`genlt'=`selatent'
+}
+set seed 123456
+qui gen `latent2'=`latent'+invnorm(uniform())*`selatent'
+qui genscore `varlist',score(`score')
+qui gengroup `latent',newvariable(`group') continuous
+qui levelsof `group'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+3',.)
+forvalues g=1/`nbgroups' {
+    matrix `groups'[`g',`=`nbitems'+3']=0
+    forvalues i=1/`nbitems' {
+	*tab ``i'' if `group'==`g'
+        qui count if ``i''!=.&`group'==`g'
+		local n=r(N)
+		if `n'>0 {
+			qui su ``i'' if `group'==`g'
+			matrix `groups'[`g',`i']=r(mean)
+			matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+		}
+		else {
+			matrix `groups'[`g',`i']=.
+			matrix `groups'[`g',`=`nbitems'+3']=.
+		}		
+    }
+	qui su `latent' if `group'==`g'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'==`g'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+}
+*matrix list `groups'
+	
+qui count if `score'!=.
+local nbobsssmd=r(N)	
+	
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i'':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i'':_cons]
+	qui lincom -_b[1.``i'':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+    *qui matrix `vardiff'[`t',`t']=_se[1.``i'':_cons]^2
+	local rn `rn' 1.``i''
+	local ++t
+	local sum _b[1.``i'':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax``i''' {
+			local sum "_b[`k'.``i'':_cons]-(`sum')"
+			di "``i'' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i'':_cons]-_b[`k'.``i'':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1':_cons]-_b[`k'.`1':_cons]+_b[1.`1':_cons]
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES ET LA VARIANCE
+*************************************************************************************************************/
+
+tempname covariates
+qui matrix `covariates'=J(`=`nbpar'+1',6,.)
+
+*set trace on
+if "`continuous'"!=""|"`categorical'"!="" {
+    qui lincom _b[/var(e.T)]
+}
+else {
+    qui lincom _b[/var(T)]
+}
+qui matrix `covariates'[1,1]=`r(estimate)'
+qui matrix `covariates'[1,2]=`r(se)'
+qui matrix `covariates'[1,3]=`r(z)'
+qui matrix `covariates'[1,4]=`r(p)'
+qui matrix `covariates'[1,5]=`r(lb)'
+qui matrix `covariates'[1,6]=`r(ub)'
+
+local t=2
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+* matrix list `covariates'
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 73}"
+	di  as text _col(60) "<--95% IC -->"
+	di  "Items" _col(60) "Lower" _col(68) "Upper"
+	di "parameters" _col(13) "category" _col(25) "Estimate" _col(37) "s.e." _col(48) "z" _col(56) "p" _col(59) " Bound" _col(68) "Bound"
+	di "{hline 73}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax``i''' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 73}"
+	local t=1
+	local n: word count  Variance `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of Variance `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		local ++t
+	}
+	di as text "{hline 73}"
+	di
+	qui su `latent'
+	qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])^2)
+	di as text "PSI:" as result %4.2f `PSI' 
+	di
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+
+tempname fit
+qui matrix `fit'=J(`nbitems',4,.)
+matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+matrix rownames `fit'=`varlist'
+*matrix list `fit'
+
+tempvar Tcum TInf cum
+qui gen `Tcum'=0
+qui gen `TInf'=0
+if "`postpce'"=="" {
+	di as text "{hline 90}"
+	di as text _col(60) "<---  Standardized   --->"
+	di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+	di as text "{hline 90}"
+	di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+	di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+	di as text "{hline 90}"
+}
+*set trace on
+local chi2=0
+local chi2_old=0
+forvalues g=1/`nbgroups' {
+   local chi2_g`g'=0
+   local chi2_old_g`g'=0
+}
+forvalues i=1/`nbitems' {
+	if "`rsm'"=="" {
+		local mm=`modamax``i'''
+	}
+	else {
+		local mm `modamax'
+	}	
+	tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+	tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+	local d=1
+	local d_old=1
+	qui gen `cum``i'''=0
+	qui gen `cum_old``i'''=0
+	forvalues k=1/`mm' {
+		local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+		local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
+	}
+	qui gen `c0_``i'''=1/(`d')
+	qui gen `c_old0_``i'''=1/(`d_old')
+	forvalues k=1/`mm' {
+		tempvar c`k'_``i'' c_old`k'_``i''
+		qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
+		qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
+		qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
+		qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
+	}
+	qui gen `Inf``i'''=0
+	qui gen `Inf_old``i'''=0
+	qui gen `C``i'''=0
+	forvalues k=0/`mm' {
+		qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
+		qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
+		qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
+	}
+	qui count if ``i''!=.
+	local n``i''=r(N)
+	
+	qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
+	qui su `C2``i'''
+	local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+	qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
+	qui su `C3``i'''
+	local n=r(sum)
+	qui su `Inf``i'''
+	local d=r(sum)
+	local q2i``i''=`n'/((`d')^2)
+	
+	//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+	
+	qui replace `Tcum'=`Tcum'+`cum``i'''
+	qui replace `TInf'=`TInf'+`Inf``i'''
+	qui gen `y``i'''=``i''-`cum``i'''
+	qui gen `y_old``i'''=``i''-`cum_old``i'''
+	qui gen `y2``i'''=(`y``i''')^2
+	qui gen `y2_old``i'''=(`y_old``i''')^2
+	qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
+	local chi2_``i''=0
+	local chi2_old_``i''=0
+	forvalues g=1/`nbgroups' {
+		qui su `y2``i''' if `group'==`g'
+		local n=r(sum)
+		qui su ``i'' if `group'==`g'
+		local n1=r(sum)
+		qui su `cum``i''' if `group'==`g'
+		local n2=r(sum)
+		qui su `Inf``i''' if `group'==`g'
+		local d=r(sum)
+		*di "chi2_`g'_``i''=`chi2'+(`n1'-`n2')^2/(`d')"
+		local chi2=`chi2'+(`n1'-`n2')^2/(`d')
+		local chi2_``i''=`chi2_``i'''+(`n1'-`n2')^2/(`d')
+		local chi2_g`g'=`chi2_g`g''+(`n1'-`n2')^2/(`d')
+		qui su `y2_old``i''' if `group'==`g'
+		local n_old=r(sum)
+		qui su ``i'' if `group'==`g'
+		local n1_old=r(sum)
+		qui su `cum_old``i''' if `group'==`g'
+		local n2_old=r(sum)
+		qui su `Inf_old``i''' if `group'==`g'
+		local d_old=r(sum)
+		local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+		local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+		local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+	}
+	*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+	*su `z``i'''
+	label variable `z``i''' "Standardized residuals associated to ``i''"
+	label variable `latent' "Latent trait"
+	*set trace on
+	if  "`graphs'"!=""&"`graphitems'"=="" {
+		if "`filesave'"!="" {
+			local fs saving("`dirsave'//residuals_``i''",replace)
+		}
+		qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+	}
+	*set trace off
+	qui gen `z2``i'''=(`z``i''')^2
+	qui su `z2``i'''
+	local OUTFIT``i''=`r(mean)'
+	qui matrix `fit'[`i',1]=`OUTFIT``i'''
+	local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+	qui matrix `fit'[`i',3]=`OUTFITs``i'''
+	qui su `Inf``i''' if ``i''!=.
+	local sumw``i''=r(sum)
+	qui gen `i``i'''=`Inf``i'''*`z2``i''' 
+	qui su `i``i''' if ``i''!=.
+	local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+	qui matrix `fit'[`i',2]=`INFIT``i'''
+	local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+	qui matrix `fit'[`i',4]=`INFITs``i'''
+	if "`postpce'"=="" {
+		di abbrev("``i''",19) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+	}
+}
+if "`postpce'"=="" {
+	di as text "{hline 90}"
+	di as text "*: As suggested by Wright (Smith, 1998)
+	di as text "**: As suggested by Bond and Fox (2007)
+}
+if "`geninf'"!="" {
+   gen `geninf'=`TInf'
+}
+
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Itération `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1')
+		`qui' pcm `varlist' [iweight=`sinf'],diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1')
+		qui su `ecart_`it''
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+
+if "`graphs'"!="" {
+
+	tempfile savefile
+	qui save `savefile'
+
+	qui clear
+	qui set obs 2000
+	qui gen u=(_n-1000)/250
+	qui gen Tcum=0
+	qui gen TInf=0
+	forvalues i=1/`nbitems' {
+	   local scatteri`i' 
+	   forvalues g=1/`nbgroups' {
+		  local x=`groups'[`g',`=`nbitems'+1']
+		  local y=`groups'[`g',`i']
+		  local s1=`groups'[`g',`=`nbitems'+2']
+		  local seuil=30
+		  local s vtiny
+		  *set trace on
+		  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+		      if `s1'>`seuil' {
+			     local s `lab'
+			  }
+			  local seuil=`seuil'+10
+		  }
+		  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+		*set trace off
+		}
+		local d=1
+		qui gen cum``i''=0
+		*set trace on
+		if "`rsm'"=="" {
+			local mm=`modamax``i'''
+		}
+		else {
+			local mm `modamax'
+		}	
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+		}
+		qui gen c0_``i''=1/(`d')
+		label variable c0_``i'' "Pr(``i''=0)"
+		forvalues k=1/`mm' {
+			qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+			qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+			label variable c`k'_``i'' "Pr(``i''=`k')"
+		}
+		qui gen Inf``i''=0
+		forvalues k=1/`mm' {
+			qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+		}
+		if "`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fsc saving("`dirsave'//CCC_``i''",replace)
+				local fsi saving("`dirsave'//ICC_``i''",replace)
+			}
+		    qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+		    qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+		}
+		qui replace Tcum=Tcum+cum``i''
+		qui replace TInf=TInf+Inf``i''	
+		label variable Inf``i'' "``i''"
+	}
+	if "`filesave'"!="" {
+		local fst saving("`dirsave'//TCC",replace)
+		local fsteo saving("`dirsave'//TCCeo",replace)
+		local fsi saving("`dirsave'//ICC",replace)
+		local fsti saving("`dirsave'//TIC",replace)
+		local fsm saving("`dirsave'//map",replace)
+	}
+	qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+	qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+	qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+
+	local scatteri
+	forvalues g=1/`nbgroups' {
+		local x=`groups'[`g',`=`nbitems'+1']
+		local y=`groups'[`g',`=`nbitems'+3']
+		  local s1=`groups'[`g',`=`nbitems'+2']
+		  local seuil=30
+		  local s vtiny
+		  *set trace on
+		  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+		      if `s1'>`seuil' {
+			     local s `lab'
+			  }
+			  local seuil=`seuil'+10
+		  }
+		local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+	}
+	qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+	
+	
+	
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+*set trace on
+	gen eff=0
+	local effmax=0
+	forvalues g=1/`nbgroups' {
+	    local eff=`groups'[`g',`=`nbitems'+2']
+		if `groups'[`g',`=`nbitems'+2']>`effmax' {
+		   local effmax=`groups'[`g',`=`nbitems'+2']
+		}
+	    local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
+	    *di "replace eff=`eff' if round(u,0.004)==`lat'"
+	    qui replace eff=`eff' if round(u,0.004)==`lat'
+    }
+	gen density=normalden(u)*sqrt(`covariates'[1,1])
+	label variable eff "Frequencies"
+	label variable u "Latent trait"
+	label variable TInf "Information curve"
+	label variable density "Density function of the latent trait"
+	local scatteri
+	qui su u if eff!=0
+	*set trace on
+	local floor=floor(`r(min)')
+	local ceil=ceil(`r(max)')
+	forvalues i=1/`nbitems' {
+	   local color`i':word `i' of `color'
+	   local y=-`i'*`effmax'/`nbitems'
+	   forvalues l=1/`modamax' {
+		   local x=`diffmat'[`i',`l']
+		   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+		   if `x'<`floor' {
+		      local floor=floor(`x')
+		   }
+		   if `x'>`ceil'&`x'!=. {
+		      local ceil=ceil(`x')
+		   }
+	   }
+	   local scatteri `scatteri' || scatteri `y' `floor' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+	}
+	qui su eff
+	local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+	qui su TInf
+	local maxi=ceil(`r(max)')
+	qui su density
+    local maxd=ceil(`r(max)')
+	qui drop if u<`floor'|u>`ceil'
+	qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(`floor'(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3))    `scatteri'  , name(map,replace) ytitle("Frequencies")  ylabel(-`maxi'(`=`maxi'/5')`maxi' ,axis(2)) ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait") xtitle("Latent trait") `fsm'
+
+
+	qui clear
+	qui use `savefile'
+
+}
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+
+di
+di as text "{hline 57}"
+di _col(31) "Latent Variable" _col(50) "Expected"
+di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score"
+di as text "{hline 57}"
+*set trace on
+forvalues g=1/`nbgroups' {
+    qui count if `group'==`g' 
+	local eff`g'=r(N)
+	qui count if `score'!=.&`group'==`g'
+	local n=r(N)
+	di as text "`g' (n=" as result `eff`g'' as text ")" _c
+	if `n'>0 {
+		qui su `score' if `group'==`g'
+		local scoremin`g'=`r(min)'
+		local scoremax`g'=`r(max)'
+		forvalues s=`scoremin`g''/`scoremax`g'' {
+			qui count if `group'==`g'&`score'==`s'
+			local eff=r(N)
+			qui su `latent' if `group'==`g'&`score'==`s'
+			local mean=r(mean)
+			qui su `selatent' if `group'==`g'&`score'==`s'
+			local se=r(mean)
+			qui su `Tcum' if `group'==`g'&`score'==`s'
+			local exp=r(mean)
+			if `eff'>0 {
+			   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+			}
+		}
+	}
+	qui count if `group'==`g'&`score'==.
+	local eff=r(N)
+	qui su `latent' if `group'==`g'&`score'==.
+	local mean=r(mean)
+	qui su `selatent' if `group'==`g'&`score'==.
+	local se=r(mean)
+	qui su `Tcum' if `group'==`g'&`score'==.
+	local exp=r(mean)
+	if `eff'>0 {
+		di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+	}
+    di as text "{hline 57}"
+}
+	
+
+
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin
+	putdocx paragraph
+	putdocx text ("General informations") , bold underline font(,14) smallcaps
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph
+	putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	qui putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx paragraph
+	putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
+	qui putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm 4.0.ado b/Modules/ado/personal/p/pcm 4.0.ado
new file mode 100644
index 0000000..67b6376
--- /dev/null
+++ b/Modules/ado/personal/p/pcm 4.0.ado	
@@ -0,0 +1,1196 @@
+*! Version 4 13September2019
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
+* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
+*
+*
+* Jean-benoit Hardouin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(name) GENINF(name) postpce visit(name) id(name)]
+
+
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+if "`visit'"!=""{
+	if "`id'"==""{
+		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
+		exit 198
+	}
+	qui tab `visit'
+	if r(r)>4{
+		di as error "You must use a discrete time variable with less than 5 time points"
+		error 198
+	}
+	local timemax=r(r)
+	qui levelsof `visit'
+	local levelsofv `r(levels)'
+	qui reshape wide `varlist', i(`id') j(`visit')
+}
+else {
+	local timemax=1
+}
+qui count
+local nbobs=r(N)
+
+local timelist
+forvalues t=1/`timemax'{
+	local timelist `timelist' T`t'
+}
+
+local modcont
+local premodcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local premodcont (`modcont'->T1)
+	local modcont (`modcont'->`timelist')
+}
+
+local modcat
+local premodcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local premodcat (`modcat'->T1)
+	local modcat (`modcat'->`timelist')
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' se`genlt' `geninf'
+	if _rc!=0 {
+	    di in red "The variables `genlt', se`genlt' and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+forvalues i=1/`nbitems' {
+	local modamax`i'=1
+	if `timemax'==1{
+		qui rename ``i'' ``i''1
+	}
+	local t=1
+	foreach l in `levelsofv' {
+		qui rename ``i''`l' ``i''`t'
+		local ++t
+	}
+	forvalues t=1/`timemax'{
+		 *qui replace ``i'`t''=``i'`t''-`min' 
+		 qui su ``i''`t'
+		 if `r(min)'!=`modamin' {
+			 local modamin=r(min)
+			 local pbmin `pbmin' ``i'`t''
+		 }
+		 if `r(max)'>`modamax' {
+			 local modamax=r(max)
+		 }
+		 if `r(max)'>`modamax`i'' {
+			local modamax`i'=r(max)
+		}
+	}
+	if "`rsm'"=="" {
+		local nbdiff=`nbdiff'+`modamax`i''
+	}
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count
+local nbind=r(N)
+*set trace on
+local code
+local precode
+forvalues k=1/`modamax' {
+   forvalues t=1/`timemax'{
+		local code`k'
+	   forvalues i=1/`nbitems' {
+		   if `k'<=`modamax`i'' {
+			  local code`k' `code`k'' `k'.``i''`t'
+		   }
+	   }
+	   local code`k' (`code`k''<-T`t'@`k')
+	   if `t'==1{
+			local precode `precode' `code`k''
+	   }
+	   local code `code' `code`k''
+	}
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+local t=1
+local constraints
+local codemean
+local codevar
+local codecov
+forvalues j=2/`timemax'{
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			constraint `t' [`k'.``i''`j']_cons=[`k'.``i''1]_cons
+			local constraints `constraints' `t'
+			local ++t
+			
+		}
+	}	
+	if "`continuous'"=="" &  "`categorical'"==""{
+		local codemean `codemean' T`j'@m`j'
+		local codevar `codevar' T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' T`l'*T`j'@cov`l'`j'
+		}
+	}
+	else{
+		local codevar `codevar' e.T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
+		}	
+	}
+}
+if `timemax'>1{
+	if "`continuous'"=="" &  "`categorical'"==""{	
+		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
+	}
+	else{
+		local codelg var(e.T1@v1 `codevar') cov(`codecov')
+	}
+}
+
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				constraint `t' [`k'.``i''1]_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+}
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+
+if "`rsm'"!="" {
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       constraint `t'   [`=`k'-1'.``i''1]_cons-[`k'.``i''1]_cons+[1.``i''1]_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
+local qui qui
+if "`model'"!="" {
+   local qui
+}
+if `timemax'==1{
+`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist')
+}
+else{
+*di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
+`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') constraint(`constraints') 
+matrix esti_B = e(b)
+`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
+}
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2 miss
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent'*,latent se(`selatent'*)
+
+if "`genlt'"!="" {
+	tokenize `genlt'
+	forvalues i=1/`timemax'{
+		gen ``i''=`latent'`i'
+		gen se``i''=`selatent'`i'
+	}
+	tokenize `varlist'
+}
+
+set seed 123456
+forvalues t=1/`timemax'{
+	qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t'
+	local listit 
+	forvalues i=1/`nbitems' {
+		local listit `listit' ``i''`t'
+	}
+	qui genscore `listit',score(`score'`t')
+	qui gengroup `latent'`t',newvariable(`group'`t') continuous
+}
+
+/*time 1 only*/
+qui levelsof `group'1
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+3',.)
+forvalues g=1/`nbgroups' {
+    matrix `groups'[`g',`=`nbitems'+3']=0
+    forvalues i=1/`nbitems' {
+	*tab ``i'' if `group'1==`g'
+        qui count if ``i''1!=.&`group'1==`g'
+		local n=r(N)
+		if `n'>0 {
+			qui su ``i''1 if `group'1==`g'
+			matrix `groups'[`g',`i']=r(mean)
+			matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+		}
+		else {
+			matrix `groups'[`g',`i']=.
+			matrix `groups'[`g',`=`nbitems'+3']=.
+		}		
+    }
+	qui su `latent'1 if `group'1==`g'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'1==`g'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+}
+*matrix list `groups'
+
+/*number of non-missing on all time points*/
+egen `miss'=rowmiss(`score'*)
+qui count if `miss'==0
+local nbobsssmd=r(N)
+drop `miss'	
+
+	
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i''1:_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i''1:_cons]
+	qui lincom -_b[1.``i''1:_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+    *qui matrix `vardiff'[`t',`t']=_se[1.``i''1:_cons]^2
+	local rn `rn' 1.``i''1
+	local ++t
+	local sum _b[1.``i''1:_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax`i'' {
+			local sum "_b[`k'.``i''1:_cons]-(`sum')"
+			di "``i''1 `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i''1:_cons]-_b[`k'.``i''1:_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''1
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1':_cons]-_b[`k'.`1':_cons]+_b[1.`1':_cons] *``i'' instead of `i'?
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
+*************************************************************************************************************/
+tempname covariates
+local nbcov=0
+forvalues j=2/`timemax'{
+	local nbcov=`nbcov'+`j'-1
+}
+qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)
+
+*set trace on
+local t=1
+
+
+forvalues j=1/`=`timemax'-1'{
+	forvalues k=`=`j'+1'/`timemax'{
+		if "`categorical'"=="" & "`continuous'"=="" {
+			if `j'==1{
+				qui lincom [/]mean(T`k')
+			}
+			else{
+				qui lincom [/]mean(T`k')-[/]mean(T`j')
+			}
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+		else{
+			if "`categorical'"!=""{
+				local first=0 
+				foreach l in `levelsof`cat1'' {
+					if `first'==0 {
+						local ++first
+					}
+					else{
+						if `first'==1 {
+							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
+							qui matrix `covariates'[`t',1]=`r(estimate)'
+							qui matrix `covariates'[`t',2]=`r(se)'
+							qui matrix `covariates'[`t',3]=`r(z)'
+							qui matrix `covariates'[`t',4]=`r(p)'
+							qui matrix `covariates'[`t',5]=`r(lb)'
+							qui matrix `covariates'[`t',6]=`r(ub)'
+							local ++t
+							local ++first
+						}
+					}
+				}
+			}
+			else{
+				qui lincom [T`k']`cont1'-[T`j']`cont1'
+				qui matrix `covariates'[`t',1]=`r(estimate)'
+				qui matrix `covariates'[`t',2]=`r(se)'
+				qui matrix `covariates'[`t',3]=`r(z)'
+				qui matrix `covariates'[`t',4]=`r(p)'
+				qui matrix `covariates'[`t',5]=`r(lb)'
+				qui matrix `covariates'[`t',6]=`r(ub)'
+				local ++t
+			}		
+		}
+	}
+}	
+		
+forvalues j=1/`timemax'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		qui lincom _b[/var(e.T`j')]
+	}
+	else {
+		qui lincom _b[/var(T`j')]
+	}
+	qui matrix `covariates'[`t',1]=`r(estimate)'
+	qui matrix `covariates'[`t',2]=`r(se)'
+	qui matrix `covariates'[`t',3]=`r(z)'
+	qui matrix `covariates'[`t',4]=`r(p)'
+	qui matrix `covariates'[`t',5]=`r(lb)'
+	qui matrix `covariates'[`t',6]=`r(ub)'
+	local ++t
+}
+forvalues j=1/`=`timemax'-1'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(e.T`j',e.T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+	else{
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(T`j',T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+}
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+*matrix list `covariates'
+
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 73}"
+	di  as text _col(60) "<--95% IC -->"
+	di  "Items" _col(60) "Lower" _col(68) "Upper"
+	di "parameters" _col(13) "category" _col(25) "Estimate" _col(37) "s.e." _col(48) "z" _col(56) "p" _col(59) " Bound" _col(68) "Bound"
+	di "{hline 73}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax`i'' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 73}"
+	local t=1
+	local listmoy
+	local listvar
+	local listcov
+	forvalues j=1/`timemax'{
+		local listvar `listvar' Variance_T`j'
+		forvalues k=`=`j'+1'/`timemax'{
+			local listcov `listcov' Cov_T`j'_T`k'
+		}
+		forvalues k=`=`j'+1'/`timemax'{
+			local listmoy `listmoy' Mean_diff_T`j'_T`k'
+		}
+	}
+	local n: word count `listmoy' `listvar' `listcov' `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of `listmoy' `listvar' `listcov' `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		local ++t
+	}
+	di as text "{hline 73}"
+	if "`visit'"==""{
+		di
+		qui su `latent'
+		qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])^2)
+		di as text "PSI:" as result %4.2f `PSI' 
+		di
+	}
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+if "`visit'"==""{
+	tempname fit
+	qui matrix `fit'=J(`nbitems',4,.)
+	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+	matrix rownames `fit'=`varlist'
+	*matrix list `fit'
+
+	tempvar Tcum TInf cum
+	qui gen `Tcum'=0
+	qui gen `TInf'=0
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text _col(60) "<---  Standardized   --->"
+		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+		di as text "{hline 90}"
+		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "{hline 90}"
+	}
+	*set trace on
+	local chi2=0
+	local chi2_old=0
+	forvalues g=1/`nbgroups' {
+	   local chi2_g`g'=0
+	   local chi2_old_g`g'=0
+	}
+	forvalues i=1/`nbitems' {
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+		local d=1
+		local d_old=1
+		qui gen `cum``i'''=0
+		qui gen `cum_old``i'''=0
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+			local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
+		}
+		qui gen `c0_``i'''=1/(`d')
+		qui gen `c_old0_``i'''=1/(`d_old')
+		forvalues k=1/`mm' {
+			tempvar c`k'_``i'' c_old`k'_``i''
+			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
+			qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
+			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
+			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
+		}
+		qui gen `Inf``i'''=0
+		qui gen `Inf_old``i'''=0
+		qui gen `C``i'''=0
+		forvalues k=0/`mm' {
+			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
+			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
+			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
+		}
+		qui count if ``i''!=.
+		local n``i''=r(N)
+		
+		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
+		qui su `C2``i'''
+		local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
+		qui su `C3``i'''
+		local n=r(sum)
+		qui su `Inf``i'''
+		local d=r(sum)
+		local q2i``i''=`n'/((`d')^2)
+		
+		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+		
+		qui replace `Tcum'=`Tcum'+`cum``i'''
+		qui replace `TInf'=`TInf'+`Inf``i'''
+		qui gen `y``i'''=``i''-`cum``i'''
+		qui gen `y_old``i'''=``i''-`cum_old``i'''
+		qui gen `y2``i'''=(`y``i''')^2
+		qui gen `y2_old``i'''=(`y_old``i''')^2
+		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
+		local chi2_``i''=0
+		local chi2_old_``i''=0
+		forvalues g=1/`nbgroups' {
+			qui su `y2``i''' if `group'==`g'
+			local n=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1=r(sum)
+			qui su `cum``i''' if `group'==`g'
+			local n2=r(sum)
+			qui su `Inf``i''' if `group'==`g'
+			local d=r(sum)
+			*di "chi2_`g'_``i''=`chi2'+(`n1'-`n2')^2/(`d')"
+			local chi2=`chi2'+(`n1'-`n2')^2/(`d')
+			local chi2_``i''=`chi2_``i'''+(`n1'-`n2')^2/(`d')
+			local chi2_g`g'=`chi2_g`g''+(`n1'-`n2')^2/(`d')
+			qui su `y2_old``i''' if `group'==`g'
+			local n_old=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1_old=r(sum)
+			qui su `cum_old``i''' if `group'==`g'
+			local n2_old=r(sum)
+			qui su `Inf_old``i''' if `group'==`g'
+			local d_old=r(sum)
+			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+		}
+		*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+		*su `z``i'''
+		label variable `z``i''' "Standardized residuals associated to ``i''"
+		label variable `latent' "Latent trait"
+		*set trace on
+		if  "`graphs'"!=""&"`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fs saving("`dirsave'//residuals_``i''",replace)
+			}
+			qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+		}
+		*set trace off
+		qui gen `z2``i'''=(`z``i''')^2
+		qui su `z2``i'''
+		local OUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',1]=`OUTFIT``i'''
+		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `Inf``i''' if ``i''!=.
+		local sumw``i''=r(sum)
+		qui gen `i``i'''=`Inf``i'''*`z2``i''' 
+		qui su `i``i''' if ``i''!=.
+		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+		qui matrix `fit'[`i',2]=`INFIT``i'''
+		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		qui matrix `fit'[`i',4]=`INFITs``i'''
+		if "`postpce'"=="" {
+			di abbrev("``i''",19) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+		}
+	}
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text "*: As suggested by Wright (Smith, 1998)
+		di as text "**: As suggested by Bond and Fox (2007)
+	}
+	if "`geninf'"!="" {
+	   gen `geninf'=`TInf'
+	}
+}
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Itération `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1')
+		`qui' pcm `varlist' [iweight=`sinf'],diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1')
+		qui su `ecart_`it''
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+if "`visit'"==""{
+	if "`graphs'"!="" {
+
+		tempfile savefile
+		qui save `savefile'
+
+		qui clear
+		qui set obs 2000
+		qui gen u=(_n-1000)/250
+		qui gen Tcum=0
+		qui gen TInf=0
+		forvalues i=1/`nbitems' {
+		   local scatteri`i' 
+		   forvalues g=1/`nbgroups' {
+			  local x=`groups'[`g',`=`nbitems'+1']
+			  local y=`groups'[`g',`i']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			*set trace off
+			}
+			local d=1
+			qui gen cum``i''=0
+			*set trace on
+			if "`rsm'"=="" {
+				local mm=`modamax`i''
+			}
+			else {
+				local mm `modamax'
+			}	
+			forvalues k=1/`mm' {
+				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+			}
+			qui gen c0_``i''=1/(`d')
+			label variable c0_``i'' "Pr(``i''=0)"
+			forvalues k=1/`mm' {
+				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+				label variable c`k'_``i'' "Pr(``i''=`k')"
+			}
+			qui gen Inf``i''=0
+			forvalues k=1/`mm' {
+				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+			}
+			if "`graphitems'"=="" {
+				if "`filesave'"!="" {
+					local fsc saving("`dirsave'//CCC_``i''",replace)
+					local fsi saving("`dirsave'//ICC_``i''",replace)
+				}
+				qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+				qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+			}
+			qui replace Tcum=Tcum+cum``i''
+			qui replace TInf=TInf+Inf``i''	
+			label variable Inf``i'' "``i''"
+		}
+		if "`filesave'"!="" {
+			local fst saving("`dirsave'//TCC",replace)
+			local fsteo saving("`dirsave'//TCCeo",replace)
+			local fsi saving("`dirsave'//ICC",replace)
+			local fsti saving("`dirsave'//TIC",replace)
+			local fsm saving("`dirsave'//map",replace)
+		}
+		qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+		qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+		qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+
+		local scatteri
+		forvalues g=1/`nbgroups' {
+			local x=`groups'[`g',`=`nbitems'+1']
+			local y=`groups'[`g',`=`nbitems'+3']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+		}
+		qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+	
+	
+	
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+	*set trace on
+		gen eff=0
+		local effmax=0
+		forvalues g=1/`nbgroups' {
+			local eff=`groups'[`g',`=`nbitems'+2']
+			if `groups'[`g',`=`nbitems'+2']>`effmax' {
+			   local effmax=`groups'[`g',`=`nbitems'+2']
+			}
+			local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
+			*di "replace eff=`eff' if round(u,0.004)==`lat'"
+			qui replace eff=`eff' if round(u,0.004)==`lat'
+		}
+		gen density=normalden(u)*sqrt(`covariates'[1,1])
+		label variable eff "Frequencies"
+		label variable u "Latent trait"
+		label variable TInf "Information curve"
+		label variable density "Density function of the latent trait"
+		local scatteri
+		qui su u if eff!=0
+		*set trace on
+		local floor=floor(`r(min)')
+		local ceil=ceil(`r(max)')
+		forvalues i=1/`nbitems' {
+		   local color`i':word `i' of `color'
+		   local y=-`i'*`effmax'/`nbitems'
+		   forvalues l=1/`modamax' {
+			   local x=`diffmat'[`i',`l']
+			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+			   if `x'<`floor' {
+				  local floor=floor(`x')
+			   }
+			   if `x'>`ceil'&`x'!=. {
+				  local ceil=ceil(`x')
+			   }
+		   }
+		   local scatteri `scatteri' || scatteri `y' `floor' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+		}
+		qui su eff
+		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+		qui su TInf
+		local maxi=ceil(`r(max)')
+		qui su density
+		local maxd=ceil(`r(max)')
+		qui drop if u<`floor'|u>`ceil'
+		qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(`floor'(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3))    `scatteri'  , name(map,replace) ytitle("Frequencies")  ylabel(-`maxi'(`=`maxi'/5')`maxi' ,axis(2)) ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait") xtitle("Latent trait") `fsm'
+
+
+		qui clear
+		qui use `savefile'
+
+	}
+}
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+if "`visit'"==""{
+	di
+	di as text "{hline 57}"
+	di _col(31) "Latent Variable" _col(50) "Expected"
+	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score"
+	di as text "{hline 57}"
+	*set trace on
+	forvalues g=1/`nbgroups' {
+		qui count if `group'1==`g' 
+		local eff`g'=r(N)
+		qui count if `score'1!=.&`group'1==`g'
+		local n=r(N)
+		di as text "`g' (n=" as result `eff`g'' as text ")" _c
+		if `n'>0 {
+			qui su `score'1 if `group'1==`g'
+			local scoremin`g'=`r(min)'
+			local scoremax`g'=`r(max)'
+			forvalues s=`scoremin`g''/`scoremax`g'' {
+				qui count if `group'1==`g'&`score'1==`s'
+				local eff=r(N)
+				qui su `latent' if `group'1==`g'&`score'1==`s'
+				local mean=r(mean)
+				qui su `selatent' if `group'1==`g'&`score'1==`s'
+				local se=r(mean)
+				qui su `Tcum' if `group'1==`g'&`score'1==`s'
+				local exp=r(mean)
+				if `eff'>0 {
+				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+				}
+			}
+		}
+		qui count if `group'1==`g'&`score'1==.
+		local eff=r(N)
+		qui su `latent' if `group'1==`g'&`score'1==.
+		local mean=r(mean)
+		qui su `selatent' if `group'1==`g'&`score'1==.
+		local se=r(mean)
+		qui su `Tcum' if `group'1==`g'&`score'1==.
+		local exp=r(mean)
+		if `eff'>0 {
+			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+		}
+		di as text "{hline 57}"
+	}
+}	
+
+
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin
+	putdocx paragraph
+	putdocx text ("General informations") , bold underline font(,14) smallcaps
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph
+	putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	qui putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx paragraph
+	putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
+	qui putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm 4.1.ado b/Modules/ado/personal/p/pcm 4.1.ado
new file mode 100644
index 0000000..fd5c7e5
--- /dev/null
+++ b/Modules/ado/personal/p/pcm 4.1.ado	
@@ -0,0 +1,1208 @@
+*! Version 4.1 15September2019
+*! Jean-Benoit Hardouin, Myriam Blanchin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
+* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
+* Version 4.1: September 15th, 2019 [Jean-Benoit Hardouin]: correction of a small bug in the outputs
+*
+*
+* Jean-benoit Hardouin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(name) GENINF(name) postpce visit(name) id(name)]
+
+
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+if "`visit'"!=""{
+	if "`id'"==""{
+		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
+		exit 198
+	}
+	qui tab `visit'
+	if r(r)>4{
+		di as error "You must use a discrete time variable with less than 5 time points"
+		error 198
+	}
+	local timemax=r(r)
+	qui levelsof `visit'
+	local levelsofv `r(levels)'
+	qui reshape wide `varlist', i(`id') j(`visit')
+}
+else {
+	local timemax=1
+}
+qui count
+local nbobs=r(N)
+
+local timelist
+forvalues t=1/`timemax'{
+	local timelist `timelist' T`t'
+}
+
+local modcont
+local premodcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local premodcont (`modcont'->T1)
+	local modcont (`modcont'->`timelist')
+}
+
+local modcat
+local premodcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local premodcat (`modcat'->T1)
+	local modcat (`modcat'->`timelist')
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' se`genlt' `geninf'
+	if _rc!=0 {
+	    di in red "The variables `genlt', se`genlt' and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+forvalues i=1/`nbitems' {
+	local modamax`i'=1
+	if `timemax'==1{
+		qui rename ``i'' ``i''1
+	}
+	local t=1
+	foreach l in `levelsofv' {
+		qui rename ``i''`l' ``i''`t'
+		local ++t
+	}
+	forvalues t=1/`timemax'{
+		 *qui replace ``i'`t''=``i'`t''-`min' 
+		 qui su ``i''`t'
+		 if `r(min)'!=`modamin' {
+			 local modamin=r(min)
+			 local pbmin `pbmin' ``i'`t''
+		 }
+		 if `r(max)'>`modamax' {
+			 local modamax=r(max)
+		 }
+		 if `r(max)'>`modamax`i'' {
+			local modamax`i'=r(max)
+		}
+	}
+	if "`rsm'"=="" {
+		local nbdiff=`nbdiff'+`modamax`i''
+	}
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count
+local nbind=r(N)
+*set trace on
+local code
+local precode
+forvalues k=1/`modamax' {
+   forvalues t=1/`timemax'{
+		local code`k'
+	   forvalues i=1/`nbitems' {
+		   if `k'<=`modamax`i'' {
+			  local code`k' `code`k'' `k'.``i''`t'
+		   }
+	   }
+	   local code`k' (`code`k''<-T`t'@`k')
+	   if `t'==1{
+			local precode `precode' `code`k''
+	   }
+	   local code `code' `code`k''
+	}
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+local t=1
+local constraints
+local codemean
+local codevar
+local codecov
+forvalues j=2/`timemax'{
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			qui constraint `t' [`k'.``i''`j']_cons=[`k'.``i''1]_cons
+			local constraints `constraints' `t'
+			local ++t
+			
+		}
+	}	
+	if "`continuous'"=="" &  "`categorical'"==""{
+		local codemean `codemean' T`j'@m`j'
+		local codevar `codevar' T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' T`l'*T`j'@cov`l'`j'
+		}
+	}
+	else{
+		local codevar `codevar' e.T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
+		}	
+	}
+}
+if `timemax'>1{
+	if "`continuous'"=="" &  "`categorical'"==""{	
+		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
+	}
+	else{
+		local codelg var(e.T1@v1 `codevar') cov(`codecov')
+	}
+}
+
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				qui constraint `t' [`k'.``i''1]_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+}
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+if "`rsm'"!="" {
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       qui constraint `t'   [`=`k'-1'.``i''1]_cons-[`k'.``i''1]_cons+[1.``i''1]_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
+local qui qui
+if "`model'"!="" {
+   local qui
+}
+if `timemax'==1{
+   `qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist')
+}
+else{
+    *di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
+    `qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') constraint(`constraints') 
+     matrix esti_B = e(b)
+    `qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
+}
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2 miss
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent'*,latent se(`selatent'*)
+
+if "`genlt'"!="" {
+	tokenize `genlt'
+	forvalues i=1/`timemax'{
+		gen ``i''=`latent'`i'
+		gen se``i''=`selatent'`i'
+	}
+	tokenize `varlist'
+}
+
+set seed 123456
+forvalues t=1/`timemax'{
+	qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t'
+	local listit 
+	forvalues i=1/`nbitems' {
+		local listit `listit' ``i''`t'
+	}
+	qui genscore `listit',score(`score'`t')
+	qui gengroup `latent'`t',newvariable(`group'`t') continuous
+}
+
+/*time 1 only*/
+qui levelsof `group'1
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+3',.)
+forvalues g=1/`nbgroups' {
+    matrix `groups'[`g',`=`nbitems'+3']=0
+    forvalues i=1/`nbitems' {
+	*tab ``i'' if `group'1==`g'
+        qui count if ``i''1!=.&`group'1==`g'
+		local n=r(N)
+		if `n'>0 {
+			qui su ``i''1 if `group'1==`g'
+			matrix `groups'[`g',`i']=r(mean)
+			matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+		}
+		else {
+			matrix `groups'[`g',`i']=.
+			matrix `groups'[`g',`=`nbitems'+3']=.
+		}		
+    }
+	qui su `latent'1 if `group'1==`g'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'1==`g'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+}
+*matrix list `groups'
+
+/*number of non-missing on all time points*/
+egen `miss'=rowmiss(`score'*)
+qui count if `miss'==0
+local nbobsssmd=r(N)
+drop `miss'	
+
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i''1:_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i''1:_cons]
+	qui lincom -_b[1.``i''1:_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+    *qui matrix `vardiff'[`t',`t']=_se[1.``i''1:_cons]^2
+	local rn `rn' 1.``i''1
+	local ++t
+	local sum _b[1.``i''1:_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax`i'' {
+			local sum "_b[`k'.``i''1:_cons]-(`sum')"
+			*di "``i''1 `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i''1:_cons]-_b[`k'.``i''1:_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''1
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1'1:_cons]-_b[`k'.`1'1:_cons]+_b[1.`1'1:_cons] /*``i'' instead of `i'?*/
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
+*************************************************************************************************************/
+tempname covariates
+local nbcov=0
+forvalues j=2/`timemax'{
+	local nbcov=`nbcov'+`j'-1
+}
+qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)
+
+*set trace on
+local t=1
+
+
+forvalues j=1/`=`timemax'-1'{
+	forvalues k=`=`j'+1'/`timemax'{
+		if "`categorical'"=="" & "`continuous'"=="" {
+			if `j'==1{
+				qui lincom [/]mean(T`k')
+			}
+			else{
+				qui lincom [/]mean(T`k')-[/]mean(T`j')
+			}
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+		else{
+			if "`categorical'"!=""{
+				local first=0 
+				foreach l in `levelsof`cat1'' {
+					if `first'==0 {
+						local ++first
+					}
+					else{
+						if `first'==1 {
+							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
+							qui matrix `covariates'[`t',1]=`r(estimate)'
+							qui matrix `covariates'[`t',2]=`r(se)'
+							qui matrix `covariates'[`t',3]=`r(z)'
+							qui matrix `covariates'[`t',4]=`r(p)'
+							qui matrix `covariates'[`t',5]=`r(lb)'
+							qui matrix `covariates'[`t',6]=`r(ub)'
+							local ++t
+							local ++first
+						}
+					}
+				}
+			}
+			else{
+				qui lincom [T`k']`cont1'-[T`j']`cont1'
+				qui matrix `covariates'[`t',1]=`r(estimate)'
+				qui matrix `covariates'[`t',2]=`r(se)'
+				qui matrix `covariates'[`t',3]=`r(z)'
+				qui matrix `covariates'[`t',4]=`r(p)'
+				qui matrix `covariates'[`t',5]=`r(lb)'
+				qui matrix `covariates'[`t',6]=`r(ub)'
+				local ++t
+			}		
+		}
+	}
+}	
+		
+forvalues j=1/`timemax'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		qui lincom _b[/var(e.T`j')]
+	}
+	else {
+		qui lincom _b[/var(T`j')]
+	}
+	qui matrix `covariates'[`t',1]=`r(estimate)'
+	qui matrix `covariates'[`t',2]=`r(se)'
+	qui matrix `covariates'[`t',3]=`r(z)'
+	qui matrix `covariates'[`t',4]=`r(p)'
+	qui matrix `covariates'[`t',5]=`r(lb)'
+	qui matrix `covariates'[`t',6]=`r(ub)'
+	local ++t
+}
+forvalues j=1/`=`timemax'-1'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(e.T`j',e.T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+	else{
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(T`j',T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+}
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+*matrix list `covariates'
+
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 73}"
+	di  as text _col(60) "<--95% IC -->"
+	di  "Items" _col(60) "Lower" _col(68) "Upper"
+	di "parameters" _col(13) "category" _col(25) "Estimate" _col(37) "s.e." _col(48) "z" _col(56) "p" _col(59) " Bound" _col(68) "Bound"
+	di "{hline 73}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax`i'' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 73}"
+	local t=1
+	local listmoy
+	local listvar
+	local listcov
+	forvalues j=1/`timemax'{
+		local listvar `listvar' Variance_T`j'
+		forvalues k=`=`j'+1'/`timemax'{
+			local listcov `listcov' Cov_T`j'_T`k'
+		}
+		forvalues k=`=`j'+1'/`timemax'{
+			local listmoy `listmoy' Mean_diff_T`j'_T`k'
+		}
+	}
+	local n: word count `listmoy' `listvar' `listcov' `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of `listmoy' `listvar' `listcov' `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		*local ++t
+	}
+	di as text "{hline 73}"
+	if "`visit'"==""{
+		di
+		qui su `latent'
+		*qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])+(`r(sd)')^2)
+		*di as text "Variance of the estimated latent variable: " as result %4.2f `=(`r(sd)')^2'
+        tempvar se2latent
+		qui gen `se2latent'=(`selatent')^2
+		qui su `se2latent'
+		di as text "Mean squared std error of the latent variable: " as result %4.2f `=(`r(mean)')'
+		di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`r(mean)'))'
+		local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`r(mean)'))
+		di as text "PSI: " as result %4.2f `PSI' _c
+		if "`continuous'"!=""|"`categorical'"!="" {
+		    di as text " (without adjustment on covariates)"
+	    }
+		else {
+		    di
+		}
+		di
+	}
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+if "`visit'"==""{
+	tempname fit
+	qui matrix `fit'=J(`nbitems',4,.)
+	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+	matrix rownames `fit'=`varlist'
+	*matrix list `fit'
+
+	tempvar Tcum TInf cum
+	qui gen `Tcum'=0
+	qui gen `TInf'=0
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text _col(60) "<---  Standardized   --->"
+		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+		di as text "{hline 90}"
+		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "{hline 90}"
+	}
+	*set trace on
+	local chi2=0
+	local chi2_old=0
+	forvalues g=1/`nbgroups' {
+	   local chi2_g`g'=0
+	   local chi2_old_g`g'=0
+	}
+	forvalues i=1/`nbitems' {
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+		local d=1
+		local d_old=1
+		qui gen `cum``i'''=0
+		qui gen `cum_old``i'''=0
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+			local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
+		}
+		qui gen `c0_``i'''=1/(`d')
+		qui gen `c_old0_``i'''=1/(`d_old')
+		forvalues k=1/`mm' {
+			tempvar c`k'_``i'' c_old`k'_``i''
+			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
+			qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
+			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
+			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
+		}
+		qui gen `Inf``i'''=0
+		qui gen `Inf_old``i'''=0
+		qui gen `C``i'''=0
+		forvalues k=0/`mm' {
+			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
+			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
+			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
+		}
+		qui count if ``i''!=.
+		local n``i''=r(N)
+		
+		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
+		qui su `C2``i'''
+		local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
+		qui su `C3``i'''
+		local n=r(sum)
+		qui su `Inf``i'''
+		local d=r(sum)
+		local q2i``i''=`n'/((`d')^2)
+		
+		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+		
+		qui replace `Tcum'=`Tcum'+`cum``i'''
+		qui replace `TInf'=`TInf'+`Inf``i'''
+		qui gen `y``i'''=``i''-`cum``i'''
+		qui gen `y_old``i'''=``i''-`cum_old``i'''
+		qui gen `y2``i'''=(`y``i''')^2
+		qui gen `y2_old``i'''=(`y_old``i''')^2
+		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
+		local chi2_``i''=0
+		local chi2_old_``i''=0
+		forvalues g=1/`nbgroups' {
+			qui su `y2``i''' if `group'==`g'
+			local n=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1=r(sum)
+			qui su `cum``i''' if `group'==`g'
+			local n2=r(sum)
+			qui su `Inf``i''' if `group'==`g'
+			local d=r(sum)
+			*di "chi2_`g'_``i''=`chi2'+(`n1'-`n2')^2/(`d')"
+			local chi2=`chi2'+(`n1'-`n2')^2/(`d')
+			local chi2_``i''=`chi2_``i'''+(`n1'-`n2')^2/(`d')
+			local chi2_g`g'=`chi2_g`g''+(`n1'-`n2')^2/(`d')
+			qui su `y2_old``i''' if `group'==`g'
+			local n_old=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1_old=r(sum)
+			qui su `cum_old``i''' if `group'==`g'
+			local n2_old=r(sum)
+			qui su `Inf_old``i''' if `group'==`g'
+			local d_old=r(sum)
+			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+		}
+		*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+		*su `z``i'''
+		label variable `z``i''' "Standardized residuals associated to ``i''"
+		label variable `latent' "Latent trait"
+		*set trace on
+		if  "`graphs'"!=""&"`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fs saving("`dirsave'//residuals_``i''",replace)
+			}
+			qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+		}
+		*set trace off
+		qui gen `z2``i'''=(`z``i''')^2
+		qui su `z2``i'''
+		local OUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',1]=`OUTFIT``i'''
+		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `Inf``i''' if ``i''!=.
+		local sumw``i''=r(sum)
+		qui gen `i``i'''=`Inf``i'''*`z2``i''' 
+		qui su `i``i''' if ``i''!=.
+		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+		qui matrix `fit'[`i',2]=`INFIT``i'''
+		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		qui matrix `fit'[`i',4]=`INFITs``i'''
+		if "`postpce'"=="" {
+			di abbrev("``i''",19) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+		}
+	}
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text "*: As suggested by Wright (Smith, 1998)
+		di as text "**: As suggested by Bond and Fox (2007)
+	}
+	if "`geninf'"!="" {
+	   gen `geninf'=`TInf'
+	}
+}
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Itération `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1')
+		`qui' pcm `varlist' [iweight=`sinf'],diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1')
+		qui su `ecart_`it''
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+if "`visit'"==""{
+	if "`graphs'"!="" {
+
+		tempfile savefile
+		qui save `savefile'
+
+		qui clear
+		qui set obs 2000
+		qui gen u=(_n-1000)/250
+		qui gen Tcum=0
+		qui gen TInf=0
+		forvalues i=1/`nbitems' {
+		   local scatteri`i' 
+		   forvalues g=1/`nbgroups' {
+			  local x=`groups'[`g',`=`nbitems'+1']
+			  local y=`groups'[`g',`i']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			*set trace off
+			}
+			local d=1
+			qui gen cum``i''=0
+			*set trace on
+			if "`rsm'"=="" {
+				local mm=`modamax`i''
+			}
+			else {
+				local mm `modamax'
+			}	
+			forvalues k=1/`mm' {
+				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+			}
+			qui gen c0_``i''=1/(`d')
+			label variable c0_``i'' "Pr(``i''=0)"
+			forvalues k=1/`mm' {
+				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+				label variable c`k'_``i'' "Pr(``i''=`k')"
+			}
+			qui gen Inf``i''=0
+			forvalues k=1/`mm' {
+				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+			}
+			if "`graphitems'"=="" {
+				if "`filesave'"!="" {
+					local fsc saving("`dirsave'//CCC_``i''",replace)
+					local fsi saving("`dirsave'//ICC_``i''",replace)
+				}
+				qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+				qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+			}
+			qui replace Tcum=Tcum+cum``i''
+			qui replace TInf=TInf+Inf``i''	
+			label variable Inf``i'' "``i''"
+		}
+		if "`filesave'"!="" {
+			local fst saving("`dirsave'//TCC",replace)
+			local fsteo saving("`dirsave'//TCCeo",replace)
+			local fsi saving("`dirsave'//ICC",replace)
+			local fsti saving("`dirsave'//TIC",replace)
+			local fsm saving("`dirsave'//map",replace)
+		}
+		qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+		qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+		qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+
+		local scatteri
+		forvalues g=1/`nbgroups' {
+			local x=`groups'[`g',`=`nbitems'+1']
+			local y=`groups'[`g',`=`nbitems'+3']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+		}
+		qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+	
+	
+	
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+	*set trace on
+		gen eff=0
+		local effmax=0
+		forvalues g=1/`nbgroups' {
+			local eff=`groups'[`g',`=`nbitems'+2']
+			if `groups'[`g',`=`nbitems'+2']>`effmax' {
+			   local effmax=`groups'[`g',`=`nbitems'+2']
+			}
+			local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
+			*di "replace eff=`eff' if round(u,0.004)==`lat'"
+			qui replace eff=`eff' if round(u,0.004)==`lat'
+		}
+		gen density=normalden(u)*sqrt(`covariates'[1,1])
+		label variable eff "Frequencies"
+		label variable u "Latent trait"
+		label variable TInf "Information curve"
+		label variable density "Density function of the latent trait"
+		local scatteri
+		qui su u if eff!=0
+		*set trace on
+		local floor=floor(`r(min)')
+		local ceil=ceil(`r(max)')
+		forvalues i=1/`nbitems' {
+		   local color`i':word `i' of `color'
+		   local y=-`i'*`effmax'/`nbitems'
+		   forvalues l=1/`modamax' {
+			   local x=`diffmat'[`i',`l']
+			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+			   if `x'<`floor' {
+				  local floor=floor(`x')
+			   }
+			   if `x'>`ceil'&`x'!=. {
+				  local ceil=ceil(`x')
+			   }
+		   }
+		   local scatteri `scatteri' || scatteri `y' `floor' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+		}
+		qui su eff
+		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+		qui su TInf
+		local maxi=ceil(`r(max)')
+		qui su density
+		local maxd=ceil(`r(max)')
+		qui drop if u<`floor'|u>`ceil'
+		qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(`floor'(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3))    `scatteri'  , name(map,replace) ytitle("Frequencies")  ylabel(-`maxi'(`=`maxi'/5')`maxi' ,axis(2)) ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait") xtitle("Latent trait") `fsm'
+
+
+		qui clear
+		qui use `savefile'
+
+	}
+}
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+if "`visit'"==""{
+	di
+	di as text "{hline 57}"
+	di _col(31) "Latent Variable" _col(50) "Expected"
+	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score"
+	di as text "{hline 57}"
+	*set trace on
+	forvalues g=1/`nbgroups' {
+		qui count if `group'1==`g' 
+		local eff`g'=r(N)
+		qui count if `score'1!=.&`group'1==`g'
+		local n=r(N)
+		di as text "`g' (n=" as result `eff`g'' as text ")" _c
+		if `n'>0 {
+			qui su `score'1 if `group'1==`g'
+			local scoremin`g'=`r(min)'
+			local scoremax`g'=`r(max)'
+			forvalues s=`scoremin`g''/`scoremax`g'' {
+				qui count if `group'1==`g'&`score'1==`s'
+				local eff=r(N)
+				qui su `latent' if `group'1==`g'&`score'1==`s'
+				local mean=r(mean)
+				qui su `selatent' if `group'1==`g'&`score'1==`s'
+				local se=r(mean)
+				qui su `Tcum' if `group'1==`g'&`score'1==`s'
+				local exp=r(mean)
+				if `eff'>0 {
+				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+				}
+			}
+		}
+		qui count if `group'1==`g'&`score'1==.
+		local eff=r(N)
+		qui su `latent' if `group'1==`g'&`score'1==.
+		local mean=r(mean)
+		qui su `selatent' if `group'1==`g'&`score'1==.
+		local se=r(mean)
+		qui su `Tcum' if `group'1==`g'&`score'1==.
+		local exp=r(mean)
+		if `eff'>0 {
+			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+		}
+		di as text "{hline 57}"
+	}
+}	
+
+
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin
+	putdocx paragraph
+	putdocx text ("General informations") , bold underline font(,14) smallcaps
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph
+	putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	qui putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx paragraph
+	putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
+	qui putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm 4.2 sauv le 8nov2019.ado b/Modules/ado/personal/p/pcm 4.2 sauv le 8nov2019.ado
new file mode 100644
index 0000000..94b9b15
--- /dev/null
+++ b/Modules/ado/personal/p/pcm 4.2 sauv le 8nov2019.ado	
@@ -0,0 +1,1504 @@
+*! Version 4.2 21September2019
+*! Jean-Benoit Hardouin, Myriam Blanchin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
+* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
+* Version 4.1: September 15th, 2019 [Jean-Benoit Hardouin]: correction of a small bug in the outputs
+* Version 4.2: September 27th, 2019 [Jean-Benoit Hardouin]
+*
+*
+* Jean-benoit Hardouin, Myriam Blanchin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr myriam.blanchin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) VARiance(real -1) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(string) GENINF(string) REPlace postpce visit(varname) id(varname) eqset1(varlist) eqset2(varlist) EQGraph minsize(int 30)]
+
+preserve
+
+/*************************************************************************************************************
+QUELQUES TESTS
+*************************************************************************************************************/
+
+if `variance'!=-1&`variance'<=0 {
+	di in red "The -variance- option cannot be negative"
+	exit 198
+}
+if `variance'!=-1&"`visit'"!="" {
+	di in red "The -variance- and -visit- options cannot be used simultaneously."*
+	exit 198
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' se`genlt' `geninf'
+	if _rc!=0&"`replace'"=="" {
+	    di in red "The variables `genlt', se`genlt' and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+	if _rc!=0&"`replace'"!="" {
+	    qui drop `genlt' se`genlt' `geninf' 
+	}
+}
+if ("`eqset1'"!=""&"`eqset2'"=="")|("`eqset1'"==""&"`eqset2'"!="") {
+    di in red "The two options -eqset1- and -eqset2- must be used simultaneously"
+	exit 198
+}
+if ("`eqset1'"!=""&"`graphs'"!="") {
+    di in red "The two options -eqset1- and -graph- cannot be used simultaneously"
+	exit 198
+}
+
+
+
+
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+if "`visit'"!=""{
+	if "`id'"==""{
+		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
+		exit 198
+	}
+	qui levelsof `visit'
+	local levelsofv `r(levels)'
+	local nbvisits=r(r)
+	local timemin: word 1 of `levelsofv'
+	local timemax: word `nbvisits' of `levelsofv'
+	if `timemax'>5{
+		di as error "You must use a discrete time variable (-visit- option) with less than 5 measurement occasions"
+		error 198
+	}
+	if `timemin'!=1{
+		di as error "You must use a -visit- variable coded at 1 for the first visit"
+		error 198
+	}
+	qui reshape wide `varlist', i(`id') j(`visit')
+	local multivist=1
+}
+else {
+	local timemax=1
+	foreach i in `varlist' {
+	   *rename `i' `i'1
+	}
+	local multivisit
+}
+qui count
+local nbobs=r(N)
+
+local timelist
+forvalues t=1/`timemax'{
+	local timelist `timelist' T`t'
+}
+
+local modcont
+local premodcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local premodcont (`modcont'->T1)
+	local modcont (`modcont'->`timelist')
+}
+
+local modcat
+local premodcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local premodcat (`modcat'->T1)
+	local modcat (`modcat'->`timelist')
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+forvalues i=1/`nbitems' {
+	local modamax`i'=1
+	local modamax``i''=1
+	if `timemax'>1 {
+		forvalues t=1/`timemax'{
+			 *qui replace ``i'`t''=``i'`t''-`min' 
+			 qui su ``i''`t'
+			 if `r(min)'!=`modamin' {
+				 local modamin=r(min)
+				 local pbmin `pbmin' ``i'`t''
+			 }
+			 if `r(max)'>`modamax' {
+				 local modamax=r(max)
+			 }
+			 if `r(max)'>`modamax`i'' {
+				local modamax`i'=r(max)
+			}
+		}
+	}
+	else {
+		qui su ``i''
+		if `r(min)'!=`modamin' {
+		    local modamin=r(min)
+			local pbmin `pbmin' ``i''
+		}
+		if `r(max)'>`modamax' {
+			local modamax=r(max)
+		}
+		if `r(max)'>`modamax`i'' {
+			local modamax`i'=r(max)
+			local modamax``i''=r(max)
+		}
+	}
+	if "`rsm'"=="" {
+		local nbdiff=`nbdiff'+`modamax`i''
+	}
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count
+local nbind=r(N)
+*set trace on
+local code
+local precode
+if `timemax'>1 {
+	forvalues k=1/`modamax' {
+	   forvalues t=1/`timemax'{
+			local code`k'
+		   forvalues i=1/`nbitems' {
+			   if `k'<=`modamax`i'' {
+				  local code`k' `code`k'' `k'.``i''`t'
+			   }
+		   }
+		   local code`k' (`code`k''<-T`t'@`k')
+		   if `t'==1{
+				local precode `precode' `code`k''
+		   }
+		   local code `code' `code`k''
+		}
+	}
+}
+else {
+	forvalues k=1/`modamax' {
+		local code`k'
+		forvalues i=1/`nbitems' {
+			if `k'<=`modamax`i'' {
+				local code`k' `code`k'' `k'.``i''
+			}
+		}
+		local code`k' (`code`k''<-T@`k')
+		local precode `precode' `code`k''
+		local code `code' `code`k''
+	}
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+local t=1
+local constraints
+local codemean
+local codevar
+local codecov
+forvalues j=2/`timemax'{
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			qui constraint `t' [`k'.``i''`j']_cons=[`k'.``i''`multivisit']_cons
+			local constraints `constraints' `t'
+			local ++t
+			
+		}
+	}	
+	if "`continuous'"=="" &  "`categorical'"==""{
+		local codemean `codemean' T`j'@m`j'
+		local codevar `codevar' T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' T`l'*T`j'@cov`l'`j'
+		}
+	}
+	else{
+		local codevar `codevar' e.T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
+		}	
+	}
+}
+if `timemax'>1{
+	if "`continuous'"=="" &  "`categorical'"==""{	
+		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
+	}
+	else{
+		local codelg var(e.T1@v1 `codevar') cov(`codecov')
+	}
+}
+else {
+    local constrvar
+    if `variance'>0 {
+		if "`continuous'"=="" &  "`categorical'"==""{	
+			local constrvar var(T1@`variance') 
+		}
+		else{
+			local constrvar var(e.T1@`variance') 
+		}
+	}
+}
+
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				qui constraint `t' [`k'.``i''`multivisit']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+}
+
+
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+if "`rsm'"!="" {
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       qui constraint `t'   [`=`k'-1'.``i''`multivisit']_cons-[`k'.``i''`multivisit']_cons+[1.``i''`multivisit']_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
+if "`model'"!="" {
+    local qui
+}
+else {
+	local qui qui
+}
+if `timemax'==1{
+   `qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar'
+}
+else{
+    di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
+    `qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') constraint(`constraints') 
+     matrix esti_B = e(b)
+    di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)"
+    `qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
+}
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2 miss
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent'*,latent se(`selatent'*)
+
+if "`genlt'"!="" {
+	if `timemax'==1 {
+		qui gen `genlt'=`latent'`i'
+		qui gen se`genlt'=`selatent'`i'
+	}
+	forvalues t=2/`timemax' {
+		qui gen `genlt'`t'=`latent'`t'
+		qui gen se`genlt'`t'=`selatent'`t'
+	}
+}
+
+set seed 123456
+if `timemax'>1 {
+	forvalues t=1/`timemax'{
+		qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t'
+		local listit 
+		forvalues i=1/`nbitems' {
+			local listit `listit' ``i''`t'
+		}
+		qui genscore `listit',score(`score'`t')
+		qui gengroup `latent'`t',newvariable(`group'`t') continuous minsize(`minsize')
+	}
+}
+else {
+	qui gen `latent2'=`latent'+invnorm(uniform())*`selatent'
+	local listit 
+	forvalues i=1/`nbitems' {
+		local listit `listit' ``i''
+	}
+	qui genscore `listit',score(`score')
+	qui gengroup `latent',newvariable(`group') continuous minsize(`minsize')
+}
+
+/*time 1 only*/
+qui levelsof `group'`multivisit'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+3',.)
+forvalues g=1/`nbgroups' {
+	matrix `groups'[`g',`=`nbitems'+3']=0
+	forvalues i=1/`nbitems' {
+			qui count if ``i''`multivisit'!=.&`group'`multivisit'==`g'
+			local n=r(N)
+			if `n'>0 {
+				qui su ``i''`multivisit' if `group'`multivisit'==`g'
+				matrix `groups'[`g',`i']=r(mean)
+				matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+			}
+			else {
+				matrix `groups'[`g',`i']=.
+				matrix `groups'[`g',`=`nbitems'+3']=.
+			}		
+	}
+	qui su `latent'`multivisit' if `group'`multivisit'==`g'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'`multivisit'==`g'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+}
+
+/*number of non-missing on all time points*/
+egen `miss'=rowmiss(`score'*)
+qui count if `miss'==0
+local nbobsssmd=r(N)
+drop `miss'	
+
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i''`multivisit':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i''`multivisit':_cons]
+	qui lincom -_b[1.``i''`multivisit':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+	local rn `rn' 1.``i''`multivisit'
+	local ++t
+	local sum _b[1.``i''`multivisit':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax`i'' {
+			local sum "_b[`k'.``i''`multivisit':_cons]-(`sum')"
+			*di "``i''`multivisit' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i''`multivisit':_cons]-_b[`k'.``i''`multivisit':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''`multivisit'
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1'`multivisit':_cons]-_b[`k'.`1'`multivisit':_cons]+_b[1.`1'`multivisit':_cons] /*``i'' instead of `i'?*/
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
+*************************************************************************************************************/
+tempname covariates
+local nbcov=0
+forvalues j=2/`timemax'{
+	local nbcov=`nbcov'+`j'-1
+}
+qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)
+
+*set trace on
+local t=1
+
+
+forvalues j=1/`=`timemax'-1'{
+	forvalues k=`=`j'+1'/`timemax'{
+		if "`categorical'"=="" & "`continuous'"=="" {
+			if `j'==1{
+				qui lincom [/]mean(T`k')
+			}
+			else{
+				qui lincom [/]mean(T`k')-[/]mean(T`j')
+			}
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+		else{
+			if "`categorical'"!=""{
+				local first=0 
+				foreach l in `levelsof`cat1'' {
+					if `first'==0 {
+						local ++first
+					}
+					else{
+						if `first'==1 {
+							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
+							qui matrix `covariates'[`t',1]=`r(estimate)'
+							qui matrix `covariates'[`t',2]=`r(se)'
+							qui matrix `covariates'[`t',3]=`r(z)'
+							qui matrix `covariates'[`t',4]=`r(p)'
+							qui matrix `covariates'[`t',5]=`r(lb)'
+							qui matrix `covariates'[`t',6]=`r(ub)'
+							local ++t
+							local ++first
+						}
+					}
+				}
+			}
+			else{
+				qui lincom [T`k']`cont1'-[T`j']`cont1'
+				qui matrix `covariates'[`t',1]=`r(estimate)'
+				qui matrix `covariates'[`t',2]=`r(se)'
+				qui matrix `covariates'[`t',3]=`r(z)'
+				qui matrix `covariates'[`t',4]=`r(p)'
+				qui matrix `covariates'[`t',5]=`r(lb)'
+				qui matrix `covariates'[`t',6]=`r(ub)'
+				local ++t
+			}		
+		}
+	}
+}	
+		
+forvalues j=1/`timemax'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		qui lincom _b[/var(e.T`j')]
+	}
+	else {
+		qui lincom _b[/var(T`j')]
+	}
+	qui matrix `covariates'[`t',1]=`r(estimate)'
+	qui matrix `covariates'[`t',2]=`r(se)'
+	qui matrix `covariates'[`t',3]=`r(z)'
+	qui matrix `covariates'[`t',4]=`r(p)'
+	qui matrix `covariates'[`t',5]=`r(lb)'
+	qui matrix `covariates'[`t',6]=`r(ub)'
+	local ++t
+}
+forvalues j=1/`=`timemax'-1'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(e.T`j',e.T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+	else{
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(T`j',T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+}
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+*matrix list `covariates'
+
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 73}"
+	di  as text _col(60) "<--95% IC -->"
+	di  "Items" _col(60) "Lower" _col(68) "Upper"
+	di "parameters" _col(13) "category" _col(25) "Estimate" _col(37) "s.e." _col(48) "z" _col(56) "p" _col(59) " Bound" _col(68) "Bound"
+	di "{hline 73}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax`i'' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 73}"
+	local t=1
+	local listmoy
+	local listvar
+	local listcov
+	forvalues j=1/`timemax'{
+		local listvar `listvar' Variance_T`j'
+		forvalues k=`=`j'+1'/`timemax'{
+			local listcov `listcov' Cov_T`j'_T`k'
+		}
+		forvalues k=`=`j'+1'/`timemax'{
+			local listmoy `listmoy' Mean_diff_T`j'_T`k'
+		}
+	}
+	local n: word count `listmoy' `listvar' `listcov' `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of `listmoy' `listvar' `listcov' `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		*local ++t
+	}
+	di as text "{hline 73}"
+	if "`visit'"==""{
+		di
+		qui su `latent'
+		*qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])+(`r(sd)')^2)
+		*di as text "Variance of the estimated latent variable: " as result %4.2f `=(`r(sd)')^2'
+        tempvar se2latent
+		qui gen `se2latent'=(`selatent')^2
+		qui su `se2latent'
+		di as text "Mean squared std error of the latent variable: " as result %4.2f `=(`r(mean)')'
+		di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`r(mean)'))'
+		local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`r(mean)'))
+		di as text "PSI: " as result %4.2f `PSI' _c
+		if "`continuous'"!=""|"`categorical'"!="" {
+		    di as text " (without adjustment on covariates)"
+	    }
+		else {
+		    di
+		}
+		di
+	}
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+if "`visit'"==""{
+	tempname fit
+	qui matrix `fit'=J(`nbitems',4,.)
+	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+	matrix rownames `fit'=`varlist'
+	*matrix list `fit'
+
+	tempvar Tcum TInf cum
+	qui gen `Tcum'=0
+	qui gen `TInf'=0
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text _col(60) "<---  Standardized   --->"
+		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+		di as text "{hline 90}"
+		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "{hline 90}"
+	}
+	*set trace on
+	local chi2=0
+	local chi2_old=0
+	forvalues g=1/`nbgroups' {
+	   local chi2_g`g'=0
+	   local chi2_old_g`g'=0
+	}
+	forvalues i=1/`nbitems' {
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+		local d=1
+		local d_old=1
+		qui gen `cum``i'''=0
+		qui gen `cum_old``i'''=0
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+			local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
+		}
+		qui gen `c0_``i'''=1/(`d')
+		qui gen `c_old0_``i'''=1/(`d_old')
+		forvalues k=1/`mm' {
+			tempvar c`k'_``i'' c_old`k'_``i''
+			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
+			qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
+			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
+			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
+		}
+		qui gen `Inf``i'''=0
+		qui gen `Inf_old``i'''=0
+		qui gen `C``i'''=0
+		forvalues k=0/`mm' {
+			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
+			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
+			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
+		}
+		qui count if ``i''!=.
+		local n``i''=r(N)
+		
+		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
+		qui su `C2``i'''
+		local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
+		qui su `C3``i'''
+		local n=r(sum)
+		qui su `Inf``i'''
+		local d=r(sum)
+		local q2i``i''=`n'/((`d')^2)
+		
+		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+		
+		qui replace `Tcum'=`Tcum'+`cum``i'''
+		qui replace `TInf'=`TInf'+`Inf``i'''
+		qui gen `y``i'''=``i''-`cum``i'''
+		qui gen `y_old``i'''=``i''-`cum_old``i'''
+		qui gen `y2``i'''=(`y``i''')^2
+		qui gen `y2_old``i'''=(`y_old``i''')^2
+		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
+		local chi2_``i''=0
+		local chi2_old_``i''=0
+		forvalues g=1/`nbgroups' {
+			qui su `y2``i''' if `group'==`g'
+			local n=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1=r(sum)
+			qui su `cum``i''' if `group'==`g'
+			local n2=r(sum)
+			qui su `Inf``i''' if `group'==`g'
+			local d=r(sum)
+			*qui count if `group'==`g'
+			*local eff=r(N)
+			*di "chi2_`g'_``i''=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')"
+			local chi2=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_``i''=`chi2_``i'''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_g`g'=`chi2_g`g''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			qui su `y2_old``i''' if `group'==`g'
+			local n_old=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1_old=r(sum)
+			qui su `cum_old``i''' if `group'==`g'
+			local n2_old=r(sum)
+			qui su `Inf_old``i''' if `group'==`g'
+			local d_old=r(sum)
+			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+		}
+		di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+		*su `z``i'''
+		label variable `z``i''' "Standardized residuals associated to ``i''"
+		label variable `latent' "Latent trait"
+		*set trace on
+		if  "`graphs'"!=""&"`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fs saving("`dirsave'//residuals_``i''",replace)
+			}
+			qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+		}
+		*set trace off
+		qui gen `z2``i'''=(`z``i''')^2
+		qui su `z2``i'''
+		local OUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',1]=`OUTFIT``i'''
+		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `Inf``i''' if ``i''!=.
+		local sumw``i''=r(sum)
+		qui gen `i``i'''=`Inf``i'''*`z2``i''' 
+		qui su `i``i''' if ``i''!=.
+		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+		qui matrix `fit'[`i',2]=`INFIT``i'''
+		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		qui matrix `fit'[`i',4]=`INFITs``i'''
+		if "`postpce'"=="" {
+			di abbrev("``i''",19) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+		}
+	}
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text "*: As suggested by Wright (Smith, 1998)
+		di as text "**: As suggested by Bond and Fox (2007)
+	}
+	if "`geninf'"!="" {
+	    gen `geninf'=`TInf'
+	}
+}
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Itération `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1')
+		`qui' pcm `varlist' [iweight=`sinf'],diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1')
+		qui su `ecart_`it''
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+if "`visit'"==""{
+	if "`graphs'"!="" {
+
+		tempfile savefile
+		qui save `savefile'
+
+		*qui clear
+		qui drop _all
+		
+		qui set obs 2000
+		qui gen u=(_n-1000)/250
+		qui gen Tcum=0
+		qui gen TInf=0
+		forvalues i=1/`nbitems' {
+		   local scatteri`i' 
+		   forvalues g=1/`nbgroups' {
+			  local x=`groups'[`g',`=`nbitems'+1']
+			  local y=`groups'[`g',`i']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			*set trace off
+			}
+			local d=1
+			qui gen cum``i''=0
+			*set trace on
+			if "`rsm'"=="" {
+				local mm=`modamax`i''
+			}
+			else {
+				local mm `modamax'
+			}	
+			forvalues k=1/`mm' {
+				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+			}
+			qui gen c0_``i''=1/(`d')
+			label variable c0_``i'' "Pr(``i''=0)"
+			forvalues k=1/`mm' {
+				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+				label variable c`k'_``i'' "Pr(``i''=`k')"
+			}
+			qui gen Inf``i''=0
+			forvalues k=1/`mm' {
+				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+			}
+			if "`graphitems'"=="" {
+				if "`filesave'"!="" {
+					local fsc saving("`dirsave'//CCC_``i''",replace)
+					local fsi saving("`dirsave'//ICC_``i''",replace)
+				}
+				qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+				qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+			}
+			qui replace Tcum=Tcum+cum``i''
+			qui replace TInf=TInf+Inf``i''	
+			label variable Inf``i'' "``i''"
+		}
+		if "`filesave'"!="" {
+			local fst saving("`dirsave'//TCC",replace)
+			local fsteo saving("`dirsave'//TCCeo",replace)
+			local fsi saving("`dirsave'//ICC",replace)
+			local fsti saving("`dirsave'//TIC",replace)
+			local fsm saving("`dirsave'//map",replace)
+		}
+		qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+		qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+		qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+
+		local scatteri
+		forvalues g=1/`nbgroups' {
+			local x=`groups'[`g',`=`nbitems'+1']
+			local y=`groups'[`g',`=`nbitems'+3']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+		}
+		qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+	
+	
+	
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+	*set trace on
+		gen eff=0
+		local effmax=0
+		forvalues g=1/`nbgroups' {
+			local eff=`groups'[`g',`=`nbitems'+2']
+			if `groups'[`g',`=`nbitems'+2']>`effmax' {
+			   local effmax=`groups'[`g',`=`nbitems'+2']
+			}
+			local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
+			*di "replace eff=`eff' if round(u,0.004)==`lat'"
+			qui replace eff=`eff' if round(u,0.004)==`lat'
+		}
+		gen density=normalden(u)*sqrt(`covariates'[1,1])
+		label variable eff "Frequencies"
+		label variable u "Latent trait"
+		label variable TInf "Information curve"
+		label variable density "Density function of the latent trait"
+		local scatteri
+		qui su u if eff!=0
+		*set trace on
+		local floor=floor(`r(min)')
+		local ceil=ceil(`r(max)')
+		forvalues i=1/`nbitems' {
+		   local color`i':word `i' of `color'
+		   local y=-`i'*`effmax'/`nbitems'
+		   forvalues l=1/`modamax' {
+			   local x=`diffmat'[`i',`l']
+			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+			   if `x'<`floor' {
+				  local floor=floor(`x')
+			   }
+			   if `x'>`ceil'&`x'!=. {
+				  local ceil=ceil(`x')
+			   }
+		   }
+		   local scatteri `scatteri' || scatteri `y' `floor' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+		}
+		qui su eff
+		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+		qui su TInf
+		local maxi=ceil(`r(max)')
+		qui su density
+		local maxd=ceil(`r(max)')
+		qui drop if u<`floor'|u>`ceil'
+		qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(`floor'(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3))    `scatteri'  , name(map,replace) ytitle("Frequencies")  ylabel(-`maxi'(`=`maxi'/5')`maxi' ,axis(2)) ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait") xtitle("Latent trait") `fsm'
+
+
+		qui use `savefile', clear
+
+	}
+}
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+if "`visit'"==""{
+	*set trace on
+    tempname matscorelt
+	qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)
+	di
+	di as text "{hline 57}"
+	di _col(31) "Latent Variable" _col(50) "Expected"
+	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score"
+	di as text "{hline 57}"
+	forvalues g=1/`nbgroups' {
+		qui count if `group'`multivisit'==`g' 
+		local eff`g'=r(N)
+		qui count if `score'`multivisit'!=.&`group'`multivisit'==`g'
+		local n=r(N)
+		di as text "`g' (n=" as result `eff`g'' as text ")" _c
+		if `n'>0 {
+			qui su `score'`multivisit' if `group'`multivisit'==`g'
+			local scoremin`g'=`r(min)'
+			local scoremax`g'=`r(max)'
+			forvalues s=`scoremin`g''/`scoremax`g'' {
+				qui count if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local eff=r(N)
+				qui su `latent' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local mean=r(mean)
+				qui su `selatent' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local se=r(mean)
+				qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local exp=r(mean)
+				if `eff'>0 {
+				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+				}
+				qui matrix `matscorelt'[`=`s'+1',1]=`s'
+				qui matrix `matscorelt'[`=`s'+1',2]=`mean'
+				qui matrix `matscorelt'[`=`s'+1',3]=`se'
+			}
+		}
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local eff=r(N)
+		qui su `latent' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local mean=r(mean)
+		qui su `selatent' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local se=r(mean)
+		qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local exp=r(mean)
+		if `eff'>0 {
+			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+		}
+		di as text "{hline 57}"
+	}
+	*matrix list `matscorelt'
+}	
+
+/*************************************************************************************************************
+EQUATING
+*************************************************************************************************************/
+*set trace on
+if "`eqset1'"!="" {
+
+    tokenize `eqset1'
+	local nbset1: word count `eqset1'
+	forvalues i=1/`nbset1' {
+	   local eq1_`i':word `i' of `eqset1'
+	   *di "set1 (`nbset1') : `eq1_`i''"
+	}
+	*di "`eqset1'"
+    tokenize `eqset2'
+	local nbset2: word count  `eqset2'
+	*di "`eqset2'"
+	forvalues i=1/`nbset2' {
+	   local eq2_`i':word `i' of `eqset2'
+	   *di "set2  (`nbset2') : `eq2_`i''"
+	}	
+
+
+
+	tempfile fileeq
+	qui save `fileeq',replace
+	forvalues t=1/2{
+		local scoremaxset`t'=0
+		forvalues i=1/`nbset`t'' {
+		    *di "`eq`t'_`i''"
+			*local tmp=""
+			local scoremaxset`t'=`scoremaxset`t''+`modamax`eq`t'_`i'''
+		}
+	}
+	drop _all
+	*set trace on
+	qui set obs `=(`scoremaxset1'+`scoremaxset2'+2)*3'
+	forvalues t=1/2 {
+		qui gen scoreset`t'=.
+		qui gen scoreset`t'm=.
+		qui gen scoreset`t'p=.	
+	}
+	forvalues i=0/`scoremaxset1' {
+	    qui replace scoreset1=`i' in `=`i'+1'
+	    qui replace scoreset1m=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset1p=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	forvalues i=`=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2' {
+	    qui replace scoreset2=`i'-`scoremaxset1'-2 in `i'
+	    qui replace scoreset2m=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset2p=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	local s=0
+	local eqset1b
+	foreach i in `eqset1' {
+		qui gen s1_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s1_`i'_`m'=0 in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'_`m'=1 if scoreset1>`s' in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'=s1_`i'+s1_`i'_`m'
+		   local ++s
+		}
+	    local eqset1b `eqset1b' s1_`i'
+	}
+	local s=0
+	local eqset2b
+	foreach i in `eqset2' {
+		qui gen s2_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s2_`i'_`m'=0 in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'_`m'=1 if scoreset2>`s' in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'=s2_`i'+s2_`i'_`m'
+		   local ++s
+		}
+		local eqset2b `eqset2b' s2_`i'
+	}
+	tokenize `varlist'
+	tempname diffset1 diffset2
+	*matrix list `diffmat'
+	forvalues t=1/2 {
+		qui matrix `diffset`t''=J(`nbset`t'',`modamax',.)
+		local n=1
+		local listset`t'
+		foreach j in `eqset`t'' {
+			forvalues i=1/`nbitems' {
+				if "`j'"=="``i''" {
+					local listset`t' `listset`t'' `i'
+					forvalues m=1/`modamax' {
+						qui matrix `diffset`t''[`n',`m']=`diffmat'[`i',`m']
+					}
+					local ++n						
+				}
+			}
+		}
+	}
+	*matrix list `diffset1'
+	*matrix list `diffset2'
+	local var=`covariates'[1,1]
+	qui gen lt=.
+	*qui gen selt=.
+	forvalues t=1/2 {
+		tempname matscorelt`t'
+		qui pcm `eqset`t'b', diff(`diffset`t'') var(`var') minsize(1)
+		qui matrix `matscorelt`t''=r(matscorelt)
+		*di "matscorelt`t':"
+		*matrix list `matscorelt`t''
+		forvalues i=0/`scoremaxset`t'' {
+			qui replace lt=`matscorelt`t''[`=`i'+1',2] if scoreset`t'==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]+1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'p==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]-1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'm==`i'
+			*qui replace selt=`matscorelt`t''[`=`i'+1',3] if scoreset`t'==`i'
+		}
+		qui ipolate scoreset`t' lt, gen(score`t') epolate
+	}
+	qui ipolate scoreset1 lt, gen(score1bis) epolate
+
+
+	*list
+	forvalues t=1/2 {
+		qui replace score`t'=scoreset`t'm if scoreset`t'm!=.
+		qui replace score`t'=scoreset`t'p if scoreset`t'p!=.
+		qui replace score1=score1bis if score1==.
+		qui replace score`t'=0 if score`t'<0
+		qui replace score`t'=`scoremaxset`t'' if score`t'>`scoremaxset`t''
+	}
+	forvalues t=1/2 {
+		tempname matscore`t'
+		qui matrix `matscore`t''=J(`=`scoremaxset`t''+1',7,.)
+		forvalues s=0/`scoremaxset`t'' {
+		    qui matrix `matscore`t''[`=`s'+1',1]=`s'
+			qui su lt if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',2]=r(mean)
+			qui su lt if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',3]=r(mean)
+			qui su lt if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',4]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',5]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',6]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',7]=r(mean)
+		}
+		matrix colnames `matscore`t'' =score`t' lt lt- lt+ score`=3-`t'' score`=3-`t''- score`=3-`t''+
+		*matrix list `matscore`t''
+		di
+		di "{hline 78}"
+		di "EQUATING SET`t' TO SET`=3-`t''"
+		di "{hline 78}"
+		di "Set`t' : `eqset`t''"
+		di "Set`=3-`t'' : `eqset`=3-`t'''"
+		di "{hline 78}"
+		di            _col(20) "<----- Latent trait ----->" _col(52) "<------- Score `=3-`t'' --------->"
+		di "Score`t'" _col(20) "Estimated" _col(39) "[95%IC]" _col(52) "Estimated" _col(72) "[95%IC]"
+		di "{hline 78}"
+		forvalues s=0/`scoremaxset`t'' {
+			di %4.0f `matscore`t''[`=`s'+1',1] _col(24) %5.2f `matscore`t''[`=`s'+1',2] _col(33) "[" %5.2f `matscore`t''[`=`s'+1',3] ";" %5.2f `matscore`t''[`=`s'+1',4] "]" _col(56) %5.2f `matscore`t''[`=`s'+1',5] _col(66) "[" %5.2f `matscore`t''[`=`s'+1',6] ";" %5.2f `matscore`t''[`=`s'+1',7] "]"
+		}
+		di "{hline 78}"
+		return matrix score`t'_to_`=3-`t''=`matscore`t''
+		if "`eqgraph'"!="" {
+			*twoway (line lt scoreset1) (line lt scoreset2), name(eq1)
+			*twoway (line scoreset1 scoreset2 lt) , name(eq2)
+			*twoway (line score1 scoreset1m scoreset1p score2), name(eq3)
+			*twoway (line score2 scoreset2m scoreset2p score1), name(eq4)
+			twoway (line score`t' score`=3-`t'' if scoreset`=3-`t''!=.) (line score`t' score`=3-`t'' if scoreset`=3-`t''m!=.) (line score`t' score`=3-`t'' if scoreset`=3-`t''p!=.), title("Equating score of the Set `t' from the Set `=3-`t''") ytitle("Score `t'") xtitle("Score `=3-`t''") ylabel(0(1)`scoremaxset`t'') xlabel(0(1)`scoremaxset`=3-`t''') name(eq`t'to`=3-`t'')
+			*twoway (line score2 score1 if scoreset1!=.) (line score2 score1 if scoreset1m!=.) (line score2 score1 if scoreset1p!=.), name(eq6)
+		}
+	}
+	*save prout, replace
+	*clear
+	
+	qui use `fileeq',clear
+}
+
+
+/*************************************************************************************************************
+RETOUR AU FICHIER INITIAL ET SAUVEGARDE DES NOUVELLES VARIABLES
+*************************************************************************************************************/
+if "`visit'"!="" {
+	tempfile sauv
+	qui keep `latent'* `selatent'* `id' `visit'
+    qui reshape wide , i(`id') j(`visit')
+	qui sort `id'	
+	qui save `sauv', replace
+	restore,preserve
+	*su
+	if "`replace'"!=""&("`genlt'"!=""|"`genfit'"!="") {
+    	capture drop `genlt' se`genlt' `geninf'
+    }
+	tempname idorder
+	qui gen `idorder'=_n
+	qui sort `id'
+	qui merge 1:1 `id' using `sauv'
+	qui sort `idorder'
+    qui drop `idorder'	
+}
+else {
+	restore,not
+}
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin
+	putdocx paragraph
+	putdocx text ("General informations") , bold underline font(,14) smallcaps
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph
+	putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	qui putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx paragraph
+	putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
+	qui putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+return matrix matscorelt=`matscorelt'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm 4.2.ado b/Modules/ado/personal/p/pcm 4.2.ado
new file mode 100644
index 0000000..94b9b15
--- /dev/null
+++ b/Modules/ado/personal/p/pcm 4.2.ado	
@@ -0,0 +1,1504 @@
+*! Version 4.2 21September2019
+*! Jean-Benoit Hardouin, Myriam Blanchin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
+* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
+* Version 4.1: September 15th, 2019 [Jean-Benoit Hardouin]: correction of a small bug in the outputs
+* Version 4.2: September 27th, 2019 [Jean-Benoit Hardouin]
+*
+*
+* Jean-benoit Hardouin, Myriam Blanchin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr myriam.blanchin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) VARiance(real -1) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(string) GENINF(string) REPlace postpce visit(varname) id(varname) eqset1(varlist) eqset2(varlist) EQGraph minsize(int 30)]
+
+preserve
+
+/*************************************************************************************************************
+QUELQUES TESTS
+*************************************************************************************************************/
+
+if `variance'!=-1&`variance'<=0 {
+	di in red "The -variance- option cannot be negative"
+	exit 198
+}
+if `variance'!=-1&"`visit'"!="" {
+	di in red "The -variance- and -visit- options cannot be used simultaneously."*
+	exit 198
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' se`genlt' `geninf'
+	if _rc!=0&"`replace'"=="" {
+	    di in red "The variables `genlt', se`genlt' and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+	if _rc!=0&"`replace'"!="" {
+	    qui drop `genlt' se`genlt' `geninf' 
+	}
+}
+if ("`eqset1'"!=""&"`eqset2'"=="")|("`eqset1'"==""&"`eqset2'"!="") {
+    di in red "The two options -eqset1- and -eqset2- must be used simultaneously"
+	exit 198
+}
+if ("`eqset1'"!=""&"`graphs'"!="") {
+    di in red "The two options -eqset1- and -graph- cannot be used simultaneously"
+	exit 198
+}
+
+
+
+
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+if "`visit'"!=""{
+	if "`id'"==""{
+		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
+		exit 198
+	}
+	qui levelsof `visit'
+	local levelsofv `r(levels)'
+	local nbvisits=r(r)
+	local timemin: word 1 of `levelsofv'
+	local timemax: word `nbvisits' of `levelsofv'
+	if `timemax'>5{
+		di as error "You must use a discrete time variable (-visit- option) with less than 5 measurement occasions"
+		error 198
+	}
+	if `timemin'!=1{
+		di as error "You must use a -visit- variable coded at 1 for the first visit"
+		error 198
+	}
+	qui reshape wide `varlist', i(`id') j(`visit')
+	local multivist=1
+}
+else {
+	local timemax=1
+	foreach i in `varlist' {
+	   *rename `i' `i'1
+	}
+	local multivisit
+}
+qui count
+local nbobs=r(N)
+
+local timelist
+forvalues t=1/`timemax'{
+	local timelist `timelist' T`t'
+}
+
+local modcont
+local premodcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local premodcont (`modcont'->T1)
+	local modcont (`modcont'->`timelist')
+}
+
+local modcat
+local premodcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local premodcat (`modcat'->T1)
+	local modcat (`modcat'->`timelist')
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+forvalues i=1/`nbitems' {
+	local modamax`i'=1
+	local modamax``i''=1
+	if `timemax'>1 {
+		forvalues t=1/`timemax'{
+			 *qui replace ``i'`t''=``i'`t''-`min' 
+			 qui su ``i''`t'
+			 if `r(min)'!=`modamin' {
+				 local modamin=r(min)
+				 local pbmin `pbmin' ``i'`t''
+			 }
+			 if `r(max)'>`modamax' {
+				 local modamax=r(max)
+			 }
+			 if `r(max)'>`modamax`i'' {
+				local modamax`i'=r(max)
+			}
+		}
+	}
+	else {
+		qui su ``i''
+		if `r(min)'!=`modamin' {
+		    local modamin=r(min)
+			local pbmin `pbmin' ``i''
+		}
+		if `r(max)'>`modamax' {
+			local modamax=r(max)
+		}
+		if `r(max)'>`modamax`i'' {
+			local modamax`i'=r(max)
+			local modamax``i''=r(max)
+		}
+	}
+	if "`rsm'"=="" {
+		local nbdiff=`nbdiff'+`modamax`i''
+	}
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count
+local nbind=r(N)
+*set trace on
+local code
+local precode
+if `timemax'>1 {
+	forvalues k=1/`modamax' {
+	   forvalues t=1/`timemax'{
+			local code`k'
+		   forvalues i=1/`nbitems' {
+			   if `k'<=`modamax`i'' {
+				  local code`k' `code`k'' `k'.``i''`t'
+			   }
+		   }
+		   local code`k' (`code`k''<-T`t'@`k')
+		   if `t'==1{
+				local precode `precode' `code`k''
+		   }
+		   local code `code' `code`k''
+		}
+	}
+}
+else {
+	forvalues k=1/`modamax' {
+		local code`k'
+		forvalues i=1/`nbitems' {
+			if `k'<=`modamax`i'' {
+				local code`k' `code`k'' `k'.``i''
+			}
+		}
+		local code`k' (`code`k''<-T@`k')
+		local precode `precode' `code`k''
+		local code `code' `code`k''
+	}
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+local t=1
+local constraints
+local codemean
+local codevar
+local codecov
+forvalues j=2/`timemax'{
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			qui constraint `t' [`k'.``i''`j']_cons=[`k'.``i''`multivisit']_cons
+			local constraints `constraints' `t'
+			local ++t
+			
+		}
+	}	
+	if "`continuous'"=="" &  "`categorical'"==""{
+		local codemean `codemean' T`j'@m`j'
+		local codevar `codevar' T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' T`l'*T`j'@cov`l'`j'
+		}
+	}
+	else{
+		local codevar `codevar' e.T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
+		}	
+	}
+}
+if `timemax'>1{
+	if "`continuous'"=="" &  "`categorical'"==""{	
+		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
+	}
+	else{
+		local codelg var(e.T1@v1 `codevar') cov(`codecov')
+	}
+}
+else {
+    local constrvar
+    if `variance'>0 {
+		if "`continuous'"=="" &  "`categorical'"==""{	
+			local constrvar var(T1@`variance') 
+		}
+		else{
+			local constrvar var(e.T1@`variance') 
+		}
+	}
+}
+
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				qui constraint `t' [`k'.``i''`multivisit']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+}
+
+
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+if "`rsm'"!="" {
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       qui constraint `t'   [`=`k'-1'.``i''`multivisit']_cons-[`k'.``i''`multivisit']_cons+[1.``i''`multivisit']_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
+if "`model'"!="" {
+    local qui
+}
+else {
+	local qui qui
+}
+if `timemax'==1{
+   `qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar'
+}
+else{
+    di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
+    `qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') constraint(`constraints') 
+     matrix esti_B = e(b)
+    di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)"
+    `qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
+}
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2 miss
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent'*,latent se(`selatent'*)
+
+if "`genlt'"!="" {
+	if `timemax'==1 {
+		qui gen `genlt'=`latent'`i'
+		qui gen se`genlt'=`selatent'`i'
+	}
+	forvalues t=2/`timemax' {
+		qui gen `genlt'`t'=`latent'`t'
+		qui gen se`genlt'`t'=`selatent'`t'
+	}
+}
+
+set seed 123456
+if `timemax'>1 {
+	forvalues t=1/`timemax'{
+		qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t'
+		local listit 
+		forvalues i=1/`nbitems' {
+			local listit `listit' ``i''`t'
+		}
+		qui genscore `listit',score(`score'`t')
+		qui gengroup `latent'`t',newvariable(`group'`t') continuous minsize(`minsize')
+	}
+}
+else {
+	qui gen `latent2'=`latent'+invnorm(uniform())*`selatent'
+	local listit 
+	forvalues i=1/`nbitems' {
+		local listit `listit' ``i''
+	}
+	qui genscore `listit',score(`score')
+	qui gengroup `latent',newvariable(`group') continuous minsize(`minsize')
+}
+
+/*time 1 only*/
+qui levelsof `group'`multivisit'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+3',.)
+forvalues g=1/`nbgroups' {
+	matrix `groups'[`g',`=`nbitems'+3']=0
+	forvalues i=1/`nbitems' {
+			qui count if ``i''`multivisit'!=.&`group'`multivisit'==`g'
+			local n=r(N)
+			if `n'>0 {
+				qui su ``i''`multivisit' if `group'`multivisit'==`g'
+				matrix `groups'[`g',`i']=r(mean)
+				matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+			}
+			else {
+				matrix `groups'[`g',`i']=.
+				matrix `groups'[`g',`=`nbitems'+3']=.
+			}		
+	}
+	qui su `latent'`multivisit' if `group'`multivisit'==`g'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'`multivisit'==`g'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+}
+
+/*number of non-missing on all time points*/
+egen `miss'=rowmiss(`score'*)
+qui count if `miss'==0
+local nbobsssmd=r(N)
+drop `miss'	
+
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i''`multivisit':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i''`multivisit':_cons]
+	qui lincom -_b[1.``i''`multivisit':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+	local rn `rn' 1.``i''`multivisit'
+	local ++t
+	local sum _b[1.``i''`multivisit':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax`i'' {
+			local sum "_b[`k'.``i''`multivisit':_cons]-(`sum')"
+			*di "``i''`multivisit' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i''`multivisit':_cons]-_b[`k'.``i''`multivisit':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''`multivisit'
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1'`multivisit':_cons]-_b[`k'.`1'`multivisit':_cons]+_b[1.`1'`multivisit':_cons] /*``i'' instead of `i'?*/
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
+*************************************************************************************************************/
+tempname covariates
+local nbcov=0
+forvalues j=2/`timemax'{
+	local nbcov=`nbcov'+`j'-1
+}
+qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)
+
+*set trace on
+local t=1
+
+
+forvalues j=1/`=`timemax'-1'{
+	forvalues k=`=`j'+1'/`timemax'{
+		if "`categorical'"=="" & "`continuous'"=="" {
+			if `j'==1{
+				qui lincom [/]mean(T`k')
+			}
+			else{
+				qui lincom [/]mean(T`k')-[/]mean(T`j')
+			}
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+		else{
+			if "`categorical'"!=""{
+				local first=0 
+				foreach l in `levelsof`cat1'' {
+					if `first'==0 {
+						local ++first
+					}
+					else{
+						if `first'==1 {
+							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
+							qui matrix `covariates'[`t',1]=`r(estimate)'
+							qui matrix `covariates'[`t',2]=`r(se)'
+							qui matrix `covariates'[`t',3]=`r(z)'
+							qui matrix `covariates'[`t',4]=`r(p)'
+							qui matrix `covariates'[`t',5]=`r(lb)'
+							qui matrix `covariates'[`t',6]=`r(ub)'
+							local ++t
+							local ++first
+						}
+					}
+				}
+			}
+			else{
+				qui lincom [T`k']`cont1'-[T`j']`cont1'
+				qui matrix `covariates'[`t',1]=`r(estimate)'
+				qui matrix `covariates'[`t',2]=`r(se)'
+				qui matrix `covariates'[`t',3]=`r(z)'
+				qui matrix `covariates'[`t',4]=`r(p)'
+				qui matrix `covariates'[`t',5]=`r(lb)'
+				qui matrix `covariates'[`t',6]=`r(ub)'
+				local ++t
+			}		
+		}
+	}
+}	
+		
+forvalues j=1/`timemax'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		qui lincom _b[/var(e.T`j')]
+	}
+	else {
+		qui lincom _b[/var(T`j')]
+	}
+	qui matrix `covariates'[`t',1]=`r(estimate)'
+	qui matrix `covariates'[`t',2]=`r(se)'
+	qui matrix `covariates'[`t',3]=`r(z)'
+	qui matrix `covariates'[`t',4]=`r(p)'
+	qui matrix `covariates'[`t',5]=`r(lb)'
+	qui matrix `covariates'[`t',6]=`r(ub)'
+	local ++t
+}
+forvalues j=1/`=`timemax'-1'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(e.T`j',e.T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+	else{
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(T`j',T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+}
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+*matrix list `covariates'
+
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 73}"
+	di  as text _col(60) "<--95% IC -->"
+	di  "Items" _col(60) "Lower" _col(68) "Upper"
+	di "parameters" _col(13) "category" _col(25) "Estimate" _col(37) "s.e." _col(48) "z" _col(56) "p" _col(59) " Bound" _col(68) "Bound"
+	di "{hline 73}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax`i'' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 73}"
+	local t=1
+	local listmoy
+	local listvar
+	local listcov
+	forvalues j=1/`timemax'{
+		local listvar `listvar' Variance_T`j'
+		forvalues k=`=`j'+1'/`timemax'{
+			local listcov `listcov' Cov_T`j'_T`k'
+		}
+		forvalues k=`=`j'+1'/`timemax'{
+			local listmoy `listmoy' Mean_diff_T`j'_T`k'
+		}
+	}
+	local n: word count `listmoy' `listvar' `listcov' `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of `listmoy' `listvar' `listcov' `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		*local ++t
+	}
+	di as text "{hline 73}"
+	if "`visit'"==""{
+		di
+		qui su `latent'
+		*qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])+(`r(sd)')^2)
+		*di as text "Variance of the estimated latent variable: " as result %4.2f `=(`r(sd)')^2'
+        tempvar se2latent
+		qui gen `se2latent'=(`selatent')^2
+		qui su `se2latent'
+		di as text "Mean squared std error of the latent variable: " as result %4.2f `=(`r(mean)')'
+		di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`r(mean)'))'
+		local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`r(mean)'))
+		di as text "PSI: " as result %4.2f `PSI' _c
+		if "`continuous'"!=""|"`categorical'"!="" {
+		    di as text " (without adjustment on covariates)"
+	    }
+		else {
+		    di
+		}
+		di
+	}
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+if "`visit'"==""{
+	tempname fit
+	qui matrix `fit'=J(`nbitems',4,.)
+	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+	matrix rownames `fit'=`varlist'
+	*matrix list `fit'
+
+	tempvar Tcum TInf cum
+	qui gen `Tcum'=0
+	qui gen `TInf'=0
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text _col(60) "<---  Standardized   --->"
+		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+		di as text "{hline 90}"
+		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "{hline 90}"
+	}
+	*set trace on
+	local chi2=0
+	local chi2_old=0
+	forvalues g=1/`nbgroups' {
+	   local chi2_g`g'=0
+	   local chi2_old_g`g'=0
+	}
+	forvalues i=1/`nbitems' {
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+		local d=1
+		local d_old=1
+		qui gen `cum``i'''=0
+		qui gen `cum_old``i'''=0
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+			local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
+		}
+		qui gen `c0_``i'''=1/(`d')
+		qui gen `c_old0_``i'''=1/(`d_old')
+		forvalues k=1/`mm' {
+			tempvar c`k'_``i'' c_old`k'_``i''
+			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
+			qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
+			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
+			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
+		}
+		qui gen `Inf``i'''=0
+		qui gen `Inf_old``i'''=0
+		qui gen `C``i'''=0
+		forvalues k=0/`mm' {
+			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
+			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
+			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
+		}
+		qui count if ``i''!=.
+		local n``i''=r(N)
+		
+		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
+		qui su `C2``i'''
+		local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
+		qui su `C3``i'''
+		local n=r(sum)
+		qui su `Inf``i'''
+		local d=r(sum)
+		local q2i``i''=`n'/((`d')^2)
+		
+		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+		
+		qui replace `Tcum'=`Tcum'+`cum``i'''
+		qui replace `TInf'=`TInf'+`Inf``i'''
+		qui gen `y``i'''=``i''-`cum``i'''
+		qui gen `y_old``i'''=``i''-`cum_old``i'''
+		qui gen `y2``i'''=(`y``i''')^2
+		qui gen `y2_old``i'''=(`y_old``i''')^2
+		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
+		local chi2_``i''=0
+		local chi2_old_``i''=0
+		forvalues g=1/`nbgroups' {
+			qui su `y2``i''' if `group'==`g'
+			local n=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1=r(sum)
+			qui su `cum``i''' if `group'==`g'
+			local n2=r(sum)
+			qui su `Inf``i''' if `group'==`g'
+			local d=r(sum)
+			*qui count if `group'==`g'
+			*local eff=r(N)
+			*di "chi2_`g'_``i''=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')"
+			local chi2=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_``i''=`chi2_``i'''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_g`g'=`chi2_g`g''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			qui su `y2_old``i''' if `group'==`g'
+			local n_old=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1_old=r(sum)
+			qui su `cum_old``i''' if `group'==`g'
+			local n2_old=r(sum)
+			qui su `Inf_old``i''' if `group'==`g'
+			local d_old=r(sum)
+			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+		}
+		di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+		*su `z``i'''
+		label variable `z``i''' "Standardized residuals associated to ``i''"
+		label variable `latent' "Latent trait"
+		*set trace on
+		if  "`graphs'"!=""&"`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fs saving("`dirsave'//residuals_``i''",replace)
+			}
+			qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+		}
+		*set trace off
+		qui gen `z2``i'''=(`z``i''')^2
+		qui su `z2``i'''
+		local OUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',1]=`OUTFIT``i'''
+		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `Inf``i''' if ``i''!=.
+		local sumw``i''=r(sum)
+		qui gen `i``i'''=`Inf``i'''*`z2``i''' 
+		qui su `i``i''' if ``i''!=.
+		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+		qui matrix `fit'[`i',2]=`INFIT``i'''
+		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		qui matrix `fit'[`i',4]=`INFITs``i'''
+		if "`postpce'"=="" {
+			di abbrev("``i''",19) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+		}
+	}
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text "*: As suggested by Wright (Smith, 1998)
+		di as text "**: As suggested by Bond and Fox (2007)
+	}
+	if "`geninf'"!="" {
+	    gen `geninf'=`TInf'
+	}
+}
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Itération `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1')
+		`qui' pcm `varlist' [iweight=`sinf'],diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1')
+		qui su `ecart_`it''
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+if "`visit'"==""{
+	if "`graphs'"!="" {
+
+		tempfile savefile
+		qui save `savefile'
+
+		*qui clear
+		qui drop _all
+		
+		qui set obs 2000
+		qui gen u=(_n-1000)/250
+		qui gen Tcum=0
+		qui gen TInf=0
+		forvalues i=1/`nbitems' {
+		   local scatteri`i' 
+		   forvalues g=1/`nbgroups' {
+			  local x=`groups'[`g',`=`nbitems'+1']
+			  local y=`groups'[`g',`i']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			*set trace off
+			}
+			local d=1
+			qui gen cum``i''=0
+			*set trace on
+			if "`rsm'"=="" {
+				local mm=`modamax`i''
+			}
+			else {
+				local mm `modamax'
+			}	
+			forvalues k=1/`mm' {
+				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+			}
+			qui gen c0_``i''=1/(`d')
+			label variable c0_``i'' "Pr(``i''=0)"
+			forvalues k=1/`mm' {
+				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+				label variable c`k'_``i'' "Pr(``i''=`k')"
+			}
+			qui gen Inf``i''=0
+			forvalues k=1/`mm' {
+				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+			}
+			if "`graphitems'"=="" {
+				if "`filesave'"!="" {
+					local fsc saving("`dirsave'//CCC_``i''",replace)
+					local fsi saving("`dirsave'//ICC_``i''",replace)
+				}
+				qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+				qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+			}
+			qui replace Tcum=Tcum+cum``i''
+			qui replace TInf=TInf+Inf``i''	
+			label variable Inf``i'' "``i''"
+		}
+		if "`filesave'"!="" {
+			local fst saving("`dirsave'//TCC",replace)
+			local fsteo saving("`dirsave'//TCCeo",replace)
+			local fsi saving("`dirsave'//ICC",replace)
+			local fsti saving("`dirsave'//TIC",replace)
+			local fsm saving("`dirsave'//map",replace)
+		}
+		qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+		qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+		qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+
+		local scatteri
+		forvalues g=1/`nbgroups' {
+			local x=`groups'[`g',`=`nbitems'+1']
+			local y=`groups'[`g',`=`nbitems'+3']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+		}
+		qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+	
+	
+	
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+	*set trace on
+		gen eff=0
+		local effmax=0
+		forvalues g=1/`nbgroups' {
+			local eff=`groups'[`g',`=`nbitems'+2']
+			if `groups'[`g',`=`nbitems'+2']>`effmax' {
+			   local effmax=`groups'[`g',`=`nbitems'+2']
+			}
+			local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
+			*di "replace eff=`eff' if round(u,0.004)==`lat'"
+			qui replace eff=`eff' if round(u,0.004)==`lat'
+		}
+		gen density=normalden(u)*sqrt(`covariates'[1,1])
+		label variable eff "Frequencies"
+		label variable u "Latent trait"
+		label variable TInf "Information curve"
+		label variable density "Density function of the latent trait"
+		local scatteri
+		qui su u if eff!=0
+		*set trace on
+		local floor=floor(`r(min)')
+		local ceil=ceil(`r(max)')
+		forvalues i=1/`nbitems' {
+		   local color`i':word `i' of `color'
+		   local y=-`i'*`effmax'/`nbitems'
+		   forvalues l=1/`modamax' {
+			   local x=`diffmat'[`i',`l']
+			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+			   if `x'<`floor' {
+				  local floor=floor(`x')
+			   }
+			   if `x'>`ceil'&`x'!=. {
+				  local ceil=ceil(`x')
+			   }
+		   }
+		   local scatteri `scatteri' || scatteri `y' `floor' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+		}
+		qui su eff
+		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+		qui su TInf
+		local maxi=ceil(`r(max)')
+		qui su density
+		local maxd=ceil(`r(max)')
+		qui drop if u<`floor'|u>`ceil'
+		qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(`floor'(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3))    `scatteri'  , name(map,replace) ytitle("Frequencies")  ylabel(-`maxi'(`=`maxi'/5')`maxi' ,axis(2)) ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait") xtitle("Latent trait") `fsm'
+
+
+		qui use `savefile', clear
+
+	}
+}
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+if "`visit'"==""{
+	*set trace on
+    tempname matscorelt
+	qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)
+	di
+	di as text "{hline 57}"
+	di _col(31) "Latent Variable" _col(50) "Expected"
+	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score"
+	di as text "{hline 57}"
+	forvalues g=1/`nbgroups' {
+		qui count if `group'`multivisit'==`g' 
+		local eff`g'=r(N)
+		qui count if `score'`multivisit'!=.&`group'`multivisit'==`g'
+		local n=r(N)
+		di as text "`g' (n=" as result `eff`g'' as text ")" _c
+		if `n'>0 {
+			qui su `score'`multivisit' if `group'`multivisit'==`g'
+			local scoremin`g'=`r(min)'
+			local scoremax`g'=`r(max)'
+			forvalues s=`scoremin`g''/`scoremax`g'' {
+				qui count if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local eff=r(N)
+				qui su `latent' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local mean=r(mean)
+				qui su `selatent' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local se=r(mean)
+				qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local exp=r(mean)
+				if `eff'>0 {
+				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+				}
+				qui matrix `matscorelt'[`=`s'+1',1]=`s'
+				qui matrix `matscorelt'[`=`s'+1',2]=`mean'
+				qui matrix `matscorelt'[`=`s'+1',3]=`se'
+			}
+		}
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local eff=r(N)
+		qui su `latent' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local mean=r(mean)
+		qui su `selatent' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local se=r(mean)
+		qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local exp=r(mean)
+		if `eff'>0 {
+			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+		}
+		di as text "{hline 57}"
+	}
+	*matrix list `matscorelt'
+}	
+
+/*************************************************************************************************************
+EQUATING
+*************************************************************************************************************/
+*set trace on
+if "`eqset1'"!="" {
+
+    tokenize `eqset1'
+	local nbset1: word count `eqset1'
+	forvalues i=1/`nbset1' {
+	   local eq1_`i':word `i' of `eqset1'
+	   *di "set1 (`nbset1') : `eq1_`i''"
+	}
+	*di "`eqset1'"
+    tokenize `eqset2'
+	local nbset2: word count  `eqset2'
+	*di "`eqset2'"
+	forvalues i=1/`nbset2' {
+	   local eq2_`i':word `i' of `eqset2'
+	   *di "set2  (`nbset2') : `eq2_`i''"
+	}	
+
+
+
+	tempfile fileeq
+	qui save `fileeq',replace
+	forvalues t=1/2{
+		local scoremaxset`t'=0
+		forvalues i=1/`nbset`t'' {
+		    *di "`eq`t'_`i''"
+			*local tmp=""
+			local scoremaxset`t'=`scoremaxset`t''+`modamax`eq`t'_`i'''
+		}
+	}
+	drop _all
+	*set trace on
+	qui set obs `=(`scoremaxset1'+`scoremaxset2'+2)*3'
+	forvalues t=1/2 {
+		qui gen scoreset`t'=.
+		qui gen scoreset`t'm=.
+		qui gen scoreset`t'p=.	
+	}
+	forvalues i=0/`scoremaxset1' {
+	    qui replace scoreset1=`i' in `=`i'+1'
+	    qui replace scoreset1m=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset1p=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	forvalues i=`=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2' {
+	    qui replace scoreset2=`i'-`scoremaxset1'-2 in `i'
+	    qui replace scoreset2m=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset2p=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	local s=0
+	local eqset1b
+	foreach i in `eqset1' {
+		qui gen s1_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s1_`i'_`m'=0 in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'_`m'=1 if scoreset1>`s' in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'=s1_`i'+s1_`i'_`m'
+		   local ++s
+		}
+	    local eqset1b `eqset1b' s1_`i'
+	}
+	local s=0
+	local eqset2b
+	foreach i in `eqset2' {
+		qui gen s2_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s2_`i'_`m'=0 in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'_`m'=1 if scoreset2>`s' in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'=s2_`i'+s2_`i'_`m'
+		   local ++s
+		}
+		local eqset2b `eqset2b' s2_`i'
+	}
+	tokenize `varlist'
+	tempname diffset1 diffset2
+	*matrix list `diffmat'
+	forvalues t=1/2 {
+		qui matrix `diffset`t''=J(`nbset`t'',`modamax',.)
+		local n=1
+		local listset`t'
+		foreach j in `eqset`t'' {
+			forvalues i=1/`nbitems' {
+				if "`j'"=="``i''" {
+					local listset`t' `listset`t'' `i'
+					forvalues m=1/`modamax' {
+						qui matrix `diffset`t''[`n',`m']=`diffmat'[`i',`m']
+					}
+					local ++n						
+				}
+			}
+		}
+	}
+	*matrix list `diffset1'
+	*matrix list `diffset2'
+	local var=`covariates'[1,1]
+	qui gen lt=.
+	*qui gen selt=.
+	forvalues t=1/2 {
+		tempname matscorelt`t'
+		qui pcm `eqset`t'b', diff(`diffset`t'') var(`var') minsize(1)
+		qui matrix `matscorelt`t''=r(matscorelt)
+		*di "matscorelt`t':"
+		*matrix list `matscorelt`t''
+		forvalues i=0/`scoremaxset`t'' {
+			qui replace lt=`matscorelt`t''[`=`i'+1',2] if scoreset`t'==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]+1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'p==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]-1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'm==`i'
+			*qui replace selt=`matscorelt`t''[`=`i'+1',3] if scoreset`t'==`i'
+		}
+		qui ipolate scoreset`t' lt, gen(score`t') epolate
+	}
+	qui ipolate scoreset1 lt, gen(score1bis) epolate
+
+
+	*list
+	forvalues t=1/2 {
+		qui replace score`t'=scoreset`t'm if scoreset`t'm!=.
+		qui replace score`t'=scoreset`t'p if scoreset`t'p!=.
+		qui replace score1=score1bis if score1==.
+		qui replace score`t'=0 if score`t'<0
+		qui replace score`t'=`scoremaxset`t'' if score`t'>`scoremaxset`t''
+	}
+	forvalues t=1/2 {
+		tempname matscore`t'
+		qui matrix `matscore`t''=J(`=`scoremaxset`t''+1',7,.)
+		forvalues s=0/`scoremaxset`t'' {
+		    qui matrix `matscore`t''[`=`s'+1',1]=`s'
+			qui su lt if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',2]=r(mean)
+			qui su lt if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',3]=r(mean)
+			qui su lt if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',4]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',5]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',6]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',7]=r(mean)
+		}
+		matrix colnames `matscore`t'' =score`t' lt lt- lt+ score`=3-`t'' score`=3-`t''- score`=3-`t''+
+		*matrix list `matscore`t''
+		di
+		di "{hline 78}"
+		di "EQUATING SET`t' TO SET`=3-`t''"
+		di "{hline 78}"
+		di "Set`t' : `eqset`t''"
+		di "Set`=3-`t'' : `eqset`=3-`t'''"
+		di "{hline 78}"
+		di            _col(20) "<----- Latent trait ----->" _col(52) "<------- Score `=3-`t'' --------->"
+		di "Score`t'" _col(20) "Estimated" _col(39) "[95%IC]" _col(52) "Estimated" _col(72) "[95%IC]"
+		di "{hline 78}"
+		forvalues s=0/`scoremaxset`t'' {
+			di %4.0f `matscore`t''[`=`s'+1',1] _col(24) %5.2f `matscore`t''[`=`s'+1',2] _col(33) "[" %5.2f `matscore`t''[`=`s'+1',3] ";" %5.2f `matscore`t''[`=`s'+1',4] "]" _col(56) %5.2f `matscore`t''[`=`s'+1',5] _col(66) "[" %5.2f `matscore`t''[`=`s'+1',6] ";" %5.2f `matscore`t''[`=`s'+1',7] "]"
+		}
+		di "{hline 78}"
+		return matrix score`t'_to_`=3-`t''=`matscore`t''
+		if "`eqgraph'"!="" {
+			*twoway (line lt scoreset1) (line lt scoreset2), name(eq1)
+			*twoway (line scoreset1 scoreset2 lt) , name(eq2)
+			*twoway (line score1 scoreset1m scoreset1p score2), name(eq3)
+			*twoway (line score2 scoreset2m scoreset2p score1), name(eq4)
+			twoway (line score`t' score`=3-`t'' if scoreset`=3-`t''!=.) (line score`t' score`=3-`t'' if scoreset`=3-`t''m!=.) (line score`t' score`=3-`t'' if scoreset`=3-`t''p!=.), title("Equating score of the Set `t' from the Set `=3-`t''") ytitle("Score `t'") xtitle("Score `=3-`t''") ylabel(0(1)`scoremaxset`t'') xlabel(0(1)`scoremaxset`=3-`t''') name(eq`t'to`=3-`t'')
+			*twoway (line score2 score1 if scoreset1!=.) (line score2 score1 if scoreset1m!=.) (line score2 score1 if scoreset1p!=.), name(eq6)
+		}
+	}
+	*save prout, replace
+	*clear
+	
+	qui use `fileeq',clear
+}
+
+
+/*************************************************************************************************************
+RETOUR AU FICHIER INITIAL ET SAUVEGARDE DES NOUVELLES VARIABLES
+*************************************************************************************************************/
+if "`visit'"!="" {
+	tempfile sauv
+	qui keep `latent'* `selatent'* `id' `visit'
+    qui reshape wide , i(`id') j(`visit')
+	qui sort `id'	
+	qui save `sauv', replace
+	restore,preserve
+	*su
+	if "`replace'"!=""&("`genlt'"!=""|"`genfit'"!="") {
+    	capture drop `genlt' se`genlt' `geninf'
+    }
+	tempname idorder
+	qui gen `idorder'=_n
+	qui sort `id'
+	qui merge 1:1 `id' using `sauv'
+	qui sort `idorder'
+    qui drop `idorder'	
+}
+else {
+	restore,not
+}
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin
+	putdocx paragraph
+	putdocx text ("General informations") , bold underline font(,14) smallcaps
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph
+	putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	qui putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx paragraph
+	putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
+	qui putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+return matrix matscorelt=`matscorelt'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm 5.1.ado b/Modules/ado/personal/p/pcm 5.1.ado
new file mode 100644
index 0000000..ede39c9
--- /dev/null
+++ b/Modules/ado/personal/p/pcm 5.1.ado	
@@ -0,0 +1,1791 @@
+*! Version 5 2August2022
+*! Jean-Benoit Hardouin, Myriam Blanchin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
+* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
+* Version 4.1: September 15th, 2019 [Jean-Benoit Hardouin]: correction of a small bug in the outputs
+* Version 4.2: September 27th, 2019 [Jean-Benoit Hardouin] : EQUATING
+* Version 4.3: November 8th, 2019 [Jean-Benoit Hardouin] : add a constant when difficulty parameters are fixed
+* Version 5: August 2nd, 2022 [Jean-Benoit Hardouin] : New MAP graph, corrected estimation of the latent trait
+* Version 5.1: July 8th, 2023 [Jean-Benoit Hardouin] : Correction of the MAP graph (histogram) and residuals graphs
+*
+*
+* Jean-benoit Hardouin, Myriam Blanchin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr, myriam.blanchin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019, 2022, 2023 Jean-Benoit Hardouin, Myriam Blanchin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) VARiance(real -1) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(string) GENINF(string) REPlace postpce visit(varname) id(varname) eqset1(varlist) eqset2(varlist) EQGraph minsize(int 30)]
+
+preserve
+
+/*************************************************************************************************************
+QUELQUES TESTS
+*************************************************************************************************************/
+
+if `variance'!=-1&`variance'<=0 {
+	di in red "The -variance- option cannot be negative"
+	exit 198
+}
+if `variance'!=-1&"`visit'"!="" {
+	di in red "The -variance- and -visit- options cannot be used simultaneously."*
+	exit 198
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' `genlt'_se `geninf' `genlt'_corr `genlt'_opt `genlt'_opt_se 
+	if _rc!=0&"`replace'"=="" {
+	    di in red "The variables `genlt', `genlt'_se, `genlt'_corr, `genlt'_opt, `genlt'_opt_se and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+	if _rc!=0&"`replace'"!="" {
+	    qui capture drop `genlt' 
+		qui capture drop `genlt'_se 
+		qui capture drop `geninf' 
+		qui capture drop `genlt'_corr
+		qui capture drop `genlt'_opt
+		qui capture drop `genlt'_opt_se
+	}
+}
+if ("`eqset1'"!=""&"`eqset2'"=="")|("`eqset1'"==""&"`eqset2'"!="") {
+    di in red "The two options -eqset1- and -eqset2- must be used simultaneously"
+	exit 198
+}
+if ("`eqset1'"!=""&"`graphs'"!="") {
+    di in red "The two options -eqset1- and -graph- cannot be used simultaneously"
+	exit 198
+}
+
+
+
+
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+if "`visit'"!=""{
+	if "`id'"==""{
+		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
+		exit 198
+	}
+	qui levelsof `visit'
+	local levelsofv `r(levels)'
+	local nbvisits=r(r)
+	local timemin: word 1 of `levelsofv'
+	local timemax: word `nbvisits' of `levelsofv'
+	if `timemax'>5{
+		di as error "You must use a discrete time variable (-visit- option) with less than 5 measurement occasions"
+		error 198
+	}
+	if `timemin'!=1{
+		di as error "You must use a -visit- variable coded at 1 for the first visit"
+		error 198
+	}
+	qui reshape wide `varlist', i(`id') j(`visit')
+	local multivist=1
+}
+else {
+	local timemax=1
+	foreach i in `varlist' {
+	   *rename `i' `i'1
+	}
+	local multivisit
+}
+qui count
+local nbobs=r(N)
+
+local timelist
+forvalues t=1/`timemax'{
+	local timelist `timelist' T`t'
+}
+
+local modcont
+local premodcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local premodcont (`modcont'->T1)
+	local modcont (`modcont'->`timelist')
+}
+
+local modcat
+local premodcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local premodcat (`modcat'->T1)
+	local modcat (`modcat'->`timelist')
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+local scoremax=0
+forvalues i=1/`nbitems' {
+	local modamax`i'=1
+	local modamax``i''=1
+	if `timemax'>1 {
+		forvalues t=1/`timemax'{
+			 *qui replace ``i'`t''=``i'`t''-`min' 
+			 qui su ``i''`t'
+			 if `r(min)'!=`modamin' {
+				 local modamin=r(min)
+				 local pbmin `pbmin' ``i'`t''
+			 }
+			 if `r(max)'>`modamax' {
+				 local modamax=r(max)
+			 }
+			 if `r(max)'>`modamax`i'' {
+				local modamax`i'=r(max)
+			}
+		}
+	}
+	else {
+		qui su ``i''
+		if `r(min)'!=`modamin' {
+		    local modamin=r(min)
+			local pbmin `pbmin' ``i''
+		}
+		if `r(max)'>`modamax' {
+			local modamax=r(max)
+		}
+		if `r(max)'>`modamax`i'' {
+			local modamax`i'=r(max)
+			local modamax``i''=r(max)
+		}
+	}
+	*di "local scoremax=`scoremax'+`modamax`i''"
+	local scoremax=`scoremax'+`modamax`i''
+	if "`rsm'"=="" {
+		local nbdiff=`nbdiff'+`modamax`i''
+	}
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count
+local nbind=r(N)
+*set trace on
+local code
+local precode
+if `timemax'>1 {
+	forvalues k=1/`modamax' {
+	   forvalues t=1/`timemax'{
+			local code`k'
+		   forvalues i=1/`nbitems' {
+			   if `k'<=`modamax`i'' {
+				  local code`k' `code`k'' `k'.``i''`t'
+			   }
+		   }
+		   local code`k' (`code`k''<-T`t'@`k')
+		   if `t'==1{
+				local precode `precode' `code`k''
+		   }
+		   local code `code' `code`k''
+		}
+	}
+}
+else {
+	forvalues k=1/`modamax' {
+		local code`k'
+		forvalues i=1/`nbitems' {
+			if `k'<=`modamax`i'' {
+				local code`k' `code`k'' `k'.``i''
+			}
+		}
+		local code`k' (`code`k''<-T1@`k')
+		local precode `precode' `code`k''
+		local code `code' `code`k''
+	}
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+local t=1
+local constraints
+local codemean
+local codevar
+local codecov
+forvalues j=2/`timemax'{
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			qui constraint `t' [`k'.``i''`j']_cons=[`k'.``i''`multivisit']_cons
+			local constraints `constraints' `t'
+			local ++t
+			
+		}
+	}	
+	if "`continuous'"=="" &  "`categorical'"==""{
+		local codemean `codemean' T`j'@m`j'
+		local codevar `codevar' T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' T`l'*T`j'@cov`l'`j'
+		}
+	}
+	else{
+		local codevar `codevar' e.T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
+		}	
+	}
+}
+if `timemax'>1{
+	if "`continuous'"=="" &  "`categorical'"==""{	
+		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
+	}
+	else{
+		local codelg var(e.T1@v1 `codevar') cov(`codecov')
+	}
+}
+else {
+    local constrvar
+    if `variance'>0 {
+		if "`continuous'"=="" &  "`categorical'"==""{	
+			local constrvar var(T1@`variance') 
+		}
+		else{ 
+			*local constrvar var(e.T1@`variance') 
+		}
+	}
+}
+
+local fixedmean
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				qui constraint `t' [`k'.``i''`multivisit']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+	if "`continuous'"=="" &  "`categorical'"=="" {	
+		local fixedmean mean(T1) 
+	}
+	else{
+		local fixedmean 
+	}
+}
+
+
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+if "`rsm'"!="" {
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       qui constraint `t'   [`=`k'-1'.``i''`multivisit']_cons-[`k'.``i''`multivisit']_cons+[1.``i''`multivisit']_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
+if "`model'"!="" {
+    local qui
+}
+else {
+	local qui qui
+}
+if `timemax'==1{
+   *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'"
+   `qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+   *qui gen un=1
+   *`qui' gsem `code' (i.group un->T) ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+}
+else{
+    *di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
+    `qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') constraint(`constraints') 
+     matrix esti_B = e(b)
+    *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)"
+    `qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
+}
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2 miss
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent'*,latent se(`selatent'*)
+
+if "`genlt'"!="" {
+	if `timemax'==1 {
+		qui gen `genlt'=`latent'`i'
+		qui gen `genlt'_se=`selatent'`i'
+	}
+	forvalues t=2/`timemax' {
+		qui gen `genlt'`t'=`latent'`t'
+		qui gen `genlt'`t'_se=`selatent'`t'
+	}
+}
+
+set seed 123456
+if `timemax'>1 {
+	forvalues t=1/`timemax'{
+		qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t'
+		local listit 
+		forvalues i=1/`nbitems' {
+			local listit `listit' ``i''`t'
+		}
+		qui genscore `listit',score(`score'`t')
+		qui gengroup `latent'`t',newvariable(`group'`t') continuous minsize(`minsize')
+	}
+}
+else {
+	qui gen `latent2'=`latent'+invnorm(uniform())*`selatent'
+	local listit 
+	forvalues i=1/`nbitems' {
+		local listit `listit' ``i''
+	}
+	qui genscore `listit',score(`score')
+	qui gengroup `latent',newvariable(`group') continuous minsize(`minsize')
+}
+forvalues s=0/`scoremax' {
+    qui count if `score'==`s'
+	local effscore`s'=r(N)
+}
+
+
+/*time 1 only*/
+qui levelsof `group'`multivisit'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+6',.)
+forvalues g=1/`nbgroups' {
+	matrix `groups'[`g',`=`nbitems'+3']=0
+	qui count if `group'`multivisit'==`g'
+	local effgroup`g'=r(N)
+	forvalues i=1/`nbitems' {
+			qui count if ``i''`multivisit'!=.&`group'`multivisit'==`g'
+			local n=r(N)
+			if `n'>0 {
+				qui su ``i''`multivisit' if `group'`multivisit'==`g'
+				matrix `groups'[`g',`i']=r(mean)
+				matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+			}
+			else {
+				matrix `groups'[`g',`i']=.
+				matrix `groups'[`g',`=`nbitems'+3']=.
+			}		
+	}
+	qui su `latent'`multivisit' if `group'`multivisit'==`g'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'`multivisit'==`g'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+	qui su `score' if `group'`multivisit'==`g'&`score'!=.
+	matrix `groups'[`g',`=`nbitems'+4']=r(min)
+	matrix `groups'[`g',`=`nbitems'+5']=r(max)	
+}
+
+/*number of non-missing on all time points*/
+egen `miss'=rowmiss(`score'*)
+qui count if `miss'==0
+local nbobsssmd=r(N)
+drop `miss'	
+
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i''`multivisit':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i''`multivisit':_cons]
+	qui lincom -_b[1.``i''`multivisit':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+	local rn `rn' 1.``i''`multivisit'
+	local ++t
+	local sum _b[1.``i''`multivisit':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax`i'' {
+			local sum "_b[`k'.``i''`multivisit':_cons]-(`sum')"
+			*di "``i''`multivisit' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i''`multivisit':_cons]-_b[`k'.``i''`multivisit':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''`multivisit'
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1'`multivisit':_cons]-_b[`k'.`1'`multivisit':_cons]+_b[1.`1'`multivisit':_cons] /*``i'' instead of `i'?*/
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
+*************************************************************************************************************/
+tempname covariates
+local nbcov=0
+forvalues j=2/`timemax'{
+	local nbcov=`nbcov'+`j'-1
+}
+qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)
+
+*set trace on
+local t=1
+
+
+forvalues j=1/`=`timemax'-1'{
+	forvalues k=`=`j'+1'/`timemax'{
+		if "`categorical'"=="" & "`continuous'"=="" {
+			if `j'==1{
+				qui lincom [/]mean(T`k')
+			}
+			else{
+				qui lincom [/]mean(T`k')-[/]mean(T`j')
+			}
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+		else{
+			if "`categorical'"!=""{
+				local first=0 
+				foreach l in `levelsof`cat1'' {
+					if `first'==0 {
+						local ++first
+					}
+					else{
+						if `first'==1 {
+							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
+							qui matrix `covariates'[`t',1]=`r(estimate)'
+							qui matrix `covariates'[`t',2]=`r(se)'
+							qui matrix `covariates'[`t',3]=`r(z)'
+							qui matrix `covariates'[`t',4]=`r(p)'
+							qui matrix `covariates'[`t',5]=`r(lb)'
+							qui matrix `covariates'[`t',6]=`r(ub)'
+							local ++t
+							local ++first
+						}
+					}
+				}
+			}
+			else{
+				qui lincom [T`k']`cont1'-[T`j']`cont1'
+				qui matrix `covariates'[`t',1]=`r(estimate)'
+				qui matrix `covariates'[`t',2]=`r(se)'
+				qui matrix `covariates'[`t',3]=`r(z)'
+				qui matrix `covariates'[`t',4]=`r(p)'
+				qui matrix `covariates'[`t',5]=`r(lb)'
+				qui matrix `covariates'[`t',6]=`r(ub)'
+				local ++t
+			}		
+		}
+	}
+}	
+		
+forvalues j=1/`timemax'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		qui lincom _b[/var(e.T`j')]
+	}
+	else {
+		qui lincom _b[/var(T`j')]
+	}
+	qui matrix `covariates'[`t',1]=`r(estimate)'
+	qui matrix `covariates'[`t',2]=`r(se)'
+	qui matrix `covariates'[`t',3]=`r(z)'
+	qui matrix `covariates'[`t',4]=`r(p)'
+	qui matrix `covariates'[`t',5]=`r(lb)'
+	qui matrix `covariates'[`t',6]=`r(ub)'
+	local ++t
+}
+forvalues j=1/`=`timemax'-1'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(e.T`j',e.T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+	else{
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(T`j',T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+}
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+*matrix list `covariates'
+
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 83}"
+	di  as text _col(70) "<--95% IC -->"
+	di   _col(70) "Lower" _col(78) "Upper"
+	di "Items" _col(22) "Threshold" _col(35) "Estimate" _col(47) "s.e." _col(58) "z" _col(66) "p" _col(69) " Bound" _col(78) "Bound"
+	di "{hline 83}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax`i'' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %5.2f `diff'[`t',3] _col(62) %5.2f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %5.2f `diff'[`t',3] _col(62) %5.2f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 83}"
+	local t=1
+	local listmoy
+	local listvar
+	local listcov
+	forvalues j=1/`timemax'{
+		local listvar `listvar' Variance_T`j'
+		forvalues k=`=`j'+1'/`timemax'{
+			local listcov `listcov' Cov_T`j'_T`k'
+		}
+		forvalues k=`=`j'+1'/`timemax'{
+			local listmoy `listmoy' Mean_diff_T`j'_T`k'
+		}
+	}
+	local n: word count `listmoy' `listvar' `listcov' `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of `listmoy' `listvar' `listcov' `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %5.2f `covariates'[`t',3] _col(62) %5.2f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %5.2f `covariates'[`t',3] _col(62) %5.2f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		*local ++t
+	}
+	di as text "{hline 83}"
+	if "`visit'"==""{
+		di
+		qui su `latent'
+		*qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])+(`r(sd)')^2)
+		*di as text "Variance of the estimated latent variable: " as result %4.2f `=(`r(sd)')^2'
+        tempvar se2latent
+		qui gen `se2latent'=(`selatent')^2
+		qui su `se2latent'
+		local resvar=r(mean)
+		di as text "Mean squared std error of the latent variable: " as result %4.2f `resvar'
+		di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`resvar'))'
+		local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`resvar'))
+		di as text "PSI: " as result %4.2f `PSI' _c
+		if "`continuous'"!=""|"`categorical'"!="" {
+		    di as text " (without adjustment on covariates)"
+	    }
+		else {
+		    di
+		}
+		di
+		return scalar PSI=`PSI'
+
+	}
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+if "`visit'"==""{
+	tempname fit
+	qui matrix `fit'=J(`nbitems',4,.)
+	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+	matrix rownames `fit'=`varlist'
+	*matrix list `fit'
+
+	tempvar Tcum TInf cum
+	qui gen `Tcum'=0
+	qui gen `TInf'=0
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text _col(60) "<---  Standardized   --->"
+		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+		di as text "{hline 90}"
+		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "{hline 90}"
+	}
+	*set trace on
+	local chi2=0
+	local chi2_old=0
+	forvalues g=1/`nbgroups' {
+	   local chi2_g`g'=0
+	   local chi2_old_g`g'=0
+	}
+	forvalues i=1/`nbitems' {
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+		local d=1
+		local d_old=1
+		qui gen `cum``i'''=0
+		qui gen `cum_old``i'''=0
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+			local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
+		}
+		qui gen `c0_``i'''=1/(`d')
+		qui gen `c_old0_``i'''=1/(`d_old')
+		forvalues k=1/`mm' {
+			tempvar c`k'_``i'' c_old`k'_``i''
+			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
+			qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
+			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
+			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
+		}
+		qui gen `Inf``i'''=0
+		qui gen `Inf_old``i'''=0
+		qui gen `C``i'''=0
+		forvalues k=0/`mm' {
+			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
+			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
+			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
+		}
+		qui count if ``i''!=.
+		local n``i''=r(N)
+		
+		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
+		qui su `C2``i'''
+		local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
+		qui su `C3``i'''
+		local n=r(sum)
+		qui su `Inf``i'''
+		local d=r(sum)
+		local q2i``i''=`n'/((`d')^2)
+		
+		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+		
+		qui replace `Tcum'=`Tcum'+`cum``i'''
+		qui replace `TInf'=`TInf'+`Inf``i'''
+		qui gen `y``i'''=``i''-`cum``i'''
+		qui gen `y_old``i'''=``i''-`cum_old``i'''
+		qui gen `y2``i'''=(`y``i''')^2
+		qui gen `y2_old``i'''=(`y_old``i''')^2
+		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
+		local chi2_``i''=0
+		local chi2_old_``i''=0
+		forvalues g=1/`nbgroups' {
+			qui su `y2``i''' if `group'==`g'
+			local n=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1=r(sum)
+			qui su `cum``i''' if `group'==`g'
+			local n2=r(sum)
+			qui su `Inf``i''' if `group'==`g'
+			local d=r(sum)
+			*qui count if `group'==`g'
+			*local eff=r(N)
+			*di "chi2_`g'_``i''=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')"
+			local chi2=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_``i''=`chi2_``i'''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_g`g'=`chi2_g`g''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			qui su `y2_old``i''' if `group'==`g'
+			local n_old=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1_old=r(sum)
+			qui su `cum_old``i''' if `group'==`g'
+			local n2_old=r(sum)
+			qui su `Inf_old``i''' if `group'==`g'
+			local d_old=r(sum)
+			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+		}
+		*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+		*su `z``i'''
+		label variable `z``i''' "Standardized residuals associated to ``i''"
+		label variable `latent' "Latent trait"
+		*set trace on
+		if  "`graphs'"!=""&"`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fs saving("`dirsave'//residuals_``i''",replace)
+			}
+			tempvar id``i''
+			qui gen `id``i'''=_n if abs(`z``i''')>2*sqrt(`covariates'[1,1])
+			qui tostring `id``i''',replace
+			qui replace `id``i'''="" if `id``i'''=="."
+			qui su `z``i'''
+			local min=r(min)
+			local max=r(max)
+			local min=floor(min(`min',`=-2*sqrt(`covariates'[1,1])'))
+			local max=ceil(max(`max',`=2*sqrt(`covariates'[1,1])'))
+			
+			qui graph twoway scatter `z``i''' `latent', yscale(range(`min'(1)`max')) yline(`=-2*sqrt(`covariates'[1,1])' `=2*sqrt(`covariates'[1,1])',lcolor(blue)) mlabel(`id``i''') name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+		}
+		*set trace off
+		qui gen `z2``i'''=(`z``i''')^2
+		qui su `z2``i'''
+		local OUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',1]=`OUTFIT``i'''
+		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `Inf``i''' if ``i''!=.
+		local sumw``i''=r(sum)
+		qui gen `i``i'''=`Inf``i'''*`z2``i''' 
+		qui su `i``i''' if ``i''!=.
+		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+		qui matrix `fit'[`i',2]=`INFIT``i'''
+		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		qui matrix `fit'[`i',4]=`INFITs``i'''
+		if "`postpce'"=="" {
+			di "``i''" _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+		}
+	}
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text "*: As suggested by Wright (Smith, 1998)
+		di as text "**: As suggested by Bond and Fox (2007)
+	}
+	if "`geninf'"!="" {
+	    gen `geninf'=`TInf'
+	}
+}
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Itération `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1')
+		`qui' pcm `varlist' [iweight=`sinf'],diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1')
+		qui su `ecart_`it''
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+/*************************************************************************************************************
+ESTIMATION OF THE CORRECTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+tempfile savefile
+qui save `savefile'
+
+qui drop _all
+		
+qui set obs 2000
+qui gen u=(_n-1000)/200*`=sqrt(`covariates'[1,1])'
+qui gen Tcum=0
+qui gen TInf=0
+forvalues i=1/`nbitems' {
+		local d=1
+		qui gen cum``i''=0
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+		}
+		qui gen c0_``i''=1/(`d')
+		forvalues k=1/`mm' {
+			qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+			qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+		}
+		qui gen Inf``i''=0
+		forvalues k=1/`mm' {
+			qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+		}
+		qui replace Tcum=Tcum+cum``i''
+		qui replace TInf=TInf+Inf``i''	
+	    local scoremax=0
+		forvalues i=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`i''
+	    }
+		qui gen ecart=.
+		forvalues i=0/`scoremax' {
+		    if `i'==0 {  
+			   local j=0.25
+			}
+			else if `i'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`i'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`i'=`r(mean)'
+		}
+		qui drop ecart
+}
+qui use `savefile', clear
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+if "`visit'"==""{
+*set trace on
+    tempname matscorelt
+	qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)
+	di
+	di as text "{hline 71}"
+	di _col(32) "Latent Trait" _col(50) "Expected" _col(63) "Corrected"
+	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score" _col(60) "latent trait"
+	di as text "{hline 71}"
+	forvalues g=1/`nbgroups' {
+		local sumuc=0
+		local sumc=0
+		qui count if `group'`multivisit'==`g' 
+		local eff`g'=r(N)
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'!=. 
+		local effcompleted`g'=r(N)
+		qui count if `score'`multivisit'!=.&`group'`multivisit'==`g'
+		local n=r(N)
+		di as text "`g' (n=" as result `eff`g'' as text ")" _c
+		if `n'>0 {
+			qui su `score'`multivisit' if `group'`multivisit'==`g'
+			local scoremin`g'=`r(min)'
+			local scoremax`g'=`r(max)'
+			forvalues s=`scoremin`g''/`scoremax`g'' {
+				qui count if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local eff=r(N)
+				if `eff'!=0 {
+					qui su `latent' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+					local mean=r(mean)
+					*di "local sumc=`sumc'+(`eff')*(`estlt`s'')"
+					*di "local sumuc=`sumuc'+(`eff')*(`mean')"
+				    local sumuc=(`sumuc'+((`eff')*(`mean')))
+				    local sumc=(`sumc'+((`eff')*(`estlt`s'')))
+				}
+				qui su `selatent' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local se=r(mean)
+				qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local exp=r(mean)
+				if `eff'>0 {
+				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp' _col(66) %6.3f `estlt`s''
+				}
+				qui matrix `matscorelt'[`=`s'+1',1]=`s'
+				qui matrix `matscorelt'[`=`s'+1',2]=`mean'
+				qui matrix `matscorelt'[`=`s'+1',3]=`se'
+			}
+			
+		}
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local eff=r(N)
+
+		qui su `latent' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local mean=r(mean)
+	    local sumuc=(`sumuc'+((`eff')*(`mean')))
+		qui su `selatent' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local se=r(mean)
+		qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local exp=r(mean)
+		
+		if `eff'>0 {
+			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+		}
+		*di "local lt`g'=`sumuc'/`eff`g''"		
+		*di "local clt`g'=`sumc'/`eff`g''"
+		local lt`g'=(`sumuc')/(`eff`g'')
+		local clt`g'=(`sumc')/(`effcompleted`g'')
+		matrix `groups'[`g',`=`nbitems'+6']=`clt`g''
+		*di "group `g' est=`lt`g'' corrected est=`clt`g''"
+		di as text "         " "{dup 62:-}"
+		di  as text _col(10) "`scoremin`g''/`scoremax`g''" as result _col(20) %4.0f `eff`g'' _col(30) %6.3f `lt`g''  _col(66) %6.3f `clt`g''
+		di as text "{hline 71}"
+	}
+	*matrix list `matscorelt'
+}	
+
+
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+*set trace on
+if "`visit'"==""{
+	if "`graphs'"!=""|"`graphs'"=="" {
+
+		tempfile savefile
+		qui save `savefile'
+
+		*qui clear
+		qui drop _all
+		local pas=1000*round(`=sqrt(`covariates'[1,1])',0.001)
+		qui set obs `pas'
+		qui gen u=round((_n-`pas'/2)/(`pas'/10)*`=sqrt(`covariates'[1,1])',0.01)
+		*list u
+		qui gen Tcum=0
+		qui gen TInf=0
+		qui gen ecartcum=.
+		forvalues i=1/`nbitems' {
+		   local scatteri`i' 
+		   local scatteric`i' 
+		   forvalues g=1/`nbgroups' {
+			  local x=`groups'[`g',`=`nbitems'+1']
+			  local xc=`groups'[`g',`=`nbitems'+6']
+			  local y=`groups'[`g',`i']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			  local scatteric`i' `scatteric`i'' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off)
+			*set trace off
+			}
+			local d=1
+			qui gen cum``i''=0
+			*set trace on
+			if "`rsm'"=="" {
+				local mm=`modamax`i''
+			}
+			else {
+				local mm `modamax'
+			}	
+			forvalues k=1/`mm' {
+				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+			}
+			qui gen c0_``i''=1/(`d')
+			label variable c0_``i'' "Pr(``i''=0)"
+			forvalues k=1/`mm' {
+				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+				label variable c`k'_``i'' "Pr(``i''=`k')"
+			}
+			forvalues k=0/`mm' {
+			    if `k'==0 {
+				   local l=0.25
+				}
+				else if `k'==`mm' {
+				   local l=`k'-0.25
+				}
+				else {
+				   local l=`k'
+				}
+				qui replace ecartcum=abs(cum``i''-`l')
+				qui su ecartcum
+				qui su u if round(ecartcum,0.01)==round(`r(min)',0.01)
+				local bestest``i''_`k'=r(mean)
+				*di "item ``i'' cat `k' : est=`bestest``i''_`k''"
+			}
+			qui gen Inf``i''=0
+			forvalues k=0/`mm' {
+				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+			}
+			if "`graphitems'"=="" {
+				if "`filesave'"!="" {
+					local fsc saving("`dirsave'//CCC_``i''",replace)
+					local fsi saving("`dirsave'//ICC_``i''",replace)
+				}
+				if "`graphs'"!="" {
+					qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+					qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+					qui graph twoway line cum``i'' u, name(ICCc``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Corrected latent trait") `scatteric`i'' `fsi'
+				}
+			}
+			qui replace Tcum=Tcum+cum``i''
+			*tab Tcum
+			qui replace TInf=TInf+Inf``i''	
+			label variable Inf``i'' "``i''"
+		}
+	    local scoremax=0
+		forvalues i=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`i''
+	    }
+		qui gen ecart=.
+		forvalues i=0/`scoremax' {
+		    if `i'==0 {  
+			   local j=0.25
+			}
+			else if `i'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`i'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`i'=`r(mean)'
+			*di "score `i' : `r(mean)'"
+		}
+		if "`filesave'"!="" {
+			local fst saving("`dirsave'//TCC",replace)
+			local fsteo saving("`dirsave'//TCCeo",replace)
+			local fsi saving("`dirsave'//ICC",replace)
+			local fsti saving("`dirsave'//TIC",replace)
+			local fsm saving("`dirsave'//map",replace)
+		}
+		if "`graphs'"!="" {
+*qui save "C:\temp\info\info",replace
+			qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+			qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+			qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+		}
+		local scatteri
+		local scatteric
+		forvalues g=1/`nbgroups' {
+			local x=`groups'[`g',`=`nbitems'+1']
+			local xc=`groups'[`g',`=`nbitems'+6']
+			local y=`groups'[`g',`=`nbitems'+3']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			local scatteric `scatteric' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off)
+		}
+		if "`graphs'"!="" {
+			qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+			qui graph twoway line Tcum u , name(TCCceo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Corrrected latent trait") `scatteric' `fsteo'
+		}
+	}
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+	*set trace on
+	if "`graphs'"!="" {
+		gen eff=0
+		local effmax=0
+			*gen uround=round(u,0.01)
+			*list uround
+		forvalues g=1/`nbgroups' {
+			local eff=`groups'[`g',`=`nbitems'+2']
+			if `groups'[`g',`=`nbitems'+2']>`effmax' {
+			   local effmax=`groups'[`g',`=`nbitems'+2']
+			}
+			local lat=round(`groups'[`g',`=`nbitems'+1'],0.01)
+			*di "replace eff=`eff' if round(u,0.01)==`lat'"
+			qui replace eff=`eff' if round(u,0.01)==`lat'
+		}
+		gen density=normalden(u)*sqrt(`covariates'[1,1])
+		label variable eff "Frequencies"
+		label variable u "Latent trait"
+		label variable TInf "Information curve"
+		label variable density "Density function of the latent trait"
+		local scatteri
+		local scatterj
+		local color 
+		qui su u if eff!=0
+		*set trace on
+		*set tracedepth 1
+		local floor=floor(`r(min)')
+		local ceil=ceil(`r(max)')
+		local sep
+		local ylbl
+		forvalues i=1/`nbitems' {
+		   local color`i':word `i' of `color'
+		   local unit=round(`effmax'/`nbitems',1)
+		   local y=-`i'*`unit'             
+		   loca staritem
+		   local legend `" 2 "1" "'
+		   forvalues l=1/`modamax' {
+			   if `l'>=2 {
+			      local legend `" `legend' `=2*`l'' "`l'" "'
+			   }			   
+			   local x=`diffmat'[`i',`l']
+			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+			   if `l'==1 {
+			      local xant=`x'
+			   }
+			   else {
+			      local xant=`diffmat'[`i',`=`l'-1']
+			   }
+			   if `xant'>`x' {
+				  local star *
+				  local staritem *
+			   }
+			   else {
+			      local star
+			   }
+			   local scatterj `" `scatterj' `sep' scatteri `y' `x'   , pstyle(p`l') || pci `y' `xant' `y' `x', pstyle(p1) color(black)"'
+			   local sep ||
+			   if `x'<`floor' {
+				  local floor=floor(`x')
+			   }
+			   if `x'>`ceil'&`x'!=. {
+				  local ceil=ceil(`x')
+			   }
+		   }
+   		   local ylbl `ylbl' `=-`i'*`unit'' "``i''`staritem'"
+		   local scatteri `scatteri' || scatteri `y' `=`floor'-2' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+		}
+		qui su eff
+		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+		qui su TInf
+		local maxi=ceil(`r(max)')
+		qui su density
+		local maxd=round(`r(max)', 0.01)+0.01
+		qui drop if u<`floor'|u>`ceil'
+		*di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(0(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3)) `scatterj'   , name(map,replace) ytitle(Frequencies)  ylabel(0(`=`maxi'/5')`maxi' ,axis(2)) ylabel(0(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title(Individuals/items representations (Map)) xsize(12) ysize(9) note(Red line: Information curve - Green line : Density of the latent trait) xtitle(Latent trait) `fsm'"
+		*graph combine TIC IIC,  col(1)
+		*graph save "map" "map.gph", replace
+		*discard
+		*qui graph twoway line TInf u , name(map,replace)
+		*qui graph twoway `scatterj'  , name(map2,replace) ytitle("")   ylabel(`ylbl', grid angle(0))  legend(off) xsize(12) ysize(9) 
+		*su
+*list eff u if eff!=0
+*browse
+		qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`floor'(1)`ceil') color(erose)) (line TInf u,yaxis(2) lwidth(medthick)) (line density u,yaxis(3) lwidth(medthick) )  `scatterj'  , xline(0, lcolor(black)) legend(on position(6) order(`"`legend'"') rows(1) subtitle(Threshold parameters) size(small)) name(map,replace) ytitle("                           Frequencies")  ylabel(0(`=`maxi'/5')`maxi' `maxi'(`maxi')`=`maxi'*2' ,axis(2)) yscale(axis(2) off) yscale(axis(3) off)  ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) yline(0,lwidth(thick) lcolor(black))  ylabel(`ylbl',/*noticks*/ grid angle(0) axis(1)) ylabel(`ylbl' 0(`=`maxe'/5')`maxe', grid angle(0) axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait - * : dysfunctioning items") xtitle("Latent trait") `fsm'
+*qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`floor'(1)`ceil') color(erose)), name(jbh,replace)
+		*histogram u,  name(map,replace)
+		*graph use "map.gph", name(map, replace)
+		*graph combine TIC IIC, xcombine col(1)
+	}
+	qui use `savefile', clear
+}
+		 
+
+
+/*************************************************************************************************************
+Best estimates by category 
+*************************************************************************************************************/
+
+tempname bestest
+matrix `bestest'=J(`nbitems',`=`modamax'+1',.)
+di
+local long=`modamax'*8+33
+di
+di "Best estimates by answer category" 
+di "{hline `long'}"
+di "Item" _col(29) "Cat 0"  _c
+forvalues j=1/`modamax' {
+     local col=29+`j'*8 
+	 di _col(`col') "Cat `j'"     _c
+}
+di
+di "{hline `long'}"
+forvalues i=1/`nbitems' {
+    di "``i''" _c
+	forvalues j=0/`modamax`i'' {
+	    di _col(`=28+`j'*8') %6.3f round(`bestest``i''_`j'', 0.001) _c
+		matrix `bestest'[`i',`=`j'+1']=`bestest``i''_`j''
+	}
+	di
+}
+di "{hline `long'}"
+		
+
+
+/*************************************************************************************************************
+EQUATING
+*************************************************************************************************************/
+*set trace on
+if "`eqset1'"!="" {
+
+    tokenize `eqset1'
+	local nbset1: word count `eqset1'
+	forvalues i=1/`nbset1' {
+	   local eq1_`i':word `i' of `eqset1'
+	   *di "set1 (`nbset1') : `eq1_`i''"
+	}
+	*di "`eqset1'"
+    tokenize `eqset2'
+	local nbset2: word count  `eqset2'
+	*di "`eqset2'"
+	forvalues i=1/`nbset2' {
+	   local eq2_`i':word `i' of `eqset2'
+	   *di "set2  (`nbset2') : `eq2_`i''"
+	}	
+
+
+
+	tempfile fileeq
+	qui save `fileeq',replace
+	forvalues t=1/2{
+		local scoremaxset`t'=0
+		forvalues i=1/`nbset`t'' {
+		    *di "`eq`t'_`i''"
+			*local tmp=""
+			local scoremaxset`t'=`scoremaxset`t''+`modamax`eq`t'_`i'''
+		}
+	}
+	drop _all
+	*set trace on
+	qui set obs `=(`scoremaxset1'+`scoremaxset2'+2)*3'
+	forvalues t=1/2 {
+		qui gen scoreset`t'=.
+		qui gen scoreset`t'm=.
+		qui gen scoreset`t'p=.	
+	}
+	forvalues i=0/`scoremaxset1' {
+	    qui replace scoreset1=`i' in `=`i'+1'
+	    qui replace scoreset1m=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset1p=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	forvalues i=`=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2' {
+	    qui replace scoreset2=`i'-`scoremaxset1'-2 in `i'
+	    qui replace scoreset2m=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset2p=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	local s=0
+	local eqset1b
+	foreach i in `eqset1' {
+		qui gen s1_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s1_`i'_`m'=0 in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'_`m'=1 if scoreset1>`s' in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'=s1_`i'+s1_`i'_`m'
+		   local ++s
+		}
+	    local eqset1b `eqset1b' s1_`i'
+	}
+	local s=0
+	local eqset2b
+	foreach i in `eqset2' {
+		qui gen s2_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s2_`i'_`m'=0 in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'_`m'=1 if scoreset2>`s' in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'=s2_`i'+s2_`i'_`m'
+		   local ++s
+		}
+		local eqset2b `eqset2b' s2_`i'
+	}
+	tokenize `varlist'
+	tempname diffset1 diffset2
+	*matrix list `diffmat'
+	forvalues t=1/2 {
+		qui matrix `diffset`t''=J(`nbset`t'',`modamax',.)
+		local n=1
+		local listset`t'
+		foreach j in `eqset`t'' {
+			forvalues i=1/`nbitems' {
+				if "`j'"=="``i''" {
+					local listset`t' `listset`t'' `i'
+					forvalues m=1/`modamax' {
+						qui matrix `diffset`t''[`n',`m']=`diffmat'[`i',`m']
+					}
+					local ++n						
+				}
+			}
+		}
+	}
+	*matrix list `diffset1'
+	*matrix list `diffset2'
+	local var=`covariates'[1,1]
+	qui gen lt=.
+	*qui gen selt=.
+	forvalues t=1/2 {
+		tempname matscorelt`t'
+		qui pcm `eqset`t'b', diff(`diffset`t'') var(`var') minsize(1)
+		qui matrix `matscorelt`t''=r(matscorelt)
+		*di "matscorelt`t':"
+		*matrix list `matscorelt`t''
+		forvalues i=0/`scoremaxset`t'' {
+			qui replace lt=`matscorelt`t''[`=`i'+1',2] if scoreset`t'==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]+1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'p==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]-1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'm==`i'
+			*qui replace selt=`matscorelt`t''[`=`i'+1',3] if scoreset`t'==`i'
+		}
+		qui ipolate scoreset`t' lt, gen(score`t') epolate
+	}
+	qui ipolate scoreset1 lt, gen(score1bis) epolate
+
+
+	*list
+	forvalues t=1/2 {
+		qui replace score`t'=scoreset`t'm if scoreset`t'm!=.
+		qui replace score`t'=scoreset`t'p if scoreset`t'p!=.
+		qui replace score1=score1bis if score1==.
+		qui replace score`t'=0 if score`t'<0
+		qui replace score`t'=`scoremaxset`t'' if score`t'>`scoremaxset`t''
+	}
+	forvalues t=1/2 {
+		tempname matscore`t'
+		qui matrix `matscore`t''=J(`=`scoremaxset`t''+1',7,.)
+		forvalues s=0/`scoremaxset`t'' {
+		    qui matrix `matscore`t''[`=`s'+1',1]=`s'
+			qui su lt if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',2]=r(mean)
+			qui su lt if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',3]=r(mean)
+			qui su lt if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',4]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',5]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',6]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',7]=r(mean)
+		}
+		matrix colnames `matscore`t'' =score`t' lt lt- lt+ score`=3-`t'' score`=3-`t''- score`=3-`t''+
+		*matrix list `matscore`t''
+		di
+		di "{hline 78}"
+		di "EQUATING SET`t' TO SET`=3-`t''"
+		di "{hline 78}"
+		di "Set`t' : `eqset`t''"
+		di "Set`=3-`t'' : `eqset`=3-`t'''"
+		di "{hline 78}"
+		di            _col(20) "<----- Latent trait ----->" _col(52) "<------- Score `=3-`t'' --------->"
+		di "Score`t'" _col(20) "Estimated" _col(39) "[95%IC]" _col(52) "Estimated" _col(72) "[95%IC]"
+		di "{hline 78}"
+		forvalues s=0/`scoremaxset`t'' {
+			di %4.0f `matscore`t''[`=`s'+1',1] _col(24) %5.2f `matscore`t''[`=`s'+1',2] _col(33) "[" %5.2f `matscore`t''[`=`s'+1',3] ";" %5.2f `matscore`t''[`=`s'+1',4] "]" _col(56) %5.2f `matscore`t''[`=`s'+1',5] _col(66) "[" %5.2f `matscore`t''[`=`s'+1',6] ";" %5.2f `matscore`t''[`=`s'+1',7] "]"
+		}
+		di "{hline 78}"
+		return matrix score`t'_to_`=3-`t''=`matscore`t''
+		if "`eqgraph'"!="" {
+			*twoway (line lt scoreset1) (line lt scoreset2), name(eq1)
+			*twoway (line scoreset1 scoreset2 lt) , name(eq2)
+			*twoway (line score1 scoreset1m scoreset1p score2), name(eq3)
+			*twoway (line score2 scoreset2m scoreset2p score1), name(eq4)
+			twoway (line score`t' score`=3-`t'' if scoreset`=3-`t''!=.) (line score`t' score`=3-`t'' if scoreset`=3-`t''m!=.) (line score`t' score`=3-`t'' if scoreset`=3-`t''p!=.), title("Equating score of the Set `t' from the Set `=3-`t''") ytitle("Score `t'") xtitle("Score `=3-`t''") ylabel(0(1)`scoremaxset`t'') xlabel(0(1)`scoremaxset`=3-`t''') name(eq`t'to`=3-`t'')
+			*twoway (line score2 score1 if scoreset1!=.) (line score2 score1 if scoreset1m!=.) (line score2 score1 if scoreset1p!=.), name(eq6)
+		}
+	}
+	*save prout, replace
+	*clear
+	
+	qui use `fileeq',clear
+}
+
+
+/*************************************************************************************************************
+RETOUR AU FICHIER INITIAL ET SAUVEGARDE DES NOUVELLES VARIABLES
+*************************************************************************************************************/
+if "`visit'"!="" {
+	tempfile sauv
+	set trace on
+	*tempname corrlatent corrbilatent
+	qui keep `latent'* `selatent'* `id' `visit' 
+    qui reshape wide , i(`id') j(`visit')
+	qui sort `id'	
+	qui save `sauv', replace
+	restore,preserve
+	if "`replace'"!=""&("`genlt'"!=""|"`geninf'"!="") {
+    	capture drop `genlt' 
+    	capture drop `genlt'_se 
+    	capture drop `geninf' 
+    	capture drop `genlt'_corr
+    	capture drop `genlt'_opt
+    	capture drop `genlt'_opt_se
+    }
+	*su
+	tempname idorder
+	qui gen `idorder'=_n
+	qui sort `id'
+	qui merge 1:1 `id' using `sauv'
+	
+	qui sort `idorder'
+    qui drop `idorder'	
+}
+else {
+*set trace on
+*set tracedepth 1
+    if "`genlt'"!="" {
+		qui gen `genlt'_corr=.
+		forvalues s=0/`scoremax' {
+			qui replace `genlt'_corr=`estlt`s'' if `score'==`s'
+		}
+		forvalues g=1/`nbgroups' {
+			qui replace `genlt'_corr=`clt`g'' if `group'==`g'&`genlt'_corr==.
+		}
+		tempvar tmpitem mean nbnonmiss
+		forvalues i=1/`nbitems' {
+			qui gen `tmpitem'_`i'=.
+			forvalues k=0/`modamax' {
+				qui replace `tmpitem'_`i'=`bestest'[`i',`=`k'+1'] if ``i''==`k'
+			}
+		}
+		*su
+		qui egen `genlt'_opt=rowmean(`tmpitem'_*)
+		qui egen `genlt'_opt_se=rowsd(`tmpitem'_*)
+		qui egen `nbnonmiss'=rownonmiss(`tmpitem'_*)
+		qui replace `genlt'_opt_se=sqrt((`genlt'_opt_se^2+`resvar')/`nbnonmiss')
+ 	}
+	restore,not
+}
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin
+	putdocx paragraph
+	putdocx text ("General informations") , bold underline font(,14) smallcaps
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph
+	putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	qui putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx paragraph
+	putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
+	qui putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+return matrix matscorelt=`matscorelt'
+return matrix bestest=`bestest'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm 5.2.ado b/Modules/ado/personal/p/pcm 5.2.ado
new file mode 100644
index 0000000..2bac1f8
--- /dev/null
+++ b/Modules/ado/personal/p/pcm 5.2.ado	
@@ -0,0 +1,1958 @@
+*! Version 5.2 16July2023
+*! Jean-Benoit Hardouin, Myriam Blanchin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
+* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
+* Version 4.1: September 15th, 2019 [Jean-Benoit Hardouin]: correction of a small bug in the outputs
+* Version 4.2: September 27th, 2019 [Jean-Benoit Hardouin] : EQUATING
+* Version 4.3: November 8th, 2019 [Jean-Benoit Hardouin] : add a constant when difficulty parameters are fixed
+* Version 5: August 2nd, 2022 [Jean-Benoit Hardouin] : New MAP graph, corrected estimation of the latent trait
+* Version 5.1: July 8th, 2023 [Jean-Benoit Hardouin] : Correction of the MAP graph (histogram) and residuals graphs
+* Version 5.2: July 16th, 2023 [Jean-Benoit Hardouin] : Add of new graphs for Equating
+*
+*
+* Jean-benoit Hardouin, Myriam Blanchin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr, myriam.blanchin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019, 2022, 2023 Jean-Benoit Hardouin, Myriam Blanchin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [if] [in] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) VARiance(real -1) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(string) GENINF(string) REPlace postpce visit(varname) id(varname) eqset1(varlist) eqset2(varlist) eqset1name(string) eqset2name(string) EQGraph eqaddset1(real 0) eqaddset2(real 0) eqmultset1(real 1) eqmultset2(real 1) eqwithic eqgenscore(string)  subtitle(string) minsize(int 30)]
+
+preserve
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+/*************************************************************************************************************
+QUELQUES TESTS
+*************************************************************************************************************/
+
+if `variance'!=-1&`variance'<=0 {
+	di in red "The -variance- option cannot be negative"
+	exit 198
+}
+if `variance'!=-1&"`visit'"!="" {
+	di in red "The -variance- and -visit- options cannot be used simultaneously."*
+	exit 198
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' `genlt'_se `geninf' `genlt'_corr `genlt'_opt `genlt'_opt_se 
+	if _rc!=0&"`replace'"=="" {
+	    di in red "The variables `genlt', `genlt'_se, `genlt'_corr, `genlt'_opt, `genlt'_opt_se and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+	if _rc!=0&"`replace'"!="" {
+	    qui capture drop `genlt' 
+		qui capture drop `genlt'_se 
+		qui capture drop `geninf' 
+		qui capture drop `genlt'_corr
+		qui capture drop `genlt'_opt
+		qui capture drop `genlt'_opt_se
+	}
+}
+if ("`eqset1'"!=""&"`eqset2'"=="")|("`eqset1'"==""&"`eqset2'"!="") {
+    di in red "The two options -eqset1- and -eqset2- must be used simultaneously"
+	exit 198
+}
+if ("`eqset1'"!=""&"`graphs'"!="") {
+    di in red "The two options -eqset1- and -graph- cannot be used simultaneously"
+	exit 198
+}
+
+
+
+
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+if "`visit'"!=""{
+	if "`id'"==""{
+		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
+		exit 198
+	}
+	qui levelsof `visit'
+	local levelsofv `r(levels)'
+	local nbvisits=r(r)
+	local timemin: word 1 of `levelsofv'
+	local timemax: word `nbvisits' of `levelsofv'
+	if `timemax'>5{
+		di as error "You must use a discrete time variable (-visit- option) with less than 5 measurement occasions"
+		error 198
+	}
+	if `timemin'!=1{
+		di as error "You must use a -visit- variable coded at 1 for the first visit"
+		error 198
+	}
+	qui reshape wide `varlist', i(`id') j(`visit')
+	local multivisit=1
+}
+else {
+	local timemax=1
+	foreach i in `varlist' {
+	   *rename `i' `i'1
+	}
+	local multivisit
+}
+qui count if `touse'
+local nbobs=r(N)
+
+local timelist
+forvalues t=1/`timemax'{
+	local timelist `timelist' T`t'
+}
+
+local modcont
+local premodcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local premodcont (`modcont'->T1)
+	local modcont (`modcont'->`timelist')
+}
+
+local modcat
+local premodcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local premodcat (`modcat'->T1)
+	local modcat (`modcat'->`timelist')
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+local scoremax=0
+forvalues i=1/`nbitems' {
+	local modamax`i'=1
+	local modamax``i''=1
+	if `timemax'>1 {
+		forvalues t=1/`timemax'{
+			 *qui replace ``i'`t''=``i'`t''-`min' 
+			 qui su ``i''`t' if `touse'
+			 if `r(min)'!=`modamin' {
+				 local modamin=r(min)
+				 local pbmin `pbmin' ``i'`t''
+			 }
+			 if `r(max)'>`modamax' {
+				 local modamax=r(max)
+			 }
+			 if `r(max)'>`modamax`i'' {
+				local modamax`i'=r(max)
+			}
+		}
+	}
+	else {
+		*di "i: `i' ``i''"
+		qui su ``i'' if `touse'
+		if `r(min)'!=`modamin' {
+		    local modamin=r(min)
+			local pbmin `pbmin' ``i''
+		}
+		if `r(max)'>`modamax' {
+			local modamax=r(max)
+		}
+		if `r(max)'>`modamax`i'' {
+			local modamax`i'=r(max)
+			local modamax``i''=r(max)
+		}
+	}
+	*di "local scoremax=`scoremax'+`modamax`i''"
+	local scoremax=`scoremax'+`modamax`i''
+	if "`rsm'"=="" {
+		local nbdiff=`nbdiff'+`modamax`i''
+	}
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count if `touse'
+local nbind=r(N)
+*set trace on
+local code
+local precode
+if `timemax'>1 {
+	forvalues k=1/`modamax' {
+	   forvalues t=1/`timemax'{
+			local code`k'
+		   forvalues i=1/`nbitems' {
+			   if `k'<=`modamax`i'' {
+				  local code`k' `code`k'' `k'.``i''`t'
+			   }
+		   }
+		   local code`k' (`code`k''<-T`t'@`k')
+		   if `t'==1{
+				local precode `precode' `code`k''
+		   }
+		   local code `code' `code`k''
+		}
+	}
+}
+else {
+	forvalues k=1/`modamax' {
+		local code`k'
+		forvalues i=1/`nbitems' {
+			if `k'<=`modamax`i'' {
+				local code`k' `code`k'' `k'.``i''
+			}
+		}
+		local code`k' (`code`k''<-T1@`k')
+		local precode `precode' `code`k''
+		local code `code' `code`k''
+	}
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist' if `touse'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist' if `touse', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+local t=1
+local constraints
+local codemean
+local codevar
+local codecov
+forvalues j=2/`timemax'{
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			qui constraint `t' [`k'.``i''`j']_cons=[`k'.``i''`multivisit']_cons
+			local constraints `constraints' `t'
+			local ++t
+			
+		}
+	}	
+	if "`continuous'"=="" &  "`categorical'"==""{
+		local codemean `codemean' T`j'@m`j'
+		local codevar `codevar' T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' T`l'*T`j'@cov`l'`j'
+		}
+	}
+	else{
+		local codevar `codevar' e.T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
+		}	
+	}
+}
+if `timemax'>1{
+	if "`continuous'"=="" &  "`categorical'"==""{	
+		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
+	}
+	else{
+		local codelg var(e.T1@v1 `codevar') cov(`codecov')
+	}
+}
+else {
+    local constrvar
+    if `variance'>0 {
+		if "`continuous'"=="" &  "`categorical'"==""{	
+			local constrvar var(T1@`variance') 
+		}
+		else{ 
+			*local constrvar var(e.T1@`variance') 
+		}
+	}
+}
+
+local fixedmean
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				qui constraint `t' [`k'.``i''`multivisit']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+	if "`continuous'"=="" &  "`categorical'"=="" {	
+		local fixedmean mean(T1) 
+	}
+	else{
+		local fixedmean 
+	}
+}
+
+
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+if "`rsm'"!="" {
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       qui constraint `t'   [`=`k'-1'.``i''`multivisit']_cons-[`k'.``i''`multivisit']_cons+[1.``i''`multivisit']_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
+if "`model'"!="" {
+    local qui
+}
+else {
+	local qui qui
+}
+if `timemax'==1{
+   *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'"
+   `qui' gsem `code' `modcont' `modcat' if `touse' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+   *qui gen un=1
+   *`qui' gsem `code' (i.group un->T) ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+}
+else{
+    *di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
+    `qui' gsem `precode' `premodcont' `premodcat' if `touse',iterate(`iterate') tol(`tolerance') constraint(`constraints') 
+     matrix esti_B = e(b)
+    *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)"
+    `qui' gsem `code' `modcont' `modcat' if `touse',iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
+}
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2 miss
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent'* if `touse',latent se(`selatent'*)
+*di "latent=`latent' "
+*su
+*set trace on
+
+if "`genlt'"!="" {
+	if `timemax'==1 {
+		qui gen `genlt'=`latent'1 if `touse'
+		qui gen `genlt'_se=`selatent'1 if `touse'
+	}
+	forvalues t=2/`timemax' {
+		qui gen `genlt'`t'=`latent'`t' if `touse'
+		qui gen `genlt'`t'_se=`selatent'`t' if `touse'
+	}
+}
+
+set seed 123456
+if `timemax'>1 {
+	forvalues t=1/`timemax'{
+		qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t' if `touse'
+		local listit 
+		forvalues i=1/`nbitems' {
+			local listit `listit' ``i''`t'
+		}
+		qui genscore `listit' if `touse',score(`score'`t')
+		qui gengroup `latent'`t' if `touse',newvariable(`group'`t') continuous minsize(`minsize')
+	}
+}
+else {
+	qui gen `latent2'=`latent'1+invnorm(uniform())*`selatent'1 if `touse'
+	local listit 
+	forvalues i=1/`nbitems' {
+		local listit `listit' ``i''
+	}
+	qui genscore `listit' if `touse',score(`score')
+	qui gengroup `latent'1 if `touse',newvariable(`group') continuous minsize(`minsize')
+}
+forvalues s=0/`scoremax' {
+    qui count if `score'==`s'&`touse'
+	local effscore`s'=r(N)
+}
+
+
+/*time 1 only*/
+qui levelsof `group'`multivisit' if `touse'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+6',.)
+forvalues g=1/`nbgroups' {
+	matrix `groups'[`g',`=`nbitems'+3']=0
+	qui count if `group'`multivisit'==`g'&`touse'
+	local effgroup`g'=r(N)
+	forvalues i=1/`nbitems' {
+			qui count if ``i''`multivisit'!=.&`group'`multivisit'==`g'&`touse'
+			local n=r(N)
+			if `n'>0 {
+				qui su ``i''`multivisit' if `group'`multivisit'==`g'&`touse'
+				matrix `groups'[`g',`i']=r(mean)
+				matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+			}
+			else {
+				matrix `groups'[`g',`i']=.
+				matrix `groups'[`g',`=`nbitems'+3']=.
+			}		
+	}
+	qui su `latent'1 if `group'`multivisit'==`g'&`touse'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'`multivisit'==`g'&`touse'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+	qui su `score' if `group'`multivisit'==`g'&`score'!=.&`touse'
+	matrix `groups'[`g',`=`nbitems'+4']=r(min)
+	matrix `groups'[`g',`=`nbitems'+5']=r(max)	
+}
+
+/*number of non-missing on all time points*/
+egen `miss'=rowmiss(`score'*) if `touse'
+qui count if `miss'==0&`touse'
+local nbobsssmd=r(N)
+drop `miss'	
+
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i''`multivisit':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i''`multivisit':_cons]
+	qui lincom -_b[1.``i''`multivisit':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+	local rn `rn' 1.``i''`multivisit'
+	local ++t
+	local sum _b[1.``i''`multivisit':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax`i'' {
+			local sum "_b[`k'.``i''`multivisit':_cons]-(`sum')"
+			*di "``i''`multivisit' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i''`multivisit':_cons]-_b[`k'.``i''`multivisit':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''`multivisit'
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1'`multivisit':_cons]-_b[`k'.`1'`multivisit':_cons]+_b[1.`1'`multivisit':_cons] /*``i'' instead of `i'?*/
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
+*************************************************************************************************************/
+tempname covariates
+local nbcov=0
+forvalues j=2/`timemax'{
+	local nbcov=`nbcov'+`j'-1
+}
+qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)
+
+*set trace on
+local t=1
+
+
+forvalues j=1/`=`timemax'-1'{
+	forvalues k=`=`j'+1'/`timemax'{
+		if "`categorical'"=="" & "`continuous'"=="" {
+			if `j'==1{
+				qui lincom [/]mean(T`k')
+			}
+			else{
+				qui lincom [/]mean(T`k')-[/]mean(T`j')
+			}
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+		else{
+			if "`categorical'"!=""{
+				local first=0 
+				foreach l in `levelsof`cat1'' {
+					if `first'==0 {
+						local ++first
+					}
+					else{
+						if `first'==1 {
+							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
+							qui matrix `covariates'[`t',1]=`r(estimate)'
+							qui matrix `covariates'[`t',2]=`r(se)'
+							qui matrix `covariates'[`t',3]=`r(z)'
+							qui matrix `covariates'[`t',4]=`r(p)'
+							qui matrix `covariates'[`t',5]=`r(lb)'
+							qui matrix `covariates'[`t',6]=`r(ub)'
+							local ++t
+							local ++first
+						}
+					}
+				}
+			}
+			else{
+				qui lincom [T`k']`cont1'-[T`j']`cont1'
+				qui matrix `covariates'[`t',1]=`r(estimate)'
+				qui matrix `covariates'[`t',2]=`r(se)'
+				qui matrix `covariates'[`t',3]=`r(z)'
+				qui matrix `covariates'[`t',4]=`r(p)'
+				qui matrix `covariates'[`t',5]=`r(lb)'
+				qui matrix `covariates'[`t',6]=`r(ub)'
+				local ++t
+			}		
+		}
+	}
+}	
+		
+forvalues j=1/`timemax'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		qui lincom _b[/var(e.T`j')]
+	}
+	else {
+		qui lincom _b[/var(T`j')]
+	}
+	qui matrix `covariates'[`t',1]=`r(estimate)'
+	qui matrix `covariates'[`t',2]=`r(se)'
+	qui matrix `covariates'[`t',3]=`r(z)'
+	qui matrix `covariates'[`t',4]=`r(p)'
+	qui matrix `covariates'[`t',5]=`r(lb)'
+	qui matrix `covariates'[`t',6]=`r(ub)'
+	local ++t
+}
+forvalues j=1/`=`timemax'-1'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(e.T`j',e.T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+	else{
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(T`j',T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+}
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+*matrix list `covariates'
+
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 83}"
+	di  as text _col(70) "<--95% IC -->"
+	di   _col(70) "Lower" _col(78) "Upper"
+	di "Items" _col(22) "Threshold" _col(35) "Estimate" _col(47) "s.e." _col(58) "z" _col(66) "p" _col(69) " Bound" _col(78) "Bound"
+	di "{hline 83}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax`i'' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %5.2f `diff'[`t',3] _col(62) %5.2f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %5.2f `diff'[`t',3] _col(62) %5.2f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 83}"
+	local t=1
+	local listmoy
+	local listvar
+	local listcov
+	forvalues j=1/`timemax'{
+		local listvar `listvar' Variance_T`j'
+		forvalues k=`=`j'+1'/`timemax'{
+			local listcov `listcov' Cov_T`j'_T`k'
+		}
+		forvalues k=`=`j'+1'/`timemax'{
+			local listmoy `listmoy' Mean_diff_T`j'_T`k'
+		}
+	}
+	local n: word count `listmoy' `listvar' `listcov' `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of `listmoy' `listvar' `listcov' `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %5.2f `covariates'[`t',3] _col(62) %5.2f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %5.2f `covariates'[`t',3] _col(62) %5.2f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		*local ++t
+	}
+	di as text "{hline 83}"
+	if "`visit'"==""{
+		di
+		qui su `latent'1 if `touse'
+		*qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])+(`r(sd)')^2)
+		*di as text "Variance of the estimated latent variable: " as result %4.2f `=(`r(sd)')^2'
+        tempvar se2latent
+		qui gen `se2latent'=(`selatent'1)^2 if `touse'
+		qui su `se2latent' if `touse'
+		local resvar=r(mean)
+		di as text "Mean squared std error of the latent variable: " as result %4.2f `resvar'
+		di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`resvar'))'
+		local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`resvar'))
+		di as text "PSI: " as result %4.2f `PSI' _c
+		if "`continuous'"!=""|"`categorical'"!="" {
+		    di as text " (without adjustment on covariates)"
+	    }
+		else {
+		    di
+		}
+		di
+		return scalar PSI=`PSI'
+
+	}
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+if "`visit'"==""{
+	tempname fit
+	qui matrix `fit'=J(`nbitems',4,.)
+	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+	matrix rownames `fit'=`varlist'
+	*matrix list `fit'
+
+	tempvar Tcum TInf cum
+	qui gen `Tcum'=0 if `touse'
+	qui gen `TInf'=0 if `touse'
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text _col(60) "<---  Standardized   --->"
+		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+		di as text "{hline 90}"
+		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "{hline 90}"
+	}
+	*set trace on
+	local chi2=0
+	local chi2_old=0
+	forvalues g=1/`nbgroups' {
+	   local chi2_g`g'=0
+	   local chi2_old_g`g'=0
+	}
+	forvalues i=1/`nbitems' {
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+		local d=1
+		local d_old=1
+		qui gen `cum``i'''=0 if `touse'
+		qui gen `cum_old``i'''=0 if `touse'
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+			local d_old `d_old'+exp(`k'*`latent'1-`diffmat2'[`i',`k'])
+		}
+		qui gen `c0_``i'''=1/(`d') if `touse' 
+		qui gen `c_old0_``i'''=1/(`d_old') if `touse'
+		forvalues k=1/`mm' {
+			tempvar c`k'_``i'' c_old`k'_``i''
+			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d') if `touse'
+			qui gen `c_old`k'_``i'''=exp(`k'*`latent'1-`diffmat2'[`i',`k'])/(`d') if `touse'
+			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k' if `touse'
+			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k' if `touse'
+		}
+		qui gen `Inf``i'''=0 if `touse'
+		qui gen `Inf_old``i'''=0 if `touse'
+		qui gen `C``i'''=0 if `touse'
+		forvalues k=0/`mm' {
+			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i''' if `touse'
+			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i''' if `touse'
+			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i''' if `touse'
+		}
+		qui count if ``i''!=.&`touse'
+		local n``i''=r(N)
+		
+		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2) if `touse'
+		qui su `C2``i''' if `touse'
+		local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2 if `touse'
+		qui su `C3``i'''
+		local n=r(sum)
+		qui su `Inf``i''' if `touse'
+		local d=r(sum)
+		local q2i``i''=`n'/((`d')^2)
+		
+		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+		
+		qui replace `Tcum'=`Tcum'+`cum``i''' if `touse'
+		qui replace `TInf'=`TInf'+`Inf``i''' if `touse'
+		qui gen `y``i'''=``i''-`cum``i''' if `touse'
+		qui gen `y_old``i'''=``i''-`cum_old``i''' if `touse'
+		qui gen `y2``i'''=(`y``i''')^2 if `touse'
+		qui gen `y2_old``i'''=(`y_old``i''')^2 if `touse'
+		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i''')) if `touse'
+		local chi2_``i''=0
+		local chi2_old_``i''=0
+		forvalues g=1/`nbgroups' {
+			qui su `y2``i''' if `group'==`g'&`touse'
+			local n=r(sum)
+			qui su ``i'' if `group'==`g'&`touse'
+			local n1=r(sum)
+			qui su `cum``i''' if `group'==`g'&`touse'
+			local n2=r(sum)
+			qui su `Inf``i''' if `group'==`g'&`touse'
+			local d=r(sum)
+			*qui count if `group'==`g'
+			*local eff=r(N)
+			*di "chi2_`g'_``i''=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')"
+			local chi2=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_``i''=`chi2_``i'''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_g`g'=`chi2_g`g''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			qui su `y2_old``i''' if `group'==`g'&`touse'
+			local n_old=r(sum)
+			qui su ``i'' if `group'==`g'&`touse'
+			local n1_old=r(sum)
+			qui su `cum_old``i''' if `group'==`g'&`touse'
+			local n2_old=r(sum)
+			qui su `Inf_old``i''' if `group'==`g'&`touse'
+			local d_old=r(sum)
+			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+		}
+		*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+		*su `z``i'''
+		label variable `z``i''' "Standardized residuals associated to ``i''"
+		label variable `latent'1 "Latent trait"
+		*set trace on
+		if  "`graphs'"!=""&"`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fs saving("`dirsave'//residuals_``i''",replace)
+			}
+			tempvar id``i''
+			qui gen `id``i'''=_n if abs(`z``i''')>2*sqrt(`covariates'[1,1])&`touse'
+			qui tostring `id``i''',replace
+			qui replace `id``i'''="" if `id``i'''=="."&`touse'
+			qui su `z``i''' if `touse'
+			local min=r(min)
+			local max=r(max)
+			local min=floor(min(`min',`=-2*sqrt(`covariates'[1,1])'))
+			local max=ceil(max(`max',`=2*sqrt(`covariates'[1,1])'))
+			
+			qui graph twoway scatter `z``i''' `latent' if `touse', yscale(range(`min'(1)`max')) yline(`=-2*sqrt(`covariates'[1,1])' `=2*sqrt(`covariates'[1,1])',lcolor(blue)) mlabel(`id``i''') name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+		}
+		*set trace off 
+		qui gen `z2``i'''=(`z``i''')^2 if `touse'
+		qui su `z2``i''' if `touse'
+		local OUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',1]=`OUTFIT``i'''
+		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `Inf``i''' if ``i''!=.&`touse'
+		local sumw``i''=r(sum)
+		qui gen `i``i'''=`Inf``i'''*`z2``i''' if `touse' 
+		qui su `i``i''' if ``i''!=.&`touse'
+		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+		qui matrix `fit'[`i',2]=`INFIT``i'''
+		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		qui matrix `fit'[`i',4]=`INFITs``i'''
+		if "`postpce'"=="" {
+			di "``i''" _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+		}
+	}
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text "*: As suggested by Wright (Smith, 1998)"
+		di as text "**: As suggested by Bond and Fox (2007)"
+	}
+	if "`geninf'"!="" {
+	    gen `geninf'=`TInf' if `touse'
+	}
+}
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Iteration `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1') if `touse'
+		`qui' pcm `varlist' [iweight=`sinf'] if `touse',diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1') if `touse'
+		qui su `ecart_`it'' if `touse'
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+/*************************************************************************************************************
+ESTIMATION OF THE CORRECTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+tempfile savefile
+qui save `savefile'
+
+qui drop _all
+		
+qui set obs 2000
+qui gen u=(_n-1000)/200*`=sqrt(`covariates'[1,1])'
+qui gen Tcum=0
+qui gen TInf=0
+forvalues i=1/`nbitems' {
+		local d=1
+		qui gen cum``i''=0
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+		}
+		qui gen c0_``i''=1/(`d')
+		forvalues k=1/`mm' {
+			qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+			qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+		}
+		qui gen Inf``i''=0
+		forvalues k=1/`mm' {
+			qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+		}
+		qui replace Tcum=Tcum+cum``i''
+		qui replace TInf=TInf+Inf``i''	
+	    local scoremax=0
+		forvalues i=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`i''
+	    }
+		qui gen ecart=.
+		forvalues i=0/`scoremax' {
+		    if `i'==0 {  
+			   local j=0.25
+			}
+			else if `i'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`i'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`i'=`r(mean)'
+		}
+		qui drop ecart
+}
+qui use `savefile', clear
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+if "`visit'"==""{
+*set trace on
+    tempname matscorelt
+	qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)
+	di
+	di as text "{hline 71}"
+	di _col(32) "Latent Trait" _col(50) "Expected" _col(63) "Corrected"
+	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score" _col(60) "latent trait"
+	di as text "{hline 71}"
+	forvalues g=1/`nbgroups' {
+		local sumuc=0
+		local sumc=0
+		qui count if `group'`multivisit'==`g'&`touse'
+		local eff`g'=r(N)
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'!=.&`touse'
+		local effcompleted`g'=r(N)
+		qui count if `score'`multivisit'!=.&`group'`multivisit'==`g'&`touse'
+		local n=r(N)
+		di as text "`g' (n=" as result `eff`g'' as text ")" _c
+		if `n'>0 {
+			qui su `score'`multivisit' if `group'`multivisit'==`g'&`touse'
+			local scoremin`g'=`r(min)'
+			local scoremax`g'=`r(max)'
+			forvalues s=`scoremin`g''/`scoremax`g'' {
+				qui count if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local eff=r(N)
+				local effscore`s'=r(N)
+				if `eff'!=0 {
+					qui su `latent'1 if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+					local mean=r(mean)
+					*di "local ltscore`s'=`=ceil(`r(mean)'*100)/100'"
+					local ltscore`s'=`=ceil(`r(mean)'*100)/100'
+					*di "local sumc=`sumc'+(`eff')*(`estlt`s'')"
+					*di "local sumuc=`sumuc'+(`eff')*(`mean')"
+				    local sumuc=(`sumuc'+((`eff')*(`mean')))
+				    local sumc=(`sumc'+((`eff')*(`estlt`s'')))
+				}
+				qui su `selatent'1 if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local se=r(mean)
+				qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local exp=r(mean)
+				if `eff'>0 {
+				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp' _col(66) %6.3f `estlt`s''
+				}
+				qui matrix `matscorelt'[`=`s'+1',1]=`s'
+				qui matrix `matscorelt'[`=`s'+1',2]=`mean'
+				qui matrix `matscorelt'[`=`s'+1',3]=`se'
+			}
+			
+		}
+		*set trace on
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+		local eff=r(N)
+		local eff_md_`g'=r(N)
+		if `eff'!=0 {
+			qui su `latent'1 if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local mean=r(mean)
+			local lt_md_`g'=r(mean)
+			local sumuc=(`sumuc'+((`eff')*(`mean')))
+			qui su `selatent'1 if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local se=r(mean)
+			qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local exp=r(mean)
+			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+		}
+		*set trace off
+		*di "local lt`g'=`sumuc'/`eff`g''"		
+		*di "local clt`g'=`sumc'/`effcompleted`g''"
+		local lt`g'=(`sumuc')/(`eff`g'')
+		local clt`g'=(`sumc')/(`effcompleted`g'')
+		matrix `groups'[`g',`=`nbitems'+6']=`clt`g''
+		*di "group `g' est=`lt`g'' corrected est=`clt`g''"
+		di as text "         " "{dup 62:-}"
+		if "`scoremin`g''"=="" {
+			local scoremin`g' "."
+		}
+		if "`scoremax`g''"=="" {
+			local scoremax`g' "."
+		}
+		di  as text _col(10) "`scoremin`g''/`scoremax`g''" as result _col(20) %4.0f `eff`g'' _col(30) %6.3f `lt`g''  _col(66) %6.3f `clt`g''
+		di as text "{hline 71}"
+	}
+	*matrix list `matscorelt'
+}	
+
+
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+*set trace on
+if "`visit'"==""{
+	if "`graphs'"!=""|"`graphs'"=="" {
+
+		tempfile savefile
+		qui save `savefile'
+
+		*qui clear
+		qui drop _all
+		local pas=1000*round(`=sqrt(`covariates'[1,1])',0.001)
+		qui set obs `pas'
+		qui gen u=round((_n-`pas'/2)/(`pas'/10)*`=sqrt(`covariates'[1,1])',0.01)
+		*list u
+		qui gen Tcum=0
+		qui gen TInf=0
+		qui gen ecartcum=.
+		forvalues i=1/`nbitems' {
+		   local scatteri`i' 
+		   local scatteric`i' 
+		   forvalues g=1/`nbgroups' {
+			  local x=`groups'[`g',`=`nbitems'+1']
+			  local xc=`groups'[`g',`=`nbitems'+6']
+			  local y=`groups'[`g',`i']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			  local scatteric`i' `scatteric`i'' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off)
+			*set trace off
+			}
+			local d=1
+			qui gen cum``i''=0
+			*set trace on
+			if "`rsm'"=="" {
+				local mm=`modamax`i''
+			}
+			else {
+				local mm `modamax'
+			}	
+			forvalues k=1/`mm' {
+				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+			}
+			qui gen c0_``i''=1/(`d')
+			label variable c0_``i'' "Pr(``i''=0)"
+			forvalues k=1/`mm' {
+				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+				label variable c`k'_``i'' "Pr(``i''=`k')"
+			}
+			forvalues k=0/`mm' {
+			    if `k'==0 {
+				   local l=0.25
+				}
+				else if `k'==`mm' {
+				   local l=`k'-0.25
+				}
+				else {
+				   local l=`k'
+				}
+				qui replace ecartcum=abs(cum``i''-`l')
+				qui su ecartcum
+				qui su u if round(ecartcum,0.01)==round(`r(min)',0.01)
+				local bestest``i''_`k'=r(mean)
+				*di "item ``i'' cat `k' : est=`bestest``i''_`k''"
+			}
+			qui gen Inf``i''=0
+			forvalues k=0/`mm' {
+				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+			}
+			if "`graphitems'"=="" {
+				if "`filesave'"!="" {
+					local fsc saving("`dirsave'//CCC_``i''",replace)
+					local fsi saving("`dirsave'//ICC_``i''",replace)
+				}
+				if "`graphs'"!="" {
+					qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+					qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+					qui graph twoway line cum``i'' u, name(ICCc``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Corrected latent trait") `scatteric`i'' `fsi'
+				}
+			}
+			qui replace Tcum=Tcum+cum``i''
+			*tab Tcum
+			qui replace TInf=TInf+Inf``i''	
+			label variable Inf``i'' "``i''"
+		}
+	    local scoremax=0
+		forvalues i=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`i''
+	    }
+		qui gen ecart=.
+		forvalues i=0/`scoremax' {
+		    if `i'==0 {  
+			   local j=0.25
+			}
+			else if `i'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`i'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`i'=`r(mean)'
+			*di "score `i' : `r(mean)'"
+		}
+		if "`filesave'"!="" {
+			local fst saving("`dirsave'//TCC",replace)
+			local fsteo saving("`dirsave'//TCCeo",replace)
+			local fsi saving("`dirsave'//ICC",replace)
+			local fsti saving("`dirsave'//TIC",replace)
+			local fsm saving("`dirsave'//map",replace)
+		}
+		if "`graphs'"!="" {
+*qui save "C:\temp\info\info",replace
+			qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+			qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+			qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+		}
+		local scatteri
+		local scatteric
+		forvalues g=1/`nbgroups' {
+			local x=`groups'[`g',`=`nbitems'+1']
+			local xc=`groups'[`g',`=`nbitems'+6']
+			local y=`groups'[`g',`=`nbitems'+3']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			local scatteric `scatteric' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off)
+		}
+		if "`graphs'"!="" {
+			qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+			qui graph twoway line Tcum u , name(TCCceo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Corrrected latent trait") `scatteric' `fsteo'
+		}
+	}
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+	*set trace on
+	if "`graphs'"!=""|"eqset1"!="" {
+		gen eff=0
+		gen eff_md=0
+		local effmax=0
+			*gen uround=round(u,0.01)
+			*list uround
+		/*le bloc suivant Ă©tait pour avoir des batons par groupe*/
+		/*forvalues g=1/`nbgroups' {
+			local eff=`groups'[`g',`=`nbitems'+2']
+			if `groups'[`g',`=`nbitems'+2']>`effmax' {
+			   local effmax=`groups'[`g',`=`nbitems'+2']
+			}
+			local lat=round(`groups'[`g',`=`nbitems'+1'],0.01)
+			*di "replace eff=`eff' if round(u,0.01)==`lat'"
+			qui replace eff=`eff' if round(u,0.01)==`lat'
+		}*/
+		/*le bloc suivant est pour avoir des batons par score*/
+		qui gen uceil=ceil(u*100)/100
+		forvalues s=0/`scoremax' {
+			if `effscore`s''>`effmax' {
+			   local effmax=`effscore`s''
+			}
+			*di "`s' qui replace eff=`effscore`s'' if ceil(u*100)/100==`=round(`ltscore`s'',0.01)'"
+			qui replace eff=`effscore`s'' if round(u,0.01)==round(`ltscore`s'',0.01)
+		}
+		forvalues g=1/`nbgroups' {
+			*di "if `eff_md_`g''>`effmax' { (`lt_md_`g'')"
+			if `eff_md_`g''>`effmax' {
+			   local effmax=`eff_md_`g''
+			}
+			qui replace eff_md=`eff_md_`g'' if round(u,0.01)==round(`lt_md_`g'',0.01)
+		}
+
+		gen density=normalden(u)*sqrt(`covariates'[1,1])
+		label variable eff "Frequencies"
+		label variable u "Latent trait"
+		label variable TInf "Information curve"
+		label variable density "Density function of the latent trait"
+		local scatteri
+		local scatterj
+		local color 
+		qui su u if eff!=0|eff_md!=0
+		*set trace on
+		*set tracedepth 1
+		*if eff!=0|eff_md!=0 {
+			local floor=floor(`r(min)')
+			local ceil=ceil(`r(max)')
+		*}
+		*else  {
+		*	local floor=-10
+		*	local ceil=10
+		*}
+		local sep
+		local ylbl
+		forvalues i=1/`nbitems' {
+		   local color`i':word `i' of `color'
+		   local unit=round(`effmax'/`nbitems',1)
+		   local y=-`i'*`unit'             
+		   loca staritem
+		   local legend `"3 "1" "'
+		   forvalues l=1/`modamax' {
+			   if `l'>=2 {
+			      local legend `" `legend' `=2*`l'+1' "`l'" "'
+			   }			   
+			   local x=`diffmat'[`i',`l']
+			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+			   if `l'==1 {
+			      local xant=`x'
+			   }
+			   else {
+			      local xant=`diffmat'[`i',`=`l'-1']
+			   }
+			   if `xant'>`x' {
+				  local star *
+				  local staritem *
+			   }
+			   else {
+			      local star
+			   }
+			   local scatterj `" `scatterj' `sep' scatteri `y' `x'   , pstyle(p`l') || pci `y' `xant' `y' `x', pstyle(p1) color(black)"'
+			   local sep ||
+			   if `x'<`floor' {
+				  local floor=floor(`x')
+			   }
+			   if `x'>`ceil'&`x'!=. {
+				  local ceil=ceil(`x')
+			   }
+		   }
+   		   local ylbl `ylbl' `=-`i'*`unit'' "``i''`staritem'"
+		   local scatteri `scatteri' || scatteri `y' `=`floor'-2' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+		}
+		qui su eff
+		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+		qui su eff_md
+		local maxe_md=ceil(`=(floor(`r(max)'/10)+1)*10')
+		local maxe=max(`maxe',`maxe_md')
+		qui su TInf
+		local maxi=ceil(`r(max)')
+		qui su density
+		local maxd=round(`r(max)', 0.01)+0.01
+		qui drop if u<`floor'|u>`ceil'
+		*di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(0(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3)) `scatterj'   , name(map,replace) ytitle(Frequencies)  ylabel(0(`=`maxi'/5')`maxi' ,axis(2)) ylabel(0(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title(Individuals/items representations (Map)) xsize(12) ysize(9) note(Red line: Information curve - Green line : Density of the latent trait) xtitle(Latent trait) `fsm'"
+		*graph combine TIC IIC,  col(1)
+		*graph save "map" "map.gph", replace
+		*discard
+		*qui graph twoway line TInf u , name(map,replace)
+		*qui graph twoway `scatterj'  , name(map2,replace) ytitle("")   ylabel(`ylbl', grid angle(0))  legend(off) xsize(12) ysize(9) 
+		*su
+*list eff u if eff!=0
+*browse
+		if "`eqset1'"==""&"`graphs'"!="" {
+		    *list eff u uceil if eff!=0&eff!=.
+			*save tmp, replace
+			qui graph twoway (bar eff u,  barwidth(.1) yaxis(1) xlabel(`floor'(1)`ceil') color(erose) ) (line TInf u,yaxis(2) lwidth(medthick)) (line density u,yaxis(3) lwidth(medthick) lcolo(green) ) (bar eff_md u,  barwidth(.05) yaxis(1) xlabel(`floor'(1)`ceil') color(stred) )  `scatterj'   , xline(0, lcolor(black)) legend(on position(6) cols(`modamax') rows(1) order(`"`legend'"')  subtitle(Threshold parameters) size(small)) name(map,replace) ytitle("                           Frequencies")  ylabel(0(`=`maxi'/5')`maxi' `maxi'(`maxi')`=`maxi'*2' ,axis(2)) yscale(axis(2) off) yscale(axis(3) off)  ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) yline(0,lwidth(medium) lpattern(solid) lcolor(black))  ylabel(`ylbl',/*noticks*/ grid angle(0) axis(1)) ylabel(`ylbl' 0(`=`maxe'/5')`maxe', grid angle(0) axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait - * : dysfunctioning items") xtitle("Latent trait") `fsm'
+		}
+		else if "`eqset1'"!="" {
+			qui su eff
+	        local ceil=ceil(ceil(`r(max)'/10)*10)
+
+            qui tempfile equating
+			qui save `equating', replace
+		}
+	}
+	qui use `savefile', clear
+}
+		 
+
+
+/*************************************************************************************************************
+Best estimates by category 
+*************************************************************************************************************/
+
+tempname bestest
+matrix `bestest'=J(`nbitems',`=`modamax'+1',.)
+di
+local long=`modamax'*8+33
+di
+di "Best estimates by answer category" 
+di "{hline `long'}"
+di "Item" _col(29) "Cat 0"  _c
+forvalues j=1/`modamax' {
+     local col=29+`j'*8 
+	 di _col(`col') "Cat `j'"     _c
+}
+di
+di "{hline `long'}"
+forvalues i=1/`nbitems' {
+    di "``i''" _c
+	forvalues j=0/`modamax`i'' {
+	    di _col(`=28+`j'*8') %6.3f round(`bestest``i''_`j'', 0.001) _c
+		matrix `bestest'[`i',`=`j'+1']=`bestest``i''_`j''
+	}
+	di
+}
+di "{hline `long'}"
+		
+
+
+/*************************************************************************************************************
+EQUATING
+*************************************************************************************************************/
+if "`eqset1'"!="" {
+    if "`eqgenscore'"!="" {
+	   local tmp1 `=ustrlen("`eqgenscore'`eqset1name'")'
+	   local tmp2 `=ustrlen("`eqgenscore'`eqset2name'")'
+	   local mlength=max(`tmp1',`tmp2')
+	   if `mlength'>27 {
+			di as error "The number of characters containing in the strings eqgenscore+eqset1name or eqgenscore+eqset2name must be lesser than 27"
+			di as error "eqgenscore+eqset1name : `tmp1' characters"
+			di as error "eqgenscore+eqset2name : `tmp2' characters"
+			error 130
+			*exit
+		}
+	}
+	if "`eqset1name'"=="" {
+	   local eqset1name="Set 1"
+	}
+	if "`eqset2name'"=="" {
+	   local eqset2name="Set 2"
+	}
+	local eqset1name `=regexreplaceall("`eqset1name'"," ","_",.)'
+	local eqset2name `=regexreplaceall("`eqset2name'"," ","_",.)'
+	*di "set1:`eqset1name' set2:`eqset2name'"  
+
+    tokenize `eqset1'
+	local nbset1: word count `eqset1'
+	forvalues i=1/`nbset1' {
+	   local eq1_`i':word `i' of `eqset1'
+	}
+    tokenize `eqset2'
+	local nbset2: word count  `eqset2'
+	forvalues i=1/`nbset2' {
+	   local eq2_`i':word `i' of `eqset2'
+	}	
+
+
+
+	tempfile fileeq
+	qui save `fileeq',replace
+	forvalues t=1/2{
+		local scoremaxset`t'=0
+		forvalues i=1/`nbset`t'' {
+			local scoremaxset`t'=`scoremaxset`t''+`modamax`eq`t'_`i'''
+		}
+	}
+	drop _all
+	qui set obs `=(`scoremaxset1'+`scoremaxset2'+2)*3'
+	forvalues t=1/2 {
+		qui gen scoreset`t'=.
+		qui gen scoreset`t'm=.
+		qui gen scoreset`t'p=.	
+	}
+	forvalues i=0/`scoremaxset1' {
+	    qui replace scoreset1=`i' in `=`i'+1'
+	    qui replace scoreset1m=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset1p=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	forvalues i=`=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2' {
+	    qui replace scoreset2=`i'-`scoremaxset1'-2 in `i'
+	    qui replace scoreset2m=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset2p=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	local s=0
+	local eqset1b
+	foreach i in `eqset1' {
+		qui gen s1_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s1_`i'_`m'=0 in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'_`m'=1 if scoreset1>`s' in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'=s1_`i'+s1_`i'_`m'
+		   local ++s
+		}
+	    local eqset1b `eqset1b' s1_`i'
+	}
+	local s=0
+	local eqset2b
+	foreach i in `eqset2' {
+		qui gen s2_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s2_`i'_`m'=0 in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'_`m'=1 if scoreset2>`s' in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'=s2_`i'+s2_`i'_`m'
+		   local ++s
+		}
+		local eqset2b `eqset2b' s2_`i'
+	}
+	tokenize `varlist'
+	tempname diffset1 diffset2
+	forvalues t=1/2 {
+		qui matrix `diffset`t''=J(`nbset`t'',`modamax',.)
+		local n=1
+		local listset`t'
+		foreach j in `eqset`t'' {
+			forvalues i=1/`nbitems' {
+				if "`j'"=="``i''" {
+					local listset`t' `listset`t'' `i'
+					forvalues m=1/`modamax' {
+						qui matrix `diffset`t''[`n',`m']=`diffmat'[`i',`m']
+					}
+					local ++n						
+				}
+			}
+		}
+	}
+	local var=`covariates'[1,1]
+	qui gen lt=.
+	forvalues t=1/2 {
+		tempname matscorelt`t'
+		qui pcm `eqset`t'b', diff(`diffset`t'') var(`var') minsize(1)
+		qui matrix `matscorelt`t''=r(matscorelt)
+		forvalues i=0/`scoremaxset`t'' {
+			qui replace lt=`matscorelt`t''[`=`i'+1',2] if scoreset`t'==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]+1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'p==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]-1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'm==`i'
+		}
+		qui ipolate scoreset`t' lt, gen(score`t') epolate
+	}
+	qui ipolate scoreset1 lt, gen(score1bis) epolate
+
+
+	forvalues t=1/2 {
+		qui replace score`t'=scoreset`t'm if scoreset`t'm!=.
+		qui replace score`t'=scoreset`t'p if scoreset`t'p!=.
+		qui replace score1=score1bis if score1==.
+		qui replace score`t'=0 if score`t'<0
+		qui replace score`t'=`scoremaxset`t'' if score`t'>`scoremaxset`t''
+	}
+	local pciset1
+	local pciset2
+	*set trace on
+	local minimini=0
+	local maximaxi=0
+	forvalues t=1/2 {
+        qui gen adjscore`t'=(score`t'+`eqaddset`t'')*`eqmultset`t''
+	    qui gen adjscore`=3-`t''=(score`=3-`t''+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''
+		tempname matscore`t'
+		qui matrix `matscore`t''=J(`=`scoremaxset`t''+1',7,.)
+		*set trace on
+		forvalues s=0/`scoremaxset`t'' {
+		    qui matrix `matscore`t''[`=`s'+1',1]=`s'
+			qui su lt if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',2]=r(mean)
+			if `ceil'==0 {
+				local ceil=1
+			}
+			if "`eqwithic'"=="" {
+				local pciset`t'  `pciset`t'' scatteri `=-`ceil'/5*`t'' `r(mean)' (12) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , mlabsize(tiny) mcolor(black) mlabcolor(black)||
+			}
+			local mean=r(mean)
+			qui su lt if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',3]=r(mean)
+			local moins=r(mean)
+			if `moins'<`minimini' {
+				*di "local minimini=floor(`moins')"
+				local minimini=floor(`moins')
+			}
+			qui su lt if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',4]=r(mean)
+			local plus=r(mean)
+			if `plus'>`maximaxi' {
+				*di "local maximaxi=ceil(`plus')"
+				local maximaxi=ceil(`plus')
+			}
+
+			if "`eqwithic'"!="" {
+				local y=-`ceil'/5*((2.5*`t'-2)+2*(`s'/`scoremaxset`t''))
+				*local pciset`t'  `pciset`t'' scatteri `y' `mean' (12) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , mlabsize(tiny) mcolor(black) mlabcolor(black)|| pci `y' `moins' `y' `plus',pstyle(p1) color(black)||
+				local pciset`t'  `pciset`t'' scatteri `y' `mean'  , mlabsize(tiny) mcolor(black) mlabcolor(black)|| scatteri `y' `moins' (9) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , msize(0) mlabsize(tiny) mcolor(black) mlabcolor(black)|| pci `y' `moins' `y' `plus',pstyle(p1) color(black)||
+			}
+			qui su score`=3-`t'' if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',5]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',6]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',7]=r(mean)
+		}
+		matrix colnames `matscore`t'' =score`t' lt lt- lt+ score`=3-`t'' score`=3-`t''- score`=3-`t''+
+		di as text
+		di as text "{hline 78}"
+		di as text "EQUATING `eqset`t'name' TO `eqset`=3-`t''name'"
+		di as text "{hline 78}"
+		di "`eqset`t'name' : `eqset`t''"
+		di "`eqset`=3-`t''name' : `eqset`=3-`t'''"
+		local eqset`t'namea=abbrev("`eqset`t'name'",18)
+		local eqset`=3-`t''namea=abbrev("`eqset`=3-`t''name'",12)
+		di "{hline 78}"
+		di "Score"           _col(20) "<----- Latent trait ----->" _col(52) "<- Score `eqset`=3-`t''namea'" _col(77) "->"
+		di "`eqset`t'namea'" _col(20) "Estimated" _col(39) "[95%IC]" _col(52) "Estimated" _col(72) "[95%IC]"
+		di "{hline 78}"
+		forvalues s=0/`scoremaxset`t'' {
+		    local min=min(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+		    local max=max(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+			
+			di %4.0f `=(`matscore`t''[`=`s'+1',1]+`eqaddset`t'')*`eqmultset`t''' _col(24) %5.2f `matscore`t''[`=`s'+1',2] _col(33) "[" %5.2f `matscore`t''[`=`s'+1',3] ";" %5.2f `matscore`t''[`=`s'+1',4] "]" _col(56) %5.2f `=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''' _col(66) "[" %5.2f `min' ";" %5.2f `max' "]"			
+		}
+		di "{hline 78}"
+		if "`eqgraph'"!="" {
+		    *set trace on
+			if `eqmultset`=3-`t'''>0 {
+				local xlabel 	"`=`eqaddset`=3-`t'''*`eqmultset`=3-`t''''(`=ceil((`scoremaxset`=3-`t'''*`eqmultset`=3-`t''')/20)')`=(`scoremaxset`=3-`t'''+`eqaddset`=3-`t''')*`eqmultset`=3-`t''''"
+			}
+			else {
+				local xlabel 	"`=(`scoremaxset`=3-`t'''+`eqaddset`=3-`t''')*`eqmultset`=3-`t''''(`=ceil((-`scoremaxset`=3-`t'''*`eqmultset`=3-`t''')/20)')`=`eqaddset`=3-`t'''*`eqmultset`=3-`t''''"
+			}
+			if `eqmultset`t''>0 {
+				local ylabel 	"`=`eqaddset`t''*`eqmultset`t'''(`=ceil((`scoremaxset`t''*`eqmultset`t'')/20)')`=(`scoremaxset`t''+`eqaddset`t'')*`eqmultset`t'''"
+			}
+			else {
+				local ylabel 	"`=(`scoremaxset`t''+`eqaddset`t'')*`eqmultset`t'''(`=ceil((-`scoremaxset`t''*`eqmultset`t'')/20)')`=`eqaddset`t''*`eqmultset`t'''"
+			}
+			*set trace off
+			*di "xlabel : `xlabel'"
+			*di "subtitle=`subtitle'"
+			twoway (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''!=.,lcolor(black) lpattern(solid) lwidth(thick)) (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''m!=.,lcolor(black) lpattern(dash) lwidth(thin)) (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''p!=.,lcolor(black) lpattern(dash) lwidth(thin)), title("Equating score of `eqset`=3-`t''name' to `eqset`t'name' ") ytitle("Score `eqset`t'name'") xtitle("Score `eqset`=3-`t''name'") ylabel(`ylabel') xlabel(`xlabel') name(eq`t'to`=3-`t'') legend(order(1 2) label(1 "Estimated") label(2 "95%IC") position(6)) subtitle("`subtitle'") 
+		}
+		qui drop adjscore`t' adjscore`=3-`t''
+	}
+	
+	if "`eqgraph'"!="" {
+		qui use "`equating'",clear
+	    qui su u
+	    local flooru=floor(`r(min)')
+	    local ceilu=ceil(`r(max)')
+		qui su eff
+	    local ceil=ceil(ceil(`r(max)'/10)*10)
+		if `ceil'==0 {
+		   local ceil=1
+		}
+
+		local title "Equating"
+		if "`eqset1name'"!=""&"`eqset2name'"!=""{
+		   local title "Equating between `eqset1name' and `eqset2name'"
+		}
+		if "`eqwithic'"=="" {
+		   local ylabel1=-`ceil'/5
+		   local ylabel2=-2*`ceil'/5
+		   local gapu=ceil((`ceilu'-`flooru')/15)
+		}
+		else {
+		    local ylabel1=-0.5*`ceil'/5
+		    local ylabel2=-3*`ceil'/5
+		   	local flooru=min(`flooru',`minimini')
+			local ceilu=max(`ceilu',`maximaxi')
+			local gapu=ceil((`ceilu'-`flooru')/15)
+		}
+	    *di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`flooru'(1)`ceilu') color(erose)) || `pciset1' `pciset2'  , yline(0, lcolor(black)) legend(off) name(equating,replace) ytitle(                           Frequencies)    ylabel(`=-`ceil'/5*2' `eqset1name' `=-`ceil'/5' `eqset2name' 0(`=`ceil'/5')`ceil', grid angle(0) axis(1)) title(Equating) xsize(12) ysize(9)  xtitle(Latent trait) "
+	    qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`flooru'(`gapu')`ceilu') color(erose)) || `pciset1' `pciset2'  , yline(0, lcolor(black)) legend(off) name(equating,replace) ytitle("                           Frequencies")    /*ylabel(`ylbl', grid angle(0) axis(1))*/ ylabel(`ylabel1' "`eqset1name'" `ylabel2' "`eqset2name'" 0(`=`ceil'/5')`ceil', grid angle(0) axis(1)) title("`title'") subtitle("`subtitle'") xsize(12) ysize(9)  xtitle("Latent trait") 
+	}
+	qui use `fileeq',clear
+	*set trace on
+	tempname scoreset1 scoreset2
+	forvalues t=1/2 {
+		qui genscore `eqset`t'' if `touse',score(`scoreset`t'')
+	 	qui su `scoreset`t'' if `touse'
+		local maxscoreset=r(max)
+		*qui matrix list `matscore`t''
+		if "`eqgenscore'"!="" {
+			local eqgenscore `=regexreplaceall("`eqgenscore'"," ","_")'
+			*di "eqgenscore : `eqgenscore'"
+			foreach k in mean min max alea {
+				capture confirm  variable `eqgenscore'_`k'_`eqset`=3-`t''name'
+				if _rc==0&"`replace'"!="" {
+					qui replace `eqgenscore'_`k'_`eqset`=3-`t''name'=. if `touse'
+				}
+				else if _rc==0&"`replace'"!="" {
+					di as error "The variable `eqgenscore'_`k'_`eqset`=3-`t''name' already exists"
+					error 198
+				}
+				else {
+					qui gen `eqgenscore'_`k'_`eqset`=3-`t''name'=. if `touse'
+				}
+			}
+			*tab `scoreset`t''
+			forvalues s=0/`maxscoreset' {
+				*di "qui replace `eqgenscore'_`eqset`=3-`t''name'=`=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''' if `scoreset`t''==`s'"
+				local min=min(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+				local max=max(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+				qui replace `eqgenscore'_mean_`eqset`=3-`t''name'=round(`=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_min_`eqset`=3-`t''name'=round(`min',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_max_`eqset`=3-`t''name'=round(`max',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_alea_`eqset`=3-`t''name'=round(uniform()*(`max'-`min')+`min',1) if round(`scoreset`t'',1)==`s'&`touse'
+			}
+		}
+		return matrix score`t'_to_`=3-`t''=`matscore`t''
+	}
+	
+}
+
+
+/*************************************************************************************************************
+RETOUR AU FICHIER INITIAL ET SAUVEGARDE DES NOUVELLES VARIABLES
+*************************************************************************************************************/
+if "`visit'"!="" {
+	tempfile sauv
+	*set trace on
+	*tempname corrlatent corrbilatent
+	qui keep `latent'* `selatent'* `id' `visit' 
+    qui reshape wide , i(`id') j(`visit')
+	qui sort `id'	
+	qui save `sauv', replace
+	restore,preserve
+	if "`replace'"!=""&("`genlt'"!=""|"`geninf'"!="") {
+    	capture drop `genlt' 
+    	capture drop `genlt'_se 
+    	capture drop `geninf' 
+    	capture drop `genlt'_corr
+    	capture drop `genlt'_opt
+    	capture drop `genlt'_opt_se
+    }
+	*su
+	tempname idorder
+	qui gen `idorder'=_n 
+	qui sort `id'
+	qui merge 1:1 `id' using `sauv'
+	
+	qui sort `idorder'
+    qui drop `idorder'	
+}
+else {
+*set trace on
+*set tracedepth 1
+    if "`genlt'"!="" {
+		qui gen `genlt'_corr=. if `touse'
+		forvalues s=0/`scoremax' {
+			qui replace `genlt'_corr=`estlt`s'' if `score'==`s'&`touse'
+		}
+		forvalues g=1/`nbgroups' {
+			qui replace `genlt'_corr=`clt`g'' if `group'==`g'&`genlt'_corr==.&`touse'
+		}
+		tempvar tmpitem mean nbnonmiss
+		forvalues i=1/`nbitems' {
+			qui gen `tmpitem'_`i'=. if `touse'
+			forvalues k=0/`modamax' {
+				qui replace `tmpitem'_`i'=`bestest'[`i',`=`k'+1'] if ``i''==`k'&`touse'
+			}
+		}
+		*su
+		qui egen `genlt'_opt=rowmean(`tmpitem'_*) if `touse'
+		qui egen `genlt'_opt_se=rowsd(`tmpitem'_*) if `touse'
+		qui egen `nbnonmiss'=rownonmiss(`tmpitem'_*) if `touse'
+		qui replace `genlt'_opt_se=sqrt((`genlt'_opt_se^2+`resvar')/`nbnonmiss') if `touse'
+ 	}
+	restore,not
+}
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin
+	putdocx paragraph
+	putdocx text ("General informations") , bold underline font(,14) smallcaps
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph
+	putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	qui putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx paragraph
+	putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
+	qui putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+return matrix matscorelt=`matscorelt'
+return matrix bestest=`bestest'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm 5.3.ado b/Modules/ado/personal/p/pcm 5.3.ado
new file mode 100644
index 0000000..ae440ec
--- /dev/null
+++ b/Modules/ado/personal/p/pcm 5.3.ado	
@@ -0,0 +1,2218 @@
+*! Version 5.3 21July2023
+*! Jean-Benoit Hardouin, Myriam Blanchin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
+* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
+* Version 4.1: September 15th, 2019 [Jean-Benoit Hardouin]: correction of a small bug in the outputs
+* Version 4.2: September 27th, 2019 [Jean-Benoit Hardouin] : EQUATING
+* Version 4.3: November 8th, 2019 [Jean-Benoit Hardouin] : add a constant when difficulty parameters are fixed
+* Version 5: August 2nd, 2022 [Jean-Benoit Hardouin] : New MAP graph, corrected estimation of the latent trait
+* Version 5.1: July 8th, 2023 [Jean-Benoit Hardouin] : Correction of the MAP graph (histogram) and residuals graphs
+* Version 5.2: July 16th, 2023 [Jean-Benoit Hardouin] : Add of new graphs for Equating
+* Version 5.3: July 21th, 2023 [Jean-Benoit Hardouin] : Improvement for the docx option
+*
+*
+* Jean-benoit Hardouin, Myriam Blanchin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr, myriam.blanchin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019, 2022, 2023 Jean-Benoit Hardouin, Myriam Blanchin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [if] [in] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) VARiance(real -1) rsm Graphs noGRAPHItems noCORRected filesave dirsave(string) docx(string) extension(string) alpha(real 0.01)  PCE WMLiterate(int 1) GENLT(string) GENINF(string) REPlace postpce visit(varname) id(varname) eqset1(varlist) eqset2(varlist) eqset1name(string) eqset2name(string) EQGraph eqaddset1(real 0) eqaddset2(real 0) eqmultset1(real 1) eqmultset2(real 1) eqwithic eqgenscore(string)  DIMname(string) minsize(int 30) vardif(varname) itemsdif(varlist)]
+
+version 14
+preserve
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+/*************************************************************************************************************
+QUELQUES TESTS
+*************************************************************************************************************/
+
+if `variance'!=-1&`variance'<=0 {
+	di in red "The -variance- option cannot be negative"
+	exit 198
+}
+if `variance'!=-1&"`visit'"!="" {
+	di in red "The -variance- and -visit- options cannot be used simultaneously."*
+	exit 198
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' `genlt'_se `geninf' `genlt'_corr `genlt'_opt `genlt'_opt_se 
+	if _rc!=0&"`replace'"=="" {
+	    di in red "The variables `genlt', `genlt'_se, `genlt'_corr, `genlt'_opt, `genlt'_opt_se and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+	if _rc!=0&"`replace'"!="" {
+	    qui capture drop `genlt' 
+		qui capture drop `genlt'_se 
+		qui capture drop `geninf' 
+		qui capture drop `genlt'_corr
+		qui capture drop `genlt'_opt
+		qui capture drop `genlt'_opt_se
+	}
+}
+if ("`eqset1'"!=""&"`eqset2'"=="")|("`eqset1'"==""&"`eqset2'"!="") {
+    di in red "The two options -eqset1- and -eqset2- must be used simultaneously"
+	exit 198
+}
+if ("`eqset1'"!=""&"`graphs'"!="") {
+    di in red "The two options -eqset1- and -graph- cannot be used simultaneously"
+	exit 198
+}
+if "`corrected'"!="" {
+	local xtitle "Latent trait"
+}
+else {
+	local xtitle "Corrected latent trait"
+}
+
+
+
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+if "`visit'"!=""{
+	if "`id'"==""{
+		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
+		exit 198
+	}
+	qui levelsof `visit'
+	local levelsofv `r(levels)'
+	local nbvisits=r(r)
+	local timemin: word 1 of `levelsofv'
+	local timemax: word `nbvisits' of `levelsofv'
+	if `timemax'>5{
+		di as error "You must use a discrete time variable (-visit- option) with less than 5 measurement occasions"
+		error 198
+	}
+	if `timemin'!=1{
+		di as error "You must use a -visit- variable coded at 1 for the first visit"
+		error 198
+	}
+	qui reshape wide `varlist', i(`id') j(`visit')
+	local multivisit=1
+}
+else {
+	local timemax=1
+	foreach i in `varlist' {
+	   *rename `i' `i'1
+	}
+	local multivisit
+}
+qui count if `touse'
+local nbobs=r(N)
+
+local timelist
+forvalues t=1/`timemax'{
+	local timelist `timelist' T`t'
+}
+
+local modcont
+local premodcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local premodcont (`modcont'->T1)
+	local modcont (`modcont'->`timelist')
+}
+
+local modcat
+local premodcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local premodcat (`modcat'->T1)
+	local modcat (`modcat'->`timelist')
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+local scoremax=0
+forvalues i=1/`nbitems' {
+	local modamax`i'=1
+	local modamax``i''=1
+	if `timemax'>1 {
+		forvalues t=1/`timemax'{
+			 *qui replace ``i'`t''=``i'`t''-`min' 
+			 qui su ``i''`t' if `touse'
+			 if `r(min)'!=`modamin' {
+				 local modamin=r(min)
+				 local pbmin `pbmin' ``i'`t''
+			 }
+			 if `r(max)'>`modamax' {
+				 local modamax=r(max)
+			 }
+			 if `r(max)'>`modamax`i'' {
+				local modamax`i'=r(max)
+			}
+		}
+	}
+	else {
+		*di "i: `i' ``i''"
+		qui su ``i'' if `touse'
+		if `r(min)'!=`modamin' {
+		    local modamin=r(min)
+			local pbmin `pbmin' ``i''
+		}
+		if `r(max)'>`modamax' {
+			local modamax=r(max)
+		}
+		if `r(max)'>`modamax`i'' {
+			local modamax`i'=r(max)
+			local modamax``i''=r(max)
+		}
+	}
+	*di "local scoremax=`scoremax'+`modamax`i''"
+	local scoremax=`scoremax'+`modamax`i''
+	if "`rsm'"=="" {
+		local nbdiff=`nbdiff'+`modamax`i''
+	}
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count if `touse'
+local nbind=r(N)
+*set trace on
+local code
+local precode
+if `timemax'>1 {
+	forvalues k=1/`modamax' {
+	   forvalues t=1/`timemax'{
+			local code`k'
+		   forvalues i=1/`nbitems' {
+			   if `k'<=`modamax`i'' {
+				  local code`k' `code`k'' `k'.``i''`t'
+			   }
+		   }
+		   local code`k' (`code`k''<-T`t'@`k')
+		   if `t'==1{
+				local precode `precode' `code`k''
+		   }
+		   local code `code' `code`k''
+		}
+	}
+}
+else {
+	forvalues k=1/`modamax' {
+		local code`k'
+		forvalues i=1/`nbitems' {
+			if `k'<=`modamax`i'' {
+				local code`k' `code`k'' `k'.``i''
+			}
+		}
+		local code`k' (`code`k''<-T1@`k')
+		local precode `precode' `code`k''
+		local code `code' `code`k''
+	}
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist' if `touse'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist' if `touse', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+local t=1
+local constraints
+local codemean
+local codevar
+local codecov
+forvalues j=2/`timemax'{
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			qui constraint `t' [`k'.``i''`j']_cons=[`k'.``i''`multivisit']_cons
+			local constraints `constraints' `t'
+			local ++t
+			
+		}
+	}	
+	if "`continuous'"=="" &  "`categorical'"==""{
+		local codemean `codemean' T`j'@m`j'
+		local codevar `codevar' T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' T`l'*T`j'@cov`l'`j'
+		}
+	}
+	else{
+		local codevar `codevar' e.T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
+		}	
+	}
+}
+if `timemax'>1{
+	if "`continuous'"=="" &  "`categorical'"==""{	
+		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
+	}
+	else{
+		local codelg var(e.T1@v1 `codevar') cov(`codecov')
+	}
+}
+else {
+    local constrvar
+    if `variance'>0 {
+		if "`continuous'"=="" &  "`categorical'"==""{	
+			local constrvar var(T1@`variance') 
+		}
+		else{ 
+			*local constrvar var(e.T1@`variance') 
+		}
+	}
+}
+
+local fixedmean
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				qui constraint `t' [`k'.``i''`multivisit']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+	if "`continuous'"=="" &  "`categorical'"=="" {	
+		local fixedmean mean(T1) 
+	}
+	else{
+		local fixedmean 
+	}
+}
+
+
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+if "`rsm'"!="" {
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       qui constraint `t'   [`=`k'-1'.``i''`multivisit']_cons-[`k'.``i''`multivisit']_cons+[1.``i''`multivisit']_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
+if "`model'"!="" {
+    local qui
+}
+else {
+	local qui qui
+}
+if `timemax'==1{
+   *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'"
+   `qui' gsem `code' `modcont' `modcat' if `touse' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+   *qui gen un=1
+   *`qui' gsem `code' (i.group un->T) ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+}
+else{
+    *di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
+    `qui' gsem `precode' `premodcont' `premodcat' if `touse',iterate(`iterate') tol(`tolerance') constraint(`constraints') 
+     matrix esti_B = e(b)
+    *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)"
+    `qui' gsem `code' `modcont' `modcat' if `touse',iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
+}
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2 miss
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent'* if `touse',latent se(`selatent'*)
+*di "latent=`latent' "
+*su
+*set trace on
+
+if "`genlt'"!="" {
+	if `timemax'==1 {
+		qui gen `genlt'=`latent'1 if `touse'
+		qui gen `genlt'_se=`selatent'1 if `touse'
+	}
+	forvalues t=2/`timemax' {
+		qui gen `genlt'`t'=`latent'`t' if `touse'
+		qui gen `genlt'`t'_se=`selatent'`t' if `touse'
+	}
+}
+
+set seed 123456
+if `timemax'>1 {
+	forvalues t=1/`timemax'{
+		qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t' if `touse'
+		local listit 
+		forvalues i=1/`nbitems' {
+			local listit `listit' ``i''`t'
+		}
+		qui genscore `listit' if `touse',score(`score'`t')
+		qui gengroup `latent'`t' if `touse',newvariable(`group'`t') continuous minsize(`minsize')
+	}
+}
+else {
+	qui gen `latent2'=`latent'1+invnorm(uniform())*`selatent'1 if `touse'
+	local listit 
+	forvalues i=1/`nbitems' {
+		local listit `listit' ``i''
+	}
+	qui genscore `listit' if `touse',score(`score')
+	qui gengroup `latent'1 if `touse',newvariable(`group') continuous minsize(`minsize')
+}
+forvalues s=0/`scoremax' {
+    qui count if `score'==`s'&`touse'
+	local effscore`s'=r(N)
+}
+
+
+/*time 1 only*/
+qui levelsof `group'`multivisit' if `touse'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+6',.)
+forvalues g=1/`nbgroups' {
+	matrix `groups'[`g',`=`nbitems'+3']=0
+	qui count if `group'`multivisit'==`g'&`touse'
+	local effgroup`g'=r(N)
+	forvalues i=1/`nbitems' {
+			qui count if ``i''`multivisit'!=.&`group'`multivisit'==`g'&`touse'
+			local n=r(N)
+			if `n'>0 {
+				qui su ``i''`multivisit' if `group'`multivisit'==`g'&`touse'
+				matrix `groups'[`g',`i']=r(mean)
+				matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+			}
+			else {
+				matrix `groups'[`g',`i']=.
+				matrix `groups'[`g',`=`nbitems'+3']=.
+			}		
+	}
+	qui su `latent'1 if `group'`multivisit'==`g'&`touse'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'`multivisit'==`g'&`touse'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+	qui su `score' if `group'`multivisit'==`g'&`score'!=.&`touse'
+	matrix `groups'[`g',`=`nbitems'+4']=r(min)
+	matrix `groups'[`g',`=`nbitems'+5']=r(max)	
+}
+
+/*number of non-missing on all time points*/
+egen `miss'=rowmiss(`score'*) if `touse'
+qui count if `miss'==0&`touse'
+local nbobsssmd=r(N)
+drop `miss'	
+
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i''`multivisit':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i''`multivisit':_cons]
+	qui lincom -_b[1.``i''`multivisit':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+	local rn `rn' 1.``i''`multivisit'
+	local ++t
+	local sum _b[1.``i''`multivisit':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax`i'' {
+			local sum "_b[`k'.``i''`multivisit':_cons]-(`sum')"
+			*di "``i''`multivisit' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i''`multivisit':_cons]-_b[`k'.``i''`multivisit':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''`multivisit'
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1'`multivisit':_cons]-_b[`k'.`1'`multivisit':_cons]+_b[1.`1'`multivisit':_cons] /*``i'' instead of `i'?*/
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
+*************************************************************************************************************/
+tempname covariates
+local nbcov=0
+forvalues j=2/`timemax'{
+	local nbcov=`nbcov'+`j'-1
+}
+qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)
+
+*set trace on
+local t=1
+
+
+forvalues j=1/`=`timemax'-1'{
+	forvalues k=`=`j'+1'/`timemax'{
+		if "`categorical'"=="" & "`continuous'"=="" {
+			if `j'==1{
+				qui lincom [/]mean(T`k')
+			}
+			else{
+				qui lincom [/]mean(T`k')-[/]mean(T`j')
+			}
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+		else{
+			if "`categorical'"!=""{
+				local first=0 
+				foreach l in `levelsof`cat1'' {
+					if `first'==0 {
+						local ++first
+					}
+					else{
+						if `first'==1 {
+							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
+							qui matrix `covariates'[`t',1]=`r(estimate)'
+							qui matrix `covariates'[`t',2]=`r(se)'
+							qui matrix `covariates'[`t',3]=`r(z)'
+							qui matrix `covariates'[`t',4]=`r(p)'
+							qui matrix `covariates'[`t',5]=`r(lb)'
+							qui matrix `covariates'[`t',6]=`r(ub)'
+							local ++t
+							local ++first
+						}
+					}
+				}
+			}
+			else{
+				qui lincom [T`k']`cont1'-[T`j']`cont1'
+				qui matrix `covariates'[`t',1]=`r(estimate)'
+				qui matrix `covariates'[`t',2]=`r(se)'
+				qui matrix `covariates'[`t',3]=`r(z)'
+				qui matrix `covariates'[`t',4]=`r(p)'
+				qui matrix `covariates'[`t',5]=`r(lb)'
+				qui matrix `covariates'[`t',6]=`r(ub)'
+				local ++t
+			}		
+		}
+	}
+}	
+		
+forvalues j=1/`timemax'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		qui lincom _b[/var(e.T`j')]
+	}
+	else {
+		qui lincom _b[/var(T`j')]
+	}
+	qui matrix `covariates'[`t',1]=`r(estimate)'
+	qui matrix `covariates'[`t',2]=`r(se)'
+	qui matrix `covariates'[`t',3]=`r(z)'
+	qui matrix `covariates'[`t',4]=`r(p)'
+	qui matrix `covariates'[`t',5]=`r(lb)'
+	qui matrix `covariates'[`t',6]=`r(ub)'
+	local ++t
+}
+forvalues j=1/`=`timemax'-1'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(e.T`j',e.T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+	else{
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(T`j',T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+}
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+*matrix list `covariates'
+
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 83}"
+	di  as text _col(70) "<--95% IC -->"
+	di   _col(70) "Lower" _col(78) "Upper"
+	di "Items" _col(22) "Threshold" _col(35) "Estimate" _col(47) "s.e." _col(58) "z" _col(66) "p" _col(69) " Bound" _col(78) "Bound"
+	di "{hline 83}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax`i'' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %5.2f `diff'[`t',3] _col(62) %5.2f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %5.2f `diff'[`t',3] _col(62) %5.2f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 83}"
+	local t=1
+	local listmoy
+	local listvar
+	local listcov
+	forvalues j=1/`timemax'{
+		local listvar `listvar' Variance_T`j'
+		forvalues k=`=`j'+1'/`timemax'{
+			local listcov `listcov' Cov_T`j'_T`k'
+		}
+		forvalues k=`=`j'+1'/`timemax'{
+			local listmoy `listmoy' Mean_diff_T`j'_T`k'
+		}
+	}
+	local n: word count `listmoy' `listvar' `listcov' `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of `listmoy' `listvar' `listcov' `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %5.2f `covariates'[`t',3] _col(62) %5.2f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %5.2f `covariates'[`t',3] _col(62) %5.2f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		*local ++t
+	}
+	di as text "{hline 83}"
+	if "`visit'"==""{
+		di
+		qui su `latent'1 if `touse'
+		*qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])+(`r(sd)')^2)
+		*di as text "Variance of the estimated latent variable: " as result %4.2f `=(`r(sd)')^2'
+        tempvar se2latent
+		qui gen `se2latent'=(`selatent'1)^2 if `touse'
+		qui su `se2latent' if `touse'
+		local resvar=r(mean)
+		di as text "Mean squared std error of the latent variable: " as result %4.2f `resvar'
+		di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`resvar'))'
+		local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`resvar'))
+		di as text "PSI: " as result %4.2f `PSI' _c
+		if "`continuous'"!=""|"`categorical'"!="" {
+		    di as text " (without adjustment on covariates)"
+	    }
+		else {
+		    di
+		}
+		di
+		return scalar PSI=`PSI'
+
+	}
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+
+/*************************************************************************************************************
+ESTIMATION OF THE CORRECTED VALUES OF THE LT ESTIMATORS (values of lt that explained the best the score)
+**************************************************************************************************************/
+*set trace on
+tempfile savefile
+qui save `savefile'
+
+qui drop _all
+		
+qui set obs 2000
+qui gen u=(_n-1000)/200*`=sqrt(`covariates'[1,1])'
+qui gen Tcum=0
+qui gen TInf=0
+forvalues i=1/`nbitems' {
+		local d=1
+		qui gen cum``i''=0
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+		}
+		qui gen c0_``i''=1/(`d')
+		forvalues k=1/`mm' {
+			qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+			qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+		}
+		qui gen Inf``i''=0
+		forvalues k=1/`mm' {
+			qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+		}
+		*set trace on
+		qui replace Tcum=Tcum+cum``i''
+		qui replace TInf=TInf+Inf``i''	
+	    local scoremax=0
+		forvalues l=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`l''
+	    }
+		qui gen ecart=.
+		forvalues l=0/`scoremax' {
+		    if `l'==0 {  
+			   local j=0.25
+			}
+			else if `l'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`l'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`l'=`r(mean)'
+			*qui su TInf if round(ecart, 0.01)==round(`tmp',0.01)
+			*local setlt`l'=sqrt(1/`r(mean)')
+		}
+		qui drop ecart
+}
+qui use `savefile', clear
+
+
+*set trace on
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+
+/*Quelques explications
+latent : estimation EAP du trait latent
+latent2 : estimation Plausible Value Ă  partir de l'estimation EAP
+corrlatent : estimation corrigée cherchant la meilleur valeur du trait latent qui explique le score, interpolation à partir de l'EAP pour les individus avec des données manquantes
+*/
+
+
+if "`visit'"==""{
+	tempvar corrlatent corrlatenttmp 
+	qui gen `corrlatenttmp'=.
+	forvalues s=0/`scoremax' {
+	    qui replace `corrlatenttmp'=`estlt`s'' if `score'==`s'
+	}
+	qui ipolate `corrlatenttmp' `latent'1 , generate(`corrlatent') epolate
+	*list `corrlatenttmp' `latent2' `corrlatent' 
+	qui replace `corrlatent'=`corrlatenttmp' if `corrlatenttmp'!=.
+	*su  `corrlatenttmp' `latent2' `corrlatent' 
+    *twoway (scatter `corrlatent' `score') (scatter `latent2' `score') 
+	
+	tempname fit
+	qui matrix `fit'=J(`nbitems',6,.)
+	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT" "corrOUTFIT" "corrINFIT"
+	matrix rownames `fit'=`varlist'
+	*matrix list `fit'
+
+	tempvar Tcum TInf cum
+	qui gen `Tcum'=0 if `touse'
+	qui gen `TInf'=0 if `touse'
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text _col(60) "<---  Standardized   --->"
+		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+		di as text "{hline 90}"
+		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "{hline 90}"
+	}
+	*set trace on
+	local chi2=0
+	local chi2_old=0
+	forvalues g=1/`nbgroups' {
+	   local chi2_g`g'=0
+	   local chi2_old_g`g'=0
+	}
+	forvalues i=1/`nbitems' {
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+		tempvar corrcum``i'' corrc0_``i'' corrInf``i'' corry``i'' corrz``i'' corrz2``i'' corri``i'' 
+
+		local d=1
+		local corrd=1
+		local d_old=1
+		qui gen `corrcum``i'''=0 if `touse'
+		qui gen `cum``i'''=0 if `touse'
+		qui gen `cum_old``i'''=0 if `touse'
+		forvalues k=1/`mm' {
+			local corrd `corrd'+exp(`k'*`corrlatent'-`diffmat2'[`i',`k'])
+			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+			local d_old `d_old'+exp(`k'*`latent'1-`diffmat2'[`i',`k'])
+		}
+		qui gen `corrc0_``i'''=1/(`corrd') if `touse' 
+		qui gen `c0_``i'''=1/(`d') if `touse' 
+		qui gen `c_old0_``i'''=1/(`d_old') if `touse'
+		forvalues k=1/`mm' {
+			tempvar corrc`k'_``i'' c`k'_``i'' c_old`k'_``i''
+			qui gen `corrc`k'_``i'''=exp(`k'*`corrlatent'-`diffmat2'[`i',`k'])/(`corrd') if `touse'
+			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d') if `touse'
+			qui gen `c_old`k'_``i'''=exp(`k'*`latent'1-`diffmat2'[`i',`k'])/(`d') if `touse'
+			qui replace `corrcum``i'''=`corrcum``i'''+`corrc`k'_``i'''*`k' if `touse'
+			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k' if `touse'
+			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k' if `touse'
+		}
+		qui gen `corrInf``i'''=0 if `touse'
+		qui gen `Inf``i'''=0 if `touse'
+		qui gen `Inf_old``i'''=0 if `touse'
+		qui gen `C``i'''=0 if `touse'
+		forvalues k=0/`mm' {
+			qui replace `corrInf``i'''=`corrInf``i'''+(`k'-`corrcum``i''')^2*`corrc`k'_``i''' if `touse'
+			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i''' if `touse'
+			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i''' if `touse'
+			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i''' if `touse'
+		}
+		qui count if ``i''!=.&`touse'
+		local n``i''=r(N)
+		
+		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2) if `touse'
+		qui su `C2``i''' if `touse'
+		local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2 if `touse'
+		qui su `C3``i'''
+		local n=r(sum)
+		qui su `Inf``i''' if `touse'
+		local d=r(sum)
+		local q2i``i''=`n'/((`d')^2)
+		
+		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+		
+		qui replace `Tcum'=`Tcum'+`cum``i''' if `touse'
+		qui replace `TInf'=`TInf'+`Inf``i''' if `touse'
+		qui gen `corry``i'''=``i''-`corrcum``i''' if `touse'
+		qui gen `y``i'''=``i''-`cum``i''' if `touse'
+		qui gen `y_old``i'''=``i''-`cum_old``i''' if `touse'
+		qui gen `y2``i'''=(`y``i''')^2 if `touse'
+		qui gen `y2_old``i'''=(`y_old``i''')^2 if `touse'
+		qui gen `corrz``i'''=(`corry``i'''/sqrt(`corrInf``i''')) if `touse'
+		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i''')) if `touse'
+		local chi2_``i''=0
+		local chi2_old_``i''=0
+		forvalues g=1/`nbgroups' {
+			qui su `y2``i''' if `group'==`g'&`touse'
+			local n=r(sum)
+			qui su ``i'' if `group'==`g'&`touse'
+			local n1=r(sum)
+			qui su `cum``i''' if `group'==`g'&`touse'
+			local n2=r(sum)
+			qui su `Inf``i''' if `group'==`g'&`touse'
+			local d=r(sum)
+			*qui count if `group'==`g'
+			*local eff=r(N)
+			*di "chi2_`g'_``i''=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')"
+			local chi2=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_``i''=`chi2_``i'''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_g`g'=`chi2_g`g''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			qui su `y2_old``i''' if `group'==`g'&`touse'
+			local n_old=r(sum)
+			qui su ``i'' if `group'==`g'&`touse'
+			local n1_old=r(sum)
+			qui su `cum_old``i''' if `group'==`g'&`touse'
+			local n2_old=r(sum)
+			qui su `Inf_old``i''' if `group'==`g'&`touse'
+			local d_old=r(sum)
+			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+		}
+		*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+		*su `z``i'''
+		label variable `corrz``i''' "Corrected standardized residuals associated to ``i''"
+		label variable `z``i''' "Standardized residuals associated to ``i''"
+		label variable `latent'1 "Latent trait"
+		label variable `corrlatent' "Corrected latent trait"
+		*set trace on
+		if  "`graphs'"!=""&"`graphitems'"=="" {
+			*set trace on
+			*set tracedepth 1
+			if "`filesave'"!="" {
+				local fs saving("`dirsave'//residuals_``i''",replace)
+			}
+			local thr=abs(invnorm(`alpha'/2))
+			tempvar id``i''
+			if "`corrected'"!="" {
+				qui gen `id``i'''=_n if abs(`z``i''')>`thr'*sqrt(`covariates'[1,1])&`touse'
+				qui tostring `id``i''',replace
+				qui replace `id``i'''="" if `id``i'''=="."&`touse'
+				qui su `z``i''' if `touse'
+				local min=r(min)
+				local max=r(max)
+				local min=floor(min(`min',`=-`thr'*sqrt(`covariates'[1,1])'))
+				local max=ceil(max(`max',`=`thr'*sqrt(`covariates'[1,1])'))
+			
+				qui graph twoway scatter `z``i''' `latent' if `touse', ylabel(`min'(1)`max') yline(`=-`thr'*sqrt(`covariates'[1,1])' `=`thr'*sqrt(`covariates'[1,1])',lcolor(black)) mlabel(`id``i''') name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+			}
+			else {
+			*set trace on
+				qui gen `id``i'''=_n if abs(`corrz``i''')>`thr'*sqrt(`covariates'[1,1])&`touse'
+				qui tostring `id``i''',replace
+				qui replace `id``i'''="" if `id``i'''=="."&`touse'
+				qui su `corrz``i''' if `touse'
+				local min=r(min)
+				local max=r(max)
+				local min=floor(min(`min',`=-`thr'*sqrt(`covariates'[1,1])'))
+				local max=ceil(max(`max',`=`thr'*sqrt(`covariates'[1,1])'))
+				qui graph twoway scatter `corrz``i''' `corrlatent' if `touse', ylabel(`min'(1)`max') yline(`=-`thr'*sqrt(`covariates'[1,1])' `=`thr'*sqrt(`covariates'[1,1])',lcolor(black)) mlabel(`id``i''') name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs' /*colorvar(`group') colordiscrete*/
+			}
+			*set trace off
+		}
+		*set trace off 
+		qui gen `z2``i'''=(`z``i''')^2 if `touse'
+		qui su `z2``i''' if `touse'
+		local OUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',1]=`OUTFIT``i'''
+		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `Inf``i''' if ``i''!=.&`touse'
+		local sumw``i''=r(sum)
+		qui gen `i``i'''=`Inf``i'''*`z2``i''' if `touse' 
+		qui su `i``i''' if ``i''!=.&`touse'
+		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+		qui matrix `fit'[`i',2]=`INFIT``i'''
+		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		qui matrix `fit'[`i',4]=`INFITs``i'''
+		
+		/*corrected*/
+		qui gen `corrz2``i'''=(`corrz``i''')^2 if `touse'
+		qui su `corrz2``i''' if `touse'
+		local corrOUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',5]=`corrOUTFIT``i'''
+		*local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		*qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `corrInf``i''' if ``i''!=.&`touse'
+		local corrsumw``i''=r(sum)
+		qui gen `corri``i'''=`corrInf``i'''*`corrz2``i''' if `touse' 
+		qui su `corri``i''' if ``i''!=.&`touse'
+		local corrINFIT``i'' = `=`r(sum)'/`corrsumw``i''''
+		qui matrix `fit'[`i',6]=`corrINFIT``i'''
+		*local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		*qui matrix `fit'[`i',4]=`INFITs``i'''
+
+
+		if "`postpce'"=="" {
+			di "``i''" _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' /*_col(94) %5.3f `corrOUTFIT``i''' _col(109) %5.3f `corrINFIT``i'''*/
+		}
+	}
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text "*: As suggested by Wright (Smith, 1998)"
+		di as text "**: As suggested by Bond and Fox (2007)"
+	}
+	if "`geninf'"!="" {
+	    gen `geninf'=`TInf' if `touse'
+	}
+}
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Iteration `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1') if `touse'
+		`qui' pcm `varlist' [iweight=`sinf'] if `touse',diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1') if `touse'
+		qui su `ecart_`it'' if `touse'
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+/*ANCIENNE PLACE DES CORRECTED VALUES*/
+
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+if "`visit'"==""{
+*set trace on
+    tempname matscorelt matgroupscorelt
+	*di "qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)"
+	qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)
+	qui matrix `matgroupscorelt'=J(`=`nbitems'*`modamax'+1'+2*`nbgroups'',7,.)
+	qui matrix colnames `matgroupscorelt'="Group" "Score" "Frequency" "Estimation of latent trait" "s.e. of latent trait" "Expected score" "Corrected latent trait"
+	
+	local row=1
+	di
+	di as text "{hline 71}"
+	di _col(32) "Latent Trait" _col(50) "Expected" _col(63) "Corrected"
+	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score" _col(60) "latent trait"
+	di as text "{hline 71}"
+	forvalues g=1/`nbgroups' {
+		local sumuc=0
+		local sumc=0
+		qui count if `group'`multivisit'==`g'&`touse'
+		local eff`g'=r(N)
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'!=.&`touse'
+		local effcompleted`g'=r(N)
+		qui count if `score'`multivisit'!=.&`group'`multivisit'==`g'&`touse'
+		local n=r(N)
+		di as text "`g' (n=" as result `eff`g'' as text ")" _c
+		if `n'>0 {
+			qui su `score'`multivisit' if `group'`multivisit'==`g'&`touse'
+			local scoremin`g'=`r(min)'
+			local scoremax`g'=`r(max)'
+			forvalues s=`scoremin`g''/`scoremax`g'' {
+				qui count if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local eff=r(N)
+				local effscore`s'=r(N)
+				if `eff'!=0 {
+					qui su `latent'1 if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+					local mean=r(mean)
+					*di "local ltscore`s'=`=ceil(`r(mean)'*100)/100'"
+					local ltscore`s'=`=ceil(`r(mean)'*100)/100'
+					*di "local sumc=`sumc'+(`eff')*(`estlt`s'')"
+					*di "local sumuc=`sumuc'+(`eff')*(`mean')"
+				    local sumuc=(`sumuc'+((`eff')*(`mean')))
+				    local sumc=(`sumc'+((`eff')*(`estlt`s'')))
+				}
+				qui su `selatent'1 if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local se=r(mean)
+				qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local exp=r(mean)
+				if `eff'>0 {
+				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp' _col(66) %6.3f `estlt`s''  `setlt`s''
+				}
+				*set trace on
+				*matrix list `matscorelt'
+				qui matrix `matscorelt'[`=`s'+1',1]=`eff'
+				qui matrix `matscorelt'[`=`s'+1',2]=`mean'
+				qui matrix `matscorelt'[`=`s'+1',3]=`se'
+				qui matrix `matgroupscorelt'[`row',1]=`g'
+				qui matrix `matgroupscorelt'[`row',2]=`s'
+				qui matrix `matgroupscorelt'[`row',3]=`eff'
+				qui matrix `matgroupscorelt'[`row',4]=`mean'
+				qui matrix `matgroupscorelt'[`row',5]=`se'
+				qui matrix `matgroupscorelt'[`row',6]=`exp'
+				qui matrix `matgroupscorelt'[`row',7]=`estlt`s''
+				local ++row
+				*set trace off
+			}
+			
+		}
+		*set trace on
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+		local eff=r(N)
+		local eff_md_`g'=r(N)
+		if `eff'!=0 {
+			qui su `latent'1 if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local mean=r(mean)
+			local lt_md_`g'=r(mean)
+			local sumuc=(`sumuc'+((`eff')*(`mean')))
+			qui su `selatent'1 if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local se=r(mean)
+			qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local exp=r(mean)
+			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) /*%5.2f `exp'*/
+			qui matrix `matgroupscorelt'[`row',1]=`g'
+			*qui matrix `matgroupscorelt'[`row',2]=`s'
+			qui matrix `matgroupscorelt'[`row',3]=`eff'
+			qui matrix `matgroupscorelt'[`row',4]=`mean'
+			qui matrix `matgroupscorelt'[`row',5]=`se'
+			qui matrix `matgroupscorelt'[`row',6]=`exp'
+			*qui matrix `matgroupscorelt'[`row',7]=`estlt`s''
+			local ++row
+		}
+		*set trace off
+		*di "local lt`g'=`sumuc'/`eff`g''"		
+		*di "local clt`g'=`sumc'/`effcompleted`g''"
+		local lt`g'=(`sumuc')/(`eff`g'')
+		local clt`g'=(`sumc')/(`effcompleted`g'')
+		matrix `groups'[`g',`=`nbitems'+6']=`clt`g''
+		*di "group `g' est=`lt`g'' corrected est=`clt`g''"
+		di as text "         " "{dup 62:-}"
+		if "`scoremin`g''"=="" {
+			local scoremin`g' "."
+		}
+		if "`scoremax`g''"=="" {
+			local scoremax`g' "."
+		}
+		di  as text _col(10) "`scoremin`g''/`scoremax`g''" as result _col(20) %4.0f `eff`g'' _col(30) %6.3f `lt`g''  _col(66) %6.3f `clt`g''
+		di as text "{hline 71}"
+		qui matrix `matgroupscorelt'[`row',1]=`g'
+		*qui matrix `matgroupscorelt'[`row',2]="`scoremin`g''/`scoremax`g''"
+		qui matrix `matgroupscorelt'[`row',3]=`eff`g''
+		qui matrix `matgroupscorelt'[`row',4]=`lt`g''
+		qui matrix `matgroupscorelt'[`row',5]=`se'
+		*qui matrix `matgroupscorelt'[`row',6]=`exp'
+		qui matrix `matgroupscorelt'[`row',7]=`clt`g''
+		local ++row
+	}
+	local nbrowmat=`row'-1
+	qui matrix `matgroupscorelt'=`matgroupscorelt'[1..`nbrowmat',1..7]
+	*matrix list `matscorelt'
+}	
+
+*set trace on
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+*set trace on
+if "`visit'"==""{
+	if "`graphs'"!=""|"`graphs'"=="" {
+
+		tempfile savefile
+		qui save `savefile'
+
+		*qui clear
+		qui drop _all
+		local pas=1000*round(`=sqrt(`covariates'[1,1])',0.001)
+		qui set obs `pas'
+		qui gen u=round((_n-`pas'/2)/(`pas'/10)*`=sqrt(`covariates'[1,1])',0.01)
+		*list u
+		qui gen Tcum=0
+		qui gen TInf=0
+		qui gen ecartcum=.
+		forvalues i=1/`nbitems' {
+		   local scatteri`i' 
+		   local scatteric`i' 
+		   forvalues g=1/`nbgroups' {
+			  local x=`groups'[`g',`=`nbitems'+1']
+			  local xc=`groups'[`g',`=`nbitems'+6']
+			  local y=`groups'[`g',`i']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			  local scatteric`i' `scatteric`i'' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off)
+			*set trace off
+			}
+			local d=1
+			qui gen cum``i''=0
+			*set trace on
+			if "`rsm'"=="" {
+				local mm=`modamax`i''
+			}
+			else {
+				local mm `modamax'
+			}	
+			forvalues k=1/`mm' {
+				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+			}
+			qui gen c0_``i''=1/(`d')
+			label variable c0_``i'' "Pr(``i''=0)"
+			forvalues k=1/`mm' {
+				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+				label variable c`k'_``i'' "Pr(``i''=`k')"
+			}
+			forvalues k=0/`mm' {
+			    if `k'==0 {
+				   local l=0.25
+				}
+				else if `k'==`mm' {
+				   local l=`k'-0.25
+				}
+				else {
+				   local l=`k'
+				}
+				qui replace ecartcum=abs(cum``i''-`l')
+				qui su ecartcum
+				qui su u if round(ecartcum,0.01)==round(`r(min)',0.01)
+				local bestest``i''_`k'=r(mean)
+				*di "item ``i'' cat `k' : est=`bestest``i''_`k''"
+			}
+			qui gen Inf``i''=0
+			forvalues k=0/`mm' {
+				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+			}
+			if "`graphitems'"=="" {
+				if "`filesave'"!="" {
+					local fsc saving("`dirsave'//CCC_``i''",replace)
+					local fsi saving("`dirsave'//ICC_``i''",replace)
+				}
+				if "`graphs'"!="" {
+					qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("`xtitle'") `fsc'
+					if "`corrected'"!="" {
+						qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+					}
+					else {
+						qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Corrected latent trait") `scatteric`i'' `fsi'
+					}
+				}
+			}
+			qui replace Tcum=Tcum+cum``i''
+			*tab Tcum
+			qui replace TInf=TInf+Inf``i''	
+			label variable Inf``i'' "``i''"
+		}
+	    local scoremax=0
+		forvalues i=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`i''
+	    }
+		qui gen ecart=.
+		forvalues i=0/`scoremax' {
+		    if `i'==0 {  
+			   local j=0.25
+			}
+			else if `i'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`i'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`i'=`r(mean)'
+			*di "score `i' : `r(mean)'"
+		}
+		if "`filesave'"!="" {
+			local fst saving("`dirsave'//TCC",replace)
+			local fsteo saving("`dirsave'//TCCeo",replace)
+			local fsi saving("`dirsave'//ICC",replace)
+			local fsti saving("`dirsave'//TIC",replace)
+			local fstii saving("`dirsave'//TICi",replace)
+			local fsm saving("`dirsave'//map",replace)
+		}
+		if "`graphs'"!="" {
+*qui save "C:\temp\info\info",replace
+			qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("`xtitle'") `fst' subtitle(`dimname')
+			qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("`xtitle'")  `fsi' subtitle(`dimname')
+			qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("`xtitle'")  `fsti' subtitle(`dimname')
+			qui graph twoway (line Inf*  u, lwidth(thin)) (line TInf u, lwidth(thick)), name(TIC,replace) title("Test/Item Information Curve") ytitle("Information") xtitle("`xtitle'")  `fstii' subtitle(`dimname')
+		}
+		local scatteri
+		local scatteric
+		forvalues g=1/`nbgroups' {
+			local x=`groups'[`g',`=`nbitems'+1']
+			local xc=`groups'[`g',`=`nbitems'+6']
+			local y=`groups'[`g',`=`nbitems'+3']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			local scatteric `scatteric' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off)
+		}
+		if "`graphs'"!="" {
+			if "`corrected'"!="" {
+				qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo' subtitle(`dimname')
+			}
+			else {
+				qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Corrrected latent trait") `scatteric' `fsteo' subtitle(`dimname')
+			}
+		}
+	}
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+	*set trace on
+	if "`graphs'"!=""|"eqset1"!="" {
+		gen eff=0
+		gen eff_md=0
+		local effmax=0
+			*gen uround=round(u,0.01)
+			*list uround
+		/*le bloc suivant Ă©tait pour avoir des batons par groupe*/
+		/*forvalues g=1/`nbgroups' {
+			local eff=`groups'[`g',`=`nbitems'+2']
+			if `groups'[`g',`=`nbitems'+2']>`effmax' {
+			   local effmax=`groups'[`g',`=`nbitems'+2']
+			}
+			local lat=round(`groups'[`g',`=`nbitems'+1'],0.01)
+			*di "replace eff=`eff' if round(u,0.01)==`lat'"
+			qui replace eff=`eff' if round(u,0.01)==`lat'
+		}*/
+		/*le bloc suivant est pour avoir des batons par score*/
+		qui gen uceil=ceil(u*100)/100
+		forvalues s=0/`scoremax' {
+			if `effscore`s''>`effmax' {
+			   local effmax=`effscore`s''
+			}
+			*di "`s' qui replace eff=`effscore`s'' if ceil(u*100)/100==`=round(`ltscore`s'',0.01)'"
+			qui replace eff=`effscore`s'' if round(u,0.01)==round(`ltscore`s'',0.01)
+		}
+		forvalues g=1/`nbgroups' {
+			*di "if `eff_md_`g''>`effmax' { (`lt_md_`g'')"
+			if `eff_md_`g''>`effmax' {
+			   local effmax=`eff_md_`g''
+			}
+			qui replace eff_md=`eff_md_`g'' if round(u,0.01)==round(`lt_md_`g'',0.01)
+		}
+
+		gen density=normalden(u)*sqrt(`covariates'[1,1])
+		label variable eff "Frequencies"
+		label variable u "Latent trait"
+		label variable TInf "Information curve"
+		label variable density "Density function of the latent trait"
+		local scatteri
+		local scatterj
+		local color 
+		qui su u if eff!=0|eff_md!=0
+		*set trace on
+		*set tracedepth 1
+		*if eff!=0|eff_md!=0 {
+			local floor=floor(`r(min)')
+			local ceil=ceil(`r(max)')
+		*}
+		*else  {
+		*	local floor=-10
+		*	local ceil=10
+		*}
+		local sep
+		local ylbl
+		forvalues i=1/`nbitems' {
+		   local color`i':word `i' of `color'
+		   local unit=round(`effmax'/`nbitems',1)
+		   local y=-`i'*`unit'             
+		   loca staritem
+		   local legend `"3 "1" "'
+		   forvalues l=1/`modamax' {
+			   if `l'>=2 {
+			      local legend `" `legend' `=2*`l'+1' "`l'" "'
+			   }			   
+			   local x=`diffmat'[`i',`l']
+			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+			   if `l'==1 {
+			      local xant=`x'
+			   }
+			   else {
+			      local xant=`diffmat'[`i',`=`l'-1']
+			   }
+			   if `xant'>`x' {
+				  local star *
+				  local staritem *
+			   }
+			   else {
+			      local star
+			   }
+			   local scatterj `" `scatterj' `sep' scatteri `y' `x'   , pstyle(p`l') || pci `y' `xant' `y' `x', pstyle(p1) color(black)"'
+			   local sep ||
+			   if `x'<`floor' {
+				  local floor=floor(`x')
+			   }
+			   if `x'>`ceil'&`x'!=. {
+				  local ceil=ceil(`x')
+			   }
+		   }
+   		   local ylbl `ylbl' `=-`i'*`unit'' "``i''`staritem'"
+		   local scatteri `scatteri' || scatteri `y' `=`floor'-2' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+		}
+		qui su eff
+		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+		qui su eff_md
+		local maxe_md=ceil(`=(floor(`r(max)'/10)+1)*10')
+		local maxe=max(`maxe',`maxe_md')
+		qui su TInf
+		local maxi=1.2*ceil(`r(max)')
+		qui su density
+		local maxd=round(`r(max)', 0.01)+0.01
+		qui drop if u<`floor'|u>`ceil'
+		*di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(0(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3)) `scatterj'   , name(map,replace) ytitle(Frequencies)  ylabel(0(`=`maxi'/5')`maxi' ,axis(2)) ylabel(0(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title(Individuals/items representations (Map)) xsize(12) ysize(9) note(Red line: Information curve - Green line : Density of the latent trait) xtitle(Latent trait) `fsm'"
+		*graph combine TIC IIC,  col(1)
+		*graph save "map" "map.gph", replace
+		*discard
+		*qui graph twoway line TInf u , name(map,replace)
+		*qui graph twoway `scatterj'  , name(map2,replace) ytitle("")   ylabel(`ylbl', grid angle(0))  legend(off) xsize(12) ysize(9) 
+		*su
+*list eff u if eff!=0
+*browse
+		if "`eqset1'"==""&"`graphs'"!="" {
+		    *list eff u uceil if eff!=0&eff!=.
+			*save tmp, replace
+			qui graph twoway (bar eff u,  barwidth(.1) yaxis(1) xlabel(`floor'(1)`ceil') color(erose) ) (line TInf u,yaxis(2) lwidth(medthick)) (line density u,yaxis(3) lwidth(medthick) lcolo(green) ) (bar eff_md u,  barwidth(.05) yaxis(1) xlabel(`floor'(1)`ceil') color(stred) )  `scatterj'   , xline(0, lcolor(black)) legend(on position(6) cols(`modamax') rows(1) order(`"`legend'"')  subtitle(Threshold parameters) size(small)) name(map,replace) ytitle("                           Frequencies")  ylabel(0(`=`maxi'/5')`maxi' `maxi'(`maxi')`=`maxi'*2' ,axis(2)) yscale(axis(2) off) yscale(axis(3) off)  ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) yline(0,lwidth(medium) lpattern(solid) lcolor(black))  ylabel(`ylbl',/*noticks*/ grid angle(0) axis(1)) ylabel(`ylbl' 0(`=`maxe'/5')`maxe', grid angle(0) axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait - * : dysfunctioning items") xtitle("`xtitle'") `fsm' subtitle(`dimname')
+		}
+		else if "`eqset1'"!="" {
+			qui su eff
+	        local ceil=ceil(ceil(`r(max)'/10)*10)
+
+            qui tempfile equating
+			qui save `equating', replace
+		}
+	}
+	qui use `savefile', clear
+}
+		 
+
+
+/*************************************************************************************************************
+Best estimates by category 
+*************************************************************************************************************/
+
+tempname bestest
+matrix `bestest'=J(`nbitems',`=`modamax'+1',.)
+di
+local long=`modamax'*8+33
+di
+di "Best estimates by answer category" 
+di "{hline `long'}"
+di "Item" _col(29) "Cat 0"  _c
+forvalues j=1/`modamax' {
+     local col=29+`j'*8 
+	 di _col(`col') "Cat `j'"     _c
+}
+di
+di "{hline `long'}"
+forvalues i=1/`nbitems' {
+    di "``i''" _c
+	forvalues j=0/`modamax`i'' {
+	    di _col(`=28+`j'*8') %6.3f round(`bestest``i''_`j'', 0.001) _c
+		matrix `bestest'[`i',`=`j'+1']=`bestest``i''_`j''
+	}
+	di
+}
+di "{hline `long'}"
+		
+
+
+/*************************************************************************************************************
+EQUATING
+*************************************************************************************************************/
+if "`eqset1'"!="" {
+    if "`eqgenscore'"!="" {
+	   local tmp1 `=ustrlen("`eqgenscore'`eqset1name'")'
+	   local tmp2 `=ustrlen("`eqgenscore'`eqset2name'")'
+	   local mlength=max(`tmp1',`tmp2')
+	   if `mlength'>27 {
+			di as error "The number of characters containing in the strings eqgenscore+eqset1name or eqgenscore+eqset2name must be lesser than 27"
+			di as error "eqgenscore+eqset1name : `tmp1' characters"
+			di as error "eqgenscore+eqset2name : `tmp2' characters"
+			error 130
+			*exit
+		}
+	}
+	if "`eqset1name'"=="" {
+	   local eqset1name="Set 1"
+	}
+	if "`eqset2name'"=="" {
+	   local eqset2name="Set 2"
+	}
+	local eqset1name `=regexreplaceall("`eqset1name'"," ","_",.)'
+	local eqset2name `=regexreplaceall("`eqset2name'"," ","_",.)'
+	*di "set1:`eqset1name' set2:`eqset2name'"  
+
+    tokenize `eqset1'
+	local nbset1: word count `eqset1'
+	forvalues i=1/`nbset1' {
+	   local eq1_`i':word `i' of `eqset1'
+	}
+    tokenize `eqset2'
+	local nbset2: word count  `eqset2'
+	forvalues i=1/`nbset2' {
+	   local eq2_`i':word `i' of `eqset2'
+	}	
+
+
+
+	tempfile fileeq
+	qui save `fileeq',replace
+	forvalues t=1/2{
+		local scoremaxset`t'=0
+		forvalues i=1/`nbset`t'' {
+			local scoremaxset`t'=`scoremaxset`t''+`modamax`eq`t'_`i'''
+		}
+	}
+	drop _all
+	qui set obs `=(`scoremaxset1'+`scoremaxset2'+2)*3'
+	forvalues t=1/2 {
+		qui gen scoreset`t'=.
+		qui gen scoreset`t'm=.
+		qui gen scoreset`t'p=.	
+	}
+	forvalues i=0/`scoremaxset1' {
+	    qui replace scoreset1=`i' in `=`i'+1'
+	    qui replace scoreset1m=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset1p=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	forvalues i=`=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2' {
+	    qui replace scoreset2=`i'-`scoremaxset1'-2 in `i'
+	    qui replace scoreset2m=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset2p=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	local s=0
+	local eqset1b
+	foreach i in `eqset1' {
+		qui gen s1_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s1_`i'_`m'=0 in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'_`m'=1 if scoreset1>`s' in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'=s1_`i'+s1_`i'_`m'
+		   local ++s
+		}
+	    local eqset1b `eqset1b' s1_`i'
+	}
+	local s=0
+	local eqset2b
+	foreach i in `eqset2' {
+		qui gen s2_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s2_`i'_`m'=0 in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'_`m'=1 if scoreset2>`s' in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'=s2_`i'+s2_`i'_`m'
+		   local ++s
+		}
+		local eqset2b `eqset2b' s2_`i'
+	}
+	tokenize `varlist'
+	tempname diffset1 diffset2
+	forvalues t=1/2 {
+		qui matrix `diffset`t''=J(`nbset`t'',`modamax',.)
+		local n=1
+		local listset`t'
+		foreach j in `eqset`t'' {
+			forvalues i=1/`nbitems' {
+				if "`j'"=="``i''" {
+					local listset`t' `listset`t'' `i'
+					forvalues m=1/`modamax' {
+						qui matrix `diffset`t''[`n',`m']=`diffmat'[`i',`m']
+					}
+					local ++n						
+				}
+			}
+		}
+	}
+	local var=`covariates'[1,1]
+	qui gen lt=.
+	forvalues t=1/2 {
+		tempname matscorelt`t'
+		qui pcm `eqset`t'b', diff(`diffset`t'') var(`var') minsize(1)
+		qui matrix `matscorelt`t''=r(matscorelt)
+		forvalues i=0/`scoremaxset`t'' {
+			qui replace lt=`matscorelt`t''[`=`i'+1',2] if scoreset`t'==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]+1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'p==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]-1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'm==`i'
+		}
+		qui ipolate scoreset`t' lt, gen(score`t') epolate
+	}
+	qui ipolate scoreset1 lt, gen(score1bis) epolate
+
+
+	forvalues t=1/2 {
+		qui replace score`t'=scoreset`t'm if scoreset`t'm!=.
+		qui replace score`t'=scoreset`t'p if scoreset`t'p!=.
+		qui replace score1=score1bis if score1==.
+		qui replace score`t'=0 if score`t'<0
+		qui replace score`t'=`scoremaxset`t'' if score`t'>`scoremaxset`t''
+	}
+	local pciset1
+	local pciset2
+	*set trace on
+	local minimini=0
+	local maximaxi=0
+	forvalues t=1/2 {
+        qui gen adjscore`t'=(score`t'+`eqaddset`t'')*`eqmultset`t''
+	    qui gen adjscore`=3-`t''=(score`=3-`t''+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''
+		tempname matscore`t'
+		qui matrix `matscore`t''=J(`=`scoremaxset`t''+1',7,.)
+		*set trace on
+		forvalues s=0/`scoremaxset`t'' {
+		    qui matrix `matscore`t''[`=`s'+1',1]=`s'
+			qui su lt if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',2]=r(mean)
+			if `ceil'==0 {
+				local ceil=1
+			}
+			if "`eqwithic'"=="" {
+				local pciset`t'  `pciset`t'' scatteri `=-`ceil'/5*`t'' `r(mean)' (12) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , mlabsize(tiny) mcolor(black) mlabcolor(black)||
+			}
+			local mean=r(mean)
+			qui su lt if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',3]=r(mean)
+			local moins=r(mean)
+			if `moins'<`minimini' {
+				*di "local minimini=floor(`moins')"
+				local minimini=floor(`moins')
+			}
+			qui su lt if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',4]=r(mean)
+			local plus=r(mean)
+			if `plus'>`maximaxi' {
+				*di "local maximaxi=ceil(`plus')"
+				local maximaxi=ceil(`plus')
+			}
+
+			if "`eqwithic'"!="" {
+				local y=-`ceil'/5*((2.5*`t'-2)+2*(`s'/`scoremaxset`t''))
+				*local pciset`t'  `pciset`t'' scatteri `y' `mean' (12) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , mlabsize(tiny) mcolor(black) mlabcolor(black)|| pci `y' `moins' `y' `plus',pstyle(p1) color(black)||
+				local pciset`t'  `pciset`t'' scatteri `y' `mean'  , mlabsize(tiny) mcolor(black) mlabcolor(black)|| scatteri `y' `moins' (9) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , msize(0) mlabsize(tiny) mcolor(black) mlabcolor(black)|| pci `y' `moins' `y' `plus',pstyle(p1) color(black)||
+			}
+			qui su score`=3-`t'' if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',5]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',6]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',7]=r(mean)
+		}
+		matrix colnames `matscore`t'' =score`t' lt lt- lt+ score`=3-`t'' score`=3-`t''- score`=3-`t''+
+		di as text
+		di as text "{hline 78}"
+		di as text "EQUATING `eqset`t'name' TO `eqset`=3-`t''name'"
+		di as text "{hline 78}"
+		di "`eqset`t'name' : `eqset`t''"
+		di "`eqset`=3-`t''name' : `eqset`=3-`t'''"
+		local eqset`t'namea=abbrev("`eqset`t'name'",18)
+		local eqset`=3-`t''namea=abbrev("`eqset`=3-`t''name'",12)
+		di "{hline 78}"
+		di "Score"           _col(20) "<----- Latent trait ----->" _col(52) "<- Score `eqset`=3-`t''namea'" _col(77) "->"
+		di "`eqset`t'namea'" _col(20) "Estimated" _col(39) "[95%IC]" _col(52) "Estimated" _col(72) "[95%IC]"
+		di "{hline 78}"
+		forvalues s=0/`scoremaxset`t'' {
+		    local min=min(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+		    local max=max(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+			
+			di %4.0f `=(`matscore`t''[`=`s'+1',1]+`eqaddset`t'')*`eqmultset`t''' _col(24) %5.2f `matscore`t''[`=`s'+1',2] _col(33) "[" %5.2f `matscore`t''[`=`s'+1',3] ";" %5.2f `matscore`t''[`=`s'+1',4] "]" _col(56) %5.2f `=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''' _col(66) "[" %5.2f `min' ";" %5.2f `max' "]"			
+		}
+		di "{hline 78}"
+		if "`eqgraph'"!="" {
+		    *set trace on
+			if `eqmultset`=3-`t'''>0 {
+				local xlabel 	"`=`eqaddset`=3-`t'''*`eqmultset`=3-`t''''(`=ceil((`scoremaxset`=3-`t'''*`eqmultset`=3-`t''')/20)')`=(`scoremaxset`=3-`t'''+`eqaddset`=3-`t''')*`eqmultset`=3-`t''''"
+			}
+			else {
+				local xlabel 	"`=(`scoremaxset`=3-`t'''+`eqaddset`=3-`t''')*`eqmultset`=3-`t''''(`=ceil((-`scoremaxset`=3-`t'''*`eqmultset`=3-`t''')/20)')`=`eqaddset`=3-`t'''*`eqmultset`=3-`t''''"
+			}
+			if `eqmultset`t''>0 {
+				local ylabel 	"`=`eqaddset`t''*`eqmultset`t'''(`=ceil((`scoremaxset`t''*`eqmultset`t'')/20)')`=(`scoremaxset`t''+`eqaddset`t'')*`eqmultset`t'''"
+			}
+			else {
+				local ylabel 	"`=(`scoremaxset`t''+`eqaddset`t'')*`eqmultset`t'''(`=ceil((-`scoremaxset`t''*`eqmultset`t'')/20)')`=`eqaddset`t''*`eqmultset`t'''"
+			}
+			*set trace off
+			*di "xlabel : `xlabel'"
+			*di "subtitle=`subtitle'"
+			twoway (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''!=.,lcolor(black) lpattern(solid) lwidth(thick)) (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''m!=.,lcolor(black) lpattern(dash) lwidth(thin)) (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''p!=.,lcolor(black) lpattern(dash) lwidth(thin)), title("Equating score of `eqset`=3-`t''name' to `eqset`t'name' ") ytitle("Score `eqset`t'name'") xtitle("Score `eqset`=3-`t''name'") ylabel(`ylabel') xlabel(`xlabel') name(eq`t'to`=3-`t'') legend(order(1 2) label(1 "Estimated") label(2 "95%IC") position(6)) subtitle("`dimname'") 
+		}
+		qui drop adjscore`t' adjscore`=3-`t''
+	}
+	
+	if "`eqgraph'"!="" {
+		qui use "`equating'",clear
+	    qui su u
+	    local flooru=floor(`r(min)')
+	    local ceilu=ceil(`r(max)')
+		qui su eff
+	    local ceil=ceil(ceil(`r(max)'/10)*10)
+		if `ceil'==0 {
+		   local ceil=1
+		}
+
+		local title "Equating"
+		if "`eqset1name'"!=""&"`eqset2name'"!=""{
+		   local title "Equating between `eqset1name' and `eqset2name'"
+		}
+		if "`eqwithic'"=="" {
+		   local ylabel1=-`ceil'/5
+		   local ylabel2=-2*`ceil'/5
+		   local gapu=ceil((`ceilu'-`flooru')/15)
+		}
+		else {
+		    local ylabel1=-0.5*`ceil'/5
+		    local ylabel2=-3*`ceil'/5
+		   	local flooru=min(`flooru',`minimini')
+			local ceilu=max(`ceilu',`maximaxi')
+			local gapu=ceil((`ceilu'-`flooru')/15)
+		}
+	    *di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`flooru'(1)`ceilu') color(erose)) || `pciset1' `pciset2'  , yline(0, lcolor(black)) legend(off) name(equating,replace) ytitle(                           Frequencies)    ylabel(`=-`ceil'/5*2' `eqset1name' `=-`ceil'/5' `eqset2name' 0(`=`ceil'/5')`ceil', grid angle(0) axis(1)) title(Equating) xsize(12) ysize(9)  xtitle(Latent trait) "
+	    qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`flooru'(`gapu')`ceilu') color(erose)) || `pciset1' `pciset2'  , yline(0, lcolor(black)) legend(off) name(equating,replace) ytitle("                           Frequencies")    /*ylabel(`ylbl', grid angle(0) axis(1))*/ ylabel(`ylabel1' "`eqset1name'" `ylabel2' "`eqset2name'" 0(`=`ceil'/5')`ceil', grid angle(0) axis(1)) title("`title'") subtitle("`dimname'") xsize(12) ysize(9)  xtitle("Latent trait") 
+	}
+	qui use `fileeq',clear
+	*set trace on
+	tempname scoreset1 scoreset2
+	forvalues t=1/2 {
+		qui genscore `eqset`t'' if `touse',score(`scoreset`t'')
+	 	qui su `scoreset`t'' if `touse'
+		local maxscoreset=r(max)
+		*qui matrix list `matscore`t''
+		if "`eqgenscore'"!="" {
+			local eqgenscore `=regexreplaceall("`eqgenscore'"," ","_")'
+			*di "eqgenscore : `eqgenscore'"
+			foreach k in mean min max random {
+				capture confirm  variable `eqgenscore'_`k'_`eqset`=3-`t''name'
+				if _rc==0&"`replace'"!="" {
+					qui replace `eqgenscore'_`k'_`eqset`=3-`t''name'=. if `touse'
+				}
+				else if _rc==0&"`replace'"!="" {
+					di as error "The variable `eqgenscore'_`k'_`eqset`=3-`t''name' already exists"
+					error 198
+				}
+				else {
+					qui gen `eqgenscore'_`k'_`eqset`=3-`t''name'=. if `touse'
+				}
+			}
+			*tab `scoreset`t''
+			forvalues s=0/`maxscoreset' {
+				*di "qui replace `eqgenscore'_`eqset`=3-`t''name'=`=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''' if `scoreset`t''==`s'"
+				local min=min(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+				local max=max(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+				qui replace `eqgenscore'_mean_`eqset`=3-`t''name'=round(`=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_min_`eqset`=3-`t''name'=round(`min',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_max_`eqset`=3-`t''name'=round(`max',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_random_`eqset`=3-`t''name'=round(uniform()*(`max'-`min')+`min',1) if round(`scoreset`t'',1)==`s'&`touse'
+			}
+		}
+		return matrix score`t'_to_`=3-`t''=`matscore`t''
+	}
+	
+}
+
+
+/*************************************************************************************************************
+RETOUR AU FICHIER INITIAL ET SAUVEGARDE DES NOUVELLES VARIABLES
+*************************************************************************************************************/
+*set trace on
+if "`visit'"!="" {
+	tempfile sauv
+	*set trace on
+	*tempname corrlatent corrbilatent
+	qui keep `latent'* `selatent'* `id' `visit' 
+    qui reshape wide , i(`id') j(`visit')
+	qui sort `id'	
+	qui save `sauv', replace
+	restore,preserve
+	if "`replace'"!=""&("`genlt'"!=""|"`geninf'"!="") {
+    	capture drop `genlt' 
+    	capture drop `genlt'_se 
+    	capture drop `geninf' 
+    	capture drop `genlt'_corr
+    	capture drop `genlt'_opt
+    	capture drop `genlt'_opt_se
+    }
+	*su
+	tempname idorder
+	qui gen `idorder'=_n 
+	qui sort `id'
+	qui merge 1:1 `id' using `sauv'
+	
+	qui sort `idorder'
+    qui drop `idorder'	
+}
+else {
+*set trace on
+*set tracedepth 1
+    if "`genlt'"!="" {
+		qui gen `genlt'_corr=`corrlatent' if `touse'
+/*		qui gen `genlt'_corr2=. if `touse'
+		forvalues s=0/`scoremax' {
+			qui replace `genlt'_corr2=`estlt`s'' if `score'==`s'&`touse'
+		}
+		forvalues g=1/`nbgroups' {
+			qui replace `genlt'_corr2=`clt`g'' if `group'==`g'&`genlt'_corr==.&`touse'
+		}
+*/
+		tempvar tmpitem mean nbnonmiss
+		forvalues i=1/`nbitems' {
+			qui gen `tmpitem'_`i'=. if `touse'
+			forvalues k=0/`modamax' {
+				qui replace `tmpitem'_`i'=`bestest'[`i',`=`k'+1'] if ``i''==`k'&`touse'
+			}
+		}
+		*su
+		qui egen `genlt'_opt=rowmean(`tmpitem'_*) if `touse'
+		*qui egen `genlt'_opt_se=rowsd(`tmpitem'_*) if `touse'
+		qui egen `nbnonmiss'=rownonmiss(`tmpitem'_*) if `touse'
+		*qui replace `genlt'_opt_se=sqrt((`genlt'_opt_se^2+`resvar')/`nbnonmiss') if `touse'
+ 	}
+	restore,not
+}
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin, footer(fall_report)
+	putdocx table hdr = (1, 3), border(all, nil) tofooter(fall_report)
+	if "`rsm'"=="" {
+		putdocx table hdr(1, 1) = ("Partial Credit Model")
+	}
+	else {
+		putdocx table hdr(1, 1) = ("Rating Scale Model")
+	}
+	putdocx table hdr(1, 2) = ("`dimname'"), halign(center)
+	putdocx table hdr(1, 3) = ("Page "), pagenumber
+	putdocx table hdr(1, 3) = ("/"), totalpages append
+	putdocx table hdr(1, 3), halign(right)
+	putdocx paragraph ,style(Title)
+	if "`dimname'" =="" {
+	    local dimname2 "Rasch analysis"
+	}
+	else {
+	    local dimname2 "Rasch analysis of the `dimname' dimension"
+	}
+	putdocx text ("`dimname2'") ,
+	putdocx paragraph ,style(Subtitle)
+	putdocx text ("General informations") ,
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("Names of the dimension: `dimname'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph, style(Subtitle)
+	putdocx text ("Estimation of the parameters") , 
+	local paramname
+	forvalues j=1/`nbitems' {
+		forvalues k=1/`modamax' {
+		     if `k'<=`modamax`j'' {
+			     local paramname `paramname' "``j''_`k'"
+			 }
+	    }
+	}
+	*di "matrix colnames `diff'=`paramname'"
+	matrix rownames `diff'=`paramname'
+    putdocx table table1 = matrix(`diff') , nformat(%9.3f) rownames colnames  border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil) headerrow(1)  halign(center)
+    putdocx table table1(.,1), halign(left) 
+    putdocx table table1(.,2/7), halign(right) 
+    putdocx table table1(1,.), halign(right) border(top) border(bottom)
+	
+	
+	qui putdocx table table2 = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)  headerrow(1)
+    putdocx table table2(.,1), halign(left) 
+    putdocx table table2(.,2/7), halign(right) 
+    putdocx table table2(1,.), halign(right) border(top) border(bottom)
+
+
+
+	
+	putdocx paragraph,style(Subtitle)
+	putdocx text ("Fit indexes for items") , /*bold underline font(,14) smallcaps*/
+	qui putdocx table table3 = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)    headerrow(1)
+    putdocx table table3(.,1), halign(left) 
+    putdocx table table3(.,2/5), halign(right) 
+    putdocx table table3(1,.), halign(right) border(top) border(bottom)
+
+
+
+	putdocx paragraph, style(Subtitle)
+	putdocx text ("Estimation per group/score")
+	*putdocx text ("Estimation per group/score") , bold underline font(,14) smallcaps
+	*set trace on
+	putdocx table tbl = (`=`nbrowmat'+1',7), border(all,nil) width(7) halign(center) note(EAP: Expected A Posteriori ; BE: Best Estimates) headerrow(1)
+    putdocx table tbl(1,.), halign(right) border(top) border(bottom)
+	putdocx table tbl(1,1) = ("Group"), halign(right) 
+	putdocx table tbl(1,2) = ("score"), halign(right) 
+	putdocx table tbl(1,3) = ("Frequency"), halign(right) 
+	putdocx table tbl(1,4) = ("EAP Mean"), halign(right) 
+	putdocx table tbl(1,5) = ("EAP s.e."), halign(right) 
+	putdocx table tbl(1,6) = ("Exp score"), halign(right) 
+	putdocx table tbl(1,7) = ("BE Mean"), halign(right) 
+	local fin=1
+	forvalues row=1/`nbrowmat' {
+	    local row2=`row'+1
+		local g: di %9.0f `matgroupscorelt'[`row',1]
+		local gh=`matgroupscorelt'[`row',1]
+		if `fin'==1 {
+			putdocx table tbl(`row2',1) = ("`g'"), halign(right) 
+		}
+		if `matgroupscorelt'[`row',2]!=.|`matgroupscorelt'[`row',7]==. {
+		    local s: di %9.0f `matgroupscorelt'[`row',2]
+			local fin=0
+		}
+		else {
+			local s "`scoremin`gh''/`scoremax`gh''"
+			local fin=1
+			*local fin "border(top) border(bottom)"
+			*di "c'est la fin"
+			putdocx table tbl(`row2',.),  border(bottom) border(top, dashed)
+			putdocx table tbl(`row2',1), border(top, nil)
+		}
+		local eff: di %9.0f `matgroupscorelt'[`row',3]
+		local lt: di %9.3f `matgroupscorelt'[`row',4]
+		local se: di %9.3f `matgroupscorelt'[`row',5]
+		local exp: di %9.2f `matgroupscorelt'[`row',6]
+		local clt: di %9.3f `matgroupscorelt'[`row',7]
+		*putdocx table tbl(`row',.), addrows(7)
+		putdocx table tbl(`row2',2) = ("`s'"), halign(right) 
+		putdocx table tbl(`row2',3) = ("`eff'"), halign(right) 
+		putdocx table tbl(`row2',4) = ("`lt'"), halign(right) 
+		putdocx table tbl(`row2',5) = ("`se'"), halign(right) 
+		putdocx table tbl(`row2',6) = ("`exp'"), halign(right) 
+		putdocx table tbl(`row2',7) = ("`clt'"), halign(right) 
+
+	}
+
+/*
+		qui matrix `matgroupscorelt'[`row',1]=`g'
+		*qui matrix `matgroupscorelt'[`row',2]="`scoremin`g''/`scoremax`g''"
+		qui matrix `matgroupscorelt'[`row',3]=`eff`g''
+		qui matrix `matgroupscorelt'[`row',4]=`lt`g''
+		qui matrix `matgroupscorelt'[`row',5]=`se'
+		*qui matrix `matgroupscorelt'[`row',6]=`exp'
+		qui matrix `matgroupscorelt'[`row',7]=`clt`g''
+		local ++row
+	}
+	local nbrowmat=`row'-1
+
+
+local row 1
+local vari 1
+foreach x in gear_ratio turn foreign _cons {
+putdocx table tbl5(`row',.), addrows(2)
+local b: display %9.3f rtable[`vari',1]
+local se: display %9.3f rtable[`vari',2]
+local ++vari
+local ++row
+putdocx table tbl5(`row',1) = ("`x'"), halign(right)
+putdocx table tbl5(`row',2) = ("`b'"), halign(right)
+local ++row
+local se = strtrim("`se'")
+putdocx table tbl5(`row',2) = ("(`se')"), halign(right)
+}*/
+	
+	*qui putdocx table tablename = matrix(`matgroupscorelt') , nformat(%9.3f) /*rownames*/ colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+				putdocx paragraph, style(Subtitle)
+				putdocx text ("General Graphs")
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			putdocx paragraph, style(Subtitle)
+			putdocx text ("Graphs per item")
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+					putdocx paragraph, style(Heading1)
+				    putdocx text ("Graphs for ``i''") 
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+*set trace on
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+return matrix matscorelt=`matscorelt'
+return matrix matgroupscorelt=`matgroupscorelt'
+return matrix bestest=`bestest'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm 5.4.ado b/Modules/ado/personal/p/pcm 5.4.ado
new file mode 100644
index 0000000..2ef1b82
--- /dev/null
+++ b/Modules/ado/personal/p/pcm 5.4.ado	
@@ -0,0 +1,2298 @@
+*! Version 5.4 28July2023
+*! Jean-Benoit Hardouin, Myriam Blanchin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
+* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
+* Version 4.1: September 15th, 2019 [Jean-Benoit Hardouin]: correction of a small bug in the outputs
+* Version 4.2: September 27th, 2019 [Jean-Benoit Hardouin] : EQUATING
+* Version 4.3: November 8th, 2019 [Jean-Benoit Hardouin] : add a constant when difficulty parameters are fixed
+* Version 5: August 2nd, 2022 [Jean-Benoit Hardouin] : New MAP graph, corrected estimation of the latent trait
+* Version 5.1: July 8th, 2023 [Jean-Benoit Hardouin] : Correction of the MAP graph (histogram) and residuals graphs
+* Version 5.2: July 16th, 2023 [Jean-Benoit Hardouin] : Add of new graphs for Equating
+* Version 5.3: July 21th, 2023 [Jean-Benoit Hardouin] : Improvements for the docx option
+* Version 5.4: July 28th, 2023 [Jean-Benoit Hardouin] : Improvements for graphs et corrections of bugs
+*
+*
+* Jean-benoit Hardouin, Myriam Blanchin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr, myriam.blanchin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019, 2022, 2023 Jean-Benoit Hardouin, Myriam Blanchin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [if] [in] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) VARiance(real -1) rsm Graphs noGRAPHItems noCORRected filesave dirsave(string) docx(string) extension(string) alpha(real 0.01)  PCE WMLiterate(int 1) GENLT(string) GENINF(string) REPlace postpce visit(varname) id(varname) eqset1(varlist) eqset2(varlist) eqset1name(string) eqset2name(string) EQGraph eqaddset1(real 0) eqaddset2(real 0) eqmultset1(real 1) eqmultset2(real 1) eqwithci eqgenscore(string)  DIMname(string) minsize(int 30) vardif(varname) itemsdif(varlist) noRESiduals]
+
+version 14
+preserve
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+/*************************************************************************************************************
+QUELQUES TESTS
+*************************************************************************************************************/
+
+if `variance'!=-1&`variance'<=0 {
+	di in red "The -variance- option cannot be negative"
+	exit 198
+}
+if `variance'!=-1&"`visit'"!="" {
+	di in red "The -variance- and -visit- options cannot be used simultaneously."*
+	exit 198
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' `genlt'_se `geninf' `genlt'_corr `genlt'_opt `genlt'_opt_se 
+	if _rc!=0&"`replace'"=="" {
+	    di in red "The variables `genlt', `genlt'_se, `genlt'_corr, `genlt'_opt, `genlt'_opt_se and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+	if _rc!=0&"`replace'"!="" {
+	    qui capture drop `genlt' 
+		qui capture drop `genlt'_se 
+		qui capture drop `geninf' 
+		qui capture drop `genlt'_corr
+		qui capture drop `genlt'_opt
+		qui capture drop `genlt'_opt_se
+	}
+}
+if ("`eqset1'"!=""&"`eqset2'"=="")|("`eqset1'"==""&"`eqset2'"!="") {
+    di in red "The two options -eqset1- and -eqset2- must be used simultaneously"
+	exit 198
+}
+if ("`eqset1'"!=""&"`graphs'"!="") {
+    di in red "The two options -eqset1- and -graph- cannot be used simultaneously"
+	exit 198
+}
+if "`corrected'"!="" {
+	local xtitle "Latent trait"
+}
+else {
+	local xtitle "Corrected latent trait"
+}
+
+
+
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+if "`visit'"!=""{
+	if "`id'"==""{
+		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
+		exit 198
+	}
+	qui levelsof `visit'
+	local levelsofv `r(levels)'
+	local nbvisits=r(r)
+	local timemin: word 1 of `levelsofv'
+	local timemax: word `nbvisits' of `levelsofv'
+	if `timemax'>5{
+		di as error "You must use a discrete time variable (-visit- option) with less than 5 measurement occasions"
+		error 198
+	}
+	if `timemin'!=1{
+		di as error "You must use a -visit- variable coded at 1 for the first visit"
+		error 198
+	}
+	qui reshape wide `varlist', i(`id') j(`visit')
+	local multivisit=1
+}
+else {
+	local timemax=1
+	foreach i in `varlist' {
+	   *rename `i' `i'1
+	}
+	local multivisit
+}
+qui count if `touse'
+local nbobs=r(N)
+
+local timelist
+forvalues t=1/`timemax'{
+	local timelist `timelist' T`t'
+}
+
+local modcont
+local premodcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local premodcont (`modcont'->T1)
+	local modcont (`modcont'->`timelist')
+}
+
+local modcat
+local premodcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local premodcat (`modcat'->T1)
+	local modcat (`modcat'->`timelist')
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+local scoremax=0
+forvalues i=1/`nbitems' {
+    local name``i'': variable label ``i''
+	if "`name``i'''"=="" {
+		local name``i'' ``i''
+	}
+	local modamax`i'=1
+	local modamax``i''=1
+	if `timemax'>1 {
+		forvalues t=1/`timemax'{
+			 *qui replace ``i'`t''=``i'`t''-`min' 
+			 qui su ``i''`t' if `touse'
+			 if `r(min)'!=`modamin' {
+				 local modamin=r(min)
+				 local pbmin `pbmin' ``i'`t''
+			 }
+			 if `r(max)'>`modamax' {
+				 local modamax=r(max)
+			 }
+			 if `r(max)'>`modamax`i'' {
+				local modamax`i'=r(max)
+			}
+		}
+	}
+	else {
+		*di "i: `i' ``i''"
+		qui su ``i'' if `touse'
+		if `r(min)'!=`modamin' {
+		    local modamin=r(min)
+			local pbmin `pbmin' ``i''
+		}
+		if `r(max)'>`modamax' {
+			local modamax=r(max)
+		}
+		if `r(max)'>`modamax`i'' {
+			local modamax`i'=r(max)
+			local modamax``i''=r(max)
+		}
+	}
+	*di "local scoremax=`scoremax'+`modamax`i''"
+	local scoremax=`scoremax'+`modamax`i''
+	if "`rsm'"=="" {
+		local nbdiff=`nbdiff'+`modamax`i''
+	}
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count if `touse'
+local nbind=r(N)
+*set trace on
+local code
+local precode
+if `timemax'>1 {
+	forvalues k=1/`modamax' {
+	   forvalues t=1/`timemax'{
+			local code`k'
+		   forvalues i=1/`nbitems' {
+			   if `k'<=`modamax`i'' {
+				  local code`k' `code`k'' `k'.``i''`t'
+			   }
+		   }
+		   local code`k' (`code`k''<-T`t'@`k')
+		   if `t'==1{
+				local precode `precode' `code`k''
+		   }
+		   local code `code' `code`k''
+		}
+	}
+}
+else {
+	forvalues k=1/`modamax' {
+		local code`k'
+		forvalues i=1/`nbitems' {
+			if `k'<=`modamax`i'' {
+				local code`k' `code`k'' `k'.``i''
+			}
+		}
+		local code`k' (`code`k''<-T1@`k')
+		local precode `precode' `code`k''
+		local code `code' `code`k''
+	}
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist' if `touse'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist' if `touse', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+local t=1
+local constraints
+local codemean
+local codevar
+local codecov
+forvalues j=2/`timemax'{
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			qui constraint `t' [`k'.``i''`j']_cons=[`k'.``i''`multivisit']_cons
+			local constraints `constraints' `t'
+			local ++t
+			
+		}
+	}	
+	if "`continuous'"=="" &  "`categorical'"==""{
+		local codemean `codemean' T`j'@m`j'
+		local codevar `codevar' T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' T`l'*T`j'@cov`l'`j'
+		}
+	}
+	else{
+		local codevar `codevar' e.T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
+		}	
+	}
+}
+if `timemax'>1{
+	if "`continuous'"=="" &  "`categorical'"==""{	
+		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
+	}
+	else{
+		local codelg var(e.T1@v1 `codevar') cov(`codecov')
+	}
+}
+else {
+    local constrvar
+    if `variance'>0 {
+		if "`continuous'"=="" &  "`categorical'"==""{	
+			local constrvar var(T1@`variance') 
+		}
+		else{ 
+			*local constrvar var(e.T1@`variance') 
+		}
+	}
+}
+
+local fixedmean
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				qui constraint `t' [`k'.``i''`multivisit']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+	if "`continuous'"=="" &  "`categorical'"=="" {	
+		local fixedmean mean(T1) 
+	}
+	else{
+		local fixedmean 
+	}
+}
+
+
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+if "`rsm'"!="" {
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       qui constraint `t'   [`=`k'-1'.``i''`multivisit']_cons-[`k'.``i''`multivisit']_cons+[1.``i''`multivisit']_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
+if "`model'"!="" {
+    local qui
+}
+else {
+	local qui qui
+}
+if `timemax'==1{
+   *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'"
+   `qui' gsem `code' `modcont' `modcat' if `touse' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+   *qui gen un=1
+   *`qui' gsem `code' (i.group un->T) ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+}
+else{
+    *di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
+    `qui' gsem `precode' `premodcont' `premodcat' if `touse',iterate(`iterate') tol(`tolerance') constraint(`constraints') 
+     matrix esti_B = e(b)
+    *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)"
+    `qui' gsem `code' `modcont' `modcat' if `touse',iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
+}
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2 miss
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent'* if `touse',latent se(`selatent'*)
+*di "latent=`latent' "
+*su
+*set trace on
+
+if "`genlt'"!="" {
+	if `timemax'==1 {
+		qui gen `genlt'=`latent'1 if `touse'
+		qui gen `genlt'_se=`selatent'1 if `touse'
+	}
+	forvalues t=2/`timemax' {
+		qui gen `genlt'`t'=`latent'`t' if `touse'
+		qui gen `genlt'`t'_se=`selatent'`t' if `touse'
+	}
+}
+
+set seed 123456
+if `timemax'>1 {
+	forvalues t=1/`timemax'{
+		qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t' if `touse'
+		local listit 
+		forvalues i=1/`nbitems' {
+			local listit `listit' ``i''`t'
+		}
+		qui genscore `listit' if `touse',score(`score'`t')
+		qui gengroup `latent'`t' if `touse',newvariable(`group'`t') continuous minsize(`minsize')
+	}
+}
+else {
+	qui gen `latent2'=`latent'1+invnorm(uniform())*`selatent'1 if `touse'
+	local listit 
+	forvalues i=1/`nbitems' {
+		local listit `listit' ``i''
+	}
+	qui genscore `listit' if `touse',score(`score')
+	qui gengroup `latent'1 if `touse',newvariable(`group') continuous minsize(`minsize')
+}
+forvalues s=0/`scoremax' {
+    qui count if `score'==`s'&`touse'
+	local effscore`s'=r(N)
+}
+
+
+/*time 1 only*/
+qui levelsof `group'`multivisit' if `touse'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+10',.)
+forvalues g=1/`nbgroups' {
+	matrix `groups'[`g',`=`nbitems'+3']=0
+	qui count if `group'`multivisit'==`g'&`touse'
+	local effgroup`g'=r(N)
+	forvalues i=1/`nbitems' {
+			qui count if ``i''`multivisit'!=.&`group'`multivisit'==`g'&`touse'
+			local n=r(N)
+			if `n'>0 {
+				qui su ``i''`multivisit' if `group'`multivisit'==`g'&`touse'
+				matrix `groups'[`g',`i']=r(mean)
+				matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+			}
+			else {
+				matrix `groups'[`g',`i']=.
+				matrix `groups'[`g',`=`nbitems'+3']=.
+			}		
+	}
+	qui su `latent'1 if `group'`multivisit'==`g'&`touse'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	matrix `groups'[`g',`=`nbitems'+7']=r(min)
+	matrix `groups'[`g',`=`nbitems'+8']=r(max)
+	qui count if `group'`multivisit'==`g'&`touse'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+	qui su `score' if `group'`multivisit'==`g'&`score'!=.&`touse'
+	matrix `groups'[`g',`=`nbitems'+4']=r(min)
+	matrix `groups'[`g',`=`nbitems'+5']=r(max)	
+}
+
+/*number of non-missing on all time points*/
+egen `miss'=rowmiss(`score'*) if `touse'
+qui count if `miss'==0&`touse'
+local nbobsssmd=r(N)
+drop `miss'	
+
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of individuals with a complete answer pattern:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i''`multivisit':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i''`multivisit':_cons]
+	qui lincom -_b[1.``i''`multivisit':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+	local rn `rn' 1.``i''`multivisit'
+	local ++t
+	local sum _b[1.``i''`multivisit':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax`i'' {
+			local sum "_b[`k'.``i''`multivisit':_cons]-(`sum')"
+			*di "``i''`multivisit' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i''`multivisit':_cons]-_b[`k'.``i''`multivisit':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''`multivisit'
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1'`multivisit':_cons]-_b[`k'.`1'`multivisit':_cons]+_b[1.`1'`multivisit':_cons] /*``i'' instead of `i'?*/
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+*di "matrix rownames `diff'=`rn'"
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
+*************************************************************************************************************/
+tempname covariates
+local nbcov=0
+forvalues j=2/`timemax'{
+	local nbcov=`nbcov'+`j'-1
+}
+qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)
+
+*set trace on
+local t=1
+
+
+forvalues j=1/`=`timemax'-1'{
+	forvalues k=`=`j'+1'/`timemax'{
+		if "`categorical'"=="" & "`continuous'"=="" {
+			if `j'==1{
+				qui lincom [/]mean(T`k')
+			}
+			else{
+				qui lincom [/]mean(T`k')-[/]mean(T`j')
+			}
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+		else{
+			if "`categorical'"!=""{
+				local first=0 
+				foreach l in `levelsof`cat1'' {
+					if `first'==0 {
+						local ++first
+					}
+					else{
+						if `first'==1 {
+							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
+							qui matrix `covariates'[`t',1]=`r(estimate)'
+							qui matrix `covariates'[`t',2]=`r(se)'
+							qui matrix `covariates'[`t',3]=`r(z)'
+							qui matrix `covariates'[`t',4]=`r(p)'
+							qui matrix `covariates'[`t',5]=`r(lb)'
+							qui matrix `covariates'[`t',6]=`r(ub)'
+							local ++t
+							local ++first
+						}
+					}
+				}
+			}
+			else{
+				qui lincom [T`k']`cont1'-[T`j']`cont1'
+				qui matrix `covariates'[`t',1]=`r(estimate)'
+				qui matrix `covariates'[`t',2]=`r(se)'
+				qui matrix `covariates'[`t',3]=`r(z)'
+				qui matrix `covariates'[`t',4]=`r(p)'
+				qui matrix `covariates'[`t',5]=`r(lb)'
+				qui matrix `covariates'[`t',6]=`r(ub)'
+				local ++t
+			}		
+		}
+	}
+}	
+		
+forvalues j=1/`timemax'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		qui lincom _b[/var(e.T`j')]
+	}
+	else {
+		qui lincom _b[/var(T`j')]
+	}
+	qui matrix `covariates'[`t',1]=`r(estimate)'
+	qui matrix `covariates'[`t',2]=`r(se)'
+	qui matrix `covariates'[`t',3]=`r(z)'
+	qui matrix `covariates'[`t',4]=`r(p)'
+	qui matrix `covariates'[`t',5]=`r(lb)'
+	qui matrix `covariates'[`t',6]=`r(ub)'
+	local ++t
+}
+forvalues j=1/`=`timemax'-1'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(e.T`j',e.T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+	else{
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(T`j',T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+}
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+*matrix list `covariates'
+
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 83}"
+	di  as text _col(70) "<--95% IC -->"
+	di   _col(70) "Lower" _col(78) "Upper"
+	di "Items" _col(22) "Threshold" _col(35) "Estimate" _col(47) "s.e." _col(59) "z" _col(66) "p" _col(69) " Bound" _col(78) "Bound"
+	di "{hline 83}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax`i'' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("`name``i'''",20) _c
+			  }
+			  di as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %6.2f `diff'[`t',3] _col(62) %5.3f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %6.2f `diff'[`t',3] _col(62) %5.3f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 83}"
+	local t=1
+	local listmoy
+	local listvar
+	local listcov
+	forvalues j=1/`timemax'{
+		local listvar `listvar' Variance_T`j'
+		forvalues k=`=`j'+1'/`timemax'{
+			local listcov `listcov' Cov_T`j'_T`k'
+		}
+		forvalues k=`=`j'+1'/`timemax'{
+			local listmoy `listmoy' Mean_diff_T`j'_T`k'
+		}
+	}
+	local n: word count `listmoy' `listvar' `listcov' 
+	forvalues i=1/`n' {
+		local v: word `i' of `listmoy' `listvar' `listcov' 
+		di as text _col(1) %5.2f "`v'"  as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %6.2f `covariates'[`t',3] _col(62) %5.3f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+	local n: word count `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of  `continuous' 
+		local v2 :  variable label `v'
+		if "`v2'"=="" {
+		   local v2 `v'
+		}
+		di as text _col(1) %5.2f  abbrev("`v2'",20)  as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %6.2f `covariates'[`t',3] _col(62) %5.3f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count  `categorical' 
+	*di "local n: word count of  `categorical' "
+	*di "n=`n'"
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local v2 : variable label `v'
+		if "`v2'"=="" {
+		   local v2 `v'
+		}
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v2'",20) _c
+				}
+				di  as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %6.2f `covariates'[`t',3] _col(62) %5.3f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		*local ++t
+	}
+	di as text "{hline 83}"
+	if "`visit'"==""{
+		di
+		qui su `latent'1 if `touse'
+		*qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])+(`r(sd)')^2)
+		*di as text "Variance of the estimated latent variable: " as result %4.2f `=(`r(sd)')^2'
+        tempvar se2latent
+		qui gen `se2latent'=(`selatent'1)^2 if `touse'
+		qui su `se2latent' if `touse'
+		local resvar=r(mean)
+		di as text "Mean squared std error of the latent variable: " as result %4.2f `resvar'
+		di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`resvar'))'
+		local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`resvar'))
+		di as text "PSI: " as result %4.2f `PSI' _c
+		if "`continuous'"!=""|"`categorical'"!="" {
+		    di as text " (without adjustment on covariates)"
+	    }
+		else {
+		    di
+		}
+		di
+		return scalar PSI=`PSI'
+
+	}
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+
+/*************************************************************************************************************
+ESTIMATION OF THE CORRECTED VALUES OF THE LT ESTIMATORS (values of lt that explained the best the score)
+**************************************************************************************************************/
+*set trace on
+tempfile savefile
+qui save `savefile'
+
+qui drop _all
+		
+qui set obs 2000
+qui gen u=(_n-1000)/200*`=2*sqrt(`covariates'[1,1])'
+qui gen Tcum=0
+qui gen TInf=0
+forvalues i=1/`nbitems' {
+		local d=1
+		qui gen cum``i''=0
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+		}
+		qui gen c0_``i''=1/(`d')
+		forvalues k=1/`mm' {
+			qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+			qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+		}
+		qui gen Inf``i''=0
+		forvalues k=1/`mm' {
+			qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+		}
+		*set trace on
+		qui replace Tcum=Tcum+cum``i''
+		qui replace TInf=TInf+Inf``i''	
+	    local scoremax=0
+		forvalues l=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`l''
+	    }
+		qui gen ecart=.
+		local listlt
+		forvalues l=0/`scoremax' {
+		    if `l'==0 {  
+			   local j=0.25
+			}
+			else if `l'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`l'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`l'=`r(mean)'
+			local listlt `listlt' `estlt`l''
+			*qui su TInf if round(ecart, 0.01)==round(`tmp',0.01)
+			*local setlt`l'=sqrt(1/`r(mean)')
+		}
+		qui drop ecart
+}
+qui use `savefile', clear
+
+
+*set trace on
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+
+/*Quelques explications
+latent : estimation EAP du trait latent
+latent2 : estimation Plausible Value Ă  partir de l'estimation EAP
+corrlatent : estimation corrigée cherchant la meilleur valeur du trait latent qui explique le score, interpolation à partir de l'EAP pour les individus avec des données manquantes
+*/
+
+
+if "`visit'"==""{
+	tempvar corrlatent corrlatenttmp 
+	qui gen `corrlatenttmp'=.
+	forvalues s=0/`scoremax' {
+	    qui replace `corrlatenttmp'=`estlt`s'' if `score'==`s'
+	}
+	qui ipolate `corrlatenttmp' `latent'1 , generate(`corrlatent') epolate
+	*list `corrlatenttmp' `latent2' `corrlatent' 
+	qui replace `corrlatent'=`corrlatenttmp' if `corrlatenttmp'!=.
+	qui replace `corrlatent'=`latent' if `corrlatenttmp'==.
+	*su  `corrlatenttmp' `latent2' `corrlatent' 
+    *twoway (scatter `corrlatent' `score') (scatter `latent2' `score') 
+	forvalues g=1/`nbgroups' {
+			*di "group=`g'" 
+			qui su `corrlatent' if `group'==`g'&`touse'
+			*di "qui matrix `groups'[`g',`=`nbitems'+9']=`r(min)'"
+			*di "qui matrix `groups'[`g',`=`nbitems'+10']=`r(max)'"
+			if r(N)!=0 {
+				qui matrix `groups'[`g',`=`nbitems'+9']=`r(min)'
+				qui matrix `groups'[`g',`=`nbitems'+10']=`r(max)'
+			}
+	}
+	tempname fit
+	qui matrix `fit'=J(`nbitems',6,.)
+	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT" "corrOUTFIT" "corrINFIT"
+	matrix rownames `fit'=`varlist'
+	*matrix list `fit'
+
+	tempvar Tcum TInf cum
+	qui gen `Tcum'=0 if `touse'
+	qui gen `TInf'=0 if `touse'
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text _col(60) "<---  Standardized   --->"
+		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+		di as text "{hline 90}"
+		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "{hline 90}"
+	}
+	*set trace on
+	local chi2=0
+	local chi2_old=0
+	forvalues g=1/`nbgroups' {
+	   local chi2_g`g'=0
+	   local chi2_old_g`g'=0
+	}
+	forvalues i=1/`nbitems' {
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+		tempvar corrcum``i'' corrc0_``i'' corrInf``i'' corry``i'' corrz``i'' corrz2``i'' corri``i'' 
+
+		local d=1
+		local corrd=1
+		local d_old=1
+		qui gen `corrcum``i'''=0 if `touse'
+		qui gen `cum``i'''=0 if `touse'
+		qui gen `cum_old``i'''=0 if `touse'
+		forvalues k=1/`mm' {
+			local corrd `corrd'+exp(`k'*`corrlatent'-`diffmat2'[`i',`k'])
+			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+			local d_old `d_old'+exp(`k'*`latent'1-`diffmat2'[`i',`k'])
+		}
+		qui gen `corrc0_``i'''=1/(`corrd') if `touse' 
+		qui gen `c0_``i'''=1/(`d') if `touse' 
+		qui gen `c_old0_``i'''=1/(`d_old') if `touse'
+		forvalues k=1/`mm' {
+			tempvar corrc`k'_``i'' c`k'_``i'' c_old`k'_``i''
+			qui gen `corrc`k'_``i'''=exp(`k'*`corrlatent'-`diffmat2'[`i',`k'])/(`corrd') if `touse'
+			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d') if `touse'
+			qui gen `c_old`k'_``i'''=exp(`k'*`latent'1-`diffmat2'[`i',`k'])/(`d') if `touse'
+			qui replace `corrcum``i'''=`corrcum``i'''+`corrc`k'_``i'''*`k' if `touse'
+			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k' if `touse'
+			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k' if `touse'
+		}
+		qui gen `corrInf``i'''=0 if `touse'
+		qui gen `Inf``i'''=0 if `touse'
+		qui gen `Inf_old``i'''=0 if `touse'
+		qui gen `C``i'''=0 if `touse'
+		forvalues k=0/`mm' {
+			qui replace `corrInf``i'''=`corrInf``i'''+(`k'-`corrcum``i''')^2*`corrc`k'_``i''' if `touse'
+			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i''' if `touse'
+			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i''' if `touse'
+			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i''' if `touse'
+		}
+		qui count if ``i''!=.&`touse'
+		local n``i''=r(N)
+		
+		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2) if `touse'
+		qui su `C2``i''' if `touse'
+		local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2 if `touse'
+		qui su `C3``i'''
+		local n=r(sum)
+		qui su `Inf``i''' if `touse'
+		local d=r(sum)
+		local q2i``i''=`n'/((`d')^2)
+		
+		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+		
+		qui replace `Tcum'=`Tcum'+`cum``i''' if `touse'
+		qui replace `TInf'=`TInf'+`Inf``i''' if `touse'
+		qui gen `corry``i'''=``i''-`corrcum``i''' if `touse'
+		qui gen `y``i'''=``i''-`cum``i''' if `touse'
+		qui gen `y_old``i'''=``i''-`cum_old``i''' if `touse'
+		qui gen `y2``i'''=(`y``i''')^2 if `touse'
+		qui gen `y2_old``i'''=(`y_old``i''')^2 if `touse'
+		qui gen `corrz``i'''=(`corry``i'''/sqrt(`corrInf``i''')) if `touse'
+		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i''')) if `touse'
+		local chi2_``i''=0
+		local chi2_old_``i''=0
+		forvalues g=1/`nbgroups' {
+			
+			qui su `y2``i''' if `group'==`g'&`touse'
+			local n=r(sum)
+			qui su ``i'' if `group'==`g'&`touse'
+			local n1=r(sum)
+			qui su `cum``i''' if `group'==`g'&`touse'
+			local n2=r(sum)
+			qui su `Inf``i''' if `group'==`g'&`touse'
+			local d=r(sum)
+			*qui count if `group'==`g'
+			*local eff=r(N)
+			*di "chi2_`g'_``i''=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')"
+			local chi2=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_``i''=`chi2_``i'''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_g`g'=`chi2_g`g''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			qui su `y2_old``i''' if `group'==`g'&`touse'
+			local n_old=r(sum)
+			qui su ``i'' if `group'==`g'&`touse'
+			local n1_old=r(sum)
+			qui su `cum_old``i''' if `group'==`g'&`touse'
+			local n2_old=r(sum)
+			qui su `Inf_old``i''' if `group'==`g'&`touse'
+			local d_old=r(sum)
+			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+		}
+		*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+		*su `z``i'''
+		label variable `corrz``i''' "Corrected standardized residuals associated to ``i''"
+		label variable `z``i''' "Standardized residuals associated to ``i''"
+		label variable `latent'1 "Latent trait"
+		label variable `corrlatent' "Corrected latent trait"
+		*set trace on
+		if  "`graphs'"!=""&"`graphitems'"=="" {
+			*set trace on
+			*set tracedepth 1
+			if "`filesave'"!="" {
+				local fs saving("`dirsave'//residuals_``i''",replace)
+			}
+			local thr=abs(invnorm(`alpha'/2))
+			tempvar id``i''
+			local hline
+			forvalues l=1/`modamax`i'' {
+				local hline `hline' `=`diffmat'[`i',`l']'
+			}
+			if "`residuals'"=="" {
+				if "`corrected'"!="" {
+					qui gen `id``i'''=_n if abs(`z``i''')>`thr'*sqrt(`covariates'[1,1])&`touse'
+					qui tostring `id``i''',replace
+					qui replace `id``i'''="" if `id``i'''=="."&`touse'
+					qui su `z``i''' if `touse'
+					local min=r(min)
+					local max=r(max)
+					local min=floor(min(`min',`=-`thr'*sqrt(`covariates'[1,1])'))
+					local max=ceil(max(`max',`=`thr'*sqrt(`covariates'[1,1])'))
+				
+					qui graph twoway scatter `z``i''' `latent' if `touse', xline(`hline',lwidth(vthin) lcolor(gray)) colordiscrete colorvar(``i'') colorlist(blue green orange purple gray red cyan ) ylabel(`min'(1)`max') yline(`=-`thr'*sqrt(`covariates'[1,1])' `=`thr'*sqrt(`covariates'[1,1])',  lcolor(black)) mlabel(`id``i''') name(residuals``i'',replace) title("Standardized residuals") subtitle(`name``i''') `fs'
+				}
+				else {
+				*set trace on
+					qui gen `id``i'''=_n if abs(`corrz``i''')>`thr'*sqrt(`covariates'[1,1])&`touse'
+					qui tostring `id``i''',replace
+					qui replace `id``i'''="" if `id``i'''=="."&`touse'
+					qui su `corrz``i''' if `touse'
+					local min=r(min)
+					local max=r(max)
+					local min=floor(min(`min',`=-`thr'*sqrt(`covariates'[1,1])'))
+					local max=ceil(max(`max',`=`thr'*sqrt(`covariates'[1,1])'))
+					qui graph twoway scatter `corrz``i''' `corrlatent' if `touse',xline(`hline',lwidth(vthin)  lcolor(gray))  colordiscrete colorvar(``i'') colorlist(blue green orange purple gray red cyan ) ylabel(`min'(1)`max') yline(`=-`thr'*sqrt(`covariates'[1,1])' `=`thr'*sqrt(`covariates'[1,1])', lcolor(black)) mlabel(`id``i''') name(residuals``i'',replace) title("Standardized residuals") subtitle(`name``i''') `fs' 
+				}
+			}
+			*set trace off
+		}
+		*set trace off 
+		qui gen `z2``i'''=(`z``i''')^2 if `touse'
+		qui su `z2``i''' if `touse'
+		local OUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',1]=`OUTFIT``i'''
+		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `Inf``i''' if ``i''!=.&`touse'
+		local sumw``i''=r(sum)
+		qui gen `i``i'''=`Inf``i'''*`z2``i''' if `touse' 
+		qui su `i``i''' if ``i''!=.&`touse'
+		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+		qui matrix `fit'[`i',2]=`INFIT``i'''
+		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		qui matrix `fit'[`i',4]=`INFITs``i'''
+		
+		/*corrected*/
+		qui gen `corrz2``i'''=(`corrz``i''')^2 if `touse'
+		qui su `corrz2``i''' if `touse'
+		local corrOUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',5]=`corrOUTFIT``i'''
+		*local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		*qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `corrInf``i''' if ``i''!=.&`touse'
+		local corrsumw``i''=r(sum)
+		qui gen `corri``i'''=`corrInf``i'''*`corrz2``i''' if `touse' 
+		qui su `corri``i''' if ``i''!=.&`touse'
+		local corrINFIT``i'' = `=`r(sum)'/`corrsumw``i''''
+		qui matrix `fit'[`i',6]=`corrINFIT``i'''
+		*local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		*qui matrix `fit'[`i',4]=`INFITs``i'''
+
+
+		if "`postpce'"=="" {
+			di abbrev("`name``i'''",20) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' /*_col(94) %5.3f `corrOUTFIT``i''' _col(109) %5.3f `corrINFIT``i'''*/
+		}
+	}
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text "*: As suggested by Bond and Fox (2007)"
+		di as text "**: As suggested by Wright (Smith, 1998)"
+	}
+	if "`geninf'"!="" {
+	    gen `geninf'=`TInf' if `touse'
+	}
+}
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Iteration `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1') if `touse'
+		`qui' pcm `varlist' [iweight=`sinf'] if `touse',diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1') if `touse'
+		qui su `ecart_`it'' if `touse'
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+/*ANCIENNE PLACE DES CORRECTED VALUES*/
+
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+if "`visit'"==""{
+*set trace on
+    tempname matscorelt matgroupscorelt
+	*di "qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)"
+	qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)
+	qui matrix `matgroupscorelt'=J(`=(`nbitems'*`modamax'+1+2*`nbgroups')*4',7,.)
+	qui matrix colnames `matgroupscorelt'="Group" "Score" "Frequency" "Estimation of latent trait" "s.e. of latent trait" "Expected score" "Corrected latent trait"
+	
+	local row=1
+	di
+	di as text "{hline 71}"
+	di _col(32) "Latent Trait" _col(50) "Expected" _col(63) "Corrected"
+	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score" _col(60) "latent trait"
+	di as text "{hline 71}"
+	forvalues g=1/`nbgroups' {
+		local sumuc=0
+		local sumc=0
+		qui count if `group'`multivisit'==`g'&`touse'
+		local eff`g'=r(N)
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'!=.&`touse'
+		local effcompleted`g'=r(N)
+		qui count if `score'`multivisit'!=.&`group'`multivisit'==`g'&`touse'
+		local n=r(N)
+		di as text "`g' (n=" as result `eff`g'' as text ")" _c
+		if `n'>0 {
+			qui su `score'`multivisit' if `group'`multivisit'==`g'&`touse'
+			local scoremin`g'=`r(min)'
+			local scoremax`g'=`r(max)'
+			forvalues s=`scoremin`g''/`scoremax`g'' {
+				qui count if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local eff=r(N)
+				local effscore`s'=r(N)
+				if `eff'!=0 {
+					qui su `latent'1 if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+					local mean=r(mean)
+					*di "local ltscore`s'=`=ceil(`r(mean)'*100)/100'"
+					local ltscore`s'=`=ceil(`r(mean)'*100)/100'
+					*di "local sumc=`sumc'+(`eff')*(`estlt`s'')"
+					*di "local sumuc=`sumuc'+(`eff')*(`mean')"
+				    local sumuc=(`sumuc'+((`eff')*(`mean')))
+				    local sumc=(`sumc'+((`eff')*(`estlt`s'')))
+				}
+				qui su `selatent'1 if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local se=r(mean)
+				qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local exp=r(mean)
+				if `eff'>0 {
+				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp' _col(66) %6.3f `estlt`s''  `setlt`s''
+				}
+				*set trace on
+				*matrix list `matscorelt'
+				qui matrix `matscorelt'[`=`s'+1',1]=`eff'
+				qui matrix `matscorelt'[`=`s'+1',2]=`mean'
+				qui matrix `matscorelt'[`=`s'+1',3]=`se'
+				qui matrix `matgroupscorelt'[`row',1]=`g'
+				qui matrix `matgroupscorelt'[`row',2]=`s'
+				qui matrix `matgroupscorelt'[`row',3]=`eff'
+				qui matrix `matgroupscorelt'[`row',4]=`mean'
+				qui matrix `matgroupscorelt'[`row',5]=`se'
+				qui matrix `matgroupscorelt'[`row',6]=`exp'
+				qui matrix `matgroupscorelt'[`row',7]=`estlt`s''
+				local ++row
+				*set trace off
+			}
+			
+		}
+		*set trace on
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+		local eff=r(N)
+		local eff_md_`g'=r(N)
+		if `eff'!=0 {
+			qui su `latent'1 if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local mean=r(mean)
+			local lt_md_`g'=r(mean)
+			local sumuc=(`sumuc'+((`eff')*(`mean')))
+			qui su `selatent'1 if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local se=r(mean)
+			qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local exp=r(mean)
+			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) /*%5.2f `exp'*/
+			qui matrix `matgroupscorelt'[`row',1]=`g'
+			*qui matrix `matgroupscorelt'[`row',2]=`s'
+			qui matrix `matgroupscorelt'[`row',3]=`eff'
+			qui matrix `matgroupscorelt'[`row',4]=`mean'
+			qui matrix `matgroupscorelt'[`row',5]=`se'
+			qui matrix `matgroupscorelt'[`row',6]=`exp'
+			*qui matrix `matgroupscorelt'[`row',7]=`estlt`s''
+			local ++row
+		}
+		*set trace off
+		*di "local lt`g'=`sumuc'/`eff`g''"		
+		*di "local clt`g'=`sumc'/`effcompleted`g''"
+		local lt`g'=(`sumuc')/(`eff`g'')
+		local clt`g'=(`sumc')/(`effcompleted`g'')
+		matrix `groups'[`g',`=`nbitems'+6']=`clt`g''
+		*di "group `g' est=`lt`g'' corrected est=`clt`g''"
+		di as text "         " "{dup 62:-}"
+		if "`scoremin`g''"=="" {
+			local scoremin`g' "."
+		}
+		if "`scoremax`g''"=="" {
+			local scoremax`g' "."
+		}
+		di  as text _col(10) "`scoremin`g''/`scoremax`g''" as result _col(20) %4.0f `eff`g'' _col(30) %6.3f `lt`g''  _col(66) %6.3f `clt`g''
+		di as text "{hline 71}"
+		qui matrix `matgroupscorelt'[`row',1]=`g'
+		*qui matrix `matgroupscorelt'[`row',2]="`scoremin`g''/`scoremax`g''"
+		qui matrix `matgroupscorelt'[`row',3]=`eff`g''
+		qui matrix `matgroupscorelt'[`row',4]=`lt`g''
+		qui matrix `matgroupscorelt'[`row',5]=`se'
+		*qui matrix `matgroupscorelt'[`row',6]=`exp'
+		qui matrix `matgroupscorelt'[`row',7]=`clt`g''
+		local ++row
+	}
+	local nbrowmat=`row'-1
+	qui matrix `matgroupscorelt'=`matgroupscorelt'[1..`nbrowmat',1..7]
+	*matrix list `matscorelt'
+}	
+
+*set trace on
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+*set trace on
+if "`visit'"==""{
+	if "`graphs'"!=""|"`graphs'"=="" {
+
+		tempfile savefile
+		qui save `savefile'
+
+		*qui clear
+		qui drop _all
+		local pas=1000*round(`=sqrt(`covariates'[1,1])',0.001)
+		local pas=round(`pas')
+		qui set obs `pas'
+		qui gen u=round((_n-`pas'/2)/(`pas'/10)*`=sqrt(`covariates'[1,1])',0.01)
+		*list u
+		qui gen Tcum=0
+		qui gen TInf=0
+		qui gen ecartcum=.
+		forvalues i=1/`nbitems' {
+		   local scatteri`i' 
+		   local scatteric`i' 
+		   forvalues g=1/`nbgroups' {
+			  local x=`groups'[`g',`=`nbitems'+1']
+			  local xc=`groups'[`g',`=`nbitems'+6']
+			  local xmin=`groups'[`g',`=`nbitems'+7']
+			  local xmax=`groups'[`g',`=`nbitems'+8']
+			  local xcmin=`groups'[`g',`=`nbitems'+9']
+			  local xcmax=`groups'[`g',`=`nbitems'+10']
+			  local y=`groups'[`g',`i']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=20
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off) || pci `y' `xmin'  `y' `xmax' ,lcolor(black)
+			  local scatteric`i' `scatteric`i'' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off) || pci `y' `xcmin'  `y' `xcmax' ,lcolor(black)
+			*set trace off
+			}
+			local d=1
+			qui gen cum``i''=0
+			*set trace on
+			if "`rsm'"=="" {
+				local mm=`modamax`i''
+			}
+			else {
+				local mm `modamax'
+			}	
+			forvalues k=1/`mm' {
+				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+			}
+			qui gen c0_``i''=1/(`d')
+			label variable c0_``i'' "Pr(X=0)"
+			local xline 
+			local yline
+			forvalues k=1/`mm' {
+				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+				label variable c`k'_``i'' "Pr(X=`k')"
+				local xline `xline' `=`diffmat'[`i',`k']'
+				local yline `yline' `=`k'-0.5'
+
+			}
+			forvalues k=0/`mm' {
+			    if `k'==0 {
+				   local l=0.25
+				}
+				else if `k'==`mm' {
+				   local l=`k'-0.25
+				}
+				else {
+				   local l=`k'
+				}
+				qui replace ecartcum=abs(cum``i''-`l')
+				qui su ecartcum
+				qui su u if round(ecartcum,0.01)==round(`r(min)',0.01)
+				local bestest``i''_`k'=r(mean)
+				*di "item ``i'' cat `k' : est=`bestest``i''_`k''"
+			}
+			qui gen Inf``i''=0
+			label variable Inf``i'' "`name``i'''"
+			forvalues k=0/`mm' {
+				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+			}
+			if "`graphitems'"=="" {
+				if "`filesave'"!="" {
+					local fsc saving("`dirsave'//CCC_``i''",replace)
+					local fsi saving("`dirsave'//ICC_``i''",replace)
+				}
+				if "`graphs'"!="" {
+					qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC)) subtitle(`name``i''') ytitle("Probability") xtitle("`xtitle'") `fsc' xline(`xline',lwidth(vthin) lcolor(gray))
+					if "`corrected'"!="" {
+						qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC)") subtitle(`name``i''') ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi' xline(`xline',lwidth(vthin) lcolor(gray)) ylabel(0(.5)`modamax`i'')
+					}
+					else {
+						qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC)") subtitle(`name``i''') ytitle("Score to the item") xtitle("Corrected latent trait") `scatteric`i'' `fsi' xline(`xline',lwidth(vthin) lcolor(gray)) ylabel(0(.5)`modamax`i'')
+					}
+				}
+			}
+			qui replace Tcum=Tcum+cum``i''
+			qui replace TInf=TInf+Inf``i''	
+		}
+	    local scoremax=0
+		forvalues i=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`i''
+	    }
+		qui gen ecart=.
+		forvalues i=0/`scoremax' {
+		    if `i'==0 {  
+			   local j=0.25
+			}
+			else if `i'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`i'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`i'=`r(mean)'
+			*di "score `i' : `r(mean)'"
+		}
+		if "`filesave'"!="" {
+			local fst saving("`dirsave'//TCC",replace)
+			local fsteo saving("`dirsave'//TCCeo",replace)
+			local fsi saving("`dirsave'//ICC",replace)
+			local fsti saving("`dirsave'//TIC",replace)
+			local fstii saving("`dirsave'//TICi",replace)
+			local fsm saving("`dirsave'//map",replace)
+		}
+		if "`graphs'"!="" {
+*qui save "C:\temp\info\info",replace
+			label variable TInf "Information curve"
+
+			qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("`xtitle'") `fst' subtitle(`dimname') ylabel(0(1)`scoremax') xline(`listlt',lwidth(vthin) lcolor(gray)) 
+			qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("`xtitle'")  `fsi' subtitle(`dimname')
+			qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("`xtitle'")  `fsti' subtitle(`dimname')
+			qui graph twoway (line Inf*  u, lwidth(thin)) (line TInf u, lwidth(thick)), name(TIC,replace) title("Test/Item Information Curve") ytitle("Information") xtitle("`xtitle'")  `fstii' subtitle(`dimname')
+		}
+		local scatteri
+		local scatteric
+		forvalues g=1/`nbgroups' {
+		*matrix list `groups'
+			local x=`groups'[`g',`=`nbitems'+1']
+			local xc=`groups'[`g',`=`nbitems'+6']
+			local xmin=`groups'[`g',`=`nbitems'+7']
+			local xmax=`groups'[`g',`=`nbitems'+8']
+			local xcmin=`groups'[`g',`=`nbitems'+9']
+			local xcmax=`groups'[`g',`=`nbitems'+10']
+			local y=`groups'[`g',`=`nbitems'+3']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=20
+			  local s tiny
+			  *set trace on
+			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)|| pci `y' `xmin'  `y' `xmax' ,lcolor(black)
+			local scatteric `scatteric' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off) || pci `y' `xcmin'  `y' `xcmax' ,lcolor(black) 
+		}
+		*set trace on
+		if "`graphs'"!="" {
+			if "`corrected'"!="" {
+				qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo' subtitle(`dimname') xline(`listlt',lwidth(vthin) lcolor(gray))
+			}
+			else {
+				qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Corrrected latent trait") `scatteric' `fsteo' subtitle(`dimname') xline(`listlt',lwidth(vthin) lcolor(gray))
+			}
+		}
+		*set trace off
+	}
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+	*set trace on
+	if "`graphs'"!=""|"eqset1"!="" {
+		gen eff=0
+		gen eff_md=0
+		local effmax=0
+			*gen uround=round(u,0.01)
+			*list uround
+		/*le bloc suivant Ă©tait pour avoir des batons par groupe*/
+		/*forvalues g=1/`nbgroups' {
+			local eff=`groups'[`g',`=`nbitems'+2']
+			if `groups'[`g',`=`nbitems'+2']>`effmax' {
+			   local effmax=`groups'[`g',`=`nbitems'+2']
+			}
+			local lat=round(`groups'[`g',`=`nbitems'+1'],0.01)
+			*di "replace eff=`eff' if round(u,0.01)==`lat'"
+			qui replace eff=`eff' if round(u,0.01)==`lat'
+		}*/
+		/*le bloc suivant est pour avoir des batons par score*/
+		qui gen uceil=ceil(u*100)/100
+		forvalues s=0/`scoremax' {
+			if `effscore`s''>`effmax' {
+			   local effmax=`effscore`s''
+			}
+			*di "`s' qui replace eff=`effscore`s'' if ceil(u*100)/100==`=round(`ltscore`s'',0.01)'"
+			qui replace eff=`effscore`s'' if round(u,0.01)==round(`ltscore`s'',0.01)
+		}
+		forvalues g=1/`nbgroups' {
+			*di "if `eff_md_`g''>`effmax' { (`lt_md_`g'')"
+			if `eff_md_`g''>`effmax' {
+			   local effmax=`eff_md_`g''
+			}
+			qui replace eff_md=`eff_md_`g'' if round(u,0.01)==round(`lt_md_`g'',0.01)
+		}
+
+		gen density=normalden(u)*sqrt(`covariates'[1,1])
+		label variable eff "Complete"
+		label variable eff_md "Incomplete"
+		label variable u "Latent trait"
+		label variable TInf "Information curve"
+		label variable density "Density function of the latent trait"
+		local scatteri
+		local scatterj
+		local color 
+		qui su u if eff!=0|eff_md!=0
+		*set trace on
+		*set tracedepth 1
+		*if eff!=0|eff_md!=0 {
+			local floor=floor(`r(min)')
+			local ceil=ceil(`r(max)')
+		*}
+		*else  {
+		*	local floor=-10
+		*	local ceil=10
+		*}
+		local sep
+		local ylbl
+		forvalues i=1/`nbitems' {
+		   local color`i':word `i' of `color'
+		   local unit=round(`effmax'/`nbitems',1)
+		   local y=-`i'*`unit'             
+		   loca staritem
+		   *local legend `"1 2 `=(`modamax'+1)*`nbitems'+1' `=(`modamax'+1)*`nbitems'+2' 3 "1" "'
+		   local legend `"5 "1" "'
+		   forvalues l=1/`modamax' {
+			   if `l'>=2 {
+			      local legend `" `legend' `=2*`l'+3' "`l'" "'
+			   }			   
+			   local x=`diffmat'[`i',`l']
+			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+			   if `l'==1 {
+			      local xant=`x'
+			   }
+			   else {
+			      local xant=`diffmat'[`i',`=`l'-1']
+			   }
+			   if `xant'>`x' {
+				  local star *
+				  local staritem *
+			   }
+			   else {
+			      local star
+			   }
+			   local scatterj `" `scatterj' `sep' scatteri `y' `x'   , pstyle(p`l') || pci `y' `xant' `y' `x', pstyle(p1) color(black)"'
+			   local sep ||
+			   if `x'<`floor' {
+				  local floor=floor(`x')
+			   }
+			   if `x'>`ceil'&`x'!=. {
+				  local ceil=ceil(`x')
+			   }
+		   }
+		   local nomcourt``i''=abbrev("`name``i'''",20)
+   		   local ylbl `ylbl' `=-`i'*`unit'' "`nomcourt``i'''`staritem'"
+		   local scatteri `scatteri' || scatteri `y' `=`floor'-2' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+		}
+		qui su eff
+		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+		qui su eff_md
+		local maxe_md=ceil(`=(floor(`r(max)'/10)+1)*10')
+		local maxe=max(`maxe',`maxe_md')
+		qui su TInf
+		local maxi=1.2*ceil(`r(max)')
+		qui su density
+		local maxd=round(`r(max)', 0.01)+0.01
+		qui drop if u<`floor'|u>`ceil'
+		*di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(0(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3)) `scatterj'   , name(map,replace) ytitle(Frequencies)  ylabel(0(`=`maxi'/5')`maxi' ,axis(2)) ylabel(0(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title(Individuals/items representations (Map)) xsize(12) ysize(9) note(Red line: Information curve - Green line : Density of the latent trait) xtitle(Latent trait) `fsm'"
+		*graph combine TIC IIC,  col(1)
+		*graph save "map" "map.gph", replace
+		*discard
+		*qui graph twoway line TInf u , name(map,replace)
+		*qui graph twoway `scatterj'  , name(map2,replace) ytitle("")   ylabel(`ylbl', grid angle(0))  legend(off) xsize(12) ysize(9) 
+		*su
+*list eff u if eff!=0
+*browse
+		if "`eqset1'"==""&"`graphs'"!="" {
+		    *list eff u uceil if eff!=0&eff!=.
+			*save tmp, replace
+			*di "`legend'"
+			*di "holes(3/`nbcolslegende' `=`nbcolslegende'+3'/`=`nbcolslegende'*2')"
+			local nbcolslegende=max(2,`modamax')
+			if `modamax'==1 {
+			   local holes "holes(2)"
+			}
+			tempvar line1 line2 
+			qui gen `line1'=.
+			qui gen `line2'=.
+			label variable `line2' "Density"
+			label variable `line1' "Information"
+			qui graph twoway (line `line1' u ,lwidth(medthick) lcolo(red)) (line `line2' u ,lwidth(medthick) lcolo(green)) (line density u,yaxis(3) lwidth(medthick) lcolo(green) ) (bar eff u,  barwidth(.1) yaxis(1) xlabel(`floor'(1)`ceil') color(erose) )  (bar eff_md u,  barwidth(.05) yaxis(1) xlabel(`floor'(1)`ceil') color(stred) )  (line TInf u,yaxis(2) lwidth(medthick) lcolo(red) ) `scatterj'   , xline(0, lcolor(black)) legend(on position(3)     /*symysize(*.6) symxsize(*.6) textwidth(*.6)*/ /*cols(`nbcolslegende')*/ cols(1)  `holes' order(`"- "Functions" 2 1 - "" - "Patterns" 3 4 - "" - "Thresholds" `legend'  "') /*subtitle(Threshold parameters,size(*.7)) */size(small)) name(map,replace) ytitle("                           Frequencies")  ylabel(0(`=`maxi'/5')`maxi' `maxi'(`maxi')`=`maxi'*2' ,axis(2)) yscale(axis(2) off) yscale(axis(3) off)  ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) yline(0,lwidth(medium) lpattern(solid) lcolor(black))  ylabel(`ylbl',/*noticks*/ grid angle(0) axis(1)) ylabel(`ylbl' 0(`=`maxe'/5')`maxe', grid angle(0) axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("* : dysfunctioning items") xtitle("`xtitle'") `fsm' subtitle(`dimname')
+		}
+		else if "`eqset1'"!="" {
+			qui su eff
+	        local ceil=ceil(ceil(`r(max)'/10)*10)
+
+            qui tempfile equating
+			qui save `equating', replace
+		}
+	}
+	qui use `savefile', clear
+}
+		 
+
+
+/*************************************************************************************************************
+Best estimates by category 
+*************************************************************************************************************/
+
+tempname bestest
+matrix `bestest'=J(`nbitems',`=`modamax'+1',.)
+di
+local long=`modamax'*8+33
+di
+di "Best estimates by answer category" 
+di "{hline `long'}"
+di "Item" _col(29) "Cat 0"  _c
+forvalues j=1/`modamax' {
+     local col=29+`j'*8 
+	 di _col(`col') "Cat `j'"     _c
+}
+di
+di "{hline `long'}"
+forvalues i=1/`nbitems' {
+    di abbrev("`name``i'''",20) _c
+	forvalues j=0/`modamax`i'' {
+	    di _col(`=28+`j'*8') %6.3f round(`bestest``i''_`j'', 0.001) _c
+		matrix `bestest'[`i',`=`j'+1']=`bestest``i''_`j''
+	}
+	di
+}
+di "{hline `long'}"
+		
+
+
+/*************************************************************************************************************
+EQUATING
+*************************************************************************************************************/
+if "`eqset1'"!="" {
+    if "`eqgenscore'"!="" {
+	   local tmp1 `=ustrlen("`eqgenscore'`eqset1name'")'
+	   local tmp2 `=ustrlen("`eqgenscore'`eqset2name'")'
+	   local mlength=max(`tmp1',`tmp2')
+	   if `mlength'>27 {
+			di as error "The number of characters containing in the strings eqgenscore+eqset1name or eqgenscore+eqset2name must be lesser than 27"
+			di as error "eqgenscore+eqset1name : `tmp1' characters"
+			di as error "eqgenscore+eqset2name : `tmp2' characters"
+			error 130
+			*exit
+		}
+	}
+	if "`eqset1name'"=="" {
+	   local eqset1name="Set_1"
+	}
+	else if `c(version)'>17 {
+		local eqset1name `=regexreplaceall("`eqset1name'"," ","_",.)'
+	}
+	if "`eqset2name'"=="" {
+	   local eqset2name="Set_2"
+	}
+	else if `c(version)'>17 {
+		local eqset2name `=regexreplaceall("`eqset2name'"," ","_",.)'
+	}
+	*di "set1:`eqset1name' set2:`eqset2name'"  
+
+    tokenize `eqset1'
+	local nbset1: word count `eqset1'
+	forvalues i=1/`nbset1' {
+	   local eq1_`i':word `i' of `eqset1'
+	}
+    tokenize `eqset2'
+	local nbset2: word count  `eqset2'
+	forvalues i=1/`nbset2' {
+	   local eq2_`i':word `i' of `eqset2'
+	}	
+
+
+
+	tempfile fileeq
+	qui save `fileeq',replace
+	forvalues t=1/2{
+		local scoremaxset`t'=0
+		forvalues i=1/`nbset`t'' {
+			local scoremaxset`t'=`scoremaxset`t''+`modamax`eq`t'_`i'''
+		}
+	}
+	drop _all
+	qui set obs `=(`scoremaxset1'+`scoremaxset2'+2)*3'
+	forvalues t=1/2 {
+		qui gen scoreset`t'=.
+		qui gen scoreset`t'm=.
+		qui gen scoreset`t'p=.	
+	}
+	forvalues i=0/`scoremaxset1' {
+	    qui replace scoreset1=`i' in `=`i'+1'
+	    qui replace scoreset1m=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset1p=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	forvalues i=`=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2' {
+	    qui replace scoreset2=`i'-`scoremaxset1'-2 in `i'
+	    qui replace scoreset2m=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset2p=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	local s=0
+	local eqset1b
+	foreach i in `eqset1' {
+		qui gen s1_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s1_`i'_`m'=0 in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'_`m'=1 if scoreset1>`s' in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'=s1_`i'+s1_`i'_`m'
+		   local ++s
+		}
+	    local eqset1b `eqset1b' s1_`i'
+	}
+	local s=0
+	local eqset2b
+	foreach i in `eqset2' {
+		qui gen s2_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s2_`i'_`m'=0 in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'_`m'=1 if scoreset2>`s' in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'=s2_`i'+s2_`i'_`m'
+		   local ++s
+		}
+		local eqset2b `eqset2b' s2_`i'
+	}
+	tokenize `varlist'
+	tempname diffset1 diffset2
+	forvalues t=1/2 {
+		qui matrix `diffset`t''=J(`nbset`t'',`modamax',.)
+		local n=1
+		local listset`t'
+		foreach j in `eqset`t'' {
+			forvalues i=1/`nbitems' {
+				if "`j'"=="``i''" {
+					local listset`t' `listset`t'' `i'
+					forvalues m=1/`modamax' {
+						qui matrix `diffset`t''[`n',`m']=`diffmat'[`i',`m']
+					}
+					local ++n						
+				}
+			}
+		}
+	}
+	local var=`covariates'[1,1]
+	qui gen lt=.
+	forvalues t=1/2 {
+		tempname matscorelt`t'
+		qui pcm `eqset`t'b', diff(`diffset`t'') var(`var') minsize(1)
+		qui matrix `matscorelt`t''=r(matscorelt)
+		forvalues i=0/`scoremaxset`t'' {
+			qui replace lt=`matscorelt`t''[`=`i'+1',2] if scoreset`t'==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]+1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'p==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]-1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'm==`i'
+		}
+		qui ipolate scoreset`t' lt, gen(score`t') epolate
+	}
+	qui ipolate scoreset1 lt, gen(score1bis) epolate
+
+
+	forvalues t=1/2 {
+		qui replace score`t'=scoreset`t'm if scoreset`t'm!=.
+		qui replace score`t'=scoreset`t'p if scoreset`t'p!=.
+		qui replace score1=score1bis if score1==.
+		qui replace score`t'=0 if score`t'<0
+		qui replace score`t'=`scoremaxset`t'' if score`t'>`scoremaxset`t''
+	}
+	local pciset1
+	local pciset2
+	*set trace on
+	local minimini=0
+	local maximaxi=0
+	forvalues t=1/2 {
+        qui gen adjscore`t'=(score`t'+`eqaddset`t'')*`eqmultset`t''
+	    qui gen adjscore`=3-`t''=(score`=3-`t''+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''
+		tempname matscore`t'
+		qui matrix `matscore`t''=J(`=`scoremaxset`t''+1',7,.)
+		*set trace on
+		forvalues s=0/`scoremaxset`t'' {
+		    qui matrix `matscore`t''[`=`s'+1',1]=`s'
+			qui su lt if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',2]=r(mean)
+			if `ceil'==0 {
+				local ceil=1
+			}
+			if "`eqwithci'"=="" {
+				local pciset`t'  `pciset`t'' scatteri `=-`ceil'/5*`t'' `r(mean)' (12) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , mlabsize(tiny) mcolor(black) mlabcolor(black)||
+			}
+			local mean=r(mean)
+			qui su lt if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',3]=r(mean)
+			local moins=r(mean)
+			if `moins'<`minimini' {
+				*di "local minimini=floor(`moins')"
+				local minimini=floor(`moins')
+			}
+			qui su lt if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',4]=r(mean)
+			local plus=r(mean)
+			if `plus'>`maximaxi' {
+				*di "local maximaxi=ceil(`plus')"
+				local maximaxi=ceil(`plus')
+			}
+
+			if "`eqwithci'"!="" {
+				local y=-`ceil'/5*((2.5*`t'-2)+2*(`s'/`scoremaxset`t''))
+				*local pciset`t'  `pciset`t'' scatteri `y' `mean' (12) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , mlabsize(tiny) mcolor(black) mlabcolor(black)|| pci `y' `moins' `y' `plus',pstyle(p1) color(black)||
+				local pciset`t'  `pciset`t'' scatteri `y' `mean'  , mlabsize(tiny) mcolor(black) mlabcolor(black)|| scatteri `y' `moins' (9) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , msize(0) mlabsize(tiny) mcolor(black) mlabcolor(black)|| pci `y' `moins' `y' `plus',pstyle(p1) color(black)||
+			}
+			qui su score`=3-`t'' if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',5]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',6]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',7]=r(mean)
+		}
+		matrix colnames `matscore`t'' =score`t' lt lt- lt+ score`=3-`t'' score`=3-`t''- score`=3-`t''+
+		di as text
+		di as text "{hline 78}"
+		di as text "EQUATING `eqset`t'name' TO `eqset`=3-`t''name'"
+		di as text "{hline 78}"
+		di "`eqset`t'name' : `eqset`t''"
+		di "`eqset`=3-`t''name' : `eqset`=3-`t'''"
+		local eqset`t'namea=abbrev("`eqset`t'name'",18)
+		local eqset`=3-`t''namea=abbrev("`eqset`=3-`t''name'",12)
+		di "{hline 78}"
+		di "Score"           _col(20) "<----- Latent trait ----->" _col(52) "<- Score `eqset`=3-`t''namea'" _col(77) "->"
+		di "`eqset`t'namea'" _col(20) "Estimated" _col(39) "[95%IC]" _col(52) "Estimated" _col(72) "[95%IC]"
+		di "{hline 78}"
+		forvalues s=0/`scoremaxset`t'' {
+		    local min=min(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+		    local max=max(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+			
+			di %4.0f `=(`matscore`t''[`=`s'+1',1]+`eqaddset`t'')*`eqmultset`t''' _col(24) %5.2f `matscore`t''[`=`s'+1',2] _col(33) "[" %5.2f `matscore`t''[`=`s'+1',3] ";" %5.2f `matscore`t''[`=`s'+1',4] "]" _col(56) %5.2f `=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''' _col(66) "[" %5.2f `min' ";" %5.2f `max' "]"			
+		}
+		di "{hline 78}"
+		if "`eqgraph'"!="" {
+		    *set trace on
+			if `eqmultset`=3-`t'''>0 {
+				local xlabel 	"`=`eqaddset`=3-`t'''*`eqmultset`=3-`t''''(`=ceil((`scoremaxset`=3-`t'''*`eqmultset`=3-`t''')/20)')`=(`scoremaxset`=3-`t'''+`eqaddset`=3-`t''')*`eqmultset`=3-`t''''"
+			}
+			else {
+				local xlabel 	"`=(`scoremaxset`=3-`t'''+`eqaddset`=3-`t''')*`eqmultset`=3-`t''''(`=ceil((-`scoremaxset`=3-`t'''*`eqmultset`=3-`t''')/20)')`=`eqaddset`=3-`t'''*`eqmultset`=3-`t''''"
+			}
+			if `eqmultset`t''>0 {
+				local ylabel 	"`=`eqaddset`t''*`eqmultset`t'''(`=ceil((`scoremaxset`t''*`eqmultset`t'')/20)')`=(`scoremaxset`t''+`eqaddset`t'')*`eqmultset`t'''"
+			}
+			else {
+				local ylabel 	"`=(`scoremaxset`t''+`eqaddset`t'')*`eqmultset`t'''(`=ceil((-`scoremaxset`t''*`eqmultset`t'')/20)')`=`eqaddset`t''*`eqmultset`t'''"
+			}
+			*set trace off
+			*di "xlabel : `xlabel'"
+			*di "subtitle=`subtitle'"
+			twoway (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''!=.,lcolor(black) lpattern(solid) lwidth(thick)) (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''m!=.,lcolor(black) lpattern(dash) lwidth(thin)) (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''p!=.,lcolor(black) lpattern(dash) lwidth(thin)), title("Equating score of `eqset`=3-`t''name' to `eqset`t'name' ") ytitle("Score `eqset`t'name'") xtitle("Score `eqset`=3-`t''name'") ylabel(`ylabel') xlabel(`xlabel') name(eq`t'to`=3-`t'') legend(order(1 2) label(1 "Estimated") label(2 "95%IC") position(6)) subtitle("`dimname'") 
+		}
+		qui drop adjscore`t' adjscore`=3-`t''
+	}
+	
+	if "`eqgraph'"!="" {
+		qui use "`equating'",clear
+	    qui su u
+	    local flooru=floor(`r(min)')
+	    local ceilu=ceil(`r(max)')
+		qui su eff
+	    local ceil=ceil(ceil(`r(max)'/10)*10)
+		if `ceil'==0 {
+		   local ceil=1
+		}
+
+		local title "Equating"
+		if "`eqset1name'"!=""&"`eqset2name'"!=""{
+		   local title "Equating between `eqset1name' and `eqset2name'"
+		}
+		if "`eqwithci'"=="" {
+		   local ylabel1=-`ceil'/5
+		   local ylabel2=-2*`ceil'/5
+		   local gapu=ceil((`ceilu'-`flooru')/15)
+		}
+		else {
+		    local ylabel1=-0.5*`ceil'/5
+		    local ylabel2=-3*`ceil'/5
+		   	local flooru=min(`flooru',`minimini')
+			local ceilu=max(`ceilu',`maximaxi')
+			local gapu=ceil((`ceilu'-`flooru')/15)
+		}
+	    *di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`flooru'(1)`ceilu') color(erose)) || `pciset1' `pciset2'  , yline(0, lcolor(black)) legend(off) name(equating,replace) ytitle(                           Frequencies)    ylabel(`=-`ceil'/5*2' `eqset1name' `=-`ceil'/5' `eqset2name' 0(`=`ceil'/5')`ceil', grid angle(0) axis(1)) title(Equating) xsize(12) ysize(9)  xtitle(Latent trait) "
+	    qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`flooru'(`gapu')`ceilu') color(erose)) || `pciset1' `pciset2'  , yline(0, lcolor(black)) legend(off) name(equating,replace) ytitle("                           Frequencies")    /*ylabel(`ylbl', grid angle(0) axis(1))*/ ylabel(`ylabel1' "`eqset1name'" `ylabel2' "`eqset2name'" 0(`=`ceil'/5')`ceil', grid angle(0) axis(1)) title("`title'") subtitle("`dimname'") xsize(12) ysize(9)  xtitle("Latent trait") 
+	}
+	qui use `fileeq',clear
+	*set trace on
+	tempname scoreset1 scoreset2
+	forvalues t=1/2 {
+		qui genscore `eqset`t'' if `touse',score(`scoreset`t'')
+	 	qui su `scoreset`t'' if `touse'
+		local maxscoreset=r(max)
+		*qui matrix list `matscore`t''
+		if "`eqgenscore'"!="" {
+			local eqgenscore `=regexreplaceall("`eqgenscore'"," ","_")'
+			*di "eqgenscore : `eqgenscore'"
+			foreach k in mean min max random {
+				capture confirm  variable `eqgenscore'_`k'_`eqset`=3-`t''name'
+				if _rc==0&"`replace'"!="" {
+					qui replace `eqgenscore'_`k'_`eqset`=3-`t''name'=. if `touse'
+				}
+				else if _rc==0&"`replace'"!="" {
+					di as error "The variable `eqgenscore'_`k'_`eqset`=3-`t''name' already exists"
+					error 198
+				}
+				else {
+					qui gen `eqgenscore'_`k'_`eqset`=3-`t''name'=. if `touse'
+				}
+			}
+			*tab `scoreset`t''
+			forvalues s=0/`maxscoreset' {
+				*di "qui replace `eqgenscore'_`eqset`=3-`t''name'=`=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''' if `scoreset`t''==`s'"
+				local min=min(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+				local max=max(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+				qui replace `eqgenscore'_mean_`eqset`=3-`t''name'=round(`=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_min_`eqset`=3-`t''name'=round(`min',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_max_`eqset`=3-`t''name'=round(`max',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_random_`eqset`=3-`t''name'=round(uniform()*(`max'-`min')+`min',1) if round(`scoreset`t'',1)==`s'&`touse'
+			}
+		}
+		return matrix score`t'_to_`=3-`t''=`matscore`t''
+	}
+	
+}
+
+
+/*************************************************************************************************************
+RETOUR AU FICHIER INITIAL ET SAUVEGARDE DES NOUVELLES VARIABLES
+*************************************************************************************************************/
+*set trace on
+if "`visit'"!="" {
+	tempfile sauv
+	*set trace on
+	*tempname corrlatent corrbilatent
+	qui keep `latent'* `selatent'* `id' `visit' 
+    qui reshape wide , i(`id') j(`visit')
+	qui sort `id'	
+	qui save `sauv', replace
+	restore,preserve
+	if "`replace'"!=""&("`genlt'"!=""|"`geninf'"!="") {
+    	capture drop `genlt' 
+    	capture drop `genlt'_se 
+    	capture drop `geninf' 
+    	capture drop `genlt'_corr
+    	capture drop `genlt'_best
+    	*capture drop `genlt'_opt_se
+    }
+	*su
+	tempname idorder
+	qui gen `idorder'=_n 
+	qui sort `id'
+	qui merge 1:1 `id' using `sauv'
+	
+	qui sort `idorder'
+    qui drop `idorder'	
+}
+else {
+*set trace on
+*set tracedepth 1
+    if "`genlt'"!="" {
+		qui gen `genlt'_corr=`corrlatent' if `touse'
+/*		qui gen `genlt'_corr2=. if `touse'
+		forvalues s=0/`scoremax' {
+			qui replace `genlt'_corr2=`estlt`s'' if `score'==`s'&`touse'
+		}
+		forvalues g=1/`nbgroups' {
+			qui replace `genlt'_corr2=`clt`g'' if `group'==`g'&`genlt'_corr==.&`touse'
+		}
+*/
+		tempvar tmpitem mean nbnonmiss
+		forvalues i=1/`nbitems' {
+			qui gen `tmpitem'_`i'=. if `touse'
+			forvalues k=0/`modamax' {
+				qui replace `tmpitem'_`i'=`bestest'[`i',`=`k'+1'] if ``i''==`k'&`touse'
+			}
+		}
+		*su
+		qui egen `genlt'_best=rowmean(`tmpitem'_*) if `touse'
+		*qui egen `genlt'_opt_se=rowsd(`tmpitem'_*) if `touse'
+		qui egen `nbnonmiss'=rownonmiss(`tmpitem'_*) if `touse'
+		*qui replace `genlt'_opt_se=sqrt((`genlt'_opt_se^2+`resvar')/`nbnonmiss') if `touse'
+ 	}
+	restore,not
+}
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin, footer(fall_report)
+	putdocx table hdr = (1, 3), border(all, nil) tofooter(fall_report)
+	if "`rsm'"=="" {
+		putdocx table hdr(1, 1) = ("Partial Credit Model")
+	}
+	else {
+		putdocx table hdr(1, 1) = ("Rating Scale Model")
+	}
+	putdocx table hdr(1, 2) = ("`dimname'"), halign(center)
+	putdocx table hdr(1, 3) = ("Page "), pagenumber
+	putdocx table hdr(1, 3) = ("/"), totalpages append
+	putdocx table hdr(1, 3), halign(right)
+	putdocx paragraph ,style(Title)
+	if "`dimname'" =="" {
+	    local dimname2 "Rasch analysis"
+	}
+	else {
+	    local dimname2 "Rasch analysis of the `dimname' dimension"
+	}
+	putdocx text ("`dimname2'") ,
+	putdocx paragraph ,style(Subtitle)
+	putdocx text ("General informations") ,
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("Names of the dimension: `dimname'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph, style(Subtitle)
+	putdocx text ("Estimation of the parameters") , 
+	local paramname
+	forvalues j=1/`nbitems' {
+		forvalues k=1/`modamax' {
+		     if `k'<=`modamax`j'' {
+			     local paramname `paramname' "``j''_`k'"
+			 }
+	    }
+	}
+	*di "matrix colnames `diff'=`paramname'"
+	matrix rownames `diff'=`paramname'
+    putdocx table table1 = matrix(`diff') , nformat(%9.3f) rownames colnames  border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil) headerrow(1)  halign(center)
+    putdocx table table1(.,1), halign(left) 
+    putdocx table table1(.,2/7), halign(right) 
+    putdocx table table1(1,.), halign(right) border(top) border(bottom)
+	
+	
+	qui putdocx table table2 = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)  headerrow(1)
+    putdocx table table2(.,1), halign(left) 
+    putdocx table table2(.,2/7), halign(right) 
+    putdocx table table2(1,.), halign(right) border(top) border(bottom)
+
+
+
+	
+	putdocx paragraph,style(Subtitle)
+	putdocx text ("Fit indexes for items") , /*bold underline font(,14) smallcaps*/
+	qui putdocx table table3 = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)    headerrow(1)
+    putdocx table table3(.,1), halign(left) 
+    putdocx table table3(.,2/5), halign(right) 
+    putdocx table table3(1,.), halign(right) border(top) border(bottom)
+
+
+
+	putdocx paragraph, style(Subtitle)
+	putdocx text ("Estimation per group/score")
+	*putdocx text ("Estimation per group/score") , bold underline font(,14) smallcaps
+	*set trace on
+	putdocx table tbl = (`=`nbrowmat'+1',7), border(all,nil) width(7) halign(center) note(EAP: Expected A Posteriori ; BE: Best Estimates) headerrow(1)
+    putdocx table tbl(1,.), halign(right) border(top) border(bottom)
+	putdocx table tbl(1,1) = ("Group"), halign(right) 
+	putdocx table tbl(1,2) = ("score"), halign(right) 
+	putdocx table tbl(1,3) = ("Frequency"), halign(right) 
+	putdocx table tbl(1,4) = ("EAP Mean"), halign(right) 
+	putdocx table tbl(1,5) = ("EAP s.e."), halign(right) 
+	putdocx table tbl(1,6) = ("Exp score"), halign(right) 
+	putdocx table tbl(1,7) = ("BE Mean"), halign(right) 
+	local fin=1
+	forvalues row=1/`nbrowmat' {
+	    local row2=`row'+1
+		local g: di %9.0f `matgroupscorelt'[`row',1]
+		local gh=`matgroupscorelt'[`row',1]
+		if `fin'==1 {
+			putdocx table tbl(`row2',1) = ("`g'"), halign(right) 
+		}
+		if `matgroupscorelt'[`row',2]!=.|`matgroupscorelt'[`row',7]==. {
+		    local s: di %9.0f `matgroupscorelt'[`row',2]
+			local fin=0
+		}
+		else {
+			local s "`scoremin`gh''/`scoremax`gh''"
+			local fin=1
+			*local fin "border(top) border(bottom)"
+			*di "c'est la fin"
+			putdocx table tbl(`row2',.),  border(bottom) border(top, dashed)
+			putdocx table tbl(`row2',1), border(top, nil)
+		}
+		local eff: di %9.0f `matgroupscorelt'[`row',3]
+		local lt: di %9.3f `matgroupscorelt'[`row',4]
+		local se: di %9.3f `matgroupscorelt'[`row',5]
+		local exp: di %9.2f `matgroupscorelt'[`row',6]
+		local clt: di %9.3f `matgroupscorelt'[`row',7]
+		*putdocx table tbl(`row',.), addrows(7)
+		putdocx table tbl(`row2',2) = ("`s'"), halign(right) 
+		putdocx table tbl(`row2',3) = ("`eff'"), halign(right) 
+		putdocx table tbl(`row2',4) = ("`lt'"), halign(right) 
+		putdocx table tbl(`row2',5) = ("`se'"), halign(right) 
+		putdocx table tbl(`row2',6) = ("`exp'"), halign(right) 
+		putdocx table tbl(`row2',7) = ("`clt'"), halign(right) 
+
+	}
+
+/*
+		qui matrix `matgroupscorelt'[`row',1]=`g'
+		*qui matrix `matgroupscorelt'[`row',2]="`scoremin`g''/`scoremax`g''"
+		qui matrix `matgroupscorelt'[`row',3]=`eff`g''
+		qui matrix `matgroupscorelt'[`row',4]=`lt`g''
+		qui matrix `matgroupscorelt'[`row',5]=`se'
+		*qui matrix `matgroupscorelt'[`row',6]=`exp'
+		qui matrix `matgroupscorelt'[`row',7]=`clt`g''
+		local ++row
+	}
+	local nbrowmat=`row'-1
+
+
+local row 1
+local vari 1
+foreach x in gear_ratio turn foreign _cons {
+putdocx table tbl5(`row',.), addrows(2)
+local b: display %9.3f rtable[`vari',1]
+local se: display %9.3f rtable[`vari',2]
+local ++vari
+local ++row
+putdocx table tbl5(`row',1) = ("`x'"), halign(right)
+putdocx table tbl5(`row',2) = ("`b'"), halign(right)
+local ++row
+local se = strtrim("`se'")
+putdocx table tbl5(`row',2) = ("(`se')"), halign(right)
+}*/
+	
+	*qui putdocx table tablename = matrix(`matgroupscorelt') , nformat(%9.3f) /*rownames*/ colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+				putdocx paragraph, style(Subtitle)
+				putdocx text ("General Graphs")
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			putdocx paragraph, style(Subtitle)
+			putdocx text ("Graphs per item")
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+					putdocx paragraph, style(Heading1)
+				    putdocx text ("Graphs for ``i''") 
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+*set trace on
+
+matrix colnames `diff'="Estimate" "Std err" "z" "p" "lb" "ul"
+matrix colnames `covariates'=Estimate s.e. z p lb ul
+matrix rownames `diff'=`diffname'
+*matrix list `diff'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+return matrix matscorelt=`matscorelt'
+return matrix matgroupscorelt=`matgroupscorelt'
+return matrix bestest=`bestest'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm.ado b/Modules/ado/personal/p/pcm.ado
new file mode 100644
index 0000000..ec43d62
--- /dev/null
+++ b/Modules/ado/personal/p/pcm.ado
@@ -0,0 +1,2299 @@
+*! Version 5.4 28July2023
+*! Jean-Benoit Hardouin, Myriam Blanchin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
+* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
+* Version 4.1: September 15th, 2019 [Jean-Benoit Hardouin]: correction of a small bug in the outputs
+* Version 4.2: September 27th, 2019 [Jean-Benoit Hardouin] : EQUATING
+* Version 4.3: November 8th, 2019 [Jean-Benoit Hardouin] : add a constant when difficulty parameters are fixed
+* Version 5: August 2nd, 2022 [Jean-Benoit Hardouin] : New MAP graph, corrected estimation of the latent trait
+* Version 5.1: July 8th, 2023 [Jean-Benoit Hardouin] : Correction of the MAP graph (histogram) and residuals graphs
+* Version 5.2: July 16th, 2023 [Jean-Benoit Hardouin] : Add of new graphs for Equating
+* Version 5.3: July 21th, 2023 [Jean-Benoit Hardouin] : Improvements for the docx option
+* Version 5.4: July 28th, 2023 [Jean-Benoit Hardouin] : Improvements for graphs et corrections of bugs
+* Version 5.5: October 25th, 2023 [Jean-Benoit Hardouin] : first attemp with DIF
+*
+*
+* Jean-benoit Hardouin, Myriam Blanchin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr, myriam.blanchin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019, 2022, 2023 Jean-Benoit Hardouin, Myriam Blanchin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [if] [in] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) VARiance(real -1) rsm Graphs noGRAPHItems noCORRected filesave dirsave(string) docx(string) extension(string) alpha(real 0.01)  PCE WMLiterate(int 1) GENLT(string) GENINF(string) REPlace postpce visit(varname) id(varname) eqset1(varlist) eqset2(varlist) eqset1name(string) eqset2name(string) EQGraph eqaddset1(real 0) eqaddset2(real 0) eqmultset1(real 1) eqmultset2(real 1) eqwithci eqgenscore(string)  DIMname(string) minsize(int 30) vardif(varname) itemsdif(varlist) noRESiduals scorewithdif(varname) vardif(varname) ]
+
+version 14
+preserve
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+/*************************************************************************************************************
+QUELQUES TESTS
+*************************************************************************************************************/
+
+if `variance'!=-1&`variance'<=0 {
+	di in red "The -variance- option cannot be negative"
+	exit 198
+}
+if `variance'!=-1&"`visit'"!="" {
+	di in red "The -variance- and -visit- options cannot be used simultaneously."*
+	exit 198
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' `genlt'_se `geninf' `genlt'_corr `genlt'_opt `genlt'_opt_se 
+	if _rc!=0&"`replace'"=="" {
+	    di in red "The variables `genlt', `genlt'_se, `genlt'_corr, `genlt'_opt, `genlt'_opt_se and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+	if _rc!=0&"`replace'"!="" {
+	    qui capture drop `genlt' 
+		qui capture drop `genlt'_se 
+		qui capture drop `geninf' 
+		qui capture drop `genlt'_corr
+		qui capture drop `genlt'_opt
+		qui capture drop `genlt'_opt_se
+	}
+}
+if ("`eqset1'"!=""&"`eqset2'"=="")|("`eqset1'"==""&"`eqset2'"!="") {
+    di in red "The two options -eqset1- and -eqset2- must be used simultaneously"
+	exit 198
+}
+if ("`eqset1'"!=""&"`graphs'"!="") {
+    di in red "The two options -eqset1- and -graph- cannot be used simultaneously"
+	exit 198
+}
+if "`corrected'"!="" {
+	local xtitle "Latent trait"
+}
+else {
+	local xtitle "Corrected latent trait"
+}
+
+
+
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+if "`visit'"!=""{
+	if "`id'"==""{
+		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
+		exit 198
+	}
+	qui levelsof `visit'
+	local levelsofv `r(levels)'
+	local nbvisits=r(r)
+	local timemin: word 1 of `levelsofv'
+	local timemax: word `nbvisits' of `levelsofv'
+	if `timemax'>5{
+		di as error "You must use a discrete time variable (-visit- option) with less than 5 measurement occasions"
+		error 198
+	}
+	if `timemin'!=1{
+		di as error "You must use a -visit- variable coded at 1 for the first visit"
+		error 198
+	}
+	qui reshape wide `varlist', i(`id') j(`visit')
+	local multivisit=1
+}
+else {
+	local timemax=1
+	foreach i in `varlist' {
+	   *rename `i' `i'1
+	}
+	local multivisit
+}
+qui count if `touse'
+local nbobs=r(N)
+
+local timelist
+forvalues t=1/`timemax'{
+	local timelist `timelist' T`t'
+}
+
+local modcont
+local premodcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local premodcont (`modcont'->T1)
+	local modcont (`modcont'->`timelist')
+}
+
+local modcat
+local premodcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local premodcat (`modcat'->T1)
+	local modcat (`modcat'->`timelist')
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+local scoremax=0
+forvalues i=1/`nbitems' {
+    local name``i'': variable label ``i''
+	if "`name``i'''"=="" {
+		local name``i'' ``i''
+	}
+	local modamax`i'=1
+	local modamax``i''=1
+	if `timemax'>1 {
+		forvalues t=1/`timemax'{
+			 *qui replace ``i'`t''=``i'`t''-`min' 
+			 qui su ``i''`t' if `touse'
+			 if `r(min)'!=`modamin' {
+				 local modamin=r(min)
+				 local pbmin `pbmin' ``i'`t''
+			 }
+			 if `r(max)'>`modamax' {
+				 local modamax=r(max)
+			 }
+			 if `r(max)'>`modamax`i'' {
+				local modamax`i'=r(max)
+			}
+		}
+	}
+	else {
+		*di "i: `i' ``i''"
+		qui su ``i'' if `touse'
+		if `r(min)'!=`modamin' {
+		    local modamin=r(min)
+			local pbmin `pbmin' ``i''
+		}
+		if `r(max)'>`modamax' {
+			local modamax=r(max)
+		}
+		if `r(max)'>`modamax`i'' {
+			local modamax`i'=r(max)
+			local modamax``i''=r(max)
+		}
+	}
+	*di "local scoremax=`scoremax'+`modamax`i''"
+	local scoremax=`scoremax'+`modamax`i''
+	if "`rsm'"=="" {
+		local nbdiff=`nbdiff'+`modamax`i''
+	}
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count if `touse'
+local nbind=r(N)
+*set trace on
+local code
+local precode
+if `timemax'>1 {
+	forvalues k=1/`modamax' {
+	   forvalues t=1/`timemax'{
+			local code`k'
+		   forvalues i=1/`nbitems' {
+			   if `k'<=`modamax`i'' {
+				  local code`k' `code`k'' `k'.``i''`t'
+			   }
+		   }
+		   local code`k' (`code`k''<-T`t'@`k')
+		   if `t'==1{
+				local precode `precode' `code`k''
+		   }
+		   local code `code' `code`k''
+		}
+	}
+}
+else {
+	forvalues k=1/`modamax' {
+		local code`k'
+		forvalues i=1/`nbitems' {
+			if `k'<=`modamax`i'' {
+				local code`k' `code`k'' `k'.``i''
+			}
+		}
+		local code`k' (`code`k''<-T1@`k')
+		local precode `precode' `code`k''
+		local code `code' `code`k''
+	}
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist' if `touse'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist' if `touse', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+local t=1
+local constraints
+local codemean
+local codevar
+local codecov
+forvalues j=2/`timemax'{
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			qui constraint `t' [`k'.``i''`j']_cons=[`k'.``i''`multivisit']_cons
+			local constraints `constraints' `t'
+			local ++t
+			
+		}
+	}	
+	if "`continuous'"=="" &  "`categorical'"==""{
+		local codemean `codemean' T`j'@m`j'
+		local codevar `codevar' T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' T`l'*T`j'@cov`l'`j'
+		}
+	}
+	else{
+		local codevar `codevar' e.T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
+		}	
+	}
+}
+if `timemax'>1{
+	if "`continuous'"=="" &  "`categorical'"==""{	
+		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
+	}
+	else{
+		local codelg var(e.T1@v1 `codevar') cov(`codecov')
+	}
+}
+else {
+    local constrvar
+    if `variance'>0 {
+		if "`continuous'"=="" &  "`categorical'"==""{	
+			local constrvar var(T1@`variance') 
+		}
+		else{ 
+			*local constrvar var(e.T1@`variance') 
+		}
+	}
+}
+
+local fixedmean
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				qui constraint `t' [`k'.``i''`multivisit']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+	if "`continuous'"=="" &  "`categorical'"=="" {	
+		local fixedmean mean(T1) 
+	}
+	else{
+		local fixedmean 
+	}
+}
+
+
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+if "`rsm'"!="" {
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       qui constraint `t'   [`=`k'-1'.``i''`multivisit']_cons-[`k'.``i''`multivisit']_cons+[1.``i''`multivisit']_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
+if "`model'"!="" {
+    local qui
+}
+else {
+	local qui qui
+}
+if `timemax'==1{
+   *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'"
+   `qui' gsem `code' `modcont' `modcat' if `touse' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+   *qui gen un=1
+   *`qui' gsem `code' (i.group un->T) ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+}
+else{
+    *di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
+    `qui' gsem `precode' `premodcont' `premodcat' if `touse',iterate(`iterate') tol(`tolerance') constraint(`constraints') 
+     matrix esti_B = e(b)
+    *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)"
+    `qui' gsem `code' `modcont' `modcat' if `touse',iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
+}
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2 miss
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent'* if `touse',latent se(`selatent'*)
+*di "latent=`latent' "
+*su
+*set trace on
+
+if "`genlt'"!="" {
+	if `timemax'==1 {
+		qui gen `genlt'=`latent'1 if `touse'
+		qui gen `genlt'_se=`selatent'1 if `touse'
+	}
+	forvalues t=2/`timemax' {
+		qui gen `genlt'`t'=`latent'`t' if `touse'
+		qui gen `genlt'`t'_se=`selatent'`t' if `touse'
+	}
+}
+
+set seed 123456
+if `timemax'>1 {
+	forvalues t=1/`timemax'{
+		qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t' if `touse'
+		local listit 
+		forvalues i=1/`nbitems' {
+			local listit `listit' ``i''`t'
+		}
+		qui genscore `listit' if `touse',score(`score'`t')
+		qui gengroup `latent'`t' if `touse',newvariable(`group'`t') continuous minsize(`minsize')
+	}
+}
+else {
+	qui gen `latent2'=`latent'1+invnorm(uniform())*`selatent'1 if `touse'
+	local listit 
+	forvalues i=1/`nbitems' {
+		local listit `listit' ``i''
+	}
+	qui genscore `listit' if `touse',score(`score')
+	qui gengroup `latent'1 if `touse',newvariable(`group') continuous minsize(`minsize')
+}
+forvalues s=0/`scoremax' {
+    qui count if `score'==`s'&`touse'
+	local effscore`s'=r(N)
+}
+
+
+/*time 1 only*/
+qui levelsof `group'`multivisit' if `touse'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+10',.)
+forvalues g=1/`nbgroups' {
+	matrix `groups'[`g',`=`nbitems'+3']=0
+	qui count if `group'`multivisit'==`g'&`touse'
+	local effgroup`g'=r(N)
+	forvalues i=1/`nbitems' {
+			qui count if ``i''`multivisit'!=.&`group'`multivisit'==`g'&`touse'
+			local n=r(N)
+			if `n'>0 {
+				qui su ``i''`multivisit' if `group'`multivisit'==`g'&`touse'
+				matrix `groups'[`g',`i']=r(mean)
+				matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+			}
+			else {
+				matrix `groups'[`g',`i']=.
+				matrix `groups'[`g',`=`nbitems'+3']=.
+			}		
+	}
+	qui su `latent'1 if `group'`multivisit'==`g'&`touse'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	matrix `groups'[`g',`=`nbitems'+7']=r(min)
+	matrix `groups'[`g',`=`nbitems'+8']=r(max)
+	qui count if `group'`multivisit'==`g'&`touse'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+	qui su `score' if `group'`multivisit'==`g'&`score'!=.&`touse'
+	matrix `groups'[`g',`=`nbitems'+4']=r(min)
+	matrix `groups'[`g',`=`nbitems'+5']=r(max)	
+}
+
+/*number of non-missing on all time points*/
+egen `miss'=rowmiss(`score'*) if `touse'
+qui count if `miss'==0&`touse'
+local nbobsssmd=r(N)
+drop `miss'	
+
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of individuals with a complete answer pattern:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i''`multivisit':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i''`multivisit':_cons]
+	qui lincom -_b[1.``i''`multivisit':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+	local rn `rn' 1.``i''`multivisit'
+	local ++t
+	local sum _b[1.``i''`multivisit':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax`i'' {
+			local sum "_b[`k'.``i''`multivisit':_cons]-(`sum')"
+			*di "``i''`multivisit' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i''`multivisit':_cons]-_b[`k'.``i''`multivisit':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''`multivisit'
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1'`multivisit':_cons]-_b[`k'.`1'`multivisit':_cons]+_b[1.`1'`multivisit':_cons] /*``i'' instead of `i'?*/
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+*di "matrix rownames `diff'=`rn'"
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
+*************************************************************************************************************/
+tempname covariates
+local nbcov=0
+forvalues j=2/`timemax'{
+	local nbcov=`nbcov'+`j'-1
+}
+qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)
+
+*set trace on
+local t=1
+
+
+forvalues j=1/`=`timemax'-1'{
+	forvalues k=`=`j'+1'/`timemax'{
+		if "`categorical'"=="" & "`continuous'"=="" {
+			if `j'==1{
+				qui lincom [/]mean(T`k')
+			}
+			else{
+				qui lincom [/]mean(T`k')-[/]mean(T`j')
+			}
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+		else{
+			if "`categorical'"!=""{
+				local first=0 
+				foreach l in `levelsof`cat1'' {
+					if `first'==0 {
+						local ++first
+					}
+					else{
+						if `first'==1 {
+							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
+							qui matrix `covariates'[`t',1]=`r(estimate)'
+							qui matrix `covariates'[`t',2]=`r(se)'
+							qui matrix `covariates'[`t',3]=`r(z)'
+							qui matrix `covariates'[`t',4]=`r(p)'
+							qui matrix `covariates'[`t',5]=`r(lb)'
+							qui matrix `covariates'[`t',6]=`r(ub)'
+							local ++t
+							local ++first
+						}
+					}
+				}
+			}
+			else{
+				qui lincom [T`k']`cont1'-[T`j']`cont1'
+				qui matrix `covariates'[`t',1]=`r(estimate)'
+				qui matrix `covariates'[`t',2]=`r(se)'
+				qui matrix `covariates'[`t',3]=`r(z)'
+				qui matrix `covariates'[`t',4]=`r(p)'
+				qui matrix `covariates'[`t',5]=`r(lb)'
+				qui matrix `covariates'[`t',6]=`r(ub)'
+				local ++t
+			}		
+		}
+	}
+}	
+		
+forvalues j=1/`timemax'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		qui lincom _b[/var(e.T`j')]
+	}
+	else {
+		qui lincom _b[/var(T`j')]
+	}
+	qui matrix `covariates'[`t',1]=`r(estimate)'
+	qui matrix `covariates'[`t',2]=`r(se)'
+	qui matrix `covariates'[`t',3]=`r(z)'
+	qui matrix `covariates'[`t',4]=`r(p)'
+	qui matrix `covariates'[`t',5]=`r(lb)'
+	qui matrix `covariates'[`t',6]=`r(ub)'
+	local ++t
+}
+forvalues j=1/`=`timemax'-1'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(e.T`j',e.T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+	else{
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(T`j',T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+}
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+*matrix list `covariates'
+
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 83}"
+	di  as text _col(70) "<--95% IC -->"
+	di   _col(70) "Lower" _col(78) "Upper"
+	di "Items" _col(22) "Threshold" _col(35) "Estimate" _col(47) "s.e." _col(59) "z" _col(66) "p" _col(69) " Bound" _col(78) "Bound"
+	di "{hline 83}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax`i'' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("`name``i'''",20) _c
+			  }
+			  di as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %6.2f `diff'[`t',3] _col(62) %5.3f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %6.2f `diff'[`t',3] _col(62) %5.3f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 83}"
+	local t=1
+	local listmoy
+	local listvar
+	local listcov
+	forvalues j=1/`timemax'{
+		local listvar `listvar' Variance_T`j'
+		forvalues k=`=`j'+1'/`timemax'{
+			local listcov `listcov' Cov_T`j'_T`k'
+		}
+		forvalues k=`=`j'+1'/`timemax'{
+			local listmoy `listmoy' Mean_diff_T`j'_T`k'
+		}
+	}
+	local n: word count `listmoy' `listvar' `listcov' 
+	forvalues i=1/`n' {
+		local v: word `i' of `listmoy' `listvar' `listcov' 
+		di as text _col(1) %5.2f "`v'"  as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %6.2f `covariates'[`t',3] _col(62) %5.3f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+	local n: word count `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of  `continuous' 
+		local v2 :  variable label `v'
+		if "`v2'"=="" {
+		   local v2 `v'
+		}
+		di as text _col(1) %5.2f  abbrev("`v2'",20)  as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %6.2f `covariates'[`t',3] _col(62) %5.3f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count  `categorical' 
+	*di "local n: word count of  `categorical' "
+	*di "n=`n'"
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local v2 : variable label `v'
+		if "`v2'"=="" {
+		   local v2 `v'
+		}
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v2'",20) _c
+				}
+				di  as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %6.2f `covariates'[`t',3] _col(62) %5.3f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		*local ++t
+	}
+	di as text "{hline 83}"
+	if "`visit'"==""{
+		di
+		qui su `latent'1 if `touse'
+		*qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])+(`r(sd)')^2)
+		*di as text "Variance of the estimated latent variable: " as result %4.2f `=(`r(sd)')^2'
+        tempvar se2latent
+		qui gen `se2latent'=(`selatent'1)^2 if `touse'
+		qui su `se2latent' if `touse'
+		local resvar=r(mean)
+		di as text "Mean squared std error of the latent variable: " as result %4.2f `resvar'
+		di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`resvar'))'
+		local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`resvar'))
+		di as text "PSI: " as result %4.2f `PSI' _c
+		if "`continuous'"!=""|"`categorical'"!="" {
+		    di as text " (without adjustment on covariates)"
+	    }
+		else {
+		    di
+		}
+		di
+		return scalar PSI=`PSI'
+
+	}
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+
+/*************************************************************************************************************
+ESTIMATION OF THE CORRECTED VALUES OF THE LT ESTIMATORS (values of lt that explained the best the score)
+**************************************************************************************************************/
+*set trace on
+tempfile savefile
+qui save `savefile'
+
+qui drop _all
+		
+qui set obs 2000
+qui gen u=(_n-1000)/200*`=2*sqrt(`covariates'[1,1])'
+qui gen Tcum=0
+qui gen TInf=0
+forvalues i=1/`nbitems' {
+		local d=1
+		qui gen cum``i''=0
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+		}
+		qui gen c0_``i''=1/(`d')
+		forvalues k=1/`mm' {
+			qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+			qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+		}
+		qui gen Inf``i''=0
+		forvalues k=1/`mm' {
+			qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+		}
+		*set trace on
+		qui replace Tcum=Tcum+cum``i''
+		qui replace TInf=TInf+Inf``i''	
+	    local scoremax=0
+		forvalues l=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`l''
+	    }
+		qui gen ecart=.
+		local listlt
+		forvalues l=0/`scoremax' {
+		    if `l'==0 {  
+			   local j=0.25
+			}
+			else if `l'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`l'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`l'=`r(mean)'
+			local listlt `listlt' `estlt`l''
+			*qui su TInf if round(ecart, 0.01)==round(`tmp',0.01)
+			*local setlt`l'=sqrt(1/`r(mean)')
+		}
+		qui drop ecart
+}
+qui use `savefile', clear
+
+
+*set trace on
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+
+/*Quelques explications
+latent : estimation EAP du trait latent
+latent2 : estimation Plausible Value Ă  partir de l'estimation EAP
+corrlatent : estimation corrigée cherchant la meilleur valeur du trait latent qui explique le score, interpolation à partir de l'EAP pour les individus avec des données manquantes
+*/
+
+
+if "`visit'"==""{
+	tempvar corrlatent corrlatenttmp 
+	qui gen `corrlatenttmp'=.
+	forvalues s=0/`scoremax' {
+	    qui replace `corrlatenttmp'=`estlt`s'' if `score'==`s'
+	}
+	qui ipolate `corrlatenttmp' `latent'1 , generate(`corrlatent') epolate
+	*list `corrlatenttmp' `latent2' `corrlatent' 
+	qui replace `corrlatent'=`corrlatenttmp' if `corrlatenttmp'!=.
+	qui replace `corrlatent'=`latent' if `corrlatenttmp'==.
+	*su  `corrlatenttmp' `latent2' `corrlatent' 
+    *twoway (scatter `corrlatent' `score') (scatter `latent2' `score') 
+	forvalues g=1/`nbgroups' {
+			*di "group=`g'" 
+			qui su `corrlatent' if `group'==`g'&`touse'
+			*di "qui matrix `groups'[`g',`=`nbitems'+9']=`r(min)'"
+			*di "qui matrix `groups'[`g',`=`nbitems'+10']=`r(max)'"
+			if r(N)!=0 {
+				qui matrix `groups'[`g',`=`nbitems'+9']=`r(min)'
+				qui matrix `groups'[`g',`=`nbitems'+10']=`r(max)'
+			}
+	}
+	tempname fit
+	qui matrix `fit'=J(`nbitems',6,.)
+	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT" "corrOUTFIT" "corrINFIT"
+	matrix rownames `fit'=`varlist'
+	*matrix list `fit'
+
+	tempvar Tcum TInf cum
+	qui gen `Tcum'=0 if `touse'
+	qui gen `TInf'=0 if `touse'
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text _col(60) "<---  Standardized   --->"
+		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+		di as text "{hline 90}"
+		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "{hline 90}"
+	}
+	*set trace on
+	local chi2=0
+	local chi2_old=0
+	forvalues g=1/`nbgroups' {
+	   local chi2_g`g'=0
+	   local chi2_old_g`g'=0
+	}
+	forvalues i=1/`nbitems' {
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+		tempvar corrcum``i'' corrc0_``i'' corrInf``i'' corry``i'' corrz``i'' corrz2``i'' corri``i'' 
+
+		local d=1
+		local corrd=1
+		local d_old=1
+		qui gen `corrcum``i'''=0 if `touse'
+		qui gen `cum``i'''=0 if `touse'
+		qui gen `cum_old``i'''=0 if `touse'
+		forvalues k=1/`mm' {
+			local corrd `corrd'+exp(`k'*`corrlatent'-`diffmat2'[`i',`k'])
+			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+			local d_old `d_old'+exp(`k'*`latent'1-`diffmat2'[`i',`k'])
+		}
+		qui gen `corrc0_``i'''=1/(`corrd') if `touse' 
+		qui gen `c0_``i'''=1/(`d') if `touse' 
+		qui gen `c_old0_``i'''=1/(`d_old') if `touse'
+		forvalues k=1/`mm' {
+			tempvar corrc`k'_``i'' c`k'_``i'' c_old`k'_``i''
+			qui gen `corrc`k'_``i'''=exp(`k'*`corrlatent'-`diffmat2'[`i',`k'])/(`corrd') if `touse'
+			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d') if `touse'
+			qui gen `c_old`k'_``i'''=exp(`k'*`latent'1-`diffmat2'[`i',`k'])/(`d') if `touse'
+			qui replace `corrcum``i'''=`corrcum``i'''+`corrc`k'_``i'''*`k' if `touse'
+			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k' if `touse'
+			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k' if `touse'
+		}
+		qui gen `corrInf``i'''=0 if `touse'
+		qui gen `Inf``i'''=0 if `touse'
+		qui gen `Inf_old``i'''=0 if `touse'
+		qui gen `C``i'''=0 if `touse'
+		forvalues k=0/`mm' {
+			qui replace `corrInf``i'''=`corrInf``i'''+(`k'-`corrcum``i''')^2*`corrc`k'_``i''' if `touse'
+			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i''' if `touse'
+			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i''' if `touse'
+			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i''' if `touse'
+		}
+		qui count if ``i''!=.&`touse'
+		local n``i''=r(N)
+		
+		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2) if `touse'
+		qui su `C2``i''' if `touse'
+		local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2 if `touse'
+		qui su `C3``i'''
+		local n=r(sum)
+		qui su `Inf``i''' if `touse'
+		local d=r(sum)
+		local q2i``i''=`n'/((`d')^2)
+		
+		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+		
+		qui replace `Tcum'=`Tcum'+`cum``i''' if `touse'
+		qui replace `TInf'=`TInf'+`Inf``i''' if `touse'
+		qui gen `corry``i'''=``i''-`corrcum``i''' if `touse'
+		qui gen `y``i'''=``i''-`cum``i''' if `touse'
+		qui gen `y_old``i'''=``i''-`cum_old``i''' if `touse'
+		qui gen `y2``i'''=(`y``i''')^2 if `touse'
+		qui gen `y2_old``i'''=(`y_old``i''')^2 if `touse'
+		qui gen `corrz``i'''=(`corry``i'''/sqrt(`corrInf``i''')) if `touse'
+		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i''')) if `touse'
+		local chi2_``i''=0
+		local chi2_old_``i''=0
+		forvalues g=1/`nbgroups' {
+			
+			qui su `y2``i''' if `group'==`g'&`touse'
+			local n=r(sum)
+			qui su ``i'' if `group'==`g'&`touse'
+			local n1=r(sum)
+			qui su `cum``i''' if `group'==`g'&`touse'
+			local n2=r(sum)
+			qui su `Inf``i''' if `group'==`g'&`touse'
+			local d=r(sum)
+			*qui count if `group'==`g'
+			*local eff=r(N)
+			*di "chi2_`g'_``i''=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')"
+			local chi2=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_``i''=`chi2_``i'''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_g`g'=`chi2_g`g''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			qui su `y2_old``i''' if `group'==`g'&`touse'
+			local n_old=r(sum)
+			qui su ``i'' if `group'==`g'&`touse'
+			local n1_old=r(sum)
+			qui su `cum_old``i''' if `group'==`g'&`touse'
+			local n2_old=r(sum)
+			qui su `Inf_old``i''' if `group'==`g'&`touse'
+			local d_old=r(sum)
+			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+		}
+		*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+		*su `z``i'''
+		label variable `corrz``i''' "Corrected standardized residuals associated to ``i''"
+		label variable `z``i''' "Standardized residuals associated to ``i''"
+		label variable `latent'1 "Latent trait"
+		label variable `corrlatent' "Corrected latent trait"
+		*set trace on
+		if  "`graphs'"!=""&"`graphitems'"=="" {
+			*set trace on
+			*set tracedepth 1
+			if "`filesave'"!="" {
+				local fs saving("`dirsave'//residuals_``i''",replace)
+			}
+			local thr=abs(invnorm(`alpha'/2))
+			tempvar id``i''
+			local hline
+			forvalues l=1/`modamax`i'' {
+				local hline `hline' `=`diffmat'[`i',`l']'
+			}
+			if "`residuals'"=="" {
+				if "`corrected'"!="" {
+					qui gen `id``i'''=_n if abs(`z``i''')>`thr'*sqrt(`covariates'[1,1])&`touse'
+					qui tostring `id``i''',replace
+					qui replace `id``i'''="" if `id``i'''=="."&`touse'
+					qui su `z``i''' if `touse'
+					local min=r(min)
+					local max=r(max)
+					local min=floor(min(`min',`=-`thr'*sqrt(`covariates'[1,1])'))
+					local max=ceil(max(`max',`=`thr'*sqrt(`covariates'[1,1])'))
+				
+					qui graph twoway scatter `z``i''' `latent' if `touse', xline(`hline',lwidth(vthin) lcolor(gray)) colordiscrete colorvar(``i'') colorlist(blue green orange purple gray red cyan ) ylabel(`min'(1)`max') yline(`=-`thr'*sqrt(`covariates'[1,1])' `=`thr'*sqrt(`covariates'[1,1])',  lcolor(black)) mlabel(`id``i''') name(residuals``i'',replace) title("Standardized residuals") subtitle(`name``i''') `fs'
+				}
+				else {
+				*set trace on
+					qui gen `id``i'''=_n if abs(`corrz``i''')>`thr'*sqrt(`covariates'[1,1])&`touse'
+					qui tostring `id``i''',replace
+					qui replace `id``i'''="" if `id``i'''=="."&`touse'
+					qui su `corrz``i''' if `touse'
+					local min=r(min)
+					local max=r(max)
+					local min=floor(min(`min',`=-`thr'*sqrt(`covariates'[1,1])'))
+					local max=ceil(max(`max',`=`thr'*sqrt(`covariates'[1,1])'))
+					qui graph twoway scatter `corrz``i''' `corrlatent' if `touse',xline(`hline',lwidth(vthin)  lcolor(gray))  colordiscrete colorvar(``i'') colorlist(blue green orange purple gray red cyan ) ylabel(`min'(1)`max') yline(`=-`thr'*sqrt(`covariates'[1,1])' `=`thr'*sqrt(`covariates'[1,1])', lcolor(black)) mlabel(`id``i''') name(residuals``i'',replace) title("Standardized residuals") subtitle(`name``i''') `fs' 
+				}
+			}
+			*set trace off
+		}
+		*set trace off 
+		qui gen `z2``i'''=(`z``i''')^2 if `touse'
+		qui su `z2``i''' if `touse'
+		local OUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',1]=`OUTFIT``i'''
+		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `Inf``i''' if ``i''!=.&`touse'
+		local sumw``i''=r(sum)
+		qui gen `i``i'''=`Inf``i'''*`z2``i''' if `touse' 
+		qui su `i``i''' if ``i''!=.&`touse'
+		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+		qui matrix `fit'[`i',2]=`INFIT``i'''
+		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		qui matrix `fit'[`i',4]=`INFITs``i'''
+		
+		/*corrected*/
+		qui gen `corrz2``i'''=(`corrz``i''')^2 if `touse'
+		qui su `corrz2``i''' if `touse'
+		local corrOUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',5]=`corrOUTFIT``i'''
+		*local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		*qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `corrInf``i''' if ``i''!=.&`touse'
+		local corrsumw``i''=r(sum)
+		qui gen `corri``i'''=`corrInf``i'''*`corrz2``i''' if `touse' 
+		qui su `corri``i''' if ``i''!=.&`touse'
+		local corrINFIT``i'' = `=`r(sum)'/`corrsumw``i''''
+		qui matrix `fit'[`i',6]=`corrINFIT``i'''
+		*local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		*qui matrix `fit'[`i',4]=`INFITs``i'''
+
+
+		if "`postpce'"=="" {
+			di abbrev("`name``i'''",20) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' /*_col(94) %5.3f `corrOUTFIT``i''' _col(109) %5.3f `corrINFIT``i'''*/
+		}
+	}
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text "*: As suggested by Bond and Fox (2007)"
+		di as text "**: As suggested by Wright (Smith, 1998)"
+	}
+	if "`geninf'"!="" {
+	    gen `geninf'=`TInf' if `touse'
+	}
+}
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Iteration `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1') if `touse'
+		`qui' pcm `varlist' [iweight=`sinf'] if `touse',diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1') if `touse'
+		qui su `ecart_`it'' if `touse'
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+/*ANCIENNE PLACE DES CORRECTED VALUES*/
+
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+if "`visit'"==""{
+*set trace on
+    tempname matscorelt matgroupscorelt
+	*di "qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)"
+	qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)
+	qui matrix `matgroupscorelt'=J(`=(`nbitems'*`modamax'+1+2*`nbgroups')*4',7,.)
+	qui matrix colnames `matgroupscorelt'="Group" "Score" "Frequency" "Estimation of latent trait" "s.e. of latent trait" "Expected score" "Corrected latent trait"
+	
+	local row=1
+	di
+	di as text "{hline 71}"
+	di _col(32) "Latent Trait" _col(50) "Expected" _col(63) "Corrected"
+	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score" _col(60) "latent trait"
+	di as text "{hline 71}"
+	forvalues g=1/`nbgroups' {
+		local sumuc=0
+		local sumc=0
+		qui count if `group'`multivisit'==`g'&`touse'
+		local eff`g'=r(N)
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'!=.&`touse'
+		local effcompleted`g'=r(N)
+		qui count if `score'`multivisit'!=.&`group'`multivisit'==`g'&`touse'
+		local n=r(N)
+		di as text "`g' (n=" as result `eff`g'' as text ")" _c
+		if `n'>0 {
+			qui su `score'`multivisit' if `group'`multivisit'==`g'&`touse'
+			local scoremin`g'=`r(min)'
+			local scoremax`g'=`r(max)'
+			forvalues s=`scoremin`g''/`scoremax`g'' {
+				qui count if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local eff=r(N)
+				local effscore`s'=r(N)
+				if `eff'!=0 {
+					qui su `latent'1 if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+					local mean=r(mean)
+					*di "local ltscore`s'=`=ceil(`r(mean)'*100)/100'"
+					local ltscore`s'=`=ceil(`r(mean)'*100)/100'
+					*di "local sumc=`sumc'+(`eff')*(`estlt`s'')"
+					*di "local sumuc=`sumuc'+(`eff')*(`mean')"
+				    local sumuc=(`sumuc'+((`eff')*(`mean')))
+				    local sumc=(`sumc'+((`eff')*(`estlt`s'')))
+				}
+				qui su `selatent'1 if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local se=r(mean)
+				qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
+				local exp=r(mean)
+				if `eff'>0 {
+				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp' _col(66) %6.3f `estlt`s''  `setlt`s''
+				}
+				*set trace on
+				*matrix list `matscorelt'
+				qui matrix `matscorelt'[`=`s'+1',1]=`eff'
+				qui matrix `matscorelt'[`=`s'+1',2]=`mean'
+				qui matrix `matscorelt'[`=`s'+1',3]=`se'
+				qui matrix `matgroupscorelt'[`row',1]=`g'
+				qui matrix `matgroupscorelt'[`row',2]=`s'
+				qui matrix `matgroupscorelt'[`row',3]=`eff'
+				qui matrix `matgroupscorelt'[`row',4]=`mean'
+				qui matrix `matgroupscorelt'[`row',5]=`se'
+				qui matrix `matgroupscorelt'[`row',6]=`exp'
+				qui matrix `matgroupscorelt'[`row',7]=`estlt`s''
+				local ++row
+				*set trace off
+			}
+			
+		}
+		*set trace on
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+		local eff=r(N)
+		local eff_md_`g'=r(N)
+		if `eff'!=0 {
+			qui su `latent'1 if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local mean=r(mean)
+			local lt_md_`g'=r(mean)
+			local sumuc=(`sumuc'+((`eff')*(`mean')))
+			qui su `selatent'1 if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local se=r(mean)
+			qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
+			local exp=r(mean)
+			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) /*%5.2f `exp'*/
+			qui matrix `matgroupscorelt'[`row',1]=`g'
+			*qui matrix `matgroupscorelt'[`row',2]=`s'
+			qui matrix `matgroupscorelt'[`row',3]=`eff'
+			qui matrix `matgroupscorelt'[`row',4]=`mean'
+			qui matrix `matgroupscorelt'[`row',5]=`se'
+			qui matrix `matgroupscorelt'[`row',6]=`exp'
+			*qui matrix `matgroupscorelt'[`row',7]=`estlt`s''
+			local ++row
+		}
+		*set trace off
+		*di "local lt`g'=`sumuc'/`eff`g''"		
+		*di "local clt`g'=`sumc'/`effcompleted`g''"
+		local lt`g'=(`sumuc')/(`eff`g'')
+		local clt`g'=(`sumc')/(`effcompleted`g'')
+		matrix `groups'[`g',`=`nbitems'+6']=`clt`g''
+		*di "group `g' est=`lt`g'' corrected est=`clt`g''"
+		di as text "         " "{dup 62:-}"
+		if "`scoremin`g''"=="" {
+			local scoremin`g' "."
+		}
+		if "`scoremax`g''"=="" {
+			local scoremax`g' "."
+		}
+		di  as text _col(10) "`scoremin`g''/`scoremax`g''" as result _col(20) %4.0f `eff`g'' _col(30) %6.3f `lt`g''  _col(66) %6.3f `clt`g''
+		di as text "{hline 71}"
+		qui matrix `matgroupscorelt'[`row',1]=`g'
+		*qui matrix `matgroupscorelt'[`row',2]="`scoremin`g''/`scoremax`g''"
+		qui matrix `matgroupscorelt'[`row',3]=`eff`g''
+		qui matrix `matgroupscorelt'[`row',4]=`lt`g''
+		qui matrix `matgroupscorelt'[`row',5]=`se'
+		*qui matrix `matgroupscorelt'[`row',6]=`exp'
+		qui matrix `matgroupscorelt'[`row',7]=`clt`g''
+		local ++row
+	}
+	local nbrowmat=`row'-1
+	qui matrix `matgroupscorelt'=`matgroupscorelt'[1..`nbrowmat',1..7]
+	*matrix list `matscorelt'
+}	
+
+*set trace on
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+*set trace on
+if "`visit'"==""{
+	if "`graphs'"!=""|"`graphs'"=="" {
+
+		tempfile savefile
+		qui save `savefile'
+
+		*qui clear
+		qui drop _all
+		local pas=1000*round(`=sqrt(`covariates'[1,1])',0.001)
+		local pas=round(`pas')
+		qui set obs `pas'
+		qui gen u=round((_n-`pas'/2)/(`pas'/10)*`=sqrt(`covariates'[1,1])',0.01)
+		*list u
+		qui gen Tcum=0
+		qui gen TInf=0
+		qui gen ecartcum=.
+		forvalues i=1/`nbitems' {
+		   local scatteri`i' 
+		   local scatteric`i' 
+		   forvalues g=1/`nbgroups' {
+			  local x=`groups'[`g',`=`nbitems'+1']
+			  local xc=`groups'[`g',`=`nbitems'+6']
+			  local xmin=`groups'[`g',`=`nbitems'+7']
+			  local xmax=`groups'[`g',`=`nbitems'+8']
+			  local xcmin=`groups'[`g',`=`nbitems'+9']
+			  local xcmax=`groups'[`g',`=`nbitems'+10']
+			  local y=`groups'[`g',`i']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=20
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off) || pci `y' `xmin'  `y' `xmax' ,lcolor(black)
+			  local scatteric`i' `scatteric`i'' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off) || pci `y' `xcmin'  `y' `xcmax' ,lcolor(black)
+			*set trace off
+			}
+			local d=1
+			qui gen cum``i''=0
+			*set trace on
+			if "`rsm'"=="" {
+				local mm=`modamax`i''
+			}
+			else {
+				local mm `modamax'
+			}	
+			forvalues k=1/`mm' {
+				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+			}
+			qui gen c0_``i''=1/(`d')
+			label variable c0_``i'' "Pr(X=0)"
+			local xline 
+			local yline
+			forvalues k=1/`mm' {
+				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+				label variable c`k'_``i'' "Pr(X=`k')"
+				local xline `xline' `=`diffmat'[`i',`k']'
+				local yline `yline' `=`k'-0.5'
+
+			}
+			forvalues k=0/`mm' {
+			    if `k'==0 {
+				   local l=0.25
+				}
+				else if `k'==`mm' {
+				   local l=`k'-0.25
+				}
+				else {
+				   local l=`k'
+				}
+				qui replace ecartcum=abs(cum``i''-`l')
+				qui su ecartcum
+				qui su u if round(ecartcum,0.01)==round(`r(min)',0.01)
+				local bestest``i''_`k'=r(mean)
+				*di "item ``i'' cat `k' : est=`bestest``i''_`k''"
+			}
+			qui gen Inf``i''=0
+			label variable Inf``i'' "`name``i'''"
+			forvalues k=0/`mm' {
+				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+			}
+			if "`graphitems'"=="" {
+				if "`filesave'"!="" {
+					local fsc saving("`dirsave'//CCC_``i''",replace)
+					local fsi saving("`dirsave'//ICC_``i''",replace)
+				}
+				if "`graphs'"!="" {
+					qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC)) subtitle(`name``i''') ytitle("Probability") xtitle("`xtitle'") `fsc' xline(`xline',lwidth(vthin) lcolor(gray))
+					if "`corrected'"!="" {
+						qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC)") subtitle(`name``i''') ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi' xline(`xline',lwidth(vthin) lcolor(gray)) ylabel(0(.5)`modamax`i'')
+					}
+					else {
+						qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC)") subtitle(`name``i''') ytitle("Score to the item") xtitle("Corrected latent trait") `scatteric`i'' `fsi' xline(`xline',lwidth(vthin) lcolor(gray)) ylabel(0(.5)`modamax`i'')
+					}
+				}
+			}
+			qui replace Tcum=Tcum+cum``i''
+			qui replace TInf=TInf+Inf``i''	
+		}
+	    local scoremax=0
+		forvalues i=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`i''
+	    }
+		qui gen ecart=.
+		forvalues i=0/`scoremax' {
+		    if `i'==0 {  
+			   local j=0.25
+			}
+			else if `i'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`i'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`i'=`r(mean)'
+			*di "score `i' : `r(mean)'"
+		}
+		if "`filesave'"!="" {
+			local fst saving("`dirsave'//TCC",replace)
+			local fsteo saving("`dirsave'//TCCeo",replace)
+			local fsi saving("`dirsave'//ICC",replace)
+			local fsti saving("`dirsave'//TIC",replace)
+			local fstii saving("`dirsave'//TICi",replace)
+			local fsm saving("`dirsave'//map",replace)
+		}
+		if "`graphs'"!="" {
+*qui save "C:\temp\info\info",replace
+			label variable TInf "Information curve"
+
+			qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("`xtitle'") `fst' subtitle(`dimname') ylabel(0(1)`scoremax') xline(`listlt',lwidth(vthin) lcolor(gray)) 
+			qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("`xtitle'")  `fsi' subtitle(`dimname')
+			qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("`xtitle'")  `fsti' subtitle(`dimname')
+			qui graph twoway (line Inf*  u, lwidth(thin)) (line TInf u, lwidth(thick)), name(TIC,replace) title("Test/Item Information Curve") ytitle("Information") xtitle("`xtitle'")  `fstii' subtitle(`dimname')
+		}
+		local scatteri
+		local scatteric
+		forvalues g=1/`nbgroups' {
+		*matrix list `groups'
+			local x=`groups'[`g',`=`nbitems'+1']
+			local xc=`groups'[`g',`=`nbitems'+6']
+			local xmin=`groups'[`g',`=`nbitems'+7']
+			local xmax=`groups'[`g',`=`nbitems'+8']
+			local xcmin=`groups'[`g',`=`nbitems'+9']
+			local xcmax=`groups'[`g',`=`nbitems'+10']
+			local y=`groups'[`g',`=`nbitems'+3']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=20
+			  local s tiny
+			  *set trace on
+			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)|| pci `y' `xmin'  `y' `xmax' ,lcolor(black)
+			local scatteric `scatteric' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off) || pci `y' `xcmin'  `y' `xcmax' ,lcolor(black) 
+		}
+		*set trace on
+		if "`graphs'"!="" {
+			if "`corrected'"!="" {
+				qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo' subtitle(`dimname') xline(`listlt',lwidth(vthin) lcolor(gray))
+			}
+			else {
+				qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Corrrected latent trait") `scatteric' `fsteo' subtitle(`dimname') xline(`listlt',lwidth(vthin) lcolor(gray))
+			}
+		}
+		*set trace off
+	}
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+	*set trace on
+	if "`graphs'"!=""|"eqset1"!="" {
+		gen eff=0
+		gen eff_md=0
+		local effmax=0
+			*gen uround=round(u,0.01)
+			*list uround
+		/*le bloc suivant Ă©tait pour avoir des batons par groupe*/
+		/*forvalues g=1/`nbgroups' {
+			local eff=`groups'[`g',`=`nbitems'+2']
+			if `groups'[`g',`=`nbitems'+2']>`effmax' {
+			   local effmax=`groups'[`g',`=`nbitems'+2']
+			}
+			local lat=round(`groups'[`g',`=`nbitems'+1'],0.01)
+			*di "replace eff=`eff' if round(u,0.01)==`lat'"
+			qui replace eff=`eff' if round(u,0.01)==`lat'
+		}*/
+		/*le bloc suivant est pour avoir des batons par score*/
+		qui gen uceil=ceil(u*100)/100
+		forvalues s=0/`scoremax' {
+			if `effscore`s''>`effmax' {
+			   local effmax=`effscore`s''
+			}
+			*di "`s' qui replace eff=`effscore`s'' if ceil(u*100)/100==`=round(`ltscore`s'',0.01)'"
+			qui replace eff=`effscore`s'' if round(u,0.01)==round(`ltscore`s'',0.01)
+		}
+		forvalues g=1/`nbgroups' {
+			*di "if `eff_md_`g''>`effmax' { (`lt_md_`g'')"
+			if `eff_md_`g''>`effmax' {
+			   local effmax=`eff_md_`g''
+			}
+			qui replace eff_md=`eff_md_`g'' if round(u,0.01)==round(`lt_md_`g'',0.01)
+		}
+
+		gen density=normalden(u)*sqrt(`covariates'[1,1])
+		label variable eff "Complete"
+		label variable eff_md "Incomplete"
+		label variable u "Latent trait"
+		label variable TInf "Information curve"
+		label variable density "Density function of the latent trait"
+		local scatteri
+		local scatterj
+		local color 
+		qui su u if eff!=0|eff_md!=0
+		*set trace on
+		*set tracedepth 1
+		*if eff!=0|eff_md!=0 {
+			local floor=floor(`r(min)')
+			local ceil=ceil(`r(max)')
+		*}
+		*else  {
+		*	local floor=-10
+		*	local ceil=10
+		*}
+		local sep
+		local ylbl
+		forvalues i=1/`nbitems' {
+		   local color`i':word `i' of `color'
+		   local unit=round(`effmax'/`nbitems',1)
+		   local y=-`i'*`unit'             
+		   loca staritem
+		   *local legend `"1 2 `=(`modamax'+1)*`nbitems'+1' `=(`modamax'+1)*`nbitems'+2' 3 "1" "'
+		   local legend `"5 "1" "'
+		   forvalues l=1/`modamax' {
+			   if `l'>=2 {
+			      local legend `" `legend' `=2*`l'+3' "`l'" "'
+			   }			   
+			   local x=`diffmat'[`i',`l']
+			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+			   if `l'==1 {
+			      local xant=`x'
+			   }
+			   else {
+			      local xant=`diffmat'[`i',`=`l'-1']
+			   }
+			   if `xant'>`x' {
+				  local star *
+				  local staritem *
+			   }
+			   else {
+			      local star
+			   }
+			   local scatterj `" `scatterj' `sep' scatteri `y' `x'   , pstyle(p`l') || pci `y' `xant' `y' `x', pstyle(p1) color(black)"'
+			   local sep ||
+			   if `x'<`floor' {
+				  local floor=floor(`x')
+			   }
+			   if `x'>`ceil'&`x'!=. {
+				  local ceil=ceil(`x')
+			   }
+		   }
+		   local nomcourt``i''=abbrev("`name``i'''",20)
+   		   local ylbl `ylbl' `=-`i'*`unit'' "`nomcourt``i'''`staritem'"
+		   local scatteri `scatteri' || scatteri `y' `=`floor'-2' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+		}
+		qui su eff
+		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+		qui su eff_md
+		local maxe_md=ceil(`=(floor(`r(max)'/10)+1)*10')
+		local maxe=max(`maxe',`maxe_md')
+		qui su TInf
+		local maxi=1.2*ceil(`r(max)')
+		qui su density
+		local maxd=round(`r(max)', 0.01)+0.01
+		qui drop if u<`floor'|u>`ceil'
+		*di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(0(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3)) `scatterj'   , name(map,replace) ytitle(Frequencies)  ylabel(0(`=`maxi'/5')`maxi' ,axis(2)) ylabel(0(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title(Individuals/items representations (Map)) xsize(12) ysize(9) note(Red line: Information curve - Green line : Density of the latent trait) xtitle(Latent trait) `fsm'"
+		*graph combine TIC IIC,  col(1)
+		*graph save "map" "map.gph", replace
+		*discard
+		*qui graph twoway line TInf u , name(map,replace)
+		*qui graph twoway `scatterj'  , name(map2,replace) ytitle("")   ylabel(`ylbl', grid angle(0))  legend(off) xsize(12) ysize(9) 
+		*su
+*list eff u if eff!=0
+*browse
+		if "`eqset1'"==""&"`graphs'"!="" {
+		    *list eff u uceil if eff!=0&eff!=.
+			*save tmp, replace
+			*di "`legend'"
+			*di "holes(3/`nbcolslegende' `=`nbcolslegende'+3'/`=`nbcolslegende'*2')"
+			local nbcolslegende=max(2,`modamax')
+			if `modamax'==1 {
+			   local holes "holes(2)"
+			}
+			tempvar line1 line2 
+			qui gen `line1'=.
+			qui gen `line2'=.
+			label variable `line2' "Density"
+			label variable `line1' "Information"
+			qui graph twoway (line `line1' u ,lwidth(medthick) lcolo(red)) (line `line2' u ,lwidth(medthick) lcolo(green)) (line density u,yaxis(3) lwidth(medthick) lcolo(green) ) (bar eff u,  barwidth(.1) yaxis(1) xlabel(`floor'(1)`ceil') color(erose) )  (bar eff_md u,  barwidth(.05) yaxis(1) xlabel(`floor'(1)`ceil') color(stred) )  (line TInf u,yaxis(2) lwidth(medthick) lcolo(red) ) `scatterj'   , xline(0, lcolor(black)) legend(on position(3)     /*symysize(*.6) symxsize(*.6) textwidth(*.6)*/ /*cols(`nbcolslegende')*/ cols(1)  `holes' order(`"- "Functions" 2 1 - "" - "Patterns" 3 4 - "" - "Thresholds" `legend'  "') /*subtitle(Threshold parameters,size(*.7)) */size(small)) name(map,replace) ytitle("                           Frequencies")  ylabel(0(`=`maxi'/5')`maxi' `maxi'(`maxi')`=`maxi'*2' ,axis(2)) yscale(axis(2) off) yscale(axis(3) off)  ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) yline(0,lwidth(medium) lpattern(solid) lcolor(black))  ylabel(`ylbl',/*noticks*/ grid angle(0) axis(1)) ylabel(`ylbl' 0(`=`maxe'/5')`maxe', grid angle(0) axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("* : dysfunctioning items") xtitle("`xtitle'") `fsm' subtitle(`dimname')
+		}
+		else if "`eqset1'"!="" {
+			qui su eff
+	        local ceil=ceil(ceil(`r(max)'/10)*10)
+
+            qui tempfile equating
+			qui save `equating', replace
+		}
+	}
+	qui use `savefile', clear
+}
+		 
+
+
+/*************************************************************************************************************
+Best estimates by category 
+*************************************************************************************************************/
+
+tempname bestest
+matrix `bestest'=J(`nbitems',`=`modamax'+1',.)
+di
+local long=`modamax'*8+33
+di
+di "Best estimates by answer category" 
+di "{hline `long'}"
+di "Item" _col(29) "Cat 0"  _c
+forvalues j=1/`modamax' {
+     local col=29+`j'*8 
+	 di _col(`col') "Cat `j'"     _c
+}
+di
+di "{hline `long'}"
+forvalues i=1/`nbitems' {
+    di abbrev("`name``i'''",20) _c
+	forvalues j=0/`modamax`i'' {
+	    di _col(`=28+`j'*8') %6.3f round(`bestest``i''_`j'', 0.001) _c
+		matrix `bestest'[`i',`=`j'+1']=`bestest``i''_`j''
+	}
+	di
+}
+di "{hline `long'}"
+		
+
+
+/*************************************************************************************************************
+EQUATING
+*************************************************************************************************************/
+if "`eqset1'"!="" {
+    if "`eqgenscore'"!="" {
+	   local tmp1 `=ustrlen("`eqgenscore'`eqset1name'")'
+	   local tmp2 `=ustrlen("`eqgenscore'`eqset2name'")'
+	   local mlength=max(`tmp1',`tmp2')
+	   if `mlength'>27 {
+			di as error "The number of characters containing in the strings eqgenscore+eqset1name or eqgenscore+eqset2name must be lesser than 27"
+			di as error "eqgenscore+eqset1name : `tmp1' characters"
+			di as error "eqgenscore+eqset2name : `tmp2' characters"
+			error 130
+			*exit
+		}
+	}
+	if "`eqset1name'"=="" {
+	   local eqset1name="Set_1"
+	}
+	else if `c(version)'>17 {
+		local eqset1name `=regexreplaceall("`eqset1name'"," ","_",.)'
+	}
+	if "`eqset2name'"=="" {
+	   local eqset2name="Set_2"
+	}
+	else if `c(version)'>17 {
+		local eqset2name `=regexreplaceall("`eqset2name'"," ","_",.)'
+	}
+	*di "set1:`eqset1name' set2:`eqset2name'"  
+
+    tokenize `eqset1'
+	local nbset1: word count `eqset1'
+	forvalues i=1/`nbset1' {
+	   local eq1_`i':word `i' of `eqset1'
+	}
+    tokenize `eqset2'
+	local nbset2: word count  `eqset2'
+	forvalues i=1/`nbset2' {
+	   local eq2_`i':word `i' of `eqset2'
+	}	
+
+
+
+	tempfile fileeq
+	qui save `fileeq',replace
+	forvalues t=1/2{
+		local scoremaxset`t'=0
+		forvalues i=1/`nbset`t'' {
+			local scoremaxset`t'=`scoremaxset`t''+`modamax`eq`t'_`i'''
+		}
+	}
+	drop _all
+	qui set obs `=(`scoremaxset1'+`scoremaxset2'+2)*3'
+	forvalues t=1/2 {
+		qui gen scoreset`t'=.
+		qui gen scoreset`t'm=.
+		qui gen scoreset`t'p=.	
+	}
+	forvalues i=0/`scoremaxset1' {
+	    qui replace scoreset1=`i' in `=`i'+1'
+	    qui replace scoreset1m=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset1p=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	forvalues i=`=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2' {
+	    qui replace scoreset2=`i'-`scoremaxset1'-2 in `i'
+	    qui replace scoreset2m=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset2p=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	local s=0
+	local eqset1b
+	foreach i in `eqset1' {
+		qui gen s1_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s1_`i'_`m'=0 in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'_`m'=1 if scoreset1>`s' in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'=s1_`i'+s1_`i'_`m'
+		   local ++s
+		}
+	    local eqset1b `eqset1b' s1_`i'
+	}
+	local s=0
+	local eqset2b
+	foreach i in `eqset2' {
+		qui gen s2_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s2_`i'_`m'=0 in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'_`m'=1 if scoreset2>`s' in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'=s2_`i'+s2_`i'_`m'
+		   local ++s
+		}
+		local eqset2b `eqset2b' s2_`i'
+	}
+	tokenize `varlist'
+	tempname diffset1 diffset2
+	forvalues t=1/2 {
+		qui matrix `diffset`t''=J(`nbset`t'',`modamax',.)
+		local n=1
+		local listset`t'
+		foreach j in `eqset`t'' {
+			forvalues i=1/`nbitems' {
+				if "`j'"=="``i''" {
+					local listset`t' `listset`t'' `i'
+					forvalues m=1/`modamax' {
+						qui matrix `diffset`t''[`n',`m']=`diffmat'[`i',`m']
+					}
+					local ++n						
+				}
+			}
+		}
+	}
+	local var=`covariates'[1,1]
+	qui gen lt=.
+	forvalues t=1/2 {
+		tempname matscorelt`t'
+		qui pcm `eqset`t'b', diff(`diffset`t'') var(`var') minsize(1)
+		qui matrix `matscorelt`t''=r(matscorelt)
+		forvalues i=0/`scoremaxset`t'' {
+			qui replace lt=`matscorelt`t''[`=`i'+1',2] if scoreset`t'==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]+1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'p==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]-1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'm==`i'
+		}
+		qui ipolate scoreset`t' lt, gen(score`t') epolate
+	}
+	qui ipolate scoreset1 lt, gen(score1bis) epolate
+
+
+	forvalues t=1/2 {
+		qui replace score`t'=scoreset`t'm if scoreset`t'm!=.
+		qui replace score`t'=scoreset`t'p if scoreset`t'p!=.
+		qui replace score1=score1bis if score1==.
+		qui replace score`t'=0 if score`t'<0
+		qui replace score`t'=`scoremaxset`t'' if score`t'>`scoremaxset`t''
+	}
+	local pciset1
+	local pciset2
+	*set trace on
+	local minimini=0
+	local maximaxi=0
+	forvalues t=1/2 {
+        qui gen adjscore`t'=(score`t'+`eqaddset`t'')*`eqmultset`t''
+	    qui gen adjscore`=3-`t''=(score`=3-`t''+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''
+		tempname matscore`t'
+		qui matrix `matscore`t''=J(`=`scoremaxset`t''+1',7,.)
+		*set trace on
+		forvalues s=0/`scoremaxset`t'' {
+		    qui matrix `matscore`t''[`=`s'+1',1]=`s'
+			qui su lt if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',2]=r(mean)
+			if `ceil'==0 {
+				local ceil=1
+			}
+			if "`eqwithci'"=="" {
+				local pciset`t'  `pciset`t'' scatteri `=-`ceil'/5*`t'' `r(mean)' (12) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , mlabsize(tiny) mcolor(black) mlabcolor(black)||
+			}
+			local mean=r(mean)
+			qui su lt if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',3]=r(mean)
+			local moins=r(mean)
+			if `moins'<`minimini' {
+				*di "local minimini=floor(`moins')"
+				local minimini=floor(`moins')
+			}
+			qui su lt if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',4]=r(mean)
+			local plus=r(mean)
+			if `plus'>`maximaxi' {
+				*di "local maximaxi=ceil(`plus')"
+				local maximaxi=ceil(`plus')
+			}
+
+			if "`eqwithci'"!="" {
+				local y=-`ceil'/5*((2.5*`t'-2)+2*(`s'/`scoremaxset`t''))
+				*local pciset`t'  `pciset`t'' scatteri `y' `mean' (12) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , mlabsize(tiny) mcolor(black) mlabcolor(black)|| pci `y' `moins' `y' `plus',pstyle(p1) color(black)||
+				local pciset`t'  `pciset`t'' scatteri `y' `mean'  , mlabsize(tiny) mcolor(black) mlabcolor(black)|| scatteri `y' `moins' (9) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , msize(0) mlabsize(tiny) mcolor(black) mlabcolor(black)|| pci `y' `moins' `y' `plus',pstyle(p1) color(black)||
+			}
+			qui su score`=3-`t'' if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',5]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',6]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',7]=r(mean)
+		}
+		matrix colnames `matscore`t'' =score`t' lt lt- lt+ score`=3-`t'' score`=3-`t''- score`=3-`t''+
+		di as text
+		di as text "{hline 78}"
+		di as text "EQUATING `eqset`t'name' TO `eqset`=3-`t''name'"
+		di as text "{hline 78}"
+		di "`eqset`t'name' : `eqset`t''"
+		di "`eqset`=3-`t''name' : `eqset`=3-`t'''"
+		local eqset`t'namea=abbrev("`eqset`t'name'",18)
+		local eqset`=3-`t''namea=abbrev("`eqset`=3-`t''name'",12)
+		di "{hline 78}"
+		di "Score"           _col(20) "<----- Latent trait ----->" _col(52) "<- Score `eqset`=3-`t''namea'" _col(77) "->"
+		di "`eqset`t'namea'" _col(20) "Estimated" _col(39) "[95%IC]" _col(52) "Estimated" _col(72) "[95%IC]"
+		di "{hline 78}"
+		forvalues s=0/`scoremaxset`t'' {
+		    local min=min(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+		    local max=max(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+			
+			di %4.0f `=(`matscore`t''[`=`s'+1',1]+`eqaddset`t'')*`eqmultset`t''' _col(24) %5.2f `matscore`t''[`=`s'+1',2] _col(33) "[" %5.2f `matscore`t''[`=`s'+1',3] ";" %5.2f `matscore`t''[`=`s'+1',4] "]" _col(56) %5.2f `=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''' _col(66) "[" %5.2f `min' ";" %5.2f `max' "]"			
+		}
+		di "{hline 78}"
+		if "`eqgraph'"!="" {
+		    *set trace on
+			if `eqmultset`=3-`t'''>0 {
+				local xlabel 	"`=`eqaddset`=3-`t'''*`eqmultset`=3-`t''''(`=ceil((`scoremaxset`=3-`t'''*`eqmultset`=3-`t''')/20)')`=(`scoremaxset`=3-`t'''+`eqaddset`=3-`t''')*`eqmultset`=3-`t''''"
+			}
+			else {
+				local xlabel 	"`=(`scoremaxset`=3-`t'''+`eqaddset`=3-`t''')*`eqmultset`=3-`t''''(`=ceil((-`scoremaxset`=3-`t'''*`eqmultset`=3-`t''')/20)')`=`eqaddset`=3-`t'''*`eqmultset`=3-`t''''"
+			}
+			if `eqmultset`t''>0 {
+				local ylabel 	"`=`eqaddset`t''*`eqmultset`t'''(`=ceil((`scoremaxset`t''*`eqmultset`t'')/20)')`=(`scoremaxset`t''+`eqaddset`t'')*`eqmultset`t'''"
+			}
+			else {
+				local ylabel 	"`=(`scoremaxset`t''+`eqaddset`t'')*`eqmultset`t'''(`=ceil((-`scoremaxset`t''*`eqmultset`t'')/20)')`=`eqaddset`t''*`eqmultset`t'''"
+			}
+			*set trace off
+			*di "xlabel : `xlabel'"
+			*di "subtitle=`subtitle'"
+			twoway (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''!=.,lcolor(black) lpattern(solid) lwidth(thick)) (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''m!=.,lcolor(black) lpattern(dash) lwidth(thin)) (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''p!=.,lcolor(black) lpattern(dash) lwidth(thin)), title("Equating score of `eqset`=3-`t''name' to `eqset`t'name' ") ytitle("Score `eqset`t'name'") xtitle("Score `eqset`=3-`t''name'") ylabel(`ylabel') xlabel(`xlabel') name(eq`t'to`=3-`t'') legend(order(1 2) label(1 "Estimated") label(2 "95%IC") position(6)) subtitle("`dimname'") 
+		}
+		qui drop adjscore`t' adjscore`=3-`t''
+	}
+	
+	if "`eqgraph'"!="" {
+		qui use "`equating'",clear
+	    qui su u
+	    local flooru=floor(`r(min)')
+	    local ceilu=ceil(`r(max)')
+		qui su eff
+	    local ceil=ceil(ceil(`r(max)'/10)*10)
+		if `ceil'==0 {
+		   local ceil=1
+		}
+
+		local title "Equating"
+		if "`eqset1name'"!=""&"`eqset2name'"!=""{
+		   local title "Equating between `eqset1name' and `eqset2name'"
+		}
+		if "`eqwithci'"=="" {
+		   local ylabel1=-`ceil'/5
+		   local ylabel2=-2*`ceil'/5
+		   local gapu=ceil((`ceilu'-`flooru')/15)
+		}
+		else {
+		    local ylabel1=-0.5*`ceil'/5
+		    local ylabel2=-3*`ceil'/5
+		   	local flooru=min(`flooru',`minimini')
+			local ceilu=max(`ceilu',`maximaxi')
+			local gapu=ceil((`ceilu'-`flooru')/15)
+		}
+	    *di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`flooru'(1)`ceilu') color(erose)) || `pciset1' `pciset2'  , yline(0, lcolor(black)) legend(off) name(equating,replace) ytitle(                           Frequencies)    ylabel(`=-`ceil'/5*2' `eqset1name' `=-`ceil'/5' `eqset2name' 0(`=`ceil'/5')`ceil', grid angle(0) axis(1)) title(Equating) xsize(12) ysize(9)  xtitle(Latent trait) "
+	    qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`flooru'(`gapu')`ceilu') color(erose)) || `pciset1' `pciset2'  , yline(0, lcolor(black)) legend(off) name(equating,replace) ytitle("                           Frequencies")    /*ylabel(`ylbl', grid angle(0) axis(1))*/ ylabel(`ylabel1' "`eqset1name'" `ylabel2' "`eqset2name'" 0(`=`ceil'/5')`ceil', grid angle(0) axis(1)) title("`title'") subtitle("`dimname'") xsize(12) ysize(9)  xtitle("Latent trait") 
+	}
+	qui use `fileeq',clear
+	*set trace on
+	tempname scoreset1 scoreset2
+	forvalues t=1/2 {
+		qui genscore `eqset`t'' if `touse',score(`scoreset`t'')
+	 	qui su `scoreset`t'' if `touse'
+		local maxscoreset=r(max)
+		*qui matrix list `matscore`t''
+		if "`eqgenscore'"!="" {
+			local eqgenscore `=regexreplaceall("`eqgenscore'"," ","_")'
+			*di "eqgenscore : `eqgenscore'"
+			foreach k in mean min max random {
+				capture confirm  variable `eqgenscore'_`k'_`eqset`=3-`t''name'
+				if _rc==0&"`replace'"!="" {
+					qui replace `eqgenscore'_`k'_`eqset`=3-`t''name'=. if `touse'
+				}
+				else if _rc==0&"`replace'"!="" {
+					di as error "The variable `eqgenscore'_`k'_`eqset`=3-`t''name' already exists"
+					error 198
+				}
+				else {
+					qui gen `eqgenscore'_`k'_`eqset`=3-`t''name'=. if `touse'
+				}
+			}
+			*tab `scoreset`t''
+			forvalues s=0/`maxscoreset' {
+				*di "qui replace `eqgenscore'_`eqset`=3-`t''name'=`=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''' if `scoreset`t''==`s'"
+				local min=min(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+				local max=max(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
+				qui replace `eqgenscore'_mean_`eqset`=3-`t''name'=round(`=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_min_`eqset`=3-`t''name'=round(`min',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_max_`eqset`=3-`t''name'=round(`max',1) if round(`scoreset`t'',1)==`s'&`touse'
+				qui replace `eqgenscore'_random_`eqset`=3-`t''name'=round(uniform()*(`max'-`min')+`min',1) if round(`scoreset`t'',1)==`s'&`touse'
+			}
+		}
+		return matrix score`t'_to_`=3-`t''=`matscore`t''
+	}
+	
+}
+
+
+/*************************************************************************************************************
+RETOUR AU FICHIER INITIAL ET SAUVEGARDE DES NOUVELLES VARIABLES
+*************************************************************************************************************/
+*set trace on
+if "`visit'"!="" {
+	tempfile sauv
+	*set trace on
+	*tempname corrlatent corrbilatent
+	qui keep `latent'* `selatent'* `id' `visit' 
+    qui reshape wide , i(`id') j(`visit')
+	qui sort `id'	
+	qui save `sauv', replace
+	restore,preserve
+	if "`replace'"!=""&("`genlt'"!=""|"`geninf'"!="") {
+    	capture drop `genlt' 
+    	capture drop `genlt'_se 
+    	capture drop `geninf' 
+    	capture drop `genlt'_corr
+    	capture drop `genlt'_best
+    	*capture drop `genlt'_opt_se
+    }
+	*su
+	tempname idorder
+	qui gen `idorder'=_n 
+	qui sort `id'
+	qui merge 1:1 `id' using `sauv'
+	
+	qui sort `idorder'
+    qui drop `idorder'	
+}
+else {
+*set trace on
+*set tracedepth 1
+    if "`genlt'"!="" {
+		qui gen `genlt'_corr=`corrlatent' if `touse'
+/*		qui gen `genlt'_corr2=. if `touse'
+		forvalues s=0/`scoremax' {
+			qui replace `genlt'_corr2=`estlt`s'' if `score'==`s'&`touse'
+		}
+		forvalues g=1/`nbgroups' {
+			qui replace `genlt'_corr2=`clt`g'' if `group'==`g'&`genlt'_corr==.&`touse'
+		}
+*/
+		tempvar tmpitem mean nbnonmiss
+		forvalues i=1/`nbitems' {
+			qui gen `tmpitem'_`i'=. if `touse'
+			forvalues k=0/`modamax' {
+				qui replace `tmpitem'_`i'=`bestest'[`i',`=`k'+1'] if ``i''==`k'&`touse'
+			}
+		}
+		*su
+		qui egen `genlt'_best=rowmean(`tmpitem'_*) if `touse'
+		*qui egen `genlt'_opt_se=rowsd(`tmpitem'_*) if `touse'
+		qui egen `nbnonmiss'=rownonmiss(`tmpitem'_*) if `touse'
+		*qui replace `genlt'_opt_se=sqrt((`genlt'_opt_se^2+`resvar')/`nbnonmiss') if `touse'
+ 	}
+	restore,not
+}
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin, footer(fall_report)
+	putdocx table hdr = (1, 3), border(all, nil) tofooter(fall_report)
+	if "`rsm'"=="" {
+		putdocx table hdr(1, 1) = ("Partial Credit Model")
+	}
+	else {
+		putdocx table hdr(1, 1) = ("Rating Scale Model")
+	}
+	putdocx table hdr(1, 2) = ("`dimname'"), halign(center)
+	putdocx table hdr(1, 3) = ("Page "), pagenumber
+	putdocx table hdr(1, 3) = ("/"), totalpages append
+	putdocx table hdr(1, 3), halign(right)
+	putdocx paragraph ,style(Title)
+	if "`dimname'" =="" {
+	    local dimname2 "Rasch analysis"
+	}
+	else {
+	    local dimname2 "Rasch analysis of the `dimname' dimension"
+	}
+	putdocx text ("`dimname2'") ,
+	putdocx paragraph ,style(Subtitle)
+	putdocx text ("General informations") ,
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("Names of the dimension: `dimname'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph, style(Subtitle)
+	putdocx text ("Estimation of the parameters") , 
+	local paramname
+	forvalues j=1/`nbitems' {
+		forvalues k=1/`modamax' {
+		     if `k'<=`modamax`j'' {
+			     local paramname `paramname' "``j''_`k'"
+			 }
+	    }
+	}
+	*di "matrix colnames `diff'=`paramname'"
+	matrix rownames `diff'=`paramname'
+    putdocx table table1 = matrix(`diff') , nformat(%9.3f) rownames colnames  border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil) headerrow(1)  halign(center)
+    putdocx table table1(.,1), halign(left) 
+    putdocx table table1(.,2/7), halign(right) 
+    putdocx table table1(1,.), halign(right) border(top) border(bottom)
+	
+	
+	qui putdocx table table2 = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)  headerrow(1)
+    putdocx table table2(.,1), halign(left) 
+    putdocx table table2(.,2/7), halign(right) 
+    putdocx table table2(1,.), halign(right) border(top) border(bottom)
+
+
+
+	
+	putdocx paragraph,style(Subtitle)
+	putdocx text ("Fit indexes for items") , /*bold underline font(,14) smallcaps*/
+	qui putdocx table table3 = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)    headerrow(1)
+    putdocx table table3(.,1), halign(left) 
+    putdocx table table3(.,2/5), halign(right) 
+    putdocx table table3(1,.), halign(right) border(top) border(bottom)
+
+
+
+	putdocx paragraph, style(Subtitle)
+	putdocx text ("Estimation per group/score")
+	*putdocx text ("Estimation per group/score") , bold underline font(,14) smallcaps
+	*set trace on
+	putdocx table tbl = (`=`nbrowmat'+1',7), border(all,nil) width(7) halign(center) note(EAP: Expected A Posteriori ; BE: Best Estimates) headerrow(1)
+    putdocx table tbl(1,.), halign(right) border(top) border(bottom)
+	putdocx table tbl(1,1) = ("Group"), halign(right) 
+	putdocx table tbl(1,2) = ("score"), halign(right) 
+	putdocx table tbl(1,3) = ("Frequency"), halign(right) 
+	putdocx table tbl(1,4) = ("EAP Mean"), halign(right) 
+	putdocx table tbl(1,5) = ("EAP s.e."), halign(right) 
+	putdocx table tbl(1,6) = ("Exp score"), halign(right) 
+	putdocx table tbl(1,7) = ("BE Mean"), halign(right) 
+	local fin=1
+	forvalues row=1/`nbrowmat' {
+	    local row2=`row'+1
+		local g: di %9.0f `matgroupscorelt'[`row',1]
+		local gh=`matgroupscorelt'[`row',1]
+		if `fin'==1 {
+			putdocx table tbl(`row2',1) = ("`g'"), halign(right) 
+		}
+		if `matgroupscorelt'[`row',2]!=.|`matgroupscorelt'[`row',7]==. {
+		    local s: di %9.0f `matgroupscorelt'[`row',2]
+			local fin=0
+		}
+		else {
+			local s "`scoremin`gh''/`scoremax`gh''"
+			local fin=1
+			*local fin "border(top) border(bottom)"
+			*di "c'est la fin"
+			putdocx table tbl(`row2',.),  border(bottom) border(top, dashed)
+			putdocx table tbl(`row2',1), border(top, nil)
+		}
+		local eff: di %9.0f `matgroupscorelt'[`row',3]
+		local lt: di %9.3f `matgroupscorelt'[`row',4]
+		local se: di %9.3f `matgroupscorelt'[`row',5]
+		local exp: di %9.2f `matgroupscorelt'[`row',6]
+		local clt: di %9.3f `matgroupscorelt'[`row',7]
+		*putdocx table tbl(`row',.), addrows(7)
+		putdocx table tbl(`row2',2) = ("`s'"), halign(right) 
+		putdocx table tbl(`row2',3) = ("`eff'"), halign(right) 
+		putdocx table tbl(`row2',4) = ("`lt'"), halign(right) 
+		putdocx table tbl(`row2',5) = ("`se'"), halign(right) 
+		putdocx table tbl(`row2',6) = ("`exp'"), halign(right) 
+		putdocx table tbl(`row2',7) = ("`clt'"), halign(right) 
+
+	}
+
+/*
+		qui matrix `matgroupscorelt'[`row',1]=`g'
+		*qui matrix `matgroupscorelt'[`row',2]="`scoremin`g''/`scoremax`g''"
+		qui matrix `matgroupscorelt'[`row',3]=`eff`g''
+		qui matrix `matgroupscorelt'[`row',4]=`lt`g''
+		qui matrix `matgroupscorelt'[`row',5]=`se'
+		*qui matrix `matgroupscorelt'[`row',6]=`exp'
+		qui matrix `matgroupscorelt'[`row',7]=`clt`g''
+		local ++row
+	}
+	local nbrowmat=`row'-1
+
+
+local row 1
+local vari 1
+foreach x in gear_ratio turn foreign _cons {
+putdocx table tbl5(`row',.), addrows(2)
+local b: display %9.3f rtable[`vari',1]
+local se: display %9.3f rtable[`vari',2]
+local ++vari
+local ++row
+putdocx table tbl5(`row',1) = ("`x'"), halign(right)
+putdocx table tbl5(`row',2) = ("`b'"), halign(right)
+local ++row
+local se = strtrim("`se'")
+putdocx table tbl5(`row',2) = ("(`se')"), halign(right)
+}*/
+	
+	*qui putdocx table tablename = matrix(`matgroupscorelt') , nformat(%9.3f) /*rownames*/ colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+				putdocx paragraph, style(Subtitle)
+				putdocx text ("General Graphs")
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			putdocx paragraph, style(Subtitle)
+			putdocx text ("Graphs per item")
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+					putdocx paragraph, style(Heading1)
+				    putdocx text ("Graphs for ``i''") 
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+*set trace on
+
+matrix colnames `diff'="Estimate" "Std err" "z" "p" "lb" "ul"
+matrix colnames `covariates'=Estimate s.e. z p lb ul
+matrix rownames `diff'=`diffname'
+*matrix list `diff'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+return matrix matscorelt=`matscorelt'
+return matrix matgroupscorelt=`matgroupscorelt'
+return matrix bestest=`bestest'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm.sthlp b/Modules/ado/personal/p/pcm.sthlp
new file mode 100644
index 0000000..dd7e2e5
--- /dev/null
+++ b/Modules/ado/personal/p/pcm.sthlp
@@ -0,0 +1,167 @@
+{smcl}
+{* 2August2022}{...}
+{hline}
+help for {hi:pcm}{right:Jean-Benoit Hardouin, Myriam Blanchin}
+{hline}
+
+{title:Estimation of the parameters of a Partial Credit Model (PCM) or a Rating Scale Model (RSM) and specific graphs}
+
+{title:Syntax for Rasch analysis}
+
+{p 8 14 2}{cmd:pcm} {it:varlist} [{it:if}] [{it:in}]
+[, {cmdab:rsm} {cmdab:it:erate}({it:#})   {cmdab:model}  {cmdab:diff:iculties}({it:matrix}) {cmdab:var:iance}({it:real}) {cmdab:minsize}({it:#})
+{cmdab:cont:inuous}({it:varlist}) {cmdab:cat:egorical}({ir:varlist})  
+{cmdab:G:raphs} {cmdab:nographi:tems} {cmdab:dim:name}({it:string}) {cmdab:nocorr:ected} {cmdab:alpha}({it:#})
+{cmdab:filesave} {cmdab:extension}({it:string}) {cmdab:dirsave}({it:directory} {cmdab:docx}({it:string}) 
+{cmdab:genlt}({it:string}) {cmdab:geninf}({it:string}) {cmdab:rep:lace}
+
+{title:Syntax for Rasch equating}
+{p 8 14 2}{cmd:pcm} {it:varlist} [{it:if}] [{it:in}] [, {cmdab:rsm} {cmdab:it:erate}({it:#})   {cmdab:model}  {cmdab:diff:iculties}({it:matrix}) {cmdab:var:iance}({it:real}) {cmdab:minsize}({it:#}) {cmdab:G:raphs}  {cmdab:dim:name}({it:string}) {cmdab:eqset1}({it:varlist}) {cmdab:eqset2}({it:varlist}) {cmdab:eqset1name}({it:string}) {cmdab:eqset2name}({it:string}) {cmdab:EQG:raph} {cmdab:eqaddset1}({it:#}) {cmdab:eqaddset2}({it:#}) {cmdab:eqmultset1}({it:#) {cmdab:eqmultset2}({it:#}) 
+{cmdab:eqwithci} {cmdab:eqgenscore}({it:string})  {cmdab:rep:lace}  ]
+
+
+{p 8 14 2}{it:varlist} is a list of two existing categorical variables or more.
+
+{title:Description}
+
+{p 4 8 2}{cmd:pcm} estimates the parameters of a Partial Credit Model (PCM) or of a Rating Scale Model (RSM).  Parameters are estimated using Marginal Maximum Likelihood (MML). Several graphical representations can be easily obtained: comparison of the observed and theorical Item Characteristic Curves (ICC), Map difficulty parameters/Scores, results of the split tests, and information function (for the scale and by item). {cmd:pcm} allow equating two sets of items.
+
+{title:Options for a Rasch analysis}
+
+{p 4 8 2}{cmdab:rsm} estimates a Rating Scale Model instead of a Partial Credit Model.
+
+{p 4 8 2}{cmdab:it:erate} defines the maximal number of iterations of the maximisation algorithm.
+By default, this number is fixed to 100.
+
+{p 4 8 2}{cmd:model} displays the outputs of the maximisation alogorithm .
+
+{p 4 8 2}{cmdab:diff:iculties}({it:matrix}) fixes the values of the difficulties parameters of the items (by default, these values are estimated).
+The vector must be a matrix containing as many rows as items, and a column for each threshold parameter (number of answer categories minus 1). 
+A missing value (.) replaces unexisting difficulty paremeters in the matrix.
+
+{p 4 8 2}{cmdab:var:iance}({it:#}) fixes the value of the variance of the latent trait (by default, this value is estimated).
+
+{p 4 8 2}{cmdab:minsize}({it:#}) fixes the minimal value of the groups (30 individuals by default).
+
+{p 4 8 2}{cmdab:cont:inuous}({it:varlist}) defines a list of continuous variables explaining the latent trait.
+
+{p 4 8 2}{cmdab:cat:egorical}({it:varlist}) defines a list of categorical variables explaining the latent trait.
+
+{p 4 8 2}{cmdab:G:raphs} displays the graphs.
+
+{p 4 8 2}{cmdab:nographi:tems} avoids displaying the graphs by items.
+
+{p 4 8 2}{cmdab:dim:name}({it:string}) defines the name of the analysed dimension (this name appears on the graphs).
+
+{p 4 8 2}{cmdab:nocorr:ected} avoids using corrected latent trait estimates on the graphs.
+
+{p 4 8 2}{cmdab:alpha}({it:#}) defines the level of confidence of the interval presented on the graphs of residuals.
+
+{p 4 8 2}{cmdab:filesave} save the graph files.
+
+{p 4 8 2}{cmdab:extension}({it:string}) defines the extension of the graph files.
+
+{p 4 8 2}{cmdab:dirsave}({it:directory}  defines the directory to save the graph files and the docx file.
+
+{p 4 8 2}{cmdab:docx}({it:string}) creates a docx file with the main results and graphs.
+
+{p 4 8 2}{cmdab:genlt}({it:string}) creates several variables. The new variables {it:string} contains Expected A Posteriori estimates of the latent trait and {it:string_se} their standard deviations. The new variable {it:string_corr} contains estimates of the latent traits allowing obtaining the closer estimations of the item-sum scores. The new variables {it:string_opt} contains estimated of the latent traits obtained by searching, for each observed item to maximize the probability to obtain the observed answer (the obtained value is the mean of all these estimates).
+
+{p 4 8 2}{cmd:geninf}({it:string}) contains the information associated for each individual.
+
+{p 4 8 2}{cmdab:rep:lace} specifies that the existing  files or  variables will be replaced.
+
+{title:Options for a Rasch equating}
+
+
+{p 4 8 2}{cmdab:rsm} estimates a Rating Scale Model instead of a Partial Credit Model.
+
+{p 4 8 2}{cmdab:it:erate} defines the maximal number of iterations of the maximisation algorithm.
+By default, this number is fixed to 100.
+
+{p 4 8 2}{cmd:model} displays the outputs of the maximisation alogorithm .
+
+{p 4 8 2}{cmdab:diff:iculties}({it:matrix}) fixes the values of the difficulties parameters of the items (by default, these values are estimated).
+The vector must be a matrix containing as many rows as items, and a column for each threshold parameter (number of answer categories minus 1). 
+A missing value (.) replaces unexisting difficulty paremeters in the matrix.
+
+{p 4 8 2}{cmdab:var:iance}({it:#}) fixes the value of the variance of the latent trait (by default, this value is estimated).
+
+{p 4 8 2}{cmdab:minsize}({it:#}) fixes the minimal value of the groups (30 individuals by default).
+
+{p 4 8 2}{cmdab:G:raphs} displays the graphs.
+
+{p 4 8 2}{cmdab:dim:name}({it:string}) defines the name of the analysed dimension (this name appears on the graphs).
+
+{p 4 8 2}{cmdab:eqset1}({it:varlist}) and {cmdab:eqset2}({it:varlist}) define the items containing in the two sets of items to equate (disjoint or not sets of items)
+
+{p 4 8 2}{cmdab:eqset1name}({it:string}) and {cmdab:eqset2name}({it:string}) define the names of the two sets of items (set1 and set2 by default). The string cannot contains spaces if the version of Stata is 17 or less.
+
+{p 4 8 2}{cmdab:EQG:raph} displays graphs  
+
+{p 4 8 2}{cmdab:eqaddset1}({it:#}) and {cmdab:eqaddset2}({it:#}) allows adding a real to the row score to obtain a linear transformed score for each set of items (0 by default)
+
+{p 4 8 2}{cmdab:eqmultset1}({it:#) and {cmdab:eqmultset2}({it:#}) allows multiplying the row score by a real to obtain a linear transformed score for each set of items (1 by default)
+
+{p 4 8 2}{cmdab:eqwithci} allows representing the 95% confidence interval of the equated score on the graph
+
+{p 4 8 2}{cmdab:eqgenscore}({it:string}) create several variables containing the center (_mean_), the minimal (_min_) and the maximal (_max_) values of the 95% confidence interval and a random value (_random_) drawn in this interval
+
+{p 4 8 2}{cmdab:rep:lace} specifies that the existing  files or  variables will be replaced.
+
+
+{title:Outputs}
+
+{p 4 8 2}{cmd:e()}: Output of the gsem procedure
+
+{p 4 8 2}{cmd:r(ll)}: Marginal Log-likelihood
+
+{p 4 8 2}{cmd:r(PSI)}: Personal Separation Index
+
+{p 4 8 2}{cmd:r(difficulties)}: Estimates of the threshold parameters
+
+{p 4 8 2}{cmd:r(matscorelt)} : estimates of the latent trait associated to each complete item-sum score 
+
+{p 4 8 2}{cmd:r(matgroupscorelt)} : estimates of the latent trait associated to each complete item-sum score and to each group of individuals used for graphical fit tests 
+
+{p 4 8 2}{cmd:r(covariates)} : estimates of the variance of the latent trait and of the parameters associates to covariates
+
+{p 4 8 2}{cmd:r(bestest)}: estimates of the latent trait obtained for each item by searching the value maximizing the response to each answer category
+
+{p 4 8 2}{cmd:r(score2_to_1)} : gives the results to equate the raw scores of the set2 to set1
+
+{p 4 8 2}{cmd:r(score1_to_2)}: gives the results to equate the raw scores of the set1 to set2
+
+
+
+{title:Examples of Rasch analysis}
+
+{p 4 8 2}{cmd: . pcm item1-item9} 
+
+{p 4 8 2}{cmd: . pcm item*, graph dirsave(c:\graphs) filesave genlt(lt) docx(report)}
+
+{p 4 8 2}{cmd: . matrix diff=(-1,-0.8,0.2\-.5,0,0.5\0,1,.\0.2,1,1.2\0.5,.,.)}{p_end}
+{p 4 8 2}{cmd: . pcm item1-item5 , diff(diff) cat(sex) cont(age) }
+
+{title:Example of Rasch equating}
+
+{p 4 8 2}{cmd: . pcm item1-item9, eqset1(item1-item5) eqset2(item6-item9) eqnameset1(First part) eqnameset2(Second part) eqaddset1(5) eqmultset1(-1) graph} 
+
+
+{title:Author}
+
+{p 4 8 2}Jean-Benoit Hardouin, PhD-HDR, Associate professor - Hospital Practitioner{p_end}
+{p 4 8 2}Myriam Blanchin, PhD, Research engineer{p_end}
+{p 4 8 2}INSERM UMR 1246-SPHERE "Methods in Patients Centered Outcomes and Health Research"{p_end}
+{p 4 8 2}Nantes University - Faculty of Medicine{p_end}
+{p 4 8 2}Intitute of Research in Health 2{p_end}
+{p 4 8 2}22 boulevard BĂ©noni-Goullin{p_end}
+{p 4 8 2}44200 Nantes - FRANCE{p_end}
+{p 4 8 2}Email:
+{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}, {browse "mailto:myriam.blanchin@univ-nantes.fr":myriam.blanchin@univ-nantes.fr}{p_end}
+
+
+{title:Also see}
+
+{p 4 13 2}Online: help for {help raschtest} and {help gsem}  if installed.{p_end}
+
diff --git a/Modules/ado/personal/p/pcm.zip b/Modules/ado/personal/p/pcm.zip
new file mode 100644
index 0000000..b0bba31
Binary files /dev/null and b/Modules/ado/personal/p/pcm.zip differ
diff --git a/Modules/ado/personal/p/pcm21.ado b/Modules/ado/personal/p/pcm21.ado
new file mode 100644
index 0000000..8e0ef5c
--- /dev/null
+++ b/Modules/ado/personal/p/pcm21.ado
@@ -0,0 +1,244 @@
+*! Version 2.1 18october2011
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007
+* Version 2 : July 15, 2011
+* Version 2.1 : October 18th, 2011 : -fixedvar- option, new presentation
+*
+* Jean-benoit Hardouin, EA4275 Biostatistics, Clinical Research and Subjective Measures in Health Sciences
+* Faculties of Pharmaceutical Sciences & Medicine - University of Nantes - France
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2007, 2011 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm,eclass
+version 8.0
+syntax varlist(min=3 numeric) [if] [in] [,rsm fixed(string) fixedvar(real -1) fixedmu short COVariates(varname)]
+preserve
+tempfile pcmfile
+qui save `pcmfile',replace
+
+if "`fixedmu'"!=""&`fixedvar'!=-1&"`covariates'"=="" {
+   di in red "You cannot fix in the same time the mean (fixedmu option) and the variance (fixedvar option) of the latent trait without covariables"
+   error 184
+}
+if "`fixed'"!=""&"`fixedmu'"==""&`fixedvar'!=-1&"`covariates'"=="" {
+   di in red "You cannot fix in the same time the difficulties (fixed option) and the variance (fixedvar option) of the latent trait without covariables"
+   error 184
+}
+
+/*******************************************************************************
+ESTIMATION OF THE PARAMETERS
+********************************************************************************/
+
+marksample touse
+qui keep if `touse'
+qui count
+local N=r(N)
+tokenize `varlist'
+local nbitems : word count `varlist'
+
+if "`rsm'"=="" {
+   di in gr "Model: " in ye "Partial Credit Model"
+}
+else {
+   di in gr "Model: " in ye "Rating Scale Model"
+}
+
+tempname one var w id item it obs x chosen d score
+qui gen `one'=1
+qui gen `id'=_n
+local modamax=0
+forvalues i=1/`nbitems' {
+   qui rename ``i'' `var'`i'
+   qui su `var'`i'
+   local moda`i'=`r(max)'
+   if `modamax'<`r(max)' {
+      local modamax=r(max)
+   }
+}
+qui genscore `var'1-`var'`nbitems' ,score(`score')
+qui collapse (sum) `w'=`one',by(`var'1-`var'`nbitems' `covariates')
+qui gen `id'=_n
+qui reshape long `var',i(`id') j(`item')
+qui drop if `var'==.
+qui gen `obs'=_n
+qui expand `=`modamax'+1'
+qui sort `id' `item' `obs'
+by `obs', sort: gen `x'=_n-1
+
+qui gen `chosen'=`var'==`x'
+qui tab `item', gen(`it')
+forvalues i=1/`nbitems' {
+   forvalues g=1/`modamax' {
+      qui gen `d'`i'_`g'=-1*`it'`i'*(`x'>=`g')
+   }
+}
+qui rename `w' `w'2
+bysort `id':egen score=sum(`x'*`chosen')
+qui su score
+local maxscore=r(max)
+
+
+if "`covariates'"!="" {
+   qui gen covw=`covariates'*`x'
+   local listcov covw
+}
+else {
+   local listcov
+}
+if `fixedvar'!=-1 {
+   local tmp=sqrt(`fixedvar')
+   constraint 1 `x'=`tmp'
+   local listconstr "constraints(1)"
+}
+if "`rsm'"=="" {
+   if "`fixed'"!="" {
+      qui gen offset=0
+      local l=1
+      forvalues i=1/`nbitems' {
+         forvalues mi=1/`moda`i'' {
+            qui replace offset=offset+`fixed'[1,`l']*`d'`i'_`mi'
+            local ++l
+         }
+      }
+      if "`fixedmu'"!="" {
+         local mu
+      }
+      else {
+         local mu "`x'"
+      }
+
+      eq slope:`x'
+      noi di "gllamm `x' `listcov' `mu',offset(offset) `listconstr' nocons i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace"
+      gllamm `x' `listcov' `mu',offset(offset) `listconstr' nocons i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace 
+   }
+   else if "`short'"!="" {
+      eq slope:`x'
+      qui gllamm `x' `d'1_1-`d'`nbitems'_`modamax',i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons init
+      tempname bsave Vsave
+      matrix `bsave'=e(b)
+      matrix `Vsave'=e(V)
+      restore
+      qui pcm `varlist' , fixed(`bsave')
+   }
+   else {
+      di "no short"
+      eq slope:`x'
+      qui gen i=`id'
+      constraint 1 `x'=1
+      gllamm `x' `d'1_1-`d'`nbitems'_`modamax' `listcov',i(i) `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons
+   }
+}
+else {
+   tempname step n
+   forvalues i=2/`modamax' {
+      qui gen `step'`i'=-1*(`x'>=`i')
+   }
+   forvalues i=1/`nbitems' {
+      qui gen `n'`var'`i'=(-1)*(`it'`i')*(`x')
+   }
+   qui sort `id' `item' `x'
+   eq slope:`x'
+   gllamm `x' `n'`var'1-`n'`var'`nbitems' `step'2-`step'`modamax' `listcov', i(`id') `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons
+}
+
+tempname b V chol
+matrix b=e(b)
+matrix V=e(V)
+local ll=e(ll)
+matrix chol=e(chol)
+
+
+if "`rsm'"=="" {
+   di
+   di in gr "Number of observations: " in ye `N'
+   di in gr "Number of items: " in ye `nbitems'
+   di in gr "Number of parameters: " in  ye `=`nbitems'*`modamax'+1'
+   di in gr "Log-likelihood: " in ye `ll'
+   di
+   di
+   di in gr "{hline 100}"
+   di in gr "Item" _col(10) "Modality" _col(20) "Parameter" _col(30) "Std Error"
+   di in gr "{hline 100}"
+   if "`fixed'"=="" {
+      forvalues i=1/`nbitems' {
+         forvalues j=1/`modamax' {
+            if `j'==1 {
+               di in ye "``i''" _cont
+            }
+            local k=(`i'-1)*`modamax'+`j'
+            if "`short'"!="" {
+               di in ye _col(17) `j' _col(20) %9.6f `bsave'[1,`k'] in ye _col(30) %9.6f (`Vsave'[`k',`k'])^.5
+            }
+            else {
+               di in ye _col(17) `j' _col(20) %9.6f b[1,`k'] in ye _col(30) %9.6f (V[`k',`k'])^.5
+            }
+         }
+         di in gr "{dup 100:-}"
+      }
+   }
+   else {
+      forvalues i=1/`nbitems' {
+         forvalues j=1/`modamax' {
+            if `j'==1 {
+               di in ye "``i''" _cont
+            }
+            local k=(`i'-1)*`modamax'+`j'
+            di in ye _col(17) `j' _col(20) %9.6f `fixed'[1,`k'] in ye _col(32) "(fixed)"
+         }
+         di in gr "{dup 100:-}"
+      }
+   }
+   if "`fixed'"==""&"`short'"=="" {
+      local k=`nbitems'*`modamax'+1
+   }
+   else if "`fixed'"!=""&"`fixedmu'"=="" {
+      di in ye "Mu" in ye _col(20) %9.6f b[1,1] _col(29) %10.6f  (V[1,1])^.5
+      local k=2
+   }
+   else if "`fixed'"!=""&"`fixedmu'"!="" {
+      di in ye "Mu" in ye _col(20) %9.6f 0 _col(32) %10.6f  "(fixed)"
+      local k=1
+   }
+   else {
+      local k=1
+   }
+   if "`covariates'"!="" {
+      di in ye "`covariates'" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f  (V[`k',`k'])^.5
+      local k=`k'+1
+   }
+   if `fixedvar'==-1 {
+      di in ye "Sigma" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f  (V[`k',`k'])^.5
+      di in ye "Variance" in ye _col(20) %9.6f b[1,`k']^2  _col(29) %10.6f  2*(V[`k',`k'])^.5*b[1,`k']
+   }
+   else {
+      di in ye "Sigma" in ye _col(20) %9.6f `fixedvar'^.5 _col(32) %10.6f  "(fixed)"
+      di in ye "Variance" in ye _col(20) %9.6f `fixedvar'  _col(32) %10.6f  "(fixed)"
+   }
+   di in gr "{hline 100}"
+   di
+   di
+}
+
+end
diff --git a/Modules/ado/personal/p/pcm22.ado b/Modules/ado/personal/p/pcm22.ado
new file mode 100644
index 0000000..3320946
--- /dev/null
+++ b/Modules/ado/personal/p/pcm22.ado
@@ -0,0 +1,245 @@
+*! Version 2.2 23october2013
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007
+* Version 2 : July 15, 2011
+* Version 2.1 : October 18th, 2011 : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 : correction of -fixedvar- option
+*
+* Jean-benoit Hardouin, EA4275 Biostatistics, Clinical Research and Subjective Measures in Health Sciences
+* Faculties of Pharmaceutical Sciences & Medicine - University of Nantes - France
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2007, 2011 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm,eclass
+version 8.0
+syntax varlist(min=3 numeric) [if] [in] [,rsm fixed(string) fixedvar(real -1) fixedmu short COVariates(varname)]
+preserve
+tempfile pcmfile
+qui save `pcmfile',replace
+
+if "`fixedmu'"!=""&`fixedvar'!=-1&"`covariates'"=="" {
+   di in red "You cannot fix in the same time the mean (fixedmu option) and the variance (fixedvar option) of the latent trait without covariables"
+   error 184
+}
+if "`fixed'"!=""&"`fixedmu'"==""&`fixedvar'!=-1&"`covariates'"=="" {
+   di in red "You cannot fix in the same time the difficulties (fixed option) and the variance (fixedvar option) of the latent trait without covariables"
+   error 184
+}
+
+/*******************************************************************************
+ESTIMATION OF THE PARAMETERS
+********************************************************************************/
+
+marksample touse
+qui keep if `touse'
+qui count
+local N=r(N)
+tokenize `varlist'
+local nbitems : word count `varlist'
+
+if "`rsm'"=="" {
+   di in gr "Model: " in ye "Partial Credit Model"
+}
+else {
+   di in gr "Model: " in ye "Rating Scale Model"
+}
+
+tempname one var w id item it obs x chosen d score
+qui gen `one'=1
+qui gen `id'=_n
+local modamax=0
+forvalues i=1/`nbitems' {
+   qui rename ``i'' `var'`i'
+   qui su `var'`i'
+   local moda`i'=`r(max)'
+   if `modamax'<`r(max)' {
+      local modamax=r(max)
+   }
+}
+qui genscore `var'1-`var'`nbitems' ,score(`score')
+qui collapse (sum) `w'=`one',by(`var'1-`var'`nbitems' `covariates')
+qui gen `id'=_n
+qui reshape long `var',i(`id') j(`item')
+qui drop if `var'==.
+qui gen `obs'=_n
+qui expand `=`modamax'+1'
+qui sort `id' `item' `obs'
+by `obs', sort: gen `x'=_n-1
+
+qui gen `chosen'=`var'==`x'
+qui tab `item', gen(`it')
+forvalues i=1/`nbitems' {
+   forvalues g=1/`modamax' {
+      qui gen `d'`i'_`g'=-1*`it'`i'*(`x'>=`g')
+   }
+}
+qui rename `w' `w'2
+bysort `id':egen score=sum(`x'*`chosen')
+qui su score
+local maxscore=r(max)
+
+
+if "`covariates'"!="" {
+   qui gen covw=`covariates'*`x'
+   local listcov covw
+}
+else {
+   local listcov
+}
+if `fixedvar'!=-1 {
+   local tmp=sqrt(`fixedvar')
+   constraint 1 `x'=`tmp'
+   local listconstr "constraints(1)"
+}
+if "`rsm'"=="" {
+   if "`fixed'"!="" {
+      qui gen offset=0
+      local l=1
+      forvalues i=1/`nbitems' {
+         forvalues mi=1/`moda`i'' {
+            qui replace offset=offset+`fixed'[1,`l']*`d'`i'_`mi'
+            local ++l
+         }
+      }
+      if "`fixedmu'"!="" {
+         local mu
+      }
+      else {
+         local mu "`x'"
+      }
+
+      eq slope:`x'
+      noi di "gllamm `x' `listcov' `mu',offset(offset) `listconstr' nocons i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace"
+      gllamm `x' `listcov' `mu',offset(offset) `listconstr' nocons i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace 
+   }
+   else if "`short'"!="" {
+      eq slope:`x'
+      qui gllamm `x' `d'1_1-`d'`nbitems'_`modamax',i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons init
+      tempname bsave Vsave
+      matrix `bsave'=e(b)
+      matrix `Vsave'=e(V)
+      restore
+      qui pcm `varlist' , fixed(`bsave')
+   }
+   else {
+      di "no short"
+      eq slope:`x'
+      qui gen i=`id'
+      constraint 1 `x'=1
+      gllamm `x' `d'1_1-`d'`nbitems'_`modamax' `listcov',i(i) `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons
+   }
+}
+else {
+   tempname step n
+   forvalues i=2/`modamax' {
+      qui gen `step'`i'=-1*(`x'>=`i')
+   }
+   forvalues i=1/`nbitems' {
+      qui gen `n'`var'`i'=(-1)*(`it'`i')*(`x')
+   }
+   qui sort `id' `item' `x'
+   eq slope:`x'
+   gllamm `x' `n'`var'1-`n'`var'`nbitems' `step'2-`step'`modamax' `listcov', i(`id') `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons
+}
+
+tempname b V chol
+matrix b=e(b)
+matrix V=e(V)
+local ll=e(ll)
+matrix chol=e(chol)
+
+
+if "`rsm'"=="" {
+   di
+   di in gr "Number of observations: " in ye `N'
+   di in gr "Number of items: " in ye `nbitems'
+   di in gr "Number of parameters: " in  ye `=`nbitems'*`modamax'+1'
+   di in gr "Log-likelihood: " in ye `ll'
+   di
+   di
+   di in gr "{hline 100}"
+   di in gr "Item" _col(10) "Modality" _col(20) "Parameter" _col(30) "Std Error"
+   di in gr "{hline 100}"
+   if "`fixed'"=="" {
+      forvalues i=1/`nbitems' {
+         forvalues j=1/`modamax' {
+            if `j'==1 {
+               di in ye "``i''" _cont
+            }
+            local k=(`i'-1)*`modamax'+`j'
+            if "`short'"!="" {
+               di in ye _col(17) `j' _col(20) %9.6f `bsave'[1,`k'] in ye _col(30) %9.6f (`Vsave'[`k',`k'])^.5
+            }
+            else {
+               di in ye _col(17) `j' _col(20) %9.6f b[1,`k'] in ye _col(30) %9.6f (V[`k',`k'])^.5
+            }
+         }
+         di in gr "{dup 100:-}"
+      }
+   }
+   else {
+      forvalues i=1/`nbitems' {
+         forvalues j=1/`modamax' {
+            if `j'==1 {
+               di in ye "``i''" _cont
+            }
+            local k=(`i'-1)*`modamax'+`j'
+            di in ye _col(17) `j' _col(20) %9.6f `fixed'[1,`k'] in ye _col(32) "(fixed)"
+         }
+         di in gr "{dup 100:-}"
+      }
+   }
+   if "`fixed'"==""&"`short'"=="" {
+      local k=`nbitems'*`modamax'+1
+   }
+   else if "`fixed'"!=""&"`fixedmu'"=="" {
+      di in ye "Mu" in ye _col(20) %9.6f b[1,1] _col(29) %10.6f  (V[1,1])^.5
+      local k=2
+   }
+   else if "`fixed'"!=""&"`fixedmu'"!="" {
+      di in ye "Mu" in ye _col(20) %9.6f 0 _col(32) %10.6f  "(fixed)"
+      local k=1
+   }
+   else {
+      local k=1
+   }
+   if "`covariates'"!="" {
+      di in ye "`covariates'" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f  (V[`k',`k'])^.5
+      local k=`k'+1
+   }
+   if `fixedvar'==-1 {
+      di in ye "Sigma" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f  (V[`k',`k'])^.5
+      di in ye "Variance" in ye _col(20) %9.6f b[1,`k']^2  _col(29) %10.6f  2*(V[`k',`k'])^.5*b[1,`k']
+   }
+   else {
+      di in ye "Sigma" in ye _col(20) %9.6f `fixedvar'^.5 _col(32) %10.6f  "(fixed)"
+      di in ye "Variance" in ye _col(20) %9.6f `fixedvar'  _col(32) %10.6f  "(fixed)"
+   }
+   di in gr "{hline 100}"
+   di
+   di
+}
+
+end
diff --git a/Modules/ado/personal/p/pcm23.ado b/Modules/ado/personal/p/pcm23.ado
new file mode 100644
index 0000000..ab130f2
--- /dev/null
+++ b/Modules/ado/personal/p/pcm23.ado
@@ -0,0 +1,283 @@
+*! Version 2.3 10april2014
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007
+* Version 2 : July 15, 2011
+* Version 2.1 : October 18th, 2011 : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 : correction of -fixedvar- option
+*
+* Jean-benoit Hardouin, EA4275 Biostatistics, Clinical Research and Subjective Measures in Health Sciences
+* Faculties of Pharmaceutical Sciences & Medicine - University of Nantes - France
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2007-2014 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm,eclass
+version 8.0
+syntax varlist(min=3 numeric) [if] [in] [,rsm fixed(string) fixedvar(real -1) fixedmu short COVariates(varname) fixedvargroupc(string) vargroupc]
+preserve
+tempfile pcmfile
+qui save `pcmfile',replace
+
+if "`fixedmu'"!=""&`fixedvar'!=-1&"`covariates'"=="" {
+   di in red "You cannot fix in the same time the mean (fixedmu option) and the variance (fixedvar option) of the latent trait without covariables"
+   error 184
+}
+if "`fixed'"!=""&"`fixedmu'"==""&`fixedvar'!=-1&"`covariates'"=="" {
+   di in red "You cannot fix in the same time the difficulties (fixed option) and the variance (fixedvar option) of the latent trait without covariables"
+   error 184
+}
+
+/*******************************************************************************
+ESTIMATION OF THE PARAMETERS
+********************************************************************************/
+
+marksample touse
+qui keep if `touse'
+qui count
+local N=r(N)
+tokenize `varlist'
+local nbitems : word count `varlist'
+
+if "`rsm'"=="" {
+   di in gr "Model: " in ye "Partial Credit Model"
+}
+else {
+   di in gr "Model: " in ye "Rating Scale Model"
+}
+
+tempname one var w id item it obs x chosen d score
+qui gen `one'=1
+qui gen `id'=_n
+local modamax=0
+forvalues i=1/`nbitems' {
+   qui rename ``i'' `var'`i'
+   qui su `var'`i'
+   local moda`i'=`r(max)'
+   if `modamax'<`r(max)' {
+      local modamax=r(max)
+   }
+}
+qui genscore `var'1-`var'`nbitems' ,score(`score')
+qui collapse (sum) `w'=`one',by(`var'1-`var'`nbitems' `covariates')
+qui gen `id'=_n
+qui reshape long `var',i(`id') j(`item')
+qui drop if `var'==.
+qui gen `obs'=_n
+qui expand `=`modamax'+1'
+qui sort `id' `item' `obs'
+by `obs', sort: gen `x'=_n-1
+
+qui gen `chosen'=`var'==`x'
+qui tab `item', gen(`it')
+forvalues i=1/`nbitems' {
+   forvalues g=1/`modamax' {
+      qui gen `d'`i'_`g'=-1*`it'`i'*(`x'>=`g')
+   }
+}
+qui rename `w' `w'2
+bysort `id':egen score=sum(`x'*`chosen')
+qui su score
+local maxscore=r(max)
+
+
+if "`covariates'"!="" {
+   qui gen covw=`covariates'*`x'
+   local listcov covw
+}
+else {
+   local listcov
+}
+if `fixedvar'!=-1 {
+   local tmp=sqrt(`fixedvar')
+   constraint 1 `x'=`tmp'
+   local listconstr "constraints(1)"
+   local eq "eqs(slope) nrf(1)"
+}
+local eq "eqs(slope) nrf(1)"
+*set trace on
+if "`rsm'"=="" { /*PARTIAL CREDIT MODEL*/
+   *di "cas 1"
+   if "`fixed'"!="" { /*FIXED ITEMS DIFFICULTIES*/
+   *di "cas 2"
+      qui gen offset=0
+      local l=1
+      forvalues i=1/`nbitems' {
+         forvalues mi=1/`moda`i'' {
+            qui replace offset=offset+`fixed'[1,`l']*`d'`i'_`mi'
+            local ++l
+         }
+      }
+      if "`fixedmu'"!="" {
+         local mu
+      }
+      else {
+         local mu "`x'"
+      }
+*set trace on
+	  if "`fixedvargroupc'"!=""|"`vargroupc'"!="" {/*INEQUAL VARIANCES*/
+	       local var0: word 1 of `fixedvargroupc'
+	       local var1: word 2 of `fixedvargroupc'
+		   tempvar G0 G1
+		   qui gen `G0'=groupc<0
+		   qui gen `G1'=groupc>0
+		   qui replace `G0'=`G0'*`x'
+		   qui replace `G1'=`G1'*`x'
+		   qui eq B0: `G0'
+		   qui eq B1: `G1'
+	       constraint 1 _cons=0
+		   if "`fixedvargroupc'"!="" {/*FIXED INEQUAL VARIANCES*/
+		      constraint 2 `G0'=`=sqrt(`var0')' 
+		      constraint 3 `G1'=`=sqrt(`var1')'
+		      local listconstr "constraints(1 2 3)"
+           }
+		   else { /*FREE INEQUAL VARIANCE*/
+		      local listconstr "constraints(1)"
+		   }
+           local eq "eqs(B0 B1) nrf(2)"
+      }
+      eq slope:`x'
+      su
+	  tab covw
+	  di "ICI*******************jb"
+      di "`x' : x"
+	  di "`listcov' : listcov"
+	  di "`mu' : mu" 
+      noi di "gllamm `x'   `listcov' `mu',offset(offset) `listconstr' nocons i(`id') link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace `eq'"
+*set trace on
+      noi gllamm `x' `listcov' `mu' ,offset(offset) `listconstr' nocons i(`id') link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace `eq' iterate(100)
+   }
+   else if "`short'"!="" {
+      *di "cas 3"
+      eq slope:`x'
+      qui gllamm `x' `d'1_1-`d'`nbitems'_`modamax',i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons init iterate(100)
+      tempname bsave Vsave
+      matrix `bsave'=e(b)
+      matrix `Vsave'=e(V)
+      restore
+      qui pcm `varlist' , fixed(`bsave')
+   }
+   else {
+      *di "cas 4"
+      di "no short"
+      eq slope:`x'
+      qui gen i=`id'
+      constraint 1 `x'=1
+      gllamm `x' `d'1_1-`d'`nbitems'_`modamax' `listcov',i(i) `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons iterate(100)
+   }
+}
+else {
+   *di "cas 5"
+
+   tempname step n
+   forvalues i=2/`modamax' {
+      qui gen `step'`i'=-1*(`x'>=`i')
+   }
+   forvalues i=1/`nbitems' {
+      qui gen `n'`var'`i'=(-1)*(`it'`i')*(`x')
+   }
+   qui sort `id' `item' `x'
+   eq slope:`x'
+   gllamm `x' `n'`var'1-`n'`var'`nbitems' `step'2-`step'`modamax' `listcov', i(`id') `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons  iterate(100)
+}
+
+tempname b V chol
+matrix b=e(b)
+matrix V=e(V)
+local ll=e(ll)
+matrix chol=e(chol)
+
+
+if "`rsm'"=="" {
+   di
+   di in gr "Number of observations: " in ye `N'
+   di in gr "Number of items: " in ye `nbitems'
+   di in gr "Number of parameters: " in  ye `=`nbitems'*`modamax'+1'
+   di in gr "Log-likelihood: " in ye `ll'
+   di
+   di
+   di in gr "{hline 100}"
+   di in gr "Item" _col(10) "Modality" _col(20) "Parameter" _col(30) "Std Error"
+   di in gr "{hline 100}"
+   if "`fixed'"=="" {
+      forvalues i=1/`nbitems' {
+         forvalues j=1/`modamax' {
+            if `j'==1 {
+               di in ye "``i''" _cont
+            }
+            local k=(`i'-1)*`modamax'+`j'
+            if "`short'"!="" {
+               di in ye _col(17) `j' _col(20) %9.6f `bsave'[1,`k'] in ye _col(30) %9.6f (`Vsave'[`k',`k'])^.5
+            }
+            else {
+               di in ye _col(17) `j' _col(20) %9.6f b[1,`k'] in ye _col(30) %9.6f (V[`k',`k'])^.5
+            }
+         }
+         di in gr "{dup 100:-}"
+      }
+   }
+   else {
+      forvalues i=1/`nbitems' {
+         forvalues j=1/`modamax' {
+            if `j'==1 {
+               di in ye "``i''" _cont
+            }
+            local k=(`i'-1)*`modamax'+`j'
+            di in ye _col(17) `j' _col(20) %9.6f `fixed'[1,`k'] in ye _col(32) "(fixed)"
+         }
+         di in gr "{dup 100:-}"
+      }
+   }
+   if "`fixed'"==""&"`short'"=="" {
+      local k=`nbitems'*`modamax'+1
+   }
+   else if "`fixed'"!=""&"`fixedmu'"=="" {
+      di in ye "Mu" in ye _col(20) %9.6f b[1,1] _col(29) %10.6f  (V[1,1])^.5
+      local k=2
+   }
+   else if "`fixed'"!=""&"`fixedmu'"!="" {
+      di in ye "Mu" in ye _col(20) %9.6f 0 _col(32) %10.6f  "(fixed)"
+      local k=1
+   }
+   else {
+      local k=1
+   }
+   if "`covariates'"!="" {
+      di in ye "`covariates'" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f  (V[`k',`k'])^.5
+      local k=`k'+1
+   }
+   if `fixedvar'==-1 {
+      di in ye "Sigma" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f  (V[`k',`k'])^.5
+      di in ye "Variance" in ye _col(20) %9.6f b[1,`k']^2  _col(29) %10.6f  2*(V[`k',`k'])^.5*b[1,`k']
+   }
+   else {
+      di in ye "Sigma" in ye _col(20) %9.6f `fixedvar'^.5 _col(32) %10.6f  "(fixed)"
+      di in ye "Variance" in ye _col(20) %9.6f `fixedvar'  _col(32) %10.6f  "(fixed)"
+   }
+   di in gr "{hline 100}"
+   di
+   di
+}
+
+end
diff --git a/Modules/ado/personal/p/pcm3.2.ado b/Modules/ado/personal/p/pcm3.2.ado
new file mode 100644
index 0000000..2215ace
--- /dev/null
+++ b/Modules/ado/personal/p/pcm3.2.ado
@@ -0,0 +1,917 @@
+*! Version 3.2 17july2019
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+*
+*
+*
+* Jean-benoit Hardouin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(string) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string)]
+
+qui count
+local nbobs=r(N)
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+local modcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local modcont (`modcont'->T)
+}
+
+local modcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local modcat (`modcat'->T)
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+preserve
+
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+forvalues i=1/`nbitems' {
+     qui su ``i''
+	 if `r(min)'!=`modamin' {
+	     local modamin=r(min)
+		 local pbmin `pbmin' ``i''
+	 }
+	 if `r(max)'>`modamax' {
+	     local modamax=r(max)
+	 }
+	 local modamax``i''=r(max)
+	 if "`rsm'"=="" {
+	    local nbdiff=`nbdiff'+`modamax``i'''
+	 }
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count
+local nbind=r(N)
+*set trace on
+local code
+forvalues k=1/`modamax' {
+   local code`k'
+   forvalues i=1/`nbitems' {
+       if `k'<=`modamax``i''' {
+	      local code`k' `code`k'' `k'.``i''
+	   }
+   }
+   local code`k' (`code`k''<-T@`k')
+   local code `code' `code`k''
+}
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+if "`difficulties'"!="" {
+	local t=1
+	local constraints
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax``i''' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				local val=0
+				forvalues l=1/`k' {
+				   local val=`val'-`difficulties'[`i',`l']
+				}
+				constraint `t' [`k'.``i'']_cons=`val'
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+}
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+
+if "`rsm'"!="" {
+   local t=1
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       constraint `t'   [`=`k'-1'.``i'']_cons-[`k'.``i'']_cons+[1.``i'']_cons=[`=`k'-1'.`1']_cons-[`k'.`1']_cons+[1.`1']_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')"
+local qui qui
+if "`model'"!="" {
+   local qui
+}
+`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2
+tempname groups
+qui predict mu, mu
+*su mu 
+qui predict `latent',latent se(`selatent')
+set seed 123456
+qui gen `latent2'=`latent'+invnorm(uniform())*`selatent'
+qui genscore `varlist',score(`score')
+qui gengroup `latent',newvariable(`group') continuous
+qui levelsof `group'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+3',.)
+forvalues g=1/`nbgroups' {
+    matrix `groups'[`g',`=`nbitems'+3']=0
+    forvalues i=1/`nbitems' {
+	*tab ``i'' if `group'==`g'
+        qui count if ``i''!=.&`group'==`g'
+		local n=r(N)
+		if `n'>0 {
+			qui su ``i'' if `group'==`g'
+			matrix `groups'[`g',`i']=r(mean)
+			matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+		}
+		else {
+			matrix `groups'[`g',`i']=.
+			matrix `groups'[`g',`=`nbitems'+3']=.
+		}		
+    }
+	qui su `latent' if `group'==`g'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'==`g'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+}
+*matrix list `groups'
+	
+qui count if `score'!=.
+local nbobsssmd=r(N)	
+	
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i'':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i'':_cons]
+	qui lincom -_b[1.``i'':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+    *qui matrix `vardiff'[`t',`t']=_se[1.``i'':_cons]^2
+	local rn `rn' 1.``i''
+	local ++t
+	local sum _b[1.``i'':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax``i''' {
+			local sum "_b[`k'.``i'':_cons]-`sum'"
+			qui lincom -(`sum')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1':_cons]-_b[`k'.`1':_cons]+_b[1.`1':_cons]
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES ET LA VARIANCE
+*************************************************************************************************************/
+
+tempname covariates
+qui matrix `covariates'=J(`=`nbpar'+1',6,.)
+
+*set trace on
+if "`continuous'"!=""|"`categorical'"!="" {
+    qui lincom _b[/var(e.T)]
+}
+else {
+    qui lincom _b[/var(T)]
+}
+qui matrix `covariates'[1,1]=`r(estimate)'
+qui matrix `covariates'[1,2]=`r(se)'
+qui matrix `covariates'[1,3]=`r(z)'
+qui matrix `covariates'[1,4]=`r(p)'
+qui matrix `covariates'[1,5]=`r(lb)'
+qui matrix `covariates'[1,6]=`r(ub)'
+
+local t=2
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+* matrix list `covariates'
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+
+local t=1
+local diffname
+*set trace on
+di "{hline 73}"
+di  as text _col(60) "<--95% IC -->"
+di  "Items" _col(60) "Lower" _col(68) "Upper"
+di "parameters" _col(13) "category" _col(25) "Estimate" _col(37) "s.e." _col(48) "z" _col(56) "p" _col(59) " Bound" _col(68) "Bound"
+di "{hline 73}"
+*set trace on
+forvalues i=1/`nbitems' {
+   *local l=1
+   forvalues j=1/`modamax``i''' {
+      if "`rsm'"==""|`j'==1 {
+		  if `j'==1 {
+			 di as text abbrev("``i''",19) _c
+		  }
+		  di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+		  local ++t
+		  *local ++l
+		  local diffname `diffname' `j'.``i''
+	  }
+   }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		di as text "tau`k'"  as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+	    local diffname `diffname' tau`k'
+		local ++t
+    }
+}
+di as text "{hline 73}"
+local t=1
+local n: word count  Variance `continuous' 
+forvalues i=1/`n' {
+    local v: word `i' of Variance `continuous' 
+    di as text _col(1) %5.2f "`v'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+    local ++t
+}
+
+local rn Variance `continuous'
+
+local n: word count of  `categorical' 
+local catname
+forvalues i=1/`n' {
+    local v: word `i' of `categorical'
+	local first=1
+	local saute=1
+    foreach j in `levelsof`cat`i''' {
+	    if `saute'==0 {
+		    if `first'==1 {
+			    di as text _col(1) abbrev("`v'",19) _c
+		    }
+		    di  as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+		    local ++first
+			local rn `rn' `j'.`n'
+		    local ++t
+			local catname `catname' `j'.`v'
+        }
+		else {
+		   local saute=0
+		}
+	}
+    local ++t
+}
+di as text "{hline 73}"
+di
+qui su `latent'
+qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])^2)
+di as text "PSI:" as result %4.2f `PSI' 
+di
+
+
+
+matrix colnames `covariates'=`cn'
+matrix rownames `covariates'=`rn'
+
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+
+tempname fit
+qui matrix `fit'=J(`nbitems',4,.)
+matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+matrix rownames `fit'=`varlist'
+*matrix list `fit'
+
+tempvar Tcum TInf cum
+qui gen `Tcum'=0
+qui gen `TInf'=0
+di as text "{hline 90}"
+di as text _col(60) "<---  Standardized   --->"
+di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+di as text "{hline 90}"
+di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+di as text "{hline 90}"
+
+*set trace on
+local chi2=0
+local chi2_old=0
+forvalues g=1/`nbgroups' {
+   local chi2_g`g'=0
+   local chi2_old_g`g'=0
+}
+forvalues i=1/`nbitems' {
+    if "`rsm'"=="" {
+	    local mm=`modamax``i'''
+	}
+	else {
+	    local mm `modamax'
+	}	
+	tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+	tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+	local d=1
+	local d_old=1
+	qui gen `cum``i'''=0
+	qui gen `cum_old``i'''=0
+	forvalues k=1/`mm' {
+		local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+		local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
+	}
+	qui gen `c0_``i'''=1/(`d')
+	qui gen `c_old0_``i'''=1/(`d_old')
+	forvalues k=1/`mm' {
+		tempvar c`k'_``i'' c_old`k'_``i''
+		qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
+		qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
+		qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
+		qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
+	}
+	qui gen `Inf``i'''=0
+	qui gen `Inf_old``i'''=0
+	qui gen `C``i'''=0
+	forvalues k=0/`mm' {
+		qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
+		qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
+		qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
+	}
+	qui count if ``i''!=.
+	local n``i''=r(N)
+	
+	qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
+	qui su `C2``i'''
+	local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+	qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
+	qui su `C3``i'''
+	local n=r(sum)
+	qui su `Inf``i'''
+	local d=r(sum)
+	local q2i``i''=`n'/((`d')^2)
+	
+	//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+	
+	qui replace `Tcum'=`Tcum'+`cum``i'''
+	qui replace `TInf'=`TInf'+`Inf``i'''
+	qui gen `y``i'''=``i''-`cum``i'''
+	qui gen `y_old``i'''=``i''-`cum_old``i'''
+	qui gen `y2``i'''=(`y``i''')^2
+	qui gen `y2_old``i'''=(`y_old``i''')^2
+	qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
+	local chi2_``i''=0
+	local chi2_old_``i''=0
+	forvalues g=1/`nbgroups' {
+		qui su `y2``i''' if `group'==`g'
+		local n=r(sum)
+		qui su ``i'' if `group'==`g'
+		local n1=r(sum)
+		qui su `cum``i''' if `group'==`g'
+		local n2=r(sum)
+		qui su `Inf``i''' if `group'==`g'
+		local d=r(sum)
+		*di "chi2_`g'_``i''=`chi2'+(`n1'-`n2')^2/(`d')"
+		local chi2=`chi2'+(`n1'-`n2')^2/(`d')
+		local chi2_``i''=`chi2_``i'''+(`n1'-`n2')^2/(`d')
+		local chi2_g`g'=`chi2_g`g''+(`n1'-`n2')^2/(`d')
+		qui su `y2_old``i''' if `group'==`g'
+		local n_old=r(sum)
+		qui su ``i'' if `group'==`g'
+		local n1_old=r(sum)
+		qui su `cum_old``i''' if `group'==`g'
+		local n2_old=r(sum)
+		qui su `Inf_old``i''' if `group'==`g'
+		local d_old=r(sum)
+		local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+		local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+		local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+	}
+	*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+	*su `z``i'''
+	label variable `z``i''' "Standardized residuals associated to ``i''"
+	label variable `latent' "Latent trait"
+	*set trace on
+	if  "`graphs'"!=""&"`graphitems'"=="" {
+        if "`filesave'"!="" {
+		    local fs saving(`dirsave'//residuals_``i'',replace)
+		}
+	    qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+	}
+	*set trace off
+	qui gen `z2``i'''=(`z``i''')^2
+	qui su `z2``i'''
+	local OUTFIT``i''=`r(mean)'
+	qui matrix `fit'[`i',1]=`OUTFIT``i'''
+	local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+	qui matrix `fit'[`i',3]=`OUTFITs``i'''
+	qui su `Inf``i''' if ``i''!=.
+	local sumw``i''=r(sum)
+	qui gen `i``i'''=`Inf``i'''*`z2``i''' 
+	qui su `i``i''' if ``i''!=.
+	local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+	qui matrix `fit'[`i',2]=`INFIT``i'''
+	local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+	qui matrix `fit'[`i',4]=`INFITs``i'''
+	
+	di abbrev("``i''",19) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+	
+}
+di as text "{hline 90}"
+di as text "*: As suggested by Wright (Smith, 1998)
+di as text "**: As suggested by Bond and Fox (2007)
+
+set trace off
+
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+
+if "`graphs'"!="" {
+
+	tempfile savefile
+	qui save `savefile'
+
+	qui clear
+	qui set obs 2000
+	qui gen u=(_n-1000)/250
+	qui gen Tcum=0
+	qui gen TInf=0
+	forvalues i=1/`nbitems' {
+	   local scatteri`i' 
+	   forvalues g=1/`nbgroups' {
+		  local x=`groups'[`g',`=`nbitems'+1']
+		  local y=`groups'[`g',`i']
+		  local s1=`groups'[`g',`=`nbitems'+2']
+		  local seuil=30
+		  local s vtiny
+		  *set trace on
+		  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+		      if `s1'>`seuil' {
+			     local s `lab'
+			  }
+			  local seuil=`seuil'+10
+		  }
+		  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+		*set trace off
+		}
+		local d=1
+		qui gen cum``i''=0
+		*set trace on
+		if "`rsm'"=="" {
+			local mm=`modamax``i'''
+		}
+		else {
+			local mm `modamax'
+		}	
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+		}
+		qui gen c0_``i''=1/(`d')
+		label variable c0_``i'' "Pr(``i''=0)"
+		forvalues k=1/`mm' {
+			qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+			qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+			label variable c`k'_``i'' "Pr(``i''=`k')"
+		}
+		qui gen Inf``i''=0
+		forvalues k=1/`mm' {
+			qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+		}
+		if "`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fsc saving(`dirsave'//CCC_``i'',replace)
+				local fsi saving(`dirsave'//ICC_``i'',replace)
+			}
+		    qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+		    qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+		}
+		qui replace Tcum=Tcum+cum``i''
+		qui replace TInf=TInf+Inf``i''	
+		label variable Inf``i'' "``i''"
+	}
+	if "`filesave'"!="" {
+		local fst saving(`dirsave'//TCC,replace)
+		local fsteo saving(`dirsave'//TCCeo,replace)
+		local fsi saving(`dirsave'//ICC,replace)
+		local fsti saving(`dirsave'//TIC,replace)
+		local fsm saving(`dirsave'//map,replace)
+	}
+	qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+	qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+	qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+
+	local scatteri
+	forvalues g=1/`nbgroups' {
+		local x=`groups'[`g',`=`nbitems'+1']
+		local y=`groups'[`g',`=`nbitems'+3']
+		  local s1=`groups'[`g',`=`nbitems'+2']
+		  local seuil=30
+		  local s vtiny
+		  *set trace on
+		  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+		      if `s1'>`seuil' {
+			     local s `lab'
+			  }
+			  local seuil=`seuil'+10
+		  }
+		local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+	}
+	qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+	
+	
+	
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+
+	gen eff=0
+	local effmax=0
+	forvalues g=1/`nbgroups' {
+	    local eff=`groups'[`g',`=`nbitems'+2']
+		if `groups'[`g',`=`nbitems'+2']>`effmax' {
+		   local effmax=`groups'[`g',`=`nbitems'+2']
+		}
+	    local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
+	    *di "replace eff=`eff' if round(u,0.004)==`lat'"
+	    qui replace eff=`eff' if round(u,0.004)==`lat'
+    }
+	gen density=normalden(u)*sqrt(`covariates'[1,1])
+	label variable eff "Frequencies"
+	label variable u "Latent trait"
+	label variable TInf "Information curve"
+	label variable density "Density function of the latent trait"
+	local scatteri
+	qui su u if eff!=0
+	local floor=floor(`r(min)')
+	local ceil=ceil(`r(max)')
+	forvalues i=1/`nbitems' {
+	   local color`i':word `i' of `color'
+	   local y=-`i'*`effmax'/`nbitems'
+	   forvalues l=1/`modamax' {
+		   local x=`diffmat'[`i',`l']
+		   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+		   if `x'<`floor' {
+		      local floor=floor(`x')
+		   }
+		   if `x'>`ceil' {
+		      local ceil=ceil(`x')
+		   }
+	   }
+	   local scatteri `scatteri' || scatteri `y' `floor' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+	}
+	qui su eff
+	local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+	qui su TInf
+	local maxi=ceil(`r(max)')
+	qui su density
+    local maxd=ceil(`r(max)')
+	qui drop if u<`floor'|u>`ceil'
+	qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(`floor'(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3))    `scatteri'  , name(map,replace) ytitle("Frequencies")  ylabel(-`maxi'(`=`maxi'/5')`maxi' ,axis(2)) ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait") xtitle("Latent trait") `fsm'
+
+
+	qui clear
+	qui use `savefile'
+
+}
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+
+di
+di as text "{hline 57}"
+di _col(31) "Latent Variable" _col(50) "Expected"
+di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score"
+di as text "{hline 57}"
+*set trace on
+forvalues g=1/`nbgroups' {
+    qui count if `group'==`g' 
+	local eff`g'=r(N)
+	qui count if `score'!=.&`group'==`g'
+	local n=r(N)
+	di as text "`g' (n=" as result `eff`g'' as text ")" _c
+	if `n'>0 {
+		qui su `score' if `group'==`g'
+		local scoremin`g'=`r(min)'
+		local scoremax`g'=`r(max)'
+		forvalues s=`scoremin`g''/`scoremax`g'' {
+			qui count if `group'==`g'&`score'==`s'
+			local eff=r(N)
+			qui su `latent' if `group'==`g'&`score'==`s'
+			local mean=r(mean)
+			qui su `selatent' if `group'==`g'&`score'==`s'
+			local se=r(mean)
+			qui su `Tcum' if `group'==`g'&`score'==`s'
+			local exp=r(mean)
+			if `eff'>0 {
+			   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+			}
+		}
+	}
+	qui count if `group'==`g'&`score'==.
+	local eff=r(N)
+	qui su `latent' if `group'==`g'&`score'==.
+	local mean=r(mean)
+	qui su `selatent' if `group'==`g'&`score'==.
+	local se=r(mean)
+	qui su `Tcum' if `group'==`g'&`score'==.
+	local exp=r(mean)
+	if `eff'>0 {
+		di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+	}
+    di as text "{hline 57}"
+}
+	
+
+
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin
+	putdocx paragraph
+	putdocx text ("General informations") , bold underline font(,14) smallcaps
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph
+	putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx paragraph
+	putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export `dirsave'//`i'.`extension', replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save `dirsave'//`i', replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image `dirsave'//`i'.png, height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save `dirsave'//`j'_``i'', replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export `dirsave'//`j'_``i''.`extension', replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image `dirsave'//`j'_``i''.png , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save `dirsave'//`docx'.docx, replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+restore, preserve
+end
diff --git a/Modules/ado/personal/p/pcm3.3.ado b/Modules/ado/personal/p/pcm3.3.ado
new file mode 100644
index 0000000..ea5fe5d
--- /dev/null
+++ b/Modules/ado/personal/p/pcm3.3.ado
@@ -0,0 +1,984 @@
+*! Version 3.3 25july2019
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+*
+*
+*
+* Jean-benoit Hardouin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(name) GENINF(name) postpce]
+
+qui count
+local nbobs=r(N)
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+local modcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local modcont (`modcont'->T)
+}
+
+local modcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local modcat (`modcat'->T)
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' se`genlt' `geninf'
+	if _rc!=0 {
+	    di in red "The variables `genlt', se`genlt' and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+forvalues i=1/`nbitems' {
+     qui su ``i''
+	 if `r(min)'!=`modamin' {
+	     local modamin=r(min)
+		 local pbmin `pbmin' ``i''
+	 }
+	 if `r(max)'>`modamax' {
+	     local modamax=r(max)
+	 }
+	 local modamax``i''=r(max)
+	 if "`rsm'"=="" {
+	    local nbdiff=`nbdiff'+`modamax``i'''
+	 }
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count
+local nbind=r(N)
+*set trace on
+local code
+forvalues k=1/`modamax' {
+   local code`k'
+   forvalues i=1/`nbitems' {
+       if `k'<=`modamax``i''' {
+	      local code`k' `code`k'' `k'.``i''
+	   }
+   }
+   local code`k' (`code`k''<-T@`k')
+   local code `code' `code`k''
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	local t=1
+	local constraints
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax``i''' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				constraint `t' [`k'.``i'']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+}
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+
+if "`rsm'"!="" {
+   local t=1
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       constraint `t'   [`=`k'-1'.``i'']_cons-[`k'.``i'']_cons+[1.``i'']_cons=[`=`k'-1'.`1']_cons-[`k'.`1']_cons+[1.`1']_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')"
+local qui qui
+if "`model'"!="" {
+   local qui
+}
+`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent',latent se(`selatent')
+if "`genlt'"!="" {
+    gen `genlt'=`latent'
+	gen se`genlt'=`selatent'
+}
+set seed 123456
+qui gen `latent2'=`latent'+invnorm(uniform())*`selatent'
+qui genscore `varlist',score(`score')
+qui gengroup `latent',newvariable(`group') continuous
+qui levelsof `group'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+3',.)
+forvalues g=1/`nbgroups' {
+    matrix `groups'[`g',`=`nbitems'+3']=0
+    forvalues i=1/`nbitems' {
+	*tab ``i'' if `group'==`g'
+        qui count if ``i''!=.&`group'==`g'
+		local n=r(N)
+		if `n'>0 {
+			qui su ``i'' if `group'==`g'
+			matrix `groups'[`g',`i']=r(mean)
+			matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+		}
+		else {
+			matrix `groups'[`g',`i']=.
+			matrix `groups'[`g',`=`nbitems'+3']=.
+		}		
+    }
+	qui su `latent' if `group'==`g'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'==`g'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+}
+*matrix list `groups'
+	
+qui count if `score'!=.
+local nbobsssmd=r(N)	
+	
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i'':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i'':_cons]
+	qui lincom -_b[1.``i'':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+    *qui matrix `vardiff'[`t',`t']=_se[1.``i'':_cons]^2
+	local rn `rn' 1.``i''
+	local ++t
+	local sum _b[1.``i'':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax``i''' {
+			local sum "_b[`k'.``i'':_cons]-(`sum')"
+			di "``i'' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i'':_cons]-_b[`k'.``i'':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1':_cons]-_b[`k'.`1':_cons]+_b[1.`1':_cons]
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES ET LA VARIANCE
+*************************************************************************************************************/
+
+tempname covariates
+qui matrix `covariates'=J(`=`nbpar'+1',6,.)
+
+*set trace on
+if "`continuous'"!=""|"`categorical'"!="" {
+    qui lincom _b[/var(e.T)]
+}
+else {
+    qui lincom _b[/var(T)]
+}
+qui matrix `covariates'[1,1]=`r(estimate)'
+qui matrix `covariates'[1,2]=`r(se)'
+qui matrix `covariates'[1,3]=`r(z)'
+qui matrix `covariates'[1,4]=`r(p)'
+qui matrix `covariates'[1,5]=`r(lb)'
+qui matrix `covariates'[1,6]=`r(ub)'
+
+local t=2
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+* matrix list `covariates'
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 73}"
+	di  as text _col(60) "<--95% IC -->"
+	di  "Items" _col(60) "Lower" _col(68) "Upper"
+	di "parameters" _col(13) "category" _col(25) "Estimate" _col(37) "s.e." _col(48) "z" _col(56) "p" _col(59) " Bound" _col(68) "Bound"
+	di "{hline 73}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax``i''' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 73}"
+	local t=1
+	local n: word count  Variance `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of Variance `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		local ++t
+	}
+	di as text "{hline 73}"
+	di
+	qui su `latent'
+	qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])^2)
+	di as text "PSI:" as result %4.2f `PSI' 
+	di
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+
+tempname fit
+qui matrix `fit'=J(`nbitems',4,.)
+matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+matrix rownames `fit'=`varlist'
+*matrix list `fit'
+
+tempvar Tcum TInf cum
+qui gen `Tcum'=0
+qui gen `TInf'=0
+if "`postpce'"=="" {
+	di as text "{hline 90}"
+	di as text _col(60) "<---  Standardized   --->"
+	di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+	di as text "{hline 90}"
+	di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+	di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+	di as text "{hline 90}"
+}
+*set trace on
+local chi2=0
+local chi2_old=0
+forvalues g=1/`nbgroups' {
+   local chi2_g`g'=0
+   local chi2_old_g`g'=0
+}
+forvalues i=1/`nbitems' {
+	if "`rsm'"=="" {
+		local mm=`modamax``i'''
+	}
+	else {
+		local mm `modamax'
+	}	
+	tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+	tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+	local d=1
+	local d_old=1
+	qui gen `cum``i'''=0
+	qui gen `cum_old``i'''=0
+	forvalues k=1/`mm' {
+		local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+		local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
+	}
+	qui gen `c0_``i'''=1/(`d')
+	qui gen `c_old0_``i'''=1/(`d_old')
+	forvalues k=1/`mm' {
+		tempvar c`k'_``i'' c_old`k'_``i''
+		qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
+		qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
+		qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
+		qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
+	}
+	qui gen `Inf``i'''=0
+	qui gen `Inf_old``i'''=0
+	qui gen `C``i'''=0
+	forvalues k=0/`mm' {
+		qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
+		qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
+		qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
+	}
+	qui count if ``i''!=.
+	local n``i''=r(N)
+	
+	qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
+	qui su `C2``i'''
+	local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+	qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
+	qui su `C3``i'''
+	local n=r(sum)
+	qui su `Inf``i'''
+	local d=r(sum)
+	local q2i``i''=`n'/((`d')^2)
+	
+	//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+	
+	qui replace `Tcum'=`Tcum'+`cum``i'''
+	qui replace `TInf'=`TInf'+`Inf``i'''
+	qui gen `y``i'''=``i''-`cum``i'''
+	qui gen `y_old``i'''=``i''-`cum_old``i'''
+	qui gen `y2``i'''=(`y``i''')^2
+	qui gen `y2_old``i'''=(`y_old``i''')^2
+	qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
+	local chi2_``i''=0
+	local chi2_old_``i''=0
+	forvalues g=1/`nbgroups' {
+		qui su `y2``i''' if `group'==`g'
+		local n=r(sum)
+		qui su ``i'' if `group'==`g'
+		local n1=r(sum)
+		qui su `cum``i''' if `group'==`g'
+		local n2=r(sum)
+		qui su `Inf``i''' if `group'==`g'
+		local d=r(sum)
+		*di "chi2_`g'_``i''=`chi2'+(`n1'-`n2')^2/(`d')"
+		local chi2=`chi2'+(`n1'-`n2')^2/(`d')
+		local chi2_``i''=`chi2_``i'''+(`n1'-`n2')^2/(`d')
+		local chi2_g`g'=`chi2_g`g''+(`n1'-`n2')^2/(`d')
+		qui su `y2_old``i''' if `group'==`g'
+		local n_old=r(sum)
+		qui su ``i'' if `group'==`g'
+		local n1_old=r(sum)
+		qui su `cum_old``i''' if `group'==`g'
+		local n2_old=r(sum)
+		qui su `Inf_old``i''' if `group'==`g'
+		local d_old=r(sum)
+		local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+		local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+		local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+	}
+	*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+	*su `z``i'''
+	label variable `z``i''' "Standardized residuals associated to ``i''"
+	label variable `latent' "Latent trait"
+	*set trace on
+	if  "`graphs'"!=""&"`graphitems'"=="" {
+		if "`filesave'"!="" {
+			local fs saving(`dirsave'//residuals_``i'',replace)
+		}
+		qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+	}
+	*set trace off
+	qui gen `z2``i'''=(`z``i''')^2
+	qui su `z2``i'''
+	local OUTFIT``i''=`r(mean)'
+	qui matrix `fit'[`i',1]=`OUTFIT``i'''
+	local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+	qui matrix `fit'[`i',3]=`OUTFITs``i'''
+	qui su `Inf``i''' if ``i''!=.
+	local sumw``i''=r(sum)
+	qui gen `i``i'''=`Inf``i'''*`z2``i''' 
+	qui su `i``i''' if ``i''!=.
+	local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+	qui matrix `fit'[`i',2]=`INFIT``i'''
+	local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+	qui matrix `fit'[`i',4]=`INFITs``i'''
+	if "`postpce'"=="" {
+		di abbrev("``i''",19) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+	}
+}
+if "`postpce'"=="" {
+	di as text "{hline 90}"
+	di as text "*: As suggested by Wright (Smith, 1998)
+	di as text "**: As suggested by Bond and Fox (2007)
+}
+if "`geninf'"!="" {
+   gen `geninf'=`TInf'
+}
+
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Itération `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1')
+		`qui' pcm `varlist' [iweight=`sinf'],diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1')
+		qui su `ecart_`it''
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+
+if "`graphs'"!="" {
+
+	tempfile savefile
+	qui save `savefile'
+
+	qui clear
+	qui set obs 2000
+	qui gen u=(_n-1000)/250
+	qui gen Tcum=0
+	qui gen TInf=0
+	forvalues i=1/`nbitems' {
+	   local scatteri`i' 
+	   forvalues g=1/`nbgroups' {
+		  local x=`groups'[`g',`=`nbitems'+1']
+		  local y=`groups'[`g',`i']
+		  local s1=`groups'[`g',`=`nbitems'+2']
+		  local seuil=30
+		  local s vtiny
+		  *set trace on
+		  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+		      if `s1'>`seuil' {
+			     local s `lab'
+			  }
+			  local seuil=`seuil'+10
+		  }
+		  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+		*set trace off
+		}
+		local d=1
+		qui gen cum``i''=0
+		*set trace on
+		if "`rsm'"=="" {
+			local mm=`modamax``i'''
+		}
+		else {
+			local mm `modamax'
+		}	
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+		}
+		qui gen c0_``i''=1/(`d')
+		label variable c0_``i'' "Pr(``i''=0)"
+		forvalues k=1/`mm' {
+			qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+			qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+			label variable c`k'_``i'' "Pr(``i''=`k')"
+		}
+		qui gen Inf``i''=0
+		forvalues k=1/`mm' {
+			qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+		}
+		if "`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fsc saving(`dirsave'//CCC_``i'',replace)
+				local fsi saving(`dirsave'//ICC_``i'',replace)
+			}
+		    qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+		    qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+		}
+		qui replace Tcum=Tcum+cum``i''
+		qui replace TInf=TInf+Inf``i''	
+		label variable Inf``i'' "``i''"
+	}
+	if "`filesave'"!="" {
+		local fst saving(`dirsave'//TCC,replace)
+		local fsteo saving(`dirsave'//TCCeo,replace)
+		local fsi saving(`dirsave'//ICC,replace)
+		local fsti saving(`dirsave'//TIC,replace)
+		local fsm saving(`dirsave'//map,replace)
+	}
+	qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+	qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+	qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+
+	local scatteri
+	forvalues g=1/`nbgroups' {
+		local x=`groups'[`g',`=`nbitems'+1']
+		local y=`groups'[`g',`=`nbitems'+3']
+		  local s1=`groups'[`g',`=`nbitems'+2']
+		  local seuil=30
+		  local s vtiny
+		  *set trace on
+		  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+		      if `s1'>`seuil' {
+			     local s `lab'
+			  }
+			  local seuil=`seuil'+10
+		  }
+		local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+	}
+	qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+	
+	
+	
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+
+	gen eff=0
+	local effmax=0
+	forvalues g=1/`nbgroups' {
+	    local eff=`groups'[`g',`=`nbitems'+2']
+		if `groups'[`g',`=`nbitems'+2']>`effmax' {
+		   local effmax=`groups'[`g',`=`nbitems'+2']
+		}
+	    local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
+	    *di "replace eff=`eff' if round(u,0.004)==`lat'"
+	    qui replace eff=`eff' if round(u,0.004)==`lat'
+    }
+	gen density=normalden(u)*sqrt(`covariates'[1,1])
+	label variable eff "Frequencies"
+	label variable u "Latent trait"
+	label variable TInf "Information curve"
+	label variable density "Density function of the latent trait"
+	local scatteri
+	qui su u if eff!=0
+	local floor=floor(`r(min)')
+	local ceil=ceil(`r(max)')
+	forvalues i=1/`nbitems' {
+	   local color`i':word `i' of `color'
+	   local y=-`i'*`effmax'/`nbitems'
+	   forvalues l=1/`modamax' {
+		   local x=`diffmat'[`i',`l']
+		   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+		   if `x'<`floor' {
+		      local floor=floor(`x')
+		   }
+		   if `x'>`ceil' {
+		      local ceil=ceil(`x')
+		   }
+	   }
+	   local scatteri `scatteri' || scatteri `y' `floor' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+	}
+	qui su eff
+	local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+	qui su TInf
+	local maxi=ceil(`r(max)')
+	qui su density
+    local maxd=ceil(`r(max)')
+	qui drop if u<`floor'|u>`ceil'
+	qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(`floor'(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3))    `scatteri'  , name(map,replace) ytitle("Frequencies")  ylabel(-`maxi'(`=`maxi'/5')`maxi' ,axis(2)) ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait") xtitle("Latent trait") `fsm'
+
+
+	qui clear
+	qui use `savefile'
+
+}
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+
+di
+di as text "{hline 57}"
+di _col(31) "Latent Variable" _col(50) "Expected"
+di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score"
+di as text "{hline 57}"
+*set trace on
+forvalues g=1/`nbgroups' {
+    qui count if `group'==`g' 
+	local eff`g'=r(N)
+	qui count if `score'!=.&`group'==`g'
+	local n=r(N)
+	di as text "`g' (n=" as result `eff`g'' as text ")" _c
+	if `n'>0 {
+		qui su `score' if `group'==`g'
+		local scoremin`g'=`r(min)'
+		local scoremax`g'=`r(max)'
+		forvalues s=`scoremin`g''/`scoremax`g'' {
+			qui count if `group'==`g'&`score'==`s'
+			local eff=r(N)
+			qui su `latent' if `group'==`g'&`score'==`s'
+			local mean=r(mean)
+			qui su `selatent' if `group'==`g'&`score'==`s'
+			local se=r(mean)
+			qui su `Tcum' if `group'==`g'&`score'==`s'
+			local exp=r(mean)
+			if `eff'>0 {
+			   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+			}
+		}
+	}
+	qui count if `group'==`g'&`score'==.
+	local eff=r(N)
+	qui su `latent' if `group'==`g'&`score'==.
+	local mean=r(mean)
+	qui su `selatent' if `group'==`g'&`score'==.
+	local se=r(mean)
+	qui su `Tcum' if `group'==`g'&`score'==.
+	local exp=r(mean)
+	if `eff'>0 {
+		di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+	}
+    di as text "{hline 57}"
+}
+	
+
+
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin
+	putdocx paragraph
+	putdocx text ("General informations") , bold underline font(,14) smallcaps
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph
+	putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx paragraph
+	putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export `dirsave'//`i'.`extension', replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save `dirsave'//`i', replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image `dirsave'//`i'.png, height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save `dirsave'//`j'_``i'', replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export `dirsave'//`j'_``i''.`extension', replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image `dirsave'//`j'_``i''.png , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save `dirsave'//`docx'.docx, replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm3.ado b/Modules/ado/personal/p/pcm3.ado
new file mode 100644
index 0000000..5b7849d
--- /dev/null
+++ b/Modules/ado/personal/p/pcm3.ado
@@ -0,0 +1,1005 @@
+*! Version 3.5 16September2019
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : September 16th, 2019 [Jean-Benoit Hardouin] : Correction of bugs
+*
+*
+*
+* Jean-benoit Hardouin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm3, rclass 
+syntax varlist(min=2 numeric) [iweight] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(name) GENINF(name) postpce]
+
+qui count
+local nbobs=r(N)
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+local modcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local modcont (`modcont'->T)
+}
+
+local modcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local modcat (`modcat'->T)
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' se`genlt' `geninf'
+	if _rc!=0 {
+	    di in red "The variables `genlt', se`genlt' and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+forvalues i=1/`nbitems' {
+     qui su ``i''
+	 if `r(min)'!=`modamin' {
+	     local modamin=r(min)
+		 local pbmin `pbmin' ``i''
+	 }
+	 if `r(max)'>`modamax' {
+	     local modamax=r(max)
+	 }
+	 local modamax``i''=r(max)
+	 if "`rsm'"=="" {
+	    local nbdiff=`nbdiff'+`modamax``i'''
+	 }
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count
+local nbind=r(N)
+*set trace on
+local code
+forvalues k=1/`modamax' {
+   local code`k'
+   forvalues i=1/`nbitems' {
+       if `k'<=`modamax``i''' {
+	      local code`k' `code`k'' `k'.``i''
+	   }
+   }
+   local code`k' (`code`k''<-T@`k')
+   local code `code' `code`k''
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	local t=1
+	local constraints
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax``i''' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				constraint `t' [`k'.``i'']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+}
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+
+if "`rsm'"!="" {
+   local t=1
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       constraint `t'   [`=`k'-1'.``i'']_cons-[`k'.``i'']_cons+[1.``i'']_cons=[`=`k'-1'.`1']_cons-[`k'.`1']_cons+[1.`1']_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')"
+local qui qui
+if "`model'"!="" {
+   local qui
+}
+`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent',latent se(`selatent')
+if "`genlt'"!="" {
+    gen `genlt'=`latent'
+	gen se`genlt'=`selatent'
+}
+set seed 123456
+qui gen `latent2'=`latent'+invnorm(uniform())*`selatent'
+qui genscore `varlist',score(`score')
+qui gengroup `latent',newvariable(`group') continuous
+qui levelsof `group'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+3',.)
+forvalues g=1/`nbgroups' {
+    matrix `groups'[`g',`=`nbitems'+3']=0
+    forvalues i=1/`nbitems' {
+	*tab ``i'' if `group'==`g'
+        qui count if ``i''!=.&`group'==`g'
+		local n=r(N)
+		if `n'>0 {
+			qui su ``i'' if `group'==`g'
+			matrix `groups'[`g',`i']=r(mean)
+			matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+		}
+		else {
+			matrix `groups'[`g',`i']=.
+			matrix `groups'[`g',`=`nbitems'+3']=.
+		}		
+    }
+	qui su `latent' if `group'==`g'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'==`g'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+}
+*matrix list `groups'
+	
+qui count if `score'!=.
+local nbobsssmd=r(N)	
+	
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i'':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i'':_cons]
+	qui lincom -_b[1.``i'':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+    *qui matrix `vardiff'[`t',`t']=_se[1.``i'':_cons]^2
+	local rn `rn' 1.``i''
+	local ++t
+	local sum _b[1.``i'':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax``i''' {
+			local sum "_b[`k'.``i'':_cons]-(`sum')"
+			di "``i'' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i'':_cons]-_b[`k'.``i'':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1':_cons]-_b[`k'.`1':_cons]+_b[1.`1':_cons]
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES ET LA VARIANCE
+*************************************************************************************************************/
+
+tempname covariates
+qui matrix `covariates'=J(`=`nbpar'+1',6,.)
+
+*set trace on
+if "`continuous'"!=""|"`categorical'"!="" {
+    qui lincom _b[/var(e.T)]
+}
+else {
+    qui lincom _b[/var(T)]
+}
+qui matrix `covariates'[1,1]=`r(estimate)'
+qui matrix `covariates'[1,2]=`r(se)'
+qui matrix `covariates'[1,3]=`r(z)'
+qui matrix `covariates'[1,4]=`r(p)'
+qui matrix `covariates'[1,5]=`r(lb)'
+qui matrix `covariates'[1,6]=`r(ub)'
+
+local t=2
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+* matrix list `covariates'
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 73}"
+	di  as text _col(60) "<--95% IC -->"
+	di  "Items" _col(60) "Lower" _col(68) "Upper"
+	di "parameters" _col(13) "category" _col(25) "Estimate" _col(37) "s.e." _col(48) "z" _col(56) "p" _col(59) " Bound" _col(68) "Bound"
+	di "{hline 73}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax``i''' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 73}"
+	local t=1
+	local n: word count  Variance `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of Variance `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		*local ++t
+	}
+	di as text "{hline 73}"
+	/*
+	di
+	qui su `latent'
+	qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])^2)
+	di as text "PSI:" as result %4.2f `PSI' 
+	di
+	*/
+
+	di
+	qui su `latent'
+	tempvar se2latent
+	qui gen `se2latent'=(`selatent')^2
+	qui su `se2latent'
+	di as text "Mean squared std error of the latent variable: " as result %4.2f `=(`r(mean)')'
+	di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`r(mean)'))'
+	local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`r(mean)'))
+	di as text "PSI: " as result %4.2f `PSI' _c
+	if "`continuous'"!=""|"`categorical'"!="" {
+		di as text " (without adjustment on covariates)"
+	}
+	else {
+		di
+	}
+	di
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+
+tempname fit
+qui matrix `fit'=J(`nbitems',4,.)
+matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+matrix rownames `fit'=`varlist'
+*matrix list `fit'
+
+tempvar Tcum TInf cum
+qui gen `Tcum'=0
+qui gen `TInf'=0
+if "`postpce'"=="" {
+	di as text "{hline 90}"
+	di as text _col(60) "<---  Standardized   --->"
+	di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+	di as text "{hline 90}"
+	di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+	di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+	di as text "{hline 90}"
+}
+*set trace on
+local chi2=0
+local chi2_old=0
+forvalues g=1/`nbgroups' {
+   local chi2_g`g'=0
+   local chi2_old_g`g'=0
+}
+forvalues i=1/`nbitems' {
+	if "`rsm'"=="" {
+		local mm=`modamax``i'''
+	}
+	else {
+		local mm `modamax'
+	}	
+	tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+	tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+	local d=1
+	local d_old=1
+	qui gen `cum``i'''=0
+	qui gen `cum_old``i'''=0
+	forvalues k=1/`mm' {
+		local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+		local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
+	}
+	qui gen `c0_``i'''=1/(`d')
+	qui gen `c_old0_``i'''=1/(`d_old')
+	forvalues k=1/`mm' {
+		tempvar c`k'_``i'' c_old`k'_``i''
+		qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
+		qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
+		qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
+		qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
+	}
+	qui gen `Inf``i'''=0
+	qui gen `Inf_old``i'''=0
+	qui gen `C``i'''=0
+	forvalues k=0/`mm' {
+		qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
+		qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
+		qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
+	}
+	qui count if ``i''!=.
+	local n``i''=r(N)
+	
+	qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
+	qui su `C2``i'''
+	local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+	qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
+	qui su `C3``i'''
+	local n=r(sum)
+	qui su `Inf``i'''
+	local d=r(sum)
+	local q2i``i''=`n'/((`d')^2)
+	
+	//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+	
+	qui replace `Tcum'=`Tcum'+`cum``i'''
+	qui replace `TInf'=`TInf'+`Inf``i'''
+	qui gen `y``i'''=``i''-`cum``i'''
+	qui gen `y_old``i'''=``i''-`cum_old``i'''
+	qui gen `y2``i'''=(`y``i''')^2
+	qui gen `y2_old``i'''=(`y_old``i''')^2
+	qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
+	local chi2_``i''=0
+	local chi2_old_``i''=0
+	forvalues g=1/`nbgroups' {
+		qui su `y2``i''' if `group'==`g'
+		local n=r(sum)
+		qui su ``i'' if `group'==`g'
+		local n1=r(sum)
+		qui su `cum``i''' if `group'==`g'
+		local n2=r(sum)
+		qui su `Inf``i''' if `group'==`g'
+		local d=r(sum)
+		*di "chi2_`g'_``i''=`chi2'+(`n1'-`n2')^2/(`d')"
+		local chi2=`chi2'+(`n1'-`n2')^2/(`d')
+		local chi2_``i''=`chi2_``i'''+(`n1'-`n2')^2/(`d')
+		local chi2_g`g'=`chi2_g`g''+(`n1'-`n2')^2/(`d')
+		qui su `y2_old``i''' if `group'==`g'
+		local n_old=r(sum)
+		qui su ``i'' if `group'==`g'
+		local n1_old=r(sum)
+		qui su `cum_old``i''' if `group'==`g'
+		local n2_old=r(sum)
+		qui su `Inf_old``i''' if `group'==`g'
+		local d_old=r(sum)
+		local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+		local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+		local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+	}
+	*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+	*su `z``i'''
+	label variable `z``i''' "Standardized residuals associated to ``i''"
+	label variable `latent' "Latent trait"
+	*set trace on
+	if  "`graphs'"!=""&"`graphitems'"=="" {
+		if "`filesave'"!="" {
+			local fs saving("`dirsave'//residuals_``i''",replace)
+		}
+		qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+	}
+	*set trace off
+	qui gen `z2``i'''=(`z``i''')^2
+	qui su `z2``i'''
+	local OUTFIT``i''=`r(mean)'
+	qui matrix `fit'[`i',1]=`OUTFIT``i'''
+	local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+	qui matrix `fit'[`i',3]=`OUTFITs``i'''
+	qui su `Inf``i''' if ``i''!=.
+	local sumw``i''=r(sum)
+	qui gen `i``i'''=`Inf``i'''*`z2``i''' 
+	qui su `i``i''' if ``i''!=.
+	local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+	qui matrix `fit'[`i',2]=`INFIT``i'''
+	local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+	qui matrix `fit'[`i',4]=`INFITs``i'''
+	if "`postpce'"=="" {
+		di abbrev("``i''",19) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+	}
+}
+if "`postpce'"=="" {
+	di as text "{hline 90}"
+	di as text "*: As suggested by Wright (Smith, 1998)
+	di as text "**: As suggested by Bond and Fox (2007)
+}
+if "`geninf'"!="" {
+   gen `geninf'=`TInf'
+}
+
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Itération `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1')
+		`qui' pcm `varlist' [iweight=`sinf'],diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1')
+		qui su `ecart_`it''
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+
+if "`graphs'"!="" {
+
+	tempfile savefile
+	qui save `savefile'
+
+	qui clear
+	qui set obs 2000
+	qui gen u=(_n-1000)/250
+	qui gen Tcum=0
+	qui gen TInf=0
+	forvalues i=1/`nbitems' {
+	   local scatteri`i' 
+	   forvalues g=1/`nbgroups' {
+		  local x=`groups'[`g',`=`nbitems'+1']
+		  local y=`groups'[`g',`i']
+		  local s1=`groups'[`g',`=`nbitems'+2']
+		  local seuil=30
+		  local s vtiny
+		  *set trace on
+		  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+		      if `s1'>`seuil' {
+			     local s `lab'
+			  }
+			  local seuil=`seuil'+10
+		  }
+		  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+		*set trace off
+		}
+		local d=1
+		qui gen cum``i''=0
+		*set trace on
+		if "`rsm'"=="" {
+			local mm=`modamax``i'''
+		}
+		else {
+			local mm `modamax'
+		}	
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+		}
+		qui gen c0_``i''=1/(`d')
+		label variable c0_``i'' "Pr(``i''=0)"
+		forvalues k=1/`mm' {
+			qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+			qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+			label variable c`k'_``i'' "Pr(``i''=`k')"
+		}
+		qui gen Inf``i''=0
+		forvalues k=1/`mm' {
+			qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+		}
+		if "`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fsc saving("`dirsave'//CCC_``i''",replace)
+				local fsi saving("`dirsave'//ICC_``i''",replace)
+			}
+		    qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+		    qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+		}
+		qui replace Tcum=Tcum+cum``i''
+		qui replace TInf=TInf+Inf``i''	
+		label variable Inf``i'' "``i''"
+	}
+	if "`filesave'"!="" {
+		local fst saving("`dirsave'//TCC",replace)
+		local fsteo saving("`dirsave'//TCCeo",replace)
+		local fsi saving("`dirsave'//ICC",replace)
+		local fsti saving("`dirsave'//TIC",replace)
+		local fsm saving("`dirsave'//map",replace)
+	}
+	qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+	qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+	qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+
+	local scatteri
+	forvalues g=1/`nbgroups' {
+		local x=`groups'[`g',`=`nbitems'+1']
+		local y=`groups'[`g',`=`nbitems'+3']
+		  local s1=`groups'[`g',`=`nbitems'+2']
+		  local seuil=30
+		  local s vtiny
+		  *set trace on
+		  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+		      if `s1'>`seuil' {
+			     local s `lab'
+			  }
+			  local seuil=`seuil'+10
+		  }
+		local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+	}
+	qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+	
+	
+	
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+*set trace on
+	gen eff=0
+	local effmax=0
+	forvalues g=1/`nbgroups' {
+	    local eff=`groups'[`g',`=`nbitems'+2']
+		if `groups'[`g',`=`nbitems'+2']>`effmax' {
+		   local effmax=`groups'[`g',`=`nbitems'+2']
+		}
+	    local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
+	    *di "replace eff=`eff' if round(u,0.004)==`lat'"
+	    qui replace eff=`eff' if round(u,0.004)==`lat'
+    }
+	gen density=normalden(u)*sqrt(`covariates'[1,1])
+	label variable eff "Frequencies"
+	label variable u "Latent trait"
+	label variable TInf "Information curve"
+	label variable density "Density function of the latent trait"
+	local scatteri
+	qui su u if eff!=0
+	*set trace on
+	local floor=floor(`r(min)')
+	local ceil=ceil(`r(max)')
+	forvalues i=1/`nbitems' {
+	   local color`i':word `i' of `color'
+	   local y=-`i'*`effmax'/`nbitems'
+	   forvalues l=1/`modamax' {
+		   local x=`diffmat'[`i',`l']
+		   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+		   if `x'<`floor' {
+		      local floor=floor(`x')
+		   }
+		   if `x'>`ceil'&`x'!=. {
+		      local ceil=ceil(`x')
+		   }
+	   }
+	   local scatteri `scatteri' || scatteri `y' `floor' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+	}
+	qui su eff
+	local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+	qui su TInf
+	local maxi=ceil(`r(max)')
+	qui su density
+    local maxd=ceil(`r(max)')
+	qui drop if u<`floor'|u>`ceil'
+	qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(`floor'(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3))    `scatteri'  , name(map,replace) ytitle("Frequencies")  ylabel(-`maxi'(`=`maxi'/5')`maxi' ,axis(2)) ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait") xtitle("Latent trait") `fsm'
+
+
+	qui clear
+	qui use `savefile'
+
+}
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+
+di
+di as text "{hline 57}"
+di _col(31) "Latent Variable" _col(50) "Expected"
+di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score"
+di as text "{hline 57}"
+*set trace on
+forvalues g=1/`nbgroups' {
+    qui count if `group'==`g' 
+	local eff`g'=r(N)
+	qui count if `score'!=.&`group'==`g'
+	local n=r(N)
+	di as text "`g' (n=" as result `eff`g'' as text ")" _c
+	if `n'>0 {
+		qui su `score' if `group'==`g'
+		local scoremin`g'=`r(min)'
+		local scoremax`g'=`r(max)'
+		forvalues s=`scoremin`g''/`scoremax`g'' {
+			qui count if `group'==`g'&`score'==`s'
+			local eff=r(N)
+			qui su `latent' if `group'==`g'&`score'==`s'
+			local mean=r(mean)
+			qui su `selatent' if `group'==`g'&`score'==`s'
+			local se=r(mean)
+			qui su `Tcum' if `group'==`g'&`score'==`s'
+			local exp=r(mean)
+			if `eff'>0 {
+			   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+			}
+		}
+	}
+	qui count if `group'==`g'&`score'==.
+	local eff=r(N)
+	qui su `latent' if `group'==`g'&`score'==.
+	local mean=r(mean)
+	qui su `selatent' if `group'==`g'&`score'==.
+	local se=r(mean)
+	qui su `Tcum' if `group'==`g'&`score'==.
+	local exp=r(mean)
+	if `eff'>0 {
+		di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+	}
+    di as text "{hline 57}"
+}
+	
+
+
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin
+	putdocx paragraph
+	putdocx text ("General informations") , bold underline font(,14) smallcaps
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph
+	putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	qui putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx paragraph
+	putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
+	qui putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm44.ado b/Modules/ado/personal/p/pcm44.ado
new file mode 100644
index 0000000..982c0b1
--- /dev/null
+++ b/Modules/ado/personal/p/pcm44.ado
@@ -0,0 +1,1517 @@
+*! Version 4.4 29September2021
+*! Jean-Benoit Hardouin, Myriam Blanchin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
+* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
+* Version 4.1: September 15th, 2019 [Jean-Benoit Hardouin]: correction of a small bug in the outputs
+* Version 4.2: September 27th, 2019 [Jean-Benoit Hardouin] : EQUATING
+* Version 4.3: November 8th, 2019 [Jean-Benoit Hardouin] : add a constant when difficulty parameters are fixed
+* Version 4.4: September 29th, 2021 [Myriam Blanchin] : Correction of a bug in longitudinal option
+*
+* Jean-benoit Hardouin, Myriam Blanchin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr myriam.blanchin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm44, rclass 
+syntax varlist(min=2 numeric) [iweight] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) VARiance(real -1) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(string) GENINF(string) REPlace postpce visit(varname) id(varname) eqset1(varlist) eqset2(varlist) EQGraph minsize(int 30)]
+
+preserve
+
+/*************************************************************************************************************
+QUELQUES TESTS
+*************************************************************************************************************/
+
+if `variance'!=-1&`variance'<=0 {
+	di in red "The -variance- option cannot be negative"
+	exit 198
+}
+if `variance'!=-1&"`visit'"!="" {
+	di in red "The -variance- and -visit- options cannot be used simultaneously."*
+	exit 198
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' se`genlt' `geninf'
+	if _rc!=0&"`replace'"=="" {
+	    di in red "The variables `genlt', se`genlt' and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+	if _rc!=0&"`replace'"!="" {
+	    qui drop `genlt' se`genlt' `geninf' 
+	}
+}
+if ("`eqset1'"!=""&"`eqset2'"=="")|("`eqset1'"==""&"`eqset2'"!="") {
+    di in red "The two options -eqset1- and -eqset2- must be used simultaneously"
+	exit 198
+}
+if ("`eqset1'"!=""&"`graphs'"!="") {
+    di in red "The two options -eqset1- and -graph- cannot be used simultaneously"
+	exit 198
+}
+
+
+
+
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+if "`visit'"!=""{
+	if "`id'"==""{
+		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
+		exit 198
+	}
+	qui levelsof `visit'
+	local levelsofv `r(levels)'
+	local nbvisits=r(r)
+	local timemin: word 1 of `levelsofv'
+	local timemax: word `nbvisits' of `levelsofv'
+	if `timemax'>5{
+		di as error "You must use a discrete time variable (-visit- option) with less than 5 measurement occasions"
+		error 198
+	}
+	if `timemin'!=1{
+		di as error "You must use a -visit- variable coded at 1 for the first visit"
+		error 198
+	}
+	qui reshape wide `varlist', i(`id') j(`visit')
+	local multivisit=1
+}
+else {
+	local timemax=1
+	foreach i in `varlist' {
+	   *rename `i' `i'1
+	}
+	local multivisit
+}
+qui count
+local nbobs=r(N)
+
+local timelist
+forvalues t=1/`timemax'{
+	local timelist `timelist' T`t'
+}
+
+local modcont
+local premodcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local premodcont (`modcont'->T1)
+	local modcont (`modcont'->`timelist')
+}
+
+local modcat
+local premodcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local premodcat (`modcat'->T1)
+	local modcat (`modcat'->`timelist')
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+forvalues i=1/`nbitems' {
+	local modamax`i'=1
+	local modamax``i''=1
+	if `timemax'>1 {
+		forvalues t=1/`timemax'{
+			 *qui replace ``i'`t''=``i'`t''-`min' 
+			 qui su ``i''`t'
+			 if `r(min)'!=`modamin' {
+				 local modamin=r(min)
+				 local pbmin `pbmin' ``i'`t''
+			 }
+			 if `r(max)'>`modamax' {
+				 local modamax=r(max)
+			 }
+			 if `r(max)'>`modamax`i'' {
+				local modamax`i'=r(max)
+			}
+		}
+	}
+	else {
+		qui su ``i''
+		if `r(min)'!=`modamin' {
+		    local modamin=r(min)
+			local pbmin `pbmin' ``i''
+		}
+		if `r(max)'>`modamax' {
+			local modamax=r(max)
+		}
+		if `r(max)'>`modamax`i'' {
+			local modamax`i'=r(max)
+			local modamax``i''=r(max)
+		}
+	}
+	if "`rsm'"=="" {
+		local nbdiff=`nbdiff'+`modamax`i''
+	}
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count
+local nbind=r(N)
+*set trace on
+local code
+local precode
+if `timemax'>1 {
+	forvalues k=1/`modamax' {
+	   forvalues t=1/`timemax'{
+			local code`k'
+		   forvalues i=1/`nbitems' {
+			   if `k'<=`modamax`i'' {
+				  local code`k' `code`k'' `k'.``i''`t'
+			   }
+		   }
+		   local code`k' (`code`k''<-T`t'@`k')
+		   if `t'==1{
+				local precode `precode' `code`k''
+		   }
+		   local code `code' `code`k''
+		}
+	}
+}
+else {
+	forvalues k=1/`modamax' {
+		local code`k'
+		forvalues i=1/`nbitems' {
+			if `k'<=`modamax`i'' {
+				local code`k' `code`k'' `k'.``i''
+			}
+		}
+		local code`k' (`code`k''<-T1@`k')
+		local precode `precode' `code`k''
+		local code `code' `code`k''
+	}
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+local t=1
+local constraints
+local codemean
+local codevar
+local codecov
+forvalues j=2/`timemax'{
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			qui constraint `t' [`k'.``i''`j']_cons=[`k'.``i''`multivisit']_cons
+			local constraints `constraints' `t'
+			local ++t
+			
+		}
+	}	
+	if "`continuous'"=="" &  "`categorical'"==""{
+		local codemean `codemean' T`j'@m`j'
+		local codevar `codevar' T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' T`l'*T`j'@cov`l'`j'
+		}
+	}
+	else{
+		local codevar `codevar' e.T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
+		}	
+	}
+}
+if `timemax'>1{
+	if "`continuous'"=="" &  "`categorical'"==""{	
+		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
+	}
+	else{
+		local codelg var(e.T1@v1 `codevar') cov(`codecov')
+	}
+}
+else {
+    local constrvar
+    if `variance'>0 {
+		if "`continuous'"=="" &  "`categorical'"==""{	
+			local constrvar var(T1@`variance') 
+		}
+		else{ 
+			*local constrvar var(e.T1@`variance') 
+		}
+	}
+}
+
+local fixedmean
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				qui constraint `t' [`k'.``i''`multivisit']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+	if "`continuous'"=="" &  "`categorical'"=="" {	
+		local fixedmean mean(T1) 
+	}
+	else{
+		local fixedmean 
+	}
+}
+
+
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+if "`rsm'"!="" {
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       qui constraint `t'   [`=`k'-1'.``i''`multivisit']_cons-[`k'.``i''`multivisit']_cons+[1.``i''`multivisit']_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
+if "`model'"!="" {
+    local qui
+}
+else {
+	local qui qui
+}
+if `timemax'==1{
+   di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'"
+   `qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+   *qui gen un=1
+   *`qui' gsem `code' (i.group un->T) ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+}
+else{
+    di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
+    `qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') constraint(`constraints') 
+     matrix esti_B = e(b)
+    di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)"
+    `qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
+}
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2 miss
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent'*,latent se(`selatent'*)
+
+if "`genlt'"!="" {
+	if `timemax'==1 {
+		qui gen `genlt'=`latent'`i'
+		qui gen se`genlt'=`selatent'`i'
+	}
+	forvalues t=2/`timemax' {
+		qui gen `genlt'`t'=`latent'`t'
+		qui gen se`genlt'`t'=`selatent'`t'
+	}
+}
+
+set seed 123456
+if `timemax'>1 {
+	forvalues t=1/`timemax'{
+		qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t'
+		local listit 
+		forvalues i=1/`nbitems' {
+			local listit `listit' ``i''`t'
+		}
+		qui genscore `listit',score(`score'`t')
+		qui gengroup `latent'`t',newvariable(`group'`t') continuous minsize(`minsize')
+	}
+}
+else {
+	qui gen `latent2'=`latent'+invnorm(uniform())*`selatent'
+	local listit 
+	forvalues i=1/`nbitems' {
+		local listit `listit' ``i''
+	}
+	qui genscore `listit',score(`score')
+	qui gengroup `latent',newvariable(`group') continuous minsize(`minsize')
+}
+
+/*time 1 only*/
+qui levelsof `group'`multivisit'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+3',.)
+forvalues g=1/`nbgroups' {
+	matrix `groups'[`g',`=`nbitems'+3']=0
+	forvalues i=1/`nbitems' {
+			qui count if ``i''`multivisit'!=.&`group'`multivisit'==`g'
+			local n=r(N)
+			if `n'>0 {
+				qui su ``i''`multivisit' if `group'`multivisit'==`g'
+				matrix `groups'[`g',`i']=r(mean)
+				matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+			}
+			else {
+				matrix `groups'[`g',`i']=.
+				matrix `groups'[`g',`=`nbitems'+3']=.
+			}		
+	}
+	qui su `latent'`multivisit' if `group'`multivisit'==`g'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'`multivisit'==`g'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+}
+
+/*number of non-missing on all time points*/
+egen `miss'=rowmiss(`score'*)
+qui count if `miss'==0
+local nbobsssmd=r(N)
+drop `miss'	
+
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i''`multivisit':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i''`multivisit':_cons]
+	qui lincom -_b[1.``i''`multivisit':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+	local rn `rn' 1.``i''`multivisit'
+	local ++t
+	local sum _b[1.``i''`multivisit':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax`i'' {
+			local sum "_b[`k'.``i''`multivisit':_cons]-(`sum')"
+			*di "``i''`multivisit' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i''`multivisit':_cons]-_b[`k'.``i''`multivisit':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''`multivisit'
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1'`multivisit':_cons]-_b[`k'.`1'`multivisit':_cons]+_b[1.`1'`multivisit':_cons] /*``i'' instead of `i'?*/
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
+*************************************************************************************************************/
+tempname covariates
+local nbcov=0
+forvalues j=2/`timemax'{
+	local nbcov=`nbcov'+`j'-1
+}
+qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)
+
+*set trace on
+local t=1
+
+
+forvalues j=1/`=`timemax'-1'{
+	forvalues k=`=`j'+1'/`timemax'{
+		if "`categorical'"=="" & "`continuous'"=="" {
+			if `j'==1{
+				qui lincom [/]mean(T`k')
+			}
+			else{
+				qui lincom [/]mean(T`k')-[/]mean(T`j')
+			}
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+		else{
+			if "`categorical'"!=""{
+				local first=0 
+				foreach l in `levelsof`cat1'' {
+					if `first'==0 {
+						local ++first
+					}
+					else{
+						if `first'==1 {
+							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
+							qui matrix `covariates'[`t',1]=`r(estimate)'
+							qui matrix `covariates'[`t',2]=`r(se)'
+							qui matrix `covariates'[`t',3]=`r(z)'
+							qui matrix `covariates'[`t',4]=`r(p)'
+							qui matrix `covariates'[`t',5]=`r(lb)'
+							qui matrix `covariates'[`t',6]=`r(ub)'
+							local ++t
+							local ++first
+						}
+					}
+				}
+			}
+			else{
+				qui lincom [T`k']`cont1'-[T`j']`cont1'
+				qui matrix `covariates'[`t',1]=`r(estimate)'
+				qui matrix `covariates'[`t',2]=`r(se)'
+				qui matrix `covariates'[`t',3]=`r(z)'
+				qui matrix `covariates'[`t',4]=`r(p)'
+				qui matrix `covariates'[`t',5]=`r(lb)'
+				qui matrix `covariates'[`t',6]=`r(ub)'
+				local ++t
+			}		
+		}
+	}
+}	
+		
+forvalues j=1/`timemax'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		qui lincom _b[/var(e.T`j')]
+	}
+	else {
+		qui lincom _b[/var(T`j')]
+	}
+	qui matrix `covariates'[`t',1]=`r(estimate)'
+	qui matrix `covariates'[`t',2]=`r(se)'
+	qui matrix `covariates'[`t',3]=`r(z)'
+	qui matrix `covariates'[`t',4]=`r(p)'
+	qui matrix `covariates'[`t',5]=`r(lb)'
+	qui matrix `covariates'[`t',6]=`r(ub)'
+	local ++t
+}
+forvalues j=1/`=`timemax'-1'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(e.T`j',e.T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+	else{
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(T`j',T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+}
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+*matrix list `covariates'
+
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 73}"
+	di  as text _col(60) "<--95% IC -->"
+	di  "Items" _col(60) "Lower" _col(68) "Upper"
+	di "parameters" _col(13) "category" _col(25) "Estimate" _col(37) "s.e." _col(48) "z" _col(56) "p" _col(59) " Bound" _col(68) "Bound"
+	di "{hline 73}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax`i'' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(28) %5.2f `diff'[`t',1]  _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 73}"
+	local t=1
+	local listmoy
+	local listvar
+	local listcov
+	forvalues j=1/`timemax'{
+		local listvar `listvar' Variance_T`j'
+		forvalues k=`=`j'+1'/`timemax'{
+			local listcov `listcov' Cov_T`j'_T`k'
+		}
+		forvalues k=`=`j'+1'/`timemax'{
+			local listmoy `listmoy' Mean_diff_T`j'_T`k'
+		}
+	}
+	local n: word count `listmoy' `listvar' `listcov' `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of `listmoy' `listvar' `listcov' `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `covariates'[`t',1]  _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		*local ++t
+	}
+	di as text "{hline 73}"
+	if "`visit'"==""{
+		di
+		qui su `latent'
+		*qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])+(`r(sd)')^2)
+		*di as text "Variance of the estimated latent variable: " as result %4.2f `=(`r(sd)')^2'
+        tempvar se2latent
+		qui gen `se2latent'=(`selatent')^2
+		qui su `se2latent'
+		di as text "Mean squared std error of the latent variable: " as result %4.2f `=(`r(mean)')'
+		di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`r(mean)'))'
+		local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`r(mean)'))
+		di as text "PSI: " as result %4.2f `PSI' _c
+		if "`continuous'"!=""|"`categorical'"!="" {
+		    di as text " (without adjustment on covariates)"
+	    }
+		else {
+		    di
+		}
+		di
+	}
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+if "`visit'"==""{
+	tempname fit
+	qui matrix `fit'=J(`nbitems',4,.)
+	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+	matrix rownames `fit'=`varlist'
+	*matrix list `fit'
+
+	tempvar Tcum TInf cum
+	qui gen `Tcum'=0
+	qui gen `TInf'=0
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text _col(60) "<---  Standardized   --->"
+		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+		di as text "{hline 90}"
+		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "{hline 90}"
+	}
+	*set trace on
+	local chi2=0
+	local chi2_old=0
+	forvalues g=1/`nbgroups' {
+	   local chi2_g`g'=0
+	   local chi2_old_g`g'=0
+	}
+	forvalues i=1/`nbitems' {
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+		local d=1
+		local d_old=1
+		qui gen `cum``i'''=0
+		qui gen `cum_old``i'''=0
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+			local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
+		}
+		qui gen `c0_``i'''=1/(`d')
+		qui gen `c_old0_``i'''=1/(`d_old')
+		forvalues k=1/`mm' {
+			tempvar c`k'_``i'' c_old`k'_``i''
+			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
+			qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
+			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
+			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
+		}
+		qui gen `Inf``i'''=0
+		qui gen `Inf_old``i'''=0
+		qui gen `C``i'''=0
+		forvalues k=0/`mm' {
+			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
+			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
+			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
+		}
+		qui count if ``i''!=.
+		local n``i''=r(N)
+		
+		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
+		qui su `C2``i'''
+		local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
+		qui su `C3``i'''
+		local n=r(sum)
+		qui su `Inf``i'''
+		local d=r(sum)
+		local q2i``i''=`n'/((`d')^2)
+		
+		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+		
+		qui replace `Tcum'=`Tcum'+`cum``i'''
+		qui replace `TInf'=`TInf'+`Inf``i'''
+		qui gen `y``i'''=``i''-`cum``i'''
+		qui gen `y_old``i'''=``i''-`cum_old``i'''
+		qui gen `y2``i'''=(`y``i''')^2
+		qui gen `y2_old``i'''=(`y_old``i''')^2
+		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
+		local chi2_``i''=0
+		local chi2_old_``i''=0
+		forvalues g=1/`nbgroups' {
+			qui su `y2``i''' if `group'==`g'
+			local n=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1=r(sum)
+			qui su `cum``i''' if `group'==`g'
+			local n2=r(sum)
+			qui su `Inf``i''' if `group'==`g'
+			local d=r(sum)
+			*qui count if `group'==`g'
+			*local eff=r(N)
+			*di "chi2_`g'_``i''=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')"
+			local chi2=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_``i''=`chi2_``i'''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_g`g'=`chi2_g`g''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			qui su `y2_old``i''' if `group'==`g'
+			local n_old=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1_old=r(sum)
+			qui su `cum_old``i''' if `group'==`g'
+			local n2_old=r(sum)
+			qui su `Inf_old``i''' if `group'==`g'
+			local d_old=r(sum)
+			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+		}
+		*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+		*su `z``i'''
+		label variable `z``i''' "Standardized residuals associated to ``i''"
+		label variable `latent' "Latent trait"
+		*set trace on
+		if  "`graphs'"!=""&"`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fs saving("`dirsave'//residuals_``i''",replace)
+			}
+			qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+		}
+		*set trace off
+		qui gen `z2``i'''=(`z``i''')^2
+		qui su `z2``i'''
+		local OUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',1]=`OUTFIT``i'''
+		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `Inf``i''' if ``i''!=.
+		local sumw``i''=r(sum)
+		qui gen `i``i'''=`Inf``i'''*`z2``i''' 
+		qui su `i``i''' if ``i''!=.
+		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+		qui matrix `fit'[`i',2]=`INFIT``i'''
+		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		qui matrix `fit'[`i',4]=`INFITs``i'''
+		if "`postpce'"=="" {
+			di abbrev("``i''",19) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+		}
+	}
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text "*: As suggested by Wright (Smith, 1998)
+		di as text "**: As suggested by Bond and Fox (2007)
+	}
+	if "`geninf'"!="" {
+	    gen `geninf'=`TInf'
+	}
+}
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Itération `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1')
+		`qui' pcm `varlist' [iweight=`sinf'],diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1')
+		qui su `ecart_`it''
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+if "`visit'"==""{
+	if "`graphs'"!="" {
+
+		tempfile savefile
+		qui save `savefile'
+
+		*qui clear
+		qui drop _all
+		
+		qui set obs 2000
+		qui gen u=(_n-1000)/250
+		qui gen Tcum=0
+		qui gen TInf=0
+		forvalues i=1/`nbitems' {
+		   local scatteri`i' 
+		   forvalues g=1/`nbgroups' {
+			  local x=`groups'[`g',`=`nbitems'+1']
+			  local y=`groups'[`g',`i']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			*set trace off
+			}
+			local d=1
+			qui gen cum``i''=0
+			*set trace on
+			if "`rsm'"=="" {
+				local mm=`modamax`i''
+			}
+			else {
+				local mm `modamax'
+			}	
+			forvalues k=1/`mm' {
+				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+			}
+			qui gen c0_``i''=1/(`d')
+			label variable c0_``i'' "Pr(``i''=0)"
+			forvalues k=1/`mm' {
+				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+				label variable c`k'_``i'' "Pr(``i''=`k')"
+			}
+			qui gen Inf``i''=0
+			forvalues k=1/`mm' {
+				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+			}
+			if "`graphitems'"=="" {
+				if "`filesave'"!="" {
+					local fsc saving("`dirsave'//CCC_``i''",replace)
+					local fsi saving("`dirsave'//ICC_``i''",replace)
+				}
+				qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+				qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+			}
+			qui replace Tcum=Tcum+cum``i''
+			qui replace TInf=TInf+Inf``i''	
+			label variable Inf``i'' "``i''"
+		}
+		if "`filesave'"!="" {
+			local fst saving("`dirsave'//TCC",replace)
+			local fsteo saving("`dirsave'//TCCeo",replace)
+			local fsi saving("`dirsave'//ICC",replace)
+			local fsti saving("`dirsave'//TIC",replace)
+			local fsm saving("`dirsave'//map",replace)
+		}
+		qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+		qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+		qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+
+		local scatteri
+		forvalues g=1/`nbgroups' {
+			local x=`groups'[`g',`=`nbitems'+1']
+			local y=`groups'[`g',`=`nbitems'+3']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+		}
+		qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+	
+	
+	
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+	*set trace on
+		gen eff=0
+		local effmax=0
+		forvalues g=1/`nbgroups' {
+			local eff=`groups'[`g',`=`nbitems'+2']
+			if `groups'[`g',`=`nbitems'+2']>`effmax' {
+			   local effmax=`groups'[`g',`=`nbitems'+2']
+			}
+			local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
+			*di "replace eff=`eff' if round(u,0.004)==`lat'"
+			qui replace eff=`eff' if round(u,0.004)==`lat'
+		}
+		gen density=normalden(u)*sqrt(`covariates'[1,1])
+		label variable eff "Frequencies"
+		label variable u "Latent trait"
+		label variable TInf "Information curve"
+		label variable density "Density function of the latent trait"
+		local scatteri
+		qui su u if eff!=0
+		*set trace on
+		local floor=floor(`r(min)')
+		local ceil=ceil(`r(max)')
+		forvalues i=1/`nbitems' {
+		   local color`i':word `i' of `color'
+		   local y=-`i'*`effmax'/`nbitems'
+		   forvalues l=1/`modamax' {
+			   local x=`diffmat'[`i',`l']
+			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+			   if `x'<`floor' {
+				  local floor=floor(`x')
+			   }
+			   if `x'>`ceil'&`x'!=. {
+				  local ceil=ceil(`x')
+			   }
+		   }
+		   local scatteri `scatteri' || scatteri `y' `floor' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+		}
+		qui su eff
+		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+		qui su TInf
+		local maxi=ceil(`r(max)')
+		qui su density
+		local maxd=ceil(`r(max)')
+		qui drop if u<`floor'|u>`ceil'
+		qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(`floor'(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3))    `scatteri'  , name(map,replace) ytitle("Frequencies")  ylabel(-`maxi'(`=`maxi'/5')`maxi' ,axis(2)) ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait") xtitle("Latent trait") `fsm'
+
+
+		qui use `savefile', clear
+
+	}
+}
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+if "`visit'"==""{
+	*set trace on
+    tempname matscorelt
+	qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)
+	di
+	di as text "{hline 57}"
+	di _col(31) "Latent Variable" _col(50) "Expected"
+	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score"
+	di as text "{hline 57}"
+	forvalues g=1/`nbgroups' {
+		qui count if `group'`multivisit'==`g' 
+		local eff`g'=r(N)
+		qui count if `score'`multivisit'!=.&`group'`multivisit'==`g'
+		local n=r(N)
+		di as text "`g' (n=" as result `eff`g'' as text ")" _c
+		if `n'>0 {
+			qui su `score'`multivisit' if `group'`multivisit'==`g'
+			local scoremin`g'=`r(min)'
+			local scoremax`g'=`r(max)'
+			forvalues s=`scoremin`g''/`scoremax`g'' {
+				qui count if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local eff=r(N)
+				qui su `latent' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local mean=r(mean)
+				qui su `selatent' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local se=r(mean)
+				qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local exp=r(mean)
+				if `eff'>0 {
+				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+				}
+				qui matrix `matscorelt'[`=`s'+1',1]=`s'
+				qui matrix `matscorelt'[`=`s'+1',2]=`mean'
+				qui matrix `matscorelt'[`=`s'+1',3]=`se'
+			}
+		}
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local eff=r(N)
+		qui su `latent' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local mean=r(mean)
+		qui su `selatent' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local se=r(mean)
+		qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local exp=r(mean)
+		if `eff'>0 {
+			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+		}
+		di as text "{hline 57}"
+	}
+	*matrix list `matscorelt'
+}	
+
+/*************************************************************************************************************
+EQUATING
+*************************************************************************************************************/
+*set trace on
+if "`eqset1'"!="" {
+
+    tokenize `eqset1'
+	local nbset1: word count `eqset1'
+	forvalues i=1/`nbset1' {
+	   local eq1_`i':word `i' of `eqset1'
+	   *di "set1 (`nbset1') : `eq1_`i''"
+	}
+	*di "`eqset1'"
+    tokenize `eqset2'
+	local nbset2: word count  `eqset2'
+	*di "`eqset2'"
+	forvalues i=1/`nbset2' {
+	   local eq2_`i':word `i' of `eqset2'
+	   *di "set2  (`nbset2') : `eq2_`i''"
+	}	
+
+
+
+	tempfile fileeq
+	qui save `fileeq',replace
+	forvalues t=1/2{
+		local scoremaxset`t'=0
+		forvalues i=1/`nbset`t'' {
+		    *di "`eq`t'_`i''"
+			*local tmp=""
+			local scoremaxset`t'=`scoremaxset`t''+`modamax`eq`t'_`i'''
+		}
+	}
+	drop _all
+	*set trace on
+	qui set obs `=(`scoremaxset1'+`scoremaxset2'+2)*3'
+	forvalues t=1/2 {
+		qui gen scoreset`t'=.
+		qui gen scoreset`t'm=.
+		qui gen scoreset`t'p=.	
+	}
+	forvalues i=0/`scoremaxset1' {
+	    qui replace scoreset1=`i' in `=`i'+1'
+	    qui replace scoreset1m=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset1p=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	forvalues i=`=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2' {
+	    qui replace scoreset2=`i'-`scoremaxset1'-2 in `i'
+	    qui replace scoreset2m=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset2p=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	local s=0
+	local eqset1b
+	foreach i in `eqset1' {
+		qui gen s1_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s1_`i'_`m'=0 in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'_`m'=1 if scoreset1>`s' in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'=s1_`i'+s1_`i'_`m'
+		   local ++s
+		}
+	    local eqset1b `eqset1b' s1_`i'
+	}
+	local s=0
+	local eqset2b
+	foreach i in `eqset2' {
+		qui gen s2_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s2_`i'_`m'=0 in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'_`m'=1 if scoreset2>`s' in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'=s2_`i'+s2_`i'_`m'
+		   local ++s
+		}
+		local eqset2b `eqset2b' s2_`i'
+	}
+	tokenize `varlist'
+	tempname diffset1 diffset2
+	*matrix list `diffmat'
+	forvalues t=1/2 {
+		qui matrix `diffset`t''=J(`nbset`t'',`modamax',.)
+		local n=1
+		local listset`t'
+		foreach j in `eqset`t'' {
+			forvalues i=1/`nbitems' {
+				if "`j'"=="``i''" {
+					local listset`t' `listset`t'' `i'
+					forvalues m=1/`modamax' {
+						qui matrix `diffset`t''[`n',`m']=`diffmat'[`i',`m']
+					}
+					local ++n						
+				}
+			}
+		}
+	}
+	*matrix list `diffset1'
+	*matrix list `diffset2'
+	local var=`covariates'[1,1]
+	qui gen lt=.
+	*qui gen selt=.
+	forvalues t=1/2 {
+		tempname matscorelt`t'
+		qui pcm `eqset`t'b', diff(`diffset`t'') var(`var') minsize(1)
+		qui matrix `matscorelt`t''=r(matscorelt)
+		*di "matscorelt`t':"
+		*matrix list `matscorelt`t''
+		forvalues i=0/`scoremaxset`t'' {
+			qui replace lt=`matscorelt`t''[`=`i'+1',2] if scoreset`t'==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]+1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'p==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]-1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'm==`i'
+			*qui replace selt=`matscorelt`t''[`=`i'+1',3] if scoreset`t'==`i'
+		}
+		qui ipolate scoreset`t' lt, gen(score`t') epolate
+	}
+	qui ipolate scoreset1 lt, gen(score1bis) epolate
+
+
+	*list
+	forvalues t=1/2 {
+		qui replace score`t'=scoreset`t'm if scoreset`t'm!=.
+		qui replace score`t'=scoreset`t'p if scoreset`t'p!=.
+		qui replace score1=score1bis if score1==.
+		qui replace score`t'=0 if score`t'<0
+		qui replace score`t'=`scoremaxset`t'' if score`t'>`scoremaxset`t''
+	}
+	forvalues t=1/2 {
+		tempname matscore`t'
+		qui matrix `matscore`t''=J(`=`scoremaxset`t''+1',7,.)
+		forvalues s=0/`scoremaxset`t'' {
+		    qui matrix `matscore`t''[`=`s'+1',1]=`s'
+			qui su lt if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',2]=r(mean)
+			qui su lt if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',3]=r(mean)
+			qui su lt if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',4]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',5]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',6]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',7]=r(mean)
+		}
+		matrix colnames `matscore`t'' =score`t' lt lt- lt+ score`=3-`t'' score`=3-`t''- score`=3-`t''+
+		*matrix list `matscore`t''
+		di
+		di "{hline 78}"
+		di "EQUATING SET`t' TO SET`=3-`t''"
+		di "{hline 78}"
+		di "Set`t' : `eqset`t''"
+		di "Set`=3-`t'' : `eqset`=3-`t'''"
+		di "{hline 78}"
+		di            _col(20) "<----- Latent trait ----->" _col(52) "<------- Score `=3-`t'' --------->"
+		di "Score`t'" _col(20) "Estimated" _col(39) "[95%IC]" _col(52) "Estimated" _col(72) "[95%IC]"
+		di "{hline 78}"
+		forvalues s=0/`scoremaxset`t'' {
+			di %4.0f `matscore`t''[`=`s'+1',1] _col(24) %5.2f `matscore`t''[`=`s'+1',2] _col(33) "[" %5.2f `matscore`t''[`=`s'+1',3] ";" %5.2f `matscore`t''[`=`s'+1',4] "]" _col(56) %5.2f `matscore`t''[`=`s'+1',5] _col(66) "[" %5.2f `matscore`t''[`=`s'+1',6] ";" %5.2f `matscore`t''[`=`s'+1',7] "]"
+		}
+		di "{hline 78}"
+		return matrix score`t'_to_`=3-`t''=`matscore`t''
+		if "`eqgraph'"!="" {
+			*twoway (line lt scoreset1) (line lt scoreset2), name(eq1)
+			*twoway (line scoreset1 scoreset2 lt) , name(eq2)
+			*twoway (line score1 scoreset1m scoreset1p score2), name(eq3)
+			*twoway (line score2 scoreset2m scoreset2p score1), name(eq4)
+			twoway (line score`t' score`=3-`t'' if scoreset`=3-`t''!=.) (line score`t' score`=3-`t'' if scoreset`=3-`t''m!=.) (line score`t' score`=3-`t'' if scoreset`=3-`t''p!=.), title("Equating score of the Set `t' from the Set `=3-`t''") ytitle("Score `t'") xtitle("Score `=3-`t''") ylabel(0(1)`scoremaxset`t'') xlabel(0(1)`scoremaxset`=3-`t''') name(eq`t'to`=3-`t'')
+			*twoway (line score2 score1 if scoreset1!=.) (line score2 score1 if scoreset1m!=.) (line score2 score1 if scoreset1p!=.), name(eq6)
+		}
+	}
+	*save prout, replace
+	*clear
+	
+	qui use `fileeq',clear
+}
+
+/*************************************************************************************************************
+RETOUR AU FICHIER INITIAL ET SAUVEGARDE DES NOUVELLES VARIABLES
+*************************************************************************************************************/
+if "`visit'"!="" {
+	tempfile sauv
+	keep `latent'* `selatent'* `id' 
+	qui reshape long `latent' `selatent', i(`id') j(`visit')
+	qui sort `id'	
+	qui save `sauv', replace
+	restore,preserve
+	*su
+	if "`replace'"!=""&("`genlt'"!=""|"`genfit'"!="") {
+    	capture drop `genlt' se`genlt' `geninf'
+    }
+	tempname idorder
+	qui gen `idorder'=_n
+	qui sort `id'
+	qui merge 1:1 `id' `visit' using `sauv'
+	qui drop _merge
+	qui sort `idorder'
+    qui drop `idorder'	
+}
+else {
+	restore,not
+}
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin
+	putdocx paragraph
+	putdocx text ("General informations") , bold underline font(,14) smallcaps
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph
+	putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	qui putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx paragraph
+	putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
+	qui putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+if "`visit'"==""{
+	return matrix matscorelt=`matscorelt'
+}
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcm5.ado b/Modules/ado/personal/p/pcm5.ado
new file mode 100644
index 0000000..44248b6
--- /dev/null
+++ b/Modules/ado/personal/p/pcm5.ado
@@ -0,0 +1,1771 @@
+*! Version 5 2August2022
+*! Jean-Benoit Hardouin, Myriam Blanchin
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
+* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
+* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
+* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
+* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
+* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
+* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
+* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
+* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
+* Version 4.1: September 15th, 2019 [Jean-Benoit Hardouin]: correction of a small bug in the outputs
+* Version 4.2: September 27th, 2019 [Jean-Benoit Hardouin] : EQUATING
+* Version 4.3: November 8th, 2019 [Jean-Benoit Hardouin] : add a constant when difficulty parameters are fixed
+* Version 5: August 2nd, 2022 [Jean-Benoit Hardouin] : New MAP graph, corrected estimation of the latent trait
+*
+*
+* Jean-benoit Hardouin, Myriam Blanchin - University of Nantes - France
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* jean-benoit.hardouin@univ-nantes.fr, myriam.blanchin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+*
+* Copyright 2007, 2011, 2013, 2014, 2019, 2022 Jean-Benoit Hardouin, Myriam Blanchin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcm, rclass 
+syntax varlist(min=2 numeric) [iweight] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) VARiance(real -1) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(string) GENINF(string) REPlace postpce visit(varname) id(varname) eqset1(varlist) eqset2(varlist) EQGraph minsize(int 30)]
+
+preserve
+
+/*************************************************************************************************************
+QUELQUES TESTS
+*************************************************************************************************************/
+
+if `variance'!=-1&`variance'<=0 {
+	di in red "The -variance- option cannot be negative"
+	exit 198
+}
+if `variance'!=-1&"`visit'"!="" {
+	di in red "The -variance- and -visit- options cannot be used simultaneously."*
+	exit 198
+}
+if "`genlt'"!=""|"`geninf'"!="" {
+    capture confirm new variable `genlt' `genlt'_se `geninf' `genlt'_corr `genlt'_opt `genlt'_opt_se 
+	if _rc!=0&"`replace'"=="" {
+	    di in red "The variables `genlt', `genlt'_se, `genlt'_corr, `genlt'_opt, `genlt'_opt_se and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
+		exit 198
+	}
+	if _rc!=0&"`replace'"!="" {
+	    qui capture drop `genlt' 
+		qui capture drop `genlt'_se 
+		qui capture drop `geninf' 
+		qui capture drop `genlt'_corr
+		qui capture drop `genlt'_opt
+		qui capture drop `genlt'_opt_se
+	}
+}
+if ("`eqset1'"!=""&"`eqset2'"=="")|("`eqset1'"==""&"`eqset2'"!="") {
+    di in red "The two options -eqset1- and -eqset2- must be used simultaneously"
+	exit 198
+}
+if ("`eqset1'"!=""&"`graphs'"!="") {
+    di in red "The two options -eqset1- and -graph- cannot be used simultaneously"
+	exit 198
+}
+
+
+
+
+/*************************************************************************************************************
+GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
+*************************************************************************************************************/
+if "`visit'"!=""{
+	if "`id'"==""{
+		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
+		exit 198
+	}
+	qui levelsof `visit'
+	local levelsofv `r(levels)'
+	local nbvisits=r(r)
+	local timemin: word 1 of `levelsofv'
+	local timemax: word `nbvisits' of `levelsofv'
+	if `timemax'>5{
+		di as error "You must use a discrete time variable (-visit- option) with less than 5 measurement occasions"
+		error 198
+	}
+	if `timemin'!=1{
+		di as error "You must use a -visit- variable coded at 1 for the first visit"
+		error 198
+	}
+	qui reshape wide `varlist', i(`id') j(`visit')
+	local multivist=1
+}
+else {
+	local timemax=1
+	foreach i in `varlist' {
+	   *rename `i' `i'1
+	}
+	local multivisit
+}
+qui count
+local nbobs=r(N)
+
+local timelist
+forvalues t=1/`timemax'{
+	local timelist `timelist' T`t'
+}
+
+local modcont
+local premodcont
+local nbpar=0
+local nbcont=0
+local nbcat=0
+if "`continuous'"!="" {
+	tokenize `continuous'
+	local nbcont : word count `continuous'
+	local continuous
+	forvalues i=1/`nbcont' {
+		local cont`i' ``i''
+		local continuous `continuous' ``i''
+		local modcont `modcont' ``i''
+	    local ++nbpar
+	}
+	local premodcont (`modcont'->T1)
+	local modcont (`modcont'->`timelist')
+}
+
+local modcat
+local premodcat
+if "`categorical'"!="" {
+	tokenize `categorical'
+	local nbcat : word count `categorical'
+	local categorical
+	forvalues i=1/`nbcat' {
+		local cat`i' ``i''
+		local categorical `categorical' ``i''
+		local modcat `modcat' i.``i''
+		qui levelsof ``i''
+		local levelsof``i'' `r(levels)'
+		local nbpar=`nbpar'+`r(r)'-1
+	    *di "categorical : ``i'' levels : `levelsof``i'''"
+	}
+	local premodcat (`modcat'->T1)
+	local modcat (`modcat'->`timelist')
+}
+
+
+if "`dirsave'"=="" {
+   local dirsave `c(pwd)'
+}
+
+/*************************************************************************************************************
+GESTION DES ITEMS ET TESTS
+*************************************************************************************************************/
+
+tokenize `varlist'
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+*preserve
+
+local modamax=1
+local modamin=0
+local pbmin
+local nbdiff=0
+local scoremax=0
+forvalues i=1/`nbitems' {
+	local modamax`i'=1
+	local modamax``i''=1
+	if `timemax'>1 {
+		forvalues t=1/`timemax'{
+			 *qui replace ``i'`t''=``i'`t''-`min' 
+			 qui su ``i''`t'
+			 if `r(min)'!=`modamin' {
+				 local modamin=r(min)
+				 local pbmin `pbmin' ``i'`t''
+			 }
+			 if `r(max)'>`modamax' {
+				 local modamax=r(max)
+			 }
+			 if `r(max)'>`modamax`i'' {
+				local modamax`i'=r(max)
+			}
+		}
+	}
+	else {
+		qui su ``i''
+		if `r(min)'!=`modamin' {
+		    local modamin=r(min)
+			local pbmin `pbmin' ``i''
+		}
+		if `r(max)'>`modamax' {
+			local modamax=r(max)
+		}
+		if `r(max)'>`modamax`i'' {
+			local modamax`i'=r(max)
+			local modamax``i''=r(max)
+		}
+	}
+	*di "local scoremax=`scoremax'+`modamax`i''"
+	local scoremax=`scoremax'+`modamax`i''
+	if "`rsm'"=="" {
+		local nbdiff=`nbdiff'+`modamax`i''
+	}
+}
+if "`rsm'"!="" {
+   local nbdiff=`nbitems'+`modamax'-1
+}
+if `modamin'!=0 {
+   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
+   error 198
+}
+qui count
+local nbind=r(N)
+*set trace on
+local code
+local precode
+if `timemax'>1 {
+	forvalues k=1/`modamax' {
+	   forvalues t=1/`timemax'{
+			local code`k'
+		   forvalues i=1/`nbitems' {
+			   if `k'<=`modamax`i'' {
+				  local code`k' `code`k'' `k'.``i''`t'
+			   }
+		   }
+		   local code`k' (`code`k''<-T`t'@`k')
+		   if `t'==1{
+				local precode `precode' `code`k''
+		   }
+		   local code `code' `code`k''
+		}
+	}
+}
+else {
+	forvalues k=1/`modamax' {
+		local code`k'
+		forvalues i=1/`nbitems' {
+			if `k'<=`modamax`i'' {
+				local code`k' `code`k'' `k'.``i''
+			}
+		}
+		local code`k' (`code`k''<-T1@`k')
+		local precode `precode' `code`k''
+		local code `code' `code`k''
+	}
+}
+
+/*************************************************************************************************************
+OPTION PCE
+*************************************************************************************************************/
+
+if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
+    tempname sedelta b
+	qui raschpce `varlist'
+	local ll=r(ll)
+	matrix `sedelta'=r(sedelta)
+	matrix `sedelta'=`sedelta''
+	matrix `b'=r(b)
+	*matrix `b'=`b''
+	local difficulties `b'
+	*matrix list `b'
+	matrix loulou=`b'
+	return matrix diff_parm=`b'
+	`qui' pcm `varlist', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
+	*exit
+}
+
+
+/*************************************************************************************************************
+RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
+*************************************************************************************************************/
+if "`difficulties'"!=""&"`rsm'"!="" {
+   di as error "You can not defined in the same time the difficulties and the rsm options"
+   error 198
+}
+local t=1
+local constraints
+local codemean
+local codevar
+local codecov
+forvalues j=2/`timemax'{
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			qui constraint `t' [`k'.``i''`j']_cons=[`k'.``i''`multivisit']_cons
+			local constraints `constraints' `t'
+			local ++t
+			
+		}
+	}	
+	if "`continuous'"=="" &  "`categorical'"==""{
+		local codemean `codemean' T`j'@m`j'
+		local codevar `codevar' T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' T`l'*T`j'@cov`l'`j'
+		}
+	}
+	else{
+		local codevar `codevar' e.T`j'@v`j'
+		forvalues l=1/`=`j'-1'{
+			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
+		}	
+	}
+}
+if `timemax'>1{
+	if "`continuous'"=="" &  "`categorical'"==""{	
+		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
+	}
+	else{
+		local codelg var(e.T1@v1 `codevar') cov(`codecov')
+	}
+}
+else {
+    local constrvar
+    if `variance'>0 {
+		if "`continuous'"=="" &  "`categorical'"==""{	
+			local constrvar var(T1@`variance') 
+		}
+		else{ 
+			*local constrvar var(e.T1@`variance') 
+		}
+	}
+}
+
+local fixedmean
+if "`difficulties'"!="" {
+    tempname beta
+	matrix `beta'=J(`nbitems',`modamax',.)
+	matrix list `difficulties'
+	forvalues i=1/`nbitems' {
+		forvalues k=1/`modamax`i'' {
+			if `difficulties'[`i',`k']==. {
+				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
+				 error 198
+			}
+			else {
+				if `k'==1 {
+					matrix `beta'[`i',1]=-`difficulties'[`i',1]
+  			    }
+				else {
+				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
+				}
+				qui constraint `t' [`k'.``i''`multivisit']_cons=`beta'[`i',`k']
+				local constraints `constraints' `t'
+				local ++t
+			}
+		}
+	}
+	if "`continuous'"=="" &  "`categorical'"=="" {	
+		local fixedmean mean(T1) 
+	}
+	else{
+		local fixedmean 
+	}
+}
+
+
+
+/*************************************************************************************************************
+DEFINITION DES CONTRAINTES POUR UN RSM
+*************************************************************************************************************/
+if "`rsm'"!="" {
+   local constraints
+   forvalues k=2/`modamax' {
+       forvalues i=2/`nbitems' {
+	       qui constraint `t'   [`=`k'-1'.``i''`multivisit']_cons-[`k'.``i''`multivisit']_cons+[1.``i''`multivisit']_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
+		   local constraints `constraints' `t'
+		   local ++t
+	   }
+   }
+}
+
+/*************************************************************************************************************
+MODELE
+*************************************************************************************************************/
+
+
+discard
+*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
+if "`model'"!="" {
+    local qui
+}
+else {
+	local qui qui
+}
+if `timemax'==1{
+   di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'"
+   `qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+   *qui gen un=1
+   *`qui' gsem `code' (i.group un->T) ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
+}
+else{
+    di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
+    `qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') constraint(`constraints') 
+     matrix esti_B = e(b)
+    di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)"
+    `qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
+}
+local ll=e(ll)
+
+*set trace on
+tempvar latent score group selatent latent2 miss
+tempname groups
+*capture qui predict mu, mu
+*su mu 
+qui predict `latent'*,latent se(`selatent'*)
+
+if "`genlt'"!="" {
+	if `timemax'==1 {
+		qui gen `genlt'=`latent'`i'
+		qui gen `genlt'_se=`selatent'`i'
+	}
+	forvalues t=2/`timemax' {
+		qui gen `genlt'`t'=`latent'`t'
+		qui gen `genlt'`t'_se=`selatent'`t'
+	}
+}
+
+set seed 123456
+if `timemax'>1 {
+	forvalues t=1/`timemax'{
+		qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t'
+		local listit 
+		forvalues i=1/`nbitems' {
+			local listit `listit' ``i''`t'
+		}
+		qui genscore `listit',score(`score'`t')
+		qui gengroup `latent'`t',newvariable(`group'`t') continuous minsize(`minsize')
+	}
+}
+else {
+	qui gen `latent2'=`latent'+invnorm(uniform())*`selatent'
+	local listit 
+	forvalues i=1/`nbitems' {
+		local listit `listit' ``i''
+	}
+	qui genscore `listit',score(`score')
+	qui gengroup `latent',newvariable(`group') continuous minsize(`minsize')
+}
+forvalues s=0/`scoremax' {
+    qui count if `score'==`s'
+	local effscore`s'=r(N)
+}
+
+
+/*time 1 only*/
+qui levelsof `group'`multivisit'
+local nbgroups=r(r)
+matrix `groups'=J(`nbgroups',`=`nbitems'+6',.)
+forvalues g=1/`nbgroups' {
+	matrix `groups'[`g',`=`nbitems'+3']=0
+	qui count if `group'`multivisit'==`g'
+	local effgroup`g'=r(N)
+	forvalues i=1/`nbitems' {
+			qui count if ``i''`multivisit'!=.&`group'`multivisit'==`g'
+			local n=r(N)
+			if `n'>0 {
+				qui su ``i''`multivisit' if `group'`multivisit'==`g'
+				matrix `groups'[`g',`i']=r(mean)
+				matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
+			}
+			else {
+				matrix `groups'[`g',`i']=.
+				matrix `groups'[`g',`=`nbitems'+3']=.
+			}		
+	}
+	qui su `latent'`multivisit' if `group'`multivisit'==`g'
+	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
+	qui count if `group'`multivisit'==`g'
+	matrix `groups'[`g',`=`nbitems'+2']=r(N)
+	qui su `score' if `group'`multivisit'==`g'&`score'!=.
+	matrix `groups'[`g',`=`nbitems'+4']=r(min)
+	matrix `groups'[`g',`=`nbitems'+5']=r(max)	
+}
+
+/*number of non-missing on all time points*/
+egen `miss'=rowmiss(`score'*)
+qui count if `miss'==0
+local nbobsssmd=r(N)
+drop `miss'	
+
+di
+di as text "Number of individuals:" %6.0f as result `nbobs'
+di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
+di as text "Number of items:" %6.0f as result `nbitems'
+
+di as text "Marginal log-likelihood:" %12.4f as result `ll'
+di 
+return scalar ll=`ll'
+
+
+
+*set trace on
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
+*************************************************************************************************************/
+
+tempname diff diffmat vardiff diffmat2
+*set trace on
+qui matrix `diffmat'=J(`nbitems',`modamax',.)
+qui matrix `diffmat2'=J(`nbitems',`modamax',.)
+qui matrix `diff'=J(`nbdiff',6,.)
+local rn
+*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
+*matrix list `diff'
+*set trace on
+local t=1
+forvalues i=1/`nbitems' {
+    qui matrix `diffmat'[`i',1]=-_b[1.``i''`multivisit':_cons]
+    qui matrix `diffmat2'[`i',1]=-_b[1.``i''`multivisit':_cons]
+	qui lincom -_b[1.``i''`multivisit':_cons]
+    qui matrix `diff'[`t',1]=`r(estimate)'
+    qui matrix `diff'[`t',2]=`r(se)'
+    qui matrix `diff'[`t',3]=`r(z)'
+    qui matrix `diff'[`t',4]=`r(p)'
+    qui matrix `diff'[`t',5]=`r(lb)'
+    qui matrix `diff'[`t',6]=`r(ub)'
+	local rn `rn' 1.``i''`multivisit'
+	local ++t
+	local sum _b[1.``i''`multivisit':_cons]
+	if "`rsm'"=="" {
+	    forvalues k=2/`modamax`i'' {
+			local sum "_b[`k'.``i''`multivisit':_cons]-(`sum')"
+			*di "``i''`multivisit' `k' `sum'"
+			local sum2 "_b[`=`k'-1'.``i''`multivisit':_cons]-_b[`k'.``i''`multivisit':_cons]"
+			qui lincom (`sum2')
+			*set trace on
+			qui matrix `diffmat'[`i',`k']=`r(estimate)'
+			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
+			qui matrix `diff'[`t',1]=`r(estimate)'
+			qui matrix `diff'[`t',2]=`r(se)'
+			qui matrix `diff'[`t',3]=`r(z)'
+			qui matrix `diff'[`t',4]=`r(p)'
+			qui matrix `diff'[`t',5]=`r(lb)'
+			qui matrix `diff'[`t',6]=`r(ub)'
+			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
+			*set trace off
+			local rn `rn' `k'.``i''`multivisit'
+			local ++t
+		}
+    }
+}
+if "`rsm'"!="" {
+    forvalues k=2/`modamax' {
+		qui lincom _b[`=`k'-1'.`1'`multivisit':_cons]-_b[`k'.`1'`multivisit':_cons]+_b[1.`1'`multivisit':_cons] /*``i'' instead of `i'?*/
+		qui matrix `diff'[`t',1]=`r(estimate)'
+		qui matrix `diff'[`t',2]=`r(se)'
+		qui matrix `diff'[`t',3]=`r(z)'
+		qui matrix `diff'[`t',4]=`r(p)'
+		qui matrix `diff'[`t',5]=`r(lb)'
+		qui matrix `diff'[`t',6]=`r(ub)'
+		forvalues i=1/`nbitems' {
+		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
+		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
+		}
+		local rn `rn' tau`k'
+		local ++t
+	}
+}
+local cn Estimate S.e. z p "Lower bound" "Upper Bound"
+matrix colnames `diff'=`cn'
+matrix rownames `diff'=`rn'
+*matrix list `diff'
+*matrix list `diffmat'
+*matrix list `diffmat2'
+*matrix list `vardiff'
+
+/*************************************************************************************************************
+RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
+*************************************************************************************************************/
+tempname covariates
+local nbcov=0
+forvalues j=2/`timemax'{
+	local nbcov=`nbcov'+`j'-1
+}
+qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)
+
+*set trace on
+local t=1
+
+
+forvalues j=1/`=`timemax'-1'{
+	forvalues k=`=`j'+1'/`timemax'{
+		if "`categorical'"=="" & "`continuous'"=="" {
+			if `j'==1{
+				qui lincom [/]mean(T`k')
+			}
+			else{
+				qui lincom [/]mean(T`k')-[/]mean(T`j')
+			}
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+		else{
+			if "`categorical'"!=""{
+				local first=0 
+				foreach l in `levelsof`cat1'' {
+					if `first'==0 {
+						local ++first
+					}
+					else{
+						if `first'==1 {
+							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
+							qui matrix `covariates'[`t',1]=`r(estimate)'
+							qui matrix `covariates'[`t',2]=`r(se)'
+							qui matrix `covariates'[`t',3]=`r(z)'
+							qui matrix `covariates'[`t',4]=`r(p)'
+							qui matrix `covariates'[`t',5]=`r(lb)'
+							qui matrix `covariates'[`t',6]=`r(ub)'
+							local ++t
+							local ++first
+						}
+					}
+				}
+			}
+			else{
+				qui lincom [T`k']`cont1'-[T`j']`cont1'
+				qui matrix `covariates'[`t',1]=`r(estimate)'
+				qui matrix `covariates'[`t',2]=`r(se)'
+				qui matrix `covariates'[`t',3]=`r(z)'
+				qui matrix `covariates'[`t',4]=`r(p)'
+				qui matrix `covariates'[`t',5]=`r(lb)'
+				qui matrix `covariates'[`t',6]=`r(ub)'
+				local ++t
+			}		
+		}
+	}
+}	
+		
+forvalues j=1/`timemax'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		qui lincom _b[/var(e.T`j')]
+	}
+	else {
+		qui lincom _b[/var(T`j')]
+	}
+	qui matrix `covariates'[`t',1]=`r(estimate)'
+	qui matrix `covariates'[`t',2]=`r(se)'
+	qui matrix `covariates'[`t',3]=`r(z)'
+	qui matrix `covariates'[`t',4]=`r(p)'
+	qui matrix `covariates'[`t',5]=`r(lb)'
+	qui matrix `covariates'[`t',6]=`r(ub)'
+	local ++t
+}
+forvalues j=1/`=`timemax'-1'{
+	if "`continuous'"!=""|"`categorical'"!="" {
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(e.T`j',e.T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+	else{
+		forvalues k=`=`j'+1'/`timemax'{
+			qui lincom _b[/cov(T`j',T`k')]
+			qui matrix `covariates'[`t',1]=`r(estimate)'
+			qui matrix `covariates'[`t',2]=`r(se)'
+			qui matrix `covariates'[`t',3]=`r(z)'
+			qui matrix `covariates'[`t',4]=`r(p)'
+			qui matrix `covariates'[`t',5]=`r(lb)'
+			qui matrix `covariates'[`t',6]=`r(ub)'
+			local ++t
+		}
+	}
+}
+forvalues i=1/ `nbcont' {
+   qui lincom `cont`i''
+   qui matrix `covariates'[`t',1]=`r(estimate)'
+   qui matrix `covariates'[`t',2]=`r(se)'
+   qui matrix `covariates'[`t',3]=`r(z)'
+   qui matrix `covariates'[`t',4]=`r(p)'
+   qui matrix `covariates'[`t',5]=`r(lb)'
+   qui matrix `covariates'[`t',6]=`r(ub)'
+   local ++t
+}
+forvalues i=1/ `nbcat' {
+   local first=0
+   foreach j in `levelsof`cat`i''' {
+	   if `first'==0 {
+	      local ++first
+	   }
+	   else {
+		   qui	lincom `j'.`cat`i''
+		   qui matrix `covariates'[`t',1]=`r(estimate)'
+		   qui matrix `covariates'[`t',2]=`r(se)'
+		   qui matrix `covariates'[`t',3]=`r(z)'
+		   qui matrix `covariates'[`t',4]=`r(p)'
+		   qui matrix `covariates'[`t',5]=`r(lb)'
+		   qui matrix `covariates'[`t',6]=`r(ub)'
+		   local ++t
+	   }
+   }
+}
+*matrix list `covariates'
+
+
+/*************************************************************************************************************
+OUTPUTS
+*************************************************************************************************************/
+
+if "`postpce'"=="" {
+	local t=1
+	local diffname
+	*set trace on
+	di "{hline 83}"
+	di  as text _col(70) "<--95% IC -->"
+	di   _col(70) "Lower" _col(78) "Upper"
+	di "Items" _col(22) "Threshold" _col(35) "Estimate" _col(47) "s.e." _col(58) "z" _col(66) "p" _col(69) " Bound" _col(78) "Bound"
+	di "{hline 83}"
+	*set trace on
+	forvalues i=1/`nbitems' {
+	   *local l=1
+	   forvalues j=1/`modamax`i'' {
+		  if "`rsm'"==""|`j'==1 {
+			  if `j'==1 {
+				 di as text abbrev("``i''",19) _c
+			  }
+			  di as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %5.2f `diff'[`t',3] _col(62) %5.2f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			  local ++t
+			  *local ++l
+			  local diffname `diffname' `j'.``i''
+		  }
+	   }
+	}
+	if "`rsm'"!="" {
+		forvalues k=2/`modamax' {
+			di as text "tau`k'"  as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %5.2f `diff'[`t',3] _col(62) %5.2f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6] 
+			local diffname `diffname' tau`k'
+			local ++t
+		}
+	}
+	di as text "{hline 83}"
+	local t=1
+	local listmoy
+	local listvar
+	local listcov
+	forvalues j=1/`timemax'{
+		local listvar `listvar' Variance_T`j'
+		forvalues k=`=`j'+1'/`timemax'{
+			local listcov `listcov' Cov_T`j'_T`k'
+		}
+		forvalues k=`=`j'+1'/`timemax'{
+			local listmoy `listmoy' Mean_diff_T`j'_T`k'
+		}
+	}
+	local n: word count `listmoy' `listvar' `listcov' `continuous' 
+	forvalues i=1/`n' {
+		local v: word `i' of `listmoy' `listvar' `listcov' `continuous' 
+		di as text _col(1) %5.2f "`v'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %5.2f `covariates'[`t',3] _col(62) %5.2f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+		local ++t
+	}
+
+	local rn Variance `continuous'
+
+	local n: word count of  `categorical' 
+	local catname
+	forvalues i=1/`n' {
+		local v: word `i' of `categorical'
+		local first=1
+		local saute=1
+		foreach j in `levelsof`cat`i''' {
+			if `saute'==0 {
+				if `first'==1 {
+					di as text _col(1) abbrev("`v'",19) _c
+				}
+				di  as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %5.2f `covariates'[`t',3] _col(62) %5.2f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6] 
+				local ++first
+				local rn `rn' `j'.`n'
+				local ++t
+				local catname `catname' `j'.`v'
+			}
+			else {
+			   local saute=0
+			}
+		}
+		*local ++t
+	}
+	di as text "{hline 83}"
+	if "`visit'"==""{
+		di
+		qui su `latent'
+		*qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])+(`r(sd)')^2)
+		*di as text "Variance of the estimated latent variable: " as result %4.2f `=(`r(sd)')^2'
+        tempvar se2latent
+		qui gen `se2latent'=(`selatent')^2
+		qui su `se2latent'
+		local resvar=r(mean)
+		di as text "Mean squared std error of the latent variable: " as result %4.2f `resvar'
+		di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`resvar'))'
+		local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`resvar'))
+		di as text "PSI: " as result %4.2f `PSI' _c
+		if "`continuous'"!=""|"`categorical'"!="" {
+		    di as text " (without adjustment on covariates)"
+	    }
+		else {
+		    di
+		}
+		di
+		return scalar PSI=`PSI'
+
+	}
+
+
+
+	matrix colnames `covariates'=`cn'
+	matrix rownames `covariates'=`rn'
+}
+
+/*************************************************************************************************************
+FIT TESTS
+*************************************************************************************************************/
+if "`visit'"==""{
+	tempname fit
+	qui matrix `fit'=J(`nbitems',4,.)
+	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
+	matrix rownames `fit'=`varlist'
+	*matrix list `fit'
+
+	tempvar Tcum TInf cum
+	qui gen `Tcum'=0
+	qui gen `TInf'=0
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text _col(60) "<---  Standardized   --->"
+		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
+		di as text "{hline 90}"
+		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
+		di as text "{hline 90}"
+	}
+	*set trace on
+	local chi2=0
+	local chi2_old=0
+	forvalues g=1/`nbgroups' {
+	   local chi2_g`g'=0
+	   local chi2_old_g`g'=0
+	}
+	forvalues i=1/`nbitems' {
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''  	
+		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i'' 
+
+		local d=1
+		local d_old=1
+		qui gen `cum``i'''=0
+		qui gen `cum_old``i'''=0
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
+			local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
+		}
+		qui gen `c0_``i'''=1/(`d')
+		qui gen `c_old0_``i'''=1/(`d_old')
+		forvalues k=1/`mm' {
+			tempvar c`k'_``i'' c_old`k'_``i''
+			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
+			qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
+			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
+			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
+		}
+		qui gen `Inf``i'''=0
+		qui gen `Inf_old``i'''=0
+		qui gen `C``i'''=0
+		forvalues k=0/`mm' {
+			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
+			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
+			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
+		}
+		qui count if ``i''!=.
+		local n``i''=r(N)
+		
+		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
+		qui su `C2``i'''
+		local q2o``i''=(`r(mean)'-1)/((`n``i'''))
+
+		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
+		qui su `C3``i'''
+		local n=r(sum)
+		qui su `Inf``i'''
+		local d=r(sum)
+		local q2i``i''=`n'/((`d')^2)
+		
+		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
+		
+		qui replace `Tcum'=`Tcum'+`cum``i'''
+		qui replace `TInf'=`TInf'+`Inf``i'''
+		qui gen `y``i'''=``i''-`cum``i'''
+		qui gen `y_old``i'''=``i''-`cum_old``i'''
+		qui gen `y2``i'''=(`y``i''')^2
+		qui gen `y2_old``i'''=(`y_old``i''')^2
+		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
+		local chi2_``i''=0
+		local chi2_old_``i''=0
+		forvalues g=1/`nbgroups' {
+			qui su `y2``i''' if `group'==`g'
+			local n=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1=r(sum)
+			qui su `cum``i''' if `group'==`g'
+			local n2=r(sum)
+			qui su `Inf``i''' if `group'==`g'
+			local d=r(sum)
+			*qui count if `group'==`g'
+			*local eff=r(N)
+			*di "chi2_`g'_``i''=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')"
+			local chi2=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_``i''=`chi2_``i'''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			local chi2_g`g'=`chi2_g`g''+/*`eff'**/(`n1'-`n2')^2/(`d')
+			qui su `y2_old``i''' if `group'==`g'
+			local n_old=r(sum)
+			qui su ``i'' if `group'==`g'
+			local n1_old=r(sum)
+			qui su `cum_old``i''' if `group'==`g'
+			local n2_old=r(sum)
+			qui su `Inf_old``i''' if `group'==`g'
+			local d_old=r(sum)
+			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
+			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
+			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
+		}
+		*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
+		*su `z``i'''
+		label variable `z``i''' "Standardized residuals associated to ``i''"
+		label variable `latent' "Latent trait"
+		*set trace on
+		if  "`graphs'"!=""&"`graphitems'"=="" {
+			if "`filesave'"!="" {
+				local fs saving("`dirsave'//residuals_``i''",replace)
+			}
+			qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
+		}
+		*set trace off
+		qui gen `z2``i'''=(`z``i''')^2
+		qui su `z2``i'''
+		local OUTFIT``i''=`r(mean)'
+		qui matrix `fit'[`i',1]=`OUTFIT``i'''
+		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
+		qui matrix `fit'[`i',3]=`OUTFITs``i'''
+		qui su `Inf``i''' if ``i''!=.
+		local sumw``i''=r(sum)
+		qui gen `i``i'''=`Inf``i'''*`z2``i''' 
+		qui su `i``i''' if ``i''!=.
+		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
+		qui matrix `fit'[`i',2]=`INFIT``i'''
+		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
+		qui matrix `fit'[`i',4]=`INFITs``i'''
+		if "`postpce'"=="" {
+			di "``i''" _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' 
+		}
+	}
+	if "`postpce'"=="" {
+		di as text "{hline 90}"
+		di as text "*: As suggested by Wright (Smith, 1998)
+		di as text "**: As suggested by Bond and Fox (2007)
+	}
+	if "`geninf'"!="" {
+	    gen `geninf'=`TInf'
+	}
+}
+*set trace off
+/*************************************************************************************************************
+ESTIMATION OF THE WEIGHTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+*di "estimation `wmliterate'"
+if "`postpce'"!="" {
+    local conv=10
+	local it=`wmliterate'
+	di "Iteration : `it'"
+	while(`conv'>=1) {
+		di "Itération `it' : conv=`conv'"
+		tempvar   sinf
+		qui gen `sinf'=sqrt(TInf_`=`it'-1')
+		`qui' pcm `varlist' [iweight=`sinf'],diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it') 
+		tempvar  ecart_`it' 
+		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1')
+		qui su `ecart_`it''
+		local conv =r(mean)
+		local ++it
+	}
+    exit	
+}
+
+/*************************************************************************************************************
+ESTIMATION OF THE CORRECTED ML ESTIMATORS
+**************************************************************************************************************/
+*set trace on
+tempfile savefile
+qui save `savefile'
+
+qui drop _all
+		
+qui set obs 2000
+qui gen u=(_n-1000)/200*`=sqrt(`covariates'[1,1])'
+qui gen Tcum=0
+qui gen TInf=0
+forvalues i=1/`nbitems' {
+		local d=1
+		qui gen cum``i''=0
+		if "`rsm'"=="" {
+			local mm=`modamax`i''
+		}
+		else {
+			local mm `modamax'
+		}	
+		forvalues k=1/`mm' {
+			local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+		}
+		qui gen c0_``i''=1/(`d')
+		forvalues k=1/`mm' {
+			qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+			qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+		}
+		qui gen Inf``i''=0
+		forvalues k=1/`mm' {
+			qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+		}
+		qui replace Tcum=Tcum+cum``i''
+		qui replace TInf=TInf+Inf``i''	
+	    local scoremax=0
+		forvalues i=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`i''
+	    }
+		qui gen ecart=.
+		forvalues i=0/`scoremax' {
+		    if `i'==0 {  
+			   local j=0.25
+			}
+			else if `i'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`i'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`i'=`r(mean)'
+		}
+		qui drop ecart
+}
+qui use `savefile', clear
+
+
+
+
+/*************************************************************************************************************
+RESULTS BY GROUP
+*************************************************************************************************************/
+if "`visit'"==""{
+*set trace on
+    tempname matscorelt
+	qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)
+	di
+	di as text "{hline 71}"
+	di _col(32) "Latent Trait" _col(50) "Expected" _col(63) "Corrected"
+	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score" _col(60) "latent trait"
+	di as text "{hline 71}"
+	forvalues g=1/`nbgroups' {
+		local sumuc=0
+		local sumc=0
+		qui count if `group'`multivisit'==`g' 
+		local eff`g'=r(N)
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'!=. 
+		local effcompleted`g'=r(N)
+		qui count if `score'`multivisit'!=.&`group'`multivisit'==`g'
+		local n=r(N)
+		di as text "`g' (n=" as result `eff`g'' as text ")" _c
+		if `n'>0 {
+			qui su `score'`multivisit' if `group'`multivisit'==`g'
+			local scoremin`g'=`r(min)'
+			local scoremax`g'=`r(max)'
+			forvalues s=`scoremin`g''/`scoremax`g'' {
+				qui count if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local eff=r(N)
+				if `eff'!=0 {
+					qui su `latent' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+					local mean=r(mean)
+					*di "local sumc=`sumc'+(`eff')*(`estlt`s'')"
+					*di "local sumuc=`sumuc'+(`eff')*(`mean')"
+				    local sumuc=(`sumuc'+((`eff')*(`mean')))
+				    local sumc=(`sumc'+((`eff')*(`estlt`s'')))
+				}
+				qui su `selatent' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local se=r(mean)
+				qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==`s'
+				local exp=r(mean)
+				if `eff'>0 {
+				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp' _col(66) %6.3f `estlt`s''
+				}
+				qui matrix `matscorelt'[`=`s'+1',1]=`s'
+				qui matrix `matscorelt'[`=`s'+1',2]=`mean'
+				qui matrix `matscorelt'[`=`s'+1',3]=`se'
+			}
+			
+		}
+		qui count if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local eff=r(N)
+
+		qui su `latent' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local mean=r(mean)
+	    local sumuc=(`sumuc'+((`eff')*(`mean')))
+		qui su `selatent' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local se=r(mean)
+		qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==.
+		local exp=r(mean)
+		
+		if `eff'>0 {
+			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
+		}
+		*di "local lt`g'=`sumuc'/`eff`g''"		
+		*di "local clt`g'=`sumc'/`eff`g''"
+		local lt`g'=(`sumuc')/(`eff`g'')
+		local clt`g'=(`sumc')/(`effcompleted`g'')
+		matrix `groups'[`g',`=`nbitems'+6']=`clt`g''
+		*di "group `g' est=`lt`g'' corrected est=`clt`g''"
+		di as text "         " "{dup 62:-}"
+		di  as text _col(10) "`scoremin`g''/`scoremax`g''" as result _col(20) %4.0f `eff`g'' _col(30) %6.3f `lt`g''  _col(66) %6.3f `clt`g''
+		di as text "{hline 71}"
+	}
+	*matrix list `matscorelt'
+}	
+
+
+
+/*************************************************************************************************************
+Categories/Items/Test Characteristics Curves and Information graphs
+*************************************************************************************************************/
+*set trace on
+if "`visit'"==""{
+	if "`graphs'"!=""|"`graphs'"=="" {
+
+		tempfile savefile
+		qui save `savefile'
+
+		*qui clear
+		qui drop _all
+		
+		qui set obs 2000
+		qui gen u=(_n-1000)/200*`=sqrt(`covariates'[1,1])'
+		qui gen Tcum=0
+		qui gen TInf=0
+		qui gen ecartcum=.
+		forvalues i=1/`nbitems' {
+		   local scatteri`i' 
+		   local scatteric`i' 
+		   forvalues g=1/`nbgroups' {
+			  local x=`groups'[`g',`=`nbitems'+1']
+			  local xc=`groups'[`g',`=`nbitems'+6']
+			  local y=`groups'[`g',`i']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			  local scatteric`i' `scatteric`i'' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off)
+			*set trace off
+			}
+			local d=1
+			qui gen cum``i''=0
+			*set trace on
+			if "`rsm'"=="" {
+				local mm=`modamax`i''
+			}
+			else {
+				local mm `modamax'
+			}	
+			forvalues k=1/`mm' {
+				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
+			}
+			qui gen c0_``i''=1/(`d')
+			label variable c0_``i'' "Pr(``i''=0)"
+			forvalues k=1/`mm' {
+				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
+				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
+				label variable c`k'_``i'' "Pr(``i''=`k')"
+			}
+			forvalues k=0/`mm' {
+			    if `k'==0 {
+				   local l=0.25
+				}
+				else if `k'==`mm' {
+				   local l=`k'-0.25
+				}
+				else {
+				   local l=`k'
+				}
+				qui replace ecartcum=abs(cum``i''-`l')
+				qui su ecartcum
+				qui su u if round(ecartcum,0.01)==round(`r(min)',0.01)
+				local bestest``i''_`k'=r(mean)
+				*di "item ``i'' cat `k' : est=`bestest``i''_`k''"
+			}
+			qui gen Inf``i''=0
+			forvalues k=0/`mm' {
+				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
+			}
+			if "`graphitems'"=="" {
+				if "`filesave'"!="" {
+					local fsc saving("`dirsave'//CCC_``i''",replace)
+					local fsi saving("`dirsave'//ICC_``i''",replace)
+				}
+				if "`graphs'"!="" {
+					qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
+					qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
+					qui graph twoway line cum``i'' u, name(ICCc``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Corrected latent trait") `scatteric`i'' `fsi'
+				}
+			}
+			qui replace Tcum=Tcum+cum``i''
+			*tab Tcum
+			qui replace TInf=TInf+Inf``i''	
+			label variable Inf``i'' "``i''"
+		}
+	    local scoremax=0
+		forvalues i=1/`nbitems' {
+		      local scoremax=`scoremax'+`modamax`i''
+	    }
+		qui gen ecart=.
+		forvalues i=0/`scoremax' {
+		    if `i'==0 {  
+			   local j=0.25
+			}
+			else if `i'==`scoremax' {
+			   local j=`scoremax'-0.25
+			}
+			else {
+			   local j=`i'
+			}
+		    qui replace ecart=abs(Tcum-`j')
+		    qui su ecart
+			local tmp=r(min)
+			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
+			local estlt`i'=`r(mean)'
+			*di "score `i' : `r(mean)'"
+		}
+		if "`filesave'"!="" {
+			local fst saving("`dirsave'//TCC",replace)
+			local fsteo saving("`dirsave'//TCCeo",replace)
+			local fsi saving("`dirsave'//ICC",replace)
+			local fsti saving("`dirsave'//TIC",replace)
+			local fsm saving("`dirsave'//map",replace)
+		}
+		if "`graphs'"!="" {
+qui save "C:\temp\info\info",replace
+			qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
+			qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait")  `fsi'
+			qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait")  `fsti'
+		}
+		local scatteri
+		local scatteric
+		forvalues g=1/`nbgroups' {
+			local x=`groups'[`g',`=`nbitems'+1']
+			local xc=`groups'[`g',`=`nbitems'+6']
+			local y=`groups'[`g',`=`nbitems'+3']
+			  local s1=`groups'[`g',`=`nbitems'+2']
+			  local seuil=30
+			  local s vtiny
+			  *set trace on
+			  foreach lab in  tiny vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
+				  if `s1'>`seuil' {
+					 local s `lab'
+				  }
+				  local seuil=`seuil'+10
+			  }
+			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
+			local scatteric `scatteric' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off)
+		}
+		if "`graphs'"!="" {
+			qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
+			qui graph twoway line Tcum u , name(TCCceo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Corrrected latent trait") `scatteric' `fsteo'
+		}
+	}
+	
+	
+/*************************************************************************************************************
+MAP
+*************************************************************************************************************/
+	*set trace on
+	if "`graphs'"!="" {
+		gen eff=0
+		local effmax=0
+		forvalues g=1/`nbgroups' {
+			local eff=`groups'[`g',`=`nbitems'+2']
+			if `groups'[`g',`=`nbitems'+2']>`effmax' {
+			   local effmax=`groups'[`g',`=`nbitems'+2']
+			}
+			local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
+			*di "replace eff=`eff' if round(u,0.004)==`lat'"
+			qui replace eff=`eff' if round(u,0.004)==`lat'
+		}
+		gen density=normalden(u)*sqrt(`covariates'[1,1])
+		label variable eff "Frequencies"
+		label variable u "Latent trait"
+		label variable TInf "Information curve"
+		label variable density "Density function of the latent trait"
+		local scatteri
+		local scatterj
+		local color 
+		qui su u if eff!=0
+		*set trace on
+		*set tracedepth 1
+		local floor=floor(`r(min)')
+		local ceil=ceil(`r(max)')
+		local sep
+		local ylbl
+		forvalues i=1/`nbitems' {
+		   local color`i':word `i' of `color'
+		   local unit=round(`effmax'/`nbitems',1)
+		   local y=-`i'*`unit'             
+		   loca staritem
+		   local legend `" 2 "1" "'
+		   forvalues l=1/`modamax' {
+			   if `l'>=2 {
+			      local legend `" `legend' `=2*`l'' "`l'" "'
+			   }			   
+			   local x=`diffmat'[`i',`l']
+			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
+			   if `l'==1 {
+			      local xant=`x'
+			   }
+			   else {
+			      local xant=`diffmat'[`i',`=`l'-1']
+			   }
+			   if `xant'>`x' {
+				  local star *
+				  local staritem *
+			   }
+			   else {
+			      local star
+			   }
+			   local scatterj `" `scatterj' `sep' scatteri `y' `x'   , pstyle(p`l') || pci `y' `xant' `y' `x', pstyle(p1) color(black)"'
+			   local sep ||
+			   if `x'<`floor' {
+				  local floor=floor(`x')
+			   }
+			   if `x'>`ceil'&`x'!=. {
+				  local ceil=ceil(`x')
+			   }
+		   }
+   		   local ylbl `ylbl' `=-`i'*`unit'' "``i''`staritem'"
+		   local scatteri `scatteri' || scatteri `y' `=`floor'-2' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
+		}
+		qui su eff
+		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
+		qui su TInf
+		local maxi=ceil(`r(max)')
+		qui su density
+		local maxd=round(`r(max)', 0.01)+0.01
+		qui drop if u<`floor'|u>`ceil'
+		*di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(0(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3)) `scatterj'   , name(map,replace) ytitle(Frequencies)  ylabel(0(`=`maxi'/5')`maxi' ,axis(2)) ylabel(0(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title(Individuals/items representations (Map)) xsize(12) ysize(9) note(Red line: Information curve - Green line : Density of the latent trait) xtitle(Latent trait) `fsm'"
+		*graph combine TIC IIC,  col(1)
+		*graph save "map" "map.gph", replace
+		*discard
+		*qui graph twoway line TInf u , name(map,replace)
+		*qui graph twoway `scatterj'  , name(map2,replace) ytitle("")   ylabel(`ylbl', grid angle(0))  legend(off) xsize(12) ysize(9) 
+		qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`floor'(1)`ceil') color(erose)) (line TInf u,yaxis(2) lwidth(medthick)) (line density u,yaxis(3) lwidth(medthick) )  `scatterj'  , xline(0, lcolor(black)) legend(on order(`"`legend'"') rows(1) subtitle(Threshold parameters) size(small)) name(map,replace) ytitle("                           Frequencies")  ylabel(0(`=`maxi'/5')`maxi' `maxi'(`maxi')`=`maxi'*2' ,axis(2)) yscale(axis(2) off) yscale(axis(3) off)  ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) yline(0,lwidth(thick) lcolor(black))  ylabel(`ylbl',/*noticks*/ grid angle(0) axis(1)) ylabel(`ylbl' 0(`=`maxe'/5')`maxe', grid angle(0) axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait - * : dysfunctioning items") xtitle("Latent trait") `fsm'
+		*histogram u,  name(map,replace)
+		*graph use "map.gph", name(map, replace)
+		*graph combine TIC IIC, xcombine col(1)
+	}
+	qui use `savefile', clear
+}
+		 
+
+
+/*************************************************************************************************************
+Best estimates by category 
+*************************************************************************************************************/
+
+tempname bestest
+matrix `bestest'=J(`nbitems',`=`modamax'+1',.)
+di
+local long=`modamax'*8+33
+di "{hline `long'}"
+di "Item" _col(29) "Cat 0"  _c
+forvalues j=1/`modamax' {
+     local col=29+`j'*8 
+	 di _col(`col') "Cat `j'"     _c
+}
+di
+di "{hline `long'}"
+forvalues i=1/`nbitems' {
+    di "``i''" _c
+	forvalues j=0/`modamax`i'' {
+	    di _col(`=28+`j'*8') %6.3f round(`bestest``i''_`j'', 0.001) _c
+		matrix `bestest'[`i',`=`j'+1']=`bestest``i''_`j''
+	}
+	di
+}
+di "{hline `long'}"
+		
+
+
+/*************************************************************************************************************
+EQUATING
+*************************************************************************************************************/
+*set trace on
+if "`eqset1'"!="" {
+
+    tokenize `eqset1'
+	local nbset1: word count `eqset1'
+	forvalues i=1/`nbset1' {
+	   local eq1_`i':word `i' of `eqset1'
+	   *di "set1 (`nbset1') : `eq1_`i''"
+	}
+	*di "`eqset1'"
+    tokenize `eqset2'
+	local nbset2: word count  `eqset2'
+	*di "`eqset2'"
+	forvalues i=1/`nbset2' {
+	   local eq2_`i':word `i' of `eqset2'
+	   *di "set2  (`nbset2') : `eq2_`i''"
+	}	
+
+
+
+	tempfile fileeq
+	qui save `fileeq',replace
+	forvalues t=1/2{
+		local scoremaxset`t'=0
+		forvalues i=1/`nbset`t'' {
+		    *di "`eq`t'_`i''"
+			*local tmp=""
+			local scoremaxset`t'=`scoremaxset`t''+`modamax`eq`t'_`i'''
+		}
+	}
+	drop _all
+	*set trace on
+	qui set obs `=(`scoremaxset1'+`scoremaxset2'+2)*3'
+	forvalues t=1/2 {
+		qui gen scoreset`t'=.
+		qui gen scoreset`t'm=.
+		qui gen scoreset`t'p=.	
+	}
+	forvalues i=0/`scoremaxset1' {
+	    qui replace scoreset1=`i' in `=`i'+1'
+	    qui replace scoreset1m=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset1p=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	forvalues i=`=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2' {
+	    qui replace scoreset2=`i'-`scoremaxset1'-2 in `i'
+	    qui replace scoreset2m=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)'
+	    qui replace scoreset2p=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)*2'
+	}
+	local s=0
+	local eqset1b
+	foreach i in `eqset1' {
+		qui gen s1_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s1_`i'_`m'=0 in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'_`m'=1 if scoreset1>`s' in 1/`=`scoremaxset1'+1'
+		   qui replace s1_`i'=s1_`i'+s1_`i'_`m'
+		   local ++s
+		}
+	    local eqset1b `eqset1b' s1_`i'
+	}
+	local s=0
+	local eqset2b
+	foreach i in `eqset2' {
+		qui gen s2_`i'=0
+		forvalues m=1/`modamax`i'' {
+		   qui gen s2_`i'_`m'=0 in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'_`m'=1 if scoreset2>`s' in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
+		   qui replace s2_`i'=s2_`i'+s2_`i'_`m'
+		   local ++s
+		}
+		local eqset2b `eqset2b' s2_`i'
+	}
+	tokenize `varlist'
+	tempname diffset1 diffset2
+	*matrix list `diffmat'
+	forvalues t=1/2 {
+		qui matrix `diffset`t''=J(`nbset`t'',`modamax',.)
+		local n=1
+		local listset`t'
+		foreach j in `eqset`t'' {
+			forvalues i=1/`nbitems' {
+				if "`j'"=="``i''" {
+					local listset`t' `listset`t'' `i'
+					forvalues m=1/`modamax' {
+						qui matrix `diffset`t''[`n',`m']=`diffmat'[`i',`m']
+					}
+					local ++n						
+				}
+			}
+		}
+	}
+	*matrix list `diffset1'
+	*matrix list `diffset2'
+	local var=`covariates'[1,1]
+	qui gen lt=.
+	*qui gen selt=.
+	forvalues t=1/2 {
+		tempname matscorelt`t'
+		qui pcm `eqset`t'b', diff(`diffset`t'') var(`var') minsize(1)
+		qui matrix `matscorelt`t''=r(matscorelt)
+		*di "matscorelt`t':"
+		*matrix list `matscorelt`t''
+		forvalues i=0/`scoremaxset`t'' {
+			qui replace lt=`matscorelt`t''[`=`i'+1',2] if scoreset`t'==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]+1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'p==`i'
+			qui replace lt=`matscorelt`t''[`=`i'+1',2]-1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'm==`i'
+			*qui replace selt=`matscorelt`t''[`=`i'+1',3] if scoreset`t'==`i'
+		}
+		qui ipolate scoreset`t' lt, gen(score`t') epolate
+	}
+	qui ipolate scoreset1 lt, gen(score1bis) epolate
+
+
+	*list
+	forvalues t=1/2 {
+		qui replace score`t'=scoreset`t'm if scoreset`t'm!=.
+		qui replace score`t'=scoreset`t'p if scoreset`t'p!=.
+		qui replace score1=score1bis if score1==.
+		qui replace score`t'=0 if score`t'<0
+		qui replace score`t'=`scoremaxset`t'' if score`t'>`scoremaxset`t''
+	}
+	forvalues t=1/2 {
+		tempname matscore`t'
+		qui matrix `matscore`t''=J(`=`scoremaxset`t''+1',7,.)
+		forvalues s=0/`scoremaxset`t'' {
+		    qui matrix `matscore`t''[`=`s'+1',1]=`s'
+			qui su lt if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',2]=r(mean)
+			qui su lt if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',3]=r(mean)
+			qui su lt if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',4]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'==`s'
+		    qui matrix `matscore`t''[`=`s'+1',5]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'm==`s'
+		    qui matrix `matscore`t''[`=`s'+1',6]=r(mean)
+			qui su score`=3-`t'' if scoreset`t'p==`s'
+		    qui matrix `matscore`t''[`=`s'+1',7]=r(mean)
+		}
+		matrix colnames `matscore`t'' =score`t' lt lt- lt+ score`=3-`t'' score`=3-`t''- score`=3-`t''+
+		*matrix list `matscore`t''
+		di
+		di "{hline 78}"
+		di "EQUATING SET`t' TO SET`=3-`t''"
+		di "{hline 78}"
+		di "Set`t' : `eqset`t''"
+		di "Set`=3-`t'' : `eqset`=3-`t'''"
+		di "{hline 78}"
+		di            _col(20) "<----- Latent trait ----->" _col(52) "<------- Score `=3-`t'' --------->"
+		di "Score`t'" _col(20) "Estimated" _col(39) "[95%IC]" _col(52) "Estimated" _col(72) "[95%IC]"
+		di "{hline 78}"
+		forvalues s=0/`scoremaxset`t'' {
+			di %4.0f `matscore`t''[`=`s'+1',1] _col(24) %5.2f `matscore`t''[`=`s'+1',2] _col(33) "[" %5.2f `matscore`t''[`=`s'+1',3] ";" %5.2f `matscore`t''[`=`s'+1',4] "]" _col(56) %5.2f `matscore`t''[`=`s'+1',5] _col(66) "[" %5.2f `matscore`t''[`=`s'+1',6] ";" %5.2f `matscore`t''[`=`s'+1',7] "]"
+		}
+		di "{hline 78}"
+		return matrix score`t'_to_`=3-`t''=`matscore`t''
+		if "`eqgraph'"!="" {
+			*twoway (line lt scoreset1) (line lt scoreset2), name(eq1)
+			*twoway (line scoreset1 scoreset2 lt) , name(eq2)
+			*twoway (line score1 scoreset1m scoreset1p score2), name(eq3)
+			*twoway (line score2 scoreset2m scoreset2p score1), name(eq4)
+			twoway (line score`t' score`=3-`t'' if scoreset`=3-`t''!=.) (line score`t' score`=3-`t'' if scoreset`=3-`t''m!=.) (line score`t' score`=3-`t'' if scoreset`=3-`t''p!=.), title("Equating score of the Set `t' from the Set `=3-`t''") ytitle("Score `t'") xtitle("Score `=3-`t''") ylabel(0(1)`scoremaxset`t'') xlabel(0(1)`scoremaxset`=3-`t''') name(eq`t'to`=3-`t'')
+			*twoway (line score2 score1 if scoreset1!=.) (line score2 score1 if scoreset1m!=.) (line score2 score1 if scoreset1p!=.), name(eq6)
+		}
+	}
+	*save prout, replace
+	*clear
+	
+	qui use `fileeq',clear
+}
+
+
+/*************************************************************************************************************
+RETOUR AU FICHIER INITIAL ET SAUVEGARDE DES NOUVELLES VARIABLES
+*************************************************************************************************************/
+if "`visit'"!="" {
+	tempfile sauv
+	set trace on
+	*tempname corrlatent corrbilatent
+	qui keep `latent'* `selatent'* `id' `visit' 
+    qui reshape wide , i(`id') j(`visit')
+	qui sort `id'	
+	qui save `sauv', replace
+	restore,preserve
+	if "`replace'"!=""&("`genlt'"!=""|"`geninf'"!="") {
+    	capture drop `genlt' 
+    	capture drop `genlt'_se 
+    	capture drop `geninf' 
+    	capture drop `genlt'_corr
+    	capture drop `genlt'_opt
+    	capture drop `genlt'_opt_se
+    }
+	*su
+	tempname idorder
+	qui gen `idorder'=_n
+	qui sort `id'
+	qui merge 1:1 `id' using `sauv'
+	
+	qui sort `idorder'
+    qui drop `idorder'	
+}
+else {
+*set trace on
+*set tracedepth 1
+    if "`genlt'"!="" {
+		qui gen `genlt'_corr=.
+		forvalues s=0/`scoremax' {
+			qui replace `genlt'_corr=`estlt`s'' if `score'==`s'
+		}
+		forvalues g=1/`nbgroups' {
+			qui replace `genlt'_corr=`clt`g'' if `group'==`g'&`genlt'_corr==.
+		}
+		tempvar tmpitem mean nbnonmiss
+		forvalues i=1/`nbitems' {
+			qui gen `tmpitem'_`i'=.
+			forvalues k=0/`modamax' {
+				qui replace `tmpitem'_`i'=`bestest'[`i',`=`k'+1'] if ``i''==`k'
+			}
+		}
+		*su
+		qui egen `genlt'_opt=rowmean(`tmpitem'_*)
+		qui egen `genlt'_opt_se=rowsd(`tmpitem'_*)
+		qui egen `nbnonmiss'=rownonmiss(`tmpitem'_*)
+		qui replace `genlt'_opt_se=sqrt((`genlt'_opt_se^2+`resvar')/`nbnonmiss')
+ 	}
+	restore,not
+}
+
+/*************************************************************************************************************
+CREATION DU DOCX
+*************************************************************************************************************/
+
+if "`docx'"!="" {
+    putdocx clear
+    putdocx begin
+	putdocx paragraph
+	putdocx text ("General informations") , bold underline font(,14) smallcaps
+	putdocx paragraph
+	putdocx text ("Number of individuals: `nbobs'")
+	putdocx paragraph
+	putdocx text ("Number of complete individuals: `nbobsssmd'")
+	putdocx paragraph
+    putdocx text ("Number of items: `nbitems'")
+	putdocx paragraph
+    putdocx text ("List of items: `varlist'")
+	putdocx paragraph
+    putdocx text ("Date: $S_DATE, $S_TIME")
+	putdocx paragraph
+	local model Partial Credit Model (PCM)
+	if "`rsm'"!="" {
+	   local model Rating Scale Model (RSM)
+	}
+	putdocx text ("Model: `model'")
+	putdocx paragraph
+	putdocx text ("Marginal log-likelihood: `ll'")
+
+	putdocx paragraph
+	putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
+	putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	qui putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	putdocx paragraph
+	putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
+	qui putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)   
+	local extension png
+}
+
+/*************************************************************************************************************
+SAUVEGARDE DES GRAPHIQUES
+*************************************************************************************************************/
+
+*set trace on
+if "`filesave'"!="" {
+    if "`graphs'"!="" {
+		if "`docx'"!="" {
+		    putdocx pagebreak
+		    putdocx paragraph
+	        putdocx text ("General graphs") , bold underline font(,14) smallcaps
+		}
+		foreach i in TCC TCCeo TIC IIC map {
+			if "`extension'"!="" {
+			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')     
+            }
+			*graph display `i' 
+			*qui graph save "`dirsave'//`i'", replace    
+			if "`docx'"!="" {
+			    putdocx paragraph
+			    putdocx image "`dirsave'//`i'.png", height(10cm)
+			}
+		}
+	    *discard
+		if "`graphitems'"=="" {
+			forvalues i=1/`nbitems' {
+				if "`docx'"!="" {
+				    putdocx paragraph
+				    putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
+				}
+				foreach j in CCC ICC residuals {
+					*graph display `j'``i'' 
+					*qui graph save "`dirsave'//`j'_``i''", replace    
+
+	 			    if "`extension'"!="" {
+					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'') 
+					}
+					if "`docx'"!="" {
+						putdocx paragraph
+						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
+					}
+				}
+			}
+		}
+	}
+}
+if "`docx'"!="" {
+    putdocx save "`dirsave'//`docx'.docx", replace
+}
+
+
+/*************************************************************************************************************
+RETURNS
+*************************************************************************************************************/
+
+
+matrix colnames `diff'=Estimate "s.e." z p lb ul
+matrix colnames `covariates'=Estimate "s.e." z p lb ul
+matrix rownames `diff'=`diffname'
+matrix rownames `covariates'=Variance `continuous' `catname'
+return matrix difficulties=`diff'
+return matrix covariates=`covariates'
+return matrix matscorelt=`matscorelt'
+return matrix bestest=`bestest'
+capture restore, not
+end
diff --git a/Modules/ado/personal/p/pcmodel.hlp b/Modules/ado/personal/p/pcmodel.hlp
new file mode 100644
index 0000000..59db43f
--- /dev/null
+++ b/Modules/ado/personal/p/pcmodel.hlp
@@ -0,0 +1,126 @@
+{smcl}
+{* Mars 2012}{...}
+{hline}
+help for {hi:pcmodel}{right:JFH}
+{hline}
+
+{title:Estimation of the parameters of a Partial Credit Model}
+
+{p 8 14 2}{cmd:pcmodel} (varlist) [{cmd:if} {it:exp}], 
+[{cmdab:qual:itatives}({it:varlist})
+{cmdab:quant:itatives}({it:varlist}) 
+{cmdab:dif:ficulties}({it:matrix list}) 
+{cmdab:it:erate}(#)
+{cmdab:ad:apt} 
+{cmdab:ro:bust}
+{cmdab:f:rom}(matrix)]
+
+{title:Description}
+
+{p 8 14 2}{cmd:pcmodel} allows estimating the parameters of a random effect
+ partial credit model (the item difficulties, and the potential covariates
+  that may influence the considered latent trait are considered as fixed effects.
+   The individual latent traits are considered as a  normally distributed
+    random effect){p_end}
+{p 14 14 2}Two situations are possible:{p_end}
+{p 14 14 2}- The item difficulties can be
+ considered as already known. They do not have to be estimated during the
+  analysis.{p_end}
+{p 14 14 2}- The difficulties are considered as unknowns, and then require
+   to be estimated during the analysis. {p_end}
+{p 14 14 2}It is possible to include covariates (that can possibly influence
+ the individual latent traits) in the partial credit model. These covariates
+  can either be qualitative or quantitative. {p_end}
+{p 14 14 2}{cmd:pcmodel} provides assistance for interpreting the estimated
+ effects of covariates (estimation of the type III sum of squares, percentage
+  of variance explained with the introduction of each covariates). {p_end}
+{p 14 14 2}It is finally possible to thest the fit using {cmd:pcmtest} after
+ estimating parameters of the model with {cmd:pcmodel}
+
+{title:Options}
+
+{p 4 8 2}{cmdab:qual:itatives} List of the categorical covariates included in
+ the partial credit model
+
+{p 4 8 2}{cmdab:quant:itatives} List of the continuous covariates included in
+ the partial credit model
+
+{p 4 8 2}{cmd:difficulties} Row vectors containing the considered known values
+ of each item difficulty. A row vector must match with each item, and have the
+  same name as the corresponding item. The item difficulties should be known for
+   all the items. If {cmd:difficulties} is not filled, the dificulties are
+    considered as unknown, and are estimated during the analysis. 
+
+{p 4 8 2}{cmd:iterate} specifies the (maximum) number of iterations. With the
+ adapt option, use of the iterate(#) option will cause pcmodel to skip the
+  "Newton Raphson" iterations usually performed at the end without updating
+   the quadrature locations.
+
+
+{p 4 8 2}{cmd:adapt} causes adaptive quadrature to be used instead of
+ ordinary quadrature.
+
+{p 4 8 2}{cmd:robust} specifies that the Huber/White/sandwich estimator of the
+ covariance matrix of the parameter estimates is to be used. 
+
+
+{p 4 8 2}{cmd:from} specifies a row vector to be used for the initial values.
+ Note that the column-names and equation-names do not have to be correct. This
+  line vector must have exactly the number of parameters to be estimated,
+   starting with the difficulties parameters, then the parameters associated
+    with the covariates, and finishing with the estimated standard deviation
+     of the latent trait.
+
+{title:Outputs}
+
+{p 4 8 2}{cmd:e(lll)}: (marginal) log-likelihood
+
+{p 4 8 2}{cmd:e(cn)}: Condition number
+
+{p 4 8 2}{cmd:e(N)}: Number of observations
+
+{p 4 8 2}{cmd:e(Nit)}: Number of items
+
+{p 4 8 2}{cmd:e(Nqual)}: Number of qualitative covariates
+
+{p 4 8 2}{cmd:e(Nquant)}: Number of quantitative covariates
+
+{p 4 8 2}{cmd:e(items)}: program used to implement {cmdpcmtest}
+
+{p 4 8 2}{cmd:e(itest)}: program used to implement {cmdpcmtest}
+
+{p 4 8 2}{cmd:e(datatest)}: program used to implement {cmdpcmtest}
+
+{p 4 8 2}{cmd:e(mugauss)}: program used to implement {cmdpcmtest}
+
+{p 4 8 2}{cmd:e(sdgauss)}: program used to implement {cmdpcmtest}
+
+{p 4 8 2}{cmd:e(cmd)}: program used to implement {cmdpcmtest}
+
+{p 4 8 2}{cmd:e(sigma)}: Estimated standard deviation of the latent trait
+
+{p 4 8 2}{cmd:e(Varsigma)}: Variance of the estimated standard deviation of
+ the latent trait
+
+{p 4 8 2}{cmd:e(b)}: coefficient vector of the parameters associated with
+ the latent trait covariates (if no covariate is included in the model, value
+  of the average latent trait).
+
+{p 4 8 2}{cmd:e(V)}: Covariance matrix for the latent trait covariates.
+
+{p 4 8 2}{cmd:e(delta)}: Estimated difficulty parameters
+
+{p 4 8 2}{cmd:e(Vardelta)}: Covariance matrix for the estimated difficulty
+ parameters
+
+
+{title:Author}
+
+{p 4 8 2}Jean-François HAMEL{p_end}
+
+{title:Also see}
+
+{p 4 13 2}Online: help for {help pcmtest}, {help gllamm}, {help simirt},
+ {help raschtest}.{p_end}
+
+
diff --git a/Modules/ado/personal/p/pcmodel.sthlp b/Modules/ado/personal/p/pcmodel.sthlp
new file mode 100644
index 0000000..f9b887c
--- /dev/null
+++ b/Modules/ado/personal/p/pcmodel.sthlp
@@ -0,0 +1,194 @@
+{smcl}
+{* Mars 2012}{...}
+{hline}
+help for {hi:pcmodel}
+{hline}
+
+
+{title:Estimation of the parameters of a Partial Credit Model}
+
+{p 8 14 2}{cmd:pcmodel} (varlist) [{help if} {help in}], 
+[{cmdab:cat:egorical}({it:varlist})
+{cmdab:cont:inuous}({it:varlist}) 
+{cmdab:dif:ficulties}({it:matrix list}) 
+{cmdab:it:erate}(#)
+{cmdab:ad:apt} 
+{cmdab:ro:bust}
+{cmdab:f:rom}(matrix)
+{cmdab:rsm:}
+{cmdab:nip:}
+{cmdab:tr:ace}
+{cmdab:est:imateonly}
+{cmdab:l:evel}(#)]
+
+
+{title:Description}
+
+{p 8 14 2}{cmd:pcmodel} allows estimating the parameters of a random effect
+ partial credit model or a random effect rating scale model 
+ (the item difficulties, and the covariates
+  that may influence the considered latent trait are considered as fixed 
+effects, and the individual latent traits are considered as a normally distributed
+    random effect){p_end}
+{p 14 14 2}Two situations are possible:{p_end}
+{p 16 18 2}- The item difficulties can be considered as already known 
+(for example provided by the scale developer). 
+In this case, they do not have to be estimated during the analysis.{p_end}
+{p 16 18 2}- The difficulties are considered as unknowns and will
+   be estimated during the analysis. {p_end} 
+   
+{p 14 14 2}{cmd:pcmodel} allows including covariates that 
+can possibly influence the individual latent traits in the considered model 
+(partial credit or rating scale). These covariates
+  can either be categorical or continuous. {p_end}
+  
+{p 14 14 2}{cmd:pcmodel} provides assistance for interpreting both the quality 
+of model fit (by estimating the marginal McFadden's pseudo R2) and the
+ contribution of covariates to the model 
+  (by estimating the the type III sum of squares, the percentage
+  of variance explained with the introduction of each covariates and the percentage
+   of McFadden's pseudo R2 explained with the introduction of each
+    covariate). {p_end}
+    
+{p 14 14 2}It is finally possible to test the fit using {cmd:pcmtest} after
+ estimating parameters of the model with {cmd:pcmodel}
+
+
+{title:Options}
+
+{p 4 8 2}{cmd:categorical} List of the categorical covariates included in
+ the Partial Credit model or the Rating Scale model.
+
+{p 4 8 2}{cmd:continuous} List of the continuous covariates included in
+ the Partial Credit model or the Rating Scale model.
+
+{p 4 8 2}{cmd:difficulties} Row vectors containing the known values
+ of each item difficulty (if they are known).
+  A row vector must match with each item, and have the
+  same name as the corresponding item. If the option {cmd:difficulties} 
+  is not filled, the item difficulties are
+    considered as unknown, and they are estimated during the analysis. 
+    (this option cannot be used with the {cmd:rsm} option
+
+{p 4 8 2}{cmd:iterate} specifies the (maximum) number of iterations. With the
+ adapt option, use of the iterate(#) option will cause pcmodel to skip the
+  "Newton Raphson" iterations usually performed at the end without updating
+   the quadrature locations.
+
+{p 4 8 2}{cmd:adapt} causes adaptive quadrature to be used instead of
+ ordinary quadrature.
+
+{p 4 8 2}{cmd:robust} specifies that the Huber/White/sandwich estimator of the
+ covariance matrix of the parameter estimates is to be used. 
+
+{p 4 8 2}{cmd:from} specifies a row vector to be used for the initial values.
+ It is not necessary to specify column-names or equation-names for this line vector,
+ but this vector must have exactly the number of parameters to be estimated,
+   starting with the difficulties parameters, the parameters associated
+    with the covariates, and ending with the estimated standard deviation
+     of the latent trait.
+
+{p 4 8 2}{cmd:rsm} performs a Rating Scale model instead of a Partial Credit model.
+
+{p 4 8 2}{cmd:estimateonly} Do not perform the Marginal McFadden's pseudo R2 
+nor the type III sums of square computations
+
+{p 4 8 2}{cmd:nip} specifies the number of integration points to be used for each 
+integral or summation. Only the following degrees are available:  5, 7, 9, 11, 15.
+
+{p 4 8 2}{cmd:trace} causes more output to be displayed. Before estimation begins, 
+details of the specified model are displayed. In addition, a detailed iteration 
+log is shown including parameter estimates and log-likelihood values for each iteration.
+
+{p 4 8 2}{cmd:level} set confidence level; default is level(95)
+
+
+
+{title:Outputs}
+
+{p 4 8 2}{cmd:e(ll)}: marginal log-likelihood
+
+{p 4 8 2}{cmd:e(cn)}: Condition number
+
+{p 4 8 2}{cmd:e(N)}: Number of observations
+
+{p 4 8 2}{cmd:e(Nit)}: Number of items
+
+{p 4 8 2}{cmd:e(Ncat)}: Number of categorical covariates
+
+{p 4 8 2}{cmd:e(Ncont)}: Number of continuous covariates
+
+{p 4 8 2}{cmd:e(sigma)}: Estimated standard deviation of the latent trait
+
+{p 4 8 2}{cmd:e(Varsigma)}: Variance of the estimated standard deviation of
+ the latent trait
+
+{p 4 8 2}{cmd:e(theta)}: Coefficient vector of the parameters associated with the latent trait covariates (if no covariate is included in the model, value of the average latent trait)
+
+{p 4 8 2}{cmd:e(Vartheta)}: Covariance matrix for the latent trait covariates.
+
+{p 4 8 2}{cmd:e(delta)}: Estimated difficulty parameters
+
+{p 4 8 2}{cmd:e(Vardelta)}: Covariance matrix for the estimated difficulty parameters
+
+{p 4 8 2}{cmd:e(b)}: Overall estimated parameters of the PCM (or RSM)
+
+{p 4 8 2}{cmd:e(V)}: Covariance matrix for the overall estimated parameters
+
+{marker example}{...}
+{title:Example}
+
+{pstd}
+Simulation of the data (using {help simirt}):
+
+	. {cmd:simirt, nbobs(200) dim(5) rsm1(0.2) group(0.5) deltagroup(0.4) clear}{right:(1)    }
+
+{pstd}
+Estimating a Partial Credit Model with {cmd:pcmodel}:
+
+	. {cmd:pcmodel item*}{right:(2)    }
+
+{pstd}
+Estimating a Rating Sacle Model with {cmd:pcmodel}:
+
+	. {cmd:pcmodel item*, rsm}{right:(3)    }
+
+{pstd}
+Testing the fit of the previously performed model with {help pcmtest}:
+
+	. {cmd:pcmtest, si }{right:(4)    }
+
+{pstd}
+Estimating a Partial Credit Model with {cmd:pcmodel}, considering that the item difficulties 
+are provided by the scale developer (-1 & -0.8 for item1, -0.5 & -0.3 for item2, 0 & 0.2 for 
+item3, 0.5 & 0.7 for item4 and 1 & 1.2 for item5) and that the {it:group} covariate may 
+influence the individual latent trait:
+
+{p 6 9 2}
+1/ Defining the row vectors containing the known values of each item difficulty, with the 
+same name as the corresponding item:
+
+	. {cmd:matrix item1=(-1,-0.8)}{right:(5)    }
+	. {cmd:matrix item2=(-0.5,-0.3)}{right:(6)    }
+	. {cmd:matrix item3=(0,0.2)}{right:(7)    }
+	. {cmd:matrix item4=(0.5,0.7)}{right:(8)    }
+	. {cmd:matrix item5=(1,1.2)}{right:(9)    }
+
+{p 6 9 2}
+2/ Estimating the Partial Credit Model with item difficulties already known, including 
+the {it:group} covariate as a categorical covariate:
+
+	. {cmd:pcmodel item*, difficulties(item1 item2 item3 item4 item5) cat(group)}{right:(10)    }
+
+
+{title:Author}
+
+{p 4 8 2}Jean-François Hamel{p_end}
+{p 4 8 2}Email:
+{browse "mailto:jeanfrancois.hamel@chu-angers.fr":jeanfrancois.hamel@chu-angers.fr}{p_end}
+
+
+{title:Also see}
+
+{p 4 13 2}Online: help for {help pcmtest}, {help gllamm}, {help simirt},
+ {help raschtest}.{p_end}
diff --git a/Modules/ado/personal/p/pcmodel22.ado b/Modules/ado/personal/p/pcmodel22.ado
new file mode 100644
index 0000000..3228fd1
--- /dev/null
+++ b/Modules/ado/personal/p/pcmodel22.ado
@@ -0,0 +1,1140 @@
+/********************************************************************************/
+/* v1.1 : Bug fixed regarding the estimation of the latent trait standard error */
+/* v2 : Bugs with temporary names fixed, New options have been added,           */
+/*      modifications of the output                                             */
+/********************************************************************************/
+
+program define pcmodel, eclass
+version 11.0
+syntax [varlist] [if] [in] [, CATegorical(string) CONTinuous(string) DIFficulties(string) ITerate(string)  ADapt RObust From(string) RSM ESTimateonly nip(string) TRace Level(string)]
+
+preserve
+tempfile bddinip
+qui save `bddinip',replace
+local Cond=0
+
+if "`level'"==""{
+	local level=c(level)
+}
+
+
+if replay() {
+	capture local cmdavant=e(cmd)
+	if _rc!=0 | "`cmdavant'"!="pcmodel"{
+		noi di in red "pcmodel was not the last command"
+		error 100
+	}
+	if "`categorical'`continuous'`difficulties'`iterate'`adapt'`robust'`from'`rsm'`estimateonly'`nip'"==""{
+		local rsm=e(rsm)
+		local LLfull=e(ll)
+		local estimateonly=e(estimateonly)
+		local R2Nag=e(r2)
+		local Nbid=e(N)
+		local nbit=e(Nit)
+		local categorical=e(categorical)
+		local continuous=e(continuous)
+		if "`continuous'"=="."{
+			local continuous=""
+		}
+		if "`categorical'"=="."{
+			local categorical=""
+		}
+		local nbcov: word count `categorical'
+		local nbcovquant: word count `continuous'
+		local varlist=e(items)
+		tokenize `varlist' `categorical' `continuous'
+		local difficulties=e(difficulties)
+		local contrR=e(constr)
+		tempname eB eV VarExpSS
+		matrix `eB'=e(b)
+		matrix `eV'=e(V)
+		matrix `VarExpSS'=e(VarExpSS)
+		local nbc=colsof(`eB')
+		local nbdifftotbis=e(ndtb)
+		if `nbcov'!=0{
+			forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+				local ``i''_m=e(``i'')
+				local k=1
+				local nbModCov`=`i'-`nbit''=wordcount("```i''_m'")
+				foreach m in ```i''_m'{
+					local ident`=`i'-`nbit''_`k'=`m'
+					local k=`k'+1
+				}
+			}
+		}
+		if "`rsm'"!="."{
+			di in gr "Model : " in ye "Rating Scale Model"
+		}
+		else{
+			di in gr "Model : " in ye "Partial Credit Model"
+		}
+		di in gr ""
+		di in gr "                log likelihood: " in ye %-18.3f `LLfull'
+		if "`estimateonly'"=="."{
+			di in gr "                Marginal McFadden's pseudo R2: " in ye %-4.1f `=`R2Nag'*100' "%"
+		}
+		di in gr "                Number of individuals: "in ye "`Nbid'"
+		di in gr "                Number of items: "in ye "`nbit'"
+		if `=`nbcov'+`nbcovquant''!=0{
+			di in gr "                Number of covariates: "in ye "`=`nbcov'+`nbcovquant''"
+		}
+		di in gr ""
+		di ""
+		di in gr "Parameters of the Latent trait distribution:"
+		di ""
+		if "`difficulties'"=="."{
+			di in gr "                Identifiability constraint: `contrR'set to 0"
+		}
+		di in gr "		  Variance of the Latent trait: SigmaÂČ=" in ye %-8.3f (`=`=`eB'[1,`nbc']'')^2 in gr " (SE:"in ye %-8.3f `= sqrt((2*`=`eB'[1,`nbc']')^2 *`=`eV'[`nbc',`nbc']'	)' in gr ")"
+		local varTheta=(`=`=`eB'[1,`nbc']'')^2
+		local Varvartheta=(2*`=`eB'[1,`nbc']')^2 *`=`eV'[`nbc',`nbc']'
+		di ""
+		if `nbcov'+`nbcovquant'!=0{
+			di in gr "Latent trait group effect:"
+			di ""
+			di in gr "{hline 66}"
+			di _col(20) in gr "Coef." _col(30) in gr "S.E." _col(41) in gr "z" _col(45) in gr "P>|z|" _col(57) in gr "[`level'% C.I.]"
+			di in gr "{hline 66}"
+			local compteur=1
+			if "`difficulties'"=="."{
+				local compteur=`nbdifftotbis'
+			}
+			if `nbcov'!=0{
+				forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+					local compteur=`compteur'+1
+					noi{
+						di _col(1) in gr "``i'':" 
+							di _col(4) in gr "`=abbrev("``i''",10)':" in ye " `ident`=`i'-`nbit''_1'" _col(24) in ye  "0" _col(33) in ye "." _col(41) in ye "." _col(49) in ye "." _col(57) in ye "." _col(66) in ye "."
+					}
+					forvalues k=2/`nbModCov`=`i'-`nbit'''{
+						local compteur=`compteur'+1
+						local estimate_e=`eB'[1,`compteur']
+						local se_e=sqrt(`=`eV'[`compteur',`compteur']')
+						noi{
+							di _col(4) in gr "`=abbrev("``i''",10)':" in ye " `ident`=`i'-`nbit''_`k''" _col(19) in ye %6.3f `estimate_e' _col(28) in ye %6.3f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %6.3f `=`estimate_e'-`=(1+`level'/100)/2'*`se_e'' _col(61) in ye %6.3f `=`estimate_e'+`=(1+`level'/100)/2'*`se_e''
+						}
+					}
+					di in gr "{hline 66}"
+				}
+			}
+			if `nbcovquant'!=0{
+				forvalues i=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+					local compteur=`compteur'+1
+						local estimate_e=`eB'[1,`compteur']
+						local se_e=sqrt(`=`eV'[`compteur',`compteur']')
+					noi{		
+						di _col(1) in gr "``i'':" _col(19) in ye %6.3f `estimate_e' _col(28) in ye %6.3f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %6.3f `=`estimate_e'-`=(1+`level'/100)/2'*`se_e'' _col(61) in ye %6.3f `=`estimate_e'+`=(1+`level'/100)/2'*`se_e'' 
+					}
+					di in gr "{hline 66}"
+				}
+			}
+			if "`difficulties'"!="."{
+				di _col(1) in gr "_Cons" _col(19) in ye %6.3f `=`eB'[1,1]' _col(28) in ye %6.3f `=sqrt(`eV'[1,1])' _col(37) in ye %5.2f `=`=`eB'[1,1]'/`=sqrt(`eV'[1,1])'' _col(44) in ye %6.3f `=2*(1-normal(abs(`=`eB'[1,1]'/`=sqrt(`eV'[1,1])')))'  _col(52) in ye %6.3f `=`=`eB'[1,1]'-`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1])'' _col(61) in ye %6.3f `=`=`eB'[1,1]'+`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1])''
+				di in gr "{hline 66}"
+			}
+			if "`estimateonly'"=="."{
+				di ""
+				di "Proportion of latent trait variance explained by covariates"
+				di ""
+				di in gr "{hline 53}"
+				di _col(23) in gr "SS.III" _col(34) in gr "df" _col(38) in gr "V.exp." _col(47) in gr "R2.exp."
+				di in gr "{hline 53}"
+				local compteur=1
+				if "`difficulties'"=="."{
+					local compteur=`nbdifftotbis'
+				}
+				local compte=1
+				if `nbcov'!=0{
+					forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+						local ss3=`VarExpSS'[`compte',1]
+						local df=`VarExpSS'[`compte',2]
+						local vexp=`VarExpSS'[`compte',3]
+						local r2exp=`VarExpSS'[`compte',4]
+						local compteur=`compteur'+1
+						local compte=`compte'+1
+						noi di _col(1) in gr "``i'':"  _col(22) in ye %6.3f `ss3'	 _col(34) in ye %2.0f  `df'  _col(37) in ye %6.1f `vexp' "%"    _col(46) in ye %6.1f  `r2exp' "%"
+					}
+				}
+				if `nbcovquant'!=0{
+					forvalues i=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+						local ss3=`VarExpSS'[`compte',1]
+						local df=`VarExpSS'[`compte',2]
+						local vexp=`VarExpSS'[`compte',3]
+						local r2exp=`VarExpSS'[`compte',4]
+						local compteur=`compteur'+1
+						local compte=`compte'+1
+						noi di _col(1) in gr "``i'':" _col(22) in ye %6.3f `ss3'	 _col(34) in ye %2.0f  `df'  _col(37) in ye %6.1f `vexp' "%"    _col(46) in ye %6.1f  `r2exp' "%"
+					}
+				}
+				di in gr "{hline 53}"
+				local sssc=`VarExpSS'[`=`compte'',1]
+				local dfsc=`VarExpSS'[`=`compte'',2]
+				local ssac=`VarExpSS'[`=`compte'+1',1]
+				local dfac=`VarExpSS'[`=`compte'+1',2]
+				di _col(23) in gr "SS.res" _col(34) in gr "df"
+				di _col(1) in gr "Model without cov." _col(22) in ye %6.3f `sssc'  _col(31) in ye %5.0f `dfsc'
+				di _col(1) in gr "Full model" _col(22) in ye %6.3f `ssac'  _col(31) in ye %5.0f `dfac'
+				di in gr "{hline 53}"
+				di ""
+			}
+		}
+		else if "`difficulties'"!="."{
+			di in gr "Latent trait distribution"
+			di in gr "{hline 80}"
+			di _col(18) in gr "Coef." _col(31) in gr "S.E." _col(43) in gr "z" _col(52) in gr "P>|z|" _col(61) in gr "[`level'% Conf. Interval]"
+			di in gr "{hline 80}"
+			di _col(1) in gr "Mu" _col(15) in ye %8.5f `=`eB'[1,1]' _col(27) in ye %8.5f `=sqrt(`eV'[1,1]) ' _col(39) in ye %5.2f `=`=`eB'[1,1]'/`=sqrt(`eV'[1,1]) '' _col(51) in ye %6.3f `=2*(1-normal(abs(`=`eB'[1,1]'/`=sqrt(`eV'[1,1]) ')))'  _col(61) in ye %8.5f `=`=`eB'[1,1]'-`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1]) '' _col(73) in ye %8.5f `=`=`eB'[1,1]'+`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1]) ''
+
+			di _col(1) in gr "Sigma" _col(15) in ye %8.5f `=abs(`eB'[1,`nbc'])' _col(27) in ye %8.5f `=sqrt(`=`eV'[`nbc',`nbc']')' _col(39) in ye %5.2f `=`eB'[1,`nbc']/sqrt(`=`eV'[`nbc',`nbc']')' _col(51) in ye %6.3f `=2*(1-normal(abs(`eB'[1,`nbc']/sqrt(`=`eV'[`nbc',`nbc']'))))'  _col(61) in ye %8.5f `=`eB'[1,`nbc']-`=(1+`level'/100)/2'*sqrt(`=`eV'[`nbc',`nbc']')' _col(73) in ye %8.5f `=`eB'[1,`nbc']+`=(1+`level'/100)/2'*sqrt(`=`eV'[`nbc',`nbc']')'
+			di in gr "{hline 80}"
+			di ""
+		}
+		if "`difficulties'"=="."{
+			di in gr "Items difficulty parameters:"
+			di ""
+			di in gr "{hline 52}"
+			di _col(1) in gr "Item"  _col(21) in gr "Coef." _col(31) in gr "S.E."   _col(43) in gr "[`level'% C.I.]" _col(66) 
+			di in gr "{hline 52}"
+			local compteur=1
+			if "`rsm'"=="."{
+				forvalues i=1/`nbit'{
+		
+				tempname rep__`i'
+				qui tab ``i'', matrow(`rep__`i'')
+						local moda`i'=`=r(r)'
+					di _col(1) in gr "``i'':" 
+					forvalues g=1/`=`moda`i''-1'{
+						di _col(4) in gr "response: " in ye %-6.2g `=`rep__`i''[`=`g'+1',1]' _col(20) in ye %6.3f `=`eB'[1,`compteur']' _col(29) in ye %6.3f `=sqrt(`=`eV'[`compteur',`compteur']')'   _col(38) in ye %6.3f `=`eB'[1,`compteur']-`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' _col(47) in ye %6.3f `=`eB'[1,`compteur']+`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' 
+						local compteur=`compteur'+1
+					}
+					di in gr "{hline 52}"
+				}
+				di ""
+			}
+			else{
+			tempname tau
+			matrix `tau'=e(Tau)
+				forvalues i=1/`nbit'{
+				tempname rep__`i'
+				qui tab ``i'', matrow(`rep__`i'')
+						local moda`i'=`=r(r)'
+					di _col(1) in gr "``i'':"   _col(20) in ye %6.3f `=`eB'[1,`compteur']' _col(29) in ye %6.3f `=sqrt(`=`eV'[`compteur',`compteur']')'   _col(38) in ye %6.3f `=`eB'[1,`compteur']-`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' _col(47) in ye %6.3f `=`eB'[1,`compteur']+`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' 
+					local compteur=`compteur'+`=`moda1'-1'
+				}
+				di in gr "{hline 52}"
+				forvalues i=2/`=`moda1'-1'{
+					di _col(1) in gr "tau`=`i'-1':"  _col(20) in ye %6.3f `=`tau'[1,`i']' _col(29) in ye %6.3f `=`tau'[2,`i']'   _col(38) in ye %6.3f `=`=`tau'[1,`i']'-`=(1+`level'/100)/2'*`=`tau'[2,`i']'' _col(47) in ye %6.3f `=`=`tau'[1,`i']'+`=(1+`level'/100)/2'*`=`tau'[2,`i']'' 
+				}
+				di in gr "{hline 52}"
+			}
+		}
+		else{
+			di in gr "Items difficulty parameters: fixed for the analysis"
+		}
+	}
+	else{
+		local Cond=1
+		local varlist=e(items)
+		if "`categorical'"=="" & "`=e(categorical)'"!="."{
+			local categorical=e(categorical)
+		}
+		if "`continuous'"=="" & "`=e(continuous)'"!="."{
+			local continuous=e(continuous)
+		}
+		if "`difficulties'"=="" & "`=e(difficulties)'"!="."{
+			local difficulties=e(difficulties)
+		}
+		if "`iterate'"=="" & "`=e(iterate)'"!="."{
+			local iterate=e(iterate)
+		}
+		if "`adapt'"=="" & "`=e(adapt)'"!="."{
+			local adapt=e(adapt)
+		}
+		if "`robust'"=="" & "`=e(robust)'"!="."{
+			local robust=e(robust)
+		}
+		if "`from'"=="" & "`=e(from)'"!="."{
+			local from=e(from)
+		}
+		if "`rsm'"=="" & "`=e(rsm)'"!="."{
+			local rsm=e(rsm)
+		}
+		if "`estimateonly'"=="" & "`=e(estimateonly)'"!="."{
+			local estimateonly=e(estimateonly)
+		}
+	}
+}
+else{
+	local Cond=1
+}
+if `Cond'==1{
+	tokenize `varlist' `categorical' `continuous'
+	local nbit: word count `varlist'
+	local nbcov: word count `categorical'
+	local nbcovquant: word count `continuous'
+	local nbit2:word count `difficulties'
+	local NIP ""
+	if "`nip'"!=""{
+		local NIP "nip(`nip')"
+	}
+	tempname nom val
+	if `nbit2'==0{
+		local itest=1
+	}
+	else{
+		local itest=0
+	}
+	if "`from'"!=""{
+		local verifFrom=colsof(`from')
+	}
+	tempfile bddini bddinib
+	qui{
+		marksample touse,novarlist
+		keep if `touse'
+		local ordre=0
+		forvalues i=1/`nbit'{
+			tempname rep__`i'
+			tab ``i'', matrow(`rep__`i'')
+			local ordre=`ordre'+`=rowsof(`rep__`i'')'-1
+			forvalues j=1/`=rowsof(`rep__`i'')'{
+				replace ``i''=`j'-1 if ``i''==`rep__`i''[`j',1]
+			}
+		}
+		save `bddinib',replace
+		q memory
+	}
+	local matsizeini=r(matsize)
+	if "`rsm'"!=""{
+		local nbtotmodait=rowsof(`rep__1')
+		forvalues i=2/`nbit'{
+			if `=rowsof(`rep__`i'')'!=`nbtotmodait'{
+				noi di in red "The number of item response categories must be equal for each item when using Rating Scale models"
+				use `bddinip',replace 
+				error 100
+			}
+		}
+		if "`difficulties'"!=""{
+			noi di in red "RSM option only available for unknow difficulties"
+			use `bddinip',replace 
+			error 100
+		}
+	}
+	if "`from'"!=""{
+		if "`difficulties'"!=""{
+			noi di in red "From option only available for unknow difficulties"
+			use `bddinip',replace 
+			error 100
+		}
+		if "`rsm'"!=""{
+			noi di in red "From option only available for the Partial Credit model"
+			use `bddinip',replace 
+			error 100
+		}
+	}
+
+	  /*************************************/
+	 /*		   Verifications			  */
+	/*************************************/
+
+	if "`iterate'"==""{
+		local it=""
+	}
+	else{
+		local iterateII="it(`iterate')"
+	}
+	tempvar one id item reponse obs wt x choix it covariable covverytemp
+	qui save `bddinib', replace
+	if "`difficulties'"!=""{
+		if `nbit2'!=`nbit'{
+			noi di in red "Not the same number of difficulty vectors and of items"
+			use `bddinip',replace 
+			error 100
+		}
+		forvalues i=1/`nbit'{
+			if strpos("`varlist'",word("`difficulties'",`i'))==0{
+				noi di in red "The item difficulty vectors must have the same names than the item variables"
+				use `bddinip',replace 
+				error 100
+			}
+		}
+	}
+	  /*************************************/
+	 /*	Estimation of the parameters	  */
+	/*************************************/
+	local nbtotmodacov=0
+	if `nbcov'!=0{
+		forvalues i=1/`nbcov'{
+			qui tab ``=`nbit'+`i''', matrow(`nom') matcell(`val')
+			local nbModCov`i'=r(r)
+			forvalues k=1/`nbModCov`i''{
+				local valmod`k'cov`i'=`nom'[`k',1]
+				local nbmod`k'cov`i'=`val'[`k',1]
+			}
+			local nbtotmodacov=`nbtotmodacov'+`nbModCov`i''
+			if `nbModCov`i''>15{
+				noi di in ye "Are you sure that ``=`nbit'+`i''' is a categorical variable? (``=`nbit'+`i''' has `nbModCov`i'' categories)"
+				noi di in gr ""
+			}
+			local tot`i'=r(N)
+			forvalues k=1/`nbModCov`i''{
+				local sum=0
+				forvalues k2=1/`nbModCov`i''{
+					if `k2'!=`k'{
+						local sum=`sum'+`val'[`k2',1]
+					}
+				}
+				local a`i'_`k'=round((`sum'-`tot`i'')/`tot`i'',0.01)
+				local b`i'_`k'=round((`sum')/`tot`i'',0.01)
+			}
+		}
+	}
+	local nbparcov=`nbtotmodacov'+`nbcovquant'
+	qui{
+		keep `varlist' `categorical' `continuous'
+		local nbdifftotbis=0
+		local nbdifftot=0
+		if "`difficulties'"=="" & "`rsm'"==""{
+			forvalues i=1/`nbit'{
+				gen `reponse'`i' = ``i''
+				drop ``i''
+				tab `reponse'`i'
+				local moda`i'=`=r(r)'
+				local nbdifftot=`nbdifftot'+`moda`i''-1
+				local nbdifftotbis=`nbdifftotbis'+`moda`i''-1
+			}
+		}
+		else if "`difficulties'"=="" & "`rsm'"!=""{
+			forvalues i=1/`nbit'{
+				gen `reponse'`i' = ``i''
+				drop ``i''
+				tab `reponse'`i'
+				local moda`i'=`=r(r)'
+				local nbdifftot=`nbdifftot'+1
+				local nbdifftotbis=`nbdifftotbis'+`moda`i''-1
+			}
+			local nbdifftot=`nbdifftot'+`nbtotmodait'-2
+		}
+		else{
+			forvalues i=1/`nbit'{
+				gen `reponse'`i' = ``i''
+				drop ``i''
+				local moda`i'=colsof(``i'')+1
+			}
+		}
+		if "`from'"!=""{
+			if `nbcov'!=0{
+				if `verifFrom'!=`nbtotmodacov'-`nbcov'+1+`nbdifftot'+`nbcovquant'{
+					noi di in red "Mismatch between the number of parameters to estimate and the number of provided parameters"
+					use `bddinip',replace 
+					error 100
+				}
+			}
+			else{
+				if `verifFrom'!=1+`nbdifftot'+`nbcovquant'{
+					noi di in red "Mismatch between the number of parameters to estimate and the number of provided parameters"
+					use `bddinip',replace 
+					error 100
+				}
+			}
+		}
+		gen `one'=1
+		su `one'
+		local Nbid=r(N)
+		collapse (sum) `wt'2=`one', by(`reponse'1-`reponse'`nbit' `categorical' `continuous')
+		gen `id'=_n
+		reshape long `reponse', i(`id') j(`item')
+		drop if `reponse'==.	
+		ologit `reponse' [fweight=`wt'2]
+		local LLL00=e(ll)
+		tempname eBLLL00
+		matrix `eBLLL00'=e(b)
+		gen `obs'=_n
+		su `wt'2
+		local ddlssIII=r(sum)-1
+		forvalues i=1/`nbit'{
+			expand `moda`i'' if `item'==`i'
+		}
+		by `obs', sort: gen `x'=_n-1
+		gen `choix'=`reponse'==`x'
+		tab `item', gen(`it')
+		forvalues i=1/`nbit'{
+			forvalues g=1/`=`moda`i''-1'{
+				gen d_``i''_`g'=(-1)*`it'`i'*(`x'>=`g')
+			}
+		}
+		forvalues i=1/`nbit'{
+			forvalues g=1/`=`moda`i''-1'{
+				capture gen __dd_`g'=0
+			}
+		}
+		forvalues i=1/`nbit'{
+			forvalues g=1/`=`moda`i''-1'{
+				replace  __dd_`g'=(-1)*`it'`i'*(`x'>=`g') if ((-1)*`it'`i'*(`x'>=`g'))<__dd_`g'
+			}
+		}
+		if "`difficulties'"!=""{
+			gen difficulties=0
+			forvalues i=1/`nbit'{
+				forvalues g=1/`=`moda`i''-1'{
+					replace difficulties=difficulties+``i''[1,`g']*d_``i''_`g'
+				}
+			}
+		}
+		if `nbcov'!=0{
+			forvalues i=1/`nbcov'{
+				gen `covverytemp'=``=`nbit'+`i'''
+				drop ``=`nbit'+`i'''
+				rename `covverytemp' ``=`nbit'+`i'''
+				tab ``=`nbit'+`i''', gen(``=`nbit'+`i'''__) matrow(`nom')
+				local nbModCov`i'=r(r)
+				forvalues k=1/`nbModCov`i''{
+					gen ``=`nbit'+`i'''__`k'_old=``=`nbit'+`i'''__`k'
+					order ``=`nbit'+`i'''__`k'_old, first
+					replace ``=`nbit'+`i'''__`k'=``=`nbit'+`i'''__`k'*`x'
+					local ident`i'_`k'=`nom'[`k',1]
+					if `k'==1 & `i'==1{
+						local ident1=`ident`i'_`k''
+					}
+					rename ``=`nbit'+`i'''__`k' ``=`nbit'+`i'''_`ident`i'_`k''
+				}
+			}
+			forvalues i=1/`nbcov'{
+				drop ``=`nbit'+`i'''
+			}
+		}
+		if `nbcovquant'!=0{
+			forvalues i=1/`nbcovquant'{
+				gen `covverytemp'=``=`nbit'+`nbcov'+`i'''*`x'
+				rename ``=`nbit'+`nbcov'+`i''' ``=`nbit'+`nbcov'+`i'''_old
+				rename `covverytemp' ``=`nbit'+`nbcov'+`i'''
+			}
+		}
+		rename `id' theta
+		rename `x' estimates
+	}
+	eq slope:estimates
+	gen obs=`obs'
+	gen choix=`choix'
+	gen wt=`wt'
+	local contrainte ""
+	local contrainteit ""
+	if "`rsm'"!="" & "`difficulties'"==""{
+		forvalues i=2/`nbit'{
+			forvalues j=2/`=`nbtotmodait'-1'{
+				constraint free
+				local con=r(free)
+				local contrainteit "`contrainteit' `con'"
+				constraint `con' d_`1'_`j'-d_`1'_1=d_``i''_`j'-d_``i''_1
+			}
+		}
+	}
+	local offset "offset(difficulties)"
+	local covariablesit ""
+	if "`difficulties'"==""{
+		local covariablesit "d_`1'_1-d_``nbit''_`=`moda`nbit''-1'"
+		local offset ""
+	}
+	local nbitdiffpara=0
+	forvalues i=1/`nbit'{
+		forvalues j=1/`=`moda`nbit''-1'{
+			local nbitdiffpara=`nbitdiffpara'+1
+		}
+	}
+	local covariables ""
+	if `nbcov'!=0{
+		local covariables "`covariables' ``=`nbit'+1''_`ident1'-``=`nbit'+`nbcov'''_`ident`nbcov'_`nbModCov`nbcov'''"
+		forvalues i=1/`nbcov'{
+			constraint free
+			local con=r(free)
+			local contrainte "`contrainte' `con'"
+			constraint `con' ``=`nbit'+`i'''_`ident`i'_1'=0
+		}
+	}
+	if `nbcovquant'!=0{
+		local covariables "`covariables' ``=`nbit'+`nbcov'+1''-``=`nbit'+`nbcov'+`nbcovquant'''"
+	}
+	tempname a
+	matrix `a'=(0,0)
+	local skipcopy "skip"
+	if "`difficulties'"==""{
+		if "`from'"!=""{
+			matrix `a'=`from'
+			local skipcopy "copy"
+		}
+	}
+	gen cons=estimates
+	local varcons ""
+	if "`difficulties'"!=""{
+		local varcons "cons"
+	}
+	  /**********************/
+	 /*Estimation du modĂšle*/
+	/**********************/
+
+	unab vars : `covariables' , min(0)
+	local _c1= `: word count `vars''
+	local _c2= `: word count `contrainte''
+	gllamm estimates `varcons' `covariablesit' `covariables' , `offset' i(theta) eqs(slope) link(mlogit) expand(`obs' `choix' o) weight(`wt') `adapt' `robust' nocons `iterateII'  nodis   constraint(`contrainteit' `contrainte') from(`a') `skipcopy'  `NIP' `trace'
+	local convergeance=e(converged)
+	tempname eB eV
+	matrix `eB'=e(b)
+	local nbc=colsof(`eB')
+	matrix `eV'=e(V)
+	local nbpar=e(k)
+	local nbN=e(N)
+	local LLfull=e(ll)
+	local ccnn=e(cn)
+	local dfree_ModComp=`ddlssIII'-`=colsof(`eB')'+ wordcount("`contrainteit' `contrainte'")
+	local SS_ModComp=(`eB'[1,`=colsof(`eB')']^2)*`dfree_ModComp'
+	local dfree_ModSsCov=`dfree_ModComp'+`nbparcov'- wordcount("`contrainte'")
+	local ordre=`ordre'- wordcount("`contrainteit'")+1
+	if "`rsm'"!=""{
+		tempname tau
+		matrix `tau'=J(2,`=`moda1'-1',.)
+		forvalues i=2/`=`moda1'-1'{
+			qui lincom d_`1'_`i'-d_`1'_1
+			local tau`i'=r(estimate)
+			local setau`i'=r(se)
+			matrix `tau'[1,`i']=`tau`i''
+			matrix `tau'[2,`i']=`setau`i''
+		}
+	}
+
+	qui{
+		capture su difficulties
+		if _rc==0{
+			gen difficultiespost=difficulties
+		}
+		else{
+			gen difficultiespost=0
+			local indent=1
+			forvalues i=1/`nbit'{
+				forvalues g=1/`=`moda`i''-1'{
+					replace difficultiespost=difficultiespost+`eB'[1,`indent']*d_``i''_`g'
+					local indent=1+`indent'
+				}
+			}
+		}
+		/* Commande GLLAMM qui est responsable de génération de matrices résiduelles */
+		qui gllamm estimates cons , offset(difficultiespost) i(theta) eqs(slope) link(mlogit) expand(`obs' `choix' o) weight(`wt') `adapt' `robust' nocons from(`eB') skip  `NIP'
+		tempname eB_tot
+		matrix `eB_tot'=e(b)
+		local SS_ModSsCov=(`eB_tot'[1,`=colsof(`eB_tot')']^2)*`dfree_ModSsCov'
+	}
+	local mugauss=`eB_tot'[1,1]
+	local sdgauss=abs(`eB_tot'[1,2])
+	if "`estimateonly'"==""{
+		noi di in gr " "
+		if `nbcov'+`nbcovquant'!=0{
+			noi di "McFadden's pseudo R square and type III Sums of squares computation"
+		}
+		else{
+			noi di "McFadden's pseudo R square computation"
+		}
+
+	  /**********************************************************/
+	 /* ModÚle nul (juste intercept et effets aléatoires -> R2 */
+	/**********************************************************/
+
+		qui gllamm estimates __dd_*  , i(theta) eqs(slope) link(mlogit) expand(`obs' `choix' o) weight(`wt') `adapt' `robust' nocons `iterateII' from(`a') skip  `NIP'
+		local LLinterSS=e(ll)
+		tempname eB4
+		matrix `eB4'=e(b)
+		local R2Nag=1-(`LLfull'/`LLinterSS')
+
+	  /*****************/
+	 /* Calcul des SS */
+	/*****************/
+		qui{
+			local covariables2 ""
+			forvalues covs=`=`nbit'+1'/`=`nbit'+`nbcov''{
+				local covariables2 "`covariables2' ``covs''_`ident`=`covs'-`nbit''_1'-``covs''_`ident`=`covs'-`nbit''_`nbModCov`=`covs'-`nbit''''"
+			}
+			forvalues covs=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+				local covariables2 "`covariables2' ``covs''"
+			}
+			if `nbcov'+`nbcovquant'!=0{
+				forvalues covs=`=`nbit'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+					noi di "                for " in ye "``covs''" in gr " covariate"
+					if strpos("`categorical'","``covs''")!=0 & "``covs''"!=""{
+						local covsans= subinword("`covariables2'","``covs''_`ident`=`covs'-`nbit''_1'-``covs''_`ident`=`covs'-`nbit''_`nbModCov`=`covs'-`nbit''''","",.)
+						local dfree_Mss``covs''=`dfree_ModComp'+ `nbModCov`=`covs'-`nbit'''-1
+					}
+					else{
+						local covsans= subinword("`covariables2'","``covs''","",.)
+						local dfree_Mss``covs''=`dfree_ModComp'+1
+					}
+					capture constraint drop `contrainterep' 
+					local contrainterep ""
+					if `nbcov'!=0{
+						forvalues i=1/`nbcov'{
+							if `=`nbit'+`i''!=`covs'{
+								constraint free
+								local con=r(free)
+								local contrainterep "`contrainterep' `con'"
+								constraint `con' ``=`nbit'+`i'''_`ident`i'_1'=0
+							}
+						}
+					}
+					gllamm estimates cons `covsans' , offset(difficultiespost) i(theta) eqs(slope) link(mlogit) expand(`obs' `choix' o) weight(`wt') `adapt' `robust' nocons `iterateII'   constraint(`contrainterep') from(`eB') skip  `NIP'
+					tempname eB``covs''
+					matrix `eB``covs'''=e(b)
+					local SS_Mss``covs''=(`eB``covs'''[1,`=colsof(`eB``covs''')']^2)*`dfree_Mss``covs'''
+					local LLfullmoin=e(ll)
+					tempname eB4
+					matrix `eB4'=e(b)
+					local R2N_``covs''=1-(`LLfullmoin'/`LLinterSS')
+					tempname eB2
+					matrix `eB2'=e(b)
+					local nbpar2=e(k)				
+				}
+			}
+		}
+		noi di in gr " "
+	}
+	di in gr ""
+	if "`rsm'"!=""{
+		di in gr "Model : " in ye "Rating Scale Model"
+	}
+	else{
+		di in gr "Model : " in ye "Partial Credit Model"
+	}
+	di in gr ""
+	di in gr "                log likelihood: " in ye %-18.3f `LLfull'
+	local lll=e(ll)
+	if "`estimateonly'"==""{
+		di in gr "                Marginal McFadden's pseudo R2: " in ye %-4.1f `=`R2Nag'*100' "%"
+	}
+	di in gr "                Number of individuals: "in ye "`Nbid'"
+	di in gr "                Number of items: "in ye "`nbit'"
+	if `=`nbcov'+`nbcovquant''!=0{
+		di in gr "                Number of covariates: "in ye "`=`nbcov'+`nbcovquant''"
+	}
+	di in gr ""
+	di ""
+	di in gr "Parameters of the Latent trait distribution:"
+	di ""
+	local contrR ""
+	if "`difficulties'"==""{
+		if `=`nbcov'+`nbcovquant''!=0{
+			local subgroup0 ""
+			if `nbcov'!=0{
+				forvalues i=1/`nbcov'{
+					local subgroup0 "`subgroup0'``=`nbit'+`i''' = `ident`i'_1', "
+				}	
+			}
+			if `nbcovquant'!=0{
+				forvalues i=1/`nbcovquant'{
+					local subgroup0 "`subgroup0'``=`nbit'+`nbcov'+`i''' = 0, "
+				}
+			}
+			local subgroup0b "`=reverse(subinstr(reverse("`subgroup0'"), ",", ":", 1))'"
+			local contrR "latent trait for `subgroup0b'"
+		}
+		else{
+		
+			local contrR "overall latent trait mean "
+		}
+		di in gr "                Identifiability constraint: `contrR'set to 0"
+	}
+	di in gr "		  Variance of the Latent trait: SigmaÂČ=" in ye %-8.3f (`=`=`eB'[1,`nbc']'')^2 in gr " (SE:"in ye %-8.3f `= sqrt((2*`=`eB'[1,`nbc']')^2 *`=`eV'[`nbc',`nbc']'	)' in gr ")"
+	local varTheta=(`=`=`eB'[1,`nbc']'')^2
+	local Varvartheta=(2*`=`eB'[1,`nbc']')^2 *`=`eV'[`nbc',`nbc']'
+	di ""
+	if `nbcov'+`nbcovquant'!=0{
+		if "`estimateonly'"=="" & `=`nbcov'+`nbcovquant''>0 {
+			tempname VarExpSS
+			matrix `VarExpSS'=J(`=`nbcov'+`nbcovquant'+2',4,.)
+			local compte=1
+			if `nbcov'!=0{
+				forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+					matrix `VarExpSS'[`compte',1]=`SS_Mss``i'''-`SS_ModComp'
+					matrix `VarExpSS'[`compte',2]=`dfree_Mss``i'''-`dfree_ModComp'
+					matrix `VarExpSS'[`compte',3]=(`SS_Mss``i'''-`SS_ModComp')/`SS_Mss``i'''*100
+					matrix `VarExpSS'[`compte',4]=(`R2Nag'-`R2N_``i''')/`R2Nag'*100
+					local compte=`compte'+1
+				}
+			}
+			if `nbcovquant'!=0{
+				forvalues i=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+					matrix `VarExpSS'[`compte',1]=`SS_Mss``i'''-`SS_ModComp'
+					matrix `VarExpSS'[`compte',2]=`dfree_Mss``i'''-`dfree_ModComp'
+					matrix `VarExpSS'[`compte',3]=(`SS_Mss``i'''-`SS_ModComp')/`SS_Mss``i'''*100
+					matrix `VarExpSS'[`compte',4]=(`R2Nag'-`R2N_``i''')/`R2Nag'*100
+					local compte=`compte'+1
+				}
+			}
+			matrix `VarExpSS'[`=`compte'',1]=`SS_ModSsCov'
+			matrix `VarExpSS'[`=`compte'',2]=`dfree_ModSsCov'
+			matrix `VarExpSS'[`=`compte'+1',1]=`SS_ModComp'
+			matrix `VarExpSS'[`=`compte'+1',2]=`dfree_ModComp'
+		}
+		if c(linesize)>=101{
+			di in gr "Latent trait group effect:"
+			di ""
+			di in gr "{hline 101}"
+			di _col(20) in gr "Coef." _col(30) in gr "S.E." _col(41) in gr "z" _col(45) in gr "P>|z|" _col(57) in gr "[`level'% C.I.]" _col(73) in gr "SS.III" _col(81) in gr "df" _col(85) in gr "V.exp." _col(95) in gr "R2.exp."
+			di in gr "{hline 101}"
+			local compteur=1
+			if "`difficulties'"==""{
+				local compteur=`nbdifftotbis'
+			}
+			if `nbcov'!=0{
+				forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+					local ss3=.
+					local df=.
+					local vexp=.
+					local r2exp=.
+					if "`estimateonly'"==""{
+						local ss3=`SS_Mss``i'''-`SS_ModComp'
+						local df=`dfree_Mss``i'''-`dfree_ModComp'
+						local vexp=(`SS_Mss``i'''-`SS_ModComp')/`SS_Mss``i'''*100
+						local r2exp=(`R2Nag'-`R2N_``i''')/`R2Nag'*100
+					}
+					local compteur=`compteur'+1
+					noi{
+						di _col(1) in gr "``i'':"  _col(72) in ye %6.3f `ss3'	 _col(81) in ye %2.0f  `df'  _col(84) in ye %6.1f `vexp' "%"    _col(94) in ye %6.1f  `r2exp' "%"
+						di _col(4) in gr "`=abbrev("``i''",10)':" in ye " `ident`=`i'-`nbit''_1'" _col(24) in ye  "0" _col(33) in ye "." _col(41) in ye "." _col(49) in ye "." _col(57) in ye "." _col(66) in ye "."  
+					}
+					forvalues k=2/`nbModCov`=`i'-`nbit'''{
+						local compteur=`compteur'+1
+						local estimate_e=`eB'[1,`compteur']
+						local se_e=sqrt(`=`eV'[`compteur',`compteur']')
+						noi{
+							di _col(4) in gr "`=abbrev("``i''",10)':" in ye " `ident`=`i'-`nbit''_`k''" _col(19) in ye %6.3f `estimate_e' _col(28) in ye %6.3f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %6.3f `=`estimate_e'-`=(1+`level'/100)/2'*`se_e'' _col(61) in ye %6.3f `=`estimate_e'+`=(1+`level'/100)/2'*`se_e''	
+						}
+					}
+					di in gr "{hline 101}"
+				}
+			}	
+			if `nbcovquant'!=0{
+				forvalues i=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+					local ss3=.
+					local df=.
+					local vexp=.
+					local r2exp=.
+					if "`estimateonly'"==""{
+						local ss3=`SS_Mss``i'''-`SS_ModComp'
+						local df=`dfree_Mss``i'''-`dfree_ModComp'
+						local vexp=(`SS_Mss``i'''-`SS_ModComp')/`SS_Mss``i'''*100
+						local r2exp=(`R2Nag'-`R2N_``i''')/`R2Nag'*100
+					}
+					local compteur=`compteur'+1
+						local estimate_e=`eB'[1,`compteur']
+						local se_e=sqrt(`=`eV'[`compteur',`compteur']')
+					noi{		
+						di _col(1) in gr "``i'':" _col(19) in ye %6.3f `estimate_e' _col(28) in ye %6.3f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %6.3f `=`estimate_e'-`=(1+`level'/100)/2'*`se_e'' _col(61) in ye %6.3f `=`estimate_e'+`=(1+`level'/100)/2'*`se_e''   _col(72) in ye %6.3f `ss3'	 _col(81) in ye %2.0f  `df'  _col(84) in ye %6.1f `vexp' "%"    _col(94) in ye %6.1f  `r2exp' "%"
+					}
+					di in gr "{hline 101}"
+				}
+			}	
+			if "`difficulties'"!=""{
+				di _col(1) in gr "_Cons" _col(19) in ye %6.3f `=`eB'[1,1]' _col(28) in ye %6.3f `=sqrt(`eV'[1,1])' _col(37) in ye %5.2f `=`=`eB'[1,1]'/`=sqrt(`eV'[1,1])'' _col(44) in ye %6.3f `=2*(1-normal(abs(`=`eB'[1,1]'/`=sqrt(`eV'[1,1])')))'  _col(52) in ye %6.3f `=`=`eB'[1,1]'-`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1])'' _col(61) in ye %6.3f `=`=`eB'[1,1]'+`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1])''
+				di in gr "{hline 101}"
+			}
+			local sssc=.
+			local dfsc=.
+			local ssac=.
+			local dfac=.
+			if "`estimateonly'"==""{
+				local sssc=`SS_ModSsCov'
+				local dfsc=`dfree_ModSsCov'
+				local ssac=`SS_ModComp'
+				local dfac=`dfree_ModComp'
+			}
+			di _col(73) in gr "SS.res" _col(84) in gr "df"
+			di _col(45) in gr "Model without covariates" _col(72) in ye %6.3f `sssc'  _col(81) in ye %5.0f `dfsc'
+			di _col(59) in gr "Full model" _col(72) in ye %6.3f `ssac'  _col(81) in ye %5.0f `dfac'
+			di in gr "{hline 101}"
+			di ""
+		}
+		else{
+			di in gr "Latent trait group effect:"
+			di ""
+			di in gr "{hline 66}"
+			di _col(20) in gr "Coef." _col(30) in gr "S.E." _col(41) in gr "z" _col(45) in gr "P>|z|" _col(57) in gr "[`level'% C.I.]"
+			di in gr "{hline 66}"
+			local compteur=1
+			if "`difficulties'"==""{
+				local compteur=`nbdifftotbis'
+			}
+			if `nbcov'!=0{
+				forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+					local compteur=`compteur'+1
+					noi{
+						di _col(1) in gr "``i'':" 
+						di _col(4) in gr "`=abbrev("``i''",10)':" in ye " `ident`=`i'-`nbit''_1'" _col(24) in ye  "0" _col(33) in ye "." _col(41) in ye "." _col(49) in ye "." _col(57) in ye "." _col(66) in ye "."	
+					}
+					forvalues k=2/`nbModCov`=`i'-`nbit'''{
+						local compteur=`compteur'+1
+						local estimate_e=`eB'[1,`compteur']
+						local se_e=sqrt(`=`eV'[`compteur',`compteur']')
+						noi{
+							di _col(4) in gr "`=abbrev("``i''",10)':" in ye " `ident`=`i'-`nbit''_`k''" _col(19) in ye %6.3f `estimate_e' _col(28) in ye %6.3f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %6.3f `=`estimate_e'-`=(1+`level'/100)/2'*`se_e'' _col(61) in ye %6.3f `=`estimate_e'+`=(1+`level'/100)/2'*`se_e''	
+						}
+					}
+					di in gr "{hline 66}"
+				}
+			}	
+			if `nbcovquant'!=0{
+				forvalues i=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+					local compteur=`compteur'+1
+						local estimate_e=`eB'[1,`compteur']
+						local se_e=sqrt(`=`eV'[`compteur',`compteur']')
+					noi{		
+						di _col(1) in gr "``i'':" _col(19) in ye %6.3f `estimate_e' _col(28) in ye %6.3f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %6.3f `=`estimate_e'-`=(1+`level'/100)/2'*`se_e'' _col(61) in ye %6.3f `=`estimate_e'+`=(1+`level'/100)/2'*`se_e'' 
+					}
+					di in gr "{hline 66}"
+				}
+			}	
+			if "`difficulties'"!=""{
+				di _col(1) in gr "_Cons" _col(19) in ye %6.3f `=`eB'[1,1]' _col(28) in ye %6.3f `=sqrt(`eV'[1,1])' _col(37) in ye %5.2f `=`=`eB'[1,1]'/`=sqrt(`eV'[1,1])'' _col(44) in ye %6.3f `=2*(1-normal(abs(`=`eB'[1,1]'/`=sqrt(`eV'[1,1])')))'  _col(52) in ye %6.3f `=`=`eB'[1,1]'-`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1])'' _col(61) in ye %6.3f `=`=`eB'[1,1]'+`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1])''
+				di in gr "{hline 66}"
+			}
+			if "`estimateonly'"==""{
+				di ""
+				di "Proportion of latent trait variance explained by covariates"
+				di ""
+				di in gr "{hline 53}"
+				di _col(23) in gr "SS.III" _col(34) in gr "df" _col(38) in gr "V.exp." _col(47) in gr "R2.exp."
+				di in gr "{hline 53}"
+				local compteur=1
+				if "`difficulties'"==""{
+					local compteur=`nbdifftotbis'
+				}
+				if `nbcov'!=0{
+					forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+						local ss3=`SS_Mss``i'''-`SS_ModComp'
+						local df=`dfree_Mss``i'''-`dfree_ModComp'
+						local vexp=(`SS_Mss``i'''-`SS_ModComp')/`SS_Mss``i'''*100
+						local r2exp=(`R2Nag'-`R2N_``i''')/`R2Nag'*100
+						local compteur=`compteur'+1
+						noi di _col(1) in gr "``i'':"  _col(22) in ye %6.3f `ss3'	 _col(34) in ye %2.0f  `df'  _col(37) in ye %6.1f `vexp' "%"    _col(46) in ye %6.1f  `r2exp' "%"
+					}
+				}
+				if `nbcovquant'!=0{
+					forvalues i=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+						local ss3=`SS_Mss``i'''-`SS_ModComp'
+						local df=`dfree_Mss``i'''-`dfree_ModComp'
+						local vexp=(`SS_Mss``i'''-`SS_ModComp')/`SS_Mss``i'''*100
+						local r2exp=(`R2Nag'-`R2N_``i''')/`R2Nag'*100
+						local compteur=`compteur'+1
+						noi di _col(1) in gr "``i'':" _col(22) in ye %6.3f `ss3'	 _col(34) in ye %2.0f  `df'  _col(37) in ye %6.1f `vexp' "%"    _col(46) in ye %6.1f  `r2exp' "%"
+					}
+				}
+				di in gr "{hline 53}"
+				local sssc=`SS_ModSsCov'
+				local dfsc=`dfree_ModSsCov'
+				local ssac=`SS_ModComp'
+				local dfac=`dfree_ModComp'
+				di _col(23) in gr "SS.res" _col(34) in gr "df"
+				di _col(1) in gr "Model without cov." _col(22) in ye %6.3f `sssc'  _col(31) in ye %5.0f `dfsc'
+				di _col(1) in gr "Full model" _col(22) in ye %6.3f `ssac'  _col(31) in ye %5.0f `dfac'
+				di in gr "{hline 53}"
+				di ""
+			}
+		}
+	}
+	else if "`difficulties'"!=""{
+		di in gr "Latent trait distribution"
+		di in gr "{hline 80}"
+		di _col(18) in gr "Coef." _col(31) in gr "S.E." _col(43) in gr "z" _col(52) in gr "P>|z|" _col(61) in gr "[`level'% Conf. Interval]"
+		di in gr "{hline 80}"
+		di _col(1) in gr "Mu" _col(15) in ye %8.5f `=`eB'[1,1]' _col(27) in ye %8.5f `=sqrt(`eV'[1,1]) ' _col(39) in ye %5.2f `=`=`eB'[1,1]'/`=sqrt(`eV'[1,1]) '' _col(51) in ye %6.3f `=2*(1-normal(abs(`=`eB'[1,1]'/`=sqrt(`eV'[1,1]) ')))'  _col(61) in ye %8.5f `=`=`eB'[1,1]'-`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1]) '' _col(73) in ye %8.5f `=`=`eB'[1,1]'+`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1]) ''
+	
+		di _col(1) in gr "Sigma" _col(15) in ye %8.5f `=abs(`eB'[1,`nbc'])' _col(27) in ye %8.5f `=sqrt(`=`eV'[`nbc',`nbc']')' _col(39) in ye %5.2f `=`eB'[1,`nbc']/sqrt(`=`eV'[`nbc',`nbc']')' _col(51) in ye %6.3f `=2*(1-normal(abs(`eB'[1,`nbc']/sqrt(`=`eV'[`nbc',`nbc']'))))'  _col(61) in ye %8.5f `=`eB'[1,`nbc']-`=(1+`level'/100)/2'*sqrt(`=`eV'[`nbc',`nbc']')' _col(73) in ye %8.5f `=`eB'[1,`nbc']+`=(1+`level'/100)/2'*sqrt(`=`eV'[`nbc',`nbc']')'
+		di in gr "{hline 80}"
+		di ""
+	}	
+	if "`difficulties'"==""{
+		di in gr "Items difficulty parameters:"
+		di ""
+		di in gr "{hline 52}"
+		di _col(1) in gr "Item"  _col(21) in gr "Coef." _col(31) in gr "S.E."   _col(43) in gr "[`level'% C.I.]" _col(66) 
+		di in gr "{hline 52}"
+		local compteur=1
+		if "`rsm'"==""{
+			forvalues i=1/`nbit'{
+				di _col(1) in gr "``i'':" 
+				forvalues g=1/`=`moda`i''-1'{
+					di _col(4) in gr "response: " in ye %-6.2g `=`rep__`i''[`=`g'+1',1]' _col(20) in ye %6.3f `=`eB'[1,`compteur']' _col(29) in ye %6.3f `=sqrt(`=`eV'[`compteur',`compteur']')'   _col(38) in ye %6.3f `=`eB'[1,`compteur']-`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' _col(47) in ye %6.3f `=`eB'[1,`compteur']+`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' 
+					local compteur=`compteur'+1
+				}
+				di in gr "{hline 52}"
+			}
+			di ""
+		}
+		else{
+			forvalues i=1/`nbit'{
+				di _col(1) in gr "``i'':"   _col(20) in ye %6.3f `=`eB'[1,`compteur']' _col(29) in ye %6.3f `=sqrt(`=`eV'[`compteur',`compteur']')'   _col(38) in ye %6.3f `=`eB'[1,`compteur']-`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' _col(47) in ye %6.3f `=`eB'[1,`compteur']+`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' 
+				local compteur=`compteur'+`=`moda1'-1'
+			}
+			di in gr "{hline 52}"
+			forvalues i=2/`=`moda1'-1'{
+				di _col(1) in gr "tau`=`i'-1':"  _col(20) in ye %6.3f `tau`i'' _col(29) in ye %6.3f `setau`i''   _col(38) in ye %6.3f `=`tau`i''-`=(1+`level'/100)/2'*`setau`i''' _col(47) in ye %6.3f `=`tau`i''+`=(1+`level'/100)/2'*`setau`i''' 
+			}
+			di in gr "{hline 52}"
+		}
+	}
+	else{
+		di in gr "Items difficulty parameters: fixed for the analysis"
+	}
+
+	  /*************************************/
+	 /*	             ereturn              */
+	/*************************************/
+
+	qui{
+		if "`difficulties'"==""{
+	tempname Varbeta Vardelta beta delta Vartheta theta
+			matrix `Varbeta'=`eV'
+			local Varsigma=`Varbeta'[`=colsof(`Varbeta')',`=colsof(`Varbeta')']
+			matrix `Vardelta'=`Varbeta'[1..`nbdifftotbis',1..`nbdifftotbis']
+			matrix `beta'=`eB'
+			local sigma=abs(`beta'[1,`=colsof(`beta')'])
+			matrix `delta'=`beta'[1,1..`nbdifftotbis']
+			if `=`nbcov'+`nbcovquant''!=0{
+				matrix `Vartheta'=`Varbeta'[`=`nbdifftotbis'+1'..`=colsof(`Varbeta')-1',`=`nbdifftotbis'+1'..`=colsof(`Varbeta')-1']
+				matrix `theta'=`beta'[1,`=`nbdifftotbis'+1'..`=colsof(`beta')-1']
+			}
+			else{
+				local thetas=0
+				local Varthetas=0
+			}
+		}
+		else{
+			if `=`nbcov'+`nbcovquant''!=0{
+				tempname Vartheta theta
+				matrix `Vartheta'=`eV'
+				local Varsigma=`Vartheta'[`=colsof(`Vartheta')',`=colsof(`Vartheta')']
+				matrix `Vartheta'=`Vartheta'[1..`=colsof(`Vartheta')-1',1..`=colsof(`Vartheta')-1']
+				matrix `theta'=`eB'
+				local sigma=abs(`theta'[1,`=colsof(`theta')'])
+				matrix `theta'=`theta'[1,1..`=colsof(`theta')-1']
+			}
+			else{
+				tempname theta Vtheta
+				matrix `theta'=`eB'
+				local sigma=abs(`theta'[1,`=colsof(`theta')'])
+				matrix `Vtheta'=`eV'
+				local Varsigma=`Vtheta'[`=colsof(`Vtheta')',`=colsof(`Vtheta')']
+				local thetas=`theta'[1,1]
+				local varthetas=`Vtheta'[1,1]
+			}
+		}
+		ereturn clear
+		if `=`nbcov'+`nbcovquant''!=0{
+			matrix b=`eB'
+			matrix V=`eV'
+			ereturn post b V, depname(theta)
+			ereturn matrix theta=`theta'
+			ereturn matrix Vartheta=`Vartheta'
+		}
+		else{
+			if "`difficulties'"==""{
+				matrix V=`eV'
+				tempname thetatemp Varthetatemp
+				matrix `thetatemp'=(0)
+				matrix `Varthetatemp'=(0)
+				matrix coleq `Varthetatemp'=estimates
+				matrix coln `Varthetatemp'=mu
+				matrix roweq `Varthetatemp'=estimates
+				matrix rown `Varthetatemp'=mu
+				matrix b=`eB'
+				matrix coleq `thetatemp'=estimates
+				matrix coln `thetatemp'=mu
+				matrix rown `thetatemp'=y1
+				ereturn post b V, depname(theta)
+				ereturn matrix theta=`thetatemp'
+				ereturn matrix Vartheta=`Varthetatemp'
+			}
+			else{
+				tempname thetatemp Varthetatemp
+				matrix `Varthetatemp'=(`varthetas')
+				matrix coleq `Varthetatemp'=estimates
+				matrix coln `Varthetatemp'=mu
+				matrix roweq `Varthetatemp'=estimates
+				matrix rown `Varthetatemp'=mu
+				matrix `thetatemp'=(`thetas')
+				matrix coleq `thetatemp'=estimates
+				matrix coln `thetatemp'=mu
+				matrix rown `thetatemp'=y1
+				matrix V=`eV'
+				matrix b=`eB'
+				ereturn post b V, depname(theta)
+				tempname vvvt vvvVt
+				matrix `vvvt'=(`thetas')
+				matrix `vvvVt'=(`varthetas')
+				ereturn matrix theta=`vvvt'
+				ereturn matrix Vartheta=`vvvVt'
+			}
+		}
+		ereturn scalar ll=`LLfull'
+		ereturn scalar cn=`ccnn'
+		ereturn scalar r2=`R2Nag'
+		ereturn scalar N=`Nbid'
+		ereturn scalar Nit=`nbit'
+		ereturn scalar converged=`convergeance'
+		ereturn scalar ndtb=`nbdifftotbis'
+		ereturn scalar mugauss=`mugauss'
+		ereturn scalar sdgauss=`sdgauss'
+		if "`nip'"!=""{
+		ereturn scalar nip=`nip'
+		}
+		ereturn local items `varlist'
+		ereturn local categorical `categorical'
+		ereturn local continuous `continuous'
+		ereturn local estimateonly `estimateonly'
+		ereturn local constr `contrR'
+		ereturn local difficulties `difficulties'
+		if `nbcov'!=0{
+			forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+				local ``i''_m ""
+				forvalues k=1/`nbModCov`=`i'-`nbit'''{
+					local ``i''_m "```i''_m' `ident`=`i'-`nbit''_`k''"
+					ereturn local ``i'' ```i''_m'
+				}
+			}
+		}
+		ereturn local rsm `rsm'
+		ereturn local from `from'
+		ereturn local robust `robust'
+		ereturn local adapt `adapt'
+		ereturn local iterate `iterate'
+		ereturn local itest `itest'
+		ereturn local datatest `bddinib' 
+		ereturn local if `if'
+		ereturn local in `in'
+		ereturn local cmd "pcmodel"
+		ereturn scalar order=`ordre'
+		if `=`nbcov'+`nbcovquant''!=0{
+			ereturn scalar Ncat=`nbcov'
+			ereturn scalar Ncont=`nbcovquant'
+		}
+		if "`difficulties'"==""{
+			ereturn matrix Vardelta=`Vardelta'
+			ereturn matrix delta=`delta'
+			ereturn scalar sigma=`sigma'
+			ereturn scalar Varsigma=`Varsigma'
+			if "`rsm'"!=""{
+				ereturn matrix Tau=`tau'
+			}
+		}
+		else{ 
+			if `=`nbcov'+`nbcovquant''!=0{
+				ereturn scalar sigma=`sigma'
+				ereturn scalar Varsigma=`Varsigma'
+			}
+			else{
+				ereturn scalar sigma=`sigma'
+				ereturn scalar Varsigma=`Varvartheta'
+			}
+		}
+		if "`estimateonly'"=="" & `=`nbcov'+`nbcovquant''>0 {
+			ereturn matrix VarExpSS `VarExpSS'
+		}
+	}
+use `bddinip', replace
+}
+restore
+end
diff --git a/Modules/ado/personal/p/pcmodel_v.ado b/Modules/ado/personal/p/pcmodel_v.ado
new file mode 100644
index 0000000..3228fd1
--- /dev/null
+++ b/Modules/ado/personal/p/pcmodel_v.ado
@@ -0,0 +1,1140 @@
+/********************************************************************************/
+/* v1.1 : Bug fixed regarding the estimation of the latent trait standard error */
+/* v2 : Bugs with temporary names fixed, New options have been added,           */
+/*      modifications of the output                                             */
+/********************************************************************************/
+
+program define pcmodel, eclass
+version 11.0
+syntax [varlist] [if] [in] [, CATegorical(string) CONTinuous(string) DIFficulties(string) ITerate(string)  ADapt RObust From(string) RSM ESTimateonly nip(string) TRace Level(string)]
+
+preserve
+tempfile bddinip
+qui save `bddinip',replace
+local Cond=0
+
+if "`level'"==""{
+	local level=c(level)
+}
+
+
+if replay() {
+	capture local cmdavant=e(cmd)
+	if _rc!=0 | "`cmdavant'"!="pcmodel"{
+		noi di in red "pcmodel was not the last command"
+		error 100
+	}
+	if "`categorical'`continuous'`difficulties'`iterate'`adapt'`robust'`from'`rsm'`estimateonly'`nip'"==""{
+		local rsm=e(rsm)
+		local LLfull=e(ll)
+		local estimateonly=e(estimateonly)
+		local R2Nag=e(r2)
+		local Nbid=e(N)
+		local nbit=e(Nit)
+		local categorical=e(categorical)
+		local continuous=e(continuous)
+		if "`continuous'"=="."{
+			local continuous=""
+		}
+		if "`categorical'"=="."{
+			local categorical=""
+		}
+		local nbcov: word count `categorical'
+		local nbcovquant: word count `continuous'
+		local varlist=e(items)
+		tokenize `varlist' `categorical' `continuous'
+		local difficulties=e(difficulties)
+		local contrR=e(constr)
+		tempname eB eV VarExpSS
+		matrix `eB'=e(b)
+		matrix `eV'=e(V)
+		matrix `VarExpSS'=e(VarExpSS)
+		local nbc=colsof(`eB')
+		local nbdifftotbis=e(ndtb)
+		if `nbcov'!=0{
+			forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+				local ``i''_m=e(``i'')
+				local k=1
+				local nbModCov`=`i'-`nbit''=wordcount("```i''_m'")
+				foreach m in ```i''_m'{
+					local ident`=`i'-`nbit''_`k'=`m'
+					local k=`k'+1
+				}
+			}
+		}
+		if "`rsm'"!="."{
+			di in gr "Model : " in ye "Rating Scale Model"
+		}
+		else{
+			di in gr "Model : " in ye "Partial Credit Model"
+		}
+		di in gr ""
+		di in gr "                log likelihood: " in ye %-18.3f `LLfull'
+		if "`estimateonly'"=="."{
+			di in gr "                Marginal McFadden's pseudo R2: " in ye %-4.1f `=`R2Nag'*100' "%"
+		}
+		di in gr "                Number of individuals: "in ye "`Nbid'"
+		di in gr "                Number of items: "in ye "`nbit'"
+		if `=`nbcov'+`nbcovquant''!=0{
+			di in gr "                Number of covariates: "in ye "`=`nbcov'+`nbcovquant''"
+		}
+		di in gr ""
+		di ""
+		di in gr "Parameters of the Latent trait distribution:"
+		di ""
+		if "`difficulties'"=="."{
+			di in gr "                Identifiability constraint: `contrR'set to 0"
+		}
+		di in gr "		  Variance of the Latent trait: SigmaÂČ=" in ye %-8.3f (`=`=`eB'[1,`nbc']'')^2 in gr " (SE:"in ye %-8.3f `= sqrt((2*`=`eB'[1,`nbc']')^2 *`=`eV'[`nbc',`nbc']'	)' in gr ")"
+		local varTheta=(`=`=`eB'[1,`nbc']'')^2
+		local Varvartheta=(2*`=`eB'[1,`nbc']')^2 *`=`eV'[`nbc',`nbc']'
+		di ""
+		if `nbcov'+`nbcovquant'!=0{
+			di in gr "Latent trait group effect:"
+			di ""
+			di in gr "{hline 66}"
+			di _col(20) in gr "Coef." _col(30) in gr "S.E." _col(41) in gr "z" _col(45) in gr "P>|z|" _col(57) in gr "[`level'% C.I.]"
+			di in gr "{hline 66}"
+			local compteur=1
+			if "`difficulties'"=="."{
+				local compteur=`nbdifftotbis'
+			}
+			if `nbcov'!=0{
+				forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+					local compteur=`compteur'+1
+					noi{
+						di _col(1) in gr "``i'':" 
+							di _col(4) in gr "`=abbrev("``i''",10)':" in ye " `ident`=`i'-`nbit''_1'" _col(24) in ye  "0" _col(33) in ye "." _col(41) in ye "." _col(49) in ye "." _col(57) in ye "." _col(66) in ye "."
+					}
+					forvalues k=2/`nbModCov`=`i'-`nbit'''{
+						local compteur=`compteur'+1
+						local estimate_e=`eB'[1,`compteur']
+						local se_e=sqrt(`=`eV'[`compteur',`compteur']')
+						noi{
+							di _col(4) in gr "`=abbrev("``i''",10)':" in ye " `ident`=`i'-`nbit''_`k''" _col(19) in ye %6.3f `estimate_e' _col(28) in ye %6.3f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %6.3f `=`estimate_e'-`=(1+`level'/100)/2'*`se_e'' _col(61) in ye %6.3f `=`estimate_e'+`=(1+`level'/100)/2'*`se_e''
+						}
+					}
+					di in gr "{hline 66}"
+				}
+			}
+			if `nbcovquant'!=0{
+				forvalues i=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+					local compteur=`compteur'+1
+						local estimate_e=`eB'[1,`compteur']
+						local se_e=sqrt(`=`eV'[`compteur',`compteur']')
+					noi{		
+						di _col(1) in gr "``i'':" _col(19) in ye %6.3f `estimate_e' _col(28) in ye %6.3f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %6.3f `=`estimate_e'-`=(1+`level'/100)/2'*`se_e'' _col(61) in ye %6.3f `=`estimate_e'+`=(1+`level'/100)/2'*`se_e'' 
+					}
+					di in gr "{hline 66}"
+				}
+			}
+			if "`difficulties'"!="."{
+				di _col(1) in gr "_Cons" _col(19) in ye %6.3f `=`eB'[1,1]' _col(28) in ye %6.3f `=sqrt(`eV'[1,1])' _col(37) in ye %5.2f `=`=`eB'[1,1]'/`=sqrt(`eV'[1,1])'' _col(44) in ye %6.3f `=2*(1-normal(abs(`=`eB'[1,1]'/`=sqrt(`eV'[1,1])')))'  _col(52) in ye %6.3f `=`=`eB'[1,1]'-`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1])'' _col(61) in ye %6.3f `=`=`eB'[1,1]'+`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1])''
+				di in gr "{hline 66}"
+			}
+			if "`estimateonly'"=="."{
+				di ""
+				di "Proportion of latent trait variance explained by covariates"
+				di ""
+				di in gr "{hline 53}"
+				di _col(23) in gr "SS.III" _col(34) in gr "df" _col(38) in gr "V.exp." _col(47) in gr "R2.exp."
+				di in gr "{hline 53}"
+				local compteur=1
+				if "`difficulties'"=="."{
+					local compteur=`nbdifftotbis'
+				}
+				local compte=1
+				if `nbcov'!=0{
+					forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+						local ss3=`VarExpSS'[`compte',1]
+						local df=`VarExpSS'[`compte',2]
+						local vexp=`VarExpSS'[`compte',3]
+						local r2exp=`VarExpSS'[`compte',4]
+						local compteur=`compteur'+1
+						local compte=`compte'+1
+						noi di _col(1) in gr "``i'':"  _col(22) in ye %6.3f `ss3'	 _col(34) in ye %2.0f  `df'  _col(37) in ye %6.1f `vexp' "%"    _col(46) in ye %6.1f  `r2exp' "%"
+					}
+				}
+				if `nbcovquant'!=0{
+					forvalues i=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+						local ss3=`VarExpSS'[`compte',1]
+						local df=`VarExpSS'[`compte',2]
+						local vexp=`VarExpSS'[`compte',3]
+						local r2exp=`VarExpSS'[`compte',4]
+						local compteur=`compteur'+1
+						local compte=`compte'+1
+						noi di _col(1) in gr "``i'':" _col(22) in ye %6.3f `ss3'	 _col(34) in ye %2.0f  `df'  _col(37) in ye %6.1f `vexp' "%"    _col(46) in ye %6.1f  `r2exp' "%"
+					}
+				}
+				di in gr "{hline 53}"
+				local sssc=`VarExpSS'[`=`compte'',1]
+				local dfsc=`VarExpSS'[`=`compte'',2]
+				local ssac=`VarExpSS'[`=`compte'+1',1]
+				local dfac=`VarExpSS'[`=`compte'+1',2]
+				di _col(23) in gr "SS.res" _col(34) in gr "df"
+				di _col(1) in gr "Model without cov." _col(22) in ye %6.3f `sssc'  _col(31) in ye %5.0f `dfsc'
+				di _col(1) in gr "Full model" _col(22) in ye %6.3f `ssac'  _col(31) in ye %5.0f `dfac'
+				di in gr "{hline 53}"
+				di ""
+			}
+		}
+		else if "`difficulties'"!="."{
+			di in gr "Latent trait distribution"
+			di in gr "{hline 80}"
+			di _col(18) in gr "Coef." _col(31) in gr "S.E." _col(43) in gr "z" _col(52) in gr "P>|z|" _col(61) in gr "[`level'% Conf. Interval]"
+			di in gr "{hline 80}"
+			di _col(1) in gr "Mu" _col(15) in ye %8.5f `=`eB'[1,1]' _col(27) in ye %8.5f `=sqrt(`eV'[1,1]) ' _col(39) in ye %5.2f `=`=`eB'[1,1]'/`=sqrt(`eV'[1,1]) '' _col(51) in ye %6.3f `=2*(1-normal(abs(`=`eB'[1,1]'/`=sqrt(`eV'[1,1]) ')))'  _col(61) in ye %8.5f `=`=`eB'[1,1]'-`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1]) '' _col(73) in ye %8.5f `=`=`eB'[1,1]'+`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1]) ''
+
+			di _col(1) in gr "Sigma" _col(15) in ye %8.5f `=abs(`eB'[1,`nbc'])' _col(27) in ye %8.5f `=sqrt(`=`eV'[`nbc',`nbc']')' _col(39) in ye %5.2f `=`eB'[1,`nbc']/sqrt(`=`eV'[`nbc',`nbc']')' _col(51) in ye %6.3f `=2*(1-normal(abs(`eB'[1,`nbc']/sqrt(`=`eV'[`nbc',`nbc']'))))'  _col(61) in ye %8.5f `=`eB'[1,`nbc']-`=(1+`level'/100)/2'*sqrt(`=`eV'[`nbc',`nbc']')' _col(73) in ye %8.5f `=`eB'[1,`nbc']+`=(1+`level'/100)/2'*sqrt(`=`eV'[`nbc',`nbc']')'
+			di in gr "{hline 80}"
+			di ""
+		}
+		if "`difficulties'"=="."{
+			di in gr "Items difficulty parameters:"
+			di ""
+			di in gr "{hline 52}"
+			di _col(1) in gr "Item"  _col(21) in gr "Coef." _col(31) in gr "S.E."   _col(43) in gr "[`level'% C.I.]" _col(66) 
+			di in gr "{hline 52}"
+			local compteur=1
+			if "`rsm'"=="."{
+				forvalues i=1/`nbit'{
+		
+				tempname rep__`i'
+				qui tab ``i'', matrow(`rep__`i'')
+						local moda`i'=`=r(r)'
+					di _col(1) in gr "``i'':" 
+					forvalues g=1/`=`moda`i''-1'{
+						di _col(4) in gr "response: " in ye %-6.2g `=`rep__`i''[`=`g'+1',1]' _col(20) in ye %6.3f `=`eB'[1,`compteur']' _col(29) in ye %6.3f `=sqrt(`=`eV'[`compteur',`compteur']')'   _col(38) in ye %6.3f `=`eB'[1,`compteur']-`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' _col(47) in ye %6.3f `=`eB'[1,`compteur']+`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' 
+						local compteur=`compteur'+1
+					}
+					di in gr "{hline 52}"
+				}
+				di ""
+			}
+			else{
+			tempname tau
+			matrix `tau'=e(Tau)
+				forvalues i=1/`nbit'{
+				tempname rep__`i'
+				qui tab ``i'', matrow(`rep__`i'')
+						local moda`i'=`=r(r)'
+					di _col(1) in gr "``i'':"   _col(20) in ye %6.3f `=`eB'[1,`compteur']' _col(29) in ye %6.3f `=sqrt(`=`eV'[`compteur',`compteur']')'   _col(38) in ye %6.3f `=`eB'[1,`compteur']-`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' _col(47) in ye %6.3f `=`eB'[1,`compteur']+`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' 
+					local compteur=`compteur'+`=`moda1'-1'
+				}
+				di in gr "{hline 52}"
+				forvalues i=2/`=`moda1'-1'{
+					di _col(1) in gr "tau`=`i'-1':"  _col(20) in ye %6.3f `=`tau'[1,`i']' _col(29) in ye %6.3f `=`tau'[2,`i']'   _col(38) in ye %6.3f `=`=`tau'[1,`i']'-`=(1+`level'/100)/2'*`=`tau'[2,`i']'' _col(47) in ye %6.3f `=`=`tau'[1,`i']'+`=(1+`level'/100)/2'*`=`tau'[2,`i']'' 
+				}
+				di in gr "{hline 52}"
+			}
+		}
+		else{
+			di in gr "Items difficulty parameters: fixed for the analysis"
+		}
+	}
+	else{
+		local Cond=1
+		local varlist=e(items)
+		if "`categorical'"=="" & "`=e(categorical)'"!="."{
+			local categorical=e(categorical)
+		}
+		if "`continuous'"=="" & "`=e(continuous)'"!="."{
+			local continuous=e(continuous)
+		}
+		if "`difficulties'"=="" & "`=e(difficulties)'"!="."{
+			local difficulties=e(difficulties)
+		}
+		if "`iterate'"=="" & "`=e(iterate)'"!="."{
+			local iterate=e(iterate)
+		}
+		if "`adapt'"=="" & "`=e(adapt)'"!="."{
+			local adapt=e(adapt)
+		}
+		if "`robust'"=="" & "`=e(robust)'"!="."{
+			local robust=e(robust)
+		}
+		if "`from'"=="" & "`=e(from)'"!="."{
+			local from=e(from)
+		}
+		if "`rsm'"=="" & "`=e(rsm)'"!="."{
+			local rsm=e(rsm)
+		}
+		if "`estimateonly'"=="" & "`=e(estimateonly)'"!="."{
+			local estimateonly=e(estimateonly)
+		}
+	}
+}
+else{
+	local Cond=1
+}
+if `Cond'==1{
+	tokenize `varlist' `categorical' `continuous'
+	local nbit: word count `varlist'
+	local nbcov: word count `categorical'
+	local nbcovquant: word count `continuous'
+	local nbit2:word count `difficulties'
+	local NIP ""
+	if "`nip'"!=""{
+		local NIP "nip(`nip')"
+	}
+	tempname nom val
+	if `nbit2'==0{
+		local itest=1
+	}
+	else{
+		local itest=0
+	}
+	if "`from'"!=""{
+		local verifFrom=colsof(`from')
+	}
+	tempfile bddini bddinib
+	qui{
+		marksample touse,novarlist
+		keep if `touse'
+		local ordre=0
+		forvalues i=1/`nbit'{
+			tempname rep__`i'
+			tab ``i'', matrow(`rep__`i'')
+			local ordre=`ordre'+`=rowsof(`rep__`i'')'-1
+			forvalues j=1/`=rowsof(`rep__`i'')'{
+				replace ``i''=`j'-1 if ``i''==`rep__`i''[`j',1]
+			}
+		}
+		save `bddinib',replace
+		q memory
+	}
+	local matsizeini=r(matsize)
+	if "`rsm'"!=""{
+		local nbtotmodait=rowsof(`rep__1')
+		forvalues i=2/`nbit'{
+			if `=rowsof(`rep__`i'')'!=`nbtotmodait'{
+				noi di in red "The number of item response categories must be equal for each item when using Rating Scale models"
+				use `bddinip',replace 
+				error 100
+			}
+		}
+		if "`difficulties'"!=""{
+			noi di in red "RSM option only available for unknow difficulties"
+			use `bddinip',replace 
+			error 100
+		}
+	}
+	if "`from'"!=""{
+		if "`difficulties'"!=""{
+			noi di in red "From option only available for unknow difficulties"
+			use `bddinip',replace 
+			error 100
+		}
+		if "`rsm'"!=""{
+			noi di in red "From option only available for the Partial Credit model"
+			use `bddinip',replace 
+			error 100
+		}
+	}
+
+	  /*************************************/
+	 /*		   Verifications			  */
+	/*************************************/
+
+	if "`iterate'"==""{
+		local it=""
+	}
+	else{
+		local iterateII="it(`iterate')"
+	}
+	tempvar one id item reponse obs wt x choix it covariable covverytemp
+	qui save `bddinib', replace
+	if "`difficulties'"!=""{
+		if `nbit2'!=`nbit'{
+			noi di in red "Not the same number of difficulty vectors and of items"
+			use `bddinip',replace 
+			error 100
+		}
+		forvalues i=1/`nbit'{
+			if strpos("`varlist'",word("`difficulties'",`i'))==0{
+				noi di in red "The item difficulty vectors must have the same names than the item variables"
+				use `bddinip',replace 
+				error 100
+			}
+		}
+	}
+	  /*************************************/
+	 /*	Estimation of the parameters	  */
+	/*************************************/
+	local nbtotmodacov=0
+	if `nbcov'!=0{
+		forvalues i=1/`nbcov'{
+			qui tab ``=`nbit'+`i''', matrow(`nom') matcell(`val')
+			local nbModCov`i'=r(r)
+			forvalues k=1/`nbModCov`i''{
+				local valmod`k'cov`i'=`nom'[`k',1]
+				local nbmod`k'cov`i'=`val'[`k',1]
+			}
+			local nbtotmodacov=`nbtotmodacov'+`nbModCov`i''
+			if `nbModCov`i''>15{
+				noi di in ye "Are you sure that ``=`nbit'+`i''' is a categorical variable? (``=`nbit'+`i''' has `nbModCov`i'' categories)"
+				noi di in gr ""
+			}
+			local tot`i'=r(N)
+			forvalues k=1/`nbModCov`i''{
+				local sum=0
+				forvalues k2=1/`nbModCov`i''{
+					if `k2'!=`k'{
+						local sum=`sum'+`val'[`k2',1]
+					}
+				}
+				local a`i'_`k'=round((`sum'-`tot`i'')/`tot`i'',0.01)
+				local b`i'_`k'=round((`sum')/`tot`i'',0.01)
+			}
+		}
+	}
+	local nbparcov=`nbtotmodacov'+`nbcovquant'
+	qui{
+		keep `varlist' `categorical' `continuous'
+		local nbdifftotbis=0
+		local nbdifftot=0
+		if "`difficulties'"=="" & "`rsm'"==""{
+			forvalues i=1/`nbit'{
+				gen `reponse'`i' = ``i''
+				drop ``i''
+				tab `reponse'`i'
+				local moda`i'=`=r(r)'
+				local nbdifftot=`nbdifftot'+`moda`i''-1
+				local nbdifftotbis=`nbdifftotbis'+`moda`i''-1
+			}
+		}
+		else if "`difficulties'"=="" & "`rsm'"!=""{
+			forvalues i=1/`nbit'{
+				gen `reponse'`i' = ``i''
+				drop ``i''
+				tab `reponse'`i'
+				local moda`i'=`=r(r)'
+				local nbdifftot=`nbdifftot'+1
+				local nbdifftotbis=`nbdifftotbis'+`moda`i''-1
+			}
+			local nbdifftot=`nbdifftot'+`nbtotmodait'-2
+		}
+		else{
+			forvalues i=1/`nbit'{
+				gen `reponse'`i' = ``i''
+				drop ``i''
+				local moda`i'=colsof(``i'')+1
+			}
+		}
+		if "`from'"!=""{
+			if `nbcov'!=0{
+				if `verifFrom'!=`nbtotmodacov'-`nbcov'+1+`nbdifftot'+`nbcovquant'{
+					noi di in red "Mismatch between the number of parameters to estimate and the number of provided parameters"
+					use `bddinip',replace 
+					error 100
+				}
+			}
+			else{
+				if `verifFrom'!=1+`nbdifftot'+`nbcovquant'{
+					noi di in red "Mismatch between the number of parameters to estimate and the number of provided parameters"
+					use `bddinip',replace 
+					error 100
+				}
+			}
+		}
+		gen `one'=1
+		su `one'
+		local Nbid=r(N)
+		collapse (sum) `wt'2=`one', by(`reponse'1-`reponse'`nbit' `categorical' `continuous')
+		gen `id'=_n
+		reshape long `reponse', i(`id') j(`item')
+		drop if `reponse'==.	
+		ologit `reponse' [fweight=`wt'2]
+		local LLL00=e(ll)
+		tempname eBLLL00
+		matrix `eBLLL00'=e(b)
+		gen `obs'=_n
+		su `wt'2
+		local ddlssIII=r(sum)-1
+		forvalues i=1/`nbit'{
+			expand `moda`i'' if `item'==`i'
+		}
+		by `obs', sort: gen `x'=_n-1
+		gen `choix'=`reponse'==`x'
+		tab `item', gen(`it')
+		forvalues i=1/`nbit'{
+			forvalues g=1/`=`moda`i''-1'{
+				gen d_``i''_`g'=(-1)*`it'`i'*(`x'>=`g')
+			}
+		}
+		forvalues i=1/`nbit'{
+			forvalues g=1/`=`moda`i''-1'{
+				capture gen __dd_`g'=0
+			}
+		}
+		forvalues i=1/`nbit'{
+			forvalues g=1/`=`moda`i''-1'{
+				replace  __dd_`g'=(-1)*`it'`i'*(`x'>=`g') if ((-1)*`it'`i'*(`x'>=`g'))<__dd_`g'
+			}
+		}
+		if "`difficulties'"!=""{
+			gen difficulties=0
+			forvalues i=1/`nbit'{
+				forvalues g=1/`=`moda`i''-1'{
+					replace difficulties=difficulties+``i''[1,`g']*d_``i''_`g'
+				}
+			}
+		}
+		if `nbcov'!=0{
+			forvalues i=1/`nbcov'{
+				gen `covverytemp'=``=`nbit'+`i'''
+				drop ``=`nbit'+`i'''
+				rename `covverytemp' ``=`nbit'+`i'''
+				tab ``=`nbit'+`i''', gen(``=`nbit'+`i'''__) matrow(`nom')
+				local nbModCov`i'=r(r)
+				forvalues k=1/`nbModCov`i''{
+					gen ``=`nbit'+`i'''__`k'_old=``=`nbit'+`i'''__`k'
+					order ``=`nbit'+`i'''__`k'_old, first
+					replace ``=`nbit'+`i'''__`k'=``=`nbit'+`i'''__`k'*`x'
+					local ident`i'_`k'=`nom'[`k',1]
+					if `k'==1 & `i'==1{
+						local ident1=`ident`i'_`k''
+					}
+					rename ``=`nbit'+`i'''__`k' ``=`nbit'+`i'''_`ident`i'_`k''
+				}
+			}
+			forvalues i=1/`nbcov'{
+				drop ``=`nbit'+`i'''
+			}
+		}
+		if `nbcovquant'!=0{
+			forvalues i=1/`nbcovquant'{
+				gen `covverytemp'=``=`nbit'+`nbcov'+`i'''*`x'
+				rename ``=`nbit'+`nbcov'+`i''' ``=`nbit'+`nbcov'+`i'''_old
+				rename `covverytemp' ``=`nbit'+`nbcov'+`i'''
+			}
+		}
+		rename `id' theta
+		rename `x' estimates
+	}
+	eq slope:estimates
+	gen obs=`obs'
+	gen choix=`choix'
+	gen wt=`wt'
+	local contrainte ""
+	local contrainteit ""
+	if "`rsm'"!="" & "`difficulties'"==""{
+		forvalues i=2/`nbit'{
+			forvalues j=2/`=`nbtotmodait'-1'{
+				constraint free
+				local con=r(free)
+				local contrainteit "`contrainteit' `con'"
+				constraint `con' d_`1'_`j'-d_`1'_1=d_``i''_`j'-d_``i''_1
+			}
+		}
+	}
+	local offset "offset(difficulties)"
+	local covariablesit ""
+	if "`difficulties'"==""{
+		local covariablesit "d_`1'_1-d_``nbit''_`=`moda`nbit''-1'"
+		local offset ""
+	}
+	local nbitdiffpara=0
+	forvalues i=1/`nbit'{
+		forvalues j=1/`=`moda`nbit''-1'{
+			local nbitdiffpara=`nbitdiffpara'+1
+		}
+	}
+	local covariables ""
+	if `nbcov'!=0{
+		local covariables "`covariables' ``=`nbit'+1''_`ident1'-``=`nbit'+`nbcov'''_`ident`nbcov'_`nbModCov`nbcov'''"
+		forvalues i=1/`nbcov'{
+			constraint free
+			local con=r(free)
+			local contrainte "`contrainte' `con'"
+			constraint `con' ``=`nbit'+`i'''_`ident`i'_1'=0
+		}
+	}
+	if `nbcovquant'!=0{
+		local covariables "`covariables' ``=`nbit'+`nbcov'+1''-``=`nbit'+`nbcov'+`nbcovquant'''"
+	}
+	tempname a
+	matrix `a'=(0,0)
+	local skipcopy "skip"
+	if "`difficulties'"==""{
+		if "`from'"!=""{
+			matrix `a'=`from'
+			local skipcopy "copy"
+		}
+	}
+	gen cons=estimates
+	local varcons ""
+	if "`difficulties'"!=""{
+		local varcons "cons"
+	}
+	  /**********************/
+	 /*Estimation du modĂšle*/
+	/**********************/
+
+	unab vars : `covariables' , min(0)
+	local _c1= `: word count `vars''
+	local _c2= `: word count `contrainte''
+	gllamm estimates `varcons' `covariablesit' `covariables' , `offset' i(theta) eqs(slope) link(mlogit) expand(`obs' `choix' o) weight(`wt') `adapt' `robust' nocons `iterateII'  nodis   constraint(`contrainteit' `contrainte') from(`a') `skipcopy'  `NIP' `trace'
+	local convergeance=e(converged)
+	tempname eB eV
+	matrix `eB'=e(b)
+	local nbc=colsof(`eB')
+	matrix `eV'=e(V)
+	local nbpar=e(k)
+	local nbN=e(N)
+	local LLfull=e(ll)
+	local ccnn=e(cn)
+	local dfree_ModComp=`ddlssIII'-`=colsof(`eB')'+ wordcount("`contrainteit' `contrainte'")
+	local SS_ModComp=(`eB'[1,`=colsof(`eB')']^2)*`dfree_ModComp'
+	local dfree_ModSsCov=`dfree_ModComp'+`nbparcov'- wordcount("`contrainte'")
+	local ordre=`ordre'- wordcount("`contrainteit'")+1
+	if "`rsm'"!=""{
+		tempname tau
+		matrix `tau'=J(2,`=`moda1'-1',.)
+		forvalues i=2/`=`moda1'-1'{
+			qui lincom d_`1'_`i'-d_`1'_1
+			local tau`i'=r(estimate)
+			local setau`i'=r(se)
+			matrix `tau'[1,`i']=`tau`i''
+			matrix `tau'[2,`i']=`setau`i''
+		}
+	}
+
+	qui{
+		capture su difficulties
+		if _rc==0{
+			gen difficultiespost=difficulties
+		}
+		else{
+			gen difficultiespost=0
+			local indent=1
+			forvalues i=1/`nbit'{
+				forvalues g=1/`=`moda`i''-1'{
+					replace difficultiespost=difficultiespost+`eB'[1,`indent']*d_``i''_`g'
+					local indent=1+`indent'
+				}
+			}
+		}
+		/* Commande GLLAMM qui est responsable de génération de matrices résiduelles */
+		qui gllamm estimates cons , offset(difficultiespost) i(theta) eqs(slope) link(mlogit) expand(`obs' `choix' o) weight(`wt') `adapt' `robust' nocons from(`eB') skip  `NIP'
+		tempname eB_tot
+		matrix `eB_tot'=e(b)
+		local SS_ModSsCov=(`eB_tot'[1,`=colsof(`eB_tot')']^2)*`dfree_ModSsCov'
+	}
+	local mugauss=`eB_tot'[1,1]
+	local sdgauss=abs(`eB_tot'[1,2])
+	if "`estimateonly'"==""{
+		noi di in gr " "
+		if `nbcov'+`nbcovquant'!=0{
+			noi di "McFadden's pseudo R square and type III Sums of squares computation"
+		}
+		else{
+			noi di "McFadden's pseudo R square computation"
+		}
+
+	  /**********************************************************/
+	 /* ModÚle nul (juste intercept et effets aléatoires -> R2 */
+	/**********************************************************/
+
+		qui gllamm estimates __dd_*  , i(theta) eqs(slope) link(mlogit) expand(`obs' `choix' o) weight(`wt') `adapt' `robust' nocons `iterateII' from(`a') skip  `NIP'
+		local LLinterSS=e(ll)
+		tempname eB4
+		matrix `eB4'=e(b)
+		local R2Nag=1-(`LLfull'/`LLinterSS')
+
+	  /*****************/
+	 /* Calcul des SS */
+	/*****************/
+		qui{
+			local covariables2 ""
+			forvalues covs=`=`nbit'+1'/`=`nbit'+`nbcov''{
+				local covariables2 "`covariables2' ``covs''_`ident`=`covs'-`nbit''_1'-``covs''_`ident`=`covs'-`nbit''_`nbModCov`=`covs'-`nbit''''"
+			}
+			forvalues covs=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+				local covariables2 "`covariables2' ``covs''"
+			}
+			if `nbcov'+`nbcovquant'!=0{
+				forvalues covs=`=`nbit'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+					noi di "                for " in ye "``covs''" in gr " covariate"
+					if strpos("`categorical'","``covs''")!=0 & "``covs''"!=""{
+						local covsans= subinword("`covariables2'","``covs''_`ident`=`covs'-`nbit''_1'-``covs''_`ident`=`covs'-`nbit''_`nbModCov`=`covs'-`nbit''''","",.)
+						local dfree_Mss``covs''=`dfree_ModComp'+ `nbModCov`=`covs'-`nbit'''-1
+					}
+					else{
+						local covsans= subinword("`covariables2'","``covs''","",.)
+						local dfree_Mss``covs''=`dfree_ModComp'+1
+					}
+					capture constraint drop `contrainterep' 
+					local contrainterep ""
+					if `nbcov'!=0{
+						forvalues i=1/`nbcov'{
+							if `=`nbit'+`i''!=`covs'{
+								constraint free
+								local con=r(free)
+								local contrainterep "`contrainterep' `con'"
+								constraint `con' ``=`nbit'+`i'''_`ident`i'_1'=0
+							}
+						}
+					}
+					gllamm estimates cons `covsans' , offset(difficultiespost) i(theta) eqs(slope) link(mlogit) expand(`obs' `choix' o) weight(`wt') `adapt' `robust' nocons `iterateII'   constraint(`contrainterep') from(`eB') skip  `NIP'
+					tempname eB``covs''
+					matrix `eB``covs'''=e(b)
+					local SS_Mss``covs''=(`eB``covs'''[1,`=colsof(`eB``covs''')']^2)*`dfree_Mss``covs'''
+					local LLfullmoin=e(ll)
+					tempname eB4
+					matrix `eB4'=e(b)
+					local R2N_``covs''=1-(`LLfullmoin'/`LLinterSS')
+					tempname eB2
+					matrix `eB2'=e(b)
+					local nbpar2=e(k)				
+				}
+			}
+		}
+		noi di in gr " "
+	}
+	di in gr ""
+	if "`rsm'"!=""{
+		di in gr "Model : " in ye "Rating Scale Model"
+	}
+	else{
+		di in gr "Model : " in ye "Partial Credit Model"
+	}
+	di in gr ""
+	di in gr "                log likelihood: " in ye %-18.3f `LLfull'
+	local lll=e(ll)
+	if "`estimateonly'"==""{
+		di in gr "                Marginal McFadden's pseudo R2: " in ye %-4.1f `=`R2Nag'*100' "%"
+	}
+	di in gr "                Number of individuals: "in ye "`Nbid'"
+	di in gr "                Number of items: "in ye "`nbit'"
+	if `=`nbcov'+`nbcovquant''!=0{
+		di in gr "                Number of covariates: "in ye "`=`nbcov'+`nbcovquant''"
+	}
+	di in gr ""
+	di ""
+	di in gr "Parameters of the Latent trait distribution:"
+	di ""
+	local contrR ""
+	if "`difficulties'"==""{
+		if `=`nbcov'+`nbcovquant''!=0{
+			local subgroup0 ""
+			if `nbcov'!=0{
+				forvalues i=1/`nbcov'{
+					local subgroup0 "`subgroup0'``=`nbit'+`i''' = `ident`i'_1', "
+				}	
+			}
+			if `nbcovquant'!=0{
+				forvalues i=1/`nbcovquant'{
+					local subgroup0 "`subgroup0'``=`nbit'+`nbcov'+`i''' = 0, "
+				}
+			}
+			local subgroup0b "`=reverse(subinstr(reverse("`subgroup0'"), ",", ":", 1))'"
+			local contrR "latent trait for `subgroup0b'"
+		}
+		else{
+		
+			local contrR "overall latent trait mean "
+		}
+		di in gr "                Identifiability constraint: `contrR'set to 0"
+	}
+	di in gr "		  Variance of the Latent trait: SigmaÂČ=" in ye %-8.3f (`=`=`eB'[1,`nbc']'')^2 in gr " (SE:"in ye %-8.3f `= sqrt((2*`=`eB'[1,`nbc']')^2 *`=`eV'[`nbc',`nbc']'	)' in gr ")"
+	local varTheta=(`=`=`eB'[1,`nbc']'')^2
+	local Varvartheta=(2*`=`eB'[1,`nbc']')^2 *`=`eV'[`nbc',`nbc']'
+	di ""
+	if `nbcov'+`nbcovquant'!=0{
+		if "`estimateonly'"=="" & `=`nbcov'+`nbcovquant''>0 {
+			tempname VarExpSS
+			matrix `VarExpSS'=J(`=`nbcov'+`nbcovquant'+2',4,.)
+			local compte=1
+			if `nbcov'!=0{
+				forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+					matrix `VarExpSS'[`compte',1]=`SS_Mss``i'''-`SS_ModComp'
+					matrix `VarExpSS'[`compte',2]=`dfree_Mss``i'''-`dfree_ModComp'
+					matrix `VarExpSS'[`compte',3]=(`SS_Mss``i'''-`SS_ModComp')/`SS_Mss``i'''*100
+					matrix `VarExpSS'[`compte',4]=(`R2Nag'-`R2N_``i''')/`R2Nag'*100
+					local compte=`compte'+1
+				}
+			}
+			if `nbcovquant'!=0{
+				forvalues i=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+					matrix `VarExpSS'[`compte',1]=`SS_Mss``i'''-`SS_ModComp'
+					matrix `VarExpSS'[`compte',2]=`dfree_Mss``i'''-`dfree_ModComp'
+					matrix `VarExpSS'[`compte',3]=(`SS_Mss``i'''-`SS_ModComp')/`SS_Mss``i'''*100
+					matrix `VarExpSS'[`compte',4]=(`R2Nag'-`R2N_``i''')/`R2Nag'*100
+					local compte=`compte'+1
+				}
+			}
+			matrix `VarExpSS'[`=`compte'',1]=`SS_ModSsCov'
+			matrix `VarExpSS'[`=`compte'',2]=`dfree_ModSsCov'
+			matrix `VarExpSS'[`=`compte'+1',1]=`SS_ModComp'
+			matrix `VarExpSS'[`=`compte'+1',2]=`dfree_ModComp'
+		}
+		if c(linesize)>=101{
+			di in gr "Latent trait group effect:"
+			di ""
+			di in gr "{hline 101}"
+			di _col(20) in gr "Coef." _col(30) in gr "S.E." _col(41) in gr "z" _col(45) in gr "P>|z|" _col(57) in gr "[`level'% C.I.]" _col(73) in gr "SS.III" _col(81) in gr "df" _col(85) in gr "V.exp." _col(95) in gr "R2.exp."
+			di in gr "{hline 101}"
+			local compteur=1
+			if "`difficulties'"==""{
+				local compteur=`nbdifftotbis'
+			}
+			if `nbcov'!=0{
+				forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+					local ss3=.
+					local df=.
+					local vexp=.
+					local r2exp=.
+					if "`estimateonly'"==""{
+						local ss3=`SS_Mss``i'''-`SS_ModComp'
+						local df=`dfree_Mss``i'''-`dfree_ModComp'
+						local vexp=(`SS_Mss``i'''-`SS_ModComp')/`SS_Mss``i'''*100
+						local r2exp=(`R2Nag'-`R2N_``i''')/`R2Nag'*100
+					}
+					local compteur=`compteur'+1
+					noi{
+						di _col(1) in gr "``i'':"  _col(72) in ye %6.3f `ss3'	 _col(81) in ye %2.0f  `df'  _col(84) in ye %6.1f `vexp' "%"    _col(94) in ye %6.1f  `r2exp' "%"
+						di _col(4) in gr "`=abbrev("``i''",10)':" in ye " `ident`=`i'-`nbit''_1'" _col(24) in ye  "0" _col(33) in ye "." _col(41) in ye "." _col(49) in ye "." _col(57) in ye "." _col(66) in ye "."  
+					}
+					forvalues k=2/`nbModCov`=`i'-`nbit'''{
+						local compteur=`compteur'+1
+						local estimate_e=`eB'[1,`compteur']
+						local se_e=sqrt(`=`eV'[`compteur',`compteur']')
+						noi{
+							di _col(4) in gr "`=abbrev("``i''",10)':" in ye " `ident`=`i'-`nbit''_`k''" _col(19) in ye %6.3f `estimate_e' _col(28) in ye %6.3f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %6.3f `=`estimate_e'-`=(1+`level'/100)/2'*`se_e'' _col(61) in ye %6.3f `=`estimate_e'+`=(1+`level'/100)/2'*`se_e''	
+						}
+					}
+					di in gr "{hline 101}"
+				}
+			}	
+			if `nbcovquant'!=0{
+				forvalues i=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+					local ss3=.
+					local df=.
+					local vexp=.
+					local r2exp=.
+					if "`estimateonly'"==""{
+						local ss3=`SS_Mss``i'''-`SS_ModComp'
+						local df=`dfree_Mss``i'''-`dfree_ModComp'
+						local vexp=(`SS_Mss``i'''-`SS_ModComp')/`SS_Mss``i'''*100
+						local r2exp=(`R2Nag'-`R2N_``i''')/`R2Nag'*100
+					}
+					local compteur=`compteur'+1
+						local estimate_e=`eB'[1,`compteur']
+						local se_e=sqrt(`=`eV'[`compteur',`compteur']')
+					noi{		
+						di _col(1) in gr "``i'':" _col(19) in ye %6.3f `estimate_e' _col(28) in ye %6.3f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %6.3f `=`estimate_e'-`=(1+`level'/100)/2'*`se_e'' _col(61) in ye %6.3f `=`estimate_e'+`=(1+`level'/100)/2'*`se_e''   _col(72) in ye %6.3f `ss3'	 _col(81) in ye %2.0f  `df'  _col(84) in ye %6.1f `vexp' "%"    _col(94) in ye %6.1f  `r2exp' "%"
+					}
+					di in gr "{hline 101}"
+				}
+			}	
+			if "`difficulties'"!=""{
+				di _col(1) in gr "_Cons" _col(19) in ye %6.3f `=`eB'[1,1]' _col(28) in ye %6.3f `=sqrt(`eV'[1,1])' _col(37) in ye %5.2f `=`=`eB'[1,1]'/`=sqrt(`eV'[1,1])'' _col(44) in ye %6.3f `=2*(1-normal(abs(`=`eB'[1,1]'/`=sqrt(`eV'[1,1])')))'  _col(52) in ye %6.3f `=`=`eB'[1,1]'-`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1])'' _col(61) in ye %6.3f `=`=`eB'[1,1]'+`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1])''
+				di in gr "{hline 101}"
+			}
+			local sssc=.
+			local dfsc=.
+			local ssac=.
+			local dfac=.
+			if "`estimateonly'"==""{
+				local sssc=`SS_ModSsCov'
+				local dfsc=`dfree_ModSsCov'
+				local ssac=`SS_ModComp'
+				local dfac=`dfree_ModComp'
+			}
+			di _col(73) in gr "SS.res" _col(84) in gr "df"
+			di _col(45) in gr "Model without covariates" _col(72) in ye %6.3f `sssc'  _col(81) in ye %5.0f `dfsc'
+			di _col(59) in gr "Full model" _col(72) in ye %6.3f `ssac'  _col(81) in ye %5.0f `dfac'
+			di in gr "{hline 101}"
+			di ""
+		}
+		else{
+			di in gr "Latent trait group effect:"
+			di ""
+			di in gr "{hline 66}"
+			di _col(20) in gr "Coef." _col(30) in gr "S.E." _col(41) in gr "z" _col(45) in gr "P>|z|" _col(57) in gr "[`level'% C.I.]"
+			di in gr "{hline 66}"
+			local compteur=1
+			if "`difficulties'"==""{
+				local compteur=`nbdifftotbis'
+			}
+			if `nbcov'!=0{
+				forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+					local compteur=`compteur'+1
+					noi{
+						di _col(1) in gr "``i'':" 
+						di _col(4) in gr "`=abbrev("``i''",10)':" in ye " `ident`=`i'-`nbit''_1'" _col(24) in ye  "0" _col(33) in ye "." _col(41) in ye "." _col(49) in ye "." _col(57) in ye "." _col(66) in ye "."	
+					}
+					forvalues k=2/`nbModCov`=`i'-`nbit'''{
+						local compteur=`compteur'+1
+						local estimate_e=`eB'[1,`compteur']
+						local se_e=sqrt(`=`eV'[`compteur',`compteur']')
+						noi{
+							di _col(4) in gr "`=abbrev("``i''",10)':" in ye " `ident`=`i'-`nbit''_`k''" _col(19) in ye %6.3f `estimate_e' _col(28) in ye %6.3f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %6.3f `=`estimate_e'-`=(1+`level'/100)/2'*`se_e'' _col(61) in ye %6.3f `=`estimate_e'+`=(1+`level'/100)/2'*`se_e''	
+						}
+					}
+					di in gr "{hline 66}"
+				}
+			}	
+			if `nbcovquant'!=0{
+				forvalues i=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+					local compteur=`compteur'+1
+						local estimate_e=`eB'[1,`compteur']
+						local se_e=sqrt(`=`eV'[`compteur',`compteur']')
+					noi{		
+						di _col(1) in gr "``i'':" _col(19) in ye %6.3f `estimate_e' _col(28) in ye %6.3f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %6.3f `=`estimate_e'-`=(1+`level'/100)/2'*`se_e'' _col(61) in ye %6.3f `=`estimate_e'+`=(1+`level'/100)/2'*`se_e'' 
+					}
+					di in gr "{hline 66}"
+				}
+			}	
+			if "`difficulties'"!=""{
+				di _col(1) in gr "_Cons" _col(19) in ye %6.3f `=`eB'[1,1]' _col(28) in ye %6.3f `=sqrt(`eV'[1,1])' _col(37) in ye %5.2f `=`=`eB'[1,1]'/`=sqrt(`eV'[1,1])'' _col(44) in ye %6.3f `=2*(1-normal(abs(`=`eB'[1,1]'/`=sqrt(`eV'[1,1])')))'  _col(52) in ye %6.3f `=`=`eB'[1,1]'-`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1])'' _col(61) in ye %6.3f `=`=`eB'[1,1]'+`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1])''
+				di in gr "{hline 66}"
+			}
+			if "`estimateonly'"==""{
+				di ""
+				di "Proportion of latent trait variance explained by covariates"
+				di ""
+				di in gr "{hline 53}"
+				di _col(23) in gr "SS.III" _col(34) in gr "df" _col(38) in gr "V.exp." _col(47) in gr "R2.exp."
+				di in gr "{hline 53}"
+				local compteur=1
+				if "`difficulties'"==""{
+					local compteur=`nbdifftotbis'
+				}
+				if `nbcov'!=0{
+					forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+						local ss3=`SS_Mss``i'''-`SS_ModComp'
+						local df=`dfree_Mss``i'''-`dfree_ModComp'
+						local vexp=(`SS_Mss``i'''-`SS_ModComp')/`SS_Mss``i'''*100
+						local r2exp=(`R2Nag'-`R2N_``i''')/`R2Nag'*100
+						local compteur=`compteur'+1
+						noi di _col(1) in gr "``i'':"  _col(22) in ye %6.3f `ss3'	 _col(34) in ye %2.0f  `df'  _col(37) in ye %6.1f `vexp' "%"    _col(46) in ye %6.1f  `r2exp' "%"
+					}
+				}
+				if `nbcovquant'!=0{
+					forvalues i=`=`nbit'+`nbcov'+1'/`=`nbit'+`nbcov'+`nbcovquant''{
+						local ss3=`SS_Mss``i'''-`SS_ModComp'
+						local df=`dfree_Mss``i'''-`dfree_ModComp'
+						local vexp=(`SS_Mss``i'''-`SS_ModComp')/`SS_Mss``i'''*100
+						local r2exp=(`R2Nag'-`R2N_``i''')/`R2Nag'*100
+						local compteur=`compteur'+1
+						noi di _col(1) in gr "``i'':" _col(22) in ye %6.3f `ss3'	 _col(34) in ye %2.0f  `df'  _col(37) in ye %6.1f `vexp' "%"    _col(46) in ye %6.1f  `r2exp' "%"
+					}
+				}
+				di in gr "{hline 53}"
+				local sssc=`SS_ModSsCov'
+				local dfsc=`dfree_ModSsCov'
+				local ssac=`SS_ModComp'
+				local dfac=`dfree_ModComp'
+				di _col(23) in gr "SS.res" _col(34) in gr "df"
+				di _col(1) in gr "Model without cov." _col(22) in ye %6.3f `sssc'  _col(31) in ye %5.0f `dfsc'
+				di _col(1) in gr "Full model" _col(22) in ye %6.3f `ssac'  _col(31) in ye %5.0f `dfac'
+				di in gr "{hline 53}"
+				di ""
+			}
+		}
+	}
+	else if "`difficulties'"!=""{
+		di in gr "Latent trait distribution"
+		di in gr "{hline 80}"
+		di _col(18) in gr "Coef." _col(31) in gr "S.E." _col(43) in gr "z" _col(52) in gr "P>|z|" _col(61) in gr "[`level'% Conf. Interval]"
+		di in gr "{hline 80}"
+		di _col(1) in gr "Mu" _col(15) in ye %8.5f `=`eB'[1,1]' _col(27) in ye %8.5f `=sqrt(`eV'[1,1]) ' _col(39) in ye %5.2f `=`=`eB'[1,1]'/`=sqrt(`eV'[1,1]) '' _col(51) in ye %6.3f `=2*(1-normal(abs(`=`eB'[1,1]'/`=sqrt(`eV'[1,1]) ')))'  _col(61) in ye %8.5f `=`=`eB'[1,1]'-`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1]) '' _col(73) in ye %8.5f `=`=`eB'[1,1]'+`=(1+`level'/100)/2'*`=sqrt(`eV'[1,1]) ''
+	
+		di _col(1) in gr "Sigma" _col(15) in ye %8.5f `=abs(`eB'[1,`nbc'])' _col(27) in ye %8.5f `=sqrt(`=`eV'[`nbc',`nbc']')' _col(39) in ye %5.2f `=`eB'[1,`nbc']/sqrt(`=`eV'[`nbc',`nbc']')' _col(51) in ye %6.3f `=2*(1-normal(abs(`eB'[1,`nbc']/sqrt(`=`eV'[`nbc',`nbc']'))))'  _col(61) in ye %8.5f `=`eB'[1,`nbc']-`=(1+`level'/100)/2'*sqrt(`=`eV'[`nbc',`nbc']')' _col(73) in ye %8.5f `=`eB'[1,`nbc']+`=(1+`level'/100)/2'*sqrt(`=`eV'[`nbc',`nbc']')'
+		di in gr "{hline 80}"
+		di ""
+	}	
+	if "`difficulties'"==""{
+		di in gr "Items difficulty parameters:"
+		di ""
+		di in gr "{hline 52}"
+		di _col(1) in gr "Item"  _col(21) in gr "Coef." _col(31) in gr "S.E."   _col(43) in gr "[`level'% C.I.]" _col(66) 
+		di in gr "{hline 52}"
+		local compteur=1
+		if "`rsm'"==""{
+			forvalues i=1/`nbit'{
+				di _col(1) in gr "``i'':" 
+				forvalues g=1/`=`moda`i''-1'{
+					di _col(4) in gr "response: " in ye %-6.2g `=`rep__`i''[`=`g'+1',1]' _col(20) in ye %6.3f `=`eB'[1,`compteur']' _col(29) in ye %6.3f `=sqrt(`=`eV'[`compteur',`compteur']')'   _col(38) in ye %6.3f `=`eB'[1,`compteur']-`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' _col(47) in ye %6.3f `=`eB'[1,`compteur']+`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' 
+					local compteur=`compteur'+1
+				}
+				di in gr "{hline 52}"
+			}
+			di ""
+		}
+		else{
+			forvalues i=1/`nbit'{
+				di _col(1) in gr "``i'':"   _col(20) in ye %6.3f `=`eB'[1,`compteur']' _col(29) in ye %6.3f `=sqrt(`=`eV'[`compteur',`compteur']')'   _col(38) in ye %6.3f `=`eB'[1,`compteur']-`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' _col(47) in ye %6.3f `=`eB'[1,`compteur']+`=(1+`level'/100)/2'*sqrt(`=`eV'[`compteur',`compteur']')' 
+				local compteur=`compteur'+`=`moda1'-1'
+			}
+			di in gr "{hline 52}"
+			forvalues i=2/`=`moda1'-1'{
+				di _col(1) in gr "tau`=`i'-1':"  _col(20) in ye %6.3f `tau`i'' _col(29) in ye %6.3f `setau`i''   _col(38) in ye %6.3f `=`tau`i''-`=(1+`level'/100)/2'*`setau`i''' _col(47) in ye %6.3f `=`tau`i''+`=(1+`level'/100)/2'*`setau`i''' 
+			}
+			di in gr "{hline 52}"
+		}
+	}
+	else{
+		di in gr "Items difficulty parameters: fixed for the analysis"
+	}
+
+	  /*************************************/
+	 /*	             ereturn              */
+	/*************************************/
+
+	qui{
+		if "`difficulties'"==""{
+	tempname Varbeta Vardelta beta delta Vartheta theta
+			matrix `Varbeta'=`eV'
+			local Varsigma=`Varbeta'[`=colsof(`Varbeta')',`=colsof(`Varbeta')']
+			matrix `Vardelta'=`Varbeta'[1..`nbdifftotbis',1..`nbdifftotbis']
+			matrix `beta'=`eB'
+			local sigma=abs(`beta'[1,`=colsof(`beta')'])
+			matrix `delta'=`beta'[1,1..`nbdifftotbis']
+			if `=`nbcov'+`nbcovquant''!=0{
+				matrix `Vartheta'=`Varbeta'[`=`nbdifftotbis'+1'..`=colsof(`Varbeta')-1',`=`nbdifftotbis'+1'..`=colsof(`Varbeta')-1']
+				matrix `theta'=`beta'[1,`=`nbdifftotbis'+1'..`=colsof(`beta')-1']
+			}
+			else{
+				local thetas=0
+				local Varthetas=0
+			}
+		}
+		else{
+			if `=`nbcov'+`nbcovquant''!=0{
+				tempname Vartheta theta
+				matrix `Vartheta'=`eV'
+				local Varsigma=`Vartheta'[`=colsof(`Vartheta')',`=colsof(`Vartheta')']
+				matrix `Vartheta'=`Vartheta'[1..`=colsof(`Vartheta')-1',1..`=colsof(`Vartheta')-1']
+				matrix `theta'=`eB'
+				local sigma=abs(`theta'[1,`=colsof(`theta')'])
+				matrix `theta'=`theta'[1,1..`=colsof(`theta')-1']
+			}
+			else{
+				tempname theta Vtheta
+				matrix `theta'=`eB'
+				local sigma=abs(`theta'[1,`=colsof(`theta')'])
+				matrix `Vtheta'=`eV'
+				local Varsigma=`Vtheta'[`=colsof(`Vtheta')',`=colsof(`Vtheta')']
+				local thetas=`theta'[1,1]
+				local varthetas=`Vtheta'[1,1]
+			}
+		}
+		ereturn clear
+		if `=`nbcov'+`nbcovquant''!=0{
+			matrix b=`eB'
+			matrix V=`eV'
+			ereturn post b V, depname(theta)
+			ereturn matrix theta=`theta'
+			ereturn matrix Vartheta=`Vartheta'
+		}
+		else{
+			if "`difficulties'"==""{
+				matrix V=`eV'
+				tempname thetatemp Varthetatemp
+				matrix `thetatemp'=(0)
+				matrix `Varthetatemp'=(0)
+				matrix coleq `Varthetatemp'=estimates
+				matrix coln `Varthetatemp'=mu
+				matrix roweq `Varthetatemp'=estimates
+				matrix rown `Varthetatemp'=mu
+				matrix b=`eB'
+				matrix coleq `thetatemp'=estimates
+				matrix coln `thetatemp'=mu
+				matrix rown `thetatemp'=y1
+				ereturn post b V, depname(theta)
+				ereturn matrix theta=`thetatemp'
+				ereturn matrix Vartheta=`Varthetatemp'
+			}
+			else{
+				tempname thetatemp Varthetatemp
+				matrix `Varthetatemp'=(`varthetas')
+				matrix coleq `Varthetatemp'=estimates
+				matrix coln `Varthetatemp'=mu
+				matrix roweq `Varthetatemp'=estimates
+				matrix rown `Varthetatemp'=mu
+				matrix `thetatemp'=(`thetas')
+				matrix coleq `thetatemp'=estimates
+				matrix coln `thetatemp'=mu
+				matrix rown `thetatemp'=y1
+				matrix V=`eV'
+				matrix b=`eB'
+				ereturn post b V, depname(theta)
+				tempname vvvt vvvVt
+				matrix `vvvt'=(`thetas')
+				matrix `vvvVt'=(`varthetas')
+				ereturn matrix theta=`vvvt'
+				ereturn matrix Vartheta=`vvvVt'
+			}
+		}
+		ereturn scalar ll=`LLfull'
+		ereturn scalar cn=`ccnn'
+		ereturn scalar r2=`R2Nag'
+		ereturn scalar N=`Nbid'
+		ereturn scalar Nit=`nbit'
+		ereturn scalar converged=`convergeance'
+		ereturn scalar ndtb=`nbdifftotbis'
+		ereturn scalar mugauss=`mugauss'
+		ereturn scalar sdgauss=`sdgauss'
+		if "`nip'"!=""{
+		ereturn scalar nip=`nip'
+		}
+		ereturn local items `varlist'
+		ereturn local categorical `categorical'
+		ereturn local continuous `continuous'
+		ereturn local estimateonly `estimateonly'
+		ereturn local constr `contrR'
+		ereturn local difficulties `difficulties'
+		if `nbcov'!=0{
+			forvalues i=`=`nbit'+1'/`=`nbit'+`nbcov''{
+				local ``i''_m ""
+				forvalues k=1/`nbModCov`=`i'-`nbit'''{
+					local ``i''_m "```i''_m' `ident`=`i'-`nbit''_`k''"
+					ereturn local ``i'' ```i''_m'
+				}
+			}
+		}
+		ereturn local rsm `rsm'
+		ereturn local from `from'
+		ereturn local robust `robust'
+		ereturn local adapt `adapt'
+		ereturn local iterate `iterate'
+		ereturn local itest `itest'
+		ereturn local datatest `bddinib' 
+		ereturn local if `if'
+		ereturn local in `in'
+		ereturn local cmd "pcmodel"
+		ereturn scalar order=`ordre'
+		if `=`nbcov'+`nbcovquant''!=0{
+			ereturn scalar Ncat=`nbcov'
+			ereturn scalar Ncont=`nbcovquant'
+		}
+		if "`difficulties'"==""{
+			ereturn matrix Vardelta=`Vardelta'
+			ereturn matrix delta=`delta'
+			ereturn scalar sigma=`sigma'
+			ereturn scalar Varsigma=`Varsigma'
+			if "`rsm'"!=""{
+				ereturn matrix Tau=`tau'
+			}
+		}
+		else{ 
+			if `=`nbcov'+`nbcovquant''!=0{
+				ereturn scalar sigma=`sigma'
+				ereturn scalar Varsigma=`Varsigma'
+			}
+			else{
+				ereturn scalar sigma=`sigma'
+				ereturn scalar Varsigma=`Varvartheta'
+			}
+		}
+		if "`estimateonly'"=="" & `=`nbcov'+`nbcovquant''>0 {
+			ereturn matrix VarExpSS `VarExpSS'
+		}
+	}
+use `bddinip', replace
+}
+restore
+end
diff --git a/Modules/ado/personal/p/pcmodelplus.ado b/Modules/ado/personal/p/pcmodelplus.ado
new file mode 100644
index 0000000..0abfbb2
--- /dev/null
+++ b/Modules/ado/personal/p/pcmodelplus.ado
@@ -0,0 +1,1196 @@
+program define pcmodelplus, eclass 
+syntax varlist [, COVariates(string) DIFficulties(string) ITerate(string) Group(string) adapt robust nodis]
+/* syntaxe : liste des variables correspondant aux items, cov(liste des covariables de groupe, qualitatives codĂ©es numĂ©riquement), dif(liste de vecteurs lignes ayant le mĂȘme nom que les variables d'items, correspondant aux difficultĂ©s des modalitĂ©s d'items) it(nombre d'itĂ©rations maximum pour la procĂ©dure d'estimation par convergeance) adapt : utilisation de quadratures "adaptative" robust : utilisation de l'estimateur de Huber/White/sandwich pour la matrice de covariance */
+preserve
+tokenize `varlist' `covariates'
+local nbit: word count `varlist'
+local nbcov: word count `covariates'
+local nbit2:word count `difficulties'
+tempfile bddini
+qui q memory
+local matsizeini=r(matsize)
+
+  /*************************************/
+ /*           Verifications           */
+/*************************************/
+
+if "`iterate'"==""{
+    local it=""
+}
+else{
+    local iterateII="it(`iterate')"
+}
+tempvar one id item reponse obs wt x choix it covariable covverytemp
+qui save `bddini', replace
+if "`difficulties'"!=""{
+    if `nbit2'!=`nbit'{
+        noi di in red "Not the same number of difficuly vectors and of items, Grrr!"
+        use `bddini',replace 
+        error 100
+    }
+    forvalues i=1/`nbit'{
+        if strpos("`varlist'",word("`difficulties'",`i'))==0{
+            noi di in red "The item difficulty vectors must have the same names than the item variables, Grrr! be carefull please!!!"
+            use `bddini',replace 
+            error 100
+        }
+    }
+}
+
+
+
+
+  /*************************************/
+ /*    Estimation of the parameters   */
+/*************************************/
+
+
+if `nbcov'!=0{
+    local nbtotmodacov=0
+    forvalues i=1/`nbcov'{
+        qui tab ``=`nbit'+`i''', matrow(nom) matcell(val)
+        local nbModCov`i'=r(r)
+        forvalues k=1/`nbModCov`i''{
+            local valmod`k'cov`i'=nom[`k',1]
+            local nbmod`k'cov`i'=val[`k',1]
+        }
+        local nbtotmodacov=`nbtotmodacov'+`nbModCov`i''
+        if `nbModCov`i''>10{
+            noi di in red "``=`nbit'+`i''' has too much modalities (>10). Hey, why not a continuous variable, while you are at it?"
+            use `bddini',replace 
+            error 100
+        }
+        local tot`i'=r(N)
+        forvalues k=1/`nbModCov`i''{
+            local sum=0
+            forvalues k2=1/`nbModCov`i''{
+                if `k2'!=`k'{
+                    local sum=`sum'+val[`k2',1]
+                }
+            }
+            local a`i'_`k'=round((`sum'-`tot`i'')/`tot`i'',0.01)
+            local b`i'_`k'=round((`sum')/`tot`i'',0.01)
+        }
+    }
+}
+qui{
+    keep `varlist' `covariates'
+    local nbdifftot=0
+    if "`difficulties'"==""{
+        forvalues i=1/`nbit'{
+            gen `reponse'`i' = ``i''
+            drop ``i''
+            su `reponse'`i'
+            local moda`i'=`=r(max)+1'
+            local nbdifftot=`nbdifftot'+`moda`i''-1
+        }
+    }
+    else{
+        forvalues i=1/`nbit'{
+            gen `reponse'`i' = ``i''
+            drop ``i''
+            local moda`i'=colsof(``i'')+1
+        }
+    }
+    gen `one'=1
+    su `one'
+    local Nbid=r(N)
+    collapse (sum) `wt'2=`one', by(`reponse'1-`reponse'`nbit' `covariates')
+    gen `id'=_n
+    reshape long `reponse', i(`id') j(`item')
+    drop if `reponse'==.
+    gen `obs'=_n
+    local ddlssIII=_N-1
+    forvalues i=1/`nbit'{
+        expand `moda`i'' if `item'==`i'
+    }
+    by `obs', sort: gen `x'=_n-1
+    gen `choix'=`reponse'==`x'
+    tab `item', gen(`it')
+    forvalues i=1/`nbit'{
+        forvalues g=1/`=`moda`i''-1'{
+            gen d_``i''_`g'=(-1)*`it'`i'*(`x'>=`g')
+        }
+    }
+    if "`difficulties'"!=""{
+        gen difficulties=0
+        forvalues i=1/`nbit'{
+            forvalues g=1/`=`moda`i''-1'{
+                replace difficulties=difficulties+``i''[1,`g']*d_``i''_`g'
+            }
+        }
+    }
+    if `nbcov'!=0{
+        forvalues i=1/`nbcov'{
+            gen `covverytemp'=``=`nbit'+`i'''
+            drop ``=`nbit'+`i'''
+            rename `covverytemp' ``=`nbit'+`i'''
+            tab ``=`nbit'+`i''', gen(``=`nbit'+`i'''__) matrow(nom)
+            local nbModCov`i'=r(r)
+            forvalues k=1/`nbModCov`i''{
+                replace ``=`nbit'+`i'''__`k'=``=`nbit'+`i'''__`k'*`x'
+                local ident`i'_`k'=nom[`k',1]
+                if `k'==1 & `i'==1{
+                    local ident1=`ident`i'_`k''
+                }
+                rename ``=`nbit'+`i'''__`k' ``=`nbit'+`i'''_`ident`i'_`k''
+            }
+        }
+        forvalues i=1/`nbcov'{
+            drop ``=`nbit'+`i'''
+        }
+    }
+    rename `id' theta
+    rename `x' estimates
+}
+eq slope:estimates
+gen obs=`obs'
+gen choix=`choix'
+gen wt=`wt'
+if `nbcov'!=0{
+    if "`difficulties'"==""{
+/* Recherche de valeurs initiales */
+        matrix a0=J(1,`=`nbdifftot'+`nbtotmodacov'-`nbcov'',0)
+        
+        qui{
+            tempfile bddencours
+            save `bddencours', replace 
+            use `bddini', replace
+            local countdif=1
+            forvalues i=1/`nbit'{
+                ologit ``i''
+                matrix ttt=e(b) 
+                matrix a0[1,`countdif']=ttt/2
+                local countdif=`countdif'+e(k)
+            }
+        use `bddencours', replace 
+        }
+        
+        local colnom ""
+        forvalues i=1/`nbit'{
+            forvalues j=1/`=`moda`i''-1'{
+                local colnom "`colnom' d_``i''_`j'"
+            }
+        }
+    }
+    constraint drop _all
+    local contrainte ""
+    local subgroup0 "``=`nbit'+1'':`ident1_1'"
+    forvalues i=1/`nbcov'{
+        local contrainte "`contrainte' `i'"
+
+        constraint `i' ``=`nbit'+`i'''_`ident`i'_1'=0
+        if "`difficulties'"==""{
+            forvalues j=2/`nbModCov`i''{
+                local colnom "`colnom' ``=`nbit'+`i'''_`ident`i'_`j''"
+            }
+        }
+    }
+    if `nbcov'>1{
+        forvalues i=2/`nbcov'{
+            local subgroup0 "`subgroup0', ``=`nbit'+`i''':`ident`i'_1'"
+        }
+    }
+    if "`difficulties'"==""{
+        if wordcount("`colnom'")!=`=`nbdifftot'+`nbtotmodacov'-`nbcov''{
+            di in red "ERRUER MAJEUR!!! (trop de covariables, d'items, longueur de nom des variables d'items ou de covariable trop longs... bref, réduire le nombre de caractÚres)"
+            use `bddini',replace 
+            error 100
+        }
+        matrix coln a0=`colnom'
+        matrix coleq a0=estimates
+        matrix a1=J(1,1,0)
+        matrix coln a1=estimates
+        matrix coleq a1=theta1_1
+        matrix a=a0,a1
+    }
+    if "`difficulties'"!=""{
+        gen cons=estimates
+    }
+    ereturn clear
+    if "`difficulties'"==""{
+        gllamm estimates     d_`1'_1-d_``nbit''_`=`moda`nbit''-1'     ``=`nbit'+1''_`ident1'-``=`nbit'+`nbcov'''_`ident`nbcov'_`nbModCov`nbcov''', i(theta) eqs(slope) link(mlogit) expand(`obs' `choix' o) weight(`wt') `adapt' `robust' nocons `iterateII' nodis from(a) constraint(`contrainte') copy
+        matrix estimations = e(b)
+        local sdmu=estimations[1,`=colsof(estimations)']
+    }
+    else{
+        gllamm estimates cons ``=`nbit'+1''_`ident1'-``=`nbit'+`nbcov'''_`ident`nbcov'_`nbModCov`nbcov''', offset(difficulties) i(theta) eqs(slope) link(mlogit) expand(`obs' `choix' o) weight(`wt') `iterateII' `adapt' `robust' nocons nodis constraint(`contrainte')
+    }
+    matrix eB=e(b)
+    local nbc=colsof(eB)
+    matrix eV=e(V)
+/* SS type III*/
+    tempfile bddencours
+    qui save `bddencours', replace 
+    qui use `bddini', replace
+    local varianceRes=eB[1,`=colsof(eB)']^2
+    qui{
+        local contv=1
+        local ddlssIIIc=`ddlssIII'
+        forvalues c=`=1+`nbit''/`=`nbcov'+`nbit''{
+            local ddlssIIIc=`ddlssIIIc'-(`nbModCov`=`c'-`nbit'''-1)
+            tab ``c'', matcell(cell) matrow(row) 
+            local muG=0
+            local denommuG=0
+            local muGcarre=0
+            if "`difficulties'"==""{
+                forvalues cm=1/`nbModCov`=`c'-`nbit'''{
+                    local muG=`muG'+cell[`cm',1]*eB[1,`=`nbdifftot'+`contv'']
+                    local denommuG=`denommuG'+cell[`cm',1]
+                    local muGcarre=`muGcarre'+(`varianceRes'+eB[1,`=`nbdifftot'+`contv'']^2)*cell[`cm',1]
+                    local contv=`contv'+1
+                }
+            }
+            else{
+                forvalues cm=1/`nbModCov`=`c'-`nbit'''{
+                    local muG=`muG'+cell[`cm',1]*eB[1,`=1+`contv'']
+                    local denommuG=`denommuG'+cell[`cm',1]
+                    local muGcarre=`muGcarre'+(`varianceRes'+eB[1,`=1+`contv'']^2)*cell[`cm',1]
+                    local contv=`contv'+1
+                }
+            }
+            local Var_`c'=(`muGcarre'/`denommuG') - (`muG'/`denommuG')^2
+        }
+        local contv=1
+        local Varttot=`varianceRes'
+        forvalues c=`=1+`nbit''/`=`nbcov'+`nbit''{
+            local ddlssIIIs`c'=`ddlssIIIc'+(`nbModCov`=`c'-`nbit'''-1)
+            tab ``c'', matcell(cell) matrow(row) 
+            local muG=0
+            local denommuG=0
+            local muGcarre=0
+            if "`difficulties'"==""{
+                forvalues cm=1/`nbModCov`=`c'-`nbit'''{
+                    local muG=`muG'+cell[`cm',1]*eB[1,`=`nbdifftot'+`contv'']
+                    local denommuG=`denommuG'+cell[`cm',1]
+                    local muGcarre=`muGcarre'+(`Varttot'+eB[1,`=`nbdifftot'+`contv'']^2)*cell[`cm',1]
+                    local contv=`contv'+1
+                    local Varttot=(`muGcarre'/`denommuG') - (`muG'/`denommuG')^2
+                }
+            }
+            else{
+                forvalues cm=1/`nbModCov`=`c'-`nbit'''{
+                    local muG=`muG'+cell[`cm',1]*eB[1,`=1+`contv'']
+                    local denommuG=`denommuG'+cell[`cm',1]
+                    local muGcarre=`muGcarre'+(`Varttot'+eB[1,`=1+`contv'']^2)*cell[`cm',1]
+                    local contv=`contv'+1
+                    local Varttot=(`muGcarre'/`denommuG') - (`muG'/`denommuG')^2
+                }
+            }
+        }
+        forvalues c=`=1+`nbit''/`=`nbcov'+`nbit''{
+            local sst3_`c'=(`Var_`c''*`ddlssIIIs`c''-`varianceRes'*`ddlssIIIc')
+            local VarExp_`c'=(`Var_`c''*`ddlssIIIs`c''-`varianceRes'*`ddlssIIIc')/(`Varttot'*`ddlssIII')
+            local df_`c'=`nbModCov`=`c'-`nbit'''-1
+        }
+        local contv=1
+        forvalues c=`=1+`nbit''/`=`nbcov'+`nbit''{
+            if "`difficulties'"==""{
+                forvalues cc=1/`nbModCov`=`c'-`nbit'''{
+                    if `cc'==1{
+                        local contv=`contv'+1
+                    }
+                    else{
+                        local ESit`c'mod`cc' = `=eB[1,`=`nbdifftot'+`contv'']/sqrt(`Varttot')'
+                        local contv=`contv'+1
+                    }
+                    noi di in gr ""
+                }
+            }
+            else{
+                forvalues cc=1/`nbModCov`=`c'-`nbit'''{
+                    if `cc'==1{
+                        local contv=`contv'+1
+                    }
+                    else{
+                    /*
+                    noi di `contv'
+                    noi matrix list eB
+                    */
+                        local ESit`c'mod`cc' = `=eB[1,`=1+`contv'']/sqrt(`Varttot')'
+                        local contv=`contv'+1
+                    }
+                    noi di in gr ""
+                }
+            }
+        }
+    }
+    qui use `bddencours', replace 
+}
+else{
+    ereturn clear
+    if "`difficulties'"==""{
+        matrix a0=J(1,`nbdifftot',0)
+        qui{
+            tempfile bddencours
+            save `bddencours', replace 
+            use `bddini', replace
+            local countdif=1
+            forvalues i=1/`nbit'{
+                ologit ``i''
+                matrix ttt=e(b) 
+                matrix a0[1,`countdif']=ttt/2
+                local countdif=`countdif'+e(k)
+            }
+        use `bddencours', replace 
+        }
+        local colnom ""
+        forvalues i=1/`nbit'{
+            forvalues j=1/`=`moda`i''-1'{
+                local colnom "`colnom' d_``i''_`j'"
+            }
+        }
+        matrix coln a0=`colnom'
+        matrix coleq a0=estimates
+        matrix a1=J(1,1,0)
+        matrix coln a1=estimates
+        matrix coleq a1=theta1_1
+        matrix a=a0,a1
+        gllamm estimates d_`1'_1-d_``nbit''_`=`moda`nbit''-1', i(theta) eqs(slope) link(mlogit) expand(`obs' `choix' o) weight(`wt') `iterateII' `adapt' `robust' nocons nodis from(a) copy
+        matrix estimations = e(b)
+        local sdmu=estimations[1,`=colsof(estimations)']
+    }
+    else{
+        gen cons=estimates
+        gllamm estimates cons, offset(difficulties) i(theta) eqs(slope) link(mlogit) expand(`obs' `choix' o) weight(`wt') `iterateII' `adapt' `robust' nocons nodis
+    }
+    matrix eB=e(b)
+    local nbc=colsof(eB)
+    matrix eV=e(V)
+}
+clear
+use `bddini'
+
+
+
+if "`difficulties'"==""{
+  /*************************************/
+ /*              test R1m             */
+/*************************************/
+    noi di in gr "Performing R1m test"
+    qui{
+        set matsize `matsizeini'
+        tempfile matU
+        tempname dm cell row
+        egen `dm'=rowmiss(`varlist')
+        replace `dm'=`dm'>0
+        tab `dm',matcell(`cell') matrow(`row')
+        local nbmissing=`cell'[2,1]
+        local percentmissing=`cell'[2,1]/(`cell'[1,1]+`cell'[2,1])
+        if `nbmissing'==.{
+            local nbmissing=0
+            local percentmissing=0
+        }
+        keep if `dm'==0
+        drop `dm'
+        keep `varlist' `covariates'
+        if `nbcov'!=0{
+            local mumodifie=0
+            local compteuri=`nbdifftot'
+            forvalues c=1/`nbcov'{
+                forvalues m=1/`nbModCov`c''{
+                    local compteuri=`compteuri'+1
+                    local mumodifie=`mumodifie'+(`nbmod`m'cov`c''/`Nbid')*estimations[1,`compteuri']
+                }
+            }
+            drop `covariates'
+        }
+        forvalues i=1/`nbit'{
+            rename ``i'' pre_``i''
+        }
+        forvalues i=1/`nbit'{
+            gen it`i'=pre_``i''
+            drop pre_``i''
+        }
+        forvalues i=1/`nbit'{
+            qui tab it`i'
+            local nbmoda_`i'=r(r)
+        }
+        local score "it1"
+        forvalues i=2/`nbit'{
+            local score "`score'+it`i'"
+        }
+        gen score=`score'
+        save `bddini'_se, replace
+        local N=_N
+
+/* autogroup */
+        if "`group'"==""{
+            tab score, matcell(freq) matrow(val)
+            if r(N)<60{
+                di in red "Pas assez d'individus pour grouper de façon automatique"
+            }
+            local nbscore=r(r)
+            local ini=0
+            local pb=1
+            local list ""
+            forvalues i=1/`nbscore'{
+                local ini=`ini'+freq[`i',1]
+                if `ini'<30{
+                    local lim`i'=""
+                    local pb=1
+                }
+                else{
+                    local lim`i'=" `=val[`i',1]'"
+                    local ini=0
+                    local pb=0
+                }
+                local list "`list' `lim`i''"
+            }
+            local list "`=itrim("`list'")'"
+            if `pb'==1{
+                local list "`=subinword("`list'",word("`list'",-1),"",.)'"
+                local list "`=itrim("`list' `=val[`nbscore',1]'")'"
+            }
+            if wordcount("`list'")<2{
+                di in red "Autogroup impossible : pas de possibilité de constituer plusieurs groupes de plus de 30 individus à partir du score"
+            }
+            local nbgroup=wordcount("`list'")
+        }
+        else{
+            local list "`group'"
+            local nbgroup=wordcount("`list'")
+            tab score, matcell(freq) matrow(val)
+            local nbscore=r(r)
+        }
+        local nbmodagpe=0
+        forvalues i=1/`nbit'{
+            local nbmodagpe=`nbmodagpe'+`nbmoda_`i''
+        }
+        gen g=.
+        local liminf1=-1
+        forvalues i=1/`nbgroup'{
+            local limsup`i'=real("`=word("`list'",`i')'")
+            if `i'>1{
+                local liminf`i'=real("`=word("`list'",`=`i'-1')'")
+            }
+            replace g=`i' if score<=`limsup`i'' & score>`liminf`i''
+        } 
+        forvalues i=1/`nbgroup'{
+            su score if g==`i'
+            local N`i'=r(N)
+        }
+        save `bddini'_se, replace
+        save `bddini'_se_g, replace
+        use `bddini'_se, replace
+        local count=0
+        forvalues i=1/`nbit'{
+            forvalues j=1/`nbmoda_`i''{
+                if `j'==1{
+                    local diffest`i'_`j'=0
+                }
+                else{
+                    local count=`count'+1
+                    local diffest`i'_`j'=round(estimations[1,`count'],0.001)+`diffest`i'_`=`j'-1''
+                }
+                local num`i'_`j' "exp(`=`j'-1'*x-`diffest`i'_`j'')"
+                if `j'==1{
+                    local denom`i' "1"
+                }
+                else{
+                    local denom`i' "`denom`i''+`num`i'_`j''"
+                }
+            }
+            forvalues j=1/`nbmoda_`i''{
+                local PCM`i'_`j' "(`num`i'_`j'')/(`denom`i'')"
+            }
+        }
+        local nbcomb=1
+        forvalues i=1/`nbit'{
+            local nbcomb=`nbcomb'*`nbmoda_`i''
+        }
+        clear
+        set obs `nbcomb'
+        local facteur=1
+        gen score=0
+        local order "score"
+        forvalues i=1/`nbit'{
+            gen it`i'=floor(mod(_n/`facteur',`nbmoda_`i''))
+            local facteur=`facteur'*`nbmoda_`i''
+            replace score=score+it`i'
+            tab it`i', gen(i`i'c)
+            local order "`order' it`i'"
+        }
+        order `order', first
+        sort score
+
+/* Probabilité des paterns de réponse */
+        tab score, gen(score)
+        local nbscore=r(r)
+        gen P=1
+        local gdN=_N
+        forvalues l=1/`gdN'{
+            local exp ""
+            forvalues i=1/`nbit'{
+                forvalues m=1/`nbmoda_`i''{
+                    if i`i'c`m'[`l']==1{
+                        if "`exp'"==""{
+                            local exp "`PCM`i'_`m''"
+                        }
+                        else{
+                            local exp "`exp'*`PCM`i'_`m''"
+                        }
+                    }
+                }
+            }
+            if `nbcov'==0{
+                gausshermite `exp' , sigma(`sdmu') mu(0) display
+            }
+            else{
+                local sdgauss=sqrt(`Varttot')
+                gausshermite `exp' , sigma(`sdgauss') mu(`mumodifie') display
+            }
+            replace P=r(int) if _n==`l'
+            di "`exp'"
+        }
+        tab score
+        local Pscoresl=r(r)
+        matrix Pscores=J(`Pscoresl',2,.)
+        forvalues i=1/`Pscoresl'{
+            su P if score==`=`i'-1'
+            matrix Pscores[`i',2]=r(sum)
+            matrix Pscores[`i',1]=`i'-1
+        }
+        save `matU'_2, replace
+        local sort "score"
+        forvalues i=1/`nbit'{
+            local sort "`sort' it`i'"
+            forvalues j=1/`nbmoda_`i''{
+                replace i`i'c`j'=i`i'c`j'*P
+            }
+        }
+        forvalues i=1/`nbscore'{
+            replace score`i'=score`i'*P
+        }
+        save `matU'_1, replace
+/* Matrices U */
+        local order ""
+        forvalues i=1/`=wordcount("`list'")'{
+            local nbscoreg`i'= `nbscore'
+            forvalues j=0/`=`nbscore'-1'{
+                if `j'>`limsup`i'' | `j'<=`liminf`i''{
+                    local nbscoreg`i'=`nbscoreg`i''-1
+                    capture drop s`=`j'+1'g`i'
+                }
+            }
+            local order "`order' *g`i'"
+            use `matU'_1, replace
+            keep if score<=`limsup`i'' & score>`liminf`i''
+            gen g=`i'
+            forvalues a=1/`nbit'{
+                forvalues b=1/`nbmoda_`a''{
+                    capture rename i`a'c`b' i`a'c`b'g`i'
+                }
+            }
+            forvalues a=1/`nbscore'{
+                capture rename score`a' s`a'g`i'
+                forvalues j=1/`=wordcount("`list'")'{
+                    if `=`a'-1'>`limsup`i'' | `=`a'-1' <= `liminf`i''{
+                        capture drop s`a'g`j'
+                    }
+                }
+            }
+            tempfile bloc`i'
+            sort `sort'
+            save `bloc`i''_1, replace
+        }
+        local order ""
+        forvalues i=1/`=wordcount("`list'")'{
+            local order "`order' *g`i'"
+            use `matU'_2, replace
+            keep if score<=`limsup`i'' & score>`liminf`i''
+            gen g=`i'
+            forvalues a=1/`nbit'{
+                forvalues b=1/`nbmoda_`a''{
+                    capture rename i`a'c`b' i`a'c`b'g`i'b
+                }
+            }
+            forvalues a=1/`nbscore'{
+                capture rename score`a' s`a'g`i'b
+                forvalues j=1/`=wordcount("`list'")'{
+
+                    if `=`a'-1'>`limsup`i'' | `=`a'-1' <= `liminf`i''{
+                        capture drop s`a'g`j'
+                    }
+                }
+            }
+            sort `sort'
+            save `bloc`i''_2, replace
+            describe
+            local mat_`i'=r(k)-3-`nbit'
+        }
+
+/* Matrice W */
+        local nbscoreg0=0
+        forvalues g=1/`nbgroup'{
+            qui q memory
+            if `mat_`g''>r(matsize) & `mat_`g''<=r(m_matsize){
+                set matsize `mat_`g''
+            }
+            if `mat_`g''>r(m_matsize){
+                di in red "Error, not enought memory to allocate to the W matrix calculation"
+            }
+            matrix W_`g'=J(`mat_`g'',`mat_`g'',.)
+            use `bloc`g''_2, replace
+            local count=1
+            forvalues i=1/`nbit'{
+                forvalues j=1/`nbmoda_`i''{
+                    rename i`i'c`j'g`g'b v`count'b
+                    local count=`count'+1
+                }
+            }
+            forvalues s=1/`=`nbscore'+1'{
+                capture rename s`s'g`g'b v`count'b
+                if _rc ==0{
+                    local count=`count'+1
+                }
+            }
+            local Ncol_`g'_=`count'-1
+            save `bloc`g''_2b, replace
+            use `bloc`g''_1, replace
+            local count=1
+            forvalues i=1/`nbit'{
+                forvalues j=1/`nbmoda_`i''{
+                    rename i`i'c`j'g`g' v`count'
+                    local count=`count'+1
+                }
+            }
+            forvalues s=1/`=`nbscore'+1'{
+                capture rename s`s'g`g' v`count'
+                if _rc ==0{
+                    local count=`count'+1
+                }
+            }
+            local Ncol_`g'__=`count'-1
+            forvalues i=1/`=`count'-1'{
+                replace v`i'=P if round(v`i',0.000001)!=round(0,0.000001)
+            }
+            local countW_`g'=`count'-1
+            save `bloc`g''_1b, replace
+            merge `sort' using `bloc`g''_2b
+            drop _merge
+            forvalues i=1/`mat_`g''{
+                forvalues j=1/`mat_`g''{
+                    gen prod=v`i'*v`j'b
+                    qui su prod
+                    matrix W_`g'[`i',`j']=r(sum)
+                    drop prod
+                }
+            }
+            capture matrix W_`g'i=invsym(W_`g')
+            if _rc!=0{
+                capture matrix W_`g'i=inv(W_`g')
+            }
+            if _rc!=0{
+                di in red "Error while computing the Wg matrix"
+            }
+            mata: A=J(1,1,.)
+            mata: A[1,1]=rank(st_matrix("W_`g'"))
+            mata: st_matrix("rank_",A)
+            local rank`g'=rank_[1,1]
+        }
+
+/* Matrice poid */
+        forvalues g=1/`nbgroup'{
+            use `bddini'_se_g, replace
+            keep if g==`g'
+            gen Pd=1
+            collapse (sum) nb=Pd, by(`sort')
+            sort `sort'
+            save `bddini'_se_`g'obs, replace
+            use `bloc`g''_2b, replace
+            sort `sort'
+            merge `sort' using `bddini'_se_`g'obs
+            drop _merge
+            replace nb=0 if nb==.
+            gen nbth=P*`N'
+            gen Di=(nb-nbth)/sqrt(`N')
+            sort `sort'
+            save `bloc`g''_2bgi, replace
+            if `countW_`g''>10{
+                set matsize `countW_`g''
+            }
+            else{
+                set matsize 10
+            }
+            matrix deviation_`g'=J(`countW_`g'',1,.)
+            use `bloc`g''_2bgi, replace
+            gen Pobs=nb/`N'
+            gen Diff=Pobs-P
+            forvalues j=1/`countW_`g''{
+                replace v`j'b=v`j'b*Diff
+                su v`j'b
+                matrix deviation_`g'[`j', 1]=r(sum)*sqrt(`N')
+            }
+        }
+        local sum=0
+        local ddl=0
+        local rank ""
+        qui q memory
+        if `matsizeini'>r(matsize) & 10000 > r(m_matsize){
+            set matsize `matsizeini'
+        }
+        else{
+            set matsize 10000
+        }
+        forvalues g=1/`nbgroup'{
+            capture matrix G_`g'=deviation_`g''*W_`g'i*deviation_`g'
+            if _rc!=0{
+                noi di in red "Error, not enought memory to allocate to the W matrix calculation
+            }
+            local sum=`sum'+G_`g'[1,1]
+            local ddl=`ddl'+`rank`g''
+            local rank "`rank'`rank`g''  "
+        }
+        local ddl=`ddl'-`nbmodagpe'+`nbit'-2
+        set matsize `matsizeini'
+    }
+    local R1m_group "`list'"
+    local R1m_Rank `rank'
+    local R1M_ddl=`ddl'
+    local R1M_stat=`sum'
+    local R1M_p=`=1-chi2(`ddl', `sum')'
+
+
+  /*************************************/
+ /*              tests Si             */
+/*************************************/
+
+    qui{
+        local countbase=0
+        forvalues ii=1/`nbit'{
+            forvalues j=1/`nbmoda_`ii''{
+                local countbase=`countbase'+1
+            }
+        }
+        forvalues s=1/`nbscore'{
+            local countbase=`countbase'+1
+        }
+        matrix DGibase=J(6,`countbase',.)
+        use `bddini'_se_g, replace
+        local countbase=0
+        forvalues ii=1/`nbit'{
+            tab it`ii', gen(i`ii'c)
+            forvalues j=1/`nbmoda_`ii''{
+                local countbase=`countbase'+1
+                matrix DGibase[2,`countbase']=`ii'
+                matrix DGibase[3,`countbase']=`j'
+                su i`ii'c`j'
+                matrix DGibase[4,`countbase']=r(sum)
+            }
+            drop i`ii'c*
+        }
+        tab score, gen(s)
+        forvalues s=1/`nbscore'{
+            capture su s`s'
+            if _rc!=0{
+                gen s`s'=0
+            }
+        }
+        forvalues s=1/`nbscore'{
+            local countbase=`countbase'+1
+            matrix DGibase[2,`countbase']=`s'
+            su s`s'
+            matrix DGibase[4,`countbase']=r(sum)
+        }
+        use `matU'_2, replace
+        local countbase=0
+        forvalues ii=1/`nbit'{
+            forvalues j=1/`nbmoda_`ii''{
+                local countbase=`countbase'+1
+                su P if i`ii'c`j'==1
+                matrix DGibase[5,`countbase']=r(sum)*`N'
+                matrix DGibase[6,`countbase']=(DGibase[4,`countbase']-DGibase[5,`countbase'])/sqrt(`N')
+            }
+        }
+        forvalues s=1/`nbscore'{
+            local countbase=`countbase'+1
+                su P if score`s'==1
+                matrix DGibase[5,`countbase']=r(sum)*`N'
+                matrix DGibase[6,`countbase']=(DGibase[4,`countbase']-DGibase[5,`countbase'])/sqrt(`N')
+        }
+        local colbase=`countbase'
+    }
+    forvalues i=1/`nbit'{
+        qui{
+            use `matU'_2, replace
+            gen g=.
+            local liminf1=-1
+            forvalues g=1/`nbgroup'{
+                replace g=`g' if score<=`limsup`g'' & score>`liminf`g''
+            }
+            forvalues g=1/`nbgroup'{
+                forvalues j=1/`nbmoda_`i''{
+                    gen testi`i'c`j'g`g'=0
+                    replace testi`i'c`j'g`g'=i`i'c`j' if g==`g'
+                }
+            }
+            local count=1
+            forvalues ii=1/`nbit'{
+                forvalues j=1/`nbmoda_`ii''{
+                    rename i`ii'c`j' v`count'b
+                    local count=`count'+1
+                }
+            }
+            forvalues s=1/`=`nbscore'+1'{
+                capture rename score`s' v`count'b
+                if _rc ==0{
+                    local count=`count'+1
+                }
+            }
+            forvalues g=1/`nbgroup'{
+                forvalues j=1/`nbmoda_`i''{
+                    rename testi`i'c`j'g`g' v`count'b
+                    local count=`count'+1
+                }
+            }
+            local nbarrive`i'=`count'-1
+            sort `sort'
+            save `matU'_2i`i', replace
+            use `matU'_1, replace
+            gen g=.
+            local liminf1=-1
+            forvalues g=1/`nbgroup'{
+                replace g=`g' if score<=`limsup`g'' & score>`liminf`g''
+            }
+            forvalues g=1/`nbgroup'{
+                forvalues j=1/`nbmoda_`i''{
+                    gen testi`i'c`j'g`g'=0
+                    replace testi`i'c`j'g`g'=i`i'c`j' if g==`g'
+                }
+            }
+            local count=1
+            forvalues ii=1/`nbit'{
+                forvalues j=1/`nbmoda_`ii''{
+                    rename i`ii'c`j' v`count'
+                    local count=`count'+1
+                }
+            }
+            forvalues s=1/`=`nbscore'+1'{
+                capture rename score`s' v`count'
+                if _rc ==0{
+                    local count=`count'+1
+                }
+            }
+            forvalues g=1/`nbgroup'{
+                forvalues j=1/`nbmoda_`i''{
+                    rename testi`i'c`j'g`g' v`count'
+                    local count=`count'+1
+                }
+            }
+            sort `sort'
+            save `matU'_1i`i', replace
+            merge `sort' using `matU'_2i`i'
+            drop _merge
+            if `nbarrive`i''>r(matsize) & `nbarrive`i''<=r(m_matsize){
+                set matsize `nbarrive`i''
+            }
+            if `nbarrive`i''>r(m_matsize){
+                di in red "Error, not enought memory to allocate to the W matrix calculation"
+            }
+            matrix i`i'W=J(`nbarrive`i'',`nbarrive`i'',.)
+            forvalues ii=1/`nbarrive`i''{
+                forvalues j=1/`nbarrive`i''{
+                    gen prod=v`ii'*v`j'b
+                    qui su prod
+                    matrix i`i'W[`ii',`j']=r(sum)
+                    drop prod
+                }
+            }
+            capture matrix i`i'Wi=invsym(i`i'W)
+            if _rc!=0{
+                capture matrix i`i'Wi=inv(i`i'W)
+            }
+            if _rc!=0{
+                di in red "Error while computing the Wg matrix"
+            }
+            mata: A=J(1,1,.)
+            mata: A[1,1]=rank(st_matrix("i`i'W"))
+            mata: st_matrix("rank_",A)
+            local i`i'rank=rank_[1,1]
+            matrix plus`i'=J(6,`=`nbarrive`i''-`colbase'',.)
+            matrix DGi_`i'=DGibase,plus`i'
+            save `matU'_i`i', replace
+            local count=`colbase'
+            use `bddini'_se_g, replace
+            tab it`i', gen(i`i'c)
+            forvalues g=1/`nbgroup'{
+                forvalues j=1/`nbmoda_`i''{
+                    local count=`count'+1
+                    matrix DGi_`i'[2,`count']=`i'
+                    matrix DGi_`i'[3,`count']=`j'
+                    matrix DGi_`i'[1,`count']=`g'
+                    su i`i'c`j' if g==`g'
+                    matrix DGi_`i'[4,`count']=r(sum)
+                }
+            }
+            use `matU'_i`i', replace
+            forvalues t=`=`colbase'+1'/`nbarrive`i''{
+                su P if v`t'b==1
+                matrix DGi_`i'[5,`t']=r(sum)*`N'
+                matrix DGi_`i'[6,`t']=(DGi_`i'[4,`t']-DGi_`i'[5,`t'])/sqrt(`N')
+            }
+            set matsize `matsizeini'
+            matrix tDGi_`i'=DGi_`i'[6,1..`=colsof(DGi_`i')']'
+            matrix G=tDGi_`i''*i`i'Wi*tDGi_`i'
+            local sum=G[1,1]
+            local ddl=`i`i'rank'
+            local ddl=`ddl'-`nbmodagpe'+`nbit'-2
+            local rank "`i`i'rank'"
+        }
+        local S`i'_rank=`rank'
+        local S`i'_ddl=`ddl'
+        local S`i'_stat=`sum'
+        local S`i'_p=`=1-chi2(`ddl', `sum')'
+    }
+}
+
+  /*************************************/
+ /*               print               */
+/*************************************/
+
+
+
+di in gr ""
+di in gr "              log likelihood : " in ye "`=e(ll)'"
+local lll=e(ll)
+local ccnn=e(cn)
+di in gr "              Condition number : " in ye "`=e(cn)'"
+di in gr "              Number of individuals : "in ye "`Nbid'"
+di in gr "              Number of items : "in ye "`nbit'"
+if `nbcov'!=0{
+    di in gr "              Number of covariates : "in ye "`nbcov'"
+}
+di in gr ""
+di ""
+if "`difficulties'"==""{ 
+    di in gr "Global tests of the fit : test R1m"
+    di in gr "              groups : " in ye "`R1m_group'"
+    di in gr "              Number of individuals with missing data : " in ye "`nbmissing' "  in gr "(" in ye "`=round(`=`percentmissing'*100',0.01)'%" in gr ")"
+    di ""
+    di in gr "{hline 46}"
+    di _col(22) in gr "test value" _col(35) in gr "df" _col(40) in gr "p-value"
+    di in gr "{hline 46}"
+    di _col(3) in gr "R1m" _col(24) in ye %8.5f `R1M_stat' _col(33) in ye %4.0f `R1M_ddl'    _col(39) in ye %8.5f `R1M_p'  
+    di in gr "{hline 46}"
+    di in gr ""
+    di ""
+    matrix globalFit=(`R1M_stat',`R1M_ddl',`R1M_p')
+    matrix coln globalFit=R1m df p
+    matrix rown globalFit=Global
+
+}
+else{
+    di in gr "Tests of the fit (tests R1m and Si) not performed when difficulties are fixed"
+    di ""
+}
+di in gr "Parameters of the Latent trait distribution :"
+di ""
+if "`difficulties'"==""{
+    if `nbcov'!=0{
+        di in gr "              Latent trait mean in the subgroup `subgroup0' : fixed to 0"
+    }
+    else{
+        di in gr "              Overall latent trait mean : fixed to 0"
+    }
+}
+di in gr "              Variance of the Latent trait : SigmaÂČ=" in ye %8.5f (`=`=eB[1,`nbc']'')^2 in gr " (SE:"in ye %8.5f `= sqrt((2*`=eB[1,`nbc']')^2 *`=eV[`nbc',`nbc']'    )' in gr ")"
+local varTheta=(`=`=eB[1,`nbc']'')^2
+local Varvartheta=(2*`=eB[1,`nbc']')^2 *`=eV[`nbc',`nbc']'
+
+di ""
+if `nbcov'!=0{
+    di in gr "Latent trait group effect :"
+    di ""
+    di in gr "{hline 101}"
+    if "`difficulties'"==""{
+        local compteur=`nbdifftot'
+        di _col(21) in gr "Coef." _col(31) in gr "S.E." _col(41) in gr "z" _col(45) in gr "P>|z|" _col(58) in gr "[95% C.I.]" _col(71) in gr "D.St." _col(83) in gr "SS.III" _col(91) in gr "df" _col(95) in gr "V.expl."
+    di in gr "{hline 101}"
+    }
+    else{
+        di _col(22) in gr "Coef." _col(31) in gr "S.E." _col(41) in gr "z" _col(45) in gr "P>|z|" _col(58) in gr "[95% C.I.]" _col(71) in gr "D.St." _col(83) in gr "SS.III" _col(91) in gr "df" _col(95) in gr "V.expl."
+    di in gr "{hline 101}"
+        di _col(1) in gr "_cons" _col(19) in ye %7.4f `=eB[1,1]' _col(28) in ye %7.4f `=sqrt(eV[1,1])' _col(37) in ye %5.2f `=eB[1,1]/sqrt(eV[1,1])' _col(44) in ye %6.3f `=2*(1-normal(abs(eB[1,1]/sqrt(eV[1,1]))))'  _col(52) in ye %7.4f `=eB[1,1]-1.96*sqrt(eV[1,1])' _col(61) in ye %7.4f `=eB[1,1]+1.96*sqrt(eV[1,1])' _col(75) in ye "."  
+        di in gr "{hline 101}"
+        local compteur=1
+    }
+    forvalues i=1/`nbcov'{
+        local compteur=`compteur'+1
+        noi{
+            di _col(1) in gr "``=`nbit'+`i''' :"  _col(82) in ye %6.3f `sst3_`=`i'+`nbit'''     _col(91) in ye %2.0f  `df_`=`i'+`nbit''' _col(95) in ye %6.3f `=`VarExp_`=`i'+`nbit'''*100' "%"
+
+            di _col(4) in gr "``=`nbit'+`i''' :" in ye " `ident`i'_1'" _col(25) in ye  "0" _col(34) in ye "." _col(41) in ye "." _col(49) in ye "." _col(58) in ye "." _col(67) in ye "."    _col(75) in ye "."   
+        }
+        forvalues k=2/`nbModCov`i''{
+            local compteur=`compteur'+1
+            local estimate_e=eB[1,`compteur']
+            local se_e=sqrt(`=eV[`compteur',`compteur']')
+            noi{
+                di _col(4) in gr "``=`nbit'+`i''' :" in ye " `ident`i'_`k''" _col(19) in ye %7.4f `estimate_e' _col(28) in ye %7.4f `se_e' _col(37) in ye %5.2f `=`estimate_e'/`se_e'' _col(44) in ye %6.3f `=2*(1-normal(abs(`estimate_e'/`se_e')))'  _col(52) in ye %7.4f `=`estimate_e'-1.96*`se_e'' _col(61) in ye %7.4f `=`estimate_e'+1.96*`se_e''     _col(70) in ye %6.3f `ESit`=`i'+`nbit''mod`k''
+            }
+        }
+        di in gr "{hline 101}"
+    }
+    di ""
+}
+else if "`difficulties'"!=""{
+    di in gr "Latent trait distribution"
+    di in gr "{hline 85}"
+    di _col(23) in gr "Coef." _col(36) in gr "S.E." _col(48) in gr "z" _col(57) in gr "P>|z|" _col(66) in gr "[95% Conf. Interval]"
+    di in gr "{hline 85}"
+    di _col(1) in gr "Mu" _col(20) in ye %8.5f `=eB[1,1]' _col(32) in ye %8.5f `=sqrt(eV[1,1]) ' _col(44) in ye %5.2f `=`=eB[1,1]'/`=sqrt(eV[1,1]) '' _col(56) in ye %6.3f `=2*(1-normal(abs(`=eB[1,1]'/`=sqrt(eV[1,1]) ')))'  _col(66) in ye %8.5f `=`=eB[1,1]'-1.96*`=sqrt(eV[1,1]) '' _col(78) in ye %8.5f `=`=eB[1,1]'+1.96*`=sqrt(eV[1,1]) ''
+    
+    di _col(1) in gr "Sigma" _col(20) in ye %8.5f `=eB[1,`nbc']' _col(32) in ye %8.5f `=sqrt(`=eV[`nbc',`nbc']')' _col(44) in ye %5.2f `=eB[1,`nbc']/sqrt(`=eV[`nbc',`nbc']')' _col(56) in ye %6.3f `=2*(1-normal(abs(eB[1,`nbc']/sqrt(`=eV[`nbc',`nbc']'))))'  _col(66) in ye %8.5f `=eB[1,`nbc']-1.96*sqrt(`=eV[`nbc',`nbc']')' _col(78) in ye %8.5f `=eB[1,`nbc']+1.96*sqrt(`=eV[`nbc',`nbc']')'
+    di in gr "{hline 85}"
+    di ""
+}
+if "`difficulties'"==""{ 
+
+    matrix itemFit=J(`nbit',3,.)
+    local itemFitname ""
+    matrix coln itemFit=R1m df p
+    matrix rown globalFit=Global
+
+
+
+    di in gr "Items difficulty parameters :"
+    di ""
+    di in gr "{hline 80}"
+    di _col(1) in gr "Item"  _col(21) in gr "Coef." _col(31) in gr "S.E."   _col(43) in gr "[95% C.I.]" _col(66) in gr"Si" _col(70) in gr "df" _col(74) in gr "p-value" 
+    di in gr "{hline 80}"
+    local compteur=1
+    forvalues i=1/`nbit'{
+        local itemFitname "`itemFitname' ``i'' "
+        di _col(1) in gr "``i'' :"  _col(60) in ye %8.5f `S`i'_stat' _col(65) in ye %4.0f `S`i'_ddl'    _col(73) in ye %8.5f `S`i'_p'
+        matrix itemFit[`i',1]=`S`i'_stat'
+        matrix itemFit[`i',2]=`S`i'_ddl'
+        matrix itemFit[`i',3]=`S`i'_p'
+        forvalues g=1/`=`moda`i''-1'{
+            di _col(4) in gr "modality :" in ye "`g'" _col(19) in ye %7.4f `=eB[1,`compteur']' _col(28) in ye %7.4f `=sqrt(`=eV[`compteur',`compteur']')'   _col(37) in ye %7.4f `=eB[1,`compteur']-1.96*sqrt(`=eV[`compteur',`compteur']')' _col(46) in ye %7.4f `=eB[1,`compteur']+1.96*sqrt(`=eV[`compteur',`compteur']')' 
+            local compteur=`compteur'+1
+        }
+        di in gr "{hline 80}"
+    }
+    matrix rown itemFit=`itemFitname'
+    di ""
+}
+else{
+    di in gr "Items difficulty parameters : fixed for the analysis"
+}
+
+
+  /*************************************/
+ /*              ereturn              */
+/*************************************/
+
+if "`difficulties'"==""{ 
+    matrix Varbeta=e(V)
+    local Varsigma=Varbeta[`=colsof(Varbeta)',`=colsof(Varbeta)']
+    matrix Varbeta=Varbeta[1..`nbit',1..`nbit']
+    matrix beta=e(b)
+    local sigma=beta[1,`=colsof(beta)']
+    matrix beta=beta[1,1..`nbit']
+    if `nbcov'!=0{
+        matrix Vartheta=e(b)
+        matrix Vartheta=beta[`nbit'..`=colsof(Vartheta)-1',`nbit'..`=colsof(Vartheta)-1']
+        matrix theta=e(b)
+        matrix theta=beta[1,`nbit'..`=colsof(theta)-1']
+    }
+    else{
+        local theta=0
+        local Vartheta=0
+    }
+}
+else{ 
+    if `nbcov'!=0{
+        matrix Vartheta=e(V)
+        local Varsigma=Vartheta[`=colsof(Vartheta)',`=colsof(Vartheta)']
+        matrix Vartheta=Vartheta[1..`=colsof(Vartheta)-1',1..`=colsof(Vartheta)-1']
+        matrix theta=e(b)
+        local sigma=theta[1,`=colsof(theta)']
+        matrix theta=theta[1,1..`=colsof(theta)-1']
+    }
+    else{
+        matrix theta=e(b)
+        local sigma=theta[1,`=colsof(theta)']
+        matrix Vtheta=e(b)
+        local Varsigma=Vtheta[`=colsof(Vtheta)',`=colsof(Vtheta)']
+        local theta=theta[1,1]
+        local vartheta=Vtheta[1,1]
+    }
+}
+
+
+
+ereturn clear
+ereturn scalar lll=`lll'
+ereturn scalar cn=`ccnn'
+ereturn scalar N=`Nbid'
+ereturn scalar Nit=`nbit'
+if `nbcov'!=0{
+    ereturn scalar Ncov=`nbcov'
+}
+
+if "`difficulties'"==""{ 
+    ereturn matrix Varbeta=Varbeta
+    ereturn matrix beta=beta
+    ereturn scalar sigma=`sigma'
+    ereturn scalar Varsigma=`Varsigma'
+    if `nbcov'!=0{
+        ereturn matrix Vartheta=Vartheta
+        ereturn matrix theta=theta
+    }
+    else{
+        matrix Vartheta=(0)
+        matrix coleq Vartheta=estimates
+        matrix coln Vartheta=mu
+        matrix roweq Vartheta=estimates
+        matrix rown Vartheta=mu
+        matrix theta=(0)
+        matrix coleq theta=estimates
+        matrix coln theta=mu
+        matrix rown theta=y1
+        ereturn matrix Vartheta=Vartheta
+        ereturn matrix theta=theta
+    }
+    ereturn matrix itemFit=itemFit
+    ereturn matrix globalFit=globalFit
+}
+else{ 
+    if `nbcov'!=0{
+        ereturn scalar sigma=`sigma'
+        ereturn scalar Varsigma=`Varsigma'
+        ereturn matrix Vartheta=Vartheta
+        ereturn matrix theta=theta
+    }
+    else{
+        ereturn scalar sigma=`sigma'
+        ereturn scalar Varsigma=`Varvartheta'
+        matrix Vartheta=(`vartheta')
+        matrix coleq Vartheta=estimates
+        matrix coln Vartheta=mu
+        matrix roweq Vartheta=estimates
+        matrix rown Vartheta=mu
+        ereturn matrix Vartheta=Vartheta
+        matrix theta=(`theta')
+        matrix coleq theta=estimates
+        matrix coln theta=mu
+        matrix rown theta=y1
+        ereturn matrix theta=theta
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+use `bddini', replace
+restore
+end
diff --git a/Modules/ado/personal/p/pcmold.ado b/Modules/ado/personal/p/pcmold.ado
new file mode 100644
index 0000000..0674bce
--- /dev/null
+++ b/Modules/ado/personal/p/pcmold.ado
@@ -0,0 +1,283 @@
+*! Version 2.3 10april2014
+************************************************************************************************************
+* Stata program : pcm
+* Estimate the parameters of the Partial Credit Model
+* Version 1 : December 17, 2007
+* Version 2 : July 15, 2011
+* Version 2.1 : October 18th, 2011 : -fixedvar- option, new presentation
+* Version 2.2 : October 23rd, 2013 : correction of -fixedvar- option
+* Version 2.3 : April 10th, 2014 : correction of -fixedvar- option
+*
+* Jean-benoit Hardouin, EA4275 Biostatistics, Clinical Research and Subjective Measures in Health Sciences
+* Faculties of Pharmaceutical Sciences & Medicine - University of Nantes - France
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2007-2014 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+program define pcmold,eclass
+version 8.0
+syntax varlist(min=3 numeric) [if] [in] [,rsm fixed(string) fixedvar(real -1) fixedmu short COVariates(varname) fixedvargroupc(string) vargroupc]
+preserve
+tempfile pcmfile
+qui save `pcmfile',replace
+
+if "`fixedmu'"!=""&`fixedvar'!=-1&"`covariates'"=="" {
+   di in red "You cannot fix in the same time the mean (fixedmu option) and the variance (fixedvar option) of the latent trait without covariables"
+   error 184
+}
+if "`fixed'"!=""&"`fixedmu'"==""&`fixedvar'!=-1&"`covariates'"=="" {
+   di in red "You cannot fix in the same time the difficulties (fixed option) and the variance (fixedvar option) of the latent trait without covariables"
+   error 184
+}
+
+/*******************************************************************************
+ESTIMATION OF THE PARAMETERS
+********************************************************************************/
+
+marksample touse
+qui keep if `touse'
+qui count
+local N=r(N)
+tokenize `varlist'
+local nbitems : word count `varlist'
+
+if "`rsm'"=="" {
+   di in gr "Model: " in ye "Partial Credit Model"
+}
+else {
+   di in gr "Model: " in ye "Rating Scale Model"
+}
+
+tempname one var w id item it obs x chosen d score
+qui gen `one'=1
+qui gen `id'=_n
+local modamax=0
+forvalues i=1/`nbitems' {
+   qui rename ``i'' `var'`i'
+   qui su `var'`i'
+   local moda`i'=`r(max)'
+   if `modamax'<`r(max)' {
+      local modamax=r(max)
+   }
+}
+qui genscore `var'1-`var'`nbitems' ,score(`score')
+qui collapse (sum) `w'=`one',by(`var'1-`var'`nbitems' `covariates')
+qui gen `id'=_n
+qui reshape long `var',i(`id') j(`item')
+qui drop if `var'==.
+qui gen `obs'=_n
+qui expand `=`modamax'+1'
+qui sort `id' `item' `obs'
+by `obs', sort: gen `x'=_n-1
+
+qui gen `chosen'=`var'==`x'
+qui tab `item', gen(`it')
+forvalues i=1/`nbitems' {
+   forvalues g=1/`modamax' {
+      qui gen `d'`i'_`g'=-1*`it'`i'*(`x'>=`g')
+   }
+}
+qui rename `w' `w'2
+bysort `id':egen score=sum(`x'*`chosen')
+qui su score
+local maxscore=r(max)
+
+
+if "`covariates'"!="" {
+   qui gen covw=`covariates'*`x'
+   local listcov covw
+}
+else {
+   local listcov
+}
+if `fixedvar'!=-1 {
+   local tmp=sqrt(`fixedvar')
+   constraint 1 `x'=`tmp'
+   local listconstr "constraints(1)"
+   local eq "eqs(slope) nrf(1)"
+}
+local eq "eqs(slope) nrf(1)"
+*set trace on
+if "`rsm'"=="" { /*PARTIAL CREDIT MODEL*/
+   *di "cas 1"
+   if "`fixed'"!="" { /*FIXED ITEMS DIFFICULTIES*/
+   *di "cas 2"
+      qui gen offset=0
+      local l=1
+      forvalues i=1/`nbitems' {
+         forvalues mi=1/`moda`i'' {
+            qui replace offset=offset+`fixed'[1,`l']*`d'`i'_`mi'
+            local ++l
+         }
+      }
+      if "`fixedmu'"!="" {
+         local mu
+      }
+      else {
+         local mu "`x'"
+      }
+*set trace on
+	  if "`fixedvargroupc'"!=""|"`vargroupc'"!="" {/*INEQUAL VARIANCES*/
+	       local var0: word 1 of `fixedvargroupc'
+	       local var1: word 2 of `fixedvargroupc'
+		   tempvar G0 G1
+		   qui gen `G0'=groupc<0
+		   qui gen `G1'=groupc>0
+		   qui replace `G0'=`G0'*`x'
+		   qui replace `G1'=`G1'*`x'
+		   qui eq B0: `G0'
+		   qui eq B1: `G1'
+	       constraint 1 _cons=0
+		   if "`fixedvargroupc'"!="" {/*FIXED INEQUAL VARIANCES*/
+		      constraint 2 `G0'=`=sqrt(`var0')' 
+		      constraint 3 `G1'=`=sqrt(`var1')'
+		      local listconstr "constraints(1 2 3)"
+           }
+		   else { /*FREE INEQUAL VARIANCE*/
+		      local listconstr "constraints(1)"
+		   }
+           local eq "eqs(B0 B1) nrf(2)"
+      }
+      eq slope:`x'
+      su
+	  tab covw
+	  di "ICI*******************jb"
+      di "`x' : x"
+	  di "`listcov' : listcov"
+	  di "`mu' : mu" 
+      noi di "gllamm `x'   `listcov' `mu',offset(offset) `listconstr' nocons i(`id') link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace `eq'"
+*set trace on
+      noi gllamm `x' `listcov' `mu' ,offset(offset) `listconstr' nocons i(`id') link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace `eq' iterate(100)
+   }
+   else if "`short'"!="" {
+      *di "cas 3"
+      eq slope:`x'
+      qui gllamm `x' `d'1_1-`d'`nbitems'_`modamax',i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons init iterate(100)
+      tempname bsave Vsave
+      matrix `bsave'=e(b)
+      matrix `Vsave'=e(V)
+      restore
+      qui pcm `varlist' , fixed(`bsave')
+   }
+   else {
+      *di "cas 4"
+      di "no short"
+      eq slope:`x'
+      qui gen i=`id'
+      constraint 1 `x'=1
+      gllamm `x' `d'1_1-`d'`nbitems'_`modamax' `listcov',i(i) `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons iterate(100)
+   }
+}
+else {
+   *di "cas 5"
+
+   tempname step n
+   forvalues i=2/`modamax' {
+      qui gen `step'`i'=-1*(`x'>=`i')
+   }
+   forvalues i=1/`nbitems' {
+      qui gen `n'`var'`i'=(-1)*(`it'`i')*(`x')
+   }
+   qui sort `id' `item' `x'
+   eq slope:`x'
+   gllamm `x' `n'`var'1-`n'`var'`nbitems' `step'2-`step'`modamax' `listcov', i(`id') `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons  iterate(100)
+}
+
+tempname b V chol
+matrix b=e(b)
+matrix V=e(V)
+local ll=e(ll)
+matrix chol=e(chol)
+
+
+if "`rsm'"=="" {
+   di
+   di in gr "Number of observations: " in ye `N'
+   di in gr "Number of items: " in ye `nbitems'
+   di in gr "Number of parameters: " in  ye `=`nbitems'*`modamax'+1'
+   di in gr "Log-likelihood: " in ye `ll'
+   di
+   di
+   di in gr "{hline 100}"
+   di in gr "Item" _col(10) "Modality" _col(20) "Parameter" _col(30) "Std Error"
+   di in gr "{hline 100}"
+   if "`fixed'"=="" {
+      forvalues i=1/`nbitems' {
+         forvalues j=1/`modamax' {
+            if `j'==1 {
+               di in ye "``i''" _cont
+            }
+            local k=(`i'-1)*`modamax'+`j'
+            if "`short'"!="" {
+               di in ye _col(17) `j' _col(20) %9.6f `bsave'[1,`k'] in ye _col(30) %9.6f (`Vsave'[`k',`k'])^.5
+            }
+            else {
+               di in ye _col(17) `j' _col(20) %9.6f b[1,`k'] in ye _col(30) %9.6f (V[`k',`k'])^.5
+            }
+         }
+         di in gr "{dup 100:-}"
+      }
+   }
+   else {
+      forvalues i=1/`nbitems' {
+         forvalues j=1/`modamax' {
+            if `j'==1 {
+               di in ye "``i''" _cont
+            }
+            local k=(`i'-1)*`modamax'+`j'
+            di in ye _col(17) `j' _col(20) %9.6f `fixed'[1,`k'] in ye _col(32) "(fixed)"
+         }
+         di in gr "{dup 100:-}"
+      }
+   }
+   if "`fixed'"==""&"`short'"=="" {
+      local k=`nbitems'*`modamax'+1
+   }
+   else if "`fixed'"!=""&"`fixedmu'"=="" {
+      di in ye "Mu" in ye _col(20) %9.6f b[1,1] _col(29) %10.6f  (V[1,1])^.5
+      local k=2
+   }
+   else if "`fixed'"!=""&"`fixedmu'"!="" {
+      di in ye "Mu" in ye _col(20) %9.6f 0 _col(32) %10.6f  "(fixed)"
+      local k=1
+   }
+   else {
+      local k=1
+   }
+   if "`covariates'"!="" {
+      di in ye "`covariates'" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f  (V[`k',`k'])^.5
+      local k=`k'+1
+   }
+   if `fixedvar'==-1 {
+      di in ye "Sigma" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f  (V[`k',`k'])^.5
+      di in ye "Variance" in ye _col(20) %9.6f b[1,`k']^2  _col(29) %10.6f  2*(V[`k',`k'])^.5*b[1,`k']
+   }
+   else {
+      di in ye "Sigma" in ye _col(20) %9.6f `fixedvar'^.5 _col(32) %10.6f  "(fixed)"
+      di in ye "Variance" in ye _col(20) %9.6f `fixedvar'  _col(32) %10.6f  "(fixed)"
+   }
+   di in gr "{hline 100}"
+   di
+   di
+}
+
+end
diff --git a/Modules/ado/personal/p/pcmtest.ado b/Modules/ado/personal/p/pcmtest.ado
new file mode 100644
index 0000000..6b9bce3
--- /dev/null
+++ b/Modules/ado/personal/p/pcmtest.ado
@@ -0,0 +1,1502 @@
+/********************************************************************************/
+/* v1.1 : Modified for being used after irt pcm and irt rsm                     */
+/********************************************************************************/
+* Needed modules :
+* gausshermite (http://www.freeirt.org)
+* gllamm version 2.3.14 (ssc describe gllamm)
+
+program define pcmtest, rclass 
+version 11.0
+syntax [, APproximation NEw Group(string) NFit(string) Power(string) Alpha(string) GRAPHics FILEgraph(string) Sitest]
+preserve
+qui{
+tempfile bddtravail
+save `bddtravail', replace
+
+
+tempname x w val freq
+capture local cmdavant=e(cmd)
+if _rc!=0 | "`cmdavant'"!="pcmodel"{
+	capture local cmdavant=e(model1)
+	local condition ="`cmdavant'"=="pcm" | "`cmdavant'"=="rsm"
+	if _rc!=0 | `condition'!=1{
+		noi di in red "Please use pcmtest only after pcmodel, irt pcm or irt rsm"
+		error 100
+	}
+	else{
+	local testIrtPcm=1
+	}
+	if "`cmdavant'"=="rsm"{
+		local RSMtest=1
+	}
+}
+if "`graphics'"!=""{
+	if "`filegraph'"!=""{
+		local ReplaceGr2=0
+		local ReplaceGr=strpos("`filegraph'",",")
+		if `ReplaceGr'!=0{
+			local ReplaceGr=strpos(reverse("`filegraph'"),",")
+			local ReplaceGr2=strpos( substr("`filegraph'", strpos("`filegraph'",","), .), "r")!=0
+			local filegraphOld="`filegraph'"
+			local filegraph=rtrim(reverse(substr(reverse("`filegraph'"),`=`ReplaceGr'+1',.)))
+		}
+		if `ReplaceGr2'==0{	
+			capture graph use "`filegraph'_LT_Sc", nodraw
+			if _rc==0{
+				noi di in red "`filegraph'_LT_Sc already exists (use option replace for replacing it)"
+				error 100
+			}
+			capture graph use "`filegraph'_MAP", nodraw
+			if _rc==0{
+				noi di in red "`filegraph'_MAP already exists (use option replace for replacing it)"
+				error 100
+			}
+			capture graph use "`filegraph'_Score_Distrib", nodraw
+			if _rc==0{
+				noi di in red "`filegraph'_Score_Distrib already exists (use option replace for replacing it)"
+				error 100
+			}
+			capture graph use "`filegraph'_Contrib", nodraw
+			if _rc==0{
+				noi di in red "`filegraph'_Contrib already exists (use option replace for replacing it)"
+				error 100
+			}
+		}
+		capture save "`filegraph'", replace
+		if _rc!=0{
+			noi di in red "Invalid path specification"
+			error 603
+		}
+		else{
+			erase "`filegraph'.dta"
+		}
+	}
+}
+
+   /***************************/
+  /* RĂ©cuperation de toutes  */
+ /*  les matrices estimées  */
+/***************************/
+local itest=e(itest)
+if `itest'==0{
+	noi di in red "No tests of fit if the items difficulties are fixed (i.e. not estimated) "
+	error 100
+}
+local Elll=e(ll)
+local Ecn=e(cn)
+local EN=e(N)
+local ENit=e(Nit)
+local dataR1m=e(dataR1m)
+local mugauss=e(mugauss)
+local sdgauss=e(sdgauss)
+local ordre=e(order)
+local ENqual=e(Ncat)
+local ENquant=e(Ncont)
+local convergeance=e(converged)	
+local Esigma=e(sigma)
+local EVarsigma=e(Varsigma)
+local ENumFit=e(NumFit)
+local Eitems=e(items)
+local IF=e(if)
+local IN=e(in)
+if "`IF'"!="" & "`IF'"!="."{
+	local if "`IF'"
+}
+if "`IN'"!="" & "`IN'"!="."{
+	local in "`IN'"
+}
+tempname EglobalFit EitemFit Etheta EVartheta Edelta EVardelta
+matrix `EglobalFit'=e(globalFit)
+matrix `EitemFit'=e(itemFit)
+matrix `Etheta'=e(theta)
+matrix `EVartheta'=e(Vartheta)
+matrix `Edelta'=e(delta)
+matrix `EVardelta'=e(Vardelta)
+local rsm=e(rsm)
+if "`rsm'"!="."{
+	local RSMtest2=1
+}
+else if "`RSMtest'"=="1"{
+	local RSMtest2=1
+}
+else{
+	local RSMtest2=0
+}
+
+/* irt pcm et irt rsm */
+
+if "`testIrtPcm'"=="1"{
+	local EN=e(N)
+	local mugauss=0
+	local if strpos(,s2)
+	local IFif=e(cmdline)
+	local PosIf=strpos("`IFif'"," if ")
+	local PosIn=strpos("`IFif'"," in ")
+	if strpos("`IFif'",",")==0{
+		local posComma="."
+	}
+	else{
+		local posComma=strpos("`IFif'",",")
+	}
+	if `PosIf'!=0 & `PosIn'!=0{
+		if `PosIf'<`PosIn'{
+			local if "`=substr("`IFif'",`=`PosIf'+4',`=`PosIn'-`PosIf'-4')'"
+			local in "`=substr("`IFif'",`=`PosIn'+4',`=`posComma'-`PosIn'-4')'"
+		}
+		else{
+			local in "`=substr("`IFif'",`=`PosIn'+4',`=`PosIf'-`PosIn'-4')'"
+			local if "`=substr("`IFif'",`=`PosIf'+4',`=`posComma'-`PosIf'-4')'"
+		}
+	}
+	else{
+		local if "`=substr("`IFif'",`=`PosIf'+4',`=`posComma'-`PosIf'-4')'"
+		local in "`=substr("`IFif'",`=`PosIn'+4',`=`posComma'-`PosIn'-4')'"
+	}
+	if `PosIf'==0{
+		local if=""
+	}
+	if `PosIn'==0{
+		local in=""
+	}
+	local itPcm=e(n_cuts1)
+	tempname Edelta DifComPcm tempmatdif EglobalFit EitemFit Etheta EVartheta EVardelta
+	matrix `DifComPcm'=e(b)
+	local nbcolMD=0
+	local plus=0
+	matrix `Edelta'=(.)
+	foreach i in `itPcm'{
+		local sum=0
+		forvalues it=2/`i'{
+			local tempmatdifnnn=`DifComPcm'[1,`=2*`it'+`plus'']-`DifComPcm'[1,`=2*`=`it'-1'+`plus'']
+			matrix `tempmatdif'=(`=-`tempmatdifnnn'')
+			matrix `Edelta'=`Edelta',`tempmatdif'
+		}
+		local plus=`plus'+2*`i'
+	}
+	matrix `Edelta'=`Edelta'[....,2...]
+	local sdgauss=`DifComPcm'[1,3]
+	local Eitems=e(items1)
+}
+qui capture matrix list r(globalFitTot)
+if _rc!=0{
+	local testafaire=1
+}
+else{
+	local testafaire=0
+}
+if "`new'"!=""{
+local testafaire=1
+}
+if "`nfit'"!=""{
+	local numFit=`nfit'
+}
+else{
+	local numFit=.
+}
+local varlist `Eitems'
+local nbit: word count `varlist'
+local nbitsuf=1
+if `nbit'<2{
+	noi di in red "No tests of fit if the number of items is less than 2"
+	error 100
+}
+if `nbit'==2{
+	noi di in gr "Only the R1m test is performed if the number of items is equal to 2"
+	local nbitsuf=0
+}
+tokenize `varlist'
+qui{
+	marksample touse,novarlist
+	keep if `touse'
+	local ordre=0
+	forvalues i=1/`nbit'{
+		tempname rep__`i'
+		tab ``i'', matrow(`rep__`i'')
+		local ordre=`ordre'+`=rowsof(`rep__`i'')'-1
+		forvalues j=1/`=rowsof(`rep__`i'')'{
+			replace ``i''=`j'-1 if ``i''==`rep__`i''[`j',1]
+		}
+	}
+	if `RSMtest2'==1{
+		local ordre=`=rowsof(`rep__1')'-2+`nbit'
+	}
+	q memory
+}
+tempfile bddini datatest bdd_b bdd_se bdd_seg bdd_P bdd_R1 bdd_G
+save `bdd_b', replace
+save `datatest', replace
+
+  /*************************************/
+ /*			  	test R1m			  */
+/*************************************/
+
+noi di in gr "Performing R1m test"
+qui{
+	q memory
+	local matsizeini=r(matsize)
+	set matsize `matsizeini'
+	tempfile matU matU1 matU2
+	tempname dm cell row
+	egen `dm'=rowmiss(`varlist')
+	replace `dm'=`dm'>0
+	tab `dm',matcell(`cell') matrow(`row')
+	local nbmissing=`cell'[2,1]
+	local percentmissing=`cell'[2,1]/(`cell'[1,1]+`cell'[2,1])
+	if `nbmissing'==.{
+		local nbmissing=0
+		local percentmissing=0
+	}
+	keep if `dm'==0
+	local NbIdFit=_N
+	if `numFit'==.{
+		local propFit=1
+		local propFitPb=0
+	}
+	else if `numFit'>`NbIdFit'{
+		local propFit=1
+		local propFitPb=1
+	}
+	else{
+		local propFit=`numFit'/`NbIdFit'
+		local propFitPb=2
+	}
+	drop `dm'
+	keep `varlist'
+	forvalues i=1/`nbit'{
+		rename ``i'' pre_``i''
+	}
+	forvalues i=1/`nbit'{
+		gen it`i'=pre_``i''
+		drop pre_``i''
+	}
+	local nbscore=1
+	forvalues i=1/`nbit'{
+		qui tab it`i'
+		local nbmoda_`i'=r(r)
+		local nbscore=`nbscore'+`nbmoda_`i''-1
+	}
+	local score "it1"
+	forvalues i=2/`nbit'{
+		local score "`score'+it`i'"
+	}
+	gen score=`score'
+	save `bdd_se', replace
+	local N=_N
+/* autogroup */
+	if "`group'"==""{
+		su score, d
+		local list `=r(p25)'
+		if `=r(p25)'!=`=r(p50)'{
+		local list "`list' `=r(p50)'"
+		}
+		if `=r(p50)'!=`=r(p75)'{
+		local list "`list' `=r(p75)'"
+		}
+		if `=r(p75)'!=`=`nbscore'-1'{
+		local list "`list' `=`nbscore'-1'"
+		}
+		if wordcount("`list'")==1{
+			noi di in red "Problem with Autogroup option: creating groups from the score quartiles is not possible"
+		}
+		tab score, matcell(`freq') matrow(`val')
+		local nbgroup=wordcount("`list'")
+	}
+	else{
+		tab score, matcell(`freq') matrow(`val')
+		local list "`group'"
+		local nbgroup=wordcount("`list'")
+		if real(word("`list'",`nbgroup'))<`=`nbscore'-1'{
+			local list "`group' `=`nbscore'-1'"
+			local nbgroup=wordcount("`list'")
+		}
+	}
+	local nbmodagpe=0
+	forvalues i=1/`nbit'{
+		local nbmodagpe=`nbmodagpe'+`nbmoda_`i''
+	}
+	gen g=.
+	local liminf1=-1
+	forvalues i=1/`nbgroup'{
+		local limsup`i'=real("`=word("`list'",`i')'")
+		if `i'>1{
+			local liminf`i'=real("`=word("`list'",`=`i'-1')'")
+		}
+		replace g=`i' if score<=`limsup`i'' & score>`liminf`i''
+	} 
+	forvalues i=1/`nbgroup'{
+		su score if g==`i'
+		local N`i'=r(N)
+	}
+	save `bdd_se', replace
+	save `bdd_seg', replace
+	use `bdd_se', replace
+	local count=0
+	forvalues i=1/`nbit'{
+		forvalues j=1/`nbmoda_`i''{
+			if `j'==1{
+				local diffest`i'_`j'=0
+			}
+			else{
+				local count=`count'+1
+				local diffest`i'_`j'=round(`Edelta'[1,`count'],0.001)+`diffest`i'_`=`j'-1''
+			}
+			local num`i'_`j' "exp(`=`j'-1'*x-`diffest`i'_`j'')"
+			if `j'==1{
+				local denom`i' "1"
+			}
+			else{
+				local denom`i' "`denom`i''+`num`i'_`j''"
+			}
+		}
+		forvalues j=1/`nbmoda_`i''{
+			local PCM`i'_`j' "(`num`i'_`j'')/(`denom`i'')"
+		}
+	}
+	local nbcomb=1
+	forvalues i=1/`nbit'{
+		local nbcomb=`nbcomb'*`nbmoda_`i''
+	}
+	clear
+	set obs `=int(`nbcomb'+0.1)'
+	local facteur=1
+	gen score=0
+	local order "score"
+	forvalues i=1/`nbit'{
+		gen it`i'=floor(mod(_n/`facteur',`nbmoda_`i''))
+		local facteur=`facteur'*`nbmoda_`i''
+		replace score=score+it`i'
+		tab it`i', gen(i`i'c)
+		local order "`order' it`i'"
+	}
+	order `order', first
+	sort score
+	tab score, gen(score)
+	local nbscore=r(r)
+	gen P=1
+	local gdN=_N
+
+ /*************************************/
+/*                                   */
+/*    Calcul de la probabilité de    */
+/*      chaque patern de réponses    */
+/*                                   */    
+/*************************************/
+
+	if "`approximation'"==""{
+		local percentcount=0
+		noi di ""
+		noi di in ye "`gdN'" in gr " response pattern probabilities to compute"
+		noi di in gr "Percentage of completion"
+		noi di in gr "----|---10%---|---20%---|---30%---|---40%---|---50%"
+		_dots 0, title(Loop computation of theorical probabilities of each response pattern) reps(100)
+		forvalues l=1/`gdN'{
+			local exp ""
+			forvalues i=1/`nbit'{
+				forvalues m=1/`nbmoda_`i''{
+					if i`i'c`m'[`l']==1{
+						if "`exp'"==""{
+							local exp "`PCM`i'_`m''"
+						}
+						else{
+							local exp "`exp'*`PCM`i'_`m''"
+						}
+					}
+				}
+			}
+			gausshermite `exp' , sigma(`sdgauss') mu(`mugauss') display
+			replace P=round(r(int),0.000001) if _n==`l'
+			local percentcountplus=floor(`l'*100/`gdN')
+			forvalues percen=`=`percentcount'+1'/`percentcountplus'{
+				nois _dots `percen' 0
+			}
+			local percentcount=`percentcountplus'
+		}
+	}
+	else{
+		noi di in gr "Response pattern probabilities computation"
+		replace P=0
+		sort score it*
+		save `bdd_P', replace
+		local NbCol=1
+		local compteur=1
+		forvalues i=1/`nbit'{
+			tempname Dit`i'
+			matrix `Dit`i''=`Edelta'[1,`compteur'..`=`compteur'+`nbmoda_`i''-2']
+			if colsof(`Dit`i'')>`NbCol'{
+				local NbCol=colsof(`Dit`i'')
+			}
+			local compteur=`compteur'+`nbmoda_`i''-1
+		}
+		clear
+		noi di in gr "----|---25%---|---50%---|---75%---|---100%
+		qui _dots 0, title(Title) reps(40)
+		set obs 1000000
+		gen id=_n
+		gen theta=`mugauss'+invnormal(uniform())*`sdgauss'
+		forvalues i=1/`nbit'{
+			gen denom`i'=1
+			gen num`i'_0=1
+			forvalues j=1/`=`nbmoda_`i''-1'{
+				gen num`i'_`j'=exp(ln(num`i'_`=`j'-1') + theta-`Dit`i''[1,`j'])
+				replace denom`i'=denom`i'+num`i'_`j'
+			}
+			forvalues j=0/`=`nbmoda_`i''-1'{
+				gen p`i'_`j'=num`i'_`j'/denom`i'
+			}
+			drop denom`i'
+			drop num`i'_*
+			forvalues j=1/`=`nbmoda_`i''-1'{
+				replace p`i'_`j'=p`i'_`j'+p`i'_`=`j'-1'
+			}
+			gen it`i'=0
+			gen random`i'=runiform()
+			forvalues j=1/`=`nbmoda_`i''-1'{
+				replace it`i'=`j' if random`i'>=p`i'_`=`j'-1' & random`i'`limsup`i'' | `j'<=`liminf`i''{
+				local nbscoreg`i'=`nbscoreg`i''-1
+				capture drop s`=`j'+1'g`i'
+			}
+		}
+		local order "`order' *g`i'"
+		use `matU1', replace
+		keep if score<=`limsup`i'' & score>`liminf`i''
+		gen g=`i'
+		forvalues a=1/`nbit'{
+			forvalues b=1/`nbmoda_`a''{
+				capture rename i`a'c`b' i`a'c`b'g`i'
+			}
+		}
+		forvalues a=1/`nbscore'{
+			capture rename score`a' s`a'g`i'
+			forvalues j=1/`=wordcount("`list'")'{
+				if `=`a'-1'>`limsup`i'' | `=`a'-1' <= `liminf`i''{
+					capture drop s`a'g`j'
+				}
+			}
+		}
+		tempfile bloc`i'
+		sort `sort'
+		save `b`i'_1', replace
+	}
+	local order ""
+	forvalues i=1/`=wordcount("`list'")'{
+		tempfile b`i'_2
+		local order "`order' *g`i'"
+		use `matU2', replace
+		keep if score<=`limsup`i'' & score>`liminf`i''
+		gen g=`i'
+		forvalues a=1/`nbit'{
+			forvalues b=1/`nbmoda_`a''{
+				capture rename i`a'c`b' i`a'c`b'g`i'b
+			}
+		}
+		forvalues a=1/`nbscore'{
+			capture rename score`a' s`a'g`i'b
+			forvalues j=1/`=wordcount("`list'")'{
+
+				if `=`a'-1'>`limsup`i'' | `=`a'-1' <= `liminf`i''{
+					capture drop s`a'g`j'
+				}
+			}
+		}
+		sort `sort'
+		save `b`i'_2', replace
+		describe
+		local mat_`i'=r(k)-3-`nbit'
+	}
+noi di "W matrix computation"
+/* Matrice W */
+	local nbscoreg0=0
+	forvalues g=1/`nbgroup'{
+		tempname W_`g'i W_`g'
+		tempfile b`g'_2b
+		qui q memory
+		if `mat_`g''>r(matsize) & `mat_`g''<=r(m_matsize){
+			set matsize `mat_`g''
+		}
+		if `mat_`g''>r(m_matsize){
+			noi di in red "Error, not enough memory to allocate to the W matrix computation"
+		}
+		matrix `W_`g''=J(`mat_`g'',`mat_`g'',.)
+		use `b`g'_2', replace
+		local count=1
+		forvalues i=1/`nbit'{
+			forvalues j=1/`nbmoda_`i''{
+				rename i`i'c`j'g`g'b v`count'b
+				local count=`count'+1
+			}
+		}
+		forvalues s=1/`=`nbscore'+1'{
+			capture rename s`s'g`g'b v`count'b
+			if _rc ==0{
+				local count=`count'+1
+			}
+		}
+		local Ncol_`g'_=`count'-1
+		save `b`g'_2b', replace
+		use `b`g'_1', replace
+		local count=1
+		forvalues i=1/`nbit'{
+			forvalues j=1/`nbmoda_`i''{
+				rename i`i'c`j'g`g' v`count'
+				local count=`count'+1
+			}
+		}
+		forvalues s=1/`=`nbscore'+1'{
+			capture rename s`s'g`g' v`count'
+			if _rc ==0{
+				local count=`count'+1
+			}
+		}
+		local Ncol_`g'__=`count'-1
+		forvalues i=1/`=`count'-1'{
+			replace v`i'=P if round(v`i',0.000001)!=round(0,0.000001)
+		}
+		local countW_`g'=`count'-1
+		merge `sort' using `b`g'_2b'
+		drop _merge
+		forvalues i=1/`mat_`g''{
+			forvalues j=1/`mat_`g''{
+				gen prod=v`i'*v`j'b
+				qui su prod
+				matrix `W_`g''[`i',`j']=r(sum)
+				drop prod
+			}
+		}
+		capture matrix `W_`g'i'=invsym(`W_`g'')
+		if _rc!=0{
+			capture matrix `W_`g'i'=inv(`W_`g'')
+		}
+		if _rc!=0{
+			noi di in red "Error while computing the Wg matrix"
+		}
+		tempname A rank_
+		mata: `A'=J(1,1,.)
+		mata: `A'[1,1]=rank(st_matrix("`W_`g''"))
+		mata: st_matrix("`rank_'",`A')
+		local rank`g'=`rank_'[1,1]
+	}
+/* Matrice poid */
+	forvalues g=1/`nbgroup'{
+		tempfile bddSe`g' b`g'_2bi
+		use `bdd_seg', replace
+		keep if g==`g'
+		gen Pd=1
+		contract `sort', f(nb)
+		sort `sort'
+		save `bddSe`g'', replace
+		use `b`g'_2b', replace
+		sort `sort'
+		merge `sort' using `bddSe`g''
+		drop _merge
+		replace nb=0 if nb==.
+		gen nbth=P*`N'
+		gen Di=(nb-nbth)/sqrt(`N')
+		sort `sort'
+		save `b`g'_2bi', replace
+		if `countW_`g''>10{
+			set matsize `countW_`g''
+		}
+		else{
+			set matsize 10
+		}
+		tempname deviation_`g'
+		matrix `deviation_`g''=J(`countW_`g'',1,.)
+		use `b`g'_2bi', replace
+		gen Pobs=nb/`N'
+		gen Diff=Pobs-P
+		forvalues j=1/`countW_`g''{
+			replace v`j'b=v`j'b*Diff
+			su v`j'b
+			matrix `deviation_`g''[`j', 1]=r(sum)*sqrt(`N')
+		}
+	}
+	local sum=0
+	local ddl=0
+	local rank ""
+	qui q memory
+	if `matsizeini'>r(matsize) & 10000 > r(m_matsize){
+		set matsize `matsizeini'
+	}
+	else{
+		set matsize 10000
+	}
+	tempname graphContribPond
+	matrix `graphContribPond'=J(`nbgroup',2,.)
+	forvalues g=1/`nbgroup'{
+		tempname G_`g'
+		capture matrix `G_`g''=`deviation_`g'''*`W_`g'i'*`deviation_`g''
+		if _rc!=0{
+			noi di in red "Error, not enought memory to allocate to the W matrix computation
+		}
+		local sum=`sum'+`G_`g''[1,1]
+		local ddl=`ddl'+`rank`g''
+		local rank "`rank'`rank`g''  "
+		matrix `graphContribPond'[`g',1]=`g'
+		matrix `graphContribPond'[`g',2]=`G_`g''[1,1]
+	}
+	local ddl=`ddl'-`ordre'-1
+	set matsize `matsizeini'
+}
+local R1m_group "`list'"
+local R1m_Rank `rank'
+local R1M_ddl=`ddl'
+local R1M_stat=`sum'*`propFit'
+local R1M_p=`=1-chi2(`ddl', `R1M_stat')'
+
+/*************************************/
+/*			  tests Si			 */
+/*************************************/
+if `nbitsuf'==1 & "`sitest'"!=""{
+	qui{
+		local countbase=0
+		forvalues ii=1/`nbit'{
+			forvalues j=1/`nbmoda_`ii''{
+				local countbase=`countbase'+1
+			}
+		}
+		forvalues s=1/`nbscore'{
+			local countbase=`countbase'+1
+		}
+		tempname DGibase
+		matrix `DGibase'=J(6,`countbase',.)
+		use `bdd_seg', replace
+		local countbase=0
+		forvalues ii=1/`nbit'{
+			tab it`ii', gen(i`ii'c)
+			forvalues j=1/`nbmoda_`ii''{
+				local countbase=`countbase'+1
+				matrix `DGibase'[2,`countbase']=`ii'
+				matrix `DGibase'[3,`countbase']=`j'
+				su i`ii'c`j'
+				matrix `DGibase'[4,`countbase']=r(sum)
+			}
+			drop i`ii'c*
+		}
+		tab score, gen(s)
+		forvalues s=1/`nbscore'{
+			capture su s`s'
+			if _rc!=0{
+				gen s`s'=0
+			}
+		}
+		forvalues s=1/`nbscore'{
+			local countbase=`countbase'+1
+			matrix `DGibase'[2,`countbase']=`s'
+			su s`s'
+			matrix `DGibase'[4,`countbase']=r(sum)
+		}
+		use `matU2', replace
+		local countbase=0
+		forvalues ii=1/`nbit'{
+			forvalues j=1/`nbmoda_`ii''{
+				local countbase=`countbase'+1
+				su P if i`ii'c`j'==1
+				matrix `DGibase'[5,`countbase']=r(sum)*`N'
+				matrix `DGibase'[6,`countbase']=(`DGibase'[4,`countbase']-`DGibase'[5,`countbase'])/sqrt(`N')
+			}
+		}
+		forvalues s=1/`nbscore'{
+			local countbase=`countbase'+1
+				su P if score`s'==1
+				matrix `DGibase'[5,`countbase']=r(sum)*`N'
+				matrix `DGibase'[6,`countbase']=(`DGibase'[4,`countbase']-`DGibase'[5,`countbase'])/sqrt(`N')
+		}
+		local colbase=`countbase'
+	}
+	forvalues i=1/`nbit'{
+		tempfile mU2_`i' mU_`i'
+		noi di in gr "Performing Si test for the `i'th item"
+		qui{
+			use `matU2', replace
+			gen g=.
+			local liminf1=-1
+			forvalues g=1/`nbgroup'{
+				replace g=`g' if score<=`limsup`g'' & score>`liminf`g''
+			}
+			forvalues g=1/`nbgroup'{
+				forvalues j=1/`nbmoda_`i''{
+					gen testi`i'c`j'g`g'=0
+					replace testi`i'c`j'g`g'=i`i'c`j' if g==`g'
+				}
+			}
+			local count=1
+			forvalues ii=1/`nbit'{
+				forvalues j=1/`nbmoda_`ii''{
+					rename i`ii'c`j' v`count'b
+					local count=`count'+1
+				}
+			}
+			forvalues s=1/`=`nbscore'+1'{
+				capture rename score`s' v`count'b
+				if _rc ==0{
+					local count=`count'+1
+				}
+			}
+			forvalues g=1/`nbgroup'{
+				forvalues j=1/`nbmoda_`i''{
+					rename testi`i'c`j'g`g' v`count'b
+					local count=`count'+1
+				}
+			}
+			local nbarrive`i'=`count'-1
+			sort `sort'
+			save `mU2_`i'', replace
+			use `matU1', replace
+			gen g=.
+			local liminf1=-1
+			forvalues g=1/`nbgroup'{
+				replace g=`g' if score<=`limsup`g'' & score>`liminf`g''
+			}
+			forvalues g=1/`nbgroup'{
+				forvalues j=1/`nbmoda_`i''{
+					gen testi`i'c`j'g`g'=0
+					replace testi`i'c`j'g`g'=i`i'c`j' if g==`g'
+				}
+			}
+			local count=1
+			forvalues ii=1/`nbit'{
+				forvalues j=1/`nbmoda_`ii''{
+					rename i`ii'c`j' v`count'
+					local count=`count'+1
+				}
+			}
+			forvalues s=1/`=`nbscore'+1'{
+				capture rename score`s' v`count'
+				if _rc ==0{
+					local count=`count'+1
+				}
+			}
+			forvalues g=1/`nbgroup'{
+				forvalues j=1/`nbmoda_`i''{
+					rename testi`i'c`j'g`g' v`count'
+					local count=`count'+1
+				}
+			}
+			sort `sort'
+			merge `sort' using `mU2_`i''
+			drop _merge
+			if `nbarrive`i''>r(matsize) & `nbarrive`i''<=r(m_matsize){
+				set matsize `nbarrive`i''
+			}
+			if `nbarrive`i''>r(m_matsize){
+				noi di in red "Error, not enought memory to allocate to the W matrix computation"
+			}
+			tempname i`i'W
+			matrix `i`i'W'=J(`nbarrive`i'',`nbarrive`i'',0)
+			if `=`nbarrive`i''*`nbarrive`i'''>3000{
+				noi di in gr "----|---25%---|---50%---|---75%---|---100%
+				qui _dots 0, title(Loop computation of theorical probabilities of each response pattern) reps(40)
+				local percentcount=0
+				local countS=1
+			}
+			forvalues ii=1/`nbarrive`i''{
+				su v`ii'
+				if r(max)>=0.000001{
+				forvalues j=1/`nbarrive`i''{
+					gen prod=v`ii'*v`j'b
+					qui su prod
+					matrix `i`i'W'[`ii',`j']=r(sum)
+					drop prod
+					if `=`nbarrive`i''*`nbarrive`i'''>3000{
+						local percentcountplus=floor(`countS'*40/`=`nbarrive`i''*`nbarrive`i''')
+						forvalues percen=`=`percentcount'+1'/`percentcountplus'{
+							nois _dots `percen' 0
+						}
+						local percentcount=`percentcountplus'
+						local countS=`countS'+1
+					}
+				}
+				}
+				else{
+					if `=`nbarrive`i''*`nbarrive`i'''>3000{
+						local percentcountplus=floor((`countS'+`nbarrive`i''-1)*40/`=`nbarrive`i''*`nbarrive`i''')
+						forvalues percen=`=`percentcount'+1'/`percentcountplus'{
+							nois _dots `percen' 0
+						}
+						local percentcount=`percentcountplus'
+						local countS=`countS'+`nbarrive`i''
+					}
+				}
+			}
+			if `=`nbarrive`i''*`nbarrive`i'''>3000{
+				noi di ""
+			}
+			tempname i`i'Wi
+			capture matrix `i`i'Wi'=invsym(`i`i'W')
+			if _rc!=0{
+				capture matrix `i`i'Wi'=inv(`i`i'W')
+			}
+			if _rc!=0{
+				noi di in red "Error while computing the Wg matrix"
+			}
+			tempname A rank_
+			mata: `A'=J(1,1,.)
+			mata: `A'[1,1]=rank(st_matrix("`i`i'W'"))
+			mata: st_matrix("`rank_'",`A')
+			local i`i'rank=`rank_'[1,1]
+			tempname plus`i' DGi_`i' DGi`i'_a DGi`i'_b DGi_`i'_v2
+			matrix `plus`i''=J(6,`=`nbarrive`i''-`colbase'',.)
+			matrix `DGi_`i''=`DGibase',`plus`i''
+			matrix `DGi`i'_a'=J(1,`=colsof(`DGibase')',0)
+			matrix `DGi`i'_b'=J(1,`=`nbarrive`i''-`colbase'',.)
+			matrix `DGi_`i'_v2'=`DGi`i'_a',`DGi`i'_b'
+			save `mU_`i'', replace
+			local count=`colbase'
+			use `bdd_seg', replace
+			tab it`i', gen(i`i'c)
+			forvalues g=1/`nbgroup'{
+				forvalues j=1/`nbmoda_`i''{
+					local count=`count'+1
+					matrix `DGi_`i''[2,`count']=`i'
+					matrix `DGi_`i''[3,`count']=`j'
+					matrix `DGi_`i''[1,`count']=`g'
+					su i`i'c`j' if g==`g'
+					matrix `DGi_`i''[4,`count']=r(sum)
+				}
+			}
+			use `mU_`i'', replace
+			forvalues t=`=`colbase'+1'/`nbarrive`i''{
+				su P if v`t'b==1
+				matrix `DGi_`i''[5,`t']=r(sum)*`N'
+				matrix `DGi_`i''[6,`t']=(`DGi_`i''[4,`t']-`DGi_`i''[5,`t'])/sqrt(`N')
+				matrix `DGi_`i'_v2'[1,`t']=(`DGi_`i''[4,`t']-`DGi_`i''[5,`t'])/sqrt(`N')
+			}
+			set matsize `matsizeini'
+			tempname tDGi_`i' tDGi_`i'_v2 G G_v2
+			matrix `tDGi_`i''=`DGi_`i''[6,1..`=colsof(`DGi_`i'')']'
+			matrix `tDGi_`i'_v2'=`DGi_`i'_v2''
+			matrix `G'=`tDGi_`i'''*`i`i'Wi'*`tDGi_`i''
+			matrix `G_v2'=`tDGi_`i'_v2''*`i`i'Wi'*`tDGi_`i'_v2'
+			local sum=`G'[1,1]
+			local sum_v2=`G_v2'[1,1]
+			local rank "`i`i'rank'"
+			local ddl=(`nbgroup'-1)*(`nbmoda_`i''-1)
+		}
+		local S`i'_rank=`rank'
+		local S`i'_ddl=`ddl'
+		local S`i'_stat=`sum'*`propFit'
+		local S`i'_p=`=1-chi2(`S`i'_ddl', `S`i'_stat')'
+	}
+}
+
+/* Graphs : */
+
+if "`graphics'"!=""{
+	noi di ""
+	noi di ""
+	noi di in gr "Graphics:"
+	tempfile graph	
+	qui{
+		local debut=1
+		local fin=1
+		forvalues i=1/`nbit'{
+			local fin=`fin'+`nbmoda_`i''-2
+			tempname it`i'
+			matrix `it`i''=`Edelta'[1,`debut'..`fin']
+			local fin=`fin'+1
+			local debut=`debut'+`nbmoda_`i''-1
+		}
+		clear
+		use `bdd_se', replace
+		local scmin=1
+		local scmax=-1
+		forvalues i=1/`nbit'{
+			local scmax=`scmax'+`nbmoda_`i''-1
+		}		
+		gen select=score<=`scmin'
+		su score if select==1
+		local scorereel_scmin=r(mean)
+		replace select=score>=`scmax'
+		su score if select==1
+		local scorereel_scmax=r(mean)
+		replace score=`scmin' if score<`scmin'
+		replace score=`scmax' if score>`scmax'
+		tab score, matcell(matname)  
+		local tottab=r(N)
+		clear
+		set obs 2000
+		gen theta=_n/100-10
+		gen scoreth=0
+		forvalues i=1/`nbit'{
+			tempname D`i'
+			matrix `D`i''=J(1,`nbmoda_`i'',0)
+			gen eV`i'_0=1
+			gen SeV`i'=1
+			forvalues j=1/`=`nbmoda_`i''-1'{
+				matrix `D`i''[1,`=`j'+1']=`it`i''[1,`j']+`D`i''[1,`j']
+				gen eV`i'_`j'=exp(`j'*theta-`D`i''[1,`=`j'+1'])
+				replace SeV`i'=SeV`i'+eV`i'_`j'
+			}
+			gen p`i'_0=eV`i'_0/SeV`i'
+			forvalues j=1/`=`nbmoda_`i''-1'{
+				gen p`i'_`j'=eV`i'_`j'/SeV`i'
+				replace scoreth=scoreth+(eV`i'_`j'/SeV`i')*`j'
+			}
+		}
+		drop e* S* p*
+		su scoreth
+		local scmin=ceil(r(min))
+		local scmax=floor(r(max))
+		gen sc=abs(scoreth-`scorereel_scmin')
+		sort sc
+		local valini_`scmin'=theta[1]
+		drop sc
+		gen sc=abs(scoreth-`scorereel_scmax')
+		sort sc
+		local valini_`scmax'=theta[1]
+		drop sc
+		tempname scoretheta
+		matrix `scoretheta'=J(2,`scmax',.)
+		forvalues i=`=`scmin'+1'/`=`scmax'-1'{
+			matrix `scoretheta'[1,`i']=`i'
+			gen sc=abs(scoreth-`i')
+			sort sc
+			local valini_`i'=theta[1]
+			drop sc
+		}
+		matrix `scoretheta'[1,1]=`scorereel_scmin'
+		matrix `scoretheta'[1,`scmax']=`scorereel_scmax'
+		forvalues i=1/`scmax'{
+			matrix `scoretheta'[2,`i']=`valini_`i''
+		}
+		tempfile graphscthscobstheta
+		save `graphscthscobstheta', replace
+		clear
+		use `bdd_se', replace
+		gen select=score<=`scmin'
+		su score if select==1
+		local scorereel_scmin=r(mean)
+		replace select=score>=`scmax'
+		su score if select==1
+		local scorereel_scmax=r(mean)
+		replace score=`scmin' if score<`scmin'
+		replace score=`scmax' if score>`scmax'
+		drop g
+		forvalues i=1/`nbit'{
+			gen rep`i' = it`i'
+			drop it`i'
+		}
+		contract rep1-rep`nbit' score, f(wt2)
+		gen id=_n
+		reshape long rep, i(id) j(it)
+		drop if rep==.
+		gen obs=_n
+		forvalues i=1/`nbit'{
+			expand `nbmoda_`i'' if it==`i'
+		}
+		by obs, sort: gen `x'=_n-1
+		gen choix=rep==`x'
+		rename it item
+		tab item, gen(it)
+		forvalues i=1/`nbit'{
+			forvalues g=1/`=`nbmoda_`i''-1'{
+				gen d_i`i'_m`g'=(-1)*it`i'*(`x'>=`g')
+			}
+		}
+		gen difficulties=0
+		forvalues i=1/`nbit'{
+			forvalues g=1/`=`nbmoda_`i''-1'{
+				replace difficulties=difficulties+`it`i''[1,`g']*d_i`i'_m`g'
+			}
+		}
+		tab score, gen(score__) matrow(nom)
+		local nbmodscore=r(r)
+		forvalues k=1/`nbmodscore'{
+			replace score__`k'=`x' if score__`k'==1
+			local ident=nom[`k',1]
+			if `k'==1{
+				local ident1=`ident'
+			}
+			rename score__`k' score_`ident'
+		}
+		eq slope: `x'
+		noi di in gr "Performing graphics"
+		use `graphscthscobstheta', replace
+		gen sc=abs(scoreth-`scorereel_scmin')
+		sort sc
+		local limginf=theta[1]-1.5
+		drop sc
+		gen sc=abs(scoreth-`scorereel_scmax')
+		sort sc
+		local limgsup=theta[1]+1.5
+		drop sc
+		drop if theta<`limginf' | theta>`limgsup'
+		capture graph drop Obs_vs_Exp_LT 
+		capture graph drop MAP 
+		capture graph drop Score_Distrib 
+		capture graph drop Contrib
+		twoway (line scoreth theta, sort) , ytitle(Score) xtitle(Latent trait) title("Expected scores depending on individual latent traits", size(medium))  scheme(s2mono) graphregion(fcolor(white) ifcolor(white))  name("LT_Sc", replace)
+		tempfile gEO
+		graph save `gEO', replace
+		if "`filegraph'"!=""{
+			graph save "`filegraph'_LT_Sc", replace
+		}
+		clear
+		set obs `=int(`=rowsof(matname)+colsof(`Edelta')'+0.1)'
+		gen theta=.
+		gen diff=0
+		gen freq=.
+		forvalues i=1/`=rowsof(matname)'{
+			replace theta=`scoretheta'[2,`i'] if _n==`i'
+			replace freq=matname[`i',1]/`tottab' if _n==`i'
+		}	
+		su freq
+		local tadatzouinzou=-r(max)/8
+		forvalues i=1/`=colsof(`Edelta')'{
+			replace theta=`Edelta'[1,`i'] if _n==`i'+`=rowsof(matname)'
+			replace freq=`tadatzouinzou' if _n==`i'+`=rowsof(matname)'
+			replace diff=1 if _n==`i'+`=rowsof(matname)'
+		}
+		sort diff theta
+		bysort diff: replace freq=freq-(`tadatzouinzou'/5) if theta1
+		gen d2=.
+		replace d2=(d1-d1[_n-1])/(theta-theta[_n-1]) if _n>1
+		replace d2=-d2
+		su freq
+		local freqmin=r(min)
+		local freqmax=r(max)
+		su d2
+		local d2max=r(max)
+		local d2min=`d2max'*`freqmax'/`freqmin'
+		label variable freq "Freq. (%)"
+		label variable d2 "Information"
+		sort theta
+		twoway (spike freq theta if diff==0, lwidth(thick) horizontal xscale(alt  axis(1)) ) (scatter theta freq if diff==1,mcolor(black) msymbol(plus)) (line theta d2, xaxis(2) xscale(alt axis(2))) , yscale(noline) ylabel(#5, angle(horizontal)) xscale(range(`freqmin' `freqmax') axis(1)) xscale(reverse range(`d2min' `d2max') axis(2))  yscale(range(`mininf' `maxinf'))  xline(0) xlabel(0 (0.05) `freqmax') title(, size(medium)) legend(order(1 "Persons" 2 "Thresholds location" 3 "Information curve") cols(1) size(small)) scheme(s2mono) graphregion(fcolor(white) ifcolor(white)) ytitle(Latent trait) title(MAP) name("MAP", replace)		
+		tempfile gMAP
+		graph save `gMAP', replace	
+		if "`filegraph'"!=""{
+			graph save "`filegraph'_MAP", replace
+		}
+		clear
+		use "`dataR1m'"
+		keep score P
+		collapse (sum) P, by(score)
+		sort score
+		save `bdd_G', replace
+		clear
+		use "`datatest'"
+		keep `varlist'
+		tempname dm SumScore
+		egen `dm'=rowmiss(`varlist')
+		replace `dm'=`dm'>0
+		keep if `dm'==0
+		tempname SumScore
+		egen `SumScore'=rowtotal(`varlist')
+		gen Pobs=1
+		rename `SumScore' score
+		keep Pobs score
+		local tot=_N
+		collapse (sum) Pobs, by(score)
+		replace Pobs=Pobs/`tot'
+		sort score
+		merge 1:1 score using `bdd_G'
+		gen g=.
+		drop _merge
+		sort g 
+		save `bdd_G', replace
+		clear
+		svmat `graphContribPond'
+		rename `graphContribPond'1 g
+		rename `graphContribPond'2 Contrib
+		sort g
+		merge g using `bdd_G'
+		su Contrib
+		replace Contrib=Contrib/r(sum)
+		capture label drop g
+		local liminf1=-1
+		forvalues i=1/`nbgroup'{
+			local limsup`i'=real("`=word("`list'",`i')'")
+			if `i'>1{
+				local liminf`i'=real("`=word("`list'",`=`i'-1')'")
+			}
+			replace g=`i' if score<=`limsup`i'' & score>`liminf`i''
+			if `i'==1{
+				label define g `i' "[0;`limsup`i'']"
+			}
+			else if `i' == `nbgroup'{
+				label define g `i' "]`liminf`i'';`=`nbscore'-1']", a
+			}
+			else{
+				label define g `i' "]`liminf`i'';`limsup`i'']", a
+			}
+		} 
+		label values g g
+		gen nb=P*`EN'
+		 su score [iweight=nb]
+		local MoyThScore=r(mean)
+		local SdThScore=r(sd)
+		gen nbObs=Pobs*`EN'
+		 su score [iweight=nbObs]
+		local MoyObsScore=r(mean)
+		local SdObdcore=r(sd)
+		drop _merge
+		tempfile BDD
+		sort score
+		save `BDD', replace
+		clear
+		set obs `=(`=r(max)'+2)*100'
+		gen score=(_n/100)-1
+		gen p=normalden(score,`MoyThScore',`SdThScore')
+		gen pobs=normalden(score,`MoyObsScore',`SdObdcore')
+		sort score
+		merge score using `BDD'
+		gen score1=score if Pobs!=.
+		gen scorep=score1-0.15
+		gen scorep2=score1+0.15
+		twoway (bar  Pobs scorep, horizontal  barwidth(0.3)) (bar  P scorep2, horizontal barwidth(0.3)) (line score p, lpattern(solid)lcolor(black)) (line 			score pobs, lpattern(vshortdash) lcolor(gs12)), yscale(reverse) scheme(s2mono) xtitle(%) xscale(range(0 0.01)) xlabel(#5) legend(order(1 "% observed" 3 "" 2 "% expected" 4 "") cols(2) size(small)) title("Observed and expected" "scores distribution", size(medium)) graphregion(fcolor(white)) name("Score_Distrib", replace)
+		tempfile gTS
+		graph save `gTS', replace
+		if "`filegraph'"!=""{
+			graph save "`filegraph'_totscore", replace
+		}
+		graph hbar (sum) Pobs P Contrib, over(g)  yvaroptions(relabel(1 "% observed" 2 "% expected" 3 "% R1m contribution") label(labcolor(none) labsize(zero)))  title("Groups contribution to" "the R1m statistic", size(medium)) legend(cols(1) size(small)) ytitle("%") scheme(s2mono) graphregion(fcolor(white)) bar(3, fcolor(black)) bar(1, fcolor(gs8)) bar(2, fcolor(gs13)) name("Contrib", replace)
+		tempfile gSG
+		graph save `gSG', replace
+		if "`filegraph'"!=""{
+			graph save "`filegraph'_scoregp", replace
+		}
+	}
+}
+tempname globalFit itemFit
+matrix `globalFit'=(`R1M_stat',`R1M_ddl',`R1M_p')
+if `nbitsuf'==1 & "`sitest'"!=""{
+	matrix itemFit=J(`nbit',3,.)
+	forvalues i=1/`nbit'{
+		matrix itemFit[`i',1]=`S`i'_stat'
+		matrix itemFit[`i',2]=`S`i'_ddl'
+		matrix itemFit[`i',3]=`S`i'_p'
+	}
+}
+if "`alpha'"==""{
+	local alpha=0.05
+}
+tempname  g it r Power bB cC Discriminant
+matrix `g'=`globalFit'
+if `nbitsuf'==1 & "`sitest'"!=""{
+	matrix `it'=itemFit
+}
+if "`nfit'"==""{
+	local `r'=1
+}
+else{
+	local `r'=`NbIdFit'/`nfit'
+}
+local `g'_t=`g'[1,1]*``r''
+if `g'[1,2]<=200{
+	local `Power'_t_R1m= 1-nchi2(`g'[1,2],``g'_t',invchi2tail(`g'[1,2],`alpha'))
+}
+else{
+	local `Power'_t_R1m=1-(normal((invchi2tail(`g'[1,2],`alpha')-(`g'[1,2]+``g'_t'))/sqrt(2*(`g'[1,2]+2*``g'_t'))))
+}
+if `nbitsuf'==1 & "`sitest'"!=""{
+	forvalues i=1/`nbit'{
+		local `it'_`i'_t=`it'[`i',1]*``r''
+		if `it'[`i',2]>200 | ``it'_`i'_t'>1000{
+			local `Power'_t_S`i'=1-(normal((invchi2tail(`it'[`i',2],`alpha')-(`it'[`i',2]+``it'_`i'_t'))/sqrt(2*(`it'[`i',2]+2*``it'_`i'_t'))))
+		}
+		else{
+			local `Power'_t_S`i'= 1-nchi2(`it'[`i',2],``it'_`i'_t',invchi2tail(`it'[`i',2],`alpha'))
+		}
+	}
+}
+if "`nfit'"!=""{
+	local `r'_2=``r''*`nfit'/`NbIdFit'
+	local `g'_newN=`g'[1,1]*``r'_2'
+	if `g'[1,2]<=200{
+		local `Power'_newN_R1m= 1-nchi2(`g'[1,2],``g'_newN',invchi2tail(`g'[1,2],`alpha'))
+	}
+	else{
+		local `Power'_newN_R1m=1-(normal((invchi2tail(`g'[1,2],`alpha')-(`g'[1,2]+``g'_newN'))/sqrt(2*(`g'[1,2]+2*``g'_newN'))))
+	}
+	if `nbitsuf'==1 & "`sitest'"!=""{
+		forvalues i=1/`nbit'{
+			local `it'_`i'_newN=`it'[`i',1]*``r'_2'
+			if `it'[`i',2]>200 | ``it'_`i'_newN'>1000{
+				local `Power'_newN_S`i'=1-(normal((invchi2tail(`it'[`i',2],`alpha')-(`it'[`i',2]+``it'_`i'_newN'))/sqrt(2*(`it'[`i',2]+2*``it'_`i'_newN'))))
+			}
+			else{
+				local `Power'_newN_S`i'= 1-nchi2(`it'[`i',2],``it'_`i'_newN',invchi2tail(`it'[`i',2],`alpha'))
+			}
+		}
+	}
+}
+if "`power'"!=""{
+	if `g'[1,2]<=200{
+		local `g'_newP=npnchi2(`=`g'[1,2]',`=invchi2tail(`=`g'[1,2]',`alpha')',`=1-`power'')
+	}
+	else{
+		local `bB'=2*`=`g'[1,2]'-2*`=invchi2tail(`=`g'[1,2]',`alpha')'-4*(invnormal(`=1-0.8'))^2
+		local `cC'=(`=invchi2tail(`=`g'[1,2]',`alpha')')^2-2*`=`g'[1,2]'*`=invchi2tail(`=`g'[1,2]',`alpha')'+(`=`g'[1,2]')^2-2*`=`g'[1,2]'*(invnormal(`=1-0.8'))^2
+		local `Discriminant'=(``bB'')^2-4*``cC''
+		local `g'_newP=(sqrt(``Discriminant'')-``bB'')/2
+	}
+	local `r'_3=``g'_newP'/``g'_t'
+	if `nbitsuf'==1 & "`sitest'"!=""{
+		forvalues i=1/`nbit'{
+			local `it'_`i'_newP=``it'_`i'_t'*``r'_3'
+			if `it'[`i',2]>200 | ``it'_`i'_newP'>1000{
+				local `Power'_newP_S`i'=1-(normal((invchi2tail(`it'[`i',2],`alpha')-(`it'[`i',2]+``it'_`i'_newP'))/sqrt(2*(`it'[`i',2]+2*``it'_`i'_newP'))))
+			}
+			else{
+				local `Power'_newP_S`i'= 1-nchi2(`it'[`i',2],``it'_`i'_newP',invchi2tail(`it'[`i',2],`alpha'))
+			}
+		}
+	}
+}
+}
+
+  /*************************************/
+ /*               print               */
+/*************************************/
+
+di ""
+di ""
+di in gr "Global tests of the fit : test R1m"
+di in gr "			  groups : " in ye "`R1m_group'"
+di in gr "			  Number of individuals with missing data : " in ye "`nbmissing' "  in gr "(" in ye "`=round(`=`percentmissing'*100',0.01)'%" in gr ")"
+di ""
+if "`nfit'"!="" & "`power'"!=""{
+	di in gr "{hline 90}"
+	di  _col(30) in gr "N = " in ye %6.0f `NbIdFit' _col(53) in gr "N = " in ye %6.0f `nfit'  _col(76) in gr  "N = " in ye %6.0f `=ceil(`NbIdFit'*``r'_3')'
+	di _col(16) in gr "df" _col(26) in gr "R1m" _col(32) in gr "p-val" _col(39) in gr "Power" _col(49) in gr "R1m" _col(55) in gr "p-val" _col(62) in gr "Power" _col(72) in gr "R1m" _col(78) in gr "p-val" _col(85) in gr "Power"
+	di in gr "{hline 90}"
+	di _col(3) in gr "R1m" _col(14) in ye %4.0f `R1M_ddl' _col(23) in ye %6.1f ``g'_t' _col(32) in ye %5.4f `=1-chi2(`=`g'[1,2]', ``g'_t')'  _col(39) in ye %5.4f ``Power'_t_R1m'   _col(46) in ye %6.1f ``g'_newN' _col(55) in ye %5.4f `=1-chi2(`=`g'[1,2]', ``g'_newN')'  _col(62) in ye %5.4f ``Power'_newN_R1m'         _col(69) in ye %6.1f ``g'_newP' _col(78) in ye %5.4f `=1-chi2(`=`g'[1,2]', ``g'_newP')'  _col(85) in ye %5.4f `power'
+	di in gr "{hline 90}"
+	di in gr ""
+	if `nbitsuf'==1 & "`sitest'"!=""{
+		di in gr "Items specific tests of the fit : tests Si"
+		di in gr ""
+		di in gr "{hline 90}"
+		di  _col(30) in gr "N = " in ye %6.0f `NbIdFit' _col(53) in gr "N = " in ye %6.0f `nfit'  _col(76) in gr  "N = " in ye %6.0f `=ceil(`NbIdFit'*``r'_3')'
+		di _col(1) in gr "Item" _col(16) in gr "df" _col(27) in gr "Si" _col(32) in gr "p-val" _col(39) in gr "Power" _col(50) in gr "Si" _col(55) in gr "p-val" _col(62) in gr "Power" _col(73) in gr "Si" _col(78) in gr "p-val" _col(85) in gr "Power"
+		di in gr "{hline 90}"
+		forvalues i=1/`nbit'{
+			di _col(1) in gr "``i'' :" _col(14) in ye %4.0f `S`i'_ddl' _col(23) in ye %6.1f ``it'_`i'_t' _col(32) in ye %5.4f `=1-chi2(`=`it'[`i',2]', ``it'_`i'_t')'  _col(39) in ye %5.4f ``Power'_t_S`i''   _col(46) in ye %6.1f ``it'_`i'_newN' _col(55) in ye %5.4f `=1-chi2(`=`it'[`i',2]', ``it'_`i'_newN')'  _col(62) in ye %5.4f ``Power'_newN_S`i''         _col(69) in ye %6.1f ``it'_`i'_newP' _col(78) in ye %5.4f `=1-chi2(`=`it'[`i',2]', ``it'_`i'_newP')'  _col(85) in ye %5.4f ``Power'_newP_S`i''
+			di in gr "{hline 90}"
+		}
+	}
+}
+else if "`nfit'"!=""{
+	di in gr "{hline 67}"
+	di  _col(30) in gr "N = " in ye %6.0f `NbIdFit' _col(53) in gr "N = " in ye %6.0f `nfit'  
+	di _col(16) in gr "df" _col(26) in gr "R1m" _col(32) in gr "p-val" _col(39) in gr "Power" _col(49) in gr "R1m" _col(55) in gr "p-val" _col(62) in gr "Power" 
+	di in gr "{hline 67}"
+	di _col(3) in gr "R1m" _col(14) in ye %4.0f `R1M_ddl' _col(23) in ye %6.1f ``g'_t' _col(32) in ye %5.4f `=1-chi2(`=`g'[1,2]', ``g'_t')'  _col(39) in ye %5.4f ``Power'_t_R1m'   _col(46) in ye %6.1f ``g'_newN' _col(55) in ye %5.4f `=1-chi2(`=`g'[1,2]', ``g'_newN')'  _col(62) in ye %5.4f ``Power'_newN_R1m'
+	di in gr "{hline 67}"
+	di in gr ""
+	if `nbitsuf'==1 & "`sitest'"!=""{
+		di in gr "Items specific tests of the fit : tests Si"
+		di in gr ""
+		di in gr "{hline 67}"
+		di  _col(30) in gr "N = " in ye %6.0f `NbIdFit' _col(53) in gr "N = " in ye %6.0f `nfit'  
+		di _col(1) in gr "Item" _col(17) in gr "df" _col(26) in gr "Si" _col(32) in gr "p-val" _col(39) in gr "Power" _col(50) in gr "Si" _col(55) in gr "p-val" _col(62) in gr "Power" 
+		di in gr "{hline 67}"
+		forvalues i=1/`nbit'{
+			di _col(1) in gr "``i'' :" _col(14) in ye %4.0f `S`i'_ddl' _col(23) in ye %6.1f ``it'_`i'_t' _col(32) in ye %5.4f `=1-chi2(`=`it'[`i',2]', ``it'_`i'_t')'  _col(39) in ye %5.4f ``Power'_t_S`i''   _col(46) in ye %6.1f ``it'_`i'_newN' _col(55) in ye %5.4f `=1-chi2(`=`it'[`i',2]', ``it'_`i'_newN')'  _col(62) in ye %5.4f ``Power'_newN_S`i'' 
+			di in gr "{hline 90}"
+		}
+	}
+}
+else if "`power'"!=""{
+	di in gr "{hline 67}"
+	di  _col(30) in gr "N = " in ye %6.0f `NbIdFit'   _col(53) in gr  "N = " in ye %6.0f `=ceil(`NbIdFit'*``r'_3')'
+	di _col(16) in gr "df" _col(26) in gr "R1m" _col(32) in gr "p-val" _col(39) in gr "Power" _col(49) in gr "R1m" _col(55) in gr "p-val" _col(62) in gr "Power" 
+	di in gr "{hline 67}"
+	di _col(3) in gr "R1m" _col(14) in ye %4.0f `R1M_ddl' _col(23) in ye %6.1f ``g'_t' _col(32) in ye %5.4f `=1-chi2(`=`g'[1,2]', ``g'_t')'  _col(39) in ye %5.4f ``Power'_t_R1m'   _col(46) in ye %6.1f ``g'_newP' _col(55) in ye %5.4f `=1-chi2(`=`g'[1,2]', ``g'_newP')'  _col(62) in ye %5.4f `power'
+	di in gr "{hline 67}"
+	di in gr ""
+	if `nbitsuf'==1 & "`sitest'"!=""{
+		di in gr "Items specific tests of the fit : tests Si"
+		di in gr ""
+		di in gr "{hline 67}"
+		di  _col(30) in gr "N = " in ye %6.0f `NbIdFit' _col(53)  in gr  "N = " in ye %6.0f `=ceil(`NbIdFit'*``r'_3')'
+		di _col(1) in gr "Item" _col(16) in gr "df" _col(27) in gr "Si" _col(32) in gr "p-val" _col(39) in gr "Power" _col(50) in gr "Si" _col(55) in gr "p-val" _col(62) in gr "Power"
+		di in gr "{hline 67}"
+		forvalues i=1/`nbit'{
+			di _col(1) in gr "``i'' :" _col(14) in ye %4.0f `S`i'_ddl' _col(23) in ye %6.1f ``it'_`i'_t' _col(32) in ye %5.4f `=1-chi2(`=`it'[`i',2]', ``it'_`i'_t')'  _col(39) in ye %5.4f ``Power'_t_S`i''   _col(46) in ye %6.1f ``it'_`i'_newP' _col(55) in ye %5.4f `=1-chi2(`=`it'[`i',2]', ``it'_`i'_newP')'  _col(62) in ye %5.4f ``Power'_newP_S`i''
+			di in gr "{hline 67}"
+		}
+	}
+}
+else{
+	di in gr "{hline 44}"
+	di  _col(30) in gr "N = " in ye %6.0f `NbIdFit' 
+	di _col(16) in gr "df" _col(26) in gr "R1m" _col(32) in gr "p-val" _col(39) in gr "Power" 
+	di in gr "{hline 44}"
+	di _col(3) in gr "R1m" _col(14) in ye %4.0f `R1M_ddl' _col(23) in ye %6.1f ``g'_t' _col(32) in ye %5.4f `=1-chi2(`=`g'[1,2]', ``g'_t')'  _col(39) in ye %5.4f ``Power'_t_R1m'  
+	di in gr "{hline 44}"
+	di in gr ""
+	if `nbitsuf'==1 & "`sitest'"!=""{
+		di in gr "Items specific tests of the fit : tests Si"
+		di in gr ""
+		di in gr "{hline 44}"
+		di  _col(30) in gr "N = " in ye %6.0f `NbIdFit' 
+		di _col(1) in gr "Item" _col(16) in gr "df" _col(27) in gr "Si" _col(32) in gr "p-val" _col(39) in gr "Power" 
+		di in gr "{hline 44}"
+		forvalues i=1/`nbit'{
+			di _col(1) in gr "``i'' :" _col(14) in ye %4.0f `S`i'_ddl' _col(23) in ye %6.1f ``it'_`i'_t' _col(32) in ye %5.4f `=1-chi2(`=`it'[`i',2]', ``it'_`i'_t')'  _col(39) in ye %5.4f ``Power'_t_S`i'' 
+			di in gr "{hline 44}"
+		}
+	}
+}
+
+  /*************************************/
+ /*	             ereturn              */
+/*************************************/
+
+
+return clear
+if "`nfit'"!=""{
+	return scalar NumFit=`nfit'
+	tempname globalFitNu itemFitNu
+	matrix `globalFitNu'=(``g'_newN',`R1M_ddl',`=1-chi2(`=`g'[1,2]', ``g'_newN')',``Power'_newN_R1m',`nfit')
+	if `nbitsuf'==1 & "`sitest'"!=""{
+		matrix `itemFitNu'=J(`nbit',5,.)
+			forvalues i=1/`nbit'{
+			matrix `itemFitNu'[`i',1]=``it'_`i'_newN'
+			matrix `itemFitNu'[`i',2]=`S`i'_ddl'
+			matrix `itemFitNu'[`i',3]=`=1-chi2(`=`it'[`i',2]', ``it'_`i'_newN')'
+			matrix `itemFitNu'[`i',4]=``Power'_newN_S`i''
+			matrix `itemFitNu'[`i',5]=`nfit'
+		}
+	}
+	matrix coln `globalFitNu'=R1m df alpha power N
+	matrix rown `globalFitNu'=Global
+	if `nbitsuf'==1 & "`sitest'"!=""{
+		matrix coln `itemFitNu'=Si df alpha power N
+		return matrix itemFitNu=`itemFitNu'
+	}
+	return matrix globalFitNu=`globalFitNu'
+}
+if "`power'"!=""{
+	return scalar PowFit=`power'
+	tempname globalFitPo itemFitPo
+	matrix `globalFitPo'=(``g'_newP',`R1M_ddl',`=1-chi2(`=`g'[1,2]', ``g'_newP')',`power',`=ceil(`NbIdFit'*``r'_3')')
+	if `nbitsuf'==1 & "`sitest'"!=""{
+		matrix `itemFitPo'=J(`nbit',5,.)
+			forvalues i=1/`nbit'{
+			matrix `itemFitPo'[`i',1]=``it'_`i'_newP'
+			matrix `itemFitPo'[`i',2]=`S`i'_ddl'
+			matrix `itemFitPo'[`i',3]=`=1-chi2(`=`it'[`i',2]', ``it'_`i'_newP')'
+			matrix `itemFitPo'[`i',4]=``Power'_newP_S`i''
+			matrix `itemFitPo'[`i',5]=`=ceil(`NbIdFit'*``r'_3')'
+		}
+	}
+	matrix coln `globalFitPo'=R1m df alpha power N
+	matrix rown `globalFitPo'=Global
+	if `nbitsuf'==1 & "`sitest'"!=""{
+		matrix coln `itemFitPo'=Si df alpha power N
+		return matrix itemFitPo=`itemFitPo'
+	}
+	return matrix globalFitPo=`globalFitPo'
+}
+tempname globalFitTot itemFitTot
+matrix `globalFitTot'=(``g'_t',`R1M_ddl',`=1-chi2(`=`g'[1,2]', ``g'_t')',``Power'_t_R1m',`NbIdFit')
+if `nbitsuf'==1 & "`sitest'"!=""{
+	matrix `itemFitTot'=J(`nbit',5,.)
+		forvalues i=1/`nbit'{
+		matrix `itemFitTot'[`i',1]=``it'_`i'_t'
+		matrix `itemFitTot'[`i',2]=`S`i'_ddl'
+		matrix `itemFitTot'[`i',3]=`=1-chi2(`=`it'[`i',2]', ``it'_`i'_t')'
+		matrix `itemFitTot'[`i',4]=``Power'_t_S`i''
+		matrix `itemFitTot'[`i',5]=`NbIdFit'
+	}
+}
+matrix coln `globalFitTot'=R1m df alpha power N
+matrix rown `globalFitTot'=Global
+if `nbitsuf'==1 & "`sitest'"!=""{
+	matrix coln `itemFitTot'=Si df alpha power N
+	return matrix itemFitTot=`itemFitTot'
+}
+return matrix globalFitTot=`globalFitTot'
+use `bddtravail', replace
+restore
+end
diff --git a/Modules/ado/personal/p/pcmtest.hlp b/Modules/ado/personal/p/pcmtest.hlp
new file mode 100644
index 0000000..e6d8ca1
--- /dev/null
+++ b/Modules/ado/personal/p/pcmtest.hlp
@@ -0,0 +1,65 @@
+{smcl}
+{* Mars 2012}{...}
+{hline}
+help for {hi:pcmtest}{right:JFH}
+{hline}
+
+{title:Global and item specific tests of the fit for Partial Cradit Model}
+
+{p 8 14 2}{cmd:pcmtest}, [{cmdab:g:roup}({it:numlist})
+{cmdab:n:fit}(#)
+{cmdab:p:ower}(#)
+{cmdab:graph:ics}(#)
+{cmdab:a:lpha}(#)
+{cmdab:ap:proximation}
+{cmdab:n:ew}]
+
+{title:Description}
+
+{p 8 14 2}{cmd:pcmtest} allows to test the fit between an observed data and the
+ partial credit model.{p_end}
+{p 14 14 2}The global test of the fit (test R1m) can only be computed if the data
+ contains at least two items. Item specific test of the fit (Si tests) can only be
+  computed if the data contains at least three items. {p_end}
+{p 14 14 2}{cmd:pcmtest} is only performed if item difficulties have been
+  estimated using {cmd:pcmodel}. {cmd:pcmtest} can be performed either if covariates
+   have been included in {cmd:pcmodel} or not.
+
+{title:Options}
+
+{p 4 8 2}{cmd:group} specifies groups of scores, by defining the superior limits of
+ each group
+
+{p 4 8 2}{cmd:nfit} specifies the size of a virtual sample with items response
+ distribution strictly identical to that observed ({cmd:nfit} can deal with
+  over-power problems when tests of the fit are performed on large samples).
+
+{p 4 8 2}{cmd:power} specifies the desired power for a test R1m, and estimates the
+ corresponding size of a virtual sample with items response distribution strictly
+  identical to that observed.
+
+{p 4 8 2}{cmd:alpha} specifies the type I error used to performe the tests of the fit
+ (default: 0.05).
+
+{p 4 8 2}{cmd:graphics} displays several graphs (Graphical fit between the observed and
+ expected latent traits according to the individual scores, graphic of MAP, graphic of
+  groups contribution to the R1m statistic, and graphice of the observed and expected
+   score distribution)
+
+{p 4 8 2}{cmd:approximation} Computation of the pattern response probabilities using 
+simulation instead of Gauss Hermitte quadratures. Computation should be quicker for 
+high number of items or responses modalities.
+
+{p 4 8 2}{cmd:new} Do not use pattern response probabilities computed during a previous 
+test of the fit, compute it an other time! (allows changing the computation methodology)
+
+{title:Author}
+
+{p 4 8 2}Jean-François HAMEL{p_end}
+
+{title:Also see}
+
+{p 4 13 2}Online: help for {help pcmodel}, {help gllamm}, {help simirt}
+, {help raschtest}.{p_end}
+
+
diff --git a/Modules/ado/personal/p/pcmtest.sthlp b/Modules/ado/personal/p/pcmtest.sthlp
new file mode 100644
index 0000000..87328a1
--- /dev/null
+++ b/Modules/ado/personal/p/pcmtest.sthlp
@@ -0,0 +1,98 @@
+{smcl}
+{* Mars 2012}{...}
+{hline}
+help for {hi:pcmtest}
+{hline}
+
+
+{title:Global and item specific tests of fit for a Partial Credit Model or a Rating Scale Model}
+
+{p 8 14 2}{cmd:pcmtest}, [{cmdab:g:roup}({it:numlist})
+{cmdab:ne:w}
+{cmdab:nf:it}(#)
+{cmdab:p:ower}(#)
+{cmdab:a:lpha}(#)
+{cmdab:ap:proximation}
+{cmdab:s:itest}
+{cmdab:graph:ics}
+{cmdab:file:graph}({it:filegraph[, replace])]
+
+
+{title:Description}
+
+{p 8 14 2}{cmd:pcmtest} allows testing the fit between observed data and a
+ partial credit model or a rating scale model.{p_end}
+{p 14 14 2}The global test of fit (test R1m) can only be computed if the data
+ contains at least two items. Item specific test of fit (Si tests) can only be
+  computed if the data contains at least three items. {p_end}
+{p 14 14 2}{cmd:pcmtest} is only performed if item difficulties have been
+  estimated using {cmd:pcmodel}. {cmd:pcmtest} can be performed whether covariates
+   have been included in {cmd:pcmodel} or not.
+
+
+{title:Options}
+
+{p 4 8 2}{cmd:group} specifies groups of scores, by defining the upper limit of
+ each group
+
+{p 4 8 2}{cmd:new} allows changing the computation methodology of the pattern 
+response probabilities between several tests of fit, rather than using the pattern 
+response probabilities stored in Stata memory.
+
+{p 4 8 2}{cmd:nfit} specifies the size of a virtual sample with items response
+ distribution strictly identical to that observed ({cmd:nfit} can deal with
+  over-power problems when fit tests are performed on large samples).
+
+{p 4 8 2}{cmd:power} specifies the desired power for a R1m test, and estimates the
+ corresponding size of a virtual sample with items response distribution strictly
+  identical to that observed.
+
+{p 4 8 2}{cmd:alpha} specifies the type I error used to perform the test of fit
+ (default: 0.05).
+
+{p 4 8 2}{cmd:approximation} Computation of the pattern response probabilities using 
+simulation instead of Gauss Hermitte quadratures. Computation should be quicker for 
+high number of items or responses categories.
+
+{p 4 8 2}{cmd:sitest} performs item specific test of fit (Si tests).
+
+{p 4 8 2}{cmd:graphics} displays several graphs (Distribution of the latent trait 
+depending on the individual scores, graphic of MAP, graphic of
+ the groups contributions to the R1m statistic, and graphic of the observed and expected
+   score distribution).
+
+{p 4 8 2}{cmd:filegraph} indicates the filename and path for saving the graphs 
+(four graphs are store: {it:filegraph}_LT_Sc, {it:filegraph}_MAP, {it:filegraph}_Contrib 
+and {it:filegraph}_Score_Distrib.)
+
+
+{title:Outputs}
+
+{p 4 8 2}{cmd:e(globalFitTot)}: Results of the R1m test performed on the observed sample.
+
+{p 4 8 2}{cmd:e(itemFitTot)}: Results of the Si tests performed on the observed sample.
+
+{p 4 8 2}{cmd:e(globalFitPo)}: Results of the R1m test corresponding 
+to the indicated power.
+
+{p 4 8 2}{cmd:e(itemFitPo)}: Results of the Si tests corresponding 
+to the indicated power.
+
+{p 4 8 2}{cmd:e(globalFitTot)}: Results of the R1m test corresponding 
+to the indicated sample size.
+
+{p 4 8 2}{cmd:e(itemFitTot)}: Results of the Si tests corresponding 
+to the indicated  sample size.
+
+
+{title:Author}
+
+{p 4 8 2}Jean-François Hamel{p_end}
+{p 4 8 2}Email:
+{browse "mailto:jeanfrancois.hamel@chu-angers.fr":jeanfrancois.hamel@chu-angers.fr}{p_end}
+
+
+{title:Also see}
+
+{p 4 13 2}Online: help for {help pcmodel}, {help gllamm}, {help simirt}
+, {help raschtest}.{p_end}
diff --git a/Modules/ado/personal/p/predraschwlm.ado b/Modules/ado/personal/p/predraschwlm.ado
new file mode 100644
index 0000000..3abc1db
--- /dev/null
+++ b/Modules/ado/personal/p/predraschwlm.ado
@@ -0,0 +1,66 @@
+program define predraschwlm,rclass
+syntax varlist , genlt(string) id(string)
+
+tempfile filesave
+qui save `filesave',replace
+tempname diff theta
+matrix `diff'=r(beta)
+matrix `theta'=r(theta)
+
+
+qui count
+local N=r(N)
+
+tokenize `varlist'
+local nbitems:word count `varlist'
+
+tempname item offset id
+qui gen `id'=_n
+
+forvalues i=0/`nbitems' {
+   local thetascore`i'=`theta'[1,`=`i'+1']
+}
+
+tempname nbmiss
+qui egen `nbmiss'=rowmiss(`varlist')
+tempfile s
+qui save `s',replace
+forvalues i=1/`N' {
+   use `s',clear
+   if `nbmiss'[`i']!=0 {
+      local w`i'=0
+      local l`i'=1
+      forvalues j=1/`nbitems' {
+         local item`j'=``j''[`N']
+         local diff`j'=`diff'[1,`j']
+         local rep`i'_`j'=``j''[`i']
+         if `rep`i'_`j''!=. {
+            local w`i' `w`i''+exp(x-`diff`j'')/(1+exp(x-`diff`j''))^2
+            local l`i' `l`i''*exp(`rep`i'_`j''*(x-`diff`j''))/(1+exp(x-`diff`j''))
+         }
+      }
+      local w`i' sqrt(`w`i'')
+      *di "`i'"
+      clear
+      qui set obs 20001
+      qui gen u=_n
+      qui gen x=(u-10001)/1000
+      qui gen f=`w`i''*`l`i''
+      qui gsort -f
+      local tl`i'=x[1]
+   }
+}
+qui use `filesave',clear
+qui capture drop `genlt'
+qui gen `genlt'=.
+tempname scores
+qui genscore `varlist',score(`scores')
+forvalues i=0/`nbitems' {
+   qui replace `genlt'=`thetascore`i'' if `scores'==`i'
+}
+forvalues i=1/`N' {
+   if `genlt'[`i']==. {
+      qui replace `genlt'=`tl`i'' in `i' if `genlt'==.
+   }
+}
+end
diff --git a/Modules/ado/personal/qualmosta/Grille QUALMOSTA.docx b/Modules/ado/personal/qualmosta/Grille QUALMOSTA.docx
new file mode 100644
index 0000000..3901977
Binary files /dev/null and b/Modules/ado/personal/qualmosta/Grille QUALMOSTA.docx differ
diff --git a/Modules/ado/personal/qualmosta/~$ille QUALMOSTA.docx b/Modules/ado/personal/qualmosta/~$ille QUALMOSTA.docx
new file mode 100644
index 0000000..072c8e7
Binary files /dev/null and b/Modules/ado/personal/qualmosta/~$ille QUALMOSTA.docx differ
diff --git a/Modules/ado/personal/r/old/raschfit2.ado b/Modules/ado/personal/r/old/raschfit2.ado
new file mode 100644
index 0000000..350af8a
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschfit2.ado
@@ -0,0 +1,315 @@
+************************************************************************************************************
+* Stata program : Raschfit
+* The Raschfit and the Raschfit-fast procedures to construct sub-scales of items
+* Release 2 : June 8, 2004
+*
+* Historic
+* Version 1 (2004-05-06) [Jean-Benoit Hardouin]
+*
+* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France
+* jean-benoit.hardouin@neuf.fr
+*
+* Use the Stata programs mmsrm, raschtest and gammasym who can be download on http://anaqol.free.fr
+* News about this program :http://anaqol.free.fr
+*
+* FreeIRT Project website : http://freeirt.free.fr
+*
+* Copyright 2004 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+************************************************************************************************************
+
+
+program define raschfit,rclass
+version 7.0
+syntax varlist(min=2 numeric) [,KERnel(integer 0) NBSCales(integer 1) ITEMSorder(string) nofast]
+if "`itemsorder'"=="" {
+        local itemsorder mspinv
+}
+local nbitemstot : word count `varlist'
+tokenize `varlist'
+
+tempfile raschfitfile
+qui save `raschfitfile',replace
+preserve
+
+tempname affect
+matrix define `affect'=J(1,`nbitemstot',0)
+matrix colnames  `affect'=`varlist'
+
+tempname rep item  matbetadim1 matbetadim2
+if `kernel'!=0 {
+   local listkernel
+   forvalues i=1/`kernel' {
+             local listkernel `listkernel' `rep'`i'
+             matrix `affect'[1,`i']=1
+   }
+}
+
+local dim=0
+local nbitemsnosel=`nbitemstot'
+local nbitemstotdim1=`nbitemstot'
+local nbitemsnoselukernel=`nbitemstot'-`kernel'
+
+
+tempvar id betadim1 betadim2
+forvalues i=1/`nbitemstot' {
+      qui drop if ``i''==.
+      rename ``i'' `rep'`i'
+}
+qui gen `id'=_n
+tempfile filescale
+qui save `filescale',replace
+
+
+while `nbitemsnosel'>2&`dim'<`nbscales' {
+      use `filescale',replace
+      local iteration=0
+      local dim=`dim'+1
+      if `dim'>1 {
+         local kernel=0
+         local listkernel
+      }
+
+      di in green "SCALE: " in yellow `dim'
+      di in green "{hline 9}"
+      di
+      tempname result`dim'
+      local listitemsnosel
+      local varlist`dim'
+      tokenize `varlist'
+      forvalues i=1/`nbitemstot' {
+            if `affect'[1,`i']==0 {
+                   local varlist`dim' `varlist`dim'' ``i''
+                   local listitemsnosel `listitemsnosel' `rep'`i'
+            }
+      }
+      local nbitemsnosel:word count `listitemsnosel'
+      if `dim'>1 {
+            local nbitemstotdim`dim':word count `listitemsnosel'
+      }
+
+      if `kernel'>=2 {
+            local fixed=`kernel'
+      }
+      else {
+            local fixed=2
+      }
+      matrix define `result`dim''=J(`=`nbitemstotdim`dim''-`fixed'',`=`nbitemstotdim`dim''+7',0)
+
+      tempname order`dim' affect`dim'
+      matrix `order`dim''=J(1,`nbitemstotdim`dim'',0)
+      matrix `affect`dim''=J(1,`nbitemstotdim`dim'',0)
+
+      if "`itemsorder'"=="msp"|"`itemsorder'"=="mspinv" {
+            di in green _col(0) "The program is ordering the items"
+            qui msp `listkernel' `listitemsnosel',c(-99)  notest kernel(`kernel')
+            local scale1 "`r(scale1)'"
+            local scalenum1 "`r(scalenum1)'"
+            tokenize `scalenum1'
+            local listitemsselnum
+            forvalues j=`=`nbitemstotdim`dim''+1-`fixed''/`nbitemstotdim`dim'' {
+                matrix `order`dim''[1,``j'']=1
+                local k:word `j' of `scalenum1'
+                matrix `affect`dim''[1,`k']=1
+                local listitemsselnum `listitemsselnum' `k'
+            }
+            forvalues j=1/`nbitemsnosel' {
+                matrix `order`dim''[1,`j']=`=`nbitemsnosel'+1-`j''
+            }
+            tokenize `scale1'
+            local listitemssel ``=`nbitemstotdim`dim''-1'' ``nbitemstotdim`dim'''
+
+            local listitemsnosel
+            local listitemsnoselnum
+            
+            if "`itemsorder'"=="mspinv" {
+                forvalues j=1/`=`nbitemstotdim`dim''-`fixed'' {
+                      local listitemsnosel `listitemsnosel' ``j''
+                      local k:word `j' of `scalenum1'
+                      local listitemsnoselnum `listitemsnoselnum' `k'
+                }
+            }
+            else if "`itemsorder'"=="msp"{
+                 forvalues j=`=`nbitemstotdim`dim''-`fixed''(-1)1 {
+                      local listitemsnosel  `listitemsnosel' ``j''
+                      local k:word `j' of `scalenum1'
+                      local listitemsnoselnum  `listitemsnoselnum' `k'
+                 }
+            }
+      }
+      else if "`itemsorder'"=="order" {
+           tokenize `listkernel' `varlist`dim''
+           local listitemssel
+           local listitemsselnum
+           local listitemsnosel
+           local listitemsnoselnum
+           forvalues j=1/`fixed'{
+                     local listitemssel `listitemssel' `rep'`j'
+                     local listitemsselnum `listitemsselnum' `j'
+                     matrix `affect`dim''[1,`j']=1
+           }
+           forvalues j=`=`fixed'+1'/`nbitemstotdim`dim'' {
+                     local listitemsnosel `listitemsnosel' `rep'`j'
+                     local listitemsnoselnum `listitemsnoselnum' `j'
+           }
+      }
+
+      if `dim'>1 {
+             tokenize `varlist`dim''
+      }
+      else {
+             tokenize `varlist'
+      }
+
+      local nbitemsnosel:word count `listitemsnosel'
+      local list
+      *tokenize `varlist'
+      forvalues i=1/`=`nbitemsnosel'+`fixed'' {
+            local tmp:word `i' of "`listitemsnosel' `listitemssel'"
+            local list `list' ``i''
+      }
+
+      matrix colnames `result`dim''=`list'  iteration nbitems ll1 AIC1 ll2 AIC2 choose
+
+      di _col(0) in green "The kernel of the scale is " in yellow _continue
+      forvalues i=1/`fixed' {
+            local inum:word `i' of `listitemsselnum'
+            di in yellow "``inum'' " _continue
+      }
+      di
+      tokenize `listitemsnosel'
+      forvalues i=1/`=`nbitemsnosel-2'' {
+            local iteration=`iteration'+1
+            di
+            di in green _col(10) "iteration:" in yellow" `iteration'"
+            di in green _col(10) "{hline 13}"
+            di
+            qui use `filescale' , clear
+            local i2:word `i' of `listitemsnosel'
+            local i2num:word `i' of `listitemsnoselnum'
+            qui keep `id' `listitemssel' `i2'
+            tempname score1 score2
+            qui gen `score2'=0
+            tokenize `listitemssel'
+            local nbitemssel: word count `listitemssel'
+            forvalues j=1/`i' {
+                      local j2num:word `j' of `listitemsnoselnum'
+                      if `affect`dim''[1,`j2num']==1 {
+                            matrix `result`dim''[`iteration',`j']=1
+                      }
+            }
+            forvalues j=1/`nbitemssel' {
+                      local j2:word `j' of `listitemssel'
+                      local j2num:word `j' of `listitemsselnum'
+                      qui replace `score2'=`score2'+`j2'
+            }
+            tokenize `listitemsnosel'
+            qui gen `score1'=`score2'+`i2'
+            forvalues j=`=`nbitemsnosel'+1'/`=`nbitemsnosel'+`nbitemssel'' {
+                      matrix `result`dim''[`iteration',`j']=1
+            }
+            matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+1']=`iteration'
+            matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+2']=`nbitemssel'
+            matrix `result`dim''[`iteration',`i']=2
+
+            if "`fast'"=="" {
+                        qui count if `score1'!=`=`nbitemssel'+1'&`score1'!=0&`score2'!=`nbitemssel'
+                        local N=r(N)
+                        di in green _col(10)"The program is estimating the parameters of the models (N=" in yellow "`N'" in green ")"
+                        qui raschtest `listitemssel' `i2' if `score1'!=3&`score1'!=0&`score2'!=2, mml notest
+
+                        matrix `matbetadim1'=e(beta),0
+                        qui raschtest `listitemssel' if `score1'!=3&`score1'!=0&`score2'!=2, mml notest
+                        matrix `matbetadim2'=e(beta),0
+                        qui reshape long `rep' , i(`id') j(`item')
+                        qui gen `betadim1'=0
+                        qui gen `betadim2'=0
+
+                        forvalues j=1/`nbitemssel' {
+                                  local j2num:word `j' of `listitemsselnum'
+                                  qui replace `betadim1'=-`matbetadim1'[1,`j'] if `item'==`j2num'
+                                  qui replace `betadim2'=-`matbetadim2'[1,`j'] if `item'==`j2num'
+                        }
+                        qui replace `betadim1'= -`matbetadim1'[1,`=`nbitemssel'+1'] if `item'==`i2num'
+                        qui count if `rep'==1&`item'==`i2num'&`score1'!=`=`nbitemssel'+1'&`score1'!=0&`score2'!=`nbitemssel'
+                        local nb1=r(N)
+                        qui count if `item'==`i2num'&`score1'!=`=`nbitemssel'+1'&`score1'!=0&`score2'!=`nbitemssel'
+                        local nb2=r(N)
+
+                        qui replace `betadim2'= log(`nb1'/(`nb2'-`nb1')) if `item'==`i2num'
+                        qui xi:logit `rep' i.`score1' if `score1'!=`=`nbitemssel'+1'&`score1'!=0&`score2'!=`nbitemssel', nocons offset(`betadim1') iter(100)
+                        local N1=e(N)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+3']=e(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+4']=2*(-e(ll)+2*(`nbitemssel'+1)-1)
+
+                        tempvar  newscore2
+                        qui gen `newscore2'=`score2'
+                        qui replace `newscore2'=99 if `item'==`i2num'
+                        qui xi:logit `rep' i.`newscore2' if `score1'!=`=`nbitemssel'+1'&`score1'!=0&`score2'!=`nbitemssel',  offset(`betadim2') iter(100)
+                        local N2=e(N)
+                        local ll=e(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=e(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+6']=2*(-e(ll)+2*(`nbitemssel'+1)-2)
+            }
+            else {
+                        qui count
+                        local N=r(N)
+                        di in green _col(10)"The program is estimating the parameters of the models (N=" in yellow "`N'" in green ")"
+                        qui raschtest `listitemssel' `i2' , mml notest
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+3']=e(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+4']=2*(-e(ll)+`nbitemssel'+2)
+
+                        local nb1:word count `listitemssel'
+                        qui mmsrm `listitemssel' `i2' , part(`nb1' 1)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=e(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+6']=2*(-e(ll)+`nbitemssel'+4)
+            }
+            di in green _col(10)"Unidimensional model: " _col(32) "ll: "  in yellow _col(37) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+3'] _col(52) in green "AIC: " in yellow _col(57) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+4']
+            di in green _col(10)"Bidimensional model: " _col(32) "ll: "   in yellow _col(37) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+5'] _col(52) in green "AIC: " in yellow _col(57) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+6']
+            tokenize `listkernel' `varlist`dim''
+            if `result`dim''[`iteration',`=`nbitemstot'+4']<=`result`dim''[`iteration',`=`nbitemstot'+6'] {
+                 matrix `result`dim''[`iteration',`i']=1
+                 matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+7']=1
+                 local nbitemssel=`nbitemssel'+1
+                 local nbitemsnosel=`nbitemsnosel'-1
+                 local listitemssel `listitemssel' `rep'`i2num'
+                 local listitemsselnum `listitemsselnum' `i2num'
+                 matrix `affect`dim''[1,`i2num']=1
+                 di _col(10) in green "The item " in yellow "``i2num''" in green " is selected in the scale " in yellow `dim'
+            }
+            else {
+                 matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+7']=2
+                 di _col(10) in green "The item "in yellow "``i2num''" in green " is not selected in the scale " in yellow `dim'
+
+            }
+     }
+     return matrix result`dim' `result`dim''
+     local j=`kernel'+1
+     forvalues i=`=`kernel'+1'/`nbitemstot' {
+            if `affect'[1,`i']==0 {
+                 if `affect`dim''[1,`j']==1 {
+                        matrix `affect'[1,`i']=`dim'
+                 }
+            local j=`j'+1
+            }
+     }
+}
+use `raschfitfile',clear
+
+return matrix affect `affect'
+
+end
diff --git a/Modules/ado/personal/r/old/raschfit31.ado b/Modules/ado/personal/r/old/raschfit31.ado
new file mode 100644
index 0000000..673d554
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschfit31.ado
@@ -0,0 +1,336 @@
+*! Raschfit version 3.1 (29 January 2006)
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Stata program : Raschfit
+* The Raschfit and the Raschfit-fast procedures to construct sub-scales of items
+* Release 3.1 : January 29, 2006 /*MEAN option in raschtestv7, correction of a bug when there is several scales*/
+*
+* Historic
+* Version 1 (2004-05-06) [Jean-Benoit Hardouin]
+* Version 2 (2004-06-08) [Jean-Benoit Hardouin]
+* Version 3 (2005-12-28) [Jean-Benoit Hardouin]
+*
+* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France
+* jean-benoit.hardouin@neuf.fr
+*
+* Use the Stata programs mmsrm, raschtest and gammasym who can be download on http://anaqol.free.fr
+* News about this program :http://anaqol.free.fr
+*
+* FreeIRT Project website : http://freeirt.free.fr
+*
+* Copyright 2004-2006 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+************************************************************************************************************
+
+
+program define raschfit,rclass
+version 7
+syntax varlist(min=2 numeric) [,KERnel(integer 0) NBSCales(integer 1) ITEMSorder(string) nofast ]
+if "`itemsorder'"=="" {
+        local itemsorder mspinv
+}
+local nbitemstot : word count `varlist'
+tokenize `varlist'
+
+tempfile raschfitfile
+qui save `raschfitfile',replace
+preserve
+
+tempname affect
+matrix define `affect'=J(1,`nbitemstot',0)
+matrix colnames  `affect'=`varlist'
+
+tempname rep item  matbetadim1 matbetadim2
+if `kernel'!=0 {
+   local listkernel
+   forvalues i=1/`kernel' {
+             local listkernel `listkernel' `rep'`i'
+             matrix `affect'[1,`i']=1
+   }
+}
+
+local dim=0
+local nbitemsnosel=`nbitemstot'
+local nbitemstotdim1=`nbitemstot'
+local nbitemsnoselukernel=`nbitemstot'-`kernel'
+
+
+tempvar id betadim1 betadim2
+forvalues i=1/`nbitemstot' {
+      qui drop if ``i''==.
+      rename ``i'' `rep'`i'
+}
+qui gen `id'=_n
+tempfile filescale
+qui save `filescale',replace
+
+di in green "{hline 55}"
+qui count
+local N=r(N)
+if "`fast'"!="" {
+   di in green "Method: " in ye "Raschfit"
+}
+else {
+   di in green "Method: " in ye "Raschfit-Fast"
+}
+di in green "Number of individuals: " in ye `N' in green " (with none missing values)"
+di in green "Number of items: " in ye `nbitemstot'
+di in green "{hline 55}"
+di
+di in green "{hline 100}"
+if "`fast'"!="" {
+   di in green "Model 1: " in ye "Rasch model"
+   di in green "Model 2: " in ye "MMSRM"
+}
+else {
+   di in green "Model 1: " in ye "Rasch model"
+   di in green "Model 2: " in ye "Adapted Rasch model (the response of the new item is not influenced by the latent trait)"
+}
+di in green "Order of the items:" _c
+if "`itemsorder'"=="order" {
+   di in ye " order of {it:varlist}"
+}
+else if "`itemsorder'"=="msp" {
+   di in ye " Obtained with MSP (from the first selected item to the last one)"
+}
+else if "`itemsorder'"=="mspinv" {
+   di in ye " Obtained with MSP (from the last selected item to the first one)"
+}
+if `kernel'!=0 {
+   di in green "Kernel of the first scale: " _c
+   forvalues i=1/`kernel' {
+       di in ye " ``i''" _c
+   }
+   di
+}
+di in green "{hline 100}"
+di
+
+while `nbitemsnosel'>2&`dim'<`nbscales' {
+      use `filescale',replace
+      local iteration=0
+      local dim=`dim'+1
+      if `dim'>1 {
+         local kernel=0
+         local listkernel
+      }
+
+      di in green "SCALE: " in yellow `dim'
+      di in green "{hline 9}"
+      di
+      tempname result`dim'
+      local listitemsnosel
+      local varlist`dim'
+      tokenize `varlist'
+      forvalues i=1/`nbitemstot' {
+            if `affect'[1,`i']==0 {
+                   local varlist`dim' `varlist`dim'' ``i''
+                   local listitemsnosel `listitemsnosel' `rep'`i'
+            }
+      }
+      local nbitemsnosel:word count `listitemsnosel'
+      if `dim'>1 {
+            local nbitemstotdim`dim':word count `listitemsnosel'
+      }
+
+      if `kernel'>=2 {
+            local fixed=`kernel'
+      }
+      else {
+            local fixed=2
+      }
+      matrix define `result`dim''=J(`=`nbitemstotdim`dim''-`fixed'',`=`nbitemstotdim`dim''+7',0)
+
+      tempname order`dim' affect`dim'
+      matrix `order`dim''=J(1,`nbitemstotdim`dim'',0)
+      matrix `affect`dim''=J(1,`nbitemstotdim`dim'',0)
+
+      if "`itemsorder'"=="msp"|"`itemsorder'"=="mspinv" {
+            di in green _col(0) "The program is ordering the items"
+            di
+            qui msp `listkernel' `listitemsnosel',c(-99)  notest kernel(`kernel')
+            local scale1 "`r(scale1)'"
+            local scalenum1 "`r(scalenum1)'"
+            tokenize `scalenum1'
+            local listitemsselnum
+            forvalues j=`=`nbitemstotdim`dim''+1-`fixed''/`nbitemstotdim`dim'' {
+                matrix `order`dim''[1,`j']=1
+                local k:word `j' of `scalenum1'
+                matrix `affect`dim''[1,`k']=1
+                local listitemsselnum `listitemsselnum' `k'
+            }
+            forvalues j=1/`nbitemsnosel' {
+                matrix `order`dim''[1,`j']=`=`nbitemsnosel'+1-`j''
+            }
+            tokenize `scale1'
+            local listitemssel ``=`nbitemstotdim`dim''-1'' ``nbitemstotdim`dim'''
+
+            local listitemsnosel
+            local listitemsnoselnum
+
+            if "`itemsorder'"=="mspinv" {
+                forvalues j=1/`=`nbitemstotdim`dim''-`fixed'' {
+                      local listitemsnosel `listitemsnosel' ``j''
+                      local k:word `j' of `scalenum1'
+                      local listitemsnoselnum `listitemsnoselnum' `k'
+                }
+            }
+            else if "`itemsorder'"=="msp"{
+                 forvalues j=`=`nbitemstotdim`dim''-`fixed''(-1)1 {
+                      local listitemsnosel  `listitemsnosel' ``j''
+                      local k:word `j' of `scalenum1'
+                      local listitemsnoselnum  `listitemsnoselnum' `k'
+                 }
+            }
+      }
+      else if "`itemsorder'"=="order" {
+           tokenize `listkernel' `varlist`dim''
+           local listitemssel
+           local listitemsselnum
+           local listitemsnosel
+           local listitemsnoselnum
+           forvalues j=1/`fixed'{
+                     local listitemssel `listitemssel' `rep'`j'
+                     local listitemsselnum `listitemsselnum' `j'
+                     matrix `affect`dim''[1,`j']=1
+           }
+           forvalues j=`=`fixed'+1'/`nbitemstotdim`dim'' {
+                     local listitemsnosel `listitemsnosel' `rep'`j'
+                     local listitemsnoselnum `listitemsnoselnum' `j'
+           }
+      }
+
+      if `dim'>1 {
+             tokenize `varlist`dim''
+      }
+      else {
+             tokenize `varlist'
+      }
+
+      local nbitemsnosel:word count `listitemsnosel'
+      local list
+      tokenize `varlist`dim''
+      forvalues i=1/`=`nbitemsnosel'+`fixed'' {
+            local tmp:word `i' of `listitemsnoselnum' `listitemsselnum'
+            local list `list' ``tmp''
+      }
+      matrix colnames `result`dim''=`list'  Iteration Nbitems ll1 AIC1 ll2 AIC2 Selected
+
+      di _col(0) in green "The kernel of the scale is " in yellow _continue
+      forvalues i=1/`fixed' {
+            local inum:word `i' of `listitemsselnum'
+            di in yellow "``inum'' " _continue
+      }
+      di
+      di
+      tokenize `listitemsnosel'
+      di in green "{hline 90}"
+      di in green _col(36) "Log-Likelihood" _col(58) "Akaike Criterion (AIC)"
+      di in green _col(4) "Iteration" _col(20) "New Item" _col(34) "Model 1" _col(47) "Model 2" _col(60) "Model 1" _col(73) "Model 2" _col(81) "Selected"
+      di in green "{hline 90}"
+      forvalues i=1/`=`nbitemsnosel-2'' {
+            local iteration=`iteration'+1
+            qui use `filescale' , clear
+            local i2:word `i' of `listitemsnosel'
+            local i2num:word `i' of `listitemsnoselnum'
+            qui keep `id' `listitemssel' `i2'
+            tempname score1 score2
+            qui gen `score2'=0
+            tokenize `listitemssel'
+            local nbitemssel: word count `listitemssel'
+            forvalues j=1/`i' {
+                      local j2num:word `j' of `listitemsnoselnum'
+                      if `affect`dim''[1,`j2num']==1 {
+                            matrix `result`dim''[`iteration',`j']=1
+                      }
+            }
+            forvalues j=1/`nbitemssel' {
+                      local j2:word `j' of `listitemssel'
+                      local j2num:word `j' of `listitemsselnum'
+                      qui replace `score2'=`score2'+`j2'
+            }
+            tokenize `listitemsnosel'
+            qui gen `score1'=`score2'+`i2'
+            forvalues j=`=`nbitemsnosel'+1'/`=`nbitemsnosel'+`nbitemssel'' {
+                      matrix `result`dim''[`iteration',`j']=1
+            }
+            matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+1']=`iteration'
+            matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+2']=`nbitemssel'
+            matrix `result`dim''[`iteration',`i']=2
+
+            if "`fast'"=="" {
+                        qui count
+                        local N=r(N)
+*                        di "qui raschtestv7 `listitemssel' `i2' , mean method(cml) test(none)"
+                        qui raschtestv7 `listitemssel' `i2' , mean method(cml) test(none)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+3']=r(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+4']=2*(-r(ll)+(2*`nbitemssel'+3))
+
+                        local nb1:word count `listitemssel'
+                        qui raschtestv7 `listitemssel',trace test(none) mean
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=r(ll)
+                        qui logit `i2'
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=`result`dim''[`iteration',`=`nbitemstotdim`dim''+5']+e(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+6']=2*(-`result`dim''[`iteration',`=`nbitemstotdim`dim''+5']+(2*`nbitemssel'+3))
+            }
+            else {
+                        qui count
+                        local N=r(N)
+                        qui raschtestv7 `listitemssel' `i2' , method(mml) test(none)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+3']=r(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+4']=2*(-r(ll)+`nbitemssel'+2)
+
+                        local nb1:word count `listitemssel'
+                        qui mmsrm `listitemssel' `i2' , part(`nb1' 1) iterate(20)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=e(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+6']=2*(-e(ll)+`nbitemssel'+4)
+            }
+            tokenize `listkernel' `varlist`dim''
+            di in ye _col(4) %9.0f `iteration' _col(14) %14s abbrev("``i2num''",14) _col(29) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+3'] _col(42) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+5'] _col(55) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+4'] _col(68) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+6'] _c
+            if `result`dim''[`iteration',`=`nbitemstot'+4']<=`result`dim''[`iteration',`=`nbitemstot'+6'] {
+                 matrix `result`dim''[`iteration',`i']=1
+                 matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+7']=1
+                 local nbitemssel=`nbitemssel'+1
+                 local nbitemsnosel=`nbitemsnosel'-1
+*                 local listitemssel `listitemssel' `rep'`i2num'
+                 local listitemssel `listitemssel' `i2'
+                 local listitemsselnum `listitemsselnum' `i2num'
+                 matrix `affect`dim''[1,`i2num']=1
+                 di in ye _col(88) "X"
+            }
+            else {
+                 matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+7']=2
+                 di
+            }
+     }
+     di in green "{hline 90}"
+     return matrix result`dim' `result`dim''
+     local j=`kernel'+1
+     forvalues i=`=`kernel'+1'/`nbitemstot' {
+            if `affect'[1,`i']==0 {
+                 if `affect`dim''[1,`j']==1 {
+                        matrix `affect'[1,`i']=`dim'
+                 }
+            local j=`j'+1
+            }
+     }
+}
+use `raschfitfile',clear
+
+return matrix affect `affect'
+
+end
diff --git a/Modules/ado/personal/r/old/raschpower - Copie version SIM.ado b/Modules/ado/personal/r/old/raschpower - Copie version SIM.ado
new file mode 100644
index 0000000..674f1a1
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschpower - Copie version SIM.ado	
@@ -0,0 +1,217 @@
+*! version 1.2  November 1st, 2010
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
+*
+* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
+* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
+* Version 1.1 : November 1st, 2010 (Jean-Benoit Hardouin)
+*
+* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2010 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+program define raschpower,rclass
+syntax [varlist] [, n0(int 100) n1(int 100) gamma(real .5) d(string) var(real 1) nodes(int 12)]
+version 11
+
+
+if "`d'"=="" {
+   tempname d
+   matrix `d'=[-1\-.5\0\.5\1]
+}
+
+
+/*tempname abs weight
+ghquadm `nodes' `abs' `weight'
+matrix `abs'=`abs''
+matrix `weight'=`weight''
+
+matrix `abs'=`abs'*sqrt(`var')
+*matrix list `abs'
+matrix `abs'=[5.50090170446774,4.27182584793228,3.22370982877010,2.25946445100080,1.34037519715162,0.444403001944139,-5.50090170446774,-4.27182584793228,-3.22370982877010,-2.25946445100080,-1.34037519715162,-0.444403001944139]
+matrix `abs'=`abs''*sqrt(`var')
+matrix `weight'=[0.000000375975985,0.000121250244966,0.005523056331147,0.072984713184739,0.368391758069477,0.806292983509187,0.000000375975985,0.000121250244966,0.005523056331147,0.072984713184739,0.368391758069477,0.806292983509187]
+matrix `weight'=`weight''
+*matrix list `abs'
+*/
+local nbitems=rowsof(`d')
+
+di in gr "Number of individuals in the first group:  " in ye `n0'
+di in gr "Number of individuals in the second group: " in ye `n1'
+di in green "Group effect: " in ye `gamma'
+di in  gr "Variance of the latent trait: " in ye `var'
+di in gr "Number of items: " in ye `nbitems'
+di in green "Difficulties parameters of the items: " _c
+tempname dd
+matrix `dd'=`d''
+matrix list `dd',noblank nohalf nonames noheader
+
+matrix `dd'=`d'/sqrt(`var')
+local gamma=`gamma'/sqrt(`var')
+
+
+clear
+local temp=2^(`nbitems')
+qui range x 0 `=`temp'-1' `temp'
+qui g t=x
+loc i=1
+qui count if t>0
+loc z=r(N)
+qui while `z'>0 {
+  qui g item`i'=mod(t,2^`i')==2^`=`i'-1'
+  qui replace t=t-item`i'*2^`=`i'-1'
+  qui count if t>0
+  loc z=r(N)
+  loc i=`i'+1
+}
+drop t
+qui expand 2
+qui gen group=0 in 1/`temp'
+qui replace group=1 in `=`temp'+1'/`=2*`temp''
+qui gen mean=-`n1'*`gamma'/(`n0'+`n1') if group==0
+qui replace mean=`n0'*`gamma'/(`n0'+`n1') if group==1
+qui gen proba=1
+forvalues i=1/`nbitems' {
+   qui gen eps`i'=exp(mean-`d'[`i',1])
+   qui replace proba=proba*eps`i'^item`i'/(1+eps`i')
+}
+
+*list item* proba
+
+qui gen eff=.
+forvalues i=0/1 {
+   qui replace eff=proba*`n`i'' if group==`i'
+}
+
+/*
+forvalues i=1/`nbitems' {
+   qui gen f`i'=eps`i'^item`i'/(1+eps`i')
+   qui gen fp`i'=(item`i'*eps`i'^item`i'+(item`i'-1)*eps`i'^(item`i'+1))/(1+eps`i')^2
+   qui gen fpp`i'=((item`i'^2*eps`i'^item`i'+(item`i'^2-1)*eps`i'^(item`i'+1))*(1+eps`i')^2-2*eps`i'*(1+eps`i')*(item`i'*eps`i'^item`i'+(item`i'-1)*eps`i'^(item`i'+1)))/(1+eps`i')^4
+}
+*/
+qui replace eff=proba
+keep item* eff group proba
+
+local p1=1/`n1'
+local p0=1/`n0'
+qui gen eff2=.
+qui replace eff2=floor(eff/`p1') if group==1
+qui replace eff2=floor(eff/`p0') if group==0
+
+
+qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
+qui su eff2 if group==1
+local aff1=r(sum)
+qui su eff2 if group==0
+local aff0=r(sum)
+
+*di "Nombre de patients affectes : `aff1' dans groupe 1 (sur `n1') et `aff0' dans le groupe 0 (sur `n0')"
+
+local unaff1=`n1'-`aff1'
+local unaff0=`n0'-`aff0'
+*di "Nombre de patients non affectes : `unaff1' dans groupe 1 (sur `n1') et `unaff0' dans le groupe 0 (sur `n0')"
+
+
+di "avant sort"
+list item* group proba eff2
+
+
+qui gsort + group - eff
+list item* group proba eff2
+qui replace eff2=eff2+1 in 1/`unaff0'
+di "apres sort"
+qui gsort - group - eff
+qui replace eff2=eff2+1 in 1/`unaff1'
+list item* group proba eff2
+su proba
+return list
+
+*list eff eff2 group proba
+
+qui drop if eff2==0
+
+qui expand eff2
+qui gen i=_n
+
+tempname diff
+matrix `diff'=`dd''
+
+/***************************A REVOIR
+forvalues i=1/`nbitems' {
+    qui su item`i'
+	local var=r(Var)
+	if `var'==0 {
+	    qui drop item`i'
+    }
+}
+****************************FIN A REVOIR*/
+
+*irtpoly item*,  fixedvar(1) rasch fixed(`diff') covariablemean(group) sasout
+
+qui drop proba eff eff2
+qui reshape long item, i(i)
+qui rename item rep
+qui rename _j item
+
+qui gen  offset=0
+forvalues i=1/`nbitems' {
+    qui replace offset=-`diff'[1,`i'] if item==`i'
+}
+constraint 1 _cons=0
+qui gen groupc=group-.5
+qui xtlogit rep groupc  ,nocons i(i) offset(offset) constraint(1)
+
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local gammaest=`b'[1,1]*sqrt(`var')
+local se=`V'[1,1]^.5*sqrt(`var')
+di
+di
+di in gr "{hline 76}"
+di _col(50)  "Estimation with the "
+di _col(40)  "Cramer-Rao bound" _col(60) "classical formula"
+di in gr "{hline 76}"
+di in green "Estimated value of the group effect" _col(49) in ye  %7.2f `gammaest'
+di in green "Standard Error of this estimation" _col(49) in ye %7.2f `se'
+di in green "Variance of this estimation" _col(46) in ye %10.4f `=`se'^2'
+local power=1-normal(1.96-`gamma'*sqrt(`var')/`se')
+local clpower=normal(sqrt(`n1'*`gamma'^2/(`n1'/`n0'+1))-1.96)
+di in green "Estimated value of the power" _col(50) in ye %6.4f `power' _col(71) in ye %6.4f `clpower'
+local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*`gamma'^2)*(1.96-invnorm(1-`power'))^2
+di in green "Number of patients for a power of" %6.2f `=`power'*100' "%" _col(49) in ye `n0' "/" `n1' _col(62) in ye %7.2f `clnsn' "/" %7.2f `clnsn'
+di in green "Ratio of the number of patients" in ye %6.2f _col(55)`=(`n0'+`n1')/(2*`clnsn')'
+di in gr "{hline 76}"
+
+return scalar EstGamma=`gammaest'
+return scalar CRbound=`=`se'^2'
+return scalar CRPower=`power'
+return scalar ClPower=`clpower'
+return scalar ClSS=`clnsn'
+return scalar Ratio=`=`n0'/`clnsn''
+
+
+
+
+end
diff --git a/Modules/ado/personal/r/old/raschpower1.5.ado b/Modules/ado/personal/r/old/raschpower1.5.ado
new file mode 100644
index 0000000..e5b59f7
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschpower1.5.ado
@@ -0,0 +1,220 @@
+*! version 1.5 : July 11th, 2011
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
+*
+* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
+* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
+* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
+* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin)
+* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
+* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
+*
+* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2010-2011 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+program define raschpower,rclass
+syntax [varlist] [, n0(int 100) n1(int 100) gamma(real .5) d(string) var(real 1) fast nodata gammafix EXPectedpower(real -1)]
+version 11
+
+tempfile raschpowerfile
+capture qui save "`raschpowerfile'",replace
+if "`d'"=="" {
+   tempname d
+   matrix `d'=[-1\-.5\0\.5\1]
+}
+
+local nbitems=rowsof(`d')
+
+di in gr "Number of individuals in the first group:  " in ye `n0'
+di in gr "Number of individuals in the second group: " in ye `n1'
+di in green "Group effect: " in ye `gamma'
+di in  gr "Variance of the latent trait: " in ye `var'
+di in gr "Number of items: " in ye `nbitems'
+di in green "Difficulties parameters of the items: " _c
+tempname dd
+matrix `dd'=`d''
+matrix list `dd',noblank nohalf nonames noheader
+
+matrix `dd'=`d'/*sqrt(`var')*/
+local gamma=`gamma'/*sqrt(`var')*/
+
+if "`data'"=="" {
+   clear
+   local temp=2^(`nbitems')
+   qui range x 0 `=`temp'-1' `temp'
+   qui g t=x
+   loc i=1
+   qui count if t>0
+   loc z=r(N)
+   qui while `z'>0 {
+      qui g item`i'=mod(t,2^`i')==2^`=`i'-1'
+      qui replace t=t-item`i'*2^`=`i'-1'
+      qui count if t>0
+      loc z=r(N)
+      loc i=`i'+1
+   }
+   drop t
+   qui expand 2
+   qui gen group=0 in 1/`temp'
+   qui replace group=1 in `=`temp'+1'/`=2*`temp''
+   qui gen mean=-`n1'*`gamma'/(`n0'+`n1') if group==0
+   qui replace mean=`n0'*`gamma'/(`n0'+`n1') if group==1
+
+   if "`fast'"=="" {
+      qui gen proba=.
+      forvalues i=1/`=2*`temp'' {
+         local int=1
+         forvalues j=1/`nbitems' {
+            qui su item`j' in `i'
+            local rep=r(mean)
+            local diff=`d'[`j',1]
+            local int "`int'*exp(`rep'*(x-`diff'))/(1+exp(x-`diff'))"
+         }
+         qui su mean in `i'
+         local mean=r(mean)
+         qui gausshermite `int',mu(`mean') sigma(`=sqrt(`var')') display
+         qui replace proba=r(int) in `i'
+      }
+   }
+   else {
+      qui gen proba=1
+      forvalues i=1/`nbitems' {
+         qui gen eps`i'=exp(mean-`d'[`i',1])
+         qui replace proba=proba*eps`i'^item`i'/(1+eps`i')
+      }
+   }
+   qui gen eff=.
+   forvalues i=0/1 {
+      qui replace eff=proba*`n`i'' if group==`i'
+   }
+   qui replace eff=proba
+   keep item* eff group proba
+
+   local p1=1/`n1'
+   local p0=1/`n0'
+   qui gen eff2=.
+   qui replace eff2=floor(eff/`p1') if group==1
+   qui replace eff2=floor(eff/`p0') if group==0
+   qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
+   qui su eff2 if group==1
+   local aff1=r(sum)
+   qui su eff2 if group==0
+   local aff0=r(sum)
+
+   local unaff1=`n1'-`aff1'
+   local unaff0=`n0'-`aff0'
+   gen efftmp=eff2
+
+   qui gsort + group - eff
+   qui replace eff2=eff2+1 in 1/`unaff0'
+   qui gsort - group - eff
+   qui replace eff2=eff2+1 in 1/`unaff1'
+
+   *qui drop if eff2==0
+   gsort group item*
+   gen res=proba*50
+*list item* group efftmp eff2  proba
+
+   qui expand eff2
+   qui drop proba eff eff2
+}
+qui gen i=_n
+
+*su
+qui alpha item*
+local alpha=r(alpha)
+
+tempname diff
+matrix `diff'=`dd''
+
+qui reshape long item, i(i)
+qui rename item rep
+qui rename _j item
+
+qui gen  offset=0
+forvalues i=1/`nbitems' {
+    qui replace offset=-`diff'[1,`i'] if item==`i'
+}
+qui gen groupc=group-.5
+matrix est=(`gamma',`=sqrt(`var')')
+
+
+
+if "`gammafix'"=="" {
+   constraint 1 _cons=`=ln(`var')'
+   qui xtlogit rep groupc  ,nocons i(i) offset(offset) constraint(1)
+}
+else {
+   qui gllamm   rep groupc, nocons i(i) offset(offset)  iterate(0) fam(bin) link(logit) from(est) copy
+}
+
+
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local gammaest=`b'[1,1]/*sqrt(`var')*/
+local se=`V'[1,1]^.5/*sqrt(`var')*/
+di
+di
+di in gr "{hline 91}"
+di _col(60)  "Estimation with the "
+di _col(50)  "Cramer-Rao bound" _col(75) "classical formula"
+di in gr "{hline 91}"
+if "`gammafixed'"==""  {
+   di in green "Estimated value of the group effect" _col(59) in ye  %7.2f `gammaest'
+}
+di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
+di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+local power=1-normal(1.96-`gamma'/*sqrt(`var')*//`se')+normal(-1.96-`gamma'*sqrt(`var')/`se')
+local poweruni=1-normal(1.96-`gamma'/*sqrt(`var')*//`se')
+local clpower=normal(sqrt(`n1'*`gamma'^2/(`n1'/`n0'+1))-1.96)
+/*si on ne néglige pas le deuxième terme, la bonne puissance est*/
+*di in green "Estimation of the power" _col(60) in ye %6.4f `power' _col(86) in ye %6.4f `clpower'
+di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+/*si on ne néglige pas le deucième terme, la bonne puissance est*/
+*local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96-invnorm(1-`power'))^2
+local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96-invnorm(1-`poweruni'))^2
+di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `clnsn'
+di in green "Ratio of the number of patients" in ye %6.2f _col(68)`=(`n0'+`n1')/(2*`clnsn')'
+if `expectedpower'!=-1 {
+   qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower')
+   local expn=r(N_1)
+   local expn2=`expn'*`=(`n0'+`n1')/(2*`clnsn')'
+   di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `expn2' _col(77) in ye %7.2f `expn' "/" %7.2f `expn'
+}
+di in gr "{hline 91}"
+
+return scalar EstGamma=`gammaest'
+return scalar CRbound=`=`se'^2'
+return scalar CRPower=`poweruni'
+return scalar ClPower=`clpower'
+return scalar ClSS=`clnsn'
+return scalar Ratio=`=`n0'/`clnsn''
+return scalar CronbachAlpha=`alpha'
+
+
+
+capture qui use `raschpowerfile',clear
+
+end
diff --git a/Modules/ado/personal/r/old/raschpower1.ado b/Modules/ado/personal/r/old/raschpower1.ado
new file mode 100644
index 0000000..2e2f2fe
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschpower1.ado
@@ -0,0 +1,193 @@
+*! version 1  january 25th, 2010
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
+*
+* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
+*
+* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2010 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+program define raschpower1,rclass
+syntax [varlist] [, n0(int 100) n1(int 100) gamma(real .5) d(string) var(real 1) nodes(int 12)]
+
+
+
+if "`d'"=="" {
+   tempname d
+   matrix `d'=[-1\-.5\0\.5\1]
+}
+
+/*tempname abs weight
+ghquadm `nodes' `abs' `weight'
+matrix `abs'=`abs''
+matrix `weight'=`weight''
+
+matrix `abs'=`abs'*sqrt(`var')
+*matrix list `abs'
+matrix `abs'=[5.50090170446774,4.27182584793228,3.22370982877010,2.25946445100080,1.34037519715162,0.444403001944139,-5.50090170446774,-4.27182584793228,-3.22370982877010,-2.25946445100080,-1.34037519715162,-0.444403001944139]
+matrix `abs'=`abs''*sqrt(`var')
+matrix `weight'=[0.000000375975985,0.000121250244966,0.005523056331147,0.072984713184739,0.368391758069477,0.806292983509187,0.000000375975985,0.000121250244966,0.005523056331147,0.072984713184739,0.368391758069477,0.806292983509187]
+matrix `weight'=`weight''
+*matrix list `abs'
+*/
+local nbitems=rowsof(`d')
+
+di in gr "Number of individuals in the first group:  " in ye `n0'
+di in gr "Number of individuals in the second group: " in ye `n1'
+di in green "Group effect: " in ye `gamma'
+di in  gr "Variance of the latent trait: " in ye `var'
+di in gr "Number of items: " in ye `nbitems'
+di in green "Difficulties parameters of the items: " _c
+tempname dd
+matrix `dd'=`d''
+matrix list `dd',noblank nohalf nonames noheader
+
+
+
+clear
+local temp=2^(`nbitems')
+qui range x 0 `=`temp'-1' `temp'
+qui g t=x
+loc i=1
+qui count if t>0
+loc z=r(N)
+qui while `z'>0 {
+  qui g item`i'=mod(t,2^`i')==2^`=`i'-1'
+  qui replace t=t-item`i'*2^`=`i'-1'
+  qui count if t>0
+  loc z=r(N)
+  loc i=`i'+1
+}
+drop t
+qui expand 2
+qui gen group=0 in 1/`temp'
+qui replace group=1 in `=`temp'+1'/`=2*`temp''
+qui gen mean=(-1)^(1-group)*`gamma'*sqrt(`var')/2
+qui gen proba=1
+forvalues i=1/`nbitems' {
+   qui gen eps`i'=exp(mean-`d'[`i',1])
+   qui replace proba=proba*eps`i'^item`i'/(1+eps`i')
+}
+qui gen eff=.
+forvalues i=0/1 {
+   qui replace eff=proba*`n`i'' if group==`i'
+}
+forvalues i=1/`nbitems' {
+   qui gen f`i'=eps`i'^item`i'/(1+eps`i')
+   qui gen fp`i'=(item`i'*eps`i'^item`i'+(item`i'-1)*eps`i'^(item`i'+1))/(1+eps`i')^2
+   qui gen fpp`i'=((item`i'^2*eps`i'^item`i'+(item`i'^2-1)*eps`i'^(item`i'+1))*(1+eps`i')^2-2*eps`i'*(1+eps`i')*(item`i'*eps`i'^item`i'+(item`i'-1)*eps`i'^(item`i'+1)))/(1+eps`i')^4
+}
+qui replace eff=proba
+keep item* eff group proba
+
+local p1=1/`n1'
+local p0=1/`n0'
+qui gen eff2=.
+qui replace eff2=floor(eff/`p1') if group==1
+qui replace eff2=floor(eff/`p0') if group==0
+qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
+qui su eff2 if group==1
+local aff1=r(sum)
+qui su eff2 if group==0
+local aff0=r(sum)
+
+*di "Nombre de patients affectes : `aff1' dans groupe 1 (sur `n1') et `aff0' dans le groupe 0 (sur `n0')"
+
+local unaff1=`n1'-`aff1'
+local unaff0=`n0'-`aff0'
+*di "Nombre de patients non affectes : `unaff1' dans groupe 1 (sur `n1') et `unaff0' dans le groupe 0 (sur `n0')"
+
+qui gsort + group - eff
+qui replace eff2=eff2+1 in 1/`unaff0'
+qui gsort - group - eff
+qui replace eff2=eff2+1 in 1/`unaff1'
+
+*list eff eff2 group proba
+
+qui drop if eff2==0
+
+qui expand eff2
+qui gen i=_n
+
+tempname diff
+matrix `diff'=`d''
+
+/***************************A REVOIR
+forvalues i=1/`nbitems' {
+    qui su item`i'
+	local var=r(Var)
+	if `var'==0 {
+	    qui drop item`i'
+    }
+}
+****************************FIN A REVOIR*/
+
+*irtpoly item*,  fixedvar(1) rasch fixed(`diff') covariablemean(group) sasout
+
+qui drop proba eff eff2
+qui reshape long item, i(i)
+qui rename item rep
+qui rename _j item
+
+qui gen  offset=0
+forvalues i=1/`nbitems' {
+    qui replace offset=-`diff'[1,`i'] if item==`i'
+}
+constraint 1 _cons=0
+qui gen groupc=group-.5
+ xtlogit rep groupc  ,nocons i(i) offset(offset) constraint(1)
+
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local gammaest=`b'[1,1]
+local se=`V'[1,1]^.5
+di
+di
+di in gr "{hline 76}"
+di _col(50)  "Estimation with the "
+di _col(40)  "Cramer-Rao bound" _col(60) "classical formula"
+di in gr "{hline 76}"
+di in green "Estimated value of the group effect" _col(49) in ye  %7.2f `gammaest'
+di in green "Standard Error of this estimation" _col(49) in ye %7.2f `se'
+di in green "Variance if this estimation" _col(46) in ye %10.4f `=`se'^2'
+local power=1-normal(1.96-`gamma'/`se')
+local clpower=normal(sqrt(`n0'*`gamma'^2/2)-1.96)
+di in green "Estimated value of the power" _col(50) in ye %6.4f `power' _col(71) in ye %6.4f `clpower'
+local clnsn=2/`gamma'^2*(1.96-invnorm(1-`power'))^2
+di in green "Number of patients for a power of" %6.2f `=`power'*100' "%" _col(49) in ye `n0' "/" `n1' _col(62) in ye %7.2f `clnsn' "/" %7.2f `clnsn'
+di in green "Ratio of the number of patients" in ye %6.2f _col(55)`=(`n0'+`n1')/(2*`clnsn')'
+di in gr "{hline 76}"
+
+return scalar EstGamma=`gammaest'
+return scalar CRbound=`=`se'^2'
+return scalar CRPower=`power'
+return scalar ClPower=`clpower'
+return scalar ClSS=`clnsn'
+return scalar Ratio=`=`n0'/`clnsn''
+
+
+
+
+end
diff --git a/Modules/ado/personal/r/old/raschpowerpcm.ado b/Modules/ado/personal/r/old/raschpowerpcm.ado
new file mode 100644
index 0000000..7219cf2
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschpowerpcm.ado
@@ -0,0 +1,374 @@
+*! version 3.1 : October 25th, 2011
+*! Jean-Benoit Hardouin, Myriam Blanchin
+************************************************************************************************************
+* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
+*
+* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
+* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
+* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
+* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin)
+* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
+* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
+* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
+* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
+* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
+*
+* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
+* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
+* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
+* Faculty of Pharmaceutical Sciences - University of Nantes - France
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2010-2011 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+program define raschpowerpcm,rclass
+syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(real 1) Method(string) NBPatterns(int 2) nodata gammafix EXPectedpower(real -1)]
+version 11
+
+tempfile raschpowerfile
+capture qui save "`raschpowerfile'",replace
+tempname db d
+if "`difficulties'"=="" {
+   *matrix `d'=[-1\-.5\0\.5\1]
+   matrix `d'=[-1.151, -0.987\-0.615, -0.325\-0.184, -0.043\0.246, 0.554\0.782, 1.724]
+   *matrix `d'=[ -1.527, -1.019\-1.100, -0.793\-0.796, -0.369\-0.540, 0.152\-0.306, -0.220\-0.077, 0.147\0.156, 0.431\0.412, 0.685\0.716, 1.332\1.043, 1.572]
+}
+else {
+   matrix `d'=`difficulties'
+}
+local nbitems=rowsof(`d')
+local nbmodat=colsof(`d')+1
+if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`=`nbmodat'^`nbitems'*2' {
+   di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
+   di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
+   di in gr "The -method- option is replaced by GH."
+   local method GH
+}
+else if "`method'"=="" {
+    if `nbmodat'^`nbitems'*2<1000 {
+        local method GH
+    }
+    else if `nbmodat'^`nbitems'<10000 {
+        local method MEAN+GH
+    }
+    else if `nbmodat'^`nbitems'<1000000 {
+        local method MEAN
+    }
+    else  {
+        local method POPULATION+GH
+    }
+}
+
+
+
+di in gr "Method:  " in ye "`method'"
+di in gr "Number of individuals in the first group:  " in ye `n0'
+di in gr "Number of individuals in the second group: " in ye `n1'
+di in green "Group effect: " in ye `gamma'
+di in  gr "Variance of the latent trait: " in ye `var'
+di in gr "Number of items: " in ye `nbitems'
+di in green "Difficulties parameters of the items: "
+tempname dd
+matrix `dd'=`d''
+local items
+forvalues i=1/`nbitems' {
+   local items "`items' item`i'"
+}
+local modalities
+forvalues i=1/`=`nbmodat'-1' {
+   local modalities "`modalities' delta_`i'"
+}
+
+matrix colnames `dd'=`items'
+matrix rownames `dd'=`modalities'
+matrix list `dd',noblank nohalf  noheader
+di in gr "Number of studied response's patterns: " in ye `=`nbmodat'^`nbitems'*2'
+
+matrix `dd'=`d'
+local gamma=`gamma'
+
+local tmp=1
+qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
+forvalues j=1/`nbitems' {
+   forvalues m=1/`=`nbmodat'-1' {
+      qui matrix `db'[`tmp',1]=`d'[`j',`m']
+      local ++tmp
+   }
+}
+
+if "`data'"=="" {
+   clear
+   if "`method'"!="POPULATION+GH"&"`method'"!="POPULATION+MEAN" {
+      local temp=`nbmodat'^(`nbitems')
+      qui range x 0 `=`temp'-1' `temp'
+      qui g t=x
+      loc i=`nbitems'
+      qui count if t>0
+      loc z=r(N)
+      qui while `z'>0 {
+         qui gen item`=`nbitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
+         qui replace t=mod(t,`nbmodat'^`=`i'-1')
+         qui count if t>0
+         loc z=r(N)
+         loc i=`i'-1
+      }
+      drop t
+      qui expand 2
+      qui gen group=0 in 1/`temp'
+      qui replace group=1 in `=`temp'+1'/`=2*`temp''
+   }
+   else {
+      qui simirt, clear pcm(`difficulties') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
+      qui drop lt1
+      qui contract item* group, freq(freq)
+      qui gen keep=0
+      qui gsort +group -freq
+      qui replace keep=1 in 1/`=`nbpatterns'*`n1''
+      qui gsort -group -freq
+      qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+      qui keep if keep==1
+      qui count
+      local tmp=r(N)
+      di "Number of kept patterns:`tmp'"
+      local method GH
+   }
+   qui gen mean=-`n1'*`gamma'/(`n0'+`n1') if group==0
+   qui replace mean=`n0'*`gamma'/(`n0'+`n1') if group==1
+
+   if "`method'"=="GH" {
+      local temp=`nbmodat'^(`nbitems')
+      local diff0=0
+      qui gen proba=.
+      local dixj=10
+      qui count
+      local tmp=r(N)
+      forvalues i=1/`tmp' {
+         local dix=floor(`tmp'/10)
+         if mod(`i',`dix')==0 {
+            if "`dixj'"!="10" {
+               di ".." _c
+            }
+            di "`dixj'%" _c
+            local dixj=`dixj'+10
+         }
+         local int=1
+         forvalues j=1/`nbitems' {
+            qui su item`j' in `i'
+            local rep=r(mean)
+            local diff0=0
+            local diff1=`d'[`j',1]
+            local sum "1+exp(x-`diff1')"
+            forvalues m=2/`=`nbmodat'-1' {
+               local diff`m'=`diff`=`m'-1''+`d'[`j',`m']
+               local sum "`sum'+exp(`m'*x-`diff`m'')"
+            }
+            local int "(`int'*exp(`rep'*x-`diff`rep''))/(`sum')"
+         }
+         qui su mean in `i'
+         local mean=r(mean)
+         qui gausshermite `int',mu(`mean') sigma(`=sqrt(`var')') display
+         qui replace proba=r(int) in `i'
+      }
+      di
+   }
+   else {
+      qui gen proba=1
+      forvalues i=1/`nbitems' {
+         local diff0=0
+         local diff1=`d'[`i',1]
+         qui gen eps0=1
+         qui gen eps1=exp(mean-`diff1')
+         qui gen d=eps0+eps1
+         forvalues m=2/`=`nbmodat'-1' {
+            local diff`m'=`diff`=`m'-1''+`d'[`i',`m']
+            qui gen eps`m'=exp(`m'*mean-`diff`m'')
+            qui replace d=d+eps`m'
+         }
+         local listeps
+         forvalues m=0/`=`nbmodat'-1' {
+            qui replace proba=proba*eps`m'/d if item`i'==`m'
+            local listeps `listeps' eps`m'
+         }
+         qui drop `listeps' d
+      }
+      if "`method'"=="MEAN+GH" {
+      set tracedepth 1
+         qui gen keep=0
+         qui gsort -group -proba
+         local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
+         qui replace keep=1 in 1/`min'
+         qui gsort +group -proba
+         local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
+         qui replace keep=1 in 1/`min'
+         qui keep if keep==1
+         qui su proba if group==0
+         local sumproba0=r(sum)*100
+         qui su proba if group==1
+         local sumproba1=r(sum)*100
+
+
+         qui drop keep proba
+         local diff0=0
+         qui gen proba=.
+         qui count
+         local nnew=r(N)
+         di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
+         di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
+         local dixj=10
+         forvalues i=1/`nnew' {
+            local dix=floor(`nnew'/10)
+            if mod(`i',`dix')==0 {
+               if "`dixj'"!="10" {
+                  di ".." _c
+               }
+               di "`dixj'%" _c
+               local dixj=`dixj'+10
+            }
+            local int=1
+            forvalues j=1/`nbitems' {
+               qui su item`j' in `i'
+               local rep=r(mean)
+               local diff0=0
+               local diff1=`d'[`j',1]
+               local sum "1+exp(x-`diff1')"
+               forvalues m=2/`=`nbmodat'-1' {
+                  local diff`m'=`diff`=`m'-1''+`d'[`j',`m']
+                  local sum "`sum'+exp(`m'*x-`diff`m'')"
+               }
+               local int "(`int'*exp(`rep'*x-`diff`rep''))/(`sum')"
+            }
+            qui su mean in `i'
+            local mean=r(mean)
+            qui gausshermite `int',mu(`mean') sigma(`=sqrt(`var')') display
+            qui replace proba=r(int) in `i'
+         }
+      }
+   }
+   qui gen eff=.
+   forvalues i=0/1 {
+      qui replace eff=proba*`n`i'' if group==`i'
+   }
+   qui replace eff=proba
+   qui keep item* eff group proba
+
+   local p1=1/`n1'
+   local p0=1/`n0'
+   qui gen eff2=.
+   qui replace eff2=floor(eff/`p1') if group==1
+   qui replace eff2=floor(eff/`p0') if group==0
+   qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
+   qui su eff2 if group==1
+   local aff1=r(sum)
+   qui su eff2 if group==0
+   local aff0=r(sum)
+
+   local unaff1=`n1'-`aff1'
+   local unaff0=`n0'-`aff0'
+   qui gen efftmp=eff2
+   qui gsort + group - eff
+   qui replace eff2=eff2+1 in 1/`unaff0'
+   qui gsort - group - eff
+   qui replace eff2=eff2+1 in 1/`unaff1'
+
+   qui drop if eff2==0
+   gsort group item*
+   qui expand eff2
+   qui drop proba eff eff2
+}
+
+qui alpha item*
+local alpha=r(alpha)
+qui gen groupc=group-.5
+if `nbmodat'==1 {
+   qui gen i=_n
+
+   tempname diff
+   matrix `diff'=`dd''
+
+   qui reshape long item, i(i)
+   qui rename item rep
+   qui rename _j item
+
+   qui gen  offset=0
+   forvalues i=1/`nbitems' {
+      qui replace offset=-`diff'[1,`i'] if item==`i'
+   }
+   matrix est=(`gamma',`=sqrt(`var')')
+
+   if "`gammafix'"=="" {
+      constraint 1 _cons=`=ln(`var')'
+      qui xtlogit rep groupc  ,nocons i(i) offset(offset) constraint(1)
+   }
+   else {
+      qui gllamm   rep groupc, nocons i(i) offset(offset)  iterate(0) fam(bin) link(logit) from(est) copy
+   }
+   tempname b V
+}
+else {
+   matrix `db'=`db''
+   qui pcm item*, fixed(`db') covariates(groupc)  fixedmu fixedvar(`var')
+}
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local gammaest=`b'[1,1]
+local se=`V'[1,1]^.5
+
+
+di
+di
+di in gr "{hline 91}"
+di _col(60)  "Estimation with the "
+di _col(50)  "Cramer-Rao bound" _col(75) "classical formula"
+di in gr "{hline 91}"
+if "`gammafixed'"==""  {
+   di in green "Estimated value of the group effect" _col(59) in ye  %7.2f `gammaest'
+}
+di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
+di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
+local poweruni=1-normal(1.96-`gamma'/`se')
+local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
+di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
+di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
+local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+if `expectedpower'!=-1 {
+   qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
+   local expn_1=r(N_1)
+   local expn_2=r(N_2)
+   local expn2=`expn_1'*`ratio'
+   di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
+}
+di in gr "{hline 91}"
+return scalar EstGamma=`gammaest'
+return scalar CRbound=`=`se'^2'
+return scalar CRPower=`poweruni'
+return scalar ClPower=`clpower'
+return scalar ClSS=`clnsn'
+return scalar Ratio=`ratio'
+return scalar CronbachAlpha=`alpha'
+
+
+
+capture qui use `raschpowerfile',clear
+
+end
diff --git a/Modules/ado/personal/r/old/raschpowers.hlp b/Modules/ado/personal/r/old/raschpowers.hlp
new file mode 100644
index 0000000..eb18771
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschpowers.hlp
@@ -0,0 +1,51 @@
+{smcl}
+{* 7july2011}{...}
+{hline}
+help for {hi:raschpower}{right:Jean-Benoit Hardouin, Myriam Blanchin}
+{hline}
+
+{title:Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals}
+
+{p 8 14 2}{cmd:raschpower} [{cmd:,} {cmdab:n0}({it:#}) {cmdab:n1}({it:#})
+{cmdab:gamma}({it:#}) {cmdab:var}({it:#}) {cmdab:d}({it:vector})]
+
+
+{title:Description}
+
+{p 4 8 2}{cmd:raschpower} allows estimating the power of the Wald test comparing the means of two groups of patients in the context of the Rasch model. The estimation is based on the estimation of the variance of the difference of the means based on the Cramer-Rao bound.
+
+{title:Options}
+
+{p 4 8 2}{cmd:n0} and {cmd:n1} indicates the numbers of individuals in the two groups (100 by default).
+
+{p 4 8 2}{cmd:gamma} indicates the group effect (difference between the two means) [0.5 by default].
+
+{p 4 8 2}{cmd:var} indicates the value of the variance of the latent trait [1 by default].
+
+{p 4 8 2}{cmd:d} is a vector containing the difficulties of the items [one row per item, one column - (-1,-0.5,0,0.5,1)' by default].
+
+{title:Example}
+
+	{p 4 8 2}{cmd:. raschpower}
+
+	{p 4 8 2}{cmd:. raschpower, n0(200) n1(200) gamma(0.4) var(1.3)}
+
+	{p 4 8 2}{cmd:. matrix diff=(-1.47\-0.97\-.23\-0.12\0.02\0.1)}{p_end}
+	{p 4 8 2}{cmd:. raschpower, n0(127) n1(134) gamma(0.23) d(diff) var(2.58)}{p_end}
+
+{title:References}
+
+	{p 4 8 2}Hardouin J.B., Amri S., Feddag M., Sébille V. (2011) Towards Power And Sample Size Calculations For The Comparison Of Two Groups Of Patients With Item Response Theory Models. Accept to appear in Statistics in Medicine. 
+
+	
+{title:Author}
+
+{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
+{p 4 8 2}EA4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"{p_end}
+{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end}
+{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end}
+{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end}
+{p 4 8 2}Email:
+{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end}
+{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol}
+and {browse "http://www.freeirt.org":FreeIRT}
diff --git a/Modules/ado/personal/r/old/raschtest2.ado b/Modules/ado/personal/r/old/raschtest2.ado
new file mode 100644
index 0000000..4a007a4
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschtest2.ado
@@ -0,0 +1,200 @@
+*! version 8  25june2009
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Raschtest: Rasch model, fit tests and graphical validation
+*
+* Historic:
+* Version 1 (2003-06-30): Jean-Benoit Hardouin
+* Version 2 (2003-07-07): Jean-Benoit Hardouin
+* Version 3 (2004-01-02): Jean-Benoit Hardouin
+* Version 4 (2004-01-21): Jean-Benoit Hardouin
+* Version 5 (2004-01-24): Jean-Benoit Hardouin
+* Version 6 (2004-02-05): Jean-Benoit Hardouin
+* Version 6.1 (2004-03-29): Jean-Benoit Hardouin
+* Version 6.2 (2004-04-06): Jean-Benoit Hardouin
+* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin
+* Version 7  (2005-04-02) : Jean-Benoit Hardouin
+* Version 7.2  (2005-05-20) : Jean-Benoit Hardouin
+* Version 7.3  (2005-07-02) : Jean-Benoit Hardouin
+* Version 7.4  (2006-01-15) : Jean-Benoit Hardouin
+* Version 7.5  (2006-04-20) : Jean-Benoit Hardouin
+* Version 7.6  (2008-06-20) : Jean-Benoit Hardouin /*nold option*/
+* Version 8  (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/
+*
+* Needed modules :
+* raschtestv7jf version 8.1 (http://freeirt.free.fr)
+* gammasym version 2.2 (http://www.freeirt.org)
+* gausshermite version 1 (http://www.freeirt.org)
+* geekel2d version 4.3 (http://www.freeirt.org)
+* genscore version 1.4 (http://www.freeirt.org)
+* ghquadm (findit ghquadm)
+* gllamm version 2.3.14 (ssc describe gllamm)
+* gllapred version  2.3.7 (ssc describe gllapred)
+* elapse (ssc describe elapse)
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2003-2009 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+
+program define raschtest2,eclass
+syntax varlist(min=1 numeric) [if] [in] , ID(varname) [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200)  DIFFiculties(string) COVariates(string) ]
+
+local nbitems:word count `varlist'
+if "`method'"=="" {
+   local method "cml"
+}
+else {
+   local method=lower("`method'")
+}
+if "`test'"=="" {
+   local test "R"
+}
+else {
+   local test=upper("`test'")
+}
+if "`dirsave'"!="" {
+   local dirsavev8 "dirsave(`dirsave')"
+}
+if "`method'"!="" {
+   local methodv8 "method(`method')"
+}
+if "`test'"!="" {
+   local testv8 "test(`test')"
+}
+if "`group'"!="" {
+   local groupv8 "group(`group')"
+}
+if "`genlt'"!="" {
+   local genltv8 "genlt(`genlt')"
+}
+if "`genscore'"!="" {
+   local genscorev8 "genscore(`genscore')"
+}
+if "`genfit'"!="" {
+   local genfitv8 "genfit(`genfit')"
+}
+if "`comp'"!="" {
+   local compv8 "comp(`comp')"
+}
+if "`dif'"!="" {
+   local difv8 "dif(`dif')"
+}
+if "`iterate'"!="" {
+   local iteratev8 "iterate(`iterate')"
+}
+if "`difficulties'"!="" {
+   local difficultiesv8 "difficulties(`difficulties')"
+}
+if "`covariates'"!="" {
+   local covariatesv8 "covariates(`covariates')"
+}
+
+raschtestv7jf `varlist' `if' `in' , id(`id') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8'
+
+/***********************************************************************************************************
+RETURN
+************************************************************************************************************/
+
+ereturn clear
+if `nbitems'>=3 {
+	if "`method'"=="cml" {
+	        if "`test'"!="none" {
+                   tempname AndersenZv8
+                   matrix `AndersenZv8'=r(AndersenZ)
+                   ereturn matrix AndersenZ=`AndersenZv8'
+                }
+	        if "`dif'"!="" {
+                   tempname DIFv8
+                   matrix `DIFv8'=r(DIF)
+                   ereturn matrix DIF=`DIFv8'
+                }
+                tempname cllv8
+		scalar `cllv8'=r(cll)
+                ereturn scalar cll=`cllv8'
+
+	}
+	if "`test'"!="NONE" {
+	        tempname itemFitv8 globalFitv8
+	        matrix `itemFitv8'=r(itemFit)
+	        matrix `globalFitv8'=r(globalFit)
+         	ereturn matrix itemFit=`itemFitv8'
+		ereturn matrix globalFit=`globalFitv8'
+	}
+}
+
+if "`method'"!="cml" {
+        tempname sigmav8 sesigmav8
+        local `sigmav8'=`r(sigma)'
+        local `sesigmav8'=`r(sesigma)'
+	ereturn scalar sigma=``sigmav8''
+	ereturn scalar sesigma=``sesigmav8''
+}
+
+tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8
+matrix `betav8'=r(beta)
+matrix `Varbetav8'=r(Varbeta)
+ereturn matrix beta=`betav8'
+ereturn matrix Varbeta=`Varbetav8'
+matrix `thetav8'=r(theta)
+matrix `Varthetav8'=r(Vartheta)
+ereturn matrix theta=`thetav8'
+ereturn matrix Vartheta=`Varthetav8'
+scalar `llv8'=`r(ll)'
+scalar `AICv8'=`r(AIC)'
+ereturn scalar ll=`llv8'
+ereturn scalar AIC=`AICv8'
+ereturn scalar Zcomp=r(Zcomp)
+ereturn scalar pZcomp=r(pZcomp)
+
+
+if "`method'"=="mml" {
+   local psi=r(PSI)
+   local psiadj=r(PSIadj)
+   ereturn scalar PSI=`psi'
+   ereturn scalar PSIadj=`psiadj'
+}
+if "`covariates'"!="" {
+   tempname betacovariates Vbetacovariates zcovariates pcovariates
+   matrix `betacovariates'=r(betacovariates)
+   matrix `Vbetacovariates'=r(Vbetacovariates)
+   matrix `zcovariates'=r(zcovariates)
+   matrix `pcovariates'=r(pcovariates)
+
+   ereturn matrix betacovariates=`betacovariates'
+   ereturn matrix Vbetacovariates=`Vbetacovariates'
+   ereturn matrix zcovariates=`zcovariates'
+   ereturn matrix pcovariates=`pcovariates'
+}
+
+
+
+
+return clear
+
+end
diff --git a/Modules/ado/personal/r/old/raschtest82.ado b/Modules/ado/personal/r/old/raschtest82.ado
new file mode 100644
index 0000000..b443c36
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschtest82.ado
@@ -0,0 +1,200 @@
+*! version 8  25june2009
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Raschtest: Rasch model, fit tests and graphical validation
+*
+* Historic:
+* Version 1 (2003-06-30): Jean-Benoit Hardouin
+* Version 2 (2003-07-07): Jean-Benoit Hardouin
+* Version 3 (2004-01-02): Jean-Benoit Hardouin
+* Version 4 (2004-01-21): Jean-Benoit Hardouin
+* Version 5 (2004-01-24): Jean-Benoit Hardouin
+* Version 6 (2004-02-05): Jean-Benoit Hardouin
+* Version 6.1 (2004-03-29): Jean-Benoit Hardouin
+* Version 6.2 (2004-04-06): Jean-Benoit Hardouin
+* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin
+* Version 7  (2005-04-02) : Jean-Benoit Hardouin
+* Version 7.2  (2005-05-20) : Jean-Benoit Hardouin
+* Version 7.3  (2005-07-02) : Jean-Benoit Hardouin
+* Version 7.4  (2006-01-15) : Jean-Benoit Hardouin
+* Version 7.5  (2006-04-20) : Jean-Benoit Hardouin
+* Version 7.6  (2008-06-20) : Jean-Benoit Hardouin /*nold option*/
+* Version 8  (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/
+*
+* Needed modules :
+* raschtestv7 version 8.1 (http://freeirt.free.fr)
+* gammasym version 2.2 (http://www.freeirt.org)
+* gausshermite version 1 (http://www.freeirt.org)
+* geekel2d version 4.3 (http://www.freeirt.org)
+* genscore version 1.4 (http://www.freeirt.org)
+* ghquadm (findit ghquadm)
+* gllamm version 2.3.14 (ssc describe gllamm)
+* gllapred version  2.3.7 (ssc describe gllapred)
+* elapse (ssc describe elapse)
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2003-2009 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+
+program define raschtest,eclass
+syntax varlist(min=1 numeric) [if] [in] , ID(varname) [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200)  DIFFiculties(string) COVariates(string) ]
+
+local nbitems:word count `varlist'
+if "`method'"=="" {
+   local method "cml"
+}
+else {
+   local method=lower("`method'")
+}
+if "`test'"=="" {
+   local test "R"
+}
+else {
+   local test=upper("`test'")
+}
+if "`dirsave'"!="" {
+   local dirsavev8 "dirsave(`dirsave')"
+}
+if "`method'"!="" {
+   local methodv8 "method(`method')"
+}
+if "`test'"!="" {
+   local testv8 "test(`test')"
+}
+if "`group'"!="" {
+   local groupv8 "group(`group')"
+}
+if "`genlt'"!="" {
+   local genltv8 "genlt(`genlt')"
+}
+if "`genscore'"!="" {
+   local genscorev8 "genscore(`genscore')"
+}
+if "`genfit'"!="" {
+   local genfitv8 "genfit(`genfit')"
+}
+if "`comp'"!="" {
+   local compv8 "comp(`comp')"
+}
+if "`dif'"!="" {
+   local difv8 "dif(`dif')"
+}
+if "`iterate'"!="" {
+   local iteratev8 "iterate(`iterate')"
+}
+if "`difficulties'"!="" {
+   local difficultiesv8 "difficulties(`difficulties')"
+}
+if "`covariates'"!="" {
+   local covariatesv8 "covariates(`covariates')"
+}
+
+raschtestv7 `varlist' `if' `in' , id(`id') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8'
+
+/***********************************************************************************************************
+RETURN
+************************************************************************************************************/
+
+ereturn clear
+if `nbitems'>=3 {
+	if "`method'"=="cml" {
+	        if "`test'"!="none" {
+                   tempname AndersenZv8
+                   matrix `AndersenZv8'=r(AndersenZ)
+                   ereturn matrix AndersenZ=`AndersenZv8'
+                }
+	        if "`dif'"!="" {
+                   tempname DIFv8
+                   matrix `DIFv8'=r(DIF)
+                   ereturn matrix DIF=`DIFv8'
+                }
+                tempname cllv8
+		scalar `cllv8'=r(cll)
+                ereturn scalar cll=`cllv8'
+
+	}
+	if "`test'"!="NONE" {
+	        tempname itemFitv8 globalFitv8
+	        matrix `itemFitv8'=r(itemFit)
+	        matrix `globalFitv8'=r(globalFit)
+         	ereturn matrix itemFit=`itemFitv8'
+		ereturn matrix globalFit=`globalFitv8'
+	}
+}
+
+if "`method'"!="cml" {
+        tempname sigmav8 sesigmav8
+        local `sigmav8'=`r(sigma)'
+        local `sesigmav8'=`r(sesigma)'
+	ereturn scalar sigma=``sigmav8''
+	ereturn scalar sesigma=``sesigmav8''
+}
+
+tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8
+matrix `betav8'=r(beta)
+matrix `Varbetav8'=r(Varbeta)
+ereturn matrix beta=`betav8'
+ereturn matrix Varbeta=`Varbetav8'
+matrix `thetav8'=r(theta)
+matrix `Varthetav8'=r(Vartheta)
+ereturn matrix theta=`thetav8'
+ereturn matrix Vartheta=`Varthetav8'
+scalar `llv8'=`r(ll)'
+scalar `AICv8'=`r(AIC)'
+ereturn scalar ll=`llv8'
+ereturn scalar AIC=`AICv8'
+ereturn scalar Zcomp=r(Zcomp)
+ereturn scalar pZcomp=r(pZcomp)
+
+
+if "`method'"=="mml" {
+   local psi=r(PSI)
+   local psiadj=r(PSIadj)
+   ereturn scalar PSI=`psi'
+   ereturn scalar PSIadj=`psiadj'
+}
+if "`covariates'"!="" {
+   tempname betacovariates Vbetacovariates zcovariates pcovariates
+   matrix `betacovariates'=r(betacovariates)
+   matrix `Vbetacovariates'=r(Vbetacovariates)
+   matrix `zcovariates'=r(zcovariates)
+   matrix `pcovariates'=r(pcovariates)
+
+   ereturn matrix betacovariates=`betacovariates'
+   ereturn matrix Vbetacovariates=`Vbetacovariates'
+   ereturn matrix zcovariates=`zcovariates'
+   ereturn matrix pcovariates=`pcovariates'
+}
+
+
+
+
+return clear
+
+end
diff --git a/Modules/ado/personal/r/old/raschtest83.ado b/Modules/ado/personal/r/old/raschtest83.ado
new file mode 100644
index 0000000..be65556
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschtest83.ado
@@ -0,0 +1,204 @@
+*! version 8.3  15june2010
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Raschtest: Rasch model, fit tests and graphical validation
+*
+* Historic:
+* Version 1 (2003-06-30): Jean-Benoit Hardouin
+* Version 2 (2003-07-07): Jean-Benoit Hardouin
+* Version 3 (2004-01-02): Jean-Benoit Hardouin
+* Version 4 (2004-01-21): Jean-Benoit Hardouin
+* Version 5 (2004-01-24): Jean-Benoit Hardouin
+* Version 6 (2004-02-05): Jean-Benoit Hardouin
+* Version 6.1 (2004-03-29): Jean-Benoit Hardouin
+* Version 6.2 (2004-04-06): Jean-Benoit Hardouin
+* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin
+* Version 7  (2005-04-02) : Jean-Benoit Hardouin
+* Version 7.2  (2005-05-20) : Jean-Benoit Hardouin
+* Version 7.3  (2005-07-02) : Jean-Benoit Hardouin
+* Version 7.4  (2006-01-15) : Jean-Benoit Hardouin
+* Version 7.5  (2006-04-20) : Jean-Benoit Hardouin
+* Version 7.6  (2008-06-20) : Jean-Benoit Hardouin /*nold option*/
+* Version 8  (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/
+* Version 8.3  (2009-06-20) : Jean-Benoit Hardouin /*GENRES option*/
+*
+* Needed modules :
+* raschtestv7 version 8.1 (http://freeirt.free.fr)
+* gammasym version 2.2 (http://www.freeirt.org)
+* gausshermite version 1 (http://www.freeirt.org)
+* geekel2d version 4.3 (http://www.freeirt.org)
+* genscore version 1.4 (http://www.freeirt.org)
+* ghquadm (findit ghquadm)
+* gllamm version 2.3.14 (ssc describe gllamm)
+* gllapred version  2.3.7 (ssc describe gllapred)
+* elapse (ssc describe elapse)
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2003-2009 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+
+program define raschtest,eclass
+syntax varlist(min=1 numeric) [if] [in] , ID(varname) [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200)  DIFFiculties(string) COVariates(string) GENRes(string)]
+
+local nbitems:word count `varlist'
+if "`method'"=="" {
+   local method "cml"
+}
+else {
+   local method=lower("`method'")
+}
+if "`test'"=="" {
+   local test "R"
+}
+else {
+   local test=upper("`test'")
+}
+if "`dirsave'"!="" {
+   local dirsavev8 "dirsave(`dirsave')"
+}
+if "`method'"!="" {
+   local methodv8 "method(`method')"
+}
+if "`test'"!="" {
+   local testv8 "test(`test')"
+}
+if "`group'"!="" {
+   local groupv8 "group(`group')"
+}
+if "`genlt'"!="" {
+   local genltv8 "genlt(`genlt')"
+}
+if "`genscore'"!="" {
+   local genscorev8 "genscore(`genscore')"
+}
+if "`genres'"!="" {
+   local gensresv8 "genres(`genres')"
+}
+if "`genfit'"!="" {
+   local genfitv8 "genfit(`genfit')"
+}
+if "`comp'"!="" {
+   local compv8 "comp(`comp')"
+}
+if "`dif'"!="" {
+   local difv8 "dif(`dif')"
+}
+if "`iterate'"!="" {
+   local iteratev8 "iterate(`iterate')"
+}
+if "`difficulties'"!="" {
+   local difficultiesv8 "difficulties(`difficulties')"
+}
+if "`covariates'"!="" {
+   local covariatesv8 "covariates(`covariates')"
+}
+
+raschtestv7 `varlist' `if' `in' , id(`id') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genresv8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8'
+
+/***********************************************************************************************************
+RETURN
+************************************************************************************************************/
+
+ereturn clear
+if `nbitems'>=3 {
+	if "`method'"=="cml" {
+	        if "`test'"!="none" {
+                   tempname AndersenZv8
+                   matrix `AndersenZv8'=r(AndersenZ)
+                   ereturn matrix AndersenZ=`AndersenZv8'
+                }
+	        if "`dif'"!="" {
+                   tempname DIFv8
+                   matrix `DIFv8'=r(DIF)
+                   ereturn matrix DIF=`DIFv8'
+                }
+                tempname cllv8
+		scalar `cllv8'=r(cll)
+                ereturn scalar cll=`cllv8'
+
+	}
+	if "`test'"!="NONE" {
+	        tempname itemFitv8 globalFitv8
+	        matrix `itemFitv8'=r(itemFit)
+	        matrix `globalFitv8'=r(globalFit)
+         	ereturn matrix itemFit=`itemFitv8'
+		ereturn matrix globalFit=`globalFitv8'
+	}
+}
+
+if "`method'"!="cml" {
+        tempname sigmav8 sesigmav8
+        local `sigmav8'=`r(sigma)'
+        local `sesigmav8'=`r(sesigma)'
+	ereturn scalar sigma=``sigmav8''
+	ereturn scalar sesigma=``sesigmav8''
+}
+
+tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8
+matrix `betav8'=r(beta)
+matrix `Varbetav8'=r(Varbeta)
+ereturn matrix beta=`betav8'
+ereturn matrix Varbeta=`Varbetav8'
+matrix `thetav8'=r(theta)
+matrix `Varthetav8'=r(Vartheta)
+ereturn matrix theta=`thetav8'
+ereturn matrix Vartheta=`Varthetav8'
+scalar `llv8'=`r(ll)'
+scalar `AICv8'=`r(AIC)'
+ereturn scalar ll=`llv8'
+ereturn scalar AIC=`AICv8'
+ereturn scalar Zcomp=r(Zcomp)
+ereturn scalar pZcomp=r(pZcomp)
+
+
+if "`method'"=="mml" {
+   local psi=r(PSI)
+   local psiadj=r(PSIadj)
+   ereturn scalar PSI=`psi'
+   ereturn scalar PSIadj=`psiadj'
+}
+if "`covariates'"!="" {
+   tempname betacovariates Vbetacovariates zcovariates pcovariates
+   matrix `betacovariates'=r(betacovariates)
+   matrix `Vbetacovariates'=r(Vbetacovariates)
+   matrix `zcovariates'=r(zcovariates)
+   matrix `pcovariates'=r(pcovariates)
+
+   ereturn matrix betacovariates=`betacovariates'
+   ereturn matrix Vbetacovariates=`Vbetacovariates'
+   ereturn matrix zcovariates=`zcovariates'
+   ereturn matrix pcovariates=`pcovariates'
+}
+
+
+
+
+return clear
+
+end
diff --git a/Modules/ado/personal/r/old/raschtestv7732.ado b/Modules/ado/personal/r/old/raschtestv7732.ado
new file mode 100644
index 0000000..eb90c63
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschtestv7732.ado
@@ -0,0 +1,1743 @@
+*! version 7.3.2  5october2005
+************************************************************************************************************
+* Raschtestv7: Rasch model, fit tests and graphical representations
+* Corresponds to the version 7.3 of Raschtest (http://freeirt.free.fr) for Stata7
+*
+* Version 7.3.2 (Stata 7.0) : July 2, 2005 /*correction for the *genlt* option with *method(cml)**/
+*
+* Historic:
+* Version 2.1 (2003-07-10): Jean-Benoit Hardouin
+* Version 3.1 (2004-01-02) : Jean-Benoit Hardouin
+* Version 7.1 (2005-03-30) : Jean-Benoit Hardouin
+* Version 7.2.1 (2005-05-21) : Jean-Benoit Hardouin
+* Version 7.3.1 (2005-07-02) : Jean-Benoit Hardouin
+*
+* Needed modules :
+* gammasym version 2.1 (http://freeirt.free.fr)
+* gausshermite version 1 (http://freeirt.free.fr)
+* geekel2d version 4.2 (http://freeirt.free.fr)
+* ghquadm (findit ghquadm)
+* gllamm version 2.3.10 (ssc describe gllamm)
+* gllapred version  2.3.2 (ssc describe gllapred)
+* elapse (ssc describe elapse)
+*
+* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France
+* jean-benoit.hardouin@orscentre.org
+*
+* News about this program : http://anaqol.free.fr
+* FreeIRT Project : http://freeirt.free.fr
+*
+* Copyright 2003-2005 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+DEFINITION / SYNTAX
+***********************************************************************************************************/
+
+
+program define raschtestv7,rclass
+syntax varlist(min=1 numeric) [if] [in] , [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph v8 COMp(varname) time TRace Details Explain ]
+
+
+/***********************************************************************************************************
+EXPLAIN OPTION
+***********************************************************************************************************/
+
+if "`explain'"!="" {
+
+   di in green "{hline}"
+   di in green "{title:ESTIMATION METHODS} (define by the {cmd:method} option)"
+   di in green "{hline}"
+   di
+   di in green "{p 0 0 0}{hi:CML : Conditional Maximum Likelihood} ({cmd:method(cml)}) {p_end}"
+   di in green "{p 4 4 2}The latent trait is considered as a set of fixed parameters, and the difficulty parameters are estimated conditionnally to them{p_end}"
+   di in green "{p 4 4 2}The identifiability constraint consit to fix the difficulty parameter of the last item to 0{p_end}"
+   di in green "{p 0 0 0}{hi:MML : Marginal Maximum Likelihood} ({cmd:method(mml)}){p_end}"
+   di in green "{p 4 4 2}The latent trait is considered as a random variable, and the difficulty parameters are estimated marginally to it{p_end}"
+   di in green "{p 4 4 2}The identifiability constraint consit to fix the mean fo the latent trait to 0{p_end}"
+   di in green "{p 0 0 0}{hi:GEE : Generalized Estimating Equation} ({cmd:method(gee)}){p_end}"
+   di in green "{p 4 4 2}Same assumption than for the MML technic.{p_end}"
+   di
+   di in green "{hline}"
+   di in green "{title:NOTATIONS} "
+   di in green "{hline}"
+   di
+   di in green "{p 0 0 0}{hi :J} is the number of items.{p_end}"
+   di in green "{p 0 0 0}{hi :N} is the number of individuals.{p_end}"
+   di in green "{p 0 0 0}{hi :N_c} is the number of individuals with a score different of 0 and of J.{p_end}"
+   di in green "{p 0 0 0}{hi :G} is the number of number of groups of scores.{p_end}"
+   di
+   di in green "{hline}"
+   di in green "{title:TESTS} "
+   di in green "{hline}"
+   di
+   di in green "{p 0 0 0}{hi: General test}{p_end}"
+   di in green "{p 4 4 2}The {hi: Andersen test} consit to test if the difficulty parameters of the items are the same values in estimating them in each subgroups of individuals defined by the values of the score (who can be grouped by the {cmd:group} or {cmd:autogroup} options). This test is only available with CML technic.{p_end}"
+   di
+   di in green "{p 0 0 0}{hi: Tests of the first order}{p_end} (defined by the {cmd:test} option)"
+   di in green "{p 4 4 2}The {hi: Wright Panchapakesan test}, the {hi:Q1 test}, the {hi:R1c test} and the {hi:R1m test} consist to test the adequation  between the observed and the theorical number of positive responses to each item in each group of scores (defined by the {cmd:group} or {cmd:autogroup} options). The differences between the tests are explained by the method to estimate the theorical number of positive response in each group of scores, and by the definition of the covariance matrix between these theorical numbers. {p_end}"
+   di in green "{p 4 4 2}{hi: The Wright Panchapakesan test} ({cmd:test(WP)})  consist to estimate the number of positive responses to each item in function of the estimations of the difficulty parameters and of the individual values of the latent trait. The covariance matrix between these estimations is a diagonal matrix. {p_end}"
+   di in green "{p 4 4 2}{hi:The Van den Wollenberg Q1 test} ({cmd:test(Q)}) consist to estimate the number of positive responses to each item only in function of the estimations of the difficulty parameters. The covariance matrix between these estimations is a diagonal matrix.{p_end}"
+   di in green "{p 4 4 2}{hi:The R1c test} ({cmd:test(R)}) consist to estimate the number of positive responses to each item only in function of the estimations of the difficulty parameters. The covariance matrix between these estimations is no more a diagonal matrix. This test is available only with a CML technic of estimation of the parameters.{p_end}"
+   di in green "{p 4 4 2}{hi:The R1m test} ({cmd:test(R)}) is the same test than the R1c test, except that the individuals with a nul score or a perfect score are considered. This test is available with the MML or the GEE technic of estimation of the parameters.{p_end}"
+   di
+   di in green "{p 0 0 0}{hi:Others Tests and indexes}{p_end}"
+   di in green "{p 4 4 2}{hi:The split test} (obtained by the {cmd:splittest} option) consists to estimate the parameters of the items conditionnaly to the response to one of them. We can test the global difference between the two estimated vectors of parameters with the Andersen LR Z test. This test allows detecting dependent items.{p_end}"
+   di in green "{p 4 4 2}{hi:The U test} allows detecting items with low or high discriminating powers. The U statistics follow a standardized gaussian distribution, and a significant positive value signifies that the slope of the item is too low (compared to the others items) and a significant negative value signifies that the slope of the item is too high (compared to the others). {p_end}"
+   di in green "{p 4 4 2}{hi:The OUTFIT and INFIT} (graphs obtained by the {cmd:fitgraph} option) indexes allows detecting items with a baf fit. The values of these two indexes must be in the interval [.6;1.4].{p_end}"
+
+   di
+
+   exit
+}
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Tests of conformity"
+}
+if "`v8'"=="" {
+        version 7.0
+}
+else {
+        version 8.0
+}
+
+local st = "$S_TIME"
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+tokenize `varlist'
+
+
+if "`method'"=="" {
+    local method cml
+}
+if "`test'"=="" {
+    local test R
+}
+local method=lower("`method'")
+local test=upper("`test'")
+if "`method'"!="mml"&"`method'"!="cml"&"`method'"!="gee" {
+    di in red "Uncorrect method option."
+    error 198
+    exit
+}
+
+if "`test'"!="R"&"`test'"!="Q"&"`test'"!="WP"&"`test'"!="NONE" {
+   di in red "Uncorrect test option."
+   error 198
+   exit
+}
+
+if "`genfit'"!="" {
+   local nbwordgenfit:word count `genfit'
+   if `nbwordgenfit'!=2 {
+      di in red "Uncorrect genfit option."
+      di in red "This option must contain exactly two words"
+      error 198
+      exit
+   }
+}
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+   confirm new variable `genfit' `genlt' `genscore'
+   if "`genfit'"!="" {
+      local o:word 1 of `genfit'
+      forvalues i=1/`nbitems' {
+         confirm new variable `o'``i''
+      }
+   }
+}
+
+preserve
+
+tempfile saveraschtest
+qui save `saveraschtest'
+
+if "`autogroup'"!=""&"`group'"!="" {
+   di in green "The autogroup and the group options cannot be defined in the same time"
+   di in green "Only the group option is retained."
+   local autogroup
+}
+
+if "`autogroup'"!="" {
+   tempvar autoscore
+   qui gen `autoscore'=0
+   forvalues i=1/`nbitems' {
+       qui replace `autoscore'=`autoscore'+``i''
+   }
+   tempname matscore tmp
+   *qui tab `autoscore', matcell(`tmp')
+   matrix `matscore'=J(`=`nbitems'-1',3,0)
+   forvalues i=1/`=`nbitems'-1' {
+        matrix `matscore'[`i',1]=`i'
+        matrix `matscore'[`i',2]=`i'
+        qui count if `autoscore'==`i'
+        matrix `matscore'[`i',3]=r(N)
+   }
+   local stop=0
+   local j=0
+   while `j'<=`=`nbitems'-3'&`stop'!=1 {
+      local j=`j'+1
+      local scoretogroup=99999999
+      local rowtogroup1=0
+      local rowtogroup2=0
+      local stop=1
+      forvalues i=1/`=`nbitems'-`j'' {
+         if `matscore'[`i',1]>=0 & `matscore'[`i',3]<30 & `matscore'[`i',3]<`scoretogroup' {
+            local scoretogroup=`matscore'[`i',3]
+            local rowtogroup1=`i'
+            local stop=0
+         }
+      }
+      if `stop'!=1 {
+         if `rowtogroup1'>1&`rowtogroup1'<`=`nbitems'-`j'' {
+            if `matscore'[`=`rowtogroup1'-1',1]<`matscore'[`=`rowtogroup1'+1',1] {
+               local rowtogroup2=`rowtogroup1'
+               local rowtogroup1=`rowtogroup1'-1
+            }
+            else {
+               local rowtogroup2=`rowtogroup1'+1
+            }
+         }
+         else if `rowtogroup1'==1 {
+            local rowtogroup2=2
+         }
+         else if `rowtogroup1'==`=`nbitems'-`j'' {
+            local rowtogroup2=`nbitems'-`j'
+            local rowtogroup1=`nbitems'-`j'-1
+         }
+         matrix `tmp'=`matscore'
+         matrix `matscore'=J(`=`nbitems'-`j'',3,0)
+         if `rowtogroup1'!=1 {
+            matrix `matscore'[1,1]=`tmp'[1..`=`rowtogroup1'-1',1..3]
+         }
+         matrix `matscore'[`rowtogroup1',1]=`tmp'[`rowtogroup1',1]
+         matrix `matscore'[`rowtogroup1',2]=`tmp'[`rowtogroup2',2]
+         matrix `matscore'[`rowtogroup1',3]=`tmp'[`rowtogroup1',3]+`tmp'[`rowtogroup2',3]
+         if `rowtogroup2'!=`=`nbitems'-`j'' {
+            matrix `matscore'[`rowtogroup2',1]=`tmp'[`=`rowtogroup2'+1'..`=`nbitems'-`j'',1..3]
+         }
+      }
+   }
+   local nbrows=rowsof(`matscore')-1
+   local thresholds
+   forvalues i=1/`nbrows' {
+      local tmp=`matscore'[`i',2]
+      local thresholds `thresholds' `tmp'
+   }
+   local group `thresholds'
+}
+
+
+if "`group'"=="" {
+	forvalues i=1/`=`nbitems'-1' {
+		local group "`group' `i'"
+	}
+}
+local nbgroups:word count `group'
+local groupmax:word `nbgroups' of `group'
+if `groupmax'>=`nbitems' {
+	di in red "You cannot form a group with the higher possible score."
+	di in red "The higher possible value of the group option is `=`nbitems'-1'."
+        di in red "Please correct your group option."
+	error 198
+        exit
+}
+else {
+	if `groupmax'!=`=`nbitems'-1' {
+		local group "`group' `=`nbitems'-1'"
+		local nbgroups=`nbgroups'+1
+	}
+}
+if "`comp'"!=""&"`method'"=="cml" {
+   	di in red "You cannot compare two populations with the CML estimation method"
+   	di in red "Use another method of estimation."
+        error 198
+        exit
+}
+local nbgroups=`nbgroups'+1
+
+if "`dirsave'"!=""&"`filessave'"=="" {
+        di in ye "If you want to save yours graphs, use the filessave option"
+}
+if "`filessave'"!="" {
+        if "`dirsave'"=="" {
+              local dirsave "`c(pwd)'"
+        }
+        di in ye "The graphs files will be saved in `dirsave'"
+}
+if "`dirsave'"!="" {
+        if "`filesave'"=="" {
+              local filesave "filesave"
+        }
+}
+
+
+if "`pause'"!=""&"`draw'"=="" {
+     pause on
+}
+
+
+/***********************************************************************************************************
+POSSIBLE TEST
+***********************************************************************************************************/
+
+if ("`icc'"!=""|"`fitgraph'"!=""|"`splittest'"!=""|"`details'"!="")&"`test'"=="NONE" {
+	di in green "You cannot use the details, icc, fitgraph or splittest if you use test(none)."
+        di in green "These options are ignored."
+	local icc
+	local fitgraph
+	local splittest
+}
+if "`method'"!="cml"&"`test'"=="WP" {
+	di in green "The Wright-Panchapakesan test is not authorized with MML or GEE."
+	di in green "The WP tests are replaced by Van den Wollenberg Q tests."
+        local test Q
+}
+
+
+if "`test'"==""|"`test'"=="R" {
+   local test "R"
+   if "`method'"=="cml" {
+      local namewp "R1c"
+      local descwp "R1c test"
+   }
+   else {
+      local namewp="R1m"
+      local descwp "R1m test"
+   }
+}
+if `nbitems'>999999|"`test'"=="WP" {
+	local namewp "  Y"
+	local descwp "Wright-Panchapakesan Y test"
+	local q2
+}
+ else if "`test'"=="Q" {
+	local namewp " Q1"
+	local descwp "Van den Wollenberg Q1 test"
+}
+
+if "`method'"!="cml"&"`meandiff'"!="" {
+	di in green "The MEANDIFF option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local meandiff
+}
+
+if "`method'"!="cml"&"`splittests'"!="" {
+	di in green "The SPLITTESTS option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local splittests
+}
+
+/***********************************************************************************************************
+SCORES AND GROUPS
+************************************************************************************************************/
+
+qui count if `touse'==1
+local N=r(N)
+
+tempvar id
+gen `id'=_n
+
+qui keep if `touse'==1
+
+qui keep `varlist' `comp' `id'
+
+tempname rep item
+tempvar score realscore
+gen `score'=0
+
+
+forvalues i=1/`nbitems' {
+	rename ``i'' `rep'`i'
+	qui drop if `rep'`i'==.|`rep'`i'>1
+	qui replace `score'=`score'+`rep'`i'
+}
+
+
+
+local liminf0=0
+local limsup0=0
+local liminf`nbgroups'=`nbitems'
+local limsup`nbgroups'=`nbitems'
+
+
+local recode
+forvalues i=1/`=`nbgroups'-1' {
+	if `i'!= 1{
+		local liminf`i' : word `=`i'-1' of `group'
+	}
+	else {
+		local liminf1=0
+	}
+	local liminf`i'=`liminf`i''+1
+	local limsup`i':word `i' of `group'
+
+	local recode "`recode' `liminf`i''/`limsup`i''=`i'"
+}
+qui gen `realscore'=`score'
+qui recode `score' `recode' `nbitems'=`nbgroups'
+
+local smallgroup=0
+
+forvalues i=0/`nbgroups' {
+	qui count if `score'==`i'
+	local effscore`i'=r(N)
+	if `i'!=0&`i'!=`nbgroups'&`effscore`i''<30 {
+		local smallgroup=1
+	}
+}
+/***********************************************************************************************************
+ESTIMATION OF THE DIFFICULTY PARAMETERS
+************************************************************************************************************/
+if "`trace'"!="" {
+  di in green "*** Estimation of the difficulty parameters"
+}
+
+tempname ll coef var beta Vbeta est
+
+if "`method'"=="gee" {
+   qui geekel2d `rep'1-`rep'`nbitems',ll
+   if `r(error)'==1 {
+       di "The variance of the latent trait probably is too high to made the GEE a efficient method to estimate the parameters."
+       error 499
+       exit
+   }
+   scalar `ll'=r(ll)
+   local nbind=r(N)
+   matrix `coef'=r(b)
+   matrix `est'=`coef'
+   matrix `est'[1,`=`nbitems'+1']=sqrt(`est'[1,`=`nbitems'+1'])
+   matrix `var'=r(V)
+   matrix `beta'=`coef'[1,1..`nbitems']
+   matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+   local sig=sqrt(`coef'[1,`=`nbitems'+1'])
+   local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])/sqrt(`nbind')/(`sig'*2)
+}
+
+qui reshape long `rep' , i(`id') j(`item')
+
+tempvar diff tl
+gen `diff'=0
+
+forvalues i=1/`nbitems' {
+	qui gen `rep'`i'=`item'==`i'
+	qui replace `rep'`i'=-`rep'`i'
+}
+
+
+if "`method'"=="mml" {
+   qui xtlogit `rep' `rep'1-`rep'`nbitems', i(`id') nocons
+   matrix `est'=e(b)
+   matrix `est'[1,`=`nbitems'+1']=exp(`est'[1,`=`nbitems'+1']/2)
+}
+else if "`method'"=="cml" {
+	qui clogit `rep' `rep'1-`rep'`=`nbitems'-1', group(`id')
+}
+
+if "`method'"!="gee" {
+   matrix `coef'=e(b)
+   scalar `ll'=e(ll)
+   local nbind=e(N)/`nbitems'
+   matrix `var'=e(V)
+
+
+   if "`meandiff'"!="" {
+      matrix `var'=J(`nbitems',`nbitems',.)
+      matrix `coef'=J(1,`nbitems',.)
+      local param
+      local lin `rep'1
+      forvalues j=2/`=`nbitems'-1' {
+         local lin `lin'+`rep'`j'
+      }
+      local lin (`lin')/`nbitems'
+
+      forvalues j=1/`=`nbitems'-1' {
+         qui lincom `rep'`j'-`lin'
+         matrix `coef'[1,`j']=`r(estimate)'
+         matrix `var'[`j',`j']=`r(se)'^2
+      }
+      qui lincom -`lin'
+      matrix `coef'[1,`nbitems']=`r(estimate)'
+      matrix `var'[`nbitems',`nbitems']=`r(se)'^2
+   }
+   if "`method'"=="mml" {
+	local sig=e(sigma_u)
+	local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])*`sig'/2
+	matrix `beta'=`coef'[1,1..`nbitems']
+	matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+   }
+   else if "`method'"=="cml"&"`meandiff'"==""{
+	matrix `beta'=`coef'[1,1..`=`nbitems'-1']
+	matrix `Vbeta'=`var'[1..`=`nbitems'-1',1..`=`nbitems'-1']
+   }
+   else if "`method'"=="cml"&"`meandiff'"!=""{
+	matrix `beta'=`coef'
+	matrix `Vbeta'=`var'
+   }
+}
+
+if ("`method'"=="mml"|"`method'"=="gee") {
+   local colnames
+   forvalues i=1/`nbitems' {
+      local colnames "`colnames' `rep':`rep'`i'"
+   }
+   local id2=substr("`id'",1,4)
+   local colnames "`colnames' `id2'1:_cons"
+   matrix colnames `est'=`colnames'
+   /************************************
+   A VIRER DEBUT
+   ****************************************/
+   /*
+   tempfile jbh
+   save `jbh',replace
+   set trace on
+   rename `rep' rep
+   forvalues i=1/`nbitems' {
+   rename `rep'`i' rep`i'
+   }
+   rename `id' id
+   matrix est=`est'
+   keep rep* id
+   save c:\ado\jbh.dta,replace
+   set trace off
+   use `jbh',replace
+   */
+   /************************************
+   A VIRER FIN
+   ****************************************/
+
+
+   capture gllamm `rep' `rep'1-`rep'`nbitems', i(`id') nocons family(binom) link(logit) trace from(`est') eval
+   tempname u
+   qui gllapred `u',u
+   tempname theta sdtheta
+   matrix `theta'=J(1,`=`nbitems'+1',0)
+   matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',0)
+   forvalues s=0/`nbitems' {
+      qui su `u'm1 if `realscore'==`s'
+      local theta`s'=r(mean)
+      qui su `u's1 if `realscore'==`s'
+      local sdtheta`s'=r(mean)
+      matrix `theta'[1,`=`s'+1']=`theta`s''
+      matrix `sdtheta'[`=`s'+1',`=`s'+1']=`sdtheta`s''
+   }
+}
+
+forvalues i=1/`nbitems' {
+	if `i'==`nbitems'&"`method'"=="cml"&"`meandiff'"=="" {
+		local beta`i'=0
+		local sd`i' .
+		local fixed`i' "*"
+	}
+	else {
+		local beta`i'=`coef'[1,`i']
+		local sd`i'=sqrt(`var'[`i',`i'])
+	}
+	qui replace `diff'=-`beta`i'' if `item'==`i'
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATIONS
+***********************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+   if "`trace'"!="" {
+     di in green "*** Test of comparison of two populations"
+   }
+         qui inspect `comp'
+         local unique=r(N_unique)
+         if `unique'== 2 {
+		qui su `comp'
+		local mincomp=r(min)
+		local maxcomp=r(max)
+	    	tempname bmin bmax
+	    	qui xtlogit `rep' if `comp'==`mincomp',offset(`diff') i(`id')
+	    	matrix `bmin'=e(b)
+	    	local meanmin=`bmin'[1,1]
+	    	local varmin=e(sigma_u)^2
+	    	local llmin=e(ll)
+	    	local Nmin=e(N_g)
+	    	qui xtlogit `rep' if `comp'==`maxcomp',offset(`diff') i(`id')
+	    	matrix `bmax'=e(b)
+	    	local meanmax=`bmax'[1,1]
+	    	local varmax=e(sigma_u)^2
+	    	local llmax=e(ll)
+	    	local Nmax=e(N_g)
+	    	local Zcomp=(`meanmin'-`meanmax')/sqrt(`varmin'/`Nmin'+`varmax'/`Nmax')
+		local pvalue=1-norm(abs(`Zcomp'))
+	 }
+	 else {
+	        di "It is impossible to compare more than two populations"
+	        di "The comparison process is not run"
+	        local comp
+	 }
+}
+
+/***********************************************************************************************************
+ESTIMATION OF THE ABILITY PARAMETERS
+************************************************************************************************************/
+if `nbitems'>=2 {
+   if "`trace'"!="" {
+      di in green "*** Estimation of the ability parameters"
+   }
+   if "`method'"=="cml" {
+      tempfile verytmp
+      qui save `verytmp',replace
+      drop _all
+      qui set obs 10001
+      qui gen theta=(_n-5001)/1000
+      qui gen A=1
+      *set trace on
+      forvalues j=1/`nbitems' {
+         qui gen u`j'=exp(theta-`beta`j'')
+         qui gen p`j'=u`j'/(1+u`j')
+         qui gen a`j'=1/u`j'
+         qui replace A=A*a`j'
+         qui gen i`j'=u`j'/(1+u`j')^2
+         qui gen j`j'=(u`j'*(1-u`j'))/(1+u`j')^3
+      }
+      qui egen P=rsum(p*)
+      qui egen I=rsum(i*)
+      qui egen J=rsum(j*)
+      qui gen V=1/I^2*(I+J^2)/(4*I^2)
+      tempname theta sdtheta
+      matrix `theta'=J(1,`=`nbitems'+1',0)
+      matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',.)
+      forvalues s=0/`nbitems' {
+         qui gen f`s'=abs(`s'-P+.5*J/I)
+         qui sort f`s'
+         matrix `theta'[1,`=`s'+1']=theta[1]
+         matrix `sdtheta'[`=`s'+1',`=`s'+1']=V[1]
+      }
+      use `verytmp',replace
+   }
+   qui gen `tl'=0
+   forvalues s=0/`nbitems' {
+      local theta`s'=`theta'[1,`=`s'+1']
+      qui replace `tl'=`theta`s'' if `realscore'==`s'
+      local sdtheta`s'=sqrt(`sdtheta'[`=`s'+1',`= `s'+1'])
+   }
+   tempname pred
+   qui gen `pred'=log(exp(`rep'*(`tl'+`diff'))/(1+exp(`tl'+`diff')))
+
+   qui su `pred'
+   local globalll=r(sum)
+
+   forvalues i=0/`nbitems' {
+      qui count if `score'==`i'&`item'==1
+      local nbscore`i'=r(N)
+      qui count if `realscore'==`i'&`item'==1
+      local nbrealscore`i'=r(N)
+   }
+}
+
+/***********************************************************************************************************
+TESTS OF THE FIRST ORDER
+************************************************************************************************************/
+
+if "`test'"!="NONE" {
+   if "`trace'"!="" {
+      di in green "*** Tests of the first order"
+   }
+   tempname Obs Obs2 Pi Th Th2
+
+   matrix define `Obs'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Obs2'=J(`nbitems',`=`nbgroups'-1',0)
+   matrix define `Pi'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Th'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Th2'=J(`nbitems',`=`nbgroups'-1',0)
+   local listofitemsc
+
+   /* Estimation of the gamma symetrical functions*/
+   local c0 "1"
+   local c`nbitems' "`nbitems'*x"
+   forvalues j=1/`nbitems' {
+      local listini`j'
+      local listofitemsc "`listofitemsc' `beta`j''"
+      local c0 `c0'*(1+exp(x-`beta`j''))
+      local c`nbitems' `c`nbitems''-`beta`j''
+      forvalues k=1/`nbitems' {
+         local listini`j'k`k'
+         if `k'!=`j' {
+            local listini`j' "`listini`j'' `beta`k''"
+         }
+         forvalues l=1/`nbitems' {
+            if `l'!=`j'&`l'!=`k' {
+               local listini`j'k`k' "`listini`j'k`k'' `beta`l''"
+            }
+         }
+      }
+   }
+
+   gammasym `listofitemsc'
+
+   /*Estimation, for each value of the score s of the probability to respond to each item (Pi) and of the theorical number of positive responses (Ths) and of theorical number of positive respond per item pair (Ws)*/
+   forvalues s=1/`nbitems' {
+      local denom`s'=r(gamma`s')
+      tempname  W`s'
+      matrix define `W`s''=J(`nbitems',`nbitems',0)
+   }
+   tempvar prob prob2 z y v z2 y2 v2
+   qui gen `prob'=.
+   qui gen `prob2'=.
+   forvalues j=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui count if `rep'==1&`item'==`j'&`realscore'==`s'
+         matrix `Obs'[`j',`s']=r(N)
+         if "`test'"!="WP" {
+            gammasym `listini`j''
+            local num`j'=r(gamma`=`s'-1')
+            if "`method'"=="cml" {
+               matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s''
+            }
+            else if "`test'"=="R"&`nbrealscore`s''!=0{
+               gausshermite exp(`s'*x)/(`c0'), sigma(`sig')
+               local int`s'=r(int)
+               local tmp=exp(-`beta`j'')*`num`j''*`int`s''*`nbind'/`nbrealscore`s''
+               matrix `Pi'[`j',`s']=`tmp'
+            }
+            else if  "`test'"=="Q" {
+               matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s''
+            }
+            else if `nbrealscore`s''==0 {
+               matrix `Pi'[`j',`s']=0
+            }
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  if `s'>=2 {
+                     gammasym `listini`j'k`k''
+                     local num`j'k`k'=r(gamma`=`s'-2')
+                     if "`method'"=="cml" {
+                        matrix `W`s''[`j',`k']=`nbrealscore`s''*exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''/`denom`s''
+                     }
+                     else {
+                        matrix `W`s''[`j',`k']=exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''*`int`s''*`nbind'
+                     }
+                     matrix `W`s''[`k',`j']=`W`s''[`j',`k']
+                  }
+               }
+            }
+         }
+         else if "`test'"=="WP" {
+            matrix `Pi'[`j',`s']=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j''))
+         }
+         matrix `Th'[`j',`s']=`Pi'[`j',`s']*`nbrealscore`s''
+         qui replace `prob'=`Pi'[`j',`s'] if `realscore'==`s'&`item'==`j'
+         qui replace `prob2'=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) if `realscore'==`s'&`item'==`j'
+         matrix `W`s''[`j',`j']=`nbrealscore`s''*`Pi'[`j',`s']
+         if "`test'"!="R" {
+            matrix `W`s''[`j',`j']=`W`s''[`j',`j']*abs(1-`Pi'[`j',`s'])
+         }
+      }
+   }
+   qui gen `v2'=abs(`prob2'*(1-`prob2'))
+   qui gen `z2'=(`rep'-`prob2')^2
+   qui gen `y2'=`z2'/`v2'
+
+   forvalues j=1/`nbitems' {
+      qui su `y2' if `item'==`j'
+      local outfit`j'=r(mean)
+      qui su `z2' if `item'==`j'
+      local n=r(sum)
+      qui su `v2' if `item'==`j'
+      local d=r(sum)
+      local infit`j'=`n'/`d'
+   }
+   tempname tmp stattest testitems
+
+   /*Estimation, by scores group g, of the theorical number of positive response (Th2g) and of the positive respond to each items pair (W2g)*/
+   scalar `stattest'=0
+   forvalues g=1/`=`nbgroups'-1' {
+      tempname  W2`g' d2`g'
+      matrix define `W2`g''=J(`nbitems',`nbitems',0)
+      forvalues s=`liminf`g''/`limsup`g'' {
+         forvalues j=1/`nbitems' {
+            matrix `Obs2'[`j',`g']=`Obs2'[`j',`g']+`Obs'[`j',`s']
+            matrix `Th2'[`j',`g']=`Th2'[`j',`g']+`Th'[`j',`s']
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  matrix `W2`g''[`j',`k']=`W2`g''[`j',`k']+`W`s''[`j',`k']
+                  matrix `W2`g''[`k',`j']=`W2`g''[`j',`k']
+               }
+            }
+            matrix `W2`g''[`j',`j']=`W2`g''[`j',`j']+`W`s''[`j',`j']
+         }
+      }
+
+      /*Estimation of the d2g vectors*/
+      matrix `d2`g''=`Obs2'[1..`nbitems',`g']-`Th2'[1..`nbitems',`g']
+
+      /*Estimation of the influences on the test of each item (testitemsg matrix) and of the test statistic (stattest)*/
+      tempname test`g' testitems`g'
+      matrix `test`g''=`d2`g'''*syminv(`W2`g'')*`d2`g''
+      capture matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      if _rc!=0 {
+         matrix `tmp'=J(`nbitems',`nbitems',0)
+         forvalues j=1/`nbitems' {
+            matrix `tmp'[`j',`j']=`W2`g''[`j',`j']
+         }
+         di in green "Score `g' : The weight matrix is not positive-definite, the diagonal matrix is used to estimate the contribution of the items on the `wpname' statistic"
+         matrix list `tmp'
+         matrix `testitems`g''=cholesky(syminv(`tmp'))*`d2`g''
+      }
+      else {
+         matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      }
+      scalar `stattest'=`stattest'+`test`g''[1,1]
+   }
+   matrix `testitems'=J(`nbitems',1,0)
+   forvalues j=1/`nbitems' {
+      forvalues g=1/`=`nbgroups'-1' {
+         matrix `testitems'[`j',1]=`testitems'[`j',1]+`testitems`g''[`j',1]^2
+      }
+   }
+
+   /*Adaptation for the Q1 statistic*/
+   if "`test'"=="Q" {
+      scalar `stattest'=`stattest'*`=`nbitems'-1'/`nbitems'
+   }
+
+   /*Correction for R1m and Q1m*/
+   if ("`test'"=="R"|"`test'"=="Q")&("`method'"=="mml"|"`method'"=="gee") {
+      local c`nbitems' exp(`c`nbitems'')/(`c0')
+      local c0 1/(`c0')
+      gausshermite `c0', sigma(`sig')
+      local ci0=r(int)*`nbind'
+      gausshermite `c`nbitems'',sigma(`sig')
+      local ci`nbitems'=`nbind'*r(int)
+      scalar `stattest'=`stattest'+(`nbrealscore0'-`ci0')^2/`ci0'+(`nbrealscore`nbitems''-`ci`nbitems'')^2/`ci`nbitems''
+  }
+
+
+
+/***********************************************************************************************************
+TESTS U
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests U"
+      }
+
+      local quartile=`nbind'/4
+      local c1=0
+      local n1=0
+      while `n1'<`quartile' {
+         local c1=`c1'+1
+         local n1=`n1'+`nbrealscore`c1''
+      }
+      local c2=`nbitems'
+      local n2=0
+      while `n2'<`quartile' {
+         local c2=`c2'-1
+         local n2=`n2'+`nbrealscore`c2''
+      }
+      forvalues j=1/`nbitems' {
+         local zu1=0
+         local zu2=0
+         forvalues s=1/`c1' {
+            local zu1=`zu1'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         forvalues s=`c2'/`=`nbitems'-1' {
+            local zu2=`zu2'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         local U`j'=(`zu1'-`zu2')/sqrt(`c1'+`nbitems'-`c2')
+      }
+   }
+
+
+
+/***********************************************************************************************************
+TESTS OF THE SECOND ORDER /*undocumented in beta test*/
+************************************************************************************************************/
+
+   if "`q2'"!="" {
+      if "`trace'"!="" {
+         di in green "*** Tests of the second order"
+      }
+
+      tempfile Q2file
+      qui save  `Q2file',replace
+      qui use `saveraschtest',replace
+
+      qui keep if `touse'==1
+      gen `score'=0
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'
+	 rename ``i'' `rep'`i'
+	 qui replace `score'=`score'+`rep'`i'
+      }
+      qui recode `score' `recode'
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'=0
+         forvalues j=`=`i'+1'/`nbitems' {
+	    local listinci`i'j`j'
+	    forvalues k=1/`nbitems' {
+	       if `k'!=`i'&`k'!=`j' {
+	          local listinci`i'j`j' "`listinci`i'j`j'' `beta`k''"
+	       }
+	    }
+	 }
+      }
+
+      local Q2tot=0
+      forvalues k=2/`=`nbitems'-1' {
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`i'+1'/`nbitems' {
+	       if `k'==1 {
+	          local num=0
+               }
+	       else {
+	          gammasym `listinci`i'j`j''
+                  local num=r(gamma`=`k'-2')
+               }
+	       local athi`i'j`j'k`k'=exp(-`beta`i'')*exp(-`beta`j'')*`num'/`denom`k''
+	       local bthi`i'j`j'k`k'=`nbth`i's`k''-`athi`i'j`j'k`k''
+	       local cthi`i'j`j'k`k'=`nbth`j's`k''-`athi`i'j`j'k`k''
+	       local dthi`i'j`j'k`k'=1-`athi`i'j`j'k`k''-`bthi`i'j`j'k`k''-`cthi`i'j`j'k`k''
+            }
+         }
+      }
+      forvalues k=1/`=`nbgroups'-1' {
+         local Q2`k'=0
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`j'+1'/`nbitems' {
+	       qui count if  `rep'`i'==1&`rep'`j'==1&`score'==`k'
+	       local aempi`i'j`j'k`k'=r(N)
+	       local ath2i`i'j`j'k`k'=0
+	       local bth2i`i'j`j'k`k'=0
+	       local cth2i`i'j`j'k`k'=0
+	       local dth2i`i'j`j'k`k'=0
+	    }
+	 }
+         if `limsup`k''!=1 {
+            forvalues l=`liminf`k''/`limsup`k'' {
+	       forvalues i=1/`=`nbitems'-1' {
+	          forvalues j=`=`i'+1'/`nbitems' {
+		     if `l'!=1 {
+		        local ath2i`i'j`j'k`k'=`ath2i`i'j`j'k`k''+`athi`i'j`j'k`l''*`nbrealscore`l''
+			local bth2i`i'j`j'k`k'=`bth2i`i'j`j'k`k''+`bthi`i'j`j'k`l''*`nbrealscore`l''
+			local cth2i`i'j`j'k`k'=`cth2i`i'j`j'k`k''+`cthi`i'j`j'k`l''*`nbrealscore`l''
+			local dth2i`i'j`j'k`k'=`dth2i`i'j`j'k`k''+`dthi`i'j`j'k`l''*`nbrealscore`l''
+                     }
+		  }
+               }
+            }
+	    forvalues i=1/`=`nbitems'-1' {
+	       forvalues j=`=`i'+1'/`nbitems' {
+	          local d2i`i'j`j'k`k'=(`aempi`i'j`j'k`k''-`ath2i`i'j`j'k`k'')^2
+		  local Q2i`i'j`j'k`k'=`d2i`i'j`j'k`k''/`ath2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`bth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`cth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`dth2i`i'j`j'k`k''
+		  local Q2i`i'=`Q2i`i''+`Q2i`i'j`j'k`k''
+		  local Q2i`j'=`Q2i`j''+`Q2i`i'j`j'k`k''
+		  local Q2`k'=`Q2`k''+`Q2i`i'j`j'k`k''
+	       }
+	    }
+	 }
+         local Q2tot=`Q2tot'+`Q2`k''
+      }
+      forvalues i=1/`nbitems' {
+         di in green "Item ``i'' : Q2 = `Q2i`i''"
+      }
+      local Q2=`Q2tot'*(`nbitems'-3)/(`nbitems'-1)
+      di in green "Q2 = `Q2tot'"
+      qui use `Q2file',replace
+   }
+
+/***********************************************************************************************************
+TEST LR Z
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests LR of Andersen"
+      }
+      local ssll=0
+      tempname Zfile
+      qui save `Zfile', replace
+      qui use `saveraschtest',replace
+      qui keep if `touse'==1
+      gen `score'=0
+      forvalues j=1/`nbitems' {
+         qui replace `score'=`score'+``j''
+      }
+      qui recode `score' `recode' `nbitems'=`nbgroups'
+      forvalues i=1/`=`nbgroups'-1' {
+         if `effscore`i''>0 {
+            qui raschtestv7 `varlist' if `score'==`i', test(NONE)
+            local ll`i'=r(cll)
+            local ssll=`ssll'+(`ll`i'')
+         }
+      }
+      local Z=2*`ssll'-2*`ll'
+      use `Zfile',replace
+      tempname AndersenZ
+      matrix define `AndersenZ'=(`Z',`=(`nbgroups'-2)*(`nbitems'-1)',1-chi2(`=(`nbitems'-1)*(`nbgroups'-2)',`Z'))
+   }
+}
+
+/***********************************************************************************************************
+DISPLAYING RESULTS WITH TESTS
+************************************************************************************************************/
+
+if "`test'"!="NONE" {
+   local conttest= "_c"
+}
+di
+tempname itemfit globalfit
+matrix `globalfit'=J(1,3,0)
+if "`method'"=="cml" {
+   di in green "Estimation method: " in yellow  "Conditional maximum likelihood (CML)"
+   local nbtest=`nbgroups'-1
+   local line=77
+}
+else if "`method'"=="mml"{
+   di in green "Estimation method: " in yellow  "Marginal maximum likelihood (MML)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+else if "`method'"=="gee" {
+   di in green "Estimation method: " in yellow  "Generalized Estimating Equations (GEE)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+if "`test'"=="NONE" {
+   local line=34
+}
+di in green  "Number of items: " in yellow  `nbitems'
+
+di in green  "Number of groups: " in yellow  `=`nbgroups'+1' `conttest'
+if "`test'"!="NONE" {
+   di in green " (" in yellow "`nbtest'" in green " of them are used to compute the statistics of test)"
+}
+if "`method'"=="cml" {
+   local nbind=`nbind'+`effscore0'+`effscore`nbgroups''
+   local cont "_c"
+   matrix `itemfit'=J(`nbitems',6,0)
+}
+else {
+   local cont
+   matrix `itemfit'=J(`nbitems',5,0)
+}
+local missing=`N'-`nbind'
+di in green  "Number of individuals: " in yellow `nbind' in green " (" in yellow `missing' in green " individuals removed for missing values)"
+di in green  "Number of individuals with nul or perfect score: " in yellow `=`effscore0'+`effscore`nbgroups'''
+if "`method'"=="cml" {
+   di in green  "Conditional log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+else {
+   di in green "Marginal log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+di
+noi di in green  _col(16) "Difficulty"
+noi di in green _col(9) "Items" _col(16) "parameters" _col(28) "std Err." `conttest'
+if "`test'"!="NONE" {
+   di _col(41) "`namewp'" _col(47) "df" _col(50) "p-value" _col(58) "Outfit" _col(66) "Infit" `cont'
+   if "`method'"=="cml" {
+      di in green _col(77) "U"
+   }
+}
+di in green  "{hline `line'}"
+forvalues i=1/`nbitems' {
+   noi di in green  "`fixed`i''" in yellow _col(3) %12s abbrev("``i''" ,12) in yellow _col(18) %8.5f `beta`i'' _col(29) %6.5f `sd`i'' `conttest'
+   if "`test'"!="NONE" {
+      di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfit`i'' _col(65) %6.3f `infit`i'' `cont'
+      matrix `itemfit'[`i',1]=`testitems'[`i',1]
+      matrix `itemfit'[`i',2]=`=`nbgroups'-2'
+      matrix `itemfit'[`i',3]=1-chi2(`=`nbgroups'-2',`testitems'[`i',1])
+      matrix `itemfit'[`i',4]=`outfit`i''
+      matrix `itemfit'[`i',5]=`infit`i''
+      if "`method'"=="cml" {
+         di in ye _col(72) %6.3f `U`i''
+         matrix `itemfit'[`i',6]=`U`i''
+      }
+   }
+}
+di in green  "{hline `line'}"
+if "`test'"!="NONE" {
+   if "`method'"=="cml" {
+      local df=(`nbgroups'-2)*(`nbitems'-1)
+   }
+   else {
+      local df=(`nbgroups'-1)*(`nbitems'-1)-1
+   }
+   matrix `globalfit'=(`stattest',`df',1-chi2(`df',`stattest'))
+   noi di in green _col(7) "`descwp'" _col(32) in gr "`namewp'=" _col(36) in ye %8.3f `globalfit'[1,1] _col(46) %3.0f `globalfit'[1,2] _col(51) %6.4f `globalfit'[1,3]
+   if "`method'"=="cml" {
+      noi di in green _col(7) "Andersen LR test" _col(34) "Z=" in yellow _col(36) %8.3f `AndersenZ'[1,1] _col(46) %3.0f `AndersenZ'[1,2] _col(51) %6.4f `AndersenZ'[1,3]
+   }
+   di in green  "{hline `line'}"
+}
+if "`method'"!="cml" {
+   di in green _col(10) in yellow "Sigma" _col(18) %8.5f `sig' _col(29) %6.5f `sesig'
+   di in green  "{hline `line'}"
+}
+
+if "`method'"=="cml"&"`meandiff'"==""{
+   di in green "*: The difficulty parameter of this item had been fixed to 0"
+}
+if "`method'"=="cml"&"`meandiff'"!=""{
+   di in green "The mean of the difficulty parameters is fixed to 0"
+}
+if `smallgroup'==1&"`test'"!="NONE" {
+   di in green "You have groups of scores with less than 30 individuals. The tests can be invalid."
+}
+if "`method'"!="cml"&"`test'"=="Q" {
+   di in green "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test."
+}
+
+/*Tabular of the estimated values of the latent trait*/
+
+   di
+   di
+   noi di in green _col(33) "Ability"
+   noi di in green _col(17) "Group" _col(23) "Score" _col(30) "parameters" _col(42) "std Err." _col(54) "Freq." _c
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      noi di in green _col(69) "ll"
+   }
+   else {
+      noi di ""
+   }
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      local line=54
+   }
+   else {
+     local line=42
+   }
+   di in green _col(17) "{hline `line'}"
+   local nonul=0
+   forvalues g=0/`nbgroups' {
+      if `g'!=0 {
+         di in green _col(17) "{dup `line':-}"
+      }
+      forvalues s=`liminf`g''/`limsup`g'' {
+         if `s'==`liminf`g'' {
+            local tmp `ll`g''
+            local gr `g'
+         }
+         else {
+            local tmp
+            local gr
+         }
+         if `effscore`g''!=0 {
+            if "`method'"=="cml" {
+               local format1 %8.3f
+            }
+            else {
+               local format1 %8.5f
+            }
+            noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(32) `format1' `theta`nonul'' _col(42) `format1' `sdtheta`nonul'' _col(55) %4.0f `nbrealscore`s'' _col(60) %11.4f `tmp'
+            local nonul=`nonul'+1
+         }
+         else {
+            noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(55) %4.0f `nbrealscore`s''
+         }
+      }
+   }
+   di in green _col(17) "{hline `line'}"
+
+
+/***********************************************************************************************************
+DETAILS OPTION
+************************************************************************************************************/
+
+if "`details'"!="" {
+   forvalues g=0/`nbgroups' {
+      if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" {
+         di
+         di in  green "{hline 44}"
+         di in green "Group: " in ye "`g'" in green " from " in ye "`liminf`g''" in green " to " in ye "`limsup`g''" in green " (n=" in ye "`nbscore`g''" in green")"
+         di
+         di _col(3) "Item" _col(10) "Observed" _col(23) "Expected" _col(37) "Scaled"
+         di in green "{dup 44:-}"
+      }
+      if `g'!=0&`g'!=`nbgroups' {
+         forvalues j=1/`nbitems' {
+            local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j'])
+            di _col(3) in ye "``j''" _col(14) %4.0f `Obs2'[`j',`g'] _col(25) %6.2f `Th2'[`j',`g'] _col(36) %7.4f `tmp'
+         }
+         di in green "{dup 44:-}"
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `test`g''[1,1]
+      }
+      else if "`method'"!="cml" {
+         if `g'==0 {
+            local h=0
+         }
+         else {
+            local h=`nbitems'
+         }
+         local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'')
+         di in ye _col(14) %4.0f `nbrealscore`h'' _col(25) %6.2f `ci`h'' _col(36) %7.4f `tmp'
+         di in green "{dup 44:-}"
+         local tmp=`tmp'^2
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `tmp'
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION ICC
+************************************************************************************************************/
+
+if "`icc'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Items Characteristic Curves"
+   }
+   tempvar proba propemp propth propthb
+   qui replace `tl'=. if `realscore'==0|`realscore'==`nbitems'|`realscore'==.
+   qui gen `propemp'=.
+   qui gen `propth'=.
+   qui gen `propthb'=.
+   label variable `propth' "Expected ICC"
+   label variable `propemp' "Observed ICC"
+   label variable `propthb' "Expected ICC"
+   label variable `tl' "Latent trait"
+   global iccs
+   forvalues i=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui replace `propthb'=exp(`theta`s''-`beta`i'')/(1+exp(`theta`s''-`beta`i'')) if `item'==`i'&`realscore'==`s'
+      }
+      qui replace `propemp'=.
+      qui replace `propth'=.
+      tempvar propemp`i' propth`i'
+      qui bysort `realscore' `item' : egen `propth`i''=mean(`propthb') if `item'==`i'
+      qui bysort `realscore' `item' : egen `propemp`i''=mean(`rep') if `item'==`i'
+      qui replace `propth'=`propth`i'' if `item'==`i'
+      qui replace `propemp'=`propemp`i'' if `item'==`i'
+      local mintl=floor(`theta1')
+      local maxtl=floor(`theta`=`nbitems'-1'')+1
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\icc``i''"
+      }
+      if "`v8'"!="" {
+         graph twoway (line  `propemp' `propth' `tl') if `item'==`i' , name(icc`i',replace) ytitle("")  ylabel(0(.25)1) title("Observed and Expected ICC for the item ``i''") xlabel(`mintl'(1)`maxtl') `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save icc`i' `saving' , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui graph `propemp' `propth' `tl' if `item'==`i' , twoway `saving' c(ll) ylabel(0(.25)1)   xlabel(`mintl'(1)`maxtl') title("Observed and Expected ICC for the item ``i''")
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION INFORMATION
+************************************************************************************************************/
+
+if "`information'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Information graph"
+   }
+
+   tempfile saveinfo
+   qui save `saveinfo',replace
+   tempvar info latent
+   drop _all
+   qui set obs 2001
+   gen `latent'=((_n-1)/1001-1)*3
+   label variable `latent' "latent trait"
+   gen `info'=0
+   forvalues i=1/`nbitems' {
+      qui replace `info'=`info'+exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2
+   }
+   local saving "`dirsave'\\information"
+   if "`v8'"!="" {
+      graph twoway (line  `info' `latent') , name(information,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the scale") `draw'
+      if "`filessave'"!="" {
+         graph save information `saving' , `replace'
+      }
+      pause
+   }
+   else {
+      if "`filessave'"!="" {
+         local saving "saving(`saving'"
+         if "`replace'"=="" {
+            local saving "`saving')"
+         }
+         else {
+            local saving "`saving',replace)"
+         }
+      }
+      if "`filessave'"=="" {
+         local saving
+      }
+      qui graph `info' `latent' , twoway  `saving' c(l) xlabel(-3(1)3) title("Information graph of the scale")
+      pause
+   }
+   qui use `saveinfo',replace
+}
+
+/***********************************************************************************************************
+OPTION FITGRAPH
+************************************************************************************************************/
+
+if "`fitgraph'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graphical validation of the fit"
+   }
+
+   tempname outfit meanz2 meanv2 infit
+   qui egen `outfit'=mean(`y2'),by(`id')
+   qui egen `meanz2'=sum(`z2'),by(`id')
+   qui egen `meanv2'=sum(`v2'),by(`id')
+   qui gen `infit'=`meanz2'/`meanv2'
+   qui su `outfit'
+   local maxo=r(max)
+   qui su `infit'
+   local maxi=r(max)
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfitind"
+      local savingi "`dirsave'\\infitind"
+   }
+   if "`v8'"!="" {
+      graph twoway (scatter `outfit' `id'), name(outfit,replace) yline(.6 1.4) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(0(.2)2 2(.5)`maxo') `draw'
+      pause
+      graph twoway (scatter `infit' `id'), name(infit,replace) yline(.6 1.4) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(0(.2)2 2(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfit `savingo' , `replace'
+         graph save infit `savingi' , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfit' `id', `savingo' twoway sy(.) c(.) yline(.6 1.4) title("Outfit indexes") b2title("Individual indexes") l1("") l2title("Outfit") ylabel(0(.2)2 2(.5)`maxo')
+      pause
+      graph `infit' `id', `savingi' twoway sy(.) c(.) yline(.6 1.4) title("Infit indexes") b2title("Individual indexes") l1("")  l2title("Infit") ylabel(0(.2)2 2(.5)`maxi')
+      pause
+   }
+   drop _all
+   qui set obs `nbitems'
+   tempvar name betap outfitj infitj
+   qui gen str9 `name'=""
+   qui gen `betap'=.
+   qui gen `outfitj'=.
+   qui gen `infitj'=.
+   local mino=.6
+   local maxo=1.4
+   local mini=.6
+   local maxi=1.4
+   forvalues j=1/`nbitems' {
+      qui replace `name'="``j''" in `j'
+      qui replace `betap'=`beta`j'' in `j'
+      qui replace `outfitj'=`outfit`j'' in `j'
+      qui replace `infitj'=`infit`j'' in `j'
+      local mino=min(`mino',`outfit`j'')
+      local mini=min(`mini',`infit`j'')
+      local maxo=max(`maxo',`outfit`j'')
+      local maxi=max(`maxi',`infit`j'')
+   }
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfititems"
+      local savingi "`dirsave'\\infititems"
+   }
+   if "`v8'"!="" {
+      graph twoway (scatter `outfitj' `betap',name(outfit,replace) mlabel(`name')), yline(.6 1.4) title("Outfit indexes") xtitle("Difficulty") ytitle("Outfit") ylabel(`mino'(.2)`maxo') `draw'
+      pause
+      graph twoway (scatter `infitj' `betap',name(infit,replace) mlabel(`name')), yline(.6 1.4) title("Infit indexes") xtitle("Difficulty") ytitle("Infit") ylabel(`mini'(.2)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfit `savingo' , `replace'
+         graph save infit `savingi' , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitj' `betap', `savingo' twoway c(.) yline(.6 1.4) title("Outfit indexes") b2title("Difficulty") l1title("") l2title("Outfit") ylabel(`mino'(.2)`maxo') sy([`name'])
+      pause
+      graph `infitj' `betap', `savingi' twoway c(.) yline(.6 1.4) title("Infit indexes") b2title("Difficulty") l1title("") l2title("Infit") ylabel(`mini'(.2)`maxi') sy([`name'])
+      pause
+   }
+}
+
+
+/***********************************************************************************************************
+OPTION SPLITTESTS
+************************************************************************************************************/
+
+if "`splittests'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Splitting tests"
+   }
+ *set trace on
+   forvalues j=1/`nbitems' {
+      tempname estneg`j' estpos`j'
+      local listitems
+      forvalues k=1/`nbitems' {
+         if `j'!=`k' {
+            local listitems `listitems' ``k''
+         }
+      }
+      qui use `saveraschtest',replace
+      qui keep if `touse'==1
+      qui raschtestv7 `listitems' if ``j''==0,test(NONE) meth(cml)
+      matrix `estneg`j''=r(beta)
+      local llneg=r(cll)
+      qui raschtestv7 `listitems' if ``j''==1,test(NONE) meth(cml)
+      matrix `estpos`j''=r(beta)
+      local llpos=r(cll)
+      qui raschtestv7 `listitems',test(NONE) meth(cml)
+      local llnegpos=r(cll)
+      local nbcol=colsof(`estneg`j'')
+      local meanneg=0
+      local meanpos=0
+      forvalues k=1/`nbcol' {
+         local meanneg=`meanneg'+`estneg`j''[1,`k']
+         local meanpos=`meanpos'+`estpos`j''[1,`k']
+      }
+      local meanneg=`meanneg'/`nbitems'
+      local meanpos=`meanpos'/`nbitems'
+      forvalues k=1/`nbcol' {
+         matrix `estneg`j''[1,`k']=`estneg`j''[1,`k']-`meanneg'
+         matrix `estpos`j''[1,`k']=`estpos`j''[1,`k']-`meanpos'
+         if "`method'"=="cml" {
+            matrix `estneg`j''=`estneg`j'',-`meanneg'
+            matrix `estpos`j''=`estpos`j'',-`meanpos'
+         }
+      }
+      drop _all
+      qui set obs `=`nbitems'+1'
+      tempvar neg pos name diag
+      qui gen `neg'=.
+      qui gen `pos'=.
+      qui gen str9 `name'=""
+      local min=`estneg`j''[1,1]
+      local max=`estneg`j''[1,1]
+      forvalues k=1/`=`nbitems'-1' {
+         qui replace `neg'=`estneg`j''[1,`k'] in `k'
+         qui replace `pos'=`estpos`j''[1,`k'] in `k'
+         local min=min(`min',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local max=max(`max',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local tmp:word `k' of `listitems'
+         qui replace `name'="`tmp'" in `k'
+      }
+      local min=floor(`min')
+      local max=floor(`max')+1
+      qui gen `diag'=.
+      qui replace `diag'=`min' in `nbitems'
+      qui replace `diag'=`max' in `=`nbitems'+1'
+      local Zgr=round(2*(`llneg'+`llpos'-`llnegpos'),0.001)
+      local Zgr=substr("`Zgr'",1,6)
+      local pgr=round(1-chi2(`=`nbitems'-1',`Zgr'),0.0001)
+      local pgr=substr("`pgr'",1,5)
+      local note="Z=`Zgr', df=`=`nbitems'-1' , p=`pgr'"
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\split``j''"
+      }
+      if "`v8'"!="" {
+         graph twoway (scatter `pos' `neg' ,mlabel(`name')) (line `diag' `diag'), ytitle("Positive answer") xtitle("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title(Splitting on ``j'') `draw' legend(off) note("Andersen Z test: `note'") name(split,replace) `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save split `saving' , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui replace `diag'=`neg' if `diag'==.
+         graph  `pos' `diag' `diag', `saving' c(.l) sy([`name']i) l1title("") l2title("Positive answer") b2title("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title("Splitting on ``j'' (`note')") `draw'
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION GRAPH
+************************************************************************************************************/
+
+if "`graph'"!=""&"`v8'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graph option"
+   }
+   tempvar  latent2  tl2 delta2 tlth2 labdelta2 labtl2
+   drop _all
+   qui set obs 1001
+   gen `latent2'=(_n-501)/100
+   label variable `latent2' "latent trait"
+   qui gen `tl2'=.
+   qui gen `labtl2'=""
+   forvalues i=0/`nbitems' {
+      *if (`i'!=0&`i'!=`nbitems')|"`method'"!="cml" {
+         qui replace `tl2'=`nbrealscore`i''/`N' if round(`latent2',0.01)==round(`theta`i'',0.01)
+         qui replace `labtl2'="`i'" if round(`latent2',0.01)==round(`theta`i'',0.01)
+      *}
+   }
+   qui gen `delta2'=.
+   qui gen `labdelta2'=""
+   forvalues i=1/`nbitems' {
+      qui replace `delta2'=-.05 if round(`latent2',0.01)==round(`beta`i'',0.01)
+      qui replace `labdelta2'="``i''" if round(`latent2',0.01)==round(`beta`i'',0.01)
+   }
+   if "`method'"=="mml"|"`method'"=="gee" {
+      qui gen `tlth2'=1/(2*_pi*`sig')*exp(-.5*(`latent2'/`sig')^2)
+      label variable `tlth2' "Theorical distribution"
+      local graphmml line `tlth2' `latent2'
+   }
+   label variable `tl2' "Score"
+   label variable `delta2' "Items"
+   local saving "`dirsave'\\graph"
+   local min=-2
+   local max=2
+   forvalues j=1/`nbitems' {
+      if `beta`j''<`min' {
+         local min=`beta`j''-.5
+      }
+      if `beta`j''>`max'&`beta`j''!=. {
+         local max=`beta`j''+.5
+      }
+   }
+   if "`method'"=="cml" {
+      if `theta0'<`min' {
+         local min=`theta0'-.5
+      }
+      if `theta`=`nbitems'-1''>`max' {
+         local max=`theta`=`nbitems'-1''+.5
+      }
+   }
+   else if "`method'"!="cml" {
+      if `theta0'<`min'&`theta0'!=. {
+         local min=`theta0'-.5
+      }
+      if `theta`nbitems''>`max'&`theta`nbitems''!=. {
+         local max=`theta`nbitems''+.5
+      }
+   }
+   local min=floor(`min')
+   local max=floor(`max')+1
+   qui su `tl2'
+   local max2=r(max)
+   if "`method'"!="cml" {
+      qui su `tlth2'
+      local max2=max(`max2',`r(max)')
+   }
+   qui replace `latent2'=. if `latent2'<`min'|`latent2'>`max'
+   if "`v8'"!="" {
+      graph twoway (scatter `tl2' `latent2',mlabel(`labtl2')) (dropline `delta2' `latent2',mlabel(`labdelta2') mlabposition(6)) (`graphmml'), name(graph,replace) ytitle("") xlabel(`min'(1)`max') ylabel(-.1 0(0.05)`max2') title("Individuals/items representations") `draw'
+      if "`filessave'"!="" {
+         graph save graph `saving' , `replace'
+      }
+      pause
+   }
+}
+else if "`graph'"!=""&"`v8'"=="" {
+   di in ye "The graph option is not available with Stata 7"
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATION
+************************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+      di
+      di _col(4) in green "Comparison of two populations"
+      di _col(4) "{hline 30}"
+      di
+      di _col(4) in green "`comp'==`mincomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmin' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmin' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmin'
+      di _col(4) in green "`comp'==`maxcomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmax' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmax' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmax'
+      di                                                                       _col(33) in green "Z= " _col(35) in yellow %8.4f `Zcomp' _col(47) in green "pvalue= "    _col(57) in yellow %6.4f `pvalue'
+}
+
+
+/***********************************************************************************************************
+RETURN
+************************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Returns"
+}
+local colnametheta
+
+if "`method'"=="cml" {
+   forvalues i=1/`=`nbgroups'-1' {
+      if `effscore`i''!=0 {
+            local colnametheta `colnametheta' score_`i'
+      }
+   }
+}
+else {
+   forvalues i=0/`nbgroups' {
+      if `effscore`i''!=0 {
+            local colnametheta `colnametheta' score_`i'
+      }
+   }
+}
+
+
+return clear
+
+if `nbitems'>=3&"`test'"!="NONE" {
+        matrix colnames `globalfit'=`namewp' df p
+	matrix rownames `globalfit'=`method'
+	matrix rownames `itemfit'=`varlist'
+        matrix roweq `itemfit'=`method'
+
+	if "`method'"=="cml" {
+                matrix colnames `itemfit'=`namewp' df p outfit infit U
+		matrix rownames `AndersenZ'=`method'
+		matrix colnames `AndersenZ'=Z df p
+		return matrix AndersenZ=`AndersenZ'
+	}
+	else {
+                matrix colnames `itemfit'=`namewp' df p outfit infit
+	}
+	return matrix itemFit=`itemfit'
+	return matrix globalFit=`globalfit'
+*set trace off
+}
+
+matrix colnames `theta'=`colnametheta'
+matrix rownames `theta'=theta
+return matrix theta `theta'
+matrix colnames `sdtheta'=`colnametheta'
+matrix rownames `sdtheta'=`colnametheta'
+return matrix Vartheta `sdtheta'
+local varlist2
+matrix coleq `beta'=`method'
+matrix coleq `Vbeta'=`method'
+matrix roweq `Vbeta'=`method'
+if "`method'"=="cml" {
+	forvalues i=1/`=`nbitems'-1' {
+		local varlist2 `varlist2' ``i''
+	}
+        return scalar cll=`ll'
+        return scalar ll=`globalll'
+	local AIC=-2*`globalll'+2*(`nbitems'-1)
+}
+else {
+        return scalar ll=`ll'
+	local varlist2 `varlist'
+	return scalar sigma=`sig'
+	return scalar sesigma=`sesig'
+	local AIC=-2*`ll'+2*(`nbitems'+1)
+}
+
+matrix colnames `beta'=`varlist2'
+matrix rownames `beta'=beta
+return matrix beta `beta'
+
+matrix colnames `Vbeta'=`varlist2'
+matrix rownames `Vbeta'=`varlist2'
+return matrix Varbeta `Vbeta'
+
+return scalar AIC=`AIC'
+return scalar N=`nbind'
+
+if "`pause'"!="" {
+   pause off
+}
+
+drop _all
+
+restore,not
+use `saveraschtest'
+
+/***********************************************************************************************************
+CREATE EVENTUAL NEW VARIABLES
+************************************************************************************************************/
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+        tempname genlt2 genscore2 outfit2 infit2
+        qui gen `score'=0
+        forvalues i=1/`nbitems' {
+           qui replace `score'=`score'+``i''
+        }
+        qui gen `genlt2'=.
+        forvalues i=0/`nbitems' {
+           qui replace `genlt2'=`theta`i'' if `score'==`i'
+        }
+        if "`genscore'"!="" {
+           qui gen `genscore'=`score'
+        }
+        if "`genlt'"!="" {
+           qui gen `genlt'=`genlt2'
+        }
+        if "`genfit'"!="" {
+           local outfit:word 1 of `genfit'
+           local infit:word 2 of `genfit'
+           qui gen `outfit'=0
+           qui gen `infit'=0
+           tempname infit1 infit2
+           qui gen `infit1'=0
+           qui gen `infit2'=0
+           forvalues j=1/`nbitems' {
+               tempname pi`j'
+               qui gen `pi`j''=exp(`genlt2'-`beta`j'')/(1+exp(`genlt2'-`beta`j''))
+               qui gen `outfit'``j''=(``j''-`pi`j'')^2/(`pi`j''*(1-`pi`j''))
+               qui replace `infit1'=`infit1'+(``j''-`pi`j'')^2
+               qui replace `infit2'=`infit2'+(`pi`j''*(1-`pi`j''))
+               qui replace `outfit'=`outfit'+`outfit'``j''/`nbitems'
+           }
+           qui replace `infit'=`infit1'/`infit2'
+        }
+}
+
+if "`trace'"!=""|"`time'"!="" {
+    capture qui elapse `st'
+    di in green "** Time : " in yellow "$S_elap " in green "seconds"
+}
+end
diff --git a/Modules/ado/personal/r/old/raschtestv7761.ado b/Modules/ado/personal/r/old/raschtestv7761.ado
new file mode 100644
index 0000000..df9201a
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschtestv7761.ado
@@ -0,0 +1,1809 @@
+*! version 7.6.1  26june2008
+*! Jean-Benoit Hardouin
+*************************************************************************************************************
+* Raschtestv7: Rasch model, fit tests and graphical representations
+* Corresponds to the version 7.6 of Raschtest (http://freeirt.org) for Stata7
+*
+* Historic:
+* Version 2.1 (2003-07-10): Jean-Benoit Hardouin
+* Version 3.1 (2004-01-02) : Jean-Benoit Hardouin
+* Version 7.1 (2005-03-30) : Jean-Benoit Hardouin
+* Version 7.2.1 (2005-05-21) : Jean-Benoit Hardouin
+* Version 7.3.1 (2005-07-02) : Jean-Benoit Hardouin
+* Version 7.3.2 (2005-10-05) : Jean-Benoit Hardouin /*correction for the *genlt* option with *method(cml)**/
+* Version 7.3.3 (2005-12-21) : Jean-Benoit Hardouin /*correction if scores are not represented with method(mml) or method(gee)*/
+* Version 7.4.1 (2006-01-17) : Jean-Benoit Hardouin /*Standardized OUTFIT and INFIT, DIF option*/
+* Version 7.4.2 (2006-03-21) : Jean-Benoit Hardouin /*Avoids a bug when the temporary files are saved in a directory containing special characters*/
+* Version 7.4.3 (2006-11-15) : Jean-Benoit Hardouin /*Avoids a bug when the directory defined in the dirsave option contains special characters*/
+* Version 7.5.1 (2007-04-20) : Jean-Benoit Hardouin /*Return results of the comp option*/
+* Version 7.6.1 (2008-06-26) : Jean-Benoit Hardouin /*Nold option, corrects a bug with the genlt option*/
+*
+* Needed modules :
+* gammasym version 2.1 (http://freeirt.free.fr)
+* gausshermite version 1 (http://freeirt.free.fr)
+* geekel2d version 4.2 (http://freeirt.free.fr)
+* genscore version 1.4 (http://freeirt.free.fr)
+* ghquadm (findit ghquadm)
+* gllamm version 2.3.11 (ssc describe gllamm)
+* gllapred version  2.3.2 (ssc describe gllapred)
+* elapse (ssc describe elapse)
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://anaqol.free.fr
+* FreeIRT Project : http://freeirt.free.fr
+*
+* Copyright 2003-2008 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+DEFINITION / SYNTAX
+***********************************************************************************************************/
+
+
+program define raschtestv7,rclass
+syntax varlist(min=1 numeric) [if] [in] , [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph v8 COMp(varname) dif(varlist) time TRace Details  nold]
+
+
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Tests of conformity"
+}
+if "`v8'"=="" {
+        version 7.0
+}
+else {
+        version 8.0
+}
+
+local st = "$S_TIME"
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+tokenize `varlist'
+
+local bad
+forvalues i=1/`nbitems' {
+   qui count if ``i''!=0&``i''!=1&``i''!=.
+   local N=r(N)
+   if `N'>0 {
+      local bad `bad' ``i''
+   }
+}
+if "`bad'"!="" {
+   di in red "The item(s) {hi:`bad'} is(are) not binary item(s) (with responses 0 or 1)."
+   exit
+}
+
+if "`method'"=="" {
+    local method cml
+}
+if "`test'"=="" {
+    local test R
+}
+local method=lower("`method'")
+local test=upper("`test'")
+if "`method'"!="mml"&"`method'"!="cml"&"`method'"!="gee" {
+    di in red "Uncorrect method option."
+    error 198
+    exit
+}
+
+if "`test'"!="R"&"`test'"!="Q"&"`test'"!="WP"&"`test'"!="NONE" {
+   di in red "Uncorrect test option."
+   error 198
+   exit
+}
+
+if "`genfit'"!="" {
+   local nbwordgenfit:word count `genfit'
+   if `nbwordgenfit'!=2 {
+      di in red "Uncorrect genfit option."
+      di in red "This option must contain exactly two words"
+      error 198
+      exit
+   }
+}
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+   confirm new variable `genfit' `genlt' `genscore'
+   if "`genfit'"!="" {
+      local o:word 1 of `genfit'
+      forvalues i=1/`nbitems' {
+         confirm new variable `o'``i''
+      }
+   }
+}
+
+preserve
+
+tempfile saveraschtest
+qui save `saveraschtest'
+qui keep if `touse'==1
+
+if "`autogroup'"!=""&"`group'"!="" {
+   di in green "The autogroup and the group options cannot be defined in the same time"
+   di in green "Only the group option is retained."
+   local autogroup
+}
+
+if "`autogroup'"!="" {
+   tempvar autoscore
+   qui genscore `varlist',score(`autoscore')
+
+   tempname matscore tmp
+   matrix `matscore'=J(`=`nbitems'-1',3,0)
+   forvalues i=1/`=`nbitems'-1' {
+        matrix `matscore'[`i',1]=`i'
+        matrix `matscore'[`i',2]=`i'
+        qui count if `autoscore'==`i'
+        matrix `matscore'[`i',3]=r(N)
+   }
+   local stop=0
+   local j=0
+   while `j'<=`=`nbitems'-3'&`stop'!=1 {
+      local j=`j'+1
+      local scoretogroup=99999999
+      local rowtogroup1=0
+      local rowtogroup2=0
+      local stop=1
+      forvalues i=1/`=`nbitems'-`j'' {
+         if `matscore'[`i',1]>=0 & `matscore'[`i',3]<30 & `matscore'[`i',3]<`scoretogroup' {
+            local scoretogroup=`matscore'[`i',3]
+            local rowtogroup1=`i'
+            local stop=0
+         }
+      }
+      if `stop'!=1 {
+         if `rowtogroup1'>1&`rowtogroup1'<`=`nbitems'-`j'' {
+            if `matscore'[`=`rowtogroup1'-1',1]<`matscore'[`=`rowtogroup1'+1',1] {
+               local rowtogroup2=`rowtogroup1'
+               local rowtogroup1=`rowtogroup1'-1
+            }
+            else {
+               local rowtogroup2=`rowtogroup1'+1
+            }
+         }
+         else if `rowtogroup1'==1 {
+            local rowtogroup2=2
+         }
+         else if `rowtogroup1'==`=`nbitems'-`j'' {
+            local rowtogroup2=`nbitems'-`j'
+            local rowtogroup1=`nbitems'-`j'-1
+         }
+         matrix `tmp'=`matscore'
+         matrix `matscore'=J(`=`nbitems'-`j'',3,0)
+         if `rowtogroup1'!=1 {
+            matrix `matscore'[1,1]=`tmp'[1..`=`rowtogroup1'-1',1..3]
+         }
+         matrix `matscore'[`rowtogroup1',1]=`tmp'[`rowtogroup1',1]
+         matrix `matscore'[`rowtogroup1',2]=`tmp'[`rowtogroup2',2]
+         matrix `matscore'[`rowtogroup1',3]=`tmp'[`rowtogroup1',3]+`tmp'[`rowtogroup2',3]
+         if `rowtogroup2'!=`=`nbitems'-`j'' {
+            matrix `matscore'[`rowtogroup2',1]=`tmp'[`=`rowtogroup2'+1'..`=`nbitems'-`j'',1..3]
+         }
+      }
+   }
+   local nbrows=rowsof(`matscore')-1
+   local thresholds
+   forvalues i=1/`nbrows' {
+      local tmp=`matscore'[`i',2]
+      local thresholds `thresholds' `tmp'
+   }
+   local group `thresholds'
+}
+
+
+if "`group'"=="" {
+	forvalues i=1/`=`nbitems'-1' {
+		local group "`group' `i'"
+	}
+}
+local nbgroups:word count `group'
+local groupmax:word `nbgroups' of `group'
+if `groupmax'>=`nbitems' {
+	di in red "You cannot form a group with the higher possible score."
+	di in red "The higher possible value of the group option is `=`nbitems'-1'."
+        di in red "Please correct your group option."
+	error 198
+        exit
+}
+else {
+	if `groupmax'!=`=`nbitems'-1' {
+		local group "`group' `=`nbitems'-1'"
+		local nbgroups=`nbgroups'+1
+	}
+}
+local nbgroups=`nbgroups'+1
+
+if "`dirsave'"!=""&"`filessave'"=="" {
+        di in ye "If you want to save yours graphs, use the filessave option"
+}
+if "`filessave'"!="" {
+        if "`dirsave'"=="" {
+              local dirsave "`c(pwd)'"
+        }
+        di in ye "The graphs files will be saved in `dirsave'"
+}
+if "`dirsave'"!="" {
+        if "`filesave'"=="" {
+              local filesave "filesave"
+        }
+}
+
+
+if "`pause'"!=""&"`draw'"=="" {
+     pause on
+}
+
+
+/***********************************************************************************************************
+POSSIBLE TEST
+***********************************************************************************************************/
+
+if ("`icc'"!=""|"`fitgraph'"!=""|"`splittest'"!=""|"`details'"!="")&"`test'"=="NONE" {
+	di in green "You cannot use the {hi:details}, {hi:icc}, {hi:fitgraph} or {hi:splittest} options if you use {hi:test(none)}."
+        di in green "These options are ignored."
+	local details
+	local icc
+	local fitgraph
+	local splittest
+}
+if "`comp'"!=""&"`method'"=="cml" {
+   	di in green "You cannot compare two populations ({hi:comp} option) with the CML estimation method"
+   	di in green "This option is ignored."
+        local comp
+}
+if "`method'"!="cml"&"`test'"=="WP" {
+	di in green "The Wright-Panchapakesan test is not authorized with MML or GEE."
+	di in green "The WP tests are replaced by Van den Wollenberg Q tests."
+        local test Q
+}
+if "`method'"=="gee"&"`ld'"!="" {
+	di in green "You cannot use the {hi:nold} option with the GEE method of estimation"
+	di in green "This option is ignored."
+        local ld
+}
+
+
+if "`test'"==""|"`test'"=="R" {
+   local test "R"
+   if "`method'"=="cml" {
+      local namewp "R1c"
+      local descwp "R1c test"
+   }
+   else {
+      local namewp="R1m"
+      local descwp "R1m test"
+   }
+}
+if `nbitems'>999999|"`test'"=="WP" {
+	local namewp "  Y"
+	local descwp "Wright-Panchapakesan Y test"
+	local q2
+}
+ else if "`test'"=="Q" {
+	local namewp " Q1"
+	local descwp "Van den Wollenberg Q1 test"
+}
+
+if "`method'"!="cml"&"`meandiff'"!="" {
+	di in green "The {hi:meandiff} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local meandiff
+}
+
+if "`method'"!="cml"&"`splittests'"!="" {
+	di in green "The {hi:splittests} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local splittests
+}
+if "`method'"!="cml"&"`dif'"!="" {
+	di in green "The {hi:dif} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local dif
+}
+
+/***********************************************************************************************************
+SCORES AND GROUPS
+************************************************************************************************************/
+
+qui count if `touse'==1
+local N=r(N)
+
+
+tempvar id
+gen `id'=_n
+
+
+qui keep `varlist' `comp' `id' `touse'
+
+tempname rep item
+tempvar score realscore
+qui genscore `varlist',score(`score')
+*   di "LD : `ld'"
+qui count if `score'==.&`touse'==1
+local nbindmiss=r(N)
+
+if "`ld'"=="" {
+   qui drop if `score'==.
+}
+forvalues i=1/`nbitems' {
+	rename ``i'' `rep'`i'
+	*qui drop if `rep'`i'==.|`rep'`i'>1
+	*qui replace `score'=`score'+`rep'`i'
+}
+
+
+
+local liminf0=0
+local limsup0=0
+local liminf`nbgroups'=`nbitems'
+local limsup`nbgroups'=`nbitems'
+
+
+local recode
+forvalues i=1/`=`nbgroups'-1' {
+	if `i'!= 1{
+		local liminf`i' : word `=`i'-1' of `group'
+	}
+	else {
+		local liminf1=0
+	}
+	local liminf`i'=`liminf`i''+1
+	local limsup`i':word `i' of `group'
+
+	local recode "`recode' `liminf`i''/`limsup`i''=`i'"
+}
+qui gen `realscore'=`score'
+qui recode `score' `recode' `nbitems'=`nbgroups'
+
+local smallgroup=0
+
+forvalues i=0/`nbgroups' {
+	qui count if `score'==`i'
+	local effscore`i'=r(N)
+	if `i'!=0&`i'!=`nbgroups'&`effscore`i''<30 {
+		local smallgroup=1
+	}
+}
+/***********************************************************************************************************
+ESTIMATION OF THE DIFFICULTY PARAMETERS
+************************************************************************************************************/
+if "`trace'"!="" {
+  di in green "*** Estimation of the difficulty parameters"
+}
+
+tempname ll coef var beta Vbeta est
+
+if "`method'"=="gee" {
+   qui geekel2d `rep'1-`rep'`nbitems',ll
+   if `r(error)'==1 {
+       di "The variance of the latent trait probably is too high to made the GEE a efficient method to estimate the parameters."
+       error 499
+       exit
+   }
+   scalar `ll'=r(ll)
+   local nbind=r(N)
+   matrix `coef'=r(b)
+   matrix `est'=`coef'
+   matrix `est'[1,`=`nbitems'+1']=sqrt(`est'[1,`=`nbitems'+1'])
+   matrix `var'=r(V)
+   matrix `beta'=`coef'[1,1..`nbitems']
+   matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+   local sig=sqrt(`coef'[1,`=`nbitems'+1'])
+   local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])/sqrt(`nbind')/(`sig'*2)
+}
+
+qui reshape long `rep' , i(`id') j(`item')
+
+tempvar diff tl
+gen `diff'=0
+
+forvalues i=1/`nbitems' {
+	qui gen `rep'`i'=`item'==`i'
+	qui replace `rep'`i'=-`rep'`i'
+}
+
+
+if "`method'"=="mml" {
+   qui xtlogit `rep' `rep'1-`rep'`nbitems', i(`id') nocons
+   matrix `est'=e(b)
+   matrix `est'[1,`=`nbitems'+1']=exp(`est'[1,`=`nbitems'+1']/2)
+}
+else if "`method'"=="cml" {
+	qui clogit `rep' `rep'1-`rep'`=`nbitems'-1', group(`id')
+}
+
+if "`method'"!="gee" {
+   matrix `coef'=e(b)
+   scalar `ll'=e(ll)
+   local nbind=e(N)/`nbitems'
+   matrix `var'=e(V)
+
+
+   if "`meandiff'"!="" {
+      matrix `var'=J(`nbitems',`nbitems',.)
+      matrix `coef'=J(1,`nbitems',.)
+      local param
+      local lin `rep'1
+      forvalues j=2/`=`nbitems'-1' {
+         local lin `lin'+`rep'`j'
+      }
+      local lin (`lin')/`nbitems'
+
+      forvalues j=1/`=`nbitems'-1' {
+         qui lincom `rep'`j'-`lin'
+         matrix `coef'[1,`j']=`r(estimate)'
+         matrix `var'[`j',`j']=`r(se)'^2
+      }
+      qui lincom -`lin'
+      matrix `coef'[1,`nbitems']=`r(estimate)'
+      matrix `var'[`nbitems',`nbitems']=`r(se)'^2
+   }
+   if "`method'"=="mml" {
+	local sig=e(sigma_u)
+	local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])*`sig'/2
+	matrix `beta'=`coef'[1,1..`nbitems']
+	matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+   }
+   else if "`method'"=="cml"&"`meandiff'"==""{
+	matrix `beta'=`coef'[1,1..`=`nbitems'-1']
+	matrix `Vbeta'=`var'[1..`=`nbitems'-1',1..`=`nbitems'-1']
+   }
+   else if "`method'"=="cml"&"`meandiff'"!=""{
+	matrix `beta'=`coef'
+	matrix `Vbeta'=`var'
+   }
+}
+
+if ("`method'"=="mml"|"`method'"=="gee") {
+   local colnames
+   forvalues i=1/`nbitems' {
+      local colnames "`colnames' `rep':`rep'`i'"
+   }
+   local id2=substr("`id'",1,4)
+   local colnames "`colnames' `id2'1:_cons"
+   matrix colnames `est'=`colnames'
+
+   capture gllamm `rep' `rep'1-`rep'`nbitems', i(`id') nocons family(binom) link(logit) trace from(`est') eval
+   tempname u
+   qui gllapred `u',u
+   tempname theta sdtheta
+   matrix `theta'=J(1,`=`nbitems'+1',0)
+   matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',0)
+   forvalues s=0/`nbitems' {
+      qui su `u'm1 if `realscore'==`s'
+      local theta`s'=r(mean)
+      qui su `u's1 if `realscore'==`s'
+      local sdtheta`s'=r(mean)
+      matrix `theta'[1,`=`s'+1']=`theta`s''
+      matrix `sdtheta'[`=`s'+1',`=`s'+1']=`sdtheta`s''
+   }
+}
+
+forvalues i=1/`nbitems' {
+	if `i'==`nbitems'&"`method'"=="cml"&"`meandiff'"=="" {
+		local beta`i'=0
+		local sd`i' .
+		local fixed`i' "*"
+	}
+	else {
+		local beta`i'=`coef'[1,`i']
+		local sd`i'=sqrt(`var'[`i',`i'])
+	}
+	qui replace `diff'=-`beta`i'' if `item'==`i'
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATIONS
+***********************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+   if "`trace'"!="" {
+     di in green "*** Test of comparison of two populations"
+   }
+         qui inspect `comp'
+         local unique=r(N_unique)
+         if `unique'== 2 {
+		qui su `comp'
+		local mincomp=r(min)
+		local maxcomp=r(max)
+	    	tempname bmin bmax
+	    	qui xtlogit `rep' if `comp'==`mincomp',offset(`diff') i(`id')
+	    	matrix `bmin'=e(b)
+	    	local meanmin=`bmin'[1,1]
+	    	local varmin=e(sigma_u)^2
+	    	local llmin=e(ll)
+	    	local Nmin=e(N_g)
+	    	qui xtlogit `rep' if `comp'==`maxcomp',offset(`diff') i(`id')
+	    	matrix `bmax'=e(b)
+	    	local meanmax=`bmax'[1,1]
+	    	local varmax=e(sigma_u)^2
+	    	local llmax=e(ll)
+	    	local Nmax=e(N_g)
+	    	local Zcomp=(`meanmin'-`meanmax')/sqrt(`varmin'/`Nmin'+`varmax'/`Nmax')
+		local pvalue=1-norm(abs(`Zcomp'))
+	 }
+	 else {
+	        di "It is impossible to compare more than two populations"
+	        di "The comparison process is not run"
+	        local comp
+	 }
+}
+
+/***********************************************************************************************************
+ESTIMATION OF THE ABILITY PARAMETERS  / CML
+************************************************************************************************************/
+if `nbitems'>=2 {
+   if "`trace'"!="" {
+      di in green "*** Estimation of the ability parameters"
+   }
+   if "`method'"=="cml" {
+      tempfile verytmp
+      qui save `verytmp',replace
+      drop _all
+      qui set obs 20001
+      qui gen theta=(_n-10001)/1000
+      qui gen A=1
+      forvalues j=1/`nbitems' {
+         qui gen u`j'=exp(theta-`beta`j'')
+         qui gen p`j'=u`j'/(1+u`j')
+         qui gen a`j'=1/u`j'
+         qui replace A=A*a`j'
+         qui gen i`j'=u`j'/(1+u`j')^2
+         qui gen j`j'=(u`j'*(1-u`j'))/(1+u`j')^3
+      }
+      qui egen P=rsum(p*)
+      qui egen I=rsum(i*)
+      qui egen J=rsum(j*)
+      qui gen V=1/I^2*(I+J^2)/(4*I^2)
+      tempname theta sdtheta
+      matrix `theta'=J(1,`=`nbitems'+1',0)
+      matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',.)
+      forvalues s=0/`nbitems' {
+         qui gen f`s'=abs(`s'-P+.5*J/I)
+         qui sort f`s'
+         matrix `theta'[1,`=`s'+1']=theta[1]
+         matrix `sdtheta'[`=`s'+1',`=`s'+1']=V[1]
+      }
+      use "`verytmp'",replace
+   }
+   qui gen `tl'=0
+   forvalues s=0/`nbitems' {
+      local theta`s'=`theta'[1,`=`s'+1']
+      qui replace `tl'=`theta`s'' if `realscore'==`s'
+      local sdtheta`s'=sqrt(`sdtheta'[`=`s'+1',`= `s'+1'])
+   }
+   tempname pred
+   qui gen `pred'=log(exp(`rep'*(`tl'+`diff'))/(1+exp(`tl'+`diff')))
+
+   qui su `pred'
+   local globalll=r(sum)
+
+   local nulscore=0
+   forvalues i=0/`nbgroups' {
+      qui count if `score'==`i'&`item'==1
+      local nbscore`i'=r(N)
+      if `nbscore`i''==0 {
+         local nulscore=1
+      }
+   }
+   if `nulscore' {
+      di in green "{p}At least one group of scores concerns none individuals. Tests will be not computed.{p_end}"
+      di in green "{p}Use the {hi:group} or the {hi:autogroup} options.{p_end}"
+      local test "NONE"
+      local details
+      local icc
+      local fitgraph
+      local splittest
+   }
+   forvalues i=0/`nbitems' {
+      qui count if `realscore'==`i'&`item'==1
+      local nbrealscore`i'=r(N)
+   }
+}
+
+/***********************************************************************************************************
+TESTS OF THE FIRST ORDER
+************************************************************************************************************/
+
+tempname Pi
+matrix define `Pi'=J(`nbitems',`=`nbitems'-1',0)
+if "`test'"!="NONE" {
+   qui drop if `score'==.
+   if "`trace'"!="" {
+      di in green "*** Tests of the first order"
+   }
+   tempname Obs Obs2 Th Th2
+
+   matrix define `Obs'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Obs2'=J(`nbitems',`=`nbgroups'-1',0)
+   matrix define `Th'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Th2'=J(`nbitems',`=`nbgroups'-1',0)
+   local listofitemsc
+
+   /* Estimation of the gamma symetrical functions*/
+   local c0 "1"
+   local c`nbitems' "`nbitems'*x"
+   forvalues j=1/`nbitems' {
+      local listini`j'
+      local listofitemsc "`listofitemsc' `beta`j''"
+      local c0 `c0'*(1+exp(x-`beta`j''))
+      local c`nbitems' `c`nbitems''-`beta`j''
+      forvalues k=1/`nbitems' {
+         local listini`j'k`k'
+         if `k'!=`j' {
+            local listini`j' "`listini`j'' `beta`k''"
+         }
+         forvalues l=1/`nbitems' {
+            if `l'!=`j'&`l'!=`k' {
+               local listini`j'k`k' "`listini`j'k`k'' `beta`l''"
+            }
+         }
+      }
+   }
+
+   gammasym `listofitemsc'
+
+   /*Estimation, for each value of the score s of the probability to respond to each item (Pi) and of the theorical number of positive responses (Ths) and of theorical number of positive respond per item pair (Ws)*/
+   forvalues s=1/`nbitems' {
+      local denom`s'=r(gamma`s')
+      tempname  W`s'
+      matrix define `W`s''=J(`nbitems',`nbitems',0)
+   }
+   tempvar prob prob2 z y v z2 y2 v2 c r q e
+   qui gen `prob'=.
+   qui gen `prob2'=.
+   forvalues j=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui count if `rep'==1&`item'==`j'&`realscore'==`s'
+         matrix `Obs'[`j',`s']=r(N)
+         if "`test'"!="WP" {
+            gammasym `listini`j''
+            local num`j'=r(gamma`=`s'-1')
+            if "`method'"=="cml"|"`test'"=="Q" {
+               matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s''
+            }
+            else {
+               gausshermite exp(`s'*x)/(`c0'), sigma(`sig')
+               local int`s'=r(int)
+               if "`test'"=="R"&`nbrealscore`s''!=0{
+                  local tmp=exp(-`beta`j'')*`num`j''*`int`s''*`nbind'/`nbrealscore`s''
+                  matrix `Pi'[`j',`s']=`tmp'
+               }
+               else if `nbrealscore`s''==0 {
+                  matrix `Pi'[`j',`s']=0
+               }
+            }
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  if `s'>=2 {
+                     gammasym `listini`j'k`k''
+                     local num`j'k`k'=r(gamma`=`s'-2')
+                     if "`method'"=="cml" {
+                        matrix `W`s''[`j',`k']=`nbrealscore`s''*exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''/`denom`s''
+                     }
+                     else {
+                        matrix `W`s''[`j',`k']=exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''*`int`s''*`nbind'
+                     }
+                     matrix `W`s''[`k',`j']=`W`s''[`j',`k']
+                  }
+               }
+            }
+         }
+         else if "`test'"=="WP" {
+            matrix `Pi'[`j',`s']=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j''))
+         }
+         matrix `Th'[`j',`s']=`Pi'[`j',`s']*`nbrealscore`s''
+         qui replace `prob'=`Pi'[`j',`s'] if `realscore'==`s'&`item'==`j'
+         qui replace `prob2'=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) if `realscore'==`s'&`item'==`j'
+         matrix `W`s''[`j',`j']=`nbrealscore`s''*`Pi'[`j',`s']
+         if "`test'"!="R" {
+            matrix `W`s''[`j',`j']=`W`s''[`j',`j']*abs(1-`Pi'[`j',`s'])
+         }
+      }
+   }
+   qui gen `v2'=abs(`prob'*(1-`prob'))
+   qui gen `z2'=(`rep'-`prob')^2
+   qui gen `y2'=`z2'/`v2'
+   qui gen `c'=abs(`prob'*(1-`prob')*(`prob'^3+(1-`prob')^3))
+   qui gen `r'=`c'/(`v2')^2
+   qui gen `e'=`c'-(`v2')^2
+
+   forvalues j=1/`nbitems' {
+      qui su `y2' if `item'==`j'
+      local outfit`j'=r(mean)
+      qui su `r' if `item'==`j'
+      local Voutfit`j'=r(sum)
+      local Voutfit`j'=`Voutfit`j''/(`nbind')^2-1/`nbind'
+      local outfitstd`j'=(`outfit`j''^(1/3)-1)*(3/sqrt(`Voutfit`j''))-sqrt(`Voutfit`j'')/3
+
+      qui su `z2' if `item'==`j'
+      local n=r(sum)
+      qui su `v2' if `item'==`j'
+      local d=r(sum)
+      local infit`j'=`n'/`d'
+      qui su `e' if `item'==`j'
+      local sume=r(sum)
+      local Vinfit`j'=`sume'/(`d')^2
+      local infitstd`j'=(`infit`j''^(1/3)-1)*(3/sqrt(`Vinfit`j''))-sqrt(`Vinfit`j'')/3
+   }
+   tempname tmp stattest testitems
+
+   /*Estimation, by scores group g, of the theorical number of positive response (Th2g) and of the positive respond to each items pair (W2g)*/
+   scalar `stattest'=0
+   forvalues g=1/`=`nbgroups'-1' {
+      tempname  W2`g' d2`g'
+      matrix define `W2`g''=J(`nbitems',`nbitems',0)
+      forvalues s=`liminf`g''/`limsup`g'' {
+         forvalues j=1/`nbitems' {
+            matrix `Obs2'[`j',`g']=`Obs2'[`j',`g']+`Obs'[`j',`s']
+            matrix `Th2'[`j',`g']=`Th2'[`j',`g']+`Th'[`j',`s']
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  matrix `W2`g''[`j',`k']=`W2`g''[`j',`k']+`W`s''[`j',`k']
+                  matrix `W2`g''[`k',`j']=`W2`g''[`j',`k']
+               }
+            }
+            matrix `W2`g''[`j',`j']=`W2`g''[`j',`j']+`W`s''[`j',`j']
+         }
+      }
+
+      /*Estimation of the d2g vectors*/
+      matrix `d2`g''=`Obs2'[1..`nbitems',`g']-`Th2'[1..`nbitems',`g']
+
+      /*Estimation of the influences on the test of each item (testitemsg matrix) and of the test statistic (stattest)*/
+      tempname test`g' testitems`g'
+      matrix `test`g''=`d2`g'''*syminv(`W2`g'')*`d2`g''
+      capture matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      if _rc!=0 {
+         matrix `tmp'=J(`nbitems',`nbitems',0)
+         forvalues j=1/`nbitems' {
+            matrix `tmp'[`j',`j']=`W2`g''[`j',`j']
+         }
+         di in green "Group `g' (`liminf`g''/`limsup`g''): The weight matrix is not positive-definite, the diagonal matrix is used to estimate the contribution of the items on the `wpname' statistic"
+         matrix list `tmp'
+         matrix `testitems`g''=cholesky(syminv(`tmp'))*`d2`g''
+      }
+      else {
+         matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      }
+      scalar `stattest'=`stattest'+`test`g''[1,1]
+   }
+   matrix `testitems'=J(`nbitems',1,0)
+   forvalues j=1/`nbitems' {
+      forvalues g=1/`=`nbgroups'-1' {
+         matrix `testitems'[`j',1]=`testitems'[`j',1]+`testitems`g''[`j',1]^2
+      }
+   }
+
+   /*Adaptation for the Q1 statistic*/
+   if "`test'"=="Q" {
+      scalar `stattest'=`stattest'*`=`nbitems'-1'/`nbitems'
+   }
+
+   /*Correction for R1m and Q1m*/
+   if ("`test'"=="R"|"`test'"=="Q")&("`method'"=="mml"|"`method'"=="gee") {
+      local c`nbitems' exp(`c`nbitems'')/(`c0')
+      local c0 1/(`c0')
+      gausshermite `c0', sigma(`sig')
+      local ci0=r(int)*`nbind'
+      gausshermite `c`nbitems'',sigma(`sig')
+      local ci`nbitems'=`nbind'*r(int)
+      scalar `stattest'=`stattest'+(`nbrealscore0'-`ci0')^2/`ci0'+(`nbrealscore`nbitems''-`ci`nbitems'')^2/`ci`nbitems''
+  }
+
+
+
+/***********************************************************************************************************
+TESTS U
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests U"
+      }
+
+      local quartile=`nbind'/4
+      local c1=0
+      local n1=0
+      while `n1'<`quartile' {
+         local c1=`c1'+1
+         local n1=`n1'+`nbrealscore`c1''
+      }
+      local c2=`nbitems'
+      local n2=0
+      while `n2'<`quartile' {
+         local c2=`c2'-1
+         local n2=`n2'+`nbrealscore`c2''
+      }
+      forvalues j=1/`nbitems' {
+         local zu1=0
+         local zu2=0
+         forvalues s=1/`c1' {
+            local zu1=`zu1'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         forvalues s=`c2'/`=`nbitems'-1' {
+            local zu2=`zu2'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         local U`j'=(`zu1'-`zu2')/sqrt(`c1'+`nbitems'-`c2')
+      }
+   }
+
+
+
+/***********************************************************************************************************
+TESTS OF THE SECOND ORDER /*undocumented in beta test*/
+************************************************************************************************************/
+
+   if "`q2'"!="" {
+      if "`trace'"!="" {
+         di in green "*** Tests of the second order"
+      }
+
+      tempfile Q2file
+      qui save "`Q2file'",replace
+      qui use "`saveraschtest'",replace
+
+      qui keep if `touse'==1
+      gen `score'=0
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'
+	 rename ``i'' `rep'`i'
+	 qui replace `score'=`score'+`rep'`i'
+      }
+      qui recode `score' `recode'
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'=0
+         forvalues j=`=`i'+1'/`nbitems' {
+	    local listinci`i'j`j'
+	    forvalues k=1/`nbitems' {
+	       if `k'!=`i'&`k'!=`j' {
+	          local listinci`i'j`j' "`listinci`i'j`j'' `beta`k''"
+	       }
+	    }
+	 }
+      }
+
+      local Q2tot=0
+      forvalues k=2/`=`nbitems'-1' {
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`i'+1'/`nbitems' {
+	       if `k'==1 {
+	          local num=0
+               }
+	       else {
+	          gammasym `listinci`i'j`j''
+                  local num=r(gamma`=`k'-2')
+               }
+	       local athi`i'j`j'k`k'=exp(-`beta`i'')*exp(-`beta`j'')*`num'/`denom`k''
+	       local bthi`i'j`j'k`k'=`nbth`i's`k''-`athi`i'j`j'k`k''
+	       local cthi`i'j`j'k`k'=`nbth`j's`k''-`athi`i'j`j'k`k''
+	       local dthi`i'j`j'k`k'=1-`athi`i'j`j'k`k''-`bthi`i'j`j'k`k''-`cthi`i'j`j'k`k''
+            }
+         }
+      }
+      forvalues k=1/`=`nbgroups'-1' {
+         local Q2`k'=0
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`j'+1'/`nbitems' {
+	       qui count if  `rep'`i'==1&`rep'`j'==1&`score'==`k'
+	       local aempi`i'j`j'k`k'=r(N)
+	       local ath2i`i'j`j'k`k'=0
+	       local bth2i`i'j`j'k`k'=0
+	       local cth2i`i'j`j'k`k'=0
+	       local dth2i`i'j`j'k`k'=0
+	    }
+	 }
+         if `limsup`k''!=1 {
+            forvalues l=`liminf`k''/`limsup`k'' {
+	       forvalues i=1/`=`nbitems'-1' {
+	          forvalues j=`=`i'+1'/`nbitems' {
+		     if `l'!=1 {
+		        local ath2i`i'j`j'k`k'=`ath2i`i'j`j'k`k''+`athi`i'j`j'k`l''*`nbrealscore`l''
+			local bth2i`i'j`j'k`k'=`bth2i`i'j`j'k`k''+`bthi`i'j`j'k`l''*`nbrealscore`l''
+			local cth2i`i'j`j'k`k'=`cth2i`i'j`j'k`k''+`cthi`i'j`j'k`l''*`nbrealscore`l''
+			local dth2i`i'j`j'k`k'=`dth2i`i'j`j'k`k''+`dthi`i'j`j'k`l''*`nbrealscore`l''
+                     }
+		  }
+               }
+            }
+	    forvalues i=1/`=`nbitems'-1' {
+	       forvalues j=`=`i'+1'/`nbitems' {
+	          local d2i`i'j`j'k`k'=(`aempi`i'j`j'k`k''-`ath2i`i'j`j'k`k'')^2
+		  local Q2i`i'j`j'k`k'=`d2i`i'j`j'k`k''/`ath2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`bth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`cth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`dth2i`i'j`j'k`k''
+		  local Q2i`i'=`Q2i`i''+`Q2i`i'j`j'k`k''
+		  local Q2i`j'=`Q2i`j''+`Q2i`i'j`j'k`k''
+		  local Q2`k'=`Q2`k''+`Q2i`i'j`j'k`k''
+	       }
+	    }
+	 }
+         local Q2tot=`Q2tot'+`Q2`k''
+      }
+      forvalues i=1/`nbitems' {
+         di in green "Item ``i'' : Q2 = `Q2i`i''"
+      }
+      local Q2=`Q2tot'*(`nbitems'-3)/(`nbitems'-1)
+      di in green "Q2 = `Q2tot'"
+      qui use "`Q2file'",replace
+   }
+
+/***********************************************************************************************************
+TEST LR Z
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests LR of Andersen"
+      }
+      local ssll=0
+      tempname Zfile
+      qui save "`Zfile'", replace
+      qui use "`saveraschtest'",replace
+      qui keep if `touse'==1
+      gen `score'=0
+      forvalues j=1/`nbitems' {
+         qui replace `score'=`score'+``j''
+      }
+      qui recode `score' `recode' `nbitems'=`nbgroups'
+      forvalues i=1/`=`nbgroups'-1' {
+         if `effscore`i''>0 {
+            qui raschtestv7 `varlist' if `score'==`i', test(NONE) `ld'
+            local ll`i'=r(cll)
+            local ssll=`ssll'+(`ll`i'')
+         }
+      }
+      local Z=2*`ssll'-2*`ll'
+      use "`Zfile'",replace
+      tempname AndersenZ
+      matrix define `AndersenZ'=(`Z',`=(`nbgroups'-2)*(`nbitems'-1)',1-chi2(`=(`nbitems'-1)*(`nbgroups'-2)',`Z'))
+   }
+}
+
+
+/***********************************************************************************************************
+DISPLAYING RESULTS WITH TESTS
+************************************************************************************************************/
+
+if "`test'"!="NONE" {
+   local conttest= "_c"
+}
+di
+tempname itemfit globalfit
+matrix `globalfit'=J(1,3,0)
+if "`method'"=="cml" {
+   di in green "Estimation method: " in yellow  "Conditional maximum likelihood (CML)"
+   local nbtest=`nbgroups'-1
+   local line=77
+}
+else if "`method'"=="mml"{
+   di in green "Estimation method: " in yellow  "Marginal maximum likelihood (MML)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+else if "`method'"=="gee" {
+   di in green "Estimation method: " in yellow  "Generalized Estimating Equations (GEE)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+if "`test'"=="NONE" {
+   local line=35
+}
+di in green  "Number of items: " in yellow  `nbitems'
+
+di in green  "Number of groups: " in yellow  `=`nbgroups'+1' `conttest'
+if "`test'"!="NONE" {
+   di in green " (" in yellow "`nbtest'" in green " of them are used to compute the statistics of test)"
+}
+if "`method'"=="cml" {
+   local nbind=`nbind'+`effscore0'+`effscore`nbgroups''
+   local cont "_c"
+   matrix `itemfit'=J(`nbitems',6,0)
+}
+else {
+   local cont
+   matrix `itemfit'=J(`nbitems',5,0)
+}
+local missing=`N'-`nbind'
+di in green "Number of individuals: " in yellow `N'
+di in green "Number of individuals with missing values: " in yellow `nbindmiss' _c
+if "`ld'"=="" {
+   di in green " (removed)"
+}
+else {
+   di
+}
+di in green  "Number of individuals with nul or perfect score: " in yellow `=`effscore0'+`effscore`nbgroups'''
+if "`method'"=="cml" {
+   di in green  "Conditional log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+else {
+   di in green "Marginal log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+di
+noi di in green  _col(16) "Difficulty" `conttest'
+if "`test'"!="NONE" {
+   di in green _col(58) "Standardized"
+}
+noi di in green _col(9) "Items" _col(16) "parameters" _col(28) "std Err." `conttest'
+if "`test'"!="NONE" {
+   local varin=int(2/sqrt(`nbind')*100)/100
+   local varout=int(6/sqrt(`nbind')*100)/100
+   di _col(41) "`namewp'" _col(47) "df" _col(50) "p-value" _col(58) "Outfit" _col(66) "Infit" `cont'
+   if "`method'"=="cml" {
+      di in green _col(77) "U"
+   }
+}
+di in green  "{hline `line'}"
+forvalues i=1/`nbitems' {
+   noi di in yellow _col(3) %12s abbrev("``i''`fixed`i''" ,12) in yellow _col(18) %8.5f `beta`i'' _col(29) %6.5f `sd`i'' `conttest'
+   if "`test'"!="NONE" {
+      di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfitstd`i'' _col(65) %6.3f `infitstd`i''  /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/  `cont'
+      matrix `itemfit'[`i',1]=`testitems'[`i',1]
+      matrix `itemfit'[`i',2]=`=`nbgroups'-2'
+      matrix `itemfit'[`i',3]=1-chi2(`=`nbgroups'-2',`testitems'[`i',1])
+      matrix `itemfit'[`i',4]=`outfitstd`i''
+      matrix `itemfit'[`i',5]=`infitstd`i''
+      if "`method'"=="cml" {
+         di in ye _col(72) %6.3f `U`i''
+         matrix `itemfit'[`i',6]=`U`i''
+      }
+   }
+}
+di in green  "{hline `line'}"
+if "`test'"!="NONE" {
+   if "`method'"=="cml" {
+      local df=(`nbgroups'-2)*(`nbitems'-1)
+   }
+   else {
+      local df=(`nbgroups'-1)*(`nbitems'-1)-1
+   }
+   matrix `globalfit'=(`stattest',`df',1-chi2(`df',`stattest'))
+   noi di in green _col(6) "`descwp'" _col(32) in gr "`namewp'=" _col(36) in ye %8.3f `globalfit'[1,1] _col(46) %3.0f `globalfit'[1,2] _col(51) %6.4f `globalfit'[1,3]
+   if "`method'"=="cml" {
+      noi di in green _col(6) "Andersen LR test" _col(34) "Z=" in yellow _col(36) %8.3f `AndersenZ'[1,1] _col(46) %3.0f `AndersenZ'[1,2] _col(51) %6.4f `AndersenZ'[1,3]
+   }
+   di in green  "{hline `line'}"
+}
+if "`method'"!="cml" {
+   di in green _col(10) in yellow "Sigma" _col(18) %8.5f `sig' _col(29) %6.5f `sesig'
+   di in green  "{hline `line'}"
+}
+
+if "`method'"=="cml"&"`meandiff'"==""{
+   di in green "*: The difficulty parameter of this item had been fixed to 0"
+}
+if "`method'"=="cml"&"`meandiff'"!=""{
+   di in green "The mean of the difficulty parameters is fixed to 0"
+}
+if `smallgroup'==1&"`test'"!="NONE" {
+   di in green "You have groups of scores with less than 30 individuals. The tests can be invalid."
+}
+if "`method'"!="cml"&"`test'"=="Q" {
+   di in green "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test."
+}
+
+/*Tabular of the estimated values of the latent trait*/
+
+   di
+   di
+   noi di in green _col(33) "Ability" _col(60) "Expected"
+   noi di in green _col(17) "Group" _col(23) "Score" _col(30) "parameters" _col(42) "std Err." _col(54) "Freq." _col(63) "Score"_c
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      noi di in green _col(75) "ll"
+   }
+   else {
+      noi di ""
+   }
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      local line=62
+   }
+   else {
+     local line=51
+   }
+   di in green _col(17) "{hline `line'}"
+   local nonul=0
+   forvalues g=0/`nbgroups' {
+      if `g'!=0 {
+         di in green _col(17) "{dup `line':-}"
+      }
+      forvalues s=`liminf`g''/`limsup`g'' {
+         if `s'==`liminf`g'' {
+            local tmp `ll`g''
+            local gr `g'
+         }
+         else {
+            local tmp
+            local gr
+         }
+         local expscore`nonul'=0
+         forvalues i=1/`nbitems' {
+            local expscore`nonul'=`expscore`nonul''+1/(1+exp(-`theta`nonul''+`beta`i''))
+         }
+         if "`method'"=="cml" {
+            local format1 %8.3f
+         }
+         else {
+            local format1 %8.5f
+         }
+         noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(32) `format1' `theta`nonul'' _col(42) `format1' `sdtheta`nonul'' _col(55) %4.0f `nbrealscore`s'' _col(64) % 4.2f `expscore`nonul'' _col(68) %11.4f `tmp'
+         local nonul=`nonul'+1
+      }
+   }
+   di in green _col(17) "{hline `line'}"
+
+
+/***********************************************************************************************************
+DETAILS OPTION
+************************************************************************************************************/
+
+if "`details'"!="" {
+   forvalues g=0/`nbgroups' {
+      if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" {
+         di
+         di in  green "{hline 44}"
+         di in green "Group: " in ye "`g'" in green " from " in ye "`liminf`g''" in green " to " in ye "`limsup`g''" in green " (n=" in ye "`nbscore`g''" in green")"
+         di
+         di _col(3) "Item" _col(10) "Observed" _col(23) "Expected" _col(37) "Scaled"
+         di in green "{dup 44:-}"
+      }
+      if `g'!=0&`g'!=`nbgroups' {
+         forvalues j=1/`nbitems' {
+            local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j'])
+            di _col(3) in ye "``j''" _col(14) %4.0f `Obs2'[`j',`g'] _col(25) %6.2f `Th2'[`j',`g'] _col(36) %7.4f `tmp'
+         }
+         di in green "{dup 44:-}"
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `test`g''[1,1]
+      }
+      else if "`method'"!="cml" {
+         if `g'==0 {
+            local h=0
+         }
+         else {
+            local h=`nbitems'
+         }
+         local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'')
+         di in ye _col(14) %4.0f `nbrealscore`h'' _col(25) %6.2f `ci`h'' _col(36) %7.4f `tmp'
+         di in green "{dup 44:-}"
+         local tmp=`tmp'^2
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `tmp'
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION ICC
+************************************************************************************************************/
+
+if "`icc'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Items Characteristic Curves"
+   }
+   tempvar proba propemp propth propthb
+   qui replace `tl'=. if `realscore'==0|`realscore'==`nbitems'|`realscore'==.
+   qui gen `propemp'=.
+   qui gen `propth'=.
+   qui gen `propthb'=.
+   label variable `propth' "Expected ICC"
+   label variable `propemp' "Observed ICC"
+   label variable `propthb' "Expected ICC"
+   label variable `tl' "Latent trait"
+   global iccs
+   forvalues i=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui replace `propthb'=exp(`theta`s''-`beta`i'')/(1+exp(`theta`s''-`beta`i'')) if `item'==`i'&`realscore'==`s'
+      }
+      qui replace `propemp'=.
+      qui replace `propth'=.
+      tempvar propemp`i' propth`i'
+      qui bysort `realscore' `item' : egen `propth`i''=mean(`propthb') if `item'==`i'
+      qui bysort `realscore' `item' : egen `propemp`i''=mean(`rep') if `item'==`i'
+      qui replace `propth'=`propth`i'' if `item'==`i'
+      qui replace `propemp'=`propemp`i'' if `item'==`i'
+      local mintl=floor(`theta1')
+      local maxtl=floor(`theta`=`nbitems'-1'')+1
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\icc``i''"
+      }
+      if "`v8'"!="" {
+         graph twoway (line  `propemp' `propth' `tl') if `item'==`i' , name(icc``i'',replace) ytitle("")  ylabel(0(.25)1) title("Observed and Expected ICC for the item ``i''") xlabel(`mintl'(1)`maxtl') `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save icc``i''  "`saving'" , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui graph `propemp' `propth' `tl' if `item'==`i' , twoway `saving' c(ll) ylabel(0(.25)1)   xlabel(`mintl'(1)`maxtl') title("Observed and Expected ICC for the item ``i''")
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION INFORMATION
+************************************************************************************************************/
+
+if "`information'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Information graph"
+   }
+
+   tempfile saveinfo
+   qui save "`saveinfo'",replace
+   tempvar info latent
+   drop _all
+   qui set obs 2001
+   gen `latent'=((_n-1)/1001-1)*3
+   label variable `latent' "latent trait"
+   gen `info'=0
+   forvalues i=1/`nbitems' {
+      qui replace `info'=`info'+exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2
+   }
+   local saving "`dirsave'\\information"
+   if "`v8'"!="" {
+      graph twoway (line  `info' `latent') , name(information,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the scale") `draw'
+      if "`filessave'"!="" {
+         graph save information "`saving'" , `replace'
+      }
+      pause
+   }
+   else {
+      if "`filessave'"!="" {
+         local saving "saving(`saving'"
+         if "`replace'"=="" {
+            local saving "`saving')"
+         }
+         else {
+            local saving "`saving',replace)"
+         }
+      }
+      if "`filessave'"=="" {
+         local saving
+      }
+      qui graph `info' `latent' , twoway  `saving' c(l) xlabel(-3(1)3) title("Information graph of the scale")
+      pause
+   }
+   qui use "`saveinfo'",replace
+}
+
+/***********************************************************************************************************
+OPTION FITGRAPH
+************************************************************************************************************/
+
+if "`fitgraph'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graphical validation of the fit"
+   }
+   *set trace on
+   tempname outfit meanz2 meanv2 sumd infit Voutfit outfitstd Vinfit infitstd
+   qui egen `outfit'=mean(`y2'),by(`id')
+   qui egen `Voutfit'=sum(`r'),by(`id')
+   qui replace `Voutfit'=`Voutfit'/(`nbitems')^2-1/`nbitems'
+   qui gen `outfitstd'=(`outfit'^(1/3)-1)*(3/sqrt(`Voutfit'))-sqrt(`Voutfit')/3
+   qui egen `meanz2'=sum(`z2'),by(`id')
+   qui egen `meanv2'=sum(`v2'),by(`id')
+   qui gen `infit'=`meanz2'/`meanv2'
+   qui egen `Vinfit'=sum(`e'),by(`id')
+   qui replace `Vinfit'=`Vinfit'/(`meanv2')^2
+   qui gen `infitstd'=(`infit'^(1/3)-1)*(3/sqrt(`Vinfit'))-sqrt(`Vinfit')/3
+
+   qui su `outfitstd'
+   local mino=floor(2*min(`r(min)',-2))/2
+   local maxo=ceil(2*max(`r(max)',2))/2
+   qui su `infitstd'
+   local mini=floor(2*min(`r(min)',-2))/2
+   local maxi=ceil(2*max(`r(max)',2))/2
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfitind"
+      local savingi "`dirsave'\\infitind"
+   }
+   if "`v8'"!="" {
+      *graph twoway (scatter `outfit' `id'), name(outfit,replace) yline(.6 1.4) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(0(.2)2 2(.5)`maxo') `draw'
+      graph twoway (scatter `outfitstd' `id'), name(outfit,replace) yline(-2 2) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw'
+      pause
+      *graph twoway (scatter `infit' `id'), name(infit,replace) yline(.6 1.4) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(0(.2)2 2(.5)`maxi') `draw'
+      graph twoway (scatter `infitstd' `id'), name(infit,replace) yline(-2 2) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfit "`savingo'" , `replace'
+         graph save infit "`savingi'" , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitstd' `id', `savingo' twoway sy(.) c(.) yline(-2 2) title("Outfit indexes") b2title("Individual indexes") l1("") l2title("Outfit") ylabel(`mino'(.5)`maxo')
+      pause
+      graph `infitstd' `id', `savingi' twoway sy(.) c(.) yline(-2 2) title("Infit indexes") b2title("Individual indexes") l1("")  l2title("Infit") ylabel(`mini'(.5)`maxi')
+      pause
+   }
+   drop _all
+   qui set obs `nbitems'
+   tempvar name betap outfitstdj infitstdj
+   qui gen str9 `name'=""
+   qui gen `betap'=.
+   qui gen `outfitstdj'=.
+   qui gen `infitstdj'=.
+   local mino=-2
+   local maxo=2
+   local mini=-2
+   local maxi=2
+   forvalues j=1/`nbitems' {
+      qui replace `name'="``j''" in `j'
+      qui replace `betap'=`beta`j'' in `j'
+      qui replace `outfitstdj'=`outfitstd`j'' in `j'
+      qui replace `infitstdj'=`infitstd`j'' in `j'
+      local mino=floor(min(`mino',`outfitstd`j'')*2)/2
+      local mini=floor(min(`mini',`infitstd`j'')*2)/2
+      local maxo=ceil(max(`maxo',`outfitstd`j'')*2)/2
+      local maxi=ceil(max(`maxi',`infitstd`j'')*2)/2
+   }
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfititems"
+      local savingi "`dirsave'\\infititems"
+   }
+   if "`v8'"!="" {
+      graph twoway (scatter `outfitstdj' `betap',name(outfititem,replace) mlabel(`name')), yline(-2 2) title("Outfit indexes") xtitle("Difficulty") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw'
+      pause
+      graph twoway (scatter `infitstdj' `betap',name(infititem,replace) mlabel(`name')), yline(-2 2) title("Infit indexes") xtitle("Difficulty") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfititem "`savingo'" , `replace'
+         graph save infititem "`savingi'" , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitstdj' `betap', `savingo' twoway c(.) yline(-2 2) title("Outfit indexes") b2title("Difficulty") l1title("") l2title("Outfit") ylabel(`mino'(.5)`maxo') sy([`name'])
+      pause
+      graph `infitstdj' `betap', `savingi' twoway c(.) yline(-2 2) title("Infit indexes") b2title("Difficulty") l1title("") l2title("Infit") ylabel(`mini'(.5)`maxi') sy([`name'])
+      pause
+   }
+}
+
+
+/***********************************************************************************************************
+OPTION SPLITTESTS
+************************************************************************************************************/
+
+if "`splittests'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Splitting tests"
+   }
+   forvalues j=1/`nbitems' {
+      tempname estneg`j' estpos`j'
+      local listitems
+      forvalues k=1/`nbitems' {
+         if `j'!=`k' {
+            local listitems `listitems' ``k''
+         }
+      }
+      qui use "`saveraschtest'",replace
+      qui keep if `touse'==1
+      qui raschtestv7 `listitems' if ``j''==0,test(NONE) meth(cml) `ld'
+      matrix `estneg`j''=r(beta)
+      local llneg=r(cll)
+      qui raschtestv7 `listitems' if ``j''==1,test(NONE) meth(cml) `ld'
+      matrix `estpos`j''=r(beta)
+      local llpos=r(cll)
+      qui raschtestv7 `listitems',test(NONE) meth(cml) `ld'
+      local llnegpos=r(cll)
+      local nbcol=colsof(`estneg`j'')
+      local meanneg=0
+      local meanpos=0
+      forvalues k=1/`nbcol' {
+         local meanneg=`meanneg'+`estneg`j''[1,`k']
+         local meanpos=`meanpos'+`estpos`j''[1,`k']
+      }
+      local meanneg=`meanneg'/`nbitems'
+      local meanpos=`meanpos'/`nbitems'
+      forvalues k=1/`nbcol' {
+         matrix `estneg`j''[1,`k']=`estneg`j''[1,`k']-`meanneg'
+         matrix `estpos`j''[1,`k']=`estpos`j''[1,`k']-`meanpos'
+         if "`method'"=="cml" {
+            matrix `estneg`j''=`estneg`j'',-`meanneg'
+            matrix `estpos`j''=`estpos`j'',-`meanpos'
+         }
+      }
+      drop _all
+      qui set obs `=`nbitems'+1'
+      tempvar neg pos name diag
+      qui gen `neg'=.
+      qui gen `pos'=.
+      qui gen str9 `name'=""
+      local min=`estneg`j''[1,1]
+      local max=`estneg`j''[1,1]
+      forvalues k=1/`=`nbitems'-1' {
+         qui replace `neg'=`estneg`j''[1,`k'] in `k'
+         qui replace `pos'=`estpos`j''[1,`k'] in `k'
+         local min=min(`min',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local max=max(`max',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local tmp:word `k' of `listitems'
+         qui replace `name'="`tmp'" in `k'
+      }
+      local min=floor(`min')
+      local max=floor(`max')+1
+      qui gen `diag'=.
+      qui replace `diag'=`min' in `nbitems'
+      qui replace `diag'=`max' in `=`nbitems'+1'
+      local Zgr=round(2*(`llneg'+`llpos'-`llnegpos'),0.001)
+      local Zgr=substr("`Zgr'",1,6)
+      local pgr=round(1-chi2(`=`nbitems'-1',`Zgr'),0.0001)
+      local pgr=substr("`pgr'",1,5)
+      local note="Z=`Zgr', df=`=`nbitems'-1' , p=`pgr'"
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\split``j''"
+      }
+      if "`v8'"!="" {
+         graph twoway (scatter `pos' `neg' ,mlabel(`name')) (line `diag' `diag'), ytitle("Positive answer") xtitle("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title(Splitting on ``j'') `draw' legend(off) note("Andersen Z test: `note'") name(split,replace) `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save split "`saving'" , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui replace `diag'=`neg' if `diag'==.
+         graph  `pos' `diag' `diag', `saving' c(.l) sy([`name']i) l1title("") l2title("Positive answer") b2title("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title("Splitting on ``j'' (`note')") `draw'
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION GRAPH
+************************************************************************************************************/
+
+if "`graph'"!=""&"`v8'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graph option"
+   }
+   tempvar  latent2  tl2 delta2 tlth2 labdelta2 labtl2
+   drop _all
+   qui set obs 1001
+   gen `latent2'=(_n-501)/100
+   label variable `latent2' "latent trait"
+   qui gen `tl2'=.
+   qui gen `labtl2'=""
+   forvalues i=0/`nbitems' {
+      *if (`i'!=0&`i'!=`nbitems')|"`method'"!="cml" {
+         qui replace `tl2'=`nbrealscore`i''/`N' if round(`latent2',0.01)==round(`theta`i'',0.01)
+         qui replace `labtl2'="`i'" if round(`latent2',0.01)==round(`theta`i'',0.01)
+      *}
+   }
+   qui gen `delta2'=.
+   qui gen `labdelta2'=""
+   forvalues i=1/`nbitems' {
+      qui replace `delta2'=-.05 if round(`latent2',0.01)==round(`beta`i'',0.01)
+      qui replace `labdelta2'="``i''" if round(`latent2',0.01)==round(`beta`i'',0.01)
+   }
+   if "`method'"=="mml"|"`method'"=="gee" {
+      qui gen `tlth2'=1/(2*_pi*`sig')*exp(-.5*(`latent2'/`sig')^2)
+      label variable `tlth2' "Theorical distribution"
+      local graphmml line `tlth2' `latent2'
+   }
+   label variable `tl2' "Score"
+   label variable `delta2' "Items"
+   local saving "`dirsave'\\graph"
+   local min=-2
+   local max=2
+   forvalues j=1/`nbitems' {
+      if `beta`j''<`min' {
+         local min=`beta`j''-.5
+      }
+      if `beta`j''>`max'&`beta`j''!=. {
+         local max=`beta`j''+.5
+      }
+   }
+   if "`method'"=="cml" {
+      if `theta0'<`min' {
+         local min=`theta0'-.5
+      }
+      if `theta`=`nbitems'-1''>`max' {
+         local max=`theta`=`nbitems'-1''+.5
+      }
+   }
+   else if "`method'"!="cml" {
+      if `theta0'<`min'&`theta0'!=. {
+         local min=`theta0'-.5
+      }
+      if `theta`nbitems''>`max'&`theta`nbitems''!=. {
+         local max=`theta`nbitems''+.5
+      }
+   }
+   local min=floor(`min')
+   local max=floor(`max')+1
+   qui su `tl2'
+   local max2=r(max)
+   if "`method'"!="cml" {
+      qui su `tlth2'
+      local max2=max(`max2',`r(max)')
+   }
+   qui replace `latent2'=. if `latent2'<`min'|`latent2'>`max'
+   if "`v8'"!="" {
+      graph twoway (scatter `tl2' `latent2',mlabel(`labtl2')) (dropline `delta2' `latent2',mlabel(`labdelta2') mlabposition(6)) (`graphmml'), name(graph,replace) ytitle("") xlabel(`min'(1)`max') ylabel(-.1 0(0.05)`max2') title("Individuals/items representations") `draw'
+      if "`filessave'"!="" {
+         graph save graph "`saving'" , `replace'
+      }
+      pause
+   }
+}
+else if "`graph'"!=""&"`v8'"=="" {
+   di in ye "The graph option is not available with Stata 7"
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATION
+************************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+      di
+      di _col(4) "{hline 30}"
+      di _col(4) in green "Comparison of two populations"
+      di _col(4) "{hline 30}"
+      di
+      di _col(4) in green "`comp'==`mincomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmin' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmin' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmin'
+      di _col(4) in green "`comp'==`maxcomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmax' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmax' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmax'
+      di                                                                       _col(33) in green "Z= " _col(35) in yellow %8.4f `Zcomp' _col(47) in green "pvalue= "    _col(57) in yellow %6.4f `pvalue'
+}
+
+/***********************************************************************************************************
+TEST DIF
+************************************************************************************************************/
+
+if "`method'"=="cml"&"`dif'"!=""&"`test'"!="NONE" {
+   if "`trace'"!="" {
+      di in green "*** Tests of DIF"
+   }
+   local ssll=0
+   tempname DIFfile
+   qui save "`DIFfile'", replace
+   qui use "`saveraschtest'",replace
+   qui keep if `touse'==1
+   unab list:`dif'
+   local nbdif:word count `list'
+   tempname DIF
+   matrix define `DIF'=J(`nbdif',4,0)
+   local count=1
+   di
+   di _col(4) in green "{hline 45}"
+   di _col(4) in green "Test of Differential Item Functioning (DIF)"
+   di _col(4) in green "{hline 45}"
+   foreach j in `list' {
+      qui inspect `j'
+      local nbdif=r(N_unique)
+      qui su `j'
+      local maxdif=r(max)
+      if `nbdif'>10&`maxdif'<=10 {
+         di in ye "The {hi:dif} option is available with variables containing 10 or less modalities (coded from 0 or 1 to k<10)."
+         di in ye "The variable `j' (`nbdif' modalities) is omitted."
+      }
+      else {
+         local ssll=0
+         forvalues i=0/10 {
+            qui count if `j'==`i'
+            local effdif=r(N)
+            if `effdif'>0 {
+               qui raschtestv7 `varlist' if `j'==`i', test(NONE)
+               local ll`i'=r(cll)
+               local ssll=`ssll'+(`ll`i'')
+            }
+         }
+         local Z=2*`ssll'-2*`ll'
+         local ddl=(`nbdif'-1)*(`nbitems'-1)
+         matrix define `DIF'[`count',1]=(`count',`Z',`ddl',1-chi2(`ddl',`Z'))
+         di
+         di _col(4) in green "Variable:" in ye " `j' " in green "   Number of groups: "  in ye "`nbdif'"
+         di _col(4) in green "LR Test Z=" in ye %8.3f `Z' in gr "   ddl=" in ye %4.0f `ddl' in gr "    p-value=" in ye %6.4f `=1-chi2(`ddl',`Z')'
+         di
+      }
+      local ++count
+   }
+   use "`DIFfile'",replace
+}
+
+/***********************************************************************************************************
+RETURN
+************************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Returns"
+}
+local colnametheta
+
+forvalues i=0/`nbgroups' {
+         local colnametheta `colnametheta' score_`i'
+}
+
+
+return clear
+
+if `nbitems'>=3&"`test'"!="NONE" {
+        matrix colnames `globalfit'=`namewp' df p
+	matrix rownames `globalfit'=`method'
+	matrix rownames `itemfit'=`varlist'
+        matrix roweq `itemfit'=`method'
+
+	if "`method'"=="cml" {
+                matrix colnames `itemfit'=`namewp' df p outfit infit U
+		matrix rownames `AndersenZ'=`method'
+		matrix colnames `AndersenZ'=Z df p
+		return matrix AndersenZ=`AndersenZ'
+                if "`dif'"!="" {
+		   matrix rownames `DIF'=`list'
+		   matrix colnames `DIF'=num Z df p
+		   return matrix DIF=`DIF'
+                }
+	}
+	else {
+                matrix colnames `itemfit'=`namewp' df p outfit infit
+	}
+	return matrix itemFit=`itemfit'
+	return matrix globalFit=`globalfit'
+}
+
+matrix colnames `theta'=`colnametheta'
+matrix rownames `theta'=theta
+return matrix theta `theta'
+matrix colnames `sdtheta'=`colnametheta'
+matrix rownames `sdtheta'=`colnametheta'
+return matrix Vartheta `sdtheta'
+local varlist2
+matrix coleq `beta'=`method'
+matrix coleq `Vbeta'=`method'
+matrix roweq `Vbeta'=`method'
+if "`method'"=="cml" {
+	forvalues i=1/`=`nbitems'-1' {
+		local varlist2 `varlist2' ``i''
+	}
+        return scalar cll=`ll'
+        return scalar ll=`globalll'
+	local AIC=-2*`globalll'+2*(`nbitems'-1)
+}
+else {
+        return scalar ll=`ll'
+	local varlist2 `varlist'
+	return scalar sigma=`sig'
+	return scalar sesigma=`sesig'
+	local AIC=-2*`ll'+2*(`nbitems'+1)
+}
+
+if "`comp'"!="" {
+   return scalar Zcomp=`Zcomp'
+   return scalar pZcomp=`pvalue'
+}
+
+matrix colnames `beta'=`varlist2'
+matrix rownames `beta'=beta
+return matrix beta `beta'
+
+matrix colnames `Vbeta'=`varlist2'
+matrix rownames `Vbeta'=`varlist2'
+return matrix Varbeta `Vbeta'
+
+return scalar AIC=`AIC'
+return scalar N=`nbind'
+
+if "`pause'"!="" {
+   pause off
+}
+
+drop _all
+
+restore,not
+use "`saveraschtest'"
+
+/***********************************************************************************************************
+CREATE EVENTUAL NEW VARIABLES
+************************************************************************************************************/
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+        tempname genlt2 genscore2 outfit2 infit2
+        qui gen `score'=0 `if'
+        forvalues i=1/`nbitems' {
+           qui replace `score'=`score'+``i'' `if'
+        }
+        qui gen `genlt2'=. `if'
+        forvalues i=0/`nbitems' {
+           qui replace `genlt2'=`theta`i'' `if'&`score'==`i'
+        }
+        if "`genscore'"!="" {
+           qui gen `genscore'=`score' `if'
+        }
+        if "`genlt'"!="" {
+           qui gen `genlt'=`genlt2' `if'
+        }
+        if "`genfit'"!="" {
+           local outfit:word 1 of `genfit'
+           local infit:word 2 of `genfit'
+           qui gen `outfit'=0 `if'
+           qui gen `infit'=0  `if'
+           tempname infit1 infit2
+           qui gen `infit1'=0 `if'
+           qui gen `infit2'=0 `if'
+           forvalues j=1/`nbitems' {
+               tempname pi`j'
+               qui gen `pi`j''=exp(`genlt2'-`beta`j'')/(1+exp(`genlt2'-`beta`j'')) `if'
+               qui replace `pi`j''=0  `if'
+               forvalues s=1/`nbitems' {
+                  qui replace `pi`j''=`Pi'[`j',`s'] `if'&`score'==`s'
+               }
+               qui gen `outfit'``j''=(``j''-`pi`j'')^2/(`pi`j''*(1-`pi`j'')) `if'
+               qui replace `infit1'=`infit1'+(``j''-`pi`j'')^2  `if'
+               qui replace `infit2'=`infit2'+(`pi`j''*(1-`pi`j'')) `if'
+               qui replace `outfit'=`outfit'+`outfit'``j''/`nbitems' `if'
+           }
+           qui replace `infit'=`infit1'/`infit2'  `if'
+        }
+}
+
+if "`trace'"!=""|"`time'"!="" {
+    capture qui elapse `st'
+    di in green "** Time : " in yellow "$S_elap " in green "seconds"
+}
+end
diff --git a/Modules/ado/personal/r/old/raschtestv7762.ado b/Modules/ado/personal/r/old/raschtestv7762.ado
new file mode 100644
index 0000000..7f5fc09
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschtestv7762.ado
@@ -0,0 +1,1829 @@
+*! version 7.6.1  26june2008
+*! Jean-Benoit Hardouin
+*************************************************************************************************************
+* Raschtestv7: Rasch model, fit tests and graphical representations
+* Corresponds to the version 7.6 of Raschtest (http://freeirt.org) for Stata7
+*
+* Historic:
+* Version 2.1 (2003-07-10): Jean-Benoit Hardouin
+* Version 3.1 (2004-01-02) : Jean-Benoit Hardouin
+* Version 7.1 (2005-03-30) : Jean-Benoit Hardouin
+* Version 7.2.1 (2005-05-21) : Jean-Benoit Hardouin
+* Version 7.3.1 (2005-07-02) : Jean-Benoit Hardouin
+* Version 7.3.2 (2005-10-05) : Jean-Benoit Hardouin /*correction for the *genlt* option with *method(cml)**/
+* Version 7.3.3 (2005-12-21) : Jean-Benoit Hardouin /*correction if scores are not represented with method(mml) or method(gee)*/
+* Version 7.4.1 (2006-01-17) : Jean-Benoit Hardouin /*Standardized OUTFIT and INFIT, DIF option*/
+* Version 7.4.2 (2006-03-21) : Jean-Benoit Hardouin /*Avoids a bug when the temporary files are saved in a directory containing special characters*/
+* Version 7.4.3 (2006-11-15) : Jean-Benoit Hardouin /*Avoids a bug when the directory defined in the dirsave option contains special characters*/
+* Version 7.5.1 (2007-04-20) : Jean-Benoit Hardouin /*Return results of the comp option*/
+* Version 7.6.1 (2008-06-26) : Jean-Benoit Hardouin /*Nold option, corrects a bug with the genlt option*/
+* Version 7.6.2 (2009-03-01) : Jean-Benoit Hardouin /*Correction of the SE of the latent trait, graph option, correction of a bug with the if option, PSI in MML*/
+*
+* Needed modules :
+* gammasym version 2.1 (http://freeirt.free.fr)
+* gausshermite version 1 (http://freeirt.free.fr)
+* geekel2d version 4.2 (http://freeirt.free.fr)
+* genscore version 1.4 (http://freeirt.free.fr)
+* ghquadm (findit ghquadm)
+* gllamm version 2.3.11 (ssc describe gllamm)
+* gllapred version  2.3.2 (ssc describe gllapred)
+* elapse (ssc describe elapse)
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://anaqol.free.fr
+* FreeIRT Project : http://freeirt.free.fr
+*
+* Copyright 2003-2008 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+DEFINITION / SYNTAX
+***********************************************************************************************************/
+
+
+program define raschtestv7,rclass
+syntax varlist(min=1 numeric) [if] [in] , [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph v8 COMp(varname) dif(varlist) time TRace Details  nold iterate(int 200)]
+
+
+if "`if'"=="" {
+   local if "if 1"
+}
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Tests of conformity"
+}
+if "`v8'"=="" {
+        version 7.0
+}
+else {
+        version 8.0
+}
+
+local st = "$S_TIME"
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+tokenize `varlist'
+
+local bad
+forvalues i=1/`nbitems' {
+   qui count if ``i''!=0&``i''!=1&``i''!=.
+   local N=r(N)
+   if `N'>0 {
+      local bad `bad' ``i''
+   }
+}
+if "`bad'"!="" {
+   di in red "The item(s) {hi:`bad'} is(are) not binary item(s) (with responses 0 or 1)."
+   exit
+}
+
+if "`method'"=="" {
+    local method cml
+}
+if "`test'"=="" {
+    local test R
+}
+local method=lower("`method'")
+local test=upper("`test'")
+if "`method'"!="mml"&"`method'"!="cml"&"`method'"!="gee" {
+    di in red "Uncorrect method option."
+    error 198
+    exit
+}
+
+if "`test'"!="R"&"`test'"!="Q"&"`test'"!="WP"&"`test'"!="NONE" {
+   di in red "Uncorrect test option."
+   error 198
+   exit
+}
+
+if "`genfit'"!="" {
+   local nbwordgenfit:word count `genfit'
+   if `nbwordgenfit'!=2 {
+      di in red "Uncorrect genfit option."
+      di in red "This option must contain exactly two words"
+      error 198
+      exit
+   }
+}
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+   confirm new variable `genfit' `genlt' `genscore'
+   if "`genfit'"!="" {
+      local o:word 1 of `genfit'
+      forvalues i=1/`nbitems' {
+         confirm new variable `o'``i''
+      }
+   }
+}
+
+preserve
+
+tempfile saveraschtest
+qui save `saveraschtest'
+qui keep if `touse'==1
+
+if "`autogroup'"!=""&"`group'"!="" {
+   di in green "The autogroup and the group options cannot be defined in the same time"
+   di in green "Only the group option is retained."
+   local autogroup
+}
+
+if "`autogroup'"!="" {
+   tempvar autoscore
+   qui genscore `varlist',score(`autoscore')
+
+   tempname matscore tmp
+   matrix `matscore'=J(`=`nbitems'-1',3,0)
+   forvalues i=1/`=`nbitems'-1' {
+        matrix `matscore'[`i',1]=`i'
+        matrix `matscore'[`i',2]=`i'
+        qui count if `autoscore'==`i'
+        matrix `matscore'[`i',3]=r(N)
+   }
+   local stop=0
+   local j=0
+   while `j'<=`=`nbitems'-3'&`stop'!=1 {
+      local j=`j'+1
+      local scoretogroup=99999999
+      local rowtogroup1=0
+      local rowtogroup2=0
+      local stop=1
+      forvalues i=1/`=`nbitems'-`j'' {
+         if `matscore'[`i',1]>=0 & `matscore'[`i',3]<30 & `matscore'[`i',3]<`scoretogroup' {
+            local scoretogroup=`matscore'[`i',3]
+            local rowtogroup1=`i'
+            local stop=0
+         }
+      }
+      if `stop'!=1 {
+         if `rowtogroup1'>1&`rowtogroup1'<`=`nbitems'-`j'' {
+            if `matscore'[`=`rowtogroup1'-1',1]<`matscore'[`=`rowtogroup1'+1',1] {
+               local rowtogroup2=`rowtogroup1'
+               local rowtogroup1=`rowtogroup1'-1
+            }
+            else {
+               local rowtogroup2=`rowtogroup1'+1
+            }
+         }
+         else if `rowtogroup1'==1 {
+            local rowtogroup2=2
+         }
+         else if `rowtogroup1'==`=`nbitems'-`j'' {
+            local rowtogroup2=`nbitems'-`j'
+            local rowtogroup1=`nbitems'-`j'-1
+         }
+         matrix `tmp'=`matscore'
+         matrix `matscore'=J(`=`nbitems'-`j'',3,0)
+         if `rowtogroup1'!=1 {
+            matrix `matscore'[1,1]=`tmp'[1..`=`rowtogroup1'-1',1..3]
+         }
+         matrix `matscore'[`rowtogroup1',1]=`tmp'[`rowtogroup1',1]
+         matrix `matscore'[`rowtogroup1',2]=`tmp'[`rowtogroup2',2]
+         matrix `matscore'[`rowtogroup1',3]=`tmp'[`rowtogroup1',3]+`tmp'[`rowtogroup2',3]
+         if `rowtogroup2'!=`=`nbitems'-`j'' {
+            matrix `matscore'[`rowtogroup2',1]=`tmp'[`=`rowtogroup2'+1'..`=`nbitems'-`j'',1..3]
+         }
+      }
+   }
+   local nbrows=rowsof(`matscore')-1
+   local thresholds
+   forvalues i=1/`nbrows' {
+      local tmp=`matscore'[`i',2]
+      local thresholds `thresholds' `tmp'
+   }
+   local group `thresholds'
+}
+
+
+if "`group'"=="" {
+	forvalues i=1/`=`nbitems'-1' {
+		local group "`group' `i'"
+	}
+}
+local nbgroups:word count `group'
+local groupmax:word `nbgroups' of `group'
+if `groupmax'>=`nbitems' {
+	di in red "You cannot form a group with the higher possible score."
+	di in red "The higher possible value of the group option is `=`nbitems'-1'."
+        di in red "Please correct your group option."
+	error 198
+        exit
+}
+else {
+	if `groupmax'!=`=`nbitems'-1' {
+		local group "`group' `=`nbitems'-1'"
+		local nbgroups=`nbgroups'+1
+	}
+}
+local nbgroups=`nbgroups'+1
+
+if "`dirsave'"!=""&"`filessave'"=="" {
+        di in ye "If you want to save yours graphs, use the filessave option"
+}
+if "`filessave'"!="" {
+        if "`dirsave'"=="" {
+              local dirsave "`c(pwd)'"
+        }
+        di in ye "The graphs files will be saved in `dirsave'"
+}
+if "`dirsave'"!="" {
+        if "`filesave'"=="" {
+              local filesave "filesave"
+        }
+}
+
+
+if "`pause'"!=""&"`draw'"=="" {
+     pause on
+}
+
+
+/***********************************************************************************************************
+POSSIBLE TEST
+***********************************************************************************************************/
+
+if ("`icc'"!=""|"`fitgraph'"!=""|"`splittest'"!=""|"`details'"!="")&"`test'"=="NONE" {
+	di in green "You cannot use the {hi:details}, {hi:icc}, {hi:fitgraph} or {hi:splittest} options if you use {hi:test(none)}."
+        di in green "These options are ignored."
+	local details
+	local icc
+	local fitgraph
+	local splittest
+}
+if "`comp'"!=""&"`method'"=="cml" {
+   	di in green "You cannot compare two populations ({hi:comp} option) with the CML estimation method"
+   	di in green "This option is ignored."
+        local comp
+}
+if "`method'"!="cml"&"`test'"=="WP" {
+	di in green "The Wright-Panchapakesan test is not authorized with MML or GEE."
+	di in green "The WP tests are replaced by Van den Wollenberg Q tests."
+        local test Q
+}
+if "`method'"=="gee"&"`ld'"!="" {
+	di in green "You cannot use the {hi:nold} option with the GEE method of estimation"
+	di in green "This option is ignored."
+        local ld
+}
+
+
+if "`test'"==""|"`test'"=="R" {
+   local test "R"
+   if "`method'"=="cml" {
+      local namewp "R1c"
+      local descwp "R1c test"
+   }
+   else {
+      local namewp="R1m"
+      local descwp "R1m test"
+   }
+}
+if `nbitems'>999999|"`test'"=="WP" {
+	local namewp "  Y"
+	local descwp "Wright-Panchapakesan Y test"
+	local q2
+}
+ else if "`test'"=="Q" {
+	local namewp " Q1"
+	local descwp "Van den Wollenberg Q1 test"
+}
+
+if "`method'"!="cml"&"`meandiff'"!="" {
+	di in green "The {hi:meandiff} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local meandiff
+}
+
+if "`method'"!="cml"&"`splittests'"!="" {
+	di in green "The {hi:splittests} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local splittests
+}
+if "`method'"!="cml"&"`dif'"!="" {
+	di in green "The {hi:dif} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local dif
+}
+
+/***********************************************************************************************************
+SCORES AND GROUPS
+************************************************************************************************************/
+
+qui count if `touse'==1
+local N=r(N)
+
+
+tempvar id
+gen `id'=_n
+
+
+qui keep `varlist' `comp' `id' `touse'
+
+tempname rep item
+tempvar score realscore
+qui genscore `varlist',score(`score')
+*   di "LD : `ld'"
+qui count if `score'==.&`touse'==1
+local nbindmiss=r(N)
+
+if "`ld'"=="" {
+   qui drop if `score'==.
+}
+forvalues i=1/`nbitems' {
+	rename ``i'' `rep'`i'
+	*qui drop if `rep'`i'==.|`rep'`i'>1
+	*qui replace `score'=`score'+`rep'`i'
+}
+
+
+
+local liminf0=0
+local limsup0=0
+local liminf`nbgroups'=`nbitems'
+local limsup`nbgroups'=`nbitems'
+
+
+local recode
+forvalues i=1/`=`nbgroups'-1' {
+	if `i'!= 1{
+		local liminf`i' : word `=`i'-1' of `group'
+	}
+	else {
+		local liminf1=0
+	}
+	local liminf`i'=`liminf`i''+1
+	local limsup`i':word `i' of `group'
+
+	local recode "`recode' `liminf`i''/`limsup`i''=`i'"
+}
+qui gen `realscore'=`score'
+qui recode `score' `recode' `nbitems'=`nbgroups'
+
+local smallgroup=0
+
+forvalues i=0/`nbgroups' {
+	qui count if `score'==`i'
+	local effscore`i'=r(N)
+	if `i'!=0&`i'!=`nbgroups'&`effscore`i''<30 {
+		local smallgroup=1
+	}
+}
+/***********************************************************************************************************
+ESTIMATION OF THE DIFFICULTY PARAMETERS
+************************************************************************************************************/
+if "`trace'"!="" {
+  di in green "*** Estimation of the difficulty parameters"
+}
+
+tempname ll coef var beta Vbeta est
+
+if "`method'"=="gee" {
+   qui geekel2d `rep'1-`rep'`nbitems',ll
+   if `r(error)'==1 {
+       di "The variance of the latent trait probably is too high to made the GEE a efficient method to estimate the parameters."
+       error 499
+       exit
+   }
+   scalar `ll'=r(ll)
+   local nbind=r(N)
+   matrix `coef'=r(b)
+   matrix `est'=`coef'
+   matrix `est'[1,`=`nbitems'+1']=sqrt(`est'[1,`=`nbitems'+1'])
+   matrix `var'=r(V)
+   matrix `beta'=`coef'[1,1..`nbitems']
+   matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+   local sig=sqrt(`coef'[1,`=`nbitems'+1'])
+   local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])/sqrt(`nbind')/(`sig'*2)
+}
+
+qui reshape long `rep' , i(`id') j(`item')
+
+tempvar diff tl
+gen `diff'=0
+
+forvalues i=1/`nbitems' {
+	qui gen `rep'`i'=`item'==`i'
+	qui replace `rep'`i'=-`rep'`i'
+}
+
+
+if "`method'"=="mml" {
+   noi xtlogit `rep' `rep'1-`rep'`nbitems', i(`id') nocons iterate(`iterate')  
+   matrix `est'=e(b)
+   matrix `est'[1,`=`nbitems'+1']=exp(`est'[1,`=`nbitems'+1']/2)
+}
+else if "`method'"=="cml" {
+	qui clogit `rep' `rep'1-`rep'`=`nbitems'-1', group(`id')
+}
+
+if "`method'"!="gee" {
+   matrix `coef'=e(b)
+   scalar `ll'=e(ll)
+   local nbind=e(N)/`nbitems'
+   matrix `var'=e(V)
+
+
+   if "`meandiff'"!="" {
+      matrix `var'=J(`nbitems',`nbitems',.)
+      matrix `coef'=J(1,`nbitems',.)
+      local param
+      local lin `rep'1
+      forvalues j=2/`=`nbitems'-1' {
+         local lin `lin'+`rep'`j'
+      }
+      local lin (`lin')/`nbitems'
+
+      forvalues j=1/`=`nbitems'-1' {
+         qui lincom `rep'`j'-`lin'
+         matrix `coef'[1,`j']=`r(estimate)'
+         matrix `var'[`j',`j']=`r(se)'^2
+      }
+      qui lincom -`lin'
+      matrix `coef'[1,`nbitems']=`r(estimate)'
+      matrix `var'[`nbitems',`nbitems']=`r(se)'^2
+   }
+   if "`method'"=="mml" {
+	local sig=e(sigma_u)
+	local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])*`sig'/2
+	matrix `beta'=`coef'[1,1..`nbitems']
+	matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+   }
+   else if "`method'"=="cml"&"`meandiff'"==""{
+	matrix `beta'=`coef'[1,1..`=`nbitems'-1']
+	matrix `Vbeta'=`var'[1..`=`nbitems'-1',1..`=`nbitems'-1']
+   }
+   else if "`method'"=="cml"&"`meandiff'"!=""{
+	matrix `beta'=`coef'
+	matrix `Vbeta'=`var'
+   }
+}
+
+if ("`method'"=="mml"|"`method'"=="gee") {
+   local colnames
+   forvalues i=1/`nbitems' {
+      local colnames "`colnames' `rep':`rep'`i'"
+   }
+   local id2=substr("`id'",1,4)
+   local colnames "`colnames' `id2'1:_cons"
+   matrix colnames `est'=`colnames'
+
+   capture gllamm `rep' `rep'1-`rep'`nbitems', i(`id') nocons family(binom) link(logit) trace from(`est') eval
+   tempname u
+   qui gllapred `u',u
+   tempname theta sdtheta
+   matrix `theta'=J(1,`=`nbitems'+1',0)
+   matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',0)
+   qui su `u'm1 if `rep'1==-1
+   local vartheta=r(Var)
+   qui gen `u's2=`u's1^2
+   qui su `u's2 if `rep'1==-1
+   local meanse2=r(mean)
+   local psi=1-`meanse2'/`vartheta'
+   forvalues s=0/`nbitems' {
+      qui su `u'm1 if `realscore'==`s'
+      local theta`s'=r(mean)
+      qui su `u's1 if `realscore'==`s'
+      local sdtheta`s'=r(mean)
+      matrix `theta'[1,`=`s'+1']=`theta`s''
+      matrix `sdtheta'[`=`s'+1',`=`s'+1']=`sdtheta`s''
+   }
+}
+
+forvalues i=1/`nbitems' {
+	if `i'==`nbitems'&"`method'"=="cml"&"`meandiff'"=="" {
+		local beta`i'=0
+		local sd`i' .
+		local fixed`i' "*"
+	}
+	else {
+		local beta`i'=`coef'[1,`i']
+		local sd`i'=sqrt(`var'[`i',`i'])
+	}
+	qui replace `diff'=-`beta`i'' if `item'==`i'
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATIONS
+***********************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+   if "`trace'"!="" {
+     di in green "*** Test of comparison of two populations"
+   }
+         qui inspect `comp'
+         local unique=r(N_unique)
+         if `unique'== 2 {
+		qui su `comp'
+		local mincomp=r(min)
+		local maxcomp=r(max)
+	    	tempname bmin bmax
+	    	qui xtlogit `rep' if `comp'==`mincomp',offset(`diff') i(`id')
+	    	matrix `bmin'=e(b)
+	    	local meanmin=`bmin'[1,1]
+	    	local varmin=e(sigma_u)^2
+	    	local llmin=e(ll)
+	    	local Nmin=e(N_g)
+	    	qui xtlogit `rep' if `comp'==`maxcomp',offset(`diff') i(`id')
+	    	matrix `bmax'=e(b)
+	    	local meanmax=`bmax'[1,1]
+	    	local varmax=e(sigma_u)^2
+	    	local llmax=e(ll)
+	    	local Nmax=e(N_g)
+	    	local Zcomp=(`meanmin'-`meanmax')/sqrt(`varmin'/`Nmin'+`varmax'/`Nmax')
+		local pvalue=1-norm(abs(`Zcomp'))
+	 }
+	 else {
+	        di "It is impossible to compare more than two populations"
+	        di "The comparison process is not run"
+	        local comp
+	 }
+}
+
+/***********************************************************************************************************
+ESTIMATION OF THE ABILITY PARAMETERS  / CML
+************************************************************************************************************/
+if `nbitems'>=2 {
+   if "`trace'"!="" {
+      di in green "*** Estimation of the ability parameters"
+   }
+   if "`method'"=="cml" {
+      tempfile verytmp
+      qui save `verytmp',replace
+      drop _all
+      qui set obs 20001
+      qui gen theta=(_n-10001)/1000
+      qui gen A=1
+      forvalues j=1/`nbitems' {
+         qui gen u`j'=exp(theta-`beta`j'')
+         qui gen p`j'=u`j'/(1+u`j')
+         qui gen a`j'=1/u`j'
+         qui replace A=A*a`j'
+         qui gen i`j'=u`j'/(1+u`j')^2
+         qui gen j`j'=(u`j'*(1-u`j'))/(1+u`j')^3
+      }
+      qui egen P=rsum(p*)
+      qui egen I=rsum(i*)
+      qui egen J=rsum(j*)
+      qui gen V=1/I^2*(I+J^2)/(4*I^2)
+      qui gen V2=1/I
+      tempname theta sdtheta
+      matrix `theta'=J(1,`=`nbitems'+1',0)
+      matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',.)
+      forvalues s=0/`nbitems' {
+         qui gen f`s'=abs(`s'-P+.5*J/I)
+         qui sort f`s'
+         matrix `theta'[1,`=`s'+1']=theta[1]
+         matrix `sdtheta'[`=`s'+1',`=`s'+1']=sqrt(V2[1])
+      }
+      use "`verytmp'",replace
+   }
+   qui gen `tl'=0
+   forvalues s=0/`nbitems' {
+      local theta`s'=`theta'[1,`=`s'+1']
+      qui replace `tl'=`theta`s'' if `realscore'==`s'
+      local sdtheta`s'=`sdtheta'[`=`s'+1',`= `s'+1']
+   }
+   tempname pred
+   qui gen `pred'=log(exp(`rep'*(`tl'+`diff'))/(1+exp(`tl'+`diff')))
+
+   qui su `pred'
+   local globalll=r(sum)
+
+   local nulscore=0
+   forvalues i=0/`nbgroups' {
+      qui count if `score'==`i'&`item'==1
+      local nbscore`i'=r(N)
+      if `nbscore`i''==0 {
+         local nulscore=1
+      }
+   }
+   if `nulscore' {
+      di in green "{p}At least one group of scores concerns none individuals. Tests will be not computed.{p_end}"
+      di in green "{p}Use the {hi:group} or the {hi:autogroup} options.{p_end}"
+      local test "NONE"
+      local details
+      local icc
+      local fitgraph
+      local splittest
+   }
+   forvalues i=0/`nbitems' {
+      qui count if `realscore'==`i'&`item'==1
+      local nbrealscore`i'=r(N)
+   }
+}
+
+/***********************************************************************************************************
+TESTS OF THE FIRST ORDER
+************************************************************************************************************/
+
+tempname Pi
+matrix define `Pi'=J(`nbitems',`=`nbitems'-1',0)
+if "`test'"!="NONE" {
+   qui drop if `score'==.
+   if "`trace'"!="" {
+      di in green "*** Tests of the first order"
+   }
+   tempname Obs Obs2 Th Th2
+
+   matrix define `Obs'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Obs2'=J(`nbitems',`=`nbgroups'-1',0)
+   matrix define `Th'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Th2'=J(`nbitems',`=`nbgroups'-1',0)
+   local listofitemsc
+
+   /* Estimation of the gamma symetrical functions*/
+   local c0 "1"
+   local c`nbitems' "`nbitems'*x"
+   forvalues j=1/`nbitems' {
+      local listini`j'
+      local listofitemsc "`listofitemsc' `beta`j''"
+      local c0 `c0'*(1+exp(x-`beta`j''))
+      local c`nbitems' `c`nbitems''-`beta`j''
+      forvalues k=1/`nbitems' {
+         local listini`j'k`k'
+         if `k'!=`j' {
+            local listini`j' "`listini`j'' `beta`k''"
+         }
+         forvalues l=1/`nbitems' {
+            if `l'!=`j'&`l'!=`k' {
+               local listini`j'k`k' "`listini`j'k`k'' `beta`l''"
+            }
+         }
+      }
+   }
+
+   gammasym `listofitemsc'
+
+   /*Estimation, for each value of the score s of the probability to respond to each item (Pi) and of the theorical number of positive responses (Ths) and of theorical number of positive respond per item pair (Ws)*/
+   forvalues s=1/`nbitems' {
+      local denom`s'=r(gamma`s')
+      tempname  W`s'
+      matrix define `W`s''=J(`nbitems',`nbitems',0)
+   }
+   tempvar prob prob2 z y v z2 y2 v2 c r q e
+   qui gen `prob'=.
+   qui gen `prob2'=.
+   forvalues j=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui count if `rep'==1&`item'==`j'&`realscore'==`s'
+         matrix `Obs'[`j',`s']=r(N)
+         if "`test'"!="WP" {
+            gammasym `listini`j''
+            local num`j'=r(gamma`=`s'-1')
+            if "`method'"=="cml"|"`test'"=="Q" {
+               matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s''
+            }
+            else {
+               gausshermite exp(`s'*x)/(`c0'), sigma(`sig')
+               local int`s'=r(int)
+               if "`test'"=="R"&`nbrealscore`s''!=0{
+                  local tmp=exp(-`beta`j'')*`num`j''*`int`s''*`nbind'/`nbrealscore`s''
+                  matrix `Pi'[`j',`s']=`tmp'
+               }
+               else if `nbrealscore`s''==0 {
+                  matrix `Pi'[`j',`s']=0
+               }
+            }
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  if `s'>=2 {
+                     gammasym `listini`j'k`k''
+                     local num`j'k`k'=r(gamma`=`s'-2')
+                     if "`method'"=="cml" {
+                        matrix `W`s''[`j',`k']=`nbrealscore`s''*exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''/`denom`s''
+                     }
+                     else {
+                        matrix `W`s''[`j',`k']=exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''*`int`s''*`nbind'
+                     }
+                     matrix `W`s''[`k',`j']=`W`s''[`j',`k']
+                  }
+               }
+            }
+         }
+         else if "`test'"=="WP" {
+            matrix `Pi'[`j',`s']=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j''))
+         }
+         matrix `Th'[`j',`s']=`Pi'[`j',`s']*`nbrealscore`s''
+         qui replace `prob'=`Pi'[`j',`s'] if `realscore'==`s'&`item'==`j'
+         qui replace `prob2'=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) if `realscore'==`s'&`item'==`j'
+         matrix `W`s''[`j',`j']=`nbrealscore`s''*`Pi'[`j',`s']
+         if "`test'"!="R" {
+            matrix `W`s''[`j',`j']=`W`s''[`j',`j']*abs(1-`Pi'[`j',`s'])
+         }
+      }
+   }
+   qui gen `v2'=abs(`prob'*(1-`prob'))
+   qui gen `z2'=(`rep'-`prob')^2
+   qui gen `y2'=`z2'/`v2'
+   qui gen `c'=abs(`prob'*(1-`prob')*(`prob'^3+(1-`prob')^3))
+   qui gen `r'=`c'/(`v2')^2
+   qui gen `e'=`c'-(`v2')^2
+
+   forvalues j=1/`nbitems' {
+      qui su `y2' if `item'==`j'
+      local outfit`j'=r(mean)
+      qui su `r' if `item'==`j'
+      local Voutfit`j'=r(sum)
+      local Voutfit`j'=`Voutfit`j''/(`nbind')^2-1/`nbind'
+      local outfitstd`j'=(`outfit`j''^(1/3)-1)*(3/sqrt(`Voutfit`j''))-sqrt(`Voutfit`j'')/3
+
+      qui su `z2' if `item'==`j'
+      local n=r(sum)
+      qui su `v2' if `item'==`j'
+      local d=r(sum)
+      local infit`j'=`n'/`d'
+      qui su `e' if `item'==`j'
+      local sume=r(sum)
+      local Vinfit`j'=`sume'/(`d')^2
+      local infitstd`j'=(`infit`j''^(1/3)-1)*(3/sqrt(`Vinfit`j''))-sqrt(`Vinfit`j'')/3
+   }
+   tempname tmp stattest testitems
+
+   /*Estimation, by scores group g, of the theorical number of positive response (Th2g) and of the positive respond to each items pair (W2g)*/
+   scalar `stattest'=0
+   forvalues g=1/`=`nbgroups'-1' {
+      tempname  W2`g' d2`g'
+      matrix define `W2`g''=J(`nbitems',`nbitems',0)
+      forvalues s=`liminf`g''/`limsup`g'' {
+         forvalues j=1/`nbitems' {
+            matrix `Obs2'[`j',`g']=`Obs2'[`j',`g']+`Obs'[`j',`s']
+            matrix `Th2'[`j',`g']=`Th2'[`j',`g']+`Th'[`j',`s']
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  matrix `W2`g''[`j',`k']=`W2`g''[`j',`k']+`W`s''[`j',`k']
+                  matrix `W2`g''[`k',`j']=`W2`g''[`j',`k']
+               }
+            }
+            matrix `W2`g''[`j',`j']=`W2`g''[`j',`j']+`W`s''[`j',`j']
+         }
+      }
+
+      /*Estimation of the d2g vectors*/
+      matrix `d2`g''=`Obs2'[1..`nbitems',`g']-`Th2'[1..`nbitems',`g']
+
+      /*Estimation of the influences on the test of each item (testitemsg matrix) and of the test statistic (stattest)*/
+      tempname test`g' testitems`g'
+      matrix `test`g''=`d2`g'''*syminv(`W2`g'')*`d2`g''
+      capture matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      if _rc!=0 {
+         matrix `tmp'=J(`nbitems',`nbitems',0)
+         forvalues j=1/`nbitems' {
+            matrix `tmp'[`j',`j']=`W2`g''[`j',`j']
+         }
+         di in green "Group `g' (`liminf`g''/`limsup`g''): The weight matrix is not positive-definite, the diagonal matrix is used to estimate the contribution of the items on the `wpname' statistic"
+         matrix list `tmp'
+         matrix `testitems`g''=cholesky(syminv(`tmp'))*`d2`g''
+      }
+      else {
+         matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      }
+      scalar `stattest'=`stattest'+`test`g''[1,1]
+   }
+   matrix `testitems'=J(`nbitems',1,0)
+   forvalues j=1/`nbitems' {
+      forvalues g=1/`=`nbgroups'-1' {
+         matrix `testitems'[`j',1]=`testitems'[`j',1]+`testitems`g''[`j',1]^2
+      }
+   }
+
+   /*Adaptation for the Q1 statistic*/
+   if "`test'"=="Q" {
+      scalar `stattest'=`stattest'*`=`nbitems'-1'/`nbitems'
+   }
+
+   /*Correction for R1m and Q1m*/
+   if ("`test'"=="R"|"`test'"=="Q")&("`method'"=="mml"|"`method'"=="gee") {
+      local c`nbitems' exp(`c`nbitems'')/(`c0')
+      local c0 1/(`c0')
+      gausshermite `c0', sigma(`sig')
+      local ci0=r(int)*`nbind'
+      gausshermite `c`nbitems'',sigma(`sig')
+      local ci`nbitems'=`nbind'*r(int)
+      scalar `stattest'=`stattest'+(`nbrealscore0'-`ci0')^2/`ci0'+(`nbrealscore`nbitems''-`ci`nbitems'')^2/`ci`nbitems''
+  }
+
+
+
+/***********************************************************************************************************
+TESTS U
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests U"
+      }
+
+      local quartile=`nbind'/4
+      local c1=0
+      local n1=0
+      while `n1'<`quartile' {
+         local c1=`c1'+1
+         local n1=`n1'+`nbrealscore`c1''
+      }
+      local c2=`nbitems'
+      local n2=0
+      while `n2'<`quartile' {
+         local c2=`c2'-1
+         local n2=`n2'+`nbrealscore`c2''
+      }
+      forvalues j=1/`nbitems' {
+         local zu1=0
+         local zu2=0
+         forvalues s=1/`c1' {
+            local zu1=`zu1'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         forvalues s=`c2'/`=`nbitems'-1' {
+            local zu2=`zu2'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         local U`j'=(`zu1'-`zu2')/sqrt(`c1'+`nbitems'-`c2')
+      }
+   }
+
+
+
+/***********************************************************************************************************
+TESTS OF THE SECOND ORDER /*undocumented in beta test*/
+************************************************************************************************************/
+
+   if "`q2'"!="" {
+      if "`trace'"!="" {
+         di in green "*** Tests of the second order"
+      }
+
+      tempfile Q2file
+      qui save "`Q2file'",replace
+      qui use "`saveraschtest'",replace
+
+      qui keep if `touse'==1
+      gen `score'=0
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'
+	 rename ``i'' `rep'`i'
+	 qui replace `score'=`score'+`rep'`i'
+      }
+      qui recode `score' `recode'
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'=0
+         forvalues j=`=`i'+1'/`nbitems' {
+	    local listinci`i'j`j'
+	    forvalues k=1/`nbitems' {
+	       if `k'!=`i'&`k'!=`j' {
+	          local listinci`i'j`j' "`listinci`i'j`j'' `beta`k''"
+	       }
+	    }
+	 }
+      }
+
+      local Q2tot=0
+      forvalues k=2/`=`nbitems'-1' {
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`i'+1'/`nbitems' {
+	       if `k'==1 {
+	          local num=0
+               }
+	       else {
+	          gammasym `listinci`i'j`j''
+                  local num=r(gamma`=`k'-2')
+               }
+	       local athi`i'j`j'k`k'=exp(-`beta`i'')*exp(-`beta`j'')*`num'/`denom`k''
+	       local bthi`i'j`j'k`k'=`nbth`i's`k''-`athi`i'j`j'k`k''
+	       local cthi`i'j`j'k`k'=`nbth`j's`k''-`athi`i'j`j'k`k''
+	       local dthi`i'j`j'k`k'=1-`athi`i'j`j'k`k''-`bthi`i'j`j'k`k''-`cthi`i'j`j'k`k''
+            }
+         }
+      }
+      forvalues k=1/`=`nbgroups'-1' {
+         local Q2`k'=0
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`j'+1'/`nbitems' {
+	       qui count if  `rep'`i'==1&`rep'`j'==1&`score'==`k'
+	       local aempi`i'j`j'k`k'=r(N)
+	       local ath2i`i'j`j'k`k'=0
+	       local bth2i`i'j`j'k`k'=0
+	       local cth2i`i'j`j'k`k'=0
+	       local dth2i`i'j`j'k`k'=0
+	    }
+	 }
+         if `limsup`k''!=1 {
+            forvalues l=`liminf`k''/`limsup`k'' {
+	       forvalues i=1/`=`nbitems'-1' {
+	          forvalues j=`=`i'+1'/`nbitems' {
+		     if `l'!=1 {
+		        local ath2i`i'j`j'k`k'=`ath2i`i'j`j'k`k''+`athi`i'j`j'k`l''*`nbrealscore`l''
+			local bth2i`i'j`j'k`k'=`bth2i`i'j`j'k`k''+`bthi`i'j`j'k`l''*`nbrealscore`l''
+			local cth2i`i'j`j'k`k'=`cth2i`i'j`j'k`k''+`cthi`i'j`j'k`l''*`nbrealscore`l''
+			local dth2i`i'j`j'k`k'=`dth2i`i'j`j'k`k''+`dthi`i'j`j'k`l''*`nbrealscore`l''
+                     }
+		  }
+               }
+            }
+	    forvalues i=1/`=`nbitems'-1' {
+	       forvalues j=`=`i'+1'/`nbitems' {
+	          local d2i`i'j`j'k`k'=(`aempi`i'j`j'k`k''-`ath2i`i'j`j'k`k'')^2
+		  local Q2i`i'j`j'k`k'=`d2i`i'j`j'k`k''/`ath2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`bth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`cth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`dth2i`i'j`j'k`k''
+		  local Q2i`i'=`Q2i`i''+`Q2i`i'j`j'k`k''
+		  local Q2i`j'=`Q2i`j''+`Q2i`i'j`j'k`k''
+		  local Q2`k'=`Q2`k''+`Q2i`i'j`j'k`k''
+	       }
+	    }
+	 }
+         local Q2tot=`Q2tot'+`Q2`k''
+      }
+      forvalues i=1/`nbitems' {
+         di in green "Item ``i'' : Q2 = `Q2i`i''"
+      }
+      local Q2=`Q2tot'*(`nbitems'-3)/(`nbitems'-1)
+      di in green "Q2 = `Q2tot'"
+      qui use "`Q2file'",replace
+   }
+
+/***********************************************************************************************************
+TEST LR Z
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests LR of Andersen"
+      }
+      local ssll=0
+      tempname Zfile
+      qui save "`Zfile'", replace
+      qui use "`saveraschtest'",replace
+      qui keep if `touse'==1
+      gen `score'=0
+      forvalues j=1/`nbitems' {
+         qui replace `score'=`score'+``j''
+      }
+      qui recode `score' `recode' `nbitems'=`nbgroups'
+      forvalues i=1/`=`nbgroups'-1' {
+         if `effscore`i''>0 {
+            qui raschtestv7 `varlist' if `score'==`i', test(NONE) `ld'
+            local ll`i'=r(cll)
+            local ssll=`ssll'+(`ll`i'')
+         }
+      }
+      local Z=2*`ssll'-2*`ll'
+      use "`Zfile'",replace
+      tempname AndersenZ
+      matrix define `AndersenZ'=(`Z',`=(`nbgroups'-2)*(`nbitems'-1)',1-chi2(`=(`nbitems'-1)*(`nbgroups'-2)',`Z'))
+   }
+}
+
+
+/***********************************************************************************************************
+DISPLAYING RESULTS WITH TESTS
+************************************************************************************************************/
+
+if "`test'"!="NONE" {
+   local conttest= "_c"
+}
+di
+tempname itemfit globalfit
+matrix `globalfit'=J(1,3,0)
+if "`method'"=="cml" {
+   di in green "Estimation method: " in yellow  "Conditional maximum likelihood (CML)"
+   local nbtest=`nbgroups'-1
+   local line=77
+}
+else if "`method'"=="mml"{
+   di in green "Estimation method: " in yellow  "Marginal maximum likelihood (MML)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+else if "`method'"=="gee" {
+   di in green "Estimation method: " in yellow  "Generalized Estimating Equations (GEE)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+if "`test'"=="NONE" {
+   local line=35
+}
+di in green  "Number of items: " in yellow  `nbitems'
+
+di in green  "Number of groups: " in yellow  `=`nbgroups'+1' `conttest'
+if "`test'"!="NONE" {
+   di in green " (" in yellow "`nbtest'" in green " of them are used to compute the statistics of test)"
+}
+if "`method'"=="cml" {
+   local nbind=`nbind'+`effscore0'+`effscore`nbgroups''
+   local cont "_c"
+   matrix `itemfit'=J(`nbitems',6,0)
+}
+else {
+   local cont
+   matrix `itemfit'=J(`nbitems',5,0)
+}
+local missing=`N'-`nbind'
+di in green "Number of individuals: " in yellow `N'
+di in green "Number of individuals with missing values: " in yellow `nbindmiss' _c
+if "`ld'"=="" {
+   di in green " (removed)"
+}
+else {
+   di
+}
+di in green  "Number of individuals with nul or perfect score: " in yellow `=`effscore0'+`effscore`nbgroups'''
+if "`method'"=="cml" {
+   di in green  "Conditional log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+else {
+   di in green "Marginal log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+di
+noi di in green  _col(16) "Difficulty" `conttest'
+if "`test'"!="NONE" {
+   di in green _col(58) "Standardized"
+}
+noi di in green _col(9) "Items" _col(16) "parameters" _col(28) "std Err." `conttest'
+if "`test'"!="NONE" {
+   local varin=int(2/sqrt(`nbind')*100)/100
+   local varout=int(6/sqrt(`nbind')*100)/100
+   di _col(41) "`namewp'" _col(47) "df" _col(50) "p-value" _col(58) "Outfit" _col(66) "Infit" `cont'
+   if "`method'"=="cml" {
+      di in green _col(77) "U"
+   }
+}
+di in green  "{hline `line'}"
+forvalues i=1/`nbitems' {
+   noi di in yellow _col(3) %12s abbrev("``i''`fixed`i''" ,12) in yellow _col(18) %8.5f `beta`i'' _col(29) %6.5f `sd`i'' `conttest'
+   if "`test'"!="NONE" {
+      di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfitstd`i'' _col(65) %6.3f `infitstd`i''  /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/  `cont'
+      matrix `itemfit'[`i',1]=`testitems'[`i',1]
+      matrix `itemfit'[`i',2]=`=`nbgroups'-2'
+      matrix `itemfit'[`i',3]=1-chi2(`=`nbgroups'-2',`testitems'[`i',1])
+      matrix `itemfit'[`i',4]=`outfitstd`i''
+      matrix `itemfit'[`i',5]=`infitstd`i''
+      if "`method'"=="cml" {
+         di in ye _col(72) %6.3f `U`i''
+         matrix `itemfit'[`i',6]=`U`i''
+      }
+   }
+}
+di in green  "{hline `line'}"
+if "`test'"!="NONE" {
+   if "`method'"=="cml" {
+      local df=(`nbgroups'-2)*(`nbitems'-1)
+   }
+   else {
+      local df=(`nbgroups'-1)*(`nbitems'-1)-1
+   }
+   matrix `globalfit'=(`stattest',`df',1-chi2(`df',`stattest'))
+   noi di in green _col(6) "`descwp'" _col(32) in gr "`namewp'=" _col(36) in ye %8.3f `globalfit'[1,1] _col(46) %3.0f `globalfit'[1,2] _col(51) %6.4f `globalfit'[1,3]
+   if "`method'"=="cml" {
+      noi di in green _col(6) "Andersen LR test" _col(34) "Z=" in yellow _col(36) %8.3f `AndersenZ'[1,1] _col(46) %3.0f `AndersenZ'[1,2] _col(51) %6.4f `AndersenZ'[1,3]
+   }
+   di in green  "{hline `line'}"
+}
+if "`method'"!="cml" {
+   di in green _col(10) in yellow "Sigma" _col(18) %8.5f `sig' _col(29) %6.5f `sesig'
+   di in green  "{hline `line'}"
+}
+
+if "`method'"=="cml"&"`meandiff'"==""{
+   di in green "*: The difficulty parameter of this item had been fixed to 0"
+}
+if "`method'"=="cml"&"`meandiff'"!=""{
+   di in green "The mean of the difficulty parameters is fixed to 0"
+}
+if `smallgroup'==1&"`test'"!="NONE" {
+   di in green "You have groups of scores with less than 30 individuals. The tests can be invalid."
+}
+if "`method'"!="cml"&"`test'"=="Q" {
+   di in green "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test."
+}
+
+/*Tabular of the estimated values of the latent trait*/
+
+   di
+   di
+   noi di in green _col(33) "Ability" _col(60) "Expected"
+   noi di in green _col(17) "Group" _col(23) "Score" _col(30) "parameters" _col(42) "std Err." _col(54) "Freq." _col(63) "Score"_c
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      noi di in green _col(75) "ll"
+   }
+   else {
+      noi di ""
+   }
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      local line=62
+   }
+   else {
+     local line=51
+   }
+   di in green _col(17) "{hline `line'}"
+   local nonul=0
+   forvalues g=0/`nbgroups' {
+      if `g'!=0 {
+         di in green _col(17) "{dup `line':-}"
+      }
+      forvalues s=`liminf`g''/`limsup`g'' {
+         if `s'==`liminf`g'' {
+            local tmp `ll`g''
+            local gr `g'
+         }
+         else {
+            local tmp
+            local gr
+         }
+         local expscore`nonul'=0
+         forvalues i=1/`nbitems' {
+            local expscore`nonul'=`expscore`nonul''+1/(1+exp(-`theta`nonul''+`beta`i''))
+         }
+         if "`method'"=="cml" {
+            local format1 %8.3f
+         }
+         else {
+            local format1 %8.5f
+         }
+         noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(32) `format1' `theta`nonul'' _col(42) `format1' `sdtheta`nonul'' _col(55) %4.0f `nbrealscore`s'' _col(64) % 4.2f `expscore`nonul'' _col(68) %11.4f `tmp'
+         local nonul=`nonul'+1
+      }
+   }
+   di in green _col(17) "{hline `line'}"
+   if "`method'"=="mml"|"`method'"=="gee" {
+       di
+       *di in green "Variance of the estimated latent trait" _col(45) in ye %10.4f `vartheta'
+       di in green "Mean variance of the error" _col(45) in ye %10.4f `meanse2'
+       *di in green "Personal Separation Index (PSI)" _col(50) in ye %5.3f `psi'
+       local sig2=`sig'^2
+       di in green "Estimated variance of the latent trait" _col(45) in ye %10.4f `sig2'
+       local psi2=1-`meanse2'/`sig2'
+       di in green "Personal Separation Index (PSI)" _col(45) in ye %10.4f `psi2'
+   }
+
+/***********************************************************************************************************
+DETAILS OPTION
+************************************************************************************************************/
+
+if "`details'"!="" {
+   forvalues g=0/`nbgroups' {
+      if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" {
+         di
+         di in  green "{hline 44}"
+         di in green "Group: " in ye "`g'" in green " from " in ye "`liminf`g''" in green " to " in ye "`limsup`g''" in green " (n=" in ye "`nbscore`g''" in green")"
+         di
+         di _col(3) "Item" _col(10) "Observed" _col(23) "Expected" _col(37) "Scaled"
+         di in green "{dup 44:-}"
+      }
+      if `g'!=0&`g'!=`nbgroups' {
+         forvalues j=1/`nbitems' {
+            local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j'])
+            di _col(3) in ye "``j''" _col(14) %4.0f `Obs2'[`j',`g'] _col(25) %6.2f `Th2'[`j',`g'] _col(36) %7.4f `tmp'
+         }
+         di in green "{dup 44:-}"
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `test`g''[1,1]
+      }
+      else if "`method'"!="cml" {
+         if `g'==0 {
+            local h=0
+         }
+         else {
+            local h=`nbitems'
+         }
+         local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'')
+         di in ye _col(14) %4.0f `nbrealscore`h'' _col(25) %6.2f `ci`h'' _col(36) %7.4f `tmp'
+         di in green "{dup 44:-}"
+         local tmp=`tmp'^2
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `tmp'
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION ICC
+************************************************************************************************************/
+
+if "`icc'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Items Characteristic Curves"
+   }
+   tempvar proba propemp propth propthb
+   qui replace `tl'=. if `realscore'==0|`realscore'==`nbitems'|`realscore'==.
+   qui gen `propemp'=.
+   qui gen `propth'=.
+   qui gen `propthb'=.
+   label variable `propth' "Expected ICC"
+   label variable `propemp' "Observed ICC"
+   label variable `propthb' "Expected ICC"
+   label variable `tl' "Latent trait"
+   global iccs
+   forvalues i=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui replace `propthb'=exp(`theta`s''-`beta`i'')/(1+exp(`theta`s''-`beta`i'')) if `item'==`i'&`realscore'==`s'
+      }
+      qui replace `propemp'=.
+      qui replace `propth'=.
+      tempvar propemp`i' propth`i'
+      qui bysort `realscore' `item' : egen `propth`i''=mean(`propthb') if `item'==`i'
+      qui bysort `realscore' `item' : egen `propemp`i''=mean(`rep') if `item'==`i'
+      qui replace `propth'=`propth`i'' if `item'==`i'
+      qui replace `propemp'=`propemp`i'' if `item'==`i'
+      local mintl=floor(`theta1')
+      local maxtl=floor(`theta`=`nbitems'-1'')+1
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\icc``i''"
+      }
+      if "`v8'"!="" {
+         graph twoway (line  `propemp' `propth' `tl') if `item'==`i' , name(icc``i'',replace) ytitle("")  ylabel(0(.25)1) title("Observed and Expected ICC for the item ``i''") xlabel(`mintl'(1)`maxtl') `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save icc``i''  "`saving'" , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui graph `propemp' `propth' `tl' if `item'==`i' , twoway `saving' c(ll) ylabel(0(.25)1)   xlabel(`mintl'(1)`maxtl') title("Observed and Expected ICC for the item ``i''")
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION INFORMATION
+************************************************************************************************************/
+
+if "`information'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Information graph"
+   }
+
+   tempfile saveinfo
+   qui save "`saveinfo'",replace
+   tempvar info latent
+   drop _all
+   qui set obs 2001
+   gen `latent'=((_n-1)/1001-1)*3
+   label variable `latent' "latent trait"
+   gen `info'=0
+   forvalues i=1/`nbitems' {
+      qui replace `info'=`info'+exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2
+   }
+   local saving "`dirsave'\\information"
+   if "`v8'"!="" {
+      graph twoway (line  `info' `latent') , name(information,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the scale") `draw'
+      if "`filessave'"!="" {
+         graph save information "`saving'" , `replace'
+      }
+      pause
+   }
+   else {
+      if "`filessave'"!="" {
+         local saving "saving(`saving'"
+         if "`replace'"=="" {
+            local saving "`saving')"
+         }
+         else {
+            local saving "`saving',replace)"
+         }
+      }
+      if "`filessave'"=="" {
+         local saving
+      }
+      qui graph `info' `latent' , twoway  `saving' c(l) xlabel(-3(1)3) title("Information graph of the scale")
+      pause
+   }
+   qui use "`saveinfo'",replace
+}
+
+/***********************************************************************************************************
+OPTION FITGRAPH
+************************************************************************************************************/
+
+if "`fitgraph'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graphical validation of the fit"
+   }
+   *set trace on
+   tempname outfit meanz2 meanv2 sumd infit Voutfit outfitstd Vinfit infitstd
+   qui egen `outfit'=mean(`y2'),by(`id')
+   qui egen `Voutfit'=sum(`r'),by(`id')
+   qui replace `Voutfit'=`Voutfit'/(`nbitems')^2-1/`nbitems'
+   qui gen `outfitstd'=(`outfit'^(1/3)-1)*(3/sqrt(`Voutfit'))-sqrt(`Voutfit')/3
+   qui egen `meanz2'=sum(`z2'),by(`id')
+   qui egen `meanv2'=sum(`v2'),by(`id')
+   qui gen `infit'=`meanz2'/`meanv2'
+   qui egen `Vinfit'=sum(`e'),by(`id')
+   qui replace `Vinfit'=`Vinfit'/(`meanv2')^2
+   qui gen `infitstd'=(`infit'^(1/3)-1)*(3/sqrt(`Vinfit'))-sqrt(`Vinfit')/3
+
+   qui su `outfitstd'
+   local mino=floor(2*min(`r(min)',-2))/2
+   local maxo=ceil(2*max(`r(max)',2))/2
+   qui su `infitstd'
+   local mini=floor(2*min(`r(min)',-2))/2
+   local maxi=ceil(2*max(`r(max)',2))/2
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfitind"
+      local savingi "`dirsave'\\infitind"
+   }
+   if "`v8'"!="" {
+      *graph twoway (scatter `outfit' `id'), name(outfit,replace) yline(.6 1.4) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(0(.2)2 2(.5)`maxo') `draw'
+      graph twoway (scatter `outfitstd' `id'), name(outfit,replace) yline(-2 2) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw'
+      pause
+      *graph twoway (scatter `infit' `id'), name(infit,replace) yline(.6 1.4) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(0(.2)2 2(.5)`maxi') `draw'
+      graph twoway (scatter `infitstd' `id'), name(infit,replace) yline(-2 2) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfit "`savingo'" , `replace'
+         graph save infit "`savingi'" , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitstd' `id', `savingo' twoway sy(.) c(.) yline(-2 2) title("Outfit indexes") b2title("Individual indexes") l1("") l2title("Outfit") ylabel(`mino'(.5)`maxo')
+      pause
+      graph `infitstd' `id', `savingi' twoway sy(.) c(.) yline(-2 2) title("Infit indexes") b2title("Individual indexes") l1("")  l2title("Infit") ylabel(`mini'(.5)`maxi')
+      pause
+   }
+   drop _all
+   qui set obs `nbitems'
+   tempvar name betap outfitstdj infitstdj
+   qui gen str9 `name'=""
+   qui gen `betap'=.
+   qui gen `outfitstdj'=.
+   qui gen `infitstdj'=.
+   local mino=-2
+   local maxo=2
+   local mini=-2
+   local maxi=2
+   forvalues j=1/`nbitems' {
+      qui replace `name'="``j''" in `j'
+      qui replace `betap'=`beta`j'' in `j'
+      qui replace `outfitstdj'=`outfitstd`j'' in `j'
+      qui replace `infitstdj'=`infitstd`j'' in `j'
+      local mino=floor(min(`mino',`outfitstd`j'')*2)/2
+      local mini=floor(min(`mini',`infitstd`j'')*2)/2
+      local maxo=ceil(max(`maxo',`outfitstd`j'')*2)/2
+      local maxi=ceil(max(`maxi',`infitstd`j'')*2)/2
+   }
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfititems"
+      local savingi "`dirsave'\\infititems"
+   }
+   if "`v8'"!="" {
+      graph twoway (scatter `outfitstdj' `betap',name(outfititem,replace) mlabel(`name')), yline(-2 2) title("Outfit indexes") xtitle("Difficulty") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw'
+      pause
+      graph twoway (scatter `infitstdj' `betap',name(infititem,replace) mlabel(`name')), yline(-2 2) title("Infit indexes") xtitle("Difficulty") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfititem "`savingo'" , `replace'
+         graph save infititem "`savingi'" , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitstdj' `betap', `savingo' twoway c(.) yline(-2 2) title("Outfit indexes") b2title("Difficulty") l1title("") l2title("Outfit") ylabel(`mino'(.5)`maxo') sy([`name'])
+      pause
+      graph `infitstdj' `betap', `savingi' twoway c(.) yline(-2 2) title("Infit indexes") b2title("Difficulty") l1title("") l2title("Infit") ylabel(`mini'(.5)`maxi') sy([`name'])
+      pause
+   }
+}
+
+
+/***********************************************************************************************************
+OPTION SPLITTESTS
+************************************************************************************************************/
+
+if "`splittests'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Splitting tests"
+   }
+   forvalues j=1/`nbitems' {
+      tempname estneg`j' estpos`j'
+      local listitems
+      forvalues k=1/`nbitems' {
+         if `j'!=`k' {
+            local listitems `listitems' ``k''
+         }
+      }
+      qui use "`saveraschtest'",replace
+      qui keep if `touse'==1
+      qui raschtestv7 `listitems' if ``j''==0,test(NONE) meth(cml) `ld'
+      matrix `estneg`j''=r(beta)
+      local llneg=r(cll)
+      qui raschtestv7 `listitems' if ``j''==1,test(NONE) meth(cml) `ld'
+      matrix `estpos`j''=r(beta)
+      local llpos=r(cll)
+      qui raschtestv7 `listitems',test(NONE) meth(cml) `ld'
+      local llnegpos=r(cll)
+      local nbcol=colsof(`estneg`j'')
+      local meanneg=0
+      local meanpos=0
+      forvalues k=1/`nbcol' {
+         local meanneg=`meanneg'+`estneg`j''[1,`k']
+         local meanpos=`meanpos'+`estpos`j''[1,`k']
+      }
+      local meanneg=`meanneg'/`nbitems'
+      local meanpos=`meanpos'/`nbitems'
+      forvalues k=1/`nbcol' {
+         matrix `estneg`j''[1,`k']=`estneg`j''[1,`k']-`meanneg'
+         matrix `estpos`j''[1,`k']=`estpos`j''[1,`k']-`meanpos'
+         if "`method'"=="cml" {
+            matrix `estneg`j''=`estneg`j'',-`meanneg'
+            matrix `estpos`j''=`estpos`j'',-`meanpos'
+         }
+      }
+      drop _all
+      qui set obs `=`nbitems'+1'
+      tempvar neg pos name diag
+      qui gen `neg'=.
+      qui gen `pos'=.
+      qui gen str9 `name'=""
+      local min=`estneg`j''[1,1]
+      local max=`estneg`j''[1,1]
+      forvalues k=1/`=`nbitems'-1' {
+         qui replace `neg'=`estneg`j''[1,`k'] in `k'
+         qui replace `pos'=`estpos`j''[1,`k'] in `k'
+         local min=min(`min',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local max=max(`max',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local tmp:word `k' of `listitems'
+         qui replace `name'="`tmp'" in `k'
+      }
+      local min=floor(`min')
+      local max=floor(`max')+1
+      qui gen `diag'=.
+      qui replace `diag'=`min' in `nbitems'
+      qui replace `diag'=`max' in `=`nbitems'+1'
+      local Zgr=round(2*(`llneg'+`llpos'-`llnegpos'),0.001)
+      local Zgr=substr("`Zgr'",1,6)
+      local pgr=round(1-chi2(`=`nbitems'-1',`Zgr'),0.0001)
+      local pgr=substr("`pgr'",1,5)
+      local note="Z=`Zgr', df=`=`nbitems'-1' , p=`pgr'"
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\split``j''"
+      }
+      if "`v8'"!="" {
+         graph twoway (scatter `pos' `neg' ,mlabel(`name')) (line `diag' `diag'), ytitle("Positive answer") xtitle("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title(Splitting on ``j'') `draw' legend(off) note("Andersen Z test: `note'") name(split,replace) `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save split "`saving'" , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui replace `diag'=`neg' if `diag'==.
+         graph  `pos' `diag' `diag', `saving' c(.l) sy([`name']i) l1title("") l2title("Positive answer") b2title("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title("Splitting on ``j'' (`note')") `draw'
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION GRAPH
+************************************************************************************************************/
+
+if "`graph'"!=""&"`v8'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graph option"
+   }
+   tempvar  latent2  tl2 delta2 tlth2 labdelta2 labtl2
+   drop _all
+   qui set obs 1001
+   gen `latent2'=(_n-501)/100
+   label variable `latent2' "latent trait"
+   qui gen `tl2'=.
+   qui gen `labtl2'=""
+   forvalues i=0/`nbitems' {
+      *if (`i'!=0&`i'!=`nbitems')|"`method'"!="cml" {
+         qui replace `tl2'=`nbrealscore`i''/`N' if round(`latent2',0.01)==round(`theta`i'',0.01)
+         qui replace `labtl2'="`i'" if round(`latent2',0.01)==round(`theta`i'',0.01)
+      *}
+   }
+   qui gen `delta2'=.
+   qui gen `labdelta2'=""
+   forvalues i=1/`nbitems' {
+      qui replace `delta2'=-.05 if round(`latent2',0.01)==round(`beta`i'',0.01)
+      qui replace `labdelta2'="``i''" if round(`latent2',0.01)==round(`beta`i'',0.01)
+   }
+   if "`method'"=="mml"|"`method'"=="gee" {
+      qui gen `tlth2'=1/(2*_pi*`sig')*exp(-.5*(`latent2'/`sig')^2)
+      label variable `tlth2' "Theorical distribution"
+      local graphmml line `tlth2' `latent2'
+   }
+   label variable `tl2' "Score"
+   label variable `delta2' "Items"
+   local saving "`dirsave'\\graph"
+   local min=-2
+   local max=2
+   forvalues j=1/`nbitems' {
+      if `beta`j''<`min' {
+         local min=`beta`j''-.5
+      }
+      if `beta`j''>`max'&`beta`j''!=. {
+         local max=`beta`j''+.5
+      }
+   }
+   if "`method'"=="cml" {
+      if `theta0'<`min' {
+         local min=`theta0'-.5
+      }
+      if `theta`=`nbitems'-1''>`max' {
+         local max=`theta`=`nbitems'-1''+.5
+      }
+   }
+   else if "`method'"!="cml" {
+      if `theta0'<`min'&`theta0'!=. {
+         local min=`theta0'-.5
+      }
+      if `theta`nbitems''>`max'&`theta`nbitems''!=. {
+         local max=`theta`nbitems''+.5
+      }
+   }
+   local min=floor(`min')
+   local max=floor(`max')+1
+   qui su `tl2'
+   local max2=r(max)
+   if "`method'"!="cml" {
+      qui su `tlth2'
+      local max2=max(`max2',`r(max)')
+   }
+   qui replace `latent2'=. if `latent2'<`min'|`latent2'>`max'
+   if "`v8'"!="" {
+      graph twoway (bar `tl2' `latent2',/*mlabel(`labtl2')*/ barwidth(.3) ) (dropline `delta2' `latent2',mlabel(`labdelta2') mlabposition(6)) (`graphmml'), name(graph,replace) ytitle("") xlabel(`min'(1)`max') ylabel(-.1 0(0.05)`max2') title("Individuals/items representations") `draw'
+      if "`filessave'"!="" {
+         graph save graph "`saving'" , `replace'
+      }
+      pause
+   }
+}
+else if "`graph'"!=""&"`v8'"=="" {
+   di in ye "The graph option is not available with Stata 7"
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATION
+************************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+      di
+      di _col(4) "{hline 30}"
+      di _col(4) in green "Comparison of two populations"
+      di _col(4) "{hline 30}"
+      di
+      di _col(4) in green "`comp'==`mincomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmin' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmin' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmin'
+      di _col(4) in green "`comp'==`maxcomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmax' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmax' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmax'
+      di                                                                       _col(33) in green "Z= " _col(35) in yellow %8.4f `Zcomp' _col(47) in green "pvalue= "    _col(57) in yellow %6.4f `pvalue'
+}
+
+/***********************************************************************************************************
+TEST DIF
+************************************************************************************************************/
+
+if "`method'"=="cml"&"`dif'"!=""&"`test'"!="NONE" {
+   if "`trace'"!="" {
+      di in green "*** Tests of DIF"
+   }
+   local ssll=0
+   tempname DIFfile
+   qui save "`DIFfile'", replace
+   qui use "`saveraschtest'",replace
+   qui keep if `touse'==1
+   unab list:`dif'
+   local nbdif:word count `list'
+   tempname DIF
+   matrix define `DIF'=J(`nbdif',4,0)
+   local count=1
+   di
+   di _col(4) in green "{hline 45}"
+   di _col(4) in green "Test of Differential Item Functioning (DIF)"
+   di _col(4) in green "{hline 45}"
+   foreach j in `list' {
+      qui inspect `j'
+      local nbdif=r(N_unique)
+      qui su `j'
+      local maxdif=r(max)
+      if `nbdif'>10&`maxdif'<=10 {
+         di in ye "The {hi:dif} option is available with variables containing 10 or less modalities (coded from 0 or 1 to k<10)."
+         di in ye "The variable `j' (`nbdif' modalities) is omitted."
+      }
+      else {
+         local ssll=0
+         forvalues i=0/10 {
+            qui count if `j'==`i'
+            local effdif=r(N)
+            if `effdif'>0 {
+               qui raschtestv7 `varlist' if `j'==`i', test(NONE)
+               local ll`i'=r(cll)
+               local ssll=`ssll'+(`ll`i'')
+            }
+         }
+         local Z=2*`ssll'-2*`ll'
+         local ddl=(`nbdif'-1)*(`nbitems'-1)
+         matrix define `DIF'[`count',1]=(`count',`Z',`ddl',1-chi2(`ddl',`Z'))
+         di
+         di _col(4) in green "Variable:" in ye " `j' " in green "   Number of groups: "  in ye "`nbdif'"
+         di _col(4) in green "LR Test Z=" in ye %8.3f `Z' in gr "   ddl=" in ye %4.0f `ddl' in gr "    p-value=" in ye %6.4f `=1-chi2(`ddl',`Z')'
+         di
+      }
+      local ++count
+   }
+   use "`DIFfile'",replace
+}
+
+/***********************************************************************************************************
+RETURN
+************************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Returns"
+}
+local colnametheta
+
+forvalues i=0/`nbgroups' {
+         local colnametheta `colnametheta' score_`i'
+}
+
+
+return clear
+
+if `nbitems'>=3&"`test'"!="NONE" {
+        matrix colnames `globalfit'=`namewp' df p
+	matrix rownames `globalfit'=`method'
+	matrix rownames `itemfit'=`varlist'
+        matrix roweq `itemfit'=`method'
+
+	if "`method'"=="cml" {
+                matrix colnames `itemfit'=`namewp' df p outfit infit U
+		matrix rownames `AndersenZ'=`method'
+		matrix colnames `AndersenZ'=Z df p
+		return matrix AndersenZ=`AndersenZ'
+                if "`dif'"!="" {
+		   matrix rownames `DIF'=`list'
+		   matrix colnames `DIF'=num Z df p
+		   return matrix DIF=`DIF'
+                }
+	}
+	else {
+                matrix colnames `itemfit'=`namewp' df p outfit infit
+	}
+	return matrix itemFit=`itemfit'
+	return matrix globalFit=`globalfit'
+}
+
+matrix colnames `theta'=`colnametheta'
+matrix rownames `theta'=theta
+return matrix theta `theta'
+matrix colnames `sdtheta'=`colnametheta'
+matrix rownames `sdtheta'=`colnametheta'
+return matrix Vartheta `sdtheta'
+local varlist2
+matrix coleq `beta'=`method'
+matrix coleq `Vbeta'=`method'
+matrix roweq `Vbeta'=`method'
+if "`method'"=="cml" {
+	forvalues i=1/`=`nbitems'-1' {
+		local varlist2 `varlist2' ``i''
+	}
+        return scalar cll=`ll'
+        return scalar ll=`globalll'
+	local AIC=-2*`globalll'+2*(`nbitems'-1)
+}
+else {
+        return scalar ll=`ll'
+	local varlist2 `varlist'
+	return scalar sigma=`sig'
+	return scalar sesigma=`sesig'
+	local AIC=-2*`ll'+2*(`nbitems'+1)
+}
+
+if "`comp'"!="" {
+   return scalar Zcomp=`Zcomp'
+   return scalar pZcomp=`pvalue'
+}
+
+matrix colnames `beta'=`varlist2'
+matrix rownames `beta'=beta
+return matrix beta `beta'
+
+matrix colnames `Vbeta'=`varlist2'
+matrix rownames `Vbeta'=`varlist2'
+return matrix Varbeta `Vbeta'
+
+return scalar AIC=`AIC'
+return scalar N=`nbind'
+
+if "`pause'"!="" {
+   pause off
+}
+
+drop _all
+
+restore,not
+use "`saveraschtest'"
+
+/***********************************************************************************************************
+CREATE EVENTUAL NEW VARIABLES
+************************************************************************************************************/
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+        tempname genlt2 genscore2 outfit2 infit2
+        qui gen `score'=0 `if'
+        forvalues i=1/`nbitems' {
+           qui replace `score'=`score'+``i'' `if'
+        }
+        qui gen `genlt2'=. `if'
+        forvalues i=0/`nbitems' {
+           qui replace `genlt2'=`theta`i'' `if'&`score'==`i'
+        }
+        if "`genscore'"!="" {
+           qui gen `genscore'=`score' `if'
+        }
+        if "`genlt'"!="" {
+           qui gen `genlt'=`genlt2' `if'
+        }
+        if "`genfit'"!="" {
+           local outfit:word 1 of `genfit'
+           local infit:word 2 of `genfit'
+           qui gen `outfit'=0 `if'
+           qui gen `infit'=0  `if'
+           tempname infit1 infit2
+           qui gen `infit1'=0 `if'
+           qui gen `infit2'=0 `if'
+           forvalues j=1/`nbitems' {
+               tempname pi`j'
+               qui gen `pi`j''=exp(`genlt2'-`beta`j'')/(1+exp(`genlt2'-`beta`j'')) `if'
+               qui replace `pi`j''=0  `if'
+               forvalues s=1/`nbitems' {
+                  qui replace `pi`j''=`Pi'[`j',`s'] `if'&`score'==`s'
+               }
+               qui gen `outfit'``j''=(``j''-`pi`j'')^2/(`pi`j''*(1-`pi`j'')) `if'
+               qui replace `infit1'=`infit1'+(``j''-`pi`j'')^2  `if'
+               qui replace `infit2'=`infit2'+(`pi`j''*(1-`pi`j'')) `if'
+               qui replace `outfit'=`outfit'+`outfit'``j''/`nbitems' `if'
+           }
+           qui replace `infit'=`infit1'/`infit2'  `if'
+        }
+}
+
+if "`trace'"!=""|"`time'"!="" {
+    capture qui elapse `st'
+    di in green "** Time : " in yellow "$S_elap " in green "seconds"
+}
+end
diff --git a/Modules/ado/personal/r/old/raschtestv78 avant COVARIABLES.ado b/Modules/ado/personal/r/old/raschtestv78 avant COVARIABLES.ado
new file mode 100644
index 0000000..2a7b5b1
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschtestv78 avant COVARIABLES.ado	
@@ -0,0 +1,1890 @@
+*! version 7.6.1  26june2008
+*! Jean-Benoit Hardouin
+*************************************************************************************************************
+* Raschtestv7: Rasch model, fit tests and graphical representations
+* Corresponds to the version 7.6 of Raschtest (http://freeirt.org) for Stata7
+*
+* Historic:
+* Version 2.1 (2003-07-10): Jean-Benoit Hardouin
+* Version 3.1 (2004-01-02) : Jean-Benoit Hardouin
+* Version 7.1 (2005-03-30) : Jean-Benoit Hardouin
+* Version 7.2.1 (2005-05-21) : Jean-Benoit Hardouin
+* Version 7.3.1 (2005-07-02) : Jean-Benoit Hardouin
+* Version 7.3.2 (2005-10-05) : Jean-Benoit Hardouin /*correction for the *genlt* option with *method(cml)**/
+* Version 7.3.3 (2005-12-21) : Jean-Benoit Hardouin /*correction if scores are not represented with method(mml) or method(gee)*/
+* Version 7.4.1 (2006-01-17) : Jean-Benoit Hardouin /*Standardized OUTFIT and INFIT, DIF option*/
+* Version 7.4.2 (2006-03-21) : Jean-Benoit Hardouin /*Avoids a bug when the temporary files are saved in a directory containing special characters*/
+* Version 7.4.3 (2006-11-15) : Jean-Benoit Hardouin /*Avoids a bug when the directory defined in the dirsave option contains special characters*/
+* Version 7.5.1 (2007-04-20) : Jean-Benoit Hardouin /*Return results of the comp option*/
+* Version 7.6.1 (2008-06-26) : Jean-Benoit Hardouin /*Nold option, corrects a bug with the genlt option*/
+* Version 7.6.2 (2009-03-01) : Jean-Benoit Hardouin /*Correction of the SE of the latent trait, graph option, correction of a bug with the if option, PSI in MML*/
+* Version 8 (2009-03-01) : Jean-Benoit Hardouin /*DIFFICULTIES option*/
+*
+* Needed modules :
+* gammasym version 2.1 (http://freeirt.free.fr)
+* gausshermite version 1 (http://freeirt.free.fr)
+* geekel2d version 4.2 (http://freeirt.free.fr)
+* genscore version 1.4 (http://freeirt.free.fr)
+* ghquadm (findit ghquadm)
+* gllamm version 2.3.11 (ssc describe gllamm)
+* gllapred version  2.3.2 (ssc describe gllapred)
+* elapse (ssc describe elapse)
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://anaqol.free.fr
+* FreeIRT Project : http://freeirt.free.fr
+*
+* Copyright 2003-2009 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+DEFINITION / SYNTAX
+***********************************************************************************************************/
+
+
+program define raschtestv7,rclass
+syntax varlist(min=1 numeric) [if] [in] , [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph v8 COMp(varname) dif(varlist) time TRace Details  nold iterate(int 200) DIFFiculties(string) COVariables(varlist)]
+
+
+if "`if'"=="" {
+   local if "if 1"
+}
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Tests of conformity"
+}
+if "`v8'"=="" {
+        version 7.0
+}
+else {
+        version 8.0
+}
+
+local st = "$S_TIME"
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+tokenize `varlist'
+
+local bad
+forvalues i=1/`nbitems' {
+   qui count if ``i''!=0&``i''!=1&``i''!=.
+   local N=r(N)
+   if `N'>0 {
+      local bad `bad' ``i''
+   }
+}
+if "`bad'"!="" {
+   di in red "The item(s) {hi:`bad'} is(are) not binary item(s) (with responses 0 or 1)."
+   exit
+}
+
+if "`method'"=="" {
+    local method cml
+}
+if "`test'"=="" {
+    local test R
+}
+local method=lower("`method'")
+local test=upper("`test'")
+if "`method'"!="mml"&"`method'"!="cml"&"`method'"!="gee" {
+    di in red "Uncorrect method option."
+    error 198
+    exit
+}
+
+if "`test'"!="R"&"`test'"!="Q"&"`test'"!="WP"&"`test'"!="NONE" {
+   di in red "Uncorrect test option."
+   error 198
+   exit
+}
+
+if "`genfit'"!="" {
+   local nbwordgenfit:word count `genfit'
+   if `nbwordgenfit'!=2 {
+      di in red "Uncorrect genfit option."
+      di in red "This option must contain exactly two words"
+      error 198
+      exit
+   }
+}
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+   confirm new variable `genfit' `genlt' `genscore'
+   if "`genfit'"!="" {
+      local o:word 1 of `genfit'
+      forvalues i=1/`nbitems' {
+         confirm new variable `o'``i''
+      }
+   }
+}
+
+preserve
+
+tempfile saveraschtest
+qui save `saveraschtest'
+qui keep if `touse'==1
+
+if "`autogroup'"!=""&"`group'"!="" {
+   di in green "The autogroup and the group options cannot be defined in the same time"
+   di in green "Only the group option is retained."
+   local autogroup
+}
+
+if "`autogroup'"!="" {
+   tempvar autoscore
+   qui genscore `varlist',score(`autoscore')
+
+   tempname matscore tmp
+   matrix `matscore'=J(`=`nbitems'-1',3,0)
+   forvalues i=1/`=`nbitems'-1' {
+        matrix `matscore'[`i',1]=`i'
+        matrix `matscore'[`i',2]=`i'
+        qui count if `autoscore'==`i'
+        matrix `matscore'[`i',3]=r(N)
+   }
+   local stop=0
+   local j=0
+   while `j'<=`=`nbitems'-3'&`stop'!=1 {
+      local j=`j'+1
+      local scoretogroup=99999999
+      local rowtogroup1=0
+      local rowtogroup2=0
+      local stop=1
+      forvalues i=1/`=`nbitems'-`j'' {
+         if `matscore'[`i',1]>=0 & `matscore'[`i',3]<30 & `matscore'[`i',3]<`scoretogroup' {
+            local scoretogroup=`matscore'[`i',3]
+            local rowtogroup1=`i'
+            local stop=0
+         }
+      }
+      if `stop'!=1 {
+         if `rowtogroup1'>1&`rowtogroup1'<`=`nbitems'-`j'' {
+            if `matscore'[`=`rowtogroup1'-1',1]<`matscore'[`=`rowtogroup1'+1',1] {
+               local rowtogroup2=`rowtogroup1'
+               local rowtogroup1=`rowtogroup1'-1
+            }
+            else {
+               local rowtogroup2=`rowtogroup1'+1
+            }
+         }
+         else if `rowtogroup1'==1 {
+            local rowtogroup2=2
+         }
+         else if `rowtogroup1'==`=`nbitems'-`j'' {
+            local rowtogroup2=`nbitems'-`j'
+            local rowtogroup1=`nbitems'-`j'-1
+         }
+         matrix `tmp'=`matscore'
+         matrix `matscore'=J(`=`nbitems'-`j'',3,0)
+         if `rowtogroup1'!=1 {
+            matrix `matscore'[1,1]=`tmp'[1..`=`rowtogroup1'-1',1..3]
+         }
+         matrix `matscore'[`rowtogroup1',1]=`tmp'[`rowtogroup1',1]
+         matrix `matscore'[`rowtogroup1',2]=`tmp'[`rowtogroup2',2]
+         matrix `matscore'[`rowtogroup1',3]=`tmp'[`rowtogroup1',3]+`tmp'[`rowtogroup2',3]
+         if `rowtogroup2'!=`=`nbitems'-`j'' {
+            matrix `matscore'[`rowtogroup2',1]=`tmp'[`=`rowtogroup2'+1'..`=`nbitems'-`j'',1..3]
+         }
+      }
+   }
+   local nbrows=rowsof(`matscore')-1
+   local thresholds
+   forvalues i=1/`nbrows' {
+      local tmp=`matscore'[`i',2]
+      local thresholds `thresholds' `tmp'
+   }
+   local group `thresholds'
+}
+
+
+if "`group'"=="" {
+	forvalues i=1/`=`nbitems'-1' {
+		local group "`group' `i'"
+	}
+}
+local nbgroups:word count `group'
+local groupmax:word `nbgroups' of `group'
+if `groupmax'>=`nbitems' {
+	di in red "You cannot form a group with the higher possible score."
+	di in red "The higher possible value of the group option is `=`nbitems'-1'."
+        di in red "Please correct your group option."
+	error 198
+        exit
+}
+else {
+	if `groupmax'!=`=`nbitems'-1' {
+		local group "`group' `=`nbitems'-1'"
+		local nbgroups=`nbgroups'+1
+	}
+}
+local nbgroups=`nbgroups'+1
+
+if "`dirsave'"!=""&"`filessave'"=="" {
+        di in ye "If you want to save yours graphs, use the filessave option"
+}
+if "`filessave'"!="" {
+        if "`dirsave'"=="" {
+              local dirsave "`c(pwd)'"
+        }
+        di in ye "The graphs files will be saved in `dirsave'"
+}
+if "`dirsave'"!="" {
+        if "`filesave'"=="" {
+              local filesave "filesave"
+        }
+}
+
+
+if "`pause'"!=""&"`draw'"=="" {
+     pause on
+}
+
+if "`difficulties'"!="" {
+    capture confirm matrix `difficulties'
+    if _rc!=0  {
+	di in red "The vector `difficulties' defined in the {hi:difficulties} option does not exist."
+	error 198
+        exit
+    }
+}
+
+if "`difficulties'"!=""&"`method'"!="mml" {
+   di in red "The {hi:difficulties} option can be defined only for MML method."
+   error 198
+   exit
+}
+
+if "`covariables'"!=""&"`method'"!="mml" {
+   di in red "The {hi:covariables} option can be defined only for MML method."
+   error 198
+   exit
+}
+
+
+
+/***********************************************************************************************************
+POSSIBLE TEST
+***********************************************************************************************************/
+
+if ("`icc'"!=""|"`fitgraph'"!=""|"`splittest'"!=""|"`details'"!="")&"`test'"=="NONE" {
+	di in green "You cannot use the {hi:details}, {hi:icc}, {hi:fitgraph} or {hi:splittest} options if you use {hi:test(none)}."
+        di in green "These options are ignored."
+	local details
+	local icc
+	local fitgraph
+	local splittest
+}
+if "`comp'"!=""&"`method'"=="cml" {
+   	di in green "You cannot compare two populations ({hi:comp} option) with the CML estimation method"
+   	di in green "This option is ignored."
+        local comp
+}
+if "`method'"!="cml"&"`test'"=="WP" {
+	di in green "The Wright-Panchapakesan test is not authorized with MML or GEE."
+	di in green "The WP tests are replaced by Van den Wollenberg Q tests."
+        local test Q
+}
+if "`method'"=="gee"&"`ld'"!="" {
+	di in green "You cannot use the {hi:nold} option with the GEE method of estimation"
+	di in green "This option is ignored."
+        local ld
+}
+
+
+if "`test'"==""|"`test'"=="R" {
+   local test "R"
+   if "`method'"=="cml" {
+      local namewp "R1c"
+      local descwp "R1c test"
+   }
+   else {
+      local namewp="R1m"
+      local descwp "R1m test"
+   }
+}
+if `nbitems'>999999|"`test'"=="WP" {
+	local namewp "  Y"
+	local descwp "Wright-Panchapakesan Y test"
+	local q2
+}
+ else if "`test'"=="Q" {
+	local namewp " Q1"
+	local descwp "Van den Wollenberg Q1 test"
+}
+
+if "`method'"!="cml"&"`meandiff'"!="" {
+	di in green "The {hi:meandiff} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local meandiff
+}
+
+if "`method'"!="cml"&"`splittests'"!="" {
+	di in green "The {hi:splittests} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local splittests
+}
+if "`method'"!="cml"&"`dif'"!="" {
+	di in green "The {hi:dif} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local dif
+}
+
+/***********************************************************************************************************
+SCORES AND GROUPS
+************************************************************************************************************/
+
+qui count if `touse'==1
+local N=r(N)
+
+
+tempvar id
+gen `id'=_n
+
+
+qui keep `varlist' `comp' `id' `touse'
+
+tempname rep item
+tempvar score realscore
+qui genscore `varlist',score(`score')
+*   di "LD : `ld'"
+qui count if `score'==.&`touse'==1
+local nbindmiss=r(N)
+
+if "`ld'"=="" {
+   qui drop if `score'==.
+}
+forvalues i=1/`nbitems' {
+	rename ``i'' `rep'`i'
+	*qui drop if `rep'`i'==.|`rep'`i'>1
+	*qui replace `score'=`score'+`rep'`i'
+}
+
+
+
+local liminf0=0
+local limsup0=0
+local liminf`nbgroups'=`nbitems'
+local limsup`nbgroups'=`nbitems'
+
+
+local recode
+forvalues i=1/`=`nbgroups'-1' {
+	if `i'!= 1{
+		local liminf`i' : word `=`i'-1' of `group'
+	}
+	else {
+		local liminf1=0
+	}
+	local liminf`i'=`liminf`i''+1
+	local limsup`i':word `i' of `group'
+
+	local recode "`recode' `liminf`i''/`limsup`i''=`i'"
+}
+qui gen `realscore'=`score'
+qui recode `score' `recode' `nbitems'=`nbgroups'
+
+local smallgroup=0
+
+forvalues i=0/`nbgroups' {
+	qui count if `score'==`i'
+	local effscore`i'=r(N)
+	if `i'!=0&`i'!=`nbgroups'&`effscore`i''<30 {
+		local smallgroup=1
+	}
+}
+/***********************************************************************************************************
+ESTIMATION OF THE DIFFICULTY PARAMETERS
+************************************************************************************************************/
+if "`trace'"!="" {
+  di in green "*** Estimation of the difficulty parameters"
+}
+
+tempname ll coef var beta Vbeta est
+
+if "`method'"=="gee" {
+   qui geekel2d `rep'1-`rep'`nbitems',ll
+   if `r(error)'==1 {
+       di "The variance of the latent trait probably is too high to made the GEE a efficient method to estimate the parameters."
+       error 499
+       exit
+   }
+   scalar `ll'=r(ll)
+   local nbind=r(N)
+   matrix `coef'=r(b)
+   matrix `est'=`coef'
+   matrix `est'[1,`=`nbitems'+1']=sqrt(`est'[1,`=`nbitems'+1'])
+   matrix `var'=r(V)
+   matrix `beta'=`coef'[1,1..`nbitems']
+   matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+   local sig=sqrt(`coef'[1,`=`nbitems'+1'])
+   local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])/sqrt(`nbind')/(`sig'*2)
+}
+
+qui reshape long `rep' , i(`id') j(`item')
+
+tempvar diff tl
+gen `diff'=0
+
+forvalues i=1/`nbitems' {
+	qui gen `rep'`i'=`item'==`i'
+	qui replace `rep'`i'=-`rep'`i'
+}
+
+
+if "`method'"=="mml" {
+   if "`difficulties'"==""{
+      qui xtlogit `rep' `rep'1-`rep'`nbitems', i(`id') nocons iterate(`iterate')
+      matrix `est'=e(b)
+      matrix `est'[1,`=`nbitems'+1']=exp(`est'[1,`=`nbitems'+1']/2)
+   }
+   else {
+      tempname offset b
+      qui gen `offset'=0
+      forvalues i=1/`nbitems' {
+          qui replace `offset'=-(`difficulties'[1,`i']) if `item'==`i'
+      }
+      *xtlogit `rep'  , offset(`offset') i(`id') nocons iterate(`iterate')
+      qui gllamm `rep'  , offset(`offset') i(`id') nocons iterate(`iterate') link(logit) fam(bin)
+*      noi ereturn list
+      matrix `b'=e(b)
+      matrix `est'=`difficulties',0
+      matrix `est'[1,`=`nbitems'+1']=exp(`b'[1,1]/2)
+   }
+}
+else if "`method'"=="cml" {
+	qui clogit `rep' `rep'1-`rep'`=`nbitems'-1', group(`id')
+}
+
+*set trace on
+
+if "`method'"!="gee" {
+   if "`difficulties'"=="" {
+      matrix `coef'=e(b)
+      matrix `var'=e(V)
+   }
+   else {
+      matrix `coef'=`difficulties'
+      matrix `var'=J(`=`nbitems'+1',`=`nbitems'+1',.)
+      matrix `var'[`=`nbitems'+1',`=`nbitems'+1']=e(V)
+   }
+   scalar `ll'=e(ll)
+   local nbind=e(N)/`nbitems'
+
+
+   if "`meandiff'"!="" {
+      matrix `var'=J(`nbitems',`nbitems',.)
+      matrix `coef'=J(1,`nbitems',.)
+      local param
+      local lin `rep'1
+      forvalues j=2/`=`nbitems'-1' {
+         local lin `lin'+`rep'`j'
+      }
+      local lin (`lin')/`nbitems'
+
+      forvalues j=1/`=`nbitems'-1' {
+         qui lincom `rep'`j'-`lin'
+         matrix `coef'[1,`j']=`r(estimate)'
+         matrix `var'[`j',`j']=`r(se)'^2
+      }
+      qui lincom -`lin'
+      matrix `coef'[1,`nbitems']=`r(estimate)'
+      matrix `var'[`nbitems',`nbitems']=`r(se)'^2
+   }
+   *set trace on
+   if "`method'"=="mml" {
+	local sig=e(sigma_u)
+	local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])*`sig'/2
+	if "`difficulties'"=="" {
+           matrix `beta'=`coef'[1,1..`nbitems']
+           matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+           local sig=e(sigma_u)
+	   local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])*`sig'/2
+	}
+	else {
+	   tempname tmp
+	   matrix `tmp'=e(b)
+           local sig=`tmp'[1,1]
+           matrix `tmp'=e(V)
+	   local sesig=sqrt(`tmp'[1,1])
+           matrix `beta'=`difficulties'
+           matrix `Vbeta'=J(`nbitems',`nbitems',.)
+	}
+   }
+   else if "`method'"=="cml"&"`meandiff'"==""{
+	matrix `beta'=`coef'[1,1..`=`nbitems'-1']
+	matrix `Vbeta'=`var'[1..`=`nbitems'-1',1..`=`nbitems'-1']
+   }
+   else if "`method'"=="cml"&"`meandiff'"!=""{
+	matrix `beta'=`coef'
+	matrix `Vbeta'=`var'
+   }
+}
+
+if ("`method'"=="mml"|"`method'"=="gee") {
+   local colnames
+   forvalues i=1/`nbitems' {
+      local colnames "`colnames' `rep':`rep'`i'"
+   }
+   local id2=substr("`id'",1,4)
+   local colnames "`colnames' `id2'1:_cons"
+   matrix colnames `est'=`colnames'
+
+   capture gllamm `rep' `rep'1-`rep'`nbitems', i(`id') nocons family(binom) link(logit) trace from(`est') eval
+   tempname u
+   qui gllapred `u',u
+   tempname theta sdtheta
+   matrix `theta'=J(1,`=`nbitems'+1',0)
+   matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',0)
+   qui su `u'm1 if `rep'1==-1
+   local vartheta=r(Var)
+   qui gen `u's2=`u's1^2
+   qui su `u's2 if `rep'1==-1
+   local meanse2=r(mean)
+   local psi=1-`meanse2'/`vartheta'
+   forvalues s=0/`nbitems' {
+      qui su `u'm1 if `realscore'==`s'
+      local theta`s'=r(mean)
+      qui su `u's1 if `realscore'==`s'
+      local sdtheta`s'=r(mean)
+      matrix `theta'[1,`=`s'+1']=`theta`s''
+      matrix `sdtheta'[`=`s'+1',`=`s'+1']=`sdtheta`s''
+   }
+}
+
+forvalues i=1/`nbitems' {
+	if `i'==`nbitems'&"`method'"=="cml"&"`meandiff'"=="" {
+		local beta`i'=0
+		local sd`i' .
+		local fixed`i' "*"
+	}
+	else {
+		local beta`i'=`coef'[1,`i']
+		local sd`i'=sqrt(`var'[`i',`i'])
+	}
+	qui replace `diff'=-`beta`i'' if `item'==`i'
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATIONS
+***********************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+   if "`trace'"!="" {
+     di in green "*** Test of comparison of two populations"
+   }
+         qui inspect `comp'
+         local unique=r(N_unique)
+         if `unique'== 2 {
+		qui su `comp'
+		local mincomp=r(min)
+		local maxcomp=r(max)
+	    	tempname bmin bmax
+	    	qui xtlogit `rep' if `comp'==`mincomp',offset(`diff') i(`id')
+	    	matrix `bmin'=e(b)
+	    	local meanmin=`bmin'[1,1]
+	    	local varmin=e(sigma_u)^2
+	    	local llmin=e(ll)
+	    	local Nmin=e(N_g)
+	    	qui xtlogit `rep' if `comp'==`maxcomp',offset(`diff') i(`id')
+	    	matrix `bmax'=e(b)
+	    	local meanmax=`bmax'[1,1]
+	    	local varmax=e(sigma_u)^2
+	    	local llmax=e(ll)
+	    	local Nmax=e(N_g)
+	    	local Zcomp=(`meanmin'-`meanmax')/sqrt(`varmin'/`Nmin'+`varmax'/`Nmax')
+		local pvalue=1-norm(abs(`Zcomp'))
+	 }
+	 else {
+	        di "It is impossible to compare more than two populations"
+	        di "The comparison process is not run"
+	        local comp
+	 }
+}
+
+/***********************************************************************************************************
+ESTIMATION OF THE ABILITY PARAMETERS  / CML
+************************************************************************************************************/
+if `nbitems'>=2 {
+   if "`trace'"!="" {
+      di in green "*** Estimation of the ability parameters"
+   }
+   if "`method'"=="cml" {
+      tempfile verytmp
+      qui save `verytmp',replace
+      drop _all
+      qui set obs 20001
+      qui gen theta=(_n-10001)/1000
+      qui gen A=1
+      forvalues j=1/`nbitems' {
+         qui gen u`j'=exp(theta-`beta`j'')
+         qui gen p`j'=u`j'/(1+u`j')
+         qui gen a`j'=1/u`j'
+         qui replace A=A*a`j'
+         qui gen i`j'=u`j'/(1+u`j')^2
+         qui gen j`j'=(u`j'*(1-u`j'))/(1+u`j')^3
+      }
+      qui egen P=rsum(p*)
+      qui egen I=rsum(i*)
+      qui egen J=rsum(j*)
+      qui gen V=1/I^2*(I+J^2)/(4*I^2)
+      qui gen V2=1/I
+      tempname theta sdtheta
+      matrix `theta'=J(1,`=`nbitems'+1',0)
+      matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',.)
+      forvalues s=0/`nbitems' {
+         qui gen f`s'=abs(`s'-P+.5*J/I)
+         qui sort f`s'
+         matrix `theta'[1,`=`s'+1']=theta[1]
+         matrix `sdtheta'[`=`s'+1',`=`s'+1']=sqrt(V2[1])
+      }
+      use "`verytmp'",replace
+   }
+   qui gen `tl'=0
+   forvalues s=0/`nbitems' {
+      local theta`s'=`theta'[1,`=`s'+1']
+      qui replace `tl'=`theta`s'' if `realscore'==`s'
+      local sdtheta`s'=`sdtheta'[`=`s'+1',`= `s'+1']
+   }
+   tempname pred
+   qui gen `pred'=log(exp(`rep'*(`tl'+`diff'))/(1+exp(`tl'+`diff')))
+
+   qui su `pred'
+   local globalll=r(sum)
+
+   local nulscore=0
+   forvalues i=0/`nbgroups' {
+      qui count if `score'==`i'&`item'==1
+      local nbscore`i'=r(N)
+      if `nbscore`i''==0 {
+         local nulscore=1
+      }
+   }
+   if `nulscore' {
+      di in green "{p}At least one group of scores concerns none individuals. Tests will be not computed.{p_end}"
+      di in green "{p}Use the {hi:group} or the {hi:autogroup} options.{p_end}"
+      local test "NONE"
+      local details
+      local icc
+      local fitgraph
+      local splittest
+   }
+   forvalues i=0/`nbitems' {
+      qui count if `realscore'==`i'&`item'==1
+      local nbrealscore`i'=r(N)
+   }
+}
+
+/***********************************************************************************************************
+TESTS OF THE FIRST ORDER
+************************************************************************************************************/
+
+tempname Pi
+matrix define `Pi'=J(`nbitems',`=`nbitems'-1',0)
+if "`test'"!="NONE" {
+   qui drop if `score'==.
+   if "`trace'"!="" {
+      di in green "*** Tests of the first order"
+   }
+   tempname Obs Obs2 Th Th2
+
+   matrix define `Obs'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Obs2'=J(`nbitems',`=`nbgroups'-1',0)
+   matrix define `Th'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Th2'=J(`nbitems',`=`nbgroups'-1',0)
+   local listofitemsc
+
+   /* Estimation of the gamma symetrical functions*/
+   local c0 "1"
+   local c`nbitems' "`nbitems'*x"
+   forvalues j=1/`nbitems' {
+      local listini`j'
+      local listofitemsc "`listofitemsc' `beta`j''"
+      local c0 `c0'*(1+exp(x-`beta`j''))
+      local c`nbitems' `c`nbitems''-`beta`j''
+      forvalues k=1/`nbitems' {
+         local listini`j'k`k'
+         if `k'!=`j' {
+            local listini`j' "`listini`j'' `beta`k''"
+         }
+         forvalues l=1/`nbitems' {
+            if `l'!=`j'&`l'!=`k' {
+               local listini`j'k`k' "`listini`j'k`k'' `beta`l''"
+            }
+         }
+      }
+   }
+
+   gammasym `listofitemsc'
+
+   /*Estimation, for each value of the score s of the probability to respond to each item (Pi) and of the theorical number of positive responses (Ths) and of theorical number of positive respond per item pair (Ws)*/
+   forvalues s=1/`nbitems' {
+      local denom`s'=r(gamma`s')
+      tempname  W`s'
+      matrix define `W`s''=J(`nbitems',`nbitems',0)
+   }
+   tempvar prob prob2 z y v z2 y2 v2 c r q e
+   qui gen `prob'=.
+   qui gen `prob2'=.
+   forvalues j=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui count if `rep'==1&`item'==`j'&`realscore'==`s'
+         matrix `Obs'[`j',`s']=r(N)
+         if "`test'"!="WP" {
+            gammasym `listini`j''
+            local num`j'=r(gamma`=`s'-1')
+            if "`method'"=="cml"|"`test'"=="Q" {
+               matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s''
+            }
+            else {
+               gausshermite exp(`s'*x)/(`c0'), sigma(`sig')
+               local int`s'=r(int)
+               if "`test'"=="R"&`nbrealscore`s''!=0{
+                  local tmp=exp(-`beta`j'')*`num`j''*`int`s''*`nbind'/`nbrealscore`s''
+                  matrix `Pi'[`j',`s']=`tmp'
+               }
+               else if `nbrealscore`s''==0 {
+                  matrix `Pi'[`j',`s']=0
+               }
+            }
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  if `s'>=2 {
+                     gammasym `listini`j'k`k''
+                     local num`j'k`k'=r(gamma`=`s'-2')
+                     if "`method'"=="cml" {
+                        matrix `W`s''[`j',`k']=`nbrealscore`s''*exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''/`denom`s''
+                     }
+                     else {
+                        matrix `W`s''[`j',`k']=exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''*`int`s''*`nbind'
+                     }
+                     matrix `W`s''[`k',`j']=`W`s''[`j',`k']
+                  }
+               }
+            }
+         }
+         else if "`test'"=="WP" {
+            matrix `Pi'[`j',`s']=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j''))
+         }
+         matrix `Th'[`j',`s']=`Pi'[`j',`s']*`nbrealscore`s''
+         qui replace `prob'=`Pi'[`j',`s'] if `realscore'==`s'&`item'==`j'
+         qui replace `prob2'=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) if `realscore'==`s'&`item'==`j'
+         matrix `W`s''[`j',`j']=`nbrealscore`s''*`Pi'[`j',`s']
+         if "`test'"!="R" {
+            matrix `W`s''[`j',`j']=`W`s''[`j',`j']*abs(1-`Pi'[`j',`s'])
+         }
+      }
+   }
+   qui gen `v2'=abs(`prob'*(1-`prob'))
+   qui gen `z2'=(`rep'-`prob')^2
+   qui gen `y2'=`z2'/`v2'
+   qui gen `c'=abs(`prob'*(1-`prob')*(`prob'^3+(1-`prob')^3))
+   qui gen `r'=`c'/(`v2')^2
+   qui gen `e'=`c'-(`v2')^2
+
+   forvalues j=1/`nbitems' {
+      qui su `y2' if `item'==`j'
+      local outfit`j'=r(mean)
+      qui su `r' if `item'==`j'
+      local Voutfit`j'=r(sum)
+      local Voutfit`j'=`Voutfit`j''/(`nbind')^2-1/`nbind'
+      local outfitstd`j'=(`outfit`j''^(1/3)-1)*(3/sqrt(`Voutfit`j''))-sqrt(`Voutfit`j'')/3
+
+      qui su `z2' if `item'==`j'
+      local n=r(sum)
+      qui su `v2' if `item'==`j'
+      local d=r(sum)
+      local infit`j'=`n'/`d'
+      qui su `e' if `item'==`j'
+      local sume=r(sum)
+      local Vinfit`j'=`sume'/(`d')^2
+      local infitstd`j'=(`infit`j''^(1/3)-1)*(3/sqrt(`Vinfit`j''))-sqrt(`Vinfit`j'')/3
+   }
+   tempname tmp stattest testitems
+
+   /*Estimation, by scores group g, of the theorical number of positive response (Th2g) and of the positive respond to each items pair (W2g)*/
+   scalar `stattest'=0
+   forvalues g=1/`=`nbgroups'-1' {
+      tempname  W2`g' d2`g'
+      matrix define `W2`g''=J(`nbitems',`nbitems',0)
+      forvalues s=`liminf`g''/`limsup`g'' {
+         forvalues j=1/`nbitems' {
+            matrix `Obs2'[`j',`g']=`Obs2'[`j',`g']+`Obs'[`j',`s']
+            matrix `Th2'[`j',`g']=`Th2'[`j',`g']+`Th'[`j',`s']
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  matrix `W2`g''[`j',`k']=`W2`g''[`j',`k']+`W`s''[`j',`k']
+                  matrix `W2`g''[`k',`j']=`W2`g''[`j',`k']
+               }
+            }
+            matrix `W2`g''[`j',`j']=`W2`g''[`j',`j']+`W`s''[`j',`j']
+         }
+      }
+
+      /*Estimation of the d2g vectors*/
+      matrix `d2`g''=`Obs2'[1..`nbitems',`g']-`Th2'[1..`nbitems',`g']
+
+      /*Estimation of the influences on the test of each item (testitemsg matrix) and of the test statistic (stattest)*/
+      tempname test`g' testitems`g'
+      matrix `test`g''=`d2`g'''*syminv(`W2`g'')*`d2`g''
+      capture matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      if _rc!=0 {
+         matrix `tmp'=J(`nbitems',`nbitems',0)
+         forvalues j=1/`nbitems' {
+            matrix `tmp'[`j',`j']=`W2`g''[`j',`j']
+         }
+         di in green "Group `g' (`liminf`g''/`limsup`g''): The weight matrix is not positive-definite, the diagonal matrix is used to estimate the contribution of the items on the `wpname' statistic"
+         matrix list `tmp'
+         matrix `testitems`g''=cholesky(syminv(`tmp'))*`d2`g''
+      }
+      else {
+         matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      }
+      scalar `stattest'=`stattest'+`test`g''[1,1]
+   }
+   matrix `testitems'=J(`nbitems',1,0)
+   forvalues j=1/`nbitems' {
+      forvalues g=1/`=`nbgroups'-1' {
+         matrix `testitems'[`j',1]=`testitems'[`j',1]+`testitems`g''[`j',1]^2
+      }
+   }
+
+   /*Adaptation for the Q1 statistic*/
+   if "`test'"=="Q" {
+      scalar `stattest'=`stattest'*`=`nbitems'-1'/`nbitems'
+   }
+
+   /*Correction for R1m and Q1m*/
+   if ("`test'"=="R"|"`test'"=="Q")&("`method'"=="mml"|"`method'"=="gee") {
+      local c`nbitems' exp(`c`nbitems'')/(`c0')
+      local c0 1/(`c0')
+      gausshermite `c0', sigma(`sig')
+      local ci0=r(int)*`nbind'
+      gausshermite `c`nbitems'',sigma(`sig')
+      local ci`nbitems'=`nbind'*r(int)
+      scalar `stattest'=`stattest'+(`nbrealscore0'-`ci0')^2/`ci0'+(`nbrealscore`nbitems''-`ci`nbitems'')^2/`ci`nbitems''
+  }
+
+
+
+/***********************************************************************************************************
+TESTS U
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests U"
+      }
+
+      local quartile=`nbind'/4
+      local c1=0
+      local n1=0
+      while `n1'<`quartile' {
+         local c1=`c1'+1
+         local n1=`n1'+`nbrealscore`c1''
+      }
+      local c2=`nbitems'
+      local n2=0
+      while `n2'<`quartile' {
+         local c2=`c2'-1
+         local n2=`n2'+`nbrealscore`c2''
+      }
+      forvalues j=1/`nbitems' {
+         local zu1=0
+         local zu2=0
+         forvalues s=1/`c1' {
+            local zu1=`zu1'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         forvalues s=`c2'/`=`nbitems'-1' {
+            local zu2=`zu2'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         local U`j'=(`zu1'-`zu2')/sqrt(`c1'+`nbitems'-`c2')
+      }
+   }
+
+
+
+/***********************************************************************************************************
+TESTS OF THE SECOND ORDER /*undocumented in beta test*/
+************************************************************************************************************/
+
+   if "`q2'"!="" {
+      if "`trace'"!="" {
+         di in green "*** Tests of the second order"
+      }
+
+      tempfile Q2file
+      qui save "`Q2file'",replace
+      qui use "`saveraschtest'",replace
+
+      qui keep if `touse'==1
+      gen `score'=0
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'
+	 rename ``i'' `rep'`i'
+	 qui replace `score'=`score'+`rep'`i'
+      }
+      qui recode `score' `recode'
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'=0
+         forvalues j=`=`i'+1'/`nbitems' {
+	    local listinci`i'j`j'
+	    forvalues k=1/`nbitems' {
+	       if `k'!=`i'&`k'!=`j' {
+	          local listinci`i'j`j' "`listinci`i'j`j'' `beta`k''"
+	       }
+	    }
+	 }
+      }
+
+      local Q2tot=0
+      forvalues k=2/`=`nbitems'-1' {
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`i'+1'/`nbitems' {
+	       if `k'==1 {
+	          local num=0
+               }
+	       else {
+	          gammasym `listinci`i'j`j''
+                  local num=r(gamma`=`k'-2')
+               }
+	       local athi`i'j`j'k`k'=exp(-`beta`i'')*exp(-`beta`j'')*`num'/`denom`k''
+	       local bthi`i'j`j'k`k'=`nbth`i's`k''-`athi`i'j`j'k`k''
+	       local cthi`i'j`j'k`k'=`nbth`j's`k''-`athi`i'j`j'k`k''
+	       local dthi`i'j`j'k`k'=1-`athi`i'j`j'k`k''-`bthi`i'j`j'k`k''-`cthi`i'j`j'k`k''
+            }
+         }
+      }
+      forvalues k=1/`=`nbgroups'-1' {
+         local Q2`k'=0
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`j'+1'/`nbitems' {
+	       qui count if  `rep'`i'==1&`rep'`j'==1&`score'==`k'
+	       local aempi`i'j`j'k`k'=r(N)
+	       local ath2i`i'j`j'k`k'=0
+	       local bth2i`i'j`j'k`k'=0
+	       local cth2i`i'j`j'k`k'=0
+	       local dth2i`i'j`j'k`k'=0
+	    }
+	 }
+         if `limsup`k''!=1 {
+            forvalues l=`liminf`k''/`limsup`k'' {
+	       forvalues i=1/`=`nbitems'-1' {
+	          forvalues j=`=`i'+1'/`nbitems' {
+		     if `l'!=1 {
+		        local ath2i`i'j`j'k`k'=`ath2i`i'j`j'k`k''+`athi`i'j`j'k`l''*`nbrealscore`l''
+			local bth2i`i'j`j'k`k'=`bth2i`i'j`j'k`k''+`bthi`i'j`j'k`l''*`nbrealscore`l''
+			local cth2i`i'j`j'k`k'=`cth2i`i'j`j'k`k''+`cthi`i'j`j'k`l''*`nbrealscore`l''
+			local dth2i`i'j`j'k`k'=`dth2i`i'j`j'k`k''+`dthi`i'j`j'k`l''*`nbrealscore`l''
+                     }
+		  }
+               }
+            }
+	    forvalues i=1/`=`nbitems'-1' {
+	       forvalues j=`=`i'+1'/`nbitems' {
+	          local d2i`i'j`j'k`k'=(`aempi`i'j`j'k`k''-`ath2i`i'j`j'k`k'')^2
+		  local Q2i`i'j`j'k`k'=`d2i`i'j`j'k`k''/`ath2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`bth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`cth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`dth2i`i'j`j'k`k''
+		  local Q2i`i'=`Q2i`i''+`Q2i`i'j`j'k`k''
+		  local Q2i`j'=`Q2i`j''+`Q2i`i'j`j'k`k''
+		  local Q2`k'=`Q2`k''+`Q2i`i'j`j'k`k''
+	       }
+	    }
+	 }
+         local Q2tot=`Q2tot'+`Q2`k''
+      }
+      forvalues i=1/`nbitems' {
+         di in green "Item ``i'' : Q2 = `Q2i`i''"
+      }
+      local Q2=`Q2tot'*(`nbitems'-3)/(`nbitems'-1)
+      di in green "Q2 = `Q2tot'"
+      qui use "`Q2file'",replace
+   }
+
+/***********************************************************************************************************
+TEST LR Z
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests LR of Andersen"
+      }
+      local ssll=0
+      tempname Zfile
+      qui save "`Zfile'", replace
+      qui use "`saveraschtest'",replace
+      qui keep if `touse'==1
+      gen `score'=0
+      forvalues j=1/`nbitems' {
+         qui replace `score'=`score'+``j''
+      }
+      qui recode `score' `recode' `nbitems'=`nbgroups'
+      forvalues i=1/`=`nbgroups'-1' {
+         if `effscore`i''>0 {
+            qui raschtestv7 `varlist' if `score'==`i', test(NONE) `ld'
+            local ll`i'=r(cll)
+            local ssll=`ssll'+(`ll`i'')
+         }
+      }
+      local Z=2*`ssll'-2*`ll'
+      use "`Zfile'",replace
+      tempname AndersenZ
+      matrix define `AndersenZ'=(`Z',`=(`nbgroups'-2)*(`nbitems'-1)',1-chi2(`=(`nbitems'-1)*(`nbgroups'-2)',`Z'))
+   }
+}
+
+
+/***********************************************************************************************************
+DISPLAYING RESULTS WITH TESTS
+************************************************************************************************************/
+
+if "`test'"!="NONE" {
+   local conttest= "_c"
+}
+di
+tempname itemfit globalfit
+matrix `globalfit'=J(1,3,0)
+if "`method'"=="cml" {
+   di in green "Estimation method: " in yellow  "Conditional maximum likelihood (CML)"
+   local nbtest=`nbgroups'-1
+   local line=77
+}
+else if "`method'"=="mml"{
+   di in green "Estimation method: " in yellow  "Marginal maximum likelihood (MML)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+else if "`method'"=="gee" {
+   di in green "Estimation method: " in yellow  "Generalized Estimating Equations (GEE)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+if "`test'"=="NONE" {
+   local line=35
+}
+di in green  "Number of items: " in yellow  `nbitems'
+
+di in green  "Number of groups: " in yellow  `=`nbgroups'+1' `conttest'
+if "`test'"!="NONE" {
+   di in green " (" in yellow "`nbtest'" in green " of them are used to compute the statistics of test)"
+}
+if "`method'"=="cml" {
+   local nbind=`nbind'+`effscore0'+`effscore`nbgroups''
+   local cont "_c"
+   matrix `itemfit'=J(`nbitems',6,0)
+}
+else {
+   local cont
+   matrix `itemfit'=J(`nbitems',5,0)
+}
+local missing=`N'-`nbind'
+di in green "Number of individuals: " in yellow `N'
+di in green "Number of individuals with missing values: " in yellow `nbindmiss' _c
+if "`ld'"=="" {
+   di in green " (removed)"
+}
+else {
+   di
+}
+di in green  "Number of individuals with nul or perfect score: " in yellow `=`effscore0'+`effscore`nbgroups'''
+if "`method'"=="cml" {
+   di in green  "Conditional log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+else {
+   di in green "Marginal log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+di
+noi di in green  _col(16) "Difficulty" `conttest'
+if "`test'"!="NONE" {
+   di in green _col(58) "Standardized"
+}
+noi di in green _col(9) "Items" _col(16) "parameters" _col(28) "std Err." `conttest'
+if "`test'"!="NONE" {
+   local varin=int(2/sqrt(`nbind')*100)/100
+   local varout=int(6/sqrt(`nbind')*100)/100
+   di _col(41) "`namewp'" _col(47) "df" _col(50) "p-value" _col(58) "Outfit" _col(66) "Infit" `cont'
+   if "`method'"=="cml" {
+      di in green _col(77) "U"
+   }
+}
+di in green  "{hline `line'}"
+forvalues i=1/`nbitems' {
+   noi di in yellow _col(3) %12s abbrev("``i''`fixed`i''" ,12) in yellow _col(18) %8.5f `beta`i'' _col(29) %6.5f `sd`i'' `conttest'
+   if "`test'"!="NONE" {
+      di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfitstd`i'' _col(65) %6.3f `infitstd`i''  /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/  `cont'
+      matrix `itemfit'[`i',1]=`testitems'[`i',1]
+      matrix `itemfit'[`i',2]=`=`nbgroups'-2'
+      matrix `itemfit'[`i',3]=1-chi2(`=`nbgroups'-2',`testitems'[`i',1])
+      matrix `itemfit'[`i',4]=`outfitstd`i''
+      matrix `itemfit'[`i',5]=`infitstd`i''
+      if "`method'"=="cml" {
+         di in ye _col(72) %6.3f `U`i''
+         matrix `itemfit'[`i',6]=`U`i''
+      }
+   }
+}
+di in green  "{hline `line'}"
+if "`test'"!="NONE" {
+   if "`method'"=="cml" {
+      local df=(`nbgroups'-2)*(`nbitems'-1)
+   }
+   else {
+      local df=(`nbgroups'-1)*(`nbitems'-1)-1
+   }
+   matrix `globalfit'=(`stattest',`df',1-chi2(`df',`stattest'))
+   noi di in green _col(6) "`descwp'" _col(32) in gr "`namewp'=" _col(36) in ye %8.3f `globalfit'[1,1] _col(46) %3.0f `globalfit'[1,2] _col(51) %6.4f `globalfit'[1,3]
+   if "`method'"=="cml" {
+      noi di in green _col(6) "Andersen LR test" _col(34) "Z=" in yellow _col(36) %8.3f `AndersenZ'[1,1] _col(46) %3.0f `AndersenZ'[1,2] _col(51) %6.4f `AndersenZ'[1,3]
+   }
+   di in green  "{hline `line'}"
+}
+if "`method'"!="cml" {
+   di in green _col(10) in yellow "Sigma" _col(18) %8.5f `sig' _col(29) %6.5f `sesig'
+   di in green  "{hline `line'}"
+}
+
+if "`method'"=="cml"&"`meandiff'"==""{
+   di in green "*: The difficulty parameter of this item had been fixed to 0"
+}
+if "`method'"=="cml"&"`meandiff'"!=""{
+   di in green "The mean of the difficulty parameters is fixed to 0"
+}
+if `smallgroup'==1&"`test'"!="NONE" {
+   di in green "You have groups of scores with less than 30 individuals. The tests can be invalid."
+}
+if "`method'"!="cml"&"`test'"=="Q" {
+   di in green "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test."
+}
+
+/*Tabular of the estimated values of the latent trait*/
+
+   di
+   di
+   noi di in green _col(33) "Ability" _col(60) "Expected"
+   noi di in green _col(17) "Group" _col(23) "Score" _col(30) "parameters" _col(42) "std Err." _col(54) "Freq." _col(63) "Score"_c
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      noi di in green _col(75) "ll"
+   }
+   else {
+      noi di ""
+   }
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      local line=62
+   }
+   else {
+     local line=51
+   }
+   di in green _col(17) "{hline `line'}"
+   local nonul=0
+   forvalues g=0/`nbgroups' {
+      if `g'!=0 {
+         di in green _col(17) "{dup `line':-}"
+      }
+      forvalues s=`liminf`g''/`limsup`g'' {
+         if `s'==`liminf`g'' {
+            local tmp `ll`g''
+            local gr `g'
+         }
+         else {
+            local tmp
+            local gr
+         }
+         local expscore`nonul'=0
+         forvalues i=1/`nbitems' {
+            local expscore`nonul'=`expscore`nonul''+1/(1+exp(-`theta`nonul''+`beta`i''))
+         }
+         if "`method'"=="cml" {
+            local format1 %8.3f
+         }
+         else {
+            local format1 %8.5f
+         }
+         noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(32) `format1' `theta`nonul'' _col(42) `format1' `sdtheta`nonul'' _col(55) %4.0f `nbrealscore`s'' _col(64) % 4.2f `expscore`nonul'' _col(68) %11.4f `tmp'
+         local nonul=`nonul'+1
+      }
+   }
+   di in green _col(17) "{hline `line'}"
+   if "`method'"=="mml"|"`method'"=="gee" {
+       di
+       *di in green "Variance of the estimated latent trait" _col(45) in ye %10.4f `vartheta'
+       di in green "Mean variance of the error" _col(45) in ye %10.4f `meanse2'
+       *di in green "Personal Separation Index (PSI)" _col(50) in ye %5.3f `psi'
+       local sig2=`sig'^2
+       di in green "Estimated variance of the latent trait" _col(45) in ye %10.4f `sig2'
+       local psi2=1-`meanse2'/`sig2'
+       di in green "Personal Separation Index (PSI)" _col(45) in ye %10.4f `psi2'
+   }
+
+/***********************************************************************************************************
+DETAILS OPTION
+************************************************************************************************************/
+
+if "`details'"!="" {
+   forvalues g=0/`nbgroups' {
+      if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" {
+         di
+         di in  green "{hline 44}"
+         di in green "Group: " in ye "`g'" in green " from " in ye "`liminf`g''" in green " to " in ye "`limsup`g''" in green " (n=" in ye "`nbscore`g''" in green")"
+         di
+         di _col(3) "Item" _col(10) "Observed" _col(23) "Expected" _col(37) "Scaled"
+         di in green "{dup 44:-}"
+      }
+      if `g'!=0&`g'!=`nbgroups' {
+         forvalues j=1/`nbitems' {
+            local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j'])
+            di _col(3) in ye "``j''" _col(14) %4.0f `Obs2'[`j',`g'] _col(25) %6.2f `Th2'[`j',`g'] _col(36) %7.4f `tmp'
+         }
+         di in green "{dup 44:-}"
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `test`g''[1,1]
+      }
+      else if "`method'"!="cml" {
+         if `g'==0 {
+            local h=0
+         }
+         else {
+            local h=`nbitems'
+         }
+         local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'')
+         di in ye _col(14) %4.0f `nbrealscore`h'' _col(25) %6.2f `ci`h'' _col(36) %7.4f `tmp'
+         di in green "{dup 44:-}"
+         local tmp=`tmp'^2
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `tmp'
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION ICC
+************************************************************************************************************/
+
+if "`icc'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Items Characteristic Curves"
+   }
+   tempvar proba propemp propth propthb
+   qui replace `tl'=. if `realscore'==0|`realscore'==`nbitems'|`realscore'==.
+   qui gen `propemp'=.
+   qui gen `propth'=.
+   qui gen `propthb'=.
+   label variable `propth' "Expected ICC"
+   label variable `propemp' "Observed ICC"
+   label variable `propthb' "Expected ICC"
+   label variable `tl' "Latent trait"
+   global iccs
+   forvalues i=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui replace `propthb'=exp(`theta`s''-`beta`i'')/(1+exp(`theta`s''-`beta`i'')) if `item'==`i'&`realscore'==`s'
+      }
+      qui replace `propemp'=.
+      qui replace `propth'=.
+      tempvar propemp`i' propth`i'
+      qui bysort `realscore' `item' : egen `propth`i''=mean(`propthb') if `item'==`i'
+      qui bysort `realscore' `item' : egen `propemp`i''=mean(`rep') if `item'==`i'
+      qui replace `propth'=`propth`i'' if `item'==`i'
+      qui replace `propemp'=`propemp`i'' if `item'==`i'
+      local mintl=floor(`theta1')
+      local maxtl=floor(`theta`=`nbitems'-1'')+1
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\icc``i''"
+      }
+      if "`v8'"!="" {
+         graph twoway (line  `propemp' `propth' `tl') if `item'==`i' , name(icc``i'',replace) ytitle("")  ylabel(0(.25)1) title("Observed and Expected ICC for the item ``i''") xlabel(`mintl'(1)`maxtl') `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save icc``i''  "`saving'" , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui graph `propemp' `propth' `tl' if `item'==`i' , twoway `saving' c(ll) ylabel(0(.25)1)   xlabel(`mintl'(1)`maxtl') title("Observed and Expected ICC for the item ``i''")
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION INFORMATION
+************************************************************************************************************/
+
+if "`information'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Information graph"
+   }
+
+   tempfile saveinfo
+   qui save "`saveinfo'",replace
+   tempvar info latent
+   drop _all
+   qui set obs 2001
+   gen `latent'=((_n-1)/1001-1)*3
+   label variable `latent' "latent trait"
+   gen `info'=0
+   forvalues i=1/`nbitems' {
+      qui replace `info'=`info'+exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2
+   }
+   local saving "`dirsave'\\information"
+   if "`v8'"!="" {
+      graph twoway (line  `info' `latent') , name(information,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the scale") `draw'
+      if "`filessave'"!="" {
+         graph save information "`saving'" , `replace'
+      }
+      pause
+   }
+   else {
+      if "`filessave'"!="" {
+         local saving "saving(`saving'"
+         if "`replace'"=="" {
+            local saving "`saving')"
+         }
+         else {
+            local saving "`saving',replace)"
+         }
+      }
+      if "`filessave'"=="" {
+         local saving
+      }
+      qui graph `info' `latent' , twoway  `saving' c(l) xlabel(-3(1)3) title("Information graph of the scale")
+      pause
+   }
+   qui use "`saveinfo'",replace
+}
+
+/***********************************************************************************************************
+OPTION FITGRAPH
+************************************************************************************************************/
+
+if "`fitgraph'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graphical validation of the fit"
+   }
+   *set trace on
+   tempname outfit meanz2 meanv2 sumd infit Voutfit outfitstd Vinfit infitstd
+   qui egen `outfit'=mean(`y2'),by(`id')
+   qui egen `Voutfit'=sum(`r'),by(`id')
+   qui replace `Voutfit'=`Voutfit'/(`nbitems')^2-1/`nbitems'
+   qui gen `outfitstd'=(`outfit'^(1/3)-1)*(3/sqrt(`Voutfit'))-sqrt(`Voutfit')/3
+   qui egen `meanz2'=sum(`z2'),by(`id')
+   qui egen `meanv2'=sum(`v2'),by(`id')
+   qui gen `infit'=`meanz2'/`meanv2'
+   qui egen `Vinfit'=sum(`e'),by(`id')
+   qui replace `Vinfit'=`Vinfit'/(`meanv2')^2
+   qui gen `infitstd'=(`infit'^(1/3)-1)*(3/sqrt(`Vinfit'))-sqrt(`Vinfit')/3
+
+   qui su `outfitstd'
+   local mino=floor(2*min(`r(min)',-2))/2
+   local maxo=ceil(2*max(`r(max)',2))/2
+   qui su `infitstd'
+   local mini=floor(2*min(`r(min)',-2))/2
+   local maxi=ceil(2*max(`r(max)',2))/2
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfitind"
+      local savingi "`dirsave'\\infitind"
+   }
+   if "`v8'"!="" {
+      *graph twoway (scatter `outfit' `id'), name(outfit,replace) yline(.6 1.4) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(0(.2)2 2(.5)`maxo') `draw'
+      graph twoway (scatter `outfitstd' `id'), name(outfit,replace) yline(-2 2) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw'
+      pause
+      *graph twoway (scatter `infit' `id'), name(infit,replace) yline(.6 1.4) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(0(.2)2 2(.5)`maxi') `draw'
+      graph twoway (scatter `infitstd' `id'), name(infit,replace) yline(-2 2) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfit "`savingo'" , `replace'
+         graph save infit "`savingi'" , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitstd' `id', `savingo' twoway sy(.) c(.) yline(-2 2) title("Outfit indexes") b2title("Individual indexes") l1("") l2title("Outfit") ylabel(`mino'(.5)`maxo')
+      pause
+      graph `infitstd' `id', `savingi' twoway sy(.) c(.) yline(-2 2) title("Infit indexes") b2title("Individual indexes") l1("")  l2title("Infit") ylabel(`mini'(.5)`maxi')
+      pause
+   }
+   drop _all
+   qui set obs `nbitems'
+   tempvar name betap outfitstdj infitstdj
+   qui gen str9 `name'=""
+   qui gen `betap'=.
+   qui gen `outfitstdj'=.
+   qui gen `infitstdj'=.
+   local mino=-2
+   local maxo=2
+   local mini=-2
+   local maxi=2
+   forvalues j=1/`nbitems' {
+      qui replace `name'="``j''" in `j'
+      qui replace `betap'=`beta`j'' in `j'
+      qui replace `outfitstdj'=`outfitstd`j'' in `j'
+      qui replace `infitstdj'=`infitstd`j'' in `j'
+      local mino=floor(min(`mino',`outfitstd`j'')*2)/2
+      local mini=floor(min(`mini',`infitstd`j'')*2)/2
+      local maxo=ceil(max(`maxo',`outfitstd`j'')*2)/2
+      local maxi=ceil(max(`maxi',`infitstd`j'')*2)/2
+   }
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfititems"
+      local savingi "`dirsave'\\infititems"
+   }
+   if "`v8'"!="" {
+      graph twoway (scatter `outfitstdj' `betap',name(outfititem,replace) mlabel(`name')), yline(-2 2) title("Outfit indexes") xtitle("Difficulty") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw'
+      pause
+      graph twoway (scatter `infitstdj' `betap',name(infititem,replace) mlabel(`name')), yline(-2 2) title("Infit indexes") xtitle("Difficulty") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfititem "`savingo'" , `replace'
+         graph save infititem "`savingi'" , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitstdj' `betap', `savingo' twoway c(.) yline(-2 2) title("Outfit indexes") b2title("Difficulty") l1title("") l2title("Outfit") ylabel(`mino'(.5)`maxo') sy([`name'])
+      pause
+      graph `infitstdj' `betap', `savingi' twoway c(.) yline(-2 2) title("Infit indexes") b2title("Difficulty") l1title("") l2title("Infit") ylabel(`mini'(.5)`maxi') sy([`name'])
+      pause
+   }
+}
+
+
+/***********************************************************************************************************
+OPTION SPLITTESTS
+************************************************************************************************************/
+
+if "`splittests'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Splitting tests"
+   }
+   forvalues j=1/`nbitems' {
+      tempname estneg`j' estpos`j'
+      local listitems
+      forvalues k=1/`nbitems' {
+         if `j'!=`k' {
+            local listitems `listitems' ``k''
+         }
+      }
+      qui use "`saveraschtest'",replace
+      qui keep if `touse'==1
+      qui raschtestv7 `listitems' if ``j''==0,test(NONE) meth(cml) `ld'
+      matrix `estneg`j''=r(beta)
+      local llneg=r(cll)
+      qui raschtestv7 `listitems' if ``j''==1,test(NONE) meth(cml) `ld'
+      matrix `estpos`j''=r(beta)
+      local llpos=r(cll)
+      qui raschtestv7 `listitems',test(NONE) meth(cml) `ld'
+      local llnegpos=r(cll)
+      local nbcol=colsof(`estneg`j'')
+      local meanneg=0
+      local meanpos=0
+      forvalues k=1/`nbcol' {
+         local meanneg=`meanneg'+`estneg`j''[1,`k']
+         local meanpos=`meanpos'+`estpos`j''[1,`k']
+      }
+      local meanneg=`meanneg'/`nbitems'
+      local meanpos=`meanpos'/`nbitems'
+      forvalues k=1/`nbcol' {
+         matrix `estneg`j''[1,`k']=`estneg`j''[1,`k']-`meanneg'
+         matrix `estpos`j''[1,`k']=`estpos`j''[1,`k']-`meanpos'
+         if "`method'"=="cml" {
+            matrix `estneg`j''=`estneg`j'',-`meanneg'
+            matrix `estpos`j''=`estpos`j'',-`meanpos'
+         }
+      }
+      drop _all
+      qui set obs `=`nbitems'+1'
+      tempvar neg pos name diag
+      qui gen `neg'=.
+      qui gen `pos'=.
+      qui gen str9 `name'=""
+      local min=`estneg`j''[1,1]
+      local max=`estneg`j''[1,1]
+      forvalues k=1/`=`nbitems'-1' {
+         qui replace `neg'=`estneg`j''[1,`k'] in `k'
+         qui replace `pos'=`estpos`j''[1,`k'] in `k'
+         local min=min(`min',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local max=max(`max',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local tmp:word `k' of `listitems'
+         qui replace `name'="`tmp'" in `k'
+      }
+      local min=floor(`min')
+      local max=floor(`max')+1
+      qui gen `diag'=.
+      qui replace `diag'=`min' in `nbitems'
+      qui replace `diag'=`max' in `=`nbitems'+1'
+      local Zgr=round(2*(`llneg'+`llpos'-`llnegpos'),0.001)
+      local Zgr=substr("`Zgr'",1,6)
+      local pgr=round(1-chi2(`=`nbitems'-1',`Zgr'),0.0001)
+      local pgr=substr("`pgr'",1,5)
+      local note="Z=`Zgr', df=`=`nbitems'-1' , p=`pgr'"
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\split``j''"
+      }
+      if "`v8'"!="" {
+         graph twoway (scatter `pos' `neg' ,mlabel(`name')) (line `diag' `diag'), ytitle("Positive answer") xtitle("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title(Splitting on ``j'') `draw' legend(off) note("Andersen Z test: `note'") name(split,replace) `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save split "`saving'" , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui replace `diag'=`neg' if `diag'==.
+         graph  `pos' `diag' `diag', `saving' c(.l) sy([`name']i) l1title("") l2title("Positive answer") b2title("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title("Splitting on ``j'' (`note')") `draw'
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION GRAPH
+************************************************************************************************************/
+
+if "`graph'"!=""&"`v8'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graph option"
+   }
+   tempvar  latent2  tl2 delta2 tlth2 labdelta2 labtl2
+   drop _all
+   qui set obs 1001
+   gen `latent2'=(_n-501)/100
+   label variable `latent2' "latent trait"
+   qui gen `tl2'=.
+   qui gen `labtl2'=""
+   forvalues i=0/`nbitems' {
+      *if (`i'!=0&`i'!=`nbitems')|"`method'"!="cml" {
+         qui replace `tl2'=`nbrealscore`i''/`N' if round(`latent2',0.01)==round(`theta`i'',0.01)
+         qui replace `labtl2'="`i'" if round(`latent2',0.01)==round(`theta`i'',0.01)
+      *}
+   }
+   qui gen `delta2'=.
+   qui gen `labdelta2'=""
+   forvalues i=1/`nbitems' {
+      qui replace `delta2'=-.05 if round(`latent2',0.01)==round(`beta`i'',0.01)
+      qui replace `labdelta2'="``i''" if round(`latent2',0.01)==round(`beta`i'',0.01)
+   }
+   if "`method'"=="mml"|"`method'"=="gee" {
+      qui gen `tlth2'=1/(2*_pi*`sig')*exp(-.5*(`latent2'/`sig')^2)
+      label variable `tlth2' "Theorical distribution"
+      local graphmml line `tlth2' `latent2'
+   }
+   label variable `tl2' "Score"
+   label variable `delta2' "Items"
+   local saving "`dirsave'\\graph"
+   local min=-2
+   local max=2
+   forvalues j=1/`nbitems' {
+      if `beta`j''<`min' {
+         local min=`beta`j''-.5
+      }
+      if `beta`j''>`max'&`beta`j''!=. {
+         local max=`beta`j''+.5
+      }
+   }
+   if "`method'"=="cml" {
+      if `theta0'<`min' {
+         local min=`theta0'-.5
+      }
+      if `theta`=`nbitems'-1''>`max' {
+         local max=`theta`=`nbitems'-1''+.5
+      }
+   }
+   else if "`method'"!="cml" {
+      if `theta0'<`min'&`theta0'!=. {
+         local min=`theta0'-.5
+      }
+      if `theta`nbitems''>`max'&`theta`nbitems''!=. {
+         local max=`theta`nbitems''+.5
+      }
+   }
+   local min=floor(`min')
+   local max=floor(`max')+1
+   qui su `tl2'
+   local max2=r(max)
+   if "`method'"!="cml" {
+      qui su `tlth2'
+      local max2=max(`max2',`r(max)')
+   }
+   qui replace `latent2'=. if `latent2'<`min'|`latent2'>`max'
+   if "`v8'"!="" {
+      graph twoway (bar `tl2' `latent2',/*mlabel(`labtl2')*/ barwidth(.3) ) (dropline `delta2' `latent2',mlabel(`labdelta2') mlabposition(6)) (`graphmml'), name(graph,replace) ytitle("") xlabel(`min'(1)`max') ylabel(-.1 0(0.05)`max2') title("Individuals/items representations") `draw'
+      if "`filessave'"!="" {
+         graph save graph "`saving'" , `replace'
+      }
+      pause
+   }
+}
+else if "`graph'"!=""&"`v8'"=="" {
+   di in ye "The graph option is not available with Stata 7"
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATION
+************************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+      di
+      di _col(4) "{hline 30}"
+      di _col(4) in green "Comparison of two populations"
+      di _col(4) "{hline 30}"
+      di
+      di _col(4) in green "`comp'==`mincomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmin' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmin' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmin'
+      di _col(4) in green "`comp'==`maxcomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmax' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmax' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmax'
+      di                                                                       _col(33) in green "Z= " _col(35) in yellow %8.4f `Zcomp' _col(47) in green "pvalue= "    _col(57) in yellow %6.4f `pvalue'
+}
+
+/***********************************************************************************************************
+TEST DIF
+************************************************************************************************************/
+
+if "`method'"=="cml"&"`dif'"!=""&"`test'"!="NONE" {
+   if "`trace'"!="" {
+      di in green "*** Tests of DIF"
+   }
+   local ssll=0
+   tempname DIFfile
+   qui save "`DIFfile'", replace
+   qui use "`saveraschtest'",replace
+   qui keep if `touse'==1
+   unab list:`dif'
+   local nbdif:word count `list'
+   tempname DIF
+   matrix define `DIF'=J(`nbdif',4,0)
+   local count=1
+   di
+   di _col(4) in green "{hline 45}"
+   di _col(4) in green "Test of Differential Item Functioning (DIF)"
+   di _col(4) in green "{hline 45}"
+   foreach j in `list' {
+      qui inspect `j'
+      local nbdif=r(N_unique)
+      qui su `j'
+      local maxdif=r(max)
+      if `nbdif'>10&`maxdif'<=10 {
+         di in ye "The {hi:dif} option is available with variables containing 10 or less modalities (coded from 0 or 1 to k<10)."
+         di in ye "The variable `j' (`nbdif' modalities) is omitted."
+      }
+      else {
+         local ssll=0
+         forvalues i=0/10 {
+            qui count if `j'==`i'
+            local effdif=r(N)
+            if `effdif'>0 {
+               qui raschtestv7 `varlist' if `j'==`i', test(NONE)
+               local ll`i'=r(cll)
+               local ssll=`ssll'+(`ll`i'')
+            }
+         }
+         local Z=2*`ssll'-2*`ll'
+         local ddl=(`nbdif'-1)*(`nbitems'-1)
+         matrix define `DIF'[`count',1]=(`count',`Z',`ddl',1-chi2(`ddl',`Z'))
+         di
+         di _col(4) in green "Variable:" in ye " `j' " in green "   Number of groups: "  in ye "`nbdif'"
+         di _col(4) in green "LR Test Z=" in ye %8.3f `Z' in gr "   ddl=" in ye %4.0f `ddl' in gr "    p-value=" in ye %6.4f `=1-chi2(`ddl',`Z')'
+         di
+      }
+      local ++count
+   }
+   use "`DIFfile'",replace
+}
+
+/***********************************************************************************************************
+RETURN
+************************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Returns"
+}
+local colnametheta
+
+forvalues i=0/`nbgroups' {
+         local colnametheta `colnametheta' score_`i'
+}
+
+
+return clear
+
+if `nbitems'>=3&"`test'"!="NONE" {
+        matrix colnames `globalfit'=`namewp' df p
+	matrix rownames `globalfit'=`method'
+	matrix rownames `itemfit'=`varlist'
+        matrix roweq `itemfit'=`method'
+
+	if "`method'"=="cml" {
+                matrix colnames `itemfit'=`namewp' df p outfit infit U
+		matrix rownames `AndersenZ'=`method'
+		matrix colnames `AndersenZ'=Z df p
+		return matrix AndersenZ=`AndersenZ'
+                if "`dif'"!="" {
+		   matrix rownames `DIF'=`list'
+		   matrix colnames `DIF'=num Z df p
+		   return matrix DIF=`DIF'
+                }
+	}
+	else {
+                matrix colnames `itemfit'=`namewp' df p outfit infit
+	}
+	return matrix itemFit=`itemfit'
+	return matrix globalFit=`globalfit'
+}
+
+matrix colnames `theta'=`colnametheta'
+matrix rownames `theta'=theta
+return matrix theta `theta'
+matrix colnames `sdtheta'=`colnametheta'
+matrix rownames `sdtheta'=`colnametheta'
+return matrix Vartheta `sdtheta'
+local varlist2
+matrix coleq `beta'=`method'
+matrix coleq `Vbeta'=`method'
+matrix roweq `Vbeta'=`method'
+if "`method'"=="cml" {
+	forvalues i=1/`=`nbitems'-1' {
+		local varlist2 `varlist2' ``i''
+	}
+        return scalar cll=`ll'
+        return scalar ll=`globalll'
+	local AIC=-2*`globalll'+2*(`nbitems'-1)
+}
+else {
+        return scalar ll=`ll'
+	local varlist2 `varlist'
+	return scalar sigma=`sig'
+	return scalar sesigma=`sesig'
+	local AIC=-2*`ll'+2*(`nbitems'+1)
+}
+
+if "`comp'"!="" {
+   return scalar Zcomp=`Zcomp'
+   return scalar pZcomp=`pvalue'
+}
+
+matrix colnames `beta'=`varlist2'
+matrix rownames `beta'=beta
+return matrix beta `beta'
+
+matrix colnames `Vbeta'=`varlist2'
+matrix rownames `Vbeta'=`varlist2'
+return matrix Varbeta `Vbeta'
+
+return scalar AIC=`AIC'
+return scalar N=`nbind'
+
+if "`pause'"!="" {
+   pause off
+}
+
+drop _all
+
+restore,not
+use "`saveraschtest'"
+
+/***********************************************************************************************************
+CREATE EVENTUAL NEW VARIABLES
+************************************************************************************************************/
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+        tempname genlt2 genscore2 outfit2 infit2
+        qui gen `score'=0 `if'
+        forvalues i=1/`nbitems' {
+           qui replace `score'=`score'+``i'' `if'
+        }
+        qui gen `genlt2'=. `if'
+        forvalues i=0/`nbitems' {
+           qui replace `genlt2'=`theta`i'' `if'&`score'==`i'
+        }
+        if "`genscore'"!="" {
+           qui gen `genscore'=`score' `if'
+        }
+        if "`genlt'"!="" {
+           qui gen `genlt'=`genlt2' `if'
+        }
+        if "`genfit'"!="" {
+           local outfit:word 1 of `genfit'
+           local infit:word 2 of `genfit'
+           qui gen `outfit'=0 `if'
+           qui gen `infit'=0  `if'
+           tempname infit1 infit2
+           qui gen `infit1'=0 `if'
+           qui gen `infit2'=0 `if'
+           forvalues j=1/`nbitems' {
+               tempname pi`j'
+               qui gen `pi`j''=exp(`genlt2'-`beta`j'')/(1+exp(`genlt2'-`beta`j'')) `if'
+               qui replace `pi`j''=0  `if'
+               forvalues s=1/`nbitems' {
+                  qui replace `pi`j''=`Pi'[`j',`s'] `if'&`score'==`s'
+               }
+               qui gen `outfit'``j''=(``j''-`pi`j'')^2/(`pi`j''*(1-`pi`j'')) `if'
+               qui replace `infit1'=`infit1'+(``j''-`pi`j'')^2  `if'
+               qui replace `infit2'=`infit2'+(`pi`j''*(1-`pi`j'')) `if'
+               qui replace `outfit'=`outfit'+`outfit'``j''/`nbitems' `if'
+           }
+           qui replace `infit'=`infit1'/`infit2'  `if'
+        }
+}
+
+if "`trace'"!=""|"`time'"!="" {
+    capture qui elapse `st'
+    di in green "** Time : " in yellow "$S_elap " in green "seconds"
+}
+end
diff --git a/Modules/ado/personal/r/old/raschtestv782.ado b/Modules/ado/personal/r/old/raschtestv782.ado
new file mode 100644
index 0000000..e6baeb9
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschtestv782.ado
@@ -0,0 +1,2157 @@
+*! version 8  24june2009
+*! Jean-Benoit Hardouin
+*************************************************************************************************************
+* Raschtestv7: Rasch model, fit tests and graphical representations
+* Corresponds to the version 8 of Raschtest (http://freeirt.org) for Stata7
+*
+* Historic:
+* Version 2.1 (2003-07-10): Jean-Benoit Hardouin
+* Version 3.1 (2004-01-02) : Jean-Benoit Hardouin
+* Version 7.1 (2005-03-30) : Jean-Benoit Hardouin
+* Version 7.2.1 (2005-05-21) : Jean-Benoit Hardouin
+* Version 7.3.1 (2005-07-02) : Jean-Benoit Hardouin
+* Version 7.3.2 (2005-10-05) : Jean-Benoit Hardouin /*correction for the *genlt* option with *method(cml)**/
+* Version 7.3.3 (2005-12-21) : Jean-Benoit Hardouin /*correction if scores are not represented with method(mml) or method(gee)*/
+* Version 7.4.1 (2006-01-17) : Jean-Benoit Hardouin /*Standardized OUTFIT and INFIT, DIF option*/
+* Version 7.4.2 (2006-03-21) : Jean-Benoit Hardouin /*Avoids a bug when the temporary files are saved in a directory containing special characters*/
+* Version 7.4.3 (2006-11-15) : Jean-Benoit Hardouin /*Avoids a bug when the directory defined in the dirsave option contains special characters*/
+* Version 7.5.1 (2007-04-20) : Jean-Benoit Hardouin /*Return results of the comp option*/
+* Version 7.6.1 (2008-06-26) : Jean-Benoit Hardouin /*Nold option, corrects a bug with the genlt option*/
+* Version 7.6.2 (2009-03-01) : Jean-Benoit Hardouin /*Correction of the SE of the latent trait, graph option, correction of a bug with the if option, PSI in MML*/
+* Version 8.1 (2009-06-24) : Jean-Benoit Hardouin /*DIFFICULTIES option, COVARIATES option*/
+*
+* Needed modules :
+* gammasym version 2.2 (http://www.freeirt.org)
+* gausshermite version 1 (http://www.freeirt.org)
+* geekel2d version 4.3 (http://www.freeirt.org)
+* genscore version 1.4 (http://www.freeirt.org)
+* ghquadm (findit ghquadm)
+* gllamm version 2.3.14 (ssc describe gllamm)
+* gllapred version  2.3.7 (ssc describe gllapred)
+* elapse (ssc describe elapse)
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2003-2009 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+DEFINITION / SYNTAX
+***********************************************************************************************************/
+
+
+program define raschtestv7,rclass
+syntax varlist(min=1 numeric) [if] [in] , ID(varname) [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph v8 COMp(varname) dif(varlist) time TRace Details  nold iterate(int 200) DIFFiculties(string) COVariates(string) DIF2(string)]
+
+local covariables `covariates'
+
+if "`if'"=="" {
+   local if "if 1"
+}
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Tests of conformity"
+}
+if "`v8'"=="" {
+        version 7.0
+}
+else {
+        version 8.0
+}
+
+local st = "$S_TIME"
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+if "`covariables'"!="" {
+   tokenize "`covariables'",parse(" ,")
+   local i=1
+   local tcovariables
+   while "``i''"!=","&"``i''"!="" {
+     local covariable`i' ``i''
+     local tcovariables `tcovariables' ``i''
+     local ++i
+   }
+   local nbcovariables=`i'-1
+   local ss1
+   local ss3
+   if "``i''"=="," {
+      forvalues j=`=`i'+1'/`=`i'+2' {
+         if "``j''"=="ss1" {
+            local ss1 ss1
+         }
+         else if "``j''"=="ss3" {
+            local ss3 ss3
+         }
+         else if "``j''"=="" {
+*            di in green "option `j' vide"
+         }
+         else {
+            di in red "Invalid option in the {hi:covariables} option"
+            error 198
+         }
+      }
+      local i=`i'+3
+      if "``i''"!="" {
+         di in red "There is too much options in the {hi:covariates} option."
+         error 198
+      }
+   }
+   local covariables `tcovariables'
+}
+else {
+   local nbcovariables=0
+}
+
+isid `id'
+tokenize `varlist'
+
+local bad
+forvalues i=1/`nbitems' {
+   qui count if ``i''!=0&``i''!=1&``i''!=.
+   local N=r(N)
+   if `N'>0 {
+      local bad `bad' ``i''
+   }
+}
+if "`bad'"!="" {
+   di in red "The item(s) {hi:`bad'} is(are) not binary item(s) (with responses 0 or 1)."
+   exit
+}
+
+
+
+if "`method'"=="" {
+    local method cml
+}
+if "`test'"=="" {
+    local test R
+}
+local method=lower("`method'")
+local test=upper("`test'")
+if "`method'"!="mml"&"`method'"!="cml"&"`method'"!="gee"&"`method'"!="pce" {
+    di in red "Uncorrect {hi:method} option."
+    error 198
+    exit
+}
+
+if "`test'"!="R"&"`test'"!="Q"&"`test'"!="WP"&"`test'"!="NONE" {
+   di in red "Uncorrect test option."
+   error 198
+   exit
+}
+
+if "`genfit'"!="" {
+   local nbwordgenfit:word count `genfit'
+   if `nbwordgenfit'!=2 {
+      di in red "Uncorrect genfit option."
+      di in red "This option must contain exactly two words"
+      error 198
+      exit
+   }
+}
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+   capture confirm new variable `genfit' `genscore'
+   if "`genfit'"!="" {
+      local o:word 1 of `genfit'
+      forvalues i=1/`nbitems' {
+         confirm new variable `o'``i''
+      }
+   }
+   if "`genlt'"!="" {
+       local 0 `genlt'
+       gettoken left  0: 0,parse(",")
+       gettoken right  0: 0,parse(",")
+       local genlt `left'
+       local replacegenlt `0'
+       local length=length("`replacegenlt'")
+       if `length'>=3&substr("`replacegenlt'",1,`length')==substr("replace",1,`length') {
+          local replacegenlt replace
+       }
+       if "`replacegenlt'"!="replace"&"`replacegenlt'"!="" {
+           di "Not allowed option in the {hi:genlt} option"
+           error 198
+       }
+       else if "`replacegenlt'"=="" {
+           confirm new variable `genlt'
+       }
+   }
+}
+
+preserve
+
+tempfile saveraschtest
+qui save `saveraschtest'
+qui keep if `touse'==1
+
+if "`method'"=="pce" {
+*set trace on
+*set tracedepth 1
+   raschpce `varlist'
+   exit
+}
+
+
+if "`autogroup'"!=""&"`group'"!="" {
+   di in green "The autogroup and the group options cannot be defined in the same time"
+   di in green "Only the group option is retained."
+   local autogroup
+}
+
+if "`autogroup'"!="" {
+   tempvar autoscore
+   qui genscore `varlist',score(`autoscore')
+
+   tempname matscore tmp
+   matrix `matscore'=J(`=`nbitems'-1',3,0)
+   forvalues i=1/`=`nbitems'-1' {
+        matrix `matscore'[`i',1]=`i'
+        matrix `matscore'[`i',2]=`i'
+        qui count if `autoscore'==`i'
+        matrix `matscore'[`i',3]=r(N)
+   }
+   local stop=0
+   local j=0
+   while `j'<=`=`nbitems'-3'&`stop'!=1 {
+      local j=`j'+1
+      local scoretogroup=99999999
+      local rowtogroup1=0
+      local rowtogroup2=0
+      local stop=1
+      forvalues i=1/`=`nbitems'-`j'' {
+         if `matscore'[`i',1]>=0 & `matscore'[`i',3]<30 & `matscore'[`i',3]<`scoretogroup' {
+            local scoretogroup=`matscore'[`i',3]
+            local rowtogroup1=`i'
+            local stop=0
+         }
+      }
+      if `stop'!=1 {
+         if `rowtogroup1'>1&`rowtogroup1'<`=`nbitems'-`j'' {
+            if `matscore'[`=`rowtogroup1'-1',1]<`matscore'[`=`rowtogroup1'+1',1] {
+               local rowtogroup2=`rowtogroup1'
+               local rowtogroup1=`rowtogroup1'-1
+            }
+            else {
+               local rowtogroup2=`rowtogroup1'+1
+            }
+         }
+         else if `rowtogroup1'==1 {
+            local rowtogroup2=2
+         }
+         else if `rowtogroup1'==`=`nbitems'-`j'' {
+            local rowtogroup2=`nbitems'-`j'
+            local rowtogroup1=`nbitems'-`j'-1
+         }
+         matrix `tmp'=`matscore'
+         matrix `matscore'=J(`=`nbitems'-`j'',3,0)
+         if `rowtogroup1'!=1 {
+            matrix `matscore'[1,1]=`tmp'[1..`=`rowtogroup1'-1',1..3]
+         }
+         matrix `matscore'[`rowtogroup1',1]=`tmp'[`rowtogroup1',1]
+         matrix `matscore'[`rowtogroup1',2]=`tmp'[`rowtogroup2',2]
+         matrix `matscore'[`rowtogroup1',3]=`tmp'[`rowtogroup1',3]+`tmp'[`rowtogroup2',3]
+         if `rowtogroup2'!=`=`nbitems'-`j'' {
+            matrix `matscore'[`rowtogroup2',1]=`tmp'[`=`rowtogroup2'+1'..`=`nbitems'-`j'',1..3]
+         }
+      }
+   }
+   local nbrows=rowsof(`matscore')-1
+   local thresholds
+   forvalues i=1/`nbrows' {
+      local tmp=`matscore'[`i',2]
+      local thresholds `thresholds' `tmp'
+   }
+   local group `thresholds'
+}
+
+
+if "`group'"=="" {
+	forvalues i=1/`=`nbitems'-1' {
+		local group "`group' `i'"
+	}
+}
+local nbgroups:word count `group'
+local groupmax:word `nbgroups' of `group'
+if `groupmax'>=`nbitems' {
+	di in red "You cannot form a group with the higher possible score."
+	di in red "The higher possible value of the group option is `=`nbitems'-1'."
+        di in red "Please correct your group option."
+	error 198
+        exit
+}
+else {
+	if `groupmax'!=`=`nbitems'-1' {
+		local group "`group' `=`nbitems'-1'"
+		local nbgroups=`nbgroups'+1
+	}
+}
+local nbgroups=`nbgroups'+1
+
+if "`dirsave'"!=""&"`filessave'"=="" {
+        di in ye "If you want to save yours graphs, use the filessave option"
+}
+if "`filessave'"!="" {
+        if "`dirsave'"=="" {
+              local dirsave "`c(pwd)'"
+        }
+        di in ye "The graphs files will be saved in `dirsave'"
+}
+if "`dirsave'"!="" {
+        if "`filesave'"=="" {
+              local filesave "filesave"
+        }
+}
+
+
+if "`pause'"!=""&"`draw'"=="" {
+     pause on
+}
+
+if "`difficulties'"!="" {
+    capture confirm matrix `difficulties'
+    if _rc!=0  {
+	di in red "The vector `difficulties' defined in the {hi:difficulties} option does not exist."
+	error 198
+        exit
+    }
+}
+
+if "`difficulties'"!=""&"`method'"!="mml" {
+   di in red "The {hi:difficulties} option can be defined only for MML method."
+   error 198
+   exit
+}
+
+if "`covariables'"!=""&"`method'"!="mml" {
+   di in red "The {hi:covariables} option can be defined only for MML method."
+   error 198
+   exit
+}
+if "`covariables'"!=""&"`comp'"!="" {
+   di in red "The {hi:covariables} and {hi:comp} options can be defined jointly."
+   error 198
+   exit
+}
+
+
+
+
+
+/***********************************************************************************************************
+POSSIBLE TEST
+***********************************************************************************************************/
+
+if ("`icc'"!=""|"`fitgraph'"!=""|"`splittest'"!=""|"`details'"!="")&"`test'"=="NONE" {
+	di in green "You cannot use the {hi:details}, {hi:icc}, {hi:fitgraph} or {hi:splittest} options if you use {hi:test(none)}."
+        di in green "These options are ignored."
+	local details
+	local icc
+	local fitgraph
+	local splittest
+}
+if "`comp'"!=""&"`method'"=="cml" {
+   	di in green "You cannot compare two populations ({hi:comp} option) with the CML estimation method"
+   	di in green "This option is ignored."
+        local comp
+}
+if "`method'"!="cml"&"`test'"=="WP" {
+	di in green "The Wright-Panchapakesan test is not authorized with MML or GEE."
+	di in green "The WP tests are replaced by Van den Wollenberg Q tests."
+        local test Q
+}
+if "`method'"=="gee"&"`ld'"!="" {
+	di in green "You cannot use the {hi:nold} option with the GEE method of estimation"
+	di in green "This option is ignored."
+        local ld
+}
+
+
+if "`test'"==""|"`test'"=="R" {
+   local test "R"
+   if "`method'"=="cml" {
+      local namewp "R1c"
+      local descwp "R1c test"
+   }
+   else {
+      local namewp="R1m"
+      local descwp "R1m test"
+   }
+}
+if `nbitems'>999999|"`test'"=="WP" {
+	local namewp "  Y"
+	local descwp "Wright-Panchapakesan Y test"
+	local q2
+}
+ else if "`test'"=="Q" {
+	local namewp " Q1"
+	local descwp "Van den Wollenberg Q1 test"
+}
+
+if "`method'"!="cml"&"`meandiff'"!="" {
+	di in green "The {hi:meandiff} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local meandiff
+}
+
+if "`method'"!="cml"&"`splittests'"!="" {
+	di in green "The {hi:splittests} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local splittests
+}
+if "`method'"!="cml"&"`dif'"!="" {
+	di in green "The {hi:dif} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local dif
+}
+
+/***********************************************************************************************************
+SCORES AND GROUPS
+************************************************************************************************************/
+
+qui count if `touse'==1
+local N=r(N)
+
+qui keep `varlist' `comp' `covariables' `id' `touse'
+
+tempname rep item
+tempvar score realscore
+qui genscore `varlist',score(`score')
+qui count if `score'==.&`touse'==1
+local nbindmiss=r(N)
+
+if "`ld'"=="" {
+   qui drop if `score'==.
+}
+forvalues i=1/`nbitems' {
+	rename ``i'' `rep'`i'
+}
+
+
+
+local liminf0=0
+local limsup0=0
+local liminf`nbgroups'=`nbitems'
+local limsup`nbgroups'=`nbitems'
+
+
+local recode
+forvalues i=1/`=`nbgroups'-1' {
+	if `i'!= 1{
+		local liminf`i' : word `=`i'-1' of `group'
+	}
+	else {
+		local liminf1=0
+	}
+	local liminf`i'=`liminf`i''+1
+	local limsup`i':word `i' of `group'
+
+	local recode "`recode' `liminf`i''/`limsup`i''=`i'"
+}
+qui gen `realscore'=`score'
+qui recode `score' `recode' `nbitems'=`nbgroups'
+
+local smallgroup=0
+
+forvalues i=0/`nbgroups' {
+	qui count if `score'==`i'
+	local effscore`i'=r(N)
+	if `i'!=0&`i'!=`nbgroups'&`effscore`i''<30 {
+		local smallgroup=1
+	}
+}
+/***********************************************************************************************************
+ESTIMATION OF THE DIFFICULTY PARAMETERS
+************************************************************************************************************/
+if "`trace'"!="" {
+  di in green "*** Estimation of the difficulty parameters"
+}
+
+
+if "`covariables'"!="" {
+  forvalues i=1/`nbcovariables' {
+     qui su `covariable`i''
+     local mean`covariable`i''=r(mean)
+     qui replace `covariable`i''=`covariable`i''-`mean`covariable`i'''
+  }
+}
+
+tempname ll coef var beta Vbeta est
+
+if "`method'"=="gee" {
+   qui geekel2d `rep'1-`rep'`nbitems',ll
+   if `r(error)'==1 {
+       di "The variance of the latent trait probably is too high to made the GEE a efficient method to estimate the parameters."
+       error 499
+       exit
+   }
+   scalar `ll'=r(ll)
+   local nbind=r(N)
+   matrix `coef'=r(b)
+   matrix `est'=`coef'
+   matrix `est'[1,`=`nbitems'+1']=sqrt(`est'[1,`=`nbitems'+1'])
+   matrix `var'=r(V)
+   matrix `beta'=`coef'[1,1..`nbitems']
+   matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+   local sig=sqrt(`coef'[1,`=`nbitems'+1'])
+   local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])/sqrt(`nbind')/(`sig'*2)
+}
+
+qui reshape long `rep', i(`id') j(`item')
+
+tempvar diff tl
+gen `diff'=0
+
+forvalues i=1/`nbitems' {
+	qui gen `rep'`i'=`item'==`i'
+	qui replace `rep'`i'=-`rep'`i'
+}
+local nbinteractions=0
+if "`dif2'"!="" {
+   local interactions
+   local listinteractions
+   forvalues i=1/`nbcovariables' {
+      forvalues j=1/`nbitems' {
+         if `dif2'[`i',`j']==1 {
+            gen int`nbinteractions'=-`rep'`j'*`covariable`i''
+            qui su int`nbinteractions'
+            *replace int`nbinteractions'=int`nbinteractions'-`r(mean)'
+            local interactions `interactions' int`nbinteractions'
+            local listinteractions `listinteractions' ``j''*`covariable`i''
+            local ++nbinteractions
+         }
+      }
+   }
+}
+
+*       set trace on
+if "`method'"=="mml" {
+   if "`difficulties'"==""{
+      *di "xtlogit `rep' `rep'1-`rep'`nbitems' `covariables' `interactions', i(`id') nocons iterate(`iterate')"
+      *list in 1/10
+      *dshqkjf
+      xtlogit `rep' `rep'1-`rep'`nbitems' `covariables' `interactions', i(`id') nocons iterate(`iterate')
+      matrix `est'=e(b)
+      matrix `est'[1,`=`nbitems'+`nbcovariables'+`nbinteractions'+1']=exp(`est'[1,`=`nbitems'+`nbcovariables'+`nbinteractions'+1']/2)
+   }
+   else {
+      tempname offset b
+      qui gen `offset'=0
+      forvalues i=1/`nbitems' {
+          qui replace `offset'=-(`difficulties'[1,`i']) if `item'==`i'
+      }
+      qui gllamm `rep' `covariables'  `interactions', offset(`offset') i(`id') nocons iterate(`iterate') link(logit) fam(bin)
+      matrix `b'=e(b)
+      matrix `est'=`difficulties',`b'
+      matrix `est'[1,`=`nbitems'+`nbcovariables'+`nbinteractions'+1']=exp(`b'[1,`=`nbcovariables'+`nbinteractions'+1']/2)
+   }
+}
+else if "`method'"=="cml" {
+	qui clogit `rep' `rep'1-`rep'`=`nbitems'-1' , group(`id')
+}
+
+
+if "`method'"!="gee" {
+   if "`difficulties'"=="" {
+      matrix `coef'=e(b)
+      matrix `var'=e(V)
+   }
+   else {
+      matrix `coef'=`difficulties'
+      matrix `var'=J(`=`nbitems'+`nbcovariables'+`nbinteractions'+1',`=`nbitems'+`nbcovariables'+`nbinteractions'+1',.)
+      matrix `var'[`=`nbitems'/*+`nbcovariables'+`nbinteractions'*/+1',`=`nbitems'/*+`nbcovariables'+`nbinteractions'*/+1']=e(V)
+   }
+   scalar `ll'=e(ll)
+   local nbind=e(N)/`nbitems'
+
+
+   if "`meandiff'"!="" {
+      matrix `var'=J(`nbitems',`nbitems',.)
+      matrix `coef'=J(1,`nbitems',.)
+      local param
+      local lin `rep'1
+      forvalues j=2/`=`nbitems'-1' {
+         local lin `lin'+`rep'`j'
+      }
+      local lin (`lin')/`nbitems'
+
+      forvalues j=1/`=`nbitems'-1' {
+         qui lincom `rep'`j'-`lin'
+         matrix `coef'[1,`j']=`r(estimate)'
+         matrix `var'[`j',`j']=`r(se)'^2
+      }
+      qui lincom -`lin'
+      matrix `coef'[1,`nbitems']=`r(estimate)'
+      matrix `var'[`nbitems',`nbitems']=`r(se)'^2
+   }
+   if "`method'"=="mml" {
+	local sig=e(sigma_u)
+	local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+`nbinteractions'+1',`=`nbitems'+`nbinteractions'+`nbcovariables'+1'])*`sig'/2
+        tempname betacov Vbetacov
+	if "`difficulties'"=="" {
+           matrix `beta'=`coef'[1,1..`nbitems']
+           matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+           if "`covariables'"!="" {
+              matrix `betacov'=`coef'[1,`=`nbitems'+1'..`=`nbitems'+`nbcovariables'+`nbinteractions'']
+              matrix `Vbetacov'=`var'[`=`nbitems'+1'..`=`nbitems'+`nbcovariables'+`nbinteractions'',`=`nbitems'+1'..`=`nbitems'+`nbcovariables'+`nbinteractions'']
+           }
+           local sig=e(sigma_u)
+	   local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+`nbinteractions'+1',`=`nbitems'+`nbcovariables'+`nbinteractions'+1'])*`sig'/2
+	}
+	else {
+	   tempname tmp
+	   matrix `tmp'=e(b)
+           matrix `beta'=`difficulties'
+           if "`covariables'"!="" {
+              matrix `betacov'=`tmp'[1,1..`=`nbcovariables'+`nbinteractions'']
+           }
+           local sig=`tmp'[1,`=`nbcovariables'+1']
+           matrix `tmp'=e(V)
+	   local sesig=sqrt(`tmp'[`=`nbcovariables'+`nbinteractions'+1',`=`nbcovariables'+`nbinteractions'+1'])
+           matrix `Vbeta'=J(`nbitems',`nbitems',.)
+           if "`covariables'"!="" {
+              matrix `Vbetacov'=`tmp'[1..`=`nbcovariables'+`nbinteractions'',1..`=`nbcovariables'+`nbinteractions'']
+           }
+	}
+   }
+   else if "`method'"=="cml"&"`meandiff'"==""{
+	matrix `beta'=`coef'[1,1..`=`nbitems'-1']
+	matrix `Vbeta'=`var'[1..`=`nbitems'-1',1..`=`nbitems'-1']
+   }
+   else if "`method'"=="cml"&"`meandiff'"!=""{
+	matrix `beta'=`coef'
+	matrix `Vbeta'=`var'
+   }
+}
+
+if ("`method'"=="mml"|"`method'"=="gee") {
+   local colnames
+   forvalues i=1/`nbitems' {
+      local colnames "`colnames' `rep':`rep'`i'"
+   }
+   forvalues i=1/`nbcovariables'{
+      local tmp:word `i' of `covariables'
+      local colnames "`colnames' `rep':`tmp'"
+   }
+   forvalues i=1/`nbinteractions'{
+      local tmp:word `i' of `interactionss'
+      local colnames "`colnames' `rep':`tmp'"
+   }
+
+   local id2=substr("`id'",1,4)
+   local colnames "`colnames' `id2'1:_cons"
+   matrix colnames `est'=`colnames'
+
+   qui gllamm `rep' `rep'1-`rep'`nbitems' `covariables' `interactions', i(`id') allc nocons family(binom) link(logit) trace from(`est') eval
+   tempname u
+   qui gllapred `u',u fsample
+
+   forvalues i=1/`nbcovariables' {
+      local tmp:word `i' of `covariables'
+      qui replace `u'm1=`u'm1+`betacov'[1,`i']*(`tmp')/*+`mean`covariable`i''')*/
+   }
+   tempname theta sdtheta
+   matrix `theta'=J(1,`=`nbitems'+1',0)
+   matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',0)
+   qui su `u'm1 if `rep'1==-1
+   local vartheta=r(Var)
+   qui gen `u's2=`u's1^2
+   qui su `u's2 if `rep'1==-1
+   local meanse2=r(mean)
+   local psi=1-`meanse2'/(`meanse2'+`vartheta')
+   forvalues s=0/`nbitems' {
+      qui su `u'm1 if `realscore'==`s'
+      local theta`s'=r(mean)
+      qui su `u's1 if `realscore'==`s'
+      local sdtheta`s'=r(mean)
+      matrix `theta'[1,`=`s'+1']=`theta`s''
+      matrix `sdtheta'[`=`s'+1',`=`s'+1']=`sdtheta`s''
+   }
+   if "`genlt'"!="" {
+      tempfile ltsave ltsavetmp
+      qui save `ltsavetmp', replace
+      qui keep if `rep'1==-1
+      qui keep `u'm1 `u's1 `id'
+      qui sort `id'
+      qui save `ltsave'
+      qui use `ltsavetmp'
+   }
+}
+
+forvalues i=1/`nbitems' {
+	if `i'==`nbitems'&"`method'"=="cml"&"`meandiff'"=="" {
+		local beta`i'=0
+		local sd`i' .
+		local fixed`i' "*"
+	}
+	else {
+		local beta`i'=`coef'[1,`i']
+		local sd`i'=sqrt(`var'[`i',`i'])
+	}
+	qui replace `diff'=-`beta`i'' if `item'==`i'
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATIONS
+***********************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+   if "`trace'"!="" {
+     di in green "*** Test of comparison of two populations"
+   }
+         qui inspect `comp'
+         local unique=r(N_unique)
+         if `unique'== 2 {
+		qui su `comp'
+		local mincomp=r(min)
+		local maxcomp=r(max)
+	    	tempname bmin bmax
+	    	qui xtlogit `rep' if `comp'==`mincomp',offset(`diff') i(`id')
+	    	matrix `bmin'=e(b)
+	    	local meanmin=`bmin'[1,1]
+	    	local varmin=e(sigma_u)^2
+	    	local llmin=e(ll)
+	    	local Nmin=e(N_g)
+	    	qui xtlogit `rep' if `comp'==`maxcomp',offset(`diff') i(`id')
+	    	matrix `bmax'=e(b)
+	    	local meanmax=`bmax'[1,1]
+	    	local varmax=e(sigma_u)^2
+	    	local llmax=e(ll)
+	    	local Nmax=e(N_g)
+	    	local Zcomp=(`meanmin'-`meanmax')/sqrt(`varmin'/`Nmin'+`varmax'/`Nmax')
+		local pvalue=1-norm(abs(`Zcomp'))
+	 }
+	 else {
+	        di "It is impossible to compare more than two populations"
+	        di "The comparison process is not run"
+	        local comp
+	 }
+}
+
+/***********************************************************************************************************
+ESTIMATION OF THE ABILITY PARAMETERS  / CML
+************************************************************************************************************/
+if `nbitems'>=2 {
+   if "`trace'"!="" {
+      di in green "*** Estimation of the ability parameters"
+   }
+   if "`method'"=="cml" {
+      tempfile verytmp
+      qui save `verytmp',replace
+      drop _all
+      qui set obs 20001
+      qui gen theta=(_n-10001)/1000
+      qui gen A=1
+      forvalues j=1/`nbitems' {
+         qui gen u`j'=exp(theta-`beta`j'')
+         qui gen p`j'=u`j'/(1+u`j')
+         qui gen a`j'=1/u`j'
+         qui replace A=A*a`j'
+         qui gen i`j'=u`j'/(1+u`j')^2
+         qui gen j`j'=(u`j'*(1-u`j'))/(1+u`j')^3
+      }
+      qui egen P=rsum(p*)
+      qui egen I=rsum(i*)
+      qui egen J=rsum(j*)
+      qui gen V=1/I^2*(I+J^2)/(4*I^2)
+      qui gen V2=1/I
+      tempname theta sdtheta
+      matrix `theta'=J(1,`=`nbitems'+1',0)
+      matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',.)
+      forvalues s=0/`nbitems' {
+         qui gen f`s'=abs(`s'-P+.5*J/I)
+         qui sort f`s'
+         matrix `theta'[1,`=`s'+1']=theta[1]
+         matrix `sdtheta'[`=`s'+1',`=`s'+1']=sqrt(V2[1])
+      }
+      use "`verytmp'",replace
+   }
+   qui gen `tl'=0
+   forvalues s=0/`nbitems' {
+      local theta`s'=`theta'[1,`=`s'+1']
+      qui replace `tl'=`theta`s'' if `realscore'==`s'
+      local sdtheta`s'=`sdtheta'[`=`s'+1',`= `s'+1']
+   }
+   tempname pred
+   qui gen `pred'=log(exp(`rep'*(`tl'+`diff'))/(1+exp(`tl'+`diff')))
+
+   qui su `pred'
+   local globalll=r(sum)
+
+   local nulscore=0
+   forvalues i=0/`nbgroups' {
+      qui count if `score'==`i'&`item'==1
+      local nbscore`i'=r(N)
+      if `nbscore`i''==0 {
+         local nulscore=1
+      }
+   }
+   if `nulscore' {
+      di in green "{p}At least one group of scores concerns none individuals. Tests will be not computed.{p_end}"
+      di in green "{p}Use the {hi:group} or the {hi:autogroup} options.{p_end}"
+      local test "NONE"
+      local details
+      local icc
+      local fitgraph
+      local splittest
+   }
+   forvalues i=0/`nbitems' {
+      qui count if `realscore'==`i'&`item'==1
+      local nbrealscore`i'=r(N)
+   }
+}
+
+/***********************************************************************************************************
+TESTS OF THE FIRST ORDER
+************************************************************************************************************/
+
+tempname Pi
+matrix define `Pi'=J(`nbitems',`=`nbitems'-1',0)
+if "`test'"!="NONE" {
+   qui drop if `score'==.
+   if "`trace'"!="" {
+      di in green "*** Tests of the first order"
+   }
+   tempname Obs Obs2 Th Th2
+
+   matrix define `Obs'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Obs2'=J(`nbitems',`=`nbgroups'-1',0)
+   matrix define `Th'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Th2'=J(`nbitems',`=`nbgroups'-1',0)
+   local listofitemsc
+
+   /* Estimation of the gamma symetrical functions*/
+   local c0 "1"
+   local c`nbitems' "`nbitems'*x"
+   forvalues j=1/`nbitems' {
+      local listini`j'
+      local listofitemsc "`listofitemsc' `beta`j''"
+      local c0 `c0'*(1+exp(x-`beta`j''))
+      local c`nbitems' `c`nbitems''-`beta`j''
+      forvalues k=1/`nbitems' {
+         local listini`j'k`k'
+         if `k'!=`j' {
+            local listini`j' "`listini`j'' `beta`k''"
+         }
+         forvalues l=1/`nbitems' {
+            if `l'!=`j'&`l'!=`k' {
+               local listini`j'k`k' "`listini`j'k`k'' `beta`l''"
+            }
+         }
+      }
+   }
+
+   gammasym `listofitemsc'
+
+   /*Estimation, for each value of the score s of the probability to respond to each item (Pi) and of the theorical number of positive responses (Ths) and of theorical number of positive respond per item pair (Ws)*/
+   forvalues s=1/`nbitems' {
+      local denom`s'=r(gamma`s')
+      tempname  W`s'
+      matrix define `W`s''=J(`nbitems',`nbitems',0)
+   }
+   tempvar prob prob2 z y v z2 y2 v2 c r q e
+   qui gen `prob'=.
+   qui gen `prob2'=.
+   forvalues j=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui count if `rep'==1&`item'==`j'&`realscore'==`s'
+         matrix `Obs'[`j',`s']=r(N)
+         if "`test'"!="WP" {
+            gammasym `listini`j''
+            local num`j'=r(gamma`=`s'-1')
+            if "`method'"=="cml"|"`test'"=="Q" {
+               matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s''
+            }
+            else {
+               gausshermite exp(`s'*x)/(`c0'), sigma(`sig')
+               local int`s'=r(int)
+               if "`test'"=="R"&`nbrealscore`s''!=0{
+                  local tmp=exp(-`beta`j'')*`num`j''*`int`s''*`nbind'/`nbrealscore`s''
+                  matrix `Pi'[`j',`s']=`tmp'
+               }
+               else if `nbrealscore`s''==0 {
+                  matrix `Pi'[`j',`s']=0
+               }
+            }
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  if `s'>=2 {
+                     gammasym `listini`j'k`k''
+                     local num`j'k`k'=r(gamma`=`s'-2')
+                     if "`method'"=="cml" {
+                        matrix `W`s''[`j',`k']=`nbrealscore`s''*exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''/`denom`s''
+                     }
+                     else {
+                        matrix `W`s''[`j',`k']=exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''*`int`s''*`nbind'
+                     }
+                     matrix `W`s''[`k',`j']=`W`s''[`j',`k']
+                  }
+               }
+            }
+         }
+         else if "`test'"=="WP" {
+            matrix `Pi'[`j',`s']=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j''))
+         }
+         matrix `Th'[`j',`s']=`Pi'[`j',`s']*`nbrealscore`s''
+         qui replace `prob'=`Pi'[`j',`s'] if `realscore'==`s'&`item'==`j'
+         qui replace `prob2'=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) if `realscore'==`s'&`item'==`j'
+         matrix `W`s''[`j',`j']=`nbrealscore`s''*`Pi'[`j',`s']
+         if "`test'"!="R" {
+            matrix `W`s''[`j',`j']=`W`s''[`j',`j']*abs(1-`Pi'[`j',`s'])
+         }
+      }
+   }
+   qui gen `v2'=abs(`prob'*(1-`prob'))
+   qui gen `z2'=(`rep'-`prob')^2
+   qui gen `y2'=`z2'/`v2'
+   qui gen `c'=abs(`prob'*(1-`prob')*(`prob'^3+(1-`prob')^3))
+   qui gen `r'=`c'/(`v2')^2
+   qui gen `e'=`c'-(`v2')^2
+
+   forvalues j=1/`nbitems' {
+      qui su `y2' if `item'==`j'
+      local outfit`j'=r(mean)
+      qui su `r' if `item'==`j'
+      local Voutfit`j'=r(sum)
+      local Voutfit`j'=`Voutfit`j''/(`nbind')^2-1/`nbind'
+      local outfitstd`j'=(`outfit`j''^(1/3)-1)*(3/sqrt(`Voutfit`j''))-sqrt(`Voutfit`j'')/3
+
+      qui su `z2' if `item'==`j'
+      local n=r(sum)
+      qui su `v2' if `item'==`j'
+      local d=r(sum)
+      local infit`j'=`n'/`d'
+      qui su `e' if `item'==`j'
+      local sume=r(sum)
+      local Vinfit`j'=`sume'/(`d')^2
+      local infitstd`j'=(`infit`j''^(1/3)-1)*(3/sqrt(`Vinfit`j''))-sqrt(`Vinfit`j'')/3
+   }
+   tempname tmp stattest testitems
+
+   /*Estimation, by scores group g, of the theorical number of positive response (Th2g) and of the positive respond to each items pair (W2g)*/
+   scalar `stattest'=0
+   forvalues g=1/`=`nbgroups'-1' {
+      tempname  W2`g' d2`g'
+      matrix define `W2`g''=J(`nbitems',`nbitems',0)
+      forvalues s=`liminf`g''/`limsup`g'' {
+         forvalues j=1/`nbitems' {
+            matrix `Obs2'[`j',`g']=`Obs2'[`j',`g']+`Obs'[`j',`s']
+            matrix `Th2'[`j',`g']=`Th2'[`j',`g']+`Th'[`j',`s']
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  matrix `W2`g''[`j',`k']=`W2`g''[`j',`k']+`W`s''[`j',`k']
+                  matrix `W2`g''[`k',`j']=`W2`g''[`j',`k']
+               }
+            }
+            matrix `W2`g''[`j',`j']=`W2`g''[`j',`j']+`W`s''[`j',`j']
+         }
+      }
+
+      /*Estimation of the d2g vectors*/
+      matrix `d2`g''=`Obs2'[1..`nbitems',`g']-`Th2'[1..`nbitems',`g']
+
+      /*Estimation of the influences on the test of each item (testitemsg matrix) and of the test statistic (stattest)*/
+      tempname test`g' testitems`g'
+      matrix `test`g''=`d2`g'''*syminv(`W2`g'')*`d2`g''
+      capture matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      if _rc!=0 {
+         matrix `tmp'=J(`nbitems',`nbitems',0)
+         forvalues j=1/`nbitems' {
+            matrix `tmp'[`j',`j']=`W2`g''[`j',`j']
+         }
+         di in green "Group `g' (`liminf`g''/`limsup`g''): The weight matrix is not positive-definite, the diagonal matrix is used to estimate the contribution of the items on the `wpname' statistic"
+         matrix list `tmp'
+         matrix `testitems`g''=cholesky(syminv(`tmp'))*`d2`g''
+      }
+      else {
+         matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      }
+      scalar `stattest'=`stattest'+`test`g''[1,1]
+   }
+   matrix `testitems'=J(`nbitems',1,0)
+   forvalues j=1/`nbitems' {
+      forvalues g=1/`=`nbgroups'-1' {
+         matrix `testitems'[`j',1]=`testitems'[`j',1]+`testitems`g''[`j',1]^2
+      }
+   }
+
+   /*Adaptation for the Q1 statistic*/
+   if "`test'"=="Q" {
+      scalar `stattest'=`stattest'*`=`nbitems'-1'/`nbitems'
+   }
+
+   /*Correction for R1m and Q1m*/
+   if ("`test'"=="R"|"`test'"=="Q")&("`method'"=="mml"|"`method'"=="gee") {
+      local c`nbitems' exp(`c`nbitems'')/(`c0')
+      local c0 1/(`c0')
+      gausshermite `c0', sigma(`sig')
+      local ci0=r(int)*`nbind'
+      gausshermite `c`nbitems'',sigma(`sig')
+      local ci`nbitems'=`nbind'*r(int)
+      scalar `stattest'=`stattest'+(`nbrealscore0'-`ci0')^2/`ci0'+(`nbrealscore`nbitems''-`ci`nbitems'')^2/`ci`nbitems''
+  }
+
+
+
+/***********************************************************************************************************
+TESTS U
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests U"
+      }
+
+      local quartile=`nbind'/4
+      local c1=0
+      local n1=0
+      while `n1'<`quartile' {
+         local c1=`c1'+1
+         local n1=`n1'+`nbrealscore`c1''
+      }
+      local c2=`nbitems'
+      local n2=0
+      while `n2'<`quartile' {
+         local c2=`c2'-1
+         local n2=`n2'+`nbrealscore`c2''
+      }
+      forvalues j=1/`nbitems' {
+         local zu1=0
+         local zu2=0
+         forvalues s=1/`c1' {
+            local zu1=`zu1'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         forvalues s=`c2'/`=`nbitems'-1' {
+            local zu2=`zu2'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         local U`j'=(`zu1'-`zu2')/sqrt(`c1'+`nbitems'-`c2')
+      }
+   }
+
+
+
+/***********************************************************************************************************
+TESTS OF THE SECOND ORDER /*undocumented in beta test*/
+************************************************************************************************************/
+
+   if "`q2'"!="" {
+      if "`trace'"!="" {
+         di in green "*** Tests of the second order"
+      }
+
+      tempfile Q2file
+      qui save "`Q2file'",replace
+      qui use "`saveraschtest'",replace
+
+      qui keep if `touse'==1
+      gen `score'=0
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'
+	 rename ``i'' `rep'`i'
+	 qui replace `score'=`score'+`rep'`i'
+      }
+      qui recode `score' `recode'
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'=0
+         forvalues j=`=`i'+1'/`nbitems' {
+	    local listinci`i'j`j'
+	    forvalues k=1/`nbitems' {
+	       if `k'!=`i'&`k'!=`j' {
+	          local listinci`i'j`j' "`listinci`i'j`j'' `beta`k''"
+	       }
+	    }
+	 }
+      }
+
+      local Q2tot=0
+      forvalues k=2/`=`nbitems'-1' {
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`i'+1'/`nbitems' {
+	       if `k'==1 {
+	          local num=0
+               }
+	       else {
+	          gammasym `listinci`i'j`j''
+                  local num=r(gamma`=`k'-2')
+               }
+	       local athi`i'j`j'k`k'=exp(-`beta`i'')*exp(-`beta`j'')*`num'/`denom`k''
+	       local bthi`i'j`j'k`k'=`nbth`i's`k''-`athi`i'j`j'k`k''
+	       local cthi`i'j`j'k`k'=`nbth`j's`k''-`athi`i'j`j'k`k''
+	       local dthi`i'j`j'k`k'=1-`athi`i'j`j'k`k''-`bthi`i'j`j'k`k''-`cthi`i'j`j'k`k''
+            }
+         }
+      }
+      forvalues k=1/`=`nbgroups'-1' {
+         local Q2`k'=0
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`j'+1'/`nbitems' {
+	       qui count if  `rep'`i'==1&`rep'`j'==1&`score'==`k'
+	       local aempi`i'j`j'k`k'=r(N)
+	       local ath2i`i'j`j'k`k'=0
+	       local bth2i`i'j`j'k`k'=0
+	       local cth2i`i'j`j'k`k'=0
+	       local dth2i`i'j`j'k`k'=0
+	    }
+	 }
+         if `limsup`k''!=1 {
+            forvalues l=`liminf`k''/`limsup`k'' {
+	       forvalues i=1/`=`nbitems'-1' {
+	          forvalues j=`=`i'+1'/`nbitems' {
+		     if `l'!=1 {
+		        local ath2i`i'j`j'k`k'=`ath2i`i'j`j'k`k''+`athi`i'j`j'k`l''*`nbrealscore`l''
+			local bth2i`i'j`j'k`k'=`bth2i`i'j`j'k`k''+`bthi`i'j`j'k`l''*`nbrealscore`l''
+			local cth2i`i'j`j'k`k'=`cth2i`i'j`j'k`k''+`cthi`i'j`j'k`l''*`nbrealscore`l''
+			local dth2i`i'j`j'k`k'=`dth2i`i'j`j'k`k''+`dthi`i'j`j'k`l''*`nbrealscore`l''
+                     }
+		  }
+               }
+            }
+	    forvalues i=1/`=`nbitems'-1' {
+	       forvalues j=`=`i'+1'/`nbitems' {
+	          local d2i`i'j`j'k`k'=(`aempi`i'j`j'k`k''-`ath2i`i'j`j'k`k'')^2
+		  local Q2i`i'j`j'k`k'=`d2i`i'j`j'k`k''/`ath2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`bth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`cth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`dth2i`i'j`j'k`k''
+		  local Q2i`i'=`Q2i`i''+`Q2i`i'j`j'k`k''
+		  local Q2i`j'=`Q2i`j''+`Q2i`i'j`j'k`k''
+		  local Q2`k'=`Q2`k''+`Q2i`i'j`j'k`k''
+	       }
+	    }
+	 }
+         local Q2tot=`Q2tot'+`Q2`k''
+      }
+      forvalues i=1/`nbitems' {
+         di in green "Item ``i'' : Q2 = `Q2i`i''"
+      }
+      local Q2=`Q2tot'*(`nbitems'-3)/(`nbitems'-1)
+      di in green "Q2 = `Q2tot'"
+      qui use "`Q2file'",replace
+   }
+
+/***********************************************************************************************************
+TEST LR Z
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests LR of Andersen"
+      }
+      local ssll=0
+      tempname Zfile
+      qui save "`Zfile'", replace
+      qui use "`saveraschtest'",replace
+      qui keep if `touse'==1
+      gen `score'=0
+      forvalues j=1/`nbitems' {
+         qui replace `score'=`score'+``j''
+      }
+      qui recode `score' `recode' `nbitems'=`nbgroups'
+      forvalues i=1/`=`nbgroups'-1' {
+         if `effscore`i''>0 {
+            qui raschtestv7 `varlist' if `score'==`i', id(`id') test(NONE) `ld'
+            local ll`i'=r(cll)
+            local ssll=`ssll'+(`ll`i'')
+         }
+      }
+      local Z=2*`ssll'-2*`ll'
+      use "`Zfile'",replace
+      tempname AndersenZ
+      matrix define `AndersenZ'=(`Z',`=(`nbgroups'-2)*(`nbitems'-1)',1-chi2(`=(`nbitems'-1)*(`nbgroups'-2)',`Z'))
+   }
+}
+
+
+/***********************************************************************************************************
+DISPLAYING RESULTS WITH TESTS
+************************************************************************************************************/
+
+if "`test'"!="NONE" {
+   local conttest= "_c"
+}
+di
+tempname itemfit globalfit
+matrix `globalfit'=J(1,3,0)
+if "`method'"=="cml" {
+   di in green "Estimation method: " in yellow  "Conditional maximum likelihood (CML)"
+   local nbtest=`nbgroups'-1
+   local line=77
+}
+else if "`method'"=="mml"{
+   di in green "Estimation method: " in yellow  "Marginal maximum likelihood (MML)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+else if "`method'"=="gee" {
+   di in green "Estimation method: " in yellow  "Generalized Estimating Equations (GEE)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+if "`test'"=="NONE" {
+   local line=35
+}
+
+di in green  "Number of items: " in yellow  `nbitems'
+
+di in green  "Number of groups: " in yellow  `=`nbgroups'+1' `conttest'
+if "`test'"!="NONE" {
+   di in green " (" in yellow "`nbtest'" in green " of them are used to compute the statistics of test)"
+}
+if "`method'"=="cml" {
+   local nbind=`nbind'+`effscore0'+`effscore`nbgroups''
+   local cont "_c"
+   matrix `itemfit'=J(`nbitems',6,0)
+}
+else {
+   local cont
+   matrix `itemfit'=J(`nbitems',5,0)
+}
+local missing=`N'-`nbind'
+di in green "Number of individuals: " in yellow `N'
+di in green "Number of individuals with missing values: " in yellow `nbindmiss' _c
+if "`ld'"=="" {
+   di in green " (removed)"
+}
+else {
+   di
+}
+di in green  "Number of individuals with nul or perfect score: " in yellow `=`effscore0'+`effscore`nbgroups'''
+if "`method'"=="cml" {
+   di in green  "Conditional log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+else {
+   di in green "Marginal log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+di
+noi di in green  _col(16) "Difficulty" `conttest'
+if "`test'"!="NONE" {
+   di in green _col(58) "Standardized"
+}
+noi di in green _col(9) "Items" _col(16) "parameters" _col(28) "std Err." `conttest'
+if "`test'"!="NONE" {
+   local varin=int(2/sqrt(`nbind')*100)/100
+   local varout=int(6/sqrt(`nbind')*100)/100
+   di _col(41) "`namewp'" _col(47) "df" _col(50) "p-value" _col(58) "Outfit" _col(66) "Infit" `cont'
+   if "`method'"=="cml" {
+      di in green _col(77) "U"
+   }
+}
+di in green  "{hline `line'}"
+forvalues i=1/`nbitems' {
+   noi di in yellow _col(3) %12s abbrev("``i''`fixed`i''" ,12) in yellow _col(18) %8.5f `beta`i'' _col(29) %6.5f `sd`i'' `conttest'
+   if "`test'"!="NONE" {
+      di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfitstd`i'' _col(65) %6.3f `infitstd`i''  /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/  `cont'
+      matrix `itemfit'[`i',1]=`testitems'[`i',1]
+      matrix `itemfit'[`i',2]=`=`nbgroups'-2'
+      matrix `itemfit'[`i',3]=1-chi2(`=`nbgroups'-2',`testitems'[`i',1])
+      matrix `itemfit'[`i',4]=`outfitstd`i''
+      matrix `itemfit'[`i',5]=`infitstd`i''
+      if "`method'"=="cml" {
+         di in ye _col(72) %6.3f `U`i''
+         matrix `itemfit'[`i',6]=`U`i''
+      }
+   }
+}
+di in green  "{hline `line'}"
+if "`test'"!="NONE" {
+   if "`method'"=="cml" {
+      local df=(`nbgroups'-2)*(`nbitems'-1)
+   }
+   else {
+      local df=(`nbgroups'-1)*(`nbitems'-1)-1
+   }
+   matrix `globalfit'=(`stattest',`df',1-chi2(`df',`stattest'))
+   noi di in green _col(6) "`descwp'" _col(32) in gr "`namewp'=" _col(36) in ye %8.3f `globalfit'[1,1] _col(46) %3.0f `globalfit'[1,2] _col(51) %6.4f `globalfit'[1,3]
+   if "`method'"=="cml" {
+      noi di in green _col(6) "Andersen LR test" _col(34) "Z=" in yellow _col(36) %8.3f `AndersenZ'[1,1] _col(46) %3.0f `AndersenZ'[1,2] _col(51) %6.4f `AndersenZ'[1,3]
+   }
+   di in green  "{hline `line'}"
+}
+
+if "`method'"=="cml"&"`meandiff'"==""{
+   di in green "*: The difficulty parameter of this item had been fixed to 0"
+}
+if "`method'"=="cml"&"`meandiff'"!=""{
+   di in green "The mean of the difficulty parameters is fixed to 0"
+}
+if `smallgroup'==1&"`test'"!="NONE" {
+   di in green "You have groups of scores with less than 30 individuals. The tests can be invalid."
+}
+if "`method'"!="cml"&"`test'"=="Q" {
+   di in green "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test."
+}
+
+
+
+di
+if "`method'"!="cml" {
+   di in green  "{hline 56}"
+   noi di in green _col(5) "Parameters" _col(21) "Coef." _col(28) "std Err." _col(43) "z" _col(52) "P>|z|"
+   di in green  "{hline 56}"
+   local zsig=`sig'/`sesig'
+   local pzsig=2*(1-norm(abs(`zsig')))
+   di in green _col(10) in yellow "Sigma" _col(18) %8.5f `sig' _col(29) %6.5f `sesig' _col(38) %6.3f `zsig' _col(50) %7.4f `pzsig'
+   di in green  "{hline 56}"
+}
+*set trace on
+if "`covariables'"!="" {
+   tempname zcovariates pcovariates
+   matrix `zcovariates'=J(1,`nbcovariables',0)
+   matrix `pcovariates'=J(1,`nbcovariables',0)
+   forvalues i=1/`nbcovariables' {
+      local tmp :word `i' of `covariables'
+      local zcov=`betacov'[1,`i']/`Vbetacov'[`i',`i']^.5
+      local pzcov=2*(1-norm(abs(`zcov')))
+      matrix `zcovariates'[1,`i']=`zcov'
+      matrix `pcovariates'[1,`i']=`pzcov'
+      di in green _col(3) %12s in yellow abbrev("`tmp'",12) _col(18) %8.5f `betacov'[1,`i'] _col(29) %6.5f `Vbetacov'[`i',`i']^.5 _col(38) %6.3f `zcov' _col(50) %7.4f `pzcov'
+   }
+   di in green  "{hline 56}"
+   local difficulties2
+   if "`difficulties'"!="" {
+      local difficulties2 diff(`difficulties')
+   }
+   if "`ss1'"!="" {
+      tempfile ss1save
+      qui save `ss1save'
+      qui use `saveraschtest'
+      qui keep if `touse'==1
+
+      qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2'
+      local sigma0=r(sigma)
+      local var0=`sigma0'^2
+      local ss10=`var0'*`=`N'-1'
+      local ss1c0=0
+      di
+      di in green "Type 1 Sum of Squares (sequential)"
+      di "{hline 56}"
+      di in green _col(27) "Variance of the" _col(48) "Explained"
+      di in green _col(4) "Covariates" _col(25) "SS" _col(30) "latent trait" _col(49) "Variance"
+      di "{hline 56}"
+      di _col(10) in green  "None" _col(15) in ye %12.3f `ss10' _col(34) %8.3f `var0'
+      di in green "{dup 56:-}"
+      local covariablesss1
+      forvalues i=1/`nbcovariables' {
+         local covariablesss1 `covariablesss1' `covariable`i''
+         qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss1') test(none)  `ld' `difficulties2'
+         local sigma`i'=r(sigma)
+         local var`i'=`sigma`i''^2
+         local ss1`i'=`var`i''*`=`N'-1'
+         di _col(2) %12s in yellow abbrev("`covariable`i''",12) _col(15) %12.3f in ye `=`ss1`=`i'-1''-`ss1`i''' _col(34) %8.3f `var`i'' _col(52) %5.3f (`=`ss1`=`i'-1''-`ss1`i''')/`ss10'
+      }
+      di in green "{hline 56}"
+      qui use `ss1save'
+   }
+   if "`ss3'"!="" {
+      tempfile ss3save
+      qui save `ss3save'
+      qui use `saveraschtest'
+      qui keep if `touse'==1
+      if "`ss1'"=="" {
+         qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2'
+         local sigma0=r(sigma)
+         local var0=`sigma0'^2
+         local ss30=`var0'*`=`N'-1'
+      }
+      else {
+         local ss30=`ss10'
+      }
+      di
+      di in green "Type 3 Sum of Squares "
+      di "{hline 56}"
+      di in green _col(27) "Variance of the" _col(48) "Explained"
+      di in green _col(4) "Covariates" _col(25) "SS" _col(30) "latent trait" _col(49) "Variance"
+      di "{hline 56}"
+      di _col(10) in green  "None" _col(15) in ye %12.3f `ss10' _col(34) %8.3f `var0'
+      di _col(6) in green  "Complete" _col(15) in ye %12.3f `sig'^2*(`N'-1) _col(34) %8.3f `sig'^2
+      di in green "{dup 56:-}"
+      forvalues i=1/`nbcovariables' {
+         local covariablesss3
+         forvalues j=1/`nbcovariables' {
+            if `i'!=`j' {
+               local covariablesss3 `covariablesss3' `covariable`j''
+            }
+         }
+         qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss3') test(none) `ld' `difficulties2'
+         local sigmas`i'=r(sigma)
+         local vars`i'=`sigmas`i''^2
+         local ss3s`i'=`vars`i''*`=`N'-1'
+         local vara`i'=`sig'^2
+         local ss3a`i'=`vara`i''*`=`N'-1'
+         di _col(2) %12s in yellow abbrev("`covariable`i''",12) _col(15) %12.3f in ye `=`ss3s`i''-`ss3a`i''' _col(34) %8.3f `vars`i'' _col(52) %5.3f (`=`ss3s`i''-`ss3a`i''')/`ss30'
+      }
+      di in green "{hline 56}"
+      qui use `ss3save'
+   }
+}
+
+
+
+/*Tabular of the estimated values of the latent trait*/
+
+if "`covariables'"=="" {
+   di
+   di
+   noi di in green _col(33) "Ability" _col(60) "Expected"
+   noi di in green _col(17) "Group" _col(23) "Score" _col(30) "parameters" _col(42) "std Err." _col(54) "Freq." _col(63) "Score"_c
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      noi di in green _col(75) "ll"
+   }
+   else {
+      noi di ""
+   }
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      local line=62
+   }
+   else {
+     local line=51
+   }
+   di in green _col(17) "{hline `line'}"
+   local nonul=0
+   forvalues g=0/`nbgroups' {
+      if `g'!=0 {
+         di in green _col(17) "{dup `line':-}"
+      }
+      forvalues s=`liminf`g''/`limsup`g'' {
+         if `s'==`liminf`g'' {
+            local tmp `ll`g''
+            local gr `g'
+         }
+         else {
+            local tmp
+            local gr
+         }
+         local expscore`nonul'=0
+         forvalues i=1/`nbitems' {
+            local expscore`nonul'=`expscore`nonul''+1/(1+exp(-`theta`nonul''+`beta`i''))
+         }
+         if "`method'"=="cml" {
+            local format1 %8.3f
+         }
+         else {
+            local format1 %8.5f
+         }
+         noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(32) `format1' `theta`nonul'' _col(42) `format1' `sdtheta`nonul'' _col(55) %4.0f `nbrealscore`s'' _col(64) % 4.2f `expscore`nonul'' _col(68) %11.4f `tmp'
+         local nonul=`nonul'+1
+      }
+   }
+   di in green _col(17) "{hline `line'}"
+}
+if "`method'"=="mml"|"`method'"=="gee" {
+       di
+       *di in green "Variance of the estimated latent trait" _col(45) in ye %10.4f `vartheta'
+       di in green "Mean variance of the error" _col(45) in ye %10.4f `meanse2'
+       local sig2=`sig'^2
+       di in green "Estimated variance of the latent trait" _col(45) in ye %10.4f `sig2'
+       local psi2=1-`meanse2'/`sig2'
+       di in green "Personal Separation Index (PSI)" _col(45) in ye %10.4f `psi2'
+       di in green "Adjusted PSI on covariates (PSIadj)" _col(45) in ye %10.4f `psi'
+}
+
+
+/***********************************************************************************************************
+DETAILS OPTION
+************************************************************************************************************/
+
+if "`details'"!="" {
+   forvalues g=0/`nbgroups' {
+      if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" {
+         di
+         di in  green "{hline 44}"
+         di in green "Group: " in ye "`g'" in green " from " in ye "`liminf`g''" in green " to " in ye "`limsup`g''" in green " (n=" in ye "`nbscore`g''" in green")"
+         di
+         di _col(3) "Item" _col(10) "Observed" _col(23) "Expected" _col(37) "Scaled"
+         di in green "{dup 44:-}"
+      }
+      if `g'!=0&`g'!=`nbgroups' {
+         forvalues j=1/`nbitems' {
+            local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j'])
+            di _col(3) in ye "``j''" _col(14) %4.0f `Obs2'[`j',`g'] _col(25) %6.2f `Th2'[`j',`g'] _col(36) %7.4f `tmp'
+         }
+         di in green "{dup 44:-}"
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `test`g''[1,1]
+      }
+      else if "`method'"!="cml" {
+         if `g'==0 {
+            local h=0
+         }
+         else {
+            local h=`nbitems'
+         }
+         local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'')
+         di in ye _col(14) %4.0f `nbrealscore`h'' _col(25) %6.2f `ci`h'' _col(36) %7.4f `tmp'
+         di in green "{dup 44:-}"
+         local tmp=`tmp'^2
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `tmp'
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION ICC
+************************************************************************************************************/
+*set trace on
+if "`icc'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Items Characteristic Curves"
+   }
+   tempvar proba propemp propth propthb
+   qui replace `tl'=. if `realscore'==0|`realscore'==`nbitems'|`realscore'==.
+   qui gen `propemp'=.
+   qui gen `propth'=.
+   qui gen `propthb'=.
+   label variable `propth' "Expected ICC"
+   label variable `propemp' "Observed ICC"
+   label variable `propthb' "Expected ICC"
+   label variable `tl' "Latent trait"
+   global iccs
+   forvalues i=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui replace `propthb'=exp(`theta`s''-`beta`i'')/(1+exp(`theta`s''-`beta`i'')) if `item'==`i'&`realscore'==`s'
+      }
+      qui replace `propemp'=.
+      qui replace `propth'=.
+      tempvar propemp`i' propth`i'
+      qui bysort `realscore' `item' : egen `propth`i''=mean(`propthb') if `item'==`i'
+      qui bysort `realscore' `item' : egen `propemp`i''=mean(`rep') if `item'==`i'
+      qui replace `propth'=`propth`i'' if `item'==`i'
+      qui replace `propemp'=`propemp`i'' if `item'==`i'
+      local mintl=floor(`theta1')
+      local maxtl=floor(`theta`=`nbitems'-1'')+1
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\icc``i''"
+      }
+      if "`v8'"!="" {
+         graph twoway (line  `propemp' `propth' `tl') if `item'==`i' , name(icc``i'',replace) ytitle("")  ylabel(0(.25)1) title("Observed and Expected ICC for the item ``i''") xlabel(`mintl'(1)`maxtl') `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save icc``i''  "`saving'" , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui graph `propemp' `propth' `tl' if `item'==`i' , twoway `saving' c(ll) ylabel(0(.25)1)   xlabel(`mintl'(1)`maxtl') title("Observed and Expected ICC for the item ``i''")
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION INFORMATION
+************************************************************************************************************/
+
+if "`information'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Information graph"
+   }
+
+   tempfile saveinfo
+   qui save "`saveinfo'",replace
+   tempvar info latent
+   drop _all
+   qui set obs 2001
+   gen `latent'=((_n-1)/1001-1)*3
+   label variable `latent' "latent trait"
+   gen `info'=0
+   forvalues i=1/`nbitems' {
+      qui replace `info'=`info'+exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2
+   }
+   local saving "`dirsave'\\information"
+   if "`v8'"!="" {
+      graph twoway (line  `info' `latent') , name(information,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the scale") `draw'
+      if "`filessave'"!="" {
+         graph save information "`saving'" , `replace'
+      }
+      pause
+   }
+   else {
+      if "`filessave'"!="" {
+         local saving "saving(`saving'"
+         if "`replace'"=="" {
+            local saving "`saving')"
+         }
+         else {
+            local saving "`saving',replace)"
+         }
+      }
+      if "`filessave'"=="" {
+         local saving
+      }
+      qui graph `info' `latent' , twoway  `saving' c(l) xlabel(-3(1)3) title("Information graph of the scale")
+      pause
+   }
+   qui use "`saveinfo'",replace
+}
+
+/***********************************************************************************************************
+OPTION FITGRAPH
+************************************************************************************************************/
+
+if "`fitgraph'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graphical validation of the fit"
+   }
+   *set trace on
+   tempname outfit meanz2 meanv2 sumd infit Voutfit outfitstd Vinfit infitstd
+   qui egen `outfit'=mean(`y2'),by(`id')
+   qui egen `Voutfit'=sum(`r'),by(`id')
+   qui replace `Voutfit'=`Voutfit'/(`nbitems')^2-1/`nbitems'
+   qui gen `outfitstd'=(`outfit'^(1/3)-1)*(3/sqrt(`Voutfit'))-sqrt(`Voutfit')/3
+   qui egen `meanz2'=sum(`z2'),by(`id')
+   qui egen `meanv2'=sum(`v2'),by(`id')
+   qui gen `infit'=`meanz2'/`meanv2'
+   qui egen `Vinfit'=sum(`e'),by(`id')
+   qui replace `Vinfit'=`Vinfit'/(`meanv2')^2
+   qui gen `infitstd'=(`infit'^(1/3)-1)*(3/sqrt(`Vinfit'))-sqrt(`Vinfit')/3
+
+   qui su `outfitstd'
+   local mino=floor(2*min(`r(min)',-2))/2
+   local maxo=ceil(2*max(`r(max)',2))/2
+   qui su `infitstd'
+   local mini=floor(2*min(`r(min)',-2))/2
+   local maxi=ceil(2*max(`r(max)',2))/2
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfitind"
+      local savingi "`dirsave'\\infitind"
+   }
+   if "`v8'"!="" {
+      graph twoway (scatter `outfitstd' `id'), name(outfit,replace) yline(-2 2) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw'
+      pause
+      graph twoway (scatter `infitstd' `id'), name(infit,replace) yline(-2 2) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfit "`savingo'" , `replace'
+         graph save infit "`savingi'" , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitstd' `id', `savingo' twoway sy(.) c(.) yline(-2 2) title("Outfit indexes") b2title("Individual indexes") l1("") l2title("Outfit") ylabel(`mino'(.5)`maxo')
+      pause
+      graph `infitstd' `id', `savingi' twoway sy(.) c(.) yline(-2 2) title("Infit indexes") b2title("Individual indexes") l1("")  l2title("Infit") ylabel(`mini'(.5)`maxi')
+      pause
+   }
+   drop _all
+   qui set obs `nbitems'
+   tempvar name betap outfitstdj infitstdj
+   qui gen str9 `name'=""
+   qui gen `betap'=.
+   qui gen `outfitstdj'=.
+   qui gen `infitstdj'=.
+   local mino=-2
+   local maxo=2
+   local mini=-2
+   local maxi=2
+   forvalues j=1/`nbitems' {
+      qui replace `name'="``j''" in `j'
+      qui replace `betap'=`beta`j'' in `j'
+      qui replace `outfitstdj'=`outfitstd`j'' in `j'
+      qui replace `infitstdj'=`infitstd`j'' in `j'
+      local mino=floor(min(`mino',`outfitstd`j'')*2)/2
+      local mini=floor(min(`mini',`infitstd`j'')*2)/2
+      local maxo=ceil(max(`maxo',`outfitstd`j'')*2)/2
+      local maxi=ceil(max(`maxi',`infitstd`j'')*2)/2
+   }
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfititems"
+      local savingi "`dirsave'\\infititems"
+   }
+   if "`v8'"!="" {
+      graph twoway (scatter `outfitstdj' `betap',name(outfititem,replace) mlabel(`name')), yline(-2 2) title("Outfit indexes") xtitle("Difficulty") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw'
+      pause
+      graph twoway (scatter `infitstdj' `betap',name(infititem,replace) mlabel(`name')), yline(-2 2) title("Infit indexes") xtitle("Difficulty") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfititem "`savingo'" , `replace'
+         graph save infititem "`savingi'" , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitstdj' `betap', `savingo' twoway c(.) yline(-2 2) title("Outfit indexes") b2title("Difficulty") l1title("") l2title("Outfit") ylabel(`mino'(.5)`maxo') sy([`name'])
+      pause
+      graph `infitstdj' `betap', `savingi' twoway c(.) yline(-2 2) title("Infit indexes") b2title("Difficulty") l1title("") l2title("Infit") ylabel(`mini'(.5)`maxi') sy([`name'])
+      pause
+   }
+}
+
+
+/***********************************************************************************************************
+OPTION SPLITTESTS
+************************************************************************************************************/
+
+if "`splittests'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Splitting tests"
+   }
+   forvalues j=1/`nbitems' {
+      tempname estneg`j' estpos`j'
+      local listitems
+      forvalues k=1/`nbitems' {
+         if `j'!=`k' {
+            local listitems `listitems' ``k''
+         }
+      }
+      qui use "`saveraschtest'",replace
+      qui keep if `touse'==1
+      qui raschtestv7 `listitems' if ``j''==0,id(`id') test(NONE) meth(cml) `ld'
+      matrix `estneg`j''=r(beta)
+      local llneg=r(cll)
+      qui raschtestv7 `listitems' if ``j''==1,id(`id') test(NONE) meth(cml) `ld'
+      matrix `estpos`j''=r(beta)
+      local llpos=r(cll)
+      qui raschtestv7 `listitems',id(`id') test(NONE) meth(cml) `ld'
+      local llnegpos=r(cll)
+      local nbcol=colsof(`estneg`j'')
+      local meanneg=0
+      local meanpos=0
+      forvalues k=1/`nbcol' {
+         local meanneg=`meanneg'+`estneg`j''[1,`k']
+         local meanpos=`meanpos'+`estpos`j''[1,`k']
+      }
+      local meanneg=`meanneg'/`nbitems'
+      local meanpos=`meanpos'/`nbitems'
+      forvalues k=1/`nbcol' {
+         matrix `estneg`j''[1,`k']=`estneg`j''[1,`k']-`meanneg'
+         matrix `estpos`j''[1,`k']=`estpos`j''[1,`k']-`meanpos'
+         if "`method'"=="cml" {
+            matrix `estneg`j''=`estneg`j'',-`meanneg'
+            matrix `estpos`j''=`estpos`j'',-`meanpos'
+         }
+      }
+      drop _all
+      qui set obs `=`nbitems'+1'
+      tempvar neg pos name diag
+      qui gen `neg'=.
+      qui gen `pos'=.
+      qui gen str9 `name'=""
+      local min=`estneg`j''[1,1]
+      local max=`estneg`j''[1,1]
+      forvalues k=1/`=`nbitems'-1' {
+         qui replace `neg'=`estneg`j''[1,`k'] in `k'
+         qui replace `pos'=`estpos`j''[1,`k'] in `k'
+         local min=min(`min',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local max=max(`max',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local tmp:word `k' of `listitems'
+         qui replace `name'="`tmp'" in `k'
+      }
+      local min=floor(`min')
+      local max=floor(`max')+1
+      qui gen `diag'=.
+      qui replace `diag'=`min' in `nbitems'
+      qui replace `diag'=`max' in `=`nbitems'+1'
+      local Zgr=round(2*(`llneg'+`llpos'-`llnegpos'),0.001)
+      local Zgr=substr("`Zgr'",1,6)
+      local pgr=round(1-chi2(`=`nbitems'-1',`Zgr'),0.0001)
+      local pgr=substr("`pgr'",1,5)
+      local note="Z=`Zgr', df=`=`nbitems'-1' , p=`pgr'"
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\split``j''"
+      }
+      if "`v8'"!="" {
+         graph twoway (scatter `pos' `neg' ,mlabel(`name')) (line `diag' `diag'), ytitle("Positive answer") xtitle("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title(Splitting on ``j'') `draw' legend(off) note("Andersen Z test: `note'") name(split,replace) `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save split "`saving'" , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui replace `diag'=`neg' if `diag'==.
+         graph  `pos' `diag' `diag', `saving' c(.l) sy([`name']i) l1title("") l2title("Positive answer") b2title("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title("Splitting on ``j'' (`note')") `draw'
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION GRAPH
+************************************************************************************************************/
+
+if "`graph'"!=""&"`v8'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graph option"
+   }
+   tempvar  latent2  tl2 delta2 tlth2 labdelta2 labtl2
+   drop _all
+   qui set obs 1001
+   gen `latent2'=(_n-501)/100
+   label variable `latent2' "latent trait"
+   qui gen `tl2'=.
+   qui gen `labtl2'=""
+   forvalues i=0/`nbitems' {
+      *if (`i'!=0&`i'!=`nbitems')|"`method'"!="cml" {
+         qui replace `tl2'=`nbrealscore`i''/`N' if round(`latent2',0.01)==round(`theta`i'',0.01)
+         qui replace `labtl2'="`i'" if round(`latent2',0.01)==round(`theta`i'',0.01)
+      *}
+   }
+   qui gen `delta2'=.
+   qui gen `labdelta2'=""
+   forvalues i=1/`nbitems' {
+      qui replace `delta2'=-.05 if round(`latent2',0.01)==round(`beta`i'',0.01)
+      qui replace `labdelta2'="``i''" if round(`latent2',0.01)==round(`beta`i'',0.01)
+   }
+   if "`method'"=="mml"|"`method'"=="gee" {
+      qui gen `tlth2'=1/(2*_pi*`sig')*exp(-.5*(`latent2'/`sig')^2)
+      label variable `tlth2' "Theorical distribution"
+      local graphmml line `tlth2' `latent2'
+   }
+   label variable `tl2' "Score"
+   label variable `delta2' "Items"
+   local saving "`dirsave'\\graph"
+   local min=-2
+   local max=2
+   forvalues j=1/`nbitems' {
+      if `beta`j''<`min' {
+         local min=`beta`j''-.5
+      }
+      if `beta`j''>`max'&`beta`j''!=. {
+         local max=`beta`j''+.5
+      }
+   }
+   if "`method'"=="cml" {
+      if `theta0'<`min' {
+         local min=`theta0'-.5
+      }
+      if `theta`=`nbitems'-1''>`max' {
+         local max=`theta`=`nbitems'-1''+.5
+      }
+   }
+   else if "`method'"!="cml" {
+      if `theta0'<`min'&`theta0'!=. {
+         local min=`theta0'-.5
+      }
+      if `theta`nbitems''>`max'&`theta`nbitems''!=. {
+         local max=`theta`nbitems''+.5
+      }
+   }
+   local min=floor(`min')
+   local max=floor(`max')+1
+   qui su `tl2'
+   local max2=r(max)
+   if "`method'"!="cml" {
+      qui su `tlth2'
+      local max2=max(`max2',`r(max)')
+   }
+   qui replace `latent2'=. if `latent2'<`min'|`latent2'>`max'
+   if "`v8'"!="" {
+      graph twoway (bar `tl2' `latent2',/*mlabel(`labtl2')*/ barwidth(.3) ) (dropline `delta2' `latent2',mlabel(`labdelta2') mlabposition(6)) (`graphmml'), name(graph,replace) ytitle("") xlabel(`min'(1)`max') ylabel(-.1 0(0.05)`max2') title("Individuals/items representations") `draw'
+      if "`filessave'"!="" {
+         graph save graph "`saving'" , `replace'
+      }
+      pause
+   }
+}
+else if "`graph'"!=""&"`v8'"=="" {
+   di in ye "The graph option is not available with Stata 7"
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATION
+************************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+      di
+      di _col(4) "{hline 30}"
+      di _col(4) in green "Comparison of two populations"
+      di _col(4) "{hline 30}"
+      di
+      di _col(4) in green "`comp'==`mincomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmin' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmin' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmin'
+      di _col(4) in green "`comp'==`maxcomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmax' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmax' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmax'
+      di                                                                       _col(33) in green "Z= " _col(35) in yellow %8.4f `Zcomp' _col(47) in green "pvalue= "    _col(57) in yellow %6.4f `pvalue'
+}
+
+/***********************************************************************************************************
+TEST DIF
+************************************************************************************************************/
+
+if "`method'"=="cml"&"`dif'"!=""&"`test'"!="NONE" {
+   if "`trace'"!="" {
+      di in green "*** Tests of DIF"
+   }
+   local ssll=0
+   tempname DIFfile
+   qui save "`DIFfile'", replace
+   qui use "`saveraschtest'",replace
+   qui keep if `touse'==1
+   unab list:`dif'
+   local nbdif:word count `list'
+   tempname DIF
+   matrix define `DIF'=J(`nbdif',4,0)
+   local count=1
+   di
+   di _col(4) in green "{hline 45}"
+   di _col(4) in green "Test of Differential Item Functioning (DIF)"
+   di _col(4) in green "{hline 45}"
+   foreach j in `list' {
+      qui inspect `j'
+      local nbdif=r(N_unique)
+      qui su `j'
+      local maxdif=r(max)
+      if `nbdif'>10&`maxdif'<=10 {
+         di in ye "The {hi:dif} option is available with variables containing 10 or less modalities (coded from 0 or 1 to k<10)."
+         di in ye "The variable `j' (`nbdif' modalities) is omitted."
+      }
+      else {
+         local ssll=0
+         forvalues i=0/10 {
+            qui count if `j'==`i'
+            local effdif=r(N)
+            if `effdif'>0 {
+               qui raschtestv7 `varlist' if `j'==`i', id(`id') test(NONE)
+               local ll`i'=r(cll)
+               local ssll=`ssll'+(`ll`i'')
+            }
+         }
+         local Z=2*`ssll'-2*`ll'
+         local ddl=(`nbdif'-1)*(`nbitems'-1)
+         matrix define `DIF'[`count',1]=(`count',`Z',`ddl',1-chi2(`ddl',`Z'))
+         di
+         di _col(4) in green "Variable:" in ye " `j' " in green "   Number of groups: "  in ye "`nbdif'"
+         di _col(4) in green "LR Test Z=" in ye %8.3f `Z' in gr "   ddl=" in ye %4.0f `ddl' in gr "    p-value=" in ye %6.4f `=1-chi2(`ddl',`Z')'
+         di
+      }
+      local ++count
+   }
+   use "`DIFfile'",replace
+}
+
+/***********************************************************************************************************
+RETURN
+************************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Returns"
+}
+local colnametheta
+
+forvalues i=0/`nbgroups' {
+         local colnametheta `colnametheta' score_`i'
+}
+
+
+return clear
+
+if `nbitems'>=3&"`test'"!="NONE" {
+        matrix colnames `globalfit'=`namewp' df p
+	matrix rownames `globalfit'=`method'
+	matrix rownames `itemfit'=`varlist'
+        matrix roweq `itemfit'=`method'
+
+	if "`method'"=="cml" {
+                matrix colnames `itemfit'=`namewp' df p outfit infit U
+		matrix rownames `AndersenZ'=`method'
+		matrix colnames `AndersenZ'=Z df p
+		return matrix AndersenZ=`AndersenZ'
+                if "`dif'"!="" {
+		   matrix rownames `DIF'=`list'
+		   matrix colnames `DIF'=num Z df p
+		   return matrix DIF=`DIF'
+                }
+	}
+	else {
+                matrix colnames `itemfit'=`namewp' df p outfit infit
+	}
+	return matrix itemFit=`itemfit'
+	return matrix globalFit=`globalfit'
+}
+
+matrix colnames `theta'=`colnametheta'
+matrix rownames `theta'=theta
+return matrix theta `theta'
+matrix colnames `sdtheta'=`colnametheta'
+matrix rownames `sdtheta'=`colnametheta'
+return matrix Vartheta `sdtheta'
+local varlist2
+matrix coleq `beta'=`method'
+matrix coleq `Vbeta'=`method'
+matrix roweq `Vbeta'=`method'
+if "`method'"=="cml" {
+	forvalues i=1/`=`nbitems'-1' {
+		local varlist2 `varlist2' ``i''
+	}
+        return scalar cll=`ll'
+        return scalar ll=`globalll'
+	local AIC=-2*`globalll'+2*(`nbitems'-1)
+}
+else {
+        return scalar ll=`ll'
+	local varlist2 `varlist'
+	return scalar sigma=`sig'
+	return scalar sesigma=`sesig'
+	local AIC=-2*`ll'+2*(`nbitems'+1)
+}
+
+if "`comp'"!="" {
+   return scalar Zcomp=`Zcomp'
+   return scalar pZcomp=`pvalue'
+}
+
+matrix colnames `beta'=`varlist2'
+matrix rownames `beta'=beta
+return matrix beta `beta'
+
+matrix colnames `Vbeta'=`varlist2'
+matrix rownames `Vbeta'=`varlist2'
+return matrix Varbeta `Vbeta'
+
+return scalar AIC=`AIC'
+return scalar N=`nbind'
+
+if "`method'"=="mml" {
+   return scalar PSI=`psi2'
+   return scalar PSIadj=`psi'
+}
+if "`covariables'"!="" {
+   local tmp
+   local tmp2
+   forvalues i=1/`nbcovariables' {
+      local tmp `tmp' `covariable`i''
+      local tmp2 "`tmp2' :`covariable`i''"
+   }
+   matrix colnames `betacov'=`tmp2'
+   matrix rownames `Vbetacov'=`tmp2'
+   matrix colnames `Vbetacov'=`tmp2'
+   matrix colnames `zcovariates'=`tmp'
+   matrix colnames `pcovariates'=`tmp'
+   return matrix betacovariates=`betacov'
+   return matrix Vbetacovariates=`Vbetacov'
+   return matrix zcovariates=`zcovariates'
+   return matrix pcovariates=`pcovariates'
+}
+if "`pause'"!="" {
+   pause off
+}
+
+drop _all
+
+restore,not
+use "`saveraschtest'"
+
+/***********************************************************************************************************
+CREATE EVENTUAL NEW VARIABLES
+************************************************************************************************************/
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+        tempname genlt2 genscore2 outfit2 infit2
+        qui gen `score'=0 `if'
+        forvalues i=1/`nbitems' {
+           qui replace `score'=`score'+``i'' `if'
+        }
+        if "`genscore'"!="" {
+           qui gen `genscore'=`score' `if'
+        }
+        if "`genlt'"!="" {
+           if "`replacegenlt'"=="replace" {
+              capture drop `genlt'
+              capture drop se`genlt'
+           }
+           if "`method'"=="mml" {
+              qui sort `id'
+              qui merge `id' using `ltsave'
+              qui rename `u'm1 `genlt'
+              qui rename `u's1 se`genlt'
+              qui drop _merge
+           }
+           else if "`method'"!="mml" {
+              qui gen `genlt2'=. `if'
+              forvalues i=0/`nbitems' {
+                 qui replace `genlt2'=`theta`i'' `if'&`score'==`i'
+              }
+              qui gen `genlt'=`genlt2' `if'
+           }
+        }
+        if "`genfit'"!="" {
+           local outfit:word 1 of `genfit'
+           local infit:word 2 of `genfit'
+           qui gen `outfit'=0 `if'
+           qui gen `infit'=0  `if'
+           tempname infit1 infit2
+           qui gen `infit1'=0 `if'
+           qui gen `infit2'=0 `if'
+           forvalues j=1/`nbitems' {
+               tempname pi`j'
+               qui gen `pi`j''=exp(`genlt2'-`beta`j'')/(1+exp(`genlt2'-`beta`j'')) `if'
+               qui replace `pi`j''=0  `if'
+               forvalues s=1/`nbitems' {
+                  qui replace `pi`j''=`Pi'[`j',`s'] `if'&`score'==`s'
+               }
+               qui gen `outfit'``j''=(``j''-`pi`j'')^2/(`pi`j''*(1-`pi`j'')) `if'
+               qui replace `infit1'=`infit1'+(``j''-`pi`j'')^2  `if'
+               qui replace `infit2'=`infit2'+(`pi`j''*(1-`pi`j'')) `if'
+               qui replace `outfit'=`outfit'+`outfit'``j''/`nbitems' `if'
+           }
+           qui replace `infit'=`infit1'/`infit2'  `if'
+        }
+}
+
+if "`trace'"!=""|"`time'"!="" {
+    capture qui elapse `st'
+    di in green "** Time : " in yellow "$S_elap " in green "seconds"
+}
+
+end
diff --git a/Modules/ado/personal/r/old/raschtestv785.ado b/Modules/ado/personal/r/old/raschtestv785.ado
new file mode 100644
index 0000000..4025d5d
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschtestv785.ado
@@ -0,0 +1,2146 @@
+*! version 8.5  20december2009
+*! Jean-Benoit Hardouin
+*************************************************************************************************************
+* Raschtestv7: Rasch model, fit tests and graphical representations
+* Corresponds to the version 8 of Raschtest (http://freeirt.org) for Stata7
+*
+* Historic:
+* Version 2.1 (2003-07-10): Jean-Benoit Hardouin
+* Version 3.1 (2004-01-02) : Jean-Benoit Hardouin
+* Version 7.1 (2005-03-30) : Jean-Benoit Hardouin
+* Version 7.2.1 (2005-05-21) : Jean-Benoit Hardouin
+* Version 7.3.1 (2005-07-02) : Jean-Benoit Hardouin
+* Version 7.3.2 (2005-10-05) : Jean-Benoit Hardouin /*correction for the *genlt* option with *method(cml)**/
+* Version 7.3.3 (2005-12-21) : Jean-Benoit Hardouin /*correction if scores are not represented with method(mml) or method(gee)*/
+* Version 7.4.1 (2006-01-17) : Jean-Benoit Hardouin /*Standardized OUTFIT and INFIT, DIF option*/
+* Version 7.4.2 (2006-03-21) : Jean-Benoit Hardouin /*Avoids a bug when the temporary files are saved in a directory containing special characters*/
+* Version 7.4.3 (2006-11-15) : Jean-Benoit Hardouin /*Avoids a bug when the directory defined in the dirsave option contains special characters*/
+* Version 7.5.1 (2007-04-20) : Jean-Benoit Hardouin /*Return results of the comp option*/
+* Version 7.6.1 (2008-06-26) : Jean-Benoit Hardouin /*Nold option, corrects a bug with the genlt option*/
+* Version 7.6.2 (2009-03-01) : Jean-Benoit Hardouin /*Correction of the SE of the latent trait, graph option, correction of a bug with the if option, PSI in MML*/
+* Version 8.1 (2009-06-24) : Jean-Benoit Hardouin /*DIFFICULTIES option, COVARIATES option*/
+* Version 8.2 (2009-07-15) : Jean-Benoit Hardouin /*Correction of a bug with CML*/
+* Version 8.3 (2009-12-19) : Jean-Benoit Hardouin /*correction of a bug with DIFFICULTIES and COVARIATES options together*/
+* Version 8.4 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option */
+* Version 8.5 (2011-12-20) : Jean-Benoit Hardouin /*Correction for the ss1 and ss3 suboptions of the COVARIATES option */
+*
+* Needed modules :
+* gammasym version 2.2 (http://www.freeirt.org)
+* gausshermite version 1 (http://www.freeirt.org)
+* geekel2d version 4.3 (http://www.freeirt.org)
+* genscore version 1.4 (http://www.freeirt.org)
+* ghquadm (findit ghquadm)
+* gllamm version 2.3.14 (ssc describe gllamm)
+* gllapred version  2.3.7 (ssc describe gllapred)
+* elapse (ssc describe elapse)
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2003-2009 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+DEFINITION / SYNTAX
+***********************************************************************************************************/
+
+
+program define raschtestv7,rclass
+syntax varlist(min=1 numeric) [if] [in] , ID(varname) [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GENRES(string) GRAph v8 COMp(varname) dif(varlist) time TRace Details  nold iterate(int 200) DIFFiculties(string) COVariates(string)]
+
+local covariables `covariates'
+
+if "`if'"=="" {
+   local if "if 1"
+}
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Tests of conformity"
+}
+if "`v8'"=="" {
+        version 7.0
+}
+else {
+        version 8.0
+}
+
+local st = "$S_TIME"
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+if "`covariables'"!="" {
+   tokenize "`covariables'",parse(" ,")
+   local i=1
+   local tcovariables
+   while "``i''"!=","&"``i''"!="" {
+     local covariable`i' ``i''
+     local tcovariables `tcovariables' ``i''
+     local ++i
+   }
+   local nbcovariables=`i'-1
+   local ss1
+   local ss3
+   if "``i''"=="," {
+      forvalues j=`=`i'+1'/`=`i'+2' {
+         if "``j''"=="ss1" {
+            local ss1 ss1
+         }
+         else if "``j''"=="ss3" {
+            local ss3 ss3
+         }
+         else if "``j''"=="" {
+*            di in green "option `j' vide"
+         }
+         else {
+            di in red "Invalid option in the {hi:covariables} option"
+            error 198
+         }
+      }
+      local i=`i'+3
+      if "``i''"!="" {
+         di in red "There is too much options in the {hi:covariates} option."
+         error 198
+      }
+   }
+   local covariables `tcovariables'
+}
+else {
+   local nbcovariables=0
+}
+
+isid `id'
+tokenize `varlist'
+
+local bad
+forvalues i=1/`nbitems' {
+   qui count if ``i''!=0&``i''!=1&``i''!=.
+   local N=r(N)
+   if `N'>0 {
+      local bad `bad' ``i''
+   }
+}
+if "`bad'"!="" {
+   di in red "The item(s) {hi:`bad'} is(are) not binary item(s) (with responses 0 or 1)."
+   exit
+}
+
+
+
+if "`method'"=="" {
+    local method cml
+}
+if "`test'"=="" {
+    local test R
+}
+local method=lower("`method'")
+local test=upper("`test'")
+if "`method'"!="mml"&"`method'"!="cml"&"`method'"!="gee" {
+    di in red "Uncorrect method option."
+    error 198
+    exit
+}
+
+if "`test'"!="R"&"`test'"!="Q"&"`test'"!="WP"&"`test'"!="NONE" {
+   di in red "Uncorrect test option."
+   error 198
+   exit
+}
+
+if "`genfit'"!="" {
+   local nbwordgenfit:word count `genfit'
+   if `nbwordgenfit'!=2 {
+      di in red "Uncorrect genfit option."
+      di in red "This option must contain exactly two words"
+      error 198
+      exit
+   }
+}
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!=""|"`genres'"!="" {
+   capture confirm new variable `genfit' `genscore' `genres'
+   if "`genfit'"!="" {
+      local o:word 1 of `genfit'
+      forvalues i=1/`nbitems' {
+         confirm new variable `o'``i''
+      }
+   }
+   if "`genlt'"!="" {
+       local 0 `genlt'
+       gettoken left  0: 0,parse(",")
+       gettoken right  0: 0,parse(",")
+       local genlt `left'
+       local replacegenlt `0'
+       local length=length("`replacegenlt'")
+       if `length'>=3&substr("`replacegenlt'",1,`length')==substr("replace",1,`length') {
+          local replacegenlt replace
+       }
+       if "`replacegenlt'"!="replace"&"`replacegenlt'"!="" {
+           di "Not allowed option in the {hi:genlt} option"
+           error 198
+       }
+       else if "`replacegenlt'"=="" {
+           confirm new variable `genlt'
+       }
+   }
+}
+
+preserve
+
+tempfile saveraschtest
+qui save `saveraschtest'
+qui keep if `touse'==1
+
+if "`autogroup'"!=""&"`group'"!="" {
+   di in green "The autogroup and the group options cannot be defined in the same time"
+   di in green "Only the group option is retained."
+   local autogroup
+}
+
+if "`autogroup'"!="" {
+   tempvar autoscore
+   qui genscore `varlist',score(`autoscore')
+
+   tempname matscore tmp
+   matrix `matscore'=J(`=`nbitems'-1',3,0)
+   forvalues i=1/`=`nbitems'-1' {
+        matrix `matscore'[`i',1]=`i'
+        matrix `matscore'[`i',2]=`i'
+        qui count if `autoscore'==`i'
+        matrix `matscore'[`i',3]=r(N)
+   }
+   local stop=0
+   local j=0
+   while `j'<=`=`nbitems'-3'&`stop'!=1 {
+      local j=`j'+1
+      local scoretogroup=99999999
+      local rowtogroup1=0
+      local rowtogroup2=0
+      local stop=1
+      forvalues i=1/`=`nbitems'-`j'' {
+         if `matscore'[`i',1]>=0 & `matscore'[`i',3]<30 & `matscore'[`i',3]<`scoretogroup' {
+            local scoretogroup=`matscore'[`i',3]
+            local rowtogroup1=`i'
+            local stop=0
+         }
+      }
+      if `stop'!=1 {
+         if `rowtogroup1'>1&`rowtogroup1'<`=`nbitems'-`j'' {
+            if `matscore'[`=`rowtogroup1'-1',1]<`matscore'[`=`rowtogroup1'+1',1] {
+               local rowtogroup2=`rowtogroup1'
+               local rowtogroup1=`rowtogroup1'-1
+            }
+            else {
+               local rowtogroup2=`rowtogroup1'+1
+            }
+         }
+         else if `rowtogroup1'==1 {
+            local rowtogroup2=2
+         }
+         else if `rowtogroup1'==`=`nbitems'-`j'' {
+            local rowtogroup2=`nbitems'-`j'
+            local rowtogroup1=`nbitems'-`j'-1
+         }
+         matrix `tmp'=`matscore'
+         matrix `matscore'=J(`=`nbitems'-`j'',3,0)
+         if `rowtogroup1'!=1 {
+            matrix `matscore'[1,1]=`tmp'[1..`=`rowtogroup1'-1',1..3]
+         }
+         matrix `matscore'[`rowtogroup1',1]=`tmp'[`rowtogroup1',1]
+         matrix `matscore'[`rowtogroup1',2]=`tmp'[`rowtogroup2',2]
+         matrix `matscore'[`rowtogroup1',3]=`tmp'[`rowtogroup1',3]+`tmp'[`rowtogroup2',3]
+         if `rowtogroup2'!=`=`nbitems'-`j'' {
+            matrix `matscore'[`rowtogroup2',1]=`tmp'[`=`rowtogroup2'+1'..`=`nbitems'-`j'',1..3]
+         }
+      }
+   }
+   local nbrows=rowsof(`matscore')-1
+   local thresholds
+   forvalues i=1/`nbrows' {
+      local tmp=`matscore'[`i',2]
+      local thresholds `thresholds' `tmp'
+   }
+   local group `thresholds'
+}
+
+
+if "`group'"=="" {
+	forvalues i=1/`=`nbitems'-1' {
+		local group "`group' `i'"
+	}
+}
+local nbgroups:word count `group'
+local groupmax:word `nbgroups' of `group'
+if `groupmax'>=`nbitems' {
+	di in red "You cannot form a group with the higher possible score."
+	di in red "The higher possible value of the group option is `=`nbitems'-1'."
+        di in red "Please correct your group option."
+	error 198
+        exit
+}
+else {
+	if `groupmax'!=`=`nbitems'-1' {
+		local group "`group' `=`nbitems'-1'"
+		local nbgroups=`nbgroups'+1
+	}
+}
+local nbgroups=`nbgroups'+1
+
+if "`dirsave'"!=""&"`filessave'"=="" {
+        di in ye "If you want to save yours graphs, use the filessave option"
+}
+if "`filessave'"!="" {
+        if "`dirsave'"=="" {
+              local dirsave "`c(pwd)'"
+        }
+        di in ye "The graphs files will be saved in `dirsave'"
+}
+if "`dirsave'"!="" {
+        if "`filesave'"=="" {
+              local filesave "filesave"
+        }
+}
+
+
+if "`pause'"!=""&"`draw'"=="" {
+     pause on
+}
+
+if "`difficulties'"!="" {
+    capture confirm matrix `difficulties'
+    if _rc!=0  {
+	di in red "The vector `difficulties' defined in the {hi:difficulties} option does not exist."
+	error 198
+        exit
+    }
+}
+
+if "`difficulties'"!=""&"`method'"!="mml" {
+   di in red "The {hi:difficulties} option can be defined only for MML method."
+   error 198
+   exit
+}
+
+if "`covariables'"!=""&"`method'"!="mml" {
+   di in red "The {hi:covariables} option can be defined only for MML method."
+   error 198
+   exit
+}
+if "`covariables'"!=""&"`comp'"!="" {
+   di in red "The {hi:covariables} and {hi:comp} options can be defined jointly."
+   error 198
+   exit
+}
+
+
+
+
+
+/***********************************************************************************************************
+POSSIBLE TEST
+***********************************************************************************************************/
+
+if ("`icc'"!=""|"`fitgraph'"!=""|"`splittest'"!=""|"`details'"!="")&"`test'"=="NONE" {
+	di in green "You cannot use the {hi:details}, {hi:icc}, {hi:fitgraph} or {hi:splittest} options if you use {hi:test(none)}."
+        di in green "These options are ignored."
+	local details
+	local icc
+	local fitgraph
+	local splittest
+}
+if "`comp'"!=""&"`method'"=="cml" {
+   	di in green "You cannot compare two populations ({hi:comp} option) with the CML estimation method"
+   	di in green "This option is ignored."
+        local comp
+}
+if "`method'"!="cml"&"`test'"=="WP" {
+	di in green "The Wright-Panchapakesan test is not authorized with MML or GEE."
+	di in green "The WP tests are replaced by Van den Wollenberg Q tests."
+        local test Q
+}
+if "`method'"=="gee"&"`ld'"!="" {
+	di in green "You cannot use the {hi:nold} option with the GEE method of estimation"
+	di in green "This option is ignored."
+        local ld
+}
+
+
+if "`test'"==""|"`test'"=="R" {
+   local test "R"
+   if "`method'"=="cml" {
+      local namewp "R1c"
+      local descwp "R1c test"
+   }
+   else {
+      local namewp="R1m"
+      local descwp "R1m test"
+   }
+}
+if `nbitems'>999999|"`test'"=="WP" {
+	local namewp "  Y"
+	local descwp "Wright-Panchapakesan Y test"
+	local q2
+}
+ else if "`test'"=="Q" {
+	local namewp " Q1"
+	local descwp "Van den Wollenberg Q1 test"
+}
+
+if "`method'"!="cml"&"`meandiff'"!="" {
+	di in green "The {hi:meandiff} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local meandiff
+}
+
+if "`method'"!="cml"&"`splittests'"!="" {
+	di in green "The {hi:splittests} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local splittests
+}
+if "`method'"!="cml"&"`dif'"!="" {
+	di in green "The {hi:dif} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local dif
+}
+
+/***********************************************************************************************************
+SCORES AND GROUPS
+************************************************************************************************************/
+
+qui count if `touse'==1
+local N=r(N)
+
+qui keep `varlist' `comp' `covariables' `id' `touse'
+
+tempname rep item
+tempvar score realscore
+qui genscore `varlist',score(`score')
+qui count if `score'==.&`touse'==1
+local nbindmiss=r(N)
+
+if "`ld'"=="" {
+   qui drop if `score'==.
+}
+forvalues i=1/`nbitems' {
+	rename ``i'' `rep'`i'
+}
+
+
+
+local liminf0=0
+local limsup0=0
+local liminf`nbgroups'=`nbitems'
+local limsup`nbgroups'=`nbitems'
+
+
+local recode
+forvalues i=1/`=`nbgroups'-1' {
+	if `i'!= 1{
+		local liminf`i' : word `=`i'-1' of `group'
+	}
+	else {
+		local liminf1=0
+	}
+	local liminf`i'=`liminf`i''+1
+	local limsup`i':word `i' of `group'
+
+	local recode "`recode' `liminf`i''/`limsup`i''=`i'"
+}
+qui gen `realscore'=`score'
+qui recode `score' `recode' `nbitems'=`nbgroups'
+
+local smallgroup=0
+
+forvalues i=0/`nbgroups' {
+	qui count if `score'==`i'
+	local effscore`i'=r(N)
+	if `i'!=0&`i'!=`nbgroups'&`effscore`i''<30 {
+		local smallgroup=1
+	}
+}
+/***********************************************************************************************************
+ESTIMATION OF THE DIFFICULTY PARAMETERS
+************************************************************************************************************/
+if "`trace'"!="" {
+  di in green "*** Estimation of the difficulty parameters"
+}
+
+
+if "`covariables'"!=""&"`difficulties'"=="" {
+  forvalues i=1/`nbcovariables' {
+     qui su `covariable`i''
+     local mean`covariable`i''=r(mean)
+     qui replace `covariable`i''=`covariable`i''-`mean`covariable`i'''
+  }
+}
+
+tempname ll coef var beta Vbeta est
+
+if "`method'"=="gee" {
+   qui geekel2d `rep'1-`rep'`nbitems',ll
+   if `r(error)'==1 {
+       di "The variance of the latent trait probably is too high to made the GEE a efficient method to estimate the parameters."
+       error 499
+       exit
+   }
+   scalar `ll'=r(ll)
+   local nbind=r(N)
+   matrix `coef'=r(b)
+   matrix `est'=`coef'
+   matrix `est'[1,`=`nbitems'+1']=sqrt(`est'[1,`=`nbitems'+1'])
+   matrix `var'=r(V)
+   matrix `beta'=`coef'[1,1..`nbitems']
+   matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+   local sig=sqrt(`coef'[1,`=`nbitems'+1'])
+   local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])/sqrt(`nbind')/(`sig'*2)
+}
+
+qui reshape long `rep', i(`id') j(`item')
+
+tempvar diff tl
+gen `diff'=0
+
+forvalues i=1/`nbitems' {
+	qui gen `rep'`i'=`item'==`i'
+	qui replace `rep'`i'=-`rep'`i'
+}
+
+
+if "`method'"=="mml" {
+   if "`difficulties'"==""{
+      qui xtlogit `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') nocons iterate(`iterate')
+      matrix `est'=e(b)
+      matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`est'[1,`=`nbitems'+`nbcovariables'+1']/2)
+   }
+   else {
+      tempname offset b
+      qui gen `offset'=0
+      forvalues i=1/`nbitems' {
+          qui replace `offset'=-(`difficulties'[1,`i']) if `item'==`i'
+      }
+      qui gllamm `rep' `covariables'  , offset(`offset') i(`id') nocons iterate(`iterate') link(logit) fam(bin)
+      matrix `b'=e(b)
+      matrix `est'=`difficulties',`b'
+      matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`b'[1,`=`nbcovariables'+1']/2)
+   }
+}
+else if "`method'"=="cml" {
+	qui clogit `rep' `rep'1-`rep'`=`nbitems'-1' , group(`id')
+}
+
+
+if "`method'"!="gee" {
+   if "`difficulties'"=="" {
+      matrix `coef'=e(b)
+      matrix `var'=e(V)
+   }
+   else {
+      matrix `coef'=`difficulties'
+      matrix `var'=J(`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1',.)
+      matrix `var'[`=`nbitems'+1',`=`nbitems'+1']=e(V)
+   }
+   scalar `ll'=e(ll)
+   local nbind=e(N)/`nbitems'
+
+
+   if "`meandiff'"!="" {
+      matrix `var'=J(`nbitems',`nbitems',.)
+      matrix `coef'=J(1,`nbitems',.)
+      local param
+      local lin `rep'1
+      forvalues j=2/`=`nbitems'-1' {
+         local lin `lin'+`rep'`j'
+      }
+      local lin (`lin')/`nbitems'
+
+      forvalues j=1/`=`nbitems'-1' {
+         qui lincom `rep'`j'-`lin'
+         matrix `coef'[1,`j']=`r(estimate)'
+         matrix `var'[`j',`j']=`r(se)'^2
+      }
+      qui lincom -`lin'
+      matrix `coef'[1,`nbitems']=`r(estimate)'
+      matrix `var'[`nbitems',`nbitems']=`r(se)'^2
+   }
+   if "`method'"=="mml" {
+	local sig=e(sigma_u)
+	local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2
+        tempname betacov Vbetacov
+	if "`difficulties'"=="" {
+           matrix `beta'=`coef'[1,1..`nbitems']
+           matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+           if "`covariables'"!="" {
+              matrix `betacov'=`coef'[1,`=`nbitems'+1'..`=`nbitems'+`nbcovariables'']
+              matrix `Vbetacov'=`var'[`=`nbitems'+1'..`=`nbitems'+`nbcovariables'',`=`nbitems'+1'..`=`nbitems'+`nbcovariables'']
+           }
+           local sig=e(sigma_u)
+	   local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2
+	}
+	else {
+	   tempname tmp
+	   matrix `tmp'=e(b)
+           matrix `beta'=`difficulties'
+           if "`covariables'"!="" {
+              matrix `betacov'=`tmp'[1,1..`nbcovariables']
+           }
+           local sig=`tmp'[1,`=`nbcovariables'+1']
+           matrix `tmp'=e(V)
+	   local sesig=sqrt(`tmp'[`=`nbcovariables'+1',`=`nbcovariables'+1'])
+           matrix `Vbeta'=J(`nbitems',`nbitems',.)
+           if "`covariables'"!="" {
+              matrix `Vbetacov'=`tmp'[1..`nbcovariables',1..`nbcovariables']
+           }
+	}
+   }
+   else if "`method'"=="cml"&"`meandiff'"==""{
+	matrix `beta'=`coef'[1,1..`=`nbitems'-1']
+	matrix `Vbeta'=`var'[1..`=`nbitems'-1',1..`=`nbitems'-1']
+   }
+   else if "`method'"=="cml"&"`meandiff'"!=""{
+	matrix `beta'=`coef'
+	matrix `Vbeta'=`var'
+   }
+}
+
+if ("`method'"=="mml"|"`method'"=="gee") {
+   local colnames
+   forvalues i=1/`nbitems' {
+      local colnames "`colnames' `rep':`rep'`i'"
+   }
+   forvalues i=1/`nbcovariables'{
+      local tmp:word `i' of `covariables'
+      local colnames "`colnames' `rep':`tmp'"
+   }
+   local id2=substr("`id'",1,4)
+   local colnames "`colnames' `id2'1:_cons"
+   matrix colnames `est'=`colnames'
+
+   qui gllamm `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') allc nocons family(binom) link(logit) trace from(`est') eval
+   tempname u
+   qui gllapred `u',u fsample
+
+   forvalues i=1/`nbcovariables' {
+      local tmp:word `i' of `covariables'
+      qui replace `u'm1=`u'm1+`betacov'[1,`i']*(`tmp')/*+`mean`covariable`i''')*/
+   }
+   tempname theta sdtheta
+   matrix `theta'=J(1,`=`nbitems'+1',0)
+   matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',0)
+   qui su `u'm1 if `rep'1==-1
+   local vartheta=r(Var)
+   qui gen `u's2=`u's1^2
+   qui su `u's2 if `rep'1==-1
+   local meanse2=r(mean)
+   local psi=1-`meanse2'/(`meanse2'+`vartheta')
+   forvalues s=0/`nbitems' {
+      qui su `u'm1 if `realscore'==`s'
+      local theta`s'=r(mean)
+      qui su `u's1 if `realscore'==`s'
+      local sdtheta`s'=r(mean)
+      matrix `theta'[1,`=`s'+1']=`theta`s''
+      matrix `sdtheta'[`=`s'+1',`=`s'+1']=`sdtheta`s''
+   }
+   if "`genlt'"!="" {
+      tempfile ltsave ltsavetmp
+      qui save `ltsavetmp', replace
+      qui keep if `rep'1==-1
+      qui keep `u'm1 `u's1 `id'
+      qui sort `id'
+      qui save `ltsave'
+      qui use `ltsavetmp'
+   }
+}
+
+forvalues i=1/`nbitems' {
+	if `i'==`nbitems'&"`method'"=="cml"&"`meandiff'"=="" {
+		local beta`i'=0
+		local sd`i' .
+		local fixed`i' "*"
+	}
+	else {
+		local beta`i'=`coef'[1,`i']
+		local sd`i'=sqrt(`var'[`i',`i'])
+	}
+	qui replace `diff'=-`beta`i'' if `item'==`i'
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATIONS
+***********************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+   if "`trace'"!="" {
+     di in green "*** Test of comparison of two populations"
+   }
+         qui inspect `comp'
+         local unique=r(N_unique)
+         if `unique'== 2 {
+		qui su `comp'
+		local mincomp=r(min)
+		local maxcomp=r(max)
+	    	tempname bmin bmax
+	    	qui xtlogit `rep' if `comp'==`mincomp',offset(`diff') i(`id')
+	    	matrix `bmin'=e(b)
+	    	local meanmin=`bmin'[1,1]
+	    	local varmin=e(sigma_u)^2
+	    	local llmin=e(ll)
+	    	local Nmin=e(N_g)
+	    	qui xtlogit `rep' if `comp'==`maxcomp',offset(`diff') i(`id')
+	    	matrix `bmax'=e(b)
+	    	local meanmax=`bmax'[1,1]
+	    	local varmax=e(sigma_u)^2
+	    	local llmax=e(ll)
+	    	local Nmax=e(N_g)
+	    	local Zcomp=(`meanmin'-`meanmax')/sqrt(`varmin'/`Nmin'+`varmax'/`Nmax')
+		local pvalue=1-norm(abs(`Zcomp'))
+	 }
+	 else {
+	        di "It is impossible to compare more than two populations"
+	        di "The comparison process is not run"
+	        local comp
+	 }
+}
+
+/***********************************************************************************************************
+ESTIMATION OF THE ABILITY PARAMETERS  / CML
+************************************************************************************************************/
+if `nbitems'>=2 {
+   if "`trace'"!="" {
+      di in green "*** Estimation of the ability parameters"
+   }
+   if "`method'"=="cml" {
+      tempfile verytmp
+      qui save `verytmp',replace
+      drop _all
+      qui set obs 20001
+      qui gen theta=(_n-10001)/1000
+      qui gen A=1
+      forvalues j=1/`nbitems' {
+         qui gen u`j'=exp(theta-`beta`j'')
+         qui gen p`j'=u`j'/(1+u`j')
+         qui gen a`j'=1/u`j'
+         qui replace A=A*a`j'
+         qui gen i`j'=u`j'/(1+u`j')^2
+         qui gen j`j'=(u`j'*(1-u`j'))/(1+u`j')^3
+      }
+      qui egen P=rsum(p*)
+      qui egen I=rsum(i*)
+      qui egen J=rsum(j*)
+      qui gen V=1/I^2*(I+J^2)/(4*I^2)
+      qui gen V2=1/I
+      tempname theta sdtheta
+      matrix `theta'=J(1,`=`nbitems'+1',0)
+      matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',.)
+      forvalues s=0/`nbitems' {
+         qui gen f`s'=abs(`s'-P+.5*J/I)
+         qui sort f`s'
+         matrix `theta'[1,`=`s'+1']=theta[1]
+         matrix `sdtheta'[`=`s'+1',`=`s'+1']=sqrt(V2[1])
+      }
+      use "`verytmp'",replace
+   }
+   qui gen `tl'=0
+   forvalues s=0/`nbitems' {
+      local theta`s'=`theta'[1,`=`s'+1']
+      qui replace `tl'=`theta`s'' if `realscore'==`s'
+      local sdtheta`s'=`sdtheta'[`=`s'+1',`= `s'+1']
+   }
+   tempname pred
+   qui gen `pred'=log(exp(`rep'*(`tl'+`diff'))/(1+exp(`tl'+`diff')))
+
+   qui su `pred'
+   local globalll=r(sum)
+
+   local nulscore=0
+   forvalues i=0/`nbgroups' {
+      qui count if `score'==`i'&`item'==1
+      local nbscore`i'=r(N)
+      if `nbscore`i''==0 {
+         local nulscore=1
+      }
+   }
+   if `nulscore' {
+      di in green "{p}At least one group of scores concerns none individuals. Tests will be not computed.{p_end}"
+      di in green "{p}Use the {hi:group} or the {hi:autogroup} options.{p_end}"
+      local test "NONE"
+      local details
+      local icc
+      local fitgraph
+      local splittest
+   }
+   forvalues i=0/`nbitems' {
+      qui count if `realscore'==`i'&`item'==1
+      local nbrealscore`i'=r(N)
+   }
+}
+
+/***********************************************************************************************************
+TESTS OF THE FIRST ORDER
+************************************************************************************************************/
+
+tempname Pi
+matrix define `Pi'=J(`nbitems',`=`nbitems'-1',0)
+if "`test'"!="NONE" {
+   qui drop if `score'==.
+   if "`trace'"!="" {
+      di in green "*** Tests of the first order"
+   }
+   tempname Obs Obs2 Th Th2
+
+   matrix define `Obs'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Obs2'=J(`nbitems',`=`nbgroups'-1',0)
+   matrix define `Th'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Th2'=J(`nbitems',`=`nbgroups'-1',0)
+   local listofitemsc
+
+   /* Estimation of the gamma symetrical functions*/
+   local c0 "1"
+   local c`nbitems' "`nbitems'*x"
+   forvalues j=1/`nbitems' {
+      local listini`j'
+      local listofitemsc "`listofitemsc' `beta`j''"
+      local c0 `c0'*(1+exp(x-`beta`j''))
+      local c`nbitems' `c`nbitems''-`beta`j''
+      forvalues k=1/`nbitems' {
+         local listini`j'k`k'
+         if `k'!=`j' {
+            local listini`j' "`listini`j'' `beta`k''"
+         }
+         forvalues l=1/`nbitems' {
+            if `l'!=`j'&`l'!=`k' {
+               local listini`j'k`k' "`listini`j'k`k'' `beta`l''"
+            }
+         }
+      }
+   }
+
+   gammasym `listofitemsc'
+
+   /*Estimation, for each value of the score s of the probability to respond to each item (Pi) and of the theorical number of positive responses (Ths) and of theorical number of positive respond per item pair (Ws)*/
+   forvalues s=1/`nbitems' {
+      local denom`s'=r(gamma`s')
+      tempname  W`s'
+      matrix define `W`s''=J(`nbitems',`nbitems',0)
+   }
+   tempvar prob prob2 z y v z2 y2 v2 c r q e
+   qui gen `prob'=.
+   qui gen `prob2'=.
+   forvalues j=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui count if `rep'==1&`item'==`j'&`realscore'==`s'
+         matrix `Obs'[`j',`s']=r(N)
+         if "`test'"!="WP" {
+            gammasym `listini`j''
+            local num`j'=r(gamma`=`s'-1')
+            if "`method'"=="cml"|"`test'"=="Q" {
+               matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s''
+            }
+            else {
+               gausshermite exp(`s'*x)/(`c0'), sigma(`sig')
+               local int`s'=r(int)
+               if "`test'"=="R"&`nbrealscore`s''!=0{
+                  local tmp=exp(-`beta`j'')*`num`j''*`int`s''*`nbind'/`nbrealscore`s''
+                  matrix `Pi'[`j',`s']=`tmp'
+               }
+               else if `nbrealscore`s''==0 {
+                  matrix `Pi'[`j',`s']=0
+               }
+            }
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  if `s'>=2 {
+                     gammasym `listini`j'k`k''
+                     local num`j'k`k'=r(gamma`=`s'-2')
+                     if "`method'"=="cml" {
+                        matrix `W`s''[`j',`k']=`nbrealscore`s''*exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''/`denom`s''
+                     }
+                     else {
+                        matrix `W`s''[`j',`k']=exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''*`int`s''*`nbind'
+                     }
+                     matrix `W`s''[`k',`j']=`W`s''[`j',`k']
+                  }
+               }
+            }
+         }
+         else if "`test'"=="WP" {
+            matrix `Pi'[`j',`s']=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j''))
+         }
+         matrix `Th'[`j',`s']=`Pi'[`j',`s']*`nbrealscore`s''
+         qui replace `prob'=`Pi'[`j',`s'] if `realscore'==`s'&`item'==`j'
+         qui replace `prob2'=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) if `realscore'==`s'&`item'==`j'
+         matrix `W`s''[`j',`j']=`nbrealscore`s''*`Pi'[`j',`s']
+         if "`test'"!="R" {
+            matrix `W`s''[`j',`j']=`W`s''[`j',`j']*abs(1-`Pi'[`j',`s'])
+         }
+      }
+   }
+   qui gen `v2'=abs(`prob'*(1-`prob'))
+   qui gen `z2'=(`rep'-`prob')^2
+   qui gen `y2'=`z2'/`v2'
+   qui gen `c'=abs(`prob'*(1-`prob')*(`prob'^3+(1-`prob')^3))
+   qui gen `r'=`c'/(`v2')^2
+   qui gen `e'=`c'-(`v2')^2
+
+   forvalues j=1/`nbitems' {
+      qui su `y2' if `item'==`j'
+      local outfit`j'=r(mean)
+      qui su `r' if `item'==`j'
+      local Voutfit`j'=r(sum)
+      local Voutfit`j'=`Voutfit`j''/(`nbind')^2-1/`nbind'
+      local outfitstd`j'=(`outfit`j''^(1/3)-1)*(3/sqrt(`Voutfit`j''))-sqrt(`Voutfit`j'')/3
+
+      qui su `z2' if `item'==`j'
+      local n=r(sum)
+      qui su `v2' if `item'==`j'
+      local d=r(sum)
+      local infit`j'=`n'/`d'
+      qui su `e' if `item'==`j'
+      local sume=r(sum)
+      local Vinfit`j'=`sume'/(`d')^2
+      local infitstd`j'=(`infit`j''^(1/3)-1)*(3/sqrt(`Vinfit`j''))-sqrt(`Vinfit`j'')/3
+   }
+   tempname tmp stattest testitems
+
+   /*Estimation, by scores group g, of the theorical number of positive response (Th2g) and of the positive respond to each items pair (W2g)*/
+   scalar `stattest'=0
+   forvalues g=1/`=`nbgroups'-1' {
+      tempname  W2`g' d2`g'
+      matrix define `W2`g''=J(`nbitems',`nbitems',0)
+      forvalues s=`liminf`g''/`limsup`g'' {
+         forvalues j=1/`nbitems' {
+            matrix `Obs2'[`j',`g']=`Obs2'[`j',`g']+`Obs'[`j',`s']
+            matrix `Th2'[`j',`g']=`Th2'[`j',`g']+`Th'[`j',`s']
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  matrix `W2`g''[`j',`k']=`W2`g''[`j',`k']+`W`s''[`j',`k']
+                  matrix `W2`g''[`k',`j']=`W2`g''[`j',`k']
+               }
+            }
+            matrix `W2`g''[`j',`j']=`W2`g''[`j',`j']+`W`s''[`j',`j']
+         }
+      }
+
+      /*Estimation of the d2g vectors*/
+      matrix `d2`g''=`Obs2'[1..`nbitems',`g']-`Th2'[1..`nbitems',`g']
+
+      /*Estimation of the influences on the test of each item (testitemsg matrix) and of the test statistic (stattest)*/
+      tempname test`g' testitems`g'
+      matrix `test`g''=`d2`g'''*syminv(`W2`g'')*`d2`g''
+      capture matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      if _rc!=0 {
+         matrix `tmp'=J(`nbitems',`nbitems',0)
+         forvalues j=1/`nbitems' {
+            matrix `tmp'[`j',`j']=`W2`g''[`j',`j']
+         }
+         di in green "Group `g' (`liminf`g''/`limsup`g''): The weight matrix is not positive-definite, the diagonal matrix is used to estimate the contribution of the items on the `wpname' statistic"
+         matrix list `tmp'
+         matrix `testitems`g''=cholesky(syminv(`tmp'))*`d2`g''
+      }
+      else {
+         matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      }
+      scalar `stattest'=`stattest'+`test`g''[1,1]
+   }
+   matrix `testitems'=J(`nbitems',1,0)
+   forvalues j=1/`nbitems' {
+      forvalues g=1/`=`nbgroups'-1' {
+         matrix `testitems'[`j',1]=`testitems'[`j',1]+`testitems`g''[`j',1]^2
+      }
+   }
+
+   /*Adaptation for the Q1 statistic*/
+   if "`test'"=="Q" {
+      scalar `stattest'=`stattest'*`=`nbitems'-1'/`nbitems'
+   }
+
+   /*Correction for R1m and Q1m*/
+   if ("`test'"=="R"|"`test'"=="Q")&("`method'"=="mml"|"`method'"=="gee") {
+      local c`nbitems' exp(`c`nbitems'')/(`c0')
+      local c0 1/(`c0')
+      gausshermite `c0', sigma(`sig')
+      local ci0=r(int)*`nbind'
+      gausshermite `c`nbitems'',sigma(`sig')
+      local ci`nbitems'=`nbind'*r(int)
+      scalar `stattest'=`stattest'+(`nbrealscore0'-`ci0')^2/`ci0'+(`nbrealscore`nbitems''-`ci`nbitems'')^2/`ci`nbitems''
+  }
+
+
+
+/***********************************************************************************************************
+TESTS U
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests U"
+      }
+
+      local quartile=`nbind'/4
+      local c1=0
+      local n1=0
+      while `n1'<`quartile' {
+         local c1=`c1'+1
+         local n1=`n1'+`nbrealscore`c1''
+      }
+      local c2=`nbitems'
+      local n2=0
+      while `n2'<`quartile' {
+         local c2=`c2'-1
+         local n2=`n2'+`nbrealscore`c2''
+      }
+      forvalues j=1/`nbitems' {
+         local zu1=0
+         local zu2=0
+         forvalues s=1/`c1' {
+            local zu1=`zu1'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         forvalues s=`c2'/`=`nbitems'-1' {
+            local zu2=`zu2'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         local U`j'=(`zu1'-`zu2')/sqrt(`c1'+`nbitems'-`c2')
+      }
+   }
+
+
+
+/***********************************************************************************************************
+TESTS OF THE SECOND ORDER /*undocumented in beta test*/
+************************************************************************************************************/
+
+   if "`q2'"!="" {
+      if "`trace'"!="" {
+         di in green "*** Tests of the second order"
+      }
+
+      tempfile Q2file
+      qui save "`Q2file'",replace
+      qui use "`saveraschtest'",replace
+
+      qui keep if `touse'==1
+      gen `score'=0
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'
+	 rename ``i'' `rep'`i'
+	 qui replace `score'=`score'+`rep'`i'
+      }
+      qui recode `score' `recode'
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'=0
+         forvalues j=`=`i'+1'/`nbitems' {
+	    local listinci`i'j`j'
+	    forvalues k=1/`nbitems' {
+	       if `k'!=`i'&`k'!=`j' {
+	          local listinci`i'j`j' "`listinci`i'j`j'' `beta`k''"
+	       }
+	    }
+	 }
+      }
+
+      local Q2tot=0
+      forvalues k=2/`=`nbitems'-1' {
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`i'+1'/`nbitems' {
+	       if `k'==1 {
+	          local num=0
+               }
+	       else {
+	          gammasym `listinci`i'j`j''
+                  local num=r(gamma`=`k'-2')
+               }
+	       local athi`i'j`j'k`k'=exp(-`beta`i'')*exp(-`beta`j'')*`num'/`denom`k''
+	       local bthi`i'j`j'k`k'=`nbth`i's`k''-`athi`i'j`j'k`k''
+	       local cthi`i'j`j'k`k'=`nbth`j's`k''-`athi`i'j`j'k`k''
+	       local dthi`i'j`j'k`k'=1-`athi`i'j`j'k`k''-`bthi`i'j`j'k`k''-`cthi`i'j`j'k`k''
+            }
+         }
+      }
+      forvalues k=1/`=`nbgroups'-1' {
+         local Q2`k'=0
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`j'+1'/`nbitems' {
+	       qui count if  `rep'`i'==1&`rep'`j'==1&`score'==`k'
+	       local aempi`i'j`j'k`k'=r(N)
+	       local ath2i`i'j`j'k`k'=0
+	       local bth2i`i'j`j'k`k'=0
+	       local cth2i`i'j`j'k`k'=0
+	       local dth2i`i'j`j'k`k'=0
+	    }
+	 }
+         if `limsup`k''!=1 {
+            forvalues l=`liminf`k''/`limsup`k'' {
+	       forvalues i=1/`=`nbitems'-1' {
+	          forvalues j=`=`i'+1'/`nbitems' {
+		     if `l'!=1 {
+		        local ath2i`i'j`j'k`k'=`ath2i`i'j`j'k`k''+`athi`i'j`j'k`l''*`nbrealscore`l''
+			local bth2i`i'j`j'k`k'=`bth2i`i'j`j'k`k''+`bthi`i'j`j'k`l''*`nbrealscore`l''
+			local cth2i`i'j`j'k`k'=`cth2i`i'j`j'k`k''+`cthi`i'j`j'k`l''*`nbrealscore`l''
+			local dth2i`i'j`j'k`k'=`dth2i`i'j`j'k`k''+`dthi`i'j`j'k`l''*`nbrealscore`l''
+                     }
+		  }
+               }
+            }
+	    forvalues i=1/`=`nbitems'-1' {
+	       forvalues j=`=`i'+1'/`nbitems' {
+	          local d2i`i'j`j'k`k'=(`aempi`i'j`j'k`k''-`ath2i`i'j`j'k`k'')^2
+		  local Q2i`i'j`j'k`k'=`d2i`i'j`j'k`k''/`ath2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`bth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`cth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`dth2i`i'j`j'k`k''
+		  local Q2i`i'=`Q2i`i''+`Q2i`i'j`j'k`k''
+		  local Q2i`j'=`Q2i`j''+`Q2i`i'j`j'k`k''
+		  local Q2`k'=`Q2`k''+`Q2i`i'j`j'k`k''
+	       }
+	    }
+	 }
+         local Q2tot=`Q2tot'+`Q2`k''
+      }
+      forvalues i=1/`nbitems' {
+         di in green "Item ``i'' : Q2 = `Q2i`i''"
+      }
+      local Q2=`Q2tot'*(`nbitems'-3)/(`nbitems'-1)
+      di in green "Q2 = `Q2tot'"
+      qui use "`Q2file'",replace
+   }
+
+/***********************************************************************************************************
+TEST LR Z
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests LR of Andersen"
+      }
+      local ssll=0
+      tempname Zfile
+      qui save "`Zfile'", replace
+      qui use "`saveraschtest'",replace
+      qui keep if `touse'==1
+      gen `score'=0
+      forvalues j=1/`nbitems' {
+         qui replace `score'=`score'+``j''
+      }
+      qui recode `score' `recode' `nbitems'=`nbgroups'
+      forvalues i=1/`=`nbgroups'-1' {
+         if `effscore`i''>0 {
+            qui raschtestv7 `varlist' if `score'==`i', test(NONE) `ld'  id(`id')
+            local ll`i'=r(cll)
+            local ssll=`ssll'+(`ll`i'')
+         }
+      }
+      local Z=2*`ssll'-2*`ll'
+      use "`Zfile'",replace
+      tempname AndersenZ
+      matrix define `AndersenZ'=(`Z',`=(`nbgroups'-2)*(`nbitems'-1)',1-chi2(`=(`nbitems'-1)*(`nbgroups'-2)',`Z'))
+   }
+}
+
+
+/***********************************************************************************************************
+DISPLAYING RESULTS WITH TESTS
+************************************************************************************************************/
+
+if "`test'"!="NONE" {
+   local conttest= "_c"
+}
+di
+tempname itemfit globalfit
+matrix `globalfit'=J(1,3,0)
+if "`method'"=="cml" {
+   di in green "Estimation method: " in yellow  "Conditional maximum likelihood (CML)"
+   local nbtest=`nbgroups'-1
+   local line=77
+}
+else if "`method'"=="mml"{
+   di in green "Estimation method: " in yellow  "Marginal maximum likelihood (MML)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+else if "`method'"=="gee" {
+   di in green "Estimation method: " in yellow  "Generalized Estimating Equations (GEE)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+if "`test'"=="NONE" {
+   local line=35
+}
+
+di in green  "Number of items: " in yellow  `nbitems'
+
+di in green  "Number of groups: " in yellow  `=`nbgroups'+1' `conttest'
+if "`test'"!="NONE" {
+   di in green " (" in yellow "`nbtest'" in green " of them are used to compute the statistics of test)"
+}
+if "`method'"=="cml" {
+   local nbind=`nbind'+`effscore0'+`effscore`nbgroups''
+   local cont "_c"
+   matrix `itemfit'=J(`nbitems',6,0)
+}
+else {
+   local cont
+   matrix `itemfit'=J(`nbitems',5,0)
+}
+local missing=`N'-`nbind'
+di in green "Number of individuals: " in yellow `N'
+di in green "Number of individuals with missing values: " in yellow `nbindmiss' _c
+if "`ld'"=="" {
+   di in green " (removed)"
+}
+else {
+   di
+}
+di in green  "Number of individuals with nul or perfect score: " in yellow `=`effscore0'+`effscore`nbgroups'''
+if "`method'"=="cml" {
+   di in green  "Conditional log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+else {
+   di in green "Marginal log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+di
+noi di in green  _col(16) "Difficulty" `conttest'
+if "`test'"!="NONE" {
+   di in green _col(58) "Standardized"
+}
+noi di in green _col(9) "Items" _col(16) "parameters" _col(28) "std Err." `conttest'
+if "`test'"!="NONE" {
+   local varin=int(2/sqrt(`nbind')*100)/100
+   local varout=int(6/sqrt(`nbind')*100)/100
+   di _col(41) "`namewp'" _col(47) "df" _col(50) "p-value" _col(58) "Outfit" _col(66) "Infit" `cont'
+   if "`method'"=="cml" {
+      di in green _col(77) "U"
+   }
+}
+di in green  "{hline `line'}"
+forvalues i=1/`nbitems' {
+   noi di in yellow _col(3) %12s abbrev("``i''`fixed`i''" ,12) in yellow _col(18) %8.5f `beta`i'' _col(29) %6.5f `sd`i'' `conttest'
+   if "`test'"!="NONE" {
+      di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfitstd`i'' _col(65) %6.3f `infitstd`i''  /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/  `cont'
+      matrix `itemfit'[`i',1]=`testitems'[`i',1]
+      matrix `itemfit'[`i',2]=`=`nbgroups'-2'
+      matrix `itemfit'[`i',3]=1-chi2(`=`nbgroups'-2',`testitems'[`i',1])
+      matrix `itemfit'[`i',4]=`outfitstd`i''
+      matrix `itemfit'[`i',5]=`infitstd`i''
+      if "`method'"=="cml" {
+         di in ye _col(72) %6.3f `U`i''
+         matrix `itemfit'[`i',6]=`U`i''
+      }
+   }
+}
+di in green  "{hline `line'}"
+if "`test'"!="NONE" {
+   if "`method'"=="cml" {
+      local df=(`nbgroups'-2)*(`nbitems'-1)
+   }
+   else {
+      local df=(`nbgroups'-1)*(`nbitems'-1)-1
+   }
+   matrix `globalfit'=(`stattest',`df',1-chi2(`df',`stattest'))
+   noi di in green _col(6) "`descwp'" _col(32) in gr "`namewp'=" _col(36) in ye %8.3f `globalfit'[1,1] _col(46) %3.0f `globalfit'[1,2] _col(51) %6.4f `globalfit'[1,3]
+   if "`method'"=="cml" {
+      noi di in green _col(6) "Andersen LR test" _col(34) "Z=" in yellow _col(36) %8.3f `AndersenZ'[1,1] _col(46) %3.0f `AndersenZ'[1,2] _col(51) %6.4f `AndersenZ'[1,3]
+   }
+   di in green  "{hline `line'}"
+}
+
+if "`method'"=="cml"&"`meandiff'"==""{
+   di in green "*: The difficulty parameter of this item had been fixed to 0"
+}
+if "`method'"=="cml"&"`meandiff'"!=""{
+   di in green "The mean of the difficulty parameters is fixed to 0"
+}
+if `smallgroup'==1&"`test'"!="NONE" {
+   di in green "You have groups of scores with less than 30 individuals. The tests can be invalid."
+}
+if "`method'"!="cml"&"`test'"=="Q" {
+   di in green "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test."
+}
+
+
+
+di
+if "`method'"!="cml" {
+   di in green  "{hline 56}"
+   noi di in green _col(5) "Parameters" _col(21) "Coef." _col(28) "std Err." _col(43) "z" _col(52) "P>|z|"
+   di in green  "{hline 56}"
+   local zsig=`sig'/`sesig'
+   local pzsig=2*(1-norm(abs(`zsig')))
+   di in green _col(10) in yellow "Sigma" _col(18) %8.5f `sig' _col(29) %6.5f `sesig' _col(38) %6.3f `zsig' _col(50) %7.4f `pzsig'
+   di in green  "{hline 56}"
+}
+*set trace on
+if "`covariables'"!="" {
+   tempname zcovariates pcovariates
+   matrix `zcovariates'=J(1,`nbcovariables',0)
+   matrix `pcovariates'=J(1,`nbcovariables',0)
+   forvalues i=1/`nbcovariables' {
+      local tmp :word `i' of `covariables'
+      local zcov=`betacov'[1,`i']/`Vbetacov'[`i',`i']^.5
+      local pzcov=2*(1-norm(abs(`zcov')))
+      matrix `zcovariates'[1,`i']=`zcov'
+      matrix `pcovariates'[1,`i']=`pzcov'
+      di in green _col(3) %12s in yellow abbrev("`tmp'",12) _col(18) %8.5f `betacov'[1,`i'] _col(29) %6.5f `Vbetacov'[`i',`i']^.5 _col(38) %6.3f `zcov' _col(50) %7.4f `pzcov'
+   }
+   di in green  "{hline 56}"
+   local difficulties2
+   if "`difficulties'"!="" {
+      local difficulties2 diff(`difficulties')
+   }
+   if "`ss1'"!="" {
+      tempfile ss1save
+      qui save `ss1save'
+      qui use `saveraschtest'
+      qui keep if `touse'==1
+
+      qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2'
+      local sigma0=r(sigma)
+      local var0=`sigma0'^2
+      local df0=`N'*`nbitems'-(`nbitems'+1)-1
+      local ss10=`var0'*(`df0')
+      local ss1c0=0
+      di
+      di in green "Type 1 Sum of Squares (sequential)"
+      di "{hline 75}"
+      di in green _col(34) "Degrees" _col(46) "Variance of the"  _col(67) "Explained"
+      di in green _col(4) "Covariates" _col(25) "SS" _col(34) "freedom"_col(49) "latent trait" _col(68) "Variance"
+      di "{hline 75}"
+      di _col(10) in green  "None" _col(15) in ye %12.3f `ss10' _col(37) %4.0f `df0' _col(53) %8.3f `var0'
+      di in green "{dup 75:-}"
+      local covariablesss1
+      forvalues i=1/`nbcovariables' {
+         local covariablesss1 `covariablesss1' `covariable`i''
+         qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss1') test(none)  `ld' `difficulties2'
+         local sigma`i'=r(sigma)
+         local var`i'=`sigma`i''^2
+         local nbcovtmp:word count of `covariablesss1'
+         *di " ss1`i'=`var`i''*`=`N'*`nbitems'-(`nbitems'+1+`nbcovtmp')-1'"
+         local df`i'=`N'*`nbitems'-(`nbitems'+1+`nbcovtmp')-1
+         local ss1`i'=`var`i''* `df`i''
+         di _col(2) %12s in yellow abbrev("`covariable`i''",12) _col(15) %12.3f in ye `=`ss1`=`i'-1''-`ss1`i''' _col(40) %4.0f "1" _col(53) %8.3f `var`i'' _col(71) %5.3f (`=`ss1`=`i'-1''-`ss1`i''')/`ss10'
+      }
+      di in green "{hline 75}"
+      qui use `ss1save'
+   }
+   if "`ss3'"!="" {
+      tempfile ss3save
+      qui save `ss3save'
+      qui use `saveraschtest'
+      qui keep if `touse'==1
+      if "`ss1'"=="" {
+         qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2'
+         local sigma0=r(sigma)
+         local var0=`sigma0'^2
+         local df0=`N'*`nbitems'-(`nbitems'+1)-1
+         local ss30=`var0'*(`df0')
+      }
+      else {
+         local ss30=`ss10'
+      }
+      di
+      di in green "Type 3 Sum of Squares "
+      di "{hline 75}"
+      di in green _col(34) "Degrees" _col(46) "Variance of the"  _col(67) "Explained"
+      di in green _col(4) "Covariates" _col(25) "SS" _col(34) "freedom"_col(49) "latent trait" _col(68) "Variance"
+      di "{hline 75}"
+      di _col(10) in green  "None" _col(15) in ye %12.3f `ss30' _col(37) %4.0f `df0' _col(53) %8.3f `var0'
+      di _col(6) in green  "Complete" _col(15) in ye %12.3f `=`sig'^2*(`df0'+`nbcovariables')' _col(37) %4.0f `=`df0'+`nbcovariables'' _col(53) %8.3f `sig'^2  _col(71) %5.3f 1-`sig'^2*(`df0'+`nbcovariables')/`ss30'
+      di in green "{dup 75:-}"
+      forvalues i=1/`nbcovariables' {
+         local covariablesss3
+         forvalues j=1/`nbcovariables' {
+            if `i'!=`j' {
+               local covariablesss3 `covariablesss3' `covariable`j''
+            }
+         }
+         qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss3') test(none) `ld' `difficulties2'
+         local sigmas`i'=r(sigma)
+         local vars`i'=`sigmas`i''^2
+         local ss3s`i'=`vars`i''*`=`N'-1'
+         local vara`i'=`sig'^2
+         local ss3a`i'=`vara`i''*`=`N'-1'
+         di _col(2) %12s in yellow abbrev("`covariable`i''",12) _col(15) %12.3f in ye `=`ss3s`i''-`ss3a`i''' _col(40) %4.0f "1" _col(53) %8.3f `vars`i'' _col(71) %5.3f (`=`ss3s`i''-`ss3a`i''')/`ss30'
+      }
+      di in green "{hline 75}"
+      qui use `ss3save'
+   }
+}
+
+
+
+/*Tabular of the estimated values of the latent trait*/
+
+if "`covariables'"=="" {
+   di
+   di
+   noi di in green _col(33) "Ability" _col(60) "Expected"
+   noi di in green _col(17) "Group" _col(23) "Score" _col(30) "parameters" _col(42) "std Err." _col(54) "Freq." _col(63) "Score"_c
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      noi di in green _col(75) "ll"
+   }
+   else {
+      noi di ""
+   }
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      local line=62
+   }
+   else {
+     local line=51
+   }
+   di in green _col(17) "{hline `line'}"
+   local nonul=0
+   forvalues g=0/`nbgroups' {
+      if `g'!=0 {
+         di in green _col(17) "{dup `line':-}"
+      }
+      forvalues s=`liminf`g''/`limsup`g'' {
+         if `s'==`liminf`g'' {
+            local tmp `ll`g''
+            local gr `g'
+         }
+         else {
+            local tmp
+            local gr
+         }
+         local expscore`nonul'=0
+         forvalues i=1/`nbitems' {
+            local expscore`nonul'=`expscore`nonul''+1/(1+exp(-`theta`nonul''+`beta`i''))
+         }
+         if "`method'"=="cml" {
+            local format1 %8.3f
+         }
+         else {
+            local format1 %8.5f
+         }
+         noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(32) `format1' `theta`nonul'' _col(42) `format1' `sdtheta`nonul'' _col(55) %4.0f `nbrealscore`s'' _col(64) % 4.2f `expscore`nonul'' _col(68) %11.4f `tmp'
+         local nonul=`nonul'+1
+      }
+   }
+   di in green _col(17) "{hline `line'}"
+}
+if "`method'"=="mml"|"`method'"=="gee" {
+       di
+       *di in green "Variance of the estimated latent trait" _col(45) in ye %10.4f `vartheta'
+       di in green "Mean variance of the error" _col(45) in ye %10.4f `meanse2'
+       local sig2=`sig'^2
+       di in green "Estimated variance of the latent trait" _col(45) in ye %10.4f `sig2'
+       local psi2=1-`meanse2'/`sig2'
+       di in green "Personal Separation Index (PSI)" _col(45) in ye %10.4f `psi2'
+       di in green "Adjusted PSI on covariates (PSIadj)" _col(45) in ye %10.4f `psi'
+}
+
+
+/***********************************************************************************************************
+DETAILS OPTION
+************************************************************************************************************/
+
+if "`details'"!="" {
+   forvalues g=0/`nbgroups' {
+      if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" {
+         di
+         di in  green "{hline 44}"
+         di in green "Group: " in ye "`g'" in green " from " in ye "`liminf`g''" in green " to " in ye "`limsup`g''" in green " (n=" in ye "`nbscore`g''" in green")"
+         di
+         di _col(3) "Item" _col(10) "Observed" _col(23) "Expected" _col(37) "Scaled"
+         di in green "{dup 44:-}"
+      }
+      if `g'!=0&`g'!=`nbgroups' {
+         forvalues j=1/`nbitems' {
+            local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j'])
+            di _col(3) in ye "``j''" _col(14) %4.0f `Obs2'[`j',`g'] _col(25) %6.2f `Th2'[`j',`g'] _col(36) %7.4f `tmp'
+         }
+         di in green "{dup 44:-}"
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `test`g''[1,1]
+      }
+      else if "`method'"!="cml" {
+         if `g'==0 {
+            local h=0
+         }
+         else {
+            local h=`nbitems'
+         }
+         local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'')
+         di in ye _col(14) %4.0f `nbrealscore`h'' _col(25) %6.2f `ci`h'' _col(36) %7.4f `tmp'
+         di in green "{dup 44:-}"
+         local tmp=`tmp'^2
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `tmp'
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION ICC
+************************************************************************************************************/
+*set trace on
+if "`icc'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Items Characteristic Curves"
+   }
+   tempvar proba propemp propth propthb
+   qui replace `tl'=. if `realscore'==0|`realscore'==`nbitems'|`realscore'==.
+   qui gen `propemp'=.
+   qui gen `propth'=.
+   qui gen `propthb'=.
+   label variable `propth' "Expected ICC"
+   label variable `propemp' "Observed ICC"
+   label variable `propthb' "Expected ICC"
+   label variable `tl' "Latent trait"
+   global iccs
+   forvalues i=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui replace `propthb'=exp(`theta`s''-`beta`i'')/(1+exp(`theta`s''-`beta`i'')) if `item'==`i'&`realscore'==`s'
+      }
+      qui replace `propemp'=.
+      qui replace `propth'=.
+      tempvar propemp`i' propth`i'
+      qui bysort `realscore' `item' : egen `propth`i''=mean(`propthb') if `item'==`i'
+      qui bysort `realscore' `item' : egen `propemp`i''=mean(`rep') if `item'==`i'
+      qui replace `propth'=`propth`i'' if `item'==`i'
+      qui replace `propemp'=`propemp`i'' if `item'==`i'
+      local mintl=floor(`theta1')
+      local maxtl=floor(`theta`=`nbitems'-1'')+1
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\icc``i''"
+      }
+      if "`v8'"!="" {
+         graph twoway (line  `propemp' `propth' `tl') if `item'==`i' , name(icc``i'',replace) ytitle("")  ylabel(0(.25)1) title("Observed and Expected ICC for the item ``i''") xlabel(`mintl'(1)`maxtl') `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save icc``i''  "`saving'" , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui graph `propemp' `propth' `tl' if `item'==`i' , twoway `saving' c(ll) ylabel(0(.25)1)   xlabel(`mintl'(1)`maxtl') title("Observed and Expected ICC for the item ``i''")
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION INFORMATION
+************************************************************************************************************/
+
+if "`information'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Information graph"
+   }
+
+   tempfile saveinfo
+   qui save "`saveinfo'",replace
+   tempvar info latent
+   drop _all
+   qui set obs 2001
+   gen `latent'=((_n-1)/1001-1)*3
+   label variable `latent' "latent trait"
+   gen `info'=0
+   forvalues i=1/`nbitems' {
+      qui replace `info'=`info'+exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2
+   }
+   local saving "`dirsave'\\information"
+   if "`v8'"!="" {
+      graph twoway (line  `info' `latent') , name(information,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the scale") `draw'
+      if "`filessave'"!="" {
+         graph save information "`saving'" , `replace'
+      }
+      pause
+   }
+   else {
+      if "`filessave'"!="" {
+         local saving "saving(`saving'"
+         if "`replace'"=="" {
+            local saving "`saving')"
+         }
+         else {
+            local saving "`saving',replace)"
+         }
+      }
+      if "`filessave'"=="" {
+         local saving
+      }
+      qui graph `info' `latent' , twoway  `saving' c(l) xlabel(-3(1)3) title("Information graph of the scale")
+      pause
+   }
+   qui use "`saveinfo'",replace
+}
+
+/***********************************************************************************************************
+OPTION FITGRAPH
+************************************************************************************************************/
+
+if "`fitgraph'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graphical validation of the fit"
+   }
+   *set trace on
+   tempname outfit meanz2 meanv2 sumd infit Voutfit outfitstd Vinfit infitstd
+   qui egen `outfit'=mean(`y2'),by(`id')
+   qui egen `Voutfit'=sum(`r'),by(`id')
+   qui replace `Voutfit'=`Voutfit'/(`nbitems')^2-1/`nbitems'
+   qui gen `outfitstd'=(`outfit'^(1/3)-1)*(3/sqrt(`Voutfit'))-sqrt(`Voutfit')/3
+   qui egen `meanz2'=sum(`z2'),by(`id')
+   qui egen `meanv2'=sum(`v2'),by(`id')
+   qui gen `infit'=`meanz2'/`meanv2'
+   qui egen `Vinfit'=sum(`e'),by(`id')
+   qui replace `Vinfit'=`Vinfit'/(`meanv2')^2
+   qui gen `infitstd'=(`infit'^(1/3)-1)*(3/sqrt(`Vinfit'))-sqrt(`Vinfit')/3
+
+   qui su `outfitstd'
+   local mino=floor(2*min(`r(min)',-2))/2
+   local maxo=ceil(2*max(`r(max)',2))/2
+   qui su `infitstd'
+   local mini=floor(2*min(`r(min)',-2))/2
+   local maxi=ceil(2*max(`r(max)',2))/2
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfitind"
+      local savingi "`dirsave'\\infitind"
+   }
+   if "`v8'"!="" {
+      graph twoway (scatter `outfitstd' `id'), name(outfit,replace) yline(-2 2) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw'
+      pause
+      graph twoway (scatter `infitstd' `id'), name(infit,replace) yline(-2 2) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfit "`savingo'" , `replace'
+         graph save infit "`savingi'" , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitstd' `id', `savingo' twoway sy(.) c(.) yline(-2 2) title("Outfit indexes") b2title("Individual indexes") l1("") l2title("Outfit") ylabel(`mino'(.5)`maxo')
+      pause
+      graph `infitstd' `id', `savingi' twoway sy(.) c(.) yline(-2 2) title("Infit indexes") b2title("Individual indexes") l1("")  l2title("Infit") ylabel(`mini'(.5)`maxi')
+      pause
+   }
+   drop _all
+   qui set obs `nbitems'
+   tempvar name betap outfitstdj infitstdj
+   qui gen str9 `name'=""
+   qui gen `betap'=.
+   qui gen `outfitstdj'=.
+   qui gen `infitstdj'=.
+   local mino=-2
+   local maxo=2
+   local mini=-2
+   local maxi=2
+   forvalues j=1/`nbitems' {
+      qui replace `name'="``j''" in `j'
+      qui replace `betap'=`beta`j'' in `j'
+      qui replace `outfitstdj'=`outfitstd`j'' in `j'
+      qui replace `infitstdj'=`infitstd`j'' in `j'
+      local mino=floor(min(`mino',`outfitstd`j'')*2)/2
+      local mini=floor(min(`mini',`infitstd`j'')*2)/2
+      local maxo=ceil(max(`maxo',`outfitstd`j'')*2)/2
+      local maxi=ceil(max(`maxi',`infitstd`j'')*2)/2
+   }
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfititems"
+      local savingi "`dirsave'\\infititems"
+   }
+   if "`v8'"!="" {
+      graph twoway (scatter `outfitstdj' `betap',name(outfititem,replace) mlabel(`name')), yline(-2 2) title("Outfit indexes") xtitle("Difficulty") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw'
+      pause
+      graph twoway (scatter `infitstdj' `betap',name(infititem,replace) mlabel(`name')), yline(-2 2) title("Infit indexes") xtitle("Difficulty") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfititem "`savingo'" , `replace'
+         graph save infititem "`savingi'" , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitstdj' `betap', `savingo' twoway c(.) yline(-2 2) title("Outfit indexes") b2title("Difficulty") l1title("") l2title("Outfit") ylabel(`mino'(.5)`maxo') sy([`name'])
+      pause
+      graph `infitstdj' `betap', `savingi' twoway c(.) yline(-2 2) title("Infit indexes") b2title("Difficulty") l1title("") l2title("Infit") ylabel(`mini'(.5)`maxi') sy([`name'])
+      pause
+   }
+}
+
+
+/***********************************************************************************************************
+OPTION SPLITTESTS
+************************************************************************************************************/
+
+if "`splittests'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Splitting tests"
+   }
+   forvalues j=1/`nbitems' {
+      tempname estneg`j' estpos`j'
+      local listitems
+      forvalues k=1/`nbitems' {
+         if `j'!=`k' {
+            local listitems `listitems' ``k''
+         }
+      }
+      qui use "`saveraschtest'",replace
+      qui keep if `touse'==1
+      qui raschtestv7 `listitems' if ``j''==0,test(NONE) meth(cml) `ld' id(`id')
+      matrix `estneg`j''=r(beta)
+      local llneg=r(cll)
+      qui raschtestv7 `listitems' if ``j''==1,test(NONE) meth(cml) `ld'  id(`id')
+      matrix `estpos`j''=r(beta)
+      local llpos=r(cll)
+      qui raschtestv7 `listitems',test(NONE) meth(cml) `ld' id(`id')
+      local llnegpos=r(cll)
+      local nbcol=colsof(`estneg`j'')
+      local meanneg=0
+      local meanpos=0
+      forvalues k=1/`nbcol' {
+         local meanneg=`meanneg'+`estneg`j''[1,`k']
+         local meanpos=`meanpos'+`estpos`j''[1,`k']
+      }
+      local meanneg=`meanneg'/`nbitems'
+      local meanpos=`meanpos'/`nbitems'
+      forvalues k=1/`nbcol' {
+         matrix `estneg`j''[1,`k']=`estneg`j''[1,`k']-`meanneg'
+         matrix `estpos`j''[1,`k']=`estpos`j''[1,`k']-`meanpos'
+         if "`method'"=="cml" {
+            matrix `estneg`j''=`estneg`j'',-`meanneg'
+            matrix `estpos`j''=`estpos`j'',-`meanpos'
+         }
+      }
+      drop _all
+      qui set obs `=`nbitems'+1'
+      tempvar neg pos name diag
+      qui gen `neg'=.
+      qui gen `pos'=.
+      qui gen str9 `name'=""
+      local min=`estneg`j''[1,1]
+      local max=`estneg`j''[1,1]
+      forvalues k=1/`=`nbitems'-1' {
+         qui replace `neg'=`estneg`j''[1,`k'] in `k'
+         qui replace `pos'=`estpos`j''[1,`k'] in `k'
+         local min=min(`min',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local max=max(`max',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local tmp:word `k' of `listitems'
+         qui replace `name'="`tmp'" in `k'
+      }
+      local min=floor(`min')
+      local max=floor(`max')+1
+      qui gen `diag'=.
+      qui replace `diag'=`min' in `nbitems'
+      qui replace `diag'=`max' in `=`nbitems'+1'
+      local Zgr=round(2*(`llneg'+`llpos'-`llnegpos'),0.001)
+      local Zgr=substr("`Zgr'",1,6)
+      local pgr=round(1-chi2(`=`nbitems'-1',`Zgr'),0.0001)
+      local pgr=substr("`pgr'",1,5)
+      local note="Z=`Zgr', df=`=`nbitems'-1' , p=`pgr'"
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\split``j''"
+      }
+      if "`v8'"!="" {
+         graph twoway (scatter `pos' `neg' ,mlabel(`name')) (line `diag' `diag'), ytitle("Positive answer") xtitle("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title(Splitting on ``j'') `draw' legend(off) note("Andersen Z test: `note'") name(split,replace) `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save split "`saving'" , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui replace `diag'=`neg' if `diag'==.
+         graph  `pos' `diag' `diag', `saving' c(.l) sy([`name']i) l1title("") l2title("Positive answer") b2title("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title("Splitting on ``j'' (`note')") `draw'
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION GRAPH
+************************************************************************************************************/
+
+if "`graph'"!=""&"`v8'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graph option"
+   }
+   tempvar  latent2  tl2 delta2 tlth2 labdelta2 labtl2
+   drop _all
+   qui set obs 1001
+   gen `latent2'=(_n-501)/100
+   label variable `latent2' "latent trait"
+   qui gen `tl2'=.
+   qui gen `labtl2'=""
+   forvalues i=0/`nbitems' {
+      *if (`i'!=0&`i'!=`nbitems')|"`method'"!="cml" {
+         qui replace `tl2'=`nbrealscore`i''/`N' if round(`latent2',0.01)==round(`theta`i'',0.01)
+         qui replace `labtl2'="`i'" if round(`latent2',0.01)==round(`theta`i'',0.01)
+      *}
+   }
+   qui gen `delta2'=.
+   qui gen `labdelta2'=""
+   forvalues i=1/`nbitems' {
+      qui replace `delta2'=-.05 if round(`latent2',0.01)==round(`beta`i'',0.01)
+      qui replace `labdelta2'="``i''" if round(`latent2',0.01)==round(`beta`i'',0.01)
+   }
+   if "`method'"=="mml"|"`method'"=="gee" {
+      qui gen `tlth2'=1/(2*_pi*`sig')*exp(-.5*(`latent2'/`sig')^2)
+      label variable `tlth2' "Theorical distribution"
+      local graphmml line `tlth2' `latent2'
+   }
+   label variable `tl2' "Score"
+   label variable `delta2' "Items"
+   local saving "`dirsave'\\graph"
+   local min=-2
+   local max=2
+   forvalues j=1/`nbitems' {
+      if `beta`j''<`min' {
+         local min=`beta`j''-.5
+      }
+      if `beta`j''>`max'&`beta`j''!=. {
+         local max=`beta`j''+.5
+      }
+   }
+   if "`method'"=="cml" {
+      if `theta0'<`min' {
+         local min=`theta0'-.5
+      }
+      if `theta`=`nbitems'-1''>`max' {
+         local max=`theta`=`nbitems'-1''+.5
+      }
+   }
+   else if "`method'"!="cml" {
+      if `theta0'<`min'&`theta0'!=. {
+         local min=`theta0'-.5
+      }
+      if `theta`nbitems''>`max'&`theta`nbitems''!=. {
+         local max=`theta`nbitems''+.5
+      }
+   }
+   local min=floor(`min')
+   local max=floor(`max')+1
+   qui su `tl2'
+   local max2=r(max)
+   if "`method'"!="cml" {
+      qui su `tlth2'
+      local max2=max(`max2',`r(max)')
+   }
+   qui replace `latent2'=. if `latent2'<`min'|`latent2'>`max'
+   if "`v8'"!="" {
+      graph twoway (bar `tl2' `latent2',/*mlabel(`labtl2')*/ barwidth(.3) ) (dropline `delta2' `latent2',mlabel(`labdelta2') mlabposition(6)) (`graphmml'), name(graph,replace) ytitle("") xlabel(`min'(1)`max') ylabel(-.1 0(0.05)`max2') title("Individuals/items representations") `draw'
+      if "`filessave'"!="" {
+         graph save graph "`saving'" , `replace'
+      }
+      pause
+   }
+}
+else if "`graph'"!=""&"`v8'"=="" {
+   di in ye "The graph option is not available with Stata 7"
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATION
+************************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+      di
+      di _col(4) "{hline 30}"
+      di _col(4) in green "Comparison of two populations"
+      di _col(4) "{hline 30}"
+      di
+      di _col(4) in green "`comp'==`mincomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmin' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmin' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmin'
+      di _col(4) in green "`comp'==`maxcomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmax' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmax' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmax'
+      di                                                                       _col(33) in green "Z= " _col(35) in yellow %8.4f `Zcomp' _col(47) in green "pvalue= "    _col(57) in yellow %6.4f `pvalue'
+}
+
+/***********************************************************************************************************
+TEST DIF
+************************************************************************************************************/
+
+if "`method'"=="cml"&"`dif'"!=""&"`test'"!="NONE" {
+   if "`trace'"!="" {
+      di in green "*** Tests of DIF"
+   }
+   local ssll=0
+   tempname DIFfile
+   qui save "`DIFfile'", replace
+   qui use "`saveraschtest'",replace
+   qui keep if `touse'==1
+   unab list:`dif'
+   local nbdif:word count `list'
+   tempname DIF
+   matrix define `DIF'=J(`nbdif',4,0)
+   local count=1
+   di
+   di _col(4) in green "{hline 45}"
+   di _col(4) in green "Test of Differential Item Functioning (DIF)"
+   di _col(4) in green "{hline 45}"
+   foreach j in `list' {
+      qui inspect `j'
+      local nbdif=r(N_unique)
+      qui su `j'
+      local maxdif=r(max)
+      if `nbdif'>10&`maxdif'<=10 {
+         di in ye "The {hi:dif} option is available with variables containing 10 or less modalities (coded from 0 or 1 to k<10)."
+         di in ye "The variable `j' (`nbdif' modalities) is omitted."
+      }
+      else {
+         local ssll=0
+         forvalues i=0/10 {
+            qui count if `j'==`i'
+            local effdif=r(N)
+            if `effdif'>0 {
+               qui raschtestv7 `varlist' if `j'==`i', test(NONE) id(`id')
+               local ll`i'=r(cll)
+               local ssll=`ssll'+(`ll`i'')
+            }
+         }
+         local Z=2*`ssll'-2*`ll'
+         local ddl=(`nbdif'-1)*(`nbitems'-1)
+         matrix define `DIF'[`count',1]=(`count',`Z',`ddl',1-chi2(`ddl',`Z'))
+         di
+         di _col(4) in green "Variable:" in ye " `j' " in green "   Number of groups: "  in ye "`nbdif'"
+         di _col(4) in green "LR Test Z=" in ye %8.3f `Z' in gr "   ddl=" in ye %4.0f `ddl' in gr "    p-value=" in ye %6.4f `=1-chi2(`ddl',`Z')'
+         di
+      }
+      local ++count
+   }
+   use "`DIFfile'",replace
+}
+
+/***********************************************************************************************************
+RETURN
+************************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Returns"
+}
+local colnametheta
+
+forvalues i=0/`nbgroups' {
+         local colnametheta `colnametheta' score_`i'
+}
+
+
+return clear
+
+if `nbitems'>=3&"`test'"!="NONE" {
+        matrix colnames `globalfit'=`namewp' df p
+	matrix rownames `globalfit'=`method'
+	matrix rownames `itemfit'=`varlist'
+        matrix roweq `itemfit'=`method'
+
+	if "`method'"=="cml" {
+                matrix colnames `itemfit'=`namewp' df p outfit infit U
+		matrix rownames `AndersenZ'=`method'
+		matrix colnames `AndersenZ'=Z df p
+		return matrix AndersenZ=`AndersenZ'
+                if "`dif'"!="" {
+		   matrix rownames `DIF'=`list'
+		   matrix colnames `DIF'=num Z df p
+		   return matrix DIF=`DIF'
+                }
+	}
+	else {
+                matrix colnames `itemfit'=`namewp' df p outfit infit
+	}
+	return matrix itemFit=`itemfit'
+	return matrix globalFit=`globalfit'
+}
+
+matrix colnames `theta'=`colnametheta'
+matrix rownames `theta'=theta
+return matrix theta `theta'
+matrix colnames `sdtheta'=`colnametheta'
+matrix rownames `sdtheta'=`colnametheta'
+return matrix Vartheta `sdtheta'
+local varlist2
+matrix coleq `beta'=`method'
+matrix coleq `Vbeta'=`method'
+matrix roweq `Vbeta'=`method'
+if "`method'"=="cml" {
+	forvalues i=1/`=`nbitems'-1' {
+		local varlist2 `varlist2' ``i''
+	}
+        return scalar cll=`ll'
+        return scalar ll=`globalll'
+	local AIC=-2*`globalll'+2*(`nbitems'-1)
+}
+else {
+        return scalar ll=`ll'
+	local varlist2 `varlist'
+	return scalar sigma=`sig'
+	return scalar sesigma=`sesig'
+	local AIC=-2*`ll'+2*(`nbitems'+1)
+}
+
+if "`comp'"!="" {
+   return scalar Zcomp=`Zcomp'
+   return scalar pZcomp=`pvalue'
+}
+
+matrix colnames `beta'=`varlist2'
+matrix rownames `beta'=beta
+return matrix beta `beta'
+
+matrix colnames `Vbeta'=`varlist2'
+matrix rownames `Vbeta'=`varlist2'
+return matrix Varbeta `Vbeta'
+
+return scalar AIC=`AIC'
+return scalar N=`nbind'
+
+if "`method'"=="mml" {
+   return scalar PSI=`psi2'
+   return scalar PSIadj=`psi'
+}
+if "`covariables'"!="" {
+   local tmp
+   local tmp2
+   forvalues i=1/`nbcovariables' {
+      local tmp `tmp' `covariable`i''
+      local tmp2 "`tmp2' :`covariable`i''"
+   }
+   matrix colnames `betacov'=`tmp2'
+   matrix rownames `Vbetacov'=`tmp2'
+   matrix colnames `Vbetacov'=`tmp2'
+   matrix colnames `zcovariates'=`tmp'
+   matrix colnames `pcovariates'=`tmp'
+   return matrix betacovariates=`betacov'
+   return matrix Vbetacovariates=`Vbetacov'
+   return matrix zcovariates=`zcovariates'
+   return matrix pcovariates=`pcovariates'
+}
+if "`pause'"!="" {
+   pause off
+}
+
+drop _all
+
+restore,not
+use "`saveraschtest'"
+
+/***********************************************************************************************************
+CREATE EVENTUAL NEW VARIABLES
+************************************************************************************************************/
+
+*set trace on
+if "`genres'"!="" {
+   qui sort `id'
+   qui merge `id' using `ltsave'
+   qui rename `u'm1 `genlt'
+   qui rename `u's1 se`genlt'
+   qui drop _merge se`genlt'
+   forvalues i=1/`nbitems' {
+      gen `genres'`i'=exp(``i''*(`genlt'-`beta`i''))/(1+exp(`genlt'-`beta`i''))/sqrt(exp(`genlt'-`beta`i'')/(1+exp(`genlt'-`beta`i''))^2)
+   }
+   corr `genres'*
+   pca `genres'*
+   drop `u'm1
+}
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+        tempname genlt2 genscore2 outfit2 infit2
+        qui gen `score'=0 `if'
+        forvalues i=1/`nbitems' {
+           qui replace `score'=`score'+``i'' `if'
+        }
+        if "`genscore'"!="" {
+           qui gen `genscore'=`score' `if'
+        }
+        if "`genlt'"!="" {
+           if "`replacegenlt'"=="replace" {
+              capture drop `genlt'
+              capture drop se`genlt'
+           }
+           if "`method'"=="mml" {
+              qui sort `id'
+              qui merge `id' using `ltsave'
+              qui rename `u'm1 `genlt'
+              qui rename `u's1 se`genlt'
+              qui drop _merge
+           }
+           else if "`method'"!="mml" {
+              qui gen `genlt2'=. `if'
+              forvalues i=0/`nbitems' {
+                 qui replace `genlt2'=`theta`i'' `if'&`score'==`i'
+              }
+              qui gen `genlt'=`genlt2' `if'
+           }
+        }
+        if "`genfit'"!="" {
+           local outfit:word 1 of `genfit'
+           local infit:word 2 of `genfit'
+           qui gen `outfit'=0 `if'
+           qui gen `infit'=0  `if'
+           tempname infit1 infit2
+           qui gen `infit1'=0 `if'
+           qui gen `infit2'=0 `if'
+           forvalues j=1/`nbitems' {
+               tempname pi`j'
+               qui gen `pi`j''=exp(`genlt2'-`beta`j'')/(1+exp(`genlt2'-`beta`j'')) `if'
+               qui replace `pi`j''=0  `if'
+               forvalues s=1/`nbitems' {
+                  qui replace `pi`j''=`Pi'[`j',`s'] `if'&`score'==`s'
+               }
+               qui gen `outfit'``j''=(``j''-`pi`j'')^2/(`pi`j''*(1-`pi`j'')) `if'
+               qui replace `infit1'=`infit1'+(``j''-`pi`j'')^2  `if'
+               qui replace `infit2'=`infit2'+(`pi`j''*(1-`pi`j'')) `if'
+               qui replace `outfit'=`outfit'+`outfit'``j''/`nbitems' `if'
+           }
+           qui replace `infit'=`infit1'/`infit2'  `if'
+        }
+}
+
+if "`trace'"!=""|"`time'"!="" {
+    capture qui elapse `st'
+    di in green "** Time : " in yellow "$S_elap " in green "seconds"
+}
+
+end
diff --git a/Modules/ado/personal/r/old/raschtestv7jf.ado b/Modules/ado/personal/r/old/raschtestv7jf.ado
new file mode 100644
index 0000000..35b27f3
--- /dev/null
+++ b/Modules/ado/personal/r/old/raschtestv7jf.ado
@@ -0,0 +1,2239 @@
+*! version 8.2  15july2009
+*! Jean-Benoit Hardouin
+*************************************************************************************************************
+* Raschtestv7: Rasch model, fit tests and graphical representations
+* Corresponds to the version 8 of Raschtest (http://freeirt.org) for Stata7
+*
+* Historic:
+* Version 2.1 (2003-07-10): Jean-Benoit Hardouin
+* Version 3.1 (2004-01-02) : Jean-Benoit Hardouin
+* Version 7.1 (2005-03-30) : Jean-Benoit Hardouin
+* Version 7.2.1 (2005-05-21) : Jean-Benoit Hardouin
+* Version 7.3.1 (2005-07-02) : Jean-Benoit Hardouin
+* Version 7.3.2 (2005-10-05) : Jean-Benoit Hardouin /*correction for the *genlt* option with *method(cml)**/
+* Version 7.3.3 (2005-12-21) : Jean-Benoit Hardouin /*correction if scores are not represented with method(mml) or method(gee)*/
+* Version 7.4.1 (2006-01-17) : Jean-Benoit Hardouin /*Standardized OUTFIT and INFIT, DIF option*/
+* Version 7.4.2 (2006-03-21) : Jean-Benoit Hardouin /*Avoids a bug when the temporary files are saved in a directory containing special characters*/
+* Version 7.4.3 (2006-11-15) : Jean-Benoit Hardouin /*Avoids a bug when the directory defined in the dirsave option contains special characters*/
+* Version 7.5.1 (2007-04-20) : Jean-Benoit Hardouin /*Return results of the comp option*/
+* Version 7.6.1 (2008-06-26) : Jean-Benoit Hardouin /*Nold option, corrects a bug with the genlt option*/
+* Version 7.6.2 (2009-03-01) : Jean-Benoit Hardouin /*Correction of the SE of the latent trait, graph option, correction of a bug with the if option, PSI in MML*/
+* Version 8.1 (2009-06-24) : Jean-Benoit Hardouin /*DIFFICULTIES option, COVARIATES option*/
+* Version 8.2 (2009-07-15) : Jean-Benoit Hardouin /*Correction of a bug with CML*/
+*
+* Needed modules :
+* gammasym version 2.2 (http://www.freeirt.org)
+* gausshermite version 1 (http://www.freeirt.org)
+* geekel2d version 4.3 (http://www.freeirt.org)
+* genscore version 1.4 (http://www.freeirt.org)
+* ghquadm (findit ghquadm)
+* gllamm version 2.3.14 (ssc describe gllamm)
+* gllapred version  2.3.7 (ssc describe gllapred)
+* elapse (ssc describe elapse)
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2003-2009 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+DEFINITION / SYNTAX
+***********************************************************************************************************/
+
+
+program define raschtestv7jf,rclass
+syntax varlist(min=1 numeric) [if] [in] , ID(varname) [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph v8 COMp(varname) dif(varlist) time TRace Details  nold iterate(int 200) DIFFiculties(string) COVariates(string) ]
+
+local covariables `covariates'
+
+if "`if'"=="" {
+   local if "if 1"
+}
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Tests of conformity"
+}
+if "`v8'"=="" {
+        version 7.0
+}
+else {
+        version 8.0
+}
+
+local st = "$S_TIME"
+local nbitems : word count `varlist'
+marksample touse ,novarlist
+if "`covariables'"!="" {
+   tokenize "`covariables'",parse(" ,")
+   local i=1
+   local tcovariables
+   while "``i''"!=","&"``i''"!="" {
+     local covariable`i' ``i''
+     local tcovariables `tcovariables' ``i''
+     local ++i
+   }
+   local nbcovariables=`i'-1
+   local ss1
+   local ss3
+   if "``i''"=="," {
+      forvalues j=`=`i'+1'/`=`i'+2' {
+         if "``j''"=="ss1" {
+            local ss1 ss1
+         }
+         else if "``j''"=="ss3" {
+            local ss3 ss3
+         }
+         else if "``j''"=="" {
+*            di in green "option `j' vide"
+         }
+         else {
+            di in red "Invalid option in the {hi:covariables} option"
+            error 198
+         }
+      }
+      local i=`i'+3
+      if "``i''"!="" {
+         di in red "There is too much options in the {hi:covariates} option."
+         error 198
+      }
+   }
+   local covariables `tcovariables'
+}
+else {
+   local nbcovariables=0
+}
+
+isid `id'
+tokenize `varlist'
+
+local bad
+forvalues i=1/`nbitems' {
+   qui count if ``i''!=0&``i''!=1&``i''!=.
+   local N=r(N)
+   if `N'>0 {
+      local bad `bad' ``i''
+   }
+}
+if "`bad'"!="" {
+   di in red "The item(s) {hi:`bad'} is(are) not binary item(s) (with responses 0 or 1)."
+   exit
+}
+
+
+
+if "`method'"=="" {
+    local method cml
+}
+if "`test'"=="" {
+    local test R
+}
+local method=lower("`method'")
+local test=upper("`test'")
+if "`method'"!="mml"&"`method'"!="cml"&"`method'"!="gee" {
+    di in red "Uncorrect method option."
+    error 198
+    exit
+}
+
+if "`test'"!="R"&"`test'"!="Q"&"`test'"!="WP"&"`test'"!="NONE" {
+   di in red "Uncorrect test option."
+   error 198
+   exit
+}
+
+if "`genfit'"!="" {
+   local nbwordgenfit:word count `genfit'
+   if `nbwordgenfit'!=2 {
+      di in red "Uncorrect genfit option."
+      di in red "This option must contain exactly two words"
+      error 198
+      exit
+   }
+}
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+   capture confirm new variable `genfit' `genscore'
+   if "`genfit'"!="" {
+      local o:word 1 of `genfit'
+      forvalues i=1/`nbitems' {
+         confirm new variable `o'``i''
+      }
+   }
+   if "`genlt'"!="" {
+       local 0 `genlt'
+       gettoken left  0: 0,parse(",")
+       gettoken right  0: 0,parse(",")
+       local genlt `left'
+       local replacegenlt `0'
+       local length=length("`replacegenlt'")
+       if `length'>=3&substr("`replacegenlt'",1,`length')==substr("replace",1,`length') {
+          local replacegenlt replace
+       }
+       if "`replacegenlt'"!="replace"&"`replacegenlt'"!="" {
+           di "Not allowed option in the {hi:genlt} option"
+           error 198
+       }
+       else if "`replacegenlt'"=="" {
+           confirm new variable `genlt'
+       }
+   }
+}
+
+preserve
+
+tempfile saveraschtest
+qui save `saveraschtest'
+
+
+qui keep if `touse'==1
+
+if "`autogroup'"!=""&"`group'"!="" {
+   di in green "The autogroup and the group options cannot be defined in the same time"
+   di in green "Only the group option is retained."
+   local autogroup
+}
+
+if "`autogroup'"!="" {
+   tempvar autoscore
+   qui genscore `varlist',score(`autoscore')
+
+   tempname matscore tmp
+   matrix `matscore'=J(`=`nbitems'-1',3,0)
+   forvalues i=1/`=`nbitems'-1' {
+        matrix `matscore'[`i',1]=`i'
+        matrix `matscore'[`i',2]=`i'
+        qui count if `autoscore'==`i'
+        matrix `matscore'[`i',3]=r(N)
+   }
+   local stop=0
+   local j=0
+   while `j'<=`=`nbitems'-3'&`stop'!=1 {
+      local j=`j'+1
+      local scoretogroup=99999999
+      local rowtogroup1=0
+      local rowtogroup2=0
+      local stop=1
+      forvalues i=1/`=`nbitems'-`j'' {
+         if `matscore'[`i',1]>=0 & `matscore'[`i',3]<30 & `matscore'[`i',3]<`scoretogroup' {
+            local scoretogroup=`matscore'[`i',3]
+            local rowtogroup1=`i'
+            local stop=0
+         }
+      }
+      if `stop'!=1 {
+         if `rowtogroup1'>1&`rowtogroup1'<`=`nbitems'-`j'' {
+            if `matscore'[`=`rowtogroup1'-1',1]<`matscore'[`=`rowtogroup1'+1',1] {
+               local rowtogroup2=`rowtogroup1'
+               local rowtogroup1=`rowtogroup1'-1
+            }
+            else {
+               local rowtogroup2=`rowtogroup1'+1
+            }
+         }
+         else if `rowtogroup1'==1 {
+            local rowtogroup2=2
+         }
+         else if `rowtogroup1'==`=`nbitems'-`j'' {
+            local rowtogroup2=`nbitems'-`j'
+            local rowtogroup1=`nbitems'-`j'-1
+         }
+         matrix `tmp'=`matscore'
+         matrix `matscore'=J(`=`nbitems'-`j'',3,0)
+         if `rowtogroup1'!=1 {
+            matrix `matscore'[1,1]=`tmp'[1..`=`rowtogroup1'-1',1..3]
+         }
+         matrix `matscore'[`rowtogroup1',1]=`tmp'[`rowtogroup1',1]
+         matrix `matscore'[`rowtogroup1',2]=`tmp'[`rowtogroup2',2]
+         matrix `matscore'[`rowtogroup1',3]=`tmp'[`rowtogroup1',3]+`tmp'[`rowtogroup2',3]
+         if `rowtogroup2'!=`=`nbitems'-`j'' {
+            matrix `matscore'[`rowtogroup2',1]=`tmp'[`=`rowtogroup2'+1'..`=`nbitems'-`j'',1..3]
+         }
+      }
+   }
+   local nbrows=rowsof(`matscore')-1
+   local thresholds
+   forvalues i=1/`nbrows' {
+      local tmp=`matscore'[`i',2]
+      local thresholds `thresholds' `tmp'
+   }
+   local group `thresholds'
+}
+
+
+if "`group'"=="" {
+	forvalues i=1/`=`nbitems'-1' {
+		local group "`group' `i'"
+	}
+}
+local nbgroups:word count `group'
+local groupmax:word `nbgroups' of `group'
+if `groupmax'>=`nbitems' {
+	di in red "You cannot form a group with the higher possible score."
+	di in red "The higher possible value of the group option is `=`nbitems'-1'."
+        di in red "Please correct your group option."
+	error 198
+        exit
+}
+else {
+	if `groupmax'!=`=`nbitems'-1' {
+		local group "`group' `=`nbitems'-1'"
+		local nbgroups=`nbgroups'+1
+	}
+}
+local nbgroups=`nbgroups'+1
+
+if "`dirsave'"!=""&"`filessave'"=="" {
+        di in ye "If you want to save yours graphs, use the filessave option"
+}
+if "`filessave'"!="" {
+        if "`dirsave'"=="" {
+              local dirsave "`c(pwd)'"
+        }
+        di in ye "The graphs files will be saved in `dirsave'"
+}
+if "`dirsave'"!="" {
+        if "`filesave'"=="" {
+              local filesave "filesave"
+        }
+}
+
+
+if "`pause'"!=""&"`draw'"=="" {
+     pause on
+}
+
+if "`difficulties'"!="" {
+    capture confirm matrix `difficulties'
+    if _rc!=0  {
+	di in red "The vector `difficulties' defined in the {hi:difficulties} option does not exist."
+	error 198
+        exit
+    }
+}
+
+if "`difficulties'"!=""&"`method'"!="mml" {
+   di in red "The {hi:difficulties} option can be defined only for MML method."
+   error 198
+   exit
+}
+
+if "`covariables'"!=""&"`method'"!="mml" {
+   di in red "The {hi:covariables} option can be defined only for MML method."
+   error 198
+   exit
+}
+if "`covariables'"!=""&"`comp'"!="" {
+   di in red "The {hi:covariables} and {hi:comp} options can be defined jointly."
+   error 198
+   exit
+}
+
+
+
+
+
+/***********************************************************************************************************
+POSSIBLE TEST
+***********************************************************************************************************/
+
+if ("`icc'"!=""|"`fitgraph'"!=""|"`splittest'"!=""|"`details'"!="")&"`test'"=="NONE" {
+	di in green "You cannot use the {hi:details}, {hi:icc}, {hi:fitgraph} or {hi:splittest} options if you use {hi:test(none)}."
+        di in green "These options are ignored."
+	local details
+	local icc
+	local fitgraph
+	local splittest
+}
+if "`comp'"!=""&"`method'"=="cml" {
+   	di in green "You cannot compare two populations ({hi:comp} option) with the CML estimation method"
+   	di in green "This option is ignored."
+        local comp
+}
+if "`method'"!="cml"&"`test'"=="WP" {
+	di in green "The Wright-Panchapakesan test is not authorized with MML or GEE."
+	di in green "The WP tests are replaced by Van den Wollenberg Q tests."
+        local test Q
+}
+if "`method'"=="gee"&"`ld'"!="" {
+	di in green "You cannot use the {hi:nold} option with the GEE method of estimation"
+	di in green "This option is ignored."
+        local ld
+}
+
+
+if "`test'"==""|"`test'"=="R" {
+   local test "R"
+   if "`method'"=="cml" {
+      local namewp "R1c"
+      local descwp "R1c test"
+   }
+   else {
+      local namewp="R1m"
+      local descwp "R1m test"
+   }
+}
+if `nbitems'>999999|"`test'"=="WP" {
+	local namewp "  Y"
+	local descwp "Wright-Panchapakesan Y test"
+	local q2
+}
+ else if "`test'"=="Q" {
+	local namewp " Q1"
+	local descwp "Van den Wollenberg Q1 test"
+}
+
+if "`method'"!="cml"&"`meandiff'"!="" {
+	di in green "The {hi:meandiff} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local meandiff
+}
+
+if "`method'"!="cml"&"`splittests'"!="" {
+	di in green "The {hi:splittests} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local splittests
+}
+if "`method'"!="cml"&"`dif'"!="" {
+	di in green "The {hi:dif} option is not available with MML or GEE."
+	di in green "This option is ignored."
+        local dif
+}
+
+/***********************************************************************************************************
+SCORES AND GROUPS
+************************************************************************************************************/
+
+qui count if `touse'==1
+local N=r(N)
+
+qui keep `varlist' `comp' `covariables' `id' `touse'
+
+tempname rep item
+tempvar score realscore
+qui genscore `varlist',score(`score')
+qui count if `score'==.&`touse'==1
+local nbindmiss=r(N)
+
+if "`ld'"=="" {
+   qui drop if `score'==.
+}
+forvalues i=1/`nbitems' {
+	rename ``i'' `rep'`i'
+}
+
+
+
+local liminf0=0
+local limsup0=0
+local liminf`nbgroups'=`nbitems'
+local limsup`nbgroups'=`nbitems'
+
+
+local recode
+forvalues i=1/`=`nbgroups'-1' {
+	if `i'!= 1{
+		local liminf`i' : word `=`i'-1' of `group'
+	}
+	else {
+		local liminf1=0
+	}
+	local liminf`i'=`liminf`i''+1
+	local limsup`i':word `i' of `group'
+
+	local recode "`recode' `liminf`i''/`limsup`i''=`i'"
+}
+qui gen `realscore'=`score'
+qui recode `score' `recode' `nbitems'=`nbgroups'
+
+local smallgroup=0
+
+forvalues i=0/`nbgroups' {
+	qui count if `score'==`i'
+	local effscore`i'=r(N)
+	if `i'!=0&`i'!=`nbgroups'&`effscore`i''<30 {
+		local smallgroup=1
+	}
+}
+/***********************************************************************************************************
+ESTIMATION OF THE DIFFICULTY PARAMETERS
+************************************************************************************************************/
+if "`trace'"!="" {
+  di in green "*** Estimation of the difficulty parameters"
+}
+
+
+if "`covariables'"!="" {
+  forvalues i=1/`nbcovariables' {
+     qui su `covariable`i''
+     local mean`covariable`i''=r(mean)
+     qui replace `covariable`i''=`covariable`i''-`mean`covariable`i'''
+  }
+}
+
+tempname ll coef var beta Vbeta est
+
+if "`method'"=="gee" {
+   qui geekel2d `rep'1-`rep'`nbitems',ll
+   if `r(error)'==1 {
+       di "The variance of the latent trait probably is too high to made the GEE a efficient method to estimate the parameters."
+       error 499
+       exit
+   }
+   scalar `ll'=r(ll)
+   local nbind=r(N)
+   matrix `coef'=r(b)
+   matrix `est'=`coef'
+   matrix `est'[1,`=`nbitems'+1']=sqrt(`est'[1,`=`nbitems'+1'])
+   matrix `var'=r(V)
+   matrix `beta'=`coef'[1,1..`nbitems']
+   matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+   local sig=sqrt(`coef'[1,`=`nbitems'+1'])
+   local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])/sqrt(`nbind')/(`sig'*2)
+}
+
+qui reshape long `rep', i(`id') j(`item')
+
+tempvar diff tl
+gen `diff'=0
+
+forvalues i=1/`nbitems' {
+	qui gen `rep'`i'=`item'==`i'
+	qui replace `rep'`i'=-`rep'`i'
+}
+
+
+if "`method'"=="mml" {
+   if "`difficulties'"==""{
+      qui xtlogit `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') nocons iterate(`iterate')
+      matrix `est'=e(b)
+      matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`est'[1,`=`nbitems'+`nbcovariables'+1']/2)
+   }
+   else {
+      tempname offset b
+      qui gen `offset'=0
+      forvalues i=1/`nbitems' {
+          qui replace `offset'=-(`difficulties'[1,`i']) if `item'==`i'
+      }
+      qui gllamm `rep' `covariables'  , offset(`offset') i(`id') nocons iterate(`iterate') link(logit) fam(bin)
+      matrix `b'=e(b)
+      matrix `est'=`difficulties',`b'
+      matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`b'[1,`=`nbcovariables'+1']/2)
+   }
+}
+else if "`method'"=="cml" {
+	qui clogit `rep' `rep'1-`rep'`=`nbitems'-1' , group(`id')
+}
+
+
+if "`method'"!="gee" {
+   if "`difficulties'"=="" {
+      matrix `coef'=e(b)
+      matrix `var'=e(V)
+   }
+   else {
+      matrix `coef'=`difficulties'
+      matrix `var'=J(`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1',.)
+      matrix `var'[`=`nbitems'+1',`=`nbitems'+1']=e(V)
+   }
+   scalar `ll'=e(ll)
+   local nbind=e(N)/`nbitems'
+
+
+   if "`meandiff'"!="" {
+      matrix `var'=J(`nbitems',`nbitems',.)
+      matrix `coef'=J(1,`nbitems',.)
+      local param
+      local lin `rep'1
+      forvalues j=2/`=`nbitems'-1' {
+         local lin `lin'+`rep'`j'
+      }
+      local lin (`lin')/`nbitems'
+
+      forvalues j=1/`=`nbitems'-1' {
+         qui lincom `rep'`j'-`lin'
+         matrix `coef'[1,`j']=`r(estimate)'
+         matrix `var'[`j',`j']=`r(se)'^2
+      }
+      qui lincom -`lin'
+      matrix `coef'[1,`nbitems']=`r(estimate)'
+      matrix `var'[`nbitems',`nbitems']=`r(se)'^2
+   }
+   if "`method'"=="mml" {
+	local sig=e(sigma_u)
+	local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2
+        tempname betacov Vbetacov
+	if "`difficulties'"=="" {
+           matrix `beta'=`coef'[1,1..`nbitems']
+           matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems']
+           if "`covariables'"!="" {
+              matrix `betacov'=`coef'[1,`=`nbitems'+1'..`=`nbitems'+`nbcovariables'']
+              matrix `Vbetacov'=`var'[`=`nbitems'+1'..`=`nbitems'+`nbcovariables'',`=`nbitems'+1'..`=`nbitems'+`nbcovariables'']
+           }
+           local sig=e(sigma_u)
+	   local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2
+	}
+	else {
+	   tempname tmp
+	   matrix `tmp'=e(b)
+           matrix `beta'=`difficulties'
+           if "`covariables'"!="" {
+              matrix `betacov'=`tmp'[1,1..`nbcovariables']
+           }
+           local sig=`tmp'[1,`=`nbcovariables'+1']
+           matrix `tmp'=e(V)
+	   local sesig=sqrt(`tmp'[`=`nbcovariables'+1',`=`nbcovariables'+1'])
+           matrix `Vbeta'=J(`nbitems',`nbitems',.)
+           if "`covariables'"!="" {
+              matrix `Vbetacov'=`tmp'[1..`nbcovariables',1..`nbcovariables']
+           }
+	}
+   }
+   else if "`method'"=="cml"&"`meandiff'"==""{
+	matrix `beta'=`coef'[1,1..`=`nbitems'-1']
+	matrix `Vbeta'=`var'[1..`=`nbitems'-1',1..`=`nbitems'-1']
+   }
+   else if "`method'"=="cml"&"`meandiff'"!=""{
+	matrix `beta'=`coef'
+	matrix `Vbeta'=`var'
+   }
+}
+
+if ("`method'"=="mml"|"`method'"=="gee") {
+   local colnames
+   forvalues i=1/`nbitems' {
+      local colnames "`colnames' `rep':`rep'`i'"
+   }
+   forvalues i=1/`nbcovariables'{
+      local tmp:word `i' of `covariables'
+      local colnames "`colnames' `rep':`tmp'"
+   }
+   local id2=substr("`id'",1,4)
+   local colnames "`colnames' `id2'1:_cons"
+   matrix colnames `est'=`colnames'
+
+   qui gllamm `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') allc nocons family(binom) link(logit) trace from(`est') eval
+   tempname u
+   qui gllapred `u',u fsample
+
+   forvalues i=1/`nbcovariables' {
+      local tmp:word `i' of `covariables'
+      qui replace `u'm1=`u'm1+`betacov'[1,`i']*(`tmp')/*+`mean`covariable`i''')*/
+   }
+   tempname theta sdtheta
+   matrix `theta'=J(1,`=`nbitems'+1',0)
+   matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',0)
+   qui su `u'm1 if `rep'1==-1
+   local vartheta=r(Var)
+   qui gen `u's2=`u's1^2
+   qui su `u's2 if `rep'1==-1
+   local meanse2=r(mean)
+   local psi=1-`meanse2'/(`meanse2'+`vartheta')
+   forvalues s=0/`nbitems' {
+      qui su `u'm1 if `realscore'==`s'
+      local theta`s'=r(mean)
+      qui su `u's1 if `realscore'==`s'
+      local sdtheta`s'=r(mean)
+      matrix `theta'[1,`=`s'+1']=`theta`s''
+      matrix `sdtheta'[`=`s'+1',`=`s'+1']=`sdtheta`s''
+   }
+   if "`genlt'"!="" {
+      tempfile ltsave ltsavetmp
+      qui save `ltsavetmp', replace
+      qui keep if `rep'1==-1
+      qui keep `u'm1 `u's1 `id'
+      qui sort `id'
+      qui save `ltsave'
+      qui use `ltsavetmp'
+   }
+}
+
+forvalues i=1/`nbitems' {
+	if `i'==`nbitems'&"`method'"=="cml"&"`meandiff'"=="" {
+		local beta`i'=0
+		local sd`i' .
+		local fixed`i' "*"
+	}
+	else {
+		local beta`i'=`coef'[1,`i']
+		local sd`i'=sqrt(`var'[`i',`i'])
+	}
+	qui replace `diff'=-`beta`i'' if `item'==`i'
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATIONS
+***********************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+   if "`trace'"!="" {
+     di in green "*** Test of comparison of two populations"
+   }
+         qui inspect `comp'
+         local unique=r(N_unique)
+         if `unique'== 2 {
+		qui su `comp'
+		local mincomp=r(min)
+		local maxcomp=r(max)
+	    	tempname bmin bmax
+	    	qui xtlogit `rep' if `comp'==`mincomp',offset(`diff') i(`id')
+	    	matrix `bmin'=e(b)
+	    	local meanmin=`bmin'[1,1]
+	    	local varmin=e(sigma_u)^2
+	    	local llmin=e(ll)
+	    	local Nmin=e(N_g)
+	    	qui xtlogit `rep' if `comp'==`maxcomp',offset(`diff') i(`id')
+	    	matrix `bmax'=e(b)
+	    	local meanmax=`bmax'[1,1]
+	    	local varmax=e(sigma_u)^2
+	    	local llmax=e(ll)
+	    	local Nmax=e(N_g)
+	    	local Zcomp=(`meanmin'-`meanmax')/sqrt(`varmin'/`Nmin'+`varmax'/`Nmax')
+		local pvalue=1-norm(abs(`Zcomp'))
+	 }
+	 else {
+	        di "It is impossible to compare more than two populations"
+	        di "The comparison process is not run"
+	        local comp
+	 }
+}
+
+/***********************************************************************************************************
+ESTIMATION OF THE ABILITY PARAMETERS  / CML
+************************************************************************************************************/
+if `nbitems'>=2 {
+   if "`trace'"!="" {
+      di in green "*** Estimation of the ability parameters"
+   }
+   if "`method'"=="cml" {
+      tempfile verytmp verytmp2
+      qui save `verytmp',replace
+     clear
+     qui use `saveraschtest'
+
+    tempvar itembis score2 a aa b c z
+    forvalues i=1/`nbitems'{
+    gen `itembis'`i'=``i''
+    replace `itembis'`i'=0 if ``i''==.
+    }
+    genscore `itembis'*, score(`score2')
+    drop `itembis'*
+
+    local exp "string(`1'!=.)"
+    noi di
+    local exp2 "`1'==. "
+    forvalues i=2/`nbitems'{
+        local exp "`exp'+string(``i''!=.)"
+        local exp2 "`exp2' & ``i''==."
+    }
+    gen `z'=0
+    replace `z'=1 if `exp2'
+*   save "~/Bureau/baseRasch.dta", replace
+set trace on
+set tracedepth 1
+     su
+    gen `aa'=`exp'  if `z'==0
+
+    encode `aa',gen(`b')
+    bysort `b': gen `c'=_n if `z'==0
+    su `b'
+    local nbpos=r(max)
+
+forvalues i=1/`nbpos'{
+    su `score2' if `b'==`i'
+    local scorem`i'=r(max)
+    local expp`i' ""
+    local expi`i' ""
+    local expj`i' ""
+    forvalues j=1/`nbitems'{
+        su ``j'' if `b'==`i'
+        if r(N)!=0{
+            local expp`i' "`expp`i'' p`j'"
+            local expi`i' "`expi`i'' i`j'"
+            local expj`i' "`expj`i'' j`j'"
+        }
+    }
+}
+drop `aa' `c'
+qui save `verytmp2',replace
+      
+
+      
+
+      
+      
+      
+      
+      drop _all
+      qui set obs 20001
+      qui gen theta=(_n-10001)/1000
+      qui gen A=1
+      forvalues j=1/`nbitems' {
+         qui gen u`j'=exp(theta-`beta`j'')
+         qui gen p`j'=u`j'/(1+u`j')
+         qui gen a`j'=1/u`j'
+         qui replace A=A*a`j'
+         qui gen i`j'=u`j'/(1+u`j')^2
+         qui gen j`j'=(u`j'*(1-u`j'))/(1+u`j')^3
+      }
+      
+      
+      
+forvalues i=1/`nbpos'{
+    egen P`i'=rsum(`expp`i'') 
+    egen I`i'=rsum(`expi`i'') 
+    egen J`i'=rsum(`expj`i'')
+    tempname theta sdtheta
+    matrix `theta'`i'=J(1,`=`scorem`i''+1',0)
+    matrix `sdtheta'`i'=J(`=`scorem`i''+1',`=`scorem`i''+1',0)
+    forvalues s=0/`scorem`i'' {
+        capture drop f`s'
+	    gen f`s'=abs(`s'-P`i'+.5*J`i'/I`i'^2)
+	    sort f`s'
+	    matrix `theta'`i'[1,`=`s'+1']=theta[1]
+	    matrix `sdtheta'`i'[`=`s'+1',`=`s'+1']=sqrt(1/I`i'[1])
+    }
+    drop P`i' I`i' J`i' 
+}
+matrix `theta'=`theta'`nbpos'
+matrix `sdtheta'=`sdtheta'`nbpos'
+
+use "`verytmp2'",replace      
+      
+tempvar gentl3 sdgentl3   
+gen `gentl3'=.  
+gen `sdgentl3'=.
+forvalues i=1/`nbpos'{
+    forvalues j=0/`scorem`i''{
+	    replace `gentl3'=`theta'`i'[1,`=`j'+1'] if `score2'==`j'& `b'==`i'
+	    replace `sdgentl3'=`sdtheta'`i'[1,`=`j'+1'] if `score2'==`j'& `b'==`i'
+    }
+}
+  
+keep `id' `gentl3' `sdgentl3'
+qui save `verytmp2',replace
+         
+      
+      
+      
+      
+      use "`verytmp'",replace
+   }
+   qui gen `tl'=0
+   forvalues s=0/`nbitems' {
+      local theta`s'=`theta'[1,`=`s'+1']
+      qui replace `tl'=`theta`s'' if `realscore'==`s'
+      local sdtheta`s'=`sdtheta'[`=`s'+1',`= `s'+1']
+   }
+   tempname pred
+   qui gen `pred'=log(exp(`rep'*(`tl'+`diff'))/(1+exp(`tl'+`diff')))
+
+   qui su `pred'
+   local globalll=r(sum)
+
+   local nulscore=0
+   forvalues i=0/`nbgroups' {
+      qui count if `score'==`i'&`item'==1
+      local nbscore`i'=r(N)
+      if `nbscore`i''==0 {
+         local nulscore=1
+      }
+   }
+   if `nulscore' {
+      di in green "{p}At least one group of scores concerns none individuals. Tests will be not computed.{p_end}"
+      di in green "{p}Use the {hi:group} or the {hi:autogroup} options.{p_end}"
+      local test "NONE"
+      local details
+      local icc
+      local fitgraph
+      local splittest
+   }
+   forvalues i=0/`nbitems' {
+      qui count if `realscore'==`i'&`item'==1
+      local nbrealscore`i'=r(N)
+   }
+}
+
+/***********************************************************************************************************
+TESTS OF THE FIRST ORDER
+************************************************************************************************************/
+
+tempname Pi
+matrix define `Pi'=J(`nbitems',`=`nbitems'-1',0)
+if "`test'"!="NONE" {
+   qui drop if `score'==.
+   if "`trace'"!="" {
+      di in green "*** Tests of the first order"
+   }
+   tempname Obs Obs2 Th Th2
+
+   matrix define `Obs'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Obs2'=J(`nbitems',`=`nbgroups'-1',0)
+   matrix define `Th'=J(`nbitems',`=`nbitems'-1',0)
+   matrix define `Th2'=J(`nbitems',`=`nbgroups'-1',0)
+   local listofitemsc
+
+   /* Estimation of the gamma symetrical functions*/
+   local c0 "1"
+   local c`nbitems' "`nbitems'*x"
+   forvalues j=1/`nbitems' {
+      local listini`j'
+      local listofitemsc "`listofitemsc' `beta`j''"
+      local c0 `c0'*(1+exp(x-`beta`j''))
+      local c`nbitems' `c`nbitems''-`beta`j''
+      forvalues k=1/`nbitems' {
+         local listini`j'k`k'
+         if `k'!=`j' {
+            local listini`j' "`listini`j'' `beta`k''"
+         }
+         forvalues l=1/`nbitems' {
+            if `l'!=`j'&`l'!=`k' {
+               local listini`j'k`k' "`listini`j'k`k'' `beta`l''"
+            }
+         }
+      }
+   }
+
+   gammasym `listofitemsc'
+
+   /*Estimation, for each value of the score s of the probability to respond to each item (Pi) and of the theorical number of positive responses (Ths) and of theorical number of positive respond per item pair (Ws)*/
+   forvalues s=1/`nbitems' {
+      local denom`s'=r(gamma`s')
+      tempname  W`s'
+      matrix define `W`s''=J(`nbitems',`nbitems',0)
+   }
+   tempvar prob prob2 z y v z2 y2 v2 c r q e
+   qui gen `prob'=.
+   qui gen `prob2'=.
+   forvalues j=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui count if `rep'==1&`item'==`j'&`realscore'==`s'
+         matrix `Obs'[`j',`s']=r(N)
+         if "`test'"!="WP" {
+            gammasym `listini`j''
+            local num`j'=r(gamma`=`s'-1')
+            if "`method'"=="cml"|"`test'"=="Q" {
+               matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s''
+            }
+            else {
+               gausshermite exp(`s'*x)/(`c0'), sigma(`sig')
+               local int`s'=r(int)
+               if "`test'"=="R"&`nbrealscore`s''!=0{
+                  local tmp=exp(-`beta`j'')*`num`j''*`int`s''*`nbind'/`nbrealscore`s''
+                  matrix `Pi'[`j',`s']=`tmp'
+               }
+               else if `nbrealscore`s''==0 {
+                  matrix `Pi'[`j',`s']=0
+               }
+            }
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  if `s'>=2 {
+                     gammasym `listini`j'k`k''
+                     local num`j'k`k'=r(gamma`=`s'-2')
+                     if "`method'"=="cml" {
+                        matrix `W`s''[`j',`k']=`nbrealscore`s''*exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''/`denom`s''
+                     }
+                     else {
+                        matrix `W`s''[`j',`k']=exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''*`int`s''*`nbind'
+                     }
+                     matrix `W`s''[`k',`j']=`W`s''[`j',`k']
+                  }
+               }
+            }
+         }
+         else if "`test'"=="WP" {
+            matrix `Pi'[`j',`s']=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j''))
+         }
+         matrix `Th'[`j',`s']=`Pi'[`j',`s']*`nbrealscore`s''
+         qui replace `prob'=`Pi'[`j',`s'] if `realscore'==`s'&`item'==`j'
+         qui replace `prob2'=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) if `realscore'==`s'&`item'==`j'
+         matrix `W`s''[`j',`j']=`nbrealscore`s''*`Pi'[`j',`s']
+         if "`test'"!="R" {
+            matrix `W`s''[`j',`j']=`W`s''[`j',`j']*abs(1-`Pi'[`j',`s'])
+         }
+      }
+   }
+   qui gen `v2'=abs(`prob'*(1-`prob'))
+   qui gen `z2'=(`rep'-`prob')^2
+   qui gen `y2'=`z2'/`v2'
+   qui gen `c'=abs(`prob'*(1-`prob')*(`prob'^3+(1-`prob')^3))
+   qui gen `r'=`c'/(`v2')^2
+   qui gen `e'=`c'-(`v2')^2
+
+   forvalues j=1/`nbitems' {
+      qui su `y2' if `item'==`j'
+      local outfit`j'=r(mean)
+      qui su `r' if `item'==`j'
+      local Voutfit`j'=r(sum)
+      local Voutfit`j'=`Voutfit`j''/(`nbind')^2-1/`nbind'
+      local outfitstd`j'=(`outfit`j''^(1/3)-1)*(3/sqrt(`Voutfit`j''))-sqrt(`Voutfit`j'')/3
+
+      qui su `z2' if `item'==`j'
+      local n=r(sum)
+      qui su `v2' if `item'==`j'
+      local d=r(sum)
+      local infit`j'=`n'/`d'
+      qui su `e' if `item'==`j'
+      local sume=r(sum)
+      local Vinfit`j'=`sume'/(`d')^2
+      local infitstd`j'=(`infit`j''^(1/3)-1)*(3/sqrt(`Vinfit`j''))-sqrt(`Vinfit`j'')/3
+   }
+   tempname tmp stattest testitems
+
+   /*Estimation, by scores group g, of the theorical number of positive response (Th2g) and of the positive respond to each items pair (W2g)*/
+   scalar `stattest'=0
+   forvalues g=1/`=`nbgroups'-1' {
+      tempname  W2`g' d2`g'
+      matrix define `W2`g''=J(`nbitems',`nbitems',0)
+      forvalues s=`liminf`g''/`limsup`g'' {
+         forvalues j=1/`nbitems' {
+            matrix `Obs2'[`j',`g']=`Obs2'[`j',`g']+`Obs'[`j',`s']
+            matrix `Th2'[`j',`g']=`Th2'[`j',`g']+`Th'[`j',`s']
+            if "`test'"=="R" {
+               forvalues k=`=`j'+1'/`nbitems' {
+                  matrix `W2`g''[`j',`k']=`W2`g''[`j',`k']+`W`s''[`j',`k']
+                  matrix `W2`g''[`k',`j']=`W2`g''[`j',`k']
+               }
+            }
+            matrix `W2`g''[`j',`j']=`W2`g''[`j',`j']+`W`s''[`j',`j']
+         }
+      }
+
+      /*Estimation of the d2g vectors*/
+      matrix `d2`g''=`Obs2'[1..`nbitems',`g']-`Th2'[1..`nbitems',`g']
+
+      /*Estimation of the influences on the test of each item (testitemsg matrix) and of the test statistic (stattest)*/
+      tempname test`g' testitems`g'
+      matrix `test`g''=`d2`g'''*syminv(`W2`g'')*`d2`g''
+      capture matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      if _rc!=0 {
+         matrix `tmp'=J(`nbitems',`nbitems',0)
+         forvalues j=1/`nbitems' {
+            matrix `tmp'[`j',`j']=`W2`g''[`j',`j']
+         }
+         di in green "Group `g' (`liminf`g''/`limsup`g''): The weight matrix is not positive-definite, the diagonal matrix is used to estimate the contribution of the items on the `wpname' statistic"
+         matrix list `tmp'
+         matrix `testitems`g''=cholesky(syminv(`tmp'))*`d2`g''
+      }
+      else {
+         matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g''
+      }
+      scalar `stattest'=`stattest'+`test`g''[1,1]
+   }
+   matrix `testitems'=J(`nbitems',1,0)
+   forvalues j=1/`nbitems' {
+      forvalues g=1/`=`nbgroups'-1' {
+         matrix `testitems'[`j',1]=`testitems'[`j',1]+`testitems`g''[`j',1]^2
+      }
+   }
+
+   /*Adaptation for the Q1 statistic*/
+   if "`test'"=="Q" {
+      scalar `stattest'=`stattest'*`=`nbitems'-1'/`nbitems'
+   }
+
+   /*Correction for R1m and Q1m*/
+   if ("`test'"=="R"|"`test'"=="Q")&("`method'"=="mml"|"`method'"=="gee") {
+      local c`nbitems' exp(`c`nbitems'')/(`c0')
+      local c0 1/(`c0')
+      gausshermite `c0', sigma(`sig')
+      local ci0=r(int)*`nbind'
+      gausshermite `c`nbitems'',sigma(`sig')
+      local ci`nbitems'=`nbind'*r(int)
+      scalar `stattest'=`stattest'+(`nbrealscore0'-`ci0')^2/`ci0'+(`nbrealscore`nbitems''-`ci`nbitems'')^2/`ci`nbitems''
+  }
+
+
+
+/***********************************************************************************************************
+TESTS U
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests U"
+      }
+
+      local quartile=`nbind'/4
+      local c1=0
+      local n1=0
+      while `n1'<`quartile' {
+         local c1=`c1'+1
+         local n1=`n1'+`nbrealscore`c1''
+      }
+      local c2=`nbitems'
+      local n2=0
+      while `n2'<`quartile' {
+         local c2=`c2'-1
+         local n2=`n2'+`nbrealscore`c2''
+      }
+      forvalues j=1/`nbitems' {
+         local zu1=0
+         local zu2=0
+         forvalues s=1/`c1' {
+            local zu1=`zu1'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         forvalues s=`c2'/`=`nbitems'-1' {
+            local zu2=`zu2'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s']))
+         }
+         local U`j'=(`zu1'-`zu2')/sqrt(`c1'+`nbitems'-`c2')
+      }
+   }
+
+
+
+/***********************************************************************************************************
+TESTS OF THE SECOND ORDER /*undocumented in beta test*/
+************************************************************************************************************/
+
+   if "`q2'"!="" {
+      if "`trace'"!="" {
+         di in green "*** Tests of the second order"
+      }
+
+      tempfile Q2file
+      qui save "`Q2file'",replace
+      qui use "`saveraschtest'",replace
+
+      qui keep if `touse'==1
+      gen `score'=0
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'
+	 rename ``i'' `rep'`i'
+	 qui replace `score'=`score'+`rep'`i'
+      }
+      qui recode `score' `recode'
+
+      forvalues i=1/`nbitems' {
+         local Q2i`i'=0
+         forvalues j=`=`i'+1'/`nbitems' {
+	    local listinci`i'j`j'
+	    forvalues k=1/`nbitems' {
+	       if `k'!=`i'&`k'!=`j' {
+	          local listinci`i'j`j' "`listinci`i'j`j'' `beta`k''"
+	       }
+	    }
+	 }
+      }
+
+      local Q2tot=0
+      forvalues k=2/`=`nbitems'-1' {
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`i'+1'/`nbitems' {
+	       if `k'==1 {
+	          local num=0
+               }
+	       else {
+	          gammasym `listinci`i'j`j''
+                  local num=r(gamma`=`k'-2')
+               }
+	       local athi`i'j`j'k`k'=exp(-`beta`i'')*exp(-`beta`j'')*`num'/`denom`k''
+	       local bthi`i'j`j'k`k'=`nbth`i's`k''-`athi`i'j`j'k`k''
+	       local cthi`i'j`j'k`k'=`nbth`j's`k''-`athi`i'j`j'k`k''
+	       local dthi`i'j`j'k`k'=1-`athi`i'j`j'k`k''-`bthi`i'j`j'k`k''-`cthi`i'j`j'k`k''
+            }
+         }
+      }
+      forvalues k=1/`=`nbgroups'-1' {
+         local Q2`k'=0
+         forvalues i=1/`=`nbitems'-1' {
+	    forvalues j=`=`j'+1'/`nbitems' {
+	       qui count if  `rep'`i'==1&`rep'`j'==1&`score'==`k'
+	       local aempi`i'j`j'k`k'=r(N)
+	       local ath2i`i'j`j'k`k'=0
+	       local bth2i`i'j`j'k`k'=0
+	       local cth2i`i'j`j'k`k'=0
+	       local dth2i`i'j`j'k`k'=0
+	    }
+	 }
+         if `limsup`k''!=1 {
+            forvalues l=`liminf`k''/`limsup`k'' {
+	       forvalues i=1/`=`nbitems'-1' {
+	          forvalues j=`=`i'+1'/`nbitems' {
+		     if `l'!=1 {
+		        local ath2i`i'j`j'k`k'=`ath2i`i'j`j'k`k''+`athi`i'j`j'k`l''*`nbrealscore`l''
+			local bth2i`i'j`j'k`k'=`bth2i`i'j`j'k`k''+`bthi`i'j`j'k`l''*`nbrealscore`l''
+			local cth2i`i'j`j'k`k'=`cth2i`i'j`j'k`k''+`cthi`i'j`j'k`l''*`nbrealscore`l''
+			local dth2i`i'j`j'k`k'=`dth2i`i'j`j'k`k''+`dthi`i'j`j'k`l''*`nbrealscore`l''
+                     }
+		  }
+               }
+            }
+	    forvalues i=1/`=`nbitems'-1' {
+	       forvalues j=`=`i'+1'/`nbitems' {
+	          local d2i`i'j`j'k`k'=(`aempi`i'j`j'k`k''-`ath2i`i'j`j'k`k'')^2
+		  local Q2i`i'j`j'k`k'=`d2i`i'j`j'k`k''/`ath2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`bth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`cth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`dth2i`i'j`j'k`k''
+		  local Q2i`i'=`Q2i`i''+`Q2i`i'j`j'k`k''
+		  local Q2i`j'=`Q2i`j''+`Q2i`i'j`j'k`k''
+		  local Q2`k'=`Q2`k''+`Q2i`i'j`j'k`k''
+	       }
+	    }
+	 }
+         local Q2tot=`Q2tot'+`Q2`k''
+      }
+      forvalues i=1/`nbitems' {
+         di in green "Item ``i'' : Q2 = `Q2i`i''"
+      }
+      local Q2=`Q2tot'*(`nbitems'-3)/(`nbitems'-1)
+      di in green "Q2 = `Q2tot'"
+      qui use "`Q2file'",replace
+   }
+
+/***********************************************************************************************************
+TEST LR Z
+************************************************************************************************************/
+
+   if "`method'"=="cml" {
+      if "`trace'"!="" {
+         di in green "*** Tests LR of Andersen"
+      }
+      local ssll=0
+      tempname Zfile
+      qui save "`Zfile'", replace
+      qui use "`saveraschtest'",replace
+      qui keep if `touse'==1
+      gen `score'=0
+      forvalues j=1/`nbitems' {
+         qui replace `score'=`score'+``j''
+      }
+      qui recode `score' `recode' `nbitems'=`nbgroups'
+      forvalues i=1/`=`nbgroups'-1' {
+         if `effscore`i''>0 {
+            qui raschtestv7jf `varlist' if `score'==`i', test(NONE) `ld'  id(`id')
+            local ll`i'=r(cll)
+            local ssll=`ssll'+(`ll`i'')
+         }
+      }
+      local Z=2*`ssll'-2*`ll'
+      use "`Zfile'",replace
+      tempname AndersenZ
+      matrix define `AndersenZ'=(`Z',`=(`nbgroups'-2)*(`nbitems'-1)',1-chi2(`=(`nbitems'-1)*(`nbgroups'-2)',`Z'))
+   }
+}
+
+
+/***********************************************************************************************************
+DISPLAYING RESULTS WITH TESTS
+************************************************************************************************************/
+
+if "`test'"!="NONE" {
+   local conttest= "_c"
+}
+di
+tempname itemfit globalfit
+matrix `globalfit'=J(1,3,0)
+if "`method'"=="cml" {
+   di in green "Estimation method: " in yellow  "Conditional maximum likelihood (CML)"
+   local nbtest=`nbgroups'-1
+   local line=77
+}
+else if "`method'"=="mml"{
+   di in green "Estimation method: " in yellow  "Marginal maximum likelihood (MML)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+else if "`method'"=="gee" {
+   di in green "Estimation method: " in yellow  "Generalized Estimating Equations (GEE)"
+   local nbtest=`nbgroups'+1
+   local line=70
+}
+if "`test'"=="NONE" {
+   local line=35
+}
+
+di in green  "Number of items: " in yellow  `nbitems'
+
+di in green  "Number of groups: " in yellow  `=`nbgroups'+1' `conttest'
+if "`test'"!="NONE" {
+   di in green " (" in yellow "`nbtest'" in green " of them are used to compute the statistics of test)"
+}
+if "`method'"=="cml" {
+   local nbind=`nbind'+`effscore0'+`effscore`nbgroups''
+   local cont "_c"
+   matrix `itemfit'=J(`nbitems',6,0)
+}
+else {
+   local cont
+   matrix `itemfit'=J(`nbitems',5,0)
+}
+local missing=`N'-`nbind'
+di in green "Number of individuals: " in yellow `N'
+di in green "Number of individuals with missing values: " in yellow `nbindmiss' _c
+if "`ld'"=="" {
+   di in green " (removed)"
+}
+else {
+   di
+}
+di in green  "Number of individuals with nul or perfect score: " in yellow `=`effscore0'+`effscore`nbgroups'''
+if "`method'"=="cml" {
+   di in green  "Conditional log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+else {
+   di in green "Marginal log-likelihood: " in yellow %-13.4f `ll'
+   di in green  "Log-likelihood: " in yellow %-13.4f `globalll'
+}
+di
+noi di in green  _col(16) "Difficulty" `conttest'
+if "`test'"!="NONE" {
+   di in green _col(58) "Standardized"
+}
+noi di in green _col(9) "Items" _col(16) "parameters" _col(28) "std Err." `conttest'
+if "`test'"!="NONE" {
+   local varin=int(2/sqrt(`nbind')*100)/100
+   local varout=int(6/sqrt(`nbind')*100)/100
+   di _col(41) "`namewp'" _col(47) "df" _col(50) "p-value" _col(58) "Outfit" _col(66) "Infit" `cont'
+   if "`method'"=="cml" {
+      di in green _col(77) "U"
+   }
+}
+di in green  "{hline `line'}"
+forvalues i=1/`nbitems' {
+   noi di in yellow _col(3) %12s abbrev("``i''`fixed`i''" ,12) in yellow _col(18) %8.5f `beta`i'' _col(29) %6.5f `sd`i'' `conttest'
+   if "`test'"!="NONE" {
+      di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfitstd`i'' _col(65) %6.3f `infitstd`i''  /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/  `cont'
+      matrix `itemfit'[`i',1]=`testitems'[`i',1]
+      matrix `itemfit'[`i',2]=`=`nbgroups'-2'
+      matrix `itemfit'[`i',3]=1-chi2(`=`nbgroups'-2',`testitems'[`i',1])
+      matrix `itemfit'[`i',4]=`outfitstd`i''
+      matrix `itemfit'[`i',5]=`infitstd`i''
+      if "`method'"=="cml" {
+         di in ye _col(72) %6.3f `U`i''
+         matrix `itemfit'[`i',6]=`U`i''
+      }
+   }
+}
+di in green  "{hline `line'}"
+if "`test'"!="NONE" {
+   if "`method'"=="cml" {
+      local df=(`nbgroups'-2)*(`nbitems'-1)
+   }
+   else {
+      local df=(`nbgroups'-1)*(`nbitems'-1)-1
+   }
+   matrix `globalfit'=(`stattest',`df',1-chi2(`df',`stattest'))
+   noi di in green _col(6) "`descwp'" _col(32) in gr "`namewp'=" _col(36) in ye %8.3f `globalfit'[1,1] _col(46) %3.0f `globalfit'[1,2] _col(51) %6.4f `globalfit'[1,3]
+   if "`method'"=="cml" {
+      noi di in green _col(6) "Andersen LR test" _col(34) "Z=" in yellow _col(36) %8.3f `AndersenZ'[1,1] _col(46) %3.0f `AndersenZ'[1,2] _col(51) %6.4f `AndersenZ'[1,3]
+   }
+   di in green  "{hline `line'}"
+}
+
+if "`method'"=="cml"&"`meandiff'"==""{
+   di in green "*: The difficulty parameter of this item had been fixed to 0"
+}
+if "`method'"=="cml"&"`meandiff'"!=""{
+   di in green "The mean of the difficulty parameters is fixed to 0"
+}
+if `smallgroup'==1&"`test'"!="NONE" {
+   di in green "You have groups of scores with less than 30 individuals. The tests can be invalid."
+}
+if "`method'"!="cml"&"`test'"=="Q" {
+   di in green "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test."
+}
+
+
+
+di
+if "`method'"!="cml" {
+   di in green  "{hline 56}"
+   noi di in green _col(5) "Parameters" _col(21) "Coef." _col(28) "std Err." _col(43) "z" _col(52) "P>|z|"
+   di in green  "{hline 56}"
+   local zsig=`sig'/`sesig'
+   local pzsig=2*(1-norm(abs(`zsig')))
+   di in green _col(10) in yellow "Sigma" _col(18) %8.5f `sig' _col(29) %6.5f `sesig' _col(38) %6.3f `zsig' _col(50) %7.4f `pzsig'
+   di in green  "{hline 56}"
+}
+*set trace on
+if "`covariables'"!="" {
+   tempname zcovariates pcovariates
+   matrix `zcovariates'=J(1,`nbcovariables',0)
+   matrix `pcovariates'=J(1,`nbcovariables',0)
+   forvalues i=1/`nbcovariables' {
+      local tmp :word `i' of `covariables'
+      local zcov=`betacov'[1,`i']/`Vbetacov'[`i',`i']^.5
+      local pzcov=2*(1-norm(abs(`zcov')))
+      matrix `zcovariates'[1,`i']=`zcov'
+      matrix `pcovariates'[1,`i']=`pzcov'
+      di in green _col(3) %12s in yellow abbrev("`tmp'",12) _col(18) %8.5f `betacov'[1,`i'] _col(29) %6.5f `Vbetacov'[`i',`i']^.5 _col(38) %6.3f `zcov' _col(50) %7.4f `pzcov'
+   }
+   di in green  "{hline 56}"
+   local difficulties2
+   if "`difficulties'"!="" {
+      local difficulties2 diff(`difficulties')
+   }
+   if "`ss1'"!="" {
+      tempfile ss1save
+      qui save `ss1save'
+      qui use `saveraschtest'
+      qui keep if `touse'==1
+
+      qui raschtestv7jf `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2'
+      local sigma0=r(sigma)
+      local var0=`sigma0'^2
+      local ss10=`var0'*`=`N'-1'
+      local ss1c0=0
+      di
+      di in green "Type 1 Sum of Squares (sequential)"
+      di "{hline 56}"
+      di in green _col(27) "Variance of the" _col(48) "Explained"
+      di in green _col(4) "Covariates" _col(25) "SS" _col(30) "latent trait" _col(49) "Variance"
+      di "{hline 56}"
+      di _col(10) in green  "None" _col(15) in ye %12.3f `ss10' _col(34) %8.3f `var0'
+      di in green "{dup 56:-}"
+      local covariablesss1
+      forvalues i=1/`nbcovariables' {
+         local covariablesss1 `covariablesss1' `covariable`i''
+         qui raschtestv7jf `varlist' ,id(`id') meth(`method') covariates(`covariablesss1') test(none)  `ld' `difficulties2'
+         local sigma`i'=r(sigma)
+         local var`i'=`sigma`i''^2
+         local ss1`i'=`var`i''*`=`N'-1'
+         di _col(2) %12s in yellow abbrev("`covariable`i''",12) _col(15) %12.3f in ye `=`ss1`=`i'-1''-`ss1`i''' _col(34) %8.3f `var`i'' _col(52) %5.3f (`=`ss1`=`i'-1''-`ss1`i''')/`ss10'
+      }
+      di in green "{hline 56}"
+      qui use `ss1save'
+   }
+   if "`ss3'"!="" {
+      tempfile ss3save
+      qui save `ss3save'
+      qui use `saveraschtest'
+      qui keep if `touse'==1
+      if "`ss1'"=="" {
+         qui raschtestv7jf `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2'
+         local sigma0=r(sigma)
+         local var0=`sigma0'^2
+         local ss30=`var0'*`=`N'-1'
+      }
+      else {
+         local ss30=`ss10'
+      }
+      di
+      di in green "Type 3 Sum of Squares "
+      di "{hline 56}"
+      di in green _col(27) "Variance of the" _col(48) "Explained"
+      di in green _col(4) "Covariates" _col(25) "SS" _col(30) "latent trait" _col(49) "Variance"
+      di "{hline 56}"
+      di _col(10) in green  "None" _col(15) in ye %12.3f `ss10' _col(34) %8.3f `var0'
+      di _col(6) in green  "Complete" _col(15) in ye %12.3f `sig'^2*(`N'-1) _col(34) %8.3f `sig'^2
+      di in green "{dup 56:-}"
+      forvalues i=1/`nbcovariables' {
+         local covariablesss3
+         forvalues j=1/`nbcovariables' {
+            if `i'!=`j' {
+               local covariablesss3 `covariablesss3' `covariable`j''
+            }
+         }
+         qui raschtestv7jf `varlist' ,id(`id') meth(`method') covariates(`covariablesss3') test(none) `ld' `difficulties2'
+         local sigmas`i'=r(sigma)
+         local vars`i'=`sigmas`i''^2
+         local ss3s`i'=`vars`i''*`=`N'-1'
+         local vara`i'=`sig'^2
+         local ss3a`i'=`vara`i''*`=`N'-1'
+         di _col(2) %12s in yellow abbrev("`covariable`i''",12) _col(15) %12.3f in ye `=`ss3s`i''-`ss3a`i''' _col(34) %8.3f `vars`i'' _col(52) %5.3f (`=`ss3s`i''-`ss3a`i''')/`ss30'
+      }
+      di in green "{hline 56}"
+      qui use `ss3save'
+   }
+}
+
+
+
+/*Tabular of the estimated values of the latent trait*/
+
+if "`covariables'"=="" {
+   di
+   di
+   noi di in green _col(33) "Ability" _col(60) "Expected"
+   noi di in green _col(17) "Group" _col(23) "Score" _col(30) "parameters" _col(42) "std Err." _col(54) "Freq." _col(63) "Score"_c
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      noi di in green _col(75) "ll"
+   }
+   else {
+      noi di ""
+   }
+   if "`method'"=="cml"&"`test'"!="NONE" {
+      local line=62
+   }
+   else {
+     local line=51
+   }
+   di in green _col(17) "{hline `line'}"
+   local nonul=0
+   forvalues g=0/`nbgroups' {
+      if `g'!=0 {
+         di in green _col(17) "{dup `line':-}"
+      }
+      forvalues s=`liminf`g''/`limsup`g'' {
+         if `s'==`liminf`g'' {
+            local tmp `ll`g''
+            local gr `g'
+         }
+         else {
+            local tmp
+            local gr
+         }
+         local expscore`nonul'=0
+         forvalues i=1/`nbitems' {
+            local expscore`nonul'=`expscore`nonul''+1/(1+exp(-`theta`nonul''+`beta`i''))
+         }
+         if "`method'"=="cml" {
+            local format1 %8.3f
+         }
+         else {
+            local format1 %8.5f
+         }
+         noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(32) `format1' `theta`nonul'' _col(42) `format1' `sdtheta`nonul'' _col(55) %4.0f `nbrealscore`s'' _col(64) % 4.2f `expscore`nonul'' _col(68) %11.4f `tmp'
+         local nonul=`nonul'+1
+      }
+   }
+   di in green _col(17) "{hline `line'}"
+}
+if "`method'"=="mml"|"`method'"=="gee" {
+       di
+       *di in green "Variance of the estimated latent trait" _col(45) in ye %10.4f `vartheta'
+       di in green "Mean variance of the error" _col(45) in ye %10.4f `meanse2'
+       local sig2=`sig'^2
+       di in green "Estimated variance of the latent trait" _col(45) in ye %10.4f `sig2'
+       local psi2=1-`meanse2'/`sig2'
+       di in green "Personal Separation Index (PSI)" _col(45) in ye %10.4f `psi2'
+       di in green "Adjusted PSI on covariates (PSIadj)" _col(45) in ye %10.4f `psi'
+}
+
+
+/***********************************************************************************************************
+DETAILS OPTION
+************************************************************************************************************/
+
+if "`details'"!="" {
+   forvalues g=0/`nbgroups' {
+      if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" {
+         di
+         di in  green "{hline 44}"
+         di in green "Group: " in ye "`g'" in green " from " in ye "`liminf`g''" in green " to " in ye "`limsup`g''" in green " (n=" in ye "`nbscore`g''" in green")"
+         di
+         di _col(3) "Item" _col(10) "Observed" _col(23) "Expected" _col(37) "Scaled"
+         di in green "{dup 44:-}"
+      }
+      if `g'!=0&`g'!=`nbgroups' {
+         forvalues j=1/`nbitems' {
+            local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j'])
+            di _col(3) in ye "``j''" _col(14) %4.0f `Obs2'[`j',`g'] _col(25) %6.2f `Th2'[`j',`g'] _col(36) %7.4f `tmp'
+         }
+         di in green "{dup 44:-}"
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `test`g''[1,1]
+      }
+      else if "`method'"!="cml" {
+         if `g'==0 {
+            local h=0
+         }
+         else {
+            local h=`nbitems'
+         }
+         local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'')
+         di in ye _col(14) %4.0f `nbrealscore`h'' _col(25) %6.2f `ci`h'' _col(36) %7.4f `tmp'
+         di in green "{dup 44:-}"
+         local tmp=`tmp'^2
+         di in green "Contribution to the `namewp' statistics: " %8.4f in ye `tmp'
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION ICC
+************************************************************************************************************/
+*set trace on
+if "`icc'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Items Characteristic Curves"
+   }
+   tempvar proba propemp propth propthb
+   qui replace `tl'=. if `realscore'==0|`realscore'==`nbitems'|`realscore'==.
+   qui gen `propemp'=.
+   qui gen `propth'=.
+   qui gen `propthb'=.
+   label variable `propth' "Expected ICC"
+   label variable `propemp' "Observed ICC"
+   label variable `propthb' "Expected ICC"
+   label variable `tl' "Latent trait"
+   global iccs
+   forvalues i=1/`nbitems' {
+      forvalues s=1/`=`nbitems'-1' {
+         qui replace `propthb'=exp(`theta`s''-`beta`i'')/(1+exp(`theta`s''-`beta`i'')) if `item'==`i'&`realscore'==`s'
+      }
+      qui replace `propemp'=.
+      qui replace `propth'=.
+      tempvar propemp`i' propth`i'
+      qui bysort `realscore' `item' : egen `propth`i''=mean(`propthb') if `item'==`i'
+      qui bysort `realscore' `item' : egen `propemp`i''=mean(`rep') if `item'==`i'
+      qui replace `propth'=`propth`i'' if `item'==`i'
+      qui replace `propemp'=`propemp`i'' if `item'==`i'
+      local mintl=floor(`theta1')
+      local maxtl=floor(`theta`=`nbitems'-1'')+1
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\icc``i''"
+      }
+      if "`v8'"!="" {
+         graph twoway (line  `propemp' `propth' `tl') if `item'==`i' , name(icc``i'',replace) ytitle("")  ylabel(0(.25)1) title("Observed and Expected ICC for the item ``i''") xlabel(`mintl'(1)`maxtl') `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save icc``i''  "`saving'" , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui graph `propemp' `propth' `tl' if `item'==`i' , twoway `saving' c(ll) ylabel(0(.25)1)   xlabel(`mintl'(1)`maxtl') title("Observed and Expected ICC for the item ``i''")
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION INFORMATION
+************************************************************************************************************/
+
+if "`information'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Information graph"
+   }
+
+   tempfile saveinfo
+   qui save "`saveinfo'",replace
+   tempvar info latent
+   drop _all
+   qui set obs 2001
+   gen `latent'=((_n-1)/1001-1)*3
+   label variable `latent' "latent trait"
+   gen `info'=0
+   forvalues i=1/`nbitems' {
+      qui replace `info'=`info'+exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2
+   }
+   local saving "`dirsave'\\information"
+   if "`v8'"!="" {
+      graph twoway (line  `info' `latent') , name(information,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the scale") `draw'
+      if "`filessave'"!="" {
+         graph save information "`saving'" , `replace'
+      }
+      pause
+   }
+   else {
+      if "`filessave'"!="" {
+         local saving "saving(`saving'"
+         if "`replace'"=="" {
+            local saving "`saving')"
+         }
+         else {
+            local saving "`saving',replace)"
+         }
+      }
+      if "`filessave'"=="" {
+         local saving
+      }
+      qui graph `info' `latent' , twoway  `saving' c(l) xlabel(-3(1)3) title("Information graph of the scale")
+      pause
+   }
+   qui use "`saveinfo'",replace
+}
+
+/***********************************************************************************************************
+OPTION FITGRAPH
+************************************************************************************************************/
+
+if "`fitgraph'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graphical validation of the fit"
+   }
+   *set trace on
+   tempname outfit meanz2 meanv2 sumd infit Voutfit outfitstd Vinfit infitstd
+   qui egen `outfit'=mean(`y2'),by(`id')
+   qui egen `Voutfit'=sum(`r'),by(`id')
+   qui replace `Voutfit'=`Voutfit'/(`nbitems')^2-1/`nbitems'
+   qui gen `outfitstd'=(`outfit'^(1/3)-1)*(3/sqrt(`Voutfit'))-sqrt(`Voutfit')/3
+   qui egen `meanz2'=sum(`z2'),by(`id')
+   qui egen `meanv2'=sum(`v2'),by(`id')
+   qui gen `infit'=`meanz2'/`meanv2'
+   qui egen `Vinfit'=sum(`e'),by(`id')
+   qui replace `Vinfit'=`Vinfit'/(`meanv2')^2
+   qui gen `infitstd'=(`infit'^(1/3)-1)*(3/sqrt(`Vinfit'))-sqrt(`Vinfit')/3
+
+   qui su `outfitstd'
+   local mino=floor(2*min(`r(min)',-2))/2
+   local maxo=ceil(2*max(`r(max)',2))/2
+   qui su `infitstd'
+   local mini=floor(2*min(`r(min)',-2))/2
+   local maxi=ceil(2*max(`r(max)',2))/2
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfitind"
+      local savingi "`dirsave'\\infitind"
+   }
+   if "`v8'"!="" {
+      graph twoway (scatter `outfitstd' `id'), name(outfit,replace) yline(-2 2) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw'
+      pause
+      graph twoway (scatter `infitstd' `id'), name(infit,replace) yline(-2 2) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfit "`savingo'" , `replace'
+         graph save infit "`savingi'" , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitstd' `id', `savingo' twoway sy(.) c(.) yline(-2 2) title("Outfit indexes") b2title("Individual indexes") l1("") l2title("Outfit") ylabel(`mino'(.5)`maxo')
+      pause
+      graph `infitstd' `id', `savingi' twoway sy(.) c(.) yline(-2 2) title("Infit indexes") b2title("Individual indexes") l1("")  l2title("Infit") ylabel(`mini'(.5)`maxi')
+      pause
+   }
+   drop _all
+   qui set obs `nbitems'
+   tempvar name betap outfitstdj infitstdj
+   qui gen str9 `name'=""
+   qui gen `betap'=.
+   qui gen `outfitstdj'=.
+   qui gen `infitstdj'=.
+   local mino=-2
+   local maxo=2
+   local mini=-2
+   local maxi=2
+   forvalues j=1/`nbitems' {
+      qui replace `name'="``j''" in `j'
+      qui replace `betap'=`beta`j'' in `j'
+      qui replace `outfitstdj'=`outfitstd`j'' in `j'
+      qui replace `infitstdj'=`infitstd`j'' in `j'
+      local mino=floor(min(`mino',`outfitstd`j'')*2)/2
+      local mini=floor(min(`mini',`infitstd`j'')*2)/2
+      local maxo=ceil(max(`maxo',`outfitstd`j'')*2)/2
+      local maxi=ceil(max(`maxi',`infitstd`j'')*2)/2
+   }
+   if "`filessave'"!=""{
+      local savingo "`dirsave'\\outfititems"
+      local savingi "`dirsave'\\infititems"
+   }
+   if "`v8'"!="" {
+      graph twoway (scatter `outfitstdj' `betap',name(outfititem,replace) mlabel(`name')), yline(-2 2) title("Outfit indexes") xtitle("Difficulty") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw'
+      pause
+      graph twoway (scatter `infitstdj' `betap',name(infititem,replace) mlabel(`name')), yline(-2 2) title("Infit indexes") xtitle("Difficulty") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw'
+      pause
+      if "`filessave'"!="" {
+         graph save outfititem "`savingo'" , `replace'
+         graph save infititem "`savingi'" , `replace'
+      }
+   }
+   else {
+      if "`filessave'"!="" {
+         local savingo "saving(`savingo'"
+         local savingi "saving(`savingi'"
+         if "`replace'"=="" {
+            local savingo "`savingo')"
+            local savingi "`savingi')"
+         }
+         else {
+            local savingo "`savingo',replace)"
+            local savingi "`savingi',replace)"
+         }
+      }
+      graph `outfitstdj' `betap', `savingo' twoway c(.) yline(-2 2) title("Outfit indexes") b2title("Difficulty") l1title("") l2title("Outfit") ylabel(`mino'(.5)`maxo') sy([`name'])
+      pause
+      graph `infitstdj' `betap', `savingi' twoway c(.) yline(-2 2) title("Infit indexes") b2title("Difficulty") l1title("") l2title("Infit") ylabel(`mini'(.5)`maxi') sy([`name'])
+      pause
+   }
+}
+
+
+/***********************************************************************************************************
+OPTION SPLITTESTS
+************************************************************************************************************/
+
+if "`splittests'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Splitting tests"
+   }
+   forvalues j=1/`nbitems' {
+      tempname estneg`j' estpos`j'
+      local listitems
+      forvalues k=1/`nbitems' {
+         if `j'!=`k' {
+            local listitems `listitems' ``k''
+         }
+      }
+      qui use "`saveraschtest'",replace
+      qui keep if `touse'==1
+      qui raschtestv7jf `listitems' if ``j''==0,test(NONE) meth(cml) `ld' id(`id')
+      matrix `estneg`j''=r(beta)
+      local llneg=r(cll)
+      qui raschtestv7jf `listitems' if ``j''==1,test(NONE) meth(cml) `ld'  id(`id')
+      matrix `estpos`j''=r(beta)
+      local llpos=r(cll)
+      qui raschtestv7jf `listitems',test(NONE) meth(cml) `ld' id(`id')
+      local llnegpos=r(cll)
+      local nbcol=colsof(`estneg`j'')
+      local meanneg=0
+      local meanpos=0
+      forvalues k=1/`nbcol' {
+         local meanneg=`meanneg'+`estneg`j''[1,`k']
+         local meanpos=`meanpos'+`estpos`j''[1,`k']
+      }
+      local meanneg=`meanneg'/`nbitems'
+      local meanpos=`meanpos'/`nbitems'
+      forvalues k=1/`nbcol' {
+         matrix `estneg`j''[1,`k']=`estneg`j''[1,`k']-`meanneg'
+         matrix `estpos`j''[1,`k']=`estpos`j''[1,`k']-`meanpos'
+         if "`method'"=="cml" {
+            matrix `estneg`j''=`estneg`j'',-`meanneg'
+            matrix `estpos`j''=`estpos`j'',-`meanpos'
+         }
+      }
+      drop _all
+      qui set obs `=`nbitems'+1'
+      tempvar neg pos name diag
+      qui gen `neg'=.
+      qui gen `pos'=.
+      qui gen str9 `name'=""
+      local min=`estneg`j''[1,1]
+      local max=`estneg`j''[1,1]
+      forvalues k=1/`=`nbitems'-1' {
+         qui replace `neg'=`estneg`j''[1,`k'] in `k'
+         qui replace `pos'=`estpos`j''[1,`k'] in `k'
+         local min=min(`min',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local max=max(`max',`estneg`j''[1,`k'],`estpos`j''[1,`k'])
+         local tmp:word `k' of `listitems'
+         qui replace `name'="`tmp'" in `k'
+      }
+      local min=floor(`min')
+      local max=floor(`max')+1
+      qui gen `diag'=.
+      qui replace `diag'=`min' in `nbitems'
+      qui replace `diag'=`max' in `=`nbitems'+1'
+      local Zgr=round(2*(`llneg'+`llpos'-`llnegpos'),0.001)
+      local Zgr=substr("`Zgr'",1,6)
+      local pgr=round(1-chi2(`=`nbitems'-1',`Zgr'),0.0001)
+      local pgr=substr("`pgr'",1,5)
+      local note="Z=`Zgr', df=`=`nbitems'-1' , p=`pgr'"
+      if "`filessave'"!=""{
+         local saving "`dirsave'\\split``j''"
+      }
+      if "`v8'"!="" {
+         graph twoway (scatter `pos' `neg' ,mlabel(`name')) (line `diag' `diag'), ytitle("Positive answer") xtitle("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title(Splitting on ``j'') `draw' legend(off) note("Andersen Z test: `note'") name(split,replace) `draw'
+         pause
+         if "`filessave'"!="" {
+            graph save split "`saving'" , `replace'
+         }
+      }
+      else {
+         if "`filessave'"!="" {
+            local saving "saving(`saving'"
+            if "`replace'"=="" {
+               local saving "`saving')"
+            }
+            else {
+               local saving "`saving',replace)"
+            }
+         }
+         qui replace `diag'=`neg' if `diag'==.
+         graph  `pos' `diag' `diag', `saving' c(.l) sy([`name']i) l1title("") l2title("Positive answer") b2title("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title("Splitting on ``j'' (`note')") `draw'
+         pause
+      }
+   }
+}
+
+/***********************************************************************************************************
+OPTION GRAPH
+************************************************************************************************************/
+
+if "`graph'"!=""&"`v8'"!="" {
+   if "`trace'"!="" {
+      di in green "*** Graph option"
+   }
+   tempvar  latent2  tl2 delta2 tlth2 labdelta2 labtl2
+   drop _all
+   qui set obs 1001
+   gen `latent2'=(_n-501)/100
+   label variable `latent2' "latent trait"
+   qui gen `tl2'=.
+   qui gen `labtl2'=""
+   forvalues i=0/`nbitems' {
+      *if (`i'!=0&`i'!=`nbitems')|"`method'"!="cml" {
+         qui replace `tl2'=`nbrealscore`i''/`N' if round(`latent2',0.01)==round(`theta`i'',0.01)
+         qui replace `labtl2'="`i'" if round(`latent2',0.01)==round(`theta`i'',0.01)
+      *}
+   }
+   qui gen `delta2'=.
+   qui gen `labdelta2'=""
+   forvalues i=1/`nbitems' {
+      qui replace `delta2'=-.05 if round(`latent2',0.01)==round(`beta`i'',0.01)
+      qui replace `labdelta2'="``i''" if round(`latent2',0.01)==round(`beta`i'',0.01)
+   }
+   if "`method'"=="mml"|"`method'"=="gee" {
+      qui gen `tlth2'=1/(2*_pi*`sig')*exp(-.5*(`latent2'/`sig')^2)
+      label variable `tlth2' "Theorical distribution"
+      local graphmml line `tlth2' `latent2'
+   }
+   label variable `tl2' "Score"
+   label variable `delta2' "Items"
+   local saving "`dirsave'\\graph"
+   local min=-2
+   local max=2
+   forvalues j=1/`nbitems' {
+      if `beta`j''<`min' {
+         local min=`beta`j''-.5
+      }
+      if `beta`j''>`max'&`beta`j''!=. {
+         local max=`beta`j''+.5
+      }
+   }
+   if "`method'"=="cml" {
+      if `theta0'<`min' {
+         local min=`theta0'-.5
+      }
+      if `theta`=`nbitems'-1''>`max' {
+         local max=`theta`=`nbitems'-1''+.5
+      }
+   }
+   else if "`method'"!="cml" {
+      if `theta0'<`min'&`theta0'!=. {
+         local min=`theta0'-.5
+      }
+      if `theta`nbitems''>`max'&`theta`nbitems''!=. {
+         local max=`theta`nbitems''+.5
+      }
+   }
+   local min=floor(`min')
+   local max=floor(`max')+1
+   qui su `tl2'
+   local max2=r(max)
+   if "`method'"!="cml" {
+      qui su `tlth2'
+      local max2=max(`max2',`r(max)')
+   }
+   qui replace `latent2'=. if `latent2'<`min'|`latent2'>`max'
+   if "`v8'"!="" {
+      graph twoway (bar `tl2' `latent2',/*mlabel(`labtl2')*/ barwidth(.3) ) (dropline `delta2' `latent2',mlabel(`labdelta2') mlabposition(6)) (`graphmml'), name(graph,replace) ytitle("") xlabel(`min'(1)`max') ylabel(-.1 0(0.05)`max2') title("Individuals/items representations") `draw'
+      if "`filessave'"!="" {
+         graph save graph "`saving'" , `replace'
+      }
+      pause
+   }
+}
+else if "`graph'"!=""&"`v8'"=="" {
+   di in ye "The graph option is not available with Stata 7"
+}
+
+/***********************************************************************************************************
+COMPARISON OF TWO POPULATION
+************************************************************************************************************/
+
+if "`comp'"!=""&"`method'"!="cml" {
+      di
+      di _col(4) "{hline 30}"
+      di _col(4) in green "Comparison of two populations"
+      di _col(4) "{hline 30}"
+      di
+      di _col(4) in green "`comp'==`mincomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmin' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmin' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmin'
+      di _col(4) in green "`comp'==`maxcomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmax' _col(30) in green "mean= "       _col(35) in yellow %8.4f `meanmax' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmax'
+      di                                                                       _col(33) in green "Z= " _col(35) in yellow %8.4f `Zcomp' _col(47) in green "pvalue= "    _col(57) in yellow %6.4f `pvalue'
+}
+
+/***********************************************************************************************************
+TEST DIF
+************************************************************************************************************/
+
+if "`method'"=="cml"&"`dif'"!=""&"`test'"!="NONE" {
+   if "`trace'"!="" {
+      di in green "*** Tests of DIF"
+   }
+   local ssll=0
+   tempname DIFfile
+   qui save "`DIFfile'", replace
+   qui use "`saveraschtest'",replace
+   qui keep if `touse'==1
+   unab list:`dif'
+   local nbdif:word count `list'
+   tempname DIF
+   matrix define `DIF'=J(`nbdif',4,0)
+   local count=1
+   di
+   di _col(4) in green "{hline 45}"
+   di _col(4) in green "Test of Differential Item Functioning (DIF)"
+   di _col(4) in green "{hline 45}"
+   foreach j in `list' {
+      qui inspect `j'
+      local nbdif=r(N_unique)
+      qui su `j'
+      local maxdif=r(max)
+      if `nbdif'>10&`maxdif'<=10 {
+         di in ye "The {hi:dif} option is available with variables containing 10 or less modalities (coded from 0 or 1 to k<10)."
+         di in ye "The variable `j' (`nbdif' modalities) is omitted."
+      }
+      else {
+         local ssll=0
+         forvalues i=0/10 {
+            qui count if `j'==`i'
+            local effdif=r(N)
+            if `effdif'>0 {
+               qui raschtestv7jf `varlist' if `j'==`i', test(NONE) id(`id')
+               local ll`i'=r(cll)
+               local ssll=`ssll'+(`ll`i'')
+            }
+         }
+         local Z=2*`ssll'-2*`ll'
+         local ddl=(`nbdif'-1)*(`nbitems'-1)
+         matrix define `DIF'[`count',1]=(`count',`Z',`ddl',1-chi2(`ddl',`Z'))
+         di
+         di _col(4) in green "Variable:" in ye " `j' " in green "   Number of groups: "  in ye "`nbdif'"
+         di _col(4) in green "LR Test Z=" in ye %8.3f `Z' in gr "   ddl=" in ye %4.0f `ddl' in gr "    p-value=" in ye %6.4f `=1-chi2(`ddl',`Z')'
+         di
+      }
+      local ++count
+   }
+   use "`DIFfile'",replace
+}
+
+/***********************************************************************************************************
+RETURN
+************************************************************************************************************/
+
+if "`trace'"!="" {
+  di in green "*** Returns"
+}
+local colnametheta
+
+forvalues i=0/`nbgroups' {
+         local colnametheta `colnametheta' score_`i'
+}
+
+
+return clear
+
+if `nbitems'>=3&"`test'"!="NONE" {
+        matrix colnames `globalfit'=`namewp' df p
+	matrix rownames `globalfit'=`method'
+	matrix rownames `itemfit'=`varlist'
+        matrix roweq `itemfit'=`method'
+
+	if "`method'"=="cml" {
+                matrix colnames `itemfit'=`namewp' df p outfit infit U
+		matrix rownames `AndersenZ'=`method'
+		matrix colnames `AndersenZ'=Z df p
+		return matrix AndersenZ=`AndersenZ'
+                if "`dif'"!="" {
+		   matrix rownames `DIF'=`list'
+		   matrix colnames `DIF'=num Z df p
+		   return matrix DIF=`DIF'
+                }
+	}
+	else {
+                matrix colnames `itemfit'=`namewp' df p outfit infit
+	}
+	return matrix itemFit=`itemfit'
+	return matrix globalFit=`globalfit'
+}
+
+matrix colnames `theta'=`colnametheta'
+matrix rownames `theta'=theta
+return matrix theta `theta'
+matrix colnames `sdtheta'=`colnametheta'
+matrix rownames `sdtheta'=`colnametheta'
+return matrix Vartheta `sdtheta'
+local varlist2
+matrix coleq `beta'=`method'
+matrix coleq `Vbeta'=`method'
+matrix roweq `Vbeta'=`method'
+if "`method'"=="cml" {
+	forvalues i=1/`=`nbitems'-1' {
+		local varlist2 `varlist2' ``i''
+	}
+        return scalar cll=`ll'
+        return scalar ll=`globalll'
+	local AIC=-2*`globalll'+2*(`nbitems'-1)
+}
+else {
+        return scalar ll=`ll'
+	local varlist2 `varlist'
+	return scalar sigma=`sig'
+	return scalar sesigma=`sesig'
+	local AIC=-2*`ll'+2*(`nbitems'+1)
+}
+
+if "`comp'"!="" {
+   return scalar Zcomp=`Zcomp'
+   return scalar pZcomp=`pvalue'
+}
+
+matrix colnames `beta'=`varlist2'
+matrix rownames `beta'=beta
+return matrix beta `beta'
+
+matrix colnames `Vbeta'=`varlist2'
+matrix rownames `Vbeta'=`varlist2'
+return matrix Varbeta `Vbeta'
+
+return scalar AIC=`AIC'
+return scalar N=`nbind'
+
+if "`method'"=="mml" {
+   return scalar PSI=`psi2'
+   return scalar PSIadj=`psi'
+}
+if "`covariables'"!="" {
+   local tmp
+   local tmp2
+   forvalues i=1/`nbcovariables' {
+      local tmp `tmp' `covariable`i''
+      local tmp2 "`tmp2' :`covariable`i''"
+   }
+   matrix colnames `betacov'=`tmp2'
+   matrix rownames `Vbetacov'=`tmp2'
+   matrix colnames `Vbetacov'=`tmp2'
+   matrix colnames `zcovariates'=`tmp'
+   matrix colnames `pcovariates'=`tmp'
+   return matrix betacovariates=`betacov'
+   return matrix Vbetacovariates=`Vbetacov'
+   return matrix zcovariates=`zcovariates'
+   return matrix pcovariates=`pcovariates'
+}
+if "`pause'"!="" {
+   pause off
+}
+
+drop _all
+
+restore,not
+use "`saveraschtest'"
+
+/***********************************************************************************************************
+CREATE EVENTUAL NEW VARIABLES
+************************************************************************************************************/
+
+
+if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" {
+        tempname genlt2 genscore2 outfit2 infit2
+        qui gen `score'=0 `if'
+        forvalues i=1/`nbitems' {
+           qui replace `score'=`score'+``i'' `if'
+        }
+        if "`genscore'"!="" {
+           qui gen `genscore'=`score' `if'
+        }
+        if "`genlt'"!="" {
+           if "`replacegenlt'"=="replace" {
+              capture drop `genlt'
+              capture drop se`genlt'
+           }
+           if "`method'"=="mml" {
+              qui sort `id'
+              qui merge `id' using `ltsave'
+              qui rename `u'm1 `genlt'
+              qui rename `u's1 se`genlt'
+              qui drop _merge
+           }
+           
+           
+           
+           
+           
+           
+           
+           
+           
+           else if "`method'"=="cml" {
+           
+           qui sort `id'
+              qui merge `id' using `verytmp2'
+              qui rename `gentl3' `genlt'
+              qui rename `sdgentl3' se`genlt'
+              qui drop _merge
+
+           }
+           
+           
+        
+
+
+           
+           
+           
+           
+           
+           
+           else if "`method'"!="mml" {
+              qui gen `genlt2'=. `if'
+              forvalues i=0/`nbitems' {
+                 qui replace `genlt2'=`theta`i'' `if'&`score'==`i'
+              }
+              qui gen `genlt'=`genlt2' `if'
+           }
+        }
+        if "`genfit'"!="" {
+           local outfit:word 1 of `genfit'
+           local infit:word 2 of `genfit'
+           qui gen `outfit'=0 `if'
+           qui gen `infit'=0  `if'
+           tempname infit1 infit2
+           qui gen `infit1'=0 `if'
+           qui gen `infit2'=0 `if'
+           forvalues j=1/`nbitems' {
+               tempname pi`j'
+               qui gen `pi`j''=exp(`genlt2'-`beta`j'')/(1+exp(`genlt2'-`beta`j'')) `if'
+               qui replace `pi`j''=0  `if'
+               forvalues s=1/`nbitems' {
+                  qui replace `pi`j''=`Pi'[`j',`s'] `if'&`score'==`s'
+               }
+               qui gen `outfit'``j''=(``j''-`pi`j'')^2/(`pi`j''*(1-`pi`j'')) `if'
+               qui replace `infit1'=`infit1'+(``j''-`pi`j'')^2  `if'
+               qui replace `infit2'=`infit2'+(`pi`j''*(1-`pi`j'')) `if'
+               qui replace `outfit'=`outfit'+`outfit'``j''/`nbitems' `if'
+           }
+           qui replace `infit'=`infit1'/`infit2'  `if'
+        }
+}
+
+if "`trace'"!=""|"`time'"!="" {
+    capture qui elapse `st'
+    di in green "** Time : " in yellow "$S_elap " in green "seconds"
+}
+
+end
diff --git a/Modules/ado/personal/r/old/rsoort.do b/Modules/ado/personal/r/old/rsoort.do
new file mode 100644
index 0000000..76f1389
--- /dev/null
+++ b/Modules/ado/personal/r/old/rsoort.do
@@ -0,0 +1,584 @@
+*! version 1  25februar2013
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* rsoort: Response Shift detection with the Oort procedure
+*
+* Historic:
+* Version 1 (2013-02-25): Jean-Benoit Hardouin
+*
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* Copyright 2013 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+
+program define rsoort,eclass
+syntax varlist(min=1 numeric) [if] [in] [,METHod(string) UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPriorisation(varlist) noSearch]
+
+tokenize `varlist'
+local nbitems:word count `varlist'
+local mod=mod(`nbitems',2)
+if `mod'!=0 {
+  di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2"
+  error
+}
+
+if "`method'"=="" {
+   local method "ml"
+}
+local nbitems=`nbitems'/2
+
+di _col(20) "{hline 30}"
+di  _col(20) in gr "Time 1" _col(40) "Time 2"
+di _col(20) "{hline 30}"
+forvalues i=1/`nbitems' {
+    di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''"
+}
+di _col(20) "{hline 30}"
+
+
+/**************************************************************************************************************
+Model 1
+***************************************************************************************************************/
+
+qui sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0)  method(`method')
+qui estat gof, stat(all)
+local tli1=r(tli)
+local cfi1=r(cfi)
+local srmr1=r(srmr)
+local rmsea1=r(rmsea)
+local ubrmsea1=r(ub90_rmsea)
+local lbrmsea1=r(lb90_rmsea)
+local chi21=r(chi2_ms)
+local df1=r(df_ms)
+local dfc1=6*`nbitems'+1
+local p1=r(p_ms)
+*di
+*di in green "          ***********************************Model 1********************************************"
+*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
+*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1'  _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
+
+/**************************************************************************************************************
+Model 2
+***************************************************************************************************************/
+
+local sem
+local var
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local sem `sem' `sem`i''
+   local var `var' `var`i''
+}
+
+qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'     iterate(100)  method(`method')
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local truechange2=`b'[1,`=`nbitems'*4+1']
+local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
+qui estat gof, stat(all)
+local tli2=r(tli)
+local cfi2=r(cfi)
+local srmr2=r(srmr)
+local rmsea2=r(rmsea)
+local ubrmsea2=r(ub90_rmsea)
+local lbrmsea2=r(lb90_rmsea)
+local chi22=r(chi2_ms)
+local df2=r(df_ms)
+local dfc2=3*`nbitems'+3
+local p2=r(p_ms)
+
+local chi221=abs(`chi21'-`chi22')
+local df21=`df2'-`df1'
+local p21=1-chi2(`df21',`chi221')
+
+
+di "{hline 105}"
+di in gr                                _col(39) "Test of global Response-Shift "              _col(79) "Comparison with model 1"
+di in gr "Models" _col(18)  "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
+di "{hline 105}"
+di in gr "Model 1" _col(20) %8.2f in ye `chi21'
+di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' _col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'
+di "{hline 105}"
+
+
+/**************************************************************************************************************
+Model 3
+***************************************************************************************************************/
+
+
+/**************************************************************************************************************
+Model 3 / Non uniform recalibration
+***************************************************************************************************************/
+
+tempname RS  RSprec
+qui matrix `RS'=J(`nbitems',3,0)
+qui matrix `RSprec'=J(`nbitems',3,0)
+local df3=`dfc2'
+
+*set trace on
+
+
+forvalues i=1/`nbitems' {
+   local nbUR:word count `uniformrecalibration'
+   forvalues j=1/`nbUR' {
+      local itemj: word `j' of `uniformrecalibration'
+      if "``i''"=="`itemj'" {
+	     matrix `RS'[`i',2]=1
+      }
+   }
+   local nbNUR:word count `nonuniformrecalibration'
+   forvalues j=1/`nbNUR' {
+      local itemj: word `j' of `nonuniformrecalibration'
+     if "``i''"=="`itemj'" {
+	     matrix `RS'[`i',1]=1
+      }
+   }
+   local nbR:word count `repriorisation'
+   forvalues j=1/`nbR' {
+      local itemj: word `j' of `repriorisation'
+      if "``i''"=="`itemj'" {
+	     matrix `RS'[`i',3]=1
+      }
+   }
+}
+matrix list `RS'
+
+if "`search'"=="" {
+
+di
+di "{hline 105}"
+di in green _col(50)  "Model 3"
+di "{hline 105}"
+di
+di in white _col(10) "Non uniform Recalibration"
+
+local continue=1
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
+   local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
+   local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
+}
+local prec_chi2=`chi22'
+local testNU_varchi2=0
+local testNU_p=1
+di "{hline 105}"
+di in gr                                _col(39) "Comparison with previous model"              _col(79) "Comparison with model 1"
+di in gr "Items" _col(18)  "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
+di "{hline 105}"
+
+
+while (`continue') {
+   local cpt=0
+   local testNU_varchi2_temp=0
+   local testNU_p_temp=0
+   local testNU_item_temp=0
+   local chi2encours_temp=-1
+   local continue=0
+   local sem
+   local var
+   forvalues j=1/`nbitems' {
+      local sem
+      local var
+      local already=0
+      forvalues i=1/`nbitems' {
+         if `RS'[`i',1]==0&`i'!=`j' {
+            local sem `sem' `sem`i''
+            local var `var' `var`i''
+         }
+         if `RS'[`i',1]==1&`i'!=`j' {
+            local sem `sem' `sem`i''
+            local var `var' `varrecNU`i''
+         }
+         else if `i'==`j'&`RS'[`j',1]==0 {
+            local sem `sem' `sem`i''
+            local var `var' `varrecNU`i''
+         }
+         else if `i'==`j'&`RS'[`j',1]==1 {
+            local sem `sem' `sem`i''
+            local var `var' `varrecNU`i''
+            local already=1
+         }
+      }
+      if (`already'!=1) {
+         qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)  method(`method')
+         qui estat gof
+         local chi2encours=r(chi2_ms)
+         if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') {
+            local continue=1
+            local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
+            local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp')
+            local testNU_item_temp=`j'
+            local chi2encours_tmp=`chi2encours'
+            local tmp=`chi2encours'
+         }
+         di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
+         local ++cpt
+      }
+   }
+   if (`testNU_item_temp'!=0) {
+      matrix `RS'[`testNU_item_temp',1]=1
+      local ++df3
+      local testNU_varchi2=`testNU_varchi2_temp'
+      local testNU_p=`testNU_p_temp'
+      local testNU_item_temp=0
+      local prec_chi2=`tmp'
+   }
+   if (`cpt'!=0) {
+      di "{hline 105}"
+   }
+}
+
+
+
+/**************************************************************************************************************
+Model 3 / Uniform recalibration
+***************************************************************************************************************/
+
+di
+di in white _col(10) "Uniform Recalibration"
+
+local continue=1
+local var
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
+   local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
+   if `RS'[`i',1]==1 {
+      local var "`var' `varrecNU`i''"
+   }
+   if `RS'[`i',1]==0 {
+      local var "`var' `var`i''"
+   }
+}
+local testU_varchi2=0
+local testU_p=1
+di "{hline 105}"
+di in gr                                _col(39) "Comparison with previous model"              _col(79) "Comparison with model 1"
+di in gr "Items" _col(18)  "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
+di "{hline 105}"
+
+while (`continue') {
+   local cpt=0
+   local testU_varchi2_temp=0
+   local testU_p_temp=0
+   local testU_item_temp=0
+   local chi2encours_temp=-1
+   local continue=0
+   local sem
+   forvalues j=1/`nbitems' {
+      local sem
+      local already=0
+      forvalues i=1/`nbitems' {
+         if `RS'[`i',2]==0&`i'!=`j' {
+            local sem `sem' `sem`i''
+         }
+         if `RS'[`i',2]==1&`i'!=`j' {
+            local sem `sem' `semrecU`i''
+         }
+         else if `i'==`j'&`RS'[`j',2]==0 {
+            local sem `sem' `semrecU`i''
+         }
+         else if `i'==`j'&`RS'[`j',2]==1 {
+            local sem `sem' `semrecU`i''
+            local already=1
+         }
+      }
+      if (`already'!=1) {
+         qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)  method(`method')
+         qui estat gof
+         local chi2encours=r(chi2_ms)
+         if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') {
+            local continue=1
+            local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
+            local testU_p_temp =1-chi2(1,`testU_varchi2_temp')
+            local testU_item_temp=`j'
+            local chi2encours_tmp=`chi2encours'
+            local tmp=`chi2encours'
+         }
+         di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
+         local ++cpt
+      }
+   }
+   if (`testU_item_temp'!=0) {
+      matrix `RS'[`testU_item_temp',2]=1
+      local ++df3
+      local testU_varchi2=`testU_varchi2_temp'
+      local testU_p=`testU_p_temp'
+      local testU_item_temp=0
+      local prec_chi2=`tmp'
+   }
+   if (`cpt'!=0) {
+       di "{hline 105}"
+   }
+}
+
+
+
+
+/**************************************************************************************************************
+Model 3 / Repriorisation
+***************************************************************************************************************/
+
+di
+di in white _col(10) "Repriorisation"
+
+local continue=1
+local var
+local sem
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
+   local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
+   local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
+   if `RS'[`i',1]==1 {
+      local var "`var' `varrecNU`i''"
+   }
+   if `RS'[`i',1]==0 {
+      local var "`var' `var`i''"
+   }
+}
+local testU_varchi2=0
+local testU_p=1
+di "{hline 105}"
+di in gr                                _col(39) "Comparison with previous model"              _col(79) "Comparison with model 1"
+di in gr "Items" _col(18)  "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
+di "{hline 105}"
+
+while (`continue') {
+   local cpt=0
+   local testR_varchi2_temp=0
+   local testR_p_temp=0
+   local testR_item_temp=0
+   local chi2encours_temp=-1
+   local continue=0
+   local sem
+   forvalues j=1/`nbitems' {
+      local sem
+      local already=0
+      forvalues i=1/`nbitems' {
+         if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' {
+            local sem `sem' `sem`i''
+         }
+         else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' {
+            local sem `sem' `semrecU`i''
+         }
+         else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' {
+            local sem `sem' `semrep`i''
+         }
+         else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' {
+            local sem `sem' `semrecUrep`i''
+         }
+         else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 {
+            local sem `sem' `semrep`i''
+         }
+         else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 {
+            local sem `sem' `semrecUrep`i''
+         }
+         else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 {
+            local already=1
+         }
+         else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 {
+            local sem `sem' `semrep`i''
+            local already=1
+         }
+         else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 {
+            local sem `sem' `semrecUrep`i''
+            local already=1
+         }
+      }
+      if (`already'!=1) {
+         qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)  method(`method')
+         qui estat gof
+         local chi2encours=r(chi2_ms)
+         if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') {
+            local continue=1
+            local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
+            local testR_p_temp =1-chi2(1,`testR_varchi2_temp')
+            local testR_item_temp=`j'
+            local chi2encours_tmp=`chi2encours'
+            local tmp=`chi2encours'
+         }
+         if ( `chi2encours'<`prec_chi2') {
+            di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
+         }
+         else {
+            di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) "Anavailable"
+         }
+         local ++cpt
+      }
+   }
+   if (`testR_item_temp'!=0) {
+      matrix `RS'[`testR_item_temp',3]=1
+      local ++df3
+      local testR_varchi2=`testR_varchi2_temp'
+      local testR_p=`testR_p_temp'
+      local testR_item_temp=0
+      local prec_chi2=`tmp'
+   }
+   if (`cpt'!=0) {
+      di "{hline 105}"
+   }
+}
+}
+
+/**************************************************************************************************************
+Model 3 Final
+***************************************************************************************************************/
+
+di
+local continue=1
+local var
+local sem
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
+   local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
+   local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
+   if `RS'[`i',1]==1 {
+      local var "`var' `varrecNU`i''"
+   }
+   if `RS'[`i',1]==0 {
+      local var "`var' `var`i''"
+   }
+   if `RS'[`i',2]==0&`RS'[`i',3]==0 {
+      local sem "`sem' `sem`i''"
+   }
+   if `RS'[`i',2]==0&`RS'[`i',3]==1 {
+      local sem "`sem' `semrep`i''"
+   }
+   if `RS'[`i',2]==1&`RS'[`i',3]==0 {
+      local sem "`sem' `semrecU`i''"
+   }
+   if `RS'[`i',2]==1&`RS'[`i',3]==1 {
+      local sem "`sem' `semrecUrep`i''"
+   }
+}
+qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)   method(`method')
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local truechange=`b'[1,`=`nbitems'*4+1']
+local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
+qui estat gof
+local tli3=r(tli)
+local cfi3=r(cfi)
+local srmr3=r(srmr)
+local rmsea3=r(rmsea)
+local ubrmsea3=r(ub90_rmsea)
+local lbrmsea3=r(lb90_rmsea)
+local chi23=r(chi2_ms)
+local dfc3=`df3'
+local p3=r(p_ms)
+
+
+
+/**************************************************************************************************************
+Bilan
+***************************************************************************************************************/
+
+di
+di  "{hline 74}"
+di in gr           _col(22) "Non uniform"       _col(46) "Uniform"
+di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(60) "Repriorisation"
+di  "{hline 74}"
+forvalues i=1/`nbitems' {
+   local recNU
+   local recU
+   local rep
+   if (`RS'[`i',1]==1) {
+      local recNU "*"
+   }
+   if (`RS'[`i',2]==1) {
+      local recU "*"
+   }
+   if (`RS'[`i',3]==1) {
+      local rep "*"
+   }
+   di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'"
+}
+di  "{hline 74}"
+
+
+/**************************************************************************************************************
+Model 4
+***************************************************************************************************************/
+
+qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local truechange=`b'[1,`=`nbitems'*4+1']
+local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
+qui estat gof,stat(all)
+local tli4=r(tli)
+local cfi4=r(cfi)
+local srmr4=r(srmr)
+local rmsea4=r(rmsea)
+local ubrmsea4=r(ub90_rmsea)
+local lbrmsea4=r(lb90_rmsea)
+local chi24=r(chi2_ms)
+local dfc4=`df3'+1
+local p4=r(p_ms)
+local chi2encours=r(chi2_ms)
+
+local z=`truechange'/sqrt(`Vtruechange')
+
+
+di
+di  "{hline 95}"
+di in gr "Models" _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
+di  "{hline 95}"
+di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1'  _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
+di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `dfc2' _col(30) %6.4f `p2' _col(40) %6.4f `rmsea2' _col(50) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2'  _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2'
+*di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3'  _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3'
+di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `dfc4' _col(30) %6.4f `p4' _col(40) %6.4f `rmsea4' _col(50) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4'  _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4'
+di  "{hline 95}"
+
+
+
+di
+di  "{hline 77}"
+di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value"
+di  "{hline 77}"
+di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))'
+di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))'
+di  "{hline 77}"
+
+di
+
+
+
+
+end
diff --git a/Modules/ado/personal/r/old/rsoort1 (2).ado b/Modules/ado/personal/r/old/rsoort1 (2).ado
new file mode 100644
index 0000000..76f1389
--- /dev/null
+++ b/Modules/ado/personal/r/old/rsoort1 (2).ado	
@@ -0,0 +1,584 @@
+*! version 1  25februar2013
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* rsoort: Response Shift detection with the Oort procedure
+*
+* Historic:
+* Version 1 (2013-02-25): Jean-Benoit Hardouin
+*
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* Copyright 2013 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+
+program define rsoort,eclass
+syntax varlist(min=1 numeric) [if] [in] [,METHod(string) UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPriorisation(varlist) noSearch]
+
+tokenize `varlist'
+local nbitems:word count `varlist'
+local mod=mod(`nbitems',2)
+if `mod'!=0 {
+  di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2"
+  error
+}
+
+if "`method'"=="" {
+   local method "ml"
+}
+local nbitems=`nbitems'/2
+
+di _col(20) "{hline 30}"
+di  _col(20) in gr "Time 1" _col(40) "Time 2"
+di _col(20) "{hline 30}"
+forvalues i=1/`nbitems' {
+    di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''"
+}
+di _col(20) "{hline 30}"
+
+
+/**************************************************************************************************************
+Model 1
+***************************************************************************************************************/
+
+qui sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0)  method(`method')
+qui estat gof, stat(all)
+local tli1=r(tli)
+local cfi1=r(cfi)
+local srmr1=r(srmr)
+local rmsea1=r(rmsea)
+local ubrmsea1=r(ub90_rmsea)
+local lbrmsea1=r(lb90_rmsea)
+local chi21=r(chi2_ms)
+local df1=r(df_ms)
+local dfc1=6*`nbitems'+1
+local p1=r(p_ms)
+*di
+*di in green "          ***********************************Model 1********************************************"
+*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
+*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1'  _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
+
+/**************************************************************************************************************
+Model 2
+***************************************************************************************************************/
+
+local sem
+local var
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local sem `sem' `sem`i''
+   local var `var' `var`i''
+}
+
+qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'     iterate(100)  method(`method')
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local truechange2=`b'[1,`=`nbitems'*4+1']
+local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
+qui estat gof, stat(all)
+local tli2=r(tli)
+local cfi2=r(cfi)
+local srmr2=r(srmr)
+local rmsea2=r(rmsea)
+local ubrmsea2=r(ub90_rmsea)
+local lbrmsea2=r(lb90_rmsea)
+local chi22=r(chi2_ms)
+local df2=r(df_ms)
+local dfc2=3*`nbitems'+3
+local p2=r(p_ms)
+
+local chi221=abs(`chi21'-`chi22')
+local df21=`df2'-`df1'
+local p21=1-chi2(`df21',`chi221')
+
+
+di "{hline 105}"
+di in gr                                _col(39) "Test of global Response-Shift "              _col(79) "Comparison with model 1"
+di in gr "Models" _col(18)  "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
+di "{hline 105}"
+di in gr "Model 1" _col(20) %8.2f in ye `chi21'
+di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' _col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'
+di "{hline 105}"
+
+
+/**************************************************************************************************************
+Model 3
+***************************************************************************************************************/
+
+
+/**************************************************************************************************************
+Model 3 / Non uniform recalibration
+***************************************************************************************************************/
+
+tempname RS  RSprec
+qui matrix `RS'=J(`nbitems',3,0)
+qui matrix `RSprec'=J(`nbitems',3,0)
+local df3=`dfc2'
+
+*set trace on
+
+
+forvalues i=1/`nbitems' {
+   local nbUR:word count `uniformrecalibration'
+   forvalues j=1/`nbUR' {
+      local itemj: word `j' of `uniformrecalibration'
+      if "``i''"=="`itemj'" {
+	     matrix `RS'[`i',2]=1
+      }
+   }
+   local nbNUR:word count `nonuniformrecalibration'
+   forvalues j=1/`nbNUR' {
+      local itemj: word `j' of `nonuniformrecalibration'
+     if "``i''"=="`itemj'" {
+	     matrix `RS'[`i',1]=1
+      }
+   }
+   local nbR:word count `repriorisation'
+   forvalues j=1/`nbR' {
+      local itemj: word `j' of `repriorisation'
+      if "``i''"=="`itemj'" {
+	     matrix `RS'[`i',3]=1
+      }
+   }
+}
+matrix list `RS'
+
+if "`search'"=="" {
+
+di
+di "{hline 105}"
+di in green _col(50)  "Model 3"
+di "{hline 105}"
+di
+di in white _col(10) "Non uniform Recalibration"
+
+local continue=1
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
+   local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
+   local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
+}
+local prec_chi2=`chi22'
+local testNU_varchi2=0
+local testNU_p=1
+di "{hline 105}"
+di in gr                                _col(39) "Comparison with previous model"              _col(79) "Comparison with model 1"
+di in gr "Items" _col(18)  "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
+di "{hline 105}"
+
+
+while (`continue') {
+   local cpt=0
+   local testNU_varchi2_temp=0
+   local testNU_p_temp=0
+   local testNU_item_temp=0
+   local chi2encours_temp=-1
+   local continue=0
+   local sem
+   local var
+   forvalues j=1/`nbitems' {
+      local sem
+      local var
+      local already=0
+      forvalues i=1/`nbitems' {
+         if `RS'[`i',1]==0&`i'!=`j' {
+            local sem `sem' `sem`i''
+            local var `var' `var`i''
+         }
+         if `RS'[`i',1]==1&`i'!=`j' {
+            local sem `sem' `sem`i''
+            local var `var' `varrecNU`i''
+         }
+         else if `i'==`j'&`RS'[`j',1]==0 {
+            local sem `sem' `sem`i''
+            local var `var' `varrecNU`i''
+         }
+         else if `i'==`j'&`RS'[`j',1]==1 {
+            local sem `sem' `sem`i''
+            local var `var' `varrecNU`i''
+            local already=1
+         }
+      }
+      if (`already'!=1) {
+         qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)  method(`method')
+         qui estat gof
+         local chi2encours=r(chi2_ms)
+         if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') {
+            local continue=1
+            local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
+            local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp')
+            local testNU_item_temp=`j'
+            local chi2encours_tmp=`chi2encours'
+            local tmp=`chi2encours'
+         }
+         di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
+         local ++cpt
+      }
+   }
+   if (`testNU_item_temp'!=0) {
+      matrix `RS'[`testNU_item_temp',1]=1
+      local ++df3
+      local testNU_varchi2=`testNU_varchi2_temp'
+      local testNU_p=`testNU_p_temp'
+      local testNU_item_temp=0
+      local prec_chi2=`tmp'
+   }
+   if (`cpt'!=0) {
+      di "{hline 105}"
+   }
+}
+
+
+
+/**************************************************************************************************************
+Model 3 / Uniform recalibration
+***************************************************************************************************************/
+
+di
+di in white _col(10) "Uniform Recalibration"
+
+local continue=1
+local var
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
+   local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
+   if `RS'[`i',1]==1 {
+      local var "`var' `varrecNU`i''"
+   }
+   if `RS'[`i',1]==0 {
+      local var "`var' `var`i''"
+   }
+}
+local testU_varchi2=0
+local testU_p=1
+di "{hline 105}"
+di in gr                                _col(39) "Comparison with previous model"              _col(79) "Comparison with model 1"
+di in gr "Items" _col(18)  "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
+di "{hline 105}"
+
+while (`continue') {
+   local cpt=0
+   local testU_varchi2_temp=0
+   local testU_p_temp=0
+   local testU_item_temp=0
+   local chi2encours_temp=-1
+   local continue=0
+   local sem
+   forvalues j=1/`nbitems' {
+      local sem
+      local already=0
+      forvalues i=1/`nbitems' {
+         if `RS'[`i',2]==0&`i'!=`j' {
+            local sem `sem' `sem`i''
+         }
+         if `RS'[`i',2]==1&`i'!=`j' {
+            local sem `sem' `semrecU`i''
+         }
+         else if `i'==`j'&`RS'[`j',2]==0 {
+            local sem `sem' `semrecU`i''
+         }
+         else if `i'==`j'&`RS'[`j',2]==1 {
+            local sem `sem' `semrecU`i''
+            local already=1
+         }
+      }
+      if (`already'!=1) {
+         qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)  method(`method')
+         qui estat gof
+         local chi2encours=r(chi2_ms)
+         if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') {
+            local continue=1
+            local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
+            local testU_p_temp =1-chi2(1,`testU_varchi2_temp')
+            local testU_item_temp=`j'
+            local chi2encours_tmp=`chi2encours'
+            local tmp=`chi2encours'
+         }
+         di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
+         local ++cpt
+      }
+   }
+   if (`testU_item_temp'!=0) {
+      matrix `RS'[`testU_item_temp',2]=1
+      local ++df3
+      local testU_varchi2=`testU_varchi2_temp'
+      local testU_p=`testU_p_temp'
+      local testU_item_temp=0
+      local prec_chi2=`tmp'
+   }
+   if (`cpt'!=0) {
+       di "{hline 105}"
+   }
+}
+
+
+
+
+/**************************************************************************************************************
+Model 3 / Repriorisation
+***************************************************************************************************************/
+
+di
+di in white _col(10) "Repriorisation"
+
+local continue=1
+local var
+local sem
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
+   local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
+   local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
+   if `RS'[`i',1]==1 {
+      local var "`var' `varrecNU`i''"
+   }
+   if `RS'[`i',1]==0 {
+      local var "`var' `var`i''"
+   }
+}
+local testU_varchi2=0
+local testU_p=1
+di "{hline 105}"
+di in gr                                _col(39) "Comparison with previous model"              _col(79) "Comparison with model 1"
+di in gr "Items" _col(18)  "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
+di "{hline 105}"
+
+while (`continue') {
+   local cpt=0
+   local testR_varchi2_temp=0
+   local testR_p_temp=0
+   local testR_item_temp=0
+   local chi2encours_temp=-1
+   local continue=0
+   local sem
+   forvalues j=1/`nbitems' {
+      local sem
+      local already=0
+      forvalues i=1/`nbitems' {
+         if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' {
+            local sem `sem' `sem`i''
+         }
+         else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' {
+            local sem `sem' `semrecU`i''
+         }
+         else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' {
+            local sem `sem' `semrep`i''
+         }
+         else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' {
+            local sem `sem' `semrecUrep`i''
+         }
+         else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 {
+            local sem `sem' `semrep`i''
+         }
+         else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 {
+            local sem `sem' `semrecUrep`i''
+         }
+         else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 {
+            local already=1
+         }
+         else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 {
+            local sem `sem' `semrep`i''
+            local already=1
+         }
+         else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 {
+            local sem `sem' `semrecUrep`i''
+            local already=1
+         }
+      }
+      if (`already'!=1) {
+         qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)  method(`method')
+         qui estat gof
+         local chi2encours=r(chi2_ms)
+         if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') {
+            local continue=1
+            local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
+            local testR_p_temp =1-chi2(1,`testR_varchi2_temp')
+            local testR_item_temp=`j'
+            local chi2encours_tmp=`chi2encours'
+            local tmp=`chi2encours'
+         }
+         if ( `chi2encours'<`prec_chi2') {
+            di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
+         }
+         else {
+            di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) "Anavailable"
+         }
+         local ++cpt
+      }
+   }
+   if (`testR_item_temp'!=0) {
+      matrix `RS'[`testR_item_temp',3]=1
+      local ++df3
+      local testR_varchi2=`testR_varchi2_temp'
+      local testR_p=`testR_p_temp'
+      local testR_item_temp=0
+      local prec_chi2=`tmp'
+   }
+   if (`cpt'!=0) {
+      di "{hline 105}"
+   }
+}
+}
+
+/**************************************************************************************************************
+Model 3 Final
+***************************************************************************************************************/
+
+di
+local continue=1
+local var
+local sem
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
+   local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
+   local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
+   if `RS'[`i',1]==1 {
+      local var "`var' `varrecNU`i''"
+   }
+   if `RS'[`i',1]==0 {
+      local var "`var' `var`i''"
+   }
+   if `RS'[`i',2]==0&`RS'[`i',3]==0 {
+      local sem "`sem' `sem`i''"
+   }
+   if `RS'[`i',2]==0&`RS'[`i',3]==1 {
+      local sem "`sem' `semrep`i''"
+   }
+   if `RS'[`i',2]==1&`RS'[`i',3]==0 {
+      local sem "`sem' `semrecU`i''"
+   }
+   if `RS'[`i',2]==1&`RS'[`i',3]==1 {
+      local sem "`sem' `semrecUrep`i''"
+   }
+}
+qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)   method(`method')
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local truechange=`b'[1,`=`nbitems'*4+1']
+local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
+qui estat gof
+local tli3=r(tli)
+local cfi3=r(cfi)
+local srmr3=r(srmr)
+local rmsea3=r(rmsea)
+local ubrmsea3=r(ub90_rmsea)
+local lbrmsea3=r(lb90_rmsea)
+local chi23=r(chi2_ms)
+local dfc3=`df3'
+local p3=r(p_ms)
+
+
+
+/**************************************************************************************************************
+Bilan
+***************************************************************************************************************/
+
+di
+di  "{hline 74}"
+di in gr           _col(22) "Non uniform"       _col(46) "Uniform"
+di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(60) "Repriorisation"
+di  "{hline 74}"
+forvalues i=1/`nbitems' {
+   local recNU
+   local recU
+   local rep
+   if (`RS'[`i',1]==1) {
+      local recNU "*"
+   }
+   if (`RS'[`i',2]==1) {
+      local recU "*"
+   }
+   if (`RS'[`i',3]==1) {
+      local rep "*"
+   }
+   di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'"
+}
+di  "{hline 74}"
+
+
+/**************************************************************************************************************
+Model 4
+***************************************************************************************************************/
+
+qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local truechange=`b'[1,`=`nbitems'*4+1']
+local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
+qui estat gof,stat(all)
+local tli4=r(tli)
+local cfi4=r(cfi)
+local srmr4=r(srmr)
+local rmsea4=r(rmsea)
+local ubrmsea4=r(ub90_rmsea)
+local lbrmsea4=r(lb90_rmsea)
+local chi24=r(chi2_ms)
+local dfc4=`df3'+1
+local p4=r(p_ms)
+local chi2encours=r(chi2_ms)
+
+local z=`truechange'/sqrt(`Vtruechange')
+
+
+di
+di  "{hline 95}"
+di in gr "Models" _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
+di  "{hline 95}"
+di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1'  _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
+di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `dfc2' _col(30) %6.4f `p2' _col(40) %6.4f `rmsea2' _col(50) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2'  _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2'
+*di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3'  _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3'
+di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `dfc4' _col(30) %6.4f `p4' _col(40) %6.4f `rmsea4' _col(50) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4'  _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4'
+di  "{hline 95}"
+
+
+
+di
+di  "{hline 77}"
+di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value"
+di  "{hline 77}"
+di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))'
+di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))'
+di  "{hline 77}"
+
+di
+
+
+
+
+end
diff --git a/Modules/ado/personal/r/old/rsoort1.ado b/Modules/ado/personal/r/old/rsoort1.ado
new file mode 100644
index 0000000..76f1389
--- /dev/null
+++ b/Modules/ado/personal/r/old/rsoort1.ado
@@ -0,0 +1,584 @@
+*! version 1  25februar2013
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* rsoort: Response Shift detection with the Oort procedure
+*
+* Historic:
+* Version 1 (2013-02-25): Jean-Benoit Hardouin
+*
+*
+* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
+* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam"
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* Copyright 2013 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+
+/***********************************************************************************************************
+INTRODUCTION
+***********************************************************************************************************/
+
+
+program define rsoort,eclass
+syntax varlist(min=1 numeric) [if] [in] [,METHod(string) UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPriorisation(varlist) noSearch]
+
+tokenize `varlist'
+local nbitems:word count `varlist'
+local mod=mod(`nbitems',2)
+if `mod'!=0 {
+  di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2"
+  error
+}
+
+if "`method'"=="" {
+   local method "ml"
+}
+local nbitems=`nbitems'/2
+
+di _col(20) "{hline 30}"
+di  _col(20) in gr "Time 1" _col(40) "Time 2"
+di _col(20) "{hline 30}"
+forvalues i=1/`nbitems' {
+    di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''"
+}
+di _col(20) "{hline 30}"
+
+
+/**************************************************************************************************************
+Model 1
+***************************************************************************************************************/
+
+qui sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0)  method(`method')
+qui estat gof, stat(all)
+local tli1=r(tli)
+local cfi1=r(cfi)
+local srmr1=r(srmr)
+local rmsea1=r(rmsea)
+local ubrmsea1=r(ub90_rmsea)
+local lbrmsea1=r(lb90_rmsea)
+local chi21=r(chi2_ms)
+local df1=r(df_ms)
+local dfc1=6*`nbitems'+1
+local p1=r(p_ms)
+*di
+*di in green "          ***********************************Model 1********************************************"
+*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
+*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1'  _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
+
+/**************************************************************************************************************
+Model 2
+***************************************************************************************************************/
+
+local sem
+local var
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local sem `sem' `sem`i''
+   local var `var' `var`i''
+}
+
+qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'     iterate(100)  method(`method')
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local truechange2=`b'[1,`=`nbitems'*4+1']
+local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
+qui estat gof, stat(all)
+local tli2=r(tli)
+local cfi2=r(cfi)
+local srmr2=r(srmr)
+local rmsea2=r(rmsea)
+local ubrmsea2=r(ub90_rmsea)
+local lbrmsea2=r(lb90_rmsea)
+local chi22=r(chi2_ms)
+local df2=r(df_ms)
+local dfc2=3*`nbitems'+3
+local p2=r(p_ms)
+
+local chi221=abs(`chi21'-`chi22')
+local df21=`df2'-`df1'
+local p21=1-chi2(`df21',`chi221')
+
+
+di "{hline 105}"
+di in gr                                _col(39) "Test of global Response-Shift "              _col(79) "Comparison with model 1"
+di in gr "Models" _col(18)  "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
+di "{hline 105}"
+di in gr "Model 1" _col(20) %8.2f in ye `chi21'
+di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' _col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'
+di "{hline 105}"
+
+
+/**************************************************************************************************************
+Model 3
+***************************************************************************************************************/
+
+
+/**************************************************************************************************************
+Model 3 / Non uniform recalibration
+***************************************************************************************************************/
+
+tempname RS  RSprec
+qui matrix `RS'=J(`nbitems',3,0)
+qui matrix `RSprec'=J(`nbitems',3,0)
+local df3=`dfc2'
+
+*set trace on
+
+
+forvalues i=1/`nbitems' {
+   local nbUR:word count `uniformrecalibration'
+   forvalues j=1/`nbUR' {
+      local itemj: word `j' of `uniformrecalibration'
+      if "``i''"=="`itemj'" {
+	     matrix `RS'[`i',2]=1
+      }
+   }
+   local nbNUR:word count `nonuniformrecalibration'
+   forvalues j=1/`nbNUR' {
+      local itemj: word `j' of `nonuniformrecalibration'
+     if "``i''"=="`itemj'" {
+	     matrix `RS'[`i',1]=1
+      }
+   }
+   local nbR:word count `repriorisation'
+   forvalues j=1/`nbR' {
+      local itemj: word `j' of `repriorisation'
+      if "``i''"=="`itemj'" {
+	     matrix `RS'[`i',3]=1
+      }
+   }
+}
+matrix list `RS'
+
+if "`search'"=="" {
+
+di
+di "{hline 105}"
+di in green _col(50)  "Model 3"
+di "{hline 105}"
+di
+di in white _col(10) "Non uniform Recalibration"
+
+local continue=1
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
+   local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
+   local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
+}
+local prec_chi2=`chi22'
+local testNU_varchi2=0
+local testNU_p=1
+di "{hline 105}"
+di in gr                                _col(39) "Comparison with previous model"              _col(79) "Comparison with model 1"
+di in gr "Items" _col(18)  "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
+di "{hline 105}"
+
+
+while (`continue') {
+   local cpt=0
+   local testNU_varchi2_temp=0
+   local testNU_p_temp=0
+   local testNU_item_temp=0
+   local chi2encours_temp=-1
+   local continue=0
+   local sem
+   local var
+   forvalues j=1/`nbitems' {
+      local sem
+      local var
+      local already=0
+      forvalues i=1/`nbitems' {
+         if `RS'[`i',1]==0&`i'!=`j' {
+            local sem `sem' `sem`i''
+            local var `var' `var`i''
+         }
+         if `RS'[`i',1]==1&`i'!=`j' {
+            local sem `sem' `sem`i''
+            local var `var' `varrecNU`i''
+         }
+         else if `i'==`j'&`RS'[`j',1]==0 {
+            local sem `sem' `sem`i''
+            local var `var' `varrecNU`i''
+         }
+         else if `i'==`j'&`RS'[`j',1]==1 {
+            local sem `sem' `sem`i''
+            local var `var' `varrecNU`i''
+            local already=1
+         }
+      }
+      if (`already'!=1) {
+         qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)  method(`method')
+         qui estat gof
+         local chi2encours=r(chi2_ms)
+         if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') {
+            local continue=1
+            local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
+            local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp')
+            local testNU_item_temp=`j'
+            local chi2encours_tmp=`chi2encours'
+            local tmp=`chi2encours'
+         }
+         di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
+         local ++cpt
+      }
+   }
+   if (`testNU_item_temp'!=0) {
+      matrix `RS'[`testNU_item_temp',1]=1
+      local ++df3
+      local testNU_varchi2=`testNU_varchi2_temp'
+      local testNU_p=`testNU_p_temp'
+      local testNU_item_temp=0
+      local prec_chi2=`tmp'
+   }
+   if (`cpt'!=0) {
+      di "{hline 105}"
+   }
+}
+
+
+
+/**************************************************************************************************************
+Model 3 / Uniform recalibration
+***************************************************************************************************************/
+
+di
+di in white _col(10) "Uniform Recalibration"
+
+local continue=1
+local var
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
+   local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
+   if `RS'[`i',1]==1 {
+      local var "`var' `varrecNU`i''"
+   }
+   if `RS'[`i',1]==0 {
+      local var "`var' `var`i''"
+   }
+}
+local testU_varchi2=0
+local testU_p=1
+di "{hline 105}"
+di in gr                                _col(39) "Comparison with previous model"              _col(79) "Comparison with model 1"
+di in gr "Items" _col(18)  "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
+di "{hline 105}"
+
+while (`continue') {
+   local cpt=0
+   local testU_varchi2_temp=0
+   local testU_p_temp=0
+   local testU_item_temp=0
+   local chi2encours_temp=-1
+   local continue=0
+   local sem
+   forvalues j=1/`nbitems' {
+      local sem
+      local already=0
+      forvalues i=1/`nbitems' {
+         if `RS'[`i',2]==0&`i'!=`j' {
+            local sem `sem' `sem`i''
+         }
+         if `RS'[`i',2]==1&`i'!=`j' {
+            local sem `sem' `semrecU`i''
+         }
+         else if `i'==`j'&`RS'[`j',2]==0 {
+            local sem `sem' `semrecU`i''
+         }
+         else if `i'==`j'&`RS'[`j',2]==1 {
+            local sem `sem' `semrecU`i''
+            local already=1
+         }
+      }
+      if (`already'!=1) {
+         qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)  method(`method')
+         qui estat gof
+         local chi2encours=r(chi2_ms)
+         if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') {
+            local continue=1
+            local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
+            local testU_p_temp =1-chi2(1,`testU_varchi2_temp')
+            local testU_item_temp=`j'
+            local chi2encours_tmp=`chi2encours'
+            local tmp=`chi2encours'
+         }
+         di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
+         local ++cpt
+      }
+   }
+   if (`testU_item_temp'!=0) {
+      matrix `RS'[`testU_item_temp',2]=1
+      local ++df3
+      local testU_varchi2=`testU_varchi2_temp'
+      local testU_p=`testU_p_temp'
+      local testU_item_temp=0
+      local prec_chi2=`tmp'
+   }
+   if (`cpt'!=0) {
+       di "{hline 105}"
+   }
+}
+
+
+
+
+/**************************************************************************************************************
+Model 3 / Repriorisation
+***************************************************************************************************************/
+
+di
+di in white _col(10) "Repriorisation"
+
+local continue=1
+local var
+local sem
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
+   local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
+   local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
+   if `RS'[`i',1]==1 {
+      local var "`var' `varrecNU`i''"
+   }
+   if `RS'[`i',1]==0 {
+      local var "`var' `var`i''"
+   }
+}
+local testU_varchi2=0
+local testU_p=1
+di "{hline 105}"
+di in gr                                _col(39) "Comparison with previous model"              _col(79) "Comparison with model 1"
+di in gr "Items" _col(18)  "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
+di "{hline 105}"
+
+while (`continue') {
+   local cpt=0
+   local testR_varchi2_temp=0
+   local testR_p_temp=0
+   local testR_item_temp=0
+   local chi2encours_temp=-1
+   local continue=0
+   local sem
+   forvalues j=1/`nbitems' {
+      local sem
+      local already=0
+      forvalues i=1/`nbitems' {
+         if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' {
+            local sem `sem' `sem`i''
+         }
+         else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' {
+            local sem `sem' `semrecU`i''
+         }
+         else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' {
+            local sem `sem' `semrep`i''
+         }
+         else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' {
+            local sem `sem' `semrecUrep`i''
+         }
+         else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 {
+            local sem `sem' `semrep`i''
+         }
+         else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 {
+            local sem `sem' `semrecUrep`i''
+         }
+         else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 {
+            local already=1
+         }
+         else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 {
+            local sem `sem' `semrep`i''
+            local already=1
+         }
+         else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 {
+            local sem `sem' `semrecUrep`i''
+            local already=1
+         }
+      }
+      if (`already'!=1) {
+         qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)  method(`method')
+         qui estat gof
+         local chi2encours=r(chi2_ms)
+         if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') {
+            local continue=1
+            local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
+            local testR_p_temp =1-chi2(1,`testR_varchi2_temp')
+            local testR_item_temp=`j'
+            local chi2encours_tmp=`chi2encours'
+            local tmp=`chi2encours'
+         }
+         if ( `chi2encours'<`prec_chi2') {
+            di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
+         }
+         else {
+            di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) "Anavailable"
+         }
+         local ++cpt
+      }
+   }
+   if (`testR_item_temp'!=0) {
+      matrix `RS'[`testR_item_temp',3]=1
+      local ++df3
+      local testR_varchi2=`testR_varchi2_temp'
+      local testR_p=`testR_p_temp'
+      local testR_item_temp=0
+      local prec_chi2=`tmp'
+   }
+   if (`cpt'!=0) {
+      di "{hline 105}"
+   }
+}
+}
+
+/**************************************************************************************************************
+Model 3 Final
+***************************************************************************************************************/
+
+di
+local continue=1
+local var
+local sem
+forvalues i=1/`nbitems' {
+   local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
+   local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
+   local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
+   local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
+   local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
+   local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
+   if `RS'[`i',1]==1 {
+      local var "`var' `varrecNU`i''"
+   }
+   if `RS'[`i',1]==0 {
+      local var "`var' `var`i''"
+   }
+   if `RS'[`i',2]==0&`RS'[`i',3]==0 {
+      local sem "`sem' `sem`i''"
+   }
+   if `RS'[`i',2]==0&`RS'[`i',3]==1 {
+      local sem "`sem' `semrep`i''"
+   }
+   if `RS'[`i',2]==1&`RS'[`i',3]==0 {
+      local sem "`sem' `semrecU`i''"
+   }
+   if `RS'[`i',2]==1&`RS'[`i',3]==1 {
+      local sem "`sem' `semrecUrep`i''"
+   }
+}
+qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)   method(`method')
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local truechange=`b'[1,`=`nbitems'*4+1']
+local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
+qui estat gof
+local tli3=r(tli)
+local cfi3=r(cfi)
+local srmr3=r(srmr)
+local rmsea3=r(rmsea)
+local ubrmsea3=r(ub90_rmsea)
+local lbrmsea3=r(lb90_rmsea)
+local chi23=r(chi2_ms)
+local dfc3=`df3'
+local p3=r(p_ms)
+
+
+
+/**************************************************************************************************************
+Bilan
+***************************************************************************************************************/
+
+di
+di  "{hline 74}"
+di in gr           _col(22) "Non uniform"       _col(46) "Uniform"
+di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(60) "Repriorisation"
+di  "{hline 74}"
+forvalues i=1/`nbitems' {
+   local recNU
+   local recU
+   local rep
+   if (`RS'[`i',1]==1) {
+      local recNU "*"
+   }
+   if (`RS'[`i',2]==1) {
+      local recU "*"
+   }
+   if (`RS'[`i',3]==1) {
+      local rep "*"
+   }
+   di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'"
+}
+di  "{hline 74}"
+
+
+/**************************************************************************************************************
+Model 4
+***************************************************************************************************************/
+
+qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var'  iterate(100)
+tempname b V
+matrix `b'=e(b)
+matrix `V'=e(V)
+local truechange=`b'[1,`=`nbitems'*4+1']
+local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
+qui estat gof,stat(all)
+local tli4=r(tli)
+local cfi4=r(cfi)
+local srmr4=r(srmr)
+local rmsea4=r(rmsea)
+local ubrmsea4=r(ub90_rmsea)
+local lbrmsea4=r(lb90_rmsea)
+local chi24=r(chi2_ms)
+local dfc4=`df3'+1
+local p4=r(p_ms)
+local chi2encours=r(chi2_ms)
+
+local z=`truechange'/sqrt(`Vtruechange')
+
+
+di
+di  "{hline 95}"
+di in gr "Models" _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
+di  "{hline 95}"
+di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1'  _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
+di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `dfc2' _col(30) %6.4f `p2' _col(40) %6.4f `rmsea2' _col(50) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2'  _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2'
+*di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3'  _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3'
+di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `dfc4' _col(30) %6.4f `p4' _col(40) %6.4f `rmsea4' _col(50) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4'  _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4'
+di  "{hline 95}"
+
+
+
+di
+di  "{hline 77}"
+di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value"
+di  "{hline 77}"
+di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))'
+di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))'
+di  "{hline 77}"
+
+di
+
+
+
+
+end
diff --git a/Modules/ado/personal/r/raschfit.ado b/Modules/ado/personal/r/raschfit.ado
new file mode 100644
index 0000000..d363b89
--- /dev/null
+++ b/Modules/ado/personal/r/raschfit.ado
@@ -0,0 +1,340 @@
+*! Raschfit version 4 (19 December 2012)
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* Stata program : Raschfit
+* The Raschfit and the Raschfit-fast procedures to construct sub-scales of items
+*
+* Historic
+* Version 1 (2004-05-06) [Jean-Benoit Hardouin]
+* Version 2 (2004-06-08) [Jean-Benoit Hardouin]
+* Version 3 (2005-12-28) [Jean-Benoit Hardouin]
+* Release 3.1 (January 29, 2006) [Jean-Benoit Hardouin] /*MEAN option in raschtestv7, correction of a bug when there is several scales*/
+* Release 4 (December 19, 2019) [Jean-Benoit Hardouin] /*identifiant variable for raschtest and mmsrm*/
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences  (UPRES EA 4275 SPHERE)
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* News about this program :http://www.anaqol.org
+*
+* Copyright 2004-2006, 2012 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+************************************************************************************************************
+
+
+program define raschfit,rclass
+version 7
+syntax varlist(min=2 numeric) [,KERnel(integer 0) NBSCales(integer 1) ITEMSorder(string) nofast ]
+if "`itemsorder'"=="" {
+        local itemsorder mspinv
+}
+local nbitemstot : word count `varlist'
+tokenize `varlist'
+
+tempfile raschfitfile
+qui save `raschfitfile',replace
+preserve
+
+tempname affect
+matrix define `affect'=J(1,`nbitemstot',0)
+matrix colnames  `affect'=`varlist'
+
+tempvar id
+gen `id'=_n
+
+tempname rep item  matbetadim1 matbetadim2
+if `kernel'!=0 {
+   local listkernel
+   forvalues i=1/`kernel' {
+             local listkernel `listkernel' `rep'`i'
+             matrix `affect'[1,`i']=1
+   }
+}
+
+local dim=0
+local nbitemsnosel=`nbitemstot'
+local nbitemstotdim1=`nbitemstot'
+local nbitemsnoselukernel=`nbitemstot'-`kernel'
+
+
+tempvar id betadim1 betadim2
+forvalues i=1/`nbitemstot' {
+      qui drop if ``i''==.
+      rename ``i'' `rep'`i'
+}
+qui gen `id'=_n
+tempfile filescale
+qui save `filescale',replace
+
+di in green "{hline 55}"
+qui count
+local N=r(N)
+if "`fast'"!="" {
+   di in green "Method: " in ye "Raschfit"
+}
+else {
+   di in green "Method: " in ye "Raschfit-Fast"
+}
+di in green "Number of individuals: " in ye `N' in green " (with none missing values)"
+di in green "Number of items: " in ye `nbitemstot'
+di in green "{hline 55}"
+di
+di in green "{hline 100}"
+if "`fast'"!="" {
+   di in green "Model 1: " in ye "Rasch model"
+   di in green "Model 2: " in ye "MMSRM"
+}
+else {
+   di in green "Model 1: " in ye "Rasch model"
+   di in green "Model 2: " in ye "Adapted Rasch model (the response of the new item is not influenced by the latent trait)"
+}
+di in green "Order of the items:" _c
+if "`itemsorder'"=="order" {
+   di in ye " order of {it:varlist}"
+}
+else if "`itemsorder'"=="msp" {
+   di in ye " Obtained with MSP (from the first selected item to the last one)"
+}
+else if "`itemsorder'"=="mspinv" {
+   di in ye " Obtained with MSP (from the last selected item to the first one)"
+}
+if `kernel'!=0 {
+   di in green "Kernel of the first scale: " _c
+   forvalues i=1/`kernel' {
+       di in ye " ``i''" _c
+   }
+   di
+}
+di in green "{hline 100}"
+di
+
+while `nbitemsnosel'>2&`dim'<`nbscales' {
+      use `filescale',replace
+      local iteration=0
+      local dim=`dim'+1
+      if `dim'>1 {
+         local kernel=0
+         local listkernel
+      }
+
+      di in green "SCALE: " in yellow `dim'
+      di in green "{hline 9}"
+      di
+      tempname result`dim'
+      local listitemsnosel
+      local varlist`dim'
+      tokenize `varlist'
+      forvalues i=1/`nbitemstot' {
+            if `affect'[1,`i']==0 {
+                   local varlist`dim' `varlist`dim'' ``i''
+                   local listitemsnosel `listitemsnosel' `rep'`i'
+            }
+      }
+      local nbitemsnosel:word count `listitemsnosel'
+      if `dim'>1 {
+            local nbitemstotdim`dim':word count `listitemsnosel'
+      }
+
+      if `kernel'>=2 {
+            local fixed=`kernel'
+      }
+      else {
+            local fixed=2
+      }
+      matrix define `result`dim''=J(`=`nbitemstotdim`dim''-`fixed'',`=`nbitemstotdim`dim''+7',0)
+
+      tempname order`dim' affect`dim'
+      matrix `order`dim''=J(1,`nbitemstotdim`dim'',0)
+      matrix `affect`dim''=J(1,`nbitemstotdim`dim'',0)
+
+      if "`itemsorder'"=="msp"|"`itemsorder'"=="mspinv" {
+            di in green _col(0) "The program is ordering the items"
+            di
+            qui msp `listkernel' `listitemsnosel',c(-99)  notest kernel(`kernel')
+            local scale1 "`r(scale1)'"
+            local scalenum1 "`r(scalenum1)'"
+            tokenize `scalenum1'
+            local listitemsselnum
+            forvalues j=`=`nbitemstotdim`dim''+1-`fixed''/`nbitemstotdim`dim'' {
+                matrix `order`dim''[1,`j']=1
+                local k:word `j' of `scalenum1'
+                matrix `affect`dim''[1,`k']=1
+                local listitemsselnum `listitemsselnum' `k'
+            }
+            forvalues j=1/`nbitemsnosel' {
+                matrix `order`dim''[1,`j']=`=`nbitemsnosel'+1-`j''
+            }
+            tokenize `scale1'
+            local listitemssel ``=`nbitemstotdim`dim''-1'' ``nbitemstotdim`dim'''
+
+            local listitemsnosel
+            local listitemsnoselnum
+
+            if "`itemsorder'"=="mspinv" {
+                forvalues j=1/`=`nbitemstotdim`dim''-`fixed'' {
+                      local listitemsnosel `listitemsnosel' ``j''
+                      local k:word `j' of `scalenum1'
+                      local listitemsnoselnum `listitemsnoselnum' `k'
+                }
+            }
+            else if "`itemsorder'"=="msp"{
+                 forvalues j=`=`nbitemstotdim`dim''-`fixed''(-1)1 {
+                      local listitemsnosel  `listitemsnosel' ``j''
+                      local k:word `j' of `scalenum1'
+                      local listitemsnoselnum  `listitemsnoselnum' `k'
+                 }
+            }
+      }
+      else if "`itemsorder'"=="order" {
+           tokenize `listkernel' `varlist`dim''
+           local listitemssel
+           local listitemsselnum
+           local listitemsnosel
+           local listitemsnoselnum
+           forvalues j=1/`fixed'{
+                     local listitemssel `listitemssel' `rep'`j'
+                     local listitemsselnum `listitemsselnum' `j'
+                     matrix `affect`dim''[1,`j']=1
+           }
+           forvalues j=`=`fixed'+1'/`nbitemstotdim`dim'' {
+                     local listitemsnosel `listitemsnosel' `rep'`j'
+                     local listitemsnoselnum `listitemsnoselnum' `j'
+           }
+      }
+
+      if `dim'>1 {
+             tokenize `varlist`dim''
+      }
+      else {
+             tokenize `varlist'
+      }
+
+      local nbitemsnosel:word count `listitemsnosel'
+      local list
+      tokenize `varlist`dim''
+      forvalues i=1/`=`nbitemsnosel'+`fixed'' {
+            local tmp:word `i' of `listitemsnoselnum' `listitemsselnum'
+            local list `list' ``tmp''
+      }
+      matrix colnames `result`dim''=`list'  Iteration Nbitems ll1 AIC1 ll2 AIC2 Selected
+
+      di _col(0) in green "The kernel of the scale is " in yellow _continue
+      forvalues i=1/`fixed' {
+            local inum:word `i' of `listitemsselnum'
+            di in yellow "``inum'' " _continue
+      }
+      di
+      di
+      tokenize `listitemsnosel'
+      di in green "{hline 90}"
+      di in green _col(36) "Log-Likelihood" _col(58) "Akaike Criterion (AIC)"
+      di in green _col(4) "Iteration" _col(20) "New Item" _col(34) "Model 1" _col(47) "Model 2" _col(60) "Model 1" _col(73) "Model 2" _col(81) "Selected"
+      di in green "{hline 90}"
+      forvalues i=1/`=`nbitemsnosel-2'' {
+            local iteration=`iteration'+1
+            qui use `filescale' , clear
+            local i2:word `i' of `listitemsnosel'
+            local i2num:word `i' of `listitemsnoselnum'
+            qui keep `id' `listitemssel' `i2'
+            tempname score1 score2
+            qui gen `score2'=0
+            tokenize `listitemssel'
+            local nbitemssel: word count `listitemssel'
+            forvalues j=1/`i' {
+                      local j2num:word `j' of `listitemsnoselnum'
+                      if `affect`dim''[1,`j2num']==1 {
+                            matrix `result`dim''[`iteration',`j']=1
+                      }
+            }
+            forvalues j=1/`nbitemssel' {
+                      local j2:word `j' of `listitemssel'
+                      local j2num:word `j' of `listitemsselnum'
+                      qui replace `score2'=`score2'+`j2'
+            }
+            tokenize `listitemsnosel'
+            qui gen `score1'=`score2'+`i2'
+            forvalues j=`=`nbitemsnosel'+1'/`=`nbitemsnosel'+`nbitemssel'' {
+                      matrix `result`dim''[`iteration',`j']=1
+            }
+            matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+1']=`iteration'
+            matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+2']=`nbitemssel'
+            matrix `result`dim''[`iteration',`i']=2
+
+            if "`fast'"=="" {
+                        qui count
+                        local N=r(N)
+*                        di "qui raschtestv7 `listitemssel' `i2' , mean method(cml) test(none)"
+                        qui raschtestv7 `listitemssel' `i2' , mean method(cml) test(none) id(`id')
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+3']=r(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+4']=2*(-r(ll)+(2*`nbitemssel'+3))
+
+                        local nb1:word count `listitemssel'
+                        qui raschtestv7 `listitemssel',trace test(none) mean id(`id')
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=r(ll)
+                        qui logit `i2'
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=`result`dim''[`iteration',`=`nbitemstotdim`dim''+5']+e(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+6']=2*(-`result`dim''[`iteration',`=`nbitemstotdim`dim''+5']+(2*`nbitemssel'+3))
+            }
+            else {
+                        qui count
+                        local N=r(N)
+                        qui raschtestv7 `listitemssel' `i2' , method(mml) test(none) id(`id')
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+3']=r(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+4']=2*(-r(ll)+`nbitemssel'+2)
+
+                        local nb1:word count `listitemssel'
+                        qui mmsrm `listitemssel' `i2' , part(`nb1' 1) iterate(20) id(`id')
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=e(ll)
+                        matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+6']=2*(-e(ll)+`nbitemssel'+4)
+            }
+            tokenize `listkernel' `varlist`dim''
+            di in ye _col(4) %9.0f `iteration' _col(14) %14s abbrev("``i2num''",14) _col(29) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+3'] _col(42) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+5'] _col(55) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+4'] _col(68) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+6'] _c
+            if `result`dim''[`iteration',`=`nbitemstot'+4']<=`result`dim''[`iteration',`=`nbitemstot'+6'] {
+                 matrix `result`dim''[`iteration',`i']=1
+                 matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+7']=1
+                 local nbitemssel=`nbitemssel'+1
+                 local nbitemsnosel=`nbitemsnosel'-1
+*                 local listitemssel `listitemssel' `rep'`i2num'
+                 local listitemssel `listitemssel' `i2'
+                 local listitemsselnum `listitemsselnum' `i2num'
+                 matrix `affect`dim''[1,`i2num']=1
+                 di in ye _col(88) "X"
+            }
+            else {
+                 matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+7']=2
+                 di
+            }
+     }
+     di in green "{hline 90}"
+     return matrix result`dim' `result`dim''
+     local j=`kernel'+1
+     forvalues i=`=`kernel'+1'/`nbitemstot' {
+            if `affect'[1,`i']==0 {
+                 if `affect`dim''[1,`j']==1 {
+                        matrix `affect'[1,`i']=`dim'
+                 }
+            local j=`j'+1
+            }
+     }
+}
+use `raschfitfile',clear
+
+return matrix affect `affect'
+
+end
diff --git a/Modules/ado/personal/r/raschfit.hlp b/Modules/ado/personal/r/raschfit.hlp
new file mode 100644
index 0000000..3585db6
--- /dev/null
+++ b/Modules/ado/personal/r/raschfit.hlp
@@ -0,0 +1,70 @@
+{smcl}
+{* 208December2005}{...}
+{hline}
+help for {hi:raschfit}{right:Jean-Benoit Hardouin}
+{hline}
+
+{title:The Raschfit procedure}
+
+{p 8 14 2}{cmd:raschfit} {it:varlist} {cmd:,} [{cmdab:ker:nel}({it:#}) {cmdab:nbsc:ales}({it:#}) {cmdab:items:order}({it:keyword}) {cmdab:nofast}]
+
+{title:Description}
+
+{p 4 8 2}{cmd:raschfit} realizes the Raschfit algorithm defined by Hardouin and
+Mesbah (2004). This method selects sub-scales of items which fit a
+Rasch model. The method begin with a kernel of items (two or more items)
+defined by the user. At each step, the method uses a new item and verifies if this
+new item is explained by the same latent trait than the already selected items.
+If not, the items is not selected. The former version of the Raschfit algorithm
+is based on the comparison of two model: A Rasch model and a Multidimensional 
+Marginally Sufficient Rasch Model (MMSRM). These two models are compared by the
+Akaike Information Criterion (AIC). A faster version of the algorithm (Raschfit-Fast)
+compares the Rasch model and an adapted version of this model where the response 
+to the "new" item is not explained by the latent trait. Raschfit-Fast is executed
+by default.
+
+{title:Options}
+
+{p 4 8 2}{cmd:kernel}({it:#}) defines the # first items of {it:varlist} as the kernel 
+of the first sub-scale (by default with {cmd:itemsorder}({it:order}), this number is 
+fixed to 2).
+
+{p 4 8 2}{cmd:nbscales}({it:#}) defines the maximal number of sub-scales (by default,
+only one sub-scale is selected).
+
+{p 4 8 2}{cmd:itemsorder}({it:keyword}) defines the order of the items. If you type 
+{it:order}, the kernel is composed of the first items defined in {it:varlist},
+and the items are tested in the same order than in {it:varlist}. 
+If you type {it:msp} or {it:mspinv}, a Mokken Scale Procedure is run under 
+the items (the {it:msp} and {it:loevH} Stata programs are necessary) and the 
+items are selected from the first order selected by this procedure to the last 
+one (with {it:msp}), or in the inverse order (with {it:mspinv}). The method {it:msp} 
+is generaly more robust, but is longer to run. By default, the program uses {it:msp}.
+
+{p 4 8 2}{cmd:nofast} allows to execute the former version of the algorithm.
+
+{title:Example}
+
+{p 4 8 2}{cmd:. raschfit itemA* , itemsorder(order)}
+
+{p 4 8 2}{cmd:. raschfit itemA1-itemA7 , itemsorder(msp) kernel(4) nofast}
+
+{p 4 8 2}{cmd:. raschfit item* }
+
+{title:References}
+
+{p 4 8 2} Hardouin J.-B. and Mesbah M. {it:Clustering binary variables in subscales using an extended Rasch model and Akaike Information Criterion}, Communication in Statistics – Theory and methods}, {cmd:33}(6), pp. 1277-1294, 2004
+
+{p 4 8 2} Hardouin J.-B. {it:Construction d'échelles d'items unidimensionnelles en qualité de vie (Item selection in unidimensional scale applied to the Quality of Life)}, PhD thesis of the University René Descartes - Paris 5, 
+France, 201 pp, 2005
+
+{p 4 8 2} Hardouin J.-B. and Mesbah M. {it:Fast Clustering of Binary Variables in Subscales}, Unpublished document, 2005.
+
+{title:Author}
+
+{p 4 8 2} Jean-Benoit Hardouin, Regional Health Observatory (ORS) - 1, rue Porte
+Madeleine - BP 2439 - 45032 Orleans Cedex 1 - France. You can contact the
+author at
+{browse "mailto:jean-benoit.hardouin@orscentre.org":jean-benoit.hardouin@orscentre.org}
+and visit the websites {browse "http://anaqol.free.fr":AnaQol}
+and {browse "http://freeirt.free.fr":FreeIRT}
diff --git a/Modules/ado/personal/r/raschlong.ado b/Modules/ado/personal/r/raschlong.ado
new file mode 100644
index 0000000..168653e
--- /dev/null
+++ b/Modules/ado/personal/r/raschlong.ado
@@ -0,0 +1,229 @@
+*! version 1 : February 15th, 2012
+*! Myriam Blanchin
+************************************************************************************************************
+* raschlong: Estimation of the parameters of a model of the Rasch family in a longitudinal setting
+*
+* Version 1 : February 15th, 2012: pcm et rasch, contraintes sur la matrice de variance-covariance et difficultés d'items fixées 
+*
+************************************************************************************************************/
+
+program define raschlong,eclass
+syntax varlist [, NBT(int 2) DIFFiculties(string) VAR(string) ]
+
+*the dataset should be in wide format
+*the matrix of difficulties should contain `nbit' rows and `nbmodpos' columns
+*the item parameters are assumed to be constant with time
+*same number of modalities for each item
+*varlist should contain for each timepoint the list of variables containing the answers to the items - example: T1item1 T1item2 T1item3 T2item1 T2item2 T2item3
+preserve
+
+tempname diff varcov item id temps one obs estbeta estvar 
+/*di "item" "`item'"
+di "temps" "`temps'"
+di "obs" "`obs'"
+di "diff" "`diff'"
+di "varcov" "`varcov'"
+di "id" "`id'"
+di "one" "`one'"*/
+*verif varlist
+tokenize `varlist'
+local nbittot:word count `varlist'
+local nbit=`nbittot'/`nbt'
+if `=int(`nbit')'!=`nbit'{
+	di in red "The number of variables should be equal to (the number of items * the number of timepoints). Please correct it."
+	error 198
+	exit
+}
+
+
+/*verif nb diff items*/
+if "`difficulties'"!=""{
+	matrix `diff'=`difficulties'
+	if `nbit'!=`=rowsof(`diff')'{
+		di in red "The number of rows of the matrix of item parameters should be equal to the number of items. Please correct it."
+		error 198
+		exit
+	 }
+	local nbmodat=colsof(`diff')+1
+}
+else{
+	local modcount=word("`varlist'",1)
+	qui tab `modcount'
+    local nbmodat=r(r)
+}
+
+*verif matcov
+if "`var'"!=""{
+	matrix `varcov'=`var'
+	if `=rowsof(`var')'!=`nbt'{
+		di in red "The covariance matrix is incorrectly specified. Please correct it."
+		error 198
+		exit
+	}
+}
+
+qui{
+	*reshape of the dataset
+	gen `one'=1
+	collapse(sum) wt2=`one', by (`varlist')
+	*list in 1/3
+	forvalues t=1/`nbt'{
+		forvalues i=1/`nbit'{
+			local vartemp=word("`varlist'",`=(`t'-1)*`nbit'+`i'')
+			gen tps`t'item`i'=`vartemp'
+		}
+	}
+
+	gen `id'=_n
+	local list=""
+	forvalues i=1/`nbit'{
+		local list="`list' tps@item`i'"
+	}
+	reshape long `list', i(`id') j(`temps')
+	*list in 1/20
+	reshape long tpsitem, i(`id' `temps') j(`item')
+	*list in 1/20
+	drop if tpsitem==.
+	gen `obs'=_n
+	expand `nbmodat'
+	sort `id' `temps' `item' `obs'
+	*list in 1/20
+	tab `temps', gen(t)
+	forvalues t=1/`nbt'{
+		by `obs', sort: gen x`t'=(_n-1)*t`t'
+	}
+	gen chosen=.
+	forvalues t=1/`nbt'{
+		replace chosen=tpsitem==x`t' if `temps'==`t'
+	}
+	tab `item', gen(it)
+
+	if "`difficulties'"==""{
+		forvalues i=1/`nbit'{
+			forvalues g=1/`=`nbmodat'-1'{
+				gen d`i'_`g'=.
+			}
+		}
+		forvalues t=1/`nbt'{
+			forvalues i=1/`nbit'{
+				forvalues g=1/`=`nbmodat'-1'{
+					replace d`i'_`g'=-1*it`i'*(x`t'>=`g') if `temps'==`t'
+				}
+			}
+		}
+	}
+	else{
+		gen offset=0
+		forvalues t=1/`nbt'{
+			forvalues i=1/`nbit'{
+				local sumdiff=0 
+				forvalues g=1/`=`nbmodat'-1'{
+					local sumdiff=`sumdiff'-`diff'[`i',`g']
+					replace offset=`sumdiff' if it`i'==1 & x`t'==`g'
+				}
+			}			
+		}
+	}
+	*list in 1/25
+	local listeq ""
+	forvalues t=1/`nbt'{
+		eq slope`t':x`t'
+		local listeq "`listeq' slope`t'"
+	}
+	if "`var'"!=""{
+		matrix C=cholesky(`varcov')
+		constraint define 1 [__01_1]x1=`=C[1,1]'
+		constraint define 2 [__01_2]x2=`=C[2,2]'
+		constraint define 3 [__01_2_1]_cons=`=C[2,1]'
+	}
+}
+tempname b V
+if "`difficulties'"==""{
+	if "`var'"==""{
+		gllamm x1-x`nbt' d1_1-d`nbit'_`=`nbmodat'-1',i(`id') eqs(`listeq') link(mlogit) expand(`obs' chosen o) weight(wt) nocons nrf(`nbt') adapt
+	}
+	else{
+		gllamm x1-x`nbt' d1_1-d`nbit'_`=`nbmodat'-1',i(`id') eqs(`listeq') link(mlogit) constraints(1 2 3)  expand(`obs' chosen o) weight(wt) nocons nrf(`nbt') adapt
+	}
+	matrix `b'=e(b)
+	matrix EstDiff=J(`nbit',`=`nbmodat'-1',.)
+	forvalues j=1/`nbit'{
+		matrix EstDiff[`j',1]=`b'[1,`=`nbt'+(`j'-1)*(`nbmodat'-1)'..`=`nbt'-1+`j'*(`nbmodat'-1)']
+	}
+
+}
+else{
+	if "`var'"==""{
+		gllamm x1-x`nbt',i(`id') eqs(`listeq') link(mlogit) expand(`obs' chosen o) weight(wt) nocons nrf(`nbt') adapt offset(offset)
+	}
+	else{
+		gllamm x1-x`nbt',i(`id') eqs(`listeq') link(mlogit) constraints(1 2 3) expand(`obs' chosen o) weight(wt) nocons nrf(`nbt') adapt offset(offset)
+	}
+	matrix `b'=e(b)
+}
+matrix `V'=e(V)
+matrix EstMu=`b'[1,1..`=`nbt'-1']
+matrix Var=e(chol)*e(chol)'
+matrix se2=vecdiag(`V'[1..`=`nbt'-1',1..`=`nbt'-1'])
+
+/*if test
+test x2=x3=0
+ r(chi2)
+  r(df)
+  r(p)
+*/
+di
+di
+di in gr "{hline 91}"
+di in gr _col(39) "RASCH FAMILY MODEL"
+di in gr "{hline 91}"
+di in gr "Number of timepoints:   " in ye `nbt'
+di in gr "Number of items:   " in ye `nbit'
+di in gr "Number of modalities per item:   " in ye `nbmodat'
+di in gr "{hline 91}"
+
+local collist ""
+forvalues i=1/`=`nbmodat'-1'{
+	local collist "`collist' dj_`i'"
+}
+local rowlist ""
+forvalues i=1/`nbit'{
+	local rowlist "`rowlist' item`i'"
+}
+	
+if "`difficulties'"==""{
+	di in gr "Item parameters estimations:"
+	matrix colnames EstDiff = `collist'
+	matrix rownames EstDiff = `rowlist'
+	matrix list EstDiff,noheader format(%7.3f)
+	ereturn matrix Diff=EstDiff
+}
+else{
+	di in gr "Item parameters fixed to:"
+	matrix colnames `diff' = `collist'
+	matrix rownames `diff' = `rowlist'
+	matrix list `diff',noheader format(%7.3f)
+	ereturn matrix Diff=`diff'
+}
+di
+di
+if "`var'"==""{
+	di in gr "Covariance matrix estimations:"
+}
+else{
+	di in gr "Covariance matrix fixed to:"
+}
+matrix list Var,noheader nonames format(%7.3f)
+di
+di
+di in gr "Time effect estimations:"
+di in gr _col(19) "Coef" _col(29) "S.E."
+forvalues t=1/`=`nbt'-1'{
+	di in gr "Time" `=`t'+1' in ye _col(16) %7.2f EstMu[1,`t'] _col(26) %7.2f `=sqrt(se2[1,`t'])'
+}
+
+ereturn matrix Var=Var
+
+
+
+end
diff --git a/Modules/ado/personal/r/raschlongitudinal2.ado b/Modules/ado/personal/r/raschlongitudinal2.ado
new file mode 100644
index 0000000..24aa04f
--- /dev/null
+++ b/Modules/ado/personal/r/raschlongitudinal2.ado
@@ -0,0 +1,210 @@
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+program define raschlongitudinal2,rclass
+syntax [varlist] [, n(int 100)  diff(string) Mu(string) Sigma(string) Nodes(int 12) fast]
+version 11
+tempfile raschlongitudinalfile
+capture qui save "`raschlongitudinalfile'",replace
+
+if "`diff'"=="" {
+   tempname diff
+   *matrix `diff'=[-1\0\1]
+   matrix `diff'=[-1\-.5\0\.5\1]
+}
+
+if "`mu'"=="" {
+   tempname mu
+   matrix `mu'=[0,0]
+}
+if "`sigma'"=="" {
+   tempname sigma
+   matrix `sigma'=[1,0\0,1]
+}
+
+local nbitems=rowsof(`diff')
+*local J=rowsof(`diff')+1
+*local Nbit=rowsof(`diff')*2
+di in gr "Number of individuals in the study:  " in ye `n'
+di in gr "Number of items: " in ye  `nbitems'
+di in green "Difficulties parameters of the items: " _c
+tempname dt
+matrix `dt'=`diff' ' ''
+matrix list `dt',noblank nohalf nonames noheader
+di in green "mean of the latent traits: " _c
+matrix list `mu',noblank nohalf nonames noheader
+di in green "variance matrix of the latent traits: " _c
+di
+matrix list `sigma',noblank nohalf nonames noheader
+
+
+if "`data'"=="" {
+   clear
+   local temp=2^(`nbitems'*2)
+   qui range x1 0 `=`temp'-1' `temp'
+   qui g t=x1
+   qui g x2=x1
+   qui g x=x2
+   loc i=1
+   qui count if t>0
+   loc z=r(N)
+   qui while `z'>0 {
+      qui g item`i'=mod(t,2^`i')==2^`=`i'-1'
+      qui replace t=t-item`i'*2^`=`i'-1'
+      qui count if t>0
+      loc z=r(N)
+      loc i=`i'+1
+   }
+}
+drop t
+*edit
+
+if "`fast'"=="" {
+      qui gen proba=.
+      *qui gen proba2=.
+      forvalues i=1/`temp' {
+         local int1=1
+         local int2=1
+         forvalues j=1/`nbitems' {
+              qui su item`j' in `i'
+              local rep=r(mean)
+              local diffic=`diff'[`j',1]
+              local int1 "`int1'*exp(`rep'*(x1-`diffic'))/(1+exp(x1-`diffic'))"
+              *di `j'
+              *di `int1'
+           }
+           *qui gausshermite `int1', mu(1) sigma(2) display
+          * di r(int)
+           *qui replace proba=r(int)  in `i'
+           
+           forvalues k=`=`nbitems'+1' /`=2*`nbitems'' {
+              qui su item`k' in `i'
+              local rep=r(mean)
+              local diffic=`diff'[`=`k'-`nbitems'',1]
+              local int2 "`int2'*exp(`rep'*(x2-`diffic'))/(1+exp(x2-`diffic'))"
+         }
+           *di `i'
+           *di "`int1'"
+           *di "`int2'"
+           local int "`int1'*`int2'"
+           qui gausshermite2 `int', mu(`mu') sigma(`sigma') display
+           qui replace proba=r(int)  in `i' 
+           *di proba[`i']
+         }
+         }
+         
+   gen eff=proba 
+   keep item*  proba   eff 
+   *gen eff2=`n'*proba2 
+   *keep item*  proba  proba2 eff1 eff2 
+   
+   edit
+   local p=1/`n'     
+   qui gen eff2=floor(eff/`p')   
+   *list eff2 eff    
+   qui replace eff=eff-eff2*(`p') 
+   qui su eff2 
+   local aff=r(sum)
+   
+   local unaff=`n'-`aff'
+   di `aff'
+   di `unaff'
+   gen efftmp=eff2
+   qui gsort - eff
+   qui replace eff2=eff2+1 in 1/`unaff'
+  
+   qui drop if eff2==0
+   gsort  item*
+   *gen res=proba*50
+  * keep item*  proba   eff eff2 aff unaff
+  
+  * Matrice complete qui ne tient pas compte des effectifs dans l'analyse 
+  
+   qui expand eff2
+   *qui drop proba eff eff2
+   *keep item*  proba   eff eff2 
+   *}
+
+
+   forvalues j=1/`nbitems' {
+      rename item`j' T1reponse`j'
+   }
+
+ forvalues j=`=1+`nbitems''/`=2*`nbitems'' {
+      rename item`j' T2reponse`=`j'-`nbitems'' 
+   }
+rename eff2 Eff
+keep T1reponse* T2reponse*  Eff
+
+gen id=_n
+forvalues i=1/`nbitems'{
+	local list="`list' T@reponse`i'"
+}
+reshape long `list', i(id) j(temps)
+reshape long Treponse, i(id temps) j(item)
+forvalues i=1/`nbitems'{
+	gen item`i'=0
+	replace item`i'=-1 if item==`i'
+}
+gen temps1=temps==1
+gen temps2=temps==2
+*gen W1=0
+*gen W2=0
+*replace  W1=Eff if temps1==1
+*replace W2=Eff if temps2==1
+
+qui gen  offset=0
+forvalues i=1/`nbitems' {
+    qui replace offset=-`diff'[`i',1] if item==`i'
+}
+
+matrix C=cholesky(`sigma')
+
+*constraint define 1  `sigma'[1,1]-C[1,1]^2=0
+*constraint define 2  `sigma'[2,2]-C[2,1]^2-C[2,2]^2=0
+*constraint define 3  `sigma'[2,1]-C[1,1]*C[2,1]=0
+
+*constraint define 1 id_1:temps1=`=sqrt(`sigma'[1,1])'
+*constraint define 2 id_2:temps2=`=sqrt(`sigma'[2,2]-`sigma'[2,1]^2/`sigma'[1,1])'
+*constraint define 3 id1_2_1:_cons=`=`sigma'[2,1]/sqrt(`sigma'[1,1])'
+
+*constraint define 1 var(1): =`=`sigma'[1,1]'
+*constraint define 2  cov(2,1): =`=`sigma'[1,2]'    
+*constraint define 3 var(2): =`=`sigma'[2,2]'     
+
+
+
+constraint define 1 id1_1:temps1=`=C[1,1]'
+constraint define 2  id1_2:temps2=`=C[2,2]'
+constraint define 3  id1_2_1:_cons=`=C[2,1]'
+
+/*CODE JBH*/
+gen Treponse1=Treponse if temps1
+replace Treponse1=0 if Treponse1==.
+gen Treponse2=Treponse if temps2
+replace Treponse2=0 if Treponse2==.
+
+constraint define 1 Treponse1=`=C[1,1]'
+constraint define 2 Treponse2=`=C[2,2]'
+constraint define 3 _cons=`=C[2,1]'
+
+eq b1:Treponse1
+eq b2:Treponse2
+/*FIN CODE JBH*/
+gllamm Treponse temps1 temps2, offset(offset) i(id) link(logit) nocons fam(bin) nrf(2) constraints(1 2 3) eqs(b1 b2)  iterate(20) trace
+
+capture qui use `raschlongitudinalfile',clear
+
+end
diff --git a/Modules/ado/personal/r/raschpce.ado b/Modules/ado/personal/r/raschpce.ado
new file mode 100644
index 0000000..aba801f
--- /dev/null
+++ b/Modules/ado/personal/r/raschpce.ado
@@ -0,0 +1,227 @@
+program define raschpce,rclass
+syntax varlist [if] [in] [, rsm]
+preserve
+if "`if'"!=""|"`in'"!="" {
+    di "if:`if' in: `in'"
+    keep `if' `in'
+}
+tokenize `varlist'
+
+local nbitems:word count `varlist'
+
+local lines=1
+local summ=0
+local modamax=0
+forvalues i=1/`nbitems' {
+   qui su ``i''
+   local moda`i'=r(max)
+   local lines=`lines'*(`moda`i''+1)
+   local summ=`summ'+`moda`i''
+   if `modamax'<`moda`i'' {
+       local modamax `moda`i''
+   }
+}
+local col=1+`nbitems'
+*di "matrix table=J(`lines',`col',.)"
+
+
+*matrix table=J(`lines',`col',.)
+
+local line=1
+/*forvalues i=1/`nbitems' {
+   forvalues j=`=`i'+1'/`nbitems' {
+      forvalues mi=0/`moda`i'' {
+         forvalues mj=0/`moda`j'' {
+             matrix table[`line',`i']=`mi'
+             matrix table[`line',`j']=`mj'
+             qui count if ``i''==`mi'&``j''==`mj'
+             matrix table[`line',`=`nbitems'+1']=r(N)
+             local ++line
+         }
+      }
+   }
+}
+*/
+
+local line=1
+forvalues i=1/`nbitems' {
+   forvalues j=`=`i'+1'/`nbitems' {
+      forvalues mi=0/`moda`i'' {
+         forvalues mj=0/`moda`j'' {
+             qui count if ``i''==`mi'&``j''==`mj'
+             local table_`line'_`=`nbitems'+1'=r(N)
+             local ++line
+         }
+      }
+   }
+}
+qui drop _all
+set obs `=`line'-1'
+local line=1
+forvalues i=1/`nbitems' {
+   qui gen table`i'=.
+}
+qui gen table`=`nbitems'+1'=.
+*set trace on
+forvalues i=1/`nbitems' {
+   forvalues j=`=`i'+1'/`nbitems' {
+      forvalues mi=0/`moda`i'' {
+         forvalues mj=0/`moda`j'' {
+            qui replace table`i'=`mi' in `line'
+            qui replace table`j'=`mj' in `line'
+            qui replace table`=`nbitems'+1'=`table_`line'_`=`nbitems'+1'' in `line'
+            local ++line
+         }
+      }
+   }
+}
+*qui svmat table
+local ti
+local vi
+forvalues i=1/`nbitems' {
+    rename table`i' ``i''
+}
+rename table`=`nbitems'+1' freq
+local s="0"
+local max=0
+forvalues i=1/`nbitems' {
+   local max=`max'+`moda`i''
+   local bi`i'm0=0
+   local s="`s'+vi`i'mi`moda`i''"
+   forvalues j=`=`i'+1'/`nbitems'  {
+      qui gen ti`i'j`j'=``i''+``j''
+      qui replace ti`i'j`j'=0 if ti`i'j`j'==.
+      local ti "`ti' i.ti`i'j`j'"
+   }
+   forvalues mi=1/`moda`i'' {
+      qui gen vi`i'mi`mi'=``i''==`mi'
+      local vi "`vi' vi`i'mi`mi'"
+   }
+}
+local s="(`s')/`max'"
+
+count
+if "`rsm'"=="" {
+   *edit
+   qui xi:poisson freq `vi' `ti', nocons  iterate(30)
+   local ll=e(ll)
+  *set trace on
+
+   *lincom -(vi1mi1-(vi1mi3+vi2mi3+vi3mi3+vi4mi3+vi5mi3)/15)
+   *lincom -(vi1mi2-(vi1mi3+vi2mi3+vi3mi3+vi4mi3+vi5mi3)/15-vi1mi1)
+   *lincom -(vi1mi3-(vi1mi3+vi2mi3+vi3mi3+vi4mi3+vi5mi3)/15-vi1mi2)
+   *lincom -.5*(vi1mi1-(vi1mi2+vi2mi2+vi3mi2+vi4mi2+vi5mi2+vi6mi2+vi7mi2)/14)-.5*(vi1mi2-(vi1mi2+vi2mi2+vi3mi2+vi4mi2+vi5mi2+vi6mi2+vi7mi2)/14-vi1mi1)
+
+    qui matrix b=e(b)
+    local col=1
+    forvalues i=1/`nbitems' {
+       forvalues mi=1/`moda`i'' {
+          local bi`i'm`mi'=b[1,`col']
+          local ++col
+       }
+    }
+    *local s=`s'/`max'
+    *set trace on
+    forvalues i=1/`nbitems' {
+       local location`i'="0"
+       forvalues mi=1/`moda`i'' {
+          local delta`i'm`mi'=-(`bi`i'm`mi''-`mi'*`s'-`bi`i'm`=`mi'-1'')
+          if (`mi'==1) {
+             qui di "-(vi`i'mi`mi'-`s')"
+             local tdelta`i'_1 "-(vi`i'mi`mi'-`s')"
+             qui lincom -(vi`i'mi`mi'-`s')
+             local location`i' "`location`i''-(vi`i'mi`mi'-`s')"
+          }
+          else {
+    /*QUESTION : DOIT-ON MULTIPLIER `s' par `mi'*/
+             qui di " vi`i'mi`=`mi'-1'-vi`i'mi`mi'+`s'"
+             local tdelta`i'_`mi' " vi`i'mi`=`mi'-1'-vi`i'mi`mi'+`s'"
+             qui lincom vi`i'mi`=`mi'-1'-vi`i'mi`mi'+`s'
+             local location`i' "`location`i''+vi`i'mi`=`mi'-1'-vi`i'mi`mi'+`s'"
+          }
+          local delta`i'_`mi'=r(estimate)
+          local sedelta`i'_`mi'=r(se)
+       }
+       qui lincom  (`location`i'')/`moda`i''
+       local delta`i'=r(estimate)
+       local sedelta`i'=r(se)
+    }
+    forvalues i=1/`nbitems' {
+       forvalues mi=1/`moda`i'' {
+          di "delta`i'_`mi' : `delta`i'_`mi'' (`sedelta`i'_`mi'')"
+       }
+          di "delta`i' : `delta`i'' (`sedelta`i'')"
+    }
+}
+else {
+   qui gen vmi2=vi1mi2+vi2mi2+vi3mi2
+   drop vi1mi2 vi2mi2 vi3mi2
+   edit
+   qui xi:poisson freq vi1mi1 vi2mi1 vi3mi1 vmi2 `ti', nocons
+   local ll=e(ll)
+   *set trace on
+
+   *lincom -(vi1mi1-(vi1mi3+vi2mi3+vi3mi3+vi4mi3+vi5mi3)/15)
+   *lincom -(vi1mi2-(vi1mi3+vi2mi3+vi3mi3+vi4mi3+vi5mi3)/15-vi1mi1)
+   *lincom -(vi1mi3-(vi1mi3+vi2mi3+vi3mi3+vi4mi3+vi5mi3)/15-vi1mi2)
+   *lincom -.5*(vi1mi1-(vi1mi2+vi2mi2+vi3mi2+vi4mi2+vi5mi2+vi6mi2+vi7mi2)/14)-.5*(vi1mi2-(vi1mi2+vi2mi2+vi3mi2+vi4mi2+vi5mi2+vi6mi2+vi7mi2)/14-vi1mi1)
+
+    forvalues i=1/`nbitems' {
+       local location`i'="0"
+       forvalues mi=1/`moda`i'' {
+*          local delta`i'm`mi'=-(`bi`i'm`mi''-`mi'*`s'-`bi`i'm`=`mi'-1'')
+          if (`mi'==1) {
+             qui di "-(vi`i'mi1-vi2)"
+             local tdelta`i'_1 "-(vi`i'mi1-vi2)"
+             qui lincom -(vi`i'mi1-vi2)
+             local location`i' "`location`i''-(vi`i'mi1)"
+          }
+          else {
+    /*QUESTION : DOIT-ON MULTIPLIER `s' par `mi'*/
+             qui di " vi`i'mi`=`mi'-1'"
+             local tdelta`i'_`mi' " vi`i'mi`=`mi'-1'"
+             qui lincom vi`i'mi`=`mi'-1'
+             local location`i' "`location`i''+vi`i'mi`=`mi'-1'"
+          }
+          local delta`i'_`mi'=r(estimate)
+          local sedelta`i'_`mi'=r(se)
+       }
+       qui lincom  (`location`i'')/`moda`i''
+       local delta`i'=r(estimate)
+       local sedelta`i'=r(se)
+    }
+    forvalues i=1/`nbitems' {
+       forvalues mi=1/`moda`i'' {
+          di "delta`i'_`mi' : `delta`i'_`mi'' (`sedelta`i'_`mi'')"
+       }
+          di "delta`i' : `delta`i'' (`sedelta`i'')"
+    }
+}
+*set trace on
+matrix delta=J(`nbitems',`modamax',.)
+matrix sedelta=J(`nbitems',`modamax',.)
+forvalues i=1/`nbitems' {
+   forvalues mi=1/`moda`i'' {
+       matrix delta[`i',`mi']=`delta`i'_`mi''
+       matrix sedelta[`i',`mi']=`sedelta`i'_`mi''
+   }
+}
+*set trace on
+matrix b=delta
+matrix list delta
+*matrix delta=delta'
+*matrix sedelta=sedelta'
+return matrix b=delta
+return matrix sedelta=sedelta
+return scalar ll=`ll'
+restore
+
+
+
+*set trace on
+matrix list b
+*pcm item*, fixed(b)
+
+
+
+end
diff --git a/Modules/ado/personal/r/raschpower.ado b/Modules/ado/personal/r/raschpower.ado
new file mode 100644
index 0000000..1345c66
--- /dev/null
+++ b/Modules/ado/personal/r/raschpower.ado
@@ -0,0 +1,908 @@
+*! version 5.12 : Novembre 19, 2021
+*! Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot
+************************************************************************************************************
+* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
+*
+* Version 1 : January 25th, 2010 (Jean-Benoit Hardouin)
+* Version 1.1 : January 26th, 2010 (Jean-Benoit Hardouin)
+* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
+* version 1.3 : May 2nd, 2011 (Jean-Benoit Hardouin)
+* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
+* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
+* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
+* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
+* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
+* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
+* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
+* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option
+* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items
+* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups
+* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups
+* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug 
+* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display 
+* version 5.5 : April 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : graph option for longitudinal design 
+* version 5.6 : April 10th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : corrections of bugs 
+* version 5.7 : June 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : minor corrections 
+* version 5.8 : July 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : correction of a bug when the variances are different in the 2 groups (transversal) 
+* version 5.9 : September 26th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : fixed of a bug with the graph option (correlation could be greater than one) 
+* version 5.10 : July 18th, 2019 (Jean-Benoit Hardouin) : filesave and dirsave options
+* version 5.11 : July 24th, 2019 (Jean-Benoit Hardouin) : pcm->pcmold
+* version 5.12 : July 24th, 2019 (Myriam Blanchin) : correction of bug (essai.dta)
+
+* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
+* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
+* Bastien Perrot, Bastien.perrot@univ-nantes.fr
+* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
+* http://www.sphere-nantes.org
+*
+* News about this program : http://www.anaqol.org - anaqol@sphere-nantes.fr
+*
+* Copyright 2010-2014, 2019 Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+************************************************************************************************************/
+
+program define raschpower,rclass
+syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1) min(real 0.25) step(real 1) max(real 9) FILESave DIRSave(string) pro]
+version 11
+
+if "`pro'"!="" {
+    di "START"
+}
+
+if "`html'" != "" {
+	set scheme sj
+    local htmlregion  "graphregion(fcolor(white) ifcolor(white))"
+	di ""
+	di "
"
+}
+
+tempfile raschpowerfile
+capture qui save "`raschpowerfile'",replace
+tempname db d dlong matvar
+
+/*******************************************************************************
+DEFINITION DES PARAMETRES
+*******************************************************************************/
+
+if "`graph'" != "" & "`longitudinal'" != "" {
+	if `gvar' != -1 & `gcorr' != -1 {
+		di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
+		error 198
+	}
+	if `gvar' == -1 & `gcorr' == -1 {
+		di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
+		error 198
+	}
+}
+
+if "`difficulties'"=="" {
+   matrix `d'=[-1\-0.5\0\0.5\1]
+}
+else {
+   matrix `d'=`difficulties'
+}
+local nbitems=rowsof(`d')
+local nbmodat=colsof(`d')+1
+
+if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
+	local nbt=1
+	local nbtotitems=`nbitems'
+	local nbpatmax=2*`nbmodat'^`nbitems'
+	if "`var'"==""{
+		local var=1
+		local var0=1
+		local var1=1
+	}
+	else{
+		capture confirm number `var'
+		if !_rc {
+			local var0=`var'
+			local var1=`var'
+		}
+		else{
+		   local nbw:word count `var'
+		   local grp=1
+		   if `nbw'==2 {
+				local t1: word 1 of `var'
+                capture confirm number `t1'
+				if !_rc {
+					local t2: word 2 of `var'
+                    capture confirm number `t2'
+                    if !_rc {
+                       local var0=`t1'
+                       local var1=`t2'
+                       local grp=2
+                    }
+				}
+			}
+			if `nbw'!=2|`grp'==1 {
+				capture confirm matrix `var'
+			    if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
+				    matrix `matvar'=`var'
+					local var0=`matvar'[1,1]
+					local var1=`matvar'[1,1]
+			    }
+			    else{
+					di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
+					error 198
+					exit
+			    }
+		    }
+		}
+	}
+	matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
+    local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
+
+	local sumd=0
+	forvalues numit=1/`nbitems'{
+		local sumd=`sumd'+`d'[`numit',1]
+	}
+	local sumd=`sumd'/`nbitems'
+	if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
+		if "`html'" == "" {
+			di  "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
+		}
+	}
+
+}
+else{ /*CAS LONGITUDINAL*/
+	local nbt=2
+	local nbtotitems=2*`nbitems'
+	local nbpatmax=`nbmodat'^(`nbitems'*2)
+	local n1=0
+	local mean1=0
+	local mean2=`mean1'+`gamma'
+	if "`var'"==""{
+		matrix `matvar'=(1,0\0,1)
+	}
+	else{
+		matrix `matvar'=`var'
+		capture confirm matrix `matvar'
+		if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
+			di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
+			error 198
+			exit
+		}
+	}
+	matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
+	matrix `dlong'[1,1]=`d'
+	matrix `dlong'[`=`nbitems'+1',1]=`d'
+}
+
+/*
+if "`max'" == "" {
+	local max = 9 + `step'/2
+}
+else {
+	local max = `max' + `step'/2
+}*/
+
+forval v = `min'(`step')`max' {
+	local w = `v'
+}
+if `w' < `max' {
+	local max = `max' + `step'
+}
+if "`longitudinal'"!="" & `gvar'!=-1 {                
+	local max = min(`max',0.99999)    /* pour avoir des corrélations < 1 */
+}
+
+/*******************************************************************************
+DEFINITION DE LA METHODE
+*******************************************************************************/
+
+if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
+	local method POPULATION+GH
+}
+
+if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
+   di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
+   di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
+   di in gr "The -method- option is replaced by GH."
+   local method GH
+}
+else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
+	di in red "The number of patterns is too high for the chosen method"
+	exit
+}
+else if "`method'"=="" {
+    if `nbpatmax'<2000 {
+        local method GH
+    }
+    else  {
+        local method POPULATION+GH
+    }
+}
+
+if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
+	di in red "Invalid method name"
+	exit
+}
+
+/*******************************************************************************
+AFFICHAGE DES PARAMETRES
+*******************************************************************************/
+
+if "`longitudinal'"==""{
+	di in gr "Number of individuals in the first group: " in ye `n0'
+	di in gr "Number of individuals in the second group: " in ye `n1'
+	di in green "Group effect: " in ye `gamma'
+	di in  gr "Variance of the latent trait in the first group: " in ye `var0'
+	di in  gr "Variance of the latent trait in the second group: " in ye `var1'
+}
+else{
+	di in gr "Number of individuals at each time:  " in ye `n0'
+	di in green "Time effect: " in ye `gamma'
+	di in  gr "Variance matrix of the latent trait: " 
+	matrix list `matvar',noheader
+	di
+}
+di in gr "Number of items: " in ye `nbitems'
+di in green "Difficulties parameters of the items: "
+tempname dd
+matrix `dd'=`d''
+local items
+forvalues i=1/`nbitems' {
+   local items "`items' item`i'"
+}
+local modalities
+forvalues i=1/`=`nbmodat'-1' {
+   local modalities "`modalities' delta_`i'"
+}
+
+matrix colnames `dd'=`items'
+matrix rownames `dd'=`modalities'
+
+
+di
+tempname ddt
+matrix `ddt' = `dd''
+matrix colnames `ddt'=`modalities'
+matrix rownames `ddt'=`items'
+if "`html'" != "" {
+	matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficultés dans l'autre sens */
+}
+else {
+	matrix list `dd',noblank nohalf noheader
+}
+di
+
+if "`detail'"!="" & "`html'" == ""{
+	di in gr "Method:  " in ye "`method'"
+	di in gr "Number of studied response's patterns: " in ye `nbpatmax'
+}
+matrix `dd'=`d'
+local gamma=`gamma'
+
+local tmp=1
+qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
+forvalues j=1/`nbitems' {
+	forvalues m=1/`=`nbmodat'-1' {
+		qui matrix `db'[`tmp',1]=`d'[`j',`m']
+		local ++tmp
+	}
+}
+
+
+/*******************************************************************************
+CREATION DU DATASET ATTENDU 
+*******************************************************************************/
+
+if "`data'"=="" {
+	clear
+	if "`method'"!="POPULATION+GH"{
+		local temp=`nbmodat'^(`nbtotitems')
+		qui range x 0 `=`temp'-1' `temp'
+		qui g t=x
+		loc i=`nbtotitems'
+		qui count if t>0
+		loc z=r(N)
+		qui while `z'>0 {
+			qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
+			qui replace t=mod(t,`nbmodat'^`=`i'-1')
+			qui count if t>0
+			loc z=r(N)
+			loc i=`i'-1
+		}
+		drop t
+		if "`longitudinal'"==""{
+			qui expand 2
+			qui gen group=0 in 1/`temp'
+			qui replace group=1 in `=`temp'+1'/`=2*`temp''
+		}	
+	}
+	else { /*METHODE POPULATION (SIMULATION)*/
+		if "`longitudinal'"==""{
+			*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'*`gamma'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
+			qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
+			qui gen group=1
+			tempfile save1
+			qui save `save1',replace
+			qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
+			qui gen group=0
+			qui append using `save1'
+			*qui save d:\tmp,replace
+            bysort group:su lt
+			qui drop lt1
+			qui contract item* group, freq(freq)
+			qui count
+			local patobs=r(N)
+			if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
+				qui gen keep=0
+				qui gsort +group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+				qui gsort -group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n1''
+			}
+			else{
+				qui gen keep=1
+			}
+		}
+		else{
+			qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
+			forvalues j=1/`nbitems'{
+				rename itemA`j' item`j'
+				rename itemB`j' item`=`nbitems'+`j''
+			}
+			qui drop lt1 lt2
+			qui contract item*, freq(freq)
+			local patobs=r(N)
+			if `patobs'>=`=`n0'*`nbpatterns''{
+				qui gen keep=0
+				qui gsort -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+			}
+			else{
+			  qui gen keep=1
+			}
+		}
+		qui keep if keep==1
+		qui count
+		local retain=r(N)
+		di "Number of kept patterns:`retain'"
+		local method GH
+	}
+	if "`longitudinal'"==""{
+		qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
+		qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
+		qui gen var1=`var0' if group==0
+		qui replace var1=`var1' if group==1
+	}
+	else{
+		qui gen mean1=`mean1'
+		qui gen mean2=`mean2'
+	}
+	/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
+	if "`method'"=="GH" {
+		local temp=`nbmodat'^(`nbtotitems')
+		local diff0=0
+		qui gen proba=.
+		local dixj=10
+		qui count
+		local tmp=r(N)
+
+		forvalues i=1/`tmp' {
+			local dix=floor(`tmp'/10)
+			if mod(`i',`dix')==0 & "`html'"=="" {
+			    qui su proba
+				local tmpprob=r(sum)
+				if "`dixj'"!="10" {
+					di ".." _c
+				}
+				*di "`dixj'% (`tmpprob')" _c
+				di "`dixj'%" _c
+				local dixj=`dixj'+10
+			}
+			forvalues t=1/`nbt'{
+				local int`t'=1			 
+				forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+					qui su item`j' in `i'
+					local rep=r(mean)
+					local diff0=0
+					local diff1=`dlong'[`j',1]
+					local sum "1+exp(x`t'-`diff1')"
+					forvalues m=2/`=`nbmodat'-1' {
+					   local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+					   local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+					}
+					local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+				}
+			}	
+			if "`longitudinal'"==""{
+				qui su mean1 in `i'
+				local mean=r(mean)
+				qui su var1 in `i'
+				local vart=r(mean)
+				*di "gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
+				*prout
+				qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+				qui replace proba=r(int) in `i'
+			}
+			else{
+				local int "`int1'*`int2'"
+				matrix mean=(`mean1',`mean2')
+				qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
+				qui replace proba=r(int) in `i'
+			}
+		}
+		di
+	}
+	else { /*if "`method'"!="GH"*/
+		qui gen proba=1
+		forvalues t=1/`nbt'{
+			forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+				local diff0=0
+				local diff1=`dlong'[`i',1]
+				qui gen eps0=1
+				qui gen eps1=exp(mean`t'-`diff1')
+				qui gen d=eps0+eps1
+				forvalues m=2/`=`nbmodat'-1' {
+					local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
+					qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
+					qui replace d=d+eps`m'
+				}
+				local listeps
+				forvalues m=0/`=`nbmodat'-1' {
+					qui replace proba=proba*eps`m'/d if item`i'==`m'
+					local listeps `listeps' eps`m'
+				}
+				qui drop `listeps' d
+			}
+		}
+		if "`method'"=="MEAN+GH" {
+			set tracedepth 1
+			if "`longitudinal'"==""{
+				qui gen keep=0
+				qui gsort -group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui gsort +group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+				qui su proba if group==0
+				local sumproba0=r(sum)*100
+				qui su proba if group==1
+				local sumproba1=r(sum)*100
+			}
+			else{
+				qui gen keep=0
+				qui gsort -proba
+				local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+			}
+
+			qui drop keep proba
+			local diff0=0
+			qui gen proba=.
+			qui count
+			local nnew=r(N)
+			di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
+			if "`longitudinal'"==""{
+				di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
+			}
+			local dixj=10
+			forvalues i=1/`nnew' {
+				local dix=floor(`nnew'/10)
+				if mod(`i',`dix')==0 & "`html'"=="" {
+				    qui su proba
+					local sum=r(sum)
+					if "`dixj'"!="10" {
+						di ".." _c
+					}
+					di "`dixj'% (`sum')" _c
+					local dixj=`dixj'+10
+				}
+				forvalues t=1/`nbt'{
+					local int`t'=1
+					forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+						qui su item`j' in `i'
+						local rep=r(mean)
+						local diff0=0
+						local diff1=`dlong'[`j',1]
+						local sum "1+exp(x`t'-`diff1')"
+						forvalues m=2/`=`nbmodat'-1' {
+							local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+							local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+						}
+						local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+					}
+				}
+				if "`longitudinal'"==""{
+					qui su mean1 in `i'
+					local mean=r(mean)
+					qui su var1 in `i'
+					local vart=r(mean)
+					*di "qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
+					qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+					qui replace proba=r(int) in `i'
+				}
+				else{
+					local int "`int1'*`int2'"
+					matrix mean=(`mean1',`mean2')
+					qui gausshermite `int',mu(mean) var(`matvar') display
+					qui replace proba=r(int) in `i'
+				}
+			}
+		}
+	}
+	qui gen eff=proba
+	qui gen eff2=.  
+   
+	if "`longitudinal'"==""{
+		qui keep item* eff* group proba
+		local p1=1/`n1'
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p1') if group==1
+		qui replace eff2=floor(eff/`p0') if group==0
+		qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
+		qui su eff2 if group==1
+		local aff1=r(sum)
+		qui su eff2 if group==0
+		local aff0=r(sum)
+
+		local unaff1=`n1'-`aff1'
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort + group - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+		qui gsort - group - eff
+		qui replace eff2=eff2+1 in 1/`unaff1'
+
+		qui drop if eff2==0
+		qui gsort group item*
+		qui expand eff2
+	}
+	else{
+		qui keep item* eff* proba
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p0')
+		qui replace eff=eff-eff2*`p0'
+		qui su eff2
+		local aff0=r(sum)
+
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+
+		qui drop if eff2==0
+		qui gsort item*
+		qui expand eff2
+	}
+   qui drop proba eff eff2
+}
+/*
+if "`html'" == "" {
+	qui save "d:\essai.dta", replace
+}*/
+qui alpha item*
+local alpha=r(alpha)
+
+if "`longitudinal'"==""{ /*TRANSVERSAL*/
+	qui gen groupc=-`n1'/(`n0'+`n1') if group==0
+	qui replace groupc=`n0'/(`n0'+`n1') if group==1
+	if `nbmodat'==2 {   /*DICHOTOMOUS CASE*/
+        if "`freeitems'"=="" {
+		      local offset "offset(offset)"
+			  local items
+        }
+        else {
+		      local offset
+		      local items "item1-item`nbitems'"
+        }
+		qui gen i=_n
+
+		tempname diff
+		matrix `diff'=`dd''
+
+		qui reshape long item, i(i)
+		qui rename item rep
+		qui rename _j item
+
+		qui gen  offset=0
+		forvalues i=1/`nbitems' {
+			qui replace offset=-`diff'[1,`i'] if item==`i'
+			qui gen item`i'=item==`i'
+			qui replace item`i'=-item`i'
+		}
+        if `var0'==`var1' { /*EQUAL VARIANCES*/
+	       *constraint 1 _cons=`=ln(`var')'
+		   *qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
+	       if  "`freevar'"=="" {
+		      constraint 1 _cons=`=sqrt(`var0')'
+		      local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
+		}
+		else {/*UNEQUAL VARIANCES*/
+		   tempvar G0 G1
+		   qui gen `G0'=group==0
+		   qui gen `G1'=group==1
+		   qui eq B0: `G0'
+		   qui eq B1: `G1'
+	       constraint 1 _cons=0
+	       if  "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
+			   constraint 2 `G0'=`=sqrt(`var0')'
+			   constraint 3 `G1'=`=sqrt(`var1')'
+		       constraint 1 _cons=`=sqrt(`var0')'
+		       local constvar "constraint(1 2 3)"
+		   }
+		   else { /*FREE UNEQUAL VARIANCES*/
+		       local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
+		}
+		tempname b V/*LONGITUDINAL*/
+		local row = 1
+	}
+	else { /*POLYTOMOUS CASE*/
+		matrix `db'=`db''
+		if "`freeitems'"=="" {
+		   local fi "fixed(`db') fixedmu"
+		   local row=1
+		}
+		else {
+		   local fi
+		   local row=(`nbmodat'-1)*`nbitems'+1
+		}
+	    if `var0'==`var1' {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvar(`var0')"
+		   }
+		   else {
+		       local fv 
+			   *noi pcm item*, `fi' covariates(groupc) 
+
+		   }
+		}
+		else {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvargroupc(`var')"
+		   }
+		   else {
+		       local fv "vargroupc"
+		   }
+        }
+	      *di "jk pcm item*, `fi' covariates(groupc) `fv'"
+		   	/********************************ESSAI 23 mai 2014*/
+			qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`n1')
+			qui gen group=1
+			tempfile save1
+			qui save `save1',replace
+			qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`n0')
+			qui gen group=0
+			qui append using `save1'
+			qui gen groupc=group-0.5
+			*di "ON A SIMULE"
+			**********************************FIN ESSAI 23 mai 2014*/
+
+		 qui pcmold item*, `fi' covariates(groupc) `fv'
+	}
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,`row']
+	local se=`V'[`row',`row']^.5
+}
+else{ /*LONGITUDINAL*/ 
+	qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,1]
+	local se=`V'[1,1]^.5
+	local n1=`n0'
+}
+local poweruni=1-normal(1.96-`gamma'/`se')
+
+if "`html'" == "" {
+	di
+	di
+}
+if "`detail'"!=""{
+	di in gr "{hline 91}"
+	di _col(60)  "Estimation with the "
+	di _col(50)  "Cramer-Rao bound" _col(75) "classical formula"
+	di in gr "{hline 91}"
+}
+
+if "`longitudinal'"==""{
+	local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
+	local nbw:word count `var'
+	if `nbw' == 2 { /* variance commune */
+		local varc = ((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
+	}
+	else {
+		local varc = `var'
+	}
+	local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`varc'))-1.96)
+	local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`varc'))^2)*(1.96+invnorm(`poweruni'))^2
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the group effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+else{
+	local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
+	local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the time effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+
+if `expectedpower'!=-1 {
+   qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
+   local expn_1=r(N_1)
+   local expn_2=r(N_2)
+   local expn2=`expn_1'*`ratio'
+   di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _c
+   if "`detail'"!="" {
+      di _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
+   }
+}
+
+
+return scalar EstGamma=`gammaest'
+return scalar CRbound=`=`se'^2'
+return scalar CRPower=`poweruni'
+return scalar ClPower=`clpower'
+return scalar ClSS=`clnsn'
+return scalar Ratio=`ratio'
+return scalar CronbachAlpha=`alpha'
+
+
+if "`graph'" != "" {
+	local x = "`min'(`step')`max'"
+	matrix res=J(15,5,.)
+	matrix colnames res= n0 n1 gamma variance power
+	local l=1
+
+	if "`longitudinal'"==""{
+		forval var = `x' {
+			qui raschpower, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
+			qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
+			local ++l
+		}
+		clear
+		qui svmat res,names(col)
+		
+		if "`html'" != "" {
+			qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
+			qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving'
+			qui graph use `c(tmpdir)'/`html'_planif_graph.gph
+			qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
+			di "
" + di " _char(34) " + } + else { + if "`filesave'"!="" { + qui local saving "saving(`dirsave'//planif,replace) nodraw" + } + else { + qui local saving + } + twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving' + } + } + + else { + if `gcorr' != -1 { + local l=1 + forval var = `x' { + local cov = `gcorr'*`var' + local matv "`var',`cov'" " \ `cov',`var'" + qui raschpower, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + if "`filesave'"!="" { + qui local saving "saving(`dirsave'//planif,replace) nodraw" + } + else { + qui local saving + } + twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving' + } + } + + if `gvar' != -1 { + matrix res=J(9,5,.) + matrix colnames res= n0 n1 gamma corr power + local l=1 + forvalues corr = `x' { + local cov = `corr'*`gvar' + local matv "`gvar',`cov'" " \ `cov',`gvar'" + qui raschpower, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation, margin(top)) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + if "`filesave'"!="" { + qui local saving "saving(`dirsave'//planif,replace) nodraw" + } + else { + qui local saving + } + twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) + } + } + } + +//di in gr "Method: " in ye "`method'" + + if "`html'" != "" { + di "
" + } +} + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschpower.hlp b/Modules/ado/personal/r/raschpower.hlp new file mode 100644 index 0000000..b15f494 --- /dev/null +++ b/Modules/ado/personal/r/raschpower.hlp @@ -0,0 +1,78 @@ +{smcl} +{* 6february2012}{...} +{hline} +help for {hi:raschpower}{right:Jean-Benoit Hardouin, Myriam Blanchin} +{hline} + +{title:Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals} + +{p 8 14 2}{cmd:raschpower} [{cmd:,} {cmdab:n0}({it:#}) {cmdab:n1}({it:#}) +{cmdab:gamma}({it:#}) {cmdab:var}({it:# [#]}) {cmdab:d:ifficulties}({it:matrix}) {cmdab:m:ethod}({it:method}) {cmdab:det:ail} {cmdab:exp:ectedpower}({it:#})] + + +{title:Description} + +{p 4 8 2}{cmd:raschpower} allows estimating the power of the Wald test comparing the means of two groups of patients in the context of the Rasch model or the partial-credit model. The estimation is based + on the estimation of the variance of the difference of the means based on the Cramer-Rao bound. + +{title:Options} + +{p 4 8 2}{cmd:n0} and {cmd:n1} indicates the numbers of individuals in the two groups [100 by default]. + +{p 4 8 2}{cmd:gamma} indicates the group effect (difference between the two means) [0.5 by default]. + +{p 4 8 2}{cmd:var} is the expected values of the variances of the latent trait (1 by default): if this option contains only one value, variances are considered as equal between the two groups; if this option contains two values, variances are considered as unequal between the two groups. + +{p 4 8 2}{cmdab:d:ifficulties} is a matrix containing the item parameters [one row per item, one column per positive modality - (-1.151, -0.987\-0.615, -0.325\-0.184, -0.043\0.246, 0.554\0.782, 1.724) by default]. + +{p 4 8 2}{cmd:method}({it:method}) indicates the method for constructing data. ({it:method}) may be GH, MEAN, MEAN+GH or POPULATION+GH [default is method(GH) if number of patterns<500, method(MEAN+GH) if 500<=number of patterns<10000, +method(MEAN) if 10000<=number of patterns<1000000, method(POPULATION+GH) otherwise]. + +{p 8 14 2} {bf:GH}: The probability of all possible response patterns is estimated by Gauss-Hermite quadratures. + +{p 8 14 2} {bf:MEAN}: The mean of the latent trait for each group is used instead of Gauss-Hermite quadratures. + +{p 8 14 2} {bf:MEAN+GH}: In a first step, the MEAN method is used to determine the most probable patterns. In a second step, the probability of response patterns is estimated by Gauss-Hermite quadratures on the most probable patterns. + +{p 8 14 2} {bf:POPULATION+GH}: The most frequent response patterns are selected from a simulated population of 1,000,000 of individuals. The probability of the selected response patterns is estimated by Gauss-Hermite quadratures. + +{p 4 8 2}{cmd:detail} allows a comparison with the classical formula (for manifest variable). + +{p 4 8 2}{cmd:expectedpower} allows searching for a sample size in order to reach a fixed level of power (the obtained sample sizes take into account the ratio between $n0$ and $n1$). + + +{title:Example} + + {p 4 8 2}{cmd:. raschpower} + + {p 4 8 2}{cmd:. raschpower, n0(200) n1(200) gamma(0.4) var(1.3)} + + {p 4 8 2}{cmd:. matrix diff=(-1.47\-0.97\-.23\-0.12\0.02\0.1)}{p_end} + {p 4 8 2}{cmd:. raschpower, n0(127) n1(134) gamma(0.23) d(diff) var(2.58)}{p_end} + + {p 4 8 2}{cmd:. matrix diff=(-0.328,-0.811,0.329\ 0.556,0.818,1.409\ 1.394,1.049,1.288\ 0.560,0.363,0.950)}{p_end} + {p 4 8 2}{cmd:. raschpower, d(diff) n0(167) n1(205) gamma(0.178) var(0.77) exp(0.8)}{p_end} + + +{title:References} + + {p 4 8 2}Hardouin J.B., Amri S., Feddag M., Sébille V. (2012) Towards Power And Sample Size Calculations For The Comparison Of Two Groups Of Patients With Item Response Theory Models. Statistics in Medicine, 31(11): 1277-1290.{p_end} + {p 4 8 2}Blanchin M., Hardouin J.B., Guillemin F., Falissard B., Sébille V. (2013) Power and sample size determination for the group comparison of patient-reported outcomes with Rasch family models. PLoS ONE, 8(2): e57279.{p_end} + {p 4 8 2}Feddag M.L., Blanchin M., Hardouin J.B., Sébille V. (2014) Power analysis on the time effect for the longitudinal Rasch model. Journal of Applied Measurement: (under press).{p_end} + {p 4 8 2}Guilleux A., Blanchin M., Hardouin J.B., Sébille V. (2014) Power and sample size determination in the Rasch model: Evaluation of the robustness of a numerical method to non-normality of the latent trait. Plos One, 9(1): e0083652.{p_end} + + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end} +{p 4 8 2}Myriam Blanchin, PhD, research assistant{p_end} +{p 4 8 2}Bastien Perrot, biostatistician{p_end} +{p 4 8 2}EA4275 "Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences"{p_end} +{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end} +{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end} +{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end} +{p 4 8 2}Emails: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 13 8 2}{browse "mailto:myriam.blanchin@univ-nantes.fr":myriam.blanchin@univ-nantes.fr}{p_end} +{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol} +and {browse "http://www.freeirt.org":FreeIRT} diff --git a/Modules/ado/personal/r/raschpower33.ado b/Modules/ado/personal/r/raschpower33.ado new file mode 100644 index 0000000..f83a15d --- /dev/null +++ b/Modules/ado/personal/r/raschpower33.ado @@ -0,0 +1,371 @@ +*! version 3.3 : October 2nd, 2012 +*! Jean-Benoit Hardouin, Myriam Blanchin +************************************************************************************************************ +* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals +* +* Version 1 : January 25, 2010 (Jean-Benoit Hardouin) +* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin) +* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin) +* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin) +* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections +* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results +* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method +* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* version 3.3 : October 2nd, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* +* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* Myriam Blanchin, myriam.blanchin@univ-nantes.fr +* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health" +* Faculty of Pharmaceutical Sciences - University of Nantes - France +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2010-2012 Jean-Benoit Hardouin, Myriam Blanchin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschpower,rclass +syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(real 1) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1)] +version 11 + +tempfile raschpowerfile +capture qui save "`raschpowerfile'",replace +tempname db d +if "`difficulties'"=="" { + matrix `d'=[-1.151, -0.987\-0.615, -0.325\-0.184, -0.043\0.246, 0.554\0.782, 1.724] +} +else { + matrix `d'=`difficulties' +} +local nbitems=rowsof(`d') +local nbmodat=colsof(`d')+1 +if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`=`nbmodat'^`nbitems'*2' { + di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses" + di in gr "is lesser than the number of pattern retained by the MEAN+GH method." + di in gr "The -method- option is replaced by GH." + local method GH +} +else if "`method'"=="" { + if `nbmodat'^`nbitems'*2<1000 { + local method GH + } + else if `nbmodat'^`nbitems'<10000 { + local method MEAN+GH + } + else if `nbmodat'^`nbitems'<1000000 { + local method MEAN + } + else { + local method POPULATION+GH + } +} + + + +di in gr "Method: " in ye "`method'" +di in gr "Number of individuals in the first group: " in ye `n0' +di in gr "Number of individuals in the second group: " in ye `n1' +di in green "Group effect: " in ye `gamma' +di in gr "Variance of the latent trait: " in ye `var' +di in gr "Number of items: " in ye `nbitems' +di in green "Difficulties parameters of the items: " +tempname dd +matrix `dd'=`d'' +local items +forvalues i=1/`nbitems' { + local items "`items' item`i'" +} +local modalities +forvalues i=1/`=`nbmodat'-1' { + local modalities "`modalities' delta_`i'" +} + +matrix colnames `dd'=`items' +matrix rownames `dd'=`modalities' +matrix list `dd',noblank nohalf noheader +di in gr "Number of studied response's patterns: " in ye `=`nbmodat'^`nbitems'*2' + +matrix `dd'=`d' +local gamma=`gamma' + +local tmp=1 +qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.) +forvalues j=1/`nbitems' { + forvalues m=1/`=`nbmodat'-1' { + qui matrix `db'[`tmp',1]=`d'[`j',`m'] + local ++tmp + } +} + +if "`data'"=="" { + clear + if "`method'"!="POPULATION+GH"{ + local temp=`nbmodat'^(`nbitems') + qui range x 0 `=`temp'-1' `temp' + qui g t=x + loc i=`nbitems' + qui count if t>0 + loc z=r(N) + qui while `z'>0 { + qui gen item`=`nbitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1') + qui replace t=mod(t,`nbmodat'^`=`i'-1') + qui count if t>0 + loc z=r(N) + loc i=`i'-1 + } + drop t + qui expand 2 + qui gen group=0 in 1/`temp' + qui replace group=1 in `=`temp'+1'/`=2*`temp'' + } + else { + qui simirt, clear pcm(`difficulties') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000) + qui drop lt1 + qui contract item* group, freq(freq) + qui gen keep=0 + qui gsort +group -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n0'' + qui gsort -group -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n1'' + qui keep if keep==1 + qui count + local tmp=r(N) + di "Number of kept patterns:`tmp'" + local method GH + } + qui gen mean=-`n1'*`gamma'/(`n0'+`n1') if group==0 + qui replace mean=`n0'*`gamma'/(`n0'+`n1') if group==1 + + if "`method'"=="GH" { + local temp=`nbmodat'^(`nbitems') + local diff0=0 + qui gen proba=. + local dixj=10 + qui count + local tmp=r(N) + forvalues i=1/`tmp' { + local dix=floor(`tmp'/10) + if mod(`i',`dix')==0 { + if "`dixj'"!="10" { + di ".." _c + } + di "`dixj'%" _c + local dixj=`dixj'+10 + } + local int=1 + forvalues j=1/`nbitems' { + qui su item`j' in `i' + local rep=r(mean) + local diff0=0 + local diff1=`d'[`j',1] + local sum "1+exp(x-`diff1')" + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`d'[`j',`m'] + local sum "`sum'+exp(`m'*x-`diff`m'')" + } + local int "(`int'*exp(`rep'*x-`diff`rep''))/(`sum')" + } + qui su mean in `i' + local mean=r(mean) + qui gausshermite `int',mu(`mean') sigma(`=sqrt(`var')') display + qui replace proba=r(int) in `i' + } + di + } + else { + qui gen proba=1 + forvalues i=1/`nbitems' { + local diff0=0 + local diff1=`d'[`i',1] + qui gen eps0=1 + qui gen eps1=exp(mean-`diff1') + qui gen d=eps0+eps1 + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`d'[`i',`m'] + qui gen eps`m'=exp(`m'*mean-`diff`m'') + qui replace d=d+eps`m' + } + local listeps + forvalues m=0/`=`nbmodat'-1' { + qui replace proba=proba*eps`m'/d if item`i'==`m' + local listeps `listeps' eps`m' + } + qui drop `listeps' d + } + if "`method'"=="MEAN+GH" { + set tracedepth 1 + qui gen keep=0 + qui gsort -group -proba + local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui gsort +group -proba + local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui keep if keep==1 + qui su proba if group==0 + local sumproba0=r(sum)*100 + qui su proba if group==1 + local sumproba1=r(sum)*100 + + + qui drop keep proba + local diff0=0 + qui gen proba=. + qui count + local nnew=r(N) + di in gr "Number of studied response's patterns for the GH step: " in ye `nnew' + di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)" + local dixj=10 + forvalues i=1/`nnew' { + local dix=floor(`nnew'/10) + if mod(`i',`dix')==0 { + if "`dixj'"!="10" { + di ".." _c + } + di "`dixj'%" _c + local dixj=`dixj'+10 + } + local int=1 + forvalues j=1/`nbitems' { + qui su item`j' in `i' + local rep=r(mean) + local diff0=0 + local diff1=`d'[`j',1] + local sum "1+exp(x-`diff1')" + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`d'[`j',`m'] + local sum "`sum'+exp(`m'*x-`diff`m'')" + } + local int "(`int'*exp(`rep'*x-`diff`rep''))/(`sum')" + } + qui su mean in `i' + local mean=r(mean) + qui gausshermite `int',mu(`mean') sigma(`=sqrt(`var')') display + qui replace proba=r(int) in `i' + } + } + } + qui gen eff=. + forvalues i=0/1 { + qui replace eff=proba*`n`i'' if group==`i' + } + qui replace eff=proba + qui keep item* eff group proba + + local p1=1/`n1' + local p0=1/`n0' + qui gen eff2=. + qui replace eff2=floor(eff/`p1') if group==1 + qui replace eff2=floor(eff/`p0') if group==0 + qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group)) + qui su eff2 if group==1 + local aff1=r(sum) + qui su eff2 if group==0 + local aff0=r(sum) + + local unaff1=`n1'-`aff1' + local unaff0=`n0'-`aff0' + qui gen efftmp=eff2 + qui gsort + group - eff + qui replace eff2=eff2+1 in 1/`unaff0' + qui gsort - group - eff + qui replace eff2=eff2+1 in 1/`unaff1' + + qui drop if eff2==0 + gsort group item* + qui expand eff2 + qui drop proba eff eff2 +} + +qui alpha item* +local alpha=r(alpha) +qui gen groupc=group-.5 +if `nbmodat'==2 { + qui gen i=_n + + tempname diff + matrix `diff'=`dd'' + + qui reshape long item, i(i) + qui rename item rep + qui rename _j item + + qui gen offset=0 + forvalues i=1/`nbitems' { + qui replace offset=-`diff'[1,`i'] if item==`i' + } + + constraint 1 _cons=`=ln(`var')' + qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1) + tempname b V +} +else { + matrix `db'=`db'' + *di "qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvar(`var')" + qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvar(`var') + +} + + tempname b V + matrix `b'=e(b) + matrix `V'=e(V) + local gammaest=`b'[1,1] + local se=`V'[1,1]^.5 + + + di + di + di in gr "{hline 91}" + di _col(60) "Estimation with the " + di _col(50) "Cramer-Rao bound" _col(75) "classical formula" + di in gr "{hline 91}" + if "`gammafixed'"=="" { + di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest' + } + di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se' + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se') + local poweruni=1-normal(1.96-`gamma'/`se') + local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96) + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower' + local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2 + di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0'' + local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0')) + di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio' + if `expectedpower'!=-1 { + qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'') + local expn_1=r(N_1) + local expn_2=r(N_2) + local expn2=`expn_1'*`ratio' + di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2' + } + di in gr "{hline 91}" + return scalar EstGamma=`gammaest' + return scalar CRbound=`=`se'^2' + return scalar CRPower=`poweruni' + return scalar ClPower=`clpower' + return scalar ClSS=`clnsn' + return scalar Ratio=`ratio' + return scalar CronbachAlpha=`alpha' + + + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschpower4.ado b/Modules/ado/personal/r/raschpower4.ado new file mode 100644 index 0000000..cdaa892 --- /dev/null +++ b/Modules/ado/personal/r/raschpower4.ado @@ -0,0 +1,676 @@ +*! version 4 : January 30th, 2013 +*! Jean-Benoit Hardouin, Myriam Blanchin +************************************************************************************************************ +* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals +* +* Version 1 : January 25, 2010 (Jean-Benoit Hardouin) +* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin) +* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin) +* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin) +* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections +* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results +* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method +* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* version 4 : January 30th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design +* +* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* Myriam Blanchin, myriam.blanchin@univ-nantes.fr +* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health" +* Faculty of Pharmaceutical Sciences - University of Nantes - France +* http://www.sphere-nantes.org +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2010-2013 Jean-Benoit Hardouin, Myriam Blanchin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschpower,rclass +syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar HTML(string)] +version 11 + +if "`html'" != "" { + di "" +} +tempfile raschpowerfile +capture qui save "`raschpowerfile'",replace +tempname db d dlong matvar + +if "`difficulties'"=="" { + matrix `d'=[-1\-0.5\0\0.5\1] +} +else { + matrix `d'=`difficulties' +} +local nbitems=rowsof(`d') +local nbmodat=colsof(`d')+1 +if "`longitudinal'"!="" & `nbmodat'>2{ + di in red "{p}The {hi:longitudinal} option is not available with polytomous items{p_end}" + error 198 + exit +} +if "`longitudinal'"==""{ + local nbt=1 + local nbtotitems=`nbitems' + local nbpatmax=2*`nbmodat'^`nbitems' + if "`var'"==""{ + local var=1 + } + else{ + capture confirm number `var' + if !_rc { + local var=`var' + } + else{ + matrix `matvar'=`var' + capture confirm matrix `matvar' + if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{ + local var=`matvar'[1,1] + } + else{ + di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}" + error 198 + exit + } + } + } + matrix `dlong'=`d' + + local sumd=0 + forvalues numit=1/`nbitems'{ + local sumd=`sumd'+`d'[`numit',1] + } + local sumd=`sumd'/`nbitems' + + if `=abs(`sumd')'>=`=2*sqrt(`var')'{ + if "`html'" == ""{ + di "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}" + } + else { + di "

WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait.


" + } + } + +} +else{ + local nbt=2 + local nbtotitems=2*`nbitems' + local nbpatmax=`nbmodat'^(`nbitems'*2) + local n1=0 + local mean1=0 + local mean2=`mean1'+`gamma' + if "`var'"==""{ + matrix matvar=(1,0\0,1) + } + else{ + matrix `matvar'=`var' + capture confirm matrix `matvar' + if !_rc & colsof(`matvar')==2 & rowsof(`matvar')==2 & issymmetric(`matvar'){ + matrix matvar=`matvar' + } + else{ + di in red "{p}The {hi:var} option should contain a symmetric 2x2 matrix for longitudinal studies{p_end}" + error 198 + exit + } + } + matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.) + matrix `dlong'[1,1]=`d' + matrix `dlong'[`=`nbitems'+1',1]=`d' +} + +if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{ + local method POPULATION+GH +} + +if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' { + di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses" + di in gr "is lesser than the number of pattern retained by the MEAN+GH method." + di in gr "The -method- option is replaced by GH." + local method GH +} +else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{ + di in red "The number of patterns is too high for the chosen method" + exit +} +else if "`method'"=="" { + if `nbpatmax'<2000 { + local method GH + } + else { + local method POPULATION+GH + } +} + +if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{ + di in red "Invalid method name" + exit +} +if "`html'" == "" { + di in gr "Method: " in ye "`method'" + + if "`longitudinal'"==""{ + di in gr "Number of individuals in the first group: " in ye `n0' + di in gr "Number of individuals in the second group: " in ye `n1' + di in green "Group effect: " in ye `gamma' + di in gr "Variance of the latent trait: " in ye `var' + } + else{ + di in gr "Number of individuals at each time: " in ye `n0' + di in green "Time effect: " in ye `gamma' + di in gr "Variance matrix of the latent trait: " + matrix list matvar + } + di in gr "Number of items: " in ye `nbitems' + di in green "Difficulties parameters of the items: " +} +else { + di "Method: " in ye "`method'" "
" + + if "`longitudinal'"==""{ + di "Number of individuals in the first group: " in ye `n0' "
" + di "Number of individuals in the second group: " in ye `n1' "
" + di "Group effect: " in ye `gamma' "
" + di "Variance of the latent trait: " in ye `var' "
" + } + else{ + di "Number of individuals at each time: " in ye `n0' "
" + di "Time effect: " in ye `gamma' "
" +/*@TODO +* di in gr "Variance matrix of the latent trait: " "
" +* matrix list matvar +*/ + } + di "Number of items: " in ye `nbitems' "
" +} + +tempname dd +matrix `dd'=`d' +local items +forvalues i=1/`nbitems' { + local items "`items' item`i'" +} +local modalities +forvalues i=1/`=`nbmodat'-1' { + local modalities "`modalities' delta_`i'" +} + +matrix colnames `dd'=`modalities' +matrix rownames `dd'=`items' +if "`html'" == "" { + matrix list `dd',noblank nohalf noheader + di in gr "Number of studied response's patterns: " in ye `nbpatmax' +} +else { + //di in gr "Number of studied response's patterns: " in ye `nbpatmax' "
" +} + +matrix `dd'=`d' +local gamma=`gamma' + +local tmp=1 +qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.) +forvalues j=1/`nbitems' { + forvalues m=1/`=`nbmodat'-1' { + qui matrix `db'[`tmp',1]=`d'[`j',`m'] + local ++tmp + } +} + +if "`data'"=="" { + clear + if "`method'"!="POPULATION+GH"{ + local temp=`nbmodat'^(`nbtotitems') + qui range x 0 `=`temp'-1' `temp' + qui g t=x + loc i=`nbtotitems' + qui count if t>0 + loc z=r(N) + qui while `z'>0 { + qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1') + qui replace t=mod(t,`nbmodat'^`=`i'-1') + qui count if t>0 + loc z=r(N) + loc i=`i'-1 + } + drop t + if "`longitudinal'"==""{ + qui expand 2 + qui gen group=0 in 1/`temp' + qui replace group=1 in `=`temp'+1'/`=2*`temp'' + } + } + else { + if "`longitudinal'"==""{ + qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000) + qui drop lt1 + qui contract item* group, freq(freq) + qui count + local patobs=r(N) + if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{ + qui gen keep=0 + qui gsort +group -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n0'' + qui gsort -group -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n1'' + } + else{ + qui gen keep=1 + } + } + else{ + qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000) + forvalues j=1/`nbitems'{ + rename itemA`j' item`j' + rename itemB`j' item`=`nbitems'+`j'' + } + qui drop lt1 lt2 + qui contract item*, freq(freq) + local patobs=r(N) + if `patobs'>=`=`n0'*`nbpatterns''{ + qui gen keep=0 + qui gsort -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n0'' + } + else{ + qui gen keep=1 + } + } + qui keep if keep==1 + qui count + local retain=r(N) + di "Number of kept patterns:`retain'" + local method GH + } + if "`longitudinal'"==""{ + qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0 + qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1 + } + else{ + qui gen mean1=`mean1' + qui gen mean2=`mean2' + } + if "`method'"=="GH" { + local temp=`nbmodat'^(`nbtotitems') + local diff0=0 + qui gen proba=. + local dixj=10 + qui count + local tmp=r(N) + + forvalues i=1/`tmp' { + local dix=floor(`tmp'/10) + if mod(`i',`dix')==0 { + if "`html'" == "" { + if "`dixj'"!="10" { + di ".." _c + } + di "`dixj'%" _c + } + local dixj=`dixj'+10 + } + forvalues t=1/`nbt'{ + local int`t'=1 + forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + qui su item`j' in `i' + local rep=r(mean) + local diff0=0 + local diff1=`dlong'[`j',1] + local sum "1+exp(x`t'-`diff1')" + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m'] + local sum "`sum'+exp(`m'*x`t'-`diff`m'')" + } + local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')" + } + } + if "`longitudinal'"==""{ + qui su mean1 in `i' + local mean=r(mean) + qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`var')') display name(x1) + qui replace proba=r(int) in `i' + } + else{ + local int "`int1'*`int2'" + matrix mean=(`mean1',`mean2') + qui gausshermite `int',mu(mean) var(matvar) display name(x1 x2) + qui replace proba=r(int) in `i' + } + } + di + } + else { + qui gen proba=1 + forvalues t=1/`nbt'{ + forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + local diff0=0 + local diff1=`dlong'[`i',1] + qui gen eps0=1 + qui gen eps1=exp(mean`t'-`diff1') + qui gen d=eps0+eps1 + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m'] + qui gen eps`m'=exp(`m'*mean`t'-`diff`m'') + qui replace d=d+eps`m' + } + local listeps + forvalues m=0/`=`nbmodat'-1' { + qui replace proba=proba*eps`m'/d if item`i'==`m' + local listeps `listeps' eps`m' + } + qui drop `listeps' d + } + } + if "`method'"=="MEAN+GH" { + set tracedepth 1 + if "`longitudinal'"==""{ + qui gen keep=0 + qui gsort -group -proba + local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui gsort +group -proba + local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui keep if keep==1 + qui su proba if group==0 + local sumproba0=r(sum)*100 + qui su proba if group==1 + local sumproba1=r(sum)*100 + } + else{ + qui gen keep=0 + qui gsort -proba + local min=min(`nbpatmax',`=`n0'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui keep if keep==1 + } + + qui drop keep proba + local diff0=0 + qui gen proba=. + qui count + local nnew=r(N) + di in gr "Number of studied response's patterns for the GH step: " in ye `nnew' + if "`longitudinal'"==""{ + di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)" + } + local dixj=10 + forvalues i=1/`nnew' { + local dix=floor(`nnew'/10) + if mod(`i',`dix')==0 { + if "`dixj'"!="10" { + di ".." _c + } + di "`dixj'%" _c + local dixj=`dixj'+10 + } + forvalues t=1/`nbt'{ + local int`t'=1 + forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + qui su item`j' in `i' + local rep=r(mean) + local diff0=0 + local diff1=`dlong'[`j',1] + local sum "1+exp(x`t'-`diff1')" + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m'] + local sum "`sum'+exp(`m'*x`t'-`diff`m'')" + } + local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')" + } + } + if "`longitudinal'"==""{ + qui su mean1 in `i' + local mean=r(mean) + qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`var')') display name(x1) + qui replace proba=r(int) in `i' + } + else{ + local int "`int1'*`int2'" + matrix mean=(`mean1',`mean2') + qui gausshermite `int',mu(mean) sigma(matvar) display + qui replace proba=r(int) in `i' + } + } + } + } + qui gen eff=proba + qui gen eff2=. + + if "`longitudinal'"==""{ + qui keep item* eff* group proba + local p1=1/`n1' + local p0=1/`n0' + qui replace eff2=floor(eff/`p1') if group==1 + qui replace eff2=floor(eff/`p0') if group==0 + qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group)) + qui su eff2 if group==1 + local aff1=r(sum) + qui su eff2 if group==0 + local aff0=r(sum) + + local unaff1=`n1'-`aff1' + local unaff0=`n0'-`aff0' + qui gen efftmp=eff2 + qui gsort + group - eff + qui replace eff2=eff2+1 in 1/`unaff0' + qui gsort - group - eff + qui replace eff2=eff2+1 in 1/`unaff1' + + qui drop if eff2==0 + gsort group item* + qui expand eff2 + } + else{ + qui keep item* eff* proba + local p0=1/`n0' + qui replace eff2=floor(eff/`p0') + qui replace eff=eff-eff2*`p0' + qui su eff2 + local aff0=r(sum) + + local unaff0=`n0'-`aff0' + qui gen efftmp=eff2 + qui gsort - eff + qui replace eff2=eff2+1 in 1/`unaff0' + + qui drop if eff2==0 + gsort item* + qui expand eff2 + } + qui drop proba eff eff2 +} + +qui alpha item* +local alpha=r(alpha) + +if "`longitudinal'"==""{ + qui gen groupc=-`n1'/(`n0'+`n1') if group==0 + qui replace groupc=`n0'/(`n0'+`n1') if group==1 + if `nbmodat'==2 { + qui gen i=_n + + tempname diff + matrix `diff'=`dd'' + + qui reshape long item, i(i) + qui rename item rep + qui rename _j item + + qui gen offset=0 + forvalues i=1/`nbitems' { + qui replace offset=-`diff'[1,`i'] if item==`i' + } + + constraint 1 _cons=`=ln(`var')' + qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1) + tempname b V + } + else { + matrix `db'=`db'' + qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvar(`var') + + } + tempname b V + matrix `b'=e(b) + matrix `V'=e(V) + local gammaest=`b'[1,1] + local se=`V'[1,1]^.5 +} +else{ + forvalues i=1/`nbitems'{ + rename item`i' t1item`i' + } + forvalues i=`=`nbitems'+1'/`nbtotitems'{ + rename item`i' t2item`=`i'-`nbitems'' + } + qui gen i=_n + local list="" + forvalues i=1/`nbitems'{ + local list="`list' t@item`i'" + } + qui reshape long `list', i(i) j(temps) + qui reshape long titem, i(i temps) j(item) + qui drop if titem==. + + qui gen offset=0 + local itemnb=1 + forvalues t=1/`nbt'{ + forvalues i=1/`nbitems' { + qui replace offset=-`dlong'[`itemnb',1] if item==`i' & temps==`t' + local ++itemnb + } + } + gen t1=temps==1 + gen t2=temps==2 + + matrix C=cholesky(matvar) + constraint define 1 [i1_1]t1=`=C[1,1]' + constraint define 2 [i1_2]t2=`=C[2,2]' + constraint define 3 [i1_2_1]_cons=`=C[2,1]' + + eq b1:t1 + eq b2:t2 + qui gllamm titem t2,i(i) link(logit) nocons fam(bin) nrf(2) eq(b1 b2) constraints(1 2 3) iterate(20) trace offset(offset) + tempname b V + matrix `b'=e(b) + matrix `V'=e(V) + local gammaest=`b'[1,1] + local se=`V'[1,1]^.5 + local n1=`n0' +} +local poweruni=1-normal(1.96-`gamma'/`se') + +if "`html'" == "" { + di + di + di in gr "{hline 91}" + di _col(60) "Estimation with the " + di _col(50) "Cramer-Rao bound" _col(75) "classical formula" + di in gr "{hline 91}" +} +else { + di "" + di "" + di "" + di "" +} + + if "`longitudinal'"==""{ + if "`gammafixed'"=="" { + if "`html'" == "" { + di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest' + } + else { + di "" + } + } + if "`html'" == "" { + di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se' + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + } + else { + di "" + di "" + } + local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se') + local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96) + local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2 + } + else{ + if "`gammafixed'"=="" { + if "`html'" == "" { + di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest' + } + else { + di "" + } + } + if "`html'" == "" { + di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se' + di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2' + } + else { + di "" + di "" + } + local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=matvar[1,1]'-`=matvar[2,1]'))-1.96) + local clnsn=2*(`=matvar[1,1]'-`=matvar[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2) + } + if "`html'" == "" { + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower' + di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0'' + } + else { + di "" + di "" + } + local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0')) + if "`html'" == "" { + di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio' + } + else { + di "" + } + if `expectedpower'!=-1 { + qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'') + local expn_1=r(N_1) + local expn_2=r(N_2) + local expn2=`expn_1'*`ratio' + di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2' + } + if "`html'" == "" { + di in gr "{hline 91}" + } + else { + di "
Estimation with the
Cramer-Rao boundclassical formula
Estimated value of the group effect" in ye %7.2f `gammaest' "
Estimation of the s.e. of the group effect" in ye %7.2f `se' "
Estimation of the variance of the group effect" in ye %10.4f `=`se'^2' "
Estimated value of the time effect" in ye %7.2f `gammaest' "
Estimation of the s.e. of the time effect" in ye %7.2f `se' "
Estimation of the variance of the time effect" in ye %10.4f `=`se'^2' "
Estimation of the power" in ye %6.4f `poweruni' "" in ye %6.4f `clpower' "
Number of patients for a power of" %6.2f `=`poweruni'*100' "%" in ye `n0' "/" `n1' "" in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0'' "
Ratio of the number of patients" in ye %6.2f `ratio' "
" + } + return scalar EstGamma=`gammaest' + return scalar CRbound=`=`se'^2' + return scalar CRPower=`poweruni' + return scalar ClPower=`clpower' + return scalar ClSS=`clnsn' + return scalar Ratio=`ratio' + return scalar CronbachAlpha=`alpha' + + + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschpower5.ado b/Modules/ado/personal/r/raschpower5.ado new file mode 100644 index 0000000..1496037 --- /dev/null +++ b/Modules/ado/personal/r/raschpower5.ado @@ -0,0 +1,582 @@ +*! version 5 : October 22th, 2013 +*! Jean-Benoit Hardouin, Myriam Blanchin +************************************************************************************************************ +* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals +* +* Version 1 : January 25, 2010 (Jean-Benoit Hardouin) +* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin) +* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin) +* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin) +* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections +* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results +* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method +* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design +* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option +* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items +* +* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* Myriam Blanchin, myriam.blanchin@univ-nantes.fr +* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health" +* Faculty of Pharmaceutical Sciences - University of Nantes - France +* http://www.sphere-nantes.org +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2010-2013 Jean-Benoit Hardouin, Myriam Blanchin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschpower5,rclass +syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar DETail] +version 11 + +tempfile raschpowerfile +capture qui save "`raschpowerfile'",replace +tempname db d dlong matvar +if "`difficulties'"=="" { + matrix `d'=[-1\-0.5\0\0.5\1] +} +else { + matrix `d'=`difficulties' +} +local nbitems=rowsof(`d') +local nbmodat=colsof(`d')+1 + +if "`longitudinal'"==""{ + local nbt=1 + local nbtotitems=`nbitems' + local nbpatmax=2*`nbmodat'^`nbitems' + if "`var'"==""{ + local var=1 + } + else{ + capture confirm number `var' + if !_rc { + local var=`var' + } + else{ + matrix `matvar'=`var' + capture confirm matrix `matvar' + if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{ + local var=`matvar'[1,1] + } + else{ + di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}" + error 198 + exit + } + } + } + matrix `dlong'=`d' + + + local sumd=0 + forvalues numit=1/`nbitems'{ + local sumd=`sumd'+`d'[`numit',1] + } + local sumd=`sumd'/`nbitems' + if `=abs(`sumd')'>=`=2*sqrt(`var')'{ + di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}" + } + +} +else{ + local nbt=2 + local nbtotitems=2*`nbitems' + local nbpatmax=`nbmodat'^(`nbitems'*2) + local n1=0 + local mean1=0 + local mean2=`mean1'+`gamma' + if "`var'"==""{ + matrix `matvar'=(1,0\0,1) + } + else{ + matrix `matvar'=`var' + capture confirm matrix `matvar' + if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{ + di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}" + error 198 + exit + } + } + matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.) + matrix `dlong'[1,1]=`d' + matrix `dlong'[`=`nbitems'+1',1]=`d' +} + +if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{ + local method POPULATION+GH +} + +if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' { + di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses" + di in gr "is lesser than the number of pattern retained by the MEAN+GH method." + di in gr "The -method- option is replaced by GH." + local method GH +} +else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{ + di in red "The number of patterns is too high for the chosen method" + exit +} +else if "`method'"=="" { + if `nbpatmax'<2000 { + local method GH + } + else { + local method POPULATION+GH + } +} + +if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{ + di in red "Invalid method name" + exit +} + + +if "`longitudinal'"==""{ + di in gr "Number of individuals in the first group: " in ye `n0' + di in gr "Number of individuals in the second group: " in ye `n1' + di in green "Group effect: " in ye `gamma' + di in gr "Variance of the latent trait: " in ye `var' +} +else{ + di in gr "Number of individuals at each time: " in ye `n0' + di in green "Time effect: " in ye `gamma' + di in gr "Variance matrix of the latent trait: " + matrix list `matvar',noheader +} +di in gr "Number of items: " in ye `nbitems' +di in green "Difficulties parameters of the items: " +tempname dd +matrix `dd'=`d'' +local items +forvalues i=1/`nbitems' { + local items "`items' item`i'" +} +local modalities +forvalues i=1/`=`nbmodat'-1' { + local modalities "`modalities' delta_`i'" +} + +matrix colnames `dd'=`items' +matrix rownames `dd'=`modalities' +matrix list `dd',noblank nohalf noheader +if "`detail'"!=""{ + di in gr "Method: " in ye "`method'" + di in gr "Number of studied response's patterns: " in ye `nbpatmax' +} +matrix `dd'=`d' +local gamma=`gamma' + +local tmp=1 +qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.) +forvalues j=1/`nbitems' { + forvalues m=1/`=`nbmodat'-1' { + qui matrix `db'[`tmp',1]=`d'[`j',`m'] + local ++tmp + } +} + +if "`data'"=="" { + clear + if "`method'"!="POPULATION+GH"{ + local temp=`nbmodat'^(`nbtotitems') + qui range x 0 `=`temp'-1' `temp' + qui g t=x + loc i=`nbtotitems' + qui count if t>0 + loc z=r(N) + qui while `z'>0 { + qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1') + qui replace t=mod(t,`nbmodat'^`=`i'-1') + qui count if t>0 + loc z=r(N) + loc i=`i'-1 + } + drop t + if "`longitudinal'"==""{ + qui expand 2 + qui gen group=0 in 1/`temp' + qui replace group=1 in `=`temp'+1'/`=2*`temp'' + } + } + else { + if "`longitudinal'"==""{ + qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000) + qui drop lt1 + qui contract item* group, freq(freq) + qui count + local patobs=r(N) + if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{ + qui gen keep=0 + qui gsort +group -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n0'' + qui gsort -group -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n1'' + } + else{ + qui gen keep=1 + } + } + else{ + qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000) + forvalues j=1/`nbitems'{ + rename itemA`j' item`j' + rename itemB`j' item`=`nbitems'+`j'' + } + qui drop lt1 lt2 + qui contract item*, freq(freq) + local patobs=r(N) + if `patobs'>=`=`n0'*`nbpatterns''{ + qui gen keep=0 + qui gsort -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n0'' + } + else{ + qui gen keep=1 + } + } + qui keep if keep==1 + qui count + local retain=r(N) + di "Number of kept patterns:`retain'" + local method GH + } + if "`longitudinal'"==""{ + qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0 + qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1 + } + else{ + qui gen mean1=`mean1' + qui gen mean2=`mean2' + } + if "`method'"=="GH" { + local temp=`nbmodat'^(`nbtotitems') + local diff0=0 + qui gen proba=. + local dixj=10 + qui count + local tmp=r(N) + + forvalues i=1/`tmp' { + local dix=floor(`tmp'/10) + if mod(`i',`dix')==0 { + if "`dixj'"!="10" { + di ".." _c + } + di "`dixj'%" _c + local dixj=`dixj'+10 + } + forvalues t=1/`nbt'{ + local int`t'=1 + forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + qui su item`j' in `i' + local rep=r(mean) + local diff0=0 + local diff1=`dlong'[`j',1] + local sum "1+exp(x`t'-`diff1')" + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m'] + local sum "`sum'+exp(`m'*x`t'-`diff`m'')" + } + local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')" + } + } + if "`longitudinal'"==""{ + qui su mean1 in `i' + local mean=r(mean) + qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`var')') display name(x1) + qui replace proba=r(int) in `i' + } + else{ + local int "`int1'*`int2'" + matrix mean=(`mean1',`mean2') + qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2) + qui replace proba=r(int) in `i' + } + } + di + } + else { + qui gen proba=1 + forvalues t=1/`nbt'{ + forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + local diff0=0 + local diff1=`dlong'[`i',1] + qui gen eps0=1 + qui gen eps1=exp(mean`t'-`diff1') + qui gen d=eps0+eps1 + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m'] + qui gen eps`m'=exp(`m'*mean`t'-`diff`m'') + qui replace d=d+eps`m' + } + local listeps + forvalues m=0/`=`nbmodat'-1' { + qui replace proba=proba*eps`m'/d if item`i'==`m' + local listeps `listeps' eps`m' + } + qui drop `listeps' d + } + } + if "`method'"=="MEAN+GH" { + set tracedepth 1 + if "`longitudinal'"==""{ + qui gen keep=0 + qui gsort -group -proba + local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui gsort +group -proba + local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui keep if keep==1 + qui su proba if group==0 + local sumproba0=r(sum)*100 + qui su proba if group==1 + local sumproba1=r(sum)*100 + } + else{ + qui gen keep=0 + qui gsort -proba + local min=min(`nbpatmax',`=`n0'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui keep if keep==1 + } + + qui drop keep proba + local diff0=0 + qui gen proba=. + qui count + local nnew=r(N) + di in gr "Number of studied response's patterns for the GH step: " in ye `nnew' + if "`longitudinal'"==""{ + di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)" + } + local dixj=10 + forvalues i=1/`nnew' { + local dix=floor(`nnew'/10) + if mod(`i',`dix')==0 { + if "`dixj'"!="10" { + di ".." _c + } + di "`dixj'%" _c + local dixj=`dixj'+10 + } + forvalues t=1/`nbt'{ + local int`t'=1 + forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + qui su item`j' in `i' + local rep=r(mean) + local diff0=0 + local diff1=`dlong'[`j',1] + local sum "1+exp(x`t'-`diff1')" + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m'] + local sum "`sum'+exp(`m'*x`t'-`diff`m'')" + } + local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')" + } + } + if "`longitudinal'"==""{ + qui su mean1 in `i' + local mean=r(mean) + qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`var')') display name(x1) + qui replace proba=r(int) in `i' + } + else{ + local int "`int1'*`int2'" + matrix mean=(`mean1',`mean2') + qui gausshermite `int',mu(mean) var(`matvar') display + qui replace proba=r(int) in `i' + } + } + } + } + qui gen eff=proba + qui gen eff2=. + + if "`longitudinal'"==""{ + qui keep item* eff* group proba + local p1=1/`n1' + local p0=1/`n0' + qui replace eff2=floor(eff/`p1') if group==1 + qui replace eff2=floor(eff/`p0') if group==0 + qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group)) + qui su eff2 if group==1 + local aff1=r(sum) + qui su eff2 if group==0 + local aff0=r(sum) + + local unaff1=`n1'-`aff1' + local unaff0=`n0'-`aff0' + qui gen efftmp=eff2 + qui gsort + group - eff + qui replace eff2=eff2+1 in 1/`unaff0' + qui gsort - group - eff + qui replace eff2=eff2+1 in 1/`unaff1' + + qui drop if eff2==0 + gsort group item* + qui expand eff2 + } + else{ + qui keep item* eff* proba + local p0=1/`n0' + qui replace eff2=floor(eff/`p0') + qui replace eff=eff-eff2*`p0' + qui su eff2 + local aff0=r(sum) + + local unaff0=`n0'-`aff0' + qui gen efftmp=eff2 + qui gsort - eff + qui replace eff2=eff2+1 in 1/`unaff0' + + qui drop if eff2==0 + gsort item* + qui expand eff2 + } + qui drop proba eff eff2 +} + +qui alpha item* +local alpha=r(alpha) + +if "`longitudinal'"==""{ + qui gen groupc=-`n1'/(`n0'+`n1') if group==0 + qui replace groupc=`n0'/(`n0'+`n1') if group==1 + if `nbmodat'==2 { + qui gen i=_n + + tempname diff + matrix `diff'=`dd'' + + qui reshape long item, i(i) + qui rename item rep + qui rename _j item + + qui gen offset=0 + forvalues i=1/`nbitems' { + qui replace offset=-`diff'[1,`i'] if item==`i' + } + + constraint 1 _cons=`=ln(`var')' + qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1) + tempname b V + } + else { + matrix `db'=`db'' + qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvar(`var') + + } + tempname b V + matrix `b'=e(b) + matrix `V'=e(V) + local gammaest=`b'[1,1] + local se=`V'[1,1]^.5 +} +else{ + qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar') + tempname b V + matrix `b'=e(b) + matrix `V'=e(V) + local gammaest=`b'[1,1] + local se=`V'[1,1]^.5 + local n1=`n0' +} +local poweruni=1-normal(1.96-`gamma'/`se') + + + di + di + if "`detail'"!=""{ + di in gr "{hline 91}" + di _col(60) "Estimation with the " + di _col(50) "Cramer-Rao bound" _col(75) "classical formula" + di in gr "{hline 91}" + } + + if "`longitudinal'"==""{ + local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se') + local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96) + local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2 + local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0')) + if "`detail'"==""{ + di in gr "{hline 65}" + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' + di in gr "{hline 65}" + } + else{ + if "`gammafixed'"=="" { + di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest' + } + di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se' + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower' + di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0'' + di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio' + di in gr "{hline 91}" + } + } + else{ + local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96) + local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2) + local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0')) + if "`detail'"==""{ + di in gr "{hline 65}" + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' + di in gr "{hline 65}" + } + else{ + if "`gammafixed'"=="" { + di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest' + } + di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se' + di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower' + di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn' + di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio' + di in gr "{hline 91}" + } + } + /* ceci est un commentaire */ + if `expectedpower'!=-1 { + qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'') + local expn_1=r(N_1) + local expn_2=r(N_2) + local expn2=`expn_1'*`ratio' + di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2' + } + + return scalar EstGamma=`gammaest' + return scalar CRbound=`=`se'^2' + return scalar CRPower=`poweruni' + return scalar ClPower=`clpower' + return scalar ClSS=`clnsn' + return scalar Ratio=`ratio' + return scalar CronbachAlpha=`alpha' + + + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschpower51.ado b/Modules/ado/personal/r/raschpower51.ado new file mode 100644 index 0000000..9e70e7a --- /dev/null +++ b/Modules/ado/personal/r/raschpower51.ado @@ -0,0 +1,651 @@ +*! version 5.1 : January 21th, 2014 +*! Jean-Benoit Hardouin, Myriam Blanchin +************************************************************************************************************ +* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals +* +* Version 1 : January 25, 2010 (Jean-Benoit Hardouin) +* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin) +* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin) +* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin) +* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections +* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results +* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method +* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design +* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option +* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items +* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups +* +* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* Myriam Blanchin, myriam.blanchin@univ-nantes.fr +* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health" +* Faculty of Pharmaceutical Sciences - University of Nantes - France +* http://www.sphere-nantes.org +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschpower51,rclass +syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar DETail] +version 11 + +tempfile raschpowerfile +capture qui save "`raschpowerfile'",replace +tempname db d dlong matvar + +/******************************************************************************* +DEFINITION DES PARAMETRES +*******************************************************************************/ +if "`difficulties'"=="" { + matrix `d'=[-1\-0.5\0\0.5\1] +} +else { + matrix `d'=`difficulties' +} +local nbitems=rowsof(`d') +local nbmodat=colsof(`d')+1 + +if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/ + local nbt=1 + local nbtotitems=`nbitems' + local nbpatmax=2*`nbmodat'^`nbitems' + if "`var'"==""{ + local var=1 + } + else{ + capture confirm number `var' + if !_rc { + local var0=`var' + local var1=`var' + } + else{ + local nbw:word count `var' + local grp=1 + if `nbw'==2 { + local t1: word 1 of `var' + capture confirm number `t1' + if !_rc { + local t2: word 2 of `var' + capture confirm number `t2' + if !_rc { + local var0=`t1' + local var1=`t2' + local grp=2 + } + } + } + if `nbw'!=2|`grp'==1 { + capture confirm matrix `var' + if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{ + matrix `matvar'=`var' + local var0=`matvar'[1,1] + local var1=`matvar'[1,1] + } + else{ + di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}" + error 198 + exit + } + } + } + } + matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/ + local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2) + + local sumd=0 + forvalues numit=1/`nbitems'{ + local sumd=`sumd'+`d'[`numit',1] + } + local sumd=`sumd'/`nbitems' + if `=abs(`sumd')'>=`=2*sqrt(`varc')'{ + di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}" + } + +} +else{ /*CAS LONGITUDINAL*/ + local nbt=2 + local nbtotitems=2*`nbitems' + local nbpatmax=`nbmodat'^(`nbitems'*2) + local n1=0 + local mean1=0 + local mean2=`mean1'+`gamma' + if "`var'"==""{ + matrix `matvar'=(1,0\0,1) + } + else{ + matrix `matvar'=`var' + capture confirm matrix `matvar' + if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{ + di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}" + error 198 + exit + } + } + matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.) + matrix `dlong'[1,1]=`d' + matrix `dlong'[`=`nbitems'+1',1]=`d' +} + +/******************************************************************************* +DEFINITION DE LA METHODE +*******************************************************************************/ + +if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{ + local method POPULATION+GH +} + +if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' { + di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses" + di in gr "is lesser than the number of pattern retained by the MEAN+GH method." + di in gr "The -method- option is replaced by GH." + local method GH +} +else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{ + di in red "The number of patterns is too high for the chosen method" + exit +} +else if "`method'"=="" { + if `nbpatmax'<2000 { + local method GH + } + else { + local method POPULATION+GH + } +} + +if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{ + di in red "Invalid method name" + exit +} + +/******************************************************************************* +AFFICHAGE DES PARAMETRES +*******************************************************************************/ + +if "`longitudinal'"==""{ + di in gr "Number of individuals in the first group: " in ye `n0' + di in gr "Number of individuals in the second group: " in ye `n1' + di in green "Group effect: " in ye `gamma' + di in gr "Variance of the latent trait in the first group: " in ye `var0' + di in gr "Variance of the latent trait in the second group: " in ye `var1' +} +else{ + di in gr "Number of individuals at each time: " in ye `n0' + di in green "Time effect: " in ye `gamma' + di in gr "Variance matrix of the latent trait: " + matrix list `matvar',noheader +} +di in gr "Number of items: " in ye `nbitems' +di in green "Difficulties parameters of the items: " +tempname dd +matrix `dd'=`d'' +local items +forvalues i=1/`nbitems' { + local items "`items' item`i'" +} +local modalities +forvalues i=1/`=`nbmodat'-1' { + local modalities "`modalities' delta_`i'" +} + +matrix colnames `dd'=`items' +matrix rownames `dd'=`modalities' +matrix list `dd',noblank nohalf noheader +if "`detail'"!=""{ + di in gr "Method: " in ye "`method'" + di in gr "Number of studied response's patterns: " in ye `nbpatmax' +} +matrix `dd'=`d' +local gamma=`gamma' + +local tmp=1 +qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.) +forvalues j=1/`nbitems' { + forvalues m=1/`=`nbmodat'-1' { + qui matrix `db'[`tmp',1]=`d'[`j',`m'] + local ++tmp + } +} + + +/******************************************************************************* +CREATION DU DATASET ATTENDU +*******************************************************************************/ + +if "`data'"=="" { + clear + if "`method'"!="POPULATION+GH"{ + local temp=`nbmodat'^(`nbtotitems') + qui range x 0 `=`temp'-1' `temp' + qui g t=x + loc i=`nbtotitems' + qui count if t>0 + loc z=r(N) + qui while `z'>0 { + qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1') + qui replace t=mod(t,`nbmodat'^`=`i'-1') + qui count if t>0 + loc z=r(N) + loc i=`i'-1 + } + drop t + if "`longitudinal'"==""{ + qui expand 2 + qui gen group=0 in 1/`temp' + qui replace group=1 in `=`temp'+1'/`=2*`temp'' + } + } + else { /*METHODE POPULATION (SIMULATION)*/ + if "`longitudinal'"==""{ + *qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000) + qui simirt, clear pcm(`d') cov(`var1') mean(`=`n0'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)') + qui gen group=1 + tempfile save1 + qui save `save1',replace + qui simirt, clear pcm(`d') cov(`var0') mean(`=-`n1'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)') + qui gen group=0 + qui append usinf `save1' + qui drop lt1 + qui contract item* group, freq(freq) + qui count + local patobs=r(N) + if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{ + qui gen keep=0 + qui gsort +group -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n0'' + qui gsort -group -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n1'' + } + else{ + qui gen keep=1 + } + } + else{ + qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000) + forvalues j=1/`nbitems'{ + rename itemA`j' item`j' + rename itemB`j' item`=`nbitems'+`j'' + } + qui drop lt1 lt2 + qui contract item*, freq(freq) + local patobs=r(N) + if `patobs'>=`=`n0'*`nbpatterns''{ + qui gen keep=0 + qui gsort -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n0'' + } + else{ + qui gen keep=1 + } + } + qui keep if keep==1 + qui count + local retain=r(N) + di "Number of kept patterns:`retain'" + local method GH + } + if "`longitudinal'"==""{ + qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0 + qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1 + qui gen var1=`var0' if group==0 + qui replace var1=`var1' if group==1 + } + else{ + qui gen mean1=`mean1' + qui gen mean2=`mean2' + } + /*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/ + if "`method'"=="GH" { + local temp=`nbmodat'^(`nbtotitems') + local diff0=0 + qui gen proba=. + local dixj=10 + qui count + local tmp=r(N) + + forvalues i=1/`tmp' { + local dix=floor(`tmp'/10) + if mod(`i',`dix')==0 { + if "`dixj'"!="10" { + di ".." _c + } + di "`dixj'%" _c + local dixj=`dixj'+10 + } + forvalues t=1/`nbt'{ + local int`t'=1 + forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + qui su item`j' in `i' + local rep=r(mean) + local diff0=0 + local diff1=`dlong'[`j',1] + local sum "1+exp(x`t'-`diff1')" + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m'] + local sum "`sum'+exp(`m'*x`t'-`diff`m'')" + } + local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')" + } + } + if "`longitudinal'"==""{ + qui su mean1 in `i' + local mean=r(mean) + qui su var1 in `i' + local vart=r(mean) + qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1) + qui replace proba=r(int) in `i' + } + else{ + local int "`int1'*`int2'" + matrix mean=(`mean1',`mean2') + qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2) + qui replace proba=r(int) in `i' + } + } + di + } + else { + qui gen proba=1 + forvalues t=1/`nbt'{ + forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + local diff0=0 + local diff1=`dlong'[`i',1] + qui gen eps0=1 + qui gen eps1=exp(mean`t'-`diff1') + qui gen d=eps0+eps1 + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m'] + qui gen eps`m'=exp(`m'*mean`t'-`diff`m'') + qui replace d=d+eps`m' + } + local listeps + forvalues m=0/`=`nbmodat'-1' { + qui replace proba=proba*eps`m'/d if item`i'==`m' + local listeps `listeps' eps`m' + } + qui drop `listeps' d + } + } + if "`method'"=="MEAN+GH" { + set tracedepth 1 + if "`longitudinal'"==""{ + qui gen keep=0 + qui gsort -group -proba + local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui gsort +group -proba + local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui keep if keep==1 + qui su proba if group==0 + local sumproba0=r(sum)*100 + qui su proba if group==1 + local sumproba1=r(sum)*100 + } + else{ + qui gen keep=0 + qui gsort -proba + local min=min(`nbpatmax',`=`n0'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui keep if keep==1 + } + + qui drop keep proba + local diff0=0 + qui gen proba=. + qui count + local nnew=r(N) + di in gr "Number of studied response's patterns for the GH step: " in ye `nnew' + if "`longitudinal'"==""{ + di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)" + } + local dixj=10 + forvalues i=1/`nnew' { + local dix=floor(`nnew'/10) + if mod(`i',`dix')==0 { + if "`dixj'"!="10" { + di ".." _c + } + di "`dixj'%" _c + local dixj=`dixj'+10 + } + forvalues t=1/`nbt'{ + local int`t'=1 + forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + qui su item`j' in `i' + local rep=r(mean) + local diff0=0 + local diff1=`dlong'[`j',1] + local sum "1+exp(x`t'-`diff1')" + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m'] + local sum "`sum'+exp(`m'*x`t'-`diff`m'')" + } + local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')" + } + } + if "`longitudinal'"==""{ + qui su mean1 in `i' + local mean=r(mean) + qui su var1 in `i' + local vart=r(mean) + qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1) + qui replace proba=r(int) in `i' + } + else{ + local int "`int1'*`int2'" + matrix mean=(`mean1',`mean2') + qui gausshermite `int',mu(mean) var(`matvar') display + qui replace proba=r(int) in `i' + } + } + } + } + qui gen eff=proba + qui gen eff2=. + + if "`longitudinal'"==""{ + qui keep item* eff* group proba + local p1=1/`n1' + local p0=1/`n0' + qui replace eff2=floor(eff/`p1') if group==1 + qui replace eff2=floor(eff/`p0') if group==0 + qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group)) + qui su eff2 if group==1 + local aff1=r(sum) + qui su eff2 if group==0 + local aff0=r(sum) + + local unaff1=`n1'-`aff1' + local unaff0=`n0'-`aff0' + qui gen efftmp=eff2 + qui gsort + group - eff + qui replace eff2=eff2+1 in 1/`unaff0' + qui gsort - group - eff + qui replace eff2=eff2+1 in 1/`unaff1' + + qui drop if eff2==0 + gsort group item* + qui expand eff2 + } + else{ + qui keep item* eff* proba + local p0=1/`n0' + qui replace eff2=floor(eff/`p0') + qui replace eff=eff-eff2*`p0' + qui su eff2 + local aff0=r(sum) + + local unaff0=`n0'-`aff0' + qui gen efftmp=eff2 + qui gsort - eff + qui replace eff2=eff2+1 in 1/`unaff0' + + qui drop if eff2==0 + gsort item* + qui expand eff2 + } + qui drop proba eff eff2 +} + +qui alpha item* +local alpha=r(alpha) + +if "`longitudinal'"==""{ + qui gen groupc=-`n1'/(`n0'+`n1') if group==0 + qui replace groupc=`n0'/(`n0'+`n1') if group==1 + if `nbmodat'==2 { + qui gen i=_n + + tempname diff + matrix `diff'=`dd'' + + qui reshape long item, i(i) + qui rename item rep + qui rename _j item + + qui gen offset=0 + forvalues i=1/`nbitems' { + qui replace offset=-`diff'[1,`i'] if item==`i' + } + if `var0'==`var1' { + *constraint 1 _cons=`=ln(`var')' + *qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1) + constraint 1 _cons=`=sqrt(`var0')' + qui gllamm rep groupc ,nocons i(i) offset(offset) constraint(1) fam(bin) link(logit) nrf(1) trace + } + else { + tempvar G0 G1 + qui gen `G0'=group==0 + qui gen `G1'=group==1 + qui eq B0: `G0' + qui eq B1: `G1' + constraint 1 _cons=0 + constraint 2 `G0'=`=sqrt(`var0')' + constraint 3 `G1'=`=sqrt(`var1')' + qui gllamm rep groupc ,nocons i(i) offset(offset) constraint(1 2 3) fam(bin) link(logit) eqs(B0 B1) nrf(2) trace + } + tempname b V + } + else { + matrix `db'=`db'' + if `var0'==`var1' { + qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvar(`var0') + } + else { + qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvargroupc(`var') + } + } + tempname b V + matrix `b'=e(b) + matrix `V'=e(V) + local gammaest=`b'[1,1] + local se=`V'[1,1]^.5 +} +else{ + qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar') + tempname b V + matrix `b'=e(b) + matrix `V'=e(V) + local gammaest=`b'[1,1] + local se=`V'[1,1]^.5 + local n1=`n0' +} +local poweruni=1-normal(1.96-`gamma'/`se') + + + di + di + if "`detail'"!=""{ + di in gr "{hline 91}" + di _col(60) "Estimation with the " + di _col(50) "Cramer-Rao bound" _col(75) "classical formula" + di in gr "{hline 91}" + } + + if "`longitudinal'"==""{ + local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se') + local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96) + local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2 + local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0')) + if "`detail'"==""{ + di in gr "{hline 65}" + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' + di in gr "{hline 65}" + } + else{ + if "`gammafixed'"=="" { + di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest' + } + di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se' + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower' + di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0'' + di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio' + di in gr "{hline 91}" + } + } + else{ + local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96) + local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2) + local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0')) + if "`detail'"==""{ + di in gr "{hline 65}" + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' + di in gr "{hline 65}" + } + else{ + if "`gammafixed'"=="" { + di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest' + } + di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se' + di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower' + di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn' + di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio' + di in gr "{hline 91}" + } + } + + if `expectedpower'!=-1 { + qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'') + local expn_1=r(N_1) + local expn_2=r(N_2) + local expn2=`expn_1'*`ratio' + di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2' + } + + return scalar EstGamma=`gammaest' + return scalar CRbound=`=`se'^2' + return scalar CRPower=`poweruni' + return scalar ClPower=`clpower' + return scalar ClSS=`clnsn' + return scalar Ratio=`ratio' + return scalar CronbachAlpha=`alpha' + + + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschpower511.ado b/Modules/ado/personal/r/raschpower511.ado new file mode 100644 index 0000000..9be0f0a --- /dev/null +++ b/Modules/ado/personal/r/raschpower511.ado @@ -0,0 +1,907 @@ +*! version 5.11 : July 24, 2019 +*! Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot +************************************************************************************************************ +* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals +* +* Version 1 : January 25th, 2010 (Jean-Benoit Hardouin) +* Version 1.1 : January 26th, 2010 (Jean-Benoit Hardouin) +* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin) +* version 1.3 : May 2nd, 2011 (Jean-Benoit Hardouin) +* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections +* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results +* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method +* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design +* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option +* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items +* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups +* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups +* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug +* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display +* version 5.5 : April 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : graph option for longitudinal design +* version 5.6 : April 10th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : corrections of bugs +* version 5.7 : June 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : minor corrections +* version 5.8 : July 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : correction of a bug when the variances are different in the 2 groups (transversal) +* version 5.9 : September 26th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : fixed of a bug with the graph option (correlation could be greater than one) +* version 5.10 : July 18th, 2019 (Jean-Benoit Hardouin) : filesave and dirsave options +* version 5.10 : July 24th, 2019 (Jean-Benoit Hardouin) : pcm->pcmold +* +* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* Myriam Blanchin, myriam.blanchin@univ-nantes.fr +* Bastien Perrot, Bastien.perrot@univ-nantes.fr +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours +* http://www.sphere-nantes.org +* +* News about this program : http://www.anaqol.org - anaqol@sphere-nantes.fr +* +* Copyright 2010-2014, 2019 Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschpower,rclass +syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1) min(real 0.25) step(real 1) max(real 9) FILESave DIRSave(string) pro] +version 11 + +if "`pro'"!="" { + di "START" +} + +if "`html'" != "" { + set scheme sj + local htmlregion "graphregion(fcolor(white) ifcolor(white))" + di "" + di "
"
+}
+
+tempfile raschpowerfile
+capture qui save "`raschpowerfile'",replace
+tempname db d dlong matvar
+
+/*******************************************************************************
+DEFINITION DES PARAMETRES
+*******************************************************************************/
+
+if "`graph'" != "" & "`longitudinal'" != "" {
+	if `gvar' != -1 & `gcorr' != -1 {
+		di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
+		error 198
+	}
+	if `gvar' == -1 & `gcorr' == -1 {
+		di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
+		error 198
+	}
+}
+
+if "`difficulties'"=="" {
+   matrix `d'=[-1\-0.5\0\0.5\1]
+}
+else {
+   matrix `d'=`difficulties'
+}
+local nbitems=rowsof(`d')
+local nbmodat=colsof(`d')+1
+
+if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
+	local nbt=1
+	local nbtotitems=`nbitems'
+	local nbpatmax=2*`nbmodat'^`nbitems'
+	if "`var'"==""{
+		local var=1
+		local var0=1
+		local var1=1
+	}
+	else{
+		capture confirm number `var'
+		if !_rc {
+			local var0=`var'
+			local var1=`var'
+		}
+		else{
+		   local nbw:word count `var'
+		   local grp=1
+		   if `nbw'==2 {
+				local t1: word 1 of `var'
+                capture confirm number `t1'
+				if !_rc {
+					local t2: word 2 of `var'
+                    capture confirm number `t2'
+                    if !_rc {
+                       local var0=`t1'
+                       local var1=`t2'
+                       local grp=2
+                    }
+				}
+			}
+			if `nbw'!=2|`grp'==1 {
+				capture confirm matrix `var'
+			    if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
+				    matrix `matvar'=`var'
+					local var0=`matvar'[1,1]
+					local var1=`matvar'[1,1]
+			    }
+			    else{
+					di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
+					error 198
+					exit
+			    }
+		    }
+		}
+	}
+	matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
+    local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
+
+	local sumd=0
+	forvalues numit=1/`nbitems'{
+		local sumd=`sumd'+`d'[`numit',1]
+	}
+	local sumd=`sumd'/`nbitems'
+	if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
+		if "`html'" == "" {
+			di  "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
+		}
+	}
+
+}
+else{ /*CAS LONGITUDINAL*/
+	local nbt=2
+	local nbtotitems=2*`nbitems'
+	local nbpatmax=`nbmodat'^(`nbitems'*2)
+	local n1=0
+	local mean1=0
+	local mean2=`mean1'+`gamma'
+	if "`var'"==""{
+		matrix `matvar'=(1,0\0,1)
+	}
+	else{
+		matrix `matvar'=`var'
+		capture confirm matrix `matvar'
+		if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
+			di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
+			error 198
+			exit
+		}
+	}
+	matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
+	matrix `dlong'[1,1]=`d'
+	matrix `dlong'[`=`nbitems'+1',1]=`d'
+}
+
+/*
+if "`max'" == "" {
+	local max = 9 + `step'/2
+}
+else {
+	local max = `max' + `step'/2
+}*/
+
+forval v = `min'(`step')`max' {
+	local w = `v'
+}
+if `w' < `max' {
+	local max = `max' + `step'
+}
+if "`longitudinal'"!="" & `gvar'!=-1 {                
+	local max = min(`max',0.99999)    /* pour avoir des corrélations < 1 */
+}
+
+/*******************************************************************************
+DEFINITION DE LA METHODE
+*******************************************************************************/
+
+if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
+	local method POPULATION+GH
+}
+
+if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
+   di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
+   di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
+   di in gr "The -method- option is replaced by GH."
+   local method GH
+}
+else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
+	di in red "The number of patterns is too high for the chosen method"
+	exit
+}
+else if "`method'"=="" {
+    if `nbpatmax'<2000 {
+        local method GH
+    }
+    else  {
+        local method POPULATION+GH
+    }
+}
+
+if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
+	di in red "Invalid method name"
+	exit
+}
+
+/*******************************************************************************
+AFFICHAGE DES PARAMETRES
+*******************************************************************************/
+
+if "`longitudinal'"==""{
+	di in gr "Number of individuals in the first group: " in ye `n0'
+	di in gr "Number of individuals in the second group: " in ye `n1'
+	di in green "Group effect: " in ye `gamma'
+	di in  gr "Variance of the latent trait in the first group: " in ye `var0'
+	di in  gr "Variance of the latent trait in the second group: " in ye `var1'
+}
+else{
+	di in gr "Number of individuals at each time:  " in ye `n0'
+	di in green "Time effect: " in ye `gamma'
+	di in  gr "Variance matrix of the latent trait: " 
+	matrix list `matvar',noheader
+	di
+}
+di in gr "Number of items: " in ye `nbitems'
+di in green "Difficulties parameters of the items: "
+tempname dd
+matrix `dd'=`d''
+local items
+forvalues i=1/`nbitems' {
+   local items "`items' item`i'"
+}
+local modalities
+forvalues i=1/`=`nbmodat'-1' {
+   local modalities "`modalities' delta_`i'"
+}
+
+matrix colnames `dd'=`items'
+matrix rownames `dd'=`modalities'
+
+
+di
+tempname ddt
+matrix `ddt' = `dd''
+matrix colnames `ddt'=`modalities'
+matrix rownames `ddt'=`items'
+if "`html'" != "" {
+	matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficultés dans l'autre sens */
+}
+else {
+	matrix list `dd',noblank nohalf noheader
+}
+di
+
+if "`detail'"!="" & "`html'" == ""{
+	di in gr "Method:  " in ye "`method'"
+	di in gr "Number of studied response's patterns: " in ye `nbpatmax'
+}
+matrix `dd'=`d'
+local gamma=`gamma'
+
+local tmp=1
+qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
+forvalues j=1/`nbitems' {
+	forvalues m=1/`=`nbmodat'-1' {
+		qui matrix `db'[`tmp',1]=`d'[`j',`m']
+		local ++tmp
+	}
+}
+
+
+/*******************************************************************************
+CREATION DU DATASET ATTENDU 
+*******************************************************************************/
+
+if "`data'"=="" {
+	clear
+	if "`method'"!="POPULATION+GH"{
+		local temp=`nbmodat'^(`nbtotitems')
+		qui range x 0 `=`temp'-1' `temp'
+		qui g t=x
+		loc i=`nbtotitems'
+		qui count if t>0
+		loc z=r(N)
+		qui while `z'>0 {
+			qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
+			qui replace t=mod(t,`nbmodat'^`=`i'-1')
+			qui count if t>0
+			loc z=r(N)
+			loc i=`i'-1
+		}
+		drop t
+		if "`longitudinal'"==""{
+			qui expand 2
+			qui gen group=0 in 1/`temp'
+			qui replace group=1 in `=`temp'+1'/`=2*`temp''
+		}	
+	}
+	else { /*METHODE POPULATION (SIMULATION)*/
+		if "`longitudinal'"==""{
+			*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'*`gamma'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
+			qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
+			qui gen group=1
+			tempfile save1
+			qui save `save1',replace
+			qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
+			qui gen group=0
+			qui append using `save1'
+			*qui save d:\tmp,replace
+            bysort group:su lt
+			qui drop lt1
+			qui contract item* group, freq(freq)
+			qui count
+			local patobs=r(N)
+			if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
+				qui gen keep=0
+				qui gsort +group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+				qui gsort -group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n1''
+			}
+			else{
+				qui gen keep=1
+			}
+		}
+		else{
+			qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
+			forvalues j=1/`nbitems'{
+				rename itemA`j' item`j'
+				rename itemB`j' item`=`nbitems'+`j''
+			}
+			qui drop lt1 lt2
+			qui contract item*, freq(freq)
+			local patobs=r(N)
+			if `patobs'>=`=`n0'*`nbpatterns''{
+				qui gen keep=0
+				qui gsort -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+			}
+			else{
+			  qui gen keep=1
+			}
+		}
+		qui keep if keep==1
+		qui count
+		local retain=r(N)
+		di "Number of kept patterns:`retain'"
+		local method GH
+	}
+	if "`longitudinal'"==""{
+		qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
+		qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
+		qui gen var1=`var0' if group==0
+		qui replace var1=`var1' if group==1
+	}
+	else{
+		qui gen mean1=`mean1'
+		qui gen mean2=`mean2'
+	}
+	/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
+	if "`method'"=="GH" {
+		local temp=`nbmodat'^(`nbtotitems')
+		local diff0=0
+		qui gen proba=.
+		local dixj=10
+		qui count
+		local tmp=r(N)
+
+		forvalues i=1/`tmp' {
+			local dix=floor(`tmp'/10)
+			if mod(`i',`dix')==0 & "`html'"=="" {
+			    qui su proba
+				local tmpprob=r(sum)
+				if "`dixj'"!="10" {
+					di ".." _c
+				}
+				*di "`dixj'% (`tmpprob')" _c
+				di "`dixj'%" _c
+				local dixj=`dixj'+10
+			}
+			forvalues t=1/`nbt'{
+				local int`t'=1			 
+				forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+					qui su item`j' in `i'
+					local rep=r(mean)
+					local diff0=0
+					local diff1=`dlong'[`j',1]
+					local sum "1+exp(x`t'-`diff1')"
+					forvalues m=2/`=`nbmodat'-1' {
+					   local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+					   local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+					}
+					local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+				}
+			}	
+			if "`longitudinal'"==""{
+				qui su mean1 in `i'
+				local mean=r(mean)
+				qui su var1 in `i'
+				local vart=r(mean)
+				*di "gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
+				*prout
+				qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+				qui replace proba=r(int) in `i'
+			}
+			else{
+				local int "`int1'*`int2'"
+				matrix mean=(`mean1',`mean2')
+				qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
+				qui replace proba=r(int) in `i'
+			}
+		}
+		di
+	}
+	else { /*if "`method'"!="GH"*/
+		qui gen proba=1
+		forvalues t=1/`nbt'{
+			forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+				local diff0=0
+				local diff1=`dlong'[`i',1]
+				qui gen eps0=1
+				qui gen eps1=exp(mean`t'-`diff1')
+				qui gen d=eps0+eps1
+				forvalues m=2/`=`nbmodat'-1' {
+					local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
+					qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
+					qui replace d=d+eps`m'
+				}
+				local listeps
+				forvalues m=0/`=`nbmodat'-1' {
+					qui replace proba=proba*eps`m'/d if item`i'==`m'
+					local listeps `listeps' eps`m'
+				}
+				qui drop `listeps' d
+			}
+		}
+		if "`method'"=="MEAN+GH" {
+			set tracedepth 1
+			if "`longitudinal'"==""{
+				qui gen keep=0
+				qui gsort -group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui gsort +group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+				qui su proba if group==0
+				local sumproba0=r(sum)*100
+				qui su proba if group==1
+				local sumproba1=r(sum)*100
+			}
+			else{
+				qui gen keep=0
+				qui gsort -proba
+				local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+			}
+
+			qui drop keep proba
+			local diff0=0
+			qui gen proba=.
+			qui count
+			local nnew=r(N)
+			di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
+			if "`longitudinal'"==""{
+				di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
+			}
+			local dixj=10
+			forvalues i=1/`nnew' {
+				local dix=floor(`nnew'/10)
+				if mod(`i',`dix')==0 & "`html'"=="" {
+				    qui su proba
+					local sum=r(sum)
+					if "`dixj'"!="10" {
+						di ".." _c
+					}
+					di "`dixj'% (`sum')" _c
+					local dixj=`dixj'+10
+				}
+				forvalues t=1/`nbt'{
+					local int`t'=1
+					forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+						qui su item`j' in `i'
+						local rep=r(mean)
+						local diff0=0
+						local diff1=`dlong'[`j',1]
+						local sum "1+exp(x`t'-`diff1')"
+						forvalues m=2/`=`nbmodat'-1' {
+							local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+							local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+						}
+						local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+					}
+				}
+				if "`longitudinal'"==""{
+					qui su mean1 in `i'
+					local mean=r(mean)
+					qui su var1 in `i'
+					local vart=r(mean)
+					*di "qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
+					qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+					qui replace proba=r(int) in `i'
+				}
+				else{
+					local int "`int1'*`int2'"
+					matrix mean=(`mean1',`mean2')
+					qui gausshermite `int',mu(mean) var(`matvar') display
+					qui replace proba=r(int) in `i'
+				}
+			}
+		}
+	}
+	qui gen eff=proba
+	qui gen eff2=.  
+   
+	if "`longitudinal'"==""{
+		qui keep item* eff* group proba
+		local p1=1/`n1'
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p1') if group==1
+		qui replace eff2=floor(eff/`p0') if group==0
+		qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
+		qui su eff2 if group==1
+		local aff1=r(sum)
+		qui su eff2 if group==0
+		local aff0=r(sum)
+
+		local unaff1=`n1'-`aff1'
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort + group - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+		qui gsort - group - eff
+		qui replace eff2=eff2+1 in 1/`unaff1'
+
+		qui drop if eff2==0
+		qui gsort group item*
+		qui expand eff2
+	}
+	else{
+		qui keep item* eff* proba
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p0')
+		qui replace eff=eff-eff2*`p0'
+		qui su eff2
+		local aff0=r(sum)
+
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+
+		qui drop if eff2==0
+		qui gsort item*
+		qui expand eff2
+	}
+   qui drop proba eff eff2
+}
+
+if "`html'" == "" {
+	qui save "d:\essai.dta", replace
+}
+qui alpha item*
+local alpha=r(alpha)
+
+if "`longitudinal'"==""{ /*TRANSVERSAL*/
+	qui gen groupc=-`n1'/(`n0'+`n1') if group==0
+	qui replace groupc=`n0'/(`n0'+`n1') if group==1
+	if `nbmodat'==2 {   /*DICHOTOMOUS CASE*/
+        if "`freeitems'"=="" {
+		      local offset "offset(offset)"
+			  local items
+        }
+        else {
+		      local offset
+		      local items "item1-item`nbitems'"
+        }
+		qui gen i=_n
+
+		tempname diff
+		matrix `diff'=`dd''
+
+		qui reshape long item, i(i)
+		qui rename item rep
+		qui rename _j item
+
+		qui gen  offset=0
+		forvalues i=1/`nbitems' {
+			qui replace offset=-`diff'[1,`i'] if item==`i'
+			qui gen item`i'=item==`i'
+			qui replace item`i'=-item`i'
+		}
+        if `var0'==`var1' { /*EQUAL VARIANCES*/
+	       *constraint 1 _cons=`=ln(`var')'
+		   *qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
+	       if  "`freevar'"=="" {
+		      constraint 1 _cons=`=sqrt(`var0')'
+		      local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
+		}
+		else {/*UNEQUAL VARIANCES*/
+		   tempvar G0 G1
+		   qui gen `G0'=group==0
+		   qui gen `G1'=group==1
+		   qui eq B0: `G0'
+		   qui eq B1: `G1'
+	       constraint 1 _cons=0
+	       if  "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
+			   constraint 2 `G0'=`=sqrt(`var0')'
+			   constraint 3 `G1'=`=sqrt(`var1')'
+		       constraint 1 _cons=`=sqrt(`var0')'
+		       local constvar "constraint(1 2 3)"
+		   }
+		   else { /*FREE UNEQUAL VARIANCES*/
+		       local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
+		}
+		tempname b V/*LONGITUDINAL*/
+		local row = 1
+	}
+	else { /*POLYTOMOUS CASE*/
+		matrix `db'=`db''
+		if "`freeitems'"=="" {
+		   local fi "fixed(`db') fixedmu"
+		   local row=1
+		}
+		else {
+		   local fi
+		   local row=(`nbmodat'-1)*`nbitems'+1
+		}
+	    if `var0'==`var1' {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvar(`var0')"
+		   }
+		   else {
+		       local fv 
+			   *noi pcm item*, `fi' covariates(groupc) 
+
+		   }
+		}
+		else {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvargroupc(`var')"
+		   }
+		   else {
+		       local fv "vargroupc"
+		   }
+        }
+	      *di "jk pcm item*, `fi' covariates(groupc) `fv'"
+		   	/********************************ESSAI 23 mai 2014*/
+			qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`n1')
+			qui gen group=1
+			tempfile save1
+			qui save `save1',replace
+			qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`n0')
+			qui gen group=0
+			qui append using `save1'
+			qui gen groupc=group-0.5
+			*di "ON A SIMULE"
+			**********************************FIN ESSAI 23 mai 2014*/
+
+		 qui pcmold item*, `fi' covariates(groupc) `fv'
+	}
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,`row']
+	local se=`V'[`row',`row']^.5
+}
+else{ /*LONGITUDINAL*/ 
+	qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,1]
+	local se=`V'[1,1]^.5
+	local n1=`n0'
+}
+local poweruni=1-normal(1.96-`gamma'/`se')
+
+if "`html'" == "" {
+	di
+	di
+}
+if "`detail'"!=""{
+	di in gr "{hline 91}"
+	di _col(60)  "Estimation with the "
+	di _col(50)  "Cramer-Rao bound" _col(75) "classical formula"
+	di in gr "{hline 91}"
+}
+
+if "`longitudinal'"==""{
+	local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
+	local nbw:word count `var'
+	if `nbw' == 2 { /* variance commune */
+		local varc = ((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
+	}
+	else {
+		local varc = `var'
+	}
+	local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`varc'))-1.96)
+	local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`varc'))^2)*(1.96+invnorm(`poweruni'))^2
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the group effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+else{
+	local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
+	local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the time effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+
+if `expectedpower'!=-1 {
+   qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
+   local expn_1=r(N_1)
+   local expn_2=r(N_2)
+   local expn2=`expn_1'*`ratio'
+   di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _c
+   if "`detail'"!="" {
+      di _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
+   }
+}
+
+
+return scalar EstGamma=`gammaest'
+return scalar CRbound=`=`se'^2'
+return scalar CRPower=`poweruni'
+return scalar ClPower=`clpower'
+return scalar ClSS=`clnsn'
+return scalar Ratio=`ratio'
+return scalar CronbachAlpha=`alpha'
+
+
+if "`graph'" != "" {
+	local x = "`min'(`step')`max'"
+	matrix res=J(15,5,.)
+	matrix colnames res= n0 n1 gamma variance power
+	local l=1
+
+	if "`longitudinal'"==""{
+		forval var = `x' {
+			qui raschpower, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
+			qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
+			local ++l
+		}
+		clear
+		qui svmat res,names(col)
+		
+		if "`html'" != "" {
+			qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
+			qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving'
+			qui graph use `c(tmpdir)'/`html'_planif_graph.gph
+			qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
+			di "
" + di " _char(34) " + } + else { + if "`filesave'"!="" { + qui local saving "saving(`dirsave'//planif,replace) nodraw" + } + else { + qui local saving + } + twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving' + } + } + + else { + if `gcorr' != -1 { + local l=1 + forval var = `x' { + local cov = `gcorr'*`var' + local matv "`var',`cov'" " \ `cov',`var'" + qui raschpower, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + if "`filesave'"!="" { + qui local saving "saving(`dirsave'//planif,replace) nodraw" + } + else { + qui local saving + } + twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving' + } + } + + if `gvar' != -1 { + matrix res=J(9,5,.) + matrix colnames res= n0 n1 gamma corr power + local l=1 + forvalues corr = `x' { + local cov = `corr'*`gvar' + local matv "`gvar',`cov'" " \ `cov',`gvar'" + qui raschpower, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation, margin(top)) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + if "`filesave'"!="" { + qui local saving "saving(`dirsave'//planif,replace) nodraw" + } + else { + qui local saving + } + twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) + } + } + } + +//di in gr "Method: " in ye "`method'" + + if "`html'" != "" { + di "
" + } +} + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschpower52.ado b/Modules/ado/personal/r/raschpower52.ado new file mode 100644 index 0000000..909ffae --- /dev/null +++ b/Modules/ado/personal/r/raschpower52.ado @@ -0,0 +1,692 @@ +*! version 5.2 : January 22th, 2014 +*! Jean-Benoit Hardouin, Myriam Blanchin +************************************************************************************************************ +* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals +* +* Version 1 : January 25, 2010 (Jean-Benoit Hardouin) +* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin) +* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin) +* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin) +* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections +* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results +* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method +* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design +* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option +* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items +* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups +* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups +* +* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* Myriam Blanchin, myriam.blanchin@univ-nantes.fr +* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health" +* Faculty of Pharmaceutical Sciences - University of Nantes - France +* http://www.sphere-nantes.org +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschpower52,rclass +syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail] +version 11 + +tempfile raschpowerfile +capture qui save "`raschpowerfile'",replace +tempname db d dlong matvar + +/******************************************************************************* +DEFINITION DES PARAMETRES +*******************************************************************************/ +if "`difficulties'"=="" { + matrix `d'=[-1\-0.5\0\0.5\1] +} +else { + matrix `d'=`difficulties' +} +local nbitems=rowsof(`d') +local nbmodat=colsof(`d')+1 + +if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/ + local nbt=1 + local nbtotitems=`nbitems' + local nbpatmax=2*`nbmodat'^`nbitems' + if "`var'"==""{ + local var=1 + } + else{ + capture confirm number `var' + if !_rc { + local var0=`var' + local var1=`var' + } + else{ + local nbw:word count `var' + local grp=1 + if `nbw'==2 { + local t1: word 1 of `var' + capture confirm number `t1' + if !_rc { + local t2: word 2 of `var' + capture confirm number `t2' + if !_rc { + local var0=`t1' + local var1=`t2' + local grp=2 + } + } + }on + if `nbw'!=2|`grp'==1 { + capture confirm matrix `var' + if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{ + matrix `matvar'=`var' + local var0=`matvar'[1,1] + local var1=`matvar'[1,1] + } + else{ + di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}" + error 198 + exit + } + } + } + } + matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/ + local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2) + + local sumd=0 + forvalues numit=1/`nbitems'{ + local sumd=`sumd'+`d'[`numit',1] + } + local sumd=`sumd'/`nbitems' + if `=abs(`sumd')'>=`=2*sqrt(`varc')'{ + di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}" + } + +} +else{ /*CAS LONGITUDINAL*/ + local nbt=2 + local nbtotitems=2*`nbitems' + local nbpatmax=`nbmodat'^(`nbitems'*2) + local n1=0 + local mean1=0 + local mean2=`mean1'+`gamma' + if "`var'"==""{ + matrix `matvar'=(1,0\0,1) + } + else{ + matrix `matvar'=`var' + capture confirm matrix `matvar' + if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{ + di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}" + error 198 + exit + } + } + matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.) + matrix `dlong'[1,1]=`d' + matrix `dlong'[`=`nbitems'+1',1]=`d' +} + +/******************************************************************************* +DEFINITION DE LA METHODE +*******************************************************************************/ + +if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{ + local method POPULATION+GH +} + +if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' { + di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses" + di in gr "is lesser than the number of pattern retained by the MEAN+GH method." + di in gr "The -method- option is replaced by GH." + local method GH +} +else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{ + di in red "The number of patterns is too high for the chosen method" + exit +} +else if "`method'"=="" { + if `nbpatmax'<2000 { + local method GH + } + else { + local method POPULATION+GH + } +} + +if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{ + di in red "Invalid method name" + exit +} + +/******************************************************************************* +AFFICHAGE DES PARAMETRES +*******************************************************************************/ + +if "`longitudinal'"==""{ + di in gr "Number of individuals in the first group: " in ye `n0' + di in gr "Number of individuals in the second group: " in ye `n1' + di in green "Group effect: " in ye `gamma' + di in gr "Variance of the latent trait in the first group: " in ye `var0' + di in gr "Variance of the latent trait in the second group: " in ye `var1' +} +else{ + di in gr "Number of individuals at each time: " in ye `n0' + di in green "Time effect: " in ye `gamma' + di in gr "Variance matrix of the latent trait: " + matrix list `matvar',noheader +} +di in gr "Number of items: " in ye `nbitems' +di in green "Difficulties parameters of the items: " +tempname dd +matrix `dd'=`d'' +local items +forvalues i=1/`nbitems' { + local items "`items' item`i'" +} +local modalities +forvalues i=1/`=`nbmodat'-1' { + local modalities "`modalities' delta_`i'" +} + +matrix colnames `dd'=`items' +matrix rownames `dd'=`modalities' +matrix list `dd',noblank nohalf noheader +if "`detail'"!=""{ + di in gr "Method: " in ye "`method'" + di in gr "Number of studied response's patterns: " in ye `nbpatmax' +} +matrix `dd'=`d' +local gamma=`gamma' + +local tmp=1 +qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.) +forvalues j=1/`nbitems' { + forvalues m=1/`=`nbmodat'-1' { + qui matrix `db'[`tmp',1]=`d'[`j',`m'] + local ++tmp + } +} + + +/******************************************************************************* +CREATION DU DATASET ATTENDU +*******************************************************************************/ + +if "`data'"=="" { + clear + if "`method'"!="POPULATION+GH"{ + local temp=`nbmodat'^(`nbtotitems') + qui range x 0 `=`temp'-1' `temp' + qui g t=x + loc i=`nbtotitems' + qui count if t>0 + loc z=r(N) + qui while `z'>0 { + qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1') + qui replace t=mod(t,`nbmodat'^`=`i'-1') + qui count if t>0 + loc z=r(N) + loc i=`i'-1 + } + drop t + if "`longitudinal'"==""{ + qui expand 2 + qui gen group=0 in 1/`temp' + qui replace group=1 in `=`temp'+1'/`=2*`temp'' + } + } + else { /*METHODE POPULATION (SIMULATION)*/ + if "`longitudinal'"==""{ + *qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000) + qui simirt, clear pcm(`d') cov(`var1') mean(`=`n0'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)') + qui gen group=1 + tempfile save1 + qui save `save1',replace + qui simirt, clear pcm(`d') cov(`var0') mean(`=-`n1'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)') + qui gen group=0 + qui append usinf `save1' + qui drop lt1 + qui contract item* group, freq(freq) + qui count + local patobs=r(N) + if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{ + qui gen keep=0 + qui gsort +group -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n0'' + qui gsort -group -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n1'' + } + else{ + qui gen keep=1 + } + } + else{ + qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000) + forvalues j=1/`nbitems'{ + rename itemA`j' item`j' + rename itemB`j' item`=`nbitems'+`j'' + } + qui drop lt1 lt2 + qui contract item*, freq(freq) + local patobs=r(N) + if `patobs'>=`=`n0'*`nbpatterns''{ + qui gen keep=0 + qui gsort -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n0'' + } + else{ + qui gen keep=1 + } + } + qui keep if keep==1 + qui count + local retain=r(N) + di "Number of kept patterns:`retain'" + local method GH + } + if "`longitudinal'"==""{ + qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0 + qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1 + qui gen var1=`var0' if group==0 + qui replace var1=`var1' if group==1 + } + else{ + qui gen mean1=`mean1' + qui gen mean2=`mean2' + } + /*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/ + if "`method'"=="GH" { + local temp=`nbmodat'^(`nbtotitems') + local diff0=0 + qui gen proba=. + local dixj=10 + qui count + local tmp=r(N) + + forvalues i=1/`tmp' { + local dix=floor(`tmp'/10) + if mod(`i',`dix')==0 { + if "`dixj'"!="10" { + di ".." _c + } + di "`dixj'%" _c + local dixj=`dixj'+10 + } + forvalues t=1/`nbt'{ + local int`t'=1 + forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + qui su item`j' in `i' + local rep=r(mean) + local diff0=0 + local diff1=`dlong'[`j',1] + local sum "1+exp(x`t'-`diff1')" + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m'] + local sum "`sum'+exp(`m'*x`t'-`diff`m'')" + } + local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')" + } + } + if "`longitudinal'"==""{ + qui su mean1 in `i' + local mean=r(mean) + qui su var1 in `i' + local vart=r(mean) + qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1) + qui replace proba=r(int) in `i' + } + else{ + local int "`int1'*`int2'" + matrix mean=(`mean1',`mean2') + qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2) + qui replace proba=r(int) in `i' + } + } + di + } + else { + qui gen proba=1 + forvalues t=1/`nbt'{ + forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + local diff0=0 + local diff1=`dlong'[`i',1] + qui gen eps0=1 + qui gen eps1=exp(mean`t'-`diff1') + qui gen d=eps0+eps1 + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m'] + qui gen eps`m'=exp(`m'*mean`t'-`diff`m'') + qui replace d=d+eps`m' + } + local listeps + forvalues m=0/`=`nbmodat'-1' { + qui replace proba=proba*eps`m'/d if item`i'==`m' + local listeps `listeps' eps`m' + } + qui drop `listeps' d + } + } + if "`method'"=="MEAN+GH" { + set tracedepth 1 + if "`longitudinal'"==""{ + qui gen keep=0 + qui gsort -group -proba + local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui gsort +group -proba + local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui keep if keep==1 + qui su proba if group==0 + local sumproba0=r(sum)*100 + qui su proba if group==1 + local sumproba1=r(sum)*100 + } + else{ + qui gen keep=0 + qui gsort -proba + local min=min(`nbpatmax',`=`n0'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui keep if keep==1 + } + + qui drop keep proba + local diff0=0 + qui gen proba=. + qui count + local nnew=r(N) + di in gr "Number of studied response's patterns for the GH step: " in ye `nnew' + if "`longitudinal'"==""{ + di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)" + } + local dixj=10 + forvalues i=1/`nnew' { + local dix=floor(`nnew'/10) + if mod(`i',`dix')==0 { + if "`dixj'"!="10" { + di ".." _c + } + di "`dixj'%" _c + local dixj=`dixj'+10 + } + forvalues t=1/`nbt'{ + local int`t'=1 + forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + qui su item`j' in `i' + local rep=r(mean) + local diff0=0 + local diff1=`dlong'[`j',1] + local sum "1+exp(x`t'-`diff1')" + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m'] + local sum "`sum'+exp(`m'*x`t'-`diff`m'')" + } + local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')" + } + } + if "`longitudinal'"==""{ + qui su mean1 in `i' + local mean=r(mean) + qui su var1 in `i' + local vart=r(mean) + qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1) + qui replace proba=r(int) in `i' + } + else{ + local int "`int1'*`int2'" + matrix mean=(`mean1',`mean2') + qui gausshermite `int',mu(mean) var(`matvar') display + qui replace proba=r(int) in `i' + } + } + } + } + qui gen eff=proba + qui gen eff2=. + + if "`longitudinal'"==""{ + qui keep item* eff* group proba + local p1=1/`n1' + local p0=1/`n0' + qui replace eff2=floor(eff/`p1') if group==1 + qui replace eff2=floor(eff/`p0') if group==0 + qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group)) + qui su eff2 if group==1 + local aff1=r(sum) + qui su eff2 if group==0 + local aff0=r(sum) + + local unaff1=`n1'-`aff1' + local unaff0=`n0'-`aff0' + qui gen efftmp=eff2 + qui gsort + group - eff + qui replace eff2=eff2+1 in 1/`unaff0' + qui gsort - group - eff + qui replace eff2=eff2+1 in 1/`unaff1' + + qui drop if eff2==0 + gsort group item* + qui expand eff2 + } + else{ + qui keep item* eff* proba + local p0=1/`n0' + qui replace eff2=floor(eff/`p0') + qui replace eff=eff-eff2*`p0' + qui su eff2 + local aff0=r(sum) + + local unaff0=`n0'-`aff0' + qui gen efftmp=eff2 + qui gsort - eff + qui replace eff2=eff2+1 in 1/`unaff0' + + qui drop if eff2==0 + gsort item* + qui expand eff2 + } + qui drop proba eff eff2 +} + +qui alpha item* +local alpha=r(alpha) + +if "`longitudinal'"==""{ /*TRANSVERSAL*/ + qui gen groupc=-`n1'/(`n0'+`n1') if group==0 + qui replace groupc=`n0'/(`n0'+`n1') if group==1 + if `nbmodat'==2 { /*DICHOTOMOUS CASE*/ + if "`freeitems'"=="" { + local offset "offset(offset)" + local items + } + else { + local offset + local items "item1-item`nbitems'" + } + qui gen i=_n + + tempname diff + matrix `diff'=`dd'' + + qui reshape long item, i(i) + qui rename item rep + qui rename _j item + + qui gen offset=0 + forvalues i=1/`nbitems' { + qui replace offset=-`diff'[1,`i'] if item==`i' + qui gen item`i'=item==`i' + qui replace item`i'=-item`i' + } + if `var0'==`var1' { /*EQUAL VARIANCES*/ + *constraint 1 _cons=`=ln(`var')' + *qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1) + if "`freevar'"=="" { + constraint 1 _cons=`=sqrt(`var0')' + local constvar "constraint(1)" + } + gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace + } + else {/*UNEQUAL VARIANCES*/ + tempvar G0 G1 + qui gen `G0'=group==0 + qui gen `G1'=group==1 + qui eq B0: `G0' + qui eq B1: `G1' + constraint 1 _cons=0 + if "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/ + constraint 2 `G0'=`=sqrt(`var0')' + constraint 3 `G1'=`=sqrt(`var1')' + constraint 1 _cons=`=sqrt(`var0')' + local constvar "constraint(1 2 3)" + } + else { /*FREE UNEQUAL VARIANCES*/ + local constvar "constraint(1)" + } + qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace + } + tempname b V/*LONGITUDINAL*/ + } + else { /*POLYTOMOUS CASE*/ + matrix `db'=`db'' + if `var0'==`var1' { + if "`freevar'"=="" { + local fv "fixedvar(`var0')" + } + else { + local fv + } + } + else { + if "`freevar'"=="" { + local fv "fixedvargroupc(`var')" + } + else { + local fv "vargroupc" + } + } + if "`freeitems'"=="" { + local fi "fixed(`db') fixedmu" + local row=1 + } + else { + local fi + local row=(`nbmodat'-1)*`nbitems'+1 + } + *di "pcm item*, `fi' covariates(groupc) `fv'" + qui pcm item*, `fi' covariates(groupc) `fv' + } + tempname b V + matrix `b'=e(b) + matrix `V'=e(V) + local gammaest=`b'[1,`row'] + local se=`V'[`row',`row']^.5 +} +else{ + qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar') + tempname b V + matrix `b'=e(b) + matrix `V'=e(V) + local gammaest=`b'[1,1] + local se=`V'[1,1]^.5 + local n1=`n0' +} +local poweruni=1-normal(1.96-`gamma'/`se') + + + di + di + if "`detail'"!=""{ + di in gr "{hline 91}" + di _col(60) "Estimation with the " + di _col(50) "Cramer-Rao bound" _col(75) "classical formula" + di in gr "{hline 91}" + } + + if "`longitudinal'"==""{ + local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se') + local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96) + local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2 + local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0')) + if "`detail'"==""{ + di in gr "{hline 65}" + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' + di in gr "{hline 65}" + } + else{ + if "`gammafixed'"=="" { + di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest' + } + di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se' + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower' + di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0'' + di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio' + di in gr "{hline 91}" + } + } + else{ + local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96) + local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2) + local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0')) + if "`detail'"==""{ + di in gr "{hline 65}" + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' + di in gr "{hline 65}" + } + else{ + if "`gammafixed'"=="" { + di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest' + } + di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se' + di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower' + di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn' + di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio' + di in gr "{hline 91}" + } + } + + if `expectedpower'!=-1 { + qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'') + local expn_1=r(N_1) + local expn_2=r(N_2) + local expn2=`expn_1'*`ratio' + di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2' + } + + return scalar EstGamma=`gammaest' + return scalar CRbound=`=`se'^2' + return scalar CRPower=`poweruni' + return scalar ClPower=`clpower' + return scalar ClSS=`clnsn' + return scalar Ratio=`ratio' + return scalar CronbachAlpha=`alpha' + + + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschpower53.ado b/Modules/ado/personal/r/raschpower53.ado new file mode 100644 index 0000000..d1e81f2 --- /dev/null +++ b/Modules/ado/personal/r/raschpower53.ado @@ -0,0 +1,695 @@ +*! version 5.3 : January 29th, 2014 +*! Jean-Benoit Hardouin, Myriam Blanchin +************************************************************************************************************ +* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals +* +* Version 1 : January 25, 2010 (Jean-Benoit Hardouin) +* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin) +* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin) +* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin) +* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections +* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results +* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method +* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design +* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option +* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items +* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups +* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups +* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug +* +* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* Myriam Blanchin, myriam.blanchin@univ-nantes.fr +* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health" +* Faculty of Pharmaceutical Sciences - University of Nantes - France +* http://www.sphere-nantes.org +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschpower53,rclass +syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail] +version 11 + +tempfile raschpowerfile +capture qui save "`raschpowerfile'",replace +tempname db d dlong matvar + +/******************************************************************************* +DEFINITION DES PARAMETRES +*******************************************************************************/ +if "`difficulties'"=="" { + matrix `d'=[-1\-0.5\0\0.5\1] +} +else { + matrix `d'=`difficulties' +} +local nbitems=rowsof(`d') +local nbmodat=colsof(`d')+1 + +if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/ + local nbt=1 + local nbtotitems=`nbitems' + local nbpatmax=2*`nbmodat'^`nbitems' + if "`var'"==""{ + local var=1 + local var0=1 + local var1=1 + } + else{ + capture confirm number `var' + if !_rc { + local var0=`var' + local var1=`var' + } + else{ + local nbw:word count `var' + local grp=1 + if `nbw'==2 { + local t1: word 1 of `var' + capture confirm number `t1' + if !_rc { + local t2: word 2 of `var' + capture confirm number `t2' + if !_rc { + local var0=`t1' + local var1=`t2' + local grp=2 + } + } + } + if `nbw'!=2|`grp'==1 { + capture confirm matrix `var' + if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{ + matrix `matvar'=`var' + local var0=`matvar'[1,1] + local var1=`matvar'[1,1] + } + else{ + di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}" + error 198 + exit + } + } + } + } + matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/ + local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2) + + local sumd=0 + forvalues numit=1/`nbitems'{ + local sumd=`sumd'+`d'[`numit',1] + } + local sumd=`sumd'/`nbitems' + if `=abs(`sumd')'>=`=2*sqrt(`varc')'{ + di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}" + } + +} +else{ /*CAS LONGITUDINAL*/ + local nbt=2 + local nbtotitems=2*`nbitems' + local nbpatmax=`nbmodat'^(`nbitems'*2) + local n1=0 + local mean1=0 + local mean2=`mean1'+`gamma' + if "`var'"==""{ + matrix `matvar'=(1,0\0,1) + } + else{ + matrix `matvar'=`var' + capture confirm matrix `matvar' + if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{ + di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}" + error 198 + exit + } + } + matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.) + matrix `dlong'[1,1]=`d' + matrix `dlong'[`=`nbitems'+1',1]=`d' +} + +/******************************************************************************* +DEFINITION DE LA METHODE +*******************************************************************************/ + +if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{ + local method POPULATION+GH +} + +if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' { + di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses" + di in gr "is lesser than the number of pattern retained by the MEAN+GH method." + di in gr "The -method- option is replaced by GH." + local method GH +} +else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{ + di in red "The number of patterns is too high for the chosen method" + exit +} +else if "`method'"=="" { + if `nbpatmax'<2000 { + local method GH + } + else { + local method POPULATION+GH + } +} + +if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{ + di in red "Invalid method name" + exit +} + +/******************************************************************************* +AFFICHAGE DES PARAMETRES +*******************************************************************************/ + +if "`longitudinal'"==""{ + di in gr "Number of individuals in the first group: " in ye `n0' + di in gr "Number of individuals in the second group: " in ye `n1' + di in green "Group effect: " in ye `gamma' + di in gr "Variance of the latent trait in the first group: " in ye `var0' + di in gr "Variance of the latent trait in the second group: " in ye `var1' +} +else{ + di in gr "Number of individuals at each time: " in ye `n0' + di in green "Time effect: " in ye `gamma' + di in gr "Variance matrix of the latent trait: " + matrix list `matvar',noheader +} +di in gr "Number of items: " in ye `nbitems' +di in green "Difficulties parameters of the items: " +tempname dd +matrix `dd'=`d'' +local items +forvalues i=1/`nbitems' { + local items "`items' item`i'" +} +local modalities +forvalues i=1/`=`nbmodat'-1' { + local modalities "`modalities' delta_`i'" +} + +matrix colnames `dd'=`items' +matrix rownames `dd'=`modalities' +matrix list `dd',noblank nohalf noheader +if "`detail'"!=""{ + di in gr "Method: " in ye "`method'" + di in gr "Number of studied response's patterns: " in ye `nbpatmax' +} +matrix `dd'=`d' +local gamma=`gamma' + +local tmp=1 +qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.) +forvalues j=1/`nbitems' { + forvalues m=1/`=`nbmodat'-1' { + qui matrix `db'[`tmp',1]=`d'[`j',`m'] + local ++tmp + } +} + + +/******************************************************************************* +CREATION DU DATASET ATTENDU +*******************************************************************************/ + +if "`data'"=="" { + clear + if "`method'"!="POPULATION+GH"{ + local temp=`nbmodat'^(`nbtotitems') + qui range x 0 `=`temp'-1' `temp' + qui g t=x + loc i=`nbtotitems' + qui count if t>0 + loc z=r(N) + qui while `z'>0 { + qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1') + qui replace t=mod(t,`nbmodat'^`=`i'-1') + qui count if t>0 + loc z=r(N) + loc i=`i'-1 + } + drop t + if "`longitudinal'"==""{ + qui expand 2 + qui gen group=0 in 1/`temp' + qui replace group=1 in `=`temp'+1'/`=2*`temp'' + } + } + else { /*METHODE POPULATION (SIMULATION)*/ + if "`longitudinal'"==""{ + *qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000) + qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)') + qui gen group=1 + tempfile save1 + qui save `save1',replace + qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)') + qui gen group=0 + qui append using `save1' + qui drop lt1 + qui contract item* group, freq(freq) + qui count + local patobs=r(N) + if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{ + qui gen keep=0 + qui gsort +group -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n0'' + qui gsort -group -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n1'' + } + else{ + qui gen keep=1 + } + } + else{ + qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000) + forvalues j=1/`nbitems'{ + rename itemA`j' item`j' + rename itemB`j' item`=`nbitems'+`j'' + } + qui drop lt1 lt2 + qui contract item*, freq(freq) + local patobs=r(N) + if `patobs'>=`=`n0'*`nbpatterns''{ + qui gen keep=0 + qui gsort -freq + qui replace keep=1 in 1/`=`nbpatterns'*`n0'' + } + else{ + qui gen keep=1 + } + } + qui keep if keep==1 + qui count + local retain=r(N) + di "Number of kept patterns:`retain'" + local method GH + } + if "`longitudinal'"==""{ + qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0 + qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1 + qui gen var1=`var0' if group==0 + qui replace var1=`var1' if group==1 + } + else{ + qui gen mean1=`mean1' + qui gen mean2=`mean2' + } + /*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/ + if "`method'"=="GH" { + local temp=`nbmodat'^(`nbtotitems') + local diff0=0 + qui gen proba=. + local dixj=10 + qui count + local tmp=r(N) + + forvalues i=1/`tmp' { + local dix=floor(`tmp'/10) + if mod(`i',`dix')==0 { + if "`dixj'"!="10" { + di ".." _c + } + di "`dixj'%" _c + local dixj=`dixj'+10 + } + forvalues t=1/`nbt'{ + local int`t'=1 + forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + qui su item`j' in `i' + local rep=r(mean) + local diff0=0 + local diff1=`dlong'[`j',1] + local sum "1+exp(x`t'-`diff1')" + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m'] + local sum "`sum'+exp(`m'*x`t'-`diff`m'')" + } + local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')" + } + } + if "`longitudinal'"==""{ + qui su mean1 in `i' + local mean=r(mean) + qui su var1 in `i' + local vart=r(mean) + qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1) + qui replace proba=r(int) in `i' + } + else{ + local int "`int1'*`int2'" + matrix mean=(`mean1',`mean2') + qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2) + qui replace proba=r(int) in `i' + } + } + di + } + else { + qui gen proba=1 + forvalues t=1/`nbt'{ + forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + local diff0=0 + local diff1=`dlong'[`i',1] + qui gen eps0=1 + qui gen eps1=exp(mean`t'-`diff1') + qui gen d=eps0+eps1 + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m'] + qui gen eps`m'=exp(`m'*mean`t'-`diff`m'') + qui replace d=d+eps`m' + } + local listeps + forvalues m=0/`=`nbmodat'-1' { + qui replace proba=proba*eps`m'/d if item`i'==`m' + local listeps `listeps' eps`m' + } + qui drop `listeps' d + } + } + if "`method'"=="MEAN+GH" { + set tracedepth 1 + if "`longitudinal'"==""{ + qui gen keep=0 + qui gsort -group -proba + local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui gsort +group -proba + local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui keep if keep==1 + qui su proba if group==0 + local sumproba0=r(sum)*100 + qui su proba if group==1 + local sumproba1=r(sum)*100 + } + else{ + qui gen keep=0 + qui gsort -proba + local min=min(`nbpatmax',`=`n0'*`nbpatterns'') + qui replace keep=1 in 1/`min' + qui keep if keep==1 + } + + qui drop keep proba + local diff0=0 + qui gen proba=. + qui count + local nnew=r(N) + di in gr "Number of studied response's patterns for the GH step: " in ye `nnew' + if "`longitudinal'"==""{ + di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)" + } + local dixj=10 + forvalues i=1/`nnew' { + local dix=floor(`nnew'/10) + if mod(`i',`dix')==0 { + if "`dixj'"!="10" { + di ".." _c + } + di "`dixj'%" _c + local dixj=`dixj'+10 + } + forvalues t=1/`nbt'{ + local int`t'=1 + forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' { + qui su item`j' in `i' + local rep=r(mean) + local diff0=0 + local diff1=`dlong'[`j',1] + local sum "1+exp(x`t'-`diff1')" + forvalues m=2/`=`nbmodat'-1' { + local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m'] + local sum "`sum'+exp(`m'*x`t'-`diff`m'')" + } + local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')" + } + } + if "`longitudinal'"==""{ + qui su mean1 in `i' + local mean=r(mean) + qui su var1 in `i' + local vart=r(mean) + qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1) + qui replace proba=r(int) in `i' + } + else{ + local int "`int1'*`int2'" + matrix mean=(`mean1',`mean2') + qui gausshermite `int',mu(mean) var(`matvar') display + qui replace proba=r(int) in `i' + } + } + } + } + qui gen eff=proba + qui gen eff2=. + + if "`longitudinal'"==""{ + qui keep item* eff* group proba + local p1=1/`n1' + local p0=1/`n0' + qui replace eff2=floor(eff/`p1') if group==1 + qui replace eff2=floor(eff/`p0') if group==0 + qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group)) + qui su eff2 if group==1 + local aff1=r(sum) + qui su eff2 if group==0 + local aff0=r(sum) + + local unaff1=`n1'-`aff1' + local unaff0=`n0'-`aff0' + qui gen efftmp=eff2 + qui gsort + group - eff + qui replace eff2=eff2+1 in 1/`unaff0' + qui gsort - group - eff + qui replace eff2=eff2+1 in 1/`unaff1' + + qui drop if eff2==0 + gsort group item* + qui expand eff2 + } + else{ + qui keep item* eff* proba + local p0=1/`n0' + qui replace eff2=floor(eff/`p0') + qui replace eff=eff-eff2*`p0' + qui su eff2 + local aff0=r(sum) + + local unaff0=`n0'-`aff0' + qui gen efftmp=eff2 + qui gsort - eff + qui replace eff2=eff2+1 in 1/`unaff0' + + qui drop if eff2==0 + gsort item* + qui expand eff2 + } + qui drop proba eff eff2 +} + +qui alpha item* +local alpha=r(alpha) + +if "`longitudinal'"==""{ /*TRANSVERSAL*/ + qui gen groupc=-`n1'/(`n0'+`n1') if group==0 + qui replace groupc=`n0'/(`n0'+`n1') if group==1 + if `nbmodat'==2 { /*DICHOTOMOUS CASE*/ + if "`freeitems'"=="" { + local offset "offset(offset)" + local items + } + else { + local offset + local items "item1-item`nbitems'" + } + qui gen i=_n + + tempname diff + matrix `diff'=`dd'' + + qui reshape long item, i(i) + qui rename item rep + qui rename _j item + + qui gen offset=0 + forvalues i=1/`nbitems' { + qui replace offset=-`diff'[1,`i'] if item==`i' + qui gen item`i'=item==`i' + qui replace item`i'=-item`i' + } + if `var0'==`var1' { /*EQUAL VARIANCES*/ + *constraint 1 _cons=`=ln(`var')' + *qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1) + if "`freevar'"=="" { + constraint 1 _cons=`=sqrt(`var0')' + local constvar "constraint(1)" + } + qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100) + } + else {/*UNEQUAL VARIANCES*/ + tempvar G0 G1 + qui gen `G0'=group==0 + qui gen `G1'=group==1 + qui eq B0: `G0' + qui eq B1: `G1' + constraint 1 _cons=0 + if "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/ + constraint 2 `G0'=`=sqrt(`var0')' + constraint 3 `G1'=`=sqrt(`var1')' + constraint 1 _cons=`=sqrt(`var0')' + local constvar "constraint(1 2 3)" + } + else { /*FREE UNEQUAL VARIANCES*/ + local constvar "constraint(1)" + } + qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100) + } + tempname b V/*LONGITUDINAL*/ + } + else { /*POLYTOMOUS CASE*/ + matrix `db'=`db'' + if `var0'==`var1' { + if "`freevar'"=="" { + local fv "fixedvar(`var0')" + } + else { + local fv + } + } + else { + if "`freevar'"=="" { + local fv "fixedvargroupc(`var')" + } + else { + local fv "vargroupc" + } + } + if "`freeitems'"=="" { + local fi "fixed(`db') fixedmu" + local row=1 + } + else { + local fi + local row=(`nbmodat'-1)*`nbitems'+1 + } + di "pcm item*, `fi' covariates(groupc) `fv'" + noi pcm item*, `fi' covariates(groupc) `fv' + } + tempname b V + matrix `b'=e(b) + matrix `V'=e(V) + local gammaest=`b'[1,`row'] + local se=`V'[`row',`row']^.5 +} +else{ + qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar') + tempname b V + matrix `b'=e(b) + matrix `V'=e(V) + local gammaest=`b'[1,1] + local se=`V'[1,1]^.5 + local n1=`n0' +} +local poweruni=1-normal(1.96-`gamma'/`se') + + + di + di + if "`detail'"!=""{ + di in gr "{hline 91}" + di _col(60) "Estimation with the " + di _col(50) "Cramer-Rao bound" _col(75) "classical formula" + di in gr "{hline 91}" + } + + if "`longitudinal'"==""{ + local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se') + local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96) + local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2 + local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0')) + if "`detail'"==""{ + di in gr "{hline 65}" + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' + di in gr "{hline 65}" + } + else{ + if "`gammafixed'"=="" { + di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest' + } + di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se' + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower' + di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0'' + di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio' + di in gr "{hline 91}" + } + } + else{ + local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96) + local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2) + local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0')) + if "`detail'"==""{ + di in gr "{hline 65}" + di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' + di in gr "{hline 65}" + } + else{ + if "`gammafixed'"=="" { + di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest' + } + di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se' + di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2' + di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower' + di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn' + di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio' + di in gr "{hline 91}" + } + } + + if `expectedpower'!=-1 { + qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'') + local expn_1=r(N_1) + local expn_2=r(N_2) + local expn2=`expn_1'*`ratio' + di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2' + } + + return scalar EstGamma=`gammaest' + return scalar CRbound=`=`se'^2' + return scalar CRPower=`poweruni' + return scalar ClPower=`clpower' + return scalar ClSS=`clnsn' + return scalar Ratio=`ratio' + return scalar CronbachAlpha=`alpha' + + + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschpower54.ado b/Modules/ado/personal/r/raschpower54.ado new file mode 100644 index 0000000..df91b8d --- /dev/null +++ b/Modules/ado/personal/r/raschpower54.ado @@ -0,0 +1,820 @@ +*! version 5.4 : March 28th, 2014 +*! Jean-Benoit Hardouin, Myriam Blanchin +************************************************************************************************************ +* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals +* +* Version 1 : January 25, 2010 (Jean-Benoit Hardouin) +* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin) +* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin) +* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin) +* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections +* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results +* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method +* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design +* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option +* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items +* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups +* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups +* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug +* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display +* +* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* Myriam Blanchin, myriam.blanchin@univ-nantes.fr +* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health" +* Faculty of Pharmaceutical Sciences - University of Nantes - France +* http://www.sphere-nantes.org +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschpower54,rclass +syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1)] +version 11 + +if "`html'" != "" { + di "" + di "
"
+}
+
+tempfile raschpowerfile
+capture qui save "`raschpowerfile'",replace
+tempname db d dlong matvar
+
+/*******************************************************************************
+DEFINITION DES PARAMETRES
+*******************************************************************************/
+
+if "`graph'" != "" {
+	if `gvar' != -1 & `gcorr' != -1 {
+		di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
+		error 198
+	}
+	if `gvar' == -1 & `gcorr' == -1 {
+		di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
+		error 198
+	}
+}
+
+if "`difficulties'"=="" {
+   matrix `d'=[-1\-0.5\0\0.5\1]
+}
+else {
+   matrix `d'=`difficulties'
+}
+local nbitems=rowsof(`d')
+local nbmodat=colsof(`d')+1
+
+if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
+	local nbt=1
+	local nbtotitems=`nbitems'
+	local nbpatmax=2*`nbmodat'^`nbitems'
+	if "`var'"==""{
+		local var=1
+		local var0=1
+		local var1=1
+	}
+	else{
+		capture confirm number `var'
+		if !_rc {
+			local var0=`var'
+			local var1=`var'
+		}
+		else{
+		   local nbw:word count `var'
+		   local grp=1
+		   if `nbw'==2 {
+				local t1: word 1 of `var'
+                capture confirm number `t1'
+				if !_rc {
+					local t2: word 2 of `var'
+                    capture confirm number `t2'
+                    if !_rc {
+                       local var0=`t1'
+                       local var1=`t2'
+                       local grp=2
+                    }
+				}
+			}
+			if `nbw'!=2|`grp'==1 {
+				capture confirm matrix `var'
+			    if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
+				    matrix `matvar'=`var'
+					local var0=`matvar'[1,1]
+					local var1=`matvar'[1,1]
+			    }
+			    else{
+					di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
+					error 198
+					exit
+			    }
+		    }
+		}
+	}
+	matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
+    local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
+
+	local sumd=0
+	forvalues numit=1/`nbitems'{
+		local sumd=`sumd'+`d'[`numit',1]
+	}
+	local sumd=`sumd'/`nbitems'
+	if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
+		if "`html'" == "" {
+			di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
+		}
+	}
+
+}
+else{ /*CAS LONGITUDINAL*/
+	local nbt=2
+	local nbtotitems=2*`nbitems'
+	local nbpatmax=`nbmodat'^(`nbitems'*2)
+	local n1=0
+	local mean1=0
+	local mean2=`mean1'+`gamma'
+	if "`var'"==""{
+		matrix `matvar'=(1,0\0,1)
+	}
+	else{
+		matrix `matvar'=`var'
+		capture confirm matrix `matvar'
+		if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
+			di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
+			error 198
+			exit
+		}
+	}
+	matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
+	matrix `dlong'[1,1]=`d'
+	matrix `dlong'[`=`nbitems'+1',1]=`d'
+}
+
+/*******************************************************************************
+DEFINITION DE LA METHODE
+*******************************************************************************/
+
+if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
+	local method POPULATION+GH
+}
+
+if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
+   di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
+   di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
+   di in gr "The -method- option is replaced by GH."
+   local method GH
+}
+else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
+	di in red "The number of patterns is too high for the chosen method"
+	exit
+}
+else if "`method'"=="" {
+    if `nbpatmax'<2000 {
+        local method GH
+    }
+    else  {
+        local method POPULATION+GH
+    }
+}
+
+if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
+	di in red "Invalid method name"
+	exit
+}
+
+/*******************************************************************************
+AFFICHAGE DES PARAMETRES
+*******************************************************************************/
+
+if "`longitudinal'"==""{
+	di in gr "Number of individuals in the first group: " in ye `n0'
+	di in gr "Number of individuals in the second group: " in ye `n1'
+	di in green "Group effect: " in ye `gamma'
+	di in  gr "Variance of the latent trait in the first group: " in ye `var0'
+	di in  gr "Variance of the latent trait in the second group: " in ye `var1'
+}
+else{
+	di in gr "Number of individuals at each time:  " in ye `n0'
+	di in green "Time effect: " in ye `gamma'
+	di in  gr "Variance matrix of the latent trait: " 
+	matrix list `matvar',noheader
+}
+di in gr "Number of items: " in ye `nbitems'
+di in green "Difficulties parameters of the items: "
+tempname dd
+matrix `dd'=`d''
+local items
+forvalues i=1/`nbitems' {
+   local items "`items' item`i'"
+}
+local modalities
+forvalues i=1/`=`nbmodat'-1' {
+   local modalities "`modalities' delta_`i'"
+}
+
+matrix colnames `dd'=`items'
+matrix rownames `dd'=`modalities'
+
+
+di
+tempname ddt
+matrix `ddt' = `dd''
+matrix colnames `ddt'=`modalities'
+matrix rownames `ddt'=`items'
+if "`html'" != "" {
+	matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficultés dans l'autre sens */
+}
+else {
+	matrix list `dd',noblank nohalf noheader
+}
+di
+
+if "`detail'"!="" & "`html'" == ""{
+	di in gr "Method:  " in ye "`method'"
+	di in gr "Number of studied response's patterns: " in ye `nbpatmax'
+}
+matrix `dd'=`d'
+local gamma=`gamma'
+
+local tmp=1
+qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
+forvalues j=1/`nbitems' {
+	forvalues m=1/`=`nbmodat'-1' {
+		qui matrix `db'[`tmp',1]=`d'[`j',`m']
+		local ++tmp
+	}
+}
+
+
+/*******************************************************************************
+CREATION DU DATASET ATTENDU 
+*******************************************************************************/
+
+if "`data'"=="" {
+	clear
+	if "`method'"!="POPULATION+GH"{
+		local temp=`nbmodat'^(`nbtotitems')
+		qui range x 0 `=`temp'-1' `temp'
+		qui g t=x
+		loc i=`nbtotitems'
+		qui count if t>0
+		loc z=r(N)
+		qui while `z'>0 {
+			qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
+			qui replace t=mod(t,`nbmodat'^`=`i'-1')
+			qui count if t>0
+			loc z=r(N)
+			loc i=`i'-1
+		}
+		drop t
+		if "`longitudinal'"==""{
+			qui expand 2
+			qui gen group=0 in 1/`temp'
+			qui replace group=1 in `=`temp'+1'/`=2*`temp''
+		}	
+	}
+	else { /*METHODE POPULATION (SIMULATION)*/
+		if "`longitudinal'"==""{
+			*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
+			qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
+			qui gen group=1
+			tempfile save1
+			qui save `save1',replace
+			qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
+			qui gen group=0
+			qui append using `save1'
+			qui drop lt1
+			qui contract item* group, freq(freq)
+			qui count
+			local patobs=r(N)
+			if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
+				qui gen keep=0
+				qui gsort +group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+				qui gsort -group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n1''
+			}
+			else{
+				qui gen keep=1
+			}
+		}
+		else{
+			qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
+			forvalues j=1/`nbitems'{
+				rename itemA`j' item`j'
+				rename itemB`j' item`=`nbitems'+`j''
+			}
+			qui drop lt1 lt2
+			qui contract item*, freq(freq)
+			local patobs=r(N)
+			if `patobs'>=`=`n0'*`nbpatterns''{
+				qui gen keep=0
+				qui gsort -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+			}
+			else{
+			  qui gen keep=1
+			}
+		}
+		qui keep if keep==1
+		qui count
+		local retain=r(N)
+		di "Number of kept patterns:`retain'"
+		local method GH
+	}
+	if "`longitudinal'"==""{
+		qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
+		qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
+		qui gen var1=`var0' if group==0
+		qui replace var1=`var1' if group==1
+	}
+	else{
+		qui gen mean1=`mean1'
+		qui gen mean2=`mean2'
+	}
+	/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
+	if "`method'"=="GH" {
+		local temp=`nbmodat'^(`nbtotitems')
+		local diff0=0
+		qui gen proba=.
+		local dixj=10
+		qui count
+		local tmp=r(N)
+
+		forvalues i=1/`tmp' {
+			local dix=floor(`tmp'/10)
+			if mod(`i',`dix')==0 & "`html'"=="" {
+				if "`dixj'"!="10" {
+					di ".." _c
+				}
+				di "`dixj'%" _c
+				local dixj=`dixj'+10
+			}
+			forvalues t=1/`nbt'{
+				local int`t'=1			 
+				forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+					qui su item`j' in `i'
+					local rep=r(mean)
+					local diff0=0
+					local diff1=`dlong'[`j',1]
+					local sum "1+exp(x`t'-`diff1')"
+					forvalues m=2/`=`nbmodat'-1' {
+					   local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+					   local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+					}
+					local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+				}
+			}	
+			if "`longitudinal'"==""{
+				qui su mean1 in `i'
+				local mean=r(mean)
+				qui su var1 in `i'
+				local vart=r(mean)
+				qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+				qui replace proba=r(int) in `i'
+			}
+			else{
+				local int "`int1'*`int2'"
+				matrix mean=(`mean1',`mean2')
+				qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
+				qui replace proba=r(int) in `i'
+			}
+		}
+		di
+	}
+	else {
+		qui gen proba=1
+		forvalues t=1/`nbt'{
+			forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+				local diff0=0
+				local diff1=`dlong'[`i',1]
+				qui gen eps0=1
+				qui gen eps1=exp(mean`t'-`diff1')
+				qui gen d=eps0+eps1
+				forvalues m=2/`=`nbmodat'-1' {
+					local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
+					qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
+					qui replace d=d+eps`m'
+				}
+				local listeps
+				forvalues m=0/`=`nbmodat'-1' {
+					qui replace proba=proba*eps`m'/d if item`i'==`m'
+					local listeps `listeps' eps`m'
+				}
+				qui drop `listeps' d
+			}
+		}
+		if "`method'"=="MEAN+GH" {
+			set tracedepth 1
+			if "`longitudinal'"==""{
+				qui gen keep=0
+				qui gsort -group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui gsort +group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+				qui su proba if group==0
+				local sumproba0=r(sum)*100
+				qui su proba if group==1
+				local sumproba1=r(sum)*100
+			}
+			else{
+				qui gen keep=0
+				qui gsort -proba
+				local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+			}
+
+			qui drop keep proba
+			local diff0=0
+			qui gen proba=.
+			qui count
+			local nnew=r(N)
+			di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
+			if "`longitudinal'"==""{
+				di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
+			}
+			local dixj=10
+			forvalues i=1/`nnew' {
+				local dix=floor(`nnew'/10)
+				if mod(`i',`dix')==0 & "`html'"=="" {
+					if "`dixj'"!="10" {
+						di ".." _c
+					}
+					di "`dixj'%" _c
+					local dixj=`dixj'+10
+				}
+				forvalues t=1/`nbt'{
+					local int`t'=1
+					forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+						qui su item`j' in `i'
+						local rep=r(mean)
+						local diff0=0
+						local diff1=`dlong'[`j',1]
+						local sum "1+exp(x`t'-`diff1')"
+						forvalues m=2/`=`nbmodat'-1' {
+							local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+							local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+						}
+						local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+					}
+				}
+				if "`longitudinal'"==""{
+					qui su mean1 in `i'
+					local mean=r(mean)
+					qui su var1 in `i'
+					local vart=r(mean)
+					qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+					qui replace proba=r(int) in `i'
+				}
+				else{
+					local int "`int1'*`int2'"
+					matrix mean=(`mean1',`mean2')
+					qui gausshermite `int',mu(mean) var(`matvar') display
+					qui replace proba=r(int) in `i'
+				}
+			}
+		}
+	}
+	qui gen eff=proba
+	qui gen eff2=.  
+   
+	if "`longitudinal'"==""{
+		qui keep item* eff* group proba
+		local p1=1/`n1'
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p1') if group==1
+		qui replace eff2=floor(eff/`p0') if group==0
+		qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
+		qui su eff2 if group==1
+		local aff1=r(sum)
+		qui su eff2 if group==0
+		local aff0=r(sum)
+
+		local unaff1=`n1'-`aff1'
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort + group - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+		qui gsort - group - eff
+		qui replace eff2=eff2+1 in 1/`unaff1'
+
+		qui drop if eff2==0
+		gsort group item*
+		qui expand eff2
+	}
+	else{
+		qui keep item* eff* proba
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p0')
+		qui replace eff=eff-eff2*`p0'
+		qui su eff2
+		local aff0=r(sum)
+
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+
+		qui drop if eff2==0
+		gsort item*
+		qui expand eff2
+	}
+   qui drop proba eff eff2
+}
+
+qui alpha item*
+local alpha=r(alpha)
+
+if "`longitudinal'"==""{ /*TRANSVERSAL*/
+	qui gen groupc=-`n1'/(`n0'+`n1') if group==0
+	qui replace groupc=`n0'/(`n0'+`n1') if group==1
+	if `nbmodat'==2 {   /*DICHOTOMOUS CASE*/
+        if "`freeitems'"=="" {
+		      local offset "offset(offset)"
+			  local items
+        }
+        else {
+		      local offset
+		      local items "item1-item`nbitems'"
+        }
+		qui gen i=_n
+
+		tempname diff
+		matrix `diff'=`dd''
+
+		qui reshape long item, i(i)
+		qui rename item rep
+		qui rename _j item
+
+		qui gen  offset=0
+		forvalues i=1/`nbitems' {
+			qui replace offset=-`diff'[1,`i'] if item==`i'
+			qui gen item`i'=item==`i'
+			qui replace item`i'=-item`i'
+		}
+        if `var0'==`var1' { /*EQUAL VARIANCES*/
+	       *constraint 1 _cons=`=ln(`var')'
+		   *qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
+	       if  "`freevar'"=="" {
+		      constraint 1 _cons=`=sqrt(`var0')'
+		      local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
+		}
+		else {/*UNEQUAL VARIANCES*/
+		   tempvar G0 G1
+		   qui gen `G0'=group==0
+		   qui gen `G1'=group==1
+		   qui eq B0: `G0'
+		   qui eq B1: `G1'
+	       constraint 1 _cons=0
+	       if  "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
+			   constraint 2 `G0'=`=sqrt(`var0')'
+			   constraint 3 `G1'=`=sqrt(`var1')'
+		       constraint 1 _cons=`=sqrt(`var0')'
+		       local constvar "constraint(1 2 3)"
+		   }
+		   else { /*FREE UNEQUAL VARIANCES*/
+		       local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
+		}
+		tempname b V/*LONGITUDINAL*/
+		local row = 1
+	}
+	else { /*POLYTOMOUS CASE*/
+		matrix `db'=`db''
+	    if `var0'==`var1' {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvar(`var0')"
+		   }
+		   else {
+		       local fv 
+		   }
+		}
+		else {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvargroupc(`var')"
+		   }
+		   else {
+		       local fv "vargroupc"
+		   }
+        }
+		if "`freeitems'"=="" {
+		   local fi "fixed(`db') fixedmu"
+		   local row=1
+		}
+		else {
+		   local fi
+		   local row=(`nbmodat'-1)*`nbitems'+1
+		}
+	     *di "pcm item*, `fi' covariates(groupc) `fv'"
+	     noi pcm item*, `fi' covariates(groupc) `fv'
+	}
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,`row']
+	local se=`V'[`row',`row']^.5
+}
+else{ 
+	qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,1]
+	local se=`V'[1,1]^.5
+	local n1=`n0'
+}
+local poweruni=1-normal(1.96-`gamma'/`se')
+
+if "`html'" == "" {
+	di
+	di
+}
+if "`detail'"!=""{
+	di in gr "{hline 91}"
+	di _col(60)  "Estimation with the "
+	di _col(50)  "Cramer-Rao bound" _col(75) "classical formula"
+	di in gr "{hline 91}"
+}
+
+if "`longitudinal'"==""{
+	local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
+	local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
+	local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the group effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+else{
+	local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
+	local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the time effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+
+if `expectedpower'!=-1 {
+   qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
+   local expn_1=r(N_1)
+   local expn_2=r(N_2)
+   local expn2=`expn_1'*`ratio'
+   di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
+}
+
+
+return scalar EstGamma=`gammaest'
+return scalar CRbound=`=`se'^2'
+return scalar CRPower=`poweruni'
+return scalar ClPower=`clpower'
+return scalar ClSS=`clnsn'
+return scalar Ratio=`ratio'
+return scalar CronbachAlpha=`alpha'
+
+
+if "`graph'" != "" {
+	matrix res=J(15,5,.)
+	matrix colnames res= n0 n1 gamma variance power
+	local l=1
+
+	if "`longitudinal'"==""{
+		foreach var in 0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 {
+			qui raschpower54, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
+			qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
+			local ++l
+		}
+		clear
+		qui svmat res,names(col)
+		
+		if "`html'" != "" {
+			qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
+			qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving'
+			qui graph use `c(tmpdir)'/`html'_planif_graph.gph
+			qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
+			di "
" + di " _char(34) " + } + else { + twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) + } + } + + else { + if `gcorr' != -1 { + local l=1 + foreach var in 0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 { + local cov = `gcorr'*`var' + local matv "`var',`cov'" " \ `cov',`var'" + qui raschpower54, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) + } + } + + if `gvar' != -1 { + matrix res=J(15,5,.) + matrix colnames res= n0 n1 gamma corr power + local l=1 + forvalues corr = 0.1(0.1)0.9 { + local cov = `corr'*`gvar' + local matv "`gvar',`cov'" " \ `cov',`gvar'" + qui raschpower54, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(0.4 0.7 0.9) xtitle(Correlation) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(0.1[0.1]0.9) xtitle(Correlation) ytitle(Power) name(planif_graph,replace) + } + } + } + +//di in gr "Method: " in ye "`method'" + + if "`html'" != "" { + di "
" + } +} + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschpower55.ado b/Modules/ado/personal/r/raschpower55.ado new file mode 100644 index 0000000..7494f92 --- /dev/null +++ b/Modules/ado/personal/r/raschpower55.ado @@ -0,0 +1,822 @@ +*! version 5.5 : April 9th, 2014 +*! Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot +************************************************************************************************************ +* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals +* +* Version 1 : January 25th, 2010 (Jean-Benoit Hardouin) +* Version 1.1 : January 26th, 2010 (Jean-Benoit Hardouin) +* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin) +* version 1.3 : May 2nd, 2011 (Jean-Benoit Hardouin) +* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections +* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results +* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method +* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design +* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option +* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items +* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups +* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups +* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug +* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display +* version 5.5 : April 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : graph option for longitudinal design +* +* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* Myriam Blanchin, myriam.blanchin@univ-nantes.fr +* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health" +* Faculty of Pharmaceutical Sciences - University of Nantes - France +* http://www.sphere-nantes.org +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschpower55,rclass +syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1)] +version 11 + +if "`html'" != "" { + di "" + di "
"
+}
+
+tempfile raschpowerfile
+capture qui save "`raschpowerfile'",replace
+tempname db d dlong matvar
+
+/*******************************************************************************
+DEFINITION DES PARAMETRES
+*******************************************************************************/
+
+if "`graph'" != "" & "`longitudinal'" != "" {
+	if `gvar' != -1 & `gcorr' != -1 {
+		di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
+		error 198
+	}
+	if `gvar' == -1 & `gcorr' == -1 {
+		di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
+		error 198
+	}
+}
+
+if "`difficulties'"=="" {
+   matrix `d'=[-1\-0.5\0\0.5\1]
+}
+else {
+   matrix `d'=`difficulties'
+}
+local nbitems=rowsof(`d')
+local nbmodat=colsof(`d')+1
+
+if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
+	local nbt=1
+	local nbtotitems=`nbitems'
+	local nbpatmax=2*`nbmodat'^`nbitems'
+	if "`var'"==""{
+		local var=1
+		local var0=1
+		local var1=1
+	}
+	else{
+		capture confirm number `var'
+		if !_rc {
+			local var0=`var'
+			local var1=`var'
+		}
+		else{
+		   local nbw:word count `var'
+		   local grp=1
+		   if `nbw'==2 {
+				local t1: word 1 of `var'
+                capture confirm number `t1'
+				if !_rc {
+					local t2: word 2 of `var'
+                    capture confirm number `t2'
+                    if !_rc {
+                       local var0=`t1'
+                       local var1=`t2'
+                       local grp=2
+                    }
+				}
+			}
+			if `nbw'!=2|`grp'==1 {
+				capture confirm matrix `var'
+			    if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
+				    matrix `matvar'=`var'
+					local var0=`matvar'[1,1]
+					local var1=`matvar'[1,1]
+			    }
+			    else{
+					di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
+					error 198
+					exit
+			    }
+		    }
+		}
+	}
+	matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
+    local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
+
+	local sumd=0
+	forvalues numit=1/`nbitems'{
+		local sumd=`sumd'+`d'[`numit',1]
+	}
+	local sumd=`sumd'/`nbitems'
+	if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
+		if "`html'" == "" {
+			di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
+		}
+	}
+
+}
+else{ /*CAS LONGITUDINAL*/
+	local nbt=2
+	local nbtotitems=2*`nbitems'
+	local nbpatmax=`nbmodat'^(`nbitems'*2)
+	local n1=0
+	local mean1=0
+	local mean2=`mean1'+`gamma'
+	if "`var'"==""{
+		matrix `matvar'=(1,0\0,1)
+	}
+	else{
+		matrix `matvar'=`var'
+		capture confirm matrix `matvar'
+		if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
+			di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
+			error 198
+			exit
+		}
+	}
+	matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
+	matrix `dlong'[1,1]=`d'
+	matrix `dlong'[`=`nbitems'+1',1]=`d'
+}
+
+/*******************************************************************************
+DEFINITION DE LA METHODE
+*******************************************************************************/
+
+if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
+	local method POPULATION+GH
+}
+
+if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
+   di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
+   di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
+   di in gr "The -method- option is replaced by GH."
+   local method GH
+}
+else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
+	di in red "The number of patterns is too high for the chosen method"
+	exit
+}
+else if "`method'"=="" {
+    if `nbpatmax'<2000 {
+        local method GH
+    }
+    else  {
+        local method POPULATION+GH
+    }
+}
+
+if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
+	di in red "Invalid method name"
+	exit
+}
+
+/*******************************************************************************
+AFFICHAGE DES PARAMETRES
+*******************************************************************************/
+
+if "`longitudinal'"==""{
+	di in gr "Number of individuals in the first group: " in ye `n0'
+	di in gr "Number of individuals in the second group: " in ye `n1'
+	di in green "Group effect: " in ye `gamma'
+	di in  gr "Variance of the latent trait in the first group: " in ye `var0'
+	di in  gr "Variance of the latent trait in the second group: " in ye `var1'
+}
+else{
+	di in gr "Number of individuals at each time:  " in ye `n0'
+	di in green "Time effect: " in ye `gamma'
+	di in  gr "Variance matrix of the latent trait: " 
+	matrix list `matvar',noheader
+	di
+}
+di in gr "Number of items: " in ye `nbitems'
+di in green "Difficulties parameters of the items: "
+tempname dd
+matrix `dd'=`d''
+local items
+forvalues i=1/`nbitems' {
+   local items "`items' item`i'"
+}
+local modalities
+forvalues i=1/`=`nbmodat'-1' {
+   local modalities "`modalities' delta_`i'"
+}
+
+matrix colnames `dd'=`items'
+matrix rownames `dd'=`modalities'
+
+
+di
+tempname ddt
+matrix `ddt' = `dd''
+matrix colnames `ddt'=`modalities'
+matrix rownames `ddt'=`items'
+if "`html'" != "" {
+	matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficultés dans l'autre sens */
+}
+else {
+	matrix list `dd',noblank nohalf noheader
+}
+di
+
+if "`detail'"!="" & "`html'" == ""{
+	di in gr "Method:  " in ye "`method'"
+	di in gr "Number of studied response's patterns: " in ye `nbpatmax'
+}
+matrix `dd'=`d'
+local gamma=`gamma'
+
+local tmp=1
+qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
+forvalues j=1/`nbitems' {
+	forvalues m=1/`=`nbmodat'-1' {
+		qui matrix `db'[`tmp',1]=`d'[`j',`m']
+		local ++tmp
+	}
+}
+
+
+/*******************************************************************************
+CREATION DU DATASET ATTENDU 
+*******************************************************************************/
+
+if "`data'"=="" {
+	clear
+	if "`method'"!="POPULATION+GH"{
+		local temp=`nbmodat'^(`nbtotitems')
+		qui range x 0 `=`temp'-1' `temp'
+		qui g t=x
+		loc i=`nbtotitems'
+		qui count if t>0
+		loc z=r(N)
+		qui while `z'>0 {
+			qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
+			qui replace t=mod(t,`nbmodat'^`=`i'-1')
+			qui count if t>0
+			loc z=r(N)
+			loc i=`i'-1
+		}
+		drop t
+		if "`longitudinal'"==""{
+			qui expand 2
+			qui gen group=0 in 1/`temp'
+			qui replace group=1 in `=`temp'+1'/`=2*`temp''
+		}	
+	}
+	else { /*METHODE POPULATION (SIMULATION)*/
+		if "`longitudinal'"==""{
+			*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
+			qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
+			qui gen group=1
+			tempfile save1
+			qui save `save1',replace
+			qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
+			qui gen group=0
+			qui append using `save1'
+			qui drop lt1
+			qui contract item* group, freq(freq)
+			qui count
+			local patobs=r(N)
+			if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
+				qui gen keep=0
+				qui gsort +group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+				qui gsort -group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n1''
+			}
+			else{
+				qui gen keep=1
+			}
+		}
+		else{
+			qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
+			forvalues j=1/`nbitems'{
+				rename itemA`j' item`j'
+				rename itemB`j' item`=`nbitems'+`j''
+			}
+			qui drop lt1 lt2
+			qui contract item*, freq(freq)
+			local patobs=r(N)
+			if `patobs'>=`=`n0'*`nbpatterns''{
+				qui gen keep=0
+				qui gsort -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+			}
+			else{
+			  qui gen keep=1
+			}
+		}
+		qui keep if keep==1
+		qui count
+		local retain=r(N)
+		di "Number of kept patterns:`retain'"
+		local method GH
+	}
+	if "`longitudinal'"==""{
+		qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
+		qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
+		qui gen var1=`var0' if group==0
+		qui replace var1=`var1' if group==1
+	}
+	else{
+		qui gen mean1=`mean1'
+		qui gen mean2=`mean2'
+	}
+	/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
+	if "`method'"=="GH" {
+		local temp=`nbmodat'^(`nbtotitems')
+		local diff0=0
+		qui gen proba=.
+		local dixj=10
+		qui count
+		local tmp=r(N)
+
+		forvalues i=1/`tmp' {
+			local dix=floor(`tmp'/10)
+			if mod(`i',`dix')==0 & "`html'"=="" {
+				if "`dixj'"!="10" {
+					di ".." _c
+				}
+				di "`dixj'%" _c
+				local dixj=`dixj'+10
+			}
+			forvalues t=1/`nbt'{
+				local int`t'=1			 
+				forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+					qui su item`j' in `i'
+					local rep=r(mean)
+					local diff0=0
+					local diff1=`dlong'[`j',1]
+					local sum "1+exp(x`t'-`diff1')"
+					forvalues m=2/`=`nbmodat'-1' {
+					   local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+					   local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+					}
+					local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+				}
+			}	
+			if "`longitudinal'"==""{
+				qui su mean1 in `i'
+				local mean=r(mean)
+				qui su var1 in `i'
+				local vart=r(mean)
+				qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+				qui replace proba=r(int) in `i'
+			}
+			else{
+				local int "`int1'*`int2'"
+				matrix mean=(`mean1',`mean2')
+				qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
+				qui replace proba=r(int) in `i'
+			}
+		}
+		di
+	}
+	else {
+		qui gen proba=1
+		forvalues t=1/`nbt'{
+			forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+				local diff0=0
+				local diff1=`dlong'[`i',1]
+				qui gen eps0=1
+				qui gen eps1=exp(mean`t'-`diff1')
+				qui gen d=eps0+eps1
+				forvalues m=2/`=`nbmodat'-1' {
+					local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
+					qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
+					qui replace d=d+eps`m'
+				}
+				local listeps
+				forvalues m=0/`=`nbmodat'-1' {
+					qui replace proba=proba*eps`m'/d if item`i'==`m'
+					local listeps `listeps' eps`m'
+				}
+				qui drop `listeps' d
+			}
+		}
+		if "`method'"=="MEAN+GH" {
+			set tracedepth 1
+			if "`longitudinal'"==""{
+				qui gen keep=0
+				qui gsort -group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui gsort +group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+				qui su proba if group==0
+				local sumproba0=r(sum)*100
+				qui su proba if group==1
+				local sumproba1=r(sum)*100
+			}
+			else{
+				qui gen keep=0
+				qui gsort -proba
+				local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+			}
+
+			qui drop keep proba
+			local diff0=0
+			qui gen proba=.
+			qui count
+			local nnew=r(N)
+			di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
+			if "`longitudinal'"==""{
+				di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
+			}
+			local dixj=10
+			forvalues i=1/`nnew' {
+				local dix=floor(`nnew'/10)
+				if mod(`i',`dix')==0 & "`html'"=="" {
+					if "`dixj'"!="10" {
+						di ".." _c
+					}
+					di "`dixj'%" _c
+					local dixj=`dixj'+10
+				}
+				forvalues t=1/`nbt'{
+					local int`t'=1
+					forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+						qui su item`j' in `i'
+						local rep=r(mean)
+						local diff0=0
+						local diff1=`dlong'[`j',1]
+						local sum "1+exp(x`t'-`diff1')"
+						forvalues m=2/`=`nbmodat'-1' {
+							local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+							local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+						}
+						local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+					}
+				}
+				if "`longitudinal'"==""{
+					qui su mean1 in `i'
+					local mean=r(mean)
+					qui su var1 in `i'
+					local vart=r(mean)
+					qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+					qui replace proba=r(int) in `i'
+				}
+				else{
+					local int "`int1'*`int2'"
+					matrix mean=(`mean1',`mean2')
+					qui gausshermite `int',mu(mean) var(`matvar') display
+					qui replace proba=r(int) in `i'
+				}
+			}
+		}
+	}
+	qui gen eff=proba
+	qui gen eff2=.  
+   
+	if "`longitudinal'"==""{
+		qui keep item* eff* group proba
+		local p1=1/`n1'
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p1') if group==1
+		qui replace eff2=floor(eff/`p0') if group==0
+		qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
+		qui su eff2 if group==1
+		local aff1=r(sum)
+		qui su eff2 if group==0
+		local aff0=r(sum)
+
+		local unaff1=`n1'-`aff1'
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort + group - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+		qui gsort - group - eff
+		qui replace eff2=eff2+1 in 1/`unaff1'
+
+		qui drop if eff2==0
+		gsort group item*
+		qui expand eff2
+	}
+	else{
+		qui keep item* eff* proba
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p0')
+		qui replace eff=eff-eff2*`p0'
+		qui su eff2
+		local aff0=r(sum)
+
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+
+		qui drop if eff2==0
+		gsort item*
+		qui expand eff2
+	}
+   qui drop proba eff eff2
+}
+
+qui alpha item*
+local alpha=r(alpha)
+
+if "`longitudinal'"==""{ /*TRANSVERSAL*/
+	qui gen groupc=-`n1'/(`n0'+`n1') if group==0
+	qui replace groupc=`n0'/(`n0'+`n1') if group==1
+	if `nbmodat'==2 {   /*DICHOTOMOUS CASE*/
+        if "`freeitems'"=="" {
+		      local offset "offset(offset)"
+			  local items
+        }
+        else {
+		      local offset
+		      local items "item1-item`nbitems'"
+        }
+		qui gen i=_n
+
+		tempname diff
+		matrix `diff'=`dd''
+
+		qui reshape long item, i(i)
+		qui rename item rep
+		qui rename _j item
+
+		qui gen  offset=0
+		forvalues i=1/`nbitems' {
+			qui replace offset=-`diff'[1,`i'] if item==`i'
+			qui gen item`i'=item==`i'
+			qui replace item`i'=-item`i'
+		}
+        if `var0'==`var1' { /*EQUAL VARIANCES*/
+	       *constraint 1 _cons=`=ln(`var')'
+		   *qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
+	       if  "`freevar'"=="" {
+		      constraint 1 _cons=`=sqrt(`var0')'
+		      local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
+		}
+		else {/*UNEQUAL VARIANCES*/
+		   tempvar G0 G1
+		   qui gen `G0'=group==0
+		   qui gen `G1'=group==1
+		   qui eq B0: `G0'
+		   qui eq B1: `G1'
+	       constraint 1 _cons=0
+	       if  "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
+			   constraint 2 `G0'=`=sqrt(`var0')'
+			   constraint 3 `G1'=`=sqrt(`var1')'
+		       constraint 1 _cons=`=sqrt(`var0')'
+		       local constvar "constraint(1 2 3)"
+		   }
+		   else { /*FREE UNEQUAL VARIANCES*/
+		       local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
+		}
+		tempname b V/*LONGITUDINAL*/
+		local row = 1
+	}
+	else { /*POLYTOMOUS CASE*/
+		matrix `db'=`db''
+	    if `var0'==`var1' {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvar(`var0')"
+		   }
+		   else {
+		       local fv 
+		   }
+		}
+		else {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvargroupc(`var')"
+		   }
+		   else {
+		       local fv "vargroupc"
+		   }
+        }
+		if "`freeitems'"=="" {
+		   local fi "fixed(`db') fixedmu"
+		   local row=1
+		}
+		else {
+		   local fi
+		   local row=(`nbmodat'-1)*`nbitems'+1
+		}
+	     *di "pcm item*, `fi' covariates(groupc) `fv'"
+	     noi pcm item*, `fi' covariates(groupc) `fv'
+	}
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,`row']
+	local se=`V'[`row',`row']^.5
+}
+else{ 
+	qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,1]
+	local se=`V'[1,1]^.5
+	local n1=`n0'
+}
+local poweruni=1-normal(1.96-`gamma'/`se')
+
+if "`html'" == "" {
+	di
+	di
+}
+if "`detail'"!=""{
+	di in gr "{hline 91}"
+	di _col(60)  "Estimation with the "
+	di _col(50)  "Cramer-Rao bound" _col(75) "classical formula"
+	di in gr "{hline 91}"
+}
+
+if "`longitudinal'"==""{
+	local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
+	local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
+	local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the group effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+else{
+	local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
+	local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the time effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+
+if `expectedpower'!=-1 {
+   qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
+   local expn_1=r(N_1)
+   local expn_2=r(N_2)
+   local expn2=`expn_1'*`ratio'
+   di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
+}
+
+
+return scalar EstGamma=`gammaest'
+return scalar CRbound=`=`se'^2'
+return scalar CRPower=`poweruni'
+return scalar ClPower=`clpower'
+return scalar ClSS=`clnsn'
+return scalar Ratio=`ratio'
+return scalar CronbachAlpha=`alpha'
+
+
+if "`graph'" != "" {
+	matrix res=J(15,5,.)
+	matrix colnames res= n0 n1 gamma variance power
+	local l=1
+
+	if "`longitudinal'"==""{
+		foreach var in 0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 {
+			qui raschpower55, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
+			qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
+			local ++l
+		}
+		clear
+		qui svmat res,names(col)
+		
+		if "`html'" != "" {
+			qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
+			qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving'
+			qui graph use `c(tmpdir)'/`html'_planif_graph.gph
+			qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
+			di "
" + di " _char(34) " + } + else { + twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) + } + } + + else { + if `gcorr' != -1 { + local l=1 + foreach var in 0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 { + local cov = `gcorr'*`var' + local matv "`var',`cov'" " \ `cov',`var'" + qui raschpower55, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) + } + } + + if `gvar' != -1 { + matrix res=J(9,5,.) + matrix colnames res= n0 n1 gamma corr power + local l=1 + forvalues corr = 0.1(0.1)0.9 { + local cov = `corr'*`gvar' + local matv "`gvar',`cov'" " \ `cov',`gvar'" + qui raschpower55, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(0.1[0.1]0.9) xtitle(Correlation) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(0.1[0.1]0.9) xtitle(Correlation) ytitle(Power) name(planif_graph,replace) + } + } + } + +//di in gr "Method: " in ye "`method'" + + if "`html'" != "" { + di "
" + } +} + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschpower56.ado b/Modules/ado/personal/r/raschpower56.ado new file mode 100644 index 0000000..adae592 --- /dev/null +++ b/Modules/ado/personal/r/raschpower56.ado @@ -0,0 +1,852 @@ +*! version 5.7 : June 21th, 2014 +*! Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot +************************************************************************************************************ +* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals +* +* Version 1 : January 25th, 2010 (Jean-Benoit Hardouin) +* Version 1.1 : January 26th, 2010 (Jean-Benoit Hardouin) +* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin) +* version 1.3 : May 2nd, 2011 (Jean-Benoit Hardouin) +* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections +* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results +* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method +* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design +* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option +* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items +* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups +* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups +* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug +* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display +* version 5.5 : April 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : graph option for longitudinal design +* version 5.6 : April 10th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : corrections of bugs +* version 5.7 : June 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : minor corrections +* +* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* Myriam Blanchi n, myriam.blanchin@univ-nantes.fr +* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health" +* Faculty of Pharmaceutical Sciences - University of Nantes - France +* http://www.sphere-nantes.org +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschpower56,rclass +syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1)] +version 11 + +if "`html'" != "" { + di "" + di "
"
+}
+
+tempfile raschpowerfile
+capture qui save "`raschpowerfile'",replace
+tempname db d dlong matvar
+
+/*******************************************************************************
+DEFINITION DES PARAMETRES
+*******************************************************************************/
+
+if "`graph'" != "" & "`longitudinal'" != "" {
+	if `gvar' != -1 & `gcorr' != -1 {
+		di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
+		error 198
+	}
+	if `gvar' == -1 & `gcorr' == -1 {
+		di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
+		error 198
+	}
+}
+
+if "`difficulties'"=="" {
+   matrix `d'=[-1\-0.5\0\0.5\1]
+}
+else {
+   matrix `d'=`difficulties'
+}
+local nbitems=rowsof(`d')
+local nbmodat=colsof(`d')+1
+
+if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
+	local nbt=1
+	local nbtotitems=`nbitems'
+	local nbpatmax=2*`nbmodat'^`nbitems'
+	if "`var'"==""{
+		local var=1
+		local var0=1
+		local var1=1
+	}
+	else{
+		capture confirm number `var'
+		if !_rc {
+			local var0=`var'
+			local var1=`var'
+		}
+		else{
+		   local nbw:word count `var'
+		   local grp=1
+		   if `nbw'==2 {
+				local t1: word 1 of `var'
+                capture confirm number `t1'
+				if !_rc {
+					local t2: word 2 of `var'
+                    capture confirm number `t2'
+                    if !_rc {
+                       local var0=`t1'
+                       local var1=`t2'
+                       local grp=2
+                    }
+				}
+			}
+			if `nbw'!=2|`grp'==1 {
+				capture confirm matrix `var'
+			    if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
+				    matrix `matvar'=`var'
+					local var0=`matvar'[1,1]
+					local var1=`matvar'[1,1]
+			    }
+			    else{
+					di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
+					error 198
+					exit
+			    }
+		    }
+		}
+	}
+	matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
+    local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
+
+	local sumd=0
+	forvalues numit=1/`nbitems'{
+		local sumd=`sumd'+`d'[`numit',1]
+	}
+	local sumd=`sumd'/`nbitems'
+	if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
+		if "`html'" == "" {
+			di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
+		}
+	}
+
+}
+else{ /*CAS LONGITUDINAL*/
+	local nbt=2
+	local nbtotitems=2*`nbitems'
+	local nbpatmax=`nbmodat'^(`nbitems'*2)
+	local n1=0
+	local mean1=0
+	local mean2=`mean1'+`gamma'
+	if "`var'"==""{
+		matrix `matvar'=(1,0\0,1)
+	}
+	else{
+		matrix `matvar'=`var'
+		capture confirm matrix `matvar'
+		if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
+			di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
+			error 198
+			exit
+		}
+	}
+	matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
+	matrix `dlong'[1,1]=`d'
+	matrix `dlong'[`=`nbitems'+1',1]=`d'
+}
+
+/*******************************************************************************
+DEFINITION DE LA METHODE
+*******************************************************************************/
+
+if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
+	local method POPULATION+GH
+}
+
+if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
+   di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
+   di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
+   di in gr "The -method- option is replaced by GH."
+   local method GH
+}
+else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
+	di in red "The number of patterns is too high for the chosen method"
+	exit
+}
+else if "`method'"=="" {
+    if `nbpatmax'<2000 {
+        local method GH
+    }
+    else  {
+        local method POPULATION+GH
+    }
+}
+
+if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
+	di in red "Invalid method name"
+	exit
+}
+
+/*******************************************************************************
+AFFICHAGE DES PARAMETRES
+*******************************************************************************/
+
+if "`longitudinal'"==""{
+	di in gr "Number of individuals in the first group: " in ye `n0'
+	di in gr "Number of individuals in the second group: " in ye `n1'
+	di in green "Group effect: " in ye `gamma'
+	di in  gr "Variance of the latent trait in the first group: " in ye `var0'
+	di in  gr "Variance of the latent trait in the second group: " in ye `var1'
+}
+else{
+	di in gr "Number of individuals at each time:  " in ye `n0'
+	di in green "Time effect: " in ye `gamma'
+	di in  gr "Variance matrix of the latent trait: " 
+	matrix list `matvar',noheader
+	di
+}
+di in gr "Number of items: " in ye `nbitems'
+di in green "Difficulties parameters of the items: "
+tempname dd
+matrix `dd'=`d''
+local items
+forvalues i=1/`nbitems' {
+   local items "`items' item`i'"
+}
+local modalities
+forvalues i=1/`=`nbmodat'-1' {
+   local modalities "`modalities' delta_`i'"
+}
+
+matrix colnames `dd'=`items'
+matrix rownames `dd'=`modalities'
+
+
+di
+tempname ddt
+matrix `ddt' = `dd''
+matrix colnames `ddt'=`modalities'
+matrix rownames `ddt'=`items'
+if "`html'" != "" {
+	matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficultés dans l'autre sens */
+}
+else {
+	matrix list `dd',noblank nohalf noheader
+}
+di
+
+if "`detail'"!="" & "`html'" == ""{
+	di in gr "Method:  " in ye "`method'"
+	di in gr "Number of studied response's patterns: " in ye `nbpatmax'
+}
+matrix `dd'=`d'
+local gamma=`gamma'
+
+local tmp=1
+qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
+forvalues j=1/`nbitems' {
+	forvalues m=1/`=`nbmodat'-1' {
+		qui matrix `db'[`tmp',1]=`d'[`j',`m']
+		local ++tmp
+	}
+}
+
+
+/*******************************************************************************
+CREATION DU DATASET ATTENDU 
+*******************************************************************************/
+
+if "`data'"=="" {
+	clear
+	if "`method'"!="POPULATION+GH"{
+		local temp=`nbmodat'^(`nbtotitems')
+		qui range x 0 `=`temp'-1' `temp'
+		qui g t=x
+		loc i=`nbtotitems'
+		qui count if t>0
+		loc z=r(N)
+		qui while `z'>0 {
+			qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
+			qui replace t=mod(t,`nbmodat'^`=`i'-1')
+			qui count if t>0
+			loc z=r(N)
+			loc i=`i'-1
+		}
+		drop t
+		if "`longitudinal'"==""{
+			qui expand 2
+			qui gen group=0 in 1/`temp'
+			qui replace group=1 in `=`temp'+1'/`=2*`temp''
+		}	
+	}
+	else { /*METHODE POPULATION (SIMULATION)*/
+		if "`longitudinal'"==""{
+			*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'*`gamma'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
+			qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
+			qui gen group=1
+			tempfile save1
+			qui save `save1',replace
+			qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
+			qui gen group=0
+			qui append using `save1'
+			*qui save d:\tmp,replace
+            bysort group:su lt
+			qui drop lt1
+			qui contract item* group, freq(freq)
+			qui count
+			local patobs=r(N)
+			if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
+				qui gen keep=0
+				qui gsort +group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+				qui gsort -group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n1''
+			}
+			else{
+				qui gen keep=1
+			}
+		}
+		else{
+			qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
+			forvalues j=1/`nbitems'{
+				rename itemA`j' item`j'
+				rename itemB`j' item`=`nbitems'+`j''
+			}
+			qui drop lt1 lt2
+			qui contract item*, freq(freq)
+			local patobs=r(N)
+			if `patobs'>=`=`n0'*`nbpatterns''{
+				qui gen keep=0
+				qui gsort -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+			}
+			else{
+			  qui gen keep=1
+			}
+		}
+		qui keep if keep==1
+		qui count
+		local retain=r(N)
+		di "Number of kept patterns:`retain'"
+		local method GH
+	}
+	if "`longitudinal'"==""{
+		qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
+		qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
+		qui gen var1=`var0' if group==0
+		qui replace var1=`var1' if group==1
+	}
+	else{
+		qui gen mean1=`mean1'
+		qui gen mean2=`mean2'
+	}
+	/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
+	if "`method'"=="GH" {
+		local temp=`nbmodat'^(`nbtotitems')
+		local diff0=0
+		qui gen proba=.
+		local dixj=10
+		qui count
+		local tmp=r(N)
+
+		forvalues i=1/`tmp' {
+			local dix=floor(`tmp'/10)
+			if mod(`i',`dix')==0 & "`html'"=="" {
+			    qui su proba
+				local tmpprob=r(sum)
+				if "`dixj'"!="10" {
+					di ".." _c
+				}
+				*di "`dixj'% (`tmpprob')" _c
+				di "`dixj'%" _c
+				local dixj=`dixj'+10
+			}
+			forvalues t=1/`nbt'{
+				local int`t'=1			 
+				forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+					qui su item`j' in `i'
+					local rep=r(mean)
+					local diff0=0
+					local diff1=`dlong'[`j',1]
+					local sum "1+exp(x`t'-`diff1')"
+					forvalues m=2/`=`nbmodat'-1' {
+					   local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+					   local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+					}
+					local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+				}
+			}	
+			if "`longitudinal'"==""{
+				qui su mean1 in `i'
+				local mean=r(mean)
+				qui su var1 in `i'
+				local vart=r(mean)
+				*di "gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
+				*prout
+				qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+				qui replace proba=r(int) in `i'
+			}
+			else{
+				local int "`int1'*`int2'"
+				matrix mean=(`mean1',`mean2')
+				qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
+				qui replace proba=r(int) in `i'
+			}
+		}
+		di
+	}
+	else { /*if "`method'"!="GH"*/
+		qui gen proba=1
+		forvalues t=1/`nbt'{
+			forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+				local diff0=0
+				local diff1=`dlong'[`i',1]
+				qui gen eps0=1
+				qui gen eps1=exp(mean`t'-`diff1')
+				qui gen d=eps0+eps1
+				forvalues m=2/`=`nbmodat'-1' {
+					local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
+					qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
+					qui replace d=d+eps`m'
+				}
+				local listeps
+				forvalues m=0/`=`nbmodat'-1' {
+					qui replace proba=proba*eps`m'/d if item`i'==`m'
+					local listeps `listeps' eps`m'
+				}
+				qui drop `listeps' d
+			}
+		}
+		if "`method'"=="MEAN+GH" {
+			set tracedepth 1
+			if "`longitudinal'"==""{
+				qui gen keep=0
+				qui gsort -group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui gsort +group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+				qui su proba if group==0
+				local sumproba0=r(sum)*100
+				qui su proba if group==1
+				local sumproba1=r(sum)*100
+			}
+			else{
+				qui gen keep=0
+				qui gsort -proba
+				local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+			}
+
+			qui drop keep proba
+			local diff0=0
+			qui gen proba=.
+			qui count
+			local nnew=r(N)
+			di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
+			if "`longitudinal'"==""{
+				di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
+			}
+			local dixj=10
+			forvalues i=1/`nnew' {
+				local dix=floor(`nnew'/10)
+				if mod(`i',`dix')==0 & "`html'"=="" {
+				    qui su proba
+					local sum=r(sum)
+					if "`dixj'"!="10" {
+						di ".." _c
+					}
+					di "`dixj'% (`sum')" _c
+					local dixj=`dixj'+10
+				}
+				forvalues t=1/`nbt'{
+					local int`t'=1
+					forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+						qui su item`j' in `i'
+						local rep=r(mean)
+						local diff0=0
+						local diff1=`dlong'[`j',1]
+						local sum "1+exp(x`t'-`diff1')"
+						forvalues m=2/`=`nbmodat'-1' {
+							local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+							local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+						}
+						local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+					}
+				}
+				if "`longitudinal'"==""{
+					qui su mean1 in `i'
+					local mean=r(mean)
+					qui su var1 in `i'
+					local vart=r(mean)
+					*di "qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
+					qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+					qui replace proba=r(int) in `i'
+				}
+				else{
+					local int "`int1'*`int2'"
+					matrix mean=(`mean1',`mean2')
+					qui gausshermite `int',mu(mean) var(`matvar') display
+					qui replace proba=r(int) in `i'
+				}
+			}
+		}
+	}
+	qui gen eff=proba
+	qui gen eff2=.  
+   
+	if "`longitudinal'"==""{
+		qui keep item* eff* group proba
+		local p1=1/`n1'
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p1') if group==1
+		qui replace eff2=floor(eff/`p0') if group==0
+		qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
+		qui su eff2 if group==1
+		local aff1=r(sum)
+		qui su eff2 if group==0
+		local aff0=r(sum)
+
+		local unaff1=`n1'-`aff1'
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort + group - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+		qui gsort - group - eff
+		qui replace eff2=eff2+1 in 1/`unaff1'
+
+		qui drop if eff2==0
+		qui gsort group item*
+		qui expand eff2
+	}
+	else{
+		qui keep item* eff* proba
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p0')
+		qui replace eff=eff-eff2*`p0'
+		qui su eff2
+		local aff0=r(sum)
+
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+
+		qui drop if eff2==0
+		qui gsort item*
+		qui expand eff2
+	}
+   qui drop proba eff eff2
+}
+
+qui save "d:\essai.dta", replace
+qui alpha item*
+local alpha=r(alpha)
+
+if "`longitudinal'"==""{ /*TRANSVERSAL*/
+	qui gen groupc=-`n1'/(`n0'+`n1') if group==0
+	qui replace groupc=`n0'/(`n0'+`n1') if group==1
+	if `nbmodat'==2 {   /*DICHOTOMOUS CASE*/
+        if "`freeitems'"=="" {
+		      local offset "offset(offset)"
+			  local items
+        }
+        else {
+		      local offset
+		      local items "item1-item`nbitems'"
+        }
+		qui gen i=_n
+
+		tempname diff
+		matrix `diff'=`dd''
+
+		qui reshape long item, i(i)
+		qui rename item rep
+		qui rename _j item
+
+		qui gen  offset=0
+		forvalues i=1/`nbitems' {
+			qui replace offset=-`diff'[1,`i'] if item==`i'
+			qui gen item`i'=item==`i'
+			qui replace item`i'=-item`i'
+		}
+        if `var0'==`var1' { /*EQUAL VARIANCES*/
+	       *constraint 1 _cons=`=ln(`var')'
+		   *qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
+	       if  "`freevar'"=="" {
+		      constraint 1 _cons=`=sqrt(`var0')'
+		      local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
+		}
+		else {/*UNEQUAL VARIANCES*/
+		   tempvar G0 G1
+		   qui gen `G0'=group==0
+		   qui gen `G1'=group==1
+		   qui eq B0: `G0'
+		   qui eq B1: `G1'
+	       constraint 1 _cons=0
+	       if  "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
+			   constraint 2 `G0'=`=sqrt(`var0')'
+			   constraint 3 `G1'=`=sqrt(`var1')'
+		       constraint 1 _cons=`=sqrt(`var0')'
+		       local constvar "constraint(1 2 3)"
+		   }
+		   else { /*FREE UNEQUAL VARIANCES*/
+		       local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
+		}
+		tempname b V/*LONGITUDINAL*/
+		local row = 1
+	}
+	else { /*POLYTOMOUS CASE*/
+		matrix `db'=`db''
+		if "`freeitems'"=="" {
+		   local fi "fixed(`db') fixedmu"
+		   local row=1
+		}
+		else {
+		   local fi
+		   local row=(`nbmodat'-1)*`nbitems'+1
+		}
+	    if `var0'==`var1' {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvar(`var0')"
+		   }
+		   else {
+		       local fv 
+			   *noi pcm item*, `fi' covariates(groupc) 
+
+		   }
+		}
+		else {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvargroupc(`var')"
+		   }
+		   else {
+		       local fv "vargroupc"
+		   }
+        }
+	      *di "jk pcm item*, `fi' covariates(groupc) `fv'"
+		   	/********************************ESSAI 23 mai 2014*/
+			qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`n1')
+			qui gen group=1
+			tempfile save1
+			qui save `save1',replace
+			qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`n0')
+			qui gen group=0
+			qui append using `save1'
+			qui gen groupc=group-0.5
+			*di "ON A SIMULE"
+			**********************************FIN ESSAI 23 mai 2014*/
+
+		 qui pcm item*, `fi' covariates(groupc) `fv'
+	}
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,`row']
+	local se=`V'[`row',`row']^.5
+}
+else{ /*LONGITUDINAL*/ 
+	qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,1]
+	local se=`V'[1,1]^.5
+	local n1=`n0'
+}
+local poweruni=1-normal(1.96-`gamma'/`se')
+
+if "`html'" == "" {
+	di
+	di
+}
+if "`detail'"!=""{
+	di in gr "{hline 91}"
+	di _col(60)  "Estimation with the "
+	di _col(50)  "Cramer-Rao bound" _col(75) "classical formula"
+	di in gr "{hline 91}"
+}
+
+if "`longitudinal'"==""{
+	local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
+	local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
+	local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the group effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+else{
+	local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
+	local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the time effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+
+if `expectedpower'!=-1 {
+   qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
+   local expn_1=r(N_1)
+   local expn_2=r(N_2)
+   local expn2=`expn_1'*`ratio'
+   di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _c
+   if "`detail'"!="" {
+      di _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
+   }
+}
+
+
+return scalar EstGamma=`gammaest'
+return scalar CRbound=`=`se'^2'
+return scalar CRPower=`poweruni'
+return scalar ClPower=`clpower'
+return scalar ClSS=`clnsn'
+return scalar Ratio=`ratio'
+return scalar CronbachAlpha=`alpha'
+
+
+if "`graph'" != "" {
+	matrix res=J(15,5,.)
+	matrix colnames res= n0 n1 gamma variance power
+	local l=1
+
+	if "`longitudinal'"==""{
+		foreach var in 0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 {
+			qui raschpower55, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
+			qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
+			local ++l
+		}
+		clear
+		qui svmat res,names(col)
+		
+		if "`html'" != "" {
+			qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
+			qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving'
+			qui graph use `c(tmpdir)'/`html'_planif_graph.gph
+			qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
+			di "
" + di " _char(34) " + } + else { + twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) + } + } + + else { + if `gcorr' != -1 { + local l=1 + foreach var in 0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 { + local cov = `gcorr'*`var' + local matv "`var',`cov'" " \ `cov',`var'" + qui raschpower55, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) + } + } + + if `gvar' != -1 { + matrix res=J(9,5,.) + matrix colnames res= n0 n1 gamma corr power + local l=1 + forvalues corr = 0.1(0.1)0.9 { + local cov = `corr'*`gvar' + local matv "`gvar',`cov'" " \ `cov',`gvar'" + qui raschpower55, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(0.1[0.1]0.9) xtitle(Correlation) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(0.1[0.1]0.9) xtitle(Correlation) ytitle(Power) name(planif_graph,replace) + } + } + } + +//di in gr "Method: " in ye "`method'" + + if "`html'" != "" { + di "
" + } +} + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschpower58.ado b/Modules/ado/personal/r/raschpower58.ado new file mode 100644 index 0000000..15827a5 --- /dev/null +++ b/Modules/ado/personal/r/raschpower58.ado @@ -0,0 +1,878 @@ +*! version 5.8 : July 9th, 2014 +*! Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot +************************************************************************************************************ +* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals +* +* Version 1 : January 25th, 2010 (Jean-Benoit Hardouin) +* Version 1.1 : January 26th, 2010 (Jean-Benoit Hardouin) +* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin) +* version 1.3 : May 2nd, 2011 (Jean-Benoit Hardouin) +* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections +* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results +* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method +* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design +* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option +* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items +* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups +* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups +* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug +* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display +* version 5.5 : April 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : graph option for longitudinal design +* version 5.6 : April 10th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : corrections of bugs +* version 5.7 : June 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : minor corrections +* version 5.8 : July 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : correction of a bug when the variances are different in the 2 groups (transversal) +* +* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* Myriam Blanchi n, myriam.blanchin@univ-nantes.fr +* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health" +* Faculty of Pharmaceutical Sciences - University of Nantes - France +* http://www.sphere-nantes.org +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschpower58,rclass +syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1) min(real 0.25) step(real 1) max(real 9)] +version 11 + +if "`html'" != "" { + di "" + di "
"
+}
+
+tempfile raschpowerfile
+capture qui save "`raschpowerfile'",replace
+tempname db d dlong matvar
+
+/*******************************************************************************
+DEFINITION DES PARAMETRES
+*******************************************************************************/
+
+if "`graph'" != "" & "`longitudinal'" != "" {
+	if `gvar' != -1 & `gcorr' != -1 {
+		di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
+		error 198
+	}
+	if `gvar' == -1 & `gcorr' == -1 {
+		di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
+		error 198
+	}
+}
+
+if "`difficulties'"=="" {
+   matrix `d'=[-1\-0.5\0\0.5\1]
+}
+else {
+   matrix `d'=`difficulties'
+}
+local nbitems=rowsof(`d')
+local nbmodat=colsof(`d')+1
+
+if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
+	local nbt=1
+	local nbtotitems=`nbitems'
+	local nbpatmax=2*`nbmodat'^`nbitems'
+	if "`var'"==""{
+		local var=1
+		local var0=1
+		local var1=1
+	}
+	else{
+		capture confirm number `var'
+		if !_rc {
+			local var0=`var'
+			local var1=`var'
+		}
+		else{
+		   local nbw:word count `var'
+		   local grp=1
+		   if `nbw'==2 {
+				local t1: word 1 of `var'
+                capture confirm number `t1'
+				if !_rc {
+					local t2: word 2 of `var'
+                    capture confirm number `t2'
+                    if !_rc {
+                       local var0=`t1'
+                       local var1=`t2'
+                       local grp=2
+                    }
+				}
+			}
+			if `nbw'!=2|`grp'==1 {
+				capture confirm matrix `var'
+			    if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
+				    matrix `matvar'=`var'
+					local var0=`matvar'[1,1]
+					local var1=`matvar'[1,1]
+			    }
+			    else{
+					di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
+					error 198
+					exit
+			    }
+		    }
+		}
+	}
+	matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
+    local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
+
+	local sumd=0
+	forvalues numit=1/`nbitems'{
+		local sumd=`sumd'+`d'[`numit',1]
+	}
+	local sumd=`sumd'/`nbitems'
+	if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
+		if "`html'" == "" {
+			di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
+		}
+	}
+
+}
+else{ /*CAS LONGITUDINAL*/
+	local nbt=2
+	local nbtotitems=2*`nbitems'
+	local nbpatmax=`nbmodat'^(`nbitems'*2)
+	local n1=0
+	local mean1=0
+	local mean2=`mean1'+`gamma'
+	if "`var'"==""{
+		matrix `matvar'=(1,0\0,1)
+	}
+	else{
+		matrix `matvar'=`var'
+		capture confirm matrix `matvar'
+		if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
+			di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
+			error 198
+			exit
+		}
+	}
+	matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
+	matrix `dlong'[1,1]=`d'
+	matrix `dlong'[`=`nbitems'+1',1]=`d'
+}
+
+/*
+if "`max'" == "" {
+	local max = 9 + `step'/2
+}
+else {
+	local max = `max' + `step'/2
+}*/
+
+forval v = `min'(`step')`max' {
+	local w = `v'
+}
+if `w' < `max' {
+	local max = `max' + `step'
+}
+
+/*******************************************************************************
+DEFINITION DE LA METHODE
+*******************************************************************************/
+
+if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
+	local method POPULATION+GH
+}
+
+if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
+   di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
+   di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
+   di in gr "The -method- option is replaced by GH."
+   local method GH
+}
+else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
+	di in red "The number of patterns is too high for the chosen method"
+	exit
+}
+else if "`method'"=="" {
+    if `nbpatmax'<2000 {
+        local method GH
+    }
+    else  {
+        local method POPULATION+GH
+    }
+}
+
+if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
+	di in red "Invalid method name"
+	exit
+}
+
+/*******************************************************************************
+AFFICHAGE DES PARAMETRES
+*******************************************************************************/
+
+if "`longitudinal'"==""{
+	di in gr "Number of individuals in the first group: " in ye `n0'
+	di in gr "Number of individuals in the second group: " in ye `n1'
+	di in green "Group effect: " in ye `gamma'
+	di in  gr "Variance of the latent trait in the first group: " in ye `var0'
+	di in  gr "Variance of the latent trait in the second group: " in ye `var1'
+}
+else{
+	di in gr "Number of individuals at each time:  " in ye `n0'
+	di in green "Time effect: " in ye `gamma'
+	di in  gr "Variance matrix of the latent trait: " 
+	matrix list `matvar',noheader
+	di
+}
+di in gr "Number of items: " in ye `nbitems'
+di in green "Difficulties parameters of the items: "
+tempname dd
+matrix `dd'=`d''
+local items
+forvalues i=1/`nbitems' {
+   local items "`items' item`i'"
+}
+local modalities
+forvalues i=1/`=`nbmodat'-1' {
+   local modalities "`modalities' delta_`i'"
+}
+
+matrix colnames `dd'=`items'
+matrix rownames `dd'=`modalities'
+
+
+di
+tempname ddt
+matrix `ddt' = `dd''
+matrix colnames `ddt'=`modalities'
+matrix rownames `ddt'=`items'
+if "`html'" != "" {
+	matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficultés dans l'autre sens */
+}
+else {
+	matrix list `dd',noblank nohalf noheader
+}
+di
+
+if "`detail'"!="" & "`html'" == ""{
+	di in gr "Method:  " in ye "`method'"
+	di in gr "Number of studied response's patterns: " in ye `nbpatmax'
+}
+matrix `dd'=`d'
+local gamma=`gamma'
+
+local tmp=1
+qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
+forvalues j=1/`nbitems' {
+	forvalues m=1/`=`nbmodat'-1' {
+		qui matrix `db'[`tmp',1]=`d'[`j',`m']
+		local ++tmp
+	}
+}
+
+
+/*******************************************************************************
+CREATION DU DATASET ATTENDU 
+*******************************************************************************/
+
+if "`data'"=="" {
+	clear
+	if "`method'"!="POPULATION+GH"{
+		local temp=`nbmodat'^(`nbtotitems')
+		qui range x 0 `=`temp'-1' `temp'
+		qui g t=x
+		loc i=`nbtotitems'
+		qui count if t>0
+		loc z=r(N)
+		qui while `z'>0 {
+			qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
+			qui replace t=mod(t,`nbmodat'^`=`i'-1')
+			qui count if t>0
+			loc z=r(N)
+			loc i=`i'-1
+		}
+		drop t
+		if "`longitudinal'"==""{
+			qui expand 2
+			qui gen group=0 in 1/`temp'
+			qui replace group=1 in `=`temp'+1'/`=2*`temp''
+		}	
+	}
+	else { /*METHODE POPULATION (SIMULATION)*/
+		if "`longitudinal'"==""{
+			*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'*`gamma'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
+			qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
+			qui gen group=1
+			tempfile save1
+			qui save `save1',replace
+			qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
+			qui gen group=0
+			qui append using `save1'
+			*qui save d:\tmp,replace
+            bysort group:su lt
+			qui drop lt1
+			qui contract item* group, freq(freq)
+			qui count
+			local patobs=r(N)
+			if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
+				qui gen keep=0
+				qui gsort +group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+				qui gsort -group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n1''
+			}
+			else{
+				qui gen keep=1
+			}
+		}
+		else{
+			qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
+			forvalues j=1/`nbitems'{
+				rename itemA`j' item`j'
+				rename itemB`j' item`=`nbitems'+`j''
+			}
+			qui drop lt1 lt2
+			qui contract item*, freq(freq)
+			local patobs=r(N)
+			if `patobs'>=`=`n0'*`nbpatterns''{
+				qui gen keep=0
+				qui gsort -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+			}
+			else{
+			  qui gen keep=1
+			}
+		}
+		qui keep if keep==1
+		qui count
+		local retain=r(N)
+		di "Number of kept patterns:`retain'"
+		local method GH
+	}
+	if "`longitudinal'"==""{
+		qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
+		qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
+		qui gen var1=`var0' if group==0
+		qui replace var1=`var1' if group==1
+	}
+	else{
+		qui gen mean1=`mean1'
+		qui gen mean2=`mean2'
+	}
+	/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
+	if "`method'"=="GH" {
+		local temp=`nbmodat'^(`nbtotitems')
+		local diff0=0
+		qui gen proba=.
+		local dixj=10
+		qui count
+		local tmp=r(N)
+
+		forvalues i=1/`tmp' {
+			local dix=floor(`tmp'/10)
+			if mod(`i',`dix')==0 & "`html'"=="" {
+			    qui su proba
+				local tmpprob=r(sum)
+				if "`dixj'"!="10" {
+					di ".." _c
+				}
+				*di "`dixj'% (`tmpprob')" _c
+				di "`dixj'%" _c
+				local dixj=`dixj'+10
+			}
+			forvalues t=1/`nbt'{
+				local int`t'=1			 
+				forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+					qui su item`j' in `i'
+					local rep=r(mean)
+					local diff0=0
+					local diff1=`dlong'[`j',1]
+					local sum "1+exp(x`t'-`diff1')"
+					forvalues m=2/`=`nbmodat'-1' {
+					   local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+					   local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+					}
+					local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+				}
+			}	
+			if "`longitudinal'"==""{
+				qui su mean1 in `i'
+				local mean=r(mean)
+				qui su var1 in `i'
+				local vart=r(mean)
+				*di "gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
+				*prout
+				qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+				qui replace proba=r(int) in `i'
+			}
+			else{
+				local int "`int1'*`int2'"
+				matrix mean=(`mean1',`mean2')
+				qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
+				qui replace proba=r(int) in `i'
+			}
+		}
+		di
+	}
+	else { /*if "`method'"!="GH"*/
+		qui gen proba=1
+		forvalues t=1/`nbt'{
+			forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+				local diff0=0
+				local diff1=`dlong'[`i',1]
+				qui gen eps0=1
+				qui gen eps1=exp(mean`t'-`diff1')
+				qui gen d=eps0+eps1
+				forvalues m=2/`=`nbmodat'-1' {
+					local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
+					qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
+					qui replace d=d+eps`m'
+				}
+				local listeps
+				forvalues m=0/`=`nbmodat'-1' {
+					qui replace proba=proba*eps`m'/d if item`i'==`m'
+					local listeps `listeps' eps`m'
+				}
+				qui drop `listeps' d
+			}
+		}
+		if "`method'"=="MEAN+GH" {
+			set tracedepth 1
+			if "`longitudinal'"==""{
+				qui gen keep=0
+				qui gsort -group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui gsort +group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+				qui su proba if group==0
+				local sumproba0=r(sum)*100
+				qui su proba if group==1
+				local sumproba1=r(sum)*100
+			}
+			else{
+				qui gen keep=0
+				qui gsort -proba
+				local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+			}
+
+			qui drop keep proba
+			local diff0=0
+			qui gen proba=.
+			qui count
+			local nnew=r(N)
+			di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
+			if "`longitudinal'"==""{
+				di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
+			}
+			local dixj=10
+			forvalues i=1/`nnew' {
+				local dix=floor(`nnew'/10)
+				if mod(`i',`dix')==0 & "`html'"=="" {
+				    qui su proba
+					local sum=r(sum)
+					if "`dixj'"!="10" {
+						di ".." _c
+					}
+					di "`dixj'% (`sum')" _c
+					local dixj=`dixj'+10
+				}
+				forvalues t=1/`nbt'{
+					local int`t'=1
+					forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+						qui su item`j' in `i'
+						local rep=r(mean)
+						local diff0=0
+						local diff1=`dlong'[`j',1]
+						local sum "1+exp(x`t'-`diff1')"
+						forvalues m=2/`=`nbmodat'-1' {
+							local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+							local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+						}
+						local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+					}
+				}
+				if "`longitudinal'"==""{
+					qui su mean1 in `i'
+					local mean=r(mean)
+					qui su var1 in `i'
+					local vart=r(mean)
+					*di "qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
+					qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+					qui replace proba=r(int) in `i'
+				}
+				else{
+					local int "`int1'*`int2'"
+					matrix mean=(`mean1',`mean2')
+					qui gausshermite `int',mu(mean) var(`matvar') display
+					qui replace proba=r(int) in `i'
+				}
+			}
+		}
+	}
+	qui gen eff=proba
+	qui gen eff2=.  
+   
+	if "`longitudinal'"==""{
+		qui keep item* eff* group proba
+		local p1=1/`n1'
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p1') if group==1
+		qui replace eff2=floor(eff/`p0') if group==0
+		qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
+		qui su eff2 if group==1
+		local aff1=r(sum)
+		qui su eff2 if group==0
+		local aff0=r(sum)
+
+		local unaff1=`n1'-`aff1'
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort + group - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+		qui gsort - group - eff
+		qui replace eff2=eff2+1 in 1/`unaff1'
+
+		qui drop if eff2==0
+		qui gsort group item*
+		qui expand eff2
+	}
+	else{
+		qui keep item* eff* proba
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p0')
+		qui replace eff=eff-eff2*`p0'
+		qui su eff2
+		local aff0=r(sum)
+
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+
+		qui drop if eff2==0
+		qui gsort item*
+		qui expand eff2
+	}
+   qui drop proba eff eff2
+}
+
+if "`html'" == "" {
+	qui save "d:\essai.dta", replace
+}
+qui alpha item*
+local alpha=r(alpha)
+
+if "`longitudinal'"==""{ /*TRANSVERSAL*/
+	qui gen groupc=-`n1'/(`n0'+`n1') if group==0
+	qui replace groupc=`n0'/(`n0'+`n1') if group==1
+	if `nbmodat'==2 {   /*DICHOTOMOUS CASE*/
+        if "`freeitems'"=="" {
+		      local offset "offset(offset)"
+			  local items
+        }
+        else {
+		      local offset
+		      local items "item1-item`nbitems'"
+        }
+		qui gen i=_n
+
+		tempname diff
+		matrix `diff'=`dd''
+
+		qui reshape long item, i(i)
+		qui rename item rep
+		qui rename _j item
+
+		qui gen  offset=0
+		forvalues i=1/`nbitems' {
+			qui replace offset=-`diff'[1,`i'] if item==`i'
+			qui gen item`i'=item==`i'
+			qui replace item`i'=-item`i'
+		}
+        if `var0'==`var1' { /*EQUAL VARIANCES*/
+	       *constraint 1 _cons=`=ln(`var')'
+		   *qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
+	       if  "`freevar'"=="" {
+		      constraint 1 _cons=`=sqrt(`var0')'
+		      local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
+		}
+		else {/*UNEQUAL VARIANCES*/
+		   tempvar G0 G1
+		   qui gen `G0'=group==0
+		   qui gen `G1'=group==1
+		   qui eq B0: `G0'
+		   qui eq B1: `G1'
+	       constraint 1 _cons=0
+	       if  "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
+			   constraint 2 `G0'=`=sqrt(`var0')'
+			   constraint 3 `G1'=`=sqrt(`var1')'
+		       constraint 1 _cons=`=sqrt(`var0')'
+		       local constvar "constraint(1 2 3)"
+		   }
+		   else { /*FREE UNEQUAL VARIANCES*/
+		       local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
+		}
+		tempname b V/*LONGITUDINAL*/
+		local row = 1
+	}
+	else { /*POLYTOMOUS CASE*/
+		matrix `db'=`db''
+		if "`freeitems'"=="" {
+		   local fi "fixed(`db') fixedmu"
+		   local row=1
+		}
+		else {
+		   local fi
+		   local row=(`nbmodat'-1)*`nbitems'+1
+		}
+	    if `var0'==`var1' {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvar(`var0')"
+		   }
+		   else {
+		       local fv 
+			   *noi pcm item*, `fi' covariates(groupc) 
+
+		   }
+		}
+		else {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvargroupc(`var')"
+		   }
+		   else {
+		       local fv "vargroupc"
+		   }
+        }
+	      *di "jk pcm item*, `fi' covariates(groupc) `fv'"
+		   	/********************************ESSAI 23 mai 2014*/
+			qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`n1')
+			qui gen group=1
+			tempfile save1
+			qui save `save1',replace
+			qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`n0')
+			qui gen group=0
+			qui append using `save1'
+			qui gen groupc=group-0.5
+			*di "ON A SIMULE"
+			**********************************FIN ESSAI 23 mai 2014*/
+
+		 qui pcm item*, `fi' covariates(groupc) `fv'
+	}
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,`row']
+	local se=`V'[`row',`row']^.5
+}
+else{ /*LONGITUDINAL*/ 
+	qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,1]
+	local se=`V'[1,1]^.5
+	local n1=`n0'
+}
+local poweruni=1-normal(1.96-`gamma'/`se')
+
+if "`html'" == "" {
+	di
+	di
+}
+if "`detail'"!=""{
+	di in gr "{hline 91}"
+	di _col(60)  "Estimation with the "
+	di _col(50)  "Cramer-Rao bound" _col(75) "classical formula"
+	di in gr "{hline 91}"
+}
+
+if "`longitudinal'"==""{
+	local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
+	local nbw:word count `var'
+	if `nbw' == 2 { /* variance commune */
+		local varc = ((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
+	}
+	else {
+		local varc = `var'
+	}
+	local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`varc'))-1.96)
+	local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`varc'))^2)*(1.96+invnorm(`poweruni'))^2
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the group effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+else{
+	local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
+	local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the time effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+
+if `expectedpower'!=-1 {
+   qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
+   local expn_1=r(N_1)
+   local expn_2=r(N_2)
+   local expn2=`expn_1'*`ratio'
+   di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _c
+   if "`detail'"!="" {
+      di _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
+   }
+}
+
+
+return scalar EstGamma=`gammaest'
+return scalar CRbound=`=`se'^2'
+return scalar CRPower=`poweruni'
+return scalar ClPower=`clpower'
+return scalar ClSS=`clnsn'
+return scalar Ratio=`ratio'
+return scalar CronbachAlpha=`alpha'
+
+
+if "`graph'" != "" {
+	local x = "`min'(`step')`max'"
+	matrix res=J(15,5,.)
+	matrix colnames res= n0 n1 gamma variance power
+	local l=1
+
+	if "`longitudinal'"==""{
+		forval var = `x' {
+			qui raschpower58, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
+			qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
+			local ++l
+		}
+		clear
+		qui svmat res,names(col)
+		
+		if "`html'" != "" {
+			qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
+			qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving'
+			qui graph use `c(tmpdir)'/`html'_planif_graph.gph
+			qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
+			di "
" + di " _char(34) " + } + else { + twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) + } + } + + else { + if `gcorr' != -1 { + local l=1 + forval var = `x' { + local cov = `gcorr'*`var' + local matv "`var',`cov'" " \ `cov',`var'" + qui raschpower58, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) + } + } + + if `gvar' != -1 { + matrix res=J(9,5,.) + matrix colnames res= n0 n1 gamma corr power + local l=1 + forvalues corr = `x' { + local cov = `corr'*`gvar' + local matv "`gvar',`cov'" " \ `cov',`gvar'" + qui raschpower58, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation) ytitle(Power) name(planif_graph,replace) + } + } + } + +//di in gr "Method: " in ye "`method'" + + if "`html'" != "" { + di "
" + } +} + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschpower59.ado b/Modules/ado/personal/r/raschpower59.ado new file mode 100644 index 0000000..12f3469 --- /dev/null +++ b/Modules/ado/personal/r/raschpower59.ado @@ -0,0 +1,884 @@ +*! version 5.9 : September 26th, 2014 +*! Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot +************************************************************************************************************ +* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals +* +* Version 1 : January 25th, 2010 (Jean-Benoit Hardouin) +* Version 1.1 : January 26th, 2010 (Jean-Benoit Hardouin) +* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin) +* version 1.3 : May 2nd, 2011 (Jean-Benoit Hardouin) +* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections +* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections +* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results +* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method +* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections +* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design +* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option +* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items +* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups +* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups +* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug +* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display +* version 5.5 : April 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : graph option for longitudinal design +* version 5.6 : April 10th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : corrections of bugs +* version 5.7 : June 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : minor corrections +* version 5.8 : July 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : correction of a bug when the variances are different in the 2 groups (transversal) +* version 5.9 : September 26th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : fixed of a bug with the graph option (correlation could be greater than one) +* +* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr +* Myriam Blanchin, myriam.blanchin@univ-nantes.fr +* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health" +* Faculty of Pharmaceutical Sciences - University of Nantes - France +* http://www.sphere-nantes.org +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschpower59,rclass +syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1) min(real 0.25) step(real 1) max(real 9)] +version 11 + +if "`html'" != "" { + set scheme sj + local htmlregion "graphregion(fcolor(white) ifcolor(white))" + di "" + di "
"
+}
+
+tempfile raschpowerfile
+capture qui save "`raschpowerfile'",replace
+tempname db d dlong matvar
+
+/*******************************************************************************
+DEFINITION DES PARAMETRES
+*******************************************************************************/
+
+if "`graph'" != "" & "`longitudinal'" != "" {
+	if `gvar' != -1 & `gcorr' != -1 {
+		di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
+		error 198
+	}
+	if `gvar' == -1 & `gcorr' == -1 {
+		di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
+		error 198
+	}
+}
+
+if "`difficulties'"=="" {
+   matrix `d'=[-1\-0.5\0\0.5\1]
+}
+else {
+   matrix `d'=`difficulties'
+}
+local nbitems=rowsof(`d')
+local nbmodat=colsof(`d')+1
+
+if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
+	local nbt=1
+	local nbtotitems=`nbitems'
+	local nbpatmax=2*`nbmodat'^`nbitems'
+	if "`var'"==""{
+		local var=1
+		local var0=1
+		local var1=1
+	}
+	else{
+		capture confirm number `var'
+		if !_rc {
+			local var0=`var'
+			local var1=`var'
+		}
+		else{
+		   local nbw:word count `var'
+		   local grp=1
+		   if `nbw'==2 {
+				local t1: word 1 of `var'
+                capture confirm number `t1'
+				if !_rc {
+					local t2: word 2 of `var'
+                    capture confirm number `t2'
+                    if !_rc {
+                       local var0=`t1'
+                       local var1=`t2'
+                       local grp=2
+                    }
+				}
+			}
+			if `nbw'!=2|`grp'==1 {
+				capture confirm matrix `var'
+			    if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
+				    matrix `matvar'=`var'
+					local var0=`matvar'[1,1]
+					local var1=`matvar'[1,1]
+			    }
+			    else{
+					di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
+					error 198
+					exit
+			    }
+		    }
+		}
+	}
+	matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
+    local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
+
+	local sumd=0
+	forvalues numit=1/`nbitems'{
+		local sumd=`sumd'+`d'[`numit',1]
+	}
+	local sumd=`sumd'/`nbitems'
+	if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
+		if "`html'" == "" {
+			di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
+		}
+	}
+
+}
+else{ /*CAS LONGITUDINAL*/
+	local nbt=2
+	local nbtotitems=2*`nbitems'
+	local nbpatmax=`nbmodat'^(`nbitems'*2)
+	local n1=0
+	local mean1=0
+	local mean2=`mean1'+`gamma'
+	if "`var'"==""{
+		matrix `matvar'=(1,0\0,1)
+	}
+	else{
+		matrix `matvar'=`var'
+		capture confirm matrix `matvar'
+		if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
+			di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
+			error 198
+			exit
+		}
+	}
+	matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
+	matrix `dlong'[1,1]=`d'
+	matrix `dlong'[`=`nbitems'+1',1]=`d'
+}
+
+/*
+if "`max'" == "" {
+	local max = 9 + `step'/2
+}
+else {
+	local max = `max' + `step'/2
+}*/
+
+forval v = `min'(`step')`max' {
+	local w = `v'
+}
+if `w' < `max' {
+	local max = `max' + `step'
+}
+if "`longitudinal'"!="" & `gvar'!=-1 {                
+	local max = min(`max',0.99999)    /* pour avoir des corrélations < 1 */
+}
+
+/*******************************************************************************
+DEFINITION DE LA METHODE
+*******************************************************************************/
+
+if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
+	local method POPULATION+GH
+}
+
+if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
+   di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
+   di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
+   di in gr "The -method- option is replaced by GH."
+   local method GH
+}
+else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
+	di in red "The number of patterns is too high for the chosen method"
+	exit
+}
+else if "`method'"=="" {
+    if `nbpatmax'<2000 {
+        local method GH
+    }
+    else  {
+        local method POPULATION+GH
+    }
+}
+
+if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
+	di in red "Invalid method name"
+	exit
+}
+
+/*******************************************************************************
+AFFICHAGE DES PARAMETRES
+*******************************************************************************/
+
+if "`longitudinal'"==""{
+	di in gr "Number of individuals in the first group: " in ye `n0'
+	di in gr "Number of individuals in the second group: " in ye `n1'
+	di in green "Group effect: " in ye `gamma'
+	di in  gr "Variance of the latent trait in the first group: " in ye `var0'
+	di in  gr "Variance of the latent trait in the second group: " in ye `var1'
+}
+else{
+	di in gr "Number of individuals at each time:  " in ye `n0'
+	di in green "Time effect: " in ye `gamma'
+	di in  gr "Variance matrix of the latent trait: " 
+	matrix list `matvar',noheader
+	di
+}
+di in gr "Number of items: " in ye `nbitems'
+di in green "Difficulties parameters of the items: "
+tempname dd
+matrix `dd'=`d''
+local items
+forvalues i=1/`nbitems' {
+   local items "`items' item`i'"
+}
+local modalities
+forvalues i=1/`=`nbmodat'-1' {
+   local modalities "`modalities' delta_`i'"
+}
+
+matrix colnames `dd'=`items'
+matrix rownames `dd'=`modalities'
+
+
+di
+tempname ddt
+matrix `ddt' = `dd''
+matrix colnames `ddt'=`modalities'
+matrix rownames `ddt'=`items'
+if "`html'" != "" {
+	matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficultés dans l'autre sens */
+}
+else {
+	matrix list `dd',noblank nohalf noheader
+}
+di
+
+if "`detail'"!="" & "`html'" == ""{
+	di in gr "Method:  " in ye "`method'"
+	di in gr "Number of studied response's patterns: " in ye `nbpatmax'
+}
+matrix `dd'=`d'
+local gamma=`gamma'
+
+local tmp=1
+qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
+forvalues j=1/`nbitems' {
+	forvalues m=1/`=`nbmodat'-1' {
+		qui matrix `db'[`tmp',1]=`d'[`j',`m']
+		local ++tmp
+	}
+}
+
+
+/*******************************************************************************
+CREATION DU DATASET ATTENDU 
+*******************************************************************************/
+
+if "`data'"=="" {
+	clear
+	if "`method'"!="POPULATION+GH"{
+		local temp=`nbmodat'^(`nbtotitems')
+		qui range x 0 `=`temp'-1' `temp'
+		qui g t=x
+		loc i=`nbtotitems'
+		qui count if t>0
+		loc z=r(N)
+		qui while `z'>0 {
+			qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
+			qui replace t=mod(t,`nbmodat'^`=`i'-1')
+			qui count if t>0
+			loc z=r(N)
+			loc i=`i'-1
+		}
+		drop t
+		if "`longitudinal'"==""{
+			qui expand 2
+			qui gen group=0 in 1/`temp'
+			qui replace group=1 in `=`temp'+1'/`=2*`temp''
+		}	
+	}
+	else { /*METHODE POPULATION (SIMULATION)*/
+		if "`longitudinal'"==""{
+			*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'*`gamma'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
+			qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
+			qui gen group=1
+			tempfile save1
+			qui save `save1',replace
+			qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
+			qui gen group=0
+			qui append using `save1'
+			*qui save d:\tmp,replace
+            bysort group:su lt
+			qui drop lt1
+			qui contract item* group, freq(freq)
+			qui count
+			local patobs=r(N)
+			if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
+				qui gen keep=0
+				qui gsort +group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+				qui gsort -group -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n1''
+			}
+			else{
+				qui gen keep=1
+			}
+		}
+		else{
+			qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
+			forvalues j=1/`nbitems'{
+				rename itemA`j' item`j'
+				rename itemB`j' item`=`nbitems'+`j''
+			}
+			qui drop lt1 lt2
+			qui contract item*, freq(freq)
+			local patobs=r(N)
+			if `patobs'>=`=`n0'*`nbpatterns''{
+				qui gen keep=0
+				qui gsort -freq
+				qui replace keep=1 in 1/`=`nbpatterns'*`n0''
+			}
+			else{
+			  qui gen keep=1
+			}
+		}
+		qui keep if keep==1
+		qui count
+		local retain=r(N)
+		di "Number of kept patterns:`retain'"
+		local method GH
+	}
+	if "`longitudinal'"==""{
+		qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
+		qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
+		qui gen var1=`var0' if group==0
+		qui replace var1=`var1' if group==1
+	}
+	else{
+		qui gen mean1=`mean1'
+		qui gen mean2=`mean2'
+	}
+	/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
+	if "`method'"=="GH" {
+		local temp=`nbmodat'^(`nbtotitems')
+		local diff0=0
+		qui gen proba=.
+		local dixj=10
+		qui count
+		local tmp=r(N)
+
+		forvalues i=1/`tmp' {
+			local dix=floor(`tmp'/10)
+			if mod(`i',`dix')==0 & "`html'"=="" {
+			    qui su proba
+				local tmpprob=r(sum)
+				if "`dixj'"!="10" {
+					di ".." _c
+				}
+				*di "`dixj'% (`tmpprob')" _c
+				di "`dixj'%" _c
+				local dixj=`dixj'+10
+			}
+			forvalues t=1/`nbt'{
+				local int`t'=1			 
+				forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+					qui su item`j' in `i'
+					local rep=r(mean)
+					local diff0=0
+					local diff1=`dlong'[`j',1]
+					local sum "1+exp(x`t'-`diff1')"
+					forvalues m=2/`=`nbmodat'-1' {
+					   local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+					   local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+					}
+					local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+				}
+			}	
+			if "`longitudinal'"==""{
+				qui su mean1 in `i'
+				local mean=r(mean)
+				qui su var1 in `i'
+				local vart=r(mean)
+				*di "gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
+				*prout
+				qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+				qui replace proba=r(int) in `i'
+			}
+			else{
+				local int "`int1'*`int2'"
+				matrix mean=(`mean1',`mean2')
+				qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
+				qui replace proba=r(int) in `i'
+			}
+		}
+		di
+	}
+	else { /*if "`method'"!="GH"*/
+		qui gen proba=1
+		forvalues t=1/`nbt'{
+			forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+				local diff0=0
+				local diff1=`dlong'[`i',1]
+				qui gen eps0=1
+				qui gen eps1=exp(mean`t'-`diff1')
+				qui gen d=eps0+eps1
+				forvalues m=2/`=`nbmodat'-1' {
+					local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
+					qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
+					qui replace d=d+eps`m'
+				}
+				local listeps
+				forvalues m=0/`=`nbmodat'-1' {
+					qui replace proba=proba*eps`m'/d if item`i'==`m'
+					local listeps `listeps' eps`m'
+				}
+				qui drop `listeps' d
+			}
+		}
+		if "`method'"=="MEAN+GH" {
+			set tracedepth 1
+			if "`longitudinal'"==""{
+				qui gen keep=0
+				qui gsort -group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui gsort +group -proba
+				local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+				qui su proba if group==0
+				local sumproba0=r(sum)*100
+				qui su proba if group==1
+				local sumproba1=r(sum)*100
+			}
+			else{
+				qui gen keep=0
+				qui gsort -proba
+				local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
+				qui replace keep=1 in 1/`min'
+				qui keep if keep==1
+			}
+
+			qui drop keep proba
+			local diff0=0
+			qui gen proba=.
+			qui count
+			local nnew=r(N)
+			di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
+			if "`longitudinal'"==""{
+				di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
+			}
+			local dixj=10
+			forvalues i=1/`nnew' {
+				local dix=floor(`nnew'/10)
+				if mod(`i',`dix')==0 & "`html'"=="" {
+				    qui su proba
+					local sum=r(sum)
+					if "`dixj'"!="10" {
+						di ".." _c
+					}
+					di "`dixj'% (`sum')" _c
+					local dixj=`dixj'+10
+				}
+				forvalues t=1/`nbt'{
+					local int`t'=1
+					forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
+						qui su item`j' in `i'
+						local rep=r(mean)
+						local diff0=0
+						local diff1=`dlong'[`j',1]
+						local sum "1+exp(x`t'-`diff1')"
+						forvalues m=2/`=`nbmodat'-1' {
+							local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
+							local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
+						}
+						local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
+					}
+				}
+				if "`longitudinal'"==""{
+					qui su mean1 in `i'
+					local mean=r(mean)
+					qui su var1 in `i'
+					local vart=r(mean)
+					*di "qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
+					qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
+					qui replace proba=r(int) in `i'
+				}
+				else{
+					local int "`int1'*`int2'"
+					matrix mean=(`mean1',`mean2')
+					qui gausshermite `int',mu(mean) var(`matvar') display
+					qui replace proba=r(int) in `i'
+				}
+			}
+		}
+	}
+	qui gen eff=proba
+	qui gen eff2=.  
+   
+	if "`longitudinal'"==""{
+		qui keep item* eff* group proba
+		local p1=1/`n1'
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p1') if group==1
+		qui replace eff2=floor(eff/`p0') if group==0
+		qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
+		qui su eff2 if group==1
+		local aff1=r(sum)
+		qui su eff2 if group==0
+		local aff0=r(sum)
+
+		local unaff1=`n1'-`aff1'
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort + group - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+		qui gsort - group - eff
+		qui replace eff2=eff2+1 in 1/`unaff1'
+
+		qui drop if eff2==0
+		qui gsort group item*
+		qui expand eff2
+	}
+	else{
+		qui keep item* eff* proba
+		local p0=1/`n0'
+		qui replace eff2=floor(eff/`p0')
+		qui replace eff=eff-eff2*`p0'
+		qui su eff2
+		local aff0=r(sum)
+
+		local unaff0=`n0'-`aff0'
+		qui gen efftmp=eff2
+		qui gsort - eff
+		qui replace eff2=eff2+1 in 1/`unaff0'
+
+		qui drop if eff2==0
+		qui gsort item*
+		qui expand eff2
+	}
+   qui drop proba eff eff2
+}
+
+if "`html'" == "" {
+	qui save "d:\essai.dta", replace
+}
+qui alpha item*
+local alpha=r(alpha)
+
+if "`longitudinal'"==""{ /*TRANSVERSAL*/
+	qui gen groupc=-`n1'/(`n0'+`n1') if group==0
+	qui replace groupc=`n0'/(`n0'+`n1') if group==1
+	if `nbmodat'==2 {   /*DICHOTOMOUS CASE*/
+        if "`freeitems'"=="" {
+		      local offset "offset(offset)"
+			  local items
+        }
+        else {
+		      local offset
+		      local items "item1-item`nbitems'"
+        }
+		qui gen i=_n
+
+		tempname diff
+		matrix `diff'=`dd''
+
+		qui reshape long item, i(i)
+		qui rename item rep
+		qui rename _j item
+
+		qui gen  offset=0
+		forvalues i=1/`nbitems' {
+			qui replace offset=-`diff'[1,`i'] if item==`i'
+			qui gen item`i'=item==`i'
+			qui replace item`i'=-item`i'
+		}
+        if `var0'==`var1' { /*EQUAL VARIANCES*/
+	       *constraint 1 _cons=`=ln(`var')'
+		   *qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
+	       if  "`freevar'"=="" {
+		      constraint 1 _cons=`=sqrt(`var0')'
+		      local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
+		}
+		else {/*UNEQUAL VARIANCES*/
+		   tempvar G0 G1
+		   qui gen `G0'=group==0
+		   qui gen `G1'=group==1
+		   qui eq B0: `G0'
+		   qui eq B1: `G1'
+	       constraint 1 _cons=0
+	       if  "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
+			   constraint 2 `G0'=`=sqrt(`var0')'
+			   constraint 3 `G1'=`=sqrt(`var1')'
+		       constraint 1 _cons=`=sqrt(`var0')'
+		       local constvar "constraint(1 2 3)"
+		   }
+		   else { /*FREE UNEQUAL VARIANCES*/
+		       local constvar "constraint(1)"
+		   }
+		   qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
+		}
+		tempname b V/*LONGITUDINAL*/
+		local row = 1
+	}
+	else { /*POLYTOMOUS CASE*/
+		matrix `db'=`db''
+		if "`freeitems'"=="" {
+		   local fi "fixed(`db') fixedmu"
+		   local row=1
+		}
+		else {
+		   local fi
+		   local row=(`nbmodat'-1)*`nbitems'+1
+		}
+	    if `var0'==`var1' {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvar(`var0')"
+		   }
+		   else {
+		       local fv 
+			   *noi pcm item*, `fi' covariates(groupc) 
+
+		   }
+		}
+		else {
+	       if  "`freevar'"=="" {
+		       local fv "fixedvargroupc(`var')"
+		   }
+		   else {
+		       local fv "vargroupc"
+		   }
+        }
+	      *di "jk pcm item*, `fi' covariates(groupc) `fv'"
+		   	/********************************ESSAI 23 mai 2014*/
+			qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`n1')
+			qui gen group=1
+			tempfile save1
+			qui save `save1',replace
+			qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`n0')
+			qui gen group=0
+			qui append using `save1'
+			qui gen groupc=group-0.5
+			*di "ON A SIMULE"
+			**********************************FIN ESSAI 23 mai 2014*/
+
+		 qui pcm item*, `fi' covariates(groupc) `fv'
+	}
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,`row']
+	local se=`V'[`row',`row']^.5
+}
+else{ /*LONGITUDINAL*/ 
+	qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
+	tempname b V
+	matrix `b'=e(b)
+	matrix `V'=e(V)
+	local gammaest=`b'[1,1]
+	local se=`V'[1,1]^.5
+	local n1=`n0'
+}
+local poweruni=1-normal(1.96-`gamma'/`se')
+
+if "`html'" == "" {
+	di
+	di
+}
+if "`detail'"!=""{
+	di in gr "{hline 91}"
+	di _col(60)  "Estimation with the "
+	di _col(50)  "Cramer-Rao bound" _col(75) "classical formula"
+	di in gr "{hline 91}"
+}
+
+if "`longitudinal'"==""{
+	local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
+	local nbw:word count `var'
+	if `nbw' == 2 { /* variance commune */
+		local varc = ((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
+	}
+	else {
+		local varc = `var'
+	}
+	local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`varc'))-1.96)
+	local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`varc'))^2)*(1.96+invnorm(`poweruni'))^2
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the group effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+else{
+	local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
+	local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
+	local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
+	if "`detail'"==""{
+		di in gr "{hline 65}"
+		di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
+		di in gr "{hline 65}"
+	}
+	else{
+		if "`gammafixed'"==""  {
+		   di in green "Estimated value of the time effect" _col(59) in ye  %7.2f `gammaest'
+		}
+		di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
+		di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
+		di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
+		di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
+		di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
+		di in gr "{hline 91}"
+	}
+}
+
+if `expectedpower'!=-1 {
+   qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
+   local expn_1=r(N_1)
+   local expn_2=r(N_2)
+   local expn2=`expn_1'*`ratio'
+   di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _c
+   if "`detail'"!="" {
+      di _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
+   }
+}
+
+
+return scalar EstGamma=`gammaest'
+return scalar CRbound=`=`se'^2'
+return scalar CRPower=`poweruni'
+return scalar ClPower=`clpower'
+return scalar ClSS=`clnsn'
+return scalar Ratio=`ratio'
+return scalar CronbachAlpha=`alpha'
+
+
+if "`graph'" != "" {
+	local x = "`min'(`step')`max'"
+	matrix res=J(15,5,.)
+	matrix colnames res= n0 n1 gamma variance power
+	local l=1
+
+	if "`longitudinal'"==""{
+		forval var = `x' {
+			qui raschpower59, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
+			qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
+			local ++l
+		}
+		clear
+		qui svmat res,names(col)
+		
+		if "`html'" != "" {
+			qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
+			qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving'
+			qui graph use `c(tmpdir)'/`html'_planif_graph.gph
+			qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
+			di "
" + di " _char(34) " + } + else { + twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) + } + } + + else { + if `gcorr' != -1 { + local l=1 + forval var = `x' { + local cov = `gcorr'*`var' + local matv "`var',`cov'" " \ `cov',`var'" + qui raschpower59, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) + } + } + + if `gvar' != -1 { + matrix res=J(9,5,.) + matrix colnames res= n0 n1 gamma corr power + local l=1 + forvalues corr = `x' { + local cov = `corr'*`gvar' + local matv "`gvar',`cov'" " \ `cov',`gvar'" + qui raschpower59, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal' + qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower)) + local ++l + } + clear + qui svmat res,names(col) + if "`html'" != "" { + qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw" + qui graph twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation, margin(top)) ytitle(Power) name(planif_graph,replace) `saving' + qui graph use `c(tmpdir)'/`html'_planif_graph.gph + qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace + di "
" + di " _char(34) " + } + else { + twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) + } + } + } + +//di in gr "Method: " in ye "`method'" + + if "`html'" != "" { + di "
" + } +} + +capture qui use `raschpowerfile',clear + +end diff --git a/Modules/ado/personal/r/raschres.ado b/Modules/ado/personal/r/raschres.ado new file mode 100644 index 0000000..507e93c --- /dev/null +++ b/Modules/ado/personal/r/raschres.ado @@ -0,0 +1,235 @@ +*! Version 1.2 June 3, 2013 +************************************************************************************************************ +* Stata program : raschres +* Analysis of the residuals of the Rasch model +* Version 1 : June 16, 2010 +* Version 1.1 : July 15, 2011 +* Version 1.2 : June 3, 2013 /*formatting outputs*/ +* +* +* Jean-benoit Hardouin, phD, Assistant Professor +* EA4275 - SPHERE +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* +* Copyright 2010-2013 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define raschres,rclass +syntax varlist [if] [in] , diff(string) theta(varname) [genres(string) genfit(string) vargroup(varname) PCAres DETails] +tempfile saveraschres +if "`if'"!=""|"`in'"!="" { + *keep `if' `in' +} +*qui save `saveraschres',replace + +tempname res + +qui count +local ntotal=r(N) +tokenize `varlist' +local nbitems: word count `varlist' +qui tempname score lt +qui genscore `varlist',score(`score') +qui gen `lt'=`theta' +forvalues i=1/`nbitems' { + local z2`i'=0 +} + +forvalues i=1/`nbitems'{ + qui tempname p`i' res`i' + qui gen `p`i''=exp(`lt'-`diff'[1,`i'])/(1+exp(`lt'-`diff'[1,`i'])) + qui gen `res'`i'=(1-`p`i'')/sqrt(`p`i''*(1-`p`i'')) if ``i''==1 + qui replace `res'`i'=(0-`p`i'')/sqrt(`p`i''*(1-`p`i'')) if ``i''==0 +} +su +local chi2=0 +forvalues i=1/`nbitems' { + qui tempname res2 + qui gen `res2'`i'=`res'`i'^2 + qui su `res2'`i' + local chi2=`chi2'+`r(sum)' + label variable `res'`i' "``i''" +} +su +tempname cor Ev +matrix `cor'=J(`nbitems',`nbitems',.) +local list +forvalues i=1/`nbitems' { + forvalues j=1/`nbitems' { + qui corr `res'`i' `res'`j' + matrix `cor'[`i',`j']=r(rho) + } + local list "`list' ``i''" +} +matrix colname `cor'=`list' +matrix rowname `cor'=`list' +qui pca `res'* +matrix `Ev'=e(Ev) + +tempname lt2 ltcl group df nbmiss rep total +qui egen `nbmiss'=rowmiss(`varlist') +qui gen `rep'=`nbitems'-`nbmiss' +qui gen `lt2'=`lt' if `score'!=0&`score'!=`rep' +if "`vargroup'"=="" { + qui gengroup `lt2', newvar(`group') cont det minsize(33) +} +else { + qui `group'=`vargroup' +} +qui su `group' +local maxgroup=r(max) + +if "`details'"!="" { + di "{hline 42}" + di _col(12) "Min" _col(29) "Max" + di "{dup 42:-}" + di "" _col(8) "" _col(14) "Latent" _col(28) "" _col(31) "Latent" _col(53) "" + di "Group" _col(8) "Score" _col(15) "trait" _col(25) "Score" _col(32) "trait" _col(42) "n" + di "{hline 42}" + forvalues i=1/`maxgroup' { + qui count if `group'==`i' + local n`i'=r(N) + qui su `score' if `group'==`i' + local scoremin`i'=r(min) + local scoremax`i'=r(max) + qui su `lt' if `group'==`i' + local ltmin`i'=r(min) + local ltmax`i'=r(max) + di "`i'" _col(9) %4.0f `scoremin`i'' _col(14) %6.3f `ltmin`i'' _col(26) %4.0f `scoremax`i'' _col(31) %6.3f `ltmax`i'' _col(39) %4.0f `n`i'' + } + di "{hline 42}" +} + +local nj=0 +forvalues i=1/`nbitems' { + qui count if ``i''!=. + local nj=`nj'+r(N) +} +qui gen `df'=(`nj'-(`ntotal' + `nbitems' - 1 ))/`nj'*`rep' +qui gen `total' =`score' +local mult=(`nj'-(`ntotal' + `nbitems' - 1 ))/`nj' + + +forvalues i=1/`nbitems' { + qui count if (`total'!=0&`total'!=`rep')&``i''!=. + local mult`i'=r(N) + local df`i'=`mult'*`mult`i'' + tempname res2`i' + qui gen `res2`i''=(`res'`i')^2 + qui su `res2`i'' if `total'!=0&`total'!=`rep' + local sumsq`i'=r(sum) + local fit`i'=(`sumsq`i''-`df`i'')/sqrt(2*`df`i'') +} + +qui gen `ltcl'=. +forvalues g=1/`maxgroup' { + qui su `lt' if `group'==`g' + local ltgroup`g'=r(mean) + local N`g'=r(N) + qui replace `ltcl'=`ltgroup`g'' if `group'==`g' +} +forvalues i=1/`nbitems' { + local chi`i'=0 + forvalues g=1/`maxgroup' { + qui su ``i'' if `group'==`g' + local po`i'_`g'=r(mean) + local pe`i'_`g'=exp(`ltgroup`g''-`diff'[1,`i'])/(1+exp(`ltgroup`g''-`diff'[1,`i'])) + local std`i'_`g'=2*`N`g''*(`po`i'_`g''-`pe`i'_`g'')^2/sqrt(.5*(`po`i'_`g''+`pe`i'_`g'')*(1-.5*(`po`i'_`g''+`pe`i'_`g''))) + local chi`i'=`chi`i''+`std`i'_`g'' + } + di "chi item ``i'' = `chi`i''" +} + +local chisq=0 +tempname y2 vy2 +qui gen `y2'=0 +qui gen `vy2'=0 +forvalues i=1/`nbitems' { + qui replace `y2'=`y2'+`res'`i'^2 if ``i''!=. + qui replace `vy2'=`vy2'+2*tanh((`lt2'-`diff'[1,`i'])/2)*sinh(`lt2'-`diff'[1,`i']) if ``i''!=. + tempname y2`i' vy2`i' + qui gen `y2`i''=`res'`i'^2 + qui su `y2`i'' if `total'!=0&`total'!=`rep'&``i''!=. + local sumy2`i'=r(sum) + qui tab `ltcl' + qui gen `vy2`i''=2*tanh((`lt2'-`diff'[1,`i'])/2)*sinh(`lt2'-`diff'[1,`i']) + di "item ``i''" + su `vy2`i'' if `total'!=0&`total'!=`rep'&``i''!=. + local sumvy2`i'=r(sum) + local fit`i'=(`sumy2`i''-`df`i'')/sqrt(`sumvy2`i'') + local fit2`i'=`df`i''*(ln(`sumy2`i'')-ln(`df`i''))/sqrt(`sumvy2`i'') + local chisq`i'=0 + forvalues g=1/`maxgroup' { + qui su `y2`i'' if `group'==`g'&``i''!=. + local sumy2`i'_g`g'=r(sum) + local n`i'g`g'=r(N) + qui su `vy2`i'' if `group'==`g'&``i''!=. + local sumvy2`i'_g`g'=r(sum) + local fit`i'_g`g'=(`sumy2`i'_g`g''-`n`i'g`g'')/sqrt(`sumvy2`i'_g`g'') + local chisq`i'=`chisq`i''+(`fit`i'_g`g'')^2 + } + local chisq=`chisq'+`chisq`i'' + /*fit2 est l'équivalent de FitResid et chisq est correct*/ +} +local RMSEA=sqrt(`chisq'/((`nbitems'*(`maxgroup'-1)-1)*(`ntotal'-1))) + +di in gr "{hline 55}" +di in gr "Items" _col(18) "FitResid" _col(31) "ChiSq" _col(42) "df" _col(55) "p" +di in gr "{hline 55}" +forvalues i=1/`nbitems' { + di in ye abbrev("``i''",18) _col(19) %7.3f `fit2`i'' _col(30) %6.2f `chisq`i'' _col(40) %4.0f `=`maxgroup'-1' _col(50) %6.4f 1-chi2(`=`maxgroup'-1',`chisq`i'') +} +di in gr "{dup 55:-}" +di in ye "Total" _col(30) %6.2f `chisq' _col(40) %4.0f `=(`maxgroup'-1)*`nbitems'' _col(50) %6.4f 1-chi2(`=(`maxgroup'-1)*`nbitems'',`chisq`i'') +di in ye "RMSEA" _col(30) %6.4f `RMSEA' +di in gr "{hline 55}" +di + +if "`pcares'"!="" { + di "{hline 36}" + di "Correlation matrix between residuals" + di "{hline 36}" + matrix list `cor',noheader format(%5.3f) + di + di "{hline 28}" + di "Eigenvalues of the residuals" + di "{hline 28}" + matrix rowname `Ev'=Eigenvalues + tempname Evp E + matrix `Evp'=`Ev'/`nbitems' + matrix `E'=`Ev' \ `Evp' + matrix rowname `E'=Eigenvalues Proportion +matrix list `E',noheader format(%5.3f) +} + +*use `saveraschres', clear +local dfind=`df'/`ntotal'*`nbitems' +if "`genfit'"!="" { + qui gen `genfit'=`df'*(ln(`y2')-log(`df'))/sqrt(`vy2') `if' `in' +} +if "`genres'"!="" { + forvalues i=1/`nbitems' { + qui gen `genres'`i'=`res'`i' `if' `in' + } +} + +end diff --git a/Modules/ado/personal/r/raschres.hlp b/Modules/ado/personal/r/raschres.hlp new file mode 100644 index 0000000..0a9a2aa --- /dev/null +++ b/Modules/ado/personal/r/raschres.hlp @@ -0,0 +1,54 @@ +{smcl} +{* 3june2013}{...} +{hline} +help for {hi:raschres}{right:Jean-Benoit Hardouin} +{hline} + +{title:Test of fit of the Rasch model using tests similar to RUMM based on residuals} + +{p 8 14 2}{cmd:raschres} {varlist} {cmd:,} {cmdab:diff}({it:vector}) {cmdab:theta}({it:varname}) [ {cmdab:genres}({it:string}) {cmdab:genfit}({it:newvarname}) +{cmdab:vargroup}({it:varname}) {cmdab:PCA:res} {cmdab:det:ails}] + +{title:Description} + +{p 4 8 2}{cmd:raschres} allows estimating similar tests than the RUMM software in order to test the fit of the dataset to a Rasch model, or to evaluate the +unidimensionality of the data using a Principal Components Analysis (PCA) on the residuals. {cmd:raschres} is available only for dichotomous items. + +{title:Options} + +{p 4 8 2}{cmd:diff} is required and defines a (1xJ) vector of values corresponding to the estimations of the difficulty parameters + +{p 4 8 2}{cmd:theta} is required and defines a variable containing the estimated values of the latent trait for each individual of the sample. + +{p 4 8 2}{cmd:genres} allows creating new variables containing the residuals (one new variable per item). This option must contain a prefix which will be given to +each new variable. + +{p 4 8 2}{cmd:genfit} create a new variable containing a fit index for each individual. + +{p 4 8 2}{cmd:vargroup} defines a variable containing the affectation between groups of individuals in order to compute fit statistics. + +{p 4 8 2} {cmd:pcares} allows providing a PCA on the residuals. + +{p 4 8 2} {cmd:details} allows obtaining more detailed results. + +{title:Example} + + {p 4 8 2}{cmd:. matrix diff=(-1.47,-0.97,-.23,-0.12,0.02,0.1)}{p_end} + {p 4 8 2}{cmd:. raschres items*, diff(diff) theta(theta)}{p_end} + + {p 4 8 2}{cmd:. raschres items*, diff(diff) theta(theta) genfit(fit) genres(res)}{p_end} + + {p 4 8 2}{cmd:. raschres items*, diff(diff) theta(theta) PCA det}{p_end} + + + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end} +{p 4 8 2}EA4275 "Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences"{p_end} +{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end} +{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end} +{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end} +{p 4 8 2}Emails: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol} diff --git a/Modules/ado/personal/r/raschtest v8.10.1.ado b/Modules/ado/personal/r/raschtest v8.10.1.ado new file mode 100644 index 0000000..bd9fc19 --- /dev/null +++ b/Modules/ado/personal/r/raschtest v8.10.1.ado @@ -0,0 +1,206 @@ +*! version 8.10.1 15july2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Raschtest: Rasch model, fit tests and graphical validation +* +* Historic: +* Version 1 (2003-06-30): Jean-Benoit Hardouin +* Version 2 (2003-07-07): Jean-Benoit Hardouin +* Version 3 (2004-01-02): Jean-Benoit Hardouin +* Version 4 (2004-01-21): Jean-Benoit Hardouin +* Version 5 (2004-01-24): Jean-Benoit Hardouin +* Version 6 (2004-02-05): Jean-Benoit Hardouin +* Version 6.1 (2004-03-29): Jean-Benoit Hardouin +* Version 6.2 (2004-04-06): Jean-Benoit Hardouin +* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin +* Version 7 (2005-04-02) : Jean-Benoit Hardouin +* Version 7.2 (2005-05-20) : Jean-Benoit Hardouin +* Version 7.3 (2005-07-02) : Jean-Benoit Hardouin +* Version 7.4 (2006-01-15) : Jean-Benoit Hardouin +* Version 7.5 (2006-04-20) : Jean-Benoit Hardouin +* Version 7.6 (2008-06-20) : Jean-Benoit Hardouin /*nold option*/ +* Version 8 (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/ +* Version 8.3 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option*/ +* Version 8.6 (2012-11-19) : Jean-Benoit Hardouin /*HTML option*/ +* Version 8.9 (2019-06-05) : Jean-Benoit Hardouin /*PNG option*/ +* Version 8.10 (2019-06-05) : Jean-Benoit Hardouin /*EXTENSION option*/ +* Version 8.10.1 (2019-06-15) : Jean-Benoit Hardouin /*NOSTAND option*/ +* +* Required modules : +* raschtestv7 version 8.1 (http://freeirt.free.fr) +* gammasym version 2.2 (http://www.freeirt.org) +* gausshermite version 1 (http://www.freeirt.org) +* geekel2d version 4.3 (http://www.freeirt.org) +* genscore version 1.4 (http://www.freeirt.org) +* ghquadm (findit ghquadm) +* gllamm version 2.3.14 (ssc describe gllamm) +* gllapred version 2.3.7 (ssc describe gllapred) +* elapse (ssc describe elapse) +* +* Jean-benoit Hardouin - University of Nantes - France +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research" +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* +* Copyright 2003-2012, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + + +program define raschtest,eclass +syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) GENRes(string) EXTension(string) graphclose docx(string) noSTand] + +local nbitems:word count `varlist' +if "`method'"=="" { + local method "cml" +} +else { + local method=lower("`method'") +} +if "`test'"=="" { + local test "R" +} +else { + local test=upper("`test'") +} +if "`dirsave'"!="" { + local dirsavev8 "dirsave(`dirsave')" +} +if "`method'"!="" { + local methodv8 "method(`method')" +} +if "`test'"!="" { + local testv8 "test(`test')" +} +if "`group'"!="" { + local groupv8 "group(`group')" +} +if "`genlt'"!="" { + local genltv8 "genlt(`genlt')" +} +if "`genscore'"!="" { + local genscorev8 "genscore(`genscore')" +} +if "`genres'"!="" { + local gensresv8 "genres(`genres')" +} +if "`genfit'"!="" { + local genfitv8 "genfit(`genfit')" +} +if "`comp'"!="" { + local compv8 "comp(`comp')" +} +if "`dif'"!="" { + local difv8 "dif(`dif')" +} +if "`iterate'"!="" { + local iteratev8 "iterate(`iterate')" +} +if "`difficulties'"!="" { + local difficultiesv8 "difficulties(`difficulties')" +} +if "`covariates'"!="" { + local covariatesv8 "covariates(`covariates')" +} +raschtestv7 `varlist' `if' `in' , id(`id') html(`html') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genresv8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8' `png' extension(`extension') `graphclose' docx(`docx') `stand' + +/*********************************************************************************************************** +RETURN +************************************************************************************************************/ + +ereturn clear +if `nbitems'>=3 { + if "`method'"=="cml" { + if "`test'"!="none" { + tempname AndersenZv8 + matrix `AndersenZv8'=r(AndersenZ) + ereturn matrix AndersenZ=`AndersenZv8' + } + if "`dif'"!="" { + tempname DIFv8 + matrix `DIFv8'=r(DIF) + ereturn matrix DIF=`DIFv8' + } + tempname cllv8 + scalar `cllv8'=r(cll) + ereturn scalar cll=`cllv8' + + } + if "`test'"!="NONE" { + tempname itemFitv8 globalFitv8 + matrix `itemFitv8'=r(itemFit) + matrix `globalFitv8'=r(globalFit) + ereturn matrix itemFit=`itemFitv8' + ereturn matrix globalFit=`globalFitv8' + } +} + +if "`method'"!="cml" { + tempname sigmav8 sesigmav8 + local `sigmav8'=`r(sigma)' + local `sesigmav8'=`r(sesigma)' + ereturn scalar sigma=``sigmav8'' + ereturn scalar sesigma=``sesigmav8'' +} + +tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8 +matrix `betav8'=r(beta) +matrix `Varbetav8'=r(Varbeta) +ereturn matrix beta=`betav8' +ereturn matrix Varbeta=`Varbetav8' +matrix `thetav8'=r(theta) +matrix `Varthetav8'=r(Vartheta) +ereturn matrix theta=`thetav8' +ereturn matrix Vartheta=`Varthetav8' +scalar `llv8'=`r(ll)' +scalar `AICv8'=`r(AIC)' +ereturn scalar ll=`llv8' +ereturn scalar AIC=`AICv8' +ereturn scalar Zcomp=r(Zcomp) +ereturn scalar pZcomp=r(pZcomp) + + +if "`method'"=="mml" { + local psi=r(PSI) + local psiadj=r(PSIadj) + ereturn scalar PSI=`psi' + ereturn scalar PSIadj=`psiadj' +} +if "`covariates'"!="" { + tempname betacovariates Vbetacovariates zcovariates pcovariates + matrix `betacovariates'=r(betacovariates) + matrix `Vbetacovariates'=r(Vbetacovariates) + matrix `zcovariates'=r(zcovariates) + matrix `pcovariates'=r(pcovariates) + + ereturn matrix betacovariates=`betacovariates' + ereturn matrix Vbetacovariates=`Vbetacovariates' + ereturn matrix zcovariates=`zcovariates' + ereturn matrix pcovariates=`pcovariates' +} + + + + +return clear + +end diff --git a/Modules/ado/personal/r/raschtest.ado b/Modules/ado/personal/r/raschtest.ado new file mode 100644 index 0000000..bd9fc19 --- /dev/null +++ b/Modules/ado/personal/r/raschtest.ado @@ -0,0 +1,206 @@ +*! version 8.10.1 15july2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Raschtest: Rasch model, fit tests and graphical validation +* +* Historic: +* Version 1 (2003-06-30): Jean-Benoit Hardouin +* Version 2 (2003-07-07): Jean-Benoit Hardouin +* Version 3 (2004-01-02): Jean-Benoit Hardouin +* Version 4 (2004-01-21): Jean-Benoit Hardouin +* Version 5 (2004-01-24): Jean-Benoit Hardouin +* Version 6 (2004-02-05): Jean-Benoit Hardouin +* Version 6.1 (2004-03-29): Jean-Benoit Hardouin +* Version 6.2 (2004-04-06): Jean-Benoit Hardouin +* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin +* Version 7 (2005-04-02) : Jean-Benoit Hardouin +* Version 7.2 (2005-05-20) : Jean-Benoit Hardouin +* Version 7.3 (2005-07-02) : Jean-Benoit Hardouin +* Version 7.4 (2006-01-15) : Jean-Benoit Hardouin +* Version 7.5 (2006-04-20) : Jean-Benoit Hardouin +* Version 7.6 (2008-06-20) : Jean-Benoit Hardouin /*nold option*/ +* Version 8 (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/ +* Version 8.3 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option*/ +* Version 8.6 (2012-11-19) : Jean-Benoit Hardouin /*HTML option*/ +* Version 8.9 (2019-06-05) : Jean-Benoit Hardouin /*PNG option*/ +* Version 8.10 (2019-06-05) : Jean-Benoit Hardouin /*EXTENSION option*/ +* Version 8.10.1 (2019-06-15) : Jean-Benoit Hardouin /*NOSTAND option*/ +* +* Required modules : +* raschtestv7 version 8.1 (http://freeirt.free.fr) +* gammasym version 2.2 (http://www.freeirt.org) +* gausshermite version 1 (http://www.freeirt.org) +* geekel2d version 4.3 (http://www.freeirt.org) +* genscore version 1.4 (http://www.freeirt.org) +* ghquadm (findit ghquadm) +* gllamm version 2.3.14 (ssc describe gllamm) +* gllapred version 2.3.7 (ssc describe gllapred) +* elapse (ssc describe elapse) +* +* Jean-benoit Hardouin - University of Nantes - France +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research" +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* +* Copyright 2003-2012, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + + +program define raschtest,eclass +syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) GENRes(string) EXTension(string) graphclose docx(string) noSTand] + +local nbitems:word count `varlist' +if "`method'"=="" { + local method "cml" +} +else { + local method=lower("`method'") +} +if "`test'"=="" { + local test "R" +} +else { + local test=upper("`test'") +} +if "`dirsave'"!="" { + local dirsavev8 "dirsave(`dirsave')" +} +if "`method'"!="" { + local methodv8 "method(`method')" +} +if "`test'"!="" { + local testv8 "test(`test')" +} +if "`group'"!="" { + local groupv8 "group(`group')" +} +if "`genlt'"!="" { + local genltv8 "genlt(`genlt')" +} +if "`genscore'"!="" { + local genscorev8 "genscore(`genscore')" +} +if "`genres'"!="" { + local gensresv8 "genres(`genres')" +} +if "`genfit'"!="" { + local genfitv8 "genfit(`genfit')" +} +if "`comp'"!="" { + local compv8 "comp(`comp')" +} +if "`dif'"!="" { + local difv8 "dif(`dif')" +} +if "`iterate'"!="" { + local iteratev8 "iterate(`iterate')" +} +if "`difficulties'"!="" { + local difficultiesv8 "difficulties(`difficulties')" +} +if "`covariates'"!="" { + local covariatesv8 "covariates(`covariates')" +} +raschtestv7 `varlist' `if' `in' , id(`id') html(`html') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genresv8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8' `png' extension(`extension') `graphclose' docx(`docx') `stand' + +/*********************************************************************************************************** +RETURN +************************************************************************************************************/ + +ereturn clear +if `nbitems'>=3 { + if "`method'"=="cml" { + if "`test'"!="none" { + tempname AndersenZv8 + matrix `AndersenZv8'=r(AndersenZ) + ereturn matrix AndersenZ=`AndersenZv8' + } + if "`dif'"!="" { + tempname DIFv8 + matrix `DIFv8'=r(DIF) + ereturn matrix DIF=`DIFv8' + } + tempname cllv8 + scalar `cllv8'=r(cll) + ereturn scalar cll=`cllv8' + + } + if "`test'"!="NONE" { + tempname itemFitv8 globalFitv8 + matrix `itemFitv8'=r(itemFit) + matrix `globalFitv8'=r(globalFit) + ereturn matrix itemFit=`itemFitv8' + ereturn matrix globalFit=`globalFitv8' + } +} + +if "`method'"!="cml" { + tempname sigmav8 sesigmav8 + local `sigmav8'=`r(sigma)' + local `sesigmav8'=`r(sesigma)' + ereturn scalar sigma=``sigmav8'' + ereturn scalar sesigma=``sesigmav8'' +} + +tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8 +matrix `betav8'=r(beta) +matrix `Varbetav8'=r(Varbeta) +ereturn matrix beta=`betav8' +ereturn matrix Varbeta=`Varbetav8' +matrix `thetav8'=r(theta) +matrix `Varthetav8'=r(Vartheta) +ereturn matrix theta=`thetav8' +ereturn matrix Vartheta=`Varthetav8' +scalar `llv8'=`r(ll)' +scalar `AICv8'=`r(AIC)' +ereturn scalar ll=`llv8' +ereturn scalar AIC=`AICv8' +ereturn scalar Zcomp=r(Zcomp) +ereturn scalar pZcomp=r(pZcomp) + + +if "`method'"=="mml" { + local psi=r(PSI) + local psiadj=r(PSIadj) + ereturn scalar PSI=`psi' + ereturn scalar PSIadj=`psiadj' +} +if "`covariates'"!="" { + tempname betacovariates Vbetacovariates zcovariates pcovariates + matrix `betacovariates'=r(betacovariates) + matrix `Vbetacovariates'=r(Vbetacovariates) + matrix `zcovariates'=r(zcovariates) + matrix `pcovariates'=r(pcovariates) + + ereturn matrix betacovariates=`betacovariates' + ereturn matrix Vbetacovariates=`Vbetacovariates' + ereturn matrix zcovariates=`zcovariates' + ereturn matrix pcovariates=`pcovariates' +} + + + + +return clear + +end diff --git a/Modules/ado/personal/r/raschtest.hlp b/Modules/ado/personal/r/raschtest.hlp new file mode 100644 index 0000000..5628958 --- /dev/null +++ b/Modules/ado/personal/r/raschtest.hlp @@ -0,0 +1 @@ +.h raschtestv7 diff --git a/Modules/ado/personal/r/raschtestv7.ado b/Modules/ado/personal/r/raschtestv7.ado new file mode 100644 index 0000000..63d21c3 --- /dev/null +++ b/Modules/ado/personal/r/raschtestv7.ado @@ -0,0 +1,2570 @@ +*! version 8.10.2 24september2019 +*! Jean-Benoit Hardouin +************************************************************************************************************* +* Raschtestv7: Rasch model, fit tests and graphical representations +* Corresponds to the version 8 of Raschtest (http://freeirt.org) for Stata7 +* +* Historic: +* Version 2.1 (2003-07-10): Jean-Benoit Hardouin +* Version 3.1 (2004-01-02) : Jean-Benoit Hardouin +* Version 7.1 (2005-03-30) : Jean-Benoit Hardouin +* Version 7.2.1 (2005-05-21) : Jean-Benoit Hardouin +* Version 7.3.1 (2005-07-02) : Jean-Benoit Hardouin +* Version 7.3.2 (2005-10-05) : Jean-Benoit Hardouin /*correction for the *genlt* option with *method(cml)**/ +* Version 7.3.3 (2005-12-21) : Jean-Benoit Hardouin /*correction if scores are not represented with method(mml) or method(gee)*/ +* Version 7.4.1 (2006-01-17) : Jean-Benoit Hardouin /*Standardized OUTFIT and INFIT, DIF option*/ +* Version 7.4.2 (2006-03-21) : Jean-Benoit Hardouin /*Avoids a bug when the temporary files are saved in a directory containing special characters*/ +* Version 7.4.3 (2006-11-15) : Jean-Benoit Hardouin /*Avoids a bug when the directory defined in the dirsave option contains special characters*/ +* Version 7.5.1 (2007-04-20) : Jean-Benoit Hardouin /*Return results of the comp option*/ +* Version 7.6.1 (2008-06-26) : Jean-Benoit Hardouin /*Nold option, corrects a bug with the genlt option*/ +* Version 7.6.2 (2009-03-01) : Jean-Benoit Hardouin /*Correction of the SE of the latent trait, graph option, correction of a bug with the if option, PSI in MML*/ +* Version 8.1 (2009-06-24) : Jean-Benoit Hardouin /*DIFFICULTIES option, COVARIATES option*/ +* Version 8.2 (2009-07-15) : Jean-Benoit Hardouin /*Correction of a bug with CML*/ +* Version 8.3 (2009-12-19) : Jean-Benoit Hardouin /*correction of a bug with DIFFICULTIES and COVARIATES options together*/ +* Version 8.4 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option */ +* Version 8.5 (2011-12-20) : Jean-Benoit Hardouin /*Correction for the ss1 and ss3 suboptions of the COVARIATES option */ +* Version 8.6 (2012-11-20) : Jean-Benoit Hardouin /*HTML option*/ +* Version 8.7 (2013-05-28) : Jean-Benoit Hardouin /*Correction of a bug in the covariates option with ss1 and ss3*/ +* Version 8.8 (2014-02-27) : Jean-Benoit Hardouin /*Correction of a bug when the null or the parfect score have a frequency of 0 (no test)*/ +* Version 8.9 (2019-06-05) : Jean-Benoit Hardouin /*png option (graphs in png), information curve by item*/ +* Version 8.10 (2019-07-05) : Jean-Benoit Hardouin /*extension option (graphs with the chosen extension) who replaces the png option, docx option*/ +* Version 8.10.1 (2019-07-15) : Jean-Benoit Hardouin /*nostand option*/ +* Version 8.10.2 (2019-09-24) : Jean-Benoit Hardouin /*correction of a small bug*/ +* +* Needed modules : +* gammasym version 2.2 (http://www.freeirt.org) +* gausshermite version 1 (http://www.freeirt.org) +* geekel2d version 4.3 (http://www.freeirt.org) +* genscore version 1.4 (http://www.freeirt.org) +* ghquadm (findit ghquadm) +* gllamm version 2.3.20 (ssc describe gllamm) +* gllapred version 2.3.8 (ssc describe gllapred) +* elapse (ssc describe elapse) +* +* Jean-benoit Hardouin - University of Nantes - France +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research" +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2003-2014 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*********************************************************************************************************** +DEFINITION / SYNTAX +***********************************************************************************************************/ + + +program define raschtestv7,rclass +syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GENRES(string) GRAph v8 COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) extension(string) GRAPHClose DOCX(string) noSTand] + +local covariables `covariates' + +if "`docx'"!="" { + putdocx clear + putdocx begin + putdocx paragraph + putdocx text ("Graphical outputs of the raschtest module") +} +if "`if'"=="" { + local if "if 1" +} + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + +if "`trace'"!="" { + di in green "*** Tests of conformity" +} +if "`v8'"=="" { + version 7.0 +} +else { + version 8.0 +} +if "`html'"!="" { + set scheme sj + local htmlregion "graphregion(fcolor(white) ifcolor(white))" + local draw +} + +local st = "$S_TIME" +local nbitems : word count `varlist' +marksample touse ,novarlist +if "`covariables'"!="" { + tokenize "`covariables'",parse(" ,") + local i=1 + local tcovariables + while "``i''"!=","&"``i''"!="" { + local covariable`i' ``i'' + local tcovariables `tcovariables' ``i'' + local ++i + } + local nbcovariables=`i'-1 + local ss1 + local ss3 + if "``i''"=="," { + forvalues j=`=`i'+1'/`=`i'+2' { + if "``j''"=="ss1" { + local ss1 ss1 + } + else if "``j''"=="ss3" { + local ss3 ss3 + } + else if "``j''"=="" { +* di in green "option `j' vide" + } + else { + di in red "Invalid option in the {hi:covariables} option" + error 198 + } + } + local i=`i'+3 + if "``i''"!="" { + di in red "There is too much options in the {hi:covariates} option." + error 198 + } + } + local covariables `tcovariables' +} +else { + local nbcovariables=0 +} + +isid `id' +tokenize `varlist' + +local bad +forvalues i=1/`nbitems' { + qui count if ``i''!=0&``i''!=1&``i''!=. + local N=r(N) + if `N'>0 { + local bad `bad' ``i'' + } +} +if "`bad'"!="" { + di in red "The item(s) {hi:`bad'} is(are) not binary item(s) (with responses 0 or 1)." + exit +} + + + +if "`method'"=="" { + local method cml +} +if "`test'"=="" { + local test R +} +local method=lower("`method'") +local test=upper("`test'") +if "`method'"!="mml"&"`method'"!="cml"&"`method'"!="gee" { + di in red "Uncorrect method option." + error 198 + exit +} + +if "`test'"!="R"&"`test'"!="Q"&"`test'"!="WP"&"`test'"!="NONE" { + di in red "Uncorrect test option." + error 198 + exit +} + +if "`genfit'"!="" { + local nbwordgenfit:word count `genfit' + if `nbwordgenfit'!=2 { + di in red "Uncorrect genfit option." + di in red "This option must contain exactly two words" + error 198 + exit + } +} + + +if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!=""|"`genres'"!="" { + capture confirm new variable `genfit' `genscore' `genres' + if "`genfit'"!="" { + local o:word 1 of `genfit' + forvalues i=1/`nbitems' { + confirm new variable `o'``i'' + } + } + if "`genlt'"!="" { + local 0 `genlt' + gettoken left 0: 0,parse(",") + gettoken right 0: 0,parse(",") + local genlt `left' + local replacegenlt `0' + local length=length("`replacegenlt'") + if `length'>=3&substr("`replacegenlt'",1,`length')==substr("replace",1,`length') { + local replacegenlt replace + } + if "`replacegenlt'"!="replace"&"`replacegenlt'"!="" { + di "Not allowed option in the {hi:genlt} option" + error 198 + } + else if "`replacegenlt'"=="" { + confirm new variable `genlt' + } + } +} + +preserve + +tempfile saveraschtest +qui save `saveraschtest' +qui keep if `touse'==1 + +if "`autogroup'"!=""&"`group'"!="" { + di in green "The autogroup and the group options cannot be defined in the same time" + di in green "Only the group option is retained." + local autogroup +} + +if "`autogroup'"!="" { + tempvar autoscore + qui genscore `varlist',score(`autoscore') + + tempname matscore tmp + matrix `matscore'=J(`=`nbitems'-1',3,0) + forvalues i=1/`=`nbitems'-1' { + matrix `matscore'[`i',1]=`i' + matrix `matscore'[`i',2]=`i' + qui count if `autoscore'==`i' + matrix `matscore'[`i',3]=r(N) + } + local stop=0 + local j=0 + while `j'<=`=`nbitems'-3'&`stop'!=1 { + local j=`j'+1 + local scoretogroup=99999999 + local rowtogroup1=0 + local rowtogroup2=0 + local stop=1 + forvalues i=1/`=`nbitems'-`j'' { + if `matscore'[`i',1]>=0 & `matscore'[`i',3]<30 & `matscore'[`i',3]<`scoretogroup' { + local scoretogroup=`matscore'[`i',3] + local rowtogroup1=`i' + local stop=0 + } + } + if `stop'!=1 { + if `rowtogroup1'>1&`rowtogroup1'<`=`nbitems'-`j'' { + if `matscore'[`=`rowtogroup1'-1',1]<`matscore'[`=`rowtogroup1'+1',1] { + local rowtogroup2=`rowtogroup1' + local rowtogroup1=`rowtogroup1'-1 + } + else { + local rowtogroup2=`rowtogroup1'+1 + } + } + else if `rowtogroup1'==1 { + local rowtogroup2=2 + } + else if `rowtogroup1'==`=`nbitems'-`j'' { + local rowtogroup2=`nbitems'-`j' + local rowtogroup1=`nbitems'-`j'-1 + } + matrix `tmp'=`matscore' + matrix `matscore'=J(`=`nbitems'-`j'',3,0) + if `rowtogroup1'!=1 { + matrix `matscore'[1,1]=`tmp'[1..`=`rowtogroup1'-1',1..3] + } + matrix `matscore'[`rowtogroup1',1]=`tmp'[`rowtogroup1',1] + matrix `matscore'[`rowtogroup1',2]=`tmp'[`rowtogroup2',2] + matrix `matscore'[`rowtogroup1',3]=`tmp'[`rowtogroup1',3]+`tmp'[`rowtogroup2',3] + if `rowtogroup2'!=`=`nbitems'-`j'' { + matrix `matscore'[`rowtogroup2',1]=`tmp'[`=`rowtogroup2'+1'..`=`nbitems'-`j'',1..3] + } + } + } + local nbrows=rowsof(`matscore')-1 + local thresholds + forvalues i=1/`nbrows' { + local tmp=`matscore'[`i',2] + local thresholds `thresholds' `tmp' + } + local group `thresholds' +} + + +if "`group'"=="" { + forvalues i=1/`=`nbitems'-1' { + local group "`group' `i'" + } +} +local nbgroups:word count `group' +local groupmax:word `nbgroups' of `group' +if `groupmax'>=`nbitems' { + di in red "You cannot form a group with the higher possible score." + di in red "The higher possible value of the group option is `=`nbitems'-1'." + di in red "Please correct your group option." + error 198 + exit +} +else { + if `groupmax'!=`=`nbitems'-1' { + local group "`group' `=`nbitems'-1'" + local nbgroups=`nbgroups'+1 + } +} +local nbgroups=`nbgroups'+1 + +if "`dirsave'"!=""&"`filessave'"=="" { + di in ye "If you want to save yours graphs, use the filessave option" +} +if "`filessave'"!="" { + if "`dirsave'"=="" { + local dirsave "`c(pwd)'" + } + di in ye "The graphs files will be saved in `dirsave'" +} +if "`dirsave'"!="" { + if "`filesave'"=="" { + local filesave "filesave" + } +} +if "`extension'"!=""&"`extension'"!="png"&"`extension'"!="eps"&"`extension'"!="ps"&"`extension'"!="svg"&"`extension'"!="wmf"&"`extension'"!="png"&"`extension'"!="emf"&"`extension'"!="pdf"&"`extension'"!="tif" { + di in red "The {hi:extension} option can not contain the value `extension'. Please correct it." + error 198 + exit +} +if "`pause'"!=""&"`draw'"=="" { + pause on +} + +if "`difficulties'"!="" { + capture confirm matrix `difficulties' + if _rc!=0 { + di in red "The vector `difficulties' defined in the {hi:difficulties} option does not exist." + error 198 + exit + } +} + +if "`difficulties'"!=""&"`method'"!="mml" { + di in red "The {hi:difficulties} option can be defined only for MML method." + error 198 + exit +} + +if "`covariables'"!=""&"`method'"!="mml" { + di in red "The {hi:covariables} option can be defined only for MML method." + error 198 + exit +} +if "`covariables'"!=""&"`comp'"!="" { + di in red "The {hi:covariables} and {hi:comp} options can be defined jointly." + error 198 + exit +} + + + + + +/*********************************************************************************************************** +POSSIBLE TEST +***********************************************************************************************************/ + +if ("`icc'"!=""|"`fitgraph'"!=""|"`splittest'"!=""|"`details'"!="")&"`test'"=="NONE" { + di in green "You cannot use the {hi:details}, {hi:icc}, {hi:fitgraph} or {hi:splittest} options if you use {hi:test(none)}." + di in green "These options are ignored." + local details + local icc + local fitgraph + local splittest +} +if "`comp'"!=""&"`method'"=="cml" { + di in green "You cannot compare two populations ({hi:comp} option) with the CML estimation method" + di in green "This option is ignored." + local comp +} +if "`method'"!="cml"&"`test'"=="WP" { + di in green "The Wright-Panchapakesan test is not authorized with MML or GEE." + di in green "The WP tests are replaced by Van den Wollenberg Q tests." + local test Q +} +if "`method'"=="gee"&"`ld'"!="" { + di in green "You cannot use the {hi:nold} option with the GEE method of estimation" + di in green "This option is ignored." + local ld +} + + +if "`test'"==""|"`test'"=="R" { + local test "R" + if "`method'"=="cml" { + local namewp "R1c" + local descwp "R1c test" + } + else { + local namewp="R1m" + local descwp "R1m test" + } +} +if `nbitems'>999999|"`test'"=="WP" { + local namewp " Y" + local descwp "Wright-Panchapakesan Y test" + local q2 +} + else if "`test'"=="Q" { + local namewp " Q1" + local descwp "Van den Wollenberg Q1 test" +} + +if "`method'"!="cml"&"`meandiff'"!="" { + di in green "The {hi:meandiff} option is not available with MML or GEE." + di in green "This option is ignored." + local meandiff +} + +if "`method'"!="cml"&"`splittests'"!="" { + di in green "The {hi:splittests} option is not available with MML or GEE." + di in green "This option is ignored." + local splittests +} +if "`method'"!="cml"&"`dif'"!="" { + di in green "The {hi:dif} option is not available with MML or GEE." + di in green "This option is ignored." + local dif +} + +/*********************************************************************************************************** +SCORES AND GROUPS +************************************************************************************************************/ + +qui count if `touse'==1 +local N=r(N) + +qui keep `varlist' `comp' `covariables' `id' `touse' + +tempname rep item +tempvar score realscore +qui genscore `varlist',score(`score') +qui count if `score'==.&`touse'==1 +local nbindmiss=r(N) + +if "`ld'"=="" { + qui drop if `score'==. +} +forvalues i=1/`nbitems' { + rename ``i'' `rep'`i' +} + + + +local liminf0=0 +local limsup0=0 +local liminf`nbgroups'=`nbitems' +local limsup`nbgroups'=`nbitems' + + +local recode +forvalues i=1/`=`nbgroups'-1' { + if `i'!= 1{ + local liminf`i' : word `=`i'-1' of `group' + } + else { + local liminf1=0 + } + local liminf`i'=`liminf`i''+1 + local limsup`i':word `i' of `group' + + local recode "`recode' `liminf`i''/`limsup`i''=`i'" +} +qui gen `realscore'=`score' +qui recode `score' `recode' `nbitems'=`nbgroups' + +local smallgroup=0 + +forvalues i=0/`nbgroups' { + qui count if `score'==`i' + local effscore`i'=r(N) + if `i'!=0&`i'!=`nbgroups'&`effscore`i''<30 { + local smallgroup=1 + } +} +/*********************************************************************************************************** +ESTIMATION OF THE DIFFICULTY PARAMETERS +************************************************************************************************************/ +if "`trace'"!="" { + di in green "*** Estimation of the difficulty parameters" +} + + +if "`covariables'"!=""&"`difficulties'"=="" { + forvalues i=1/`nbcovariables' { + qui su `covariable`i'' + local mean`covariable`i''=r(mean) + qui replace `covariable`i''=`covariable`i''-`mean`covariable`i''' + } +} + +tempname ll coef var beta Vbeta est + +if "`method'"=="gee" { + qui geekel2d `rep'1-`rep'`nbitems',ll + local nbobserv=r(N) + + if `r(error)'==1 { + di "The variance of the latent trait probably is too high to made the GEE a efficient method to estimate the parameters." + error 499 + exit + } + scalar `ll'=r(ll) + local nbind=r(N) + matrix `coef'=r(b) + matrix `est'=`coef' + matrix `est'[1,`=`nbitems'+1']=sqrt(`est'[1,`=`nbitems'+1']) + matrix `var'=r(V) + matrix `beta'=`coef'[1,1..`nbitems'] + matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems'] + local sig=sqrt(`coef'[1,`=`nbitems'+1']) + local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])/sqrt(`nbind')/(`sig'*2) +} + +qui reshape long `rep', i(`id') j(`item') + +tempvar diff tl +gen `diff'=0 + +forvalues i=1/`nbitems' { + qui gen `rep'`i'=`item'==`i' + qui replace `rep'`i'=-`rep'`i' +} + + +if "`method'"=="mml" { + if "`difficulties'"==""{ + qui xtlogit `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') nocons iterate(`iterate') + matrix `est'=e(b) + matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`est'[1,`=`nbitems'+`nbcovariables'+1']/2) + } + else { + tempname offset b + qui gen `offset'=0 + forvalues i=1/`nbitems' { + qui replace `offset'=-(`difficulties'[1,`i']) if `item'==`i' + } + qui gllamm `rep' `covariables' , offset(`offset') i(`id') nocons iterate(`iterate') link(logit) fam(bin) + matrix `b'=e(b) + matrix `est'=`difficulties',`b' + matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`b'[1,`=`nbcovariables'+1']/2) + } +} +else if "`method'"=="cml" { + qui clogit `rep' `rep'1-`rep'`=`nbitems'-1' , group(`id') +} + + +if "`method'"!="gee" { + if "`difficulties'"=="" { + matrix `coef'=e(b) + matrix `var'=e(V) + } + else { + matrix `coef'=`difficulties' + matrix `var'=J(`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1',.) + matrix `var'[`=`nbitems'+1',`=`nbitems'+1']=e(V) + } + scalar `ll'=e(ll) + local nbind=e(N)/`nbitems' + local nbobserv=e(N) + *di "nombre d'obs:`nbobserv'" + + if "`meandiff'"!="" { + matrix `var'=J(`nbitems',`nbitems',.) + matrix `coef'=J(1,`nbitems',.) + local param + local lin `rep'1 + forvalues j=2/`=`nbitems'-1' { + local lin `lin'+`rep'`j' + } + local lin (`lin')/`nbitems' + + forvalues j=1/`=`nbitems'-1' { + qui lincom `rep'`j'-`lin' + matrix `coef'[1,`j']=`r(estimate)' + matrix `var'[`j',`j']=`r(se)'^2 + } + qui lincom -`lin' + matrix `coef'[1,`nbitems']=`r(estimate)' + matrix `var'[`nbitems',`nbitems']=`r(se)'^2 + } + if "`method'"=="mml" { + local sig=e(sigma_u) + local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2 + tempname betacov Vbetacov + if "`difficulties'"=="" { + matrix `beta'=`coef'[1,1..`nbitems'] + matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems'] + if "`covariables'"!="" { + matrix `betacov'=`coef'[1,`=`nbitems'+1'..`=`nbitems'+`nbcovariables''] + matrix `Vbetacov'=`var'[`=`nbitems'+1'..`=`nbitems'+`nbcovariables'',`=`nbitems'+1'..`=`nbitems'+`nbcovariables''] + } + local sig=e(sigma_u) + local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2 + } + else { + tempname tmp + matrix `tmp'=e(b) + matrix `beta'=`difficulties' + if "`covariables'"!="" { + matrix `betacov'=`tmp'[1,1..`nbcovariables'] + } + local sig=`tmp'[1,`=`nbcovariables'+1'] + matrix `tmp'=e(V) + local sesig=sqrt(`tmp'[`=`nbcovariables'+1',`=`nbcovariables'+1']) + matrix `Vbeta'=J(`nbitems',`nbitems',.) + if "`covariables'"!="" { + matrix `Vbetacov'=`tmp'[1..`nbcovariables',1..`nbcovariables'] + } + } + } + else if "`method'"=="cml"&"`meandiff'"==""{ + matrix `beta'=`coef'[1,1..`=`nbitems'-1'] + matrix `Vbeta'=`var'[1..`=`nbitems'-1',1..`=`nbitems'-1'] + } + else if "`method'"=="cml"&"`meandiff'"!=""{ + matrix `beta'=`coef' + matrix `Vbeta'=`var' + } +} + +if ("`method'"=="mml"|"`method'"=="gee") { + local colnames + forvalues i=1/`nbitems' { + local colnames "`colnames' `rep':`rep'`i'" + } + forvalues i=1/`nbcovariables'{ + local tmp:word `i' of `covariables' + local colnames "`colnames' `rep':`tmp'" + } + local id2=substr("`id'",1,4) + local colnames "`colnames' `id2'1:_cons" + matrix colnames `est'=`colnames' + + qui gllamm `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') allc nocons family(binom) link(logit) trace from(`est') eval + tempname u + qui gllapred `u',u fsample + + forvalues i=1/`nbcovariables' { + local tmp:word `i' of `covariables' + qui replace `u'm1=`u'm1+`betacov'[1,`i']*(`tmp')/*+`mean`covariable`i''')*/ + } + tempname theta sdtheta + matrix `theta'=J(1,`=`nbitems'+1',0) + matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',0) + qui su `u'm1 if `rep'1==-1 + local vartheta=r(Var) + qui gen `u's2=`u's1^2 + qui su `u's2 if `rep'1==-1 + local meanse2=r(mean) + local psi=1-`meanse2'/(`meanse2'+`vartheta') + forvalues s=0/`nbitems' { + qui su `u'm1 if `realscore'==`s' + local theta`s'=r(mean) + qui su `u's1 if `realscore'==`s' + local sdtheta`s'=r(mean) + matrix `theta'[1,`=`s'+1']=`theta`s'' + matrix `sdtheta'[`=`s'+1',`=`s'+1']=`sdtheta`s'' + } + if "`genlt'"!="" { + tempfile ltsave ltsavetmp + qui save `ltsavetmp', replace + qui keep if `rep'1==-1 + qui keep `u'm1 `u's1 `id' + qui sort `id' + qui save `ltsave' + qui use `ltsavetmp' + } +} + +forvalues i=1/`nbitems' { + if `i'==`nbitems'&"`method'"=="cml"&"`meandiff'"=="" { + local beta`i'=0 + local sd`i' . + local fixed`i' "*" + } + else { + local beta`i'=`coef'[1,`i'] + local sd`i'=sqrt(`var'[`i',`i']) + } + qui replace `diff'=-`beta`i'' if `item'==`i' +} + +/*********************************************************************************************************** +COMPARISON OF TWO POPULATIONS +***********************************************************************************************************/ + +if "`comp'"!=""&"`method'"!="cml" { + if "`trace'"!="" { + di in green "*** Test of comparison of two populations" + } + qui inspect `comp' + local unique=r(N_unique) + if `unique'== 2 { + qui su `comp' + local mincomp=r(min) + local maxcomp=r(max) + tempname bmin bmax + qui xtlogit `rep' if `comp'==`mincomp',offset(`diff') i(`id') + matrix `bmin'=e(b) + local meanmin=`bmin'[1,1] + local varmin=e(sigma_u)^2 + local llmin=e(ll) + local Nmin=e(N_g) + qui xtlogit `rep' if `comp'==`maxcomp',offset(`diff') i(`id') + matrix `bmax'=e(b) + local meanmax=`bmax'[1,1] + local varmax=e(sigma_u)^2 + local llmax=e(ll) + local Nmax=e(N_g) + local Zcomp=(`meanmin'-`meanmax')/sqrt(`varmin'/`Nmin'+`varmax'/`Nmax') + local pvalue=1-norm(abs(`Zcomp')) + } + else { + di "It is impossible to compare more than two populations" + di "The comparison process is not run" + local comp + } +} + +/*********************************************************************************************************** +ESTIMATION OF THE ABILITY PARAMETERS / CML +************************************************************************************************************/ +if `nbitems'>=2 { + if "`trace'"!="" { + di in green "*** Estimation of the ability parameters" + } + if "`method'"=="cml" { + tempfile verytmp + qui save `verytmp',replace + drop _all + qui set obs 20001 + qui gen theta=(_n-10001)/1000 + qui gen A=1 + forvalues j=1/`nbitems' { + qui gen u`j'=exp(theta-`beta`j'') + qui gen p`j'=u`j'/(1+u`j') + qui gen a`j'=1/u`j' + qui replace A=A*a`j' + qui gen i`j'=u`j'/(1+u`j')^2 + qui gen j`j'=(u`j'*(1-u`j'))/(1+u`j')^3 + } + qui egen P=rsum(p*) + qui egen I=rsum(i*) + qui egen J=rsum(j*) + qui gen V=1/I^2*(I+J^2)/(4*I^2) + qui gen V2=1/I + tempname theta sdtheta + matrix `theta'=J(1,`=`nbitems'+1',0) + matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',.) + forvalues s=0/`nbitems' { + qui gen f`s'=abs(`s'-P+.5*J/I) + qui sort f`s' + matrix `theta'[1,`=`s'+1']=theta[1] + matrix `sdtheta'[`=`s'+1',`=`s'+1']=sqrt(V2[1]) + } + use "`verytmp'",replace + } + qui gen `tl'=0 + forvalues s=0/`nbitems' { + local theta`s'=`theta'[1,`=`s'+1'] + qui replace `tl'=`theta`s'' if `realscore'==`s' + local sdtheta`s'=`sdtheta'[`=`s'+1',`= `s'+1'] + } + tempname pred + qui gen `pred'=log(exp(`rep'*(`tl'+`diff'))/(1+exp(`tl'+`diff'))) + + qui su `pred' + local globalll=r(sum) + + local nulscore=0 + forvalues i=0/`nbgroups' { + qui count if `score'==`i'&`item'==1 + local nbscore`i'=r(N) + if `nbscore`i''==0 { + local nulscore=1 + } + } + if `nulscore' { + di in green "{p}At least one group of scores concerns none individuals. Tests will be not computed.{p_end}" + di in green "{p}Use the {hi:group} or the {hi:autogroup} options.{p_end}" + local test "NONE" + local details + local icc + local fitgraph + local splittest + } + forvalues i=0/`nbitems' { + qui count if `realscore'==`i'&`item'==1 + local nbrealscore`i'=r(N) + } +} + +/*********************************************************************************************************** +TESTS OF THE FIRST ORDER +************************************************************************************************************/ + +tempname Pi +matrix define `Pi'=J(`nbitems',`=`nbitems'-1',0) +if "`test'"!="NONE" { + qui drop if `score'==. + if "`trace'"!="" { + di in green "*** Tests of the first order" + } + tempname Obs Obs2 Th Th2 + + matrix define `Obs'=J(`nbitems',`=`nbitems'-1',0) + matrix define `Obs2'=J(`nbitems',`=`nbgroups'-1',0) + matrix define `Th'=J(`nbitems',`=`nbitems'-1',0) + matrix define `Th2'=J(`nbitems',`=`nbgroups'-1',0) + local listofitemsc + + /* Estimation of the gamma symetrical functions*/ + local c0 "1" + local c`nbitems' "`nbitems'*x" + forvalues j=1/`nbitems' { + local listini`j' + local listofitemsc "`listofitemsc' `beta`j''" + local c0 `c0'*(1+exp(x-`beta`j'')) + local c`nbitems' `c`nbitems''-`beta`j'' + forvalues k=1/`nbitems' { + local listini`j'k`k' + if `k'!=`j' { + local listini`j' "`listini`j'' `beta`k''" + } + forvalues l=1/`nbitems' { + if `l'!=`j'&`l'!=`k' { + local listini`j'k`k' "`listini`j'k`k'' `beta`l''" + } + } + } + } + + gammasym `listofitemsc' + + /*Estimation, for each value of the score s of the probability to respond to each item (Pi) and of the theorical number of positive responses (Ths) and of theorical number of positive respond per item pair (Ws)*/ + forvalues s=1/`nbitems' { + local denom`s'=r(gamma`s') + tempname W`s' + matrix define `W`s''=J(`nbitems',`nbitems',0) + } + tempvar prob prob2 z y v z2 y2 v2 c r q e + qui gen `prob'=. + qui gen `prob2'=. + forvalues j=1/`nbitems' { + forvalues s=1/`=`nbitems'-1' { + qui count if `rep'==1&`item'==`j'&`realscore'==`s' + matrix `Obs'[`j',`s']=r(N) + if "`test'"!="WP" { + gammasym `listini`j'' + local num`j'=r(gamma`=`s'-1') + if "`method'"=="cml"|"`test'"=="Q" { + matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s'' + } + else { + gausshermite exp(`s'*x)/(`c0'), sigma(`sig') + local int`s'=r(int) + if "`test'"=="R"&`nbrealscore`s''!=0{ + local tmp=exp(-`beta`j'')*`num`j''*`int`s''*`nbind'/`nbrealscore`s'' + matrix `Pi'[`j',`s']=`tmp' + } + else if `nbrealscore`s''==0 { + matrix `Pi'[`j',`s']=0 + } + } + if "`test'"=="R" { + forvalues k=`=`j'+1'/`nbitems' { + if `s'>=2 { + gammasym `listini`j'k`k'' + local num`j'k`k'=r(gamma`=`s'-2') + if "`method'"=="cml" { + matrix `W`s''[`j',`k']=`nbrealscore`s''*exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''/`denom`s'' + } + else { + matrix `W`s''[`j',`k']=exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''*`int`s''*`nbind' + } + matrix `W`s''[`k',`j']=`W`s''[`j',`k'] + } + } + } + } + else if "`test'"=="WP" { + matrix `Pi'[`j',`s']=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) + } + matrix `Th'[`j',`s']=`Pi'[`j',`s']*`nbrealscore`s'' + qui replace `prob'=`Pi'[`j',`s'] if `realscore'==`s'&`item'==`j' + qui replace `prob2'=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) if `realscore'==`s'&`item'==`j' + matrix `W`s''[`j',`j']=`nbrealscore`s''*`Pi'[`j',`s'] + if "`test'"!="R" { + matrix `W`s''[`j',`j']=`W`s''[`j',`j']*abs(1-`Pi'[`j',`s']) + } + } + } + qui gen `v2'=abs(`prob'*(1-`prob')) + qui gen `z2'=(`rep'-`prob')^2 + qui gen `y2'=`z2'/`v2' + qui gen `c'=abs(`prob'*(1-`prob')*(`prob'^3+(1-`prob')^3)) + qui gen `r'=`c'/(`v2')^2 + qui gen `e'=`c'-(`v2')^2 + + forvalues j=1/`nbitems' { + qui su `y2' if `item'==`j' + local outfit`j'=r(mean) + qui su `r' if `item'==`j' + local Voutfit`j'=r(sum) + local Voutfit`j'=`Voutfit`j''/(`nbind')^2-1/`nbind' + local outfitstd`j'=(`outfit`j''^(1/3)-1)*(3/sqrt(`Voutfit`j''))-sqrt(`Voutfit`j'')/3 + + qui su `z2' if `item'==`j' + local n=r(sum) + qui su `v2' if `item'==`j' + local d=r(sum) + local infit`j'=`n'/`d' + qui su `e' if `item'==`j' + local sume=r(sum) + local Vinfit`j'=`sume'/(`d')^2 + local infitstd`j'=(`infit`j''^(1/3)-1)*(3/sqrt(`Vinfit`j''))-sqrt(`Vinfit`j'')/3 + } + tempname tmp stattest testitems + + /*Estimation, by scores group g, of the theorical number of positive response (Th2g) and of the positive respond to each items pair (W2g)*/ + scalar `stattest'=0 + forvalues g=1/`=`nbgroups'-1' { + tempname W2`g' d2`g' + matrix define `W2`g''=J(`nbitems',`nbitems',0) + forvalues s=`liminf`g''/`limsup`g'' { + forvalues j=1/`nbitems' { + matrix `Obs2'[`j',`g']=`Obs2'[`j',`g']+`Obs'[`j',`s'] + matrix `Th2'[`j',`g']=`Th2'[`j',`g']+`Th'[`j',`s'] + if "`test'"=="R" { + forvalues k=`=`j'+1'/`nbitems' { + matrix `W2`g''[`j',`k']=`W2`g''[`j',`k']+`W`s''[`j',`k'] + matrix `W2`g''[`k',`j']=`W2`g''[`j',`k'] + } + } + matrix `W2`g''[`j',`j']=`W2`g''[`j',`j']+`W`s''[`j',`j'] + } + } + + /*Estimation of the d2g vectors*/ + matrix `d2`g''=`Obs2'[1..`nbitems',`g']-`Th2'[1..`nbitems',`g'] + + /*Estimation of the influences on the test of each item (testitemsg matrix) and of the test statistic (stattest)*/ + tempname test`g' testitems`g' + matrix `test`g''=`d2`g'''*syminv(`W2`g'')*`d2`g'' + capture matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g'' + if _rc!=0 { + matrix `tmp'=J(`nbitems',`nbitems',0) + forvalues j=1/`nbitems' { + matrix `tmp'[`j',`j']=`W2`g''[`j',`j'] + } + di in green "Group `g' (`liminf`g''/`limsup`g''): The weight matrix is not positive-definite, the diagonal matrix is used to estimate the contribution of the items on the `wpname' statistic" + matrix list `tmp' + matrix `testitems`g''=cholesky(syminv(`tmp'))*`d2`g'' + } + else { + matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g'' + } + scalar `stattest'=`stattest'+`test`g''[1,1] + } + matrix `testitems'=J(`nbitems',1,0) + forvalues j=1/`nbitems' { + forvalues g=1/`=`nbgroups'-1' { + matrix `testitems'[`j',1]=`testitems'[`j',1]+`testitems`g''[`j',1]^2 + } + } + + /*Adaptation for the Q1 statistic*/ + if "`test'"=="Q" { + scalar `stattest'=`stattest'*`=`nbitems'-1'/`nbitems' + } + + /*Correction for R1m and Q1m*/ + if ("`test'"=="R"|"`test'"=="Q")&("`method'"=="mml"|"`method'"=="gee") { + local c`nbitems' exp(`c`nbitems'')/(`c0') + local c0 1/(`c0') + gausshermite `c0', sigma(`sig') + local ci0=r(int)*`nbind' + gausshermite `c`nbitems'',sigma(`sig') + local ci`nbitems'=`nbind'*r(int) + scalar `stattest'=`stattest'+(`nbrealscore0'-`ci0')^2/`ci0'+(`nbrealscore`nbitems''-`ci`nbitems'')^2/`ci`nbitems'' + } + + + +/*********************************************************************************************************** +TESTS U +************************************************************************************************************/ + + if "`method'"=="cml" { + if "`trace'"!="" { + di in green "*** Tests U" + } + + local quartile=`nbind'/4 + local c1=0 + local n1=0 + while `n1'<`quartile' { + local c1=`c1'+1 + local n1=`n1'+`nbrealscore`c1'' + } + local c2=`nbitems' + local n2=0 + while `n2'<`quartile' { + local c2=`c2'-1 + local n2=`n2'+`nbrealscore`c2'' + } + forvalues j=1/`nbitems' { + local zu1=0 + local zu2=0 + forvalues s=1/`c1' { + local zu1=`zu1'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s'])) + } + forvalues s=`c2'/`=`nbitems'-1' { + local zu2=`zu2'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s'])) + } + local U`j'=(`zu1'-`zu2')/sqrt(`c1'+`nbitems'-`c2') + } + } + + + +/*********************************************************************************************************** +TESTS OF THE SECOND ORDER /*undocumented in beta test*/ +************************************************************************************************************/ + + if "`q2'"!="" { + if "`trace'"!="" { + di in green "*** Tests of the second order" + } + + tempfile Q2file + qui save "`Q2file'",replace + qui use "`saveraschtest'",replace + + qui keep if `touse'==1 + gen `score'=0 + + forvalues i=1/`nbitems' { + local Q2i`i' + rename ``i'' `rep'`i' + qui replace `score'=`score'+`rep'`i' + } + qui recode `score' `recode' + + forvalues i=1/`nbitems' { + local Q2i`i'=0 + forvalues j=`=`i'+1'/`nbitems' { + local listinci`i'j`j' + forvalues k=1/`nbitems' { + if `k'!=`i'&`k'!=`j' { + local listinci`i'j`j' "`listinci`i'j`j'' `beta`k''" + } + } + } + } + + local Q2tot=0 + forvalues k=2/`=`nbitems'-1' { + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + if `k'==1 { + local num=0 + } + else { + gammasym `listinci`i'j`j'' + local num=r(gamma`=`k'-2') + } + local athi`i'j`j'k`k'=exp(-`beta`i'')*exp(-`beta`j'')*`num'/`denom`k'' + local bthi`i'j`j'k`k'=`nbth`i's`k''-`athi`i'j`j'k`k'' + local cthi`i'j`j'k`k'=`nbth`j's`k''-`athi`i'j`j'k`k'' + local dthi`i'j`j'k`k'=1-`athi`i'j`j'k`k''-`bthi`i'j`j'k`k''-`cthi`i'j`j'k`k'' + } + } + } + forvalues k=1/`=`nbgroups'-1' { + local Q2`k'=0 + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`j'+1'/`nbitems' { + qui count if `rep'`i'==1&`rep'`j'==1&`score'==`k' + local aempi`i'j`j'k`k'=r(N) + local ath2i`i'j`j'k`k'=0 + local bth2i`i'j`j'k`k'=0 + local cth2i`i'j`j'k`k'=0 + local dth2i`i'j`j'k`k'=0 + } + } + if `limsup`k''!=1 { + forvalues l=`liminf`k''/`limsup`k'' { + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + if `l'!=1 { + local ath2i`i'j`j'k`k'=`ath2i`i'j`j'k`k''+`athi`i'j`j'k`l''*`nbrealscore`l'' + local bth2i`i'j`j'k`k'=`bth2i`i'j`j'k`k''+`bthi`i'j`j'k`l''*`nbrealscore`l'' + local cth2i`i'j`j'k`k'=`cth2i`i'j`j'k`k''+`cthi`i'j`j'k`l''*`nbrealscore`l'' + local dth2i`i'j`j'k`k'=`dth2i`i'j`j'k`k''+`dthi`i'j`j'k`l''*`nbrealscore`l'' + } + } + } + } + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + local d2i`i'j`j'k`k'=(`aempi`i'j`j'k`k''-`ath2i`i'j`j'k`k'')^2 + local Q2i`i'j`j'k`k'=`d2i`i'j`j'k`k''/`ath2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`bth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`cth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`dth2i`i'j`j'k`k'' + local Q2i`i'=`Q2i`i''+`Q2i`i'j`j'k`k'' + local Q2i`j'=`Q2i`j''+`Q2i`i'j`j'k`k'' + local Q2`k'=`Q2`k''+`Q2i`i'j`j'k`k'' + } + } + } + local Q2tot=`Q2tot'+`Q2`k'' + } + forvalues i=1/`nbitems' { + di in green "Item ``i'' : Q2 = `Q2i`i''" + } + local Q2=`Q2tot'*(`nbitems'-3)/(`nbitems'-1) + di in green "Q2 = `Q2tot'" + qui use "`Q2file'",replace + } + +/*********************************************************************************************************** +TEST LR Z +************************************************************************************************************/ + + if "`method'"=="cml" { + if "`trace'"!="" { + di in green "*** Tests LR of Andersen" + } + local ssll=0 + tempfile Zfile + qui save "`Zfile'", replace + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + gen `score'=0 + forvalues j=1/`nbitems' { + qui replace `score'=`score'+``j'' + } + qui recode `score' `recode' `nbitems'=`nbgroups' + forvalues i=1/`=`nbgroups'-1' { + if `effscore`i''>0 { + qui raschtestv7 `varlist' if `score'==`i', test(NONE) `ld' id(`id') + local ll`i'=r(cll) + local ssll=`ssll'+(`ll`i'') + } + } + local Z=2*`ssll'-2*`ll' + use "`Zfile'",replace + tempname AndersenZ + matrix define `AndersenZ'=(`Z',`=(`nbgroups'-2)*(`nbitems'-1)',1-chi2(`=(`nbitems'-1)*(`nbgroups'-2)',`Z')) + } +} + + +/*********************************************************************************************************** +DISPLAYING RESULTS WITH TESTS +************************************************************************************************************/ +if "`html'" != "" { + di "" +} + +if "`test'"!="NONE" { + local conttest= "_c" +} +di +tempname itemfit globalfit +matrix `globalfit'=J(1,3,0) +if "`method'"=="cml" { + if "`html'" == "" { + di in green "Estimation method: " in yellow "Conditional maximum likelihood (CML)" + } + else { + di "

Estimation method: Conditional maximum likelihood (CML)

" + } + local nbtest=`nbgroups'-1 + local line=77 +} +else if "`method'"=="mml"{ + if "`html'" == "" { + di in green "Estimation method: " in yellow "Marginal maximum likelihood (MML)" + } + else { + di "

Estimation method: Marginal maximum likelihood (MML)

" + } + local nbtest=`nbgroups'+1 + local line=70 +} +else if "`method'"=="gee" { + di in green "Estimation method: " in yellow "Generalized Estimating Equations (GEE)" + local nbtest=`nbgroups'+1 + local line=70 +} +if "`test'"=="NONE" { + local line=35 +} + +if "`html'" == "" { + di in green "Number of items: " in yellow `nbitems' + di in green "Number of groups: " in yellow `=`nbgroups'+1' `conttest' + if "`test'"!="NONE" { + di in green " (" in yellow "`nbtest'" in green " of them are used to compute the statistics of test)" + } +} +else { + di "Number of items: " `nbitems' "
" + di "Number of groups: " `=`nbgroups'+1' `conttest' + if "`test'"!="NONE" { + di " (`nbtest' of them are used to compute the statistics of test)" + } + di "
" +} +if "`method'"=="cml" { + local nbind=`nbind'+`effscore0'+`effscore`nbgroups'' + local cont "_c" + matrix `itemfit'=J(`nbitems',6,0) +} +else { + local cont + matrix `itemfit'=J(`nbitems',5,0) +} +local missing=`N'-`nbind' +if "`html'" == "" { + di in green "Number of individuals: " in yellow `N' + di in green "Number of individuals with missing values: " in yellow `nbindmiss' _c + if "`ld'"=="" { + di in green " (removed)" + } + else { + di + } + di in green "Number of individuals with nul or perfect score: " in yellow `=`effscore0'+`effscore`nbgroups''' +} +else { + di "Number of individuals: `N'
" + di "Number of individuals with missing values: " `nbindmiss' + if "`ld'"=="" { + di " (removed)" + } + di "
" + di "Number of individuals with nul or perfect score: " `=`effscore0'+`effscore`nbgroups''' "
" +} +if "`method'"=="cml" { + if "`html'" == "" { + di in green "Conditional log-likelihood: " in yellow %-13.4f `ll' + di in green "Log-likelihood: " in yellow %-13.4f `globalll' + } +} +else { + if "`html'" == "" { + di in green "Marginal log-likelihood: " in yellow %-13.4f `ll' + di in green "Log-likelihood: " in yellow %-13.4f `globalll' + di + } + else { + di "Marginal log-likelihood: " %-13.4f `ll' "
" + di "Log-likelihood: " %-13.4f `globalll' "

" + } +} + +if "`html'" == "" { + noi di in green _col(16) "Difficulty" `conttest' + if "`test'"!="NONE"&"`stand'"=="" { + di in green _col(58) "Standardized" + } + if "`test'"!="NONE"&"`stand'"!="" { + di + } + noi di in green _col(9) "Items" _col(16) "parameters" _col(28) "std Err." `conttest' + if "`test'"!="NONE" { + local varin=int(2/sqrt(`nbind')*100)/100 + local varout=int(6/sqrt(`nbind')*100)/100 + di _col(41) "`namewp'" _col(47) "df" _col(50) "p-value" _col(58) "Outfit" _col(66) "Infit" `cont' + if "`method'"=="cml" { + di in green _col(77) "U" + } + } + di in green "{hline `line'}" +} +else { + di "" + di "" + di "" + if "`test'"!="NONE" { + di "" + } + di "" + di "" + if "`test'"!="NONE" { + local varin=int(2/sqrt(`nbind')*100)/100 + local varout=int(6/sqrt(`nbind')*100)/100 + di "" + if "`method'"=="cml" { + di "" + } + } + di "" +} + +forvalues i=1/`nbitems' { + if "`html'" == "" { + noi di in yellow _col(3) %12s abbrev("``i''`fixed`i''" ,12) in yellow _col(18) %8.5f `beta`i'' _col(29) %6.5f `sd`i'' `conttest' + } + else { + di "" + } + if "`test'"!="NONE" { + if "`html'" == "" { + if "`stand'"=="" { + di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfitstd`i'' _col(65) %6.3f `infitstd`i'' /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/ `cont' +* di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfit`i'' _col(65) %6.3f `infit`i'' /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/ `cont' + } + else { + di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfit`i'' _col(65) %6.3f `infit`i'' /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/ `cont' + } + } + else { + if "`stand'"=="" { + di "" + } + else { + di "" + } + } + matrix `itemfit'[`i',1]=`testitems'[`i',1] + matrix `itemfit'[`i',2]=`=`nbgroups'-2' + matrix `itemfit'[`i',3]=1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) + if "`stand'"=="" { + matrix `itemfit'[`i',4]=`outfitstd`i'' + matrix `itemfit'[`i',5]=`infitstd`i'' + } + else { + matrix `itemfit'[`i',4]=`outfit`i'' + matrix `itemfit'[`i',5]=`infit`i'' + } + + if "`method'"=="cml" { + if "`html'" == "" { + di in ye _col(72) %6.3f `U`i'' + } + else { + di "" + } + matrix `itemfit'[`i',6]=`U`i'' + } + if "`html'" != "" { + di "" + } + } +} +if "`html'" == "" { + di in green "{hline `line'}" +} +else { + di "" +} +if "`test'"!="NONE" { + if "`method'"=="cml" { + local df=(`nbgroups'-2)*(`nbitems'-1) + } + else { + local df=(`nbgroups'-1)*(`nbitems'-1)-1 + } + matrix `globalfit'=(`stattest',`df',1-chi2(`df',`stattest')) + if "`html'" == "" { + noi di in green _col(6) "`descwp'" _col(32) in gr "`namewp'=" _col(36) in ye %8.3f `globalfit'[1,1] _col(46) %3.0f `globalfit'[1,2] _col(51) %6.4f `globalfit'[1,3] + if "`method'"=="cml" { + noi di in green _col(6) "Andersen LR test" _col(34) "Z=" in yellow _col(36) %8.3f `AndersenZ'[1,1] _col(46) %3.0f `AndersenZ'[1,2] _col(51) %6.4f `AndersenZ'[1,3] + } + di in green "{hline `line'}" + } + else { + di "" + if "`method'"=="cml" { + di "" + } + di "
DifficultyStandardized
Itemsparametersstd Err.`namewp'dfp-valueOutfitInfitU
" %12s abbrev("``i''`fixed`i''" ,12) "" %8.5f `beta`i'' "" %6.5f `sd`i'' "" %8.3f `testitems'[`i',1] "" %3.0f `=`nbgroups'-2' "" %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) "" %6.3f `outfitstd`i'' "" %6.3f `infitstd`i'' "" %8.3f `testitems'[`i',1] "" %3.0f `=`nbgroups'-2' "" %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) "" %6.3f `outfit`i'' "" %6.3f `infit`i'' "" %6.3f `U`i'' "
`descwp'`namewp'=" %8.3f `globalfit'[1,1] "" %3.0f `globalfit'[1,2] "" %6.4f `globalfit'[1,3] "
Andersen LR testZ=" %8.3f `AndersenZ'[1,1] "" %3.0f `AndersenZ'[1,2] "" %6.4f `AndersenZ'[1,3] "
" + } +} + +if "`html'" == "" { + if "`method'"=="cml"&"`meandiff'"==""{ + di in green "*: The difficulty parameter of this item had been fixed to 0" + } + if "`method'"=="cml"&"`meandiff'"!=""{ + di in green "The mean of the difficulty parameters is fixed to 0" + } + if `smallgroup'==1&"`test'"!="NONE" { + di in green "You have groups of scores with less than 30 individuals. The tests can be invalid." + } + if "`method'"!="cml"&"`test'"=="Q" { + di in green "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test." + } + + di +} +else { + if "`method'"=="cml"&"`meandiff'"==""{ + di "*: The difficulty parameter of this item had been fixed to 0
" + } + if "`method'"=="cml"&"`meandiff'"!=""{ + di "The mean of the difficulty parameters is fixed to 0
" + } + if `smallgroup'==1&"`test'"!="NONE" { + di "You have groups of scores with less than 30 individuals. The tests can be invalid.
" + } + if "`method'"!="cml"&"`test'"=="Q" { + di "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test.
" + } + di "

" +} + +if "`html'" == "" { + if "`method'"!="cml" { + di in green "{hline 56}" + noi di in green _col(5) "Parameters" _col(21) "Coef." _col(28) "std Err." _col(43) "z" _col(52) "P>|z|" + di in green "{hline 56}" + local zsig=`sig'/`sesig' + local pzsig=2*(1-norm(abs(`zsig'))) + di in green _col(10) in yellow "Sigma" _col(18) %8.5f `sig' _col(29) %6.5f `sesig' _col(38) %6.3f `zsig' _col(50) %7.4f `pzsig' + di in green "{hline 56}" + } +} +else { + if "`method'"!="cml" { + di "" + di "" + di "" + local zsig=`sig'/`sesig' + local pzsig=2*(1-norm(abs(`zsig'))) + di "
ParametersCoef.std Err.zP>|z|
Sigma" %8.5f `sig' "" %6.5f `sesig' "" %6.3f `zsig' "" %7.4f `pzsig' "
" + } +} + + + +*set trace on +if "`covariables'"!="" { + tempname zcovariates pcovariates + matrix `zcovariates'=J(1,`nbcovariables',0) + matrix `pcovariates'=J(1,`nbcovariables',0) + forvalues i=1/`nbcovariables' { + local tmp :word `i' of `covariables' + local zcov=`betacov'[1,`i']/`Vbetacov'[`i',`i']^.5 + local pzcov=2*(1-norm(abs(`zcov'))) + matrix `zcovariates'[1,`i']=`zcov' + matrix `pcovariates'[1,`i']=`pzcov' + di in green _col(3) %12s in yellow abbrev("`tmp'",12) _col(18) %8.5f `betacov'[1,`i'] _col(29) %6.5f `Vbetacov'[`i',`i']^.5 _col(38) %6.3f `zcov' _col(50) %7.4f `pzcov' + } + di in green "{hline 56}" + local difficulties2 + if "`difficulties'"!="" { + local difficulties2 diff(`difficulties') + } + if "`ss1'"!="" { + tempfile ss1save + qui save `ss1save' + qui use `saveraschtest' + qui keep if `touse'==1 + + qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2' + local sigma0=r(sigma) + local var0=`sigma0'^2 + local nbobs=r(N_obs) + *di "nbobs=`nbobs'" + local df0=`nbobs'-(`nbitems'+1)-1 + local ss10=`var0'*(`df0') + local ss1c0=0 + di + di in green "Type 1 Sum of Squares (sequential)" + di "{hline 85}" + di in green _col(44) "Degrees" _col(56) "Variance of the" _col(77) "Explained" + di in green _col(4) "Covariates" _col(25) "SS" _col(35) "Diff" _col(41) "of freedom"_col(59) "latent trait" _col(78) "Variance" + di "{hline 85}" + di _col(10) in green "None" _col(15) in ye %12.3f `ss10' _col(47) %4.0f `df0' _col(63) %8.3f `var0' + di in green "{dup 85:-}" + local covariablesss1 + forvalues i=1/`nbcovariables' { + local covariablesss1 `covariablesss1' `covariable`i'' + qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss1') test(none) `ld' `difficulties2' + local nbobs=r(N_obs) + local sigma`i'=r(sigma) + local var`i'=`sigma`i''^2 + local nbcovtmp:word count `covariablesss1' + *di " ss1`i'=`var`i''*`=`nbobs'-(`nbitems'+1+`nbcovtmp')-1'" + local df`i'=`nbobs'-(`nbitems'+1+`nbcovtmp')-1 + *di "local df`i'=`nbobs'-(`nbitems'+1+`nbcovtmp')-1 (cov:`covariablesss1')" + local ss1`i'=`var`i''*`df`i'' + *di "cov : `covariablesss1' var=`var`i'' df=`df`i''" + di _col(2) %12s in yellow abbrev("`covariable`i''",12) _col(15) %12.3f in ye `ss1`i'' _col(25) %12.3f `=`ss1`=`i'-1''-`ss1`i''' _col(47) %4.0f `df`i'' _col(63) %8.3f `var`i'' _col(81) %5.3f (`=`ss1`=`i'-1''-`ss1`i''')/`ss10' + } + di in green "{hline 85}" + qui use `ss1save' + } + if "`ss3'"!="" { + tempfile ss3save + qui save `ss3save' + qui use `saveraschtest' + qui keep if `touse'==1 + if "`ss1'"=="" { + qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2' + local sigma0=r(sigma) + local var0=`sigma0'^2 + local nbobs=e(N_obs) + local df0=`nbobs'-(`nbitems'+1)-1 + local ss30=`var0'*(`df0') + } + else { + local ss30=`ss10' + } + local ss3ref=`=`sig'^2*(`df0'-`nbcovariables')' + di + di in green "Type 3 Sum of Squares " + di "{hline 85}" + di in green _col(44) "Degrees" _col(56) "Variance of the" _col(77) "Explained" + di in green _col(4) "Covariates" _col(25) "SS" _col(35) "Diff" _col(41) "of freedom"_col(59) "latent trait" _col(78) "Variance" + di "{hline 85}" + di _col(10) in green "None" _col(15) in ye %12.3f `ss30' _col(47) %4.0f `df0' _col(63) %8.3f `var0' + di _col(6) in green "Complete" _col(15) in ye %12.3f `ss3ref' _col(25) %12.3f `=`ss30'-`ss3ref'' _col(47) %4.0f `=`df0'-`nbcovariables'' _col(63) %8.3f `sig'^2 _col(81) %5.3f 1-`sig'^2*(`df0'+`nbcovariables')/`ss30' + di in green "{dup 85:-}" + forvalues i=1/`nbcovariables' { + local covariablesss3 + forvalues j=1/`nbcovariables' { + if `i'!=`j' { + local covariablesss3 `covariablesss3' `covariable`j'' + } + } + qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss3') test(none) `ld' `difficulties2' + *ereturn list + local sigmas`i'=r(sigma) + local vars`i'=`sigmas`i''^2 + local nbobs=e(N) + local dfs`i'=`nbobs'-(`nbitems'+1)-1-(`nbcovariables'-1) + *di "local dfs`i'=`nbobs'-(`nbitems'+1)-1-(`nbcovariables'-1)" + local ss3s`i'=`vars`i''*`dfs`i'' + local vara`i'=`sig'^2 + local dfa`i'=`nbobs'-(`nbitems'+1)-1-`nbcovariables' + local ss3a`i'=`vara`i''*`dfa`i'' + *di "cov : `covariablesss3' var=`vars`i'' df=`dfs`i''" + di _col(2) %12s in green abbrev("`covariable`i''",12) _col(15) in ye %12.3f `ss3s`i'' _col(25) %12.3f in ye `=`ss3s`i''-`ss3a`i''' _col(47) %4.0f `=`df0'-`nbcovariables'+1' _col(63) %8.3f `vars`i'' _col(80) %6.3f (`=`ss3s`i''-`ss3a`i''')/`ss30' + } + di in green "{hline 85}" + qui use `ss3save' + } +} + + + +/*Tabular of the estimated values of the latent trait*/ + +if "`covariables'"=="" { + if "`html'" == "" { + di + di + noi di in green _col(33) "Ability" _col(60) "Expected" + noi di in green _col(17) "Group" _col(23) "Score" _col(30) "parameters" _col(42) "std Err." _col(54) "Freq." _col(63) "Score"_c + if "`method'"=="cml"&"`test'"!="NONE" { + noi di in green _col(75) "ll" + } + else { + noi di "" + } + if "`method'"=="cml"&"`test'"!="NONE" { + local line=62 + } + else { + local line=51 + } + di in green _col(17) "{hline `line'}" + } + else { + di "" + di "" + di "" + if "`method'"=="cml"&"`test'"!="NONE" { + di "" + } + di "" + } + + local nonul=0 + forvalues g=0/`nbgroups' { + if `g'!=0 { + if "`html'" == "" { + di in green _col(17) "{dup `line':-}" + } + } + forvalues s=`liminf`g''/`limsup`g'' { + if `s'==`liminf`g'' { + local tmp `ll`g'' + local gr `g' + } + else { + local tmp + local gr + } + local expscore`nonul'=0 + forvalues i=1/`nbitems' { + local expscore`nonul'=`expscore`nonul''+1/(1+exp(-`theta`nonul''+`beta`i'')) + } + if "`method'"=="cml" { + local format1 %8.3f + } + else { + local format1 %8.5f + } + if "`html'" == "" { + noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(32) `format1' `theta`nonul'' _col(42) `format1' `sdtheta`nonul'' _col(55) %4.0f `nbrealscore`s'' _col(64) % 4.2f `expscore`nonul'' _col(68) %11.4f `tmp' + } + else { + di "" + } + local nonul=`nonul'+1 + } + } + if "`html'" == "" { + di in green _col(17) "{hline `line'}" + } + else { + di "
GroupScoreAbility
parameters
std Err.Freq.Expected
Score
ll
" %5s "`gr'" "" %5s "`s'" "" `format1' `theta`nonul'' "" `format1' `sdtheta`nonul'' "" %4.0f `nbrealscore`s'' "" % 4.2f `expscore`nonul'' "" %11.4f `tmp' "
" + } +} + +if "`method'"=="mml"|"`method'"=="gee" { + if "`html'" == "" { + di + *di in green "Variance of the estimated latent trait" _col(45) in ye %10.4f `vartheta' + di in green "Mean variance of the error" _col(45) in ye %10.4f `meanse2' + local sig2=`sig'^2 + di in green "Estimated variance of the latent trait" _col(45) in ye %10.4f `sig2' + local psi2=1-`meanse2'/`sig2' + di in green "Personal Separation Index (PSI)" _col(45) in ye %10.4f `psi2' + di in green "Adjusted PSI on covariates (PSIadj)" _col(45) in ye %10.4f `psi' + } + else { + di "" + di "" + di "" + di "" + local sig2=`sig'^2 + di "" + local psi2=1-`meanse2'/`sig2' + di "" + di "" + di "
Mean variance of the error" %10.4f `meanse2' "
Estimated variance of the latent trait" %10.4f `sig2' "
Personal Separation Index (PSI)" %10.4f `psi2' "
Adjusted PSI on covariates (PSIadj)" %10.4f `psi' "
" + } +} + + +/*********************************************************************************************************** +DETAILS OPTION +************************************************************************************************************/ + +if "`details'"!="" { + if "`html'"=="" { + forvalues g=0/`nbgroups' { + if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" { + di + di in green "{hline 44}" + di in green "Group: " in ye "`g'" in green " from " in ye "`liminf`g''" in green " to " in ye "`limsup`g''" in green " (n=" in ye "`nbscore`g''" in green")" + di + di _col(3) "Item" _col(10) "Observed" _col(23) "Expected" _col(37) "Scaled" + di in green "{dup 44:-}" + } + if `g'!=0&`g'!=`nbgroups' { + forvalues j=1/`nbitems' { + local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j']) + di _col(3) in ye "``j''" _col(14) %4.0f `Obs2'[`j',`g'] _col(25) %6.2f `Th2'[`j',`g'] _col(36) %7.4f `tmp' + } + di in green "{dup 44:-}" + di in green "Contribution to the `namewp' statistics: " %8.4f in ye `test`g''[1,1] + } + else if "`method'"!="cml" { + if `g'==0 { + local h=0 + } + else { + local h=`nbitems' + } + local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'') + di in ye _col(14) %4.0f `nbrealscore`h'' _col(25) %6.2f `ci`h'' _col(36) %7.4f `tmp' + di in green "{dup 44:-}" + local tmp=`tmp'^2 + di in green "Contribution to the `namewp' statistics: " %8.4f in ye `tmp' + } + } + } + else { + forvalues g=0/`nbgroups' { + if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" { + di in gr "" + di in gr "" + di in gr "" + } + if `g'!=0&`g'!=`nbgroups' { + forvalues j=1/`nbitems' { + local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j']) + di "" + } + di "" + } + else if "`method'"!="cml" { + if `g'==0 { + local h=0 + } + else { + local h=`nbitems' + } + local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'') + di "" + local tmp=`tmp'^2 + di "" + } + di "
Group: `g' from `liminf`g'' to `limsup`g'' (n=`nbscore`g'')
ItemObservedExpectedScaled
``j''" %4.0f `Obs2'[`j',`g'] "" %6.2f `Th2'[`j',`g'] "" %7.4f `tmp' "
Contribution to the `namewp' statistics:" %8.4f `test`g''[1,1] "
" %4.0f `nbrealscore`h'' "" %6.2f `ci`h'' "" %7.4f `tmp' "
Contribution to the `namewp' statistics:" %8.4f `tmp' "
" + } + } +} + +/*********************************************************************************************************** +OPTION ICC +************************************************************************************************************/ +*set trace on +if "`icc'"!="" { + if "`trace'"!="" { + di in green "*** Items Characteristic Curves" + } + tempvar proba propemp propth propthb + qui replace `tl'=. if `realscore'==0|`realscore'==`nbitems'|`realscore'==. + qui gen `propemp'=. + qui gen `propth'=. + qui gen `propthb'=. + label variable `propth' "Expected ICC" + label variable `propemp' "Observed ICC" + label variable `propthb' "Expected ICC" + label variable `tl' "Latent trait" + global iccs + forvalues i=1/`nbitems' { + forvalues s=1/`=`nbitems'-1' { + qui replace `propthb'=exp(`theta`s''-`beta`i'')/(1+exp(`theta`s''-`beta`i'')) if `item'==`i'&`realscore'==`s' + } + qui replace `propemp'=. + qui replace `propth'=. + tempvar propemp`i' propth`i' + qui bysort `realscore' `item' : egen `propth`i''=mean(`propthb') if `item'==`i' + qui bysort `realscore' `item' : egen `propemp`i''=mean(`rep') if `item'==`i' + qui replace `propth'=`propth`i'' if `item'==`i' + qui replace `propemp'=`propemp`i'' if `item'==`i' + local mintl=floor(`theta1') + local maxtl=floor(`theta`=`nbitems'-1'')+1 + if "`filessave'"!=""{ + local saving "`dirsave'\\icc``i''" + } + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_icc_``i''" + } + if "`v8'"!=""|"`html'"!="" { + graph twoway (line `propemp' `propth' `tl') if `item'==`i' , `htmlregion' name(icc``i'',replace) ytitle("") ylabel(0(.25)1) title("Observed and Expected ICC for the item ``i''") xlabel(`mintl'(1)`maxtl') xsize(12) ysize(9) `draw' + if "`html'"=="" { + pause + } + else { + qui graph save icc``i'' "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_icc_``i''.eps, replace + di " _char(34) " + + } + *set trace on + if "`filessave'"!="" { + qui graph save icc``i'' "`saving'" , `replace' + if "`extension'"!="" { + if "`graphclose'"!="" { + graph close + } + *qui graph use `dirsave'\\icc``i'' + qui graph export `dirsave'\\icc``i''.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + putdocx image `dirsave'\\icc``i''.`extension', width(4) + } + } + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + qui graph `propemp' `propth' `tl' if `item'==`i' , twoway `saving' c(ll) ylabel(0(.25)1) xlabel(`mintl'(1)`maxtl') title("Observed and Expected ICC for the item ``i''") + pause + } + } +} + +/*********************************************************************************************************** +OPTION INFORMATION +************************************************************************************************************/ + +if "`information'"!="" { + if "`trace'"!="" { + di in green "*** Information graph" + } + + tempfile saveinfo + qui save "`saveinfo'",replace + tempvar info latent + forvalues i=1/`nbitems' { + tempvar info``i'' + } + drop _all + qui set obs 2001 + gen `latent'=((_n-1)/1001-1)*3 + label variable `latent' "latent trait" + gen `info'=0 + local gphbyitem + forvalues i=1/`nbitems' { + qui gen `info``i'''=exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2 + label variable `info``i''' "``i''" + qui replace `info'=`info'+exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2 + local gphbyitem `gphbyitem' `info``i''' + } + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_information" + } + if "`v8'"!=""|"`html'"!="" { + *set trace on + local saving "`dirsave'\\information" + graph twoway (line `info' `latent') , `htmlregion' name(information,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the scale") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + qui graph save information "`saving'" , `replace' + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\information + qui graph export `dirsave'\\information.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\information.`extension', width(4) + } + + } + } + if "`html'"=="" { + pause + } + else { + qui graph save information "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_information.eps, replace + di " _char(34) " + } + local saving "`dirsave'\\inf_items" + graph twoway (line `gphbyitem' `latent') , `htmlregion' name(inf_items,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the items") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + qui graph save inf_items "`saving'" , `replace' + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\inf_items + qui graph export `dirsave'\\inf_items.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\inf_items.`extension', width(4) + } + + } + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + if "`filessave'"=="" { + local saving + } + qui graph `info' `latent' , twoway `saving' c(l) xlabel(-3(1)3) title("Information graph of the scale") + pause + } + qui use "`saveinfo'",replace +} + +/*********************************************************************************************************** +OPTION FITGRAPH +************************************************************************************************************/ + +if "`fitgraph'"!="" { + if "`trace'"!="" { + di in green "*** Graphical validation of the fit" + } + *set trace on + tempname outfit meanz2 meanv2 sumd infit Voutfit outfitstd Vinfit infitstd + qui egen `outfit'=mean(`y2'),by(`id') + qui egen `Voutfit'=sum(`r'),by(`id') + qui replace `Voutfit'=`Voutfit'/(`nbitems')^2-1/`nbitems' + qui gen `outfitstd'=(`outfit'^(1/3)-1)*(3/sqrt(`Voutfit'))-sqrt(`Voutfit')/3 + qui egen `meanz2'=sum(`z2'),by(`id') + qui egen `meanv2'=sum(`v2'),by(`id') + qui gen `infit'=`meanz2'/`meanv2' + qui egen `Vinfit'=sum(`e'),by(`id') + qui replace `Vinfit'=`Vinfit'/(`meanv2')^2 + qui gen `infitstd'=(`infit'^(1/3)-1)*(3/sqrt(`Vinfit'))-sqrt(`Vinfit')/3 + + qui su `outfitstd' + local mino=floor(2*min(`r(min)',-2))/2 + local maxo=ceil(2*max(`r(max)',2))/2 + qui su `infitstd' + local mini=floor(2*min(`r(min)',-2))/2 + local maxi=ceil(2*max(`r(max)',2))/2 + if "`filessave'"!=""{ + local savingo "`dirsave'\\outfitind" + local savingi "`dirsave'\\infitind" + } + if "`v8'"!="" { + graph twoway (scatter `outfitstd' `id'), `htmlregion' name(outfit,replace) yline(-2 2) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw' + if "`html'"=="" { + pause + } + graph twoway (scatter `infitstd' `id'), `htmlregion' name(infit,replace) yline(-2 2) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw' + if "`html'"=="" { + pause + } + if "`filessave'"!=""|"`html'"!="" { + qui graph save outfit "`savingo'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_outfit.eps, replace + } + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\outfitind + qui graph export `dirsave'\\outfit.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\outfit.`extension', width(4) + } + + } + qui graph save infit "`savingi'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_infit.eps, replace + } + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\infitind + qui graph export `dirsave'\\infit.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\infit.`extension', width(4) + } + } + } + } + else { + if "`filessave'"!="" { + local savingo "saving(`savingo'" + local savingi "saving(`savingi'" + if "`replace'"=="" { + local savingo "`savingo')" + local savingi "`savingi')" + } + else { + local savingo "`savingo',replace)" + local savingi "`savingi',replace)" + } + } + graph `outfitstd' `id', `savingo' twoway sy(.) c(.) yline(-2 2) title("Outfit indexes") b2title("Individual indexes") l1("") l2title("Outfit") ylabel(`mino'(.5)`maxo') + pause + graph `infitstd' `id', `savingi' twoway sy(.) c(.) yline(-2 2) title("Infit indexes") b2title("Individual indexes") l1("") l2title("Infit") ylabel(`mini'(.5)`maxi') + pause + } + drop _all + qui set obs `nbitems' + tempvar name betap outfitstdj infitstdj + qui gen str9 `name'="" + qui gen `betap'=. + qui gen `outfitstdj'=. + qui gen `infitstdj'=. + local mino=-2 + local maxo=2 + local mini=-2 + local maxi=2 + forvalues j=1/`nbitems' { + qui replace `name'="``j''" in `j' + qui replace `betap'=`beta`j'' in `j' + qui replace `outfitstdj'=`outfitstd`j'' in `j' + qui replace `infitstdj'=`infitstd`j'' in `j' + local mino=floor(min(`mino',`outfitstd`j'')*2)/2 + local mini=floor(min(`mini',`infitstd`j'')*2)/2 + local maxo=ceil(max(`maxo',`outfitstd`j'')*2)/2 + local maxi=ceil(max(`maxi',`infitstd`j'')*2)/2 + } + if "`filessave'"!=""{ + local savingo "`dirsave'\\outfititems" + local savingi "`dirsave'\\infititems" + } + if "`v8'"!="" { + graph twoway (scatter `outfitstdj' `betap',`htmlregion' name(outfititem,replace) mlabel(`name')), yline(-2 2) title("Outfit indexes") xtitle("Difficulty") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw' + if "`html"=="" { + pause + } + graph twoway (scatter `infitstdj' `betap',`htmlregion' name(infititem,replace) mlabel(`name')), yline(-2 2) title("Infit indexes") xtitle("Difficulty") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw' + if "`html"=="" { + pause + } + if "`filessave'"!=""|"`html'"!="" { + qui graph save outfititem "`savingo'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_outfititem.eps, replace + } + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\outfititems + qui graph export `dirsave'\\outfititems.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\outfititems.`extension', width(4) + } + } + qui graph save infititem "`savingi'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_infititems.eps, replace + } + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\infititems + qui graph export `dirsave'\\infititems.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\infititems.`extension', width(4) + } + + } + } + } + else { + if "`filessave'"!="" { + local savingo "saving(`savingo'" + local savingi "saving(`savingi'" + if "`replace'"=="" { + local savingo "`savingo')" + local savingi "`savingi')" + } + else { + local savingo "`savingo',replace)" + local savingi "`savingi',replace)" + } + } + graph `outfitstdj' `betap', `savingo' twoway c(.) yline(-2 2) title("Outfit indexes") b2title("Difficulty") l1title("") l2title("Outfit") ylabel(`mino'(.5)`maxo') sy([`name']) + pause + graph `infitstdj' `betap', `savingi' twoway c(.) yline(-2 2) title("Infit indexes") b2title("Difficulty") l1title("") l2title("Infit") ylabel(`mini'(.5)`maxi') sy([`name']) + pause + } +} + + +/*********************************************************************************************************** +OPTION SPLITTESTS +************************************************************************************************************/ + +if "`splittests'"!="" { + if "`trace'"!="" { + di in green "*** Splitting tests" + } + forvalues j=1/`nbitems' { + tempname estneg`j' estpos`j' + local listitems + forvalues k=1/`nbitems' { + if `j'!=`k' { + local listitems `listitems' ``k'' + } + } + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + qui raschtestv7 `listitems' if ``j''==0,test(NONE) meth(cml) `ld' id(`id') + matrix `estneg`j''=r(beta) + local llneg=r(cll) + qui raschtestv7 `listitems' if ``j''==1,test(NONE) meth(cml) `ld' id(`id') + matrix `estpos`j''=r(beta) + local llpos=r(cll) + qui raschtestv7 `listitems',test(NONE) meth(cml) `ld' id(`id') + local llnegpos=r(cll) + local nbcol=colsof(`estneg`j'') + local meanneg=0 + local meanpos=0 + forvalues k=1/`nbcol' { + local meanneg=`meanneg'+`estneg`j''[1,`k'] + local meanpos=`meanpos'+`estpos`j''[1,`k'] + } + local meanneg=`meanneg'/`nbitems' + local meanpos=`meanpos'/`nbitems' + forvalues k=1/`nbcol' { + matrix `estneg`j''[1,`k']=`estneg`j''[1,`k']-`meanneg' + matrix `estpos`j''[1,`k']=`estpos`j''[1,`k']-`meanpos' + if "`method'"=="cml" { + matrix `estneg`j''=`estneg`j'',-`meanneg' + matrix `estpos`j''=`estpos`j'',-`meanpos' + } + } + drop _all + qui set obs `=`nbitems'+1' + tempvar neg pos name diag + qui gen `neg'=. + qui gen `pos'=. + qui gen str9 `name'="" + local min=`estneg`j''[1,1] + local max=`estneg`j''[1,1] + forvalues k=1/`=`nbitems'-1' { + qui replace `neg'=`estneg`j''[1,`k'] in `k' + qui replace `pos'=`estpos`j''[1,`k'] in `k' + local min=min(`min',`estneg`j''[1,`k'],`estpos`j''[1,`k']) + local max=max(`max',`estneg`j''[1,`k'],`estpos`j''[1,`k']) + local tmp:word `k' of `listitems' + qui replace `name'="`tmp'" in `k' + } + local min=floor(`min') + local max=floor(`max')+1 + qui gen `diag'=. + qui replace `diag'=`min' in `nbitems' + qui replace `diag'=`max' in `=`nbitems'+1' + local Zgr=round(2*(`llneg'+`llpos'-`llnegpos'),0.001) + local Zgr=substr("`Zgr'",1,6) + local pgr=round(1-chi2(`=`nbitems'-1',`Zgr'),0.0001) + local pgr=substr("`pgr'",1,5) + local note="Z=`Zgr', df=`=`nbitems'-1' , p=`pgr'" + if "`filessave'"!=""{ + local saving "`dirsave'\\split``j''" + } + if "`v8'"!="" { + graph twoway (scatter `pos' `neg' ,mlabel(`name')) (line `diag' `diag'), ytitle("Positive answer") xtitle("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title(Splitting on ``j'') `draw' legend(off) note("Andersen Z test: `note'") name(split,replace) `draw' + pause + if "`filessave'"!="" { + graph save split "`saving'" , `replace' + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + qui replace `diag'=`neg' if `diag'==. + graph `pos' `diag' `diag', `saving' c(.l) sy([`name']i) l1title("") l2title("Positive answer") b2title("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title("Splitting on ``j'' (`note')") `draw' + pause + } + } +} + +/*********************************************************************************************************** +OPTION GRAPH +************************************************************************************************************/ + +if "`graph'"!=""&"`v8'"!="" { + if "`trace'"!="" { + di in green "*** Graph option" + } + tempvar latent2 tl2 delta2 tlth2 labdelta2 labtl2 + drop _all + qui set obs 1001 + gen `latent2'=(_n-501)/100 + label variable `latent2' "latent trait" + qui gen `tl2'=. + qui gen `labtl2'="" + forvalues i=0/`nbitems' { + *if (`i'!=0&`i'!=`nbitems')|"`method'"!="cml" { + qui replace `tl2'=`nbrealscore`i''/`N' if round(`latent2',0.01)==round(`theta`i'',0.01) + qui replace `labtl2'="`i'" if round(`latent2',0.01)==round(`theta`i'',0.01) + *} + } + qui gen `delta2'=. + qui gen `labdelta2'="" + forvalues i=1/`nbitems' { + qui replace `delta2'=-.05 if round(`latent2',0.01)==round(`beta`i'',0.01) + qui replace `labdelta2'="``i''" if round(`latent2',0.01)==round(`beta`i'',0.01) + } + if "`method'"=="mml"|"`method'"=="gee" { + qui gen `tlth2'=1/(2*_pi*`sig')*exp(-.5*(`latent2'/`sig')^2) + label variable `tlth2' "Theorical distribution" + local graphmml line `tlth2' `latent2' + } + label variable `tl2' "Score" + label variable `delta2' "Items" + local saving "`dirsave'\\graph" + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_map" + } + local min=-2 + local max=2 + forvalues j=1/`nbitems' { + if `beta`j''<`min' { + local min=`beta`j''-.5 + } + if `beta`j''>`max'&`beta`j''!=. { + local max=`beta`j''+.5 + } + } + if "`method'"=="cml" { + if `theta0'<`min' { + local min=`theta0'-.5 + } + if `theta`=`nbitems'-1''>`max' { + local max=`theta`=`nbitems'-1''+.5 + } + } + else if "`method'"!="cml" { + if `theta0'<`min'&`theta0'!=. { + local min=`theta0'-.5 + } + if `theta`nbitems''>`max'&`theta`nbitems''!=. { + local max=`theta`nbitems''+.5 + } + } + local min=floor(`min') + local max=floor(`max')+1 + qui su `tl2' + local max2=r(max) + if "`method'"!="cml" { + qui su `tlth2' + local max2=max(`max2',`r(max)') + } + qui replace `latent2'=. if `latent2'<`min'|`latent2'>`max' + if "`v8'"!="" { + graph twoway (bar `tl2' `latent2',/*mlabel(`labtl2')*/ barwidth(.3) ) (dropline `delta2' `latent2',mlabel(`labdelta2') mlabposition(6)) (`graphmml'), `htmlregion' name(graph,replace) ytitle("") xlabel(`min'(1)`max') ylabel(-.1 0(0.05)`max2') title("Individuals/items representations") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + qui graph save graph "`saving'" , `replace' + if "`extension'"!="" { + *qui graph use `dirsave'\\graph + qui graph export `dirsave'\\graph.`extension' , `replace' + if "`docx'"!="" { + putdocx paragraph + putdocx text ("In this dataset, there are `r(N)' models") + + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\graph.`extension', width(4) + } + if "`graphclose'"!="" { + qui graph close + } + + } + } + if "`html'"=="" { + pause + } + else { + qui graph save graph "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_map.eps, replace + di " _char(34) " + } + } +} +else if "`graph'"!=""&"`v8'"=="" { + di in ye "The graph option is not available with Stata 7" +} + +/*********************************************************************************************************** +COMPARISON OF TWO POPULATION +************************************************************************************************************/ + +if "`comp'"!=""&"`method'"!="cml" { + di + di _col(4) "{hline 30}" + di _col(4) in green "Comparison of two populations" + di _col(4) "{hline 30}" + di + di _col(4) in green "`comp'==`mincomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmin' _col(30) in green "mean= " _col(35) in yellow %8.4f `meanmin' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmin' + di _col(4) in green "`comp'==`maxcomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmax' _col(30) in green "mean= " _col(35) in yellow %8.4f `meanmax' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmax' + di _col(33) in green "Z= " _col(35) in yellow %8.4f `Zcomp' _col(47) in green "pvalue= " _col(57) in yellow %6.4f `pvalue' +} + +/*********************************************************************************************************** +TEST DIF +************************************************************************************************************/ + +if "`method'"=="cml"&"`dif'"!=""&"`test'"!="NONE" { + if "`trace'"!="" { + di in green "*** Tests of DIF" + } + local ssll=0 + tempname DIFfile + qui save "`DIFfile'", replace + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + unab list:`dif' + local nbdif:word count `list' + tempname DIF + matrix define `DIF'=J(`nbdif',4,0) + local count=1 + di + di _col(4) in green "{hline 45}" + di _col(4) in green "Test of Differential Item Functioning (DIF)" + di _col(4) in green "{hline 45}" + foreach j in `list' { + qui inspect `j' + local nbdif=r(N_unique) + qui su `j' + local maxdif=r(max) + if `nbdif'>10&`maxdif'<=10 { + di in ye "The {hi:dif} option is available with variables containing 10 or more modalities (coded from 0 or 1 to k<10)." + di in ye "The variable `j' (`nbdif' modalities) is omitted." + } + else { + local ssll=0 + forvalues i=0/10 { + qui count if `j'==`i' + local effdif=r(N) + if `effdif'>0 { + qui raschtestv7 `varlist' if `j'==`i', test(NONE) id(`id') + local ll`i'=r(cll) + local ssll=`ssll'+(`ll`i'') + } + } + local Z=2*`ssll'-2*`ll' + local ddl=(`nbdif'-1)*(`nbitems'-1) + matrix define `DIF'[`count',1]=(`count',`Z',`ddl',1-chi2(`ddl',`Z')) + di + di _col(4) in green "Variable:" in ye " `j' " in green " Number of groups: " in ye "`nbdif'" + di _col(4) in green "LR Test Z=" in ye %8.3f `Z' in gr " ddl=" in ye %4.0f `ddl' in gr " p-value=" in ye %6.4f `=1-chi2(`ddl',`Z')' + di + } + local ++count + } + use "`DIFfile'",replace +} + +/*********************************************************************************************************** +RETURN +************************************************************************************************************/ + +if "`trace'"!="" { + di in green "*** Returns" +} +local colnametheta + +forvalues i=0/`nbgroups' { + local colnametheta `colnametheta' score_`i' +} + + +return clear + +if `nbitems'>=3&"`test'"!="NONE" { + matrix colnames `globalfit'=`namewp' df p + matrix rownames `globalfit'=`method' + matrix rownames `itemfit'=`varlist' + matrix roweq `itemfit'=`method' + + if "`method'"=="cml" { + matrix colnames `itemfit'=`namewp' df p outfit infit U + matrix rownames `AndersenZ'=`method' + matrix colnames `AndersenZ'=Z df p + return matrix AndersenZ=`AndersenZ' + if "`dif'"!="" { + matrix rownames `DIF'=`list' + matrix colnames `DIF'=num Z df p + return matrix DIF=`DIF' + } + } + else { + matrix colnames `itemfit'=`namewp' df p outfit infit + } + return matrix itemFit=`itemfit' + return matrix globalFit=`globalfit' +} + +matrix colnames `theta'=`colnametheta' +matrix rownames `theta'=theta +return matrix theta `theta' +matrix colnames `sdtheta'=`colnametheta' +matrix rownames `sdtheta'=`colnametheta' +return matrix Vartheta `sdtheta' +local varlist2 +matrix coleq `beta'=`method' +matrix coleq `Vbeta'=`method' +matrix roweq `Vbeta'=`method' +if "`method'"=="cml" { + forvalues i=1/`=`nbitems'-1' { + local varlist2 `varlist2' ``i'' + } + return scalar cll=`ll' + return scalar ll=`globalll' + local AIC=-2*`globalll'+2*(`nbitems'-1) +} +else { + return scalar ll=`ll' + local varlist2 `varlist' + return scalar sigma=`sig' + return scalar sesigma=`sesig' + local AIC=-2*`ll'+2*(`nbitems'+1) +} + +if "`comp'"!="" { + return scalar Zcomp=`Zcomp' + return scalar pZcomp=`pvalue' +} + +matrix colnames `beta'=`varlist2' +matrix rownames `beta'=beta +return matrix beta `beta' + +matrix colnames `Vbeta'=`varlist2' +matrix rownames `Vbeta'=`varlist2' +return matrix Varbeta `Vbeta' + +return scalar AIC=`AIC' +return scalar N=`nbind' +return scalar N_obs=`nbobserv' + +if "`method'"=="mml" { + return scalar PSI=`psi2' + return scalar PSIadj=`psi' +} +if "`covariables'"!="" { + local tmp + local tmp2 + forvalues i=1/`nbcovariables' { + local tmp `tmp' `covariable`i'' + local tmp2 "`tmp2' :`covariable`i''" + } + matrix colnames `betacov'=`tmp2' + matrix rownames `Vbetacov'=`tmp2' + matrix colnames `Vbetacov'=`tmp2' + matrix colnames `zcovariates'=`tmp' + matrix colnames `pcovariates'=`tmp' + return matrix betacovariates=`betacov' + return matrix Vbetacovariates=`Vbetacov' + return matrix zcovariates=`zcovariates' + return matrix pcovariates=`pcovariates' +} +if "`pause'"!="" { + pause off +} + +drop _all + +restore,not +use "`saveraschtest'" + +/*********************************************************************************************************** +CREATE EVENTUAL NEW VARIABLES +************************************************************************************************************/ + +*set trace on +if "`genres'"!="" { + qui sort `id' + qui merge `id' using `ltsave' + qui rename `u'm1 `genlt' + qui rename `u's1 se`genlt' + qui drop _merge se`genlt' + forvalues i=1/`nbitems' { + gen `genres'`i'=exp(``i''*(`genlt'-`beta`i''))/(1+exp(`genlt'-`beta`i''))/sqrt(exp(`genlt'-`beta`i'')/(1+exp(`genlt'-`beta`i''))^2) + } + corr `genres'* + pca `genres'* + drop `u'm1 +} +if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" { + tempname genlt2 genscore2 outfit2 infit2 + qui gen `score'=0 `if' + forvalues i=1/`nbitems' { + qui replace `score'=`score'+``i'' `if' + } + if "`genscore'"!="" { + qui gen `genscore'=`score' `if' + } + if "`genlt'"!="" { + if "`replacegenlt'"=="replace" { + capture drop `genlt' + capture drop se`genlt' + } + if "`method'"=="mml" { + qui sort `id' + qui merge `id' using `ltsave' + qui rename `u'm1 `genlt' + qui rename `u's1 se`genlt' + qui drop _merge + } + else if "`method'"!="mml" { + qui gen `genlt2'=. `if' + forvalues i=0/`nbitems' { + qui replace `genlt2'=`theta`i'' `if'&`score'==`i' + } + qui gen `genlt'=`genlt2' `if' + } + } + if "`genfit'"!="" { + local outfit:word 1 of `genfit' + local infit:word 2 of `genfit' + qui gen `outfit'=0 `if' + qui gen `infit'=0 `if' + tempname infit1 infit2 + qui gen `infit1'=0 `if' + qui gen `infit2'=0 `if' + forvalues j=1/`nbitems' { + tempname pi`j' + qui gen `pi`j''=exp(`genlt2'-`beta`j'')/(1+exp(`genlt2'-`beta`j'')) `if' + qui replace `pi`j''=0 `if' + forvalues s=1/`nbitems' { + qui replace `pi`j''=`Pi'[`j',`s'] `if'&`score'==`s' + } + qui gen `outfit'``j''=(``j''-`pi`j'')^2/(`pi`j''*(1-`pi`j'')) `if' + qui replace `infit1'=`infit1'+(``j''-`pi`j'')^2 `if' + qui replace `infit2'=`infit2'+(`pi`j''*(1-`pi`j'')) `if' + qui replace `outfit'=`outfit'+`outfit'``j''/`nbitems' `if' + } + qui replace `infit'=`infit1'/`infit2' `if' + } +} +if "`docx'"!="" { +*set trace on + putdocx save "`dirsave'\\`docx'.docx", replace + putdocx clear +} +if "`trace'"!=""|"`time'"!="" { + capture qui elapse `st' + di in green "** Time : " in yellow "$S_elap " in green "seconds" +} + +end diff --git a/Modules/ado/personal/r/raschtestv7.hlp b/Modules/ado/personal/r/raschtestv7.hlp new file mode 100644 index 0000000..812a57f --- /dev/null +++ b/Modules/ado/personal/r/raschtestv7.hlp @@ -0,0 +1,222 @@ +{smcl} +{* 5june2019}{...} +{hline} +help for {hi:raschtest} and {hi:raschtestv7}{right:Jean-Benoit Hardouin} +{hline} + +{title:Estimation of the parameters of a Rasch model, tests and specific graphs} + +{p 8 14 2}{cmd:raschtestv7} {it:varlist} [{cmd:if} {it:exp}] [{cmd:in} {it:range}] +, {cmdab:id}({it:varname}) [{cmdab:meth:od}({it:keyword}) {cmdab:nold} {cmdab:iterate}({it:#}) +{cmdab:t:est}({it:keyword}) {cmdab:diff:iculties}({it:vector}) +{cmdab:mean:diff} {cmdab:d:etails} {cmd:group}({it:numlist}) {cmdab:autog:roup} +{cmdab:cov:ariates}({it:varlist}[,{cmd: ss1 ss3}]) +{cmdab:dir:save}({it:directory}) {cmdab:files:save} {cmd:png} {cmdab:pause} +{cmdab:rep:lace} {cmdab:nodraw} {cmdab:icc} +{cmdab:inf:ormation} {cmdab:split:test} {cmdab:fit:graph} +{cmdab:genlt}({it:newvarname}[,{cmdab:rep:lace}]) {cmdab:gensco:re}({it:newvarname}) +{cmd:genfit}({it:newvarlist}) {cmd:genres}({it:string}) +{cmdab:com:p}({it:varname}) +{cmdab:dif}({it:varlist}) +{cmdab:tr:ace} {cmdab:time}] + +{p 8 14 2}{cmd:raschtest} {it:varlist} [{cmd:if} {it:exp}] [{cmd:in} {it:range}] +[, {it:options_of_raschtestv7} {cmdab:gra:ph}] + +{p 8 14 2}{it:varlist} is a list of two existing binary variables or more. + +{title:Description} + +{p 4 8 2}{cmd:raschtest} estimates the parameters of a Rasch model. The estimation +method can be chosen between conditional maximum likelihood (CML), marginal +maximum likelihood (MML) and generalized estimating equations (GEE). {cmd:raschtest} +offer a set of tests, to valuate the fit of the data to the Rasch model, or detect +non homogeneous items (Andersen Z test, First order test (Q1, R1c, R1m, or Wright +Panchapakesan), U test, Split test) and indexes (OUTFIT and INFIT per items or per +individuals). Several graphical representations can be easily obtained: comparison +of the observed and theorical Item Characteristic Curves (ICC), Map difficulty +parameters/Scores, results of the split tests, and information function (for the scale and by item). + +{title:Options} + +{p 4 8 2}{cmd:method} specifies the used method to estimate the difficulty +parameter among CML ({cmd:method}({it:cml}) - by default), MML ({cmd:method}({it:mml})) +or GEE ({cmd:method}({it:gee})). + +{p 4 8 2}{cmd:nold} avoids the Listwise Deletion of the individuals with missing data. +By default, all the individuals with one or more missing data are omited. + +{p 4 8 2}{cmd:iterate} allows defining the maximal number of iterations of the maximisation algorithm. +By default, this number is fixed to 200. + +{p 4 8 2}{cmd:test} specifies the tests to use among {cmd:test}({it:R}) (by +default, for the R1c or the R1m test), {cmd:test}({it:WP}) (for the Wright- +Panchapakesan test) and {cmd:test}({it:Q}) (for the Q1 test). + +{p 4 8 2}{cmd:difficulties} allows fixing the values of the difficulties parameters of the items. +The vector must be a row vector and must contain as many values as items. +This option is available only with {cmd:method}({it:mml}). + +{p 4 8 2}{cmd:meandiff} centers the difficulty parameters (only with +{cmd:method}({it:cml})): by default for the CML estimations, the difficulty +parameter to the last item is fixed to 0. With {cmd:meandiff}, only the +diagonal elements of the covariance matrix of these parameters are estimated. + +{p 4 8 2}{cmd:details} displays for each group of scores a table containing the +observed and expected number of positive responses and the contribution of this +group to the global first-order statistic. + +{p 4 8 2}{cmd:group} specifies groups of scores, by defining the superior +limits of each group (note that the score "0" and this one corresponding to the +number of items are always isolated). + +{p 4 8 2}{cmd:autogroup} automatically creates groups of scores (with at least +30 individuals per group). + +{p 4 8 2}{cmd:covariates} allows introducing covariates on the model. The {cmd:ss1} and +{cmd:ss3} options allows computing the type 1 and type 3 sums of squares to explain the +variance of the latent trait by these covariates. This option is available only with {cmd:method}({it:mml}). + +{p 4 8 2}{cmd:dirsave} specifies the directory where the graphs will be saved +(by default, the directory defined in c(pwd)). + +{p 4 8 2}{cmd:filessave} saves all the graphs in .gph files (by default, the +graphs are not saved). + +{p 4 8 2}{cmd:png} saves all the graphs in .png files. + +{p 4 8 2}{cmd:pause} allows to made a pause between the displaying of each graph. + +{p 4 8 2}{cmd:replace} specifies that the existing graphical files will be +replaced. + +{p 4 8 2}{cmd:nodraw} avoids displaying of the graphs. + +{p 4 8 2}{cmd:icc} displays, for each item, the observed and expected (under the Rasch +model) ICC in a graph. + +{p 4 8 2}{cmd:graph} represents in the same graph the distributions of the +difficulty parameters, this one of the scores, and [with {cmd:method}({it:mml}) or +{cmd:method}({it:gee})] the expected distribution of the latent trait, in +function of the latent trait. + +{p 4 8 2}{cmd:information} represents the information function for the set of +the items in function of the latent trait. + +{p 4 8 2}{cmd:splittest} represents, for each item, the CML estimations of the +difficulty parameters for the others items in the two sub-samples defined by +the individuals who have positively respond to the splitting item for the first +group, and by the individuals who have negatively respond to the splitting item +for the second one. + +{p 4 8 2}{cmd:fitgraph} represents four graphs. The first one concerns the +OUTFIT indexes for each item, the second one, the INFIT indexes for each item, +the third one the OUTFIT indexes for each individual, and the last one the +INFIT indexes for each individual. + +{p 4 8 2}{cmd:genlt} creates a new variable containing, for each individual, +the estimated value of the latent trait. The {cmd:replace} option allows replacing +an existing variable. + +{p 4 8 2}{cmd:genscore} creates a new variable containing, for each individual, +the value of the score. + +{p 4 8 2}{cmd:genres} creates new variables containing, for each individual, +the value of the residuals. This option defines the prefix to these new variables +which will be followed by the name of each item. + +{p 4 8 2}{cmd:genfit} creates several new variables. {it:newvarlist} +contains two words. The first one represents "outfit" and the second one "infit". +This option generates two variables with this names for the OUTFIT and INFIT +indexes for each individual, and the variables "outfitXX" (by replacing "outfit" +by the first word) for the contribution of the item XX to the OUTFIT index (Note +that the new variables contain unstandardized OUTFIT and INFIT indices, even +the program displays standardized statistics in the results table and with the +{cmd:fitgraph} option). + +{p 4 8 2}{cmd:comp} tests the equality of the means of the latent trait for two +groups of individuals defined by a binary variable (only with {cmd:method}({it:mml}) +or {cmd:method}({it:gee})). + +{p 4 8 2}{cmd:dif} tests the Differential Item Functioning (DIF) on a list of +variables by likelihood ration tests. For each variable defined in the list, +the items parameters are estimated in each groups defined by this variable, +and the test considers the null assumption: the estimations are the same in each group. +The statistic of the test follows a chi-square distribution under the null assumption. +The variable defined in the {cmd:dif} option must have 10 or less modalities, coded +from 0 or 1 to an integer k<=10. This option is available only with {cmd:method}({it:cml}). + +{p 4 8 2}{cmd:trace} displays more outputs during the running of the module. + +{p 4 8 2}{cmd:time} displays the number of seconds to run the module. + +{title:Outputs} + +{p 4 8 2}{cmd:e(N)}: Number of observations + +{p 4 8 2}{cmd:e(ll)}: (Marginal) Log-likelihood + +{p 4 8 2}{cmd:e(cll)}: Conditional log-likelihood + +{p 4 8 2}{cmd:e(AIC)}: Akaike Information Criterion + +{p 4 8 2}{cmd:e(PSI)} and {cmd:e(PSIadj)}: Personal Separation Indexes (only for {cmd:meth}({it:mml}) + +{p 4 8 2}{cmd:e(sigma)}: Estimated standard deviation of the latent trait + +{p 4 8 2}{cmd:e(sesigma)}: Standard error of the estimated standard deviation of the latent trait + +{p 4 8 2}{cmd:e(beta)}: Estimated difficulty parameters + +{p 4 8 2}{cmd:e(Varbeta)}: Covariance matrix of the estimated difficulty parameters + +{p 4 8 2}{cmd:e(theta)}: Estimated values for the latent trait for each value of the score + +{p 4 8 2}{cmd:e(Varbeta)}: Covariance matrix for the estimated values for the latent trait for each value of the score + +{p 4 8 2}{cmd:e(itemFit)}: Statistics of fit for each item (first order statistic, degree of freedom, p-value, OUTFIT index, INFIT index, and (if {cmd:method}({it:cml})) U-test statistic + +{p 4 8 2}{cmd:e(globalFit)}: Global first order test (statistic, degrees of freedom, p-value) + +{p 4 8 2}{cmd:e(AndersenZ)}: Andersen LR Z test (first order statistic, degree of freedom, p-value) (if {cmd:method}({it:cml})) + +{p 4 8 2}{cmd:e(DIF)}: DIF LR Z test (statistic, degree of freedom, p-value for each variable defined in {cmd:dif}) (if {cmd:method}({it:cml})) + +{p 4 8 2}{cmd:e(Zcomp)} and {cmd:e(pZcomp)}: Statistics of test and associated p-value for the test of comparison of the two population defined with the {cmd:comp} option. + +{p 4 8 2}{cmd:e(betacovariates)}, {cmd:e(Vbetacovariates)}, {cmd:e(zcovariates)} and {cmd:e(pcovariates)}: respectivelly the estimated values of the parameters associated to the covariates, the covariance matrix of the estimations, the statistics of the tests to compare the parameters to 0 and the associated p-values (only with the {cmd:covariates} option) + +{title:Examples} + +{p 4 8 2}{cmd: . raschtest item1-item9, id(id)} /*estimates the parameters by CML approach*/ + +{p 4 8 2}{cmd: . raschtest item*, id(id) method(gee) information icc dirsave(c:\graphs) filesnames(graphs)} +/*estimates the parameters by GEE, draw the information graph and the ICCs and +save the graphical representations under gph files*/ + +{p 4 8 2}{cmd: . raschtest item1 item4 item7 item 18 item23 item35-item39 , id(id) group(2 3 4 5) test(WP) split graph} +/*creates groups of score (1 and 2, 3, 4, 5 and more) to compute the Wright +Panchapakesan tests, computes the split test, and represent the map difficulty +parameters/scores*/ + +{p 4 8 2}{cmd: . matrix diff=(-1,-.5,0,.5,1)}{p_end} +{p 4 8 2}{cmd: . raschtest item1-item5 , id(id) diff(diff) covariable(group sex age,ss1 ss3) nold} +/*difficulties parameters are fixed, 3 covariables are introduced, no listwise deletion*/ + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD-HDR, associate professor{p_end} +{p 4 8 2}INSERM UMR 1246-SPHERE "Methods in Patients Centered Outcomes and Health Research"{p_end} +{p 4 8 2}Nantes University - Faculty of Pharmaceutical Sciences{p_end} +{p 4 8 2}Intitute of Research in Health 2{p_end} +{p 4 8 2}22 boulevard BĂ©noni-Goullin{p_end} +{p 4 8 2}44200 Nantes - FRANCE{p_end} +{p 4 8 2}Email: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol} + + +{title:Also see} + +{p 4 13 2}Online: help for {help xtlogit}, {help clogit} and {help geekel2d} and {help gllamm} if installed.{p_end} + diff --git a/Modules/ado/personal/r/raschtestv787.ado b/Modules/ado/personal/r/raschtestv787.ado new file mode 100644 index 0000000..db9efba --- /dev/null +++ b/Modules/ado/personal/r/raschtestv787.ado @@ -0,0 +1,2422 @@ +*! version 8.7 28 May 2013 +*! Jean-Benoit Hardouin +************************************************************************************************************* +* Raschtestv7: Rasch model, fit tests and graphical representations +* Corresponds to the version 8 of Raschtest (http://freeirt.org) for Stata7 +* +* Historic: +* Version 2.1 (2003-07-10): Jean-Benoit Hardouin +* Version 3.1 (2004-01-02) : Jean-Benoit Hardouin +* Version 7.1 (2005-03-30) : Jean-Benoit Hardouin +* Version 7.2.1 (2005-05-21) : Jean-Benoit Hardouin +* Version 7.3.1 (2005-07-02) : Jean-Benoit Hardouin +* Version 7.3.2 (2005-10-05) : Jean-Benoit Hardouin /*correction for the *genlt* option with *method(cml)**/ +* Version 7.3.3 (2005-12-21) : Jean-Benoit Hardouin /*correction if scores are not represented with method(mml) or method(gee)*/ +* Version 7.4.1 (2006-01-17) : Jean-Benoit Hardouin /*Standardized OUTFIT and INFIT, DIF option*/ +* Version 7.4.2 (2006-03-21) : Jean-Benoit Hardouin /*Avoids a bug when the temporary files are saved in a directory containing special characters*/ +* Version 7.4.3 (2006-11-15) : Jean-Benoit Hardouin /*Avoids a bug when the directory defined in the dirsave option contains special characters*/ +* Version 7.5.1 (2007-04-20) : Jean-Benoit Hardouin /*Return results of the comp option*/ +* Version 7.6.1 (2008-06-26) : Jean-Benoit Hardouin /*Nold option, corrects a bug with the genlt option*/ +* Version 7.6.2 (2009-03-01) : Jean-Benoit Hardouin /*Correction of the SE of the latent trait, graph option, correction of a bug with the if option, PSI in MML*/ +* Version 8.1 (2009-06-24) : Jean-Benoit Hardouin /*DIFFICULTIES option, COVARIATES option*/ +* Version 8.2 (2009-07-15) : Jean-Benoit Hardouin /*Correction of a bug with CML*/ +* Version 8.3 (2009-12-19) : Jean-Benoit Hardouin /*correction of a bug with DIFFICULTIES and COVARIATES options together*/ +* Version 8.4 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option */ +* Version 8.5 (2011-12-20) : Jean-Benoit Hardouin /*Correction for the ss1 and ss3 suboptions of the COVARIATES option */ +* Version 8.6 (2012-11-20) : Jean-Benoit Hardouin /*HTML option*/ +* Version 8.7 (2013-05-28) : Jean-Benoit Hardouin /*Correction of a bug in the covariates option with ss1 and ss3*/ +* +* Needed modules : +* gammasym version 2.2 (http://www.freeirt.org) +* gausshermite version 1 (http://www.freeirt.org) +* geekel2d version 4.3 (http://www.freeirt.org) +* genscore version 1.4 (http://www.freeirt.org) +* ghquadm (findit ghquadm) +* gllamm version 2.3.20 (ssc describe gllamm) +* gllapred version 2.3.8 (ssc describe gllapred) +* elapse (ssc describe elapse) +* +* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France +* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences" +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2003-2013 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*********************************************************************************************************** +DEFINITION / SYNTAX +***********************************************************************************************************/ + + +program define raschtestv7,rclass +syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GENRES(string) GRAph v8 COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string)] + +local covariables `covariates' + +if "`if'"=="" { + local if "if 1" +} + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + +if "`trace'"!="" { + di in green "*** Tests of conformity" +} +if "`v8'"=="" { + version 7.0 +} +else { + version 8.0 +} +if "`html'"!="" { + set scheme sj + local htmlregion "graphregion(fcolor(white) ifcolor(white))" + local draw +} + +local st = "$S_TIME" +local nbitems : word count `varlist' +marksample touse ,novarlist +if "`covariables'"!="" { + tokenize "`covariables'",parse(" ,") + local i=1 + local tcovariables + while "``i''"!=","&"``i''"!="" { + local covariable`i' ``i'' + local tcovariables `tcovariables' ``i'' + local ++i + } + local nbcovariables=`i'-1 + local ss1 + local ss3 + if "``i''"=="," { + forvalues j=`=`i'+1'/`=`i'+2' { + if "``j''"=="ss1" { + local ss1 ss1 + } + else if "``j''"=="ss3" { + local ss3 ss3 + } + else if "``j''"=="" { +* di in green "option `j' vide" + } + else { + di in red "Invalid option in the {hi:covariables} option" + error 198 + } + } + local i=`i'+3 + if "``i''"!="" { + di in red "There is too much options in the {hi:covariates} option." + error 198 + } + } + local covariables `tcovariables' +} +else { + local nbcovariables=0 +} + +isid `id' +tokenize `varlist' + +local bad +forvalues i=1/`nbitems' { + qui count if ``i''!=0&``i''!=1&``i''!=. + local N=r(N) + if `N'>0 { + local bad `bad' ``i'' + } +} +if "`bad'"!="" { + di in red "The item(s) {hi:`bad'} is(are) not binary item(s) (with responses 0 or 1)." + exit +} + + + +if "`method'"=="" { + local method cml +} +if "`test'"=="" { + local test R +} +local method=lower("`method'") +local test=upper("`test'") +if "`method'"!="mml"&"`method'"!="cml"&"`method'"!="gee" { + di in red "Uncorrect method option." + error 198 + exit +} + +if "`test'"!="R"&"`test'"!="Q"&"`test'"!="WP"&"`test'"!="NONE" { + di in red "Uncorrect test option." + error 198 + exit +} + +if "`genfit'"!="" { + local nbwordgenfit:word count `genfit' + if `nbwordgenfit'!=2 { + di in red "Uncorrect genfit option." + di in red "This option must contain exactly two words" + error 198 + exit + } +} + + +if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!=""|"`genres'"!="" { + capture confirm new variable `genfit' `genscore' `genres' + if "`genfit'"!="" { + local o:word 1 of `genfit' + forvalues i=1/`nbitems' { + confirm new variable `o'``i'' + } + } + if "`genlt'"!="" { + local 0 `genlt' + gettoken left 0: 0,parse(",") + gettoken right 0: 0,parse(",") + local genlt `left' + local replacegenlt `0' + local length=length("`replacegenlt'") + if `length'>=3&substr("`replacegenlt'",1,`length')==substr("replace",1,`length') { + local replacegenlt replace + } + if "`replacegenlt'"!="replace"&"`replacegenlt'"!="" { + di "Not allowed option in the {hi:genlt} option" + error 198 + } + else if "`replacegenlt'"=="" { + confirm new variable `genlt' + } + } +} + +preserve + +tempfile saveraschtest +qui save `saveraschtest' +qui keep if `touse'==1 + +if "`autogroup'"!=""&"`group'"!="" { + di in green "The autogroup and the group options cannot be defined in the same time" + di in green "Only the group option is retained." + local autogroup +} + +if "`autogroup'"!="" { + tempvar autoscore + qui genscore `varlist',score(`autoscore') + + tempname matscore tmp + matrix `matscore'=J(`=`nbitems'-1',3,0) + forvalues i=1/`=`nbitems'-1' { + matrix `matscore'[`i',1]=`i' + matrix `matscore'[`i',2]=`i' + qui count if `autoscore'==`i' + matrix `matscore'[`i',3]=r(N) + } + local stop=0 + local j=0 + while `j'<=`=`nbitems'-3'&`stop'!=1 { + local j=`j'+1 + local scoretogroup=99999999 + local rowtogroup1=0 + local rowtogroup2=0 + local stop=1 + forvalues i=1/`=`nbitems'-`j'' { + if `matscore'[`i',1]>=0 & `matscore'[`i',3]<30 & `matscore'[`i',3]<`scoretogroup' { + local scoretogroup=`matscore'[`i',3] + local rowtogroup1=`i' + local stop=0 + } + } + if `stop'!=1 { + if `rowtogroup1'>1&`rowtogroup1'<`=`nbitems'-`j'' { + if `matscore'[`=`rowtogroup1'-1',1]<`matscore'[`=`rowtogroup1'+1',1] { + local rowtogroup2=`rowtogroup1' + local rowtogroup1=`rowtogroup1'-1 + } + else { + local rowtogroup2=`rowtogroup1'+1 + } + } + else if `rowtogroup1'==1 { + local rowtogroup2=2 + } + else if `rowtogroup1'==`=`nbitems'-`j'' { + local rowtogroup2=`nbitems'-`j' + local rowtogroup1=`nbitems'-`j'-1 + } + matrix `tmp'=`matscore' + matrix `matscore'=J(`=`nbitems'-`j'',3,0) + if `rowtogroup1'!=1 { + matrix `matscore'[1,1]=`tmp'[1..`=`rowtogroup1'-1',1..3] + } + matrix `matscore'[`rowtogroup1',1]=`tmp'[`rowtogroup1',1] + matrix `matscore'[`rowtogroup1',2]=`tmp'[`rowtogroup2',2] + matrix `matscore'[`rowtogroup1',3]=`tmp'[`rowtogroup1',3]+`tmp'[`rowtogroup2',3] + if `rowtogroup2'!=`=`nbitems'-`j'' { + matrix `matscore'[`rowtogroup2',1]=`tmp'[`=`rowtogroup2'+1'..`=`nbitems'-`j'',1..3] + } + } + } + local nbrows=rowsof(`matscore')-1 + local thresholds + forvalues i=1/`nbrows' { + local tmp=`matscore'[`i',2] + local thresholds `thresholds' `tmp' + } + local group `thresholds' +} + + +if "`group'"=="" { + forvalues i=1/`=`nbitems'-1' { + local group "`group' `i'" + } +} +local nbgroups:word count `group' +local groupmax:word `nbgroups' of `group' +if `groupmax'>=`nbitems' { + di in red "You cannot form a group with the higher possible score." + di in red "The higher possible value of the group option is `=`nbitems'-1'." + di in red "Please correct your group option." + error 198 + exit +} +else { + if `groupmax'!=`=`nbitems'-1' { + local group "`group' `=`nbitems'-1'" + local nbgroups=`nbgroups'+1 + } +} +local nbgroups=`nbgroups'+1 + +if "`dirsave'"!=""&"`filessave'"=="" { + di in ye "If you want to save yours graphs, use the filessave option" +} +if "`filessave'"!="" { + if "`dirsave'"=="" { + local dirsave "`c(pwd)'" + } + di in ye "The graphs files will be saved in `dirsave'" +} +if "`dirsave'"!="" { + if "`filesave'"=="" { + local filesave "filesave" + } +} + + +if "`pause'"!=""&"`draw'"=="" { + pause on +} + +if "`difficulties'"!="" { + capture confirm matrix `difficulties' + if _rc!=0 { + di in red "The vector `difficulties' defined in the {hi:difficulties} option does not exist." + error 198 + exit + } +} + +if "`difficulties'"!=""&"`method'"!="mml" { + di in red "The {hi:difficulties} option can be defined only for MML method." + error 198 + exit +} + +if "`covariables'"!=""&"`method'"!="mml" { + di in red "The {hi:covariables} option can be defined only for MML method." + error 198 + exit +} +if "`covariables'"!=""&"`comp'"!="" { + di in red "The {hi:covariables} and {hi:comp} options can be defined jointly." + error 198 + exit +} + + + + + +/*********************************************************************************************************** +POSSIBLE TEST +***********************************************************************************************************/ + +if ("`icc'"!=""|"`fitgraph'"!=""|"`splittest'"!=""|"`details'"!="")&"`test'"=="NONE" { + di in green "You cannot use the {hi:details}, {hi:icc}, {hi:fitgraph} or {hi:splittest} options if you use {hi:test(none)}." + di in green "These options are ignored." + local details + local icc + local fitgraph + local splittest +} +if "`comp'"!=""&"`method'"=="cml" { + di in green "You cannot compare two populations ({hi:comp} option) with the CML estimation method" + di in green "This option is ignored." + local comp +} +if "`method'"!="cml"&"`test'"=="WP" { + di in green "The Wright-Panchapakesan test is not authorized with MML or GEE." + di in green "The WP tests are replaced by Van den Wollenberg Q tests." + local test Q +} +if "`method'"=="gee"&"`ld'"!="" { + di in green "You cannot use the {hi:nold} option with the GEE method of estimation" + di in green "This option is ignored." + local ld +} + + +if "`test'"==""|"`test'"=="R" { + local test "R" + if "`method'"=="cml" { + local namewp "R1c" + local descwp "R1c test" + } + else { + local namewp="R1m" + local descwp "R1m test" + } +} +if `nbitems'>999999|"`test'"=="WP" { + local namewp " Y" + local descwp "Wright-Panchapakesan Y test" + local q2 +} + else if "`test'"=="Q" { + local namewp " Q1" + local descwp "Van den Wollenberg Q1 test" +} + +if "`method'"!="cml"&"`meandiff'"!="" { + di in green "The {hi:meandiff} option is not available with MML or GEE." + di in green "This option is ignored." + local meandiff +} + +if "`method'"!="cml"&"`splittests'"!="" { + di in green "The {hi:splittests} option is not available with MML or GEE." + di in green "This option is ignored." + local splittests +} +if "`method'"!="cml"&"`dif'"!="" { + di in green "The {hi:dif} option is not available with MML or GEE." + di in green "This option is ignored." + local dif +} + +/*********************************************************************************************************** +SCORES AND GROUPS +************************************************************************************************************/ + +qui count if `touse'==1 +local N=r(N) + +qui keep `varlist' `comp' `covariables' `id' `touse' + +tempname rep item +tempvar score realscore +qui genscore `varlist',score(`score') +qui count if `score'==.&`touse'==1 +local nbindmiss=r(N) + +if "`ld'"=="" { + qui drop if `score'==. +} +forvalues i=1/`nbitems' { + rename ``i'' `rep'`i' +} + + + +local liminf0=0 +local limsup0=0 +local liminf`nbgroups'=`nbitems' +local limsup`nbgroups'=`nbitems' + + +local recode +forvalues i=1/`=`nbgroups'-1' { + if `i'!= 1{ + local liminf`i' : word `=`i'-1' of `group' + } + else { + local liminf1=0 + } + local liminf`i'=`liminf`i''+1 + local limsup`i':word `i' of `group' + + local recode "`recode' `liminf`i''/`limsup`i''=`i'" +} +qui gen `realscore'=`score' +qui recode `score' `recode' `nbitems'=`nbgroups' + +local smallgroup=0 + +forvalues i=0/`nbgroups' { + qui count if `score'==`i' + local effscore`i'=r(N) + if `i'!=0&`i'!=`nbgroups'&`effscore`i''<30 { + local smallgroup=1 + } +} +/*********************************************************************************************************** +ESTIMATION OF THE DIFFICULTY PARAMETERS +************************************************************************************************************/ +if "`trace'"!="" { + di in green "*** Estimation of the difficulty parameters" +} + + +if "`covariables'"!=""&"`difficulties'"=="" { + forvalues i=1/`nbcovariables' { + qui su `covariable`i'' + local mean`covariable`i''=r(mean) + qui replace `covariable`i''=`covariable`i''-`mean`covariable`i''' + } +} + +tempname ll coef var beta Vbeta est + +if "`method'"=="gee" { + qui geekel2d `rep'1-`rep'`nbitems',ll + local nbobserv=r(N) + + if `r(error)'==1 { + di "The variance of the latent trait probably is too high to made the GEE a efficient method to estimate the parameters." + error 499 + exit + } + scalar `ll'=r(ll) + local nbind=r(N) + matrix `coef'=r(b) + matrix `est'=`coef' + matrix `est'[1,`=`nbitems'+1']=sqrt(`est'[1,`=`nbitems'+1']) + matrix `var'=r(V) + matrix `beta'=`coef'[1,1..`nbitems'] + matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems'] + local sig=sqrt(`coef'[1,`=`nbitems'+1']) + local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])/sqrt(`nbind')/(`sig'*2) +} + +qui reshape long `rep', i(`id') j(`item') + +tempvar diff tl +gen `diff'=0 + +forvalues i=1/`nbitems' { + qui gen `rep'`i'=`item'==`i' + qui replace `rep'`i'=-`rep'`i' +} + + +if "`method'"=="mml" { + if "`difficulties'"==""{ + qui xtlogit `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') nocons iterate(`iterate') + matrix `est'=e(b) + matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`est'[1,`=`nbitems'+`nbcovariables'+1']/2) + } + else { + tempname offset b + qui gen `offset'=0 + forvalues i=1/`nbitems' { + qui replace `offset'=-(`difficulties'[1,`i']) if `item'==`i' + } + qui gllamm `rep' `covariables' , offset(`offset') i(`id') nocons iterate(`iterate') link(logit) fam(bin) + matrix `b'=e(b) + matrix `est'=`difficulties',`b' + matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`b'[1,`=`nbcovariables'+1']/2) + } +} +else if "`method'"=="cml" { + qui clogit `rep' `rep'1-`rep'`=`nbitems'-1' , group(`id') +} + + +if "`method'"!="gee" { + if "`difficulties'"=="" { + matrix `coef'=e(b) + matrix `var'=e(V) + } + else { + matrix `coef'=`difficulties' + matrix `var'=J(`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1',.) + matrix `var'[`=`nbitems'+1',`=`nbitems'+1']=e(V) + } + scalar `ll'=e(ll) + local nbind=e(N)/`nbitems' + local nbobserv=e(N) + *di "nombre d'obs:`nbobserv'" + + if "`meandiff'"!="" { + matrix `var'=J(`nbitems',`nbitems',.) + matrix `coef'=J(1,`nbitems',.) + local param + local lin `rep'1 + forvalues j=2/`=`nbitems'-1' { + local lin `lin'+`rep'`j' + } + local lin (`lin')/`nbitems' + + forvalues j=1/`=`nbitems'-1' { + qui lincom `rep'`j'-`lin' + matrix `coef'[1,`j']=`r(estimate)' + matrix `var'[`j',`j']=`r(se)'^2 + } + qui lincom -`lin' + matrix `coef'[1,`nbitems']=`r(estimate)' + matrix `var'[`nbitems',`nbitems']=`r(se)'^2 + } + if "`method'"=="mml" { + local sig=e(sigma_u) + local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2 + tempname betacov Vbetacov + if "`difficulties'"=="" { + matrix `beta'=`coef'[1,1..`nbitems'] + matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems'] + if "`covariables'"!="" { + matrix `betacov'=`coef'[1,`=`nbitems'+1'..`=`nbitems'+`nbcovariables''] + matrix `Vbetacov'=`var'[`=`nbitems'+1'..`=`nbitems'+`nbcovariables'',`=`nbitems'+1'..`=`nbitems'+`nbcovariables''] + } + local sig=e(sigma_u) + local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2 + } + else { + tempname tmp + matrix `tmp'=e(b) + matrix `beta'=`difficulties' + if "`covariables'"!="" { + matrix `betacov'=`tmp'[1,1..`nbcovariables'] + } + local sig=`tmp'[1,`=`nbcovariables'+1'] + matrix `tmp'=e(V) + local sesig=sqrt(`tmp'[`=`nbcovariables'+1',`=`nbcovariables'+1']) + matrix `Vbeta'=J(`nbitems',`nbitems',.) + if "`covariables'"!="" { + matrix `Vbetacov'=`tmp'[1..`nbcovariables',1..`nbcovariables'] + } + } + } + else if "`method'"=="cml"&"`meandiff'"==""{ + matrix `beta'=`coef'[1,1..`=`nbitems'-1'] + matrix `Vbeta'=`var'[1..`=`nbitems'-1',1..`=`nbitems'-1'] + } + else if "`method'"=="cml"&"`meandiff'"!=""{ + matrix `beta'=`coef' + matrix `Vbeta'=`var' + } +} + +if ("`method'"=="mml"|"`method'"=="gee") { + local colnames + forvalues i=1/`nbitems' { + local colnames "`colnames' `rep':`rep'`i'" + } + forvalues i=1/`nbcovariables'{ + local tmp:word `i' of `covariables' + local colnames "`colnames' `rep':`tmp'" + } + local id2=substr("`id'",1,4) + local colnames "`colnames' `id2'1:_cons" + matrix colnames `est'=`colnames' + + qui gllamm `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') allc nocons family(binom) link(logit) trace from(`est') eval + tempname u + qui gllapred `u',u fsample + + forvalues i=1/`nbcovariables' { + local tmp:word `i' of `covariables' + qui replace `u'm1=`u'm1+`betacov'[1,`i']*(`tmp')/*+`mean`covariable`i''')*/ + } + tempname theta sdtheta + matrix `theta'=J(1,`=`nbitems'+1',0) + matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',0) + qui su `u'm1 if `rep'1==-1 + local vartheta=r(Var) + qui gen `u's2=`u's1^2 + qui su `u's2 if `rep'1==-1 + local meanse2=r(mean) + local psi=1-`meanse2'/(`meanse2'+`vartheta') + forvalues s=0/`nbitems' { + qui su `u'm1 if `realscore'==`s' + local theta`s'=r(mean) + qui su `u's1 if `realscore'==`s' + local sdtheta`s'=r(mean) + matrix `theta'[1,`=`s'+1']=`theta`s'' + matrix `sdtheta'[`=`s'+1',`=`s'+1']=`sdtheta`s'' + } + if "`genlt'"!="" { + tempfile ltsave ltsavetmp + qui save `ltsavetmp', replace + qui keep if `rep'1==-1 + qui keep `u'm1 `u's1 `id' + qui sort `id' + qui save `ltsave' + qui use `ltsavetmp' + } +} + +forvalues i=1/`nbitems' { + if `i'==`nbitems'&"`method'"=="cml"&"`meandiff'"=="" { + local beta`i'=0 + local sd`i' . + local fixed`i' "*" + } + else { + local beta`i'=`coef'[1,`i'] + local sd`i'=sqrt(`var'[`i',`i']) + } + qui replace `diff'=-`beta`i'' if `item'==`i' +} + +/*********************************************************************************************************** +COMPARISON OF TWO POPULATIONS +***********************************************************************************************************/ + +if "`comp'"!=""&"`method'"!="cml" { + if "`trace'"!="" { + di in green "*** Test of comparison of two populations" + } + qui inspect `comp' + local unique=r(N_unique) + if `unique'== 2 { + qui su `comp' + local mincomp=r(min) + local maxcomp=r(max) + tempname bmin bmax + qui xtlogit `rep' if `comp'==`mincomp',offset(`diff') i(`id') + matrix `bmin'=e(b) + local meanmin=`bmin'[1,1] + local varmin=e(sigma_u)^2 + local llmin=e(ll) + local Nmin=e(N_g) + qui xtlogit `rep' if `comp'==`maxcomp',offset(`diff') i(`id') + matrix `bmax'=e(b) + local meanmax=`bmax'[1,1] + local varmax=e(sigma_u)^2 + local llmax=e(ll) + local Nmax=e(N_g) + local Zcomp=(`meanmin'-`meanmax')/sqrt(`varmin'/`Nmin'+`varmax'/`Nmax') + local pvalue=1-norm(abs(`Zcomp')) + } + else { + di "It is impossible to compare more than two populations" + di "The comparison process is not run" + local comp + } +} + +/*********************************************************************************************************** +ESTIMATION OF THE ABILITY PARAMETERS / CML +************************************************************************************************************/ +if `nbitems'>=2 { + if "`trace'"!="" { + di in green "*** Estimation of the ability parameters" + } + if "`method'"=="cml" { + tempfile verytmp + qui save `verytmp',replace + drop _all + qui set obs 20001 + qui gen theta=(_n-10001)/1000 + qui gen A=1 + forvalues j=1/`nbitems' { + qui gen u`j'=exp(theta-`beta`j'') + qui gen p`j'=u`j'/(1+u`j') + qui gen a`j'=1/u`j' + qui replace A=A*a`j' + qui gen i`j'=u`j'/(1+u`j')^2 + qui gen j`j'=(u`j'*(1-u`j'))/(1+u`j')^3 + } + qui egen P=rsum(p*) + qui egen I=rsum(i*) + qui egen J=rsum(j*) + qui gen V=1/I^2*(I+J^2)/(4*I^2) + qui gen V2=1/I + tempname theta sdtheta + matrix `theta'=J(1,`=`nbitems'+1',0) + matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',.) + forvalues s=0/`nbitems' { + qui gen f`s'=abs(`s'-P+.5*J/I) + qui sort f`s' + matrix `theta'[1,`=`s'+1']=theta[1] + matrix `sdtheta'[`=`s'+1',`=`s'+1']=sqrt(V2[1]) + } + use "`verytmp'",replace + } + qui gen `tl'=0 + forvalues s=0/`nbitems' { + local theta`s'=`theta'[1,`=`s'+1'] + qui replace `tl'=`theta`s'' if `realscore'==`s' + local sdtheta`s'=`sdtheta'[`=`s'+1',`= `s'+1'] + } + tempname pred + qui gen `pred'=log(exp(`rep'*(`tl'+`diff'))/(1+exp(`tl'+`diff'))) + + qui su `pred' + local globalll=r(sum) + + local nulscore=0 + forvalues i=0/`nbgroups' { + qui count if `score'==`i'&`item'==1 + local nbscore`i'=r(N) + if `nbscore`i''==0 { + local nulscore=1 + } + } + if `nulscore' { + di in green "{p}At least one group of scores concerns none individuals. Tests will be not computed.{p_end}" + di in green "{p}Use the {hi:group} or the {hi:autogroup} options.{p_end}" + local test "NONE" + local details + local icc + local fitgraph + local splittest + } + forvalues i=0/`nbitems' { + qui count if `realscore'==`i'&`item'==1 + local nbrealscore`i'=r(N) + } +} + +/*********************************************************************************************************** +TESTS OF THE FIRST ORDER +************************************************************************************************************/ + +tempname Pi +matrix define `Pi'=J(`nbitems',`=`nbitems'-1',0) +if "`test'"!="NONE" { + qui drop if `score'==. + if "`trace'"!="" { + di in green "*** Tests of the first order" + } + tempname Obs Obs2 Th Th2 + + matrix define `Obs'=J(`nbitems',`=`nbitems'-1',0) + matrix define `Obs2'=J(`nbitems',`=`nbgroups'-1',0) + matrix define `Th'=J(`nbitems',`=`nbitems'-1',0) + matrix define `Th2'=J(`nbitems',`=`nbgroups'-1',0) + local listofitemsc + + /* Estimation of the gamma symetrical functions*/ + local c0 "1" + local c`nbitems' "`nbitems'*x" + forvalues j=1/`nbitems' { + local listini`j' + local listofitemsc "`listofitemsc' `beta`j''" + local c0 `c0'*(1+exp(x-`beta`j'')) + local c`nbitems' `c`nbitems''-`beta`j'' + forvalues k=1/`nbitems' { + local listini`j'k`k' + if `k'!=`j' { + local listini`j' "`listini`j'' `beta`k''" + } + forvalues l=1/`nbitems' { + if `l'!=`j'&`l'!=`k' { + local listini`j'k`k' "`listini`j'k`k'' `beta`l''" + } + } + } + } + + gammasym `listofitemsc' + + /*Estimation, for each value of the score s of the probability to respond to each item (Pi) and of the theorical number of positive responses (Ths) and of theorical number of positive respond per item pair (Ws)*/ + forvalues s=1/`nbitems' { + local denom`s'=r(gamma`s') + tempname W`s' + matrix define `W`s''=J(`nbitems',`nbitems',0) + } + tempvar prob prob2 z y v z2 y2 v2 c r q e + qui gen `prob'=. + qui gen `prob2'=. + forvalues j=1/`nbitems' { + forvalues s=1/`=`nbitems'-1' { + qui count if `rep'==1&`item'==`j'&`realscore'==`s' + matrix `Obs'[`j',`s']=r(N) + if "`test'"!="WP" { + gammasym `listini`j'' + local num`j'=r(gamma`=`s'-1') + if "`method'"=="cml"|"`test'"=="Q" { + matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s'' + } + else { + gausshermite exp(`s'*x)/(`c0'), sigma(`sig') + local int`s'=r(int) + if "`test'"=="R"&`nbrealscore`s''!=0{ + local tmp=exp(-`beta`j'')*`num`j''*`int`s''*`nbind'/`nbrealscore`s'' + matrix `Pi'[`j',`s']=`tmp' + } + else if `nbrealscore`s''==0 { + matrix `Pi'[`j',`s']=0 + } + } + if "`test'"=="R" { + forvalues k=`=`j'+1'/`nbitems' { + if `s'>=2 { + gammasym `listini`j'k`k'' + local num`j'k`k'=r(gamma`=`s'-2') + if "`method'"=="cml" { + matrix `W`s''[`j',`k']=`nbrealscore`s''*exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''/`denom`s'' + } + else { + matrix `W`s''[`j',`k']=exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''*`int`s''*`nbind' + } + matrix `W`s''[`k',`j']=`W`s''[`j',`k'] + } + } + } + } + else if "`test'"=="WP" { + matrix `Pi'[`j',`s']=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) + } + matrix `Th'[`j',`s']=`Pi'[`j',`s']*`nbrealscore`s'' + qui replace `prob'=`Pi'[`j',`s'] if `realscore'==`s'&`item'==`j' + qui replace `prob2'=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) if `realscore'==`s'&`item'==`j' + matrix `W`s''[`j',`j']=`nbrealscore`s''*`Pi'[`j',`s'] + if "`test'"!="R" { + matrix `W`s''[`j',`j']=`W`s''[`j',`j']*abs(1-`Pi'[`j',`s']) + } + } + } + qui gen `v2'=abs(`prob'*(1-`prob')) + qui gen `z2'=(`rep'-`prob')^2 + qui gen `y2'=`z2'/`v2' + qui gen `c'=abs(`prob'*(1-`prob')*(`prob'^3+(1-`prob')^3)) + qui gen `r'=`c'/(`v2')^2 + qui gen `e'=`c'-(`v2')^2 + + forvalues j=1/`nbitems' { + qui su `y2' if `item'==`j' + local outfit`j'=r(mean) + qui su `r' if `item'==`j' + local Voutfit`j'=r(sum) + local Voutfit`j'=`Voutfit`j''/(`nbind')^2-1/`nbind' + local outfitstd`j'=(`outfit`j''^(1/3)-1)*(3/sqrt(`Voutfit`j''))-sqrt(`Voutfit`j'')/3 + + qui su `z2' if `item'==`j' + local n=r(sum) + qui su `v2' if `item'==`j' + local d=r(sum) + local infit`j'=`n'/`d' + qui su `e' if `item'==`j' + local sume=r(sum) + local Vinfit`j'=`sume'/(`d')^2 + local infitstd`j'=(`infit`j''^(1/3)-1)*(3/sqrt(`Vinfit`j''))-sqrt(`Vinfit`j'')/3 + } + tempname tmp stattest testitems + + /*Estimation, by scores group g, of the theorical number of positive response (Th2g) and of the positive respond to each items pair (W2g)*/ + scalar `stattest'=0 + forvalues g=1/`=`nbgroups'-1' { + tempname W2`g' d2`g' + matrix define `W2`g''=J(`nbitems',`nbitems',0) + forvalues s=`liminf`g''/`limsup`g'' { + forvalues j=1/`nbitems' { + matrix `Obs2'[`j',`g']=`Obs2'[`j',`g']+`Obs'[`j',`s'] + matrix `Th2'[`j',`g']=`Th2'[`j',`g']+`Th'[`j',`s'] + if "`test'"=="R" { + forvalues k=`=`j'+1'/`nbitems' { + matrix `W2`g''[`j',`k']=`W2`g''[`j',`k']+`W`s''[`j',`k'] + matrix `W2`g''[`k',`j']=`W2`g''[`j',`k'] + } + } + matrix `W2`g''[`j',`j']=`W2`g''[`j',`j']+`W`s''[`j',`j'] + } + } + + /*Estimation of the d2g vectors*/ + matrix `d2`g''=`Obs2'[1..`nbitems',`g']-`Th2'[1..`nbitems',`g'] + + /*Estimation of the influences on the test of each item (testitemsg matrix) and of the test statistic (stattest)*/ + tempname test`g' testitems`g' + matrix `test`g''=`d2`g'''*syminv(`W2`g'')*`d2`g'' + capture matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g'' + if _rc!=0 { + matrix `tmp'=J(`nbitems',`nbitems',0) + forvalues j=1/`nbitems' { + matrix `tmp'[`j',`j']=`W2`g''[`j',`j'] + } + di in green "Group `g' (`liminf`g''/`limsup`g''): The weight matrix is not positive-definite, the diagonal matrix is used to estimate the contribution of the items on the `wpname' statistic" + matrix list `tmp' + matrix `testitems`g''=cholesky(syminv(`tmp'))*`d2`g'' + } + else { + matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g'' + } + scalar `stattest'=`stattest'+`test`g''[1,1] + } + matrix `testitems'=J(`nbitems',1,0) + forvalues j=1/`nbitems' { + forvalues g=1/`=`nbgroups'-1' { + matrix `testitems'[`j',1]=`testitems'[`j',1]+`testitems`g''[`j',1]^2 + } + } + + /*Adaptation for the Q1 statistic*/ + if "`test'"=="Q" { + scalar `stattest'=`stattest'*`=`nbitems'-1'/`nbitems' + } + + /*Correction for R1m and Q1m*/ + if ("`test'"=="R"|"`test'"=="Q")&("`method'"=="mml"|"`method'"=="gee") { + local c`nbitems' exp(`c`nbitems'')/(`c0') + local c0 1/(`c0') + gausshermite `c0', sigma(`sig') + local ci0=r(int)*`nbind' + gausshermite `c`nbitems'',sigma(`sig') + local ci`nbitems'=`nbind'*r(int) + scalar `stattest'=`stattest'+(`nbrealscore0'-`ci0')^2/`ci0'+(`nbrealscore`nbitems''-`ci`nbitems'')^2/`ci`nbitems'' + } + + + +/*********************************************************************************************************** +TESTS U +************************************************************************************************************/ + + if "`method'"=="cml" { + if "`trace'"!="" { + di in green "*** Tests U" + } + + local quartile=`nbind'/4 + local c1=0 + local n1=0 + while `n1'<`quartile' { + local c1=`c1'+1 + local n1=`n1'+`nbrealscore`c1'' + } + local c2=`nbitems' + local n2=0 + while `n2'<`quartile' { + local c2=`c2'-1 + local n2=`n2'+`nbrealscore`c2'' + } + forvalues j=1/`nbitems' { + local zu1=0 + local zu2=0 + forvalues s=1/`c1' { + local zu1=`zu1'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s'])) + } + forvalues s=`c2'/`=`nbitems'-1' { + local zu2=`zu2'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s'])) + } + local U`j'=(`zu1'-`zu2')/sqrt(`c1'+`nbitems'-`c2') + } + } + + + +/*********************************************************************************************************** +TESTS OF THE SECOND ORDER /*undocumented in beta test*/ +************************************************************************************************************/ + + if "`q2'"!="" { + if "`trace'"!="" { + di in green "*** Tests of the second order" + } + + tempfile Q2file + qui save "`Q2file'",replace + qui use "`saveraschtest'",replace + + qui keep if `touse'==1 + gen `score'=0 + + forvalues i=1/`nbitems' { + local Q2i`i' + rename ``i'' `rep'`i' + qui replace `score'=`score'+`rep'`i' + } + qui recode `score' `recode' + + forvalues i=1/`nbitems' { + local Q2i`i'=0 + forvalues j=`=`i'+1'/`nbitems' { + local listinci`i'j`j' + forvalues k=1/`nbitems' { + if `k'!=`i'&`k'!=`j' { + local listinci`i'j`j' "`listinci`i'j`j'' `beta`k''" + } + } + } + } + + local Q2tot=0 + forvalues k=2/`=`nbitems'-1' { + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + if `k'==1 { + local num=0 + } + else { + gammasym `listinci`i'j`j'' + local num=r(gamma`=`k'-2') + } + local athi`i'j`j'k`k'=exp(-`beta`i'')*exp(-`beta`j'')*`num'/`denom`k'' + local bthi`i'j`j'k`k'=`nbth`i's`k''-`athi`i'j`j'k`k'' + local cthi`i'j`j'k`k'=`nbth`j's`k''-`athi`i'j`j'k`k'' + local dthi`i'j`j'k`k'=1-`athi`i'j`j'k`k''-`bthi`i'j`j'k`k''-`cthi`i'j`j'k`k'' + } + } + } + forvalues k=1/`=`nbgroups'-1' { + local Q2`k'=0 + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`j'+1'/`nbitems' { + qui count if `rep'`i'==1&`rep'`j'==1&`score'==`k' + local aempi`i'j`j'k`k'=r(N) + local ath2i`i'j`j'k`k'=0 + local bth2i`i'j`j'k`k'=0 + local cth2i`i'j`j'k`k'=0 + local dth2i`i'j`j'k`k'=0 + } + } + if `limsup`k''!=1 { + forvalues l=`liminf`k''/`limsup`k'' { + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + if `l'!=1 { + local ath2i`i'j`j'k`k'=`ath2i`i'j`j'k`k''+`athi`i'j`j'k`l''*`nbrealscore`l'' + local bth2i`i'j`j'k`k'=`bth2i`i'j`j'k`k''+`bthi`i'j`j'k`l''*`nbrealscore`l'' + local cth2i`i'j`j'k`k'=`cth2i`i'j`j'k`k''+`cthi`i'j`j'k`l''*`nbrealscore`l'' + local dth2i`i'j`j'k`k'=`dth2i`i'j`j'k`k''+`dthi`i'j`j'k`l''*`nbrealscore`l'' + } + } + } + } + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + local d2i`i'j`j'k`k'=(`aempi`i'j`j'k`k''-`ath2i`i'j`j'k`k'')^2 + local Q2i`i'j`j'k`k'=`d2i`i'j`j'k`k''/`ath2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`bth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`cth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`dth2i`i'j`j'k`k'' + local Q2i`i'=`Q2i`i''+`Q2i`i'j`j'k`k'' + local Q2i`j'=`Q2i`j''+`Q2i`i'j`j'k`k'' + local Q2`k'=`Q2`k''+`Q2i`i'j`j'k`k'' + } + } + } + local Q2tot=`Q2tot'+`Q2`k'' + } + forvalues i=1/`nbitems' { + di in green "Item ``i'' : Q2 = `Q2i`i''" + } + local Q2=`Q2tot'*(`nbitems'-3)/(`nbitems'-1) + di in green "Q2 = `Q2tot'" + qui use "`Q2file'",replace + } + +/*********************************************************************************************************** +TEST LR Z +************************************************************************************************************/ + + if "`method'"=="cml" { + if "`trace'"!="" { + di in green "*** Tests LR of Andersen" + } + local ssll=0 + tempfile Zfile + qui save "`Zfile'", replace + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + gen `score'=0 + forvalues j=1/`nbitems' { + qui replace `score'=`score'+``j'' + } + qui recode `score' `recode' `nbitems'=`nbgroups' + forvalues i=1/`=`nbgroups'-1' { + if `effscore`i''>0 { + qui raschtestv7 `varlist' if `score'==`i', test(NONE) `ld' id(`id') + local ll`i'=r(cll) + local ssll=`ssll'+(`ll`i'') + } + } + local Z=2*`ssll'-2*`ll' + use "`Zfile'",replace + tempname AndersenZ + matrix define `AndersenZ'=(`Z',`=(`nbgroups'-2)*(`nbitems'-1)',1-chi2(`=(`nbitems'-1)*(`nbgroups'-2)',`Z')) + } +} + + +/*********************************************************************************************************** +DISPLAYING RESULTS WITH TESTS +************************************************************************************************************/ +if "`html'" != "" { + di "" +} + +if "`test'"!="NONE" { + local conttest= "_c" +} +di +tempname itemfit globalfit +matrix `globalfit'=J(1,3,0) +if "`method'"=="cml" { + if "`html'" == "" { + di in green "Estimation method: " in yellow "Conditional maximum likelihood (CML)" + } + else { + di "

Estimation method: Conditional maximum likelihood (CML)

" + } + local nbtest=`nbgroups'-1 + local line=77 +} +else if "`method'"=="mml"{ + if "`html'" == "" { + di in green "Estimation method: " in yellow "Marginal maximum likelihood (MML)" + } + else { + di "

Estimation method: Marginal maximum likelihood (MML)

" + } + local nbtest=`nbgroups'+1 + local line=70 +} +else if "`method'"=="gee" { + di in green "Estimation method: " in yellow "Generalized Estimating Equations (GEE)" + local nbtest=`nbgroups'+1 + local line=70 +} +if "`test'"=="NONE" { + local line=35 +} + +if "`html'" == "" { + di in green "Number of items: " in yellow `nbitems' + di in green "Number of groups: " in yellow `=`nbgroups'+1' `conttest' + if "`test'"!="NONE" { + di in green " (" in yellow "`nbtest'" in green " of them are used to compute the statistics of test)" + } +} +else { + di "Number of items: " `nbitems' "
" + di "Number of groups: " `=`nbgroups'+1' `conttest' + if "`test'"!="NONE" { + di " (`nbtest' of them are used to compute the statistics of test)" + } + di "
" +} +if "`method'"=="cml" { + local nbind=`nbind'+`effscore0'+`effscore`nbgroups'' + local cont "_c" + matrix `itemfit'=J(`nbitems',6,0) +} +else { + local cont + matrix `itemfit'=J(`nbitems',5,0) +} +local missing=`N'-`nbind' +if "`html'" == "" { + di in green "Number of individuals: " in yellow `N' + di in green "Number of individuals with missing values: " in yellow `nbindmiss' _c + if "`ld'"=="" { + di in green " (removed)" + } + else { + di + } + di in green "Number of individuals with nul or perfect score: " in yellow `=`effscore0'+`effscore`nbgroups''' +} +else { + di "Number of individuals: `N'
" + di "Number of individuals with missing values: " `nbindmiss' + if "`ld'"=="" { + di " (removed)" + } + di "
" + di "Number of individuals with nul or perfect score: " `=`effscore0'+`effscore`nbgroups''' "
" +} +if "`method'"=="cml" { + if "`html'" == "" { + di in green "Conditional log-likelihood: " in yellow %-13.4f `ll' + di in green "Log-likelihood: " in yellow %-13.4f `globalll' + } +} +else { + if "`html'" == "" { + di in green "Marginal log-likelihood: " in yellow %-13.4f `ll' + di in green "Log-likelihood: " in yellow %-13.4f `globalll' + di + } + else { + di "Marginal log-likelihood: " %-13.4f `ll' "
" + di "Log-likelihood: " %-13.4f `globalll' "

" + } +} + +if "`html'" == "" { + noi di in green _col(16) "Difficulty" `conttest' + if "`test'"!="NONE" { + di in green _col(58) "Standardized" + } + noi di in green _col(9) "Items" _col(16) "parameters" _col(28) "std Err." `conttest' + if "`test'"!="NONE" { + local varin=int(2/sqrt(`nbind')*100)/100 + local varout=int(6/sqrt(`nbind')*100)/100 + di _col(41) "`namewp'" _col(47) "df" _col(50) "p-value" _col(58) "Outfit" _col(66) "Infit" `cont' + if "`method'"=="cml" { + di in green _col(77) "U" + } + } + di in green "{hline `line'}" +} +else { + di "" + di "" + di "" + if "`test'"!="NONE" { + di "" + } + di "" + di "" + if "`test'"!="NONE" { + local varin=int(2/sqrt(`nbind')*100)/100 + local varout=int(6/sqrt(`nbind')*100)/100 + di "" + if "`method'"=="cml" { + di "" + } + } + di "" +} + +forvalues i=1/`nbitems' { + if "`html'" == "" { + noi di in yellow _col(3) %12s abbrev("``i''`fixed`i''" ,12) in yellow _col(18) %8.5f `beta`i'' _col(29) %6.5f `sd`i'' `conttest' + } + else { + di "" + } + if "`test'"!="NONE" { + if "`html'" == "" { + di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfitstd`i'' _col(65) %6.3f `infitstd`i'' /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/ `cont' + } + else { + di "" + } + matrix `itemfit'[`i',1]=`testitems'[`i',1] + matrix `itemfit'[`i',2]=`=`nbgroups'-2' + matrix `itemfit'[`i',3]=1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) + matrix `itemfit'[`i',4]=`outfitstd`i'' + matrix `itemfit'[`i',5]=`infitstd`i'' + if "`method'"=="cml" { + if "`html'" == "" { + di in ye _col(72) %6.3f `U`i'' + } + else { + di "" + } + matrix `itemfit'[`i',6]=`U`i'' + } + if "`html'" != "" { + di "" + } + } +} +if "`html'" == "" { + di in green "{hline `line'}" +} +else { + di "" +} +if "`test'"!="NONE" { + if "`method'"=="cml" { + local df=(`nbgroups'-2)*(`nbitems'-1) + } + else { + local df=(`nbgroups'-1)*(`nbitems'-1)-1 + } + matrix `globalfit'=(`stattest',`df',1-chi2(`df',`stattest')) + if "`html'" == "" { + noi di in green _col(6) "`descwp'" _col(32) in gr "`namewp'=" _col(36) in ye %8.3f `globalfit'[1,1] _col(46) %3.0f `globalfit'[1,2] _col(51) %6.4f `globalfit'[1,3] + if "`method'"=="cml" { + noi di in green _col(6) "Andersen LR test" _col(34) "Z=" in yellow _col(36) %8.3f `AndersenZ'[1,1] _col(46) %3.0f `AndersenZ'[1,2] _col(51) %6.4f `AndersenZ'[1,3] + } + di in green "{hline `line'}" + } + else { + di "" + if "`method'"=="cml" { + di "" + } + di "
DifficultyStandardized
Itemsparametersstd Err.`namewp'dfp-valueOutfitInfitU
" %12s abbrev("``i''`fixed`i''" ,12) "" %8.5f `beta`i'' "" %6.5f `sd`i'' "" %8.3f `testitems'[`i',1] "" %3.0f `=`nbgroups'-2' "" %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) "" %6.3f `outfitstd`i'' "" %6.3f `infitstd`i'' "" %6.3f `U`i'' "
`descwp'`namewp'=" %8.3f `globalfit'[1,1] "" %3.0f `globalfit'[1,2] "" %6.4f `globalfit'[1,3] "
Andersen LR testZ=" %8.3f `AndersenZ'[1,1] "" %3.0f `AndersenZ'[1,2] "" %6.4f `AndersenZ'[1,3] "
" + } +} + +if "`html'" == "" { + if "`method'"=="cml"&"`meandiff'"==""{ + di in green "*: The difficulty parameter of this item had been fixed to 0" + } + if "`method'"=="cml"&"`meandiff'"!=""{ + di in green "The mean of the difficulty parameters is fixed to 0" + } + if `smallgroup'==1&"`test'"!="NONE" { + di in green "You have groups of scores with less than 30 individuals. The tests can be invalid." + } + if "`method'"!="cml"&"`test'"=="Q" { + di in green "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test." + } + + di +} +else { + if "`method'"=="cml"&"`meandiff'"==""{ + di "*: The difficulty parameter of this item had been fixed to 0
" + } + if "`method'"=="cml"&"`meandiff'"!=""{ + di "The mean of the difficulty parameters is fixed to 0
" + } + if `smallgroup'==1&"`test'"!="NONE" { + di "You have groups of scores with less than 30 individuals. The tests can be invalid.
" + } + if "`method'"!="cml"&"`test'"=="Q" { + di "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test.
" + } + di "

" +} + +if "`html'" == "" { + if "`method'"!="cml" { + di in green "{hline 56}" + noi di in green _col(5) "Parameters" _col(21) "Coef." _col(28) "std Err." _col(43) "z" _col(52) "P>|z|" + di in green "{hline 56}" + local zsig=`sig'/`sesig' + local pzsig=2*(1-norm(abs(`zsig'))) + di in green _col(10) in yellow "Sigma" _col(18) %8.5f `sig' _col(29) %6.5f `sesig' _col(38) %6.3f `zsig' _col(50) %7.4f `pzsig' + di in green "{hline 56}" + } +} +else { + if "`method'"!="cml" { + di "" + di "" + di "" + local zsig=`sig'/`sesig' + local pzsig=2*(1-norm(abs(`zsig'))) + di "
ParametersCoef.std Err.zP>|z|
Sigma" %8.5f `sig' "" %6.5f `sesig' "" %6.3f `zsig' "" %7.4f `pzsig' "
" + } +} + + + +*set trace on +if "`covariables'"!="" { + tempname zcovariates pcovariates + matrix `zcovariates'=J(1,`nbcovariables',0) + matrix `pcovariates'=J(1,`nbcovariables',0) + forvalues i=1/`nbcovariables' { + local tmp :word `i' of `covariables' + local zcov=`betacov'[1,`i']/`Vbetacov'[`i',`i']^.5 + local pzcov=2*(1-norm(abs(`zcov'))) + matrix `zcovariates'[1,`i']=`zcov' + matrix `pcovariates'[1,`i']=`pzcov' + di in green _col(3) %12s in yellow abbrev("`tmp'",12) _col(18) %8.5f `betacov'[1,`i'] _col(29) %6.5f `Vbetacov'[`i',`i']^.5 _col(38) %6.3f `zcov' _col(50) %7.4f `pzcov' + } + di in green "{hline 56}" + local difficulties2 + if "`difficulties'"!="" { + local difficulties2 diff(`difficulties') + } + if "`ss1'"!="" { + tempfile ss1save + qui save `ss1save' + qui use `saveraschtest' + qui keep if `touse'==1 + + qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2' + local sigma0=r(sigma) + local var0=`sigma0'^2 + local nbobs=r(N_obs) + *di "nbobs=`nbobs'" + local df0=`nbobs'-(`nbitems'+1)-1 + local ss10=`var0'*(`df0') + local ss1c0=0 + di + di in green "Type 1 Sum of Squares (sequential)" + di "{hline 85}" + di in green _col(44) "Degrees" _col(56) "Variance of the" _col(77) "Explained" + di in green _col(4) "Covariates" _col(25) "SS" _col(35) "Diff" _col(41) "of freedom"_col(59) "latent trait" _col(78) "Variance" + di "{hline 85}" + di _col(10) in green "None" _col(15) in ye %12.3f `ss10' _col(47) %4.0f `df0' _col(63) %8.3f `var0' + di in green "{dup 85:-}" + local covariablesss1 + forvalues i=1/`nbcovariables' { + local covariablesss1 `covariablesss1' `covariable`i'' + qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss1') test(none) `ld' `difficulties2' + local nbobs=r(N_obs) + local sigma`i'=r(sigma) + local var`i'=`sigma`i''^2 + local nbcovtmp:word count `covariablesss1' + *di " ss1`i'=`var`i''*`=`nbobs'-(`nbitems'+1+`nbcovtmp')-1'" + local df`i'=`nbobs'-(`nbitems'+1+`nbcovtmp')-1 + *di "local df`i'=`nbobs'-(`nbitems'+1+`nbcovtmp')-1 (cov:`covariablesss1')" + local ss1`i'=`var`i''*`df`i'' + *di "cov : `covariablesss1' var=`var`i'' df=`df`i''" + di _col(2) %12s in yellow abbrev("`covariable`i''",12) _col(15) %12.3f in ye `ss1`i'' _col(25) %12.3f `=`ss1`=`i'-1''-`ss1`i''' _col(47) %4.0f `df`i'' _col(63) %8.3f `var`i'' _col(81) %5.3f (`=`ss1`=`i'-1''-`ss1`i''')/`ss10' + } + di in green "{hline 85}" + qui use `ss1save' + } + if "`ss3'"!="" { + tempfile ss3save + qui save `ss3save' + qui use `saveraschtest' + qui keep if `touse'==1 + if "`ss1'"=="" { + qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2' + local sigma0=r(sigma) + local var0=`sigma0'^2 + local nbobs=e(N_obs) + local df0=`nbobs'-(`nbitems'+1)-1 + local ss30=`var0'*(`df0') + } + else { + local ss30=`ss10' + } + local ss3ref=`=`sig'^2*(`df0'-`nbcovariables')' + di + di in green "Type 3 Sum of Squares " + di "{hline 85}" + di in green _col(44) "Degrees" _col(56) "Variance of the" _col(77) "Explained" + di in green _col(4) "Covariates" _col(25) "SS" _col(35) "Diff" _col(41) "of freedom"_col(59) "latent trait" _col(78) "Variance" + di "{hline 85}" + di _col(10) in green "None" _col(15) in ye %12.3f `ss30' _col(47) %4.0f `df0' _col(63) %8.3f `var0' + di _col(6) in green "Complete" _col(15) in ye %12.3f `ss3ref' _col(25) %12.3f `=`ss30'-`ss3ref'' _col(47) %4.0f `=`df0'-`nbcovariables'' _col(63) %8.3f `sig'^2 _col(81) %5.3f 1-`sig'^2*(`df0'+`nbcovariables')/`ss30' + di in green "{dup 85:-}" + forvalues i=1/`nbcovariables' { + local covariablesss3 + forvalues j=1/`nbcovariables' { + if `i'!=`j' { + local covariablesss3 `covariablesss3' `covariable`j'' + } + } + qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss3') test(none) `ld' `difficulties2' + *ereturn list + local sigmas`i'=r(sigma) + local vars`i'=`sigmas`i''^2 + local nbobs=e(N) + local dfs`i'=`nbobs'-(`nbitems'+1)-1-(`nbcovariables'-1) + *di "local dfs`i'=`nbobs'-(`nbitems'+1)-1-(`nbcovariables'-1)" + local ss3s`i'=`vars`i''*`dfs`i'' + local vara`i'=`sig'^2 + local dfa`i'=`nbobs'-(`nbitems'+1)-1-`nbcovariables' + local ss3a`i'=`vara`i''*`dfa`i'' + *di "cov : `covariablesss3' var=`vars`i'' df=`dfs`i''" + di _col(2) %12s in green abbrev("`covariable`i''",12) _col(15) in ye %12.3f `ss3s`i'' _col(25) %12.3f in ye `=`ss3s`i''-`ss3a`i''' _col(47) %4.0f `=`df0'-`nbcovariables'+1' _col(63) %8.3f `vars`i'' _col(80) %6.3f (`=`ss3s`i''-`ss3a`i''')/`ss30' + } + di in green "{hline 85}" + qui use `ss3save' + } +} + + + +/*Tabular of the estimated values of the latent trait*/ + +if "`covariables'"=="" { + if "`html'" == "" { + di + di + noi di in green _col(33) "Ability" _col(60) "Expected" + noi di in green _col(17) "Group" _col(23) "Score" _col(30) "parameters" _col(42) "std Err." _col(54) "Freq." _col(63) "Score"_c + if "`method'"=="cml"&"`test'"!="NONE" { + noi di in green _col(75) "ll" + } + else { + noi di "" + } + if "`method'"=="cml"&"`test'"!="NONE" { + local line=62 + } + else { + local line=51 + } + di in green _col(17) "{hline `line'}" + } + else { + di "" + di "" + di "" + if "`method'"=="cml"&"`test'"!="NONE" { + di "" + } + di "" + } + + local nonul=0 + forvalues g=0/`nbgroups' { + if `g'!=0 { + if "`html'" == "" { + di in green _col(17) "{dup `line':-}" + } + } + forvalues s=`liminf`g''/`limsup`g'' { + if `s'==`liminf`g'' { + local tmp `ll`g'' + local gr `g' + } + else { + local tmp + local gr + } + local expscore`nonul'=0 + forvalues i=1/`nbitems' { + local expscore`nonul'=`expscore`nonul''+1/(1+exp(-`theta`nonul''+`beta`i'')) + } + if "`method'"=="cml" { + local format1 %8.3f + } + else { + local format1 %8.5f + } + if "`html'" == "" { + noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(32) `format1' `theta`nonul'' _col(42) `format1' `sdtheta`nonul'' _col(55) %4.0f `nbrealscore`s'' _col(64) % 4.2f `expscore`nonul'' _col(68) %11.4f `tmp' + } + else { + di "" + } + local nonul=`nonul'+1 + } + } + if "`html'" == "" { + di in green _col(17) "{hline `line'}" + } + else { + di "
GroupScoreAbility
parameters
std Err.Freq.Expected
Score
ll
" %5s "`gr'" "" %5s "`s'" "" `format1' `theta`nonul'' "" `format1' `sdtheta`nonul'' "" %4.0f `nbrealscore`s'' "" % 4.2f `expscore`nonul'' "" %11.4f `tmp' "
" + } +} + +if "`method'"=="mml"|"`method'"=="gee" { + if "`html'" == "" { + di + *di in green "Variance of the estimated latent trait" _col(45) in ye %10.4f `vartheta' + di in green "Mean variance of the error" _col(45) in ye %10.4f `meanse2' + local sig2=`sig'^2 + di in green "Estimated variance of the latent trait" _col(45) in ye %10.4f `sig2' + local psi2=1-`meanse2'/`sig2' + di in green "Personal Separation Index (PSI)" _col(45) in ye %10.4f `psi2' + di in green "Adjusted PSI on covariates (PSIadj)" _col(45) in ye %10.4f `psi' + } + else { + di "" + di "" + di "" + di "" + local sig2=`sig'^2 + di "" + local psi2=1-`meanse2'/`sig2' + di "" + di "" + di "
Mean variance of the error" %10.4f `meanse2' "
Estimated variance of the latent trait" %10.4f `sig2' "
Personal Separation Index (PSI)" %10.4f `psi2' "
Adjusted PSI on covariates (PSIadj)" %10.4f `psi' "
" + } +} + + +/*********************************************************************************************************** +DETAILS OPTION +************************************************************************************************************/ + +if "`details'"!="" { + if "`html'"=="" { + forvalues g=0/`nbgroups' { + if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" { + di + di in green "{hline 44}" + di in green "Group: " in ye "`g'" in green " from " in ye "`liminf`g''" in green " to " in ye "`limsup`g''" in green " (n=" in ye "`nbscore`g''" in green")" + di + di _col(3) "Item" _col(10) "Observed" _col(23) "Expected" _col(37) "Scaled" + di in green "{dup 44:-}" + } + if `g'!=0&`g'!=`nbgroups' { + forvalues j=1/`nbitems' { + local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j']) + di _col(3) in ye "``j''" _col(14) %4.0f `Obs2'[`j',`g'] _col(25) %6.2f `Th2'[`j',`g'] _col(36) %7.4f `tmp' + } + di in green "{dup 44:-}" + di in green "Contribution to the `namewp' statistics: " %8.4f in ye `test`g''[1,1] + } + else if "`method'"!="cml" { + if `g'==0 { + local h=0 + } + else { + local h=`nbitems' + } + local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'') + di in ye _col(14) %4.0f `nbrealscore`h'' _col(25) %6.2f `ci`h'' _col(36) %7.4f `tmp' + di in green "{dup 44:-}" + local tmp=`tmp'^2 + di in green "Contribution to the `namewp' statistics: " %8.4f in ye `tmp' + } + } + } + else { + forvalues g=0/`nbgroups' { + if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" { + di in gr "" + di in gr "" + di in gr "" + } + if `g'!=0&`g'!=`nbgroups' { + forvalues j=1/`nbitems' { + local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j']) + di "" + } + di "" + } + else if "`method'"!="cml" { + if `g'==0 { + local h=0 + } + else { + local h=`nbitems' + } + local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'') + di "" + local tmp=`tmp'^2 + di "" + } + di "
Group: `g' from `liminf`g'' to `limsup`g'' (n=`nbscore`g'')
ItemObservedExpectedScaled
``j''" %4.0f `Obs2'[`j',`g'] "" %6.2f `Th2'[`j',`g'] "" %7.4f `tmp' "
Contribution to the `namewp' statistics:" %8.4f `test`g''[1,1] "
" %4.0f `nbrealscore`h'' "" %6.2f `ci`h'' "" %7.4f `tmp' "
Contribution to the `namewp' statistics:" %8.4f `tmp' "
" + } + } +} + +/*********************************************************************************************************** +OPTION ICC +************************************************************************************************************/ +*set trace on +if "`icc'"!="" { + if "`trace'"!="" { + di in green "*** Items Characteristic Curves" + } + tempvar proba propemp propth propthb + qui replace `tl'=. if `realscore'==0|`realscore'==`nbitems'|`realscore'==. + qui gen `propemp'=. + qui gen `propth'=. + qui gen `propthb'=. + label variable `propth' "Expected ICC" + label variable `propemp' "Observed ICC" + label variable `propthb' "Expected ICC" + label variable `tl' "Latent trait" + global iccs + forvalues i=1/`nbitems' { + forvalues s=1/`=`nbitems'-1' { + qui replace `propthb'=exp(`theta`s''-`beta`i'')/(1+exp(`theta`s''-`beta`i'')) if `item'==`i'&`realscore'==`s' + } + qui replace `propemp'=. + qui replace `propth'=. + tempvar propemp`i' propth`i' + qui bysort `realscore' `item' : egen `propth`i''=mean(`propthb') if `item'==`i' + qui bysort `realscore' `item' : egen `propemp`i''=mean(`rep') if `item'==`i' + qui replace `propth'=`propth`i'' if `item'==`i' + qui replace `propemp'=`propemp`i'' if `item'==`i' + local mintl=floor(`theta1') + local maxtl=floor(`theta`=`nbitems'-1'')+1 + if "`filessave'"!=""{ + local saving "`dirsave'\\icc``i''" + } + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_icc_``i''" + } + if "`v8'"!=""|"`html'"!="" { + graph twoway (line `propemp' `propth' `tl') if `item'==`i' , `htmlregion' name(icc``i'',replace) ytitle("") ylabel(0(.25)1) title("Observed and Expected ICC for the item ``i''") xlabel(`mintl'(1)`maxtl') xsize(12) ysize(9) `draw' + if "html"=="" { + pause + } + else { + qui graph save icc``i'' "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_icc_``i''.eps, replace + di " _char(34) " + + } + if "`filessave'"!="" { + qui graph save icc``i'' "`saving'" , `replace' + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + qui graph `propemp' `propth' `tl' if `item'==`i' , twoway `saving' c(ll) ylabel(0(.25)1) xlabel(`mintl'(1)`maxtl') title("Observed and Expected ICC for the item ``i''") + pause + } + } +} + +/*********************************************************************************************************** +OPTION INFORMATION +************************************************************************************************************/ + +if "`information'"!="" { + if "`trace'"!="" { + di in green "*** Information graph" + } + + tempfile saveinfo + qui save "`saveinfo'",replace + tempvar info latent + drop _all + qui set obs 2001 + gen `latent'=((_n-1)/1001-1)*3 + label variable `latent' "latent trait" + gen `info'=0 + forvalues i=1/`nbitems' { + qui replace `info'=`info'+exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2 + } + local saving "`dirsave'\\information" + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_information" + } + if "`v8'"!=""|"`html'"!="" { + *set trace on + graph twoway (line `info' `latent') , `htmlregion' name(information,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the scale") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + graph save information "`saving'" , `replace' + } + if "`html'"=="" { + pause + } + else { + qui graph save information "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_information.eps, replace + di " _char(34) " + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + if "`filessave'"=="" { + local saving + } + qui graph `info' `latent' , twoway `saving' c(l) xlabel(-3(1)3) title("Information graph of the scale") + pause + } + qui use "`saveinfo'",replace +} + +/*********************************************************************************************************** +OPTION FITGRAPH +************************************************************************************************************/ + +if "`fitgraph'"!="" { + if "`trace'"!="" { + di in green "*** Graphical validation of the fit" + } + *set trace on + tempname outfit meanz2 meanv2 sumd infit Voutfit outfitstd Vinfit infitstd + qui egen `outfit'=mean(`y2'),by(`id') + qui egen `Voutfit'=sum(`r'),by(`id') + qui replace `Voutfit'=`Voutfit'/(`nbitems')^2-1/`nbitems' + qui gen `outfitstd'=(`outfit'^(1/3)-1)*(3/sqrt(`Voutfit'))-sqrt(`Voutfit')/3 + qui egen `meanz2'=sum(`z2'),by(`id') + qui egen `meanv2'=sum(`v2'),by(`id') + qui gen `infit'=`meanz2'/`meanv2' + qui egen `Vinfit'=sum(`e'),by(`id') + qui replace `Vinfit'=`Vinfit'/(`meanv2')^2 + qui gen `infitstd'=(`infit'^(1/3)-1)*(3/sqrt(`Vinfit'))-sqrt(`Vinfit')/3 + + qui su `outfitstd' + local mino=floor(2*min(`r(min)',-2))/2 + local maxo=ceil(2*max(`r(max)',2))/2 + qui su `infitstd' + local mini=floor(2*min(`r(min)',-2))/2 + local maxi=ceil(2*max(`r(max)',2))/2 + if "`filessave'"!=""{ + local savingo "`dirsave'\\outfitind" + local savingi "`dirsave'\\infitind" + } + if "`v8'"!="" { + graph twoway (scatter `outfitstd' `id'), `htmlregion' name(outfit,replace) yline(-2 2) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw' + if "`html'"=="" { + pause + } + graph twoway (scatter `infitstd' `id'), `htmlregion' name(infit,replace) yline(-2 2) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw' + if "`html'"=="" { + pause + } + if "`filessave'"!=""|"`html'"!="" { + qui graph save outfit "`savingo'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_outfit.eps, replace + } + qui graph save infit "`savingi'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_infit.eps, replace + } + } + } + else { + if "`filessave'"!="" { + local savingo "saving(`savingo'" + local savingi "saving(`savingi'" + if "`replace'"=="" { + local savingo "`savingo')" + local savingi "`savingi')" + } + else { + local savingo "`savingo',replace)" + local savingi "`savingi',replace)" + } + } + graph `outfitstd' `id', `savingo' twoway sy(.) c(.) yline(-2 2) title("Outfit indexes") b2title("Individual indexes") l1("") l2title("Outfit") ylabel(`mino'(.5)`maxo') + pause + graph `infitstd' `id', `savingi' twoway sy(.) c(.) yline(-2 2) title("Infit indexes") b2title("Individual indexes") l1("") l2title("Infit") ylabel(`mini'(.5)`maxi') + pause + } + drop _all + qui set obs `nbitems' + tempvar name betap outfitstdj infitstdj + qui gen str9 `name'="" + qui gen `betap'=. + qui gen `outfitstdj'=. + qui gen `infitstdj'=. + local mino=-2 + local maxo=2 + local mini=-2 + local maxi=2 + forvalues j=1/`nbitems' { + qui replace `name'="``j''" in `j' + qui replace `betap'=`beta`j'' in `j' + qui replace `outfitstdj'=`outfitstd`j'' in `j' + qui replace `infitstdj'=`infitstd`j'' in `j' + local mino=floor(min(`mino',`outfitstd`j'')*2)/2 + local mini=floor(min(`mini',`infitstd`j'')*2)/2 + local maxo=ceil(max(`maxo',`outfitstd`j'')*2)/2 + local maxi=ceil(max(`maxi',`infitstd`j'')*2)/2 + } + if "`filessave'"!=""{ + local savingo "`dirsave'\\outfititems" + local savingi "`dirsave'\\infititems" + } + if "`v8'"!="" { + graph twoway (scatter `outfitstdj' `betap',`htmlregion' name(outfititem,replace) mlabel(`name')), yline(-2 2) title("Outfit indexes") xtitle("Difficulty") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw' + if "`html"=="" { + pause + } + graph twoway (scatter `infitstdj' `betap',`htmlregion' name(infititem,replace) mlabel(`name')), yline(-2 2) title("Infit indexes") xtitle("Difficulty") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw' + if "`html"=="" { + pause + } + if "`filessave'"!=""|"`html'"!="" { + qui graph save outfititem "`savingo'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_outfititem.eps, replace + } + qui graph save infititem "`savingi'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_infititem.eps, replace + } + } + } + else { + if "`filessave'"!="" { + local savingo "saving(`savingo'" + local savingi "saving(`savingi'" + if "`replace'"=="" { + local savingo "`savingo')" + local savingi "`savingi')" + } + else { + local savingo "`savingo',replace)" + local savingi "`savingi',replace)" + } + } + graph `outfitstdj' `betap', `savingo' twoway c(.) yline(-2 2) title("Outfit indexes") b2title("Difficulty") l1title("") l2title("Outfit") ylabel(`mino'(.5)`maxo') sy([`name']) + pause + graph `infitstdj' `betap', `savingi' twoway c(.) yline(-2 2) title("Infit indexes") b2title("Difficulty") l1title("") l2title("Infit") ylabel(`mini'(.5)`maxi') sy([`name']) + pause + } +} + + +/*********************************************************************************************************** +OPTION SPLITTESTS +************************************************************************************************************/ + +if "`splittests'"!="" { + if "`trace'"!="" { + di in green "*** Splitting tests" + } + forvalues j=1/`nbitems' { + tempname estneg`j' estpos`j' + local listitems + forvalues k=1/`nbitems' { + if `j'!=`k' { + local listitems `listitems' ``k'' + } + } + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + qui raschtestv7 `listitems' if ``j''==0,test(NONE) meth(cml) `ld' id(`id') + matrix `estneg`j''=r(beta) + local llneg=r(cll) + qui raschtestv7 `listitems' if ``j''==1,test(NONE) meth(cml) `ld' id(`id') + matrix `estpos`j''=r(beta) + local llpos=r(cll) + qui raschtestv7 `listitems',test(NONE) meth(cml) `ld' id(`id') + local llnegpos=r(cll) + local nbcol=colsof(`estneg`j'') + local meanneg=0 + local meanpos=0 + forvalues k=1/`nbcol' { + local meanneg=`meanneg'+`estneg`j''[1,`k'] + local meanpos=`meanpos'+`estpos`j''[1,`k'] + } + local meanneg=`meanneg'/`nbitems' + local meanpos=`meanpos'/`nbitems' + forvalues k=1/`nbcol' { + matrix `estneg`j''[1,`k']=`estneg`j''[1,`k']-`meanneg' + matrix `estpos`j''[1,`k']=`estpos`j''[1,`k']-`meanpos' + if "`method'"=="cml" { + matrix `estneg`j''=`estneg`j'',-`meanneg' + matrix `estpos`j''=`estpos`j'',-`meanpos' + } + } + drop _all + qui set obs `=`nbitems'+1' + tempvar neg pos name diag + qui gen `neg'=. + qui gen `pos'=. + qui gen str9 `name'="" + local min=`estneg`j''[1,1] + local max=`estneg`j''[1,1] + forvalues k=1/`=`nbitems'-1' { + qui replace `neg'=`estneg`j''[1,`k'] in `k' + qui replace `pos'=`estpos`j''[1,`k'] in `k' + local min=min(`min',`estneg`j''[1,`k'],`estpos`j''[1,`k']) + local max=max(`max',`estneg`j''[1,`k'],`estpos`j''[1,`k']) + local tmp:word `k' of `listitems' + qui replace `name'="`tmp'" in `k' + } + local min=floor(`min') + local max=floor(`max')+1 + qui gen `diag'=. + qui replace `diag'=`min' in `nbitems' + qui replace `diag'=`max' in `=`nbitems'+1' + local Zgr=round(2*(`llneg'+`llpos'-`llnegpos'),0.001) + local Zgr=substr("`Zgr'",1,6) + local pgr=round(1-chi2(`=`nbitems'-1',`Zgr'),0.0001) + local pgr=substr("`pgr'",1,5) + local note="Z=`Zgr', df=`=`nbitems'-1' , p=`pgr'" + if "`filessave'"!=""{ + local saving "`dirsave'\\split``j''" + } + if "`v8'"!="" { + graph twoway (scatter `pos' `neg' ,mlabel(`name')) (line `diag' `diag'), ytitle("Positive answer") xtitle("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title(Splitting on ``j'') `draw' legend(off) note("Andersen Z test: `note'") name(split,replace) `draw' + pause + if "`filessave'"!="" { + graph save split "`saving'" , `replace' + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + qui replace `diag'=`neg' if `diag'==. + graph `pos' `diag' `diag', `saving' c(.l) sy([`name']i) l1title("") l2title("Positive answer") b2title("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title("Splitting on ``j'' (`note')") `draw' + pause + } + } +} + +/*********************************************************************************************************** +OPTION GRAPH +************************************************************************************************************/ + +if "`graph'"!=""&"`v8'"!="" { + if "`trace'"!="" { + di in green "*** Graph option" + } + tempvar latent2 tl2 delta2 tlth2 labdelta2 labtl2 + drop _all + qui set obs 1001 + gen `latent2'=(_n-501)/100 + label variable `latent2' "latent trait" + qui gen `tl2'=. + qui gen `labtl2'="" + forvalues i=0/`nbitems' { + *if (`i'!=0&`i'!=`nbitems')|"`method'"!="cml" { + qui replace `tl2'=`nbrealscore`i''/`N' if round(`latent2',0.01)==round(`theta`i'',0.01) + qui replace `labtl2'="`i'" if round(`latent2',0.01)==round(`theta`i'',0.01) + *} + } + qui gen `delta2'=. + qui gen `labdelta2'="" + forvalues i=1/`nbitems' { + qui replace `delta2'=-.05 if round(`latent2',0.01)==round(`beta`i'',0.01) + qui replace `labdelta2'="``i''" if round(`latent2',0.01)==round(`beta`i'',0.01) + } + if "`method'"=="mml"|"`method'"=="gee" { + qui gen `tlth2'=1/(2*_pi*`sig')*exp(-.5*(`latent2'/`sig')^2) + label variable `tlth2' "Theorical distribution" + local graphmml line `tlth2' `latent2' + } + label variable `tl2' "Score" + label variable `delta2' "Items" + local saving "`dirsave'\\graph" + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_map" + } + local min=-2 + local max=2 + forvalues j=1/`nbitems' { + if `beta`j''<`min' { + local min=`beta`j''-.5 + } + if `beta`j''>`max'&`beta`j''!=. { + local max=`beta`j''+.5 + } + } + if "`method'"=="cml" { + if `theta0'<`min' { + local min=`theta0'-.5 + } + if `theta`=`nbitems'-1''>`max' { + local max=`theta`=`nbitems'-1''+.5 + } + } + else if "`method'"!="cml" { + if `theta0'<`min'&`theta0'!=. { + local min=`theta0'-.5 + } + if `theta`nbitems''>`max'&`theta`nbitems''!=. { + local max=`theta`nbitems''+.5 + } + } + local min=floor(`min') + local max=floor(`max')+1 + qui su `tl2' + local max2=r(max) + if "`method'"!="cml" { + qui su `tlth2' + local max2=max(`max2',`r(max)') + } + qui replace `latent2'=. if `latent2'<`min'|`latent2'>`max' + if "`v8'"!="" { + graph twoway (bar `tl2' `latent2',/*mlabel(`labtl2')*/ barwidth(.3) ) (dropline `delta2' `latent2',mlabel(`labdelta2') mlabposition(6)) (`graphmml'), `htmlregion' name(graph,replace) ytitle("") xlabel(`min'(1)`max') ylabel(-.1 0(0.05)`max2') title("Individuals/items representations") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + graph save graph "`saving'" , `replace' + } + if "`html'"=="" { + pause + } + else { + qui graph save graph "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_map.eps, replace + di " _char(34) " + } + } +} +else if "`graph'"!=""&"`v8'"=="" { + di in ye "The graph option is not available with Stata 7" +} + +/*********************************************************************************************************** +COMPARISON OF TWO POPULATION +************************************************************************************************************/ + +if "`comp'"!=""&"`method'"!="cml" { + di + di _col(4) "{hline 30}" + di _col(4) in green "Comparison of two populations" + di _col(4) "{hline 30}" + di + di _col(4) in green "`comp'==`mincomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmin' _col(30) in green "mean= " _col(35) in yellow %8.4f `meanmin' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmin' + di _col(4) in green "`comp'==`maxcomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmax' _col(30) in green "mean= " _col(35) in yellow %8.4f `meanmax' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmax' + di _col(33) in green "Z= " _col(35) in yellow %8.4f `Zcomp' _col(47) in green "pvalue= " _col(57) in yellow %6.4f `pvalue' +} + +/*********************************************************************************************************** +TEST DIF +************************************************************************************************************/ + +if "`method'"=="cml"&"`dif'"!=""&"`test'"!="NONE" { + if "`trace'"!="" { + di in green "*** Tests of DIF" + } + local ssll=0 + tempname DIFfile + qui save "`DIFfile'", replace + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + unab list:`dif' + local nbdif:word count `list' + tempname DIF + matrix define `DIF'=J(`nbdif',4,0) + local count=1 + di + di _col(4) in green "{hline 45}" + di _col(4) in green "Test of Differential Item Functioning (DIF)" + di _col(4) in green "{hline 45}" + foreach j in `list' { + qui inspect `j' + local nbdif=r(N_unique) + qui su `j' + local maxdif=r(max) + if `nbdif'>10&`maxdif'<=10 { + di in ye "The {hi:dif} option is available with variables containing 10 or less modalities (coded from 0 or 1 to k<10)." + di in ye "The variable `j' (`nbdif' modalities) is omitted." + } + else { + local ssll=0 + forvalues i=0/10 { + qui count if `j'==`i' + local effdif=r(N) + if `effdif'>0 { + qui raschtestv7 `varlist' if `j'==`i', test(NONE) id(`id') + local ll`i'=r(cll) + local ssll=`ssll'+(`ll`i'') + } + } + local Z=2*`ssll'-2*`ll' + local ddl=(`nbdif'-1)*(`nbitems'-1) + matrix define `DIF'[`count',1]=(`count',`Z',`ddl',1-chi2(`ddl',`Z')) + di + di _col(4) in green "Variable:" in ye " `j' " in green " Number of groups: " in ye "`nbdif'" + di _col(4) in green "LR Test Z=" in ye %8.3f `Z' in gr " ddl=" in ye %4.0f `ddl' in gr " p-value=" in ye %6.4f `=1-chi2(`ddl',`Z')' + di + } + local ++count + } + use "`DIFfile'",replace +} + +/*********************************************************************************************************** +RETURN +************************************************************************************************************/ + +if "`trace'"!="" { + di in green "*** Returns" +} +local colnametheta + +forvalues i=0/`nbgroups' { + local colnametheta `colnametheta' score_`i' +} + + +return clear + +if `nbitems'>=3&"`test'"!="NONE" { + matrix colnames `globalfit'=`namewp' df p + matrix rownames `globalfit'=`method' + matrix rownames `itemfit'=`varlist' + matrix roweq `itemfit'=`method' + + if "`method'"=="cml" { + matrix colnames `itemfit'=`namewp' df p outfit infit U + matrix rownames `AndersenZ'=`method' + matrix colnames `AndersenZ'=Z df p + return matrix AndersenZ=`AndersenZ' + if "`dif'"!="" { + matrix rownames `DIF'=`list' + matrix colnames `DIF'=num Z df p + return matrix DIF=`DIF' + } + } + else { + matrix colnames `itemfit'=`namewp' df p outfit infit + } + return matrix itemFit=`itemfit' + return matrix globalFit=`globalfit' +} + +matrix colnames `theta'=`colnametheta' +matrix rownames `theta'=theta +return matrix theta `theta' +matrix colnames `sdtheta'=`colnametheta' +matrix rownames `sdtheta'=`colnametheta' +return matrix Vartheta `sdtheta' +local varlist2 +matrix coleq `beta'=`method' +matrix coleq `Vbeta'=`method' +matrix roweq `Vbeta'=`method' +if "`method'"=="cml" { + forvalues i=1/`=`nbitems'-1' { + local varlist2 `varlist2' ``i'' + } + return scalar cll=`ll' + return scalar ll=`globalll' + local AIC=-2*`globalll'+2*(`nbitems'-1) +} +else { + return scalar ll=`ll' + local varlist2 `varlist' + return scalar sigma=`sig' + return scalar sesigma=`sesig' + local AIC=-2*`ll'+2*(`nbitems'+1) +} + +if "`comp'"!="" { + return scalar Zcomp=`Zcomp' + return scalar pZcomp=`pvalue' +} + +matrix colnames `beta'=`varlist2' +matrix rownames `beta'=beta +return matrix beta `beta' + +matrix colnames `Vbeta'=`varlist2' +matrix rownames `Vbeta'=`varlist2' +return matrix Varbeta `Vbeta' + +return scalar AIC=`AIC' +return scalar N=`nbind' +return scalar N_obs=`nbobserv' + +if "`method'"=="mml" { + return scalar PSI=`psi2' + return scalar PSIadj=`psi' +} +if "`covariables'"!="" { + local tmp + local tmp2 + forvalues i=1/`nbcovariables' { + local tmp `tmp' `covariable`i'' + local tmp2 "`tmp2' :`covariable`i''" + } + matrix colnames `betacov'=`tmp2' + matrix rownames `Vbetacov'=`tmp2' + matrix colnames `Vbetacov'=`tmp2' + matrix colnames `zcovariates'=`tmp' + matrix colnames `pcovariates'=`tmp' + return matrix betacovariates=`betacov' + return matrix Vbetacovariates=`Vbetacov' + return matrix zcovariates=`zcovariates' + return matrix pcovariates=`pcovariates' +} +if "`pause'"!="" { + pause off +} + +drop _all + +restore,not +use "`saveraschtest'" + +/*********************************************************************************************************** +CREATE EVENTUAL NEW VARIABLES +************************************************************************************************************/ + +*set trace on +if "`genres'"!="" { + qui sort `id' + qui merge `id' using `ltsave' + qui rename `u'm1 `genlt' + qui rename `u's1 se`genlt' + qui drop _merge se`genlt' + forvalues i=1/`nbitems' { + gen `genres'`i'=exp(``i''*(`genlt'-`beta`i''))/(1+exp(`genlt'-`beta`i''))/sqrt(exp(`genlt'-`beta`i'')/(1+exp(`genlt'-`beta`i''))^2) + } + corr `genres'* + pca `genres'* + drop `u'm1 +} +if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" { + tempname genlt2 genscore2 outfit2 infit2 + qui gen `score'=0 `if' + forvalues i=1/`nbitems' { + qui replace `score'=`score'+``i'' `if' + } + if "`genscore'"!="" { + qui gen `genscore'=`score' `if' + } + if "`genlt'"!="" { + if "`replacegenlt'"=="replace" { + capture drop `genlt' + capture drop se`genlt' + } + if "`method'"=="mml" { + qui sort `id' + qui merge `id' using `ltsave' + qui rename `u'm1 `genlt' + qui rename `u's1 se`genlt' + qui drop _merge + } + else if "`method'"!="mml" { + qui gen `genlt2'=. `if' + forvalues i=0/`nbitems' { + qui replace `genlt2'=`theta`i'' `if'&`score'==`i' + } + qui gen `genlt'=`genlt2' `if' + } + } + if "`genfit'"!="" { + local outfit:word 1 of `genfit' + local infit:word 2 of `genfit' + qui gen `outfit'=0 `if' + qui gen `infit'=0 `if' + tempname infit1 infit2 + qui gen `infit1'=0 `if' + qui gen `infit2'=0 `if' + forvalues j=1/`nbitems' { + tempname pi`j' + qui gen `pi`j''=exp(`genlt2'-`beta`j'')/(1+exp(`genlt2'-`beta`j'')) `if' + qui replace `pi`j''=0 `if' + forvalues s=1/`nbitems' { + qui replace `pi`j''=`Pi'[`j',`s'] `if'&`score'==`s' + } + qui gen `outfit'``j''=(``j''-`pi`j'')^2/(`pi`j''*(1-`pi`j'')) `if' + qui replace `infit1'=`infit1'+(``j''-`pi`j'')^2 `if' + qui replace `infit2'=`infit2'+(`pi`j''*(1-`pi`j'')) `if' + qui replace `outfit'=`outfit'+`outfit'``j''/`nbitems' `if' + } + qui replace `infit'=`infit1'/`infit2' `if' + } +} + +if "`trace'"!=""|"`time'"!="" { + capture qui elapse `st' + di in green "** Time : " in yellow "$S_elap " in green "seconds" +} + +end diff --git a/Modules/ado/personal/r/raschtestv7v8.10.1.ado b/Modules/ado/personal/r/raschtestv7v8.10.1.ado new file mode 100644 index 0000000..ca3ed1c --- /dev/null +++ b/Modules/ado/personal/r/raschtestv7v8.10.1.ado @@ -0,0 +1,2568 @@ +*! version 8.10.1 15july2019 +*! Jean-Benoit Hardouin +************************************************************************************************************* +* Raschtestv7: Rasch model, fit tests and graphical representations +* Corresponds to the version 8 of Raschtest (http://freeirt.org) for Stata7 +* +* Historic: +* Version 2.1 (2003-07-10): Jean-Benoit Hardouin +* Version 3.1 (2004-01-02) : Jean-Benoit Hardouin +* Version 7.1 (2005-03-30) : Jean-Benoit Hardouin +* Version 7.2.1 (2005-05-21) : Jean-Benoit Hardouin +* Version 7.3.1 (2005-07-02) : Jean-Benoit Hardouin +* Version 7.3.2 (2005-10-05) : Jean-Benoit Hardouin /*correction for the *genlt* option with *method(cml)**/ +* Version 7.3.3 (2005-12-21) : Jean-Benoit Hardouin /*correction if scores are not represented with method(mml) or method(gee)*/ +* Version 7.4.1 (2006-01-17) : Jean-Benoit Hardouin /*Standardized OUTFIT and INFIT, DIF option*/ +* Version 7.4.2 (2006-03-21) : Jean-Benoit Hardouin /*Avoids a bug when the temporary files are saved in a directory containing special characters*/ +* Version 7.4.3 (2006-11-15) : Jean-Benoit Hardouin /*Avoids a bug when the directory defined in the dirsave option contains special characters*/ +* Version 7.5.1 (2007-04-20) : Jean-Benoit Hardouin /*Return results of the comp option*/ +* Version 7.6.1 (2008-06-26) : Jean-Benoit Hardouin /*Nold option, corrects a bug with the genlt option*/ +* Version 7.6.2 (2009-03-01) : Jean-Benoit Hardouin /*Correction of the SE of the latent trait, graph option, correction of a bug with the if option, PSI in MML*/ +* Version 8.1 (2009-06-24) : Jean-Benoit Hardouin /*DIFFICULTIES option, COVARIATES option*/ +* Version 8.2 (2009-07-15) : Jean-Benoit Hardouin /*Correction of a bug with CML*/ +* Version 8.3 (2009-12-19) : Jean-Benoit Hardouin /*correction of a bug with DIFFICULTIES and COVARIATES options together*/ +* Version 8.4 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option */ +* Version 8.5 (2011-12-20) : Jean-Benoit Hardouin /*Correction for the ss1 and ss3 suboptions of the COVARIATES option */ +* Version 8.6 (2012-11-20) : Jean-Benoit Hardouin /*HTML option*/ +* Version 8.7 (2013-05-28) : Jean-Benoit Hardouin /*Correction of a bug in the covariates option with ss1 and ss3*/ +* Version 8.8 (2014-02-27) : Jean-Benoit Hardouin /*Correction of a bug when the null or the parfect score have a frequency of 0 (no test)*/ +* Version 8.9 (2019-06-05) : Jean-Benoit Hardouin /*png option (graphs in png), information curve by item*/ +* Version 8.10 (2019-07-05) : Jean-Benoit Hardouin /*extension option (graphs with the chosen extension) who replaces the png option, docx option*/ +* Version 8.10.1 (2019-07-15) : Jean-Benoit Hardouin /*nostand option*/ +* +* Needed modules : +* gammasym version 2.2 (http://www.freeirt.org) +* gausshermite version 1 (http://www.freeirt.org) +* geekel2d version 4.3 (http://www.freeirt.org) +* genscore version 1.4 (http://www.freeirt.org) +* ghquadm (findit ghquadm) +* gllamm version 2.3.20 (ssc describe gllamm) +* gllapred version 2.3.8 (ssc describe gllapred) +* elapse (ssc describe elapse) +* +* Jean-benoit Hardouin - University of Nantes - France +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research" +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2003-2014 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*********************************************************************************************************** +DEFINITION / SYNTAX +***********************************************************************************************************/ + + +program define raschtestv7,rclass +syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GENRES(string) GRAph v8 COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) extension(string) GRAPHClose DOCX(string) noSTand] + +local covariables `covariates' + +if "`docx'"!="" { + putdocx clear + putdocx begin + putdocx paragraph + putdocx text ("Graphical outputs of the raschtest module") +} +if "`if'"=="" { + local if "if 1" +} + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + +if "`trace'"!="" { + di in green "*** Tests of conformity" +} +if "`v8'"=="" { + version 7.0 +} +else { + version 8.0 +} +if "`html'"!="" { + set scheme sj + local htmlregion "graphregion(fcolor(white) ifcolor(white))" + local draw +} + +local st = "$S_TIME" +local nbitems : word count `varlist' +marksample touse ,novarlist +if "`covariables'"!="" { + tokenize "`covariables'",parse(" ,") + local i=1 + local tcovariables + while "``i''"!=","&"``i''"!="" { + local covariable`i' ``i'' + local tcovariables `tcovariables' ``i'' + local ++i + } + local nbcovariables=`i'-1 + local ss1 + local ss3 + if "``i''"=="," { + forvalues j=`=`i'+1'/`=`i'+2' { + if "``j''"=="ss1" { + local ss1 ss1 + } + else if "``j''"=="ss3" { + local ss3 ss3 + } + else if "``j''"=="" { +* di in green "option `j' vide" + } + else { + di in red "Invalid option in the {hi:covariables} option" + error 198 + } + } + local i=`i'+3 + if "``i''"!="" { + di in red "There is too much options in the {hi:covariates} option." + error 198 + } + } + local covariables `tcovariables' +} +else { + local nbcovariables=0 +} + +isid `id' +tokenize `varlist' + +local bad +forvalues i=1/`nbitems' { + qui count if ``i''!=0&``i''!=1&``i''!=. + local N=r(N) + if `N'>0 { + local bad `bad' ``i'' + } +} +if "`bad'"!="" { + di in red "The item(s) {hi:`bad'} is(are) not binary item(s) (with responses 0 or 1)." + exit +} + + + +if "`method'"=="" { + local method cml +} +if "`test'"=="" { + local test R +} +local method=lower("`method'") +local test=upper("`test'") +if "`method'"!="mml"&"`method'"!="cml"&"`method'"!="gee" { + di in red "Uncorrect method option." + error 198 + exit +} + +if "`test'"!="R"&"`test'"!="Q"&"`test'"!="WP"&"`test'"!="NONE" { + di in red "Uncorrect test option." + error 198 + exit +} + +if "`genfit'"!="" { + local nbwordgenfit:word count `genfit' + if `nbwordgenfit'!=2 { + di in red "Uncorrect genfit option." + di in red "This option must contain exactly two words" + error 198 + exit + } +} + + +if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!=""|"`genres'"!="" { + capture confirm new variable `genfit' `genscore' `genres' + if "`genfit'"!="" { + local o:word 1 of `genfit' + forvalues i=1/`nbitems' { + confirm new variable `o'``i'' + } + } + if "`genlt'"!="" { + local 0 `genlt' + gettoken left 0: 0,parse(",") + gettoken right 0: 0,parse(",") + local genlt `left' + local replacegenlt `0' + local length=length("`replacegenlt'") + if `length'>=3&substr("`replacegenlt'",1,`length')==substr("replace",1,`length') { + local replacegenlt replace + } + if "`replacegenlt'"!="replace"&"`replacegenlt'"!="" { + di "Not allowed option in the {hi:genlt} option" + error 198 + } + else if "`replacegenlt'"=="" { + confirm new variable `genlt' + } + } +} + +preserve + +tempfile saveraschtest +qui save `saveraschtest' +qui keep if `touse'==1 + +if "`autogroup'"!=""&"`group'"!="" { + di in green "The autogroup and the group options cannot be defined in the same time" + di in green "Only the group option is retained." + local autogroup +} + +if "`autogroup'"!="" { + tempvar autoscore + qui genscore `varlist',score(`autoscore') + + tempname matscore tmp + matrix `matscore'=J(`=`nbitems'-1',3,0) + forvalues i=1/`=`nbitems'-1' { + matrix `matscore'[`i',1]=`i' + matrix `matscore'[`i',2]=`i' + qui count if `autoscore'==`i' + matrix `matscore'[`i',3]=r(N) + } + local stop=0 + local j=0 + while `j'<=`=`nbitems'-3'&`stop'!=1 { + local j=`j'+1 + local scoretogroup=99999999 + local rowtogroup1=0 + local rowtogroup2=0 + local stop=1 + forvalues i=1/`=`nbitems'-`j'' { + if `matscore'[`i',1]>=0 & `matscore'[`i',3]<30 & `matscore'[`i',3]<`scoretogroup' { + local scoretogroup=`matscore'[`i',3] + local rowtogroup1=`i' + local stop=0 + } + } + if `stop'!=1 { + if `rowtogroup1'>1&`rowtogroup1'<`=`nbitems'-`j'' { + if `matscore'[`=`rowtogroup1'-1',1]<`matscore'[`=`rowtogroup1'+1',1] { + local rowtogroup2=`rowtogroup1' + local rowtogroup1=`rowtogroup1'-1 + } + else { + local rowtogroup2=`rowtogroup1'+1 + } + } + else if `rowtogroup1'==1 { + local rowtogroup2=2 + } + else if `rowtogroup1'==`=`nbitems'-`j'' { + local rowtogroup2=`nbitems'-`j' + local rowtogroup1=`nbitems'-`j'-1 + } + matrix `tmp'=`matscore' + matrix `matscore'=J(`=`nbitems'-`j'',3,0) + if `rowtogroup1'!=1 { + matrix `matscore'[1,1]=`tmp'[1..`=`rowtogroup1'-1',1..3] + } + matrix `matscore'[`rowtogroup1',1]=`tmp'[`rowtogroup1',1] + matrix `matscore'[`rowtogroup1',2]=`tmp'[`rowtogroup2',2] + matrix `matscore'[`rowtogroup1',3]=`tmp'[`rowtogroup1',3]+`tmp'[`rowtogroup2',3] + if `rowtogroup2'!=`=`nbitems'-`j'' { + matrix `matscore'[`rowtogroup2',1]=`tmp'[`=`rowtogroup2'+1'..`=`nbitems'-`j'',1..3] + } + } + } + local nbrows=rowsof(`matscore')-1 + local thresholds + forvalues i=1/`nbrows' { + local tmp=`matscore'[`i',2] + local thresholds `thresholds' `tmp' + } + local group `thresholds' +} + + +if "`group'"=="" { + forvalues i=1/`=`nbitems'-1' { + local group "`group' `i'" + } +} +local nbgroups:word count `group' +local groupmax:word `nbgroups' of `group' +if `groupmax'>=`nbitems' { + di in red "You cannot form a group with the higher possible score." + di in red "The higher possible value of the group option is `=`nbitems'-1'." + di in red "Please correct your group option." + error 198 + exit +} +else { + if `groupmax'!=`=`nbitems'-1' { + local group "`group' `=`nbitems'-1'" + local nbgroups=`nbgroups'+1 + } +} +local nbgroups=`nbgroups'+1 + +if "`dirsave'"!=""&"`filessave'"=="" { + di in ye "If you want to save yours graphs, use the filessave option" +} +if "`filessave'"!="" { + if "`dirsave'"=="" { + local dirsave "`c(pwd)'" + } + di in ye "The graphs files will be saved in `dirsave'" +} +if "`dirsave'"!="" { + if "`filesave'"=="" { + local filesave "filesave" + } +} +if "`extension'"!=""&"`extension'"!="png"&"`extension'"!="eps"&"`extension'"!="ps"&"`extension'"!="svg"&"`extension'"!="wmf"&"`extension'"!="png"&"`extension'"!="emf"&"`extension'"!="pdf"&"`extension'"!="tif" { + di in red "The {hi:extension} option can not contain the value `extension'. Please correct it." + error 198 + exit +} +if "`pause'"!=""&"`draw'"=="" { + pause on +} + +if "`difficulties'"!="" { + capture confirm matrix `difficulties' + if _rc!=0 { + di in red "The vector `difficulties' defined in the {hi:difficulties} option does not exist." + error 198 + exit + } +} + +if "`difficulties'"!=""&"`method'"!="mml" { + di in red "The {hi:difficulties} option can be defined only for MML method." + error 198 + exit +} + +if "`covariables'"!=""&"`method'"!="mml" { + di in red "The {hi:covariables} option can be defined only for MML method." + error 198 + exit +} +if "`covariables'"!=""&"`comp'"!="" { + di in red "The {hi:covariables} and {hi:comp} options can be defined jointly." + error 198 + exit +} + + + + + +/*********************************************************************************************************** +POSSIBLE TEST +***********************************************************************************************************/ + +if ("`icc'"!=""|"`fitgraph'"!=""|"`splittest'"!=""|"`details'"!="")&"`test'"=="NONE" { + di in green "You cannot use the {hi:details}, {hi:icc}, {hi:fitgraph} or {hi:splittest} options if you use {hi:test(none)}." + di in green "These options are ignored." + local details + local icc + local fitgraph + local splittest +} +if "`comp'"!=""&"`method'"=="cml" { + di in green "You cannot compare two populations ({hi:comp} option) with the CML estimation method" + di in green "This option is ignored." + local comp +} +if "`method'"!="cml"&"`test'"=="WP" { + di in green "The Wright-Panchapakesan test is not authorized with MML or GEE." + di in green "The WP tests are replaced by Van den Wollenberg Q tests." + local test Q +} +if "`method'"=="gee"&"`ld'"!="" { + di in green "You cannot use the {hi:nold} option with the GEE method of estimation" + di in green "This option is ignored." + local ld +} + + +if "`test'"==""|"`test'"=="R" { + local test "R" + if "`method'"=="cml" { + local namewp "R1c" + local descwp "R1c test" + } + else { + local namewp="R1m" + local descwp "R1m test" + } +} +if `nbitems'>999999|"`test'"=="WP" { + local namewp " Y" + local descwp "Wright-Panchapakesan Y test" + local q2 +} + else if "`test'"=="Q" { + local namewp " Q1" + local descwp "Van den Wollenberg Q1 test" +} + +if "`method'"!="cml"&"`meandiff'"!="" { + di in green "The {hi:meandiff} option is not available with MML or GEE." + di in green "This option is ignored." + local meandiff +} + +if "`method'"!="cml"&"`splittests'"!="" { + di in green "The {hi:splittests} option is not available with MML or GEE." + di in green "This option is ignored." + local splittests +} +if "`method'"!="cml"&"`dif'"!="" { + di in green "The {hi:dif} option is not available with MML or GEE." + di in green "This option is ignored." + local dif +} + +/*********************************************************************************************************** +SCORES AND GROUPS +************************************************************************************************************/ + +qui count if `touse'==1 +local N=r(N) + +qui keep `varlist' `comp' `covariables' `id' `touse' + +tempname rep item +tempvar score realscore +qui genscore `varlist',score(`score') +qui count if `score'==.&`touse'==1 +local nbindmiss=r(N) + +if "`ld'"=="" { + qui drop if `score'==. +} +forvalues i=1/`nbitems' { + rename ``i'' `rep'`i' +} + + + +local liminf0=0 +local limsup0=0 +local liminf`nbgroups'=`nbitems' +local limsup`nbgroups'=`nbitems' + + +local recode +forvalues i=1/`=`nbgroups'-1' { + if `i'!= 1{ + local liminf`i' : word `=`i'-1' of `group' + } + else { + local liminf1=0 + } + local liminf`i'=`liminf`i''+1 + local limsup`i':word `i' of `group' + + local recode "`recode' `liminf`i''/`limsup`i''=`i'" +} +qui gen `realscore'=`score' +qui recode `score' `recode' `nbitems'=`nbgroups' + +local smallgroup=0 + +forvalues i=0/`nbgroups' { + qui count if `score'==`i' + local effscore`i'=r(N) + if `i'!=0&`i'!=`nbgroups'&`effscore`i''<30 { + local smallgroup=1 + } +} +/*********************************************************************************************************** +ESTIMATION OF THE DIFFICULTY PARAMETERS +************************************************************************************************************/ +if "`trace'"!="" { + di in green "*** Estimation of the difficulty parameters" +} + + +if "`covariables'"!=""&"`difficulties'"=="" { + forvalues i=1/`nbcovariables' { + qui su `covariable`i'' + local mean`covariable`i''=r(mean) + qui replace `covariable`i''=`covariable`i''-`mean`covariable`i''' + } +} + +tempname ll coef var beta Vbeta est + +if "`method'"=="gee" { + qui geekel2d `rep'1-`rep'`nbitems',ll + local nbobserv=r(N) + + if `r(error)'==1 { + di "The variance of the latent trait probably is too high to made the GEE a efficient method to estimate the parameters." + error 499 + exit + } + scalar `ll'=r(ll) + local nbind=r(N) + matrix `coef'=r(b) + matrix `est'=`coef' + matrix `est'[1,`=`nbitems'+1']=sqrt(`est'[1,`=`nbitems'+1']) + matrix `var'=r(V) + matrix `beta'=`coef'[1,1..`nbitems'] + matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems'] + local sig=sqrt(`coef'[1,`=`nbitems'+1']) + local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])/sqrt(`nbind')/(`sig'*2) +} + +qui reshape long `rep', i(`id') j(`item') + +tempvar diff tl +gen `diff'=0 + +forvalues i=1/`nbitems' { + qui gen `rep'`i'=`item'==`i' + qui replace `rep'`i'=-`rep'`i' +} + + +if "`method'"=="mml" { + if "`difficulties'"==""{ + qui xtlogit `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') nocons iterate(`iterate') + matrix `est'=e(b) + matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`est'[1,`=`nbitems'+`nbcovariables'+1']/2) + } + else { + tempname offset b + qui gen `offset'=0 + forvalues i=1/`nbitems' { + qui replace `offset'=-(`difficulties'[1,`i']) if `item'==`i' + } + qui gllamm `rep' `covariables' , offset(`offset') i(`id') nocons iterate(`iterate') link(logit) fam(bin) + matrix `b'=e(b) + matrix `est'=`difficulties',`b' + matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`b'[1,`=`nbcovariables'+1']/2) + } +} +else if "`method'"=="cml" { + qui clogit `rep' `rep'1-`rep'`=`nbitems'-1' , group(`id') +} + + +if "`method'"!="gee" { + if "`difficulties'"=="" { + matrix `coef'=e(b) + matrix `var'=e(V) + } + else { + matrix `coef'=`difficulties' + matrix `var'=J(`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1',.) + matrix `var'[`=`nbitems'+1',`=`nbitems'+1']=e(V) + } + scalar `ll'=e(ll) + local nbind=e(N)/`nbitems' + local nbobserv=e(N) + *di "nombre d'obs:`nbobserv'" + + if "`meandiff'"!="" { + matrix `var'=J(`nbitems',`nbitems',.) + matrix `coef'=J(1,`nbitems',.) + local param + local lin `rep'1 + forvalues j=2/`=`nbitems'-1' { + local lin `lin'+`rep'`j' + } + local lin (`lin')/`nbitems' + + forvalues j=1/`=`nbitems'-1' { + qui lincom `rep'`j'-`lin' + matrix `coef'[1,`j']=`r(estimate)' + matrix `var'[`j',`j']=`r(se)'^2 + } + qui lincom -`lin' + matrix `coef'[1,`nbitems']=`r(estimate)' + matrix `var'[`nbitems',`nbitems']=`r(se)'^2 + } + if "`method'"=="mml" { + local sig=e(sigma_u) + local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2 + tempname betacov Vbetacov + if "`difficulties'"=="" { + matrix `beta'=`coef'[1,1..`nbitems'] + matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems'] + if "`covariables'"!="" { + matrix `betacov'=`coef'[1,`=`nbitems'+1'..`=`nbitems'+`nbcovariables''] + matrix `Vbetacov'=`var'[`=`nbitems'+1'..`=`nbitems'+`nbcovariables'',`=`nbitems'+1'..`=`nbitems'+`nbcovariables''] + } + local sig=e(sigma_u) + local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2 + } + else { + tempname tmp + matrix `tmp'=e(b) + matrix `beta'=`difficulties' + if "`covariables'"!="" { + matrix `betacov'=`tmp'[1,1..`nbcovariables'] + } + local sig=`tmp'[1,`=`nbcovariables'+1'] + matrix `tmp'=e(V) + local sesig=sqrt(`tmp'[`=`nbcovariables'+1',`=`nbcovariables'+1']) + matrix `Vbeta'=J(`nbitems',`nbitems',.) + if "`covariables'"!="" { + matrix `Vbetacov'=`tmp'[1..`nbcovariables',1..`nbcovariables'] + } + } + } + else if "`method'"=="cml"&"`meandiff'"==""{ + matrix `beta'=`coef'[1,1..`=`nbitems'-1'] + matrix `Vbeta'=`var'[1..`=`nbitems'-1',1..`=`nbitems'-1'] + } + else if "`method'"=="cml"&"`meandiff'"!=""{ + matrix `beta'=`coef' + matrix `Vbeta'=`var' + } +} + +if ("`method'"=="mml"|"`method'"=="gee") { + local colnames + forvalues i=1/`nbitems' { + local colnames "`colnames' `rep':`rep'`i'" + } + forvalues i=1/`nbcovariables'{ + local tmp:word `i' of `covariables' + local colnames "`colnames' `rep':`tmp'" + } + local id2=substr("`id'",1,4) + local colnames "`colnames' `id2'1:_cons" + matrix colnames `est'=`colnames' + + qui gllamm `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') allc nocons family(binom) link(logit) trace from(`est') eval + tempname u + qui gllapred `u',u fsample + + forvalues i=1/`nbcovariables' { + local tmp:word `i' of `covariables' + qui replace `u'm1=`u'm1+`betacov'[1,`i']*(`tmp')/*+`mean`covariable`i''')*/ + } + tempname theta sdtheta + matrix `theta'=J(1,`=`nbitems'+1',0) + matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',0) + qui su `u'm1 if `rep'1==-1 + local vartheta=r(Var) + qui gen `u's2=`u's1^2 + qui su `u's2 if `rep'1==-1 + local meanse2=r(mean) + local psi=1-`meanse2'/(`meanse2'+`vartheta') + forvalues s=0/`nbitems' { + qui su `u'm1 if `realscore'==`s' + local theta`s'=r(mean) + qui su `u's1 if `realscore'==`s' + local sdtheta`s'=r(mean) + matrix `theta'[1,`=`s'+1']=`theta`s'' + matrix `sdtheta'[`=`s'+1',`=`s'+1']=`sdtheta`s'' + } + if "`genlt'"!="" { + tempfile ltsave ltsavetmp + qui save `ltsavetmp', replace + qui keep if `rep'1==-1 + qui keep `u'm1 `u's1 `id' + qui sort `id' + qui save `ltsave' + qui use `ltsavetmp' + } +} + +forvalues i=1/`nbitems' { + if `i'==`nbitems'&"`method'"=="cml"&"`meandiff'"=="" { + local beta`i'=0 + local sd`i' . + local fixed`i' "*" + } + else { + local beta`i'=`coef'[1,`i'] + local sd`i'=sqrt(`var'[`i',`i']) + } + qui replace `diff'=-`beta`i'' if `item'==`i' +} + +/*********************************************************************************************************** +COMPARISON OF TWO POPULATIONS +***********************************************************************************************************/ + +if "`comp'"!=""&"`method'"!="cml" { + if "`trace'"!="" { + di in green "*** Test of comparison of two populations" + } + qui inspect `comp' + local unique=r(N_unique) + if `unique'== 2 { + qui su `comp' + local mincomp=r(min) + local maxcomp=r(max) + tempname bmin bmax + qui xtlogit `rep' if `comp'==`mincomp',offset(`diff') i(`id') + matrix `bmin'=e(b) + local meanmin=`bmin'[1,1] + local varmin=e(sigma_u)^2 + local llmin=e(ll) + local Nmin=e(N_g) + qui xtlogit `rep' if `comp'==`maxcomp',offset(`diff') i(`id') + matrix `bmax'=e(b) + local meanmax=`bmax'[1,1] + local varmax=e(sigma_u)^2 + local llmax=e(ll) + local Nmax=e(N_g) + local Zcomp=(`meanmin'-`meanmax')/sqrt(`varmin'/`Nmin'+`varmax'/`Nmax') + local pvalue=1-norm(abs(`Zcomp')) + } + else { + di "It is impossible to compare more than two populations" + di "The comparison process is not run" + local comp + } +} + +/*********************************************************************************************************** +ESTIMATION OF THE ABILITY PARAMETERS / CML +************************************************************************************************************/ +if `nbitems'>=2 { + if "`trace'"!="" { + di in green "*** Estimation of the ability parameters" + } + if "`method'"=="cml" { + tempfile verytmp + qui save `verytmp',replace + drop _all + qui set obs 20001 + qui gen theta=(_n-10001)/1000 + qui gen A=1 + forvalues j=1/`nbitems' { + qui gen u`j'=exp(theta-`beta`j'') + qui gen p`j'=u`j'/(1+u`j') + qui gen a`j'=1/u`j' + qui replace A=A*a`j' + qui gen i`j'=u`j'/(1+u`j')^2 + qui gen j`j'=(u`j'*(1-u`j'))/(1+u`j')^3 + } + qui egen P=rsum(p*) + qui egen I=rsum(i*) + qui egen J=rsum(j*) + qui gen V=1/I^2*(I+J^2)/(4*I^2) + qui gen V2=1/I + tempname theta sdtheta + matrix `theta'=J(1,`=`nbitems'+1',0) + matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',.) + forvalues s=0/`nbitems' { + qui gen f`s'=abs(`s'-P+.5*J/I) + qui sort f`s' + matrix `theta'[1,`=`s'+1']=theta[1] + matrix `sdtheta'[`=`s'+1',`=`s'+1']=sqrt(V2[1]) + } + use "`verytmp'",replace + } + qui gen `tl'=0 + forvalues s=0/`nbitems' { + local theta`s'=`theta'[1,`=`s'+1'] + qui replace `tl'=`theta`s'' if `realscore'==`s' + local sdtheta`s'=`sdtheta'[`=`s'+1',`= `s'+1'] + } + tempname pred + qui gen `pred'=log(exp(`rep'*(`tl'+`diff'))/(1+exp(`tl'+`diff'))) + + qui su `pred' + local globalll=r(sum) + + local nulscore=0 + forvalues i=1/`=`nbgroups'-1' { + qui count if `score'==`i'&`item'==1 + local nbscore`i'=r(N) + if `nbscore`i''==0 { + local nulscore=1 + } + } + if `nulscore' { + di in green "{p}At least one group of scores concerns none individuals. Tests will be not computed.{p_end}" + di in green "{p}Use the {hi:group} or the {hi:autogroup} options.{p_end}" + local test "NONE" + local details + local icc + local fitgraph + local splittest + } + forvalues i=0/`nbitems' { + qui count if `realscore'==`i'&`item'==1 + local nbrealscore`i'=r(N) + } +} + +/*********************************************************************************************************** +TESTS OF THE FIRST ORDER +************************************************************************************************************/ + +tempname Pi +matrix define `Pi'=J(`nbitems',`=`nbitems'-1',0) +if "`test'"!="NONE" { + qui drop if `score'==. + if "`trace'"!="" { + di in green "*** Tests of the first order" + } + tempname Obs Obs2 Th Th2 + + matrix define `Obs'=J(`nbitems',`=`nbitems'-1',0) + matrix define `Obs2'=J(`nbitems',`=`nbgroups'-1',0) + matrix define `Th'=J(`nbitems',`=`nbitems'-1',0) + matrix define `Th2'=J(`nbitems',`=`nbgroups'-1',0) + local listofitemsc + + /* Estimation of the gamma symetrical functions*/ + local c0 "1" + local c`nbitems' "`nbitems'*x" + forvalues j=1/`nbitems' { + local listini`j' + local listofitemsc "`listofitemsc' `beta`j''" + local c0 `c0'*(1+exp(x-`beta`j'')) + local c`nbitems' `c`nbitems''-`beta`j'' + forvalues k=1/`nbitems' { + local listini`j'k`k' + if `k'!=`j' { + local listini`j' "`listini`j'' `beta`k''" + } + forvalues l=1/`nbitems' { + if `l'!=`j'&`l'!=`k' { + local listini`j'k`k' "`listini`j'k`k'' `beta`l''" + } + } + } + } + + gammasym `listofitemsc' + + /*Estimation, for each value of the score s of the probability to respond to each item (Pi) and of the theorical number of positive responses (Ths) and of theorical number of positive respond per item pair (Ws)*/ + forvalues s=1/`nbitems' { + local denom`s'=r(gamma`s') + tempname W`s' + matrix define `W`s''=J(`nbitems',`nbitems',0) + } + tempvar prob prob2 z y v z2 y2 v2 c r q e + qui gen `prob'=. + qui gen `prob2'=. + forvalues j=1/`nbitems' { + forvalues s=1/`=`nbitems'-1' { + qui count if `rep'==1&`item'==`j'&`realscore'==`s' + matrix `Obs'[`j',`s']=r(N) + if "`test'"!="WP" { + gammasym `listini`j'' + local num`j'=r(gamma`=`s'-1') + if "`method'"=="cml"|"`test'"=="Q" { + matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s'' + } + else { + gausshermite exp(`s'*x)/(`c0'), sigma(`sig') + local int`s'=r(int) + if "`test'"=="R"&`nbrealscore`s''!=0{ + local tmp=exp(-`beta`j'')*`num`j''*`int`s''*`nbind'/`nbrealscore`s'' + matrix `Pi'[`j',`s']=`tmp' + } + else if `nbrealscore`s''==0 { + matrix `Pi'[`j',`s']=0 + } + } + if "`test'"=="R" { + forvalues k=`=`j'+1'/`nbitems' { + if `s'>=2 { + gammasym `listini`j'k`k'' + local num`j'k`k'=r(gamma`=`s'-2') + if "`method'"=="cml" { + matrix `W`s''[`j',`k']=`nbrealscore`s''*exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''/`denom`s'' + } + else { + matrix `W`s''[`j',`k']=exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''*`int`s''*`nbind' + } + matrix `W`s''[`k',`j']=`W`s''[`j',`k'] + } + } + } + } + else if "`test'"=="WP" { + matrix `Pi'[`j',`s']=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) + } + matrix `Th'[`j',`s']=`Pi'[`j',`s']*`nbrealscore`s'' + qui replace `prob'=`Pi'[`j',`s'] if `realscore'==`s'&`item'==`j' + qui replace `prob2'=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) if `realscore'==`s'&`item'==`j' + matrix `W`s''[`j',`j']=`nbrealscore`s''*`Pi'[`j',`s'] + if "`test'"!="R" { + matrix `W`s''[`j',`j']=`W`s''[`j',`j']*abs(1-`Pi'[`j',`s']) + } + } + } + qui gen `v2'=abs(`prob'*(1-`prob')) + qui gen `z2'=(`rep'-`prob')^2 + qui gen `y2'=`z2'/`v2' + qui gen `c'=abs(`prob'*(1-`prob')*(`prob'^3+(1-`prob')^3)) + qui gen `r'=`c'/(`v2')^2 + qui gen `e'=`c'-(`v2')^2 + + forvalues j=1/`nbitems' { + qui su `y2' if `item'==`j' + local outfit`j'=r(mean) + qui su `r' if `item'==`j' + local Voutfit`j'=r(sum) + local Voutfit`j'=`Voutfit`j''/(`nbind')^2-1/`nbind' + local outfitstd`j'=(`outfit`j''^(1/3)-1)*(3/sqrt(`Voutfit`j''))-sqrt(`Voutfit`j'')/3 + + qui su `z2' if `item'==`j' + local n=r(sum) + qui su `v2' if `item'==`j' + local d=r(sum) + local infit`j'=`n'/`d' + qui su `e' if `item'==`j' + local sume=r(sum) + local Vinfit`j'=`sume'/(`d')^2 + local infitstd`j'=(`infit`j''^(1/3)-1)*(3/sqrt(`Vinfit`j''))-sqrt(`Vinfit`j'')/3 + } + tempname tmp stattest testitems + + /*Estimation, by scores group g, of the theorical number of positive response (Th2g) and of the positive respond to each items pair (W2g)*/ + scalar `stattest'=0 + forvalues g=1/`=`nbgroups'-1' { + tempname W2`g' d2`g' + matrix define `W2`g''=J(`nbitems',`nbitems',0) + forvalues s=`liminf`g''/`limsup`g'' { + forvalues j=1/`nbitems' { + matrix `Obs2'[`j',`g']=`Obs2'[`j',`g']+`Obs'[`j',`s'] + matrix `Th2'[`j',`g']=`Th2'[`j',`g']+`Th'[`j',`s'] + if "`test'"=="R" { + forvalues k=`=`j'+1'/`nbitems' { + matrix `W2`g''[`j',`k']=`W2`g''[`j',`k']+`W`s''[`j',`k'] + matrix `W2`g''[`k',`j']=`W2`g''[`j',`k'] + } + } + matrix `W2`g''[`j',`j']=`W2`g''[`j',`j']+`W`s''[`j',`j'] + } + } + + /*Estimation of the d2g vectors*/ + matrix `d2`g''=`Obs2'[1..`nbitems',`g']-`Th2'[1..`nbitems',`g'] + + /*Estimation of the influences on the test of each item (testitemsg matrix) and of the test statistic (stattest)*/ + tempname test`g' testitems`g' + matrix `test`g''=`d2`g'''*syminv(`W2`g'')*`d2`g'' + capture matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g'' + if _rc!=0 { + matrix `tmp'=J(`nbitems',`nbitems',0) + forvalues j=1/`nbitems' { + matrix `tmp'[`j',`j']=`W2`g''[`j',`j'] + } + di in green "Group `g' (`liminf`g''/`limsup`g''): The weight matrix is not positive-definite, the diagonal matrix is used to estimate the contribution of the items on the `wpname' statistic" + matrix list `tmp' + matrix `testitems`g''=cholesky(syminv(`tmp'))*`d2`g'' + } + else { + matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g'' + } + scalar `stattest'=`stattest'+`test`g''[1,1] + } + matrix `testitems'=J(`nbitems',1,0) + forvalues j=1/`nbitems' { + forvalues g=1/`=`nbgroups'-1' { + matrix `testitems'[`j',1]=`testitems'[`j',1]+`testitems`g''[`j',1]^2 + } + } + + /*Adaptation for the Q1 statistic*/ + if "`test'"=="Q" { + scalar `stattest'=`stattest'*`=`nbitems'-1'/`nbitems' + } + + /*Correction for R1m and Q1m*/ + if ("`test'"=="R"|"`test'"=="Q")&("`method'"=="mml"|"`method'"=="gee") { + local c`nbitems' exp(`c`nbitems'')/(`c0') + local c0 1/(`c0') + gausshermite `c0', sigma(`sig') + local ci0=r(int)*`nbind' + gausshermite `c`nbitems'',sigma(`sig') + local ci`nbitems'=`nbind'*r(int) + scalar `stattest'=`stattest'+(`nbrealscore0'-`ci0')^2/`ci0'+(`nbrealscore`nbitems''-`ci`nbitems'')^2/`ci`nbitems'' + } + + + +/*********************************************************************************************************** +TESTS U +************************************************************************************************************/ + + if "`method'"=="cml" { + if "`trace'"!="" { + di in green "*** Tests U" + } + + local quartile=`nbind'/4 + local c1=0 + local n1=0 + while `n1'<`quartile' { + local c1=`c1'+1 + local n1=`n1'+`nbrealscore`c1'' + } + local c2=`nbitems' + local n2=0 + while `n2'<`quartile' { + local c2=`c2'-1 + local n2=`n2'+`nbrealscore`c2'' + } + forvalues j=1/`nbitems' { + local zu1=0 + local zu2=0 + forvalues s=1/`c1' { + local zu1=`zu1'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s'])) + } + forvalues s=`c2'/`=`nbitems'-1' { + local zu2=`zu2'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s'])) + } + local U`j'=(`zu1'-`zu2')/sqrt(`c1'+`nbitems'-`c2') + } + } + + + +/*********************************************************************************************************** +TESTS OF THE SECOND ORDER /*undocumented in beta test*/ +************************************************************************************************************/ + + if "`q2'"!="" { + if "`trace'"!="" { + di in green "*** Tests of the second order" + } + + tempfile Q2file + qui save "`Q2file'",replace + qui use "`saveraschtest'",replace + + qui keep if `touse'==1 + gen `score'=0 + + forvalues i=1/`nbitems' { + local Q2i`i' + rename ``i'' `rep'`i' + qui replace `score'=`score'+`rep'`i' + } + qui recode `score' `recode' + + forvalues i=1/`nbitems' { + local Q2i`i'=0 + forvalues j=`=`i'+1'/`nbitems' { + local listinci`i'j`j' + forvalues k=1/`nbitems' { + if `k'!=`i'&`k'!=`j' { + local listinci`i'j`j' "`listinci`i'j`j'' `beta`k''" + } + } + } + } + + local Q2tot=0 + forvalues k=2/`=`nbitems'-1' { + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + if `k'==1 { + local num=0 + } + else { + gammasym `listinci`i'j`j'' + local num=r(gamma`=`k'-2') + } + local athi`i'j`j'k`k'=exp(-`beta`i'')*exp(-`beta`j'')*`num'/`denom`k'' + local bthi`i'j`j'k`k'=`nbth`i's`k''-`athi`i'j`j'k`k'' + local cthi`i'j`j'k`k'=`nbth`j's`k''-`athi`i'j`j'k`k'' + local dthi`i'j`j'k`k'=1-`athi`i'j`j'k`k''-`bthi`i'j`j'k`k''-`cthi`i'j`j'k`k'' + } + } + } + forvalues k=1/`=`nbgroups'-1' { + local Q2`k'=0 + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`j'+1'/`nbitems' { + qui count if `rep'`i'==1&`rep'`j'==1&`score'==`k' + local aempi`i'j`j'k`k'=r(N) + local ath2i`i'j`j'k`k'=0 + local bth2i`i'j`j'k`k'=0 + local cth2i`i'j`j'k`k'=0 + local dth2i`i'j`j'k`k'=0 + } + } + if `limsup`k''!=1 { + forvalues l=`liminf`k''/`limsup`k'' { + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + if `l'!=1 { + local ath2i`i'j`j'k`k'=`ath2i`i'j`j'k`k''+`athi`i'j`j'k`l''*`nbrealscore`l'' + local bth2i`i'j`j'k`k'=`bth2i`i'j`j'k`k''+`bthi`i'j`j'k`l''*`nbrealscore`l'' + local cth2i`i'j`j'k`k'=`cth2i`i'j`j'k`k''+`cthi`i'j`j'k`l''*`nbrealscore`l'' + local dth2i`i'j`j'k`k'=`dth2i`i'j`j'k`k''+`dthi`i'j`j'k`l''*`nbrealscore`l'' + } + } + } + } + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + local d2i`i'j`j'k`k'=(`aempi`i'j`j'k`k''-`ath2i`i'j`j'k`k'')^2 + local Q2i`i'j`j'k`k'=`d2i`i'j`j'k`k''/`ath2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`bth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`cth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`dth2i`i'j`j'k`k'' + local Q2i`i'=`Q2i`i''+`Q2i`i'j`j'k`k'' + local Q2i`j'=`Q2i`j''+`Q2i`i'j`j'k`k'' + local Q2`k'=`Q2`k''+`Q2i`i'j`j'k`k'' + } + } + } + local Q2tot=`Q2tot'+`Q2`k'' + } + forvalues i=1/`nbitems' { + di in green "Item ``i'' : Q2 = `Q2i`i''" + } + local Q2=`Q2tot'*(`nbitems'-3)/(`nbitems'-1) + di in green "Q2 = `Q2tot'" + qui use "`Q2file'",replace + } + +/*********************************************************************************************************** +TEST LR Z +************************************************************************************************************/ + + if "`method'"=="cml" { + if "`trace'"!="" { + di in green "*** Tests LR of Andersen" + } + local ssll=0 + tempfile Zfile + qui save "`Zfile'", replace + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + gen `score'=0 + forvalues j=1/`nbitems' { + qui replace `score'=`score'+``j'' + } + qui recode `score' `recode' `nbitems'=`nbgroups' + forvalues i=1/`=`nbgroups'-1' { + if `effscore`i''>0 { + qui raschtestv7 `varlist' if `score'==`i', test(NONE) `ld' id(`id') + local ll`i'=r(cll) + local ssll=`ssll'+(`ll`i'') + } + } + local Z=2*`ssll'-2*`ll' + use "`Zfile'",replace + tempname AndersenZ + matrix define `AndersenZ'=(`Z',`=(`nbgroups'-2)*(`nbitems'-1)',1-chi2(`=(`nbitems'-1)*(`nbgroups'-2)',`Z')) + } +} + + +/*********************************************************************************************************** +DISPLAYING RESULTS WITH TESTS +************************************************************************************************************/ +if "`html'" != "" { + di "" +} + +if "`test'"!="NONE" { + local conttest= "_c" +} +di +tempname itemfit globalfit +matrix `globalfit'=J(1,3,0) +if "`method'"=="cml" { + if "`html'" == "" { + di in green "Estimation method: " in yellow "Conditional maximum likelihood (CML)" + } + else { + di "

Estimation method: Conditional maximum likelihood (CML)

" + } + local nbtest=`nbgroups'-1 + local line=77 +} +else if "`method'"=="mml"{ + if "`html'" == "" { + di in green "Estimation method: " in yellow "Marginal maximum likelihood (MML)" + } + else { + di "

Estimation method: Marginal maximum likelihood (MML)

" + } + local nbtest=`nbgroups'+1 + local line=70 +} +else if "`method'"=="gee" { + di in green "Estimation method: " in yellow "Generalized Estimating Equations (GEE)" + local nbtest=`nbgroups'+1 + local line=70 +} +if "`test'"=="NONE" { + local line=35 +} + +if "`html'" == "" { + di in green "Number of items: " in yellow `nbitems' + di in green "Number of groups: " in yellow `=`nbgroups'+1' `conttest' + if "`test'"!="NONE" { + di in green " (" in yellow "`nbtest'" in green " of them are used to compute the statistics of test)" + } +} +else { + di "Number of items: " `nbitems' "
" + di "Number of groups: " `=`nbgroups'+1' `conttest' + if "`test'"!="NONE" { + di " (`nbtest' of them are used to compute the statistics of test)" + } + di "
" +} +if "`method'"=="cml" { + local nbind=`nbind'+`effscore0'+`effscore`nbgroups'' + local cont "_c" + matrix `itemfit'=J(`nbitems',6,0) +} +else { + local cont + matrix `itemfit'=J(`nbitems',5,0) +} +local missing=`N'-`nbind' +if "`html'" == "" { + di in green "Number of individuals: " in yellow `N' + di in green "Number of individuals with missing values: " in yellow `nbindmiss' _c + if "`ld'"=="" { + di in green " (removed)" + } + else { + di + } + di in green "Number of individuals with nul or perfect score: " in yellow `=`effscore0'+`effscore`nbgroups''' +} +else { + di "Number of individuals: `N'
" + di "Number of individuals with missing values: " `nbindmiss' + if "`ld'"=="" { + di " (removed)" + } + di "
" + di "Number of individuals with nul or perfect score: " `=`effscore0'+`effscore`nbgroups''' "
" +} +if "`method'"=="cml" { + if "`html'" == "" { + di in green "Conditional log-likelihood: " in yellow %-13.4f `ll' + di in green "Log-likelihood: " in yellow %-13.4f `globalll' + } +} +else { + if "`html'" == "" { + di in green "Marginal log-likelihood: " in yellow %-13.4f `ll' + di in green "Log-likelihood: " in yellow %-13.4f `globalll' + di + } + else { + di "Marginal log-likelihood: " %-13.4f `ll' "
" + di "Log-likelihood: " %-13.4f `globalll' "

" + } +} + +if "`html'" == "" { + noi di in green _col(16) "Difficulty" `conttest' + if "`test'"!="NONE"&"`stand'"=="" { + di in green _col(58) "Standardized" + } + if "`test'"!="NONE"&"`stand'"!="" { + di + } + noi di in green _col(9) "Items" _col(16) "parameters" _col(28) "std Err." `conttest' + if "`test'"!="NONE" { + local varin=int(2/sqrt(`nbind')*100)/100 + local varout=int(6/sqrt(`nbind')*100)/100 + di _col(41) "`namewp'" _col(47) "df" _col(50) "p-value" _col(58) "Outfit" _col(66) "Infit" `cont' + if "`method'"=="cml" { + di in green _col(77) "U" + } + } + di in green "{hline `line'}" +} +else { + di "" + di "" + di "" + if "`test'"!="NONE" { + di "" + } + di "" + di "" + if "`test'"!="NONE" { + local varin=int(2/sqrt(`nbind')*100)/100 + local varout=int(6/sqrt(`nbind')*100)/100 + di "" + if "`method'"=="cml" { + di "" + } + } + di "" +} + +forvalues i=1/`nbitems' { + if "`html'" == "" { + noi di in yellow _col(3) %12s abbrev("``i''`fixed`i''" ,12) in yellow _col(18) %8.5f `beta`i'' _col(29) %6.5f `sd`i'' `conttest' + } + else { + di "" + } + if "`test'"!="NONE" { + if "`html'" == "" { + if "`stand'"=="" { + di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfitstd`i'' _col(65) %6.3f `infitstd`i'' /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/ `cont' + } + else { + di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfit`i'' _col(65) %6.3f `infit`i'' /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/ `cont' + } + } + else { + if "`stand'"=="" { + di "" + } + else { + di "" + } + } + matrix `itemfit'[`i',1]=`testitems'[`i',1] + matrix `itemfit'[`i',2]=`=`nbgroups'-2' + matrix `itemfit'[`i',3]=1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) + if "`stand'"=="" { + matrix `itemfit'[`i',4]=`outfitstd`i'' + matrix `itemfit'[`i',5]=`infitstd`i'' + } + else { + matrix `itemfit'[`i',4]=`outfit`i'' + matrix `itemfit'[`i',5]=`infit`i'' + } + + if "`method'"=="cml" { + if "`html'" == "" { + di in ye _col(72) %6.3f `U`i'' + } + else { + di "" + } + matrix `itemfit'[`i',6]=`U`i'' + } + if "`html'" != "" { + di "" + } + } +} +if "`html'" == "" { + di in green "{hline `line'}" +} +else { + di "" +} +if "`test'"!="NONE" { + if "`method'"=="cml" { + local df=(`nbgroups'-2)*(`nbitems'-1) + } + else { + local df=(`nbgroups'-1)*(`nbitems'-1)-1 + } + matrix `globalfit'=(`stattest',`df',1-chi2(`df',`stattest')) + if "`html'" == "" { + noi di in green _col(6) "`descwp'" _col(32) in gr "`namewp'=" _col(36) in ye %8.3f `globalfit'[1,1] _col(46) %3.0f `globalfit'[1,2] _col(51) %6.4f `globalfit'[1,3] + if "`method'"=="cml" { + noi di in green _col(6) "Andersen LR test" _col(34) "Z=" in yellow _col(36) %8.3f `AndersenZ'[1,1] _col(46) %3.0f `AndersenZ'[1,2] _col(51) %6.4f `AndersenZ'[1,3] + } + di in green "{hline `line'}" + } + else { + di "" + if "`method'"=="cml" { + di "" + } + di "
DifficultyStandardized
Itemsparametersstd Err.`namewp'dfp-valueOutfitInfitU
" %12s abbrev("``i''`fixed`i''" ,12) "" %8.5f `beta`i'' "" %6.5f `sd`i'' "" %8.3f `testitems'[`i',1] "" %3.0f `=`nbgroups'-2' "" %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) "" %6.3f `outfitstd`i'' "" %6.3f `infitstd`i'' "" %8.3f `testitems'[`i',1] "" %3.0f `=`nbgroups'-2' "" %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) "" %6.3f `outfit`i'' "" %6.3f `infit`i'' "" %6.3f `U`i'' "
`descwp'`namewp'=" %8.3f `globalfit'[1,1] "" %3.0f `globalfit'[1,2] "" %6.4f `globalfit'[1,3] "
Andersen LR testZ=" %8.3f `AndersenZ'[1,1] "" %3.0f `AndersenZ'[1,2] "" %6.4f `AndersenZ'[1,3] "
" + } +} + +if "`html'" == "" { + if "`method'"=="cml"&"`meandiff'"==""{ + di in green "*: The difficulty parameter of this item had been fixed to 0" + } + if "`method'"=="cml"&"`meandiff'"!=""{ + di in green "The mean of the difficulty parameters is fixed to 0" + } + if `smallgroup'==1&"`test'"!="NONE" { + di in green "You have groups of scores with less than 30 individuals. The tests can be invalid." + } + if "`method'"!="cml"&"`test'"=="Q" { + di in green "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test." + } + + di +} +else { + if "`method'"=="cml"&"`meandiff'"==""{ + di "*: The difficulty parameter of this item had been fixed to 0
" + } + if "`method'"=="cml"&"`meandiff'"!=""{ + di "The mean of the difficulty parameters is fixed to 0
" + } + if `smallgroup'==1&"`test'"!="NONE" { + di "You have groups of scores with less than 30 individuals. The tests can be invalid.
" + } + if "`method'"!="cml"&"`test'"=="Q" { + di "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test.
" + } + di "

" +} + +if "`html'" == "" { + if "`method'"!="cml" { + di in green "{hline 56}" + noi di in green _col(5) "Parameters" _col(21) "Coef." _col(28) "std Err." _col(43) "z" _col(52) "P>|z|" + di in green "{hline 56}" + local zsig=`sig'/`sesig' + local pzsig=2*(1-norm(abs(`zsig'))) + di in green _col(10) in yellow "Sigma" _col(18) %8.5f `sig' _col(29) %6.5f `sesig' _col(38) %6.3f `zsig' _col(50) %7.4f `pzsig' + di in green "{hline 56}" + } +} +else { + if "`method'"!="cml" { + di "" + di "" + di "" + local zsig=`sig'/`sesig' + local pzsig=2*(1-norm(abs(`zsig'))) + di "
ParametersCoef.std Err.zP>|z|
Sigma" %8.5f `sig' "" %6.5f `sesig' "" %6.3f `zsig' "" %7.4f `pzsig' "
" + } +} + + + +*set trace on +if "`covariables'"!="" { + tempname zcovariates pcovariates + matrix `zcovariates'=J(1,`nbcovariables',0) + matrix `pcovariates'=J(1,`nbcovariables',0) + forvalues i=1/`nbcovariables' { + local tmp :word `i' of `covariables' + local zcov=`betacov'[1,`i']/`Vbetacov'[`i',`i']^.5 + local pzcov=2*(1-norm(abs(`zcov'))) + matrix `zcovariates'[1,`i']=`zcov' + matrix `pcovariates'[1,`i']=`pzcov' + di in green _col(3) %12s in yellow abbrev("`tmp'",12) _col(18) %8.5f `betacov'[1,`i'] _col(29) %6.5f `Vbetacov'[`i',`i']^.5 _col(38) %6.3f `zcov' _col(50) %7.4f `pzcov' + } + di in green "{hline 56}" + local difficulties2 + if "`difficulties'"!="" { + local difficulties2 diff(`difficulties') + } + if "`ss1'"!="" { + tempfile ss1save + qui save `ss1save' + qui use `saveraschtest' + qui keep if `touse'==1 + + qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2' + local sigma0=r(sigma) + local var0=`sigma0'^2 + local nbobs=r(N_obs) + *di "nbobs=`nbobs'" + local df0=`nbobs'-(`nbitems'+1)-1 + local ss10=`var0'*(`df0') + local ss1c0=0 + di + di in green "Type 1 Sum of Squares (sequential)" + di "{hline 85}" + di in green _col(44) "Degrees" _col(56) "Variance of the" _col(77) "Explained" + di in green _col(4) "Covariates" _col(25) "SS" _col(35) "Diff" _col(41) "of freedom"_col(59) "latent trait" _col(78) "Variance" + di "{hline 85}" + di _col(10) in green "None" _col(15) in ye %12.3f `ss10' _col(47) %4.0f `df0' _col(63) %8.3f `var0' + di in green "{dup 85:-}" + local covariablesss1 + forvalues i=1/`nbcovariables' { + local covariablesss1 `covariablesss1' `covariable`i'' + qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss1') test(none) `ld' `difficulties2' + local nbobs=r(N_obs) + local sigma`i'=r(sigma) + local var`i'=`sigma`i''^2 + local nbcovtmp:word count `covariablesss1' + *di " ss1`i'=`var`i''*`=`nbobs'-(`nbitems'+1+`nbcovtmp')-1'" + local df`i'=`nbobs'-(`nbitems'+1+`nbcovtmp')-1 + *di "local df`i'=`nbobs'-(`nbitems'+1+`nbcovtmp')-1 (cov:`covariablesss1')" + local ss1`i'=`var`i''*`df`i'' + *di "cov : `covariablesss1' var=`var`i'' df=`df`i''" + di _col(2) %12s in yellow abbrev("`covariable`i''",12) _col(15) %12.3f in ye `ss1`i'' _col(25) %12.3f `=`ss1`=`i'-1''-`ss1`i''' _col(47) %4.0f `df`i'' _col(63) %8.3f `var`i'' _col(81) %5.3f (`=`ss1`=`i'-1''-`ss1`i''')/`ss10' + } + di in green "{hline 85}" + qui use `ss1save' + } + if "`ss3'"!="" { + tempfile ss3save + qui save `ss3save' + qui use `saveraschtest' + qui keep if `touse'==1 + if "`ss1'"=="" { + qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2' + local sigma0=r(sigma) + local var0=`sigma0'^2 + local nbobs=e(N_obs) + local df0=`nbobs'-(`nbitems'+1)-1 + local ss30=`var0'*(`df0') + } + else { + local ss30=`ss10' + } + local ss3ref=`=`sig'^2*(`df0'-`nbcovariables')' + di + di in green "Type 3 Sum of Squares " + di "{hline 85}" + di in green _col(44) "Degrees" _col(56) "Variance of the" _col(77) "Explained" + di in green _col(4) "Covariates" _col(25) "SS" _col(35) "Diff" _col(41) "of freedom"_col(59) "latent trait" _col(78) "Variance" + di "{hline 85}" + di _col(10) in green "None" _col(15) in ye %12.3f `ss30' _col(47) %4.0f `df0' _col(63) %8.3f `var0' + di _col(6) in green "Complete" _col(15) in ye %12.3f `ss3ref' _col(25) %12.3f `=`ss30'-`ss3ref'' _col(47) %4.0f `=`df0'-`nbcovariables'' _col(63) %8.3f `sig'^2 _col(81) %5.3f 1-`sig'^2*(`df0'+`nbcovariables')/`ss30' + di in green "{dup 85:-}" + forvalues i=1/`nbcovariables' { + local covariablesss3 + forvalues j=1/`nbcovariables' { + if `i'!=`j' { + local covariablesss3 `covariablesss3' `covariable`j'' + } + } + qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss3') test(none) `ld' `difficulties2' + *ereturn list + local sigmas`i'=r(sigma) + local vars`i'=`sigmas`i''^2 + local nbobs=e(N) + local dfs`i'=`nbobs'-(`nbitems'+1)-1-(`nbcovariables'-1) + *di "local dfs`i'=`nbobs'-(`nbitems'+1)-1-(`nbcovariables'-1)" + local ss3s`i'=`vars`i''*`dfs`i'' + local vara`i'=`sig'^2 + local dfa`i'=`nbobs'-(`nbitems'+1)-1-`nbcovariables' + local ss3a`i'=`vara`i''*`dfa`i'' + *di "cov : `covariablesss3' var=`vars`i'' df=`dfs`i''" + di _col(2) %12s in green abbrev("`covariable`i''",12) _col(15) in ye %12.3f `ss3s`i'' _col(25) %12.3f in ye `=`ss3s`i''-`ss3a`i''' _col(47) %4.0f `=`df0'-`nbcovariables'+1' _col(63) %8.3f `vars`i'' _col(80) %6.3f (`=`ss3s`i''-`ss3a`i''')/`ss30' + } + di in green "{hline 85}" + qui use `ss3save' + } +} + + + +/*Tabular of the estimated values of the latent trait*/ + +if "`covariables'"=="" { + if "`html'" == "" { + di + di + noi di in green _col(33) "Ability" _col(60) "Expected" + noi di in green _col(17) "Group" _col(23) "Score" _col(30) "parameters" _col(42) "std Err." _col(54) "Freq." _col(63) "Score"_c + if "`method'"=="cml"&"`test'"!="NONE" { + noi di in green _col(75) "ll" + } + else { + noi di "" + } + if "`method'"=="cml"&"`test'"!="NONE" { + local line=62 + } + else { + local line=51 + } + di in green _col(17) "{hline `line'}" + } + else { + di "" + di "" + di "" + if "`method'"=="cml"&"`test'"!="NONE" { + di "" + } + di "" + } + + local nonul=0 + forvalues g=0/`nbgroups' { + if `g'!=0 { + if "`html'" == "" { + di in green _col(17) "{dup `line':-}" + } + } + forvalues s=`liminf`g''/`limsup`g'' { + if `s'==`liminf`g'' { + local tmp `ll`g'' + local gr `g' + } + else { + local tmp + local gr + } + local expscore`nonul'=0 + forvalues i=1/`nbitems' { + local expscore`nonul'=`expscore`nonul''+1/(1+exp(-`theta`nonul''+`beta`i'')) + } + if "`method'"=="cml" { + local format1 %8.3f + } + else { + local format1 %8.5f + } + if "`html'" == "" { + noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(32) `format1' `theta`nonul'' _col(42) `format1' `sdtheta`nonul'' _col(55) %4.0f `nbrealscore`s'' _col(64) % 4.2f `expscore`nonul'' _col(68) %11.4f `tmp' + } + else { + di "" + } + local nonul=`nonul'+1 + } + } + if "`html'" == "" { + di in green _col(17) "{hline `line'}" + } + else { + di "
GroupScoreAbility
parameters
std Err.Freq.Expected
Score
ll
" %5s "`gr'" "" %5s "`s'" "" `format1' `theta`nonul'' "" `format1' `sdtheta`nonul'' "" %4.0f `nbrealscore`s'' "" % 4.2f `expscore`nonul'' "" %11.4f `tmp' "
" + } +} + +if "`method'"=="mml"|"`method'"=="gee" { + if "`html'" == "" { + di + *di in green "Variance of the estimated latent trait" _col(45) in ye %10.4f `vartheta' + di in green "Mean variance of the error" _col(45) in ye %10.4f `meanse2' + local sig2=`sig'^2 + di in green "Estimated variance of the latent trait" _col(45) in ye %10.4f `sig2' + local psi2=1-`meanse2'/`sig2' + di in green "Personal Separation Index (PSI)" _col(45) in ye %10.4f `psi2' + di in green "Adjusted PSI on covariates (PSIadj)" _col(45) in ye %10.4f `psi' + } + else { + di "" + di "" + di "" + di "" + local sig2=`sig'^2 + di "" + local psi2=1-`meanse2'/`sig2' + di "" + di "" + di "
Mean variance of the error" %10.4f `meanse2' "
Estimated variance of the latent trait" %10.4f `sig2' "
Personal Separation Index (PSI)" %10.4f `psi2' "
Adjusted PSI on covariates (PSIadj)" %10.4f `psi' "
" + } +} + + +/*********************************************************************************************************** +DETAILS OPTION +************************************************************************************************************/ + +if "`details'"!="" { + if "`html'"=="" { + forvalues g=0/`nbgroups' { + if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" { + di + di in green "{hline 44}" + di in green "Group: " in ye "`g'" in green " from " in ye "`liminf`g''" in green " to " in ye "`limsup`g''" in green " (n=" in ye "`nbscore`g''" in green")" + di + di _col(3) "Item" _col(10) "Observed" _col(23) "Expected" _col(37) "Scaled" + di in green "{dup 44:-}" + } + if `g'!=0&`g'!=`nbgroups' { + forvalues j=1/`nbitems' { + local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j']) + di _col(3) in ye "``j''" _col(14) %4.0f `Obs2'[`j',`g'] _col(25) %6.2f `Th2'[`j',`g'] _col(36) %7.4f `tmp' + } + di in green "{dup 44:-}" + di in green "Contribution to the `namewp' statistics: " %8.4f in ye `test`g''[1,1] + } + else if "`method'"!="cml" { + if `g'==0 { + local h=0 + } + else { + local h=`nbitems' + } + local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'') + di in ye _col(14) %4.0f `nbrealscore`h'' _col(25) %6.2f `ci`h'' _col(36) %7.4f `tmp' + di in green "{dup 44:-}" + local tmp=`tmp'^2 + di in green "Contribution to the `namewp' statistics: " %8.4f in ye `tmp' + } + } + } + else { + forvalues g=0/`nbgroups' { + if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" { + di in gr "" + di in gr "" + di in gr "" + } + if `g'!=0&`g'!=`nbgroups' { + forvalues j=1/`nbitems' { + local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j']) + di "" + } + di "" + } + else if "`method'"!="cml" { + if `g'==0 { + local h=0 + } + else { + local h=`nbitems' + } + local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'') + di "" + local tmp=`tmp'^2 + di "" + } + di "
Group: `g' from `liminf`g'' to `limsup`g'' (n=`nbscore`g'')
ItemObservedExpectedScaled
``j''" %4.0f `Obs2'[`j',`g'] "" %6.2f `Th2'[`j',`g'] "" %7.4f `tmp' "
Contribution to the `namewp' statistics:" %8.4f `test`g''[1,1] "
" %4.0f `nbrealscore`h'' "" %6.2f `ci`h'' "" %7.4f `tmp' "
Contribution to the `namewp' statistics:" %8.4f `tmp' "
" + } + } +} + +/*********************************************************************************************************** +OPTION ICC +************************************************************************************************************/ +*set trace on +if "`icc'"!="" { + if "`trace'"!="" { + di in green "*** Items Characteristic Curves" + } + tempvar proba propemp propth propthb + qui replace `tl'=. if `realscore'==0|`realscore'==`nbitems'|`realscore'==. + qui gen `propemp'=. + qui gen `propth'=. + qui gen `propthb'=. + label variable `propth' "Expected ICC" + label variable `propemp' "Observed ICC" + label variable `propthb' "Expected ICC" + label variable `tl' "Latent trait" + global iccs + forvalues i=1/`nbitems' { + forvalues s=1/`=`nbitems'-1' { + qui replace `propthb'=exp(`theta`s''-`beta`i'')/(1+exp(`theta`s''-`beta`i'')) if `item'==`i'&`realscore'==`s' + } + qui replace `propemp'=. + qui replace `propth'=. + tempvar propemp`i' propth`i' + qui bysort `realscore' `item' : egen `propth`i''=mean(`propthb') if `item'==`i' + qui bysort `realscore' `item' : egen `propemp`i''=mean(`rep') if `item'==`i' + qui replace `propth'=`propth`i'' if `item'==`i' + qui replace `propemp'=`propemp`i'' if `item'==`i' + local mintl=floor(`theta1') + local maxtl=floor(`theta`=`nbitems'-1'')+1 + if "`filessave'"!=""{ + local saving "`dirsave'\\icc``i''" + } + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_icc_``i''" + } + if "`v8'"!=""|"`html'"!="" { + graph twoway (line `propemp' `propth' `tl') if `item'==`i' , `htmlregion' name(icc``i'',replace) ytitle("") ylabel(0(.25)1) title("Observed and Expected ICC for the item ``i''") xlabel(`mintl'(1)`maxtl') xsize(12) ysize(9) `draw' + if "`html'"=="" { + pause + } + else { + qui graph save icc``i'' "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_icc_``i''.eps, replace + di " _char(34) " + + } + *set trace on + if "`filessave'"!="" { + qui graph save icc``i'' "`saving'" , `replace' + if "`extension'"!="" { + if "`graphclose'"!="" { + graph close + } + *qui graph use `dirsave'\\icc``i'' + qui graph export `dirsave'\\icc``i''.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + putdocx image `dirsave'\\icc``i''.`extension', width(4) + } + } + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + qui graph `propemp' `propth' `tl' if `item'==`i' , twoway `saving' c(ll) ylabel(0(.25)1) xlabel(`mintl'(1)`maxtl') title("Observed and Expected ICC for the item ``i''") + pause + } + } +} + +/*********************************************************************************************************** +OPTION INFORMATION +************************************************************************************************************/ + +if "`information'"!="" { + if "`trace'"!="" { + di in green "*** Information graph" + } + + tempfile saveinfo + qui save "`saveinfo'",replace + tempvar info latent + forvalues i=1/`nbitems' { + tempvar info``i'' + } + drop _all + qui set obs 2001 + gen `latent'=((_n-1)/1001-1)*3 + label variable `latent' "latent trait" + gen `info'=0 + local gphbyitem + forvalues i=1/`nbitems' { + qui gen `info``i'''=exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2 + label variable `info``i''' "``i''" + qui replace `info'=`info'+exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2 + local gphbyitem `gphbyitem' `info``i''' + } + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_information" + } + if "`v8'"!=""|"`html'"!="" { + *set trace on + local saving "`dirsave'\\information" + graph twoway (line `info' `latent') , `htmlregion' name(information,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the scale") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + qui graph save information "`saving'" , `replace' + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\information + qui graph export `dirsave'\\information.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\information.`extension', width(4) + } + + } + } + if "`html'"=="" { + pause + } + else { + qui graph save information "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_information.eps, replace + di " _char(34) " + } + local saving "`dirsave'\\inf_items" + graph twoway (line `gphbyitem' `latent') , `htmlregion' name(inf_items,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the items") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + qui graph save inf_items "`saving'" , `replace' + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\inf_items + qui graph export `dirsave'\\inf_items.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\inf_items.`extension', width(4) + } + + } + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + if "`filessave'"=="" { + local saving + } + qui graph `info' `latent' , twoway `saving' c(l) xlabel(-3(1)3) title("Information graph of the scale") + pause + } + qui use "`saveinfo'",replace +} + +/*********************************************************************************************************** +OPTION FITGRAPH +************************************************************************************************************/ + +if "`fitgraph'"!="" { + if "`trace'"!="" { + di in green "*** Graphical validation of the fit" + } + *set trace on + tempname outfit meanz2 meanv2 sumd infit Voutfit outfitstd Vinfit infitstd + qui egen `outfit'=mean(`y2'),by(`id') + qui egen `Voutfit'=sum(`r'),by(`id') + qui replace `Voutfit'=`Voutfit'/(`nbitems')^2-1/`nbitems' + qui gen `outfitstd'=(`outfit'^(1/3)-1)*(3/sqrt(`Voutfit'))-sqrt(`Voutfit')/3 + qui egen `meanz2'=sum(`z2'),by(`id') + qui egen `meanv2'=sum(`v2'),by(`id') + qui gen `infit'=`meanz2'/`meanv2' + qui egen `Vinfit'=sum(`e'),by(`id') + qui replace `Vinfit'=`Vinfit'/(`meanv2')^2 + qui gen `infitstd'=(`infit'^(1/3)-1)*(3/sqrt(`Vinfit'))-sqrt(`Vinfit')/3 + + qui su `outfitstd' + local mino=floor(2*min(`r(min)',-2))/2 + local maxo=ceil(2*max(`r(max)',2))/2 + qui su `infitstd' + local mini=floor(2*min(`r(min)',-2))/2 + local maxi=ceil(2*max(`r(max)',2))/2 + if "`filessave'"!=""{ + local savingo "`dirsave'\\outfitind" + local savingi "`dirsave'\\infitind" + } + if "`v8'"!="" { + graph twoway (scatter `outfitstd' `id'), `htmlregion' name(outfit,replace) yline(-2 2) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw' + if "`html'"=="" { + pause + } + graph twoway (scatter `infitstd' `id'), `htmlregion' name(infit,replace) yline(-2 2) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw' + if "`html'"=="" { + pause + } + if "`filessave'"!=""|"`html'"!="" { + qui graph save outfit "`savingo'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_outfit.eps, replace + } + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\outfitind + qui graph export `dirsave'\\outfit.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\outfit.`extension', width(4) + } + + } + qui graph save infit "`savingi'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_infit.eps, replace + } + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\infitind + qui graph export `dirsave'\\infit.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\infit.`extension', width(4) + } + } + } + } + else { + if "`filessave'"!="" { + local savingo "saving(`savingo'" + local savingi "saving(`savingi'" + if "`replace'"=="" { + local savingo "`savingo')" + local savingi "`savingi')" + } + else { + local savingo "`savingo',replace)" + local savingi "`savingi',replace)" + } + } + graph `outfitstd' `id', `savingo' twoway sy(.) c(.) yline(-2 2) title("Outfit indexes") b2title("Individual indexes") l1("") l2title("Outfit") ylabel(`mino'(.5)`maxo') + pause + graph `infitstd' `id', `savingi' twoway sy(.) c(.) yline(-2 2) title("Infit indexes") b2title("Individual indexes") l1("") l2title("Infit") ylabel(`mini'(.5)`maxi') + pause + } + drop _all + qui set obs `nbitems' + tempvar name betap outfitstdj infitstdj + qui gen str9 `name'="" + qui gen `betap'=. + qui gen `outfitstdj'=. + qui gen `infitstdj'=. + local mino=-2 + local maxo=2 + local mini=-2 + local maxi=2 + forvalues j=1/`nbitems' { + qui replace `name'="``j''" in `j' + qui replace `betap'=`beta`j'' in `j' + qui replace `outfitstdj'=`outfitstd`j'' in `j' + qui replace `infitstdj'=`infitstd`j'' in `j' + local mino=floor(min(`mino',`outfitstd`j'')*2)/2 + local mini=floor(min(`mini',`infitstd`j'')*2)/2 + local maxo=ceil(max(`maxo',`outfitstd`j'')*2)/2 + local maxi=ceil(max(`maxi',`infitstd`j'')*2)/2 + } + if "`filessave'"!=""{ + local savingo "`dirsave'\\outfititems" + local savingi "`dirsave'\\infititems" + } + if "`v8'"!="" { + graph twoway (scatter `outfitstdj' `betap',`htmlregion' name(outfititem,replace) mlabel(`name')), yline(-2 2) title("Outfit indexes") xtitle("Difficulty") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw' + if "`html"=="" { + pause + } + graph twoway (scatter `infitstdj' `betap',`htmlregion' name(infititem,replace) mlabel(`name')), yline(-2 2) title("Infit indexes") xtitle("Difficulty") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw' + if "`html"=="" { + pause + } + if "`filessave'"!=""|"`html'"!="" { + qui graph save outfititem "`savingo'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_outfititem.eps, replace + } + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\outfititems + qui graph export `dirsave'\\outfititems.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\outfititems.`extension', width(4) + } + } + qui graph save infititem "`savingi'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_infititems.eps, replace + } + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\infititems + qui graph export `dirsave'\\infititems.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\infititems.`extension', width(4) + } + + } + } + } + else { + if "`filessave'"!="" { + local savingo "saving(`savingo'" + local savingi "saving(`savingi'" + if "`replace'"=="" { + local savingo "`savingo')" + local savingi "`savingi')" + } + else { + local savingo "`savingo',replace)" + local savingi "`savingi',replace)" + } + } + graph `outfitstdj' `betap', `savingo' twoway c(.) yline(-2 2) title("Outfit indexes") b2title("Difficulty") l1title("") l2title("Outfit") ylabel(`mino'(.5)`maxo') sy([`name']) + pause + graph `infitstdj' `betap', `savingi' twoway c(.) yline(-2 2) title("Infit indexes") b2title("Difficulty") l1title("") l2title("Infit") ylabel(`mini'(.5)`maxi') sy([`name']) + pause + } +} + + +/*********************************************************************************************************** +OPTION SPLITTESTS +************************************************************************************************************/ + +if "`splittests'"!="" { + if "`trace'"!="" { + di in green "*** Splitting tests" + } + forvalues j=1/`nbitems' { + tempname estneg`j' estpos`j' + local listitems + forvalues k=1/`nbitems' { + if `j'!=`k' { + local listitems `listitems' ``k'' + } + } + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + qui raschtestv7 `listitems' if ``j''==0,test(NONE) meth(cml) `ld' id(`id') + matrix `estneg`j''=r(beta) + local llneg=r(cll) + qui raschtestv7 `listitems' if ``j''==1,test(NONE) meth(cml) `ld' id(`id') + matrix `estpos`j''=r(beta) + local llpos=r(cll) + qui raschtestv7 `listitems',test(NONE) meth(cml) `ld' id(`id') + local llnegpos=r(cll) + local nbcol=colsof(`estneg`j'') + local meanneg=0 + local meanpos=0 + forvalues k=1/`nbcol' { + local meanneg=`meanneg'+`estneg`j''[1,`k'] + local meanpos=`meanpos'+`estpos`j''[1,`k'] + } + local meanneg=`meanneg'/`nbitems' + local meanpos=`meanpos'/`nbitems' + forvalues k=1/`nbcol' { + matrix `estneg`j''[1,`k']=`estneg`j''[1,`k']-`meanneg' + matrix `estpos`j''[1,`k']=`estpos`j''[1,`k']-`meanpos' + if "`method'"=="cml" { + matrix `estneg`j''=`estneg`j'',-`meanneg' + matrix `estpos`j''=`estpos`j'',-`meanpos' + } + } + drop _all + qui set obs `=`nbitems'+1' + tempvar neg pos name diag + qui gen `neg'=. + qui gen `pos'=. + qui gen str9 `name'="" + local min=`estneg`j''[1,1] + local max=`estneg`j''[1,1] + forvalues k=1/`=`nbitems'-1' { + qui replace `neg'=`estneg`j''[1,`k'] in `k' + qui replace `pos'=`estpos`j''[1,`k'] in `k' + local min=min(`min',`estneg`j''[1,`k'],`estpos`j''[1,`k']) + local max=max(`max',`estneg`j''[1,`k'],`estpos`j''[1,`k']) + local tmp:word `k' of `listitems' + qui replace `name'="`tmp'" in `k' + } + local min=floor(`min') + local max=floor(`max')+1 + qui gen `diag'=. + qui replace `diag'=`min' in `nbitems' + qui replace `diag'=`max' in `=`nbitems'+1' + local Zgr=round(2*(`llneg'+`llpos'-`llnegpos'),0.001) + local Zgr=substr("`Zgr'",1,6) + local pgr=round(1-chi2(`=`nbitems'-1',`Zgr'),0.0001) + local pgr=substr("`pgr'",1,5) + local note="Z=`Zgr', df=`=`nbitems'-1' , p=`pgr'" + if "`filessave'"!=""{ + local saving "`dirsave'\\split``j''" + } + if "`v8'"!="" { + graph twoway (scatter `pos' `neg' ,mlabel(`name')) (line `diag' `diag'), ytitle("Positive answer") xtitle("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title(Splitting on ``j'') `draw' legend(off) note("Andersen Z test: `note'") name(split,replace) `draw' + pause + if "`filessave'"!="" { + graph save split "`saving'" , `replace' + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + qui replace `diag'=`neg' if `diag'==. + graph `pos' `diag' `diag', `saving' c(.l) sy([`name']i) l1title("") l2title("Positive answer") b2title("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title("Splitting on ``j'' (`note')") `draw' + pause + } + } +} + +/*********************************************************************************************************** +OPTION GRAPH +************************************************************************************************************/ + +if "`graph'"!=""&"`v8'"!="" { + if "`trace'"!="" { + di in green "*** Graph option" + } + tempvar latent2 tl2 delta2 tlth2 labdelta2 labtl2 + drop _all + qui set obs 1001 + gen `latent2'=(_n-501)/100 + label variable `latent2' "latent trait" + qui gen `tl2'=. + qui gen `labtl2'="" + forvalues i=0/`nbitems' { + *if (`i'!=0&`i'!=`nbitems')|"`method'"!="cml" { + qui replace `tl2'=`nbrealscore`i''/`N' if round(`latent2',0.01)==round(`theta`i'',0.01) + qui replace `labtl2'="`i'" if round(`latent2',0.01)==round(`theta`i'',0.01) + *} + } + qui gen `delta2'=. + qui gen `labdelta2'="" + forvalues i=1/`nbitems' { + qui replace `delta2'=-.05 if round(`latent2',0.01)==round(`beta`i'',0.01) + qui replace `labdelta2'="``i''" if round(`latent2',0.01)==round(`beta`i'',0.01) + } + if "`method'"=="mml"|"`method'"=="gee" { + qui gen `tlth2'=1/(2*_pi*`sig')*exp(-.5*(`latent2'/`sig')^2) + label variable `tlth2' "Theorical distribution" + local graphmml line `tlth2' `latent2' + } + label variable `tl2' "Score" + label variable `delta2' "Items" + local saving "`dirsave'\\graph" + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_map" + } + local min=-2 + local max=2 + forvalues j=1/`nbitems' { + if `beta`j''<`min' { + local min=`beta`j''-.5 + } + if `beta`j''>`max'&`beta`j''!=. { + local max=`beta`j''+.5 + } + } + if "`method'"=="cml" { + if `theta0'<`min' { + local min=`theta0'-.5 + } + if `theta`=`nbitems'-1''>`max' { + local max=`theta`=`nbitems'-1''+.5 + } + } + else if "`method'"!="cml" { + if `theta0'<`min'&`theta0'!=. { + local min=`theta0'-.5 + } + if `theta`nbitems''>`max'&`theta`nbitems''!=. { + local max=`theta`nbitems''+.5 + } + } + local min=floor(`min') + local max=floor(`max')+1 + qui su `tl2' + local max2=r(max) + if "`method'"!="cml" { + qui su `tlth2' + local max2=max(`max2',`r(max)') + } + qui replace `latent2'=. if `latent2'<`min'|`latent2'>`max' + if "`v8'"!="" { + graph twoway (bar `tl2' `latent2',/*mlabel(`labtl2')*/ barwidth(.3) ) (dropline `delta2' `latent2',mlabel(`labdelta2') mlabposition(6)) (`graphmml'), `htmlregion' name(graph,replace) ytitle("") xlabel(`min'(1)`max') ylabel(-.1 0(0.05)`max2') title("Individuals/items representations") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + qui graph save graph "`saving'" , `replace' + if "`extension'"!="" { + *qui graph use `dirsave'\\graph + qui graph export `dirsave'\\graph.`extension' , `replace' + if "`docx'"!="" { + putdocx paragraph + putdocx text ("In this dataset, there are `r(N)' models") + + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\graph.`extension', width(4) + } + if "`graphclose'"!="" { + qui graph close + } + + } + } + if "`html'"=="" { + pause + } + else { + qui graph save graph "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_map.eps, replace + di " _char(34) " + } + } +} +else if "`graph'"!=""&"`v8'"=="" { + di in ye "The graph option is not available with Stata 7" +} + +/*********************************************************************************************************** +COMPARISON OF TWO POPULATION +************************************************************************************************************/ + +if "`comp'"!=""&"`method'"!="cml" { + di + di _col(4) "{hline 30}" + di _col(4) in green "Comparison of two populations" + di _col(4) "{hline 30}" + di + di _col(4) in green "`comp'==`mincomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmin' _col(30) in green "mean= " _col(35) in yellow %8.4f `meanmin' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmin' + di _col(4) in green "`comp'==`maxcomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmax' _col(30) in green "mean= " _col(35) in yellow %8.4f `meanmax' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmax' + di _col(33) in green "Z= " _col(35) in yellow %8.4f `Zcomp' _col(47) in green "pvalue= " _col(57) in yellow %6.4f `pvalue' +} + +/*********************************************************************************************************** +TEST DIF +************************************************************************************************************/ + +if "`method'"=="cml"&"`dif'"!=""&"`test'"!="NONE" { + if "`trace'"!="" { + di in green "*** Tests of DIF" + } + local ssll=0 + tempname DIFfile + qui save "`DIFfile'", replace + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + unab list:`dif' + local nbdif:word count `list' + tempname DIF + matrix define `DIF'=J(`nbdif',4,0) + local count=1 + di + di _col(4) in green "{hline 45}" + di _col(4) in green "Test of Differential Item Functioning (DIF)" + di _col(4) in green "{hline 45}" + foreach j in `list' { + qui inspect `j' + local nbdif=r(N_unique) + qui su `j' + local maxdif=r(max) + if `nbdif'>10&`maxdif'<=10 { + di in ye "The {hi:dif} option is available with variables containing 10 or more modalities (coded from 0 or 1 to k<10)." + di in ye "The variable `j' (`nbdif' modalities) is omitted." + } + else { + local ssll=0 + forvalues i=0/10 { + qui count if `j'==`i' + local effdif=r(N) + if `effdif'>0 { + qui raschtestv7 `varlist' if `j'==`i', test(NONE) id(`id') + local ll`i'=r(cll) + local ssll=`ssll'+(`ll`i'') + } + } + local Z=2*`ssll'-2*`ll' + local ddl=(`nbdif'-1)*(`nbitems'-1) + matrix define `DIF'[`count',1]=(`count',`Z',`ddl',1-chi2(`ddl',`Z')) + di + di _col(4) in green "Variable:" in ye " `j' " in green " Number of groups: " in ye "`nbdif'" + di _col(4) in green "LR Test Z=" in ye %8.3f `Z' in gr " ddl=" in ye %4.0f `ddl' in gr " p-value=" in ye %6.4f `=1-chi2(`ddl',`Z')' + di + } + local ++count + } + use "`DIFfile'",replace +} + +/*********************************************************************************************************** +RETURN +************************************************************************************************************/ + +if "`trace'"!="" { + di in green "*** Returns" +} +local colnametheta + +forvalues i=0/`nbgroups' { + local colnametheta `colnametheta' score_`i' +} + + +return clear + +if `nbitems'>=3&"`test'"!="NONE" { + matrix colnames `globalfit'=`namewp' df p + matrix rownames `globalfit'=`method' + matrix rownames `itemfit'=`varlist' + matrix roweq `itemfit'=`method' + + if "`method'"=="cml" { + matrix colnames `itemfit'=`namewp' df p outfit infit U + matrix rownames `AndersenZ'=`method' + matrix colnames `AndersenZ'=Z df p + return matrix AndersenZ=`AndersenZ' + if "`dif'"!="" { + matrix rownames `DIF'=`list' + matrix colnames `DIF'=num Z df p + return matrix DIF=`DIF' + } + } + else { + matrix colnames `itemfit'=`namewp' df p outfit infit + } + return matrix itemFit=`itemfit' + return matrix globalFit=`globalfit' +} + +matrix colnames `theta'=`colnametheta' +matrix rownames `theta'=theta +return matrix theta `theta' +matrix colnames `sdtheta'=`colnametheta' +matrix rownames `sdtheta'=`colnametheta' +return matrix Vartheta `sdtheta' +local varlist2 +matrix coleq `beta'=`method' +matrix coleq `Vbeta'=`method' +matrix roweq `Vbeta'=`method' +if "`method'"=="cml" { + forvalues i=1/`=`nbitems'-1' { + local varlist2 `varlist2' ``i'' + } + return scalar cll=`ll' + return scalar ll=`globalll' + local AIC=-2*`globalll'+2*(`nbitems'-1) +} +else { + return scalar ll=`ll' + local varlist2 `varlist' + return scalar sigma=`sig' + return scalar sesigma=`sesig' + local AIC=-2*`ll'+2*(`nbitems'+1) +} + +if "`comp'"!="" { + return scalar Zcomp=`Zcomp' + return scalar pZcomp=`pvalue' +} + +matrix colnames `beta'=`varlist2' +matrix rownames `beta'=beta +return matrix beta `beta' + +matrix colnames `Vbeta'=`varlist2' +matrix rownames `Vbeta'=`varlist2' +return matrix Varbeta `Vbeta' + +return scalar AIC=`AIC' +return scalar N=`nbind' +return scalar N_obs=`nbobserv' + +if "`method'"=="mml" { + return scalar PSI=`psi2' + return scalar PSIadj=`psi' +} +if "`covariables'"!="" { + local tmp + local tmp2 + forvalues i=1/`nbcovariables' { + local tmp `tmp' `covariable`i'' + local tmp2 "`tmp2' :`covariable`i''" + } + matrix colnames `betacov'=`tmp2' + matrix rownames `Vbetacov'=`tmp2' + matrix colnames `Vbetacov'=`tmp2' + matrix colnames `zcovariates'=`tmp' + matrix colnames `pcovariates'=`tmp' + return matrix betacovariates=`betacov' + return matrix Vbetacovariates=`Vbetacov' + return matrix zcovariates=`zcovariates' + return matrix pcovariates=`pcovariates' +} +if "`pause'"!="" { + pause off +} + +drop _all + +restore,not +use "`saveraschtest'" + +/*********************************************************************************************************** +CREATE EVENTUAL NEW VARIABLES +************************************************************************************************************/ + +*set trace on +if "`genres'"!="" { + qui sort `id' + qui merge `id' using `ltsave' + qui rename `u'm1 `genlt' + qui rename `u's1 se`genlt' + qui drop _merge se`genlt' + forvalues i=1/`nbitems' { + gen `genres'`i'=exp(``i''*(`genlt'-`beta`i''))/(1+exp(`genlt'-`beta`i''))/sqrt(exp(`genlt'-`beta`i'')/(1+exp(`genlt'-`beta`i''))^2) + } + corr `genres'* + pca `genres'* + drop `u'm1 +} +if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" { + tempname genlt2 genscore2 outfit2 infit2 + qui gen `score'=0 `if' + forvalues i=1/`nbitems' { + qui replace `score'=`score'+``i'' `if' + } + if "`genscore'"!="" { + qui gen `genscore'=`score' `if' + } + if "`genlt'"!="" { + if "`replacegenlt'"=="replace" { + capture drop `genlt' + capture drop se`genlt' + } + if "`method'"=="mml" { + qui sort `id' + qui merge `id' using `ltsave' + qui rename `u'm1 `genlt' + qui rename `u's1 se`genlt' + qui drop _merge + } + else if "`method'"!="mml" { + qui gen `genlt2'=. `if' + forvalues i=0/`nbitems' { + qui replace `genlt2'=`theta`i'' `if'&`score'==`i' + } + qui gen `genlt'=`genlt2' `if' + } + } + if "`genfit'"!="" { + local outfit:word 1 of `genfit' + local infit:word 2 of `genfit' + qui gen `outfit'=0 `if' + qui gen `infit'=0 `if' + tempname infit1 infit2 + qui gen `infit1'=0 `if' + qui gen `infit2'=0 `if' + forvalues j=1/`nbitems' { + tempname pi`j' + qui gen `pi`j''=exp(`genlt2'-`beta`j'')/(1+exp(`genlt2'-`beta`j'')) `if' + qui replace `pi`j''=0 `if' + forvalues s=1/`nbitems' { + qui replace `pi`j''=`Pi'[`j',`s'] `if'&`score'==`s' + } + qui gen `outfit'``j''=(``j''-`pi`j'')^2/(`pi`j''*(1-`pi`j'')) `if' + qui replace `infit1'=`infit1'+(``j''-`pi`j'')^2 `if' + qui replace `infit2'=`infit2'+(`pi`j''*(1-`pi`j'')) `if' + qui replace `outfit'=`outfit'+`outfit'``j''/`nbitems' `if' + } + qui replace `infit'=`infit1'/`infit2' `if' + } +} +if "`docx'"!="" { +*set trace on + putdocx save "`dirsave'\\`docx'.docx", replace + putdocx clear +} +if "`trace'"!=""|"`time'"!="" { + capture qui elapse `st' + di in green "** Time : " in yellow "$S_elap " in green "seconds" +} + +end diff --git a/Modules/ado/personal/r/raschtestv7v8.10.ado b/Modules/ado/personal/r/raschtestv7v8.10.ado new file mode 100644 index 0000000..4328488 --- /dev/null +++ b/Modules/ado/personal/r/raschtestv7v8.10.ado @@ -0,0 +1,2547 @@ +*! version 8.10 5july2019 +*! Jean-Benoit Hardouin +************************************************************************************************************* +* Raschtestv7: Rasch model, fit tests and graphical representations +* Corresponds to the version 8 of Raschtest (http://freeirt.org) for Stata7 +* +* Historic: +* Version 2.1 (2003-07-10): Jean-Benoit Hardouin +* Version 3.1 (2004-01-02) : Jean-Benoit Hardouin +* Version 7.1 (2005-03-30) : Jean-Benoit Hardouin +* Version 7.2.1 (2005-05-21) : Jean-Benoit Hardouin +* Version 7.3.1 (2005-07-02) : Jean-Benoit Hardouin +* Version 7.3.2 (2005-10-05) : Jean-Benoit Hardouin /*correction for the *genlt* option with *method(cml)**/ +* Version 7.3.3 (2005-12-21) : Jean-Benoit Hardouin /*correction if scores are not represented with method(mml) or method(gee)*/ +* Version 7.4.1 (2006-01-17) : Jean-Benoit Hardouin /*Standardized OUTFIT and INFIT, DIF option*/ +* Version 7.4.2 (2006-03-21) : Jean-Benoit Hardouin /*Avoids a bug when the temporary files are saved in a directory containing special characters*/ +* Version 7.4.3 (2006-11-15) : Jean-Benoit Hardouin /*Avoids a bug when the directory defined in the dirsave option contains special characters*/ +* Version 7.5.1 (2007-04-20) : Jean-Benoit Hardouin /*Return results of the comp option*/ +* Version 7.6.1 (2008-06-26) : Jean-Benoit Hardouin /*Nold option, corrects a bug with the genlt option*/ +* Version 7.6.2 (2009-03-01) : Jean-Benoit Hardouin /*Correction of the SE of the latent trait, graph option, correction of a bug with the if option, PSI in MML*/ +* Version 8.1 (2009-06-24) : Jean-Benoit Hardouin /*DIFFICULTIES option, COVARIATES option*/ +* Version 8.2 (2009-07-15) : Jean-Benoit Hardouin /*Correction of a bug with CML*/ +* Version 8.3 (2009-12-19) : Jean-Benoit Hardouin /*correction of a bug with DIFFICULTIES and COVARIATES options together*/ +* Version 8.4 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option */ +* Version 8.5 (2011-12-20) : Jean-Benoit Hardouin /*Correction for the ss1 and ss3 suboptions of the COVARIATES option */ +* Version 8.6 (2012-11-20) : Jean-Benoit Hardouin /*HTML option*/ +* Version 8.7 (2013-05-28) : Jean-Benoit Hardouin /*Correction of a bug in the covariates option with ss1 and ss3*/ +* Version 8.8 (2014-02-27) : Jean-Benoit Hardouin /*Correction of a bug when the null or the parfect score have a frequency of 0 (no test)*/ +* Version 8.9 (2019-06-05) : Jean-Benoit Hardouin /*png option (graphs in png), information curve by item*/ +* Version 8.10 (2019-07-05) : Jean-Benoit Hardouin /*extension option (graphs with the chosen extension) who replaces the png option, docx option*/ +* +* Needed modules : +* gammasym version 2.2 (http://www.freeirt.org) +* gausshermite version 1 (http://www.freeirt.org) +* geekel2d version 4.3 (http://www.freeirt.org) +* genscore version 1.4 (http://www.freeirt.org) +* ghquadm (findit ghquadm) +* gllamm version 2.3.20 (ssc describe gllamm) +* gllapred version 2.3.8 (ssc describe gllapred) +* elapse (ssc describe elapse) +* +* Jean-benoit Hardouin - University of Nantes - France +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research" +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2003-2014 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*********************************************************************************************************** +DEFINITION / SYNTAX +***********************************************************************************************************/ + + +program define raschtestv7,rclass +syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GENRES(string) GRAph v8 COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) extension(string) GRAPHClose DOCX(string)] + +local covariables `covariates' + +if "`docx'"!="" { + putdocx clear + putdocx begin + putdocx paragraph + putdocx text ("Graphical outputs of the raschtest module") +} +if "`if'"=="" { + local if "if 1" +} + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + +if "`trace'"!="" { + di in green "*** Tests of conformity" +} +if "`v8'"=="" { + version 7.0 +} +else { + version 8.0 +} +if "`html'"!="" { + set scheme sj + local htmlregion "graphregion(fcolor(white) ifcolor(white))" + local draw +} + +local st = "$S_TIME" +local nbitems : word count `varlist' +marksample touse ,novarlist +if "`covariables'"!="" { + tokenize "`covariables'",parse(" ,") + local i=1 + local tcovariables + while "``i''"!=","&"``i''"!="" { + local covariable`i' ``i'' + local tcovariables `tcovariables' ``i'' + local ++i + } + local nbcovariables=`i'-1 + local ss1 + local ss3 + if "``i''"=="," { + forvalues j=`=`i'+1'/`=`i'+2' { + if "``j''"=="ss1" { + local ss1 ss1 + } + else if "``j''"=="ss3" { + local ss3 ss3 + } + else if "``j''"=="" { +* di in green "option `j' vide" + } + else { + di in red "Invalid option in the {hi:covariables} option" + error 198 + } + } + local i=`i'+3 + if "``i''"!="" { + di in red "There is too much options in the {hi:covariates} option." + error 198 + } + } + local covariables `tcovariables' +} +else { + local nbcovariables=0 +} + +isid `id' +tokenize `varlist' + +local bad +forvalues i=1/`nbitems' { + qui count if ``i''!=0&``i''!=1&``i''!=. + local N=r(N) + if `N'>0 { + local bad `bad' ``i'' + } +} +if "`bad'"!="" { + di in red "The item(s) {hi:`bad'} is(are) not binary item(s) (with responses 0 or 1)." + exit +} + + + +if "`method'"=="" { + local method cml +} +if "`test'"=="" { + local test R +} +local method=lower("`method'") +local test=upper("`test'") +if "`method'"!="mml"&"`method'"!="cml"&"`method'"!="gee" { + di in red "Uncorrect method option." + error 198 + exit +} + +if "`test'"!="R"&"`test'"!="Q"&"`test'"!="WP"&"`test'"!="NONE" { + di in red "Uncorrect test option." + error 198 + exit +} + +if "`genfit'"!="" { + local nbwordgenfit:word count `genfit' + if `nbwordgenfit'!=2 { + di in red "Uncorrect genfit option." + di in red "This option must contain exactly two words" + error 198 + exit + } +} + + +if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!=""|"`genres'"!="" { + capture confirm new variable `genfit' `genscore' `genres' + if "`genfit'"!="" { + local o:word 1 of `genfit' + forvalues i=1/`nbitems' { + confirm new variable `o'``i'' + } + } + if "`genlt'"!="" { + local 0 `genlt' + gettoken left 0: 0,parse(",") + gettoken right 0: 0,parse(",") + local genlt `left' + local replacegenlt `0' + local length=length("`replacegenlt'") + if `length'>=3&substr("`replacegenlt'",1,`length')==substr("replace",1,`length') { + local replacegenlt replace + } + if "`replacegenlt'"!="replace"&"`replacegenlt'"!="" { + di "Not allowed option in the {hi:genlt} option" + error 198 + } + else if "`replacegenlt'"=="" { + confirm new variable `genlt' + } + } +} + +preserve + +tempfile saveraschtest +qui save `saveraschtest' +qui keep if `touse'==1 + +if "`autogroup'"!=""&"`group'"!="" { + di in green "The autogroup and the group options cannot be defined in the same time" + di in green "Only the group option is retained." + local autogroup +} + +if "`autogroup'"!="" { + tempvar autoscore + qui genscore `varlist',score(`autoscore') + + tempname matscore tmp + matrix `matscore'=J(`=`nbitems'-1',3,0) + forvalues i=1/`=`nbitems'-1' { + matrix `matscore'[`i',1]=`i' + matrix `matscore'[`i',2]=`i' + qui count if `autoscore'==`i' + matrix `matscore'[`i',3]=r(N) + } + local stop=0 + local j=0 + while `j'<=`=`nbitems'-3'&`stop'!=1 { + local j=`j'+1 + local scoretogroup=99999999 + local rowtogroup1=0 + local rowtogroup2=0 + local stop=1 + forvalues i=1/`=`nbitems'-`j'' { + if `matscore'[`i',1]>=0 & `matscore'[`i',3]<30 & `matscore'[`i',3]<`scoretogroup' { + local scoretogroup=`matscore'[`i',3] + local rowtogroup1=`i' + local stop=0 + } + } + if `stop'!=1 { + if `rowtogroup1'>1&`rowtogroup1'<`=`nbitems'-`j'' { + if `matscore'[`=`rowtogroup1'-1',1]<`matscore'[`=`rowtogroup1'+1',1] { + local rowtogroup2=`rowtogroup1' + local rowtogroup1=`rowtogroup1'-1 + } + else { + local rowtogroup2=`rowtogroup1'+1 + } + } + else if `rowtogroup1'==1 { + local rowtogroup2=2 + } + else if `rowtogroup1'==`=`nbitems'-`j'' { + local rowtogroup2=`nbitems'-`j' + local rowtogroup1=`nbitems'-`j'-1 + } + matrix `tmp'=`matscore' + matrix `matscore'=J(`=`nbitems'-`j'',3,0) + if `rowtogroup1'!=1 { + matrix `matscore'[1,1]=`tmp'[1..`=`rowtogroup1'-1',1..3] + } + matrix `matscore'[`rowtogroup1',1]=`tmp'[`rowtogroup1',1] + matrix `matscore'[`rowtogroup1',2]=`tmp'[`rowtogroup2',2] + matrix `matscore'[`rowtogroup1',3]=`tmp'[`rowtogroup1',3]+`tmp'[`rowtogroup2',3] + if `rowtogroup2'!=`=`nbitems'-`j'' { + matrix `matscore'[`rowtogroup2',1]=`tmp'[`=`rowtogroup2'+1'..`=`nbitems'-`j'',1..3] + } + } + } + local nbrows=rowsof(`matscore')-1 + local thresholds + forvalues i=1/`nbrows' { + local tmp=`matscore'[`i',2] + local thresholds `thresholds' `tmp' + } + local group `thresholds' +} + + +if "`group'"=="" { + forvalues i=1/`=`nbitems'-1' { + local group "`group' `i'" + } +} +local nbgroups:word count `group' +local groupmax:word `nbgroups' of `group' +if `groupmax'>=`nbitems' { + di in red "You cannot form a group with the higher possible score." + di in red "The higher possible value of the group option is `=`nbitems'-1'." + di in red "Please correct your group option." + error 198 + exit +} +else { + if `groupmax'!=`=`nbitems'-1' { + local group "`group' `=`nbitems'-1'" + local nbgroups=`nbgroups'+1 + } +} +local nbgroups=`nbgroups'+1 + +if "`dirsave'"!=""&"`filessave'"=="" { + di in ye "If you want to save yours graphs, use the filessave option" +} +if "`filessave'"!="" { + if "`dirsave'"=="" { + local dirsave "`c(pwd)'" + } + di in ye "The graphs files will be saved in `dirsave'" +} +if "`dirsave'"!="" { + if "`filesave'"=="" { + local filesave "filesave" + } +} +if "`extension'"!=""&"`extension'"!="png"&"`extension'"!="eps"&"`extension'"!="ps"&"`extension'"!="svg"&"`extension'"!="wmf"&"`extension'"!="png"&"`extension'"!="emf"&"`extension'"!="pdf"&"`extension'"!="tif" { + di in red "The {hi:extension} option can not contain the value `extension'. Please correct it." + error 198 + exit +} +if "`pause'"!=""&"`draw'"=="" { + pause on +} + +if "`difficulties'"!="" { + capture confirm matrix `difficulties' + if _rc!=0 { + di in red "The vector `difficulties' defined in the {hi:difficulties} option does not exist." + error 198 + exit + } +} + +if "`difficulties'"!=""&"`method'"!="mml" { + di in red "The {hi:difficulties} option can be defined only for MML method." + error 198 + exit +} + +if "`covariables'"!=""&"`method'"!="mml" { + di in red "The {hi:covariables} option can be defined only for MML method." + error 198 + exit +} +if "`covariables'"!=""&"`comp'"!="" { + di in red "The {hi:covariables} and {hi:comp} options can be defined jointly." + error 198 + exit +} + + + + + +/*********************************************************************************************************** +POSSIBLE TEST +***********************************************************************************************************/ + +if ("`icc'"!=""|"`fitgraph'"!=""|"`splittest'"!=""|"`details'"!="")&"`test'"=="NONE" { + di in green "You cannot use the {hi:details}, {hi:icc}, {hi:fitgraph} or {hi:splittest} options if you use {hi:test(none)}." + di in green "These options are ignored." + local details + local icc + local fitgraph + local splittest +} +if "`comp'"!=""&"`method'"=="cml" { + di in green "You cannot compare two populations ({hi:comp} option) with the CML estimation method" + di in green "This option is ignored." + local comp +} +if "`method'"!="cml"&"`test'"=="WP" { + di in green "The Wright-Panchapakesan test is not authorized with MML or GEE." + di in green "The WP tests are replaced by Van den Wollenberg Q tests." + local test Q +} +if "`method'"=="gee"&"`ld'"!="" { + di in green "You cannot use the {hi:nold} option with the GEE method of estimation" + di in green "This option is ignored." + local ld +} + + +if "`test'"==""|"`test'"=="R" { + local test "R" + if "`method'"=="cml" { + local namewp "R1c" + local descwp "R1c test" + } + else { + local namewp="R1m" + local descwp "R1m test" + } +} +if `nbitems'>999999|"`test'"=="WP" { + local namewp " Y" + local descwp "Wright-Panchapakesan Y test" + local q2 +} + else if "`test'"=="Q" { + local namewp " Q1" + local descwp "Van den Wollenberg Q1 test" +} + +if "`method'"!="cml"&"`meandiff'"!="" { + di in green "The {hi:meandiff} option is not available with MML or GEE." + di in green "This option is ignored." + local meandiff +} + +if "`method'"!="cml"&"`splittests'"!="" { + di in green "The {hi:splittests} option is not available with MML or GEE." + di in green "This option is ignored." + local splittests +} +if "`method'"!="cml"&"`dif'"!="" { + di in green "The {hi:dif} option is not available with MML or GEE." + di in green "This option is ignored." + local dif +} + +/*********************************************************************************************************** +SCORES AND GROUPS +************************************************************************************************************/ + +qui count if `touse'==1 +local N=r(N) + +qui keep `varlist' `comp' `covariables' `id' `touse' + +tempname rep item +tempvar score realscore +qui genscore `varlist',score(`score') +qui count if `score'==.&`touse'==1 +local nbindmiss=r(N) + +if "`ld'"=="" { + qui drop if `score'==. +} +forvalues i=1/`nbitems' { + rename ``i'' `rep'`i' +} + + + +local liminf0=0 +local limsup0=0 +local liminf`nbgroups'=`nbitems' +local limsup`nbgroups'=`nbitems' + + +local recode +forvalues i=1/`=`nbgroups'-1' { + if `i'!= 1{ + local liminf`i' : word `=`i'-1' of `group' + } + else { + local liminf1=0 + } + local liminf`i'=`liminf`i''+1 + local limsup`i':word `i' of `group' + + local recode "`recode' `liminf`i''/`limsup`i''=`i'" +} +qui gen `realscore'=`score' +qui recode `score' `recode' `nbitems'=`nbgroups' + +local smallgroup=0 + +forvalues i=0/`nbgroups' { + qui count if `score'==`i' + local effscore`i'=r(N) + if `i'!=0&`i'!=`nbgroups'&`effscore`i''<30 { + local smallgroup=1 + } +} +/*********************************************************************************************************** +ESTIMATION OF THE DIFFICULTY PARAMETERS +************************************************************************************************************/ +if "`trace'"!="" { + di in green "*** Estimation of the difficulty parameters" +} + + +if "`covariables'"!=""&"`difficulties'"=="" { + forvalues i=1/`nbcovariables' { + qui su `covariable`i'' + local mean`covariable`i''=r(mean) + qui replace `covariable`i''=`covariable`i''-`mean`covariable`i''' + } +} + +tempname ll coef var beta Vbeta est + +if "`method'"=="gee" { + qui geekel2d `rep'1-`rep'`nbitems',ll + local nbobserv=r(N) + + if `r(error)'==1 { + di "The variance of the latent trait probably is too high to made the GEE a efficient method to estimate the parameters." + error 499 + exit + } + scalar `ll'=r(ll) + local nbind=r(N) + matrix `coef'=r(b) + matrix `est'=`coef' + matrix `est'[1,`=`nbitems'+1']=sqrt(`est'[1,`=`nbitems'+1']) + matrix `var'=r(V) + matrix `beta'=`coef'[1,1..`nbitems'] + matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems'] + local sig=sqrt(`coef'[1,`=`nbitems'+1']) + local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])/sqrt(`nbind')/(`sig'*2) +} + +qui reshape long `rep', i(`id') j(`item') + +tempvar diff tl +gen `diff'=0 + +forvalues i=1/`nbitems' { + qui gen `rep'`i'=`item'==`i' + qui replace `rep'`i'=-`rep'`i' +} + + +if "`method'"=="mml" { + if "`difficulties'"==""{ + qui xtlogit `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') nocons iterate(`iterate') + matrix `est'=e(b) + matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`est'[1,`=`nbitems'+`nbcovariables'+1']/2) + } + else { + tempname offset b + qui gen `offset'=0 + forvalues i=1/`nbitems' { + qui replace `offset'=-(`difficulties'[1,`i']) if `item'==`i' + } + qui gllamm `rep' `covariables' , offset(`offset') i(`id') nocons iterate(`iterate') link(logit) fam(bin) + matrix `b'=e(b) + matrix `est'=`difficulties',`b' + matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`b'[1,`=`nbcovariables'+1']/2) + } +} +else if "`method'"=="cml" { + qui clogit `rep' `rep'1-`rep'`=`nbitems'-1' , group(`id') +} + + +if "`method'"!="gee" { + if "`difficulties'"=="" { + matrix `coef'=e(b) + matrix `var'=e(V) + } + else { + matrix `coef'=`difficulties' + matrix `var'=J(`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1',.) + matrix `var'[`=`nbitems'+1',`=`nbitems'+1']=e(V) + } + scalar `ll'=e(ll) + local nbind=e(N)/`nbitems' + local nbobserv=e(N) + *di "nombre d'obs:`nbobserv'" + + if "`meandiff'"!="" { + matrix `var'=J(`nbitems',`nbitems',.) + matrix `coef'=J(1,`nbitems',.) + local param + local lin `rep'1 + forvalues j=2/`=`nbitems'-1' { + local lin `lin'+`rep'`j' + } + local lin (`lin')/`nbitems' + + forvalues j=1/`=`nbitems'-1' { + qui lincom `rep'`j'-`lin' + matrix `coef'[1,`j']=`r(estimate)' + matrix `var'[`j',`j']=`r(se)'^2 + } + qui lincom -`lin' + matrix `coef'[1,`nbitems']=`r(estimate)' + matrix `var'[`nbitems',`nbitems']=`r(se)'^2 + } + if "`method'"=="mml" { + local sig=e(sigma_u) + local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2 + tempname betacov Vbetacov + if "`difficulties'"=="" { + matrix `beta'=`coef'[1,1..`nbitems'] + matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems'] + if "`covariables'"!="" { + matrix `betacov'=`coef'[1,`=`nbitems'+1'..`=`nbitems'+`nbcovariables''] + matrix `Vbetacov'=`var'[`=`nbitems'+1'..`=`nbitems'+`nbcovariables'',`=`nbitems'+1'..`=`nbitems'+`nbcovariables''] + } + local sig=e(sigma_u) + local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2 + } + else { + tempname tmp + matrix `tmp'=e(b) + matrix `beta'=`difficulties' + if "`covariables'"!="" { + matrix `betacov'=`tmp'[1,1..`nbcovariables'] + } + local sig=`tmp'[1,`=`nbcovariables'+1'] + matrix `tmp'=e(V) + local sesig=sqrt(`tmp'[`=`nbcovariables'+1',`=`nbcovariables'+1']) + matrix `Vbeta'=J(`nbitems',`nbitems',.) + if "`covariables'"!="" { + matrix `Vbetacov'=`tmp'[1..`nbcovariables',1..`nbcovariables'] + } + } + } + else if "`method'"=="cml"&"`meandiff'"==""{ + matrix `beta'=`coef'[1,1..`=`nbitems'-1'] + matrix `Vbeta'=`var'[1..`=`nbitems'-1',1..`=`nbitems'-1'] + } + else if "`method'"=="cml"&"`meandiff'"!=""{ + matrix `beta'=`coef' + matrix `Vbeta'=`var' + } +} + +if ("`method'"=="mml"|"`method'"=="gee") { + local colnames + forvalues i=1/`nbitems' { + local colnames "`colnames' `rep':`rep'`i'" + } + forvalues i=1/`nbcovariables'{ + local tmp:word `i' of `covariables' + local colnames "`colnames' `rep':`tmp'" + } + local id2=substr("`id'",1,4) + local colnames "`colnames' `id2'1:_cons" + matrix colnames `est'=`colnames' + + qui gllamm `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') allc nocons family(binom) link(logit) trace from(`est') eval + tempname u + qui gllapred `u',u fsample + + forvalues i=1/`nbcovariables' { + local tmp:word `i' of `covariables' + qui replace `u'm1=`u'm1+`betacov'[1,`i']*(`tmp')/*+`mean`covariable`i''')*/ + } + tempname theta sdtheta + matrix `theta'=J(1,`=`nbitems'+1',0) + matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',0) + qui su `u'm1 if `rep'1==-1 + local vartheta=r(Var) + qui gen `u's2=`u's1^2 + qui su `u's2 if `rep'1==-1 + local meanse2=r(mean) + local psi=1-`meanse2'/(`meanse2'+`vartheta') + forvalues s=0/`nbitems' { + qui su `u'm1 if `realscore'==`s' + local theta`s'=r(mean) + qui su `u's1 if `realscore'==`s' + local sdtheta`s'=r(mean) + matrix `theta'[1,`=`s'+1']=`theta`s'' + matrix `sdtheta'[`=`s'+1',`=`s'+1']=`sdtheta`s'' + } + if "`genlt'"!="" { + tempfile ltsave ltsavetmp + qui save `ltsavetmp', replace + qui keep if `rep'1==-1 + qui keep `u'm1 `u's1 `id' + qui sort `id' + qui save `ltsave' + qui use `ltsavetmp' + } +} + +forvalues i=1/`nbitems' { + if `i'==`nbitems'&"`method'"=="cml"&"`meandiff'"=="" { + local beta`i'=0 + local sd`i' . + local fixed`i' "*" + } + else { + local beta`i'=`coef'[1,`i'] + local sd`i'=sqrt(`var'[`i',`i']) + } + qui replace `diff'=-`beta`i'' if `item'==`i' +} + +/*********************************************************************************************************** +COMPARISON OF TWO POPULATIONS +***********************************************************************************************************/ + +if "`comp'"!=""&"`method'"!="cml" { + if "`trace'"!="" { + di in green "*** Test of comparison of two populations" + } + qui inspect `comp' + local unique=r(N_unique) + if `unique'== 2 { + qui su `comp' + local mincomp=r(min) + local maxcomp=r(max) + tempname bmin bmax + qui xtlogit `rep' if `comp'==`mincomp',offset(`diff') i(`id') + matrix `bmin'=e(b) + local meanmin=`bmin'[1,1] + local varmin=e(sigma_u)^2 + local llmin=e(ll) + local Nmin=e(N_g) + qui xtlogit `rep' if `comp'==`maxcomp',offset(`diff') i(`id') + matrix `bmax'=e(b) + local meanmax=`bmax'[1,1] + local varmax=e(sigma_u)^2 + local llmax=e(ll) + local Nmax=e(N_g) + local Zcomp=(`meanmin'-`meanmax')/sqrt(`varmin'/`Nmin'+`varmax'/`Nmax') + local pvalue=1-norm(abs(`Zcomp')) + } + else { + di "It is impossible to compare more than two populations" + di "The comparison process is not run" + local comp + } +} + +/*********************************************************************************************************** +ESTIMATION OF THE ABILITY PARAMETERS / CML +************************************************************************************************************/ +if `nbitems'>=2 { + if "`trace'"!="" { + di in green "*** Estimation of the ability parameters" + } + if "`method'"=="cml" { + tempfile verytmp + qui save `verytmp',replace + drop _all + qui set obs 20001 + qui gen theta=(_n-10001)/1000 + qui gen A=1 + forvalues j=1/`nbitems' { + qui gen u`j'=exp(theta-`beta`j'') + qui gen p`j'=u`j'/(1+u`j') + qui gen a`j'=1/u`j' + qui replace A=A*a`j' + qui gen i`j'=u`j'/(1+u`j')^2 + qui gen j`j'=(u`j'*(1-u`j'))/(1+u`j')^3 + } + qui egen P=rsum(p*) + qui egen I=rsum(i*) + qui egen J=rsum(j*) + qui gen V=1/I^2*(I+J^2)/(4*I^2) + qui gen V2=1/I + tempname theta sdtheta + matrix `theta'=J(1,`=`nbitems'+1',0) + matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',.) + forvalues s=0/`nbitems' { + qui gen f`s'=abs(`s'-P+.5*J/I) + qui sort f`s' + matrix `theta'[1,`=`s'+1']=theta[1] + matrix `sdtheta'[`=`s'+1',`=`s'+1']=sqrt(V2[1]) + } + use "`verytmp'",replace + } + qui gen `tl'=0 + forvalues s=0/`nbitems' { + local theta`s'=`theta'[1,`=`s'+1'] + qui replace `tl'=`theta`s'' if `realscore'==`s' + local sdtheta`s'=`sdtheta'[`=`s'+1',`= `s'+1'] + } + tempname pred + qui gen `pred'=log(exp(`rep'*(`tl'+`diff'))/(1+exp(`tl'+`diff'))) + + qui su `pred' + local globalll=r(sum) + + local nulscore=0 + forvalues i=1/`=`nbgroups'-1' { + qui count if `score'==`i'&`item'==1 + local nbscore`i'=r(N) + if `nbscore`i''==0 { + local nulscore=1 + } + } + if `nulscore' { + di in green "{p}At least one group of scores concerns none individuals. Tests will be not computed.{p_end}" + di in green "{p}Use the {hi:group} or the {hi:autogroup} options.{p_end}" + local test "NONE" + local details + local icc + local fitgraph + local splittest + } + forvalues i=0/`nbitems' { + qui count if `realscore'==`i'&`item'==1 + local nbrealscore`i'=r(N) + } +} + +/*********************************************************************************************************** +TESTS OF THE FIRST ORDER +************************************************************************************************************/ + +tempname Pi +matrix define `Pi'=J(`nbitems',`=`nbitems'-1',0) +if "`test'"!="NONE" { + qui drop if `score'==. + if "`trace'"!="" { + di in green "*** Tests of the first order" + } + tempname Obs Obs2 Th Th2 + + matrix define `Obs'=J(`nbitems',`=`nbitems'-1',0) + matrix define `Obs2'=J(`nbitems',`=`nbgroups'-1',0) + matrix define `Th'=J(`nbitems',`=`nbitems'-1',0) + matrix define `Th2'=J(`nbitems',`=`nbgroups'-1',0) + local listofitemsc + + /* Estimation of the gamma symetrical functions*/ + local c0 "1" + local c`nbitems' "`nbitems'*x" + forvalues j=1/`nbitems' { + local listini`j' + local listofitemsc "`listofitemsc' `beta`j''" + local c0 `c0'*(1+exp(x-`beta`j'')) + local c`nbitems' `c`nbitems''-`beta`j'' + forvalues k=1/`nbitems' { + local listini`j'k`k' + if `k'!=`j' { + local listini`j' "`listini`j'' `beta`k''" + } + forvalues l=1/`nbitems' { + if `l'!=`j'&`l'!=`k' { + local listini`j'k`k' "`listini`j'k`k'' `beta`l''" + } + } + } + } + + gammasym `listofitemsc' + + /*Estimation, for each value of the score s of the probability to respond to each item (Pi) and of the theorical number of positive responses (Ths) and of theorical number of positive respond per item pair (Ws)*/ + forvalues s=1/`nbitems' { + local denom`s'=r(gamma`s') + tempname W`s' + matrix define `W`s''=J(`nbitems',`nbitems',0) + } + tempvar prob prob2 z y v z2 y2 v2 c r q e + qui gen `prob'=. + qui gen `prob2'=. + forvalues j=1/`nbitems' { + forvalues s=1/`=`nbitems'-1' { + qui count if `rep'==1&`item'==`j'&`realscore'==`s' + matrix `Obs'[`j',`s']=r(N) + if "`test'"!="WP" { + gammasym `listini`j'' + local num`j'=r(gamma`=`s'-1') + if "`method'"=="cml"|"`test'"=="Q" { + matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s'' + } + else { + gausshermite exp(`s'*x)/(`c0'), sigma(`sig') + local int`s'=r(int) + if "`test'"=="R"&`nbrealscore`s''!=0{ + local tmp=exp(-`beta`j'')*`num`j''*`int`s''*`nbind'/`nbrealscore`s'' + matrix `Pi'[`j',`s']=`tmp' + } + else if `nbrealscore`s''==0 { + matrix `Pi'[`j',`s']=0 + } + } + if "`test'"=="R" { + forvalues k=`=`j'+1'/`nbitems' { + if `s'>=2 { + gammasym `listini`j'k`k'' + local num`j'k`k'=r(gamma`=`s'-2') + if "`method'"=="cml" { + matrix `W`s''[`j',`k']=`nbrealscore`s''*exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''/`denom`s'' + } + else { + matrix `W`s''[`j',`k']=exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''*`int`s''*`nbind' + } + matrix `W`s''[`k',`j']=`W`s''[`j',`k'] + } + } + } + } + else if "`test'"=="WP" { + matrix `Pi'[`j',`s']=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) + } + matrix `Th'[`j',`s']=`Pi'[`j',`s']*`nbrealscore`s'' + qui replace `prob'=`Pi'[`j',`s'] if `realscore'==`s'&`item'==`j' + qui replace `prob2'=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) if `realscore'==`s'&`item'==`j' + matrix `W`s''[`j',`j']=`nbrealscore`s''*`Pi'[`j',`s'] + if "`test'"!="R" { + matrix `W`s''[`j',`j']=`W`s''[`j',`j']*abs(1-`Pi'[`j',`s']) + } + } + } + qui gen `v2'=abs(`prob'*(1-`prob')) + qui gen `z2'=(`rep'-`prob')^2 + qui gen `y2'=`z2'/`v2' + qui gen `c'=abs(`prob'*(1-`prob')*(`prob'^3+(1-`prob')^3)) + qui gen `r'=`c'/(`v2')^2 + qui gen `e'=`c'-(`v2')^2 + + forvalues j=1/`nbitems' { + qui su `y2' if `item'==`j' + local outfit`j'=r(mean) + qui su `r' if `item'==`j' + local Voutfit`j'=r(sum) + local Voutfit`j'=`Voutfit`j''/(`nbind')^2-1/`nbind' + local outfitstd`j'=(`outfit`j''^(1/3)-1)*(3/sqrt(`Voutfit`j''))-sqrt(`Voutfit`j'')/3 + + qui su `z2' if `item'==`j' + local n=r(sum) + qui su `v2' if `item'==`j' + local d=r(sum) + local infit`j'=`n'/`d' + qui su `e' if `item'==`j' + local sume=r(sum) + local Vinfit`j'=`sume'/(`d')^2 + local infitstd`j'=(`infit`j''^(1/3)-1)*(3/sqrt(`Vinfit`j''))-sqrt(`Vinfit`j'')/3 + } + tempname tmp stattest testitems + + /*Estimation, by scores group g, of the theorical number of positive response (Th2g) and of the positive respond to each items pair (W2g)*/ + scalar `stattest'=0 + forvalues g=1/`=`nbgroups'-1' { + tempname W2`g' d2`g' + matrix define `W2`g''=J(`nbitems',`nbitems',0) + forvalues s=`liminf`g''/`limsup`g'' { + forvalues j=1/`nbitems' { + matrix `Obs2'[`j',`g']=`Obs2'[`j',`g']+`Obs'[`j',`s'] + matrix `Th2'[`j',`g']=`Th2'[`j',`g']+`Th'[`j',`s'] + if "`test'"=="R" { + forvalues k=`=`j'+1'/`nbitems' { + matrix `W2`g''[`j',`k']=`W2`g''[`j',`k']+`W`s''[`j',`k'] + matrix `W2`g''[`k',`j']=`W2`g''[`j',`k'] + } + } + matrix `W2`g''[`j',`j']=`W2`g''[`j',`j']+`W`s''[`j',`j'] + } + } + + /*Estimation of the d2g vectors*/ + matrix `d2`g''=`Obs2'[1..`nbitems',`g']-`Th2'[1..`nbitems',`g'] + + /*Estimation of the influences on the test of each item (testitemsg matrix) and of the test statistic (stattest)*/ + tempname test`g' testitems`g' + matrix `test`g''=`d2`g'''*syminv(`W2`g'')*`d2`g'' + capture matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g'' + if _rc!=0 { + matrix `tmp'=J(`nbitems',`nbitems',0) + forvalues j=1/`nbitems' { + matrix `tmp'[`j',`j']=`W2`g''[`j',`j'] + } + di in green "Group `g' (`liminf`g''/`limsup`g''): The weight matrix is not positive-definite, the diagonal matrix is used to estimate the contribution of the items on the `wpname' statistic" + matrix list `tmp' + matrix `testitems`g''=cholesky(syminv(`tmp'))*`d2`g'' + } + else { + matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g'' + } + scalar `stattest'=`stattest'+`test`g''[1,1] + } + matrix `testitems'=J(`nbitems',1,0) + forvalues j=1/`nbitems' { + forvalues g=1/`=`nbgroups'-1' { + matrix `testitems'[`j',1]=`testitems'[`j',1]+`testitems`g''[`j',1]^2 + } + } + + /*Adaptation for the Q1 statistic*/ + if "`test'"=="Q" { + scalar `stattest'=`stattest'*`=`nbitems'-1'/`nbitems' + } + + /*Correction for R1m and Q1m*/ + if ("`test'"=="R"|"`test'"=="Q")&("`method'"=="mml"|"`method'"=="gee") { + local c`nbitems' exp(`c`nbitems'')/(`c0') + local c0 1/(`c0') + gausshermite `c0', sigma(`sig') + local ci0=r(int)*`nbind' + gausshermite `c`nbitems'',sigma(`sig') + local ci`nbitems'=`nbind'*r(int) + scalar `stattest'=`stattest'+(`nbrealscore0'-`ci0')^2/`ci0'+(`nbrealscore`nbitems''-`ci`nbitems'')^2/`ci`nbitems'' + } + + + +/*********************************************************************************************************** +TESTS U +************************************************************************************************************/ + + if "`method'"=="cml" { + if "`trace'"!="" { + di in green "*** Tests U" + } + + local quartile=`nbind'/4 + local c1=0 + local n1=0 + while `n1'<`quartile' { + local c1=`c1'+1 + local n1=`n1'+`nbrealscore`c1'' + } + local c2=`nbitems' + local n2=0 + while `n2'<`quartile' { + local c2=`c2'-1 + local n2=`n2'+`nbrealscore`c2'' + } + forvalues j=1/`nbitems' { + local zu1=0 + local zu2=0 + forvalues s=1/`c1' { + local zu1=`zu1'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s'])) + } + forvalues s=`c2'/`=`nbitems'-1' { + local zu2=`zu2'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s'])) + } + local U`j'=(`zu1'-`zu2')/sqrt(`c1'+`nbitems'-`c2') + } + } + + + +/*********************************************************************************************************** +TESTS OF THE SECOND ORDER /*undocumented in beta test*/ +************************************************************************************************************/ + + if "`q2'"!="" { + if "`trace'"!="" { + di in green "*** Tests of the second order" + } + + tempfile Q2file + qui save "`Q2file'",replace + qui use "`saveraschtest'",replace + + qui keep if `touse'==1 + gen `score'=0 + + forvalues i=1/`nbitems' { + local Q2i`i' + rename ``i'' `rep'`i' + qui replace `score'=`score'+`rep'`i' + } + qui recode `score' `recode' + + forvalues i=1/`nbitems' { + local Q2i`i'=0 + forvalues j=`=`i'+1'/`nbitems' { + local listinci`i'j`j' + forvalues k=1/`nbitems' { + if `k'!=`i'&`k'!=`j' { + local listinci`i'j`j' "`listinci`i'j`j'' `beta`k''" + } + } + } + } + + local Q2tot=0 + forvalues k=2/`=`nbitems'-1' { + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + if `k'==1 { + local num=0 + } + else { + gammasym `listinci`i'j`j'' + local num=r(gamma`=`k'-2') + } + local athi`i'j`j'k`k'=exp(-`beta`i'')*exp(-`beta`j'')*`num'/`denom`k'' + local bthi`i'j`j'k`k'=`nbth`i's`k''-`athi`i'j`j'k`k'' + local cthi`i'j`j'k`k'=`nbth`j's`k''-`athi`i'j`j'k`k'' + local dthi`i'j`j'k`k'=1-`athi`i'j`j'k`k''-`bthi`i'j`j'k`k''-`cthi`i'j`j'k`k'' + } + } + } + forvalues k=1/`=`nbgroups'-1' { + local Q2`k'=0 + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`j'+1'/`nbitems' { + qui count if `rep'`i'==1&`rep'`j'==1&`score'==`k' + local aempi`i'j`j'k`k'=r(N) + local ath2i`i'j`j'k`k'=0 + local bth2i`i'j`j'k`k'=0 + local cth2i`i'j`j'k`k'=0 + local dth2i`i'j`j'k`k'=0 + } + } + if `limsup`k''!=1 { + forvalues l=`liminf`k''/`limsup`k'' { + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + if `l'!=1 { + local ath2i`i'j`j'k`k'=`ath2i`i'j`j'k`k''+`athi`i'j`j'k`l''*`nbrealscore`l'' + local bth2i`i'j`j'k`k'=`bth2i`i'j`j'k`k''+`bthi`i'j`j'k`l''*`nbrealscore`l'' + local cth2i`i'j`j'k`k'=`cth2i`i'j`j'k`k''+`cthi`i'j`j'k`l''*`nbrealscore`l'' + local dth2i`i'j`j'k`k'=`dth2i`i'j`j'k`k''+`dthi`i'j`j'k`l''*`nbrealscore`l'' + } + } + } + } + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + local d2i`i'j`j'k`k'=(`aempi`i'j`j'k`k''-`ath2i`i'j`j'k`k'')^2 + local Q2i`i'j`j'k`k'=`d2i`i'j`j'k`k''/`ath2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`bth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`cth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`dth2i`i'j`j'k`k'' + local Q2i`i'=`Q2i`i''+`Q2i`i'j`j'k`k'' + local Q2i`j'=`Q2i`j''+`Q2i`i'j`j'k`k'' + local Q2`k'=`Q2`k''+`Q2i`i'j`j'k`k'' + } + } + } + local Q2tot=`Q2tot'+`Q2`k'' + } + forvalues i=1/`nbitems' { + di in green "Item ``i'' : Q2 = `Q2i`i''" + } + local Q2=`Q2tot'*(`nbitems'-3)/(`nbitems'-1) + di in green "Q2 = `Q2tot'" + qui use "`Q2file'",replace + } + +/*********************************************************************************************************** +TEST LR Z +************************************************************************************************************/ + + if "`method'"=="cml" { + if "`trace'"!="" { + di in green "*** Tests LR of Andersen" + } + local ssll=0 + tempfile Zfile + qui save "`Zfile'", replace + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + gen `score'=0 + forvalues j=1/`nbitems' { + qui replace `score'=`score'+``j'' + } + qui recode `score' `recode' `nbitems'=`nbgroups' + forvalues i=1/`=`nbgroups'-1' { + if `effscore`i''>0 { + qui raschtestv7 `varlist' if `score'==`i', test(NONE) `ld' id(`id') + local ll`i'=r(cll) + local ssll=`ssll'+(`ll`i'') + } + } + local Z=2*`ssll'-2*`ll' + use "`Zfile'",replace + tempname AndersenZ + matrix define `AndersenZ'=(`Z',`=(`nbgroups'-2)*(`nbitems'-1)',1-chi2(`=(`nbitems'-1)*(`nbgroups'-2)',`Z')) + } +} + + +/*********************************************************************************************************** +DISPLAYING RESULTS WITH TESTS +************************************************************************************************************/ +if "`html'" != "" { + di "" +} + +if "`test'"!="NONE" { + local conttest= "_c" +} +di +tempname itemfit globalfit +matrix `globalfit'=J(1,3,0) +if "`method'"=="cml" { + if "`html'" == "" { + di in green "Estimation method: " in yellow "Conditional maximum likelihood (CML)" + } + else { + di "

Estimation method: Conditional maximum likelihood (CML)

" + } + local nbtest=`nbgroups'-1 + local line=77 +} +else if "`method'"=="mml"{ + if "`html'" == "" { + di in green "Estimation method: " in yellow "Marginal maximum likelihood (MML)" + } + else { + di "

Estimation method: Marginal maximum likelihood (MML)

" + } + local nbtest=`nbgroups'+1 + local line=70 +} +else if "`method'"=="gee" { + di in green "Estimation method: " in yellow "Generalized Estimating Equations (GEE)" + local nbtest=`nbgroups'+1 + local line=70 +} +if "`test'"=="NONE" { + local line=35 +} + +if "`html'" == "" { + di in green "Number of items: " in yellow `nbitems' + di in green "Number of groups: " in yellow `=`nbgroups'+1' `conttest' + if "`test'"!="NONE" { + di in green " (" in yellow "`nbtest'" in green " of them are used to compute the statistics of test)" + } +} +else { + di "Number of items: " `nbitems' "
" + di "Number of groups: " `=`nbgroups'+1' `conttest' + if "`test'"!="NONE" { + di " (`nbtest' of them are used to compute the statistics of test)" + } + di "
" +} +if "`method'"=="cml" { + local nbind=`nbind'+`effscore0'+`effscore`nbgroups'' + local cont "_c" + matrix `itemfit'=J(`nbitems',6,0) +} +else { + local cont + matrix `itemfit'=J(`nbitems',5,0) +} +local missing=`N'-`nbind' +if "`html'" == "" { + di in green "Number of individuals: " in yellow `N' + di in green "Number of individuals with missing values: " in yellow `nbindmiss' _c + if "`ld'"=="" { + di in green " (removed)" + } + else { + di + } + di in green "Number of individuals with nul or perfect score: " in yellow `=`effscore0'+`effscore`nbgroups''' +} +else { + di "Number of individuals: `N'
" + di "Number of individuals with missing values: " `nbindmiss' + if "`ld'"=="" { + di " (removed)" + } + di "
" + di "Number of individuals with nul or perfect score: " `=`effscore0'+`effscore`nbgroups''' "
" +} +if "`method'"=="cml" { + if "`html'" == "" { + di in green "Conditional log-likelihood: " in yellow %-13.4f `ll' + di in green "Log-likelihood: " in yellow %-13.4f `globalll' + } +} +else { + if "`html'" == "" { + di in green "Marginal log-likelihood: " in yellow %-13.4f `ll' + di in green "Log-likelihood: " in yellow %-13.4f `globalll' + di + } + else { + di "Marginal log-likelihood: " %-13.4f `ll' "
" + di "Log-likelihood: " %-13.4f `globalll' "

" + } +} + +if "`html'" == "" { + noi di in green _col(16) "Difficulty" `conttest' + if "`test'"!="NONE" { + di in green _col(58) "Standardized" + } + noi di in green _col(9) "Items" _col(16) "parameters" _col(28) "std Err." `conttest' + if "`test'"!="NONE" { + local varin=int(2/sqrt(`nbind')*100)/100 + local varout=int(6/sqrt(`nbind')*100)/100 + di _col(41) "`namewp'" _col(47) "df" _col(50) "p-value" _col(58) "Outfit" _col(66) "Infit" `cont' + if "`method'"=="cml" { + di in green _col(77) "U" + } + } + di in green "{hline `line'}" +} +else { + di "" + di "" + di "" + if "`test'"!="NONE" { + di "" + } + di "" + di "" + if "`test'"!="NONE" { + local varin=int(2/sqrt(`nbind')*100)/100 + local varout=int(6/sqrt(`nbind')*100)/100 + di "" + if "`method'"=="cml" { + di "" + } + } + di "" +} + +forvalues i=1/`nbitems' { + if "`html'" == "" { + noi di in yellow _col(3) %12s abbrev("``i''`fixed`i''" ,12) in yellow _col(18) %8.5f `beta`i'' _col(29) %6.5f `sd`i'' `conttest' + } + else { + di "" + } + if "`test'"!="NONE" { + if "`html'" == "" { + di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfitstd`i'' _col(65) %6.3f `infitstd`i'' /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/ `cont' + } + else { + di "" + } + matrix `itemfit'[`i',1]=`testitems'[`i',1] + matrix `itemfit'[`i',2]=`=`nbgroups'-2' + matrix `itemfit'[`i',3]=1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) + matrix `itemfit'[`i',4]=`outfitstd`i'' + matrix `itemfit'[`i',5]=`infitstd`i'' + if "`method'"=="cml" { + if "`html'" == "" { + di in ye _col(72) %6.3f `U`i'' + } + else { + di "" + } + matrix `itemfit'[`i',6]=`U`i'' + } + if "`html'" != "" { + di "" + } + } +} +if "`html'" == "" { + di in green "{hline `line'}" +} +else { + di "" +} +if "`test'"!="NONE" { + if "`method'"=="cml" { + local df=(`nbgroups'-2)*(`nbitems'-1) + } + else { + local df=(`nbgroups'-1)*(`nbitems'-1)-1 + } + matrix `globalfit'=(`stattest',`df',1-chi2(`df',`stattest')) + if "`html'" == "" { + noi di in green _col(6) "`descwp'" _col(32) in gr "`namewp'=" _col(36) in ye %8.3f `globalfit'[1,1] _col(46) %3.0f `globalfit'[1,2] _col(51) %6.4f `globalfit'[1,3] + if "`method'"=="cml" { + noi di in green _col(6) "Andersen LR test" _col(34) "Z=" in yellow _col(36) %8.3f `AndersenZ'[1,1] _col(46) %3.0f `AndersenZ'[1,2] _col(51) %6.4f `AndersenZ'[1,3] + } + di in green "{hline `line'}" + } + else { + di "" + if "`method'"=="cml" { + di "" + } + di "
DifficultyStandardized
Itemsparametersstd Err.`namewp'dfp-valueOutfitInfitU
" %12s abbrev("``i''`fixed`i''" ,12) "" %8.5f `beta`i'' "" %6.5f `sd`i'' "" %8.3f `testitems'[`i',1] "" %3.0f `=`nbgroups'-2' "" %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) "" %6.3f `outfitstd`i'' "" %6.3f `infitstd`i'' "" %6.3f `U`i'' "
`descwp'`namewp'=" %8.3f `globalfit'[1,1] "" %3.0f `globalfit'[1,2] "" %6.4f `globalfit'[1,3] "
Andersen LR testZ=" %8.3f `AndersenZ'[1,1] "" %3.0f `AndersenZ'[1,2] "" %6.4f `AndersenZ'[1,3] "
" + } +} + +if "`html'" == "" { + if "`method'"=="cml"&"`meandiff'"==""{ + di in green "*: The difficulty parameter of this item had been fixed to 0" + } + if "`method'"=="cml"&"`meandiff'"!=""{ + di in green "The mean of the difficulty parameters is fixed to 0" + } + if `smallgroup'==1&"`test'"!="NONE" { + di in green "You have groups of scores with less than 30 individuals. The tests can be invalid." + } + if "`method'"!="cml"&"`test'"=="Q" { + di in green "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test." + } + + di +} +else { + if "`method'"=="cml"&"`meandiff'"==""{ + di "*: The difficulty parameter of this item had been fixed to 0
" + } + if "`method'"=="cml"&"`meandiff'"!=""{ + di "The mean of the difficulty parameters is fixed to 0
" + } + if `smallgroup'==1&"`test'"!="NONE" { + di "You have groups of scores with less than 30 individuals. The tests can be invalid.
" + } + if "`method'"!="cml"&"`test'"=="Q" { + di "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test.
" + } + di "

" +} + +if "`html'" == "" { + if "`method'"!="cml" { + di in green "{hline 56}" + noi di in green _col(5) "Parameters" _col(21) "Coef." _col(28) "std Err." _col(43) "z" _col(52) "P>|z|" + di in green "{hline 56}" + local zsig=`sig'/`sesig' + local pzsig=2*(1-norm(abs(`zsig'))) + di in green _col(10) in yellow "Sigma" _col(18) %8.5f `sig' _col(29) %6.5f `sesig' _col(38) %6.3f `zsig' _col(50) %7.4f `pzsig' + di in green "{hline 56}" + } +} +else { + if "`method'"!="cml" { + di "" + di "" + di "" + local zsig=`sig'/`sesig' + local pzsig=2*(1-norm(abs(`zsig'))) + di "
ParametersCoef.std Err.zP>|z|
Sigma" %8.5f `sig' "" %6.5f `sesig' "" %6.3f `zsig' "" %7.4f `pzsig' "
" + } +} + + + +*set trace on +if "`covariables'"!="" { + tempname zcovariates pcovariates + matrix `zcovariates'=J(1,`nbcovariables',0) + matrix `pcovariates'=J(1,`nbcovariables',0) + forvalues i=1/`nbcovariables' { + local tmp :word `i' of `covariables' + local zcov=`betacov'[1,`i']/`Vbetacov'[`i',`i']^.5 + local pzcov=2*(1-norm(abs(`zcov'))) + matrix `zcovariates'[1,`i']=`zcov' + matrix `pcovariates'[1,`i']=`pzcov' + di in green _col(3) %12s in yellow abbrev("`tmp'",12) _col(18) %8.5f `betacov'[1,`i'] _col(29) %6.5f `Vbetacov'[`i',`i']^.5 _col(38) %6.3f `zcov' _col(50) %7.4f `pzcov' + } + di in green "{hline 56}" + local difficulties2 + if "`difficulties'"!="" { + local difficulties2 diff(`difficulties') + } + if "`ss1'"!="" { + tempfile ss1save + qui save `ss1save' + qui use `saveraschtest' + qui keep if `touse'==1 + + qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2' + local sigma0=r(sigma) + local var0=`sigma0'^2 + local nbobs=r(N_obs) + *di "nbobs=`nbobs'" + local df0=`nbobs'-(`nbitems'+1)-1 + local ss10=`var0'*(`df0') + local ss1c0=0 + di + di in green "Type 1 Sum of Squares (sequential)" + di "{hline 85}" + di in green _col(44) "Degrees" _col(56) "Variance of the" _col(77) "Explained" + di in green _col(4) "Covariates" _col(25) "SS" _col(35) "Diff" _col(41) "of freedom"_col(59) "latent trait" _col(78) "Variance" + di "{hline 85}" + di _col(10) in green "None" _col(15) in ye %12.3f `ss10' _col(47) %4.0f `df0' _col(63) %8.3f `var0' + di in green "{dup 85:-}" + local covariablesss1 + forvalues i=1/`nbcovariables' { + local covariablesss1 `covariablesss1' `covariable`i'' + qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss1') test(none) `ld' `difficulties2' + local nbobs=r(N_obs) + local sigma`i'=r(sigma) + local var`i'=`sigma`i''^2 + local nbcovtmp:word count `covariablesss1' + *di " ss1`i'=`var`i''*`=`nbobs'-(`nbitems'+1+`nbcovtmp')-1'" + local df`i'=`nbobs'-(`nbitems'+1+`nbcovtmp')-1 + *di "local df`i'=`nbobs'-(`nbitems'+1+`nbcovtmp')-1 (cov:`covariablesss1')" + local ss1`i'=`var`i''*`df`i'' + *di "cov : `covariablesss1' var=`var`i'' df=`df`i''" + di _col(2) %12s in yellow abbrev("`covariable`i''",12) _col(15) %12.3f in ye `ss1`i'' _col(25) %12.3f `=`ss1`=`i'-1''-`ss1`i''' _col(47) %4.0f `df`i'' _col(63) %8.3f `var`i'' _col(81) %5.3f (`=`ss1`=`i'-1''-`ss1`i''')/`ss10' + } + di in green "{hline 85}" + qui use `ss1save' + } + if "`ss3'"!="" { + tempfile ss3save + qui save `ss3save' + qui use `saveraschtest' + qui keep if `touse'==1 + if "`ss1'"=="" { + qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2' + local sigma0=r(sigma) + local var0=`sigma0'^2 + local nbobs=e(N_obs) + local df0=`nbobs'-(`nbitems'+1)-1 + local ss30=`var0'*(`df0') + } + else { + local ss30=`ss10' + } + local ss3ref=`=`sig'^2*(`df0'-`nbcovariables')' + di + di in green "Type 3 Sum of Squares " + di "{hline 85}" + di in green _col(44) "Degrees" _col(56) "Variance of the" _col(77) "Explained" + di in green _col(4) "Covariates" _col(25) "SS" _col(35) "Diff" _col(41) "of freedom"_col(59) "latent trait" _col(78) "Variance" + di "{hline 85}" + di _col(10) in green "None" _col(15) in ye %12.3f `ss30' _col(47) %4.0f `df0' _col(63) %8.3f `var0' + di _col(6) in green "Complete" _col(15) in ye %12.3f `ss3ref' _col(25) %12.3f `=`ss30'-`ss3ref'' _col(47) %4.0f `=`df0'-`nbcovariables'' _col(63) %8.3f `sig'^2 _col(81) %5.3f 1-`sig'^2*(`df0'+`nbcovariables')/`ss30' + di in green "{dup 85:-}" + forvalues i=1/`nbcovariables' { + local covariablesss3 + forvalues j=1/`nbcovariables' { + if `i'!=`j' { + local covariablesss3 `covariablesss3' `covariable`j'' + } + } + qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss3') test(none) `ld' `difficulties2' + *ereturn list + local sigmas`i'=r(sigma) + local vars`i'=`sigmas`i''^2 + local nbobs=e(N) + local dfs`i'=`nbobs'-(`nbitems'+1)-1-(`nbcovariables'-1) + *di "local dfs`i'=`nbobs'-(`nbitems'+1)-1-(`nbcovariables'-1)" + local ss3s`i'=`vars`i''*`dfs`i'' + local vara`i'=`sig'^2 + local dfa`i'=`nbobs'-(`nbitems'+1)-1-`nbcovariables' + local ss3a`i'=`vara`i''*`dfa`i'' + *di "cov : `covariablesss3' var=`vars`i'' df=`dfs`i''" + di _col(2) %12s in green abbrev("`covariable`i''",12) _col(15) in ye %12.3f `ss3s`i'' _col(25) %12.3f in ye `=`ss3s`i''-`ss3a`i''' _col(47) %4.0f `=`df0'-`nbcovariables'+1' _col(63) %8.3f `vars`i'' _col(80) %6.3f (`=`ss3s`i''-`ss3a`i''')/`ss30' + } + di in green "{hline 85}" + qui use `ss3save' + } +} + + + +/*Tabular of the estimated values of the latent trait*/ + +if "`covariables'"=="" { + if "`html'" == "" { + di + di + noi di in green _col(33) "Ability" _col(60) "Expected" + noi di in green _col(17) "Group" _col(23) "Score" _col(30) "parameters" _col(42) "std Err." _col(54) "Freq." _col(63) "Score"_c + if "`method'"=="cml"&"`test'"!="NONE" { + noi di in green _col(75) "ll" + } + else { + noi di "" + } + if "`method'"=="cml"&"`test'"!="NONE" { + local line=62 + } + else { + local line=51 + } + di in green _col(17) "{hline `line'}" + } + else { + di "" + di "" + di "" + if "`method'"=="cml"&"`test'"!="NONE" { + di "" + } + di "" + } + + local nonul=0 + forvalues g=0/`nbgroups' { + if `g'!=0 { + if "`html'" == "" { + di in green _col(17) "{dup `line':-}" + } + } + forvalues s=`liminf`g''/`limsup`g'' { + if `s'==`liminf`g'' { + local tmp `ll`g'' + local gr `g' + } + else { + local tmp + local gr + } + local expscore`nonul'=0 + forvalues i=1/`nbitems' { + local expscore`nonul'=`expscore`nonul''+1/(1+exp(-`theta`nonul''+`beta`i'')) + } + if "`method'"=="cml" { + local format1 %8.3f + } + else { + local format1 %8.5f + } + if "`html'" == "" { + noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(32) `format1' `theta`nonul'' _col(42) `format1' `sdtheta`nonul'' _col(55) %4.0f `nbrealscore`s'' _col(64) % 4.2f `expscore`nonul'' _col(68) %11.4f `tmp' + } + else { + di "" + } + local nonul=`nonul'+1 + } + } + if "`html'" == "" { + di in green _col(17) "{hline `line'}" + } + else { + di "
GroupScoreAbility
parameters
std Err.Freq.Expected
Score
ll
" %5s "`gr'" "" %5s "`s'" "" `format1' `theta`nonul'' "" `format1' `sdtheta`nonul'' "" %4.0f `nbrealscore`s'' "" % 4.2f `expscore`nonul'' "" %11.4f `tmp' "
" + } +} + +if "`method'"=="mml"|"`method'"=="gee" { + if "`html'" == "" { + di + *di in green "Variance of the estimated latent trait" _col(45) in ye %10.4f `vartheta' + di in green "Mean variance of the error" _col(45) in ye %10.4f `meanse2' + local sig2=`sig'^2 + di in green "Estimated variance of the latent trait" _col(45) in ye %10.4f `sig2' + local psi2=1-`meanse2'/`sig2' + di in green "Personal Separation Index (PSI)" _col(45) in ye %10.4f `psi2' + di in green "Adjusted PSI on covariates (PSIadj)" _col(45) in ye %10.4f `psi' + } + else { + di "" + di "" + di "" + di "" + local sig2=`sig'^2 + di "" + local psi2=1-`meanse2'/`sig2' + di "" + di "" + di "
Mean variance of the error" %10.4f `meanse2' "
Estimated variance of the latent trait" %10.4f `sig2' "
Personal Separation Index (PSI)" %10.4f `psi2' "
Adjusted PSI on covariates (PSIadj)" %10.4f `psi' "
" + } +} + + +/*********************************************************************************************************** +DETAILS OPTION +************************************************************************************************************/ + +if "`details'"!="" { + if "`html'"=="" { + forvalues g=0/`nbgroups' { + if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" { + di + di in green "{hline 44}" + di in green "Group: " in ye "`g'" in green " from " in ye "`liminf`g''" in green " to " in ye "`limsup`g''" in green " (n=" in ye "`nbscore`g''" in green")" + di + di _col(3) "Item" _col(10) "Observed" _col(23) "Expected" _col(37) "Scaled" + di in green "{dup 44:-}" + } + if `g'!=0&`g'!=`nbgroups' { + forvalues j=1/`nbitems' { + local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j']) + di _col(3) in ye "``j''" _col(14) %4.0f `Obs2'[`j',`g'] _col(25) %6.2f `Th2'[`j',`g'] _col(36) %7.4f `tmp' + } + di in green "{dup 44:-}" + di in green "Contribution to the `namewp' statistics: " %8.4f in ye `test`g''[1,1] + } + else if "`method'"!="cml" { + if `g'==0 { + local h=0 + } + else { + local h=`nbitems' + } + local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'') + di in ye _col(14) %4.0f `nbrealscore`h'' _col(25) %6.2f `ci`h'' _col(36) %7.4f `tmp' + di in green "{dup 44:-}" + local tmp=`tmp'^2 + di in green "Contribution to the `namewp' statistics: " %8.4f in ye `tmp' + } + } + } + else { + forvalues g=0/`nbgroups' { + if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" { + di in gr "" + di in gr "" + di in gr "" + } + if `g'!=0&`g'!=`nbgroups' { + forvalues j=1/`nbitems' { + local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j']) + di "" + } + di "" + } + else if "`method'"!="cml" { + if `g'==0 { + local h=0 + } + else { + local h=`nbitems' + } + local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'') + di "" + local tmp=`tmp'^2 + di "" + } + di "
Group: `g' from `liminf`g'' to `limsup`g'' (n=`nbscore`g'')
ItemObservedExpectedScaled
``j''" %4.0f `Obs2'[`j',`g'] "" %6.2f `Th2'[`j',`g'] "" %7.4f `tmp' "
Contribution to the `namewp' statistics:" %8.4f `test`g''[1,1] "
" %4.0f `nbrealscore`h'' "" %6.2f `ci`h'' "" %7.4f `tmp' "
Contribution to the `namewp' statistics:" %8.4f `tmp' "
" + } + } +} + +/*********************************************************************************************************** +OPTION ICC +************************************************************************************************************/ +*set trace on +if "`icc'"!="" { + if "`trace'"!="" { + di in green "*** Items Characteristic Curves" + } + tempvar proba propemp propth propthb + qui replace `tl'=. if `realscore'==0|`realscore'==`nbitems'|`realscore'==. + qui gen `propemp'=. + qui gen `propth'=. + qui gen `propthb'=. + label variable `propth' "Expected ICC" + label variable `propemp' "Observed ICC" + label variable `propthb' "Expected ICC" + label variable `tl' "Latent trait" + global iccs + forvalues i=1/`nbitems' { + forvalues s=1/`=`nbitems'-1' { + qui replace `propthb'=exp(`theta`s''-`beta`i'')/(1+exp(`theta`s''-`beta`i'')) if `item'==`i'&`realscore'==`s' + } + qui replace `propemp'=. + qui replace `propth'=. + tempvar propemp`i' propth`i' + qui bysort `realscore' `item' : egen `propth`i''=mean(`propthb') if `item'==`i' + qui bysort `realscore' `item' : egen `propemp`i''=mean(`rep') if `item'==`i' + qui replace `propth'=`propth`i'' if `item'==`i' + qui replace `propemp'=`propemp`i'' if `item'==`i' + local mintl=floor(`theta1') + local maxtl=floor(`theta`=`nbitems'-1'')+1 + if "`filessave'"!=""{ + local saving "`dirsave'\\icc``i''" + } + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_icc_``i''" + } + if "`v8'"!=""|"`html'"!="" { + graph twoway (line `propemp' `propth' `tl') if `item'==`i' , `htmlregion' name(icc``i'',replace) ytitle("") ylabel(0(.25)1) title("Observed and Expected ICC for the item ``i''") xlabel(`mintl'(1)`maxtl') xsize(12) ysize(9) `draw' + if "`html'"=="" { + pause + } + else { + qui graph save icc``i'' "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_icc_``i''.eps, replace + di " _char(34) " + + } + *set trace on + if "`filessave'"!="" { + qui graph save icc``i'' "`saving'" , `replace' + if "`extension'"!="" { + if "`graphclose'"!="" { + graph close + } + *qui graph use `dirsave'\\icc``i'' + qui graph export `dirsave'\\icc``i''.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + putdocx image `dirsave'\\icc``i''.`extension', width(4) + } + } + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + qui graph `propemp' `propth' `tl' if `item'==`i' , twoway `saving' c(ll) ylabel(0(.25)1) xlabel(`mintl'(1)`maxtl') title("Observed and Expected ICC for the item ``i''") + pause + } + } +} + +/*********************************************************************************************************** +OPTION INFORMATION +************************************************************************************************************/ + +if "`information'"!="" { + if "`trace'"!="" { + di in green "*** Information graph" + } + + tempfile saveinfo + qui save "`saveinfo'",replace + tempvar info latent + forvalues i=1/`nbitems' { + tempvar info``i'' + } + drop _all + qui set obs 2001 + gen `latent'=((_n-1)/1001-1)*3 + label variable `latent' "latent trait" + gen `info'=0 + local gphbyitem + forvalues i=1/`nbitems' { + qui gen `info``i'''=exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2 + label variable `info``i''' "``i''" + qui replace `info'=`info'+exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2 + local gphbyitem `gphbyitem' `info``i''' + } + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_information" + } + if "`v8'"!=""|"`html'"!="" { + *set trace on + local saving "`dirsave'\\information" + graph twoway (line `info' `latent') , `htmlregion' name(information,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the scale") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + qui graph save information "`saving'" , `replace' + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\information + qui graph export `dirsave'\\information.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\information.`extension', width(4) + } + + } + } + if "`html'"=="" { + pause + } + else { + qui graph save information "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_information.eps, replace + di " _char(34) " + } + local saving "`dirsave'\\inf_items" + graph twoway (line `gphbyitem' `latent') , `htmlregion' name(inf_items,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the items") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + qui graph save inf_items "`saving'" , `replace' + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\inf_items + qui graph export `dirsave'\\inf_items.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\inf_items.`extension', width(4) + } + + } + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + if "`filessave'"=="" { + local saving + } + qui graph `info' `latent' , twoway `saving' c(l) xlabel(-3(1)3) title("Information graph of the scale") + pause + } + qui use "`saveinfo'",replace +} + +/*********************************************************************************************************** +OPTION FITGRAPH +************************************************************************************************************/ + +if "`fitgraph'"!="" { + if "`trace'"!="" { + di in green "*** Graphical validation of the fit" + } + *set trace on + tempname outfit meanz2 meanv2 sumd infit Voutfit outfitstd Vinfit infitstd + qui egen `outfit'=mean(`y2'),by(`id') + qui egen `Voutfit'=sum(`r'),by(`id') + qui replace `Voutfit'=`Voutfit'/(`nbitems')^2-1/`nbitems' + qui gen `outfitstd'=(`outfit'^(1/3)-1)*(3/sqrt(`Voutfit'))-sqrt(`Voutfit')/3 + qui egen `meanz2'=sum(`z2'),by(`id') + qui egen `meanv2'=sum(`v2'),by(`id') + qui gen `infit'=`meanz2'/`meanv2' + qui egen `Vinfit'=sum(`e'),by(`id') + qui replace `Vinfit'=`Vinfit'/(`meanv2')^2 + qui gen `infitstd'=(`infit'^(1/3)-1)*(3/sqrt(`Vinfit'))-sqrt(`Vinfit')/3 + + qui su `outfitstd' + local mino=floor(2*min(`r(min)',-2))/2 + local maxo=ceil(2*max(`r(max)',2))/2 + qui su `infitstd' + local mini=floor(2*min(`r(min)',-2))/2 + local maxi=ceil(2*max(`r(max)',2))/2 + if "`filessave'"!=""{ + local savingo "`dirsave'\\outfitind" + local savingi "`dirsave'\\infitind" + } + if "`v8'"!="" { + graph twoway (scatter `outfitstd' `id'), `htmlregion' name(outfit,replace) yline(-2 2) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw' + if "`html'"=="" { + pause + } + graph twoway (scatter `infitstd' `id'), `htmlregion' name(infit,replace) yline(-2 2) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw' + if "`html'"=="" { + pause + } + if "`filessave'"!=""|"`html'"!="" { + qui graph save outfit "`savingo'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_outfit.eps, replace + } + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\outfitind + qui graph export `dirsave'\\outfit.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\outfit.`extension', width(4) + } + + } + qui graph save infit "`savingi'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_infit.eps, replace + } + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\infitind + qui graph export `dirsave'\\infit.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\infit.`extension', width(4) + } + } + } + } + else { + if "`filessave'"!="" { + local savingo "saving(`savingo'" + local savingi "saving(`savingi'" + if "`replace'"=="" { + local savingo "`savingo')" + local savingi "`savingi')" + } + else { + local savingo "`savingo',replace)" + local savingi "`savingi',replace)" + } + } + graph `outfitstd' `id', `savingo' twoway sy(.) c(.) yline(-2 2) title("Outfit indexes") b2title("Individual indexes") l1("") l2title("Outfit") ylabel(`mino'(.5)`maxo') + pause + graph `infitstd' `id', `savingi' twoway sy(.) c(.) yline(-2 2) title("Infit indexes") b2title("Individual indexes") l1("") l2title("Infit") ylabel(`mini'(.5)`maxi') + pause + } + drop _all + qui set obs `nbitems' + tempvar name betap outfitstdj infitstdj + qui gen str9 `name'="" + qui gen `betap'=. + qui gen `outfitstdj'=. + qui gen `infitstdj'=. + local mino=-2 + local maxo=2 + local mini=-2 + local maxi=2 + forvalues j=1/`nbitems' { + qui replace `name'="``j''" in `j' + qui replace `betap'=`beta`j'' in `j' + qui replace `outfitstdj'=`outfitstd`j'' in `j' + qui replace `infitstdj'=`infitstd`j'' in `j' + local mino=floor(min(`mino',`outfitstd`j'')*2)/2 + local mini=floor(min(`mini',`infitstd`j'')*2)/2 + local maxo=ceil(max(`maxo',`outfitstd`j'')*2)/2 + local maxi=ceil(max(`maxi',`infitstd`j'')*2)/2 + } + if "`filessave'"!=""{ + local savingo "`dirsave'\\outfititems" + local savingi "`dirsave'\\infititems" + } + if "`v8'"!="" { + graph twoway (scatter `outfitstdj' `betap',`htmlregion' name(outfititem,replace) mlabel(`name')), yline(-2 2) title("Outfit indexes") xtitle("Difficulty") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw' + if "`html"=="" { + pause + } + graph twoway (scatter `infitstdj' `betap',`htmlregion' name(infititem,replace) mlabel(`name')), yline(-2 2) title("Infit indexes") xtitle("Difficulty") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw' + if "`html"=="" { + pause + } + if "`filessave'"!=""|"`html'"!="" { + qui graph save outfititem "`savingo'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_outfititem.eps, replace + } + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\outfititems + qui graph export `dirsave'\\outfititems.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\outfititems.`extension', width(4) + } + } + qui graph save infititem "`savingi'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_infititems.eps, replace + } + if "`extension'"!="" { + if "`graphclose'"!="" { + qui graph close + } + *qui graph use `dirsave'\\infititems + qui graph export `dirsave'\\infititems.`extension', `replace' + if "`docx'"!="" { + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\infititems.`extension', width(4) + } + + } + } + } + else { + if "`filessave'"!="" { + local savingo "saving(`savingo'" + local savingi "saving(`savingi'" + if "`replace'"=="" { + local savingo "`savingo')" + local savingi "`savingi')" + } + else { + local savingo "`savingo',replace)" + local savingi "`savingi',replace)" + } + } + graph `outfitstdj' `betap', `savingo' twoway c(.) yline(-2 2) title("Outfit indexes") b2title("Difficulty") l1title("") l2title("Outfit") ylabel(`mino'(.5)`maxo') sy([`name']) + pause + graph `infitstdj' `betap', `savingi' twoway c(.) yline(-2 2) title("Infit indexes") b2title("Difficulty") l1title("") l2title("Infit") ylabel(`mini'(.5)`maxi') sy([`name']) + pause + } +} + + +/*********************************************************************************************************** +OPTION SPLITTESTS +************************************************************************************************************/ + +if "`splittests'"!="" { + if "`trace'"!="" { + di in green "*** Splitting tests" + } + forvalues j=1/`nbitems' { + tempname estneg`j' estpos`j' + local listitems + forvalues k=1/`nbitems' { + if `j'!=`k' { + local listitems `listitems' ``k'' + } + } + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + qui raschtestv7 `listitems' if ``j''==0,test(NONE) meth(cml) `ld' id(`id') + matrix `estneg`j''=r(beta) + local llneg=r(cll) + qui raschtestv7 `listitems' if ``j''==1,test(NONE) meth(cml) `ld' id(`id') + matrix `estpos`j''=r(beta) + local llpos=r(cll) + qui raschtestv7 `listitems',test(NONE) meth(cml) `ld' id(`id') + local llnegpos=r(cll) + local nbcol=colsof(`estneg`j'') + local meanneg=0 + local meanpos=0 + forvalues k=1/`nbcol' { + local meanneg=`meanneg'+`estneg`j''[1,`k'] + local meanpos=`meanpos'+`estpos`j''[1,`k'] + } + local meanneg=`meanneg'/`nbitems' + local meanpos=`meanpos'/`nbitems' + forvalues k=1/`nbcol' { + matrix `estneg`j''[1,`k']=`estneg`j''[1,`k']-`meanneg' + matrix `estpos`j''[1,`k']=`estpos`j''[1,`k']-`meanpos' + if "`method'"=="cml" { + matrix `estneg`j''=`estneg`j'',-`meanneg' + matrix `estpos`j''=`estpos`j'',-`meanpos' + } + } + drop _all + qui set obs `=`nbitems'+1' + tempvar neg pos name diag + qui gen `neg'=. + qui gen `pos'=. + qui gen str9 `name'="" + local min=`estneg`j''[1,1] + local max=`estneg`j''[1,1] + forvalues k=1/`=`nbitems'-1' { + qui replace `neg'=`estneg`j''[1,`k'] in `k' + qui replace `pos'=`estpos`j''[1,`k'] in `k' + local min=min(`min',`estneg`j''[1,`k'],`estpos`j''[1,`k']) + local max=max(`max',`estneg`j''[1,`k'],`estpos`j''[1,`k']) + local tmp:word `k' of `listitems' + qui replace `name'="`tmp'" in `k' + } + local min=floor(`min') + local max=floor(`max')+1 + qui gen `diag'=. + qui replace `diag'=`min' in `nbitems' + qui replace `diag'=`max' in `=`nbitems'+1' + local Zgr=round(2*(`llneg'+`llpos'-`llnegpos'),0.001) + local Zgr=substr("`Zgr'",1,6) + local pgr=round(1-chi2(`=`nbitems'-1',`Zgr'),0.0001) + local pgr=substr("`pgr'",1,5) + local note="Z=`Zgr', df=`=`nbitems'-1' , p=`pgr'" + if "`filessave'"!=""{ + local saving "`dirsave'\\split``j''" + } + if "`v8'"!="" { + graph twoway (scatter `pos' `neg' ,mlabel(`name')) (line `diag' `diag'), ytitle("Positive answer") xtitle("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title(Splitting on ``j'') `draw' legend(off) note("Andersen Z test: `note'") name(split,replace) `draw' + pause + if "`filessave'"!="" { + graph save split "`saving'" , `replace' + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + qui replace `diag'=`neg' if `diag'==. + graph `pos' `diag' `diag', `saving' c(.l) sy([`name']i) l1title("") l2title("Positive answer") b2title("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title("Splitting on ``j'' (`note')") `draw' + pause + } + } +} + +/*********************************************************************************************************** +OPTION GRAPH +************************************************************************************************************/ + +if "`graph'"!=""&"`v8'"!="" { + if "`trace'"!="" { + di in green "*** Graph option" + } + tempvar latent2 tl2 delta2 tlth2 labdelta2 labtl2 + drop _all + qui set obs 1001 + gen `latent2'=(_n-501)/100 + label variable `latent2' "latent trait" + qui gen `tl2'=. + qui gen `labtl2'="" + forvalues i=0/`nbitems' { + *if (`i'!=0&`i'!=`nbitems')|"`method'"!="cml" { + qui replace `tl2'=`nbrealscore`i''/`N' if round(`latent2',0.01)==round(`theta`i'',0.01) + qui replace `labtl2'="`i'" if round(`latent2',0.01)==round(`theta`i'',0.01) + *} + } + qui gen `delta2'=. + qui gen `labdelta2'="" + forvalues i=1/`nbitems' { + qui replace `delta2'=-.05 if round(`latent2',0.01)==round(`beta`i'',0.01) + qui replace `labdelta2'="``i''" if round(`latent2',0.01)==round(`beta`i'',0.01) + } + if "`method'"=="mml"|"`method'"=="gee" { + qui gen `tlth2'=1/(2*_pi*`sig')*exp(-.5*(`latent2'/`sig')^2) + label variable `tlth2' "Theorical distribution" + local graphmml line `tlth2' `latent2' + } + label variable `tl2' "Score" + label variable `delta2' "Items" + local saving "`dirsave'\\graph" + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_map" + } + local min=-2 + local max=2 + forvalues j=1/`nbitems' { + if `beta`j''<`min' { + local min=`beta`j''-.5 + } + if `beta`j''>`max'&`beta`j''!=. { + local max=`beta`j''+.5 + } + } + if "`method'"=="cml" { + if `theta0'<`min' { + local min=`theta0'-.5 + } + if `theta`=`nbitems'-1''>`max' { + local max=`theta`=`nbitems'-1''+.5 + } + } + else if "`method'"!="cml" { + if `theta0'<`min'&`theta0'!=. { + local min=`theta0'-.5 + } + if `theta`nbitems''>`max'&`theta`nbitems''!=. { + local max=`theta`nbitems''+.5 + } + } + local min=floor(`min') + local max=floor(`max')+1 + qui su `tl2' + local max2=r(max) + if "`method'"!="cml" { + qui su `tlth2' + local max2=max(`max2',`r(max)') + } + qui replace `latent2'=. if `latent2'<`min'|`latent2'>`max' + if "`v8'"!="" { + graph twoway (bar `tl2' `latent2',/*mlabel(`labtl2')*/ barwidth(.3) ) (dropline `delta2' `latent2',mlabel(`labdelta2') mlabposition(6)) (`graphmml'), `htmlregion' name(graph,replace) ytitle("") xlabel(`min'(1)`max') ylabel(-.1 0(0.05)`max2') title("Individuals/items representations") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + qui graph save graph "`saving'" , `replace' + if "`extension'"!="" { + *qui graph use `dirsave'\\graph + qui graph export `dirsave'\\graph.`extension' , `replace' + if "`docx'"!="" { + putdocx paragraph + putdocx text ("In this dataset, there are `r(N)' models") + + putdocx paragraph, halign(center) + qui putdocx image `dirsave'\\graph.`extension', width(4) + } + if "`graphclose'"!="" { + qui graph close + } + + } + } + if "`html'"=="" { + pause + } + else { + qui graph save graph "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_map.eps, replace + di " _char(34) " + } + } +} +else if "`graph'"!=""&"`v8'"=="" { + di in ye "The graph option is not available with Stata 7" +} + +/*********************************************************************************************************** +COMPARISON OF TWO POPULATION +************************************************************************************************************/ + +if "`comp'"!=""&"`method'"!="cml" { + di + di _col(4) "{hline 30}" + di _col(4) in green "Comparison of two populations" + di _col(4) "{hline 30}" + di + di _col(4) in green "`comp'==`mincomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmin' _col(30) in green "mean= " _col(35) in yellow %8.4f `meanmin' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmin' + di _col(4) in green "`comp'==`maxcomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmax' _col(30) in green "mean= " _col(35) in yellow %8.4f `meanmax' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmax' + di _col(33) in green "Z= " _col(35) in yellow %8.4f `Zcomp' _col(47) in green "pvalue= " _col(57) in yellow %6.4f `pvalue' +} + +/*********************************************************************************************************** +TEST DIF +************************************************************************************************************/ + +if "`method'"=="cml"&"`dif'"!=""&"`test'"!="NONE" { + if "`trace'"!="" { + di in green "*** Tests of DIF" + } + local ssll=0 + tempname DIFfile + qui save "`DIFfile'", replace + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + unab list:`dif' + local nbdif:word count `list' + tempname DIF + matrix define `DIF'=J(`nbdif',4,0) + local count=1 + di + di _col(4) in green "{hline 45}" + di _col(4) in green "Test of Differential Item Functioning (DIF)" + di _col(4) in green "{hline 45}" + foreach j in `list' { + qui inspect `j' + local nbdif=r(N_unique) + qui su `j' + local maxdif=r(max) + if `nbdif'>10&`maxdif'<=10 { + di in ye "The {hi:dif} option is available with variables containing 10 or more modalities (coded from 0 or 1 to k<10)." + di in ye "The variable `j' (`nbdif' modalities) is omitted." + } + else { + local ssll=0 + forvalues i=0/10 { + qui count if `j'==`i' + local effdif=r(N) + if `effdif'>0 { + qui raschtestv7 `varlist' if `j'==`i', test(NONE) id(`id') + local ll`i'=r(cll) + local ssll=`ssll'+(`ll`i'') + } + } + local Z=2*`ssll'-2*`ll' + local ddl=(`nbdif'-1)*(`nbitems'-1) + matrix define `DIF'[`count',1]=(`count',`Z',`ddl',1-chi2(`ddl',`Z')) + di + di _col(4) in green "Variable:" in ye " `j' " in green " Number of groups: " in ye "`nbdif'" + di _col(4) in green "LR Test Z=" in ye %8.3f `Z' in gr " ddl=" in ye %4.0f `ddl' in gr " p-value=" in ye %6.4f `=1-chi2(`ddl',`Z')' + di + } + local ++count + } + use "`DIFfile'",replace +} + +/*********************************************************************************************************** +RETURN +************************************************************************************************************/ + +if "`trace'"!="" { + di in green "*** Returns" +} +local colnametheta + +forvalues i=0/`nbgroups' { + local colnametheta `colnametheta' score_`i' +} + + +return clear + +if `nbitems'>=3&"`test'"!="NONE" { + matrix colnames `globalfit'=`namewp' df p + matrix rownames `globalfit'=`method' + matrix rownames `itemfit'=`varlist' + matrix roweq `itemfit'=`method' + + if "`method'"=="cml" { + matrix colnames `itemfit'=`namewp' df p outfit infit U + matrix rownames `AndersenZ'=`method' + matrix colnames `AndersenZ'=Z df p + return matrix AndersenZ=`AndersenZ' + if "`dif'"!="" { + matrix rownames `DIF'=`list' + matrix colnames `DIF'=num Z df p + return matrix DIF=`DIF' + } + } + else { + matrix colnames `itemfit'=`namewp' df p outfit infit + } + return matrix itemFit=`itemfit' + return matrix globalFit=`globalfit' +} + +matrix colnames `theta'=`colnametheta' +matrix rownames `theta'=theta +return matrix theta `theta' +matrix colnames `sdtheta'=`colnametheta' +matrix rownames `sdtheta'=`colnametheta' +return matrix Vartheta `sdtheta' +local varlist2 +matrix coleq `beta'=`method' +matrix coleq `Vbeta'=`method' +matrix roweq `Vbeta'=`method' +if "`method'"=="cml" { + forvalues i=1/`=`nbitems'-1' { + local varlist2 `varlist2' ``i'' + } + return scalar cll=`ll' + return scalar ll=`globalll' + local AIC=-2*`globalll'+2*(`nbitems'-1) +} +else { + return scalar ll=`ll' + local varlist2 `varlist' + return scalar sigma=`sig' + return scalar sesigma=`sesig' + local AIC=-2*`ll'+2*(`nbitems'+1) +} + +if "`comp'"!="" { + return scalar Zcomp=`Zcomp' + return scalar pZcomp=`pvalue' +} + +matrix colnames `beta'=`varlist2' +matrix rownames `beta'=beta +return matrix beta `beta' + +matrix colnames `Vbeta'=`varlist2' +matrix rownames `Vbeta'=`varlist2' +return matrix Varbeta `Vbeta' + +return scalar AIC=`AIC' +return scalar N=`nbind' +return scalar N_obs=`nbobserv' + +if "`method'"=="mml" { + return scalar PSI=`psi2' + return scalar PSIadj=`psi' +} +if "`covariables'"!="" { + local tmp + local tmp2 + forvalues i=1/`nbcovariables' { + local tmp `tmp' `covariable`i'' + local tmp2 "`tmp2' :`covariable`i''" + } + matrix colnames `betacov'=`tmp2' + matrix rownames `Vbetacov'=`tmp2' + matrix colnames `Vbetacov'=`tmp2' + matrix colnames `zcovariates'=`tmp' + matrix colnames `pcovariates'=`tmp' + return matrix betacovariates=`betacov' + return matrix Vbetacovariates=`Vbetacov' + return matrix zcovariates=`zcovariates' + return matrix pcovariates=`pcovariates' +} +if "`pause'"!="" { + pause off +} + +drop _all + +restore,not +use "`saveraschtest'" + +/*********************************************************************************************************** +CREATE EVENTUAL NEW VARIABLES +************************************************************************************************************/ + +*set trace on +if "`genres'"!="" { + qui sort `id' + qui merge `id' using `ltsave' + qui rename `u'm1 `genlt' + qui rename `u's1 se`genlt' + qui drop _merge se`genlt' + forvalues i=1/`nbitems' { + gen `genres'`i'=exp(``i''*(`genlt'-`beta`i''))/(1+exp(`genlt'-`beta`i''))/sqrt(exp(`genlt'-`beta`i'')/(1+exp(`genlt'-`beta`i''))^2) + } + corr `genres'* + pca `genres'* + drop `u'm1 +} +if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" { + tempname genlt2 genscore2 outfit2 infit2 + qui gen `score'=0 `if' + forvalues i=1/`nbitems' { + qui replace `score'=`score'+``i'' `if' + } + if "`genscore'"!="" { + qui gen `genscore'=`score' `if' + } + if "`genlt'"!="" { + if "`replacegenlt'"=="replace" { + capture drop `genlt' + capture drop se`genlt' + } + if "`method'"=="mml" { + qui sort `id' + qui merge `id' using `ltsave' + qui rename `u'm1 `genlt' + qui rename `u's1 se`genlt' + qui drop _merge + } + else if "`method'"!="mml" { + qui gen `genlt2'=. `if' + forvalues i=0/`nbitems' { + qui replace `genlt2'=`theta`i'' `if'&`score'==`i' + } + qui gen `genlt'=`genlt2' `if' + } + } + if "`genfit'"!="" { + local outfit:word 1 of `genfit' + local infit:word 2 of `genfit' + qui gen `outfit'=0 `if' + qui gen `infit'=0 `if' + tempname infit1 infit2 + qui gen `infit1'=0 `if' + qui gen `infit2'=0 `if' + forvalues j=1/`nbitems' { + tempname pi`j' + qui gen `pi`j''=exp(`genlt2'-`beta`j'')/(1+exp(`genlt2'-`beta`j'')) `if' + qui replace `pi`j''=0 `if' + forvalues s=1/`nbitems' { + qui replace `pi`j''=`Pi'[`j',`s'] `if'&`score'==`s' + } + qui gen `outfit'``j''=(``j''-`pi`j'')^2/(`pi`j''*(1-`pi`j'')) `if' + qui replace `infit1'=`infit1'+(``j''-`pi`j'')^2 `if' + qui replace `infit2'=`infit2'+(`pi`j''*(1-`pi`j'')) `if' + qui replace `outfit'=`outfit'+`outfit'``j''/`nbitems' `if' + } + qui replace `infit'=`infit1'/`infit2' `if' + } +} +if "`docx'"!="" { +*set trace on + putdocx save "`dirsave'\\`docx'.docx", replace + putdocx clear +} +if "`trace'"!=""|"`time'"!="" { + capture qui elapse `st' + di in green "** Time : " in yellow "$S_elap " in green "seconds" +} + +end diff --git a/Modules/ado/personal/r/raschtestv7v88.ado b/Modules/ado/personal/r/raschtestv7v88.ado new file mode 100644 index 0000000..228b5a3 --- /dev/null +++ b/Modules/ado/personal/r/raschtestv7v88.ado @@ -0,0 +1,2423 @@ +*! version 8.8 27 Februar 2014 +*! Jean-Benoit Hardouin +************************************************************************************************************* +* Raschtestv7: Rasch model, fit tests and graphical representations +* Corresponds to the version 8 of Raschtest (http://freeirt.org) for Stata7 +* +* Historic: +* Version 2.1 (2003-07-10): Jean-Benoit Hardouin +* Version 3.1 (2004-01-02) : Jean-Benoit Hardouin +* Version 7.1 (2005-03-30) : Jean-Benoit Hardouin +* Version 7.2.1 (2005-05-21) : Jean-Benoit Hardouin +* Version 7.3.1 (2005-07-02) : Jean-Benoit Hardouin +* Version 7.3.2 (2005-10-05) : Jean-Benoit Hardouin /*correction for the *genlt* option with *method(cml)**/ +* Version 7.3.3 (2005-12-21) : Jean-Benoit Hardouin /*correction if scores are not represented with method(mml) or method(gee)*/ +* Version 7.4.1 (2006-01-17) : Jean-Benoit Hardouin /*Standardized OUTFIT and INFIT, DIF option*/ +* Version 7.4.2 (2006-03-21) : Jean-Benoit Hardouin /*Avoids a bug when the temporary files are saved in a directory containing special characters*/ +* Version 7.4.3 (2006-11-15) : Jean-Benoit Hardouin /*Avoids a bug when the directory defined in the dirsave option contains special characters*/ +* Version 7.5.1 (2007-04-20) : Jean-Benoit Hardouin /*Return results of the comp option*/ +* Version 7.6.1 (2008-06-26) : Jean-Benoit Hardouin /*Nold option, corrects a bug with the genlt option*/ +* Version 7.6.2 (2009-03-01) : Jean-Benoit Hardouin /*Correction of the SE of the latent trait, graph option, correction of a bug with the if option, PSI in MML*/ +* Version 8.1 (2009-06-24) : Jean-Benoit Hardouin /*DIFFICULTIES option, COVARIATES option*/ +* Version 8.2 (2009-07-15) : Jean-Benoit Hardouin /*Correction of a bug with CML*/ +* Version 8.3 (2009-12-19) : Jean-Benoit Hardouin /*correction of a bug with DIFFICULTIES and COVARIATES options together*/ +* Version 8.4 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option */ +* Version 8.5 (2011-12-20) : Jean-Benoit Hardouin /*Correction for the ss1 and ss3 suboptions of the COVARIATES option */ +* Version 8.6 (2012-11-20) : Jean-Benoit Hardouin /*HTML option*/ +* Version 8.7 (2013-05-28) : Jean-Benoit Hardouin /*Correction of a bug in the covariates option with ss1 and ss3*/ +* Version 8.8 (2014-02-27) : Jean-Benoit Hardouin /*Correction of a bug when the null or the parfect score have a frequency of 0 (no test)*/ +* +* Needed modules : +* gammasym version 2.2 (http://www.freeirt.org) +* gausshermite version 1 (http://www.freeirt.org) +* geekel2d version 4.3 (http://www.freeirt.org) +* genscore version 1.4 (http://www.freeirt.org) +* ghquadm (findit ghquadm) +* gllamm version 2.3.20 (ssc describe gllamm) +* gllapred version 2.3.8 (ssc describe gllapred) +* elapse (ssc describe elapse) +* +* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France +* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences" +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2003-2014 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*********************************************************************************************************** +DEFINITION / SYNTAX +***********************************************************************************************************/ + + +program define raschtestv7,rclass +syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GENRES(string) GRAph v8 COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string)] + +local covariables `covariates' + +if "`if'"=="" { + local if "if 1" +} + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + +if "`trace'"!="" { + di in green "*** Tests of conformity" +} +if "`v8'"=="" { + version 7.0 +} +else { + version 8.0 +} +if "`html'"!="" { + set scheme sj + local htmlregion "graphregion(fcolor(white) ifcolor(white))" + local draw +} + +local st = "$S_TIME" +local nbitems : word count `varlist' +marksample touse ,novarlist +if "`covariables'"!="" { + tokenize "`covariables'",parse(" ,") + local i=1 + local tcovariables + while "``i''"!=","&"``i''"!="" { + local covariable`i' ``i'' + local tcovariables `tcovariables' ``i'' + local ++i + } + local nbcovariables=`i'-1 + local ss1 + local ss3 + if "``i''"=="," { + forvalues j=`=`i'+1'/`=`i'+2' { + if "``j''"=="ss1" { + local ss1 ss1 + } + else if "``j''"=="ss3" { + local ss3 ss3 + } + else if "``j''"=="" { +* di in green "option `j' vide" + } + else { + di in red "Invalid option in the {hi:covariables} option" + error 198 + } + } + local i=`i'+3 + if "``i''"!="" { + di in red "There is too much options in the {hi:covariates} option." + error 198 + } + } + local covariables `tcovariables' +} +else { + local nbcovariables=0 +} + +isid `id' +tokenize `varlist' + +local bad +forvalues i=1/`nbitems' { + qui count if ``i''!=0&``i''!=1&``i''!=. + local N=r(N) + if `N'>0 { + local bad `bad' ``i'' + } +} +if "`bad'"!="" { + di in red "The item(s) {hi:`bad'} is(are) not binary item(s) (with responses 0 or 1)." + exit +} + + + +if "`method'"=="" { + local method cml +} +if "`test'"=="" { + local test R +} +local method=lower("`method'") +local test=upper("`test'") +if "`method'"!="mml"&"`method'"!="cml"&"`method'"!="gee" { + di in red "Uncorrect method option." + error 198 + exit +} + +if "`test'"!="R"&"`test'"!="Q"&"`test'"!="WP"&"`test'"!="NONE" { + di in red "Uncorrect test option." + error 198 + exit +} + +if "`genfit'"!="" { + local nbwordgenfit:word count `genfit' + if `nbwordgenfit'!=2 { + di in red "Uncorrect genfit option." + di in red "This option must contain exactly two words" + error 198 + exit + } +} + + +if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!=""|"`genres'"!="" { + capture confirm new variable `genfit' `genscore' `genres' + if "`genfit'"!="" { + local o:word 1 of `genfit' + forvalues i=1/`nbitems' { + confirm new variable `o'``i'' + } + } + if "`genlt'"!="" { + local 0 `genlt' + gettoken left 0: 0,parse(",") + gettoken right 0: 0,parse(",") + local genlt `left' + local replacegenlt `0' + local length=length("`replacegenlt'") + if `length'>=3&substr("`replacegenlt'",1,`length')==substr("replace",1,`length') { + local replacegenlt replace + } + if "`replacegenlt'"!="replace"&"`replacegenlt'"!="" { + di "Not allowed option in the {hi:genlt} option" + error 198 + } + else if "`replacegenlt'"=="" { + confirm new variable `genlt' + } + } +} + +preserve + +tempfile saveraschtest +qui save `saveraschtest' +qui keep if `touse'==1 + +if "`autogroup'"!=""&"`group'"!="" { + di in green "The autogroup and the group options cannot be defined in the same time" + di in green "Only the group option is retained." + local autogroup +} + +if "`autogroup'"!="" { + tempvar autoscore + qui genscore `varlist',score(`autoscore') + + tempname matscore tmp + matrix `matscore'=J(`=`nbitems'-1',3,0) + forvalues i=1/`=`nbitems'-1' { + matrix `matscore'[`i',1]=`i' + matrix `matscore'[`i',2]=`i' + qui count if `autoscore'==`i' + matrix `matscore'[`i',3]=r(N) + } + local stop=0 + local j=0 + while `j'<=`=`nbitems'-3'&`stop'!=1 { + local j=`j'+1 + local scoretogroup=99999999 + local rowtogroup1=0 + local rowtogroup2=0 + local stop=1 + forvalues i=1/`=`nbitems'-`j'' { + if `matscore'[`i',1]>=0 & `matscore'[`i',3]<30 & `matscore'[`i',3]<`scoretogroup' { + local scoretogroup=`matscore'[`i',3] + local rowtogroup1=`i' + local stop=0 + } + } + if `stop'!=1 { + if `rowtogroup1'>1&`rowtogroup1'<`=`nbitems'-`j'' { + if `matscore'[`=`rowtogroup1'-1',1]<`matscore'[`=`rowtogroup1'+1',1] { + local rowtogroup2=`rowtogroup1' + local rowtogroup1=`rowtogroup1'-1 + } + else { + local rowtogroup2=`rowtogroup1'+1 + } + } + else if `rowtogroup1'==1 { + local rowtogroup2=2 + } + else if `rowtogroup1'==`=`nbitems'-`j'' { + local rowtogroup2=`nbitems'-`j' + local rowtogroup1=`nbitems'-`j'-1 + } + matrix `tmp'=`matscore' + matrix `matscore'=J(`=`nbitems'-`j'',3,0) + if `rowtogroup1'!=1 { + matrix `matscore'[1,1]=`tmp'[1..`=`rowtogroup1'-1',1..3] + } + matrix `matscore'[`rowtogroup1',1]=`tmp'[`rowtogroup1',1] + matrix `matscore'[`rowtogroup1',2]=`tmp'[`rowtogroup2',2] + matrix `matscore'[`rowtogroup1',3]=`tmp'[`rowtogroup1',3]+`tmp'[`rowtogroup2',3] + if `rowtogroup2'!=`=`nbitems'-`j'' { + matrix `matscore'[`rowtogroup2',1]=`tmp'[`=`rowtogroup2'+1'..`=`nbitems'-`j'',1..3] + } + } + } + local nbrows=rowsof(`matscore')-1 + local thresholds + forvalues i=1/`nbrows' { + local tmp=`matscore'[`i',2] + local thresholds `thresholds' `tmp' + } + local group `thresholds' +} + + +if "`group'"=="" { + forvalues i=1/`=`nbitems'-1' { + local group "`group' `i'" + } +} +local nbgroups:word count `group' +local groupmax:word `nbgroups' of `group' +if `groupmax'>=`nbitems' { + di in red "You cannot form a group with the higher possible score." + di in red "The higher possible value of the group option is `=`nbitems'-1'." + di in red "Please correct your group option." + error 198 + exit +} +else { + if `groupmax'!=`=`nbitems'-1' { + local group "`group' `=`nbitems'-1'" + local nbgroups=`nbgroups'+1 + } +} +local nbgroups=`nbgroups'+1 + +if "`dirsave'"!=""&"`filessave'"=="" { + di in ye "If you want to save yours graphs, use the filessave option" +} +if "`filessave'"!="" { + if "`dirsave'"=="" { + local dirsave "`c(pwd)'" + } + di in ye "The graphs files will be saved in `dirsave'" +} +if "`dirsave'"!="" { + if "`filesave'"=="" { + local filesave "filesave" + } +} + + +if "`pause'"!=""&"`draw'"=="" { + pause on +} + +if "`difficulties'"!="" { + capture confirm matrix `difficulties' + if _rc!=0 { + di in red "The vector `difficulties' defined in the {hi:difficulties} option does not exist." + error 198 + exit + } +} + +if "`difficulties'"!=""&"`method'"!="mml" { + di in red "The {hi:difficulties} option can be defined only for MML method." + error 198 + exit +} + +if "`covariables'"!=""&"`method'"!="mml" { + di in red "The {hi:covariables} option can be defined only for MML method." + error 198 + exit +} +if "`covariables'"!=""&"`comp'"!="" { + di in red "The {hi:covariables} and {hi:comp} options can be defined jointly." + error 198 + exit +} + + + + + +/*********************************************************************************************************** +POSSIBLE TEST +***********************************************************************************************************/ + +if ("`icc'"!=""|"`fitgraph'"!=""|"`splittest'"!=""|"`details'"!="")&"`test'"=="NONE" { + di in green "You cannot use the {hi:details}, {hi:icc}, {hi:fitgraph} or {hi:splittest} options if you use {hi:test(none)}." + di in green "These options are ignored." + local details + local icc + local fitgraph + local splittest +} +if "`comp'"!=""&"`method'"=="cml" { + di in green "You cannot compare two populations ({hi:comp} option) with the CML estimation method" + di in green "This option is ignored." + local comp +} +if "`method'"!="cml"&"`test'"=="WP" { + di in green "The Wright-Panchapakesan test is not authorized with MML or GEE." + di in green "The WP tests are replaced by Van den Wollenberg Q tests." + local test Q +} +if "`method'"=="gee"&"`ld'"!="" { + di in green "You cannot use the {hi:nold} option with the GEE method of estimation" + di in green "This option is ignored." + local ld +} + + +if "`test'"==""|"`test'"=="R" { + local test "R" + if "`method'"=="cml" { + local namewp "R1c" + local descwp "R1c test" + } + else { + local namewp="R1m" + local descwp "R1m test" + } +} +if `nbitems'>999999|"`test'"=="WP" { + local namewp " Y" + local descwp "Wright-Panchapakesan Y test" + local q2 +} + else if "`test'"=="Q" { + local namewp " Q1" + local descwp "Van den Wollenberg Q1 test" +} + +if "`method'"!="cml"&"`meandiff'"!="" { + di in green "The {hi:meandiff} option is not available with MML or GEE." + di in green "This option is ignored." + local meandiff +} + +if "`method'"!="cml"&"`splittests'"!="" { + di in green "The {hi:splittests} option is not available with MML or GEE." + di in green "This option is ignored." + local splittests +} +if "`method'"!="cml"&"`dif'"!="" { + di in green "The {hi:dif} option is not available with MML or GEE." + di in green "This option is ignored." + local dif +} + +/*********************************************************************************************************** +SCORES AND GROUPS +************************************************************************************************************/ + +qui count if `touse'==1 +local N=r(N) + +qui keep `varlist' `comp' `covariables' `id' `touse' + +tempname rep item +tempvar score realscore +qui genscore `varlist',score(`score') +qui count if `score'==.&`touse'==1 +local nbindmiss=r(N) + +if "`ld'"=="" { + qui drop if `score'==. +} +forvalues i=1/`nbitems' { + rename ``i'' `rep'`i' +} + + + +local liminf0=0 +local limsup0=0 +local liminf`nbgroups'=`nbitems' +local limsup`nbgroups'=`nbitems' + + +local recode +forvalues i=1/`=`nbgroups'-1' { + if `i'!= 1{ + local liminf`i' : word `=`i'-1' of `group' + } + else { + local liminf1=0 + } + local liminf`i'=`liminf`i''+1 + local limsup`i':word `i' of `group' + + local recode "`recode' `liminf`i''/`limsup`i''=`i'" +} +qui gen `realscore'=`score' +qui recode `score' `recode' `nbitems'=`nbgroups' + +local smallgroup=0 + +forvalues i=0/`nbgroups' { + qui count if `score'==`i' + local effscore`i'=r(N) + if `i'!=0&`i'!=`nbgroups'&`effscore`i''<30 { + local smallgroup=1 + } +} +/*********************************************************************************************************** +ESTIMATION OF THE DIFFICULTY PARAMETERS +************************************************************************************************************/ +if "`trace'"!="" { + di in green "*** Estimation of the difficulty parameters" +} + + +if "`covariables'"!=""&"`difficulties'"=="" { + forvalues i=1/`nbcovariables' { + qui su `covariable`i'' + local mean`covariable`i''=r(mean) + qui replace `covariable`i''=`covariable`i''-`mean`covariable`i''' + } +} + +tempname ll coef var beta Vbeta est + +if "`method'"=="gee" { + qui geekel2d `rep'1-`rep'`nbitems',ll + local nbobserv=r(N) + + if `r(error)'==1 { + di "The variance of the latent trait probably is too high to made the GEE a efficient method to estimate the parameters." + error 499 + exit + } + scalar `ll'=r(ll) + local nbind=r(N) + matrix `coef'=r(b) + matrix `est'=`coef' + matrix `est'[1,`=`nbitems'+1']=sqrt(`est'[1,`=`nbitems'+1']) + matrix `var'=r(V) + matrix `beta'=`coef'[1,1..`nbitems'] + matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems'] + local sig=sqrt(`coef'[1,`=`nbitems'+1']) + local sesig=sqrt(`var'[`=`nbitems'+1',`=`nbitems'+1'])/sqrt(`nbind')/(`sig'*2) +} + +qui reshape long `rep', i(`id') j(`item') + +tempvar diff tl +gen `diff'=0 + +forvalues i=1/`nbitems' { + qui gen `rep'`i'=`item'==`i' + qui replace `rep'`i'=-`rep'`i' +} + + +if "`method'"=="mml" { + if "`difficulties'"==""{ + qui xtlogit `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') nocons iterate(`iterate') + matrix `est'=e(b) + matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`est'[1,`=`nbitems'+`nbcovariables'+1']/2) + } + else { + tempname offset b + qui gen `offset'=0 + forvalues i=1/`nbitems' { + qui replace `offset'=-(`difficulties'[1,`i']) if `item'==`i' + } + qui gllamm `rep' `covariables' , offset(`offset') i(`id') nocons iterate(`iterate') link(logit) fam(bin) + matrix `b'=e(b) + matrix `est'=`difficulties',`b' + matrix `est'[1,`=`nbitems'+`nbcovariables'+1']=exp(`b'[1,`=`nbcovariables'+1']/2) + } +} +else if "`method'"=="cml" { + qui clogit `rep' `rep'1-`rep'`=`nbitems'-1' , group(`id') +} + + +if "`method'"!="gee" { + if "`difficulties'"=="" { + matrix `coef'=e(b) + matrix `var'=e(V) + } + else { + matrix `coef'=`difficulties' + matrix `var'=J(`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1',.) + matrix `var'[`=`nbitems'+1',`=`nbitems'+1']=e(V) + } + scalar `ll'=e(ll) + local nbind=e(N)/`nbitems' + local nbobserv=e(N) + *di "nombre d'obs:`nbobserv'" + + if "`meandiff'"!="" { + matrix `var'=J(`nbitems',`nbitems',.) + matrix `coef'=J(1,`nbitems',.) + local param + local lin `rep'1 + forvalues j=2/`=`nbitems'-1' { + local lin `lin'+`rep'`j' + } + local lin (`lin')/`nbitems' + + forvalues j=1/`=`nbitems'-1' { + qui lincom `rep'`j'-`lin' + matrix `coef'[1,`j']=`r(estimate)' + matrix `var'[`j',`j']=`r(se)'^2 + } + qui lincom -`lin' + matrix `coef'[1,`nbitems']=`r(estimate)' + matrix `var'[`nbitems',`nbitems']=`r(se)'^2 + } + if "`method'"=="mml" { + local sig=e(sigma_u) + local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2 + tempname betacov Vbetacov + if "`difficulties'"=="" { + matrix `beta'=`coef'[1,1..`nbitems'] + matrix `Vbeta'=`var'[1..`nbitems',1..`nbitems'] + if "`covariables'"!="" { + matrix `betacov'=`coef'[1,`=`nbitems'+1'..`=`nbitems'+`nbcovariables''] + matrix `Vbetacov'=`var'[`=`nbitems'+1'..`=`nbitems'+`nbcovariables'',`=`nbitems'+1'..`=`nbitems'+`nbcovariables''] + } + local sig=e(sigma_u) + local sesig=sqrt(`var'[`=`nbitems'+`nbcovariables'+1',`=`nbitems'+`nbcovariables'+1'])*`sig'/2 + } + else { + tempname tmp + matrix `tmp'=e(b) + matrix `beta'=`difficulties' + if "`covariables'"!="" { + matrix `betacov'=`tmp'[1,1..`nbcovariables'] + } + local sig=`tmp'[1,`=`nbcovariables'+1'] + matrix `tmp'=e(V) + local sesig=sqrt(`tmp'[`=`nbcovariables'+1',`=`nbcovariables'+1']) + matrix `Vbeta'=J(`nbitems',`nbitems',.) + if "`covariables'"!="" { + matrix `Vbetacov'=`tmp'[1..`nbcovariables',1..`nbcovariables'] + } + } + } + else if "`method'"=="cml"&"`meandiff'"==""{ + matrix `beta'=`coef'[1,1..`=`nbitems'-1'] + matrix `Vbeta'=`var'[1..`=`nbitems'-1',1..`=`nbitems'-1'] + } + else if "`method'"=="cml"&"`meandiff'"!=""{ + matrix `beta'=`coef' + matrix `Vbeta'=`var' + } +} + +if ("`method'"=="mml"|"`method'"=="gee") { + local colnames + forvalues i=1/`nbitems' { + local colnames "`colnames' `rep':`rep'`i'" + } + forvalues i=1/`nbcovariables'{ + local tmp:word `i' of `covariables' + local colnames "`colnames' `rep':`tmp'" + } + local id2=substr("`id'",1,4) + local colnames "`colnames' `id2'1:_cons" + matrix colnames `est'=`colnames' + + qui gllamm `rep' `rep'1-`rep'`nbitems' `covariables', i(`id') allc nocons family(binom) link(logit) trace from(`est') eval + tempname u + qui gllapred `u',u fsample + + forvalues i=1/`nbcovariables' { + local tmp:word `i' of `covariables' + qui replace `u'm1=`u'm1+`betacov'[1,`i']*(`tmp')/*+`mean`covariable`i''')*/ + } + tempname theta sdtheta + matrix `theta'=J(1,`=`nbitems'+1',0) + matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',0) + qui su `u'm1 if `rep'1==-1 + local vartheta=r(Var) + qui gen `u's2=`u's1^2 + qui su `u's2 if `rep'1==-1 + local meanse2=r(mean) + local psi=1-`meanse2'/(`meanse2'+`vartheta') + forvalues s=0/`nbitems' { + qui su `u'm1 if `realscore'==`s' + local theta`s'=r(mean) + qui su `u's1 if `realscore'==`s' + local sdtheta`s'=r(mean) + matrix `theta'[1,`=`s'+1']=`theta`s'' + matrix `sdtheta'[`=`s'+1',`=`s'+1']=`sdtheta`s'' + } + if "`genlt'"!="" { + tempfile ltsave ltsavetmp + qui save `ltsavetmp', replace + qui keep if `rep'1==-1 + qui keep `u'm1 `u's1 `id' + qui sort `id' + qui save `ltsave' + qui use `ltsavetmp' + } +} + +forvalues i=1/`nbitems' { + if `i'==`nbitems'&"`method'"=="cml"&"`meandiff'"=="" { + local beta`i'=0 + local sd`i' . + local fixed`i' "*" + } + else { + local beta`i'=`coef'[1,`i'] + local sd`i'=sqrt(`var'[`i',`i']) + } + qui replace `diff'=-`beta`i'' if `item'==`i' +} + +/*********************************************************************************************************** +COMPARISON OF TWO POPULATIONS +***********************************************************************************************************/ + +if "`comp'"!=""&"`method'"!="cml" { + if "`trace'"!="" { + di in green "*** Test of comparison of two populations" + } + qui inspect `comp' + local unique=r(N_unique) + if `unique'== 2 { + qui su `comp' + local mincomp=r(min) + local maxcomp=r(max) + tempname bmin bmax + qui xtlogit `rep' if `comp'==`mincomp',offset(`diff') i(`id') + matrix `bmin'=e(b) + local meanmin=`bmin'[1,1] + local varmin=e(sigma_u)^2 + local llmin=e(ll) + local Nmin=e(N_g) + qui xtlogit `rep' if `comp'==`maxcomp',offset(`diff') i(`id') + matrix `bmax'=e(b) + local meanmax=`bmax'[1,1] + local varmax=e(sigma_u)^2 + local llmax=e(ll) + local Nmax=e(N_g) + local Zcomp=(`meanmin'-`meanmax')/sqrt(`varmin'/`Nmin'+`varmax'/`Nmax') + local pvalue=1-norm(abs(`Zcomp')) + } + else { + di "It is impossible to compare more than two populations" + di "The comparison process is not run" + local comp + } +} + +/*********************************************************************************************************** +ESTIMATION OF THE ABILITY PARAMETERS / CML +************************************************************************************************************/ +if `nbitems'>=2 { + if "`trace'"!="" { + di in green "*** Estimation of the ability parameters" + } + if "`method'"=="cml" { + tempfile verytmp + qui save `verytmp',replace + drop _all + qui set obs 20001 + qui gen theta=(_n-10001)/1000 + qui gen A=1 + forvalues j=1/`nbitems' { + qui gen u`j'=exp(theta-`beta`j'') + qui gen p`j'=u`j'/(1+u`j') + qui gen a`j'=1/u`j' + qui replace A=A*a`j' + qui gen i`j'=u`j'/(1+u`j')^2 + qui gen j`j'=(u`j'*(1-u`j'))/(1+u`j')^3 + } + qui egen P=rsum(p*) + qui egen I=rsum(i*) + qui egen J=rsum(j*) + qui gen V=1/I^2*(I+J^2)/(4*I^2) + qui gen V2=1/I + tempname theta sdtheta + matrix `theta'=J(1,`=`nbitems'+1',0) + matrix `sdtheta'=J(`=`nbitems'+1',`=`nbitems'+1',.) + forvalues s=0/`nbitems' { + qui gen f`s'=abs(`s'-P+.5*J/I) + qui sort f`s' + matrix `theta'[1,`=`s'+1']=theta[1] + matrix `sdtheta'[`=`s'+1',`=`s'+1']=sqrt(V2[1]) + } + use "`verytmp'",replace + } + qui gen `tl'=0 + forvalues s=0/`nbitems' { + local theta`s'=`theta'[1,`=`s'+1'] + qui replace `tl'=`theta`s'' if `realscore'==`s' + local sdtheta`s'=`sdtheta'[`=`s'+1',`= `s'+1'] + } + tempname pred + qui gen `pred'=log(exp(`rep'*(`tl'+`diff'))/(1+exp(`tl'+`diff'))) + + qui su `pred' + local globalll=r(sum) + + local nulscore=0 + forvalues i=1/`=`nbgroups'-1' { + qui count if `score'==`i'&`item'==1 + local nbscore`i'=r(N) + if `nbscore`i''==0 { + local nulscore=1 + } + } + if `nulscore' { + di in green "{p}At least one group of scores concerns none individuals. Tests will be not computed.{p_end}" + di in green "{p}Use the {hi:group} or the {hi:autogroup} options.{p_end}" + local test "NONE" + local details + local icc + local fitgraph + local splittest + } + forvalues i=0/`nbitems' { + qui count if `realscore'==`i'&`item'==1 + local nbrealscore`i'=r(N) + } +} + +/*********************************************************************************************************** +TESTS OF THE FIRST ORDER +************************************************************************************************************/ + +tempname Pi +matrix define `Pi'=J(`nbitems',`=`nbitems'-1',0) +if "`test'"!="NONE" { + qui drop if `score'==. + if "`trace'"!="" { + di in green "*** Tests of the first order" + } + tempname Obs Obs2 Th Th2 + + matrix define `Obs'=J(`nbitems',`=`nbitems'-1',0) + matrix define `Obs2'=J(`nbitems',`=`nbgroups'-1',0) + matrix define `Th'=J(`nbitems',`=`nbitems'-1',0) + matrix define `Th2'=J(`nbitems',`=`nbgroups'-1',0) + local listofitemsc + + /* Estimation of the gamma symetrical functions*/ + local c0 "1" + local c`nbitems' "`nbitems'*x" + forvalues j=1/`nbitems' { + local listini`j' + local listofitemsc "`listofitemsc' `beta`j''" + local c0 `c0'*(1+exp(x-`beta`j'')) + local c`nbitems' `c`nbitems''-`beta`j'' + forvalues k=1/`nbitems' { + local listini`j'k`k' + if `k'!=`j' { + local listini`j' "`listini`j'' `beta`k''" + } + forvalues l=1/`nbitems' { + if `l'!=`j'&`l'!=`k' { + local listini`j'k`k' "`listini`j'k`k'' `beta`l''" + } + } + } + } + + gammasym `listofitemsc' + + /*Estimation, for each value of the score s of the probability to respond to each item (Pi) and of the theorical number of positive responses (Ths) and of theorical number of positive respond per item pair (Ws)*/ + forvalues s=1/`nbitems' { + local denom`s'=r(gamma`s') + tempname W`s' + matrix define `W`s''=J(`nbitems',`nbitems',0) + } + tempvar prob prob2 z y v z2 y2 v2 c r q e + qui gen `prob'=. + qui gen `prob2'=. + forvalues j=1/`nbitems' { + forvalues s=1/`=`nbitems'-1' { + qui count if `rep'==1&`item'==`j'&`realscore'==`s' + matrix `Obs'[`j',`s']=r(N) + if "`test'"!="WP" { + gammasym `listini`j'' + local num`j'=r(gamma`=`s'-1') + if "`method'"=="cml"|"`test'"=="Q" { + matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s'' + } + else { + gausshermite exp(`s'*x)/(`c0'), sigma(`sig') + local int`s'=r(int) + if "`test'"=="R"&`nbrealscore`s''!=0{ + local tmp=exp(-`beta`j'')*`num`j''*`int`s''*`nbind'/`nbrealscore`s'' + matrix `Pi'[`j',`s']=`tmp' + } + else if `nbrealscore`s''==0 { + matrix `Pi'[`j',`s']=0 + } + } + if "`test'"=="R" { + forvalues k=`=`j'+1'/`nbitems' { + if `s'>=2 { + gammasym `listini`j'k`k'' + local num`j'k`k'=r(gamma`=`s'-2') + if "`method'"=="cml" { + matrix `W`s''[`j',`k']=`nbrealscore`s''*exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''/`denom`s'' + } + else { + matrix `W`s''[`j',`k']=exp(-`beta`j'')*exp(-`beta`k'')*`num`j'k`k''*`int`s''*`nbind' + } + matrix `W`s''[`k',`j']=`W`s''[`j',`k'] + } + } + } + } + else if "`test'"=="WP" { + matrix `Pi'[`j',`s']=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) + } + matrix `Th'[`j',`s']=`Pi'[`j',`s']*`nbrealscore`s'' + qui replace `prob'=`Pi'[`j',`s'] if `realscore'==`s'&`item'==`j' + qui replace `prob2'=exp(`theta`s''-`beta`j'')/(1+exp(`theta`s''-`beta`j'')) if `realscore'==`s'&`item'==`j' + matrix `W`s''[`j',`j']=`nbrealscore`s''*`Pi'[`j',`s'] + if "`test'"!="R" { + matrix `W`s''[`j',`j']=`W`s''[`j',`j']*abs(1-`Pi'[`j',`s']) + } + } + } + qui gen `v2'=abs(`prob'*(1-`prob')) + qui gen `z2'=(`rep'-`prob')^2 + qui gen `y2'=`z2'/`v2' + qui gen `c'=abs(`prob'*(1-`prob')*(`prob'^3+(1-`prob')^3)) + qui gen `r'=`c'/(`v2')^2 + qui gen `e'=`c'-(`v2')^2 + + forvalues j=1/`nbitems' { + qui su `y2' if `item'==`j' + local outfit`j'=r(mean) + qui su `r' if `item'==`j' + local Voutfit`j'=r(sum) + local Voutfit`j'=`Voutfit`j''/(`nbind')^2-1/`nbind' + local outfitstd`j'=(`outfit`j''^(1/3)-1)*(3/sqrt(`Voutfit`j''))-sqrt(`Voutfit`j'')/3 + + qui su `z2' if `item'==`j' + local n=r(sum) + qui su `v2' if `item'==`j' + local d=r(sum) + local infit`j'=`n'/`d' + qui su `e' if `item'==`j' + local sume=r(sum) + local Vinfit`j'=`sume'/(`d')^2 + local infitstd`j'=(`infit`j''^(1/3)-1)*(3/sqrt(`Vinfit`j''))-sqrt(`Vinfit`j'')/3 + } + tempname tmp stattest testitems + + /*Estimation, by scores group g, of the theorical number of positive response (Th2g) and of the positive respond to each items pair (W2g)*/ + scalar `stattest'=0 + forvalues g=1/`=`nbgroups'-1' { + tempname W2`g' d2`g' + matrix define `W2`g''=J(`nbitems',`nbitems',0) + forvalues s=`liminf`g''/`limsup`g'' { + forvalues j=1/`nbitems' { + matrix `Obs2'[`j',`g']=`Obs2'[`j',`g']+`Obs'[`j',`s'] + matrix `Th2'[`j',`g']=`Th2'[`j',`g']+`Th'[`j',`s'] + if "`test'"=="R" { + forvalues k=`=`j'+1'/`nbitems' { + matrix `W2`g''[`j',`k']=`W2`g''[`j',`k']+`W`s''[`j',`k'] + matrix `W2`g''[`k',`j']=`W2`g''[`j',`k'] + } + } + matrix `W2`g''[`j',`j']=`W2`g''[`j',`j']+`W`s''[`j',`j'] + } + } + + /*Estimation of the d2g vectors*/ + matrix `d2`g''=`Obs2'[1..`nbitems',`g']-`Th2'[1..`nbitems',`g'] + + /*Estimation of the influences on the test of each item (testitemsg matrix) and of the test statistic (stattest)*/ + tempname test`g' testitems`g' + matrix `test`g''=`d2`g'''*syminv(`W2`g'')*`d2`g'' + capture matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g'' + if _rc!=0 { + matrix `tmp'=J(`nbitems',`nbitems',0) + forvalues j=1/`nbitems' { + matrix `tmp'[`j',`j']=`W2`g''[`j',`j'] + } + di in green "Group `g' (`liminf`g''/`limsup`g''): The weight matrix is not positive-definite, the diagonal matrix is used to estimate the contribution of the items on the `wpname' statistic" + matrix list `tmp' + matrix `testitems`g''=cholesky(syminv(`tmp'))*`d2`g'' + } + else { + matrix `testitems`g''=cholesky(syminv(`W2`g''))*`d2`g'' + } + scalar `stattest'=`stattest'+`test`g''[1,1] + } + matrix `testitems'=J(`nbitems',1,0) + forvalues j=1/`nbitems' { + forvalues g=1/`=`nbgroups'-1' { + matrix `testitems'[`j',1]=`testitems'[`j',1]+`testitems`g''[`j',1]^2 + } + } + + /*Adaptation for the Q1 statistic*/ + if "`test'"=="Q" { + scalar `stattest'=`stattest'*`=`nbitems'-1'/`nbitems' + } + + /*Correction for R1m and Q1m*/ + if ("`test'"=="R"|"`test'"=="Q")&("`method'"=="mml"|"`method'"=="gee") { + local c`nbitems' exp(`c`nbitems'')/(`c0') + local c0 1/(`c0') + gausshermite `c0', sigma(`sig') + local ci0=r(int)*`nbind' + gausshermite `c`nbitems'',sigma(`sig') + local ci`nbitems'=`nbind'*r(int) + scalar `stattest'=`stattest'+(`nbrealscore0'-`ci0')^2/`ci0'+(`nbrealscore`nbitems''-`ci`nbitems'')^2/`ci`nbitems'' + } + + + +/*********************************************************************************************************** +TESTS U +************************************************************************************************************/ + + if "`method'"=="cml" { + if "`trace'"!="" { + di in green "*** Tests U" + } + + local quartile=`nbind'/4 + local c1=0 + local n1=0 + while `n1'<`quartile' { + local c1=`c1'+1 + local n1=`n1'+`nbrealscore`c1'' + } + local c2=`nbitems' + local n2=0 + while `n2'<`quartile' { + local c2=`c2'-1 + local n2=`n2'+`nbrealscore`c2'' + } + forvalues j=1/`nbitems' { + local zu1=0 + local zu2=0 + forvalues s=1/`c1' { + local zu1=`zu1'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s'])) + } + forvalues s=`c2'/`=`nbitems'-1' { + local zu2=`zu2'+`nbrealscore`s''*(`Obs'[`j',`s']/`nbrealscore`s''-`Pi'[`j',`s'])/sqrt(`nbrealscore`s''*`Pi'[`j',`s']*(1-`Pi'[`j',`s'])) + } + local U`j'=(`zu1'-`zu2')/sqrt(`c1'+`nbitems'-`c2') + } + } + + + +/*********************************************************************************************************** +TESTS OF THE SECOND ORDER /*undocumented in beta test*/ +************************************************************************************************************/ + + if "`q2'"!="" { + if "`trace'"!="" { + di in green "*** Tests of the second order" + } + + tempfile Q2file + qui save "`Q2file'",replace + qui use "`saveraschtest'",replace + + qui keep if `touse'==1 + gen `score'=0 + + forvalues i=1/`nbitems' { + local Q2i`i' + rename ``i'' `rep'`i' + qui replace `score'=`score'+`rep'`i' + } + qui recode `score' `recode' + + forvalues i=1/`nbitems' { + local Q2i`i'=0 + forvalues j=`=`i'+1'/`nbitems' { + local listinci`i'j`j' + forvalues k=1/`nbitems' { + if `k'!=`i'&`k'!=`j' { + local listinci`i'j`j' "`listinci`i'j`j'' `beta`k''" + } + } + } + } + + local Q2tot=0 + forvalues k=2/`=`nbitems'-1' { + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + if `k'==1 { + local num=0 + } + else { + gammasym `listinci`i'j`j'' + local num=r(gamma`=`k'-2') + } + local athi`i'j`j'k`k'=exp(-`beta`i'')*exp(-`beta`j'')*`num'/`denom`k'' + local bthi`i'j`j'k`k'=`nbth`i's`k''-`athi`i'j`j'k`k'' + local cthi`i'j`j'k`k'=`nbth`j's`k''-`athi`i'j`j'k`k'' + local dthi`i'j`j'k`k'=1-`athi`i'j`j'k`k''-`bthi`i'j`j'k`k''-`cthi`i'j`j'k`k'' + } + } + } + forvalues k=1/`=`nbgroups'-1' { + local Q2`k'=0 + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`j'+1'/`nbitems' { + qui count if `rep'`i'==1&`rep'`j'==1&`score'==`k' + local aempi`i'j`j'k`k'=r(N) + local ath2i`i'j`j'k`k'=0 + local bth2i`i'j`j'k`k'=0 + local cth2i`i'j`j'k`k'=0 + local dth2i`i'j`j'k`k'=0 + } + } + if `limsup`k''!=1 { + forvalues l=`liminf`k''/`limsup`k'' { + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + if `l'!=1 { + local ath2i`i'j`j'k`k'=`ath2i`i'j`j'k`k''+`athi`i'j`j'k`l''*`nbrealscore`l'' + local bth2i`i'j`j'k`k'=`bth2i`i'j`j'k`k''+`bthi`i'j`j'k`l''*`nbrealscore`l'' + local cth2i`i'j`j'k`k'=`cth2i`i'j`j'k`k''+`cthi`i'j`j'k`l''*`nbrealscore`l'' + local dth2i`i'j`j'k`k'=`dth2i`i'j`j'k`k''+`dthi`i'j`j'k`l''*`nbrealscore`l'' + } + } + } + } + forvalues i=1/`=`nbitems'-1' { + forvalues j=`=`i'+1'/`nbitems' { + local d2i`i'j`j'k`k'=(`aempi`i'j`j'k`k''-`ath2i`i'j`j'k`k'')^2 + local Q2i`i'j`j'k`k'=`d2i`i'j`j'k`k''/`ath2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`bth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`cth2i`i'j`j'k`k''+`d2i`i'j`j'k`k''/`dth2i`i'j`j'k`k'' + local Q2i`i'=`Q2i`i''+`Q2i`i'j`j'k`k'' + local Q2i`j'=`Q2i`j''+`Q2i`i'j`j'k`k'' + local Q2`k'=`Q2`k''+`Q2i`i'j`j'k`k'' + } + } + } + local Q2tot=`Q2tot'+`Q2`k'' + } + forvalues i=1/`nbitems' { + di in green "Item ``i'' : Q2 = `Q2i`i''" + } + local Q2=`Q2tot'*(`nbitems'-3)/(`nbitems'-1) + di in green "Q2 = `Q2tot'" + qui use "`Q2file'",replace + } + +/*********************************************************************************************************** +TEST LR Z +************************************************************************************************************/ + + if "`method'"=="cml" { + if "`trace'"!="" { + di in green "*** Tests LR of Andersen" + } + local ssll=0 + tempfile Zfile + qui save "`Zfile'", replace + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + gen `score'=0 + forvalues j=1/`nbitems' { + qui replace `score'=`score'+``j'' + } + qui recode `score' `recode' `nbitems'=`nbgroups' + forvalues i=1/`=`nbgroups'-1' { + if `effscore`i''>0 { + qui raschtestv7 `varlist' if `score'==`i', test(NONE) `ld' id(`id') + local ll`i'=r(cll) + local ssll=`ssll'+(`ll`i'') + } + } + local Z=2*`ssll'-2*`ll' + use "`Zfile'",replace + tempname AndersenZ + matrix define `AndersenZ'=(`Z',`=(`nbgroups'-2)*(`nbitems'-1)',1-chi2(`=(`nbitems'-1)*(`nbgroups'-2)',`Z')) + } +} + + +/*********************************************************************************************************** +DISPLAYING RESULTS WITH TESTS +************************************************************************************************************/ +if "`html'" != "" { + di "" +} + +if "`test'"!="NONE" { + local conttest= "_c" +} +di +tempname itemfit globalfit +matrix `globalfit'=J(1,3,0) +if "`method'"=="cml" { + if "`html'" == "" { + di in green "Estimation method: " in yellow "Conditional maximum likelihood (CML)" + } + else { + di "

Estimation method: Conditional maximum likelihood (CML)

" + } + local nbtest=`nbgroups'-1 + local line=77 +} +else if "`method'"=="mml"{ + if "`html'" == "" { + di in green "Estimation method: " in yellow "Marginal maximum likelihood (MML)" + } + else { + di "

Estimation method: Marginal maximum likelihood (MML)

" + } + local nbtest=`nbgroups'+1 + local line=70 +} +else if "`method'"=="gee" { + di in green "Estimation method: " in yellow "Generalized Estimating Equations (GEE)" + local nbtest=`nbgroups'+1 + local line=70 +} +if "`test'"=="NONE" { + local line=35 +} + +if "`html'" == "" { + di in green "Number of items: " in yellow `nbitems' + di in green "Number of groups: " in yellow `=`nbgroups'+1' `conttest' + if "`test'"!="NONE" { + di in green " (" in yellow "`nbtest'" in green " of them are used to compute the statistics of test)" + } +} +else { + di "Number of items: " `nbitems' "
" + di "Number of groups: " `=`nbgroups'+1' `conttest' + if "`test'"!="NONE" { + di " (`nbtest' of them are used to compute the statistics of test)" + } + di "
" +} +if "`method'"=="cml" { + local nbind=`nbind'+`effscore0'+`effscore`nbgroups'' + local cont "_c" + matrix `itemfit'=J(`nbitems',6,0) +} +else { + local cont + matrix `itemfit'=J(`nbitems',5,0) +} +local missing=`N'-`nbind' +if "`html'" == "" { + di in green "Number of individuals: " in yellow `N' + di in green "Number of individuals with missing values: " in yellow `nbindmiss' _c + if "`ld'"=="" { + di in green " (removed)" + } + else { + di + } + di in green "Number of individuals with nul or perfect score: " in yellow `=`effscore0'+`effscore`nbgroups''' +} +else { + di "Number of individuals: `N'
" + di "Number of individuals with missing values: " `nbindmiss' + if "`ld'"=="" { + di " (removed)" + } + di "
" + di "Number of individuals with nul or perfect score: " `=`effscore0'+`effscore`nbgroups''' "
" +} +if "`method'"=="cml" { + if "`html'" == "" { + di in green "Conditional log-likelihood: " in yellow %-13.4f `ll' + di in green "Log-likelihood: " in yellow %-13.4f `globalll' + } +} +else { + if "`html'" == "" { + di in green "Marginal log-likelihood: " in yellow %-13.4f `ll' + di in green "Log-likelihood: " in yellow %-13.4f `globalll' + di + } + else { + di "Marginal log-likelihood: " %-13.4f `ll' "
" + di "Log-likelihood: " %-13.4f `globalll' "

" + } +} + +if "`html'" == "" { + noi di in green _col(16) "Difficulty" `conttest' + if "`test'"!="NONE" { + di in green _col(58) "Standardized" + } + noi di in green _col(9) "Items" _col(16) "parameters" _col(28) "std Err." `conttest' + if "`test'"!="NONE" { + local varin=int(2/sqrt(`nbind')*100)/100 + local varout=int(6/sqrt(`nbind')*100)/100 + di _col(41) "`namewp'" _col(47) "df" _col(50) "p-value" _col(58) "Outfit" _col(66) "Infit" `cont' + if "`method'"=="cml" { + di in green _col(77) "U" + } + } + di in green "{hline `line'}" +} +else { + di "" + di "" + di "" + if "`test'"!="NONE" { + di "" + } + di "" + di "" + if "`test'"!="NONE" { + local varin=int(2/sqrt(`nbind')*100)/100 + local varout=int(6/sqrt(`nbind')*100)/100 + di "" + if "`method'"=="cml" { + di "" + } + } + di "" +} + +forvalues i=1/`nbitems' { + if "`html'" == "" { + noi di in yellow _col(3) %12s abbrev("``i''`fixed`i''" ,12) in yellow _col(18) %8.5f `beta`i'' _col(29) %6.5f `sd`i'' `conttest' + } + else { + di "" + } + if "`test'"!="NONE" { + if "`html'" == "" { + di _col(36) %8.3f `testitems'[`i',1] _col(46) %3.0f `=`nbgroups'-2' _col(51) %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) _col(58) %6.3f `outfitstd`i'' _col(65) %6.3f `infitstd`i'' /*_col(72) %6.3f `outfit`i'' _col(79) %6.3f `infit`i''*/ `cont' + } + else { + di "" + } + matrix `itemfit'[`i',1]=`testitems'[`i',1] + matrix `itemfit'[`i',2]=`=`nbgroups'-2' + matrix `itemfit'[`i',3]=1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) + matrix `itemfit'[`i',4]=`outfitstd`i'' + matrix `itemfit'[`i',5]=`infitstd`i'' + if "`method'"=="cml" { + if "`html'" == "" { + di in ye _col(72) %6.3f `U`i'' + } + else { + di "" + } + matrix `itemfit'[`i',6]=`U`i'' + } + if "`html'" != "" { + di "" + } + } +} +if "`html'" == "" { + di in green "{hline `line'}" +} +else { + di "" +} +if "`test'"!="NONE" { + if "`method'"=="cml" { + local df=(`nbgroups'-2)*(`nbitems'-1) + } + else { + local df=(`nbgroups'-1)*(`nbitems'-1)-1 + } + matrix `globalfit'=(`stattest',`df',1-chi2(`df',`stattest')) + if "`html'" == "" { + noi di in green _col(6) "`descwp'" _col(32) in gr "`namewp'=" _col(36) in ye %8.3f `globalfit'[1,1] _col(46) %3.0f `globalfit'[1,2] _col(51) %6.4f `globalfit'[1,3] + if "`method'"=="cml" { + noi di in green _col(6) "Andersen LR test" _col(34) "Z=" in yellow _col(36) %8.3f `AndersenZ'[1,1] _col(46) %3.0f `AndersenZ'[1,2] _col(51) %6.4f `AndersenZ'[1,3] + } + di in green "{hline `line'}" + } + else { + di "" + if "`method'"=="cml" { + di "" + } + di "
DifficultyStandardized
Itemsparametersstd Err.`namewp'dfp-valueOutfitInfitU
" %12s abbrev("``i''`fixed`i''" ,12) "" %8.5f `beta`i'' "" %6.5f `sd`i'' "" %8.3f `testitems'[`i',1] "" %3.0f `=`nbgroups'-2' "" %6.4f 1-chi2(`=`nbgroups'-2',`testitems'[`i',1]) "" %6.3f `outfitstd`i'' "" %6.3f `infitstd`i'' "" %6.3f `U`i'' "
`descwp'`namewp'=" %8.3f `globalfit'[1,1] "" %3.0f `globalfit'[1,2] "" %6.4f `globalfit'[1,3] "
Andersen LR testZ=" %8.3f `AndersenZ'[1,1] "" %3.0f `AndersenZ'[1,2] "" %6.4f `AndersenZ'[1,3] "
" + } +} + +if "`html'" == "" { + if "`method'"=="cml"&"`meandiff'"==""{ + di in green "*: The difficulty parameter of this item had been fixed to 0" + } + if "`method'"=="cml"&"`meandiff'"!=""{ + di in green "The mean of the difficulty parameters is fixed to 0" + } + if `smallgroup'==1&"`test'"!="NONE" { + di in green "You have groups of scores with less than 30 individuals. The tests can be invalid." + } + if "`method'"!="cml"&"`test'"=="Q" { + di in green "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test." + } + + di +} +else { + if "`method'"=="cml"&"`meandiff'"==""{ + di "*: The difficulty parameter of this item had been fixed to 0
" + } + if "`method'"=="cml"&"`meandiff'"!=""{ + di "The mean of the difficulty parameters is fixed to 0
" + } + if `smallgroup'==1&"`test'"!="NONE" { + di "You have groups of scores with less than 30 individuals. The tests can be invalid.
" + } + if "`method'"!="cml"&"`test'"=="Q" { + di "The Q statistics is approximated in the `method' approach. It is preferable to use the R1m test.
" + } + di "

" +} + +if "`html'" == "" { + if "`method'"!="cml" { + di in green "{hline 56}" + noi di in green _col(5) "Parameters" _col(21) "Coef." _col(28) "std Err." _col(43) "z" _col(52) "P>|z|" + di in green "{hline 56}" + local zsig=`sig'/`sesig' + local pzsig=2*(1-norm(abs(`zsig'))) + di in green _col(10) in yellow "Sigma" _col(18) %8.5f `sig' _col(29) %6.5f `sesig' _col(38) %6.3f `zsig' _col(50) %7.4f `pzsig' + di in green "{hline 56}" + } +} +else { + if "`method'"!="cml" { + di "" + di "" + di "" + local zsig=`sig'/`sesig' + local pzsig=2*(1-norm(abs(`zsig'))) + di "
ParametersCoef.std Err.zP>|z|
Sigma" %8.5f `sig' "" %6.5f `sesig' "" %6.3f `zsig' "" %7.4f `pzsig' "
" + } +} + + + +*set trace on +if "`covariables'"!="" { + tempname zcovariates pcovariates + matrix `zcovariates'=J(1,`nbcovariables',0) + matrix `pcovariates'=J(1,`nbcovariables',0) + forvalues i=1/`nbcovariables' { + local tmp :word `i' of `covariables' + local zcov=`betacov'[1,`i']/`Vbetacov'[`i',`i']^.5 + local pzcov=2*(1-norm(abs(`zcov'))) + matrix `zcovariates'[1,`i']=`zcov' + matrix `pcovariates'[1,`i']=`pzcov' + di in green _col(3) %12s in yellow abbrev("`tmp'",12) _col(18) %8.5f `betacov'[1,`i'] _col(29) %6.5f `Vbetacov'[`i',`i']^.5 _col(38) %6.3f `zcov' _col(50) %7.4f `pzcov' + } + di in green "{hline 56}" + local difficulties2 + if "`difficulties'"!="" { + local difficulties2 diff(`difficulties') + } + if "`ss1'"!="" { + tempfile ss1save + qui save `ss1save' + qui use `saveraschtest' + qui keep if `touse'==1 + + qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2' + local sigma0=r(sigma) + local var0=`sigma0'^2 + local nbobs=r(N_obs) + *di "nbobs=`nbobs'" + local df0=`nbobs'-(`nbitems'+1)-1 + local ss10=`var0'*(`df0') + local ss1c0=0 + di + di in green "Type 1 Sum of Squares (sequential)" + di "{hline 85}" + di in green _col(44) "Degrees" _col(56) "Variance of the" _col(77) "Explained" + di in green _col(4) "Covariates" _col(25) "SS" _col(35) "Diff" _col(41) "of freedom"_col(59) "latent trait" _col(78) "Variance" + di "{hline 85}" + di _col(10) in green "None" _col(15) in ye %12.3f `ss10' _col(47) %4.0f `df0' _col(63) %8.3f `var0' + di in green "{dup 85:-}" + local covariablesss1 + forvalues i=1/`nbcovariables' { + local covariablesss1 `covariablesss1' `covariable`i'' + qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss1') test(none) `ld' `difficulties2' + local nbobs=r(N_obs) + local sigma`i'=r(sigma) + local var`i'=`sigma`i''^2 + local nbcovtmp:word count `covariablesss1' + *di " ss1`i'=`var`i''*`=`nbobs'-(`nbitems'+1+`nbcovtmp')-1'" + local df`i'=`nbobs'-(`nbitems'+1+`nbcovtmp')-1 + *di "local df`i'=`nbobs'-(`nbitems'+1+`nbcovtmp')-1 (cov:`covariablesss1')" + local ss1`i'=`var`i''*`df`i'' + *di "cov : `covariablesss1' var=`var`i'' df=`df`i''" + di _col(2) %12s in yellow abbrev("`covariable`i''",12) _col(15) %12.3f in ye `ss1`i'' _col(25) %12.3f `=`ss1`=`i'-1''-`ss1`i''' _col(47) %4.0f `df`i'' _col(63) %8.3f `var`i'' _col(81) %5.3f (`=`ss1`=`i'-1''-`ss1`i''')/`ss10' + } + di in green "{hline 85}" + qui use `ss1save' + } + if "`ss3'"!="" { + tempfile ss3save + qui save `ss3save' + qui use `saveraschtest' + qui keep if `touse'==1 + if "`ss1'"=="" { + qui raschtestv7 `varlist' ,id(`id') meth(`method') test(none) `ld' `difficulties2' + local sigma0=r(sigma) + local var0=`sigma0'^2 + local nbobs=e(N_obs) + local df0=`nbobs'-(`nbitems'+1)-1 + local ss30=`var0'*(`df0') + } + else { + local ss30=`ss10' + } + local ss3ref=`=`sig'^2*(`df0'-`nbcovariables')' + di + di in green "Type 3 Sum of Squares " + di "{hline 85}" + di in green _col(44) "Degrees" _col(56) "Variance of the" _col(77) "Explained" + di in green _col(4) "Covariates" _col(25) "SS" _col(35) "Diff" _col(41) "of freedom"_col(59) "latent trait" _col(78) "Variance" + di "{hline 85}" + di _col(10) in green "None" _col(15) in ye %12.3f `ss30' _col(47) %4.0f `df0' _col(63) %8.3f `var0' + di _col(6) in green "Complete" _col(15) in ye %12.3f `ss3ref' _col(25) %12.3f `=`ss30'-`ss3ref'' _col(47) %4.0f `=`df0'-`nbcovariables'' _col(63) %8.3f `sig'^2 _col(81) %5.3f 1-`sig'^2*(`df0'+`nbcovariables')/`ss30' + di in green "{dup 85:-}" + forvalues i=1/`nbcovariables' { + local covariablesss3 + forvalues j=1/`nbcovariables' { + if `i'!=`j' { + local covariablesss3 `covariablesss3' `covariable`j'' + } + } + qui raschtestv7 `varlist' ,id(`id') meth(`method') covariates(`covariablesss3') test(none) `ld' `difficulties2' + *ereturn list + local sigmas`i'=r(sigma) + local vars`i'=`sigmas`i''^2 + local nbobs=e(N) + local dfs`i'=`nbobs'-(`nbitems'+1)-1-(`nbcovariables'-1) + *di "local dfs`i'=`nbobs'-(`nbitems'+1)-1-(`nbcovariables'-1)" + local ss3s`i'=`vars`i''*`dfs`i'' + local vara`i'=`sig'^2 + local dfa`i'=`nbobs'-(`nbitems'+1)-1-`nbcovariables' + local ss3a`i'=`vara`i''*`dfa`i'' + *di "cov : `covariablesss3' var=`vars`i'' df=`dfs`i''" + di _col(2) %12s in green abbrev("`covariable`i''",12) _col(15) in ye %12.3f `ss3s`i'' _col(25) %12.3f in ye `=`ss3s`i''-`ss3a`i''' _col(47) %4.0f `=`df0'-`nbcovariables'+1' _col(63) %8.3f `vars`i'' _col(80) %6.3f (`=`ss3s`i''-`ss3a`i''')/`ss30' + } + di in green "{hline 85}" + qui use `ss3save' + } +} + + + +/*Tabular of the estimated values of the latent trait*/ + +if "`covariables'"=="" { + if "`html'" == "" { + di + di + noi di in green _col(33) "Ability" _col(60) "Expected" + noi di in green _col(17) "Group" _col(23) "Score" _col(30) "parameters" _col(42) "std Err." _col(54) "Freq." _col(63) "Score"_c + if "`method'"=="cml"&"`test'"!="NONE" { + noi di in green _col(75) "ll" + } + else { + noi di "" + } + if "`method'"=="cml"&"`test'"!="NONE" { + local line=62 + } + else { + local line=51 + } + di in green _col(17) "{hline `line'}" + } + else { + di "" + di "" + di "" + if "`method'"=="cml"&"`test'"!="NONE" { + di "" + } + di "" + } + + local nonul=0 + forvalues g=0/`nbgroups' { + if `g'!=0 { + if "`html'" == "" { + di in green _col(17) "{dup `line':-}" + } + } + forvalues s=`liminf`g''/`limsup`g'' { + if `s'==`liminf`g'' { + local tmp `ll`g'' + local gr `g' + } + else { + local tmp + local gr + } + local expscore`nonul'=0 + forvalues i=1/`nbitems' { + local expscore`nonul'=`expscore`nonul''+1/(1+exp(-`theta`nonul''+`beta`i'')) + } + if "`method'"=="cml" { + local format1 %8.3f + } + else { + local format1 %8.5f + } + if "`html'" == "" { + noi di in yellow _col(17) %5s "`gr'"_col(23) %5s "`s'" _col(32) `format1' `theta`nonul'' _col(42) `format1' `sdtheta`nonul'' _col(55) %4.0f `nbrealscore`s'' _col(64) % 4.2f `expscore`nonul'' _col(68) %11.4f `tmp' + } + else { + di "" + } + local nonul=`nonul'+1 + } + } + if "`html'" == "" { + di in green _col(17) "{hline `line'}" + } + else { + di "
GroupScoreAbility
parameters
std Err.Freq.Expected
Score
ll
" %5s "`gr'" "" %5s "`s'" "" `format1' `theta`nonul'' "" `format1' `sdtheta`nonul'' "" %4.0f `nbrealscore`s'' "" % 4.2f `expscore`nonul'' "" %11.4f `tmp' "
" + } +} + +if "`method'"=="mml"|"`method'"=="gee" { + if "`html'" == "" { + di + *di in green "Variance of the estimated latent trait" _col(45) in ye %10.4f `vartheta' + di in green "Mean variance of the error" _col(45) in ye %10.4f `meanse2' + local sig2=`sig'^2 + di in green "Estimated variance of the latent trait" _col(45) in ye %10.4f `sig2' + local psi2=1-`meanse2'/`sig2' + di in green "Personal Separation Index (PSI)" _col(45) in ye %10.4f `psi2' + di in green "Adjusted PSI on covariates (PSIadj)" _col(45) in ye %10.4f `psi' + } + else { + di "" + di "" + di "" + di "" + local sig2=`sig'^2 + di "" + local psi2=1-`meanse2'/`sig2' + di "" + di "" + di "
Mean variance of the error" %10.4f `meanse2' "
Estimated variance of the latent trait" %10.4f `sig2' "
Personal Separation Index (PSI)" %10.4f `psi2' "
Adjusted PSI on covariates (PSIadj)" %10.4f `psi' "
" + } +} + + +/*********************************************************************************************************** +DETAILS OPTION +************************************************************************************************************/ + +if "`details'"!="" { + if "`html'"=="" { + forvalues g=0/`nbgroups' { + if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" { + di + di in green "{hline 44}" + di in green "Group: " in ye "`g'" in green " from " in ye "`liminf`g''" in green " to " in ye "`limsup`g''" in green " (n=" in ye "`nbscore`g''" in green")" + di + di _col(3) "Item" _col(10) "Observed" _col(23) "Expected" _col(37) "Scaled" + di in green "{dup 44:-}" + } + if `g'!=0&`g'!=`nbgroups' { + forvalues j=1/`nbitems' { + local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j']) + di _col(3) in ye "``j''" _col(14) %4.0f `Obs2'[`j',`g'] _col(25) %6.2f `Th2'[`j',`g'] _col(36) %7.4f `tmp' + } + di in green "{dup 44:-}" + di in green "Contribution to the `namewp' statistics: " %8.4f in ye `test`g''[1,1] + } + else if "`method'"!="cml" { + if `g'==0 { + local h=0 + } + else { + local h=`nbitems' + } + local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'') + di in ye _col(14) %4.0f `nbrealscore`h'' _col(25) %6.2f `ci`h'' _col(36) %7.4f `tmp' + di in green "{dup 44:-}" + local tmp=`tmp'^2 + di in green "Contribution to the `namewp' statistics: " %8.4f in ye `tmp' + } + } + } + else { + forvalues g=0/`nbgroups' { + if (`g'!=0&`g'!=`nbgroups')|"`method'"!="cml" { + di in gr "" + di in gr "" + di in gr "" + } + if `g'!=0&`g'!=`nbgroups' { + forvalues j=1/`nbitems' { + local tmp=`d2`g''[`j',1]/sqrt(`W2`g''[`j',`j']) + di "" + } + di "" + } + else if "`method'"!="cml" { + if `g'==0 { + local h=0 + } + else { + local h=`nbitems' + } + local tmp=abs(`nbrealscore`h''-`ci`h'')/sqrt(`ci`h'') + di "" + local tmp=`tmp'^2 + di "" + } + di "
Group: `g' from `liminf`g'' to `limsup`g'' (n=`nbscore`g'')
ItemObservedExpectedScaled
``j''" %4.0f `Obs2'[`j',`g'] "" %6.2f `Th2'[`j',`g'] "" %7.4f `tmp' "
Contribution to the `namewp' statistics:" %8.4f `test`g''[1,1] "
" %4.0f `nbrealscore`h'' "" %6.2f `ci`h'' "" %7.4f `tmp' "
Contribution to the `namewp' statistics:" %8.4f `tmp' "
" + } + } +} + +/*********************************************************************************************************** +OPTION ICC +************************************************************************************************************/ +*set trace on +if "`icc'"!="" { + if "`trace'"!="" { + di in green "*** Items Characteristic Curves" + } + tempvar proba propemp propth propthb + qui replace `tl'=. if `realscore'==0|`realscore'==`nbitems'|`realscore'==. + qui gen `propemp'=. + qui gen `propth'=. + qui gen `propthb'=. + label variable `propth' "Expected ICC" + label variable `propemp' "Observed ICC" + label variable `propthb' "Expected ICC" + label variable `tl' "Latent trait" + global iccs + forvalues i=1/`nbitems' { + forvalues s=1/`=`nbitems'-1' { + qui replace `propthb'=exp(`theta`s''-`beta`i'')/(1+exp(`theta`s''-`beta`i'')) if `item'==`i'&`realscore'==`s' + } + qui replace `propemp'=. + qui replace `propth'=. + tempvar propemp`i' propth`i' + qui bysort `realscore' `item' : egen `propth`i''=mean(`propthb') if `item'==`i' + qui bysort `realscore' `item' : egen `propemp`i''=mean(`rep') if `item'==`i' + qui replace `propth'=`propth`i'' if `item'==`i' + qui replace `propemp'=`propemp`i'' if `item'==`i' + local mintl=floor(`theta1') + local maxtl=floor(`theta`=`nbitems'-1'')+1 + if "`filessave'"!=""{ + local saving "`dirsave'\\icc``i''" + } + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_icc_``i''" + } + if "`v8'"!=""|"`html'"!="" { + graph twoway (line `propemp' `propth' `tl') if `item'==`i' , `htmlregion' name(icc``i'',replace) ytitle("") ylabel(0(.25)1) title("Observed and Expected ICC for the item ``i''") xlabel(`mintl'(1)`maxtl') xsize(12) ysize(9) `draw' + if "html"=="" { + pause + } + else { + qui graph save icc``i'' "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_icc_``i''.eps, replace + di " _char(34) " + + } + if "`filessave'"!="" { + qui graph save icc``i'' "`saving'" , `replace' + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + qui graph `propemp' `propth' `tl' if `item'==`i' , twoway `saving' c(ll) ylabel(0(.25)1) xlabel(`mintl'(1)`maxtl') title("Observed and Expected ICC for the item ``i''") + pause + } + } +} + +/*********************************************************************************************************** +OPTION INFORMATION +************************************************************************************************************/ + +if "`information'"!="" { + if "`trace'"!="" { + di in green "*** Information graph" + } + + tempfile saveinfo + qui save "`saveinfo'",replace + tempvar info latent + drop _all + qui set obs 2001 + gen `latent'=((_n-1)/1001-1)*3 + label variable `latent' "latent trait" + gen `info'=0 + forvalues i=1/`nbitems' { + qui replace `info'=`info'+exp(`latent'-`beta`i'')/(1+exp(`latent'-`beta`i''))^2 + } + local saving "`dirsave'\\information" + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_information" + } + if "`v8'"!=""|"`html'"!="" { + *set trace on + graph twoway (line `info' `latent') , `htmlregion' name(information,replace) ytitle("Information") xlabel(-3(1)3) title("Information graph of the scale") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + graph save information "`saving'" , `replace' + } + if "`html'"=="" { + pause + } + else { + qui graph save information "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_information.eps, replace + di " _char(34) " + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + if "`filessave'"=="" { + local saving + } + qui graph `info' `latent' , twoway `saving' c(l) xlabel(-3(1)3) title("Information graph of the scale") + pause + } + qui use "`saveinfo'",replace +} + +/*********************************************************************************************************** +OPTION FITGRAPH +************************************************************************************************************/ + +if "`fitgraph'"!="" { + if "`trace'"!="" { + di in green "*** Graphical validation of the fit" + } + *set trace on + tempname outfit meanz2 meanv2 sumd infit Voutfit outfitstd Vinfit infitstd + qui egen `outfit'=mean(`y2'),by(`id') + qui egen `Voutfit'=sum(`r'),by(`id') + qui replace `Voutfit'=`Voutfit'/(`nbitems')^2-1/`nbitems' + qui gen `outfitstd'=(`outfit'^(1/3)-1)*(3/sqrt(`Voutfit'))-sqrt(`Voutfit')/3 + qui egen `meanz2'=sum(`z2'),by(`id') + qui egen `meanv2'=sum(`v2'),by(`id') + qui gen `infit'=`meanz2'/`meanv2' + qui egen `Vinfit'=sum(`e'),by(`id') + qui replace `Vinfit'=`Vinfit'/(`meanv2')^2 + qui gen `infitstd'=(`infit'^(1/3)-1)*(3/sqrt(`Vinfit'))-sqrt(`Vinfit')/3 + + qui su `outfitstd' + local mino=floor(2*min(`r(min)',-2))/2 + local maxo=ceil(2*max(`r(max)',2))/2 + qui su `infitstd' + local mini=floor(2*min(`r(min)',-2))/2 + local maxi=ceil(2*max(`r(max)',2))/2 + if "`filessave'"!=""{ + local savingo "`dirsave'\\outfitind" + local savingi "`dirsave'\\infitind" + } + if "`v8'"!="" { + graph twoway (scatter `outfitstd' `id'), `htmlregion' name(outfit,replace) yline(-2 2) title("Outfit indexes") xtitle("Individual indexes") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw' + if "`html'"=="" { + pause + } + graph twoway (scatter `infitstd' `id'), `htmlregion' name(infit,replace) yline(-2 2) title("Infit indexes") xtitle("Individual indexes") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw' + if "`html'"=="" { + pause + } + if "`filessave'"!=""|"`html'"!="" { + qui graph save outfit "`savingo'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_outfit.eps, replace + } + qui graph save infit "`savingi'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_infit.eps, replace + } + } + } + else { + if "`filessave'"!="" { + local savingo "saving(`savingo'" + local savingi "saving(`savingi'" + if "`replace'"=="" { + local savingo "`savingo')" + local savingi "`savingi')" + } + else { + local savingo "`savingo',replace)" + local savingi "`savingi',replace)" + } + } + graph `outfitstd' `id', `savingo' twoway sy(.) c(.) yline(-2 2) title("Outfit indexes") b2title("Individual indexes") l1("") l2title("Outfit") ylabel(`mino'(.5)`maxo') + pause + graph `infitstd' `id', `savingi' twoway sy(.) c(.) yline(-2 2) title("Infit indexes") b2title("Individual indexes") l1("") l2title("Infit") ylabel(`mini'(.5)`maxi') + pause + } + drop _all + qui set obs `nbitems' + tempvar name betap outfitstdj infitstdj + qui gen str9 `name'="" + qui gen `betap'=. + qui gen `outfitstdj'=. + qui gen `infitstdj'=. + local mino=-2 + local maxo=2 + local mini=-2 + local maxi=2 + forvalues j=1/`nbitems' { + qui replace `name'="``j''" in `j' + qui replace `betap'=`beta`j'' in `j' + qui replace `outfitstdj'=`outfitstd`j'' in `j' + qui replace `infitstdj'=`infitstd`j'' in `j' + local mino=floor(min(`mino',`outfitstd`j'')*2)/2 + local mini=floor(min(`mini',`infitstd`j'')*2)/2 + local maxo=ceil(max(`maxo',`outfitstd`j'')*2)/2 + local maxi=ceil(max(`maxi',`infitstd`j'')*2)/2 + } + if "`filessave'"!=""{ + local savingo "`dirsave'\\outfititems" + local savingi "`dirsave'\\infititems" + } + if "`v8'"!="" { + graph twoway (scatter `outfitstdj' `betap',`htmlregion' name(outfititem,replace) mlabel(`name')), yline(-2 2) title("Outfit indexes") xtitle("Difficulty") ytitle("Outfit") ylabel(`mino'(.5)`maxo') `draw' + if "`html"=="" { + pause + } + graph twoway (scatter `infitstdj' `betap',`htmlregion' name(infititem,replace) mlabel(`name')), yline(-2 2) title("Infit indexes") xtitle("Difficulty") ytitle("Infit") ylabel(`mini'(.5)`maxi') `draw' + if "`html"=="" { + pause + } + if "`filessave'"!=""|"`html'"!="" { + qui graph save outfititem "`savingo'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_outfititem.eps, replace + } + qui graph save infititem "`savingi'" , `replace' + if "`html'"!="" { + qui graph export `c(tmpdir)'/`html'_infititem.eps, replace + } + } + } + else { + if "`filessave'"!="" { + local savingo "saving(`savingo'" + local savingi "saving(`savingi'" + if "`replace'"=="" { + local savingo "`savingo')" + local savingi "`savingi')" + } + else { + local savingo "`savingo',replace)" + local savingi "`savingi',replace)" + } + } + graph `outfitstdj' `betap', `savingo' twoway c(.) yline(-2 2) title("Outfit indexes") b2title("Difficulty") l1title("") l2title("Outfit") ylabel(`mino'(.5)`maxo') sy([`name']) + pause + graph `infitstdj' `betap', `savingi' twoway c(.) yline(-2 2) title("Infit indexes") b2title("Difficulty") l1title("") l2title("Infit") ylabel(`mini'(.5)`maxi') sy([`name']) + pause + } +} + + +/*********************************************************************************************************** +OPTION SPLITTESTS +************************************************************************************************************/ + +if "`splittests'"!="" { + if "`trace'"!="" { + di in green "*** Splitting tests" + } + forvalues j=1/`nbitems' { + tempname estneg`j' estpos`j' + local listitems + forvalues k=1/`nbitems' { + if `j'!=`k' { + local listitems `listitems' ``k'' + } + } + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + qui raschtestv7 `listitems' if ``j''==0,test(NONE) meth(cml) `ld' id(`id') + matrix `estneg`j''=r(beta) + local llneg=r(cll) + qui raschtestv7 `listitems' if ``j''==1,test(NONE) meth(cml) `ld' id(`id') + matrix `estpos`j''=r(beta) + local llpos=r(cll) + qui raschtestv7 `listitems',test(NONE) meth(cml) `ld' id(`id') + local llnegpos=r(cll) + local nbcol=colsof(`estneg`j'') + local meanneg=0 + local meanpos=0 + forvalues k=1/`nbcol' { + local meanneg=`meanneg'+`estneg`j''[1,`k'] + local meanpos=`meanpos'+`estpos`j''[1,`k'] + } + local meanneg=`meanneg'/`nbitems' + local meanpos=`meanpos'/`nbitems' + forvalues k=1/`nbcol' { + matrix `estneg`j''[1,`k']=`estneg`j''[1,`k']-`meanneg' + matrix `estpos`j''[1,`k']=`estpos`j''[1,`k']-`meanpos' + if "`method'"=="cml" { + matrix `estneg`j''=`estneg`j'',-`meanneg' + matrix `estpos`j''=`estpos`j'',-`meanpos' + } + } + drop _all + qui set obs `=`nbitems'+1' + tempvar neg pos name diag + qui gen `neg'=. + qui gen `pos'=. + qui gen str9 `name'="" + local min=`estneg`j''[1,1] + local max=`estneg`j''[1,1] + forvalues k=1/`=`nbitems'-1' { + qui replace `neg'=`estneg`j''[1,`k'] in `k' + qui replace `pos'=`estpos`j''[1,`k'] in `k' + local min=min(`min',`estneg`j''[1,`k'],`estpos`j''[1,`k']) + local max=max(`max',`estneg`j''[1,`k'],`estpos`j''[1,`k']) + local tmp:word `k' of `listitems' + qui replace `name'="`tmp'" in `k' + } + local min=floor(`min') + local max=floor(`max')+1 + qui gen `diag'=. + qui replace `diag'=`min' in `nbitems' + qui replace `diag'=`max' in `=`nbitems'+1' + local Zgr=round(2*(`llneg'+`llpos'-`llnegpos'),0.001) + local Zgr=substr("`Zgr'",1,6) + local pgr=round(1-chi2(`=`nbitems'-1',`Zgr'),0.0001) + local pgr=substr("`pgr'",1,5) + local note="Z=`Zgr', df=`=`nbitems'-1' , p=`pgr'" + if "`filessave'"!=""{ + local saving "`dirsave'\\split``j''" + } + if "`v8'"!="" { + graph twoway (scatter `pos' `neg' ,mlabel(`name')) (line `diag' `diag'), ytitle("Positive answer") xtitle("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title(Splitting on ``j'') `draw' legend(off) note("Andersen Z test: `note'") name(split,replace) `draw' + pause + if "`filessave'"!="" { + graph save split "`saving'" , `replace' + } + } + else { + if "`filessave'"!="" { + local saving "saving(`saving'" + if "`replace'"=="" { + local saving "`saving')" + } + else { + local saving "`saving',replace)" + } + } + qui replace `diag'=`neg' if `diag'==. + graph `pos' `diag' `diag', `saving' c(.l) sy([`name']i) l1title("") l2title("Positive answer") b2title("Negative answer") xlabel(`min'(1)`max') ylabel(`min'(1)`max') title("Splitting on ``j'' (`note')") `draw' + pause + } + } +} + +/*********************************************************************************************************** +OPTION GRAPH +************************************************************************************************************/ + +if "`graph'"!=""&"`v8'"!="" { + if "`trace'"!="" { + di in green "*** Graph option" + } + tempvar latent2 tl2 delta2 tlth2 labdelta2 labtl2 + drop _all + qui set obs 1001 + gen `latent2'=(_n-501)/100 + label variable `latent2' "latent trait" + qui gen `tl2'=. + qui gen `labtl2'="" + forvalues i=0/`nbitems' { + *if (`i'!=0&`i'!=`nbitems')|"`method'"!="cml" { + qui replace `tl2'=`nbrealscore`i''/`N' if round(`latent2',0.01)==round(`theta`i'',0.01) + qui replace `labtl2'="`i'" if round(`latent2',0.01)==round(`theta`i'',0.01) + *} + } + qui gen `delta2'=. + qui gen `labdelta2'="" + forvalues i=1/`nbitems' { + qui replace `delta2'=-.05 if round(`latent2',0.01)==round(`beta`i'',0.01) + qui replace `labdelta2'="``i''" if round(`latent2',0.01)==round(`beta`i'',0.01) + } + if "`method'"=="mml"|"`method'"=="gee" { + qui gen `tlth2'=1/(2*_pi*`sig')*exp(-.5*(`latent2'/`sig')^2) + label variable `tlth2' "Theorical distribution" + local graphmml line `tlth2' `latent2' + } + label variable `tl2' "Score" + label variable `delta2' "Items" + local saving "`dirsave'\\graph" + if "`html'"!="" { + local saving "`c(tmpdir)'/`html'_map" + } + local min=-2 + local max=2 + forvalues j=1/`nbitems' { + if `beta`j''<`min' { + local min=`beta`j''-.5 + } + if `beta`j''>`max'&`beta`j''!=. { + local max=`beta`j''+.5 + } + } + if "`method'"=="cml" { + if `theta0'<`min' { + local min=`theta0'-.5 + } + if `theta`=`nbitems'-1''>`max' { + local max=`theta`=`nbitems'-1''+.5 + } + } + else if "`method'"!="cml" { + if `theta0'<`min'&`theta0'!=. { + local min=`theta0'-.5 + } + if `theta`nbitems''>`max'&`theta`nbitems''!=. { + local max=`theta`nbitems''+.5 + } + } + local min=floor(`min') + local max=floor(`max')+1 + qui su `tl2' + local max2=r(max) + if "`method'"!="cml" { + qui su `tlth2' + local max2=max(`max2',`r(max)') + } + qui replace `latent2'=. if `latent2'<`min'|`latent2'>`max' + if "`v8'"!="" { + graph twoway (bar `tl2' `latent2',/*mlabel(`labtl2')*/ barwidth(.3) ) (dropline `delta2' `latent2',mlabel(`labdelta2') mlabposition(6)) (`graphmml'), `htmlregion' name(graph,replace) ytitle("") xlabel(`min'(1)`max') ylabel(-.1 0(0.05)`max2') title("Individuals/items representations") xsize(12) ysize(9) `draw' + if "`filessave'"!="" { + graph save graph "`saving'" , `replace' + } + if "`html'"=="" { + pause + } + else { + qui graph save graph "`saving'" , `replace' + qui graph export `c(tmpdir)'/`html'_map.eps, replace + di " _char(34) " + } + } +} +else if "`graph'"!=""&"`v8'"=="" { + di in ye "The graph option is not available with Stata 7" +} + +/*********************************************************************************************************** +COMPARISON OF TWO POPULATION +************************************************************************************************************/ + +if "`comp'"!=""&"`method'"!="cml" { + di + di _col(4) "{hline 30}" + di _col(4) in green "Comparison of two populations" + di _col(4) "{hline 30}" + di + di _col(4) in green "`comp'==`mincomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmin' _col(30) in green "mean= " _col(35) in yellow %8.4f `meanmin' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmin' + di _col(4) in green "`comp'==`maxcomp':" _col(20) "N=" _col(22) in yellow %7.0f `Nmax' _col(30) in green "mean= " _col(35) in yellow %8.4f `meanmax' _col(45) in green "variance=" _col(55) in yellow %8.4f `varmax' + di _col(33) in green "Z= " _col(35) in yellow %8.4f `Zcomp' _col(47) in green "pvalue= " _col(57) in yellow %6.4f `pvalue' +} + +/*********************************************************************************************************** +TEST DIF +************************************************************************************************************/ + +if "`method'"=="cml"&"`dif'"!=""&"`test'"!="NONE" { + if "`trace'"!="" { + di in green "*** Tests of DIF" + } + local ssll=0 + tempname DIFfile + qui save "`DIFfile'", replace + qui use "`saveraschtest'",replace + qui keep if `touse'==1 + unab list:`dif' + local nbdif:word count `list' + tempname DIF + matrix define `DIF'=J(`nbdif',4,0) + local count=1 + di + di _col(4) in green "{hline 45}" + di _col(4) in green "Test of Differential Item Functioning (DIF)" + di _col(4) in green "{hline 45}" + foreach j in `list' { + qui inspect `j' + local nbdif=r(N_unique) + qui su `j' + local maxdif=r(max) + if `nbdif'>10&`maxdif'<=10 { + di in ye "The {hi:dif} option is available with variables containing 10 or less modalities (coded from 0 or 1 to k<10)." + di in ye "The variable `j' (`nbdif' modalities) is omitted." + } + else { + local ssll=0 + forvalues i=0/10 { + qui count if `j'==`i' + local effdif=r(N) + if `effdif'>0 { + qui raschtestv7 `varlist' if `j'==`i', test(NONE) id(`id') + local ll`i'=r(cll) + local ssll=`ssll'+(`ll`i'') + } + } + local Z=2*`ssll'-2*`ll' + local ddl=(`nbdif'-1)*(`nbitems'-1) + matrix define `DIF'[`count',1]=(`count',`Z',`ddl',1-chi2(`ddl',`Z')) + di + di _col(4) in green "Variable:" in ye " `j' " in green " Number of groups: " in ye "`nbdif'" + di _col(4) in green "LR Test Z=" in ye %8.3f `Z' in gr " ddl=" in ye %4.0f `ddl' in gr " p-value=" in ye %6.4f `=1-chi2(`ddl',`Z')' + di + } + local ++count + } + use "`DIFfile'",replace +} + +/*********************************************************************************************************** +RETURN +************************************************************************************************************/ + +if "`trace'"!="" { + di in green "*** Returns" +} +local colnametheta + +forvalues i=0/`nbgroups' { + local colnametheta `colnametheta' score_`i' +} + + +return clear + +if `nbitems'>=3&"`test'"!="NONE" { + matrix colnames `globalfit'=`namewp' df p + matrix rownames `globalfit'=`method' + matrix rownames `itemfit'=`varlist' + matrix roweq `itemfit'=`method' + + if "`method'"=="cml" { + matrix colnames `itemfit'=`namewp' df p outfit infit U + matrix rownames `AndersenZ'=`method' + matrix colnames `AndersenZ'=Z df p + return matrix AndersenZ=`AndersenZ' + if "`dif'"!="" { + matrix rownames `DIF'=`list' + matrix colnames `DIF'=num Z df p + return matrix DIF=`DIF' + } + } + else { + matrix colnames `itemfit'=`namewp' df p outfit infit + } + return matrix itemFit=`itemfit' + return matrix globalFit=`globalfit' +} + +matrix colnames `theta'=`colnametheta' +matrix rownames `theta'=theta +return matrix theta `theta' +matrix colnames `sdtheta'=`colnametheta' +matrix rownames `sdtheta'=`colnametheta' +return matrix Vartheta `sdtheta' +local varlist2 +matrix coleq `beta'=`method' +matrix coleq `Vbeta'=`method' +matrix roweq `Vbeta'=`method' +if "`method'"=="cml" { + forvalues i=1/`=`nbitems'-1' { + local varlist2 `varlist2' ``i'' + } + return scalar cll=`ll' + return scalar ll=`globalll' + local AIC=-2*`globalll'+2*(`nbitems'-1) +} +else { + return scalar ll=`ll' + local varlist2 `varlist' + return scalar sigma=`sig' + return scalar sesigma=`sesig' + local AIC=-2*`ll'+2*(`nbitems'+1) +} + +if "`comp'"!="" { + return scalar Zcomp=`Zcomp' + return scalar pZcomp=`pvalue' +} + +matrix colnames `beta'=`varlist2' +matrix rownames `beta'=beta +return matrix beta `beta' + +matrix colnames `Vbeta'=`varlist2' +matrix rownames `Vbeta'=`varlist2' +return matrix Varbeta `Vbeta' + +return scalar AIC=`AIC' +return scalar N=`nbind' +return scalar N_obs=`nbobserv' + +if "`method'"=="mml" { + return scalar PSI=`psi2' + return scalar PSIadj=`psi' +} +if "`covariables'"!="" { + local tmp + local tmp2 + forvalues i=1/`nbcovariables' { + local tmp `tmp' `covariable`i'' + local tmp2 "`tmp2' :`covariable`i''" + } + matrix colnames `betacov'=`tmp2' + matrix rownames `Vbetacov'=`tmp2' + matrix colnames `Vbetacov'=`tmp2' + matrix colnames `zcovariates'=`tmp' + matrix colnames `pcovariates'=`tmp' + return matrix betacovariates=`betacov' + return matrix Vbetacovariates=`Vbetacov' + return matrix zcovariates=`zcovariates' + return matrix pcovariates=`pcovariates' +} +if "`pause'"!="" { + pause off +} + +drop _all + +restore,not +use "`saveraschtest'" + +/*********************************************************************************************************** +CREATE EVENTUAL NEW VARIABLES +************************************************************************************************************/ + +*set trace on +if "`genres'"!="" { + qui sort `id' + qui merge `id' using `ltsave' + qui rename `u'm1 `genlt' + qui rename `u's1 se`genlt' + qui drop _merge se`genlt' + forvalues i=1/`nbitems' { + gen `genres'`i'=exp(``i''*(`genlt'-`beta`i''))/(1+exp(`genlt'-`beta`i''))/sqrt(exp(`genlt'-`beta`i'')/(1+exp(`genlt'-`beta`i''))^2) + } + corr `genres'* + pca `genres'* + drop `u'm1 +} +if "`genfit'"!=""|"`genlt'"!=""|"`genscore'"!="" { + tempname genlt2 genscore2 outfit2 infit2 + qui gen `score'=0 `if' + forvalues i=1/`nbitems' { + qui replace `score'=`score'+``i'' `if' + } + if "`genscore'"!="" { + qui gen `genscore'=`score' `if' + } + if "`genlt'"!="" { + if "`replacegenlt'"=="replace" { + capture drop `genlt' + capture drop se`genlt' + } + if "`method'"=="mml" { + qui sort `id' + qui merge `id' using `ltsave' + qui rename `u'm1 `genlt' + qui rename `u's1 se`genlt' + qui drop _merge + } + else if "`method'"!="mml" { + qui gen `genlt2'=. `if' + forvalues i=0/`nbitems' { + qui replace `genlt2'=`theta`i'' `if'&`score'==`i' + } + qui gen `genlt'=`genlt2' `if' + } + } + if "`genfit'"!="" { + local outfit:word 1 of `genfit' + local infit:word 2 of `genfit' + qui gen `outfit'=0 `if' + qui gen `infit'=0 `if' + tempname infit1 infit2 + qui gen `infit1'=0 `if' + qui gen `infit2'=0 `if' + forvalues j=1/`nbitems' { + tempname pi`j' + qui gen `pi`j''=exp(`genlt2'-`beta`j'')/(1+exp(`genlt2'-`beta`j'')) `if' + qui replace `pi`j''=0 `if' + forvalues s=1/`nbitems' { + qui replace `pi`j''=`Pi'[`j',`s'] `if'&`score'==`s' + } + qui gen `outfit'``j''=(``j''-`pi`j'')^2/(`pi`j''*(1-`pi`j'')) `if' + qui replace `infit1'=`infit1'+(``j''-`pi`j'')^2 `if' + qui replace `infit2'=`infit2'+(`pi`j''*(1-`pi`j'')) `if' + qui replace `outfit'=`outfit'+`outfit'``j''/`nbitems' `if' + } + qui replace `infit'=`infit1'/`infit2' `if' + } +} + +if "`trace'"!=""|"`time'"!="" { + capture qui elapse `st' + di in green "** Time : " in yellow "$S_elap " in green "seconds" +} + +end diff --git a/Modules/ado/personal/r/raschtestv8.10.ado b/Modules/ado/personal/r/raschtestv8.10.ado new file mode 100644 index 0000000..cc6b694 --- /dev/null +++ b/Modules/ado/personal/r/raschtestv8.10.ado @@ -0,0 +1,206 @@ +*! version 8.10 5july2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Raschtest: Rasch model, fit tests and graphical validation +* +* Historic: +* Version 1 (2003-06-30): Jean-Benoit Hardouin +* Version 2 (2003-07-07): Jean-Benoit Hardouin +* Version 3 (2004-01-02): Jean-Benoit Hardouin +* Version 4 (2004-01-21): Jean-Benoit Hardouin +* Version 5 (2004-01-24): Jean-Benoit Hardouin +* Version 6 (2004-02-05): Jean-Benoit Hardouin +* Version 6.1 (2004-03-29): Jean-Benoit Hardouin +* Version 6.2 (2004-04-06): Jean-Benoit Hardouin +* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin +* Version 7 (2005-04-02) : Jean-Benoit Hardouin +* Version 7.2 (2005-05-20) : Jean-Benoit Hardouin +* Version 7.3 (2005-07-02) : Jean-Benoit Hardouin +* Version 7.4 (2006-01-15) : Jean-Benoit Hardouin +* Version 7.5 (2006-04-20) : Jean-Benoit Hardouin +* Version 7.6 (2008-06-20) : Jean-Benoit Hardouin /*nold option*/ +* Version 8 (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/ +* Version 8.3 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option*/ +* Version 8.6 (2012-11-19) : Jean-Benoit Hardouin /*HTML option*/ +* Version 8.9 (2019-06-05) : Jean-Benoit Hardouin /*PNG option*/ +* Version 8.10 (2019-06-05) : Jean-Benoit Hardouin /*EXTENSION option*/ +* +* Required modules : +* raschtestv7 version 8.1 (http://freeirt.free.fr) +* gammasym version 2.2 (http://www.freeirt.org) +* gausshermite version 1 (http://www.freeirt.org) +* geekel2d version 4.3 (http://www.freeirt.org) +* genscore version 1.4 (http://www.freeirt.org) +* ghquadm (findit ghquadm) +* gllamm version 2.3.14 (ssc describe gllamm) +* gllapred version 2.3.7 (ssc describe gllapred) +* elapse (ssc describe elapse) +* +* Jean-benoit Hardouin - University of Nantes - France +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research" +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* +* Copyright 2003-2012, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + + +program define raschtest,eclass +syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) GENRes(string) EXTension(string) graphclose docx(string)] + +local nbitems:word count `varlist' +if "`method'"=="" { + local method "cml" +} +else { + local method=lower("`method'") +} +if "`test'"=="" { + local test "R" +} +else { + local test=upper("`test'") +} +if "`dirsave'"!="" { + local dirsavev8 "dirsave(`dirsave')" +} +if "`method'"!="" { + local methodv8 "method(`method')" +} +if "`test'"!="" { + local testv8 "test(`test')" +} +if "`group'"!="" { + local groupv8 "group(`group')" +} +if "`genlt'"!="" { + local genltv8 "genlt(`genlt')" +} +if "`genscore'"!="" { + local genscorev8 "genscore(`genscore')" +} +if "`genres'"!="" { + local gensresv8 "genres(`genres')" +} +if "`genfit'"!="" { + local genfitv8 "genfit(`genfit')" +} +if "`comp'"!="" { + local compv8 "comp(`comp')" +} +if "`dif'"!="" { + local difv8 "dif(`dif')" +} +if "`iterate'"!="" { + local iteratev8 "iterate(`iterate')" +} +if "`difficulties'"!="" { + local difficultiesv8 "difficulties(`difficulties')" +} +if "`covariates'"!="" { + local covariatesv8 "covariates(`covariates')" +} + +raschtestv7 `varlist' `if' `in' , id(`id') html(`html') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genresv8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8' `png' extension(`extension') `graphclose' docx(`docx') + +/*********************************************************************************************************** +RETURN +************************************************************************************************************/ + +ereturn clear +if `nbitems'>=3 { + if "`method'"=="cml" { + if "`test'"!="none" { + tempname AndersenZv8 + matrix `AndersenZv8'=r(AndersenZ) + ereturn matrix AndersenZ=`AndersenZv8' + } + if "`dif'"!="" { + tempname DIFv8 + matrix `DIFv8'=r(DIF) + ereturn matrix DIF=`DIFv8' + } + tempname cllv8 + scalar `cllv8'=r(cll) + ereturn scalar cll=`cllv8' + + } + if "`test'"!="NONE" { + tempname itemFitv8 globalFitv8 + matrix `itemFitv8'=r(itemFit) + matrix `globalFitv8'=r(globalFit) + ereturn matrix itemFit=`itemFitv8' + ereturn matrix globalFit=`globalFitv8' + } +} + +if "`method'"!="cml" { + tempname sigmav8 sesigmav8 + local `sigmav8'=`r(sigma)' + local `sesigmav8'=`r(sesigma)' + ereturn scalar sigma=``sigmav8'' + ereturn scalar sesigma=``sesigmav8'' +} + +tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8 +matrix `betav8'=r(beta) +matrix `Varbetav8'=r(Varbeta) +ereturn matrix beta=`betav8' +ereturn matrix Varbeta=`Varbetav8' +matrix `thetav8'=r(theta) +matrix `Varthetav8'=r(Vartheta) +ereturn matrix theta=`thetav8' +ereturn matrix Vartheta=`Varthetav8' +scalar `llv8'=`r(ll)' +scalar `AICv8'=`r(AIC)' +ereturn scalar ll=`llv8' +ereturn scalar AIC=`AICv8' +ereturn scalar Zcomp=r(Zcomp) +ereturn scalar pZcomp=r(pZcomp) + + +if "`method'"=="mml" { + local psi=r(PSI) + local psiadj=r(PSIadj) + ereturn scalar PSI=`psi' + ereturn scalar PSIadj=`psiadj' +} +if "`covariates'"!="" { + tempname betacovariates Vbetacovariates zcovariates pcovariates + matrix `betacovariates'=r(betacovariates) + matrix `Vbetacovariates'=r(Vbetacovariates) + matrix `zcovariates'=r(zcovariates) + matrix `pcovariates'=r(pcovariates) + + ereturn matrix betacovariates=`betacovariates' + ereturn matrix Vbetacovariates=`Vbetacovariates' + ereturn matrix zcovariates=`zcovariates' + ereturn matrix pcovariates=`pcovariates' +} + + + + +return clear + +end diff --git a/Modules/ado/personal/r/raschtestv86.ado b/Modules/ado/personal/r/raschtestv86.ado new file mode 100644 index 0000000..d70abde --- /dev/null +++ b/Modules/ado/personal/r/raschtestv86.ado @@ -0,0 +1,205 @@ +*! version 8.6 19november2012 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Raschtest: Rasch model, fit tests and graphical validation +* +* Historic: +* Version 1 (2003-06-30): Jean-Benoit Hardouin +* Version 2 (2003-07-07): Jean-Benoit Hardouin +* Version 3 (2004-01-02): Jean-Benoit Hardouin +* Version 4 (2004-01-21): Jean-Benoit Hardouin +* Version 5 (2004-01-24): Jean-Benoit Hardouin +* Version 6 (2004-02-05): Jean-Benoit Hardouin +* Version 6.1 (2004-03-29): Jean-Benoit Hardouin +* Version 6.2 (2004-04-06): Jean-Benoit Hardouin +* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin +* Version 7 (2005-04-02) : Jean-Benoit Hardouin +* Version 7.2 (2005-05-20) : Jean-Benoit Hardouin +* Version 7.3 (2005-07-02) : Jean-Benoit Hardouin +* Version 7.4 (2006-01-15) : Jean-Benoit Hardouin +* Version 7.5 (2006-04-20) : Jean-Benoit Hardouin +* Version 7.6 (2008-06-20) : Jean-Benoit Hardouin /*nold option*/ +* Version 8 (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/ +* Version 8.3 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option*/ +* Version 8.6 (2012-11-19) : Jean-Benoit Hardouin /*HTML option*/ +* +* Needed modules : +* raschtestv7 version 8.1 (http://freeirt.free.fr) +* gammasym version 2.2 (http://www.freeirt.org) +* gausshermite version 1 (http://www.freeirt.org) +* geekel2d version 4.3 (http://www.freeirt.org) +* genscore version 1.4 (http://www.freeirt.org) +* ghquadm (findit ghquadm) +* gllamm version 2.3.14 (ssc describe gllamm) +* gllapred version 2.3.7 (ssc describe gllapred) +* elapse (ssc describe elapse) +* +* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France +* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences" +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2003-2012 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + + +program define raschtest,eclass +syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) GENRes(string)] + +local nbitems:word count `varlist' +if "`method'"=="" { + local method "cml" +} +else { + local method=lower("`method'") +} +if "`test'"=="" { + local test "R" +} +else { + local test=upper("`test'") +} +if "`dirsave'"!="" { + local dirsavev8 "dirsave(`dirsave')" +} +if "`method'"!="" { + local methodv8 "method(`method')" +} +if "`test'"!="" { + local testv8 "test(`test')" +} +if "`group'"!="" { + local groupv8 "group(`group')" +} +if "`genlt'"!="" { + local genltv8 "genlt(`genlt')" +} +if "`genscore'"!="" { + local genscorev8 "genscore(`genscore')" +} +if "`genres'"!="" { + local gensresv8 "genres(`genres')" +} +if "`genfit'"!="" { + local genfitv8 "genfit(`genfit')" +} +if "`comp'"!="" { + local compv8 "comp(`comp')" +} +if "`dif'"!="" { + local difv8 "dif(`dif')" +} +if "`iterate'"!="" { + local iteratev8 "iterate(`iterate')" +} +if "`difficulties'"!="" { + local difficultiesv8 "difficulties(`difficulties')" +} +if "`covariates'"!="" { + local covariatesv8 "covariates(`covariates')" +} + +raschtestv7 `varlist' `if' `in' , id(`id') html(`html') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genresv8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8' + +/*********************************************************************************************************** +RETURN +************************************************************************************************************/ + +ereturn clear +if `nbitems'>=3 { + if "`method'"=="cml" { + if "`test'"!="none" { + tempname AndersenZv8 + matrix `AndersenZv8'=r(AndersenZ) + ereturn matrix AndersenZ=`AndersenZv8' + } + if "`dif'"!="" { + tempname DIFv8 + matrix `DIFv8'=r(DIF) + ereturn matrix DIF=`DIFv8' + } + tempname cllv8 + scalar `cllv8'=r(cll) + ereturn scalar cll=`cllv8' + + } + if "`test'"!="NONE" { + tempname itemFitv8 globalFitv8 + matrix `itemFitv8'=r(itemFit) + matrix `globalFitv8'=r(globalFit) + ereturn matrix itemFit=`itemFitv8' + ereturn matrix globalFit=`globalFitv8' + } +} + +if "`method'"!="cml" { + tempname sigmav8 sesigmav8 + local `sigmav8'=`r(sigma)' + local `sesigmav8'=`r(sesigma)' + ereturn scalar sigma=``sigmav8'' + ereturn scalar sesigma=``sesigmav8'' +} + +tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8 +matrix `betav8'=r(beta) +matrix `Varbetav8'=r(Varbeta) +ereturn matrix beta=`betav8' +ereturn matrix Varbeta=`Varbetav8' +matrix `thetav8'=r(theta) +matrix `Varthetav8'=r(Vartheta) +ereturn matrix theta=`thetav8' +ereturn matrix Vartheta=`Varthetav8' +scalar `llv8'=`r(ll)' +scalar `AICv8'=`r(AIC)' +ereturn scalar ll=`llv8' +ereturn scalar AIC=`AICv8' +ereturn scalar Zcomp=r(Zcomp) +ereturn scalar pZcomp=r(pZcomp) + + +if "`method'"=="mml" { + local psi=r(PSI) + local psiadj=r(PSIadj) + ereturn scalar PSI=`psi' + ereturn scalar PSIadj=`psiadj' +} +if "`covariates'"!="" { + tempname betacovariates Vbetacovariates zcovariates pcovariates + matrix `betacovariates'=r(betacovariates) + matrix `Vbetacovariates'=r(Vbetacovariates) + matrix `zcovariates'=r(zcovariates) + matrix `pcovariates'=r(pcovariates) + + ereturn matrix betacovariates=`betacovariates' + ereturn matrix Vbetacovariates=`Vbetacovariates' + ereturn matrix zcovariates=`zcovariates' + ereturn matrix pcovariates=`pcovariates' +} + + + + +return clear + +end diff --git a/Modules/ado/personal/r/rel.ado b/Modules/ado/personal/r/rel.ado new file mode 100644 index 0000000..77dd72b --- /dev/null +++ b/Modules/ado/personal/r/rel.ado @@ -0,0 +1,203 @@ +capture program drop rel +program rel,rclass +syntax varlist, PARTition(numlist integer >0) [SCOrename(string) Alpha(real 0.7) Delta(real 0.9) h(real 0.3) HJmin(real 0.3)] + +local C = 0 +foreach z in `partition' { + local C = `C' + `z' +} + +local nbvars : word count `varlist' + +if `C' != `nbvars' { + di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist" + exit +} + +local P:word count `partition' +if "`scorename'" !="" { + local S:word count `scorename' + if `P'!=`S' { + di in red "The number of score names given is different from the number of dimensions in the partition option" + exit + } +} +di as result "{hline}" +di "{bf:Reliability}" +di as result "{hline}" +di + +local y = 1 +local nbitems = 0 +matrix aa = J(`P',4,.) + +foreach z in `partition' { + local nbitems = `nbitems' + `z' +} + +local i = 1 +foreach x in `varlist' { + local var`i' = "`x'" + local `++i' +} + +matrix d = J(`nbitems',2,.) + +local i = 1 +foreach x in `partition' { + + if `i' == 1 local s = `x' + else local s = `s' +`x' + + local liste = "" + forvalues w = `y'/`s' { + local liste `liste' `var`w'' + } + + *qui count if !=. + + capture qui alpha `liste', asi item std + local al`i' = r(alpha) + local n`i' = e(N) + + capture qui loevh `liste', pairwise + local h`i' = r(loevH) + mat a = r(Obs) + *local n`i' = a[1,1] + matrix c = r(loevHj) + matrix ct = c' + + + local lister = "" + forvalues w = `y'/`s' { + tempvar z + qui gen `z' = round(`var`w'') + local lister `lister' `z' + } + + capture qui delta `lister' + local delt`i' = r(delta) + + + // on remplit d avec les valeurs de ct + local k = 0 + forvalues j = `y'/`s' { + local k = `k'+1 + matrix d[`j',1] = ct[`k',1] + matrix d[`j',2] = `i' + } + + matrix aa [`i',1] = `al`i'' + matrix aa [`i',2] = `delt`i'' + matrix aa [`i',3] = `h`i'' + + local `i++' + local y = `s'+1 +} + +matrix rownames d = `varlist' +local i = 1 +local y = 1 + +foreach x in `partition' { + if `i' == 1 local s = `x' + else local s = `s' +`x' + + matrix C = d[`y'..`s',1.] + local min`i' = C[1,1] + local n : rownames C + tokenize `n' + local t`i' = "`1'" + forvalues j = 1/`x' { + local t = "``j''" + if C[`j',1] <= `min`i'' { + local min`i' = C[`j',1] + local t`i' = "``j''" + local itmin`i' = "``j''" + } + } + *di "`t`i''" + matrix aa [`i',4] = `min`i'' + local `i++' + local y = `s'+1 +} + +matrix colnames aa = "alpha" "delta" "H" "Hj_min" + +if "`scorename'"=="" { + local i = 1 + local y = 1 + local name + local nname + forvalues i = 1/`P' { + local name "Dim`i'" + local nname `nname' `name' + } +local scorename = "`nname'" +} + +local maxlen = 0 +foreach sco in `scorename' { + local w = length("`sco'") + if `w' > `maxlen' local maxlen = `w' +} + +local i = 1 +local j = 1 +local y = 1 +local col = `maxlen'+8 +di _col(`col') "{bf:n}" _c +local col = `col'+5 +di _col(`col') "{bf:alpha}" _c +local col = `col'+8 +di _col(`col') "{bf:delta}" _c +local col = `col'+11 +di _col(`col') "{bf:H}" _c +local col = `col'+5 +di _col(`col') "{bf:Hj_min}" +*di "{hline 41}" + + +foreach s in `scorename' { + di in blue "{bf:`s'}" _c + local col = `maxlen'+3 + local n : di %6.0f `n`i'' + di in blue _col(`col') "{text:`n'}" _c + local col = `col'+10 + + local a : di %5.2f `al`i'' + if `a' < `alpha' { + di _col(`col') "{error:`a'} " _c + } + else di _col(`col') "{text:`a'}" _c + + local col = `col'+8 + local d : di %5.2f `delt`i'' + if `d' < `delta' { + di _col(`col') "{error:`d'} " _c + } + else di _col(`col') "{text:`d'}" _c + + local col = `col'+8 + local h : di %4.2f `h`i'' + if `h' < `h' { + di _col(`col') "{error:`h'} " _c + } + else di _col(`col') "{text:`h'}" _c + + local col = `col'+8 + local m : di %6.2f `min`i'' + if `m' < `hjmin' { + di _col(`col') "{error:`m'} " _c + di "{text:(item `itmin`i'')}" _c + } + else di _col(`col') "{text:`m'}" _c + + di + local `++i' +} + +end + +*rel ioc1-ioc37, partition(4 4 7 3 3 4 7 5) scorename(HA PSE W BCC AC AE LI MOC) a(0.7) d(0.9) h(0.3) hjmin(0.3) +*rel x1-x40, partition(5 5 5 5 5 5 5 5) scorename(HA PSE W BCC AC AE LI MOC) a(0.7) d(0.9) h(0.3) hjmin(0.3) diff --git a/Modules/ado/personal/r/repet.ado b/Modules/ado/personal/r/repet.ado new file mode 100644 index 0000000..26cd4d2 --- /dev/null +++ b/Modules/ado/personal/r/repet.ado @@ -0,0 +1,275 @@ +capture program drop repet +program repet,rclass +syntax varlist [in], t2(varlist) PARTition(numlist integer >0) calcmethod(string) [SCOrename(string) KAPpa ICKAPpa(integer 0)] +preserve + +local nbvars : word count `varlist' + +if "`in'"!="" { + qui keep `in' +} + +if `ickappa' <= 0 { + local ickappa = "" +} + +/* +if "`ickappa'" != "" & "`kappa'" == "" { + di "{it:The ickappa option is ignored}" +} +*/ + +local C = 0 +foreach z in `partition' { + local C = `C' + `z' +} + +local nbvars : word count `varlist' +if `C' != `nbvars' { + di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist" + exit +} + +/* +qui tab `id', nofreq +local u = r(r) +if `u' != _N { + di in red "The variable `ident' has not unique values" + exit +} +*/ + +local P:word count `partition' +if "`scorename'" !="" { + local S:word count `scorename' + if `P'!=`S' { + di in red "The number of score names given is different from the number of dimensions in the partition option" + exit + } +} +else { + local name + local nname + forvalues i = 1/`P' { + local name "Dim`i'" + local nname `nname' `name' + } +local scorename = "`nname'" +} + +local a:word count `varlist' +local b:word count `t2' +if `a' != `b' di in red "The number of items is not the same in t1 and t2" + +/* coupure noms des scores */ +/* +local i = 1 +foreach s in `scorename' { + local len = length("`s'") + if `len' > 10 { + local c = substr("`s'",1,9) + local d = substr("`s'",-1,1) + local s`i' "`c'" "~" "`d'" + } + else local s`i' = "`s'" + local sc `sc' `s`i'' + local `++i' +} +*/ + +local i = 1 +foreach s in `scorename' { + local s`i' = abbrev("`s'",10) + local sc `sc' `s`i'' + local `++i' +} + +/* coupure noms des items */ +/* +local i = 1 +foreach s in `varlist' { + local len = length("`s'") + if `len' > 10 { + local c = substr("`s'",1,9) + local var`i' "`c'" + } + else local var`i' = "`s'" + local `++i' +} +*/ + +local i = 1 +foreach v in `varlist' { + local var`i' = abbrev("`v'",10) + local `++i' +} + +local maxit = 1 +forvalues i=1/`nbvars' { + local len = length("`var`i''") + if `len' > `maxit' local maxit = `len' +} + +local decit = `maxit' + 4 +local colit = `decit' + + + +di as result "{hline}" +di as result "{bf:Reproducibility}" +di as result "{hline}" +di + +foreach sco in `scorename' { + *local t = "`sco'bis" + tempname s + local scorename2 `scorename2' `s' +} + +qui calcscore `t2', scorename(`scorename2') partition(`partition') calcmethod(`calcmethod') + +local i = 1 +foreach var in `varlist' { + tokenize `t2' + qui kap `var' ``i'' + local k`i' = r(kappa) + if "`ickappa'" != "" { + qui kapci `var' ``i'', reps(`ickappa') + local lbk`i' = r(lb_bc) + local ubk`i' = r(ub_bc) + } + local `++i' +} + +local i = 1 +foreach s in `scorename' { + tokenize `scorename2' + tempname score id temps + qui gen `id' = _n + qui gen `score'_1 = `s' + qui gen `score'_2 = ``i'' if ``i''!=. + qui reshape long `score'_, i(`id') j(`temps') + qui icc `score'_ `id' + local n`i' = r(N_target) + local icc`i' = r(icc_i) + local lb`i' = r(icc_i_lb) + local ub`i' = r(icc_i_ub) + *qui drop `score' `temps' `id' + qui sort `id' + qui duplicates drop `id', force + local `++i' +} + +tokenize `sc' +local max = length("dimension") + +forvalues j=1/`P' { + local len`j' = length("`s`j''") + if `len`j'' > `max' local max = `len`j'' +} + +local dec = `max' + 5 + +local i = 1 +local j = 1 +local y = 1 +di "{bf:Dimension}" _c +di _col(`=`dec'+2') "{bf:n}" _c +local col = `dec'+6 +di _col(`col') "{bf:Item}" _c +local col = `col'+`decit' + +if "`kappa'" != "" { + di _col(`col') "{bf:Kappa}" _c + local col = `col'+10 + if "`ickappa'" != "" { + di _col(`col') "{bf:95% CI for Kappa}" _c + local col = `col'+20 + } + +} + +di _col(`=`col'+2') "{bf:ICC}" _c +local col = `col'+9 +di _col(`col') "{bf:95% CI for ICC}" + +local zz = 0 +foreach var in `varlist' { + qui levelsof `var', local(levels) + local z : word count `levels' + if `z' > 2 local zz = 1 +} + +if "`kappa'" != "" & "`ickappa'" != "" & `zz' == 1 { + local col = `dec'+`decit'+16 + di _col(`col') "{bf:(bootstrapped)}" +} + + +if "`ickappa'" != "" local h = `dec'+6+`decit'+10+8+21+12+1 +else if "`kappa'" != "" local h = `dec'+6+`decit'+10+8+21+12-20 +else local h = `dec'+6+`decit'+10+8+21+12-30 +di "{hline `h'}" + +local i = 1 +foreach p in `partition' { + tokenize `sc' + di "{bf:``i''}" _c + di _col(`dec') "{text:`n`i''}" _c + if `j' == 1 local s = `p' + else local s = `s' +`p' + local col = `dec'+6 + di _col(`col') "{text:`var`y''}" _c + + if "`kappa'" != "" { + local k : di %5.2f `k`y'' + local col = `col'+`decit' + di _col(`col') "{text:`k'}" _c + if "`ickappa'" != "" { + local lbk : di %5.2f `lbk`i'' + local ubk : di %5.2f `ubk`i'' + local col = `col'+11 + di _col(`col') "{text:[`lbk' ; `ubk']}" _c + local col = `decit'+50 + } + + else local col = `decit'+30 + } + else local col = `decit'+20 + + *local col = `decit'+30 + local icc : di %5.2f `icc`i'' + di _col(`col') "{text:`icc'}" _c + local lb : di %5.2f `lb`i'' + local ub : di %5.2f `ub`i'' + local col = `col'+8 + di _col(`col')"{text:[`lb' ; `ub']}" + local w = `y'+1 + + forvalues z = `w'/`s' { + local col = `dec'+6 + di _col(`col') "{text:`var`z''}" _c + if "`kappa'" != "" { + local k : di %5.2f `k`z'' + local col = `col'+`decit' + di _col(`col') "{text:`k'}" _c + if "`ickappa'" != "" { + local lbk : di %5.2f `lbk`z'' + local ubk : di %5.2f `ubk`z'' + local col = `col'+11 + di _col(`col')"{text:[`lbk' ; `ubk']}" + } + else di + + } + else di + } + local `i++' + local `j++' + local y = `s'+1 + di +} +end + +*repet ioc1-ioc37, t2(ptgi1-peur16) partition(4 4 7 3 3 4 7 5) scorename(HA PSE W BCC AC AE LI MOC) kappa ickappa(20) +*repet sf36_3q_intenses sf36_3q_moderees sf36_3q_soulever sf36_3q_etages sf36_3q_etage sf36_3q_pencher sf36_3q_15km sf36_3q_500m sf36_3q_100m sf36_3q_douche sf36_4q_limite_temps_travail sf36_4q_moins_choses sf36_4q_type_travail sf36_4q_effort , t2(sf36_3q_intenses_v5 sf36_3q_moderees_v5 sf36_3q_soulever_v5 sf36_3q_etages_v5 sf36_3q_etage_v5 sf36_3q_pencher_v5 sf36_3q_15km_v5 sf36_3q_500m_v5 sf36_3q_100m_v5 sf36_3q_douche_v5 sf36_4q_limite_temps_travail_v5 sf36_4q_moins_choses_v5 sf36_4q_type_travail_v5 sf36_4q_effort_v5 ) partition(10 4) diff --git a/Modules/ado/personal/r/rosali.ado b/Modules/ado/personal/r/rosali.ado new file mode 100644 index 0000000..1276ba1 --- /dev/null +++ b/Modules/ado/personal/r/rosali.ado @@ -0,0 +1,3137 @@ +*! version 2.4 june2020 +*! Myriam Blanchin - Priscilla Brisson +************************************************************************************************************ +* ROSALI: RespOnse-Shift ALgorithm at Item-level +* Response-shift detection based on Rasch models family +* +* Version 1 : December 21, 2016 (Myriam Blanchin) /*rspcm122016*/ +* Version 1.1 : October 13, 2017 (Myriam Blanchin) /*option: MODA, automatic recoding of unused response categories*/ +* Version 2 : April, 2018 (Myriam Blanchin - Priscilla Brisson) /*option: GROUP, dichotomous group variable*/ +* Version 2.1 : October, 2018 (Myriam Blanchin - Priscilla Brisson) /* Version 1.1 + Version 2 */ +* Version 2.2 : February, 2019 (Priscilla Brisson) /* option nodif, optimization */ +* Version 2.3 : December, 2019 (Priscilla Brisson) /* option detail, + petites corrections */ +* Version 2.4 : June, 2020 (Myriam Blanchin) /* debug option detail + step C, modifs sorties et help */ +* +* Myriam Blanchin, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* myriam.blanchin@univ-nantes.fr +* +* Priscilla Brisson, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* priscilla.brisson@univ-nantes.fr +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define rosali, rclass + +timer clear 1 +timer on 1 + +syntax varlist(min=2 numeric) [if] [,GROUP(varlist) NODIF PRO DETail] + +preserve +version 15 +tempfile saverspcm +capture qui save `saverspcm',replace +local save1=_rc + +if "`if'"!="" { + qui keep `if' +} + +if "`pro'" != "" { + di "START" +} + +/**************************************************************************/ +set more off +set matsize 5000 +constraint drop _all + +local gp "`group'" + +tokenize `varlist' +local nbitems:word count `varlist' + + /* VĂ©rif nb d'items pair */ +local mod=mod(`nbitems',2) +if `mod'!=0 { + di as error "You must enter an even number of items : the first half of the items represents the items at time 1 and the second half the items at time 2" + error 198 + exit +} + +local nbitems=`nbitems'/2 + + +if "`group'"=="" & "`nodif'"!="" { + di as error "nodif can only be used with the group option ({hi:nodif} option). Please correct this option." + error 198 + exit +} + +local nbc: word count `group' +if `nbc' >= 2 { + di as error "Only one variable can be used for group option ({hi:group} option). Please correct this option." + error 198 + exit +} + + /* VĂ©rif qu'il y a 2 groupes si l'option groupe est choisie */ +if "`group'"!="" { + qui tab `group' + local nbgrp = r(r) + if `nbgrp' != 2 { + di as error "Only 2 groups are possible for the group option ({hi:group} option). Please correct this option." + error 420 + exit + } +} +/* recoder la variable de groupe en 0, 1*/ + +if "`group'"!="" { + qui tab `gp', matrow(rep) + qui matrix list rep + if rep[1,1]+rep[2,1] != 1 & rep[1,1]*rep[2,1] != 0 { + forvalues i=1/`=rowsof(rep)'{ + qui replace `gp'=`i'-1 if `gp'==rep[`i',1] + di "WARNING : `gp' `=rep[`i',1]' is now `gp' `=`i'-1' " + } + } + forvalues g = 0/1 { + qui tab `gp' if `gp' == `g' + local nbp_gp`g' = r(N) + } +} + + + +/*item rename*/ +/* +Items au temps 1 : 1 Ă  nbitems ``j'' +Items au temps 2 : nbitems Ă  2*nbitems ``=`j'+`nbitems''' + +Si t varie, puis num item : ``=(`t'-1)*`nbitems'+`j''' +*/ + + +local com_z = 0 // Indicatrice de recodage + /*verif modalitĂ©s rĂ©pondues*/ +if "`gp'" == "" { // Si pas d'option groupe + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'', matrow(rect1_`j') // RĂ©cupĂ©ration des infos moda du temps 1 + local minm`j'_t1 = rect1_`j'[1,1] + local maxm`j'_t1 = rect1_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''', matrow(rect2_`j') // RĂ©cupĂ©ration des infos moda du temps 2 + local minm`j'_t2 = rect2_`j'[1,1] + local maxm`j'_t2 = rect2_`j'[r(r),1] + + local minm_`j' = min(`minm`j'_t1',`minm`j'_t2') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1',`maxm`j'_t2') + local nbm_`j' = `=`maxm_`j''-`minm_`j''' + + if `minm_`j'' != 0 & `com_z' == 0 { + local com_z = 1 + } + + + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`nbm_`j'' { + qui count if ``j'' == `m' + local nb_rn1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' + local nb_rn2 = r(N) + local nb_rn = min(`nb_rn1',`nb_rn2') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' <= `minm`j'_t1' | `m' <= `minm`j'_t2' { // La moda 0 ou les moda min ne sont pas utilisĂ©es + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged " + local stop = 0 + } + } + } + else if `m' >= `maxm`j'_t1' | `m' >= `maxm`j'_t2' | `m' == `maxm_`j'' { // La (ou les) moda max ne sont pas utilisĂ©e(s) + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems''' =`=`m'-`k'' if ``=`j'+`nbitems''' ==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} +else { // Cas oĂč l'option groupe est utilisĂ©e + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'' if `gp' == 0, matrow(rect1_g0_`j') matcell(nbrt1_g0_`j') // RĂ©cupĂ©ration des infos moda du temps 1pour chaque groupe + local minm`j'_t1_g0 = rect1_g0_`j'[1,1] + local maxm`j'_t1_g0 = rect1_g0_`j'[r(r),1] + + qui tab ``j'' if `gp' == 1, matrow(rect1_g1_`j') matcell(nbrt1_g1_`j') + local minm`j'_t1_g1 = rect1_g1_`j'[1,1] + local maxm`j'_t1_g1 = rect1_g1_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''' if `gp' == 0, matrow(rect2_g0_`j') matcell(nbrt2_g0_`j') // RĂ©cupĂ©ration des infos moda du temps 2 pour chaque groupe + local minm`j'_t2_g0 = rect2_g0_`j'[1,1] + local maxm`j'_t2_g0 = rect2_g0_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''' if `gp' == 1 , matrow(rect2_g1_`j') matcell(nbrt2_g1_`j') + local minm`j'_t2_g1 = rect2_g0_`j'[1,1] + local maxm`j'_t2_g1 = rect2_g0_`j'[r(r),1] + + local minm_`j' = min(`minm`j'_t1_g0',`minm`j'_t2_g0',`minm`j'_t1_g1',`minm`j'_t2_g1') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1_g0',`maxm`j'_t2_g0',`maxm`j'_t1_g1',`maxm`j'_t2_g1') + local nbm_`j' = `=`maxm_`j''-`minm_`j''+1' + + if `minm_`j'' != 0 & `com_z' == 0 { + local com_z = 1 + } + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`=`nbm_`j''-1' { + qui count if ``j'' == `m' & `gp' == 0 + local nb_rn1_g0 = r(N) + qui count if ``j'' == `m' & `gp' == 1 + local nb_rn1_g1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 0 + local nb_rn2_g0 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 1 + local nb_rn2_g1 = r(N) + local nb_rn = min(`nb_rn1_g0',`nb_rn2_g0',`nb_rn1_g1',`nb_rn2_g1') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' < `minm`j'_t1_g0' | `m' < `minm`j'_t2_g0' | `m' < `minm`j'_t1_g1' | `m' < `minm`j'_t2_g1' { // La moda 0 n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + } + } + else if `m' == `=`nbm_`j''-1' | `m' >= `maxm`j'_t2_g0' | `m' >= `maxm`j'_t1_g1' | `m' >= `maxm`j'_t2_g1' { // La moda max n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`m'' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0 ) & `stop' != 0 { + qui replace ``j''= `=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { // Moda central non utilisĂ©e + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'-`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0{ + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} + +if `com_z' == 1 { + di + di "WARNING : Automatic recoding, the first response category is 0. see {help rosali:help rosali}." + di +} + +forvalues j =1/`nbitems' { + qui tab ``j'', matrow(rec) // RĂ©cupĂ©ration des infos moda du temps 1 + local nbm`j'_t1 = r(r) + + qui tab ``=`j'+`nbitems''' // RĂ©cupĂ©ration des infos moda du temps 2 + local nbm`j'_t2 = r(r) + + local nbm_`j' = max(`nbm`j'_t1', `nbm`j'_t2') + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`nbm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=rec[`=`r'+1',1]' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=rec[`=`r'+1',1]' + } +} + +/* Calcul de nbmoda & nbdif */ +forvalues j = 1/`nbitems' { + qui tab ``j'' + local nbmoda_`j' = r(r) + local nbdif_`j' = r(r) - 1 +} + +local maxdif = 0 +local nbmoda_sum = 0 +forvalues j = 1/`nbitems' { + if `maxdif' < `nbdif_`j'' { + local maxdif = `nbdif_`j'' + } + local nbmoda_sum = `nbmoda_sum' + `nbdif_`j'' +} + +/* Au moins 2 moda par item */ +forvalues j=1/`nbitems' { + if `nbmoda_`j'' == 1 { + di as error "``j'' have only one response category, the analysis can be performed only if each item has at least 2 response categories" + error 198 + exit + } +} + +local coln "" +forvalues j =1 /`nbitems' { + local coln "`coln' ``j''" +} + +matrix nbmod = J(2,`nbitems',.) + +matrix colnames nbmod = `coln' +matrix rownames nbmod = NbModa Recoding + +forvalues j = 1/`nbitems' { + matrix nbmod[1,`j'] = `nbmoda_`j'' + matrix nbmod[2,`j'] = `recoda_`j'' +} + +*Erreur si plus de 200 difficultĂ©s +local nb_test = 0 +forvalues j=1/`nbitems' { + local nb_test = `nb_test'+`nbmoda_`j'' -1 +} + +if `nb_test' >= 200 { + di as error "The total number of items difficulties to be estimated must be less than 200 ({hi:moda} option option)." + error 198 + exit +} + +local nbitp = 0 + +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' >= 2 { + local nbitp = `nbitp' + 1 + } +} + +qui count +local nbpat = r(N) + + +/********************************* +* AFFICHAGE INITIAL +*********************************/ +di +di _col(5) "{hline 78}" +di _col(15) "Time 1" _col(42) "Time 2" _col(65) "Nb of Answer Cat." +di _col(5) "{hline 78}" +forvalues j=1/`nbitems' { + di as text _col(15) abbrev("``j''",20) _col(42) abbrev("``=`j'+`nbitems'''",20) _col(65) `nbmoda_`j'' +} +di _col(5) "{hline 78}" +if "`group'" != "" { + di _col(10) "Nb of patients: " abbrev("`gp'",20) " 0 = `nbp_gp0' ;", abbrev("`gp'",20) " 1 = `nbp_gp1'" + di _col(5) "{hline 78}" +} +else { + di _col(10) "Nb. of patients: `nbpat'" + di _col(5) "{hline 78}" +} +di +if `nbitems' == 1 { + di as error "The analysis can only be performed with at least 2 items." + error 198 + exit +} +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' == 2 { + di "WARNING: ``j'' has only 2 response categories, no distinction can be made between uniform or non-uniform recalibration." + } + if `nbmoda_`j'' == 1 { + di as error "Only `nbmoda_`j'' response categories of item ``j'' were used by the sample, the analysis cannot be performed." + error 198 + exit + } + if `nbmoda_`j'' == 0 { + di as error "No response categories of item ``j'' were used by the sample, the analysis cannot be performed." + error 198 + exit + } +} +di +if "`group'" != "" { + di _col(2) as text "For all models : - mean of the latent trait in `gp' 0 at time 1 is constrained at 0" + di _col(19) "- equality of variances between groups" + di +} +else { + di _col(2) as text "For all models : mean of the latent trait at time 1 is constrained at 0" + di +} + + + +/********************************* +* DEFINITION DES CONTRAINTES +*********************************/ + +if "`group'"!="" { // Contraintes si option groupe + *EGALITE ENTRE GROUPES A T1 (1-200) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=0+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``j'']1.`gp' + } + } + + *DIF UNIFORME A T1 (201-400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=200+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp'=`p'*[1.``j'']1.`gp'-`p'*[1.``j'']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 0 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 1 (601-800) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=600+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp' + } + } + + * RC COMMUNE (801-1000) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=800+`maxdif'*(`j'-1)+`p'' [`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + * RC UNIFORME, groupe 0 (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp' + } + } + + * RC UNIFORME, groupe 1 (1201-1400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1200+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + *Sans interaction temps x groupe + constraint 1999 [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'=[/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' +} +else { //Contraintes si pas d'option groupe + *EGALITE ENTRE T1 et T2 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']:_cons = [`p'.``=`j'+`nbitems''']:_cons + } + } + *RC UNIFORME (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']:_cons - [1.``j'']:_cons)=[`p'.``=`j'+`nbitems''']:_cons -[`p'.``j'']:_cons + } + } +} + +/********************************* +* MATRICE DES RESULTATS +*********************************/ +matrix dif_rc=J(`nbitems',8,.) +matrix colnames dif_rc=DIFT1 DIFU RC RC_DIF RCG0 RCUG0 RCG1 RCUG1 +local rown "" + +forvalues j =1 /`nbitems' { + local rown "`rown' ``j''" +} +matrix rownames dif_rc = `rown' + +*Nb modalitĂ© max +local nbdif_max = 0 +forvalues j=1/`nbitems' { + if `nbdif_max' < `nbdif_`j'' { + local nbdif_max = `nbdif_`j'' + } +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////// PARTIE 1 : DIF A T1 ? //////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +if "`group'"!="" & "`nodif'"=="" { // PARTIE 1 = Slmt si option group & pas de "nodif" + + di _dup(49) "_ " + di + di as input "PART 1: DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES BETWEEN GROUPS AT TIME 1" + + ********************************* + ** MODEL B ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading cons) var(0: THETA@v) var(1:THETA@v) latent(THETA) nocapslatent + /* Stockage des estimations du modĂšle */ + estimates store modeldifB + matrix val_mB = r(table) + matrix esti_B = e(b) + + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mB=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + + matrix colnames delta_mB = `name_partOneC' + matrix rownames delta_mB = `name_partOneL' + matrix delta_mB_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mB_se = `name_partOneC_se' + matrix rownames delta_mB_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB=r(estimate) + local delta`j'_`p'g`g'mB_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB = r(estimate) + local delta`j'_`p'g`g'mB_se = r(se) + } + matrix delta_mB[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB' + matrix delta_mB_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB_se' + } + } + } + + matrix var_mB = (val_mB[1,"/var(THETA)#0bn.`gp'"]\val_mB[2,"/var(THETA)#0bn.`gp'"]) + + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmB=r(estimate) + local segeffmB=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmBp=r(p) + local gcmBchi=r(chi2) + local gcmBdf=r(df) + + + ********************************* + ** MODEL A ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading means) var(0: THETA@v) var(1:THETA@v) from(esti_B, skip) latent(THETA) nocapslatent + + /* Stockage des estimations du modĂšle */ + estimates store modeldifA + matrix val_mA = r(table) + matrix esti_A = e(b) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mA=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mA = `name_partOneC' + matrix rownames delta_mA = `name_partOneL' + matrix delta_mA_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mA_se = `name_partOneC_se' + matrix rownames delta_mA_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA=r(estimate) + local delta`j'_`p'g`g'mA_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA = r(estimate) + local delta`j'_`p'g`g'mA_se = r(se) + } + matrix delta_mA[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA' + matrix delta_mA_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA_se' + } + } + } + //Variance et se mA + matrix var_mA = (val_mA[1,"/var(THETA)#0bn.`gp'"]\val_mA[2,"/var(THETA)#0bn.`gp'"]) + + + ************************************************************* + ***********************AFFICHAGE***************************** + ************************************************************* + + + //Affichage modĂšle A + di + di as input "PROCESSING STEP A" + di + + if "`detail'" != "" { + /* Affichage des estimations des difficultĂ©s modĂšle A */ + + di _col(5) as text "{ul:MODEL A:} Overall measurement non-invariance between groups" + di + di %~85s as text "Item difficulties: estimates (s.e.)" + di _col(10) "{hline 65}" + di _col(31) as text abbrev("`gp'",20) "=0" _col(57) abbrev("`gp'",20) "=1" + di _col(10) "{hline 65}" + forvalues j=1/`nbitems' { + di as text _col(10) abbrev("``j''", 18) + forvalues p=1/`nbdif_`j'' { + di as text _col(10) "`p'" as result _col(30) %6.2f `delta`j'_`p'g0mA' %6.2f " (" %3.2f `delta`j'_`p'g0mA_se' ")" _col(56) %6.2f `delta`j'_`p'g1mA' " (" %3.2f `delta`j'_`p'g1mA_se' ")" + } + } + di as text _col(10) "{hline 65}" + /* Affichage des estimations sur le trait latent du modĂšle A */ + di + di %~85s as text "Latent trait distribution" + di _col(10) "{hline 65}" + di _col(31) "Estimate" _col(57) "Standard error" + di _col(10) "{hline 65}" + di _col(10) "Variance" as result _col(31) %6.2f `=var_mA[1,1]' _col(55) %6.2f `=var_mA[2,1]' + di _col(10) as text "Group effect" as result _col(31) "0 (constrained)" + di _col(10) as text "{hline 65}" + di + di _col(10) as text "No group effect: equality of the latent trait means between groups" + di _col(10) as text "All item difficulties are freely estimated in both groups" + di + } + //*Affichage modĂšle B + + di + di as input "PROCESSING STEP B" + di + + /* Affichage des estimations des difficultĂ©s modĂšle B */ + if "`detail'" != "" { + di _col(5) as text "{ul:MODEL B:} Overall measurement invariance between groups" + di + di %~85s as text "Item difficulties: estimates (s.e.)" + di _col(10) "{hline 65}" + di _col(31) abbrev("`gp'",20) "=0" _col(57) abbrev("`gp'",20) "=1" + di _col(10) "{hline 65}" + + forvalues j=1/`nbitems' { + di _col(10) as text "``j''" + forvalues p=1/`nbdif_`j'' { + di as text _col(10) "`p'" as result _col(30) %6.2f `delta`j'_`p'g0mB' " (" %3.2f `delta`j'_`p'g0mB_se' ")" _col(56) %6.2f `delta`j'_`p'g1mB' " (" %3.2f `delta`j'_`p'g1mB_se' ")" + } + } + + di _col(10) as text "{hline 65}" + /* Affichage des estimations sur le trait latent du modĂšle B */ + di + di %~85s as text "Latent trait distribution" + di _col(10) "{hline 65}" + di _col(28) "Estimate" _col(42) "Standard error" _col(62) "P-value" + di _col(10) "{hline 65}" + di _col(10) "Variance" as result _col(28) %6.2f `=var_mB[1,1]' _col(40) %6.2f `=var_mB[2,1]' + di _col(10) as text "Group effect" as result _col(28) %6.2f `geffmB' _col(40) %6.2f `segeffmB' _col(62) %6.4f `gcmBp' + di _col(10) as text "{hline 65}" + di + di _col(10) as text "Group effect estimated: mean of the latent trait of group 1 freely estimated" + di _col(10) "Equality of the item difficulties between groups" + di + } + + ***************************************************** + * ModĂšle A vs ModĂšle B * + ***************************************************** + + qui lrtest modeldifA modeldifB + local diftestp=r(p) + local diftestchi=r(chi2) + local diftestdf=r(df) + if "`detail'" != "" { + //affichage lrtest + di as input "LIKELIHOOD-RATIO TEST" + di + di %~60s "Model A vs Model B" + di _col(10) "{hline 40}" + di _col(10) as text "Chi-square" _col(28) "DF" _col(40) "P-value" + di _col(10) as result %6.2f `diftestchi' _col(28) %2.0f `diftestdf' _col(40) %6.4f `diftestp' + di _col(10) as text "{hline 40}" + di + } + + if `diftestp'<0.05{ + di as result "DIFFERENCE IN ITEM DIFFICULTIES BETWEEN GROUPS LIKELY" + } + else{ + di as result "NO DIFFERENCE BETWEEN GROUPS DETECTED" + } + ********************************* + *************MODEL C************* + ********************************* + // Etape itĂ©rative si lrtest significatif + local nb_stepC = 0 + if `diftestp'<0.05{ /*If pvalue(LRtest)<0.05 then step C*/ + di + di as input "PROCESSING STEP C" + di + + /*test DIF pour chaque item*/ + local boucle = 1 + local stop = 0 + while `boucle'<=`=`nbitp'-1' & `stop'==0{ /*on s'arrĂȘte quand on a libĂ©rĂ© du DIF sur (tous les items-1) ou lorsqu'il n'y a plus de tests significatifs*/ + local nb_stepC = `boucle' + local pajust=0.05/`=`nbitp'+1-`boucle'' + /*rĂ©initialisation de la matrice de test*/ + matrix test_difu_`boucle'=J(`nbitems',3,.) + matrix colnames test_difu_`boucle'=chi_DIFU df_DIFU pvalueDIFU + matrix test_dif_`boucle'=J(`nbitems',3,.) + matrix colnames test_dif_`boucle'=chi_DIF df_DIF pvalueDIF + local nbsig=0 + local minpval=1 + local itemdif=0 + if "`detail'" != ""{ + + di as text "Loop `boucle'" + di as text _col(5) "Adjusted alpha: " %6.4f `pajust' + di + di as text _col(10) "{hline 65}" + di as text _col(10) "Freed item" _col(31) "Chi-Square" _col(48) "DF" _col(57) "P-Value" + di as text _col(10) "{hline 65}" + } + /*boucle de test*/ + forvalues j=1/`nbitems'{ + //if `nbdif_`j'' > 2 { + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF dĂ©jĂ  dĂ©tectĂ© sur l'item j*/ + /*on libĂšre le DIF de l'item i: pas de contraintes*/ + forvalues k=1/`nbitems'{ /*contraintes pour les autres items (si DIF NU sur item k, pas de contraintes*/ + if `k'!=`j' & `nbmoda_`j'' >= 2 { + if dif_rc[`k',1]==. | dif_rc[`k',1]==0 {/*pas de DIF sur item k: contraintes 1-200*/ + forvalues p=1/`nbdif_`k''{ + qui local listconst "`listconst' `=0+`maxdif'*(`k'-1)+`p''" + qui constraint list `=0+`maxdif'*(`k'-1)+`p'' + } + } + else{ + if dif_rc[`k',2]!=. & dif_rc[`k',2]!= 0 & `nbmoda_`k'' > 2 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`k''{ + qui local listconst "`listconst' `=200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + } + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) latent(THETA) nocapslatent + estimates store modeldif3b`boucle'it`i' + + ************************* + *****test DIF item i***** + ************************* + qui test [1.``j'']1.`gp'=[1.``j'']0bn.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']1.`gp'=[`p'.``j'']0bn.`gp', acc + } + } + matrix test_dif_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + + /* Test DIF Uniforme */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``j'']1.`gp'-[1.``j'']0bn.`gp')=[2.``j'']1.`gp'-[2.``j'']0bn.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``j'']1.`gp'-[1.``j'']0bn.`gp')=[`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp', acc + } + matrix test_difu_`boucle'[`j',1]=(r(chi2), r(df), r(p)) + } + + if test_dif_`boucle'[`j',3]<`pajust'{/*si DIF sur item i*/ + local ++nbsig + if test_dif_`boucle'[`j',3]<`minpval'{ + local minpval=test_dif_`boucle'[`j',3] + local itemdif=`j' + } + } + if "`detail'" != "" { + di as text _col(10) abbrev("``j''",15) as result _col(31) %6.3f test_dif_`boucle'[`j',1] _col(48) test_dif_`boucle'[`j',2] _col(57) %6.4f test_dif_`boucle'[`j',3] + } + } + } + /*si nb de tests significatifs=0, on arrĂȘte*/ + if `nbsig'==0{ + local stop=1 + if `boucle' == 1 { + if "`detail'" != "" { + di as text _col(10) "{hline 65}" + di + di as result "No significant test: no difference between groups detected, no DIF detected" + di + } + } + else { + if "`detail'" != ""{ + di as text _col(10) "{hline 65}" + di + di as result "No other significant tests" + di + } + } + } + else{/*si nb de tests significatifs>0, mise Ă  jour de la matrice de rĂ©sultats*/ + matrix dif_rc[`itemdif',1]=`boucle' + if "`detail'" != ""{ + di as text _col(10) "{hline 65}" + di + di as result "Difference between groups on ``itemdif'' at time 1" + } + if `nbmoda_`itemdif'' > 2 { + if "`detail'" != "" { + + di + di %~60s as text "Test of uniform difference" + di _col(10) "{hline 40}" + di _col(10) as text "Chi-square" _col(28) "DF" _col(40) "P-value" + di _col(10) as result %4.2f `=test_difu_`boucle'[`itemdif',1]' _col(28) `=test_difu_`boucle'[`itemdif',2]' _col(40) %4.2f `=test_difu_`boucle'[`itemdif',3]' + di _col(10) as text "{hline 40}" + } + if test_difu_`boucle'[`itemdif',3]<0.05{ /*DIF NU dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=0 + di + di as result "``itemdif'' : Non-uniform differences of item difficulties between groups at T1" + di + } + else{/*DIF U dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=`boucle' + di + di as result "``itemdif'' : Uniform differences of item difficulties between groups at T1" + di + } + } + else { + // DiffĂ©rence entre groupes au temps 1 mais slmt 2 moda. donc pas de U ou NU + di _col(15) _dup(60) "-" + } + } + local ++boucle + } + } + + /* MODELE FINAL DE LA PARTIE 1. Si DIFT1 dĂ©tectĂ© (=Au moins 2 boucles dans l'Ă©tape C)*/ + if `nb_stepC' > 1 { + forvalues j=1/`nbitems'{ + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF: contraintes 1-200*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) latent(THETA) nocapslatent + /* Stockage des estimations du modĂšle */ + estimates store modeldifCFin + matrix val_mC = r(table) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mCFin=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mCFin = `name_partOneC' + matrix rownames delta_mCFin = `name_partOneL' + + matrix delta_mCFin_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + matrix colnames delta_mCFin_se = `name_partOneC_se' + matrix rownames delta_mCFin_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin=r(estimate) + local delta`j'_`p'g`g'mCFin_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin = r(estimate) + local delta`j'_`p'g`g'mCFin_se = r(se) + } + matrix delta_mCFin[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin' + matrix delta_mCFin_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin_se' + } + } + } + if "`group'" != "" { //Variance et se mA + matrix var_mC = (val_mC[1,"/var(THETA)#0bn.`gp'"]\val_mC[2,"/var(THETA)#0bn.`gp'"]) + } + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmCFin=r(estimate) + local segeffmCFin=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmCFinp=r(p) + local gcmCFinchi=r(chi2) + local gcmCFindf=r(df) + } +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////// PARTIE 2 : RECALIBRATION ? //////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +di +di as text _dup(49) "_ " +di +if "`group'" != "" { + di as input "PART 2 : DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES ACROSS TIME (RECALIBRATION)" +} +else { + di as input "DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES ACROSS TIME (RECALIBRATION)" +} + + ********************************* + ** MODEL 2 ** + ********************************* + +local listconst "" // liste des contraintes si option groupe +local listconst_g "" //LIste des contraintes sans option groupe (Notation peu logique !!) + +forvalues j=1/`nbitems'{ + if "`group'" == "" { // Contraintes pas de RC pour tous les items + forvalues p=1/`nbdif_`j''{ + local listconst_g "`listconst_g' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + } + else { + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 {/*pas de DIF Ă  T1 sur item k: contraintes 1*/ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else{ + if dif_rc[`j',2]!=. & dif_rc[`j',2] != 0 { /*diff T1 U: contraintes 200*/ + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + forvalues p=1/`nbdif_`j''{ /* egalites entre temps : groupe 0 (401-600)*/ + local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + forvalues p=1/`nbdif_`j''{ /* egalites entre temps : groupe 1 (601-800)*/ + local listconst "`listconst' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=600+`maxdif'*(`j'-1)+`p'' + } + } +} + +local model "" +forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA1@`p')(`p'.``=`j'+`nbitems'''<-THETA2@`p')" + } +} + +if "`group'" != "" { +*di "gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') latent(THETA1 THETA2) nocapslatent" + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') latent(THETA1 THETA2) nocapslatent +} +else { + qui gsem `model', mlogit tol(0.01) iterate(100) means(THETA1@0 THETA2@m20) var(THETA1@v1 THETA2@v2) cov(THETA1*THETA2@cov12) constraint(`listconst_g') latent(THETA1 THETA2) nocapslatent +} + +/*Stockage des donnĂ©es du modĂšle 2 */ +estimates store model2 +matrix val_m2 = r(table) +matrix esti_2 = e(b) + +if "`group'" != "" { + matrix var_m2 = (val_m2[1,"/var(THETA1)#0bn.`gp'"],val_m2[1,"/var(THETA2)#0bn.`gp'"]\val_m2[2,"/var(THETA1)#0bn.`gp'"],val_m2[2,"/var(THETA2)#0bn.`gp'"]) + matrix covar_m2 = (val_m2[1,"/cov(THETA1,THETA2)#0.`gp'"],val_m2[1,"/cov(THETA1,THETA2)#1.`gp'"]\val_m2[2,"/cov(THETA1,THETA2)#0.`gp'"],val_m2[2,"/cov(THETA1,THETA2)#1.`gp'"]\val_m2[4,"/cov(THETA1,THETA2)#0.`gp'"],val_m2[4,"/cov(THETA1,THETA2)#1.`gp'"]) +} +else { + matrix var_m2 = (val_m2[1,"/var(THETA1)"],val_m2[1,"/var(THETA2)"]\val_m2[2,"/var(THETA1)"],val_m2[2,"/var(THETA2)"]) + matrix covar_m2 = (val_m2[1,"/cov(THETA1,THETA2)"]\val_m2[2,"/cov(THETA1,THETA2)"]\val_m2[4,"/cov(THETA1,THETA2)"]) +} + +/*group effect*/ +if "`group'" != "" { + qui lincom [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' + local geffm2=r(estimate) + local segeffm2=r(se) + local ubgeffm2 = r(ub) + local lbgeffm2 = r(lb) + qui test [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp'=0 + local gpm2p=r(p) + local gpm2chi=r(chi2) + local gpm2df=r(df) +} + +/*time effect*/ +if "`group'" != "" { + qui lincom [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp' + local teffm2=r(estimate) + local seteffm2=r(se) + local ubteffm2 = r(ub) + local lbteffm2 = r(lb) + qui test [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp'=0 + local tm2p=r(p) + local tm2chi=r(chi2) + local tm2df=r(df) +} +else { + qui lincom [/]:mean(THETA2) /* [/]:mean(THETA1)*/ + local teffm2=r(estimate) + local seteffm2=r(se) + local ubteffm2 = r(ub) + local lbteffm2 = r(lb) + qui test [/]:mean(THETA2) = 0 /* [/]:mean(THETA1)*/ + local tm2p=r(p) + local tm2chi=r(chi2) + local tm2df=r(df) +} + +*INTERACTION +if "`group'" != "" { + qui lincom [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#1.`gp'+[/]:mean(THETA1)#0bn.`gp' + local interm2=r(estimate) + local seinterm2=r(se) + local ubinterm2 = r(ub) + local lbinterm2 = r(lb) + qui test [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#1.`gp'+[/]:mean(THETA1)#0bn.`gp' = 0 + local interm2p=r(p) + local interm2chi=r(chi2) + local interm2df=r(df) +} + +if "`group'" != "" { + matrix mod2 = J(7,`=`nbmoda_sum'*4+6',.) + local name_partTwoC "" + forvalues j = 1/`nbitems' { + forvalues p=1/`nbdif_`j'' { + forvalues t=1/2 { + forvalues g = 0/1 { + local name_partTwoC "`name_partTwoC' d_j`j'_p`p'_gp`g'_t`t'" + } + } + } + } + local name_partTwoC "`name_partTwoC' VAR(THETA1) VAR(THETA2) COV(TH1,TH2) GROUP_Effect TIME_Effect INTER_TxG " + matrix colnames mod2 = `name_partTwoC' + matrix rownames mod2 = Estimate se Upper_b Lower_b Chi_square DF pvalue +} +else { + matrix mod2 = J(7,`=`nbmoda_sum'*2+4',.) + local name_partTwoC "" + forvalues j = 1/`nbitems' { + forvalues p=1/`nbdif_`j'' { + forvalues t=1/2 { + local name_partTwoC "`name_partTwoC' d_j`j'_p`p'_t`t'" + } + } + } + local name_partTwoC "`name_partTwoC' VAR(THETA1) VAR(THETA2) COV(TH1,TH2) TIME_Effect " + matrix colnames mod2 = `name_partTwoC' + matrix rownames mod2 = Estimate se Upper_b Lower_b Chi_square DF pvalue +} + +*DifficultĂ©s +forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues t=1/2{ + if "`group'" != "" { // groupe binaire + forvalues g=0/1 { + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm2= r(estimate) + local delta`t'_`j'_`p'g`g'm2_se= r(se) + local delta`t'_`j'_`p'g`g'm2_ub=r(ub) + local delta`t'_`j'_`p'g`g'm2_lb=r(lb) + local delta`t'_`j'_`p'g`g'm2_p=r(p) + if `p'>1 { + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' - [`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm2=r(estimate) + local delta`t'_`j'_`p'g`g'm2_se=r(se) + local delta`t'_`j'_`p'g`g'm2_ub=r(ub) + local delta`t'_`j'_`p'g`g'm2_lb=r(lb) + local delta`t'_`j'_`p'g`g'm2_p=r(p) + } + local place = 0 + local compt = 1 + while `compt' < `j' { + local place = `place' + `nbdif_`compt'' + local ++compt + } + if `t' == 1 { + matrix mod2[1,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2' + matrix mod2[2,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2_se' + matrix mod2[3,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2_ub' + matrix mod2[4,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2_lb' + matrix mod2[7,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2_p' + } + if `t' == 2 { + matrix mod2[1,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2' + matrix mod2[2,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2_se' + matrix mod2[3,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2_ub' + matrix mod2[4,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2_lb' + matrix mod2[7,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2_p' + } + } + } + else { // groupe unique (=gp0) + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']_cons + local delta`t'_`j'_`p'g0m2= r(estimate) + local delta`t'_`j'_`p'g0m2_se= r(se) + local delta`t'_`j'_`p'g0m2_ub=r(ub) + local delta`t'_`j'_`p'g0m2_lb=r(lb) + local delta`t'_`j'_`p'g0m2_p=r(p) + if `p'>1{ + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']_cons - [`p'.``=(`t'-1)*`nbitems'+`j''']_cons + local delta`t'_`j'_`p'g0m2=r(estimate) + local delta`t'_`j'_`p'g0m2_se=r(se) + local delta`t'_`j'_`p'g0m2_ub=r(ub) + local delta`t'_`j'_`p'g0m2_lb=r(lb) + local delta`t'_`j'_`p'g0m2_p=r(p) + } + local place = 0 + local compt = 1 + while `compt' < `j' { + local place = `place' + `nbdif_`compt'' + local ++compt + } + if `t' == 1 { + matrix mod2[1,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2' + matrix mod2[2,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_se' + matrix mod2[3,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_ub' + matrix mod2[4,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_lb' + matrix mod2[7,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_p' + } + if `t' == 2 { + matrix mod2[1,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2' + matrix mod2[2,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_se' + matrix mod2[3,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_ub' + matrix mod2[4,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_lb' + matrix mod2[7,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_p' + } + } + } + } +} + +if "`group'" != "" { + matrix mod2[1,`=4*`nbmoda_sum'+1'] = (val_m2[1,"/var(THETA1)#0bn.`gp'"], val_m2[1,"/var(THETA2)#0bn.`gp'"]) + matrix mod2[2,`=4*`nbmoda_sum'+1'] = (val_m2[2,"/var(THETA1)#0bn.`gp'"],val_m2[2,"/var(THETA2)#0bn.`gp'"]) + matrix mod2[3,`=4*`nbmoda_sum'+1'] = (val_m2[6,"/var(THETA1)#0bn.`gp'"],val_m2[6,"/var(THETA2)#0bn.`gp'"]) + matrix mod2[4,`=4*`nbmoda_sum'+1'] = (val_m2[5,"/var(THETA1)#0bn.`gp'"],val_m2[5,"/var(THETA2)#0bn.`gp'"]) + + matrix mod2[1,`=4*`nbmoda_sum'+2+1'] = (val_m2[1,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod2[2,`=4*`nbmoda_sum'+2+1'] = (val_m2[2,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod2[3,`=4*`nbmoda_sum'+2+1'] = (val_m2[6,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod2[4,`=4*`nbmoda_sum'+2+1'] = (val_m2[5,"/cov(THETA1,THETA2)#0.`gp'"]) + + matrix mod2[1,`=4*`nbmoda_sum'+2+1+1'] = `geffm2' + matrix mod2[2,`=4*`nbmoda_sum'+2+1+1'] = `segeffm2' + matrix mod2[3,`=4*`nbmoda_sum'+2+1+1'] = `ubgeffm2' + matrix mod2[4,`=4*`nbmoda_sum'+2+1+1'] = `lbgeffm2' + matrix mod2[5,`=4*`nbmoda_sum'+2+1+1'] = `gpm2chi' + matrix mod2[6,`=4*`nbmoda_sum'+2+1+1'] = `gpm2df' + matrix mod2[7,`=4*`nbmoda_sum'+2+1+1'] = `gpm2p' + + matrix mod2[1,`=4*`nbmoda_sum'+2+1+1+1'] = `teffm2' + matrix mod2[2,`=4*`nbmoda_sum'+2+1+1+1'] = `seteffm2' + matrix mod2[3,`=4*`nbmoda_sum'+2+1+1+1'] = `ubteffm2' + matrix mod2[4,`=4*`nbmoda_sum'+2+1+1+1'] = `lbteffm2' + matrix mod2[5,`=4*`nbmoda_sum'+2+1+1+1'] = `tm2chi' + matrix mod2[6,`=4*`nbmoda_sum'+2+1+1+1'] = `tm2df' + matrix mod2[7,`=4*`nbmoda_sum'+2+1+1+1'] = `tm2p' + + matrix mod2[1,`=4*`nbmoda_sum'+2+1+1+1+1'] = `interm2' + matrix mod2[2,`=4*`nbmoda_sum'+2+1+1+1+1'] = `seinterm2' + matrix mod2[3,`=4*`nbmoda_sum'+2+1+1+1+1'] = `ubinterm2' + matrix mod2[4,`=4*`nbmoda_sum'+2+1+1+1+1'] = `lbinterm2' + matrix mod2[5,`=4*`nbmoda_sum'+2+1+1+1+1'] = `interm2chi' + matrix mod2[6,`=4*`nbmoda_sum'+2+1+1+1+1'] = `interm2df' + matrix mod2[7,`=4*`nbmoda_sum'+2+1+1+1+1'] = `interm2p' +} +else { + matrix mod2[1,`=2*`nbmoda_sum'+1'] = (val_m2[1,"/var(THETA1)"],val_m2[1,"/var(THETA2)"]) + matrix mod2[2,`=2*`nbmoda_sum'+1'] = (val_m2[2,"/var(THETA1)"],val_m2[2,"/var(THETA2)"]) + matrix mod2[3,`=2*`nbmoda_sum'+1'] = (val_m2[6,"/var(THETA1)"],val_m2[6,"/var(THETA2)"]) + matrix mod2[4,`=2*`nbmoda_sum'+1'] = (val_m2[5,"/var(THETA1)"],val_m2[5,"/var(THETA2)"]) + + matrix mod2[1,`=2*`nbmoda_sum'+2+1'] = (val_m2[1,"/cov(THETA1,THETA2)"]) + matrix mod2[2,`=2*`nbmoda_sum'+2+1'] = (val_m2[2,"/cov(THETA1,THETA2)"]) + matrix mod2[3,`=2*`nbmoda_sum'+2+1'] = (val_m2[6,"/cov(THETA1,THETA2)"]) + matrix mod2[4,`=2*`nbmoda_sum'+2+1'] = (val_m2[5,"/cov(THETA1,THETA2)"]) + + matrix mod2[1,`=2*`nbmoda_sum'+2+1+1'] = `teffm2' + matrix mod2[2,`=2*`nbmoda_sum'+2+1+1'] = `seteffm2' + matrix mod2[3,`=2*`nbmoda_sum'+2+1+1'] = `ubteffm2' + matrix mod2[4,`=2*`nbmoda_sum'+2+1+1'] = `lbteffm2' + matrix mod2[5,`=2*`nbmoda_sum'+2+1+1'] = `tm2chi' + matrix mod2[6,`=2*`nbmoda_sum'+2+1+1'] = `tm2df' + matrix mod2[7,`=2*`nbmoda_sum'+2+1+1'] = `tm2p' +} + + ********************************* + ** MODEL 1 ** + ********************************* + + +/*PCM longitudinal, no true change, group effect, interaction*/ +local listconst "" +forvalues j=1/`nbitems'{ /*contraintes pour les autres items (si DIF NU sur item k, pas de contraintes*/ + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 {/*pas de DIF sur item k: contraintes 1*/ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else{ + if `nbdif_`j'' > 1 { + if dif_rc[`j',2]!=. & dif_rc[`j',2] != 0 { /*diff T1 U: contraintes 201*/ + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } +} + + +local model "" +forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA1@`p')(`p'.``=`j'+`nbitems'''<-THETA2@`p')" + } +} + +if "`group'"!="" { + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@0) means(1: THETA1@m1 THETA2@m1) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) latent(THETA1 THETA2) nocapslatent +} +else { + qui gsem `model', mlogit tol(0.01) iterate(100) means(THETA1@0 THETA2@0) var(THETA1@v1 THETA2@v2) cov(THETA1*THETA2@cov12) from(esti_2, skip) latent(THETA1 THETA2) nocapslatent +} + +/* Stockage des estimations du modĂšle 1 */ +estimates store model1 +matrix val_m1 = r(table) + +/* Calcul des difficultĂ©s d'item (delta_j) */ +matrix delta_m1 = J(`nbitems',`=`nbdif_max'*4',.) +local name_partTwoC "" +forvalues p=1/`nbdif_max' { + forvalues t=1/2 { + forvalues g = 0/1 { + local name_partTwoC "`name_partTwoC' delta_t`t'_`p'_gp`g'" + } + } +} + +local name_partTwoL "" +forvalues j=1/`=`nbitems'*2' { + if `j' <= `nbitems' { + local name_partTwoL "`name_partTwoL' ``j''" + } + else { + local name_partTwoL "`name_partTwoL' ``=`nbitems'+`j'''" + } +} + +matrix colnames delta_m1 = `name_partTwoC' +matrix rownames delta_m1 = `name_partTwoL' + +matrix delta_m1_se = J(`nbitems',`=`nbdif_max'*4',.) +local name_partTwoC_se "" + +forvalues p=1/`nbdif_max' { + forvalues t=1/2 { + forvalues g = 0/1 { + local name_partTwoC_se "`name_partTwoC_se' delta_t`t'_`p'_gp`g'_se" + } + } +} + +matrix colnames delta_m1_se = `name_partTwoC_se' +matrix rownames delta_m1_se = `name_partTwoL' + +if "`group'"!="" { + forvalues t=1/2{ + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm1= r(estimate) + local delta`t'_`j'_`p'g`g'm1_se= r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' - [`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm1=r(estimate) + local delta`t'_`j'_`p'g`g'm1_se=r(se) + } + if `t' == 1 { + matrix delta_m1[`j',`=4*(`p'-1)+`g'+`t'']=`delta`t'_`j'_`p'g`g'm1' + matrix delta_m1_se[`j',`=4*(`p'-1)+`g'+`t'']=`delta`t'_`j'_`p'g`g'm1_se' + } + if `t' == 2 { + matrix delta_m1[`j',`=4*(`p'-1)+1+`g'+`t'']=`delta`t'_`j'_`p'g`g'm1' + matrix delta_m1_se[`j',`=4*(`p'-1)+1+`g'+`t'']=`delta`t'_`j'_`p'g`g'm1_se' + } + } + } + } + } +} +else { + forvalues t=1/2 { + forvalues j=1/`nbitems' { + forvalues p = 1/`nbdif_`j'' { + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']:_cons + local delta`t'_`j'_`p'g0m1= r(estimate) + local delta`t'_`j'_`p'g0m1_se= r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']:_cons - [`p'.``=(`t'-1)*`nbitems'+`j''']:_cons + local delta`t'_`j'_`p'g0m1=r(estimate) + local delta`t'_`j'_`p'g0m1_se=r(se) + } + if `t' == 1 { + matrix delta_m1[`j',`=4*(`p'-1)+`t'']=`delta`t'_`j'_`p'g0m1' + matrix delta_m1_se[`j',`=4*(`p'-1)+`t'']=`delta`t'_`j'_`p'g0m1_se' + } + if `t' == 2 { + matrix delta_m1[`j',`=4*(`p'-1)+1+`t'']=`delta`t'_`j'_`p'g0m1' + matrix delta_m1_se[`j',`=4*(`p'-1)+1+`t'']=`delta`t'_`j'_`p'g0m1_se' + } + } + } + } +} + +if "`group'" != "" { + matrix var_m1 = (val_m1[1,"/var(THETA1)#0bn.`gp'"],val_m1[1,"/var(THETA2)#0bn.`gp'"]\val_m1[2,"/var(THETA1)#0bn.`gp'"],val_m1[2,"/var(THETA2)#0bn.`gp'"]) + matrix covar_m1 = (val_m1[1,"/cov(THETA1,THETA2)#0.`gp'"],val_m1[1,"/cov(THETA1,THETA2)#1.`gp'"]\val_m1[2,"/cov(THETA1,THETA2)#0.`gp'"],val_m1[2,"/cov(THETA1,THETA2)#1.`gp'"]\val_m1[4,"/cov(THETA1,THETA2)#0.`gp'"],val_m1[4,"/cov(THETA1,THETA2)#1.`gp'"]) +} +else { + matrix var_m1 = (val_m1[1,"/var(THETA1)"],val_m1[1,"/var(THETA2)"]\val_m1[2,"/var(THETA1)"],val_m1[2,"/var(THETA2)"]) + matrix covar_m1 = (val_m1[1,"/cov(THETA1,THETA2)"]\val_m1[2,"/cov(THETA1,THETA2)"]\val_m1[4,"/cov(THETA1,THETA2)"]) +} + +/*group effect*/ +if "`group'"!="" { + qui lincom [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' + local geffm1=r(estimate) + local segeffm1=r(se) + qui test [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' = 0 + local gpm1p=r(p) + local gpm1chi=r(chi2) + local gpm1df=r(df) +} + + ************************************************************* + ***********************AFFICHAGE***************************** + ************************************************************* + di + di as input "PROCESSING STEP 1" + di + +if "`detail'" != "" { + // Affichage du modĂšle 1 + + /* Affichage des estimations des difficultĂ©s */ + + if "`group'" != "" { + di _col(5) as text "{ul:MODEL 1:} Overall longitudinal measurement non-invariance across time (RS on all items)" + di + di %~105s as text "Item difficulties: estimates (s.e.)" + di _col(10) "{hline 85}" + di _col(38) "Time 1" _col(76) "Time 2" + di as text _col(26) abbrev("`gp'",15) "=0" _col(44) abbrev("`gp'",15) "=1" _col(64) abbrev("`gp'",15) "=0" _col(82) abbrev("`gp'",15) "=1" + di _col(10) "{hline 85}" + } + else { + di _col(5) as text "{ul:MODEL 1:} Overall longitudinal measurement non-invariance across time (RS on all items)" + di + di %~70s as text as text "Item difficulties: estimates (s.e.)" + di _col(10) "{hline 50}" + di _col(25) "Time 1" _col(42) "Time 2" + di _col(10) "{hline 50}" + } + + forvalues j=1/`nbitems' { + di as text _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + if "`group'" != "" { + di as text _col(10) "`p'" as result _col(25) %6.2f `delta1_`j'_`p'g0m1' " (" %4.2f `delta1_`j'_`p'g0m1_se' ")" _col(43) %6.2f `delta1_`j'_`p'g1m1' " (" %4.2f `delta1_`j'_`p'g1m1_se' ")" /// + _col(63) %6.2f `delta2_`j'_`p'g0m1' " (" %4.2f `delta2_`j'_`p'g0m1_se' ")" _col(81) %6.2f `delta2_`j'_`p'g1m1' " (" %4.2f `delta2_`j'_`p'g1m1_se' ")" + } + else { + di as text _col(10) "`p'" as result _col(25) %6.2f `delta1_`j'_`p'g0m1' " (" %4.2f `delta1_`j'_`p'g0m1_se' ")" _col(42) %6.2f `delta2_`j'_`p'g0m1' " (" %4.2f `delta2_`j'_`p'g0m1_se' ")" + } + } + } + if "`group'" != "" { + di _col(10) as text "{hline 85}" + } + else { + di _col(10) as text "{hline 50}" + } + /* Affichage des estimations du trait latent du modĂšle 1 */ + + di + if "`group'" != "" { + di %~85s as text "Latent trait distribution" + di _col(10) "{hline 65}" + di _col(28) "Estimate" _col(46) "Standard error" _col(64) "P-value" + di _col(10) "{hline 65}" + } + else { + di %~70s as text "Latent trait distribution" + di _col(10) "{hline 50}" + di _col(28) as text "Estimate" _col(44) "Standard error" " + di _col(10) "{hline 50}" + } + di _col(10) as text "Variance Time 1" as result _col(28) %6.2f `=var_m1[1,1]' _col(44) %6.2f `=var_m1[2,1]' + di _col(10) as text "Variance Time 2" as result _col(28) %6.2f `=var_m1[1,2]' _col(44) %6.2f `=var_m1[2,2]' + di _col(10) as text "Covariance" as result _col(28) %6.2f `=covar_m1[1,1]' _col(44) %6.2f `=covar_m1[2,1]' + if "`group'" != "" { + di _col(10) as text "Group effect" as result _col(28) %6.2f `geffm1' _col(44) %6.2f `segeffm1' _col(64) %6.4f `gpm1p' + } + di _col(10) as text "Time effect" as result _col(28) "0 (constrained)" + if "`group'" != "" { + di _col(10) as text "TimexGroup inter" as result _col(28) "0 (constrained)" + } + if "`group'" != "" { + di _col(10) as text "{hline 65}" + } + else { + di _col(10) as text "{hline 50}" + } + di + if "`group'" != "" { + di _col(10) as text "Group effect estimated: mean of the latent trait of group 1 at time 1 freely estimated" + di _col(10) as text "No time effect: equality of means of the latent trait of group 0 across time" + di _col(10) as text "All item difficulties freely estimated across time" + } + else{ + di _col(10) as text "No time effect: equality of means of the latent trait across time" + di _col(10) as text "All item difficulties freely estimated across time" + } +} + //Affichage du modĂšle 2 +di +di as input "PROCESSING STEP 2" +di +if "`detail'" != "" { + /* Affichage des estimations des difficultĂ©s */ + di _col(5) as text "{ul:MODEL 2:} Overall longitudinal measurement invariance across time (no RS)" + di + if "`group'" != "" { + di %~105s as text "Item difficulties: estimates (s.e.)" + di _col(10) "{hline 85}" + di _col(38) "Time 1" _col(76) "Time 2" + di as text _col(26) abbrev("`gp'",15) "=0" _col(44) abbrev("`gp'",15) "=1" _col(64) abbrev("`gp'",15) "=0" _col(82) abbrev("`gp'",15) "=1" + di _col(10) "{hline 85}" + } + else { + di %~70s as text as text "Item difficulties: estimates (s.e.)" + di _col(10) "{hline 50}" + di _col(25) "Time 1" _col(42) "Time 2" + di _col(10) "{hline 50}" + } + + forvalues j=1/`nbitems' { + di as text _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + if "`group'" != "" { + di as text _col(10) "`p'" as result _col(25) %6.2f `delta1_`j'_`p'g0m2' " (" %4.2f `delta1_`j'_`p'g0m2_se' ")" _col(43) %6.2f `delta1_`j'_`p'g1m2' " (" %4.2f `delta1_`j'_`p'g1m2_se' ")" /// + _col(63) %6.2f `delta2_`j'_`p'g0m2' " (" %4.2f `delta2_`j'_`p'g0m2_se' ")" _col(81) %6.2f `delta2_`j'_`p'g1m2' " (" %4.2f `delta2_`j'_`p'g1m2_se' ")" + } + else { + di as text _col(10) "`p'" as result _col(25) %6.2f `delta1_`j'_`p'g0m2' " (" %4.2f `delta1_`j'_`p'g0m2_se' ")" _col(42) %6.2f `delta2_`j'_`p'g0m2' " (" %4.2f `delta2_`j'_`p'g0m2_se' ")" + } + } + } + if "`group'" != "" { + di as text _col(10) "{hline 85}" + } + else { + di as text _col(10) "{hline 50}" + } + /* Affichage des estimations du trait latent du modĂšle 2 */ + di + di %~85s as text "Latent trait distribution" + di _col(10) "{hline 65}" + di _col(28) as text "Estimate" _col(46) "Standard error" _col(64) "P-value" + di _col(10) "{hline 65}" + + if "`group'" == "" { + local fact_k = 2 + } + else { + local fact_k = 4 + } + + di _col(10) as text "Variance Time 1" as result _col(28) %6.2f `=mod2[1,`=`fact_k'*`nbmoda_sum'+1']' _col(44) %6.2f =mod2[2,`=`fact_k'*`nbmoda_sum'+1'] + di _col(10) as text "Variance Time 2" as result _col(28) %6.2f `=mod2[1,`=`fact_k'*`nbmoda_sum'+2']' _col(44) %6.2f `=mod2[2,`=`fact_k'*`nbmoda_sum'+2']' + di _col(10) as text "Covariance" as result _col(28) %6.2f `=mod2[1,`=`fact_k'*`nbmoda_sum'+3']' _col(44) %6.2f `=mod2[2,`=`fact_k'*`nbmoda_sum'+3']' + if "`group'" != "" { + di _col(10) as text "Group effect" as result _col(28) %6.2f `geffm2' _col(44) %6.2f `segeffm2' _col(64) %6.4f `gpm2p' + } + di _col(10) as text "Time effect" as result _col(28) %6.2f `teffm2' _col(44) %6.2f `seteffm2' _col(64) %6.4f `tm2p' + if "`group'" != "" { + di _col(10) as text "TimexGroup inter" as result _col(28) %6.2f `interm2' _col(44) %6.2f `seinterm2' _col(64) %6.4f `interm2p' + } + di as text _col(10) "{hline 65}" + di + if "`group'" != "" { + di _col(10) as text "Group effect estimated: mean of the latent trait of group 1 at time 1 freely estimated" + di _col(10) as text "Time effect estimated: mean of the latent trait of group 0 at time 2 freely estimated" + di _col(10) as text "Equality of all item difficulties across time" + } + else { + di _col(10) as text "Time effect estimated: mean of the latent trait at time 2 freely estimated" + di _col(10) as text "Equality of all item difficulties across time" + } + di +} + + ***************************************************** + * ModĂšle 1 vs ModĂšle 2 * + ***************************************************** +qui lrtest model2 model1 + +local rstestp=r(p) +local rstestchi=r(chi2) +local rstestdf=r(df) +if "`detail'" != "" { + + di as input "LIKELIHOOD-RATIO TEST + di + di %~60s "Model 1 vs Model 2" + di _col(10) "{hline 40}" + di _col(10) as text "Chi-square" _col(28) "DF" _col(40) "P-value" + di _col(10) as result %6.2f `rstestchi' _col(28) %2.0f `rstestdf' _col(40) %6.4f `rstestp' + di _col(10) as text "{hline 40}" + di +} +if `rstestp'<0.05{ + di as result "DIFFERENCE IN ITEM DIFFICULTIES ACROSS TIME LIKELY" +} +else{ + di as result "NO DIFFERENCE IN ITEM DIFFICULTIES ACROSS TIME DETECTED, NO RECALIBRATION DETECTED" +} + ********************************* + *************MODEL 3************* + ********************************* +// Etape itĂ©rative si lrtest significatif +local nb_step3=0 + +if `rstestp' < 0.05 { /* If pvalue(LRtest)<0.05 then step 3 */ + di + di as input "PROCESSING STEP 3" + di + + /*test RC pour chaque item*/ + local boucle = 1 + local stop = 0 + //matrix list dif_rc + while `boucle' <= `=`nbitp'-1' & `stop' == 0 { /*on s'arrĂȘte quand on a libĂ©rĂ© du RC sur (tous les items-1) ou lorsqu'il n'y a plus de tests significatifs*/ + local nb_step3 = `boucle' + local pajust=0.05/`=`nbitp'+1-`boucle'' // local pajust=0.05/`=`nbitems'+1-`boucle' + if "`group'" != "" { + local pajust2 = 0.05/`nbgrp' + } + /*rĂ©initialisation de la matrice de test*/ + matrix test_rc_`boucle'=J(`nbitems',9,.) + matrix test_rcCOMM_`boucle'=J(`nbitems',3,.) + matrix test_rcU_`boucle'=J(`nbitems',6,.) + matrix colnames test_rc_`boucle'= chi_RC df_RC pvalue_RC chi_RCg0 df_RCg0 pvalue_RCg0 chi_RCg1 df_RCg1 pvalue_RCg1 + matrix colnames test_rcCOMM_`boucle'= chi_RCCOMM df_RCCOMM pvalue_RCCOMM + matrix colnames test_rcU_`boucle'= chi_RCUg0 df_RCUg0 pvalue_RCUg0 chi_RCUg1 df_RCUg1 pvalue_RCUg1 + local nbsig=0 + local minpval=1 + local itemrc=0 + if "`detail'" != "" { + di as text "Loop `boucle'" + di _col(5) "Adjusted alpha : " %6.4f `pajust' + di + di as text _col(10) "{hline 65}" + di as text _col(10) "Freed item" _col(31) "Chi-Square" _col(48) "DF" _col(57) "P-Value" + di as text _col(10) "{hline 65}" + } + + + /*boucle de test*/ + forvalues j=1/`nbitems'{ + if `nbdif_`j'' >= 1 { + local model "" + local listconst "" + local listconst_g "" + if dif_rc[`j',3]==. { /*si pas de RC dĂ©jĂ  dĂ©tectĂ© sur l'item j -> test item j*/ + /*on libĂšre la RC de l'item j: pas de contraintes*/ + forvalues k=1/`nbitems'{ + if "`group'" == "" { + if `k'!=`j'{ + if dif_rc[`k',3]==. | dif_rc[`k',3]==0 {/*pas de RC sur item k: contraintes 401-600*/ + forvalues p=1/`nbdif_`k''{ + local listconst_g "`listconst_g' `=400+`maxdif'*(`k'-1)+`p'' " + qui constraint list `=400+`maxdif'*(`k'-1)+`p'' + } + } + else { + if dif_rc[`k',6]!=. & dif_rc[`k',6]!=0 { // RC commune unif. + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst_g "`listconst_g' `=1000+`maxdif'*(`k'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`k'-1)+`p'' + } + } + } + } + } + } + else { + /* Contraintes de DIF */ + if dif_rc[`k',1]==.|dif_rc[`k',1]==0 { // contraintes si pas de DIF (1-200) + forvalues p=1/`nbdif_`k''{ + local listconst "`listconst' `=0+`maxdif'*(`k'-1)+`p''" + qui constraint list `=0+`maxdif'*(`k'-1)+`p'' + } + } + else { // PrĂ©sence de DIF + if dif_rc[`k',2]!=. & dif_rc[`k',2]!=0 { // contraintes de DIF U (201-400) + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst "`listconst' `=200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + if `k'!=`j'{ /*contraintes pour les autres items */ + if dif_rc[`k',3]==. | dif_rc[`k',3]==0 {/*pas de RC sur item k: contraintes 401-600 601-800*/ + forvalues p=1/`nbdif_`k''{ + local listconst "`listconst' `=400+`maxdif'*(`k'-1)+`p'' `=600+`maxdif'*(`k'-1)+`p''" + qui constraint list `=400+`maxdif'*(`k'-1)+`p'' `=600+`maxdif'*(`k'-1)+`p'' + } + } + else { //RC dĂ©tectĂ©e sur l'item k + if dif_rc[`k',4]==0{ /*RC commune: contraintes 801-1000*/ + forvalues p=1/`nbdif_`k''{ /***************************** j=1 ou 2 ?****/ + local listconst "`listconst' `=800+`maxdif'*(`k'-1)+`p''" + qui constraint list `=800+`maxdif'*(`k'-1)+`p'' + } + if dif_rc[`k',6]!=. & dif_rc[`k',6]!=0 { // RC commune unif. + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst "`listconst' `=1000+`maxdif'*(`k'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`k'-1)+`p'' + } + } + } + } + else { // RC diff + if dif_rc[`k',5]==. | dif_rc[`k',5]==0 { // RC gp0 (400) + forvalues p=1/`nbdif_`k''{ + local listconst "`listconst' `=400+`maxdif'*(`k'-1)+`p''" + qui constraint list `=400+`maxdif'*(`k'-1)+`p'' + } + } + if dif_rc[`k',6]!=. & dif_rc[`k',6]!=0 { // RCU gp0 (1001-1200) + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst "`listconst' `=1000+`maxdif'*(`k'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`k'-1)+`p'' + } + } + } + if dif_rc[`k',7]==. | dif_rc[`k',7]==0 { // RC gp1 (600) + forvalues p=1/`nbdif_`k''{ + local listconst "`listconst' `=600+`maxdif'*(`k'-1)+`p''" + qui constraint list `=600+`maxdif'*(`k'-1)+`p'' + } + } + if dif_rc[`k',8]!=. & dif_rc[`k',8]!=0 { // RCU gp1 (1201-1400) + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst "`listconst' `=1200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=1200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + } + } + } + } + + local model "" + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA1@`p')(`p'.``=`jj'+`nbitems'''<-THETA2@`p')" + } + } + if "`group'" == "" { // Sans l'option group + qui gsem `model', mlogit tol(0.01) iterate(100) means(THETA1@0 THETA2@m20) var(THETA1@v1 THETA2@v2) cov(THETA1*THETA2@cov12) constraint(`listconst_g') from(esti_2, skip) latent(THETA1 THETA2) nocapslatent + + /*****************/ + /*tests RC item j*/ + /*****************/ + + /* RC ? */ + qui test [1.``j'']_cons =[1.``=`j'+`nbitems''']_cons + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']_cons =[`p'.``=`j'+`nbitems''']_cons, acc + } + } + matrix test_rc_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + + + /* RCU ? */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``=`j'+`nbitems''']_cons -[1.``j'']_cons)=[2.``=`j'+`nbitems''']_cons -[2.``j'']_cons + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``=`j'+`nbitems''']_cons -[1.``j'']_cons)=[`p'.``=`j'+`nbitems''']_cons -[`p'.``j'']_cons , acc + } + matrix test_rcU_`boucle'[`j',1]=(r(chi2), r(df),r(p)) + } + } + else { // Avec l'option group + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) latent(THETA1 THETA2) nocapslatent + + /*****************/ + /*tests RC item i*/ + /*****************/ + + /* RC ? */ + qui test [1.``j'']0bn.`gp'=[1.``=`j'+`nbitems''']0bn.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp', acc + } + } + qui test [1.``j'']1.`gp'=[1.``=`j'+`nbitems''']1.`gp', acc + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp', acc + } + } + matrix test_rc_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + /* RC COMMUNE ? */ + qui test [1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp'=[1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp', acc + } + } + matrix test_rcCOMM_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + /* RC groupe 0 ? */ + qui test [1.``j'']0bn.`gp'=[1.``=`j'+`nbitems''']0bn.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp', acc + } + } + matrix test_rc_`boucle'[`j',4]=(r(chi2),r(df),r(p)) + + /* RCU grp 0 ? */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[2.``=`j'+`nbitems''']0bn.`gp'-[2.``j'']0bn.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp', acc + } + matrix test_rcU_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + } + + /* RC groupe 1 ? */ + qui test [1.``j'']1.`gp'=[1.``=`j'+`nbitems''']1.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp', acc + } + } + matrix test_rc_`boucle'[`j',7]=(r(chi2),r(df),r(p)) + + /* RCU grp 1 ? */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[2.``=`j'+`nbitems''']1.`gp'-[2.``j'']1.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp', acc + } + matrix test_rcU_`boucle'[`j',4]=(r(chi2),r(df),r(p)) + } + } + /******* Matrice test complĂšte *********/ + if "`detail'" != "" { + di as text _col(10) abbrev("``j''",22) as result _col(31) %6.3f test_rc_`boucle'[`j',1] _col(48) test_rc_`boucle'[`j',2] _col(57) %6.4f test_rc_`boucle'[`j',3] + } + } + } + } + //matrix list test_rc_`boucle' + forvalues j=1/`nbitems'{ + if test_rc_`boucle'[`j',3]<`pajust'{/*si RC sur item i*/ + if test_rc_`boucle'[`j',3]<`minpval'{ + local minpval=test_rc_`boucle'[`j',3] + local itemrc=`j' + } + } + } + if `itemrc' != 0 { // itemrc = numĂ©ro de l'item avec le test le + sig. + if "`group'" == "" { // Recalibration si pas d'option groupe + local ++nbsig + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',5]=`boucle' + if `nbmoda_`itemrc'' > 2 { + if "`detail'" != "" { + di as text _col(10) "{hline 65}" + di + di as result "Recalibration on ``itemrc''" + di + di as text _col(10) "{hline 65}" + di as text _col(10) "Test" _col(31) "Chi-Square" _col(48) "DF" _col(57) "P-Value" + di as text _col(10) "{hline 65}" + di as text _col(10) "Uniform RC? " as result _col(31) %4.2f `=test_rcU_`boucle'[`itemrc',1]' _col(48) `=test_rcU_`boucle'[`itemrc',2]' _col(57) %6.4f `=test_rcU_`boucle'[`itemrc',3]' + di as text _col(10) "{hline 65}" + } + if test_rcU_`boucle'[`itemrc',3] >= 0.05 { //RC Uniforme sur itemRC + matrix dif_rc[`itemrc',6]=`boucle' + di + di as result "``itemrc'' : Uniform RC" + di + } + else { + matrix dif_rc[`itemrc',6]=0 + di + di as result "``itemrc'' : Non-uniform RC" + di + } + } + else { + di + di as result "``itemrc'' : Recalibration " + di + } + } + else { // Option groupe + if "`detail'" != "" { + di as text _col(10) "{hline 65}" + di + di as result "Recalibration on ``itemrc''" + di + di as text _col(10) "{hline 65}" + di as text _col(10) "Test" _col(31) "Chi-Square" _col(48) "DF" _col(57) "P-Value" + di as text _col(10) "{hline 65}" + di _col(10) as text "Common RC? " as result _col(31) %4.2f `=test_rcCOMM_`boucle'[`itemrc',1]' _col(48) `=test_rcCOMM_`boucle'[`itemrc',2]' _col(57) %6.4f `=test_rcCOMM_`boucle'[`itemrc',3]' + } + if test_rcCOMM_`boucle'[`itemrc',3] < 0.05 { //RC diffĂ©rentielle + if "`detail'" != "" { + di _col(10) as text "RC group 0? " as result _col(31) %4.2f `=test_rc_`boucle'[`itemrc',4]' _col(48) `=test_rc_`boucle'[`itemrc',5]' _col(57) %6.4f `=test_rc_`boucle'[`itemrc',6]' "{it: - with adjusted alpha = `pajust2' }" + } + if test_rc_`boucle'[`itemrc',6] < `pajust2' { //RC gp 0 + local ++nbsig + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',4]=`boucle' + matrix dif_rc[`itemrc',5]=`boucle' + if `nbmoda_`itemrc'' > 2 { + di _col(10) as text "Uniform RC group 0? " as result _col(31) %4.2f `=test_rcU_`boucle'[`itemrc',1]' _col(48) `=test_rcU_`boucle'[`itemrc',2]' _col(57) %6.4f `=test_rcU_`boucle'[`itemrc',3]' + if test_rcU_`boucle'[`itemrc',3] >= 0.05 { // RCU gp 0 + matrix dif_rc[`itemrc',6]=`boucle' + local phrase_diff = "``itemrc'' : Uniform differential RC in group 0." + } + else { + matrix dif_rc[`itemrc',6]=0 + local phrase_diff = "``itemrc'' : Non-uniform differential RC in group 0." + } + } + else { + local phrase_diff = "``itemrc'' : Differential RC in group 0." + } + } + if "`detail'" != "" { + di _col(10) as text "RC group 1?" as result _col(31) %4.2f `=test_rc_`boucle'[`itemrc',7]' _col(48) `=test_rc_`boucle'[`itemrc',8]' _col(57) %6.4f `=test_rc_`boucle'[`itemrc',9]' "{it: - with adjusted alpha = `pajust2' }" + } + if test_rc_`boucle'[`itemrc',9] < `pajust2' { //RC gp 1 + local ++nbsig + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',4]=`boucle' + matrix dif_rc[`itemrc',7]=`boucle' + if `nbmoda_`itemrc'' > 2 { + if "`detail'" != "" { + di _col(10) as text "Uniform RC group 1? " as result _col(31) %4.2f `=test_rcU_`boucle'[`itemrc',4]' _col(48) `=test_rcU_`boucle'[`itemrc',5]' _col(57) %6.4f `=test_rcU_`boucle'[`itemrc',6]' + } + if test_rcU_`boucle'[`itemrc',6] >= 0.05 { // RCU gp 1 + matrix dif_rc[`itemrc',8]=`boucle' + if dif_rc[`itemrc',5] != `boucle' { //RC slmt sur g1 + local phrase_diff = "``itemrc'' : Differential RC, uniform RC in group 1." + } + else { + if dif_rc[`itemrc',6] == 0 { // + RCNU g0 + local phrase_diff = "``itemrc'' : Differential RC, non-uniform RC in group 0 and uniform RC in group 1." + } + else { // + RCU G0 + local phrase_diff = "``itemrc'' : Differential RC, uniform RC in group 0 and uniform RC in group 1." + } + } + } + else { //RCNU gp 1 + matrix dif_rc[`itemrc',8]=0 + if "`detail'" != "" { + di + } + if dif_rc[`itemrc',5] != `boucle' { + local phrase_diff = "``itemrc'' : Differential RC, non-uniform RC in group 1." + } + else { + if dif_rc[`itemrc',6] == 0 { // + RCNU g0 + local phrase_diff = "``itemrc'' : Differential RC, non-uniform RC in group 0 and non-uniform RC in group 1." + } + else { // + RCU G0 + local phrase_diff = "``itemrc'' : Differential RC, uniform RC in group 0 and non-uniform RC in group 1." + } + } + } + } + else { + if dif_rc[`itemrc',5] != `boucle' { + local phrase_diff = "``itemrc'' : Differential RC in group 1." + } + else { + local phrase_diff = "``itemrc'' : Differential RC in group 0 and differential RC in group 1." + } + } + } + if "`detail'" != "" { + di as text _col(10) "{hline 65}" + } + di + di as result "`phrase_diff'" + di + } + else { // RC commune -> MAJ modĂšle 3 + /*******************************************************************************************************************/ + if `nbmoda_`itemrc'' == 2 { + if "`detail'" != "" { + di + di as result "{ul:``itemrc''}: recalibration" + di _col(20) in ye "Common " in gr "{it:(Chi-s: " %4.2f `=test_rcCOMM_`boucle'[`itemrc',1]' ", DF: `=test_rcCOMM_`boucle'[`itemrc',2]' p-val. : " %4.2f `=test_rcCOMM_`boucle'[`itemrc',3]' ")}" + } + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',4]=0 + matrix dif_rc[`itemrc',5]=`boucle' + matrix dif_rc[`itemrc',7]=`boucle' + local ++nbsig + } + else { + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',4]=0 + matrix dif_rc[`itemrc',5]=`boucle' + matrix dif_rc[`itemrc',7]=`boucle' + //matrix list dif_rc + local model "" + local listconst "" + forvalues j=1/`nbitems'{ + /* Contraintes de DIF */ + if dif_rc[`j',1]==.|dif_rc[`j',1]==0 { // contraintes si pas de DIF (1-200) + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { // PrĂ©sence de DIF + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { // contraintes de DIF U (201-400) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + if `j' != `itemrc'{ /*contraintes pour les autres items */ + if dif_rc[`j',3]==. | dif_rc[`j',3]==0 {/*pas de RC sur item p: contraintes 401-600 601-800*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p'' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' `=600+`maxdif'*(`j'-1)+`p'' + } + } + else { //RC dĂ©tectĂ©e sur l'item p + if dif_rc[`j',4]==0{ /*RC commune: contraintes 801-1000*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=800+`maxdif'*(`j'-1)+`p''" + qui constraint list `=800+`maxdif'*(`j'-1)+`p'' + } + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RC commune unif. + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + } + else if dif_rc[`j',4] != 0 & dif_rc[`j',4]!=0. { // RC diff + if dif_rc[`j',5]==. | dif_rc[`j',5]==0 { // RC gp0 (400) + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + } + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RCU gp0 (1001-1200) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + if dif_rc[`j',7]==. | dif_rc[`j',7]==0 { // RC gp1 (600) + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=600+`maxdif'*(`j'-1)+`p'' + } + } + if dif_rc[`j',8]!=. & dif_rc[`j',8]!=0 { // RCU gp1 (1201-1400) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=1200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + } + } + else { // Contrainte de RC commune pour l'itemrc + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=800+`maxdif'*(`itemrc'-1)+`p''" + qui constraint list `=800+`maxdif'*(`itemrc'-1)+`p'' + } + } + } + qui di "`listconst'" + local model "" + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA1@`p')(`p'.``=`jj'+`nbitems'''<-THETA2@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) latent(THETA1 THETA2) nocapslatent + + /************************/ + /*tests RC item `itemrc'*/ + /************************/ + matrix commU_`boucle'=J(`nbitems',3,.) //Matrice des tests de RCU slmt si RC commune + matrix colnames commU_`boucle'= chi_RCU df_RCU p_RCU + + /* RCU grp 0 ? */ + if `nbmoda_`itemrc'' > 2 { + qui test 2*([1.``=`itemrc'+`nbitems''']0bn.`gp'-[1.``itemrc'']0bn.`gp')=[2.``=`itemrc'+`nbitems''']0bn.`gp'-[2.``itemrc'']0bn.`gp' + forvalues j=3/`nbdif_`itemrc''{ + qui test `j'*([1.``=`itemrc'+`nbitems''']0bn.`gp'-[1.``itemrc'']0bn.`gp')=[`j'.``=`itemrc'+`nbitems''']0bn.`gp'-[`j'.``itemrc'']0bn.`gp', acc + } + matrix commU_`boucle'[`itemrc',1]=(r(chi2),r(df),r(p)) + if "`detail'" != "" { + di _col(10) as text "Uniform RC?" as result _col(31) %4.2f `=commU_`boucle'[`itemrc',1]' _col(48) `=commU_`boucle'[`itemrc',2]' _col(57) %6.4f `=commU_`boucle'[`itemrc',3]' + di as text _col(10) "{hline 65}" + } + if commU_`boucle'[`itemrc',3] >= 0.05 { // RCU + local ++nbsig + matrix dif_rc[`itemrc',6]=`boucle' + matrix dif_rc[`itemrc',8]=`boucle' + di + //di as result "{ul:``itemrc''}: recalibration" + //di _col(20) "Common " in gr "{it:(Chi-s: " %4.2f `=test_rcCOMM_`boucle'[`itemrc',1]' ", DF: `=test_rcCOMM_`boucle'[`itemrc',2]' p-val. : " %4.2f `=test_rcCOMM_`boucle'[`itemrc',3]' ")}" + di as result "``itemrc'' : Uniform common RC" + di + } + else { + local ++nbsig + matrix dif_rc[`itemrc',6]=0 + matrix dif_rc[`itemrc',8]=0 + di + di as result "``itemrc'' : Non-uniform common RC" + di + } + } + } + } // fin de RC commune + } + } + else { + local stop = 1 + } + /*******************************************************************************************************************/ + // Fin de RC sur item i + if `nbsig'==0{ + local stop=1 + if `boucle' == 1 { + di as text _col(10) "{hline 65}" + di + di as result "No significant tests, no recalibration detected" + di + } + else { + if "`detail'" != "" { + di as text _col(10) "{hline 65}" + di + di as result "No other significant tests" + di + } + } + } + local ++boucle + } +} + + + + ********************************* + *** BILAN *** + ********************************* + + if "`group'" != "" & "`nodif'" == "" { + di + di %~84s as result "SUMMARY" + di as result _col(2) "{hline 80}" + di as result _col(18) "Difference in" + di as result _col(2) "Item" _col(18) "groups at T1" _col(36) "Recalibration" _col(54) "RC " abbrev("`gp'",10) " 0" _col(72) "RC " abbrev("`gp'",10) " 1" + di as result _col(2) "{hline 80}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + local difft1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + if (dif_rc[`j',1] != . ) { + if (dif_rc[`j',2]!=0) { + local difft1 "Uniform" + } + else { + local difft1 "Non-uniform" + } + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + if dif_rc[`j',1] != . { + local difft1 " X " + } + } + di as result _col(2) abbrev("``j''",15) as text _col(18) "`difft1'" _col(36) "`RC'" _col(54) "`RCg0'" _col(72) "`RCg1'" + } + di as result _col(2) "{hline 80}" + di +} +else if "`group'" != "" & "`nodif'" != "" { + di + di %~90s as result "SUMMARY" + di as result _col(10) "{hline 70}" + di as result _col(10) "Item" _col(26) "Recalibration" _col(46) "RC `gp' 0" _col(62) "RC `gp' 1" + di _col(10) "{hline 70}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + } + di as result _col(10) "``j''" as text _col(26) "`RC'" _col(44) "`RCg0'" _col(62) "`RCg1'" + } + di as result _col(10) "{hline 70}" +} +else if "`group'" == "" { + di + di %~60s as result "SUMMARY" + di as result _col(10) "{hline 40}" + di _col(10) "Item" _col(36) "Recalibration" + di _col(10) "{hline 40}" + forvalues j=1/`nbitems' { + local RC + if dif_rc[`j',3] != . { + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RC "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RC "Non-uniform" + } + } + else { + local RC " X " + } + } + di as result _col(10) "``j''" as text _col(38) "`RC'" + } + di as result _col(10) "{hline 40}" + di +} + + + ********************************* + ** MODEL 4 ** + ********************************* +if "`detail'" != "" { + di + di as input "PROCESSING STEP 4" + di +} + //matrix list dif_rc, title ("Constraints") + +local model "" +local listconst "" +local listconst_g "" +forvalues j=1/`nbitems'{ + if "`group'" != "" { + if dif_rc[`j',1]==.|dif_rc[`j',1]==0 { /*si pas de DIF: contraintes 1-200 */ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { // PrĂ©sence de DIF + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { // contraintes de DIF U (201-400) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + } + if dif_rc[`j',3]==. | dif_rc[`j',3]==0 { /*pas de RC : contraintes 401-600 601-800*/ + forvalues p=1/`nbdif_`j''{ + if "`group'" == "" { + local listconst_g "`listconst_g' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + else { + local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p'' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' `=600+`maxdif'*(`j'-1)+`p'' + } + } + } + else { //RC dĂ©tectĂ©e sur l'item j + if "`group'" == "" { + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RC unif. + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst_g "`listconst_g' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + } + else { + if dif_rc[`j',4]==0{ /*RC commune: contraintes 801-1000*/ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=800+`maxdif'*(`j'-1)+`p''" + qui constraint list `=800+`maxdif'*(`j'-1)+`p'' + } + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RC commune unif. + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + } + else { // RC diff + if dif_rc[`j',5]==. | dif_rc[`j',5]==0 { // RC gp0 (400) + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + } + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RCU gp0 (1001-1200) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + if dif_rc[`j',7]==. | dif_rc[`j',7]==0 { // RC gp1 (600) + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=600+`maxdif'*(`j'-1)+`p'' + } + } + if dif_rc[`j',8]!=. & dif_rc[`j',8]!=0 { // RCU gp1 (1201-1400) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=1200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + } + } +} + +local model "" + +forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA1@`p')(`p'.``=`jj'+`nbitems'''<-THETA2@`p')" + } +} + +if "`group'" != "" { + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) latent(THETA1 THETA2) nocapslatent +} +else { + qui gsem `model', mlogit tol(0.01) iterate(100) means( THETA1@0 THETA2@m2) var(THETA1@v1 THETA2@v2) cov(THETA1*THETA2@cov12) constraint(`listconst_g') from(esti_2, skip) latent(THETA1 THETA2) nocapslatent +} + /* Stockage des estimations du modĂšle */ +matrix val_m4 = r(table) +matrix esti_4 = e(b) + +if "`group'" != "" { + matrix var_m4 = (val_m4[1,"/var(THETA1)#0bn.`gp'"],val_m4[1,"/var(THETA2)#0bn.`gp'"]\val_m4[2,"/var(THETA1)#0bn.`gp'"],val_m4[2,"/var(THETA2)#0bn.`gp'"]) + matrix covar_m4 = (val_m4[1,"/cov(THETA1,THETA2)#0.`gp'"],val_m4[1,"/cov(THETA1,THETA2)#1.`gp'"]\val_m4[2,"/cov(THETA1,THETA2)#0.`gp'"],val_m4[2,"/cov(THETA1,THETA2)#1.`gp'"]\val_m4[4,"/cov(THETA1,THETA2)#0.`gp'"],val_m4[4,"/cov(THETA1,THETA2)#1.`gp'"]) +} +else { + matrix var_m4 = (val_m4[1,"/var(THETA1)"],val_m4[1,"/var(THETA2)"]\val_m4[2,"/var(THETA1)"],val_m4[2,"/var(THETA2)"]) + matrix covar_m4 = (val_m4[1,"/cov(THETA1,THETA2)"]\val_m4[2,"/cov(THETA1,THETA2)"]\val_m4[4,"/cov(THETA1,THETA2)"]) +} + +/* Matrice des tests effet grp, tps et inter */ +matrix effet = J(5,3,.) +matrix colnames effet= Groupe Temps Interaction +matrix rownames effet = Esti Std_Err Pvalue Chi DF + +/*group effect*/ +if "`group'" != "" { + qui lincom [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' + matrix effet[1,1] =r(estimate) + matrix effet[2,1]=r(se) + qui test [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' = 0 + matrix effet[3,1]=r(p) + matrix effet[4,1]=r(chi2) + matrix effet[5,1]=r(df) +} + +/*time effect*/ +if "`group'" != "" { + qui lincom [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp' + matrix effet[1,2]=r(estimate) + matrix effet[2,2]=r(se) + qui test [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp' = 0 + matrix effet[3,2]=r(p) + matrix effet[4,2]=r(chi2) + matrix effet[5,2]=r(df) +} +else { + qui lincom [/]:mean(THETA2) /* -[/]:mean(THETA1)*/ + local teffm4=r(estimate) + local seteffm4=r(se) + local ubteffm4 = r(ub) + local lbteffm4 = r(lb) + qui test [/]:mean(THETA2) /* -[/]:mean(THETA1) */ = 0 + local tm4p=r(p) + local tm4chi=r(chi2) + local tm4df=r(df) +} + +*INTERACTION +if "`group'" != "" { + qui lincom [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#1.`gp'+[/]:mean(THETA1)#0bn.`gp' + matrix effet[1,3]=r(estimate) + matrix effet[2,3]=r(se) + local ubinterm4=r(ub) + local lbinterm4=r(lb) + qui test [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#1.`gp'+[/]:mean(THETA1)#0bn.`gp' = 0 + matrix effet[3,3]=r(p) + matrix effet[4,3]=r(chi2) + matrix effet[5,3]=r(df) +} + +if "`group'" != "" { + local effet_tps = 0 + local effet_grp = 0 + + if effet[3,3] >= 0.05 { // Si option group, on s'interesse Ă  l'interaction temps x group, et MAJ modĂšle >>> modĂšle final = modĂšle 4 + contrainte 1999 (Interaction = 0) + /* Affichage des estimations sur le trait latent du modĂšle 4 */ + if "`detail'" != "" { + di + di %~85s as text "Latent trait distribution" + di _col(10) "{hline 65}" + di _col(28) as text "Estimate" _col(46) "Standard error" _col(62) "P-value" + di _col(10) "{hline 65}" + di _col(10) as text "Variance Time 1" as result _col(28) %6.2f `=var_m4[1,1]' _col(44) %6.2f `=var_m4[2,1]' + di _col(10) as text "Variance Time 2" as result _col(28) %6.2f `=var_m4[1,2]' _col(44) %6.2f `=var_m4[2,2]' + di _col(10) as text "Covariance" as result _col(28) %6.2f `=covar_m4[1,1]' _col(44) %6.2f `=covar_m4[2,1]' + if "`group'" != "" { + di _col(10) as text "Group effect" as result _col(28) %6.2f effet[1,1] _col(44) %6.2f effet[2,1] _col(62) %6.4f effet[3,1] + } + di _col(10) as text "Time effect" as result _col(28) %6.2f effet[1,2] _col(44) %6.2f effet[2,2] _col(62) %6.4f effet[3,2] + + if "`group'" != "" { + di _col(10) as text "TimexGroup inter" as result _col(28) %6.2f effet[1,3] _col(44) %6.2f effet[2,3] _col(62) %6.4f effet[3,3] + } + di as text _col(10) "{hline 65}" + di + di as result "Time x group interaction : test not significant + di "Reestimation of model 4 with time x group interaction constrained at 0 " + di + } + local yn_inter = 0 + local listconst "`listconst' 1999" + qui di "`listconst'" + local model "" + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA1@`p')(`p'.``=`jj'+`nbitems'''<-THETA2@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_4, skip) latent(THETA1 THETA2) nocapslatent + + matrix val_m4 = r(table) + } + else { + local yn_inter = 1 + } + + /*group effect*/ + qui lincom [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' + local geffm4=r(estimate) + local segeffm4=r(se) + local ubgeffm4=r(ub) + local lbgeffm4=r(lb) + qui test [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp'=0 + local gpm4p=r(p) + local gpm4chi=r(chi2) + local gpm4df=r(df) + + /*time effect*/ + qui lincom [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp' + local teffm4=r(estimate) + local seteffm4=r(se) + local lbteffm4=r(lb) + local ubteffm4=r(ub) + qui test [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp'=0 + local tm4p=r(p) + local tm4chi=r(chi2) + local tm4df=r(df) +} + + /* Calcul des difficultĂ©s (delta_j) */ +if "`group'" != "" { + matrix mod4 = J(7,`=`nbmoda_sum'*4+6',.) + local name_partTwoC "" + forvalues j = 1/`nbitems' { + forvalues p=1/`nbdif_`j'' { + forvalues t=1/2 { + forvalues g = 0/1 { + local name_partTwoC "`name_partTwoC' d_j`j'_p`p'_gp`g'_t`t'" + } + } + } + } + local name_partTwoC "`name_partTwoC' VAR(THETA1) VAR(THETA2) COV(TH1,TH2) GROUP_Effect TIME_Effect INTER_TxG " + matrix colnames mod4 = `name_partTwoC' + matrix rownames mod4 = Estimate se Upper_b Lower_b Chi_square DF pvalue +} +else { + matrix mod4 = J(7,`=`nbmoda_sum'*2+4',.) + local name_partTwoC "" + forvalues j = 1/`nbitems' { + forvalues p=1/`nbdif_`j'' { + forvalues t=1/2 { + local name_partTwoC "`name_partTwoC' d_j`j'_p`p'_t`t'" + } + } + } + local name_partTwoC "`name_partTwoC' VAR(THETA1) VAR(THETA2) COV(TH1,TH2) TIME_Effect " + matrix colnames mod4 = `name_partTwoC' + matrix rownames mod4 = Estimate se Upper_b Lower_b Chi_square DF pvalue +} + +*DifficultĂ©s +forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues t=1/2{ + if "`group'" != "" { // groupe binaire + forvalues g=0/1 { + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm4= r(estimate) + local delta`t'_`j'_`p'g`g'm4_se= r(se) + local delta`t'_`j'_`p'g`g'm4_ub=r(ub) + local delta`t'_`j'_`p'g`g'm4_lb=r(lb) + local delta`t'_`j'_`p'g`g'm4_p=r(p) + if `p'>1 { + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' - [`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm4=r(estimate) + local delta`t'_`j'_`p'g`g'm4_se=r(se) + local delta`t'_`j'_`p'g`g'm4_ub=r(ub) + local delta`t'_`j'_`p'g`g'm4_lb=r(lb) + local delta`t'_`j'_`p'g`g'm4_p=r(p) + } + local place = 0 + local compt = 1 + while `compt' < `j' { + local place = `place' + `nbdif_`compt'' + local ++compt + } + if `t' == 1 { + matrix mod4[1,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4' + matrix mod4[2,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4_se' + matrix mod4[3,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4_ub' + matrix mod4[4,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4_lb' + matrix mod4[7,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4_p' + } + if `t' == 2 { + matrix mod4[1,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4' + matrix mod4[2,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4_se' + matrix mod4[3,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4_ub' + matrix mod4[4,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4_lb' + matrix mod4[7,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4_p' + } + } + } + else { // groupe unique (=gp0) + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']_cons + local delta`t'_`j'_`p'g0m4= r(estimate) + local delta`t'_`j'_`p'g0m4_se= r(se) + local delta`t'_`j'_`p'g0m4_ub=r(ub) + local delta`t'_`j'_`p'g0m4_lb=r(lb) + local delta`t'_`j'_`p'g0m4_p=r(p) + if `p'>1{ + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']_cons - [`p'.``=(`t'-1)*`nbitems'+`j''']_cons + local delta`t'_`j'_`p'g0m4=r(estimate) + local delta`t'_`j'_`p'g0m4_se=r(se) + local delta`t'_`j'_`p'g0m4_ub=r(ub) + local delta`t'_`j'_`p'g0m4_lb=r(lb) + local delta`t'_`j'_`p'g0m4_p=r(p) + } + local place = 0 + local compt = 1 + while `compt' < `j' { + local place = `place' + `nbdif_`compt'' + local ++compt + } + if `t' == 1 { + matrix mod4[1,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4' + matrix mod4[2,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_se' + matrix mod4[3,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_ub' + matrix mod4[4,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_lb' + matrix mod4[7,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_p' + } + if `t' == 2 { + matrix mod4[1,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4' + matrix mod4[2,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_se' + matrix mod4[3,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_ub' + matrix mod4[4,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_lb' + matrix mod4[7,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_p' + } + } + } + } +} + +if "`group'" != "" { + matrix mod4[1,`=4*`nbmoda_sum'+1'] = (val_m4[1,"/var(THETA1)#0bn.`gp'"], val_m4[1,"/var(THETA2)#0bn.`gp'"]) + matrix mod4[2,`=4*`nbmoda_sum'+1'] = (val_m4[2,"/var(THETA1)#0bn.`gp'"],val_m4[2,"/var(THETA2)#0bn.`gp'"]) + matrix mod4[3,`=4*`nbmoda_sum'+1'] = (val_m4[6,"/var(THETA1)#0bn.`gp'"],val_m4[6,"/var(THETA2)#0bn.`gp'"]) + matrix mod4[4,`=4*`nbmoda_sum'+1'] = (val_m4[5,"/var(THETA1)#0bn.`gp'"],val_m4[5,"/var(THETA2)#0bn.`gp'"]) + + matrix mod4[1,`=4*`nbmoda_sum'+2+1'] = (val_m4[1,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod4[2,`=4*`nbmoda_sum'+2+1'] = (val_m4[2,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod4[3,`=4*`nbmoda_sum'+2+1'] = (val_m4[6,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod4[4,`=4*`nbmoda_sum'+2+1'] = (val_m4[5,"/cov(THETA1,THETA2)#0.`gp'"]) + + matrix mod4[1,`=4*`nbmoda_sum'+2+1+1'] = `geffm4' + matrix mod4[2,`=4*`nbmoda_sum'+2+1+1'] = `segeffm4' + matrix mod4[3,`=4*`nbmoda_sum'+2+1+1'] = `ubgeffm4' + matrix mod4[4,`=4*`nbmoda_sum'+2+1+1'] = `lbgeffm4' + matrix mod4[5,`=4*`nbmoda_sum'+2+1+1'] = `gpm4chi' + matrix mod4[6,`=4*`nbmoda_sum'+2+1+1'] = `gpm4df' + matrix mod4[7,`=4*`nbmoda_sum'+2+1+1'] = `gpm4p' + + + matrix mod4[1,`=4*`nbmoda_sum'+2+1+1+1'] = `teffm4' + matrix mod4[2,`=4*`nbmoda_sum'+2+1+1+1'] = `seteffm4' + matrix mod4[3,`=4*`nbmoda_sum'+2+1+1+1'] = `ubteffm4' + matrix mod4[4,`=4*`nbmoda_sum'+2+1+1+1'] = `lbteffm4' + matrix mod4[5,`=4*`nbmoda_sum'+2+1+1+1'] = `tm4chi' + matrix mod4[6,`=4*`nbmoda_sum'+2+1+1+1'] = `tm4df' + matrix mod4[7,`=4*`nbmoda_sum'+2+1+1+1'] = `tm4p' + + if `yn_inter' == 1 { //Slmt si model avec interaction + matrix mod4[1,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[1,3] + matrix mod4[2,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[2,3] + matrix mod4[3,`=4*`nbmoda_sum'+2+1+1+1+1'] = `ubinterm4' + matrix mod4[4,`=4*`nbmoda_sum'+2+1+1+1+1'] = `lbinterm4' + matrix mod4[5,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[4,3] + matrix mod4[6,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[5,3] + matrix mod4[7,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[3,3] + } + +} +else { + matrix mod4[1,`=2*`nbmoda_sum'+1'] = (val_m4[1,"/var(THETA1)"],val_m4[1,"/var(THETA2)"]) + matrix mod4[2,`=2*`nbmoda_sum'+1'] = (val_m4[2,"/var(THETA1)"],val_m4[2,"/var(THETA2)"]) + matrix mod4[3,`=2*`nbmoda_sum'+1'] = (val_m4[6,"/var(THETA1)"],val_m4[6,"/var(THETA2)"]) + matrix mod4[4,`=2*`nbmoda_sum'+1'] = (val_m4[5,"/var(THETA1)"],val_m4[5,"/var(THETA2)"]) + + matrix mod4[1,`=2*`nbmoda_sum'+2+1'] = (val_m4[1,"/cov(THETA1,THETA2)"]) + matrix mod4[2,`=2*`nbmoda_sum'+2+1'] = (val_m4[2,"/cov(THETA1,THETA2)"]) + matrix mod4[3,`=2*`nbmoda_sum'+2+1'] = (val_m4[6,"/cov(THETA1,THETA2)"]) + matrix mod4[4,`=2*`nbmoda_sum'+2+1'] = (val_m4[5,"/cov(THETA1,THETA2)"]) + + matrix mod4[1,`=2*`nbmoda_sum'+2+1+1'] = `teffm4' + matrix mod4[2,`=2*`nbmoda_sum'+2+1+1'] = `seteffm4' + matrix mod4[3,`=2*`nbmoda_sum'+2+1+1'] = `ubteffm4' + matrix mod4[4,`=2*`nbmoda_sum'+2+1+1'] = `lbteffm4' + matrix mod4[5,`=2*`nbmoda_sum'+2+1+1'] = `tm4chi' + matrix mod4[6,`=2*`nbmoda_sum'+2+1+1'] = `tm4df' + matrix mod4[7,`=2*`nbmoda_sum'+2+1+1'] = `tm4p' +} + + + /* Affichage des estimations des difficultĂ©s */ +di _col(5) as text "{ul:MODEL 4} = Final model" +di +if "`group'" != "" { + di %~105s as text "Item difficulties: estimates (s.e.)" + di _col(10) "{hline 85}" + di _col(38) "Time 1" _col(76) "Time 2" + di as text _col(25) abbrev("`gp'",15) "=0" _col(43) abbrev("`gp'",15) "=1" _col(64) abbrev("`gp'",15) "=0" _col(82) abbrev("`gp'",15) "=1" + di _col(10) "{hline 85}" +} +else { + di %~70s as text as text "Item difficulties: estimates (s.e.)" + di _col(10) "{hline 50}" + di _col(25) "Time 1" _col(43) "Time 2" + di _col(10) "{hline 50}" +} + +forvalues j=1/`nbitems' { + di as text _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + if "`group'" != "" { + di as text _col(10) "`p'" as result _col(25) %6.2f `delta1_`j'_`p'g0m4' " (" %4.2f `delta1_`j'_`p'g0m4_se' ")" _col(43) %6.2f `delta1_`j'_`p'g1m4' " (" %4.2f `delta1_`j'_`p'g1m4_se' ")" /// + _col(63) %6.2f `delta2_`j'_`p'g0m4' " (" %4.2f `delta2_`j'_`p'g0m4_se' ")" _col(81) %6.2f `delta2_`j'_`p'g1m4' " (" %4.2f `delta2_`j'_`p'g1m4_se' ")" + } + else { + di as text _col(10) "`p'" as result _col(25) %6.2f `delta1_`j'_`p'g0m4' " (" %4.2f `delta1_`j'_`p'g0m4_se' ")" _col(43) %6.2f `delta2_`j'_`p'g0m4' " (" %4.2f `delta2_`j'_`p'g0m4_se' ")" + } + } +} + +if "`group'" != "" { + di as text _col(10) "{hline 85}" +} +else { + di as text _col(10) "{hline 50}" +} + + /* Affichage des estimations sur le trait latent du modĂšle final */ +di +di %~85s as text "Latent trait distribution" +di _col(10) "{hline 65}" +di _col(28) as text "Estimate" _col(44) "Standard error" _col(62) "P-value" +di _col(10) "{hline 65}" + +if "`group'" == "" { + local fact_k = 2 +} +else { + local fact_k = 4 +} + +di _col(10) as text "Variance Time 1" as result _col(28) %6.2f `=mod4[1,`=`fact_k'*`nbmoda_sum'+1']' _col(44) %6.2f =mod4[2,`=`fact_k'*`nbmoda_sum'+1'] +di _col(10) as text "Variance Time 2" as result _col(28) %6.2f `=mod4[1,`=`fact_k'*`nbmoda_sum'+2']' _col(44) %6.2f `=mod4[2,`=`fact_k'*`nbmoda_sum'+2']' +di _col(10) as text "Covariance" as result _col(28) %6.2f `=mod4[1,`=`fact_k'*`nbmoda_sum'+3']' _col(44) %6.2f `=mod4[2,`=`fact_k'*`nbmoda_sum'+3']' + +if "`group'" != "" { + + di _col(10) as text "Group effect" as result _col(28) %6.2f `geffm4' _col(44) %6.2f `segeffm4' _col(62) %6.4f `gpm4p' +} +di _col(10) as text "Time effect" as result _col(28) %6.2f `teffm4' _col(44) %6.2f `seteffm4' _col(62) %6.4f `tm4p' + +if "`group'" != "" { + if effet[3,3] < 0.05 { + di _col(10) as text "TimexGroup inter" as result _col(28) %6.2f effet[1,3] _col(44) %6.2f effet[2,3] _col(62) %6.4f effet[3,3] + } + else { + di _col(10) as text "TimexGroup inter" as result _col(28) "0 (constrained)" + } +} + +di as text _col(10) "{hline 65}" + +/***************************************/ +/* Calcul des valeurs de DIF et de RC */ +/*************************************/ + +forvalues j=1/`nbitems' { + if `nbmoda_`j'' >= 2 { + matrix valeur_difrc_`j' = J(`nbdif_`j'',8,.) + matrix colnames valeur_difrc_`j' = DIFT1 DIFT1_SE RC_GP0 RC_GP0_SE RC_GP1 RC_GP1_SE + } +} + +forvalues j=1/`nbitems'{ + if `nbmoda_`j'' >= 2 { + if "`group'" != "" { + *DIF + if "`nodif'"=="" { + if (dif_rc[`j',1] != . ) { + forvalues p=1/`nbdif_`j'' { + if `p' == 1 { + qui lincom -[1.``j'']:1.`gp'+[1.``j'']:0.`gp' + matrix valeur_difrc_`j'[`p',1] = r(estimate) + matrix valeur_difrc_`j'[`p',2] = round(r(se),0.01) + } + if `p' > 1 { + qui lincom [`=`p'-1'.``j'']:1.`gp' - [`p'.``j'']:1.`gp' -[`=`p'-1'.``j'']:0.`gp' + [`p'.``j'']:0.`gp' + matrix valeur_difrc_`j'[`p',1] = r(estimate) + matrix valeur_difrc_`j'[`p',2] = round(r(se),0.01) + } + } + } + } + *RC GROUP 0 + if (dif_rc[`j',3] != . & dif_rc[`j',5] != . ) { + forvalues p=1/`nbdif_`j'' { + qui lincom -[1.``=`j'+`nbitems''']:0.`gp' + [1.``j'']:0.`gp' + matrix valeur_difrc_`j'[`p',3] = r(estimate) + matrix valeur_difrc_`j'[`p',4] = round(r(se),0.01) + if `p' > 1 { + qui lincom [`=`p'-1'.``=`j'+`nbitems''']:0.`gp' - [`p'.``=`j'+`nbitems''']:0.`gp' -[`=`p'-1'.``j'']:0.`gp' + [`p'.``j'']:0.`gp' + matrix valeur_difrc_`j'[`p',3] = r(estimate) + matrix valeur_difrc_`j'[`p',4] = round(r(se),0.01) + } + } + } + *RC GROUP 1 + if (dif_rc[`j',3] != . & dif_rc[`j',7] != . ) { + forvalues p=1/`nbdif_`j'' { + qui lincom -[1.``=`j'+`nbitems''']:1.`gp' + [1.``j'']:1.`gp' + matrix valeur_difrc_`j'[`p',5] = r(estimate) + matrix valeur_difrc_`j'[`p',6] = round(r(se),0.01) + if `p' > 1 { + qui lincom [`=`p'-1'.``=`j'+`nbitems''']:1.`gp' - [`p'.``=`j'+`nbitems''']:1.`gp' -[`=`p'-1'.``j'']:1.`gp' + [`p'.``j'']:1.`gp' + matrix valeur_difrc_`j'[`p',5] = r(estimate) + matrix valeur_difrc_`j'[`p',6] = round(r(se),0.01) + } + } + } + } + else { + forvalues p=1/`nbdif_`j'' { + qui lincom -[1.``=`j'+`nbitems''']_cons + [1.``j'']_cons + matrix valeur_difrc_`j'[`p',3] = r(estimate) + matrix valeur_difrc_`j'[`p',4] = round(r(se),0.01) + if `p' > 1 { + qui lincom [`=`p'-1'.``=`j'+`nbitems''']_cons - [`p'.``=`j'+`nbitems''']_cons -[`=`p'-1'.``j'']_cons + [`p'.``j'']_cons + matrix valeur_difrc_`j'[`p',3] = r(estimate) + matrix valeur_difrc_`j'[`p',4] = round(r(se),0.01) + } + } + } + } +} + +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' >= 2 { + forvalues p = 1/`nbdif_`j'' { + forvalues k = 1/8 { + if valeur_difrc_`j'[`p',`k'] == . { + matrix valeur_difrc_`j'[`p',`k'] = 0 + } + } + } + } +} + + /* Affichage des estimations des valeurs de DIF et de RC */ +if "`group'" != "" { + di + di %~85s as text "Estimates of differences between groups and recalibration" +} +else { + di + di %~50s as text "Estimates of recalibration" +} +if "`group'" != "" & "`nodif'"==""{ + di _col(10) "{hline 65}" + di _col(27) "Difference of" _col(52) "RECALIBRATION" + di _col(27) "groups at T1" _col(47) abbrev("`gp'",15) "=0" _col(62) abbrev("`gp'",15) "=1" + di _col(10) "{hline 65}" +} +else if "`group'" != "" & "`nodif'"!="" { + di _col(10) "{hline 50}" + di _col(32) "RECALIBRATION" + di in ye _col(27) "`gp'=`=rep[1,1]'" _col(47) "`gp'=`=rep[2,1]'" + di _col(10) "{hline 50}" +} +else { + di _col(10) "{hline 30}" + di _col(25) "RECALIBRATION" + di _col(10) "{hline 30}" +} + +forvalues j=1/`nbitems' { + if `nbmoda_`j'' >= 2 { + if "`group'" != "" & "`nodif'" == "" { + di as text _col(10) "``j''" + } + else { + di as text _col(10) "``j''" + } + forvalues p=1/`nbdif_`j'' { + if "`group'" != "" & "`nodif'"=="" { + di as text _col(10) "`p'" as result _col(27) %6.2f `=valeur_difrc_`j'[`p',1]' " (" %4.2f `=valeur_difrc_`j'[`p',2]' ")" /// + _col(47) %6.2f `=valeur_difrc_`j'[`p',3]' " (" %4.2f `=valeur_difrc_`j'[`p',4]' ")" _col(62) %6.2f `=valeur_difrc_`j'[`p',5]' " (" %4.2f `=valeur_difrc_`j'[`p',6]' ")" + } + else if "`group'" != "" & "`nodif'"!="" { + di as text _col(10) "`p'" as result _col(25) %6.2f `=valeur_difrc_`j'[`p',3]' " (" %4.2f `=valeur_difrc_`j'[`p',4]' ")" _col(45) %6.2f `=valeur_difrc_`j'[`p',5]' " (" %4.2f `=valeur_difrc_`j'[`p',6]' ")" + } + else { + di as text _col(10) "`p'" as result _col(25) %6.2f `=valeur_difrc_`j'[`p',3]' " (" %4.2f `=valeur_difrc_`j'[`p',4]' ")" + } + } + } +} + +if "`group'" != "" & "`nodif'"=="" { + di as text _col(10) "{hline 65}" +} +else if "`group'" != "" & "`nodif'"!=""{ + di as text _col(10) "{hline 50}" +} +else { + di as text _col(10) "{hline 30}" +} +di + + +******************************************************************************* +* New outputs + +if "`group'" == "" { + matrix testlrm = J(1,3,.) + matrix colnames testlrm = chi_square df pvalue + matrix rownames testlrm = m1_vs_m2 + matrix testlrm[1,1] = (`rstestchi',`rstestdf',`rstestp') + return matrix test_model = testlrm +} +else if "`nodif'" != "" { + matrix testlrm = J(1,3,.) + matrix colnames testlrm = chi_square df pvalue + matrix rownames testlrm = m1_vs_m2 + matrix testlrm[1,1] = (`rstestchi',`rstestdf',`rstestp') + return matrix test_model = testlrm +} +else { + matrix testlrm = J(2,3,.) + matrix colnames testlrm = chi_square df pvalue + matrix rownames testlrm = mA_vs_mB m1_vs_m2 + matrix testlrm[1,1] = (`diftestchi',`diftestdf',`diftestp') + matrix testlrm[2,1] = (`rstestchi',`rstestdf',`rstestp') + return matrix test_model = testlrm +} + +return matrix model_4 = mod4 +return matrix model_2 = mod2 + +capture qui use `saverspcm', clear + +end + diff --git a/Modules/ado/personal/r/rosali.sthlp b/Modules/ado/personal/r/rosali.sthlp new file mode 100644 index 0000000..cb3f7e8 --- /dev/null +++ b/Modules/ado/personal/r/rosali.sthlp @@ -0,0 +1,64 @@ +{smcl} +{* june2020}{...} +{hline} +help for {hi:rosali}{right:Myriam Blanchin - Priscilla Brisson} +{hline} + +{title:Detection of response shift at item-level between 2 times of measurement} + +{p 4}{cmd:rosali} {it:varlist} [{it:if}] [{it:in}] [, {cmdab:group}({it:string}) {cmdab:nodif} {cmdab:detail}] + +{p 4 4 4 140}{it:varlist} contains the list of items: the first part of the list is composed of the items at time 1 and the second part of the items at time 2, in the same order. + +{title:Description} + +{p 4 12 2 140}{cmd:rosali} performs the {bf:R}esp{bf:O}nse {bf:S}hift {bf:AL}gorithm at {bf:I}tem-level (ROSALI) based on partial credit models +between two times of measurement, time 1 and time 2. Only uniform or non-uniform {bf:r}e{bf:c}alibration can be detected. Response shift detection is performed at item-level assuming all individuals of the sample are affected the same way by default. A dichotomous group variable can be specified with the {cmd:group} option to assess its impact on latent variable, item functioning and response shift. {bf:D}ifferential {bf:I}tem {bf:F}unctionning (DIF) refers to a constant difference of item difficulties between groups over time. + +{title:Options} + +{p 4 12 2 140}{cmd:group}({it:string}) specifies a binary group variable that can affect item functioning, the estimation of the latent variable means (group effect) +and response shift. Response shift can be common to both groups or differential (occuring in only one group or affecting both groups differentially). By default, response shift detection is performed assuming all individuals are affected in the same way. + +{phang}{cmd:nodif} assumes no DIF occurs in the sample and skips DIF detection. Only response shift detection is performed. {it:Use only with group option.} + +{phang}{cmd:detail} displays results of each step of ROSALI. + +{title:Remarks} + +{p 4} {it:Data} must be in wide format, one row per individual. + +{p 4} At least two items per time of measurement are required. + +{p 4 12 2 140} {cmd:automatic recoding for response categories} +{break} Response categories are automatically recoded to start from 0. +{break} If a response category is not used at one time of measurement, this category is automatically recoded at both times of measurement (for each group if group option). +{break} Rules for automatic recoding: +{break} - 0 response category: merged with response category 1. +{break} - most difficult response category: merged with the previous one. +{break} - other response categories: randomly merged with the next or previous adjacent one. + +{title:Outputs} + +{p 4 12 2 140}{bf:Matrix:} + +{phang}{cmd:r(test_model)}: Result of LRT between models A/B and models 1/2: chi-square statistic, DF and p-value. + +{phang}{cmd:r(model_#)}: Item difficulties and latent trait distribution parameters of models #2 or #4 : Estimates, standard errors, 95% confidence interval, chi-square statistics, DF and p-values. + +{title:Examples} + +{phang}{cmd: . rosali m0gh1 m0gh2 m0gh3 m0gh4 m0gh5 m6gh1 m6gh2 m6gh3 m6gh4 m6gh5, detail } + +{phang}{cmd: . rosali it1_t1-it9_t2 , group(cancer_site) } + +{title:Reference} + +{p} Blanchin, M., Guilleux, A., Hardouin, J.-B., & SĂ©bille, V. (2020). Comparison of structural equation modelling, item response theory and Rasch measurement theory-based methods for response shift detection at item level: A simulation study: Statistical Methods in Medical Research, 19(4), 1015–1029. https://doi.org/10.1177/0962280219884574 + +{title:Authors} + +{p}Myriam Blanchin, Research engineer, PhD, SPHERE - UMR INSERM U1246, "methodS in Patient-centered outcomes and HEalth ResEarch", University of Nantes, France {browse "mailto:myriam.blanchin@univ-nantes.fr":myriam.blanchin@univ-nantes.fr} +{break}Priscilla Brisson, SPHERE - UMR INSERM U1246, "methodS in Patient-centered outcomes and HEalth ResEarch", University of Nantes, France + + diff --git a/Modules/ado/personal/r/rosali22.ado b/Modules/ado/personal/r/rosali22.ado new file mode 100644 index 0000000..c072c35 --- /dev/null +++ b/Modules/ado/personal/r/rosali22.ado @@ -0,0 +1,3266 @@ +*! version 2.2 february2019 +*! Myriam Blanchin - Priscilla Brisson +*! construction +************************************************************************************************************ +* ROSALI: RespOnse-Shift ALgorithm at Item-level +* Response-shift detection based on Rasch models family +* +* Version 1 : December 21, 2016 (Myriam Blanchin) /*rspcm122016*/ +* Version 1.1 : October 13, 2017 (Myriam Blanchin) /*option: MODA, automatic recoding of unused response categories*/ +* Version 2 : April, 2018 (Myriam Blanchin - Priscilla Brisson) /*option: GROUP, dichotomous group variable*/ +* Version 2.1 : October, 2018 (Myriam Blanchin - Priscilla Brisson) /* Version 1.1 + Version 2 */ +* Version 2.2 : February, 2019 (Priscilla Brisson) /* option nodif, keep name of variables, optimization */ +* +* Myriam Blanchin, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* myriam.blanchin@univ-nantes.fr +* +* Priscilla Brisson, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* priscilla.brisson@univ-nantes.fr +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define rosali22, rclass + +timer clear 1 +timer on 1 + +syntax varlist(min=2 numeric) [if] [in] [,ID(string) MODA(string) GROUP(string) NODIF] +version 15 +tempfile saverspcm +qui save `saverspcm',replace +local save1=_rc + +if "`if'"!=""|"`in'"!="" { + qui keep `if' `in' +} + +/**************************************************************************/ +set more off +set matsize 5000 + +local id "`id'" +local gp "`group'" + +tokenize `varlist' +local nbitems:word count `varlist' + + /* VĂ©rif nb d'items pair */ +local mod=mod(`nbitems',2) +if `mod'!=0 { + di in red "You must enter an even number of items : the first half of the items represents the items at time 1 and the second half the items at time 2" + error 198 + exit +} + +local nbitems=`nbitems'/2 + + +* VĂ©rification du format wide +if "`id'" == "" { + di in red "You must enter an identifiant ({hi:id} option). Please correct this option." + error 198 + exit +} +qui tab `id' +local nbpat = r(r) +local nbline = _N +if `nbpat' != `nbline' { + di in red "Data must be in wide format : one line for one patient. Please correct this." + error 198 + exit +} + +if "`group'"=="" & "`nodif'"!="" { + di in red "nodif can only be used with the group option ({hi:nodif} option). Please correct this option." + error 198 + exit +} + +if "`moda'"!="" { + local listmoda:word count `moda' + if `listmoda'!=`nbitems' { + di in red "You have indicated a number of categories ({hi:moda} option) different of the number of items. Please correct this option." + if `listmoda' < `nbitems' { + error 122 + exit + } + if `listmoda' > `nbitems' { + error 123 + exit + } + } +} + + +local nbc: word count `group' +if `nbc' >= 2 { + di in red "Only one variable can be used for group option ({hi:group} option). Please correct this option." + error 198 + exit +} + + /* VĂ©rif qu'il y a 2 groupes si l'option groupe est choisie */ +if "`group'"!="" { + qui tab `group' + local nbgrp = r(r) + if `nbgrp' != 2 { + di in red "The option group must be used with only 2 groups ({hi:group} option). Please correct this option." + error 420 + exit + } +} +/* recoder la variable de groupe en 0, 1*/ + +if "`group'"!="" { + qui tab `gp', matrow(rep) + qui matrix list rep + if rep[1,1]+rep[2,1] != 1 & rep[1,1]*rep[2,1] != 0 { + forvalues i=1/`=rowsof(rep)'{ + qui replace `gp'=`i'-1 if `gp'==rep[`i',1] + di "WARNING : `gp' `=rep[`i',1]' is now `gp' `=`i'-1' " + } + } + forvalues g = 0/1 { + qui tab `gp' if `gp' == `g' + local nbp_gp`g' = r(N) + } +} + + + +/*item rename*/ +/* +Items au temps 1 : 1 Ă  nbitems ``j'' +Items au temps 2 : nbitems Ă  2*nbitems ``=`j'+`nbitems''' + +Si t varie, puis num item : ``=(`t'-1)*`nbitems'+`j''' +*/ + +di +di "WARNING : Automatic recoding, so that the first response category is 0. see {help rosali22:help rosali22}." +di + + /*verif modalitĂ©s rĂ©pondues*/ +if "`gp'" == "" { // Si pas d'option groupe + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'' // RĂ©cupĂ©ration des infos moda du temps 1 + local nbm`j'_t1 = r(r) + qui su ``j'' + local minm`j'_t1 = r(min) + local maxm`j'_t1 = r(max) + + qui tab ``=`j'+`nbitems''' // RĂ©cupĂ©ration des infos moda du temps 2 + local nbm`j'_t2 = r(r) + qui su ``=`j'+`nbitems''' + local minm`j'_t2 = r(min) + local maxm`j'_t2 = r(max) + + local minm_`j' = min(`minm`j'_t1',`minm`j'_t2') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1',`maxm`j'_t2') + local nbm_`j' = `=`maxm_`j''-`minm_`j''' + + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`nbm_`j'' { + qui count if ``j'' == `m' + local nb_rn1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' + local nb_rn2 = r(N) + local nb_rn = min(`nb_rn1',`nb_rn2') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' <= `minm`j'_t1' | `m' <= `minm`j'_t2' { // La moda 0 ou les moda min ne sont pas utilisĂ©es + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: item ``j'': answers `m' and `=`m'+`k'' merged " + local stop = 0 + } + } + } + else if `m' >= `maxm`j'_t1' | `m' >= `maxm`j'_t2' | `m' == `maxm_`j'' { // La (ou les) moda max ne sont pas utilisĂ©e(s) + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: item ``j'': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local hour=real(substr("$S_TIME",1,2)) + local min=real(substr("$S_TIME",4,2)) + local sec=real(substr("$S_TIME",7,2)) + local jour=real(substr("$S_DATE",1,2)) + global seed=784556+`sec'*1000000+`min'*10000+`hour'*100+`jour' + set seed $seed + + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems''' =`=`m'-`k'' if ``=`j'+`nbitems''' ==`m' + di "WARNING: item ``j'': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: item ``j'': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: item answers ``j'': `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} +else { // Cas oĂč l'option groupe est utilisĂ©e + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'' if `gp' == 0 // RĂ©cupĂ©ration des infos moda du temps 1pour chaque groupe + local nbm`j'_t1_g0 = r(r) + qui su ``j'' if `gp' == 0 + local minm`j'_t1_g0 = r(min) + local maxm`j'_t1_g0 = r(max) + + qui tab ``j'' if `gp' == 1 + local nbm`j'_t1_g1 = r(r) + qui su ``j'' if `gp' == 1 + local minm`j'_t1_g1 = r(min) + local maxm`j'_t1_g1 = r(max) + + qui tab ``=`j'+`nbitems''' if `gp' == 0 // RĂ©cupĂ©ration des infos moda du temps 2 pour chaque groupe + local nbm`j'_t2_g0 = r(r) + qui su ``=`j'+`nbitems''' if `gp' == 0 + local minm`j'_t2_g0 = r(min) + local maxm`j'_t2_g0 = r(max) + + qui tab ``=`j'+`nbitems''' if `gp' == 1 + local nbm`j'_t2_g1 = r(r) + qui su ``=`j'+`nbitems''' if `gp' == 1 + local minm`j'_t2_g1 = r(min) + local maxm`j'_t2_g1 = r(max) + + local minm_`j' = min(`minm`j'_t1_g0',`minm`j'_t2_g0',`minm`j'_t1_g1',`minm`j'_t2_g1') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1_g0',`maxm`j'_t2_g0',`maxm`j'_t1_g1',`maxm`j'_t2_g1') + local nbm_`j' = `=`maxm_`j''-`minm_`j''+1' + + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`=`nbm_`j''-1' { + qui count if ``j'' == `m' & `gp' == 0 + local nb_rn1_g0 = r(N) + qui count if ``j'' == `m' & `gp' == 1 + local nb_rn1_g1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 0 + local nb_rn2_g0 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 1 + local nb_rn2_g1 = r(N) + local nb_rn = min(`nb_rn1_g0',`nb_rn2_g0',`nb_rn1_g1',`nb_rn2_g1') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' < `minm`j'_t1_g0' | `m' < `minm`j'_t2_g0' | `m' < `minm`j'_t1_g1' | `m' < `minm`j'_t2_g1' { // La moda 0 n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: item ``j'': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + } + } + else if `m' == `=`nbm_`j''-1' | `m' >= `maxm`j'_t2_g0' | `m' >= `maxm`j'_t1_g1' | `m' >= `maxm`j'_t2_g1' { // La moda max n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`m'' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0 ) & `stop' != 0 { + qui replace ``j''= `=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: item ``j'': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { // Moda central non utilisĂ©e + local hour=real(substr("$S_TIME",1,2)) + local min=real(substr("$S_TIME",4,2)) + local sec=real(substr("$S_TIME",7,2)) + local jour=real(substr("$S_DATE",1,2)) + global seed=784556+`sec'*1000000+`min'*10000+`hour'*100+`jour' + set seed $seed + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'-`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: item ``j'': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0{ + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: item ``j'': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: item ``j'': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} + + +forvalues j =1/`nbitems' { + qui tab ``j'', matrow(rec) // RĂ©cupĂ©ration des infos moda du temps 1 + local nbm`j'_t1 = r(r) + + qui tab ``=`j'+`nbitems''' // RĂ©cupĂ©ration des infos moda du temps 2 + local nbm`j'_t2 = r(r) + + local nbm_`j' = max(`nbm`j'_t1', `nbm`j'_t2') + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`nbm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=rec[`=`r'+1',1]' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=rec[`=`r'+1',1]' + } +} + + +forvalues j = 1/`nbitems' { + if `recoda_`j'' == 1 { + if "`gp'" != "" { + di + di "``j'' & ``=`j'+`nbitems''' after automatic recoding :" + di + tab ``j'' `gp' + tab ``=`j'+`nbitems''' `gp' + } + else { + di + di "``j'' & ``=`j'+`nbitems''' after automatic recoding :" + di + tab ``j'' + tab ``=`j'+`nbitems''' + + } + di + di + } +} + + +/* Calcul de nbmoda & nbdif */ +forvalues j = 1/`nbitems' { + qui tab ``j'' + local nbmoda_`j' = r(r) + local nbdif_`j' = r(r) - 1 +} + +local maxdif = 0 +local nbmoda_sum = 0 +forvalues j = 1/`nbitems' { + if `maxdif' < `nbdif_`j'' { + local maxdif = `nbdif_`j'' + } + local nbmoda_sum = `nbmoda_sum' + `nbdif_`j'' +} + +/* Au moins 2 mmoda par item */ +forvalues j=1/`nbitems' { + if `nbmoda_`j'' == 1 { + di in red "``j'' have only one response category, each item need at least 2 response categories" + error 198 + exit + } +} + +/* VĂ©rification moda thĂ©orique VS moda rĂ©elles -> CONSTAT */ +if "`moda'" != "" { + forvalues j=1/`nbitems' { + local nbmoda`j':word `j' of `moda' + + if `nbmoda`j'' != `nbmoda_`j'' { //nbmodaj = nb moda annoncĂ© par l'uti. (thĂ©orique) VS nbmoda_j = nb moda utilisĂ©e (rĂ©el) + di " WARNING : `nbmoda`j'' response categories exist for item ``j'' but only `nbmoda_`j'' seem to be used" + local recoda_`j' = 1 + } + } +} + +local coln "" +forvalues j =1 /`nbitems' { + local coln "`coln' ``j''" +} + +matrix nbmod = J(2,`nbitems',.) + +matrix colnames nbmod = `coln' +matrix rownames nbmod = NbModa Recoding + +forvalues j = 1/`nbitems' { + matrix nbmod[1,`j'] = `nbmoda_`j'' + matrix nbmod[2,`j'] = `recoda_`j'' +} + +*Erreur si plus de 200 difficultĂ©s +local nb_test = 0 +forvalues j=1/`nbitems' { + local nb_test = `nb_test'+`nbmoda_`j'' -1 +} + +if `nb_test' >= 200 { + di in red "The number of items difficulties must be less than 200 ({hi:moda} option option). Please correct this option." + error 198 + exit +} + +local nbitp = 0 + +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' >= 2 { + local nbitp = `nbitp' + 1 + } +} + + +/********************************* +* AFFICHAGE INITIAL +*********************************/ +di _col(5) "{hline 78}" +di _col(5) in ye %~30s "Time 1" _col(30) %~30s "Time 2" _col(55) "Nb of Responses Cat." +di _col(5) "{hline 78}" +forvalues j=1/`nbitems' { + di in gr _col(5) %~30s abbrev("``j''",20) _col(30) %~30s abbrev("``=`j'+`nbitems'''",20) _col(75) `nbmoda_`j'' +} +di _col(5) "{hline 78}" +if "`group'" != "" { + di _col(10) "Nb. of patients : " abbrev("`gp'",20) " 0 = `nbp_gp0' ;", abbrev("`gp'",20) " 1 = `nbp_gp1'" + di _col(5) "{hline 78}" +} +else { + di _col(20) "Nb. of patients : `nbpat'" + di _col(5) "{hline 78}" +} +di +if `nbitems' == 1 { + di in red "2 items at least is necessary to detect DIF and/or RC at item level." + error 198 + exit +} +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' == 2 { + di "WARNING: ``j'' have only 2 response categories, the type uniform or non-uniform can't be detected." + } + if `nbmoda_`j'' == 1 { + di in red "``j'' uses only `nbmoda_`j'' response category, each item need at least 2 response categories used." + error 198 + exit + } + if `nbmoda_`j'' == 0 { + di in red "``j'' uses no response category, each item needs at least 2 response categories used." + error 198 + exit + } +} +di +if "`group'" != "" { + di _col(2) in ye "For all models : - mean of latent trait of `gp' 0 at time 1 is constrained at 0" + di _col(19) "- Equality of variances between groups" + di +} +else { + di _col(2) in ye "For all models : mean of latent trait at time 1 is constrained at 0" + di +} + +/********************************* +* DEFINITION DES CONTRAINTES +*********************************/ + +if "`group'"!="" { // Contraintes si option groupe + *EGALITE ENTRE GROUPES A T1 (1-200) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=0+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``j'']1.`gp' + } + } + + *DIF UNIFORME A T1 (201-400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=200+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp'=`p'*[1.``j'']1.`gp'-`p'*[1.``j'']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 0 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 1 (601-800) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=600+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp' + } + } + + * RC COMMUNE (801-1000) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=800+`maxdif'*(`j'-1)+`p'' [`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + * RC UNIFORME, groupe 0 (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp' + } + } + + * RC UNIFORME, groupe 1 (1201-1400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1200+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + *Sans interaction temps x groupe + constraint 1999 [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'=[/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' +} +else { //Contraintes si pas d'option groupe + *EGALITE ENTRE T1 et T2 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']:_cons = [`p'.``=`j'+`nbitems''']:_cons + } + } + *RC UNIFORME (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']:_cons - [1.``j'']:_cons)=[`p'.``=`j'+`nbitems''']:_cons -[`p'.``j'']:_cons + } + } +} + +/********************************* +* MATRICE DES RESULTATS +*********************************/ +matrix dif_rc=J(`nbitems',8,.) +matrix colnames dif_rc=DIFT1 DIFU RC RC_DIF RCG0 RCUG0 RCG1 RCUG1 +local rown "" + +forvalues j =1 /`nbitems' { + local rown "`rown' ``j''" +} +matrix rownames dif_rc = `rown' + +*Nb modalitĂ© max +local nbdif_max = 0 +forvalues j=1/`nbitems' { + if `nbdif_max' < `nbdif_`j'' { + local nbdif_max = `nbdif_`j'' + } +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////// PARTIE 1 : DIF A T1 ? //////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +if "`group'"!="" & "`nodif'"=="" { // PARTIE 1 = Slmt si option group & pas de "nodif" + di _dup(59) "_ " + di + di _col(5) in ye "PART 1: DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES BETWEEN GROUPS AT FIRST TIME OF MEASUREMENT" + + ********************************* + ** MODEL B ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading cons) var(0: THETA@v) var(1:THETA@v) + /* Stockage des estimations du modĂšle */ + estimates store modeldifB + matrix val_mB = r(table) + matrix esti_B = e(b) + + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mB=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + + matrix colnames delta_mB = `name_partOneC' + matrix rownames delta_mB = `name_partOneL' + matrix delta_mB_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mB_se = `name_partOneC_se' + matrix rownames delta_mB_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB=r(estimate) + local delta`j'_`p'g`g'mB_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB = r(estimate) + local delta`j'_`p'g`g'mB_se = r(se) + } + matrix delta_mB[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB' + matrix delta_mB_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB_se' + } + } + } + + matrix var_mB = (val_mB[1,"/var(THETA)#0bn.`gp'"]\val_mB[2,"/var(THETA)#0bn.`gp'"]) + + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmB=r(estimate) + local segeffmB=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmBp=r(p) + local gcmBchi=r(chi2) + local gcmBdf=r(df) + + + ********************************* + ** MODEL A ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading means) var(0: THETA@v) var(1:THETA@v) from(esti_B, skip) + + /* Stockage des estimations du modĂšle */ + estimates store modeldifA + matrix val_mA = r(table) + matrix esti_A = e(b) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mA=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mA = `name_partOneC' + matrix rownames delta_mA = `name_partOneL' + matrix delta_mA_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mA_se = `name_partOneC_se' + matrix rownames delta_mA_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA=r(estimate) + local delta`j'_`p'g`g'mA_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA = r(estimate) + local delta`j'_`p'g`g'mA_se = r(se) + } + matrix delta_mA[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA' + matrix delta_mA_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA_se' + } + } + } + //Variance et se mA + matrix var_mA = (val_mA[1,"/var(THETA)#0bn.`gp'"]\val_mA[2,"/var(THETA)#0bn.`gp'"]) + + + ************************************************************* + ***********************AFFICHAGE***************************** + ************************************************************* + + //Affichage modĂšle A + di + di in ye "PROCESSING STEP A" + di + + + /* Affichage des estimations des difficultĂ©s modĂšle A */ + + di _col(5) in ye "{ul:MODEL A:} No group effect: mean of latent trait of group 1 = mean of latent trait of group 0," + di _col(7) in ye "all item difficulties are freely estimated in both groups" + di + di _col(10) in ye "Item difficulties estimates (s.e.)" + di _col(10) "{hline 70}" + di _col(30) in ye abbrev("`gp'",20) "=0" _col(60) abbrev("`gp'",20) "=1" + di _col(10) "{hline 70}" + forvalues j=1/`nbitems' { + di in ye _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + di in gr _col(10) "`p'" _col(30) %6.2f `delta`j'_`p'g0mA' %6.2f " (" %3.2f `delta`j'_`p'g0mA_se' ")" _col(60) %6.2f `delta`j'_`p'g1mA' " (" %3.2f `delta`j'_`p'g1mA_se' ")" + } + } + di _col(10) "{hline 70}" + /* Affichage des estimations sur le trait latent du modĂšle A */ + di + di _col(10) in ye "Latent trait distribution estimates" + di _col(10) "{hline 65}" + di _col(45) in ye "Estimate" _col(60) "Standard error" + di _col(10) "{hline 65}" + di _col(10) in ye "Variance" in gr _col(45) %6.2f `=var_mA[1,1]' _col(62) %6.2f `=var_mA[2,1]' + di _col(10) in ye "Group effect (mean gp 1)" in gr _col(44) %6.2f "0 (constrained)" + di _col(10) "{hline 65}" + + //*Affichage modĂšle B + + di + di in ye "PROCESSING STEP B" + di + + /* Affichage des estimations des difficultĂ©s modĂšle B */ + + di _col(5) in ye "{ul:MODEL B:} Group effect estimated: mean of latent trait of group 1 free estimated," + di _col(7) in ye "Same item difficulties estimated between groups" + di + di _col(10) in ye "Item difficulties estimates (s.e.)" + di _col(10) "{hline 70}" + di _col(30) in ye abbrev("`gp'",20) "=0" _col(60) abbrev("`gp'",20) "=1" + di _col(10) "{hline 70}" + + forvalues j=1/`nbitems' { + di in ye _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + di in gr _col(10) "`p'" _col(30) %6.2f `delta`j'_`p'g0mB' " (" %3.2f `delta`j'_`p'g0mB_se' ")" _col(60) %6.2f `delta`j'_`p'g1mB' " (" %3.2f `delta`j'_`p'g1mB_se' ")" + } + } + + di _col(10) "{hline 70}" + /* Affichage des estimations sur le trait latent du modĂšle B */ + di + di _col(10) in ye "Latent trait distribution estimates" + di _col(10) "{hline 80}" + di _col(45) in ye "Estimate" _col(60) "Standard error" _col(77) "P-value" + di _col(10) "{hline 80}" + di _col(10) in ye "Variance" in gr _col(44) %6.2f `=var_mB[1,1]' _col(62) %6.2f `=var_mB[2,1]' + di _col(10) in ye "Group effect (mean gp 1)" in gr _col(44) %6.2f `geffmB' _col(62) %6.2f `segeffmB' _col(77) %6.4f `gcmBp' + di _col(10) "{hline 80}" + di + + ***************************************************** + * ModĂšle A vs ModĂšle B * + ***************************************************** + + qui lrtest modeldifA modeldifB + local diftestp=r(p) + local diftestchi=r(chi2) + local diftestdf=r(df) + + //affichage lrtest + di _col(10) in ye "LIKELIHOOD-RATIO TEST MODEL A VS MODEL B : " + di _col(10) "{hline 50}" + di _col(10) in ye "Chi-square" _col(30) "DF" _col(50) "P-value" + di _col(10) in gr %6.2f `diftestchi' _col(30) %2.0f `diftestdf' _col(50) %6.4f `diftestp' + di _col(10) "{hline 50}" + if `diftestp'<0.05{ + di _col(10) in ye "DIFFERENCE IN ITEM DIFFICULTIES BETWEEN GROUPS LIKELY" + } + else{ + di _col(10) in ye "NO DIFFERENCE BETWEEN GROUPS DETECTED" + } + + ********************************* + *************MODEL C************* + ********************************* + // Etape itĂ©rative si lrtest significatif + local nb_stepC = 0 + + if `diftestp'<0.05{ /*If pvalue(LRtest)<0.05 then step C*/ + di + di in ye "PROCESSING STEP C" + di + /*test DIF pour chaque item*/ + local boucle = 1 + local stop = 0 + while `boucle'<=`=`nbitp'-1' & `stop'==0{ /*on s'arrĂȘte quand on a libĂ©rĂ© du DIF sur (tous les items-1) ou lorsqu'il n'y a plus de tests significatifs*/ + local nb_stepC = `boucle' + local pajust=0.05/`=`nbitp'+1-`boucle'' + /*rĂ©initialisation de la matrice de test*/ + matrix test_difu_`boucle'=J(`nbitems',3,.) + matrix colnames test_difu_`boucle'=chi_DIFU df_DIFU pvalueDIFU + matrix test_dif_`boucle'=J(`nbitems',3,.) + matrix colnames test_dif_`boucle'=chi_DIF df_DIF pvalueDIF + local nbsig=0 + local minpval=1 + local itemdif=0 + di _col(10) "{hline 70}" + di _col(10) in ye "Loop `boucle'" _col(50) "Adjusted alpha: " %6.4f `pajust' + di + di in ye _col(40) "Chi-Square" _col(55) "DF" _col(60) "P-Value" + /*boucle de test*/ + forvalues j=1/`nbitems'{ + //if `nbdif_`j'' > 2 { + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF dĂ©jĂ  dĂ©tectĂ© sur l'item j*/ + /*on libĂšre le DIF de l'item i: pas de contraintes*/ + forvalues k=1/`nbitems'{ /*contraintes pour les autres items (si DIF NU sur item k, pas de contraintes*/ + if `k'!=`j' & `nbmoda_`j'' >= 2 { + if dif_rc[`k',1]==. | dif_rc[`k',1]==0 {/*pas de DIF sur item k: contraintes 1-200*/ + forvalues p=1/`nbdif_`k''{ + qui local listconst "`listconst' `=0+`maxdif'*(`k'-1)+`p''" + qui constraint list `=0+`maxdif'*(`k'-1)+`p'' + } + } + else{ + if dif_rc[`k',2]!=. & dif_rc[`k',2]!= 0 & `nbmoda_`k'' > 2 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`k''{ + qui local listconst "`listconst' `=200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + } + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) + estimates store modeldif3b`boucle'it`i' + + ************************* + *****test DIF item i***** + ************************* + qui test [1.``j'']0bn.`gp'=[1.``j'']1.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']0bn.`gp'=[`p'.``j'']1.`gp', acc + } + } + matrix test_dif_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + + /* Test DIF Uniforme */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``j'']0bn.`gp'-[1.``j'']1.`gp')=[2.``j'']0bn.`gp'-[2.``j'']1.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``j'']0bn.`gp'-[1.``j'']1.`gp')=[`p'.``j'']0bn.`gp'-[`p'.``j'']1.`gp', acc + } + matrix test_difu_`boucle'[`j',1]=(r(chi2), r(df), r(p)) + } + + if test_dif_`boucle'[`j',3]<`pajust'{/*si DIF sur item i*/ + local ++nbsig + if test_dif_`boucle'[`j',3]<`minpval'{ + local minpval=test_dif_`boucle'[`j',2] + local itemdif=`j' + } + } + di in ye _col(12) %-30s abbrev("``j'' :",22) in gr _col(40) %6.3f test_dif_`boucle'[`j',1] _col(55) test_dif_`boucle'[`j',2] _col(60) %6.4f test_dif_`boucle'[`j',3] + } + } + /*si nb de tests significatifs=0, on arrĂȘte*/ + if `nbsig'==0{ + local stop=1 + if `boucle' == 1 { + di + di _col(20) in ye ">>> No significant test: no difference between groups detected, no DIF detected" + di _col(10) "{hline 70}" + } + else { + di + di _col(20) in ye ">>> No other significant tests" + di _col(10) "{hline 70}" + } + } + else{/*si nb de tests significatifs>0, mise Ă  jour de la matrice de rĂ©sultats*/ + matrix dif_rc[`itemdif',1]=`boucle' + di _col(15) _dup(60) "-" + di _col(15) in ye "Difference between groups on ``itemdif'' at time 1" + if `nbmoda_`itemdif'' > 2 { + di + di _col(40) "Chi-Square" _col(55) "DF" _col(60) "P-value" + di _col(15) in ye "Uniform ? " in gr _col(40) %4.2f `=test_difu_`boucle'[`itemdif',1]' _col(55) `=test_difu_`boucle'[`itemdif',2]' _col(60) %4.2f `=test_difu_`boucle'[`itemdif',3]' + if test_difu_`boucle'[`itemdif',3]<0.05{ /*DIF NU dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=0 + di + di _col(17) in ye " >>> ``itemdif'' : Non-uniform differences of item difficulties between groups at T1" + di _col(15) _dup(60) "-" + + } + else{/*DIF U dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=`boucle' + di + di _col(17) in ye ">>> ``itemdif'' : Uniform differences of item difficulties between groups at T1" + di _col(15) _dup(60) "-" + } + } + else { + // DiffĂ©rence entre groupes au temps 1 mais slmt 2 moda. donc pas de U ou NU + di _col(15) _dup(60) "-" + } + } + local ++boucle + } + } + + /* MODELE FINAL DE LA PARTIE 1. Si DIFT1 dĂ©tectĂ© (=Au moins 2 boucles dans l'Ă©tape C)*/ + if `nb_stepC' > 1 { + forvalues j=1/`nbitems'{ + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF: contraintes 1-200*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) + /* Stockage des estimations du modĂšle */ + estimates store modeldifCFin + matrix val_mC = r(table) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mCFin=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mCFin = `name_partOneC' + matrix rownames delta_mCFin = `name_partOneL' + + matrix delta_mCFin_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + matrix colnames delta_mCFin_se = `name_partOneC_se' + matrix rownames delta_mCFin_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin=r(estimate) + local delta`j'_`p'g`g'mCFin_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin = r(estimate) + local delta`j'_`p'g`g'mCFin_se = r(se) + } + matrix delta_mCFin[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin' + matrix delta_mCFin_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin_se' + } + } + } + if "`group'" != "" { //Variance et se mA + matrix var_mC = (val_mC[1,"/var(THETA)#0bn.`gp'"]\val_mC[2,"/var(THETA)#0bn.`gp'"]) + } + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmCFin=r(estimate) + local segeffmCFin=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmCFinp=r(p) + local gcmCFinchi=r(chi2) + local gcmCFindf=r(df) + } +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////// PARTIE 2 : RECALIBRATION ? //////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +di +di _dup(59) "_ " +di +if "`group'" != "" { + di in ye "PART 2 : DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES ACROSS TIMES (RECALIBRATION)" +} +else { + di in ye "DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES ACROSS TIMES (RECALIBRATION)" +} + + ********************************* + ** MODEL 2 ** + ********************************* + + +local listconst "" + +forvalues j=1/`nbitems'{ /*contraintes pour les autres items (si DIF NU sur item k, pas de contraintes)*/ + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 {/*pas de DIF Ă  T1 sur item k: contraintes 1*/ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else{ + if dif_rc[`j',2]!=. & dif_rc[`j',2] != 0 { /*diff T1 U: contraintes 200*/ + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + forvalues p=1/`nbdif_`j''{ /* egalites entre temps : groupe 0 (401-600)*/ + local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + forvalues p=1/`nbdif_`j''{ /* egalites entre temps : groupe 1 (601-800)*/ + local listconst "`listconst' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=600+`maxdif'*(`j'-1)+`p'' + } +} + +local model "" +forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA1@`p')(`p'.``=`j'+`nbitems'''<-THETA2@`p')" + } +} + +if "`group'" != "" { + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') +} +else { + qui gsem `model', mlogit tol(0.01) iterate(100) means(THETA1@0 THETA2@m20) var(THETA1@v1 THETA2@v2) cov(THETA1*THETA2@cov12) constraint(`listconst') +} + +/*Stockage des donnĂ©es du modĂšle 2 */ +estimates store model2 +matrix val_m2 = r(table) +matrix esti_2 = e(b) + +if "`group'" != "" { + matrix var_m2 = (val_m2[1,"/var(THETA1)#0bn.`gp'"],val_m2[1,"/var(THETA2)#0bn.`gp'"]\val_m2[2,"/var(THETA1)#0bn.`gp'"],val_m2[2,"/var(THETA2)#0bn.`gp'"]) + matrix covar_m2 = (val_m2[1,"/cov(THETA1,THETA2)#0.`gp'"],val_m2[1,"/cov(THETA1,THETA2)#1.`gp'"]\val_m2[2,"/cov(THETA1,THETA2)#0.`gp'"],val_m2[2,"/cov(THETA1,THETA2)#1.`gp'"]\val_m2[4,"/cov(THETA1,THETA2)#0.`gp'"],val_m2[4,"/cov(THETA1,THETA2)#1.`gp'"]) +} +else { + matrix var_m2 = (val_m2[1,"/var(THETA1)"],val_m2[1,"/var(THETA2)"]\val_m2[2,"/var(THETA1)"],val_m2[2,"/var(THETA2)"]) + matrix covar_m2 = (val_m2[1,"/cov(THETA1,THETA2)"]\val_m2[2,"/cov(THETA1,THETA2)"]\val_m2[4,"/cov(THETA1,THETA2)"]) +} + +/*group effect*/ +if "`group'" != "" { + qui lincom [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' + local geffm2=r(estimate) + local segeffm2=r(se) + local ubgeffm2 = r(ub) + local lbgeffm2 = r(lb) + qui test [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp'=0 + local gpm2p=r(p) + local gpm2chi=r(chi2) + local gpm2df=r(df) +} + +/*time effect*/ +if "`group'" != "" { + qui lincom [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp' + local teffm2=r(estimate) + local seteffm2=r(se) + local ubteffm2 = r(ub) + local lbteffm2 = r(lb) + qui test [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp'=0 + local tm2p=r(p) + local tm2chi=r(chi2) + local tm2df=r(df) +} +else { + qui lincom [/]:mean(THETA2) /* [/]:mean(THETA1)*/ + local teffm2=r(estimate) + local seteffm2=r(se) + local ubteffm2 = r(ub) + local lbteffm2 = r(lb) + qui test [/]:mean(THETA2) = 0 /* [/]:mean(THETA1)*/ + local tm2p=r(p) + local tm2chi=r(chi2) + local tm2df=r(df) +} + +*INTERACTION +if "`group'" != "" { + qui lincom [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#1.`gp'+[/]:mean(THETA1)#0bn.`gp' + local interm2=r(estimate) + local seinterm2=r(se) + local ubinterm2 = r(ub) + local lbinterm2 = r(lb) + qui test [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#1.`gp'+[/]:mean(THETA1)#0bn.`gp' = 0 + local interm2p=r(p) + local interm2chi=r(chi2) + local interm2df=r(df) +} + +if "`group'" != "" { + matrix mod2 = J(7,`=`nbmoda_sum'*4+6',.) + local name_partTwoC "" + forvalues j = 1/`nbitems' { + forvalues p=1/`nbdif_`j'' { + forvalues t=1/2 { + forvalues g = 0/1 { + local name_partTwoC "`name_partTwoC' d_j`j'_p`p'_gp`g'_t`t'" + } + } + } + } + local name_partTwoC "`name_partTwoC' VAR(THETA1) VAR(THETA2) COV(TH1,TH2) GROUP_Effect TIME_Effect INTER_TxG " + matrix colnames mod2 = `name_partTwoC' + matrix rownames mod2 = Estimate se Upper_b Lower_b Chi_square DF pvalue +} +else { + matrix mod2 = J(7,`=`nbmoda_sum'*2+4',.) + local name_partTwoC "" + forvalues j = 1/`nbitems' { + forvalues p=1/`nbdif_`j'' { + forvalues t=1/2 { + local name_partTwoC "`name_partTwoC' d_j`j'_p`p'_t`t'" + } + } + } + local name_partTwoC "`name_partTwoC' VAR(THETA1) VAR(THETA2) COV(TH1,TH2) TIME_Effect " + matrix colnames mod2 = `name_partTwoC' + matrix rownames mod2 = Estimate se Upper_b Lower_b Chi_square DF pvalue +} + +*DifficultĂ©s +forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues t=1/2{ + if "`group'" != "" { // groupe binaire + forvalues g=0/1 { + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm2= r(estimate) + local delta`t'_`j'_`p'g`g'm2_se= r(se) + local delta`t'_`j'_`p'g`g'm2_ub=r(ub) + local delta`t'_`j'_`p'g`g'm2_lb=r(lb) + local delta`t'_`j'_`p'g`g'm2_p=r(p) + if `p'>1 { + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' - [`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm2=r(estimate) + local delta`t'_`j'_`p'g`g'm2_se=r(se) + local delta`t'_`j'_`p'g`g'm2_ub=r(ub) + local delta`t'_`j'_`p'g`g'm2_lb=r(lb) + local delta`t'_`j'_`p'g`g'm2_p=r(p) + } + local place = 0 + local compt = 1 + while `compt' < `j' { + local place = `place' + `nbdif_`compt'' + local ++compt + } + if `t' == 1 { + matrix mod2[1,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2' + matrix mod2[2,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2_se' + matrix mod2[3,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2_ub' + matrix mod2[4,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2_lb' + matrix mod2[7,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2_p' + } + if `t' == 2 { + matrix mod2[1,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2' + matrix mod2[2,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2_se' + matrix mod2[3,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2_ub' + matrix mod2[4,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2_lb' + matrix mod2[7,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2_p' + } + } + } + else { // groupe unique (=gp0) + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']_cons + local delta`t'_`j'_`p'g0m2= r(estimate) + local delta`t'_`j'_`p'g0m2_se= r(se) + local delta`t'_`j'_`p'g0m2_ub=r(ub) + local delta`t'_`j'_`p'g0m2_lb=r(lb) + local delta`t'_`j'_`p'g0m2_p=r(p) + if `p'>1{ + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']_cons - [`p'.``=(`t'-1)*`nbitems'+`j''']_cons + local delta`t'_`j'_`p'g0m2=r(estimate) + local delta`t'_`j'_`p'g0m2_se=r(se) + local delta`t'_`j'_`p'g0m2_ub=r(ub) + local delta`t'_`j'_`p'g0m2_lb=r(lb) + local delta`t'_`j'_`p'g0m2_p=r(p) + } + local place = 0 + local compt = 1 + while `compt' < `j' { + local place = `place' + `nbdif_`compt'' + local ++compt + } + if `t' == 1 { + matrix mod2[1,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2' + matrix mod2[2,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_se' + matrix mod2[3,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_ub' + matrix mod2[4,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_lb' + matrix mod2[7,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_p' + } + if `t' == 2 { + matrix mod2[1,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2' + matrix mod2[2,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_se' + matrix mod2[3,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_ub' + matrix mod2[4,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_lb' + matrix mod2[7,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_p' + } + } + } + } +} + +if "`group'" != "" { + matrix mod2[1,`=4*`nbmoda_sum'+1'] = (val_m2[1,"/var(THETA1)#0bn.`gp'"], val_m2[1,"/var(THETA2)#0bn.`gp'"]) + matrix mod2[2,`=4*`nbmoda_sum'+1'] = (val_m2[2,"/var(THETA1)#0bn.`gp'"],val_m2[2,"/var(THETA2)#0bn.`gp'"]) + matrix mod2[3,`=4*`nbmoda_sum'+1'] = (val_m2[6,"/var(THETA1)#0bn.`gp'"],val_m2[6,"/var(THETA2)#0bn.`gp'"]) + matrix mod2[4,`=4*`nbmoda_sum'+1'] = (val_m2[5,"/var(THETA1)#0bn.`gp'"],val_m2[5,"/var(THETA2)#0bn.`gp'"]) + + matrix mod2[1,`=4*`nbmoda_sum'+2+1'] = (val_m2[1,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod2[2,`=4*`nbmoda_sum'+2+1'] = (val_m2[2,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod2[3,`=4*`nbmoda_sum'+2+1'] = (val_m2[6,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod2[4,`=4*`nbmoda_sum'+2+1'] = (val_m2[5,"/cov(THETA1,THETA2)#0.`gp'"]) + + matrix mod2[1,`=4*`nbmoda_sum'+2+1+1'] = `geffm2' + matrix mod2[2,`=4*`nbmoda_sum'+2+1+1'] = `segeffm2' + matrix mod2[3,`=4*`nbmoda_sum'+2+1+1'] = `ubgeffm2' + matrix mod2[4,`=4*`nbmoda_sum'+2+1+1'] = `lbgeffm2' + matrix mod2[5,`=4*`nbmoda_sum'+2+1+1'] = `gpm2chi' + matrix mod2[6,`=4*`nbmoda_sum'+2+1+1'] = `gpm2df' + matrix mod2[7,`=4*`nbmoda_sum'+2+1+1'] = `gpm2p' + + matrix mod2[1,`=4*`nbmoda_sum'+2+1+1+1'] = `teffm2' + matrix mod2[2,`=4*`nbmoda_sum'+2+1+1+1'] = `seteffm2' + matrix mod2[3,`=4*`nbmoda_sum'+2+1+1+1'] = `ubteffm2' + matrix mod2[4,`=4*`nbmoda_sum'+2+1+1+1'] = `lbteffm2' + matrix mod2[5,`=4*`nbmoda_sum'+2+1+1+1'] = `tm2chi' + matrix mod2[6,`=4*`nbmoda_sum'+2+1+1+1'] = `tm2df' + matrix mod2[7,`=4*`nbmoda_sum'+2+1+1+1'] = `tm2p' + + matrix mod2[1,`=4*`nbmoda_sum'+2+1+1+1+1'] = `interm2' + matrix mod2[2,`=4*`nbmoda_sum'+2+1+1+1+1'] = `seinterm2' + matrix mod2[3,`=4*`nbmoda_sum'+2+1+1+1+1'] = `ubinterm2' + matrix mod2[4,`=4*`nbmoda_sum'+2+1+1+1+1'] = `lbinterm2' + matrix mod2[5,`=4*`nbmoda_sum'+2+1+1+1+1'] = `interm2chi' + matrix mod2[6,`=4*`nbmoda_sum'+2+1+1+1+1'] = `interm2df' + matrix mod2[7,`=4*`nbmoda_sum'+2+1+1+1+1'] = `interm2p' +} +else { + matrix mod2[1,`=2*`nbmoda_sum'+1'] = (val_m2[1,"/var(THETA1)"],val_m2[1,"/var(THETA2)"]) + matrix mod2[2,`=2*`nbmoda_sum'+1'] = (val_m2[2,"/var(THETA1)"],val_m2[2,"/var(THETA2)"]) + matrix mod2[3,`=2*`nbmoda_sum'+1'] = (val_m2[6,"/var(THETA1)"],val_m2[6,"/var(THETA2)"]) + matrix mod2[4,`=2*`nbmoda_sum'+1'] = (val_m2[5,"/var(THETA1)"],val_m2[5,"/var(THETA2)"]) + + matrix mod2[1,`=2*`nbmoda_sum'+2+1'] = (val_m2[1,"/cov(THETA1,THETA2)"]) + matrix mod2[2,`=2*`nbmoda_sum'+2+1'] = (val_m2[2,"/cov(THETA1,THETA2)"]) + matrix mod2[3,`=2*`nbmoda_sum'+2+1'] = (val_m2[6,"/cov(THETA1,THETA2)"]) + matrix mod2[4,`=2*`nbmoda_sum'+2+1'] = (val_m2[5,"/cov(THETA1,THETA2)"]) + + matrix mod2[1,`=2*`nbmoda_sum'+2+1+1'] = `teffm2' + matrix mod2[2,`=2*`nbmoda_sum'+2+1+1'] = `seteffm2' + matrix mod2[3,`=2*`nbmoda_sum'+2+1+1'] = `ubteffm2' + matrix mod2[4,`=2*`nbmoda_sum'+2+1+1'] = `lbteffm2' + matrix mod2[5,`=2*`nbmoda_sum'+2+1+1'] = `tm2chi' + matrix mod2[6,`=2*`nbmoda_sum'+2+1+1'] = `tm2df' + matrix mod2[7,`=2*`nbmoda_sum'+2+1+1'] = `tm2p' +} + + + ********************************* + ** MODEL 1 ** + ********************************* + + +/*PCM longitudinal, no true change, group effect, interaction*/ +local listconst "" +forvalues j=1/`nbitems'{ /*contraintes pour les autres items (si DIF NU sur item k, pas de contraintes*/ + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 {/*pas de DIF sur item k: contraintes 1*/ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else{ + if `nbdif_`j'' > 1 { + if dif_rc[`j',2]!=. & dif_rc[`j',2] != 0 { /*diff T1 U: contraintes 201*/ + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } +} + + +local model "" +forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA1@`p')(`p'.``=`j'+`nbitems'''<-THETA2@`p')" + } +} + +if "`group'"!="" { + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@0) means(1: THETA1@m1 THETA2@m1) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) +} +else { + qui gsem `model', mlogit tol(0.01) iterate(100) means(THETA1@0 THETA2@0) var(THETA1@v1 THETA2@v2) cov(THETA1*THETA2@cov12) from(esti_2, skip) +} + +/* Stockage des estimations du modĂšle 1 */ +estimates store model1 +matrix val_m1 = r(table) + +/* Calcul des difficultĂ©s d'item (delta_j) */ +matrix delta_m1 = J(`nbitems',`=`nbdif_max'*4',.) +local name_partTwoC "" +forvalues p=1/`nbdif_max' { + forvalues t=1/2 { + forvalues g = 0/1 { + local name_partTwoC "`name_partTwoC' delta_t`t'_`p'_gp`g'" + } + } +} + +local name_partTwoL "" +forvalues j=1/`=`nbitems'*2' { + if `j' <= `nbitems' { + local name_partTwoL "`name_partTwoL' ``j''" + } + else { + local name_partTwoL "`name_partTwoL' ``=`nbitems'+`j'''" + } +} + +matrix colnames delta_m1 = `name_partTwoC' +matrix rownames delta_m1 = `name_partTwoL' + +matrix delta_m1_se = J(`nbitems',`=`nbdif_max'*4',.) +local name_partTwoC_se "" + +forvalues p=1/`nbdif_max' { + forvalues t=1/2 { + forvalues g = 0/1 { + local name_partTwoC_se "`name_partTwoC_se' delta_t`t'_`p'_gp`g'_se" + } + } +} + +matrix colnames delta_m1_se = `name_partTwoC_se' +matrix rownames delta_m1_se = `name_partTwoL' + +if "`group'"!="" { + forvalues t=1/2{ + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm1= r(estimate) + local delta`t'_`j'_`p'g`g'm1_se= r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' - [`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm1=r(estimate) + local delta`t'_`j'_`p'g`g'm1_se=r(se) + } + if `t' == 1 { + matrix delta_m1[`j',`=4*(`p'-1)+`g'+`t'']=`delta`t'_`j'_`p'g`g'm1' + matrix delta_m1_se[`j',`=4*(`p'-1)+`g'+`t'']=`delta`t'_`j'_`p'g`g'm1_se' + } + if `t' == 2 { + matrix delta_m1[`j',`=4*(`p'-1)+1+`g'+`t'']=`delta`t'_`j'_`p'g`g'm1' + matrix delta_m1_se[`j',`=4*(`p'-1)+1+`g'+`t'']=`delta`t'_`j'_`p'g`g'm1_se' + } + } + } + } + } +} +else { + forvalues t=1/2 { + forvalues j=1/`nbitems' { + forvalues p = 1/`nbdif_`j'' { + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']:_cons + local delta`t'_`j'_`p'g0m1= r(estimate) + local delta`t'_`j'_`p'g0m1_se= r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']:_cons - [`p'.``=(`t'-1)*`nbitems'+`j''']:_cons + local delta`t'_`j'_`p'g0m1=r(estimate) + local delta`t'_`j'_`p'g0m1_se=r(se) + } + if `t' == 1 { + matrix delta_m1[`j',`=4*(`p'-1)+`t'']=`delta`t'_`j'_`p'g0m1' + matrix delta_m1_se[`j',`=4*(`p'-1)+`t'']=`delta`t'_`j'_`p'g0m1_se' + } + if `t' == 2 { + matrix delta_m1[`j',`=4*(`p'-1)+1+`t'']=`delta`t'_`j'_`p'g0m1' + matrix delta_m1_se[`j',`=4*(`p'-1)+1+`t'']=`delta`t'_`j'_`p'g0m1_se' + } + } + } + } +} + +if "`group'" != "" { + matrix var_m1 = (val_m1[1,"/var(THETA1)#0bn.`gp'"],val_m1[1,"/var(THETA2)#0bn.`gp'"]\val_m1[2,"/var(THETA1)#0bn.`gp'"],val_m1[2,"/var(THETA2)#0bn.`gp'"]) + matrix covar_m1 = (val_m1[1,"/cov(THETA1,THETA2)#0.`gp'"],val_m1[1,"/cov(THETA1,THETA2)#1.`gp'"]\val_m1[2,"/cov(THETA1,THETA2)#0.`gp'"],val_m1[2,"/cov(THETA1,THETA2)#1.`gp'"]\val_m1[4,"/cov(THETA1,THETA2)#0.`gp'"],val_m1[4,"/cov(THETA1,THETA2)#1.`gp'"]) +} +else { + matrix var_m1 = (val_m1[1,"/var(THETA1)"],val_m1[1,"/var(THETA2)"]\val_m1[2,"/var(THETA1)"],val_m1[2,"/var(THETA2)"]) + matrix covar_m1 = (val_m1[1,"/cov(THETA1,THETA2)"]\val_m1[2,"/cov(THETA1,THETA2)"]\val_m1[4,"/cov(THETA1,THETA2)"]) +} + +/*group effect*/ +if "`group'"!="" { + qui lincom [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' + local geffm1=r(estimate) + local segeffm1=r(se) + qui test [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' = 0 + local gpm1p=r(p) + local gpm1chi=r(chi2) + local gpm1df=r(df) +} + + ************************************************************* + ***********************AFFICHAGE***************************** + ************************************************************* + +// Affichage du modĂšle 1 +di +di in ye "PROCESSING STEP 1" +di + /* Affichage des estimations des difficultĂ©s */ + +if "`group'" != "" { + di _col(5) in ye "{ul:MODEL 1:} Group effect estimated, no time effect (mean of latent trait of group 0 at T2) equal to mean of group 0 at T1)," + di _col(7) in ye "all item difficulties are freely estimated across times" + di + di _col(10) in ye "Item difficulties estimates (s.e.)" + di _col(10) "{hline 85}" + di _col(30) "Time 1" _col(70) "Time 2" + di in ye _col(20) abbrev("`gp'",15) "=0" _col(38) abbrev("`gp'",15) "=1" _col(58) abbrev("`gp'",15) "=0" _col(76) abbrev("`gp'",15) "=1" + di _col(10) "{hline 85}" +} +else { + di _col(5) in ye "{ul:MODEL 1}: no time effect," + di _col(7) in ye "all item difficulties are freely estimated across times" + di + di _col(10) in ye "Item difficulties estimates (s.e.)" + di _col(10) "{hline 50}" + di _col(30) "Time 1" _col(45) "Time 2" + di _col(10) "{hline 50}" +} + +forvalues j=1/`nbitems' { + di in ye _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + if "`group'" != "" { + di in gr _col(10) "`p'" _col(20) %6.2f `delta1_`j'_`p'g0m1' " (" %4.2f `delta1_`j'_`p'g0m1_se' ")" _col(38) %6.2f `delta1_`j'_`p'g1m1' " (" %4.2f `delta1_`j'_`p'g1m1_se' ")" /// + _col(58) %6.2f `delta2_`j'_`p'g0m1' " (" %4.2f `delta2_`j'_`p'g0m1_se' ")" _col(76) %6.2f `delta2_`j'_`p'g1m1' " (" %4.2f `delta2_`j'_`p'g1m1_se' ")" + } + else { + di in gr _col(10) "`p'" _col(25) %6.2f `delta1_`j'_`p'g0m1' " (" %4.2f `delta1_`j'_`p'g0m1_se' ")" _col(42) %6.2f `delta2_`j'_`p'g0m1' " (" %4.2f `delta2_`j'_`p'g0m1_se' ")" + } + } +} +if "`group'" != "" { + di _col(10) "{hline 85}" +} +else { + di _col(10) "{hline 50}" +} + /* Affichage des estimations du trait latent du modĂšle 1 */ +di +di _col(10) in ye "Latent trait distribution estimates" +if "`group'" != "" { + di _col(10) "{hline 80}" + di _col(45) in ye "Estimate" _col(60) "Standard error" _col(77) "P-value" + di _col(10) "{hline 80}" +} +else { + di _col(10) "{hline 70}" + di _col(45) in ye "Estimate" _col(60) "Standard error" " + di _col(10) "{hline 70}" +} +di _col(10) in ye "Variance Time 1" in gr _col(44) %6.2f `=var_m1[1,1]' _col(62) %6.2f `=var_m1[2,1]' +di _col(10) in ye "Variance Time 2" in gr _col(44) %6.2f `=var_m1[1,2]' _col(62) %6.2f `=var_m1[2,2]' +di _col(10) in ye "Covariance" in gr _col(44) %6.2f `=covar_m1[1,1]' _col(62) %6.2f `=covar_m1[2,1]' +if "`group'" != "" { + di _col(10) in ye "Group effect (mean gp 1 at T1)" in gr _col(44) %6.2f `geffm1' _col(62) %6.2f `segeffm1' _col(77) %6.4f `gpm1p' +} +di _col(10) in ye "Time effect (mean gp 0 at T2)" in gr _col(44) "0 (constrained)" +if "`group'" != "" { + di _col(10) in ye "TimexGroup inter" in gr _col(44) "0 (constrained)" +} +if "`group'" != "" { + di _col(10) "{hline 80}" +} +else { + di _col(10) "{hline 70}" +} +//Affichage du modĂšle 2 +di +di in ye "PROCESSING STEP 2" +di + /* Affichage des estimations des difficultĂ©s */ + +if "`group'" != "" { + di _col(5) in ye "{ul:MODEL 2:} Group effect, time effect (mean of latent trait of group 0 at T2) free estimated, time x group interaction estimated," + di _col(7) in ye "Same item difficulties estimated across times" + di + di _col(10) in ye "Item difficulties estimates (s.e.)" + di _col(10) "{hline 85}" + di _col(30) "Time 1" _col(70) "Time 2" + di in ye _col(20) abbrev("`gp'",15) "=0" _col(38) abbrev("`gp'",15) "=1" _col(58) abbrev("`gp'",15) "=0" _col(76) abbrev("`gp'",15) "=1" + di _col(10) "{hline 85}" +} +else { + di _col(5) in ye "{ul:MODEL 2}: time effect estimated (mean of latent trait group 0 at T2) free estimated," + di _col(7) in ye "Same item difficulties estimated across times" + di + di _col(10) in ye "Item difficulties estimates (s.e.)" + di _col(10) "{hline 50}" + di _col(30) "Time 1" _col(45) "Time 2" + di _col(10) "{hline 50}" +} + +forvalues j=1/`nbitems' { + di in ye _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + if "`group'" != "" { + di in gr _col(10) "`p'" _col(20) %6.2f `delta1_`j'_`p'g0m2' " (" %4.2f `delta1_`j'_`p'g0m2_se' ")" _col(38) %6.2f `delta1_`j'_`p'g1m2' " (" %4.2f `delta1_`j'_`p'g1m2_se' ")" /// + _col(58) %6.2f `delta2_`j'_`p'g0m2' " (" %4.2f `delta2_`j'_`p'g0m2_se' ")" _col(76) %6.2f `delta2_`j'_`p'g1m2' " (" %4.2f `delta2_`j'_`p'g1m2_se' ")" + } + else { + di in gr _col(10) "`p'" _col(25) %6.2f `delta1_`j'_`p'g0m2' " (" %4.2f `delta1_`j'_`p'g0m2_se' ")" _col(42) %6.2f `delta2_`j'_`p'g0m2' " (" %4.2f `delta2_`j'_`p'g0m2_se' ")" + } + } +} +if "`group'" != "" { + di _col(10) "{hline 85}" +} +else { + di _col(10) "{hline 50}" +} + /* Affichage des estimations du trait latent du modĂšle 2 */ +di +di _col(10) in ye "Latent trait distribution estimates" +di _col(10) "{hline 80}" +di _col(45) in ye "Estimate" _col(60) "Standard error" _col(77) "P-value" +di _col(10) "{hline 80}" + +if "`group'" == "" { + local fact_k = 2 +} +else { + local fact_k = 4 +} + +di _col(10) in ye "Variance Time 1" in gr _col(44) %6.2f `=mod2[1,`=`fact_k'*`nbmoda_sum'+1']' _col(62) %6.2f =mod2[2,`=`fact_k'*`nbmoda_sum'+1'] +di _col(10) in ye "Variance Time 2" in gr _col(44) %6.2f `=mod2[1,`=`fact_k'*`nbmoda_sum'+2']' _col(62) %6.2f `=mod2[2,`=`fact_k'*`nbmoda_sum'+2']' +di _col(10) in ye "Covariance" in gr _col(44) %6.2f `=mod2[1,`=`fact_k'*`nbmoda_sum'+3']' _col(62) %6.2f `=mod2[2,`=`fact_k'*`nbmoda_sum'+3']' + +if "`group'" != "" { + + di _col(10) in ye "Group effect (mean gp 1 at T1)" in gr _col(44) %6.2f `geffm2' _col(62) %6.2f `segeffm2' _col(77) %6.4f `gpm2p' +} +di _col(10) in ye "Time effect (mean gp 0 at T2)" in gr _col(44) %6.2f `teffm2' _col(62) %6.2f `seteffm2' _col(77) %6.4f `tm2p' + +if "`group'" != "" { + di _col(10) in ye "TimexGroup inter" in gr _col(44) %6.2f `interm2' _col(62) %6.2f `seinterm2' _col(77) %6.4f `interm2p' +} +di _col(10) "{hline 80}" +di + ***************************************************** + * ModĂšle 1 vs ModĂšle 2 * + ***************************************************** +qui lrtest model2 model1 + +local rstestp=r(p) +local rstestchi=r(chi2) +local rstestdf=r(df) +di _col(10) in ye "LIKELIHOOD-RATIO TEST MODEL 1 VS MODEL 2" +di _col(10) "{hline 50}" +di _col(10) in ye "Chi-square" _col(30) "DF" _col(50) "P-value" +di _col(10) in gr %6.2f `rstestchi' _col(30) %2.0f `rstestdf' _col(50) %6.4f `rstestp' +di _col(10) "{hline 50}" +if `rstestp'<0.05{ +di _col(10) in ye "DIFFERENCE IN ITEM DIFFICULTIES ACROSS TIMES LIKELY" +} +else{ +di _col(10) in ye "NO DIFFERENCE IN ITEM DIFFICULTIES ACROSS TIMES DETECTED, NO RECALIBRATION DETECTED" +} + + ********************************* + *************MODEL 3************* + ********************************* +// Etape itĂ©rative si lrtest significatif +local nb_step3=0 + +if `rstestp' < 0.05 { /* If pvalue(LRtest)<0.05 then step 3 */ + di + di in ye "PROCESSING STEP 3" + di + /*test RC pour chaque item*/ + local boucle = 1 + local stop = 0 + //matrix list dif_rc + while `boucle' <= `=`nbitp'-1' & `stop' == 0 { /*on s'arrĂȘte quand on a libĂ©rĂ© du RC sur (tous les items-1) ou lorsqu'il n'y a plus de tests significatifs*/ + local nb_step3 = `boucle' + local pajust=0.05/`=`nbitp'+1-`boucle'' // local pajust=0.05/`=`nbitems'+1-`boucle' + if "`group'" != "" { + local pajust2 = 0.05/`nbgrp' + } + /*rĂ©initialisation de la matrice de test*/ + matrix test_rc_`boucle'=J(`nbitems',9,.) + matrix test_rcCOMM_`boucle'=J(`nbitems',3,.) + matrix test_rcU_`boucle'=J(`nbitems',6,.) + matrix colnames test_rc_`boucle'= chi_RC df_RC pvalue_RC chi_RCg0 df_RCg0 pvalue_RCg0 chi_RCg1 df_RCg1 pvalue_RCg1 + matrix colnames test_rcCOMM_`boucle'= chi_RCCOMM df_RCCOMM pvalue_RCCOMM + matrix colnames test_rcU_`boucle'= chi_RCUg0 df_RCUg0 pvalue_RCUg0 chi_RCUg1 df_RCUg1 pvalue_RCUg1 + local nbsig=0 + local minpval=1 + local itemrc=0 + di _col(10) "{hline 70}" + di _col(10) in ye "Loop `boucle'" _col(50) "Adjusted alpha : " %6.4f `pajust' + di + di in ye _col(40) "Chi-Square" _col(55) "DF" _col(60) "P-Value" + /*boucle de test*/ + forvalues j=1/`nbitems'{ + if `nbdif_`j'' >= 1 { + local model "" + local listconst "" + if dif_rc[`j',3]==. { /*si pas de RC dĂ©jĂ  dĂ©tectĂ© sur l'item j -> test item j*/ + /*on libĂšre la RC de l'item j: pas de contraintes*/ + forvalues k=1/`nbitems'{ + /* Contraintes de DIF */ + if dif_rc[`k',1]==.|dif_rc[`k',1]==0 { // contraintes si pas de DIF (1-200) + forvalues p=1/`nbdif_`k''{ + local listconst "`listconst' `=0+`maxdif'*(`k'-1)+`p''" + qui constraint list `=0+`maxdif'*(`k'-1)+`p'' + } + } + else { // PrĂ©sence de DIF + if dif_rc[`k',2]!=. & dif_rc[`k',2]!=0 { // contraintes de DIF U (201-400) + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst "`listconst' `=200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + if `k'!=`j'{ /*contraintes pour les autres items */ + if dif_rc[`k',3]==. | dif_rc[`k',3]==0 {/*pas de RC sur item k: contraintes 401-600 601-800*/ + forvalues p=1/`nbdif_`k''{ + local listconst "`listconst' `=400+`maxdif'*(`k'-1)+`p'' `=600+`maxdif'*(`k'-1)+`p''" + qui constraint list `=400+`maxdif'*(`k'-1)+`p'' `=600+`maxdif'*(`k'-1)+`p'' + } + } + else { //RC dĂ©tectĂ©e sur l'item k + if dif_rc[`k',4]==0{ /*RC commune: contraintes 801-1000*/ + forvalues p=1/`nbdif_`k''{ /***************************** j=1 ou 2 ?****/ + local listconst "`listconst' `=800+`maxdif'*(`k'-1)+`p''" + qui constraint list `=800+`maxdif'*(`k'-1)+`p'' + } + if dif_rc[`k',6]!=. & dif_rc[`k',6]!=0 { // RC commune unif. + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst "`listconst' `=1000+`maxdif'*(`k'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`k'-1)+`p'' + } + } + } + } + else { // RC diff + if dif_rc[`k',5]==. | dif_rc[`k',5]==0 { // RC gp0 (400) + forvalues p=1/`nbdif_`k''{ + local listconst "`listconst' `=400+`maxdif'*(`k'-1)+`p''" + qui constraint list `=400+`maxdif'*(`k'-1)+`p'' + } + } + if dif_rc[`k',6]!=. & dif_rc[`k',6]!=0 { // RCU gp0 (1001-1200) + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst "`listconst' `=1000+`maxdif'*(`k'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`k'-1)+`p'' + } + } + } + if dif_rc[`k',7]==. | dif_rc[`k',7]==0 { // RC gp1 (600) + forvalues p=1/`nbdif_`k''{ + local listconst "`listconst' `=600+`maxdif'*(`k'-1)+`p''" + qui constraint list `=600+`maxdif'*(`k'-1)+`p'' + } + } + if dif_rc[`k',8]!=. & dif_rc[`k',8]!=0 { // RCU gp1 (1201-1400) + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst "`listconst' `=1200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=1200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + } + } + } + qui di "`listconst'" + local model "" + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA1@`p')(`p'.``=`jj'+`nbitems'''<-THETA2@`p')" + } + } + if "`group'" == "" { // Sans l'option group + qui gsem `model', mlogit tol(0.01) iterate(100) means(THETA1@0 THETA2@m20) var(THETA1@v1 THETA2@v2) cov(THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) + + /*****************/ + /*tests RC item i*/ + /*****************/ + + /* RC ? */ + qui test [1.``j'']_cons =[1.``=`j'+`nbitems''']_cons + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']_cons =[`p'.``=`j'+`nbitems''']_cons, acc + } + } + matrix test_rc_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + + /* RCU ? */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``=`j'+`nbitems''']_cons -[1.``j'']_cons)=[2.``=`j'+`nbitems''']_cons -[2.``j'']_cons + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``=`j'+`nbitems''']_cons -[1.``j'']_cons)=[`p'.``=`j'+`nbitems''']_cons -[`p'.``j'']_cons , acc + } + matrix test_rcU_`boucle'[`j',1]=(r(chi2), r(df),r(p)) + } + } + else { // Avec l'option group + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) + + /*****************/ + /*tests RC item i*/ + /*****************/ + + /* RC ? */ + qui test [1.``j'']0bn.`gp'=[1.``=`j'+`nbitems''']0bn.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp', acc + } + } + qui test [1.``j'']1.`gp'=[1.``=`j'+`nbitems''']1.`gp', acc + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp', acc + } + } + matrix test_rc_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + /* RC COMMUNE ? */ + qui test [1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp'=[1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp', acc + } + } + matrix test_rcCOMM_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + /* RC groupe 0 ? */ + qui test [1.``j'']0bn.`gp'=[1.``=`j'+`nbitems''']0bn.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp', acc + } + } + matrix test_rc_`boucle'[`j',4]=(r(chi2),r(df),r(p)) + + /* RCU grp 0 ? */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[2.``=`j'+`nbitems''']0bn.`gp'-[2.``j'']0bn.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp', acc + } + matrix test_rcU_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + } + + /* RC groupe 1 ? */ + qui test [1.``j'']1.`gp'=[1.``=`j'+`nbitems''']1.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp', acc + } + } + matrix test_rc_`boucle'[`j',7]=(r(chi2),r(df),r(p)) + + /* RCU grp 1 ? */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[2.``=`j'+`nbitems''']1.`gp'-[2.``j'']1.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp', acc + } + matrix test_rcU_`boucle'[`j',4]=(r(chi2),r(df),r(p)) + } + } + /******* Matrice test complĂšte *********/ + di in ye _col(10) %-30s abbrev("``j'' :",22) in gr _col(40) %6.3f test_rc_`boucle'[`j',1] _col(55) test_rc_`boucle'[`j',2] _col(60) %6.4f test_rc_`boucle'[`j',3] + } + } + } + //matrix list test_rc_`boucle' + forvalues j=1/`nbitems'{ + if test_rc_`boucle'[`j',3]<`pajust'{/*si RC sur item i*/ + if test_rc_`boucle'[`j',3]<`minpval'{ + local minpval=test_rc_`boucle'[`j',3] + local itemrc=`j' + } + } + } + if `itemrc' != 0 { // itemrc = numĂ©ro de l'item avec le test le + sig. + if "`group'" == "" { // Recalibration si pas d'option groupe + local ++nbsig + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',5]=`boucle' + if `nbmoda_`itemrc'' > 2 { + di _col(15) _dup(60) "-" + di _col(15) in ye "Recalibration on ``itemrc''" + di _col(40) "Chi-square" _col(55) "DF" _col(60) "P-value" + di _col(15) in ye "Uniform RC ? " in gr _col(40) %4.2f `=test_rcU_`boucle'[`itemrc',1]' _col(55) `=test_rcU_`boucle'[`itemrc',2]' _col(60) %6.4f `=test_rcU_`boucle'[`itemrc',3]' + if test_rcU_`boucle'[`itemrc',3] >= 0.05 { //RC Uniforme sur itemRC + matrix dif_rc[`itemrc',6]=`boucle' + di + di _col(17) in ye ">>> ``itemrc'' : Uniform RC" + di _col(15) _dup(60) "-" + } + else { + matrix dif_rc[`itemrc',6]=0 + di + di _col(17) in ye ">>> ``itemrc'' : Non-uniform RC" + di _col(15) _dup(60) "-" + } + } + else { + di + di _col(17) in ye ">>> ``itemrc'' : Recalibration " + di _col(15) _dup(60) "-" + } + } + else { // Option groupe + di _col(15) _dup(60) "-" + di _col(15) in ye "Recalibration on ``itemrc''" + di + di _col(40) "Chi-Square" _col(55) "DF" _col(60) "P-value" + di _col(15) in ye "Common RC ? " in gr _col(40) %4.2f `=test_rcCOMM_`boucle'[`itemrc',1]' _col(55) `=test_rcCOMM_`boucle'[`itemrc',2]' _col(60) %6.4f `=test_rcCOMM_`boucle'[`itemrc',3]' + if test_rcCOMM_`boucle'[`itemrc',3] < 0.05 { //RC diffĂ©rentielle + di + di _col(15) in ye "RC group 0 ? " in gr _col(40) %4.2f `=test_rc_`boucle'[`itemrc',4]' _col(55) `=test_rc_`boucle'[`itemrc',5]' _col(60) %6.4f `=test_rc_`boucle'[`itemrc',6]' "{it: - with adjusted alpha = `pajust2' }" + if test_rc_`boucle'[`itemrc',6] < `pajust2' { //RC gp 0 + local ++nbsig + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',4]=`boucle' + matrix dif_rc[`itemrc',5]=`boucle' + if `nbmoda_`itemrc'' > 2 { + di _col(15) in ye "Uniform RC on gp 0 ? " in gr _col(40) %4.2f `=test_rcU_`boucle'[`itemrc',1]' _col(55) `=test_rcU_`boucle'[`itemrc',2]' _col(60) %6.4f `=test_rcU_`boucle'[`itemrc',3]' + if test_rcU_`boucle'[`itemrc',3] >= 0.05 { // RCU gp 0 + matrix dif_rc[`itemrc',6]=`boucle' + local phrase_diff = ">>> ``itemrc'' : Uniform differential RC on group 0." + } + else { + matrix dif_rc[`itemrc',6]=0 + local phrase_diff = ">>> ``itemrc'' : Non-uniform differential RC on group 0." + } + } + else { + local phrase_diff = ">>> ``itemrc'' : Differential RC on group 0." + } + } + di + di _col(15) in ye "RC group 1 ? " in gr _col(40) %4.2f `=test_rc_`boucle'[`itemrc',7]' _col(55) `=test_rc_`boucle'[`itemrc',8]' _col(60) %6.4f `=test_rc_`boucle'[`itemrc',9]' "{it: - with adjusted alpha = `pajust2' }" + if test_rc_`boucle'[`itemrc',9] < `pajust2' { //RC gp 1 + local ++nbsig + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',4]=`boucle' + matrix dif_rc[`itemrc',7]=`boucle' + if `nbmoda_`itemrc'' > 2 { + di _col(15) in ye "Uniform RC on gp 1 ? " in gr _col(40) %4.2f `=test_rcU_`boucle'[`itemrc',4]' _col(55) `=test_rcU_`boucle'[`itemrc',5]' _col(60) %6.4f `=test_rcU_`boucle'[`itemrc',6]' + if test_rcU_`boucle'[`itemrc',6] >= 0.05 { // RCU gp 1 + matrix dif_rc[`itemrc',8]=`boucle' + di + if dif_rc[`itemrc',5] != `boucle' { //RC slmt sur g1 + local phrase_diff = ">>> ``itemrc'' : Differential RC, uniform RC on group 1." + } + else { + if dif_rc[`itemrc',6] == 0 { // + RCNU g0 + local phrase_diff = ">>> ``itemrc'' : Differential RC, non-uniform RC on group 0 and uniform RC on group 1." + } + else { // + RCU G0 + local phrase_diff = ">>> ``itemrc'' : Differential RC, uniform RC on group 0 and uniform RC on group 1." + } + } + } + else { //RCNU gp 1 + matrix dif_rc[`itemrc',8]=0 + di + if dif_rc[`itemrc',5] != `boucle' { + local phrase_diff = ">>> ``itemrc'' : Differential RC, non-uniform RC on group 1." + } + else { + if dif_rc[`itemrc',6] == 0 { // + RCNU g0 + local phrase_diff = ">>> ``itemrc'' : Differential RC, non-uniform RC on group 0 and non-uniform RC on group 1." + } + else { // + RCU G0 + local phrase_diff = ">>> ``itemrc'' : Differential RC, uniform RC on group 0 and non-uniform RC on group 1." + } + } + } + } + else { + if dif_rc[`itemrc',5] != `boucle' { + local phrase_diff = ">>> ``itemrc'' : Differential RC on group 1." + } + else { + local phrase_diff = ">>> ``itemrc'' : Differential RC on group 0 and differential RC on group 1." + } + } + } + di + di _col(17) in ye "`phrase_diff'" + di _col(15) _dup(60) "-" + } + else { // RC commune -> MAJ modĂšle 3 + /*******************************************************************************************************************/ + if `nbmoda_`itemrc'' == 2 { + di + di _col(14) in ye ">>> {ul:``itemrc''}: recalibration" + di _col(20) in ye "Common " in gr "{it:(Chi-s: " %4.2f `=test_rcCOMM_`boucle'[`itemrc',1]' ", DF: `=test_rcCOMM_`boucle'[`itemrc',2]' p-val. : " %4.2f `=test_rcCOMM_`boucle'[`itemrc',3]' ")}" + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',4]=0 + matrix dif_rc[`itemrc',5]=`boucle' + matrix dif_rc[`itemrc',7]=`boucle' + local ++nbsig + } + else { + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',4]=0 + matrix dif_rc[`itemrc',5]=`boucle' + matrix dif_rc[`itemrc',7]=`boucle' + //matrix list dif_rc + local model "" + local listconst "" + forvalues j=1/`nbitems'{ + /* Contraintes de DIF */ + if dif_rc[`j',1]==.|dif_rc[`j',1]==0 { // contraintes si pas de DIF (1-200) + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { // PrĂ©sence de DIF + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { // contraintes de DIF U (201-400) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + if `j' != `itemrc'{ /*contraintes pour les autres items */ + if dif_rc[`j',3]==. | dif_rc[`j',3]==0 {/*pas de RC sur item p: contraintes 401-600 601-800*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p'' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' `=600+`maxdif'*(`j'-1)+`p'' + } + } + else { //RC dĂ©tectĂ©e sur l'item p + if dif_rc[`j',4]==0{ /*RC commune: contraintes 801-1000*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=800+`maxdif'*(`j'-1)+`p''" + qui constraint list `=800+`maxdif'*(`j'-1)+`p'' + } + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RC commune unif. + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + } + else if dif_rc[`j',4] != 0 & dif_rc[`j',4]!=0. { // RC diff + if dif_rc[`j',5]==. | dif_rc[`j',5]==0 { // RC gp0 (400) + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + } + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RCU gp0 (1001-1200) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + if dif_rc[`j',7]==. | dif_rc[`j',7]==0 { // RC gp1 (600) + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=600+`maxdif'*(`j'-1)+`p'' + } + } + if dif_rc[`j',8]!=. & dif_rc[`j',8]!=0 { // RCU gp1 (1201-1400) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=1200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + } + } + else { // Contrainte de RC commune pour l'itemrc + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=800+`maxdif'*(`itemrc'-1)+`p''" + qui constraint list `=800+`maxdif'*(`itemrc'-1)+`p'' + } + } + } + qui di "`listconst'" + local model "" + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA1@`p')(`p'.``=`jj'+`nbitems'''<-THETA2@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) + + /************************/ + /*tests RC item `itemrc'*/ + /************************/ + matrix commU_`boucle'=J(`nbitems',3,.) //Matrice des tests de RCU slmt si RC commune + matrix colnames commU_`boucle'= chi_RCU df_RCU p_RCU + + /* RCU grp 0 ? */ + if `nbmoda_`itemrc'' > 2 { + qui test 2*([1.``=`itemrc'+`nbitems''']0bn.`gp'-[1.``itemrc'']0bn.`gp')=[2.``=`itemrc'+`nbitems''']0bn.`gp'-[2.``itemrc'']0bn.`gp' + forvalues j=3/`nbdif_`itemrc''{ + qui test `j'*([1.``=`itemrc'+`nbitems''']0bn.`gp'-[1.``itemrc'']0bn.`gp')=[`j'.``=`itemrc'+`nbitems''']0bn.`gp'-[`j'.``itemrc'']0bn.`gp', acc + } + matrix commU_`boucle'[`itemrc',1]=(r(chi2),r(df),r(p)) + di _col(15) in ye "Uniform RC ?" in gr _col(40) %4.2f `=commU_`boucle'[`itemrc',1]' _col(55) `=commU_`boucle'[`itemrc',2]' _col(60) %6.4f `=commU_`boucle'[`itemrc',3]' + if commU_`boucle'[`itemrc',3] >= 0.05 { // RCU + local ++nbsig + matrix dif_rc[`itemrc',6]=`boucle' + matrix dif_rc[`itemrc',8]=`boucle' + di + //di _col(14) in ye ">>> {ul:``itemrc''}: recalibration" + //di _col(20) in ye "Common " in gr "{it:(Chi-s: " %4.2f `=test_rcCOMM_`boucle'[`itemrc',1]' ", DF: `=test_rcCOMM_`boucle'[`itemrc',2]' p-val. : " %4.2f `=test_rcCOMM_`boucle'[`itemrc',3]' ")}" + di _col(17) in ye ">>> ``itemrc'' : Uniform common RC" + di _col(15) _dup(60) "-" + } + else { + local ++nbsig + matrix dif_rc[`itemrc',6]=0 + matrix dif_rc[`itemrc',8]=0 + di + di _col(17) in ye ">>> ``itemrc'' : Non-uniform common RC" + di _col(15) _dup(60) "-" + } + } + } + } // fin de RC commune + } + } + else { + local stop = 1 + } + /*******************************************************************************************************************/ + // Fin de RC sur item i + if `nbsig'==0{ + local stop=1 + if `boucle' == 1 { + di + di _col(20) in ye "No significant tests, no recalibration detected" + di _col(10) "{hline 70}" + di + } + else { + di + di _col(20) in ye ">>> No other significant tests" + di _col(10) "{hline 70}" + di + } + } + local ++boucle + } +} + + + + ********************************* + *** BILAN *** + ********************************* + + + +if "`group'" != "" & "`nodif'" == "" { + di + di _col(2) "{hline 80}" + di in ye _col(18) "Difference in" + di in ye _col(2) "Item" _col(18) "groups at T1" _col(36) "Recalibration" _col(54) "RC " abbrev("`gp'",10) " 0" _col(72) "RC " abbrev("`gp'",10) " 1" + di _col(2) "{hline 80}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + local difft1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + if (dif_rc[`j',1] != . ) { + if (dif_rc[`j',2]!=0) { + local difft1 "Uniform" + } + else { + local difft1 "Non-uniform" + } + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + if dif_rc[`j',1] != . { + local difft1 " X " + } + } + di in ye _col(2) abbrev("``j''",15) in gr _col(18) "`difft1'" _col(36) "`RC'" _col(54) "`RCg0'" _col(72) "`RCg1'" + } + di _col(2) "{hline 80}" +} +else if "`group'" != "" & "`nodif'" != "" { + di + di _col(10) "{hline 70}" + di in ye _col(10) "Item" _col(26) "Recalibration" _col(46) "RC `gp' 0" _col(62) "RC `gp' 1" + di _col(10) "{hline 70}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + } + di in ye _col(10) "``j''" in gr _col(26) "`RC'" _col(44) "`RCg0'" _col(62) "`RCg1'" + } + di _col(10) "{hline 70}" +} +else if "`group'" == "" { + di + di _col(10) "{hline 40}" + di in ye _col(10) "Item" _col(36) "Recalibration" + di _col(10) "{hline 40}" + forvalues j=1/`nbitems' { + local RC + if dif_rc[`j',3] != . { + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RC "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RC "Non-uniform" + } + } + else { + local RC " X " + } + } + di in ye _col(10) "``j''" in gr _col(38) "`RC'" + } + di _col(10) "{hline 40}" +} + + + ********************************* + ** MODEL 4 ** + ********************************* +di +di in ye "PROCESSING STEP 4" +di +//matrix list dif_rc, title ("Constraints") + +local model "" +local listconst "" +forvalues j=1/`nbitems'{ + if dif_rc[`j',1]==.|dif_rc[`j',1]==0 { /*si pas de DIF: contraintes 1-200 */ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { // PrĂ©sence de DIF + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { // contraintes de DIF U (201-400) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + if dif_rc[`j',3]==. | dif_rc[`j',3]==0 {/*pas de RC : contraintes 401-600 601-800*/ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p'' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' `=600+`maxdif'*(`j'-1)+`p'' + } + } + else { //RC dĂ©tectĂ©e sur l'item j + if dif_rc[`j',4]==0{ /*RC commune: contraintes 801-1000*/ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=800+`maxdif'*(`j'-1)+`p''" + qui constraint list `=800+`maxdif'*(`j'-1)+`p'' + } + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RC commune unif. + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + } + else { // RC diff + if dif_rc[`j',5]==. | dif_rc[`j',5]==0 { // RC gp0 (400) + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + } + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RCU gp0 (1001-1200) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + if dif_rc[`j',7]==. | dif_rc[`j',7]==0 { // RC gp1 (600) + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=600+`maxdif'*(`j'-1)+`p'' + } + } + if dif_rc[`j',8]!=. & dif_rc[`j',8]!=0 { // RCU gp1 (1201-1400) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=1200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + } +} + +qui di "`listconst'" +local model "" + +forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA1@`p')(`p'.``=`jj'+`nbitems'''<-THETA2@`p')" + } +} + +if "`group'" != "" { + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) +} +else { + qui gsem `model', mlogit tol(0.01) iterate(100) means( THETA1@0 THETA2@m2) var(THETA1@v1 THETA2@v2) cov(THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) +} + /* Stockage des estimations du modĂšle */ +matrix val_m4 = r(table) +matrix esti_4 = e(b) + +if "`group'" != "" { + matrix var_m4 = (val_m4[1,"/var(THETA1)#0bn.`gp'"],val_m4[1,"/var(THETA2)#0bn.`gp'"]\val_m4[2,"/var(THETA1)#0bn.`gp'"],val_m4[2,"/var(THETA2)#0bn.`gp'"]) + matrix covar_m4 = (val_m4[1,"/cov(THETA1,THETA2)#0.`gp'"],val_m4[1,"/cov(THETA1,THETA2)#1.`gp'"]\val_m4[2,"/cov(THETA1,THETA2)#0.`gp'"],val_m4[2,"/cov(THETA1,THETA2)#1.`gp'"]\val_m4[4,"/cov(THETA1,THETA2)#0.`gp'"],val_m4[4,"/cov(THETA1,THETA2)#1.`gp'"]) +} +else { + matrix var_m4 = (val_m4[1,"/var(THETA1)"],val_m4[1,"/var(THETA2)"]\val_m4[2,"/var(THETA1)"],val_m4[2,"/var(THETA2)"]) + matrix covar_m4 = (val_m4[1,"/cov(THETA1,THETA2)"]\val_m4[2,"/cov(THETA1,THETA2)"]\val_m4[4,"/cov(THETA1,THETA2)"]) +} + +/* Matrice des tests effet grp, tps et inter */ +matrix effet = J(5,3,.) +matrix colnames effet= Groupe Temps Interaction +matrix rownames effet = Esti Std_Err Pvalue Chi DF + +/*group effect*/ +if "`group'" != "" { + qui lincom [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' + matrix effet[1,1] =r(estimate) + matrix effet[2,1]=r(se) + qui test [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' = 0 + matrix effet[3,1]=r(p) + matrix effet[4,1]=r(chi2) + matrix effet[5,1]=r(df) +} + +/*time effect*/ +if "`group'" != "" { + qui lincom [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp' + matrix effet[1,2]=r(estimate) + matrix effet[2,2]=r(se) + qui test [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp' = 0 + matrix effet[3,2]=r(p) + matrix effet[4,2]=r(chi2) + matrix effet[5,2]=r(df) +} +else { + qui lincom [/]:mean(THETA2) /* -[/]:mean(THETA1)*/ + local teffm4=r(estimate) + local seteffm4=r(se) + local ubteffm4 = r(ub) + local lbteffm4 = r(lb) + qui test [/]:mean(THETA2) /* -[/]:mean(THETA1) */ = 0 + local tm4p=r(p) + local tm4chi=r(chi2) + local tm4df=r(df) +} + +*INTERACTION +if "`group'" != "" { + qui lincom [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#1.`gp'+[/]:mean(THETA1)#0bn.`gp' + matrix effet[1,3]=r(estimate) + matrix effet[2,3]=r(se) + local ubinterm4=r(ub) + local lbinterm4=r(lb) + qui test [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#1.`gp'+[/]:mean(THETA1)#0bn.`gp' = 0 + matrix effet[3,3]=r(p) + matrix effet[4,3]=r(chi2) + matrix effet[5,3]=r(df) +} + +if "`group'" != "" { + local effet_tps = 0 + local effet_grp = 0 + + if effet[3,3] >= 0.05 { // Si option group, on s'interesse Ă  l'interaction temps x group, et MAJ modĂšle >>> modĂšle final = modĂšle 4 + contrainte 1999 (Interaction = 0) + /* Affichage des estimations sur le trait latent du modĂšle 4 */ + di + di _col(10) in ye "Latent trait estimates" + di _col(10) "{hline 80}" + di _col(45) in ye "Estimate" _col(60) "Standard error" _col(77) "P-value" + di _col(10) "{hline 80}" + di _col(10) in ye "Variance Time 1" in gr _col(44) %6.2f `=var_m4[1,1]' _col(62) %6.2f `=var_m4[2,1]' + di _col(10) in ye "Variance Time 2" in gr _col(44) %6.2f `=var_m4[1,2]' _col(62) %6.2f `=var_m4[2,2]' + di _col(10) in ye "Covariance" in gr _col(44) %6.2f `=covar_m4[1,1]' _col(62) %6.2f `=covar_m4[2,1]' + if "`group'" != "" { + di _col(10) in ye "Group effect (mean gp 1 at T1)" in gr _col(44) %6.2f effet[1,1] _col(62) %6.2f effet[2,1] _col(77) %6.4f effet[3,1] + } + di _col(10) in ye "Time effect (mean gp 0 at T2)" in gr _col(44) %6.2f effet[1,2] _col(62) %6.2f effet[2,2] _col(77) %6.4f effet[3,2] + + if "`group'" != "" { + di _col(10) in ye "TimexGroup inter" in gr _col(44) %6.2f effet[1,3] _col(62) %6.2f effet[2,3] _col(77) %6.4f effet[3,3] + } + di _col(10) "{hline 80}" + di + di in ye ">>> Time x group interaction : no significant test, estimate of model 4 with constraint of time x group interaction at 0 " + di + local yn_inter = 0 + local listconst "`listconst' 1999" + qui di "`listconst'" + local model "" + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA1@`p')(`p'.``=`jj'+`nbitems'''<-THETA2@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_4, skip) + + matrix val_m4 = r(table) + } + else { + local yn_inter = 1 + } + + /*group effect*/ + qui lincom [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' + local geffm4=r(estimate) + local segeffm4=r(se) + local ubgeffm4=r(ub) + local lbgeffm4=r(lb) + qui test [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp'=0 + local gpm4p=r(p) + local gpm4chi=r(chi2) + local gpm4df=r(df) + + /*time effect*/ + qui lincom [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp' + local teffm4=r(estimate) + local seteffm4=r(se) + local lbteffm4=r(lb) + local ubteffm4=r(ub) + qui test [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp'=0 + local tm4p=r(p) + local tm4chi=r(chi2) + local tm4df=r(df) +} + + /* Calcul des difficultĂ©s (delta_j) */ +if "`group'" != "" { + matrix mod4 = J(7,`=`nbmoda_sum'*4+6',.) + local name_partTwoC "" + forvalues j = 1/`nbitems' { + forvalues p=1/`nbdif_`j'' { + forvalues t=1/2 { + forvalues g = 0/1 { + local name_partTwoC "`name_partTwoC' d_j`j'_p`p'_gp`g'_t`t'" + } + } + } + } + local name_partTwoC "`name_partTwoC' VAR(THETA1) VAR(THETA2) COV(TH1,TH2) GROUP_Effect TIME_Effect INTER_TxG " + matrix colnames mod4 = `name_partTwoC' + matrix rownames mod4 = Estimate se Upper_b Lower_b Chi_square DF pvalue +} +else { + matrix mod4 = J(7,`=`nbmoda_sum'*2+4',.) + local name_partTwoC "" + forvalues j = 1/`nbitems' { + forvalues p=1/`nbdif_`j'' { + forvalues t=1/2 { + local name_partTwoC "`name_partTwoC' d_j`j'_p`p'_t`t'" + } + } + } + local name_partTwoC "`name_partTwoC' VAR(THETA1) VAR(THETA2) COV(TH1,TH2) TIME_Effect " + matrix colnames mod4 = `name_partTwoC' + matrix rownames mod4 = Estimate se Upper_b Lower_b Chi_square DF pvalue +} + +*DifficultĂ©s +forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues t=1/2{ + if "`group'" != "" { // groupe binaire + forvalues g=0/1 { + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm4= r(estimate) + local delta`t'_`j'_`p'g`g'm4_se= r(se) + local delta`t'_`j'_`p'g`g'm4_ub=r(ub) + local delta`t'_`j'_`p'g`g'm4_lb=r(lb) + local delta`t'_`j'_`p'g`g'm4_p=r(p) + if `p'>1 { + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' - [`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm4=r(estimate) + local delta`t'_`j'_`p'g`g'm4_se=r(se) + local delta`t'_`j'_`p'g`g'm4_ub=r(ub) + local delta`t'_`j'_`p'g`g'm4_lb=r(lb) + local delta`t'_`j'_`p'g`g'm4_p=r(p) + } + local place = 0 + local compt = 1 + while `compt' < `j' { + local place = `place' + `nbdif_`compt'' + local ++compt + } + if `t' == 1 { + matrix mod4[1,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4' + matrix mod4[2,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4_se' + matrix mod4[3,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4_ub' + matrix mod4[4,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4_lb' + matrix mod4[7,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4_p' + } + if `t' == 2 { + matrix mod4[1,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4' + matrix mod4[2,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4_se' + matrix mod4[3,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4_ub' + matrix mod4[4,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4_lb' + matrix mod4[7,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4_p' + } + } + } + else { // groupe unique (=gp0) + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']_cons + local delta`t'_`j'_`p'g0m4= r(estimate) + local delta`t'_`j'_`p'g0m4_se= r(se) + local delta`t'_`j'_`p'g0m4_ub=r(ub) + local delta`t'_`j'_`p'g0m4_lb=r(lb) + local delta`t'_`j'_`p'g0m4_p=r(p) + if `p'>1{ + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']_cons - [`p'.``=(`t'-1)*`nbitems'+`j''']_cons + local delta`t'_`j'_`p'g0m4=r(estimate) + local delta`t'_`j'_`p'g0m4_se=r(se) + local delta`t'_`j'_`p'g0m4_ub=r(ub) + local delta`t'_`j'_`p'g0m4_lb=r(lb) + local delta`t'_`j'_`p'g0m4_p=r(p) + } + local place = 0 + local compt = 1 + while `compt' < `j' { + local place = `place' + `nbdif_`compt'' + local ++compt + } + if `t' == 1 { + matrix mod4[1,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4' + matrix mod4[2,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_se' + matrix mod4[3,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_ub' + matrix mod4[4,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_lb' + matrix mod4[7,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_p' + } + if `t' == 2 { + matrix mod4[1,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4' + matrix mod4[2,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_se' + matrix mod4[3,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_ub' + matrix mod4[4,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_lb' + matrix mod4[7,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_p' + } + } + } + } +} + +if "`group'" != "" { + matrix mod4[1,`=4*`nbmoda_sum'+1'] = (val_m4[1,"/var(THETA1)#0bn.`gp'"], val_m4[1,"/var(THETA2)#0bn.`gp'"]) + matrix mod4[2,`=4*`nbmoda_sum'+1'] = (val_m4[2,"/var(THETA1)#0bn.`gp'"],val_m4[2,"/var(THETA2)#0bn.`gp'"]) + matrix mod4[3,`=4*`nbmoda_sum'+1'] = (val_m4[6,"/var(THETA1)#0bn.`gp'"],val_m4[6,"/var(THETA2)#0bn.`gp'"]) + matrix mod4[4,`=4*`nbmoda_sum'+1'] = (val_m4[5,"/var(THETA1)#0bn.`gp'"],val_m4[5,"/var(THETA2)#0bn.`gp'"]) + + matrix mod4[1,`=4*`nbmoda_sum'+2+1'] = (val_m4[1,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod4[2,`=4*`nbmoda_sum'+2+1'] = (val_m4[2,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod4[3,`=4*`nbmoda_sum'+2+1'] = (val_m4[6,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod4[4,`=4*`nbmoda_sum'+2+1'] = (val_m4[5,"/cov(THETA1,THETA2)#0.`gp'"]) + + matrix mod4[1,`=4*`nbmoda_sum'+2+1+1'] = `geffm4' + matrix mod4[2,`=4*`nbmoda_sum'+2+1+1'] = `segeffm4' + matrix mod4[3,`=4*`nbmoda_sum'+2+1+1'] = `ubgeffm4' + matrix mod4[4,`=4*`nbmoda_sum'+2+1+1'] = `lbgeffm4' + matrix mod4[5,`=4*`nbmoda_sum'+2+1+1'] = `gpm4chi' + matrix mod4[6,`=4*`nbmoda_sum'+2+1+1'] = `gpm4df' + matrix mod4[7,`=4*`nbmoda_sum'+2+1+1'] = `gpm4p' + + + matrix mod4[1,`=4*`nbmoda_sum'+2+1+1+1'] = `teffm4' + matrix mod4[2,`=4*`nbmoda_sum'+2+1+1+1'] = `seteffm4' + matrix mod4[3,`=4*`nbmoda_sum'+2+1+1+1'] = `ubteffm4' + matrix mod4[4,`=4*`nbmoda_sum'+2+1+1+1'] = `lbteffm4' + matrix mod4[5,`=4*`nbmoda_sum'+2+1+1+1'] = `tm4chi' + matrix mod4[6,`=4*`nbmoda_sum'+2+1+1+1'] = `tm4df' + matrix mod4[7,`=4*`nbmoda_sum'+2+1+1+1'] = `tm4p' + + if `yn_inter' == 1 { //Slmt si model avec interaction + matrix mod4[1,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[1,3] + matrix mod4[2,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[2,3] + matrix mod4[3,`=4*`nbmoda_sum'+2+1+1+1+1'] = `ubinterm4' + matrix mod4[4,`=4*`nbmoda_sum'+2+1+1+1+1'] = `lbinterm4' + matrix mod4[5,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[4,3] + matrix mod4[6,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[5,3] + matrix mod4[7,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[3,3] + } + +} +else { + matrix mod4[1,`=2*`nbmoda_sum'+1'] = (val_m4[1,"/var(THETA1)"],val_m4[1,"/var(THETA2)"]) + matrix mod4[2,`=2*`nbmoda_sum'+1'] = (val_m4[2,"/var(THETA1)"],val_m4[2,"/var(THETA2)"]) + matrix mod4[3,`=2*`nbmoda_sum'+1'] = (val_m4[6,"/var(THETA1)"],val_m4[6,"/var(THETA2)"]) + matrix mod4[4,`=2*`nbmoda_sum'+1'] = (val_m4[5,"/var(THETA1)"],val_m4[5,"/var(THETA2)"]) + + matrix mod4[1,`=2*`nbmoda_sum'+2+1'] = (val_m4[1,"/cov(THETA1,THETA2)"]) + matrix mod4[2,`=2*`nbmoda_sum'+2+1'] = (val_m4[2,"/cov(THETA1,THETA2)"]) + matrix mod4[3,`=2*`nbmoda_sum'+2+1'] = (val_m4[6,"/cov(THETA1,THETA2)"]) + matrix mod4[4,`=2*`nbmoda_sum'+2+1'] = (val_m4[5,"/cov(THETA1,THETA2)"]) + + matrix mod4[1,`=2*`nbmoda_sum'+2+1+1'] = `teffm4' + matrix mod4[2,`=2*`nbmoda_sum'+2+1+1'] = `seteffm4' + matrix mod4[3,`=2*`nbmoda_sum'+2+1+1'] = `ubteffm4' + matrix mod4[4,`=2*`nbmoda_sum'+2+1+1'] = `lbteffm4' + matrix mod4[5,`=2*`nbmoda_sum'+2+1+1'] = `tm4chi' + matrix mod4[6,`=2*`nbmoda_sum'+2+1+1'] = `tm4df' + matrix mod4[7,`=2*`nbmoda_sum'+2+1+1'] = `tm4p' +} + + + /* Affichage des estimations des difficultĂ©s */ +di _col(5) in ye "{ul:MODEL 4} = Final model" +di +di _col(10) in ye "Item difficulties estimates (s.e.)" +if "`group'" != "" { + di _col(10) "{hline 85}" + di _col(30) "Time 1" _col(70) "Time 2" + di in ye _col(20) abbrev("`gp'",15) "=0" _col(38) abbrev("`gp'",15) "=1" _col(58) abbrev("`gp'",15) "=0" _col(76) abbrev("`gp'",15) "=1" + di _col(10) "{hline 85}" +} +else { + di _col(10) "{hline 50}" + di _col(30) "Time 1" _col(45) "Time 2" + di _col(10) "{hline 50}" +} + +forvalues j=1/`nbitems' { + di in ye _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + if "`group'" != "" { + di in gr _col(10) "`p'" _col(20) %6.2f `delta1_`j'_`p'g0m4' " (" %4.2f `delta1_`j'_`p'g0m4_se' ")" _col(38) %6.2f `delta1_`j'_`p'g1m4' " (" %4.2f `delta1_`j'_`p'g1m4_se' ")" /// + _col(58) %6.2f `delta2_`j'_`p'g0m4' " (" %4.2f `delta2_`j'_`p'g0m4_se' ")" _col(76) %6.2f `delta2_`j'_`p'g1m4' " (" %4.2f `delta2_`j'_`p'g1m4_se' ")" + } + else { + di in gr _col(10) "`p'" _col(25) %6.2f `delta1_`j'_`p'g0m4' " (" %4.2f `delta1_`j'_`p'g0m4_se' ")" _col(42) %6.2f `delta2_`j'_`p'g0m4' " (" %4.2f `delta2_`j'_`p'g0m4_se' ")" + } + } +} + +if "`group'" != "" { + di _col(10) "{hline 85}" +} +else { + di _col(10) "{hline 50}" +} + + /* Affichage des estimations sur le trait latent du modĂšle final */ +di +di _col(10) in ye "Latent trait distribution estimates" +di _col(10) "{hline 80}" +di _col(45) in ye "Estimate" _col(60) "Standard error" _col(77) "P-value" +di _col(10) "{hline 80}" + +if "`group'" == "" { + local fact_k = 2 +} +else { + local fact_k = 4 +} + +di _col(10) in ye "Variance Time 1" in gr _col(44) %6.2f `=mod4[1,`=`fact_k'*`nbmoda_sum'+1']' _col(62) %6.2f =mod4[2,`=`fact_k'*`nbmoda_sum'+1'] +di _col(10) in ye "Variance Time 2" in gr _col(44) %6.2f `=mod4[1,`=`fact_k'*`nbmoda_sum'+2']' _col(62) %6.2f `=mod4[2,`=`fact_k'*`nbmoda_sum'+2']' +di _col(10) in ye "Covariance" in gr _col(44) %6.2f `=mod4[1,`=`fact_k'*`nbmoda_sum'+3']' _col(62) %6.2f `=mod4[2,`=`fact_k'*`nbmoda_sum'+3']' + +if "`group'" != "" { + + di _col(10) in ye "Group effect (mean gp 1 at T1)" in gr _col(44) %6.2f `geffm4' _col(62) %6.2f `segeffm4' _col(77) %6.4f `gpm4p' +} +di _col(10) in ye "Time effect (mean gp 0 at T2)" in gr _col(44) %6.2f `teffm4' _col(62) %6.2f `seteffm4' _col(77) %6.4f `tm4p' + +if "`group'" != "" { + if effet[3,3] < 0.05 { + di _col(10) in ye "TimexGroup inter" in gr _col(44) %6.2f effet[1,3] _col(62) %6.2f effet[2,3] _col(77) %6.4f effet[3,3] + } + else { + di _col(10) in ye "TimexGroup inter" in gr _col(44) "0 (constrained)" + } +} + +di _col(10) "{hline 80}" + +/***************************************/ +/* Calcul des valeurs de DIF et de RC */ +/*************************************/ + +forvalues j=1/`nbitems' { + if `nbmoda_`j'' >= 2 { + matrix valeur_difrc_`j' = J(`nbdif_`j'',8,.) + matrix colnames valeur_difrc_`j' = DIFT1 DIFT1_SE RC_GP0 RC_GP0_SE RC_GP1 RC_GP1_SE + } +} + +forvalues j=1/`nbitems'{ + if `nbmoda_`j'' >= 2 { + if "`group'" != "" { + *DIF + if "`nodif'"=="" { + if (dif_rc[`j',1] != . ) { + forvalues p=1/`nbdif_`j'' { + if `p' == 1 { + qui lincom -[1.``j'']:1.`gp'+[1.``j'']:0.`gp' + matrix valeur_difrc_`j'[`p',1] = r(estimate) + matrix valeur_difrc_`j'[`p',2] = round(r(se),0.01) + } + if `p' > 1 { + qui lincom [`=`p'-1'.``j'']:1.`gp' - [`p'.``j'']:1.`gp' -[`=`p'-1'.``j'']:0.`gp' + [`p'.``j'']:0.`gp' + matrix valeur_difrc_`j'[`p',1] = r(estimate) + matrix valeur_difrc_`j'[`p',2] = round(r(se),0.01) + } + } + } + } + *RC GROUP 0 + if (dif_rc[`j',3] != . & dif_rc[`j',5] != . ) { + forvalues p=1/`nbdif_`j'' { + qui lincom -[1.``=`j'+`nbitems''']:0.`gp' + [1.``j'']:0.`gp' + matrix valeur_difrc_`j'[`p',3] = r(estimate) + matrix valeur_difrc_`j'[`p',4] = round(r(se),0.01) + if `p' > 1 { + qui lincom [`=`p'-1'.``=`j'+`nbitems''']:0.`gp' - [`p'.``=`j'+`nbitems''']:0.`gp' -[`=`p'-1'.``j'']:0.`gp' + [`p'.``j'']:0.`gp' + matrix valeur_difrc_`j'[`p',3] = r(estimate) + matrix valeur_difrc_`j'[`p',4] = round(r(se),0.01) + } + } + } + *RC GROUP 1 + if (dif_rc[`j',3] != . & dif_rc[`j',7] != . ) { + forvalues p=1/`nbdif_`j'' { + qui lincom -[1.``=`j'+`nbitems''']:1.`gp' + [1.``j'']:1.`gp' + matrix valeur_difrc_`j'[`p',5] = r(estimate) + matrix valeur_difrc_`j'[`p',6] = round(r(se),0.01) + if `p' > 1 { + qui lincom [`=`p'-1'.``=`j'+`nbitems''']:1.`gp' - [`p'.``=`j'+`nbitems''']:1.`gp' -[`=`p'-1'.``j'']:1.`gp' + [`p'.``j'']:1.`gp' + matrix valeur_difrc_`j'[`p',5] = r(estimate) + matrix valeur_difrc_`j'[`p',6] = round(r(se),0.01) + } + } + } + } + else { + forvalues p=1/`nbdif_`j'' { + qui lincom -[1.``=`j'+`nbitems''']_cons + [1.``j'']_cons + matrix valeur_difrc_`j'[`p',3] = r(estimate) + matrix valeur_difrc_`j'[`p',4] = round(r(se),0.01) + if `p' > 1 { + qui lincom [`=`p'-1'.``=`j'+`nbitems''']_cons - [`p'.``=`j'+`nbitems''']_cons -[`=`p'-1'.``j'']_cons + [`p'.``j'']_cons + matrix valeur_difrc_`j'[`p',3] = r(estimate) + matrix valeur_difrc_`j'[`p',4] = round(r(se),0.01) + } + } + } + } +} + +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' >= 2 { + forvalues p = 1/`nbdif_`j'' { + forvalues k = 1/8 { + if valeur_difrc_`j'[`p',`k'] == . { + matrix valeur_difrc_`j'[`p',`k'] = 0 + } + } + } + } +} + + /* Affichage des estimations des valeurs de DIF et de RC */ +di +di _col(10) in ye "Values of differences between groups and values of recalibration" +if "`group'" != "" & "`nodif'"==""{ + di _col(10) "{hline 70}" + di _col(30) "Difference of" _col(52) "RECALIBRATION" + di _col(30) "groups at T1" _col(47) in ye abbrev("`gp'",15) "=0" _col(62) abbrev("`gp'",15) " =1" + di _col(10) "{hline 70}" +} +else if "`group'" != "" & "`nodif'"!="" { + di _col(10) "{hline 50}" + di _col(32) "RECALIBRATION" + di in ye _col(27) "`gp'=`=rep[1,1]'" _col(47) "`gp'=`=rep[2,1]'" + di _col(10) "{hline 50}" +} +else { + di _col(10) "{hline 30}" + di _col(15) "RECALIBRATION" + di _col(10) "{hline 30}" +} + +forvalues j=1/`nbitems' { + if `nbmoda_`j'' >= 2 { + if "`group'" != "" & "`nodif'" == "" { + di in ye _col(10) "``j''" + } + else { + di in ye _col(10) "``j''" + } + forvalues p=1/`nbdif_`j'' { + if "`group'" != "" & "`nodif'"=="" { + di in gr _col(10) "`p'" _col(29) %6.2f `=valeur_difrc_`j'[`p',1]' " (" %4.2f `=valeur_difrc_`j'[`p',2]' ")" /// + _col(47) %6.2f `=valeur_difrc_`j'[`p',3]' " (" %4.2f `=valeur_difrc_`j'[`p',4]' ")" _col(62) %6.2f `=valeur_difrc_`j'[`p',5]' " (" %4.2f `=valeur_difrc_`j'[`p',6]' ")" + } + else if "`group'" != "" & "`nodif'"!="" { + di in gr _col(10) "`p'" _col(25) %6.2f `=valeur_difrc_`j'[`p',3]' " (" %4.2f `=valeur_difrc_`j'[`p',4]' ")" _col(45) %6.2f `=valeur_difrc_`j'[`p',5]' " (" %4.2f `=valeur_difrc_`j'[`p',6]' ")" + } + else { + di in gr _col(10) "`p'" _col(25) %6.2f `=valeur_difrc_`j'[`p',3]' " (" %4.2f `=valeur_difrc_`j'[`p',4]' ")" + } + } + } +} + +if "`group'" != "" & "`nodif'"=="" { + di _col(10) "{hline 70}" +} +else if "`group'" != "" & "`nodif'"!=""{ + di _col(10) "{hline 50}" +} +else { + di _col(10) "{hline 30}" +} +di + + ***************************************************** + ** OUTPUTS POUR SIMULATIONS ** + ***************************************************** + +/* +forvalues j= `nbitems' (-1) 1 { + if `nbmoda_`j'' >= 2 { + return matrix val_difrc_item`j'=valeur_difrc_`j' + } +} + +* ModĂšle 4 +return matrix table_m4 = val_m4 +return matrix covariance_m4 = covar_m4 +return matrix variance_m4 = var_m4 +return matrix se_diff_m4 = delta_m4_se +return matrix difficultiesm4 = delta_m4 + +if "`group'" != "" { + return scalar with_inter=`yn_inter' + *Inter + return scalar interm4df=effet[5,3] + return scalar interm4chi=effet[4,3] + return scalar interm4p=effet[3,3] + return scalar interm4se=effet[2,3] + return scalar interm4=effet[1,3] + + *Retour paramĂštres thĂ©ta modĂšle 4 + if effet[3,3] < 0.05 { // Si modĂšle avec inter + return scalar teffm4df=effet[5,2] + return scalar teffm4chi=effet[4,2] + return scalar teffm4p=effet[3,2] + return scalar teffm4se=effet[2,2] + return scalar teffm4= effet[1,2] + * Effet groupe + return scalar gpeffm4df=effet[5,1] + return scalar gpeffm4chi=effet[4,1] + return scalar gpeffm4p=effet[3,1] + return scalar gpeffm4se=effet[2,1] + return scalar gpeffm4=effet[1,1] + } + if effet[3,3] >= 0.05 { + * Effet temps + return scalar teffm4df=`tm4df' + return scalar teffm4chi=`tm4chi' + return scalar teffm4p=`tm4p' + return scalar teffm4se=`seteffm4' + return scalar teffm4=`teffm4' + * Effet groupe + return scalar gpeffm4df=`gpm4df' + return scalar gpeffm4chi=`gpm4chi' + return scalar gpeffm4p=`gpm4p' + return scalar gpeffm4se=`segeffm4' + return scalar gpeffm4=`geffm4' + } +} +else { + if effet[3,3] < 0.05 { // Si modĂšle avec inter + return scalar teffm4df=effet[5,2] + return scalar teffm4chi=effet[4,2] + return scalar teffm4p=effet[3,2] + return scalar teffm4se=effet[2,2] + return scalar teffm4= effet[1,2] + } + if effet[3,3] >= 0.05 { + * Effet temps + return scalar teffm4df=`tm4df' + return scalar teffm4chi=`tm4chi' + return scalar teffm4p=`tm4p' + return scalar teffm4se=`seteffm4' + return scalar teffm4=`teffm4' + } +} + +* Boucle de RC +if `nb_step3' != 0 { + forvalues item = 1/`nbitems' { + forvalues s =1/`=`nb_step3'-1' { + if dif_rc[`item',4] == 0 & dif_rc[`item',3]==`s' & `nbmoda_`item'' > 2 { + return matrix commU_bcle`s'=commU_`s' + } + } + } +} + +if `nb_step3' != 0 { + forvalues s =1/`nb_step3' { + return matrix ptest_rc_bcle`s'=ptest_rc_`s' + return matrix chitest_rc_bcle`s'=chitest_rc_`s' + return matrix dftest_rc_bcle`s'=dftest_rc_`s' + } +} + +* ModĂšle 2 +return matrix table_m2 = val_m2 +return matrix covariance_m2 = covar_m2 +return matrix variance_m2 = var_m2 +return matrix se_diff_m2 = delta_m2_se +return matrix difficultiesm2 = delta_m2 + +* Effet temps +if "`group'" != "" { + * Interaction + return scalar interm2df=`interm2df' + return scalar interm2chi=`interm2chi' + return scalar interm2p=`interm2p' + return scalar interm2se=`seinterm2' + return scalar interm2=`interm2' +} +return scalar teffm2df=`tm2df' +return scalar teffm2chi=`tm2chi' +return scalar teffm2p=`tm2p' +return scalar teffm2se=`seteffm2' +return scalar teffm2=`teffm2' + +if "`group'" != "" { // SI option group + * Effet groupe + return scalar gpeffm2df=`gpm2df' + return scalar gpeffm2chi=`gpm2chi' + return scalar gpeffm2p=`gpm2p' + return scalar gpeffm2se=`segeffm2' + return scalar gpeffm2=`geffm2' +} + +* ModĂšle 1 +return matrix table_m1 = val_m1 +return matrix covariance_m1 = covar_m1 +return matrix variance_m1 = var_m1 +return matrix se_diff_m1 = delta_m1_se +return matrix difficultiesm1 = delta_m1 + +if "`group'" != "" { // Si option group + * Effet groupe + return scalar gpeffm1df=`gpm1df' + return scalar gpeffm1chi=`gpm1chi' + return scalar gpeffm1p=`gpm1p' + return scalar gpeffm1se=`segeffm1' + return scalar gpeffm1=`geffm1' +} + +* ModĂšle C +if "`group'" != "" & "`nodif'"=="" { + if `nb_stepC' != 0 { + forvalues s =1/`nb_stepC' { + return matrix ptest_dif_bcle`s'=ptest_dif_`s' + return matrix chitest_dif_bcle`s'=chitest_dif_`s' + return matrix dftest_dif_bcle`s'=dftest_dif_`s' + } + + if `nb_stepC' != 1 { + * Effet groupe + return scalar gpeffmCdf=`gcmCFindf' + return scalar gpeffmCchi=`gcmCFinchi' + return scalar gpeffmCp=`gcmCFinp' + return scalar gpeffmCse=`segeffmCFin' + return scalar gpeffmC=`geffmCFin' + *Retour modĂšle C Final + return matrix table_mC = val_mC + return matrix variance_mC = var_mC + return matrix se_diff_mC = delta_mCFin_se + return matrix difficultiesmC = delta_mCFin + } + } + + * ModĂšle B + return matrix table_mB = val_mB + return matrix variance_mB = var_mB + return matrix se_diff_mB = delta_mB_se + return matrix difficultiesmB = delta_mB + + * Effet groupe + return scalar gpeffmBdf=`gcmBdf' + return scalar gpeffmBchi=`gcmBchi' + return scalar gpeffmBp=`gcmBp' + return scalar gpeffmBse=`segeffmB' + return scalar gpeffmB=`geffmB' + + *ModĂšle A + return matrix table_mA = val_mA + return matrix variance_mA = var_mA + return matrix se_diff_mA = delta_mA_se + return matrix difficultiesmA = delta_mA + +} + +*Matrice dif_rc +return matrix rcres=dif_rc + +forvalues j = 1/`nbitems' { + local colnam = "`colnam' item`j'" +} + +return matrix modait= nbmod + +*Retour test modĂšle 1 vs modĂšle 2 +return scalar rstchi12=`rstestchi' +return scalar rstdf12=`rstestdf' +return scalar rstp12=`rstestp' + +if "`group'" != "" & "`nodif'"=="" { + *Retour test modĂšle A vs modĂšle B + return scalar diftchiAB=`diftestchi' + return scalar diftdfAB=`diftestdf' + return scalar diftpAB=`diftestp' +} + +//return scalar nb_boucle_rc=`nb_step3' + +/* +if "`group'" != "" & "`nodif'"==""{ + return scalar nb_boucle_dif=`nb_stepC' +} +*/ + +timer off 1 +qui timer list 1 +local temps = r(t1) +local minute = floor(`=`temps'/60') +local seconde = floor(`temps' - `=`minute'*60') +//di "Time : `temps's = `minute'min `seconde's" +*/ + +//return scalar time = `temps' + +******************************************************************************* +* New outputs + +if "`group'" == "" { + matrix testlrm = J(1,3,.) + matrix colnames testlrm = chi_square df pvalue + matrix rownames testlrm = m1_vs_m2 + matrix testlrm[1,1] = (`rstestchi',`rstestdf',`rstestp') + return matrix test_model = testlrm +} +else if "`nodif'" != "" { + matrix testlrm = J(1,3,.) + matrix colnames testlrm = chi_square df pvalue + matrix rownames testlrm = m1_vs_m2 + matrix testlrm[1,1] = (`rstestchi',`rstestdf',`rstestp') + return matrix test_model = testlrm +} +else { + matrix testlrm = J(2,3,.) + matrix colnames testlrm = chi_square df pvalue + matrix rownames testlrm = mA_vs_mB m1_vs_m2 + matrix testlrm[1,1] = (`diftestchi',`diftestdf',`diftestp') + matrix testlrm[2,1] = (`rstestchi',`rstestdf',`rstestp') + return matrix test_model = testlrm +} + +return matrix model_4 = mod4 +return matrix model_2 = mod2 + +end + diff --git a/Modules/ado/personal/r/rosali22.sthlp b/Modules/ado/personal/r/rosali22.sthlp new file mode 100644 index 0000000..dbc1fa9 --- /dev/null +++ b/Modules/ado/personal/r/rosali22.sthlp @@ -0,0 +1,92 @@ +{smcl} +{* february2019}{...} +{hline} +help for {hi:rosali22}{right:Myriam Blanchin - Priscilla Brisson} +{hline} + +{title:Detection of Response Shift at Item-Level between 2 times} + +{p 8 14 2}{cmd:rosali22} {it:varlist} [{it:if}] [{it:in}] [, {cmdab:id}({it:string}) +{cmdab:moda}({it:# # [#]...}) {cmdab:group}({it:string}) {cmdab:nodif}] + +{p 4 4 4 140}{it:varlist} contains items' list : the first half of the items represents the items at time 1 and the second half the items at time 2. (at least 2 items). +{break}{it:Data} : wide format, one line for one patient + + {title:Description} + +{p 4 12 2 140}{cmd:rosali22}: {bf:R}esp{bf:O}nse {bf:S}hift {bf:AL}gorithm at {bf:I}tem-level (ROSALI), +detection of Response-Shift between two measuring times based on partial credit model. +Only uniform or non-uniform {bf:r}e{bf:c}alibration (RC) can be detected. +A dichotomous group covariate can affect the estimation of the true change(group effect) +and of response shift detected. +Response shift can be common to both groups or differential. +Detection of {bf:d}ifferential {bf:i}tem {bf:f}unctionning (DIF) between two groups with the option group. + +{p 4 12 2 140} {ye:PART 1: DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES BETWEEN GROUPS AT FIRST TIME OF MEASUREMENT} +{break} {it: Only with group option and without nodif option} +{break} {ye:Model A :} Full model, transversal PCM : estimates of item difficulties free between groups, estimates of latent trait with group effect constrained to 0. +{break} {ye:Model B :} Restricted model, transversal PCM : estimates of item difficulties with constraint of equality between groups, estimates of latent trait including group effect estimate. +{break} .LR test between model A and model B. If this test is significant, algorithm proceeds to step C, otherwise algorithm proceeds to part 2, with constraint of equality between groups of item difficulties. +{break} {ye:Step C :} an iterative step to detect which items have different item difficulties between groups at time 1. At each iteration, equality constraint of item difficulties between groups are relaxed one-by-one +producing multiple models C (starting with model B). For each item, difference in item difficulties between groups is tested, a Bonferroni correction is applied. Item with the most significant test is selected and tested +to determine if the difference in item difficulties is uniform or non-uniform (if number of answer categories is greater to 2). Model C is updated and step C is repeated to identify differences on the remaining items. +{break} .When there is no more item with significant test or only one remaining item to be tested, ROSALI goes on part 2. + +{p 4 12 2 140} {ye:PART 2: DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES BETWEEN TIMES (RECALIBRATION)} +{break} For each model, algorithm takes account detection of part 1. +{break} {ye:Model 1 :} Full model, longitudinal PCM : estimates of item difficulties free across times for each group, estimates of latent trait with time effect and interaction time x group constrained to 0. +{break} {ye:Model 2 :} Restricted model, longitudinal PCM : estimates of item difficulties with constraint of equality across times, estimates of latent trait including time effect and interaction time x group estimate. +{break} .LR test between model 1 and model 2. If this test is significant, algorithm proceeds to step 3, otherwise algorithm proceeds to step 4, keeping model 2. +{break} {ye:Step 3 :} an iterative step to detect which items have different item difficulties across times. At each iteration, equality constraint of item difficulties between times are relaxed one-by-one producing multiple +models 3 (starting with model 2). For each item, recalibration is tested, a Bonferroni correction is applied. Item with the most significant test is selected and tested. +{break} .If group option, item is tested to determine if the difference in item difficulties is the same for each group (common RC), in this case, model 3 is updated to take account common recalibration, or different +(differential RC), in this case, recalibration is tested for each group with a Bonferroni correction. +{break} .Type of recalibration : uniform or non-uniform, is finally tested (if number of answer categories is greater to 2). Model 3 is updated and step 3 is repeated to identify differences on the remaining items. +{break} .When there is no more item with significant test or only one remaining item to be tested, ROSALI goes on part 4. +{break} {ye:Model 4 :} Item difficulties and latent trait are estimated with a longitudinal PCM taking account difference or no between groups or times and the type uniform or non-uniform. If interaction time x group is +not significant model 4 is updated with constraint of interaction equal to 0 and we obtained final model. + +{p 4 12 2 140} {cmd:automatic coding for answers categories}: Answers at items must be respect 2 conditions. If it is necessary algorithm recodes answers automatically. You can recodes answers before. +{break} - Answers must be ordered and start with 0. If it's necesary, algorithm recodes automatically answers categories to the first answer is 0. +{break} - It's necessary that all answers categories are used at two times of measurement (for each group if option was used). +{break} .If the first answer is not used at one time (or in a group) at least: this answer is merged with next answer. +{break} .If the last answer is not used at one time (or in a group) at least: this answer is merged with the previous answer. +{break} .If an intermediate answer is not used at one time (or in one group) at least: this answer is merged with the next or previous answer of randomly way. +{break} {it: examples :} If there is 4 answers categories, answers lightly are : 0, 1, 2 or 3. +{break} - If answer 0 is not used at one time or for one group, answers 0 and 1 merged (patient who had answered 0 or 1 have now the answer 0, the answer 2 became answer 1 and answer 3 became answer 2) +{break} - If answer 3 is not used at one time or for one group, answers 2 and 3 merged (patient who had answered 2 or 3 have now the answer 2, answers 0 and 1 remain the same) +{break} - If answer 1 (resp. 2) is not used at one time or for one group, randomly answer 1 (resp. 2) merged with answer 0 (resp. 1) or with answer 2 (resp. 3). + + {p 4 12 2 140} {cmd:automatic coding for groups}: Rosali needs to have one group 0 and one group 1. If it's necessary Rosali recodes group variable. You can recodes groups before. + + {title:Options} + +{phang}{cmd:id}({it:string}) specifies the identifiant of individuals. Necessary to validate the data format. + +{phang}{cmd:moda}({it:# # [#]...}) specifies the number of answers categories for each item. + +{phang}{cmd:group}({it:string}) specifies the binary group variable, allows the detection of differential item functionning (DIF). + +{phang}{cmd:nodif} specifies to do only the part 2 of algorithm. No detection of DIF, only detection of response shift for each group. {it:Use only with group option.} + +{title:Outputs} + +{p 2}{bf:Matrix:} + +{phang}{cmd:r(test_model)}: Result of LRT between models A/B and models 1/2: chi-square, DF and p-value. + +{phang}{cmd:r(model_#)}: Item difficulties and latent trait of model 2 and 4 : Estimates, standard error, confidence interval at 95%, chi-square, DF and p-value. + +{title:Examples} + +{phang}{cmd: . rosali22 itemA1 itemA2 itemA3 itemB1 itemB2 itemB3, id(mat) } {it: // 3 items : A = time1 & B = time2 } + +{phang}{cmd: . rosali22 it1_t1-it9_t2 , id(idpat) moda(4 4 7 7 7 7 7 7 7) group(type_c) } {it: // 9 items, 4 answers for two first items and seven for others, detection by group of type_c } + +{title:Authors} + +{phang} Myriam Blanchin, Research engineer, PhD, SPHERE - UMR INSERM U1246, "methodS in Patient-centered outomes and HEalth ResEarch", University of Nantes, France {browse "mailto:myriam.blanchin@univ-nantes.fr":myriam.blanchin@univ-nantes.fr} +{phang}Priscilla Brisson, SPHERE - UMR INSERM U1246, "methodS in Patient-centered outomes and HEalth ResEarch", University of Nantes, France +{browse "mailto:priscilla.brisson@univ-nantes.fr":priscilla.brisson@univ-nantes.fr} + + diff --git a/Modules/ado/personal/r/rosali23.ado b/Modules/ado/personal/r/rosali23.ado new file mode 100644 index 0000000..0e4683f --- /dev/null +++ b/Modules/ado/personal/r/rosali23.ado @@ -0,0 +1,3104 @@ +*! version 2.3 december2019 +*! Myriam Blanchin - Priscilla Brisson +************************************************************************************************************ +* ROSALI: RespOnse-Shift ALgorithm at Item-level +* Response-shift detection based on Rasch models family +* +* Version 1 : December 21, 2016 (Myriam Blanchin) /*rspcm122016*/ +* Version 1.1 : October 13, 2017 (Myriam Blanchin) /*option: MODA, automatic recoding of unused response categories*/ +* Version 2 : April, 2018 (Myriam Blanchin - Priscilla Brisson) /*option: GROUP, dichotomous group variable*/ +* Version 2.1 : October, 2018 (Myriam Blanchin - Priscilla Brisson) /* Version 1.1 + Version 2 */ +* Version 2.2 : February, 2019 (Priscilla Brisson) /* option nodif, optimization */ +* Version 2.3 : December, 2019 (Priscilla Brisson) /* option detail, + petites corrections */ +* +* Myriam Blanchin, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* myriam.blanchin@univ-nantes.fr +* +* Priscilla Brisson, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* priscilla.brisson@univ-nantes.fr +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define rosali, rclass + +timer clear 1 +timer on 1 + +syntax varlist(min=2 numeric) [if] [,GROUP(varlist) NODIF PRO DETail] + +preserve +version 15 +tempfile saverspcm +capture qui save `saverspcm',replace +local save1=_rc + +if "`if'"!="" { + qui keep `if' +} + +if "`pro'" != "" { + di "START" +} + +/**************************************************************************/ +set more off +set matsize 5000 + +local gp "`group'" + +tokenize `varlist' +local nbitems:word count `varlist' + + /* VĂ©rif nb d'items pair */ +local mod=mod(`nbitems',2) +if `mod'!=0 { + di in red "You must enter an even number of items : the first half of the items represents the items at time 1 and the second half the items at time 2" + error 198 + exit +} + +local nbitems=`nbitems'/2 + + +if "`group'"=="" & "`nodif'"!="" { + di in red "nodif can only be used with the group option ({hi:nodif} option). Please correct this option." + error 198 + exit +} + +local nbc: word count `group' +if `nbc' >= 2 { + di in red "Only one variable can be used for group option ({hi:group} option). Please correct this option." + error 198 + exit +} + + /* VĂ©rif qu'il y a 2 groupes si l'option groupe est choisie */ +if "`group'"!="" { + qui tab `group' + local nbgrp = r(r) + if `nbgrp' != 2 { + di in red "The option group must be used with only 2 groups ({hi:group} option). Please correct this option." + error 420 + exit + } +} +/* recoder la variable de groupe en 0, 1*/ + +if "`group'"!="" { + qui tab `gp', matrow(rep) + qui matrix list rep + if rep[1,1]+rep[2,1] != 1 & rep[1,1]*rep[2,1] != 0 { + forvalues i=1/`=rowsof(rep)'{ + qui replace `gp'=`i'-1 if `gp'==rep[`i',1] + di "WARNING : `gp' `=rep[`i',1]' is now `gp' `=`i'-1' " + } + } + forvalues g = 0/1 { + qui tab `gp' if `gp' == `g' + local nbp_gp`g' = r(N) + } +} + + + +/*item rename*/ +/* +Items au temps 1 : 1 Ă  nbitems ``j'' +Items au temps 2 : nbitems Ă  2*nbitems ``=`j'+`nbitems''' + +Si t varie, puis num item : ``=(`t'-1)*`nbitems'+`j''' +*/ + + +local com_z = 0 // Indicatrice de recodage + /*verif modalitĂ©s rĂ©pondues*/ +if "`gp'" == "" { // Si pas d'option groupe + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'', matrow(rect1_`j') // RĂ©cupĂ©ration des infos moda du temps 1 + local minm`j'_t1 = rect1_`j'[1,1] + local maxm`j'_t1 = rect1_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''', matrow(rect2_`j') // RĂ©cupĂ©ration des infos moda du temps 2 + local minm`j'_t2 = rect2_`j'[1,1] + local maxm`j'_t2 = rect2_`j'[r(r),1] + + local minm_`j' = min(`minm`j'_t1',`minm`j'_t2') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1',`maxm`j'_t2') + local nbm_`j' = `=`maxm_`j''-`minm_`j''' + + if `minm_`j'' != 0 & `com_z' == 0 { + local com_z = 1 + } + + + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`nbm_`j'' { + qui count if ``j'' == `m' + local nb_rn1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' + local nb_rn2 = r(N) + local nb_rn = min(`nb_rn1',`nb_rn2') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' <= `minm`j'_t1' | `m' <= `minm`j'_t2' { // La moda 0 ou les moda min ne sont pas utilisĂ©es + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged " + local stop = 0 + } + } + } + else if `m' >= `maxm`j'_t1' | `m' >= `maxm`j'_t2' | `m' == `maxm_`j'' { // La (ou les) moda max ne sont pas utilisĂ©e(s) + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems''' =`=`m'-`k'' if ``=`j'+`nbitems''' ==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} +else { // Cas oĂč l'option groupe est utilisĂ©e + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'' if `gp' == 0, matrow(rect1_g0_`j') matcell(nbrt1_g0_`j') // RĂ©cupĂ©ration des infos moda du temps 1pour chaque groupe + local minm`j'_t1_g0 = rect1_g0_`j'[1,1] + local maxm`j'_t1_g0 = rect1_g0_`j'[r(r),1] + + qui tab ``j'' if `gp' == 1, matrow(rect1_g1_`j') matcell(nbrt1_g1_`j') + local minm`j'_t1_g1 = rect1_g1_`j'[1,1] + local maxm`j'_t1_g1 = rect1_g1_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''' if `gp' == 0, matrow(rect2_g0_`j') matcell(nbrt2_g0_`j') // RĂ©cupĂ©ration des infos moda du temps 2 pour chaque groupe + local minm`j'_t2_g0 = rect2_g0_`j'[1,1] + local maxm`j'_t2_g0 = rect2_g0_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''' if `gp' == 1 , matrow(rect2_g1_`j') matcell(nbrt2_g1_`j') + local minm`j'_t2_g1 = rect2_g0_`j'[1,1] + local maxm`j'_t2_g1 = rect2_g0_`j'[r(r),1] + + local minm_`j' = min(`minm`j'_t1_g0',`minm`j'_t2_g0',`minm`j'_t1_g1',`minm`j'_t2_g1') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1_g0',`maxm`j'_t2_g0',`maxm`j'_t1_g1',`maxm`j'_t2_g1') + local nbm_`j' = `=`maxm_`j''-`minm_`j''+1' + + if `minm_`j'' != 0 & `com_z' == 0 { + local com_z = 1 + } + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`=`nbm_`j''-1' { + qui count if ``j'' == `m' & `gp' == 0 + local nb_rn1_g0 = r(N) + qui count if ``j'' == `m' & `gp' == 1 + local nb_rn1_g1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 0 + local nb_rn2_g0 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 1 + local nb_rn2_g1 = r(N) + local nb_rn = min(`nb_rn1_g0',`nb_rn2_g0',`nb_rn1_g1',`nb_rn2_g1') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' < `minm`j'_t1_g0' | `m' < `minm`j'_t2_g0' | `m' < `minm`j'_t1_g1' | `m' < `minm`j'_t2_g1' { // La moda 0 n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + } + } + else if `m' == `=`nbm_`j''-1' | `m' >= `maxm`j'_t2_g0' | `m' >= `maxm`j'_t1_g1' | `m' >= `maxm`j'_t2_g1' { // La moda max n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`m'' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0 ) & `stop' != 0 { + qui replace ``j''= `=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { // Moda central non utilisĂ©e + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'-`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0{ + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} + +if `com_z' == 1 { + di + di "WARNING : Automatic recoding, the first response category is 0. see {help rosali22:help rosali22}." + di +} + +forvalues j =1/`nbitems' { + qui tab ``j'', matrow(rec) // RĂ©cupĂ©ration des infos moda du temps 1 + local nbm`j'_t1 = r(r) + + qui tab ``=`j'+`nbitems''' // RĂ©cupĂ©ration des infos moda du temps 2 + local nbm`j'_t2 = r(r) + + local nbm_`j' = max(`nbm`j'_t1', `nbm`j'_t2') + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`nbm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=rec[`=`r'+1',1]' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=rec[`=`r'+1',1]' + } +} + +/* Calcul de nbmoda & nbdif */ +forvalues j = 1/`nbitems' { + qui tab ``j'' + local nbmoda_`j' = r(r) + local nbdif_`j' = r(r) - 1 +} + +local maxdif = 0 +local nbmoda_sum = 0 +forvalues j = 1/`nbitems' { + if `maxdif' < `nbdif_`j'' { + local maxdif = `nbdif_`j'' + } + local nbmoda_sum = `nbmoda_sum' + `nbdif_`j'' +} + +/* Au moins 2 mmoda par item */ +forvalues j=1/`nbitems' { + if `nbmoda_`j'' == 1 { + di in red "``j'' have only one response category, each item need at least 2 response categories" + error 198 + exit + } +} + +local coln "" +forvalues j =1 /`nbitems' { + local coln "`coln' ``j''" +} + +matrix nbmod = J(2,`nbitems',.) + +matrix colnames nbmod = `coln' +matrix rownames nbmod = NbModa Recoding + +forvalues j = 1/`nbitems' { + matrix nbmod[1,`j'] = `nbmoda_`j'' + matrix nbmod[2,`j'] = `recoda_`j'' +} + +*Erreur si plus de 200 difficultĂ©s +local nb_test = 0 +forvalues j=1/`nbitems' { + local nb_test = `nb_test'+`nbmoda_`j'' -1 +} + +if `nb_test' >= 200 { + di in red "The number of items difficulties must be less than 200 ({hi:moda} option option). Please correct this option." + error 198 + exit +} + +local nbitp = 0 + +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' >= 2 { + local nbitp = `nbitp' + 1 + } +} + +qui count +local nbpat = r(N) + + +/********************************* +* AFFICHAGE INITIAL +*********************************/ +di _col(5) "{hline 78}" +di _col(5) in ye %~30s "Time 1" _col(30) %~30s "Time 2" _col(55) "Nb of Answer Cat." +di _col(5) "{hline 78}" +forvalues j=1/`nbitems' { + di in gr _col(5) %~30s abbrev("``j''",20) _col(30) %~30s abbrev("``=`j'+`nbitems'''",20) _col(75) `nbmoda_`j'' +} +di _col(5) "{hline 78}" +if "`group'" != "" { + di _col(10) "Nb. of patients : " abbrev("`gp'",20) " 0 = `nbp_gp0' ;", abbrev("`gp'",20) " 1 = `nbp_gp1'" + di _col(5) "{hline 78}" +} +else { + di _col(20) "Nb. of patients : `nbpat'" + di _col(5) "{hline 78}" +} +di +if `nbitems' == 1 { + di in red "2 items at least is necessary to detect DIF and/or RC at item level." + error 198 + exit +} +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' == 2 { + di "WARNING: ``j'' have only 2 response categories, the type uniform or non-uniform can't be detected." + } + if `nbmoda_`j'' == 1 { + di in red "``j'' uses only `nbmoda_`j'' response category, each item need at least 2 response categories used." + error 198 + exit + } + if `nbmoda_`j'' == 0 { + di in red "``j'' uses no response category, each item needs at least 2 response categories used." + error 198 + exit + } +} +di +if "`group'" != "" { + di _col(2) in ye "For all models : - mean of latent trait of `gp' 0 at time 1 is constrained at 0" + di _col(19) "- Equality of variances between groups" + di +} +else { + di _col(2) in ye "For all models : mean of latent trait at time 1 is constrained at 0" + di +} + + + +/********************************* +* DEFINITION DES CONTRAINTES +*********************************/ + +if "`group'"!="" { // Contraintes si option groupe + *EGALITE ENTRE GROUPES A T1 (1-200) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=0+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``j'']1.`gp' + } + } + + *DIF UNIFORME A T1 (201-400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=200+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp'=`p'*[1.``j'']1.`gp'-`p'*[1.``j'']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 0 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 1 (601-800) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=600+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp' + } + } + + * RC COMMUNE (801-1000) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=800+`maxdif'*(`j'-1)+`p'' [`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + * RC UNIFORME, groupe 0 (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp' + } + } + + * RC UNIFORME, groupe 1 (1201-1400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1200+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + *Sans interaction temps x groupe + constraint 1999 [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'=[/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' +} +else { //Contraintes si pas d'option groupe + *EGALITE ENTRE T1 et T2 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']:_cons = [`p'.``=`j'+`nbitems''']:_cons + } + } + *RC UNIFORME (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']:_cons - [1.``j'']:_cons)=[`p'.``=`j'+`nbitems''']:_cons -[`p'.``j'']:_cons + } + } +} + +/********************************* +* MATRICE DES RESULTATS +*********************************/ +matrix dif_rc=J(`nbitems',8,.) +matrix colnames dif_rc=DIFT1 DIFU RC RC_DIF RCG0 RCUG0 RCG1 RCUG1 +local rown "" + +forvalues j =1 /`nbitems' { + local rown "`rown' ``j''" +} +matrix rownames dif_rc = `rown' + +*Nb modalitĂ© max +local nbdif_max = 0 +forvalues j=1/`nbitems' { + if `nbdif_max' < `nbdif_`j'' { + local nbdif_max = `nbdif_`j'' + } +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////// PARTIE 1 : DIF A T1 ? //////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +if "`group'"!="" & "`nodif'"=="" { // PARTIE 1 = Slmt si option group & pas de "nodif" + if "`detail'" != "" { + di _dup(59) "_ " + di + di _col(5) in ye "PART 1: DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES BETWEEN GROUPS AT FIRST TIME OF MEASUREMENT" + } + + ********************************* + ** MODEL B ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading cons) var(0: THETA@v) var(1:THETA@v) latent(THETA) nocapslatent + /* Stockage des estimations du modĂšle */ + estimates store modeldifB + matrix val_mB = r(table) + matrix esti_B = e(b) + + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mB=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + + matrix colnames delta_mB = `name_partOneC' + matrix rownames delta_mB = `name_partOneL' + matrix delta_mB_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mB_se = `name_partOneC_se' + matrix rownames delta_mB_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB=r(estimate) + local delta`j'_`p'g`g'mB_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB = r(estimate) + local delta`j'_`p'g`g'mB_se = r(se) + } + matrix delta_mB[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB' + matrix delta_mB_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB_se' + } + } + } + + matrix var_mB = (val_mB[1,"/var(THETA)#0bn.`gp'"]\val_mB[2,"/var(THETA)#0bn.`gp'"]) + + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmB=r(estimate) + local segeffmB=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmBp=r(p) + local gcmBchi=r(chi2) + local gcmBdf=r(df) + + + ********************************* + ** MODEL A ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading means) var(0: THETA@v) var(1:THETA@v) from(esti_B, skip) latent(THETA) nocapslatent + + /* Stockage des estimations du modĂšle */ + estimates store modeldifA + matrix val_mA = r(table) + matrix esti_A = e(b) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mA=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mA = `name_partOneC' + matrix rownames delta_mA = `name_partOneL' + matrix delta_mA_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mA_se = `name_partOneC_se' + matrix rownames delta_mA_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA=r(estimate) + local delta`j'_`p'g`g'mA_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA = r(estimate) + local delta`j'_`p'g`g'mA_se = r(se) + } + matrix delta_mA[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA' + matrix delta_mA_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA_se' + } + } + } + //Variance et se mA + matrix var_mA = (val_mA[1,"/var(THETA)#0bn.`gp'"]\val_mA[2,"/var(THETA)#0bn.`gp'"]) + + + ************************************************************* + ***********************AFFICHAGE***************************** + ************************************************************* + + if "`detail'" != "" { + //Affichage modĂšle A + di + di in ye "PROCESSING STEP A" + di + + + /* Affichage des estimations des difficultĂ©s modĂšle A */ + + di _col(5) in ye "{ul:MODEL A:} No group effect: mean of latent trait of group 1 = mean of latent trait of group 0," + di _col(7) in ye "all item difficulties are freely estimated in both groups" + di + di _col(10) in ye "Item difficulties estimates (s.e.)" + di _col(10) "{hline 70}" + di _col(30) in ye abbrev("`gp'",20) "=0" _col(60) abbrev("`gp'",20) "=1" + di _col(10) "{hline 70}" + forvalues j=1/`nbitems' { + di in ye _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + di in gr _col(10) "`p'" _col(30) %6.2f `delta`j'_`p'g0mA' %6.2f " (" %3.2f `delta`j'_`p'g0mA_se' ")" _col(60) %6.2f `delta`j'_`p'g1mA' " (" %3.2f `delta`j'_`p'g1mA_se' ")" + } + } + di _col(10) "{hline 70}" + /* Affichage des estimations sur le trait latent du modĂšle A */ + di + di _col(10) in ye "Latent trait distribution estimates" + di _col(10) "{hline 65}" + di _col(45) in ye "Estimate" _col(60) "Standard error" + di _col(10) "{hline 65}" + di _col(10) in ye "Variance" in gr _col(45) %6.2f `=var_mA[1,1]' _col(62) %6.2f `=var_mA[2,1]' + di _col(10) in ye "Group effect (mean gp 1)" in gr _col(44) %6.2f "0 (constrained)" + di _col(10) "{hline 65}" + + //*Affichage modĂšle B + + di + di in ye "PROCESSING STEP B" + di + + /* Affichage des estimations des difficultĂ©s modĂšle B */ + + di _col(5) in ye "{ul:MODEL B:} Group effect estimated: mean of latent trait of group 1 free estimated," + di _col(7) in ye "Same item difficulties estimated between groups" + di + di _col(10) in ye "Item difficulties estimates (s.e.)" + di _col(10) "{hline 70}" + di _col(30) in ye abbrev("`gp'",20) "=0" _col(60) abbrev("`gp'",20) "=1" + di _col(10) "{hline 70}" + + forvalues j=1/`nbitems' { + di in ye _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + di in gr _col(10) "`p'" _col(30) %6.2f `delta`j'_`p'g0mB' " (" %3.2f `delta`j'_`p'g0mB_se' ")" _col(60) %6.2f `delta`j'_`p'g1mB' " (" %3.2f `delta`j'_`p'g1mB_se' ")" + } + } + + di _col(10) "{hline 70}" + /* Affichage des estimations sur le trait latent du modĂšle B */ + di + di _col(10) in ye "Latent trait distribution estimates" + di _col(10) "{hline 80}" + di _col(45) in ye "Estimate" _col(60) "Standard error" _col(77) "P-value" + di _col(10) "{hline 80}" + di _col(10) in ye "Variance" in gr _col(44) %6.2f `=var_mB[1,1]' _col(62) %6.2f `=var_mB[2,1]' + di _col(10) in ye "Group effect (mean gp 1)" in gr _col(44) %6.2f `geffmB' _col(62) %6.2f `segeffmB' _col(77) %6.4f `gcmBp' + di _col(10) "{hline 80}" + di + } + + ***************************************************** + * ModĂšle A vs ModĂšle B * + ***************************************************** + + qui lrtest modeldifA modeldifB + local diftestp=r(p) + local diftestchi=r(chi2) + local diftestdf=r(df) + if "`detail'" != "" { + //affichage lrtest + di _col(10) in ye "LIKELIHOOD-RATIO TEST MODEL A VS MODEL B : " + di _col(10) "{hline 50}" + di _col(10) in ye "Chi-square" _col(30) "DF" _col(50) "P-value" + di _col(10) in gr %6.2f `diftestchi' _col(30) %2.0f `diftestdf' _col(50) %6.4f `diftestp' + di _col(10) "{hline 50}" + + if `diftestp'<0.05{ + di _col(10) in ye "DIFFERENCE IN ITEM DIFFICULTIES BETWEEN GROUPS LIKELY" + } + else{ + di _col(10) in ye "NO DIFFERENCE BETWEEN GROUPS DETECTED" + } + } + + ********************************* + *************MODEL C************* + ********************************* + // Etape itĂ©rative si lrtest significatif + local nb_stepC = 0 + + if `diftestp'<0.05{ /*If pvalue(LRtest)<0.05 then step C*/ + if "`detail'" { + di + di in ye "PROCESSING STEP C" + di + } + /*test DIF pour chaque item*/ + local boucle = 1 + local stop = 0 + while `boucle'<=`=`nbitp'-1' & `stop'==0{ /*on s'arrĂȘte quand on a libĂ©rĂ© du DIF sur (tous les items-1) ou lorsqu'il n'y a plus de tests significatifs*/ + local nb_stepC = `boucle' + local pajust=0.05/`=`nbitp'+1-`boucle'' + /*rĂ©initialisation de la matrice de test*/ + matrix test_difu_`boucle'=J(`nbitems',3,.) + matrix colnames test_difu_`boucle'=chi_DIFU df_DIFU pvalueDIFU + matrix test_dif_`boucle'=J(`nbitems',3,.) + matrix colnames test_dif_`boucle'=chi_DIF df_DIF pvalueDIF + local nbsig=0 + local minpval=1 + local itemdif=0 + if "`detail'" { + di _col(10) "{hline 70}" + di _col(10) in ye "Loop `boucle'" _col(50) "Adjusted alpha: " %6.4f `pajust' + di + di in ye _col(40) "Chi-Square" _col(55) "DF" _col(60) "P-Value" + } + /*boucle de test*/ + forvalues j=1/`nbitems'{ + //if `nbdif_`j'' > 2 { + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF dĂ©jĂ  dĂ©tectĂ© sur l'item j*/ + /*on libĂšre le DIF de l'item i: pas de contraintes*/ + forvalues k=1/`nbitems'{ /*contraintes pour les autres items (si DIF NU sur item k, pas de contraintes*/ + if `k'!=`j' & `nbmoda_`j'' >= 2 { + if dif_rc[`k',1]==. | dif_rc[`k',1]==0 {/*pas de DIF sur item k: contraintes 1-200*/ + forvalues p=1/`nbdif_`k''{ + qui local listconst "`listconst' `=0+`maxdif'*(`k'-1)+`p''" + qui constraint list `=0+`maxdif'*(`k'-1)+`p'' + } + } + else{ + if dif_rc[`k',2]!=. & dif_rc[`k',2]!= 0 & `nbmoda_`k'' > 2 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`k''{ + qui local listconst "`listconst' `=200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + } + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) latent(THETA) nocapslatent + estimates store modeldif3b`boucle'it`i' + + ************************* + *****test DIF item i***** + ************************* + qui test [1.``j'']1.`gp'=[1.``j'']0bn.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']1.`gp'=[`p'.``j'']0bn.`gp', acc + } + } + matrix test_dif_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + + /* Test DIF Uniforme */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``j'']1.`gp'-[1.``j'']0bn.`gp')=[2.``j'']1.`gp'-[2.``j'']0bn.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``j'']1.`gp'-[1.``j'']0bn.`gp')=[`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp', acc + } + matrix test_difu_`boucle'[`j',1]=(r(chi2), r(df), r(p)) + } + + if test_dif_`boucle'[`j',3]<`pajust'{/*si DIF sur item i*/ + local ++nbsig + if test_dif_`boucle'[`j',3]<`minpval'{ + local minpval=test_dif_`boucle'[`j',2] + local itemdif=`j' + } + } + if "`detail'" != "" { + di in ye _col(12) %-30s abbrev("``j'' :",22) in gr _col(40) %6.3f test_dif_`boucle'[`j',1] _col(55) test_dif_`boucle'[`j',2] _col(60) %6.4f test_dif_`boucle'[`j',3] + } + } + } + /*si nb de tests significatifs=0, on arrĂȘte*/ + if `nbsig'==0{ + local stop=1 + if `boucle' == 1 { + if "`detail'" != "" { + di + di _col(20) in ye ">>> No significant test: no difference between groups detected, no DIF detected" + di _col(10) "{hline 70}" + } + } + else { + if "`detail'" != ""{ + di + di _col(20) in ye ">>> No other significant tests" + di _col(10) "{hline 70}" + } + } + } + else{/*si nb de tests significatifs>0, mise Ă  jour de la matrice de rĂ©sultats*/ + matrix dif_rc[`itemdif',1]=`boucle' + if "`detail'" != ""{ + di _col(15) _dup(60) "-" + di _col(15) in ye "Difference between groups on ``itemdif'' at time 1" + } + if `nbmoda_`itemdif'' > 2 { + if "`detail'" != "" { + di + di _col(40) "Chi-Square" _col(55) "DF" _col(60) "P-value" + di _col(15) in ye "Uniform ? " in gr _col(40) %4.2f `=test_difu_`boucle'[`itemdif',1]' _col(55) `=test_difu_`boucle'[`itemdif',2]' _col(60) %4.2f `=test_difu_`boucle'[`itemdif',3]' + } + if test_difu_`boucle'[`itemdif',3]<0.05{ /*DIF NU dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=0 + if "`detail'" != "" { + di + di _col(17) in ye " >>> ``itemdif'' : Non-uniform differences of item difficulties between groups at T1" + di _col(15) _dup(60) "-" + } + } + else{/*DIF U dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=`boucle' + if "`detail'" != "" { + di + di _col(17) in ye ">>> ``itemdif'' : Uniform differences of item difficulties between groups at T1" + di _col(15) _dup(60) "-" + } + } + } + else { + // DiffĂ©rence entre groupes au temps 1 mais slmt 2 moda. donc pas de U ou NU + di _col(15) _dup(60) "-" + } + } + local ++boucle + } + } + + /* MODELE FINAL DE LA PARTIE 1. Si DIFT1 dĂ©tectĂ© (=Au moins 2 boucles dans l'Ă©tape C)*/ + if `nb_stepC' > 1 { + forvalues j=1/`nbitems'{ + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF: contraintes 1-200*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) latent(THETA) nocapslatent + /* Stockage des estimations du modĂšle */ + estimates store modeldifCFin + matrix val_mC = r(table) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mCFin=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mCFin = `name_partOneC' + matrix rownames delta_mCFin = `name_partOneL' + + matrix delta_mCFin_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + matrix colnames delta_mCFin_se = `name_partOneC_se' + matrix rownames delta_mCFin_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin=r(estimate) + local delta`j'_`p'g`g'mCFin_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin = r(estimate) + local delta`j'_`p'g`g'mCFin_se = r(se) + } + matrix delta_mCFin[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin' + matrix delta_mCFin_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin_se' + } + } + } + if "`group'" != "" { //Variance et se mA + matrix var_mC = (val_mC[1,"/var(THETA)#0bn.`gp'"]\val_mC[2,"/var(THETA)#0bn.`gp'"]) + } + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmCFin=r(estimate) + local segeffmCFin=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmCFinp=r(p) + local gcmCFinchi=r(chi2) + local gcmCFindf=r(df) + } +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////// PARTIE 2 : RECALIBRATION ? //////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +if "`detail'" != "" { + di + di _dup(59) "_ " + di + if "`group'" != "" { + di in ye "PART 2 : DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES ACROSS TIMES (RECALIBRATION)" + } + else { + di in ye "DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES ACROSS TIMES (RECALIBRATION)" + } +} + ********************************* + ** MODEL 2 ** + ********************************* + +local listconst "" // liste des contraintes si option groupe +local listconst_g "" //LIste des contraintes sans option groupe (Notation peu logique !!) + +forvalues j=1/`nbitems'{ + if "`group'" == "" { // Contraintes pas de RC pour tous les items + forvalues p=1/`nbdif_`j''{ + local listconst_g "`listconst_g' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + } + else { + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 {/*pas de DIF Ă  T1 sur item k: contraintes 1*/ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else{ + if dif_rc[`j',2]!=. & dif_rc[`j',2] != 0 { /*diff T1 U: contraintes 200*/ + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + forvalues p=1/`nbdif_`j''{ /* egalites entre temps : groupe 0 (401-600)*/ + local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + forvalues p=1/`nbdif_`j''{ /* egalites entre temps : groupe 1 (601-800)*/ + local listconst "`listconst' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=600+`maxdif'*(`j'-1)+`p'' + } + } +} + +local model "" +forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA1@`p')(`p'.``=`j'+`nbitems'''<-THETA2@`p')" + } +} + +if "`group'" != "" { +di "gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') latent(THETA1 THETA2) nocapslatent" + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') latent(THETA1 THETA2) nocapslatent +} +else { + qui gsem `model', mlogit tol(0.01) iterate(100) means(THETA1@0 THETA2@m20) var(THETA1@v1 THETA2@v2) cov(THETA1*THETA2@cov12) constraint(`listconst_g') latent(THETA1 THETA2) nocapslatent +} + +/*Stockage des donnĂ©es du modĂšle 2 */ +estimates store model2 +matrix val_m2 = r(table) +matrix esti_2 = e(b) + +if "`group'" != "" { + matrix var_m2 = (val_m2[1,"/var(THETA1)#0bn.`gp'"],val_m2[1,"/var(THETA2)#0bn.`gp'"]\val_m2[2,"/var(THETA1)#0bn.`gp'"],val_m2[2,"/var(THETA2)#0bn.`gp'"]) + matrix covar_m2 = (val_m2[1,"/cov(THETA1,THETA2)#0.`gp'"],val_m2[1,"/cov(THETA1,THETA2)#1.`gp'"]\val_m2[2,"/cov(THETA1,THETA2)#0.`gp'"],val_m2[2,"/cov(THETA1,THETA2)#1.`gp'"]\val_m2[4,"/cov(THETA1,THETA2)#0.`gp'"],val_m2[4,"/cov(THETA1,THETA2)#1.`gp'"]) +} +else { + matrix var_m2 = (val_m2[1,"/var(THETA1)"],val_m2[1,"/var(THETA2)"]\val_m2[2,"/var(THETA1)"],val_m2[2,"/var(THETA2)"]) + matrix covar_m2 = (val_m2[1,"/cov(THETA1,THETA2)"]\val_m2[2,"/cov(THETA1,THETA2)"]\val_m2[4,"/cov(THETA1,THETA2)"]) +} + +/*group effect*/ +if "`group'" != "" { + qui lincom [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' + local geffm2=r(estimate) + local segeffm2=r(se) + local ubgeffm2 = r(ub) + local lbgeffm2 = r(lb) + qui test [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp'=0 + local gpm2p=r(p) + local gpm2chi=r(chi2) + local gpm2df=r(df) +} + +/*time effect*/ +if "`group'" != "" { + qui lincom [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp' + local teffm2=r(estimate) + local seteffm2=r(se) + local ubteffm2 = r(ub) + local lbteffm2 = r(lb) + qui test [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp'=0 + local tm2p=r(p) + local tm2chi=r(chi2) + local tm2df=r(df) +} +else { + qui lincom [/]:mean(THETA2) /* [/]:mean(THETA1)*/ + local teffm2=r(estimate) + local seteffm2=r(se) + local ubteffm2 = r(ub) + local lbteffm2 = r(lb) + qui test [/]:mean(THETA2) = 0 /* [/]:mean(THETA1)*/ + local tm2p=r(p) + local tm2chi=r(chi2) + local tm2df=r(df) +} + +*INTERACTION +if "`group'" != "" { + qui lincom [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#1.`gp'+[/]:mean(THETA1)#0bn.`gp' + local interm2=r(estimate) + local seinterm2=r(se) + local ubinterm2 = r(ub) + local lbinterm2 = r(lb) + qui test [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#1.`gp'+[/]:mean(THETA1)#0bn.`gp' = 0 + local interm2p=r(p) + local interm2chi=r(chi2) + local interm2df=r(df) +} + +if "`group'" != "" { + matrix mod2 = J(7,`=`nbmoda_sum'*4+6',.) + local name_partTwoC "" + forvalues j = 1/`nbitems' { + forvalues p=1/`nbdif_`j'' { + forvalues t=1/2 { + forvalues g = 0/1 { + local name_partTwoC "`name_partTwoC' d_j`j'_p`p'_gp`g'_t`t'" + } + } + } + } + local name_partTwoC "`name_partTwoC' VAR(THETA1) VAR(THETA2) COV(TH1,TH2) GROUP_Effect TIME_Effect INTER_TxG " + matrix colnames mod2 = `name_partTwoC' + matrix rownames mod2 = Estimate se Upper_b Lower_b Chi_square DF pvalue +} +else { + matrix mod2 = J(7,`=`nbmoda_sum'*2+4',.) + local name_partTwoC "" + forvalues j = 1/`nbitems' { + forvalues p=1/`nbdif_`j'' { + forvalues t=1/2 { + local name_partTwoC "`name_partTwoC' d_j`j'_p`p'_t`t'" + } + } + } + local name_partTwoC "`name_partTwoC' VAR(THETA1) VAR(THETA2) COV(TH1,TH2) TIME_Effect " + matrix colnames mod2 = `name_partTwoC' + matrix rownames mod2 = Estimate se Upper_b Lower_b Chi_square DF pvalue +} + +*DifficultĂ©s +forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues t=1/2{ + if "`group'" != "" { // groupe binaire + forvalues g=0/1 { + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm2= r(estimate) + local delta`t'_`j'_`p'g`g'm2_se= r(se) + local delta`t'_`j'_`p'g`g'm2_ub=r(ub) + local delta`t'_`j'_`p'g`g'm2_lb=r(lb) + local delta`t'_`j'_`p'g`g'm2_p=r(p) + if `p'>1 { + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' - [`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm2=r(estimate) + local delta`t'_`j'_`p'g`g'm2_se=r(se) + local delta`t'_`j'_`p'g`g'm2_ub=r(ub) + local delta`t'_`j'_`p'g`g'm2_lb=r(lb) + local delta`t'_`j'_`p'g`g'm2_p=r(p) + } + local place = 0 + local compt = 1 + while `compt' < `j' { + local place = `place' + `nbdif_`compt'' + local ++compt + } + if `t' == 1 { + matrix mod2[1,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2' + matrix mod2[2,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2_se' + matrix mod2[3,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2_ub' + matrix mod2[4,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2_lb' + matrix mod2[7,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm2_p' + } + if `t' == 2 { + matrix mod2[1,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2' + matrix mod2[2,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2_se' + matrix mod2[3,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2_ub' + matrix mod2[4,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2_lb' + matrix mod2[7,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm2_p' + } + } + } + else { // groupe unique (=gp0) + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']_cons + local delta`t'_`j'_`p'g0m2= r(estimate) + local delta`t'_`j'_`p'g0m2_se= r(se) + local delta`t'_`j'_`p'g0m2_ub=r(ub) + local delta`t'_`j'_`p'g0m2_lb=r(lb) + local delta`t'_`j'_`p'g0m2_p=r(p) + if `p'>1{ + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']_cons - [`p'.``=(`t'-1)*`nbitems'+`j''']_cons + local delta`t'_`j'_`p'g0m2=r(estimate) + local delta`t'_`j'_`p'g0m2_se=r(se) + local delta`t'_`j'_`p'g0m2_ub=r(ub) + local delta`t'_`j'_`p'g0m2_lb=r(lb) + local delta`t'_`j'_`p'g0m2_p=r(p) + } + local place = 0 + local compt = 1 + while `compt' < `j' { + local place = `place' + `nbdif_`compt'' + local ++compt + } + if `t' == 1 { + matrix mod2[1,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2' + matrix mod2[2,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_se' + matrix mod2[3,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_ub' + matrix mod2[4,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_lb' + matrix mod2[7,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_p' + } + if `t' == 2 { + matrix mod2[1,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2' + matrix mod2[2,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_se' + matrix mod2[3,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_ub' + matrix mod2[4,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_lb' + matrix mod2[7,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m2_p' + } + } + } + } +} + +if "`group'" != "" { + matrix mod2[1,`=4*`nbmoda_sum'+1'] = (val_m2[1,"/var(THETA1)#0bn.`gp'"], val_m2[1,"/var(THETA2)#0bn.`gp'"]) + matrix mod2[2,`=4*`nbmoda_sum'+1'] = (val_m2[2,"/var(THETA1)#0bn.`gp'"],val_m2[2,"/var(THETA2)#0bn.`gp'"]) + matrix mod2[3,`=4*`nbmoda_sum'+1'] = (val_m2[6,"/var(THETA1)#0bn.`gp'"],val_m2[6,"/var(THETA2)#0bn.`gp'"]) + matrix mod2[4,`=4*`nbmoda_sum'+1'] = (val_m2[5,"/var(THETA1)#0bn.`gp'"],val_m2[5,"/var(THETA2)#0bn.`gp'"]) + + matrix mod2[1,`=4*`nbmoda_sum'+2+1'] = (val_m2[1,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod2[2,`=4*`nbmoda_sum'+2+1'] = (val_m2[2,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod2[3,`=4*`nbmoda_sum'+2+1'] = (val_m2[6,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod2[4,`=4*`nbmoda_sum'+2+1'] = (val_m2[5,"/cov(THETA1,THETA2)#0.`gp'"]) + + matrix mod2[1,`=4*`nbmoda_sum'+2+1+1'] = `geffm2' + matrix mod2[2,`=4*`nbmoda_sum'+2+1+1'] = `segeffm2' + matrix mod2[3,`=4*`nbmoda_sum'+2+1+1'] = `ubgeffm2' + matrix mod2[4,`=4*`nbmoda_sum'+2+1+1'] = `lbgeffm2' + matrix mod2[5,`=4*`nbmoda_sum'+2+1+1'] = `gpm2chi' + matrix mod2[6,`=4*`nbmoda_sum'+2+1+1'] = `gpm2df' + matrix mod2[7,`=4*`nbmoda_sum'+2+1+1'] = `gpm2p' + + matrix mod2[1,`=4*`nbmoda_sum'+2+1+1+1'] = `teffm2' + matrix mod2[2,`=4*`nbmoda_sum'+2+1+1+1'] = `seteffm2' + matrix mod2[3,`=4*`nbmoda_sum'+2+1+1+1'] = `ubteffm2' + matrix mod2[4,`=4*`nbmoda_sum'+2+1+1+1'] = `lbteffm2' + matrix mod2[5,`=4*`nbmoda_sum'+2+1+1+1'] = `tm2chi' + matrix mod2[6,`=4*`nbmoda_sum'+2+1+1+1'] = `tm2df' + matrix mod2[7,`=4*`nbmoda_sum'+2+1+1+1'] = `tm2p' + + matrix mod2[1,`=4*`nbmoda_sum'+2+1+1+1+1'] = `interm2' + matrix mod2[2,`=4*`nbmoda_sum'+2+1+1+1+1'] = `seinterm2' + matrix mod2[3,`=4*`nbmoda_sum'+2+1+1+1+1'] = `ubinterm2' + matrix mod2[4,`=4*`nbmoda_sum'+2+1+1+1+1'] = `lbinterm2' + matrix mod2[5,`=4*`nbmoda_sum'+2+1+1+1+1'] = `interm2chi' + matrix mod2[6,`=4*`nbmoda_sum'+2+1+1+1+1'] = `interm2df' + matrix mod2[7,`=4*`nbmoda_sum'+2+1+1+1+1'] = `interm2p' +} +else { + matrix mod2[1,`=2*`nbmoda_sum'+1'] = (val_m2[1,"/var(THETA1)"],val_m2[1,"/var(THETA2)"]) + matrix mod2[2,`=2*`nbmoda_sum'+1'] = (val_m2[2,"/var(THETA1)"],val_m2[2,"/var(THETA2)"]) + matrix mod2[3,`=2*`nbmoda_sum'+1'] = (val_m2[6,"/var(THETA1)"],val_m2[6,"/var(THETA2)"]) + matrix mod2[4,`=2*`nbmoda_sum'+1'] = (val_m2[5,"/var(THETA1)"],val_m2[5,"/var(THETA2)"]) + + matrix mod2[1,`=2*`nbmoda_sum'+2+1'] = (val_m2[1,"/cov(THETA1,THETA2)"]) + matrix mod2[2,`=2*`nbmoda_sum'+2+1'] = (val_m2[2,"/cov(THETA1,THETA2)"]) + matrix mod2[3,`=2*`nbmoda_sum'+2+1'] = (val_m2[6,"/cov(THETA1,THETA2)"]) + matrix mod2[4,`=2*`nbmoda_sum'+2+1'] = (val_m2[5,"/cov(THETA1,THETA2)"]) + + matrix mod2[1,`=2*`nbmoda_sum'+2+1+1'] = `teffm2' + matrix mod2[2,`=2*`nbmoda_sum'+2+1+1'] = `seteffm2' + matrix mod2[3,`=2*`nbmoda_sum'+2+1+1'] = `ubteffm2' + matrix mod2[4,`=2*`nbmoda_sum'+2+1+1'] = `lbteffm2' + matrix mod2[5,`=2*`nbmoda_sum'+2+1+1'] = `tm2chi' + matrix mod2[6,`=2*`nbmoda_sum'+2+1+1'] = `tm2df' + matrix mod2[7,`=2*`nbmoda_sum'+2+1+1'] = `tm2p' +} + + ********************************* + ** MODEL 1 ** + ********************************* + + +/*PCM longitudinal, no true change, group effect, interaction*/ +local listconst "" +forvalues j=1/`nbitems'{ /*contraintes pour les autres items (si DIF NU sur item k, pas de contraintes*/ + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 {/*pas de DIF sur item k: contraintes 1*/ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else{ + if `nbdif_`j'' > 1 { + if dif_rc[`j',2]!=. & dif_rc[`j',2] != 0 { /*diff T1 U: contraintes 201*/ + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } +} + + +local model "" +forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA1@`p')(`p'.``=`j'+`nbitems'''<-THETA2@`p')" + } +} + +if "`group'"!="" { + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@0) means(1: THETA1@m1 THETA2@m1) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) latent(THETA1 THETA2) nocapslatent +} +else { + qui gsem `model', mlogit tol(0.01) iterate(100) means(THETA1@0 THETA2@0) var(THETA1@v1 THETA2@v2) cov(THETA1*THETA2@cov12) from(esti_2, skip) latent(THETA1 THETA2) nocapslatent +} + +/* Stockage des estimations du modĂšle 1 */ +estimates store model1 +matrix val_m1 = r(table) + +/* Calcul des difficultĂ©s d'item (delta_j) */ +matrix delta_m1 = J(`nbitems',`=`nbdif_max'*4',.) +local name_partTwoC "" +forvalues p=1/`nbdif_max' { + forvalues t=1/2 { + forvalues g = 0/1 { + local name_partTwoC "`name_partTwoC' delta_t`t'_`p'_gp`g'" + } + } +} + +local name_partTwoL "" +forvalues j=1/`=`nbitems'*2' { + if `j' <= `nbitems' { + local name_partTwoL "`name_partTwoL' ``j''" + } + else { + local name_partTwoL "`name_partTwoL' ``=`nbitems'+`j'''" + } +} + +matrix colnames delta_m1 = `name_partTwoC' +matrix rownames delta_m1 = `name_partTwoL' + +matrix delta_m1_se = J(`nbitems',`=`nbdif_max'*4',.) +local name_partTwoC_se "" + +forvalues p=1/`nbdif_max' { + forvalues t=1/2 { + forvalues g = 0/1 { + local name_partTwoC_se "`name_partTwoC_se' delta_t`t'_`p'_gp`g'_se" + } + } +} + +matrix colnames delta_m1_se = `name_partTwoC_se' +matrix rownames delta_m1_se = `name_partTwoL' + +if "`group'"!="" { + forvalues t=1/2{ + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm1= r(estimate) + local delta`t'_`j'_`p'g`g'm1_se= r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' - [`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm1=r(estimate) + local delta`t'_`j'_`p'g`g'm1_se=r(se) + } + if `t' == 1 { + matrix delta_m1[`j',`=4*(`p'-1)+`g'+`t'']=`delta`t'_`j'_`p'g`g'm1' + matrix delta_m1_se[`j',`=4*(`p'-1)+`g'+`t'']=`delta`t'_`j'_`p'g`g'm1_se' + } + if `t' == 2 { + matrix delta_m1[`j',`=4*(`p'-1)+1+`g'+`t'']=`delta`t'_`j'_`p'g`g'm1' + matrix delta_m1_se[`j',`=4*(`p'-1)+1+`g'+`t'']=`delta`t'_`j'_`p'g`g'm1_se' + } + } + } + } + } +} +else { + forvalues t=1/2 { + forvalues j=1/`nbitems' { + forvalues p = 1/`nbdif_`j'' { + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']:_cons + local delta`t'_`j'_`p'g0m1= r(estimate) + local delta`t'_`j'_`p'g0m1_se= r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']:_cons - [`p'.``=(`t'-1)*`nbitems'+`j''']:_cons + local delta`t'_`j'_`p'g0m1=r(estimate) + local delta`t'_`j'_`p'g0m1_se=r(se) + } + if `t' == 1 { + matrix delta_m1[`j',`=4*(`p'-1)+`t'']=`delta`t'_`j'_`p'g0m1' + matrix delta_m1_se[`j',`=4*(`p'-1)+`t'']=`delta`t'_`j'_`p'g0m1_se' + } + if `t' == 2 { + matrix delta_m1[`j',`=4*(`p'-1)+1+`t'']=`delta`t'_`j'_`p'g0m1' + matrix delta_m1_se[`j',`=4*(`p'-1)+1+`t'']=`delta`t'_`j'_`p'g0m1_se' + } + } + } + } +} + +if "`group'" != "" { + matrix var_m1 = (val_m1[1,"/var(THETA1)#0bn.`gp'"],val_m1[1,"/var(THETA2)#0bn.`gp'"]\val_m1[2,"/var(THETA1)#0bn.`gp'"],val_m1[2,"/var(THETA2)#0bn.`gp'"]) + matrix covar_m1 = (val_m1[1,"/cov(THETA1,THETA2)#0.`gp'"],val_m1[1,"/cov(THETA1,THETA2)#1.`gp'"]\val_m1[2,"/cov(THETA1,THETA2)#0.`gp'"],val_m1[2,"/cov(THETA1,THETA2)#1.`gp'"]\val_m1[4,"/cov(THETA1,THETA2)#0.`gp'"],val_m1[4,"/cov(THETA1,THETA2)#1.`gp'"]) +} +else { + matrix var_m1 = (val_m1[1,"/var(THETA1)"],val_m1[1,"/var(THETA2)"]\val_m1[2,"/var(THETA1)"],val_m1[2,"/var(THETA2)"]) + matrix covar_m1 = (val_m1[1,"/cov(THETA1,THETA2)"]\val_m1[2,"/cov(THETA1,THETA2)"]\val_m1[4,"/cov(THETA1,THETA2)"]) +} + +/*group effect*/ +if "`group'"!="" { + qui lincom [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' + local geffm1=r(estimate) + local segeffm1=r(se) + qui test [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' = 0 + local gpm1p=r(p) + local gpm1chi=r(chi2) + local gpm1df=r(df) +} + + ************************************************************* + ***********************AFFICHAGE***************************** + ************************************************************* +if "`detail'" != "" { + // Affichage du modĂšle 1 + di + di in ye "PROCESSING STEP 1" + di + /* Affichage des estimations des difficultĂ©s */ + + if "`group'" != "" { + di _col(5) in ye "{ul:MODEL 1:} Group effect estimated, no time effect (mean of latent trait of group 0 at T2) equal to mean of group 0 at T1)," + di _col(7) in ye "all item difficulties are freely estimated across times" + di + di _col(10) in ye "Item difficulties estimates (s.e.)" + di _col(10) "{hline 85}" + di _col(30) "Time 1" _col(70) "Time 2" + di in ye _col(20) abbrev("`gp'",15) "=0" _col(38) abbrev("`gp'",15) "=1" _col(58) abbrev("`gp'",15) "=0" _col(76) abbrev("`gp'",15) "=1" + di _col(10) "{hline 85}" + } + else { + di _col(5) in ye "{ul:MODEL 1}: no time effect," + di _col(7) in ye "all item difficulties are freely estimated across times" + di + di _col(10) in ye "Item difficulties estimates (s.e.)" + di _col(10) "{hline 50}" + di _col(30) "Time 1" _col(45) "Time 2" + di _col(10) "{hline 50}" + } + + forvalues j=1/`nbitems' { + di in ye _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + if "`group'" != "" { + di in gr _col(10) "`p'" _col(20) %6.2f `delta1_`j'_`p'g0m1' " (" %4.2f `delta1_`j'_`p'g0m1_se' ")" _col(38) %6.2f `delta1_`j'_`p'g1m1' " (" %4.2f `delta1_`j'_`p'g1m1_se' ")" /// + _col(58) %6.2f `delta2_`j'_`p'g0m1' " (" %4.2f `delta2_`j'_`p'g0m1_se' ")" _col(76) %6.2f `delta2_`j'_`p'g1m1' " (" %4.2f `delta2_`j'_`p'g1m1_se' ")" + } + else { + di in gr _col(10) "`p'" _col(25) %6.2f `delta1_`j'_`p'g0m1' " (" %4.2f `delta1_`j'_`p'g0m1_se' ")" _col(42) %6.2f `delta2_`j'_`p'g0m1' " (" %4.2f `delta2_`j'_`p'g0m1_se' ")" + } + } + } + if "`group'" != "" { + di _col(10) "{hline 85}" + } + else { + di _col(10) "{hline 50}" + } + /* Affichage des estimations du trait latent du modĂšle 1 */ + di + di _col(10) in ye "Latent trait distribution estimates" + if "`group'" != "" { + di _col(10) "{hline 80}" + di _col(45) in ye "Estimate" _col(60) "Standard error" _col(77) "P-value" + di _col(10) "{hline 80}" + } + else { + di _col(10) "{hline 70}" + di _col(45) in ye "Estimate" _col(60) "Standard error" " + di _col(10) "{hline 70}" + } + di _col(10) in ye "Variance Time 1" in gr _col(44) %6.2f `=var_m1[1,1]' _col(62) %6.2f `=var_m1[2,1]' + di _col(10) in ye "Variance Time 2" in gr _col(44) %6.2f `=var_m1[1,2]' _col(62) %6.2f `=var_m1[2,2]' + di _col(10) in ye "Covariance" in gr _col(44) %6.2f `=covar_m1[1,1]' _col(62) %6.2f `=covar_m1[2,1]' + if "`group'" != "" { + di _col(10) in ye "Group effect (mean gp 1 at T1)" in gr _col(44) %6.2f `geffm1' _col(62) %6.2f `segeffm1' _col(77) %6.4f `gpm1p' + } + di _col(10) in ye "Time effect (mean gp 0 at T2)" in gr _col(44) "0 (constrained)" + if "`group'" != "" { + di _col(10) in ye "TimexGroup inter" in gr _col(44) "0 (constrained)" + } + if "`group'" != "" { + di _col(10) "{hline 80}" + } + else { + di _col(10) "{hline 70}" + } + //Affichage du modĂšle 2 + di + di in ye "PROCESSING STEP 2" + di + /* Affichage des estimations des difficultĂ©s */ + + if "`group'" != "" { + di _col(5) in ye "{ul:MODEL 2:} Group effect, time effect (mean of latent trait of group 0 at T2) free estimated, time x group interaction estimated," + di _col(7) in ye "Same item difficulties estimated across times" + di + di _col(10) in ye "Item difficulties estimates (s.e.)" + di _col(10) "{hline 85}" + di _col(30) "Time 1" _col(70) "Time 2" + di in ye _col(20) abbrev("`gp'",15) "=0" _col(38) abbrev("`gp'",15) "=1" _col(58) abbrev("`gp'",15) "=0" _col(76) abbrev("`gp'",15) "=1" + di _col(10) "{hline 85}" + } + else { + di _col(5) in ye "{ul:MODEL 2}: time effect estimated (mean of latent trait group 0 at T2) free estimated," + di _col(7) in ye "Same item difficulties estimated across times" + di + di _col(10) in ye "Item difficulties estimates (s.e.)" + di _col(10) "{hline 50}" + di _col(30) "Time 1" _col(45) "Time 2" + di _col(10) "{hline 50}" + } + + forvalues j=1/`nbitems' { + di in ye _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + if "`group'" != "" { + di in gr _col(10) "`p'" _col(20) %6.2f `delta1_`j'_`p'g0m2' " (" %4.2f `delta1_`j'_`p'g0m2_se' ")" _col(38) %6.2f `delta1_`j'_`p'g1m2' " (" %4.2f `delta1_`j'_`p'g1m2_se' ")" /// + _col(58) %6.2f `delta2_`j'_`p'g0m2' " (" %4.2f `delta2_`j'_`p'g0m2_se' ")" _col(76) %6.2f `delta2_`j'_`p'g1m2' " (" %4.2f `delta2_`j'_`p'g1m2_se' ")" + } + else { + di in gr _col(10) "`p'" _col(25) %6.2f `delta1_`j'_`p'g0m2' " (" %4.2f `delta1_`j'_`p'g0m2_se' ")" _col(42) %6.2f `delta2_`j'_`p'g0m2' " (" %4.2f `delta2_`j'_`p'g0m2_se' ")" + } + } + } + if "`group'" != "" { + di _col(10) "{hline 85}" + } + else { + di _col(10) "{hline 50}" + } + /* Affichage des estimations du trait latent du modĂšle 2 */ + di + di _col(10) in ye "Latent trait distribution estimates" + di _col(10) "{hline 80}" + di _col(45) in ye "Estimate" _col(60) "Standard error" _col(77) "P-value" + di _col(10) "{hline 80}" + + if "`group'" == "" { + local fact_k = 2 + } + else { + local fact_k = 4 + } + + di _col(10) in ye "Variance Time 1" in gr _col(44) %6.2f `=mod2[1,`=`fact_k'*`nbmoda_sum'+1']' _col(62) %6.2f =mod2[2,`=`fact_k'*`nbmoda_sum'+1'] + di _col(10) in ye "Variance Time 2" in gr _col(44) %6.2f `=mod2[1,`=`fact_k'*`nbmoda_sum'+2']' _col(62) %6.2f `=mod2[2,`=`fact_k'*`nbmoda_sum'+2']' + di _col(10) in ye "Covariance" in gr _col(44) %6.2f `=mod2[1,`=`fact_k'*`nbmoda_sum'+3']' _col(62) %6.2f `=mod2[2,`=`fact_k'*`nbmoda_sum'+3']' + + if "`group'" != "" { + + di _col(10) in ye "Group effect (mean gp 1 at T1)" in gr _col(44) %6.2f `geffm2' _col(62) %6.2f `segeffm2' _col(77) %6.4f `gpm2p' + } + di _col(10) in ye "Time effect (mean gp 0 at T2)" in gr _col(44) %6.2f `teffm2' _col(62) %6.2f `seteffm2' _col(77) %6.4f `tm2p' + + if "`group'" != "" { + di _col(10) in ye "TimexGroup inter" in gr _col(44) %6.2f `interm2' _col(62) %6.2f `seinterm2' _col(77) %6.4f `interm2p' + } + di _col(10) "{hline 80}" + di +} + ***************************************************** + * ModĂšle 1 vs ModĂšle 2 * + ***************************************************** +qui lrtest model2 model1 + +local rstestp=r(p) +local rstestchi=r(chi2) +local rstestdf=r(df) +if "`detail'" != "" { + di _col(10) in ye "LIKELIHOOD-RATIO TEST MODEL 1 VS MODEL 2" + di _col(10) "{hline 50}" + di _col(10) in ye "Chi-square" _col(30) "DF" _col(50) "P-value" + di _col(10) in gr %6.2f `rstestchi' _col(30) %2.0f `rstestdf' _col(50) %6.4f `rstestp' + di _col(10) "{hline 50}" + if `rstestp'<0.05{ + di _col(10) in ye "DIFFERENCE IN ITEM DIFFICULTIES ACROSS TIMES LIKELY" + } + else{ + di _col(10) in ye "NO DIFFERENCE IN ITEM DIFFICULTIES ACROSS TIMES DETECTED, NO RECALIBRATION DETECTED" + } +} + ********************************* + *************MODEL 3************* + ********************************* +// Etape itĂ©rative si lrtest significatif +local nb_step3=0 + +if `rstestp' < 0.05 { /* If pvalue(LRtest)<0.05 then step 3 */ + if "`detail'" != "" { + di + di in ye "PROCESSING STEP 3" + di + } + /*test RC pour chaque item*/ + local boucle = 1 + local stop = 0 + //matrix list dif_rc + while `boucle' <= `=`nbitp'-1' & `stop' == 0 { /*on s'arrĂȘte quand on a libĂ©rĂ© du RC sur (tous les items-1) ou lorsqu'il n'y a plus de tests significatifs*/ + local nb_step3 = `boucle' + local pajust=0.05/`=`nbitp'+1-`boucle'' // local pajust=0.05/`=`nbitems'+1-`boucle' + if "`group'" != "" { + local pajust2 = 0.05/`nbgrp' + } + /*rĂ©initialisation de la matrice de test*/ + matrix test_rc_`boucle'=J(`nbitems',9,.) + matrix test_rcCOMM_`boucle'=J(`nbitems',3,.) + matrix test_rcU_`boucle'=J(`nbitems',6,.) + matrix colnames test_rc_`boucle'= chi_RC df_RC pvalue_RC chi_RCg0 df_RCg0 pvalue_RCg0 chi_RCg1 df_RCg1 pvalue_RCg1 + matrix colnames test_rcCOMM_`boucle'= chi_RCCOMM df_RCCOMM pvalue_RCCOMM + matrix colnames test_rcU_`boucle'= chi_RCUg0 df_RCUg0 pvalue_RCUg0 chi_RCUg1 df_RCUg1 pvalue_RCUg1 + local nbsig=0 + local minpval=1 + local itemrc=0 + if "`detail'" != "" { + di _col(10) "{hline 70}" + di _col(10) in ye "Loop `boucle'" _col(50) "Adjusted alpha : " %6.4f `pajust' + di + di in ye _col(40) "Chi-Square" _col(55) "DF" _col(60) "P-Value" + } + + + /*boucle de test*/ + forvalues j=1/`nbitems'{ + if `nbdif_`j'' >= 1 { + local model "" + local listconst "" + local listconst_g "" + if dif_rc[`j',3]==. { /*si pas de RC dĂ©jĂ  dĂ©tectĂ© sur l'item j -> test item j*/ + /*on libĂšre la RC de l'item j: pas de contraintes*/ + forvalues k=1/`nbitems'{ + if "`group'" == "" { + if `k'!=`j'{ + if dif_rc[`k',3]==. | dif_rc[`k',3]==0 {/*pas de RC sur item k: contraintes 401-600*/ + forvalues p=1/`nbdif_`k''{ + local listconst_g "`listconst_g' `=400+`maxdif'*(`k'-1)+`p'' " + qui constraint list `=400+`maxdif'*(`k'-1)+`p'' + } + } + else { + if dif_rc[`k',6]!=. & dif_rc[`k',6]!=0 { // RC commune unif. + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst_g "`listconst_g' `=1000+`maxdif'*(`k'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`k'-1)+`p'' + } + } + } + } + } + } + else { + /* Contraintes de DIF */ + if dif_rc[`k',1]==.|dif_rc[`k',1]==0 { // contraintes si pas de DIF (1-200) + forvalues p=1/`nbdif_`k''{ + local listconst "`listconst' `=0+`maxdif'*(`k'-1)+`p''" + qui constraint list `=0+`maxdif'*(`k'-1)+`p'' + } + } + else { // PrĂ©sence de DIF + if dif_rc[`k',2]!=. & dif_rc[`k',2]!=0 { // contraintes de DIF U (201-400) + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst "`listconst' `=200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + if `k'!=`j'{ /*contraintes pour les autres items */ + if dif_rc[`k',3]==. | dif_rc[`k',3]==0 {/*pas de RC sur item k: contraintes 401-600 601-800*/ + forvalues p=1/`nbdif_`k''{ + local listconst "`listconst' `=400+`maxdif'*(`k'-1)+`p'' `=600+`maxdif'*(`k'-1)+`p''" + qui constraint list `=400+`maxdif'*(`k'-1)+`p'' `=600+`maxdif'*(`k'-1)+`p'' + } + } + else { //RC dĂ©tectĂ©e sur l'item k + if dif_rc[`k',4]==0{ /*RC commune: contraintes 801-1000*/ + forvalues p=1/`nbdif_`k''{ /***************************** j=1 ou 2 ?****/ + local listconst "`listconst' `=800+`maxdif'*(`k'-1)+`p''" + qui constraint list `=800+`maxdif'*(`k'-1)+`p'' + } + if dif_rc[`k',6]!=. & dif_rc[`k',6]!=0 { // RC commune unif. + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst "`listconst' `=1000+`maxdif'*(`k'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`k'-1)+`p'' + } + } + } + } + else { // RC diff + if dif_rc[`k',5]==. | dif_rc[`k',5]==0 { // RC gp0 (400) + forvalues p=1/`nbdif_`k''{ + local listconst "`listconst' `=400+`maxdif'*(`k'-1)+`p''" + qui constraint list `=400+`maxdif'*(`k'-1)+`p'' + } + } + if dif_rc[`k',6]!=. & dif_rc[`k',6]!=0 { // RCU gp0 (1001-1200) + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst "`listconst' `=1000+`maxdif'*(`k'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`k'-1)+`p'' + } + } + } + if dif_rc[`k',7]==. | dif_rc[`k',7]==0 { // RC gp1 (600) + forvalues p=1/`nbdif_`k''{ + local listconst "`listconst' `=600+`maxdif'*(`k'-1)+`p''" + qui constraint list `=600+`maxdif'*(`k'-1)+`p'' + } + } + if dif_rc[`k',8]!=. & dif_rc[`k',8]!=0 { // RCU gp1 (1201-1400) + if `nbmoda_`k'' > 2 { + forvalues p=2/`nbdif_`k''{ + local listconst "`listconst' `=1200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=1200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + } + } + } + } + + local model "" + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA1@`p')(`p'.``=`jj'+`nbitems'''<-THETA2@`p')" + } + } + if "`group'" == "" { // Sans l'option group + qui gsem `model', mlogit tol(0.01) iterate(100) means(THETA1@0 THETA2@m20) var(THETA1@v1 THETA2@v2) cov(THETA1*THETA2@cov12) constraint(`listconst_g') from(esti_2, skip) latent(THETA1 THETA2) nocapslatent + + /*****************/ + /*tests RC item j*/ + /*****************/ + + /* RC ? */ + qui test [1.``j'']_cons =[1.``=`j'+`nbitems''']_cons + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']_cons =[`p'.``=`j'+`nbitems''']_cons, acc + } + } + matrix test_rc_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + + + /* RCU ? */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``=`j'+`nbitems''']_cons -[1.``j'']_cons)=[2.``=`j'+`nbitems''']_cons -[2.``j'']_cons + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``=`j'+`nbitems''']_cons -[1.``j'']_cons)=[`p'.``=`j'+`nbitems''']_cons -[`p'.``j'']_cons , acc + } + matrix test_rcU_`boucle'[`j',1]=(r(chi2), r(df),r(p)) + } + } + else { // Avec l'option group + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) latent(THETA1 THETA2) nocapslatent + + /*****************/ + /*tests RC item i*/ + /*****************/ + + /* RC ? */ + qui test [1.``j'']0bn.`gp'=[1.``=`j'+`nbitems''']0bn.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp', acc + } + } + qui test [1.``j'']1.`gp'=[1.``=`j'+`nbitems''']1.`gp', acc + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp', acc + } + } + matrix test_rc_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + /* RC COMMUNE ? */ + qui test [1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp'=[1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp', acc + } + } + matrix test_rcCOMM_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + /* RC groupe 0 ? */ + qui test [1.``j'']0bn.`gp'=[1.``=`j'+`nbitems''']0bn.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp', acc + } + } + matrix test_rc_`boucle'[`j',4]=(r(chi2),r(df),r(p)) + + /* RCU grp 0 ? */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[2.``=`j'+`nbitems''']0bn.`gp'-[2.``j'']0bn.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp', acc + } + matrix test_rcU_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + } + + /* RC groupe 1 ? */ + qui test [1.``j'']1.`gp'=[1.``=`j'+`nbitems''']1.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp', acc + } + } + matrix test_rc_`boucle'[`j',7]=(r(chi2),r(df),r(p)) + + /* RCU grp 1 ? */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[2.``=`j'+`nbitems''']1.`gp'-[2.``j'']1.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp', acc + } + matrix test_rcU_`boucle'[`j',4]=(r(chi2),r(df),r(p)) + } + } + /******* Matrice test complĂšte *********/ + if "`detail'" != "" { + di in ye _col(10) %-30s abbrev("``j'' :",22) in gr _col(40) %6.3f test_rc_`boucle'[`j',1] _col(55) test_rc_`boucle'[`j',2] _col(60) %6.4f test_rc_`boucle'[`j',3] + } + } + } + } + //matrix list test_rc_`boucle' + forvalues j=1/`nbitems'{ + if test_rc_`boucle'[`j',3]<`pajust'{/*si RC sur item i*/ + if test_rc_`boucle'[`j',3]<`minpval'{ + local minpval=test_rc_`boucle'[`j',3] + local itemrc=`j' + } + } + } + if `itemrc' != 0 { // itemrc = numĂ©ro de l'item avec le test le + sig. + if "`group'" == "" { // Recalibration si pas d'option groupe + local ++nbsig + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',5]=`boucle' + if `nbmoda_`itemrc'' > 2 { + if "`detail'" != "" { + di _col(15) _dup(60) "-" + di _col(15) in ye "Recalibration on ``itemrc''" + di _col(40) "Chi-square" _col(55) "DF" _col(60) "P-value" + di _col(15) in ye "Uniform RC ? " in gr _col(40) %4.2f `=test_rcU_`boucle'[`itemrc',1]' _col(55) `=test_rcU_`boucle'[`itemrc',2]' _col(60) %6.4f `=test_rcU_`boucle'[`itemrc',3]' + } + if test_rcU_`boucle'[`itemrc',3] >= 0.05 { //RC Uniforme sur itemRC + matrix dif_rc[`itemrc',6]=`boucle' + if "`detail'" != "" { + di + di _col(17) in ye ">>> ``itemrc'' : Uniform RC" + di _col(15) _dup(60) "-" + } + } + else { + matrix dif_rc[`itemrc',6]=0 + if "`detail'" != "" { + di + di _col(17) in ye ">>> ``itemrc'' : Non-uniform RC" + di _col(15) _dup(60) "-" + } + } + } + else { + if "`detail'" != "" { + di + di _col(17) in ye ">>> ``itemrc'' : Recalibration " + di _col(15) _dup(60) "-" + } + } + } + else { // Option groupe + if "`detail'" != "" { + di _col(15) _dup(60) "-" + di _col(15) in ye "Recalibration on ``itemrc''" + di + di _col(40) "Chi-Square" _col(55) "DF" _col(60) "P-value" + di _col(15) in ye "Common RC ? " in gr _col(40) %4.2f `=test_rcCOMM_`boucle'[`itemrc',1]' _col(55) `=test_rcCOMM_`boucle'[`itemrc',2]' _col(60) %6.4f `=test_rcCOMM_`boucle'[`itemrc',3]' + } + if test_rcCOMM_`boucle'[`itemrc',3] < 0.05 { //RC diffĂ©rentielle + if "`detail'" != "" { + di + di _col(15) in ye "RC group 0 ? " in gr _col(40) %4.2f `=test_rc_`boucle'[`itemrc',4]' _col(55) `=test_rc_`boucle'[`itemrc',5]' _col(60) %6.4f `=test_rc_`boucle'[`itemrc',6]' "{it: - with adjusted alpha = `pajust2' }" + } + if test_rc_`boucle'[`itemrc',6] < `pajust2' { //RC gp 0 + local ++nbsig + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',4]=`boucle' + matrix dif_rc[`itemrc',5]=`boucle' + if `nbmoda_`itemrc'' > 2 { + di _col(15) in ye "Uniform RC on gp 0 ? " in gr _col(40) %4.2f `=test_rcU_`boucle'[`itemrc',1]' _col(55) `=test_rcU_`boucle'[`itemrc',2]' _col(60) %6.4f `=test_rcU_`boucle'[`itemrc',3]' + if test_rcU_`boucle'[`itemrc',3] >= 0.05 { // RCU gp 0 + matrix dif_rc[`itemrc',6]=`boucle' + local phrase_diff = ">>> ``itemrc'' : Uniform differential RC on group 0." + } + else { + matrix dif_rc[`itemrc',6]=0 + local phrase_diff = ">>> ``itemrc'' : Non-uniform differential RC on group 0." + } + } + else { + local phrase_diff = ">>> ``itemrc'' : Differential RC on group 0." + } + } + if "`detail'" != "" { + di + di _col(15) in ye "RC group 1 ? " in gr _col(40) %4.2f `=test_rc_`boucle'[`itemrc',7]' _col(55) `=test_rc_`boucle'[`itemrc',8]' _col(60) %6.4f `=test_rc_`boucle'[`itemrc',9]' "{it: - with adjusted alpha = `pajust2' }" + } + if test_rc_`boucle'[`itemrc',9] < `pajust2' { //RC gp 1 + local ++nbsig + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',4]=`boucle' + matrix dif_rc[`itemrc',7]=`boucle' + if `nbmoda_`itemrc'' > 2 { + if "`detail'" != "" { + di _col(15) in ye "Uniform RC on gp 1 ? " in gr _col(40) %4.2f `=test_rcU_`boucle'[`itemrc',4]' _col(55) `=test_rcU_`boucle'[`itemrc',5]' _col(60) %6.4f `=test_rcU_`boucle'[`itemrc',6]' + } + if test_rcU_`boucle'[`itemrc',6] >= 0.05 { // RCU gp 1 + matrix dif_rc[`itemrc',8]=`boucle' + if "`detail'" != "" { + di + } + if dif_rc[`itemrc',5] != `boucle' { //RC slmt sur g1 + local phrase_diff = ">>> ``itemrc'' : Differential RC, uniform RC on group 1." + } + else { + if dif_rc[`itemrc',6] == 0 { // + RCNU g0 + local phrase_diff = ">>> ``itemrc'' : Differential RC, non-uniform RC on group 0 and uniform RC on group 1." + } + else { // + RCU G0 + local phrase_diff = ">>> ``itemrc'' : Differential RC, uniform RC on group 0 and uniform RC on group 1." + } + } + } + else { //RCNU gp 1 + matrix dif_rc[`itemrc',8]=0 + if "`detail'" != "" { + di + } + if dif_rc[`itemrc',5] != `boucle' { + local phrase_diff = ">>> ``itemrc'' : Differential RC, non-uniform RC on group 1." + } + else { + if dif_rc[`itemrc',6] == 0 { // + RCNU g0 + local phrase_diff = ">>> ``itemrc'' : Differential RC, non-uniform RC on group 0 and non-uniform RC on group 1." + } + else { // + RCU G0 + local phrase_diff = ">>> ``itemrc'' : Differential RC, uniform RC on group 0 and non-uniform RC on group 1." + } + } + } + } + else { + if dif_rc[`itemrc',5] != `boucle' { + local phrase_diff = ">>> ``itemrc'' : Differential RC on group 1." + } + else { + local phrase_diff = ">>> ``itemrc'' : Differential RC on group 0 and differential RC on group 1." + } + } + } + if "`detail'" != "" { + di + di _col(17) in ye "`phrase_diff'" + di _col(15) _dup(60) "-" + } + } + else { // RC commune -> MAJ modĂšle 3 + /*******************************************************************************************************************/ + if `nbmoda_`itemrc'' == 2 { + if "`detail'" != "" { + di + di _col(14) in ye ">>> {ul:``itemrc''}: recalibration" + di _col(20) in ye "Common " in gr "{it:(Chi-s: " %4.2f `=test_rcCOMM_`boucle'[`itemrc',1]' ", DF: `=test_rcCOMM_`boucle'[`itemrc',2]' p-val. : " %4.2f `=test_rcCOMM_`boucle'[`itemrc',3]' ")}" + } + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',4]=0 + matrix dif_rc[`itemrc',5]=`boucle' + matrix dif_rc[`itemrc',7]=`boucle' + local ++nbsig + } + else { + matrix dif_rc[`itemrc',3]=`boucle' + matrix dif_rc[`itemrc',4]=0 + matrix dif_rc[`itemrc',5]=`boucle' + matrix dif_rc[`itemrc',7]=`boucle' + //matrix list dif_rc + local model "" + local listconst "" + forvalues j=1/`nbitems'{ + /* Contraintes de DIF */ + if dif_rc[`j',1]==.|dif_rc[`j',1]==0 { // contraintes si pas de DIF (1-200) + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { // PrĂ©sence de DIF + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { // contraintes de DIF U (201-400) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + if `j' != `itemrc'{ /*contraintes pour les autres items */ + if dif_rc[`j',3]==. | dif_rc[`j',3]==0 {/*pas de RC sur item p: contraintes 401-600 601-800*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p'' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' `=600+`maxdif'*(`j'-1)+`p'' + } + } + else { //RC dĂ©tectĂ©e sur l'item p + if dif_rc[`j',4]==0{ /*RC commune: contraintes 801-1000*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=800+`maxdif'*(`j'-1)+`p''" + qui constraint list `=800+`maxdif'*(`j'-1)+`p'' + } + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RC commune unif. + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + } + else if dif_rc[`j',4] != 0 & dif_rc[`j',4]!=0. { // RC diff + if dif_rc[`j',5]==. | dif_rc[`j',5]==0 { // RC gp0 (400) + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + } + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RCU gp0 (1001-1200) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + if dif_rc[`j',7]==. | dif_rc[`j',7]==0 { // RC gp1 (600) + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=600+`maxdif'*(`j'-1)+`p'' + } + } + if dif_rc[`j',8]!=. & dif_rc[`j',8]!=0 { // RCU gp1 (1201-1400) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=1200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + } + } + else { // Contrainte de RC commune pour l'itemrc + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=800+`maxdif'*(`itemrc'-1)+`p''" + qui constraint list `=800+`maxdif'*(`itemrc'-1)+`p'' + } + } + } + qui di "`listconst'" + local model "" + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA1@`p')(`p'.``=`jj'+`nbitems'''<-THETA2@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) latent(THETA1 THETA2) nocapslatent + + /************************/ + /*tests RC item `itemrc'*/ + /************************/ + matrix commU_`boucle'=J(`nbitems',3,.) //Matrice des tests de RCU slmt si RC commune + matrix colnames commU_`boucle'= chi_RCU df_RCU p_RCU + + /* RCU grp 0 ? */ + if `nbmoda_`itemrc'' > 2 { + qui test 2*([1.``=`itemrc'+`nbitems''']0bn.`gp'-[1.``itemrc'']0bn.`gp')=[2.``=`itemrc'+`nbitems''']0bn.`gp'-[2.``itemrc'']0bn.`gp' + forvalues j=3/`nbdif_`itemrc''{ + qui test `j'*([1.``=`itemrc'+`nbitems''']0bn.`gp'-[1.``itemrc'']0bn.`gp')=[`j'.``=`itemrc'+`nbitems''']0bn.`gp'-[`j'.``itemrc'']0bn.`gp', acc + } + matrix commU_`boucle'[`itemrc',1]=(r(chi2),r(df),r(p)) + if "`detail'" != "" { + di _col(15) in ye "Uniform RC ?" in gr _col(40) %4.2f `=commU_`boucle'[`itemrc',1]' _col(55) `=commU_`boucle'[`itemrc',2]' _col(60) %6.4f `=commU_`boucle'[`itemrc',3]' + } + if commU_`boucle'[`itemrc',3] >= 0.05 { // RCU + local ++nbsig + matrix dif_rc[`itemrc',6]=`boucle' + matrix dif_rc[`itemrc',8]=`boucle' + if "`detail'" != "" { + di + //di _col(14) in ye ">>> {ul:``itemrc''}: recalibration" + //di _col(20) in ye "Common " in gr "{it:(Chi-s: " %4.2f `=test_rcCOMM_`boucle'[`itemrc',1]' ", DF: `=test_rcCOMM_`boucle'[`itemrc',2]' p-val. : " %4.2f `=test_rcCOMM_`boucle'[`itemrc',3]' ")}" + di _col(17) in ye ">>> ``itemrc'' : Uniform common RC" + di _col(15) _dup(60) "-" + } + } + else { + local ++nbsig + matrix dif_rc[`itemrc',6]=0 + matrix dif_rc[`itemrc',8]=0 + if "`detail'" != "" { + di + di _col(17) in ye ">>> ``itemrc'' : Non-uniform common RC" + di _col(15) _dup(60) "-" + } + } + } + } + } // fin de RC commune + } + } + else { + local stop = 1 + } + /*******************************************************************************************************************/ + // Fin de RC sur item i + if `nbsig'==0{ + local stop=1 + if `boucle' == 1 { + if "`detail'" != "" { + di + di _col(20) in ye "No significant tests, no recalibration detected" + di _col(10) "{hline 70}" + di + } + } + else { + if "`detail'" != "" { + di + di _col(20) in ye ">>> No other significant tests" + di _col(10) "{hline 70}" + di + } + } + } + local ++boucle + } +} + + + + ********************************* + *** BILAN *** + ********************************* + + + +if "`group'" != "" & "`nodif'" == "" { + di + di _col(2) "{hline 80}" + di in ye _col(18) "Difference in" + di in ye _col(2) "Item" _col(18) "groups at T1" _col(36) "Recalibration" _col(54) "RC " abbrev("`gp'",10) " 0" _col(72) "RC " abbrev("`gp'",10) " 1" + di _col(2) "{hline 80}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + local difft1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + if (dif_rc[`j',1] != . ) { + if (dif_rc[`j',2]!=0) { + local difft1 "Uniform" + } + else { + local difft1 "Non-uniform" + } + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + if dif_rc[`j',1] != . { + local difft1 " X " + } + } + di in ye _col(2) abbrev("``j''",15) in gr _col(18) "`difft1'" _col(36) "`RC'" _col(54) "`RCg0'" _col(72) "`RCg1'" + } + di _col(2) "{hline 80}" +} +else if "`group'" != "" & "`nodif'" != "" { + di + di _col(10) "{hline 70}" + di in ye _col(10) "Item" _col(26) "Recalibration" _col(46) "RC `gp' 0" _col(62) "RC `gp' 1" + di _col(10) "{hline 70}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + } + di in ye _col(10) "``j''" in gr _col(26) "`RC'" _col(44) "`RCg0'" _col(62) "`RCg1'" + } + di _col(10) "{hline 70}" +} +else if "`group'" == "" { + di + di _col(10) "{hline 40}" + di in ye _col(10) "Item" _col(36) "Recalibration" + di _col(10) "{hline 40}" + forvalues j=1/`nbitems' { + local RC + if dif_rc[`j',3] != . { + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RC "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RC "Non-uniform" + } + } + else { + local RC " X " + } + } + di in ye _col(10) "``j''" in gr _col(38) "`RC'" + } + di _col(10) "{hline 40}" +} + + + ********************************* + ** MODEL 4 ** + ********************************* +if "`detail'" != "" { + di + di in ye "PROCESSING STEP 4" + di +} + //matrix list dif_rc, title ("Constraints") + +local model "" +local listconst "" +local listconst_g "" +forvalues j=1/`nbitems'{ + if "`group'" != "" { + if dif_rc[`j',1]==.|dif_rc[`j',1]==0 { /*si pas de DIF: contraintes 1-200 */ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { // PrĂ©sence de DIF + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { // contraintes de DIF U (201-400) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + } + if dif_rc[`j',3]==. | dif_rc[`j',3]==0 { /*pas de RC : contraintes 401-600 601-800*/ + forvalues p=1/`nbdif_`j''{ + if "`group'" == "" { + local listconst_g "`listconst_g' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + else { + local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p'' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' `=600+`maxdif'*(`j'-1)+`p'' + } + } + } + else { //RC dĂ©tectĂ©e sur l'item j + if "`group'" == "" { + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RC unif. + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst_g "`listconst_g' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + } + else { + if dif_rc[`j',4]==0{ /*RC commune: contraintes 801-1000*/ + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=800+`maxdif'*(`j'-1)+`p''" + qui constraint list `=800+`maxdif'*(`j'-1)+`p'' + } + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RC commune unif. + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + } + else { // RC diff + if dif_rc[`j',5]==. | dif_rc[`j',5]==0 { // RC gp0 (400) + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=400+`maxdif'*(`j'-1)+`p''" + qui constraint list `=400+`maxdif'*(`j'-1)+`p'' + } + } + if dif_rc[`j',6]!=. & dif_rc[`j',6]!=0 { // RCU gp0 (1001-1200) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=1000+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1000+`maxdif'*(`j'-1)+`p'' + } + } + } + if dif_rc[`j',7]==. | dif_rc[`j',7]==0 { // RC gp1 (600) + forvalues p=1/`nbdif_`j''{ + local listconst "`listconst' `=600+`maxdif'*(`j'-1)+`p''" + qui constraint list `=600+`maxdif'*(`j'-1)+`p'' + } + } + if dif_rc[`j',8]!=. & dif_rc[`j',8]!=0 { // RCU gp1 (1201-1400) + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + local listconst "`listconst' `=1200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=1200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + } + } +} + +local model "" + +forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA1@`p')(`p'.``=`jj'+`nbitems'''<-THETA2@`p')" + } +} + +if "`group'" != "" { + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_2, skip) latent(THETA1 THETA2) nocapslatent +} +else { + qui gsem `model', mlogit tol(0.01) iterate(100) means( THETA1@0 THETA2@m2) var(THETA1@v1 THETA2@v2) cov(THETA1*THETA2@cov12) constraint(`listconst_g') from(esti_2, skip) latent(THETA1 THETA2) nocapslatent +} + /* Stockage des estimations du modĂšle */ +matrix val_m4 = r(table) +matrix esti_4 = e(b) + +if "`group'" != "" { + matrix var_m4 = (val_m4[1,"/var(THETA1)#0bn.`gp'"],val_m4[1,"/var(THETA2)#0bn.`gp'"]\val_m4[2,"/var(THETA1)#0bn.`gp'"],val_m4[2,"/var(THETA2)#0bn.`gp'"]) + matrix covar_m4 = (val_m4[1,"/cov(THETA1,THETA2)#0.`gp'"],val_m4[1,"/cov(THETA1,THETA2)#1.`gp'"]\val_m4[2,"/cov(THETA1,THETA2)#0.`gp'"],val_m4[2,"/cov(THETA1,THETA2)#1.`gp'"]\val_m4[4,"/cov(THETA1,THETA2)#0.`gp'"],val_m4[4,"/cov(THETA1,THETA2)#1.`gp'"]) +} +else { + matrix var_m4 = (val_m4[1,"/var(THETA1)"],val_m4[1,"/var(THETA2)"]\val_m4[2,"/var(THETA1)"],val_m4[2,"/var(THETA2)"]) + matrix covar_m4 = (val_m4[1,"/cov(THETA1,THETA2)"]\val_m4[2,"/cov(THETA1,THETA2)"]\val_m4[4,"/cov(THETA1,THETA2)"]) +} + +/* Matrice des tests effet grp, tps et inter */ +matrix effet = J(5,3,.) +matrix colnames effet= Groupe Temps Interaction +matrix rownames effet = Esti Std_Err Pvalue Chi DF + +/*group effect*/ +if "`group'" != "" { + qui lincom [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' + matrix effet[1,1] =r(estimate) + matrix effet[2,1]=r(se) + qui test [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' = 0 + matrix effet[3,1]=r(p) + matrix effet[4,1]=r(chi2) + matrix effet[5,1]=r(df) +} + +/*time effect*/ +if "`group'" != "" { + qui lincom [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp' + matrix effet[1,2]=r(estimate) + matrix effet[2,2]=r(se) + qui test [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp' = 0 + matrix effet[3,2]=r(p) + matrix effet[4,2]=r(chi2) + matrix effet[5,2]=r(df) +} +else { + qui lincom [/]:mean(THETA2) /* -[/]:mean(THETA1)*/ + local teffm4=r(estimate) + local seteffm4=r(se) + local ubteffm4 = r(ub) + local lbteffm4 = r(lb) + qui test [/]:mean(THETA2) /* -[/]:mean(THETA1) */ = 0 + local tm4p=r(p) + local tm4chi=r(chi2) + local tm4df=r(df) +} + +*INTERACTION +if "`group'" != "" { + qui lincom [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#1.`gp'+[/]:mean(THETA1)#0bn.`gp' + matrix effet[1,3]=r(estimate) + matrix effet[2,3]=r(se) + local ubinterm4=r(ub) + local lbinterm4=r(lb) + qui test [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#1.`gp'+[/]:mean(THETA1)#0bn.`gp' = 0 + matrix effet[3,3]=r(p) + matrix effet[4,3]=r(chi2) + matrix effet[5,3]=r(df) +} + +if "`group'" != "" { + local effet_tps = 0 + local effet_grp = 0 + + if effet[3,3] >= 0.05 { // Si option group, on s'interesse Ă  l'interaction temps x group, et MAJ modĂšle >>> modĂšle final = modĂšle 4 + contrainte 1999 (Interaction = 0) + /* Affichage des estimations sur le trait latent du modĂšle 4 */ + if "`detail'" != "" { + di + di _col(10) in ye "Latent trait estimates" + di _col(10) "{hline 80}" + di _col(45) in ye "Estimate" _col(60) "Standard error" _col(77) "P-value" + di _col(10) "{hline 80}" + di _col(10) in ye "Variance Time 1" in gr _col(44) %6.2f `=var_m4[1,1]' _col(62) %6.2f `=var_m4[2,1]' + di _col(10) in ye "Variance Time 2" in gr _col(44) %6.2f `=var_m4[1,2]' _col(62) %6.2f `=var_m4[2,2]' + di _col(10) in ye "Covariance" in gr _col(44) %6.2f `=covar_m4[1,1]' _col(62) %6.2f `=covar_m4[2,1]' + if "`group'" != "" { + di _col(10) in ye "Group effect (mean gp 1 at T1)" in gr _col(44) %6.2f effet[1,1] _col(62) %6.2f effet[2,1] _col(77) %6.4f effet[3,1] + } + di _col(10) in ye "Time effect (mean gp 0 at T2)" in gr _col(44) %6.2f effet[1,2] _col(62) %6.2f effet[2,2] _col(77) %6.4f effet[3,2] + + if "`group'" != "" { + di _col(10) in ye "TimexGroup inter" in gr _col(44) %6.2f effet[1,3] _col(62) %6.2f effet[2,3] _col(77) %6.4f effet[3,3] + } + di _col(10) "{hline 80}" + di + di in ye ">>> Time x group interaction : no significant test, estimate of model 4 with constraint of time x group interaction at 0 " + di + } + local yn_inter = 0 + local listconst "`listconst' 1999" + qui di "`listconst'" + local model "" + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA1@`p')(`p'.``=`jj'+`nbitems'''<-THETA2@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) means(0: THETA1@0 THETA2@m20) means(1: THETA1@m11 THETA2@m21) var(0: THETA1@v1 THETA2@v2) var(1:THETA1@v1 THETA2@v2) cov(0: THETA1*THETA2@cov12) cov(1: THETA1*THETA2@cov12) constraint(`listconst') from(esti_4, skip) latent(THETA1 THETA2) nocapslatent + + matrix val_m4 = r(table) + } + else { + local yn_inter = 1 + } + + /*group effect*/ + qui lincom [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' + local geffm4=r(estimate) + local segeffm4=r(se) + local ubgeffm4=r(ub) + local lbgeffm4=r(lb) + qui test [/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp'=0 + local gpm4p=r(p) + local gpm4chi=r(chi2) + local gpm4df=r(df) + + /*time effect*/ + qui lincom [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp' + local teffm4=r(estimate) + local seteffm4=r(se) + local lbteffm4=r(lb) + local ubteffm4=r(ub) + qui test [/]:mean(THETA2)#0bn.`gp'-[/]:mean(THETA1)#0bn.`gp'=0 + local tm4p=r(p) + local tm4chi=r(chi2) + local tm4df=r(df) +} + + /* Calcul des difficultĂ©s (delta_j) */ +if "`group'" != "" { + matrix mod4 = J(7,`=`nbmoda_sum'*4+6',.) + local name_partTwoC "" + forvalues j = 1/`nbitems' { + forvalues p=1/`nbdif_`j'' { + forvalues t=1/2 { + forvalues g = 0/1 { + local name_partTwoC "`name_partTwoC' d_j`j'_p`p'_gp`g'_t`t'" + } + } + } + } + local name_partTwoC "`name_partTwoC' VAR(THETA1) VAR(THETA2) COV(TH1,TH2) GROUP_Effect TIME_Effect INTER_TxG " + matrix colnames mod4 = `name_partTwoC' + matrix rownames mod4 = Estimate se Upper_b Lower_b Chi_square DF pvalue +} +else { + matrix mod4 = J(7,`=`nbmoda_sum'*2+4',.) + local name_partTwoC "" + forvalues j = 1/`nbitems' { + forvalues p=1/`nbdif_`j'' { + forvalues t=1/2 { + local name_partTwoC "`name_partTwoC' d_j`j'_p`p'_t`t'" + } + } + } + local name_partTwoC "`name_partTwoC' VAR(THETA1) VAR(THETA2) COV(TH1,TH2) TIME_Effect " + matrix colnames mod4 = `name_partTwoC' + matrix rownames mod4 = Estimate se Upper_b Lower_b Chi_square DF pvalue +} + +*DifficultĂ©s +forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues t=1/2{ + if "`group'" != "" { // groupe binaire + forvalues g=0/1 { + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm4= r(estimate) + local delta`t'_`j'_`p'g`g'm4_se= r(se) + local delta`t'_`j'_`p'g`g'm4_ub=r(ub) + local delta`t'_`j'_`p'g`g'm4_lb=r(lb) + local delta`t'_`j'_`p'g`g'm4_p=r(p) + if `p'>1 { + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' - [`p'.``=(`t'-1)*`nbitems'+`j''']:`g'.`gp' + local delta`t'_`j'_`p'g`g'm4=r(estimate) + local delta`t'_`j'_`p'g`g'm4_se=r(se) + local delta`t'_`j'_`p'g`g'm4_ub=r(ub) + local delta`t'_`j'_`p'g`g'm4_lb=r(lb) + local delta`t'_`j'_`p'g`g'm4_p=r(p) + } + local place = 0 + local compt = 1 + while `compt' < `j' { + local place = `place' + `nbdif_`compt'' + local ++compt + } + if `t' == 1 { + matrix mod4[1,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4' + matrix mod4[2,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4_se' + matrix mod4[3,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4_ub' + matrix mod4[4,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4_lb' + matrix mod4[7,`=4*(`p'-1)+`g'+`t'+4*`place'']=`delta`t'_`j'_`p'g`g'm4_p' + } + if `t' == 2 { + matrix mod4[1,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4' + matrix mod4[2,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4_se' + matrix mod4[3,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4_ub' + matrix mod4[4,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4_lb' + matrix mod4[7,`=4*(`p'-1)+`g'+`t'+1+4*`place'']=`delta`t'_`j'_`p'g`g'm4_p' + } + } + } + else { // groupe unique (=gp0) + qui lincom -[`p'.``=(`t'-1)*`nbitems'+`j''']_cons + local delta`t'_`j'_`p'g0m4= r(estimate) + local delta`t'_`j'_`p'g0m4_se= r(se) + local delta`t'_`j'_`p'g0m4_ub=r(ub) + local delta`t'_`j'_`p'g0m4_lb=r(lb) + local delta`t'_`j'_`p'g0m4_p=r(p) + if `p'>1{ + qui lincom [`=`p'-1'.``=(`t'-1)*`nbitems'+`j''']_cons - [`p'.``=(`t'-1)*`nbitems'+`j''']_cons + local delta`t'_`j'_`p'g0m4=r(estimate) + local delta`t'_`j'_`p'g0m4_se=r(se) + local delta`t'_`j'_`p'g0m4_ub=r(ub) + local delta`t'_`j'_`p'g0m4_lb=r(lb) + local delta`t'_`j'_`p'g0m4_p=r(p) + } + local place = 0 + local compt = 1 + while `compt' < `j' { + local place = `place' + `nbdif_`compt'' + local ++compt + } + if `t' == 1 { + matrix mod4[1,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4' + matrix mod4[2,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_se' + matrix mod4[3,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_ub' + matrix mod4[4,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_lb' + matrix mod4[7,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_p' + } + if `t' == 2 { + matrix mod4[1,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4' + matrix mod4[2,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_se' + matrix mod4[3,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_ub' + matrix mod4[4,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_lb' + matrix mod4[7,`=2*(`p'-1)+`t'+2*`place'']=`delta`t'_`j'_`p'g0m4_p' + } + } + } + } +} + +if "`group'" != "" { + matrix mod4[1,`=4*`nbmoda_sum'+1'] = (val_m4[1,"/var(THETA1)#0bn.`gp'"], val_m4[1,"/var(THETA2)#0bn.`gp'"]) + matrix mod4[2,`=4*`nbmoda_sum'+1'] = (val_m4[2,"/var(THETA1)#0bn.`gp'"],val_m4[2,"/var(THETA2)#0bn.`gp'"]) + matrix mod4[3,`=4*`nbmoda_sum'+1'] = (val_m4[6,"/var(THETA1)#0bn.`gp'"],val_m4[6,"/var(THETA2)#0bn.`gp'"]) + matrix mod4[4,`=4*`nbmoda_sum'+1'] = (val_m4[5,"/var(THETA1)#0bn.`gp'"],val_m4[5,"/var(THETA2)#0bn.`gp'"]) + + matrix mod4[1,`=4*`nbmoda_sum'+2+1'] = (val_m4[1,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod4[2,`=4*`nbmoda_sum'+2+1'] = (val_m4[2,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod4[3,`=4*`nbmoda_sum'+2+1'] = (val_m4[6,"/cov(THETA1,THETA2)#0.`gp'"]) + matrix mod4[4,`=4*`nbmoda_sum'+2+1'] = (val_m4[5,"/cov(THETA1,THETA2)#0.`gp'"]) + + matrix mod4[1,`=4*`nbmoda_sum'+2+1+1'] = `geffm4' + matrix mod4[2,`=4*`nbmoda_sum'+2+1+1'] = `segeffm4' + matrix mod4[3,`=4*`nbmoda_sum'+2+1+1'] = `ubgeffm4' + matrix mod4[4,`=4*`nbmoda_sum'+2+1+1'] = `lbgeffm4' + matrix mod4[5,`=4*`nbmoda_sum'+2+1+1'] = `gpm4chi' + matrix mod4[6,`=4*`nbmoda_sum'+2+1+1'] = `gpm4df' + matrix mod4[7,`=4*`nbmoda_sum'+2+1+1'] = `gpm4p' + + + matrix mod4[1,`=4*`nbmoda_sum'+2+1+1+1'] = `teffm4' + matrix mod4[2,`=4*`nbmoda_sum'+2+1+1+1'] = `seteffm4' + matrix mod4[3,`=4*`nbmoda_sum'+2+1+1+1'] = `ubteffm4' + matrix mod4[4,`=4*`nbmoda_sum'+2+1+1+1'] = `lbteffm4' + matrix mod4[5,`=4*`nbmoda_sum'+2+1+1+1'] = `tm4chi' + matrix mod4[6,`=4*`nbmoda_sum'+2+1+1+1'] = `tm4df' + matrix mod4[7,`=4*`nbmoda_sum'+2+1+1+1'] = `tm4p' + + if `yn_inter' == 1 { //Slmt si model avec interaction + matrix mod4[1,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[1,3] + matrix mod4[2,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[2,3] + matrix mod4[3,`=4*`nbmoda_sum'+2+1+1+1+1'] = `ubinterm4' + matrix mod4[4,`=4*`nbmoda_sum'+2+1+1+1+1'] = `lbinterm4' + matrix mod4[5,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[4,3] + matrix mod4[6,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[5,3] + matrix mod4[7,`=4*`nbmoda_sum'+2+1+1+1+1'] = effet[3,3] + } + +} +else { + matrix mod4[1,`=2*`nbmoda_sum'+1'] = (val_m4[1,"/var(THETA1)"],val_m4[1,"/var(THETA2)"]) + matrix mod4[2,`=2*`nbmoda_sum'+1'] = (val_m4[2,"/var(THETA1)"],val_m4[2,"/var(THETA2)"]) + matrix mod4[3,`=2*`nbmoda_sum'+1'] = (val_m4[6,"/var(THETA1)"],val_m4[6,"/var(THETA2)"]) + matrix mod4[4,`=2*`nbmoda_sum'+1'] = (val_m4[5,"/var(THETA1)"],val_m4[5,"/var(THETA2)"]) + + matrix mod4[1,`=2*`nbmoda_sum'+2+1'] = (val_m4[1,"/cov(THETA1,THETA2)"]) + matrix mod4[2,`=2*`nbmoda_sum'+2+1'] = (val_m4[2,"/cov(THETA1,THETA2)"]) + matrix mod4[3,`=2*`nbmoda_sum'+2+1'] = (val_m4[6,"/cov(THETA1,THETA2)"]) + matrix mod4[4,`=2*`nbmoda_sum'+2+1'] = (val_m4[5,"/cov(THETA1,THETA2)"]) + + matrix mod4[1,`=2*`nbmoda_sum'+2+1+1'] = `teffm4' + matrix mod4[2,`=2*`nbmoda_sum'+2+1+1'] = `seteffm4' + matrix mod4[3,`=2*`nbmoda_sum'+2+1+1'] = `ubteffm4' + matrix mod4[4,`=2*`nbmoda_sum'+2+1+1'] = `lbteffm4' + matrix mod4[5,`=2*`nbmoda_sum'+2+1+1'] = `tm4chi' + matrix mod4[6,`=2*`nbmoda_sum'+2+1+1'] = `tm4df' + matrix mod4[7,`=2*`nbmoda_sum'+2+1+1'] = `tm4p' +} + + + /* Affichage des estimations des difficultĂ©s */ +di _col(5) in ye "{ul:MODEL 4} = Final model" +di +di _col(10) in ye "Item difficulties estimates (s.e.)" +if "`group'" != "" { + di _col(10) "{hline 85}" + di _col(30) "Time 1" _col(70) "Time 2" + di in ye _col(20) abbrev("`gp'",15) "=0" _col(38) abbrev("`gp'",15) "=1" _col(58) abbrev("`gp'",15) "=0" _col(76) abbrev("`gp'",15) "=1" + di _col(10) "{hline 85}" +} +else { + di _col(10) "{hline 50}" + di _col(30) "Time 1" _col(45) "Time 2" + di _col(10) "{hline 50}" +} + +forvalues j=1/`nbitems' { + di in ye _col(10) "``j''" + forvalues p=1/`nbdif_`j'' { + if "`group'" != "" { + di in gr _col(10) "`p'" _col(20) %6.2f `delta1_`j'_`p'g0m4' " (" %4.2f `delta1_`j'_`p'g0m4_se' ")" _col(38) %6.2f `delta1_`j'_`p'g1m4' " (" %4.2f `delta1_`j'_`p'g1m4_se' ")" /// + _col(58) %6.2f `delta2_`j'_`p'g0m4' " (" %4.2f `delta2_`j'_`p'g0m4_se' ")" _col(76) %6.2f `delta2_`j'_`p'g1m4' " (" %4.2f `delta2_`j'_`p'g1m4_se' ")" + } + else { + di in gr _col(10) "`p'" _col(25) %6.2f `delta1_`j'_`p'g0m4' " (" %4.2f `delta1_`j'_`p'g0m4_se' ")" _col(42) %6.2f `delta2_`j'_`p'g0m4' " (" %4.2f `delta2_`j'_`p'g0m4_se' ")" + } + } +} + +if "`group'" != "" { + di _col(10) "{hline 85}" +} +else { + di _col(10) "{hline 50}" +} + + /* Affichage des estimations sur le trait latent du modĂšle final */ +di +di _col(10) in ye "Latent trait distribution estimates" +di _col(10) "{hline 80}" +di _col(45) in ye "Estimate" _col(60) "Standard error" _col(77) "P-value" +di _col(10) "{hline 80}" + +if "`group'" == "" { + local fact_k = 2 +} +else { + local fact_k = 4 +} + +di _col(10) in ye "Variance Time 1" in gr _col(44) %6.2f `=mod4[1,`=`fact_k'*`nbmoda_sum'+1']' _col(62) %6.2f =mod4[2,`=`fact_k'*`nbmoda_sum'+1'] +di _col(10) in ye "Variance Time 2" in gr _col(44) %6.2f `=mod4[1,`=`fact_k'*`nbmoda_sum'+2']' _col(62) %6.2f `=mod4[2,`=`fact_k'*`nbmoda_sum'+2']' +di _col(10) in ye "Covariance" in gr _col(44) %6.2f `=mod4[1,`=`fact_k'*`nbmoda_sum'+3']' _col(62) %6.2f `=mod4[2,`=`fact_k'*`nbmoda_sum'+3']' + +if "`group'" != "" { + + di _col(10) in ye "Group effect (mean gp 1 at T1)" in gr _col(44) %6.2f `geffm4' _col(62) %6.2f `segeffm4' _col(77) %6.4f `gpm4p' +} +di _col(10) in ye "Time effect (mean gp 0 at T2)" in gr _col(44) %6.2f `teffm4' _col(62) %6.2f `seteffm4' _col(77) %6.4f `tm4p' + +if "`group'" != "" { + if effet[3,3] < 0.05 { + di _col(10) in ye "TimexGroup inter" in gr _col(44) %6.2f effet[1,3] _col(62) %6.2f effet[2,3] _col(77) %6.4f effet[3,3] + } + else { + di _col(10) in ye "TimexGroup inter" in gr _col(44) "0 (constrained)" + } +} + +di _col(10) "{hline 80}" + +/***************************************/ +/* Calcul des valeurs de DIF et de RC */ +/*************************************/ + +forvalues j=1/`nbitems' { + if `nbmoda_`j'' >= 2 { + matrix valeur_difrc_`j' = J(`nbdif_`j'',8,.) + matrix colnames valeur_difrc_`j' = DIFT1 DIFT1_SE RC_GP0 RC_GP0_SE RC_GP1 RC_GP1_SE + } +} + +forvalues j=1/`nbitems'{ + if `nbmoda_`j'' >= 2 { + if "`group'" != "" { + *DIF + if "`nodif'"=="" { + if (dif_rc[`j',1] != . ) { + forvalues p=1/`nbdif_`j'' { + if `p' == 1 { + qui lincom -[1.``j'']:1.`gp'+[1.``j'']:0.`gp' + matrix valeur_difrc_`j'[`p',1] = r(estimate) + matrix valeur_difrc_`j'[`p',2] = round(r(se),0.01) + } + if `p' > 1 { + qui lincom [`=`p'-1'.``j'']:1.`gp' - [`p'.``j'']:1.`gp' -[`=`p'-1'.``j'']:0.`gp' + [`p'.``j'']:0.`gp' + matrix valeur_difrc_`j'[`p',1] = r(estimate) + matrix valeur_difrc_`j'[`p',2] = round(r(se),0.01) + } + } + } + } + *RC GROUP 0 + if (dif_rc[`j',3] != . & dif_rc[`j',5] != . ) { + forvalues p=1/`nbdif_`j'' { + qui lincom -[1.``=`j'+`nbitems''']:0.`gp' + [1.``j'']:0.`gp' + matrix valeur_difrc_`j'[`p',3] = r(estimate) + matrix valeur_difrc_`j'[`p',4] = round(r(se),0.01) + if `p' > 1 { + qui lincom [`=`p'-1'.``=`j'+`nbitems''']:0.`gp' - [`p'.``=`j'+`nbitems''']:0.`gp' -[`=`p'-1'.``j'']:0.`gp' + [`p'.``j'']:0.`gp' + matrix valeur_difrc_`j'[`p',3] = r(estimate) + matrix valeur_difrc_`j'[`p',4] = round(r(se),0.01) + } + } + } + *RC GROUP 1 + if (dif_rc[`j',3] != . & dif_rc[`j',7] != . ) { + forvalues p=1/`nbdif_`j'' { + qui lincom -[1.``=`j'+`nbitems''']:1.`gp' + [1.``j'']:1.`gp' + matrix valeur_difrc_`j'[`p',5] = r(estimate) + matrix valeur_difrc_`j'[`p',6] = round(r(se),0.01) + if `p' > 1 { + qui lincom [`=`p'-1'.``=`j'+`nbitems''']:1.`gp' - [`p'.``=`j'+`nbitems''']:1.`gp' -[`=`p'-1'.``j'']:1.`gp' + [`p'.``j'']:1.`gp' + matrix valeur_difrc_`j'[`p',5] = r(estimate) + matrix valeur_difrc_`j'[`p',6] = round(r(se),0.01) + } + } + } + } + else { + forvalues p=1/`nbdif_`j'' { + qui lincom -[1.``=`j'+`nbitems''']_cons + [1.``j'']_cons + matrix valeur_difrc_`j'[`p',3] = r(estimate) + matrix valeur_difrc_`j'[`p',4] = round(r(se),0.01) + if `p' > 1 { + qui lincom [`=`p'-1'.``=`j'+`nbitems''']_cons - [`p'.``=`j'+`nbitems''']_cons -[`=`p'-1'.``j'']_cons + [`p'.``j'']_cons + matrix valeur_difrc_`j'[`p',3] = r(estimate) + matrix valeur_difrc_`j'[`p',4] = round(r(se),0.01) + } + } + } + } +} + +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' >= 2 { + forvalues p = 1/`nbdif_`j'' { + forvalues k = 1/8 { + if valeur_difrc_`j'[`p',`k'] == . { + matrix valeur_difrc_`j'[`p',`k'] = 0 + } + } + } + } +} + + /* Affichage des estimations des valeurs de DIF et de RC */ +if "`group'" != "" { + di + di _col(10) in ye "Values of differences between groups and values of recalibration" +} +else { + di + di _col(10) in ye "Values of recalibration" +} +if "`group'" != "" & "`nodif'"==""{ + di _col(10) "{hline 70}" + di _col(30) "Difference of" _col(52) "RECALIBRATION" + di _col(30) "groups at T1" _col(47) in ye abbrev("`gp'",15) "=0" _col(62) abbrev("`gp'",15) " =1" + di _col(10) "{hline 70}" +} +else if "`group'" != "" & "`nodif'"!="" { + di _col(10) "{hline 50}" + di _col(32) "RECALIBRATION" + di in ye _col(27) "`gp'=`=rep[1,1]'" _col(47) "`gp'=`=rep[2,1]'" + di _col(10) "{hline 50}" +} +else { + di _col(10) "{hline 30}" + di _col(15) "RECALIBRATION" + di _col(10) "{hline 30}" +} + +forvalues j=1/`nbitems' { + if `nbmoda_`j'' >= 2 { + if "`group'" != "" & "`nodif'" == "" { + di in ye _col(10) "``j''" + } + else { + di in ye _col(10) "``j''" + } + forvalues p=1/`nbdif_`j'' { + if "`group'" != "" & "`nodif'"=="" { + di in gr _col(10) "`p'" _col(29) %6.2f `=valeur_difrc_`j'[`p',1]' " (" %4.2f `=valeur_difrc_`j'[`p',2]' ")" /// + _col(47) %6.2f `=valeur_difrc_`j'[`p',3]' " (" %4.2f `=valeur_difrc_`j'[`p',4]' ")" _col(62) %6.2f `=valeur_difrc_`j'[`p',5]' " (" %4.2f `=valeur_difrc_`j'[`p',6]' ")" + } + else if "`group'" != "" & "`nodif'"!="" { + di in gr _col(10) "`p'" _col(25) %6.2f `=valeur_difrc_`j'[`p',3]' " (" %4.2f `=valeur_difrc_`j'[`p',4]' ")" _col(45) %6.2f `=valeur_difrc_`j'[`p',5]' " (" %4.2f `=valeur_difrc_`j'[`p',6]' ")" + } + else { + di in gr _col(10) "`p'" _col(25) %6.2f `=valeur_difrc_`j'[`p',3]' " (" %4.2f `=valeur_difrc_`j'[`p',4]' ")" + } + } + } +} + +if "`group'" != "" & "`nodif'"=="" { + di _col(10) "{hline 70}" +} +else if "`group'" != "" & "`nodif'"!=""{ + di _col(10) "{hline 50}" +} +else { + di _col(10) "{hline 30}" +} +di + + +******************************************************************************* +* New outputs + +if "`group'" == "" { + matrix testlrm = J(1,3,.) + matrix colnames testlrm = chi_square df pvalue + matrix rownames testlrm = m1_vs_m2 + matrix testlrm[1,1] = (`rstestchi',`rstestdf',`rstestp') + return matrix test_model = testlrm +} +else if "`nodif'" != "" { + matrix testlrm = J(1,3,.) + matrix colnames testlrm = chi_square df pvalue + matrix rownames testlrm = m1_vs_m2 + matrix testlrm[1,1] = (`rstestchi',`rstestdf',`rstestp') + return matrix test_model = testlrm +} +else { + matrix testlrm = J(2,3,.) + matrix colnames testlrm = chi_square df pvalue + matrix rownames testlrm = mA_vs_mB m1_vs_m2 + matrix testlrm[1,1] = (`diftestchi',`diftestdf',`diftestp') + matrix testlrm[2,1] = (`rstestchi',`rstestdf',`rstestp') + return matrix test_model = testlrm +} + +return matrix model_4 = mod4 +return matrix model_2 = mod2 + +capture qui use `saverspcm', clear + +end + diff --git a/Modules/ado/personal/r/rsbynpirt.ado b/Modules/ado/personal/r/rsbynpirt.ado new file mode 100644 index 0000000..1f44d07 --- /dev/null +++ b/Modules/ado/personal/r/rsbynpirt.ado @@ -0,0 +1,162 @@ +*! Version 1 20July2015 +************************************************************************************************************ +* rsbynpirt: Traces of items +* Version 1: July 20, 2015 /*ICC*/ +* +* Historic: +* Version 1 (2015-07-20): Jean-Benoit Hardouin +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* News about this program :http://www.anaqol.org +* +* Copyright 2015 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define rsbynpirt +version 8.0 +syntax varlist(numeric min=4) [, noGraph] + +preserve +local nbitems : word count `varlist' +tokenize `varlist' +if mod(`nbitems',2)!=0 { + di in red "You must indicate an even number of items" + exit +} +else { + local nbitems=`nbitems'/2 +} +local listofitems1 +local listofitems2 +forvalues i=1/`nbitems' { + local listofitems1 `listofitems1' ``i'' + local listofitems2 `listofitems2' ``=`i'+`nbitems''' +} + +tempvar varscore1 varscore2 +qui gen `varscore1'=0 +qui gen `varscore2'=0 +label variable `varscore1' "Total score time 1" +label variable `varscore2' "Total score time 2" +local scoremax=0 +local flag=0 + + + +local modamax=0 +forvalues i=1/`nbitems' { + qui replace `varscore1'=`varscore1'+``i'' + qui replace `varscore2'=`varscore2'+``=`i'+`nbitems''' + qui su ``i'' + local modamax`i'=r(max) + qui su ``=`i'+`nbitems''' + local modamax`i'=r(max) + if r(min)!=0 { + local flag=1 + } + local scoremax=`scoremax'+`modamax`i'' + if `modamax`i''!=1 { + local flagbin=0 + } + if `modamax`i''>`modamax' { + local modamax=`modamax`i'' + } +} + + +if `flag'==1 { + di as error "The lower modality of the item must be 0" + exit +} +if "`flagbin'"!=""&"`logistic'"!="" { + di as error "The logistic option is not possible with polytomous items" + exit +} + +qui su `varscore1' +local maxscore=r(max) +qui su `varscore1' +if `r(max)'>`maxscore' { + local maxscore=r(max) +} +tempfile rsbynpirtfile rsbynpirtfile1 rsbynpirtfile2 +tempvar score +qui save `rsbynpirtfile', replace +qui traces `listofitems1', nograph icc saveicc +qui drop _all +*matrix list r(matscore) +tempname mat1 +qui matrix `mat1'=r(matscore) +qui svmat `mat1', names(t1item) +forvalues i=1/`nbitems' { + local j: word `i' of `listofitems1' + qui rename t1item`i' `j' +} +qui rename t1item`=`nbitems'+1' `score' +qui contract `score' `listofitems1' +qui sort `score' +qui save `rsbynpirtfile1', replace + +qui use `rsbynpirtfile', clear +qui traces `listofitems2', nograph icc saveicc +qui drop _all +tempname mat2 +qui matrix `mat2'=r(matscore) +qui svmat `mat2', names(t2item) +forvalues i=1/`nbitems' { + local j: word `i' of `listofitems2' + qui rename t2item`i' `j' +} +qui rename t2item`=`nbitems'+1' `score' +qui contract `score' `listofitems2' +qui sort `score' +qui merge 1:1 `score' using `rsbynpirtfile1' + +if "`graph'"=="" { + forvalues i=1/`nbitems' { + twoway (line ``i'' `score') (line ``=`i'+`nbitems''' `score'), name(``i'',replace) + } +} +qui drop if `score'==0|`score'==`scoremax' + +di +di "Items" _col(18) "AUC t1" _col(28) "AUC t2" _col(38) "Var AUC" _col(46) "Diff ICC" _col(57) "SD Diff" +di "{hline 63}" +forvalues i=1/`nbitems' { + qui su ``i'' + local AUC``i''=r(sum) + local AUC``i''=(`AUC``i'''+`modamax`i''/2)/(`scoremax'*`modamax`i'')*100 + qui su ``=`i'+`nbitems''' + local AUC`=`i'+`nbitems''=r(sum) + local AUC`=`i'+`nbitems''=(`AUC`=`i'+`nbitems'''+`modamax`i''/2)/(`scoremax'*`modamax`i'')*100 + tempname diff``i'' + gen `diff``i'''=abs(``i''-``=`i'+`nbitems''') + qui su `diff``i''' + local d``i''=`r(sum)'/(`scoremax'*`modamax`i'')*100 + local var``i''=`r(sd)'*100 + di "``i''/``=`i'+`nbitems'''" _col(20) %4.1f `AUC``i''' _col(30) %4.1f `AUC`=`i'+`nbitems''' _col(40) %5.1f `=`AUC``i'''-`AUC`=`i'+`nbitems'''' _col(50) %4.1f `d``i''' _col(60) %4.1f `var``i''' +} +qui restore , preserve +end + + diff --git a/Modules/ado/personal/r/rsoort.ado b/Modules/ado/personal/r/rsoort.ado new file mode 100644 index 0000000..12f5163 --- /dev/null +++ b/Modules/ado/personal/r/rsoort.ado @@ -0,0 +1,832 @@ +*! version 1.4 29January2014 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* rsoort: Response Shift detection with the Oort procedure +* +* Historic: +* Version 1 (2013-02-25): Jean-Benoit Hardouin +* Version 1.1 (2013-06-03): Jean-Benoit Hardouin /*some improvements*/ +* Version 1.2 (2013-06-03): Jean-Benoit Hardouin /*model1 model2 model3 and covariances options*/ +* Version 1.3 (2013-06-03): Jean-Benoit Hardouin /**/ +* Version 1.4 (2014-01-29): Jean-Benoit Hardouin /*add an iterate option on model 1*/ +* +* +* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France +* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam" +* jean-benoit.hardouin@univ-nantes.fr +* +* Copyright 2013-2014 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + + +program define rsoort,eclass +syntax varlist(min=2 numeric) [if] [in] [,METHod(string) nom1 nocov12 UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPrioritization(varlist) noSearch html(string) model1 model2 model4 COVariances(string) MATrixrs(string)] +tempfile saversoort +qui save `saversoort',replace +preserve +if "`matrixrs'"!="" { + if "`uniformrecalibration'"!="" { + di in red "You cannot use the {bf:matrixrs} and the {bf:uniformrecalibration} options in the same time" + error + } + if "`nonuniformrecalibration'"!="" { + di in red "You cannot use the {bf:matrixrs} and the {bf:nonuniformrecalibration} options in the same time" + error + } + if "`reprioritization'"!="" { + di in red "You cannot use the {bf:matrixrs} and the {bf:reprioritization} options in the same time" + error + } +} + + +if "`html'" != "" { + di "" +} + + +if "`if'"!=""|"`in'"!="" { + qui keep `if' `in' +} + +tokenize `varlist' +local nbitems:word count `varlist' +local mod=mod(`nbitems',2) +if `mod'!=0 { + di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2" + error +} + +if "`method'"=="" { + local method "ml" +} +local nbitems=`nbitems'/2 + +if "`html'"== "" { + di _col(20) "{hline 30}" + di _col(20) in gr "Time 1" _col(40) "Time 2" + di _col(20) "{hline 30}" + forvalues i=1/`nbitems' { + di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''" + } + di _col(20) "{hline 30}" +} +else { + di "" + di "" + di "" + di "" + forvalues i=1/`nbitems' { + di "" + } + di "
Time 1Time2
``i''``=`i'+`nbitems'''
" +} + +/************************************************************************************************************** +Model 1 +***************************************************************************************************************/ + +if "`model1'"=="" { + local qui qui +} +else { + local qui +} +local cov12b +forvalues i=1/`nbitems' { + local cov12b `cov12b' e.``i''*e.``=`i'+`nbitems''' +} +if "`cov12'"!="" { + local cov12b +} +if "`m1'"=="" { +`qui' sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method') cov(`cov12b' `covariances') iterate(100) +qui estat gof, stat(all) +local tli1=r(tli) +local cfi1=r(cfi) +local srmr1=r(srmr) +local rmsea1=r(rmsea) +local ubrmsea1=r(ub90_rmsea) +local lbrmsea1=r(lb90_rmsea) +local chi21=r(chi2_ms) +local df1=r(df_ms) +local dfc1=6*`nbitems'+1 +local p1=r(p_ms) +local bic1=r(bic) +} +else { +local chi21=. +local df1=. +} +*di +*di in green " ***********************************Model 1********************************************" +*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI" +*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1' + +/************************************************************************************************************** +Model 2 +***************************************************************************************************************/ + +local sem +local var +forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local sem `sem' `sem`i'' + local var `var' `var`i'' +} + +if "`model2'"=="" { + local qui qui +} +else { + local qui +} + +di "`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances')" +`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances') +tempname b V +matrix `b'=e(b) +matrix `V'=e(V) +local truechange2=`b'[1,`=`nbitems'*4+1'] +local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1'] +qui estat gof, stat(all) +local tli2=r(tli) +local cfi2=r(cfi) +local srmr2=r(srmr) +local rmsea2=r(rmsea) +local ubrmsea2=r(ub90_rmsea) +local lbrmsea2=r(lb90_rmsea) +local chi22=r(chi2_ms) +local df2=r(df_ms) +local dfc2=3*`nbitems'+3 +local p2=r(p_ms) +local bic2=r(bic) + +local chi221=abs(`chi21'-`chi22') +local df21=`df2'-`df1' +local p21=1-chi2(`df21',`chi221') + +if "`html'" != "" { + di "" + di "" + *di "" + di "" + di "" + di "" + di "" + di "
Test of global Response-ShiftComparison with model 1
ModelsChi-squaredfp-valueBIC
Model 1" %8.2f `chi21' "" %4.0f `df1' "" %6.4f `p1' "" %7.2f `bic1' "
Model 2" %8.2f `chi22' "" %4.0f `df2' "" %6.4f `p2' "" %7.2f `bic2' "
" +} +else { + di "{hline 51}" + di in gr /*_col(39) "Test of global Response-Shift " _col(79) "Comparison with model 1"*/ + di in gr "Models" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" /*_col(39) "Chi-square" _col(54) "df" _col(59) "p-value" *_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 51}" + di in gr "Model 1" _col(20) %8.2f in ye `chi21' _col(30) %4.0f `df1' _col(37) %6.4f `p1' _col(45) %7.2f `bic1' + di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(30) %4.0f `df2' _col(37) %6.4f `p2' _col(45) %7.2f `bic2' /*_col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' *_col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'*/ + di "{hline 51}" +} + + +/************************************************************************************************************** +Model 3 +***************************************************************************************************************/ + + +/************************************************************************************************************** +Model 3 / Non uniform recalibration +***************************************************************************************************************/ + +tempname RS RSprec +qui matrix `RS'=J(`nbitems',3,0) +qui matrix `RSprec'=J(`nbitems',3,0) +local df3=`dfc2' + +*set trace on + +if "`matrixrs'"=="" { + forvalues i=1/`nbitems' { + local nbUR:word count `uniformrecalibration' + forvalues j=1/`nbUR' { + local itemj: word `j' of `uniformrecalibration' + if "``i''"=="`itemj'" { + matrix `RS'[`i',2]=1 + } + } + local nbNUR:word count `nonuniformrecalibration' + forvalues j=1/`nbNUR' { + local itemj: word `j' of `nonuniformrecalibration' + if "``i''"=="`itemj'" { + matrix `RS'[`i',1]=1 + } + } + local nbR:word count `reprioritization' + forvalues j=1/`nbR' { + local itemj: word `j' of `reprioritization' + if "``i''"=="`itemj'" { + matrix `RS'[`i',3]=1 + } + } + } +} +else { + matrix `RS'=`matrixrs' +} +*matrix list `RS' + +if "`search'"=="" { + + if "`html'"=="" { + di + di "{hline 88}" + di in green _col(40) "Model 3" + di "{hline 88}" + di + di in white _col(10) "Non uniform Recalibration" + } + else { + di "


Model 3

" + di "" + di "" + } + local continue=1 + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + } + local prec_chi2=`chi22' + local testNU_varchi2=0 + local testNU_p=1 + + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + while (`continue') { + local cpt=0 + local testNU_varchi2_temp=0 + local testNU_p_temp=0 + local testNU_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + local var + forvalues j=1/`nbitems' { + local sem + local var + local already=0 + forvalues i=1/`nbitems' { + if `RS'[`i',1]==0&`i'!=`j' { + local sem `sem' `sem`i'' + local var `var' `var`i'' + } + if `RS'[`i',1]==1&`i'!=`j' { + local sem `sem' `sem`i'' + local var `var' `varrecNU`i'' + } + else if `i'==`j'&`RS'[`j',1]==0 { + local sem `sem' `sem`i'' + local var `var' `varrecNU`i'' + } + else if `i'==`j'&`RS'[`j',1]==1 { + local sem `sem' `sem`i'' + local var `var' `varrecNU`i'' + local already=1 + } + } + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances') + qui estat gof + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') { + local continue=1 + local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp') + local testNU_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + } + if ( `chi2encours'<`prec_chi2') { + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + } + else { + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable" + } + } + local ++cpt + } + } + if (`testNU_item_temp'!=0) { + matrix `RS'[`testNU_item_temp',1]=1 + local ++df3 + local testNU_varchi2=`testNU_varchi2_temp' + local testNU_p=`testNU_p_temp' + local testNU_item_temp=0 + local prec_chi2=`tmp' + } + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Non uniform Recalibration
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "
``j''Unavailable

" + } + + + + /************************************************************************************************************** + Model 3 / Uniform recalibration + ***************************************************************************************************************/ + + if "`html'"=="" { + di + di in white _col(10) "Uniform Recalibration" + } + else { + di "" + di "" + } + local continue=1 + local var + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + } + local testU_varchi2=0 + local testU_p=1 + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + while (`continue') { + local cpt=0 + local testU_varchi2_temp=0 + local testU_p_temp=0 + local testU_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + forvalues j=1/`nbitems' { + local sem + local already=0 + forvalues i=1/`nbitems' { + if `RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `sem`i'' + } + if `RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecU`i'' + } + else if `i'==`j'&`RS'[`j',2]==0 { + local sem `sem' `semrecU`i'' + } + else if `i'==`j'&`RS'[`j',2]==1 { + local sem `sem' `semrecU`i'' + local already=1 + } + } + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances') + qui estat gof + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') { + local continue=1 + local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local testU_p_temp =1-chi2(1,`testU_varchi2_temp') + local testU_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + } + + if ( `chi2encours'<`prec_chi2') { + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + } + else { + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable" + } + } + local ++cpt + } + } + if (`testU_item_temp'!=0) { + matrix `RS'[`testU_item_temp',2]=1 + local ++df3 + local testU_varchi2=`testU_varchi2_temp' + local testU_p=`testU_p_temp' + local testU_item_temp=0 + local prec_chi2=`tmp' + } + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Uniform Recalibration
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "
``j''Unavailable

" + } + + + + + /************************************************************************************************************** + Model 3 / Reprioritization + ***************************************************************************************************************/ + + if "`html'"=="" { + di + di in white _col(10) "Reprioritization" + } + else { + di "" + di "" + } + + local continue=1 + local var + local sem + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + } + local testU_varchi2=0 + local testU_p=1 + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + while (`continue') { + local cpt=0 + local testR_varchi2_temp=0 + local testR_p_temp=0 + local testR_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + forvalues j=1/`nbitems' { + local sem + local already=0 + forvalues i=1/`nbitems' { + if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `sem`i'' + } + else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecU`i'' + } + else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `semrep`i'' + } + else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecUrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 { + local sem `sem' `semrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 { + local sem `sem' `semrecUrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 { + local already=1 + } + else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 { + local sem `sem' `semrep`i'' + local already=1 + } + else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 { + local sem `sem' `semrecUrep`i'' + local already=1 + } + } + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances') + qui estat gof + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') { + local continue=1 + local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local testR_p_temp =1-chi2(1,`testR_varchi2_temp') + local testR_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + } + if ( `chi2encours'<`prec_chi2') { + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + } + else { + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable" + } + } + local ++cpt + } + } + if (`testR_item_temp'!=0) { + matrix `RS'[`testR_item_temp',3]=1 + local ++df3 + local testR_varchi2=`testR_varchi2_temp' + local testR_p=`testR_p_temp' + local testR_item_temp=0 + local prec_chi2=`tmp' + } + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Reprioritization
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "
``j''Unavailable

" + } +} + +/************************************************************************************************************** +Model 3 Final +***************************************************************************************************************/ + +di +local continue=1 +local var +local sem +forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + if `RS'[`i',2]==0&`RS'[`i',3]==0 { + local sem "`sem' `sem`i''" + } + if `RS'[`i',2]==0&`RS'[`i',3]==1 { + local sem "`sem' `semrep`i''" + } + if `RS'[`i',2]==1&`RS'[`i',3]==0 { + local sem "`sem' `semrecU`i''" + } + if `RS'[`i',2]==1&`RS'[`i',3]==1 { + local sem "`sem' `semrecUrep`i''" + } +} + qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances') +tempname b V +matrix `b'=e(b) +matrix `V'=e(V) +local truechange=`b'[1,`=`nbitems'*4+1'] +local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1'] +qui estat gof +local tli3=r(tli) +local cfi3=r(cfi) +local srmr3=r(srmr) +local rmsea3=r(rmsea) +local ubrmsea3=r(ub90_rmsea) +local lbrmsea3=r(lb90_rmsea) +local chi23=r(chi2_ms) +local dfc3=`df3' +local p3=r(p_ms) +local bic3=r(bic) + + +/************************************************************************************************************** +Bilan +***************************************************************************************************************/ + +if "`html'"=="" { + di + di "{hline 74}" + di in gr _col(22) "Non uniform" _col(46) "Uniform" + di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(58) "Reprioritization" + di "{hline 74}" +} +else { + di "" + di "" + di "" + di "" +} +forvalues i=1/`nbitems' { + local recNU + local recU + local rep + if (`RS'[`i',1]==1) { + local recNU "*" + } + if (`RS'[`i',2]==1) { + local recU "*" + } + if (`RS'[`i',3]==1) { + local rep "*" + } + if "`html'"=="" { + di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'" + } + else { + di "" + } +} +if "`html'"=="" { + di "{hline 74}" +} +else { + di "
ItemsNon-uniform
Recalibration
Uniform
Recalibration

Repriorisation
``i''`recNU'`recU'`rep'
" +} + + +/************************************************************************************************************** +Model 4 +***************************************************************************************************************/ + +if "`model4'"=="" { + local qui qui +} +else { + local qui +} +`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) cov(`cov12b' `covariances') method(`method') +tempname b V +matrix `b'=e(b) +matrix `V'=e(V) +local truechange=`b'[1,`=`nbitems'*4+1'] +local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1'] +qui estat gof,stat(all) +local tli4=r(tli) +local cfi4=r(cfi) +local srmr4=r(srmr) +local rmsea4=r(rmsea) +local ubrmsea4=r(ub90_rmsea) +local lbrmsea4=r(lb90_rmsea) +local chi24=r(chi2_ms) +local df4=r(df_ms) +local dfc4=`df3'+1 +local p4=r(p_ms) +local chi2encours=r(chi2_ms) +local bic4=r(bic) + +local z=`truechange'/sqrt(`Vtruechange') + +if "`html'" != "" { + di "" + di "" + di "" + di "" + if "`m1'"=="" { + di "" + } + di "" + di "" + di "
Modelschi2dfpBICRMSEAIC90%(RMSEA)SRMRCFITLI
Model 1" %8.2f `chi21' "" %4.0f `df1' "" %7.2f `bic1' "" %6.4f `p1' "" %6.4f `rmsea1' "" %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' "" %6.4f `srmr1' "" %6.2f `cfi1' "" %6.2f `tli1' "
Model 2" %8.2f `chi22' "" %4.0f `df2' "" %7.2f `bic2' "" %6.4f `p2' "" %6.4f `rmsea2' "" %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' "" %6.4f `srmr2' "" %6.2f `cfi2' "" %6.2f `tli2' "
Model 4" %8.2f `chi24' "" %4.0f `df4' "" %7.2f `bic4' "" %6.4f `p4' "" %6.4f `rmsea4' "" %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' "" %6.4f `srmr4' "" %6.2f `cfi4' "" %6.2f `tli4' "
" +} +else { + di + di "{hline 95}" + di in gr "Models" _col(14) "chi2" _col(22) "df" _col(31) "p" _col(40) "BIC" _col(47) "RMSEA" _col(55) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI" + di "{hline 95}" + if "`m1'"=="" { + di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `df1' _col(26) %6.4f `p1' _col(36) %7.2f `bic1' _col(46) %6.4f `rmsea1' _col(54) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1' + } + di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `df2' _col(26) %6.4f `p2' _col(36) %7.2f `bic2' _col(46) %6.4f `rmsea2' _col(54) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2' + *di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3' _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3' + di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `df4' _col(26) %6.4f `p4' _col(36) %7.2f `bic4' _col(46) %6.4f `rmsea4' _col(54) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4' + di "{hline 95}" +} + + +if "`html'" != "" { + di "" + di "" + di "" + di "" + di "" + di "" + di "
Estimations.e.zp-value
True change (Model 2)" %8.4f `truechange2' "" %8.4f `=sqrt(`Vtruechange2')' "" %6.2f `=`truechange2'/sqrt(`Vtruechange2')' "" %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))' "
True change (Model 4)" %8.4f `truechange' "" %8.4f `=sqrt(`Vtruechange')' "" %6.2f `=`truechange'/sqrt(`Vtruechange')' "" %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))' "
" +} +else { + di + di "{hline 77}" + di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value" + di "{hline 77}" + di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))' + di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))' + di "{hline 77}" + di +} +qui use `saversoort',clear + + + +end diff --git a/Modules/ado/personal/r/rsoort.hlp b/Modules/ado/personal/r/rsoort.hlp new file mode 100644 index 0000000..3acb1a6 --- /dev/null +++ b/Modules/ado/personal/r/rsoort.hlp @@ -0,0 +1,69 @@ +{smcl} +{* 3June2013}{...} +{hline} +help for {hi:rsoort}{right:Jean-Benoit Hardouin} +{hline} + +{title: Oort's Structural Equations Modeling (SEM) based procedure to detect Response Shift} + +{p 8 14 2}{cmd:rsoort} {it:varlist} {ifin} [{cmd:,} {cmdab:meth:od}({it:string}) {cmdab:unif:ormrecalibration}({it:varlist}) {cmdab:nonunif:ormrecalibration}({it:varlist}) {cmdab:rep:rioritization}({it:varlist}) {cmdab:nos:earch}] + +{p 8 14 2}{it:varlist} is a list of two or more existing variables. You must first enter the list of variables to first measurement followed by the list of variables (in the same order) in the second measurement time. + +{title:Description} + +{p 4 8 2}{cmd:rsoort} provides the Oort's procedure based on Structural Equation Modeling (SEM) in order to detect Response-Shift in a set of variables. + +{title:Options} + +{p 4 8 2}{cmd:method}. By default, maximum likelihood estimations of the models parameters are used. You can use alternative methods of estimation like {cmd:mlmv} for +maximum likelihood handling missing data or {cmd:adf} for asymptotic distribution free method. + +{p 4 8 2}{cmd:uniformrecalibation} allows defining variables suspected to be affected by uniform recalibration (you should give the name of the variable to the first +measurement). In this case, the procedure force the concerned variable to be affected by uniform recalibration and this kind of response-shift is searched only on the +other variables. + +{p 4 8 2}{cmd:nonuniformrecalibation} allows defining variables suspected to be affected by non uniform recalibration (you should give the name of the variable to the +first measurement). In this case, the procedure force the concerned variable to be affected by non uniform recalibration and this kind of response-shift is searched +only on the other variables. + +{p 4 8 2}{cmd:reprioritization} allows defining variables suspected to be affected by reprioritization (you should give the name of the variable to the first +measurement). In this case, the procedure force the concerned variable to be affected by reprioritization and this kind of response-shift is searched only on the other +variables. + +{p 4 8 2}{cmd:nosearch} avoids the procedure to be run (this is useful only if you precise the {cmd:uniformrecalibation}, {cmd:nonuniformrecalibation} or +{cmd:reprioritization} options) + + + +{title:Example} + + {p 8 8}{inp:. rsoort var1t1-var10t1 var1t2-var10t2} + + {p 8 8}{inp:. rsoort var1t1-var10t1 var1t2-var10t2, unif(var3t1 var7t1) rep(var8t1)} + + {p 8 8}{inp:. rsoort var1t1-var10t1 var1t2-var10t2, unif(var3t1 var7t1) rep(var8t1) nosearch} + + +{title:References} + +{p 4 8 2}Oort F.J. Using structural equation modeling to detect response shifts and true change. {it: Quality of life Research}, vol.14(3), 2005, pp. 587-598. + +{p 4 8 2}Oort F.J., Visser M.R., Sprangers M.A. An application of structural equation modeling to detect response shifts and true change in quality of life data from cancer patients undergoing invasive surgery. {it: Quality of life Research}, vol.14(3), 2005, pp. 599-609. + +{p 4 8 2}Oort F.J. Towards a formal definition of response shift (in reply to G.W. Donaldson)., {it: Quality of life Research}, vol.14(10), 2005, pp. 2353-2355. + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end} +{p 4 8 2}EA 4275-SPHERE "Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences"{p_end} +{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end} +{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end} +{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end} +{p 4 8 2}Email: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol} + +{title:Also see} + +{p 4 13 2}Online: help for {help sem}{p_end} diff --git a/Modules/ado/personal/r/rsoort11.zip b/Modules/ado/personal/r/rsoort11.zip new file mode 100644 index 0000000..909c7d2 Binary files /dev/null and b/Modules/ado/personal/r/rsoort11.zip differ diff --git a/Modules/ado/personal/r/rsoort12.ado b/Modules/ado/personal/r/rsoort12.ado new file mode 100644 index 0000000..9e6ac0f --- /dev/null +++ b/Modules/ado/personal/r/rsoort12.ado @@ -0,0 +1,770 @@ +*! version 1.1 3June2013 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* rsoort: Response Shift detection with the Oort procedure +* +* Historic: +* Version 1 (2013-02-25): Jean-Benoit Hardouin +* Version 1.1 (2013-06-03): Jean-Benoit Hardouin /*some improvements*/ +* Version 1.2 (2013-06-03): Jean-Benoit Hardouin /*model1 model2 model3 and covariances options*/ +* +* +* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France +* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam" +* jean-benoit.hardouin@univ-nantes.fr +* +* Copyright 2013 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + + +program define rsoort,eclass +syntax varlist(min=2 numeric) [if] [in] [,METHod(string) UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPrioritization(varlist) noSearch html(string) model1 model2 model4 COVariances(string)] +tempfile saversoort +qui save `saversoort',replace + +if "`html'" != "" { + di "" +} + + +if "`if'"!=""|"`in'"!="" { + qui keep `if' `in' +} + +tokenize `varlist' +local nbitems:word count `varlist' +local mod=mod(`nbitems',2) +if `mod'!=0 { + di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2" + error +} + +if "`method'"=="" { + local method "ml" +} +local nbitems=`nbitems'/2 + +if "`html'"== "" { + di _col(20) "{hline 30}" + di _col(20) in gr "Time 1" _col(40) "Time 2" + di _col(20) "{hline 30}" + forvalues i=1/`nbitems' { + di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''" + } + di _col(20) "{hline 30}" +} +else { + di "" + di "" + di "" + di "" + forvalues i=1/`nbitems' { + di "" + } + di "
Time 1Time2
``i''``=`i'+`nbitems'''
" +} + +/************************************************************************************************************** +Model 1 +***************************************************************************************************************/ + +if "`model1'"=="" { + local qui qui +} +else { + local qui +} +`qui' sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method') cov(`covariances') +qui estat gof, stat(all) +local tli1=r(tli) +local cfi1=r(cfi) +local srmr1=r(srmr) +local rmsea1=r(rmsea) +local ubrmsea1=r(ub90_rmsea) +local lbrmsea1=r(lb90_rmsea) +local chi21=r(chi2_ms) +local df1=r(df_ms) +local dfc1=6*`nbitems'+1 +local p1=r(p_ms) +local bic1=r(bic) +*di +*di in green " ***********************************Model 1********************************************" +*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI" +*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1' + +/************************************************************************************************************** +Model 2 +***************************************************************************************************************/ + +local sem +local var +forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local sem `sem' `sem`i'' + local var `var' `var`i'' +} + +if "`model2'"=="" { + local qui qui +} +else { + local qui +} + +`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') `covariances' +tempname b V +matrix `b'=e(b) +matrix `V'=e(V) +local truechange2=`b'[1,`=`nbitems'*4+1'] +local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1'] +qui estat gof, stat(all) +local tli2=r(tli) +local cfi2=r(cfi) +local srmr2=r(srmr) +local rmsea2=r(rmsea) +local ubrmsea2=r(ub90_rmsea) +local lbrmsea2=r(lb90_rmsea) +local chi22=r(chi2_ms) +local df2=r(df_ms) +local dfc2=3*`nbitems'+3 +local p2=r(p_ms) +local bic2=r(bic) + +local chi221=abs(`chi21'-`chi22') +local df21=`df2'-`df1' +local p21=1-chi2(`df21',`chi221') + +if "`html'" != "" { + di "" + di "" + *di "" + di "" + di "" + di "" + di "" + di "
Test of global Response-ShiftComparison with model 1
ModelsChi-squaredfp-valueBIC
Model 1" %8.2f `chi21' "" %4.0f `df1' "" %6.4f `p1' "" %7.2f `bic1' "
Model 2" %8.2f `chi22' "" %4.0f `df2' "" %6.4f `p2' "" %7.2f `bic2' "
" +} +else { + di "{hline 51}" + di in gr /*_col(39) "Test of global Response-Shift " _col(79) "Comparison with model 1"*/ + di in gr "Models" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" /*_col(39) "Chi-square" _col(54) "df" _col(59) "p-value" *_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 51}" + di in gr "Model 1" _col(20) %8.2f in ye `chi21' _col(30) %4.0f `df1' _col(37) %6.4f `p1' _col(45) %7.2f `bic1' + di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(30) %4.0f `df2' _col(37) %6.4f `p2' _col(45) %7.2f `bic2' /*_col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' *_col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'*/ + di "{hline 51}" +} + + +/************************************************************************************************************** +Model 3 +***************************************************************************************************************/ + + +/************************************************************************************************************** +Model 3 / Non uniform recalibration +***************************************************************************************************************/ + +tempname RS RSprec +qui matrix `RS'=J(`nbitems',3,0) +qui matrix `RSprec'=J(`nbitems',3,0) +local df3=`dfc2' + +*set trace on + + +forvalues i=1/`nbitems' { + local nbUR:word count `uniformrecalibration' + forvalues j=1/`nbUR' { + local itemj: word `j' of `uniformrecalibration' + if "``i''"=="`itemj'" { + matrix `RS'[`i',2]=1 + } + } + local nbNUR:word count `nonuniformrecalibration' + forvalues j=1/`nbNUR' { + local itemj: word `j' of `nonuniformrecalibration' + if "``i''"=="`itemj'" { + matrix `RS'[`i',1]=1 + } + } + local nbR:word count `reprioritization' + forvalues j=1/`nbR' { + local itemj: word `j' of `reprioritization' + if "``i''"=="`itemj'" { + matrix `RS'[`i',3]=1 + } + } +} +*matrix list `RS' + +if "`search'"=="" { + + if "`html'"=="" { + di + di "{hline 88}" + di in green _col(40) "Model 3" + di "{hline 88}" + di + di in white _col(10) "Non uniform Recalibration" + } + else { + di "


Model 3

" + di "" + di "" + } + local continue=1 + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + } + local prec_chi2=`chi22' + local testNU_varchi2=0 + local testNU_p=1 + + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + while (`continue') { + local cpt=0 + local testNU_varchi2_temp=0 + local testNU_p_temp=0 + local testNU_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + local var + forvalues j=1/`nbitems' { + local sem + local var + local already=0 + forvalues i=1/`nbitems' { + if `RS'[`i',1]==0&`i'!=`j' { + local sem `sem' `sem`i'' + local var `var' `var`i'' + } + if `RS'[`i',1]==1&`i'!=`j' { + local sem `sem' `sem`i'' + local var `var' `varrecNU`i'' + } + else if `i'==`j'&`RS'[`j',1]==0 { + local sem `sem' `sem`i'' + local var `var' `varrecNU`i'' + } + else if `i'==`j'&`RS'[`j',1]==1 { + local sem `sem' `sem`i'' + local var `var' `varrecNU`i'' + local already=1 + } + } + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') `covariances' + qui estat gof + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') { + local continue=1 + local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp') + local testNU_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + } + if "`html'" != "" { + di "" + } + else { + di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + local ++cpt + } + } + if (`testNU_item_temp'!=0) { + matrix `RS'[`testNU_item_temp',1]=1 + local ++df3 + local testNU_varchi2=`testNU_varchi2_temp' + local testNU_p=`testNU_p_temp' + local testNU_item_temp=0 + local prec_chi2=`tmp' + } + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Non uniform Recalibration
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "

" + } + + + + /************************************************************************************************************** + Model 3 / Uniform recalibration + ***************************************************************************************************************/ + + if "`html'"=="" { + di + di in white _col(10) "Uniform Recalibration" + } + else { + di "" + di "" + } + local continue=1 + local var + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + } + local testU_varchi2=0 + local testU_p=1 + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + while (`continue') { + local cpt=0 + local testU_varchi2_temp=0 + local testU_p_temp=0 + local testU_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + forvalues j=1/`nbitems' { + local sem + local already=0 + forvalues i=1/`nbitems' { + if `RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `sem`i'' + } + if `RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecU`i'' + } + else if `i'==`j'&`RS'[`j',2]==0 { + local sem `sem' `semrecU`i'' + } + else if `i'==`j'&`RS'[`j',2]==1 { + local sem `sem' `semrecU`i'' + local already=1 + } + } + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') `covariances' + qui estat gof + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') { + local continue=1 + local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local testU_p_temp =1-chi2(1,`testU_varchi2_temp') + local testU_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + } + if "`html'" != "" { + di "" + } + else { + di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + local ++cpt + } + } + if (`testU_item_temp'!=0) { + matrix `RS'[`testU_item_temp',2]=1 + local ++df3 + local testU_varchi2=`testU_varchi2_temp' + local testU_p=`testU_p_temp' + local testU_item_temp=0 + local prec_chi2=`tmp' + } + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Uniform Recalibration
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "

" + } + + + + + /************************************************************************************************************** + Model 3 / Reprioritization + ***************************************************************************************************************/ + + if "`html'"=="" { + di + di in white _col(10) "Reprioritization" + } + else { + di "" + di "" + } + + local continue=1 + local var + local sem + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + } + local testU_varchi2=0 + local testU_p=1 + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + while (`continue') { + local cpt=0 + local testR_varchi2_temp=0 + local testR_p_temp=0 + local testR_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + forvalues j=1/`nbitems' { + local sem + local already=0 + forvalues i=1/`nbitems' { + if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `sem`i'' + } + else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecU`i'' + } + else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `semrep`i'' + } + else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecUrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 { + local sem `sem' `semrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 { + local sem `sem' `semrecUrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 { + local already=1 + } + else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 { + local sem `sem' `semrep`i'' + local already=1 + } + else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 { + local sem `sem' `semrecUrep`i'' + local already=1 + } + } + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') `covariances' + qui estat gof + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') { + local continue=1 + local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local testR_p_temp =1-chi2(1,`testR_varchi2_temp') + local testR_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + } + if ( `chi2encours'<`prec_chi2') { + if "`html'" != "" { + di "" + } + else { + di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + } + else { + if "`html'" != "" { + di "" + } + else { + di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) "Unavailable" + } + } + local ++cpt + } + } + if (`testR_item_temp'!=0) { + matrix `RS'[`testR_item_temp',3]=1 + local ++df3 + local testR_varchi2=`testR_varchi2_temp' + local testR_p=`testR_p_temp' + local testR_item_temp=0 + local prec_chi2=`tmp' + } + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Reprioritization
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "
``j''" %8.2f `chi2encours' "Unavailable

" + } +} + +/************************************************************************************************************** +Model 3 Final +***************************************************************************************************************/ + +di +local continue=1 +local var +local sem +forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + if `RS'[`i',2]==0&`RS'[`i',3]==0 { + local sem "`sem' `sem`i''" + } + if `RS'[`i',2]==0&`RS'[`i',3]==1 { + local sem "`sem' `semrep`i''" + } + if `RS'[`i',2]==1&`RS'[`i',3]==0 { + local sem "`sem' `semrecU`i''" + } + if `RS'[`i',2]==1&`RS'[`i',3]==1 { + local sem "`sem' `semrecUrep`i''" + } +} +qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') `covariances' +tempname b V +matrix `b'=e(b) +matrix `V'=e(V) +local truechange=`b'[1,`=`nbitems'*4+1'] +local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1'] +qui estat gof +local tli3=r(tli) +local cfi3=r(cfi) +local srmr3=r(srmr) +local rmsea3=r(rmsea) +local ubrmsea3=r(ub90_rmsea) +local lbrmsea3=r(lb90_rmsea) +local chi23=r(chi2_ms) +local dfc3=`df3' +local p3=r(p_ms) +local bic3=r(bic) + + +/************************************************************************************************************** +Bilan +***************************************************************************************************************/ + +if "`html'"=="" { + di + di "{hline 74}" + di in gr _col(22) "Non uniform" _col(46) "Uniform" + di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(58) "Reprioritization" + di "{hline 74}" +} +else { + di "" + di "" + di "" + di "" +} +forvalues i=1/`nbitems' { + local recNU + local recU + local rep + if (`RS'[`i',1]==1) { + local recNU "*" + } + if (`RS'[`i',2]==1) { + local recU "*" + } + if (`RS'[`i',3]==1) { + local rep "*" + } + if "`html'"=="" { + di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'" + } + else { + di "" + } +} +if "`html'"=="" { + di "{hline 74}" +} +else { + di "
ItemsNon-uniform
Recalibration
Uniform
Recalibration

Repriorisation
``i''`recNU'`recU'`rep'
" +} + + +/************************************************************************************************************** +Model 4 +***************************************************************************************************************/ + +if "`model4'"=="" { + local qui qui +} +else { + local qui +} +`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) `covariances' +tempname b V +matrix `b'=e(b) +matrix `V'=e(V) +local truechange=`b'[1,`=`nbitems'*4+1'] +local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1'] +qui estat gof,stat(all) +local tli4=r(tli) +local cfi4=r(cfi) +local srmr4=r(srmr) +local rmsea4=r(rmsea) +local ubrmsea4=r(ub90_rmsea) +local lbrmsea4=r(lb90_rmsea) +local chi24=r(chi2_ms) +local dfc4=`df3'+1 +local p4=r(p_ms) +local chi2encours=r(chi2_ms) +local bic4=r(bic) + +local z=`truechange'/sqrt(`Vtruechange') + +if "`html'" != "" { + di "" + di "" + di "" + di "" + di "" + di "" + di "" + di "
Modelschi2dfpBICRMSEAIC90%(RMSEA)SRMRCFITLI
Model 1" %8.2f `chi21' "" %4.0f `dfc1' "" %7.2f `bic1' "" %6.4f `p1' "" %6.4f `rmsea1' "" %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' "" %6.4f `srmr1' "" %6.2f `cfi1' "" %6.2f `tli1' "
Model 2" %8.2f `chi22' "" %4.0f `dfc2' "" %7.2f `bic2' "" %6.4f `p2' "" %6.4f `rmsea2' "" %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' "" %6.4f `srmr2' "" %6.2f `cfi2' "" %6.2f `tli2' "
Model 4" %8.2f `chi24' "" %4.0f `dfc4' "" %7.2f `bic4' "" %6.4f `p4' "" %6.4f `rmsea4' "" %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' "" %6.4f `srmr4' "" %6.2f `cfi4' "" %6.2f `tli4' "
" +} +else { + di + di "{hline 95}" + di in gr "Models" _col(14) "chi2" _col(22) "df" _col(31) "p" _col(40) "BIC" _col(47) "RMSEA" _col(55) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI" + di "{hline 95}" + di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(26) %6.4f `p1' _col(36) %7.2f `bic1' _col(46) %6.4f `rmsea1' _col(54) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1' + di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `dfc2' _col(26) %6.4f `p2' _col(36) %7.2f `bic2' _col(46) %6.4f `rmsea2' _col(54) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2' + *di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3' _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3' + di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `dfc4' _col(26) %6.4f `p4' _col(36) %7.2f `bic4' _col(46) %6.4f `rmsea4' _col(54) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4' + di "{hline 95}" +} + + +if "`html'" != "" { + di "" + di "" + di "" + di "" + di "" + di "" + di "
Estimations.e.zp-value
True change (Model 2)" %8.4f `truechange2' "" %8.4f `=sqrt(`Vtruechange2')' "" %6.2f `=`truechange2'/sqrt(`Vtruechange2')' "" %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))' "
True change (Model 4)" %8.4f `truechange' "" %8.4f `=sqrt(`Vtruechange')' "" %6.2f `=`truechange'/sqrt(`Vtruechange')' "" %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))' "
" +} +else { + di + di "{hline 77}" + di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value" + di "{hline 77}" + di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))' + di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))' + di "{hline 77}" + di +} +qui use `saversoort',clear + + + +end diff --git a/Modules/ado/personal/r/rsoort13.ado b/Modules/ado/personal/r/rsoort13.ado new file mode 100644 index 0000000..41b1284 --- /dev/null +++ b/Modules/ado/personal/r/rsoort13.ado @@ -0,0 +1,820 @@ +*! version 1.3 12June2013 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* rsoort: Response Shift detection with the Oort procedure +* +* Historic: +* Version 1 (2013-02-25): Jean-Benoit Hardouin +* Version 1.1 (2013-06-03): Jean-Benoit Hardouin /*some improvements*/ +* Version 1.2 (2013-06-03): Jean-Benoit Hardouin /*model1 model2 model3 and covariances options*/ +* Version 1.3 (2013-06-03): Jean-Benoit Hardouin /**/ +* +* +* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France +* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam" +* jean-benoit.hardouin@univ-nantes.fr +* +* Copyright 2013 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +/*********************************************************************************************************** +INTRODUCTION +***********************************************************************************************************/ + + +program define rsoort,eclass +syntax varlist(min=2 numeric) [if] [in] [,METHod(string) nocov12 UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPrioritization(varlist) noSearch html(string) model1 model2 model4 COVariances(string) MATrixrs(string)] +tempfile saversoort +qui save `saversoort',replace +preserve +if "`matrixrs'"!="" { + if "`uniformrecalibration'"!="" { + di in red "You cannot use the {bf:matrixrs} and the {bf:uniformrecalibration} options in the same time" + error + } + if "`nonuniformrecalibration'"!="" { + di in red "You cannot use the {bf:matrixrs} and the {bf:nonuniformrecalibration} options in the same time" + error + } + if "`reprioritization'"!="" { + di in red "You cannot use the {bf:matrixrs} and the {bf:reprioritization} options in the same time" + error + } +} + + +if "`html'" != "" { + di "" +} + + +if "`if'"!=""|"`in'"!="" { + qui keep `if' `in' +} + +tokenize `varlist' +local nbitems:word count `varlist' +local mod=mod(`nbitems',2) +if `mod'!=0 { + di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2" + error +} + +if "`method'"=="" { + local method "ml" +} +local nbitems=`nbitems'/2 + +if "`html'"== "" { + di _col(20) "{hline 30}" + di _col(20) in gr "Time 1" _col(40) "Time 2" + di _col(20) "{hline 30}" + forvalues i=1/`nbitems' { + di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''" + } + di _col(20) "{hline 30}" +} +else { + di "" + di "" + di "" + di "" + forvalues i=1/`nbitems' { + di "" + } + di "
Time 1Time2
``i''``=`i'+`nbitems'''
" +} + +/************************************************************************************************************** +Model 1 +***************************************************************************************************************/ + +if "`model1'"=="" { + local qui qui +} +else { + local qui +} +local cov12b +forvalues i=1/`nbitems' { + local cov12b `cov12b' e.``i''*e.``=`i'+`nbitems''' +} +if "`cov12'"!="" { + local cov12b +} +`qui' sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method') cov(`cov12b' `covariances') +qui estat gof, stat(all) +local tli1=r(tli) +local cfi1=r(cfi) +local srmr1=r(srmr) +local rmsea1=r(rmsea) +local ubrmsea1=r(ub90_rmsea) +local lbrmsea1=r(lb90_rmsea) +local chi21=r(chi2_ms) +local df1=r(df_ms) +local dfc1=6*`nbitems'+1 +local p1=r(p_ms) +local bic1=r(bic) +*di +*di in green " ***********************************Model 1********************************************" +*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI" +*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1' + +/************************************************************************************************************** +Model 2 +***************************************************************************************************************/ + +local sem +local var +forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local sem `sem' `sem`i'' + local var `var' `var`i'' +} + +if "`model2'"=="" { + local qui qui +} +else { + local qui +} + +`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances') +tempname b V +matrix `b'=e(b) +matrix `V'=e(V) +local truechange2=`b'[1,`=`nbitems'*4+1'] +local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1'] +qui estat gof, stat(all) +local tli2=r(tli) +local cfi2=r(cfi) +local srmr2=r(srmr) +local rmsea2=r(rmsea) +local ubrmsea2=r(ub90_rmsea) +local lbrmsea2=r(lb90_rmsea) +local chi22=r(chi2_ms) +local df2=r(df_ms) +local dfc2=3*`nbitems'+3 +local p2=r(p_ms) +local bic2=r(bic) + +local chi221=abs(`chi21'-`chi22') +local df21=`df2'-`df1' +local p21=1-chi2(`df21',`chi221') + +if "`html'" != "" { + di "" + di "" + *di "" + di "" + di "" + di "" + di "" + di "
Test of global Response-ShiftComparison with model 1
ModelsChi-squaredfp-valueBIC
Model 1" %8.2f `chi21' "" %4.0f `df1' "" %6.4f `p1' "" %7.2f `bic1' "
Model 2" %8.2f `chi22' "" %4.0f `df2' "" %6.4f `p2' "" %7.2f `bic2' "
" +} +else { + di "{hline 51}" + di in gr /*_col(39) "Test of global Response-Shift " _col(79) "Comparison with model 1"*/ + di in gr "Models" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" /*_col(39) "Chi-square" _col(54) "df" _col(59) "p-value" *_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 51}" + di in gr "Model 1" _col(20) %8.2f in ye `chi21' _col(30) %4.0f `df1' _col(37) %6.4f `p1' _col(45) %7.2f `bic1' + di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(30) %4.0f `df2' _col(37) %6.4f `p2' _col(45) %7.2f `bic2' /*_col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' *_col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'*/ + di "{hline 51}" +} + + +/************************************************************************************************************** +Model 3 +***************************************************************************************************************/ + + +/************************************************************************************************************** +Model 3 / Non uniform recalibration +***************************************************************************************************************/ + +tempname RS RSprec +qui matrix `RS'=J(`nbitems',3,0) +qui matrix `RSprec'=J(`nbitems',3,0) +local df3=`dfc2' + +*set trace on + +if "`matrixrs'"=="" { + forvalues i=1/`nbitems' { + local nbUR:word count `uniformrecalibration' + forvalues j=1/`nbUR' { + local itemj: word `j' of `uniformrecalibration' + if "``i''"=="`itemj'" { + matrix `RS'[`i',2]=1 + } + } + local nbNUR:word count `nonuniformrecalibration' + forvalues j=1/`nbNUR' { + local itemj: word `j' of `nonuniformrecalibration' + if "``i''"=="`itemj'" { + matrix `RS'[`i',1]=1 + } + } + local nbR:word count `reprioritization' + forvalues j=1/`nbR' { + local itemj: word `j' of `reprioritization' + if "``i''"=="`itemj'" { + matrix `RS'[`i',3]=1 + } + } + } +} +else { + matrix `RS'=`matrixrs' +} +*matrix list `RS' + +if "`search'"=="" { + + if "`html'"=="" { + di + di "{hline 88}" + di in green _col(40) "Model 3" + di "{hline 88}" + di + di in white _col(10) "Non uniform Recalibration" + } + else { + di "


Model 3

" + di "" + di "" + } + local continue=1 + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + } + local prec_chi2=`chi22' + local testNU_varchi2=0 + local testNU_p=1 + + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + while (`continue') { + local cpt=0 + local testNU_varchi2_temp=0 + local testNU_p_temp=0 + local testNU_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + local var + forvalues j=1/`nbitems' { + local sem + local var + local already=0 + forvalues i=1/`nbitems' { + if `RS'[`i',1]==0&`i'!=`j' { + local sem `sem' `sem`i'' + local var `var' `var`i'' + } + if `RS'[`i',1]==1&`i'!=`j' { + local sem `sem' `sem`i'' + local var `var' `varrecNU`i'' + } + else if `i'==`j'&`RS'[`j',1]==0 { + local sem `sem' `sem`i'' + local var `var' `varrecNU`i'' + } + else if `i'==`j'&`RS'[`j',1]==1 { + local sem `sem' `sem`i'' + local var `var' `varrecNU`i'' + local already=1 + } + } + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances') + qui estat gof + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') { + local continue=1 + local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp') + local testNU_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + } + if ( `chi2encours'<`prec_chi2') { + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + } + else { + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable" + } + } + local ++cpt + } + } + if (`testNU_item_temp'!=0) { + matrix `RS'[`testNU_item_temp',1]=1 + local ++df3 + local testNU_varchi2=`testNU_varchi2_temp' + local testNU_p=`testNU_p_temp' + local testNU_item_temp=0 + local prec_chi2=`tmp' + } + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Non uniform Recalibration
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "
``j''Unavailable

" + } + + + + /************************************************************************************************************** + Model 3 / Uniform recalibration + ***************************************************************************************************************/ + + if "`html'"=="" { + di + di in white _col(10) "Uniform Recalibration" + } + else { + di "" + di "" + } + local continue=1 + local var + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + } + local testU_varchi2=0 + local testU_p=1 + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + while (`continue') { + local cpt=0 + local testU_varchi2_temp=0 + local testU_p_temp=0 + local testU_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + forvalues j=1/`nbitems' { + local sem + local already=0 + forvalues i=1/`nbitems' { + if `RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `sem`i'' + } + if `RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecU`i'' + } + else if `i'==`j'&`RS'[`j',2]==0 { + local sem `sem' `semrecU`i'' + } + else if `i'==`j'&`RS'[`j',2]==1 { + local sem `sem' `semrecU`i'' + local already=1 + } + } + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances') + qui estat gof + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') { + local continue=1 + local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local testU_p_temp =1-chi2(1,`testU_varchi2_temp') + local testU_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + } + + if ( `chi2encours'<`prec_chi2') { + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + } + else { + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable" + } + } + local ++cpt + } + } + if (`testU_item_temp'!=0) { + matrix `RS'[`testU_item_temp',2]=1 + local ++df3 + local testU_varchi2=`testU_varchi2_temp' + local testU_p=`testU_p_temp' + local testU_item_temp=0 + local prec_chi2=`tmp' + } + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Uniform Recalibration
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "
``j''Unavailable

" + } + + + + + /************************************************************************************************************** + Model 3 / Reprioritization + ***************************************************************************************************************/ + + if "`html'"=="" { + di + di in white _col(10) "Reprioritization" + } + else { + di "" + di "" + } + + local continue=1 + local var + local sem + forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + } + local testU_varchi2=0 + local testU_p=1 + if "`html'"=="" { + di "{hline 88}" + di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/ + di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 88}" + } + else { + di "" + di "" + di "" + } + + while (`continue') { + local cpt=0 + local testR_varchi2_temp=0 + local testR_p_temp=0 + local testR_item_temp=0 + local chi2encours_temp=-1 + local continue=0 + local sem + forvalues j=1/`nbitems' { + local sem + local already=0 + forvalues i=1/`nbitems' { + if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `sem`i'' + } + else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecU`i'' + } + else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' { + local sem `sem' `semrep`i'' + } + else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' { + local sem `sem' `semrecUrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 { + local sem `sem' `semrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 { + local sem `sem' `semrecUrep`i'' + } + else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 { + local already=1 + } + else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 { + local sem `sem' `semrep`i'' + local already=1 + } + else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 { + local sem `sem' `semrecUrep`i'' + local already=1 + } + } + if (`already'!=1) { + qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances') + qui estat gof + local chi2encours=r(chi2_ms) + local dfencours=r(df_ms) + local pencours=r(p_ms) + local bicencours=r(bic) + if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') { + local continue=1 + local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' ) + local testR_p_temp =1-chi2(1,`testR_varchi2_temp') + local testR_item_temp=`j' + local chi2encours_tmp=`chi2encours' + local tmp=`chi2encours' + } + if ( `chi2encours'<`prec_chi2') { + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/ + } + } + else { + if "`html'" != "" { + di "" + } + else { + di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable" + } + } + local ++cpt + } + } + if (`testR_item_temp'!=0) { + matrix `RS'[`testR_item_temp',3]=1 + local ++df3 + local testR_varchi2=`testR_varchi2_temp' + local testR_p=`testR_p_temp' + local testR_item_temp=0 + local prec_chi2=`tmp' + } + if (`cpt'!=0) { + if "`html'" != "" { + di "" + } + else { + di "{hline 88}" + } + } + } + if "`html'" != "" { + di "
Reprioritization
Comparison with previous model
ItemsChi-squaredfp-valueBICChi-squaredfp-value
``j''" %8.2f `chi2encours' "" %4.0f `dfencours' "" %6.4f `pencours' "" %7.2f `bicencours' "" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "1" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "
``j''Unavailable

" + } +} + +/************************************************************************************************************** +Model 3 Final +***************************************************************************************************************/ + +di +local continue=1 +local var +local sem +forvalues i=1/`nbitems' { + local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')" + local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')" + local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')" + local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')" + local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')" + local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')" + if `RS'[`i',1]==1 { + local var "`var' `varrecNU`i''" + } + if `RS'[`i',1]==0 { + local var "`var' `var`i''" + } + if `RS'[`i',2]==0&`RS'[`i',3]==0 { + local sem "`sem' `sem`i''" + } + if `RS'[`i',2]==0&`RS'[`i',3]==1 { + local sem "`sem' `semrep`i''" + } + if `RS'[`i',2]==1&`RS'[`i',3]==0 { + local sem "`sem' `semrecU`i''" + } + if `RS'[`i',2]==1&`RS'[`i',3]==1 { + local sem "`sem' `semrecUrep`i''" + } +} +qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances') +tempname b V +matrix `b'=e(b) +matrix `V'=e(V) +local truechange=`b'[1,`=`nbitems'*4+1'] +local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1'] +qui estat gof +local tli3=r(tli) +local cfi3=r(cfi) +local srmr3=r(srmr) +local rmsea3=r(rmsea) +local ubrmsea3=r(ub90_rmsea) +local lbrmsea3=r(lb90_rmsea) +local chi23=r(chi2_ms) +local dfc3=`df3' +local p3=r(p_ms) +local bic3=r(bic) + + +/************************************************************************************************************** +Bilan +***************************************************************************************************************/ + +if "`html'"=="" { + di + di "{hline 74}" + di in gr _col(22) "Non uniform" _col(46) "Uniform" + di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(58) "Reprioritization" + di "{hline 74}" +} +else { + di "" + di "" + di "" + di "" +} +forvalues i=1/`nbitems' { + local recNU + local recU + local rep + if (`RS'[`i',1]==1) { + local recNU "*" + } + if (`RS'[`i',2]==1) { + local recU "*" + } + if (`RS'[`i',3]==1) { + local rep "*" + } + if "`html'"=="" { + di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'" + } + else { + di "" + } +} +if "`html'"=="" { + di "{hline 74}" +} +else { + di "
ItemsNon-uniform
Recalibration
Uniform
Recalibration

Repriorisation
``i''`recNU'`recU'`rep'
" +} + + +/************************************************************************************************************** +Model 4 +***************************************************************************************************************/ + +if "`model4'"=="" { + local qui qui +} +else { + local qui +} +`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) cov(`cov12b' `covariances') method(`method') +tempname b V +matrix `b'=e(b) +matrix `V'=e(V) +local truechange=`b'[1,`=`nbitems'*4+1'] +local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1'] +qui estat gof,stat(all) +local tli4=r(tli) +local cfi4=r(cfi) +local srmr4=r(srmr) +local rmsea4=r(rmsea) +local ubrmsea4=r(ub90_rmsea) +local lbrmsea4=r(lb90_rmsea) +local chi24=r(chi2_ms) +local df4=r(df_ms) +local dfc4=`df3'+1 +local p4=r(p_ms) +local chi2encours=r(chi2_ms) +local bic4=r(bic) + +local z=`truechange'/sqrt(`Vtruechange') + +if "`html'" != "" { + di "" + di "" + di "" + di "" + di "" + di "" + di "" + di "
Modelschi2dfpBICRMSEAIC90%(RMSEA)SRMRCFITLI
Model 1" %8.2f `chi21' "" %4.0f `df1' "" %7.2f `bic1' "" %6.4f `p1' "" %6.4f `rmsea1' "" %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' "" %6.4f `srmr1' "" %6.2f `cfi1' "" %6.2f `tli1' "
Model 2" %8.2f `chi22' "" %4.0f `df2' "" %7.2f `bic2' "" %6.4f `p2' "" %6.4f `rmsea2' "" %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' "" %6.4f `srmr2' "" %6.2f `cfi2' "" %6.2f `tli2' "
Model 4" %8.2f `chi24' "" %4.0f `df4' "" %7.2f `bic4' "" %6.4f `p4' "" %6.4f `rmsea4' "" %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' "" %6.4f `srmr4' "" %6.2f `cfi4' "" %6.2f `tli4' "
" +} +else { + di + di "{hline 95}" + di in gr "Models" _col(14) "chi2" _col(22) "df" _col(31) "p" _col(40) "BIC" _col(47) "RMSEA" _col(55) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI" + di "{hline 95}" + di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `df1' _col(26) %6.4f `p1' _col(36) %7.2f `bic1' _col(46) %6.4f `rmsea1' _col(54) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1' + di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `df2' _col(26) %6.4f `p2' _col(36) %7.2f `bic2' _col(46) %6.4f `rmsea2' _col(54) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2' + *di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3' _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3' + di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `df4' _col(26) %6.4f `p4' _col(36) %7.2f `bic4' _col(46) %6.4f `rmsea4' _col(54) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4' + di "{hline 95}" +} + + +if "`html'" != "" { + di "" + di "" + di "" + di "" + di "" + di "" + di "
Estimations.e.zp-value
True change (Model 2)" %8.4f `truechange2' "" %8.4f `=sqrt(`Vtruechange2')' "" %6.2f `=`truechange2'/sqrt(`Vtruechange2')' "" %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))' "
True change (Model 4)" %8.4f `truechange' "" %8.4f `=sqrt(`Vtruechange')' "" %6.2f `=`truechange'/sqrt(`Vtruechange')' "" %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))' "
" +} +else { + di + di "{hline 77}" + di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value" + di "{hline 77}" + di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))' + di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))' + di "{hline 77}" + di +} +qui use `saversoort',clear + + + +end diff --git a/Modules/ado/personal/r/rsoortBP.ado b/Modules/ado/personal/r/rsoortBP.ado new file mode 100644 index 0000000..0befedd --- /dev/null +++ b/Modules/ado/personal/r/rsoortBP.ado @@ -0,0 +1,2208 @@ +/* +Regarder si les modĂšles convergent dans la partie 1 +PrĂ©voir le cas du cross loading (=> numĂ©ro des contraintes, etc) +*/ + +capture program drop rsoortBP +program define rsoortBP,rclass +syntax varlist(min=2 numeric) [if] [in], PARTition(numlist) [lt(string) METHod(string) UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPrioritization(varlist) noSearch CFARmsea(real -999) CFACfi(real -999) CFAOR iterate(integer 100) onlycovl Test Hierarchical sb adjust Group(varlist) trace *] +version 15 + +preserve + +//rename *, lower + +local P:word count `partition' +local S:word count `lt' + +if "`lt'" != "" { + if `P'!=`S' { + di in red "The number of arguments in lt() must be equal to the number of arguments in partition()" + exit 119 + } + else { + tokenize `lt' + forvalues i = 1/`S' { + local ltname`i' = "``i''" + } + } +} +else { + forvalues i = 1/`P' { + local ltname`i' = "LT`i'" + } +} + + + + +order `varlist' + +if "`trace'" != "" { + local qui "" +} +else { + local qui "qui" +} + +if "`if'"!=""|"`in'"!="" { + qui keep `if' `in' +} + +tokenize `varlist' + +local nbitems:word count `varlist' + +*di "`varlist'" +local varlist +forvalues i=1/`nbitems' { + //di "``i''" + capture rename ``i'', lower + local low = lower("``i''") + local var`i' = `low' + local varlist `varlist' `low' +} +tokenize `varlist' +*di "`varlist'" + +/* +local i = 1 +foreach x in `varlist' { + local var`i' = lower("`x'") + di "ok" + rename `x' `var`i'' + local ++i +} +*/ +local nbitems:word count `varlist' +local mod=mod(`nbitems',2) +if `mod'!=0 { + di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2" + error +} +local nbitems=`nbitems'/2 + +local nbdims:word count `partition' + + +local C = 0 +foreach z in `partition' { + local C = `C' + `z' +} + + +if `C' != `nbitems' { + di in red "The sum of the numbers in the partition option is different from the number of variables specified in varlist" + exit 119 +} + + + +if `cfarmsea' == -999{ + local cfarmsea +} +if `cfacfi' == -999{ + local cfacfi +} + +if "`method'"=="" { + local method "ml" +} + +local i = 1 +local j = 0 +foreach p in `partition' { + local part`i' = `p'+`j' + local ++i + local j = `j'+`p' + +} + +if "`sb'" != "" { + local sb = "vce(sbentler)" +} + + +di as result _col(20) "{hline 35}" +di as text _col(20) "Time 1" _col(40) "Time 2" +di as text _col(20) "{hline 35}" +local j = 1 +forvalues i=1/`nbitems' { + *set trace on + if (!missing("`part`j''")) { + if (`i' ==1|`i'==`=`part`j''+1') { + if `i'!=1 local ++j + di _col(20) "`ltname`j''" _col(40) "`ltname`j''" + } + } + *set trace off + di _col(20) "``i''" _col(40) "``=`i'+`nbitems'''" +} +di as result _col(20) "{hline 35}" + + +/************************************************************************************************************** +DIF time 1 (if "group" is option specified) +***************************************************************************************************************/ + + + /************************************************************************************************************** + DIF : Model A + ***************************************************************************************************************/ + + + +if "`group'" !="" { + + + + +tokenize `varlist' + +local ii = 1 +local s +local stop = 0 +local i = 1 + + +foreach x in `varlist' { + local var`i' = "`x'" + local ++i +} + +local i = 1 +foreach x in `partition' { + local part`i' = `x' +} + +//tokenize `varlist' +forvalues i=1/`nbitems' { + local cov12b `cov12b' e.``i''*e.``=`i'+`nbitems''' +} + +//di "`varlist'" + +local k = 1 +local i = 1 +local j = 0 +local pp = 0 +foreach p in `partition' { + local pp = `pp'+`p' + while (`j'<`pp') { + local bloca`k' `bloca`k'' `var`i'' + local blocb`k' `blocb`k'' `var`=`i'+`nbitems''' + //di "`var`i''" + local i = `i'+1 + local j = `j'+1 + } + //di in red `j' + //order `var`j''-`var`pp'' + //order `var`=`j'+`nbitems'''-`var`=`pp'+`nbitems''' + + + local ++k +} + +di "`bloca1'" +di "`bloca2'" +di "`blocb1'" +di "`blocb2'" + + + +local i = 1 +local j = 1 +local pp = 0 +foreach p in `partition' { + local pp = `pp'+`p' + local s `s' (L`i'_1 -> `bloca`i'') + local cl `cl' means(L`i'_1@0) var(L`i'_1@1) + forvalues k = 1/`=`nbdims'-1' { + if (`=`i'+`k''<=`nbdims') { + local covl `covl' L`i'_1*L`=`i'+`k''_1 + } + } + + local j = `pp'+1 + local i = `i'+1 +} + + + +local z "`s', `cl' iterate(`iterate') method(`method') `sb' group(`group') ginvariant(covex)" + +di in red "DIF : model A (without search for modification indices)" + +di as text "sem `z' " + +sem `z' + +est store modelAwo + +if "`cfarmsea'"!="" { + local stoprmsea=0 + while `stoprmsea'==0 { + qui estat gof + di in red "rmsea="round(`r(rmsea)',0.001) + if r(rmsea)<`cfarmsea' { + local stoprmsea = 1 + } + else { + estat mindices, showpclass(merrvar) + tempvar rname chi df p ccovnum + mat m = r(mindices) + matrix m2 = m[.,1..3] + svmat2 m2 , rnames(`rname') names(`chi' `df' `p') full + gsort -`chi' + local nrows = rowsof(m2) + gen `ccovnum' = _n + list `ccovnum' `rname' `chi' in 1/`nrows' + + local num = `ccovnum'[1] + constraint get `num' + local c`num' = r(contents) + di "`c`num''" + constraint drop `num' + + *if (mĂȘme dimension) { + local coverror = `rnames'[1] + di "`coverror'" + *} + constraint 1001 [/]cov(L1_1,L2_1)#0bn.grp_v1 - [/]cov(L1_1,L2_1)#1.grp_v1 = 0 + + } + } + + + + + + + stop +} + + + + + + + + + + + /************************************************************************************************************** + DIF : Model B + ***************************************************************************************************************/ + +levelsof `group', local(levs) +tokenize `levs' +local length = wordcount("`levs'") +forvalues l = 1/`length' { + local level`l' = ``l'' +} +local l + +local i = 1 +local j = 1 +local pp = 0 +local s +local cl +foreach p in `partition' { + local l = 1 + local pp = `pp'+`p' + local s `s' (L`i'_1 -> `bloca`i'') + local cl `cl' means(`level1':L`i'_1@0) var(`level1':L`i'_1@1) + forvalues k = 1/`=`nbdims'-1' { + if (`=`i'+`k''<=`nbdims') { + local covl `covl' L`i'_1*L`=`i'+`k''_1 + } + } + + local j = `pp'+1 + local i = `i'+1 +} + + + +/* dĂ©finition des contraintes */ + +constraint drop _all +tokenize `varlist' + +local c = 1 +local i = 1 +local j = 1 +local pp = 0 +foreach p in `partition' { + local pp = `pp'+`p' + while `j'<= `pp' { + constraint `c' [``j'']`level1'bn.`group'#c.L`i'_1 - [``j'']`level2'.`group'#c.L`i'_1 = 0 + local ++j + local ++c + } + local ++i +} + +local i = 1 +foreach v of varlist `varlist' { + if `i'<=`nbitems' { + constraint `c' [``i'']`level1'bn.`group' - [``i'']`level2'bn.`group' = 0 + local ++c + local ++i + } +} + +local i = 1 +foreach v of varlist `varlist' { + if `i'<=`nbitems' { + constraint `c' [/]var(e.``i'')#`level1'bn.`group' - [/]var(e.``i'')#`level2'bn.`group' = 0 + local ++c + local ++i + } +} + + + +constraint list + + + + + +//local z "`s', `cl' iterate(`iterate') method(`method') `sb' group(`group') ginvariant(mcoef mcons merrvar) noanchor forcenoanchor" +//local z "`s', `cl' iterate(`iterate') method(`method') `sb' group(`group') ginvariant(covex) constraints(1/`=`nbitems'*3')" +//local z "`s', `cl' iterate(`iterate') method(`method') `sb' group(`group') ginvariant(mcoef mcons merrvar ) constraints(`=`nbitems'+1'/`=`nbitems'*3') noanchor forcenoanchor" +local z "`s', `cl' iterate(`iterate') method(`method') `sb' group(`group') ginvariant(mcoef) noanchor forcenoanchor" + +di in red "DIF : model B" + +di as text "sem `z' constraints(`=`nbitems'+1'/`=`nbitems'*3') " + +sem `z' constraints(1/`=`nbitems'*3') + +est store modelB +est store modelBref + +lrtest modelA modelB + + +if r(p) < 0.05 { +local stop = 0 + +while (`stop'!=1) { + + estat ginvariant, showpclass(mcoef mcons merrvar) + qui ret li + matrix m = r(test) + matrix m2 = m[.,4..6] + tempvar number rname chi df p + svmat2 m2, rnames(`rname') names(`chi' `df' `p') full + gen `number' = . + local c = 1 + forvalues i = 1(2)`=`nbitems'*2' { + qui replace `number' = `c' in `i' + local ++c + } + + local c = `=`nbitems'+1' + forvalues i = 2(2)`=`nbitems'*2' { + qui replace `number' = `c' in `i' + local ++c + } + + local c = `=`nbitems'*2+1' + forvalues i = `=`nbitems'*2+1'/`=`nbitems'*3' { + qui replace `number' = `c' in `i' + local ++c + } + + qui sort `p' + list `number' `rname' `chi' `df' `p' in 1/`=`nbitems'*3' + //list `number' `p' + local num = `number'[1] + //di `num' + constraint get `num' + local c`num' = r(contents) + di "`c`num''" + constraint drop `num' + constraint list _all + + di in red "ModĂšle aprĂšs avoir retirĂ© `c`num''" + + sem `z' constraints(1/`=`nbitems'*3') + + est store modelBtest + lrtest modelBref modelBtest + + if r(p) >= 0.05 { + local stop = 1 + } + else { + est store modelBref + di in red "donc on retire `c`num''" + } + + *estat ginvariant, showpclass(mcoef mcons merrvar) + +} + +} // fin if LRT < 0.05 + + +/************************************************************************************************************* +Model 1 +**************************************************************************************************************/ + + +stop +} // fin if(group) + + + + +/************* +Response-Shift +*************/ + + +/************************************************************************************************************** +Model 1 +***************************************************************************************************************/ +tokenize `varlist' + +local ii = 1 +local s +local stop = 0 +local i = 1 + + +foreach x in `varlist' { + local var`i' = "`x'" + local ++i +} + +local i = 1 +foreach x in `partition' { + local part`i' = `x' +} + +forvalues i=1/`nbitems' { + local cov12b `cov12b' e.``i''*e.``=`i'+`nbitems''' +} + +local k = 1 +local i = 1 +local j = 0 +local pp = 0 +local cl +foreach p in `partition' { + local pp = `pp'+`p' + while (`j'<`pp') { + local bloca`k' `bloca`k'' `var`i'' + local blocb`k' `blocb`k'' `var`=`i'+`nbitems''' + //di "`var`i''" + local i = `i'+1 + local j = `j'+1 + } + //di in red `j' + //order `var`j''-`var`pp'' + //order `var`=`j'+`nbitems'''-`var`=`pp'+`nbitems''' + + + local ++k +} + + +local i = 1 +local j = 1 +local pp = 0 +local s +foreach p in `partition' { + local pp = `pp'+`p' + local s `s' (L`i'_1 -> `bloca`i'') (L`i'_2 -> `blocb`i'') + local cl `cl' means(L`i'_1@0) means(L`i'_2@0) var(L`i'_1@1) var(L`i'_2@1) + local covl `covl' L`i'_1*L`i'_2 + forvalues k = 1/`=`nbdims'-1' { + if (`=`i'+`k''<=`nbdims') { + local covl `covl' L`i'_1*L`=`i'+`k''_1 L`i'_2*L`=`i'+`k''_2 // uniquement mĂȘme trait latent ou mĂȘme temps + //local covl `covl' L`i'_1*L`=`i'+`k''_1 L`i'_2*L`=`i'+`k''_2 L`i'_1*L`=`i'+`k''_2 + } + } + + local j = `pp'+1 + local i = `i'+1 +} + + +if "`onlycovl'" != "" { + local z "`s', covstruct(_lexogenous, diagonal) `cl' cov(`cov12b' `covl') iterate(`iterate') method(`method') `sb'" +} +else { + local z "`s', `cl' cov(`cov12b') iterate(`iterate') method(`method') `sb'" +} + + +//local z1 "`s', covstruct(_lexogenous, diagonal) cov(`cov12b' `covl') iterate(`iterate') method(`method') `sb'" + +`qui' di "sem `z'" + +di as result "Step 1: Measurement model" +di as text "Model 1 estimation..." + +qui sem `z' + +//ll + + + +qui est store model1 + + +//local s "sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''), var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method') cov(`cov12b' `covs')" +//sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''), var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method') cov(`cov12b' `covs') iterate(`iterate') nolog + +//estat gof, stat(all) + + +if ("`cfarmsea'"!="" | "`cfacfi'"!="") { + +while (`ii' == 1 | "`e'" != "") & `stop'!=1 { + if `ii' == 1 & ("`cfarmsea'"!="" | "`cfacfi'"!="") { + di + di _n "{bf:step 1:} {text:(model 1 without auto-search of modification indices)}" + } + + if "`covs'" != "" & ("`cfarmsea'"!="" | "`cfacfi'"!=""){ + di _n "{bf:step `ii':} {text:`covsi'}" + } + local covsi + + /* Model 1 without covariances between errors */ + + qui sem `z' cov(`covs') + est store model1 + //qui sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''), var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method') cov(`cov12b' `covs') iterate(`iterate') nolog + qui estat gof, stat(all) + + /* Looking for modification indices */ + + if ("`cfarmsea'"!="" | "`cfacfi'"!="") { + local stoprmsea = 0 + local stopcfi = 0 + if "`cfarmsea'"!="" { + qui estat gof + di "rmsea =" round(r(rmsea),0.001) + if r(rmsea)<=`cfarmsea' { + local stoprmsea = 1 + } + //else local stoprmsea = 0 + } + else local stoprmsea = 1 + if "`cfacfi'"!="" { + qui estat gof + di "cfi =" round(r(cfi),0.001) + if r(cfi)>=`cfacfi' { + local stopcfi = 1 + } + //else local stopcfi = 0 + } + else local stopcfi = 1 + + + + /* OR */ + if "`cfaor'"!="" { + if `stoprmsea'==1 | `stopcfi'==1 { + local stop = 1 + } + } + /* AND */ + if "`cfaor'"=="" { + if `stoprmsea'==1 & `stopcfi'==1 { + local stop = 1 + } + } + } + + + if ("`cfarmsea'"!="" | "`cfacfi'"!="") & `stop'!=1 { + qui estat mindices, showpclass(mcons merrvar) + tempname mm nomcol + mat `mm' = r(mindices) + //mat li `mm' + + svmat2 `mm' , r(`nomcol') full + gsort - `mm'1 + + local nrows = rowsof(`mm') + + local y = 1 + local i = 0 + //local partition `nbitems' `nbitems' + foreach x of numlist `partition' { + local ++i + if `i' == 1 local s = `x' + else local s = `s' +`x' + + forvalues w = `y'/`s' { + local class_`var`w'' = `i' + local class_`var`=`w'+`nbitems''' = `i'+`nbitems' + *di "`var`w''" + *di "`class_`var`w'''" + *di "`var`=`w'+`nbitems'''" + *di "`class_`var`=`w'+`nbitems''''" + } + local y = `s'+1 + } + + local f1b + local f2b + local f + local f1 + local f2 + forvalues i = 1/`nrows' { + local tmp3=`nomcol'[`i'] + lstrfun e, subinstr("`tmp3'","cov(","",.) + lstrfun e, subinstr("`e'","/","",.) + lstrfun e, subinstr("`e'",")","",.) + lstrfun e, subinstr("`e'",":_cons","",.) + lstrfun e, subinstr("`e'",",","*",.) + + lstrfun d, subinstr("`e'",","," ",.) + lstrfun d, subinstr("`d'","e.","",.) + lstrfun d, subinstr("`d'","*"," ",.) + + qui replace `nomcol' = "`d'" in `i' + + local d = `nomcol'[`i'] + + //tokenize "`d'" + local v1 = substr("`d'",1,strpos("`d'", " ")) + local v2 = substr("`d'",strpos("`d'", " ")+1,.) + + + + + if ("`class_`v1''" != "`class_`v2''") /*| (`class_`v1'' > `nbitems') */ { /*** enlever le | si on cherche aussi au temps2 ***/ + qui replace `nomcol' = "" in `i' + } + + local tmp3=`nomcol'[`i'] + + + if "`tmp3'" != "" { + //di in red "`tmp3'" + local e1 = substr("`tmp3'",1,strpos("`tmp3'", " ")-1) + local e2 = substr("`tmp3'",strpos("`tmp3'", " ")+1,.) + local ni = `nbitems'*2 + forvalues jj = 1/`ni' { + if `jj' <= `nbitems' { + + if "`e1'" == "``jj''" { + local f1 = "``jj''" + local f1b = "``=`jj'+`nbitems'''" + } + if "`e2'" == "``jj''" { + local f2 = "``jj''" + local f2b = "``=`jj'+`nbitems'''" + } + } + else if `jj' > `nbitems' { /*** remettre si on cherche aussi au temps2 ***/ + if "`e1'" == "``jj''" { + local f1 = "``jj''" + local f1b = "``=`jj'-`nbitems'''" + //di in red "`f1b'" + + } + if "`e2'" == "``jj''" { + local f2 = "``jj''" + local f2b = "``=`jj'-`nbitems'''" + } + } + + } + if "`f1b'"!="" & "`f2b'"!="" { + local f = "e.`f1b'*e.`f2b'" + //di in red "`f' en plus de `e'" + } + + + continue, break + } + else { + local e + local f + local f1b + local f2b + } + } + + local covsi "`e' (`f') " + local covs `covs' `e' `f' + local f + drop `mm'1-`nomcol' + + } + + //if e(converged) == 0 di in red "Warning : model did not converge after 50 iterations" + local ++ii + +} + +} + + + +/* Model 1 final */ + + +//di "{bf:Model 1 (step 1):}" +//local s "sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''), var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method') cov(`cov12b' `covs') " +//di as text "`s'" +//di "sem `z' cov(`covs')" +local sem1 `z' cov(`covs') +//sem + +//est replay model1 + +qui estat gof, stats(all) +local tli1=r(tli) +local cfi1=r(cfi) +local srmr1=r(srmr) +local rmsea1=r(rmsea) +local ubrmsea1=r(ub90_rmsea) +local lbrmsea1=r(lb90_rmsea) +local chi21=r(chi2_ms) +local df1=r(df_ms) +local dfc1=6*`nbitems'+1 +local p1=r(p_ms) +local bic1=r(bic) + +if "`sb'" != "" { + local cmodel1 = e(sbc_ms) + //local chi21=r(chi2_ms) +} + +//di in red `chi21' + +*di as text "End of step 1" + + +/************************************************************************************************************** +Model 2 +***************************************************************************************************************/ + +di +if "`test'" != "" { + di as result "Step 2: Overall test of response shift" +} +else { + di as result "Step 2: Estimation of ""no response shift"" model (no overall test is performed because the ""test"" option was not specified)" +} +di as text "Model 2 estimation..." + +local i = 1 +local j = 1 +local pp = 0 +local s +local k = 1 +local var +local cl +local covl +foreach p in `partition' { + local pp = `pp'+`p' + while `j'<= `pp' { + local s `s' (L`i'_1@load`k' _cons@int`k' -> `var`j'') (L`i'_2@load`k' _cons@int`k' -> `var`=`j'+`nbitems''') + local var `var' var(e.`var`j''@var`k') var(e.`var`=`j'+`nbitems'''@var`k') + local ++j + local ++k + } + local cl `cl' means(L`i'_1@0) var(L`i'_1@1) var(L`i'_2) means(L`i'_2) + local covl `covl' L`i'_1*L`i'_2 + forvalues g = 1/`=`nbdims'-1' { + if (`=`i'+`g''<=`nbdims') { + //di in red `g' + local covl `covl' L`i'_1*L`=`i'+`g''_1 L`i'_2*L`=`i'+`g''_2 + } + } + + local ++i +} + + +local z "`s', `var' covstruct(_lexogenous, diagonal) `cl' cov(`cov12b' `covl' `covs') iterate(`iterate') method(`method') `sb'" + +//di "sem `z'" +//di "model 2" + +qui sem `z' +local m2 = e(cmdline) +//qui `m2' stand +est store model2 +est store model2init + + +/* +tempname b V +matrix `b'=r(table) +matrix `V'=e(V) +//mat li `V' + +local i = 1 +foreach p in `partition' { + local truechange_L`i'=`b'[1,`=`nbitems'*4+`i''] + local Vtruechange_L`i'=`V'[`=`nbitems'*4+`i'',`=`nbitems'*4+`i''] + //di `Vtruechange_L`i'' + local ++i +} + + +//estat gof +qui estat gof, stat(all) +local iter2=e(ic) +local tli2=r(tli) +local cfi2=r(cfi) +local srmr2=r(srmr) +local rmsea2=r(rmsea) +local ubrmsea2=r(ub90_rmsea) +local lbrmsea2=r(lb90_rmsea) +local pclose2=r(pclose) +local chi22=r(chi2_ms) +local df2=r(df_ms) +local dfc2=3*`nbitems'+3 +local p2=r(p_ms) +local bic2=r(bic) +local convergence2=e(converged) + + +if "`sb'" != "" { + local cmodel2 = e(sbc_ms) + //local chi22=r(chi2_ms) +} + + +ereturn matrix b2=`b' +ereturn scalar iter2=`iter2' +ereturn scalar tli2=`tli2' +ereturn scalar cfi2=`cfi2' +ereturn scalar srmr2=`srmr2' +ereturn scalar rmsea2=`rmsea2' +ereturn scalar ubrmsea2=`ubrmsea2' +ereturn scalar lbrmsea2=`lbrmsea2' +ereturn scalar pclose2=`pclose2' +ereturn scalar chi22=`chi22' +ereturn scalar df2=`df2' +ereturn scalar dfc2=`dfc2' +ereturn scalar p2=`p2' +ereturn scalar bic2=`bic2' +ereturn scalar convergence2=`convergence2' + +local i = 1 +foreach p in `partition' { + ereturn scalar truechange_L`i'=`truechange_L`i'' + ereturn scalar Vtruechange_L`i'=`Vtruechange_L`i'' + ereturn scalar setruechange_L`i'=`=sqrt(`Vtruechange_L`i'')' + ereturn scalar ztruechange_L`i'=`=`truechange_L`i''/sqrt(`Vtruechange_L`i'')' + ereturn scalar ptruechange_L`i'=`=2-2*normal(abs(`truechange_L`i'')/sqrt(`Vtruechange_L`i''))' + local ++i +} +*/ + + + + + + +/************************************************************************************************************** +Autre syntaxe +***************************************************************************************************************/ + +constraint drop _all +tokenize `varlist' + +local all +local i = 1 +local j = 1 + +//local moins = 0 +foreach v of varlist `varlist' { + if `i'<=`nbitems' { + local current [/]var(e.``i'') - [/]var(e.``=`i'+`nbitems''') = 0 + if !strpos("`all'","`current'") { + constraint `j' [/]var(e.``i'') - [/]var(e.``=`i'+`nbitems''') = 0 + //local moins = 0 + local ++j + } + /*else { + local moins = 1 + }*/ + local all `all' [/]var(e.``i'') - [/]var(e.``=`i'+`nbitems''') = 0 + local ++i + } +} + + + +local all +local i = 1 +foreach v of varlist `varlist' { + if `i'<=`nbitems' { + local current [/]var(e.``i'') - [/]var(e.``=`i'+`nbitems''') = 0 + if !strpos("`all'","`current'") { + constraint `j' [``i'']_cons - [``=`i'+`nbitems''']_cons = 0 + local ++j + } + local all `all' [/]var(e.``i'') - [/]var(e.``=`i'+`nbitems''') = 0 + local ++i + } +} + + +local c = `j' +local i = 1 +local j = 1 +local pp = 0 +foreach p in `partition' { + local pp = `pp'+`p' + while `j'<= `pp' { + constraint `c' [``j'']L`i'_1 - [``=`j'+`nbitems''']L`i'_2 = 0 + //local s `s' (L`i'_1@load`k' _cons@int`k' -> `var`j'') (L`i'_2@load`k' _cons@int`k' -> `var`=`j'+`nbitems''') + local ++j + local ++c + //local ++k + } + local ++i +} + +//constraint list + + + +//di "Model 2 (step 2)" // "Model 2 (autre syntaxe)" +//di "`sem1'" +`qui' di "sem `sem1' `cl' constraints(1/`=`nbitems'*3')" +//local sem2 "`s', covstruct(_lexogenous, diagonal) cov(`cov12b' `covl') iterate(`iterate') method(`method') constraints(1/`=`nbitems'*3')" +//di "`sem2'" + +set matsize 11000 +qui sem `sem1' `cl' constraints(1/`=`nbitems'*3') +est store model2 +est store model2init + +/* +local m2 = e(cmdline) +qui `m2' stand +est store model2init +*/ + + + + + + + + +if "`sb'" != "" { + local cmodel2 = e(sbc_ms) + //local chi22=r(chi2_ms) +} + + + + +tempname b V +matrix `b'=r(table) +matrix `V'=e(V) +//mat li `V' + +local i = 1 +foreach p in `partition' { + local truechange_L`i'=`b'[1,`=`nbitems'*4+`i''] + local Vtruechange_L`i'=`V'[`=`nbitems'*4+`i'',`=`nbitems'*4+`i''] + local setruechange_L`i'=`=sqrt(`Vtruechange_L`i'')' + local ztruechange_L`i'=`=`truechange_L`i''/sqrt(`Vtruechange_L`i'')' + local ptruechange_L`i'=`=2-2*normal(abs(`truechange_L`i'')/sqrt(`Vtruechange_L`i''))' + local ++i +} + +//estat gof +qui estat gof, stat(all) +local iter2=e(ic) +local tli2=r(tli) +local cfi2=r(cfi) +local srmr2=r(srmr) +local rmsea2=r(rmsea) +local ubrmsea2=r(ub90_rmsea) +local lbrmsea2=r(lb90_rmsea) +local pclose2=r(pclose) +local chi22=r(chi2_ms) +local df2=r(df_ms) +local dfc2=3*`nbitems'+3 +local p2=r(p_ms) +local bic2=r(bic) +local convergence2=e(converged) + +/* +ereturn matrix b2=`b' +ereturn scalar iter2=`iter2' +ereturn scalar tli2=`tli2' +ereturn scalar cfi2=`cfi2' +ereturn scalar srmr2=`srmr2' +ereturn scalar rmsea2=`rmsea2' +ereturn scalar ubrmsea2=`ubrmsea2' +ereturn scalar lbrmsea2=`lbrmsea2' +ereturn scalar pclose2=`pclose2' +ereturn scalar chi22=`chi22' +ereturn scalar df2=`df2' +ereturn scalar dfc2=`dfc2' +ereturn scalar p2=`p2' +ereturn scalar bic2=`bic2' +ereturn scalar convergence2=`convergence2' +*/ + +local i = 1 +foreach p in `partition' { + return scalar truechange_L`i'_2=`truechange_L`i'' + return scalar Vtruechange_L`i'_2=`Vtruechange_L`i'' + return scalar setruechange_L`i'_2=`=sqrt(`Vtruechange_L`i'')' + return scalar ztruechange_L`i'_2=`=`truechange_L`i''/sqrt(`Vtruechange_L`i'')' + return scalar ptruechange_L`i'_2=`=2-2*normal(abs(`truechange_L`i'')/sqrt(`Vtruechange_L`i''))' + local ++i +} + +/* +local i = 1 +foreach p in `partition' { + di as text "Observed change (i.e. without accounting for response shift) for `ltname`i'' is " %4.3f `truechange_L`i'' " (p = " %4.3f `ptruechange_L`i'' ")" + local ++i +} +*/ + +if "`test'"!="" { + if "`sb'"=="" { + local chi221=`chi22'-`chi21' + local df21=`df2'-`df1' + local p21=1-chi2(`df21',`chi221') + local cmodel1= 1 + local cmodel2 = 1 + } + else { + local cd=(`df2'*`cmodel2'-`df1'*`cmodel1')/(`df2'-`df1') + local df21=`df2'-`df1' + local chi221=(`chi22'-`chi21')/`cd' + local p21 = 1-chi2(`df21',`chi221') + //local adjust = " (sb)" + } + //di in red `chi21' + //di in red `chi22' + + if (`p21'>0.05) { + local testno=" no" + } + else { + //local p21 = round(`p21',0.001) + //if `p21'<0.001 { + //local p21 = "< 0.001" + //} + local testno = "" + } + + di "{hline 51}" + di in gr /*_col(39) "Test of global Response-Shift " _col(79) "Comparison with model 1"*/ + di in gr "Models" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" /*_col(39) "Chi-square" _col(54) "df" _col(59) "p-value" *_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/ + di "{hline 51}" + di in gr "Model 1" _col(20) %8.2f `=`chi21'/`cmodel1'' _col(30) %4.0f `df1' _col(37) %6.4f `p1' _col(45) %7.2f `bic1' + di in gr "Model 2" _col(20) %8.2f `=`chi22'/`cmodel2'' _col(30) %4.0f `df2' _col(37) %6.4f `p2' _col(45) %7.2f `bic2' /*_col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' *_col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'*/ + di "{hline 51}" + + di "chi2 = " %4.2f `chi221' " (`df21')" + di "p-value of global test = " %4.3f `p21' + //di "=> `no' Step 3" +} +else local testno = "" + +if "`testno'"=="" { + +} +else { + di as text "We skip step 3 because the overall test for response shift is non significant" +} + +*di as text "End of step 2" + + + +/*** Etape 3 ***/ + +forvalues i = 1/`=`nbitems'*3' { + constraint get `i' + local c`i' = r(contents) + //local csave`i' = r(contents) +} + +matrix numcont = J(1,`=`nbitems'*3',.) +forvalues i = 1/`=`nbitems'*3'{ + if `i'<=`nbitems' { + local noms "`noms' NUR_``i''" + } + else if `i' > `nbitems' & `i'<=`=`nbitems'*2' { + local noms "`noms' UR_``=`i'-`nbitems'''" + } + else if `i' > `=`nbitems'*2' { + local noms "`noms' REP_``=`i'-2*`nbitems'''" + } + +} +matrix colnames numcont = `noms' + +if "`hierarchical'" != "" & "`testno'" !=" no"{ + + +/************************************************************************************************************** +Model 3 / Non Uniform recalibration +***************************************************************************************************************/ + +di +di as result "Step 3 --Non Uniform recalibration--" + +timer clear 20 +timer on 20 +local nbsign = 0 +di as text "Iteration 1 running" +local pbconv = 0 +local o = 1 +local k = 1 +local j = 1 +local stop = 0 +//local nonunif +while (`j'<=`nbitems' & `stop'!=1) { + local max = -1 + local c = 0 + local stop = 0 + timer clear 10 + timer on 10 + forvalues i = 1/`nbitems' { + constraint get `i' + if r(defined)== 1 { + constraint drop `i' + qui sem `sem1' `cl' constraints(1/`=`nbitems'*3') forcenoanchor + //constraint list + constraint `i' `c`i'' + //constraint list + //di "AprĂšs avoir enlevĂ© `c`i'' : " + if "`adjust'" != "" { + local nbtest = `nbitems'-`j'+1 + } + else local nbtest = 1 + //di "nbtest = `nbtest'" + qui eret li + if e(converged) == 1 { + est store model3 + if "`sb'" == "" { + `qui' lrtest model2 model3 + if r(p) < `=0.05/`nbtest'' { + local nbsign = `nbsign'+1 + } + if r(chi2) > `max' & r(p) < `=0.05/`nbtest'' { + local max = r(chi2) + local c = `i' + } + } + else { + qui estat gof, stats(all) + local df3=r(df_ms) + local cmodel3 = e(sbc_ms) + local chi23=r(chi2sb_ms) + local cd=(`df2'*`cmodel2'-`df3'*`cmodel3')/(`df2'-`df3') + local df23=`df2'-`df3' + local chi223=(`chi22'-`chi23')/`cd' + local p23 = 1-chi2(`df23',`chi223') + //di "lr(sb) = `chi223'" + //di "p = `p23'" + if `p23' < `=0.05/`nbtest'' { + local nbsign = `nbsign'+1 + } + if `chi223' > `max' & `p23' < `=0.05/`nbtest'' { + local max = `chi223' + local c = `i' + } + } + } + else { + local ++pbconv + //`qui' di "model did not converge (`pbconv' in total)" + } + + } + } + //local mmax = `max' + //di `mmax' + //local cc`j' = `c' + //di `cc`j'' + + if `c' == 0 { + //matrix numcont[1,`c']=0 + local stop = 1 + //di "stop" + } + + if `c'!=0 { + constraint get `c' + matrix numcont[1,`c']=1 + //di "donc on retire" + //di r(contents) + local reprio`k' = r(contents) + local ordre_reprio_`k' = `o' + local ++o + constraint drop `c' + local c`c' + local ++k + } + qui sem `sem1' `cl' constraints(1/`=`nbitems'*3') + qui est store model2 + if "`sb'" != "" { + qui estat gof, stats(all) + local df2=r(df_ms) + local cmodel2 = e(sbc_ms) + local chi22=r(chi2_ms) + } + timer off 10 + qui timer list 10 + local ++j + if `j'==2 { + if (`nbsign'==0) local nbsign=1 + di as text "Iteration `j' running" " (Based on the results of the first iteration, step 3 --non-uniform recalibration-- should last approximately " `=round(`r(t10)'*`nbsign')' " seconds)" + } + else { + di as text "Iteration `j' running" + } +} + +di as text "Constraints removed (non-uniform recalibration): " +forvalues i = 1/`nbitems' { + if "`nonunif`i''"!="" di "`nonunif`i''" +} + + + +/************************************************************************************************************** +Model 3 / Uniform recalibration +***************************************************************************************************************/ + + + +di +di as result "Step 3 --Uniform recalibration--" + +timer clear 20 +timer on 20 +local nbsign = 0 +di as text "Iteration 1 running..." +local pbconv = 0 +local o = 1 +local k = 1 +local j = 1 +local stop = 0 +//local nonunif +while (`j'<=`nbitems' & `stop'!=1) { + local max = -1 + local c = 0 + local stop = 0 + timer clear 10 + timer on 10 + forvalues i = `=`nbitems'+1'/`=`nbitems'*2' { + constraint get `i' + if r(defined)== 1 { + constraint drop `i' + qui sem `sem1' `cl' constraints(1/`=`nbitems'*3') forcenoanchor + //constraint list + constraint `i' `c`i'' + //constraint list + //di "AprĂšs avoir enlevĂ© `c`i'' : " + if "`adjust'" != "" { + local nbtest = `nbitems'-`j'+1 + } + else local nbtest = 1 + //di "nbtest = `nbtest'" + qui eret li + if e(converged) == 1 { + est store model3 + if "`sb'" == "" { + `qui' lrtest model2 model3 + if r(p) < `=0.05/`nbtest'' { + local nbsign = `nbsign'+1 + } + if r(chi2) > `max' & r(p) < `=0.05/`nbtest'' { + local max = r(chi2) + local c = `i' + } + } + else { + qui estat gof, stats(all) + local df3=r(df_ms) + local cmodel3 = e(sbc_ms) + local chi23=r(chi2sb_ms) + local cd=(`df2'*`cmodel2'-`df3'*`cmodel3')/(`df2'-`df3') + local df23=`df2'-`df3' + local chi223=(`chi22'-`chi23')/`cd' + local p23 = 1-chi2(`df23',`chi223') + //di "lr(sb) = `chi223'" + //di "p = `p23'" + if `p23' < `=0.05/`nbtest'' { + local nbsign = `nbsign'+1 + } + if `chi223' > `max' & `p23' < `=0.05/`nbtest'' { + local max = `chi223' + local c = `i' + } + } + } + else { + local ++pbconv + //`qui' di "model did not converge (`pbconv' in total)" + } + + } + } + //local mmax = `max' + //di `mmax' + //local cc`j' = `c' + //di `cc`j'' + + if `c' == 0 { + //matrix numcont[1,`c']=0 + local stop = 1 + //di "stop" + } + + if `c'!=0 { + constraint get `c' + matrix numcont[1,`c']=1 + //di "donc on retire" + //di r(contents) + local reprio`k' = r(contents) + local ordre_reprio_`k' = `o' + local ++o + constraint drop `c' + local c`c' + local ++k + } + qui sem `sem1' `cl' constraints(1/`=`nbitems'*3') + qui est store model2 + if "`sb'" != "" { + qui estat gof, stats(all) + local df2=r(df_ms) + local cmodel2 = e(sbc_ms) + local chi22=r(chi2_ms) + } + timer off 10 + qui timer list 10 + local ++j + if `j'==2 { + if (`nbsign'==0) local nbsign=1 + di as text "Iteration `j' running..." " (Based on the results of the first iteration, step 3 --uniform recalibration-- should last approximately " `=round(`r(t10)'*`nbsign')' " seconds)" + } + else { + di as text "Iteration `j' running..." + } +} +di as text "Constraints removed (uniform recalibration): " +forvalues i = 1/`=`nbitems'*3' { + if "`unif`i''"!="" di "`unif`i''" +} + + +/************************************************************************************************************** +Model 3 / Reprioritization +***************************************************************************************************************/ + +di +di as result "Step 3 --Reprioritization--" + +timer clear 20 +timer on 20 +local nbsign = 0 +di as text "Iteration 1 running..." +local pbconv = 0 +local o = 1 +local k = 1 +local j = 1 +local stop = 0 +//local nonunif +while (`j'<=`nbitems' & `stop'!=1) { + local max = -1 + local c = 0 + local stop = 0 + timer clear 10 + timer on 10 + forvalues i = `=`nbitems'*2+1'/`=`nbitems'*3' { + constraint get `i' + if r(defined)== 1 { + constraint drop `i' + qui sem `sem1' `cl' constraints(1/`=`nbitems'*3') forcenoanchor + //constraint list + constraint `i' `c`i'' + //constraint list + //di "AprĂšs avoir enlevĂ© `c`i'' : " + if "`adjust'" != "" { + local nbtest = `nbitems'-`j'+1 + } + else local nbtest = 1 + //di "nbtest = `nbtest'" + qui eret li + if e(converged) == 1 { + est store model3 + if "`sb'" == "" { + `qui' lrtest model2 model3 + if r(p) < `=0.05/`nbtest'' { + local nbsign = `nbsign'+1 + } + if r(chi2) > `max' & r(p) < `=0.05/`nbtest'' { + local max = r(chi2) + local c = `i' + } + } + else { + qui estat gof, stats(all) + local df3=r(df_ms) + local cmodel3 = e(sbc_ms) + local chi23=r(chi2sb_ms) + local cd=(`df2'*`cmodel2'-`df3'*`cmodel3')/(`df2'-`df3') + local df23=`df2'-`df3' + local chi223=(`chi22'-`chi23')/`cd' + local p23 = 1-chi2(`df23',`chi223') + //di "lr(sb) = `chi223'" + //di "p = `p23'" + if `p23' < `=0.05/`nbtest'' { + local nbsign = `nbsign'+1 + } + if `chi223' > `max' & `p23' < `=0.05/`nbtest'' { + local max = `chi223' + local c = `i' + } + } + } + else { + local ++pbconv + //`qui' di "model did not converge (`pbconv' in total)" + } + + } + } + //local mmax = `max' + //di `mmax' + //local cc`j' = `c' + //di `cc`j'' + + if `c' == 0 { + //matrix numcont[1,`c']=0 + local stop = 1 + //di "stop" + } + + if `c'!=0 { + constraint get `c' + matrix numcont[1,`c']=1 + //di "donc on retire" + //di r(contents) + local reprio`k' = r(contents) + local ordre_reprio_`k' = `o' + local ++o + constraint drop `c' + local c`c' + local ++k + } + qui sem `sem1' `cl' constraints(1/`=`nbitems'*3') + qui est store model2 + if "`sb'" != "" { + qui estat gof, stats(all) + local df2=r(df_ms) + local cmodel2 = e(sbc_ms) + local chi22=r(chi2_ms) + } + timer off 10 + qui timer list 10 + local ++j + if `j'==2 { + if (`nbsign'==0) local nbsign=1 + di as text "Iteration `j' running..." " (Based on the results of the first iteration, step 3 --reprioritization-- should last approximately " `=round(`r(t10)'*`nbsign')' " seconds)" + } + else { + di as text "Iteration `j' running..." + } +} + +di as text "Constraints removed (reprioritization) : " +forvalues i = 1/`nbitems' { + if "`reprio`i''"!="" di "`reprio`i''" +} + + + + +di as result "Summary of step 3 " +/* +di "`pbconv' model(s) did not converge" +di +di as text "The following constraints were removed:" +forvalues i = 1/`=`nbitems'*3' { + if "`nonunif`i''"!="" di "`nonunif`i'' (order = `ordre_nonunif_`i'')" +} +forvalues i = 1/`=`nbitems'*3' { + if "`unif`i''"!="" di "`unif`i'' (order = `ordre_unif_`i'')" +} +forvalues i = 1/`=`nbitems'*3' { + if "`reprio`i''"!="" di "`reprio`i'' (order = `ordre_reprio_`i'')" +} +//constraint list +*/ +} + + + + + + + + +else if "`hierarchical'" == "" & "`testno'" !=" no"{ + +di +di as result "Step 3: Detection of response shift" + +timer clear 20 +timer on 20 +local nbsign = 0 +di as text "Iteration 1 running " _c +local pbconv = 0 +local o = 1 +local k = 1 +local j = 1 +local stop = 0 +local nonunif +while (`stop'!=1) { + local max = -1 + local c = 0 + local stop = 0 + timer clear 10 + timer on 10 + forvalues i = 1/`=`nbitems'*3' { + constraint get `i' + if r(defined)== 1 { + //di as text "`j'_`i'" + constraint drop `i' + qui sem `sem1' `cl' constraints(1/`=`nbitems'*3') forcenoanchor + //constraint list + constraint `i' `c`i'' + //constraint list + `qui' di as text "After removing `c`i'' : " + qui eret li + if e(converged) == 1 { + est store model3 + if "`sb'" == "" { + qui lrtest model2 model3 + if "`adjust'" != "" { + local nbtest = `nbitems'*3-`j'+1 + } + else local nbtest = 1 + if r(p) < `=0.05/`nbtest'' { + local nbsign = `nbsign'+1 + } + `qui' di "nbtest = `nbtest'" + if r(chi2) > `max' & r(p) < `=0.05/`nbtest'' { + local max = r(chi2) + local c = `i' + } + } + else { + qui estat gof, stats(all) + local df3=r(df_ms) + local cmodel3 = e(sbc_ms) + local chi23=r(chi2_ms) + //di in red "chi22 = `chi22'" + //di in red "chi23 = `chi23'" + //di in red `cmodel2' + //di in red `cmodel3' + local cd=(`df2'*`cmodel2'-`df3'*`cmodel3')/(`df2'-`df3') + local df23=`df2'-`df3' + local chi223=(`chi22'-`chi23')/`cd' + local p23 = 1-chi2(`df23',`chi223') + //di "df2 = `df2'" + //di "df3 = `df3'" + di as text "cd = `cd'" + //di "chi223 = `chi223'" + //di "df23 = `df23'" + di as text "lr(sb) = `chi223'" + di as text "p = `p23'" + if `chi223' > `max' & `p23' < 0.05 { + local max = `chi223' + local c = `i' + } + } + } + else { + local ++pbconv + `qui' di "model did not converge (`pbconv' in total)" + } + + } + di %4.0f `=`i'/(`nbitems'*3)*100' "% " _c + } + + if `c' == 0 { + //matrix numcont[1,`c']=0 + local stop = 1 + //di "stop" + } + if `c'!=0 { + //di in red `c' + matrix numcont[1,`c']=1 + constraint get `c' + `qui' di "The following constraint was removed: " + `qui' di r(contents) + if `c'<=`nbitems' { + local nonunif`k' = r(contents) + local ordre_nonunif_`k' = `o' + local ++o + } + else if `c' > `nbitems' & `c'<=`=`nbitems'*2' { + local unif`k' = r(contents) + local ordre_unif_`k' = `o' + local ++o + } + else if `c' > `=`nbitems'*2' { + local reprio`k' = r(contents) + local ordre_reprio_`k' = `o' + local ++o + } + constraint drop `c' + local c`c' + local ++k + } + qui sem `sem1' `cl' constraints(1/`=`nbitems'*3') forcenoanchor + qui est store model2 + if "`sb'" != "" { + qui estat gof, stats(all) + local df2=r(df_ms) + local cmodel2 = e(sbc_ms) + local chi22=r(chi2_ms) + } + + timer off 10 + qui timer list 10 + local ++j + if `j'==2 { + di as text _n "(Based on the results of the first iteration, Step 3 should last approximately " `=round(`r(t10)'*`nbsign')' " seconds)" + di as text "Iteration 2 running " _c + } + else { + if `c'!=0 { + di as text _n "Iteration `j' running " _c + } + } +} +timer off 20 +qui timer list 20 +di _n "(Step 3 took "`=round(`r(t20)')' " seconds to complete)" +di +est store model3 + + +/* +di as text "Contraintes libĂ©rĂ©es (recalibration non-uniforme) : " +forvalues i = 1/`nbitems' { + if "`nonunif`i''"!="" di "`nonunif`i''" +}*/ + + +di as result "Summary of step 3 " +/* +di +di as text "`pbconv' model(s) did not converge" +di +di as text "The following constraints were removed:" +forvalues i = 1/`=`nbitems'*3' { + if "`nonunif`i''"!="" di "`nonunif`i'' (order = `ordre_nonunif_`i'')" +} +forvalues i = 1/`=`nbitems'*3' { + if "`unif`i''"!="" di "`unif`i'' (order = `ordre_unif_`i'')" +} +forvalues i = 1/`=`nbitems'*3' { + if "`reprio`i''"!="" di "`reprio`i'' (order = `ordre_reprio_`i'')" +} +//constraint list +*/ +} + + + +est store model4 +local m4 = e(cmdline) + +local i = 1 +foreach p in `partition' { + local cl `cl' means(L`i'_1@0) var(L`i'_1@1) var(L`i'_2@1) means(L`i'_2) + local ++i +} + + + + +mat mt = numcont' + +local maxlength = 0 +foreach v of varlist `varlist' { + if length("`v'")>`maxlength' { + local maxlength = length("`v'") + } +} + +local et = "&|" +forvalues i=1/`=`nbitems'*3' { + local et "`et'" "&" +} +matrix colnames mt = "1 if RS detected" + +if "`testno'" == "" { + di as text "Notation: " + di as text "RS = response shift" + di as text "NUR = non-uniform recalibration" + di as text "UR = uniform recalibration" + di as text "REP = reprioritization" + local esp + forvalues i = 1/`=`nbitems'*3+2' { + local esp = "`esp'&" + } + matlist mt, cspec(& %~`=`maxlength'+4's & %18.0f & ) rspec("`esp'") + mat li mt + matrix rsitems = mt + return matrix rsitems = mt + di + *di as text "End of step 3" +} + + +/*********************** + Step 4 +************************/ +di as result "Step 4: Assessment of true change" +qui est rep model4 +qui est rest model4 + +tempname b V +matrix `b'=e(b) +matrix `V'=e(V) +//mat li `V' + +local i = 1 +foreach p in `partition' { + local truechange_L`i'_4=`b'[1,`=`nbitems'*4+`i''] + local Vtruechange_L`i'_4=`V'[`=`nbitems'*4+`i'',`=`nbitems'*4+`i''] + local setruechange_L`i'_4=`=sqrt(`Vtruechange_L`i'_4')' + local ztruechange_L`i'_4=`=`truechange_L`i'_4'/sqrt(`Vtruechange_L`i'_4')' + local ptruechange_L`i'_4=`=2-2*normal(abs(`truechange_L`i'_4')/sqrt(`Vtruechange_L`i'_4'))' + local ++i +} + +local i = 1 +foreach p in `partition' { + return scalar truechange_L`i'_4 = `truechange_L`i'_4' + return scalar Vtruechange_L`i'_4=`Vtruechange_L`i'_4' + return scalar setruechange_L`i'_4=`setruechange_L`i'_4' + return scalar ztruechange_L`i'_4=`ztruechange_L`i'_4' + return scalar ptruechange_L`i'_4=`ptruechange_L`i'_4' + local ++i +} + + + + + +local i = 1 +foreach p in `partition' { + //di as text "True change (i.e. when accounting for response shift) for `ltname`i'' is " %4.3f `truechange_L`i'_4' " (p = " %4.3f `ptruechange_L`i'_4' ")" + //di as text "Without accounting for response shift, the estimated change for `ltname`i'' would be " %4.3f `truechange_L`i'' " (p = " %4.3f `ptruechange_L`i'' ")" + //di + local ++i +} + + +/* LR test for LT means */ +qui est rest model4 +local m4 = e(cmdline) + + +forvalues i = 1/`P' { + local cm `cm' means(L`i'_2@0) +} +qui `m4' `cm' +qui est store model4_0 + +if `P' > 1 { + *di as text "Test if all LT means = 0 at time 2" + qui lrtest model4 model4_0 + qui ret li + if r(p) > 0.05 { + di as text "LT means are not significantly different from 0 (p=" %4.3f r(p) ")" + } + else { + di as text "LT means are significantly different from 0 (p=" %4.3f r(p) ")" + } +} + +/* Decomposition of observed change */ + +di +di as result "Decomposition of observed change" +di +/* +di as text "Notation:" +di as text "observed change = contribution of response shift + true change" +di as text "contribution of reponse shift = contribution of recalibration + contribution of reprioritization" +di +*/ + +qui est rest model4 +qui estat framework, fitted + +mat mu = r(mu) + +forvalues i = 1/`P' { + mat muLT`i' = mu[1,`nbitems'*2+`i'*2] +} + +mat gamma = r(Gamma) + +mat gamma1 = gamma[1...,1..1] +mat gamma2 = gamma[1...,2..2] +forvalues i=1(2)`=`P'*2' { + mat g1 = gamma[1...,`i'..`i'] + mat gamma1 = gamma1,g1 + mat g2 = gamma[1...,`i'+1..`i'+1] + mat gamma2 = gamma2,g2 +} +mat gamma1 = gamma1[1...,2...] +mat gamma2 = gamma2[1...,2...] + +mat alpha = r(alpha) + +local v = 1 +local c = 1 +local i = 1 +local j = 1 +local pp = 0 +foreach p in `partition' { + local pp = `pp'+`p' + while `j'<= `pp' { + local tc = 0 + local reprio = 0 + mat mui = mu + + local mu1 = mui[1,`j'] + local mu2 = mui[1,`j'+`p'] + local mu2mu1 = `mu2'-`mu1' + local oc`v' = `mu2mu1' + + local recalibration = alpha[1,`j'+`p']-alpha[1,`j'] + + mat tc = gamma1[`j',1...]*muLT`i'[1...,1...] + forvalues k = 1/`P' { + local t = el(tc,1,`k') + local tc = `tc'+`t' + } + local tc`v' = `tc' + + mat g1 = gamma1[`j',1...] + mat g2 = gamma2[`j'+`p',1...] + mat m = muLT`i'[1...,1...] + + mat reprio = (gamma2[`j'+`p',1...]-gamma1[`j',1...])*muLT`i'[1...,1...] + *mat li reprio + forvalues k = 1/`P' { + local r = el(reprio,1,`k') + local reprio = `reprio'+`r' + } + + + local rs = `recalibration'+`reprio' + local rs`v' = `rs' + + //di as text "Observed change for `var`v'' = " %10.3g `mu2mu1' " = " %10.3g `rs' " + " %10.3g `tc' + if (`rs'!=0) { + //di as text = "Contribution of response shift = " %10.3g `rs' " = " %10.3g `recalibration' " + " %10.3g `reprio' + } + else { + //di as text "(no repsonse shift for `var`v'')" + } + local ++j + local ++v + //di + } + local j = `j'+`p' + local pp = `pp'+`p' + local ++i +} + + + + + +/* Table */ + +local v = 1 +forvalues i=1/`=`nbitems'*3' { + if rsitems[`i',1]==1 { + if `i' > `nbitems' & `i'<=`=`nbitems'*2' { + local v = `i'-`nbitems' + } + if `i' > `=`nbitems'*2' & `i'<=. { + local v = `i'-`nbitems'-`nbitems' + } + + if `i'<=`nbitems' { + local rsd`v' "`rsd`v''" "NUR " + } + if `i'>`nbitems' & `i'<=`=`nbitems'*2' { + local rsd`v' "`rsd`v''" "UR " + } + if `i'>`=`nbitems'*2' { + local rsd`v' "`rsd`v''" "REP " + } + } +} + + +di _col(0) "{hline 128}" +di as result _col(0) "Variable" _col(25) "Response shift" _col(48) "Observed change" _col(72) "Response shift contribution" _col(105) "True change contribution" +di as text _col(0) "{hline 128}" + +local i = 1 +foreach v of varlist `varlist' { + if `i' <= `nbitems' { + di as text _col(0) "`v'" _c + di _col(25) %10.2g "`rsd`i''" _c + di _col(48) %10.2g `oc`i'' _c + di _col(72) %10.2g `rs`i'' _c + di _col(105)%10.2g `tc`i'' + } + local ++i +} + +di as result _col(0) "{hline 128}" + + + + + +/* Effect-sizes */ + +di +di as result "Effect-sizes of observed change, response shift, and true change" +di +/* +di as text "Notation:" +di as text "observed change = contribution of response shift + true change" +di as text "contribution of reponse shift = contribution of recalibration + contribution of reprioritization" +*/ + +qui est rest model4 +qui estat framework, fitted + +mat mu = r(mu) + +forvalues i = 1/`P' { + mat muLT`i' = mu[1,`nbitems'*2+`i'*2] +} + +mat gamma = r(Gamma) + +mat gamma1 = gamma[1...,1..1] +mat gamma2 = gamma[1...,2..2] +forvalues i=1(2)`=`P'*2' { + mat g1 = gamma[1...,`i'..`i'] + mat gamma1 = gamma1,g1 + mat g2 = gamma[1...,`i'+1..`i'+1] + mat gamma2 = gamma2,g2 +} +mat gamma1 = gamma1[1...,2...] +mat gamma2 = gamma2[1...,2...] + +mat alpha = r(alpha) + + +mat sigma = r(Sigma) + + + +local v = 1 +local c = 1 +local i = 1 +local j = 1 +local pp = 0 +foreach p in `partition' { + local pp = `pp'+`p' + while `j'<= `pp' { + local tc = 0 + local reprio = 0 + mat mui = mu + + local mu1 = mui[1,`j'] + local mu2 = mui[1,`j'+`p'] + local mu2mu1 = `mu2'-`mu1' + + + /* standard deviations */ + local sd1 = el(sigma,`j',`j') + local sd2 = el(sigma,`j'+`p',`j'+`p') + local covar = el(sigma,`j',`j'+`p') + local sd = sqrt(`sd1'+`sd2'-2*`covar') + + *di "sd = " `sd' + + local mu2mu1 = `mu2mu1'/`sd' + local oc`v' = `mu2mu1' + + + local recalibration = alpha[1,`j'+`p']-alpha[1,`j'] + local recalibration = `recalibration'/`sd' + + mat tc = gamma1[`j',1...]*muLT`i'[1...,1...] + forvalues k = 1/`P' { + local t = el(tc,1,`k') + local tc = `tc'+`t' + } + + + local tc = `tc'/`sd' + local tc`v' = `tc' + *di "tc = " `tc' + + + mat g1 = gamma1[`j',1...] + mat g2 = gamma2[`j'+`p',1...] + mat m = muLT`i'[1...,1...] + + mat reprio = (gamma2[`j'+`p',1...]-gamma1[`j',1...])*muLT`i'[1...,1...] + *mat li reprio + forvalues k = 1/`P' { + local r = el(reprio,1,`k') + local reprio = `reprio'+`r' + } + local reprio = `reprio'/`sd' + + local rs = `recalibration'+`reprio' + local rs`v' = `rs' + + //di as text "Observed change for `var`v'' = " %4.3f `mu2mu1' " = " %4.3f `rs' " + " %4.3f `tc' + if (`rs'!=0) { + //di as text = "Contribution of response shift = " %4.3f `rs' " = " %4.3f `recalibration' " + " %4.3f `reprio' + } + else { + //di as text "(no repsonse shift for `var`v'')" + } + local ++j + local ++v + //di + } + local j = `j'+`p' + local pp = `pp'+`p' + local ++i +} + + +/* Table of effect-sizes */ + +forvalues i=1/`nbitems' { + local rsd`i' +} + +local v = 1 + +forvalues i=1/`=`nbitems'*3' { + if rsitems[`i',1]==1 { + if `i' > `nbitems' & `i'<=`=`nbitems'*2' { + local v = `i'-`nbitems' + } + if `i' > `=`nbitems'*2' & `i'<=. { + local v = `i'-`nbitems'-`nbitems' + } + + if `i'<=`nbitems' { + local rsd`v' "`rsd`v''" "NUR " + } + if `i'>`nbitems' & `i'<=`=`nbitems'*2' { + local rsd`v' "`rsd`v''" "UR " + } + if `i'>`=`nbitems'*2' { + local rsd`v' "`rsd`v''" "REP " + } + } +} + + +di _col(0) "{hline 128}" +di as result _col(0) "Variable" _col(25) "Response shift" _col(48) "Observed change" _col(72) "Response shift contribution" _col(105) "True change contribution" +di as text _col(0) "{hline 128}" + +local i = 1 +foreach v of varlist `varlist' { + if `i' <= `nbitems' { + di as text _col(0) "`v'" _c + di _col(25) %6.3f "`rsd`i''" _c + di _col(48) %6.3f `oc`i'' _c + di _col(72) %6.3f `rs`i'' _c + di _col(105)%6.3f `tc`i'' + } + local ++i +} + +di as result _col(0) "{hline 128}" + +/* radar plots */ + + +tempvar ocs tcs variable +qui gen `ocs' = . +qui gen `tcs' = . +qui gen `variable' = "" +forvalues i = 1/`nbitems' { + qui replace `variable' = "`var`i''" in `i' + qui replace `ocs' = `oc`i'' in `i' + qui replace `tcs' = `tc`i'' in `i' +} + +//list `variable' `ocs' `tcs' in 1/`nbitems' +qui replace `variable' = "a" if `variable'=="" + +qui radar `variable' `ocs' `tcs' in 1/`nbitems', aspect(1) legend(lab(1 "Observed change") lab(2 "True change")) r(-1 -0.8 -0.5 0 0.5 0.8 1) note("") title(Effect-sizes of observed change and true change) + + + + +/* return */ + +matrix effectsizes = J(`nbitems',3,.) +forvalues i = 1/`nbitems'{ + mat effectsizes[`i',1] = `oc`i'' + mat effectsizes[`i',2] = `rs`i'' + mat effectsizes[`i',3] = `tc`i'' + local names `names' `var`i'' +} +mat rownames effectsizes = `names' + +return matrix effectsizes = effectsizes + + + + +//di "modĂšle 2 avec variances Ă  1" +qui `m2' `cl' +//di "modĂšle 4 avec variances Ă  1" +qui `m4' `cl' + +est drop model2 +//est dir + + +restore +end diff --git a/Modules/ado/personal/s/old/simirt11.ado b/Modules/ado/personal/s/old/simirt11.ado new file mode 100644 index 0000000..5109605 --- /dev/null +++ b/Modules/ado/personal/s/old/simirt11.ado @@ -0,0 +1,556 @@ +*! version 1.1 8december2005 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Simirt: Simulation of dichotomous data following an IRT model (Rasch model, +* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM +* +* Version 1 : May 9, 2005 (Jean-Benoit Hardouin) +* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/ +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@orscentre.org +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2005 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ +program define simirt , rclass +version 8.0 +syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW GRoup(real 0) DELtagroup(real 0)] + + +/******************************************************************************** +TESTS +********************************************************************************/ + + +if `group'<0|`group'>1 { + di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}" + error 198 + exit +} + +if "`clear'"==""&"`store'"=="" { + di in red "You must use at least one of these two options: clear and/or store." + error 198 + exit +} + +if "`dim'"!="" { + local nbdim:word count `dim' + if `nbdim'>2 { + di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it." + error 198 + exit + } + if `nbdim'==1 { + local dim1=`dim' + local nbitems=`dim1' + local dim=1 + } + else if `nbdim'==2 { + local dim1:word 1 of `dim' + local dim2:word 2 of `dim' + local nbitems=`dim1'+`dim2' + local dim=2 + } + else { + di in red "Your {hi:dim} option is uncorrect, please correct it. This option must indicate one or two integer(s)." + error 198 + exit + } + if "`diff'"!="" { + local nbdiff:word count `diff' + if (`nbdiff'==3&`dim'==1)|(`nbdiff'==5&`dim'==2)|`nbdiff'==1 { + local typediff:word 1 of `diff' + if "`typediff'"!="gauss"&"`typediff'"!="uniform" { + local typediff values + } + } + if "`typediff'"=="values"&`nbdiff'!=`nbitems' { + di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options." + error 198 + exit + } + } + if "`diff'"=="" { + if `dim'==1 { + local diff gauss 0 1 + } + else if `dim'==2 { + local diff gauss 0 1 0 1 + } + local typediff gauss + local nbdiff:word count `diff' + } +} +else if "`dim'"==""{ + if "`diff'"=="" { + di in red "You must indicate the number of items to simulate with the {hi:dim} or the {hi:diff} option(s)." + error 198 + exit + } + else { + local nbdiff:word count `diff' + if `nbdiff'!=`nbitems' { + di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options." + error 198 + exit + } + } +} +if "`draw'"!=""&`dim'!=1 { + di in red "The {hi:draw} option is available only with unidimensional simulated data." + error 198 + exit +} +if (`group'!=0|`deltagroup'!=0)&`dim'!=1 { + di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data." + error 198 + exit +} + +if "`prefix'"=="" { + local prefix item +} + +local nbprefix:word count `prefix' +local prefix1:word 1 of `prefix' +if `dim'==2&`nbprefix'>=2 { + local prefix2:word 2 of `prefix' +} +else if `dim'==2 { + local prefix2:word 1 of `prefix' +} +if `dim'==2&"`prefix1'"=="`prefix2'" { + local prefix1 `prefix1'A + local prefix2 `prefix2'B +} + +*di in ye "dim : `dim' ; diff : `diff' ; nbdiff : `nbdiff'" + +local nbcov:word count `cov' + +if `dim'==1&`nbcov'>1 { + di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option." + error 198 + exit +} +else if `dim'==2&`nbcov'!=3&`nbcov'>0 { + di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)." + error 198 + exit +} +else if `nbcov'==0 { + if `dim'==1 { + local cov "1" + } + else if `dim'==2 { + local cov "1 1 0" + } + local nbcov:word count `cov' +} + +if `nbcov'==1 { + if `cov'<0 { + di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option." + error 198 + } +} +else if `nbcov'==3 { + local cov1:word 1 of `cov' + local cov2:word 2 of `cov' + local cov3:word 3 of `cov' + local rho=`cov3'/sqrt(`cov1'*`cov2') + if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 { + di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it." + error 198 + exit + } +} + +local nbmu:word count `mu' +if `nbmu'!=`dim'&`nbmu'!=0 { + di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')" + error 198 + exit +} +local nbdisc:word count `disc' +if `nbdisc'!=`nbitems'&`nbdisc'!=0 { + di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmin:word count `pmin' +if `nbpmin'!=`nbitems'&`nbpmin'!=0 { + di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmax:word count `pmax' +if `nbpmax'!=`nbitems'&`nbpmax'!=0 { + di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbacc:word count `acc' +if `nbacc'!=`nbitems'&`nbacc'!=0 { + di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} + +preserve + +tempfile saveraschbin +capture qui save `saveraschbin' + + + + +/******************************************************************************** +PARAMETERS +********************************************************************************/ + + +/* +scalar define hour=real(substr("$S_TIME",1,2)) +scalar define min=real(substr("$S_TIME",4,2)) +scalar define sec=real(substr("$S_TIME",7,2)) +scalar define jour=real(substr("$S_DATE",1,2)) +*/ +local hour=real(substr("$S_TIME",1,2)) +local min=real(substr("$S_TIME",4,2)) +local sec=real(substr("$S_TIME",7,2)) +local jour=real(substr("$S_DATE",1,2)) + + + + +if "$seed"!="" { + global seed2=int($seed) +} +else { + global seed2=0 +} +global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour' +if $seed>2^31-1 { + global seed=int($seed/10) +} +qui set seed $seed + +if "`typediff'"=="uniform" { + if `dim'==1 { + if `nbdiff'==3 { + local min:word 2 of `diff' + local max:word 3 of `diff' + } + else if `nbdiff'==1 { + local min=-2 + local max=2 + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + } + local diff + forvalues i=1/`nbitems' { + local diff `diff' `=`min'+(`max'-`min')*`i'/(`nbitems'+1)' + } + } + if `dim'==2 { + if `nbdiff'==5 { + local min1:word 2 of `diff' + local max1:word 3 of `diff' + local min2:word 4 of `diff' + local max2:word 5 of `diff' + } + else if `nbdiff'==1 { + local min1=-2 + local max1=2 + local min2=-2 + local max2=2 + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + exit + } + local diff + forvalues i=1/`dim1' { + local diff `diff' `=`min1'+(`max1'-`min1')*`i'/(`dim1'+1)' + } + forvalues i=1/`dim2' { + local diff `diff' `=`min2'+(`max2'-`min2')*`i'/(`dim2'+1)' + } + } +} +if "`typediff'"=="gauss" { + if `dim'==1 { + if `nbdiff'==3 { + local mean:word 2 of `diff' + local var:word 3 of `diff' + } + else if `nbdiff'==1 { + local mean=0 + local var=1 + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + error 198 + exit + } + local diff + forvalues i=1/`nbitems' { + local tmp=invnorm(`i'/(`nbitems'+1))*sqrt(`var')+`mean' + local diff `diff' `tmp' + } + } + if `dim'==2 { + if `nbdiff'==5 { + local mean1:word 2 of `diff' + local var1:word 3 of `diff' + local mean2:word 4 of `diff' + local var2:word 5 of `diff' + } + else if `nbdiff'==1 { + local mean1=0 + local var1=1 + local mean2=0 + local var2=1 + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + error 198 + exit + } + local diff + forvalues i=1/`dim1' { + local tmp=invnorm(`i'/(`dim1'+1))*sqrt(`var1')+`mean1' + local diff `diff' `tmp' + } + forvalues i=1/`dim2' { + local tmp=invnorm(`i'/(`dim2'+1))*sqrt(`var2')+`mean2' + local diff `diff' `tmp' + } + } +} + + +tempname matmu matcov matdiff matdisc matpmin matpmax matacc +matrix define `matdiff'=J(`nbitems',1,0) +matrix define `matdisc'=J(`nbitems',1,0) +matrix define `matpmin'=J(`nbitems',1,0) +matrix define `matpmax'=J(`nbitems',1,0) +matrix define `matacc'=J(`nbitems',1,0) +matrix define `matmu'=J(`dim',1,0) +matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0) + +forvalues i=1/`nbitems' { + local tmp:word `i' of `diff' + matrix `matdiff'[`i',1]=`tmp' + if `nbdisc'!=0 { + local tmp:word `i' of `disc' + matrix `matdisc'[`i',1]=`tmp' + } + else { + matrix `matdisc'[`i',1]=1 + } + if `nbpmin'!=0 { + local tmp:word `i' of `pmin' + matrix `matpmin'[`i',1]=`tmp' + } + else { + matrix `matpmin'[`i',1]=0 + } + if `nbpmax'!=0 { + local tmp:word `i' of `pmax' + matrix `matpmax'[`i',1]=`tmp' + } + else { + matrix `matpmax'[`i',1]=1 + } + if `nbacc'!=0 { + local tmp:word `i' of `acc' + matrix `matacc'[`i',1]=`tmp' + } + else { + matrix `matacc'[`i',1]=1 + } +} + +if `nbcov'==3|`nbcov'==1 { + local tmp:word 1 of `cov' + matrix `matcov'[1,1]=`tmp' + if `nbcov'==3&`dim'==2 { + local tmp:word 2 of `cov' + matrix `matcov'[2,1]=`tmp' + local tmp:word 3 of `cov' + matrix `matcov'[3,1]=`tmp' + } +} +else { + matrix `matcov'[1,1]=1 + if `dim'==2 { + matrix `matcov'[2,1]=1 + matrix `matcov'[3,1]=0 + } +} +if (`nbmu'==`dim') { + local tmp:word 1 of `mu' + matrix `matmu'[1,1]=`tmp' + if `dim'==2 { + local tmp:word 2 of `mu' + matrix `matmu'[2,1]=`tmp' + } +} +if `dim'==2 { + local corr=`matcov'[3,1]/sqrt(`matcov'[1,1]*`matcov'[2,1]) +} + +/******************************************************************************** +ITEMS CHARACTERISTIC CURVES +********************************************************************************/ + + +if "`draw'"!="" { + *set trace on + drop _all + qui set obs 2001 + qui gen lt1=_n + qui replace lt1=(lt1-1001)/1000*4*sqrt(`cov')+`matmu'[1,1] + label variable lt1 "Latent trait" + local dess + + forvalues i=1/`dim1' { + qui gen `prefix1'`i'=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(1/(1+exp(-`matdisc'[`i',1]*(lt1-`matdiff'[`i',1]))))^(`matacc'[`i',1]) + local dess `dess' (line `prefix'`i' lt1) + } + graph twoway `dess' , ylabel(0(.25)1) legend(off) ytitle("Probability of a positive response") +} + + +/******************************************************************************** +SIMULATION +********************************************************************************/ + +drop _all +qui set obs `nbobs' +qui gen lt1=invnorm(uniform()) +if `dim'==2 { + qui gen lt2=invnorm(uniform()) + qui replace lt2=`corr'*lt1+sqrt(1-(`corr')^2)*lt2 + qui replace lt2=lt2*sqrt(`matcov'[2,1])+`matmu'[2,1] +} +qui replace lt1=lt1*sqrt(`matcov'[1,1])+`matmu'[1,1] + +if `dim'==1&`group'!=0 { + qui gen group=uniform()<`group' + qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1 + qui replace lt1=lt1-`deltagroup'*`group' if group==0 +} + +di in gr "{hline 75}" +di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc" +di in gr "{hline 75}" +forvalues i=1/`dim1' { + qui gen `prefix1'`i'=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(1/(1+exp(-`matdisc'[`i',1]*(lt1-`matdiff'[`i',1]))))^(`matacc'[`i',1]) + qui replace `prefix1'`i'=uniform()<=`prefix1'`i' + di _col(1) in gr "`prefix1'`i'" _col(20) in ye %8.4f `matdiff'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1] +} +if `dim'==2 { + di in gr "{hline 75}" + forvalues i=`=`dim1'+1'/`=`dim1'+`dim2'' { + qui gen `prefix2'`=`i'-`dim1''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(1/(1+exp(-`matdisc'[`i',1]*(lt2-`matdiff'[`i',1]))))^(`matacc'[`i',1]) + qui replace `prefix2'`=`i'-`dim1''=uniform()<=`prefix2'`=`i'-`dim1'' + di _col(1) in gr "`prefix2'`=`i'-`dim1''" _col(20) in ye %8.4f `matdiff'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1] + } +} +di in gr "{hline 75}" +di + + + +qui corr lt*,cov +local var_1=r(Var_1) +return scalar var_1=r(Var_1) +if `dim'==2 { + local cov_12=r(cov_12) + local var_2=r(Var_2) + return scalar cov_12=r(cov_12) + return scalar var_2=r(Var_2) + qui corr lt* + local rho=r(rho) + return scalar rho=r(rho) +} +qui su lt1 +local mean1=r(mean) +return scalar mean_1=r(mean) +if `dim'==2 { + qui su lt2 + local mean2=r(mean) + return scalar mean_2=r(mean) +} +if `dim'==1&`group'!=0 { + qui su lt1 if group==0 + local mean_0=r(mean) + qui su lt1 if group==1 + local mean_1=r(mean) + local delta=`mean_1'-`mean_0' +} + +return scalar nbobs=`nbobs' + +di in gr "{hline 50}" +di _col(1) in gr "Latent trait" _c +if `dim'==2 { + di in gr "s"_c +} +di in gr _col(29) "Theorical" _col(42) "Observed" +di in gr "{hline 50}" +forvalues i=1/`dim' { + di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean`i'' + di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',1] _col(42) %8.4f `var_`i'' +} +if `dim'==1&`group'!=0 { + di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0' + di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1' + qui count if group==1 + local prop=r(N)/`nbobs' + di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop' +} +if `dim'==2 { + di _col(1) in gr "Covariance" _col(30) in ye %8.4f `matcov'[3,1] _col(42) %8.4f `cov_12' + di _col(1) in gr "Correlation" _col(31) in ye %7.4f `corr' _col(43) %7.4f `rho' +} +di in gr "{hline 50}" + +/******************************************************************************** +CLEAR AND/OR STORE +********************************************************************************/ + + +if "`clear'"!="" { + restore, not + preserve +} +if "`store'"!="" { + save "`store'",`replace' +} +if "`clear'"=="" { + use "`saveraschbin'",replace +} +end diff --git a/Modules/ado/personal/s/old/simirt35.ado b/Modules/ado/personal/s/old/simirt35.ado new file mode 100644 index 0000000..66e1ff4 --- /dev/null +++ b/Modules/ado/personal/s/old/simirt35.ado @@ -0,0 +1,804 @@ +*! version 3.5 May 16, 2013 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model, +* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM) +* +* Version 1 : May 9, 2005 (Jean-Benoit Hardouin) +* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/ +* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/ +* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/ +* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/ +* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/ +* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/ +* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/ +* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/ +* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/ +* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/ +* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/ +* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* +* Copyright 2005-2006, 2008-2009, 2011, 2013 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ +program define simirt , rclass +version 8.0 +syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string)] + + +/******************************************************************************** +TESTS +********************************************************************************/ + + +if `group'<0|`group'>1 { + di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}" + error 198 + exit +} + +if "`clear'"==""&"`store'"=="" { + di in red "You must use at least one of these two options: clear and/or store." + error 198 + exit +} + +if "`dim'"!="" { + local nbdim:word count `dim' + if `nbdim'>2&"`covmatrix'"=="" { + di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it." + error 198 + exit + } + if "`covmatrix'"!="" { + local nbrowcovm=rowsof(`covmatrix') + if `nbdim'!=`nbrowcovm' { + di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that." + error 198 + exit + } + } + local nbitems=0 + forvalues d=1/`nbdim' { + local dim`d':word `d' of `dim' + local nbitems=`nbitems'+`dim`d'' + } + local dim=`nbdim' + + if "`diff'"!="" { + local nbdiff:word count `diff' + local tmp:word 1 of `diff' + if "`tmp'"=="gauss"|"`tmp'"=="uniform" { + local typediff values + } + else if `nbdiff'!=`nbitems' { + di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options." + error 198 + exit + } + } + else if "`diff'"=="" { + local diff gauss + forvalues d=1/`dim' { + local diff `diff' 0 1 + } + local typediff gauss + local nbdiff:word count `diff' + } +} +else if "`dim'"==""{ + if "`diff'"==""&"`pcm'"=="" { + di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)." + error 198 + exit + } + else if "`covmatrix'"!= "" { + local nbrowcovm=rowsof(`covmatrix') + if `nbrowcovm'>1 { + di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option." + error 198 + exit + } + } + else if "`pcm'"!="" { + local nbitems=rowsof(`pcm') + local dim=1 + local dim1=`nbitems' + } + else { + local nbdiff:word count `diff' + local nbitems=`nbdiff' + local dim=1 + local dim1=`nbitems' + } +} + +if (`group'!=0|`deltagroup'!=0)&`dim'!=1 { + di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data." + error 198 + exit +} + +if "`prefix'"=="" { + local prefix item +} + +local nbprefix:word count `prefix' +if `nbprefix'!=`dim'&`nbprefix'!=1 { + di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it." + error 198 + exit +} +if `nbprefix'==`dim' { + forvalues d=1/`dim' { + local prefix`d':word `d' of `prefix' + } +} +else { + forvalues d=1/`dim' { + local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + local prefix`d' `prefix'`tmp' + } +} +*set trace on +if "`covmatrix'"=="" { + local nbcov:word count `cov' + + if `dim'==1&`nbcov'>1 { + di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option." + error 198 + exit + } + else if `dim'==2&`nbcov'!=3&`nbcov'>0 { + di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)." + error 198 + exit + } + else if `nbcov'==0 { + if `dim'==1 { + local cov "1" + } + else if `dim'==2 { + local cov "1 1 0" + } + local nbcov:word count `cov' + } + + if `nbcov'==1 { + if `cov'<0 { + di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option." + error 198 + } + } + else if `nbcov'==3 { + local cov1:word 1 of `cov' + local cov2:word 2 of `cov' + local cov3:word 3 of `cov' + local rho=`cov3'/sqrt(`cov1'*`cov2') + if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 { + di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it." + error 198 + exit + } + } + tempname covmatrix2 + if `dim'==1 { + matrix `covmatrix2'=(`cov') + } + else if `dim'==2 { + matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2') + } + local covmatrix `covmatrix2' + *matrix list `covmatrix2' +} + +local nbmu:word count `mu' +if `nbmu'!=`dim'&`nbmu'!=0 { + di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')" + error 198 + exit +} +local nbdisc:word count `disc' +if `nbdisc'!=`nbitems'&`nbdisc'!=0 { + di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmin:word count `pmin' +if `nbpmin'!=`nbitems'&`nbpmin'!=0 { + di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmax:word count `pmax' +if `nbpmax'!=`nbitems'&`nbpmax'!=0 { + di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbacc:word count `acc' +if `nbacc'!=`nbitems'&`nbacc'!=0 { + di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} + +if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if "`rsm2'"!=""&`dim'==1 { + di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension" + error 198 + exit +} +if "`id'"=="" { + local id="id" +} + +preserve + +tempfile saveraschbin +capture qui save `saveraschbin' + + + + +/******************************************************************************** +PARAMETERS +********************************************************************************/ + + +local hour=real(substr("$S_TIME",1,2)) +local min=real(substr("$S_TIME",4,2)) +local sec=real(substr("$S_TIME",7,2)) +local jour=real(substr("$S_DATE",1,2)) + + + + +if "$seed"!="" { + global seed2=int($seed) +} +else { + global seed2=0 +} +global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour' +while $seed>2^31-1 { + global seed=int($seed/231) +} +qui set seed $seed + +if "`typediff'"=="uniform" { + if `nbdiff'==`=`dim'*2+1' { + local min`d':word `=(`d'-1)*2+2' of `diff' + local max`d':word `=(`d'-1)*2+3' of `diff' + } + else if `nbdiff'==1 { + local min`d'=-2 + local max`d'=2 + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)' + } + } +} +*set trace on +if "`typediff'"=="gauss" { + if `nbdiff'==`=`dim'*2+1' { + forvalues d=1/`dim' { + local mean`d':word `=(`d'-1)*2+2' of `diff' + local var`d':word `=(`d'-1)*2+3' of `diff' + } + } + else if `nbdiff'==1 { + forvalues d=1/`dim' { + local mean`d'=0 + local var`d'=1 + } + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + error 198 + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d'' + local diff `diff' `tmp' + } + } +} +*set trace off + +forvalues d=1/`dim' { + if "`rsm`d''"!="" { + local nbrsm`d':word count `rsm`d'' + forvalues i=2/`=`nbrsm`d''+1' { + local rsm`d'`i':word `=`i'-1' of `rsm`d'' + if "`threshold'"!=""&`rsm`d'`i''<0 { + di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive." + error 198 + exit + } + } + } +} +if "`pcm'"!="" { + local nbmodas=colsof(`pcm') + forvalues j=1/`nbitems' { + local pcmpj`j'k0=-999999999999999 + forvalues k=1/`nbmodas' { + local pcmpj`j'k`k'=`pcm'[`j',`k'] + local tmp=`k'-1 + if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' { + di in red "With the {hi:threshold} option, the difficulties of a given item must increase." + error 198 + exit + } + } + } +} + +tempname matmu matcov matdiff matdisc matpmin matpmax matacc +matrix define `matdiff'=J(`nbitems',1,0) +matrix define `matdisc'=J(`nbitems',1,0) +matrix define `matpmin'=J(`nbitems',1,0) +matrix define `matpmax'=J(`nbitems',1,0) +matrix define `matacc'=J(`nbitems',1,0) +matrix define `matmu'=J(`dim',1,0) +matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0) + +if "`pcm'"=="" { + forvalues i=1/`nbitems' { + local tmp:word `i' of `diff' + matrix `matdiff'[`i',1]=`tmp' + if `nbdisc'!=0 { + local tmp:word `i' of `disc' + matrix `matdisc'[`i',1]=`tmp' + } + else { + matrix `matdisc'[`i',1]=1 + } + if `nbpmin'!=0 { + local tmp:word `i' of `pmin' + matrix `matpmin'[`i',1]=`tmp' + } + else { + matrix `matpmin'[`i',1]=0 + } + if `nbpmax'!=0 { + local tmp:word `i' of `pmax' + matrix `matpmax'[`i',1]=`tmp' + } + else { + matrix `matpmax'[`i',1]=1 + } + if `nbacc'!=0 { + local tmp:word `i' of `acc' + matrix `matacc'[`i',1]=`tmp' + } + else { + matrix `matacc'[`i',1]=1 + } + } +} + +if "`covmatrix'"=="" { + if `nbcov'==3|`nbcov'==1 { + local tmp:word 1 of `cov' + matrix `matcov'[1,1]=`tmp' + if `nbcov'==3&`dim'==2 { + local tmp:word 2 of `cov' + matrix `matcov'[2,1]=`tmp' + local tmp:word 3 of `cov' + matrix `matcov'[3,1]=`tmp' + } + } +} +else if 6==9{ + matrix `matcov'[1,1]=1 + if `dim'==2 { + matrix `matcov'[2,1]=1 + matrix `matcov'[3,1]=0 + } +} +else if "`covmatrix'"!="" { + matrix `matcov'=`covmatrix' +} +if (`nbmu'==`dim') { +* local tmp:word 1 of `mu' +* matrix `matmu'[1,1]=`tmp' + forvalues d=1/`dim' { + local tmp:word `d' of `mu' + matrix `matmu'[`d',1]=`tmp' + } +* if `dim'>1 { +* local tmp:word 2 of `mu' +* matrix `matmu'[2,1]=`tmp' +* } +} +if `dim'==2 { + local corr=`matcov'[3,1]/sqrt(`matcov'[1,1]*`matcov'[2,1]) +} + +/******************************************************************************** +ITEMS CHARACTERISTIC CURVES +********************************************************************************/ + + +if "`draw'"!="" { + *set trace on + drop _all + qui set obs 2001 + qui gen lt1=_n + qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] + label variable lt1 "Latent trait" + local dess + + + if "`rsm1'"==""&"`pcm'"=="" { + if "`title'"=="" { + local title2="Item Characteristics Curves of the items" + } + else { + local title2="`title'" + } + forvalues i=1/`dim1' { + if "`threshold'"=="" { + qui gen `prefix1'`i'=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(1/(1+exp(-`matdisc'[`i',1]*(lt1-`matdiff'[`i',1]))))^(`matacc'[`i',1]) + } + else { + qui gen `prefix1'`i'=lt1>`matdiff'[`i',1] + } + local dess `dess' (line `prefix'`i' lt1) + } + graph twoway `dess' , ylabel(0(.25)1) legend(off) ytitle("Probability of a positive response" title"") title("`title2'") + } + else if "`pcm'"==""{ + forvalues i=1/`dim1' { + if "`title'"=="" { + local title2="Item `i'" + } + else { + local title2="`title'" + } + local dess + local tau0=0 + local tau1=`matdiff'[`i',1] + local D "1+exp(lt`d'-`tau1')" + forvalues k=2/`=`nbrsm1'+1' { + local tau`k'=`tau`=`k'-1''+`matdiff'[`i',1]+`rsm1`k'' + local D "`D'+exp(`k'*lt1-`tau`k'') " + } + forvalues k=`=`nbrsm1'+1'(-1)0 { + tempname prob`k' + qui gen `prob`k''=exp(`k'*lt1-`tau`k'')/(`D') + local dess `dess' (line `prob`k'' lt1) + label variable `prob`k'' "`k'" + } + graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace) + } + } + else if "`pcm'"!=""{ + forvalues j=1/`dim1' { + if "`title'"=="" { + local title2="Item `j'" + } + else { + local title2="`title'" + } + local dess + local tauj`j'k0=0 + forvalues k=1/`nbmodas' { + local tauj`j'k`k'=`tauj`j'k`=`k'-1''+`matdiff'[`j',`k'] + local D "`D'+exp(`k'*lt1-`tauj`j'k`k'') " + } + forvalues k=`=`nbrsm1'+1'(-1)0 { + tempname prob`k' + qui gen `prob`k''=exp(`k'*lt1-`tauj`j'k`k'')/(`D') + local dess `dess' (line `prob`k'' lt1) + label variable `prob`k'' "`k'" + } + graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace) + } + } +} + + +/******************************************************************************** +SIMULATION +********************************************************************************/ + + +drop _all +qui set obs `nbobs' +gen `id'=_n +local names +forvalues d=1/`dim' { + qui gen x`d'=invnorm(uniform()) + qui compress + local names `names' lt`d' +} +/*mkmat lt1-lt`dim' , matrix(lt) +matrix Chol=cholesky(corr(`covmatrix')) +*matrix list lt +*matrix list Chol +matrix lt=lt*Chol' +matrix colnames lt=`names' + +*matrix list lt +drop _all +qui svmat lt*/ + +matrix Chol=cholesky(corr(`covmatrix')) +forvalues d=1/`dim' { + qui gen lt`d'=0 + forvalues i=1/`d' { + qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i' + } + qui compress +} +qui drop x* +forvalues d=1/`dim' { + qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1] + qui compress +} + +if `dim'==1&`group'!=0 { + if "`random'"=="" { + qui gen group=uniform()<`group' + } + else { + qui gen group=`id'<=`group'*`nbobs' + } + qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1 + qui replace lt1=lt1-`deltagroup'*`group' if group==0 + qui compress +} + +di in gr "Number of individuals: " in ye `nbobs' +di + +if "`threshold'"==""&"`rsm1'"=="" { + local line di in gr "{hline 75}" +} +else { + local line di in gr "{hline 27}" +} + +if "`threshold'"==""&"`rsm1'"==""&"`pcm'"=="" { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc" +} +else { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" +} +local dim0=0 + +*set trace on + +local deb1=1 +local fin1=`dim1' + +forvalues d=1/`dim' { /* FOREACH DIMENSION*/ + local deb`d'=`fin`=`d'-1''+1 + local fin`d'=`deb`d''+`dim`d''-1 + `line' + local p=`d'-1 + local q=1 + forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/ + *set trace on + *local q=`i'-`dim`p''*/ + qui compress + if "`pcm'"=="" { + tempname prob`=`nbrsm`d''+2' + qui gen `prob`=`nbrsm`d''+2''=0 + local tau1=`matdiff'[`i',1] + local D "1+exp(lt`d'-`tau1')" + forvalues k=2/`=`nbrsm`d''+1' { + local tau`k'=`tau`=`k'-1''+`matdiff'[`i',1]+`rsm`d'`k'' + *di "tau`k'=`tau`k''" + local D "`D'+exp(`k'*lt`d'-`tau`k'') " + } + } + else { + tempname prob`=`nbmodas'+1' + qui gen `prob`=`nbmodas'+1''=0 + local tau1=`pcm'[`i',1] + local D "1+exp(lt`d'-`tau1')" + forvalues k=2/`nbmodas' { + local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k'] + *di "tau`k'=`tau`k''" + local D "`D'+exp(`k'*lt`d'-`tau`k'') " + } + } + if "`threshold'"==""/*&"`rsm1'"==""*/ { + if "`rsm`d''"==""&"`pcm'"=="" { + tempname prob1 + qui gen `prob1'=`prob`=`nbrsm`d''+2''+`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(1/(1+exp(-`matdisc'[`i',1]*(lt`d'-`matdiff'[`i',1]))))^(`matacc'[`i',1]) + qui compress + } + else if "`rsm`d''"!=""{ + forvalues k=`=`nbrsm`d''+1'(-1)1 { + tempname prob`k' + qui gen `prob`k''=exp(`k'*lt`d'-`tau`k'')/(`D')+`prob`=`k'+1'' + qui compress + } + } + else if "`pcm'"!="" { + forvalues k=`nbmodas'(-1)1 { + tempname prob`k' + qui gen `prob`k''=exp(`k'*lt`d'-`tau`k'')/(`D')+`prob`=`k'+1'' + qui compress + } + } + qui gen `prefix`d''`q'=0 + if "`rsm1'"==""&"`pcm'"=="" { + di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `matdiff'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1] + } + else if "`rsm1'"!="" { + di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `matdiff'[`i',1] + } + else if "`pcm'"!="" { + forvalues k=1/`nbmodas' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + } + } + tempname uni + qui gen `uni'=uniform() + qui compress + if "`pcm'"=="" { + forvalues k=1/`=`nbrsm`d''+1' { + qui replace `prefix`d''`q'=`k' if `uni'<=`prob`k'' + qui drop `prob`k'' + qui compress + } + } + else { + forvalues k=1/`nbmodas' { + qui replace `prefix`d''`q'=`k' if `uni'<=`prob`k'' + qui drop `prob`k'' + qui compress + } + } + } + else { /*if "`threshold'"!=""*/ + if "`pcm'"=="" { + di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `matdiff'[`i',1] + qui gen `prefix`d''`q'=lt`d'>`matdiff'[`i',1] + qui compress + forvalues k=1/`=`nbrsm`d''+1' { + qui replace `prefix`d''`q'=`k' if lt`d'>=`tau`k'' + qui compress + } + } + else { + qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1] + forvalues k=1/`nbmodas' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + qui replace `prefix`d''`q'=`k' if lt`d'>`pcm'[`i',`k'] + qui compress + } + } + } + local q=`q'+1 + } + forvalues k=2/`=`nbrsm`d''+1' { + di _col(1) in gr "tau`k'" _col(20) in ye %8.4f `rsm`d'`k'' + } +} +`line' +di +*set trace on + + +forvalues d=1/`dim' { + qui su lt`d' + local var_`d'=r(Var) + local mean_`d'=r(mean) + forvalues l=`=`d'+1'/`dim' { + qui corr lt`d' lt`l' ,cov + local cov_`d'_`l'=r(cov_12) + return scalar cov_`d'_`l'=`cov_`d'_`l'' + } + return scalar mean_`d'=`mean_`d'' + return scalar var_`d'=`var_`d'' +} +forvalues d=1/`dim' { + forvalues l=`=`d'+1'/`dim' { + local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'') + return scalar corr_`d'_`l'=`corr_`d'_`l'' + } +} + + +if `dim'==1&`group'!=0 { + qui su lt1 if group==0 + local mean_0=r(mean) + qui su lt1 if group==1 + local mean_1=r(mean) + local delta=`mean_1'-`mean_0' +} + +return scalar nbobs=`nbobs' +tempname matcorr +*matrix list `matcov' +matrix `matcorr'=corr(`matcov') + +di in gr "{hline 50}" +di _col(1) in gr "Latent trait" _c +if `dim'==2 { + di in gr "s"_c +} +di in gr _col(30) "Expected" _col(42) "Observed" +di in gr "{hline 50}" +forvalues i=1/`dim' { + di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i'' + di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i'' + forvalues d=`=`i'+1'/`dim' { + di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d'' + di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d'' + } + di in gr "{hline 50}" +} +if `dim'==1&`group'!=0 { + di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0' + di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1' + qui count if group==1 + local prop=r(N)/`nbobs' + di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop' + di in gr "{hline 50}" +} + +/******************************************************************************** +CLEAR AND/OR STORE +********************************************************************************/ +qui compress + +if "`clear'"!="" { + restore, not + preserve +} +if "`store'"!="" { + save "`store'",`replace' +} +if "`clear'"=="" { + use "`saveraschbin'",replace +} +end diff --git a/Modules/ado/personal/s/old/simul2tl2plm.ado b/Modules/ado/personal/s/old/simul2tl2plm.ado new file mode 100644 index 0000000..0393e40 --- /dev/null +++ b/Modules/ado/personal/s/old/simul2tl2plm.ado @@ -0,0 +1,71 @@ +program define simul2tl2plm +version 7.0 +syntax [, nbobs(integer 2000) dim1(real 7) dim2(real 7) corr(real 0) disc1(real 1) disc2(real 1) sigma1(real 1) sigma2(real 1)] + +scalar define hour=real(substr("$S_TIME",1,2)) +scalar define min=real(substr("$S_TIME",4,2)) +scalar define sec=real(substr("$S_TIME",7,2)) +scalar define jour=real(substr("$S_DATE",1,2)) + +if "$seed2"!="" { +global seed2=int($seed/100000)} +else { +global seed2=0 +} +global seed=sec*1000000+min*10000+hour*100+jour+$seed2 + +set seed $seed +quietly { +drop _all +set obs `nbobs' +gen TL1=invnorm(uniform())*`sigma1' +gen TL2=invnorm(uniform())*`sigma2' +replace TL2=`corr'*TL1+sqrt(1-`corr'^2)*TL2 + +local items=1 +global rep1 +while `items'<=`dim1' { +local nitems=100+`items' +gen diff`nitems'=invnorm(`items'/(`dim1'+1)) +gen prob`nitems'=1/(1+exp(-1.7*`disc1'*(TL1-diff`nitems'))) +gen rep`nitems'=0 +replace rep`nitems'=1 if prob`nitems'>=uniform() +global rep1 $rep1 rep`nitems' +local items=`items'+1 +} + +local items=1 +global rep2 +while `items'<=`dim2' { +local nitems=200+`items' +gen diff`nitems'=invnorm(`items'/(`dim2'+1)) +gen prob`nitems'=1/(1+exp(-1.7*`disc2'*(TL2-diff`nitems'))) +gen rep`nitems'=0 +replace rep`nitems'=1 if prob`nitems'>=uniform() +global rep2 $rep2 rep`nitems' +local items=`items'+1 +} +gen ind=_n +keep ind $rep1 $rep2} + + +quietly{ +reshape long rep,i(ind) j(item) + +local items=1 +while `items'<=`dim1' { +local nitems=100+`items' +gen item`nitems'=0 +replace item`nitems'=-1 if item==`nitems' +local items=`items'+1 +} +local items=1 +while `items'<=`dim2' { +local nitems=200+`items' +gen item`nitems'=0 +replace item`nitems'=-1 if item==`nitems' +local items=`items'+1 +} + +}/*fin du quietly*/ +end diff --git a/Modules/ado/personal/s/sascfa.ado b/Modules/ado/personal/s/sascfa.ado new file mode 100644 index 0000000..65e426f --- /dev/null +++ b/Modules/ado/personal/s/sascfa.ado @@ -0,0 +1,10 @@ +program define sascfa,eclass +version 11.0 +syntax anything [if] [in] ,partition(numlist) varname(string) lisrel(string) [batch] +preserve +*%macro CFA (dataset= , listeItems= , partition= , varname= , lisrel=); + +tosas `if' `in' , pgm(%include 'C:\ado\macros SAS\MACRO cfa.sas';%CFA(dataset=stata,listeItems=`anything', partition=`partition', varname=`varname',lisrel=`lisrel');) `batch' + + +end diff --git a/Modules/ado/personal/s/senspescore.ado b/Modules/ado/personal/s/senspescore.ado new file mode 100644 index 0000000..b0b1c62 --- /dev/null +++ b/Modules/ado/personal/s/senspescore.ado @@ -0,0 +1,69 @@ +program define senspescore, rclass +version 8 +syntax varlist(min=1 max=1 numeric) [, Group(varname) Threshold(string) INVerse] + +tempfile senspescorefile +qui save `senspescorefile', replace + +qui sort `group' +tempname p0 p1 n0 n1 q0 +qui count +local nind=r(N) +qui gen `n0'=. +qui gen `n1'=. +qui gen `p0'=. +qui gen `p1'=. + +local l0=0 +local l1=1 + +if "`inverse'"=="" { + local m0="<" + local m1=">" +} +else { + local m0=">" + local m1="<" +} +qui count if `group'==`l0' +local group0=r(N) +qui count if `group'==`l1' +local group1=r(N) + + +forvalues i=1/`nind' { + qui count if `varlist'`m0'`varlist'[`i']&`group'==`l0' + qui replace `n0'=`r(N)' in `i' + qui count if `varlist'`m1'`varlist'[`i']&`group'==`l1' + qui replace `n1'=`r(N)' in `i' + qui replace `p1'=`n`l1''/`group`l1'' in `i' + qui replace `p0'=`n`l0''/`group`l0'' in `i' +} +tempname diff min +if "`threshold'"!="" { + qui gen `diff'=abs(`varlist'-`threshold') + qui sort `diff' + qui gen `min'=1 in 1 +} +sort `varlist' + +label variable `n0' "N bien classées groupe `l0'" +label variable `n1' "N bien classées groupe `l1'" +label variable `p0' "Specificity" +label variable `p1' "Sensibility" +twoway line `n0' `n1' `varlist',name(n,replace) xline(`threshold') +twoway line `p0' `p1' `varlist',name(p,replace) xline(`threshold') +qui gen `q0'=1-`p0' +label variable `q0' "1-Specificity" +local scatter +if "`threshold'"!="" { + local scatter "(scatter `p1' `q0' if `min'==1)" +} +twoway (line `p1' `q0') (line `q0' `q0') `scatter' ,name(roc,replace) legend(off) + + + + +use `senspescorefile', clear +end + diff --git a/Modules/ado/personal/s/sf36fr v1.6.ado b/Modules/ado/personal/s/sf36fr v1.6.ado new file mode 100644 index 0000000..9b94869 --- /dev/null +++ b/Modules/ado/personal/s/sf36fr v1.6.ado @@ -0,0 +1,585 @@ +*! Version 1.6 23August2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : sf36fr +* computes score of the French SF36 questionnnaire +* +* Historic : +* Version 1 (May 2, 2013) [Jean-Benoit Hardouin] +* Release 1 : May 2, 2013 [Jean-benoit Hardouin] +* Release 1.1 : May 14, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/ +* Release 1.2 : May 21, 2013 [Jean-Benoit Hardouin] /*saveimp option*/ +* Release 1.3 : May 24, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/ +* Release 1.4 : December 1, 2018 [Jean-Benoit Hardouin] /*correction of a bug on SF12*/ +* Release 1.5 : July 29, 2019 [Jean-Benoit Hardouin] /*radar option*/ +* Release 1.6 : August 23, 2019 [Jean-Benoit Hardouin] /*correction of a bug to save the scores*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program :http://www.anaqol.org +* +* Copyright 2013, 2018, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** +program define sf36fr , rclass +version 8.2 +syntax varlist(min=36 max=36 numeric) [,v2 save(string) REPlace age(varname) SEXe(varname) saveref(string) DETails saveimp(string) RADar FILESave DIRSave(string)] + +*preserve +local nbitems : word count `varlist' +if `nbitems'!=36 { + di in red "There is `nbitems' items defined instead of 36" +} + +tokenize `varlist' +local varlistsav `varlist' +local sf gh1 ht pf1 pf2 pf3 pf4 pf5 pf6 pf7 pf8 pf9 pf10 rp1 rp2 rp3 rp4 re1 re2 re3 sf1 bp1 bp2 vt1 mh1 mh2 mh3 vt2 mh4 vt3 mh5 vt4 sf2 gh2 gh3 gh4 gh5 +local sf2 +local varlist2 +forvalues i=1/36 { + local j:word `i' of `sf' + tempname `j' + *di " qui gen `j'=``i''" + qui gen ``j''=``i'' + local varlist2 "`varlist2' ``j''" +} +local varlist "`varlist2'" +tokenize `varlist' +*di "`varlist'" + + +if "`v2'"=="" { + local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 5 6 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5 +} +else { + local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 +} +forvalues i=1/36 { + local mod`i':word `i' of `modamax' +} +local error=0 +local inf +local sup +local c=1 +foreach i of varlist `varlist' { + qui count if `i'<1 + if `r(N)'>0 { + local error=1 + local inf "`inf' `i'" + } + local tmp: word `c' of `modamax' + qui count if `i'>`c' + if `r(N)'>0 { + local error=1 + local inf "`sup' `i'" + } + local ++c +} +forvalues i=1/15 { + tempname inc`i' +} +local liste1 11 12 11 12 11 12 11 12 30 24 27 23 1 20 21 +local liste2 3 3 4 4 6 6 9 9 25 26 29 31 36 32 22 +*tab `11' `3' +qui gen `inc1'=`11'==1&`3'>1 if `11'!=.&`3'!=. +* tab `inc`i'' +qui gen `inc2'=`12'==1&`3'>1 if `12'!=.&`3'!=. +qui gen `inc3'=`11'==1&`4'>1 if `11'!=.&`4'!=. +qui gen `inc4'=`12'==1&`4'>1 if `12'!=.&`4'!=. +qui gen `inc5'=`11'==1&`6'>1 if `11'!=.&`6'!=. +qui gen `inc6'=`12'==1&`6'>1 if `12'!=.&`6'!=. +qui gen `inc7'=`11'==1&`9'>1 if `11'!=.&`9'!=. +qui gen `inc8'=`12'==1&`9'>1 if `12'!=.&`9'!=. +qui gen `inc9'=(`30'==1&`25'==1)|(`30'==`mod30'&`25'==`mod25') if `30'!=.&`25'!=. +qui gen `inc10'=(`24'==1&`26'==1)|(`24'==`mod24'&`26'==`mod26') if `24'!=.&`26'!=. +qui gen `inc11'=(`27'==1&`29'==1)|(`27'==`mod27'&`29'==`mod29') if `27'!=.&`29'!=. +qui gen `inc12'=(`23'==1&`31'==1)|(`23'==`mod23'&`31'==`mod31') if `23'!=.&`31'!=. +qui gen `inc13'=(`1'==1&`36'==`mod36')|(`1'==`mod1'&`36'==1) if `1'!=.&`36'!=. +qui gen `inc14'=(`20'==1&`32'==1)|(`20'==`mod20'&`32'==`mod32') if `20'!=.&`32'!=. +qui gen `inc15'=(`21'==1&`22'==`mod22')|(`21'==`mod21'&`22'==1) if `21'!=.&`22'!=. +tempname scoreinc +genscore `inc1'-`inc15',score(`scoreinc') +if "`details'" !="" { + di "{hline 80}" + di in gr "Discrepancies" _col(20) "item 1" _col(40) "item 2" _col(60) "# individuals" + di "{hline 80}" + *di "varlist:`varlistsav'" + forvalues i=1/15 { + local i1:word `i' of `liste1' + local i2:word `i' of `liste2' + local ni1:word `i1' of `varlistsav' + local ni2:word `i2' of `varlistsav' + qui count if `inc`i''==1 + + di in gr "`i'" in ye _col(20) abbrev("`ni1'",19) _col(40) abbrev("`ni2'",19) %6.0f _col(67) `r(N)' + } + di "{hline 80}" +} + +forvalues i=1/15 { + local i1:word `i' of `liste1' + local i2:word `i' of `liste2' + qui replace ``i1''=. if `inc`i''==1 + qui replace ``i2''=. if `inc`i''==1 +} + +tempname imp scorepf scorerp scorebp scoregh scorevt scoresf scorere scoremh + + /*PF*/ + imputeitems `3' `4' `5' `6' `7' `8' `9' `10' `11' `12',max(4) noround prefix(`imp') + genscore `imp'`3' `imp'`4' `imp'`5' `imp'`6' `imp'`7' `imp'`8' `imp'`9' `imp'`10' `imp'`11' `imp'`12',score(`scorepf') + qui replace `scorepf'=(`scorepf'-10)/20*100 + /*RP*/ + imputeitems `13' `14' `15' `16',max(1) noround prefix(`imp') + genscore `imp'`13' `imp'`14' `imp'`15' `imp'`16',score(`scorerp') + qui replace `scorerp'=(`scorerp'-4)/4*100 + /*BP*/ + tempvar jb + qui gen `jb'=. + qui replace `jb'=6 if `21'==1&`22'==1 + qui replace `jb'=5 if `21'>=2&`21'<=6&`22'==1 + qui replace `jb'=4 if `22'==2&`21'!=. + qui replace `jb'=3 if `22'==3&`21'!=. + qui replace `jb'=2 if `22'==4&`21'!=. + qui replace `jb'=1 if `22'==5&`21'!=. + qui replace `jb'=6 if `22'==1&`21'==. + qui replace `jb'=4.75 if `22'==2&`21'==. + qui replace `jb'=3.5 if `22'==3&`21'==. + qui replace `jb'=2.25 if `22'==4&`21'==. + qui replace `jb'=1 if `22'==5&`21'==. + qui replace `22'=`jb' + if "`v2'"=="" { + qui recode `21' 1=6 2=5.4 3=4.2 4=3.1 5=2.2 6=1 + } + else { + qui recode `21' 1=6 2=4.8 3=2.65 4=1 + } + imputeitems `21' `22',max(0) noround prefix(`imp') +* replace `imp'`21'=`21' +* replace `imp'`22'=`22' + qui genscore `imp'`21' `imp'`22',score(`scorebp') +* list sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques `21' `22' `imp'`21' `imp'`22' `scorebp' + qui replace `scorebp'=(`scorebp'-2)/10*100 +*tab `scorebp' + /*GH*/ + qui recode `1' 1=5 2=4.4 3=3.4 4=2 5=1 + qui recode `34' 1=5 2=4 3=3 4=2 5=1 + qui recode `36' 1=5 2=4 3=3 4=2 5=1 + imputeitems `1' `33' `34' `35' `36',max(2) noround prefix(`imp') + genscore `imp'`1' `imp'`33' `imp'`34' `imp'`35' `imp'`36',score(`scoregh') + qui replace `scoregh'=(`scoregh'-5)/20*100 + /*VT*/ + if "`v2'"=="" { + qui recode `23' 1=6 2=5 3=4 4=3 5=2 6=1 + qui recode `27' 1=6 2=5 3=4 4=3 5=2 6=1 + } + else { + qui recode `23' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `27' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `29' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `31' 1=1 2=2 3=3.5 4=4.5 5=6 + } + imputeitems `23' `27' `29' `31',max(1) noround prefix(`imp') + genscore `imp'`23' `imp'`27' `imp'`29' `imp'`31',score(`scorevt') + qui replace `scorevt'=(`scorevt'-4)/20*100 + /*SF*/ + if "`v2'"=="" { + qui recode `20' 1=5 2=4 3=3 4=2 5=1 + } + else { + qui recode `20' 1=5 2=4 3=2.5 4=1 + } + imputeitems `20' `32',max(0) noround prefix(`imp') + genscore `imp'`20' `imp'`32',score(`scoresf') + qui replace `scoresf'=(`scoresf'-2)/8*100 + /*RE*/ + imputeitems `17' `18' `19',max(1) noround prefix(`imp') + genscore `imp'`17' `imp'`18' `imp'`19',score(`scorere') + qui replace `scorere'=(`scorere'-3)/3*100 + /*MH*/ + if "`v2'"=="" { + qui recode `26' 1=6 2=5 3=4 4=3 5=2 6=1 + qui recode `30' 1=6 2=5 3=4 4=3 5=2 6=1 + } + else { + qui recode `26' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `30' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `24' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `25' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `28' 1=1 2=2 3=3.5 4=4.5 5=6 + } + imputeitems `24' `25' `26' `28' `30',max(2) noround prefix(`imp') + genscore `imp'`24' `imp'`25' `imp'`26' `imp'`28' `imp'`30',score(`scoremh') + qui replace `scoremh'=(`scoremh'-5)/25*100 + tempname scorepfz scorerpz scorebpz scoreghz scorevtz scoresfz scorerez scoremhz scorepcs scoremcs + + /*scores composites*/ + qui gen `scorepfz'=(`scorepf'-84.52404)/22.89490 + qui gen `scorerpz'=(`scorerp'-81.19907)/33.79729 + qui gen `scorebpz'=(`scorebp'-75.49196)/23.55879 + qui gen `scoreghz'=(`scoregh'-72.21316)/20.16964 + qui gen `scorevtz'=(`scorevt'-61.05453)/20.86942 + qui gen `scoresfz'=(`scoresf'-83.59753)/22.37649 + qui gen `scorerez'=(`scorere'-81.29467)/33.02717 + qui gen `scoremhz'=(`scoremh'-74.84212)/18.01189 + qui gen `scorepcs'=(`scorepfz'*0.42402+`scorerpz'*0.35119+`scorebpz'*0.31754+`scoreghz'*0.24954+`scorevtz'*0.02877-`scoresfz'*0.0753-`scorerez'*0.19206-`scoremhz'*0.22069)*10+50 + qui gen `scoremcs'=(-`scorepfz'*0.22999-`scorerpz'*0.12329-`scorebpz'*0.09731-`scoreghz'*0.01571+`scorevtz'*0.23534+`scoresfz'*0.26876+`scorerez'*0.43407+`scoremhz'*0.48581)*10+50 + + +/*scores composites SF12*/ +tempname scoresf12p sf12p_1 sf12p_2a sf12p_2b sf12p_3a sf12p_3b sf12p_4a sf12p_4b sf12p_5 sf12p_6 sf12p_7a sf12p_7b sf12p_7c +tempname scoresf12m sf12m_1 sf12m_2a sf12m_2b sf12m_3a sf12m_3b sf12m_4a sf12m_4b sf12m_5 sf12m_6 sf12m_7a sf12m_7b sf12m_7c + qui gen `sf12p_1'=`1' + qui gen `sf12p_2a'=`4' + qui gen `sf12p_2b'=`6' + qui gen `sf12p_3a'=`14' + qui gen `sf12p_3b'=`15' + qui gen `sf12p_4a'=`18' + qui gen `sf12p_4b'=`19' + qui gen `sf12p_5'=`20' + qui gen `sf12p_6'=`32' + qui gen `sf12p_7a'=`26' + qui gen `sf12p_7b'=`27' + qui gen `sf12p_7c'=`28' + qui gen `sf12m_1'=`1' + qui gen `sf12m_2a'=`4' + qui gen `sf12m_2b'=`6' + qui gen `sf12m_3a'=`14' + qui gen `sf12m_3b'=`15' + qui gen `sf12m_4a'=`18' + qui gen `sf12m_4b'=`19' + qui gen `sf12m_5'=`20' + qui gen `sf12m_6'=`32' + qui gen `sf12m_7a'=`26' + qui gen `sf12m_7b'=`27' + qui gen `sf12m_7c'=`28' + qui recode `sf12p_1' 5=0 4.4=-1.31872 3.4=-3.02396 2=-5.56461 1=-8.37399 + qui recode `sf12m_1' 5=0 4.4=-0.06064 3.4=0.03482 2=-0.16891 1=-1.71175 + qui recode `sf12p_2a' 1=-7.23216 2=-3.45555 3=0 + qui recode `sf12m_2a' 1=3.93115 2=1.86840 3=0 + qui recode `sf12p_2b' 1=-6.24397 2=-2.73557 3=0 + qui recode `sf12m_2b' 1=2.68282 2=1.43103 3=0 + qui recode `sf12p_3a' 1=-4.61617 2=0 + qui recode `sf12m_3a' 1=1.44060 2=0 + qui recode `sf12p_3b' 1=-5.51747 2=0 + qui recode `sf12m_3b' 1=1.66968 2=0 + qui recode `sf12p_4a' 1=3.04365 2=0 + qui recode `sf12m_4a' 1=-6.82672 2=0 + qui recode `sf12p_4b' 1=2.32091 2=0 + qui recode `sf12m_4b' 1=-5.69921 2=0 + qui recode `sf12p_6' 1=-0.33682 2=-0.94342 3=-0.18043 4=0.11038 5=0 + qui recode `sf12m_6' 1=-6.29724 2=-8.26066 3=-5.63286 4=-3.13896 5=0 + if "`v2'"=="" { + qui recode `sf12p_5' 5=0 4=-3.80130 3=-6.50522 2=-8.38063 1=-11.25544 + qui recode `sf12m_5' 5=0 4=0.90384 3=1.49384 2=1.76691 1=1.48619 + qui recode `sf12p_7a' 6=0 5=0.66514 4=1.36689 3=2.37241 2=2.90426 1=3.46638 + qui recode `sf12m_7a' 6=0 5=-1.94949 4=-4.09842 3=-6.31121 2=-7.92717 1=-10.19085 + qui recode `sf12p_7b' 6=0 5=-0.42251 4=-1.14387 3=-1.61850 2=-2.02168 1=-2.44706 + qui recode `sf12m_7b' 6=0 5=-0.92057 4=-1.65178 3=-3.29805 2=-4.88962 1=-6.02409 + qui recode `sf12p_7c' 1=4.61446 2=3.41593 3=2.34247 4=1.28044 5=0.41188 6=0 + qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3=-8.09914 4=-4.59055 5=-1.95934 6=0 + } + else { + qui recode `sf12p_5' 5=0 4=-3.83130 2.5=-7.442925 1=-11.25544 + qui recode `sf12m_5' 5=0 4=0.90384 2.5=1.630375 1=1.48619 + qui recode `sf12p_7a' 6=0 4.5=1.016015 3.5=1.86965 2=2.90426 1=3.46638 + qui recode `sf12m_7a' 6=0 4.5=-3.023955 3.5=-5.204815 2=-7.92717 1=-10.19085 + qui recode `sf12p_7b' 6=0 4.5=-0.78319 3.5=-1.381185 2=-2.02168 1=-2.44706 + qui recode `sf12m_7b' 6=0 4.5=-1.286175 3.5=-2.474915 2=-4.88962 1=-6.02409 + qui recode `sf12p_7c' 1=4.61446 2=3.41593 3.5=1.811455 4.5=0.84616 6=0 + qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3.5=-6.344845 4.5=-3.274945 6=0 + } + qui gen `scoresf12p'=`sf12p_1'+`sf12p_2a'+`sf12p_2b'+`sf12p_3a'+`sf12p_3b'+`sf12p_4a'+`sf12p_4b'+`sf12p_5'+`sf12p_6'+`sf12p_7a'+`sf12p_7b'+`sf12p_7c'+56.57706 + qui gen `scoresf12m'=`sf12m_1'+`sf12m_2a'+`sf12m_2b'+`sf12m_3a'+`sf12m_3b'+`sf12m_4a'+`sf12m_4b'+`sf12m_5'+`sf12m_6'+`sf12m_7a'+`sf12m_7b'+`sf12m_7c'+60.75781 + +if "`save'"!="" { + local listmin pf rp bp gh vt sf re mh pcs mcs + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local error=0 + local list + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `save'`i' + if _rc==0&"`replace'"=="" { + local ++error + local list "`list' `save'`j'" + } + local ++c + } + local c=1 + if `error'==0 { + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `save'`i' + if _rc==0 { + qui replace `save'`i'=`score`i'' + } + else { + qui gen `save'`i'=`score`i'' + } + local ++c + } + } + else { + di in red "The variable(s) `list' already exist(s)" + } +} +tempname scoreref1 scoreref0 scoreref01 scoreref scorerefv1 scorerefv0 scorerefv01 scorerefv +matrix `scoreref1'=(96.65,95.80,86.82,82.36,67.86,89.76,93.14,72.85\95.75,91.16,83.60,76.07,64.50,86.50,90.64,72.08\94.41,90.76,81.03,73.13,64.32,86.37,89.07,71.01\92.27,88.64,79.02,72.27,66.06,86.69,90.00,71.53\82.32,79.81,70.21,65.97,60.19,83.33,83.00,71.10\76.58,74.74,67.10,62.37,58.21,79.74,80.04,71.16\67.16,61.28,63.99,58.61,53.93,76.16,66.67,70.24) +matrix `scoreref0'=(94.92,89.54,79.37,71.81,60.32,79.65,81.65,64.92\92.42,85.98,80.19,75.10,60.57,82.83,86.13,68.18\91.04,88.87,78.27,74.64,61.94,84.14,85.48,67.59\86.23,85.54,71.97,69.14,58.90,79.80,83.42,64.84\77.88,77.85,66.23,65.10,58.18,78.29,77.61,66.17\71.60,68.74,62.40,61.23,55.08,76.47,73.24,65.45\58.20,52.46,59.68,59.73,47.94,71.68,62.21,60.63) +matrix `scoreref01'=(95.65,92.18,82.51,76.26,63.52,83.93,86.47,68.29\93.93,88.34,81.75,75.54,62.35,84.51,88.19,69.94\92.71,89.80,79.63,73.89,63.12,85.24,87.26,69.28\89.25,87.09,75.50,70.70,62.48,83.24,86.71,68.19\79.99,78.78,68.12,65.51,59.14,80.69,80.19,68.52\73.69,71.24,64.37,61.71,56.39,77.84,76.05,67.84\62.40,56.67,61.72,59.20,50.86,73.80,64.38,65.29) +matrix `scoreref'=(84.45,81.21,73.39,69.13,59.96,81.55,82.13,68.47\87.07,83.86,75.98,70.07,62.23,84.08,85.41,71.42\82.22,78.96,71.18,68.33,58.03,79.41,79.34,65.96) +matrix `scorerefv1'=(11.78,15.33,17.21,13.93,14.16,14.43,20.73,15.28\9.64,21.30,19.63,15.89,16.72,19.05,24.18,15.83\11.08,23.63,21.00,16.20,16.65,18.97,26.12,16.70\14.92,26.35,22.09,17.41,16.24,17.01,23.15,16.23\20.48,32.67,22.24,17.93,16.89,20.35,32.04,17.40\22.78,36.05,24.06,19.08,18.03,21.94,33.89,16.60\27.44,40.86,24.38,17.61,18.86,24.08,41.43,20.03) +matrix `scorerefv0'=(9.10,21.65,21.66,17.69,18.10,22.35,29.58,17.32\14.19,28.28,21.28,16.66,18.28,20.57,28.19,18.06\14.81,25.19,21.25,17.64,18.55,20.97,29.37,17.92\19.11,29.40,23.90,18.60,17.84,21.44,31.24,16.66\21.49,33.02,24.10,18.78,18.22,23.46,34.89,18.03\23.42,38.17,23.94,17.67,17.59,22.46,37.41,18.21\25.70,39.18,23.40,18.08,17.98,24.06,39.97,18.98) +matrix `scorerefv01'=(10.33,19.46,20.21,17.00,16.94,20.00,26.80,16.83\12.44,25.45,20.60,16.31,17.69,19.96,16.51,17.18\13.19,24.43,21.15,16.95,17.66,20.02,27.85,17.40\17.39,27.92,23.25,18.06,17.41,19.64,27.65,16.76\21.11,32.83,23.29,18.37,17.61,22.16,33.63,17.88\23.27,37.40,24.09,18.28,17.83,22.29,36.13,17.77\26.85,40.16,23.92,17.83,18.62,24.13,40.67,20.04) +matrix `scorerefv'=(21.19,32.20,23.73,18.57,18.05,21.41,32.15,17.62\19.85,30.48,23.03,18.39,17.36,20.08,29.89,16.70\22.02,33.43,24.10,18.69,18.40,22.26,33.71,17.99) + +tempname scorerefpf scorerefrp scorerefbp scorerefgh scorerefvt scorerefsf scorerefre scorerefmh +tempname scorerefpfv scorerefrpv scorerefbpv scorerefghv scorerefvtv scorerefsfv scorerefrev scorerefmhv +if "`age'"!=""&"`sexe'"!="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref0'[1,`c'] if `sexe'==0&`age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref0'[2,`c'] if `sexe'==0&`age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref0'[3,`c'] if `sexe'==0&`age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref0'[4,`c'] if `sexe'==0&`age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref0'[5,`c'] if `sexe'==0&`age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref0'[6,`c'] if `sexe'==0&`age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref0'[7,`c'] if `sexe'==0&`age'>=75 + qui replace `scoreref`i''=`scoreref1'[1,`c'] if `sexe'==1&`age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref1'[2,`c'] if `sexe'==1&`age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref1'[3,`c'] if `sexe'==1&`age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref1'[4,`c'] if `sexe'==1&`age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref1'[5,`c'] if `sexe'==1&`age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref1'[6,`c'] if `sexe'==1&`age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref1'[7,`c'] if `sexe'==1&`age'>=75 + qui gen `scoreref`i'v'=(`scorerefv0'[1,`c'])^2 if `sexe'==0&`age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv0'[2,`c'])^2 if `sexe'==0&`age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv0'[3,`c'])^2 if `sexe'==0&`age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv0'[4,`c'])^2 if `sexe'==0&`age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv0'[5,`c'])^2 if `sexe'==0&`age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv0'[6,`c'])^2 if `sexe'==0&`age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv0'[7,`c'])^2 if `sexe'==0&`age'>=75 + qui replace `scoreref`i'v'=(`scorerefv1'[1,`c'])^2 if `sexe'==1&`age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv1'[2,`c'])^2 if `sexe'==1&`age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv1'[3,`c'])^2 if `sexe'==1&`age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv1'[4,`c'])^2 if `sexe'==1&`age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv1'[5,`c'])^2 if `sexe'==1&`age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv1'[6,`c'])^2 if `sexe'==1&`age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv1'[7,`c'])^2 if `sexe'==1&`age'>=75 + local ++c + } +} +else if "`age'"!=""&"`sexe'"=="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref01'[1,`c'] if `age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref01'[2,`c'] if `age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref01'[3,`c'] if `age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref01'[4,`c'] if `age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref01'[5,`c'] if `age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref01'[6,`c'] if `age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref01'[7,`c'] if `age'>=75 + qui gen `scoreref`i'v'=(`scorerefv01'[1,`c'])^2 if `age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv01'[2,`c'])^2 if `age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv01'[3,`c'])^2 if `age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv01'[4,`c'])^2 if `age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv01'[5,`c'])^2 if `age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv01'[6,`c'])^2 if `age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv01'[7,`c'])^2 if `age'>=75 + local ++c + } +} +else if "`age'"==""&"`sexe'"!="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref'[2,`c'] if `sexe'==1 + qui replace `scoreref`i''=`scoreref'[3,`c'] if `sexe'==0 + qui gen `scoreref`i'v'=(`scorerefv'[2,`c'])^2 if `sexe'==1 + qui replace `scoreref`i'v'=(`scorerefv'[3,`c'])^2 if `sexe'==0 + local ++c + } +} +else if "`age'"==""&"`sexe'"=="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + gen `scoreref`i''=`scoreref'[1,`c'] + gen `scoreref`i'v'=(`scorerefv'[1,`c'])^2 + local ++c + } +} +tempname scorerefpfz scorerefrpz scorerefbpz scorerefghz scorerefvtz scorerefsfz scorerefrez scorerefmhz scorerefpcs scorerefmcs +tempname scorerefpfvz scorerefrpvz scorerefbpvz scorerefghvz scorerefvtvz scorerefsfvz scorerefrevz scorerefmhvz scorerefpcsv scorerefmcsv + +qui gen `scorerefpfz'=(`scorerefpf'-84.52404)/22.89490 +qui gen `scorerefrpz'=(`scorerefrp'-81.19907)/33.79729 +qui gen `scorerefbpz'=(`scorerefbp'-75.49196)/23.55879 +qui gen `scorerefghz'=(`scorerefgh'-72.21316)/20.16964 +qui gen `scorerefvtz'=(`scorerefvt'-61.05453)/20.86942 +qui gen `scorerefsfz'=(`scorerefsf'-83.59753)/22.37649 +qui gen `scorerefrez'=(`scorerefre'-81.29467)/33.02717 +qui gen `scorerefmhz'=(`scorerefmh'-74.84212)/18.01189 +qui gen `scorerefpcs'=(`scorerefpfz'*0.42402+`scorerefrpz'*0.35119+`scorerefbpz'*0.31754+`scorerefghz'*0.24954+`scorerefvtz'*0.02877-`scorerefsfz'*0.0753-`scorerefrez'*0.19206-`scorerefmhz'*0.22069)*10+50 +qui gen `scorerefmcs'=(-`scorerefpfz'*0.22999-`scorerefrpz'*0.12329-`scorerefbpz'*0.09731-`scorerefghz'*0.01571+`scorerefvtz'*0.23534+`scorerefsfz'*0.26876+`scorerefrez'*0.43407+`scorerefmhz'*0.48581)*10+50 + +qui gen `scorerefpfvz'=(`scorerefpfv')/22.89490^2 +qui gen `scorerefrpvz'=(`scorerefrpv')/33.79729^2 +qui gen `scorerefbpvz'=(`scorerefbpv')/23.55879^2 +qui gen `scorerefghvz'=(`scorerefghv')/20.16964^2 +qui gen `scorerefvtvz'=(`scorerefvtv')/20.86942^2 +qui gen `scorerefsfvz'=(`scorerefsfv')/22.37649^2 +qui gen `scorerefrevz'=(`scorerefrev')/33.02717^2 +qui gen `scorerefmhvz'=(`scorerefmhv')/18.01189^2 +qui gen `scorerefpcsv'=(`scorerefpfvz'*0.42402^2+`scorerefrpvz'*0.35119^2+`scorerefbpvz'*0.31754^2+`scorerefghvz'*0.24954^2+`scorerefvtvz'*0.02877^2-`scorerefsfvz'*0.0753^2-`scorerefrevz'*0.19206^2-`scorerefmhvz'*0.22069^2)*10^2 +qui gen `scorerefmcsv'=(-`scorerefpfvz'*0.22999^2-`scorerefrpvz'*0.12329^2-`scorerefbpvz'*0.09731^2-`scorerefghvz'*0.01571^2+`scorerefvtvz'*0.23534^2+`scorerefsfvz'*0.26876^2+`scorerefrevz'*0.43407^2+`scorerefmhvz'*0.48581^2)*10^2 + + + + + +if "`saveref'"!="" { + local listmin pf rp bp gh vt sf re mh pcs mcs + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local error=0 + local list + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `saveref'`i' + if _rc==0&"`replace'"=="" { + local ++error + local list "`list' `saveref'`j'" + } + local ++c + } + local c=1 + if `error'==0 { + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `saveref'`i' + if _rc==0 { + qui replace `saveref'`i'=`scoreref`i'' + } + else { + qui gen `saveref'`i'=`scoreref`i'' + } + local ++c + } + } + else { + di in red "The variable(s) `list' already exist(s)" + } +} + +if "`details'"!=""|"`radar'"!="" { + tempname radar + qui matrix `radar'=J(12,2,.) + if "`details'"!="" { + di "{hline 80}" + di in gr _col(12) "Sample" _col(51) "Reference" + di in gr "Dimension" _col(16) "N" _col(21) "Mean" _col(29) "s.d." _col(40) "Min-Max" _col(52) "Mean" _col(60) "s.d." _col(72) "p" + di "{hline 80}" + } + local listmin pf rp bp gh vt sf re mh pcs mcs sf12p sf12m + local listmaj PF RP BP GH VT SF RE MH PCS MCS SF12P SF12M + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + qui su `score`i'' + local means`i'=r(mean) + local sds`i'=r(sd) + local mins`i'=r(min) + local maxs`i'=r(max) + local n`i'=r(N) + matrix `radar'[`c',1]=`means`i'' + qui su `scoreref`i'' + matrix `radar'[`c',2]=r(mean) + if "`i'"!="sf12p"&"`i'"!="sf12m" { + qui su `scoreref`i'' if `score`i''!=. + local meanr`i'=r(mean) + local sdr`i'=r(sd) + local vr`i'=(`sdr`i'')^2 + qui su `scoreref`i'v' if `score`i''!=. + local meanvr`i'=r(mean) + local sdr`i'=sqrt(`vr`i''+`meanvr`i'') + *local minr`i'=r(min) + *local maxr`i'=r(max) + qui ttest `score`i''=`meanr`i'' + local p`i'=r(p) + } + if "`details'"!="" { + di in gr "`j'" in ye _col(12) %5.0f `n`i'' _col(20) %5.2f `means`i'' _col(28) %5.2f `sds`i'' _col(34) %6.2f `mins`i'' "-" %6.2f `maxs`i'' _col(51) %5.2f `meanr`i'' _col(59) %5.2f `sdr`i'' _col(67) %6.4f `p`i'' + } + local ++c + } + if "`details'"!="" { + di "{hline 80}" + } + *corr `scorepcs' `scoremcs' `scoresf12p' `scoresf12m' + *scatter `scorepcs' `scoresf12p' ,name(p) + *scatter `scoremcs' `scoresf12m' ,name(m) + *su `scoresf12p' `sf12p_1' `sf12p_2a' `sf12p_2b' `sf12p_3a' `sf12p_3b' `sf12p_4a' `sf12p_4b' `sf12p_5' `sf12p_6' `sf12p_7a' `sf12p_7b' `sf12p_7c' + *su `scoresf12m' `sf12m_1' `sf12m_2a' `sf12m_2b' `sf12m_3a' `sf12m_3b' `sf12m_4a' `sf12m_4b' `sf12m_5' `sf12m_6' `sf12m_7a' `sf12m_7b' `sf12m_7c' + if "`radar'"!=""&"`v2'"=="" { + qui tempfile radarfile + qui save `radarfile', replace + qui drop _all + qui svmat `radar' + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local c=1 + qui gen name="" + foreach i in `listmin' { + qui replace name="`i'" in `c' + local ++c + } + qui rename `radar'1 scoreSF36 + rename `radar'2 scoreSF36ref + qui keep in 1/10 + label variable scoreSF36 "Sample" + label variable scoreSF36ref "General French population" + if "`filesave'"!="" { + if "`dirsave'"=="" { + local dirsave `c(pwd)' + } + local saving "saving(`dirsave'//radar, replace) " + } + qui radar name scoreSF36 scoreSF36ref, note("") title("Comparison of the sample with the general French population") legend(lab(1 "Sample") lab(2 "General French population")) `saving' + qui use `radarfile', clear + } +} +if "`saveimp'"!="" { +*su + foreach i of numlist 1 3/36 { + local j:word `i' of `varlistsav' + *di "gen `saveimp'`j'=`imp'``i''" + capture confirm variable `saveimp'`j' + if _rc==0&"`replace'"=="" { + di in ye "The variable `saveimp'`j' already exists and cannot be replaced." + } + else if _rc==0&"`replace'"!="" { + qui replace `saveimp'`j'=`imp'``i'' + } + else { + qui gen `saveimp'`j'=`imp'``i'' + } + } +} +*restore, preserve +end diff --git a/Modules/ado/personal/s/sf36fr v1.7.ado b/Modules/ado/personal/s/sf36fr v1.7.ado new file mode 100644 index 0000000..8e8e665 --- /dev/null +++ b/Modules/ado/personal/s/sf36fr v1.7.ado @@ -0,0 +1,588 @@ +*! Version 1.7 29August2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : sf36fr +* computes score of the French SF36 questionnnaire +* +* Historic : +* Version 1 (May 2, 2013) [Jean-Benoit Hardouin] +* Release 1 : May 2, 2013 [Jean-benoit Hardouin] +* Release 1.1 : May 14, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/ +* Release 1.2 : May 21, 2013 [Jean-Benoit Hardouin] /*saveimp option*/ +* Release 1.3 : May 24, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/ +* Release 1.4 : December 1, 2018 [Jean-Benoit Hardouin] /*correction of a bug on SF12*/ +* Release 1.5 : July 29, 2019 [Jean-Benoit Hardouin] /*radar option*/ +* Release 1.6 : August 23, 2019 [Jean-Benoit Hardouin] /*correction of a bug to save the scores*/ +* Release 1.7 : August 29, 2019 [Jean-Benoit Hardouin] /*improvement of radar*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program :http://www.anaqol.org +* +* Copyright 2013, 2018, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** +program define sf36fr , rclass +version 8.2 +syntax varlist(min=36 max=36 numeric) [,v2 save(string) REPlace age(varname) SEXe(varname) saveref(string) DETails saveimp(string) RADar FILESave DIRSave(string)] + +*preserve +local nbitems : word count `varlist' +if `nbitems'!=36 { + di in red "There is `nbitems' items defined instead of 36" +} + +tokenize `varlist' +local varlistsav `varlist' +local sf gh1 ht pf1 pf2 pf3 pf4 pf5 pf6 pf7 pf8 pf9 pf10 rp1 rp2 rp3 rp4 re1 re2 re3 sf1 bp1 bp2 vt1 mh1 mh2 mh3 vt2 mh4 vt3 mh5 vt4 sf2 gh2 gh3 gh4 gh5 +local sf2 +local varlist2 +forvalues i=1/36 { + local j:word `i' of `sf' + tempname `j' + *di " qui gen `j'=``i''" + qui gen ``j''=``i'' + local varlist2 "`varlist2' ``j''" +} +local varlist "`varlist2'" +tokenize `varlist' +*di "`varlist'" + + +if "`v2'"=="" { + local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 5 6 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5 +} +else { + local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 +} +forvalues i=1/36 { + local mod`i':word `i' of `modamax' +} +local error=0 +local inf +local sup +local c=1 +foreach i of varlist `varlist' { + qui count if `i'<1 + if `r(N)'>0 { + local error=1 + local inf "`inf' `i'" + } + local tmp: word `c' of `modamax' + qui count if `i'>`c' + if `r(N)'>0 { + local error=1 + local inf "`sup' `i'" + } + local ++c +} +forvalues i=1/15 { + tempname inc`i' +} +local liste1 11 12 11 12 11 12 11 12 30 24 27 23 1 20 21 +local liste2 3 3 4 4 6 6 9 9 25 26 29 31 36 32 22 +*tab `11' `3' +qui gen `inc1'=`11'==1&`3'>1 if `11'!=.&`3'!=. +* tab `inc`i'' +qui gen `inc2'=`12'==1&`3'>1 if `12'!=.&`3'!=. +qui gen `inc3'=`11'==1&`4'>1 if `11'!=.&`4'!=. +qui gen `inc4'=`12'==1&`4'>1 if `12'!=.&`4'!=. +qui gen `inc5'=`11'==1&`6'>1 if `11'!=.&`6'!=. +qui gen `inc6'=`12'==1&`6'>1 if `12'!=.&`6'!=. +qui gen `inc7'=`11'==1&`9'>1 if `11'!=.&`9'!=. +qui gen `inc8'=`12'==1&`9'>1 if `12'!=.&`9'!=. +qui gen `inc9'=(`30'==1&`25'==1)|(`30'==`mod30'&`25'==`mod25') if `30'!=.&`25'!=. +qui gen `inc10'=(`24'==1&`26'==1)|(`24'==`mod24'&`26'==`mod26') if `24'!=.&`26'!=. +qui gen `inc11'=(`27'==1&`29'==1)|(`27'==`mod27'&`29'==`mod29') if `27'!=.&`29'!=. +qui gen `inc12'=(`23'==1&`31'==1)|(`23'==`mod23'&`31'==`mod31') if `23'!=.&`31'!=. +qui gen `inc13'=(`1'==1&`36'==`mod36')|(`1'==`mod1'&`36'==1) if `1'!=.&`36'!=. +qui gen `inc14'=(`20'==1&`32'==1)|(`20'==`mod20'&`32'==`mod32') if `20'!=.&`32'!=. +qui gen `inc15'=(`21'==1&`22'==`mod22')|(`21'==`mod21'&`22'==1) if `21'!=.&`22'!=. +tempname scoreinc +genscore `inc1'-`inc15',score(`scoreinc') +if "`details'" !="" { + di "{hline 80}" + di in gr "Discrepancies" _col(20) "item 1" _col(40) "item 2" _col(60) "# individuals" + di "{hline 80}" + *di "varlist:`varlistsav'" + forvalues i=1/15 { + local i1:word `i' of `liste1' + local i2:word `i' of `liste2' + local ni1:word `i1' of `varlistsav' + local ni2:word `i2' of `varlistsav' + qui count if `inc`i''==1 + + di in gr "`i'" in ye _col(20) abbrev("`ni1'",19) _col(40) abbrev("`ni2'",19) %6.0f _col(67) `r(N)' + } + di "{hline 80}" +} +*list subjid `scoreinc' `inc1'-`inc15' `scoreinc' if `scoreinc'!=0&`scoreinc'!=. + + +forvalues i=1/15 { + local i1:word `i' of `liste1' + local i2:word `i' of `liste2' + qui replace ``i1''=. if `inc`i''==1 + qui replace ``i2''=. if `inc`i''==1 +} + +tempname imp scorepf scorerp scorebp scoregh scorevt scoresf scorere scoremh + + /*PF*/ + imputeitems `3' `4' `5' `6' `7' `8' `9' `10' `11' `12',max(4) noround prefix(`imp') + genscore `imp'`3' `imp'`4' `imp'`5' `imp'`6' `imp'`7' `imp'`8' `imp'`9' `imp'`10' `imp'`11' `imp'`12',score(`scorepf') + qui replace `scorepf'=(`scorepf'-10)/20*100 + /*RP*/ + imputeitems `13' `14' `15' `16',max(1) noround prefix(`imp') + genscore `imp'`13' `imp'`14' `imp'`15' `imp'`16',score(`scorerp') + qui replace `scorerp'=(`scorerp'-4)/4*100 + /*BP*/ + tempvar jb + qui gen `jb'=. + qui replace `jb'=6 if `21'==1&`22'==1 + qui replace `jb'=5 if `21'>=2&`21'<=6&`22'==1 + qui replace `jb'=4 if `22'==2&`21'!=. + qui replace `jb'=3 if `22'==3&`21'!=. + qui replace `jb'=2 if `22'==4&`21'!=. + qui replace `jb'=1 if `22'==5&`21'!=. + qui replace `jb'=6 if `22'==1&`21'==. + qui replace `jb'=4.75 if `22'==2&`21'==. + qui replace `jb'=3.5 if `22'==3&`21'==. + qui replace `jb'=2.25 if `22'==4&`21'==. + qui replace `jb'=1 if `22'==5&`21'==. + qui replace `22'=`jb' + if "`v2'"=="" { + qui recode `21' 1=6 2=5.4 3=4.2 4=3.1 5=2.2 6=1 + } + else { + qui recode `21' 1=6 2=4.8 3=2.65 4=1 + } + imputeitems `21' `22',max(0) noround prefix(`imp') +* replace `imp'`21'=`21' +* replace `imp'`22'=`22' + qui genscore `imp'`21' `imp'`22',score(`scorebp') +* list sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques `21' `22' `imp'`21' `imp'`22' `scorebp' + qui replace `scorebp'=(`scorebp'-2)/10*100 +*tab `scorebp' + /*GH*/ + qui recode `1' 1=5 2=4.4 3=3.4 4=2 5=1 + qui recode `34' 1=5 2=4 3=3 4=2 5=1 + qui recode `36' 1=5 2=4 3=3 4=2 5=1 + imputeitems `1' `33' `34' `35' `36',max(2) noround prefix(`imp') + genscore `imp'`1' `imp'`33' `imp'`34' `imp'`35' `imp'`36',score(`scoregh') + qui replace `scoregh'=(`scoregh'-5)/20*100 + /*VT*/ + if "`v2'"=="" { + qui recode `23' 1=6 2=5 3=4 4=3 5=2 6=1 + qui recode `27' 1=6 2=5 3=4 4=3 5=2 6=1 + } + else { + qui recode `23' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `27' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `29' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `31' 1=1 2=2 3=3.5 4=4.5 5=6 + } + imputeitems `23' `27' `29' `31',max(1) noround prefix(`imp') + genscore `imp'`23' `imp'`27' `imp'`29' `imp'`31',score(`scorevt') + qui replace `scorevt'=(`scorevt'-4)/20*100 + /*SF*/ + if "`v2'"=="" { + qui recode `20' 1=5 2=4 3=3 4=2 5=1 + } + else { + qui recode `20' 1=5 2=4 3=2.5 4=1 + } + imputeitems `20' `32',max(0) noround prefix(`imp') + genscore `imp'`20' `imp'`32',score(`scoresf') + qui replace `scoresf'=(`scoresf'-2)/8*100 + /*RE*/ + imputeitems `17' `18' `19',max(1) noround prefix(`imp') + genscore `imp'`17' `imp'`18' `imp'`19',score(`scorere') + qui replace `scorere'=(`scorere'-3)/3*100 + /*MH*/ + if "`v2'"=="" { + qui recode `26' 1=6 2=5 3=4 4=3 5=2 6=1 + qui recode `30' 1=6 2=5 3=4 4=3 5=2 6=1 + } + else { + qui recode `26' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `30' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `24' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `25' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `28' 1=1 2=2 3=3.5 4=4.5 5=6 + } + imputeitems `24' `25' `26' `28' `30',max(2) noround prefix(`imp') + genscore `imp'`24' `imp'`25' `imp'`26' `imp'`28' `imp'`30',score(`scoremh') + qui replace `scoremh'=(`scoremh'-5)/25*100 + tempname scorepfz scorerpz scorebpz scoreghz scorevtz scoresfz scorerez scoremhz scorepcs scoremcs + + /*scores composites*/ + qui gen `scorepfz'=(`scorepf'-84.52404)/22.89490 + qui gen `scorerpz'=(`scorerp'-81.19907)/33.79729 + qui gen `scorebpz'=(`scorebp'-75.49196)/23.55879 + qui gen `scoreghz'=(`scoregh'-72.21316)/20.16964 + qui gen `scorevtz'=(`scorevt'-61.05453)/20.86942 + qui gen `scoresfz'=(`scoresf'-83.59753)/22.37649 + qui gen `scorerez'=(`scorere'-81.29467)/33.02717 + qui gen `scoremhz'=(`scoremh'-74.84212)/18.01189 + qui gen `scorepcs'=(`scorepfz'*0.42402+`scorerpz'*0.35119+`scorebpz'*0.31754+`scoreghz'*0.24954+`scorevtz'*0.02877-`scoresfz'*0.0753-`scorerez'*0.19206-`scoremhz'*0.22069)*10+50 + qui gen `scoremcs'=(-`scorepfz'*0.22999-`scorerpz'*0.12329-`scorebpz'*0.09731-`scoreghz'*0.01571+`scorevtz'*0.23534+`scoresfz'*0.26876+`scorerez'*0.43407+`scoremhz'*0.48581)*10+50 + + +/*scores composites SF12*/ +tempname scoresf12p sf12p_1 sf12p_2a sf12p_2b sf12p_3a sf12p_3b sf12p_4a sf12p_4b sf12p_5 sf12p_6 sf12p_7a sf12p_7b sf12p_7c +tempname scoresf12m sf12m_1 sf12m_2a sf12m_2b sf12m_3a sf12m_3b sf12m_4a sf12m_4b sf12m_5 sf12m_6 sf12m_7a sf12m_7b sf12m_7c + qui gen `sf12p_1'=`1' + qui gen `sf12p_2a'=`4' + qui gen `sf12p_2b'=`6' + qui gen `sf12p_3a'=`14' + qui gen `sf12p_3b'=`15' + qui gen `sf12p_4a'=`18' + qui gen `sf12p_4b'=`19' + qui gen `sf12p_5'=`20' + qui gen `sf12p_6'=`32' + qui gen `sf12p_7a'=`26' + qui gen `sf12p_7b'=`27' + qui gen `sf12p_7c'=`28' + qui gen `sf12m_1'=`1' + qui gen `sf12m_2a'=`4' + qui gen `sf12m_2b'=`6' + qui gen `sf12m_3a'=`14' + qui gen `sf12m_3b'=`15' + qui gen `sf12m_4a'=`18' + qui gen `sf12m_4b'=`19' + qui gen `sf12m_5'=`20' + qui gen `sf12m_6'=`32' + qui gen `sf12m_7a'=`26' + qui gen `sf12m_7b'=`27' + qui gen `sf12m_7c'=`28' + qui recode `sf12p_1' 5=0 4.4=-1.31872 3.4=-3.02396 2=-5.56461 1=-8.37399 + qui recode `sf12m_1' 5=0 4.4=-0.06064 3.4=0.03482 2=-0.16891 1=-1.71175 + qui recode `sf12p_2a' 1=-7.23216 2=-3.45555 3=0 + qui recode `sf12m_2a' 1=3.93115 2=1.86840 3=0 + qui recode `sf12p_2b' 1=-6.24397 2=-2.73557 3=0 + qui recode `sf12m_2b' 1=2.68282 2=1.43103 3=0 + qui recode `sf12p_3a' 1=-4.61617 2=0 + qui recode `sf12m_3a' 1=1.44060 2=0 + qui recode `sf12p_3b' 1=-5.51747 2=0 + qui recode `sf12m_3b' 1=1.66968 2=0 + qui recode `sf12p_4a' 1=3.04365 2=0 + qui recode `sf12m_4a' 1=-6.82672 2=0 + qui recode `sf12p_4b' 1=2.32091 2=0 + qui recode `sf12m_4b' 1=-5.69921 2=0 + qui recode `sf12p_6' 1=-0.33682 2=-0.94342 3=-0.18043 4=0.11038 5=0 + qui recode `sf12m_6' 1=-6.29724 2=-8.26066 3=-5.63286 4=-3.13896 5=0 + if "`v2'"=="" { + qui recode `sf12p_5' 5=0 4=-3.80130 3=-6.50522 2=-8.38063 1=-11.25544 + qui recode `sf12m_5' 5=0 4=0.90384 3=1.49384 2=1.76691 1=1.48619 + qui recode `sf12p_7a' 6=0 5=0.66514 4=1.36689 3=2.37241 2=2.90426 1=3.46638 + qui recode `sf12m_7a' 6=0 5=-1.94949 4=-4.09842 3=-6.31121 2=-7.92717 1=-10.19085 + qui recode `sf12p_7b' 6=0 5=-0.42251 4=-1.14387 3=-1.61850 2=-2.02168 1=-2.44706 + qui recode `sf12m_7b' 6=0 5=-0.92057 4=-1.65178 3=-3.29805 2=-4.88962 1=-6.02409 + qui recode `sf12p_7c' 1=4.61446 2=3.41593 3=2.34247 4=1.28044 5=0.41188 6=0 + qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3=-8.09914 4=-4.59055 5=-1.95934 6=0 + } + else { + qui recode `sf12p_5' 5=0 4=-3.83130 2.5=-7.442925 1=-11.25544 + qui recode `sf12m_5' 5=0 4=0.90384 2.5=1.630375 1=1.48619 + qui recode `sf12p_7a' 6=0 4.5=1.016015 3.5=1.86965 2=2.90426 1=3.46638 + qui recode `sf12m_7a' 6=0 4.5=-3.023955 3.5=-5.204815 2=-7.92717 1=-10.19085 + qui recode `sf12p_7b' 6=0 4.5=-0.78319 3.5=-1.381185 2=-2.02168 1=-2.44706 + qui recode `sf12m_7b' 6=0 4.5=-1.286175 3.5=-2.474915 2=-4.88962 1=-6.02409 + qui recode `sf12p_7c' 1=4.61446 2=3.41593 3.5=1.811455 4.5=0.84616 6=0 + qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3.5=-6.344845 4.5=-3.274945 6=0 + } + qui gen `scoresf12p'=`sf12p_1'+`sf12p_2a'+`sf12p_2b'+`sf12p_3a'+`sf12p_3b'+`sf12p_4a'+`sf12p_4b'+`sf12p_5'+`sf12p_6'+`sf12p_7a'+`sf12p_7b'+`sf12p_7c'+56.57706 + qui gen `scoresf12m'=`sf12m_1'+`sf12m_2a'+`sf12m_2b'+`sf12m_3a'+`sf12m_3b'+`sf12m_4a'+`sf12m_4b'+`sf12m_5'+`sf12m_6'+`sf12m_7a'+`sf12m_7b'+`sf12m_7c'+60.75781 + +if "`save'"!="" { + local listmin pf rp bp gh vt sf re mh pcs mcs + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local error=0 + local list + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `save'`i' + if _rc==0&"`replace'"=="" { + local ++error + local list "`list' `save'`j'" + } + local ++c + } + local c=1 + if `error'==0 { + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `save'`i' + if _rc==0 { + qui replace `save'`i'=`score`i'' + } + else { + qui gen `save'`i'=`score`i'' + } + local ++c + } + } + else { + di in red "The variable(s) `list' already exist(s)" + } +} +tempname scoreref1 scoreref0 scoreref01 scoreref scorerefv1 scorerefv0 scorerefv01 scorerefv +matrix `scoreref1'=(96.65,95.80,86.82,82.36,67.86,89.76,93.14,72.85\95.75,91.16,83.60,76.07,64.50,86.50,90.64,72.08\94.41,90.76,81.03,73.13,64.32,86.37,89.07,71.01\92.27,88.64,79.02,72.27,66.06,86.69,90.00,71.53\82.32,79.81,70.21,65.97,60.19,83.33,83.00,71.10\76.58,74.74,67.10,62.37,58.21,79.74,80.04,71.16\67.16,61.28,63.99,58.61,53.93,76.16,66.67,70.24) +matrix `scoreref0'=(94.92,89.54,79.37,71.81,60.32,79.65,81.65,64.92\92.42,85.98,80.19,75.10,60.57,82.83,86.13,68.18\91.04,88.87,78.27,74.64,61.94,84.14,85.48,67.59\86.23,85.54,71.97,69.14,58.90,79.80,83.42,64.84\77.88,77.85,66.23,65.10,58.18,78.29,77.61,66.17\71.60,68.74,62.40,61.23,55.08,76.47,73.24,65.45\58.20,52.46,59.68,59.73,47.94,71.68,62.21,60.63) +matrix `scoreref01'=(95.65,92.18,82.51,76.26,63.52,83.93,86.47,68.29\93.93,88.34,81.75,75.54,62.35,84.51,88.19,69.94\92.71,89.80,79.63,73.89,63.12,85.24,87.26,69.28\89.25,87.09,75.50,70.70,62.48,83.24,86.71,68.19\79.99,78.78,68.12,65.51,59.14,80.69,80.19,68.52\73.69,71.24,64.37,61.71,56.39,77.84,76.05,67.84\62.40,56.67,61.72,59.20,50.86,73.80,64.38,65.29) +matrix `scoreref'=(84.45,81.21,73.39,69.13,59.96,81.55,82.13,68.47\87.07,83.86,75.98,70.07,62.23,84.08,85.41,71.42\82.22,78.96,71.18,68.33,58.03,79.41,79.34,65.96) +matrix `scorerefv1'=(11.78,15.33,17.21,13.93,14.16,14.43,20.73,15.28\9.64,21.30,19.63,15.89,16.72,19.05,24.18,15.83\11.08,23.63,21.00,16.20,16.65,18.97,26.12,16.70\14.92,26.35,22.09,17.41,16.24,17.01,23.15,16.23\20.48,32.67,22.24,17.93,16.89,20.35,32.04,17.40\22.78,36.05,24.06,19.08,18.03,21.94,33.89,16.60\27.44,40.86,24.38,17.61,18.86,24.08,41.43,20.03) +matrix `scorerefv0'=(9.10,21.65,21.66,17.69,18.10,22.35,29.58,17.32\14.19,28.28,21.28,16.66,18.28,20.57,28.19,18.06\14.81,25.19,21.25,17.64,18.55,20.97,29.37,17.92\19.11,29.40,23.90,18.60,17.84,21.44,31.24,16.66\21.49,33.02,24.10,18.78,18.22,23.46,34.89,18.03\23.42,38.17,23.94,17.67,17.59,22.46,37.41,18.21\25.70,39.18,23.40,18.08,17.98,24.06,39.97,18.98) +matrix `scorerefv01'=(10.33,19.46,20.21,17.00,16.94,20.00,26.80,16.83\12.44,25.45,20.60,16.31,17.69,19.96,16.51,17.18\13.19,24.43,21.15,16.95,17.66,20.02,27.85,17.40\17.39,27.92,23.25,18.06,17.41,19.64,27.65,16.76\21.11,32.83,23.29,18.37,17.61,22.16,33.63,17.88\23.27,37.40,24.09,18.28,17.83,22.29,36.13,17.77\26.85,40.16,23.92,17.83,18.62,24.13,40.67,20.04) +matrix `scorerefv'=(21.19,32.20,23.73,18.57,18.05,21.41,32.15,17.62\19.85,30.48,23.03,18.39,17.36,20.08,29.89,16.70\22.02,33.43,24.10,18.69,18.40,22.26,33.71,17.99) + +tempname scorerefpf scorerefrp scorerefbp scorerefgh scorerefvt scorerefsf scorerefre scorerefmh +tempname scorerefpfv scorerefrpv scorerefbpv scorerefghv scorerefvtv scorerefsfv scorerefrev scorerefmhv +if "`age'"!=""&"`sexe'"!="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref0'[1,`c'] if `sexe'==0&`age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref0'[2,`c'] if `sexe'==0&`age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref0'[3,`c'] if `sexe'==0&`age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref0'[4,`c'] if `sexe'==0&`age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref0'[5,`c'] if `sexe'==0&`age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref0'[6,`c'] if `sexe'==0&`age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref0'[7,`c'] if `sexe'==0&`age'>=75 + qui replace `scoreref`i''=`scoreref1'[1,`c'] if `sexe'==1&`age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref1'[2,`c'] if `sexe'==1&`age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref1'[3,`c'] if `sexe'==1&`age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref1'[4,`c'] if `sexe'==1&`age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref1'[5,`c'] if `sexe'==1&`age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref1'[6,`c'] if `sexe'==1&`age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref1'[7,`c'] if `sexe'==1&`age'>=75 + qui gen `scoreref`i'v'=(`scorerefv0'[1,`c'])^2 if `sexe'==0&`age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv0'[2,`c'])^2 if `sexe'==0&`age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv0'[3,`c'])^2 if `sexe'==0&`age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv0'[4,`c'])^2 if `sexe'==0&`age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv0'[5,`c'])^2 if `sexe'==0&`age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv0'[6,`c'])^2 if `sexe'==0&`age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv0'[7,`c'])^2 if `sexe'==0&`age'>=75 + qui replace `scoreref`i'v'=(`scorerefv1'[1,`c'])^2 if `sexe'==1&`age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv1'[2,`c'])^2 if `sexe'==1&`age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv1'[3,`c'])^2 if `sexe'==1&`age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv1'[4,`c'])^2 if `sexe'==1&`age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv1'[5,`c'])^2 if `sexe'==1&`age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv1'[6,`c'])^2 if `sexe'==1&`age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv1'[7,`c'])^2 if `sexe'==1&`age'>=75 + local ++c + } +} +else if "`age'"!=""&"`sexe'"=="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref01'[1,`c'] if `age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref01'[2,`c'] if `age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref01'[3,`c'] if `age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref01'[4,`c'] if `age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref01'[5,`c'] if `age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref01'[6,`c'] if `age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref01'[7,`c'] if `age'>=75 + qui gen `scoreref`i'v'=(`scorerefv01'[1,`c'])^2 if `age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv01'[2,`c'])^2 if `age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv01'[3,`c'])^2 if `age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv01'[4,`c'])^2 if `age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv01'[5,`c'])^2 if `age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv01'[6,`c'])^2 if `age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv01'[7,`c'])^2 if `age'>=75 + local ++c + } +} +else if "`age'"==""&"`sexe'"!="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref'[2,`c'] if `sexe'==1 + qui replace `scoreref`i''=`scoreref'[3,`c'] if `sexe'==0 + qui gen `scoreref`i'v'=(`scorerefv'[2,`c'])^2 if `sexe'==1 + qui replace `scoreref`i'v'=(`scorerefv'[3,`c'])^2 if `sexe'==0 + local ++c + } +} +else if "`age'"==""&"`sexe'"=="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + gen `scoreref`i''=`scoreref'[1,`c'] + gen `scoreref`i'v'=(`scorerefv'[1,`c'])^2 + local ++c + } +} +tempname scorerefpfz scorerefrpz scorerefbpz scorerefghz scorerefvtz scorerefsfz scorerefrez scorerefmhz scorerefpcs scorerefmcs +tempname scorerefpfvz scorerefrpvz scorerefbpvz scorerefghvz scorerefvtvz scorerefsfvz scorerefrevz scorerefmhvz scorerefpcsv scorerefmcsv + +qui gen `scorerefpfz'=(`scorerefpf'-84.52404)/22.89490 +qui gen `scorerefrpz'=(`scorerefrp'-81.19907)/33.79729 +qui gen `scorerefbpz'=(`scorerefbp'-75.49196)/23.55879 +qui gen `scorerefghz'=(`scorerefgh'-72.21316)/20.16964 +qui gen `scorerefvtz'=(`scorerefvt'-61.05453)/20.86942 +qui gen `scorerefsfz'=(`scorerefsf'-83.59753)/22.37649 +qui gen `scorerefrez'=(`scorerefre'-81.29467)/33.02717 +qui gen `scorerefmhz'=(`scorerefmh'-74.84212)/18.01189 +qui gen `scorerefpcs'=(`scorerefpfz'*0.42402+`scorerefrpz'*0.35119+`scorerefbpz'*0.31754+`scorerefghz'*0.24954+`scorerefvtz'*0.02877-`scorerefsfz'*0.0753-`scorerefrez'*0.19206-`scorerefmhz'*0.22069)*10+50 +qui gen `scorerefmcs'=(-`scorerefpfz'*0.22999-`scorerefrpz'*0.12329-`scorerefbpz'*0.09731-`scorerefghz'*0.01571+`scorerefvtz'*0.23534+`scorerefsfz'*0.26876+`scorerefrez'*0.43407+`scorerefmhz'*0.48581)*10+50 + +qui gen `scorerefpfvz'=(`scorerefpfv')/22.89490^2 +qui gen `scorerefrpvz'=(`scorerefrpv')/33.79729^2 +qui gen `scorerefbpvz'=(`scorerefbpv')/23.55879^2 +qui gen `scorerefghvz'=(`scorerefghv')/20.16964^2 +qui gen `scorerefvtvz'=(`scorerefvtv')/20.86942^2 +qui gen `scorerefsfvz'=(`scorerefsfv')/22.37649^2 +qui gen `scorerefrevz'=(`scorerefrev')/33.02717^2 +qui gen `scorerefmhvz'=(`scorerefmhv')/18.01189^2 +qui gen `scorerefpcsv'=(`scorerefpfvz'*0.42402^2+`scorerefrpvz'*0.35119^2+`scorerefbpvz'*0.31754^2+`scorerefghvz'*0.24954^2+`scorerefvtvz'*0.02877^2-`scorerefsfvz'*0.0753^2-`scorerefrevz'*0.19206^2-`scorerefmhvz'*0.22069^2)*10^2 +qui gen `scorerefmcsv'=(-`scorerefpfvz'*0.22999^2-`scorerefrpvz'*0.12329^2-`scorerefbpvz'*0.09731^2-`scorerefghvz'*0.01571^2+`scorerefvtvz'*0.23534^2+`scorerefsfvz'*0.26876^2+`scorerefrevz'*0.43407^2+`scorerefmhvz'*0.48581^2)*10^2 + + + + + +if "`saveref'"!="" { + local listmin pf rp bp gh vt sf re mh pcs mcs + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local error=0 + local list + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `saveref'`i' + if _rc==0&"`replace'"=="" { + local ++error + local list "`list' `saveref'`j'" + } + local ++c + } + local c=1 + if `error'==0 { + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `saveref'`i' + if _rc==0 { + qui replace `saveref'`i'=`scoreref`i'' + } + else { + qui gen `saveref'`i'=`scoreref`i'' + } + local ++c + } + } + else { + di in red "The variable(s) `list' already exist(s)" + } +} + +if "`details'"!=""|"`radar'"!="" { + tempname radar + qui matrix `radar'=J(12,2,.) + if "`details'"!="" { + di "{hline 80}" + di in gr _col(12) "Sample" _col(51) "Reference" + di in gr "Dimension" _col(16) "N" _col(21) "Mean" _col(29) "s.d." _col(40) "Min-Max" _col(52) "Mean" _col(60) "s.d." _col(72) "p" + di "{hline 80}" + } + local listmin pf rp bp gh vt sf re mh pcs mcs sf12p sf12m + local listmaj PF RP BP GH VT SF RE MH PCS MCS SF12P SF12M + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + qui su `score`i'' + local means`i'=r(mean) + local sds`i'=r(sd) + local mins`i'=r(min) + local maxs`i'=r(max) + local n`i'=r(N) + matrix `radar'[`c',1]=`means`i'' + qui su `scoreref`i'' + matrix `radar'[`c',2]=r(mean) + if "`i'"!="sf12p"&"`i'"!="sf12m" { + qui su `scoreref`i'' if `score`i''!=. + local meanr`i'=r(mean) + local sdr`i'=r(sd) + local vr`i'=(`sdr`i'')^2 + qui su `scoreref`i'v' if `score`i''!=. + local meanvr`i'=r(mean) + local sdr`i'=sqrt(`vr`i''+`meanvr`i'') + *local minr`i'=r(min) + *local maxr`i'=r(max) + qui ttest `score`i''=`meanr`i'' + local p`i'=r(p) + } + if "`details'"!="" { + di in gr "`j'" in ye _col(12) %5.0f `n`i'' _col(20) %5.2f `means`i'' _col(28) %5.2f `sds`i'' _col(34) %6.2f `mins`i'' "-" %6.2f `maxs`i'' _col(51) %5.2f `meanr`i'' _col(59) %5.2f `sdr`i'' _col(67) %6.4f `p`i'' + } + local ++c + } + if "`details'"!="" { + di "{hline 80}" + } + *corr `scorepcs' `scoremcs' `scoresf12p' `scoresf12m' + *scatter `scorepcs' `scoresf12p' ,name(p) + *scatter `scoremcs' `scoresf12m' ,name(m) + *su `scoresf12p' `sf12p_1' `sf12p_2a' `sf12p_2b' `sf12p_3a' `sf12p_3b' `sf12p_4a' `sf12p_4b' `sf12p_5' `sf12p_6' `sf12p_7a' `sf12p_7b' `sf12p_7c' + *su `scoresf12m' `sf12m_1' `sf12m_2a' `sf12m_2b' `sf12m_3a' `sf12m_3b' `sf12m_4a' `sf12m_4b' `sf12m_5' `sf12m_6' `sf12m_7a' `sf12m_7b' `sf12m_7c' + if "`radar'"!=""&"`v2'"=="" { + qui tempfile radarfile + qui save `radarfile', replace + qui drop _all + qui svmat `radar' + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local c=1 + qui gen name="" + foreach i in `listmin' { + qui replace name="`i'" in `c' + local ++c + } + qui rename `radar'1 scoreSF36 + rename `radar'2 scoreSF36ref + qui keep in 1/10 + label variable scoreSF36 "Sample" + label variable scoreSF36ref "General French population" + if "`filesave'"!="" { + if "`dirsave'"=="" { + local dirsave `c(pwd)' + } + local saving "saving(`dirsave'//radar, replace) " + } + qui radar name scoreSF36 scoreSF36ref, note("") title("Comparison of the sample with the general French population") legend(lab(1 "Sample") lab(2 "General French population")) `saving' r(0 20 40 60 80 100) + qui use `radarfile', clear + } +} +if "`saveimp'"!="" { +*su + foreach i of numlist 1 3/36 { + local j:word `i' of `varlistsav' + *di "gen `saveimp'`j'=`imp'``i''" + capture confirm variable `saveimp'`j' + if _rc==0&"`replace'"=="" { + di in ye "The variable `saveimp'`j' already exists and cannot be replaced." + } + else if _rc==0&"`replace'"!="" { + qui replace `saveimp'`j'=`imp'``i'' + } + else { + qui gen `saveimp'`j'=`imp'``i'' + } + } +} +*restore, preserve +end diff --git a/Modules/ado/personal/s/sf36fr.ado b/Modules/ado/personal/s/sf36fr.ado new file mode 100644 index 0000000..306b47c --- /dev/null +++ b/Modules/ado/personal/s/sf36fr.ado @@ -0,0 +1,589 @@ +*! Version 1.8 13December2023 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : sf36fr +* computes score of the French SF36 questionnnaire +* +* Historic : +* Version 1 (May 2, 2013) [Jean-Benoit Hardouin] +* Release 1 : May 2, 2013 [Jean-benoit Hardouin] +* Release 1.1 : May 14, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/ +* Release 1.2 : May 21, 2013 [Jean-Benoit Hardouin] /*saveimp option*/ +* Release 1.3 : May 24, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/ +* Release 1.4 : December 1, 2018 [Jean-Benoit Hardouin] /*correction of a bug on SF12*/ +* Release 1.5 : July 29, 2019 [Jean-Benoit Hardouin] /*radar option*/ +* Release 1.6 : August 23, 2019 [Jean-Benoit Hardouin] /*correction of a bug to save the scores*/ +* Release 1.7 : August 29, 2019 [Jean-Benoit Hardouin] /*improvement of radar*/ +* Release 1.8 : December 13, 2023 [Jean-Benoit Hardouin] /*Correction for individuals with exactly 50% of missing data in a scale: they should be imputed (Ware, SF36 manual) but were not imputed before*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program :http://www.anaqol.org +* +* Copyright 2013, 2018, 2019, 2023 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** +program define sf36fr , rclass +version 8.2 +syntax varlist(min=36 max=36 numeric) [,v2 save(string) REPlace age(varname) SEXe(varname) saveref(string) DETails saveimp(string) RADar FILESave DIRSave(string)] + +*preserve +local nbitems : word count `varlist' +if `nbitems'!=36 { + di in red "There is `nbitems' items defined instead of 36" +} + +tokenize `varlist' +local varlistsav `varlist' +local sf gh1 ht pf1 pf2 pf3 pf4 pf5 pf6 pf7 pf8 pf9 pf10 rp1 rp2 rp3 rp4 re1 re2 re3 sf1 bp1 bp2 vt1 mh1 mh2 mh3 vt2 mh4 vt3 mh5 vt4 sf2 gh2 gh3 gh4 gh5 +local sf2 +local varlist2 +forvalues i=1/36 { + local j:word `i' of `sf' + tempname `j' + *di " qui gen `j'=``i''" + qui gen ``j''=``i'' + local varlist2 "`varlist2' ``j''" +} +local varlist "`varlist2'" +tokenize `varlist' +*di "`varlist'" + + +if "`v2'"=="" { + local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 5 6 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5 +} +else { + local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 +} +forvalues i=1/36 { + local mod`i':word `i' of `modamax' +} +local error=0 +local inf +local sup +local c=1 +foreach i of varlist `varlist' { + qui count if `i'<1 + if `r(N)'>0 { + local error=1 + local inf "`inf' `i'" + } + local tmp: word `c' of `modamax' + qui count if `i'>`c' + if `r(N)'>0 { + local error=1 + local inf "`sup' `i'" + } + local ++c +} +forvalues i=1/15 { + tempname inc`i' +} +local liste1 11 12 11 12 11 12 11 12 30 24 27 23 1 20 21 +local liste2 3 3 4 4 6 6 9 9 25 26 29 31 36 32 22 +*tab `11' `3' +qui gen `inc1'=`11'==1&`3'>1 if `11'!=.&`3'!=. +* tab `inc`i'' +qui gen `inc2'=`12'==1&`3'>1 if `12'!=.&`3'!=. +qui gen `inc3'=`11'==1&`4'>1 if `11'!=.&`4'!=. +qui gen `inc4'=`12'==1&`4'>1 if `12'!=.&`4'!=. +qui gen `inc5'=`11'==1&`6'>1 if `11'!=.&`6'!=. +qui gen `inc6'=`12'==1&`6'>1 if `12'!=.&`6'!=. +qui gen `inc7'=`11'==1&`9'>1 if `11'!=.&`9'!=. +qui gen `inc8'=`12'==1&`9'>1 if `12'!=.&`9'!=. +qui gen `inc9'=(`30'==1&`25'==1)|(`30'==`mod30'&`25'==`mod25') if `30'!=.&`25'!=. +qui gen `inc10'=(`24'==1&`26'==1)|(`24'==`mod24'&`26'==`mod26') if `24'!=.&`26'!=. +qui gen `inc11'=(`27'==1&`29'==1)|(`27'==`mod27'&`29'==`mod29') if `27'!=.&`29'!=. +qui gen `inc12'=(`23'==1&`31'==1)|(`23'==`mod23'&`31'==`mod31') if `23'!=.&`31'!=. +qui gen `inc13'=(`1'==1&`36'==`mod36')|(`1'==`mod1'&`36'==1) if `1'!=.&`36'!=. +qui gen `inc14'=(`20'==1&`32'==1)|(`20'==`mod20'&`32'==`mod32') if `20'!=.&`32'!=. +qui gen `inc15'=(`21'==1&`22'==`mod22')|(`21'==`mod21'&`22'==1) if `21'!=.&`22'!=. +tempname scoreinc +genscore `inc1'-`inc15',score(`scoreinc') +if "`details'" !="" { + di "{hline 80}" + di in gr "Discrepancies" _col(20) "item 1" _col(40) "item 2" _col(60) "# individuals" + di "{hline 80}" + *di "varlist:`varlistsav'" + forvalues i=1/15 { + local i1:word `i' of `liste1' + local i2:word `i' of `liste2' + local ni1:word `i1' of `varlistsav' + local ni2:word `i2' of `varlistsav' + qui count if `inc`i''==1 + + di in gr "`i'" in ye _col(20) abbrev("`ni1'",19) _col(40) abbrev("`ni2'",19) %6.0f _col(67) `r(N)' + } + di "{hline 80}" +} +*list subjid `scoreinc' `inc1'-`inc15' `scoreinc' if `scoreinc'!=0&`scoreinc'!=. + + +forvalues i=1/15 { + local i1:word `i' of `liste1' + local i2:word `i' of `liste2' + qui replace ``i1''=. if `inc`i''==1 + qui replace ``i2''=. if `inc`i''==1 +} + +tempname imp scorepf scorerp scorebp scoregh scorevt scoresf scorere scoremh + + /*PF*/ + imputeitems `3' `4' `5' `6' `7' `8' `9' `10' `11' `12',max(5) noround prefix(`imp') + genscore `imp'`3' `imp'`4' `imp'`5' `imp'`6' `imp'`7' `imp'`8' `imp'`9' `imp'`10' `imp'`11' `imp'`12',score(`scorepf') + qui replace `scorepf'=(`scorepf'-10)/20*100 + /*RP*/ + imputeitems `13' `14' `15' `16',max(2) noround prefix(`imp') + genscore `imp'`13' `imp'`14' `imp'`15' `imp'`16',score(`scorerp') + qui replace `scorerp'=(`scorerp'-4)/4*100 + /*BP*/ + tempvar jb + qui gen `jb'=. + qui replace `jb'=6 if `21'==1&`22'==1 + qui replace `jb'=5 if `21'>=2&`21'<=6&`22'==1 + qui replace `jb'=4 if `22'==2&`21'!=. + qui replace `jb'=3 if `22'==3&`21'!=. + qui replace `jb'=2 if `22'==4&`21'!=. + qui replace `jb'=1 if `22'==5&`21'!=. + qui replace `jb'=6 if `22'==1&`21'==. + qui replace `jb'=4.75 if `22'==2&`21'==. + qui replace `jb'=3.5 if `22'==3&`21'==. + qui replace `jb'=2.25 if `22'==4&`21'==. + qui replace `jb'=1 if `22'==5&`21'==. + qui replace `22'=`jb' + if "`v2'"=="" { + qui recode `21' 1=6 2=5.4 3=4.2 4=3.1 5=2.2 6=1 + } + else { + qui recode `21' 1=6 2=4.8 3=2.65 4=1 + } + imputeitems `21' `22',max(1) noround prefix(`imp') +* replace `imp'`21'=`21' +* replace `imp'`22'=`22' + qui genscore `imp'`21' `imp'`22',score(`scorebp') +* list sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques `21' `22' `imp'`21' `imp'`22' `scorebp' + qui replace `scorebp'=(`scorebp'-2)/10*100 +*tab `scorebp' + /*GH*/ + qui recode `1' 1=5 2=4.4 3=3.4 4=2 5=1 + qui recode `34' 1=5 2=4 3=3 4=2 5=1 + qui recode `36' 1=5 2=4 3=3 4=2 5=1 + imputeitems `1' `33' `34' `35' `36',max(2) noround prefix(`imp') + genscore `imp'`1' `imp'`33' `imp'`34' `imp'`35' `imp'`36',score(`scoregh') + qui replace `scoregh'=(`scoregh'-5)/20*100 + /*VT*/ + if "`v2'"=="" { + qui recode `23' 1=6 2=5 3=4 4=3 5=2 6=1 + qui recode `27' 1=6 2=5 3=4 4=3 5=2 6=1 + } + else { + qui recode `23' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `27' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `29' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `31' 1=1 2=2 3=3.5 4=4.5 5=6 + } + imputeitems `23' `27' `29' `31',max(2) noround prefix(`imp') + genscore `imp'`23' `imp'`27' `imp'`29' `imp'`31',score(`scorevt') + qui replace `scorevt'=(`scorevt'-4)/20*100 + /*SF*/ + if "`v2'"=="" { + qui recode `20' 1=5 2=4 3=3 4=2 5=1 + } + else { + qui recode `20' 1=5 2=4 3=2.5 4=1 + } + imputeitems `20' `32',max(1) noround prefix(`imp') + genscore `imp'`20' `imp'`32',score(`scoresf') + qui replace `scoresf'=(`scoresf'-2)/8*100 + /*RE*/ + imputeitems `17' `18' `19',max(1) noround prefix(`imp') + genscore `imp'`17' `imp'`18' `imp'`19',score(`scorere') + qui replace `scorere'=(`scorere'-3)/3*100 + /*MH*/ + if "`v2'"=="" { + qui recode `26' 1=6 2=5 3=4 4=3 5=2 6=1 + qui recode `30' 1=6 2=5 3=4 4=3 5=2 6=1 + } + else { + qui recode `26' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `30' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `24' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `25' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `28' 1=1 2=2 3=3.5 4=4.5 5=6 + } + imputeitems `24' `25' `26' `28' `30',max(2) noround prefix(`imp') + genscore `imp'`24' `imp'`25' `imp'`26' `imp'`28' `imp'`30',score(`scoremh') + qui replace `scoremh'=(`scoremh'-5)/25*100 + tempname scorepfz scorerpz scorebpz scoreghz scorevtz scoresfz scorerez scoremhz scorepcs scoremcs + + /*scores composites*/ + qui gen `scorepfz'=(`scorepf'-84.52404)/22.89490 + qui gen `scorerpz'=(`scorerp'-81.19907)/33.79729 + qui gen `scorebpz'=(`scorebp'-75.49196)/23.55879 + qui gen `scoreghz'=(`scoregh'-72.21316)/20.16964 + qui gen `scorevtz'=(`scorevt'-61.05453)/20.86942 + qui gen `scoresfz'=(`scoresf'-83.59753)/22.37649 + qui gen `scorerez'=(`scorere'-81.29467)/33.02717 + qui gen `scoremhz'=(`scoremh'-74.84212)/18.01189 + qui gen `scorepcs'=(`scorepfz'*0.42402+`scorerpz'*0.35119+`scorebpz'*0.31754+`scoreghz'*0.24954+`scorevtz'*0.02877-`scoresfz'*0.0753-`scorerez'*0.19206-`scoremhz'*0.22069)*10+50 + qui gen `scoremcs'=(-`scorepfz'*0.22999-`scorerpz'*0.12329-`scorebpz'*0.09731-`scoreghz'*0.01571+`scorevtz'*0.23534+`scoresfz'*0.26876+`scorerez'*0.43407+`scoremhz'*0.48581)*10+50 + + +/*scores composites SF12*/ +tempname scoresf12p sf12p_1 sf12p_2a sf12p_2b sf12p_3a sf12p_3b sf12p_4a sf12p_4b sf12p_5 sf12p_6 sf12p_7a sf12p_7b sf12p_7c +tempname scoresf12m sf12m_1 sf12m_2a sf12m_2b sf12m_3a sf12m_3b sf12m_4a sf12m_4b sf12m_5 sf12m_6 sf12m_7a sf12m_7b sf12m_7c + qui gen `sf12p_1'=`1' + qui gen `sf12p_2a'=`4' + qui gen `sf12p_2b'=`6' + qui gen `sf12p_3a'=`14' + qui gen `sf12p_3b'=`15' + qui gen `sf12p_4a'=`18' + qui gen `sf12p_4b'=`19' + qui gen `sf12p_5'=`20' + qui gen `sf12p_6'=`32' + qui gen `sf12p_7a'=`26' + qui gen `sf12p_7b'=`27' + qui gen `sf12p_7c'=`28' + qui gen `sf12m_1'=`1' + qui gen `sf12m_2a'=`4' + qui gen `sf12m_2b'=`6' + qui gen `sf12m_3a'=`14' + qui gen `sf12m_3b'=`15' + qui gen `sf12m_4a'=`18' + qui gen `sf12m_4b'=`19' + qui gen `sf12m_5'=`20' + qui gen `sf12m_6'=`32' + qui gen `sf12m_7a'=`26' + qui gen `sf12m_7b'=`27' + qui gen `sf12m_7c'=`28' + qui recode `sf12p_1' 5=0 4.4=-1.31872 3.4=-3.02396 2=-5.56461 1=-8.37399 + qui recode `sf12m_1' 5=0 4.4=-0.06064 3.4=0.03482 2=-0.16891 1=-1.71175 + qui recode `sf12p_2a' 1=-7.23216 2=-3.45555 3=0 + qui recode `sf12m_2a' 1=3.93115 2=1.86840 3=0 + qui recode `sf12p_2b' 1=-6.24397 2=-2.73557 3=0 + qui recode `sf12m_2b' 1=2.68282 2=1.43103 3=0 + qui recode `sf12p_3a' 1=-4.61617 2=0 + qui recode `sf12m_3a' 1=1.44060 2=0 + qui recode `sf12p_3b' 1=-5.51747 2=0 + qui recode `sf12m_3b' 1=1.66968 2=0 + qui recode `sf12p_4a' 1=3.04365 2=0 + qui recode `sf12m_4a' 1=-6.82672 2=0 + qui recode `sf12p_4b' 1=2.32091 2=0 + qui recode `sf12m_4b' 1=-5.69921 2=0 + qui recode `sf12p_6' 1=-0.33682 2=-0.94342 3=-0.18043 4=0.11038 5=0 + qui recode `sf12m_6' 1=-6.29724 2=-8.26066 3=-5.63286 4=-3.13896 5=0 + if "`v2'"=="" { + qui recode `sf12p_5' 5=0 4=-3.80130 3=-6.50522 2=-8.38063 1=-11.25544 + qui recode `sf12m_5' 5=0 4=0.90384 3=1.49384 2=1.76691 1=1.48619 + qui recode `sf12p_7a' 6=0 5=0.66514 4=1.36689 3=2.37241 2=2.90426 1=3.46638 + qui recode `sf12m_7a' 6=0 5=-1.94949 4=-4.09842 3=-6.31121 2=-7.92717 1=-10.19085 + qui recode `sf12p_7b' 6=0 5=-0.42251 4=-1.14387 3=-1.61850 2=-2.02168 1=-2.44706 + qui recode `sf12m_7b' 6=0 5=-0.92057 4=-1.65178 3=-3.29805 2=-4.88962 1=-6.02409 + qui recode `sf12p_7c' 1=4.61446 2=3.41593 3=2.34247 4=1.28044 5=0.41188 6=0 + qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3=-8.09914 4=-4.59055 5=-1.95934 6=0 + } + else { + qui recode `sf12p_5' 5=0 4=-3.83130 2.5=-7.442925 1=-11.25544 + qui recode `sf12m_5' 5=0 4=0.90384 2.5=1.630375 1=1.48619 + qui recode `sf12p_7a' 6=0 4.5=1.016015 3.5=1.86965 2=2.90426 1=3.46638 + qui recode `sf12m_7a' 6=0 4.5=-3.023955 3.5=-5.204815 2=-7.92717 1=-10.19085 + qui recode `sf12p_7b' 6=0 4.5=-0.78319 3.5=-1.381185 2=-2.02168 1=-2.44706 + qui recode `sf12m_7b' 6=0 4.5=-1.286175 3.5=-2.474915 2=-4.88962 1=-6.02409 + qui recode `sf12p_7c' 1=4.61446 2=3.41593 3.5=1.811455 4.5=0.84616 6=0 + qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3.5=-6.344845 4.5=-3.274945 6=0 + } + qui gen `scoresf12p'=`sf12p_1'+`sf12p_2a'+`sf12p_2b'+`sf12p_3a'+`sf12p_3b'+`sf12p_4a'+`sf12p_4b'+`sf12p_5'+`sf12p_6'+`sf12p_7a'+`sf12p_7b'+`sf12p_7c'+56.57706 + qui gen `scoresf12m'=`sf12m_1'+`sf12m_2a'+`sf12m_2b'+`sf12m_3a'+`sf12m_3b'+`sf12m_4a'+`sf12m_4b'+`sf12m_5'+`sf12m_6'+`sf12m_7a'+`sf12m_7b'+`sf12m_7c'+60.75781 + +if "`save'"!="" { + local listmin pf rp bp gh vt sf re mh pcs mcs + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local error=0 + local list + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `save'`i' + if _rc==0&"`replace'"=="" { + local ++error + local list "`list' `save'`j'" + } + local ++c + } + local c=1 + if `error'==0 { + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `save'`i' + if _rc==0 { + qui replace `save'`i'=`score`i'' + } + else { + qui gen `save'`i'=`score`i'' + } + local ++c + } + } + else { + di in red "The variable(s) `list' already exist(s)" + } +} +tempname scoreref1 scoreref0 scoreref01 scoreref scorerefv1 scorerefv0 scorerefv01 scorerefv +matrix `scoreref1'=(96.65,95.80,86.82,82.36,67.86,89.76,93.14,72.85\95.75,91.16,83.60,76.07,64.50,86.50,90.64,72.08\94.41,90.76,81.03,73.13,64.32,86.37,89.07,71.01\92.27,88.64,79.02,72.27,66.06,86.69,90.00,71.53\82.32,79.81,70.21,65.97,60.19,83.33,83.00,71.10\76.58,74.74,67.10,62.37,58.21,79.74,80.04,71.16\67.16,61.28,63.99,58.61,53.93,76.16,66.67,70.24) +matrix `scoreref0'=(94.92,89.54,79.37,71.81,60.32,79.65,81.65,64.92\92.42,85.98,80.19,75.10,60.57,82.83,86.13,68.18\91.04,88.87,78.27,74.64,61.94,84.14,85.48,67.59\86.23,85.54,71.97,69.14,58.90,79.80,83.42,64.84\77.88,77.85,66.23,65.10,58.18,78.29,77.61,66.17\71.60,68.74,62.40,61.23,55.08,76.47,73.24,65.45\58.20,52.46,59.68,59.73,47.94,71.68,62.21,60.63) +matrix `scoreref01'=(95.65,92.18,82.51,76.26,63.52,83.93,86.47,68.29\93.93,88.34,81.75,75.54,62.35,84.51,88.19,69.94\92.71,89.80,79.63,73.89,63.12,85.24,87.26,69.28\89.25,87.09,75.50,70.70,62.48,83.24,86.71,68.19\79.99,78.78,68.12,65.51,59.14,80.69,80.19,68.52\73.69,71.24,64.37,61.71,56.39,77.84,76.05,67.84\62.40,56.67,61.72,59.20,50.86,73.80,64.38,65.29) +matrix `scoreref'=(84.45,81.21,73.39,69.13,59.96,81.55,82.13,68.47\87.07,83.86,75.98,70.07,62.23,84.08,85.41,71.42\82.22,78.96,71.18,68.33,58.03,79.41,79.34,65.96) +matrix `scorerefv1'=(11.78,15.33,17.21,13.93,14.16,14.43,20.73,15.28\9.64,21.30,19.63,15.89,16.72,19.05,24.18,15.83\11.08,23.63,21.00,16.20,16.65,18.97,26.12,16.70\14.92,26.35,22.09,17.41,16.24,17.01,23.15,16.23\20.48,32.67,22.24,17.93,16.89,20.35,32.04,17.40\22.78,36.05,24.06,19.08,18.03,21.94,33.89,16.60\27.44,40.86,24.38,17.61,18.86,24.08,41.43,20.03) +matrix `scorerefv0'=(9.10,21.65,21.66,17.69,18.10,22.35,29.58,17.32\14.19,28.28,21.28,16.66,18.28,20.57,28.19,18.06\14.81,25.19,21.25,17.64,18.55,20.97,29.37,17.92\19.11,29.40,23.90,18.60,17.84,21.44,31.24,16.66\21.49,33.02,24.10,18.78,18.22,23.46,34.89,18.03\23.42,38.17,23.94,17.67,17.59,22.46,37.41,18.21\25.70,39.18,23.40,18.08,17.98,24.06,39.97,18.98) +matrix `scorerefv01'=(10.33,19.46,20.21,17.00,16.94,20.00,26.80,16.83\12.44,25.45,20.60,16.31,17.69,19.96,16.51,17.18\13.19,24.43,21.15,16.95,17.66,20.02,27.85,17.40\17.39,27.92,23.25,18.06,17.41,19.64,27.65,16.76\21.11,32.83,23.29,18.37,17.61,22.16,33.63,17.88\23.27,37.40,24.09,18.28,17.83,22.29,36.13,17.77\26.85,40.16,23.92,17.83,18.62,24.13,40.67,20.04) +matrix `scorerefv'=(21.19,32.20,23.73,18.57,18.05,21.41,32.15,17.62\19.85,30.48,23.03,18.39,17.36,20.08,29.89,16.70\22.02,33.43,24.10,18.69,18.40,22.26,33.71,17.99) + +tempname scorerefpf scorerefrp scorerefbp scorerefgh scorerefvt scorerefsf scorerefre scorerefmh +tempname scorerefpfv scorerefrpv scorerefbpv scorerefghv scorerefvtv scorerefsfv scorerefrev scorerefmhv +if "`age'"!=""&"`sexe'"!="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref0'[1,`c'] if `sexe'==0&`age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref0'[2,`c'] if `sexe'==0&`age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref0'[3,`c'] if `sexe'==0&`age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref0'[4,`c'] if `sexe'==0&`age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref0'[5,`c'] if `sexe'==0&`age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref0'[6,`c'] if `sexe'==0&`age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref0'[7,`c'] if `sexe'==0&`age'>=75 + qui replace `scoreref`i''=`scoreref1'[1,`c'] if `sexe'==1&`age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref1'[2,`c'] if `sexe'==1&`age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref1'[3,`c'] if `sexe'==1&`age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref1'[4,`c'] if `sexe'==1&`age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref1'[5,`c'] if `sexe'==1&`age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref1'[6,`c'] if `sexe'==1&`age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref1'[7,`c'] if `sexe'==1&`age'>=75 + qui gen `scoreref`i'v'=(`scorerefv0'[1,`c'])^2 if `sexe'==0&`age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv0'[2,`c'])^2 if `sexe'==0&`age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv0'[3,`c'])^2 if `sexe'==0&`age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv0'[4,`c'])^2 if `sexe'==0&`age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv0'[5,`c'])^2 if `sexe'==0&`age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv0'[6,`c'])^2 if `sexe'==0&`age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv0'[7,`c'])^2 if `sexe'==0&`age'>=75 + qui replace `scoreref`i'v'=(`scorerefv1'[1,`c'])^2 if `sexe'==1&`age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv1'[2,`c'])^2 if `sexe'==1&`age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv1'[3,`c'])^2 if `sexe'==1&`age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv1'[4,`c'])^2 if `sexe'==1&`age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv1'[5,`c'])^2 if `sexe'==1&`age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv1'[6,`c'])^2 if `sexe'==1&`age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv1'[7,`c'])^2 if `sexe'==1&`age'>=75 + local ++c + } +} +else if "`age'"!=""&"`sexe'"=="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref01'[1,`c'] if `age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref01'[2,`c'] if `age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref01'[3,`c'] if `age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref01'[4,`c'] if `age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref01'[5,`c'] if `age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref01'[6,`c'] if `age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref01'[7,`c'] if `age'>=75 + qui gen `scoreref`i'v'=(`scorerefv01'[1,`c'])^2 if `age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv01'[2,`c'])^2 if `age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv01'[3,`c'])^2 if `age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv01'[4,`c'])^2 if `age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv01'[5,`c'])^2 if `age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv01'[6,`c'])^2 if `age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv01'[7,`c'])^2 if `age'>=75 + local ++c + } +} +else if "`age'"==""&"`sexe'"!="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref'[2,`c'] if `sexe'==1 + qui replace `scoreref`i''=`scoreref'[3,`c'] if `sexe'==0 + qui gen `scoreref`i'v'=(`scorerefv'[2,`c'])^2 if `sexe'==1 + qui replace `scoreref`i'v'=(`scorerefv'[3,`c'])^2 if `sexe'==0 + local ++c + } +} +else if "`age'"==""&"`sexe'"=="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + gen `scoreref`i''=`scoreref'[1,`c'] + gen `scoreref`i'v'=(`scorerefv'[1,`c'])^2 + local ++c + } +} +tempname scorerefpfz scorerefrpz scorerefbpz scorerefghz scorerefvtz scorerefsfz scorerefrez scorerefmhz scorerefpcs scorerefmcs +tempname scorerefpfvz scorerefrpvz scorerefbpvz scorerefghvz scorerefvtvz scorerefsfvz scorerefrevz scorerefmhvz scorerefpcsv scorerefmcsv + +qui gen `scorerefpfz'=(`scorerefpf'-84.52404)/22.89490 +qui gen `scorerefrpz'=(`scorerefrp'-81.19907)/33.79729 +qui gen `scorerefbpz'=(`scorerefbp'-75.49196)/23.55879 +qui gen `scorerefghz'=(`scorerefgh'-72.21316)/20.16964 +qui gen `scorerefvtz'=(`scorerefvt'-61.05453)/20.86942 +qui gen `scorerefsfz'=(`scorerefsf'-83.59753)/22.37649 +qui gen `scorerefrez'=(`scorerefre'-81.29467)/33.02717 +qui gen `scorerefmhz'=(`scorerefmh'-74.84212)/18.01189 +qui gen `scorerefpcs'=(`scorerefpfz'*0.42402+`scorerefrpz'*0.35119+`scorerefbpz'*0.31754+`scorerefghz'*0.24954+`scorerefvtz'*0.02877-`scorerefsfz'*0.0753-`scorerefrez'*0.19206-`scorerefmhz'*0.22069)*10+50 +qui gen `scorerefmcs'=(-`scorerefpfz'*0.22999-`scorerefrpz'*0.12329-`scorerefbpz'*0.09731-`scorerefghz'*0.01571+`scorerefvtz'*0.23534+`scorerefsfz'*0.26876+`scorerefrez'*0.43407+`scorerefmhz'*0.48581)*10+50 + +qui gen `scorerefpfvz'=(`scorerefpfv')/22.89490^2 +qui gen `scorerefrpvz'=(`scorerefrpv')/33.79729^2 +qui gen `scorerefbpvz'=(`scorerefbpv')/23.55879^2 +qui gen `scorerefghvz'=(`scorerefghv')/20.16964^2 +qui gen `scorerefvtvz'=(`scorerefvtv')/20.86942^2 +qui gen `scorerefsfvz'=(`scorerefsfv')/22.37649^2 +qui gen `scorerefrevz'=(`scorerefrev')/33.02717^2 +qui gen `scorerefmhvz'=(`scorerefmhv')/18.01189^2 +qui gen `scorerefpcsv'=(`scorerefpfvz'*0.42402^2+`scorerefrpvz'*0.35119^2+`scorerefbpvz'*0.31754^2+`scorerefghvz'*0.24954^2+`scorerefvtvz'*0.02877^2-`scorerefsfvz'*0.0753^2-`scorerefrevz'*0.19206^2-`scorerefmhvz'*0.22069^2)*10^2 +qui gen `scorerefmcsv'=(-`scorerefpfvz'*0.22999^2-`scorerefrpvz'*0.12329^2-`scorerefbpvz'*0.09731^2-`scorerefghvz'*0.01571^2+`scorerefvtvz'*0.23534^2+`scorerefsfvz'*0.26876^2+`scorerefrevz'*0.43407^2+`scorerefmhvz'*0.48581^2)*10^2 + + + + + +if "`saveref'"!="" { + local listmin pf rp bp gh vt sf re mh pcs mcs + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local error=0 + local list + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `saveref'`i' + if _rc==0&"`replace'"=="" { + local ++error + local list "`list' `saveref'`j'" + } + local ++c + } + local c=1 + if `error'==0 { + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `saveref'`i' + if _rc==0 { + qui replace `saveref'`i'=`scoreref`i'' + } + else { + qui gen `saveref'`i'=`scoreref`i'' + } + local ++c + } + } + else { + di in red "The variable(s) `list' already exist(s)" + } +} + +if "`details'"!=""|"`radar'"!="" { + tempname radar + qui matrix `radar'=J(12,2,.) + if "`details'"!="" { + di "{hline 80}" + di in gr _col(12) "Sample" _col(51) "Reference" + di in gr "Dimension" _col(16) "N" _col(21) "Mean" _col(29) "s.d." _col(40) "Min-Max" _col(52) "Mean" _col(60) "s.d." _col(72) "p" + di "{hline 80}" + } + local listmin pf rp bp gh vt sf re mh pcs mcs sf12p sf12m + local listmaj PF RP BP GH VT SF RE MH PCS MCS SF12P SF12M + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + qui su `score`i'' + local means`i'=r(mean) + local sds`i'=r(sd) + local mins`i'=r(min) + local maxs`i'=r(max) + local n`i'=r(N) + matrix `radar'[`c',1]=`means`i'' + qui su `scoreref`i'' + matrix `radar'[`c',2]=r(mean) + if "`i'"!="sf12p"&"`i'"!="sf12m" { + qui su `scoreref`i'' if `score`i''!=. + local meanr`i'=r(mean) + local sdr`i'=r(sd) + local vr`i'=(`sdr`i'')^2 + qui su `scoreref`i'v' if `score`i''!=. + local meanvr`i'=r(mean) + local sdr`i'=sqrt(`vr`i''+`meanvr`i'') + *local minr`i'=r(min) + *local maxr`i'=r(max) + qui ttest `score`i''=`meanr`i'' + local p`i'=r(p) + } + if "`details'"!="" { + di in gr "`j'" in ye _col(12) %5.0f `n`i'' _col(20) %5.2f `means`i'' _col(28) %5.2f `sds`i'' _col(34) %6.2f `mins`i'' "-" %6.2f `maxs`i'' _col(51) %5.2f `meanr`i'' _col(59) %5.2f `sdr`i'' _col(67) %6.4f `p`i'' + } + local ++c + } + if "`details'"!="" { + di "{hline 80}" + } + *corr `scorepcs' `scoremcs' `scoresf12p' `scoresf12m' + *scatter `scorepcs' `scoresf12p' ,name(p) + *scatter `scoremcs' `scoresf12m' ,name(m) + *su `scoresf12p' `sf12p_1' `sf12p_2a' `sf12p_2b' `sf12p_3a' `sf12p_3b' `sf12p_4a' `sf12p_4b' `sf12p_5' `sf12p_6' `sf12p_7a' `sf12p_7b' `sf12p_7c' + *su `scoresf12m' `sf12m_1' `sf12m_2a' `sf12m_2b' `sf12m_3a' `sf12m_3b' `sf12m_4a' `sf12m_4b' `sf12m_5' `sf12m_6' `sf12m_7a' `sf12m_7b' `sf12m_7c' + if "`radar'"!=""&"`v2'"=="" { + qui tempfile radarfile + qui save `radarfile', replace + qui drop _all + qui svmat `radar' + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local c=1 + qui gen name="" + foreach i in `listmin' { + qui replace name="`i'" in `c' + local ++c + } + qui rename `radar'1 scoreSF36 + rename `radar'2 scoreSF36ref + qui keep in 1/10 + label variable scoreSF36 "Sample" + label variable scoreSF36ref "General French population" + if "`filesave'"!="" { + if "`dirsave'"=="" { + local dirsave `c(pwd)' + } + local saving "saving(`dirsave'//radar, replace) " + } + qui radar name scoreSF36 scoreSF36ref, note("") title("Comparison of the sample with the general French population") legend(lab(1 "Sample") lab(2 "General French population")) `saving' r(0 20 40 60 80 100) + qui use `radarfile', clear + } +} +if "`saveimp'"!="" { +*su + foreach i of numlist 1 3/36 { + local j:word `i' of `varlistsav' + *di "gen `saveimp'`j'=`imp'``i''" + capture confirm variable `saveimp'`j' + if _rc==0&"`replace'"=="" { + di in ye "The variable `saveimp'`j' already exists and cannot be replaced." + } + else if _rc==0&"`replace'"!="" { + qui replace `saveimp'`j'=`imp'``i'' + } + else { + qui gen `saveimp'`j'=`imp'``i'' + } + } +} +*restore, preserve +end diff --git a/Modules/ado/personal/s/sf36fr.hlp b/Modules/ado/personal/s/sf36fr.hlp new file mode 100644 index 0000000..a7c8239 --- /dev/null +++ b/Modules/ado/personal/s/sf36fr.hlp @@ -0,0 +1,60 @@ +{smcl} +{* 5May2013}{...} +{hline} +help for {hi:sf36fr}{right:Jean-Benoit Hardouin} +{hline} + +{title:Computation of the score of the French SF36 questionnaire} + +{p 8 14 2}{cmd:sf36fr} {it:varlist} [{it:if}] [,{cmdab:v2} {cmd:save}({it:prefix}) {cmd:saveref}({it:prefix}) {cmd:saveimp}({it:prefix}) {cmdab:rep:lace} {cmd:age}({it:varname}) {cmdab:sex}({it:varname}) {cmdab:det:ails}] + + +{title:Description} + +{p 4 4 2}{cmd:sf36fr} computes the scores of the French versions of the SF36 questionnaire based on the algorithm of the version 1.3. By default, version 1.3 of the questionnaire is assumed. +For data provided using the version 2 of the SF36 questionnaire, this algorithm is adapted. + +{title:Options} + +{p 4 8 2}{it:varlist} must contain the name of the 36 variables representing the 36 items of the questionnaire in the same order than in the questionnaire. + +{p 4 8 2}{cmd:v2} is required if the version 2 of the SF36 questionnaire is used. + +{p 4 8 2}{cmd:save}({it:prefix}) saves the scores in new variables. The names of this variable are {it:prefix} followed by the names of the dimensions (PF RP BP GH VT SF RE MH PCS MCS). + +{p 4 8 2}{cmd:saveref}({it:prefix}) saves the scores of reference in new variables. The names of this variable are {it:prefix} followed by the names of the dimensions (PF RP BP GH VT SF RE MH PCS MCS). + +{p 4 8 2}{cmd:saveimp}({it:prefix}) saves the imputed values of each items in variables using the string as prefix followed the name of each items. + +{p 4 8 2}{cmdab:rep:lace} allows replacing the variables defined with the {cmd:save} and {cmd:saveref} options if required. + +{p 4 8 2}{cmd:age}({it:varname}) and {cmd:sex}({it:varname}) define the age and sex of the individuals in order to compute more precisely the scores of reference. + +{p 4 8 2}{cmdab:det:ails} displays tables of incoherencs and comparison between computed scores and scores of reference. + + +{title:Example} + + {cmd:. sf36fr sf36_1 - sf36_11d} + + {cmd:. sf36fr sf36_1 - sf36_11d, v2 save(score) details replace} + + {cmd:. sf36fr sf36_1 - sf36_11d, v2 save(score) details saveref(scoreref) age(age) sex(sexe)} + + +{title:Reference} + +{p 4 8 2}{cmd:Leplège A, Ecosse E, Pouchot J, Coste J, Perneger T} (2001). Le questionnaire MOS-SF36 - Manuel de l'utilisateur et guide d'interprétation des scores. Estem: Paris. + + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end} +{p 4 8 2}EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"{p_end} +{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end} +{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end} +{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end} +{p 4 8 2}Email: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 4 8 2}Website {browse "http://www.anaqol.org":AnaQol} + diff --git a/Modules/ado/personal/s/sf36fr.zip b/Modules/ado/personal/s/sf36fr.zip new file mode 100644 index 0000000..3b360b8 Binary files /dev/null and b/Modules/ado/personal/s/sf36fr.zip differ diff --git a/Modules/ado/personal/s/sf36fr1.4.ado b/Modules/ado/personal/s/sf36fr1.4.ado new file mode 100644 index 0000000..03a7f2b --- /dev/null +++ b/Modules/ado/personal/s/sf36fr1.4.ado @@ -0,0 +1,550 @@ +*! Version 1.4 1 December 2018 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : sf36fr +* computes score of the French SF36 questionnnaire +* Release 1 : May 2, 2013 [Jean-benoit Hardouin] +* Release 1.1 : May 14, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/ +* Release 1.2 : May 21, 2013 [Jean-Benoit Hardouin] /*saveimp option*/ +* Release 1.3 : May 24, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/ +* Release 1.4 : December 1, 2018 [Jean-Benoit Hardouin] /*correction of a bug on SF12*/ +* +* +* Historic : +* Version 1 (May 2, 2013) [Jean-Benoit Hardouin] +* +* Faire sauvegarde des items imputés +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* News about this program :http://www.anaqol.org +* +* Copyright 2013 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** +program define sf36fr , rclass +version 8.2 +syntax varlist(min=36 max=36 numeric) [,v2 save(string) REPlace age(varname) SEXe(varname) saveref(string) DETails saveimp(string)] + +local nbitems : word count `varlist' +if `nbitems'!=36 { + di in red "There is `nbitems' items defined instead of 36" +} + +tokenize `varlist' +local varlistsav `varlist' +local sf gh1 ht pf1 pf2 pf3 pf4 pf5 pf6 pf7 pf8 pf9 pf10 rp1 rp2 rp3 rp4 re1 re2 re3 sf1 bp1 bp2 vt1 mh1 mh2 mh3 vt2 mh4 vt3 mh5 vt4 sf2 gh2 gh3 gh4 gh5 +local sf2 +local varlist2 +forvalues i=1/36 { + local j:word `i' of `sf' + tempname `j' + *di " qui gen `j'=``i''" + qui gen ``j''=``i'' + local varlist2 "`varlist2' ``j''" +} +local varlist "`varlist2'" +tokenize `varlist' +*di "`varlist'" + + +if "`v2'"=="" { + local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 5 6 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5 +} +else { + local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 +} +forvalues i=1/36 { + local mod`i':word `i' of `modamax' +} +local error=0 +local inf +local sup +local c=1 +foreach i of varlist `varlist' { + qui count if `i'<1 + if `r(N)'>0 { + local error=1 + local inf "`inf' `i'" + } + local tmp: word `c' of `modamax' + qui count if `i'>`c' + if `r(N)'>0 { + local error=1 + local inf "`sup' `i'" + } + local ++c +} +forvalues i=1/15 { + tempname inc`i' +} +local liste1 11 12 11 12 11 12 11 12 30 24 27 23 1 20 21 +local liste2 3 3 4 4 6 6 9 9 25 26 29 31 36 32 22 +*tab `11' `3' +qui gen `inc1'=`11'==1&`3'>1 if `11'!=.&`3'!=. +* tab `inc`i'' +qui gen `inc2'=`12'==1&`3'>1 if `12'!=.&`3'!=. +qui gen `inc3'=`11'==1&`4'>1 if `11'!=.&`4'!=. +qui gen `inc4'=`12'==1&`4'>1 if `12'!=.&`4'!=. +qui gen `inc5'=`11'==1&`6'>1 if `11'!=.&`6'!=. +qui gen `inc6'=`12'==1&`6'>1 if `12'!=.&`6'!=. +qui gen `inc7'=`11'==1&`9'>1 if `11'!=.&`9'!=. +qui gen `inc8'=`12'==1&`9'>1 if `12'!=.&`9'!=. +qui gen `inc9'=(`30'==1&`25'==1)|(`30'==`mod30'&`25'==`mod25') if `30'!=.&`25'!=. +qui gen `inc10'=(`24'==1&`26'==1)|(`24'==`mod24'&`26'==`mod26') if `24'!=.&`26'!=. +qui gen `inc11'=(`27'==1&`29'==1)|(`27'==`mod27'&`29'==`mod29') if `27'!=.&`29'!=. +qui gen `inc12'=(`23'==1&`31'==1)|(`23'==`mod23'&`31'==`mod31') if `23'!=.&`31'!=. +qui gen `inc13'=(`1'==1&`36'==`mod36')|(`1'==`mod1'&`36'==1) if `1'!=.&`36'!=. +qui gen `inc14'=(`20'==1&`32'==1)|(`20'==`mod20'&`32'==`mod32') if `20'!=.&`32'!=. +qui gen `inc15'=(`21'==1&`22'==`mod22')|(`21'==`mod21'&`22'==1) if `21'!=.&`22'!=. +tempname scoreinc +genscore `inc1'-`inc15',score(`scoreinc') +if "`details'" !="" { + di "{hline 80}" + di in gr "Incoherences" _col(20) "item 1" _col(40) "item 2" _col(60) "# individuals" + di "{hline 80}" + *di "varlist:`varlistsav'" + forvalues i=1/15 { + local i1:word `i' of `liste1' + local i2:word `i' of `liste2' + local ni1:word `i1' of `varlistsav' + local ni2:word `i2' of `varlistsav' + qui count if `inc`i''==1 + + di in gr "`i'" in ye _col(20) abbrev("`ni1'",19) _col(40) abbrev("`ni2'",19) %6.0f _col(67) `r(N)' + } + di "{hline 80}" +} + +forvalues i=1/15 { + local i1:word `i' of `liste1' + local i2:word `i' of `liste2' + qui replace ``i1''=. if `inc`i''==1 + qui replace ``i2''=. if `inc`i''==1 +} + +tempname imp scorepf scorerp scorebp scoregh scorevt scoresf scorere scoremh + + /*PF*/ + imputeitems `3' `4' `5' `6' `7' `8' `9' `10' `11' `12',max(4) noround prefix(`imp') + genscore `imp'`3' `imp'`4' `imp'`5' `imp'`6' `imp'`7' `imp'`8' `imp'`9' `imp'`10' `imp'`11' `imp'`12',score(`scorepf') + qui replace `scorepf'=(`scorepf'-10)/20*100 + /*RP*/ + imputeitems `13' `14' `15' `16',max(1) noround prefix(`imp') + genscore `imp'`13' `imp'`14' `imp'`15' `imp'`16',score(`scorerp') + qui replace `scorerp'=(`scorerp'-4)/4*100 + /*BP*/ + tempvar jb + qui gen `jb'=. + qui replace `jb'=6 if `21'==1&`22'==1 + qui replace `jb'=5 if `21'>=2&`21'<=6&`22'==1 + qui replace `jb'=4 if `22'==2&`21'!=. + qui replace `jb'=3 if `22'==3&`21'!=. + qui replace `jb'=2 if `22'==4&`21'!=. + qui replace `jb'=1 if `22'==5&`21'!=. + qui replace `jb'=6 if `22'==1&`21'==. + qui replace `jb'=4.75 if `22'==2&`21'==. + qui replace `jb'=3.5 if `22'==3&`21'==. + qui replace `jb'=2.25 if `22'==4&`21'==. + qui replace `jb'=1 if `22'==5&`21'==. + qui replace `22'=`jb' + if "`v2'"=="" { + qui recode `21' 1=6 2=5.4 3=4.2 4=3.1 5=2.2 6=1 + } + else { + qui recode `21' 1=6 2=4.8 3=2.65 4=1 + } + imputeitems `21' `22',max(0) noround prefix(`imp') +* replace `imp'`21'=`21' +* replace `imp'`22'=`22' + qui genscore `imp'`21' `imp'`22',score(`scorebp') +* list sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques `21' `22' `imp'`21' `imp'`22' `scorebp' + qui replace `scorebp'=(`scorebp'-2)/10*100 +*tab `scorebp' + /*GH*/ + qui recode `1' 1=5 2=4.4 3=3.4 4=2 5=1 + qui recode `34' 1=5 2=4 3=3 4=2 5=1 + qui recode `36' 1=5 2=4 3=3 4=2 5=1 + imputeitems `1' `33' `34' `35' `36',max(2) noround prefix(`imp') + genscore `imp'`1' `imp'`33' `imp'`34' `imp'`35' `imp'`36',score(`scoregh') + qui replace `scoregh'=(`scoregh'-5)/20*100 + /*VT*/ + if "`v2'"=="" { + qui recode `23' 1=6 2=5 3=4 4=3 5=2 6=1 + qui recode `27' 1=6 2=5 3=4 4=3 5=2 6=1 + } + else { + qui recode `23' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `27' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `29' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `31' 1=1 2=2 3=3.5 4=4.5 5=6 + } + imputeitems `23' `27' `29' `31',max(1) noround prefix(`imp') + genscore `imp'`23' `imp'`27' `imp'`29' `imp'`31',score(`scorevt') + qui replace `scorevt'=(`scorevt'-4)/20*100 + /*SF*/ + if "`v2'"=="" { + qui recode `20' 1=5 2=4 3=3 4=2 5=1 + } + else { + qui recode `20' 1=5 2=4 3=2.5 4=1 + } + imputeitems `20' `32',max(0) noround prefix(`imp') + genscore `imp'`20' `imp'`32',score(`scoresf') + qui replace `scoresf'=(`scoresf'-2)/8*100 + /*RE*/ + imputeitems `17' `18' `19',max(1) noround prefix(`imp') + genscore `imp'`17' `imp'`18' `imp'`19',score(`scorere') + qui replace `scorere'=(`scorere'-3)/3*100 + /*MH*/ + if "`v2'"=="" { + qui recode `26' 1=6 2=5 3=4 4=3 5=2 6=1 + qui recode `30' 1=6 2=5 3=4 4=3 5=2 6=1 + } + else { + qui recode `26' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `30' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `24' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `25' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `28' 1=1 2=2 3=3.5 4=4.5 5=6 + } + imputeitems `24' `25' `26' `28' `30',max(2) noround prefix(`imp') + genscore `imp'`24' `imp'`25' `imp'`26' `imp'`28' `imp'`30',score(`scoremh') + qui replace `scoremh'=(`scoremh'-5)/25*100 + tempname scorepfz scorerpz scorebpz scoreghz scorevtz scoresfz scorerez scoremhz scorepcs scoremcs + + /*scores composites*/ + qui gen `scorepfz'=(`scorepf'-84.52404)/22.89490 + qui gen `scorerpz'=(`scorerp'-81.19907)/33.79729 + qui gen `scorebpz'=(`scorebp'-75.49196)/23.55879 + qui gen `scoreghz'=(`scoregh'-72.21316)/20.16964 + qui gen `scorevtz'=(`scorevt'-61.05453)/20.86942 + qui gen `scoresfz'=(`scoresf'-83.59753)/22.37649 + qui gen `scorerez'=(`scorere'-81.29467)/33.02717 + qui gen `scoremhz'=(`scoremh'-74.84212)/18.01189 + qui gen `scorepcs'=(`scorepfz'*0.42402+`scorerpz'*0.35119+`scorebpz'*0.31754+`scoreghz'*0.24954+`scorevtz'*0.02877-`scoresfz'*0.0753-`scorerez'*0.19206-`scoremhz'*0.22069)*10+50 + qui gen `scoremcs'=(-`scorepfz'*0.22999-`scorerpz'*0.12329-`scorebpz'*0.09731-`scoreghz'*0.01571+`scorevtz'*0.23534+`scoresfz'*0.26876+`scorerez'*0.43407+`scoremhz'*0.48581)*10+50 + + +/*scores composites SF12*/ +tempname scoresf12p sf12p_1 sf12p_2a sf12p_2b sf12p_3a sf12p_3b sf12p_4a sf12p_4b sf12p_5 sf12p_6 sf12p_7a sf12p_7b sf12p_7c +tempname scoresf12m sf12m_1 sf12m_2a sf12m_2b sf12m_3a sf12m_3b sf12m_4a sf12m_4b sf12m_5 sf12m_6 sf12m_7a sf12m_7b sf12m_7c + qui gen `sf12p_1'=`1' + qui gen `sf12p_2a'=`4' + qui gen `sf12p_2b'=`6' + qui gen `sf12p_3a'=`14' + qui gen `sf12p_3b'=`15' + qui gen `sf12p_4a'=`18' + qui gen `sf12p_4b'=`19' + qui gen `sf12p_5'=`20' + qui gen `sf12p_6'=`32' + qui gen `sf12p_7a'=`26' + qui gen `sf12p_7b'=`27' + qui gen `sf12p_7c'=`28' + qui gen `sf12m_1'=`1' + qui gen `sf12m_2a'=`4' + qui gen `sf12m_2b'=`6' + qui gen `sf12m_3a'=`14' + qui gen `sf12m_3b'=`15' + qui gen `sf12m_4a'=`18' + qui gen `sf12m_4b'=`19' + qui gen `sf12m_5'=`20' + qui gen `sf12m_6'=`32' + qui gen `sf12m_7a'=`26' + qui gen `sf12m_7b'=`27' + qui gen `sf12m_7c'=`28' + qui recode `sf12p_1' 5=0 4.4=-1.31872 3.4=-3.02396 2=-5.56461 1=-8.37399 + qui recode `sf12m_1' 5=0 4.4=-0.06064 3.4=0.03482 2=-0.16891 1=-1.71175 + qui recode `sf12p_2a' 1=-7.23216 2=-3.45555 3=0 + qui recode `sf12m_2a' 1=3.93115 2=1.86840 3=0 + qui recode `sf12p_2b' 1=-6.24397 2=-2.73557 3=0 + qui recode `sf12m_2b' 1=2.68282 2=1.43103 3=0 + qui recode `sf12p_3a' 1=-4.61617 2=0 + qui recode `sf12m_3a' 1=1.44060 2=0 + qui recode `sf12p_3b' 1=-5.51747 2=0 + qui recode `sf12m_3b' 1=1.66968 2=0 + qui recode `sf12p_4a' 1=3.04365 2=0 + qui recode `sf12m_4a' 1=-6.82672 2=0 + qui recode `sf12p_4b' 1=2.32091 2=0 + qui recode `sf12m_4b' 1=-5.69921 2=0 + qui recode `sf12p_6' 1=-0.33682 2=-0.94342 3=-0.18043 4=0.11038 5=0 + qui recode `sf12m_6' 1=-6.29724 2=-8.26066 3=-5.63286 4=-3.13896 5=0 + if "`v2'"=="" { + qui recode `sf12p_5' 5=0 4=-3.80130 3=-6.50522 2=-8.38063 1=-11.25544 + qui recode `sf12m_5' 5=0 4=0.90384 3=1.49384 2=1.76691 1=1.48619 + qui recode `sf12p_7a' 6=0 5=0.66514 4=1.36689 3=2.37241 2=2.90426 1=3.46638 + qui recode `sf12m_7a' 6=0 5=-1.94949 4=-4.09842 3=-6.31121 2=-7.92717 1=-10.19085 + qui recode `sf12p_7b' 6=0 5=-0.42251 4=-1.14387 3=-1.61850 2=-2.02168 1=-2.44706 + qui recode `sf12m_7b' 6=0 5=-0.92057 4=-1.65178 3=-3.29805 2=-4.88962 1=-6.02409 + qui recode `sf12p_7c' 1=4.61446 2=3.41593 3=2.34247 4=1.28044 5=0.41188 6=0 + qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3=-8.09914 4=-4.59055 5=-1.95934 6=0 + } + else { + qui recode `sf12p_5' 5=0 4=-3.83130 2.5=-7.442925 1=-11.25544 + qui recode `sf12m_5' 5=0 4=0.90384 2.5=1.630375 1=1.48619 + qui recode `sf12p_7a' 6=0 4.5=1.016015 3.5=1.86965 2=2.90426 1=3.46638 + qui recode `sf12m_7a' 6=0 4.5=-3.023955 3.5=-5.204815 2=-7.92717 1=-10.19085 + qui recode `sf12p_7b' 6=0 4.5=-0.78319 3.5=-1.381185 2=-2.02168 1=-2.44706 + qui recode `sf12m_7b' 6=0 4.5=-1.286175 3.5=-2.474915 2=-4.88962 1=-6.02409 + qui recode `sf12p_7c' 1=4.61446 2=3.41593 3.5=1.811455 4.5=0.84616 6=0 + qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3.5=-6.344845 4.5=-3.274945 6=0 + } + qui gen `scoresf12p'=`sf12p_1'+`sf12p_2a'+`sf12p_2b'+`sf12p_3a'+`sf12p_3b'+`sf12p_4a'+`sf12p_4b'+`sf12p_5'+`sf12p_6'+`sf12p_7a'+`sf12p_7b'+`sf12p_7c'+56.57706 + qui gen `scoresf12m'=`sf12m_1'+`sf12m_2a'+`sf12m_2b'+`sf12m_3a'+`sf12m_3b'+`sf12m_4a'+`sf12m_4b'+`sf12m_5'+`sf12m_6'+`sf12m_7a'+`sf12m_7b'+`sf12m_7c'+60.75781 + +if "`save'"!="" { + local listmin pf rp bp gh vt sf re mh pcs mcs + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local error=0 + local list + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `save'`i' + if _rc==0&"`replace'"=="" { + local ++error + local list "`list' `save'`j'" + } + local ++c + } + local c=1 + if `error'==0 { + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `save'`i' + if _rc==0 { + qui replace `save'`i'=`score`i'' + } + else { + qui gen `save'`i'=`score`i'' + } + local ++c + } + } + else { + di in red "The variable(s) `list' already exist(s)" + } +} +tempname scoreref1 scoreref0 scoreref01 scoreref scorerefv1 scorerefv0 scorerefv01 scorerefv +matrix `scoreref1'=(96.65,95.80,86.82,82.36,67.86,89.76,93.14,72.85\95.75,91.16,83.60,76.07,64.50,86.50,90.64,72.08\94.41,90.76,81.03,73.13,64.32,86.37,89.07,71.01\92.27,88.64,79.02,72.27,66.06,86.69,90.00,71.53\82.32,79.81,70.21,65.97,60.19,83.33,83.00,71.10\76.58,74.74,67.10,62.37,58.21,79.74,80.04,71.16\67.16,61.28,63.99,58.61,53.93,76.16,66.67,70.24) +matrix `scoreref0'=(94.92,89.54,79.37,71.81,60.32,79.65,81.65,64.92\92.42,85.98,80.19,75.10,60.57,82.83,86.13,68.18\91.04,88.87,78.27,74.64,61.94,84.14,85.48,67.59\86.23,85.54,71.97,69.14,58.90,79.80,83.42,64.84\77.88,77.85,66.23,65.10,58.18,78.29,77.61,66.17\71.60,68.74,62.40,61.23,55.08,76.47,73.24,65.45\58.20,52.46,59.68,59.73,47.94,71.68,62.21,60.63) +matrix `scoreref01'=(95.65,92.18,82.51,76.26,63.52,83.93,86.47,68.29\93.93,88.34,81.75,75.54,62.35,84.51,88.19,69.94\92.71,89.80,79.63,73.89,63.12,85.24,87.26,69.28\89.25,87.09,75.50,70.70,62.48,83.24,86.71,68.19\79.99,78.78,68.12,65.51,59.14,80.69,80.19,68.52\73.69,71.24,64.37,61.71,56.39,77.84,76.05,67.84\62.40,56.67,61.72,59.20,50.86,73.80,64.38,65.29) +matrix `scoreref'=(84.45,81.21,73.39,69.13,59.96,81.55,82.13,68.47\87.07,83.86,75.98,70.07,62.23,84.08,85.41,71.42\82.22,78.96,71.18,68.33,58.03,79.41,79.34,65.96) +matrix `scorerefv1'=(11.78,15.33,17.21,13.93,14.16,14.43,20.73,15.28\9.64,21.30,19.63,15.89,16.72,19.05,24.18,15.83\11.08,23.63,21.00,16.20,16.65,18.97,26.12,16.70\14.92,26.35,22.09,17.41,16.24,17.01,23.15,16.23\20.48,32.67,22.24,17.93,16.89,20.35,32.04,17.40\22.78,36.05,24.06,19.08,18.03,21.94,33.89,16.60\27.44,40.86,24.38,17.61,18.86,24.08,41.43,20.03) +matrix `scorerefv0'=(9.10,21.65,21.66,17.69,18.10,22.35,29.58,17.32\14.19,28.28,21.28,16.66,18.28,20.57,28.19,18.06\14.81,25.19,21.25,17.64,18.55,20.97,29.37,17.92\19.11,29.40,23.90,18.60,17.84,21.44,31.24,16.66\21.49,33.02,24.10,18.78,18.22,23.46,34.89,18.03\23.42,38.17,23.94,17.67,17.59,22.46,37.41,18.21\25.70,39.18,23.40,18.08,17.98,24.06,39.97,18.98) +matrix `scorerefv01'=(10.33,19.46,20.21,17.00,16.94,20.00,26.80,16.83\12.44,25.45,20.60,16.31,17.69,19.96,16.51,17.18\13.19,24.43,21.15,16.95,17.66,20.02,27.85,17.40\17.39,27.92,23.25,18.06,17.41,19.64,27.65,16.76\21.11,32.83,23.29,18.37,17.61,22.16,33.63,17.88\23.27,37.40,24.09,18.28,17.83,22.29,36.13,17.77\26.85,40.16,23.92,17.83,18.62,24.13,40.67,20.04) +matrix `scorerefv'=(21.19,32.20,23.73,18.57,18.05,21.41,32.15,17.62\19.85,30.48,23.03,18.39,17.36,20.08,29.89,16.70\22.02,33.43,24.10,18.69,18.40,22.26,33.71,17.99) + +tempname scorerefpf scorerefrp scorerefbp scorerefgh scorerefvt scorerefsf scorerefre scorerefmh +tempname scorerefpfv scorerefrpv scorerefbpv scorerefghv scorerefvtv scorerefsfv scorerefrev scorerefmhv +if "`age'"!=""&"`sexe'"!="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref0'[1,`c'] if `sexe'==0&`age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref0'[2,`c'] if `sexe'==0&`age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref0'[3,`c'] if `sexe'==0&`age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref0'[4,`c'] if `sexe'==0&`age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref0'[5,`c'] if `sexe'==0&`age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref0'[6,`c'] if `sexe'==0&`age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref0'[7,`c'] if `sexe'==0&`age'>=75 + qui replace `scoreref`i''=`scoreref1'[1,`c'] if `sexe'==1&`age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref1'[2,`c'] if `sexe'==1&`age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref1'[3,`c'] if `sexe'==1&`age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref1'[4,`c'] if `sexe'==1&`age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref1'[5,`c'] if `sexe'==1&`age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref1'[6,`c'] if `sexe'==1&`age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref1'[7,`c'] if `sexe'==1&`age'>=75 + qui gen `scoreref`i'v'=(`scorerefv0'[1,`c'])^2 if `sexe'==0&`age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv0'[2,`c'])^2 if `sexe'==0&`age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv0'[3,`c'])^2 if `sexe'==0&`age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv0'[4,`c'])^2 if `sexe'==0&`age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv0'[5,`c'])^2 if `sexe'==0&`age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv0'[6,`c'])^2 if `sexe'==0&`age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv0'[7,`c'])^2 if `sexe'==0&`age'>=75 + qui replace `scoreref`i'v'=(`scorerefv1'[1,`c'])^2 if `sexe'==1&`age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv1'[2,`c'])^2 if `sexe'==1&`age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv1'[3,`c'])^2 if `sexe'==1&`age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv1'[4,`c'])^2 if `sexe'==1&`age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv1'[5,`c'])^2 if `sexe'==1&`age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv1'[6,`c'])^2 if `sexe'==1&`age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv1'[7,`c'])^2 if `sexe'==1&`age'>=75 + local ++c + } +} +else if "`age'"!=""&"`sexe'"=="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref01'[1,`c'] if `age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref01'[2,`c'] if `age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref01'[3,`c'] if `age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref01'[4,`c'] if `age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref01'[5,`c'] if `age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref01'[6,`c'] if `age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref01'[7,`c'] if `age'>=75 + qui gen `scoreref`i'v'=(`scorerefv01'[1,`c'])^2 if `age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv01'[2,`c'])^2 if `age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv01'[3,`c'])^2 if `age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv01'[4,`c'])^2 if `age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv01'[5,`c'])^2 if `age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv01'[6,`c'])^2 if `age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv01'[7,`c'])^2 if `age'>=75 + local ++c + } +} +else if "`age'"==""&"`sexe'"!="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref'[2,`c'] if `sexe'==1 + qui replace `scoreref`i''=`scoreref'[3,`c'] if `sexe'==0 + qui gen `scoreref`i'v'=(`scorerefv'[2,`c'])^2 if `sexe'==1 + qui replace `scoreref`i'v'=(`scorerefv'[3,`c'])^2 if `sexe'==0 + local ++c + } +} +else if "`age'"==""&"`sexe'"=="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + gen `scoreref`i''=`scoreref'[1,`c'] + gen `scoreref`i'v'=(`scorerefv'[1,`c'])^2 + local ++c + } +} +tempname scorerefpfz scorerefrpz scorerefbpz scorerefghz scorerefvtz scorerefsfz scorerefrez scorerefmhz scorerefpcs scorerefmcs +tempname scorerefpfvz scorerefrpvz scorerefbpvz scorerefghvz scorerefvtvz scorerefsfvz scorerefrevz scorerefmhvz scorerefpcsv scorerefmcsv + +qui gen `scorerefpfz'=(`scorerefpf'-84.52404)/22.89490 +qui gen `scorerefrpz'=(`scorerefrp'-81.19907)/33.79729 +qui gen `scorerefbpz'=(`scorerefbp'-75.49196)/23.55879 +qui gen `scorerefghz'=(`scorerefgh'-72.21316)/20.16964 +qui gen `scorerefvtz'=(`scorerefvt'-61.05453)/20.86942 +qui gen `scorerefsfz'=(`scorerefsf'-83.59753)/22.37649 +qui gen `scorerefrez'=(`scorerefre'-81.29467)/33.02717 +qui gen `scorerefmhz'=(`scorerefmh'-74.84212)/18.01189 +qui gen `scorerefpcs'=(`scorerefpfz'*0.42402+`scorerefrpz'*0.35119+`scorerefbpz'*0.31754+`scorerefghz'*0.24954+`scorerefvtz'*0.02877-`scorerefsfz'*0.0753-`scorerefrez'*0.19206-`scorerefmhz'*0.22069)*10+50 +qui gen `scorerefmcs'=(-`scorerefpfz'*0.22999-`scorerefrpz'*0.12329-`scorerefbpz'*0.09731-`scorerefghz'*0.01571+`scorerefvtz'*0.23534+`scorerefsfz'*0.26876+`scorerefrez'*0.43407+`scorerefmhz'*0.48581)*10+50 + +qui gen `scorerefpfvz'=(`scorerefpfv')/22.89490^2 +qui gen `scorerefrpvz'=(`scorerefrpv')/33.79729^2 +qui gen `scorerefbpvz'=(`scorerefbpv')/23.55879^2 +qui gen `scorerefghvz'=(`scorerefghv')/20.16964^2 +qui gen `scorerefvtvz'=(`scorerefvtv')/20.86942^2 +qui gen `scorerefsfvz'=(`scorerefsfv')/22.37649^2 +qui gen `scorerefrevz'=(`scorerefrev')/33.02717^2 +qui gen `scorerefmhvz'=(`scorerefmhv')/18.01189^2 +qui gen `scorerefpcsv'=(`scorerefpfvz'*0.42402^2+`scorerefrpvz'*0.35119^2+`scorerefbpvz'*0.31754^2+`scorerefghvz'*0.24954^2+`scorerefvtvz'*0.02877^2-`scorerefsfvz'*0.0753^2-`scorerefrevz'*0.19206^2-`scorerefmhvz'*0.22069^2)*10^2 +qui gen `scorerefmcsv'=(-`scorerefpfvz'*0.22999^2-`scorerefrpvz'*0.12329^2-`scorerefbpvz'*0.09731^2-`scorerefghvz'*0.01571^2+`scorerefvtvz'*0.23534^2+`scorerefsfvz'*0.26876^2+`scorerefrevz'*0.43407^2+`scorerefmhvz'*0.48581^2)*10^2 + + + + + +if "`saveref'"!="" { + local listmin pf rp bp gh vt sf re mh pcs mcs + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local error=0 + local list + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `saveref'`i' + if _rc==0&"`replace'"=="" { + local ++error + local list "`list' `saveref'`j'" + } + local ++c + } + local c=1 + if `error'==0 { + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `saveref'`i' + if _rc==0 { + qui replace `saveref'`i'=`scoreref`i'' + } + else { + qui gen `saveref'`i'=`scoreref`i'' + } + local ++c + } + } + else { + di in red "The variable(s) `list' already exist(s)" + } +} + +if "`details'"!="" { + di "{hline 80}" + di in gr _col(12) "Sample" _col(51) "Reference" + di in gr "Dimension" _col(16) "N" _col(21) "Mean" _col(29) "s.d." _col(40) "Min-Max" _col(52) "Mean" _col(60) "s.d." _col(72) "p" + di "{hline 80}" + local listmin pf rp bp gh vt sf re mh pcs mcs sf12p sf12m + local listmaj PF RP BP GH VT SF RE MH PCS MCS SF12P SF12M + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + qui su `score`i'' + local means`i'=r(mean) + local sds`i'=r(sd) + local mins`i'=r(min) + local maxs`i'=r(max) + local n`i'=r(N) + if "`i'"!="sf12p"&"`i'"!="sf12m" { + qui su `scoreref`i'' if `score`i''!=. + local meanr`i'=r(mean) + local sdr`i'=r(sd) + local vr`i'=(`sdr`i'')^2 + qui su `scoreref`i'v' if `score`i''!=. + local meanvr`i'=r(mean) + local sdr`i'=sqrt(`vr`i''+`meanvr`i'') + *local minr`i'=r(min) + *local maxr`i'=r(max) + qui ttest `score`i''=`meanr`i'' + local p`i'=r(p) + } + di in gr "`j'" in ye _col(12) %5.0f `n`i'' _col(20) %5.2f `means`i'' _col(28) %5.2f `sds`i'' _col(34) %6.2f `mins`i'' "-" %6.2f `maxs`i'' _col(51) %5.2f `meanr`i'' _col(59) %5.2f `sdr`i'' _col(67) %6.4f `p`i'' + local ++c + } + di "{hline 80}" + *corr `scorepcs' `scoremcs' `scoresf12p' `scoresf12m' + *scatter `scorepcs' `scoresf12p' ,name(p) + *scatter `scoremcs' `scoresf12m' ,name(m) + *su `scoresf12p' `sf12p_1' `sf12p_2a' `sf12p_2b' `sf12p_3a' `sf12p_3b' `sf12p_4a' `sf12p_4b' `sf12p_5' `sf12p_6' `sf12p_7a' `sf12p_7b' `sf12p_7c' + *su `scoresf12m' `sf12m_1' `sf12m_2a' `sf12m_2b' `sf12m_3a' `sf12m_3b' `sf12m_4a' `sf12m_4b' `sf12m_5' `sf12m_6' `sf12m_7a' `sf12m_7b' `sf12m_7c' + +} +if "`saveimp'"!="" { +*su + foreach i of numlist 1 3/36 { + local j:word `i' of `varlistsav' + *di "gen `saveimp'`j'=`imp'``i''" + capture confirm variable `saveimp'`j' + if _rc==0&"`replace'"=="" { + di in ye "The variable `saveimp'`j' already exists and cannot be replaced." + } + else if _rc==0&"`replace'"!="" { + qui replace `saveimp'`j'=`imp'``i'' + } + else { + qui gen `saveimp'`j'=`imp'``i'' + } + } +} +end diff --git a/Modules/ado/personal/s/sf36fr1.5.ado b/Modules/ado/personal/s/sf36fr1.5.ado new file mode 100644 index 0000000..09a64ed --- /dev/null +++ b/Modules/ado/personal/s/sf36fr1.5.ado @@ -0,0 +1,585 @@ +*! Version 1.5 29July2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : sf36fr +* computes score of the French SF36 questionnnaire +* +* +* Historic : +* Version 1 (May 2, 2013) [Jean-Benoit Hardouin] +* Release 1 : May 2, 2013 [Jean-benoit Hardouin] +* Release 1.1 : May 14, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/ +* Release 1.2 : May 21, 2013 [Jean-Benoit Hardouin] /*saveimp option*/ +* Release 1.3 : May 24, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/ +* Release 1.4 : December 1, 2018 [Jean-Benoit Hardouin] /*correction of a bug on SF12*/ +* Release 1.5 : July 29, 2019 [Jean-Benoit Hardouin] /*radar option*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program :http://www.anaqol.org +* +* Copyright 2013, 2018, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** +program define sf36fr , rclass +version 8.2 +syntax varlist(min=36 max=36 numeric) [,v2 save(string) REPlace age(varname) SEXe(varname) saveref(string) DETails saveimp(string) RADar FILESave DIRSave(string)] + +preserve +local nbitems : word count `varlist' +if `nbitems'!=36 { + di in red "There is `nbitems' items defined instead of 36" +} + +tokenize `varlist' +local varlistsav `varlist' +local sf gh1 ht pf1 pf2 pf3 pf4 pf5 pf6 pf7 pf8 pf9 pf10 rp1 rp2 rp3 rp4 re1 re2 re3 sf1 bp1 bp2 vt1 mh1 mh2 mh3 vt2 mh4 vt3 mh5 vt4 sf2 gh2 gh3 gh4 gh5 +local sf2 +local varlist2 +forvalues i=1/36 { + local j:word `i' of `sf' + tempname `j' + *di " qui gen `j'=``i''" + qui gen ``j''=``i'' + local varlist2 "`varlist2' ``j''" +} +local varlist "`varlist2'" +tokenize `varlist' +*di "`varlist'" + + +if "`v2'"=="" { + local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 5 6 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5 +} +else { + local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 +} +forvalues i=1/36 { + local mod`i':word `i' of `modamax' +} +local error=0 +local inf +local sup +local c=1 +foreach i of varlist `varlist' { + qui count if `i'<1 + if `r(N)'>0 { + local error=1 + local inf "`inf' `i'" + } + local tmp: word `c' of `modamax' + qui count if `i'>`c' + if `r(N)'>0 { + local error=1 + local inf "`sup' `i'" + } + local ++c +} +forvalues i=1/15 { + tempname inc`i' +} +local liste1 11 12 11 12 11 12 11 12 30 24 27 23 1 20 21 +local liste2 3 3 4 4 6 6 9 9 25 26 29 31 36 32 22 +*tab `11' `3' +qui gen `inc1'=`11'==1&`3'>1 if `11'!=.&`3'!=. +* tab `inc`i'' +qui gen `inc2'=`12'==1&`3'>1 if `12'!=.&`3'!=. +qui gen `inc3'=`11'==1&`4'>1 if `11'!=.&`4'!=. +qui gen `inc4'=`12'==1&`4'>1 if `12'!=.&`4'!=. +qui gen `inc5'=`11'==1&`6'>1 if `11'!=.&`6'!=. +qui gen `inc6'=`12'==1&`6'>1 if `12'!=.&`6'!=. +qui gen `inc7'=`11'==1&`9'>1 if `11'!=.&`9'!=. +qui gen `inc8'=`12'==1&`9'>1 if `12'!=.&`9'!=. +qui gen `inc9'=(`30'==1&`25'==1)|(`30'==`mod30'&`25'==`mod25') if `30'!=.&`25'!=. +qui gen `inc10'=(`24'==1&`26'==1)|(`24'==`mod24'&`26'==`mod26') if `24'!=.&`26'!=. +qui gen `inc11'=(`27'==1&`29'==1)|(`27'==`mod27'&`29'==`mod29') if `27'!=.&`29'!=. +qui gen `inc12'=(`23'==1&`31'==1)|(`23'==`mod23'&`31'==`mod31') if `23'!=.&`31'!=. +qui gen `inc13'=(`1'==1&`36'==`mod36')|(`1'==`mod1'&`36'==1) if `1'!=.&`36'!=. +qui gen `inc14'=(`20'==1&`32'==1)|(`20'==`mod20'&`32'==`mod32') if `20'!=.&`32'!=. +qui gen `inc15'=(`21'==1&`22'==`mod22')|(`21'==`mod21'&`22'==1) if `21'!=.&`22'!=. +tempname scoreinc +genscore `inc1'-`inc15',score(`scoreinc') +if "`details'" !="" { + di "{hline 80}" + di in gr "Incoherences" _col(20) "item 1" _col(40) "item 2" _col(60) "# individuals" + di "{hline 80}" + *di "varlist:`varlistsav'" + forvalues i=1/15 { + local i1:word `i' of `liste1' + local i2:word `i' of `liste2' + local ni1:word `i1' of `varlistsav' + local ni2:word `i2' of `varlistsav' + qui count if `inc`i''==1 + + di in gr "`i'" in ye _col(20) abbrev("`ni1'",19) _col(40) abbrev("`ni2'",19) %6.0f _col(67) `r(N)' + } + di "{hline 80}" +} + +forvalues i=1/15 { + local i1:word `i' of `liste1' + local i2:word `i' of `liste2' + qui replace ``i1''=. if `inc`i''==1 + qui replace ``i2''=. if `inc`i''==1 +} + +tempname imp scorepf scorerp scorebp scoregh scorevt scoresf scorere scoremh + + /*PF*/ + imputeitems `3' `4' `5' `6' `7' `8' `9' `10' `11' `12',max(4) noround prefix(`imp') + genscore `imp'`3' `imp'`4' `imp'`5' `imp'`6' `imp'`7' `imp'`8' `imp'`9' `imp'`10' `imp'`11' `imp'`12',score(`scorepf') + qui replace `scorepf'=(`scorepf'-10)/20*100 + /*RP*/ + imputeitems `13' `14' `15' `16',max(1) noround prefix(`imp') + genscore `imp'`13' `imp'`14' `imp'`15' `imp'`16',score(`scorerp') + qui replace `scorerp'=(`scorerp'-4)/4*100 + /*BP*/ + tempvar jb + qui gen `jb'=. + qui replace `jb'=6 if `21'==1&`22'==1 + qui replace `jb'=5 if `21'>=2&`21'<=6&`22'==1 + qui replace `jb'=4 if `22'==2&`21'!=. + qui replace `jb'=3 if `22'==3&`21'!=. + qui replace `jb'=2 if `22'==4&`21'!=. + qui replace `jb'=1 if `22'==5&`21'!=. + qui replace `jb'=6 if `22'==1&`21'==. + qui replace `jb'=4.75 if `22'==2&`21'==. + qui replace `jb'=3.5 if `22'==3&`21'==. + qui replace `jb'=2.25 if `22'==4&`21'==. + qui replace `jb'=1 if `22'==5&`21'==. + qui replace `22'=`jb' + if "`v2'"=="" { + qui recode `21' 1=6 2=5.4 3=4.2 4=3.1 5=2.2 6=1 + } + else { + qui recode `21' 1=6 2=4.8 3=2.65 4=1 + } + imputeitems `21' `22',max(0) noround prefix(`imp') +* replace `imp'`21'=`21' +* replace `imp'`22'=`22' + qui genscore `imp'`21' `imp'`22',score(`scorebp') +* list sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques `21' `22' `imp'`21' `imp'`22' `scorebp' + qui replace `scorebp'=(`scorebp'-2)/10*100 +*tab `scorebp' + /*GH*/ + qui recode `1' 1=5 2=4.4 3=3.4 4=2 5=1 + qui recode `34' 1=5 2=4 3=3 4=2 5=1 + qui recode `36' 1=5 2=4 3=3 4=2 5=1 + imputeitems `1' `33' `34' `35' `36',max(2) noround prefix(`imp') + genscore `imp'`1' `imp'`33' `imp'`34' `imp'`35' `imp'`36',score(`scoregh') + qui replace `scoregh'=(`scoregh'-5)/20*100 + /*VT*/ + if "`v2'"=="" { + qui recode `23' 1=6 2=5 3=4 4=3 5=2 6=1 + qui recode `27' 1=6 2=5 3=4 4=3 5=2 6=1 + } + else { + qui recode `23' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `27' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `29' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `31' 1=1 2=2 3=3.5 4=4.5 5=6 + } + imputeitems `23' `27' `29' `31',max(1) noround prefix(`imp') + genscore `imp'`23' `imp'`27' `imp'`29' `imp'`31',score(`scorevt') + qui replace `scorevt'=(`scorevt'-4)/20*100 + /*SF*/ + if "`v2'"=="" { + qui recode `20' 1=5 2=4 3=3 4=2 5=1 + } + else { + qui recode `20' 1=5 2=4 3=2.5 4=1 + } + imputeitems `20' `32',max(0) noround prefix(`imp') + genscore `imp'`20' `imp'`32',score(`scoresf') + qui replace `scoresf'=(`scoresf'-2)/8*100 + /*RE*/ + imputeitems `17' `18' `19',max(1) noround prefix(`imp') + genscore `imp'`17' `imp'`18' `imp'`19',score(`scorere') + qui replace `scorere'=(`scorere'-3)/3*100 + /*MH*/ + if "`v2'"=="" { + qui recode `26' 1=6 2=5 3=4 4=3 5=2 6=1 + qui recode `30' 1=6 2=5 3=4 4=3 5=2 6=1 + } + else { + qui recode `26' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `30' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `24' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `25' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `28' 1=1 2=2 3=3.5 4=4.5 5=6 + } + imputeitems `24' `25' `26' `28' `30',max(2) noround prefix(`imp') + genscore `imp'`24' `imp'`25' `imp'`26' `imp'`28' `imp'`30',score(`scoremh') + qui replace `scoremh'=(`scoremh'-5)/25*100 + tempname scorepfz scorerpz scorebpz scoreghz scorevtz scoresfz scorerez scoremhz scorepcs scoremcs + + /*scores composites*/ + qui gen `scorepfz'=(`scorepf'-84.52404)/22.89490 + qui gen `scorerpz'=(`scorerp'-81.19907)/33.79729 + qui gen `scorebpz'=(`scorebp'-75.49196)/23.55879 + qui gen `scoreghz'=(`scoregh'-72.21316)/20.16964 + qui gen `scorevtz'=(`scorevt'-61.05453)/20.86942 + qui gen `scoresfz'=(`scoresf'-83.59753)/22.37649 + qui gen `scorerez'=(`scorere'-81.29467)/33.02717 + qui gen `scoremhz'=(`scoremh'-74.84212)/18.01189 + qui gen `scorepcs'=(`scorepfz'*0.42402+`scorerpz'*0.35119+`scorebpz'*0.31754+`scoreghz'*0.24954+`scorevtz'*0.02877-`scoresfz'*0.0753-`scorerez'*0.19206-`scoremhz'*0.22069)*10+50 + qui gen `scoremcs'=(-`scorepfz'*0.22999-`scorerpz'*0.12329-`scorebpz'*0.09731-`scoreghz'*0.01571+`scorevtz'*0.23534+`scoresfz'*0.26876+`scorerez'*0.43407+`scoremhz'*0.48581)*10+50 + + +/*scores composites SF12*/ +tempname scoresf12p sf12p_1 sf12p_2a sf12p_2b sf12p_3a sf12p_3b sf12p_4a sf12p_4b sf12p_5 sf12p_6 sf12p_7a sf12p_7b sf12p_7c +tempname scoresf12m sf12m_1 sf12m_2a sf12m_2b sf12m_3a sf12m_3b sf12m_4a sf12m_4b sf12m_5 sf12m_6 sf12m_7a sf12m_7b sf12m_7c + qui gen `sf12p_1'=`1' + qui gen `sf12p_2a'=`4' + qui gen `sf12p_2b'=`6' + qui gen `sf12p_3a'=`14' + qui gen `sf12p_3b'=`15' + qui gen `sf12p_4a'=`18' + qui gen `sf12p_4b'=`19' + qui gen `sf12p_5'=`20' + qui gen `sf12p_6'=`32' + qui gen `sf12p_7a'=`26' + qui gen `sf12p_7b'=`27' + qui gen `sf12p_7c'=`28' + qui gen `sf12m_1'=`1' + qui gen `sf12m_2a'=`4' + qui gen `sf12m_2b'=`6' + qui gen `sf12m_3a'=`14' + qui gen `sf12m_3b'=`15' + qui gen `sf12m_4a'=`18' + qui gen `sf12m_4b'=`19' + qui gen `sf12m_5'=`20' + qui gen `sf12m_6'=`32' + qui gen `sf12m_7a'=`26' + qui gen `sf12m_7b'=`27' + qui gen `sf12m_7c'=`28' + qui recode `sf12p_1' 5=0 4.4=-1.31872 3.4=-3.02396 2=-5.56461 1=-8.37399 + qui recode `sf12m_1' 5=0 4.4=-0.06064 3.4=0.03482 2=-0.16891 1=-1.71175 + qui recode `sf12p_2a' 1=-7.23216 2=-3.45555 3=0 + qui recode `sf12m_2a' 1=3.93115 2=1.86840 3=0 + qui recode `sf12p_2b' 1=-6.24397 2=-2.73557 3=0 + qui recode `sf12m_2b' 1=2.68282 2=1.43103 3=0 + qui recode `sf12p_3a' 1=-4.61617 2=0 + qui recode `sf12m_3a' 1=1.44060 2=0 + qui recode `sf12p_3b' 1=-5.51747 2=0 + qui recode `sf12m_3b' 1=1.66968 2=0 + qui recode `sf12p_4a' 1=3.04365 2=0 + qui recode `sf12m_4a' 1=-6.82672 2=0 + qui recode `sf12p_4b' 1=2.32091 2=0 + qui recode `sf12m_4b' 1=-5.69921 2=0 + qui recode `sf12p_6' 1=-0.33682 2=-0.94342 3=-0.18043 4=0.11038 5=0 + qui recode `sf12m_6' 1=-6.29724 2=-8.26066 3=-5.63286 4=-3.13896 5=0 + if "`v2'"=="" { + qui recode `sf12p_5' 5=0 4=-3.80130 3=-6.50522 2=-8.38063 1=-11.25544 + qui recode `sf12m_5' 5=0 4=0.90384 3=1.49384 2=1.76691 1=1.48619 + qui recode `sf12p_7a' 6=0 5=0.66514 4=1.36689 3=2.37241 2=2.90426 1=3.46638 + qui recode `sf12m_7a' 6=0 5=-1.94949 4=-4.09842 3=-6.31121 2=-7.92717 1=-10.19085 + qui recode `sf12p_7b' 6=0 5=-0.42251 4=-1.14387 3=-1.61850 2=-2.02168 1=-2.44706 + qui recode `sf12m_7b' 6=0 5=-0.92057 4=-1.65178 3=-3.29805 2=-4.88962 1=-6.02409 + qui recode `sf12p_7c' 1=4.61446 2=3.41593 3=2.34247 4=1.28044 5=0.41188 6=0 + qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3=-8.09914 4=-4.59055 5=-1.95934 6=0 + } + else { + qui recode `sf12p_5' 5=0 4=-3.83130 2.5=-7.442925 1=-11.25544 + qui recode `sf12m_5' 5=0 4=0.90384 2.5=1.630375 1=1.48619 + qui recode `sf12p_7a' 6=0 4.5=1.016015 3.5=1.86965 2=2.90426 1=3.46638 + qui recode `sf12m_7a' 6=0 4.5=-3.023955 3.5=-5.204815 2=-7.92717 1=-10.19085 + qui recode `sf12p_7b' 6=0 4.5=-0.78319 3.5=-1.381185 2=-2.02168 1=-2.44706 + qui recode `sf12m_7b' 6=0 4.5=-1.286175 3.5=-2.474915 2=-4.88962 1=-6.02409 + qui recode `sf12p_7c' 1=4.61446 2=3.41593 3.5=1.811455 4.5=0.84616 6=0 + qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3.5=-6.344845 4.5=-3.274945 6=0 + } + qui gen `scoresf12p'=`sf12p_1'+`sf12p_2a'+`sf12p_2b'+`sf12p_3a'+`sf12p_3b'+`sf12p_4a'+`sf12p_4b'+`sf12p_5'+`sf12p_6'+`sf12p_7a'+`sf12p_7b'+`sf12p_7c'+56.57706 + qui gen `scoresf12m'=`sf12m_1'+`sf12m_2a'+`sf12m_2b'+`sf12m_3a'+`sf12m_3b'+`sf12m_4a'+`sf12m_4b'+`sf12m_5'+`sf12m_6'+`sf12m_7a'+`sf12m_7b'+`sf12m_7c'+60.75781 + +if "`save'"!="" { + local listmin pf rp bp gh vt sf re mh pcs mcs + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local error=0 + local list + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `save'`i' + if _rc==0&"`replace'"=="" { + local ++error + local list "`list' `save'`j'" + } + local ++c + } + local c=1 + if `error'==0 { + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `save'`i' + if _rc==0 { + qui replace `save'`i'=`score`i'' + } + else { + qui gen `save'`i'=`score`i'' + } + local ++c + } + } + else { + di in red "The variable(s) `list' already exist(s)" + } +} +tempname scoreref1 scoreref0 scoreref01 scoreref scorerefv1 scorerefv0 scorerefv01 scorerefv +matrix `scoreref1'=(96.65,95.80,86.82,82.36,67.86,89.76,93.14,72.85\95.75,91.16,83.60,76.07,64.50,86.50,90.64,72.08\94.41,90.76,81.03,73.13,64.32,86.37,89.07,71.01\92.27,88.64,79.02,72.27,66.06,86.69,90.00,71.53\82.32,79.81,70.21,65.97,60.19,83.33,83.00,71.10\76.58,74.74,67.10,62.37,58.21,79.74,80.04,71.16\67.16,61.28,63.99,58.61,53.93,76.16,66.67,70.24) +matrix `scoreref0'=(94.92,89.54,79.37,71.81,60.32,79.65,81.65,64.92\92.42,85.98,80.19,75.10,60.57,82.83,86.13,68.18\91.04,88.87,78.27,74.64,61.94,84.14,85.48,67.59\86.23,85.54,71.97,69.14,58.90,79.80,83.42,64.84\77.88,77.85,66.23,65.10,58.18,78.29,77.61,66.17\71.60,68.74,62.40,61.23,55.08,76.47,73.24,65.45\58.20,52.46,59.68,59.73,47.94,71.68,62.21,60.63) +matrix `scoreref01'=(95.65,92.18,82.51,76.26,63.52,83.93,86.47,68.29\93.93,88.34,81.75,75.54,62.35,84.51,88.19,69.94\92.71,89.80,79.63,73.89,63.12,85.24,87.26,69.28\89.25,87.09,75.50,70.70,62.48,83.24,86.71,68.19\79.99,78.78,68.12,65.51,59.14,80.69,80.19,68.52\73.69,71.24,64.37,61.71,56.39,77.84,76.05,67.84\62.40,56.67,61.72,59.20,50.86,73.80,64.38,65.29) +matrix `scoreref'=(84.45,81.21,73.39,69.13,59.96,81.55,82.13,68.47\87.07,83.86,75.98,70.07,62.23,84.08,85.41,71.42\82.22,78.96,71.18,68.33,58.03,79.41,79.34,65.96) +matrix `scorerefv1'=(11.78,15.33,17.21,13.93,14.16,14.43,20.73,15.28\9.64,21.30,19.63,15.89,16.72,19.05,24.18,15.83\11.08,23.63,21.00,16.20,16.65,18.97,26.12,16.70\14.92,26.35,22.09,17.41,16.24,17.01,23.15,16.23\20.48,32.67,22.24,17.93,16.89,20.35,32.04,17.40\22.78,36.05,24.06,19.08,18.03,21.94,33.89,16.60\27.44,40.86,24.38,17.61,18.86,24.08,41.43,20.03) +matrix `scorerefv0'=(9.10,21.65,21.66,17.69,18.10,22.35,29.58,17.32\14.19,28.28,21.28,16.66,18.28,20.57,28.19,18.06\14.81,25.19,21.25,17.64,18.55,20.97,29.37,17.92\19.11,29.40,23.90,18.60,17.84,21.44,31.24,16.66\21.49,33.02,24.10,18.78,18.22,23.46,34.89,18.03\23.42,38.17,23.94,17.67,17.59,22.46,37.41,18.21\25.70,39.18,23.40,18.08,17.98,24.06,39.97,18.98) +matrix `scorerefv01'=(10.33,19.46,20.21,17.00,16.94,20.00,26.80,16.83\12.44,25.45,20.60,16.31,17.69,19.96,16.51,17.18\13.19,24.43,21.15,16.95,17.66,20.02,27.85,17.40\17.39,27.92,23.25,18.06,17.41,19.64,27.65,16.76\21.11,32.83,23.29,18.37,17.61,22.16,33.63,17.88\23.27,37.40,24.09,18.28,17.83,22.29,36.13,17.77\26.85,40.16,23.92,17.83,18.62,24.13,40.67,20.04) +matrix `scorerefv'=(21.19,32.20,23.73,18.57,18.05,21.41,32.15,17.62\19.85,30.48,23.03,18.39,17.36,20.08,29.89,16.70\22.02,33.43,24.10,18.69,18.40,22.26,33.71,17.99) + +tempname scorerefpf scorerefrp scorerefbp scorerefgh scorerefvt scorerefsf scorerefre scorerefmh +tempname scorerefpfv scorerefrpv scorerefbpv scorerefghv scorerefvtv scorerefsfv scorerefrev scorerefmhv +if "`age'"!=""&"`sexe'"!="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref0'[1,`c'] if `sexe'==0&`age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref0'[2,`c'] if `sexe'==0&`age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref0'[3,`c'] if `sexe'==0&`age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref0'[4,`c'] if `sexe'==0&`age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref0'[5,`c'] if `sexe'==0&`age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref0'[6,`c'] if `sexe'==0&`age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref0'[7,`c'] if `sexe'==0&`age'>=75 + qui replace `scoreref`i''=`scoreref1'[1,`c'] if `sexe'==1&`age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref1'[2,`c'] if `sexe'==1&`age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref1'[3,`c'] if `sexe'==1&`age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref1'[4,`c'] if `sexe'==1&`age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref1'[5,`c'] if `sexe'==1&`age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref1'[6,`c'] if `sexe'==1&`age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref1'[7,`c'] if `sexe'==1&`age'>=75 + qui gen `scoreref`i'v'=(`scorerefv0'[1,`c'])^2 if `sexe'==0&`age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv0'[2,`c'])^2 if `sexe'==0&`age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv0'[3,`c'])^2 if `sexe'==0&`age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv0'[4,`c'])^2 if `sexe'==0&`age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv0'[5,`c'])^2 if `sexe'==0&`age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv0'[6,`c'])^2 if `sexe'==0&`age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv0'[7,`c'])^2 if `sexe'==0&`age'>=75 + qui replace `scoreref`i'v'=(`scorerefv1'[1,`c'])^2 if `sexe'==1&`age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv1'[2,`c'])^2 if `sexe'==1&`age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv1'[3,`c'])^2 if `sexe'==1&`age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv1'[4,`c'])^2 if `sexe'==1&`age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv1'[5,`c'])^2 if `sexe'==1&`age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv1'[6,`c'])^2 if `sexe'==1&`age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv1'[7,`c'])^2 if `sexe'==1&`age'>=75 + local ++c + } +} +else if "`age'"!=""&"`sexe'"=="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref01'[1,`c'] if `age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref01'[2,`c'] if `age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref01'[3,`c'] if `age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref01'[4,`c'] if `age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref01'[5,`c'] if `age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref01'[6,`c'] if `age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref01'[7,`c'] if `age'>=75 + qui gen `scoreref`i'v'=(`scorerefv01'[1,`c'])^2 if `age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv01'[2,`c'])^2 if `age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv01'[3,`c'])^2 if `age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv01'[4,`c'])^2 if `age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv01'[5,`c'])^2 if `age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv01'[6,`c'])^2 if `age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv01'[7,`c'])^2 if `age'>=75 + local ++c + } +} +else if "`age'"==""&"`sexe'"!="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref'[2,`c'] if `sexe'==1 + qui replace `scoreref`i''=`scoreref'[3,`c'] if `sexe'==0 + qui gen `scoreref`i'v'=(`scorerefv'[2,`c'])^2 if `sexe'==1 + qui replace `scoreref`i'v'=(`scorerefv'[3,`c'])^2 if `sexe'==0 + local ++c + } +} +else if "`age'"==""&"`sexe'"=="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + gen `scoreref`i''=`scoreref'[1,`c'] + gen `scoreref`i'v'=(`scorerefv'[1,`c'])^2 + local ++c + } +} +tempname scorerefpfz scorerefrpz scorerefbpz scorerefghz scorerefvtz scorerefsfz scorerefrez scorerefmhz scorerefpcs scorerefmcs +tempname scorerefpfvz scorerefrpvz scorerefbpvz scorerefghvz scorerefvtvz scorerefsfvz scorerefrevz scorerefmhvz scorerefpcsv scorerefmcsv + +qui gen `scorerefpfz'=(`scorerefpf'-84.52404)/22.89490 +qui gen `scorerefrpz'=(`scorerefrp'-81.19907)/33.79729 +qui gen `scorerefbpz'=(`scorerefbp'-75.49196)/23.55879 +qui gen `scorerefghz'=(`scorerefgh'-72.21316)/20.16964 +qui gen `scorerefvtz'=(`scorerefvt'-61.05453)/20.86942 +qui gen `scorerefsfz'=(`scorerefsf'-83.59753)/22.37649 +qui gen `scorerefrez'=(`scorerefre'-81.29467)/33.02717 +qui gen `scorerefmhz'=(`scorerefmh'-74.84212)/18.01189 +qui gen `scorerefpcs'=(`scorerefpfz'*0.42402+`scorerefrpz'*0.35119+`scorerefbpz'*0.31754+`scorerefghz'*0.24954+`scorerefvtz'*0.02877-`scorerefsfz'*0.0753-`scorerefrez'*0.19206-`scorerefmhz'*0.22069)*10+50 +qui gen `scorerefmcs'=(-`scorerefpfz'*0.22999-`scorerefrpz'*0.12329-`scorerefbpz'*0.09731-`scorerefghz'*0.01571+`scorerefvtz'*0.23534+`scorerefsfz'*0.26876+`scorerefrez'*0.43407+`scorerefmhz'*0.48581)*10+50 + +qui gen `scorerefpfvz'=(`scorerefpfv')/22.89490^2 +qui gen `scorerefrpvz'=(`scorerefrpv')/33.79729^2 +qui gen `scorerefbpvz'=(`scorerefbpv')/23.55879^2 +qui gen `scorerefghvz'=(`scorerefghv')/20.16964^2 +qui gen `scorerefvtvz'=(`scorerefvtv')/20.86942^2 +qui gen `scorerefsfvz'=(`scorerefsfv')/22.37649^2 +qui gen `scorerefrevz'=(`scorerefrev')/33.02717^2 +qui gen `scorerefmhvz'=(`scorerefmhv')/18.01189^2 +qui gen `scorerefpcsv'=(`scorerefpfvz'*0.42402^2+`scorerefrpvz'*0.35119^2+`scorerefbpvz'*0.31754^2+`scorerefghvz'*0.24954^2+`scorerefvtvz'*0.02877^2-`scorerefsfvz'*0.0753^2-`scorerefrevz'*0.19206^2-`scorerefmhvz'*0.22069^2)*10^2 +qui gen `scorerefmcsv'=(-`scorerefpfvz'*0.22999^2-`scorerefrpvz'*0.12329^2-`scorerefbpvz'*0.09731^2-`scorerefghvz'*0.01571^2+`scorerefvtvz'*0.23534^2+`scorerefsfvz'*0.26876^2+`scorerefrevz'*0.43407^2+`scorerefmhvz'*0.48581^2)*10^2 + + + + + +if "`saveref'"!="" { + local listmin pf rp bp gh vt sf re mh pcs mcs + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local error=0 + local list + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `saveref'`i' + if _rc==0&"`replace'"=="" { + local ++error + local list "`list' `saveref'`j'" + } + local ++c + } + local c=1 + if `error'==0 { + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `saveref'`i' + if _rc==0 { + qui replace `saveref'`i'=`scoreref`i'' + } + else { + qui gen `saveref'`i'=`scoreref`i'' + } + local ++c + } + } + else { + di in red "The variable(s) `list' already exist(s)" + } +} + +if "`details'"!=""|"`radar'"!="" { + tempname radar + qui matrix `radar'=J(12,2,.) + if "`details'"!="" { + di "{hline 80}" + di in gr _col(12) "Sample" _col(51) "Reference" + di in gr "Dimension" _col(16) "N" _col(21) "Mean" _col(29) "s.d." _col(40) "Min-Max" _col(52) "Mean" _col(60) "s.d." _col(72) "p" + di "{hline 80}" + } + local listmin pf rp bp gh vt sf re mh pcs mcs sf12p sf12m + local listmaj PF RP BP GH VT SF RE MH PCS MCS SF12P SF12M + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + qui su `score`i'' + local means`i'=r(mean) + local sds`i'=r(sd) + local mins`i'=r(min) + local maxs`i'=r(max) + local n`i'=r(N) + matrix `radar'[`c',1]=`means`i'' + qui su `scoreref`i'' + matrix `radar'[`c',2]=r(mean) + if "`i'"!="sf12p"&"`i'"!="sf12m" { + qui su `scoreref`i'' if `score`i''!=. + local meanr`i'=r(mean) + local sdr`i'=r(sd) + local vr`i'=(`sdr`i'')^2 + qui su `scoreref`i'v' if `score`i''!=. + local meanvr`i'=r(mean) + local sdr`i'=sqrt(`vr`i''+`meanvr`i'') + *local minr`i'=r(min) + *local maxr`i'=r(max) + qui ttest `score`i''=`meanr`i'' + local p`i'=r(p) + } + if "`details'"!="" { + di in gr "`j'" in ye _col(12) %5.0f `n`i'' _col(20) %5.2f `means`i'' _col(28) %5.2f `sds`i'' _col(34) %6.2f `mins`i'' "-" %6.2f `maxs`i'' _col(51) %5.2f `meanr`i'' _col(59) %5.2f `sdr`i'' _col(67) %6.4f `p`i'' + } + local ++c + } + if "`details'"!="" { + di "{hline 80}" + } + *corr `scorepcs' `scoremcs' `scoresf12p' `scoresf12m' + *scatter `scorepcs' `scoresf12p' ,name(p) + *scatter `scoremcs' `scoresf12m' ,name(m) + *su `scoresf12p' `sf12p_1' `sf12p_2a' `sf12p_2b' `sf12p_3a' `sf12p_3b' `sf12p_4a' `sf12p_4b' `sf12p_5' `sf12p_6' `sf12p_7a' `sf12p_7b' `sf12p_7c' + *su `scoresf12m' `sf12m_1' `sf12m_2a' `sf12m_2b' `sf12m_3a' `sf12m_3b' `sf12m_4a' `sf12m_4b' `sf12m_5' `sf12m_6' `sf12m_7a' `sf12m_7b' `sf12m_7c' + if "`radar'"!=""&"`v2'"=="" { + qui tempfile radarfile + qui save `radarfile', replace + qui drop _all + qui svmat `radar' + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local c=1 + qui gen name="" + foreach i in `listmin' { + qui replace name="`i'" in `c' + local ++c + } + qui rename `radar'1 scoreSF36 + rename `radar'2 scoreSF36ref + qui keep in 1/10 + label variable scoreSF36 "Sample" + label variable scoreSF36ref "General French population" + if "`filesave'"!="" { + if "`dirsave'"=="" { + local dirsave `c(pwd)' + } + local saving "saving(`dirsave'//radar, replace) " + } + qui radar name scoreSF36 scoreSF36ref, note("") title("Comparison of the sample with the general French population") legend(lab(1 "Sample") lab(2 "General French population")) `saving' + qui use `radarfile', clear + } +} +if "`saveimp'"!="" { +*su + foreach i of numlist 1 3/36 { + local j:word `i' of `varlistsav' + *di "gen `saveimp'`j'=`imp'``i''" + capture confirm variable `saveimp'`j' + if _rc==0&"`replace'"=="" { + di in ye "The variable `saveimp'`j' already exists and cannot be replaced." + } + else if _rc==0&"`replace'"!="" { + qui replace `saveimp'`j'=`imp'``i'' + } + else { + qui gen `saveimp'`j'=`imp'``i'' + } + } +} +restore, preserve +end diff --git a/Modules/ado/personal/s/sf36frv13.ado b/Modules/ado/personal/s/sf36frv13.ado new file mode 100644 index 0000000..fa497ef --- /dev/null +++ b/Modules/ado/personal/s/sf36frv13.ado @@ -0,0 +1,549 @@ +*! Version 1.3 24 May 2013 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Stata program : sf36fr +* computes score of the French SF36 questionnnaire +* Release 1 : May 2, 2013 [Jean-benoit Hardouin] +* Release 1.1 : May 14, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/ +* Release 1.2 : May 21, 2013 [Jean-Benoit Hardouin] /*saveimp option*/ +* Release 1.3 : May 24, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/ +* +* +* Historic : +* Version 1 (May 2, 2013) [Jean-Benoit Hardouin] +* +* Faire sauvegarde des items imputés +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* News about this program :http://www.anaqol.org +* +* Copyright 2013 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*********************************************************************************************************** +program define sf36fr , rclass +version 8.2 +syntax varlist(min=36 max=36 numeric) [,v2 save(string) REPlace age(varname) SEXe(varname) saveref(string) DETails saveimp(string)] + +local nbitems : word count `varlist' +if `nbitems'!=36 { + di in red "There is `nbitems' items defined instead of 36" +} + +tokenize `varlist' +local varlistsav `varlist' +local sf gh1 ht pf1 pf2 pf3 pf4 pf5 pf6 pf7 pf8 pf9 pf10 rp1 rp2 rp3 rp4 re1 re2 re3 sf1 bp1 bp2 vt1 mh1 mh2 mh3 vt2 mh4 vt3 mh5 vt4 sf2 gh2 gh3 gh4 gh5 +local sf2 +local varlist2 +forvalues i=1/36 { + local j:word `i' of `sf' + tempname `j' + *di " qui gen `j'=``i''" + qui gen ``j''=``i'' + local varlist2 "`varlist2' ``j''" +} +local varlist "`varlist2'" +tokenize `varlist' +*di "`varlist'" + + +if "`v2'"=="" { + local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 5 6 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5 +} +else { + local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 +} +forvalues i=1/36 { + local mod`i':word `i' of `modamax' +} +local error=0 +local inf +local sup +local c=1 +foreach i of varlist `varlist' { + qui count if `i'<1 + if `r(N)'>0 { + local error=1 + local inf "`inf' `i'" + } + local tmp: word `c' of `modamax' + qui count if `i'>`c' + if `r(N)'>0 { + local error=1 + local inf "`sup' `i'" + } + local ++c +} +forvalues i=1/15 { + tempname inc`i' +} +local liste1 11 12 11 12 11 12 11 12 30 24 27 23 1 20 21 +local liste2 3 3 4 4 6 6 9 9 25 26 29 31 36 32 22 +*tab `11' `3' +qui gen `inc1'=`11'==1&`3'>1 if `11'!=.&`3'!=. +* tab `inc`i'' +qui gen `inc2'=`12'==1&`3'>1 if `12'!=.&`3'!=. +qui gen `inc3'=`11'==1&`4'>1 if `11'!=.&`4'!=. +qui gen `inc4'=`12'==1&`4'>1 if `12'!=.&`4'!=. +qui gen `inc5'=`11'==1&`6'>1 if `11'!=.&`6'!=. +qui gen `inc6'=`12'==1&`6'>1 if `12'!=.&`6'!=. +qui gen `inc7'=`11'==1&`9'>1 if `11'!=.&`9'!=. +qui gen `inc8'=`12'==1&`9'>1 if `12'!=.&`9'!=. +qui gen `inc9'=(`30'==1&`25'==1)|(`30'==`mod30'&`25'==`mod25') if `30'!=.&`25'!=. +qui gen `inc10'=(`24'==1&`26'==1)|(`24'==`mod24'&`26'==`mod26') if `24'!=.&`26'!=. +qui gen `inc11'=(`27'==1&`29'==1)|(`27'==`mod27'&`29'==`mod29') if `27'!=.&`29'!=. +qui gen `inc12'=(`23'==1&`31'==1)|(`23'==`mod23'&`31'==`mod31') if `23'!=.&`31'!=. +qui gen `inc13'=(`1'==1&`36'==`mod36')|(`1'==`mod1'&`36'==1) if `1'!=.&`36'!=. +qui gen `inc14'=(`20'==1&`32'==1)|(`20'==`mod20'&`32'==`mod32') if `20'!=.&`32'!=. +qui gen `inc15'=(`21'==1&`22'==`mod22')|(`21'==`mod21'&`22'==1) if `21'!=.&`22'!=. +tempname scoreinc +genscore `inc1'-`inc15',score(`scoreinc') +if "`details'" !="" { + di "{hline 80}" + di in gr "Incoherences" _col(20) "item 1" _col(40) "item 2" _col(60) "# individuals" + di "{hline 80}" + *di "varlist:`varlistsav'" + forvalues i=1/15 { + local i1:word `i' of `liste1' + local i2:word `i' of `liste2' + local ni1:word `i1' of `varlistsav' + local ni2:word `i2' of `varlistsav' + qui count if `inc`i''==1 + + di in gr "`i'" in ye _col(20) abbrev("`ni1'",19) _col(40) abbrev("`ni2'",19) %6.0f _col(67) `r(N)' + } + di "{hline 80}" +} + +forvalues i=1/15 { + local i1:word `i' of `liste1' + local i2:word `i' of `liste2' + qui replace ``i1''=. if `inc`i''==1 + qui replace ``i2''=. if `inc`i''==1 +} + +tempname imp scorepf scorerp scorebp scoregh scorevt scoresf scorere scoremh + + /*PF*/ + imputeitems `3' `4' `5' `6' `7' `8' `9' `10' `11' `12',max(4) noround prefix(`imp') + genscore `imp'`3' `imp'`4' `imp'`5' `imp'`6' `imp'`7' `imp'`8' `imp'`9' `imp'`10' `imp'`11' `imp'`12',score(`scorepf') + qui replace `scorepf'=(`scorepf'-10)/20*100 + /*RP*/ + imputeitems `13' `14' `15' `16',max(1) noround prefix(`imp') + genscore `imp'`13' `imp'`14' `imp'`15' `imp'`16',score(`scorerp') + qui replace `scorerp'=(`scorerp'-4)/4*100 + /*BP*/ + tempvar jb + qui gen `jb'=. + qui replace `jb'=6 if `21'==1&`22'==1 + qui replace `jb'=5 if `21'>=2&`21'<=6&`22'==1 + qui replace `jb'=4 if `22'==2&`21'!=. + qui replace `jb'=3 if `22'==3&`21'!=. + qui replace `jb'=2 if `22'==4&`21'!=. + qui replace `jb'=1 if `22'==5&`21'!=. + qui replace `jb'=6 if `22'==1&`21'==. + qui replace `jb'=4.75 if `22'==2&`21'==. + qui replace `jb'=3.5 if `22'==3&`21'==. + qui replace `jb'=2.25 if `22'==4&`21'==. + qui replace `jb'=1 if `22'==5&`21'==. + qui replace `22'=`jb' + if "`v2'"=="" { + qui recode `21' 1=6 2=5.4 3=4.2 4=3.1 5=2.2 6=1 + } + else { + qui recode `21' 1=6 2=4.8 3=2.65 4=1 + } + imputeitems `21' `22',max(0) noround prefix(`imp') +* replace `imp'`21'=`21' +* replace `imp'`22'=`22' + qui genscore `imp'`21' `imp'`22',score(`scorebp') +* list sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques `21' `22' `imp'`21' `imp'`22' `scorebp' + qui replace `scorebp'=(`scorebp'-2)/10*100 +*tab `scorebp' + /*GH*/ + qui recode `1' 1=5 2=4.4 3=3.4 4=2 5=1 + qui recode `34' 1=5 2=4 3=3 4=2 5=1 + qui recode `36' 1=5 2=4 3=3 4=2 5=1 + imputeitems `1' `33' `34' `35' `36',max(2) noround prefix(`imp') + genscore `imp'`1' `imp'`33' `imp'`34' `imp'`35' `imp'`36',score(`scoregh') + qui replace `scoregh'=(`scoregh'-5)/20*100 + /*VT*/ + if "`v2'"=="" { + qui recode `23' 1=6 2=5 3=4 4=3 5=2 6=1 + qui recode `27' 1=6 2=5 3=4 4=3 5=2 6=1 + } + else { + qui recode `23' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `27' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `29' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `31' 1=1 2=2 3=3.5 4=4.5 5=6 + } + imputeitems `23' `27' `29' `31',max(1) noround prefix(`imp') + genscore `imp'`23' `imp'`27' `imp'`29' `imp'`31',score(`scorevt') + qui replace `scorevt'=(`scorevt'-4)/20*100 + /*SF*/ + if "`v2'"=="" { + qui recode `20' 1=5 2=4 3=3 4=2 5=1 + } + else { + qui recode `20' 1=5 2=4 3=2.5 4=1 + } + imputeitems `20' `32',max(0) noround prefix(`imp') + genscore `imp'`20' `imp'`32',score(`scoresf') + qui replace `scoresf'=(`scoresf'-2)/8*100 + /*RE*/ + imputeitems `17' `18' `19',max(1) noround prefix(`imp') + genscore `imp'`17' `imp'`18' `imp'`19',score(`scorere') + qui replace `scorere'=(`scorere'-3)/3*100 + /*MH*/ + if "`v2'"=="" { + qui recode `26' 1=6 2=5 3=4 4=3 5=2 6=1 + qui recode `30' 1=6 2=5 3=4 4=3 5=2 6=1 + } + else { + qui recode `26' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `30' 1=6 2=4.5 3=3.5 4=2 5=1 + qui recode `24' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `25' 1=1 2=2 3=3.5 4=4.5 5=6 + qui recode `28' 1=1 2=2 3=3.5 4=4.5 5=6 + } + imputeitems `24' `25' `26' `28' `30',max(2) noround prefix(`imp') + genscore `imp'`24' `imp'`25' `imp'`26' `imp'`28' `imp'`30',score(`scoremh') + qui replace `scoremh'=(`scoremh'-5)/25*100 + tempname scorepfz scorerpz scorebpz scoreghz scorevtz scoresfz scorerez scoremhz scorepcs scoremcs + + /*scores composites*/ + qui gen `scorepfz'=(`scorepf'-84.52404)/22.89490 + qui gen `scorerpz'=(`scorerp'-81.19907)/33.79729 + qui gen `scorebpz'=(`scorebp'-75.49196)/23.55879 + qui gen `scoreghz'=(`scoregh'-72.21316)/20.16964 + qui gen `scorevtz'=(`scorevt'-61.05453)/20.86942 + qui gen `scoresfz'=(`scoresf'-83.59753)/22.37649 + qui gen `scorerez'=(`scorere'-81.29467)/33.02717 + qui gen `scoremhz'=(`scoremh'-74.84212)/18.01189 + qui gen `scorepcs'=(`scorepfz'*0.42402+`scorerpz'*0.35119+`scorebpz'*0.31754+`scoreghz'*0.24954+`scorevtz'*0.02877-`scoresfz'*0.0753-`scorerez'*0.19206-`scoremhz'*0.22069)*10+50 + qui gen `scoremcs'=(-`scorepfz'*0.22999-`scorerpz'*0.12329-`scorebpz'*0.09731-`scoreghz'*0.01571+`scorevtz'*0.23534+`scoresfz'*0.26876+`scorerez'*0.43407+`scoremhz'*0.48581)*10+50 + + +/*scores composites SF12*/ +tempname scoresf12p sf12p_1 sf12p_2a sf12p_2b sf12p_3a sf12p_3b sf12p_4a sf12p_4b sf12p_5 sf12p_6 sf12p_7a sf12p_7b sf12p_7c +tempname scoresf12m sf12m_1 sf12m_2a sf12m_2b sf12m_3a sf12m_3b sf12m_4a sf12m_4b sf12m_5 sf12m_6 sf12m_7a sf12m_7b sf12m_7c + qui gen `sf12p_1'=`1' + qui gen `sf12p_2a'=`4' + qui gen `sf12p_2b'=`6' + qui gen `sf12p_3a'=`14' + qui gen `sf12p_3b'=`15' + qui gen `sf12p_4a'=`18' + qui gen `sf12p_4b'=`19' + qui gen `sf12p_5'=`20' + qui gen `sf12p_6'=`32' + qui gen `sf12p_7a'=`26' + qui gen `sf12p_7b'=`27' + qui gen `sf12p_7c'=`28' + qui gen `sf12m_1'=`1' + qui gen `sf12m_2a'=`4' + qui gen `sf12m_2b'=`6' + qui gen `sf12m_3a'=`14' + qui gen `sf12m_3b'=`15' + qui gen `sf12m_4a'=`18' + qui gen `sf12m_4b'=`19' + qui gen `sf12m_5'=`20' + qui gen `sf12m_6'=`32' + qui gen `sf12m_7a'=`26' + qui gen `sf12m_7b'=`27' + qui gen `sf12m_7c'=`28' + qui recode `sf12p_1' 5=0 4.4=-1.31872 3.4=-3.02396 2=-5.56461 1=-8.37399 + qui recode `sf12m_1' 5=0 4.4=-0.06064 3.4=0.03482 2=-0.16891 1=-1.71175 + qui recode `sf12p_2a' 1=-7.23216 2=-3.45555 3=0 + qui recode `sf12m_2a' 1=3.93115 2=1.86840 3=0 + qui recode `sf12p_2b' 1=-6.24397 2=-2.73557 3=0 + qui recode `sf12m_2b' 1=2.68282 2=1.43103 3=0 + qui recode `sf12p_3a' 1=-4.61617 2=0 + qui recode `sf12m_3a' 1=1.44060 2=0 + qui recode `sf12p_3b' 1=-5.51747 2=0 + qui recode `sf12m_3b' 1=1.66968 2=0 + qui recode `sf12p_4a' 1=3.04365 2=0 + qui recode `sf12m_4a' 1=-6.82672 2=0 + qui recode `sf12p_4b' 1=2.32091 2=0 + qui recode `sf12m_4b' 1=-5.69921 2=0 + qui recode `sf12p_6' 1=-0.33682 2=-0.94342 3=-0.18043 4=-0.11038 5=0 + qui recode `sf12m_6' 1=-6.29724 2=-8.26066 3=-5.63286 4=-3.13896 5=0 + if "`v2'"=="" { + qui recode `sf12p_5' 5=0 4=-3.83130 3=-6.50522 2=-8.38063 1=-11.25544 + qui recode `sf12m_5' 5=0 4=0.90384 3=1.49384 2=1.76691 1=1.48619 + qui recode `sf12p_7a' 6=0 5=0.66514 4=1.36689 3=2.37241 2=2.90426 1=3.46638 + qui recode `sf12m_7a' 6=0 5=-1.94949 4=-4.09842 3=-6.31121 2=-7.92717 1=-10.19085 + qui recode `sf12p_7b' 6=0 5=-0.42251 4=-1.14387 3=-1.61850 2=-2.02168 1=-2.44706 + qui recode `sf12m_7b' 6=0 5=-0.92057 4=-1.65178 3=-3.29805 2=-4.88962 1=-6.02409 + qui recode `sf12p_7c' 1=4.61446 2=3.41593 3=2.34247 4=1.28044 5=0.41188 6=0 + qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3=-8.09914 4=-4.59055 5=-1.95934 6=0 + } + else { + qui recode `sf12p_5' 5=0 4=-3.83130 2.5=-7.442925 1=-11.25544 + qui recode `sf12m_5' 5=0 4=0.90384 2.5=1.630375 1=1.48619 + qui recode `sf12p_7a' 6=0 4.5=1.016015 3.5=1.86965 2=2.90426 1=3.46638 + qui recode `sf12m_7a' 6=0 4.5=-3.023955 3.5=-5.204815 2=-7.92717 1=-10.19085 + qui recode `sf12p_7b' 6=0 4.5=-0.78319 3.5=-1.381185 2=-2.02168 1=-2.44706 + qui recode `sf12m_7b' 6=0 4.5=-1.286175 3.5=-2.474915 2=-4.88962 1=-6.02409 + qui recode `sf12p_7c' 1=4.61446 2=3.41593 3.5=1.811455 4.5=0.84616 6=0 + qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3.5=-6.344845 4.5=-3.274945 6=0 + } + qui gen `scoresf12p'=`sf12p_1'+`sf12p_2a'+`sf12p_2b'+`sf12p_3a'+`sf12p_3b'+`sf12p_4a'+`sf12p_4b'+`sf12p_5'+`sf12p_6'+`sf12p_7a'+`sf12p_7b'+`sf12p_7c'+56.57706 + qui gen `scoresf12m'=`sf12m_1'+`sf12m_2a'+`sf12m_2b'+`sf12m_3a'+`sf12m_3b'+`sf12m_4a'+`sf12m_4b'+`sf12m_5'+`sf12m_6'+`sf12m_7a'+`sf12m_7b'+`sf12m_7c'+60.75781 + +if "`save'"!="" { + local listmin pf rp bp gh vt sf re mh pcs mcs + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local error=0 + local list + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `save'`i' + if _rc==0&"`replace'"=="" { + local ++error + local list "`list' `save'`j'" + } + local ++c + } + local c=1 + if `error'==0 { + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `save'`i' + if _rc==0 { + qui replace `save'`i'=`score`i'' + } + else { + qui gen `save'`i'=`score`i'' + } + local ++c + } + } + else { + di in red "The variable(s) `list' already exist(s)" + } +} +tempname scoreref1 scoreref0 scoreref01 scoreref scorerefv1 scorerefv0 scorerefv01 scorerefv +matrix `scoreref1'=(96.65,95.80,86.82,82.36,67.86,89.76,93.14,72.85\95.75,91.16,83.60,76.07,64.50,86.50,90.64,72.08\94.41,90.76,81.03,73.13,64.32,86.37,89.07,71.01\92.27,88.64,79.02,72.27,66.06,86.69,90.00,71.53\82.32,79.81,70.21,65.97,60.19,83.33,83.00,71.10\76.58,74.74,67.10,62.37,58.21,79.74,80.04,71.16\67.16,61.28,63.99,58.61,53.93,76.16,66.67,70.24) +matrix `scoreref0'=(94.92,89.54,79.37,71.81,60.32,79.65,81.65,64.92\92.42,85.98,80.19,75.10,60.57,82.83,86.13,68.18\91.04,88.87,78.27,74.64,61.94,84.14,85.48,67.59\86.23,85.54,71.97,69.14,58.90,79.80,83.42,64.84\77.88,77.85,66.23,65.10,58.18,78.29,77.61,66.17\71.60,68.74,62.40,61.23,55.08,76.47,73.24,65.45\58.20,52.46,59.68,59.73,47.94,71.68,62.21,60.63) +matrix `scoreref01'=(95.65,92.18,82.51,76.26,63.52,83.93,86.47,68.29\93.93,88.34,81.75,75.54,62.35,84.51,88.19,69.94\92.71,89.80,79.63,73.89,63.12,85.24,87.26,69.28\89.25,87.09,75.50,70.70,62.48,83.24,86.71,68.19\79.99,78.78,68.12,65.51,59.14,80.69,80.19,68.52\73.69,71.24,64.37,61.71,56.39,77.84,76.05,67.84\62.40,56.67,61.72,59.20,50.86,73.80,64.38,65.29) +matrix `scoreref'=(84.45,81.21,73.39,69.13,59.96,81.55,82.13,68.47\87.07,83.86,75.98,70.07,62.23,84.08,85.41,71.42\82.22,78.96,71.18,68.33,58.03,79.41,79.34,65.96) +matrix `scorerefv1'=(11.78,15.33,17.21,13.93,14.16,14.43,20.73,15.28\9.64,21.30,19.63,15.89,16.72,19.05,24.18,15.83\11.08,23.63,21.00,16.20,16.65,18.97,26.12,16.70\14.92,26.35,22.09,17.41,16.24,17.01,23.15,16.23\20.48,32.67,22.24,17.93,16.89,20.35,32.04,17.40\22.78,36.05,24.06,19.08,18.03,21.94,33.89,16.60\27.44,40.86,24.38,17.61,18.86,24.08,41.43,20.03) +matrix `scorerefv0'=(9.10,21.65,21.66,17.69,18.10,22.35,29.58,17.32\14.19,28.28,21.28,16.66,18.28,20.57,28.19,18.06\14.81,25.19,21.25,17.64,18.55,20.97,29.37,17.92\19.11,29.40,23.90,18.60,17.84,21.44,31.24,16.66\21.49,33.02,24.10,18.78,18.22,23.46,34.89,18.03\23.42,38.17,23.94,17.67,17.59,22.46,37.41,18.21\25.70,39.18,23.40,18.08,17.98,24.06,39.97,18.98) +matrix `scorerefv01'=(10.33,19.46,20.21,17.00,16.94,20.00,26.80,16.83\12.44,25.45,20.60,16.31,17.69,19.96,16.51,17.18\13.19,24.43,21.15,16.95,17.66,20.02,27.85,17.40\17.39,27.92,23.25,18.06,17.41,19.64,27.65,16.76\21.11,32.83,23.29,18.37,17.61,22.16,33.63,17.88\23.27,37.40,24.09,18.28,17.83,22.29,36.13,17.77\26.85,40.16,23.92,17.83,18.62,24.13,40.67,20.04) +matrix `scorerefv'=(21.19,32.20,23.73,18.57,18.05,21.41,32.15,17.62\19.85,30.48,23.03,18.39,17.36,20.08,29.89,16.70\22.02,33.43,24.10,18.69,18.40,22.26,33.71,17.99) + +tempname scorerefpf scorerefrp scorerefbp scorerefgh scorerefvt scorerefsf scorerefre scorerefmh +tempname scorerefpfv scorerefrpv scorerefbpv scorerefghv scorerefvtv scorerefsfv scorerefrev scorerefmhv +if "`age'"!=""&"`sexe'"!="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref0'[1,`c'] if `sexe'==0&`age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref0'[2,`c'] if `sexe'==0&`age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref0'[3,`c'] if `sexe'==0&`age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref0'[4,`c'] if `sexe'==0&`age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref0'[5,`c'] if `sexe'==0&`age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref0'[6,`c'] if `sexe'==0&`age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref0'[7,`c'] if `sexe'==0&`age'>=75 + qui replace `scoreref`i''=`scoreref1'[1,`c'] if `sexe'==1&`age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref1'[2,`c'] if `sexe'==1&`age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref1'[3,`c'] if `sexe'==1&`age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref1'[4,`c'] if `sexe'==1&`age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref1'[5,`c'] if `sexe'==1&`age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref1'[6,`c'] if `sexe'==1&`age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref1'[7,`c'] if `sexe'==1&`age'>=75 + qui gen `scoreref`i'v'=(`scorerefv0'[1,`c'])^2 if `sexe'==0&`age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv0'[2,`c'])^2 if `sexe'==0&`age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv0'[3,`c'])^2 if `sexe'==0&`age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv0'[4,`c'])^2 if `sexe'==0&`age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv0'[5,`c'])^2 if `sexe'==0&`age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv0'[6,`c'])^2 if `sexe'==0&`age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv0'[7,`c'])^2 if `sexe'==0&`age'>=75 + qui replace `scoreref`i'v'=(`scorerefv1'[1,`c'])^2 if `sexe'==1&`age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv1'[2,`c'])^2 if `sexe'==1&`age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv1'[3,`c'])^2 if `sexe'==1&`age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv1'[4,`c'])^2 if `sexe'==1&`age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv1'[5,`c'])^2 if `sexe'==1&`age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv1'[6,`c'])^2 if `sexe'==1&`age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv1'[7,`c'])^2 if `sexe'==1&`age'>=75 + local ++c + } +} +else if "`age'"!=""&"`sexe'"=="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref01'[1,`c'] if `age'>=18&`age'<25 + qui replace `scoreref`i''=`scoreref01'[2,`c'] if `age'>=25&`age'<35 + qui replace `scoreref`i''=`scoreref01'[3,`c'] if `age'>=35&`age'<45 + qui replace `scoreref`i''=`scoreref01'[4,`c'] if `age'>=45&`age'<55 + qui replace `scoreref`i''=`scoreref01'[5,`c'] if `age'>=55&`age'<65 + qui replace `scoreref`i''=`scoreref01'[6,`c'] if `age'>=65&`age'<75 + qui replace `scoreref`i''=`scoreref01'[7,`c'] if `age'>=75 + qui gen `scoreref`i'v'=(`scorerefv01'[1,`c'])^2 if `age'>=18&`age'<25 + qui replace `scoreref`i'v'=(`scorerefv01'[2,`c'])^2 if `age'>=25&`age'<35 + qui replace `scoreref`i'v'=(`scorerefv01'[3,`c'])^2 if `age'>=35&`age'<45 + qui replace `scoreref`i'v'=(`scorerefv01'[4,`c'])^2 if `age'>=45&`age'<55 + qui replace `scoreref`i'v'=(`scorerefv01'[5,`c'])^2 if `age'>=55&`age'<65 + qui replace `scoreref`i'v'=(`scorerefv01'[6,`c'])^2 if `age'>=65&`age'<75 + qui replace `scoreref`i'v'=(`scorerefv01'[7,`c'])^2 if `age'>=75 + local ++c + } +} +else if "`age'"==""&"`sexe'"!="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + qui gen `scoreref`i''=`scoreref'[2,`c'] if `sexe'==1 + qui replace `scoreref`i''=`scoreref'[3,`c'] if `sexe'==0 + qui gen `scoreref`i'v'=(`scorerefv'[2,`c'])^2 if `sexe'==1 + qui replace `scoreref`i'v'=(`scorerefv'[3,`c'])^2 if `sexe'==0 + local ++c + } +} +else if "`age'"==""&"`sexe'"=="" { + local c=1 + foreach i in pf rp bp gh vt sf re mh { + gen `scoreref`i''=`scoreref'[1,`c'] + gen `scoreref`i'v'=(`scorerefv'[1,`c'])^2 + local ++c + } +} +tempname scorerefpfz scorerefrpz scorerefbpz scorerefghz scorerefvtz scorerefsfz scorerefrez scorerefmhz scorerefpcs scorerefmcs +tempname scorerefpfvz scorerefrpvz scorerefbpvz scorerefghvz scorerefvtvz scorerefsfvz scorerefrevz scorerefmhvz scorerefpcsv scorerefmcsv + +qui gen `scorerefpfz'=(`scorerefpf'-84.52404)/22.89490 +qui gen `scorerefrpz'=(`scorerefrp'-81.19907)/33.79729 +qui gen `scorerefbpz'=(`scorerefbp'-75.49196)/23.55879 +qui gen `scorerefghz'=(`scorerefgh'-72.21316)/20.16964 +qui gen `scorerefvtz'=(`scorerefvt'-61.05453)/20.86942 +qui gen `scorerefsfz'=(`scorerefsf'-83.59753)/22.37649 +qui gen `scorerefrez'=(`scorerefre'-81.29467)/33.02717 +qui gen `scorerefmhz'=(`scorerefmh'-74.84212)/18.01189 +qui gen `scorerefpcs'=(`scorerefpfz'*0.42402+`scorerefrpz'*0.35119+`scorerefbpz'*0.31754+`scorerefghz'*0.24954+`scorerefvtz'*0.02877-`scorerefsfz'*0.0753-`scorerefrez'*0.19206-`scorerefmhz'*0.22069)*10+50 +qui gen `scorerefmcs'=(-`scorerefpfz'*0.22999-`scorerefrpz'*0.12329-`scorerefbpz'*0.09731-`scorerefghz'*0.01571+`scorerefvtz'*0.23534+`scorerefsfz'*0.26876+`scorerefrez'*0.43407+`scorerefmhz'*0.48581)*10+50 + +qui gen `scorerefpfvz'=(`scorerefpfv')/22.89490^2 +qui gen `scorerefrpvz'=(`scorerefrpv')/33.79729^2 +qui gen `scorerefbpvz'=(`scorerefbpv')/23.55879^2 +qui gen `scorerefghvz'=(`scorerefghv')/20.16964^2 +qui gen `scorerefvtvz'=(`scorerefvtv')/20.86942^2 +qui gen `scorerefsfvz'=(`scorerefsfv')/22.37649^2 +qui gen `scorerefrevz'=(`scorerefrev')/33.02717^2 +qui gen `scorerefmhvz'=(`scorerefmhv')/18.01189^2 +qui gen `scorerefpcsv'=(`scorerefpfvz'*0.42402^2+`scorerefrpvz'*0.35119^2+`scorerefbpvz'*0.31754^2+`scorerefghvz'*0.24954^2+`scorerefvtvz'*0.02877^2-`scorerefsfvz'*0.0753^2-`scorerefrevz'*0.19206^2-`scorerefmhvz'*0.22069^2)*10^2 +qui gen `scorerefmcsv'=(-`scorerefpfvz'*0.22999^2-`scorerefrpvz'*0.12329^2-`scorerefbpvz'*0.09731^2-`scorerefghvz'*0.01571^2+`scorerefvtvz'*0.23534^2+`scorerefsfvz'*0.26876^2+`scorerefrevz'*0.43407^2+`scorerefmhvz'*0.48581^2)*10^2 + + + + + +if "`saveref'"!="" { + local listmin pf rp bp gh vt sf re mh pcs mcs + local listmaj PF RP BP GH VT SF RE MH PCS MCS + local error=0 + local list + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `saveref'`i' + if _rc==0&"`replace'"=="" { + local ++error + local list "`list' `saveref'`j'" + } + local ++c + } + local c=1 + if `error'==0 { + foreach i in `listmin' { + local j:word `c' of `listmaj' + capture confirm variable `saveref'`i' + if _rc==0 { + qui replace `saveref'`i'=`scoreref`i'' + } + else { + qui gen `saveref'`i'=`scoreref`i'' + } + local ++c + } + } + else { + di in red "The variable(s) `list' already exist(s)" + } +} + +if "`details'"!="" { + di "{hline 80}" + di in gr _col(12) "Sample" _col(51) "Reference" + di in gr "Dimension" _col(16) "N" _col(21) "Mean" _col(29) "s.d." _col(40) "Min-Max" _col(52) "Mean" _col(60) "s.d." _col(72) "p" + di "{hline 80}" + local listmin pf rp bp gh vt sf re mh pcs mcs sf12p sf12m + local listmaj PF RP BP GH VT SF RE MH PCS MCS SF12P SF12M + local c=1 + foreach i in `listmin' { + local j:word `c' of `listmaj' + qui su `score`i'' + local means`i'=r(mean) + local sds`i'=r(sd) + local mins`i'=r(min) + local maxs`i'=r(max) + local n`i'=r(N) + if "`i'"!="sf12p"&"`i'"!="sf12m" { + qui su `scoreref`i'' if `score`i''!=. + local meanr`i'=r(mean) + local sdr`i'=r(sd) + local vr`i'=(`sdr`i'')^2 + qui su `scoreref`i'v' if `score`i''!=. + local meanvr`i'=r(mean) + local sdr`i'=sqrt(`vr`i''+`meanvr`i'') + *local minr`i'=r(min) + *local maxr`i'=r(max) + qui ttest `score`i''=`meanr`i'' + local p`i'=r(p) + } + di in gr "`j'" in ye _col(12) %5.0f `n`i'' _col(20) %5.2f `means`i'' _col(28) %5.2f `sds`i'' _col(34) %6.2f `mins`i'' "-" %6.2f `maxs`i'' _col(51) %5.2f `meanr`i'' _col(59) %5.2f `sdr`i'' _col(67) %6.4f `p`i'' + local ++c + } + di "{hline 80}" + *corr `scorepcs' `scoremcs' `scoresf12p' `scoresf12m' + *scatter `scorepcs' `scoresf12p' ,name(p) + *scatter `scoremcs' `scoresf12m' ,name(m) + *su `scoresf12p' `sf12p_1' `sf12p_2a' `sf12p_2b' `sf12p_3a' `sf12p_3b' `sf12p_4a' `sf12p_4b' `sf12p_5' `sf12p_6' `sf12p_7a' `sf12p_7b' `sf12p_7c' + *su `scoresf12m' `sf12m_1' `sf12m_2a' `sf12m_2b' `sf12m_3a' `sf12m_3b' `sf12m_4a' `sf12m_4b' `sf12m_5' `sf12m_6' `sf12m_7a' `sf12m_7b' `sf12m_7c' + +} +if "`saveimp'"!="" { +*su + foreach i of numlist 1 3/36 { + local j:word `i' of `varlistsav' + *di "gen `saveimp'`j'=`imp'``i''" + capture confirm variable `saveimp'`j' + if _rc==0&"`replace'"=="" { + di in ye "The variable `saveimp'`j' already exists and cannot be replaced." + } + else if _rc==0&"`replace'"!="" { + qui replace `saveimp'`j'=`imp'``i'' + } + else { + qui gen `saveimp'`j'=`imp'``i'' + } + } +} +end diff --git a/Modules/ado/personal/s/simirt - Copie.ado b/Modules/ado/personal/s/simirt - Copie.ado new file mode 100644 index 0000000..225fed2 --- /dev/null +++ b/Modules/ado/personal/s/simirt - Copie.ado @@ -0,0 +1,762 @@ +*! version 4.3 August 29, 2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model, +* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM) +* +* Version 1 : May 9, 2005 (Jean-Benoit Hardouin) +* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/ +* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/ +* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/ +* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/ +* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/ +* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/ +* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/ +* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/ +* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/ +* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/ +* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/ +* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/ +* Version 4 : December 11, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*GPCM + genp, genicc, icc options*/ +* Version 4.1 : December 17, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*drawall option*/ +* Version 4.2 : June 19, 2018 (Jean-Benoit Hardouin) /*correction of a small bug with rsm2 option*/ +* Version 4.3 : August 29, 2019 (Jean-Benoit Hardouin) /*correction of a small bug with store option*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* +* Copyright 2005-2006, 2008-2009, 2011, 20130 2018, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define simirt , rclass +version 8.0 +syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW drawall ICC GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string) GENProba GENIcc] + + +/******************************************************************************** +TESTS +********************************************************************************/ + + +if `group'<0|`group'>1 { + di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}" + error 198 + exit +} + +if "`clear'"==""&"`store'"=="" { + di in red "You must use at least one of these two options: clear and/or store." + error 198 + exit +} + +if "`dim'"!="" { + local nbdim:word count `dim' + if `nbdim'>2&"`covmatrix'"=="" { + di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it." + error 198 + exit + } + if "`covmatrix'"!="" { + local nbrowcovm=rowsof(`covmatrix') + if `nbdim'!=`nbrowcovm' { + di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that." + error 198 + exit + } + } + local nbitems=0 + forvalues d=1/`nbdim' { + local dim`d':word `d' of `dim' + local nbitems=`nbitems'+`dim`d'' + } + local dim=`nbdim' + + if "`diff'"!="" { + local nbdiff:word count `diff' + local tmp:word 1 of `diff' + if "`tmp'"=="gauss"|"`tmp'"=="uniform" { + local typediff values + } + else if `nbdiff'!=`nbitems' { + di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options." + error 198 + exit + } + } + else if "`diff'"=="" { + local diff gauss + forvalues d=1/`dim' { + local diff `diff' 0 1 + } + local typediff gauss + local nbdiff:word count `diff' + } +} +else if "`dim'"==""{ + if "`diff'"==""&"`pcm'"=="" { + di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)." + error 198 + exit + } + else if "`covmatrix'"!= "" { + local nbrowcovm=rowsof(`covmatrix') + if `nbrowcovm'>1 { + di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option." + error 198 + exit + } + } + else if "`pcm'"!="" { + local nbitems=rowsof(`pcm') + local dim=1 + local dim1=`nbitems' + } + else { + local nbdiff:word count `diff' + local nbitems=`nbdiff' + local dim=1 + local dim1=`nbitems' + } +} + +if (`group'!=0|`deltagroup'!=0)&`dim'!=1 { + di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data." + error 198 + exit +} + +if "`prefix'"=="" { + local prefix item +} + +local nbprefix:word count `prefix' +if `nbprefix'!=`dim'&`nbprefix'!=1 { + di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it." + error 198 + exit +} +if `nbprefix'==`dim' { + forvalues d=1/`dim' { + local prefix`d':word `d' of `prefix' + } +} +else { + forvalues d=1/`dim' { + local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + local prefix`d' `prefix'`tmp' + } +} +if "`covmatrix'"=="" { + tempname covmatrix2 + local nbcov:word count `cov' + + if `dim'==1 { + if "`cov'"=="" { + local cov=1 + } + if `nbcov'>1 { + di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option." + error 198 + exit + } + if `cov'<0 { + di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option." + error 198 + } + matrix `covmatrix2'=(`cov') + } + else if `dim'==2 { + if `nbcov'!=3&`nbcov'>0 { + di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)." + error 198 + exit + } + else if `nbcov'==0 { + if `dim'==1 { + local cov "1" + } + else if `dim'==2 { + local cov "1 1 0" + } + local nbcov:word count `cov' + } + if `nbcov'==3 { + local cov1:word 1 of `cov' + local cov2:word 2 of `cov' + local cov3:word 3 of `cov' + local rho=`cov3'/sqrt(`cov1'*`cov2') + if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 { + di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it." + error 198 + exit + } + } + matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2') + } + local covmatrix `covmatrix2' +} + +local nbmu:word count `mu' +if `nbmu'!=`dim'&`nbmu'!=0 { + di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')" + error 198 + exit +} +local nbdisc:word count `disc' +if `nbdisc'!=`nbitems'&`nbdisc'!=0 { + di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmin:word count `pmin' +if `nbpmin'!=`nbitems'&`nbpmin'!=0 { + di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmax:word count `pmax' +if `nbpmax'!=`nbitems'&`nbpmax'!=0 { + di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbacc:word count `acc' +if `nbacc'!=`nbitems'&`nbacc'!=0 { + di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} + +if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`pcm'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:pcm} option, you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`pcm'"!="") { + di in red "You cannot use in the same time the {hi:rsm1} and/or {hi:rsm2} options with the {hi:pcm} option" + error 198 + exit +} +if "`rsm2'"!=""&`dim'==1 { + di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension" + error 198 + exit +} +if "`id'"=="" { + local id="id" +} + +preserve + +tempfile saveraschbin +capture qui save `saveraschbin' + + + + +/******************************************************************************** +PARAMETERS +********************************************************************************/ + + +local hour=real(substr("$S_TIME",1,2)) +local min=real(substr("$S_TIME",4,2)) +local sec=real(substr("$S_TIME",7,2)) +local jour=real(substr("$S_DATE",1,2)) + + + + +if "$seed"!="" { + global seed2=int($seed) +} +else { + global seed2=0 +} +global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour' +while $seed>2^31-1 { + global seed=int($seed/231) +} +qui set seed $seed + +if "`typediff'"=="uniform" { + if `nbdiff'==`=`dim'*2+1' { + local min`d':word `=(`d'-1)*2+2' of `diff' + local max`d':word `=(`d'-1)*2+3' of `diff' + } + else if `nbdiff'==1 { + local min`d'=-2 + local max`d'=2 + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)' + } + } +} +else if "`typediff'"=="gauss" { + if `nbdiff'==`=`dim'*2+1' { + forvalues d=1/`dim' { + local mean`d':word `=(`d'-1)*2+2' of `diff' + local var`d':word `=(`d'-1)*2+3' of `diff' + } + } + else if `nbdiff'==1 { + forvalues d=1/`dim' { + local mean`d'=0 + local var`d'=1 + } + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + error 198 + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d'' + local diff `diff' `tmp' + } + } +} + +forvalues d=1/`dim' { + if "`rsm`d''"!="" { + local nbrsm`d':word count `rsm`d'' + forvalues i=2/`=`nbrsm`d''+1' { + local rsm`d'`i':word `=`i'-1' of `rsm`d'' + if "`threshold'"!=""&`rsm`d'`i''<0 { + di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive." + error 198 + exit + } + } + } +} +if "`diff'"!=""&"`pcm'"=="" { + tempname pcm + qui matrix `pcm'=J(`nbitems',1,.) + forvalues j=1/`nbitems' { + local tmp:word `j' of `diff' + qui matrix `pcm'[`j',1]=`tmp' + } +} + + +tempname matmu matcov matdiff matdisc matpmin matpmax matacc +matrix define `matdiff'=J(`nbitems',1,0) +matrix define `matdisc'=J(`nbitems',1,0) +matrix define `matpmin'=J(`nbitems',1,0) +matrix define `matpmax'=J(`nbitems',1,0) +matrix define `matacc'=J(`nbitems',1,0) +matrix define `matmu'=J(`dim',1,0) +matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0) + +forvalues i=1/`nbitems'{ + if `nbdisc'!=0 { + local tmp:word `i' of `disc' + matrix `matdisc'[`i',1]=`tmp' + } + else { + matrix `matdisc'[`i',1]=1 + } +} + +if "`pcm'"==""|"`rsm1'"!="" { + tempname pcm + if "`rsm1'"=="" { + forvalues i=1/`nbitems' { + local tmp:word `i' of `diff' + matrix `matdiff'[`i',1]=`tmp' + } + matrix `pcm'=`matdiff' + } + else { + local moda1:word count `rsm1' + local moda2:word count `rsm2' + local nbmodas=max(`=`moda1'+1',`=`moda2'+1') + matrix `pcm'=J(`nbitems',`nbmodas',.) + forvalues i=1/`dim1' { + local tmp:word `i' of `diff' + matrix `pcm'[`i',1]=`tmp' + forvalues j=1/`=`nbmodas'-1' { + local tmp:word `j' of `rsm1' + matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp' + } + } + if "`rsm2'"!="" { + forvalues i=`=`dim1'+1'/`=`dim1'+`dim2'' { + local tmp:word `i' of `diff' + matrix `pcm'[`i',1]=`tmp' + forvalues j=1/`=`nbmodas'-1' { + local tmp:word `j' of `rsm2' + matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp' + } + } + } + } +} +local nbmodas=colsof(`pcm') +forvalues j=1/`nbitems' { + local pcmpj`j'k0=-999999999999999 + forvalues k=1/`nbmodas' { + local pcmpj`j'k`k'=`pcm'[`j',`k'] + if `pcmpj`j'k`k''!=. { + local nbmodas`j'=`k' + } + local tmp=`k'-1 + if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' { + di in red "With the {hi:threshold} option, the difficulties of a given item must increase." + error 198 + exit + } + } +} + + +forvalues i=1/`nbitems' { + if `nbpmin'!=0 { + local tmp:word `i' of `pmin' + matrix `matpmin'[`i',1]=`tmp' + } + else { + matrix `matpmin'[`i',1]=0 + } + if `nbpmax'!=0 { + local tmp:word `i' of `pmax' + matrix `matpmax'[`i',1]=`tmp' + } + else { + matrix `matpmax'[`i',1]=1 + } + if `nbacc'!=0 { + local tmp:word `i' of `acc' + matrix `matacc'[`i',1]=`tmp' + } + else { + matrix `matacc'[`i',1]=1 + } +} + +if "`covmatrix'"=="" { + tempname covmatrix + if `nbcov'==1 { + matrix `covmatrix'=(`cov') + } + if `nbcov'==3 { + local tmp1:word 1 of `cov' + local tmp2:word 2 of `cov' + local tmp12:word 3 of `cov' + matrix `covmatrix'=(`tmp1',`tmp12'\`tmp12',`tmp2') + } +} +matrix `matcov'=`covmatrix' +if (`nbmu'==`dim') { + forvalues d=1/`dim' { + local tmp:word `d' of `mu' + matrix `matmu'[`d',1]=`tmp' + } +} +if `dim'==2 { + local corr=`covmatrix'[1,2]/sqrt(`covmatrix'[1,1]*`covmatrix'[2,2]) +} + + + +/******************************************************************************** +SIMULATION +********************************************************************************/ + + +drop _all +qui set obs `=`nbobs'+2001' +qui gen `id'=_n +tempname graphobs +qui gen `graphobs'=`id'>`nbobs' +local names +forvalues d=1/`dim' { + qui gen x`d'=invnorm(uniform()) + qui compress + local names `names' lt`d' +} + +matrix Chol=cholesky(corr(`covmatrix')) +forvalues d=1/`dim' { + qui gen lt`d'=0 + forvalues i=1/`d' { + qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i' + } + qui compress +} +qui drop x* +forvalues d=1/`dim' { + qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1] + qui compress +} +qui replace lt1=_n-`nbobs' if `graphobs' +qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] if `graphobs' + +if `dim'==1&`group'!=0 { + if "`random'"=="" { + qui gen group=uniform()<`group' + } + else { + qui gen group=`id'<=`group'*`nbobs' + } + qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1 + qui replace lt1=lt1-`deltagroup'*`group' if group==0 + qui compress +} + +di in gr "Number of individuals: " in ye `nbobs' +di + +if "`threshold'"=="" { + local line di in gr "{hline 75}" +} +else { + local line di in gr "{hline 27}" +} + +if "`threshold'"=="" { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc" +} +else { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" +} +local dim0=0 +local deb1=1 +local fin0=0 +local fin1=`dim1' + +forvalues d=1/`dim' { /* FOREACH DIMENSION*/ + local deb`d'=`fin`=`d'-1''+1 + local fin`d'=`deb`d''+`dim`d''-1 + `line' + local p=`d'-1 + local q=1 + forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/ + qui compress + tempname prob`i'_`=`nbmodas`i''+1' + qui gen `prob`i'_`=`nbmodas`i''+1''=0 + local tau0=0 + local tau1=`pcm'[`i',1] + local D "1+exp(`matdisc'[`i',1]*(lt`d'-`tau1'))" + forvalues k=2/`nbmodas`i'' { + local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k'] + local D "`D'+exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k'')) " + } + if "`threshold'"=="" { + tempname icc`i' + qui gen `icc`i''=0 + tempname proba`i'_0 + gen `proba`i'_0'=1 + forvalues k=`nbmodas`i''(-1)1 { + tempname prob`i'_`k' proba`i'_`k' + qui gen `proba`i'_`k''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k''))/(`D'))^`matacc'[`i',1] + qui replace `proba`i'_0'=`proba`i'_0'-`proba`i'_`k'' + qui gen `prob`i'_`k''=`proba`i'_`k''+`prob`i'_`=`k'+1'' + qui replace `icc`i''=`icc`i''+`k'*`proba`i'_`k'' + qui compress + if "`genproba'"!="" { + qui gen proba`i'_`k'=`prob`i'_`k''-`prob`i'_`=`k'+1'' + } + } + if "`genicc'"!="" { + qui gen icc`i'=`icc`i'' + } + qui gen `prefix`d''`q'=0 + di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `pcm'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1] + forvalues k=2/`nbmodas`i'' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + } + tempname uni + qui gen `uni'=uniform() + forvalues k=1/`nbmodas`i'' { + qui replace `prefix`d''`q'=`k' if `uni'<=`prob`i'_`k'' + qui compress + } + } + else { /*if "`threshold'"!=""*/ + qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1] + local tmp=0 + forvalues k=1/`nbmodas`i'' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + local tmp=`tmp'+`pcm'[`i',`k'] + qui replace `prefix`d''`q'=`k' if lt`d'>`tmp' + qui compress + } + } + local q=`q'+1 + } +} +`line' +di + + +/******************************************************************************** +CATEGORIES PROBABILITY CURVES and ITEMS CHARACTERISTIC CURVES +********************************************************************************/ + +set tracedepth 1 +if "`draw'"!=""|"`icc'"!=""|"`drawall'"!="" { + label variable lt1 "Latent trait" + local dess + sort lt1 + + if "`draw'"!=""|"`drawall'"!="" { + local alldess + forvalues i=1/`dim1' { + if "`title'"=="" { + local title2="Category Probability Curves of the Item `i'" + } + else { + local title2="`title'" + } + local dess + local tauj`j'k0=0 + forvalues k=`nbmodas`i''(-1)0 { + local dess `dess' (line `proba`i'_`k'' lt1) + label variable `proba`i'_`k'' "`k'" + } + graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace) + local alldess `alldess' `dess' + } + if "`drawall'"!="" { + graph twoway `alldess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(all,replace) + } + } + if "`icc'"!="" { + local hicc + forvalues i=1/`dim1' { + if "`titleicc'"=="" { + local title3="Item Characteristic Curve of the Item `i'" + } + else { + local title3="`title'" + } + graph twoway (line `icc`i'' lt1) if `graphobs', ylabel(0(1)`nbmodas') legend(off) ytitle("Expected response") title("`title3'") name(iccitem`i',replace) + local hicc `hicc' (line `icc`i'' lt1) + label variable `icc`i'' "Item `i'" + } + graph twoway `hicc' if `graphobs', ylabel(0(1)`nbmodas') legend(on) ytitle("Expected response") title("Item Characteristic Curves") name(icc,replace) + } +} +qui drop if `graphobs' + + +/******************************************************************************** +DISPLAYING +********************************************************************************/ + +forvalues d=1/`dim' { + qui su lt`d' + local var_`d'=r(Var) + local mean_`d'=r(mean) + forvalues l=`=`d'+1'/`dim' { + qui corr lt`d' lt`l' ,cov + local cov_`d'_`l'=r(cov_12) + return scalar cov_`d'_`l'=`cov_`d'_`l'' + } + return scalar mean_`d'=`mean_`d'' + return scalar var_`d'=`var_`d'' +} +forvalues d=1/`dim' { + forvalues l=`=`d'+1'/`dim' { + local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'') + return scalar corr_`d'_`l'=`corr_`d'_`l'' + } +} + + +if `dim'==1&`group'!=0 { + qui su lt1 if group==0 + local mean_0=r(mean) + qui su lt1 if group==1 + local mean_1=r(mean) + local delta=`mean_1'-`mean_0' +} + +return scalar nbobs=`nbobs' +tempname matcorr +matrix `matcorr'=corr(`matcov') + +di in gr "{hline 50}" +di _col(1) in gr "Latent trait" _c +if `dim'==2 { + di in gr "s"_c +} +di in gr _col(30) "Expected" _col(42) "Observed" +di in gr "{hline 50}" +forvalues i=1/`dim' { + di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i'' + di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i'' + forvalues d=`=`i'+1'/`dim' { + di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d'' + di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d'' + } + di in gr "{hline 50}" +} +if `dim'==1&`group'!=0 { + di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0' + di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1' + qui count if group==1 + local prop=r(N)/`nbobs' + di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop' + di in gr "{hline 50}" +} + +/******************************************************************************** +CLEAR AND/OR STORE +********************************************************************************/ +qui compress + +if "`clear'"!="" { + restore, not + preserve +} +if "`store'"!="" { + save "`store'",`replace' +} +if "`clear'"=="" { + capture use "`saveraschbin'",replace +} +end diff --git a/Modules/ado/personal/s/simirt v4.1.ado b/Modules/ado/personal/s/simirt v4.1.ado new file mode 100644 index 0000000..8c6c858 --- /dev/null +++ b/Modules/ado/personal/s/simirt v4.1.ado @@ -0,0 +1,760 @@ +*! version 4.1 December 17, 2013 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model, +* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM) +* +* Version 1 : May 9, 2005 (Jean-Benoit Hardouin) +* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/ +* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/ +* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/ +* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/ +* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/ +* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/ +* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/ +* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/ +* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/ +* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/ +* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/ +* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/ +* Version 4 : December 11, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*GPCM + genp, genicc, icc options*/ +* Version 4.1 : December 17, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*drawall option*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* +* Copyright 2005-2006, 2008-2009, 2011, 2013 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define simirt , rclass +version 8.0 +syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW drawall ICC GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string) GENProba GENIcc] + + +/******************************************************************************** +TESTS +********************************************************************************/ + + +if `group'<0|`group'>1 { + di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}" + error 198 + exit +} + +if "`clear'"==""&"`store'"=="" { + di in red "You must use at least one of these two options: clear and/or store." + error 198 + exit +} + +if "`dim'"!="" { + local nbdim:word count `dim' + if `nbdim'>2&"`covmatrix'"=="" { + di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it." + error 198 + exit + } + if "`covmatrix'"!="" { + local nbrowcovm=rowsof(`covmatrix') + if `nbdim'!=`nbrowcovm' { + di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that." + error 198 + exit + } + } + local nbitems=0 + forvalues d=1/`nbdim' { + local dim`d':word `d' of `dim' + local nbitems=`nbitems'+`dim`d'' + } + local dim=`nbdim' + + if "`diff'"!="" { + local nbdiff:word count `diff' + local tmp:word 1 of `diff' + if "`tmp'"=="gauss"|"`tmp'"=="uniform" { + local typediff values + } + else if `nbdiff'!=`nbitems' { + di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options." + error 198 + exit + } + } + else if "`diff'"=="" { + local diff gauss + forvalues d=1/`dim' { + local diff `diff' 0 1 + } + local typediff gauss + local nbdiff:word count `diff' + } +} +else if "`dim'"==""{ + if "`diff'"==""&"`pcm'"=="" { + di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)." + error 198 + exit + } + else if "`covmatrix'"!= "" { + local nbrowcovm=rowsof(`covmatrix') + if `nbrowcovm'>1 { + di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option." + error 198 + exit + } + } + else if "`pcm'"!="" { + local nbitems=rowsof(`pcm') + local dim=1 + local dim1=`nbitems' + } + else { + local nbdiff:word count `diff' + local nbitems=`nbdiff' + local dim=1 + local dim1=`nbitems' + } +} + +if (`group'!=0|`deltagroup'!=0)&`dim'!=1 { + di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data." + error 198 + exit +} + +if "`prefix'"=="" { + local prefix item +} + +local nbprefix:word count `prefix' +if `nbprefix'!=`dim'&`nbprefix'!=1 { + di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it." + error 198 + exit +} +if `nbprefix'==`dim' { + forvalues d=1/`dim' { + local prefix`d':word `d' of `prefix' + } +} +else { + forvalues d=1/`dim' { + local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + local prefix`d' `prefix'`tmp' + } +} +if "`covmatrix'"=="" { + tempname covmatrix2 + local nbcov:word count `cov' + + if `dim'==1 { + if "`cov'"=="" { + local cov=1 + } + if `nbcov'>1 { + di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option." + error 198 + exit + } + if `cov'<0 { + di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option." + error 198 + } + matrix `covmatrix2'=(`cov') + } + else if `dim'==2 { + if `nbcov'!=3&`nbcov'>0 { + di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)." + error 198 + exit + } + else if `nbcov'==0 { + if `dim'==1 { + local cov "1" + } + else if `dim'==2 { + local cov "1 1 0" + } + local nbcov:word count `cov' + } + if `nbcov'==3 { + local cov1:word 1 of `cov' + local cov2:word 2 of `cov' + local cov3:word 3 of `cov' + local rho=`cov3'/sqrt(`cov1'*`cov2') + if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 { + di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it." + error 198 + exit + } + } + matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2') + } + local covmatrix `covmatrix2' +} + +local nbmu:word count `mu' +if `nbmu'!=`dim'&`nbmu'!=0 { + di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')" + error 198 + exit +} +local nbdisc:word count `disc' +if `nbdisc'!=`nbitems'&`nbdisc'!=0 { + di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmin:word count `pmin' +if `nbpmin'!=`nbitems'&`nbpmin'!=0 { + di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmax:word count `pmax' +if `nbpmax'!=`nbitems'&`nbpmax'!=0 { + di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbacc:word count `acc' +if `nbacc'!=`nbitems'&`nbacc'!=0 { + di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} + +if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`pcm'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:pcm} option, you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`pcm'"!="") { + di in red "You cannot use in the same time the {hi:rsm1} and/or {hi:rsm2} options with the {hi:pcm} option" + error 198 + exit +} +if "`rsm2'"!=""&`dim'==1 { + di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension" + error 198 + exit +} +if "`id'"=="" { + local id="id" +} + +preserve + +tempfile saveraschbin +capture qui save `saveraschbin' + + + + +/******************************************************************************** +PARAMETERS +********************************************************************************/ + + +local hour=real(substr("$S_TIME",1,2)) +local min=real(substr("$S_TIME",4,2)) +local sec=real(substr("$S_TIME",7,2)) +local jour=real(substr("$S_DATE",1,2)) + + + + +if "$seed"!="" { + global seed2=int($seed) +} +else { + global seed2=0 +} +global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour' +while $seed>2^31-1 { + global seed=int($seed/231) +} +qui set seed $seed + +if "`typediff'"=="uniform" { + if `nbdiff'==`=`dim'*2+1' { + local min`d':word `=(`d'-1)*2+2' of `diff' + local max`d':word `=(`d'-1)*2+3' of `diff' + } + else if `nbdiff'==1 { + local min`d'=-2 + local max`d'=2 + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)' + } + } +} +else if "`typediff'"=="gauss" { + if `nbdiff'==`=`dim'*2+1' { + forvalues d=1/`dim' { + local mean`d':word `=(`d'-1)*2+2' of `diff' + local var`d':word `=(`d'-1)*2+3' of `diff' + } + } + else if `nbdiff'==1 { + forvalues d=1/`dim' { + local mean`d'=0 + local var`d'=1 + } + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + error 198 + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d'' + local diff `diff' `tmp' + } + } +} + +forvalues d=1/`dim' { + if "`rsm`d''"!="" { + local nbrsm`d':word count `rsm`d'' + forvalues i=2/`=`nbrsm`d''+1' { + local rsm`d'`i':word `=`i'-1' of `rsm`d'' + if "`threshold'"!=""&`rsm`d'`i''<0 { + di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive." + error 198 + exit + } + } + } +} +if "`diff'"!=""&"`pcm'"=="" { + tempname pcm + qui matrix `pcm'=J(`nbitems',1,.) + forvalues j=1/`nbitems' { + local tmp:word `j' of `diff' + qui matrix `pcm'[`j',1]=`tmp' + } +} + + +tempname matmu matcov matdiff matdisc matpmin matpmax matacc +matrix define `matdiff'=J(`nbitems',1,0) +matrix define `matdisc'=J(`nbitems',1,0) +matrix define `matpmin'=J(`nbitems',1,0) +matrix define `matpmax'=J(`nbitems',1,0) +matrix define `matacc'=J(`nbitems',1,0) +matrix define `matmu'=J(`dim',1,0) +matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0) + +forvalues i=1/`nbitems'{ + if `nbdisc'!=0 { + local tmp:word `i' of `disc' + matrix `matdisc'[`i',1]=`tmp' + } + else { + matrix `matdisc'[`i',1]=1 + } +} + +if "`pcm'"==""|"`rsm1'"!="" { + tempname pcm + if "`rsm1'"=="" { + forvalues i=1/`nbitems' { + local tmp:word `i' of `diff' + matrix `matdiff'[`i',1]=`tmp' + } + matrix `pcm'=`matdiff' + } + else { + local moda1:word count `rsm1' + local moda2:word count `rsm2' + local nbmodas=max(`=`moda1'+1',`=`moda2'+1') + matrix `pcm'=J(`nbitems',`nbmodas',.) + forvalues i=1/`dim1' { + local tmp:word `i' of `diff' + matrix `pcm'[`i',1]=`tmp' + forvalues j=1/`=`nbmodas'-1' { + local tmp:word `j' of `rsm1' + matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp' + } + } + if "`rsm2'"!="" { + forvalues i=`dim1'+1/`=`dim1'+`dim2'' { + local tmp:word `i' of `diff' + matrix `pcm'[`i',1]=`tmp' + forvalues j=1/`=`modamax'-1' { + local tmp:word `j' of `rsm2' + matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp' + } + } + } + } +} +local nbmodas=colsof(`pcm') +forvalues j=1/`nbitems' { + local pcmpj`j'k0=-999999999999999 + forvalues k=1/`nbmodas' { + local pcmpj`j'k`k'=`pcm'[`j',`k'] + if `pcmpj`j'k`k''!=. { + local nbmodas`j'=`k' + } + local tmp=`k'-1 + if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' { + di in red "With the {hi:threshold} option, the difficulties of a given item must increase." + error 198 + exit + } + } +} + + +forvalues i=1/`nbitems' { + if `nbpmin'!=0 { + local tmp:word `i' of `pmin' + matrix `matpmin'[`i',1]=`tmp' + } + else { + matrix `matpmin'[`i',1]=0 + } + if `nbpmax'!=0 { + local tmp:word `i' of `pmax' + matrix `matpmax'[`i',1]=`tmp' + } + else { + matrix `matpmax'[`i',1]=1 + } + if `nbacc'!=0 { + local tmp:word `i' of `acc' + matrix `matacc'[`i',1]=`tmp' + } + else { + matrix `matacc'[`i',1]=1 + } +} + +if "`covmatrix'"=="" { + tempname covmatrix + if `nbcov'==1 { + matrix `covmatrix'=(`cov') + } + if `nbcov'==3 { + local tmp1:word 1 of `cov' + local tmp2:word 2 of `cov' + local tmp12:word 3 of `cov' + matrix `covmatrix'=(`tmp1',`tmp12'\`tmp12',`tmp2') + } +} +matrix `matcov'=`covmatrix' +if (`nbmu'==`dim') { + forvalues d=1/`dim' { + local tmp:word `d' of `mu' + matrix `matmu'[`d',1]=`tmp' + } +} +if `dim'==2 { + local corr=`covmatrix'[1,2]/sqrt(`covmatrix'[1,1]*`covmatrix'[2,2]) +} + + + +/******************************************************************************** +SIMULATION +********************************************************************************/ + + +drop _all +qui set obs `=`nbobs'+2001' +qui gen `id'=_n +tempname graphobs +qui gen `graphobs'=`id'>`nbobs' +local names +forvalues d=1/`dim' { + qui gen x`d'=invnorm(uniform()) + qui compress + local names `names' lt`d' +} + +matrix Chol=cholesky(corr(`covmatrix')) +forvalues d=1/`dim' { + qui gen lt`d'=0 + forvalues i=1/`d' { + qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i' + } + qui compress +} +qui drop x* +forvalues d=1/`dim' { + qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1] + qui compress +} +qui replace lt1=_n-`nbobs' if `graphobs' +qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] if `graphobs' + +if `dim'==1&`group'!=0 { + if "`random'"=="" { + qui gen group=uniform()<`group' + } + else { + qui gen group=`id'<=`group'*`nbobs' + } + qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1 + qui replace lt1=lt1-`deltagroup'*`group' if group==0 + qui compress +} + +di in gr "Number of individuals: " in ye `nbobs' +di + +if "`threshold'"=="" { + local line di in gr "{hline 75}" +} +else { + local line di in gr "{hline 27}" +} + +if "`threshold'"=="" { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc" +} +else { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" +} +local dim0=0 +local deb1=1 +local fin0=0 +local fin1=`dim1' + +forvalues d=1/`dim' { /* FOREACH DIMENSION*/ + local deb`d'=`fin`=`d'-1''+1 + local fin`d'=`deb`d''+`dim`d''-1 + `line' + local p=`d'-1 + local q=1 + forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/ + qui compress + tempname prob`i'_`=`nbmodas`i''+1' + qui gen `prob`i'_`=`nbmodas`i''+1''=0 + local tau0=0 + local tau1=`pcm'[`i',1] + local D "1+exp(`matdisc'[`i',1]*(lt`d'-`tau1'))" + forvalues k=2/`nbmodas`i'' { + local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k'] + local D "`D'+exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k'')) " + } + if "`threshold'"=="" { + tempname icc`i' + qui gen `icc`i''=0 + tempname proba`i'_0 + gen `proba`i'_0'=1 + forvalues k=`nbmodas`i''(-1)1 { + tempname prob`i'_`k' proba`i'_`k' + qui gen `proba`i'_`k''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k''))/(`D'))^`matacc'[`i',1] + qui replace `proba`i'_0'=`proba`i'_0'-`proba`i'_`k'' + qui gen `prob`i'_`k''=`proba`i'_`k''+`prob`i'_`=`k'+1'' + qui replace `icc`i''=`icc`i''+`k'*`proba`i'_`k'' + qui compress + if "`genproba'"!="" { + qui gen proba`i'_`k'=`prob`i'_`k''-`prob`i'_`=`k'+1'' + } + } + if "`genicc'"!="" { + qui gen icc`i'=`icc`i'' + } + qui gen `prefix`d''`q'=0 + di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `pcm'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1] + forvalues k=2/`nbmodas`i'' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + } + tempname uni + qui gen `uni'=uniform() + forvalues k=1/`nbmodas`i'' { + qui replace `prefix`d''`q'=`k' if `uni'<=`prob`i'_`k'' + qui compress + } + } + else { /*if "`threshold'"!=""*/ + qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1] + local tmp=0 + forvalues k=1/`nbmodas`i'' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + local tmp=`tmp'+`pcm'[`i',`k'] + qui replace `prefix`d''`q'=`k' if lt`d'>`tmp' + qui compress + } + } + local q=`q'+1 + } +} +`line' +di + + +/******************************************************************************** +CATEGORIES PROBABILITY CURVES and ITEMS CHARACTERISTIC CURVES +********************************************************************************/ + +set tracedepth 1 +if "`draw'"!=""|"`icc'"!=""|"`drawall'"!="" { + label variable lt1 "Latent trait" + local dess + sort lt1 + + if "`draw'"!=""|"`drawall'"!="" { + local alldess + forvalues i=1/`dim1' { + if "`title'"=="" { + local title2="Category Probability Curves of the Item `i'" + } + else { + local title2="`title'" + } + local dess + local tauj`j'k0=0 + forvalues k=`nbmodas`i''(-1)0 { + local dess `dess' (line `proba`i'_`k'' lt1) + label variable `proba`i'_`k'' "`k'" + } + graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace) + local alldess `alldess' `dess' + } + if "`drawall'"!="" { + graph twoway `alldess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(all,replace) + } + } + if "`icc'"!="" { + local hicc + forvalues i=1/`dim1' { + if "`titleicc'"=="" { + local title3="Item Characteristic Curve of the Item `i'" + } + else { + local title3="`title'" + } + graph twoway (line `icc`i'' lt1) if `graphobs', ylabel(0(1)`nbmodas') legend(off) ytitle("Expected response") title("`title3'") name(iccitem`i',replace) + local hicc `hicc' (line `icc`i'' lt1) + label variable `icc`i'' "Item `i'" + } + graph twoway `hicc' if `graphobs', ylabel(0(1)`nbmodas') legend(on) ytitle("Expected response") title("Item Characteristic Curves") name(icc,replace) + } +} +qui drop if `graphobs' + + +/******************************************************************************** +DISPLAYING +********************************************************************************/ + +forvalues d=1/`dim' { + qui su lt`d' + local var_`d'=r(Var) + local mean_`d'=r(mean) + forvalues l=`=`d'+1'/`dim' { + qui corr lt`d' lt`l' ,cov + local cov_`d'_`l'=r(cov_12) + return scalar cov_`d'_`l'=`cov_`d'_`l'' + } + return scalar mean_`d'=`mean_`d'' + return scalar var_`d'=`var_`d'' +} +forvalues d=1/`dim' { + forvalues l=`=`d'+1'/`dim' { + local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'') + return scalar corr_`d'_`l'=`corr_`d'_`l'' + } +} + + +if `dim'==1&`group'!=0 { + qui su lt1 if group==0 + local mean_0=r(mean) + qui su lt1 if group==1 + local mean_1=r(mean) + local delta=`mean_1'-`mean_0' +} + +return scalar nbobs=`nbobs' +tempname matcorr +matrix `matcorr'=corr(`matcov') + +di in gr "{hline 50}" +di _col(1) in gr "Latent trait" _c +if `dim'==2 { + di in gr "s"_c +} +di in gr _col(30) "Expected" _col(42) "Observed" +di in gr "{hline 50}" +forvalues i=1/`dim' { + di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i'' + di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i'' + forvalues d=`=`i'+1'/`dim' { + di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d'' + di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d'' + } + di in gr "{hline 50}" +} +if `dim'==1&`group'!=0 { + di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0' + di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1' + qui count if group==1 + local prop=r(N)/`nbobs' + di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop' + di in gr "{hline 50}" +} + +/******************************************************************************** +CLEAR AND/OR STORE +********************************************************************************/ +qui compress + +if "`clear'"!="" { + restore, not + preserve +} +if "`store'"!="" { + save "`store'",`replace' +} +if "`clear'"=="" { + use "`saveraschbin'",replace +} +end diff --git a/Modules/ado/personal/s/simirt v4.2.ado b/Modules/ado/personal/s/simirt v4.2.ado new file mode 100644 index 0000000..4fd035b --- /dev/null +++ b/Modules/ado/personal/s/simirt v4.2.ado @@ -0,0 +1,761 @@ +*! version 4.2 June 19, 2018 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model, +* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM) +* +* Version 1 : May 9, 2005 (Jean-Benoit Hardouin) +* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/ +* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/ +* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/ +* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/ +* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/ +* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/ +* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/ +* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/ +* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/ +* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/ +* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/ +* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/ +* Version 4 : December 11, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*GPCM + genp, genicc, icc options*/ +* Version 4.1 : December 17, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*drawall option*/ +* Version 4.2 : June 19, 2018 (Jean-Benoit Hardouin) /*correction of a small bug with rsm2 option*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* +* Copyright 2005-2006, 2008-2009, 2011, 2013 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define simirt , rclass +version 8.0 +syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW drawall ICC GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string) GENProba GENIcc] + + +/******************************************************************************** +TESTS +********************************************************************************/ + + +if `group'<0|`group'>1 { + di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}" + error 198 + exit +} + +if "`clear'"==""&"`store'"=="" { + di in red "You must use at least one of these two options: clear and/or store." + error 198 + exit +} + +if "`dim'"!="" { + local nbdim:word count `dim' + if `nbdim'>2&"`covmatrix'"=="" { + di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it." + error 198 + exit + } + if "`covmatrix'"!="" { + local nbrowcovm=rowsof(`covmatrix') + if `nbdim'!=`nbrowcovm' { + di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that." + error 198 + exit + } + } + local nbitems=0 + forvalues d=1/`nbdim' { + local dim`d':word `d' of `dim' + local nbitems=`nbitems'+`dim`d'' + } + local dim=`nbdim' + + if "`diff'"!="" { + local nbdiff:word count `diff' + local tmp:word 1 of `diff' + if "`tmp'"=="gauss"|"`tmp'"=="uniform" { + local typediff values + } + else if `nbdiff'!=`nbitems' { + di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options." + error 198 + exit + } + } + else if "`diff'"=="" { + local diff gauss + forvalues d=1/`dim' { + local diff `diff' 0 1 + } + local typediff gauss + local nbdiff:word count `diff' + } +} +else if "`dim'"==""{ + if "`diff'"==""&"`pcm'"=="" { + di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)." + error 198 + exit + } + else if "`covmatrix'"!= "" { + local nbrowcovm=rowsof(`covmatrix') + if `nbrowcovm'>1 { + di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option." + error 198 + exit + } + } + else if "`pcm'"!="" { + local nbitems=rowsof(`pcm') + local dim=1 + local dim1=`nbitems' + } + else { + local nbdiff:word count `diff' + local nbitems=`nbdiff' + local dim=1 + local dim1=`nbitems' + } +} + +if (`group'!=0|`deltagroup'!=0)&`dim'!=1 { + di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data." + error 198 + exit +} + +if "`prefix'"=="" { + local prefix item +} + +local nbprefix:word count `prefix' +if `nbprefix'!=`dim'&`nbprefix'!=1 { + di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it." + error 198 + exit +} +if `nbprefix'==`dim' { + forvalues d=1/`dim' { + local prefix`d':word `d' of `prefix' + } +} +else { + forvalues d=1/`dim' { + local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + local prefix`d' `prefix'`tmp' + } +} +if "`covmatrix'"=="" { + tempname covmatrix2 + local nbcov:word count `cov' + + if `dim'==1 { + if "`cov'"=="" { + local cov=1 + } + if `nbcov'>1 { + di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option." + error 198 + exit + } + if `cov'<0 { + di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option." + error 198 + } + matrix `covmatrix2'=(`cov') + } + else if `dim'==2 { + if `nbcov'!=3&`nbcov'>0 { + di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)." + error 198 + exit + } + else if `nbcov'==0 { + if `dim'==1 { + local cov "1" + } + else if `dim'==2 { + local cov "1 1 0" + } + local nbcov:word count `cov' + } + if `nbcov'==3 { + local cov1:word 1 of `cov' + local cov2:word 2 of `cov' + local cov3:word 3 of `cov' + local rho=`cov3'/sqrt(`cov1'*`cov2') + if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 { + di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it." + error 198 + exit + } + } + matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2') + } + local covmatrix `covmatrix2' +} + +local nbmu:word count `mu' +if `nbmu'!=`dim'&`nbmu'!=0 { + di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')" + error 198 + exit +} +local nbdisc:word count `disc' +if `nbdisc'!=`nbitems'&`nbdisc'!=0 { + di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmin:word count `pmin' +if `nbpmin'!=`nbitems'&`nbpmin'!=0 { + di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmax:word count `pmax' +if `nbpmax'!=`nbitems'&`nbpmax'!=0 { + di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbacc:word count `acc' +if `nbacc'!=`nbitems'&`nbacc'!=0 { + di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} + +if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`pcm'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:pcm} option, you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`pcm'"!="") { + di in red "You cannot use in the same time the {hi:rsm1} and/or {hi:rsm2} options with the {hi:pcm} option" + error 198 + exit +} +if "`rsm2'"!=""&`dim'==1 { + di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension" + error 198 + exit +} +if "`id'"=="" { + local id="id" +} + +preserve + +tempfile saveraschbin +capture qui save `saveraschbin' + + + + +/******************************************************************************** +PARAMETERS +********************************************************************************/ + + +local hour=real(substr("$S_TIME",1,2)) +local min=real(substr("$S_TIME",4,2)) +local sec=real(substr("$S_TIME",7,2)) +local jour=real(substr("$S_DATE",1,2)) + + + + +if "$seed"!="" { + global seed2=int($seed) +} +else { + global seed2=0 +} +global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour' +while $seed>2^31-1 { + global seed=int($seed/231) +} +qui set seed $seed + +if "`typediff'"=="uniform" { + if `nbdiff'==`=`dim'*2+1' { + local min`d':word `=(`d'-1)*2+2' of `diff' + local max`d':word `=(`d'-1)*2+3' of `diff' + } + else if `nbdiff'==1 { + local min`d'=-2 + local max`d'=2 + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)' + } + } +} +else if "`typediff'"=="gauss" { + if `nbdiff'==`=`dim'*2+1' { + forvalues d=1/`dim' { + local mean`d':word `=(`d'-1)*2+2' of `diff' + local var`d':word `=(`d'-1)*2+3' of `diff' + } + } + else if `nbdiff'==1 { + forvalues d=1/`dim' { + local mean`d'=0 + local var`d'=1 + } + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + error 198 + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d'' + local diff `diff' `tmp' + } + } +} + +forvalues d=1/`dim' { + if "`rsm`d''"!="" { + local nbrsm`d':word count `rsm`d'' + forvalues i=2/`=`nbrsm`d''+1' { + local rsm`d'`i':word `=`i'-1' of `rsm`d'' + if "`threshold'"!=""&`rsm`d'`i''<0 { + di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive." + error 198 + exit + } + } + } +} +if "`diff'"!=""&"`pcm'"=="" { + tempname pcm + qui matrix `pcm'=J(`nbitems',1,.) + forvalues j=1/`nbitems' { + local tmp:word `j' of `diff' + qui matrix `pcm'[`j',1]=`tmp' + } +} + + +tempname matmu matcov matdiff matdisc matpmin matpmax matacc +matrix define `matdiff'=J(`nbitems',1,0) +matrix define `matdisc'=J(`nbitems',1,0) +matrix define `matpmin'=J(`nbitems',1,0) +matrix define `matpmax'=J(`nbitems',1,0) +matrix define `matacc'=J(`nbitems',1,0) +matrix define `matmu'=J(`dim',1,0) +matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0) + +forvalues i=1/`nbitems'{ + if `nbdisc'!=0 { + local tmp:word `i' of `disc' + matrix `matdisc'[`i',1]=`tmp' + } + else { + matrix `matdisc'[`i',1]=1 + } +} + +if "`pcm'"==""|"`rsm1'"!="" { + tempname pcm + if "`rsm1'"=="" { + forvalues i=1/`nbitems' { + local tmp:word `i' of `diff' + matrix `matdiff'[`i',1]=`tmp' + } + matrix `pcm'=`matdiff' + } + else { + local moda1:word count `rsm1' + local moda2:word count `rsm2' + local nbmodas=max(`=`moda1'+1',`=`moda2'+1') + matrix `pcm'=J(`nbitems',`nbmodas',.) + forvalues i=1/`dim1' { + local tmp:word `i' of `diff' + matrix `pcm'[`i',1]=`tmp' + forvalues j=1/`=`nbmodas'-1' { + local tmp:word `j' of `rsm1' + matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp' + } + } + if "`rsm2'"!="" { + forvalues i=`=`dim1'+1'/`=`dim1'+`dim2'' { + local tmp:word `i' of `diff' + matrix `pcm'[`i',1]=`tmp' + forvalues j=1/`=`nbmodas'-1' { + local tmp:word `j' of `rsm2' + matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp' + } + } + } + } +} +local nbmodas=colsof(`pcm') +forvalues j=1/`nbitems' { + local pcmpj`j'k0=-999999999999999 + forvalues k=1/`nbmodas' { + local pcmpj`j'k`k'=`pcm'[`j',`k'] + if `pcmpj`j'k`k''!=. { + local nbmodas`j'=`k' + } + local tmp=`k'-1 + if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' { + di in red "With the {hi:threshold} option, the difficulties of a given item must increase." + error 198 + exit + } + } +} + + +forvalues i=1/`nbitems' { + if `nbpmin'!=0 { + local tmp:word `i' of `pmin' + matrix `matpmin'[`i',1]=`tmp' + } + else { + matrix `matpmin'[`i',1]=0 + } + if `nbpmax'!=0 { + local tmp:word `i' of `pmax' + matrix `matpmax'[`i',1]=`tmp' + } + else { + matrix `matpmax'[`i',1]=1 + } + if `nbacc'!=0 { + local tmp:word `i' of `acc' + matrix `matacc'[`i',1]=`tmp' + } + else { + matrix `matacc'[`i',1]=1 + } +} + +if "`covmatrix'"=="" { + tempname covmatrix + if `nbcov'==1 { + matrix `covmatrix'=(`cov') + } + if `nbcov'==3 { + local tmp1:word 1 of `cov' + local tmp2:word 2 of `cov' + local tmp12:word 3 of `cov' + matrix `covmatrix'=(`tmp1',`tmp12'\`tmp12',`tmp2') + } +} +matrix `matcov'=`covmatrix' +if (`nbmu'==`dim') { + forvalues d=1/`dim' { + local tmp:word `d' of `mu' + matrix `matmu'[`d',1]=`tmp' + } +} +if `dim'==2 { + local corr=`covmatrix'[1,2]/sqrt(`covmatrix'[1,1]*`covmatrix'[2,2]) +} + + + +/******************************************************************************** +SIMULATION +********************************************************************************/ + + +drop _all +qui set obs `=`nbobs'+2001' +qui gen `id'=_n +tempname graphobs +qui gen `graphobs'=`id'>`nbobs' +local names +forvalues d=1/`dim' { + qui gen x`d'=invnorm(uniform()) + qui compress + local names `names' lt`d' +} + +matrix Chol=cholesky(corr(`covmatrix')) +forvalues d=1/`dim' { + qui gen lt`d'=0 + forvalues i=1/`d' { + qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i' + } + qui compress +} +qui drop x* +forvalues d=1/`dim' { + qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1] + qui compress +} +qui replace lt1=_n-`nbobs' if `graphobs' +qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] if `graphobs' + +if `dim'==1&`group'!=0 { + if "`random'"=="" { + qui gen group=uniform()<`group' + } + else { + qui gen group=`id'<=`group'*`nbobs' + } + qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1 + qui replace lt1=lt1-`deltagroup'*`group' if group==0 + qui compress +} + +di in gr "Number of individuals: " in ye `nbobs' +di + +if "`threshold'"=="" { + local line di in gr "{hline 75}" +} +else { + local line di in gr "{hline 27}" +} + +if "`threshold'"=="" { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc" +} +else { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" +} +local dim0=0 +local deb1=1 +local fin0=0 +local fin1=`dim1' + +forvalues d=1/`dim' { /* FOREACH DIMENSION*/ + local deb`d'=`fin`=`d'-1''+1 + local fin`d'=`deb`d''+`dim`d''-1 + `line' + local p=`d'-1 + local q=1 + forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/ + qui compress + tempname prob`i'_`=`nbmodas`i''+1' + qui gen `prob`i'_`=`nbmodas`i''+1''=0 + local tau0=0 + local tau1=`pcm'[`i',1] + local D "1+exp(`matdisc'[`i',1]*(lt`d'-`tau1'))" + forvalues k=2/`nbmodas`i'' { + local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k'] + local D "`D'+exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k'')) " + } + if "`threshold'"=="" { + tempname icc`i' + qui gen `icc`i''=0 + tempname proba`i'_0 + gen `proba`i'_0'=1 + forvalues k=`nbmodas`i''(-1)1 { + tempname prob`i'_`k' proba`i'_`k' + qui gen `proba`i'_`k''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k''))/(`D'))^`matacc'[`i',1] + qui replace `proba`i'_0'=`proba`i'_0'-`proba`i'_`k'' + qui gen `prob`i'_`k''=`proba`i'_`k''+`prob`i'_`=`k'+1'' + qui replace `icc`i''=`icc`i''+`k'*`proba`i'_`k'' + qui compress + if "`genproba'"!="" { + qui gen proba`i'_`k'=`prob`i'_`k''-`prob`i'_`=`k'+1'' + } + } + if "`genicc'"!="" { + qui gen icc`i'=`icc`i'' + } + qui gen `prefix`d''`q'=0 + di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `pcm'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1] + forvalues k=2/`nbmodas`i'' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + } + tempname uni + qui gen `uni'=uniform() + forvalues k=1/`nbmodas`i'' { + qui replace `prefix`d''`q'=`k' if `uni'<=`prob`i'_`k'' + qui compress + } + } + else { /*if "`threshold'"!=""*/ + qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1] + local tmp=0 + forvalues k=1/`nbmodas`i'' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + local tmp=`tmp'+`pcm'[`i',`k'] + qui replace `prefix`d''`q'=`k' if lt`d'>`tmp' + qui compress + } + } + local q=`q'+1 + } +} +`line' +di + + +/******************************************************************************** +CATEGORIES PROBABILITY CURVES and ITEMS CHARACTERISTIC CURVES +********************************************************************************/ + +set tracedepth 1 +if "`draw'"!=""|"`icc'"!=""|"`drawall'"!="" { + label variable lt1 "Latent trait" + local dess + sort lt1 + + if "`draw'"!=""|"`drawall'"!="" { + local alldess + forvalues i=1/`dim1' { + if "`title'"=="" { + local title2="Category Probability Curves of the Item `i'" + } + else { + local title2="`title'" + } + local dess + local tauj`j'k0=0 + forvalues k=`nbmodas`i''(-1)0 { + local dess `dess' (line `proba`i'_`k'' lt1) + label variable `proba`i'_`k'' "`k'" + } + graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace) + local alldess `alldess' `dess' + } + if "`drawall'"!="" { + graph twoway `alldess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(all,replace) + } + } + if "`icc'"!="" { + local hicc + forvalues i=1/`dim1' { + if "`titleicc'"=="" { + local title3="Item Characteristic Curve of the Item `i'" + } + else { + local title3="`title'" + } + graph twoway (line `icc`i'' lt1) if `graphobs', ylabel(0(1)`nbmodas') legend(off) ytitle("Expected response") title("`title3'") name(iccitem`i',replace) + local hicc `hicc' (line `icc`i'' lt1) + label variable `icc`i'' "Item `i'" + } + graph twoway `hicc' if `graphobs', ylabel(0(1)`nbmodas') legend(on) ytitle("Expected response") title("Item Characteristic Curves") name(icc,replace) + } +} +qui drop if `graphobs' + + +/******************************************************************************** +DISPLAYING +********************************************************************************/ + +forvalues d=1/`dim' { + qui su lt`d' + local var_`d'=r(Var) + local mean_`d'=r(mean) + forvalues l=`=`d'+1'/`dim' { + qui corr lt`d' lt`l' ,cov + local cov_`d'_`l'=r(cov_12) + return scalar cov_`d'_`l'=`cov_`d'_`l'' + } + return scalar mean_`d'=`mean_`d'' + return scalar var_`d'=`var_`d'' +} +forvalues d=1/`dim' { + forvalues l=`=`d'+1'/`dim' { + local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'') + return scalar corr_`d'_`l'=`corr_`d'_`l'' + } +} + + +if `dim'==1&`group'!=0 { + qui su lt1 if group==0 + local mean_0=r(mean) + qui su lt1 if group==1 + local mean_1=r(mean) + local delta=`mean_1'-`mean_0' +} + +return scalar nbobs=`nbobs' +tempname matcorr +matrix `matcorr'=corr(`matcov') + +di in gr "{hline 50}" +di _col(1) in gr "Latent trait" _c +if `dim'==2 { + di in gr "s"_c +} +di in gr _col(30) "Expected" _col(42) "Observed" +di in gr "{hline 50}" +forvalues i=1/`dim' { + di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i'' + di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i'' + forvalues d=`=`i'+1'/`dim' { + di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d'' + di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d'' + } + di in gr "{hline 50}" +} +if `dim'==1&`group'!=0 { + di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0' + di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1' + qui count if group==1 + local prop=r(N)/`nbobs' + di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop' + di in gr "{hline 50}" +} + +/******************************************************************************** +CLEAR AND/OR STORE +********************************************************************************/ +qui compress + +if "`clear'"!="" { + restore, not + preserve +} +if "`store'"!="" { + save "`store'",`replace' +} +if "`clear'"=="" { + use "`saveraschbin'",replace +} +end diff --git a/Modules/ado/personal/s/simirt v4.3.ado b/Modules/ado/personal/s/simirt v4.3.ado new file mode 100644 index 0000000..225fed2 --- /dev/null +++ b/Modules/ado/personal/s/simirt v4.3.ado @@ -0,0 +1,762 @@ +*! version 4.3 August 29, 2019 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model, +* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM) +* +* Version 1 : May 9, 2005 (Jean-Benoit Hardouin) +* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/ +* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/ +* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/ +* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/ +* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/ +* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/ +* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/ +* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/ +* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/ +* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/ +* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/ +* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/ +* Version 4 : December 11, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*GPCM + genp, genicc, icc options*/ +* Version 4.1 : December 17, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*drawall option*/ +* Version 4.2 : June 19, 2018 (Jean-Benoit Hardouin) /*correction of a small bug with rsm2 option*/ +* Version 4.3 : August 29, 2019 (Jean-Benoit Hardouin) /*correction of a small bug with store option*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* +* Copyright 2005-2006, 2008-2009, 2011, 20130 2018, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define simirt , rclass +version 8.0 +syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW drawall ICC GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string) GENProba GENIcc] + + +/******************************************************************************** +TESTS +********************************************************************************/ + + +if `group'<0|`group'>1 { + di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}" + error 198 + exit +} + +if "`clear'"==""&"`store'"=="" { + di in red "You must use at least one of these two options: clear and/or store." + error 198 + exit +} + +if "`dim'"!="" { + local nbdim:word count `dim' + if `nbdim'>2&"`covmatrix'"=="" { + di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it." + error 198 + exit + } + if "`covmatrix'"!="" { + local nbrowcovm=rowsof(`covmatrix') + if `nbdim'!=`nbrowcovm' { + di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that." + error 198 + exit + } + } + local nbitems=0 + forvalues d=1/`nbdim' { + local dim`d':word `d' of `dim' + local nbitems=`nbitems'+`dim`d'' + } + local dim=`nbdim' + + if "`diff'"!="" { + local nbdiff:word count `diff' + local tmp:word 1 of `diff' + if "`tmp'"=="gauss"|"`tmp'"=="uniform" { + local typediff values + } + else if `nbdiff'!=`nbitems' { + di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options." + error 198 + exit + } + } + else if "`diff'"=="" { + local diff gauss + forvalues d=1/`dim' { + local diff `diff' 0 1 + } + local typediff gauss + local nbdiff:word count `diff' + } +} +else if "`dim'"==""{ + if "`diff'"==""&"`pcm'"=="" { + di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)." + error 198 + exit + } + else if "`covmatrix'"!= "" { + local nbrowcovm=rowsof(`covmatrix') + if `nbrowcovm'>1 { + di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option." + error 198 + exit + } + } + else if "`pcm'"!="" { + local nbitems=rowsof(`pcm') + local dim=1 + local dim1=`nbitems' + } + else { + local nbdiff:word count `diff' + local nbitems=`nbdiff' + local dim=1 + local dim1=`nbitems' + } +} + +if (`group'!=0|`deltagroup'!=0)&`dim'!=1 { + di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data." + error 198 + exit +} + +if "`prefix'"=="" { + local prefix item +} + +local nbprefix:word count `prefix' +if `nbprefix'!=`dim'&`nbprefix'!=1 { + di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it." + error 198 + exit +} +if `nbprefix'==`dim' { + forvalues d=1/`dim' { + local prefix`d':word `d' of `prefix' + } +} +else { + forvalues d=1/`dim' { + local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + local prefix`d' `prefix'`tmp' + } +} +if "`covmatrix'"=="" { + tempname covmatrix2 + local nbcov:word count `cov' + + if `dim'==1 { + if "`cov'"=="" { + local cov=1 + } + if `nbcov'>1 { + di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option." + error 198 + exit + } + if `cov'<0 { + di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option." + error 198 + } + matrix `covmatrix2'=(`cov') + } + else if `dim'==2 { + if `nbcov'!=3&`nbcov'>0 { + di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)." + error 198 + exit + } + else if `nbcov'==0 { + if `dim'==1 { + local cov "1" + } + else if `dim'==2 { + local cov "1 1 0" + } + local nbcov:word count `cov' + } + if `nbcov'==3 { + local cov1:word 1 of `cov' + local cov2:word 2 of `cov' + local cov3:word 3 of `cov' + local rho=`cov3'/sqrt(`cov1'*`cov2') + if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 { + di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it." + error 198 + exit + } + } + matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2') + } + local covmatrix `covmatrix2' +} + +local nbmu:word count `mu' +if `nbmu'!=`dim'&`nbmu'!=0 { + di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')" + error 198 + exit +} +local nbdisc:word count `disc' +if `nbdisc'!=`nbitems'&`nbdisc'!=0 { + di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmin:word count `pmin' +if `nbpmin'!=`nbitems'&`nbpmin'!=0 { + di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmax:word count `pmax' +if `nbpmax'!=`nbitems'&`nbpmax'!=0 { + di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbacc:word count `acc' +if `nbacc'!=`nbitems'&`nbacc'!=0 { + di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} + +if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`pcm'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:pcm} option, you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`pcm'"!="") { + di in red "You cannot use in the same time the {hi:rsm1} and/or {hi:rsm2} options with the {hi:pcm} option" + error 198 + exit +} +if "`rsm2'"!=""&`dim'==1 { + di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension" + error 198 + exit +} +if "`id'"=="" { + local id="id" +} + +preserve + +tempfile saveraschbin +capture qui save `saveraschbin' + + + + +/******************************************************************************** +PARAMETERS +********************************************************************************/ + + +local hour=real(substr("$S_TIME",1,2)) +local min=real(substr("$S_TIME",4,2)) +local sec=real(substr("$S_TIME",7,2)) +local jour=real(substr("$S_DATE",1,2)) + + + + +if "$seed"!="" { + global seed2=int($seed) +} +else { + global seed2=0 +} +global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour' +while $seed>2^31-1 { + global seed=int($seed/231) +} +qui set seed $seed + +if "`typediff'"=="uniform" { + if `nbdiff'==`=`dim'*2+1' { + local min`d':word `=(`d'-1)*2+2' of `diff' + local max`d':word `=(`d'-1)*2+3' of `diff' + } + else if `nbdiff'==1 { + local min`d'=-2 + local max`d'=2 + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)' + } + } +} +else if "`typediff'"=="gauss" { + if `nbdiff'==`=`dim'*2+1' { + forvalues d=1/`dim' { + local mean`d':word `=(`d'-1)*2+2' of `diff' + local var`d':word `=(`d'-1)*2+3' of `diff' + } + } + else if `nbdiff'==1 { + forvalues d=1/`dim' { + local mean`d'=0 + local var`d'=1 + } + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + error 198 + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d'' + local diff `diff' `tmp' + } + } +} + +forvalues d=1/`dim' { + if "`rsm`d''"!="" { + local nbrsm`d':word count `rsm`d'' + forvalues i=2/`=`nbrsm`d''+1' { + local rsm`d'`i':word `=`i'-1' of `rsm`d'' + if "`threshold'"!=""&`rsm`d'`i''<0 { + di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive." + error 198 + exit + } + } + } +} +if "`diff'"!=""&"`pcm'"=="" { + tempname pcm + qui matrix `pcm'=J(`nbitems',1,.) + forvalues j=1/`nbitems' { + local tmp:word `j' of `diff' + qui matrix `pcm'[`j',1]=`tmp' + } +} + + +tempname matmu matcov matdiff matdisc matpmin matpmax matacc +matrix define `matdiff'=J(`nbitems',1,0) +matrix define `matdisc'=J(`nbitems',1,0) +matrix define `matpmin'=J(`nbitems',1,0) +matrix define `matpmax'=J(`nbitems',1,0) +matrix define `matacc'=J(`nbitems',1,0) +matrix define `matmu'=J(`dim',1,0) +matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0) + +forvalues i=1/`nbitems'{ + if `nbdisc'!=0 { + local tmp:word `i' of `disc' + matrix `matdisc'[`i',1]=`tmp' + } + else { + matrix `matdisc'[`i',1]=1 + } +} + +if "`pcm'"==""|"`rsm1'"!="" { + tempname pcm + if "`rsm1'"=="" { + forvalues i=1/`nbitems' { + local tmp:word `i' of `diff' + matrix `matdiff'[`i',1]=`tmp' + } + matrix `pcm'=`matdiff' + } + else { + local moda1:word count `rsm1' + local moda2:word count `rsm2' + local nbmodas=max(`=`moda1'+1',`=`moda2'+1') + matrix `pcm'=J(`nbitems',`nbmodas',.) + forvalues i=1/`dim1' { + local tmp:word `i' of `diff' + matrix `pcm'[`i',1]=`tmp' + forvalues j=1/`=`nbmodas'-1' { + local tmp:word `j' of `rsm1' + matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp' + } + } + if "`rsm2'"!="" { + forvalues i=`=`dim1'+1'/`=`dim1'+`dim2'' { + local tmp:word `i' of `diff' + matrix `pcm'[`i',1]=`tmp' + forvalues j=1/`=`nbmodas'-1' { + local tmp:word `j' of `rsm2' + matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp' + } + } + } + } +} +local nbmodas=colsof(`pcm') +forvalues j=1/`nbitems' { + local pcmpj`j'k0=-999999999999999 + forvalues k=1/`nbmodas' { + local pcmpj`j'k`k'=`pcm'[`j',`k'] + if `pcmpj`j'k`k''!=. { + local nbmodas`j'=`k' + } + local tmp=`k'-1 + if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' { + di in red "With the {hi:threshold} option, the difficulties of a given item must increase." + error 198 + exit + } + } +} + + +forvalues i=1/`nbitems' { + if `nbpmin'!=0 { + local tmp:word `i' of `pmin' + matrix `matpmin'[`i',1]=`tmp' + } + else { + matrix `matpmin'[`i',1]=0 + } + if `nbpmax'!=0 { + local tmp:word `i' of `pmax' + matrix `matpmax'[`i',1]=`tmp' + } + else { + matrix `matpmax'[`i',1]=1 + } + if `nbacc'!=0 { + local tmp:word `i' of `acc' + matrix `matacc'[`i',1]=`tmp' + } + else { + matrix `matacc'[`i',1]=1 + } +} + +if "`covmatrix'"=="" { + tempname covmatrix + if `nbcov'==1 { + matrix `covmatrix'=(`cov') + } + if `nbcov'==3 { + local tmp1:word 1 of `cov' + local tmp2:word 2 of `cov' + local tmp12:word 3 of `cov' + matrix `covmatrix'=(`tmp1',`tmp12'\`tmp12',`tmp2') + } +} +matrix `matcov'=`covmatrix' +if (`nbmu'==`dim') { + forvalues d=1/`dim' { + local tmp:word `d' of `mu' + matrix `matmu'[`d',1]=`tmp' + } +} +if `dim'==2 { + local corr=`covmatrix'[1,2]/sqrt(`covmatrix'[1,1]*`covmatrix'[2,2]) +} + + + +/******************************************************************************** +SIMULATION +********************************************************************************/ + + +drop _all +qui set obs `=`nbobs'+2001' +qui gen `id'=_n +tempname graphobs +qui gen `graphobs'=`id'>`nbobs' +local names +forvalues d=1/`dim' { + qui gen x`d'=invnorm(uniform()) + qui compress + local names `names' lt`d' +} + +matrix Chol=cholesky(corr(`covmatrix')) +forvalues d=1/`dim' { + qui gen lt`d'=0 + forvalues i=1/`d' { + qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i' + } + qui compress +} +qui drop x* +forvalues d=1/`dim' { + qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1] + qui compress +} +qui replace lt1=_n-`nbobs' if `graphobs' +qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] if `graphobs' + +if `dim'==1&`group'!=0 { + if "`random'"=="" { + qui gen group=uniform()<`group' + } + else { + qui gen group=`id'<=`group'*`nbobs' + } + qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1 + qui replace lt1=lt1-`deltagroup'*`group' if group==0 + qui compress +} + +di in gr "Number of individuals: " in ye `nbobs' +di + +if "`threshold'"=="" { + local line di in gr "{hline 75}" +} +else { + local line di in gr "{hline 27}" +} + +if "`threshold'"=="" { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc" +} +else { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" +} +local dim0=0 +local deb1=1 +local fin0=0 +local fin1=`dim1' + +forvalues d=1/`dim' { /* FOREACH DIMENSION*/ + local deb`d'=`fin`=`d'-1''+1 + local fin`d'=`deb`d''+`dim`d''-1 + `line' + local p=`d'-1 + local q=1 + forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/ + qui compress + tempname prob`i'_`=`nbmodas`i''+1' + qui gen `prob`i'_`=`nbmodas`i''+1''=0 + local tau0=0 + local tau1=`pcm'[`i',1] + local D "1+exp(`matdisc'[`i',1]*(lt`d'-`tau1'))" + forvalues k=2/`nbmodas`i'' { + local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k'] + local D "`D'+exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k'')) " + } + if "`threshold'"=="" { + tempname icc`i' + qui gen `icc`i''=0 + tempname proba`i'_0 + gen `proba`i'_0'=1 + forvalues k=`nbmodas`i''(-1)1 { + tempname prob`i'_`k' proba`i'_`k' + qui gen `proba`i'_`k''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k''))/(`D'))^`matacc'[`i',1] + qui replace `proba`i'_0'=`proba`i'_0'-`proba`i'_`k'' + qui gen `prob`i'_`k''=`proba`i'_`k''+`prob`i'_`=`k'+1'' + qui replace `icc`i''=`icc`i''+`k'*`proba`i'_`k'' + qui compress + if "`genproba'"!="" { + qui gen proba`i'_`k'=`prob`i'_`k''-`prob`i'_`=`k'+1'' + } + } + if "`genicc'"!="" { + qui gen icc`i'=`icc`i'' + } + qui gen `prefix`d''`q'=0 + di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `pcm'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1] + forvalues k=2/`nbmodas`i'' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + } + tempname uni + qui gen `uni'=uniform() + forvalues k=1/`nbmodas`i'' { + qui replace `prefix`d''`q'=`k' if `uni'<=`prob`i'_`k'' + qui compress + } + } + else { /*if "`threshold'"!=""*/ + qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1] + local tmp=0 + forvalues k=1/`nbmodas`i'' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + local tmp=`tmp'+`pcm'[`i',`k'] + qui replace `prefix`d''`q'=`k' if lt`d'>`tmp' + qui compress + } + } + local q=`q'+1 + } +} +`line' +di + + +/******************************************************************************** +CATEGORIES PROBABILITY CURVES and ITEMS CHARACTERISTIC CURVES +********************************************************************************/ + +set tracedepth 1 +if "`draw'"!=""|"`icc'"!=""|"`drawall'"!="" { + label variable lt1 "Latent trait" + local dess + sort lt1 + + if "`draw'"!=""|"`drawall'"!="" { + local alldess + forvalues i=1/`dim1' { + if "`title'"=="" { + local title2="Category Probability Curves of the Item `i'" + } + else { + local title2="`title'" + } + local dess + local tauj`j'k0=0 + forvalues k=`nbmodas`i''(-1)0 { + local dess `dess' (line `proba`i'_`k'' lt1) + label variable `proba`i'_`k'' "`k'" + } + graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace) + local alldess `alldess' `dess' + } + if "`drawall'"!="" { + graph twoway `alldess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(all,replace) + } + } + if "`icc'"!="" { + local hicc + forvalues i=1/`dim1' { + if "`titleicc'"=="" { + local title3="Item Characteristic Curve of the Item `i'" + } + else { + local title3="`title'" + } + graph twoway (line `icc`i'' lt1) if `graphobs', ylabel(0(1)`nbmodas') legend(off) ytitle("Expected response") title("`title3'") name(iccitem`i',replace) + local hicc `hicc' (line `icc`i'' lt1) + label variable `icc`i'' "Item `i'" + } + graph twoway `hicc' if `graphobs', ylabel(0(1)`nbmodas') legend(on) ytitle("Expected response") title("Item Characteristic Curves") name(icc,replace) + } +} +qui drop if `graphobs' + + +/******************************************************************************** +DISPLAYING +********************************************************************************/ + +forvalues d=1/`dim' { + qui su lt`d' + local var_`d'=r(Var) + local mean_`d'=r(mean) + forvalues l=`=`d'+1'/`dim' { + qui corr lt`d' lt`l' ,cov + local cov_`d'_`l'=r(cov_12) + return scalar cov_`d'_`l'=`cov_`d'_`l'' + } + return scalar mean_`d'=`mean_`d'' + return scalar var_`d'=`var_`d'' +} +forvalues d=1/`dim' { + forvalues l=`=`d'+1'/`dim' { + local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'') + return scalar corr_`d'_`l'=`corr_`d'_`l'' + } +} + + +if `dim'==1&`group'!=0 { + qui su lt1 if group==0 + local mean_0=r(mean) + qui su lt1 if group==1 + local mean_1=r(mean) + local delta=`mean_1'-`mean_0' +} + +return scalar nbobs=`nbobs' +tempname matcorr +matrix `matcorr'=corr(`matcov') + +di in gr "{hline 50}" +di _col(1) in gr "Latent trait" _c +if `dim'==2 { + di in gr "s"_c +} +di in gr _col(30) "Expected" _col(42) "Observed" +di in gr "{hline 50}" +forvalues i=1/`dim' { + di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i'' + di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i'' + forvalues d=`=`i'+1'/`dim' { + di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d'' + di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d'' + } + di in gr "{hline 50}" +} +if `dim'==1&`group'!=0 { + di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0' + di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1' + qui count if group==1 + local prop=r(N)/`nbobs' + di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop' + di in gr "{hline 50}" +} + +/******************************************************************************** +CLEAR AND/OR STORE +********************************************************************************/ +qui compress + +if "`clear'"!="" { + restore, not + preserve +} +if "`store'"!="" { + save "`store'",`replace' +} +if "`clear'"=="" { + capture use "`saveraschbin'",replace +} +end diff --git a/Modules/ado/personal/s/simirt v4.4.ado b/Modules/ado/personal/s/simirt v4.4.ado new file mode 100644 index 0000000..c2ed779 --- /dev/null +++ b/Modules/ado/personal/s/simirt v4.4.ado @@ -0,0 +1,764 @@ +*! version 4.4 March 21, 2022 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model, +* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM) +* +* Version 1 : May 9, 2005 (Jean-Benoit Hardouin) +* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/ +* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/ +* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/ +* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/ +* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/ +* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/ +* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/ +* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/ +* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/ +* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/ +* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/ +* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/ +* Version 4 : December 11, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*GPCM + genp, genicc, icc options*/ +* Version 4.1 : December 17, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*drawall option*/ +* Version 4.2 : June 19, 2018 (Jean-Benoit Hardouin) /*correction of a small bug with rsm2 option*/ +* Version 4.3 : August 29, 2019 (Jean-Benoit Hardouin) /*correction of a small bug with store option*/ +* Version 4.4 : March 21, 2022 (Jean-Benoit Hardouin) /*correction of a small bug with store option*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* +* Copyright 2005-2006, 2008-2009, 2011, 20130 2018, 2019, 2022 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define simirt , rclass +version 8.0 +syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW drawall ICC GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string) GENProba GENIcc] + + +/******************************************************************************** +TESTS +********************************************************************************/ + + +if `group'<0|`group'>1 { + di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}" + error 198 + exit +} + +if "`clear'"==""&"`store'"=="" { + di in red "You must use at least one of these two options: clear and/or store." + error 198 + exit +} + +if "`dim'"!="" { + local nbdim:word count `dim' + if `nbdim'>2&"`covmatrix'"=="" { + di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it." + error 198 + exit + } + if "`covmatrix'"!="" { + local nbrowcovm=rowsof(`covmatrix') + if `nbdim'!=`nbrowcovm' { + di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that." + error 198 + exit + } + } + local nbitems=0 + forvalues d=1/`nbdim' { + local dim`d':word `d' of `dim' + local nbitems=`nbitems'+`dim`d'' + } + local dim=`nbdim' + + if "`diff'"!="" { + local nbdiff:word count `diff' + local tmp:word 1 of `diff' + if "`tmp'"=="gauss"|"`tmp'"=="uniform" { + local typediff values + } + else if `nbdiff'!=`nbitems' { + di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options." + error 198 + exit + } + } + else if "`diff'"=="" { + local diff gauss + forvalues d=1/`dim' { + local diff `diff' 0 1 + } + local typediff gauss + local nbdiff:word count `diff' + } +} +else if "`dim'"==""{ + if "`diff'"==""&"`pcm'"=="" { + di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)." + error 198 + exit + } + else if "`covmatrix'"!= "" { + local nbrowcovm=rowsof(`covmatrix') + if `nbrowcovm'>1 { + di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option." + error 198 + exit + } + } + else if "`pcm'"!="" { + local nbitems=rowsof(`pcm') + local dim=1 + local dim1=`nbitems' + } + else { + local nbdiff:word count `diff' + local nbitems=`nbdiff' + local dim=1 + local dim1=`nbitems' + } +} + +if (`group'!=0|`deltagroup'!=0)&`dim'!=1 { + di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data." + error 198 + exit +} + +if "`prefix'"=="" { + local prefix item +} + +local nbprefix:word count `prefix' +if `nbprefix'!=`dim'&`nbprefix'!=1 { + di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it." + error 198 + exit +} +if `nbprefix'==`dim' { + forvalues d=1/`dim' { + local prefix`d':word `d' of `prefix' + } +} +else { + forvalues d=1/`dim' { + local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + local prefix`d' `prefix'`tmp' + } +} +if "`covmatrix'"=="" { + tempname covmatrix2 + local nbcov:word count `cov' + + if `dim'==1 { + if "`cov'"=="" { + local cov=1 + } + if `nbcov'>1 { + di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option." + error 198 + exit + } + if `cov'<0 { + di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option." + error 198 + } + matrix `covmatrix2'=(`cov') + } + else if `dim'==2 { + if `nbcov'!=3&`nbcov'>0 { + di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)." + error 198 + exit + } + else if `nbcov'==0 { + if `dim'==1 { + local cov "1" + } + else if `dim'==2 { + local cov "1 1 0" + } + local nbcov:word count `cov' + } + if `nbcov'==3 { + local cov1:word 1 of `cov' + local cov2:word 2 of `cov' + local cov3:word 3 of `cov' + local rho=`cov3'/sqrt(`cov1'*`cov2') + if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 { + di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it." + error 198 + exit + } + } + matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2') + } + local covmatrix `covmatrix2' +} + +local nbmu:word count `mu' +if `nbmu'!=`dim'&`nbmu'!=0 { + di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')" + error 198 + exit +} +local nbdisc:word count `disc' +if `nbdisc'!=`nbitems'&`nbdisc'!=0 { + di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmin:word count `pmin' +if `nbpmin'!=`nbitems'&`nbpmin'!=0 { + di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmax:word count `pmax' +if `nbpmax'!=`nbitems'&`nbpmax'!=0 { + di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbacc:word count `acc' +if `nbacc'!=`nbitems'&`nbacc'!=0 { + di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} + +if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`pcm'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:pcm} option, you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`pcm'"!="") { + di in red "You cannot use in the same time the {hi:rsm1} and/or {hi:rsm2} options with the {hi:pcm} option" + error 198 + exit +} +if "`rsm2'"!=""&`dim'==1 { + di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension" + error 198 + exit +} +if "`id'"=="" { + local id="id" +} + +preserve + +tempfile saveraschbin +capture qui save `saveraschbin' + + + + +/******************************************************************************** +PARAMETERS +********************************************************************************/ + + +local hour=real(substr("$S_TIME",1,2)) +local min=real(substr("$S_TIME",4,2)) +local sec=real(substr("$S_TIME",7,2)) +local jour=real(substr("$S_DATE",1,2)) + + + + +if "$seed"!="" { + global seed2=int($seed) +} +else { + global seed2=0 +} +global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour' +while $seed>2^31-1 { + global seed=int($seed/231) +} +qui set seed $seed + +if "`typediff'"=="uniform" { + if `nbdiff'==`=`dim'*2+1' { + local min`d':word `=(`d'-1)*2+2' of `diff' + local max`d':word `=(`d'-1)*2+3' of `diff' + } + else if `nbdiff'==1 { + local min`d'=-2 + local max`d'=2 + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)' + } + } +} +else if "`typediff'"=="gauss" { + if `nbdiff'==`=`dim'*2+1' { + forvalues d=1/`dim' { + local mean`d':word `=(`d'-1)*2+2' of `diff' + local var`d':word `=(`d'-1)*2+3' of `diff' + } + } + else if `nbdiff'==1 { + forvalues d=1/`dim' { + local mean`d'=0 + local var`d'=1 + } + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + error 198 + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d'' + local diff `diff' `tmp' + } + } +} + +forvalues d=1/`dim' { + if "`rsm`d''"!="" { + local nbrsm`d':word count `rsm`d'' + forvalues i=2/`=`nbrsm`d''+1' { + local rsm`d'`i':word `=`i'-1' of `rsm`d'' + if "`threshold'"!=""&`rsm`d'`i''<0 { + di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive." + error 198 + exit + } + } + } +} +if "`diff'"!=""&"`pcm'"=="" { + tempname pcm + qui matrix `pcm'=J(`nbitems',1,.) + forvalues j=1/`nbitems' { + local tmp:word `j' of `diff' + qui matrix `pcm'[`j',1]=`tmp' + } +} + + +tempname matmu matcov matdiff matdisc matpmin matpmax matacc +matrix define `matdiff'=J(`nbitems',1,0) +matrix define `matdisc'=J(`nbitems',1,0) +matrix define `matpmin'=J(`nbitems',1,0) +matrix define `matpmax'=J(`nbitems',1,0) +matrix define `matacc'=J(`nbitems',1,0) +matrix define `matmu'=J(`dim',1,0) +matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0) + +forvalues i=1/`nbitems'{ + if `nbdisc'!=0 { + local tmp:word `i' of `disc' + matrix `matdisc'[`i',1]=`tmp' + } + else { + matrix `matdisc'[`i',1]=1 + } +} + +if "`pcm'"==""|"`rsm1'"!="" { + tempname pcm + if "`rsm1'"=="" { + forvalues i=1/`nbitems' { + local tmp:word `i' of `diff' + matrix `matdiff'[`i',1]=`tmp' + } + matrix `pcm'=`matdiff' + } + else { + local moda1:word count `rsm1' + local moda2:word count `rsm2' + local nbmodas=max(`=`moda1'+1',`=`moda2'+1') + matrix `pcm'=J(`nbitems',`nbmodas',.) + forvalues i=1/`dim1' { + local tmp:word `i' of `diff' + matrix `pcm'[`i',1]=`tmp' + forvalues j=1/`=`nbmodas'-1' { + local tmp:word `j' of `rsm1' + matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp' + } + } + if "`rsm2'"!="" { + forvalues i=`=`dim1'+1'/`=`dim1'+`dim2'' { + local tmp:word `i' of `diff' + matrix `pcm'[`i',1]=`tmp' + forvalues j=1/`=`nbmodas'-1' { + local tmp:word `j' of `rsm2' + matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp' + } + } + } + } +} +local nbmodas=colsof(`pcm') +forvalues j=1/`nbitems' { + local pcmpj`j'k0=-999999999999999 + forvalues k=1/`nbmodas' { + local pcmpj`j'k`k'=`pcm'[`j',`k'] + if `pcmpj`j'k`k''!=. { + local nbmodas`j'=`k' + } + local tmp=`k'-1 + if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' { + di in red "With the {hi:threshold} option, the difficulties of a given item must increase." + error 198 + exit + } + } +} + + +forvalues i=1/`nbitems' { + if `nbpmin'!=0 { + local tmp:word `i' of `pmin' + matrix `matpmin'[`i',1]=`tmp' + } + else { + matrix `matpmin'[`i',1]=0 + } + if `nbpmax'!=0 { + local tmp:word `i' of `pmax' + matrix `matpmax'[`i',1]=`tmp' + } + else { + matrix `matpmax'[`i',1]=1 + } + if `nbacc'!=0 { + local tmp:word `i' of `acc' + matrix `matacc'[`i',1]=`tmp' + } + else { + matrix `matacc'[`i',1]=1 + } +} + +if "`covmatrix'"=="" { + tempname covmatrix + if `nbcov'==1 { + matrix `covmatrix'=(`cov') + } + if `nbcov'==3 { + local tmp1:word 1 of `cov' + local tmp2:word 2 of `cov' + local tmp12:word 3 of `cov' + matrix `covmatrix'=(`tmp1',`tmp12'\`tmp12',`tmp2') + } +} +matrix `matcov'=`covmatrix' +if (`nbmu'==`dim') { + forvalues d=1/`dim' { + local tmp:word `d' of `mu' + matrix `matmu'[`d',1]=`tmp' + } +} +if `dim'==2 { + local corr=`covmatrix'[1,2]/sqrt(`covmatrix'[1,1]*`covmatrix'[2,2]) +} + + + +/******************************************************************************** +SIMULATION +********************************************************************************/ + + +drop _all +qui set obs `=`nbobs'+2001' +qui gen `id'=_n +tempname graphobs +qui gen `graphobs'=`id'>`nbobs' +local names +forvalues d=1/`dim' { + qui gen x`d'=invnorm(uniform()) + qui compress + local names `names' lt`d' +} + +matrix Chol=cholesky(corr(`covmatrix')) +forvalues d=1/`dim' { + qui gen lt`d'=0 + forvalues i=1/`d' { + qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i' + } + qui compress +} +qui drop x* +forvalues d=1/`dim' { + qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1] + qui compress +} +qui replace lt1=_n-`nbobs' if `graphobs' +qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] if `graphobs' + +if `dim'==1&`group'!=0 { + if "`random'"=="" { + qui gen group=uniform()<`group' + } + else { + qui gen group=`id'<=`group'*`nbobs' + } + qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1 + qui replace lt1=lt1-`deltagroup'*`group' if group==0 + qui compress +} + +di in gr "Number of individuals: " in ye `nbobs' +di + +if "`threshold'"=="" { + local line di in gr "{hline 75}" +} +else { + local line di in gr "{hline 27}" +} + +if "`threshold'"=="" { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc" +} +else { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" +} +local dim0=0 +local deb1=1 +local fin0=0 +local fin1=`dim1' + +forvalues d=1/`dim' { /* FOREACH DIMENSION*/ + local deb`d'=`fin`=`d'-1''+1 + local fin`d'=`deb`d''+`dim`d''-1 + `line' + local p=`d'-1 + local q=1 + forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/ + qui compress + tempname prob`i'_`=`nbmodas`i''+1' + qui gen `prob`i'_`=`nbmodas`i''+1''=0 + local tau0=0 + local tau1=`pcm'[`i',1] + local D "1+exp(`matdisc'[`i',1]*(lt`d'-`tau1'))" + forvalues k=2/`nbmodas`i'' { + local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k'] + local D "`D'+exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k'')) " + } + if "`threshold'"=="" { + tempname icc`i' + qui gen `icc`i''=0 + tempname proba`i'_0 + gen `proba`i'_0'=1 + forvalues k=`nbmodas`i''(-1)1 { + tempname prob`i'_`k' proba`i'_`k' + qui gen `proba`i'_`k''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k''))/(`D'))^`matacc'[`i',1] + qui replace `proba`i'_0'=`proba`i'_0'-`proba`i'_`k'' + qui gen `prob`i'_`k''=`proba`i'_`k''+`prob`i'_`=`k'+1'' + qui replace `icc`i''=`icc`i''+`k'*`proba`i'_`k'' + qui compress + if "`genproba'"!="" { + qui gen proba`i'_`k'=`prob`i'_`k''-`prob`i'_`=`k'+1'' + } + } + if "`genicc'"!="" { + qui gen icc`i'=`icc`i'' + } + qui gen `prefix`d''`q'=0 + di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `pcm'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1] + forvalues k=2/`nbmodas`i'' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + } + tempname uni + qui gen `uni'=uniform() + forvalues k=1/`nbmodas`i'' { + qui replace `prefix`d''`q'=`k' if `uni'<=`prob`i'_`k'' + qui compress + } + } + else { /*if "`threshold'"!=""*/ + qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1] + local tmp=0 + forvalues k=1/`nbmodas`i'' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + local tmp=`tmp'+`pcm'[`i',`k'] + qui replace `prefix`d''`q'=`k' if lt`d'>`tmp' + qui compress + } + } + local q=`q'+1 + } +} +`line' +di + + +/******************************************************************************** +CATEGORIES PROBABILITY CURVES and ITEMS CHARACTERISTIC CURVES +********************************************************************************/ + +set tracedepth 1 +if "`draw'"!=""|"`icc'"!=""|"`drawall'"!="" { + label variable lt1 "Latent trait" + local dess + sort lt1 + + if "`draw'"!=""|"`drawall'"!="" { + local alldess + forvalues i=1/`dim1' { + if "`title'"=="" { + local title2="Category Probability Curves of the Item `i'" + } + else { + local title2="`title'" + } + local dess + local tauj`j'k0=0 + forvalues k=`nbmodas`i''(-1)0 { + local dess `dess' (line `proba`i'_`k'' lt1) + label variable `proba`i'_`k'' "`k'" + } + graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace) + local alldess `alldess' `dess' + } + if "`drawall'"!="" { + graph twoway `alldess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(all,replace) + } + } + if "`icc'"!="" { + local hicc + forvalues i=1/`dim1' { + if "`titleicc'"=="" { + local title3="Item Characteristic Curve of the Item `i'" + } + else { + local title3="`title'" + } + graph twoway (line `icc`i'' lt1) if `graphobs', ylabel(0(1)`nbmodas') legend(off) ytitle("Expected response") title("`title3'") name(iccitem`i',replace) + local hicc `hicc' (line `icc`i'' lt1) + label variable `icc`i'' "Item `i'" + } + graph twoway `hicc' if `graphobs', ylabel(0(1)`nbmodas') legend(on) ytitle("Expected response") title("Item Characteristic Curves") name(icc,replace) + } +} +qui drop if `graphobs' + + +/******************************************************************************** +DISPLAYING +********************************************************************************/ + +forvalues d=1/`dim' { + qui su lt`d' + local var_`d'=r(Var) + local mean_`d'=r(mean) + forvalues l=`=`d'+1'/`dim' { + qui corr lt`d' lt`l' ,cov + local cov_`d'_`l'=r(cov_12) + return scalar cov_`d'_`l'=`cov_`d'_`l'' + } + return scalar mean_`d'=`mean_`d'' + return scalar var_`d'=`var_`d'' +} +forvalues d=1/`dim' { + forvalues l=`=`d'+1'/`dim' { + local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'') + return scalar corr_`d'_`l'=`corr_`d'_`l'' + } +} + + +if `dim'==1&`group'!=0 { + qui su lt1 if group==0 + local mean_0=r(mean) + qui su lt1 if group==1 + local mean_1=r(mean) + local delta=`mean_1'-`mean_0' +} + +return scalar nbobs=`nbobs' +tempname matcorr +matrix `matcorr'=corr(`matcov') + +di in gr "{hline 50}" +di _col(1) in gr "Latent trait" _c +if `dim'==2 { + di in gr "s"_c +} +di in gr _col(30) "Expected" _col(42) "Observed" +di in gr "{hline 50}" +forvalues i=1/`dim' { + di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i'' + di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i'' + forvalues d=`=`i'+1'/`dim' { + di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d'' + di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d'' + } + di in gr "{hline 50}" +} +if `dim'==1&`group'!=0 { + di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0' + di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1' + qui count if group==1 + local prop=r(N)/`nbobs' + di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop' + di in gr "{hline 50}" +} + +/******************************************************************************** +CLEAR AND/OR STORE +********************************************************************************/ +qui compress + +if "`clear'"!="" { + restore, not + preserve +} +if "`store'"!="" { + keep id lt* item* + save "`store'",`replace' +} +if "`clear'"=="" { + capture use "`saveraschbin'",replace +} +end diff --git a/Modules/ado/personal/s/simirt.ado b/Modules/ado/personal/s/simirt.ado new file mode 100644 index 0000000..613e300 --- /dev/null +++ b/Modules/ado/personal/s/simirt.ado @@ -0,0 +1,801 @@ +*! version 4.5 March 21, 2022 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model, +* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM) +* +* Version 1 : May 9, 2005 (Jean-Benoit Hardouin) +* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/ +* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/ +* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/ +* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/ +* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/ +* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/ +* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/ +* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/ +* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/ +* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/ +* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/ +* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/ +* Version 4 : December 11, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*GPCM + genp, genicc, icc options*/ +* Version 4.1 : December 17, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*drawall option*/ +* Version 4.2 : June 19, 2018 (Jean-Benoit Hardouin) /*correction of a small bug with rsm2 option*/ +* Version 4.3 : August 29, 2019 (Jean-Benoit Hardouin) /*correction of a small bug with store option*/ +* Version 4.4 : March 21, 2022 (Jean-Benoit Hardouin) /*correction of a small bug with store option*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE) +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* +* Copyright 2005-2006, 2008-2009, 2011, 20130 2018, 2019, 2022 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define simirt , rclass +version 8.0 +syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW drawall ICC GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string) GENProba GENIcc] + + +/******************************************************************************** +TESTS +********************************************************************************/ + + +if `group'<0|`group'>1 { + di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}" + error 198 + exit +} + +if "`clear'"==""&"`store'"=="" { + di in red "You must use at least one of these two options: clear and/or store." + error 198 + exit +} + +if "`dim'"!="" { + local nbdim:word count `dim' + if `nbdim'>2&"`covmatrix'"=="" { + di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it." + error 198 + exit + } + if "`covmatrix'"!="" { + local nbrowcovm=rowsof(`covmatrix') + if `nbdim'!=`nbrowcovm' { + di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that." + error 198 + exit + } + } + local nbitems=0 + forvalues d=1/`nbdim' { + local dim`d':word `d' of `dim' + local nbitems=`nbitems'+`dim`d'' + } + local dim=`nbdim' + + if "`diff'"!="" { + local nbdiff:word count `diff' + local tmp:word 1 of `diff' + if "`tmp'"=="gauss"|"`tmp'"=="uniform" { + local typediff values + } + else if `nbdiff'!=`nbitems' { + di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options." + error 198 + exit + } + } + else if "`diff'"=="" { + local diff gauss + forvalues d=1/`dim' { + local diff `diff' 0 1 + } + local typediff gauss + local nbdiff:word count `diff' + } +} +else if "`dim'"==""{ + if "`diff'"==""&"`pcm'"=="" { + di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)." + error 198 + exit + } + else if "`covmatrix'"!= "" { + local nbrowcovm=rowsof(`covmatrix') + if `nbrowcovm'>1 { + di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option." + error 198 + exit + } + } + else if "`pcm'"!="" { + local nbitems=rowsof(`pcm') + local dim=1 + local dim1=`nbitems' + } + else { + local nbdiff:word count `diff' + local nbitems=`nbdiff' + local dim=1 + local dim1=`nbitems' + } +} + +if (`group'!=0|`deltagroup'!=0)&`dim'!=1 { + di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data." + error 198 + exit +} + +if "`prefix'"=="" { + local prefix item +} + +local nbprefix:word count `prefix' +if `nbprefix'!=`dim'&`nbprefix'!=1 { + di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it." + error 198 + exit +} +if `nbprefix'==`dim' { + forvalues d=1/`dim' { + local prefix`d':word `d' of `prefix' + } +} +else { + forvalues d=1/`dim' { + local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + local prefix`d' `prefix'`tmp' + } +} +if "`covmatrix'"=="" { + tempname covmatrix2 + local nbcov:word count `cov' + + if `dim'==1 { + if "`cov'"=="" { + local cov=1 + } + if `nbcov'>1 { + di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option." + error 198 + exit + } + if `cov'<0 { + di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option." + error 198 + } + matrix `covmatrix2'=(`cov') + } + else if `dim'==2 { + if `nbcov'!=3&`nbcov'>0 { + di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)." + error 198 + exit + } + else if `nbcov'==0 { + if `dim'==1 { + local cov "1" + } + else if `dim'==2 { + local cov "1 1 0" + } + local nbcov:word count `cov' + } + if `nbcov'==3 { + local cov1:word 1 of `cov' + local cov2:word 2 of `cov' + local cov3:word 3 of `cov' + local rho=`cov3'/sqrt(`cov1'*`cov2') + if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 { + di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it." + error 198 + exit + } + } + matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2') + } + local covmatrix `covmatrix2' +} + +local nbmu:word count `mu' +if `nbmu'!=`dim'&`nbmu'!=0 { + di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')" + error 198 + exit +} +local nbdisc:word count `disc' +if `nbdisc'!=`nbitems'&`nbdisc'!=0 { + di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmin:word count `pmin' +if `nbpmin'!=`nbitems'&`nbpmin'!=0 { + di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbpmax:word count `pmax' +if `nbpmax'!=`nbitems'&`nbpmax'!=0 { + di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} +local nbacc:word count `acc' +if `nbacc'!=`nbitems'&`nbacc'!=0 { + di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')" + error 198 + exit +} + +if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`pcm'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") { + di in red "If you use the {hi:pcm} option, you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options" + error 198 + exit +} +if ("`rsm1'"!=""|"`rsm2'"!="")&("`pcm'"!="") { + di in red "You cannot use in the same time the {hi:rsm1} and/or {hi:rsm2} options with the {hi:pcm} option" + error 198 + exit +} +if "`rsm2'"!=""&`dim'==1 { + di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension" + error 198 + exit +} +if "`id'"=="" { + local id="id" +} + +preserve + +tempfile saveraschbin +capture qui save `saveraschbin' + + + + +/******************************************************************************** +PARAMETERS +********************************************************************************/ + + +local hour=real(substr("$S_TIME",1,2)) +local min=real(substr("$S_TIME",4,2)) +local sec=real(substr("$S_TIME",7,2)) +local jour=real(substr("$S_DATE",1,2)) + + + + +if "$seed"!="" { + global seed2=int($seed) +} +else { + global seed2=0 +} +global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour' +while $seed>2^31-1 { + global seed=int($seed/231) +} +qui set seed $seed + +if "`typediff'"=="uniform" { + if `nbdiff'==`=`dim'*2+1' { + local min`d':word `=(`d'-1)*2+2' of `diff' + local max`d':word `=(`d'-1)*2+3' of `diff' + } + else if `nbdiff'==1 { + local min`d'=-2 + local max`d'=2 + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)' + } + } +} +else if "`typediff'"=="gauss" { + if `nbdiff'==`=`dim'*2+1' { + forvalues d=1/`dim' { + local mean`d':word `=(`d'-1)*2+2' of `diff' + local var`d':word `=(`d'-1)*2+3' of `diff' + } + } + else if `nbdiff'==1 { + forvalues d=1/`dim' { + local mean`d'=0 + local var`d'=1 + } + } + else { + di in red "Your {hi:diff} option is uncorrect. Please correct it." + error 198 + exit + } + local diff + forvalues d=1/`dim' { + forvalues i=1/`dim`d'' { + local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d'' + local diff `diff' `tmp' + } + } +} + +forvalues d=1/`dim' { + if "`rsm`d''"!="" { + local nbrsm`d':word count `rsm`d'' + forvalues i=2/`=`nbrsm`d''+1' { + local rsm`d'`i':word `=`i'-1' of `rsm`d'' + if "`threshold'"!=""&`rsm`d'`i''<0 { + di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive." + error 198 + exit + } + } + } +} +if "`diff'"!=""&"`pcm'"=="" { + tempname pcm + qui matrix `pcm'=J(`nbitems',1,.) + forvalues j=1/`nbitems' { + local tmp:word `j' of `diff' + qui matrix `pcm'[`j',1]=`tmp' + } +} + + +tempname matmu matcov matdiff matdisc matpmin matpmax matacc +matrix define `matdiff'=J(`nbitems',1,0) +matrix define `matdisc'=J(`nbitems',1,0) +matrix define `matpmin'=J(`nbitems',1,0) +matrix define `matpmax'=J(`nbitems',1,0) +matrix define `matacc'=J(`nbitems',1,0) +matrix define `matmu'=J(`dim',1,0) +matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0) + +forvalues i=1/`nbitems'{ + if `nbdisc'!=0 { + local tmp:word `i' of `disc' + matrix `matdisc'[`i',1]=`tmp' + } + else { + matrix `matdisc'[`i',1]=1 + } +} + +if "`pcm'"==""|"`rsm1'"!="" { + tempname pcm + if "`rsm1'"=="" { + forvalues i=1/`nbitems' { + local tmp:word `i' of `diff' + matrix `matdiff'[`i',1]=`tmp' + } + matrix `pcm'=`matdiff' + } + else { + local moda1:word count `rsm1' + local moda2:word count `rsm2' + local nbmodas=max(`=`moda1'+1',`=`moda2'+1') + matrix `pcm'=J(`nbitems',`nbmodas',.) + forvalues i=1/`dim1' { + local tmp:word `i' of `diff' + matrix `pcm'[`i',1]=`tmp' + forvalues j=1/`=`nbmodas'-1' { + local tmp:word `j' of `rsm1' + matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp' + } + } + if "`rsm2'"!="" { + forvalues i=`=`dim1'+1'/`=`dim1'+`dim2'' { + local tmp:word `i' of `diff' + matrix `pcm'[`i',1]=`tmp' + forvalues j=1/`=`nbmodas'-1' { + local tmp:word `j' of `rsm2' + matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp' + } + } + } + } +} +local nbmodas=colsof(`pcm') +forvalues j=1/`nbitems' { + local pcmpj`j'k0=-999999999999999 + forvalues k=1/`nbmodas' { + local pcmpj`j'k`k'=`pcm'[`j',`k'] + if `pcmpj`j'k`k''!=. { + local nbmodas`j'=`k' + } + local tmp=`k'-1 + if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' { + di in red "With the {hi:threshold} option, the difficulties of a given item must increase." + error 198 + exit + } + } +} + + +forvalues i=1/`nbitems' { + if `nbpmin'!=0 { + local tmp:word `i' of `pmin' + matrix `matpmin'[`i',1]=`tmp' + } + else { + matrix `matpmin'[`i',1]=0 + } + if `nbpmax'!=0 { + local tmp:word `i' of `pmax' + matrix `matpmax'[`i',1]=`tmp' + } + else { + matrix `matpmax'[`i',1]=1 + } + if `nbacc'!=0 { + local tmp:word `i' of `acc' + matrix `matacc'[`i',1]=`tmp' + } + else { + matrix `matacc'[`i',1]=1 + } +} + +if "`covmatrix'"=="" { + tempname covmatrix + if `nbcov'==1 { + matrix `covmatrix'=(`cov') + } + if `nbcov'==3 { + local tmp1:word 1 of `cov' + local tmp2:word 2 of `cov' + local tmp12:word 3 of `cov' + matrix `covmatrix'=(`tmp1',`tmp12'\`tmp12',`tmp2') + } +} +matrix `matcov'=`covmatrix' +if (`nbmu'==`dim') { + forvalues d=1/`dim' { + local tmp:word `d' of `mu' + matrix `matmu'[`d',1]=`tmp' + } +} +if `dim'==2 { + local corr=`covmatrix'[1,2]/sqrt(`covmatrix'[1,1]*`covmatrix'[2,2]) +} + + + +/******************************************************************************** +SIMULATION +********************************************************************************/ + + +drop _all +qui set obs `=`nbobs'+2001' +qui gen `id'=_n +tempname graphobs +qui gen `graphobs'=`id'>`nbobs' +local names +forvalues d=1/`dim' { + qui gen x`d'=invnorm(uniform()) + qui compress + local names `names' lt`d' +} + +matrix Chol=cholesky(corr(`covmatrix')) +forvalues d=1/`dim' { + qui gen lt`d'=0 + forvalues i=1/`d' { + qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i' + } + qui compress +} +qui drop x* +forvalues d=1/`dim' { + qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1] + qui compress +} +qui replace lt1=_n-`nbobs' if `graphobs' +qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] if `graphobs' + +if `dim'==1&`group'!=0 { + if "`random'"=="" { + qui gen group=uniform()<`group' + } + else { + qui gen group=`id'<=`group'*`nbobs' + } + qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1 + qui replace lt1=lt1-`deltagroup'*`group' if group==0 + qui compress +} + +di in gr "Number of individuals: " in ye `nbobs' +di + +if "`threshold'"=="" { + local line di in gr "{hline 75}" +} +else { + local line di in gr "{hline 27}" +} + +if "`threshold'"=="" { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc" +} +else { + `line' + di _col(1) in gr "Items" _col(18) "Difficulty" +} +local dim0=0 +local deb1=1 +local fin0=0 +local fin1=`dim1' + +forvalues d=1/`dim' { /* FOREACH DIMENSION*/ + local deb`d'=`fin`=`d'-1''+1 + local fin`d'=`deb`d''+`dim`d''-1 + `line' + local p=`d'-1 + local q=1 + forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/ + qui compress + tempname prob`i'_`=`nbmodas`i''+1' est`i' + qui gen `prob`i'_`=`nbmodas`i''+1''=0 + qui gen `est`i''=. + local tau0=0 + local tau1=`pcm'[`i',1] + local D "1+exp(`matdisc'[`i',1]*(lt`d'-`tau1'))" + forvalues k=2/`nbmodas`i'' { + local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k'] + local D "`D'+exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k'')) " + } + if "`threshold'"=="" { + tempname icc`i' + qui gen `icc`i''=0 + tempname proba`i'_0 best`i'_0 + gen `proba`i'_0'=1 + forvalues k=`nbmodas`i''(-1)1 { + tempname prob`i'_`k' proba`i'_`k' best`i'_`k' + qui gen `proba`i'_`k''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k''))/(`D'))^`matacc'[`i',1] + qui replace `proba`i'_0'=`proba`i'_0'-`proba`i'_`k'' + qui gen `prob`i'_`k''=`proba`i'_`k''+`prob`i'_`=`k'+1'' + + /************AJOUT 13/7/22**********/ + qui gen `best`i'_`k''=`proba`i'_`k''*normalden(lt`d',`matmu'[1,1],sqrt(`covmatrix'[1,1])) + qui su `best`i'_`k'' + qui su lt`d' if round(`best`i'_`k'',0.001)==round(`r(max)',0.001) + local bestloc`i'_`k'=r(mean) + di "Best location for item `i' category `k' : `bestloc`i'_`k''" + *qui replace `est`i''=`bestloc_`k'' if ``i''==`k' + /************FIN AJOUT 13/7/22**********/ + + qui replace `icc`i''=`icc`i''+`k'*`proba`i'_`k'' + qui compress + if "`genproba'"!="" { + qui gen proba`i'_`k'=`prob`i'_`k''-`prob`i'_`=`k'+1'' + } + } + /************AJOUT 13/7/22**********/ + qui gen `best`i'_0'=`proba`i'_0'*normalden(lt`d',`matmu'[1,1],sqrt(`covmatrix'[1,1])) + qui su `best`i'_0' + qui su lt`d' if round(`best`i'_0',0.001)==round(`r(max)',0.001) + local bestloc`i'_0=r(mean) + di "Best location for item `i' category 0 : `bestloc_0'" + *qui replace `est`i''=`bestloc_0' if `i'==0 + *corr `est`i'' lt1 + /************FIN AJOUT 13/7/22**********/ + if "`genicc'"!="" { + qui gen icc`i'=`icc`i'' + } + qui gen `prefix`d''`q'=0 + di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `pcm'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1] + forvalues k=2/`nbmodas`i'' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + } + tempname uni + qui gen `uni'=uniform() + forvalues k=1/`nbmodas`i'' { + qui replace `prefix`d''`q'=`k' if `uni'<=`prob`i'_`k'' + qui compress + } + forvalues k=0/`nbmodas`i'' { + qui replace `est`i''=`bestloc`i'_`k'' if `prefix`d''`q'==`k' + } + su lt1 `est`i'' + corr lt1 `est`i'' + } + else { /*if "`threshold'"!=""*/ + qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1] + local tmp=0 + forvalues k=1/`nbmodas`i'' { + di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k'] + local tmp=`tmp'+`pcm'[`i',`k'] + qui replace `prefix`d''`q'=`k' if lt`d'>`tmp' + qui compress + } + } + local q=`q'+1 + } +} +`line' +di + + +/******************************************************************************** +CATEGORIES PROBABILITY CURVES and ITEMS CHARACTERISTIC CURVES +********************************************************************************/ + +set tracedepth 1 +if "`draw'"!=""|"`icc'"!=""|"`drawall'"!="" { + label variable lt1 "Latent trait" + local dess + /************AJOUT 13/7/22**********/ + local dessbest + /************FIN AJOUT 13/7/22**********/ + sort lt1 + + if "`draw'"!=""|"`drawall'"!="" { + local alldess + forvalues i=1/`dim1' { + if "`title'"=="" { + local title2="Category Probability Curves of the Item `i'" + } + else { + local title2="`title'" + } + local dess + /************AJOUT 13/7/22**********/ + local dessbest + /************FIN AJOUT 13/7/22**********/ + local tauj`j'k0=0 + forvalues k=`nbmodas`i''(-1)0 { + local dess `dess' (line `proba`i'_`k'' lt1) + /************AJOUT 13/7/22**********/ + local dessbest `dessbest' (line `best`i'_`k'' lt1) + /************FIN AJOUT 13/7/22**********/ + label variable `proba`i'_`k'' "`k'" + } + graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace) + local alldess `alldess' `dess' + /************AJOUT 13/7/22**********/ + graph twoway `dessbest' , ylabel(0(.25)1) legend(on) ytitle("Likelihood of latent trait as a fonction of the responses") title("`title2'") name(item`i',replace) + /************FIN AJOUT 13/7/22**********/ + } + if "`drawall'"!="" { + graph twoway `alldess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(all,replace) + } + } + if "`icc'"!="" { + local hicc + forvalues i=1/`dim1' { + if "`titleicc'"=="" { + local title3="Item Characteristic Curve of the Item `i'" + } + else { + local title3="`title'" + } + graph twoway (line `icc`i'' lt1) if `graphobs', ylabel(0(1)`nbmodas') legend(off) ytitle("Expected response") title("`title3'") name(iccitem`i',replace) + local hicc `hicc' (line `icc`i'' lt1) + label variable `icc`i'' "Item `i'" + } + graph twoway `hicc' if `graphobs', ylabel(0(1)`nbmodas') legend(on) ytitle("Expected response") title("Item Characteristic Curves") name(icc,replace) + } +} +qui drop if `graphobs' + + +/******************************************************************************** +DISPLAYING +********************************************************************************/ + +forvalues d=1/`dim' { + qui su lt`d' + local var_`d'=r(Var) + local mean_`d'=r(mean) + forvalues l=`=`d'+1'/`dim' { + qui corr lt`d' lt`l' ,cov + local cov_`d'_`l'=r(cov_12) + return scalar cov_`d'_`l'=`cov_`d'_`l'' + } + return scalar mean_`d'=`mean_`d'' + return scalar var_`d'=`var_`d'' +} +forvalues d=1/`dim' { + forvalues l=`=`d'+1'/`dim' { + local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'') + return scalar corr_`d'_`l'=`corr_`d'_`l'' + } +} + + +if `dim'==1&`group'!=0 { + qui su lt1 if group==0 + local mean_0=r(mean) + qui su lt1 if group==1 + local mean_1=r(mean) + local delta=`mean_1'-`mean_0' +} + +return scalar nbobs=`nbobs' +tempname matcorr +matrix `matcorr'=corr(`matcov') + +di in gr "{hline 50}" +di _col(1) in gr "Latent trait" _c +if `dim'==2 { + di in gr "s"_c +} +di in gr _col(30) "Expected" _col(42) "Observed" +di in gr "{hline 50}" +forvalues i=1/`dim' { + di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i'' + di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i'' + forvalues d=`=`i'+1'/`dim' { + di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d'' + di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d'' + } + di in gr "{hline 50}" +} +if `dim'==1&`group'!=0 { + di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0' + di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1' + qui count if group==1 + local prop=r(N)/`nbobs' + di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop' + di in gr "{hline 50}" +} + +/******************************************************************************** +CLEAR AND/OR STORE +********************************************************************************/ +qui compress + +if "`clear'"!="" { + restore, not + preserve +} +if "`store'"!="" { + keep id lt* item* + save "`store'",`replace' +} +if "`clear'"=="" { + capture use "`saveraschbin'",replace +} +end diff --git a/Modules/ado/personal/s/simirt.hlp b/Modules/ado/personal/s/simirt.hlp new file mode 100644 index 0000000..791e381 --- /dev/null +++ b/Modules/ado/personal/s/simirt.hlp @@ -0,0 +1,185 @@ +{smcl} +{* 7May2013}{...} +{hline} +help for {hi:simirt}{right:Jean-Benoit Hardouin} +{hline} + +{title:Simulation of IRT models} + +{p 8 14 2}{cmd:simirt} [, {cmdab:nbo:bs}({it:#}) +{cmdab:d:im}({it:# [#] [#]...}) {cmdab:mu}({it:# [#] [#]...}) {cmdab:cov}({it:# [# #]}) {cmdab:covm:atrix}({it:matrix}) +{cmdab:dif:f}({it:list_of_values_or_expression}) {cmdab:pcm}({it:matrix}) {cmdab:dis:c}({it:list_of_values}) +{cmdab:pmin}({it:list_of_values}) {cmdab:pmax}({it:list_of_values}) +{cmdab:acc}({it:list_of_values}) +{cmdab:rsm1}({it:list_of_values}) +{cmdab:rsm2}({it:list_of_values}) +{cmdab:thr:eshold} +{cmdab:clear} {cmdab:sto:re}({it:filename}) {cmdab:id}({it:newvarname}) +{cmdab:rep:lace} {cmdab:pref:ix}({it:string}) {cmdab:draw} {cmdab:tit:le}({it:string}) +{cmdab:gr:oup}({it:#}) {cmdab:norand:om} {cmdab:del:tagroup}({it:#})]) + +{title:Description} + +{p 4 8 2}{cmd:simirt} allows creating a new dataset of responses +to items simulated by an unidimensional IRT model. The model can be +dichotomous (Rasch, OPLM, Birnbaum, 3PLM, 4PLM, 5PAM) or polytomous (Rating +Scale Model-RSM). It is possible to simulate two sets of items linked, for +each of them, to a specific latent trait (who can be correlated). + +{title:Options} + +{p 4 8 2}{cmd:nbobs}({it:#}) specifies the number of individuals to simulate. +By default, 2000 individuals are simulated. + +{p 4 8 2}{cmd:dim}({it:# [#] [#]...}) specifies the number of items linked to the first +latent trait (and optionally to the second one and so on). If this option is not defined, +the {cmd:simirt} command simulates only one latent trait with a number of items +equal to the number of values defined in the {cmd:diff} or in the {cmd:pcm} option (at least one of +these three options must be defined). + +{p 4 8 2}{cmd:mu}({it:# [#]}) specifies the mean(s) of each simulated latent +trait(s). + +{p 4 8 2}{cmd:cov}({it:# [# #]}) defines the covariance matrix of the latent +trait(s). If there is only one latent, {cmd:cov} is composed of the variance of +this one, else, {cmd:cov} is composed of the variance of the first latent, +followed by the variance of the second latent trait, and of the covariance. + +{p 4 8 2}{cmd:covmatrix}({it:matrix}) directly defines the covariance matrix of the latent +trait(s). This option is required instead of the {cmd:cov} option as soon as the number +of dimensions is greater than 2 (but this option could be used for one or two dimensions). + +{p 4 8 2}{cmd:diff}({it:list_of_values_or_expression}) defines the values of the +difficulty parameters as a list of values (with a number of elements equal to +the total number of items), or as an expression like {it: uniform #A #B} (to +define these parameters as uniformly distributed in {it:]#A;#B[)}, or like +{it:gauss #M #V} (to define these parameters as the percentiles of the gaussian +distribution with mean {it:#M} and variance {it:#V}). If there is two latent +traits, the expressions are defined as {it:uniform #A1 #B1 #A2 #B2} and +{it: gauss #M1 #V1 #M2 #V2}. If this option is not defined (but the {cmd:dim} +option is), these parameters are defined among a standardized gaussian +distribution. + +{p 4 8 2}{cmd:pcm}({it:matrix}) defines a matrix containing as many rows as items and +a column for each positive answer categorie. Elements of this matrix represents the +difficulty parameters of the items in a Partial Credit Model. + +{p 4 8 2}{cmd:disc}({it:list_of_values}) defines the discriminating values of +the items (by default, these parameters are fixed to 1) [only for dichotomous items]. + +{p 4 8 2}{cmd:pmin}({it:list_of_values}) defines the minimal probability of +positive responses for each item (by default, these parameters are fixed to 0) +[only for dichotomous items]. + +{p 4 8 2}{cmd:pmax}({it:list_of_values}) defines the maximal probability of +positive responses for each item (by default, these parameters are fixed to 1) +[only for dichotomous items]. + +{p 4 8 2}{cmd:acc}({it:list_of_values}) defines the accelerating parameters +for each item (by default, these parameters are fixed to 1) [only for dichotomous items]. + +{p 4 8 2}{cmd:rsm1}({it:list_of_values}) and {cmd:rsm2}({it:list_of_values}) defines +the tau parameters corresponding to the difficulty parameters of the positive answer +categorie for each item in a Rating Scale Model for the first scale ({cmd:rsm1}) or +for the second scale ({cmd:rsm2}). + +{p 4 8 2}{cmd:threshold} simulates the responses of each individuals directly from the latent trait. +In a dichotomous model ({cmd:disc}, {cmd:pmin}, {cmd:pmax} and {cmd:acc} options are not allowed), the response +1 if given as soon the latent trait of the individual is greater than the difficulty parameter of the item (defined with the {cmd:diff} option). +In a polytomous model , an answer is given when the latent trait of the individual is greater than the + difficulties corresponding to this answer. + +{p 4 8 2}{cmd:clear} does not restore the initial dataset at the end of the +command (at least one of the {cmd:clear} and {cmd:store} options must be defined). + +{p 4 8 2}{cmd:id}({it:newvarname}) defines the name of the identifiant variable (id by default). + +{p 4 8 2}{cmd:store}({it:filename}) defines the file where the new dataset will +be stored (at least one of the {cmd:clear} and {cmd:store} options must be +defined). + +{p 4 8 2}{cmd:replace}, associated to {cmd:store}, allows replacing the file +defined by {cmd:store}, if it already exist. + +{p 4 8 2}{cmd:prefix}({it:string [string]}]) allows defining the prefix to use +for the names of the items. The {it:string} cannot contain space(s). By default, +the used prefix is "item" in the unidimensional case, and "itemA" and "itemB" +in the bidimensional case. A number follows these prefixes. + +{p 4 8 2}{cmd:draw}, in the unidimensional case, this option allows drawing the +Items Characteristic Curves on a graph. + +{p 4 8 2}{cmd:title} defines the title of the graphs. + +{p 4 8 2}{cmd:group} defines, in the unidimensional case, two groups of patients, for +example a "treated" group (coded 1) and a "reference" group (coded 0). {cmd:group} +defines the expected rate of individuals of the first group. By default, the +affectation in the two groups is randomly provided (see the {cmd:norandom} option). + +{p 4 8 2}{cmd:norandom} allows affecting between the two groups the exact rates of individuals +defined in the {cmd:group} option. + +{p 4 8 2}{cmd:deltagroup} defines, in the unidimensional case, the difference between the +means of the latent trait between the two groups defined by the {cmd:group} option. This +option is disabled if the {cmd:group} option is not defined. The variance of the latent +trait is considered as equal in the two groups. + +{title:Outputs} + +{p 4 8 2}{cmd:r(nbobs)}: Number of simulated individuals. + +{p 4 8 2}{cmd:r(mean_#)}: Empirical mean of the #th latent trait. + +{p 4 8 2}{cmd:r(var_#)}: Empirical variance of the #th latent trait. + +{p 4 8 2}{cmd:r(cov_12)}: Empirical covariance between the two latent traits +(if there is two simulated dimensions). + +{p 4 8 2}{cmd:r(rho)}: Empirical correlation coefficient between the two latent +traits (if there is two simulated dimensions). + +{title:Examples} + +{p 4 8 2}{cmd: . simirt , dim(7) clear} /*simulates data by a Rasch model*/ + +{p 4 8 2}{cmd: . simirt , diff(gauss 0 1) dim(7) disc(.8 1.2 1.4 .6 1.4 1.0 1.1) clear} + /*simulates data by a Birnbaum model*/ + +{p 4 8 2}{cmd: . simirt , diff(uniform -2 3 0 1) dim(7 7) cov(2 4 1) clear}/* +simulates data with a bidimensional latent trait*/ + +{p 4 8 2}{cmd: . simirt , dim(7) clear group(.5) deltagroup(1)} /*simulates +data by a Rasch model, with two groups of approximate equal size of patients +and a difference between the means of the latent trait for the two groups of 1*/ + +{p 4 8 2}{cmd: . simirt , dim(7) clear rsm(1 .5 .2)} /*Data simulated by a RSM. Each item +has until 5 modalities*/ + +{title:Notes about the models} + +{p 4 8 2}{bf:Rasch model}: By default, you can describe only the {cmd:diff} option. + +{p 4 8 2}{bf:Birnbaum model and OPLM}: By default, the {cmd:diff} and the {cmd:disc} options must be defined. + +{p 4 8 2}{bf:3-PLM}: By default, the {cmd:diff}, the {cmd:disc} and the {cmd:pmin} options must be defined. + +{p 4 8 2}{bf:4-PLM}: By default, the {cmd:diff}, the {cmd:disc}, the {cmd:pmin} and the {cmd:pmax} options must be defined. + +{p 4 8 2}{bf:5-PM}: The {cmd:diff}, the {cmd:disc}, the {cmd:pmin}, the {cmd:pmax} and the {cmd:acc} options must be defined. + +{p 4 8 2}{bf:RSM}: The {cmd:rsm1} [and eventually the {cmd:rsm2}] option(s) must be defined. The {cmd:disc}, the {cmd:pmin}, the {cmd:pmax} and the {cmd:acc} options cannot be defined. + +{p 4 8 2}{bf:PCM}: The {cmd:pcm} option must be defined. The {cmd:disc}, the {cmd:pmin}, the {cmd:pmax} and the {cmd:acc} options cannot be defined. + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end} +{p 4 8 2}EA 4275 "Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences"{p_end} +{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end} +{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end} +{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end} +{p 4 8 2}Email: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 4 8 2}Website {browse "http://www.anaqol.org":AnaQol} + + diff --git a/Modules/ado/personal/s/simirt.zip b/Modules/ado/personal/s/simirt.zip new file mode 100644 index 0000000..310e86b Binary files /dev/null and b/Modules/ado/personal/s/simirt.zip differ diff --git a/Modules/ado/personal/t/tcm.ado b/Modules/ado/personal/t/tcm.ado new file mode 100644 index 0000000..8617cc8 --- /dev/null +++ b/Modules/ado/personal/t/tcm.ado @@ -0,0 +1,645 @@ +* Tcm : Estimation pour une entité géographique donnée de la région centre des taux de mortalitré par age +* quinquennal, et du TCM, avec possibilité de comparer ce dernier à une valeur théorique +* +* Version 2.6 : 21 janvier 2005 (corrections pour le calcul test du TCM à une valeur de référence) +* Version 2.5 : 13 janvier 2005 (corrections pour le calcul du nb de décès observés avec ICMPART) +* Version 2.4 : 11 janvier 2005 (quelques améliorations par rapport à la version 2.3) +* Version 2.3 : 6 janvier 2005 (options ICM et ICMPART, age maximal par defaut à 95) +* Version 2.2 : 16 décembre 2004 +* Version 2.1 : 7 décembre 2004 +* Version 2 : 22 octobre 2004 +* Version 1.4 : 2 septembre 2004 +* Version 1.3: 16 aout 2004 +* Version 1.2: 22 juillet 2004 +* Version 1.1: 16 juillet 2004 +* Version 1: 16 juillet 2004 +* +* Jean-benoit Hardouin, Observatoire Régional de la Santé du Centre - Orléans - France +* jean-benoit.hardouin@orscentre.fr +* +* Copyright 2004-2005 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ +program define tcm,rclass +version 7.0 +syntax [, s10(numlist) agemax(int 95) sexe(int 0) sexestd(int 0) anneepop(int 1999) anneepopstd(int 1999) annees(numlist) anneesstd(numlist) codegeo(int 1) codegeostd(int 0) prema(int 65) details tcmcomp(real 0) icm icmpart(numlist)] + + +/********************************************************************************************* +TESTS PRELIMINAIRES +*********************************************************************************************/ + +if `sexe'<0|`sexe'>2 { + di in red "Vous devez indiquer un sexe parmi 0 (deux sexes confondus), 1 (hommes) ou 2 (femmes)" + exit +} +if `sexestd'<0|`sexestd'>2 { + di in red "Vous devez indiquer un sexe de reference parmi 0 (deux sexes confondus), 1 (hommes) ou 2 (femmes)" + exit +} +if `anneepop'<82|(`anneepop'>99&`anneepop'<1982)|`anneepop'>1999 { + di in red "Vous devez indiquer une annee de reference entre 1982 et 1999 [82 et 99] (compris)" + exit +} +if `codegeo'==0 { + di in red "Il n'est pas encore possible de travailler sur la France entiere, mais cela viendra bien assez tot" + exit +} + +local st = "$S_TIME" + + +/********************************************************************************************* +SI UNE BASE EST OUVERTE, ON LA SAUVEGARDE +*********************************************************************************************/ + +capture su * +if _rc==0 { + tempfile tmp + if "`details'"!="" { + di in green "** Sauvegarde en cours" + } + qui save `tmp',replace +} +preserve + +/********************************************************************************************* +PAR DEFAUT +*********************************************************************************************/ + + +if "`s10'"=="" { + local s10des Toutes les causes + local s10 101(1)105 201(1)231 301 302 401 501 502 601 602 701(1)707 801(1)806 901(1)903 1001 1101 1201 1301 1401 1501 1600(1)1603 1701(1)1709 +} +else {local s10des `s10'} + +if "`annees'"=="" { + local annees 1998(1)2000 +} +local anneesdes `annees' + +if "`anneesstd'"=="" { + local anneesstd `annees' +} +local anneesdesstd `anneesstd' + +/********************************************************************************************* +VERIFICATION ICM +Pour calculer un ICM, il faut que le sexe, la période et la population de référence +*********************************************************************************************/ + +if `sexestd'!=`sexe'&"`icm'"!="" { + di in yellow "Le sexe de la population de reference (option sexestd) a ete modifie pour etre identique a celui de la population de travail (option sexe) et a desormais pour valeur `sexe'" + local sexestd=`sexe' +} +if "`anneesstd'"!="`annees'"&"`icm'"!="" { + di in yellow "La periode utilisee pour la population de reference (option anneesstd) a ete modifiee pour etre identique a celle utilisee pour la population de travail (option annees) et a desormais pour valeur `annees'" + local anneesstd `annees' +} +if "`anneepopstd'"!="`anneepop'"&"`icm'"!="" { + di in yellow "La population de reference (option anneepopstd) a ete modifiee pour etre identique a la population de travail (option anneepop) et a desormais pour valeur `anneepop'" + local anneepopstd `anneepop' +} +if "`icm'"==""&"`annees'"=="`anneesstd'"&`sexe'==`sexestd' { + di in yellow "Les options indiquees semblent etre correctes pour calculer un ICM" + local icm icm +} +else if "`icm'"==""{ + di in yellow "Les options indiquees ne semblent pas etre correctes pour calculer un ICM : Attention en utilisant celui-ci" +} + +/********************************************************************************************* +SI LA STANDARDISATION SE FAIT SUR LA FRANCE +*********************************************************************************************/ + + +if `codegeostd'==0 { + use "C:\ado\personal\files\dcfrance8000long.dta", clear + qui gen flagstd=0 + foreach i of numlist `anneesstd' { + qui replace flagstd=1 if annee==`i' + } + qui keep if flagstd==1 + + qui replace flagstd=0 + foreach i of numlist `s10' { + qui replace flagstd=1 if s10==`i' + } + qui keep if flagstd==1 + + qui replace flagstd=0 + if `sexestd'!=0 { + qui replace flagstd=1 if sexe==`sexestd' + qui keep if flagstd==1 + } + + qui gen n=1 + foreach i of numlist 0 1 5(5)`=`agemax'-5' { + qui su n if age==`i' [weight=eff] + local Nstd`i'=r(sum) + } + qui su n if age>=`agemax' [weight=eff] + local Nstd`agemax'=r(sum) +} + + + +/********************************************************************************************* +ON OUVRE LA BASE DE MORTALITE +*********************************************************************************************/ + +if "`details'"!="" { + di in green "** Ouverture de la base" +} +use "C:\ado\personal\files\dccentre8000reduit.dta",replace + +if "`details'"!="" { + di in green "** Base ouverte" +} + +/********************************************************************************************* +ON SELECTIONNE LES INFORMATIONS +*********************************************************************************************/ + + +if "`details'"!="" { + di in green "** Selection de l'information necessaire" +} + + + +numlist "`annees'" +local nbans:word count `r(numlist)' +local mod=mod(`nbans',2) +if `mod'==0 { + local juillet="" +} +else if `mod'==1 { + local juillet="juillet" +} +if `codegeo'<100&"`juillet'"=="" { + local commpoptr="Estimation INSEE au 1er janvier" +} +else if `codegeo'<100&"`juillet'"!="" { + local commpoptr="Estimation INSEE au 1er juillet" +} +else if `codegeo'>100 { + local commpoptr="Rétropolation entre les recencements pour" +} + +numlist "`anneesstd'" +local nbansstd:word count `r(numlist)' +local mods=mod(`nbansstd',2) +if `mods'==0 { + local juilletstd="" +} +else if `mods'==1 { + local juilletstd="juillet" +} +if `codegeostd'<100&"`juilletstd'"=="" { + local commpopstd="Estimation INSEE au 1er janvier" +} +else if `codegeostd'<100&"`juilletstd'"!="" { + local commpopstd="Estimation INSEE au 1er juillet" +} +else if `codegeostd'>100 { + local commpopstd="Rétropolation entre les recencements pour" +} + + +tempvar keeps10 keepsexe keepannees keepgeo +gen `keeps10'=0 +gen `keepsexe'=0 +gen `keepannees'=0 +gen `keepgeo'=0 + +if "`details'"!="" { + di in green "** Selection en fonction du sexe" +} + +if `sexe'==0 { + qui replace `keepsexe'=1 +} +else { + qui replace `keepsexe'=1 if sexe==`sexe' +} + +qui keep if `keepsexe'==1 + + +if "`details'"!="" { + di in green "** Selection des annees" +} + +foreach i of numlist `annees' { + qui replace `keepannees'=1 if annee==`i' +} + +qui keep if `keepannees'==1 + +if "`details'"!="" { + di in green "** Selection de la zone geographique" +} + +if `codegeo'==1 { + qui replace `keepgeo'=1 +} + +if `codegeo'>10&`codegeo'<100 { + qui replace `keepgeo'=1 if deptdom==`codegeo' +} + +if `codegeo'>1000&`codegeo'<10000&int(`codegeo'/100)!=24 { + qui replace `keepgeo'=1 if codepct==`codegeo' +} + +if int(`codegeo'/100)==24 { + qui replace `keepgeo'=1 if ze94==`codegeo' +} + +if `codegeo'>10000&`codegeo'<100000 { + qui replace `keepgeo'=1 if comdom==`codegeo' +} + +qui keep if `keepgeo'==1 + + +if "`details'"!="" { + di in green "** Selection des codes S10" +} + +foreach i of numlist `s10' { + qui replace `keeps10'=1 if S10==`i' +} + +qui keep if `keeps10'==1 + + +if "`details'"!="" { + di in green "** Selection finale" +} + +qui keep if `keeps10'==1&`keepsexe'==1&`keepannees'==1&`keepgeo'==1 + +if "`details'"!="" { + di in green "** Selection terminee" +} + +/********************************************************************************************* +ON CHERCHE LES INTITULES DE ZONE, DE SEXE POUR LA POPULATION DE TRAVAIL +*********************************************************************************************/ + +qui count +local N=r(N) +qui count if age!=0 +local N0=r(N) +if `codegeo'==1 {local zone region Centre} +else if `codegeo'==18 {local zone Cher} +else if `codegeo'==28 {local zone Eure-et-Loir} +else if `codegeo'==36 {local zone Indre} +else if `codegeo'==37 {local zone Indre-et-Loire} +else if `codegeo'==41 {local zone Loir-et-Cher} +else if `codegeo'==45 {local zone Loiret} +else { + qui trouve `codegeo' + local zone `r(trouve`codegeo')' + if "`zone'"=="" { + local zone Non reconnue + } +} + +if `sexe'==0 {local sexedes Deux sexes} +else if `sexe'==1 {local sexedes Hommes} +else if `sexe'==2 {local sexedes Femmes} +else {local sexedes Non reconnu} + +/********************************************************************************************* +ON CHERCHE LES INTITULES DE ZONE, DE SEXE POUR LA POPULATION DE STANDARDISATION +*********************************************************************************************/ + + +if `sexestd'==0 {local sexerefdes Deux sexes} +else if `sexestd'==1 {local sexerefdes Hommes} +else if `sexestd'==2 {local sexerefdes Femmes} +else {local sexerefdes Non reconnu} + + +if `codegeostd'==0 {local zonestd France metropolitaine} +else if `codegeostd'==1 {local zonestd region Centre} +else if `codegeostd'==18 {local zonestd Cher} +else if `codegeostd'==28 {local zonestd Eure-et-Loir} +else if `codegeostd'==36 {local zonestd Indre} +else if `codegeostd'==37 {local zonestd Indre-et-Loire} +else if `codegeostd'==41 {local zonestd Loir-et-Cher} +else if `codegeostd'==45 {local zonestd Loiret} +else { + qui trouve `codegeostd' + local zonestd `r(trouve`codegeostd')' + if "`zonestd'"=="" { + local zonestd Non reconnue + } +} + +/********************************************************************************************* +ENTETE DE SORTIE +*********************************************************************************************/ + +di in green "- POPULATION DE TRAVAIL -" +di in green "Zone geographique : " in yellow "`zone'" +di in green "Periode : " in yellow "`anneesdes'" in green " (" in yellow "`nbans' an(s)" in green ")" +di in green "Population : " in yellow "`commpoptr' `anneepop'" +di in green "Sexe : " in yellow "`sexedes'" +di +di in green "- POPULATION DE REFERENCE -" +di in green "Zone geographique : " in yellow "`zonestd' " +di in green "Periode : " in yellow "`anneesdesstd'" in green " (" in yellow "`nbansstd' an(s)" in green ")" +di in green "Population : " in yellow "`commpopstd' `anneepopstd'" +di in green "Sexe: " in yellow "`sexerefdes'" +di +di in green "Deces prematures : <" in yellow "`prema'" in green " ans" +di in green "S10 : " in yellow "`s10des'" +di + +/********************************************************************************************* +NB DE DECES ET DE DECES PREMATURES +*********************************************************************************************/ + +di in green "Nombre de deces concernes : " in yellow `N' _col(55) in green "Nombre de deces concernes >0 an : " in yellow `N0' +qui count if age<`prema' +local Nprema=r(N) +local Pprema=`Nprema'/`N' +qui count if age<`prema'&age>0 +local N0prema=r(N) +local P0prema=`N0prema'/`N0' +di in green "Nombre de deces prematures : " in yellow `Nprema' in green " (" in yellow %5.1f `=`Pprema'*100' in green "%)" _col(55) in green "Nombre de deces prematures >0 an : " in yellow `N0prema' in green " (" in yellow %5.1f `=`P0prema'*100' in green "%)" + +/********************************************************************************************* +TAILLE DE POPULATION DE LA POPULATION DE TRAVAIL +*********************************************************************************************/ + +tempvar agerec +gen `agerec'=age +qui recode `agerec' 0=0 `agemax'/105=`agemax' + +local trancheage 0 1 5(5)`agemax' + +qui estpop , annee(`anneepop') codegeo(`codegeo') sexe(`sexe') `juillet' +foreach i of numlist 0 1 5(5)`=`agemax'-5' { + local popr`i'=r(poprq`i') +} +local popr`agemax'=0 +foreach i of numlist `agemax'(5)95 { + local popr`agemax'=`popr`agemax''+r(poprq`i') +} + +local popr=r(popr)/*-r(popr0)*/ + + +/********************************************************************************************* +TAILLE DE POPULATION DE LA POPULATION DE STANDARDISATION +*********************************************************************************************/ + + +qui estpop , annee(`anneepopstd') codegeo(`codegeostd') sexe(`sexestd') `juilletstd' +foreach i of numlist 0 1 5(5)`=`agemax'-5' { + local pop`i'=r(poprq`i') +} +local pop`agemax'=0 +foreach i of numlist `agemax'(5)95 { + local pop`agemax'=`pop`agemax''+r(poprq`i') +} +local pop=r(popr)/*-r(popr0) */ + +/********************************************************************************************* +TABLEAU DE SORTIE +*********************************************************************************************/ + +di +di in green "{hline 14}{c TT}{hline 33}{c TT}{hline 33}{c TT}{hline 20}" +di in green _col(15) "{c |}" _col(21) "POPULATION DE TRAVAIL" _col(49) "{c |}" _col(55) "POPULATION DE REFERENCE" _col(83) "{c |}" +di in green "{hline 14}{c +}{hline 33}{c +}{hline 33}{c +}{hline 20}" +di in green "Tranche" _col(15) "{c |}" _col(16) "Population" _col(29) "Nombre" _col(37) "Taux brut de" _col(49) "{c |}" _col(50) "Population" _col(61) "Nombre de" _col(71) "Taux brut de" _col(83) "{c |}" _col(85) "Nb de deces" +di in green "d'age" _col(15) "{c |}" _col(22) "`anneepop'" _col(27) "de deces" _col(39) "mortalite*" _col(49) "{c |}" _col(56) "`anneepopstd'" _col(65) "deces" _col(73) "mortalite*" _col(83) "{c |}" _col(88) "attendus" _col(100) "ICM" +di in green "{hline 14}{c +}{hline 33}{c +}{hline 33}{c +}{hline 20}" + +/********************************************************************************************* +CALCUL CHEZ LES 0 AN DU TAUX BRUT +*********************************************************************************************/ + +local tcm=0 +local vartcm=0 +local varicm=0 +local apvp=0 + +/*qui count if `agerec'==0 +local Nage0=r(N) +local txbrut0=`Nage0'/`popr0'*100000/`nbans' +local txstd0=`Nstd0'/`pop0'*100000/`nbansstd' +local NE0=`popr0'*`txstd0'/100000*`nbans' +local apvp0=`Nage0'*`prema' +di in green "O an" _col(15) "{c |}" _col(18) in yellow %8.0f `popr0' _col(27) %8.0f `Nage0' _col(40) %8.1f `txbrut0' _col(49) in green "{c |}" in yellow _col(52) %8.0f `pop0' _col(62) %8.0f `Nstd0' _col(74) %8.1f `txstd0' _col(83) in green "{c |}" _col(88) in yellow %8.1f `NE0' _col(97) %6.1f `=`Nage0'/`NE0'*100' +di in green "{dup 14:-}{c +}{dup 33:-}{c +}{dup 33:-}{c +}{dup 20:-}" +*/ +/********************************************************************************************* +CALCUL POUR CHAQUE TRANCHE D'AGE DU TAUX BRUT ET DE LA CONTRIBUTION AU TCM +*********************************************************************************************/ +*set trace on +if "`icmpart'"!="" { + local icmpartmin:word 1 of `icmpart' + local icmpartmax:word 2 of `icmpart' + qui count if `agerec'>=`icmpartmin'&`agerec'<=`icmpartmax' + local Npart=r(N) +} + +local N0std=0 +local NE=0 +local NEpart=0 +foreach i of numlist `trancheage' { + qui count if `agerec'==`i' + local Nage`i'=r(N) + if `i'==0 { + local tranche 0 an + } + else if `i'==1 { + local tranche 1-4 ans + local apvp1=`Nage`i''*62 + local apvp=`apvp'+`apvp1' + } + else if `i'==`agemax' { + local tranche `agemax' ans et plus + } + else { + local tranche `i'-`=`i'+4' ans + if `i'<65 { + local apvp`i'=`Nage`i''*(62.5-`i') + local apvp=`apvp'+`apvp`i'' + } + } + local N0std=`N0std'+`Nstd`i'' + local txbrut`i'=`Nage`i''/`popr`i''*100000/`nbans' + local txstd`i'=`Nstd`i''/`pop`i''*100000/`nbansstd' + local NE`i'=`popr`i''*`txstd`i''/100000*`nbans' + local NE=`NE'+`NE`i'' + if "`icmpart'"!="" { + if `icmpartmin'<=`i'&`icmpartmax'>=`i' { + local NEpart=`NEpart'+`NE`i'' + } + } + local icm`i'=`Nage`i''/`NE`i''*100 + *local varicm=`varicm'+`icm`i'' + local tcm=`tcm'+`txbrut`i''*`pop`i''/`pop' + local vartcm=`vartcm'+(`pop`i''/`pop')^2*`txbrut`i''/100000/`popr`i'' + di in green "`tranche'" _col(15) "{c |}" _col(18) in yellow %8.0f `popr`i'' _col(27) %8.0f `Nage`i'' _col(40) %8.1f `txbrut`i'' _col(49) in green "{c |}" in yellow _col(52) %8.0f `pop`i'' _col(62) %8.0f `Nstd`i'' _col(74) %8.1f `txstd`i'' _col(83) in green "{c |}" in yellow _col(88) %8.1f `NE`i'' _col(97) %6.1f `icm`i'' +} +di in green "{hline 14}{c +}{hline 33}{c +}{hline 33}{c +}{hline 20}" + +/********************************************************************************************* +TAUX BRUT GLOBAL +*********************************************************************************************/ + +local txbrut=`N'/`popr'*100000/`nbans' +local txbrutstd=`=`N0std'/`pop'*100000/`nbansstd'' +local icm=`N'/`NE'*100 +*local A=`varicm' +local varicm=`icm'^2/`N' +di in green "Total" _col(15) "{c |}" in yellow _col(18) %8.0f `popr' _col(27) %8.0f `N' _col(40) %8.1f `txbrut' _col(49) in green "{c |}" in yellow _col(52) %8.0f `pop' _col(62) %8.0f `N0std' _col(74) %8.1f `=`N0std'/`pop'*100000/`nbansstd'' in green _col(83) "{c |}" in yellow _col(88) %8.1f `NE' _col(97) %6.1f `icm' +di in green "{hline 14}{c BT}{hline 33}{c BT}{hline 33}{c BT}{hline 20}" + +di in green "APVP=" _col(18) in yellow %10.1f `apvp' + +/********************************************************************************************* +TCM +*********************************************************************************************/ + + +local tcmicmoins=(`tcm'/100000-1.96*sqrt(`vartcm'))*100000 +local tcmicplus=(`tcm'/100000+1.96*sqrt(`vartcm'))*100000 +local icmicmoins=`icm'*(1-1/(9*`N')-1.96/(3*sqrt(`N')))^3 +local icmicplus=(`N'+1)/`NE'*(1-1/(9*(`N'+1))+1.96/(3*sqrt(`N'+1)))^3*100 + +di in green "TCM" _col(20) in yellow %8.2f `tcm' _col(35) in green "Ecart type" _col(45) in yellow %8.2f `=sqrt(`vartcm')*100000' _col(61) in green "[" in yellow %8.2f `tcmicmoins' in green ";" in yellow %8.2f `tcmicplus' in green "]" +di in green "ICM" _col(20) in yellow %8.2f `icm' _col(35) in green "Ecart type" _col(45) in yellow %8.2f `=sqrt(`varicm')' _col(61) in green "[" in yellow %8.2f `icmicmoins' in green ";" in yellow %8.2f `icmicplus' in green "] (methode de Byar)" +local Zicm=(abs(`N'-`NE')-.5)/sqrt(`NE') +local pvalueicm=1-norm(abs(`Zicm')) +di in green "H0: ICM=100" _col(35) "Z=" in yellow %6.4f `Zicm' _col(45) in green "p=" in yellow %6.4f `pvalueicm' + +/********************************************************************************************* +ICM PARTIEL +*********************************************************************************************/ + +if "`icmpart'"!="" { + di in green "{dup 103:-}" + if `icmpartmax'==`agemax' { + local icmpartmaxdis "`icmpartmax' et plus" + } + else { + local icmpartmaxdis=`icmpartmax'+4 + } + di in green "ICM Partiel pour les `icmpartmin'/`icmpartmaxdis'" + di in green "Deces observes : " _col(20) in yellow %8.0f `Npart' + di in green "Deces attendus : " _col(20) in yellow %8.2f `NEpart' + local icmpart=`Npart'/`NEpart'*100 + local varicmpart=`icmpart'^2/`Npart' + local icmparticmoins=`icmpart'*(1-1/(9*`Npart')-1.96/(3*sqrt(`Npart')))^3 + local icmparticplus=(`Npart'+1)/`NEpart'*(1-1/(9*(`Npart'+1))+1.96/(3*sqrt(`Npart'+1)))^3*100 + local Zicmpart=(abs(`Npart'-`NEpart')-.5)/sqrt(`NEpart') + local pvalueicmpart=1-norm(abs(`Zicmpart')) + di in green "ICM (`icmpartmin'/`icmpartmaxdis')" _col(20) in yellow %8.2f `icmpart' _col(35) in green "Ecart type" _col(45) in yellow %8.2f `=sqrt(`varicmpart')' _col(61) in green "[" in yellow %8.2f `icmparticmoins' in green ";" in yellow %8.2f `icmparticplus' in green "] (methode de Byar)" + di in green "H0: ICM(`icmpartmin'/`icmpartmaxdis')=100" _col(35) "Z=" in yellow %6.4f `Zicmpart' _col(45) in green "p=" in yellow %6.4f `pvalueicmpart' + return scalar ICMpart=`icmpart' + return scalar ZICMpart=`Zicmpart' + return scalar pvalueICMpart=`pvalueicmpart' +} + + +di in green "{hline 103}" +di in green "*: par an pour 100 000 habitants" +*set trace on + + +/********************************************************************************************* +COMPARAISON DU TCM (TEST) +*********************************************************************************************/ + +if `tcmcomp'!=0 { + local Z=(`tcm'-`tcmcomp')/100000/(sqrt(`vartcm')) + local pvalue=1-norm(abs(`Z')) + di + di in green "Comparaison du TCM a la valeur theorique (`tcmcomp') : Z= " in yellow %8.4f `Z' in green " p= " in yellow %6.4f `pvalue' + return scalar ZTCM=`Z' + return scalar pvalueTCM=`pvalue' +} + +/********************************************************************************************* +SORTIES +*********************************************************************************************/ + +return scalar N0=`N0' +return scalar APVP=`apvp' +return scalar Popref=`popr' +return scalar TCM=`tcm' +return scalar TCMICplus=`tcmicplus' +return scalar TCMICmoins=`tcmicmoins' +return scalar ICM=`icm' +return scalar ICMICmoins=`icmicmoins' +return scalar ICMICplus=`icmicplus' +return scalar N0prema=`N0prema' +return scalar ZICM=`Zicm' +return scalar pvalueICM=`pvalueicm' +return scalar txbrut=`txbrut' +return scalar txbrutstd=`txbrutstd' +tempname matsave +numlist "0 1 5(5)`agemax'" +local j `r(numlist)' +local l:word count `j' +matrix define `matsave'=J(`l',9,0) +forvalues i=1/`l' { + local k:word `i' of `j' + matrix `matsave'[`i',1]=`k' + matrix `matsave'[`i',2]=`Nage`k'' + matrix `matsave'[`i',3]=`popr`k'' + matrix `matsave'[`i',4]=`txbrut`k'' + matrix `matsave'[`i',5]=`pop`k'' + matrix `matsave'[`i',6]=`Nstd`k'' + matrix `matsave'[`i',7]=`txstd`k'' + matrix `matsave'[`i',8]=`NE`k'' + matrix `matsave'[`i',9]=`icm`k'' +} +matrix colnames `matsave'="classe d'age" "nb deces" "pop" "taux brut" "pop reference" "nb deces reference" "taux brut reference" "deces attendus" "icm" +return matrix donnees `matsave' + +/********************************************************************************************* +RECUPERATION SI BESOIN DE LA BASE INITIALE +*********************************************************************************************/ + +restore,not +qui drop _all +if "`tmp'"!="" { + if "`details'"!="" { + di + di in green "** Restauration" + } + qui use `tmp' +} +if "`details'"!="" { + capture qui elapse `st' + di in green "** Temps d'execution : " in yellow "$S_elap " in green "secondes" +} + +end + diff --git a/Modules/ado/personal/t/testclv.ado b/Modules/ado/personal/t/testclv.ado new file mode 100644 index 0000000..61cb729 --- /dev/null +++ b/Modules/ado/personal/t/testclv.ado @@ -0,0 +1,142 @@ +program define testclv +syntax [,corr(real 0) nosim] + +clear +qui set matsize 800 +qui set memory 128m +set more off + +if `corr'==0 { + local rho 0.0 +} +else if `corr'==1 { + local rho 1.0 +} +else { + local rho 0`corr' +} + +if "`sim'"=="" { + capture use "C:\Documents and Settings\Jean-Benoit\Mes documents\THESE\clv\simul (rho=`rho')\result.dta", clear + if _rc==0 { + mkmat *,matrix(result) + use "C:\Documents and Settings\Jean-Benoit\Mes documents\THESE\clv\simul (rho=`rho')\resultpoly.dta", clear + mkmat *,matrix(resultpoly) + use "C:\Documents and Settings\Jean-Benoit\Mes documents\THESE\clv\simul (rho=`rho')\result2.dta", clear + mkmat *,matrix(result2) + use "C:\Documents and Settings\Jean-Benoit\Mes documents\THESE\clv\simul (rho=`rho')\resultpoly2.dta", clear + mkmat *,matrix(resultpoly2) + + count if resultpoly21!=0 + local deb=r(N)+1 + } + else { + matrix result=J(100,14,0) + matrix resultpoly=J(100,14,0) + matrix result2=J(100,14,0) + matrix resultpoly2=J(100,14,0) + local deb=1 + } + forvalues i=`deb'/100 { + di "`i'" _c + qui simirt,dim(7 7) cov(1 1 `rho') clear nbobs(500) store(C:\Documents and Settings\Jean-Benoit\Mes documents\THESE\clv\simul (rho=`rho')\data`i') replace + di "." _c + qui clv i*,nodendro nobiplot + di "." _c + local group:word 1 of `r(bestthresold)' + local group2:word 2 of `r(bestthresold)' + qui clv,nodendro nobiplot cons(`group') + di "." _c + matrix tmp=r(affect) + matrix result[`i',1]=tmp + di "." _c + qui clv,nodendro nobiplot cons(`group2') + di "." _c + matrix tmp=r(affect) + matrix result2[`i',1]=tmp + + di "." _c + qui clv i*,nodendro nobiplot method(polychoric) + di "." _c + local group:word 1 of `r(bestthresold)' + local group2:word 2 of `r(bestthresold)' + qui clv,nodendro nobiplot cons(`group') + di "." + matrix tmp=r(affect) + matrix resultpoly[`i',1]=tmp + di "." _c + qui clv,nodendro nobiplot cons(`group2') + di "." + matrix tmp=r(affect) + matrix resultpoly2[`i',1]=tmp + + drop _all + svmat result + save "C:\Documents and Settings\Jean-Benoit\Mes documents\THESE\clv\simul (rho=`rho')\result",replace + + drop _all + svmat resultpoly + save "C:\Documents and Settings\Jean-Benoit\Mes documents\THESE\clv\simul (rho=`rho')\resultpoly",replace + + drop _all + svmat result2 + save "C:\Documents and Settings\Jean-Benoit\Mes documents\THESE\clv\simul (rho=`rho')\result2",replace + + drop _all + svmat resultpoly2 + save "C:\Documents and Settings\Jean-Benoit\Mes documents\THESE\clv\simul (rho=`rho')\resultpoly2",replace + + } +} +foreach file in "result" "result2" "resultpoly" "resultpoly2" "result2nd" "result2nd2" { + drop _all + di "`file'" + use "C:\Documents and Settings\Jean-Benoit\Mes documents\THESE\clv\simul (rho=`rho')\\`file'",clear + quietly { + forvalues i=1/7 { + rename `file'`i' itemA`i' + rename `file'`=`i'+7' itemB`i' + } + gen conc=0 + gen dis=0 + forvalues i=1/7 { + forvalues j=`=`i'+1'/7 { + replace conc=conc+1 if itemA`i'==itemA`j' + replace conc=conc+1 if itemB`i'==itemB`j' + } + } + forvalues i=1/7 { + forvalues j=1/7 { + replace dis=dis+1 if itemA`i'==itemB`j' + } + } + gen result=. + replace result=1 if conc==42&dis==0&result==. + replace result=3 if conc<42&dis==0&result==. + replace result=4 if dis>0&conc>0&result==. + replace result=5 if dis==49&result==. + egen nbcl=rowmax(item*) + } + if "`file'"=="result" { + local text="CLV Classique" + } + if "`file'"=="result2" { + local text="CLV Classique 2e choix" + } + if "`file'"=="resultpoly" { + local text="CLV Polychoric" + } + if "`file'"=="resultpoly2" { + local text="CLV Polychoric 2e choix" + } + if "`file'"=="result2nd" { + local text="CLV 2nd ordre " + } + if "`file'"=="result2nd2" { + local text="CLV 2nd ordre 2e choix" + } + di in gr "`text'" + tab result +} + +end diff --git a/Modules/ado/personal/t/todate.ado b/Modules/ado/personal/t/todate.ado new file mode 100644 index 0000000..ca575d2 --- /dev/null +++ b/Modules/ado/personal/t/todate.ado @@ -0,0 +1,168 @@ +*! 1.3.0 NJC 6 Sept 2005 +* 1.2.1 NJC 29 July 2003 +* 1.2.0 NJC 4 July 2001 +* 1.1.0 NJC 7 June 2001 +program todate + version 8 + syntax varlist [if] [in], Pattern(string) Generate(string) /// + [ Format(string) Cend(numlist int >200 <=10000 max=1) ] + + // existing and new varlists + tokenize `varlist' + local nvars : word count `varlist' + + // do before second -syntax- + marksample touse, novarlist + + local 0 "`generate'" + syntax newvarlist + + if `nvars' != `: word count `varlist'' { + di as err "number of new variables not equal to" _c + di as err " number of existing variables" + exit 198 + } + + // partial test of format + if "`format'" != "" { + capture display `format' 1 + if _rc { + di as err "invalid format()" + exit 120 + } + } + + // parse pattern into m d y h q w elements + // indulge upper case + local pattern = lower("`pattern'") + local plength = length("`pattern'") + + forval i = 1 / `plength' { + local p = substr("`pattern'",`i',1) + + if "`p'" == "m" local mlist "`mlist' `i'" + else if "`p'" == "d" local dlist "`dlist' `i'" + else if "`p'" == "y" local ylist "`ylist' `i'" + else if "`p'" == "h" local hlist "`hlist' `i'" + else if "`p'" == "q" local qlist "`qlist' `i'" + else if "`p'" == "w" local wlist "`wlist' `i'" + else { + di as err "invalid pattern" + exit 198 + } + } + + // allow mdy yh yq ym yw permutations + foreach i in m d y h q w { + if "``i'list'" != "" { + local ptype "`ptype'`i'" + local pels "`pels' `i'" + } + } + + if !inlist("`ptype'", "yh", "yq", "my", "yw", "mdy") { + di as err "invalid pattern type: `ptype'" + exit 198 + } + if "`ptype'" == "my" local ptype "ym" + + // contiguous digits will have range == # elements - 1 + foreach i in `pels' { + local `i'1 : word 1 of ``i'list' + local `i'len : word count ``i'list' + local last : word ``i'len' of ``i'list' + local range = `last' - ``i'1' + local range2 = ``i'len' - 1 + if `range' != `range2' { + di as err "`i' digits not contiguous in pattern" + exit 198 + } + } + + // year digits and cend() compatible? + if `ylen' != 4 & "`cend'" == "" { + di as err "`ylen' digit years: need cend() option?" + exit 198 + } + else if `ylen' == 4 & "`cend'" != "" { + di as txt "4 digit years: cend() option ignored" + local cend + } + + // for each variable in original varlist + qui forval i = 1 / `nvars' { + tempvar strdate datelen touse2 + + // markout separately for each variable + gen byte `touse2' = `touse' + markout `touse2' ``i'', strok + + // working string variable copy of date variable + capture confirm string variable ``i'' + if _rc gen `strdate' = string(``i'',"%12.0g") if `touse2' + else gen `strdate' = trim(``i'') if `touse2' + local v "``i''" + local `i' "`strdate'" + + // how long is date variable? + gen `datelen' = length(``i'') + su `datelen' if `touse2', meanonly + local range = r(max) - r(min) + local min = r(min) + local max = r(max) + + if `max' != `plength' { + noi di as res "`v': " /// + as txt "length does not match pattern" + continue + } + + // range == 0 is no problem + if `range' == 1 { /* leading zero needs to be supplied? */ + replace `strdate' = "0" + `strdate' /// + if `datelen' == `min' & `touse2' + } + else if `range' >= 2 { /* range of lengths >= 2 => skip this */ + noi di as res "`v': " /// + as txt "length too variable to handle" + continue + } + + // construct month, day, year, half, quarter, week as needed + foreach j in `pels' { + tempvar `j' + gen ``j'' = real(substr(``i'',``j'1',``j'len')) + } + + if "`cend'" != "" { + local c1 = int(`cend' / 100) + local c2 = mod(`cend',100) + replace `y' = /// + `y' + 100 * cond(`y' <= `c2', `c1', `c1' - 1) + } + + // generate new variable + local newvar : word `i' of `varlist' + if "`ptype'" == "mdy" { + gen `newvar' = mdy(`m',`d',`y') if `touse2' + } + else { + local o = substr("`ptype'",2,1) + gen `newvar' = y`o'(`y',``o'') if `touse2' + } + + if "`format'" != "" format `format' `newvar' + else { + if index("`ptype'", "d") format %d `newvar' + else if index("`ptype'", "w") format %tw `newvar' + else if index("`ptype'", "m") format %tm `newvar' + else if index("`ptype'", "q") format %tq `newvar' + else if index("`ptype'", "h") format %th `newvar' + } + + _crcslbl `newvar' ``i'' + + drop `touse2' + } +end + diff --git a/Modules/ado/personal/t/torumm.ado b/Modules/ado/personal/t/torumm.ado new file mode 100644 index 0000000..a77c7bc --- /dev/null +++ b/Modules/ado/personal/t/torumm.ado @@ -0,0 +1,10 @@ +program define torumm +syntax varlist ,File(string) [Replace msp] +tempname string +egen `string'=concat(`varlist') +if "`msp'"=="" { + replace `string'=subinstr(`string',"."," ",.) +} +*tab `string' +outsheet `string' using "`file'", `replace' nonames noquote +end diff --git a/Modules/ado/personal/t/tosas.ado b/Modules/ado/personal/t/tosas.ado new file mode 100644 index 0000000..f631d47 --- /dev/null +++ b/Modules/ado/personal/t/tosas.ado @@ -0,0 +1,29 @@ +program define tosas,eclass +version 10.0 +syntax [varlist] [if] [in] [,Name(string) pgm(string) Batch] +preserve +if "`if'"!=""|"`in'"!="" { + qui keep `if' `in' +} +local dir=c(tmpdir) +tempfile tosasfile totsasfile +qui outsheet `varlist' using "`tosasfile'.txt",replace +qui outsheet `varlist' using "d:\essai.txt",replace +if "`name'"=="" { + local name stata +} +drop _all +qui set obs 1000 +qui gen txt="" +qui replace txt="PROC IMPORT OUT=WORK.`name' DATAFILE='`tosasfile'.txt' DBMS=TAB REPLACE;GETNAMES=YES;DATAROW=2; RUN;" in 3 +qui replace txt="`pgm'" in 4 +qui outsheet txt using "`tosasfile'_pgmsas.txt", replace nonames noquote +if "`batch'"!="" { + shell "C:\Program Files\SAS\SASFoundation\9.3\sas.exe" "`tosasfile'_pgmsas.txt" -print "`tosasfile'.lst" -nolog + view "`tosasfile'.lst" +} +else { + shell "C:\Program Files\SASHome\SASFoundation\9.3\core\sasexe\SASOACT.EXE" action=Submit datatype=SASFile filename="`tosasfile'_pgmsas.txt" progid=SAS.Application.903 +} +restore +end diff --git a/Modules/ado/personal/t/traces v4.ado b/Modules/ado/personal/t/traces v4.ado new file mode 100644 index 0000000..08eef7d --- /dev/null +++ b/Modules/ado/personal/t/traces v4.ado @@ -0,0 +1,346 @@ +*! Version 4 22January2015 +************************************************************************************************************ +* Traces: Traces of items +* Version 4: January 22, 2015 /*ICC*/ +* +* Historic: +* Version 1 (2003-06-29): Jean-Benoit Hardouin +* Version 2 (2003-07-04): Jean-Benoit Hardouin +* version 3 (2003-07-09): Jean-Benoit Hardouin +* Version 3.1 (2005-06-07): Jean-Benoit Hardouin /*small modifications*/ +* Version 3.2: May 27, 2007 /*onlyone option*/ +* Version 3.3: October 16, 2012 /*minor modifications*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2003, 2005, 2007, 2012, 2015 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define traces, rclass +version 8.0 +syntax varlist(numeric min=2) [, COMPare(varlist min=2 max=2) ICC SAVeicc noGraph Score Test Restscore Logistic CI CUMulative REPFiles(string) SCOREFiles(string) RESTSCOREFiles(string) LOGISTICFile(string) noDraw noDRAWComb REPlace ONLYone(string) THResholds(string) Black] + +local nbitems : word count `varlist' +tokenize `varlist' + +if "`onlyone'"!=""&"`drawcomb'"!="" { + local drawcomb +} + +tempvar varscore +qui gen `varscore'=0 +label variable `varscore' "Total score" +local scoremax=0 +local flag=0 + +if "`score'"==""&"`restscore'"==""&&"`logistic'"=="" { + local score="score" +} + +local modamax=0 +forvalues i=1/`nbitems' { + qui replace `varscore'=`varscore'+``i'' + qui su ``i'' + local modamax`i'=r(max) + if r(min)!=0 { + local flag=1 + } + local scoremax=`scoremax'+`modamax`i'' + if `modamax`i''!=1 { + local flagbin=0 + } + if `modamax`i''>`modamax' { + local modamax=`modamax`i'' + } +} + + +if `flag'==1 { + di as error "The lower modality of the item must be 0" + exit +} +if "`flagbin'"!=""&"`logistic'"!="" { + di as error "The logistic option is not possible with polytomous items" + exit +} + +qui su `varscore' +local maxscore=r(max) + +forvalues i=0/`maxscore' { + qui count if `varscore'==`i' + local nscore`i'=r(N) +} + + +global score +global restscore +global logistic +qui count +local N=r(N) +if `c(matsize)'<`N'&"`saveicc'"!="" { + set matsize `N' +} + + +if "`score'"!="" { + if "`thresholds'"!="" { + * set trace on + local nbth:word count `thresholds' + forvalues t=1/`nbth' { + local th`t':word `t' of `thresholds' + } + tempname label + local recode 0/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1' + qui label define `label' 1 "0/`th1'",add + qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add + forvalues j=2/`nbth' { + local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j' + qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add + } + tempname varscore2 + qui gen `varscore2'=`varscore' + qui recode `varscore' `recode' + qui label values `varscore' `label' + local nbgroups=`nbth'+1 + local minimum=1 + } + else { + local nbgroups=`maxscore' + local minimum=0 + } + local listicc + + forvalues i=1/`nbitems' { + local y`i' + tempvar icc``i'' + gen `icc``i'''=0 + local listicc `listicc' `icc``i''' + forvalues k=1/`modamax`i'' { + tempvar propscore`i'`k' tmp + if "`cumulative'"!="" { + qui gen `tmp'=``i''>=`k'&``i''!=. + bysort `varscore' : egen `propscore`i'`k''=mean(`tmp') + label variable `propscore`i'`k'' "Item ``i''>=`k'" + } + else { + qui gen `tmp'=``i''==`k'&``i''!=. + bysort `varscore' : egen `propscore`i'`k''=mean(`tmp') + label variable `propscore`i'`k'' "Item ``i''=`k'" + *di "replace icc``i''=icc``i''+`k'*`propscore`i'`k''" + qui replace `icc``i'''=`icc``i'''+`k'*`propscore`i'`k'' + } + local y`i'="`y`i'' `propscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icscoreminus icscoreplus + forvalues l=1/`maxscore' { + qui count if `varscore'==`l' + local nscore`l'=r(N) + } + qui gen `icscoreminus'=`propscore`i'1'-1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1') + qui gen `icscoreplus'=`propscore`i'1'+1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1') + label variable `icscoreminus' "Lower 95% confidence interval" + label variable `icscoreplus' "Upper 95% confidence interval" + local y`i'="`icscoreminus' `icscoreplus' `propscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `propscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + } + + if ("``i''"=="`onlyone'"|"`onlyone'"=="")&"`nograph'"=="" { + qui graph twoway (line `y`i'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , note("`note'") ylabel(0(.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(score`i',replace) title("Trace of the item ``i'' as a function of the score") ytitle("Rate of positive response") `draw' /*areastyle(none)*/ + } + if ("``i''"=="`onlyone'"|"`onlyone'"=="")&"`icc'"!=""&"`nograph'"!=""{ + qui graph twoway (line `icc``i''' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax`i'') xlabel(`minimum'(1)`nbgroups',valuelabel) name(icc`i',replace) title("Approximate ICC of the item ``i'' as a function of the score") ytitle("Mean response") `draw' /*areastyle(none)*/ + } + global score "$score score`i'" + if "`scorefiles'"!="" { + graph save score`i' `repfiles'\\`scorefiles'``i'' ,`replace' + } + } + if "`saveicc'"!="" { + local listicc `listicc' `varscore' + tempname matscore + mkmat `listicc',matrix(`matscore') + } + if "`thresholds'"!="" { + qui replace `varscore'=`varscore2' + } +} + if "`compare'"!=""&"`nograph'"!="" { + local tmp1 : word 1 of `compare' + local tmp2 : word 2 of `compare' + di "compare `compare' tmp1 `tmp1' tmp2 `tmp2'" + label variable `icc`tmp1'' `tmp1' + label variable `icc`tmp2'' `tmp2' + di "qui graph twoway (line `icc`tmp1'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) (line `icc`tmp2'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax') xlabel(`minimum'(1)`nbgroups',valuelabel) name(score`i',replace) title(Comparison of the ICC of the items `tmp1' and `tmp2') `draw' /*areastyle(none)*/" + qui graph twoway (line `icc`tmp1'' `varscore', clpattern(`style') clcolor(blue red) clwidth(`width')) (line `icc`tmp2'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax') xlabel(`minimum'(1)`nbgroups',valuelabel) /*name(score`i',replace)*/ title("Comparison of the ICC of the items `tmp1' and `tmp2'") ytitle("Mean response") /*areastyle(none)*/ + } +if "`restscore'"!="" { + forvalues i=1/`nbitems' { + local y`i' + tempvar restscore`i' + qui gen `restscore`i''=`varscore'-``i'' + label variable `restscore`i'' "Rest score with respect to the item ``i''" + if "`thresholds'"!="" { + * set trace on + local nbth:word count `thresholds' + forvalues t=1/`nbth' { + local th`t':word `t' of `thresholds' + } + tempname label + local recode 0/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1' + qui label define `label' 1 "0/`th1'",add + qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add + forvalues j=2/`nbth' { + local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j' + qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add + } + + *di "recode `restscore`i'' `recode'" + qui recode `restscore`i'' `recode' + qui label values `restscore`i'' `label' + local nbgroups=`nbth'+1 + local minimum=1 + } + else { + local nbgroups=`maxscore' + local minimum=0 + } + + forvalues k=1/`modamax`i'' { + tempvar rtmp proprestscore`i'`k' + if "`cumulative'"!="" { + qui gen `rtmp'=``i''>=`k'&``i''!=. + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''>=`k'" + } + else { + qui gen `rtmp'=``i''==`k'&``i''!=. + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''=`k'" + } + local y`i'="`y`i'' `proprestscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icrestscoreminus icrestscoreplus + qui su `restscore`i'' + local maxrestscore=r(max) + forvalues l=1/`maxrestscore' { + qui count if `restscore`i''==`l' + local nrestscore`i'=r(N) + } + qui gen `icrestscoreminus'=`proprestscore`i'1'-1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + qui gen `icrestscoreplus'=`proprestscore`i'1'+1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + label variable `icrestscoreminus' "Lower 95% confidence interval" + label variable `icrestscoreplus' "Upper 95% confidence interval" + local y`i'="`icrestscoreminus' `icrestscoreplus' `proprestscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `proprestscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + } + local restscoremax=`scoremax'-`modamax`i'' + if ("``i''"=="`onlyone'"|"`onlyone'"=="")&"`nograph'"!="" { + *tab `proprestscore`i'1' `restscore`i'' + qui graph twoway (line `y`i'' `restscore`i'', clpattern(`style') clcolor(`color') clwidth(`width')), note("`note'") ylabel(0(0.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(restscore`i',replace) title("Trace of the item ``i'' as a function of the restscore") ytitle("Rate of positive response") `draw' + } + global restscore "$restscore restscore`i'" + if "`restscorefiles'"!="" { + graph save restscore`i' `repfiles'\\`restscorefiles'``i'' ,`replace' + } + } +} +if "logistic"!="" { + forvalues i=1/`nbitems' { + qui logistic ``i'' `varscore' + tempname coef + matrix `coef'=e(b) + local pente`i'=`coef'[1,1] + local intercept`i'=`coef'[1,2] + tempvar logit`i' + qui gen `logit`i''=exp(`intercept`i''+`pente`i''*`varscore')/(1+exp(`intercept`i''+`pente`i''*`varscore')) + label variable `logit`i'' "Item ``i''" + sort `varscore' + global logistic "$logistic `logit`i''" + } +} +if "`drawcomb'"!="" { + local drawcomb="nodraw" +} + +if ("`score'"!=""&"`onlyone'"=="")&"`nograph'"!="" { + graph combine $score , title("Trace of the items as a function of the score") name(score,replace) `drawcomb' + if "`scorefiles'"!="" { + graph save score `repfiles'\\`scorefiles' ,`replace' + } +} + +if ("`restscore'"!=""&"`onlyone'"=="")&"`nograph'"!="" { + graph combine $restscore , title("Trace of the items as a function of the restscores") name(restscore,replace) `drawcomb' + if "`restscorefiles'"!="" { + graph save restscore `repfiles'\\`restscorefiles' ,`replace' + } +} +if ("`logistic'"!="")&"`nograph'"!="" { + graph twoway (line $logistic `varscore'), ylabel(0(0.25)1) xlabel(0(1)`nbitems') title("Logistic traces") ytitle("") name(logistic,replace) `drawcomb' + if "`logisticfile'"!="" { + graph save logistic `repfiles'\\`logisticfile' ,`replace' + } +} +if "`saveicc'"!="" { + return matrix matscore=`matscore' +} +end + + diff --git a/Modules/ado/personal/t/traces v5 avec items numeric ne marche pas - Copie.ado b/Modules/ado/personal/t/traces v5 avec items numeric ne marche pas - Copie.ado new file mode 100644 index 0000000..1ba1be2 --- /dev/null +++ b/Modules/ado/personal/t/traces v5 avec items numeric ne marche pas - Copie.ado @@ -0,0 +1,357 @@ +*! Version 5 5March2016 +************************************************************************************************************ +* Traces: Traces of items +* Version 5: March 5, 2016 /*numerical items*/ +* +* Historic: +* Version 1 (2003-06-29): Jean-Benoit Hardouin +* Version 2 (2003-07-04): Jean-Benoit Hardouin +* version 3 (2003-07-09): Jean-Benoit Hardouin +* Version 3.1 (2005-06-07): Jean-Benoit Hardouin /*small modifications*/ +* Version 3.2: May 27, 2007 /*onlyone option*/ +* Version 3.3: October 16, 2012 /*minor modifications*/ +* Version 4: January 22, 2015 /*ICC*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* EA4275-SPHERE "MethodS in Patients-centered outcomes and HEalth ResEarches" +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2003, 2005, 2007, 2012, 2015, 2016 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define traces, rclass +version 8.0 +syntax varlist(numeric min=2) [, COMPare(varlist min=2 max=2) ICC SAVeicc noGraph Score Test Restscore Logistic CI CUMulative REPFiles(string) SCOREFiles(string) RESTSCOREFiles(string) LOGISTICFile(string) noDraw noDRAWComb REPlace ONLYone(string) THResholds(string) Black] + +local nbitems : word count `varlist' +tokenize `varlist' + +if "`onlyone'"!=""&"`drawcomb'"!="" { + local drawcomb +} + +tempvar varscore +qui gen `varscore'=0 +label variable `varscore' "Total score" +local scoremax=0 +local flag=0 + +if "`score'"==""&"`restscore'"==""&&"`logistic'"=="" { + local score="score" +} + +local modamax=-999 +local modamin=999 +forvalues i=1/`nbitems' { + qui replace `varscore'=`varscore'+``i'' + qui su ``i'' + local modamax`i'=r(max) + local modamin`i'=r(min) + if r(min)!=0 { + local flag=1 + } + local scoremax=`scoremax'+`modamax`i'' + if `modamax`i''!=1 { + local flagbin=0 + } + if `modamax`i''>`modamax' { + local modamax=`modamax`i'' + } + if `modamin`i''<`modamin' { + local modamin=`modamin`i'' + } +} + +/* +if `flag'==1 { + di as error "The lower modality of the item must be 0" + exit +} +*/ +if "`flagbin'"!=""&"`logistic'"!="" { + di as error "The logistic option is not possible with polytomous items" + exit +} + +qui su `varscore' +local maxscore=r(max) +local minscore=r(min) + +forvalues i=`minscore'/`maxscore' { + qui count if `varscore'>`=`i'-0.5'&`varscore'<=`=`i'+0.5' + local nscore`i'=r(N) +} + + +global score +global restscore +global logistic +qui count +local N=r(N) +if `c(matsize)'<`N'&"`saveicc'"!="" { + set matsize `N' +} + + +if "`score'"!="" { + if "`thresholds'"!="" { + * set trace on + local nbth:word count `thresholds' + forvalues t=1/`nbth' { + local th`t':word `t' of `thresholds' + } + tempname label + local recode min/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1' + qui label define `label' 1 "min/`th1'",add + qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add + forvalues j=2/`nbth' { + local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j' + qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add + } + tempname varscore2 + qui gen `varscore2'=`varscore' + qui recode `varscore' `recode' + qui label values `varscore' `label' + local nbgroups=`nbth'+1 + local minimum=1 + } + else { + local nbgroups=`maxscore' + local minimum=0 + } + local listicc + + forvalues i=1/`nbitems' { + local y`i' + tempvar icc``i'' + gen `icc``i'''=0 + local listicc `listicc' `icc``i''' + local l=0 + forvalues k=`=`modamin`i''+1'/`modamax`i'' { + tempvar propscore`i'`l' tmp + if "`cumulative'"!="" { + qui gen `tmp'=``i''>=`k'&``i''!=. + bysort `varscore' : egen `propscore`i'`l''=mean(`tmp') + label variable `propscore`i'`l'' "Item ``i''>=`k'" + } + else { + qui gen `tmp'=``i''==`k'&``i''!=. + bysort `varscore' : egen `propscore`i'`l''=mean(`tmp') + label variable `propscore`i'`l'' "Item ``i''=`k'" + *di "replace icc``i''=icc``i''+`k'*`propscore`i'`k''" + qui replace `icc``i'''=`icc``i'''+`k'*`propscore`i'`l'' + } + local y`i'="`y`i'' `propscore`i'`l''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icscoreminus icscoreplus + forvalues m=1/`maxscore' { + qui count if `varscore'==`m' + local nscore`m'=r(N) + } + qui gen `icscoreminus'=`propscore`i'1'-1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1') + qui gen `icscoreplus'=`propscore`i'1'+1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1') + label variable `icscoreminus' "Lower 95% confidence interval" + label variable `icscoreplus' "Upper 95% confidence interval" + local y`i'="`icscoreminus' `icscoreplus' `propscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `propscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + local ++l + } + + if ("``i''"=="`onlyone'"|"`onlyone'"=="")&"`graph'"=="" { + qui graph twoway (line `y`i'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , note("`note'") ylabel(0(.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(score`i',replace) title("Trace of the item ``i'' as a function of the score") ytitle("Rate of positive response") `draw' /*areastyle(none)*/ + } + if ("``i''"=="`onlyone'"|"`onlyone'"=="")&"`icc'"!=""&"`graph'"==""{ + qui graph twoway (line `icc``i''' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax`i'') xlabel(`minimum'(1)`nbgroups',valuelabel) name(icc`i',replace) title("Approximate ICC of the item ``i'' as a function of the score") ytitle("Mean response") `draw' /*areastyle(none)*/ + } + global score "$score score`i'" + if "`scorefiles'"!="" { + graph save score`i' `repfiles'\\`scorefiles'``i'' ,`replace' + } + } + if "`saveicc'"!="" { + local listicc `listicc' `varscore' + tempname matscore + mkmat `listicc',matrix(`matscore') + } + if "`thresholds'"!="" { + qui replace `varscore'=`varscore2' + } +} + if "`compare'"!=""&"`nograph'"!="" { + local tmp1 : word 1 of `compare' + local tmp2 : word 2 of `compare' + di "compare `compare' tmp1 `tmp1' tmp2 `tmp2'" + label variable `icc`tmp1'' `tmp1' + label variable `icc`tmp2'' `tmp2' + di "qui graph twoway (line `icc`tmp1'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) (line `icc`tmp2'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax') xlabel(`minimum'(1)`nbgroups',valuelabel) name(score`i',replace) title(Comparison of the ICC of the items `tmp1' and `tmp2') `draw' /*areastyle(none)*/" + qui graph twoway (line `icc`tmp1'' `varscore', clpattern(`style') clcolor(blue red) clwidth(`width')) (line `icc`tmp2'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax') xlabel(`minimum'(1)`nbgroups',valuelabel) /*name(score`i',replace)*/ title("Comparison of the ICC of the items `tmp1' and `tmp2'") ytitle("Mean response") /*areastyle(none)*/ + } +if "`restscore'"!="" { + forvalues i=1/`nbitems' { + local y`i' + tempvar restscore`i' + qui gen `restscore`i''=`varscore'-``i'' + label variable `restscore`i'' "Rest score with respect to the item ``i''" + if "`thresholds'"!="" { + * set trace on + local nbth:word count `thresholds' + forvalues t=1/`nbth' { + local th`t':word `t' of `thresholds' + } + tempname label + local recode 0/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1' + qui label define `label' 1 "min/`th1'",add + qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add + forvalues j=2/`nbth' { + local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j' + qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add + } + + *di "recode `restscore`i'' `recode'" + qui recode `restscore`i'' `recode' + qui label values `restscore`i'' `label' + local nbgroups=`nbth'+1 + local minimum=1 + } + else { + local nbgroups=`maxscore' + local minimum=0 + } + + forvalues k=1/`modamax`i'' { + tempvar rtmp proprestscore`i'`k' + if "`cumulative'"!="" { + qui gen `rtmp'=``i''>=`k'&``i''!=. + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''>=`k'" + } + else { + qui gen `rtmp'=``i''==`k'&``i''!=. + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''=`k'" + } + local y`i'="`y`i'' `proprestscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icrestscoreminus icrestscoreplus + qui su `restscore`i'' + local maxrestscore=r(max) + forvalues l=1/`maxrestscore' { + qui count if `restscore`i''==`l' + local nrestscore`i'=r(N) + } + qui gen `icrestscoreminus'=`proprestscore`i'1'-1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + qui gen `icrestscoreplus'=`proprestscore`i'1'+1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + label variable `icrestscoreminus' "Lower 95% confidence interval" + label variable `icrestscoreplus' "Upper 95% confidence interval" + local y`i'="`icrestscoreminus' `icrestscoreplus' `proprestscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `proprestscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + } + local restscoremax=`scoremax'-`modamax`i'' + if ("``i''"=="`onlyone'"|"`onlyone'"=="")&"`nograph'"!="" { + *tab `proprestscore`i'1' `restscore`i'' + qui graph twoway (line `y`i'' `restscore`i'', clpattern(`style') clcolor(`color') clwidth(`width')), note("`note'") ylabel(0(0.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(restscore`i',replace) title("Trace of the item ``i'' as a function of the restscore") ytitle("Rate of positive response") `draw' + } + global restscore "$restscore restscore`i'" + if "`restscorefiles'"!="" { + graph save restscore`i' `repfiles'\\`restscorefiles'``i'' ,`replace' + } + } +} +if "`logistic'"!="" { + forvalues i=1/`nbitems' { + qui logistic ``i'' `varscore' + tempname coef + matrix `coef'=e(b) + local pente`i'=`coef'[1,1] + local intercept`i'=`coef'[1,2] + tempvar logit`i' + qui gen `logit`i''=exp(`intercept`i''+`pente`i''*`varscore')/(1+exp(`intercept`i''+`pente`i''*`varscore')) + label variable `logit`i'' "Item ``i''" + sort `varscore' + global logistic "$logistic `logit`i''" + } +} +if "`drawcomb'"!="" { + local drawcomb="nodraw" +} + +*di " (`score'!=&`onlyone'==)&`nograph'!= {" +if ("`score'"!=""&"`onlyone'"=="")&"`nograph'"!="" { + graph combine $score , title("Trace of the items as a function of the score") name(score,replace) `drawcomb' + if "`scorefiles'"!="" { + graph save score `repfiles'\\`scorefiles' ,`replace' + } +} + +if ("`restscore'"!=""&"`onlyone'"=="")&"`nograph'"!="" { + graph combine $restscore , title("Trace of the items as a function of the restscores") name(restscore,replace) `drawcomb' + if "`restscorefiles'"!="" { + graph save restscore `repfiles'\\`restscorefiles' ,`replace' + } +} +if ("`logistic'"!="")&"`nograph'"!="" { + graph twoway (line $logistic `varscore'), ylabel(0(0.25)1) xlabel(0(1)`nbitems') title("Logistic traces") ytitle("") name(logistic,replace) `drawcomb' + if "`logisticfile'"!="" { + graph save logistic `repfiles'\\`logisticfile' ,`replace' + } +} +if "`saveicc'"!="" { + return matrix matscore=`matscore' +} +end + + diff --git a/Modules/ado/personal/t/traces.ado b/Modules/ado/personal/t/traces.ado new file mode 100644 index 0000000..c5751c0 --- /dev/null +++ b/Modules/ado/personal/t/traces.ado @@ -0,0 +1,429 @@ +*! Version 5.2 24September2019 +*!Jean-Benoit Hardouin +* +************************************************************************************************************ +* Traces: Traces of items +* +* Historic: +* Version 1 (2003-06-29) [Jean-Benoit Hardouin] +* Version 2 (2003-07-04 [Jean-Benoit Hardouin] +* version 3 (2003-07-09) [Jean-Benoit Hardouin] +* Version 3.1 (2005-06-07) [Jean-Benoit Hardouin] /*small modifications*/ +* Version 3.2: May 27, 2007 [Jean-Benoit Hardouin] /*onlyone option*/ +* Version 3.3: October 16, 2012 [Jean-Benoit Hardouin] /*minor modifications*/ +* Version 4: January 22, 2015 [Jean-Benoit Hardouin] /*ICC*/ +* Version 5: March 5, 2016 [Jean-Benoit Hardouin] /*numerical items*/ +* Version 5.1: July 13, 2019 [Jean-Benoit Hardouin] /*Bugs Corrections*/ +* Version 5.2: September 24, 2019 [Jean-Benoit Hardouin] /*Bugs Corrections*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program :http://www.anaqol.org +* +* Copyright 2003, 2005, 2007, 2012, 2015, 2016, 2019 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define traces, rclass +version 8.0 +syntax varlist(numeric min=2) [, /*COMPare(varlist min=2 max=2*/ ICC noGraph Score Test Restscore Logistic CI CUMulative REPFiles(string) DIRSave(string) FILESave SCOREFiles(string) RESTSCOREFiles(string) LOGISTICFile(string) ICCFile(string) noDraw noDRAWComb REPlace ONLYone(string) THResholds(string) Black] + +local nbitems : word count `varlist' +tokenize `varlist' + +if "`onlyone'"!=""&"`drawcomb'"!="" { + local drawcomb +} + +if "`repfiles'"!=""&"`dirsave'"=="" { + local dirsave `repfile' +} +if "`filesave'"=="" { + local saving +} +else { + if "`dirsave'"=="" { + local dirsave `c(pwd)' + } + if "`scorefiles'"=="" { + local scorefiles score + } + if "`restscorefiles'"=="" { + local restscorefiles restscore + } + if "`logicticfile'"=="" { + local logisticfile logistic + } + if "`iccfiles'"=="" { + local iccfiles icc + } +} + +tempvar varscore +qui gen `varscore'=0 +label variable `varscore' "Total score" +local scoremax=0 +local flag=0 + +if "`score'"==""&"`restscore'"==""&&"`logistic'"=="" { + local score="score" +} + +local modamax=-999 +local modamin=999 +forvalues i=1/`nbitems' { + qui replace `varscore'=`varscore'+``i'' + qui su ``i'' + local modamax`i'=r(max) + local modamin`i'=r(min) + if r(min)!=0 { + local flag=1 + } + local scoremax=`scoremax'+`modamax`i'' + if `modamax`i''!=1 { + local flagbin=0 + } + if `modamax`i''>`modamax' { + local modamax=`modamax`i'' + } + if `modamin`i''<`modamin' { + local modamin=`modamin`i'' + } +} + +/* +if `flag'==1 { + di as error "The lower modality of the item must be 0" + exit +} +*/ +if "`flagbin'"!=""&"`logistic'"!="" { + di as error "The logistic option is not possible with polytomous items" + exit +} + +qui su `varscore' +local maxscore=r(max) +local minscore=r(min) + +forvalues i=`minscore'/`maxscore' { + qui count if `varscore'>`=`i'-0.5'&`varscore'<=`=`i'+0.5' + local nscore`i'=r(N) +} + + +global score +global restscore +global logistic +qui count +local N=r(N) +if `c(matsize)'<`N'&"`saveicc'"!="" { + set matsize `N' +} + + +if "`score'"!="" { + if "`thresholds'"!="" { + * set trace on + local nbth:word count `thresholds' + forvalues t=1/`nbth' { + local th`t':word `t' of `thresholds' + } + tempname label + local recode min/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1' + qui label define `label' 1 "min/`th1'",add + qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add + forvalues j=2/`nbth' { + local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j' + qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add + } + tempname varscore2 + qui gen `varscore2'=`varscore' + qui recode `varscore' `recode' + qui label values `varscore' `label' + local nbgroups=`nbth'+1 + local minimum=1 + } + else { + local nbgroups=`maxscore' + local minimum=0 + } + local listicc + local widthicc + + forvalues i=1/`nbitems' { + local y`i' + tempvar icc``i'' + gen `icc``i'''=0 + label variable `icc``i''' "``i''" + local listicc `listicc' `icc``i''' + local l=0 + *set trace on + forvalues k=`=`modamin`i''+1'/`modamax`i'' { + tempvar propscore`i'`k' tmp propscoreicc`i'`k' tmp2 + if "`cumulative'"!="" { + qui gen `tmp'=``i''>=`k'&``i''!=. + bysort `varscore' : egen `propscore`i'`k''=mean(`tmp') + label variable `propscore`i'`k'' "Item ``i''>=`k'" + } + else { + qui gen `tmp'=``i''==`k'&``i''!=. + bysort `varscore' : egen `propscore`i'`k''=mean(`tmp') + label variable `propscore`i'`k'' "Item ``i''=`k'" + } + if "`icc'"!="" { + qui gen `tmp2'=``i''==`k'&``i''!=. + bysort `varscore' : egen `propscoreicc`i'`k''=mean(`tmp2') + qui replace `icc``i'''=`icc``i'''+`k'*`propscoreicc`i'`k'' + } + *di "replace icc``i''=icc``i''+`k'*`propscore`i'`k''" + local y`i'="`y`i'' `propscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icscoreminus icscoreplus + forvalues m=1/`maxscore' { + qui count if `varscore'==`m' + local nscore`m'=r(N) + } + qui gen `icscoreminus'=`propscore`i'1'-1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1') + qui gen `icscoreplus'=`propscore`i'1'+1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1') + label variable `icscoreminus' "Lower 95% confidence interval" + label variable `icscoreplus' "Upper 95% confidence interval" + local y`i'="`icscoreminus' `icscoreplus' `propscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `propscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + local ++l + } + *set trace on + if ("``i''"=="`onlyone'"|"`onlyone'"=="")&"`graph'"=="" { + if "`filesave'"!="" { + local saving "saving(`dirsave'//`scorefiles'_``i'',replace)" + } + qui graph twoway (line `y`i'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , note("`note'") ylabel(0(.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(score`i',replace) title("Trace of the item ``i'' as a function of the score") ytitle("Rate of positive response") `draw' `saving' + } + if ("``i''"=="`onlyone'"|"`onlyone'"=="")&"`icc'"!=""&"`graph'"==""{ + if "`filesave'"!="" { + local saving "saving(`dirsave'//`iccfiles'_``i'',replace)" + } + local widthicc `widthicc' medthick + qui graph twoway (line `icc``i''' `varscore', /*clpattern(`style') clcolor(`color')*/ clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax`i'') xlabel(`minimum'(1)`nbgroups',valuelabel) name(icc`i',replace) title("Approximate ICC of the item ``i'' as a function of the score") ytitle("Mean response") `draw' `saving' + } + /* + global score "$score score`i'" + if "`scorefiles'"!="" { + graph save score`i' `dirsave'\\`scorefiles'``i'' ,`replace' + } + */ + } + if "`saveicc'"!="" { + local listicc `listicc' `varscore' + tempname matscore + mkmat `listicc',matrix(`matscore') + } + if "`thresholds'"!="" { + qui replace `varscore'=`varscore2' + } + if "`onlyone'"==""&"`icc'"!=""&"`graph'"=="" { + if "`filesave'"!="" { + local saving "saving(`dirsave'//`iccfiles',replace)" + } + qui graph twoway (line `listicc' `varscore', /*clpattern(`style') clcolor(`color')*/ clwidth(`widthicc')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax`i'') xlabel(`minimum'(1)`nbgroups',valuelabel) name(icc,replace) title("Approximate ICC of the items as a function of the score") ytitle("Mean response") `draw' `saving' + } +} +/* + if "`compare'"!=""&"`graph'"=="" { + local tmp1 : word 1 of `compare' + local tmp2 : word 2 of `compare' + di "compare `compare' tmp1 `tmp1' tmp2 `tmp2'" + label variable `icc`tmp1'' `tmp1' + label variable `icc`tmp2'' `tmp2' + di "qui graph twoway (line `icc`tmp1'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) (line `icc`tmp2'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax') xlabel(`minimum'(1)`nbgroups',valuelabel) name(score`i',replace) title(Comparison of the ICC of the items `tmp1' and `tmp2') `draw' /*areastyle(none)*/" + qui graph twoway (line `icc`tmp1'' `varscore', clpattern(`style') clcolor(blue red) clwidth(`width')) (line `icc`tmp2'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax') xlabel(`minimum'(1)`nbgroups',valuelabel) /*name(score`i',replace)*/ title("Comparison of the ICC of the items `tmp1' and `tmp2'") ytitle("Mean response") /*areastyle(none)*/ + } +*/ +*set trace on +if "`restscore'"!="" { + forvalues i=1/`nbitems' { + local y`i' + tempvar restscore`i' + qui gen `restscore`i''=`varscore'-``i'' + label variable `restscore`i'' "Rest score with respect to the item ``i''" + if "`thresholds'"!="" { + * set trace on + local nbth:word count `thresholds' + forvalues t=1/`nbth' { + local th`t':word `t' of `thresholds' + } + tempname label + local recode 0/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1' + qui label define `label' 1 "min/`th1'",add + qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add + forvalues j=2/`nbth' { + local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j' + qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add + } + + *di "recode `restscore`i'' `recode'" + qui recode `restscore`i'' `recode' + qui label values `restscore`i'' `label' + local nbgroups=`nbth'+1 + local minimum=1 + } + else { + local nbgroups=`maxscore' + local minimum=0 + } + + forvalues k=1/`modamax`i'' { + tempvar rtmp proprestscore`i'`k' + if "`cumulative'"!="" { + qui gen `rtmp'=``i''>=`k'&``i''!=. + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''>=`k'" + } + else { + qui gen `rtmp'=``i''==`k'&``i''!=. + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''=`k'" + } + local y`i'="`y`i'' `proprestscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icrestscoreminus icrestscoreplus + qui su `restscore`i'' + local maxrestscore=r(max) + forvalues l=1/`maxrestscore' { + qui count if `restscore`i''==`l' + local nrestscore`i'=r(N) + } + qui gen `icrestscoreminus'=`proprestscore`i'1'-1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + qui gen `icrestscoreplus'=`proprestscore`i'1'+1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + label variable `icrestscoreminus' "Lower 95% confidence interval" + label variable `icrestscoreplus' "Upper 95% confidence interval" + local y`i'="`icrestscoreminus' `icrestscoreplus' `proprestscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `proprestscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + } + local restscoremax=`scoremax'-`modamax`i'' + if ("``i''"=="`onlyone'"|"`onlyone'"=="")&"`graph'"=="" { + if "`filesave'"!="" { + local saving "saving(`dirsave'//`restscorefiles'_``i'',replace)" + } + qui graph twoway (line `y`i'' `restscore`i'', clpattern(`style') clcolor(`color') clwidth(`width')), note("`note'") ylabel(0(0.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(restscore`i',replace) title("Trace of the item ``i'' as a function of the restscore") ytitle("Rate of positive response") `draw' `saving' + } + /* + global restscore "$restscore restscore`i'" + if "`restscorefiles'"!="" { + graph save restscore`i' `dirsave'\\`restscorefiles'``i'' ,`replace' + } + */ + } +} +if "`logistic'"!="" { + forvalues i=1/`nbitems' { + qui logistic ``i'' `varscore' + tempname coef + matrix `coef'=e(b) + local pente`i'=`coef'[1,1] + local intercept`i'=`coef'[1,2] + tempvar logit`i' + qui gen `logit`i''=exp(`intercept`i''+`pente`i''*`varscore')/(1+exp(`intercept`i''+`pente`i''*`varscore')) + label variable `logit`i'' "Item ``i''" + sort `varscore' + global logistic "$logistic `logit`i''" + } +} + +if "`score'"!=""&"`onlyone'"==""&"`graph'"==""&"`drawcomb'"=="" { + if "`filesave'"!="" { + local saving "saving(`dirsave'//`scorefiles',replace)" + } + local score + local restscoreg + forvalues i=1/`nbitems'{ + local score `score' score`i' + local restscoreg `restscoreg' restscore`i' + } + + qui graph combine `score', title("Trace of the items as a function of the score") name(score,replace) `draw' `saving' + /* + if "`scorefiles'"!="" { + graph save score `dirsave'\\`scorefiles' ,`replace' + } + */ +} + +if "`restscore'"!=""&"`onlyone'"==""&"`graph'"==""&"`drawcomb'"=="" { + if "`filesave'"!="" { + local saving "saving(`dirsave'//`restscorefiles',replace)" + } + qui graph combine `restscoreg' , title("Trace of the items as a function of the restscores") name(restscore,replace) `draw' `saving' + /* + if "`restscorefiles'"!="" { + graph save restscore `dirsave'\\`restscorefiles' ,`replace' + } + */ +} +if "`logistic'"!=""&"`onlyone'"==""&"`graph'"=="" { + if "`filesave'"!="" { + local saving "saving(`dirsave'//`logisticfile',replace)" + } + qui graph twoway (line $logistic `varscore'), ylabel(0(0.25)1) xlabel(0(1)`nbitems') title("Logistic traces") ytitle("") name(logistic,replace) `draw' + /* + if "`logisticfile'"!="" { + graph save logistic `dirsave'\\`logisticfile' ,`replace' + } + */ +} +if "`saveicc'"!="" { + return matrix matscore=`matscore' +} +end + + diff --git a/Modules/ado/personal/t/traces.hlp b/Modules/ado/personal/t/traces.hlp new file mode 100644 index 0000000..af423a4 --- /dev/null +++ b/Modules/ado/personal/t/traces.hlp @@ -0,0 +1,99 @@ +{smcl} +{* 6May2013}{...} +{hline} +help for {hi:traces}{right:Jean-Benoit Hardouin} +{hline} + +{title:Graphical representations of the traces of dichotomous and polytomous items} + +{p 8 14 2}{cmd:traces} {it:varlist} [{cmd:,} {cmdab:s:core} {cmdab:r:estscore} +{cmdab:ci} {cmdab:t:est} {cmdab:cum:ulative} {cmdab:l:ogistic} +{cmdab:repf:ile}({it:directory}) {cmdab:scoref:iles}({it:string}) +{cmdab:restscoref:iles}({it:string}) {cmdab:logisticf:ile}({it:string}) +{cmdab:nod:raw} {cmdab:nodrawc:omb} {cmdab:rep:lace} {cmdab:only:one}({it:varname}) {cmdab:thr:esholds}({it:string})] + + +{title:Description} + +{p 4 8 2}{cmd:traces} builds graphical representations of various kinds of +traces (non parametric Item Response Functions) for dichotomous or polytomous items. + +{title:Options} + +{p 4 8 2}{cmd:score} displays the graphical representations of the traces of the +items as a function of the total score. This is the defaut option if none {cmd:score}, +none {cmd:restscore}, none {cmd:logistic} are indicated. + +{p 4 8 2}{cmd:restscore} displays the graphical representations of the +traces of the items as a function of the rest-score (total score unless the item). + +{p 4 8 2}{cmd:ci} displays the confidence interval at 95% of the traces. + +{p 4 8 2}{cmd:test} tests the nullity of the slope of dichotomous items traces +with a linear model. + +{p 4 8 2}{cmd:cumulative} displays cumulative traces for polytomous +items instead of classical traces. + +{p 4 8 2}{cmd:logistic} displays the graphical representation of the logitic +traces of the items as a function of the score: each trace is the result of a +logistic model with the response to the item as variable to explicate and the +score (and a constant) as explicative variable. This kind of trace is possible +only for dichotomous items. All the logistic traces are represented in the same +graph. + +{p 4 8 2}{cmd:repfile}({it:directory}) is the directory where the files are saved. + +{p 4 8 2}{cmd:scorefiles}({it:string}) defines the generic name of the files containing the graphical representations of the traces as a function of the score. +The name will be followed by the name of each item and by the .gph extension. If this option is not +indicated, the corresponding graphs will be not saved. + +{p 4 8 2}{cmd:restscorefiles}({it:string}) defines the generic name of the files containing the graphical representations of the traces as a function of the rest-scores. +The name will be followed by the name of each item and by the .gph extension. If this option is not +indicated, the corresponding graphs will be not saved. + +{p 4 8 2}{cmd:logisticfile}({it:string}) defines the name of the file containing the graphical representations of the logistic traces. This name will be followed by the .gph extension. +If this option is not indicated, the corresponding graph will be not saved. + +{p 4 8 2}{cmd:nodraw} does not display the graphs by items. + +{p 4 8 2}{cmd:nodrawcomb} does not display the combined graphs by items. + +{p 4 8 2}{cmd:replace} replaces graphical files when they already exist. + +{p 4 8 2}{cmd:onlyone} displays only the trace of a given item. + +{p 4 8 2}{cmd:thresholds} groups the individuals as a function of the (rest-)score. The string contains the maximal values of the (rest-)score in each group. + + + +{title:Example} + + {p 4 8 2}{cmd:. traces item1 item2 item3 item4 , score repfile(c:\graphs) scorefiles(score) nodraw nodrawcomb replace} /*creates the graphs files of the +traces as a function of the score but do not display them.*/ + + {p 4 8 2}{cmd:. traces item1 item2 item3 item4 , score restscore} /*displays +the graphical representations of the traces of the items as a function of the +score and of the rest-scores, but does not save them*/ + + {p 4 8 2}{cmd:. traces itemA*} /*displays the graphical +representations of the traces of the items as a function of the score, by +default*/ + + {p 4 8 2}{cmd:. traces itemA*} ,only(itemA2) thresholds(2 3 5)/*displays the graphical +representations of the traces of the item A2 as a function of the score. Individuals are grouped: a first group of individuals with scores from 0 to 2, a second group with a score of 3, a third group with a score between 4 and 5 and a last group with a score superior to 5*/ + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end} +{p 4 8 2}Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences{p_end} +{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end} +{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end} +{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end} +{p 4 8 2}Email: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 4 8 2}Website {browse "http://www.anaqol.org":AnaQol} + +{title:Also see} + +{p 4 13 2}Online: help for {help graph}, {help loevH} and {help gengroup} if installed.{p_end} diff --git a/Modules/ado/personal/t/traces3.ado b/Modules/ado/personal/t/traces3.ado new file mode 100644 index 0000000..ffd63a9 --- /dev/null +++ b/Modules/ado/personal/t/traces3.ado @@ -0,0 +1,232 @@ +************************************************************************************************************ +* Traces: Traces of items +* version 3: July 9, 2003 +* +* Historic: +* Version 1 (2003-06-29): Jean-Benoit Hardouin +* Version 2 (2003-07-04): Jean-Benoit Hardouin +* +* Jean-benoit Hardouin, Regional Health Observatory of Orléans - France +* jean-benoit.hardouin@neuf.fr +* +* News about this program : http://anaqol.free.fr +* FreeIRT Project : http://freeirt.free.fr +* +* Copyright 2003 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define traces +version 8.0 +syntax varlist(numeric min=2) [, score test restscore logistic ci cumulative repfiles(string) scorefiles(string) restscorefiles(string) logisticfile(string) nodraw nodrawcomb replace] + +local nbitems : word count `varlist' +tokenize `varlist' + +tempvar varscore +gen `varscore'=0 +label variable `varscore' "Total score" +local scoremax=0 +local flag=0 + +if "`score'"==""&"`restscore'"==""&&"`logistic'"=="" { +local score="score" +} + +forvalues i=1/`nbitems' { + qui replace `varscore'=`varscore'+``i'' + qui su ``i'' + local modamax`i'=r(max) + if r(min)!=0 { + local flag=1 + } + local scoremax=`scoremax'+`modamax`i'' + if `modamax`i''!=1 { + local flagbin=0 + } +} + +if `flag'==1 { +di as error "The lower modalities of the item must be 0" +exit +} + +qui su `varscore' +local maxscore=r(max) + +forvalues i=0/`maxscore' { + qui count if `varscore'==`i' + local nscore`i'=r(N) +} + +if "`flagbin'"!=""&"`logistic'"!="" { + di as error "The logistic option is impossible with polytomic items" + exit +} + +global score +global restscore +global logistic + +forvalues i=1/`nbitems' { + if "`score'"!="" { + local y`i' + forvalues k=1/`modamax`i'' { + tempvar propscore`i'`k' tmp + if "`cumulative'"!="" { + gen `tmp'=``i''>=`k' + bysort `varscore' : egen `propscore`i'`k''=mean(`tmp') + label variable `propscore`i'`k'' "Item ``i''>=`k'" + } + else { + gen `tmp'=``i''==`k' + bysort `varscore' : egen `propscore`i'`k''=mean(`tmp') + label variable `propscore`i'`k'' "Item ``i''=`k'" + } + local y`i'="`y`i'' `propscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icscoreminus icscoreplus + gen `icscoreminus'=`propscore`i'1'-1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore`i'') + gen `icscoreplus'=`propscore`i'1'+1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore`i'') + label variable `icscoreminus' "Lower 95% confidence interval" + label variable `icscoreplus' "Upper 95% confidence interval" + local y`i'="`icscoreminus' `icscoreplus' `propscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `propscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + } + qui graph twoway (line `y`i'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , note("`note'") ylabel(0(.25)1) xlabel(0(1)`scoremax') name(score`i',replace) title("Trace of the item ``i'' in fonction of the score") ytitle("Rate of positive response") `draw' + global score "$score score`i'" + if "`scorefiles'"!="" { + graph save score`i' `repfiles'\\`scorefiles'``i'' ,`replace' + } + } + if "`restscore'"!="" { + local y`i' + tempvar restscore`i' + gen `restscore`i''=`varscore'-``i'' + label variable `restscore`i'' "Rest score with respect to the item ``i''" + forvalues k=1/`modamax`i'' { + tempvar rtmp proprestscore`i'`k' + if "`cumulative'"!="" { + gen `rtmp'=``i''>=`k' + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''>=`k'" + } + else { + gen `rtmp'=``i''==`k' + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''=`k'" + } + local y`i'="`y`i'' `proprestscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icrestscoreminus icrestscoreplus + qui su `restscore`i'' + local maxrestscore=r(max) + forvalues l=1/`maxrestscore' { + qui count if `restscore`i''==`l' + local nrestscore`i'=r(N) + } + gen `icrestscoreminus'=`proprestscore`i'1'-1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + gen `icrestscoreplus'=`proprestscore`i'1'+1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + label variable `icrestscoreminus' "Lower 95% confidence interval" + label variable `icrestscoreplus' "Upper 95% confidence interval" + local y`i'="`icrestscoreminus' `icrestscoreplus' `proprestscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `proprestscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } +} + local restscoremax=`scoremax'-`modamax`i'' + qui graph twoway (line `y`i'' `restscore`i'', clpattern(`style') clcolor(`color') clwidth(`width')), note("`note'") ylabel(0(0.25)1) xlabel(0(1)`restscoremax') name(restscore`i',replace) title("Trace of the item ``i'' in fonction of the restscore") ytitle("Rate of positive response") `draw' + global restscore "$restscore restscore`i'" + if "`restscorefiles'"!="" { + graph save restscore`i' `repfiles'\\`restscorefiles'``i'' ,`replace' + } + } + if "logistic"!="" { + qui logistic ``i'' `varscore' + tempname coef + matrix `coef'=e(b) + local pente`i'=`coef'[1,1] + local intercept`i'=`coef'[1,2] + tempvar logit`i' + gen `logit`i''=exp(`intercept`i''+`pente`i''*`varscore')/(1+exp(`intercept`i''+`pente`i''*`varscore')) + label variable `logit`i'' "Item ``i''" + sort `varscore' + global logistic "$logistic `logit`i''" + } +} + +if "`drawcomb'"!="" { +local drawcomb="nodraw" +} + +if "`score'"!="" { +graph combine $score , title("Trace of the items in function of the score") name(score,replace) `drawcomb' +if "`scorefiles'"!="" { + graph save score `repfiles'\\`scorefiles' ,`replace' +} +} + +if "`restscore'"!="" { +graph combine $restscore , title("Trace of the items in function of the restscores") name(restscore,replace) `drawcomb' +if "`restscorefiles'"!="" { + graph save restscore `repfiles'\\`restscorefiles' ,`replace' +} +} + +if "`logistic'"!="" { +graph twoway (line $logistic `varscore'), ylabel(0(0.25)1) xlabel(0(1)`nbitems') title("Logistic traces") ytitle("") name(logistic,replace) `drawcomb' +if "`logisticfile'"!="" { + graph save logistic `repfiles'\\`logisticfile' ,`replace' +} +} + + +end + + diff --git a/Modules/ado/personal/t/traces32.ado b/Modules/ado/personal/t/traces32.ado new file mode 100644 index 0000000..8495b13 --- /dev/null +++ b/Modules/ado/personal/t/traces32.ado @@ -0,0 +1,309 @@ +*! Version 3.2 27May2007 +************************************************************************************************************ +* Traces: Traces of items +* Version 3.2: May 27, 2007 (onlyone option) +* +* Historic: +* Version 1 (2003-06-29): Jean-Benoit Hardouin +* Version 2 (2003-07-04): Jean-Benoit Hardouin +* version 3 (2003-07-09): Jean-Benoit Hardouin +* Version 3.1 (2005-06-07): Jean-Benoit Hardouin /*small modifications*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2003, 2005, 2007 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define traces +version 8.0 +syntax varlist(numeric min=2) [, Score Test Restscore Logistic CI CUMulative REPFiles(string) SCOREFiles(string) RESTSCOREFiles(string) LOGISTICFile(string) noDraw noDRAWComb REPlace ONLYone(string) THResholds(string)] + +local nbitems : word count `varlist' +tokenize `varlist' + +if "`onlyone'"!=""&"`drawcomb'"!="" { + local drawcomb +} + +tempvar varscore +qui gen `varscore'=0 +label variable `varscore' "Total score" +local scoremax=0 +local flag=0 + +if "`score'"==""&"`restscore'"==""&&"`logistic'"=="" { + local score="score" +} + +forvalues i=1/`nbitems' { + qui replace `varscore'=`varscore'+``i'' + qui su ``i'' + local modamax`i'=r(max) + if r(min)!=0 { + local flag=1 + } + local scoremax=`scoremax'+`modamax`i'' + if `modamax`i''!=1 { + local flagbin=0 + } +} + + +if `flag'==1 { + di as error "The lower modality of the item must be 0" + exit +} +if "`flagbin'"!=""&"`logistic'"!="" { + di as error "The logistic option is not possible with polytomous items" + exit +} + +qui su `varscore' +local maxscore=r(max) + +forvalues i=0/`maxscore' { + qui count if `varscore'==`i' + local nscore`i'=r(N) +} + + +global score +global restscore +global logistic + +if "`score'"!="" { + if "`thresholds'"!="" { + * set trace on + local nbth:word count `thresholds' + forvalues t=1/`nbth' { + local th`t':word `t' of `thresholds' + } + tempname label + local recode 0/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1' + qui label define `label' 1 "0/`th1'",add + qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add + forvalues j=2/`nbth' { + local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j' + qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add + } + tempname varscore2 + qui gen `varscore2'=`varscore' + qui recode `varscore' `recode' + qui label values `varscore' `label' + local nbgroups=`nbth'+1 + local minimum=1 + } + else { + local nbgroups=`maxscore' + local minimum=0 + } + + forvalues i=1/`nbitems' { + local y`i' + forvalues k=1/`modamax`i'' { + tempvar propscore`i'`k' tmp + if "`cumulative'"!="" { + qui gen `tmp'=``i''>=`k'&``i''!=. + bysort `varscore' : egen `propscore`i'`k''=mean(`tmp') + label variable `propscore`i'`k'' "Item ``i''>=`k'" + } + else { + qui gen `tmp'=``i''==`k'&``i''!=. + bysort `varscore' : egen `propscore`i'`k''=mean(`tmp') + label variable `propscore`i'`k'' "Item ``i''=`k'" + } + local y`i'="`y`i'' `propscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icscoreminus icscoreplus + forvalues l=1/`maxscore' { + qui count if `varscore'==`l' + local nscore`l'=r(N) + } + qui gen `icscoreminus'=`propscore`i'1'-1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1') + qui gen `icscoreplus'=`propscore`i'1'+1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1') + label variable `icscoreminus' "Lower 95% confidence interval" + label variable `icscoreplus' "Upper 95% confidence interval" + local y`i'="`icscoreminus' `icscoreplus' `propscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `propscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + } + if "``i''"=="`onlyone'"|"`onlyone'"=="" { + qui graph twoway (line `y`i'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , note("`note'") ylabel(0(.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(score`i',replace) title("Trace of the item ``i'' as a function of the score") ytitle("Rate of positive response") `draw' + } + global score "$score score`i'" + if "`scorefiles'"!="" { + graph save score`i' `repfiles'\\`scorefiles'``i'' ,`replace' + } + } + if "`thresholds'"!="" { + qui replace `varscore'=`varscore2' + } +} +if "`restscore'"!="" { + forvalues i=1/`nbitems' { + local y`i' + tempvar restscore`i' + qui gen `restscore`i''=`varscore'-``i'' + label variable `restscore`i'' "Rest score with respect to the item ``i''" + if "`thresholds'"!="" { + * set trace on + local nbth:word count `thresholds' + forvalues t=1/`nbth' { + local th`t':word `t' of `thresholds' + } + tempname label + local recode 0/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1' + qui label define `label' 1 "0/`th1'",add + qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add + forvalues j=2/`nbth' { + local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j' + qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add + } + + *di "recode `restscore`i'' `recode'" + qui recode `restscore`i'' `recode' + qui label values `restscore`i'' `label' + local nbgroups=`nbth'+1 + local minimum=1 + } + else { + local nbgroups=`maxscore' + local minimum=0 + } + + forvalues k=1/`modamax`i'' { + tempvar rtmp proprestscore`i'`k' + if "`cumulative'"!="" { + qui gen `rtmp'=``i''>=`k'&``i''!=. + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''>=`k'" + } + else { + qui gen `rtmp'=``i''==`k'&``i''!=. + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''=`k'" + } + local y`i'="`y`i'' `proprestscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icrestscoreminus icrestscoreplus + qui su `restscore`i'' + local maxrestscore=r(max) + forvalues l=1/`maxrestscore' { + qui count if `restscore`i''==`l' + local nrestscore`i'=r(N) + } + qui gen `icrestscoreminus'=`proprestscore`i'1'-1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + qui gen `icrestscoreplus'=`proprestscore`i'1'+1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + label variable `icrestscoreminus' "Lower 95% confidence interval" + label variable `icrestscoreplus' "Upper 95% confidence interval" + local y`i'="`icrestscoreminus' `icrestscoreplus' `proprestscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `proprestscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + } + local restscoremax=`scoremax'-`modamax`i'' + if "``i''"=="`onlyone'"|"`onlyone'"=="" { + *tab `proprestscore`i'1' `restscore`i'' + qui graph twoway (line `y`i'' `restscore`i'', clpattern(`style') clcolor(`color') clwidth(`width')), note("`note'") ylabel(0(0.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(restscore`i',replace) title("Trace of the item ``i'' as a function of the restscore") ytitle("Rate of positive response") `draw' + } + global restscore "$restscore restscore`i'" + if "`restscorefiles'"!="" { + graph save restscore`i' `repfiles'\\`restscorefiles'``i'' ,`replace' + } + } +} +if "logistic"!="" { + forvalues i=1/`nbitems' { + qui logistic ``i'' `varscore' + tempname coef + matrix `coef'=e(b) + local pente`i'=`coef'[1,1] + local intercept`i'=`coef'[1,2] + tempvar logit`i' + qui gen `logit`i''=exp(`intercept`i''+`pente`i''*`varscore')/(1+exp(`intercept`i''+`pente`i''*`varscore')) + label variable `logit`i'' "Item ``i''" + sort `varscore' + global logistic "$logistic `logit`i''" + } +} +if "`drawcomb'"!="" { + local drawcomb="nodraw" +} + +if "`score'"!=""&"`onlyone'"=="" { + graph combine $score , title("Trace of the items as a function of the score") name(score,replace) `drawcomb' + if "`scorefiles'"!="" { + graph save score `repfiles'\\`scorefiles' ,`replace' + } +} + +if "`restscore'"!=""&"`onlyone'"=="" { + graph combine $restscore , title("Trace of the items as a function of the restscores") name(restscore,replace) `drawcomb' + if "`restscorefiles'"!="" { + graph save restscore `repfiles'\\`restscorefiles' ,`replace' + } +} +if "`logistic'"!="" { + graph twoway (line $logistic `varscore'), ylabel(0(0.25)1) xlabel(0(1)`nbitems') title("Logistic traces") ytitle("") name(logistic,replace) `drawcomb' + if "`logisticfile'"!="" { + graph save logistic `repfiles'\\`logisticfile' ,`replace' + } +} + + +end + + diff --git a/Modules/ado/personal/t/traces33.ado b/Modules/ado/personal/t/traces33.ado new file mode 100644 index 0000000..be4f550 --- /dev/null +++ b/Modules/ado/personal/t/traces33.ado @@ -0,0 +1,310 @@ +*! Version 3.3 16October2012 +************************************************************************************************************ +* Traces: Traces of items +* Version 3.3: October 16, 2012 /*minor modifications*/ +* +* Historic: +* Version 1 (2003-06-29): Jean-Benoit Hardouin +* Version 2 (2003-07-04): Jean-Benoit Hardouin +* version 3 (2003-07-09): Jean-Benoit Hardouin +* Version 3.1 (2005-06-07): Jean-Benoit Hardouin /*small modifications*/ +* Version 3.2: May 27, 2007 /*onlyone option*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2003, 2005, 2007, 2012 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define traces +version 8.0 +syntax varlist(numeric min=2) [, Score Test Restscore Logistic CI CUMulative REPFiles(string) SCOREFiles(string) RESTSCOREFiles(string) LOGISTICFile(string) noDraw noDRAWComb REPlace ONLYone(string) THResholds(string) Black] + +local nbitems : word count `varlist' +tokenize `varlist' + +if "`onlyone'"!=""&"`drawcomb'"!="" { + local drawcomb +} + +tempvar varscore +qui gen `varscore'=0 +label variable `varscore' "Total score" +local scoremax=0 +local flag=0 + +if "`score'"==""&"`restscore'"==""&&"`logistic'"=="" { + local score="score" +} + +forvalues i=1/`nbitems' { + qui replace `varscore'=`varscore'+``i'' + qui su ``i'' + local modamax`i'=r(max) + if r(min)!=0 { + local flag=1 + } + local scoremax=`scoremax'+`modamax`i'' + if `modamax`i''!=1 { + local flagbin=0 + } +} + + +if `flag'==1 { + di as error "The lower modality of the item must be 0" + exit +} +if "`flagbin'"!=""&"`logistic'"!="" { + di as error "The logistic option is not possible with polytomous items" + exit +} + +qui su `varscore' +local maxscore=r(max) + +forvalues i=0/`maxscore' { + qui count if `varscore'==`i' + local nscore`i'=r(N) +} + + +global score +global restscore +global logistic + +if "`score'"!="" { + if "`thresholds'"!="" { + * set trace on + local nbth:word count `thresholds' + forvalues t=1/`nbth' { + local th`t':word `t' of `thresholds' + } + tempname label + local recode 0/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1' + qui label define `label' 1 "0/`th1'",add + qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add + forvalues j=2/`nbth' { + local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j' + qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add + } + tempname varscore2 + qui gen `varscore2'=`varscore' + qui recode `varscore' `recode' + qui label values `varscore' `label' + local nbgroups=`nbth'+1 + local minimum=1 + } + else { + local nbgroups=`maxscore' + local minimum=0 + } + + forvalues i=1/`nbitems' { + local y`i' + forvalues k=1/`modamax`i'' { + tempvar propscore`i'`k' tmp + if "`cumulative'"!="" { + qui gen `tmp'=``i''>=`k'&``i''!=. + bysort `varscore' : egen `propscore`i'`k''=mean(`tmp') + label variable `propscore`i'`k'' "Item ``i''>=`k'" + } + else { + qui gen `tmp'=``i''==`k'&``i''!=. + bysort `varscore' : egen `propscore`i'`k''=mean(`tmp') + label variable `propscore`i'`k'' "Item ``i''=`k'" + } + local y`i'="`y`i'' `propscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icscoreminus icscoreplus + forvalues l=1/`maxscore' { + qui count if `varscore'==`l' + local nscore`l'=r(N) + } + qui gen `icscoreminus'=`propscore`i'1'-1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1') + qui gen `icscoreplus'=`propscore`i'1'+1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1') + label variable `icscoreminus' "Lower 95% confidence interval" + label variable `icscoreplus' "Upper 95% confidence interval" + local y`i'="`icscoreminus' `icscoreplus' `propscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `propscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + } + if "``i''"=="`onlyone'"|"`onlyone'"=="" { + qui graph twoway (line `y`i'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , note("`note'") ylabel(0(.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(score`i',replace) title("Trace of the item ``i'' as a function of the score") ytitle("Rate of positive response") `draw' areastyle(none) + } + global score "$score score`i'" + if "`scorefiles'"!="" { + graph save score`i' `repfiles'\\`scorefiles'``i'' ,`replace' + } + } + if "`thresholds'"!="" { + qui replace `varscore'=`varscore2' + } +} +if "`restscore'"!="" { + forvalues i=1/`nbitems' { + local y`i' + tempvar restscore`i' + qui gen `restscore`i''=`varscore'-``i'' + label variable `restscore`i'' "Rest score with respect to the item ``i''" + if "`thresholds'"!="" { + * set trace on + local nbth:word count `thresholds' + forvalues t=1/`nbth' { + local th`t':word `t' of `thresholds' + } + tempname label + local recode 0/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1' + qui label define `label' 1 "0/`th1'",add + qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add + forvalues j=2/`nbth' { + local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j' + qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add + } + + *di "recode `restscore`i'' `recode'" + qui recode `restscore`i'' `recode' + qui label values `restscore`i'' `label' + local nbgroups=`nbth'+1 + local minimum=1 + } + else { + local nbgroups=`maxscore' + local minimum=0 + } + + forvalues k=1/`modamax`i'' { + tempvar rtmp proprestscore`i'`k' + if "`cumulative'"!="" { + qui gen `rtmp'=``i''>=`k'&``i''!=. + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''>=`k'" + } + else { + qui gen `rtmp'=``i''==`k'&``i''!=. + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''=`k'" + } + local y`i'="`y`i'' `proprestscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icrestscoreminus icrestscoreplus + qui su `restscore`i'' + local maxrestscore=r(max) + forvalues l=1/`maxrestscore' { + qui count if `restscore`i''==`l' + local nrestscore`i'=r(N) + } + qui gen `icrestscoreminus'=`proprestscore`i'1'-1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + qui gen `icrestscoreplus'=`proprestscore`i'1'+1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + label variable `icrestscoreminus' "Lower 95% confidence interval" + label variable `icrestscoreplus' "Upper 95% confidence interval" + local y`i'="`icrestscoreminus' `icrestscoreplus' `proprestscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `proprestscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + } + local restscoremax=`scoremax'-`modamax`i'' + if "``i''"=="`onlyone'"|"`onlyone'"=="" { + *tab `proprestscore`i'1' `restscore`i'' + qui graph twoway (line `y`i'' `restscore`i'', clpattern(`style') clcolor(`color') clwidth(`width')), note("`note'") ylabel(0(0.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(restscore`i',replace) title("Trace of the item ``i'' as a function of the restscore") ytitle("Rate of positive response") `draw' + } + global restscore "$restscore restscore`i'" + if "`restscorefiles'"!="" { + graph save restscore`i' `repfiles'\\`restscorefiles'``i'' ,`replace' + } + } +} +if "logistic"!="" { + forvalues i=1/`nbitems' { + qui logistic ``i'' `varscore' + tempname coef + matrix `coef'=e(b) + local pente`i'=`coef'[1,1] + local intercept`i'=`coef'[1,2] + tempvar logit`i' + qui gen `logit`i''=exp(`intercept`i''+`pente`i''*`varscore')/(1+exp(`intercept`i''+`pente`i''*`varscore')) + label variable `logit`i'' "Item ``i''" + sort `varscore' + global logistic "$logistic `logit`i''" + } +} +if "`drawcomb'"!="" { + local drawcomb="nodraw" +} + +if "`score'"!=""&"`onlyone'"=="" { + graph combine $score , title("Trace of the items as a function of the score") name(score,replace) `drawcomb' + if "`scorefiles'"!="" { + graph save score `repfiles'\\`scorefiles' ,`replace' + } +} + +if "`restscore'"!=""&"`onlyone'"=="" { + graph combine $restscore , title("Trace of the items as a function of the restscores") name(restscore,replace) `drawcomb' + if "`restscorefiles'"!="" { + graph save restscore `repfiles'\\`restscorefiles' ,`replace' + } +} +if "`logistic'"!="" { + graph twoway (line $logistic `varscore'), ylabel(0(0.25)1) xlabel(0(1)`nbitems') title("Logistic traces") ytitle("") name(logistic,replace) `drawcomb' + if "`logisticfile'"!="" { + graph save logistic `repfiles'\\`logisticfile' ,`replace' + } +} + + +end + + diff --git a/Modules/ado/personal/t/tri.ado b/Modules/ado/personal/t/tri.ado new file mode 100644 index 0000000..f744081 --- /dev/null +++ b/Modules/ado/personal/t/tri.ado @@ -0,0 +1,146 @@ +program define tri +syntax varlist [fweight iweight] [,global test(int 2) all] + +preserve +local nbvar:word count `varlist' +tokenize `varlist' +/*forvalues i=1/`nbvar' { + qui su ``i'' [`weight'`exp'] + qui replace ``i''=(``i''-r(mean))/r(sd) +} */ + + +/*METHOD GLOBAL */ + + +/* COVARIANCE OR CORRELATION MATRIX*/ + +if "`global'"!="" { + tempname Cov W + qui matrix accum `Cov'=`varlist' [`weight'`exp'],nocons dev + qui matrix `Cov'=`Cov'/(`nbind'-1) + matrix `W'=J(2,`nbvar',0) + + local newlist + tempvar centroid + genscore `varlist',mean score(`centroid') + + forvalues i=1/`nbvar' { + qui corr ``i'' `centroid' [`weight'`exp'] + matrix `W'[1,`i']=`r(rho)' + } + + forvalues c=1/`nbvar'{ + local corrmin=2 + local var=0 + forvalues i=1/`nbvar' { + if `W'[1,`i']<`corrmin'&`W'[2,`i']==0 { + local corrmin=`W'[1,`i'] + local var=`i' + } + } + matrix `W'[2,`var']=`c' + } + matrix list `W' + forvalues c=1/`nbvar' { + forvalues i=1/`nbvar' { + if `W'[2,`i']==`c' { + local newlist `newlist' ``i'' + } + } + } + local varlist "`newlist'" + tokenize `varlist' +} +if "`all'"=="" { + local time=1 +} +else { + local time=`nbvar' +} + +local maxc=-99 +local part +forvalues t=1/`time' { + tempname W + matrix `W'=J(1,`nbvar',0) + matrix `W'[1,`t']=1 + forvalues iter=1/`nbvar' { + local dejaselect + forvalues i=1/`nbvar' { + if `W'[1,`i']!=0 { + local dejaselect `dejaselect' ``i'' + } + } + tempvar centroid + qui genscore `dejaselect',score(`centroid') standardized + local maxr=-2 + local maxi=0 + forvalues i=1/`nbvar' { + if `W'[1,`i']==0 { + qui corr `centroid' ``i'' + local r=r(rho) + if `r'>`maxr' { + local maxr=`r' + local maxi=`i' + } + } + } + if `maxi'!=0 { + matrix `W'[1,`maxi']=`iter'+1 + } + } + local list + forvalues class=1/`nbvar' { + forvalues i=1/`nbvar' { + if `W'[1,`i']==`class' { + local list `list' ``i'' + } + } + } + di "`list'" + forvalues i=0/`nbvar' { + local j=`nbvar'-`i' + if `test'>2 { + local jb `j' + } + else { + local jb 0 + } + forvalues k=0/`jb' { + local l=`nbvar'-`i'-`k' + if `test'>3 { + local lb=`l' + } + else { + local lb=0 + } + forvalues m=0/`lb' { + local n=`nbvar'-`i'-`k'-`m' + qui di "compart `list',part(`i' `k' `m' `n')" + di "`i' `k' `m' `n'" + if `i'>=0&`k'>=0&`m'>=0&`n'>=0 { + di " compart `list',part(`i' `k' `m' `n')" + qui compart2 `list',part(`i' `k' `m' `n') + local c=r(compart) + di "`c'" + if `c'>`maxc' { + local maxc=`c' + local part=r(part) + local savlist `list' + *di "Best : `c'" + } + } + } + } + } +} + di "The best partition in two groups is `part'" + di "for `savlist'" + di "COMPART=`maxc'" + + + + +restore +end diff --git a/Modules/ado/personal/t/trouve.ado b/Modules/ado/personal/t/trouve.ado new file mode 100644 index 0000000..10f4190 --- /dev/null +++ b/Modules/ado/personal/t/trouve.ado @@ -0,0 +1,110 @@ +************************************************************************************************************ +* Trouve : trouve le nom d'un commune ou d'un canton de la région centre en indiquant son code +* +* Version 1.1: 16 aout 2004 +* +* Jean-benoit Hardouin, Observatoire Régional de la Santé du Centre - Orléans - France +* jean-benoit.hardouin@neuf.fr +* +* Copyright 2004 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ +program define trouve,rclass +version 7.0 +syntax anything +local nbarg:word count `anything' +capture su * +if _rc==0 { + tempfile savetrouve + qui save `savetrouve',replace +} +preserve + +numlist "`anything'" +local list `r(numlist)' + +foreach i of numlist `list' { + if (`i'>1800&`i'<1900)|(`i'>2800&`i'<2900)|(`i'>3600&`i'<3800)|(`i'>4100&`i'<4200)|(`i'>4500&`i'<4600) { + qui use "C:\ado\PERSONAL\files\cantons" ,clear + qui su id if codepct==`i' + local tmp=r(min) + local tmp=nompct[`tmp'] + if "`tmp'"!="" { + di in green "`i' (canton):" in yellow " `tmp'" + return local trouve`i' "Canton : `tmp'" + } + else { + di in red "Il n'y a pas de canton avec ce numero (`i') dans la region Centre" + } + } + else if `i'>2400&`i'<2500 { + local erreur=0 + if `i'==2411 {local name Bourges} + else if `i'==2412 {local name Vierzon} + else if `i'==2413 {local name Saint-Amand-Montrond} + else if `i'==2414 {local name Aubigny-sur-Nère} + else if `i'==2421 {local name Chartres} + else if `i'==2422 {local name Dreux} + else if `i'==2423 {local name Chateaudun} + else if `i'==2424 {local name Nogent le Rotrou} + else if `i'==2431 {local name Chateauroux} + else if `i'==2432 {local name Le Blanc} + else if `i'==2433 {local name Issoudun} + else if `i'==2434 {local name La Chatre} + else if `i'==2441 {local name Tours} + else if `i'==2442 {local name Amboise} + else if `i'==2443 {local name Loches} + else if `i'==2444 {local name Chinon} + else if `i'==2451 {local name Blois} + else if `i'==2452 {local name Vendome} + else if `i'==2453 {local name Romoranthin-Lanthenay} + else if `i'==2461 {local name Orleans} + else if `i'==2462 {local name Montargis} + else if `i'==2463 {local name Pithiviers} + else if `i'==2464 {local name Gien} + else { + di in red "Il n'y a pas de zone d'emploi avec ce numero (`i') dans la region Centre" + local erreur=1 + } + if `erreur'==0 { + di in green "`i' (zone d'emploi):" in yellow " `name'" + return local trouve`i' "Zone d'emploi : `name'" + } + } + else if `i'>10000&`i'<100000 { + qui use "C:\ado\PERSONAL\files\communes" ,clear + qui su id if codecom==`i' + local tmp=r(min) + local tmp=nomcom[`tmp'] + if "`tmp'"!="" { + di in green "`i' (commune):" in yellow " `tmp'" + return local trouve`i' "Commune : `tmp'" + } + else { + di in red "Il n'y a pas de commune avec ce numero (`i') dans la region Centre" + } + } + else { + di in red "Ce code n'est pas utilisable" + } +} +restore,not +qui drop _all +if "`savetrouve'"!="" { + qui use `savetrouve' +} +end diff --git a/Modules/ado/personal/v/valid.ado b/Modules/ado/personal/v/valid.ado new file mode 100644 index 0000000..10f2c0a --- /dev/null +++ b/Modules/ado/personal/v/valid.ado @@ -0,0 +1,365 @@ +capture program drop valid +program valid +syntax varlist, PARTition(numlist integer >0) [SCOrename(string) IMPute NORound CALCmethod(string) DESCitems GRAPHs cfa CFAMethod(string) CFAStand CONVdiv TCONVdiv(real 0.4) CONVDIVBoxplots Alpha(real 0.7) Delta(real 0.9) h(real 0.3) HJmin(real 0.3) REPet(varlist) KAPpa ICKAPpa(integer 0) kgv(varlist) KGVBoxplots KGVGroupboxplots conc(varlist) tconc(real 0.4)] +preserve + +qui set autotabgraphs on + +qui set more off + +local C = 0 +foreach z in `partition' { + local C = `C' + `z' +} + +local nbvars : word count `varlist' +/* +if `C' > `nbvars' { + di in red "The sum of the numbers in the partition option is greater than the number of variables in the dataset" + exit 119 +} +*/ +local nbvars : word count `varlist' +if `C' != `nbvars' { + di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist" + exit 119 +} + +local P:word count `partition' + +if "`scorename'" !="" { + local S:word count `scorename' + if `P'!=`S' { + di in red "The number of score names given is different from the number of dimensions in the partition option" + exit 119 + } + foreach sco in `scorename' { + capture confirm variable `sco' + if !_rc { + di in red "`sco' is a variable of the dataset. Choose another name" + exit 119 + } + tokenize `scorename' + local g = 0 + forvalues i = 1/`S' { + if "`sco'" == "``i''" { + local `++g' + } + } + if `g' > 1 { + di in red "2 or more dimensions have the same name" + exit 119 + } + } +} +else { + local name + local nname + + forvalues i = 1/`P' { + local name "Dim`i'" + local nname `nname' `name' + } +local scorename = "`nname'" +} + +/* +if "`ident'" == "" { + tempvar id + qui gen `id' = _n +} +else { + qui tab `ident', nofreq + local u = r(r) + if `u' != _N { + di in red "`ident' has not unique values" + exit 119 + } +} +*/ +/* +if "`repitems'" !="" { + local a : word count `repitems' + if mod(`a',2) != 0 { + di in red "error repitems: odd number" + exit + } + foreach r in `repitems' { + capture confirm variable `r' + if _rc!=0 { + di in red "`r' does not exist" + exit 119 + } + } +} +*/ +/* +local y = 0 +if "`repscores'" !="" { + local a : word count `repscores' + if mod(`a',2) != 0 { + di in red "error repscores : odd number" + exit 119 + } + foreach r in `repscores' { + local x = 0 + local y = 0 + capture confirm variable `r' + if _rc!=0 local x = 1 + foreach s in `scorename' { + if "`r'" == "`s'" local y = `y'+1 + } + if `x' == 1 & `y' < 1 { + di "`r' " "non défini" + exit 119 + } + } +} +*/ + +if "`kgv'" !="" { + foreach k in `kgv' { + capture confirm variable `k' + if _rc!=0 { + di in red "`k' does not exist" + exit 119 + } + } +} + +if "`conc'" !="" { + foreach c in `conc' { + capture confirm variable `c' + if _rc!=0 { + di in red "`c' does not exist" + exit 119 + } + } +} +/* +if `t2from' > _N { + di in red "Reproductibility : invalid range for observations at time 2 (`t2from' > number of observations)" + exit 119 +} + +if `t2to' > _N { + di in red "Reproductibility : invalid range for observations at time 2 (`t2to' > number of observations)" + exit 119 +} + +if "`t2from'" != "" & "`t2to'" != "" { + if `t2from' > `t2to' { + di in red "Reproductibility : invalid range for observations at time 2" + exit 119 + } +} + +if "`t2from'" == "" local t2from = 1 +if "`t2to'" == "" local t2to = _N +*/ + +local i = 1 +foreach x in `varlist' { + local var`i' = "`x'" + local `++i' +} + +di as result "Items used for calculation of the scores" +di + +local i = 1 +local j = 1 +local y = 1 +foreach p in `partition' { + tokenize `scorename' + di "{bf:``i''} : " _c + + if `j' == 1 local s = `p' + else local s = `s' +`p' + forvalues z = `y'/`s' { + di "{text:`var`z'' }" _c + } + local `i++' + local `j++' + local y = `s'+1 + di +} + +qui destring _all, replace +di +/* +local cpt = 0 +if "`sum'" != "" { + local cpt `cpt' + 1 +} +if "`mean'" != "" { + local cpt `cpt' + 1 +} +if "`stand'" != "" { + local cpt `cpt' + 1 +} +if `cpt'>1 { + di in red "You must choose between mean, sum or stand (the options are exclusive)" + exit 119 +} +*/ +calcscore `varlist', scorename(`scorename') partition(`partition') calcmethod(`calcmethod') + +if "`descitems'" != "" { + di as result "{hline}" + di "Description of items" + di as result "{hline}" + di + descitems `varlist', partition(`partition') + di +} +if "`graphs'" != "" { + _graph `varlist', partition(`partition') scorename(`scorename') calcmethod(`calcmethod') +} + +if "`repet'" != "" { + if "`descitems'" != "" { + di as result "{hline}" + di "Description of items (time 2)" + di as result "{hline}" + di + descitems `repet', partition(`partition') + di + } +} + +if "`impute'" != "" { + *if "`noround'" != "" { + *di "Missing data handling (noround)" + *di + + imp `varlist', partition(`partition') `noround' + if "`descitems'" != "" { + di as result "{hline}" + di "Description of items after missing data handling" + di as result "{hline}" + di + descitems `varlist', partition(`partition') + di + } + if "`graphs'" != "" { + *_graph `varlist', partition(`partition') scorename(`scorename') + } + if "`repet'" != "" { + imp `repet', partition(`partition') `noround' + if "`descitems'" != "" { + di as result "{hline}" + di "Description of items after missing data handling (time 2)" + di as result "{hline}" + di + descitems `repet', partition(`partition') + di + } + } + + + *} + /*else { + di "Missing data handling (round)" + di + imp `varlist', partition(`partition') + di "Description of items after missing data handling" + di + desc_item `varlist', partition(`partition') + if "`graphs'" != "" { + *_graph `varlist', partition(`partition') scorename(`scorename') + } + di "Description of items after missing data handling (time 2)" + di + if "`repet'" != "" { + imp `repet', partition(`partition') + desc_item `repet', partition(`partition') + } + di "{hline}" + }*/ +} + +/* +if "`imp'" == "" & "`noround'" != "" { + *di "noround" + di + imp `varlist', partition(`partition') `noround' + if "`desc_items'" != "" { + di "Description of items after missing data handling" + di + desc_item `varlist', partition(`partition') + + } + if "`graphs'" != "" { + *_graph `varlist', partition(`partition') scorename(`scorename') + } + di "Description of items after missing data handling (time 2)" + di + imp `repet', partition(`partition') `noround' + desc_item `repet', partition(`partition') + di "{hline}" + +} +*/ + +*di "{hline}" + +if "`convdiv'" != "" { + convdiv `varlist', scorename(`scorename') partition(`partition') tconvdiv(`tconvdiv') `convdivboxplots' + *di as result "{hline}" + di +} + +/* +if "`cfa'" != "" { + local cpt = 0 + if "`cfa_ml'" != ""{ + local method = "cfa_ml" + local cpt `cpt' + 1 + } + if "`cfa_mlmv'" != "" { + local method = "cfa_mlmv" + local cpt `cpt' + 1 + } + if "`cfa_adf'" != "" { + local method = "cfa_adf" + local cpt `cpt' + 1 + } + else local method = "cfa_ml" + if `cpt' > 1 { + di in red "You must choose between cfa_ml, cfa_mlmv or cfa_adf (the options are exclusive)" + exit 119 + } + + cfa `varlist', scorename(`scorename') partition(`partition') `method' `cfa_stand' + di as result "{hline}" +} +*/ + +if "`cfa'" != "" { + cfa `varlist', scorename(`scorename') partition(`partition') cfamethod(`cfamethod') `cfastand' + *di as result "{hline}" + di +} + +rel `varlist', scorename(`scorename') partition(`partition') alpha(`alpha') delta(`delta') h(`h') hjmin(`hjmin') +di +*di "{hline}" + +if "`repet'" != "" { + repet `varlist', t2(`repet') partition(`partition') scorename(`scorename') `kappa' ickappa(`ickappa') calcmethod(`calcmethod') + *di "{hline}" + di +} + +if "`kgv'" != "" { + kgv `scorename', categ(`kgv') `kgvboxplots' `kgvgroupboxplots' + *di "{hline}" + di +} + +if "`conc'" != "" { + conc `scorename', comp(`conc') tconc(`tconc') + *di "{hline}" +} +end diff --git a/Modules/ado/personal/v/valid.dlg b/Modules/ado/personal/v/valid.dlg new file mode 100644 index 0000000..48f9654 --- /dev/null +++ b/Modules/ado/personal/v/valid.dlg @@ -0,0 +1,426 @@ +/* + valid.dlg +*/ + +VERSION 12.1 + +POSITION . . 590 280 + +DIALOG main, label("Validation") tabtitle("General") +BEGIN + TEXT tx_var 10 10 250 ., /// + label("Items used for calculating score") + VARLIST vl_var @ +20 280 ., /// + label("Variables") + + TEXT tx_n 10 +28 200 ., /// + label("Number of items") + + EDIT ed_n @ +20 40 ., /// + label("number") /// + numonly + + TEXT tx_score 110 58 180 ., /// + label("Name of the dimension (optional)") + EDIT ed_score 130 +20 100 ., /// + option(scorename) /// + + BUTTON bt_add 260 75 32 22, /// + label("Add") /// + onpush(script az) /// + + GROUPBOX gb_1 5 120 284 140, + + TEXT tx_v 10 +10 100 ., /// + label("Items used") + VARLIST ed_v @ +20 250 ., /// + label("Items used") + + TEXT tx_p @ +20 100 ., /// + label("Partition") + + EDIT ed_p @ +20 150 ., /// + label("Partition") /// + option(partition) /// + tooltip("Defines the number of items in each dimension") + TEXT tx_s @ +20 . ., /// + label("Names of the dimensions (optional)") + EDIT ed_s @ +20 150 ., /// + label("Names of the dimensions") /// + option(scorename) + + + GROUPBOX gb_calc 330 13 245 90, /// + label("Calculation of scores") + + RADIO rb_mean +10 +20 100 ., first label("Mean") /// + default(1) + + + RADIO rb_sum @ +20 100 ., label("Sum") + + + RADIO rb_stand @ +20 140 ., last label("Standardized scores") /// + tooltip("Set score from 0 to 100") + + GROUPBOX gb_opt 330 120 245 140, /// + label("Options") + + CHECKBOX ck_imp +10 +20 -20 ., /// + option(imp) /// + label("Imputing missing data") /// + onclickon(main.ck_nor.enable) /// + onclickoff(main.ck_nor.disable) /// + default(1) + + CHECKBOX ck_nor +145 @ -20 ., /// + option(noround) /// + label("Do not round") /// + tooltip("Do not round imputed values") + + CHECKBOX ck_desc 340 +28 -20 ., /// + option(descitems) /// + label("Description of items") /// + default(0) + + CHECKBOX ck_graphs 340 +28 -20 ., /// + option(graphs) /// + label("Display graphs") /// + default(0) /// + tooltip("Display histogram of items, biplot of dimensions and biplot of items") + + /* + CHECKBOX ck_cfa 340 +28 -20 ., /// + option(cfa) /// + label("Confirmatory factor analysis") /// + default(1) + + + CHECKBOX ck_conv @ +28 +10 ., /// + option(conv_div) /// + label("Convergent/discriminant validity") /// + default(1) + */ + +END + + +DIALOG cfa, tabtitle("Confirmatory factor analysis") +BEGIN + + CHECKBOX ck_cfa 10 10 200 ., label("Display confirmatory factor analysis") /// + option(cfa) /// + onclickon(script cfa_ck_cfa_on) /// + onclickoff(script cfa_ck_cfa_off) + + GROUPBOX gb_cfa 10 +30 220 90 , /// + label("Estimation method:") + + RADIO rb_ml +10 +24 110 ., first label("Maximum likelihood") /// + default(1) + + RADIO rb_mlmv @ +20 200 ., label("Maximum likelihood with missing values") + + RADIO rb_adf @ +20 140 ., last label("Asymptotic distribution free") + + + CHECKBOX ck_stand 14 +34 140 ., label("Standardize coefficients") /// + option(cfastand) + +END + + +DIALOG conv, tabtitle("Convergent/divergent validity") +BEGIN + + CHECKBOX ck_conv_div 10 10 220 ., /// + label("Display convergent/divergent validity") /// + option(convdiv) /// + onclickon(script conv_ck_conv_on) /// + onclickoff(script conv_ck_conv_off) + + TEXT tx_conv1 10 +26 220 ., /// + label("Correlations between item and its own score") + TEXT tx_conv2 @ +17 @ ., /// + label("below this value will be highlighted") + EDIT ed_conv 250 42 35 ., /// + default(0.4) /// + option(tconvdiv) /// + numonly + + CHECKBOX ck_conv 10 +42 170 ., /// + option(convdivboxplots) /// + label("Display boxplots of correlations") /// + default(1) + +END + + +DIALOG rel, tabtitle("Reliability") +BEGIN + + TEXT tx_rel_a 10 10 350 ., /// + label("Cronbach's alpha below this value will be highlighted") + EDIT ed_rel_a 320 @ 35 ., /// + default(0.7) /// + option(alpha) /// + numonly + + TEXT tx_rel_d 10 +30 350 ., /// + label("Ferguson's delta below this value will be highlighted") + EDIT ed_rel_d 320 @ 35 ., /// + default(0.9) /// + option(delta) /// + numonly + + TEXT tx_rel_H 10 +30 380 ., /// + label("Loevinger's H coefficient below this value will be highlighted") + EDIT ed_rel_H 320 @ 35 ., /// + default(0.3) /// + option(h) /// + numonly + + TEXT tx_rel_h 10 +30 380 ., /// + label("Loevinger's Hj coefficient below this value will be highlighted") + EDIT ed_rel_h 320 @ 35 ., /// + default(0.3) /// + option(hjmin) /// + numonly + +END + + + +DIALOG rep, tabtitle("Reproducibility") +BEGIN + + TEXT tx_rep 10 10 250 ., /// + label("Items used for calculating scores (time 2)") + VARLIST vl_rep @ +20 @ ., /// + option(repet) /// + label("Items time 2") + + CHECKBOX ck_kappa @ +35 100 ., /// + label("Kappa statistic") /// + option(kappa) /// + onclickon(script rep_ck_kappa_on) /// + onclickoff(script rep_ck_kappa_off) + + CHECKBOX ck_ickappa @ +25 280 ., /// + label("Confidence interval for kappa") /// + onclickon(script rep_ck_ickappa_on) /// + onclickoff(script rep_ck_ickappa_off) + + TEXT tx_boot @ +25 220 ., /// + label("Number of bootstrap replications to estimate") + + TEXT tx_boot2 @ +15 220 ., /// + label("confidence interval (if items are polytomous):") + + SPINNER sp_ickappa +220 -7 45 ., /// + label("Number of bootstrap replications") min(1) max(1000) /// + default(20) /// + option(ickappa) + + +END + + +DIALOG kgv, tabtitle("Known-groups validity") +BEGIN + TEXT tx_kgv 10 10 250 ., /// + label("Select qualitative variables for known-groups validity") + VARLIST vl_kgv @ +28 250 ., /// + option(kgv) /// + label("kgv") + + CHECKBOX ck_kgv @ +25 150 ., /// + label("Display boxplots") /// + option(kgvboxplots) /// + default(0) /// + onclickon(kgv.ck_kgv_group.enable) /// + onclickoff(kgv.ck_kgv_group.disable) + + CHECKBOX ck_kgv_group @ +25 190 ., /// + label("Group boxplots in one graph") /// + option(kgvgroupboxplots) /// + default(0) + +END + + +DIALOG conc, tabtitle("Concurrent validity") +BEGIN + TEXT tx_conc 10 10 186 ., /// + label("Select scores from other scales") + VARLIST vl_conc @ +28 250 ., /// + option(conc) /// + label("conc") + + TEXT tx_t_conc @ +30 350 ., /// + label("Correlations above this value will be highlighted (absolute value)") + + EDIT ed_t_conc 320 @ 30 ., /// + default(0.4) /// + option(tconc) /// + numonly + +END + + +PROGRAM az +BEGIN + main.ed_score.withvalue main.ed_s.append "@ " + main.vl_var.withvalue main.vl_v.append "@ " + main.ed_n.withvalue main.ed_p.append "@ " + + main.vl_var.setvalue "" + main.ed_n.setvalue "" + main.ed_score.setvalue "" +END + + + + +SCRIPT rep_ck_kappa_on +BEGIN + rep.ck_ickappa.enable +END + +SCRIPT rep_ck_kappa_off +BEGIN + rep.ck_ickappa.disable + rep.sp_ickappa.disable + rep.ck_ickappa.setoff +END + +SCRIPT rep_ck_ickappa_on +BEGIN + rep.sp_ickappa.enable + rep.tx_boot.enable + rep.tx_boot2.enable +END + +SCRIPT rep_ck_ickappa_off +BEGIN + rep.sp_ickappa.disable + rep.sp_ickappa.setdefault 0 + rep.tx_boot.disable + rep.tx_boot2.disable +END + +SCRIPT cfa_ck_cfa_on +BEGIN + cfa.gb_cfa.enable + cfa.rb_ml.enable + cfa.rb_mlmv.enable + cfa.rb_adf.enable + cfa.ck_stand.enable +END + +SCRIPT cfa_ck_cfa_off +BEGIN + cfa.gb_cfa.disable + cfa.rb_ml.disable + cfa.rb_mlmv.disable + cfa.rb_adf.disable + cfa.ck_stand.disable +END + +SCRIPT conv_ck_conv_on +BEGIN + conv.tx_conv1.enable + conv.tx_conv2.enable + conv.ed_conv.enable + conv.ck_conv.enable +END + +SCRIPT conv_ck_conv_off +BEGIN + conv.tx_conv1.disable + conv.tx_conv2.disable + conv.ed_conv.disable + conv.ck_conv.disable +END + +OK ok1, label("OK") +CANCEL can1, label("Cancel") +SUBMIT sub1, label("Submit") +HELP hlp1, view("help valid") +RESET res1 +COPY copy1 + +PROGRAM command +BEGIN + put "valid " + require main.ed_v + put main.ed_v + require main.ed_p + + beginoptions + optionarg main.ed_p + optionarg main.ed_s + option main.ck_imp + option main.ck_nor + option main.ck_desc + option main.ck_graphs + + if main.rb_mean{ + put " calcmethod(" + put "mean" + put ")" + } + + if main.rb_sum{ + put " calcmethod(" + put "sum" + put ")" + } + + if main.rb_stand{ + put " calcmethod(" + put "stand" + put ")" + } + + option cfa.ck_cfa + + if cfa.rb_ml{ + put " cfamethod(" + put "ml" + put ")" + } + + if cfa.rb_mlmv{ + put " cfamethod(" + put "mlmv" + put ")" + } + + if cfa.rb_adf{ + put " cfamethod(" + put "adf" + put ")" + } + + option cfa.ck_stand + option conv.ck_conv_div + optionarg conv.ed_conv + option conv.ck_conv + optionarg rel.ed_rel_a + optionarg rel.ed_rel_d + optionarg rel.ed_rel_H + optionarg rel.ed_rel_h + optionarg rep.vl_rep + option rep.ck_kappa + optionarg rep.sp_ickappa + optionarg kgv.vl_kgv + option kgv.ck_kgv + option kgv.ck_kgv_group + optionarg conc.vl_conc + optionarg conc.ed_t_conc + + endoptions + + +END diff --git a/Modules/ado/personal/v/valid.hlp b/Modules/ado/personal/v/valid.hlp new file mode 100644 index 0000000..4a16d35 --- /dev/null +++ b/Modules/ado/personal/v/valid.hlp @@ -0,0 +1,125 @@ +{smcl} +{* 2013}{...} +{hline} +help for {hi:valid} +{hline} + +{title:Syntax} + +{p 8 14 2}{cmd:valid} {it:varlist}, {bf:partition}({it:numlist}) [{it:options}] + +{p 4 4 2}{it:varlist} contains the variables (items) used to calculate the scores. The first items of {it:varlist} compose the first dimension, the following items define the second dimension, and so on. + +{p 4 4 2}{cmd:partition} permits to define in {it:numlist} the number of items in each dimension. + + +{synoptset 20 tabbed}{...} +{synopthdr} +{synoptline} +{syntab:Options} +{synopt : {opt sco:rename(string)}}define the names of the dimensions{p_end} +{synopt : {opt imp:ute}}impute missing item responses{p_end} +{synopt : {help valid##impute_options:{it:impute_options}}}options for imputation of missing data {p_end} +{synopt : {opt calc:method(method)}}define how scores are calculated{p_end} +{synopt : {opt desc:items}}display a description of items and dimensions{p_end} +{synopt : {opt graph:s}}display graphs for items description{p_end} +{synopt : {opt cfa}}assess structural validity by performing a confirmatory factor analysis{p_end} +{synopt : {help valid##cfa_options:{it:cfa_options}}}options for confirmatory factor analysis{p_end} +{synopt : {opt conv:div}}assess convergent and divergent validity assessment{p_end} +{synopt : {help valid##conv_div_options:{it:conv_div_options}}}options for convergent and divergent validity{p_end} +{synopt : {help valid##reliability_options:{it:reliability_options}}}options for reliability assessment{p_end} +{synopt : {opt rep:et(varlist)}}assess reproducibility of scores and items{p_end} +{synopt : {help valid##repet_options:{it:repet_options}}}options for reproducibility{p_end} +{synopt : {opt kgv(varlist)}}assess known-groups validity by using qualitative variable(s){p_end} +{synopt : {help valid##kgv_options:{it:kgv_options}}}options for known-groups validity assessment{p_end} +{synopt : {opt conc(varlist)}}assess concurrent validity{p_end} +{synopt : {help valid##conc_options:{it:conc_options}}}options for concurrent validity assessment{p_end} + +{p2colreset}{...} + + +{title:Description} + +{phang}{cmd:valid} assesses validity and reliability of a multidimensional scale. Specifically it evaluates +structural validity, convergent and divergent validity, reproducibility, known-groups validity, internal consistency, scalability and sensitivity. + +{marker options}{...} +{title:Options} + +{dlgtab:Options} + +{phang}{opt sco:rename(string)} allows defining the names of the dimensions. If the option is not used then dimensions are named {it:Dim1}, {it:Dim2},... + +{phang}{opt imp:ute} imputes missing items responses with Person Mean Substitution method applied in each dimension. Missing data are imputed only if the number of +missing values in the dimension is less than half the number of items in the dimension. + +{marker impute_options}{...} +{phang}{it:impute_options} allow specifying options for imputation of missing. By default, imputed values are rounded to the nearest whole number. If {opt nor:ound} is precised then imputed values +are not rounded. If {opt impute} is absent then {opt noround} is ignored. + +{phang}{opt calc:method(method)} defines the method used for calculating scores. {it:method} may be either {bf:mean} (default), {bf:sum} or {bf:stand}(set scores from 0 to 100). + +{phang}{opt desc:items} displays a description of items. This option gives missing data rate per item and distribution of item responses. It also gives Cronbach's alpha for each item, which is the alpha statistic +calculated by removing the item from the dimension. Moreover, the option computes Loevinger's Hj coefficients and the number of non significant Hjk. See {help loevh} for details about Loevinger's coefficients. + +{phang}{opt graph:s} displays graphs for items and dimensions description. It provides histograms of scores, a biplot of dimensions and a biplot of items. + +{phang}{opt cfa} performs a confirmatory factor analysis with Stata's {help sem} command. It displays estimations of coefficients and several goodness-of-fit indices. + +{marker cfa_options}{...} +{phang}{it:cfa_options} allow specifying options for confirmatory factor analysis. {opt cfam:ethod}({it:method}) specifies the method of estimation of parameters. {it:method} may be either {bf:ml} (maximum +likelihood), {bf:mlmv} ({bf:ml} with missing values) or {bf:adf} (asymptotic distribution free). The {opt cfas:tand} option displays standardized coefficients. + +{phang}{opt conv:div} assesses convergent and divergent validity. The option displays the matrix of correlations between items and dimensions. + +{marker convdiv_options}{...} +{phang}{it:conv_div_options} allow specifying options for convergent and divergent validity. {opt tconv:div(#)} defines a threshold for highlighting some values. # is a real number between 0 and 1 which is equal to 0.4 by +default. Correlations between items and their own score are printed +in red if it is less than #. Moreover, if an item is less correlated with its own dimension than with another one the correlation is printed +in red. The {opt convdivb:oxplots} option displays boxplots for assessing convergent and divergent validity. The boxes represent the correlations between the items of a given dimension and all dimensions. So the box of correlations between items of a given dimension and its score must be higher than other +boxes. There is as many boxplots (graphs) as dimensions. + +{marker reliability_options}{...} +{phang}{it:reliability_options} allow defining the thresholds for reliability indices. {opt a:lpha(#)} defines a threshold for Cronbach's alpha (see {help alpha}). # is a real number between 0 and 1 which is equal to 0.7 +by default. Cronbach's alpha coefficients less than # are printed in red. {opt d:elta(#)} defines a threshold for Ferguson's delta coefficient (see {help delta}). # is a real number between 0 and 1 which is equal to 0.9 +by default. Ferguson's delta coefficients less than # are printed in red. {opt h(#)} defines a threshold for Loevinger's H coefficient (see {help loevh}). # is a real number between 0 and 1 which is equal to +0.3 by default. Loevinger's H coefficients less than # are printed in red. {opt hj:min(#)} +defines a threshold for Loevinger's Hj coefficients. The displayed value is the minimum Hj coefficient for a item in the dimension. (see {help loevh}). # is a real number between 0 and 1 which is equal to +0.3 by default. If the minimum Loevinger's Hj coefficient is less than # then it is printed in red and the corresponding item is displayed. + +{phang}{opt rep:et(varlist)} assesses reproducibility of scores by precising in {it:varlist} the variables corresponding to responses at time 2. Scores are calculated according to the {opt partition()} option. Intraclass +Correlation Coefficients (ICC) for scores and their 95% confidence interval are computed with Stata's {help icc} command. + +{marker repet_options}{...} +{phang}{it:repet_options} display information about reproducibility of items. The {opt kap:pa} option computes kappa statistic for items with Stata's {help kap} command. The {opt ickap:pa(#)} calculates +confidence intervals for +kappa statistics. # is the number of replications for bootstrap used to estimate confidence intervals if items are polytomous. See {help kapci} for more details about calculation of confidence intervals for kappa's +coefficients. If the {opt kappa} option is absent then {opt ickappa(#)} is ignored. + +{phang}{opt kgv(varlist)} assesses known-groups validity according to the grouping variables precised in {it:varlist}. + +{marker kgv_options}{...} +{phang}{it:kgv_options} allow to display graphs for known-groups validity. The {opt kgvb:oxplots} option draws boxplots of scores split into groups of individuals. The {opt kgvg:roupboxplots} option groups +all boxplots in one graph. If {opt kgvboxplots} is absent then {opt kgvboxplotsgroup} is ignored. + +{phang}{opt conc(varlist)} assesses concurrent validity with variables precised in {it:varlist}. These variables are scores from one or several other scales. + +{marker conc_options}{...} +{phang}{it:conc_options} allow to specify options for concurrent validity. The {opt tc:onc(#)} option defines a threshold for correlations between scores and those of other scales in {it:varlist}. Correlation +coefficients greater than # are displayed in bold. + + +{marker examples}{...} +{title:Examples} + +{phang2}{cmd:. valid item1-item20, part(5 4 6 5)}{p_end} + +{phang2}{cmd:. valid item1-item20, part(5 4 6 5) imp graphs cfa cfastand convdiv convdivboxplots kgv(factor_variable) kgvboxplots conc(scoreA-scoreD)}{p_end} + +{phang2}{cmd:. valid item1-item20, part(5 4 6 5) imp rep(item1bis-item20bis) kappa}{p_end} + + +{marker alsosee}{...} +{title:Also see} + +{p 4 13 2}help for {help alpha}, {help delta}, {help loevh}, {help icc}, {help kapci}.{p_end} diff --git a/Modules/ado/personal/v/validscale.ado b/Modules/ado/personal/v/validscale.ado new file mode 100644 index 0000000..6172ac4 --- /dev/null +++ b/Modules/ado/personal/v/validscale.ado @@ -0,0 +1,2981 @@ +*! Bastien Perrot, Jean-Benoit Hardouin, Emmanuelle Anthoine +************************************************************************************************************* +* Stata program : validscale +* Assess validity and reliability of a multidimensional measurement scale using CTT methods + +* Required modules : +* delta +* loevh +* kapci +* mi_twoway +* detect +* imputeitems +* lstrfun +* svmat2 + +* Version 1.1 (September 3, 2018) /*updated the dialog box for Stata 15, fixed a bug with cfarmsea, cfacfi and cfacovs, fixed a bug with descitems when the first observation contained missing data*/ +* Version 1.2 August 13, 2019 /* filessave and dirsave options */ +* Version 1.2.1 August 28, 2019 /* cfa is now a wrapper for sem command; that means that most options of sem_estimation_options should work for cfa */ +* Version 1.2.2 February 17, 2020 /* check if svmat2 is installed */ + + + +************************************************************************************************************* + +program define validscale, rclass +version 12.0 +syntax varlist [if], PARTition(numlist integer >0) [HTML(string) CATegories(numlist) SCOREName(string) scores(varlist) IMPute(string) NORound COMPScore(string) DESCitems GRAPHs cfa CFAMethod(string) cfasb CFAStand CFACov(string) CFARmsea(real -999) CFACFi(real -999) CFAOR CFANOCOVDim CONVdiv TCONVdiv(real 0.4) CONVDIVBoxplots Alpha(real 0.7) Delta(real 0.9) h(real 0.3) HJmin(real 0.3) REPet(varlist) scores2(varlist) KAPpa ICKAPpa(integer 0) kgv(varlist) KGVBoxplots KGVGroupboxplots conc(varlist) tconc(real 0.4) DIRsave(string) FILESsave *] +preserve + + +foreach c in delta loevh mi_twoway detect imputeitems lstrfun{ + capture which "`c'" + if _rc qui ssc install "`c'" +} + +capture which kapci +if _rc qui net install st0076, from(http://www.stata-journal.com/software/sj4-4/) + +capture which svmat2 +if _rc qui net install dm79, from(http://www.stata.com/stb/stb56) + + +if "`if'"!="" { + qui keep `if' +} + +global html +global dirsave +global filessave + +if "`filessave'" != "" { + global filessave = "`filessave'" +} + +if "`dirsave'" != "" { + global dirsave = "`dirsave'" +} +else { + global dirsave "`c(pwd)'" +} + +if "`html'" != "" { + global html = "`html'" + set scheme sj + local htmlregion "graphregion(fcolor(white) ifcolor(white))" + local xsize=6 + local ysize=4 + di in gr "" + di "
" + di "
"
+}   
+
+if "`categories'" == "" {
+	foreach v in `varlist' {
+		tempvar min max
+		egen `min' = min(`v')
+		egen `max' = max(`v')
+		local mi = `min' 
+		local ma = `max'
+		local m `mi' `ma'
+		local categories `categories' `m'
+	}
+}
+
+global categories = "`categories'"
+global compscore = "`compscore'"
+if "$compscore" == "" global compscore = "mean"
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+
+local nbvars : word count `varlist' 
+
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit 119
+}
+
+
+if "`repet'" != "" {
+	local b:word count `repet'
+	if `nbvars' != `b' {
+		di in red "The number of items in varlist is different from the number of items in repet"
+		exit 119
+	}
+}
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+local P:word count `partition'
+local S:word count `scorename'
+
+if "`scores'" != "" & "`scorename'" != "" {
+	di in red "scorenames() and scores() cannot be used together"
+	exit 119
+}  
+
+if "`scorename'" != "" {
+	if `P'!=`S' {
+		di in red "The number of score names given is different from the number of dimensions in the partition option" 
+		exit 119
+	}
+	foreach sco in `scorename' {
+		capture confirm variable `sco', exact
+		if !_rc {
+			di in red "`sco' already defined. You must choose names that do not already exist or use the scores() option if the scores are already defined."
+			exit 119
+	    }
+		tokenize `scorename'
+		local g = 0
+		forvalues i = 1/`S' {
+			if "`sco'" == "``i''" {
+				local `++g'
+			}
+		}
+		if `g' > 1 {
+			di in red "2 or more dimensions have the same name"
+			exit 119
+		}
+	}
+		calcscore `varlist', scorename(`scorename') partition(`partition') compscore(`compscore') categories(`categories')
+		global exist = 0
+		global scorename = "`scorename'"
+}
+
+else if "`scorename'" == "" & "`scores'" == ""{
+
+	local name
+	local nname
+	
+	forvalues i = 1/`P' {
+	
+		local name "Dim`i'"
+		local nname `nname' `name'
+	}
+	
+	local scorename = "`nname'"
+	global scorename = "`nname'"
+	calcscore `varlist', scorename(`scorename') partition(`partition') compscore(`compscore') categories(`categories')
+	global exist = 0
+}
+
+else if "`scores'" != "" {
+	local P:word count `partition'
+	local S2:word count `scores'
+	if `P'!=`S2' {
+		di in red "The number of score names given is different from the number of dimensions in the partition option" 
+		exit 119
+	}
+	else {
+		global scorename = "`scores'"
+		local scorename = "`scores'"
+		global exist = 1
+		
+	}
+	
+}
+
+local nbm : word count $categories
+if `nbm' !=2 &`nbm' !=`P'*2 &`nbm' !=`nbvars'*2 { 
+	di in red "option categories() misspecified. You must enter either 2 or `=`nbvars'*2' or `=`P'*2' elements"
+	exit 119
+}
+
+if `nbm' == 2{
+	tokenize $categories
+	foreach v in `varlist' {
+		tempvar min
+		tempvar max
+		egen `min' = min(`v')
+		egen `max' = max(`v')
+		if `min' < `1' {
+			di in red "error in option categories() : some responses have smaller values than the minimum value in categories()"
+			exit 119
+		} 
+		if `max' > `2' {
+			di in red "error in option categories() : some responses have greater values than the maximum value in categories()"
+			exit 119
+		} 
+	}
+}
+
+if `nbm' == `nbvars'*2 {
+	local i = 1
+	foreach v in `varlist' {
+		tempvar min max
+		egen `min' = min(`v')
+		egen `max' = max(`v')
+		local mi = `min' 
+		local ma = `max'
+		tokenize $categories
+		if `mi' < ``i'' {
+			di in red "error in option categories() : some responses have values less than the minimum value specified for the variable in categories()"
+			exit 119
+		}
+	local `++i'
+	tokenize $categories
+		if `ma' > ``i'' {
+			di in red "error in option categories() : some responses have values greater than the maximum value specified for the variable in categories()"
+			exit 119
+		}
+	local `++i'
+	}
+} 
+
+if `nbm' == `P'*2 {
+	local i = 1
+	local y = 1
+	
+	foreach x in `partition' {
+		//local `i++' 
+		if `i' == 1 local s = `x'
+		else local s = `s' +`x'
+		forvalues w = `y'/`s' {
+			tokenize $categories
+			tempvar min max
+			egen `min' = min(`var`w'')
+			egen `max' = max(`var`w'')
+			local mi = `min' 
+			local ma = `max'
+			if `mi' < ``i'' {
+				di in red "error in option categories() : some responses have values less than the minimum value specified"
+				exit 119
+			}
+			local j = `i'+1
+			tokenize $categories
+			if `ma' > ``j'' {
+				di in red "error in option categories() : some responses have values greater than the maximum value specified"
+				exit 119
+			}
+		}
+		local i = `i'+2
+		local y = `s'+1
+	}
+}
+
+if "`cfa'" != "" {
+	if "`cfacov'" != "" {
+		if !strpos("`cfacov'", "*") { 
+			di "error in cfacov() option : you must enter covariances between errors as follows: item3*item5 item7*item8 ...  "
+		exit 119
+	}
+		local v = subinstr("`cfacov'","*"," ",.)
+		foreach var in `v' {
+			capture confirm variable `var'
+			if _rc {
+				di in red "error in cfacov() option : `var' is not a variable from the dataset"
+				exit 119
+			}
+		}
+	}
+	
+}
+
+if "`kgv'" !="" {
+	foreach k in `kgv' {
+		capture confirm variable `k'
+		if _rc!=0 {
+			di in red "`k' does not exist" 
+			exit 119
+		}
+    }
+}
+
+if "`conc'" !="" {
+	foreach c in `conc' {
+		capture confirm variable `c'
+		if _rc!=0 {
+			di in red "`c' does not exist" 
+			exit 119
+		}
+    }
+}
+
+di as result "Items used to compute the scores"
+di
+
+local i = 1
+local j = 1
+local y = 1
+foreach p in `partition' {
+	tokenize `scorename'
+	di "{bf:``i''} : " _c
+	
+	if `j' == 1 local s = `p'
+	else local s = `s' +`p'
+	forvalues z = `y'/`s' {
+		di "{text:`var`z'' }" _c
+	}
+	local `i++' 
+	local `j++' 
+	local y = `s'+1
+	di
+}
+
+di
+di as result "Number of observations: " _c
+di as text _N
+
+qui destring _all, replace
+di
+
+if "`descitems'" != "" {
+	di as result "{hline 105}"
+	di "Description of items"
+	di as result "{hline 105}"
+	di
+	descitems `varlist', partition(`partition')
+	di
+}
+
+
+if "`graphs'" != "" {
+	graphs `varlist', partition(`partition')
+}						
+
+
+if "`repet'" != "" {
+	if "`descitems'" != "" {
+		di as result "{hline 105}"
+		di "Description of items (time 2)"
+		di as result "{hline 105}"
+		di
+		descitems `repet', partition(`partition')
+		di
+	}
+}
+
+if "`impute'" != "" {
+	if "`impute'" != "pms" & "`impute'" !="mi" {
+		di in red "option impute() incorrectly specified. You must specify {hi:pms} or {hi:mi}."
+		error 100
+	}
+	if "`impute'" == "pms" {
+		pms `varlist', partition(`partition') `noround'
+		if "`descitems'" != "" {
+			di as result "{hline 105}"
+			di "Description of items after missing data handling (PMS imputation)"
+			di as result "{hline 105}"
+			di
+			descitems `varlist', partition(`partition')
+			di
+		}
+		if "`repet'" != "" {
+			pms `repet', partition(`partition') `noround'
+			if "`descitems'" != "" {
+				di as result "{hline 105}"
+				di "Description of items after missing data handling (time 2)"
+				di as result "{hline 105}"
+				di
+				descitems `repet', partition(`partition')
+				di
+			}
+		}
+	}
+	if "`impute'" == "mi" {
+		mitw `varlist', partition(`partition') `noround' 
+		if "`descitems'" != "" {
+			di as result "{hline 105}"
+			di "Description of items after missing data handling (mi two-way imputation)"
+			di as result "{hline 105}"
+			di
+			descitems `varlist', partition(`partition')
+			di
+		}
+		if "`repet'" != "" {
+			mitw `repet', partition(`partition') `noround'
+			if "`descitems'" != "" {
+				di as result "{hline 105}"
+				di "Description of items after missing data handling (time 2)"
+				di as result "{hline 105}"
+				di
+				descitems `repet', partition(`partition')
+				di
+			}
+		}
+	}
+}  
+
+rel `varlist', scorename(`scorename') partition(`partition') alpha(`alpha') delta(`delta') h(`h') hjmin(`hjmin') categories(`categories')
+di
+
+if "`convdiv'" != "" {
+	convdiv `varlist', partition(`partition') tconvdiv(`tconvdiv') `convdivboxplots'
+	di
+}
+
+if "`cfa'" != "" {
+	cfa `varlist', partition(`partition') cfamethod(`cfamethod') `cfasb' `cfastand' cfacov(`cfacov') cfarmsea(`cfarmsea') cfacfi(`cfacfi') `cfaor' `cfanocovdim' `options'
+	di
+}
+
+if "`repet'" != "" | "`scores2'" != "" {
+	global scores2 = "`scores2'"
+	repet `varlist', t2(`repet') partition(`partition') `kappa' ickappa(`ickappa')
+	di
+}
+
+if "`kgv'" != "" {
+	kgv `scorename', categ(`kgv') `kgvboxplots' `kgvgroupboxplots'
+	di
+}
+
+if "`conc'" != "" {
+	conc `scorename', comp(`conc') tconc(`tconc')
+}
+
+
+//capture restore, not
+end
+
+
+/* pms */
+
+capture program drop pms
+program pms
+syntax varlist, PARTition(numlist integer >0) [NORound]
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit
+}
+
+local i = 1
+local y = 1
+
+tokenize `varlist'
+foreach x in `partition' {
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' ``w'' 
+	}
+	
+	local n : word count `liste' 
+	if mod(`n',2)!=0 local max = floor(`n'/2)
+	else local max = `n'/2-1
+	
+	if "`noround'" != "" {
+		qui imputeitems `liste', method(pms) max(`max') noround 
+		foreach var of varlist `liste' {
+			qui replace `var' = imp`var'
+			qui drop imp`var'
+		}
+	}
+	else {
+		qui imputeitems `liste', method(pms) max(`max')
+		foreach var of varlist `liste' {
+			qui replace `var' = imp`var'
+			qui drop imp`var'
+		}
+	}
+	
+	local `i++' 
+	local y = `s'+1
+}
+
+end
+
+
+/* mitw */
+
+capture program drop mitw
+program mitw
+syntax varlist, PARTition(numlist integer >0) [NORound]
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit
+}
+
+local i = 1
+local y = 1
+
+
+foreach x in `partition' {
+	tokenize `varlist'
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' ``w'' 
+	}
+		
+	qui mi_twoway `liste', scorename(scoretmp) add(1) style(wide) clear  
+		
+	foreach var of varlist `liste' {
+		qui replace `var' = _1_`var'
+		if "`noround'" == "" {
+			qui replace `var' = round(`var')
+		}
+		/*if `var' > `maxm' {
+			qui replace `var' = `maxm'
+		}
+		if `var' < `minm' {
+			qui replace `var' = `minm'
+		}*/
+		qui drop _1_`var'
+		capture drop scoretmp
+		capture drop _1_scoretmp
+	}
+		
+	local `i++' 
+	local y = `s'+1
+}
+
+//capture drop _mi_miss
+qui mi unset
+end
+
+
+/*  calcscore */
+
+capture program drop calcscore
+program calcscore,rclass
+syntax varlist, PARTition(numlist integer >0) [categories(numlist) COMPscore(string) SCOrename(string)]
+
+local P:word count `partition'
+local S:word count `scorename'
+		
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit
+}
+
+if "`scorename'" != "" {
+	if `P'!=`S' {
+		di in red "The number of score names given is different from the number of dimensions in the partition option" 
+		exit 119
+	}
+}
+
+local i = 1
+local y = 1
+foreach x in `partition' {
+	tokenize `varlist'
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' ``w'' 
+	}
+	
+	tempvar nonmiss
+	qui egen `nonmiss' = rownonmiss(`liste')
+		
+	tokenize `scorename'
+	local sc = "``i''"
+
+	if "`compscore'" == "" local compscore = "mean"
+
+	if "`compscore'" != "mean" & "`compscore'" != "sum" & "`compscore'" != "stand" {
+		di in red "option compscore incorrectly specified (choose among mean, sum and stand)"
+		error 198
+	}
+	
+	if "`compscore'" == "sum" {
+		qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2
+		qui replace `sc' = `sc'*`x'
+		
+	}
+	
+	else if "`compscore'" == "stand" {
+	
+		local nbm:word count `categories'
+		
+		local nbl:word count `liste'
+		tokenize `categories'
+	
+		if `nbm' == 2 {
+			local min = `1'*`nbl'
+			local max = `2'*`nbl'
+		}
+	
+		else if `nbm' == `P'*2 {
+			local min = ``b''*`nbl'
+			local max = ``=`b'+1''*`nbl'
+			
+		}
+	
+		else if `nbm' == `nbvars'*2 {
+			if `y'==1 local yy = 1
+			else local yy = `y'*2-1
+			local bb = `yy'
+			local min = 0
+			local max = 0
+		
+			forvalues bb = `yy'(2)`=`s'*2' {
+				local tpmin = ``bb''
+				local tpmax = ``=`bb'+1''
+				local min = `min'+`tpmin'
+				local max = `max'+`tpmax'
+			}
+		}
+			
+		else {
+			di in red "option categories() misspecified. You must enter either 2 or `=`nbvars'*2' or `=`P'*2' elements"
+			exit 119
+		}
+				
+		qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2
+		qui replace `sc' = `sc'*`nonmiss'
+		qui replace `sc' = (`sc'-`min')/(`max'-`min')*100
+	}
+	
+	else {
+		qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2
+	}
+
+local `i++' 
+local y = `s'+1
+}
+
+end
+
+
+
+/* rel */
+
+capture program drop rel
+program rel,rclass
+syntax varlist, PARTition(numlist integer >0) [CATegories(numlist) SCOrename(string) Alpha(real 0.7) Delta(real 0.9) h(real 0.3) HJmin(real 0.3)]
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit
+}
+
+local P:word count `partition'
+if "`scorename'" !="" {
+	local S:word count `scorename'
+	if `P'!=`S' {
+		di in red "The number of score names given is different from the number of dimensions in the partition option" 
+		exit
+	}
+}
+di as result "{hline 105}"
+di "{bf:Reliability}" 
+di as result "{hline 105}"
+di
+
+local y = 1
+local nbitems = 0
+matrix aa = J(`P',4,.)
+
+foreach z in `partition' {
+	local nbitems = `nbitems' + `z'
+}
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+matrix d = J(`nbitems',2,.)
+
+local i = 1
+local b = 1
+foreach x in `partition' {
+	
+	tokenize `scorename'
+	
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' `var`w'' 
+	}
+	
+	capture alpha `liste', asi item std
+	local al`i' = r(alpha)
+			
+	capture qui loevh `liste', pairwise 
+	local h`i' = r(loevH)
+	matrix c = r(loevHj)	
+	matrix ct = c'
+		
+	
+	local lister = ""
+	forvalues w = `y'/`s' {
+		tempvar z
+		qui gen `z' = round(`var`w'')
+		local lister `lister' `z' 
+	}
+	
+	tempvar nbmiss
+	local nbl : word count `lister'
+	egen `nbmiss' = rowmiss(`lister')
+	qui count if `nbmiss'<`nbl'
+	local n`i' = r(N)
+	
+	
+	// delta
+	
+	if ${exist} == 0 & "$compscore" == "sum" {
+	
+		local nbm:word count `categories'
+		tokenize `categories'
+		
+		if `nbm' == 2 {
+			local min = `1'*`nbl'
+			local max = `2'*`nbl'
+		}
+		
+		else if `nbm' == `P'*2 {
+			local min = ``b''*`nbl'
+			local max = ``=`b'+1''*`nbl'
+		}
+		
+		
+		else if `nbm' == `nbvars'*2 {
+			if `y'==1 local yy = 1
+			else local yy = `y'*2-1
+			local bb = `yy'
+			local min = 0
+			local max = 0
+			
+			forvalues bb = `yy'(2)`=`s'*2' {
+				local tpmin = ``bb''
+				local tpmax = ``=`bb'+1''
+				local min = `min'+`tpmin'
+				local max = `max'+`tpmax'
+				
+			}
+		}
+		
+		else {
+			di in red "option categories() misspecified. You must enter either 2 or `=`nbvars'*2' or `=`P'*2' elements"
+			exit 119
+		}
+		
+		capture delta `lister', min(`min') max(`max')
+		local delt`i' = r(delta)
+	
+	}
+	
+	else local delt`i' = .
+		
+	local k = 0
+	forvalues j = `y'/`s' {
+		local k = `k'+1
+		matrix d[`j',1] = ct[`k',1]
+		matrix d[`j',2] = `i'
+	}
+	
+	matrix aa [`i',1] = `al`i''
+	matrix aa [`i',2] = `delt`i''
+	matrix aa [`i',3] = `h`i''
+	
+	local `i++' 
+	local y = `s'+1
+	
+	local b = `b'+2
+}
+
+matrix rownames d = `varlist'
+local i = 1
+local y = 1
+
+foreach x in `partition' {
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	matrix C = d[`y'..`s',1.]
+	local min`i' = C[1,1]
+	local n : rownames C
+	tokenize `n'
+	local t`i' = "`1'"
+	forvalues j = 1/`x' {
+		local t = "``j''"
+		if C[`j',1] <= `min`i'' {
+			local min`i' = C[`j',1] 
+			local t`i' = "``j''"
+			local itmin`i' = "``j''"
+		}
+	}
+	matrix aa [`i',4] = `min`i''
+	local `i++' 
+	local y = `s'+1
+}
+
+matrix colnames aa = "alpha" "delta" "H" "Hj_min"
+
+if "`scorename'"=="" {
+	local i = 1
+	local y = 1
+	local name
+	local nname
+	forvalues i = 1/`P' {
+		local name "Dim`i'"
+		local nname `nname' `name'
+	}
+local scorename = "`nname'"
+}	
+
+local maxlen = 0
+foreach sco in `scorename' {
+	local w = length("`sco'")
+	if `w' > `maxlen' local maxlen = `w'
+}
+
+local i = 1
+local j = 1
+local y = 1
+local col = `maxlen'+8
+
+di _col(`col') "{bf:n}" _c
+local col = `col'+6
+di _col(`col') "{bf:alpha}" _c
+local col = `col'+10
+di _col(`col') "{bf:delta}" _c
+local col = `col'+14
+di _col(`col') "{bf:H}" _c
+local col = `col'+5
+di _col(`col') "{bf:Hj_min}"
+
+foreach s in `scorename' {
+	di in blue "{bf:`s'}" _c
+	local col = `maxlen'+3
+	
+	local n : di %6.0f `n`i''
+	
+	di in blue _col(`col') "{text:`n'}" _c
+	local col = `col'+10
+	
+	local a : di %6.2f `al`i''
+	if `a' < `alpha' {
+		di _col(`col') "{error:`a'} " _c
+	}
+	else di _col(`col') "{text:`a'}" _c
+	
+	local col = `col'+10
+	local d : di %6.2f `delt`i''
+	if `d' < `delta' {
+		di _col(`col') "{error:`d'} " _c
+	}
+	else di _col(`col') "{text:`d'}" _c
+	
+	local col = `col'+10
+	local ht : di %6.2f `h`i''
+	if `ht' < `h' {
+		di _col(`col') "{error:`ht'} " _c
+	}
+	else di _col(`col') "{text:`ht'}" _c
+	
+	local col = `col'+8
+	local m : di %8.2f `min`i''
+	if `m' < `hjmin' {
+		di _col(`col') "{error:`m'} " _c
+		di "{text:(item `itmin`i'')}" _c
+	}
+	else di _col(`col') "{text:`m'}" _c
+	
+	di
+	local `++i'
+}
+
+end
+
+/* descitems */
+
+capture program drop descitems
+program descitems
+syntax varlist, PARTition(numlist integer >0)
+local i = 1
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+
+local nbvars : word count `varlist'
+
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit 119
+}
+
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+foreach var in `varlist' {
+	qui replace `var' = round(`var')
+}
+
+local lev = ""
+foreach var in `varlist' {
+	qui levelsof `var', local(levels)
+	foreach l in `levels' {
+		if strpos("`lev'","`l'") == 0 {
+		local lev `lev' `l'	
+		}
+	}
+}
+
+_qsort_index `lev'
+local lev = r(slist1)
+
+local i = 1
+matrix d = J(`nbvars',4,.)
+
+foreach var in `varlist'{
+	qui count if missing(`var')
+	local ct=r(N)
+	
+	local tx`i'=`ct'/_N
+	matrix d[`i',1] = `tx`i''
+	local `i++'
+}
+
+matrix rownames d = `varlist'
+matrix colnames d = "missing" "alpha" "Hj" 
+
+local i = 1
+local y = 1
+foreach x in `partition' {
+	
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' `var`w'' 
+	}
+	
+	qui capture alpha `liste', asi item std
+	
+	mat a = r(Alpha)
+	mat at = a'
+	
+	qui capture loevh `liste', pairwise pair
+	matrix e = r(loevHj)	
+	matrix et = e'
+	
+	//matrix ns = r(nbHjkNS)	
+	//matrix nst = ns'
+	
+	
+	matrix pval = r(pvalHjk)
+	forvalues c = 1/`x' {
+		forvalues r = 1/`x' {
+			if pval[`r',`c']>0.05 {
+				local ns`r' = `ns`r''+1
+			}
+			else local ns`r' = `ns`r''+0
+		}
+	}
+	
+	
+	foreach z in `partition' {
+		local nbitems = `nbitems' + `z'
+	}
+	matrix nst = J(`nbitems',1,0)
+	local r = 1
+	forvalues j = `y'/`s'{
+		matrix nst[`j',1]=`ns`r''
+		local `r++'
+	}
+		
+	
+	local k = 0
+	forvalues j = `y'/`s' {
+		local k = `k'+1
+		matrix d[`j',2] = at[`k',1]
+		matrix d[`j',3] = et[`k',1]
+		matrix d[`j',4] = `ns`k''
+		
+	}
+	local `i++' 
+	local y = `s'+1	
+	
+	forvalues j = 1/21{
+		local ns`j' = 0
+	}
+}
+
+
+
+local i = 1
+foreach v in `varlist' {
+	local var`i' = abbrev("`v'",8)
+	local `++i'
+}
+
+local dec = 10
+local col = `dec'
+
+
+local minm = 999
+local maxm = -999
+foreach mod in $categories {
+	if `mod' < `minm' local minm = `mod'
+	if `mod' > `maxm' local maxm = `mod'
+}
+
+local b = `maxm'-`minm'+1
+
+local i = 1
+local j = 1
+local y = 1
+
+di in blue _col(`dec') "{bf:Missing}" _c
+local col = `col'+11
+di in blue _col(`=`col'+2') "{bf:N}" _c
+
+local col = `col'+9
+di _col(`col') "{bf:Response categories}" _c
+local col = `dec'+18+8*`b'
+di _col(`col') "{bf:Alpha}" _c
+local col = `col'+9
+di _col(`col') "{bf:Loevinger}" _c  
+local col = `col'+12
+di _col(`col') "{bf:Number of}" 
+
+local col = `dec'-1
+di _col(`col') "{bf:data rate}" _c
+local col = `dec'+18
+
+forvalues m = `minm'/`maxm' {
+	di _col(`=`col'+2') "`m'" _c
+	local col = `col'+8
+}
+
+di as result _col(`col') "- item" _c
+local col = `col'+10
+di as result _col(`col') "Hj coeff" _c 
+local col = `col'+12
+di as result _col(`col') "NS Hjk"  
+
+local ch = `dec'+18+8*`b'+29
+di "{hline `ch'}"
+
+local i = 1 
+foreach x in `varlist' {
+	local varo`i' = "`x'"
+	local `++i'
+}
+
+local y = 1
+foreach p in `partition' {
+	
+	if `j' == 1 local s = `p'
+	else local s = `s' +`p'
+	
+	forvalues z = `y'/`s' { 
+		local col = `dec'
+		di "{bf:`var`z''}" _c
+		local t = d[`z',1]
+		local t : di %8.2f `t'*100 
+		di _col(`col') "{text:`t'%}" _c
+		qui count if missing(`varo`z'')
+		local m = r(N)
+		local N = _N-`m'
+		local N : di %4.0f `N'
+		local col = `col'+10
+		di _col(`col') "{text:`N'}" _c
+		
+		local col = `col'+8
+		forvalues m = `minm'/`maxm' {
+			qui count if round(`varo`z'') == `m'
+			local n = r(N)
+			if `m' == `maxm' & round(`varo`z'')>`maxm' & `varo`z''!=.{
+				local n = `n' + 1
+			}
+			if `m' == `minm' & round(`varo`z'')<`minm' & `varo`z''!=.{
+				local n = `n' + 1
+			}
+			qui count if `varo`z'' != . 
+			local d = r(N)
+			local e = `n'/`d'
+			local e : di %4.2f `e'*100
+			if `e' != 0 di _col(`=`col'-1')"{text:`e'%}" _c
+			else di _col(`=`col'-1')"{text:   -}" _c
+			local col = `col'+8
+		}
+		local a = d[`z',2]
+		local a : di %4.2f `a'
+		di _col(`=`col'+1') "{text:`a'}" _c
+		local h = d[`z',3]
+		local h : di %5.2f `h'
+		local col = `col'+10
+		di _col(`=`col'+3') "{text:`h'}" _c
+		local ns = d[`z',4]
+		local ns : di %2.0f `ns'
+		local col = `col'+11
+		di _col(`=`col'+7') "{text:`ns'}" 
+			
+	}
+	local `i++' 
+	local `j++' 
+	local y = `s'+1
+	di "{dup `ch':-}" 
+}
+end
+
+
+capture program drop graphs
+program graphs
+syntax varlist, PARTition(numlist integer >0)
+
+local P:word count `partition'
+local html = "${html}"
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+if "$compscore" == "stand" local w = 10
+if "$compscore" == "sum" local b = 10
+if "$compscore" == "mean" local w = 0.5
+
+
+
+
+if "`html'"!="" {
+	//set graphics off
+	foreach s in $scorename {
+		qui local saving "saving(`c(tmpdir)'/`html'_`s',replace) nodraw"
+		qui hist `s', name(`s',replace) percent fcolor(emidblue) lcolor(none) width(`w') bin(`b') `saving'
+		qui graph use `c(tmpdir)'/`html'_`s'.gph
+		qui graph export `c(tmpdir)'/`html'_`s'.png, replace
+		//di " _char(34) "
+
+	}
+	//set graphics on
+
+	
+	
+	qui local saving "saving(`c(tmpdir)'/`html'_group,replace) nodraw"
+	qui gr combine $scorename, name(group,replace) title("Distribution of scores") `saving'  
+	qui graph use `c(tmpdir)'/`html'_group.gph
+	qui graph export `c(tmpdir)'/`html'_group.png, replace
+	//di " _char(34) "
+
+	
+	qui local saving "saving(`c(tmpdir)'/`html'_scores,replace) nodraw"
+	qui biplot $scorename, name("Biplot_scores",replace) norow std title("Correlations between scores") xtitle("") ytitle("") `saving'
+	qui graph use `c(tmpdir)'/`html'_scores.gph
+	qui graph export `c(tmpdir)'/`html'_scores.png, replace
+	//di " _char(34) "
+}
+
+else {
+	set graphics off
+	foreach s in $scorename {
+		qui hist `s', name("`s'",replace) percent fcolor(emidblue) lcolor(none) width(`w') bin(`b')
+	}
+	set graphics on
+
+	gr combine $scorename, name("Histograms_scores",replace)
+	if ("$filessave"!="") qui graph export ${dirsave}/Histograms_scores.png, replace
+
+	capture biplot $scorename, name("Biplot_scores",replace) norow std title("") xtitle("") ytitle("")
+	if ("$filessave"!="") qui graph export ${dirsave}/Biplot_scores.png, replace
+
+}
+
+
+
+capture biplot `varlist', name("temp",replace) norow std nograph
+
+mat a = r(V)
+
+tempvar a1 a2
+mat colnames a = `a1' `a2'
+svmat a, names(col)
+
+tempvar mina1 mina2 maxa1 maxa2
+egen `mina1' = min(`a1')
+egen `mina2' = min(`a2')
+egen `maxa1' = max(`a1')
+egen `maxa2' = max(`a2')
+local mina1 = `mina1'
+local mina2 = `mina2'
+local maxa1 = `maxa1'+1.4
+local maxa1x = `maxa1'+0.3
+local maxa2 = `maxa2'
+
+local colors = "red blue black green ebblue mint erose orange maroon magenta mint gray teal navy olive sienna"
+local i = 1
+foreach c in `colors' {
+	local col`i' = "`c'"
+	local `++i'
+}
+
+local i = 1
+local y = 1
+local c = 1
+local bas = `maxa2'+0.2
+local droite = max(`maxa1',0.2)
+
+foreach x in `partition' {
+	tokenize $scorename
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	forvalues j=`y'/`s' {
+		local a = `a1'[`j']
+		local b = `a2'[`j']	
+		local call `call' || pcarrowi 0 0 `b' `a' "`var`j''", mlabcolor(`col`i'') color(`col`i'') head   
+	}
+	local bas = `bas'-0.2
+	local call `call' text(`bas' `droite' "``i''", size(3) color(`col`i'')) /*`bas' `droite' "``i''", mlabcolor("`r' `g' `b'")*/
+	local `++i' 
+	local y = `s'+1	
+	local `++c' 
+}
+
+
+if "`html'" != "" {
+	qui local saving "saving(`c(tmpdir)'/`html'_items,replace) nodraw"
+	qui twoway `call' name("items",replace) legend(off) xscale(range(`mina1' `maxa1x')) yscale(range(`mina2' `maxa2')) title("Correlations between items") xtitle("") ytitle("") xsize(`xsize') ysize(`ysize') `saving'
+	qui graph use `c(tmpdir)'/`html'_items.gph
+	qui graph export `c(tmpdir)'/`html'_items.png, replace
+	//di " _char(34) "
+}
+else {
+	qui twoway `call' name("Biplot_items",replace) legend(off) xscale(range(`mina1' `maxa1x')) yscale(range(`mina2' `maxa2')) xtitle("") ytitle("")
+	if ("$filessave"!="") qui graph export ${dirsave}/Biplot_items.png, replace
+
+}
+
+
+							
+end
+
+/* convdiv */
+
+capture program drop convdiv
+program convdiv
+syntax varlist, PARTition(numlist integer >0) [TCONVdiv(real 0.4) convdivboxplots]
+preserve
+
+//qui set autotabgraphs on
+
+
+
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+local P:word count `partition'
+local cptdiv = 0
+local cptconv = 0
+
+if ${exist} != 1 {
+
+	qui detect `varlist', partition(`partition') 
+
+	matrix A = r(Corrrestscores)
+	matrix B = r(Corrscores)
+
+	local i = 1
+	local y = 1
+
+	foreach x in `partition' {
+		if `i' == 1 local s = `x'
+		else local s = `s' +`x'
+		
+		forvalues z = `y'/`s' {
+			matrix B[`z',`i'] = A[`z',`i']
+		}
+		local `i++' 
+		local y = `s'+1
+	} 
+
+	matrix colnames B = $scorename
+
+    local i = 1
+	foreach v in `varlist' {
+		local var`i' = abbrev("`v'",10)
+		local `++i'
+	}
+
+	local i = 1
+	foreach s in $scorename {
+		local s`i' = abbrev("`s'",7)
+		local sc `sc' `s`i''
+		local `++i'
+	}
+
+	di as result "{hline 105}"
+	di "{bf:Correlation matrix}"
+	di "{hline 105}"
+	di
+
+	local dec = 10
+	local col = `dec'
+
+	local decit = 14
+	local colit = `decit'
+
+
+	local col1 = `decit'
+	forvalues i=1/`P' {
+		di _col(`col1') "{bf:`s`i''}" _c
+		local col1 = `col1' + `dec'
+	}
+
+	di 
+	local h = (`P'-1)*`dec'+`decit'+4
+	di "{hline `h'}"
+
+	local i = 1
+	local j = 1
+	local y = 1
+
+	foreach p in `partition' {
+		if `j' == 1 local s = `p'
+		else local s = `s' +`p'
+		
+		forvalues z = `y'/`s' { 
+			di as text "{bf:`var`z''}" _c
+			local col = `decit'-1	
+			
+			local dd = `z' // [count cptdiv (one per item)] 
+			
+			forvalues k = 1/`P' { 
+					
+				local t = B[`z',`k']
+				local t : di %6.3f `t'
+				if `k' == `i' {
+					if `t' < `tconvdiv' {
+						/*if "${html}" != "" {
+							di "

" + di _col(`col') "{bf:`t'}" _c + di "

" + }*/ + //else { + di in red _col(`col') "{bf:`t'}" _c + //} + + local cptconv = `cptconv'+1 + local col = `col' + `dec' + } + else { + /*if "${html}" != "" { + di "

" + di as text _col(`col') "{bf:`t'}" _c + di "

" + }*/ + //else { + di as text _col(`col') "{bf:`t'}" _c + //} + local col = `col' + `dec' + } + } + else { + + if B[`z',`k'] > B[`z',`i'] { + /*if "${html}" != "" { + di "" + di in red _col(`col') "`t'" _c + di "" + }*/ + //else { + di in red _col(`col') "`t'" _c + //} + + if `dd' == `z' local cptdiv = `cptdiv'+1 // [one per item] + local dd = 0 + local col = `col' + `dec' + } + else { + /*if "${html}" != "" { + di "

" + di as text _col(`col') "{text:`t'}"_c + di "

" + }*/ + //else { + di as text _col(`col') "{text:`t'}"_c + //} + + local col = `col' + `dec' + } + } + } + di + } + di as text "{dup `h':-}" + local `i++' + local `j++' + local y = `s'+1 + } + + local y = 1 + local h = 1 + local np : word count `partition' + + foreach p in `partition' { + if `h' == 1 local s = `p' + else local s = `s' +`p' + + forvalues j = 1/`np' { + mat C_`h'_`j' = B[`y'..`s',`j'] + + tempvar tp_`h'_`j' + mat colnames C_`h'_`j' = `tp_`h'_`j'' + + svmat C_`h'_`j', names(col) + } + + local `++h' + local y = `s'+1 + } + +} + +else if ${exist} == 1 { + + di as result "{hline 105}" + di "{bf:Correlation matrix (without rest-scores)}" + di "{hline 105}" + di + + + local i = 1 + foreach v in `varlist' { + local var`i' = abbrev("`v'",10) + local `++i' + } + + local i = 1 + foreach s in $scorename { + local s`i' = abbrev("`s'",7) + local sc `sc' `s`i'' + local `++i' + } + + local dec = 10 + local col = `dec' + + local decit = 14 + local colit = `decit' + + local col1 = `decit' + forvalues i=1/`P' { + di _col(`col1') "{bf:`s`i''}" _c + local col1 = `col1' + `dec' + } + + di + local h = (`P'-1)*`dec'+`decit'+4 + di "{hline `h'}" + + qui corr $scorename `varlist' + matrix c = r(C) + matrix B = c[`=`P'+1'..`nbvars'+`P',1..`P'] + + local i = 1 + local j = 1 + local y = 1 + + foreach p in `partition' { + if `j' == 1 local s = `p' + else local s = `s' +`p' + + forvalues z = `y'/`s' { + di as text "{bf:`var`z''}" _c + local col = `decit'-1 + + local dd = `z' // [count cptdiv (one per item)] + + forvalues k = 1/`P' { + + local t = B[`z',`k'] + local t : di %6.3f `t' + if `k' == `i' { + if `t' < `tconvdiv' { + di in red _col(`col') "{bf:`t'}" _c + local cptconv = `cptconv'+1 + local col = `col' + `dec' + } + else { + di _col(`col') "{bf:`t'}" _c + local col = `col' + `dec' + } + } + else { + + if B[`z',`k'] > B[`z',`i'] { + di in red _col(`col') "`t'" _c + + if `dd' == `z' local cptdiv = `cptdiv'+1 // [one per item] + local dd = 0 + local col = `col' + `dec' + } + else { + di as text _col(`col') "{text:`t'}"_c + local col = `col' + `dec' + } + } + } + di + } + di "{dup `h':-}" + local `i++' + local `j++' + local y = `s'+1 + } + + local y = 1 + local h = 1 + local np : word count `partition' + + foreach p in `partition' { + if `h' == 1 local s = `p' + else local s = `s' +`p' + + forvalues j = 1/`np' { + mat C_`h'_`j' = B[`y'..`s',`j'] + + tempvar tp_`h'_`j' + mat colnames C_`h'_`j' = `tp_`h'_`j'' + + svmat C_`h'_`j', names(col) + } + + local `++h' + local y = `s'+1 + } +} + +if "`convdivboxplots'" != "" { + + if "${html}" != "" { + local html = "${html}" + di "
" + di "
" + + + local colors = "red blue green orange maroon magenta ebblue mint erose gray teal navy olive sienna" + local i = 1 + foreach c in `colors' { + local col`i' = "`c'" + local `++i' + } + + forvalues h = 1/`np' { + tokenize $scorename + local call = "" + local callbox = "" + local callleg = "" + + forvalues j = 1/`np' { + local call `call' `tp_`h'_`j'' + local callbox `callbox' box(`j',fcolor(`col`j'') lcolor(`col`j'')) marker(`j', mcolor(`col`j'')) + local lab = "``j''" + local lab = `"`lab'"' + local callleg `callleg' `j' "`lab'" + } + + qui local saving "saving(`c(tmpdir)'/`html'_Conv_div_``h'',replace) nodraw" + qui graph box `call', name("Conv_div_``h''",replace) `callbox' legend(order(`"`callleg'"') stack rows(1) size(small)) title(Correlations between items of ``h'' and scores) yline(`tconvdiv', lpattern(dot) lcolor(black)) `saving' + qui graph use `c(tmpdir)'/`html'_Conv_div_``h''.gph + qui graph export `c(tmpdir)'/`html'_Conv_div_``h''.png, replace + + di " _char(34) " + + + + //qui set autotabgraphs on + } + di "
" + di "
"
+	}
+	
+	else {
+		forvalues h = 1/`np' {
+		tokenize $scorename
+		local call = ""
+		local callbox = ""
+		local callleg = ""
+		
+		forvalues j = 1/`np' {
+			local call `call' `tp_`h'_`j''
+			local callbox `callbox' box(`j',fcolor(`color') lcolor(`color')) marker(`j', mcolor(`color')) 
+			local lab = "``j''"
+			local lab = `"`lab'"'
+			local callleg `callleg' `j' "`lab'"
+		}
+		di "ok1"
+		graph box `call', name("Conv_div_``h''",replace) `callbox' legend(order(`"`callleg'"') stack rows(1) size(small)) title(Correlations between items of ``h'' and scores) yline(`tconvdiv', lpattern(dot) lcolor(black))
+		di "ok2"
+		if ("$filessave"!="") qui graph export ${dirsave}/Conv_div_``h''.png, replace
+		qui set autotabgraphs on
+		}
+	}
+}
+
+
+local t : di %5.3f `tconvdiv'
+local p1 = (`nbvars'-`cptconv')/`nbvars'*100
+local p1 : di %4.1f `p1'
+local p2 = (`nbvars'-`cptdiv')/`nbvars'*100
+local p2 : di %4.1f `p2'
+
+di
+di as result "Convergent validity:" _c
+di as text " `=`nbvars'-`cptconv''/`nbvars' items (`p1'%) have a correlation coefficient with the score of "
+di _col(22) "their own dimension greater than `t'"
+di
+di as result "Divergent validity:" _c
+di as text "  `=`nbvars'-`cptdiv''/`nbvars' items (`p2'%) have a correlation coefficient with the score"
+di _col(22) "of their own dimension greater than those computed with other scores." 
+
+end
+
+/* cfa */
+
+capture program drop cfa
+program cfa,rclass
+syntax varlist, PARTition(numlist integer >0) [CFAMethod(string) cfasb CFAStand CFACov(string) CFARmsea(real -999) CFACfi(real -999) CFAOR CFANOCOVDim *] 
+preserve
+
+if "`cfasb'"!="" & `cfacfi'!=-999 {
+	di in red "You cannot use both cfasb and cfacfi()"
+	exit 119
+} 
+
+if "`cfasb'"!="" & `cfarmsea'!=-999 {
+	di in red "You cannot use both cfasb and cfarmsea()"
+	exit 119
+}
+
+
+	
+if `cfarmsea' == -999{
+	local cfarmsea 
+	//di in red "error in cfaautormsea option : you must specify a value"
+	//exit 119
+}
+if `cfacfi' == -999{
+	local cfacfi
+	//di in red "error in cfaautocfi option : you must specify a value"
+	//exit 119
+}
+	
+local nbvars:word count `varlist'	
+local P:word count `partition'
+	
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+/*
+if "`cfarmsea'" != "" & "`cfacov'" != "" {
+	di in red "You cannot use both cfacov() and cfarmsea"
+	exit 119
+}
+if "`cfacfi'" != "" & "`cfacov'" != "" {
+	di in red "You cannot use both cfacov() and cfacfi"
+	exit 119
+}
+*/	
+if "`cfacov'" != "" {
+	
+	lstrfun v, subinstr("`cfacov'","*"," ",.)
+	foreach var in `v' {
+		capture confirm variable `var'
+		if _rc {
+			di in red "error in cfacov() option : `var' is not a variable from the dataset"
+			exit 119
+		}
+	}
+	lstrfun s,  subinstr("`cfacov'","* ","*",.)
+	lstrfun s,  subinstr("`s'"," *","*",.)
+	lstrfun s,  subinstr("`s'","*","*e.",.)
+	lstrfun f,  subinstr("`s'"," "," e.",.)
+	local g e.`f'
+	lstrfun g , lower("`g'")
+    local covs `g'
+}
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = lower("`x'")
+	qui rename `x' `var`i''
+	local `++i'
+}
+
+local upscorename = upper("$scorename")
+
+local i = 0
+local y = 1
+tokenize `upscorename'
+foreach x in `partition' {
+	local `i++' 
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' `var`w'' 
+	}
+	
+	local a =  "(``i'' -> `liste')"
+	local zz `zz' `a'
+		
+	local y = `s'+1
+}
+
+if "`cfamethod'" == "" local cfamethod = "ml"
+
+if "`cfamethod'" != "ml" & "`cfamethod'" != "mlmv" & "`cfamethod'" != "adf" {
+	di "`cfamethod'"
+	di in red "option cfamethod incorrectly specified (choose among ml, mlmv and adf)."
+	error 198
+}
+
+if "`cfastand'" != "" local cfastand = "stand"
+
+if "`cfasb'" != "" {
+	local cfasb = "vce(sbentler)"
+	local sb = "_sb"
+}
+
+di as result "{hline 105}"
+di "{bf:Confirmatory factor analysis}"
+di as result "{hline 105}"
+
+local exitloop = 0
+foreach v in `varlist' {
+		local low = lower("`v'")
+		qui su `low'
+		local range = r(max)-r(min)+1
+		if `range' < 5 & "`cfamethod'"=="ml"{
+			local message "Warning: some items have less than 5 response categories. If multivariate normality assumption does not hold, maximum likelihood estimation might not be appropriate. Consider using cfamethod(adf)."
+			continue, break
+		}
+		else if `range' >= 5 & `range' < 7  & "`cfamethod'"=="ml" & "`cfasb'" == "" {
+			local message "Warning: some items have less than 7 response categories. If multivariate normality assumption does not hold, maximum likelihood estimation might not be appropriate. Consider using cfasb in order to apply Satorra-Bentler adjustment or using cfamethod(adf)."
+			continue
+		}
+}
+
+di in red "`message'"
+
+local ii = 1
+local s
+local stop = 0 
+
+while (`ii' == 1 | "`covsi'" != "") & `stop'!=1 {
+	if `ii' == 1 & ("`cfarmsea'"!="" | "`cfacfi'"!="") {
+		di
+		di as text "step 1 (model without covariances between errors)" 
+	}
+	if "`covs'" != "" & ("`cfarmsea'"!="" | "`cfacfi'"!="") di _n "{bf:step `ii':} {text:`covsi'}"
+	local covsi
+	
+	
+	if "`cfanocovdim'" == "" {
+		qui sem `zz', method(`cfamethod') `cfastand' cov(`covs') `cfasb' `options'
+	}
+	else {
+		qui sem `zz', method(`cfamethod') `cfastand' cov(`covs') covstruct(_lexogenous, diagonal) `cfasb' `options'
+	}
+	local vce = e(vce)
+	
+	/* factor loadings */
+
+	matrix r = r(table)
+	matrix r = r[1,1...]
+	matrix r = r'
+	local n = `nbvars'*2 
+
+	matrix a = r[1,1]
+	forvalues i=3(2)`n' {
+		matrix b = r[`i',1]
+		matrix a = a\b
+	}
+
+	/* standard error factor loadings*/
+
+	matrix r = r(table)
+	matrix r = r[2,1...]
+	matrix r = r'
+	local n = `nbvars'*2 
+
+	matrix sef = r[1,1]
+	forvalues i=3(2)`n' {
+		matrix b = r[`i',1]
+		matrix sef = sef\b
+	}
+
+	
+	/* intercepts */
+
+	matrix r = r(table)
+	matrix r = r[1,1...]
+	matrix r = r'
+	local n = `nbvars'*2 
+
+	matrix a2 = r[2,1]
+	forvalues i=4(2)`n' {
+		matrix b = r[`i',1]
+		matrix a2 = a2\b
+	}
+	
+	
+	/* standard error intercepts*/
+
+	matrix r = r(table)
+	matrix r = r[2,2...]
+	matrix r = r'
+	local n = `nbvars'*2 
+
+	matrix sei = r[1,1]
+	forvalues i=3(2)`n' {
+		matrix b = r[`i',1]
+		matrix sei = sei\b
+	}
+	
+	//mat li sei
+	/* error variances */
+
+	local m = `n'+1
+	matrix r = r(table)
+	matrix r = r[1,`m'...]
+	matrix r = r'
+
+	matrix a3 = r[1,1]
+	forvalues i=2/`nbvars' {
+		matrix b = r[`i',1]
+		matrix a3 = a3\b
+	}
+
+	/* variance of dimensions*/
+
+	matrix r = r(table)
+	local n = `nbvars'*3+1
+	matrix r = r[1,`n'...]
+	matrix r = r'
+
+	matrix var = r[1,1]
+	forvalues i=2/`P' {
+		matrix b = r[`i',1]
+		matrix var = var\b
+	}
+	
+	//mat li var
+	
+	/* Covariances between dimensions */
+	
+	matrix r = r(table)
+	local P:word count `partition'
+	if `P' > 1 {
+		local one = 1
+	}
+	else{
+		local one = 0
+	}
+	local n = `nbvars'*3+`one'+`P'
+	
+	
+	if "`cfanocovdim'" == "" {
+		//mat li r
+		matrix r = r[1,`n'...]
+		//mat li r
+		matrix c = J(`P',`P',.)
+		
+		local nbcov:word count `cfacov'
+		local `++nbcov'
+		
+		local k = `nbcov'
+		forvalues c = 1/`P' { 
+			forvalues r = 2/`P' {
+				if `r'>`c' {
+					matrix c[`r',`c']=r[1,`k']
+					local `++k'
+				}
+			}
+		}
+		
+		local k = 1
+		forvalues c = 1/`P' { 
+			matrix c[`c',`c']=var[`k',1]
+			local `++k'
+		}
+			
+		matrix rownames c = $scorename
+		matrix colnames c = $scorename
+	}
+	
+	if ("`cfarmsea'"!="" | "`cfacfi'"!="") {
+		local stoprmsea = 0
+		 local stopcfi = 0
+		if "`cfarmsea'"!="" {
+			qui estat gof
+			di "rmsea =" round(r(rmsea),0.001)
+			if r(rmsea)<=`cfarmsea' {
+				local stoprmsea = 1
+			}
+			//else local stoprmsea = 0
+		}
+		else local stoprmsea = 1
+		if "`cfacfi'"!="" {
+			qui estat gof
+			di "cfi =" round(r(cfi),0.001)
+			if r(cfi)>=`cfacfi' {
+				local stopcfi = 1
+			}
+			//else local stopcfi = 0
+		}
+		else local stopcfi = 1
+		
+	
+		
+		/* OR */ 
+		if "`cfaor'"!="" {
+			if `stoprmsea'==1 | `stopcfi'==1 {
+				local stop = 1
+			}
+		}
+		/* AND */ 
+		if "`cfaor'"=="" {
+			if `stoprmsea'==1 & `stopcfi'==1 {
+				local stop = 1
+			}
+		}
+	}
+	
+	
+	if ("`cfarmsea'"!="" | "`cfacfi'"!="") & `stop'!=1 {
+		qui estat mindices, showpclass(mcons merrvar)
+		tempname mm nomcol
+		mat `mm' = r(mindices)
+				
+		svmat2 `mm' , r(`nomcol') full
+		gsort - `mm'1
+		
+		local nrows = rowsof(`mm')
+		
+		local y = 1
+		local i = 0
+		foreach x in `partition' {
+			local `i++' 
+			if `i' == 1 local s = `x'
+			else local s = `s' +`x'
+			
+			forvalues w = `y'/`s' {
+				local class_`var`w'' = `i'
+			}
+			local y = `s'+1
+		}
+		
+		
+		forvalues i = 1/`nrows' {
+			local tmp3=`nomcol'[`i']
+			lstrfun e, subinstr("`tmp3'","cov(","",.)
+			lstrfun e, subinstr("`e'",")","",.)
+			lstrfun e, subinstr("`e'",":_cons","",.)
+			lstrfun e, subinstr("`e'",",","*",.)
+			
+			lstrfun d, subinstr("`e'",","," ",.)
+			lstrfun d, subinstr("`d'","e.","",.)
+			lstrfun d, subinstr("`d'","*"," ",.)
+			
+			qui replace `nomcol' = "`d'" in `i'
+			
+			local d = `nomcol'[`i']
+			
+			tokenize "`d'"
+			if "`class_`1''" != "`class_`2''" {
+				qui replace `nomcol' = "" in `i'
+			}
+			
+			local tmp3=`nomcol'[`i']
+			
+			if "`tmp3'" != "" {
+				continue, break
+			}
+			else {
+				local e
+			}
+			
+			
+		}
+		
+		
+		
+				
+		local covsi `e'
+		local covs `covs' `e'
+		drop `mm'1-`nomcol'
+
+	}
+	
+	if e(converged) == 0 di in red "Warning : model did not converge after `e(ic)' iterations"
+	local `++ii'
+	
+}
+
+local i = 1
+foreach v in `varlist' {
+	local var`i' = abbrev("`v'",10)
+	local `++i'
+}
+
+local i = 1
+foreach s in $scorename {
+	local s`i' = abbrev("`s'",10)
+	local sc `sc' `s`i''
+	local `++i'
+
+}
+
+local max = 10
+local dec = `max'+5
+
+local max2 = 10
+
+local dec2 = `dec'+`max2'+5
+
+local a = e(N)
+di
+if e(converged) == 0 di in red "Warning : model did not converge after `e(ic)' iterations"
+di as result ""
+if "`covs'" != "" {
+	di as result "{bf:Covariances between errors added:} {text:`covs'}"
+	di
+}
+di "{bf:Number of used individuals: } {text:`a'}"
+di
+//di _col(`=`dec2'+17+4') "{bf:Estimation:}"
+
+
+di as result "{bf:Item}" _c
+di _col(`dec') "{bf:Dimension}" _c 
+di _col(`dec2') "{bf:Factor}" _c 
+di _col(`=`dec2'+14') "{bf:Standard}" _c 
+di _col(`=`dec2'+28') "{bf:Intercept}" _c  
+di _col(`=`dec2'+43') "{bf:Standard}" _c  
+
+if "`cfastand'" == "" {
+	di _col(`=`dec2'+57') "{bf:Error}" _c 
+	di _col(`=`dec2'+66') "{bf:Variance of}"
+	di _col(`dec2') "{bf:loading}" _c 
+	di _col(`=`dec2'+14') "{bf:error}" _c
+	di _col(`=`dec2'+43') "{bf:error}" _c
+	di _col(`=`dec2'+55') "{bf:variance}" _c
+	di _col(`=`dec2'+67') "{bf:dimension}"
+	local h = `dec2'+76
+}
+else {
+	di _col(`=`dec2'+57') "{bf:Error}" 
+	di _col(`dec2') "{bf:loading}" _c 
+	di _col(`=`dec2'+14') "{bf:error}" _c
+	di _col(`=`dec2'+44') "{bf:error}" _c
+	di _col(`=`dec2'+57') "{bf:variance}" 
+	local h = `dec2'+62
+} 
+
+di "{hline `h'}"
+
+local i = 1
+local y = 1
+foreach x in `partition' {
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	forvalues z = `y'/`s' {
+		tokenize `sc'
+		di "{bf:`var`z''}"_c
+		di _col(`dec') "{bf:``i''}" _c
+		local t = a[`z',1]
+		local t : di %7.2f `t'
+		di _col(`dec2') "{text:`t'}" _c
+		
+		local t = sef[`z',1]
+		local t : di %8.2f `t'
+		di _col(`=`dec2'+14') "{text:`t'}" _c
+			
+		local t = a2[`z',1]
+		local t : di %9.2f `t'
+		di _col(`=`dec2'+28') "{text:`t'}" _c
+		
+		local t = sei[`z',1]
+		local t : di %9.2f `t'
+		di _col(`=`dec2'+42') "{text:`t'}" _c
+		
+		local t = a3[`z',1]
+		local t : di %11.2f `t'
+				
+		if "`cfastand'" == "" & `z' == `y'{
+			di _col(`=`dec2'+52') "{text:`t'}" _c
+			local t = var[`i',1]
+			local t : di %11.2f `t'
+			di _col(`=`dec2'+66') "{text:`t'}"
+		}
+		else di _col(`=`dec2'+52') "{text:`t'}" 
+	}
+	di
+	local `i++' 
+	local y = `s'+1	
+}
+
+qui estat gof, stats(all)
+
+
+if "`cfasb'" != "" | "`vce'"=="sbentler"{
+	local chi2 = r(chi2sb_ms)
+	local p = r(psb_ms)
+	local ddl = r(df_ms)
+	local ratio = `chi2'/`ddl'
+	local rmsea = r(rmsea_sb)
+	*local lb = r(lb90_rmsea)
+	*local ub = r(ub90_rmsea)
+	local nfi = 1-(r(chi2sb_ms)/r(chi2sb_bs))
+	local rni = 1-(r(chi2sb_ms)-r(df_ms))/(r(chi2sb_bs)-r(df_bs))
+	local cfi = r(cfi_sb)
+	local ifi = (r(chi2sb_bs)-r(chi2sb_ms))/(r(chi2sb_bs)-r(df_ms))
+	local mci = exp(-0.5*((r(chi2sb_ms)-r(df_ms))/(e(N)-1)))
+	local srmr = r(srmr)
+}
+
+else {
+	local chi2 = r(chi2_ms)
+	local p = r(p_ms)
+	local ddl = r(df_ms)
+	local ratio = `chi2'/`ddl'
+	local rmsea = r(rmsea)
+	local lb = r(lb90_rmsea)
+	local ub = r(ub90_rmsea)
+	local nfi = 1-(r(chi2_ms)/r(chi2_bs))
+	local rni = 1-(r(chi2_ms)-r(df_ms))/(r(chi2_bs)-r(df_bs))
+	local cfi = r(cfi)
+	local ifi = (r(chi2_bs)-r(chi2_ms))/(r(chi2_bs)-r(df_ms))
+	local mci = exp(-0.5*((r(chi2_ms)-r(df_ms))/(e(N)-1)))
+	local srmr = r(srmr)
+}
+
+if "`cfanocovdim'" == "" {
+	di 
+	di "Covariances between dimensions:"
+	mat li c, nodotz noheader format(%4.2f)
+}
+
+di
+if "`cfasb'" != "" | "`vce'"=="sbentler" {
+	di "{bf:Goodness of fit (with Satorra-Bentler correction):}"
+}
+else {
+	di "{bf:Goodness of fit:}"
+}
+di
+
+
+
+if "${html}" != "" {
+
+di as result _col(4) "chi2" _c
+di as result _col(20) "df" _c
+di as result _col(28) "chi2/df" _c
+di as result _col(42) "RMSEA [90% CI]" _c
+di as result _col(64) "SRMR" _c
+di as result _col(74) "NFI" _c
+di as result _col(84) "RNI" 
+
+
+local t : di %7.2f `chi2'
+di "{text:`t'}" _c
+local t : di %3.0f `ddl'
+di _col(20) "{text:`t'}" _c
+local t : di %7.1f `ratio'
+di _col(29) "{text:`t'}" _c
+local t : di %5.3f `rmsea'
+local l : di %5.3f `lb'
+local u : di %5.3f `ub'
+di _col(40) "{text:`t' [`l' ; `u']}" _c
+local t : di %5.3f `srmr'
+di _col(63) "{text:`t'}" _c
+local t : di %5.3f `nfi'
+di _col(72) "{text:`t'}" _c
+local t : di %5.3f `rni'
+di _col(82) "{text:`t'}" 
+
+local p : di %5.3f `p'
+di "{text:(p-value = `p')}"
+di as result
+di as result _col(4) "CFI" _c 
+di as result _col(15) "IFI" _c
+di as result _col(26) "MCI"
+local t : di %5.3f `cfi'
+di _col(4) "{text:`t'}" _c
+local t : di %5.3f `ifi'
+di _col(15) "{text:`t'}" _c
+local t : di %5.3f `mci'
+di _col(26) "{text:`t'}" 
+di as result
+}
+else {
+di as result _col(4) "chi2" _c
+di as result _col(20) "df" _c
+di as result _col(28) "chi2/df" _c
+di as result _col(42) "RMSEA [90% CI]" _c
+di as result _col(64) "SRMR" _c
+di as result _col(74) "NFI" _c
+di as result _col(84) "RNI" _c
+di as result _col(94) "CFI" _c 
+di as result _col(104) "IFI" _c
+di as result _col(114) "MCI"
+
+local t : di %7.2f `chi2'
+di "{text:`t'}" _c
+local t : di %3.0f `ddl'
+di _col(20) "{text:`t'}" _c
+local t : di %7.1f `ratio'
+di _col(29) "{text:`t'}" _c
+local t : di %5.3f `rmsea'
+local l : di %5.3f `lb'
+local u : di %5.3f `ub'
+di _col(40) "{text:`t' [`l' ; `u']}" _c
+local t : di %5.3f `srmr'
+di _col(63) "{text:`t'}" _c
+local t : di %5.3f `nfi'
+di _col(72) "{text:`t'}" _c
+local t : di %5.3f `rni'
+di _col(82) "{text:`t'}" _c
+local t : di %5.3f `cfi'
+di _col(92) "{text:`t'}" _c
+local t : di %5.3f `ifi'
+di _col(102) "{text:`t'}" _c
+local t : di %5.3f `mci'
+di _col(112) "{text:`t'}" 
+local p : di %5.3f `p'
+di "{text:(p-value = `p')}"
+di as result
+
+}
+end
+
+
+/* repet */
+
+capture program drop repet
+program repet,rclass
+syntax varlist, PARTition(numlist integer >0) [t2(varlist) KAPpa ICKAPpa(integer 0)]
+preserve
+
+local nbvars : word count `varlist'
+
+if `ickappa' <= 0 {
+	local ickappa = ""
+}
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local P:word count `partition'
+
+if "$scores2" != "" {
+	local t:word count $scores2' 
+	if `P' != `t' {
+		di in red "The number of score names given in scores2() is different from the number of scores defined"
+		exit 119
+	}
+}
+
+if "`t2'" != "" { 
+
+	local i = 1
+	foreach s in $scorename {
+		local s`i' = abbrev("`s'",10)
+		local sc `sc' `s`i''
+		local `++i'
+	}
+
+	local i = 1
+	foreach v in `varlist' {
+		local var`i' = abbrev("`v'",10)
+		local `++i'
+	}
+
+	local maxit = 1
+	forvalues i=1/`nbvars' {
+		local len = length("`var`i''")
+		if `len' > `maxit' local maxit = `len'
+	}
+
+	local decit = `maxit' + 4
+	local colit = `decit'
+
+	di as result "{hline 105}"
+	di as result "{bf:Reproducibility}"
+	di as result "{hline 105}"
+	di
+
+	if "$scores2" == "" {
+		foreach sco in $scorename {
+				*local t = "`sco'bis"
+				tempname s
+				local scorename2 `scorename2' `s'
+		}
+		
+		qui calcscore `t2', scorename(`scorename2') partition(`partition') compscore(${compscore}) categories($categories)
+		
+	}
+	
+	else {
+		foreach sco in $scores2 {
+			local scorename2 `scorename2' `sco'
+		}
+	}
+	
+	local i = 1
+	foreach var in `varlist' {
+		tokenize `t2'
+		qui kap `var' ``i''
+		local k`i' = r(kappa)
+		if "`ickappa'" != "" {
+			qui kapci `var' ``i'', reps(`ickappa')
+			local lbk`i' = r(lb_bc)
+			local ubk`i' = r(ub_bc)
+		}
+		local `++i'
+	}
+
+	local i = 1
+	foreach s in $scorename {
+		tokenize `scorename2'
+		tempname score id temps
+		qui gen `id' = _n
+		qui gen `score'_1 = `s'
+		qui gen `score'_2 = ``i'' if ``i''!=.
+		qui reshape long `score'_, i(`id') j(`temps')
+		qui icc `score'_ `id'
+		local n`i' = r(N_target)
+		local icc`i' = r(icc_i)
+		local lb`i' = r(icc_i_lb)
+		local ub`i' = r(icc_i_ub)
+		qui sort `id'
+		qui duplicates drop `id', force
+		local `++i'
+	}
+
+	tokenize `sc'
+	local max = length("dimension")
+
+	forvalues j=1/`P' {
+		local len`j' = length("`s`j''")
+		if `len`j'' > `max' local max = `len`j''
+	}
+
+	local dec = `max' + 5
+
+	local i = 1
+	local j = 1
+	local y = 1
+	di "{bf:Dimension}" _c
+	di _col(`=`dec'+2') "{bf:n}" _c
+	local col = `dec'+6
+	di _col(`col') "{bf:Item}" _c
+	local col = `col'+`decit'
+
+	if "`kappa'" != "" {
+		di _col(`col') "{bf:Kappa}" _c
+		local col = `col'+10
+		if "`ickappa'" != "" {
+			di _col(`col') "{bf:95% CI for Kappa}" _c
+			local col = `col'+20	
+		}
+		
+	}
+
+	di _col(`=`col'+2') "{bf:ICC}" _c
+	local col = `col'+9
+	di _col(`col') "{bf:95% CI for ICC}"
+
+	local zz = 0
+	foreach var in `varlist' {
+		qui levelsof `var', local(levels)
+		local z : word count `levels'
+		if `z' > 2 local zz = 1
+	}
+
+	if "`kappa'" != "" & "`ickappa'" != "" & `zz' == 1 {
+		local col = `dec'+`decit'+16
+		di _col(`col') "{bf:(bootstrapped)}"
+	}
+
+
+	if "`ickappa'" != "" local h = `dec'+6+`decit'+10+8+21+12+1
+	else if "`kappa'" != "" local h = `dec'+6+`decit'+10+8+21+12-20
+	else local h = `dec'+6+`decit'+10+8+21+12-29
+	di "{hline `h'}"
+
+	local i = 1
+	foreach p in `partition' {
+		tokenize `sc'
+		di "{bf:``i''}" _c
+		di _col(`dec') "{text:`n`i''}" _c
+		if `j' == 1 local s = `p'
+		else local s = `s' +`p'
+		local col = `dec'+6
+		di _col(`col') "{text:`var`y''}" _c 
+		
+		if "`kappa'" != "" {
+			local k : di %5.2f `k`y''
+			local col = `col'+`decit'
+			di _col(`col') "{text:`k'}" _c
+			if "`ickappa'" != "" {
+				local lbk : di %5.2f `lbk`i''
+				local ubk : di %5.2f `ubk`i''
+				local col = `col'+11
+				di _col(`col') "{text:[`lbk' ; `ubk']}" _c
+				local col = `decit'+50
+			}
+			
+		else local col = `decit'+30	
+		}
+		else local col = `decit'+20
+			
+		local icc : di %5.2f `icc`i''
+		di _col(`col') "{text:`icc'}" _c
+		local lb : di %5.2f `lb`i''
+		local ub : di %5.2f `ub`i''
+		local col = `col'+8
+		di _col(`col')"{text:[`lb' ; `ub']}"
+		local w = `y'+1
+		
+		forvalues z = `w'/`s' {
+			local col = `dec'+6
+			di _col(`col') "{text:`var`z''}" _c
+			if "`kappa'" != "" {
+				local k : di %5.2f `k`z''
+				local col = `col'+`decit'
+				di _col(`col') "{text:`k'}" _c
+				if "`ickappa'" != "" {
+					local lbk : di %5.2f `lbk`z''
+					local ubk : di %5.2f `ubk`z''
+					local col = `col'+11
+					di _col(`col')"{text:[`lbk' ; `ubk']}"
+				}
+				else di
+				
+			}
+			else di
+		}
+		local `i++' 
+		local `j++' 
+		local y = `s'+1
+		di
+	}
+}
+
+else {
+	local i = 1
+	foreach s in $scorename {
+		tokenize $scores2
+		tempname score id temps
+		qui gen `id' = _n
+		qui gen `score'_1 = `s'
+		qui gen `score'_2 = ``i'' if ``i''!=.
+		qui reshape long `score'_, i(`id') j(`temps')
+		qui icc `score'_ `id'
+		local n`i' = r(N_target)
+		local icc`i' = r(icc_i)
+		local lb`i' = r(icc_i_lb)
+		local ub`i' = r(icc_i_ub)
+		qui sort `id'
+		qui duplicates drop `id', force
+		local `++i'
+	}
+
+	tokenize $scorename
+	local max = length("dimension")
+
+	local h = 1
+	foreach s in $scorename {
+		local s`h' = abbrev("`s'",10)
+		local sc `sc' `s`h''
+		local `++h'
+	}
+	
+	forvalues j=1/`P' {
+		local len`j' = length("`s`j''")
+		if `len`j'' > `max' local max = `len`j''
+	}
+
+	local dec = `max' + 5
+
+	local i = 1
+	local j = 1
+	local y = 1
+	
+	di as result "{hline 105}"
+	di as result "{bf:Reproducibility}"
+	di as result "{hline 105}"
+	di
+	
+	di "{bf:Dimension}" _c
+	local col = `dec'
+	di _col(`col') "{bf:n}" _c
+	
+
+	di _col(`=`col'+6') "{bf:ICC}" _c
+	local col = `col'+14
+	di _col(`col') "{bf:95% CI for ICC}"
+
+	di "{hline 50}"
+	
+	local i = 1
+	foreach p in `partition' {
+		tokenize $scorename
+		di "{bf:``i''}" _c
+		local n : di % 4.0f `n`i''
+		di _col(`=`dec'-3') "{text:`n'}" _c
+		if `j' == 1 local s = `p'
+		else local s = `s' +`p'
+		local col = `dec'+4
+		
+		local icc : di %5.2f `icc`i''
+		di _col(`col') "{text:`icc'}" _c
+		local lb : di %5.2f `lb`i''
+		local ub : di %5.2f `ub`i''
+		local col = `col'+9
+		di _col(`col')"{text:[`lb' ; `ub']}"
+		local w = `y'+1
+		
+		local `i++' 
+	}
+}
+
+end
+
+
+/* kgv */
+
+capture program drop kgv
+program kgv,rclass
+syntax varlist, categ(varlist) [KGVBoxplots KGVGroupboxplots]
+	
+foreach c in `categ' {
+	tempname j
+	capture encode `c', generate(`j')
+	capture confirm variable `j'
+	if _rc local j = "`c'"
+	local categ2 `categ2' `j' 
+}	
+
+local i = 1
+local j = 1	
+local k = 0
+local max = 0
+local a : word count `categ'
+local nb:word count `varlist'
+
+di as result "{hline 105}"
+di "{bf:Known-groups validity}"
+di as result "{hline 105}"
+di
+	
+foreach sco in `varlist' {
+	foreach cat in `categ2' {
+		local nblev = 0
+		local maxlen`j' = 0
+		
+		qui anova `sco' `cat'
+		local p`i'_`j' = Ftail(e(df_m), e(df_r), e(F))
+		qui kwallis `sco', by(`cat')
+		local p2`i'_`j' = chi2tail(r(df), r(chi2))
+		
+		
+		/*local inf30 = 0
+		qui tab `cat' if `sco'!=., matcell(x)
+		local r = r(r)
+		forvalues n = 1/`r' {
+			if x[`n',1]<48 {
+				local `++inf30'
+			}
+		}
+		if `inf30' > 0 {
+			//di in red "kw"
+			kwallis `sco', by(`cat')
+			local p2`i'_`j' = chi2tail(r(df), r(chi2))
+			anova `sco' `cat'
+			local p`i'_`j' = Ftail(e(df_m), e(df_r), e(F))
+			
+		}
+		else {
+			//di in red "aov"
+			anova `sco' `cat'
+			local p`i'_`j' = Ftail(e(df_m), e(df_r), e(F))
+		}*/
+		
+				
+		qui levelsof `cat', local(levels) 
+		local lbe : value label `cat'
+			
+		foreach l of local levels {
+			qui count if `sco' !=. & `cat' == `l'
+			local `++k'
+			local eff`i'_`j'_`k' = r(N)
+			
+			if "`lbe'" != "" {
+				local ll`j'_`k' : label `lbe' `l'
+				local len = length("`ll`j'_`k''")
+				if `len' > 10 {
+					local c = substr("`ll`j'_`k''",1,9)
+					local d = substr("`ll`j'_`k''",-1,1)
+					local ll`j'_`k' "`c'" "~" "`d'" 
+				}
+				local w = length("`ll`j'_`k''")
+				if `w' > `maxlen`j'' local maxlen`j' = `w'
+			}
+			else {
+				local ll`j'_`k' = `l'
+				local len = length("`ll`j'_`k''")
+				if `len' > 10 {
+					local c = substr("`ll`j'_`k''",1,9)
+					local d = substr("`ll`j'_`k''",-1,1)
+					local ll`j'_`k' "`c'" "~" "`d'" 
+				}
+				local w = length("`ll`j'_`k''")
+				if `w' > `maxlen`j'' local maxlen`j' = `w'
+			}
+			qui su `sco' if `cat' == `l'
+			local m`i'_`j'_`k' = r(mean)
+			local s`i'_`j'_`k' = r(sd)
+			local nblev = `nblev' + 1
+		}
+		if `nblev' > `max' local max = `nblev'
+		local `++j'
+		local k = 0
+	}
+	local `++i'
+	local j = 1
+}
+
+local i = 1
+foreach s in `varlist' {
+	local s`i' = abbrev("`s'",7)
+	local sc `sc' `s`i''
+	local `++i'
+}
+
+local maxs = 0
+forvalues j=1/`nb' {
+	local len`j' = length("`s`j''")
+	if `len`j'' > `maxs' local maxs = `len`j''
+}
+
+local i = 1
+local k = 0
+local j = 2
+
+foreach cat in `categ'{
+	local `++k'
+	tokenize `categ'
+	local c`k' = "``i'' ``j''"
+	local i = `i' + 2 
+	local j = `j' + 2 
+}
+
+
+local d = 1
+local f = 2
+forvalues h = 1/`a' {
+	if `f' > `a' local f = `f'-1
+	local j = 1
+	local col =  `maxs'+6
+	foreach cat in `c`h'' {
+		di _col(`col') "{bf:`cat'}" _c
+		local col = `col' + `maxlen`j'' + 5 + 40
+		local `++j'
+	}
+	di
+
+	local j = `d'
+	local col = `maxs'+6
+	foreach cat in `c`h'' {
+		di _col(`=`col'+`maxlen`j''+5') "{bf:       mean    }" _c
+		di "{bf:     sd    }" _c
+		di "{bf:p-value}" _c
+		//di "{bf:p-value (Kruskal-Wallis)}" _c
+		    
+		local col = `col' + `maxlen`j'' + 5 + 40
+		local `++j'
+	}
+	
+	local j = `d'
+	local col = `maxs'+6
+
+	di
+	di
+	local i = 1
+	local col = `maxs'+6
+
+	forvalues g = 1/`nb' {
+		
+		di "{bf:`s`g''}" _c
+		forvalues k = 1/`max' {
+			forvalues j = `d'/`f' {
+			
+				di _col(`col') "{bf:`ll`j'_`k''} " _c
+				if "`eff`i'_`j'_`k''" != "" di as text "(n=`eff`i'_`j'_`k'')" _c
+				local m : di %6.2f `m`i'_`j'_`k''
+				di _col(`=`col'+`maxlen`j''+10') "{text:`m'}  " _c
+					
+				local s : di %8.2f `s`i'_`j'_`k''
+				di "{text: `s'}  " _c
+					
+				if `k' == 1 {
+					local p : di %8.3f `p`i'_`j''
+					local p2 : di %4.3f `p2`i'_`j''
+					di _col(`=`col'+31') "{text:`p'}  " _c
+					di _col(`=`col'+35') "{text:(KW: `p2')}  " _c
+				}
+				local col = `col' + `maxlen`j'' + 5 + 40
+			}
+			di
+			local col = `maxs'+6
+		
+		}
+		di 
+		
+	local `++i'
+	
+	}
+	local d = `d'+2
+	local f = `f'+2
+	if `d' > `a' continue, break
+	di
+}
+
+if "`kgvboxplots'" != "" {
+	local html = "${html}"
+	if "`html'" != "" {
+		di "
" + di "
" + if "`kgvgroupboxplots'" != "" { + local cc = 1 + foreach c in `categ' { + local k = 1 + foreach s in `varlist' { + local pp = round(`p`k'_`cc'',0.001) + //graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c'") nodraw + + + qui local saving "saving(`c(tmpdir)'/`html'_kgv`s',replace) nodraw" + qui graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c' (p=`pp')") `saving' + qui graph use `c(tmpdir)'/`html'_kgv`s'.gph + qui graph export `c(tmpdir)'/`html'_kgv`s'.png, replace + + + local g `g' `s'_`c' + local k = `k'+1 + } + local cc = `cc'+1 + } + + qui local saving "saving(`c(tmpdir)'/`html'_kgv,replace) nodraw" + qui gr combine `g', name(kgv,replace) `saving' + qui graph use `c(tmpdir)'/`html'_kgv.gph + qui graph export `c(tmpdir)'/`html'_kgv.png, replace + //di " _char(34) " + + } + else { + local cc = 1 + foreach c in `categ' { + local k = 1 + foreach s in `varlist' { + local pp = round(`p`k'_`cc'',0.001) + //graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c'") + + qui local saving "saving(`c(tmpdir)'/`html'_kgv`s',replace) nodraw" + qui graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c' (p=`pp')") `saving' + qui graph use `c(tmpdir)'/`html'_kgv`s'.gph + qui graph export `c(tmpdir)'/`html'_kgv`s'.png, replace + //di " _char(34) " + + local g `g' `s'_`c' + local k = `k'+1 + } + local cc = `cc'+1 + } + } + di "
" + di "
"
+	
+	}
+	else {
+		if "`kgvgroupboxplots'" != "" {
+			local cc = 1
+			foreach c in `categ' {
+				local k = 1
+				foreach s in `varlist' {
+					local pp = round(`p`k'_`cc'',0.001)
+					graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c' (p=`pp')") nodraw
+					local g `g' `s'_`c' 
+					local k = `k'+1
+				}
+				local cc = `cc'+1
+			}
+			gr combine `g', name(Known_groups_validity,replace)
+			if ("$filessave"!="") qui graph export ${dirsave}/Known_groups_validity.png, replace
+
+		}
+		else {
+			local cc = 1
+			foreach c in `categ' {
+				local k = 1
+				foreach s in `varlist' {
+					local pp = round(`p`k'_`cc'',0.001)
+					graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c' (p=`pp')")
+					if ("$filessave"!="") qui graph export ${dirsave}/Known_groups_validity_`c'_`s'.png, replace
+					local g `g' `s'_`c' 
+					local k = `k'+1
+				}
+				local cc = `cc'+1
+			}
+		}
+	}
+}
+
+end
+
+
+/* conc */
+
+capture program drop conc
+program conc,rclass
+syntax varlist, comp(varlist) [tconc(real 0.4)]
+
+di as result "{hline 105}"
+di "{bf:Concurrent validity}"
+di as result "{hline 105}"
+di
+
+local n : word count `varlist'
+local p : word count `comp'
+
+matrix m = J(`n',`p',.)
+matrix rownames m = `varlist'
+matrix colnames m = `comp'
+local r = 1
+
+foreach i in `varlist' {
+	local c = 1
+	foreach j in `comp' {
+		qui corr `i' `j'
+		mat e = r(C)
+		local f = e[2,1]
+		mat m[`r',`c'] = `f' 
+		local `++c'
+	}
+	local `++r'
+}
+
+tokenize `varlist'
+local maxv = length("`1'")
+forvalues i=1/`n' {
+	local lenv = length("``i''")
+	if `lenv' > `maxv' local maxv = `lenv'
+}
+
+local decv = `maxv'+6
+
+tokenize `comp'
+local maxc = length("`1'")
+forvalues i=1/`p' {
+	local lenc = length("``i''")
+	if `lenc' > `maxc' local maxc = `lenc'
+}
+
+local decc = `maxc'+4
+
+local col = `decv'
+foreach c in `comp' {
+	di as result _col(`col') "`c'" _c
+	local col = `col'+`decc'
+}
+di
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+forvalues i=1/`n' {
+	di as result "`var`i''" _c
+	local col = `decv'
+	forvalues j=1/`p' {
+		local t = m[`i',`j']
+		if `t' > `tconc' | `t' < -`tconc' {
+			di as result _col(`=`col'-1') %5.2f `t' _c
+		}
+		else di as text _col(`=`col'-1') %5.2f `t' _c
+		local col = `col'+`decc'
+	}
+	di
+}
+
+capture restore, not
+end
+
diff --git a/Modules/ado/personal/v/validscale.ado (old) b/Modules/ado/personal/v/validscale.ado (old)
new file mode 100644
index 0000000..12d9b42
--- /dev/null
+++ b/Modules/ado/personal/v/validscale.ado (old)	
@@ -0,0 +1,2979 @@
+*! Bastien Perrot, Jean-Benoit Hardouin, Emmanuelle Anthoine
+*************************************************************************************************************
+* Stata program : validscale
+* Assess validity and reliability of a multidimensional measurement scale using CTT methods
+
+* Required modules :
+* delta
+* loevh
+* kapci
+* mi_twoway
+* detect
+* imputeitems
+* lstrfun
+
+* Version 1.1 (September 3, 2018)  /*updated the dialog box for Stata 15, fixed a bug with cfarmsea, cfacfi and cfacovs, fixed a bug with descitems when the first observation contained missing data*/
+* Version 1.2 August 13, 2019 /* filessave and dirsave options */
+
+
+*************************************************************************************************************
+
+program define validscale, rclass
+version 12.0
+syntax varlist [if], PARTition(numlist integer >0) [HTML(string) CATegories(numlist) SCOREName(string) scores(varlist) IMPute(string) NORound COMPScore(string) DESCitems GRAPHs cfa CFAMethod(string) cfasb CFAStand CFACov(string) CFARmsea(real -999) CFACFi(real -999) CFAOR CFANOCOVDim CONVdiv TCONVdiv(real 0.4) CONVDIVBoxplots Alpha(real 0.7) Delta(real 0.9) h(real 0.3) HJmin(real 0.3) REPet(varlist) scores2(varlist) KAPpa ICKAPpa(integer 0) kgv(varlist) KGVBoxplots KGVGroupboxplots conc(varlist) tconc(real 0.4) DIRsave(string) FILESsave]
+preserve
+
+
+foreach c in delta loevh mi_twoway detect imputeitems lstrfun{
+	capture which "`c'"
+	if _rc qui ssc install "`c'"
+}
+capture which kapci
+if _rc qui net install st0076, from(http://www.stata-journal.com/software/sj4-4/)
+
+if "`if'"!="" {
+   qui keep `if'
+}
+
+global html
+global dirsave
+global filessave
+
+if "`filessave'" != "" {
+	global filessave = "`filessave'"
+}
+
+if "`dirsave'" != "" {
+	global dirsave = "`dirsave'"
+}
+else {
+	global dirsave "`c(pwd)'"
+}
+
+if "`html'" != "" {
+   global html = "`html'"
+   set scheme sj
+   local htmlregion  "graphregion(fcolor(white) ifcolor(white))"
+   local xsize=6
+   local ysize=4
+   di in gr ""
+   di "
" + di "
"
+}   
+
+if "`categories'" == "" {
+	foreach v in `varlist' {
+		tempvar min max
+		egen `min' = min(`v')
+		egen `max' = max(`v')
+		local mi = `min' 
+		local ma = `max'
+		local m `mi' `ma'
+		local categories `categories' `m'
+	}
+}
+
+global categories = "`categories'"
+global compscore = "`compscore'"
+if "$compscore" == "" global compscore = "mean"
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+
+local nbvars : word count `varlist' 
+
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit 119
+}
+
+
+if "`repet'" != "" {
+	local b:word count `repet'
+	if `nbvars' != `b' {
+		di in red "The number of items in varlist is different from the number of items in repet"
+		exit 119
+	}
+}
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+local P:word count `partition'
+local S:word count `scorename'
+
+if "`scores'" != "" & "`scorename'" != "" {
+	di in red "scorenames() and scores() cannot be used together"
+	exit 119
+}  
+
+if "`scorename'" != "" {
+	if `P'!=`S' {
+		di in red "The number of score names given is different from the number of dimensions in the partition option" 
+		exit 119
+	}
+	foreach sco in `scorename' {
+		capture confirm variable `sco', exact
+		if !_rc {
+			di in red "`sco' already defined. You must choose names that do not already exist or use the scores() option if the scores are already defined."
+			exit 119
+	    }
+		tokenize `scorename'
+		local g = 0
+		forvalues i = 1/`S' {
+			if "`sco'" == "``i''" {
+				local `++g'
+			}
+		}
+		if `g' > 1 {
+			di in red "2 or more dimensions have the same name"
+			exit 119
+		}
+	}
+		calcscore `varlist', scorename(`scorename') partition(`partition') compscore(`compscore') categories(`categories')
+		global exist = 0
+		global scorename = "`scorename'"
+}
+
+else if "`scorename'" == "" & "`scores'" == ""{
+
+	local name
+	local nname
+	
+	forvalues i = 1/`P' {
+	
+		local name "Dim`i'"
+		local nname `nname' `name'
+	}
+	
+	local scorename = "`nname'"
+	global scorename = "`nname'"
+	calcscore `varlist', scorename(`scorename') partition(`partition') compscore(`compscore') categories(`categories')
+	global exist = 0
+}
+
+else if "`scores'" != "" {
+	local P:word count `partition'
+	local S2:word count `scores'
+	if `P'!=`S2' {
+		di in red "The number of score names given is different from the number of dimensions in the partition option" 
+		exit 119
+	}
+	else {
+		global scorename = "`scores'"
+		local scorename = "`scores'"
+		global exist = 1
+		
+	}
+	
+}
+
+local nbm : word count $categories
+if `nbm' !=2 &`nbm' !=`P'*2 &`nbm' !=`nbvars'*2 { 
+	di in red "option categories() misspecified. You must enter either 2 or `=`nbvars'*2' or `=`P'*2' elements"
+	exit 119
+}
+
+if `nbm' == 2{
+	tokenize $categories
+	foreach v in `varlist' {
+		tempvar min
+		tempvar max
+		egen `min' = min(`v')
+		egen `max' = max(`v')
+		if `min' < `1' {
+			di in red "error in option categories() : some responses have smaller values than the minimum value in categories()"
+			exit 119
+		} 
+		if `max' > `2' {
+			di in red "error in option categories() : some responses have greater values than the maximum value in categories()"
+			exit 119
+		} 
+	}
+}
+
+if `nbm' == `nbvars'*2 {
+	local i = 1
+	foreach v in `varlist' {
+		tempvar min max
+		egen `min' = min(`v')
+		egen `max' = max(`v')
+		local mi = `min' 
+		local ma = `max'
+		tokenize $categories
+		if `mi' < ``i'' {
+			di in red "error in option categories() : some responses have values less than the minimum value specified for the variable in categories()"
+			exit 119
+		}
+	local `++i'
+	tokenize $categories
+		if `ma' > ``i'' {
+			di in red "error in option categories() : some responses have values greater than the maximum value specified for the variable in categories()"
+			exit 119
+		}
+	local `++i'
+	}
+} 
+
+if `nbm' == `P'*2 {
+	local i = 1
+	local y = 1
+	
+	foreach x in `partition' {
+		//local `i++' 
+		if `i' == 1 local s = `x'
+		else local s = `s' +`x'
+		forvalues w = `y'/`s' {
+			tokenize $categories
+			tempvar min max
+			egen `min' = min(`var`w'')
+			egen `max' = max(`var`w'')
+			local mi = `min' 
+			local ma = `max'
+			if `mi' < ``i'' {
+				di in red "error in option categories() : some responses have values less than the minimum value specified"
+				exit 119
+			}
+			local j = `i'+1
+			tokenize $categories
+			if `ma' > ``j'' {
+				di in red "error in option categories() : some responses have values greater than the maximum value specified"
+				exit 119
+			}
+		}
+		local i = `i'+2
+		local y = `s'+1
+	}
+}
+
+if "`cfa'" != "" {
+	if "`cfacov'" != "" {
+		if !strpos("`cfacov'", "*") { 
+			di "error in cfacov() option : you must enter covariances between errors as follows: item3*item5 item7*item8 ...  "
+		exit 119
+	}
+		local v = subinstr("`cfacov'","*"," ",.)
+		foreach var in `v' {
+			capture confirm variable `var'
+			if _rc {
+				di in red "error in cfacov() option : `var' is not a variable from the dataset"
+				exit 119
+			}
+		}
+	}
+	
+}
+
+if "`kgv'" !="" {
+	foreach k in `kgv' {
+		capture confirm variable `k'
+		if _rc!=0 {
+			di in red "`k' does not exist" 
+			exit 119
+		}
+    }
+}
+
+if "`conc'" !="" {
+	foreach c in `conc' {
+		capture confirm variable `c'
+		if _rc!=0 {
+			di in red "`c' does not exist" 
+			exit 119
+		}
+    }
+}
+
+di as result "Items used to compute the scores"
+di
+
+local i = 1
+local j = 1
+local y = 1
+foreach p in `partition' {
+	tokenize `scorename'
+	di "{bf:``i''} : " _c
+	
+	if `j' == 1 local s = `p'
+	else local s = `s' +`p'
+	forvalues z = `y'/`s' {
+		di "{text:`var`z'' }" _c
+	}
+	local `i++' 
+	local `j++' 
+	local y = `s'+1
+	di
+}
+
+di
+di as result "Number of observations: " _c
+di as text _N
+
+qui destring _all, replace
+di
+
+if "`descitems'" != "" {
+	di as result "{hline 105}"
+	di "Description of items"
+	di as result "{hline 105}"
+	di
+	descitems `varlist', partition(`partition')
+	di
+}
+
+
+if "`graphs'" != "" {
+	graphs `varlist', partition(`partition')
+}						
+
+
+if "`repet'" != "" {
+	if "`descitems'" != "" {
+		di as result "{hline 105}"
+		di "Description of items (time 2)"
+		di as result "{hline 105}"
+		di
+		descitems `repet', partition(`partition')
+		di
+	}
+}
+
+if "`impute'" != "" {
+	if "`impute'" != "pms" & "`impute'" !="mi" {
+		di in red "option impute() incorrectly specified. You must specify {hi:pms} or {hi:mi}."
+		error 100
+	}
+	if "`impute'" == "pms" {
+		pms `varlist', partition(`partition') `noround'
+		if "`descitems'" != "" {
+			di as result "{hline 105}"
+			di "Description of items after missing data handling (PMS imputation)"
+			di as result "{hline 105}"
+			di
+			descitems `varlist', partition(`partition')
+			di
+		}
+		if "`repet'" != "" {
+			pms `repet', partition(`partition') `noround'
+			if "`descitems'" != "" {
+				di as result "{hline 105}"
+				di "Description of items after missing data handling (time 2)"
+				di as result "{hline 105}"
+				di
+				descitems `repet', partition(`partition')
+				di
+			}
+		}
+	}
+	if "`impute'" == "mi" {
+		mitw `varlist', partition(`partition') `noround' 
+		if "`descitems'" != "" {
+			di as result "{hline 105}"
+			di "Description of items after missing data handling (mi two-way imputation)"
+			di as result "{hline 105}"
+			di
+			descitems `varlist', partition(`partition')
+			di
+		}
+		if "`repet'" != "" {
+			mitw `repet', partition(`partition') `noround'
+			if "`descitems'" != "" {
+				di as result "{hline 105}"
+				di "Description of items after missing data handling (time 2)"
+				di as result "{hline 105}"
+				di
+				descitems `repet', partition(`partition')
+				di
+			}
+		}
+	}
+}  
+
+rel `varlist', scorename(`scorename') partition(`partition') alpha(`alpha') delta(`delta') h(`h') hjmin(`hjmin') categories(`categories')
+di
+
+if "`convdiv'" != "" {
+	convdiv `varlist', partition(`partition') tconvdiv(`tconvdiv') `convdivboxplots'
+	di
+}
+
+if "`cfa'" != "" {
+	cfa `varlist', partition(`partition') cfamethod(`cfamethod') `cfasb' `cfastand' cfacov(`cfacov') cfarmsea(`cfarmsea') cfacfi(`cfacfi') `cfaor' `cfanocovdim'
+	di
+}
+
+if "`repet'" != "" | "`scores2'" != "" {
+	global scores2 = "`scores2'"
+	repet `varlist', t2(`repet') partition(`partition') `kappa' ickappa(`ickappa')
+	di
+}
+
+if "`kgv'" != "" {
+	kgv `scorename', categ(`kgv') `kgvboxplots' `kgvgroupboxplots'
+	di
+}
+
+if "`conc'" != "" {
+	conc `scorename', comp(`conc') tconc(`tconc')
+}
+
+
+//capture restore, not
+end
+
+
+/* pms */
+
+capture program drop pms
+program pms
+syntax varlist, PARTition(numlist integer >0) [NORound]
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit
+}
+
+local i = 1
+local y = 1
+
+tokenize `varlist'
+foreach x in `partition' {
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' ``w'' 
+	}
+	
+	local n : word count `liste' 
+	if mod(`n',2)!=0 local max = floor(`n'/2)
+	else local max = `n'/2-1
+	
+	if "`noround'" != "" {
+		qui imputeitems `liste', method(pms) max(`max') noround 
+		foreach var of varlist `liste' {
+			qui replace `var' = imp`var'
+			qui drop imp`var'
+		}
+	}
+	else {
+		qui imputeitems `liste', method(pms) max(`max')
+		foreach var of varlist `liste' {
+			qui replace `var' = imp`var'
+			qui drop imp`var'
+		}
+	}
+	
+	local `i++' 
+	local y = `s'+1
+}
+
+end
+
+
+/* mitw */
+
+capture program drop mitw
+program mitw
+syntax varlist, PARTition(numlist integer >0) [NORound]
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit
+}
+
+local i = 1
+local y = 1
+
+
+foreach x in `partition' {
+	tokenize `varlist'
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' ``w'' 
+	}
+		
+	qui mi_twoway `liste', scorename(scoretmp) add(1) style(wide) clear  
+		
+	foreach var of varlist `liste' {
+		qui replace `var' = _1_`var'
+		if "`noround'" == "" {
+			qui replace `var' = round(`var')
+		}
+		/*if `var' > `maxm' {
+			qui replace `var' = `maxm'
+		}
+		if `var' < `minm' {
+			qui replace `var' = `minm'
+		}*/
+		qui drop _1_`var'
+		capture drop scoretmp
+		capture drop _1_scoretmp
+	}
+		
+	local `i++' 
+	local y = `s'+1
+}
+
+//capture drop _mi_miss
+qui mi unset
+end
+
+
+/*  calcscore */
+
+capture program drop calcscore
+program calcscore,rclass
+syntax varlist, PARTition(numlist integer >0) [categories(numlist) COMPscore(string) SCOrename(string)]
+
+local P:word count `partition'
+local S:word count `scorename'
+		
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit
+}
+
+if "`scorename'" != "" {
+	if `P'!=`S' {
+		di in red "The number of score names given is different from the number of dimensions in the partition option" 
+		exit 119
+	}
+}
+
+local i = 1
+local y = 1
+foreach x in `partition' {
+	tokenize `varlist'
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' ``w'' 
+	}
+	
+	tempvar nonmiss
+	qui egen `nonmiss' = rownonmiss(`liste')
+		
+	tokenize `scorename'
+	local sc = "``i''"
+
+	if "`compscore'" == "" local compscore = "mean"
+
+	if "`compscore'" != "mean" & "`compscore'" != "sum" & "`compscore'" != "stand" {
+		di in red "option compscore incorrectly specified (choose among mean, sum and stand)"
+		error 198
+	}
+	
+	if "`compscore'" == "sum" {
+		qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2
+		qui replace `sc' = `sc'*`x'
+		
+	}
+	
+	else if "`compscore'" == "stand" {
+	
+		local nbm:word count `categories'
+		
+		local nbl:word count `liste'
+		tokenize `categories'
+	
+		if `nbm' == 2 {
+			local min = `1'*`nbl'
+			local max = `2'*`nbl'
+		}
+	
+		else if `nbm' == `P'*2 {
+			local min = ``b''*`nbl'
+			local max = ``=`b'+1''*`nbl'
+			
+		}
+	
+		else if `nbm' == `nbvars'*2 {
+			if `y'==1 local yy = 1
+			else local yy = `y'*2-1
+			local bb = `yy'
+			local min = 0
+			local max = 0
+		
+			forvalues bb = `yy'(2)`=`s'*2' {
+				local tpmin = ``bb''
+				local tpmax = ``=`bb'+1''
+				local min = `min'+`tpmin'
+				local max = `max'+`tpmax'
+			}
+		}
+			
+		else {
+			di in red "option categories() misspecified. You must enter either 2 or `=`nbvars'*2' or `=`P'*2' elements"
+			exit 119
+		}
+				
+		qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2
+		qui replace `sc' = `sc'*`nonmiss'
+		qui replace `sc' = (`sc'-`min')/(`max'-`min')*100
+	}
+	
+	else {
+		qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2
+	}
+
+local `i++' 
+local y = `s'+1
+}
+
+end
+
+
+
+/* rel */
+
+capture program drop rel
+program rel,rclass
+syntax varlist, PARTition(numlist integer >0) [CATegories(numlist) SCOrename(string) Alpha(real 0.7) Delta(real 0.9) h(real 0.3) HJmin(real 0.3)]
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit
+}
+
+local P:word count `partition'
+if "`scorename'" !="" {
+	local S:word count `scorename'
+	if `P'!=`S' {
+		di in red "The number of score names given is different from the number of dimensions in the partition option" 
+		exit
+	}
+}
+di as result "{hline 105}"
+di "{bf:Reliability}" 
+di as result "{hline 105}"
+di
+
+local y = 1
+local nbitems = 0
+matrix aa = J(`P',4,.)
+
+foreach z in `partition' {
+	local nbitems = `nbitems' + `z'
+}
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+matrix d = J(`nbitems',2,.)
+
+local i = 1
+local b = 1
+foreach x in `partition' {
+	
+	tokenize `scorename'
+	
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' `var`w'' 
+	}
+	
+	capture alpha `liste', asi item std
+	local al`i' = r(alpha)
+			
+	capture qui loevh `liste', pairwise 
+	local h`i' = r(loevH)
+	matrix c = r(loevHj)	
+	matrix ct = c'
+		
+	
+	local lister = ""
+	forvalues w = `y'/`s' {
+		tempvar z
+		qui gen `z' = round(`var`w'')
+		local lister `lister' `z' 
+	}
+	
+	tempvar nbmiss
+	local nbl : word count `lister'
+	egen `nbmiss' = rowmiss(`lister')
+	qui count if `nbmiss'<`nbl'
+	local n`i' = r(N)
+	
+	
+	// delta
+	
+	if ${exist} == 0 & "$compscore" == "sum" {
+	
+		local nbm:word count `categories'
+		tokenize `categories'
+		
+		if `nbm' == 2 {
+			local min = `1'*`nbl'
+			local max = `2'*`nbl'
+		}
+		
+		else if `nbm' == `P'*2 {
+			local min = ``b''*`nbl'
+			local max = ``=`b'+1''*`nbl'
+		}
+		
+		
+		else if `nbm' == `nbvars'*2 {
+			if `y'==1 local yy = 1
+			else local yy = `y'*2-1
+			local bb = `yy'
+			local min = 0
+			local max = 0
+			
+			forvalues bb = `yy'(2)`=`s'*2' {
+				local tpmin = ``bb''
+				local tpmax = ``=`bb'+1''
+				local min = `min'+`tpmin'
+				local max = `max'+`tpmax'
+				
+			}
+		}
+		
+		else {
+			di in red "option categories() misspecified. You must enter either 2 or `=`nbvars'*2' or `=`P'*2' elements"
+			exit 119
+		}
+		
+		capture delta `lister', min(`min') max(`max')
+		local delt`i' = r(delta)
+	
+	}
+	
+	else local delt`i' = .
+		
+	local k = 0
+	forvalues j = `y'/`s' {
+		local k = `k'+1
+		matrix d[`j',1] = ct[`k',1]
+		matrix d[`j',2] = `i'
+	}
+	
+	matrix aa [`i',1] = `al`i''
+	matrix aa [`i',2] = `delt`i''
+	matrix aa [`i',3] = `h`i''
+	
+	local `i++' 
+	local y = `s'+1
+	
+	local b = `b'+2
+}
+
+matrix rownames d = `varlist'
+local i = 1
+local y = 1
+
+foreach x in `partition' {
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	matrix C = d[`y'..`s',1.]
+	local min`i' = C[1,1]
+	local n : rownames C
+	tokenize `n'
+	local t`i' = "`1'"
+	forvalues j = 1/`x' {
+		local t = "``j''"
+		if C[`j',1] <= `min`i'' {
+			local min`i' = C[`j',1] 
+			local t`i' = "``j''"
+			local itmin`i' = "``j''"
+		}
+	}
+	matrix aa [`i',4] = `min`i''
+	local `i++' 
+	local y = `s'+1
+}
+
+matrix colnames aa = "alpha" "delta" "H" "Hj_min"
+
+if "`scorename'"=="" {
+	local i = 1
+	local y = 1
+	local name
+	local nname
+	forvalues i = 1/`P' {
+		local name "Dim`i'"
+		local nname `nname' `name'
+	}
+local scorename = "`nname'"
+}	
+
+local maxlen = 0
+foreach sco in `scorename' {
+	local w = length("`sco'")
+	if `w' > `maxlen' local maxlen = `w'
+}
+
+local i = 1
+local j = 1
+local y = 1
+local col = `maxlen'+8
+
+di _col(`col') "{bf:n}" _c
+local col = `col'+6
+di _col(`col') "{bf:alpha}" _c
+local col = `col'+10
+di _col(`col') "{bf:delta}" _c
+local col = `col'+14
+di _col(`col') "{bf:H}" _c
+local col = `col'+5
+di _col(`col') "{bf:Hj_min}"
+
+foreach s in `scorename' {
+	di in blue "{bf:`s'}" _c
+	local col = `maxlen'+3
+	
+	local n : di %6.0f `n`i''
+	
+	di in blue _col(`col') "{text:`n'}" _c
+	local col = `col'+10
+	
+	local a : di %6.2f `al`i''
+	if `a' < `alpha' {
+		di _col(`col') "{error:`a'} " _c
+	}
+	else di _col(`col') "{text:`a'}" _c
+	
+	local col = `col'+10
+	local d : di %6.2f `delt`i''
+	if `d' < `delta' {
+		di _col(`col') "{error:`d'} " _c
+	}
+	else di _col(`col') "{text:`d'}" _c
+	
+	local col = `col'+10
+	local ht : di %6.2f `h`i''
+	if `ht' < `h' {
+		di _col(`col') "{error:`ht'} " _c
+	}
+	else di _col(`col') "{text:`ht'}" _c
+	
+	local col = `col'+8
+	local m : di %8.2f `min`i''
+	if `m' < `hjmin' {
+		di _col(`col') "{error:`m'} " _c
+		di "{text:(item `itmin`i'')}" _c
+	}
+	else di _col(`col') "{text:`m'}" _c
+	
+	di
+	local `++i'
+}
+
+end
+
+/* descitems */
+
+capture program drop descitems
+program descitems
+syntax varlist, PARTition(numlist integer >0)
+local i = 1
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+
+local nbvars : word count `varlist'
+
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit 119
+}
+
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+foreach var in `varlist' {
+	qui replace `var' = round(`var')
+}
+
+local lev = ""
+foreach var in `varlist' {
+	qui levelsof `var', local(levels)
+	foreach l in `levels' {
+		if strpos("`lev'","`l'") == 0 {
+		local lev `lev' `l'	
+		}
+	}
+}
+
+_qsort_index `lev'
+local lev = r(slist1)
+
+local i = 1
+matrix d = J(`nbvars',4,.)
+
+foreach var in `varlist'{
+	qui count if missing(`var')
+	local ct=r(N)
+	
+	local tx`i'=`ct'/_N
+	matrix d[`i',1] = `tx`i''
+	local `i++'
+}
+
+matrix rownames d = `varlist'
+matrix colnames d = "missing" "alpha" "Hj" 
+
+local i = 1
+local y = 1
+foreach x in `partition' {
+	
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' `var`w'' 
+	}
+	
+	qui capture alpha `liste', asi item std
+	
+	mat a = r(Alpha)
+	mat at = a'
+	
+	qui capture loevh `liste', pairwise pair
+	matrix e = r(loevHj)	
+	matrix et = e'
+	
+	//matrix ns = r(nbHjkNS)	
+	//matrix nst = ns'
+	
+	
+	matrix pval = r(pvalHjk)
+	forvalues c = 1/`x' {
+		forvalues r = 1/`x' {
+			if pval[`r',`c']>0.05 {
+				local ns`r' = `ns`r''+1
+			}
+			else local ns`r' = `ns`r''+0
+		}
+	}
+	
+	
+	foreach z in `partition' {
+		local nbitems = `nbitems' + `z'
+	}
+	matrix nst = J(`nbitems',1,0)
+	local r = 1
+	forvalues j = `y'/`s'{
+		matrix nst[`j',1]=`ns`r''
+		local `r++'
+	}
+		
+	
+	local k = 0
+	forvalues j = `y'/`s' {
+		local k = `k'+1
+		matrix d[`j',2] = at[`k',1]
+		matrix d[`j',3] = et[`k',1]
+		matrix d[`j',4] = `ns`k''
+		
+	}
+	local `i++' 
+	local y = `s'+1	
+	
+	forvalues j = 1/21{
+		local ns`j' = 0
+	}
+}
+
+
+
+local i = 1
+foreach v in `varlist' {
+	local var`i' = abbrev("`v'",8)
+	local `++i'
+}
+
+local dec = 10
+local col = `dec'
+
+
+local minm = 999
+local maxm = -999
+foreach mod in $categories {
+	if `mod' < `minm' local minm = `mod'
+	if `mod' > `maxm' local maxm = `mod'
+}
+
+local b = `maxm'-`minm'+1
+
+local i = 1
+local j = 1
+local y = 1
+
+di in blue _col(`dec') "{bf:Missing}" _c
+local col = `col'+11
+di in blue _col(`=`col'+2') "{bf:N}" _c
+
+local col = `col'+9
+di _col(`col') "{bf:Response categories}" _c
+local col = `dec'+18+8*`b'
+di _col(`col') "{bf:Alpha}" _c
+local col = `col'+9
+di _col(`col') "{bf:Loevinger}" _c  
+local col = `col'+12
+di _col(`col') "{bf:Number of}" 
+
+local col = `dec'-1
+di _col(`col') "{bf:data rate}" _c
+local col = `dec'+18
+
+forvalues m = `minm'/`maxm' {
+	di _col(`=`col'+2') "`m'" _c
+	local col = `col'+8
+}
+
+di as result _col(`col') "- item" _c
+local col = `col'+10
+di as result _col(`col') "Hj coeff" _c 
+local col = `col'+12
+di as result _col(`col') "NS Hjk"  
+
+local ch = `dec'+18+8*`b'+29
+di "{hline `ch'}"
+
+local i = 1 
+foreach x in `varlist' {
+	local varo`i' = "`x'"
+	local `++i'
+}
+
+local y = 1
+foreach p in `partition' {
+	
+	if `j' == 1 local s = `p'
+	else local s = `s' +`p'
+	
+	forvalues z = `y'/`s' { 
+		local col = `dec'
+		di "{bf:`var`z''}" _c
+		local t = d[`z',1]
+		local t : di %8.2f `t'*100 
+		di _col(`col') "{text:`t'%}" _c
+		qui count if missing(`varo`z'')
+		local m = r(N)
+		local N = _N-`m'
+		local N : di %4.0f `N'
+		local col = `col'+10
+		di _col(`col') "{text:`N'}" _c
+		
+		local col = `col'+8
+		forvalues m = `minm'/`maxm' {
+			qui count if round(`varo`z'') == `m'
+			local n = r(N)
+			if `m' == `maxm' & round(`varo`z'')>`maxm' & `varo`z''!=.{
+				local n = `n' + 1
+			}
+			if `m' == `minm' & round(`varo`z'')<`minm' & `varo`z''!=.{
+				local n = `n' + 1
+			}
+			qui count if `varo`z'' != . 
+			local d = r(N)
+			local e = `n'/`d'
+			local e : di %4.2f `e'*100
+			if `e' != 0 di _col(`=`col'-1')"{text:`e'%}" _c
+			else di _col(`=`col'-1')"{text:   -}" _c
+			local col = `col'+8
+		}
+		local a = d[`z',2]
+		local a : di %4.2f `a'
+		di _col(`=`col'+1') "{text:`a'}" _c
+		local h = d[`z',3]
+		local h : di %5.2f `h'
+		local col = `col'+10
+		di _col(`=`col'+3') "{text:`h'}" _c
+		local ns = d[`z',4]
+		local ns : di %2.0f `ns'
+		local col = `col'+11
+		di _col(`=`col'+7') "{text:`ns'}" 
+			
+	}
+	local `i++' 
+	local `j++' 
+	local y = `s'+1
+	di "{dup `ch':-}" 
+}
+end
+
+
+capture program drop graphs
+program graphs
+syntax varlist, PARTition(numlist integer >0)
+
+local P:word count `partition'
+local html = "${html}"
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+if "$compscore" == "stand" local w = 10
+if "$compscore" == "sum" local b = 10
+if "$compscore" == "mean" local w = 0.5
+
+
+
+
+if "`html'"!="" {
+	//set graphics off
+	foreach s in $scorename {
+		qui local saving "saving(`c(tmpdir)'/`html'_`s',replace) nodraw"
+		qui hist `s', name(`s',replace) percent fcolor(emidblue) lcolor(none) width(`w') bin(`b') `saving'
+		qui graph use `c(tmpdir)'/`html'_`s'.gph
+		qui graph save `c(tmpdir)'/`html'_`s'.gph, replace
+		//di " _char(34) "
+
+	}
+	//set graphics on
+
+	
+	
+	qui local saving "saving(`c(tmpdir)'/`html'_group,replace) nodraw"
+	qui gr combine $scorename, name(group,replace) title("Distribution of scores") `saving'  
+	qui graph use `c(tmpdir)'/`html'_group.gph
+	qui graph save `c(tmpdir)'/`html'_group.gph, replace
+	//di " _char(34) "
+
+	
+	qui local saving "saving(`c(tmpdir)'/`html'_scores,replace) nodraw"
+	qui biplot $scorename, name("Biplot_scores",replace) norow std title("Correlations between scores") xtitle("") ytitle("") `saving'
+	qui graph use `c(tmpdir)'/`html'_scores.gph
+	qui graph save `c(tmpdir)'/`html'_scores.gph, replace
+	//di " _char(34) "
+}
+
+else {
+	set graphics off
+	foreach s in $scorename {
+		qui local saving "saving(${dirsave}/Histograms_scores_`s',replace) nodraw"
+
+		qui hist `s', name("`s'",replace) percent fcolor(emidblue) lcolor(none) width(`w') bin(`b') `saving'
+	}
+	set graphics on
+
+		qui local saving "saving(${dirsave}/Histograms_scores,replace) nodraw"
+
+	gr combine $scorename, name("Histograms_scores",replace) `saving'
+	if ("$filessave"!="") qui graph save ${dirsave}/Histograms_scores.gph, replace
+
+		qui local saving "saving(${dirsave}/biplot_scores,replace) nodraw"
+
+	capture biplot $scorename, name("Biplot_scores",replace) norow std title("") xtitle("") ytitle("") `saving'
+	if ("$filessave"!="") qui graph save ${dirsave}/Biplot_scores.gph, replace
+
+}
+
+
+
+capture biplot `varlist', name("temp",replace) norow std nograph
+
+mat a = r(V)
+
+tempvar a1 a2
+mat colnames a = `a1' `a2'
+svmat a, names(col)
+
+tempvar mina1 mina2 maxa1 maxa2
+egen `mina1' = min(`a1')
+egen `mina2' = min(`a2')
+egen `maxa1' = max(`a1')
+egen `maxa2' = max(`a2')
+local mina1 = `mina1'
+local mina2 = `mina2'
+local maxa1 = `maxa1'+1.4
+local maxa1x = `maxa1'+0.3
+local maxa2 = `maxa2'
+
+local colors = "red blue black green ebblue mint erose orange maroon magenta mint gray teal navy olive sienna"
+local i = 1
+foreach c in `colors' {
+	local col`i' = "`c'"
+	local `++i'
+}
+
+local i = 1
+local y = 1
+local c = 1
+local bas = `maxa2'+0.2
+local droite = max(`maxa1',0.2)
+
+foreach x in `partition' {
+	tokenize $scorename
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	forvalues j=`y'/`s' {
+		local a = `a1'[`j']
+		local b = `a2'[`j']	
+		local call `call' || pcarrowi 0 0 `b' `a' "`var`j''", mlabcolor(`col`i'') color(`col`i'') head   
+	}
+	local bas = `bas'-0.2
+	local call `call' text(`bas' `droite' "``i''", size(3) color(`col`i'')) /*`bas' `droite' "``i''", mlabcolor("`r' `g' `b'")*/
+	local `++i' 
+	local y = `s'+1	
+	local `++c' 
+}
+
+
+if "`html'" != "" {
+	qui local saving "saving(`c(tmpdir)'/`html'_items,replace) nodraw"
+	qui twoway `call' name("items",replace) legend(off) xscale(range(`mina1' `maxa1x')) yscale(range(`mina2' `maxa2')) title("Correlations between items") xtitle("") ytitle("") xsize(`xsize') ysize(`ysize') `saving'
+	qui graph use `c(tmpdir)'/`html'_items.gph
+	qui graph save `c(tmpdir)'/`html'_items.gph, replace
+	//di " _char(34) "
+}
+else {
+	qui twoway `call' name("Biplot_items",replace) legend(off) xscale(range(`mina1' `maxa1x')) yscale(range(`mina2' `maxa2')) xtitle("") ytitle("")
+	if ("$filessave"!="") qui graph save ${dirsave}/Biplot_items.gph, replace
+
+}
+
+
+							
+end
+
+/* convdiv */
+
+capture program drop convdiv
+program convdiv
+syntax varlist, PARTition(numlist integer >0) [TCONVdiv(real 0.4) convdivboxplots]
+preserve
+
+//qui set autotabgraphs on
+
+
+
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+local P:word count `partition'
+local cptdiv = 0
+local cptconv = 0
+
+if ${exist} != 1 {
+
+	qui detect `varlist', partition(`partition') 
+
+	matrix A = r(Corrrestscores)
+	matrix B = r(Corrscores)
+
+	local i = 1
+	local y = 1
+
+	foreach x in `partition' {
+		if `i' == 1 local s = `x'
+		else local s = `s' +`x'
+		
+		forvalues z = `y'/`s' {
+			matrix B[`z',`i'] = A[`z',`i']
+		}
+		local `i++' 
+		local y = `s'+1
+	} 
+
+	matrix colnames B = $scorename
+
+    local i = 1
+	foreach v in `varlist' {
+		local var`i' = abbrev("`v'",10)
+		local `++i'
+	}
+
+	local i = 1
+	foreach s in $scorename {
+		local s`i' = abbrev("`s'",7)
+		local sc `sc' `s`i''
+		local `++i'
+	}
+
+	di as result "{hline 105}"
+	di "{bf:Correlation matrix}"
+	di "{hline 105}"
+	di
+
+	local dec = 10
+	local col = `dec'
+
+	local decit = 14
+	local colit = `decit'
+
+
+	local col1 = `decit'
+	forvalues i=1/`P' {
+		di _col(`col1') "{bf:`s`i''}" _c
+		local col1 = `col1' + `dec'
+	}
+
+	di 
+	local h = (`P'-1)*`dec'+`decit'+4
+	di "{hline `h'}"
+
+	local i = 1
+	local j = 1
+	local y = 1
+
+	foreach p in `partition' {
+		if `j' == 1 local s = `p'
+		else local s = `s' +`p'
+		
+		forvalues z = `y'/`s' { 
+			di as text "{bf:`var`z''}" _c
+			local col = `decit'-1	
+			
+			local dd = `z' // [count cptdiv (one per item)] 
+			
+			forvalues k = 1/`P' { 
+					
+				local t = B[`z',`k']
+				local t : di %6.3f `t'
+				if `k' == `i' {
+					if `t' < `tconvdiv' {
+						/*if "${html}" != "" {
+							di "

" + di _col(`col') "{bf:`t'}" _c + di "

" + }*/ + //else { + di in red _col(`col') "{bf:`t'}" _c + //} + + local cptconv = `cptconv'+1 + local col = `col' + `dec' + } + else { + /*if "${html}" != "" { + di "

" + di as text _col(`col') "{bf:`t'}" _c + di "

" + }*/ + //else { + di as text _col(`col') "{bf:`t'}" _c + //} + local col = `col' + `dec' + } + } + else { + + if B[`z',`k'] > B[`z',`i'] { + /*if "${html}" != "" { + di "" + di in red _col(`col') "`t'" _c + di "" + }*/ + //else { + di in red _col(`col') "`t'" _c + //} + + if `dd' == `z' local cptdiv = `cptdiv'+1 // [one per item] + local dd = 0 + local col = `col' + `dec' + } + else { + /*if "${html}" != "" { + di "

" + di as text _col(`col') "{text:`t'}"_c + di "

" + }*/ + //else { + di as text _col(`col') "{text:`t'}"_c + //} + + local col = `col' + `dec' + } + } + } + di + } + di as text "{dup `h':-}" + local `i++' + local `j++' + local y = `s'+1 + } + + local y = 1 + local h = 1 + local np : word count `partition' + + foreach p in `partition' { + if `h' == 1 local s = `p' + else local s = `s' +`p' + + forvalues j = 1/`np' { + mat C_`h'_`j' = B[`y'..`s',`j'] + + tempvar tp_`h'_`j' + mat colnames C_`h'_`j' = `tp_`h'_`j'' + + svmat C_`h'_`j', names(col) + } + + local `++h' + local y = `s'+1 + } + +} + +else if ${exist} == 1 { + + di as result "{hline 105}" + di "{bf:Correlation matrix (without rest-scores)}" + di "{hline 105}" + di + + + local i = 1 + foreach v in `varlist' { + local var`i' = abbrev("`v'",10) + local `++i' + } + + local i = 1 + foreach s in $scorename { + local s`i' = abbrev("`s'",7) + local sc `sc' `s`i'' + local `++i' + } + + local dec = 10 + local col = `dec' + + local decit = 14 + local colit = `decit' + + local col1 = `decit' + forvalues i=1/`P' { + di _col(`col1') "{bf:`s`i''}" _c + local col1 = `col1' + `dec' + } + + di + local h = (`P'-1)*`dec'+`decit'+4 + di "{hline `h'}" + + qui corr $scorename `varlist' + matrix c = r(C) + matrix B = c[`=`P'+1'..`nbvars'+`P',1..`P'] + + local i = 1 + local j = 1 + local y = 1 + + foreach p in `partition' { + if `j' == 1 local s = `p' + else local s = `s' +`p' + + forvalues z = `y'/`s' { + di as text "{bf:`var`z''}" _c + local col = `decit'-1 + + local dd = `z' // [count cptdiv (one per item)] + + forvalues k = 1/`P' { + + local t = B[`z',`k'] + local t : di %6.3f `t' + if `k' == `i' { + if `t' < `tconvdiv' { + di in red _col(`col') "{bf:`t'}" _c + local cptconv = `cptconv'+1 + local col = `col' + `dec' + } + else { + di _col(`col') "{bf:`t'}" _c + local col = `col' + `dec' + } + } + else { + + if B[`z',`k'] > B[`z',`i'] { + di in red _col(`col') "`t'" _c + + if `dd' == `z' local cptdiv = `cptdiv'+1 // [one per item] + local dd = 0 + local col = `col' + `dec' + } + else { + di as text _col(`col') "{text:`t'}"_c + local col = `col' + `dec' + } + } + } + di + } + di "{dup `h':-}" + local `i++' + local `j++' + local y = `s'+1 + } + + local y = 1 + local h = 1 + local np : word count `partition' + + foreach p in `partition' { + if `h' == 1 local s = `p' + else local s = `s' +`p' + + forvalues j = 1/`np' { + mat C_`h'_`j' = B[`y'..`s',`j'] + + tempvar tp_`h'_`j' + mat colnames C_`h'_`j' = `tp_`h'_`j'' + + svmat C_`h'_`j', names(col) + } + + local `++h' + local y = `s'+1 + } +} + +if "`convdivboxplots'" != "" { + + if "${html}" != "" { + local html = "${html}" + di "
" + di "
" + + + local colors = "red blue green orange maroon magenta ebblue mint erose gray teal navy olive sienna" + local i = 1 + foreach c in `colors' { + local col`i' = "`c'" + local `++i' + } + + forvalues h = 1/`np' { + tokenize $scorename + local call = "" + local callbox = "" + local callleg = "" + + forvalues j = 1/`np' { + local call `call' `tp_`h'_`j'' + local callbox `callbox' box(`j',fcolor(`col`j'') lcolor(`col`j'')) marker(`j', mcolor(`col`j'')) + local lab = "``j''" + local lab = `"`lab'"' + local callleg `callleg' `j' "`lab'" + } + + qui local saving "saving(`c(tmpdir)'/`html'_Conv_div_``h'',replace) nodraw" + qui graph box `call', name("Conv_div_``h''",replace) `callbox' legend(order(`"`callleg'"') stack rows(1) size(small)) title(Correlations between items of ``h'' and scores) yline(`tconvdiv', lpattern(dot) lcolor(black)) `saving' + qui graph use `c(tmpdir)'/`html'_Conv_div_``h''.gph + qui graph save `c(tmpdir)'/`html'_Conv_div_``h''.gph, replace + + di " _char(34) " + + + + //qui set autotabgraphs on + } + di "
" + di "
"
+	}
+	
+	else {
+		forvalues h = 1/`np' {
+		tokenize $scorename
+		local call = ""
+		local callbox = ""
+		local callleg = ""
+		
+		forvalues j = 1/`np' {
+			local call `call' `tp_`h'_`j''
+			local callbox `callbox' box(`j',fcolor(`color') lcolor(`color')) marker(`j', mcolor(`color')) 
+			local lab = "``j''"
+			local lab = `"`lab'"'
+			local callleg `callleg' `j' "`lab'"
+		}
+		di "ok1"
+		graph box `call', name("Conv_div_``h''",replace) `callbox' legend(order(`"`callleg'"') stack rows(1) size(small)) title(Correlations between items of ``h'' and scores) yline(`tconvdiv', lpattern(dot) lcolor(black))
+		di "ok2"
+		if ("$filessave"!="") qui graph save ${dirsave}/Conv_div_``h''.gph, replace
+		qui set autotabgraphs on
+		}
+	}
+}
+
+
+local t : di %5.3f `tconvdiv'
+local p1 = (`nbvars'-`cptconv')/`nbvars'*100
+local p1 : di %4.1f `p1'
+local p2 = (`nbvars'-`cptdiv')/`nbvars'*100
+local p2 : di %4.1f `p2'
+
+di
+di as result "Convergent validity:" _c
+di as text " `=`nbvars'-`cptconv''/`nbvars' items (`p1'%) have a correlation coefficient with the score of "
+di _col(22) "their own dimension greater than `t'"
+di
+di as result "Divergent validity:" _c
+di as text "  `=`nbvars'-`cptdiv''/`nbvars' items (`p2'%) have a correlation coefficient with the score"
+di _col(22) "of their own dimension greater than those computed with other scores." 
+
+end
+
+/* cfa */
+
+capture program drop cfa
+program cfa,rclass
+syntax varlist, PARTition(numlist integer >0) [CFAMethod(string) cfasb CFAStand CFACov(string) CFARmsea(real -999) CFACfi(real -999) CFAOR CFANOCOVDim] 
+preserve
+
+
+
+
+if "`cfasb'"!="" & `cfacfi'!=-999 {
+	di in red "You cannot use both cfasb and cfacfi()"
+	exit 119
+} 
+
+if "`cfasb'"!="" & `cfarmsea'!=-999 {
+	di in red "You cannot use both cfasb and cfarmsea()"
+	exit 119
+}
+
+
+	
+if `cfarmsea' == -999{
+	local cfarmsea 
+	//di in red "error in cfaautormsea option : you must specify a value"
+	//exit 119
+}
+if `cfacfi' == -999{
+	local cfacfi
+	//di in red "error in cfaautocfi option : you must specify a value"
+	//exit 119
+}
+	
+local nbvars:word count `varlist'	
+local P:word count `partition'
+	
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+/*
+if "`cfarmsea'" != "" & "`cfacov'" != "" {
+	di in red "You cannot use both cfacov() and cfarmsea"
+	exit 119
+}
+if "`cfacfi'" != "" & "`cfacov'" != "" {
+	di in red "You cannot use both cfacov() and cfacfi"
+	exit 119
+}
+*/	
+if "`cfacov'" != "" {
+	
+	lstrfun v, subinstr("`cfacov'","*"," ",.)
+	foreach var in `v' {
+		capture confirm variable `var'
+		if _rc {
+			di in red "error in cfacov() option : `var' is not a variable from the dataset"
+			exit 119
+		}
+	}
+	lstrfun s,  subinstr("`cfacov'","* ","*",.)
+	lstrfun s,  subinstr("`s'"," *","*",.)
+	lstrfun s,  subinstr("`s'","*","*e.",.)
+	lstrfun f,  subinstr("`s'"," "," e.",.)
+	local g e.`f'
+	lstrfun g , lower("`g'")
+    local covs `g'
+}
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = lower("`x'")
+	qui rename `x' `var`i''
+	local `++i'
+}
+
+local upscorename = upper("$scorename")
+
+local i = 0
+local y = 1
+tokenize `upscorename'
+foreach x in `partition' {
+	local `i++' 
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' `var`w'' 
+	}
+	
+	local a =  "(``i'' -> `liste')"
+	local zz `zz' `a'
+		
+	local y = `s'+1
+}
+
+if "`cfamethod'" == "" local cfamethod = "ml"
+
+if "`cfamethod'" != "ml" & "`cfamethod'" != "mlmv" & "`cfamethod'" != "adf" {
+	di "`cfamethod'"
+	di in red "option cfamethod incorrectly specified (choose among ml, mlmv and adf)."
+	error 198
+}
+
+if "`cfastand'" != "" local cfastand = "stand"
+
+if "`cfasb'" != "" {
+	local cfasb = "vce(sbentler)"
+	local sb = "_sb"
+}
+
+di as result "{hline 105}"
+di "{bf:Confirmatory factor analysis}"
+di as result "{hline 105}"
+
+local exitloop = 0
+foreach v in `varlist' {
+		local low = lower("`v'")
+		qui su `low'
+		local range = r(max)-r(min)+1
+		if `range' < 5 & "`cfamethod'"=="ml"{
+			local message "Warning: some items have less than 5 response categories. If multivariate normality assumption does not hold, maximum likelihood estimation might not be appropriate. Consider using cfamethod(adf)."
+			continue, break
+		}
+		else if `range' >= 5 & `range' < 7  & "`cfamethod'"=="ml" & "`cfasb'" == "" {
+			local message "Warning: some items have less than 7 response categories. If multivariate normality assumption does not hold, maximum likelihood estimation might not be appropriate. Consider using cfasb in order to apply Satorra-Bentler adjustment or using cfamethod(adf)."
+			continue
+		}
+}
+
+di in red "`message'"
+
+local ii = 1
+local s
+local stop = 0 
+
+while (`ii' == 1 | "`covsi'" != "") & `stop'!=1 {
+	if `ii' == 1 & ("`cfarmsea'"!="" | "`cfacfi'"!="") {
+		di
+		di as text "step 1 (model without covariances between errors)" 
+	}
+	if "`covs'" != "" & ("`cfarmsea'"!="" | "`cfacfi'"!="") di _n "{bf:step `ii':} {text:`covsi'}"
+	local covsi
+	
+	if "`cfanocovdim'" == "" {
+		qui sem `zz', method(`cfamethod') `cfastand' cov(`covs') iterate(50) `cfasb'
+	}
+	else {
+		qui sem `zz', method(`cfamethod') `cfastand' cov(`covs') iterate(50) covstruct(_lexogenous, diagonal) `cfasb'
+	}
+	
+	/* factor loadings */
+
+	matrix r = r(table)
+	matrix r = r[1,1...]
+	matrix r = r'
+	local n = `nbvars'*2 
+
+	matrix a = r[1,1]
+	forvalues i=3(2)`n' {
+		matrix b = r[`i',1]
+		matrix a = a\b
+	}
+
+	/* standard error factor loadings*/
+
+	matrix r = r(table)
+	matrix r = r[2,1...]
+	matrix r = r'
+	local n = `nbvars'*2 
+
+	matrix sef = r[1,1]
+	forvalues i=3(2)`n' {
+		matrix b = r[`i',1]
+		matrix sef = sef\b
+	}
+
+	
+	/* intercepts */
+
+	matrix r = r(table)
+	matrix r = r[1,1...]
+	matrix r = r'
+	local n = `nbvars'*2 
+
+	matrix a2 = r[2,1]
+	forvalues i=4(2)`n' {
+		matrix b = r[`i',1]
+		matrix a2 = a2\b
+	}
+	
+	
+	/* standard error intercepts*/
+
+	matrix r = r(table)
+	matrix r = r[2,2...]
+	matrix r = r'
+	local n = `nbvars'*2 
+
+	matrix sei = r[1,1]
+	forvalues i=3(2)`n' {
+		matrix b = r[`i',1]
+		matrix sei = sei\b
+	}
+	
+	//mat li sei
+	/* error variances */
+
+	local m = `n'+1
+	matrix r = r(table)
+	matrix r = r[1,`m'...]
+	matrix r = r'
+
+	matrix a3 = r[1,1]
+	forvalues i=2/`nbvars' {
+		matrix b = r[`i',1]
+		matrix a3 = a3\b
+	}
+
+	/* variance of dimensions*/
+
+	matrix r = r(table)
+	local n = `nbvars'*3+1
+	matrix r = r[1,`n'...]
+	matrix r = r'
+
+	matrix var = r[1,1]
+	forvalues i=2/`P' {
+		matrix b = r[`i',1]
+		matrix var = var\b
+	}
+	
+	//mat li var
+	
+	/* Covariances between dimensions */
+	
+	matrix r = r(table)
+	local P:word count `partition'
+	if `P' > 1 {
+		local one = 1
+	}
+	else{
+		local one = 0
+	}
+	local n = `nbvars'*3+`one'+`P'
+	
+	
+	if "`cfanocovdim'" == "" {
+		//mat li r
+		matrix r = r[1,`n'...]
+		//mat li r
+		matrix c = J(`P',`P',.)
+		
+		local nbcov:word count `cfacov'
+		local `++nbcov'
+		
+		local k = `nbcov'
+		forvalues c = 1/`P' { 
+			forvalues r = 2/`P' {
+				if `r'>`c' {
+					matrix c[`r',`c']=r[1,`k']
+					local `++k'
+				}
+			}
+		}
+		
+		local k = 1
+		forvalues c = 1/`P' { 
+			matrix c[`c',`c']=var[`k',1]
+			local `++k'
+		}
+			
+		matrix rownames c = $scorename
+		matrix colnames c = $scorename
+	}
+	
+	if ("`cfarmsea'"!="" | "`cfacfi'"!="") {
+		local stoprmsea = 0
+		 local stopcfi = 0
+		if "`cfarmsea'"!="" {
+			qui estat gof
+			di "rmsea =" round(r(rmsea),0.001)
+			if r(rmsea)<=`cfarmsea' {
+				local stoprmsea = 1
+			}
+			//else local stoprmsea = 0
+		}
+		else local stoprmsea = 1
+		if "`cfacfi'"!="" {
+			qui estat gof
+			di "cfi =" round(r(cfi),0.001)
+			if r(cfi)>=`cfacfi' {
+				local stopcfi = 1
+			}
+			//else local stopcfi = 0
+		}
+		else local stopcfi = 1
+		
+	
+		
+		/* OR */ 
+		if "`cfaor'"!="" {
+			if `stoprmsea'==1 | `stopcfi'==1 {
+				local stop = 1
+			}
+		}
+		/* AND */ 
+		if "`cfaor'"=="" {
+			if `stoprmsea'==1 & `stopcfi'==1 {
+				local stop = 1
+			}
+		}
+	}
+	
+	
+	if ("`cfarmsea'"!="" | "`cfacfi'"!="") & `stop'!=1 {
+		qui estat mindices, showpclass(mcons merrvar)
+		tempname mm nomcol
+		mat `mm' = r(mindices)
+				
+		svmat2 `mm' , r(`nomcol') full
+		gsort - `mm'1
+		
+		local nrows = rowsof(`mm')
+		
+		local y = 1
+		local i = 0
+		foreach x in `partition' {
+			local `i++' 
+			if `i' == 1 local s = `x'
+			else local s = `s' +`x'
+			
+			forvalues w = `y'/`s' {
+				local class_`var`w'' = `i'
+			}
+			local y = `s'+1
+		}
+		
+		
+		forvalues i = 1/`nrows' {
+			local tmp3=`nomcol'[`i']
+			lstrfun e, subinstr("`tmp3'","cov(","",.)
+			lstrfun e, subinstr("`e'",")","",.)
+			lstrfun e, subinstr("`e'",":_cons","",.)
+			lstrfun e, subinstr("`e'",",","*",.)
+			
+			lstrfun d, subinstr("`e'",","," ",.)
+			lstrfun d, subinstr("`d'","e.","",.)
+			lstrfun d, subinstr("`d'","*"," ",.)
+			
+			qui replace `nomcol' = "`d'" in `i'
+			
+			local d = `nomcol'[`i']
+			
+			tokenize "`d'"
+			if "`class_`1''" != "`class_`2''" {
+				qui replace `nomcol' = "" in `i'
+			}
+			
+			local tmp3=`nomcol'[`i']
+			
+			if "`tmp3'" != "" {
+				continue, break
+			}
+			else {
+				local e
+			}
+			
+			
+		}
+		
+		
+		
+				
+		local covsi `e'
+		local covs `covs' `e'
+		drop `mm'1-`nomcol'
+
+	}
+	
+	if e(converged) == 0 di in red "Warning : model did not converge after 50 iterations"
+	local `++ii'
+	
+}
+
+local i = 1
+foreach v in `varlist' {
+	local var`i' = abbrev("`v'",10)
+	local `++i'
+}
+
+local i = 1
+foreach s in $scorename {
+	local s`i' = abbrev("`s'",10)
+	local sc `sc' `s`i''
+	local `++i'
+
+}
+
+local max = 10
+local dec = `max'+5
+
+local max2 = 10
+
+local dec2 = `dec'+`max2'+5
+
+local a = e(N)
+di
+if e(converged) == 0 di in red "Warning : model did not converge after 50 iterations"
+di as result ""
+if "`covs'" != "" {
+	di as result "{bf:Covariances between errors added:} {text:`covs'}"
+	di
+}
+di "{bf:Number of used individuals: } {text:`a'}"
+di
+//di _col(`=`dec2'+17+4') "{bf:Estimation:}"
+
+
+di as result "{bf:Item}" _c
+di _col(`dec') "{bf:Dimension}" _c 
+di _col(`dec2') "{bf:Factor}" _c 
+di _col(`=`dec2'+14') "{bf:Standard}" _c 
+di _col(`=`dec2'+28') "{bf:Intercept}" _c  
+di _col(`=`dec2'+43') "{bf:Standard}" _c  
+
+if "`cfastand'" == "" {
+	di _col(`=`dec2'+57') "{bf:Error}" _c 
+	di _col(`=`dec2'+66') "{bf:Variance of}"
+	di _col(`dec2') "{bf:loading}" _c 
+	di _col(`=`dec2'+14') "{bf:error}" _c
+	di _col(`=`dec2'+43') "{bf:error}" _c
+	di _col(`=`dec2'+55') "{bf:variance}" _c
+	di _col(`=`dec2'+67') "{bf:dimension}"
+	local h = `dec2'+76
+}
+else {
+	di _col(`=`dec2'+57') "{bf:Error}" 
+	di _col(`dec2') "{bf:loading}" _c 
+	di _col(`=`dec2'+14') "{bf:error}" _c
+	di _col(`=`dec2'+44') "{bf:error}" _c
+	di _col(`=`dec2'+57') "{bf:variance}" 
+	local h = `dec2'+62
+} 
+
+di "{hline `h'}"
+
+local i = 1
+local y = 1
+foreach x in `partition' {
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	forvalues z = `y'/`s' {
+		tokenize `sc'
+		di "{bf:`var`z''}"_c
+		di _col(`dec') "{bf:``i''}" _c
+		local t = a[`z',1]
+		local t : di %7.2f `t'
+		di _col(`dec2') "{text:`t'}" _c
+		
+		local t = sef[`z',1]
+		local t : di %8.2f `t'
+		di _col(`=`dec2'+14') "{text:`t'}" _c
+			
+		local t = a2[`z',1]
+		local t : di %9.2f `t'
+		di _col(`=`dec2'+28') "{text:`t'}" _c
+		
+		local t = sei[`z',1]
+		local t : di %9.2f `t'
+		di _col(`=`dec2'+42') "{text:`t'}" _c
+		
+		local t = a3[`z',1]
+		local t : di %11.2f `t'
+				
+		if "`cfastand'" == "" & `z' == `y'{
+			di _col(`=`dec2'+52') "{text:`t'}" _c
+			local t = var[`i',1]
+			local t : di %11.2f `t'
+			di _col(`=`dec2'+66') "{text:`t'}"
+		}
+		else di _col(`=`dec2'+52') "{text:`t'}" 
+	}
+	di
+	local `i++' 
+	local y = `s'+1	
+}
+
+qui estat gof, stats(all)
+
+
+if "`cfasb'" != "" {
+	local chi2 = r(chi2sb_ms)
+	local p = r(psb_ms)
+	local ddl = r(df_ms)
+	local ratio = `chi2'/`ddl'
+	local rmsea = r(rmsea_sb)
+	*local lb = r(lb90_rmsea)
+	*local ub = r(ub90_rmsea)
+	local nfi = 1-(r(chi2sb_ms)/r(chi2sb_bs))
+	local rni = 1-(r(chi2sb_ms)-r(df_ms))/(r(chi2sb_bs)-r(df_bs))
+	local cfi = r(cfi_sb)
+	local ifi = (r(chi2sb_bs)-r(chi2sb_ms))/(r(chi2sb_bs)-r(df_ms))
+	local mci = exp(-0.5*((r(chi2sb_ms)-r(df_ms))/(e(N)-1)))
+	local srmr = r(srmr)
+}
+
+else {
+	local chi2 = r(chi2_ms)
+	local p = r(p_ms)
+	local ddl = r(df_ms)
+	local ratio = `chi2'/`ddl'
+	local rmsea = r(rmsea)
+	local lb = r(lb90_rmsea)
+	local ub = r(ub90_rmsea)
+	local nfi = 1-(r(chi2_ms)/r(chi2_bs))
+	local rni = 1-(r(chi2_ms)-r(df_ms))/(r(chi2_bs)-r(df_bs))
+	local cfi = r(cfi)
+	local ifi = (r(chi2_bs)-r(chi2_ms))/(r(chi2_bs)-r(df_ms))
+	local mci = exp(-0.5*((r(chi2_ms)-r(df_ms))/(e(N)-1)))
+	local srmr = r(srmr)
+}
+
+if "`cfanocovdim'" == "" {
+	di 
+	di "Covariances between dimensions:"
+	mat li c, nodotz noheader format(%4.2f)
+}
+
+di
+if "`cfasb'" != "" {
+	di "{bf:Goodness of fit (with Satorra-Bentler correction):}"
+}
+else {
+	di "{bf:Goodness of fit:}"
+}
+di
+
+
+
+if "${html}" != "" {
+
+di as result _col(4) "chi2" _c
+di as result _col(20) "df" _c
+di as result _col(28) "chi2/df" _c
+di as result _col(42) "RMSEA [90% CI]" _c
+di as result _col(64) "SRMR" _c
+di as result _col(74) "NFI" _c
+di as result _col(84) "RNI" 
+
+
+local t : di %7.2f `chi2'
+di "{text:`t'}" _c
+local t : di %3.0f `ddl'
+di _col(20) "{text:`t'}" _c
+local t : di %7.1f `ratio'
+di _col(29) "{text:`t'}" _c
+local t : di %5.3f `rmsea'
+local l : di %5.3f `lb'
+local u : di %5.3f `ub'
+di _col(40) "{text:`t' [`l' ; `u']}" _c
+local t : di %5.3f `srmr'
+di _col(63) "{text:`t'}" _c
+local t : di %5.3f `nfi'
+di _col(72) "{text:`t'}" _c
+local t : di %5.3f `rni'
+di _col(82) "{text:`t'}" 
+
+local p : di %5.3f `p'
+di "{text:(p-value = `p')}"
+di as result
+di as result _col(4) "CFI" _c 
+di as result _col(15) "IFI" _c
+di as result _col(26) "MCI"
+local t : di %5.3f `cfi'
+di _col(4) "{text:`t'}" _c
+local t : di %5.3f `ifi'
+di _col(15) "{text:`t'}" _c
+local t : di %5.3f `mci'
+di _col(26) "{text:`t'}" 
+di as result
+}
+else {
+di as result _col(4) "chi2" _c
+di as result _col(20) "df" _c
+di as result _col(28) "chi2/df" _c
+di as result _col(42) "RMSEA [90% CI]" _c
+di as result _col(64) "SRMR" _c
+di as result _col(74) "NFI" _c
+di as result _col(84) "RNI" _c
+di as result _col(94) "CFI" _c 
+di as result _col(104) "IFI" _c
+di as result _col(114) "MCI"
+
+local t : di %7.2f `chi2'
+di "{text:`t'}" _c
+local t : di %3.0f `ddl'
+di _col(20) "{text:`t'}" _c
+local t : di %7.1f `ratio'
+di _col(29) "{text:`t'}" _c
+local t : di %5.3f `rmsea'
+local l : di %5.3f `lb'
+local u : di %5.3f `ub'
+di _col(40) "{text:`t' [`l' ; `u']}" _c
+local t : di %5.3f `srmr'
+di _col(63) "{text:`t'}" _c
+local t : di %5.3f `nfi'
+di _col(72) "{text:`t'}" _c
+local t : di %5.3f `rni'
+di _col(82) "{text:`t'}" _c
+local t : di %5.3f `cfi'
+di _col(92) "{text:`t'}" _c
+local t : di %5.3f `ifi'
+di _col(102) "{text:`t'}" _c
+local t : di %5.3f `mci'
+di _col(112) "{text:`t'}" 
+local p : di %5.3f `p'
+di "{text:(p-value = `p')}"
+di as result
+
+}
+end
+
+
+/* repet */
+
+capture program drop repet
+program repet,rclass
+syntax varlist, PARTition(numlist integer >0) [t2(varlist) KAPpa ICKAPpa(integer 0)]
+preserve
+
+local nbvars : word count `varlist'
+
+if `ickappa' <= 0 {
+	local ickappa = ""
+}
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local P:word count `partition'
+
+if "$scores2" != "" {
+	local t:word count $scores2' 
+	if `P' != `t' {
+		di in red "The number of score names given in scores2() is different from the number of scores defined"
+		exit 119
+	}
+}
+
+if "`t2'" != "" { 
+
+	local i = 1
+	foreach s in $scorename {
+		local s`i' = abbrev("`s'",10)
+		local sc `sc' `s`i''
+		local `++i'
+	}
+
+	local i = 1
+	foreach v in `varlist' {
+		local var`i' = abbrev("`v'",10)
+		local `++i'
+	}
+
+	local maxit = 1
+	forvalues i=1/`nbvars' {
+		local len = length("`var`i''")
+		if `len' > `maxit' local maxit = `len'
+	}
+
+	local decit = `maxit' + 4
+	local colit = `decit'
+
+	di as result "{hline 105}"
+	di as result "{bf:Reproducibility}"
+	di as result "{hline 105}"
+	di
+
+	if "$scores2" == "" {
+		foreach sco in $scorename {
+				*local t = "`sco'bis"
+				tempname s
+				local scorename2 `scorename2' `s'
+		}
+		
+		qui calcscore `t2', scorename(`scorename2') partition(`partition') compscore(${compscore}) categories($categories)
+		
+	}
+	
+	else {
+		foreach sco in $scores2 {
+			local scorename2 `scorename2' `sco'
+		}
+	}
+	
+	local i = 1
+	foreach var in `varlist' {
+		tokenize `t2'
+		qui kap `var' ``i''
+		local k`i' = r(kappa)
+		if "`ickappa'" != "" {
+			qui kapci `var' ``i'', reps(`ickappa')
+			local lbk`i' = r(lb_bc)
+			local ubk`i' = r(ub_bc)
+		}
+		local `++i'
+	}
+
+	local i = 1
+	foreach s in $scorename {
+		tokenize `scorename2'
+		tempname score id temps
+		qui gen `id' = _n
+		qui gen `score'_1 = `s'
+		qui gen `score'_2 = ``i'' if ``i''!=.
+		qui reshape long `score'_, i(`id') j(`temps')
+		qui icc `score'_ `id'
+		local n`i' = r(N_target)
+		local icc`i' = r(icc_i)
+		local lb`i' = r(icc_i_lb)
+		local ub`i' = r(icc_i_ub)
+		qui sort `id'
+		qui duplicates drop `id', force
+		local `++i'
+	}
+
+	tokenize `sc'
+	local max = length("dimension")
+
+	forvalues j=1/`P' {
+		local len`j' = length("`s`j''")
+		if `len`j'' > `max' local max = `len`j''
+	}
+
+	local dec = `max' + 5
+
+	local i = 1
+	local j = 1
+	local y = 1
+	di "{bf:Dimension}" _c
+	di _col(`=`dec'+2') "{bf:n}" _c
+	local col = `dec'+6
+	di _col(`col') "{bf:Item}" _c
+	local col = `col'+`decit'
+
+	if "`kappa'" != "" {
+		di _col(`col') "{bf:Kappa}" _c
+		local col = `col'+10
+		if "`ickappa'" != "" {
+			di _col(`col') "{bf:95% CI for Kappa}" _c
+			local col = `col'+20	
+		}
+		
+	}
+
+	di _col(`=`col'+2') "{bf:ICC}" _c
+	local col = `col'+9
+	di _col(`col') "{bf:95% CI for ICC}"
+
+	local zz = 0
+	foreach var in `varlist' {
+		qui levelsof `var', local(levels)
+		local z : word count `levels'
+		if `z' > 2 local zz = 1
+	}
+
+	if "`kappa'" != "" & "`ickappa'" != "" & `zz' == 1 {
+		local col = `dec'+`decit'+16
+		di _col(`col') "{bf:(bootstrapped)}"
+	}
+
+
+	if "`ickappa'" != "" local h = `dec'+6+`decit'+10+8+21+12+1
+	else if "`kappa'" != "" local h = `dec'+6+`decit'+10+8+21+12-20
+	else local h = `dec'+6+`decit'+10+8+21+12-29
+	di "{hline `h'}"
+
+	local i = 1
+	foreach p in `partition' {
+		tokenize `sc'
+		di "{bf:``i''}" _c
+		di _col(`dec') "{text:`n`i''}" _c
+		if `j' == 1 local s = `p'
+		else local s = `s' +`p'
+		local col = `dec'+6
+		di _col(`col') "{text:`var`y''}" _c 
+		
+		if "`kappa'" != "" {
+			local k : di %5.2f `k`y''
+			local col = `col'+`decit'
+			di _col(`col') "{text:`k'}" _c
+			if "`ickappa'" != "" {
+				local lbk : di %5.2f `lbk`i''
+				local ubk : di %5.2f `ubk`i''
+				local col = `col'+11
+				di _col(`col') "{text:[`lbk' ; `ubk']}" _c
+				local col = `decit'+50
+			}
+			
+		else local col = `decit'+30	
+		}
+		else local col = `decit'+20
+			
+		local icc : di %5.2f `icc`i''
+		di _col(`col') "{text:`icc'}" _c
+		local lb : di %5.2f `lb`i''
+		local ub : di %5.2f `ub`i''
+		local col = `col'+8
+		di _col(`col')"{text:[`lb' ; `ub']}"
+		local w = `y'+1
+		
+		forvalues z = `w'/`s' {
+			local col = `dec'+6
+			di _col(`col') "{text:`var`z''}" _c
+			if "`kappa'" != "" {
+				local k : di %5.2f `k`z''
+				local col = `col'+`decit'
+				di _col(`col') "{text:`k'}" _c
+				if "`ickappa'" != "" {
+					local lbk : di %5.2f `lbk`z''
+					local ubk : di %5.2f `ubk`z''
+					local col = `col'+11
+					di _col(`col')"{text:[`lbk' ; `ubk']}"
+				}
+				else di
+				
+			}
+			else di
+		}
+		local `i++' 
+		local `j++' 
+		local y = `s'+1
+		di
+	}
+}
+
+else {
+	local i = 1
+	foreach s in $scorename {
+		tokenize $scores2
+		tempname score id temps
+		qui gen `id' = _n
+		qui gen `score'_1 = `s'
+		qui gen `score'_2 = ``i'' if ``i''!=.
+		qui reshape long `score'_, i(`id') j(`temps')
+		qui icc `score'_ `id'
+		local n`i' = r(N_target)
+		local icc`i' = r(icc_i)
+		local lb`i' = r(icc_i_lb)
+		local ub`i' = r(icc_i_ub)
+		qui sort `id'
+		qui duplicates drop `id', force
+		local `++i'
+	}
+
+	tokenize $scorename
+	local max = length("dimension")
+
+	local h = 1
+	foreach s in $scorename {
+		local s`h' = abbrev("`s'",10)
+		local sc `sc' `s`h''
+		local `++h'
+	}
+	
+	forvalues j=1/`P' {
+		local len`j' = length("`s`j''")
+		if `len`j'' > `max' local max = `len`j''
+	}
+
+	local dec = `max' + 5
+
+	local i = 1
+	local j = 1
+	local y = 1
+	
+	di as result "{hline 105}"
+	di as result "{bf:Reproducibility}"
+	di as result "{hline 105}"
+	di
+	
+	di "{bf:Dimension}" _c
+	local col = `dec'
+	di _col(`col') "{bf:n}" _c
+	
+
+	di _col(`=`col'+6') "{bf:ICC}" _c
+	local col = `col'+14
+	di _col(`col') "{bf:95% CI for ICC}"
+
+	di "{hline 50}"
+	
+	local i = 1
+	foreach p in `partition' {
+		tokenize $scorename
+		di "{bf:``i''}" _c
+		local n : di % 4.0f `n`i''
+		di _col(`=`dec'-3') "{text:`n'}" _c
+		if `j' == 1 local s = `p'
+		else local s = `s' +`p'
+		local col = `dec'+4
+		
+		local icc : di %5.2f `icc`i''
+		di _col(`col') "{text:`icc'}" _c
+		local lb : di %5.2f `lb`i''
+		local ub : di %5.2f `ub`i''
+		local col = `col'+9
+		di _col(`col')"{text:[`lb' ; `ub']}"
+		local w = `y'+1
+		
+		local `i++' 
+	}
+}
+
+end
+
+
+/* kgv */
+
+capture program drop kgv
+program kgv,rclass
+syntax varlist, categ(varlist) [KGVBoxplots KGVGroupboxplots]
+	
+foreach c in `categ' {
+	tempname j
+	capture encode `c', generate(`j')
+	capture confirm variable `j'
+	if _rc local j = "`c'"
+	local categ2 `categ2' `j' 
+}	
+
+local i = 1
+local j = 1	
+local k = 0
+local max = 0
+local a : word count `categ'
+local nb:word count `varlist'
+
+di as result "{hline 105}"
+di "{bf:Known-groups validity}"
+di as result "{hline 105}"
+di
+	
+foreach sco in `varlist' {
+	foreach cat in `categ2' {
+		local nblev = 0
+		local maxlen`j' = 0
+		
+		qui anova `sco' `cat'
+		local p`i'_`j' = Ftail(e(df_m), e(df_r), e(F))
+		qui kwallis `sco', by(`cat')
+		local p2`i'_`j' = chi2tail(r(df), r(chi2))
+		
+		
+		/*local inf30 = 0
+		qui tab `cat' if `sco'!=., matcell(x)
+		local r = r(r)
+		forvalues n = 1/`r' {
+			if x[`n',1]<48 {
+				local `++inf30'
+			}
+		}
+		if `inf30' > 0 {
+			//di in red "kw"
+			kwallis `sco', by(`cat')
+			local p2`i'_`j' = chi2tail(r(df), r(chi2))
+			anova `sco' `cat'
+			local p`i'_`j' = Ftail(e(df_m), e(df_r), e(F))
+			
+		}
+		else {
+			//di in red "aov"
+			anova `sco' `cat'
+			local p`i'_`j' = Ftail(e(df_m), e(df_r), e(F))
+		}*/
+		
+				
+		qui levelsof `cat', local(levels) 
+		local lbe : value label `cat'
+			
+		foreach l of local levels {
+			qui count if `sco' !=. & `cat' == `l'
+			local `++k'
+			local eff`i'_`j'_`k' = r(N)
+			
+			if "`lbe'" != "" {
+				local ll`j'_`k' : label `lbe' `l'
+				local len = length("`ll`j'_`k''")
+				if `len' > 10 {
+					local c = substr("`ll`j'_`k''",1,9)
+					local d = substr("`ll`j'_`k''",-1,1)
+					local ll`j'_`k' "`c'" "~" "`d'" 
+				}
+				local w = length("`ll`j'_`k''")
+				if `w' > `maxlen`j'' local maxlen`j' = `w'
+			}
+			else {
+				local ll`j'_`k' = `l'
+				local len = length("`ll`j'_`k''")
+				if `len' > 10 {
+					local c = substr("`ll`j'_`k''",1,9)
+					local d = substr("`ll`j'_`k''",-1,1)
+					local ll`j'_`k' "`c'" "~" "`d'" 
+				}
+				local w = length("`ll`j'_`k''")
+				if `w' > `maxlen`j'' local maxlen`j' = `w'
+			}
+			qui su `sco' if `cat' == `l'
+			local m`i'_`j'_`k' = r(mean)
+			local s`i'_`j'_`k' = r(sd)
+			local nblev = `nblev' + 1
+		}
+		if `nblev' > `max' local max = `nblev'
+		local `++j'
+		local k = 0
+	}
+	local `++i'
+	local j = 1
+}
+
+local i = 1
+foreach s in `varlist' {
+	local s`i' = abbrev("`s'",7)
+	local sc `sc' `s`i''
+	local `++i'
+}
+
+local maxs = 0
+forvalues j=1/`nb' {
+	local len`j' = length("`s`j''")
+	if `len`j'' > `maxs' local maxs = `len`j''
+}
+
+local i = 1
+local k = 0
+local j = 2
+
+foreach cat in `categ'{
+	local `++k'
+	tokenize `categ'
+	local c`k' = "``i'' ``j''"
+	local i = `i' + 2 
+	local j = `j' + 2 
+}
+
+
+local d = 1
+local f = 2
+forvalues h = 1/`a' {
+	if `f' > `a' local f = `f'-1
+	local j = 1
+	local col =  `maxs'+6
+	foreach cat in `c`h'' {
+		di _col(`col') "{bf:`cat'}" _c
+		local col = `col' + `maxlen`j'' + 5 + 40
+		local `++j'
+	}
+	di
+
+	local j = `d'
+	local col = `maxs'+6
+	foreach cat in `c`h'' {
+		di _col(`=`col'+`maxlen`j''+5') "{bf:       mean    }" _c
+		di "{bf:     sd    }" _c
+		di "{bf:p-value}" _c
+		//di "{bf:p-value (Kruskal-Wallis)}" _c
+		    
+		local col = `col' + `maxlen`j'' + 5 + 40
+		local `++j'
+	}
+	
+	local j = `d'
+	local col = `maxs'+6
+
+	di
+	di
+	local i = 1
+	local col = `maxs'+6
+
+	forvalues g = 1/`nb' {
+		
+		di "{bf:`s`g''}" _c
+		forvalues k = 1/`max' {
+			forvalues j = `d'/`f' {
+			
+				di _col(`col') "{bf:`ll`j'_`k''} " _c
+				if "`eff`i'_`j'_`k''" != "" di as text "(n=`eff`i'_`j'_`k'')" _c
+				local m : di %6.2f `m`i'_`j'_`k''
+				di _col(`=`col'+`maxlen`j''+10') "{text:`m'}  " _c
+					
+				local s : di %8.2f `s`i'_`j'_`k''
+				di "{text: `s'}  " _c
+					
+				if `k' == 1 {
+					local p : di %8.3f `p`i'_`j''
+					local p2 : di %4.3f `p2`i'_`j''
+					di _col(`=`col'+31') "{text:`p'}  " _c
+					di _col(`=`col'+35') "{text:(KW: `p2')}  " _c
+				}
+				local col = `col' + `maxlen`j'' + 5 + 40
+			}
+			di
+			local col = `maxs'+6
+		
+		}
+		di 
+		
+	local `++i'
+	
+	}
+	local d = `d'+2
+	local f = `f'+2
+	if `d' > `a' continue, break
+	di
+}
+
+if "`kgvboxplots'" != "" {
+	local html = "${html}"
+	if "`html'" != "" {
+		di "
" + di "
" + if "`kgvgroupboxplots'" != "" { + local cc = 1 + foreach c in `categ' { + local k = 1 + foreach s in `varlist' { + local pp = round(`p`k'_`cc'',0.001) + //graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c'") nodraw + + + qui local saving "saving(`c(tmpdir)'/`html'_kgv`s',replace) nodraw" + qui graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c' (p=`pp')") `saving' + qui graph use `c(tmpdir)'/`html'_kgv`s'.gph + qui graph save `c(tmpdir)'/`html'_kgv`s'.gph, replace + + + local g `g' `s'_`c' + local k = `k'+1 + } + local cc = `cc'+1 + } + + qui local saving "saving(`c(tmpdir)'/`html'_kgv,replace) nodraw" + qui gr combine `g', name(kgv,replace) `saving' + qui graph use `c(tmpdir)'/`html'_kgv.gph + qui graph save `c(tmpdir)'/`html'_kgv.gph, replace + //di " _char(34) " + + } + else { + local cc = 1 + foreach c in `categ' { + local k = 1 + foreach s in `varlist' { + local pp = round(`p`k'_`cc'',0.001) + //graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c'") + + qui local saving "saving(`c(tmpdir)'/`html'_kgv`s',replace) nodraw" + qui graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c' (p=`pp')") `saving' + qui graph use `c(tmpdir)'/`html'_kgv`s'.gph + qui graph save `c(tmpdir)'/`html'_kgv`s'.gph, replace + //di " _char(34) " + + local g `g' `s'_`c' + local k = `k'+1 + } + local cc = `cc'+1 + } + } + di "
" + di "
"
+	
+	}
+	else {
+		if "`kgvgroupboxplots'" != "" {
+			local cc = 1
+			foreach c in `categ' {
+				local k = 1
+				foreach s in `varlist' {
+					local pp = round(`p`k'_`cc'',0.001)
+					graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c' (p=`pp')") nodraw
+					local g `g' `s'_`c' 
+					local k = `k'+1
+				}
+				local cc = `cc'+1
+			}
+			gr combine `g', name(Known_groups_validity,replace)
+			if ("$filessave"!="") qui graph save ${dirsave}/Known_groups_validity.gph, replace
+
+		}
+		else {
+			local cc = 1
+			foreach c in `categ' {
+				local k = 1
+				foreach s in `varlist' {
+					local pp = round(`p`k'_`cc'',0.001)
+					graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c' (p=`pp')")
+					if ("$filessave"!="") qui graph save ${dirsave}/Known_groups_validity_`c'_`s'.gph, replace
+					local g `g' `s'_`c' 
+					local k = `k'+1
+				}
+				local cc = `cc'+1
+			}
+		}
+	}
+}
+
+end
+
+
+/* conc */
+
+capture program drop conc
+program conc,rclass
+syntax varlist, comp(varlist) [tconc(real 0.4)]
+
+di as result "{hline 105}"
+di "{bf:Concurrent validity}"
+di as result "{hline 105}"
+di
+
+local n : word count `varlist'
+local p : word count `comp'
+
+matrix m = J(`n',`p',.)
+matrix rownames m = `varlist'
+matrix colnames m = `comp'
+local r = 1
+
+foreach i in `varlist' {
+	local c = 1
+	foreach j in `comp' {
+		qui corr `i' `j'
+		mat e = r(C)
+		local f = e[2,1]
+		mat m[`r',`c'] = `f' 
+		local `++c'
+	}
+	local `++r'
+}
+
+tokenize `varlist'
+local maxv = length("`1'")
+forvalues i=1/`n' {
+	local lenv = length("``i''")
+	if `lenv' > `maxv' local maxv = `lenv'
+}
+
+local decv = `maxv'+6
+
+tokenize `comp'
+local maxc = length("`1'")
+forvalues i=1/`p' {
+	local lenc = length("``i''")
+	if `lenc' > `maxc' local maxc = `lenc'
+}
+
+local decc = `maxc'+4
+
+local col = `decv'
+foreach c in `comp' {
+	di as result _col(`col') "`c'" _c
+	local col = `col'+`decc'
+}
+di
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+forvalues i=1/`n' {
+	di as result "`var`i''" _c
+	local col = `decv'
+	forvalues j=1/`p' {
+		local t = m[`i',`j']
+		if `t' > `tconc' | `t' < -`tconc' {
+			di as result _col(`=`col'-1') %5.2f `t' _c
+		}
+		else di as text _col(`=`col'-1') %5.2f `t' _c
+		local col = `col'+`decc'
+	}
+	di
+}
+
+capture restore, not
+end
+
diff --git a/Modules/ado/personal/v/validscale.dlg b/Modules/ado/personal/v/validscale.dlg
new file mode 100644
index 0000000..48f9654
--- /dev/null
+++ b/Modules/ado/personal/v/validscale.dlg
@@ -0,0 +1,426 @@
+/* 
+  valid.dlg
+*/  
+
+VERSION 12.1
+
+POSITION . . 590 280
+
+DIALOG main, label("Validation") tabtitle("General")
+BEGIN
+  TEXT     tx_var       10    10    250     .,                 ///
+           label("Items used for calculating score")
+  VARLIST  vl_var       @     +20   280       .,                 /// 
+	       label("Variables")
+		
+  TEXT     tx_n      10    +28    200     .,  				///
+           label("Number of items")
+		   
+  EDIT     ed_n      @  +20  40  ., 						 ///
+		   label("number")									///
+		   numonly
+		
+  TEXT     tx_score       110    58    180    .,                 ///
+           label("Name of the dimension (optional)")
+  EDIT     ed_score       130  +20  100  ., 						///
+		   option(scorename)									///
+		   
+  BUTTON   bt_add 260 75 32 22, ///
+		   label("Add") ///
+		   onpush(script az) ///
+	
+  GROUPBOX gb_1 5 120 284 140,
+   
+  TEXT     tx_v 10 +10 100 .,                 ///
+           label("Items used")		   
+  VARLIST  ed_v @ +20 250 .,                   ///
+		   label("Items used")
+  
+  TEXT     tx_p @ +20 100 .,                 ///
+           label("Partition")                 
+		   
+  EDIT     ed_p @ +20 150 .,                  ///
+		   label("Partition")                 ///
+           option(partition) ///
+		   tooltip("Defines the number of items in each dimension")
+  TEXT     tx_s @ +20 . .,                 ///
+           label("Names of the dimensions (optional)")
+  EDIT     ed_s @ +20 150 .,                   ///
+		   label("Names of the dimensions")    ///
+		   option(scorename)
+  
+   
+  GROUPBOX gb_calc      330     13   245  90,               ///
+           label("Calculation of scores") 
+	 
+  RADIO    rb_mean +10  +20 100 ., first  label("Mean") ///
+           default(1) 
+		   
+		   
+  RADIO    rb_sum @  +20 100 ., label("Sum") 
+          
+		  
+  RADIO    rb_stand @  +20 140 ., last label("Standardized scores") ///
+           tooltip("Set score from 0 to 100")
+		   
+  GROUPBOX gb_opt      330     120   245   140,               ///
+           label("Options")
+		   
+  CHECKBOX ck_imp      +10   +20   -20     .,                 ///
+		   option(imp)                                       ///
+		   label("Imputing missing data")					 ///
+		   onclickon(main.ck_nor.enable)                  ///
+		   onclickoff(main.ck_nor.disable)                ///
+		   default(1)
+		   
+  CHECKBOX ck_nor     +145   @   -20     .,                 ///
+           option(noround)                                       ///
+           label("Do not round") ///
+		   tooltip("Do not round imputed values")
+
+  CHECKBOX ck_desc    340   +28   -20     .,                 ///
+		   option(descitems)									///
+           label("Description of items")	///
+		   default(0)		
+	
+  CHECKBOX ck_graphs    340   +28   -20   .,                 ///
+		   option(graphs)									///
+           label("Display graphs")	///
+		   default(0) ///
+		   tooltip("Display histogram of items, biplot of dimensions and biplot of items")
+	
+  /*	
+  CHECKBOX ck_cfa    340   +28   -20     .,                 ///
+		   option(cfa)									///
+           label("Confirmatory factor analysis")	///
+		   default(1)
+		  
+  		   
+  CHECKBOX ck_conv     @   +28   +10     .,                 ///
+		   option(conv_div)									///
+           label("Convergent/discriminant validity")	///
+		   default(1)
+  */		   
+  
+END
+
+
+DIALOG cfa, tabtitle("Confirmatory factor analysis")
+BEGIN
+  
+  CHECKBOX	ck_cfa 10 10 200 ., label("Display confirmatory factor analysis") ///
+		    option(cfa) ///
+			onclickon(script cfa_ck_cfa_on) ///
+			onclickoff(script cfa_ck_cfa_off)
+			  
+  GROUPBOX gb_cfa 10 +30 220 90 , ///
+	       label("Estimation method:") 
+ 
+  RADIO    rb_ml +10  +24 110 ., first  label("Maximum likelihood") ///
+           default(1) 
+	  
+  RADIO    rb_mlmv @  +20 200 ., label("Maximum likelihood with missing values") 
+           
+  RADIO    rb_adf @  +20 140 ., last label("Asymptotic distribution free") 
+           
+	
+  CHECKBOX	ck_stand 14  +34 140 ., label("Standardize coefficients") ///
+		    option(cfastand)
+  
+END
+
+
+DIALOG conv, tabtitle("Convergent/divergent validity")
+BEGIN
+
+  CHECKBOX ck_conv_div       10    10    220     .,  				///
+		   label("Display convergent/divergent validity") ///
+		   option(convdiv) ///
+		   onclickon(script conv_ck_conv_on) ///
+		   onclickoff(script conv_ck_conv_off)
+
+  TEXT     tx_conv1       10   +26    220     .,  				///
+		   label("Correlations between item and its own score") 
+  TEXT     tx_conv2       @     +17   @     .,  				///
+		   label("below this value will be highlighted")
+  EDIT     ed_conv       250    42   35  .,					 ///
+		   default(0.4)											///
+		   option(tconvdiv)	  				                         ///
+		   numonly
+		   
+  CHECKBOX ck_conv     10   +42   170     .,                 ///
+		   option(convdivboxplots)									///
+           label("Display boxplots of correlations")	              ///
+		   default(1)
+	
+END
+
+
+DIALOG rel, tabtitle("Reliability")
+BEGIN
+
+  TEXT     tx_rel_a       10    10    350     .,  				///
+		   label("Cronbach's alpha below this value will be highlighted")   
+  EDIT     ed_rel_a       320   @   35  ., 						 ///
+	       default(0.7)												///
+		   option(alpha)	  				                         ///
+		   numonly
+		   
+  TEXT     tx_rel_d       10    +30    350     .,  				///
+		   label("Ferguson's delta below this value will be highlighted")   
+  EDIT     ed_rel_d       320   @   35  ., 						 ///
+           default(0.9)												///
+		   option(delta)	  				                         ///
+		   numonly
+		   
+  TEXT     tx_rel_H       10    +30    380     .,  				///
+		   label("Loevinger's H coefficient below this value will be highlighted")
+  EDIT     ed_rel_H       320   @   35  ., 						 ///
+           default(0.3)												///
+		   option(h)	  				                         ///
+		   numonly
+		   
+  TEXT     tx_rel_h       10    +30    380     .,  				///
+		   label("Loevinger's Hj coefficient below this value will be highlighted")    
+  EDIT     ed_rel_h       320   @   35  ., 						 ///
+		   default(0.3)												///
+		   option(hjmin)	 										///
+		   numonly
+		   
+END
+
+
+
+DIALOG rep, tabtitle("Reproducibility")
+BEGIN
+
+  TEXT     tx_rep       10    10    250     .,                 ///
+           label("Items used for calculating scores (time 2)")
+  VARLIST  vl_rep       @     +20   @       .,                 ///
+		   option(repet)										  ///
+           label("Items time 2")
+	
+  CHECKBOX ck_kappa     @    +35    100     .,                 ///
+           label("Kappa statistic")                     ///
+		   option(kappa)                                   ///
+		   onclickon(script rep_ck_kappa_on)                  ///
+		   onclickoff(script rep_ck_kappa_off)
+		   
+  CHECKBOX ck_ickappa     @    +25   280     .,                 ///
+           label("Confidence interval for kappa")        ///
+		   onclickon(script rep_ck_ickappa_on)                  ///
+		   onclickoff(script rep_ck_ickappa_off)
+
+  TEXT     tx_boot @  +25   220   .,  ///
+           label("Number of bootstrap replications to estimate")
+            
+  TEXT     tx_boot2 @  +15   220   .,  ///
+           label("confidence interval (if items are polytomous):") 
+		   
+  SPINNER  sp_ickappa +220  -7   45   .,  ///
+           label("Number of bootstrap replications") min(1) max(1000) ///
+           default(20) ///
+		   option(ickappa)
+		   
+ 
+END
+
+
+DIALOG kgv, tabtitle("Known-groups validity")
+BEGIN
+  TEXT     tx_kgv       10    10    250     .,                 ///
+           label("Select qualitative variables for known-groups validity")
+  VARLIST  vl_kgv       @     +28   250       .,                 ///
+		   option(kgv)										  ///
+           label("kgv")
+
+  CHECKBOX ck_kgv       @	  +25	 150    .,                     ///
+		   label("Display boxplots")                                       ///
+		   option(kgvboxplots)                                    ///
+		   default(0) ///
+		   onclickon(kgv.ck_kgv_group.enable) ///
+		   onclickoff(kgv.ck_kgv_group.disable)
+		   
+   CHECKBOX ck_kgv_group       @	  +25	 190    .,                     ///
+		   label("Group boxplots in one graph")                                   ///
+		   option(kgvgroupboxplots)                                    ///
+		   default(0)
+		   
+END
+
+
+DIALOG conc, tabtitle("Concurrent validity")
+BEGIN
+  TEXT     tx_conc       10    10    186     .,                 ///
+           label("Select scores from other scales")
+  VARLIST  vl_conc       @     +28   250       .,                 ///
+		   option(conc)										  ///
+           label("conc")
+	
+  TEXT     tx_t_conc       @   +30   350     .,  				///
+		   label("Correlations above this value will be highlighted (absolute value)")   
+	
+  EDIT     ed_t_conc       320   @   30  ., 						 ///
+           default(0.4)												///
+		   option(tconc)	  				                         ///
+		   numonly
+		   
+END
+
+
+PROGRAM az
+BEGIN
+	main.ed_score.withvalue main.ed_s.append "@ "
+	main.vl_var.withvalue main.vl_v.append "@ "
+	main.ed_n.withvalue main.ed_p.append "@ "
+
+	main.vl_var.setvalue ""
+	main.ed_n.setvalue ""
+	main.ed_score.setvalue ""
+END
+
+
+
+
+SCRIPT rep_ck_kappa_on
+BEGIN
+   rep.ck_ickappa.enable
+END
+
+SCRIPT rep_ck_kappa_off
+BEGIN
+   rep.ck_ickappa.disable
+   rep.sp_ickappa.disable
+   rep.ck_ickappa.setoff
+END
+
+SCRIPT rep_ck_ickappa_on
+BEGIN
+   rep.sp_ickappa.enable
+   rep.tx_boot.enable
+   rep.tx_boot2.enable
+END
+
+SCRIPT rep_ck_ickappa_off
+BEGIN
+   rep.sp_ickappa.disable
+   rep.sp_ickappa.setdefault 0
+   rep.tx_boot.disable
+   rep.tx_boot2.disable
+END
+
+SCRIPT cfa_ck_cfa_on
+BEGIN
+	cfa.gb_cfa.enable
+	cfa.rb_ml.enable
+	cfa.rb_mlmv.enable
+	cfa.rb_adf.enable
+	cfa.ck_stand.enable
+END
+
+SCRIPT cfa_ck_cfa_off
+BEGIN
+	cfa.gb_cfa.disable
+	cfa.rb_ml.disable
+	cfa.rb_mlmv.disable
+	cfa.rb_adf.disable
+	cfa.ck_stand.disable
+END
+
+SCRIPT conv_ck_conv_on
+BEGIN
+	conv.tx_conv1.enable
+	conv.tx_conv2.enable
+	conv.ed_conv.enable
+	conv.ck_conv.enable
+END
+
+SCRIPT conv_ck_conv_off
+BEGIN
+	conv.tx_conv1.disable
+	conv.tx_conv2.disable
+	conv.ed_conv.disable
+	conv.ck_conv.disable
+END
+
+OK ok1,      label("OK")
+CANCEL can1, label("Cancel")
+SUBMIT sub1, label("Submit")
+HELP hlp1,   view("help valid")
+RESET res1
+COPY copy1
+
+PROGRAM command
+BEGIN
+	put "valid "
+	require main.ed_v
+	put main.ed_v
+	require main.ed_p
+	
+	beginoptions
+		optionarg main.ed_p
+		optionarg main.ed_s
+		option main.ck_imp
+		option main.ck_nor
+		option main.ck_desc
+		option main.ck_graphs
+		
+		if main.rb_mean{
+		put " calcmethod("
+		put "mean"
+		put ")"
+		}
+		
+		if main.rb_sum{
+		put " calcmethod("
+		put "sum"
+		put ")"
+		}
+		
+		if main.rb_stand{
+		put " calcmethod("
+		put "stand"
+		put ")"
+		}
+		
+		option cfa.ck_cfa
+		
+		if cfa.rb_ml{
+		put " cfamethod("
+		put "ml"
+		put ")"
+		}
+		
+		if cfa.rb_mlmv{
+		put " cfamethod("
+		put "mlmv"
+		put ")"
+		}
+		
+		if cfa.rb_adf{
+		put " cfamethod("
+		put "adf"
+		put ")"
+		}
+		
+		option cfa.ck_stand
+		option conv.ck_conv_div
+		optionarg conv.ed_conv
+		option conv.ck_conv
+		optionarg rel.ed_rel_a
+		optionarg rel.ed_rel_d
+		optionarg rel.ed_rel_H
+		optionarg rel.ed_rel_h
+		optionarg rep.vl_rep
+		option rep.ck_kappa
+		optionarg rep.sp_ickappa
+	    optionarg kgv.vl_kgv
+		option kgv.ck_kgv
+		option kgv.ck_kgv_group
+		optionarg conc.vl_conc
+		optionarg conc.ed_t_conc
+		
+	endoptions 
+		
+		
+END
diff --git a/Modules/ado/personal/v/validscale.hlp b/Modules/ado/personal/v/validscale.hlp
new file mode 100644
index 0000000..4408bad
--- /dev/null
+++ b/Modules/ado/personal/v/validscale.hlp
@@ -0,0 +1,143 @@
+{smcl}
+{* 2013}{...}
+{hline}
+help for {hi:validscale}{right:Bastien Perrot}
+{hline}
+
+{title:Syntax}
+
+{p 8 14 2}{cmd:validscale} {it:varlist}, {opt part:ition}({it:numlist}) [{it:options}]
+
+{p 4 4 2}{it:varlist} contains the variables (items) used to compute the scores. The first items of {it:varlist} compose the first dimension, the following items define the second dimension, and so on.
+
+{p 4 4 2}{cmd:partition} allows defining in {it:numlist} the number of items in each dimension.
+
+
+{synoptset 20 tabbed}{...}
+{synopthdr}
+{synoptline}
+{syntab:Options}
+{synopt : {opt scoren:ame(string)}}define the names of the dimensions{p_end}
+{synopt : {opt scores(varlist)}}use scores from the dataset{p_end}
+{synopt : {opt mod:alities(numlist)}}define minimum and maximum response categories for the items{p_end}
+{synopt : {opt imp:ute(method)}}impute missing item responses{p_end}
+{synopt : {help validscale##impute_options:{it:impute_options}}}options for imputation of missing data {p_end}
+{synopt : {opt comps:core(method)}}define how scores are computed{p_end}
+{synopt : {opt desc:items}}display a descriptive analysis of items and dimensions{p_end}
+{synopt : {opt graph:s}}display graphs for items description{p_end}
+{synopt : {opt cfa}}assess structural validity of the scale by performing a confirmatory factor analysis (CFA){p_end}
+{synopt : {help validscale##cfa_options:{it:cfa_options}}}options for confirmatory factor analysis (CFA){p_end}
+{synopt : {opt conv:div}}assess convergent and divergent validities assessment{p_end}
+{synopt : {help validscale##convdiv_options:{it:conv_div_options}}}options for convergent and divergent validities{p_end}
+{synopt : {help validscale##reliability_options:{it:reliability_options}}}options for reliability assessment{p_end}
+{synopt : {opt rep:et(varlist)}}assess reproducibility of scores and items{p_end}
+{synopt : {help validscale##repet_options:{it:repet_options}}}options for reproducibility{p_end}
+{synopt : {opt kgv(varlist)}}assess known-groups validity by using qualitative variable(s){p_end}
+{synopt : {help validscale##kgv_options:{it:kgv_options}}}options for known-groups validity assessment{p_end}
+{synopt : {opt conc(varlist)}}assess concurrent validity{p_end}
+{synopt : {help validscale##conc_options:{it:conc_options}}}options for concurrent validity assessment{p_end}
+
+{p2colreset}{...}
+
+
+{title:Description}
+
+{phang}{cmd:validscale} assesses validity and reliability of a multidimensional scale. Elements to provide
+structural validity, convergent and divergent validity, reproducibility, known-groups validity, internal consistency, scalability and sensitivity are computed. 
+
+{marker options}{...}
+{title:Options}
+
+{dlgtab:Options}
+
+{phang}{opt scoren:ame(string)} allows defining the names of the dimensions. If the option is not used, the dimensions are named {it:Dim1}, {it:Dim2},... unless {opt scores(varlist)} is used. 
+
+{phang}{opt scores(varlist)} allows selecting scores from the dataset. {opt scores(varlist)} and {opt scorename(string)} cannot be used together.
+
+{phang}{opt mod:alities(numlist)} allows specifying the minimum and maximum possible values for items responses. If all the items have the same response
+categories, the user may specify these 2 values in {it:numlist}. If the items response categories differ from a dimension to another, the user must define the possible minimum and maximum values of items responses for each
+dimension. So the number of elements in {it:numlist} must be equal to the number of dimensions times 2. Eventually, the user may specify the minimum and maximum response categories for each item. In this case, the
+number of elements in {it:numlist} must be equal to the number of items times 2. By default, the minimum and maximum values are assumed to be the minimum and maximum for each item.      
+
+{phang}{opt imp:ute(method)} imputes missing items responses with Person Mean Substitution ({bf:pms}) or Two-way imputation method applied in each dimension ({bf:mi}). With PMS method, missing data are imputed only if the number of
+missing values in the dimension is less than half the number of items in the dimension. 
+
+{marker impute_options}{...}
+{phang}{it:impute_options} allow specifying options for imputation of missing values. By default, imputed values are rounded to the nearest whole number but with the {opt nor:ound} option, imputed values
+are not rounded. If {opt impute} is absent then {opt noround} is ignored.
+
+{phang}{opt comp:score(method)} defines the method used to compute the scores. {it:method} may be either {bf:mean} (default), {bf:sum} or {bf:stand}(set scores from 0 to 100). {opt comp:score(method)} is ignored
+if the {opt scores(varlist)} option is used.
+
+{phang}{opt desc:items} displays a descriptive analysis of the items. This option displays missing data rate per item and distribution of item responses. It also computes for each item the Cronbach's alphas
+obtained by omitting each item in each dimension. Moreover, the option computes Loevinger's Hj coefficients and the number of non-significant Hjk. See {help loevh} for details about Loevinger's coefficients.     
+
+{phang}{opt graph:s} displays graphs for items and dimensions descriptive analyses. It provides histograms of scores, a biplot of the scores and a graph showing the correlations between the items.
+
+{phang}{opt cfa} performs a confirmatory factor analysis using {help sem} command. It displays estimations of parameters and several goodness-of-fit indices.
+
+{marker cfa_options}{...}
+{phang}{it:cfa_options} allow specifying options for confirmatory factor analysis (CFA). {opt cfam:ethod}({it:method}) specifies the method to estimate the parameters. {it:method} may be either {bf:ml} (maximum
+likelihood), {bf:mlmv} ({bf:ml} with missing values) or {bf:adf} (asymptotic distribution free). The {opt cfas:tand} option displays standardized coefficients.
+The {opt cfac:ovs} option allows adding covariances between measurement errors. You can look at the examples to see the syntax of this option. The {opt cfaa:uto} option adds automatically the covariances
+of measurement errors found with the {help estat mindices} command. The option only adds the covariances of measurement errors within a dimension.
+
+{phang}{opt conv:div} assesses convergent and divergent validities. The option displays the matrix of correlations between items and rest-scores. If {opt scores(varlist)} is used, then the correlations coefficients are computed between
+items and scores of {opt scores(varlist)}. 
+
+{marker convdiv_options}{...}
+{phang}{it:conv_div_options} allow specifying options for convergent and divergent validity. {opt tconv:div(#)} defines a threshold for highlighting some values. # is a real number between 0 and 1 which is equal to 0.4 by
+default. Correlations between items and their own score are displayed
+in red if it is less than #. Moreover, if an item has a smaller correlation coefficient with the score of its own dimension than the correlation coefficient computed with other scores, this coefficient is displayed
+in red. The {opt convdivb:oxplots} option displays boxplots for assessing convergent and divergent validities. The boxes represent the correlation coefficients between the items of a given dimension and all scores. Thus the
+box of correlation coefficients between items of a given dimension and the corresponding score must be higher than other
+boxes. There are as many boxplots as dimensions. 
+
+{marker reliability_options}{...}
+{phang}{it:reliability_options} allow defining the thresholds for reliability indices. {opt a:lpha(#)} defines a threshold for Cronbach's alpha (see {help alpha}). # is a real number between 0 and 1 which is equal to 0.7
+by default. Cronbach's alpha coefficients less than # are printed in red. {opt d:elta(#)} defines a threshold for Ferguson's delta coefficient (see {help delta}). Delta coefficients are computed only if {opt compscore}({it:sum}) is used
+and {opt scores}({it:varlist)} is not used. # is a real number between 0 and 1 which is equal to 0.9
+by default. Ferguson's delta coefficients less than # are printed in red. {opt h(#)} defines a threshold for Loevinger's H coefficient (see {help loevh}). # is a real number between 0 and 1 which is equal to
+0.3 by default. Loevinger's H coefficients less than # are printed in red. {opt hj:min(#)}
+defines a threshold for Loevinger's Hj coefficients. The displayed value is the minimal Hj coefficient for a item in the dimension. (see {help loevh}). # is a real number between 0 and 1 which is equal to
+0.3 by default. If the minimal Loevinger's Hj coefficient is less than # then it is printed in red and the corresponding item is displayed.
+																										                                                                                                                                                                                                            
+{phang}{opt rep:et(varlist)} assesses reproducibility of scores by defining in {it:varlist} the variables corresponding to responses at time 2 (in the same order than for time 1). Scores are computed according to
+the {opt partition()} option. Intraclass
+Correlation Coefficients (ICC) for scores and their 95% confidence interval are computed with Stata's {help icc} command.
+
+{marker repet_options}{...}
+{phang}{it:repet_options} display information about reproducibility of items. The {opt kap:pa} option computes kappa statistic for items with Stata's {help kap} command. The {opt ickap:pa(#)} option computes
+confidence intervals for
+kappa statistics using {help kapci}. # is the number of replications for bootstrap used to estimate confidence intervals if items are polytomous. If they are dichotomous, an analytical method is used. See {help kapci} for more details about
+calculation of
+confidence intervals for kappa's
+coefficients. If the {opt kappa} option is absent then the {opt ickappa(#)} option is ignored. {opt scores2}({it:varlist}) allows selecting scores at time 2 from the dataset. 
+
+{phang}{opt kgv(varlist)} assesses known-groups validity according to the grouping variables defined in {it:varlist}. The option performs an ANOVA which compares the scores between groups of individuals, constructed with variables in {it:varlist}.       
+
+{marker kgv_options}{...}
+{phang}{it:kgv_options} allow displaying graphs for known-groups validity. The {opt kgvb:oxplots} option draws boxplots of the scores split into groups of individuals. The {opt kgvg:roupboxplots} option groups
+all boxplots in one graph. If {opt kgvboxplots} is absent then the {opt kgvgroupboxplots} option is ignored.  
+
+{phang}{opt conc(varlist)} assesses concurrent validity with variables precised in {it:varlist}. These variables are scores from one or several other scales.  
+
+{marker conc_options}{...}
+{phang}{it:conc_options} allow specifying options for concurrent validity. The {opt tc:onc(#)} option defines a threshold for correlation coefficients between the computed scores and the scores of other scales defined in {it:varlist}. Correlation
+coefficients greater than # (0.4 by default) are displayed in bold.
+
+
+{marker examples}{...}
+{title:Examples}
+
+{phang2}{cmd:. validscale item1-item20, part(5 4 6 5)}{p_end}
+
+{phang2}{cmd:. validscale item1-item20, part(5 4 6 5) imp graphs cfa cfastand cfacovs(item1*item3 item5*item7 item17*item18) convdiv convdivboxplots kgv(factor_variable) kgvboxplots conc(scoreA-scoreD)}{p_end}
+
+{phang2}{cmd:. validscale item1-item20, part(5 4 6 5) imp scores(s1-s4) rep(item1bis-item20bis) scores2(s1bis-s4bis) kappa}{p_end}
+
+
+{marker alsosee}{...}
+{title:Also see}
+
+{p 4 13 2}help for {help alpha}, {help delta}, {help loevh}, {help icc}, {help kapci}.{p_end}
diff --git a/Modules/ado/personal/v/validscale.sthlp b/Modules/ado/personal/v/validscale.sthlp
new file mode 100644
index 0000000..5ad9ca0
--- /dev/null
+++ b/Modules/ado/personal/v/validscale.sthlp
@@ -0,0 +1,207 @@
+{smcl}
+{* 2013}{...}
+{hline}
+help for {hi:validscale}{right:Bastien Perrot}
+{hline}
+
+{title:Syntax}
+
+{p 8 14 2}{cmd:validscale} {it:varlist}, {opt part:ition}({it:numlist}) [{it:options}]
+
+{p 4 4 2}{it:varlist} contains the variables (items) used to compute the scores. The first items of {it:varlist} compose the first dimension, the following items define the second dimension, and so on.
+
+{p 4 4 2}{cmd:partition} allows defining in {it:numlist} the number of items in each dimension.
+
+
+{synoptset 20 tabbed}{...}
+{synopthdr}
+{synoptline}
+{syntab:Options}
+{synopt : {opt scoren:ame(string)}}define the names of the dimensions{p_end}
+{synopt : {opt scores(varlist)}}use scores from the dataset{p_end}
+{synopt : {opt cat:egories(numlist)}}define minimum and maximum response categories for the items{p_end}
+{synopt : {opt imp:ute(method)}}impute missing item responses{p_end}
+{synopt : {help validscale##impute_options:{it:impute_options}}}options for imputation of missing data {p_end}
+{synopt : {opt comps:core(method)}}define how scores are computed{p_end}
+{synopt : {opt desc:items}}display a descriptive analysis of items and dimensions{p_end}
+{synopt : {opt graph:s}}display graphs for items description{p_end}
+{synopt : {opt cfa}}assess structural validity of the scale by performing a confirmatory factor analysis (CFA){p_end}
+{synopt : {help validscale##cfa_options:{it:cfa_options}}}options for confirmatory factor analysis (CFA){p_end}
+{synopt : {opt conv:div}}assess convergent and divergent validities assessment{p_end}
+{synopt : {help validscale##convdiv_options:{it:conv_div_options}}}options for convergent and divergent validities{p_end}
+{synopt : {help validscale##reliability_options:{it:reliability_options}}}options for reliability assessment{p_end}
+{synopt : {opt rep:et(varlist)}}assess reproducibility of scores and items{p_end}
+{synopt : {help validscale##repet_options:{it:repet_options}}}options for reproducibility{p_end}
+{synopt : {opt kgv(varlist)}}assess known-groups validity by using qualitative variable(s){p_end}
+{synopt : {help validscale##kgv_options:{it:kgv_options}}}options for known-groups validity assessment{p_end}
+{synopt : {opt conc(varlist)}}assess concurrent validity{p_end}
+{synopt : {help validscale##conc_options:{it:conc_options}}}options for concurrent validity assessment{p_end}
+{synopt : {opt * }}options from {help sem_estimation_options} command (additional estimation options for {help validscale##cfa_options:{it:cfa_options}}) {p_end}
+
+
+{p2colreset}{...}
+
+
+{title:Description}
+
+{phang}{cmd:validscale} assesses validity and reliability of a multidimensional scale. Elements to provide
+structural validity, convergent and divergent validity, reproducibility, known-groups validity, internal consistency, scalability and sensitivity are computed. {cmd:validscale} can be used with a dialog box by typing {stata db validscale}.
+
+{marker options}{...}
+{title:Options}
+
+{dlgtab:Options}
+
+{phang}{opt scoren:ame(string)} allows defining the names of the dimensions. If the option is not used, the dimensions are named {it:Dim1}, {it:Dim2},... unless {opt scores(varlist)} is used. 
+
+{phang}{opt scores(varlist)} allows selecting scores from the dataset. {opt scores(varlist)} and {opt scorename(string)} cannot be used together.
+
+{phang}{opt cat:egories(numlist)} allows specifying the minimum and maximum possible values for items responses. If all the items have the same response
+categories, the user may specify these 2 values in {it:numlist}. If the items response categories differ from a dimension to another, the user must define the possible minimum and maximum values of items responses for each
+dimension. So the number of elements in {it:numlist} must be equal to the number of dimensions times 2. Eventually, the user may specify the minimum and maximum response categories for each item. In this case, the
+number of elements in {it:numlist} must be equal to the number of items times 2. By default, the minimum and maximum values are assumed to be the minimum and maximum for each item.      
+
+{marker impute_options}{...}
+{phang}{opt imp:ute(method)} imputes missing items responses with Person Mean Substitution ({bf:pms}) or Two-way imputation method applied in each dimension ({bf:mi}). With PMS method, missing data are imputed only if the number of
+missing values in the dimension is less than half the number of items in the dimension. 
+
+{phang2} By default, imputed values are rounded to the nearest whole number but with the {opt nor:ound} option, imputed values are not rounded. If {opt impute} is absent then {opt noround} is ignored.
+
+{phang}{opt comp:score(method)} defines the method used to compute the scores. {it:method} may be either {bf:mean} (default), {bf:sum} or {bf:stand}(set scores from 0 to 100). {opt comp:score(method)} is ignored
+if the {opt scores(varlist)} option is used.
+
+{phang}{opt desc:items} displays a descriptive analysis of the items. This option displays missing data rate per item and distribution of item responses. It also computes for each item the Cronbach's alphas
+obtained by omitting each item in each dimension. Moreover, the option computes Loevinger's Hj coefficients and the number of non-significant Hjk. See {help loevh} for details about Loevinger's coefficients.     
+
+{phang}{opt graph:s} displays graphs for items and dimensions descriptive analyses. It provides histograms of scores, a biplot of the scores and a graph showing the correlations between the items.
+
+{marker cfa_options}{...}
+{phang}{opt cfa} performs a Confirmatory Factor Analysis (CFA) using {help sem} command. It displays estimations of parameters and several goodness-of-fit indices.
+
+{phang2} {opt cfam:ethod}({it:method}) specifies the method to estimate the parameters. {it:method} may be either {bf:ml} (maximum
+likelihood), {bf:mlmv} ({bf:ml} with missing values) or {bf:adf} (asymptotic distribution free). 
+
+{phang2} {opt cfasb} produces Satorra-Bentler adjusted goodness-of-fit indices using the vce(sbentler) option from sem ({help sem_option_method##vcetype})
+
+{phang2} {opt cfas:tand} displays standardized coefficients.
+
+{phang2} {opt cfanocovd:im} asserts that the latent variables are not correlated.
+
+{phang2} {opt cfac:ovs} option allows adding covariances between measurement errors. The syntax cfacov(item1*item2)
+allows estimating the covariance between the errors of item1 and item3. To specify more than one covariance, the form of the syntax is cfacov(item1*item2 item3*item4).
+
+{phang2} {opt cfar:msea(#)} option allows adding automatically the covariances between measurement errors found
+with the estat mindices command until the RMSEA (Root Mean Square Error
+of Approximation) of the model is less than #. More precisely, the "basic" model
+(without covariances between measurement errors) is estimated then we add the covariance corresponding to the greatest modification index and the model is re-
+estimated with this extra-parameter, and so on. The option only adds the covari-
+ances between measurement errors within a dimension and can be combined with
+cfacov. The specified value # may not be reached if all possible within-dimension
+measurement errors have already been added.
+
+{phang2} {opt cfacf:i(#)} option allows adding automatically the covariances between measurement errors found with
+the estat mindices command until the CFI (Comparative Fit Index) of the model
+is greater than #. More precisely, the "basic" model (without covariances between
+measurement errors) is estimated then we add the covariance corresponding to the
+greatest modification index and the model is re-estimated with this extra-parameter,
+and so on. The option only adds the covariances between measurement errors within
+a dimension and can be combined with cfacov. The specified value # may not
+be reached if all possible within-dimension measurement errors have already been
+added.
+
+{phang2} {opt cfaor} option is useful when both {opt cfar:msea} and {opt cfacf:i} are used. By default, covariances between measurement errors are added and the model is estimated until both RMSEA
+and CFI criteria are met. If cfaor is used, the estimations stop when one of the two
+criteria is met.
+
+{phang2} {opt *} options from {help sem_estimation_options} (e.g. {opt iterate(#)}, {opt vce(vcetype)}, etc.)
+
+{marker convdiv_options}{...}
+{phang}{opt conv:div} assesses convergent and divergent validities. The option displays the matrix of correlations between items and rest-scores. If {opt scores(varlist)} is used, then the correlations coefficients are computed between
+items and scores of {opt scores(varlist)}. 
+
+{phang2} {opt tconv:div(#)} defines a threshold for highlighting some values. # is a real number between 0 and 1 which is equal to 0.4 by
+default. Correlations between items and their own score are displayed
+in red if it is less than #. Moreover, if an item has a smaller correlation coefficient with the score of its own dimension than the correlation coefficient computed with other scores, this coefficient is displayed
+in red. 
+
+{phang2} {opt convdivb:oxplots} displays boxplots for assessing convergent and divergent validities. The boxes represent the correlation coefficients between the items of a given dimension and all scores. Thus the
+box of correlation coefficients between items of a given dimension and the corresponding score must be higher than other boxes. There are as many boxplots as dimensions.
+
+{marker reliability_options}{...}
+{phang}{it:reliability_options} allow defining the thresholds for reliability and scalability indices. 
+
+{phang2} {opt a:lpha(#)} defines a threshold for Cronbach's alpha (see {help alpha}). # is a real number between 0 and 1 which is equal to 0.7
+by default. Cronbach's alpha coefficients less than # are printed in red.
+
+{phang2} {opt d:elta(#)} defines a threshold for Ferguson's delta coefficient (see {help delta}). Delta coefficients are computed only if {opt compscore}({it:sum}) is used
+and {opt scores}({it:varlist)} is not used. # is a real number between 0 and 1 which is equal to 0.9
+by default. Ferguson's delta coefficients less than # are printed in red.
+
+{phang2} {opt h(#)} defines a threshold for Loevinger's H coefficient (see {help loevh}). # is a real number between 0 and 1 which is equal to
+0.3 by default. Loevinger's H coefficients less than # are printed in red. 
+
+{phang2} {opt hj:min(#)} defines a threshold for Loevinger's Hj coefficients. The displayed value is the minimal Hj coefficient for a item in the dimension. (see {help loevh}). # is a real number between 0 and 1 which is equal to
+0.3 by default. If the minimal Loevinger's Hj coefficient is less than # then it is printed in red and the corresponding item is displayed.
+
+{marker repet_options}{...}
+{phang}{opt rep:et(varlist)} assesses reproducibility of scores by defining in {it:varlist} the variables corresponding to responses at time 2 (in the same order than for time 1). Scores are computed according to
+the {opt partition()} option. Intraclass
+Correlation Coefficients (ICC) for scores and their 95% confidence interval are computed with Stata's {help icc} command.
+
+{phang2} {opt kap:pa} computes kappa statistic for items with Stata's {help kap} command. 
+
+{phang2} {opt ickap:pa(#)} computes confidence intervals for kappa statistics using {help kapci}. # is the number of replications for bootstrap used to estimate confidence intervals if items are polytomous. If they are dichotomous, an analytical method is used. See {help kapci} for more details about
+calculation of confidence intervals for kappa's coefficients. If the {opt kappa} option is absent then {opt ickappa(#)} is ignored. 
+
+{phang2} {opt scores2}({it:varlist}) allows selecting scores at time 2 from the dataset. 
+
+{phang}{opt kgv(varlist)} assesses known-groups validity according to the grouping variables defined in {it:varlist}. The option performs an ANOVA which compares the scores between groups of individuals, constructed with variables in {it:varlist}. A p-value based on a Kruskal-Wallis test is also given.       
+
+{marker kgv_options}{...}
+
+{phang2} {opt kgvb:oxplots} draws boxplots of the scores split into groups of individuals. 
+
+{phang2} {opt kgvg:roupboxplots} groups all boxplots into one graph. If {opt kgvboxplots} is absent then the {opt kgvgroupboxplots} option is ignored.
+
+{phang}{opt conc(varlist)} assesses concurrent validity with variables precised in {it:varlist}. These variables are scores from one or several other scales.  
+
+{marker conc_options}{...}
+{phang2} {opt tc:onc(#)} defines a threshold for correlation coefficients between the computed scores and the scores of other scales defined in {it:varlist}. Correlation
+coefficients greater than # (0.4 by default) are displayed in bold.
+
+{marker examples}{...}
+{title:Examples}
+
+{phang2}{cmd:. validscale item1-item20, part(5 4 6 5)}{p_end}
+
+{phang2}{cmd:. validscale item1-item20, part(5 4 6 5) imp graphs cfa cfastand cfacovs(item1*item3 item5*item7 item17*item18) convdiv convdivboxplots kgv(factor_variable) kgvboxplots conc(scoreA-scoreD)}{p_end}
+
+{phang2}{cmd:. validscale item1-item20, part(5 4 6 5) imp scores(s1-s4) rep(item1bis-item20bis) scores2(s1bis-s4bis) kappa}{p_end}
+
+{title:References}
+
+{phang}Blanchette, D. 2010. LSTRFUN: Stata module to modify long local macros. {it:Statistical Software Components}, Boston College Department of Economics.
+
+{phang}Gadelrab, H. 2010. {it:Evaluating the fit of structural equation models: Sensitivity to specification error and descriptive goodness-of-fit indices.} Lambert Academic Publishing.
+
+{phang}Hamel, J.-F. 2014. MI TWOWAY: Stata module for computing scores on questionnaires containing missing item responses. {it:Statistical Software Components}, Boston College Department of Economics.
+
+{phang}Hardouin, J.-B. 2004. LOEVH: Stata module to compute Guttman errors and Loevinger H coeficients. {it:Statistical Software Components}, Boston College Department of Economics.
+
+{phang}Hardouin, J.-B. 2007. DELTA: Stata module to compute the Delta index of scale discrimination. {it:Statistical Software Components}, Boston College Department of Economics.
+
+{phang}Hardouin, J.-B. 2013. IMPUTEITEMS: Stata module to impute missing data of binary items.
+
+{phang}Hardouin, J.-B., A. Bonnaud-Antignac, V. Sbille, et al. 2011. Nonparametric item response theory using Stata. {it:Stata Journal} 11(1): 30.
+
+{phang}Reichenheim, M. E. 2004. Confidence intervals for the kappa statistic. {it:Stata Journal} 4(4): 421{428(8).
+
+{title:Author}
+
+{phang}Bastien Perrot, EA 4275 SPHERE, "methodS in Patient-centered outomes and HEalth ResEarch", University of Nantes, France
+{browse "mailto:bastien.perrot@univ-nantes.fr":bastien.perrot@univ-nantes.fr}{p_end}
+
+{marker alsosee}{...}
+{title:Also see}
+
+{p 4 13 2}help for {help alpha}, {help delta}, {help loevh}, {help icc}, {help kapci}.{p_end}
diff --git a/Modules/ado/personal/v/validscaleXX.ado b/Modules/ado/personal/v/validscaleXX.ado
new file mode 100644
index 0000000..4e41ed0
--- /dev/null
+++ b/Modules/ado/personal/v/validscaleXX.ado
@@ -0,0 +1,2668 @@
+
+*! version 1.2  July 02, 2014
+*! Bastien Perrot, Jean-Benoit Hardouin, Emmanuelle Anthoine
+*************************************************************************************************************
+* Stata program : validscale
+* Assess validity and reliability of a multidimensional measurement scale using CTT methods
+*
+* Historic:
+* Version 1 (2013-06-20): [Bastien Perrot, Jean-Benoit Hardouin, Emmanuelle Anthoine]
+* Version 1.1 (2014-05-13) : [Bastien Perrot, Jean-Benoit Hardouin, Emmanuelle Anthoine] /* Method for IMPUTE option (PMS or Two-way) */
+* Version 1.2 (2014-07-02) : [Bastien Perrot, Jean-Benoit Hardouin, Emmanuelle Anthoine] /* CFA: Standard error for the intercepts, IMPUTE: correction of a bug with MI option, minor corrections*/
+*
+* Required modules :
+* delta
+* loevh
+* kapci
+* mi_twoway
+* detect2
+* imputeitems
+* lstrfun
+*************************************************************************************************************
+
+program define validscale , rclass
+syntax varlist [if], PARTition(numlist integer >0) [HTML(string) MODalities(numlist) SCOREName(string) scores(varlist) IMPute(string) NORound COMPScore(string) DESCitems GRAPHs cfa CFAMethod(string) CFAStand CFACov(string) CFAAuto CONVdiv TCONVdiv(real 0.4) CONVDIVBoxplots Alpha(real 0.7) Delta(real 0.9) h(real 0.3) HJmin(real 0.3) REPet(varlist) scores2(varlist) KAPpa ICKAPpa(integer 0) kgv(varlist) KGVBoxplots KGVGroupboxplots conc(varlist) tconc(real 0.4)]
+preserve
+
+if "`if'"!="" {
+   qui keep `if'
+}
+
+if "`html'" != "" {
+   global html = "`html'"
+   set scheme sj
+   local htmlregion  "graphregion(fcolor(white) ifcolor(white))"
+   local xsize=6
+   local ysize=4
+   di in gr ""
+   di "
" + di "
"
+}   
+
+if "`modalities'" == "" {
+	foreach v in `varlist' {
+		tempvar min max
+		egen `min' = min(`v')
+		egen `max' = max(`v')
+		local mi = `min' 
+		local ma = `max'
+		local m `mi' `ma'
+		local modalities `modalities' `m'
+	}
+}
+
+global modalities = "`modalities'"
+global compscore = "`compscore'"
+if "$compscore" == "" global compscore = "mean"
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+
+local nbvars : word count `varlist' 
+
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit 119
+}
+
+
+if "`repet'" != "" {
+	local b:word count `repet'
+	if `nbvars' != `b' {
+		di in red "The number of items in varlist is different from the number of items in repet"
+		exit 119
+	}
+}
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+local P:word count `partition'
+local S:word count `scorename'
+
+if "`scores'" != "" & "`scorename'" != "" {
+	di in red "scorenames() and scores() cannot be used together"
+	exit 119
+}  
+
+if "`scorename'" != "" {
+	if `P'!=`S' {
+		di in red "The number of score names given is different from the number of dimensions in the partition option" 
+		exit 119
+	}
+	foreach sco in `scorename' {
+		capture confirm variable `sco', exact
+		if !_rc {
+			di in red "`sco' already defined. You must choose names that do not already exist or use the scores() option if the scores are already defined."
+			exit 119
+	    }
+		tokenize `scorename'
+		local g = 0
+		forvalues i = 1/`S' {
+			if "`sco'" == "``i''" {
+				local `++g'
+			}
+		}
+		if `g' > 1 {
+			di in red "2 or more dimensions have the same name"
+			exit 119
+		}
+	}
+		calcscore `varlist', scorename(`scorename') partition(`partition') compscore(`compscore') modalities(`modalities')
+		global exist = 0
+		global scorename = "`scorename'"
+}
+
+else if "`scorename'" == "" & "`scores'" == ""{
+
+	local name
+	local nname
+	
+	forvalues i = 1/`P' {
+	
+		local name "Dim`i'"
+		local nname `nname' `name'
+	}
+	
+	local scorename = "`nname'"
+	global scorename = "`nname'"
+	calcscore `varlist', scorename(`scorename') partition(`partition') compscore(`compscore') modalities(`modalities')
+	global exist = 0
+}
+
+else if "`scores'" != "" {
+	local P:word count `partition'
+	local S2:word count `scores'
+	if `P'!=`S2' {
+		di in red "The number of score names given is different from the number of dimensions in the partition option" 
+		exit 119
+	}
+	else {
+		global scorename = "`scores'"
+		local scorename = "`scores'"
+		global exist = 1
+		
+	}
+	
+}
+
+local nbm : word count $modalities
+if `nbm' !=2 &`nbm' !=`P'*2 &`nbm' !=`nbvars'*2 { 
+	di in red "option modalities() misspecified. You must enter either 2 or `=`nbvars'*2' or `=`P'*2' elements"
+	exit 119
+}
+
+if `nbm' == 2{
+	tokenize $modalities
+	foreach v in `varlist' {
+		tempvar min
+		tempvar max
+		egen `min' = min(`v')
+		egen `max' = max(`v')
+		if `min' < `1' {
+			di in red "error in option modalities() : some responses have smaller values than the minimum value in modalities()"
+			exit 119
+		} 
+		if `max' > `2' {
+			di in red "error in option modalities() : some responses have greater values than the maximum value in modalities()"
+			exit 119
+		} 
+	}
+}
+
+if `nbm' == `nbvars'*2 {
+	local i = 1
+	foreach v in `varlist' {
+		tempvar min max
+		egen `min' = min(`v')
+		egen `max' = max(`v')
+		local mi = `min' 
+		local ma = `max'
+		tokenize $modalities
+		if `mi' < ``i'' {
+			di in red "error in option modalities() : some responses have values less than the minimum value specified for the variable in modalities()"
+			exit 119
+		}
+	local `++i'
+	tokenize $modalities
+		if `ma' > ``i'' {
+			di in red "error in option modalities() : some responses have values greater than the maximum value specified for the variable in modalities()"
+			exit 119
+		}
+	local `++i'
+	}
+} 
+
+if `nbm' == `P'*2 {
+	local i = 1
+	local y = 1
+	
+	foreach x in `partition' {
+		//local `i++' 
+		if `i' == 1 local s = `x'
+		else local s = `s' +`x'
+		forvalues w = `y'/`s' {
+			tokenize $modalities
+			tempvar min max
+			egen `min' = min(`var`w'')
+			egen `max' = max(`var`w'')
+			local mi = `min' 
+			local ma = `max'
+			if `mi' < ``i'' {
+				di in red "error in option modalities() : some responses have values less than the minimum value specified"
+				exit 119
+			}
+			local j = `i'+1
+			tokenize $modalities
+			if `ma' > ``j'' {
+				di in red "error in option modalities() : some responses have values greater than the maximum value specified"
+				exit 119
+			}
+			
+		}
+		local i = `i'+2
+		local y = `s'+1
+	}
+}
+
+if "`cfa'" != "" {
+	if "`cfacov'" != "" {
+		if !strpos("`cfacov'", "*") { 
+			di "error in cfacov() option : you must enter covariances between errors as follows: item3*item5 item7*item8 ...  "
+		exit 119
+	}
+		local v = subinstr("`cfacov'","*"," ",.)
+		foreach var in `v' {
+			capture confirm variable `var'
+			if _rc {
+				di in red "error in cfacov() option : `var' is not a variable from the dataset"
+				exit 119
+			}
+		}
+	}
+}
+
+if "`kgv'" !="" {
+	foreach k in `kgv' {
+		capture confirm variable `k'
+		if _rc!=0 {
+			di in red "`k' does not exist" 
+			exit 119
+		}
+    }
+}
+
+if "`conc'" !="" {
+	foreach c in `conc' {
+		capture confirm variable `c'
+		if _rc!=0 {
+			di in red "`c' does not exist" 
+			exit 119
+		}
+    }
+}
+
+di as result "Items used to compute the scores"
+di
+
+local i = 1
+local j = 1
+local y = 1
+foreach p in `partition' {
+	tokenize `scorename'
+	di "{bf:``i''} : " _c
+	
+	if `j' == 1 local s = `p'
+	else local s = `s' +`p'
+	forvalues z = `y'/`s' {
+		di "{text:`var`z'' }" _c
+	}
+	local `i++' 
+	local `j++' 
+	local y = `s'+1
+	di
+}
+
+di
+di as result "Number of observations: " _c
+di as text _N
+
+qui destring _all, replace
+di
+
+if "`descitems'" != "" {
+	di as result "{hline 105}"
+	di "Description of items"
+	di as result "{hline 105}"
+	di
+	descitems `varlist', partition(`partition')
+	di
+}
+
+
+if "`graphs'" != "" {
+	graphs `varlist', partition(`partition')
+}						
+
+
+if "`repet'" != "" {
+	if "`descitems'" != "" {
+		di as result "{hline 105}"
+		di "Description of items (time 2)"
+		di as result "{hline 105}"
+		di
+		descitems `repet', partition(`partition')
+		di
+	}
+}
+
+if "`impute'" != "" {
+	if "`impute'" != "pms" & "`impute'" !="mi" {
+		di in red "option impute() incorrectly specified. You must specify {hi:pms} or {hi:mi}."
+		error 100
+	}
+	if "`impute'" == "pms" {
+		pms `varlist', partition(`partition') `noround'
+		if "`descitems'" != "" {
+			di as result "{hline 105}"
+			di "Description of items after missing data handling (PMS imputation)"
+			di as result "{hline 105}"
+			di
+			descitems `varlist', partition(`partition')
+			di
+		}
+		if "`repet'" != "" {
+			pms `repet', partition(`partition') `noround'
+			if "`descitems'" != "" {
+				di as result "{hline 105}"
+				di "Description of items after missing data handling (time 2)"
+				di as result "{hline 105}"
+				di
+				descitems `repet', partition(`partition')
+				di
+			}
+		}
+	}
+	if "`impute'" == "mi" {
+		mitw `varlist', partition(`partition') `noround' 
+		if "`descitems'" != "" {
+			di as result "{hline 105}"
+			di "Description of items after missing data handling (mi two-way imputation)"
+			di as result "{hline 105}"
+			di
+			descitems `varlist', partition(`partition')
+			di
+		}
+		if "`repet'" != "" {
+			mitw `repet', partition(`partition') `noround'
+			if "`descitems'" != "" {
+				di as result "{hline 105}"
+				di "Description of items after missing data handling (time 2)"
+				di as result "{hline 105}"
+				di
+				descitems `repet', partition(`partition')
+				di
+			}
+		}
+	}
+}  
+
+rel `varlist', scorename(`scorename') partition(`partition') alpha(`alpha') delta(`delta') h(`h') hjmin(`hjmin') modalities(`modalities')
+di
+
+if "`convdiv'" != "" {
+	convdiv `varlist', partition(`partition') tconvdiv(`tconvdiv') `convdivboxplots'
+	di
+}
+
+if "`cfa'" != "" {
+	cfa `varlist', partition(`partition') cfamethod(`cfamethod') `cfastand' cfacov(`cfacov') `cfaauto'
+	di
+}
+
+if "`repet'" != "" | "`scores2'" != "" {
+	global scores2 = "`scores2'"
+	repet `varlist', t2(`repet') partition(`partition') `kappa' ickappa(`ickappa')
+	di
+}
+
+if "`kgv'" != "" {
+	kgv `scorename', categ(`kgv') `kgvboxplots' `kgvgroupboxplots'
+	di
+}
+
+if "`conc'" != "" {
+	conc `scorename', comp(`conc') tconc(`tconc')
+}
+
+
+//capture restore, not
+end
+
+
+/* pms */
+
+capture program drop pms
+program pms
+syntax varlist, PARTition(numlist integer >0) [NORound]
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit
+}
+
+local i = 1
+local y = 1
+
+tokenize `varlist'
+foreach x in `partition' {
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' ``w'' 
+	}
+	
+	local n : word count `liste' 
+	if mod(`n',2)!=0 local max = floor(`n'/2)
+	else local max = `n'/2-1
+	
+	if "`noround'" != "" {
+		qui imputeitems `liste', method(pms) max(`max') noround 
+		foreach var of varlist `liste' {
+			qui replace `var' = imp`var'
+			qui drop imp`var'
+		}
+	}
+	else {
+		qui imputeitems `liste', method(pms) max(`max')
+		foreach var of varlist `liste' {
+			qui replace `var' = imp`var'
+			qui drop imp`var'
+		}
+	}
+	
+	local `i++' 
+	local y = `s'+1
+}
+
+end
+
+
+/* mitw */
+
+capture program drop mitw
+program mitw
+syntax varlist, PARTition(numlist integer >0) [NORound]
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit
+}
+
+local i = 1
+local y = 1
+
+
+foreach x in `partition' {
+	tokenize `varlist'
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' ``w'' 
+	}
+		
+	qui mi_twoway `liste', scorename(scoretmp) add(1) style(wide) clear  
+		
+	foreach var of varlist `liste' {
+		qui replace `var' = _1_`var'
+		if "`noround'" == "" {
+			qui replace `var' = round(`var')
+		}
+		/*if `var' > `maxm' {
+			qui replace `var' = `maxm'
+		}
+		if `var' < `minm' {
+			qui replace `var' = `minm'
+		}*/
+		qui drop _1_`var'
+		capture drop scoretmp
+		capture drop _1_scoretmp
+	}
+		
+	local `i++' 
+	local y = `s'+1
+}
+
+//capture drop _mi_miss
+qui mi unset
+end
+
+
+/*  calcscore */
+
+capture program drop calcscore
+program calcscore,rclass
+syntax varlist, PARTition(numlist integer >0) [modalities(numlist) COMPscore(string) SCOrename(string)]
+
+local P:word count `partition'
+local S:word count `scorename'
+		
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit
+}
+
+if "`scorename'" != "" {
+	if `P'!=`S' {
+		di in red "The number of score names given is different from the number of dimensions in the partition option" 
+		exit 119
+	}
+}
+
+local i = 1
+local y = 1
+foreach x in `partition' {
+	tokenize `varlist'
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' ``w'' 
+	}
+	
+	tempvar nonmiss
+	qui egen `nonmiss' = rownonmiss(`liste')
+		
+	tokenize `scorename'
+	local sc = "``i''"
+
+	if "`compscore'" == "" local compscore = "mean"
+
+	if "`compscore'" != "mean" & "`compscore'" != "sum" & "`compscore'" != "stand" {
+		di in red "option compscore incorrectly specified (choose among mean, sum and stand)"
+		error 198
+	}
+	
+	if "`compscore'" == "sum" {
+		qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2
+		qui replace `sc' = `sc'*`x'
+		
+	}
+	
+	else if "`compscore'" == "stand" {
+	
+		local nbm:word count `modalities'
+		
+		local nbl:word count `liste'
+		tokenize `modalities'
+	
+		if `nbm' == 2 {
+			local min = `1'*`nbl'
+			local max = `2'*`nbl'
+		}
+	
+		else if `nbm' == `P'*2 {
+			local min = ``b''*`nbl'
+			local max = ``=`b'+1''*`nbl'
+			
+		}
+	
+		else if `nbm' == `nbvars'*2 {
+			if `y'==1 local yy = 1
+			else local yy = `y'*2-1
+			local bb = `yy'
+			local min = 0
+			local max = 0
+		
+			forvalues bb = `yy'(2)`=`s'*2' {
+				local tpmin = ``bb''
+				local tpmax = ``=`bb'+1''
+				local min = `min'+`tpmin'
+				local max = `max'+`tpmax'
+			}
+		}
+			
+		else {
+			di in red "option modalities() misspecified. You must enter either 2 or `=`nbvars'*2' or `=`P'*2' elements"
+			exit 119
+		}
+				
+		qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2
+		qui replace `sc' = `sc'*`nonmiss'
+		qui replace `sc' = (`sc'-`min')/(`max'-`min')*100
+	}
+	
+	else {
+		qui egen `sc' = rowmean(`liste') if `nonmiss' >= `x'/2
+	}
+
+local `i++' 
+local y = `s'+1
+}
+
+end
+
+
+
+/* rel */
+
+capture program drop rel
+program rel,rclass
+syntax varlist, PARTition(numlist integer >0) [MODalities(numlist) SCOrename(string) Alpha(real 0.7) Delta(real 0.9) h(real 0.3) HJmin(real 0.3)]
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit
+}
+
+local P:word count `partition'
+if "`scorename'" !="" {
+	local S:word count `scorename'
+	if `P'!=`S' {
+		di in red "The number of score names given is different from the number of dimensions in the partition option" 
+		exit
+	}
+}
+di as result "{hline 105}"
+di "{bf:Reliability}" 
+di as result "{hline 105}"
+di
+
+local y = 1
+local nbitems = 0
+matrix aa = J(`P',4,.)
+
+foreach z in `partition' {
+	local nbitems = `nbitems' + `z'
+}
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+matrix d = J(`nbitems',2,.)
+
+local i = 1
+local b = 1
+foreach x in `partition' {
+	
+	tokenize `scorename'
+	
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' `var`w'' 
+	}
+	
+	capture alpha `liste', asi item std
+	local al`i' = r(alpha)
+			
+	capture qui loevh `liste', pairwise 
+	local h`i' = r(loevH)
+	matrix c = r(loevHj)	
+	matrix ct = c'
+		
+	
+	local lister = ""
+	forvalues w = `y'/`s' {
+		tempvar z
+		qui gen `z' = round(`var`w'')
+		local lister `lister' `z' 
+	}
+	
+	tempvar nbmiss
+	local nbl : word count `lister'
+	egen `nbmiss' = rowmiss(`lister')
+	qui count if `nbmiss'<`nbl'
+	local n`i' = r(N)
+	
+	
+	// delta
+	
+	if ${exist} == 0 & "$compscore" == "sum" {
+	
+		local nbm:word count `modalities'
+		tokenize `modalities'
+		
+		if `nbm' == 2 {
+			local min = `1'*`nbl'
+			local max = `2'*`nbl'
+		}
+		
+		else if `nbm' == `P'*2 {
+			local min = ``b''*`nbl'
+			local max = ``=`b'+1''*`nbl'
+		}
+		
+		
+		else if `nbm' == `nbvars'*2 {
+			if `y'==1 local yy = 1
+			else local yy = `y'*2-1
+			local bb = `yy'
+			local min = 0
+			local max = 0
+			
+			forvalues bb = `yy'(2)`=`s'*2' {
+				local tpmin = ``bb''
+				local tpmax = ``=`bb'+1''
+				local min = `min'+`tpmin'
+				local max = `max'+`tpmax'
+				
+			}
+		}
+		
+		else {
+			di in red "option modalities() misspecified. You must enter either 2 or `=`nbvars'*2' or `=`P'*2' elements"
+			exit 119
+		}
+		
+		capture delta `lister', min(`min') max(`max')
+		local delt`i' = r(delta)
+	
+	}
+	
+	else local delt`i' = .
+		
+	local k = 0
+	forvalues j = `y'/`s' {
+		local k = `k'+1
+		matrix d[`j',1] = ct[`k',1]
+		matrix d[`j',2] = `i'
+	}
+	
+	matrix aa [`i',1] = `al`i''
+	matrix aa [`i',2] = `delt`i''
+	matrix aa [`i',3] = `h`i''
+	
+	local `i++' 
+	local y = `s'+1
+	
+	local b = `b'+2
+}
+
+matrix rownames d = `varlist'
+local i = 1
+local y = 1
+
+foreach x in `partition' {
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	matrix C = d[`y'..`s',1.]
+	local min`i' = C[1,1]
+	local n : rownames C
+	tokenize `n'
+	local t`i' = "`1'"
+	forvalues j = 1/`x' {
+		local t = "``j''"
+		if C[`j',1] <= `min`i'' {
+			local min`i' = C[`j',1] 
+			//di `min`i''
+			local t`i' = "``j''"
+			local itmin`i' = "``j''"
+			//di " `i' : `itmin`i''"
+		}
+	}
+	matrix aa [`i',4] = `min`i''
+	local `i++' 
+	local y = `s'+1
+}
+
+matrix colnames aa = "alpha" "delta" "H" "Hj_min"
+
+if "`scorename'"=="" {
+	local i = 1
+	local y = 1
+	local name
+	local nname
+	forvalues i = 1/`P' {
+		local name "Dim`i'"
+		local nname `nname' `name'
+	}
+local scorename = "`nname'"
+}	
+
+local maxlen = 0
+foreach sco in `scorename' {
+	local w = length("`sco'")
+	if `w' > `maxlen' local maxlen = `w'
+}
+
+local i = 1
+local j = 1
+local y = 1
+local col = `maxlen'+8
+
+di _col(`col') "{bf:n}" _c
+local col = `col'+6
+di _col(`col') "{bf:alpha}" _c
+local col = `col'+10
+di _col(`col') "{bf:delta}" _c
+local col = `col'+14
+di _col(`col') "{bf:H}" _c
+local col = `col'+5
+di _col(`col') "{bf:Hj_min}"
+
+foreach s in `scorename' {
+	di in blue "{bf:`s'}" _c
+	local col = `maxlen'+3
+	
+	local n : di %6.0f `n`i''
+	
+	di in blue _col(`col') "{text:`n'}" _c
+	local col = `col'+10
+	
+	local a : di %6.2f `al`i''
+	if `a' < `alpha' {
+		di _col(`col') "{error:`a'} " _c
+	}
+	else di _col(`col') "{text:`a'}" _c
+	
+	local col = `col'+10
+	local d : di %6.2f `delt`i''
+	if `d' < `delta' {
+		di _col(`col') "{error:`d'} " _c
+	}
+	else di _col(`col') "{text:`d'}" _c
+	
+	local col = `col'+10
+	local h : di %6.2f `h`i''
+	if `h' < `h' {
+		di _col(`col') "{error:`h'} " _c
+	}
+	else di _col(`col') "{text:`h'}" _c
+	
+	local col = `col'+8
+	local m : di %8.2f `min`i''
+	if `m' < `hjmin' {
+		di _col(`col') "{error:`m'} " _c
+		di "{text:(item `itmin`i'')}" _c
+	}
+	else di _col(`col') "{text:`m'}" _c
+	
+	di
+	local `++i'
+}
+
+end
+
+/* descitems */
+
+capture program drop descitems
+program descitems
+syntax varlist, PARTition(numlist integer >0)
+local i = 1
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+
+local nbvars : word count `varlist'
+
+if `C' != `nbvars' {
+	di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
+	exit 119
+}
+
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+foreach var in `varlist' {
+	qui replace `var' = round(`var')
+}
+
+local lev = ""
+foreach var in `varlist' {
+	qui levelsof `var', local(levels)
+	foreach l in `levels' {
+		if strpos("`lev'","`l'") == 0 {
+		local lev `lev' `l'	
+		}
+	}
+}
+
+_qsort_index `lev'
+local lev = r(slist1)
+
+local i = 1
+matrix d = J(`nbvars',4,.)
+
+foreach var in `varlist'{
+	qui count if missing(`var')
+	local ct=r(N)
+	
+	local tx`i'=`ct'/_N
+	matrix d[`i',1] = `tx`i''
+	local `i++'
+}
+
+matrix rownames d = `varlist'
+matrix colnames d = "missing" "alpha" "Hj" 
+
+local i = 1
+local y = 1
+foreach x in `partition' {
+	
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' `var`w'' 
+	}
+	
+	qui capture alpha `liste', asi item std
+	
+	mat a = r(Alpha)
+	mat at = a'
+	
+	qui capture loevh `liste', pairwise
+	matrix e = r(loevHj)	
+	matrix et = e'
+	matrix ns = r(nbHjkNS)	
+	matrix nst = ns'
+		
+	local k = 0
+	forvalues j = `y'/`s' {
+		local k = `k'+1
+		matrix d[`j',2] = at[`k',1]
+		matrix d[`j',3] = et[`k',1]
+		matrix d[`j',4] = nst[`k',1]
+		
+	}
+	local `i++' 
+	local y = `s'+1	
+}
+
+local i = 1
+foreach v in `varlist' {
+	local var`i' = abbrev("`v'",8)
+	local `++i'
+}
+
+local dec = 10
+local col = `dec'
+
+tokenize `varlist'
+local minm = `1'
+local maxm = `1'
+foreach mod in $modalities {
+	if `mod' < `minm' local minm = `mod'
+	if `mod' > `maxm' local maxm = `mod'
+}
+
+local b = `maxm'-`minm'+1
+
+local i = 1
+local j = 1
+local y = 1
+
+di in blue _col(`dec') "{bf:Missing}" _c
+local col = `col'+11
+di in blue _col(`=`col'+2') "{bf:N}" _c
+
+local col = `col'+9
+di _col(`col') "{bf:Response categories}" _c
+local col = `dec'+18+8*`b'
+di _col(`col') "{bf:Alpha}" _c
+local col = `col'+9
+di _col(`col') "{bf:Loevinger}" _c  
+local col = `col'+12
+di _col(`col') "{bf:Number of}" 
+
+local col = `dec'-1
+di _col(`col') "{bf:data rate}" _c
+local col = `dec'+18
+
+forvalues m = `minm'/`maxm' {
+	di _col(`=`col'+2') "`m'" _c
+	local col = `col'+8
+}
+
+di as result _col(`col') "- item" _c
+local col = `col'+10
+di as result _col(`col') "Hj coeff" _c 
+local col = `col'+12
+di as result _col(`col') "NS Hjk"  
+
+local ch = `dec'+18+8*`b'+29
+di "{hline `ch'}"
+
+local i = 1 
+foreach x in `varlist' {
+	local varo`i' = "`x'"
+	local `++i'
+}
+
+local y = 1
+foreach p in `partition' {
+	
+	if `j' == 1 local s = `p'
+	else local s = `s' +`p'
+	
+	forvalues z = `y'/`s' { 
+		local col = `dec'
+		di "{bf:`var`z''}" _c
+		local t = d[`z',1]
+		local t : di %8.2f `t'*100 
+		di _col(`col') "{text:`t'%}" _c
+		qui count if missing(`varo`z'')
+		local m = r(N)
+		local N = _N-`m'
+		local N : di %4.0f `N'
+		local col = `col'+10
+		di _col(`col') "{text:`N'}" _c
+		
+		local col = `col'+8
+		forvalues m = `minm'/`maxm' {
+			qui count if round(`varo`z'') == `m'
+			local n = r(N)
+			if `m' == `maxm' & round(`varo`z'')>`maxm' {
+				local n = `n' + 1
+			}
+			if `m' == `minm' & round(`varo`z'')<`minm' {
+				local n = `n' + 1
+			}
+			qui count if `varo`z'' != . 
+			local d = r(N)
+			local e = `n'/`d'
+			local e : di %4.2f `e'*100
+			if `e' != 0 di _col(`=`col'-1')"{text:`e'%}" _c
+			else di _col(`=`col'-1')"{text:   -}" _c
+			local col = `col'+8
+		}
+		local a = d[`z',2]
+		local a : di %4.2f `a'
+		di _col(`=`col'+1') "{text:`a'}" _c
+		local h = d[`z',3]
+		local h : di %5.2f `h'
+		local col = `col'+10
+		di _col(`=`col'+3') "{text:`h'}" _c
+		local ns = d[`z',4]
+		local ns : di %2.0f `ns'
+		local col = `col'+11
+		di _col(`=`col'+7') "{text:`ns'}" 
+			
+	}
+	local `i++' 
+	local `j++' 
+	local y = `s'+1
+	di "{dup `ch':-}" 
+}
+end
+
+
+capture program drop graphs
+program graphs
+syntax varlist, PARTition(numlist integer >0)
+
+//qui set autotabgraphs on
+local P:word count `partition'
+local html = "${html}"
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+if "$compscore" == "stand" local w = 10
+if "$compscore" == "sum" local b = 10
+if "$compscore" == "mean" local w = 0.5
+
+
+
+if "`html'"!="" {
+	//set graphics off
+	foreach s in $scorename {
+		qui local saving "saving(`c(tmpdir)'/`html'_`s',replace) nodraw"
+		qui hist `s', name(`s',replace) percent fcolor(emidblue) lcolor(none) width(`w') bin(`b') `saving'
+		qui graph use `c(tmpdir)'/`html'_`s'.gph
+		qui graph export `c(tmpdir)'/`html'_`s'.eps, replace
+		//di " _char(34) "
+
+	}
+	//set graphics on
+
+	
+	
+	qui local saving "saving(`c(tmpdir)'/`html'_group,replace) nodraw"
+	qui gr combine $scorename, name(group,replace) title("Distribution of scores") `saving'  
+	qui graph use `c(tmpdir)'/`html'_group.gph
+	qui graph export `c(tmpdir)'/`html'_group.eps, replace
+	di " _char(34) "
+
+	
+	qui local saving "saving(`c(tmpdir)'/`html'_scores,replace) nodraw"
+	qui biplot $scorename, name("Biplot_scores",replace) norow std title("Correlations between scores") xtitle("") ytitle("") `saving'
+	qui graph use `c(tmpdir)'/`html'_scores.gph
+	qui graph export `c(tmpdir)'/`html'_scores.eps, replace
+	di " _char(34) "
+}
+
+else {
+	set graphics off
+	foreach s in $scorename {
+		qui hist `s', name("`s'",replace) percent fcolor(emidblue) lcolor(none) width(`w') bin(`b')
+	}
+	set graphics on
+
+	gr combine $scorename, name("Histograms_scores",replace)  
+	capture biplot $scorename, name("Biplot_scores",replace) norow std title("") xtitle("") ytitle("")
+}
+
+
+
+capture biplot `varlist', name("temp",replace) norow std nograph
+
+mat a = r(V)
+
+tempvar a1 a2
+mat colnames a = `a1' `a2'
+svmat a, names(col)
+
+tempvar mina1 mina2 maxa1 maxa2
+egen `mina1' = min(`a1')
+egen `mina2' = min(`a2')
+egen `maxa1' = max(`a1')
+egen `maxa2' = max(`a2')
+local mina1 = `mina1'
+local mina2 = `mina2'
+local maxa1 = `maxa1'+1.4
+local maxa1x = `maxa1'+0.3
+local maxa2 = `maxa2'
+
+local colors = "red blue black green ebblue mint erose orange maroon magenta mint gray teal navy olive sienna"
+local i = 1
+foreach c in `colors' {
+	local col`i' = "`c'"
+	local `++i'
+}
+
+local i = 1
+local y = 1
+local c = 1
+local bas = `maxa2'+0.2
+local droite = max(`maxa1',0.2)
+
+foreach x in `partition' {
+	tokenize $scorename
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	forvalues j=`y'/`s' {
+		local a = `a1'[`j']
+		local b = `a2'[`j']	
+		local call `call' || pcarrowi 0 0 `b' `a' "`var`j''", mlabcolor(`col`i'') color(`col`i'') head   
+	}
+	local bas = `bas'-0.2
+	local call `call' text(`bas' `droite' "``i''", size(3) color(`col`i'')) /*`bas' `droite' "``i''", mlabcolor("`r' `g' `b'")*/
+	local `++i' 
+	local y = `s'+1	
+	local `++c' 
+}
+
+
+if "`html'" != "" {
+	qui local saving "saving(`c(tmpdir)'/`html'_items,replace) nodraw"
+	qui twoway `call' name("items",replace) legend(off) xscale(range(`mina1' `maxa1x')) yscale(range(`mina2' `maxa2')) title("Correlations between items") xtitle("") ytitle("") xsize(`xsize') ysize(`ysize') `saving'
+	qui graph use `c(tmpdir)'/`html'_items.gph
+	qui graph export `c(tmpdir)'/`html'_items.eps, replace
+	di " _char(34) "
+}
+else {
+	qui twoway `call' name("Biplot_items",replace) legend(off) xscale(range(`mina1' `maxa1x')) yscale(range(`mina2' `maxa2')) xtitle("") ytitle("")
+}
+
+
+							
+end
+
+/* convdiv */
+
+capture program drop convdiv
+program convdiv
+syntax varlist, PARTition(numlist integer >0) [TCONVdiv(real 0.4) convdivboxplots]
+preserve
+
+//qui set autotabgraphs on
+
+
+
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local nbvars : word count `varlist'
+local P:word count `partition'
+local cptdiv = 0
+local cptconv = 0
+
+if ${exist} != 1 {
+
+	qui detect2 `varlist', partition(`partition') 
+
+	matrix A = r(Corrrestscores)
+	matrix B = r(Corrscores)
+
+	local i = 1
+	local y = 1
+
+	foreach x in `partition' {
+		if `i' == 1 local s = `x'
+		else local s = `s' +`x'
+		
+		forvalues z = `y'/`s' {
+			matrix B[`z',`i'] = A[`z',`i']
+		}
+		local `i++' 
+		local y = `s'+1
+	} 
+
+	matrix colnames B = $scorename
+
+    local i = 1
+	foreach v in `varlist' {
+		local var`i' = abbrev("`v'",10)
+		local `++i'
+	}
+
+	local i = 1
+	foreach s in $scorename {
+		local s`i' = abbrev("`s'",7)
+		local sc `sc' `s`i''
+		local `++i'
+	}
+
+	di as result "{hline 105}"
+	di "{bf:Correlation matrix}"
+	di "{hline 105}"
+	di
+
+	local dec = 10
+	local col = `dec'
+
+	local decit = 14
+	local colit = `decit'
+
+
+	local col1 = `decit'
+	forvalues i=1/`P' {
+		di _col(`col1') "{bf:`s`i''}" _c
+		local col1 = `col1' + `dec'
+	}
+
+	di 
+	local h = (`P'-1)*`dec'+`decit'+4
+	di "{hline `h'}"
+
+	local i = 1
+	local j = 1
+	local y = 1
+
+	foreach p in `partition' {
+		if `j' == 1 local s = `p'
+		else local s = `s' +`p'
+		
+		forvalues z = `y'/`s' { 
+			di as text "{bf:`var`z''}" _c
+			local col = `decit'-1	
+			
+			local dd = `z' // [count cptdiv (one per item)] 
+			
+			forvalues k = 1/`P' { 
+					
+				local t = B[`z',`k']
+				local t : di %6.3f `t'
+				if `k' == `i' {
+					if `t' < `tconvdiv' {
+						/*if "${html}" != "" {
+							di "

" + di _col(`col') "{bf:`t'}" _c + di "

" + }*/ + //else { + di in red _col(`col') "{bf:`t'}" _c + //} + + local cptconv = `cptconv'+1 + local col = `col' + `dec' + } + else { + /*if "${html}" != "" { + di "

" + di as text _col(`col') "{bf:`t'}" _c + di "

" + }*/ + //else { + di as text _col(`col') "{bf:`t'}" _c + //} + local col = `col' + `dec' + } + } + else { + + if B[`z',`k'] > B[`z',`i'] { + /*if "${html}" != "" { + di "" + di in red _col(`col') "`t'" _c + di "" + }*/ + //else { + di in red _col(`col') "`t'" _c + //} + + if `dd' == `z' local cptdiv = `cptdiv'+1 // [one per item] + local dd = 0 + local col = `col' + `dec' + } + else { + /*if "${html}" != "" { + di "

" + di as text _col(`col') "{text:`t'}"_c + di "

" + }*/ + //else { + di as text _col(`col') "{text:`t'}"_c + //} + + local col = `col' + `dec' + } + } + } + di + } + di as text "{dup `h':-}" + local `i++' + local `j++' + local y = `s'+1 + } + + local y = 1 + local h = 1 + local np : word count `partition' + + foreach p in `partition' { + if `h' == 1 local s = `p' + else local s = `s' +`p' + + forvalues j = 1/`np' { + mat C_`h'_`j' = B[`y'..`s',`j'] + + tempvar tp_`h'_`j' + mat colnames C_`h'_`j' = `tp_`h'_`j'' + + svmat C_`h'_`j', names(col) + } + + local `++h' + local y = `s'+1 + } + +} + +else if ${exist} == 1 { + + di as result "{hline 105}" + di "{bf:Correlation matrix (without rest-scores)}" + di "{hline 105}" + di + + + local i = 1 + foreach v in `varlist' { + local var`i' = abbrev("`v'",10) + local `++i' + } + + local i = 1 + foreach s in $scorename { + local s`i' = abbrev("`s'",7) + local sc `sc' `s`i'' + local `++i' + } + + local dec = 10 + local col = `dec' + + local decit = 14 + local colit = `decit' + + local col1 = `decit' + forvalues i=1/`P' { + di _col(`col1') "{bf:`s`i''}" _c + local col1 = `col1' + `dec' + } + + di + local h = (`P'-1)*`dec'+`decit'+4 + di "{hline `h'}" + + qui corr $scorename `varlist' + matrix c = r(C) + matrix B = c[`=`P'+1'..`nbvars'+`P',1..`P'] + + local i = 1 + local j = 1 + local y = 1 + + foreach p in `partition' { + if `j' == 1 local s = `p' + else local s = `s' +`p' + + forvalues z = `y'/`s' { + di as text "{bf:`var`z''}" _c + local col = `decit'-1 + + local dd = `z' // [count cptdiv (one per item)] + + forvalues k = 1/`P' { + + local t = B[`z',`k'] + local t : di %6.3f `t' + if `k' == `i' { + if `t' < `tconvdiv' { + di in red _col(`col') "{bf:`t'}" _c + local cptconv = `cptconv'+1 + local col = `col' + `dec' + } + else { + di _col(`col') "{bf:`t'}" _c + local col = `col' + `dec' + } + } + else { + + if B[`z',`k'] > B[`z',`i'] { + di in red _col(`col') "`t'" _c + + if `dd' == `z' local cptdiv = `cptdiv'+1 // [one per item] + local dd = 0 + local col = `col' + `dec' + } + else { + di as text _col(`col') "{text:`t'}"_c + local col = `col' + `dec' + } + } + } + di + } + di "{dup `h':-}" + local `i++' + local `j++' + local y = `s'+1 + } + + local y = 1 + local h = 1 + local np : word count `partition' + + foreach p in `partition' { + if `h' == 1 local s = `p' + else local s = `s' +`p' + + forvalues j = 1/`np' { + mat C_`h'_`j' = B[`y'..`s',`j'] + + tempvar tp_`h'_`j' + mat colnames C_`h'_`j' = `tp_`h'_`j'' + + svmat C_`h'_`j', names(col) + } + + local `++h' + local y = `s'+1 + } +} + +if "`convdivboxplots'" != "" { + + if "${html}" != "" { + local html = "${html}" + di "
" + di "
" + + + local colors = "red blue green orange maroon magenta ebblue mint erose gray teal navy olive sienna" + local i = 1 + foreach c in `colors' { + local col`i' = "`c'" + local `++i' + } + + forvalues h = 1/`np' { + tokenize $scorename + local call = "" + local callbox = "" + local callleg = "" + + forvalues j = 1/`np' { + local call `call' `tp_`h'_`j'' + local callbox `callbox' box(`j',fcolor(`col`j'') lcolor(`col`j'')) marker(`j', mcolor(`col`j'')) + local lab = "``j''" + local lab = `"`lab'"' + local callleg `callleg' `j' "`lab'" + } + + qui local saving "saving(`c(tmpdir)'/`html'_Conv_div_``h'',replace) nodraw" + qui graph box `call', name("Conv_div_``h''",replace) `callbox' legend(order(`"`callleg'"') stack rows(1) size(small)) title(Correlations between items of ``h'' and scores) yline(`tconvdiv', lpattern(dot) lcolor(black)) `saving' + qui graph use `c(tmpdir)'/`html'_Conv_div_``h''.gph + qui graph export `c(tmpdir)'/`html'_Conv_div_``h''.eps, replace + + di " _char(34) " + + + + //qui set autotabgraphs on + } + di "
" + di "
"
+	}
+	
+	else {
+		forvalues h = 1/`np' {
+		tokenize $scorename
+		local call = ""
+		local callbox = ""
+		local callleg = ""
+		
+		forvalues j = 1/`np' {
+			local call `call' `tp_`h'_`j''
+			local callbox `callbox' box(`j',fcolor(`color') lcolor(`color')) marker(`j', mcolor(`color')) 
+			local lab = "``j''"
+			local lab = `"`lab'"'
+			local callleg `callleg' `j' "`lab'"
+		}
+		graph box `call', name("Conv_div_``h''",replace) `callbox' legend(order(`"`callleg'"') stack rows(1) size(small)) title(Correlations between items of ``h'' and scores) yline(`tconvdiv', lpattern(dot) lcolor(black))
+		qui set autotabgraphs on
+		}
+	}
+}
+
+
+local t : di %5.3f `tconvdiv'
+local p1 = (`nbvars'-`cptconv')/`nbvars'*100
+local p1 : di %4.1f `p1'
+local p2 = (`nbvars'-`cptdiv')/`nbvars'*100
+local p2 : di %4.1f `p2'
+
+di
+di as result "Convergent validity:" _c
+di as text " `=`nbvars'-`cptconv''/`nbvars' items (`p1'%) have a correlation coefficient with the score of "
+di _col(22) "their own dimension greater than `t'"
+di
+di as result "Divergent validity:" _c
+di as text "  `=`nbvars'-`cptdiv''/`nbvars' items (`p2'%) have a correlation coefficient with the score"
+di _col(22) "of their own dimension greater than those computed with other scores." 
+
+end
+
+/* cfa */
+
+capture program drop cfa
+program cfa,rclass
+syntax varlist, PARTition(numlist integer >0) [CFAMethod(string) CFAStand CFACov(string) CFAAuto]
+preserve	
+	
+local nbvars:word count `varlist'	
+local P:word count `partition'
+	
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+if "`cfaauto'" != "" & "`cfacov'" != "" {
+	di in red "You cannot use both cfacov() and cfaauto"
+	exit 119
+}	
+	
+if "`cfacov'" != "" {
+	
+	lstrfun v, subinstr("`cfacov'","*"," ",.)
+	foreach var in `v' {
+		capture confirm variable `var'
+		if _rc {
+			di in red "error in cfacov() option : `var' is not a variable from the dataset"
+			exit 119
+		}
+	}
+	lstrfun s,  subinstr("`cfacov'","* ","*",.)
+	lstrfun s,  subinstr("`s'"," *","*",.)
+	lstrfun s,  subinstr("`s'","*","*e.",.)
+	lstrfun f,  subinstr("`s'"," "," e.",.)
+	local g e.`f'
+	lstrfun g , lower("`g'")
+    local covs `g'
+}
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = lower("`x'")
+	qui rename `x' `var`i''
+	local `++i'
+}
+
+local upscorename = upper("$scorename")
+
+local i = 0
+local y = 1
+tokenize `upscorename'
+foreach x in `partition' {
+	local `i++' 
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	local liste = ""
+	forvalues w = `y'/`s' {
+		local liste `liste' `var`w'' 
+	}
+	
+	local a =  "(``i'' -> `liste')"
+	local zz `zz' `a'
+		
+	local y = `s'+1
+}
+
+if "`cfamethod'" == "" local cfamethod = "ml"
+
+if "`cfamethod'" != "ml" & "`cfamethod'" != "mlmv" & "`cfamethod'" != "adf" {
+	di "`cfamethod'"
+	di in red "option cfamethod incorrectly specified (choose among ml, mlmv and adf)"
+	error 198
+}
+
+if "`cfastand'" != "" local cfastand = "stand"
+
+di as result "{hline 105}"
+di "{bf:Confirmatory factor analysis}"
+di as result "{hline 105}"
+
+local ii = 1
+local s
+
+while `ii' == 1 | "`s'" != "" {
+	
+	if "`covs'" != "" & "`cfaauto'" != "" di _n "{bf:step `ii':} {text:`s'}"
+	qui sem `zz', method(`cfamethod') `cfastand' cov(`covs') iterate(50)
+	
+	/* factor loadings */
+
+	matrix r = r(table)
+	matrix r = r[1,1...]
+	matrix r = r'
+	local n = `nbvars'*2 
+
+	matrix a = r[1,1]
+	forvalues i=3(2)`n' {
+		matrix b = r[`i',1]
+		matrix a = a\b
+	}
+
+	/* standard error factor loadings*/
+
+	matrix r = r(table)
+	matrix r = r[2,1...]
+	matrix r = r'
+	local n = `nbvars'*2 
+
+	matrix sef = r[1,1]
+	forvalues i=3(2)`n' {
+		matrix b = r[`i',1]
+		matrix sef = sef\b
+	}
+
+	
+	/* intercepts */
+
+	matrix r = r(table)
+	matrix r = r[1,1...]
+	matrix r = r'
+	local n = `nbvars'*2 
+
+	matrix a2 = r[2,1]
+	forvalues i=4(2)`n' {
+		matrix b = r[`i',1]
+		matrix a2 = a2\b
+	}
+	
+	
+	/* standard error intercepts*/
+
+	matrix r = r(table)
+	matrix r = r[2,2...]
+	matrix r = r'
+	local n = `nbvars'*2 
+
+	matrix sei = r[1,1]
+	forvalues i=3(2)`n' {
+		matrix b = r[`i',1]
+		matrix sei = sei\b
+	}
+	
+	//mat li sei
+	/* error variances */
+
+	local m = `n'+1
+	matrix r = r(table)
+	//mat li r
+	matrix r = r[1,`m'...]
+	matrix r = r'
+
+	matrix a3 = r[1,1]
+	forvalues i=2/`nbvars' {
+		matrix b = r[`i',1]
+		matrix a3 = a3\b
+	}
+
+	/* variance of dimensions*/
+
+	matrix r = r(table)
+	local n = `nbvars'*3+1
+	matrix r = r[1,`n'...]
+	matrix r = r'
+
+	matrix var = r[1,1]
+	forvalues i=2/`P' {
+		matrix b = r[`i',1]
+		matrix var = var\b
+	}
+
+	if "`cfaauto'" != "" {
+		qui estat mindices, showpclass(mcons merrvar)
+		matrix m = r(mindices_pclass)
+		local r : colfullnames m
+		if "`r'" == "c1" local r
+		lstrfun e , subinstr("`r'","cov(","",.)
+		lstrfun d , subinstr("`e'",")","",.)
+		lstrfun d , subinstr("`d'",":_cons","",.)
+		lstrfun d , subinstr("`d'","e.","",.)
+		lstrfun d , subinstr("`d'",","," ",.)
+			
+		tokenize "`d'"
+		local y = 1
+		local i = 0
+		foreach x in `partition' {
+			local `i++' 
+			if `i' == 1 local s = `x'
+			else local s = `s' +`x'
+			
+			forvalues w = `y'/`s' {
+				local class_`var`w'' = `i'
+			}
+			local y = `s'+1
+		}
+
+		tokenize "`d'"
+		local i = 1
+		local l : word count ("`d'")
+		forvalues k = 1/`=`l'/2' {
+			local j = `i'+1
+			if "`class_``i'''" != "`class_``j'''" {
+				lstrfun d , subinstr("`d'","``i'' ``j''","",1)
+				lstrfun d , itrim("`d'")
+			}
+			local i = `i'+2
+		}
+		local cfacov = "`d'" 
+				
+		local s
+		local i = 1
+		tokenize "`d'"
+		foreach k in `d' {
+			local t = mod(`i',2)
+			if `t' == 0 local s `s' e.`k'
+			else local s `s' e.`k'*
+			local `++i'
+		}
+		
+		lstrfun s , subinstr("`s'","* ","*",.)
+		local covs `covs'  `s'	
+	}
+	if e(converged) == 0 di in red "Warning : model did not converge after 50 iterations"
+	local `++ii'
+}
+
+local i = 1
+foreach v in `varlist' {
+	local var`i' = abbrev("`v'",10)
+	local `++i'
+}
+
+local i = 1
+foreach s in $scorename {
+	local s`i' = abbrev("`s'",10)
+	local sc `sc' `s`i''
+	local `++i'
+
+}
+
+local max = 10
+local dec = `max'+5
+
+local max2 = 10
+
+local dec2 = `dec'+`max2'+5
+
+local a = e(N)
+di
+if e(converged) == 0 di in red "Warning : model did not converge after 50 iterations"
+di
+if "`covs'" != "" {
+	di as result "{bf:Covariances between errors added:} {text:`covs'}"
+	di
+}
+di "{bf:Number of used individuals: } {text:`a'}"
+di
+//di _col(`=`dec2'+17+4') "{bf:Estimation:}"
+
+
+di as result "{bf:Item}" _c
+di _col(`dec') "{bf:Dimension}" _c 
+di _col(`dec2') "{bf:Factor}" _c 
+di _col(`=`dec2'+14') "{bf:Standard}" _c 
+di _col(`=`dec2'+28') "{bf:Intercept}" _c  
+di _col(`=`dec2'+43') "{bf:Standard}" _c  
+
+if "`cfastand'" == "" {
+	di _col(`=`dec2'+57') "{bf:Error}" _c 
+	di _col(`=`dec2'+66') "{bf:Variance of}"
+	di _col(`dec2') "{bf:loading}" _c 
+	di _col(`=`dec2'+14') "{bf:error}" _c
+	di _col(`=`dec2'+43') "{bf:error}" _c
+	di _col(`=`dec2'+55') "{bf:variance}" _c
+	di _col(`=`dec2'+67') "{bf:dimension}"
+	local h = `dec2'+76
+}
+else {
+	di _col(`=`dec2'+57') "{bf:Error}" 
+	di _col(`dec2') "{bf:loading}" _c 
+	di _col(`=`dec2'+14') "{bf:error}" _c
+	di _col(`=`dec2'+44') "{bf:error}" _c
+	di _col(`=`dec2'+57') "{bf:variance}" 
+	local h = `dec2'+62
+} 
+
+di "{hline `h'}"
+
+local i = 1
+local y = 1
+foreach x in `partition' {
+	if `i' == 1 local s = `x'
+	else local s = `s' +`x'
+	
+	forvalues z = `y'/`s' {
+		tokenize `sc'
+		di "{bf:`var`z''}"_c
+		di _col(`dec') "{bf:``i''}" _c
+		local t = a[`z',1]
+		local t : di %7.2f `t'
+		di _col(`dec2') "{text:`t'}" _c
+		
+		local t = sef[`z',1]
+		local t : di %8.2f `t'
+		di _col(`=`dec2'+14') "{text:`t'}" _c
+			
+		local t = a2[`z',1]
+		local t : di %9.2f `t'
+		di _col(`=`dec2'+28') "{text:`t'}" _c
+		
+		local t = sei[`z',1]
+		local t : di %9.2f `t'
+		di _col(`=`dec2'+42') "{text:`t'}" _c
+		
+		local t = a3[`z',1]
+		local t : di %11.2f `t'
+				
+		if "`cfastand'" == "" & `z' == `y'{
+			di _col(`=`dec2'+52') "{text:`t'}" _c
+			local t = var[`i',1]
+			local t : di %11.2f `t'
+			di _col(`=`dec2'+66') "{text:`t'}"
+		}
+		else di _col(`=`dec2'+52') "{text:`t'}" 
+	}
+	di
+	local `i++' 
+	local y = `s'+1	
+}
+
+qui estat gof, stats(all)
+
+local chi2 = r(chi2_ms)
+local p = r(p_ms)
+local ddl = r(df_ms)
+local ratio = `chi2'/`ddl'
+local rmsea = r(rmsea)
+local lb = r(lb90_rmsea)
+local ub = r(ub90_rmsea)
+local nfi = 1-(r(chi2_ms)/r(chi2_bs))
+local rni = 1-(r(chi2_ms)-r(df_ms))/(r(chi2_bs)-r(df_bs))
+local cfi = r(cfi)
+local ifi = (r(chi2_bs)-r(chi2_ms))/(r(chi2_bs)-r(df_ms))
+local mci = exp(-0.5*((r(chi2_ms)-r(df_ms))/(e(N)-1)))
+local srmr = r(srmr)
+
+di
+di "{bf:Goodness of fit:}"
+di
+
+
+
+if "${html}" != "" {
+
+di as result _col(4) "chi2" _c
+di as result _col(20) "ddl" _c
+di as result _col(28) "chi2/ddl" _c
+di as result _col(42) "RMSEA [90% CI]" _c
+di as result _col(64) "SRMR" _c
+di as result _col(74) "NFI" _c
+di as result _col(84) "RNI" 
+
+
+local t : di %7.2f `chi2'
+di "{text:`t'}" _c
+local t : di %3.0f `ddl'
+di _col(20) "{text:`t'}" _c
+local t : di %7.1f `ratio'
+di _col(29) "{text:`t'}" _c
+local t : di %5.3f `rmsea'
+local l : di %5.3f `lb'
+local u : di %5.3f `ub'
+di _col(40) "{text:`t' [`l' ; `u']}" _c
+local t : di %5.3f `srmr'
+di _col(63) "{text:`t'}" _c
+local t : di %5.3f `nfi'
+di _col(72) "{text:`t'}" _c
+local t : di %5.3f `rni'
+di _col(82) "{text:`t'}" 
+
+local p : di %5.3f `p'
+di "{text:(p-value = `p')}"
+di as result
+di as result _col(4) "CFI" _c 
+di as result _col(15) "IFI" _c
+di as result _col(26) "MCI"
+local t : di %5.3f `cfi'
+di _col(4) "{text:`t'}" _c
+local t : di %5.3f `ifi'
+di _col(15) "{text:`t'}" _c
+local t : di %5.3f `mci'
+di _col(26) "{text:`t'}" 
+di as result
+}
+else {
+di as result _col(4) "chi2" _c
+di as result _col(20) "ddl" _c
+di as result _col(28) "chi2/ddl" _c
+di as result _col(42) "RMSEA [90% CI]" _c
+di as result _col(64) "SRMR" _c
+di as result _col(74) "NFI" _c
+di as result _col(84) "RNI" _c
+di as result _col(94) "CFI" _c 
+di as result _col(104) "IFI" _c
+di as result _col(114) "MCI"
+
+local t : di %7.2f `chi2'
+di "{text:`t'}" _c
+local t : di %3.0f `ddl'
+di _col(20) "{text:`t'}" _c
+local t : di %7.1f `ratio'
+di _col(29) "{text:`t'}" _c
+local t : di %5.3f `rmsea'
+local l : di %5.3f `lb'
+local u : di %5.3f `ub'
+di _col(40) "{text:`t' [`l' ; `u']}" _c
+local t : di %5.3f `srmr'
+di _col(63) "{text:`t'}" _c
+local t : di %5.3f `nfi'
+di _col(72) "{text:`t'}" _c
+local t : di %5.3f `rni'
+di _col(82) "{text:`t'}" _c
+local t : di %5.3f `cfi'
+di _col(92) "{text:`t'}" _c
+local t : di %5.3f `ifi'
+di _col(102) "{text:`t'}" _c
+local t : di %5.3f `mci'
+di _col(112) "{text:`t'}" 
+local p : di %5.3f `p'
+di "{text:(p-value = `p')}"
+di as result
+
+}
+end
+
+/* repet */
+
+capture program drop repet
+program repet,rclass
+syntax varlist, PARTition(numlist integer >0) [t2(varlist) KAPpa ICKAPpa(integer 0)]
+preserve
+
+local nbvars : word count `varlist'
+
+if `ickappa' <= 0 {
+	local ickappa = ""
+}
+
+local C = 0
+foreach z in `partition' {
+	local C = `C' + `z'
+}
+	
+local P:word count `partition'
+
+if "$scores2" != "" {
+	local t:word count $scores2' 
+	if `P' != `t' {
+		di in red "The number of score names given in scores2() is different from the number of scores defined"
+		exit 119
+	}
+}
+
+if "`t2'" != "" { 
+
+	local i = 1
+	foreach s in $scorename {
+		local s`i' = abbrev("`s'",10)
+		local sc `sc' `s`i''
+		local `++i'
+	}
+
+	local i = 1
+	foreach v in `varlist' {
+		local var`i' = abbrev("`v'",10)
+		local `++i'
+	}
+
+	local maxit = 1
+	forvalues i=1/`nbvars' {
+		local len = length("`var`i''")
+		if `len' > `maxit' local maxit = `len'
+	}
+
+	local decit = `maxit' + 4
+	local colit = `decit'
+
+	di as result "{hline 105}"
+	di as result "{bf:Reproducibility}"
+	di as result "{hline 105}"
+	di
+
+	if "$scores2" == "" {
+		foreach sco in $scorename {
+				*local t = "`sco'bis"
+				tempname s
+				local scorename2 `scorename2' `s'
+		}
+		
+		qui calcscore `t2', scorename(`scorename2') partition(`partition') compscore(${compscore}) modalities($modalities)
+		
+	}
+	
+	else {
+		foreach sco in $scores2 {
+			local scorename2 `scorename2' `sco'
+		}
+	}
+	
+	local i = 1
+	foreach var in `varlist' {
+		tokenize `t2'
+		qui kap `var' ``i''
+		local k`i' = r(kappa)
+		if "`ickappa'" != "" {
+			qui kapci `var' ``i'', reps(`ickappa')
+			local lbk`i' = r(lb_bc)
+			local ubk`i' = r(ub_bc)
+		}
+		local `++i'
+	}
+
+	local i = 1
+	foreach s in $scorename {
+		tokenize `scorename2'
+		tempname score id temps
+		qui gen `id' = _n
+		qui gen `score'_1 = `s'
+		qui gen `score'_2 = ``i'' if ``i''!=.
+		qui reshape long `score'_, i(`id') j(`temps')
+		qui icc `score'_ `id'
+		local n`i' = r(N_target)
+		local icc`i' = r(icc_i)
+		local lb`i' = r(icc_i_lb)
+		local ub`i' = r(icc_i_ub)
+		qui sort `id'
+		qui duplicates drop `id', force
+		local `++i'
+	}
+
+	tokenize `sc'
+	local max = length("dimension")
+
+	forvalues j=1/`P' {
+		local len`j' = length("`s`j''")
+		if `len`j'' > `max' local max = `len`j''
+	}
+
+	local dec = `max' + 5
+
+	local i = 1
+	local j = 1
+	local y = 1
+	di "{bf:Dimension}" _c
+	di _col(`=`dec'+2') "{bf:n}" _c
+	local col = `dec'+6
+	di _col(`col') "{bf:Item}" _c
+	local col = `col'+`decit'
+
+	if "`kappa'" != "" {
+		di _col(`col') "{bf:Kappa}" _c
+		local col = `col'+10
+		if "`ickappa'" != "" {
+			di _col(`col') "{bf:95% CI for Kappa}" _c
+			local col = `col'+20	
+		}
+		
+	}
+
+	di _col(`=`col'+2') "{bf:ICC}" _c
+	local col = `col'+9
+	di _col(`col') "{bf:95% CI for ICC}"
+
+	local zz = 0
+	foreach var in `varlist' {
+		qui levelsof `var', local(levels)
+		local z : word count `levels'
+		if `z' > 2 local zz = 1
+	}
+
+	if "`kappa'" != "" & "`ickappa'" != "" & `zz' == 1 {
+		local col = `dec'+`decit'+16
+		di _col(`col') "{bf:(bootstrapped)}"
+	}
+
+
+	if "`ickappa'" != "" local h = `dec'+6+`decit'+10+8+21+12+1
+	else if "`kappa'" != "" local h = `dec'+6+`decit'+10+8+21+12-20
+	else local h = `dec'+6+`decit'+10+8+21+12-29
+	di "{hline `h'}"
+
+	local i = 1
+	foreach p in `partition' {
+		tokenize `sc'
+		di "{bf:``i''}" _c
+		di _col(`dec') "{text:`n`i''}" _c
+		if `j' == 1 local s = `p'
+		else local s = `s' +`p'
+		local col = `dec'+6
+		di _col(`col') "{text:`var`y''}" _c 
+		
+		if "`kappa'" != "" {
+			local k : di %5.2f `k`y''
+			local col = `col'+`decit'
+			di _col(`col') "{text:`k'}" _c
+			if "`ickappa'" != "" {
+				local lbk : di %5.2f `lbk`i''
+				local ubk : di %5.2f `ubk`i''
+				local col = `col'+11
+				di _col(`col') "{text:[`lbk' ; `ubk']}" _c
+				local col = `decit'+50
+			}
+			
+		else local col = `decit'+30	
+		}
+		else local col = `decit'+20
+			
+		local icc : di %5.2f `icc`i''
+		di _col(`col') "{text:`icc'}" _c
+		local lb : di %5.2f `lb`i''
+		local ub : di %5.2f `ub`i''
+		local col = `col'+8
+		di _col(`col')"{text:[`lb' ; `ub']}"
+		local w = `y'+1
+		
+		forvalues z = `w'/`s' {
+			local col = `dec'+6
+			di _col(`col') "{text:`var`z''}" _c
+			if "`kappa'" != "" {
+				local k : di %5.2f `k`z''
+				local col = `col'+`decit'
+				di _col(`col') "{text:`k'}" _c
+				if "`ickappa'" != "" {
+					local lbk : di %5.2f `lbk`z''
+					local ubk : di %5.2f `ubk`z''
+					local col = `col'+11
+					di _col(`col')"{text:[`lbk' ; `ubk']}"
+				}
+				else di
+				
+			}
+			else di
+		}
+		local `i++' 
+		local `j++' 
+		local y = `s'+1
+		di
+	}
+}
+
+else {
+	local i = 1
+	foreach s in $scorename {
+		tokenize $scores2
+		tempname score id temps
+		qui gen `id' = _n
+		qui gen `score'_1 = `s'
+		qui gen `score'_2 = ``i'' if ``i''!=.
+		qui reshape long `score'_, i(`id') j(`temps')
+		qui icc `score'_ `id'
+		local n`i' = r(N_target)
+		local icc`i' = r(icc_i)
+		local lb`i' = r(icc_i_lb)
+		local ub`i' = r(icc_i_ub)
+		qui sort `id'
+		qui duplicates drop `id', force
+		local `++i'
+	}
+
+	tokenize $scorename
+	local max = length("dimension")
+
+	local h = 1
+	foreach s in $scorename {
+		local s`h' = abbrev("`s'",10)
+		local sc `sc' `s`h''
+		local `++h'
+	}
+	
+	forvalues j=1/`P' {
+		local len`j' = length("`s`j''")
+		if `len`j'' > `max' local max = `len`j''
+	}
+
+	local dec = `max' + 5
+
+	local i = 1
+	local j = 1
+	local y = 1
+	
+	di as result "{hline 105}"
+	di as result "{bf:Reproducibility}"
+	di as result "{hline 105}"
+	di
+	
+	di "{bf:Dimension}" _c
+	local col = `dec'
+	di _col(`col') "{bf:n}" _c
+	
+
+	di _col(`=`col'+6') "{bf:ICC}" _c
+	local col = `col'+14
+	di _col(`col') "{bf:95% CI for ICC}"
+
+	di "{hline 50}"
+	
+	local i = 1
+	foreach p in `partition' {
+		tokenize $scorename
+		di "{bf:``i''}" _c
+		local n : di % 4.0f `n`i''
+		di _col(`=`dec'-3') "{text:`n'}" _c
+		if `j' == 1 local s = `p'
+		else local s = `s' +`p'
+		local col = `dec'+4
+		
+		local icc : di %5.2f `icc`i''
+		di _col(`col') "{text:`icc'}" _c
+		local lb : di %5.2f `lb`i''
+		local ub : di %5.2f `ub`i''
+		local col = `col'+9
+		di _col(`col')"{text:[`lb' ; `ub']}"
+		local w = `y'+1
+		
+		local `i++' 
+	}
+}
+
+end
+
+
+/* kgv */
+
+capture program drop kgv
+program kgv,rclass
+syntax varlist, categ(varlist) [KGVBoxplots KGVGroupboxplots]
+	
+foreach c in `categ' {
+	tempname j
+	capture encode `c', generate(`j')
+	capture confirm variable `j'
+	if _rc local j = "`c'"
+	local categ2 `categ2' `j' 
+}	
+
+local i = 1
+local j = 1	
+local k = 0
+local max = 0
+local a : word count `categ'
+local nb:word count `varlist'
+
+di as result "{hline 105}"
+di "{bf:Known-groups validity}"
+di as result "{hline 105}"
+di
+	
+foreach sco in `varlist' {
+	foreach cat in `categ2' {
+		local nblev = 0
+		local maxlen`j' = 0
+		qui anova `sco' `cat'
+		local p`i'_`j' =  Ftail(e(df_m), e(df_r), e(F))
+		qui levelsof `cat', local(levels) 
+		local lbe : value label `cat'
+			
+		foreach l of local levels {
+			qui count if `sco' !=. & `cat' == `l'
+			local `++k'
+			local eff`i'_`j'_`k' = r(N)
+			
+			if "`lbe'" != "" {
+				local ll`j'_`k' : label `lbe' `l'
+				local len = length("`ll`j'_`k''")
+				if `len' > 10 {
+					local c = substr("`ll`j'_`k''",1,9)
+					local d = substr("`ll`j'_`k''",-1,1)
+					local ll`j'_`k' "`c'" "~" "`d'" 
+				}
+				local w = length("`ll`j'_`k''")
+				if `w' > `maxlen`j'' local maxlen`j' = `w'
+			}
+			else {
+				local ll`j'_`k' = `l'
+				local len = length("`ll`j'_`k''")
+				if `len' > 10 {
+					local c = substr("`ll`j'_`k''",1,9)
+					local d = substr("`ll`j'_`k''",-1,1)
+					local ll`j'_`k' "`c'" "~" "`d'" 
+				}
+				local w = length("`ll`j'_`k''")
+				if `w' > `maxlen`j'' local maxlen`j' = `w'
+			}
+			qui su `sco' if `cat' == `l'
+			local m`i'_`j'_`k' = r(mean)
+			local s`i'_`j'_`k' = r(sd)
+			local nblev = `nblev' + 1
+		}
+		if `nblev' > `max' local max = `nblev'
+		local `++j'
+		local k = 0
+	}
+	local `++i'
+	local j = 1
+}
+
+local i = 1
+foreach s in `varlist' {
+	local s`i' = abbrev("`s'",7)
+	local sc `sc' `s`i''
+	local `++i'
+}
+
+local maxs = 0
+forvalues j=1/`nb' {
+	local len`j' = length("`s`j''")
+	if `len`j'' > `maxs' local maxs = `len`j''
+}
+
+local i = 1
+local k = 0
+local j = 2
+
+foreach cat in `categ'{
+	local `++k'
+	tokenize `categ'
+	local c`k' = "``i'' ``j''"
+	local i = `i' + 2 
+	local j = `j' + 2 
+}
+
+
+local d = 1
+local f = 2
+forvalues h = 1/`a' {
+	if `f' > `a' local f = `f'-1
+	local j = 1
+	local col =  `maxs'+6
+	foreach cat in `c`h'' {
+		di _col(`col') "{bf:`cat'}" _c
+		local col = `col' + `maxlen`j'' + 5 + 40
+		local `++j'
+	}
+	di
+
+	local j = `d'
+	local col = `maxs'+6
+	foreach cat in `c`h'' {
+		di _col(`=`col'+`maxlen`j''+5') "{bf:       mean    }" _c
+		di "{bf:     sd    }" _c
+		di "{bf:p-value}" _c
+		    
+		local col = `col' + `maxlen`j'' + 5 + 40
+		local `++j'
+	}
+	
+	local j = `d'
+	local col = `maxs'+6
+
+	di
+	di
+	local i = 1
+	local col = `maxs'+6
+
+	forvalues g = 1/`nb' {
+		
+		di "{bf:`s`g''}" _c
+		forvalues k = 1/`max' {
+			forvalues j = `d'/`f' {
+			
+				di _col(`col') "{bf:`ll`j'_`k''} " _c
+				if "`eff`i'_`j'_`k''" != "" di as text "(n=`eff`i'_`j'_`k'')" _c
+				local m : di %6.2f `m`i'_`j'_`k''
+				di _col(`=`col'+`maxlen`j''+10') "{text:`m'}  " _c
+					
+				local s : di %8.2f `s`i'_`j'_`k''
+				di "{text: `s'}  " _c
+					
+				if `k' == 1 {
+					local p : di %8.3f `p`i'_`j''
+					di _col(`=`col'+31') "{text:`p'}  " _c
+				}
+				local col = `col' + `maxlen`j'' + 5 + 40
+			}
+			di
+			local col = `maxs'+6
+		
+		}
+		di 
+		
+	local `++i'
+
+	}
+	local d = `d'+2
+	local f = `f'+2
+	if `d' > `a' continue, break
+	di
+}
+
+if "`kgvboxplots'" != "" {
+	local html = "${html}"
+	if "`html'" != "" {
+		di "
" + di "
" + if "`kgvgroupboxplots'" != "" { + foreach c in `categ' { + foreach s in `varlist' { + //graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c'") nodraw + + + qui local saving "saving(`c(tmpdir)'/`html'_kgv`s',replace) nodraw" + qui graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c'") `saving' + qui graph use `c(tmpdir)'/`html'_kgv`s'.gph + qui graph export `c(tmpdir)'/`html'_kgv`s'.eps, replace + + + local g `g' `s'_`c' + } + } + + qui local saving "saving(`c(tmpdir)'/`html'_kgv,replace) nodraw" + qui gr combine `g', name(kgv,replace) `saving' + qui graph use `c(tmpdir)'/`html'_kgv.gph + qui graph export `c(tmpdir)'/`html'_kgv.eps, replace + di " _char(34) " + + } + else { + foreach c in `categ' { + foreach s in `varlist' { + //graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c'") + + qui local saving "saving(`c(tmpdir)'/`html'_kgv`s',replace) nodraw" + qui graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c'") `saving' + qui graph use `c(tmpdir)'/`html'_kgv`s'.gph + qui graph export `c(tmpdir)'/`html'_kgv`s'.eps, replace + di " _char(34) " + + local g `g' `s'_`c' + } + } + } + di "
" + di "
"
+	
+	}
+	else {
+		if "`kgvgroupboxplots'" != "" {
+			foreach c in `categ' {
+				foreach s in `varlist' {
+					graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c'") nodraw
+					local g `g' `s'_`c' 
+				}
+			}
+			gr combine `g', name(Known_groups_validity,replace)
+		}
+		else {
+			foreach c in `categ' {
+				foreach s in `varlist' {
+					graph box `s', over(`c') name("`s'_`c'",replace) b1title("`c'")
+					local g `g' `s'_`c' 
+				}
+			}
+		}
+	}
+}
+
+end
+
+
+/* conc */
+
+capture program drop conc
+program conc,rclass
+syntax varlist, comp(varlist) [tconc(real 0.4)]
+
+di as result "{hline 105}"
+di "{bf:Concurrent validity}"
+di as result "{hline 105}"
+di
+
+local n : word count `varlist'
+local p : word count `comp'
+
+matrix m = J(`n',`p',.)
+matrix rownames m = `varlist'
+matrix colnames m = `comp'
+local r = 1
+
+foreach i in `varlist' {
+	local c = 1
+	foreach j in `comp' {
+		qui corr `i' `j'
+		mat e = r(C)
+		local f = e[2,1]
+		mat m[`r',`c'] = `f' 
+		local `++c'
+	}
+	local `++r'
+}
+
+tokenize `varlist'
+local maxv = length("`1'")
+forvalues i=1/`n' {
+	local lenv = length("``i''")
+	if `lenv' > `maxv' local maxv = `lenv'
+}
+
+local decv = `maxv'+6
+
+tokenize `comp'
+local maxc = length("`1'")
+forvalues i=1/`p' {
+	local lenc = length("``i''")
+	if `lenc' > `maxc' local maxc = `lenc'
+}
+
+local decc = `maxc'+4
+
+local col = `decv'
+foreach c in `comp' {
+	di as result _col(`col') "`c'" _c
+	local col = `col'+`decc'
+}
+di
+
+local i = 1 
+foreach x in `varlist' {
+	local var`i' = "`x'"
+	local `++i'
+}
+
+forvalues i=1/`n' {
+	di as result "`var`i''" _c
+	local col = `decv'
+	forvalues j=1/`p' {
+		local t = m[`i',`j']
+		if `t' > `tconc' | `t' < -`tconc' {
+			di as result _col(`=`col'-1') %5.2f `t' _c
+		}
+		else di as text _col(`=`col'-1') %5.2f `t' _c
+		local col = `col'+`decc'
+	}
+	di
+}
+
+capture restore, not
+end
+
diff --git a/Modules/ado/personal/w/whist.ado b/Modules/ado/personal/w/whist.ado
new file mode 100644
index 0000000..c5d1f77
--- /dev/null
+++ b/Modules/ado/personal/w/whist.ado
@@ -0,0 +1,12 @@
+program define whist, rclass
+version 9 /* si chgt version*/
+syntax varname [aweight iweight fweight pweight/] [,title(string)] /*pond posssibles*/
+di "varname :`varlist'"
+tempname varpond
+qui su `exp' if `varlist'!=.
+qui gen `varpond'=`exp'/r(sum)*100
+label variable `varpond' "fréquence"
+label variable `varlist' "`varlist'"
+graph bar (sum) `varpond', over(`varlist') blabel(bar, format (%4.1f)) title(`title') ytitle(pourcentage) b1title(`varlist')
+end
+
diff --git a/Modules/ado/personal/zip/backrasch2.zip b/Modules/ado/personal/zip/backrasch2.zip
new file mode 100644
index 0000000..4285fd3
Binary files /dev/null and b/Modules/ado/personal/zip/backrasch2.zip differ
diff --git a/Modules/ado/personal/zip/clv214.zip b/Modules/ado/personal/zip/clv214.zip
new file mode 100644
index 0000000..7062047
Binary files /dev/null and b/Modules/ado/personal/zip/clv214.zip differ
diff --git a/Modules/ado/personal/zip/detect31.zip b/Modules/ado/personal/zip/detect31.zip
new file mode 100644
index 0000000..88a2be4
Binary files /dev/null and b/Modules/ado/personal/zip/detect31.zip differ
diff --git a/Modules/ado/personal/zip/gammasym.zip b/Modules/ado/personal/zip/gammasym.zip
new file mode 100644
index 0000000..7d38697
Binary files /dev/null and b/Modules/ado/personal/zip/gammasym.zip differ
diff --git a/Modules/ado/personal/zip/gammasym22.zip b/Modules/ado/personal/zip/gammasym22.zip
new file mode 100644
index 0000000..b4fb485
Binary files /dev/null and b/Modules/ado/personal/zip/gammasym22.zip differ
diff --git a/Modules/ado/personal/zip/gausshermite1.zip b/Modules/ado/personal/zip/gausshermite1.zip
new file mode 100644
index 0000000..025b0a4
Binary files /dev/null and b/Modules/ado/personal/zip/gausshermite1.zip differ
diff --git a/Modules/ado/personal/zip/geekel2d43.zip b/Modules/ado/personal/zip/geekel2d43.zip
new file mode 100644
index 0000000..7222720
Binary files /dev/null and b/Modules/ado/personal/zip/geekel2d43.zip differ
diff --git a/Modules/ado/personal/zip/gengroup12.zip b/Modules/ado/personal/zip/gengroup12.zip
new file mode 100644
index 0000000..c3896df
Binary files /dev/null and b/Modules/ado/personal/zip/gengroup12.zip differ
diff --git a/Modules/ado/personal/zip/hcavar32.zip b/Modules/ado/personal/zip/hcavar32.zip
new file mode 100644
index 0000000..e72848b
Binary files /dev/null and b/Modules/ado/personal/zip/hcavar32.zip differ
diff --git a/Modules/ado/personal/zip/imputeitems.zip b/Modules/ado/personal/zip/imputeitems.zip
new file mode 100644
index 0000000..d7b6b87
Binary files /dev/null and b/Modules/ado/personal/zip/imputeitems.zip differ
diff --git a/Modules/ado/personal/zip/imputeitems24.zip b/Modules/ado/personal/zip/imputeitems24.zip
new file mode 100644
index 0000000..53d50d2
Binary files /dev/null and b/Modules/ado/personal/zip/imputeitems24.zip differ
diff --git a/Modules/ado/personal/zip/imputemok21.zip b/Modules/ado/personal/zip/imputemok21.zip
new file mode 100644
index 0000000..5cd69a5
Binary files /dev/null and b/Modules/ado/personal/zip/imputemok21.zip differ
diff --git a/Modules/ado/personal/zip/imputerasch2.zip b/Modules/ado/personal/zip/imputerasch2.zip
new file mode 100644
index 0000000..c587400
Binary files /dev/null and b/Modules/ado/personal/zip/imputerasch2.zip differ
diff --git a/Modules/ado/personal/zip/loevH.zip b/Modules/ado/personal/zip/loevH.zip
new file mode 100644
index 0000000..21c92bd
Binary files /dev/null and b/Modules/ado/personal/zip/loevH.zip differ
diff --git a/Modules/ado/personal/zip/loevh8.zip b/Modules/ado/personal/zip/loevh8.zip
new file mode 100644
index 0000000..9e20e9c
Binary files /dev/null and b/Modules/ado/personal/zip/loevh8.zip differ
diff --git a/Modules/ado/personal/zip/mmsrm4.zip b/Modules/ado/personal/zip/mmsrm4.zip
new file mode 100644
index 0000000..269ee86
Binary files /dev/null and b/Modules/ado/personal/zip/mmsrm4.zip differ
diff --git a/Modules/ado/personal/zip/mohand.zip b/Modules/ado/personal/zip/mohand.zip
new file mode 100644
index 0000000..86b3215
Binary files /dev/null and b/Modules/ado/personal/zip/mohand.zip differ
diff --git a/Modules/ado/personal/zip/msp.zip b/Modules/ado/personal/zip/msp.zip
new file mode 100644
index 0000000..7b9daf1
Binary files /dev/null and b/Modules/ado/personal/zip/msp.zip differ
diff --git a/Modules/ado/personal/zip/msp81.zip b/Modules/ado/personal/zip/msp81.zip
new file mode 100644
index 0000000..1ef8655
Binary files /dev/null and b/Modules/ado/personal/zip/msp81.zip differ
diff --git a/Modules/ado/personal/zip/npirt.zip b/Modules/ado/personal/zip/npirt.zip
new file mode 100644
index 0000000..ff6557a
Binary files /dev/null and b/Modules/ado/personal/zip/npirt.zip differ
diff --git a/Modules/ado/personal/zip/raschfit4.zip b/Modules/ado/personal/zip/raschfit4.zip
new file mode 100644
index 0000000..e95b8ae
Binary files /dev/null and b/Modules/ado/personal/zip/raschfit4.zip differ
diff --git a/Modules/ado/personal/zip/raschpower1.4.zip b/Modules/ado/personal/zip/raschpower1.4.zip
new file mode 100644
index 0000000..1799c5c
Binary files /dev/null and b/Modules/ado/personal/zip/raschpower1.4.zip differ
diff --git a/Modules/ado/personal/zip/raschpower1.5.zip b/Modules/ado/personal/zip/raschpower1.5.zip
new file mode 100644
index 0000000..632cb8f
Binary files /dev/null and b/Modules/ado/personal/zip/raschpower1.5.zip differ
diff --git a/Modules/ado/personal/zip/raschpower1.zip b/Modules/ado/personal/zip/raschpower1.zip
new file mode 100644
index 0000000..1fb85bb
Binary files /dev/null and b/Modules/ado/personal/zip/raschpower1.zip differ
diff --git a/Modules/ado/personal/zip/raschpower2.zip b/Modules/ado/personal/zip/raschpower2.zip
new file mode 100644
index 0000000..27489c2
Binary files /dev/null and b/Modules/ado/personal/zip/raschpower2.zip differ
diff --git a/Modules/ado/personal/zip/raschpower32.zip b/Modules/ado/personal/zip/raschpower32.zip
new file mode 100644
index 0000000..04a340c
Binary files /dev/null and b/Modules/ado/personal/zip/raschpower32.zip differ
diff --git a/Modules/ado/personal/zip/raschtest.zip b/Modules/ado/personal/zip/raschtest.zip
new file mode 100644
index 0000000..245c6fd
Binary files /dev/null and b/Modules/ado/personal/zip/raschtest.zip differ
diff --git a/Modules/ado/personal/zip/raschtest8.zip b/Modules/ado/personal/zip/raschtest8.zip
new file mode 100644
index 0000000..18defd7
Binary files /dev/null and b/Modules/ado/personal/zip/raschtest8.zip differ
diff --git a/Modules/ado/personal/zip/raschtest86.zip b/Modules/ado/personal/zip/raschtest86.zip
new file mode 100644
index 0000000..a18572a
Binary files /dev/null and b/Modules/ado/personal/zip/raschtest86.zip differ
diff --git a/Modules/ado/personal/zip/raschtest87.zip b/Modules/ado/personal/zip/raschtest87.zip
new file mode 100644
index 0000000..ba49c50
Binary files /dev/null and b/Modules/ado/personal/zip/raschtest87.zip differ
diff --git a/Modules/ado/personal/zip/raschtestv7.zip b/Modules/ado/personal/zip/raschtestv7.zip
new file mode 100644
index 0000000..829355b
Binary files /dev/null and b/Modules/ado/personal/zip/raschtestv7.zip differ
diff --git a/Modules/ado/personal/zip/sf36fr13.zip b/Modules/ado/personal/zip/sf36fr13.zip
new file mode 100644
index 0000000..c2f992b
Binary files /dev/null and b/Modules/ado/personal/zip/sf36fr13.zip differ
diff --git a/Modules/ado/personal/zip/simirt.zip b/Modules/ado/personal/zip/simirt.zip
new file mode 100644
index 0000000..299bb45
Binary files /dev/null and b/Modules/ado/personal/zip/simirt.zip differ
diff --git a/Modules/ado/personal/zip/simirt34.zip b/Modules/ado/personal/zip/simirt34.zip
new file mode 100644
index 0000000..a07bc1f
Binary files /dev/null and b/Modules/ado/personal/zip/simirt34.zip differ
diff --git a/Modules/ado/personal/zip/simirt35.zip b/Modules/ado/personal/zip/simirt35.zip
new file mode 100644
index 0000000..6f955a8
Binary files /dev/null and b/Modules/ado/personal/zip/simirt35.zip differ
diff --git a/Modules/ado/personal/zip/traces33.zip b/Modules/ado/personal/zip/traces33.zip
new file mode 100644
index 0000000..c7dc2e1
Binary files /dev/null and b/Modules/ado/personal/zip/traces33.zip differ
diff --git a/Modules/ado/plus/_/_eststo.ado b/Modules/ado/plus/_/_eststo.ado
new file mode 100644
index 0000000..ce97524
--- /dev/null
+++ b/Modules/ado/plus/_/_eststo.ado
@@ -0,0 +1,28 @@
+*! version 1.0.4  09nov2007  Ben Jann
+
+program define _eststo, byable(onecall)
+    local caller : di _caller()
+    version 8.2
+    if "`_byvars'"!="" local by "by `_byvars'`_byrc0' : "
+    if inlist(`"`1'"',"clear","dir","drop") {
+        version `caller': `by'eststo `0'
+    }
+    else {
+        capt _on_colon_parse `0'
+        if !_rc {
+            local command `"`s(after)'"'
+            if `"`command'"'!="" {
+                local command `":`command'"'
+            }
+            local 0 `"`s(before)'"'
+        }
+        syntax [anything] [, Esample * ]
+        if `"`esample'"'=="" {
+            local options `"noesample `options'"'
+        }
+        if `"`options'"'!="" {
+            local options `", `options'"'
+        }
+        version `caller': `by'eststo `anything'`options' `command'
+    }
+end
diff --git a/Modules/ado/plus/_/_eststo.hlp b/Modules/ado/plus/_/_eststo.hlp
new file mode 100644
index 0000000..acde74f
--- /dev/null
+++ b/Modules/ado/plus/_/_eststo.hlp
@@ -0,0 +1 @@
+.h eststo
diff --git a/Modules/ado/plus/_/_get_mlogit_bv.ado b/Modules/ado/plus/_/_get_mlogit_bv.ado
new file mode 100644
index 0000000..49e581b
--- /dev/null
+++ b/Modules/ado/plus/_/_get_mlogit_bv.ado
@@ -0,0 +1,86 @@
+*! version 1.0.2  07oct2009  Ben Jann
+*    - name change; restructured; new reshape algorithm
+*  version 1.0.1  15sep2009  Scott Long
+*    - reshape b to Stata 5 format
+*  version 1.0.0  15sep2009  Ben Jann
+
+*  get stata e(b) and e(V) from -mlogit- and reshape
+*  to the format used by SPost based on Stata 5
+
+capture program drop _get_mlogit_bv
+capture program drop _remove_baseeq
+program _get_mlogit_bv
+    version 9
+    args b v
+    if `"`b'"'=="" | `"`v'"'=="" {
+        di as err "_get_mlogit_bv: names for b and v must be specified"
+        exit 198
+    }
+    if `"`e(cmd)'"'!="mlogit" {
+        di as err "_get_mlogit_bv: model not mlogit"
+        exit 498
+    }
+
+    // get copy of e(b) and e(V)
+    matrix `b' = e(b)
+    matrix `v' = e(V)
+
+    // remove base eq if mlogit v11
+    _remove_baseeq `b' `v'
+
+    // reshape b to (ncat-1) rows by (nvars + 1) columns
+    // this is the stata 5 format used in SPost
+    local eqs: coleq `b', quoted
+    local eqs: list uniq eqs
+    tempname tmp bnew
+    local r 0
+    foreach eq of local eqs {
+        local ++r
+        mat `tmp' = `b'[1, `"`eq':"']
+        mat rown `tmp' = y`r'
+        mat `bnew' = nullmat(`bnew') \ `tmp'
+    }
+    mat coleq `bnew' = :
+    mat drop `b'
+    mat rename `bnew' `b'
+end
+
+program _remove_baseeq
+    args b v
+    if `"`b'"'=="" | `"`v'"'=="" {
+        di as err "_remove_baseeq: b and v must be specified"
+        exit 198
+    }
+    if c(stata_version) < 11    exit        // Stata 11 (or newer) only
+    if `"`e(cmd)'"'!="mlogit"   exit        // mlogit only
+    local ibase = e(k_eq_base)              // get base equation number
+    capt confirm integer number `ibase'     // check validity of ibase
+    if _rc exit
+    if `ibase'>=. | `ibase'<1   exit
+    _ms_eq_info, matrix(`b')                // get equations info
+    local l = 0                             // determine subscripts to
+    forv i = 1/`r(k_eq)' {                  // remove base equation:
+        if `i' == `ibase' continue, break   //   l = last element before
+        local l = `l' + r(k`i')             //       base eq, or 0
+    }                                       //   r = first element after
+    local i = `l'                           //       base eq, or .
+    while (`++i' <= r(k`ibase')) {          // make sure that base eq is,
+        if `b'[1,`i']!=0        exit        // in fact, a base eq (all 0)
+    }
+    local r = cond(`ibase' >= r(k_eq), ., `l' + r(k`ibase') + 1)
+    if `l' > 0 & `r' < . {                  // base eq within
+        mat `b' = `b'[1..., 1..`l'] , `b'[1..., `r'...]
+        mat `v' = `v'[1..., 1..`l'] , `v'[1..., `r'...]
+        mat `v' = `v'[1..`l', 1...] \ `v'[`r'..., 1...]
+    }
+    else if `r' < . {                       // base eq at beginning
+        mat `b' = `b'[1..., `r'...]
+        mat `v' = `v'[1..., `r'...]
+        mat `v' = `v'[`r'..., 1...]
+    }
+    else if `l' > 0 {                       // base eq at end
+        mat `b' = `b'[1..., 1..`l']
+        mat `v' = `v'[1..., 1..`l']
+        mat `v' = `v'[1..`l', 1...]
+    }
+end
diff --git a/Modules/ado/plus/_/_get_mlogit_bvecv.ado b/Modules/ado/plus/_/_get_mlogit_bvecv.ado
new file mode 100644
index 0000000..21724c8
--- /dev/null
+++ b/Modules/ado/plus/_/_get_mlogit_bvecv.ado
@@ -0,0 +1,85 @@
+*! version 1.0.0 2009-10-21 jsl
+*    - based on _get_mlogit_bv but leave b as vector
+
+*  get stata e(b) and e(V) from -mlogit- and reshape
+*  to the format used by SPost based on Stata 9
+
+capture program drop _get_mlogit_bvecv
+capture program drop _remove_baseeq
+program _get_mlogit_bvecv
+    version 9
+    args b v
+    if `"`b'"'=="" | `"`v'"'=="" {
+        di as err "_get_mlogit_bv: names for b and v must be specified"
+        exit 198
+    }
+    if `"`e(cmd)'"'!="mlogit" {
+        di as err "_get_mlogit_bv: model not mlogit"
+        exit 498
+    }
+
+    // get copy of e(b) and e(V)
+    matrix `b' = e(b)
+    matrix `v' = e(V)
+
+    // remove base eq if mlogit v11
+    _remove_baseeq `b' `v'
+
+/*
+    // reshape b to (ncat-1) rows by (nvars + 1) columns
+    // this is the stata 5 format used in SPost
+    local eqs: coleq `b', quoted
+    local eqs: list uniq eqs
+    tempname tmp bnew
+    local r 0
+    foreach eq of local eqs {
+        local ++r
+        mat `tmp' = `b'[1, `"`eq':"']
+        mat rown `tmp' = y`r'
+        mat `bnew' = nullmat(`bnew') \ `tmp'
+    }
+    mat coleq `bnew' = :
+    mat drop `b'
+    mat rename `bnew' `b'
+*/    
+end
+
+program _remove_baseeq
+    args b v
+    if `"`b'"'=="" | `"`v'"'=="" {
+        di as err "_remove_baseeq: b and v must be specified"
+        exit 198
+    }
+    if c(stata_version) < 11    exit        // Stata 11 (or newer) only
+    if `"`e(cmd)'"'!="mlogit"   exit        // mlogit only
+    local ibase = e(k_eq_base)              // get base equation number
+    capt confirm integer number `ibase'     // check validity of ibase
+    if _rc exit
+    if `ibase'>=. | `ibase'<1   exit
+    _ms_eq_info, matrix(`b')                // get equations info
+    local l = 0                             // determine subscripts to
+    forv i = 1/`r(k_eq)' {                  // remove base equation:
+        if `i' == `ibase' continue, break   //   l = last element before
+        local l = `l' + r(k`i')             //       base eq, or 0
+    }                                       //   r = first element after
+    local i = `l'                           //       base eq, or .
+    while (`++i' <= r(k`ibase')) {          // make sure that base eq is,
+        if `b'[1,`i']!=0        exit        // in fact, a base eq (all 0)
+    }
+    local r = cond(`ibase' >= r(k_eq), ., `l' + r(k`ibase') + 1)
+    if `l' > 0 & `r' < . {                  // base eq within
+        mat `b' = `b'[1..., 1..`l'] , `b'[1..., `r'...]
+        mat `v' = `v'[1..., 1..`l'] , `v'[1..., `r'...]
+        mat `v' = `v'[1..`l', 1...] \ `v'[`r'..., 1...]
+    }
+    else if `r' < . {                       // base eq at beginning
+        mat `b' = `b'[1..., `r'...]
+        mat `v' = `v'[1..., `r'...]
+        mat `v' = `v'[`r'..., 1...]
+    }
+    else if `l' > 0 {                       // base eq at end
+        mat `b' = `b'[1..., 1..`l']
+        mat `v' = `v'[1..., 1..`l']
+        mat `v' = `v'[1..`l', 1...]
+    }
+end
diff --git a/Modules/ado/plus/_/_peabbv.ado b/Modules/ado/plus/_/_peabbv.ado
new file mode 100644
index 0000000..9207630
--- /dev/null
+++ b/Modules/ado/plus/_/_peabbv.ado
@@ -0,0 +1,17 @@
+*! version 1.6.0 3/29/01
+
+capture program drop _peabbv
+program define _peabbv
+    cap version 7
+    if _rc == 0 {
+        local matnm "`1'"
+        local nms : colnames `matnm'
+        tokenize `nms'
+        while "`1'"!="" {
+            local x = abbrev("`1'", 12)
+            local newnms "`newnms'`x' "
+            macro shift
+        }
+        mat colnames `matnm' = `newnms'
+    }
+end
diff --git a/Modules/ado/plus/_/_pebase.ado b/Modules/ado/plus/_/_pebase.ado
new file mode 100644
index 0000000..a2a8370
--- /dev/null
+++ b/Modules/ado/plus/_/_pebase.ado
@@ -0,0 +1,342 @@
+*! version 1.6.5 2007-02-08 - rest(zero)
+
+capture program drop _pebase
+program define _pebase, rclass
+    version 6.0
+    tempvar tmp input tmp2 peb2 xmin xmax chtest mark
+    tempname tobase tobase2 b min max mean median min2 max2 mean2 median2 prev prev2
+
+    if "`e(cmd)'"=="ztp"        { local flags "none" }
+    if "`e(cmd)'"=="ztnb"       { local flags "none" }
+    if "`e(cmd)'"=="logit"      { local flags "none" }
+    if "`e(cmd)'"=="logistic"   { local flags "none" }
+    if "`e(cmd)'"=="probit"     { local flags "none" }
+    if "`e(cmd)'"=="cloglog"    { local flags "none" }
+    if "`e(cmd)'"=="ologit"     { local flags "none" }
+    if "`e(cmd)'"=="oprobit"    { local flags "none" }
+    if "`e(cmd)'"=="gologit"    { local flags "noupper" }
+    if "`e(cmd)'"=="mlogit"     { local flags "noupper" }
+    if "`e(cmd)'"=="mprobit"    { local flags "noupper" }
+    if "`e(cmd)'"=="slogit"     { local flags "noupper" }
+    if "`e(cmd)'"=="clogit"     { local flags "noupper" }
+    if "`e(cmd)'"=="poisson"    { local flags "none" }
+    if "`e(cmd)'"=="nbreg"      { local flags "none" }
+    if "`e(cmd)'"=="zip"        { local flags "twoeq noupper" }
+    if "`e(cmd)'"=="zinb"       { local flags "twoeq noupper" }
+    if "`e(cmd)'"=="tobit"      { local flags "none" }
+    if "`e(cmd)'"=="intreg"     { local flags "none" }
+    if "`e(cmd)'"=="cnreg"      { local flags "none" }
+    if "`e(cmd)'"=="fit"        { local flags "none" }
+    if "`e(cmd)'"=="regress"    { local flags "none" }
+    if "`flags'"=="" {
+        di in r "_pebase does not work with `e(cmd)'"
+        exit 198
+    }
+
+*-> unpack flags: define relevant special features of different models
+
+    *flag twoeq -- 2 equation model like zip or zinb
+    if index("`flags'", "twoeq") == 0 { local twoeq "no" }
+    else { local twoeq "yes" }
+    *flag noupper -- do not allow upper and lower for rest()
+    if index("`flags'", "noupper") == 0 { local noupper "no" }
+    else { local noupper "yes" }
+
+* options:
+*   x: specified x variable values
+*   rest: what to set remaining values to
+*   choices: choices after clogit
+*   all
+
+    syntax [if] [in] [, x(passthru) rest(string) choices(varlist) all]
+
+    *set flag because so many if zip | zinb statements
+    local twoeq "no"
+    if "`e(cmd)'"=="zip" | "`e(cmd)'"=="zinb" {
+        local twoeq "yes"
+    }
+
+    * get names of rhs variables in models
+    _perhs
+    local rhsnms "`r(rhsnms)'"
+    local nrhs = `r(nrhs)'
+    if "`twoeq'"=="yes" {
+        local rhsnms2 "`r(rhsnms2)'"
+        local nrhs2 = `r(nrhs2)'
+    }
+
+    *go to _peife to see if you need to restrict the sample
+    _peife `if', `all'
+    local if "`r(if)'"
+
+    * get summary statistics for models (both if zip/zinb)
+    quietly _pesum `if' `in', median
+    mat `min' = r(Smin)
+    mat `min' = `min'[1, 2...]
+    mat `max' = r(Smax)
+    mat `max' = `max'[1, 2...]
+    mat `mean' = r(Smean)
+    mat `mean' = `mean'[1, 2...]
+    mat `median' = r(Smedian)
+    mat `median' = `median'[1, 2...]
+*! version 1.6.5 2007-02-08 - rest(zero)
+tempname zero
+mat `zero' = 0*`mean'
+    if "`twoeq'"=="yes" {
+        quietly _pesum `if' `in', median two
+        mat `min2' = r(Smin)
+        mat `min2' = `min2'[1, 2...]
+        mat `max2' = r(Smax)
+        mat `max2' = `max2'[1, 2...]
+        mat `mean2' = r(Smean)
+        mat `mean2' = `mean2'[1, 2...]
+*! version 1.6.5 2007-02-08 - rest(zero)
+tempname zero2
+mat `zero2' = 0*`mean2'
+        mat `median2' = r(Smedian)
+        mat `median2' = `median2'[1, 2...]
+    }
+
+    * get matrix of previous values if it exists
+    local oldpe = "yes"
+    local pematch = "yes"
+    capture mat `prev' = PE_base
+    if _rc != 0 { local oldpe "no" }
+    else {
+        local test1 : colnames(`prev')
+        local test2 : colnames(`mean')
+        if "`test1'" != "`test2'" {
+            local pematch "no"
+        }
+        if "`twoeq'"=="yes" {
+            capture mat `prev2' = PE_base2
+            if _rc != 0 { local oldpe "no" }
+            else {
+                local test1 : colnames(`prev2')
+                local test2 : colnames(`mean2')
+                if "`test1'" != "`test2'" {
+                    local pematch "no"
+                }
+            } /* else */
+        } /* if "`twoeq'"=="yes" */
+    } /* else */
+    if "`oldpe'"=="no" { local pematch = "no" }
+
+*=> decode x()
+*   tokenize `x', parse(" =")
+    tokenize `x', parse("()")
+    local x "`3'"
+    tokenize `x', parse(" =")
+
+    local allnums = "yes"
+    local xchngs = 0   /* number of x changes proposed */
+    while "`1'" != "" {
+        while "`2'"=="=" | "`2'"=="==" {
+            local temp1 "`1'"
+            macro shift
+            local 1 "`temp1'"
+        }
+        if "`2'"=="" {
+            di _newline in red "Odd number of arguments in x()"
+            error 198
+        }
+        local xchngs = `xchngs' + 1
+        local cvar`xchngs' "`1'"
+        *make sure variable is rhs variable
+        local found "no"
+        local i2 = 1
+        while `i2' <= `nrhs' {
+            local rhschk : word `i2' of `rhsnms'
+            unab 1 : `1', max(1)
+            if "`1'"=="`rhschk'" {
+                local found "yes"
+                local cvno`xchngs' `i2'
+                local i2 = `nrhs'
+            }
+            local i2 = `i2' + 1
+        }
+        *check in binary equation if zip/zinb
+        if "`twoeq'"=="yes" {
+            local i3 = 1
+            while `i3' <= `nrhs2' {
+                local rhschk : word `i3' of `rhsnms2'
+                if "`1'"=="`rhschk'" {
+                    local found "yes"
+                    local cvn2`xchngs' `i3'
+                    local i3 = `nrhs2'
+                }
+                local i3 = `i3' + 1
+            }
+        }
+        if "`found'"=="no" {
+            di in r "`1' not rhs variable"
+            error 198
+        }
+        *make sure value is legal
+        local cval`xchngs' "`2'"
+        if "`2'"=="mean" | "`2'"=="median" | "`2'"=="min" | /*
+        */  "`2'"=="max" | "`2'"=="grmean" | "`2'"=="grmedian" | /*
+        */  "`2'"=="grmin" | "`2'"=="grmax" | "`2'"=="upper" | /*
+        */  "`2'"=="lower" | "`2'"=="previous" | "`2'"=="old" {
+            local allnums = "no"
+        }
+        else {
+            confirm number `2'
+            local cexp`xchngs' "`cvar`xchngs'' == `cval`xchngs''"
+        }
+        macro shift 2
+    } /* while `1' != "" { */
+
+    *set matrix to 'rest' values
+    *rest default is mean
+    if "`rest'" == "" { 
+        local rest = "mean" 
+    }
+
+    if "`rest'"=="previous" | "`rest'"=="old" {
+        mat `tobase' = `prev'
+        if "`twoeq'"=="yes" { 
+            mat `tobase2' = `prev' 
+        }
+    }
+
+*! version 1.6.5 2007-02-08 - rest(zero)
+    else if "`rest'"=="mean" | "`rest'"=="max" | "`rest'"=="min" | ///
+          "`rest'"=="median" | "`rest'"=="zero" {
+        mat `tobase' = ``rest''
+        if "`twoeq'"=="yes" { 
+            mat `tobase2' = ``rest'2' 
+        }
+    }
+
+
+    else if "`rest'"=="grmean" | "`rest'"=="grmax" | "`rest'"=="grmin" | "`rest'"=="grmedian" {
+        if "`allnums'"!="yes" {
+            di in r "`rest' not allowed if x() values not all real numbers"
+            exit 198
+        } /* if "`allnums'"!="yes" */
+        qui gen `mark' = 1 `if'
+        local i = 1
+        while `i' <= `xchngs' {
+            qui replace `mark' = . if ~(`cexp`i'')
+            local i = `i' + 1
+        } /* while i <= `xchngs' */
+
+        _pesum if `mark' == 1, median
+        if "`rest'"=="grmean"   { mat `tobase' = r(Smean)   }
+        if "`rest'"=="grmax"    { mat `tobase' = r(Smax)    }
+        if "`rest'"=="grmin"    { mat `tobase' = r(Smin)    }
+        if "`rest'"=="grmedian" { mat `tobase' = r(Smedian) }
+        mat `tobase' = `tobase'[1, 2...]
+        if "`twoeq'"=="yes" {
+            _pesum if `mark' == 1, median two
+            if "`rest'"=="grmean"   { mat `tobase2' = r(Smean)   }
+            if "`rest'"=="grmax"    { mat `tobase2' = r(Smax)    }
+            if "`rest'"=="grmin"    { mat `tobase2' = r(Smin)    }
+            if "`rest'"=="grmedian" { mat `tobase2' = r(Smedian) }
+            mat `tobase2' = `tobase2'[1, 2...]
+        } /* if "`twoeq'"=="yes" */
+    } /* else if "`rest'"=="grmean"... */
+
+    else if "`rest'"=="upper" | "`rest'"=="lower" {
+        if "`noupper'"=="yes" {
+            di in r "rest(`rest') not permitted after `e(cmd)'"
+            exit 198
+        } /* if "`noupper'"=="yes" */
+        capture matrix `b' = e(b)
+        mat `tobase' = r(Smax)
+        mat `tobase' = `tobase'[1, 2...]
+        mat `xmin' = r(Smin)
+        mat `xmin' = `xmin'[1, 2...]
+        local nvars = colsof(`tobase')
+        local i = 1
+        while `i' <= `nvars' {
+            if "`rest'"=="upper" & `b'[1,`i']<0 {
+                mat `tobase'[1, `i'] == `xmin'[1, `i']
+            }
+            if "`rest'"=="lower" & `b'[1,`i']>0 {
+                mat `tobase'[1, `i'] == `xmin'[1, `i']
+            }
+            local i = `i' + 1
+        } /* while `i' <= `nvars' */
+
+    }
+    else {
+        di in red "rest(`rest') not allowed"
+        error 999
+    }
+
+    * set specific values of tobase and tobase2...
+    local i = 1
+    while `i' <= `xchngs' {
+        if "`cvno`i''"!="" {
+            if "`cval`i''"=="mean" | "`cval`i''"=="median" | /*
+            */ "`cval`i''"=="min" | "`cval`i''"=="max" {
+                mat `tobase'[1, `cvno`i''] = ``cval`i'''[1, `cvno`i'']
+            }
+            else if "`cval`i''"=="previous" {
+                mat `tobase'[1, `cvno`i''] = `prev'[1, `cvno`i'']
+            }
+            else if "`cval`i''"=="upper" | "`cval`i''"=="lower" {
+                if "`noupper'"=="yes" {
+                    di in r "`rest' not permitted in x() after `e(cmd)'"
+                    exit 198
+                } /* if "`noupper'"=="yes" */
+                capture matrix `b' = e(b)
+                if "`cval`i''"=="upper" {
+                    if `b'[1,`cvno`i'']<0 {
+                        mat `tobase'[1, `cvno`i''] == `min'[1, `cvno`i'']
+                    }
+                    else {
+                        mat `tobase'[1, `cvno`i''] == `max'[1, `cvno`i'']
+                    }
+                }
+                if "`cval`i''"=="lower" {
+                    if `b'[1,`cvno`i'']>0 {
+                        mat `tobase'[1, `cvno`i''] == `min'[1, `cvno`i'']
+                    }
+                    else {
+                        mat `tobase'[1, `cvno`i''] == `max'[1, `cvno`i'']
+                    }
+                }
+            } /* if "`cval`i''"=="upper" | "`cval`i''"=="lower" */
+            else { mat `tobase'[1, `cvno`i''] = `cval`i'' }
+        } /* if "`cvno`i'"!="" */
+
+        if "`cvn2`i''"!="" {
+            if "`cval`i''"=="mean" | "`cval`i''"=="median" /*
+            */ | "`cval`i''"=="min" | "`cval`i''"=="max" {
+                mat `tobase2'[1, `cvn2`i''] = ``cval`i'''[1, `cvn2`i'']
+            }
+            else if "`cval`i''"=="previous" {
+                mat `tobase2'[1, `cvn2`i''] = `prev'[1, `cvn2`i'']
+            }
+            else { mat `tobase2'[1, `cvn2`i''] = `cval`i'' }
+        } /* if "`cvn2`i'"!="" */
+
+    local i = `i' + 1
+    } /* while i <= `xchngs' */
+
+    if "`choices'"!="" { return local choices `choices' }
+    mat rownames `tobase' = x
+    mat PE_base = `tobase'
+    return matrix pebase `tobase'
+    return local nrhs "`nrhs'"
+    return local rhsnms "`rhsnms'"
+    if "`twoeq'"=="yes" {
+        mat rownames `tobase2' = x_eq2
+        mat PE_base2 = `tobase2'
+        return matrix pebase2 `tobase2'
+        return local nrhs2 "`nrhs2'"
+        return local rhsnms2 "`rhsnms2'"
+    }
+end
+
+exit
+
+*History
+* version 1.6.4 13Apr2005
+* version 1.6.3 27Mar2005 slogit
+* version 1.6.2 28Feb2005 mprobit
+* version 1.6.1 18Feb2005 ztp & ztnb
+* version 1.6.0 3/29/01
diff --git a/Modules/ado/plus/_/_pebase.hlp b/Modules/ado/plus/_/_pebase.hlp
new file mode 100644
index 0000000..b7bd5f2
--- /dev/null
+++ b/Modules/ado/plus/_/_pebase.hlp
@@ -0,0 +1,54 @@
+.-
+help for ^_pebase^ - 1.6.5 2007-02-08
+.-
+
+    _pebase [if] [in] [, x(variables_and_values) rest(stat) all]
+
+    where
+
+    ^variables_and_values^ is an alternating list of variables and either
+        numeric values or mean, median, min, max, upper, lower, previous
+
+    ^stat^ is either mean, median, min, max, upper, lower, previous, zero, 
+        grmean (group mean), grmedian, grmin, grmax
+
+
+^_pebase^ is a utility command for programming commands that require the user
+to set specific values for the independent variables in regression.
+
+Values of the independent variables are set using the ^x()^, ^rest()^, and ^all^
+options.  These can be passed directly from the user input for the 
+programmer's command to ^_pebase^.
+
+Options
+-------
+
+^x()^ sets the values of independent variables for calculating predicted
+    values.  The list must alternate variable names and either numeric values
+    or types of ^stat^.  
+
+^rest()^ sets the independent variables not specified in x() to one of the 
+    types of ^stat^.  Type ^help prstar^ for more details about using ^x()^ and
+    ^rest^.
+
+^all^ specifies that any calculations of means, medians, etc., should use
+    the entire sample instead of the sample used to estimate the model.
+
+Output of _pebase
+-----------------
+
+PE_base: global matrix containing set values of independent variables
+
+r(pebase): r() class matrix containing set values of independent variables
+
+r(nrhs): r() class macro containing number of independent variables
+
+r(rhsnms): r() class macro containing names of independent variables
+
+PE_base2, r(pebase2), r(nrhs2), r(rhsnms): same as above but for the 
+    second equation of two-equation commands like ^zip^ and ^zinb^.
+
+.-
+Authors: J. Scott Long and Jeremy Freese
+         www.indiana.edu/~jslsoc/spost.htm
+         spostsup@@indiana.edu
diff --git a/Modules/ado/plus/_/_pecats.ado b/Modules/ado/plus/_/_pecats.ado
new file mode 100644
index 0000000..cbd2a74
--- /dev/null
+++ b/Modules/ado/plus/_/_pecats.ado
@@ -0,0 +1,172 @@
+*! version 1.7.3 2007-06-29 Stata 10 fix for categories
+
+capture program drop _pecats
+program define _pecats, rclass
+    version 6.0
+    tempname refval valnum rcount
+    scalar `refval' = -999
+    syntax [varlist(max=1 default=none)] [if] [in]
+
+* only return values for models with categorical outcomes
+    if "`varlist'" == "" & ( /*
+    */ "`e(cmd)'"!="logit"    &  /*
+    */ "`e(cmd)'"!="logistic" &  /*
+    */ "`e(cmd)'"!="probit"   &  /*
+    */ "`e(cmd)'"!="cloglog"  &  /*
+    */ "`e(cmd)'"!="ologit"   &  /*
+    */ "`e(cmd)'"!="oprobit"  &  /*
+    */ "`e(cmd)'"!="mlogit"   &  /*
+    */ "`e(cmd)'"!="mprobit"   &  /*
+    */ "`e(cmd)'"!="gologit"  &  /*
+    */ "`e(cmd)'"!="clogit"   &  /*
+    */ "`e(cmd)'"!="slogit"   &  /*
+    */ ) {
+        if "`e(cmd)'"=="tobit" /*
+        */ | "`e(cmd)'"=="intreg" /*
+        */ | "`e(cmd)'"=="cnreg" /*
+        */ | "`e(cmd)'"=="regress" /*
+        */ | "`e(cmd)'"!="poisson" /*
+        */ | "`e(cmd)'"!="nbreg" /*
+        */ | "`e(cmd)'"!="ztp" /*
+        */ | "`e(cmd)'"!="ztnb" /*
+        */ | "`e(cmd)'"!="zip" /*
+        */ | "`e(cmd)'"!="zinb"    {
+            return scalar numcats = 2
+        }
+        exit
+    }
+
+    * numeric value of reference category of mlogit
+* 2007-06-29 stata 10 fix    
+if c(stata_version) < 10 {
+    
+    if "`e(cmd)'"=="mlogit" { scalar `refval' = e(basecat) }
+    if "`e(cmd)'"=="mprobit" { scalar `refval' = e(i_base) }
+}
+else {
+    if "`e(cmd)'"=="mlogit" { scalar `refval' = e(baseout) }
+    if "`e(cmd)'"=="mprobit" { scalar `refval' = e(i_base) }
+}
+
+    * determine names and values of outcome categories
+    local catnms ""
+    if "`varlist'" != "" {
+        local lhs `varlist'
+        quietly tabulate `1' `if' `in', matrow(`valnum') matcell(`rcount')
+    }
+    if "`varlist'" == "" {
+        local lhs "`e(depvar)'"
+        quietly tabulate `e(depvar)' if e(sample)==1, matrow(`valnum') matcell(`rcount')
+    }
+    local nrows = rowsof(`valnum')
+
+    * grab value labels
+    local vallbl : value label `lhs'
+    local i = 1
+    while `i' <= `nrows' {
+        local vali = `valnum'[`i',1]
+
+        * if value labels have been declared
+        if "`vallbl'" != "" {
+            local valnm : label `vallbl' `vali'
+            if "`valnm'" == "" { local valnm = `vali' }
+            * change blanks to _'s
+            local valnm = trim("`valnm'")
+            local bloc = index("`valnm'"," ")
+            while `bloc' != 0 {
+                local bloc = `bloc' - 1
+                local bloc2 = `bloc' + 2
+                local valnm = trim(substr("`valnm'",1,`bloc') /*
+                */ + "_" + substr("`valnm'",`bloc2',.))
+                local bloc = index("`valnm'"," ")
+            }
+            * change :'s to _'s
+            local bloc = index("`valnm'",":")
+            while `bloc' != 0 {
+                local bloc = `bloc' - 1
+                local bloc2 = `bloc' + 2
+                local valnm = trim(substr("`valnm'",1,`bloc') /*
+                */ + "_" + substr("`valnm'",`bloc2',.))
+                local bloc = index("`valnm'",":")
+            }
+            * change {'s to _'s
+            local bloc = index("`valnm'","{")
+            while `bloc' != 0 {
+                local bloc = `bloc' - 1
+                local bloc2 = `bloc' + 2
+                local valnm = trim(substr("`valnm'",1,`bloc') /*
+                */ + "_" + substr("`valnm'",`bloc2',.))
+                local bloc = index("`valnm'","{")
+            }
+
+        }
+
+        * if no value labels, then use value numbers
+        else { local valnm `vali' }
+
+        * change .'s to _'s
+        local bloc = index("`valnm'",".")
+        while `bloc' != 0 {
+            local bloc = `bloc' - 1
+            local bloc2 = `bloc' + 2
+            local valnm = trim(substr("`valnm'",1,`bloc') /*
+            */ + "_" + substr("`valnm'",`bloc2',.))
+            local bloc = index("`valnm'",".")
+        }
+
+
+        * if current value is refernce value, store it
+        if `vali'==`refval' {
+            local refnm `valnm'
+            local refval `vali'
+        }
+        else {
+            local catnms  `catnms'  `valnm'
+            local catvals `catvals' `vali'
+
+            *handle long label names for catnms8
+            if length("`valnm'") > 8 { local valnm = substr("`valnm'", 1, 8) }
+            local catnms8 `catnms8' `valnm'
+        }
+        local i = `i' + 1
+    }
+
+    * place reference value at end for mlogit
+    if `refval'!=-999 {
+        local catnms  `catnms'  `refnm'
+        local catvals `catvals' `refval'
+
+        *handle long label names for catnms8
+        if length("`refnm'") > 8 { local refnm = substr("`refnm'", 1, 8) }
+        local catnms8 `catnms8' `refnm'
+    }
+
+    * logit probit clogit for case of 0 vs > 0
+    if "`varlist'"=="" & /*
+    */ ("`e(cmd)'"=="logit" | "`e(cmd)'"=="probit" | "`e(cmd)'"== "clogit" | "`e(cmd)'"=="cloglog" ) /*
+        */ & `nrows'~=2 {
+            local catnms 0 ~0
+            local catvals 0 ~0
+            local catnms8 0 ~0
+    }
+
+    *number of categories as catnum
+    local numcats : word count `catnms'
+
+    *return information about reference category if mlogit
+    if "`varlist'"=="" & "`e(cmd)'" == "mlogit" {
+        return scalar refval =`refval'
+        return local refnm "`refnm'"
+    }
+
+    return local catnms  "`catnms'"
+    return local catvals "`catvals'"
+    return local catnms8 "`catnms8'"
+    return scalar numcats = `numcats'
+
+end
+exit
+* version 1.7.2 13Apr2005
+* version 1.7.1 27Mar2005 slogit
+* version 1.7.0 28Feb2005 mprobit
+* version 1.6.9 18Feb2005 ztp and ztnb
diff --git a/Modules/ado/plus/_/_pecats.hlp b/Modules/ado/plus/_/_pecats.hlp
new file mode 100644
index 0000000..9af0919
--- /dev/null
+++ b/Modules/ado/plus/_/_pecats.hlp
@@ -0,0 +1,61 @@
+.-
+help for ^_pecats^ - 1.6.6 - 3/4/00
+.-
+
+Utility to determine names and values of categories of dependent variable
+-------------------------------------------------------------------------
+
+    ^_pecats^ [varname] [^if^ exp] [^in^ range]
+
+Description
+-----------
+
+^_pecats^ returns the names and values of the categories for models with
+ordinal, nominal, or binary outcomes. For ^mlogit^ it indicates the value
+of the reference category.
+
+NOTE: If no variable name is specified, _pecats will use the dependent
+variable retrieved from `e(depvar)' and will restrict the sample according
+to e(sample)
+
+Returns
+-------
+
+r(numcats): scalar value containing number of categories of depvar.
+
+r(refval):  scalar value of the reference category for ^mlogit^.
+
+r(refnm):   local macro with name of the reference category for ^mlogit^.
+
+r(catnms):  local macro with names of categories of the dependent variable.
+            For ^mlogit^ the reference category is given last.
+
+r(catnms):  local macro with names of categories of the dependent variable.
+            For ^mlogit^ the reference category is given last.
+
+r(catnms8): local macro with names of categories of the dependent variable.
+            Value labels longer than 8 characters are truncated to 8
+            characters so they can be used as matrix row/column names. For
+            ^mlogit^ the reference category is given last.
+
+r(catvals): local macro with values of categories of the dependent variable.
+            For ^mlogit^ the reference value is given last.
+
+Examples within a program
+-------------------------
+
+    ...
+    * `if' is the curret if condition
+    _peife `if'
+    * the new condition includes "& e(sample)
+    local eif "`r(if)'"
+    _pecats `e(depvar)' `eif' `in'
+    local cnames r(catnms)
+    local cvals r(catvals)
+    local refval r(refval)
+
+.-
+Authors: J. Scott Long and Jeremy Freese
+         www.indiana.edu/~jslsoc/spost.htm
+         spostsup@@indiana.edu
+         
diff --git a/Modules/ado/plus/_/_peciboot.ado b/Modules/ado/plus/_/_peciboot.ado
new file mode 100644
index 0000000..4c4d6d0
--- /dev/null
+++ b/Modules/ado/plus/_/_peciboot.ado
@@ -0,0 +1,629 @@
+*! version 1.0.0 2009-10-28 jsl
+*   - stata 11 fix
+
+//  bootstrap for prvalue
+capture program drop _peciboot
+program define _peciboot, rclass
+
+    version 8.0
+    syntax [if] [in] [, x(passthru) rest(passthru) all ///
+                     save diff ///
+                     Reps(int 1000)  SIze(int -9) dots ///
+                     ITERate(passthru) match SAving(string)]
+
+    tempname post_name lastest p_obsmat pdif_obsmat pci_mat pdifci_mat ///
+            probs1 probs2 probsdif ///
+            tempbase tempbase2
+    tempname mu_obs mudif_obs mu mudif ///
+            all0_obs all0dif_obs all0 all0dif
+    tempname p_obs p_avg p_std p_normlo p_normup ///
+            pdif_obs pdif_avg pdif_std pdif_normlo pdif_normup ///
+            p_pctlo p_pctup pdif_pctlo pdif_pctup z t tdf ///
+            totobs zpr zdc p_bcup p_bclo pdif_bcup pdif_bclo
+    tempname orig_pred orig_info orig_type orig_base orig_base2 ///
+            orig_upper orig_lower orig_upnorm orig_lonorm ///
+            orig_upbias orig_lobias
+    tempvar touse
+    tempfile original post_file
+
+    * store information to restore when bootstrapping is done
+    mat `orig_pred' = pepred
+    mat `orig_info' = peinfo
+    mat `orig_base' = pebase
+    mat `orig_upper' = peupper
+    mat `orig_lower' = pelower
+
+    * get information on model that has been estimated
+    local io $petype
+    local maxcnt = peinfo[1,11] // get max # of counts compute
+    if "`maxcnt'"=="." {
+        local maxcnt = 9
+    }
+    local cmd : word 1 of $petype // specific model command
+    local input : word 2 of $petype // typical or twoeq
+    local output : word 3 of $petype // output type
+    local depvar "`e(depvar)'" // dep var
+    local numcats = peinfo[1,2]
+    forval i = 1/`numcats' { // construct string with outcome categories
+        local curval = pepred[1, `i']
+        local catvals "`catvals'`cutval' "
+    }
+    local rhsnms : colnames(pebase)
+    if "`input'"=="twoeq" {
+        local rhsnms2 : colnames(pebase2)
+    }
+    local wtype "`e(wtype)'" // weight type
+    local wexp "`e(wexp)'" // weight expression
+    local nocon = "" // constant in model
+    if peinfo[1,6]==1 {
+        local nocon "nocon"
+    }
+    local inout "`input' `output'"
+    if "`input'"=="twoeq" {
+        mat `orig_base2' = pebase2
+    }
+    local nobs = e(N) // observations in original estimation sample
+    local level = peinfo[1,3]
+    scalar `z' = peinfo[1,4]
+
+    * trap improper use of match option
+    if ("`output'"!="binary" & "`output'"!="ordered" ///
+            & "`output'"!="mlogit") & "`match'"!="" {
+        di as error ///
+        "Error: match works only with binary, ordered, and mlogit routines."
+        exit
+    }
+
+    * create touse indicating cases in the original estimatin sample
+    mark `touse' if e(sample)
+    if "`size'"=="-9" | "`size'"=="" { // -9 is default for size
+        local size = e(N)
+    }
+    if "`size'"!="" & `size'>e(N) {
+        di as error ///
+            "Error: resample size is larger than the number of observations"
+        exit
+    }
+
+    * create list of variables and expressions used by post commands
+    forval i = 1/`numcats' {
+        tempname  p`i'
+        local post_var "`post_var'`p`i'' "
+        local post_exp "`post_exp'(`p`i'') "
+        if "`diff'"!="" {
+            tempname p`i'dif
+            local post_var "`post_var'`p`i'dif' "
+            local post_exp "`post_exp'(`p`i'dif') "
+        }
+    }
+
+    * count # of statistics to bootstrap
+    local nstats = `numcats' // # of statistics being bootstrapped
+    if  "`output'"=="count" {
+        local nstats = `nstats' + 1 // add mu
+        local post_exp "`post_exp'(`mu') "
+        local post_var "`post_var'`mu' "
+        if "`diff'"!="" {
+            local post_exp "`post_exp'(`mudif') "
+            local post_var "`post_var'`mudif' "
+        }
+    }
+    if  "`input'"=="twoeq"  {
+        local nstats = `nstats' + 1 // add pr always 0
+        local post_exp "`post_exp'(`all0') "
+        local post_var "`post_var'`all0' "
+        if "`diff'"!="" {
+            local post_exp "`post_exp'(`all0dif') "
+            local post_var "`post_var'`all0dif' "
+        }
+    }
+
+     local dots = cond("`dots'"=="", "*", "noisily")
+
+//  STORE OBSERVED ESTIMATES
+
+    * get predictions for prob and discrete change
+    mat `p_obsmat' = (pepred[2, 1...])'
+    if "`diff'"!="" {
+        mat `pdif_obsmat' = (pepred[6,1...])'
+    }
+
+    * get rate and pr always 0
+    if  "`output'"=="count" {
+        scalar `mu_obs' = pepred[3,2]
+        if "`diff'"!="" {
+            scalar `mudif_obs' = pepred[7,2]
+        }
+    }
+    if  "`input'"=="twoeq" {
+        scalar `all0_obs' = pepred[3,4]
+        if "`diff'"!="" {
+            scalar `all0dif_obs' = pepred[7,4]
+        }
+    }
+
+    * hold non-bootstrap estimation results; restore later
+    _estimates hold `lastest', restore
+
+    if "`match'"!="" {
+        preserve // #1
+        quietly keep if `touse'
+        quietly save `original'
+        restore // #1
+    }
+
+    postfile `post_name' `post_var' using `post_file'
+
+//  BEGIN SIMULATIONS
+
+    quietly {
+
+        * # of replications missed due to nonconvergence
+        local nmissed = 0
+
+        forval i = 1/`reps' {
+
+            `dots' dodot `reps' `i'
+            preserve // #2
+
+            * if match, resample within outcome categories
+            if "`match'"!="" {
+                tempname samppct catsize
+                scalar `samppct' = `size' / `nobs'
+
+                forval i = 1/`numcats' {
+                    tempfile cat`i'file
+                    use `original', clear
+                    local cur_val: word `i' of `catvals'
+                    local depval`i' "`cur_depval'"
+                    keep if `depvar'==`cur_val'
+                    count
+                    scalar `catsize' = `samppct'*r(N)
+                    local resamp = round(`catsize',1)
+                    if `catsize'==0 {
+                        local resamp = 1
+                    }
+                    bsample `resamp'
+                    save `cat`i'file'
+                }
+
+                * stack data from all categories
+                use `cat1file', clear
+                forval i = 2/`numcats' {
+                    append using `cat`i'file'
+                }
+            } // matched
+
+            * if match option not specified
+            else {
+
+                keep if `touse'
+                bsample `size'
+
+                * check if boot sample has all outcome categories
+                if "`output'"!="count" {
+                    _pecats `depvar'
+                    local catschk = r(numcats)
+                    * if category missed, count it, and take another sample
+                    if `catschk' != `numcats' {
+                        local ++nmissed // count missed replication
+                        local errlog "`errlog'`i', "
+                        restore
+                        continue
+                    }
+                }
+            } // no matched
+
+//  ESTIMATE MODEL WITH BOOTSTRAP SAMPLE
+
+            capture { // trap errors in estimation
+
+                if "`input'" == "typical" {
+                    `cmd' `depvar' `rhsnms' ///
+                            if `touse' [`wtype'`wexp'], `iterate' `nocon'
+                }
+                else if "`input'" == "twoeq" {
+                    `cmd' `depvar' `rhsnms' ///
+                            if `touse' [`wtype'`wexp'], ///
+                            inflate(`rhsnms2') `iterate' `nocon'
+                }
+
+                * get base values for bootstrap sample
+                _pebase `if' `in', `x' `rest' `all'
+                mat `tempbase' = r(pebase)
+                mat PE_in = `tempbase'
+                if "`input'"=="twoeq" {
+                    mat `tempbase2' = r(pebase2)
+                    mat PE_in2 = `tempbase2'
+                }
+
+                * get predictions
+                _pepred, level(`level') maxcnt(`maxcnt')
+                local tmp2 = r(maxcount)
+                local tmp = r(level)
+                capture _return drop pepred
+                _return hold pepred
+                _return restore pepred, hold
+                * put results from bootstrap estimate into global matrices
+                _pecollect, inout(`inout') level(`tmp') ///
+                        maxcount(`tmp2') `diff'
+
+            } // capture
+
+            * if error in estimation, count it as missed
+            if _rc!=0 {
+                local ++nmissed
+                local errlog "`errlog'`i', "
+                restore
+                continue
+            }
+
+            * get predicted probabilities
+            mat `probs1'= (pepred[2, 1...])'
+            * get mu and pr(always 0) from count models
+            if  "`output'"=="count" {
+                scalar `mu' = pepred[3,2]
+            }
+            if  "`input'"=="twoeq"  {
+                scalar `all0' = pepred[3,4]
+            }
+
+//  DISCRETE CHANGES
+
+            if "`diff'"!="" {
+
+                capture {
+
+                    * $pexsetup hold x() rest() all from prior prvalue
+                    _pebase `if' `in', $pexsetup
+                    mat `tempbase' = r(pebase)
+                    mat `tempbase2' = r(pebase2)
+                    mat PE_in = `tempbase'
+                    if "`input'"=="twoeq" {
+                        mat PE_in2 = `tempbase2'
+                    }
+                    _pepred, level(`level') maxcnt(`maxcnt')
+                    local tmp2 = r(maxcount)
+                    local tmp = r(level)
+                    _return drop _all
+                    _return hold pepred
+                    _return restore pepred, hold
+                    _pecollect, inout(`inout') level(`tmp') ///
+                            maxcount(`tmp2') `diff'
+
+                } // end of capture
+
+                if _rc !=0 { // if error in estimation
+                    local ++nmissed // count missed replication
+                    local errlog "`errlog'`i', "
+                    restore
+                    continue
+                }
+
+                mat `probs2' = (pepred[2, 1...])'
+                mat `probsdif' = `probs1' - `probs2'
+
+                * get results from count models
+                if  "`output'"=="count" {
+                    scalar `mudif' = -1 * pepred[7,2]
+                }
+                if  "`input'"=="twoeq"  {
+                    scalar `all0dif' = -1 * pepred[7,4]
+                }
+
+            } // end of diff loop
+
+//  POST RESULTS
+
+            * move probs from matrices to scalars for posting
+            forval j = 1/`numcats' {
+                scalar `p`j'' = `probs1'[`j', 1]
+                if "`diff'"!="" {
+                    scalar `p`j'dif' = `probsdif'[`j', 1]
+                }
+            }
+            post `post_name' `post_exp'
+
+            restore // #2
+
+        } // end of replications loop
+
+        postclose `post_name' // close postfile
+
+//  CONSTRUCT CI
+
+        preserve // #3
+
+        use `post_file', clear
+        qui count
+        scalar `totobs' = r(N)
+        scalar `tdf' = `totobs' -1
+        scalar `t' = invttail(`tdf',((1-(`level')/100)/2))
+
+        * rename mu and all0 so loop for p_i can be used later
+        local inew = `numcats'
+        if  "`output'"=="count" {
+            local inew = `inew' + 1
+            tempname p`inew'
+            rename `mu' `p`inew''
+            matrix `p_obsmat' = `p_obsmat' \ `mu_obs'
+            if "`diff'"!="" {
+                tempname p`inew'dif
+               rename `mudif' `p`inew'dif'
+               matrix `pdif_obsmat' = `pdif_obsmat' \ `mudif_obs'
+            }
+        }
+        if  "`input'"=="twoeq" {
+            local inew = `inew' + 1
+            tempname p`inew'
+            rename `all0' `p`inew''
+            matrix `p_obsmat' = `p_obsmat' \ `all0_obs'
+            if "`diff'"!="" {
+                tempname p`inew'dif
+                rename `all0dif' `p`inew'dif'
+                matrix `pdif_obsmat' = `pdif_obsmat' \ `all0dif_obs'
+            }
+        } // twoeq
+
+        * loop through each statistics
+        forval i = 1/`nstats' {
+
+            sum `p`i'', d
+            scalar `p_obs' = `p_obsmat'[`i',1]
+            scalar `p_avg' = r(mean)
+            scalar `p_std' = r(sd)
+
+            * bias correction method
+            qui count if `p`i''<=`p_obs'
+            * zpr will be missing if r(N)=0
+            scalar `zpr' = invnorm(r(N)/`totobs')
+
+            * use t for normal
+            scalar `p_normup' = `p_obs' + `t'*`p_std'
+            scalar `p_normlo' = `p_obs' - `t'*`p_std'
+
+            * percentile method
+            qui _pctile `p`i'', nq(1000)
+            local upperpctile = 500 - 5*-`level'
+            local lowerpctile = 1000 - `upperpctile'
+            scalar `p_pctup' = r(r`upperpctile')
+            scalar `p_pctlo' = r(r`lowerpctile')
+
+            * percentile for the bias-correction.
+            local upnum = round((norm(2*`zpr' + `z')) * 1000, 1)
+            local lonum = round((norm(2*`zpr' - `z')) * 1000, 1)
+            if `zpr'==. { // if missing, upper & lower limits are missing
+                scalar `p_bcup' = .
+                scalar `p_bclo' = .
+            }
+            else {
+                scalar `p_bcup' = r(r`upnum')
+                scalar `p_bclo' = r(r`lonum')
+            }
+
+            * stack results from 3 methods
+            mat `pci_mat' = nullmat(`pci_mat') \ ///
+                `p_pctlo', `p_pctup', ///
+                `p_normlo', `p_normup', ///
+                `p_bclo', `p_bcup'
+
+ // CI FOR DISCRETE CHANGE
+
+            if "`diff'"!="" {
+
+                sum `p`i'dif', d
+                scalar `pdif_obs' = `pdif_obsmat'[`i',1]
+                scalar `pdif_avg' = r(mean)
+                scalar `pdif_std' = r(sd)
+
+                * bias corrected method
+                qui count if `p`i'dif'<=`pdif_obs'
+                scalar `zdc' = invnorm(r(N)/`totobs')
+                local upnum = round((norm(2*`zdc' + `z'))*1000, 1)
+                local lonum = round((norm(2*`zdc' - `z'))*1000, 1)
+
+                * use t for normal
+                scalar `pdif_normup' = `pdif_obs' + `t'*`pdif_std'
+                scalar `pdif_normlo' = `pdif_obs' - `t'*`pdif_std'
+
+                * percentile method
+                _pctile `p`i'dif', nq(1000)
+                scalar `pdif_pctup' = r(r`upperpctile')
+                scalar `pdif_pctlo' = r(r`lowerpctile')
+
+                * percentile for bias corrected
+                if `zdc'==. {
+                    scalar `pdif_bcup' = .
+                    scalar `pdif_bclo' = .
+                }
+                else {
+                    scalar `pdif_bcup' = r(r`upnum')
+                    scalar `pdif_bclo' = r(r`lonum')
+                }
+
+                * stack results from 3 methods
+                mat `pdifci_mat' = nullmat(`pdifci_mat') \ ///
+                    `pdif_pctlo', `pdif_pctup', ///
+                    `pdif_normlo', `pdif_normup', ///
+                    `pdif_bclo', `pdif_bcup'
+            }
+        }
+
+    } // end of quietly
+
+    * grab the mu and all0 ci's
+    tempname muci mudifci all0ci all0difci
+    local inew = `numcats'
+    if  "`output'"=="count" {
+        local inew = `inew' + 1
+        matrix `muci' = `pci_mat'[`inew',1...]
+        if "`diff'"!="" {
+            matrix `mudifci' = `pdifci_mat'[`inew',1...]
+        }
+    }
+    if "`input'"=="twoeq" {
+        local inew = `inew' + 1
+        matrix `all0ci' = `pci_mat'[`inew',1...]
+        if "`diff'"!="" {
+            matrix `all0difci' = `pci_mat'[`inew',1...]
+        }
+    }
+    * get rid of mu and all 0 info leaving only probabilities
+    mat `pci_mat' = `pci_mat'[1..`numcats',1...]
+    if "`diff'"!="" {
+        mat `pdifci_mat' = `pdifci_mat'[1..`numcats',1...]
+    }
+
+//  RESTORE DATA FROM ORIGINAL ESTIMATION
+
+    mat pepred = `orig_pred'
+    mat peinfo = `orig_info'
+    mat pebase = `orig_base'
+    if "`input'"=="twoeq" {
+        mat pebase2 = `orig_base2'
+    }
+    mat peupper = `orig_upper'
+    mat pelower = `orig_lower'
+    mat peupnorm = peupper
+    mat pelonorm = pelower
+    mat peupbias = peupper
+    mat pelobias = pelower
+    mat peuppct = peupper
+    mat pelopct = pelower
+
+    global petype "`io'"
+
+//  ADD CIs TO GLOBAL
+
+    * get list of rownames to use in return matrices
+    forval i = 1/`numcats' {
+        local curval = pepred[1, `i'] // current val
+        local plist "`plist' p`curval' " // predicted probabilities
+        local dlist "`dlist' pdif`curval' " // discrete changes
+    }
+
+    * save x() rest() all setup to be used for prvalue, dif
+    if "`save'"!="" {
+        global pexsetup "`x' `rest' `all'"
+    }
+
+    if "`diff'"!="" { // if discrete change
+        mat colnames `pdifci_mat' = pctlo pctup nrmlo nrmup bclo bcup
+        mat rownames `pdifci_mat' = `dlist'
+        mat pelower[6,1] = (`pdifci_mat'[1...,1])'
+        mat peupper[6,1] = (`pdifci_mat'[1...,2])'
+        mat pelonorm[6,1] = (`pdifci_mat'[1...,3])'
+        mat peupnorm[6,1] = (`pdifci_mat'[1...,4])'
+        mat pelobias[6,1] = (`pdifci_mat'[1...,5])'
+        mat peupbias[6,1] = (`pdifci_mat'[1...,6])'
+        return mat bootcidifp = `pdifci_mat'
+    } // difference
+
+    mat colnames `pci_mat' = pctlo pctup nrmlo nrmup bclo bcup
+    mat rownames `pci_mat' = `plist'
+    mat pelower[2,1] = (`pci_mat'[1..., 1])'
+    mat peupper[2,1] = (`pci_mat'[1..., 2])'
+    mat pelonorm[2,1] = (`pci_mat'[1..., 3])'
+    mat peupnorm[2,1] = (`pci_mat'[1..., 4])'
+    mat pelobias[2,1] = (`pci_mat'[1..., 5])'
+    mat peupbias[2,1] = (`pci_mat'[1..., 6])'
+    return mat bootcip = `pci_mat'
+    local repsnomis = `reps' - `nmissed'
+    return scalar Nrepsnomis = `repsnomis'
+
+    if "`output'"=="count" {
+        mat pelower[3,2] = `muci'[1,1]
+        mat peupper[3,2] = `muci'[1,2]
+        mat pelonorm[3,2] = `muci'[1,3]
+        mat peupnorm[3,2] = `muci'[1,4]
+        mat pelobias[3,2] = `muci'[1,5]
+        mat peupbias[3,2] = `muci'[1,6]
+        if "`diff'"!="" {
+            mat pelower[7,2] = `mudifci'[1,1]
+            mat peupper[7,2] = `mudifci'[1,2]
+            mat pelonorm[7,2] = `mudifci'[1,3]
+            mat peupnorm[7,2] = `mudifci'[1,4]
+            mat pelobias[7,2] = `mudifci'[1,5]
+            mat peupbias[7,2] = `mudifci'[1,6]
+        }
+    }
+    if "`input'"=="twoeq" {
+        mat pelower[3,4] = `all0ci'[1,1]
+        mat peupper[3,4] = `all0ci'[1,2]
+        mat pelonorm[3,4] = `all0ci'[1,3]
+        mat peupnorm[3,4] = `all0ci'[1,4]
+        mat pelobias[3,4] = `all0ci'[1,5]
+        mat peupbias[3,4] = `all0ci'[1,6]
+        if "`diff'"!="" {
+            mat pelower[7,4] = `all0difci'[1,1]
+            mat peupper[7,4] = `all0difci'[1,2]
+            mat pelonorm[7,4] = `all0difci'[1,3]
+            mat peupnorm[7,4] = `all0difci'[1,4]
+            mat pelobias[7,4] = `all0difci'[1,5]
+            mat peupbias[7,4] = `all0difci'[1,6]
+        }
+    }
+
+    if "`saving'"!="" {
+        forval i = 1/`numcats' {
+            local varnm: word `i' of `plist'
+            rename `p`i'' b_`varnm'
+            if "`diff'"!="" {
+                local varnm: word `i' of `dlist'
+                rename `p`i'dif' b_`varnm'
+            }
+        }
+        if  "`output'"=="count" {
+            local iadd = `numcats'+1
+            rename `p`iadd'' b_mu
+            if "`diff'"!="" {
+                rename `p`iadd'dif' b_mudif
+            }
+        }
+        if  "`input'"=="twoeq" {
+            local iadd = `iadd' + 1
+            rename `p`iadd'' b_alw0
+            if "`diff'"!="" {
+                rename `p`iadd'dif' b_alw0dif
+            }
+        }
+        save `saving'
+    }
+
+    restore // #3
+
+//  RESTORE ERETURNS
+
+    mat peuppct = peupper // just duplicate the default method
+    mat pelopct = pelower // just duplicate the default method
+    _estimates unhold `lastest'
+
+end // _peciboot
+
+* produce dots
+capture program drop dodot
+program define dodot
+    version 8
+    args N n
+    local dot "."
+    * don't bother with %'s if few than 20 reps
+    if `N'>19 {
+        scalar s = `N'/10
+        forvalues c = 0/10 {
+            local c`c' = floor(`c'*s)
+            if `n'==`c`c'' {
+                local pct = `c'*10
+                di in g `pct' "%" _c
+                local dot ""
+                * new line when iterations are done
+                if `pct'==100 {
+                    di
+                }
+            }
+        } //forvalues
+    } // if > 19
+    di in g as txt "`dot'" _c
+end
+exit
+* version 0.2.0 2005-02-03 (13Apr2005)
+* version 0.2.1 13Apr2005
diff --git a/Modules/ado/plus/_/_peciboot.hlp b/Modules/ado/plus/_/_peciboot.hlp
new file mode 100644
index 0000000..0596003
--- /dev/null
+++ b/Modules/ado/plus/_/_peciboot.hlp
@@ -0,0 +1,154 @@
+{smcl}
+{* 2005-02-06}{...}
+{hline}
+help for {hi:_peciboot}{right:2/6/2005}
+{hline}
+
+{title: Utility to implement the bootstrap method for calculating confidence intervals}
+
+{p 8 15 2}{cmd:_peciboot} [if] [in] [{cmd:,}
+{cmd:x(}{it:variables_and_values}{cmd:)}
+{cmd:rest(}{it:stat}{cmd:)}
+{cmdab:r:eps(}{it:#}{cmd:)}
+{cmdab:si:ze(}{it:#}{cmd:)}
+{cmd:save}
+{cmd:diff}
+{cmd:all match dots}
+{cmdab:sa:ving(}{it:filename, save_options}{cmd:)}]
+
+{p 4 4 2}
+where {it:variables_and_values} is an alternating list of variables
+and either numeric values or mean, median, min, max, upper, lower,
+previous and {it:stat} is either mean, median, min, max, upper, lower,
+previous, grmean(group mean), mrmedian, grmin, grmax.
+
+{title: Description}
+
+{p 4 4 2}
+{cmd:_peciboot} is a utility command that returns prediction, discrete
+changes and their confidence intervals using {help bootstrap} method
+with resampling technique. It can calculate boostrapped confidence intervals
+using the normal approximation, percentile, and bias-corrected methods.
+It applies to {help logit}, {help probit}, {help cloglog}, {help ologit},
+{help oprobit}, {help gologit}, {help mlogit}, {help poisson}, {help nbreg},
+{help zip}, and {help zinb} models.
+
+{title: Options}
+
+{p 4 8 2}
+{cmd:x(}{it:variables_and_values}{cmd:)} sets the values of independent
+variables for calculating predicted values. The list must alternate variable
+names and either numeric values or types of {cmd:stat}.
+
+{p 4 8 2}
+{cmd:rest(}{it:stat}{cmd:)} sets the independent variables not specified
+in {cmd:x(}{it:variables_and_values}{cmd:)} to one of the types of {cmd:stat}.
+Check into {help prstar} for more details about using
+{cmd:x(}{it:variables_and_values}{cmd:)} and {cmd:rest(}{it:stat}{cmd:)}
+
+{p 4 8 2}
+{cmd:reps(}{it:#}{cmd:)} specifies the number of bootstrap replications
+to be performed.  The default is 1000.
+
+{p 4 8 2}
+{cmd: size(}{it:#}{cmd:)} specifies the size of the samples to be drawn.
+The default is _N, meaning to draw samples of the same size as the data.
+
+{p 4 8 2}
+{cmd:save} saves current values of indepenent variables and predictions
+for computing changes using the diff option.
+
+{p 4 8 2}
+{cmd:diff} computes difference between current predictions and those that
+were saved.
+
+{p 4 8 2}
+{cmd:all} specifies that any calculation of means, medians, etc., should
+use the entire sample instead of the sample used to estimate the model.
+
+{p 4 8 2}
+{cmd:match} requests {cmd:_peciboot} to resample from each category group
+of the dependent variable in proportion of the resample size to the original
+sample size.
+
+{p 4 8 2}
+{cmd:dots} requests a dot be placed on the screen at the beginning of each
+replication, thus providing entertainment when a large number of reps() are
+requested. It also prints out the percent replications finished.
+
+{p 4 8 2}
+{cmd:saving(}{it:filename, save_options}{cmd:)}  creates a Stata data file
+(.dta file) containing the bootstrap distribution for predictions and discrete
+changes.
+
+
+{title: Global Matrices}
+
+{p 4 4 2}
+The second row of the following matrices contains predicted probabilities and
+the sixth row contains differences for predicted probabilities.
+
+{p 4 8 2}
+peupper: is a global matrix containing upper end of confidence intervals.
+Default produces the percentile confidence intervals.
+
+{p 4 8 2}
+pelower: is a global matrix containing lower end of confidence intervals.
+Default produces the percentile confidence intervals.
+
+{p 4 8 2}
+peuppct: is a global matrix containing upper end of confidence intervals
+using the percentile method.
+
+{p 4 8 2}
+pelopct: is a global matrix containing lower end of confidence intervals
+using the percentile method.
+
+{p 4 8 2}
+peupnorm: is a global matrix containing lower end of confidence intervals
+using the normal approximation method.
+
+{p 4 8 2}
+pelonorm: is a global matrix containing lower end of confidence intervals
+using normal approximation method.
+
+{p 4 8 2}
+peupbias: is a global matrix containing upper end of confidence intervals
+using the bias-corrected method.
+
+{p 4 8 2}
+pelobias: is a global matrix containing lower end of confidence intervals
+using the bias-corrected method.
+
+{title: Returns}
+
+{p 4 8 2}
+r(Nrepsnomis): is a scalar return containing the factual number of replications
+used for calculating bootstraped confidence intervals, which might be smaller than
+the one requested by users.
+
+
+{title: Examples}
+
+{p 4 8 2}{cmd:._pebase `if' `in' , `x' `rest' `choices' `all'}{p_end}
+{p 4 8 2}{cmd:.mat `tobase' = r(pebase)}{p_end}
+{p 4 8 2}{cmd:._pepred, `level' `maxcnt'}{p_end}
+{p 4 8 2}{cmd:.local maxc = r(maxcount)}{p_end}
+{p 4 8 2}{cmd:.local lvl = r(level)}{p_end}
+{p 4 8 2}{cmd:.capture _return drop pepred}{p_end}
+{p 4 8 2}{cmd:._return hold pepred}{p_end}
+{p 4 8 2}{cmd:._return restore pepred, hold}{p_end}
+{p 4 8 2}{cmd:...}{p_end}
+{p 4 8 2}{cmd:...}{p_end}
+{p 4 8 2}{cmd:...}{p_end}
+{p 4 8 2}{cmd:._pecollect, inout("`io'") level(`lvl')  /// }{p_end}
+{p 4 8 2}{cmd:.     maxcount(`maxc') `diff' `reps'}{p_end}
+
+{p 4 8 2}{cmd:._peciboot, `x' `rest' `all' `save'      /// }{p_end}
+{p 4 8 2}{cmd:.        `diff' `reps' `size' `dots' `match' `saving'}{p_end}
+
+{hline}
+
+{p 2 4 2}Authors: J. Scott Long & Jun Xu{p_end}
+{p 11 4 2}{browse www.indiana.edu/~jslsoc/spost.htm}{p_end}
+{p 11 4 2}spostsup@indiana.edu{p_end}
diff --git a/Modules/ado/plus/_/_pecidelta.ado b/Modules/ado/plus/_/_pecidelta.ado
new file mode 100644
index 0000000..6440f0c
--- /dev/null
+++ b/Modules/ado/plus/_/_pecidelta.ado
@@ -0,0 +1,552 @@
+*! version 2.5.0 2009-10-28 jsl
+*  - stata 11 update for returns from -mlogit-
+
+//  delta method for prvalue
+
+capture program drop _pecidelta
+program define _pecidelta, rclass
+
+    version 8
+    * _G==gradient matrix; _V=var/cov matrix; _up=upper bound; _lo=lower
+    tempname x_base x_base1 x_baseneg xb b b_j b_nocuts designmat cur_eq_sav
+    tempname pdf z G V temp yval eV v
+    tempname mu mu_G mu_V mudif mudif_V
+    tempname pr_cur pr_G pr_V pr_se pr_lo pr_up pr_sav
+    tempname prdif prdif_se prdif_lo prdif_up prdif_V
+
+    /* Matrix definitions:
+
+        pr_cur   : predicted probabilities
+        pr_lo    : lower bound for pred prob
+        pr_up    : upper bound for pred prob
+        pr_G     : gradient matrix for pred prob
+                 :   [dp/db'*e(V)*dp/db]
+        pr_V     : variance (only) matrix for pred prob
+        pr_se    : standards error for pred prob
+
+        prdif    : discrete change for pred prob
+        prdif_lo : lower bound for discrete change
+        prdif_up : upper bound for discrete change
+        prdif_V  : covariance matrix for discrete change
+                 : [d(p2-p1)/db'*e(V)*d(p2-p1)/db]
+        prdif_se : standards error for discrete change
+
+        yval     : y values
+
+        G   = [dF(XB)/dB]'
+            = [dF(XB)/dXB]*[dXB/dB]' = f(XB)*X
+        V   = Var(F(XB))
+            = [dF(XB)/dB]' V(B) [dF(XB)/dB]
+    */
+
+//  DECODE SYNTAX
+
+    * syntax [, Save Diff] // 0.2.3
+    * 0.2.5 - caller indicates version of stata calling _pecidelta;
+    * needed since other commands change versions.
+
+    syntax [, Save Diff caller(real 5.0)]
+
+// GET INFORMATION STORED IN GLOBALS
+
+    loc io $petype
+    loc cmd : word 1 of $petype  // model command
+    loc input : word 2 of $petype  // typical or twoeqn
+    loc output : word 3 of $petype  // output type
+
+    loc nrhs = peinfo[1,1]  // # of rhs
+    loc nrhsp1 = peinfo[1,1] + 1  // adding 1 for constant
+    scalar `z' = peinfo[1,4]
+    loc numcats = peinfo[1,2]
+    loc numcatsm1 = peinfo[1,2] - 1
+    loc max_count = `numcats' - 1  // count model max counts
+
+    * mat `b' = e(b) // 0.2.2
+    * 0.2.5 get b and v for all estimation commands
+    mat `b' = e(b)
+    local nbeta = colsof(`b')
+    mat `eV' = e(V)
+
+    * 0.2.6 get_mlogit_bv to get b and V under Stata 11
+    if "`e(cmd)'"=="mlogit" { // if mlogit, special treatment
+         nobreak {
+            _get_mlogit_bvecv `b' `eV'
+         }
+     }
+
+    * base values
+    mat `x_base'= pebase[1, 1...] // base values for predictions
+    mat `x_base1' = `x_base', 1 // adding 1 to end for constant
+
+// GET PREDICTED PROBABILITIES
+
+    if "`output'"=="count" | "`output'"=="binary" {
+        forval i = 0/`numcats' {
+            tempname p`i'
+            scalar `p`i'' = pepred[2,`i'+1]
+        }
+    }
+    else {
+        forval i = 1/`numcats' {
+            tempname p`i'
+            scalar `p`i'' = pepred[2,`i']
+        }
+    }
+    mat `pr_cur'= pepred[2,1...]'
+
+//  BINARY MODELS - predicted probability
+
+    if "`output'"=="binary" {
+
+        scalar `xb' = pepred[3,1]
+
+        // dF(XB)/dXB = pdf
+        if "`e(cmd)'"=="cloglog" {
+            scalar `pdf' = (`p1'-1) * exp(`xb')
+        }
+        if "`e(cmd)'"=="logit" | "`e(cmd)'"=="logistic" {
+            scalar `pdf' = `p1' * (1-`p1')
+        }
+        if "`e(cmd)'"=="probit"{
+            scalar `pdf' = normden(`xb')
+        }
+
+        // dF(XB)/dB = f(XB)*X
+        mat `G' = `pdf' * `x_base1'
+        // noncon fix 2004-12-22
+        mat `G' = `G'[1,1..`nbeta']
+        mat `pr_G' = `G' \ `G'
+        // Var(F(XB)) = dF(XB)/dB' V(B) dF(XB)/dB
+        * 0.2.2 mat `V' = `G' * e(V) * `G''
+        mat `V' = `G' * `eV' * `G'' // 0.2.5
+        // Since V(p1)=V(p0):
+        mat `pr_V' = `V'[1,1] \ `V'[1,1]
+    }
+
+//  ORDERED MODELS
+
+    if "`output'"=="ordered" {
+
+        * Ordered logit/probit involves computing:
+        *
+        *   Pr(y=m) = F(t_m - xb) - F(t_m-1 * xb)
+        *
+        * The e(b) matrix is a vector of b's associated with the
+        * x's and then the tau's. To compute t_m - xb by vector
+        * multiplicaton of e(b), we need to compute vectors like:
+        *
+        *   x_tau1 = -x1 -x2 -x3 1 0 0 0
+        *   x_tau2 = -x1 -x2 -x3 0 1 0 0
+        *   x_tau3 = -x1 -x2 -x3 0 0 1 0
+        *   x_tau4 = -x1 -x2 -x3 0 0 0 1
+        *
+        * Then x_taum*e(b) = t_m - xb
+
+        tempname I tau_xb tau_xbm1 pdf1 pdflast
+        mat `I' = I(`numcatsm1')
+
+        * loop through categories
+        forval i = 1/`numcatsm1' {
+            tempname x_tau`i'
+            mat `x_tau`i'' = -(`x_base'), `I'[`i',1...]
+        }
+
+        * get b's with tau's at end
+        mat `b' = e(b)
+        * compute tau_m - xb
+        mat `tau_xb' = `x_tau1'*`b''
+        scalar `tau_xb' = `tau_xb'[1,1]
+        * for category 1: d cdf/d xb = pdf
+        if "`e(cmd)'"=="ologit" {
+            lgtpdf 0 `tau_xb'
+            scalar `pdf1' = r(pdf)
+        }
+        if "`e(cmd)'"=="oprobit" {
+            scalar `pdf1' = normden(`tau_xb')
+        }
+        * for the first outcome
+        mat `G' = `pdf1' * `x_tau1'
+        mat `pr_G' = `G'
+        * 0.2.2 mat `V' = `G' * e(V) * (`G')'
+        mat `V' = `G' * `eV' * (`G')' // 0.2.5
+        mat `pr_V' = `V'[1,1]
+
+        * cateories 2 through next to last add to matrices for category 1
+        forval i = 2/`numcatsm1' {
+
+            local im1 = `i' - 1 // prior cutpoint
+            tempname pdf`i'
+            mat `tau_xb' = `x_tau`i''*`b''
+            scalar `tau_xb' = `tau_xb'[1,1]
+            mat `tau_xbm1' = `x_tau`im1''*`b''
+            scalar `tau_xbm1' = `tau_xbm1'[1,1]
+            if "`e(cmd)'"=="ologit" {
+                * cutpoint i
+                lgtpdf 0 `tau_xb'
+                scalar `pdf`i'' = r(pdf)
+                * cutpoint i-1
+                lgtpdf 0 `tau_xbm1'
+                scalar `pdf`im1'' = r(pdf)
+            }
+            if "`e(cmd)'"=="oprobit" {
+                scalar `pdf`i'' = normden(`tau_xb')
+                scalar `pdf`im1'' = normden(`tau_xb')
+            }
+
+            mat `G' = (`pdf`i'')*(`x_tau`i'') ///
+                        - (`pdf`im1'') * (`x_tau`im1'')
+            mat `pr_G' = `pr_G' \ `G'
+            * 0.2.2     mat `V' = `G' * e(V) * (`G')'
+            mat `V' = `G' * `eV' * (`G')' // 0.2.5
+            mat `pr_V' = `pr_V' \ `V'[1,1]
+
+        } // if given category
+
+        * last category
+        local im1 = `numcats' - 1
+        mat `tau_xb' = `x_tau`im1''*`b''
+        scalar `tau_xb' = `tau_xb'[1,1]
+        if "`e(cmd)'"=="ologit" {
+            lgtpdf 0 `tau_xb'
+            scalar `pdflast' = - r(pdf)
+        }
+        if "`e(cmd)'"=="oprobit" {
+            scalar `pdflast' = -normden(`tau_xb')
+        }
+        mat `G' = `pdflast' * (`x_tau`im1'')
+        mat `pr_G' = `pr_G' \ `G'
+        * 0.2.2 mat `V' = `G' * e(V) * (`G')'
+        mat `V' = `G' * `eV' * (`G')' // 0.2.5
+        mat `pr_V' = `pr_V' \ `V'[1,1]
+
+    } // ordered
+
+//  GOLOGIT
+
+    if "`e(cmd)'"=="gologit" {
+
+        tempname nextrow pdfmat fmxb_mx
+
+        forval j = 1/`numcatsm1' {
+
+            * select betas for outcome j
+            local start = (`j'-1) * `nrhsp1' + 1
+            local end = `start' + `nrhs' // including constant
+            mat `b_j' = `b'[1...,`start'..`end']
+
+            * pdf at -xb
+            mat `xb' = `x_base1'*(`b_j')'
+            lgtpdf 0 -`xb'[1,1]
+            scalar `pdf' = r(pdf)
+
+            * collect column vector with pdfs for each outcome
+            mat `pdfmat' = nullmat(`pdfmat') \ `pdf'
+        }
+
+        * dF(-xb)/dB = dFxbdB contains vec of:
+        *
+        *  -x1*f(xb1) ... -x1*f(xbJ-1)
+        *  :::
+        *  -xK*f(xb1) ... -xK*f(xbJ-1)
+        *  -1 *f(xb1) ... -1 *f(xbJ-1)
+
+        mat `fmxb_mx' = vec((-1 * `pdfmat' * `x_base1')')
+
+        * designmat: let J = (1 1 ... 1) for # rhs + 1
+        *            let M = -J
+        *            let 0 = 0 matrix of same size
+        *
+        * designmat = J 0 0 0 0 ... 0 0 ==> -xf(-xb_1)
+        *             M J 0 0 0 ... 0 0 ==> xf(-xb_1)-xf(-xb_2)
+        *             0 M J 0 0 ... 0 0
+        *             : : : : :::::::::
+        *             0 0 0 0 0 ... 0 M==> xf(-xb_ncats)-xf(-xb_2)
+
+        tempname J M
+        mat `J' = J(1,`nrhsp1',1)
+        mat `M' = J(1,`nrhsp1',-1)
+
+        * outcome 1
+        mat `designmat' = J(1,`nrhsp1',1), J(1,`nbeta'-`nrhsp1',0)
+
+        * outcomes 2 - J-1
+        forval i = 2/`numcatsm1' {
+            mat `nextrow' = J(1,`nbeta',0)
+            local startneg = (`i'-2) * `nrhsp1' + 1 // start -1
+            local startpos = (`i'-1) * `nrhsp1' + 1 // start 1
+            mat `nextrow'[1,`startneg'] = `M'
+            mat `nextrow'[1,`startpos'] = `J'
+            mat `designmat' = nullmat(`designmat') \ `nextrow'
+        }
+
+        * outcome J
+        mat `nextrow' = J(1,`nbeta'-`nrhsp1',0), J(1,`nrhsp1',-1)
+        mat `designmat' = nullmat(`designmat') \ `nextrow'
+        * compute gradient and variance
+        mat `pr_G' = `designmat' * diag(`fmxb_mx')
+        * 0.2.2 mat `pr_V' = ( vecdiag(`pr_G' * e(V) * (`pr_G')') )'
+        mat `pr_V' = ( vecdiag(`pr_G' * `eV' * (`pr_G')') )' // 0.2.5
+    }
+
+//  NOMINAL
+
+    if "`e(cmd)'"=="mlogit" {
+        local nbeta = colsof(`b')
+        local nrhspluscon = `nrhsp1' // if constant
+        local iscon "1"
+        if `nrhs'*`numcatsm1'==`nbeta' { // if true, noconstant
+            local nrhspluscon = `nrhsp1' - 1 // if noconstant
+            local iscon ""
+        }
+
+        tempname  pj_xk_mat pj_xk_vec
+        forval i = 1/`numcats' {
+            tempname p`i'fst p`i'snd Var`i'
+        }
+
+        * X = base values with 1 for contant
+        * 0 = 0 row vector of same size.
+        * Create:
+        *           X 0 0 0 ...
+        *           0 X 0 0 ...
+        *           0 0 X 0 ...
+        mat `designmat' = J(`numcatsm1',`nbeta',0)
+        forval i = 1/`numcatsm1' {
+            local st = (`i'-1) * `nrhspluscon'
+            forval j = 1/`nrhspluscon' {
+                local k = `st' + `j'
+                mat `designmat'[`i',`k'] = `x_base`iscon''[1,`j']
+            }
+        }
+        * vector p1x1 p1x2 p1x3...p2x1 p2x2 p2x3...p3x1 p3x2 p3x3...
+        forval i = 1/`numcatsm1' {
+            mat `pj_xk_vec' = nullmat(`pj_xk_vec'),(`x_base`iscon'' * `p`i'')
+        }
+        * compute the variances
+        forval i = 1/`numcats' {
+            if "`i'"<"`numcats'" {
+                mat `G' = (`p`i'') * (`designmat'[`i',1..`nbeta']) ///
+                        - (`p`i'') * (`pj_xk_vec')
+                mat `pr_G' = nullmat(`pr_G') \ `G'
+            }
+            if "`i'"=="`numcats'" {
+                mat `G' = -(`p`i'') * (`pj_xk_vec')
+                mat `pr_G' = `pr_G' \ `G'
+            }
+
+            // noncon fix 2004-12-22
+            mat `G' = `G'[1,1..`nbeta']
+            * 0.2.2     mat `V' = `G' * e(V) * (`G')'
+            mat `V' = `G' * `eV' * (`G')' // 0.2.5
+            mat `pr_V' = nullmat(`pr_V') \ `V'[1,1]
+        }
+    }
+
+//  NBREG AND POISSON
+
+    if "`output'"=="count" & "`input'"=="typical" {
+
+        // POISSON
+
+        if "`e(cmd)'"=="poisson" {
+            scalar `mu' = pepred[3,2]
+            mat `mu_G' = `mu'*`x_base1' // d mu/dB
+            mat `mu_G' = `mu_G'[1,1..`nbeta'] // noncon fix 2004-12-22
+            forval i = 0/`max_count' {
+                matrix `G' = `x_base1' * ///
+                     ( `i' * `mu'^`i' - `mu'^(`i'+1) ) /  ///
+                     ( exp(lngamma(`i'+1)) * exp(`mu') )
+                mat `G' = `G'[1,1..`nbeta'] // noncon fix 2004-12-22
+                mat `pr_G' = nullmat(`pr_G') \ `G'
+                * 0.2.2         mat `V' = `G' * e(V) * (`G')'
+                mat `V' = `G' * `eV' * (`G')' // 0.2.5
+                mat `pr_V' = nullmat(`pr_V') \ `V'[1,1]
+                * 0.2.2                mat `eV' = e(V)
+            }
+        }
+
+        // NBREG
+
+        if "`e(cmd)'"=="nbreg" {
+
+            tempname alpha alphainv inv1alpmu
+            tempname scorexb gradb scorelnalpha gradlnalpha
+            scalar `mu' = pepred[3,2]
+            mat `mu_G' = (`mu' * `x_base1'), 0
+
+            // noncon fix 2005-01-08
+            * strip off the alpha
+            local nbeta = `nbeta' - 1 // drop alpha
+            * strip off the alpha
+            mat `mu_G' = `mu_G'[1,1..`nbeta']
+
+            scalar `alpha' = e(alpha)
+            scalar `inv1alpmu' = 1 / (1+`alpha'*`mu')
+            scalar `alphainv' = 1 / `alpha'
+
+            forval y = 0/`max_count' { // loop through counts
+
+                scalar `scorexb' = `inv1alpmu' * (`y'-`mu')
+                mat `gradb' = (`scorexb' * `x_base1') * `p`y''
+                scalar `scorelnalpha' = `alphainv' * ///
+                        (   digamma(`alphainv') ///
+                          - digamma(`y' + `alphainv') ///
+                          - ln(`inv1alpmu') ///
+                        ) ///
+                        + `inv1alpmu'*(`y'-`mu')
+                scalar `gradlnalpha' = `scorelnalpha' * `p`y''
+                mat `G' = `gradb', `gradlnalpha'
+                mat `G' = `G'[1,1..`nbeta'] // noncon fix 2004-12-22
+                mat `pr_G' = nullmat(`pr_G') \ `G'
+
+                // noncon fix 2005-01-08
+                *drop mat `V' = `G' * e(V) * (`G')'
+                * 0.2.2                mat `eV' = e(V)
+                mat `eV' = `eV'[1..`nbeta',1..`nbeta']
+                mat `V' = `G' * `eV' * (`G')'
+                mat `pr_V' = nullmat(`pr_V') \ `V'[1,1]
+
+            } // loop through counts
+
+        }
+
+        // BOTH MODELS
+
+        // noncon fix 2005-01-08
+        mat `mu_V' = `mu_G' * `eV' * (`mu_G')' // variance for expected rate
+
+     } // negbin and poisson
+
+//  GET CATEGORY VALUES FOR PROBABILITIES - used to label matrices
+
+    forval i = 1/`numcats' {
+        local category = pepred[1,`i'] // value of category
+        * used for column names later
+        local catnames "`catnames' Cat=`category'"
+    }
+
+//  VARIANCE FOR DISCRETE CHANGE
+
+    if "`diff'"=="diff" {
+
+        /* 0.2.2
+        if "`e(cmd)'"!="nbreg" {
+            mat `eV' = e(V)
+        } */
+
+        mat def `pr_sav' = pepred[4,1...]'
+        mat `prdif' = `pr_cur' - `pr_sav'
+
+        * is there no change in x? 0 if no difference.
+        scalar `cur_eq_sav' = mreldif(`pr_sav',`pr_cur')
+
+        * variance for change in prob
+        mat `prdif_V' = pegrad_pr * `eV' * pegrad_pr' ///
+                + `pr_G' * `eV' * (`pr_G')' ///
+                - pegrad_pr * `eV' * (`pr_G')' ///
+                - `pr_G' * `eV' * pegrad_pr'
+        mat `prdif_V' = (vecdiag(`prdif_V'))'
+
+        if "`e(cmd)'"=="poisson" | "`e(cmd)'"=="nbreg" {
+            mat `mudif' = `mu' - pepred[5,2] // minus save mu
+            * variance for change in mu
+            mat `mudif_V' = pegrad_mu * `eV' * pegrad_mu' ///
+                    + `mu_G' * `eV' * (`mu_G')' ///
+                    - pegrad_mu * `eV' * (`mu_G')' ///
+                    - `mu_G' * `eV' * pegrad_mu'
+        }
+    }
+
+//  COMPUTE UPPER AND LOWER BOUNDS
+
+    mat rownames `pr_V' = `catnames'
+    mat rownames `pr_G' = `catnames'
+
+    * std errors = square root of variances
+    mat `pr_se' = vecdiag(cholesky(diag(`pr_V')))'
+
+    * 2008-07-09
+    matrix pedifsep = `pr_se'
+
+    if "`diff'"=="diff" {
+
+        if `cur_eq_sav'==0 { // no change from x_dif==0
+            * se's are 0
+            mat `prdif_se' = J(rowsof(`prdif_V'),1,0)
+        }
+        else {
+            mat `prdif_se' = vecdiag(cholesky(diag(`prdif_V')))'
+        }
+
+        * 2008-07-09
+        matrix pedifsep = `prdif_se'
+
+    }
+
+    * construct bounds for pred prob
+    mat `pr_lo' = `pr_cur' - `z'*`pr_se'
+    mat `pr_up' = `pr_cur' + `z'*`pr_se'
+    mat peupper[2,1] = (`pr_up')'
+    mat pelower[2,1] = (`pr_lo')'
+
+    if "`e(cmd)'"=="poisson" | "`e(cmd)'"=="nbreg" {
+        * 2008-07-09
+        global pesemu = sqrt(`mu_V'[1,1])
+        mat peupper[3,2] = `mu' + `z'*sqrt(`mu_V'[1,1])
+        mat pelower[3,2] = `mu' - `z'*sqrt(`mu_V'[1,1])
+    }
+
+// CREATE BOUNDS FOR DISCRETE CHANGE
+
+    if "`diff'"=="diff" {
+        mat `prdif_lo' = `prdif' - `z'*`prdif_se'
+        mat `prdif_up' = `prdif' + `z'*`prdif_se'
+        mat peupper[6,1] = (`prdif_up')'
+        mat pelower[6,1] = (`prdif_lo')'
+        if "`e(cmd)'"=="poisson" | "`e(cmd)'"=="nbreg" {
+        * 2008-07-09
+        global pedifsemu = sqrt(`mudif_V'[1,1])
+            mat peupper[7,2] = (`mudif' + `z'*sqrt(`mudif_V'[1,1]))
+            mat pelower[7,2] = (`mudif' - `z'*sqrt(`mudif_V'[1,1]))
+        }
+    }
+
+// SAVE GRADIENTS TO COMPUTE CI FOR DCs
+
+    if "`save'"=="save" {
+        mat pegrad_pr = `pr_G'
+        if "`e(cmd)'"=="poisson" | "`e(cmd)'"=="nbreg" {
+            mat pegrad_mu = `mu_G'
+        }
+    }
+
+end
+
+capture program drop lgtpdf
+// lgtpdf 0 0
+//      scalar a = r(pdf) // pdf of logit
+//      scalar b = r(cdf) // cdf of logit
+// di "pdf: " r(pdf)
+// di "cdf: " r(cdf)
+
+program define lgtpdf, rclass
+    version 8
+    tempname expab pdf cdf
+    args a bx
+    scalar `expab' = exp(`a' + `bx')
+    scalar `pdf' = `expab' / (1 + `expab')^2
+    scalar `cdf' = `expab' / (1 + `expab')
+    return scalar pdf = `pdf'
+    return scalar cdf = `cdf'
+end
+
+exit
+
+version 0.2.0 2005-02-03
+version 0.2.1 13Apr2005
+version 0.2.2 2008-07-09
+    - return global pedifsep
+version 0.2.5 2009-09-18
+    - update for stata 11 - drop for _get_mlogit_bv.ado
+version 0.2.6 2009-10-21
+    - use _get_mlogit_bv.ado
diff --git a/Modules/ado/plus/_/_pecidelta.hlp b/Modules/ado/plus/_/_pecidelta.hlp
new file mode 100644
index 0000000..bc33155
--- /dev/null
+++ b/Modules/ado/plus/_/_pecidelta.hlp
@@ -0,0 +1,67 @@
+{smcl}
+{* 2005-02-06}{...}
+{hline}
+help for {hi:_pecidelta}{right:2/6/2005}
+{hline}
+
+{title: Utility to implement the delta method for calculating confidence intervals}
+
+{p 8 15 2}{cmd:_pecidelta} [{cmd:,}
+{cmdab:s:ave}
+{cmdab:d:iff}]
+
+{title: Description}
+
+{p 4 4 2}
+{cmd:_pecidelta} is a utility command that calculates confidence
+intervals for prediction and discrete changes by {search delta}
+method using analytical derivatives. It applies to {help logit},
+{help probit}, {help cloglog}, {help ologit}, {help oprobit},
+{help gologit}, {help mlogit}, {help poisson}, and {help nbreg}.
+
+{title: Options}
+
+{p 4 8 2}
+{cmd:save} saves current values of indepenent variables and predictions
+for computing changes using the diff option.
+
+{p 4 8 2}
+{cmd:diff} computes difference between current predictions and those that
+were saved.
+
+{title: Global Matrices}
+
+{p 4 4 2}
+The second row of the following matrices contains predicted probabilities and
+the sixth row contains differences for predicted probabilities.
+
+{p 4 8 2}
+peupper: _pecidelta calculates confidence intervals for prediction
+and place upper end into the global matrix peupper.
+
+{p 4 8 2}
+pelower: _pecidelta calculates confidence intervals for prediction
+and place lower end into the global matrix pelower.
+
+{title: Examples}
+
+{p 4 8 2}{cmd:._pebase `if' `in' , `x' `rest' `choices' `all'}{p_end}
+{p 4 8 2}{cmd:.mat `tobase' = r(pebase)}{p_end}
+{p 4 8 2}{cmd:._pepred, `level' `maxcnt'}{p_end}
+{p 4 8 2}{cmd:.local maxc = r(maxcount)}{p_end}
+{p 4 8 2}{cmd:.local lvl = r(level)}{p_end}
+{p 4 8 2}{cmd:.capture _return drop pepred}{p_end}
+{p 4 8 2}{cmd:._return hold pepred}{p_end}
+{p 4 8 2}{cmd:._return restore pepred, hold}{p_end}
+{p 4 8 2}{cmd:...}{p_end}
+{p 4 8 2}{cmd:...}{p_end}
+{p 4 8 2}{cmd:...}{p_end}
+{p 4 8 2}{cmd:._pecollect, inout("`io'") level(`lvl')  /// }{p_end}
+{p 4 8 2}{cmd:.     maxcount(`maxc') `diff' `reps'}{p_end}
+{p 4 8 2}{cmd:._pecidelta, `save' `diff'}{p_end}
+
+{hline}
+
+{p 2 4 2}Authors: J. Scott Long & Jun Xu{p_end}
+{p 11 4 2}{browse www.indiana.edu/~jslsoc/spost.htm}{p_end}
+{p 11 4 2}spostsup@indiana.edu{p_end}
diff --git a/Modules/ado/plus/_/_peciml.ado b/Modules/ado/plus/_/_peciml.ado
new file mode 100644
index 0000000..52fddda
--- /dev/null
+++ b/Modules/ado/plus/_/_peciml.ado
@@ -0,0 +1,70 @@
+*! version 0.2.2 2008-07-09
+*   - global pedifsey std error of dif in y
+
+// ci for difference in y or y* based on ML Wald computation
+
+capture program drop _peciml
+program define _peciml, rclass
+
+    version 8
+    tempname xb_dif xb_dif_var xb_dif_sd xb_dif_lo xb_dif_up
+    tempname x_cur x_sav x_dif z b b_var
+
+    // retrieve global data
+
+    local nocon = peinfo[1,6] // 1 if no constant
+    local output : word 3 of $petype // what is the output type?
+    scalar `z' = peinfo[1,4] // width of confidence interval
+    local nrhs = peinfo[1,1] // # of RHS variables
+    sca `xb_dif'= pepred[7,1] // difference in xb from saved to current
+    matrix `x_cur' = pebase[1,1...] // current base values
+    matrix `x_sav' = pebase[2,1...] // saved base values
+    mat `b_var' = e(V)
+    mat `b' = e(b)
+
+    // select and augment matrices to match model type
+
+    * ologit, oprobit // nocon option not allowed
+    if "`output'"=="ordered"   {
+        mat `b_var' = `b_var'[1..`nrhs',1..`nrhs']
+    }
+
+    * tobit, cnreg, intreg
+    if "`output'"=="tobit" {
+        if `nocon' != 1 {
+            mat `x_cur' = `x_cur', 1, 0
+            mat `x_sav' = `x_sav', 1, 0
+        }
+        else {
+            mat `x_cur' = `x_cur', 0
+            mat `x_sav' = `x_sav', 0
+        }
+    }
+
+    * regress, fit, logit, probit
+    if "`output'"=="regress" | "`output'"=="binary"   {
+        if `nocon' != 1 {
+            mat `x_cur' = `x_cur', 1
+            mat `x_sav' = `x_sav', 1
+        }
+    }
+
+    mat `x_dif' = `x_cur' - `x_sav'
+    * variance of difference
+    mat `xb_dif_var' = (`x_dif')*`b_var'*(`x_dif')'
+    sca `xb_dif_sd' = sqrt(`xb_dif_var'[1,1])
+
+    * 2008-07-09
+    global pedifsey = `xb_dif_sd'
+
+    * compute and store upper and lower limits
+    sca `xb_dif_lo' = `xb_dif' - `z'*`xb_dif_sd'
+    sca `xb_dif_up' = `xb_dif' + `z'*`xb_dif_sd'
+
+    mat peupper[7,1] = `xb_dif_up'
+    mat pelower[7,1] = `xb_dif_lo'
+
+end
+
+* version 0.2.1 13Apr2005
+* version 0.2.0 2005-02-03
diff --git a/Modules/ado/plus/_/_pecmdcheck.ado b/Modules/ado/plus/_/_pecmdcheck.ado
new file mode 100644
index 0000000..d6f56a0
--- /dev/null
+++ b/Modules/ado/plus/_/_pecmdcheck.ado
@@ -0,0 +1,77 @@
+*! version 0.2.3 13Apr2005
+*  version 0.2.2 03Mar2005 cloglog
+*  version 0.2.1 19Feb2005 zt
+*  version 0.2.0 03Feb2005
+
+//  simply check if last command was valid for spost
+
+capture program drop _pecmdcheck
+program define _pecmdcheck, rclass
+    version 8
+    args spostcmd
+    local io ""
+    * 03Mar2005 zt models added
+    if "`e(cmd)'"=="ztp"  {
+        local io "typical count"
+    }
+    if "`e(cmd)'"=="ztnb"  {
+        local io "typical count"
+    }
+    if "`e(cmd)'"=="cloglog"  {
+        local io "typical binary"
+    }
+    if "`e(cmd)'"=="cnreg"    {
+        local io "typical tobit"
+    }
+    if "`e(cmd)'"=="fit"      {
+        local io "typical regress"
+    }
+    if "`e(cmd)'"=="gologit"  {
+        local io "typical ordered"
+    }
+    if "`e(cmd)'"=="intreg"   {
+        local io "typical tobit"
+    }
+    if "`e(cmd)'"=="logistic" {
+        local io "typical binary"
+    }
+    if "`e(cmd)'"=="logit"    {
+        local io "typical binary"
+    }
+    if "`e(cmd)'"=="mlogit"   {
+        local io "typical nominal"
+    }
+    if "`e(cmd)'"=="nbreg"    {
+        local io "typical count"
+    }
+    if "`e(cmd)'"=="ologit"   {
+        local io "typical ordered"
+    }
+    if "`e(cmd)'"=="oprobit"  {
+        local io "typical ordered"
+    }
+    if "`e(cmd)'"=="poisson"  {
+        local io "typical count"
+    }
+    if "`e(cmd)'"=="probit"   {
+        local io "typical binary"
+    }
+    if "`e(cmd)'"=="regress"  {
+        local io "typical regress"
+    }
+    if "`e(cmd)'"=="tobit"    {
+        local io "typical tobit"
+    }
+    if "`e(cmd)'"=="zinb"     {
+        local io "twoeq count"
+    }
+    if "`e(cmd)'"=="zip"      {
+        local io "twoeq count"
+    }
+    if "`io'"=="" {
+        di as error _new ///
+            "`spostcmd' does not work for the last type of model estimated."
+    }
+    return local io = "`io'"
+
+end
diff --git a/Modules/ado/plus/_/_pecollect.ado b/Modules/ado/plus/_/_pecollect.ado
new file mode 100644
index 0000000..203a3b9
--- /dev/null
+++ b/Modules/ado/plus/_/_pecollect.ado
@@ -0,0 +1,349 @@
+*! version 2.0.1 2008-07-09 jsl
+*   - peinfo[3,8] to missing since it isn't the sd of the difference
+
+//  Utility to collect information from the current model and
+//  saves it to global matrices for use by other programs (e.g.,
+//  for simulations or constructing plots unavailable with prgen).
+//  For details on these matrices, -help prvalue_collect-
+
+capture program drop _pecollect
+program define _pecollect, rclass
+    version 8
+    tempname temp values mu xb prall0 nrhs2 muC ey mucount
+    tempname dif difp difm r1 r2 r3
+
+    syntax , level(real) inout(string) maxcount(string) [Diff reps(int 1000)]
+
+// get information about current model
+
+    * is it zero truncated?
+    local iszt = 0
+    if ("`e(cmd)'"=="ztp" | "`e(cmd)'"=="ztnb") local iszt = 1
+
+    * type of model
+    global petype "`e(cmd)' `inout'"
+    local input : word 2 of $petype // is it a typical or twoeq model?
+    local output : word 3 of $petype // what is the output type?
+
+    local level = r(level) // CI level for current model
+
+    * nrhs: # of rhs variables
+    local colnms: colnames(PE_in)
+    local nrhs: word count `colnms'
+    local nrhs = `nrhs' // no _cons included
+
+    * ncat: number of outcome categories
+    if "`output'"=="count" {
+        local ncat = `maxcount'+1
+    }
+    else if "`output'"=="regress" | "`output'"=="tobit" {
+        local ncat = 1
+    }
+    else {
+        _pecats
+        local catvals = r(catvals)
+        local ncat = r(numcats)
+        _return restore pepred, hold // restore returns from _pepred
+    }
+
+    * nrhs2: # of rhs if zip or zinb
+    local nrhs2 = .
+    if "`input'"=="twoeq" {
+        local colnms2: colnames(PE_in2)
+        local nrhs2: word count `colnms2'
+        local nrhs2 = `nrhs2' // no _cons included
+    }
+
+    * basecat: mlogit base category
+    local basecat = .
+    * if "`e(cmd)'"=="mlogit" { local basecat = e(basecat) }
+    if "`e(cmd)'"=="mlogit" {
+        local basecat = e(i_base)
+    }
+
+// peinfo - global matrix with numeric information about:
+//
+//      Row 1: the current model
+//      Row 2: the saved model used to compute the difference
+//      Row 3: Row 1 - Row 2
+
+    mat def peinfo = J(3,12,.)
+    matrix peinfo[1,1] = `nrhs' // nrhs - columns for pebase
+    matrix peinfo[1,2] = `ncat' // numcats from _pecats
+    matrix peinfo[1,3] = `level'*100 // ci level as 95 not .95
+    matrix peinfo[1,4] = -invnorm((1-`level')/2) // z @ level for ci
+    matrix peinfo[1,5] = `nrhs2' // nrhs2
+    matrix peinfo[1,6] = . // nocon
+    matrix peinfo[1,7] = `basecat' // base category for mlogit
+    matrix peinfo[1,8] = . // stdp for binary model
+    matrix peinfo[1,9] = `reps' // requested # of replications for bootstrap
+    matrix peinfo[1,10] = . // completed # of replications for bootstrap
+                            // this will be added after _peciboot is called
+    matrix peinfo[1,11] = `maxcount'
+
+    * if diff, add saved and compute current-saved
+    if "`diff'" == "diff" {
+
+        mat `r1' = peinfo[1,1...] // current
+        mat `r2' = PRVinfo // saved
+        mat `dif' = `r1' - `r2'
+        mat peinfo = `r1' \ `r2' \ `dif'
+
+* 2008-07-09
+mat peinfo[3,8] = . // since this is not a valid stdp
+
+    } // "`diff'" == "diff"
+
+//  pebase and pebase2 - global matrices with base values
+
+    * start with current base and two blank rows
+    mat pebase = PE_in \ J(1,`nrhs',.) \ J(1,`nrhs',.)
+    if "`input'" == "twoeq" {
+        mat pebase2 = PE_in2 \ J(1,`nrhs2',.) \ J(1,`nrhs2',.)
+        matrix rownames pebase2 = Current Saved Cur-Saved
+    }
+
+    * if diff, get previous base values
+    if "`diff'" == "diff" {
+        mat `dif' = pebase[1,1...] - PRVbase
+        mat pebase = PE_in \ PRVbase \ `dif'
+        if "`input'" == "twoeq" {
+            mat `dif' = pebase2[1,1...] - PRVbase2
+            mat pebase2 = PE_in2 \ PRVbase2 \ `dif'
+            matrix rownames pebase2 = Current Saved Cur-Saved
+        }
+    }
+
+//  gather information about current model
+
+    * missing by default
+    scalar `xb' = .
+    scalar `mu' = . // rate in count; e(y) in zip/zinb
+    scalar `mucount' = . // mu in count portion of zip/zinb
+    scalar `prall0' = .
+
+    * info on mu for count models
+    if "`output'"=="count" {
+        mat `temp' = r(mu)
+        scalar `mu' = `temp'[1,1]
+    }
+    if "`e(cmd)'"=="zip"  | "`e(cmd)'"=="zinb" {
+        mat `temp' = r(mucount) // grab rate from count portion of model
+        scalar `mucount' = `temp'[1,1]
+    }
+    if  `iszt' {
+        mat `temp' = r(xb)
+        scalar `xb' = `temp'[1,1]
+        mat `temp' = r(muC) // E(y|y<0)
+        scalar `muC' = `temp'[1,1]
+    }
+    if  "`e(cmd)'"=="poisson" ///
+        | "`e(cmd)'"=="nbreg" {
+        mat `temp' = r(xb)
+        scalar `xb' = `temp'[1,1]
+    }
+    if "`input'"=="twoeq" { // zip and zinb
+        scalar `xb' = log(`mu')
+        mat `temp' = r(always0)
+        scalar `prall0' = `temp'[1,1]
+    }
+
+    if "`output'"=="binary" ///
+        | "`output'"=="regress" ///
+        | "`output'"=="tobit" ///
+        | "`output'"=="ordered" {
+        mat `temp' = r(xb)
+        scalar `xb' = `temp'[1,1]
+    }
+
+//  start with empty pepred & peCpred matrices
+
+    mat def pepred = J(7,`ncat',.)
+    matrix rownames pepred = ///
+        1values 2prob 3misc 4sav_prob 5sav_misc 6dif_prob 7dif_misc
+    mat def peupper = pepred // holds upper ci
+    mat def pelower = pepred // holds lower ci
+    local method = word("$pecimethod",1)
+    if "`method'"=="bootstrap" { // bootstrap computes 3 types of CIs
+        mat def peupnorm = pepred // holds upper by normal appox
+        mat def pelonorm = pepred // holds lower by normal appox
+        mat def peupbias = pepred // holds upper with bias adjustment
+        mat def pelobias = pepred // holds lower with bias adjustment
+    }
+    if  `iszt' {
+        mat def peCpred = pepred // for conditional results
+    }
+
+//  pepred & peinfo: add info about current model
+
+    if "`output'"=="binary" {
+
+        mat pepred[1,1] = 0 // outcome values
+        mat pepred[1,2] = 1
+        mat `temp' = r(p0) // predictions
+        mat pepred[2,1] = `temp'[1,1]
+        mat `temp' = r(p1)
+        mat pepred[2,2] = `temp'[1,1]
+        mat pepred[3,1] = `xb'
+        mat `temp' = r(stdp)
+        mat peinfo[1,8] = `temp'[1,1]
+        mat `temp' = r(p0_lo) // upper and lower limits
+        * due to error in _pepred, r(p0_lo) is really upper limit
+        mat peupper[2,1] = `temp'[1,1]
+        mat `temp' = r(p0_hi)
+        mat pelower[2,1] = `temp'[1,1]
+        mat `temp' = r(p1_hi)
+        mat peupper[2,2] = `temp'[1,1]
+        mat `temp' = r(p1_lo)
+        mat pelower[2,2] = `temp'[1,1]
+        mat `temp' = r(xb_hi)
+        mat peupper[3,1] = `temp'[1,1]
+        mat `temp' = r(xb_lo)
+        mat pelower[3,1] = `temp'[1,1]
+    }
+
+    if "`output'"=="tobit" ///
+        | "`output'"=="regress" {
+
+        mat pepred[1,1] = . // value
+        mat pepred[2,1] = . // predicted probability
+        mat pepred[3,1] = `xb'
+        mat `temp' = r(xb_lo)
+        mat pelower[3,1] = `temp'[1,1]
+        mat `temp' = r(xb_hi)
+        mat peupper[3,1] = `temp'[1,1]
+        mat `temp' = r(stdp)
+        mat peinfo[1,8] = `temp'[1,1]
+    }
+
+    if "`output'"=="ordered"  { // also works for mlogit
+
+        mat `temp' = r(stdp)
+        mat peinfo[1,8] = `temp'[1,1]
+        mat `temp' = r(xb_hi)
+        mat peupper[3,1] = `temp'[1,1]
+        mat `temp' = r(xb_lo)
+        mat pelower[3,1] = `temp'[1,1]
+        forval i=1/`ncat' {
+            local v : word `i' of `catvals'
+            mat pepred[1,`i'] = `v'
+            mat `temp' = r(p`i')
+            mat pepred[2,`i'] = `temp'[1,1]
+        }
+        mat pepred[3,1] = `xb'
+    }
+
+    if "`e(cmd)'"=="gologit" | "`e(cmd)'"=="mlogit" ///
+        | "`e(cmd)'"=="mprobit" | "`e(cmd)'"== "slogit" {
+        forval i=1/`ncat' {
+            local v : word `i' of `catvals'
+            mat pepred[1,`i'] = `v'
+            mat `temp' = r(p`i')
+            mat pepred[2,`i'] = `temp'[1,1]
+            mat pepred[2,`i'] = `temp'[1,1]
+            if `i' != `ncat' {
+                mat `temp' = r(xb`i')
+                mat pepred[3,`i'] = `temp'[1,1]
+            }
+        }
+    }
+
+    if "`e(cmd)'"=="poisson" | "`e(cmd)'"=="nbreg" ///
+        | "`e(cmd)'"=="zip"  | "`e(cmd)'"=="zinb" ///
+        | `iszt' {
+        forval i=1/`ncat' { // add labels to headers
+            local im1 = `i' - 1
+            mat pepred[1,`i'] = `im1' // numbers 0 to ncat-1
+            mat `temp'=r(p`im1')
+            mat pepred[2,`i'] = `temp'[1,1]
+            if  `iszt' { // if zt model, get pr(y|y>0)
+                mat peCpred[1,`i'] = `im1' // numbers 0 to ncat-1
+                mat `temp'=r(Cp`im1')
+                mat peCpred[2,`i'] = `temp'[1,1]
+            }
+        }
+        mat pepred[3,1] = `xb'
+        mat pepred[3,2] = `mu' // overall rate E(y)
+        mat pepred[3,3] = `mucount' // mu for count model E(y|~always0)
+        mat `temp' = r(stdp)
+        mat peinfo[1,8] = `temp'[1,1]
+        mat `temp' = r(mu_hi)
+        mat peupper[3,1] = `temp'[1,1]
+        mat `temp' = r(mu_lo)
+        mat pelower[3,1] = `temp'[1,1]
+        if "`input'"=="twoeq" {
+            mat pepred[3,4] = `prall0'
+        }
+        if `iszt' { // zt models
+            mat `temp' = r(Cmu) // conditional mu
+            mat peCpred[3,2] = `temp'[1,1]
+        }
+
+    }
+
+    * Information on current model is now located in pepred, peCpred,
+    * peinfo, peupper, pelower.
+
+//  if -diff-, add saved and difference to output matrix
+
+    if "`diff'" == "diff" {
+
+        * peinfo
+        mat `dif' = peinfo[1,1...] - PRVinfo
+        mat peinfo = peinfo[1,1...] \ PRVinfo \ `dif'
+
+        * pepred: row 1-values; 2-prob; 3-misc
+        mat `difp' = pepred[2,1...] - PRVprob // dif in prob
+        mat `difm' = pepred[3,1...] - PRVmisc // dif in other stats
+        *               Current             SavedMode           Difference
+        mat pepred = pepred[1..3,1...] \ PRVprob \ PRVmisc \ `difp' \ `difm'
+
+        if  `iszt' { // if zero trucated, also fix conditional matrix
+            mat `difp' = pepred[2,1...] - PRVCprob
+            mat `difm' = pepred[3,1...] - PRVCmisc
+            mat peCpred = ///
+                pepred[1..3,1...] \ PRVCprob \ PRVCmisc \ `difp' \ `difm'
+        }
+
+    } // end if diff
+
+
+//  ADD CATEGORY NUMBERS TO FIRST ROW; ADD ROW & COL NAMES
+
+    mat `r1' = pepred[1,1...]
+    mat `r2' = peupper[2...,1...]
+    mat `r3' = pelower[2...,1...]
+    mat peupper = `r1' \ `r2'
+    mat pelower = `r1' \ `r3'
+    matrix rownames peupper = ///
+        1values 2up_pr 3up_misc 4up_sav_pr ///
+        5up_sav_misc 6up_dif_pr 7up_dif_misc
+    matrix rownames pelower = ///
+        1values 2lo_pr 3lo_misc 4lo_sav_pr ///
+        5lo_sav_misc 6lo_dif_pr 7lo_dif_misc
+    matrix rownames peinfo = Current Saved Cur-Saved
+    matrix colnames peinfo = 1nrhs 2numcats 3level 4z_level ///
+        5nrhs2 6nocon 7basecat 8stdp 9reps 10repsdone 11maxcount ///
+        12blank
+    matrix rownames pebase = Current Saved Cur-Saved
+
+//  INFORMATION ON WHETHER CONSTANT IS IN MODEL
+
+    _penocon
+    local temp = r(nocon)
+    matrix peinfo[1,6] = `temp'
+
+end
+
+exit
+
+version 1.0.0 15Apr2005 fix rate used for zip/zinb (see notes at end)
+
+    15Apr2005 - correct error for zip and zinb (see changes in _pepred, _pecollect, _peciboot
+      E(y) was used incorrectly rather than E(y|~always0).
+      _pepred[3|5|7, 2] used to be mu defined as rate in count portion of model E(y|not always 0)
+      _pepred[3|5|7, 2] now is the overall rate E(y); listed as simply mu.
+      _pepred[3|5|7, 3] rate in count portion of model E(y|not always 0); listed as mucount.
+    To simplify changes in _peciboot, E(y) is referred to as mu; E(y|~always0) is mucount.
+
+version 2.0.0 2007-03-04 jsl - revised for prvalue repeated dif calls
diff --git a/Modules/ado/plus/_/_pecollect.hlp b/Modules/ado/plus/_/_pecollect.hlp
new file mode 100644
index 0000000..8a9e6fa
--- /dev/null
+++ b/Modules/ado/plus/_/_pecollect.hlp
@@ -0,0 +1,163 @@
+{smcl}
+{* 2005-02-06}{...}
+{hline}
+help for {hi:_pecollect}{right:2/6/2005}
+{hline}
+
+{title: Utility program to collect information used by prvalue2}
+
+{p 8 15 2}{cmd:_pecollect}
+{cmd:level(}{it:real}{cmd:)}
+{cmd:inout(}{it:string}{cmd:)}
+{cmd:maxcnt(}{it:string}{cmd:)}
+[{cmdab:d:iff}]
+
+
+{title: Description}
+
+{p 4 4 2}
+{cmd:_pecollect} collects results from _pepred, _perhs, _pecats and other
+low level utility SPost programsto pass to _pecidelta and _peciboot.
+
+{title: Options}
+
+{p 4 8 2}
+{cmd:level()} sets the level of the confidence interval for predicted values
+or probabilities for the commands for which these are provided.
+
+{p 4 8 2}
+{cmd:inout()} specifies model type, such as typical one equation versus two
+equation
+
+{p 4 8 2}
+{cmd:maxcount()} is the maximum count value for which the probability is computed
+in count models. Default is 9.
+
+{p 4 8 2}
+{cmd:diff}  computes difference between current predictions and those that were
+saved.
+
+
+{title:Details on Globals}
+
+{p 4 8 2}
+{cmd:petype} - global string with type of model
+
+{p 8 8 2}
+1. Contents - string with three words
+
+{p 8 8 2}
+Word 1. cmd - e(cmd){break}
+Word 2. input from io - typical vs twoeq{break}
+Word 3. output from io - binary count mlogit ordered regress tobit{break}
+
+{p 8 8 2}
+2. To retrieve information
+
+{p 8 8 2}
+local cmd : word 1 of $petype // what model was estimated {break}
+local input : word 2 of $petype // is it a typical or twoeq model?  {break}
+local output : word 3 of $petype // what is the output type?  {break}
+
+{p 4 8 2}
+{cmd:pecimethod} - global string with type of ci
+
+{p 8 8 2}
+1. Contents - string with two words
+
+{p 8 8 2}
+Word 1. method for ci computation - ml, delta, ept, bootstrap {break}
+Word 2. type of bootstrap ci - normal, percentile, biascorrected {break}
+
+{p 8 8 2}
+2. To retrieve information
+
+{p 8 8 2}
+local cimethod : word 1 of $pecitype{break}
+local boottype : word 2 of $pecitype{break}
+
+
+{p 4 8 2}
+{cmd:peinfo} - global matrix (3x11) with information about the model
+
+{p 8 8 2}
+Row 1: current model {break}
+Row 2: saved model when diff option used{break}
+Row 3: difference current value - saved value{break}
+
+{p 8 8 2}
+Column 1:  # of rhs variables (i.e., # of columns inh PEbase) peinfo[1,1]{break}
+Column 2:  # of categories in outcome (from _pecats){break}
+Column 3:  level for confidence interval (e.g., 95 not .95) peinfo[1,3]{break}
+Column 4:  z value for confidence interval at given level peinfo[1,4]{break}
+Column 5:  # of rhs variables for inflation in zip and zinb{break}
+Column 6:  1 if model with no constant, else 0  peinfo[1,6]{break}
+Column 7:  base category for mlogit{break}
+Column 8:  stdp for binary models{break}
+Column 9:  # of requested reps for bootstrap (# specified by rep() option){break}
+Column 10: # of completed replications for bootstrap{break}
+Column 11: maximum # of values in predicted probs in count models.{break}
+
+{p 4 8 2}
+{cmd:pebase} and {cmd:pebase2} - base values for the x's
+
+{p 8 8 2}
+matrix pebase  = PE_in{break}
+matrix pebase2 = PE_in2{break}
+
+{p 8 8 2}
+The jth column of pebase is the jth right hand size variable in the
+model. The jth column of pebase2 is the jsth right hand side inflation
+variable in zip or zinb. If save and dif, three rows are in the matrix:{break}
+
+{p 8 8 2}
+Row 1: current model {break}
+Row 2: saved model when diff option used{break}
+Row 3: difference current value - saved value{break}
+
+{p 4 8 2}
+{cmd:pepred} - a global matrix (7 by # of outcome) containing predicted values
+
+{p 8 8 2}
+Row 1: values of the outcome category
+
+{p 8 8 2}
+{result:Current model}{break}
+Row 2: predicted probabilities for the value in row 1{break}
+Row 3: Column 1: xb from first part of model{break}
+Column 2: mu from count model{break}
+Column 3: xb from inflation part of zip and zinb{break}
+Column 4: pr(always 0) from zip and zinb{break}
+
+{p 8 8 2}
+{result:Saved model}{break}
+Row 4: predicted probabilities for the value in row 1{break}
+Row 5: Column 1: xb from first part of model{break}
+Column 2: mu from count model{break}
+Column 3: xb from inflation part of zip and zinb{break}
+Column 4: pr(always 0) from zip and zinb{break}
+
+{p 8 8 2}
+{result:Difference for saved - current}{break}
+Row 6: predicted probabilities for the value in row 1{break}
+Row 7: Column 1: xb from first part of model{break}
+Column 2: mu from count model{break}
+Column 3: xb from inflation part of zip and zinb{break}
+Column 4: pr(always 0) from zip and zinb{break}
+
+{p 4 8 2}
+{cmd:peupper} - upper bound of ci
+
+{p 4 8 2}
+{cmd:pelower} - lower bound of ci
+
+{p 8 8 2}
+Row 1: is identical to pepred.{break}
+Rows 2-7: the upper or lower bounds from the corresponding quantity in pepred{break}
+
+*** ADD MATRICES FROM BOOT FOR VARIOUS TYPES OF CIs
+
+{hline}
+{p 2 4 2}Authors: J. Scott Long & Jun Xu{p_end}
+{p 11 4 2}{browse www.indiana.edu/~jslsoc/spost.htm}{p_end}
+{p 11 4 2}spostsup@indiana.edu{p_end}
diff --git a/Modules/ado/plus/_/_pedum.ado b/Modules/ado/plus/_/_pedum.ado
new file mode 100644
index 0000000..2e6e27f
--- /dev/null
+++ b/Modules/ado/plus/_/_pedum.ado
@@ -0,0 +1,9 @@
+*! version 1.6.0 2/27/99
+
+capture program drop _pedum
+program define _pedum, rclass
+    version 6
+    syntax varlist(max=1) [if] [in]
+    capture assert `varlist' == 0 | `varlist' == 1 | `varlist' == . `if' `in'
+    return scalar dummy = _rc==0
+end
diff --git a/Modules/ado/plus/_/_pedum.hlp b/Modules/ado/plus/_/_pedum.hlp
new file mode 100644
index 0000000..a011292
--- /dev/null
+++ b/Modules/ado/plus/_/_pedum.hlp
@@ -0,0 +1,35 @@
+.-
+help for ^_pedum^ - 1.6.0 - 2/27/1999
+.-
+
+Utility to determine if a variable is 0, 1 or .
+-----------------------------------------------
+
+    ^_pedum^ varname [^if^ exp] [^in^ range]
+
+Description
+-----------
+
+^_pedum^ returns the scalar ^r(dummy)^=1 if the variable is binary, else 0.
+    Binary variables have all values equal to 0, 1, or missing.
+
+Examples within a program
+-------------------------
+
+    local i = 1
+    while `i'<=`nvars' {
+        local nmtoget : word `i' of `varnms'
+        _pedum `nmtoget' `if' `in'
+        mat `Sdummy'[1,`i'] = r(dummy)
+        local i=`i'+1
+    }
+
+Note
+----
+
+You must use ^_peife^ prior to calling ^_pedum^.
+
+.-
+Authors: J. Scott Long and Jeremy Freese
+         www.indiana.edu/~jslsoc/spost.htm
+         spostsup@@indiana.edu
diff --git a/Modules/ado/plus/_/_peife.ado b/Modules/ado/plus/_/_peife.ado
new file mode 100644
index 0000000..522d971
--- /dev/null
+++ b/Modules/ado/plus/_/_peife.ado
@@ -0,0 +1,25 @@
+*! version 1.6.0 2/7/99
+
+capture program drop _peife
+program define _peife, rclass
+    version 6.0
+    syntax [if/] [,All]
+
+    * Case 1: no if and no all
+    if "`if'"=="" & "`all'"!="all" { local ifis "if e(sample)" }
+    else {
+
+        * Case 2: if and no all
+        if "`all'"!="all" { local ifis "if e(sample) & `if'" }
+
+        if "`all'"=="all" {
+
+            * Case 3: if and all
+            if "`if'"!="" { local ifis "if `if'" }
+
+            * Case 4: no if and all
+            if "`if'"=="" { local ifis "" }
+        }
+    }
+    return local if "`ifis'"
+end
diff --git a/Modules/ado/plus/_/_peife.hlp b/Modules/ado/plus/_/_peife.hlp
new file mode 100644
index 0000000..6aa3462
--- /dev/null
+++ b/Modules/ado/plus/_/_peife.hlp
@@ -0,0 +1,54 @@
+.-
+help for ^_peife^ - 1.6.0 - 2/7/1999
+.-
+
+Utility to decide if estimation sample is used
+----------------------------------------------
+
+    ^_peife^ [^if^ exp] [, ^a^ll]
+
+Description
+-----------
+
+^_peife^ modifies the given ^if^ expression to add restrictions to the last
+    estimation sample ^e(sample)^. Whem the option ^all^ is specified, the
+    ^if^ statement is not modified to add ^e(sample)^.
+
+
+Output
+------
+
+You can retrieve a string with the resulting ^if^ statement by using ^r(if)^.
+    For example: local if "`r(if)'"  Note that the resulting string includes
+    the work ^if^.
+
+Options
+-------
+
+^all^ By default, the ^if^ statement passed to ^_peife^ is modified to add
+    ^& e(sample)^. With option ^all^ the ^if^ condition is not changed.
+    Consequently, all that is done is the word "if" is placed in front of the
+    current ^if^ condition before the string is returned.
+
+Examples within a program
+-------------------------
+    ...
+    * `if' is the curret if condition
+    _peife `if',`all'
+    * the new condition includes & e(sample)
+    local if "`r(if)'"
+    * note that `if' has the word if in it
+    sum `varlist' `if'
+    ...
+
+Note
+----
+
+_pesum, _pedum, _pecats do not call _peife. You need to pass the correct if
+condition to them.
+
+.-
+Authors: J. Scott Long and Jeremy Freese
+         www.indiana.edu/~jslsoc/spost.htm
+         spostsup@@indiana.edu
+         
diff --git a/Modules/ado/plus/_/_pemarg.ado b/Modules/ado/plus/_/_pemarg.ado
new file mode 100644
index 0000000..7a01b57
--- /dev/null
+++ b/Modules/ado/plus/_/_pemarg.ado
@@ -0,0 +1,232 @@
+*! version 2.5.0 2009-10-28 jsl
+*  - stata 11 update for returns from -mlogit-
+
+*   compute marginal effects
+
+capture program drop _pemarg
+program define _pemarg, rclass
+
+    * 11Apr2005; 13Jun2005
+    if c(stata_version) >= 9 {
+        tempname tmpb
+        mat `tmpb' = e(b)
+        local tmpcut : colnames `tmpb'
+        if index("`tmpcut'", "_cut1") != 0 {
+            local cut "_"
+        }
+        else {
+            local cut "/"
+        }
+    }
+    else {
+        local cut "_"
+    }
+    
+    syntax [, caller(real 5.0)] // 1.7.0 stata version
+
+    version 6.0
+    tempname b x xb sxb prob marg tmp bxb bxbm1 difpdf tmp2
+    tempname b x o xo xb sxb prob marg tmp bxb bxbm1 difpdf tmp2 bi alpha
+    tempname sumxb sp PredVal PredPr sump
+    tempname pdiag sumpb o
+
+    if "`e(cmd)'"=="cloglog"  { local hasmarg = "not yet" }
+    if "`e(cmd)'"=="cnreg"    { local hasmarg = "not applicable" }
+    if "`e(cmd)'"=="fit"      { local hasmarg = "not applicable" }
+    if "`e(cmd)'"=="gologit"  { local hasmarg = "not yet" }
+    if "`e(cmd)'"=="intreg"   { local hasmarg = "not applicable" }
+    if "`e(cmd)'"=="logistic" { local hasmarg = "yes" }
+    if "`e(cmd)'"=="logit"    { local hasmarg = "yes" }
+    if "`e(cmd)'"=="mlogit"   { local hasmarg = "yes" }
+    if "`e(cmd)'"=="nbreg"    { local hasmarg = "yes" }
+    if "`e(cmd)'"=="ologit"   { local hasmarg = "yes" }
+    if "`e(cmd)'"=="oprobit"  { local hasmarg = "yes" }
+    if "`e(cmd)'"=="poisson"  { local hasmarg = "yes" }
+    if "`e(cmd)'"=="probit"   { local hasmarg = "yes" }
+    if "`e(cmd)'"=="regress"  { local hasmarg = "not applicable" }
+    if "`e(cmd)'"=="tobit"    { local hasmarg = "not applicable" }
+    if "`e(cmd)'"=="zinb"     { local hasmarg = "not yet" }
+    if "`e(cmd)'"=="zip"      { local hasmarg = "not yet" }
+    return local hasmarg `hasmarg'
+    if "`hasmarg'"!="yes" { exit }
+
+    /* 1.6.4
+        matrix `b' = e(b)
+        if "`e(cmd)'"=="mlogit" {
+            version 5.0
+            matrix `b' = get(_b)
+            version 6.0
+        }
+    */
+    
+    tempname eV
+    * 0.2.5 - get b and v for all estimation commands
+    mat `b' = e(b)
+    * drop local nbeta = colsof(`b')
+    if "`e(cmd)'"=="mlogit" {
+        version 5.0
+        matrix `b' = get(_b)
+        version 6.0
+    }
+    mat `eV' = e(V)
+    * 2009-10-28 get b and V under Stata 11
+    if "`e(cmd)'"=="mlogit" { // if mlogit, special treatment
+         nobreak {
+            _get_mlogit_bv `b' `eV'
+         }
+     }
+         
+    if "`e(cmd)'"=="nbreg" {
+        local nb = colsof(`b') - 1 /* -1 for alpha */
+        matrix `b' = `b'[1,1..`nb']
+    }
+    matrix `x' = PE_base
+
+    if "`e(cmd)'"=="logit"  | "`e(cmd)'"=="probit" | /*
+    */ "`e(cmd)'"=="logistic" | /*
+    */"`e(cmd)'"=="poisson" | "`e(cmd)'"=="nbreg"  {
+        matrix `x' = `x',J(1,1,1)
+        matrix `xb' = `x' * `b''
+        local nb = colsof(`b') - 1
+        matrix `b' = `b'[1,1..`nb'] /* get rid of _con */
+        scalar `sxb' = `xb'[1,1]
+        if "`e(cmd)'"=="logit" | "`e(cmd)'"=="logistic" {
+            scalar `prob' = exp(`sxb')/(1+exp(`sxb'))
+            scalar `tmp' = `prob'*(1-`prob')
+            matrix `marg' = `tmp'*`b'
+        }
+        else if "`e(cmd)'"=="probit" {
+            scalar `prob' = normprob(`sxb')
+            scalar `tmp'  = exp(-`sxb'*`sxb'/2)/sqrt(2*_pi)
+            matrix `marg' = `tmp'*`b'
+        }
+        else if "`e(cmd)'"=="poisson" | "`e(cmd)'"=="nbreg" {
+            scalar `prob' = exp(`sxb')
+            matrix `marg' = `prob'*`b'
+            scalar `prob' = -exp(`sxb') /* to undo change below */
+        }
+        matrix `prob' = -1 * `marg'
+        matrix `marg' = `prob' \ `marg'
+    }
+
+    if "`e(cmd)'"=="oprobit" | "`e(cmd)'"=="ologit" {
+        local ncats = e(k_cat)
+        * xb without intercept
+        local nb = colsof(`b') - `ncats' + 1
+        matrix `b' = `b'[1,1..`nb'] /* get rid of _con's */
+        matrix `xb' = `x' * `b''
+        scalar `sxb' = `xb'[1,1]
+        matrix `difpdf' = J(1,`ncats',1)
+        matrix `marg' = J(`nb',`ncats',1)
+        * compute probabilities
+        if "`e(cmd)'"=="oprobit" {
+            matrix `prob' = J(1,`ncats',1)
+            scalar `bxb' = _b[`cut'cut1]-`sxb'
+            matrix `prob'[1,1] = normprob(`bxb') /* prob for cat 1 */
+            matrix `difpdf'[1,1] = exp(-`bxb'*`bxb'/2)/sqrt(2*_pi)
+            local i 2
+            while `i'<`ncats' {
+                local im1 = `i' - 1
+                scalar `bxb' = _b[`cut'cut`i'] - `sxb'
+                scalar `bxbm1' = _b[`cut'cut`im1'] - `sxb'
+                matrix `prob'[1,`i'] = normprob(`bxb') - normprob(`bxbm1')
+                matrix `difpdf'[1,`i'] = exp(-`bxb'*`bxb'/2)/sqrt(2*_pi) /*
+                */ - exp(-`bxbm1'*`bxbm1'/2)/sqrt(2*_pi)
+                local i = `i' + 1
+            }
+            local im1 = `i' - 1
+            scalar `bxb' = `sxb'-_b[`cut'cut`im1']
+            matrix `prob'[1,`ncats'] = normprob(`bxb')
+            * 12/6/00
+            matrix `difpdf'[1,`ncats'] = -1*exp(-`bxb'*`bxb'/2)/sqrt(2*_pi)
+        }
+        if "`e(cmd)'"=="ologit" {
+            matrix `prob' = J(1,`ncats',1)
+            scalar `tmp' = 1/(1+exp(`sxb'-_b[`cut'cut1]))
+            matrix `prob'[1,1] = `tmp'
+            matrix `difpdf'[1,1] = `tmp'*(1-`tmp')
+            local i 2
+            while `i'<`ncats' {
+                local im1=`i'-1
+                scalar `tmp' = 1/(1+exp(`sxb'-_b[`cut'cut`i']))
+                scalar `tmp2' = 1/(1+exp(`sxb'-_b[`cut'cut`im1']))
+                matrix `prob'[1,`i'] = `tmp' - `tmp2'
+                matrix `difpdf'[1,`i'] = (`tmp'*(1-`tmp')) - (`tmp2'*(1-`tmp2'))
+                local i=`i'+1
+            }
+            local im1 = `i'-1
+            scalar `tmp' = 1/(1+exp(`sxb'-_b[`cut'cut`im1']))
+            matrix `prob'[1,`ncats'] = 1-`tmp'
+            matrix `difpdf'[1,`i'] = - (`tmp'*(1-`tmp'))
+        }
+        local i 1
+        while `i'<=`nb' {
+            local j 1
+            while `j'<=`ncats' {
+                matrix `marg'[`i',`j'] = -1 * `difpdf'[1,`j'] * `b'[1,`i']
+                local j = `j' + 1
+            }
+            local i = `i' + 1
+        }
+    }
+
+    if "`e(cmd)'"=="mlogit" {
+        matrix `x'  = PE_base
+        matrix `xo' = `x',J(1,1,1)
+        matrix `PredVal'  = J(1,1,1)
+        matrix colnames `PredVal' = xb
+        /* 1.6.4 - does not work with Stat 11
+        version 5.0
+        matrix `b' = get(_b)
+        version 6.0
+        */
+        * 2007-06-29 stata 10
+        if c(stata_version) < 10 {
+            local ncats = e(k_cat)
+        }
+        else {
+            local ncats = e(k_out)
+        }
+        matrix `prob' = J(1,`ncats',-1)
+        matrix `xb' = `b'*`xo'' /* one row for each set of b's */
+        matrix `PredVal' = `xb'
+        scalar `sumxb' = 1
+        local i = 1
+        while `i' < `ncats' {
+            scalar `sxb' = exp(`xb'[`i',1])
+            scalar `sumxb' = `sumxb' + `sxb' /* sum of exp(xb) */
+            matrix `prob'[1,`i'] = `sxb'
+            local i = `i' + 1
+        }
+        scalar `sumxb' = 1/`sumxb'
+        matrix `prob'[1,`ncats'] = 1
+        matrix `prob' = `sumxb'*`prob'
+        matrix `PredPr' = `prob'
+        matrix `pdiag' = `PredPr'
+        matrix `pdiag' = diag(`pdiag')
+        * 2007-06-29 stata 10
+        if c(stata_version) < 10 {
+            local ncats = e(k_cat)
+        }
+        else {
+            local ncats = e(k_out)
+        }
+        local nb = colsof(`b')
+        matrix `b' = `b' \ J(1,`nb',0) /* add 0's for last outcome */
+        matrix `marg' = `pdiag' * (`b' - (J(`ncats',`ncats',1)*`pdiag'*`b'))
+        local nb = colsof(`b') - 1
+        matrix `marg' = `marg'[.,1..`nb']
+        matrix `marg' = `marg''
+    }
+    return matrix marginal `marg'
+
+end
+exit
+
+* version 1.6.0 3/29/01
+* version 1.6.1 11Apr2005 fix _cut for stata 9
+* version 1.6.2 13Apr2005
+* version 1.6.3 13Jun2005 - fix ologit version 8/9 bug with _cut
+* version 1.6.4 2007-06-29 stata 10
+* version 1.7.0 2009-09-19 jsl
+*   - fix for e(b) for mlogit in stata 11
diff --git a/Modules/ado/plus/_/_pemarg.hlp b/Modules/ado/plus/_/_pemarg.hlp
new file mode 100644
index 0000000..697bc4b
--- /dev/null
+++ b/Modules/ado/plus/_/_pemarg.hlp
@@ -0,0 +1,15 @@
+.-
+help for ^_pemarg^
+.-
+
+    ^_pemarg^
+
+^_pemarg^ computes marginal effects for some regression models.  ^_pemarg^ 
+takes as its input the contents of the PE_base matrix created by ^_pebase^.  
+^_pemarg^ returns the marginal effects in r() class matrix r(marginal)
+
+.-
+Authors: J. Scott Long and Jeremy Freese
+         www.indiana.edu/~jslsoc/spost.htm
+         spostsup@@indiana.edu
+         
diff --git a/Modules/ado/plus/_/_penocon.ado b/Modules/ado/plus/_/_penocon.ado
new file mode 100644
index 0000000..400ad36
--- /dev/null
+++ b/Modules/ado/plus/_/_penocon.ado
@@ -0,0 +1,94 @@
+*! version 0.2.3 13Apr2005
+*  version 0.2.2 2005-03-29 stata 9 bug for aux parameters
+*  version 0.2.1 2005-03-25 fixed long varlist bug
+*  version 0.2.0 2005-02-03
+
+*   determine if model has a constant in it
+
+capture program drop _penocon
+program define _penocon, rclass
+    version 9.0
+    tempname beta
+    matrix `beta' = e(b)
+    local nbeta = colsof(`beta')
+    local names : colnames `beta'
+    local tmpnms : subinstr local names `"_cons"' `"dog"', all count(local count)
+    local isnocon = 1 - `count'
+
+// binary
+
+    if "`e(cmd)'"=="cloglog"  {
+        local isnocon = `isnocon'
+    }
+    if "`e(cmd)'"=="logistic" {
+        local isnocon = `isnocon'
+    }
+    if "`e(cmd)'"=="logit"    {
+        local isnocon = `isnocon'
+    }
+    if "`e(cmd)'"=="probit"   {
+        local isnocon = `isnocon'
+    }
+
+// ordered : nocon not allowed
+
+    if "`e(cmd)'"=="ologit"   {
+        local isnocon = 0
+    }
+    if "`e(cmd)'"=="oprobit"  {
+        local isnocon = 0
+    }
+    if "`e(cmd)'"=="gologit"  {
+        local isnocon = 0
+    }
+
+// count
+
+    if "`e(cmd)'"=="poisson"  {
+        local isnocon = `isnocon'
+    }
+    if "`e(cmd)'"=="nbreg"    {
+        local nrhs = e(df_m)
+        local nbeta = `nbeta' - 1 // subtract alpha
+        local isnocon = (`nrhs'==`nbeta')
+    }
+
+    if "`e(cmd)'"=="zinb"     {
+        local tmpnms : subinstr local names `"_cons"' `"dog"', all count(local count)
+        local isnocon = (`count'<3)
+    }
+    if "`e(cmd)'"=="zip"      {
+        local tmpnms : subinstr local names `"_cons"' `"dog"', all count(local count)
+        local isnocon = (`count'<2)
+    }
+
+// regression models
+
+    if "`e(cmd)'"=="regress" | "`e(cmd)'"=="fit" {
+        local isnocon = `isnocon'
+    }
+    if "`e(cmd)'"=="tobit"    {
+        * stata 9 includes auxillary parameters as a second equation
+        local isnocon = (`count'==1)
+    }
+    if "`e(cmd)'"=="cnreg"    {
+        local isnocon = (`count'==1)
+    }
+    if "`e(cmd)'"=="intreg"   {
+        local isnocon = (`count'==1)
+    }
+
+//  nominal
+
+    if "`e(cmd)'"=="mlogit"   {
+        _perhs
+        local nrhs = r(nrhs)
+        local ncatm1 = e(k_cat) - 1
+        local isnocon = (`nrhs'*`ncatm1'==`nbeta')
+    }
+
+//  return results
+
+    return local nocon  "`isnocon'"
+
+end
diff --git a/Modules/ado/plus/_/_penocon.hlp b/Modules/ado/plus/_/_penocon.hlp
new file mode 100644
index 0000000..f341644
--- /dev/null
+++ b/Modules/ado/plus/_/_penocon.hlp
@@ -0,0 +1,41 @@
+{smcl}
+{* 01/13/05}{...}
+{hline}
+help for {hi:_penocon}{right:1/13/2005}
+{hline}
+
+{title: Utility to determine if model was run with nocon option}
+
+{p 8 15 2}{cmd:_penocon}
+
+
+{title: Description}
+
+{p 4 4 2}
+{cmd:_penocon} returns 1 if model used nocon option, else 0. Works
+with {help cloglog}, {help logistic}, {help logit}, {help probit},
+{help ologit}, {help oprobit}, {help gologit}, {help poisson},
+{help nbreg}, {help zinb}, {help zip}, {help regress}, {help tobit},
+{help cnreg}, {help fit}, {help intreg}, and {help mlogit}.
+
+{title: Returns}
+
+{p 4 8 2}
+r(nocon) : local with 1 if nocon option, else 0.
+
+{title: Examples}
+
+    ...
+    _penocon
+    local isnocon = r(nocon)
+    if `isnocon'==1 {
+        ::: case without constant :::
+    }
+    else {
+        :::
+    }
+
+{hline}
+{p 2 4 2}Authors: J. Scott Long & Jun Xu{p_end}
+{p 11 4 2}{browse www.indiana.edu/~jslsoc/spost.htm}{p_end}
+{p 11 4 2}spostsup@indiana.edu{p_end}
diff --git a/Modules/ado/plus/_/_pepred.ado b/Modules/ado/plus/_/_pepred.ado
new file mode 100644
index 0000000..7c653b4
--- /dev/null
+++ b/Modules/ado/plus/_/_pepred.ado
@@ -0,0 +1,651 @@
+*! version 1.6.9 2013-08-05 increase maxcnt to 40
+* version 1.6.8 2008-07-10
+*   - make stdp global
+
+* _pepred takes as input the matrix PE_in; each row is an observation and
+* the columns are values for the independent variables in the regression
+* model.  _pepred temporarily adds these observations to the dataset and
+* generates predicted values.  _pepred puts the predicted values in
+* return matrices that can then be used by the calling program.
+
+capture program drop _pepred
+program define _pepred, rclass
+    version 6
+    tempvar added stdp stdf xb xb_hi xb_lo p p1 p1_hi p1_lo p0 p0_hi p0_lo mucount mu
+    tempvar mu_hi mu_lo tempvar p1_inf p0_inf always0
+    tempname b alpha ai gai b_inf xb_inf infby replval zwidth
+    syntax [, level(integer $S_level) maxcnt(integer 9) choices(varlist)]
+    *handle 'level' option
+    if `level' < 10 | `level' > 99 {
+        di in r "level() invalid"
+        error 198
+    }
+    local level = `level'/100
+    *`zwidth' = SD width of confidence interval for `level'% ci
+    sca `zwidth' = invnorm(`level'+((1-`level')/2))
+
+    *check if `maxcnt' specified to acceptable value
+    local max_i = `maxcnt'  /* how should this be set */
+    if `max_i' < 0 | `max_i' > 41 {
+        di in r "maxcnt() value not allowed"
+        exit 198
+    }
+
+    *preserve needed because data altered
+    preserve
+
+    *add observations to end of dataset
+    qui gen `added' = 0
+    local newobs = rowsof(PE_in)
+    local oldn = _N
+    local newn = `oldn'+`newobs'
+    qui set obs `newn'
+    *`added'==1 for observations created by _pepred
+    qui replace `added' = 1 if `added' == .
+
+    *use _perhs to get information about rhs variables
+    _perhs
+    local nrhs `r(nrhs)'
+    local nrhs2 `r(nrhs2)'
+    local rhsnms `r(rhsnms)'
+    local rhsnms2 `r(rhsnms2)'
+
+    *fill in added observations with rows of PE_in
+    *cycle through all rhs variables
+    local i = 1
+    while `i' <= `nrhs' {
+        local varname : word `i' of `rhsnms'
+        *for each rhs variable, cycle through all added observations
+        local i2 = 1
+        while `i2' <= `newobs' {
+            *to_rep is the row number of the observation to insert PE_in values
+            local to_rep = `oldn' + `i2'
+            *`replval' value to move from PE_in to dataset
+            sca `replval' = PE_in[`i2',`i']
+            qui replace `varname' = `replval' in `to_rep'
+            local i2 = `i2' + 1
+        }
+        local i = `i' + 1
+    }
+
+    *fill in values for variables in second equation of ZIP/ZINB model
+    if "`nrhs2'"!="" {
+        local i = 1
+        while `i' <= `nrhs2' {
+            local varname : word `i' of `rhsnms2'
+            local i2 = 1
+            while `i2' <= `newobs' {
+                local to_rep = `oldn' + `i2'
+                sca `replval' = PE_in2[`i2',`i']
+                qui replace `varname' = `replval' in `to_rep'
+                local i2 = `i2' + 1
+            }
+            local i = `i' + 1
+        }
+    } /* if "`nrhs2'"!="" */
+
+    *list `rhsnms' in -`newobs'/-1
+    *if "`nrhs2'"!="" { list `rhsnms2' in -`newobs'/-1 }
+
+    *specify routine below that estimation command should call
+
+    if "`e(cmd)'"=="slogit"  { local routine "slogit" } // 26Mar2005
+    if "`e(cmd)'"=="mprobit" { local routine "mprobit" } // 28Feb2005
+    if "`e(cmd)'"=="ztp"     { local routine "zt" } // 050218
+    if "`e(cmd)'"=="ztnb"    { local routine "zt" }
+    if "`e(cmd)'"=="clogit"  { local routine "clogit" }
+    if "`e(cmd)'"=="cloglog" { local routine "binary" }
+    if "`e(cmd)'"=="cnreg"   { local routine "tobit" }
+    if "`e(cmd)'"=="fit"     { local routine "regress" }
+    if "`e(cmd)'"=="gologit" { local routine "gologit" }
+    if "`e(cmd)'"=="intreg"  { local routine "tobit" }
+    if "`e(cmd)'"=="logistic" { local routine "binary" }
+    if "`e(cmd)'"=="logit"   { local routine "binary" }
+    if "`e(cmd)'"=="mlogit"  { local routine "mlogit" }
+    if "`e(cmd)'"=="nbreg"   { local routine "count" }
+    if "`e(cmd)'"=="ologit"  { local routine "ordered" }
+    if "`e(cmd)'"=="oprobit" { local routine "ordered" }
+    if "`e(cmd)'"=="poisson" { local routine "count" }
+    if "`e(cmd)'"=="probit"  { local routine "binary" }
+    if "`e(cmd)'"=="regress" { local routine "regress" }
+    if "`e(cmd)'"=="tobit"   { local routine "tobit" }
+    if "`e(cmd)'"=="zinb"    { local routine "zeroinf" }
+    if "`e(cmd)'"=="zip"     { local routine "zeroinf" }
+
+*Note: these routines define a local macro `newvars', which is a list of
+* all matrices that _pepred will return to the calling program.
+
+*NB!?: predictions are done for all observations because you can't use temporary
+*variables as an if condition after predict (if `added' == 1)
+
+*BINARY ROUTINE
+
+    if "`routine'" == "binary" {
+        local newvars "xb stdp p1 p0 xb_hi p1_hi p0_hi xb_lo p1_lo p0_lo"
+
+        quietly {
+
+            *use predict to get xb and std err of prediction
+            predict `xb', xb
+            predict `stdp', stdp
+            *2008-07-09
+            global stdp = `stdp'[1]
+
+            *calculate upper and lower ci for xb
+            gen `xb_hi' = `xb' + (`zwidth'*`stdp')
+            gen `xb_lo' = `xb' - (`zwidth'*`stdp')
+
+            *convert ci bounds into probabilities
+            if "`e(cmd)'"=="logit" | "`e(cmd)'"=="logistic" {
+                gen `p1' = exp(`xb')/(1+exp(`xb'))
+                gen `p1_hi' = exp(`xb_hi')/(1+exp(`xb_hi'))
+                gen `p1_lo' = exp(`xb_lo')/(1+exp(`xb_lo'))
+            }
+            if "`e(cmd)'"=="probit" {
+                gen `p1' = normprob(`xb')
+                gen `p1_hi' = normprob(`xb_hi')
+                gen `p1_lo' = normprob(`xb_lo')
+            }
+            if "`e(cmd)'"=="cloglog" {
+                gen `p1' = 1 - exp(-exp(`xb'))
+                gen `p1_hi' = 1 - exp(-exp(`xb_hi'))
+                gen `p1_lo' = 1 - exp(-exp(`xb_lo'))
+            }
+
+            *use prob(1) values to calculate corresponding prob(0) values
+            gen `p0' = 1 - `p1'
+            gen `p0_hi' = 1 - `p1_hi'
+            gen `p0_lo' = 1 - `p1_lo'
+
+        } /* quietly */
+    }
+
+* ORDERED ROUTINE
+
+    if "`routine'" == "ordered" {
+        quietly {
+
+            *get information about categories of dependent variables
+            _pecats
+            local ncats = r(numcats)
+            local catvals "`r(catvals)'"
+
+            *use predict to get probabilities for each outcome
+            *cycle through each category
+            local i = 1
+            while `i' <= `ncats' {
+                tempvar p`i'
+                local newvars "`newvars'p`i' "
+                local catval : word `i' of `catvals'
+                *_PEtemp has to be used because temporary variable causes error
+                capture drop _PEtemp
+                predict _PEtemp, p outcome(`catval')
+                gen `p`i'' = _PEtemp
+                local i = `i' + 1
+            }
+
+            *use predict to get probability of xb and std err of prediction
+            local newvars "`newvars'xb stdp xb_hi xb_lo"
+            capture drop _PEtemp
+            predict _PEtemp, xb
+            qui gen `xb' = _PEtemp
+            capture drop _PEtemp
+            predict _PEtemp, stdp
+            qui gen `stdp' = _PEtemp
+            *2008-07-09
+            global stdp = `stdp'[1]
+
+            *calculate upper and lower ci's for xb
+            gen `xb_hi' = `xb' + (`zwidth'*`stdp')
+            gen `xb_lo' = `xb' - (`zwidth'*`stdp')
+
+        } /* quietly { */
+    } /* if "`routine'" == "ordered" */
+
+* MLOGIT ROUTINE
+
+    if "`routine'" == "mlogit" {
+
+        *get information on categories of dependent variable
+        _pecats
+        local ncats = r(numcats)
+        local catvals "`r(catvals)'"
+        local refval "`r(refval)'"
+
+        local i = 1
+        quietly {
+            while `i' <= `ncats' {
+                tempvar p`i' xb`i' stdp`i' sdp`i' xb_hi`i' xb_lo`i'
+                local newvars "`newvars'p`i' "
+
+                *use predict to get probabilities for each outcome
+                local catval : word `i' of `catvals'
+                capture drop _PEtemp
+                predict _PEtemp, p outcome(`catval')
+                gen `p`i'' = _PEtemp
+
+                *if `i' != `ncats', then outcome is not base category
+                if `i' != `ncats' {
+                    local newvars "`newvars'xb`i' stdp`i' sdp`i' "
+                    capture drop _PEtemp
+                    *use predict to get standard error of prediction
+                    predict _PEtemp, stdp outcome(`catval')
+                    qui gen `stdp`i'' = _PEtemp
+                    capture drop _PEtemp
+                    *use predict to get standard error of difference in prediction
+                    predict _PEtemp, stddp outcome(`catval', `refval')
+                    qui gen `sdp`i'' = _PEtemp
+                    capture drop _PEtemp
+                    *use predict to get xb
+                    predict _PEtemp, xb outcome(`catval')
+                    qui gen `xb`i'' = _PEtemp
+                    *calculate upper and lower bounds of ci
+                    qui gen `xb_hi`i'' = `xb`i'' + (`zwidth'*`stdp`i'')
+                    qui gen `xb_lo`i'' = `xb`i'' - (`zwidth'*`stdp`i'')
+                }
+                local i = `i' + 1
+            } /* while `i' <= `ncats' */
+        }
+    }
+
+* MPROBIT 28Feb2005
+
+    if "`routine'" == "mprobit" {
+
+        *get information on categories of dependent variable
+        _pecats
+        local ncats = r(numcats)
+        local catvals "`r(catvals)'"
+        local refval "`r(refval)'"
+
+        local i = 1
+        quietly {
+            while `i' <= `ncats' {
+                tempvar p`i' xb`i' /*stdp`i' sdp`i' xb_hi`i' xb_lo`i'*/
+                local newvars "`newvars'p`i' "
+                *use predict to get probabilities for each outcome
+                local catval : word `i' of `catvals'
+                capture drop _PEtemp
+                predict _PEtemp, p outcome(`catval')
+                gen `p`i'' = _PEtemp
+
+                *if `i' != `ncats', then outcome is not base category
+                if `i' != `ncats' {
+                    local newvars "`newvars'xb`i' " /*stdp`i' sdp`i' "*/
+                    capture drop _PEtemp
+                    *use predict to get standard error of prediction
+                    capture drop _PEtemp
+                    *use predict to get standard error of difference in prediction
+                    capture drop _PEtemp
+                    *use predict to get xb
+                    predict _PEtemp, xb outcome(`catval')
+                    qui gen `xb`i'' = _PEtemp
+                }
+                local i = `i' + 1
+            } /* while `i' <= `ncats' */
+        }
+    }
+
+
+* SLOGIT 26Mar2005
+
+    if "`routine'" == "slogit" {
+        *get information on categories of dependent variable
+        _pecats
+        local ncats = r(numcats)
+        local catvals "`r(catvals)'"
+        local refval "`r(refval)'"
+
+        local i = 1
+        quietly {
+            while `i' <= `ncats' {
+                tempvar p`i' xb`i' /*stdp`i' sdp`i' xb_hi`i' xb_lo`i'*/
+                local newvars "`newvars'p`i' "
+                *use predict to get probabilities for each outcome
+                local catval : word `i' of `catvals'
+                capture drop _PEtemp
+                predict _PEtemp, p outcome(`catval')
+                gen `p`i'' = _PEtemp
+                local i = `i' + 1
+            } /* while `i' <= `ncats' */
+        } /* quietly */
+    } /* if "`routine'" == "slogit" */
+
+    if "`routine'" == "gologit" {
+
+        *get information about number of categories
+        _pecats
+        local ncats = r(numcats)
+        local catvals "`r(catvals)'"
+        local numeqs = `ncats'-1 /* number of equations */
+        quietly {
+
+            *cycle through each equation
+            local i = 1
+            while `i' <= `numeqs' {
+                tempvar xb`i' pcut`i'
+                *use predict to get xb for each equation
+                predict `xb`i'', eq(mleq`i')
+                local newvars "`newvars'xb`i' "
+                *convert xb into prob(y<=`i')
+                gen `pcut`i'' = exp(`xb`i'')/(1+exp(`xb`i''))
+                local i = `i' + 1
+            }
+
+            *setting variables to indicate that prob(y<=0)=0 and prob(y<=`ncats)=1
+            tempvar pcut`ncats' pcut0
+            gen `pcut`ncats''=0
+            gen `pcut0'=1
+
+            *cycle through categories
+            local i = 1
+            while `i' <= `ncats' {
+                tempvar p`i'
+                local newvars "`newvars'p`i' "
+                local j = `i' - 1
+                *calculate prob(y=i) as prob(y<=i) - prob(y<=[i-1])
+                gen `p`i'' = `pcut`j''-`pcut`i''
+                local i = `i' + 1
+            } /* while `i' <= `ncats' */
+        }  /* quietly */
+    } /* if "`routine'" == "gologit" */
+
+* COUNT MODEL ROUTINE
+
+    if "`routine'"=="count" | "`routine'" == "zt" { // 050218
+        quietly {
+
+            *get alpha if nbreg
+            *zt 18Feb2005
+            if "`e(cmd)'"=="nbreg" | "`e(cmd)'"=="ztnb" {
+                sca `alpha' = e(alpha)
+                sca  `ai' = 1/`alpha'
+                *`gai' used to calculate probabilities
+                sca  `gai' = exp(lngamma(`ai'))
+                if `gai'==. {
+                    di in r "problem with alpha from nbreg prohibits " /*
+                    */ "estimation of predicted probabilities"
+                    exit 198
+                }
+            }
+
+            *use predict to get mu, xb, and std err of prediction
+            *zt add Cmu for conditional mu 050218
+            tempname Cmu
+            local newvars "mu xb stdp "
+            capture drop _PEtemp
+            predict double _PEtemp, ir  /* does not handle offset or exposure */
+            gen `mu' = _PEtemp
+            capture drop _PEtemp
+            predict double _PEtemp, xb
+            gen `xb' = _PEtemp
+            capture drop _PEtemp
+            predict double _PEtemp, stdp
+            gen `stdp' = _PEtemp
+            *zt Cmu 18Feb2005
+            * compute conditional rate
+            if "`e(cmd)'"=="ztnb" | "`e(cmd)'"=="ztp" {
+                capture drop _PEtemp
+                predict double _PEtemp, cm
+                gen `Cmu' = _PEtemp
+                local newvars "mu xb stdp Cmu "
+            }
+
+            *ci's for poisson (doesn't work for nbreg because of alpha)
+            *zt and compute upper and lower 18Feb2005
+            if "`e(cmd)'"=="poisson" | "`e(cmd)'"=="ztp" {
+                local newvars "`newvars'xb_hi xb_lo mu_hi mu_lo "
+                gen `xb_hi' = `xb' + (`zwidth'*`stdp')
+                gen `xb_lo' = `xb' - (`zwidth'*`stdp')
+                gen `mu_hi' = exp(`xb_hi')
+                gen `mu_lo' = exp(`xb_lo')
+            }
+
+            *calculate prob of observing a given count [Prob(y=1)]
+            *cycle from 0 to maximum count wanted
+            local i = 0
+            while `i' <= `max_i' {
+                tempvar p`i'
+                local newvars "`newvars'p`i' "
+                *predicting a particular count from mu
+                *zt 18Feb2005
+                if "`e(cmd)'"=="poisson" | "`e(cmd)'"=="ztp"  {
+                    * usual poisson formula
+                    qui gen double `p`i'' = ((exp(-`mu'))*(`mu'^`i')) / /*
+                        */ (round(exp(lnfact(`i'))), 1)
+                    tempname p_hi`i' p_lo`i'
+                    local newvars "`newvars'p_hi`i' p_lo`i' "
+                    qui gen double `p_hi`i'' = /*
+                        */ ((exp(-`mu_hi'))*(`mu_hi'^`i')) / /*
+                        */ (round(exp(lnfact(`i'))), 1)
+                    qui gen double `p_lo`i'' /*
+                        */ = ((exp(-`mu_lo'))*(`mu_lo'^`i')) /*
+                        */ / (round(exp(lnfact(`i'))), 1)
+                }
+
+                *zt 18Feb2005
+                if "`e(cmd)'"=="nbreg" | "`e(cmd)'"=="ztnb"  {
+                    capture drop _PEtemp
+                    qui gen double _PEtemp = (  exp(lngamma(`i'+`ai')) /*
+                    */ / ( round(exp(lnfact(`i')),1) * exp(lngamma(`ai')) ) ) /*
+                    */ * ((`ai'/(`ai'+`mu'))^`ai') * ((`mu'/(`ai'+`mu'))^`i')
+                    qui gen double `p`i'' = _PEtemp
+                }
+                local i = `i' + 1
+            }
+            return scalar maxcount = `max_i'
+        } /* quietly */
+
+*-> GENERATE CONDITIONAL PREDICTED PROBABILITIES
+    *zt compute conditional predictions 18Feb2005
+    if "`e(cmd)'"=="ztp" | "`e(cmd)'"=="ztnb" {
+        local i 1
+        while `i' <= `max_i' {
+            tempvar Cp`i' // C for Conditional
+            local newvars "`newvars'Cp`i' "
+            * divide by prob not equal to 0
+            quietly gen `Cp`i'' = `p`i''/(1-`p0')
+            label variable `Cp`i'' "Pr(y=`i'|y>0) `modelis'"
+            local i = `i' + 1
+        }
+    } // zt
+
+    } /* if "`routine'" == "count" */
+
+
+* ZERO-INFLATED COUNT MODEL ROUTINE
+
+    if "`routine'"=="zeroinf" {
+        quietly {
+            * mucount == mu from count portion of model - 15Apr2005
+            * mu == expected y
+            local newvars "mu mucount xb stdp p "
+            capture drop _PEtemp
+            * E(y)
+            predict double _PEtemp, n  /* does not handle offset or exposure */
+            gen double `mu' = _PEtemp
+            capture drop _PEtemp
+            predict double _PEtemp, xb
+            * xb from the count portion of the model
+            gen double `xb' = _PEtemp
+            capture drop _PEtemp
+            predict double _PEtemp, stdp
+            gen `stdp' = _PEtemp
+            capture drop _PEtemp
+            predict double _PEtemp, p
+            gen `p' = _PEtemp
+            * E(y | not always 0) - 15Apr2005
+            quietly gen double `mucount' = `mu'/(1-`p')
+            mat `b' = e(b)
+            if "`e(cmd)'"=="zinb" {
+                local temp = colsof(`b')
+                sca `alpha' = `b'[1, `temp']
+                sca `alpha' = exp(`alpha')
+                sca `ai' = 1/`alpha'
+                sca `gai' = exp(lngamma(`ai'))
+                if `gai'==. {
+                    di in r "problem with alpha from zinb prohibits " /*
+                    */ "estimation of predicted probabilities"
+                    exit 198
+                }
+                *take alpha off beta matrix
+                local temp = `temp' - 1
+                mat `b' = `b'[1, 1..`temp']
+            }
+
+            *make beta matrix for inflate equation
+            local temp = `nrhs' + 2
+            local temp2 = colsof(`b')
+            mat `b_inf' = `b'[1,`temp'..`temp2']
+
+            *calculate xb of the inflate model
+            local newvars "`newvars'xb_inf "
+            gen double `xb_inf' = 0 if `added' == 1
+            local i = 1
+            while `i' <= `nrhs2' {
+                local infvar : word `i' of `rhsnms2'
+                sca `infby' = `b_inf'[1,`i']
+                replace `xb_inf' = `xb_inf' + (`infby'*`infvar')
+                local i = `i' + 1
+            }
+            *add constant
+            replace `xb_inf' = `xb_inf' + `b_inf'[1, `i']
+
+            *calculate prob(inflate==1)
+            if "`e(inflate)'"=="logit" {
+                gen `p1_inf' = exp(`xb_inf')/(1+exp(`xb_inf'))
+            }
+            if "`e(inflate)'"=="probit" {
+                gen `p1_inf' = normprob(`xb_inf')
+            }
+
+            *calculate prob(inflate==0)
+            gen `p0_inf' = 1 - `p1_inf'
+
+            *return prob(inflate==1) as `always0'
+            local newvars "`newvars'always0 "
+            gen `always0' = `p1_inf'
+
+            *predicting a particular count from mucount
+            local i = 0
+            while `i' <= `max_i' {
+                tempvar p`i'
+                local newvars "`newvars'p`i' "
+                * use mucount not mu! 15Apr2005
+                if "`e(cmd)'"=="zip" {
+                    qui gen double `p`i'' = /*
+                    */ ((exp(-`mucount'))*(`mucount'^`i'))/(round(exp(lnfact(`i'))), 1)
+                }
+                * use mucount not mu! 15Apr2005
+                if "`e(cmd)'"=="zinb" {
+                    capture drop _PEtemp
+                    qui gen double _PEtemp = (  exp(lngamma(`i'+`ai')) /*
+                    */ / (round(exp(lnfact(`i')),1) * exp(lngamma(`ai')))) /*
+                    */ * ((`ai'/(`ai'+`mucount'))^`ai') * ((`mucount'/(`ai'+`mucount'))^`i')
+                    qui gen double `p`i'' = _PEtemp
+                }
+
+                *adjust counts for always zeros
+                qui replace `p`i'' = `p`i''*`p0_inf'
+
+               local i = `i' + 1
+            }
+            *adjust prob(y=0) for always zeros
+            replace `p0' = `p0' + `always0'
+            return scalar maxcount = `max_i'
+
+        }  /* quietly */
+    }    /* if "`routine'" == "zeroinf" */
+
+* TOBIT ROUTINE
+
+    if "`routine'" == "tobit" {
+* remove stdf 6/23/2006
+*        local newvars "`newvars'xb xb_hi xb_lo stdp stdf "
+        local newvars "`newvars'xb xb_hi xb_lo stdp "
+        quietly {
+            predict `xb', xb
+            predict `stdp', stdp
+            *2008-07-09
+            global stdp = `stdp'[1]
+
+            * remove stdf 6/23/2006
+            * predict `stdf', stdf
+            gen `xb_hi' = `xb' + (`zwidth'*`stdp')
+            gen `xb_lo' = `xb' - (`zwidth'*`stdp')
+        }
+    }
+
+* REGRESS ROUTINE
+
+    if "`routine'" == "regress" {
+        * remove stdf 6/23/2006
+        * local newvars "`newvars'xb xb_hi xb_lo stdp stdf "
+        local newvars "`newvars'xb xb_hi xb_lo stdp "
+        quietly {
+            predict `xb', xb
+            predict `stdp', stdp
+            *2008-07-09
+            global stdp = `stdp'[1]
+
+            * remove stdf 6/23/2006
+            * predict `stdf', stdf
+            gen `xb_hi' = `xb' + (`zwidth'*`stdp')
+            gen `xb_lo' = `xb' - (`zwidth'*`stdp')
+        }
+    }
+
+** MAKE RETURN MATRICES
+
+    *return level
+    return local level `level'
+    tokenize "`newvars'"
+
+    *cycle through all the new variables created by routine above
+    local i = 1
+    while "``i''" != "" {
+
+        *make matrix tmatnam with all observations for a given new variable
+        local tmatnam = "_``i''"
+        if length("`tmatnam'") > 7 {
+            local tmatnam = substr("`tmatnam'", 1, 7)
+        }
+        tempname `tmatnam'
+        mat ``tmatnam'' = J(`newobs', 1, 0)
+        local i2 = 1
+        while `i2' <= `newobs' {
+            local outob = `oldn' + `i2'
+            mat ``tmatnam''[`i2',1] = ```i'''[`outob']
+            local i2 = `i2' + 1
+        }
+        *return matrix so available to calling program
+        return matrix ``i'' ``tmatnam''
+        local i = `i' + 1
+    }
+
+end
+
+
+exit
+
+15Apr2005 - correct error for zip and zinb (see changes in _pepred, _pecollect, _peciboot
+
+    E(y) was used incorrectly rather than E(y|~always0).
+
+    _pepred[3|5|7, 2] used to be mu defined as rate in count portion of model E(y|not always 0)
+
+    _pepred[3|5|7, 2] now is the overall rate E(y); listed as simply mu.
+
+    _pepred[3|5|7, 3] rate in count portion of model E(y|not always 0); listed as mucount.
+
+To simplify changes in _peciboot, E(y) is referred to as mu; E(y|~always0) is mucount.
+
+* version 1.6.7 2008-07-09
+*   - save se of ystar predictions
+* version 1.6.6 23Jun2006 fix stdf bug for regress and tobit
+* version 1.6.5 15Apr2005 fix rate used for zip/zinb (see notes at end)
+* version 1.6.4 13Apr2005
+* version 1.6.3 27Mar2005 slogit
+* version 1.6.2 28Feb2005 mprobit
+* version 1.6.1 18Feb2005 zt models
+* version 1.6.0 3/29/01
diff --git a/Modules/ado/plus/_/_pepred.hlp b/Modules/ado/plus/_/_pepred.hlp
new file mode 100644
index 0000000..f5d62ae
--- /dev/null
+++ b/Modules/ado/plus/_/_pepred.hlp
@@ -0,0 +1,54 @@
+.-
+help for ^_pepred^
+.-
+
+    _pepred [, level(integer) maxcnt(integer)]
+
+^_pepred^ is a utility program designed to generate predicted values from a
+series of specified values of the independent variables.  _pepred takes as 
+input the matrix PE_in; each row is an observation and the columns are 
+values for the independent variables in the regression model.  ^_pepred^ 
+temporarily adds these observations to the dataset and generates predicted 
+values.  _pepred puts the predicted values in return matrices that can then 
+be used by the calling program.
+
+Options
+-------
+
+^level()^ sets the level of the confidence interval for predicted values
+    or probabilities for the estimation commands for which these are 
+    provided.
+
+^maxcnt()^ is the maximum count value for which the probability is computed
+    in count models. Default is 9.
+
+Return Values
+-------------
+
+Scalars
+  r(always0) : pr(Always0) for zip and zinb
+  r(xb): value of xb
+  r(xb_lo): lower bound of confidence interval for xb
+  r(xb_hi): upper bound of confidence interval for xb
+  r(p0): predicted prob of 0 for binary model
+  r(p0_lo): lower bound of confidence interval for predicted probability of 0
+  r(p0_hi): upper bound of confidence interval for predicted probability of 0
+  r(p1): predicted prob of 1 for binary model
+  r(p1_lo): lower bound of confidence interval for predicted probability of 1
+  r(p1_hi): upper bound of confidence interval for predicted probability of 1
+  r(mu): predicted count or rate for count models
+
+Macros:
+  r(level) : confidence level for commands that have this
+
+Matrices:
+  r(probs): predicted probabilities for multiple categories or counts
+  r(values): values of outcome categories for rows of r(probs)
+  r(x): x values for independent variables
+  r(x2): x values for independent variables in second equation (^zip^, ^zinb^)
+
+.-
+Authors: J. Scott Long and Jeremy Freese
+         www.indiana.edu/~jslsoc/spost.htm
+         spostsup@@indiana.edu
+         
diff --git a/Modules/ado/plus/_/_perhs.ado b/Modules/ado/plus/_/_perhs.ado
new file mode 100644
index 0000000..6591f90
--- /dev/null
+++ b/Modules/ado/plus/_/_perhs.ado
@@ -0,0 +1,107 @@
+*! version 1.6.6 2010-06-30 parse out o. names
+* version 1.6.5 13Apr2005
+*  version 1.6.4 2005-01-23 fix with zip and nocon
+
+*   determine rhs variables
+
+capture program drop _perhs
+program define _perhs, rclass
+    version 6.0
+    * if name is passed as option it will parse these names
+    local beta "`1'"
+    if "`beta'" == "" {
+        tempname beta
+        matrix `beta' = e(b)
+    }
+    local varnms : colnames(`beta')
+
+
+* 1.6 6 - strip out omitted coefficients with names o.
+    local no_o ""
+    foreach v in `varnms' {
+        local iso = substr("`v'",1,2)
+        if "`iso'"!="o." {
+            local no_o "`no_o' `v'"
+        }
+    }
+    local varnms `no_o'
+
+    tokenize "`varnms'", parse(" ")
+
+    local iszi = 0 /* is it a zip model? */
+    if "`e(cmd)'"=="zip" | "`e(cmd)'"=="zinb" {
+        _penocon /* check if there is a constant */
+        local ncon = 1 - `r(nocon)' /* 1 if constant, else 0 */
+        local iszi = 1 /* it is a zip */
+    }
+
+    * strip off _cons, _cut & _se
+    local rhsnm ""
+
+    *050123 only for nonzip
+    if `iszi'==0 {
+        local hascon "no"
+        local i 1
+        while "``i''" != "" {
+            * version 1.6.3 2004-12-22 - wrong rhs names if mlogit, nocon
+            * When it finds the same variable a second time, program sets
+            * local hascon to yes even though there is not a constant.
+            * without this it would repeat all variables ncat-1 times.
+            if "`i'"=="1" {
+                local nm1 "``i''"
+            }
+            else if "`nm1'" == "``i''" {
+                local hascon "yes"
+            }
+
+            if "``i''" == "_cons" & "`hascon'"=="no" {
+                local hascon "yes"
+                local start2 = `i' + 1
+            }
+            if "``i''" != "_cons" /*
+                */ & "``i''" != "_se" /*
+                */ & substr("``i''",1,4) != "_cut" /*
+                */ & "`hascon'"=="no" {
+                local rhsnm "`rhsnm' ``i''"
+            }
+            local i = `i' + 1
+        }
+        local nvar : word count `rhsnm'
+    } /* 050123 not zip */
+
+    *050123 if zip, have to count differently for case with no constant
+    if `iszi'==1 {
+        local nvar = e(df_m) /* # vars in count model */
+        local i = 1
+        while `i'<=`nvar' {
+            local rhsnm "`rhsnm' ``i''"
+            local ++i
+        }
+        local i = `i' + `ncon' /* if constant, skip it */
+        local rhsnm2 ""
+        local nvar2 = e(df_c) - 1 /* # vars in inf model */
+        while `i'<=`nvar'+`nvar2'+`ncon' {
+            local rhsnm2 "`rhsnm2' ``i''"
+            local ++i
+        }
+    } /* end of case for zip/zinb */
+
+    * specail case for mlogit
+    if "`e(cmd)'"=="mlogit" {
+        parse "`rhsnm'", parse(" ")
+        local rhsnm2 ""
+        local i 1
+        while `i' <= `nvar' {
+            local rhsnm2 "`rhsnm2' ``i''"
+            local i = `i' + 1
+        }
+        local rhsnm "`rhsnm2'"
+        local rhsnm2 ""
+    }
+
+    return local rhsnms  "`rhsnm'"
+    return local nrhs    "`nvar'"
+    return local rhsnms2  "`rhsnm2'"
+    return local nrhs2    "`nvar2'"
+
+end
diff --git a/Modules/ado/plus/_/_perhs.hlp b/Modules/ado/plus/_/_perhs.hlp
new file mode 100644
index 0000000..ab1db0d
--- /dev/null
+++ b/Modules/ado/plus/_/_perhs.hlp
@@ -0,0 +1,46 @@
+.-
+help for ^_perhs^ - 1.6.2 - 2/20/00
+.-
+
+Utility to determine names and number of right hand size variables
+in regression models
+------------------------------------------------------------------
+
+    ^_perhs^
+
+Description
+-----------
+
+^_perhs^ returns the number of right hand side variables and their names
+    for regression models.
+
+Works with regress, logit, probit, ologit, oprobit, mlogit, tobit,
+    zip, zinb, poisson, nbreg.
+
+Returns
+-------
+
+r(nrhs)  : local with number of rhs variables, excluding intercept.
+
+r(rhsnms): local with names of rhs variables.
+
+Examples within a program
+-------------------------
+
+    ...
+    _perhs
+    local nvars = `r(nrhs)' + 1
+    local varnms "`e(depvar)' `r(rhsnms)'"
+
+    local i = 1
+    while `i'<=`nvars' {
+        local nmtoget : word `i' of `varnms'
+        :::
+        local i=`i'+1
+    }
+
+.-
+Authors: J. Scott Long and Jeremy Freese
+         www.indiana.edu/~jslsoc/spost.htm
+         spostsup@@indiana.edu
+         
diff --git a/Modules/ado/plus/_/_pesum.ado b/Modules/ado/plus/_/_pesum.ado
new file mode 100644
index 0000000..3cfbb1f
--- /dev/null
+++ b/Modules/ado/plus/_/_pesum.ado
@@ -0,0 +1,87 @@
+*! version 1.6.2 1/6/01
+
+capture program drop _pesum
+program define _pesum, rclass
+    version 6.0
+    tempvar b tmp
+    syntax [fweight aweight pweight] [if] [in][,Median Dummy Two]
+
+* get weight info - if weight not specified in _pesum looks to see if estimation
+* was done with weights anyway - this way one can either have _pesum handle the
+* weights or let _pesum do it
+
+    local wtis "[`weight'`exp']"
+    if "`wtis'"=="" & "`e(wtype)'"!="" {
+        local weight "`e(wtype)'"
+        local wtis "[`e(wtype)'`e(wexp)']"
+    }
+    if "`weight'"=="pweight" {
+        local wtis "[aweight`e(wexp)']"
+        di in r "Warning: " in g "pweights are being treated as aweights to compute SDs"
+    }
+    if "`weight'"=="iweight" {
+        di in r "Error: command is incompatible with iweights."
+        exit
+    }
+
+* get names of variables
+    _perhs
+    local nvars = `r(nrhs)' + 1
+    local varnms "`e(depvar)' `r(rhsnms)'"
+    * get variables in 2nd eq for zip and zinb
+    if "`two'"=="two" {
+        local nvars = `r(nrhs2)' + 1
+        local varnms "`e(depvar)' `r(rhsnms2)'"
+    }
+    * intreg has two lhs vars; select only 1st one
+    if "`e(cmd)'"=="intreg" {
+        local nmtoget : word 1 of `varnms'
+        local varnms "`nmtoget' `r(rhsnms)'"
+    }
+
+* Matrices for results
+    tempname Smean Ssd Smin Smax Sdummy Smedian SN
+    mat `Smean' = J(1,`nvars',-99999)
+    mat colnames `Smean' = `varnms'
+    mat `Ssd' = `Smean'
+    mat `Smin' = `Smean'
+    mat `Smax' = `Smean'
+    mat `Sdummy' = `Smean'
+    mat `Smedian' = `Smean'
+
+* loop through variables
+    local i = 1
+    while `i'<=`nvars' {
+        local nmtoget : word `i' of `varnms'
+        quietly sum `nmtoget' `wtis' `if' `in'
+        scalar `SN' = r(N)
+        if `SN' == 0 {
+        * selection criteria left no observations
+            return scalar SN = `SN'
+            exit
+        }
+        mat `Smean'[1,`i'] = r(mean)
+        mat `Ssd'[1,`i'] = sqrt(r(Var))
+        mat `Smin'[1,`i'] = r(min)
+        mat `Smax'[1,`i'] = r(max)
+        if "`dummy'"=="dummy" {
+            * doesn't need weights. Won't change if is dummy
+            _pedum `nmtoget' `if' `in'
+            mat `Sdummy'[1,`i'] = r(dummy)
+        }
+        if "`median'"=="median" {
+            quietly _pctile `nmtoget' `if' `in' `wtis'
+            mat `Smedian'[1,`i'] = r(r1)
+        }
+        local i=`i'+1
+    }
+
+    return matrix Smean `Smean'
+    return matrix Ssd `Ssd'
+    return matrix Smin `Smin'
+    return matrix Smax `Smax'
+    return matrix Sdummy `Sdummy'
+    return matrix Smedian `Smedian'
+    return scalar SN = `SN'
+
+end
diff --git a/Modules/ado/plus/_/_pesum.hlp b/Modules/ado/plus/_/_pesum.hlp
new file mode 100644
index 0000000..13380a3
--- /dev/null
+++ b/Modules/ado/plus/_/_pesum.hlp
@@ -0,0 +1,66 @@
+.-
+help for ^_pesum^ - 1.6.1 - 1/20/00
+.-
+
+Utility to get descriptive statistics for variables in a regression model
+-------------------------------------------------------------------------
+
+    ^_pesum^ [^if^ exp] [^in^ range] [,^m^edian ^d^ummy ^t^wo]
+
+
+Description
+-----------
+
+^_pesum^ gets the mean, standard deviation, minimum and maximum for the
+    variables in a regression. Optionally, it determines the medians and
+    whether the variables are 0|1|. . Matrices are returned with the first
+    column containing statistics for the dependent variables, with the
+    remaining columns containing information for the independent variables.
+
+Note: ^_pesum^ assumes that ^_peife^ has been applied to the ^if^
+    condition.
+
+Options
+-------
+
+^median^ Return ^r(Smedian)^ with medians for the variables.
+
+^dummy^ Return ^r(Sdummy)^ with medians for the variables.
+
+^two^ Return summary statistics for the second equation in for ^zip^ and
+    ^zinb^ models.
+
+Returned Results
+----------------
+
+Matrices: Colums are in the order dependent variable, independent variables.
+
+    ^r(Smean)^          - means
+    ^r(Ssd)^            - standard deviations
+    ^r(Smin)^ & ^r(Smax)^ - minimums and maximums
+    ^r(Sdummy)^         - 1 if dummy variable, else 0; if ^dummy^ option
+                        is specified.
+    ^r(Smedian)^        - medians if ^median^ option is specified.
+
+Scalars:  ^r(SN)             - sample size
+
+Example with a Program
+-----------------------
+
+    if "`opt'"=="mean"|"`opt'"=="min"|"`opt'"=="max" {
+        _pesum `if' `in',`all'
+        mat pe_base = r(S`opt')
+    }
+    else if "`opt'"=="median" {
+        _pesum `if' `in',median `all'
+        mat pe_base = r(Smedian)
+    }
+
+Also see
+--------
+On-line: help for ^_peife^, ^_perhs^
+
+.-
+Authors: J. Scott Long and Jeremy Freese
+         www.indiana.edu/~jslsoc/spost.htm
+         spostsup@@indiana.edu
diff --git a/Modules/ado/plus/_/_petrap.ado b/Modules/ado/plus/_/_petrap.ado
new file mode 100644
index 0000000..2e0e9f9
--- /dev/null
+++ b/Modules/ado/plus/_/_petrap.ado
@@ -0,0 +1,79 @@
+*! 1.0.0 - 28 jun 2006
+
+/*
+
+cmd()    - name of command that should appear in error message  
+
+force    - ignore errors
+
+robust   - error if robust standard errors used
+cluster  - error if cluster() specified
+weight   - error if pweight, aweight, iweight specified
+pweight  - error if pweight specified
+aweight  - error if aweight specified
+iweight  - error if iweight specified
+
+*/
+
+program define _petrap
+
+    version 9
+
+    syntax [, cmd(string) Robust Cluster Weight PWeight AWeight IWeight SVY FORCE] 
+
+    if "`cmd'" == "" {
+        local cmd "program"
+    }
+
+    local vcetype = e(vcetype)
+    local clustvar = e(clustvar)
+    local wtype = e(wtype)
+    local ecmd = e(cmd)
+    local epredict = e(predict)
+    
+
+    * trap svy - possibly overkill for detecting if svy estimation performed but manuals obscure
+    * about info provided under version control
+    if ("`svyest'" == "svy_est" | substr("`ecmd'", 1, 3) == "svy" | substr("`epredict'", 1, 3) == "svy") ///
+         & "`svy'" != "" & "`force'" == "" {
+        di as err "`cmd' does not work with svy commands"
+    }    
+
+    * trap robust
+    if "`vcetype'" == "Robust" & "`robust'" != "" & "`force'" == "" {
+        di as err "`cmd' does not work with robust vcetype"
+        exit 999
+    } 
+
+    * trap cluster
+    if ("`clustvar'" != "." & "`clustvar'" != "") & "`cluster'" != "" & "`force'" == "" {
+        di as err "`cmd' does not work if cluster() specified"
+        exit 999
+    } 
+
+    * trap pweight, iweight, aweight
+    if ("`wtype'" == "pweight" | "`wtype'" == "aweight" | "`wtype'" == "iweight") & "`weight'" != "" & "`force'" == "" {
+        di as err "`cmd' does not work if `wtype' specified"
+        exit 999
+    } 
+
+    * trap pweight
+    if ("`wtype'" == "pweight") & "`pweight'" != "" & "`force'" == "" {
+        di as err "`cmd' does not work if `wtype' specified"
+        exit 999
+    } 
+
+    * trap aweight
+    if ("`wtype'" == "aweight") & "`aweight'" != "" & "`force'" == "" {
+        di as err "`cmd' does not work if `wtype' specified"
+        exit 999
+    } 
+
+    * trap iweight
+    if ("`wtype'" == "iweight") & "`iweight'" != "" & "`force'" == "" {
+        di as err "`cmd' does not work if `wtype' specified"
+        exit 999
+    } 
+
+
+end
diff --git a/Modules/ado/plus/_/_petrap.hlp b/Modules/ado/plus/_/_petrap.hlp
new file mode 100644
index 0000000..1cb739c
--- /dev/null
+++ b/Modules/ado/plus/_/_petrap.hlp
@@ -0,0 +1,42 @@
+.-
+help for ^_petrap^ - 28 Jun 2006
+.-
+
+Check to see if model estimation incompatible with postestimation command
+-------------------------------------------------------------------------
+
+    ^_petrap^ [,^cmd^(string) ^svy^ ^r^obust ^c^luster ^w^eight ^pw^eight
+         ^iw^eight ^aw^eight ^force^ ]
+
+
+Description
+-----------
+
+^_petrap^ produces an error message if the previous model estimated uses 
+    any of the specified options.  It is intended to use for trapping
+    errors in models incompatible with estimation command.
+
+Options
+-------
+
+^cmd()^ name of command that should appear in error message.  if not
+    specified, then "program" is used
+    
+^force^ will ignore conditions, and thus return with no errors
+
+^robust^ exits with error if robust standard errors used in estimated model
+
+^cluster^ exits with error if cluster() specified
+
+^weight^ exits with error if pweight, aweight, or iweight specified
+
+^pweight^ exits with error if pweight specified
+
+^aweight^ exits with error if aweight specified
+
+^iweight^ exits with error if iweight specified
+
+.-
+Authors: J. Scott Long and Jeremy Freese
+         www.indiana.edu/~jslsoc/spost.htm
+         spostsup@@indiana.edu
diff --git a/Modules/ado/plus/_/_peunvec.ado b/Modules/ado/plus/_/_peunvec.ado
new file mode 100644
index 0000000..895ffc4
--- /dev/null
+++ b/Modules/ado/plus/_/_peunvec.ado
@@ -0,0 +1,22 @@
+*! version 1.6.1 1/18/03
+
+capture program drop _peunvec
+program define _peunvec, rclass
+version 7
+    tempname oldbeta newbeta newrow
+    mat `oldbeta' = e(b)
+    _perhs
+    local cols = `r(nrhs)'+1
+    local rows = colsof(`oldbeta')/`cols'
+    local i = 1
+    while `i' <= `rows' {
+        local start = ((`i'-1) * `cols') + 1
+        local end = `start' + `cols' - 1
+        mat `newrow' = `oldbeta'[1, `start'..`end']
+        mat `newbeta' = nullmat(`newbeta') \ `newrow'
+        local i = `i' + 1
+    }
+    mat coleq `newbeta' = _
+    mat list `newbeta'
+    return matrix b `newbeta'
+end
diff --git a/Modules/ado/plus/_/_peunvec.hlp b/Modules/ado/plus/_/_peunvec.hlp
new file mode 100644
index 0000000..2d54780
--- /dev/null
+++ b/Modules/ado/plus/_/_peunvec.hlp
@@ -0,0 +1,17 @@
+.-
+help for ^_peunvec^
+.-
+
+    ^_peunvec^
+
+^_peunvec^ takes regression estimates that are kept as a vector (like ^mlogit^
+results in Stata 6) and transforms them to a matrix (like ^mlogit^ results in
+Stata 5).  
+
+The input is taken from e(b), and the new matrix is saved as r(b).  
+
+.-
+Authors: J. Scott Long and Jeremy Freese
+         www.indiana.edu/~jslsoc/spost.htm
+         spostsup@@indiana.edu
+         
diff --git a/Modules/ado/plus/_/_pexstring.ado b/Modules/ado/plus/_/_pexstring.ado
new file mode 100644
index 0000000..88428a8
--- /dev/null
+++ b/Modules/ado/plus/_/_pexstring.ado
@@ -0,0 +1,18 @@
+*! version 0.2.1 2005Jun20 - fix for long string jf
+*  version 0.2.0 2005-02-03
+
+//  change values in PE_in to string x(a=1 b=2..)
+
+capture program drop _pexstring
+program _pexstring, rclass
+    version 8
+    local cols = colsof(PE_in)
+    local xnames : colnames PE_in
+    local xis ""
+    foreach c of numlist  1/`cols'  {
+        local xnm : word `c' of `xnames'
+        local xval = PE_in[1,`c']
+        local xis "`xis' `xnm'=`xval'"
+    }
+    return local xis "`xis'"
+end
diff --git a/Modules/ado/plus/a/adoedit.ado b/Modules/ado/plus/a/adoedit.ado
new file mode 100644
index 0000000..2ed9712
--- /dev/null
+++ b/Modules/ado/plus/a/adoedit.ado
@@ -0,0 +1,77 @@
+
+*! Dan Blanchette 1.1 dan.blanchette@duke.edu 08Feb2005 
+*! Center of Entrepreneurship and Innovation Duke University's Fuqua School of Business
+** research computing, unc-ch
+* Stata fixed Linux problem of not being able to edit a file in a directory starting with "~"
+* Added "Caution" note when requesting to edit a Stata ado file.
+** Dan Blanchette 1.0.3 06 Nov 2003 made it work in Linux
+*! NJC 1.0.2 31 Dec 2002 
+** CFB 1.0.1 26Dec2002 cloned from adotype
+* NJC 1.2.1 1 December 1999
+** NJC 1.2.2 6 December 1999
+* NJC 1.2.3 14 December 1999 
+** AJM 1.3 5 August 2009   (Eliminated file size check for versions 11 and greater.)	
+
+program def adoedit, rclass
+        version 8.0
+
+
+	if "`1'" == "" | "`2'" != "" { 
+		di as err "incorrect syntax"
+		exit 198 
+	}
+	args cmd 
+
+	 /* ends with .ado */
+	if substr(`"`cmd'"',length(`"`cmd'"')-3,length(`"`cmd'"'))==".ado"  {   
+		local filen `"`cmd'"'
+	} 
+	else {
+           	local filen `"`cmd'.ado"'
+	} 
+
+	findfile `filen'
+
+	// here will exit 601 if `cmd' not found 
+	
+	local file `"`r(fn)'"' 
+
+        local tfile : subinstr local file "\" "/" , all
+
+        if index(`"`tfile'"',"/ado/base")  |  index(`"`tfile'"',"/ado/updates")  {
+          di " "
+          di as err "Caution, you are requesting to edit an ado file provided by Stata."
+          di as err "If this is really what you want, consider first copying the file to {input}`: sysdir PERSONAL' {error}."
+          di " "
+          more
+          di " "
+        }
+
+	capture hexdump `"`file'"', analyze
+	local size = r(filesize)
+	
+	* Eliminates file size check for versions 11 and greater.		
+	if c(stata_version) < 11 {
+
+		if `size' < 32000 & `size' > 0 {
+			doedit `"`file'"'
+			discard
+		return local adofile `"`file'"'
+		exit 0 
+			}
+		else {
+				di as txt _n "Sorry, files larger than 32,000 bytes cannot be do-edited."
+					di as txt "You must use another text editor for this file." 
+					error 603
+		} 
+	}
+			
+	else if c(stata_version) >= 11 {
+			doedit `"`file'"'
+			discard
+		return local adofile `"`file'"'
+		exit 0 
+		}
+
+end
+
diff --git a/Modules/ado/plus/a/adoedit.hlp b/Modules/ado/plus/a/adoedit.hlp
new file mode 100644
index 0000000..cb23827
--- /dev/null
+++ b/Modules/ado/plus/a/adoedit.hlp
@@ -0,0 +1,87 @@
+{smcl}
+{* 5Aug2009}{...}
+{* 17Jan2008}{...}
+{* 06Nov2003}{...}
+{hline}
+help for {hi:adoedit} {right:manual:  {hi:[R] none}}
+{right:dialog:  {hi: none}    }
+{hline}
+
+
+{title:Edit ado-file in Stata's do-file editor}
+
+{p 8 17 2}{cmd:adoedit} 
+{it:cmdname}
+{p_end}
+        
+{title:Description}
+
+{p 4 4 2}
+{cmd:adoedit} attempts to edit whichever ado-file named {cmd:cmdname.ado} is first on the
+current {help adopath:adopath}.  In Stata Version 10 and earlier, one cannot edit files 
+larger than 32,000 bytes in the do-file editor, nor can one edit built-in commands. 
+The file size limitation is removed for Stata Version 11 and later.
+
+{p 4 4 2}
+This routine is designed for use by those who are writing their own ado-files; 
+users are exhorted to make a copy of any official ado-files, and to save modified official 
+ado-files in the ado directory, rather than the Stata directory.{p_end}
+
+{p 4 4 2}
+{cmd:adoedit cmdname.ado}
+is tolerated.{p_end}
+
+{p 4 4 2}
+After a successful edit, the {cmd:discard} command is issued so that Stata will load the 
+revised ado-file. This will also clear any estimates from the last estimation.{p_end}
+
+{p 4 4 2}
+If you wish to edit ado-files with a different text editor, please see
+{stata findit fedit:fedit} and the {stata findit texteditors:texteditors} modules on the 
+{help ssc:SSC} archive.{p_end}
+
+
+{title:Examples}
+
+{p 4 8 2}{cmd:.  adoedit tsspell}{p_end}
+
+
+{title:Saved Results}
+
+{p 4 8 2}
+The {cmd:adoedit} command saves in {cmd:r()}:{p_end}
+ 
+{synoptset 20 tabbed}{...}
+{p2col 5 20 24 2: Macros}{p_end}
+{synopt:{cmd:r(adofile)}}the ado-file name and full path{p_end}
+
+
+{title:Author}
+
+{p 4 4 2}
+Dan Blanchette {break}
+Center of Entrepreneurship and Innovation {break}
+Duke University's Fuqua School of Business {break}
+Dan.Blanchette@Duke.edu{p_end}
+
+
+{title:Acknowledgements}
+
+{p 4 4 2}
+This program grew out of previous work by:{p_end}
+
+{p 6 4 2}
+Nicholas J. Cox, University of Durham, U.K.{p_end}
+
+{p 4 4 2}
+and{p_end}
+
+{p 6 4 2}
+Christopher F Baum, Boston College, USA{p_end}
+
+
+{title:Also see}
+
+{p 4 13 2}On-line: {help doedit:doedit} {help fildfile:findfile},
+{help fedit:fedit} (if installed){p_end}
+
diff --git a/Modules/ado/plus/a/alphlist.ado b/Modules/ado/plus/a/alphlist.ado
new file mode 100644
index 0000000..2f892b0
--- /dev/null
+++ b/Modules/ado/plus/a/alphlist.ado
@@ -0,0 +1,23 @@
+program def alphlist, rclass
+*! NJC 1.1.1 28 June 2001 
+* NJC 1.1.0 6 June 2000 
+* NJC 1.0.0 27 Jan 2000 
+	version 6.0 
+	syntax , [ Capitals Underscore Global(str) Noisily ]
+	
+	if length("`global'") > 8 { 
+		di in r "global name must be <=8 characters" 
+		exit 198 
+	} 	
+
+	if "`capitals'" != "" { 
+		local newlist "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z" 
+	} 	
+	else local newlist "a b c d e f g h i j k l m n o p q r s t u v w x y z" 
+
+	if "`underscore'" != "" { local newlist "`newlist' _" } 
+		
+	if "`noisily'" != "" { di "`newlist'" } 	
+	if "`global'" != "" { global `global' "`newlist'" } 
+	return local list `newlist' 
+end 	
diff --git a/Modules/ado/plus/a/alphlist.hlp b/Modules/ado/plus/a/alphlist.hlp
new file mode 100644
index 0000000..eacf780
--- /dev/null
+++ b/Modules/ado/plus/a/alphlist.hlp
@@ -0,0 +1,2 @@
+.h listutil
+
diff --git a/Modules/ado/plus/a/anaoption.ado b/Modules/ado/plus/a/anaoption.ado
new file mode 100644
index 0000000..46e436a
--- /dev/null
+++ b/Modules/ado/plus/a/anaoption.ado
@@ -0,0 +1,48 @@
+*! version 1  27may2007
+*! Jean-Benoit Hardouin
+*
+************************************************************************************************************
+* Stata program : anaoption
+*
+* Historic
+* Version 1 (2007-05-27): Jean-Benoit Hardouin
+*
+* Jean-benoit Hardouin, phD, Assistant Professor
+* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences
+* University of Nantes - Faculty of Pharmaceutical Sciences
+* France
+* jean-benoit.hardouin@anaqol.org
+*
+* News about this program :http://www.anaqol.org
+* FreeIRT Project website : http://www.freeirt.org
+*
+* Copyright 2007 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+************************************************************************************************************
+
+program define anaoption ,rclas
+version 7.0
+syntax [, DETails minvi(real .03) siglevel(real 0.05) minsize(real 0)]
+
+return scalar minvi=`minvi'
+return scalar siglevel=`siglevel'
+return scalar minsize=`minsize'
+return local details `details'
+
+
+end
+
diff --git a/Modules/ado/plus/a/asprvalue.ado b/Modules/ado/plus/a/asprvalue.ado
new file mode 100644
index 0000000..1b8f7ce
--- /dev/null
+++ b/Modules/ado/plus/a/asprvalue.ado
@@ -0,0 +1,697 @@
+*! 0.3.2 2009-03-14 | long freese | fix mean calculation
+
+** predictions for asmprobit
+
+capture program drop asprvalue
+capture program drop _Prvasmp
+program define asprvalue, rclass
+
+version 9
+
+    if e(cmd) == "asmprobit" {
+        _Prvasmp `0' // local program just for asmprobit -- see below
+        return add
+        exit
+    }
+
+    preserve
+
+    syntax [, x(passthru) Cat(string) Base(string) Save Diff Rest(string) BRief Full]
+
+    * need to sort to calculate means below so accurate for unbalanced panels
+    local idvar "`e(group)'"
+    tempname recordnum
+    sort `idvar', stable
+    by `idvar' : gen `recordnum' = _n
+
+    tempname b
+    mat `b' = e(b)
+    local allnames : colnames `b'
+
+    * check if there are any interactions, so that otherwise warning message can be specified
+    local anyX "no"
+
+    * make list of case-specific variables
+    foreach var of local allnames {
+        local i = index("`var'", "X")
+        if `i' != 0 {
+            local anyX "yes"
+        * is it an alternativeXcase-specific-variable interaction?
+            local temppreX = substr("`var'", 1, `i'-1)
+            local temppostX = substr("`var'", `i'+1, .)
+            * assume that preX are all cats -- TO DO: insert check?
+            local catslist "`catslist' `temppreX'"
+            local isAxA "no"
+            foreach var2 of local allnames {
+                if "`temppostX'"=="`var2'" | "`temppostX'"=="`base'" {
+                    local isAxA "yes"
+                    local aXalist "`aXalist' `var'"
+                }
+            }
+        * is it an alternativeXalternative interaction?
+            if "`isAxA'" == "no" {
+                local aXclist "`aXclist' `var'"
+                local csvlist "`csvlist' `temppostX'"
+            }
+        }
+    }
+
+
+    * if cat is specified, that is the list of categories
+    if "`cat'"!= "" {
+        local catslist = "`cat'"
+    }
+
+    * make sure either cat() or interactions specified
+    if "`cat'"=="" & "`anyX'"=="no" {
+        di as err "cat() must be specified if no interactions in model"
+        error 999
+    }
+
+    local catslist : list uniq catslist
+    local ncatsmin1 : word count `catslist'
+    local numcats = `ncatsmin1' + 1
+    local csvlist : list uniq csvlist
+
+    local asvlist : list allnames - aXclist
+    local asvlist : list asvlist - catslist
+    local asvlist : list asvlist - aXalist
+
+    /*
+    di "altXasv interactions: `aXalist'"
+    di "altXcase interactions: `aXclist'"
+    di "alternatives: `catslist'"
+    di "altspec vars: `asvlist'"
+    di "casespec vars: `csvlist'"
+    di "number of alternatives `ncatsmin1'"
+    */
+
+    * decode x() values
+    tokenize `x', parse("()")
+    local x "`3'"
+    local x : subinstr local x "=" " ", all
+    tokenize `x', parse(" ")
+    while "`1'" != "" & "`2'" != "" {
+
+        capture confirm number `3'
+        if _rc == 0 {
+            * TO DO: check that `1' is alternative-specific variables
+            forvalues i = 1(1)`numcats' {
+                local iplus1 = `i' + 1
+                confirm number ``iplus1''
+                local V`1'V`i' = ``iplus1''
+            }
+            macro shift `iplus1'
+        }
+
+        else {
+            local V`1' = `2'
+            macro shift 2
+        }
+    }
+
+    * HANDLE REST OPTION
+
+    * rest() = mean by default
+    if "`rest'" == "" {
+        local rest "mean"
+    }
+    *check that rest option includes an allowable option
+    if "`rest'" != "mean" & "`rest'" != "asmean" {
+        di as err "rest(`rest') not allowed"
+        error 999
+    }
+
+    foreach var of local csvlist {
+        if "`V`var''" == "" {
+            if "`rest'" == "mean" | "`rest'" == "asmean" {
+*                qui su `var' if e(sample) == 1 & `recordnum' == 1
+                qui su `var' if e(sample) == 1 // FIX TO MEAN CALCULATION 9/2012
+                local V`var' = r(mean)
+            }
+        }
+    }
+
+    foreach var of local asvlist {
+        if "`V`var''" == "" & "`V`var'V1'" == "" {
+            if "`rest'" == "mean" {
+*                qui su `var' if e(sample) == 1 & `recordnum' == 1
+                qui su `var' if e(sample) == 1 // FIX TO MEAN CALCULATION 9/2012
+                forvalues i = 1(1)`numcats' {
+                    local V`var'V`i' = r(mean)
+                }
+            }
+            if "`rest'" == "asmean" {
+                tempname refdum
+                * this variable will equal 1 for only those cases that indicate base
+                qui gen `refdum' = 1 if e(sample) == 1
+                local i = 1
+                foreach catname of local catslist {
+                    qui su `var' if `catname' == 1 & e(sample) == 1
+                    local V`var'V`i' = r(mean)
+                    * turn off refdum for variables indicating category
+                    qui replace `refdum' = 0 if `catname' == 1 & e(sample) == 1
+                    local i = `i' + 1
+                }
+                * use refdum to get mean for reference category
+                qui su `var' if `refdum' == 1 & e(sample) == 1
+                local V`var'V`i' = r(mean)
+            }
+        }
+    }
+
+    * add observations to bottom of dataset
+
+    local N = _N
+    local firstobs = `N' + 1 // firstobs is the reference number of the first added obs
+    local lastobs = `firstobs'+`ncatsmin1'
+
+    qui set obs `lastobs'
+    capture drop _addedobs
+    qui gen _addedobs = 1 if _n >= `firstobs'
+
+    * find unique value for new observations
+    local unique "no"
+    local i = 1234567
+    while "`unique'" == "no" {
+        qui count if `idvar' == `i'
+        if r(N) == 0 {
+            local unique "yes"
+        }
+        local i = `i' + 1234567
+    }
+    qui replace `idvar' = `i' in `firstobs'/`lastobs'
+    qui replace `idvar' = `i' in `firstobs'/`lastobs'
+
+    foreach cat of local catslist {
+        local obs = `firstobs'
+        foreach cat2 of local catslist {
+
+            * set dummy variables indicating which row is which alternative
+            qui replace `cat' = 1 in `obs' if "`cat'" == "`cat2'"
+            qui replace `cat' = 0 in `obs' if "`cat'" != "`cat2'"
+
+            * set values for aXc interactions
+            foreach csvar of local csvlist {
+                qui replace `cat'X`csvar' = `V`csvar'' in `obs' if "`cat'" == "`cat2'"
+                qui replace `cat'X`csvar' = 0 in `obs' if "`cat'" != "`cat2'"
+            }
+
+            local obs = `obs' + 1
+        }
+
+        * set all alternative dummies to zero for row indicating reference category
+        qui replace `cat' = 0 in `obs'
+
+        * set all aXc to zero for row corresponding to reference category
+        foreach csvar of local csvlist {
+            qui replace `cat'X`csvar' = 0 in `obs'
+        }
+
+    }
+
+    * set values for alternative-specific variables
+        foreach alt of local asvlist {
+            if "`V`alt''" != "" {
+                qui replace `alt' = `V`alt'' in `firstobs'/`lastobs'
+            }
+            else {
+                forvalues i = 1(1)`numcats' {
+                    local obs = `firstobs' + `i' - 1
+                    qui replace `alt' = `V`alt'V`i'' in `obs'
+                }
+            }
+        }
+
+    * set values for aXa interactions
+        foreach var of local aXalist {
+            local i = index("`var'", "X")
+            local temppreX = substr("`var'", 1, `i'-1)
+            local temppostX = substr("`var'", `i'+1, .)
+            qui replace `var' = `temppreX'*`temppostX' if _addedobs == 1
+        }
+
+    * generate predicted probabilities
+        tempname prob
+
+    * 5/26/06 WORKAROUND FOR STATA BUG (?!) WHERE PREDICT RESORTS DATA
+        tempname order
+        gen `order' = _n
+        qui predict `prob' if _addedobs == 1
+        sort `order'
+
+        * reference category name
+        if "`base'" == "" {
+            local base = "base"
+        }
+
+* DISPLAY RESULTS
+* heading
+
+        local ecmd "`e(cmd)'"
+        local edepvar "`e(depvar)'"
+        di _n as res "`ecmd'" as txt ": Predictions for " as res "`edepvar'"
+
+* display predicted probabilities
+
+    local obs = `firstobs'
+    capture mat drop asprvres
+    tempname tmpprob
+
+    foreach cat of local catslist {
+        sca `tmpprob' = `prob'[`obs']
+
+        mat asprvres = (nullmat(asprvres) \ `tmpprob')
+
+        local obs = `obs' + 1
+    }
+    sca `tmpprob' = `prob'[`obs']
+    mat asprvres = (nullmat(asprvres) \ `tmpprob')
+
+    mat rownames asprvres = `catslist' `base'
+    mat colnames asprvres = prob
+
+    if "`diff'" != "" {
+        mat changesav = asprvres - _ASPRVsav
+        tempname display
+        mat `display' = (asprvres, _ASPRVsav, changesav)
+        mat colnames `display' = Current Saved Diff
+        mat list `display', noh
+    }
+    else {
+        mat list asprvres, noh
+    }
+
+* display base values for case-specific variables
+
+    if "`csvlist'" != "" {
+        capture mat drop csvals
+        foreach var of local csvlist {
+            mat csvals = (nullmat(csvals) , `V`var'')
+        }
+        mat colnames csvals = `csvlist'
+        mat rownames csvals = x=
+
+        if "`brief'" == "" {
+            di _n as txt "case-specific variables"
+
+            if "`diff'" != "" {
+                mat changecsv = csvals - _ASPRVcsv
+                tempname displaycsv
+                mat `displaycsv' = (csvals \ _ASPRVcsv \ changecsv)
+                mat rownames `displaycsv' = Current Saved Diff
+                mat list `displaycsv', noh
+            }
+            else {
+                mat list csvals, noh
+            }
+        }
+
+    }
+
+* display base values for alternative-specific variables
+
+    if "`asvlist'" != "" {
+        capture mat drop asvals
+        foreach alt of local asvlist {
+        capture mat drop _tmp
+            if "`V`alt''" != "" {
+                mat _tmp = J(1, `numcats', `V`alt'')
+            }
+            else {
+                forvalues i = 1(1)`numcats' {
+                    mat _tmp = (nullmat(_tmp) , `V`alt'V`i'')
+                }
+            }
+            mat asvals = (nullmat(asvals) \ _tmp)
+        }
+        mat rownames asvals = `asvlist'
+        mat colnames asvals = `catslist' `base'
+
+        if "`brief'" == "" {
+            di _n as txt "alternative-specific variables"
+
+            if "`diff'" != "" {
+
+                tempname curasv
+                mat `curasv' = asvals
+
+                tempname savedasv
+                mat `savedasv' = _ASPRVasv
+                mat changeasv = asvals - `savedasv'
+
+                mat roweq `curasv' = Current
+                mat roweq `savedasv' = Saved
+                mat roweq changeasv = Dif
+
+                tempname displayasv
+                mat `displayasv' = (`curasv' \ `savedasv' \ changeasv)
+                mat list `displayasv', noh
+            }
+            else {
+                mat list asvals, noh
+            }
+        }
+    }
+
+* display all added observations and values if desired
+
+    if "`full'" != "" {
+        list `allnames' if _addedobs == 1, noobs
+    }
+
+    if "`save'" != "" {
+        mat _ASPRVsav = asprvres
+        if "`csvlist'" != "" {
+            mat _ASPRVcsv = csvals
+        }
+        if "`asvlist'" != "" {
+            mat _ASPRVasv = asvals
+        }
+    }
+
+* return results
+    if "`diff'" != "" {                                             //! added bj 24jul2008
+        capture return matrix p = changesav, copy                   //!
+        capture return matrix csv = changecsv, copy                 //!
+        capture return matrix asv = changeasv, copy                 //!
+    }                                                               //!
+    else {                                                          //!
+        capture return matrix p = asprvres, copy
+        capture return matrix csv = csvals, copy
+        capture return matrix asv = asvals, copy
+    }                                                               //!
+
+restore
+
+end
+
+program define _Prvasmp, rclass
+
+version 9
+
+preserve
+
+    syntax [, x(passthru) Cat(string) Base(string) Save Diff Rest(string) BRief Full]
+
+    if "`cat'" != "" {
+        di as err "(note: cat() ignored when using asprvalue with asmprobit)"
+    }
+    if "`base'" != "" {
+        di as err "(note: base() ignored when using asprvalue with asmprobit)"
+    }
+
+    local altvar = e(altvar)
+
+    local numcats = e(k_alt)
+    local asvlist "`e(indvars)'"
+    local csvlist "`e(ind2vars)'"
+    if "`csvlist'" == "" {
+        local csvlist "`e(casevars)'"
+    }
+    local idvar "`e(casevar)'"
+    if "`idvar'" == "" {
+        local idvar "`e(case)'"
+    }
+
+    * need to sort to calculate means below so accurate for unbalanced panels
+    tempname recordnum
+    sort `idvar', stable
+    by `idvar' : gen `recordnum' = _n
+
+
+    * add values to bottom of dataset
+
+    local N = _N
+    local firstobs = `N' + 1
+    local lastobs = `firstobs' + `numcats' - 1
+
+    qui set obs `lastobs'
+    capture drop _addedobs
+    qui gen _addedobs = 1 if _n >= `firstobs'
+
+    * find unique value for new observations
+    local unique "no"
+    local i = 1234567
+    while "`unique'" == "no" {
+        qui count if `idvar' == `i'
+        if r(N) == 0 {
+            local unique "yes"
+        }
+        local i = `i' + 1234567
+    }
+    qui replace `idvar' = `i' in `firstobs'/`lastobs'
+
+    * write values for alternative variable with values of alternatives
+    _pecats `altvar' if e(sample)
+
+    local catvals "`r(catvals)'"
+    forvalues i = 1(1)`numcats' {
+        local cat`i' : word `i' of `catvals'
+        local catslist "`catslist' `e(alt`i')'"
+
+        local obsnum = `firstobs' + `i' - 1
+        qui replace `altvar' = `cat`i'' in `obsnum'
+    }
+
+    * decode x() values
+    tokenize `x', parse("()")
+    local x "`3'"
+    local x : subinstr local x "=" " ", all
+    tokenize `x', parse(" ")
+    while "`1'" != "" & "`2'" != "" {
+
+        * if `3' exists and is a number, alternative-specific variables being specified
+        capture confirm number `3'
+        if _rc == 0 {
+            * TO DO: check that `1' is alternative-specific variable
+            forvalues i = 1(1)`numcats' {
+                local iplus1 = `i' + 1
+                confirm number ``iplus1''
+                local V`1'V`i' = ``iplus1''
+            }
+            macro shift `iplus1'
+        }
+
+        else {
+            local V`1' = `2'
+            macro shift 2
+        }
+    }
+
+    * HANDLE REST OPTION
+
+    * rest() = mean by default
+    if "`rest'" == "" {
+        local rest "mean"
+    }
+    *check that rest option includes an allowable option
+    if "`rest'" != "mean" & "`rest'" != "asmean" {
+        di as err "rest(`rest') not allowed"
+        error 999
+    }
+
+    foreach var of local csvlist {
+        if "`V`var''" == "" {
+            if "`rest'" == "mean" | "`rest'" == "asmean" {
+*                qui su `var' if e(sample) == 1 & `recordnum' == 1
+                qui su `var' if e(sample) == 1 // FIX TO MEAN CALCULATION 9/2012
+                local V`var' = r(mean)
+            }
+        }
+    }
+
+    foreach var of local asvlist {
+        if "`V`var''" == "" & "`V`var'V1'" == "" {
+            if "`rest'" == "mean" {
+*                qui su `var' if e(sample) == 1 & `recordnum' == 1
+                qui su `var' if e(sample) == 1 // FIX TO MEAN CALCULATION 9/2012
+                forvalues i = 1(1)`numcats' {
+                    local V`var'V`i' = r(mean)
+                }
+            }
+            if "`rest'" == "asmean" {
+                forvalues i = 1(1)`numcats' {
+                    qui su `var' if `altvar' == `cat`i'' & e(sample) == 1
+                    local V`var'V`i' = r(mean)
+                }
+            }
+        }
+    }
+
+    * set values for alternative-specific variables
+    foreach alt of local asvlist {
+        if "`V`alt''" != "" {
+            qui replace `alt' = `V`alt'' in `firstobs'/`lastobs'
+        }
+        else {
+            forvalues i = 1(1)`numcats' {
+                local obs = `firstobs' + `i' - 1
+                qui replace `alt' = `V`alt'V`i'' in `obs'
+            }
+        }
+    }
+
+    * set values for case-specific variables
+    foreach var of local csvlist {
+        qui replace `var' = `V`var'' in `firstobs'/`lastobs'
+    }
+
+    * generate predicted probabilities
+    tempname prob
+
+** 5/26/06 WORKAROUND FOR STATA BUG (?!) WHERE PREDICT RESORTS DATA
+    tempname order
+    gen `order' = _n
+    * 2008-06-15 list `order' if _addedobs == 1
+    qui predict `prob' if _addedobs == 1
+    sort `order'
+
+* DISPLAY RESULTS -- whole routine almost the same as asprvalue but not quite
+
+* heading
+
+    local ecmd "`e(cmd)'"
+    local edepvar "`e(depvar)'"
+    di _n as res "`ecmd'" as txt ": Predictions for " as res "`edepvar'"
+
+* display predicted probabilities
+
+    local obs = `firstobs'
+    capture mat drop asprvres
+    tempname tmpprob
+    foreach cat of local catslist {
+        sca `tmpprob' = `prob'[`obs']
+
+        mat asprvres = (nullmat(asprvres) \ `tmpprob')
+
+        local obs = `obs' + 1
+    }
+
+    mat rownames asprvres = `catslist'
+    mat colnames asprvres = prob
+
+    if "`diff'" != "" {
+        mat changesav = asprvres - _ASPRVsav
+        tempname display
+        mat `display' = (asprvres, _ASPRVsav, changesav)
+        mat colnames `display' = Current Saved Diff
+        mat list `display', noh
+    }
+    else {
+        mat list asprvres, noh
+    }
+
+* display base values for case-specific variables
+
+    if "`csvlist'" != "" {
+        capture mat drop csvals
+        foreach var of local csvlist {
+            mat csvals = (nullmat(csvals) , `V`var'')
+        }
+        mat colnames csvals = `csvlist'
+        mat rownames csvals = x=
+
+        if "`brief'" == "" {
+            di _n as txt "case-specific variables"
+
+            if "`diff'" != "" {
+                mat changecsv = csvals - _ASPRVcsv
+                tempname displaycsv
+                mat `displaycsv' = (csvals \ _ASPRVcsv \ changecsv)
+                mat rownames `displaycsv' = Current Saved Diff
+                mat list `displaycsv', noh
+            }
+            else {
+                mat list csvals, noh
+            }
+        }
+    }
+
+* display base values for alternative-specific variables
+
+    if "`asvlist'" != "" {
+        capture mat drop asvals
+        foreach alt of local asvlist {
+        capture mat drop _tmp
+            if "`V`alt''" != "" {
+                mat _tmp = J(1, `numcats', `V`alt'')
+            }
+            else {
+                forvalues i = 1(1)`numcats' {
+                    mat _tmp = (nullmat(_tmp) , `V`alt'V`i'')
+                }
+            }
+            mat asvals = (nullmat(asvals) \ _tmp)
+        }
+        mat rownames asvals = `asvlist'
+        mat colnames asvals = `catslist'
+
+        if "`brief'" == "" {
+            di _n as txt "alternative-specific variables"
+
+            if "`diff'" != "" {
+
+                tempname curasv
+                mat `curasv' = asvals
+
+                tempname savedasv
+                mat `savedasv' = _ASPRVasv
+                mat changeasv = asvals - `savedasv'
+
+                mat roweq `curasv' = Current
+                mat roweq `savedasv' = Saved
+                mat roweq changeasv = Dif
+
+                tempname displayasv
+                mat `displayasv' = (`curasv' \ `savedasv' \ changeasv)
+                mat list `displayasv', noh
+            }
+            else {
+                mat list asvals, noh
+            }
+        }
+    }
+
+* display all added observations and values if desired
+
+    if "`full'" != "" {
+        list `allnames' if _addedobs == 1, noobs
+    }
+
+    if "`save'" != "" {
+        mat _ASPRVsav = asprvres
+        if "`csvlist'" != "" {
+            mat _ASPRVcsv = csvals
+        }
+        if "`asvlist'" != "" {
+            mat _ASPRVasv = asvals
+        }
+    }
+
+* return results
+capture return matrix p = asprvres, copy
+capture return matrix csv = csvals, copy
+capture return matrix asv = asvals, copy
+
+restore
+
+end
+
+exit
+
+* 0.2.0 - jf - 5/26/06 - workaround for bug in Stata where predict resorts
+* 0.1.9 - jf - 12/19/05 - add returns
+* 0.1.8 - jf - 9/8/05 - warning but not error with cat() or base() with asmprobit
+* 0.1.7 - jf - 7/24/05 - fix asmean for asmprobit bug
+* 0.1.6 - jf - 7/19/05 - add heading to output
+* 0.1.5 - jf - 7/18/05 - bug fix
+* 0.1.4 - jf - 7/15/05 - add asmprobit (kludgy) - jf
+* 0.1.3 - jf - 7/15/05 - fix to allow = in x()
+* 0.1.2 - jf - 7/11/05 - bug fix
+* 0.1.1 - jf - 6/15/05 - change refcat() to base()
+* 0.1.0 - jf - 6/11/05
+* 0.2.1 - jf - 7/2/07 - fix for changes in stata 7 asmprobit routine
+* 0.3.0a - bj 24jul2008 for work with estout
+* 0.3.0 2008-06-15 jsl
+* 0.3.1 2009-03-14
diff --git a/Modules/ado/plus/a/asprvalue.hlp b/Modules/ado/plus/a/asprvalue.hlp
new file mode 100644
index 0000000..2b3a827
--- /dev/null
+++ b/Modules/ado/plus/a/asprvalue.hlp
@@ -0,0 +1,122 @@
+{smcl}
+{* 03Nov2005}{...}
+{hline}
+help for {hi:asprvalue}{right:03Nov2005}
+{hline}
+
+{title:Predicted probabilities for models with alternative-specific variables}
+
+{p 8 15 2}{cmd:asprvalue} [{cmd:,}
+{cmd:x(}{it:variables_and_values}{cmd:)}
+{cmdab:r:est(}{it:stat}{cmd:)}
+{cmdab:b:ase(}{it:refcatname}{cmd:)}
+{cmdab:c:at(}{it:catnames}{cmd:)}
+{cmdab:s:ave}
+{cmdab:d:iff}
+{cmdab:br:ief}
+
+{p 4 4 2}
+where {it:variables_and_values} is an alternating list of variables
+and numeric values
+
+{p 4 4 2}
+{it:stat} is either mean or asmean (alternative-specific means for alternative-specific variables)
+
+{p 4 4 2}
+{cmd:asprvalue} is intended to be used to compute predicted probabilities for logit or probit models
+that can combine case- and alternative-specific variables.  For these models, predicted probabilities
+depend on the values of the independent variables, which may or may not vary over the alternatives for
+a particular case.  {cmd:asprvalue} allows you to specify the values of the independent variables and
+presents predicted probabilities for the different alternatives.  The command presently works after
+{helpb clogit}, {helpb rologit}, or {helpb asmprobit}.
+
+{p 4 4 2}
+{cmd:IMPORTANT:} For {helpb clogit} and {helpb rologit} models, case-specific variables are specified
+by a set of interactions with dummy variables for the alternatives.  {cmd:asprvalue} can only be used
+if these interaction variables are named {it:alternative_name}X{it:case_specific_varname}.  In other
+words, if the dummy variables for the alternatives are named "car" and "bus" and a case-specific
+variable is "male", the interactions must be named "carXmale" and "busXmale".  These names for the
+interactions correspond with the names used if the data have been arranged for estimation using
+the command {cmd:case2choice}.  A capital "X" cannot be used in the names of any of the other
+variables in the model.
+
+{title:Options}
+
+{p 4 8 2}
+{cmd:save}  saves current values of indepenent variables and predictions
+for computing changes using the diff option.
+
+{p 4 8 2}
+{cmd:diff}  computes difference between current predictions and those
+that were saved.
+
+{p 4 8 2}
+{cmd:x()} sets the values of independent variables for calculating
+predicted values.  For case-specific variables, the list must alternate
+variable names and values.  For alternative-specific variables, the list
+may either be followed by a single value to be assigned to all alternatives
+or J values if there are J alternatives.  For {helpb clogit} or {helpb rologit}
+, when J values are specified, these
+are assigned to the alternatives in the order they have been specified by
+{cmd:cat()} or in the estimation command, with the value to be assigned to the
+reference category being last.  For {helpb asmprobit}, the different alternatives are specified
+using a single variable rather than a series of dummy variables, and values for
+alternative-specific variables should be ordered to correspond with the ascending
+values of the variable.
+
+
+{p 4 8 2}
+{cmd:rest()} sets the values for variables unspecified in {cmd:x()}.  The default
+is {it:mean}, which holds all unspecified variables to their case-specific means.
+One can also specific "asmean", which holds unspecified alternative-specific
+variables to their alternative-specific means.  For example, if "time" was an
+alternative-specific variable, {it:mean} would assign all alternatives the
+mean of "time" over all individuals and alternatives, while {it:asmean} would assign
+each alternative the mean of "time" for that alternative.
+
+{p 4 8 2}
+{cmd:base()} specifies the name of the base (reference) category.  If this is not
+specified, "base" will be used to refer to this category in the output.  This option
+should not be used after {helpb asmprobit}.
+
+{p 4 8 2}
+{cmd:cat()} specifies the names of the dummy variables in the model used to
+indicate different alternatives (the alternative-specific intercepts).  {cmd:cat()} only
+needs to be specified if the model includes no case-specific variables, as otherwise
+this list is inferred from the names of the interaction terms for case-specific
+variables.  The name of the reference category should not be included in {cmd:cat()}. This option
+should not be used after {helpb asmprobit}.
+
+{p 4 8 2}
+{cmd:brief} prints only limited output.
+
+{title:Examples}
+
+{p 4 4 2}
+{cmd:. use "http://www.stata-press.com/data/lfr/nomocc2.dta", clear}{break}
+{cmd:. gen busXhinc = bus*hinc}{break}
+{cmd:. gen trainXhinc = train*hinc}{break}
+{cmd:. gen busXpsize = bus*psize}{break}
+{cmd:. gen trainXpsize = train*psize}{break}
+{cmd:. clogit choice train* bus* time invc , group(id)}{break}
+{cmd:. asprvalue, x(time 600 invc 30 hinc 40 psize 0) base(car)}{break}
+
+{p 4 4 2}
+{cmd:. asprvalue, x(psize 0) base(car) save}{break}
+{cmd:. asprvalue, x(psize 1) base(car) dif}{break}
+
+{p 4 4 2}
+{cmd:. asprvalue, x(psize 0) base(car) rest(asmean) save}{break}
+{cmd:. asprvalue, x(psize 1) base(car) rest(asmean) dif}{break}
+
+{p 4 4 2}
+{cmd:. asprvalue, x(time 600 hinc 40 psize 1) base(car) save}{break}
+{cmd:. asprvalue, x(time 700 600 600 hinc 40 psize 1) base(car) dif}{break}
+{cmd:. asprvalue, x(time 600 700 600 hinc 40 psize 1) base(car) dif}{break}
+{cmd:. asprvalue, x(time 600 600 700 hinc 40 psize 1) base(car) dif}{break}
+
+{title:Authors}
+
+    Jeremy Freese and J. Scott Long
+    {browse www.indiana.edu/~jslsoc/spost.htm}
+    spostsup@indiana.edu
diff --git a/Modules/ado/plus/b/bagroup.ado b/Modules/ado/plus/b/bagroup.ado
new file mode 100644
index 0000000..b487941
--- /dev/null
+++ b/Modules/ado/plus/b/bagroup.ado
@@ -0,0 +1,220 @@
+*! bagroup.ado written 8/5/1997 by PTS version 1.2.2  (STB-55: sbe33)
+*! modified Bland-Altman plots for more than two measures
+*! one plot per figure
+*!
+*! Syntax: bagroup varlist if in, rows avlab difflab  obs_c
+
+
+* modified 3/8/1998 to allow for larger symbols if there are repetitions
+* modified 7/8/1998 to use all possible pairs, and to allow for ylines
+* modified 11/11/1998 to give n, means, sd of vars in table 
+* modified 2/2/2000 to accommodate xlab & ylab options & warn against xlab, ylab without options
+
+set trace off
+
+cap prog drop bagroup
+prog define bagroup
+	local varlist "req ex min(3)"
+	local if "opt"
+	local in "opt"
+	local options "format(str) rows(int 999) XLABel(str) YLABel(str) avlab(str) difflab(str) title(str) saving(str) obs(int 2) listwise text(real 100) *"
+
+	parse "`*'"
+	if index("`options'","xlab") ~= 0 | index("`options'","ylab") ~= 0 { 
+		di in red "xlabel and ylabel without values not permitted"
+		exit 198
+	}
+
+
+	tempvar touse
+	mark `touse' `if' `in'
+
+	local nvars : word count `varlist'
+	if "`listwise'" ~= "" {local obs = `nvars'}
+	cap assert `obs' >= 2 & `obs' <= `nvars'
+	if _rc { di in red "obs must be between 2 and the number of variables: " in ye `nvars' 
+		exit _rc}
+	tempvar obs_c
+	qui gen `obs_c' = 0
+	parse "`varlist'", parse(" ")
+	while "`1'" ~= "" {
+		qui replace `obs_c' = `obs_c' + (`1' ~= .)
+		mac shift
+		}
+
+	qui replace `touse' = 0 if `obs_c' < `obs'
+
+	if "`format'" == "" { local format "%5.2f" }
+
+	tempvar av diff 
+	qui egen `av' = rmean(`varlist') `if' `in'
+	qui gen `diff' = .
+	_table `varlist', av(`av') diff(`diff') touse(`touse') format(`format') obs_c(`obs_c')
+
+	if "`xlabel'" == "" { 
+		nicenum xlabel = $xmin $xmax
+		local xlabel "xlabel($xlabel)"
+		global xlabel 
+		}
+	else local xlabel "xlabel(`xlabel')"
+
+	if "`ylabel'" == "" { 
+		nicenum ylabel = $rrmin $rrmax
+		parse "$ylabel" , parse (",")
+		assert "`2'" == ","
+		if `1' > $rrmin { 
+			local ymin = 2*`1' - `3'
+			global ylabel "`ymin',$ylabel"
+		}
+		local ylabel "ylabel($ylabel)"
+		global ylabel 
+		}
+	else local ylabel "ylabel(`ylabel')"
+
+	if "`avlab'" ~= "" { local avlab avlab("`avlab'") }
+	if "`difflab'" ~= "" { local difflab difflab("`difflab'") }
+	if "`title'" ~= "" { local title title("`title'") }
+	if "`saving'" ~= "" { local saving saving(`saving') }
+
+	qui replace `diff' = .
+	cap noi _graph `varlist', av(`av') diff (`diff') touse(`touse') rows(`rows') /*
+*/ `xlabel' `ylabel' `avlab' `difflab' `saving' `title' `options' obs_c(`obs_c') text(`text')
+	if _rc {di in red "error in graph options"
+		exit _rc}
+
+	cap gph close
+
+end bagroup
+
+	
+prog define _table
+
+	local varlist "req ex "
+	local options "av(str) diff(str) touse(str) format(str) title(str) obs_c(str)"
+	parse "`*'"
+	di _n(2) in gr "Comparisons with the average of the other measures"
+	di _n in gr "Variable |     Obs   Mean      SD      Difference    Reference Range "
+	di in gr    "---------+----------------------------------------------------------"
+	parse "`varlist'", parse(" ")
+	while "`1'" ~ = "" {	
+
+		qui replace `diff' = (`1' - `av')* `obs_c'/(`obs_c'-1) if `touse'
+		qui summ `diff' if `touse'
+		local mean = _result(3)
+		local lrr = _result(3) - 2*_result(4)^.5
+		local urr = _result(3) + 2*_result(4)^.5
+
+		if "`rrmin'" == "" { local rrmin = `lrr' }
+		else if `lrr' < `rrmin' { local rrmin = `lrr' }
+		if "`rrmax'" == "" { local rrmax = `urr' }
+		else if `urr' > `rrmax' { local rrmax = `urr' }
+		
+* set trace on
+		summ `av' , mean
+		if "`xmin'" == "" { local xmin = _result(5) }
+		else if _result(5) < `xmin' { local xmin = _result(5) }
+		if "`xmax'" == "" { local xmax = _result(6) }
+		else if _result(6) > `xmax' { local xmax = _result(6) }
+		
+		qui corr `av' `diff' if `touse'
+		local r = _result(4)
+		local n = _result(1)
+		local sig = tprob(`n'-2, `r'*((`n'-2)/(1-`r'^2))^.5)
+		qui summ `1' if `touse'
+
+	#delim ;
+		di in gr "`1'" _col(10) "|" 
+                _col(12) in ye %7.0f `n' 
+		_col(22) `format' _result(3) 
+		_col(32) `format' _result(4)^.5
+		_col(40) `format' `mean' 
+		_col(54) `format' `lrr' in gr " to " in ye `format' `urr'; 
+	#delim cr
+		mac shift
+		}
+
+
+	global xmin = `xmin'
+	global xmax = `xmax'
+	global rrmin = `rrmin'
+	global rrmax = `rrmax'
+end _table
+
+
+prog define _graph
+	local varlist "req ex min(3)"
+	local options "av(str) diff(str) touse(str) rows(int 999) avlab(str) difflab(str) title(str) saving(str) obs_c(str) yline(str) text(real 100) *"
+
+	parse "`*'"
+	if "`yline'" ~= "" { local yline ",`yline'" }
+
+	if "`avlab'"  == "" {local avlab " " }
+	if "`difflab'"  == "" {local difflab " " }
+	if "`saving'" ~= "" { local saving saving(`saving') }
+
+	label var `av' "`avlab'"
+	label var `diff' "`difflab'"
+
+	local nvar: word count `varlist'
+	if "`rows'" == "999" { local rows = int(`nvar'^.5) }
+	local cols = int(`nvar' / `rows')
+	if `cols'*`rows' < `nvar' {
+		local cols = `cols' + 1 
+		}
+
+	local rlow = 0
+	local rmax = 23063
+	if "`title'" ~= "" {local rmax = 20000 }
+	local clow = 0
+	local cmax = 32000
+
+	local dr = `rmax'/`rows' - 100
+	local dc = `cmax'/`cols' - 100
+
+	cap noi gph open, `saving'
+	if "title" ~= "" {
+		gph pen 1
+		gph font 1000 500
+		gph text 22000 16000 0 0 `title'
+		}
+
+	parse "`varlist'", parse(" ")
+	while "`1'" ~ = "" {	
+
+		qui replace `diff' = (`1' - `av')* `obs_c'/(`obs_c'-1) if `touse'
+		qui summ `diff' if `touse'
+		local mean = _result(3)
+		local lrr = _result(3) - 2*_result(4)^.5
+		local urr = _result(3) + 2*_result(4)^.5
+		local rhigh = `rlow' + `dr'
+		local chigh = `clow' + `dc'
+
+		local lab1 : var label `1'
+		if "`lab1'" == "" { local lab1 "`1'" }
+		
+		sort `diff' `av' 
+		tempvar f n
+		qui by `diff' `av' : gen `f' = _N if `touse'
+		qui by `diff' `av' : gen `n' = _n if `touse'
+
+		local r_tx = int(400 * `text'/100)
+		local c_tx = int(200 * `text'/100)
+		
+
+	
+		#delim ;
+		cap noi graph `diff' `av' if `touse' & `n' == 1 [fw=`f'], s(o) `xlabel' `ylabel' yline(`lrr', `mean', `urr' `yline') 
+			`options' title("`lab1'")
+			bbox(`rlow', `clow', `rhigh', `chigh', `r_tx',`c_tx', 0);
+		#delim cr
+
+		local clow = `clow' + `dc'
+		if `clow' + `dc' > `cmax' { 
+			local clow = 0
+			local rlow = `rlow' + `dr'
+			}
+		mac shift
+		} 
+	gph close
+
+end _graph
diff --git a/Modules/ado/plus/b/bagroup.hlp b/Modules/ado/plus/b/bagroup.hlp
new file mode 100644
index 0000000..5cb943c
--- /dev/null
+++ b/Modules/ado/plus/b/bagroup.hlp
@@ -0,0 +1,60 @@
+.-
+help for ^bagroup^                                                (STB-55: sbe33)
+.-
+
+Modified Bland-Altman plots
+---------------------------
+
+        ^bagroup^ varlist [^if^ exp] [^in^ range] [^,^ ^format(^str^)^ ^rows(^#^)^
+                ^avlab(^str^)^ ^difflab(^str^)^ ^title(^str^)^ ^obs(^#^)^
+                ^listwise^ graph_options ]
+
+
+Description
+-----------
+
+^bagroup^ produces modified Bland-Altman plots.
+
+
+Options
+-------
+
+^format(^str^)^ sets the format for display of results.
+
+^rows(^#^)^ specifies the number of rows of graphs to be shown.
+
+^avlab(^str^)^ gives a variable label to the average before plotting the graph.
+
+^difflab(^str^)^ gives a variable label to the difference before plotting the
+    graph.
+
+^title(^str^)^ adds a single title to the block of graphs.
+
+^obs(^#^)^ specifies the minimum number of nonmissing values per observations 
+    needed for a point to be plotted.
+
+^listwise^ specifies listwise deletion of missing data.  Default is pairwise.
+    Only observations with no missing values are used.
+
+graph_options are any of the options allowed with ^graph, twoway^.
+
+
+Example
+-------
+
+ . ^use tan_part^
+ . ^bagroup pct_*^
+
+
+Author
+------
+        Paul Seed
+        GKT School of Medicine
+        King's London, UK
+        email: paul.seed@@kcl.ac.uk
+
+
+Also see
+--------
+
+    STB: STB-55 sbe33
diff --git a/Modules/ado/plus/b/bamat.ado b/Modules/ado/plus/b/bamat.ado
new file mode 100644
index 0000000..f9caac0
--- /dev/null
+++ b/Modules/ado/plus/b/bamat.ado
@@ -0,0 +1,300 @@
+*! bamat    Version 1.2.2 written 11 June 1997 by P T Seed (STB-55: sbe33)
+*!
+*! A matrix of Bland-Altman plots for a series of variables
+*! bamat varlist, graph_options
+
+* Amended 7 August 1998 to allow for saving graphs
+* 
+* Amended 3 May 2000 by arr@stata to suppress intermediary graphs and
+* display only the final matrix of Bland-Altman plots
+
+prog define bamat
+  version 5.0
+
+
+  local varlist "req ex min(3)"
+  local if "opt"
+  local in "opt"
+  local options "noTABle TItle(string) saving(string) data nograph markout FORmat(string) XLAbel(string) YLAbel(string) text(str) *"
+
+  parse "`*'"
+	if index("`options'","xlab") ~= 0 | index("`options'","ylab") ~= 0 { 
+		di in red "xlabel and ylabel without values not permitted"
+		exit 198
+	}
+
+  parse "`varlist'", parse(" ")
+
+  if "`table'" == "notable" & "`graph'" == "nograph" & "`data'" == "" {
+	di in red "Either table data or graph options must be chosen"
+	exit 194 }
+
+  preserve 
+  tempvar touse
+  mark `touse' `if'
+  if "`markout'" ~= "" {markout `touse' `varlist'}
+  if "`format'" == "" { local format "%6.3f" }
+  if "`saving'" ~= "" { local saving "saving(`saving')" }
+
+  if "`table'" ~= "notable" {
+	_table `varlist' if `touse', format(`format') `data'
+	}
+
+  if "`graph'" ~= "nograph" |"`data'" ~= "" {
+  	_limits `varlist' if `touse'
+	if "`xlabel'" == "" | "`xlabel'"  == "xlabel" { 
+  		_mynnum xlabel $xmin $xmax
+		local xlabel "xlabel($xlabel)" 
+		}
+	else {local xlabel "xlabel(`xlabel')" }
+  
+	if "`ylabel'" == "" { 
+  		_mynnum ylabel $ymin $ymax
+		local ylabel "ylabel($ylabel)" 
+		}
+	else {local ylabel "ylabel(`ylabel')" }
+
+        #delim ;
+        di _n  in gr "Range of x values is " in ye %6.0g $xmin in gr " to " in ye %6.0g $xmax 
+           in gr ", range of y values is " in ye %6.0g $ymin in gr " to " in ye %6.0g $ymax;
+        #delim cr
+	if "`title'" == "" {_graph `varlist' if `touse', `graph' `saving' `xlabel' `ylabel' `data' `options' }
+	else {_graph `varlist' if `touse', title("`title'") `graph' `saving' `xlabel' `ylabel' `data' `options' }
+	}
+end bamat
+
+prog define _table
+    local varlist "req ex" 
+    local if "opt"
+    local options "data format(str)"
+    parse "`*'"
+
+    tempvar touse
+    mark `touse' `if'
+
+    di in gr _new "Reference ranges for differences between two methods""
+    #delimit;
+    di in gr _new(2) "Method 1" _col(10) "Method 2" _col(20) "Mean" 
+    _col(30) "[95% Reference Range]"  
+    _col(54) "Minimum" _col(64) "Maximum" ;
+    #delimit cr
+    di in gr _dup(70) "-"
+
+    tempvar av diff
+    qui gen `av' = .
+    qui gen `diff' = .
+
+    local nvar : word count `varlist'
+    local i = 2
+    while `i' <= `nvar' {
+
+      local j = 1
+      while `j' < `i' {
+* di "i = |`i'|, j = |`j'|"
+          qui replace `diff' = ``i'' - ``j'' `if'  
+          label var `diff' " "
+          qui replace `av' = (``i'' + ``j'')/2 `if'
+          label var `av' " "
+          qui summ `diff' `if'
+          local mean = _result(3)
+          local lrr = `mean' - 2*_result(4)^.5
+          local urr = `mean' + 2*_result(4)^.5
+          local min = _result(5)
+          local max = _result(6)
+          di in gr "``i''" _col(10) "``j''" _col(20) in ye `format' `mean' /*
+*/ _col(30) `format' `lrr' _col(40) `format' `urr' _col(52) `format' `min' _col(62) `format' `max'
+	  local j = `j' +1
+	  }
+	local i = `i' + 1
+	}
+    di in gr _dup(70) "-"
+end _table
+
+
+prog define _data 
+	local av `1'
+	local diff `2'
+	local m1 `3'
+	local m2 `4'
+	di _n in gr _dup(40) "-"
+	di in gr  "Data for graph comparing `m1' and `m2'"
+	di in gr "Difference" _col(20) "Average"
+	di in gr _dup(40) "-"
+	local k = 1
+	while `k' <= _N { 
+	  if `av'[`k'] ~= . & `diff'[`k'] ~= . { di `diff'[`k'] _col(20) `av'[`k'] }
+	  local k = `k' + 1
+	  }
+  	di in gr _dup(40) "-" _n
+end _data
+	
+
+prog define _graph
+	local varlist "req ex"
+	local if "req"
+	local options "title(str) saving(str) xlabel(str) ylabel(str) nograph data *"
+
+	parse "`*'", 
+	if "`saving'" ~= "" { local saving "saving(`saving')" }
+
+	local nvar : word count `varlist'
+	tempvar diff av
+	qui gen `diff' = .
+	qui gen `av' = .
+	label var `diff' " "
+	label var `av' " "
+
+	local gonoff : set graphics
+	set graphics off
+	local i = 1
+	while `i' <= `nvar' {
+		local j = 1
+		while `j' <= `nvar' {
+			qui replace `diff' = ``i'' - ``j'' `if'
+			qui replace `av' = (``i'' + ``j'')/2 `if'
+			tempfile g`i'`j'	
+		       	local graph2 "`graph2' `i'`j'"
+		       	local graphs "`graphs' `g`i'`j''"
+		        if `i' == `j' & "`graph'" == "" { _namegr ``i'', saving(`g`i'`j'',  replace) }
+* set trace on
+			else if `i' ~= `j'{
+			  qui summ `diff'
+			  local mean = _result(3)
+			  local lrr = _result(3) - 2*_result(4)^.5
+			  local urr = _result(3) + 2*_result(4)^.5
+			  if "`graph'" == "" {
+				sort `diff' `av'
+* set trace off
+				tempvar f n 
+				qui by `diff' `av' : gen `f' = _N if `diff' ~= . & `av' ~= .
+				qui by `diff' `av' : gen `n' = _n if `diff' ~= . & `av' ~= .
+
+	    	      	  	qui graph `diff' `av' `if' & `n' == 1 [fw=`f'], xlabel(`xlabel')  /*
+*/ylabel(`ylabel') `options' saving(`g`i'`j'', replace) yline(`lrr', `mean', `urr') 
+				}
+			  if "`data'" ~= "" { _data `av' `diff' ``i'' ``j''}
+		          }
+			local j = `j' + 1
+        		}
+		local i = `i' + 1
+      		}
+	set graphics `gonoff'
+
+  if "`graph'" == "" { graph using `graphs', title("`title'") `saving' }
+end _graph
+               
+prog define _namegr
+  local varlist "req ex"
+  local options "saving(string)"
+  parse "`*'"
+
+  local f1 = 3000
+  local f2 = 1400
+
+
+  parse "`varlist'", parse (" ")
+  local lab1 : var label `1'
+  if "`lab1'" == "" { local lab1 "`1'" }
+
+  qui gph open, saving(`saving')
+  qui gph font `f1' `f2'
+  qui gph text 11188 16000 0 0 `lab1'
+  qui gph close
+end _namegr
+
+prog define _limits
+  local varlist "req ex"
+  local if "opt"
+  parse "`*'"
+  tempvar av diff
+
+  qui gen `diff' = `2' - `1'
+  qui gen `av' = (`2' + `1')/2
+  qui summ `av' `if'
+  global xmin = _result(5)
+  global xmax = _result(6)
+  qui summ `diff' `if'
+  global ymin = _result(5)
+  global ymax = _result(6)
+ 
+  local nvar : word count `varlist'
+  local i = 3
+  while `i' <= `nvar' {
+
+    local j = 1
+    while `j' < `i' {
+        qui replace `diff' = ``i'' - ``j'' `if'
+        qui replace `av' = (``i'' + ``j'')/2 `if'
+	qui summ `av' `if'
+	if _result(5) < $xmin {	global xmin = _result(5) }
+	if _result(6) > $xmax { global xmax = _result(6) }
+        qui summ `diff' `if'
+	if _result(5) < $ymin { global ymin = _result(5) }
+	if _result(6) > $ymax { global ymax = _result(6) }
+	local j = `j' + 1
+	}
+     local i = `i' + 1
+     }
+     if $ymax + $ymin > 0 { global ymin = -$ymax }
+     else { global ymax = -$ymin }
+end _limits
+
+prog define _mynnum
+*! _mynnum		Version 1.00 20/3/1997 PTS
+*! a version of nicenum to handle numbers less than 1
+*! usage: _mynnum global_macro minimum maximum mumber_of_ticks
+  version 5.0
+  local macro "`1'"
+  if `2' ~= `3' { 
+	if `2' < `3' {
+		local min `2'
+		local max `3'
+		}
+	else { 
+		local min `3'
+	  	local max `2'
+		}
+	}
+  else  {
+     di in red "Numbers do not differ"
+     exit  198
+     }
+  local nticks `4'
+  if "`nticks'" == "" { local nticks = 5 }
+  else { cap confirm integer `nticks'
+         assert `nticks' > 2
+         if _rc ~= 0 {
+            di in red "Number of ticks requested must be at least 2"
+            exit 198
+            }
+	}
+
+  local gap = 10^(int(log10(`max' - `min'))-1)
+
+  local nt = int((`max' - `min' )/`gap') + 1
+  while `nt' < `nticks' { 
+	local gap = `gap'/10
+  	local nt = int((`max' - `min' )/`gap') + 1
+	}
+
+  if `nt' > `nticks' - 1 { 
+	local gap = `gap' * 2 
+  	local nt = int((`max' - `min' )/`gap') + 1
+	}
+  if `nt' > `nticks' - 1 { 
+	local gap = `gap' * 2.5
+	}
+  if `nt' > `nticks' - 1 { 
+	local gap = `gap' * 2
+	}
+
+
+  local tick = `gap'*int(`min'/`gap')
+  while `tick' > `min' { local tick = `tick' - `gap' }
+  global `macro' "`tick'"
+  while `tick' < `max' {
+	local tick = `tick' + `gap'
+	global `macro' "$`macro', `tick'"
+	}
+
+end _mynnum
diff --git a/Modules/ado/plus/b/bamat.hlp b/Modules/ado/plus/b/bamat.hlp
new file mode 100644
index 0000000..db58d36
--- /dev/null
+++ b/Modules/ado/plus/b/bamat.hlp
@@ -0,0 +1,64 @@
+.-
+help for ^bamat^                                                  (STB-55: sbe33)
+.-
+
+Multiple Bland-Altman plots
+---------------------------
+
+        ^bamat^ varlist [^if^ exp] [^in^ range] [^, for^mat^(^str^)^ ^notable^
+                ^data^ ^avlab(^str^)^ ^difflab(^str^)^ ^obs(^#^)^
+                ^listwise^ ^ti^tle^(^str^)^ graph_options ]
+
+
+Description
+-----------
+
+^bamat^ produces a matrix of Bland-Altman plots for all possible pairs of 
+variables.
+
+
+Options
+-------
+
+^format(^str^)^ 
+sets the format for display of results.
+
+^notable^ suppresses display of results data list data used in plotting 
+    each graph.
+
+^avlab(^str^)^ gives a variable label to the average before plotting the graph.
+
+^difflab(^str^)^ gives a variable label to the difference before plotting 
+    the graph.
+
+^obs(^#^)^ specifies the minimum number of nonmissing values per observations 
+    needed for a point to be plotted. The default value is 2.
+
+^listwise^ specifies listwise deletion of missing data.  Default is
+    pairwise.  Only observations with no missing values are used.
+
+^title(^str^)^ adds a single title to the block of graphs.
+
+graph_options are any of the options allowed with ^graph, twoway^.
+
+
+Example
+-------
+ 
+   . ^use tan_part^
+   . ^bamat pct_*^
+
+
+Author
+------
+        Paul Seed
+        GKT School of Medicine
+        King's London, UK
+        email: paul.seed@@kcl.ac.uk
+
+
+Also see
+--------
+
+    STB: STB-55 sbe33
+
diff --git a/Modules/ado/plus/b/baplot.ado b/Modules/ado/plus/b/baplot.ado
new file mode 100644
index 0000000..5b12935
--- /dev/null
+++ b/Modules/ado/plus/b/baplot.ado
@@ -0,0 +1,218 @@
+*! baplot.ado version 1.21 written by PTS (p.seed@umds.ac.uk) (STB-55: sbe33)
+*! Produces Bland-Altman plots for two variables
+*! See Bland & Altman Lancet Feb 8 1986, pp 307-310
+*!
+*! syntax: baplot var1 var2 if in, symbol(symbol) format(%6.3f) avlab("Average") difflab("Difference") yline(str) textsize(#) other graph options 
+
+* Now allows choice of symbol, and extra ylines Feb 8 1996
+* larger plotting symbols for overlapping points
+* Silly comparisons taken out
+
+
+cap prog drop baplot
+prog define baplot
+version 6.0
+
+* set trace off
+
+	syntax varlist(min=2 max=2 numeric) [if] [in], /*
+*/ [Symbol(string) format(string) avlab(string) difflab(string) /*
+*/ novars noGRaph ci zero mean yline(string) diag saving(string) /*
+*/ text(real 100) ratio(real 1) *]"
+
+	parse "`varlist'", parse(" ")
+	local m1 "`1'"
+	local m2 "`2'"
+
+	if "`symbol'" == "" { local symbol "o" }
+	if "`format'" == "" {local format "%6.3f" }
+	if "`saving'" ~= "" { local saving "saving(`saving')"}
+	if "`ci'" ~= "" {local mean = "mean" }
+
+
+	preserve
+	tempvar touse
+	mark `touse' `if' `in'
+	markout `touse' `m1' `m2'
+	qui keep if `touse'
+
+	tempvar av diff 
+	if "`avlab'" == "" { local avlab "Average"}
+	if lower("`avlab'") == "nolab" { local avlab " "}
+
+	if "`difflab'" == "" { local difflab "Difference" }
+	if lower("`difflab'") == "nolab" { local difflab " "}
+	qui gen `av' = (`m1' + `m2')/2 
+	qui gen `diff' = `m1' - `m2' 
+	label var `av' "`avlab'"
+	label var `diff' "`difflab'"
+
+	qui summ `diff' if `touse'
+	local xbar = _result(3)
+	local sd = _result(4)^.5
+	local n = _result(2)
+	local se = `sd'/`n'^.5
+	local t = invt(_result(2)-1, .95)
+	local lrr = `xbar' - 2*`sd'
+	local urr = `xbar' + 2*`sd'
+	local min = _result(5)
+	local max = _result(6)
+	local lcb = `xbar' - `t'*`se'
+	local ucb = `xbar' + `t'*`se'
+
+	summ `av', meanonly
+	local xmin = _result(5)
+	local xmax = _result(6)
+
+	local yline "`lrr', `urr'"
+	if "`ci'" ~= "" {
+		local yline "`yline', `lcb', `ucb'"
+		}
+	if "`mean'" ~= "" | "`zero'" == "" {local yline "`yline', `xbar'"}
+	if "`zero'" ~= "" {local yline "`yline', 0"}
+
+	qui corr `av' `diff'
+	local r = _result(4)
+	local n = _result(1)
+	local sig = tprob(`n'-2, `r'*((`n'-2)/(1-`r'^2))^.5)
+
+
+	#delim ;
+	di in gr _n "Bland-Altman comparison of `m1' and `m2'";
+	di in gr "Limits of agreement (Reference Range for difference): " in ye  `format' `lrr' 
+		in gr " to " in ye `format' `urr' ;
+	di in gr "Mean difference: " in ye `format' `xbar' 
+		in gr " (CI " in ye `format' `lcb' 
+		in gr " to " in ye `format' `ucb' 
+		in gr ") ";
+	di in gr "Range : " in ye  `format' `xmin'
+		in gr " to " in ye `format' `xmax';
+	di in gr "Pitman's Test of difference in variance: r = " in ye `format' `r' 
+		in gr ", n = " in ye `n' 
+		in gr ", p =" in ye `format' `sig' ;
+	#delim cr
+
+	if "`vars'" ~= "" {
+		qui corr `m1' `m2', cov
+		local tau = _result(4)
+		qui summ `m1'
+		local err1 = _result(4) - `tau' 
+		qui summ `m2'
+		local err2 = _result(4) - `tau' 
+		di in gr "Estimated variance of true measure: " in ye `format' `tau'
+		di in gr "Estimated error variance (`1'): " in ye `format' `err1'
+		di in gr "Estimated error variance (`2'): " in ye `format' `err2'
+		di in gr "Very low or negative error variances may indiate that modelling assumptions are violated."
+		}
+
+	global S_1 `xbar'
+	global S_2 `lrr'
+	global S_3 `urr'
+
+	if "`graph'" == "" & "`diag'" == "" { 
+		sort `diff' `av'
+		tempvar f n
+		qui by `diff' `av': gen `f' = _N if `diff' ~= . & `av' ~= .
+		qui by `diff' `av': gen `n' = _n if `diff' ~= . & `av' ~= .
+		graph `diff' `av' if `touse' & `n' == 1 [fw=`f'], symbol(`symbol') `xlabel' `ylabel' yline(`yline') `saving' `options'
+		}
+
+	else if "`diag'" ~= "" {
+
+		local nobs = _N + 1 	
+		qui set obs `nobs'
+		qui replace `m2' = 0 if `m2' == .
+
+* loa		
+			tempvar lb ub
+			qui gen `ub' = `m2' + `xbar' + 2*`sd'
+			qui replace `ub' = . if `ub' < 0
+			summ `ub', mean
+			qui replace `ub' = . if `ub' > _result(5) & `ub' < _result(6)
+
+			qui gen `lb' = `m2' + `xbar' - 2*`sd'
+			summ `lb', mean
+			if _result(5) < 0 {
+				qui replace `lb' = . if `lb' < 0 
+				local nobs = _N + 1 	
+				qui set obs `nobs'
+				qui replace `lb' = 0 if _n == _N
+				qui replace `m2' = 2*`sd' - `xbar' if _n == _N
+				}
+			summ `lb', mean
+			qui replace `lb' = . if `lb' > _result(5) & `lb' < _result(6)
+
+* ci
+			if "`ci'" ~= "" {
+				tempvar lci uci
+				qui gen `lci' = `m2' + `xbar' - invt(`n'-1,0.95)*`sd'/`n'^.5
+				qui gen `uci' = `m2' + `xbar' + invt(`n'-1,0.95)*`sd'/`n'^.5
+				summ `lci', mean
+				if _result(5) < 0 {
+					qui replace `lci' = . if `lci' < 0 
+ 					local nobs = _N + 1 	
+					qui set obs `nobs'
+					qui replace `lci' = 0 if _n == _N
+					qui replace `m2' = invt(`n'-1,0.95)*`sd'/`n'^.5 - `xbar' if _n == _N
+					}
+				summ `uci', mean
+				if _result(5) < 0 {
+					qui replace `uci' = . if `uci' < 0 
+					local nobs = _N + 1 	
+					qui set obs `nobs'
+					qui replace `uci' = 0 if _n == _N
+					qui replace `m2' = - invt(`n'-1,0.95)*`sd'/`n'^.5 - `xbar' if _n == _N
+					}
+				summ `lci', mean
+				qui replace `lci' = . if `lci' > _result(5) & `lci' < _result(6)
+				summ `uci', mean
+				qui replace `uci' = . if `uci' > _result(5) & `lci' < _result(6)
+				}
+
+			summ `m2' if `m2' ~= ., mean
+			tempvar diag
+
+* zero
+			if "`zero'"  ~= "" | "`mean'" == "" {
+				qui gen `diag' = `m2' if `m2' == _result(5) | `m2' == _result(6)
+				}
+
+* mean
+			else {
+				qui gen `diag' = `m2' + `xbar' if `m2' == _result(5) | `m2' == _result(6)
+				summ `diag', mean
+				if _result(5) < 0 {
+					qui replace `diag' = . if `diag' < 0 
+					local nobs = _N + 1 	
+					qui set obs `nobs'
+					qui replace `diag' = 0 if _n == _N
+					qui replace `m2' =  - `xbar' if _n == _N
+					}
+				}
+
+			sort `m1' `m2'
+			tempvar f n
+			qui by `m1' `m2': gen `f' = _N
+			qui by `m1' `m2': gen `n' = _n
+
+			if ("`xlabel'" == "" | "`ylabel'" == "") & index("`options'","xlab") == 0 &  index("`options'","ylab") == 0  {
+				nicenum labels = 0 `m1' `m2'
+				local xlabel xlab($labels) 
+				local ylabel ylab($labels) 
+				}
+
+		local r_tx = int(923 * `text'/100)
+		local c_tx = int(444 * `text'/100)
+		local c_min = int(16000 - (23063*`ratio'/2))
+		local c_max = int(16000 + (23063*`ratio'/2))
+di "bbox(0,`c_min',23063,`c_max',`r_tx',`c_tx',0) "
+		
+		gph open, `saving'
+		graph `m1' `diag' `ub' `lb' `lci' `uci' `m2' if `n' == 1 [fw=`f'], /*
+*/ `xlabel' `ylabel' s(oiiiii) c(.lllll) sort /*
+*/ bbox(0,`c_min',23063,`c_max',`r_tx',`c_tx',0) `options'
+		gph close
+		}
+
+end
+exit
diff --git a/Modules/ado/plus/b/baplot.hlp b/Modules/ado/plus/b/baplot.hlp
new file mode 100644
index 0000000..3797975
--- /dev/null
+++ b/Modules/ado/plus/b/baplot.hlp
@@ -0,0 +1,51 @@
+.-
+help for ^baplot^                                                 (STB-55: sbe33)
+.-
+
+Bland-Altman plots
+------------------
+
+        ^baplot^ varname1 varname2 [^if^ exp] [^in^ range] [^, format(^str^)^ 
+              ^avlab(^str^) difflab(^str^)^ graph_options]
+
+
+Description
+-----------
+
+^baplot^ produces Bland-Altman plots, that is, plots of the difference of
+paired variables versus their average.
+
+
+Options
+-------
+
+^format(^str^)^ sets the format for the results given.
+
+^avlab(^str^)^ gives a variable label to the average before plotting the graph.
+
+^difflab(^str^)^  gives a variable label to the difference before plotting the
+    graph.
+
+graph_options are any of the options allowed with ^graph, twoway^.
+
+
+Examples
+--------
+
+ . ^use col_icp^
+ . ^baplot icp colorime, avlab("ICPOES vs Colorimetry)^
+
+
+Author
+------
+        Paul Seed
+        GKT School of Medicine
+        King's London, UK
+        email: paul.seed@@kcl.ac.uk
+
+
+Also see
+--------
+
+    STB: STB-55 sbe33
+
diff --git a/Modules/ado/plus/b/batplot.ado b/Modules/ado/plus/b/batplot.ado
new file mode 100644
index 0000000..19f8e2e
--- /dev/null
+++ b/Modules/ado/plus/b/batplot.ado
@@ -0,0 +1,269 @@
+*! Date        : 19 May 2009
+*! Version     : 1.12
+*! Authors     : Adrian Mander
+*! Email       : adrian.mander@mrc-bsu.cam.ac.uk
+*! Description : Bland-Altman plots with trend adjustment
+
+/*
+17/5/06   v1.3  add-in the middle line
+6/10/06   v1.4  Handle multiple data points at the same point by using frequency option
+                Also add Scatter option just to add options to the scatter part of the plot
+2/9/07    v1.5  Changed version from 8 to 9.2
+11/12/07  v1.6  Extended the shaded area
+14/12/07  v1.7  Add limits of agreement into the info option
+11/2/08   v1.8  BUGs fixed and extended the shading to the xlimits
+17/4/08   v1.9  BUG fix.. the info limits were the wrong way round!
+9/5/08    v1.10 Allowing shading to extend beyond data to any limit you like
+11/5/08   v1.11 Added the range to be displayed for the averages
+19/5/2009 v1.12 Changed email address
+11/6/12   v1.13	Added extra option for titles and number of decimal places in display
+*/
+
+prog def batplot, rclass
+version 9.2
+syntax varlist (min=2 max=2) [if] [in] [,NOtrend INFO VALabel(varname) MOPTIONS(string asis) XLABel(numlist) SHADING(numlist min=2 max=2) SCatter(string asis) NOGraph DP(int 2) *]
+local gopt "`options'"
+
+if "`moptions'"~="" local mopt `"moptions(`moptions')"'
+
+preserve
+tempvar touse
+mark `touse' `if' `in'
+markout `touse' `m1' `m2'
+qui keep if `touse'
+
+if "`xlabel'"~="" {
+  local glab `"xlabel(`xlabel')"'
+  local i 0
+  foreach xv of local xlabel {
+    if `i++'==0 local sxmin "`xv'"
+    local sxmax "`xv'"
+  }
+  local shade "shade(`sxmin' `sxmax')"
+}
+
+/* To stop the shading going the whole length of the x-axis */
+if "`shading'"~="" {
+  local i 0
+  foreach s of local shading {
+    if `i++'==0 local smin "`s'"
+    else local smax "`s'"
+  }
+  if `smin'<`smax' local shade "shade(`smin' `smax')"
+  else local shade "shade(`smax' `smin')"
+}
+
+
+/* NOW do the trend version */
+
+if "`valabel'"~="" local add "val(`valabel')"
+
+_calctrend `varlist', `gopt' `notrend' `info' `add' `mopt' sc(`scatter') `glab' `shade' `nograph' dp(`dp')
+
+
+  return local mean = "`r(mean)'"
+  return local b0 = "`r(b0)'"
+  return local b1 = "`r(b1)'"
+  return local c0 = "`r(c0)'"
+  return local c1 = "`r(c1)'"
+  return local eqn = "`r(eqn)'"
+  return local upper = "`r(upper)'"
+  return local lower = "`r(lower)'"
+
+restore
+end
+
+
+/* calculate trend and do a BA plot with trend */
+
+prog def _calctrend,rclass
+syntax [varlist] [,NOTREND INFO VALabel(varname) MOPTIONS(string asis) SCatter(string asis) shade(numlist) NOGraph DP(int 2) *]
+local xopt "`options'"
+
+if "`shade'"~="" {
+  local i 0
+  foreach s of local shade {
+    if `i++'==0 local a "`s'"
+    local b "`s'"
+  }
+  local sxmin = `a'
+  local sxmax = `b'
+}
+
+local i 1
+foreach var of varlist `varlist' {
+  local v`i++' "`var'"
+}
+
+tempvar av diff
+
+qui gen `av' = (`v1' + `v2')/2 
+qui gen `diff' = `v1' - `v2'
+local ytit "Difference (`v1'-`v2')"
+local xtit "Average of `v1' and `v2'"
+
+lab var `diff' "Diff"
+lab var `av' "Mean"
+
+if "`notrend'"~="" {
+  qui summ `diff'
+  local xbar = `r(mean)'
+  local sd = `r(Var)'^.5
+  local n = `r(N)'
+  local se = `sd'/`n'^.5
+  local t = invttail(`n'-1, .95)
+  local lrr = `xbar' - invnorm(0.975)*`sd'  /* 95% lower limit of agreement */
+  local urr = `xbar' + invnorm(0.975)*`sd'  /* 95% upper limit of agreement */
+  local mrr = `xbar'                        /* 95% mean agreement */
+
+  di "{text}Mean difference     = {res}`mrr'"
+  di "{text}Limits of agreement = ({res}`lrr'{text},{res}`urr'{text})"
+
+  local min = `r(min)'
+  local max = `r(max)'
+  local lcb = `xbar' - `t'*`se'
+  local ucb = `xbar' + `t'*`se'
+  qui summ `av'
+  local xmin = `r(min)'
+  local xmax = `r(max)'
+  local a : di %5.3f `xmin'
+  local b : di %5.3f `xmax'
+  local range = "Averages lie between `a' and `b'"
+  di "{text}Averages lie between {res} `a' {text}and {res}`b'"
+  qui corr `av' `diff'
+  local r = `r(rho)'
+  local n = `r(N)'
+  local sig = ttail(`n'-2, `r'*((`n'-2)/(1-`r'^2))^.5)
+
+  tempvar uy ly my
+
+/* The bit to extend the shade */
+
+  local obs =`c(N)'+2
+  qui set obs `obs'
+  if "`sxmin'"~="" qui replace `av'=`sxmin' in `obs--'
+  if "`sxmax'"~="" qui replace `av'=`sxmax' in `obs'
+
+  qui gen `uy' = `urr'
+  qui gen `ly' = `lrr'
+  qui gen `my' = `mrr'
+
+  sort `av'
+
+  if "`info'"~="" {
+    local te1:di %6.3f `mrr'
+    local te2:di %6.3f `lrr'
+    local te3:di %6.3f `urr'
+
+    qui count if (`diff'>`urr' | `diff'<`lrr' ) & `diff'~=.
+    local nout = `r(N)'
+    qui count if `diff'~=.
+    local n = `r(N)'
+    local pctout : di %6.2f `nout'/`n'*100
+    local xopt `"`xopt' subtitle("`nout'/`n' = `pctout'% outside the limits of agreement" "Mean difference `te1'" "95% limits of agreement (`te2',`te3')" "`range'") "'
+  }
+  if "`valabel'"~="" {
+    tempvar label
+    qui gen `label' = ""
+    cap confirm string variable `valabel'
+    if _rc~=0 qui replace `label' = string(`valabel') if `diff'>`urr' | `diff'<`lrr'
+    else qui replace `label' = `valabel' if `diff'>`urr' | `diff'<`lrr'
+    local scatteropt "mlabel(`label') note(Points outside limits labelled by `valabel')"
+  }
+
+  tempvar freq
+  qui bysort `diff' `av':gen  `freq'=_N
+  local fopt "[fw=`freq']"
+  if index("`scatter'","jitter")~=0 local fopt ""
+
+if "`nograph'"=="" twoway (rarea `uy' `ly' `av', bc(gs13) sort) (scatter `diff' `av' `fopt', m(o) `scatteropt' `scatter' `moptions' ) (line `my' `av',lp(dash) sort ) , ////
+ legend(off) ytitle(`ytit') xtitle(`xtit') xlabel(`xmin' `xmax') `xopt'
+
+  return local lower = `lrr'
+  return local upper = `urr'
+  return local mean = `mrr'
+}
+
+else {
+  qui reg `diff' `av'
+  local b1 = _b[`av']
+  local b0 = _b[_cons]
+  local sd = `e(rmse)'
+  qui predict resid , resid
+  qui gen absresid = abs(resid)
+
+  /* Analysis of the residuals */
+
+  qui reg absresid `av'
+  local c0 = _b[_cons]
+  local c1=_b[`av']
+
+  qui su `diff'
+  local max = `r(max)'
+  local min = `r(min)'
+  qui su `av'
+  local xmax = r(max)
+  local xmin = r(min)
+
+  local max: di %5.3f `xmax'
+  local min: di %5.3f `xmin'
+
+  tempvar y uy ly  x
+
+/* The bit to extend the shade */
+
+  local obs =`c(N)'+2
+  qui set obs `obs'
+  if "`sxmin'"~="" qui replace `av'=`sxmin' in `obs--'
+  if "`sxmax'"~="" qui replace `av'=`sxmax' in `obs'
+
+  sort `av'
+  qui gen `y' = `b0'+`b1'*`av'
+  qui gen `uy' = `b0'+`b1'*`av' + 2.46*(`c0'+`c1'*`av')
+  qui gen `ly' = `b0'+`b1'*`av' - 2.46*(`c0'+`c1'*`av')
+
+  if "`info'"~="" {
+    qui count if (`diff'>`uy' | `diff'<`ly') & `diff'~=.
+    local nout = `r(N)'
+    qui count if `diff'~=.
+    local n = `r(N)'
+    local mdp = `dp'+3
+    local mdp1 = `dp'+4
+    
+    local pctout : di %`mdp1'.`dp'f `nout'/`n'*100
+    local te0 : di %`mdp'.`dp'f `b0'
+    local te1 : di %`mdp'.`dp'f `b1'
+    local te2 : di %`mdp'.`dp'f `c0'
+    local te3 : di %`mdp'.`dp'f `c1'
+    local xopt `"`xopt' subtitle("`nout'/`n' = `pctout'% outside the limits of agreement" "Mean Diff = `te0'+ `te1'*Average " "Limits +/- 2.46*(`te2' + `te3'*Average) ") "'
+  }
+  if "`valabel'"~="" {
+    tempvar label
+    qui gen `label' = ""
+    cap confirm string variable `valabel'
+    if _rc~=0 qui replace `label' = string(`valabel') if `diff'>`uy' | `diff'<`ly'
+    else qui replace `label' = `valabel' if `diff'>`uy' | `diff'<`ly'
+    local scatteropt "mlabel(`label') note(Points outside limits labelled by `valabel')"
+  }
+
+  tempvar freq
+  qui bysort `diff' `av':gen  `freq'=_N
+  local fopt "[fw=`freq']"
+  if index("`scatter'","jitter")~=0 local fopt "" 
+
+if "`nograph'"==""  {
+   twoway (rarea `uy' `ly' `av', bc(gs13) sort)(scatter `diff' `av' `fopt', `scatteropt' `scatter') /*
+*/(line `y' `av', lp(dash) sort) , legend(off) ytitle(`ytit') xtitle(`xtit') xlabel(`xmin' `xmax') `xopt'
+}
+
+  return local b0 = `b0'
+  return local b1 = `b1'
+  return local c0 = `c0'
+  return local c1 = `c1'
+  return local eqn = "`b0'+`b1'*av"
+  return local upper = "`b0'+`b1'*Average + 2.46*(`c0'+`c1'*Average)"
+  return local lower = "`b0'+`b1'*Average - 2.46*(`c0'+`c1'*Average)"
+
+}
+
+end
diff --git a/Modules/ado/plus/b/batplot.hlp b/Modules/ado/plus/b/batplot.hlp
new file mode 100644
index 0000000..618342d
--- /dev/null
+++ b/Modules/ado/plus/b/batplot.hlp
@@ -0,0 +1,128 @@
+{smcl}
+{* 9May2008}{...}
+{cmd:help batplot}
+{hline}
+
+{title:Title}
+
+    {hi: Produces a Bland-Altman plot when there is a relationship between paired differences and their average}
+
+
+{title:Syntax}
+
+{p 8 17 2}
+{cmdab:batplot} {it:varname1 varname2} [if] [in]
+[{cmd:,} {it:options}]
+
+{synoptset 20 tabbed}{...}
+{synopthdr}
+{synoptline}
+{syntab:Main}
+{synopt:{opt info:}} specifies that the percentage of points outside the limits of agreement are displayed as a subtitle.{p_end}
+{synopt:{opt val:abel}({varname})} specifies that the points outside the limits of agreement be labelled using the variable {it:varname}.{p_end}
+{synopt:{opt shading:}(min max)} specifies the extent of shading beyond the range of the data.{p_end}
+{synopt:{opt notrend:}} specifies that the original Bland-Altman plot (without a trend) be plotted.{p_end}
+{synopt:{opt moptions:}} specifies options for the markers that lie outside the limits of agreement.{p_end}
+{synopt:{opt sc:atter}} specifies options for the scatter part of the final plot, see {help scatter}.{p_end}
+{synopt:{help twoway_options}} specifies options for example titles and labels.{p_end}
+{synoptline}
+{p2colreset}{...}
+
+
+{title:Description}
+
+{pstd}
+{cmd:batplot} produces a Bland-Altman plot adjusted for trend.
+
+{pstd}
+The standard Bland-Altman plot is between the difference of paired variables versus the average, this is produced
+using the {bf:notrend} option. The main addition that this command handles is when there is a linear relationship between
+the the paired difference and the paired average. A regression model is used to adjust the limits of agreement accordingly. 
+This is particularly useful when the two variables might be measured on different scales and hence a straight conversion 
+factor would recalibrate the two variables.
+
+{title:Options}
+
+{dlgtab:Main}
+
+{phang}
+{opt info:} specifies that the percentage of points outside the limits of agreement are displayed as a subtitle. Additionally
+when using the notrend option the limits of agreement and mean difference are included in the subtitle.
+
+{phang}
+{opt val:abel}({varname}) specifies that the points outside the limits of agreement be labelled using the variable {it:varname}.
+
+{phang}
+{opt shading:}(min max) specifies the extent of shading beyond the range of the data. The default is that the limits of 
+shading is determined by the values in the {hi:xlabel} option.
+
+{phang}
+{opt notrend:} specifies that the original Bland-Altman plot (without a trend) be plotted.
+
+{phang}
+{opt moptions:} specifies options for the markers that lie outside the limits of agreement, the options can be anything from
+the scatter marker options {help scatter##marker_options}.
+
+{phang}
+{opt sc:atter} specifies options for the scatter part of the final plot.
+
+{title:Examples}
+
+{pstd}
+Using the {hi:auto.dta} dataset supplied with STATA 8 this command can check whether there is agreement between 
+turning circle (ft) and miles per gallon, click the highlighted text in order,
+
+{phang}{stata sysuse auto, clear}
+
+{phang}{stata batplot mpg turn}
+
+{pstd}
+This is the most basic graphic and using twoway options the look can be improved by clicking below,
+
+{phang}
+{stata batplot mpg turn, title(Agreement between mpg and turn) xlab(26(4)38) }
+
+{pstd}
+By specifying extra options the outlying points can be labelled and identified by the car make,
+
+{phang}
+{stata batplot mpg turn, title(Agreement between mpg and turn) info valabel(make) xlab(26(4)38) }
+
+{pstd}
+To obtain the original Bland Altman plot use the notrend option,
+
+{phang}
+{stata batplot mpg turn, title(Agreement between mpg and turn) info valabel(make) notrend xlab(26(4)38) }
+
+{pstd}
+To improve the labelling of the point VW it may be preferable to change the clock position of the label i.e.
+labels could appear to the left of the point. This is handled below with {hi: moptions()}.
+
+{phang}
+{stata batplot mpg turn, title(Agreement between mpg and turn) info valabel(make) notrend xlab(26(4)38) moptions(mlabp(9))}
+
+{pstd}
+Additionally in the case of multiple scatter points by using the {hi:scatter()} option the user can specify to "{hi:jitter}" datapoints
+
+{phang}
+{stata batplot mpg turn, notrend xlab(26(4)38) moptions(mlabp(9)) sc(jitter(4))}
+
+
+{title:Author}
+
+{p}
+Adrian Mander, MRC Human Nutrition Research, Cambridge, UK.
+
+Email {browse "mailto:adrian.mander@mrc-hnr.cam.ac.uk":adrian.mander@mrc-hnr.cam.ac.uk}
+
+{title:Also see}
+
+Related commands
+
+HELP FILES
+{help baplot} (if installed)
+
+
+
+
+
diff --git a/Modules/ado/plus/b/binolist.ado b/Modules/ado/plus/b/binolist.ado
new file mode 100644
index 0000000..22eccb7
--- /dev/null
+++ b/Modules/ado/plus/b/binolist.ado
@@ -0,0 +1,22 @@
+program def binolist, rclass
+*! NJC 1.1.0 6 June 2000 
+* NJC 1.0.0 25 Jan 2000 
+	version 6.0 
+	syntax , K(numlist int max=1 >0) [ Global(str) Noisily ]
+	
+	if length("`global'") > 8 { 
+		di in r "global name must be <=8 characters" 
+		exit 198 
+	} 	
+
+	local i = 1 
+	while `i' <= `k' { 
+		local val = comb(`k'-1, `i'-1)  
+	        local newlist "`newlist' `val'" 
+		local i = `i' + 1 
+	}
+	
+	if "`noisily'" != "" { di "`newlist'" } 
+	if "`global'" != "" { global `global' "`newlist'" } 
+	return local list `newlist' 
+end 	
diff --git a/Modules/ado/plus/b/binolist.hlp b/Modules/ado/plus/b/binolist.hlp
new file mode 100644
index 0000000..eacf780
--- /dev/null
+++ b/Modules/ado/plus/b/binolist.hlp
@@ -0,0 +1,2 @@
+.h listutil
+
diff --git a/Modules/ado/plus/b/blandaltman.ado b/Modules/ado/plus/b/blandaltman.ado
new file mode 100644
index 0000000..3c0e844
--- /dev/null
+++ b/Modules/ado/plus/b/blandaltman.ado
@@ -0,0 +1,89 @@
+
+***********************************************************************************************************************
+**** Program blandaltman (one parameter against another parameter) startet ********************************************	
+***********************************************************************************************************************	
+	
+*	set more off
+*	capture program drop blandaltman
+	program blandaltman
+		syntax varlist(max=2)
+
+		// prepare for Bland Altman Interreader
+			tempvar diff_xy
+			tempvar avg_xy
+			tempvar lower
+			tempvar higher
+			tempvar MW
+			tempvar SE
+			tempvar CIhigher
+			tempvar CIlower
+			
+			generate `diff_xy'=0
+			generate `avg_xy'=0
+			generate `lower'=0
+			generate `higher'=0
+			generate `MW'=0
+			generate `SE'=0
+			generate `CIhigher'=0
+			generate `CIlower'=0
+			
+		// count the variable: how many variable are in the list?
+			local noofvars : word count `varlist'
+			display as text "The variable list of this program counts " `noofvars' " variables"
+			display as result " "
+			display as result " "
+			
+		// Interreader
+			local x = 1
+			local y = 1
+			foreach varx of varlist `varlist' { 
+				foreach vary of varlist `varlist'{
+					if `y' >`x'{
+					quietly replace `avg_xy'=(`varx'+`vary')/2
+					quietly replace `diff_xy'=`varx'-`vary'
+					display as result " Bland Altman Plot of `varx' and `vary'"
+					quietly sum `diff_xy'
+					quietly return list
+					quietly replace `MW'=r(mean)
+					quietly replace `lower'=r(mean)-2*r(sd)
+					quietly replace `higher'=r(mean)+2*r(sd)
+					quietly replace `SE'=(r(sd))/(sqrt(r(N)))
+					quietly replace `CIlower'=r(mean)-2*`SE'
+					quietly replace `CIhigher'=r(mean)+2*`SE'
+					display as result "- mean of difference between `varx' and `vary' is "r(mean)
+					display as result "- sd of difference between `varx' and `vary' is "r(sd)
+					display as result "- lower limit of difference between `varx' and `vary' is " `lower'
+					display as result "- higher limit of difference between `varx' and `vary' is " `higher'
+					display as result "- Limits of agreement (Reference Range for difference): " `lower' " to " `higher'
+					display as result "- Mean difference:" `MW' " (CI " `CIlower' " to " `CIhigher' ")"
+					display as result " "
+					display as result " "
+					
+					label var `diff_xy' "Values"
+					label var `MW' "mean of difference"
+					label var `lower' "lower limit of agreement"
+					label var `higher' "higher limit of agreement"
+					twoway (scatter `diff_xy' `avg_xy', msymbol(smcircle_hollow) mcolor(ebblue)) (line `MW' `avg_xy', lcolor(red))(line `lower' `avg_xy', lcolor(black) ) (line `higher' `avg_xy', lcolor(black) ),  title(Bland Altman Plot, size(8)) subtitle(,size(5)) xtitle(Average of `varx' and `vary') ytitle(Difference of `varx' and `vary') caption() note(NOTE)  legend(off) 
+					}
+				local y = `y'+1
+				}
+			local y = 1
+			local x =`x'+1	
+			}
+	end
+ 
+***********************************************************************************************************************
+**** Program blandaltman (one parameter against another parameter) endet **********************************************	
+***********************************************************************************************************************	
+		
+		
+		
+		
+//	EXAMPLE 
+		
+*	sysuse bpwide.dta
+	
+	// to create a bland altman plot use the command "blandaltman" with variable1  and variable2
+*	blandaltman bp_before bp_after
+	
+	
\ No newline at end of file
diff --git a/Modules/ado/plus/b/bollenstine.ado b/Modules/ado/plus/b/bollenstine.ado
new file mode 100644
index 0000000..1c5b8e4
--- /dev/null
+++ b/Modules/ado/plus/b/bollenstine.ado
@@ -0,0 +1,187 @@
+*! Bollen-Stine bootstrap, v.1.3, Stas Kolenikov
+program define bollenstine, eclass
+
+  syntax, [Reps(int 200) SAVing(str) notable noheader nolegend ///
+    SAFER CONFAOPTions(str) *]
+
+
+  * this is a post-estimation command following confa1
+  if "`e(cmd)'" ~= "confa1" & "`e(cmd)'" ~= "confa" error 301
+
+  * the low level preserve
+  preserve
+  tempfile pres
+  tempname confares
+  est store `confares'
+  qui save `pres'
+
+  qui keep if e(sample)
+  local T = e(lr_u)
+
+  local safer cap noi
+
+  if "`saving'" == "" {
+     tempfile bsres
+     local saving `bsres'
+  }
+
+  if "`e(cmd)'" == "confa1" {
+
+     local varlist = "`e(depvar)'"
+     local p : word count `varlist'
+
+     tempname Sigma bb
+     mat `Sigma' = e(Model)
+     mat `bb' = e(b)
+
+     mata: CONFA1_BSrotate("`Sigma'","`varlist'")
+
+      `safer' bootstrap _b (T: T = e(lr_u)) (reject: reject = (e(lr_u) > `T') ) , ///
+           reps(`reps') saving(`saving') notable noheader nolegend ///
+           reject( e(converged) == 0) `options' ///
+        : confa1 `varlist' , from(`bb', skip) `confaoptions'
+     * may need some other options, too!
+     nobreak if "`safer'"~="" & _rc {
+        * for whatever reason, the bootstrap broke down
+        qui use `pres' , clear
+        qui est restore `confares'
+        qui est drop `confares'
+        error _rc
+     }
+     * just to display the results
+     * the covariance matrix should have been reposted by the -bootstrap-!
+
+     * we still need to trick Stata back into confa1!
+     ereturn local cmd confa1
+
+  }
+
+  else if "`e(cmd)'" == "confa" {
+
+      local varlist = "`e(observed)'"
+      local p : word count `varlist'
+
+      tempname Sigma bb
+      mat `Sigma' = e(Sigma)
+      mat `bb' = e(b)
+
+      mata: CONFA1_BSrotate("`Sigma'","`varlist'")
+
+      * set up the call
+      local k = 1
+      while "`e(factor`k')'" ~= "" {
+         local call `call' (`e(factor`k')')
+         local ++k
+      }
+
+      * the first call and resetting the from vector
+      cap confa `call' , from(`bb') `confaoptions'
+      if _rc {
+         di as err "cannot execute confa with rotated data only"
+         restore
+         qui est restore `confares'
+         cap est drop `confares'
+         exit 309
+      }
+      mat `bb' = e(b)
+      if ~strpos("`confaoptions'", "from")  local from from(`bb')
+
+      * correlated errors?
+      * unit variance identification?
+
+       `safer' bootstrap _b (T: T = e(lr_u)) (reject: reject = (e(lr_u) > `T') ) , ///
+            reps(`reps') saving(`saving') notable noheader nolegend ///
+            reject( e(converged) == 0) `options' ///
+         : confa `call' , `from' `confaoptions'
+      * may need some other options, too!
+      nobreak if "`safer'"~="" & _rc {
+         * for whatever reason, the bootstrap broke down
+         qui use `pres' , clear
+         qui est restore `confares'
+         cap est drop `confares'
+         error _rc
+      }
+      * the covariance matrix should have been reposted by the -bootstrap-!
+
+      * we still need to trick Stata back into confa!
+      ereturn local cmd confa
+  }
+
+  else {
+      * what on earth was that?
+      error 301
+  }
+
+
+  * the bootstrap test on T
+  gettoken bsres blah : saving , parse(",")
+  * to strip off replace option, if there is any
+  qui use `bsres', clear
+  sum reject_reject, mean
+
+  local pBS = r(mean)
+  local BBS = r(N)
+
+  qui sum T_T, det
+  local q05 = r(p5)
+  local q95 = r(p95)
+
+  qui use `pres', clear
+  qui est restore `confares'
+  qui est drop `confares'
+
+  ereturn scalar p_u_BS = `pBS'
+  ereturn scalar B_BS = `BBS'
+*  ereturn scalar lr_u = `T'
+*  ereturn scalar p_u = chi2tail(e(df_u),e(lr_u))
+
+  ereturn scalar T_BS_05 = `q05'
+  ereturn scalar T_BS_95 = `q95'
+  ereturn local vce BollenStine
+  ereturn local vcetype Bollen-Stine
+
+  `e(cmd)'
+
+end
+
+cap mata: mata drop CONFA1_BSrotate()
+mata:
+void CONFA1_BSrotate(
+       string SigmaName, // the parameter matrix name
+       string varnames // the variable names
+       ) {
+
+   // declarations
+   real matrix data  // views of the data
+   real matrix Sigma, SS, S2, SS2  // the covariance matrices and temp matrices
+   real matrix means // the means -- need modifications for weighted data!!!
+   real scalar p, n // dimension, no. obs
+
+   // get the data in
+   st_view(data=., ., tokens(varnames) )
+   n=rows(data)
+   p=cols(data)
+
+   Sigma = st_matrix(SigmaName)
+
+   // probability weights!!!
+   means = colsum(data)/n
+   SS = (cross(data,data)-n*means'*means)/(n-1)
+
+   S2 = cholesky(Sigma)
+   SS2 = cholesky(SS)
+   SS2 = solveupper(SS2',I(rows(SS)))
+
+   data[,] = data*SS2*S2'
+
+}
+
+end
+
+
+exit
+
+History:
+v.1.1  -- Jan 9, 2007
+v.1.2  -- Mar 26, 2008: confa1 options added; reject() added
+v.1.3  -- July 12, 2008: upgraded to confa
diff --git a/Modules/ado/plus/b/bollenstine.sthlp b/Modules/ado/plus/b/bollenstine.sthlp
new file mode 100644
index 0000000..4a98dbc
--- /dev/null
+++ b/Modules/ado/plus/b/bollenstine.sthlp
@@ -0,0 +1,88 @@
+{smcl}
+{* *! version 1.3  28Oct2008}{...}
+{cmd:help bollenstine} {right: ({browse "http://www.stata-journal.com/article.html?article=st0169":SJ9-3: st0169})}
+{hline}
+
+{title:Title}
+
+{p2colset 5 20 22 2}{...}
+{p2col :{hi:bollenstine} {hline 2}}Bollen-Stine bootstrap following confirmatory factor analysis
+{p2colreset}{...}
+
+
+{title:Syntax}
+
+{p 8 19 2}
+{cmd:bollenstine} [{cmd:,} {cmdab:r:eps(}{it:#}{cmd:) }
+{cmdab:sav:ing(}{it:filename}{cmd:) }
+{cmdab:confaopt:ions(}{it:string}{cmd:)}
+{it:bootstrap_options}]
+{p_end}
+
+
+{title:Description}
+
+{pstd}{cmd:bollenstine} performs the Bollen and Stine (1992) bootstrap
+following structural equation models (confirmatory factor analysis) estimation.
+The original data are rotated to conform to the fitted structure.
+By default, {cmd:bollenstine} refits the model
+with rotated data and uses the estimates as
+starting values in each bootstrap iteration. It also rejects samples
+where convergence was not achieved (implemented through the {cmd:reject(e(converged) == 0)} option supplied to
+{helpb bootstrap}).
+
+
+{title:Options}
+
+{phang}{cmd:reps(}{it:#}{cmd:)} specifies the number of bootstrap replications.
+The default is {cmd:reps(200)}.{p_end}
+
+{phang}{cmd:saving(}{it:filename}{cmd:)} specifies the file
+where the simulation results (the parameter estimates and the fit statistics)
+are to be stored. The default is a temporary file that will
+be deleted as soon as {cmd:bollenstine} finishes.{p_end}
+
+{phang}{opt confaoptions(string)} allows the transfer of {cmd:confa}
+options to {cmd:bollenstine}. If nondefault model options ({cmd:unitvar()} and
+{cmd:correlated()}) were used, one would need to use them with
+{cmd:bollenstine} as well.
+
+{phang}All nonstandard model options, like {cmd:unitvar()} or {cmd:correlated()},
+must be specified with {cmd:bollenstine} to produce correct results!
+
+{phang}All other options are assumed to be {it:bootstrap_options}
+and passed through to {helpb bootstrap}.
+
+
+{title:Example}
+
+{phang2}{cmd:. use hs-cfa}{p_end}
+{phang2}{cmd:. confa (vis: x1 x2 x3) (text: x4 x5 x6) (math: x7 x8 x9), from(iv) correlated(x7:x8)}{p_end}
+{phang2}{cmd:. set seed 10101}{p_end}
+{phang2}{cmd:. bollenstine, reps(200) confaoptions(iter(20) corr(x7:x8))}
+
+
+{title:Reference}
+
+{phang}{bind:}Bollen, K., and R. Stine. 1992.
+Bootstrapping goodness-of-fit measures in structural
+equation models. {it:Sociological Methods and Research} 21: 205-229.
+{p_end}
+
+
+{title:Author}
+
+{pstd}Stanislav Kolenikov{p_end}
+{pstd}Department of Statistics{p_end}
+{pstd}University of Missouri{p_end}
+{pstd}Columbia, MO{p_end}
+{pstd}kolenikovs@missouri.edu{p_end}
+
+
+{title:Also see}
+
+{psee}
+Article: {it:Stata Journal}, volume 9, number 3: {browse "http://www.stata-journal.com/article.html?article=st0169":st0169}
+
+{psee}Online: {helpb confa}, {helpb confa_estat:confa postestimation}, 
+{helpb bootstrap} (if installed){p_end}
diff --git a/Modules/ado/plus/b/bothlist.ado b/Modules/ado/plus/b/bothlist.ado
new file mode 100644
index 0000000..4976dc9
--- /dev/null
+++ b/Modules/ado/plus/b/bothlist.ado
@@ -0,0 +1,89 @@
+program def bothlist, rclass
+*! NJC 1.3.0 6 June 2000 
+* NJC 1.2.0 31 Jan 2000 
+* NJC 1.1.0 22 Dec 1999 
+* NJC 1.0.0 21 Dec 1999 	
+	version 6.0 
+	gettoken lists 0 : 0, parse(",")
+	if "`lists'" == "" | "`lists'" == "," { /* no \ */ 
+		di in r "incorrect syntax: no separator" 
+		exit 198 
+	}
+	
+	tokenize "`lists'", parse("\") 
+	if "`4'" != "" { 
+		di in r "incorrect syntax: too much stuff" 
+		exit 198 
+	} 	
+	if "`1'" == "\" { /* list1 empty */ 
+		if "`2'" == "\" { 
+			di in r "incorrect syntax: one \ only" 
+			exit 198
+		}	
+		local list2 "`2'" /* might be empty */ 
+	} 
+	else if "`2'" == "\" { 
+		local list1 "`1'" 
+		local list2 "`3'" /* might be empty */ 
+	} 	
+	else { 
+		di in r "incorrect syntax: what to compare?" 
+		exit 198 
+	}
+	
+	syntax [ , Global(str) Noisily ] 
+
+	if length("`global'") > 8 { 
+		di in r "global name must be <=8 characters" 
+		exit 198 
+	} 	
+
+	* remove duplicates from `list1' 
+	
+	tokenize `list1' 
+	local list1 "`1'" 
+	mac shift 
+	 
+	while "`1'" != "" { 
+		local n1 : word count `list1' 
+		local i = 1 
+		local putin = 1 
+		while `i' <= `n1' { 
+			local word : word `i' of `list1' 
+			if "`word'" == "`1'" { 
+				local putin = 0 
+				local i = `n1' 
+			} 
+			local i = `i' + 1 
+		} 	
+		if `putin' { local list1 "`list1' `1'" } 
+		mac shift
+	}
+	
+	* what is in both lists? 
+	
+	local n1 : word count `list1' 
+	tokenize `list1'
+	local n2 : word count `list2' 
+
+	local i = 1 
+	while `i' <= `n1' { 
+		local j = 1 
+		local putin = 0 
+		while `j' <= `n2' { 
+			local word : word `j' of `list2' 
+			if "`word'" == "``i''" { 
+				local putin = 1 
+				local j = `n2' 
+			} 
+			local j = `j' + 1 
+		} 
+		if `putin' { local newlist "`newlist' ``i''" } 
+		local i = `i' + 1
+	}
+	
+	if "`noisily'" != "" { di "`newlist'" } 
+	if "`global'" != "" { global `global' "`newlist'" } 
+	return local list `newlist' 
+end 	
+			 
diff --git a/Modules/ado/plus/b/bothlist.hlp b/Modules/ado/plus/b/bothlist.hlp
new file mode 100644
index 0000000..eacf780
--- /dev/null
+++ b/Modules/ado/plus/b/bothlist.hlp
@@ -0,0 +1,2 @@
+.h listutil
+
diff --git a/Modules/ado/plus/b/brant.ado b/Modules/ado/plus/b/brant.ado
new file mode 100644
index 0000000..fc547a7
--- /dev/null
+++ b/Modules/ado/plus/b/brant.ado
@@ -0,0 +1,297 @@
+*! version 1.6.0 3/29/01
+
+capture program drop brant
+program define brant, rclass
+version 6
+    tempvar touse
+    tempname bout d pvals ivchi ivout step1 step2 ologit
+    tempname XpWmmX iXpWmmX XpWmlX XpWllX iXpWllX DB DBp iDvBDp
+    syntax [, detail]
+
+    if "`e(cmd)'"!="ologit" {
+        di in r "brant can only be used after ologit"
+        exit
+    }
+
+    *to make output stata 6 or stata 7 compatible
+    cap version 7
+        if _rc!=0 {
+            local vers7 "no"
+            local smcl ""
+            local dash "-"
+            local vline "|"
+            local plussgn "+"
+            local topt "-"
+            local bottomt "-"
+        }
+        else { local vers7 "yes"
+            local smcl "in smcl "
+            local dash "{c -}"
+            local vline "{c |}"
+            local plussgn "{c +}"
+            local topt "{c TT}"
+            local bottomt "{c BT}"
+        }
+    version 6.0
+
+    local ocmd "`e(cmd)'"
+    if "`ocmd'"=="ologit"  { local bcmd "logit" }
+    local depvar "`e(depvar)'"
+    gen `touse' = e(sample)
+    local wtis ""
+    if "`e(wtype)'"!="" {
+        di in r "-brant- does not work with ologit models with weights"
+        error 999
+    }
+    _perhs
+    local rhsnms "`r(rhsnms)'"
+    local nrhs "`r(nrhs)'"
+    _pecats
+    local numcats = `r(numcats)'
+    local catvals "`r(catvals)'"
+    local catnms "`r(catnms)'"
+    local catnms8 "`r(catnms8)'"
+    estimates hold `ologit'
+
+*** estimate series of binary logits
+    local i = 1
+    while `i' <= `numcats'-1 {
+        local splitat : word `i' of `catvals'
+        tempvar dummy
+        quietly gen `dummy' = 0 if `depvar' <= `splitat' & `touse'==1
+        quietly replace `dummy' = 1 if `depvar' > `splitat' & `touse'==1
+        quietly `bcmd' `dummy' `rhsnms' `wtis' if `touse' == 1
+        _perhs
+        local binnrhs = "`r(nrhs)'"
+        if `nrhs' != `binnrhs' {
+            di in r "not all independent variables can be retained in all binary logits"
+            di in r "brant test cannot be computed"
+            exit 999
+        }
+        tempvar prob`i'
+        quietly predict `prob`i''
+        tempname b`i' V`i' bc`i'
+        mat `b`i'' = e(b)
+        mat `b`i'' = `b`i''[1, 1..`nrhs']
+        mat `V`i'' = e(V)
+        mat `V`i'' = `V`i''[1..`nrhs', 1..`nrhs']
+        mat `bc`i'' = e(b) /* with constant--for detail output only */
+        mat `bc`i'' = `bc`i'''
+        local outname "y>`splitat'"
+        local outname = substr("`outname'", 1, 8)
+        mat colnames `bc`i'' = "`outname'"
+        mat `bout' = nullmat(`bout'), `bc`i''
+        local i = `i' + 1
+    }
+
+*** make variables for W(ml) matrices
+    local i = 1
+    while `i' <= `numcats'-1 {
+        local i2 = `i'
+        while `i2' <= `numcats'- 1 {
+            tempvar w`i'_`i2'
+            quietly gen `w`i'_`i2'' = `prob`i2'' - (`prob`i''*`prob`i2'')
+            local i2 = `i2' + 1
+       }
+        local i = `i' + 1
+    }
+
+*** calculate variance Bm, Bl
+    local i = 1
+    while `i' <= `numcats'-1 {
+        local i2 = `i'
+        while `i2' <= `numcats'- 1 {
+            quietly {
+                * inverse(X'W(mm)X)
+                matrix accum `XpWmmX' = `rhsnms' [iw=`w`i'_`i''] if `touse'==1
+                matrix `iXpWmmX' = inv(`XpWmmX')
+                * X'W(ml)X
+                matrix accum `XpWmlX' = `rhsnms' [iw=`w`i'_`i2''] if `touse'==1
+                * inverse(X'W(ll)X)
+                matrix accum `XpWllX' = `rhsnms' [iw=`w`i2'_`i2''] if `touse'==1
+                matrix `iXpWllX' = inv(`XpWllX')
+                * product of three matrices
+                matrix `step1' = `iXpWmmX' * `XpWmlX'
+                tempname vb`i'_`i2'
+                matrix `vb`i'_`i2'' = `step1' * `iXpWllX'
+            }
+            mat `vb`i'_`i2''= `vb`i'_`i2''[1..`nrhs',1..`nrhs']
+            local i2 = `i2' + 1
+       }
+        local i = `i' + 1
+    }
+
+    * define var(B) matrix
+    local i = 1
+    while `i' <= `numcats'-1 {
+        tempname row`i'
+        local i2 = 1
+        while `i2' <= `numcats'- 1 {
+            quietly {
+                if `i'==`i2' { mat `row`i'' = nullmat(`row`i''), `V`i'' }
+                if `i'<`i2' { mat `row`i'' = nullmat(`row`i'') , `vb`i'_`i2'' }
+                if `i'>`i2' { mat `row`i'' = nullmat(`row`i'') , `vb`i2'_`i''' }
+            }
+            local i2 = `i2' + 1
+       }
+        local i = `i' + 1
+    }
+
+    * combine matrices
+    tempname varb
+    local i = 1
+    while `i' <= `numcats'-1 {
+        mat `varb' = nullmat(`varb') \ `row`i''
+        local i = `i' + 1
+    }
+    * make beta vector
+    tempname bstar
+    local i = 1
+    while `i' <= `numcats'-1 {
+        mat `bstar' = nullmat(`bstar') , `b`i''
+        local i = `i' + 1
+    }
+    mat `bstar' = `bstar''
+
+    * create design matrix for wald test; make I, -I, and 0 matrices
+    tempname id negid zero
+    local dim = `nrhs'
+    mat `id' = I(`dim')
+    mat rownames `id' = `rhsnms'
+    mat colnames `id' = `rhsnms'
+    mat `negid' = -1*`id'
+    mat rownames `negid' = `rhsnms'
+    mat colnames `negid' = `rhsnms'
+    mat `zero' = J(`dim', `dim', 0)
+    mat rownames `zero' = `rhsnms'
+    mat colnames `zero' = `rhsnms'
+    * dummy matrix
+    local i = 1
+    while `i' <= `numcats'-2 {
+        tempname drow`i'
+        local i2 = 1
+        while `i2' <= `numcats'- 1 {
+            quietly {
+                tempname feed
+                if `i2'==1 { mat `feed' = `id' }
+                else if `i2'-`i'==1 { mat `feed' = `negid' }
+                else { mat `feed' = `zero' }
+                mat `drow`i'' = nullmat(`drow`i'') , `feed'
+            }
+            local i2 = `i2' + 1
+       }
+        local i = `i' + 1
+    }
+
+    * combine matrices
+    local i = 1
+    while `i' <= `numcats'-2 {
+        mat `d' = nullmat(`d') \ `drow`i''
+        local i = `i' + 1
+    }
+
+    * terms of wald test
+    mat `DB' = `d' * `bstar'
+    mat `DBp' = `DB''
+    mat `step1' = `d'*`varb'
+    mat `step2' = `step1' * (`d'')
+    mat `iDvBDp' = inv(`step2')
+
+*** calculate wald stat
+    tempname step1 wald waldout pout dfout
+    mat `step1' = `DBp' * `iDvBDp'
+    mat `wald' = `step1' * `DB'
+    sca `waldout' = `wald'[1,1]
+    sca `dfout' = `nrhs'*(`numcats'-2)
+    sca `pout' = chiprob(`dfout', `waldout')
+    tempname dtemp vbtemp bstemp
+    local i = 1
+    while `i' <= `nrhs' {
+        tempname d`i' vb`i' bstar`i'
+        local i2 = 1
+            while `i2' <= `numcats'-1 {
+                local row = ((`nrhs')*(`i2'-1)) + (`i')
+                tempname drow vbrow
+                local i3 = 1
+                while `i3' <= `numcats'-1 {
+                    local column = ((`nrhs')*(`i3'-1)) + (`i')
+                    if (`i2'<`numcats'-1) {
+                        mat `dtemp' = `d'[`row',`column']
+                        mat `drow' = nullmat(`drow') , `dtemp'
+                    }
+                    mat `vbtemp' = `varb'[`row',`column']
+                    mat `vbrow' = nullmat(`vbrow') , `vbtemp'
+                local i3 = `i3' + 1
+            }
+            if (`i2'<`numcats'-1) { mat `d`i'' = nullmat(`d`i'') \ `drow' }
+            mat `vb`i'' = nullmat(`vb`i'') \ `vbrow'
+            mat `bstemp' = `bstar'[`row', 1]
+            mat `bstar`i'' = nullmat(`bstar`i'') \ `bstemp'
+            local i2 = `i2' + 1
+        }
+        local i = `i' + 1
+    }
+
+*** wald test for each independent variable
+    tempname waldiv
+    local i = 1
+    while `i' <= `nrhs' {
+        tempname DB DBp iDvBDp step1 step2
+        mat `DB' = `d`i'' * `bstar`i''
+        mat `DBp' = `DB''
+        mat `step1' = `d`i''*`vb`i''
+        mat `step2' = `step1' * (`d`i''')
+        mat `iDvBDp' = inv(`step2')
+        tempname step1 wald`i'
+        mat `step1' = `DBp' * `iDvBDp'
+        mat `wald`i'' = `step1' * `DB'
+        mat `waldiv' = nullmat(`waldiv') \ `wald`i''
+        local i = `i' + 1
+    }
+
+    if "`detail'"!="" {
+        di _n in gr "Estimated coefficients from j-1 binary regressions"
+        mat list `bout', noheader
+    }
+
+    di _n in g "Brant Test of Parallel Regression Assumption"
+    di _n `smcl' in g "    Variable `vline'      chi2   p>chi2    df"
+    di  `smcl' _dup(13) in g "`dash'" "`plussgn'" _dup(26) in g "`dash'"
+    di  `smcl' in g "         All `vline'" in y /*
+    */ %10.2f `waldout' %9.3f `pout' %6.0f `dfout'
+    di  `smcl' _dup(13) in g "`dash'" "`plussgn'" _dup(26) in g "`dash'"
+    * calculate p for individual wald tests
+    mat `pvals' = J(`nrhs', 1, 0)
+    local i = 1
+    local df = `numcats'-2
+    while `i' <= `nrhs' {
+        sca `ivchi' = `waldiv'[`i',1]
+        if `ivchi' >= 0 {
+            mat `pvals'[`i',1] = chiprob(`df',`ivchi')
+        }
+        if `ivchi' < 0 {
+            mat `pvals'[`i',1] = -999
+        }
+        local vnm : word `i' of `rhsnms'
+
+        *added for stata 7 compatibility
+        local printnm "`vnm'"
+        if "`vers7'"=="yes" { local printnm = abbrev("`printnm'", 12) }
+
+        di `smcl' in g %12s "`printnm'" _col(14) "`vline'" in y /*
+        */ %10.2f `ivchi' %9.3f `pvals'[`i',1] %6.0f `df'
+        local i = `i' + 1
+    }
+    di  `smcl' _dup(13) in g "`dash'" "`bottomt'" _dup(26) in g "`dash'"
+    di _n in g /*
+        */ "A significant test statistic provides evidence that the parallel"
+    di in g "regression assumption has been violated."
+    mat `ivout' = `waldiv', `pvals'
+    mat rownames `ivout' = `rhsnms'
+    mat colnames `ivout' = chi2 p>chi2
+    estimates unhold `ologit'
+    return scalar chi2 = `waldout'
+    return scalar p = `pout'
+    return scalar df = `dfout'
+    return matrix ivtests `ivout'
+end
diff --git a/Modules/ado/plus/b/brant.hlp b/Modules/ado/plus/b/brant.hlp
new file mode 100644
index 0000000..5eff2e6
--- /dev/null
+++ b/Modules/ado/plus/b/brant.hlp
@@ -0,0 +1,54 @@
+.-
+help for ^brant^ - 1.0.1 - 11/26/00
+.-
+
+Perform Brant test of parallel regression assumption after @ologit@
+------------------------------------------------------------
+
+    ^brant^ [^,^ ^detail^]
+
+
+^brant^ is for use after ^ologit^; see help @ologit@.
+
+
+Description
+-----------
+
+^brant^ performs a Brant test of the parallel regression assumption (also
+called the proportional odds assumption) after ologit.  The test compares
+slope coefficients of the J-1 binary logits implied by the ordered regression
+model.  Stata reports both the results of an omnibus test for the entire
+model and tests of the assumption for each of the independent variables in
+the model.
+
+The Brant test can only be computed if all of the independent variables in
+the ordered model are retained in all of the implied binary models.  This
+is most likely not to be the case with models that have few observations in
+the extreme categories and many independent variables.
+
+Options
+-------
+
+^detail^ specifies that the coefficients for each of the estimated binary
+logits should be presented.
+
+Example
+-------
+
+    . ^ologit warm yr89 male white age ed prst^
+    . ^brant^
+
+    . ^ologit warm yr89 male white age ed prst^
+    . ^brant, detail^
+
+Also see
+--------
+
+ Manual:  ^[R] ologit^
+
+.-
+Authors: J. Scott Long and Jeremy Freese
+         www.indiana.edu/~jslsoc/spost.htm
+         spostsup@@indiana.edu
+         
+         
diff --git a/Modules/ado/plus/backup.trk b/Modules/ado/plus/backup.trk
new file mode 100644
index 0000000..370b899
--- /dev/null
+++ b/Modules/ado/plus/backup.trk
@@ -0,0 +1,1402 @@
+* 00000057
+*! version 1.0.0
+* Do not erase or edit this file
+* It is used by Stata to track the ado and help
+* files you have installed.
+
+S http://www.unc.edu/~skolenik/stata
+N polychoric.pkg
+D 15 Dec 2006
+U 1
+d polychoric -- The polychoric correlation package
+d 
+d Author: Stas Kolenikov, skolenik@unc.edu
+d 
+d This package provides routines to estimate
+d the polychoric, tetrachoric, polyserial and biserial
+d correlations and use them in principal component analysis.
+d Current version: 1.4
+f p\polychoric.ado
+f p\polychoricpca.ado
+f p\polych_ll.ado
+f p\polyser_ll.ado
+f p\polychoric.hlp
+f p\polychoricpca.hlp
+e
+S http://www.stata.com/stb/stb61
+N sg158_1.pkg
+D  5 Mar 2007
+U 3
+d STB-61 sg158_1.  Update to random-effects ordered probit
+d STB insert by Guillaume R. Frechette, Ohio State University
+d Support:  gurst1@@econ.ohio-state.edu
+d After installation, see help ^reoprob^
+f g\ghquadm.ado
+f g\ghquadm.hlp
+f r\reop_ll.ado
+f r\reopc_ll.ado
+f r\reoprob.ado
+f r\reoprob.hlp
+f r\rfpr_ll1.ado
+f r\rfprobit.ado
+f r\rfprobit.hlp
+e
+S http://www.stata-journal.com/software/sj5-4
+N st0067_2.pkg
+D  5 Jun 2007
+U 4
+d SJ5-4 st0067_2.  Update:  Multiple imputation of missing...
+d Update:  Multiple imputation of missing values
+d by Patrick Royston, MRC Clinical Trials Unit, London, UK
+d Support:  patrick.royston@@ctu.mrc.ac.uk
+d After installation, type help ^ice^, ^micombine^, and ^mijoin^
+f i\ice.ado
+f i\ice.hlp
+f m\micombine.ado
+f m\micombine.hlp
+f m\mijoin.ado
+f m\mijoin.hlp
+f m\misplit.ado
+f m\misplit.hlp
+f u\uvis.ado
+f u\uvis.hlp
+f c\cmdchk.ado
+e
+S http://fmwww.bc.edu/repec/bocode/m
+N metaninf.pkg
+D 10 Jan 2008
+U 7
+d 'METANINF': module to evaluate influence of a single study in meta-analysis estimation
+d 
+d metaninf investigates the influence of each individual study on
+d the overall meta-analysis summary estimate. The command presents
+d a table and a graph of the results of an influence analysis in
+d which the meta-analysis is reestimated omitting each study in
+d turn. metaninf is a parallel program to metainf (Aurelio  Tobias;
+d STB-47: sbe26; STB-56: sbe26.1) that uses metan (rather than
+d meta) as  its calculation engine, thus allowing access to the
+d additional meta-analytic models offered therein.  metaninf also
+d differs from metainf in that metaninf uses metan's syntax and a
+d subset of its options (rather than those of meta). Program mhplot
+d (a variation of Nicholas Cox's hplot) is a required support
+d program.  This version (1.0.2) allows the jackknifed estimates to
+d be saved.  A Stata 8 dialog is included.
+d 
+d Distribution-Date: 20010619
+d 
+d Author: Thomas Steichen
+d Support: email steichen@@triad.rr.com
+d 
+f m\metaninf.ado
+f m\metaninf.hlp
+f m\mhplot.ado
+f m\metaninf.dlg
+e
+S http://fmwww.bc.edu/repec/bocode/m
+N metafunnel.pkg
+D  2 Apr 2008
+U 8
+d 'METAFUNNEL': module to produce funnel plots for meta-analysis
+d 
+d    metafunnel plots funnel plots. These graphical displays are
+d used to examine whether the results of a meta-analysis may have
+d been affected by publication or other types of bias.
+d 
+d Distribution-Date: 20030827
+d 
+d Author: Jonathan Sterne, University of Bristol
+d Support: email jonathan.sterne@@bristol.ac.uk
+d 
+f m\metafunnel.ado
+f m\metafunnel.hlp
+f m\metafunnel.dlg
+e
+S http://fmwww.bc.edu/repec/bocode/m
+N metabias.pkg
+D  2 Apr 2008
+U 9
+d 'METABIAS': module to test for publication bias in meta-analysis
+d 
+d metabias performs the Begg and Mazumdar adjusted rank correlation
+d test for publication bias and performs the Egger et al.
+d regression asymmetry test for publication bias. As options, it
+d provides a funnel graph of the data or the regression asymmetry
+d plot.  This is version 1.2.4 of the software. This version has
+d been modified to run correctly under Stata Version 7 and later
+d (though it remains a version 6 program) and fixes a bug in the
+d stratified Egger p-value.
+d 
+d Author: Thomas Steichen
+d Support: email  steichen@@triad.rr.com
+d 
+d Distribution-Date: 20040409
+f m\metabias.ado
+f m\metabias.hlp
+f m\metabias.dlg
+e
+S http://www.stata.com/stb/stb56
+N sbe20_1.pkg
+D  2 Apr 2008
+U 10
+d STB-56 sbe20_1.  Update of galbr
+d STB insert by Aurelio Tobias, Universidad Miguel Hernandez
+d               Alicante, Spain
+d Support:   bledatobias@@ctv.es
+d After installation, see help ^galbr^
+f g\galbr.ado
+f g\galbr.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/l
+N loevh.pkg
+D  6 Nov 2008
+U 11
+d 'LOEVH': module to compute Guttman errors and Loevinger H coefficients
+d 
+d LoevH computes the Loevinger H coefficients and the Guttman
+d errors  (observed and expected) for each pair of items, between
+d one given item and all the  others of a scale or among all the
+d possible pairs of items of a scale.
+d 
+d KW: Loevinger H coefficients
+d KW: Guttman errors
+d KW: scale validation
+d 
+d Requires: Stata version 7
+d 
+d Distribution-Date: 20070621
+d 
+d Author: Jean-Benoit Hardouin, University of Nantes, France
+d Support: email jean-benoit.hardouin@@univ-nantes.fr
+d 
+f l\loevh.ado
+f l\loevh.hlp
+f a\anaoption.ado
+f t\traces.ado
+f t\traces.hlp
+f g\gengroup.ado
+f g\gengroup.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/d
+N delta.pkg
+D 24 Nov 2008
+U 13
+d 'DELTA': module  to compute the Delta index of scale discrimination
+d 
+d  delta computes the generalized delta index of scale
+d discrimination developed by  Hankins (2007) based on the original
+d work of Ferguson (1949). This index measures the scale's
+d ability to  distinguish between individuals. A value of 1
+d indicates that the test  has maximal discrimination (all
+d possible scores occur with the same  frequency) and a value of 0
+d means  that the test has minimal  discrimination (all the
+d respondents have the same score).  A value of  0.9 results from a
+d set of scores that is normally distributed. A  value of  1 is
+d observed if the scores follow a uniform distribution. Individuals
+d with a missing  score are omitted.
+d 
+d KW: delta index
+d KW: psychometrics
+d KW: Cronbach alpha
+d KW: discrimination
+d 
+d Requires: Stata version 7
+d 
+d Distribution-Date: 20080312
+d 
+d Author: Jean-Benoit Hardouin , University of Nantes, France
+d Support: email jean-benoit.hardouin@@univ-nantes.fr
+d 
+f d\delta.ado
+f d\delta.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/m
+N metan.pkg
+D  3 Dec 2008
+U 15
+d 'METAN': module for fixed and random effects meta-analysis
+d 
+d These routines provide facilities to conduct meta-analyses of
+d data from more than one study and to graph the results. Either
+d binary (event) or continuous data from two groups may be combined
+d using the metan command. Additionally, intervention effect
+d estimates with corresponding standard errors or confidence
+d intervals may be meta-analysed. Recently added facilities include
+d by() processing and an update to Stata 9 graphics. This is an
+d updated version of metan as published in STB-44, authored by
+d Michael J Bradburn, Jonathan J Deeks, Douglas G Altman. The
+d package includes a command to produce funnel plots to assess
+d small study effects, and L'Abbe plots to examine whether the
+d assumption of a common odds ratio, risk ratio or risk difference
+d is reasonable. Also included is the metannt program for binary
+d data, which displays estimated intervention effects in terms of
+d the absolute reduction in risk and number needed to treat. A
+d description of available Stata meta-analysis commands may be
+d found at  http://www.stata.com/support/faqs/stat/meta.html.
+d 
+d KW: meta-analysis
+d KW: fixed effects
+d KW: random effects
+d KW: forest plot
+d KW: l'Abbe plot
+d 
+d Requires: Stata version 9 (version 7 for metan7)
+d 
+d Distribution-Date: 20081117
+d 
+d Author: Ross Harris, Department of Social Medicine, University of Bristol
+d Support: email ross.harris@@bristol.ac.uk
+d 
+d Author: Mike Bradburn, Centre for Statistics in Medicine, University of Oxford
+d Support: email
+d 
+d Author: Jon Deeks, Centre for Statistics in Medicine, University of Oxford
+d Support: email
+d 
+d Author: Roger Harbord, Department of Social Medicine, University of Bristol
+d Support: email
+d 
+d Author: Doug Altman, Centre for Statistics in Medicine, University of Oxford
+d Support: email
+d 
+d Author: Thomas Steichen, RJRT
+d Support: email
+d 
+d Author: Jonathan Sterne, Department of Social Medicine, University of Bristol
+d Support: email
+d 
+f m\metan.ado
+f m\metan.hlp
+f l\labbe.ado
+f l\labbe.hlp
+f l\labbe.dlg
+f m\metan7.ado
+f m\metan7.hlp
+f m\metan7.dlg
+f m\metannt.ado
+f m\metannt.hlp
+f m\metannt.dlg
+f i\i2ci.ado
+f m\metan_examples.ado
+e
+S http://fmwww.bc.edu/repec/bocode/m
+N msp.pkg
+D 11 Dec 2008
+U 16
+d 'MSP': module to perform the Mokken Scale Procedure
+d 
+d MSP implements the Mokken Scale Procedure defined by Hemker,
+d Sijtsma and Molenaar (1995). This procedure construct sub-scales
+d based  on Loevinger H coefficients computed by LoevH (q.v.). The
+d results  depend of a threshold "c" fixed by the user : the
+d authors of the procedure  recommend to use a c exceeding 0.3. The
+d kernel of the first sub-scale can be fixed.
+d 
+d KW: Mokken Scale Procedure
+d KW: MSP
+d KW: Loevinger H coefficients
+d KW: scale construction
+d 
+d Requires: Stata version 7
+d 
+d Distribution-Date: 20081108
+d 
+d Author: Jean-Benoit Hardouin, University of Nantes, France
+d Support: email jean-benoit.hardouin@@univ-nantes.fr
+d 
+f m\msp.ado
+f m\msp.hlp
+f l\loevh.ado
+f l\loevh.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/c
+N clv.pkg
+D 11 Dec 2008
+U 17
+d 'CLV': module to implement a clustering of variables around latent components
+d 
+d clv clusters variables around latent components. The variables
+d are  clustered by searching to minimize at each step the
+d decreasing of the T criterion  computed as the sum of the first
+d eigenvalues of the matrices of data of all the  clusters. A
+d hierarchical cluster analysis based on this criterion is
+d realized.  A consolidation procedure can be run in a second time,
+d which allows assigning  each variable to the more correlated
+d latent components. The procedure is  described by Vigneau and
+d Qannari (Communications in Statistics - Simulation and
+d Computation, 2003).
+d 
+d KW:  Clustering around latent components
+d KW: Varclus
+d KW: CLV
+d KW: unidimensionality
+d 
+d Requires: Stata version 8.0
+d 
+d Distribution-Date: 20061014
+d 
+d Author: Jean-Benoit Hardouin , University of Nantes, France
+d Support: email jean-benoit.hardouin@@univ-nantes.fr
+d 
+f c\clv.ado
+f c\clv.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/s
+N simirt.pkg
+D 11 Dec 2008
+U 18
+d 'SIMIRT': module to process data generated by IRT models
+d 
+d simirt allows creating a new dataset of  responses to items
+d simulated  by an unidimensional IRT model. The model can be
+d dichotomous (Rasch, OPLM,  Birnbaum, 3PLM, 4PLM, 5PAM) or
+d polytomous (Rating Scale Model-RSM). It is possible  to simulate
+d two sets of items linked, for each of them, to a specific latent
+d trait (which can be correlated). The Items Characteristic Curves
+d can be drawn.
+d 
+d KW: simulation
+d KW: Rasch model
+d KW: Birnbaum model
+d KW: OPLM
+d KW: ICC
+d KW: Rating Scale Model
+d 
+d Requires: Stata version 8
+d 
+d Distribution-Date: 20061022
+d 
+d Author: Jean-Benoit Hardouin, University of Nantes, France
+d Support: email jean-benoit.hardouin@@univ-nantes.fr
+d 
+f s\simirt.ado
+f s\simirt.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/e
+N elapse.pkg
+D 11 Dec 2008
+U 19
+d 'ELAPSE': module to calculate elapsed time in procedure
+d 
+d Elapse displays a string with the name of the operation,  if
+d specified, and the time elapsed between start_time and current
+d time.
+d 
+d Author: Fred Zimmerman, Stanford University
+d Support: email zimmer@@leland.Stanford.EDU
+d 
+d Distribution-Date: 20031221
+f e\elapse.ado
+f e\elapse.hlp
+e
+S http://fmwww.bc.edu/RePEc/bocode/i
+N iccconf.pkg
+D  5 Feb 2009
+U 20
+d 'ICCCONF': module to compute a confidence interval for an intraclass correlation (ICC)
+d 
+d iccconf is an immediate command that computes a confidence
+d interval for a single intraclass correlation (ICC).  The
+d procedure is based on Rosner's approach using the F-test.
+d 
+d KW: intra-class correlation
+d KW: confidence interval
+d 
+d Requires: Stata version 8
+d 
+d Distribution-Date: 20081119
+d 
+d Author: Paul F. Visintainer, Baystate Health System
+d Support: email visint46@@gmail.com
+d 
+f i\iccconf.ado
+f i\iccconf.hlp
+e
+S http://www.stata-journal.com/software/sj4-2
+N pr0012.pkg
+D 24 Feb 2009
+U 22
+d SJ4-2 pr0012.  Submenu and dialogs for meta-analysis commands
+d Submenu and dialogs for meta-analysis commands
+d by Thomas J. Steichen
+d Support:  steichen@@triad.rr.com
+d After installation, type help ^meta_dialog^
+f m\meta_dialog.hlp
+f f\funnel.dlg
+f g\galbr.dlg
+f l\labbe.dlg
+f m\metabias.dlg
+f m\metacum.dlg
+f m\meta.dlg
+f m\metafunnel.dlg
+f m\metainf.dlg
+f m\metan.dlg
+f m\metaninf.dlg
+f m\metannt.dlg
+f m\metap.dlg
+f m\metareg.dlg
+f m\metatrim.dlg
+e
+S http://www.stata-journal.com/software/sj8-4
+N sbe23_1.pkg
+D 24 Feb 2009
+U 23
+d SJ8-4 sbe23_1.  Update: Meta-regression in Stata (revised)
+d Update: Meta-regression in Stata (revised)
+d by Roger Harbord, Department of Social Medicine,
+d      University of Bristol, UK
+d    Julian Higgins, MRC Biostatistics Unit, Cambridge, UK
+d Support:  roger.harbord@@bristol.ac.uk
+d After installation, type help ^metareg^
+f m\metareg.ado
+f m\metareg_ll.ado
+f m\metareg_p.ado
+f m\metareg_pm.ado
+f m\metareg.hlp
+e
+S http://web.missouri.edu/~kolenikovs/stata
+N cfa1.pkg
+D 20 Mar 2009
+U 24
+d cfa1 -- a single factor confirmatory analysis model
+d 
+d Author: Stas Kolenikov, kolenikovs@missouri.edu
+d 
+d cfa1 fits the confirmatory analysis model by maximum likelihood.
+d The model is restricted to a single level single factor.
+f c\cfa1.ado
+f c\cfa1_lf.ado
+f c\cfa1.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/i
+N icc23.pkg
+D 26 Mar 2009
+U 25
+d 'ICC23': module that computes models 2 and 3 of the intra-class correlation
+d 
+d ICC23 computes the intra-class correlation for random effects
+d models 2 and 3,  as described by Shrout and Fleiss, 1979.
+d (-loneway- computes model 1).  The  module uses Stata’s repeated
+d measures ANOVA command to retrieve the appropriate  estimates and
+d degrees of freedom. Keywords: intra-class correlation, random
+d effects model, mixed effects model
+d 
+d 
+d Requires: Stata version 9
+d 
+d Distribution-Date: 20090325
+d 
+d Author: Paul F. Visintainer, Baystate Health System
+d Support: email visint46@@gmail.com
+d 
+d Author: Luis C.Orozco,  Facultad de Salud, Universidad Industrial de Santander, Colombia
+d Support: email  lcorovar@@gmail.com
+d 
+f i\icc23.ado
+f i\icc23.hlp
+e
+S http://www.stata.com/stb/stb35
+N sg65.pkg
+D 26 Mar 2009
+U 26
+d STB-35 sg65.  Computing intraclass correlations and large ANOVAs.
+d STB insert by John R. Gleason, Syracuse University.
+d Support:  73241.717@@compuserve.com
+d After installation, see help ^l1way^ and help ^iclassr2^.
+f i\iclassr.ado
+f i\iclassr.hlp
+f i\iclassr2.ado
+f i\iclassr2.hlp
+f l\l1way.ado
+f l\l1way.hlp
+e
+S http://www.stata.com/stb/stb56
+N sbe26_1.pkg
+D 20 Apr 2009
+U 27
+d STB-56 sbe26_1.  Update of metainf
+d STB insert by Aurelio Tobias, Universidad Miguel Hernandez
+d               Alicante, Spain
+d Support:   bledatobias@@ctv.es
+d After installation, see help ^metainf^
+f h\hplot.ado
+f h\hplot.hlp
+f m\metainf.ado
+f m\metainf.hlp
+e
+S http://www.stata.com/stb/stb61
+N sbe19_4.pkg
+D 20 Apr 2009
+U 28
+d STB-61 sbe19_4.  Update to metabias to work under version 7
+d STB insert by Thomas J. Steichen, RJRT
+d Support:  steicht@@rjrt.com
+d After installation, see help ^metabias^
+f m\metabias.ado
+f m\metabias.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/i
+N imputeitems.pkg
+D  5 May 2009
+U 29
+d 'IMPUTEITEMS': module to impute missing data of binary items
+d 
+d imputeitems imputes missing responses to binary items by
+d different ways:  Item Mean Substitution (IMS), Person Mean
+d Substitution (PMS), Corrected Item Mean Substiutution (CIM),
+d Interitem Correlation Substitution (ICS),  logistic model (LOG)
+d and Worst Case (WORST).
+d 
+d KW:    Item Response Theory
+d KW: Missing data
+d KW: Imputation
+d 
+d Requires: Stata version 9.0
+d 
+d Distribution-Date: 20081211
+d 
+d Author: Jean-Benoit Hardouin, University of Nantes, France
+d Support: email jean-benoit.hardouin@@univ-nantes.fr
+d 
+f i\imputeitems.ado
+f i\imputeitems.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/x
+N xsampsi.pkg
+D 16 Jul 2009
+U 30
+d 'XSAMPSI': module to calculate sample size for cross-over trials with continuous measures
+d 
+d This program will compute the required sample size for a simple
+d crossover trial, that is AB/BA, or two-period two-treatment
+d cross-over. It will estimate the power for a given sample size,
+d too.
+d 
+d Author: Jan Brogger, University of Bergen, Norway
+d Support: email jan.brogger@@med.uib.no
+d 
+d Distribution-Date: 20020131
+f x\xsampsi.ado
+f x\xsampsi.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/n
+N nct.pkg
+D 17 Jul 2009
+U 31
+d 'NCT': modules related to the noncentral t distribution
+d 
+d nct is a package of programs, all related to the noncentral t
+d distribution.   Each one-sided program computes a missing
+d parameter given the other parameters such that P(t<=t'| delta,
+d df) = p.  The  two-sided programs yield two-sided values from a
+d noncentral t, defined such that P(|t|<=t'| delta, df) = 1 - p.
+d The programs are: nctprob -- Cumulative non-central t
+d probabilities, p, nctinv  -- Inverse cumulative non-central t
+d values, t', nctncp  -- Noncentrality parameter of the non-central
+d t, delta,  nctn    -- Sample size for the cumulative non-central
+d t, df + 1,  nct2    -- 2-sided non-central t probabilities, p,
+d and  nct2inv -- Inverse 2-sided non-central t values, |t'|.
+d 
+d Author: Thomas Steichen
+d Support: email  steichen@@triad.rr.com
+d 
+d Distribution-Date: 20000609
+f n\nct.ado
+f n\nct.hlp
+f n\nct2.ado
+f n\nct2.hlp
+f n\nct2inv.ado
+f n\nct2inv.hlp
+f n\nctinv.ado
+f n\nctinv.hlp
+f n\nctn.ado
+f n\nctn.hlp
+f n\nctncp.ado
+f n\nctncp.hlp
+f n\nctprob.ado
+f n\nctprob.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/t
+N torumm.pkg
+D 20 Jul 2009
+U 32
+d 'TORUMM': module to produce data in RUMM format
+d 
+d torumm converts and formats Stata data into 3 files required to
+d run RUMM 2010.  RUMM 2010 (Rasch Unidimensional Measurement
+d Models) is program for Rasch analysis. torumm  will work with
+d Stata 6 and Stata 7 data.
+d 
+d Author: Fred Wolfe
+d Support: email fwolfe@@arthritis-research.org
+d 
+d Distribution-Date: 20000708
+f t\torumm.ado
+f t\torumm.hlp
+e
+S http://www.fss.uu.nl/soc/iscore/stata
+N dropvars.pkg
+D 20 Jul 2009
+U 33
+d ^dropvars^.  drops all existing variables in a list.
+d ^dropvars varlist^ is similar to ^drop varlist^, but warns if a
+d variable does not exists, rather than aborts.
+d 
+d Note that ^capture drop varlist^ either drops all variables or none.
+d 
+d ^dropvars varlist^ is equivalent to
+d 
+d   for var varlist: capture drop X
+d 
+d Author:  Jeroen Weesie, Dept of Sociology, Utrecht University (NL)
+d Support: email J.Weesie@@fss.uu.nl
+f d\dropvars.ado
+f d\dropvars.hlp
+e
+S http://fmwww.bc.edu/RePEc/bocode/l
+N listutil.pkg
+D 20 Jul 2009
+U 34
+d 'LISTUTIL': modules to manipulate lists of words
+d 
+d   These functions manipulate lists of words. For details, see the
+d help file.
+d 
+d Author: Nicholas J. Cox, University of Durham
+d Support: email  N.J.Cox@@durham.ac.uk
+d 
+d Distribution-Date: 20010523
+f a\alphlist.ado
+f a\alphlist.hlp
+f b\binolist.ado
+f b\binolist.hlp
+f b\bothlist.ado
+f b\bothlist.hlp
+f c\choplist.ado
+f c\choplist.hlp
+f c\collist.ado
+f c\collist.hlp
+f c\convlist.ado
+f c\convlist.hlp
+f c\cseplist.ado
+f c\cseplist.hlp
+f c\cvarlist.ado
+f c\cvarlist.hlp
+f d\dellist.ado
+f d\dellist.hlp
+f d\difflist.ado
+f d\difflist.hlp
+f e\eqlist.ado
+f e\eqlist.hlp
+f f\fmtlist.ado
+f f\fmtlist.hlp
+f i\inslist.ado
+f i\inslist.hlp
+f j\joinlist.ado
+f j\joinlist.hlp
+f l\lclist.ado
+f l\lclist.hlp
+f m\maplist.ado
+f m\maplist.hlp
+f m\mnthlist.ado
+f m\mnthlist.hlp
+f p\poslist.ado
+f p\poslist.hlp
+f p\postlist.ado
+f p\postlist.hlp
+f p\prelist.ado
+f p\prelist.hlp
+f p\prodlist.ado
+f p\prodlist.hlp
+f r\replist.ado
+f r\replist.hlp
+f r\revlist.ado
+f r\revlist.hlp
+f r\rotlist.ado
+f r\rotlist.hlp
+f s\sellist.ado
+f s\sellist.hlp
+f s\seqlist.ado
+f s\seqlist.hlp
+f s\sortlist.ado
+f s\sortlist.hlp
+f s\sublist.ado
+f s\sublist.hlp
+f s\sumlist.ado
+f s\sumlist.hlp
+f t\takelist.ado
+f t\takelist.hlp
+f t\trnclist.ado
+f t\trnclist.hlp
+f u\uclist.ado
+f u\uclist.hlp
+f u\uniqlist.ado
+f u\uniqlist.hlp
+f v\varflist.ado
+f v\varflist.hlp
+f v\vectlist.ado
+f v\vectlist.hlp
+f w\wclist.ado
+f w\wclist.hlp
+f x\xorlist.ado
+f x\xorlist.hlp
+f l\listutil.hlp
+e
+S http://www.fss.uu.nl/soc/iscore/stata
+N listblck.pkg
+D 20 Jul 2009
+U 35
+d ^listblck^.  variant of ^list^ that "wraps variables".
+d ^listblck^ is that wraps variables, not observations. Thus, ^listblck^
+d displays as many variables as fit on the screen (listblck is ^display^
+d ^linesize^ sensitive) for all selected obs, then it displays a second
+d block of variables etc. This is especially useful if the number of
+d observations to be listed is small. See ^listby^ as an application.
+d 
+d Author:  Jeroen Weesie, Dept of Sociology, Utrecht University (NL)
+d Support: email J.Weesie@@fss.uu.nl
+f l\listblck.ado
+f l\listblck.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/s
+N saswrapper.pkg
+D 22 Nov 2009
+U 37
+d 'SASWRAPPER': module to run a SAS program from within Stata
+d 
+d saswrapper runs a SAS program in batch and prints the output in
+d the Stata results window/log file.   This usually occurs by
+d specifying a SAS program file after using, but saswrapper can
+d also run   SAS code specified by the pre_sas_prog() and/or
+d post_sas_prog() options.  By default, saswrapper  will save the
+d current data in memory using savasas and make it available in
+d SAS's WORK library.  If  that is not desired, use the nodata
+d option.  The usesas option tells saswrapper to load the  last SAS
+d dataset created in the WORK library by the submitted SAS program
+d into Stata using the SAVASTATA SAS macro.
+d 
+d KW: SAS
+d KW: Stata
+d 
+d Requires: Stata version 8.0
+d 
+d Distribution-Date: 20090507
+d 
+d Author: Dan Blanchette, Center of Entrepreneurship and Innovation, Duke University's Fuqua School of Business
+d Support: email dan.blanchette@@duke.edu
+d 
+f s\saswrapper.ado
+f s\saswrapper.hlp
+f u\usesas.ado
+f u\usesas.hlp
+f s\savasas.ado
+f s\savasas.hlp
+f u\usesasdel.ado
+f s\sasexe.ado
+f a\adoedit.ado
+f a\adoedit.hlp
+f t\tmpdir.ado
+f t\tmpdir.hlp
+f s\shortdir.ado
+f s\shortdir.hlp
+f c\confirmdir.ado
+f c\confirmdir.hlp
+e
+S http://www.stata-journal.com/software/sj4-1
+N st0057.pkg
+D 26 Nov 2009
+U 38
+d SJ4-1 st0057.  FIML estimation of an endogenous switching ...
+d FIML estimation of an endogenous switching model for count data
+d by Alfonso Miranda, Economics Department, Warwick University, UK
+d Support:  Alfonso.Miranda-Caso-Luengo@@warwick.ac.uk
+d After installation, type help ^espoisson^
+f e\espoisson.ado
+f e\espoisson.hlp
+f e\espoisson_ll.ado
+f e\espoisson_p.ado
+f e\exspoisson.ado
+f e\exspoisson_ll.ado
+f e\exspoisson_p.ado
+f g\ghquad.ado
+f h\hermite.ado
+f x\xcolnames.ado
+e
+S http://fmwww.bc.edu/repec/bocode/e
+N estout.pkg
+D  5 Dec 2009
+U 39
+d 'ESTOUT': module to make regression tables
+d 
+d estout produces a table of regression results from one or several
+d models for use with spreadsheets, LaTeX, HTML, or a
+d word-processor table. eststo stores a quick copy of the active
+d estimation results for later tabulation. esttab is a wrapper for
+d estout. It displays a pretty looking publication-style regression
+d table without much typing. estadd adds additional results to the
+d e()-returns for one or several models previously fitted and
+d stored. This package subsumes the previously circulated esto,
+d esta, estadd,  and estadd_plus. An earlier version of estout is
+d available  as estout1.
+d 
+d KW: estimates
+d KW: LaTeX
+d KW: HTML
+d KW: word processor
+d KW: output
+d 
+d Requires: Stata version 8.2
+d 
+d Distribution-Date: 20091012
+d 
+d Author: Ben Jann, ETH Zurich
+d Support: email ben.jann@@soz.gess.ethz.ch
+d 
+f _\_eststo.ado
+f _\_eststo.hlp
+f e\estadd.ado
+f e\estadd.hlp
+f e\estout.ado
+f e\estout.hlp
+f e\eststo.ado
+f e\eststo.hlp
+f e\estpost.ado
+f e\estpost.hlp
+f e\esttab.ado
+f e\esttab.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/o
+N outreg2.pkg
+D  5 Dec 2009
+U 40
+d 'OUTREG2': module to arrange regression outputs into an illustrative table
+d 
+d outreg2 provides a fast and easy way to produce an illustrative
+d table  of regression outputs. The regression outputs are produced
+d piecemeal and are  difficult to compare without some type of
+d rearrangement. outreg2  automates this process by concatenating
+d the successive regression ouputs in a  vertical format. The
+d resulting table is saved to the disk in ASCII  format, which can
+d be read by other programs. outreg2 thus facilitates  the
+d convertion of regression outputs to a standard format suitable
+d for  inclusion in a scholarly publication. The functionality of
+d outreg2 is based on the earlier package outreg,  by John Luke
+d Gallup. Unlike outreg, outreg2 is capable of writing LaTeX-format
+d tables, as well as ASCII, MS Word and MS Excel.
+d 
+d KW: regression
+d KW: output
+d KW: tables
+d KW: tab-delimited output
+d KW: LaTeX
+d KW: Word
+d KW: Excel
+d 
+d Requires: Stata version 7
+d 
+d Distribution-Date: 20091118
+d 
+d Author: Roy Wada
+d Support: email roywada@@hotmail.com
+d 
+f o\outreg2.ado
+f o\outreg2_prf.ado
+f o\outreg2.hlp
+f s\shellout.ado
+f s\shellout.hlp
+f s\seeout.ado
+f s\seeout.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/r
+N raschpower.pkg
+D 27 Jan 2010
+U 41
+d 'RASCHPOWER': module to estimate power of the Wald test in order to compare the means of the latent trait in two groups of individuals
+d 
+d raschpower allows estimating the power of the Wald test comparing
+d the means of two groups of patients in the context of the Rasch
+d model. The estimation is based on  the estimation of the variance
+d of the difference of the means based on the Cramer-Rao lower
+d bound.
+d 
+d KW: Rasch test
+d KW: power
+d KW: Wald test
+d 
+d Requires: Stata version 11
+d 
+d Distribution-Date: 20100126
+d 
+d Author: Jean-Benoit Hardouin , University of Nantes, France
+d Support: email jean-benoit.hardouin@@univ-nantes.fr
+d 
+f r\raschpower.ado
+f r\raschpower.hlp
+e
+S http://www.stata-journal.com/production
+N sjlatex.pkg
+D 24 Feb 2010
+U 42
+d sjlatex:  LaTeX files for the Stata Journal
+d ^sjlatex^ contains the LaTeX document class and packages for the
+d Stata Journal.
+d 
+d The ancillary files should be installed using the ^sjlatex^ command
+d from within Stata.
+d 
+d Distribution-Date: 18feb2010
+f s\sjlatex.ado
+f s\sjlatex.hlp
+f s\sjlog_7.ado
+f s\sjlog.ado
+f s\sjlog.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/c
+N checkfor2.pkg
+D 11 Apr 2010
+U 43
+d 'CHECKFOR2': module to check whether a variable exists or not in a dataset
+d 
+d checkfor2 is a routine to check for existence of a list of
+d variables within a (usually big) data set. checkfor2 searchs
+d through the data whether the variable exists.
+d 
+d KW: data management
+d 
+d Requires: Stata version 8
+d 
+d Distribution-Date: 20050926
+d 
+d Author: Amadou Bassirou Diallo, AFTPM, The World Bank
+d Support: email adiallo5@@worldbank.org
+d 
+d Author: Jean-Benoit Hardouin , University of Nantes, France
+d Support: email jean-benoit.hardouin@@univ-nantes.fr
+d 
+f c\checkfor2.ado
+f c\checkfor2.hlp
+f i\isvar.ado
+f i\isvar.hlp
+e
+S http://www.stata.com/stb/stb46
+N gr33.pkg
+D  6 May 2010
+U 44
+d STB-46 gr33.  Violin plots.
+d STB insert by Thomas J. Steichen, RJRT.
+d Support:  steicht@@rjrt.com
+d After installation, see help ^violin^.
+f v\violin.ado
+f v\violin.hlp
+e
+S http://www.stata.com/stb/stb47
+N sg103.pkg
+D 31 May 2010
+U 45
+d STB-47 sg103.  Within subjects (repeated measures) ANOVA, between subj.
+d STB insert by John R. Gleason, Syracuse University.
+d Support: loeslrg@@ican.net
+d After installation, see help ^wsanova^.
+f w\wsanova.ado
+f w\wsanova.hlp
+e
+S http://www.stata-journal.com/software/sj9-3
+N st0169.pkg
+D  7 Jun 2010
+U 46
+d SJ9-3 st0169.  Confirmatory factor analysis
+d Confirmatory factor analysis
+d by Stanislav Kolenikov, University of Missouri, Columbia, USA
+d Support:  kolenikovs@@missouri.edu, skolenik@@gmail.com
+d After installation, type help ^confa^
+f c\confa.ado
+f c\confa.sthlp
+f c\confa_lf.ado
+f c\confa_lfm.ado
+f c\confa.mata
+f c\confa_p.ado
+f c\confa_estat.ado
+f c\confa_estat.sthlp
+f b\bollenstine.ado
+f b\bollenstine.sthlp
+f l\lconfa.mlib
+e
+S http://www.stata.com/stb/stb55
+N sbe33.pkg
+D 25 May 2011
+U 47
+d STB-55 sbe33.  Comparing several methods of measuring the same quantity
+d STB insert by  Paul Seed, GKT School of Medicine, King's London, UK
+d Support:   paul.seed@@kcl.ac.uk
+d After installation, see help ^baplot^, help ^sdpair^, help ^bamat^,
+d help ^bagroup^
+f b\bagroup.ado
+f b\bagroup.hlp
+f b\bamat.ado
+f b\bamat.hlp
+f b\baplot.ado
+f b\baplot.hlp
+f n\nicenum.ado
+f s\sdpair.ado
+f s\sdpair.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/l
+N log2html.pkg
+D 11 Oct 2012
+U 49
+d 'LOG2HTML': module to produce HTML log files
+d 
+d log2html translates translates Stata's standard SMCL log files to
+d HTML, the language used for web pages. log2html provides greater
+d formatting flexibility than the built-in but undocumented log
+d html, providing preformatted schemes and support for CSS
+d (Cascading Style Sheets). Stata 8 is required. (log2html7 is
+d available for Stata 7.)
+d 
+d KW: log
+d KW: web
+d KW: html
+d KW: translate
+d KW: SMCL
+d KW: CSS
+d 
+d Requires: Stata version 8.0 (7.0 for log2html7)
+d 
+d 
+d Author: Christopher F Baum, Boston College
+d Support: email  baum@@bc.edu
+d 
+d Author: Nicholas J. Cox, Durham University
+d Support: email  N.J.Cox@@durham.ac.uk
+d 
+d Author: Bill Rising, StataCorp
+d Support: email  brising@@stata.com
+d 
+d Distribution-Date: 20080731
+f l\log2html.ado
+f l\log2html.hlp
+f l\log2html7.ado
+f l\log2html7.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/l
+N logout.pkg
+D 11 Oct 2012
+U 50
+d 'LOGOUT': module to convert log or ASCII files into various output formats
+d 
+d logout provides a fast and easy way to convert log or ASCII files
+d into various output formats compatible with Word, Excel, LaTeX,
+d or Stata datafile. Can be used as a prefix or by itself after a
+d log file has been created. caplog provides a fast and easy way to
+d capture text-based log file, possibly for use with logout or
+d dataout.
+d 
+d KW: log file
+d KW: table
+d KW: tab
+d KW: summary
+d KW: output
+d KW: LaTeX
+d KW: Word
+d KW: Excel
+d KW: dataout
+d 
+d Requires: Stata version 7.0
+d 
+d Distribution-Date: 20091106
+d 
+d Author: Roy Wada
+d Support: email roywada@@hotmail.com
+d 
+f l\logout.ado
+f l\logout.hlp
+f c\caplog.ado
+f c\caplog.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/g
+N gllamm.pkg
+D 19 Nov 2012
+U 51
+d 'GLLAMM': program to fit generalised linear latent and mixed models
+d 
+d gllamm fits generalized linear latent and mixed models. These
+d models  include Multilevel generalized linear regression models
+d (extensions of the simple random intercept models  that may be
+d fitted in Stata using xtreg, xtlogit, xtpois to include
+d multilevel and random coefficient models), Multilevel factor
+d models and Multilevel structural equation models. The latent
+d variables (or random effects) can be assumed to have a
+d multivariate normal distribution or to be discrete allowing
+d nonparametric maximum likelihood estimation. The common links and
+d families of generalized linear models are available and responses
+d can be of mixed type including continuous, censored, discrete,
+d dichotomous, ordered categorical and unordered categorical. The
+d version of gllamm (gllamm6) described in  STB-53, (sg129, p47-57)
+d does not incorporate many of the features outlined above. This is
+d version 2.3.20 of the software (Sep 2011). A manual in PDF form
+d is available from the SSC archive via web browser.
+d 
+d KW: multilevel models
+d KW: mixed models
+d KW: random coefficients
+d KW: latent variable models
+d 
+d Requires: Stata version 7.0
+d 
+d 
+d Author: Sophia Rabe-Hesketh, University of California - Berkeley
+d Support: email sophiarh@@berkeley.edu
+d 
+d Distribution-Date: 20110911
+d 
+f g\gllamm.ado
+f g\gllamm.hlp
+f e\eq_g.hlp
+f g\gllam_ll.ado
+f g\gllapred.ado
+f g\gllapred.hlp
+f g\gllarob.ado
+f g\gllasim.ado
+f g\gllasim.hlp
+f g\gllas_yu.ado
+f r\remcor.ado
+e
+S http://fmwww.bc.edu/repec/bocode/h
+N hotdeck.pkg
+D 30 Jan 2013
+U 52
+d 'HOTDECK': module to impute missing values using the hotdeck method
+d 
+d hotdeck replaces missing values for the variable indicated by its
+d argument.  It should be used within a multiple imputation
+d sequence since missing values  are imputed stochastically rather
+d than deterministically. The nmiss missing  values in each stratum
+d of the data described by the `by' option are replaced  by values
+d sampled from the nobs observed values in the same stratum. The
+d approximate Bayesian bootstrap method of Rubin and Scheker is
+d used; first a  bootstrap sample of nobs observations is sampled
+d with replacement from the  observed values, and the nmiss missing
+d values are sampled at random (again with replacement) from this
+d bootstrap sample. If a file is specified in a using clause, the
+d modified file is written to disk and the existing  data in memory
+d are unchanged. Otherwise the data in memory are modified. This is
+d version 1.65 of the software, requiring Stata v9. hotdeck6 may be
+d used in earlier versions of Stata.
+d 
+d Author: Adrian Mander, MRC Biostatistics Unit
+d Support: email Adrian.Mander@@mrc-hnr.cam.ac.uk
+d 
+d Author: David Clayton
+d Support: email david.clayton@@mrc-bsu.cam.ac.uk
+d 
+d Distribution-Date: 20070902
+f h\hotdeck.ado
+f h\hotdeck.hlp
+f h\hotdeck6.ado
+f h\hotdeck6.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/f
+N fitstat_ers.pkg
+D  6 May 2013
+U 53
+d 'FITSTAT_ERS': module to compute goodness of fit statistics for Rasch model
+d 
+d  fitstat_ers computes outfit and infit statistics for the
+d conditional maximum likelihood (cml) Rasch model, using formulas
+d outlined in the Linacre and Wright (1994). These fit statistics
+d differ from those computed by the –raschtest-, which are
+d normalized to be approximately normal random variates. These
+d statistics are not normalized.
+d 
+d KW: Rasch model
+d KW: goodness of fit
+d 
+d Requires: Stata version 9 and gammasym (q.v.) To output tables of statistics, xml_tab.ado and/or outtable.ado are required.
+d 
+d Distribution-Date: 20111222
+d 
+d Author: Christian Gregory, Economic Research Service, USDA
+d Support: email cgregory@@ers.usda.gov
+d 
+f f\fitstat_ers.ado
+f f\fitstat_ers.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/x
+N xml_tab.pkg
+D  6 May 2013
+U 54
+d 'XML_TAB': module to save results in Excel XML format
+d 
+d xml_tab saves Stata output directly into XML file that could be
+d opened with Microsoft Excel or OpenOffice Calc. The program is
+d relatively flexible and produces print-ready tables in Excel or
+d Calc. xml_tab allows users to apply different formats to the
+d elements of the output table and essentially do everything MS
+d Excel or OO Calc can do in terms of formatting from within Stata. d
+d KW: XML
+d KW: results
+d KW: output
+d KW: Excel
+d 
+d Requires: Stata version 8 and MS Excel (EN) 2002 for Windows, MS Excel 2004 for Mac, or OpenOffice Calc
+d 
+d Distribution-Date: 20080625
+d 
+d Author: Michael Lokshin, World Bank
+d Support: email Mlokshin@@worldbank.org
+d 
+d Author: Zurab Sajaia, World Bank
+d Support: email
+d 
+f x\xml_tab.ado
+f x\xml_tab.hlp
+e
+S http://fmwww.bc.edu/repec/bocode/g
+N gengroup.pkg
+D  6 May 2013
+U 55
+d 'GENGROUP': module to produce groups of  individuals
+d 
+d  gengroup creates groups of individuals by using the values of an
+d   ordinal variable. The module creates groups of individuals by
+d recoding several  adjacent values of the ordinal variable, until
+d obtaining groups with more than  individuals than the number
+d defined in the minsize option.
+d 
+d KW: data management
+d KW: groups
+d KW: ordinal
+d 
+d Requires: Stata version 7.0
+d 
+d Distribution-Date: 20101208
+d 
+d Author: Jean-Benoit Hardouin, University of Nantes, France
+d Support: email jean-benoit.hardouin@@univ-nantes.fr
+d 
+f g\gengroup.ado
+f g\gengroup.hlp
+e
+S http://fmwww.bc.edu/RePEc/bocode/b
+N batplot.pkg
+D 18 Sep 2013
+U 56
+d 'BATPLOT': module to produce Bland-Altman plots accounting for trend
+d 
+d  The normal Bland-Altman plot is between the difference of paired
+d variables versus  their average. This version uses a regression
+d between the difference and the  average and then alters the
+d limits of agreement accordingly. This is particularly  useful
+d when the two variables might be measured on different scales and
+d hence a  straight conversion factor would recalibrate the two
+d variables.
+d 
+d KW: plot
+d KW: Bland-Altman
+d KW: difference
+d KW: paired variables
+d 
+d Requires: Stata version 9.2
+d 
+d Distribution-Date: 20120617
+d 
+d Author: Adrian Mander
+d Support: email Adrian.Mander@@mrc-hnr.cam.ac.uk
+d 
+f b\batplot.ado
+f b\batplot.hlp
+e
+S http://www.indiana.edu/~jslsoc/stata
+N spost9_ado.pkg
+D 18 Oct 2013
+U 57
+d spost9_ado | Stata 9-13 commands for the post-estimation interpretation
+d Distribution-date: 05Aug2013
+d of regression models. Use package spostado.pkg for Stata 8.
+d Based on Long & Freese - Regression Models for Categorical Dependent
+d Variables Using Stata. Second Edition.
+d Support www.indiana.edu/~jslsoc/spost.htm
+d Scott Long & Jeremy Freese (spostsup@@indiana.edu)
+f _\_get_mlogit_bv.ado
+f _\_get_mlogit_bvecv.ado
+f _\_peabbv.ado
+f _\_pebase.ado
+f _\_pebase.hlp
+f _\_pecats.ado
+f _\_pecats.hlp
+f _\_peciboot.ado
+f _\_peciboot.hlp
+f _\_pecidelta.ado
+f _\_pecidelta.hlp
+f _\_peciml.ado
+f _\_pecmdcheck.ado
+f _\_pecollect.ado
+f _\_pecollect.hlp
+f _\_pedum.ado
+f _\_pedum.hlp
+f _\_peife.ado
+f _\_peife.hlp
+f _\_pemarg.ado
+f _\_pemarg.hlp
+f _\_penocon.ado
+f _\_penocon.hlp
+f _\_pepred.ado
+f _\_pepred.hlp
+f _\_perhs.ado
+f _\_perhs.hlp
+f _\_pesum.ado
+f _\_pesum.hlp
+f _\_petrap.ado
+f _\_petrap.hlp
+f _\_peunvec.ado
+f _\_peunvec.hlp
+f _\_pexstring.ado
+f a\asprvalue.ado
+f a\asprvalue.hlp
+f b\brant.ado
+f b\brant.hlp
+f c\case2alt.ado
+f c\case2alt.hlp
+f c\countfit.ado
+f c\countfit.hlp
+f f\fitstat.ado
+f f\fitstat.hlp
+f l\leastlikely.ado
+f l\leastlikely.hlp
+f l\listcoef.ado
+f l\listcoef.hlp
+f m\misschk.ado
+f m\misschk.sthlp
+f m\mlogplot.ado
+f m\mlogplot.hlp
+f m\mlogtest.ado
+f m\mlogtest.sthlp
+f m\mlogview.ado
+f m\mlogview.hlp
+f m\mvtab1.ado
+f m\mvtab1.hlp
+f n\nmlab.ado
+f n\nmlab.hlp
+f p\praccum.ado
+f p\praccum.hlp
+f p\prchange.ado
+f p\prchange.hlp
+f p\prcounts.ado
+f p\prcounts.hlp
+f p\prdc.ado
+f p\prdc.hlp
+f p\prgen.ado
+f p\prgen.hlp
+f p\prtab.ado
+f p\prtab.hlp
+f p\prvalue.ado
+f p\prvalue.hlp
+f p\prwhich.ado
+f s\spex.ado
+f s\spex.hlp
+f s\spost.hlp
+f s\spost_footer.ihlp
+f s\spostupdate.ado
+f v\vardesc.ado
+f v\vardesc.hlp
+f x\xpost.ado
+e
diff --git a/Modules/ado/plus/c/caplog.ado b/Modules/ado/plus/c/caplog.ado
new file mode 100644
index 0000000..2087f10
--- /dev/null
+++ b/Modules/ado/plus/c/caplog.ado
@@ -0,0 +1,235 @@
+
+*! version 1.0.2 13oct2009 caplog by roywada@hotmail.com
+*! captures a log file, possibly for use with logout or dataout
+
+program define caplog
+version 6
+
+local logfile : log
+
+version 7
+
+* invisible to Stata 7
+local Version7 ""
+cap local Version7 `c(stata_version)'
+
+if "`Version7'"=="" {
+	* it is version 7
+	local bind ""
+	*noi di in yel "limited functions under Stata 7"
+}
+else if `Version7'>=8.2 {
+	version 8.2
+	local bind "bind"
+}
+
+*qui log query
+*if `"`r(status)'"'=="on" {
+*	qui log close
+*	local filename `"`r(filename)'"'
+*}
+
+if `"`logfile'"'~="" {
+	di ""
+	qui log close
+	local filename `"`logfile'"'
+}
+
+* embbed to avoid log being open
+_caplog `0'
+
+cap log close
+
+*** c_locals coming back
+* clickables
+if "`tempfile'"~="tempfile" {
+	if "`smcl'"=="" {
+		local cl_text `"{browse `"`using1'"'}"'
+		noi di as txt `"`cl_text'"'
+	}
+	else {
+		local cl_text `"{stata `"view `using1'"':`using1'}"'
+		noi di as txt `"`cl_text'"'
+	}
+}
+
+cap log close
+
+*if `"`filename'"'~="" {
+*	log using `"`filename'"', append
+*}
+
+end
+
+
+********************************************************************************************
+
+
+program define _caplog
+version 7
+
+local Version7 ""
+cap local Version7 `c(stata_version)'
+
+if "`Version7'"=="" {
+	* it is version 7
+	local bind ""
+	*noi di in yel "limited functions under Stata 7"
+}
+else if `Version7'>=8.2 {
+	version 8.2
+	local bind "bind"
+}
+
+* encase the colon in file name in quotes, avoiding string function length limits
+
+local behind `"`0'"'
+local 0 ""
+gettoken front behind: behind, parse(" ,")
+local 0 ""
+local done 0
+while `"`front'"'~="" & `done'==0 {
+	if `"`front'"'=="using" {
+		
+		gettoken rest behind: behind, parse(" ,")
+		* strip off quotes
+		gettoken first second: rest, parse(" ")
+		cap local rest: list clean local(rest)
+		
+		* take off colon at the end
+		local goldfish ""
+		if index(`"`rest'"',":")~=0 {
+			local end=substr(`"`rest'"',length(`"`rest'"'),length(`"`rest'"'))
+			if "`end'"==":" {
+				local rest=substr(`"`rest'"',1,`=length(`"`rest'"')-1')
+				local goldfish " : "
+			}
+		}
+		
+		* colon reattached with a space at the end
+		* .txt attached here, SMCL TO BE FIXED LATER
+		local rabbit `"""'
+		if index(`"`rest'"', ".")==0 {
+			local using `"`rabbit'`rest'.txt`rabbit'`goldfish'"'
+		}
+		else {
+			local using `"`rabbit'`rest'`rabbit'`goldfish'"'
+		}
+		local 0 `"`0' using `using' `behind'"'
+		local done 1
+	}
+	else {
+		local 0 `"`0' `front'"'
+		gettoken front behind: behind, parse(" ,")
+	}
+}
+
+
+gettoken first second : 0, parse(":") `bind' match(par) quotes
+local 0 `"`first'"'
+while `"`first'"'~=":" & `"`first'"'~="" {
+	gettoken first second : second, parse(":") `bind' match(par) quotes
+}
+if `"`0'"'==":" {
+	* colon only when shorthand combined with prefix
+	local 0
+}
+else {
+	local _0 `"`0'"'
+}
+
+*** shorthand syntax if [using] is missing
+
+syntax using/ [, replace append tempfile text smcl subspace]
+
+if "`smcl'"=="smcl" {
+	if index(`"`using'"', ".txt")~=0 {
+		local temp=substr(`"`using'"',1,length(`"`using'"')-4)
+		local using `"`temp'.smcl"'
+	}
+}
+
+if "`text'"~="" & "`smcl'"~="" {
+	di "cannot choose both {opt text} and {opt smcl}"
+	exit 198
+}
+
+if "`text'"=="" & "`smcl'"=="" {
+	local text "text"
+}
+
+
+cap confirm file `"`using'"'
+if !_rc & "`replace'"~="replace" & "`append'"~="append" {
+	* it exists
+	noi di in red `"`using' exists; specify {opt replace} or {opt append}"'
+	exit 198
+}
+
+* goes with `second'
+if `"`second'"'~="" {
+	local _colon ":"
+}
+
+qui {
+	if "`subspace'"=="subspace" {
+		* fix the gaps in the value labels
+		ds8
+		foreach var in `r(varlist)'{
+			local temp : var label `var'
+			local temp = subinstr(`"`temp'"'," ","_",.)
+			label var `var' `"`temp'"'
+		}
+	}
+}
+
+	* regular stuff
+	if `"`using'"'~="" {
+		* prefix use using file
+		qui log using `"`using'"', `replace' `append' `text' `smcl'
+		`second'
+	}
+	else {
+		* prefix use temp file
+		qui log using `"`using'"', `replace' `append' `text' `smcl'
+		`second'
+	}
+
+* clickables
+c_local smcl "`smcl'"
+c_local using1 `"`using'"'
+c_local tempfile `"`tempfile'"'
+
+end
+
+
+********************************************************************************************
+
+
+*** ripped from outreg2 Mar 2009
+program define ds8
+	* get you the list of variable like -ds- does for version 8
+	version 7.0
+	qui ds
+	if "`r(varlist)'"=="" {
+		local dsVarlist ""
+		foreach var of varlist _all {
+			local dsVarlist "`dsVarlist' `var'"
+		}
+		c_local dsVarlist `dsVarlist'
+	}
+	else {
+		c_local dsVarlist `r(varlist)'
+	}
+end
+
+
+
+
+/*
+* version 1.0.1 May2009 caplog by roywada@hotmail.com
+smcl accepted
+version control fixed
+
+1.0.2 close the log file at the end to avoid the possibility of it being left open
+
diff --git a/Modules/ado/plus/c/caplog.hlp b/Modules/ado/plus/c/caplog.hlp
new file mode 100644
index 0000000..00a70e0
--- /dev/null
+++ b/Modules/ado/plus/c/caplog.hlp
@@ -0,0 +1,64 @@
+{smcl}
+{* 13oct2009}{...}
+{cmd:help caplog}
+
+{hline}
+
+{title:Title}
+
+{p2colset 5 16 22 2}{...}
+{p2col :{hi:  caplog} {hline 2}}captures a ASCII log file (for use with {cmd:{help logout}}){p_end}
+
+{marker s_Syntax}
+{title:Syntax}
+
+{p 4 4 6}
+{cmdab:caplog} using filename [, {it:options}] : command
+
+{marker s_Description}
+{title:Description}
+
+{p 4 4 6}
+{cmd:caplog} provides a fast and easy way to capture text-based log file, possibly for use with 
+{cmd:{help logout}}. The default is text log files.
+
+
+{title:Command}
+
+{p 4 12 6}Any command accepted, i.e. { help estimation commands}, tabulation, summary, descrition, etc.
+
+
+{marker s_Options}
+{title:Options}
+
+{dlgtab:Main}
+
+{p 4 12 6}{opt replace} Replace pre-exiting log files.{p_end}
+
+{p 4 12 6}{opt append} Append. {p_end}
+
+{p 4 12 6}{opt smcl} Save smcl file instead of text file. {p_end}
+
+
+{marker s_0}
+{title:Examples}
+
+
+{p 4 4 6}{cmd:* table}{p_end}
+{p 4 4 6}{stata sysuse auto, clear}{p_end}
+{p 4 4 6}{stata `"caplog using mystuff.txt, replace: table trunk rep78 , c(n mpg mean mpg sd mpg median mpg)"'}{p_end}
+{p 4 4 6}{stata `"caplog using mystuff.txt, append: table trunk rep78 , c(n mpg mean mpg sd mpg median mpg)"'}{p_end}
+
+
+{title:Remarks}
+
+{p 4 12 6}PREVIOUSLY OPENED LOG FILES WILL BE CLOSED BY CAPLOG.{p_end}
+{p 4 12 6}version 7: do not include colon characters (:) in the file path. Use -cd- instead.{p_end}
+
+
+{title:Author}
+
+{p 4 4 6}Roy Wada{p_end}
+{p 4 4 6}roywada@hotmail.com{p_end}
+
+
diff --git a/Modules/ado/plus/c/case2alt.ado b/Modules/ado/plus/c/case2alt.ado
new file mode 100644
index 0000000..ef418ce
--- /dev/null
+++ b/Modules/ado/plus/c/case2alt.ado
@@ -0,0 +1,167 @@
+*! 1.0.1 - allow either y() or choice(); yrank() or rank()
+* 1.0.0 - revise option names: case->casevar; id->case
+* 0.2.4 - small text formatting error
+* 0.2.3 - change _optnum to altnum and add as option
+* 0.2.2 - allow id() to specify new variable instead of using _id - 15Jul2005
+* 0.2.1 - change specification of csv from varlist to case() - 11Jul2005
+
+program define case2alt
+
+    version 9
+
+    syntax , [y(varname numeric) YRank(name) case(name) ///
+        Generate(name) REplace CASEVars(namelist) Alt(namelist) noNames altnum(name) ///
+        Choice(name) Rank(name)] // allow choice() and rank() to sub for y() and yrank()
+
+    ** CHANGE 9/8/05: allow choice() instead of y() and allow rank() instead of yrank()
+    if "`choice'" != "" {
+        local y "`choice'"
+        local choice ""
+    }
+
+    if "`rank'" != "" {
+        local yrank "`rank'"
+        local rank ""
+    }
+
+
+    * either y() or yrank() must be specified
+    if "`y'" == "" & "`yrank'" == "" {
+        di as err "option y() or yrank() must be specified"
+        exit 198
+    }
+
+    * figure out if rankdata is being specified
+    local rankdata "yes"
+    if "`y'" != "" {
+        local rankdata "no"
+    }
+
+    if "`rankdata'" == "no" & "`generate'" == "" & "`replace'" == "" {
+        di as txt "(note: " as res "choice " as txt "used for outcome since no variable specified by gen())"
+        confirm new variable choice
+        local generate "choice"
+    }
+    local choice "`generate'"
+
+    if "`case'" == "" {
+        di as txt "(note: variable " as res "_id" as txt " used since case() not specified)"
+        confirm new variable _id
+        gen _id = _n
+        local case "_id"
+    }
+
+    if "`altnum'" == "" {
+        di as txt "(note: variable " as res "_altnum" as txt " used since altnum() not specified)"
+        confirm new variable _altnum
+        local altnum "_altnum"
+    }
+
+    capture confirm variable `case'
+    if _rc != 0 {
+        gen `case' = _n
+    }
+
+
+    if "`rankdata'" == "no" {
+        _pecats `y'
+
+        local catval = r(catvals)
+        local catnms = r(catnms)
+        local numcats = r(numcats)
+
+        forvalues i = 1(1)`numcats' {
+            local y`i' : word `i' of `catval'
+            local ynm`i' : word `i' of `catnms'
+            confirm integer number `y`i''
+            gen _ytemp`y`i'' = 1
+        }
+
+        local ytemp "_ytemp"
+    }
+
+    if "`rankdata'" == "yes" {
+        capture label drop `altnum'
+        foreach rvar of varlist `yrank'* {
+            local rvarnum = subinstr("`rvar'", "`yrank'", "", 1)
+            local rvarnumchk = real("`rvarnum'")
+            if "`rvarnum'" == "`rvarnumchk'" {
+                local rvarlabel : variable label `rvar'
+                label define `altnum' `rvarnum' "`rvarlabel'", modify
+            }
+        }
+    }
+
+    qui reshape long `ytemp' `yrank' `alt', i(`case') j(`altnum')
+
+    capture drop _ytemp
+
+    if "`rankdata'" == "no" {
+
+        tempvar ychosen
+        gen `ychosen' = `y'
+
+        if "`replace'" == "replace" {
+            drop `y'
+            local choice "`y'"
+        }
+
+        gen `choice' = (`altnum' == `ychosen') if `altnum' < .
+
+    }
+
+    if "`rankdata'" == "yes" {
+        label define `altnum', modify
+        label values `altnum' `altnum'
+        _pecats `altnum'
+
+        local catval = r(catvals)
+        local catnms = r(catnms)
+        local numcats = r(numcats)
+
+        forvalues i = 1(1)`numcats' {
+            local y`i' : word `i' of `catval'
+            local ynm`i' : word `i' of `catnms'
+            confirm integer number `y`i''
+        }
+
+        * if generate option specified, rename stub to that
+        if "`generate'" != "" {
+            rename `yrank' `generate'
+            local yrank "`generate'"
+        }
+
+    }
+
+    forvalues i = 1(1)`numcats' {
+        local name = "y`y`i''"
+            if "`names'" != "nonames" & "`ynm`i''" != "`y`i''" {
+                local name "`ynm`i''"
+            }
+        qui gen ytemp`y`i'' = (`altnum' == `y`i'') if `altnum' < .
+        label variable ytemp`y`i'' "`ynm`i''"
+        if "`casevars'" != "" {
+            foreach var of varlist `casevars' {
+                qui gen `name'X`var' = `var' * ytemp`y`i''
+            }
+        }
+        local ylist "`ylist' `name'*"
+        clonevar `name' = ytemp`y`i''
+        drop ytemp`y`i''
+    }
+
+    * output
+
+    if "`rankdata'" == "no" {
+        di _n as txt "choice indicated by:" as res " `choice'"
+    }
+    if "`rankdata'" == "yes" {
+        di _n as txt "ranks indicated by:" as res " `yrank'"
+    }
+    di as txt "case identifier:" as res " `case'"
+    di as txt "case-specific interactions:" as res "`ylist'"
+    if "`alt'" != "" {
+        di as txt "alternative-specific variables:" as res " `alt'"
+    }
+
+end
diff --git a/Modules/ado/plus/c/case2alt.hlp b/Modules/ado/plus/c/case2alt.hlp
new file mode 100644
index 0000000..9d4cc14
--- /dev/null
+++ b/Modules/ado/plus/c/case2alt.hlp
@@ -0,0 +1,121 @@
+{smcl}
+{* 05Dec2005jf}
+{hline}
+help for {hi:case2alt}{right:03Nov2005}
+{hline}
+
+{p 4 4 2}
+{title:Convert data from one observation per case to one observation per alternative per case}
+
+{p 4 12 2}{cmd:case2alt} {cmd:,}
+{{cmdab:choice(}{it:varname}{cmd:)} | {cmdab:rank(}{it:stubname}{cmd:)}}
+[{cmdab:a:lt(}{it:stubnames}{cmd:)}
+{cmdab:casev:ars(}{it:varlist}{cmd:)}
+{cmdab:case(}{it:varname}{cmd:)}
+{cmdab:g:enerate(}{it:newvar}{cmd:)}
+{cmdab:rep:lace}
+{cmdab:altnum(}{it:varname}{cmd:)}
+{cmdab:non:ames}]
+
+{title:Description}
+
+{p 4 4 2}
+{cmd:case2alt} is intended to be used to configure data for the estimation of estimation
+of regression models for alternative-specific data, such as {helpb clogit},
+{helpb rologit} or {helpb asmprobit}. {cmd:case2alt} presumes that you have data
+where each observation corresponds to an individual case and that you want to convert
+the data to the form in which each observation corresponds to an alternative for a specific case.
+
+{p 4 4 2}
+Imagine that you have data with an outcome that has four alternatives, with values 1, 2, 3 and 8.
+{cmd:case2alt} will reshape the data so that there are n*4 observations. If you specify an
+identifying variable with the {cmd:casevars()} option, this variable will continue to identify
+unique cases; otherwise, new variable _id will identify cases.
+
+{p 4 4 2}
+A new variable, called either _altnum or the name specified in {cmd:altnum()},
+will identify the alternatives within a case. Additionally, however, {cmd:case2alt}
+will create dummy variables y{it:value} that also identify alternatives.
+In our example the new dummy variables y1, y2, y3 and y8 will be created.
+Interactions will also be created with these dummies and any variables
+specified in {cmd:case()}. For the variable educ, {cmd:case2alt} will create
+variables y1_educ, y2_educ, y3_educ, and y8_educ.
+
+{p 4 4 2}
+If we have simple choice variable, then {cmd:case2alt} will create an outcome
+variable based on {cmd:y()} that contains 1 in the observation corresponding to
+the selected alternative and 0 for other alternatives. We can specify the name of
+this new outcome variable using the {cmd:gen()} option, or we can have it be the
+same as {opt y()} using the {cmd:replace} option, or (by default) we
+can have it be named choice.
+
+{p 4 4 2}
+After using {cmd:case2alt}, we would be able to estimate models like {helpb clogit} by typing, e.g.,:
+
+{p 4 4 2}
+{cmd:. clogit choice y1* y2* y3*, group(_id)}
+
+{p 4 4 2}
+Alternative-specific variables are specified using the {cmd:alt()} option.
+The contents of {cmd:alt()} should be {it:stubnames}, corresponding to a series
+of variables that contain the alternative-specific values.
+Specifying {cmd:alt(time)}, in our example, would imply that there are
+variables time1, time2, time3 and time8 in our case-level data.
+
+{p 4 4 2}
+Case-specific variables are specified using the {cmd:casevars()} option,
+where the contents should be a {varlist}.  Neither the outcome nor id variable
+should be included in {cmd:casevars()}.
+
+{p 4 4 2}
+If we have ranked data, we can specify the ranked outcome with the
+{cmd:rank()} outcome.  The content of rank should again be a stubname.
+Specifying {cmd:rank(}rank{cmd:)} in our example would assume there are
+variables rank1, rank2, rank3, rank8 that contain the relevant information
+on the ranks of each alternative.
+
+{title:Options}
+
+{p 4 8 2}{opth choice(varname)} or {opth rank(stubname)} is required. {varname} is the
+variable that indicates the value of the selected alternative.
+In the case of ranked outcome, {it:stubname} with {opt rank()} will contain
+the stub for the names of variables that contain information about ranks of alternatives.
+
+{p 4 8 2}{opth case(varname)} indicates the variable, either existing or to be
+created, that identifies individual cases.
+If {varname} is unspecified, a new variable named _id will be created.
+
+{p 4 8 2}{cmd:alt(}{it:stubnames}{cmd:)} contains the {it:stubnames} for
+alternative-specific variables.  This requires that variables {it:stubname}# exist
+for each value of an alternative.
+
+{p 4 8 2}{opth casevars(varlist)} contains the names of the case-specific variables
+(not including the id or outcome variable).
+
+{p 4 8 2}{opth gen:erate(newvar)} and {opt replace} are used to name the variable that
+contain 1 for the selected alternative and 0 for non-selected alternatives.
+The variable will be named {newvar} if {newvar} is specified; the name of
+the variable specified in {cmd: y()} if {opt replace} is specified; and will be named {it:choice} otherwise.
+In the case of ranked data, the ranks will be contained in variable specified as the
+stub in {opt yrank()} and {opt gen:erate()} or {opt replace} will be ignored.
+
+{p 4 8 2}{opth altnum(varname)} indicates the name of the new variable used to indicate
+the alternatives. _altnum will be used if altnum() is not specified.
+
+{p 4 8 2}{opt non:ames} indicates that the case-specific interactions should be named
+y# instead of using the value labels of the outcome variable.
+
+{title:Example}
+
+{p 4 4 2}{cmd:. use "http://www.stata-press.com/data/lfr/nomocc2.dta", clear}{break}
+{cmd:. mlogit occ white ed exper}{break}
+{cmd:. case2alt, choice(ed) casevars(white ed exper) replace nonames}{break}
+{cmd:. clogit occ y1* y2* y3* y4*, group(_id)}{break}
+
+{p 4 4 2}{cmd:. case2alt, rank(rank92) casevars(hntest) alt(rank04) case(id)}
+
+{title:Authors}
+
+    Jeremy Freese and J. Scott Long
+    www.indiana.edu/~jslsoc/spost.htm
+    spostsup@indiana.edu
diff --git a/Modules/ado/plus/c/cfa1.ado b/Modules/ado/plus/c/cfa1.ado
new file mode 100644
index 0000000..4c24afa
--- /dev/null
+++ b/Modules/ado/plus/c/cfa1.ado
@@ -0,0 +1,679 @@
+*! Confirmatory factor analysis with a single factor: v.2.2
+*! Stas Kolenikov, skolenik-gmail-com
+
+program define cfa1, eclass
+  version 9.1
+
+  if replay() {
+     if ("`e(cmd)'" != "cfa1") error 301
+     Replay `0'
+  }
+
+  else Estimate `0'
+end
+
+program Estimate `0', eclass
+
+  syntax varlist(numeric min=3) [if] [in] [aw pw / ] ///
+     , [unitvar FREE POSvar FROM(str) CONSTRaint(numlist) LEVel(int $S_level) ///
+       ROBust VCE(string) CLUster(passthru) SVY SEArch(passthru) * ]
+  * syntax: cfa1 
+  * untivar is for the identification condition of the unit variance of the latent variable
+
+  unab varlist : `varlist'
+  tokenize `varlist'
+  local q: word count `varlist'
+  marksample touse
+  preserve
+  qui keep if `touse'
+  * weights!
+  global CFA1N = _N
+
+/*
+  * we'll estimate the means instead
+  qui foreach x of varlist `varlist' {
+     sum `x', meanonly
+     replace `x' = `x'-r(mean)
+     * deviations from the mean
+  }
+*/
+
+  if "`weight'" != "" {
+     local mywgt [`weight'=`exp']
+  }
+
+  if "`robust'`cluster'`svy'`weight'"~="" {
+     local needed 1
+  }
+  else {
+     local needed 0
+  }
+
+  Parse `varlist'  , `unitvar'
+  local toml `r(toml)'
+  if "`from'" == "" {
+    local from `r(tostart)', copy
+  }
+
+  * identification
+  constraint free
+  global CFA1constr `r(free)'
+  if "`unitvar'" ~= "" {
+     * identification by unit variance
+     constraint $CFA1constr [phi]_cons = 1
+  }
+  else if "`free'"=="" {
+     * identification by the first variable
+     constraint $CFA1constr [`1']_cons = 1
+  }
+  else {
+     * identification imposed by user
+     global CFA1constr
+  }
+  local nconstr : word count `constraint'
+
+  global CFA1PV = ("`posvar'" != "")
+
+  if "`posvar'" ~= "" {
+     di as text _n "Fitting the model without restrictions on error variances..."
+  }
+
+  * variance estimation
+  local vce = trim("`vce'")
+  if "`vce'" == "boot" local vce bootstrap
+  if "`vce'" == "sbentler" {
+     global CFA1SBV = 1
+     local vce
+  }
+  else {
+    if index("robustoimopg","`vce'") {
+       local vce vce(`vce')
+    }
+    else {
+       di as err "`vce' estimation is not supported"
+       if "`vce'" == "bootstrap" | "`vce'" == "boot" {
+          di as err "try {help bootstrap} command directly"
+       }
+       exit 198
+    }
+  }
+
+  tempname ilog1 ilog2
+  Tryit ml model lf cfa1_lf `toml' `mywgt', constraint($CFA1constr `constraint') ///
+      init (`from') maximize nooutput `options' `search' ///
+      `svy' `cluster' `robust' `vce'
+/*
+  ml model lf cfa1_lf `toml' `mywgt', ///
+      constraint($CFA1constr `constraint') `svy' `robust' `cluster' ///
+      maximize
+*  ml check
+*  ml search, rep(5)
+  ml init `from', copy
+  cap noi ml maximize , `options'
+*/
+  mat `ilog1' = e(ilog)
+
+  local nz = 0
+  if $CFA1PV {
+     * determine if refitting the model is needed
+     tempname ll_unr
+     scalar `ll_unr' = e(ll)
+     forvalues i=1/`q' {
+        if [``i''_v]_cons <0 {
+           constraint free
+           local ccc = `r(free)'
+           const define `ccc' [``i''_v]_cons = 0
+           local zerolist `zerolist' `ccc'
+           local ++nz
+        }
+     }
+     local zerolist = trim("`zerolist'")
+     global CFA1constr $CFA1constr `zerolist'
+     if "`zerolist'" ~= "" {
+        di as text _n "Fitting the model with some error variances set to zero..."
+        Tryit ml model lf cfa1_lf `toml' `mywgt' , constraint($CFA1constr `constraint') ///
+            init (`from') maximize nooutput `options' `search' ///
+            `svy' `robust' `cluster' `vce'
+        mat `ilog2' = e(ilog)
+
+     }
+
+     * adjust degrees of freedom!
+  }
+
+
+  * we better have this before Satorra-Bentler
+  if "`unitvar'" ~= "" {
+    ereturn local normalized Latent Variance
+  }
+  else if "`free'"=="" {
+    ereturn local normalized `1'
+  }
+
+
+  * work out Satorra-Bentler estimates
+  if "$CFA1SBV"!="" {
+     * repost Satorra-Bentler covariance matrix
+     tempname SBVar SBV Delta Gamma
+     cap SatorraBentler
+     if _rc {
+        di as err "Satorra-Bentler standard errors are not supported for this circumstance; revert to vce(oim)"
+        global CFA1SBV
+     }
+     else {
+       mat `SBVar' = r(SBVar)
+       mat `Delta' = r(Delta)
+       mat `Gamma' = r(Gamma)
+       mat `SBV'   = r(SBV)
+       ereturn repost V = `SBVar'
+       ereturn matrix SBGamma = `Gamma', copy
+       ereturn matrix SBDelta = `Delta', copy
+       ereturn matrix SBV = `SBV', copy
+       ereturn local vce SatorraBentler
+     }
+  }
+
+
+
+  * get the covariance matrix and the number of observations!
+  ***********************************************************
+  tempname lambda vars phi S Sindep Sigma trind eb
+
+  qui mat accum `S' = `varlist', dev nocons
+  mat `S' = `S' / $CFA1N
+
+  * implied matrix
+  mat `eb' = e(b)
+  mat `lambda' = `eb'[1,1..`q']
+  mat `vars' = `eb'[1,`q'+1..2*`q']
+  scalar `phi' = `eb'[1,3*`q'+1]
+  mat `Sigma' = `lambda''*`phi'*`lambda' + diag(`vars')
+  mat `Sindep' = diag(vecdiag(`S'))
+
+  * test against independence
+  mat `trind' = trace( syminv(`Sindep') * `S' )
+  local trind = `trind'[1,1]
+  ereturn scalar ll_indep = -0.5 * `q' * $CFA1N * ln(2*_pi) - 0.5 * $CFA1N * ln(det(`Sindep')) - 0.5 * $CFA1N * `trind'
+  ereturn scalar lr_indep = 2*(e(ll)-e(ll_indep))
+  ereturn scalar df_indep = `q'-`nz'-`nconstr'
+  ereturn scalar p_indep  = chi2tail(e(df_indep),e(lr_indep))
+
+  * goodness of fit test
+  ereturn scalar ll_u = -0.5 * `q' * $CFA1N * ln(2*_pi) - 0.5 * $CFA1N * ln(det(`S')) - 0.5 * `q' * $CFA1N
+  ereturn scalar lr_u = -2*(e(ll)-e(ll_u))
+  ereturn scalar df_u = `q'*(`q'+1)*.5 - (2*`q' - `nz' - `nconstr')
+  * wrong if there are any extra constraints in -constraint- command!!!
+  ereturn scalar p_u  = chi2tail(e(df_u),e(lr_u))
+  ereturn matrix ilog1 `ilog1'
+  cap ereturn matrix ilog2 `ilog2'
+
+  * Satorra-Bentler corrections
+  if "$CFA1SBV"!="" {
+     * compute the corrected tests, too
+     * Satorra-Bentler 1994
+     tempname U trUG2 Tdf
+     mat `U' = `SBV' - `SBV'*`Delta'*syminv(`Delta''*`SBV'*`Delta')*`Delta''*`SBV'
+     ereturn matrix SBU = `U'
+     mat `U' = trace( e(SBU)*`Gamma' )
+     ereturn scalar SBc = `U'[1,1]/e(df_u)
+     ereturn scalar Tscaled = e(lr_u)/e(SBc)
+     ereturn scalar p_Tscaled = chi2tail( e(df_u), e(Tscaled) )
+
+     mat `trUG2' = trace( e(SBU)*`Gamma'*e(SBU)*`Gamma')
+     ereturn scalar SBd = `U'[1,1]*`U'[1,1]/`trUG2'[1,1]
+     ereturn scalar Tadj = ( e(SBd)/`U'[1,1]) * e(lr_u)
+     ereturn scalar p_Tadj = chi2tail( e(SBd), e(Tadj) )
+
+     * Yuan-Bentler 1997
+     * weights!
+     ereturn scalar T2 = e(lr_u)/(1+e(lr_u)/e(N) )
+     ereturn scalar p_T2 = chi2tail( e(df_u), e(T2) )
+  }
+
+  if "`posvar'" ~= "" {
+     ereturn scalar lr_zerov = 2*(`ll_unr' - e(ll))
+     ereturn scalar df_zerov = `nz'
+     local replay_opt posvar llu(`ll_unr')
+  }
+  ereturn local cmd cfa1
+
+  Replay , `replay_opt' level(`level')
+  Finish
+  restore
+  ereturn repost, esample(`touse')
+
+end
+
+program define Tryit
+
+  cap noi `0'
+  local rc=_rc
+  if `rc' {
+     Finish
+     exit `rc'
+  }
+
+end
+
+program define Finish
+
+  * finishing off
+  constraint drop $CFA1constr
+  global CFA1S
+  global CFA1N
+  global CFA1PV
+  global CFA1theta
+  global CFA1arg
+  global CFA1data
+  global CFA1constr
+  global CFA1vars
+  global CFA1SBV
+
+end
+
+program define Replay
+
+  syntax, [posvar llu(str) level(passthru)]
+
+  di _n as text "Log likelihood = " as res e(ll) _col(59) as text "Number of obs = " as res e(N)
+  di as text "{hline 13}{c TT}{hline 64}"
+  di as text "             {c |}      Coef.   Std. Err.      z    P>|z|     [$S_level% Conf. Interval]"
+  di as text "{hline 13}{c +}{hline 64}"
+
+  tempname vce
+  mat `vce' = e(V)
+  local q = colsof(`vce')
+  local q = (`q'-1)/3
+  local a : colfullnames(`vce')
+  tokenize `a'
+
+  di as text "Lambda{col 14}{c |}"
+  forvalues i = 1/`q' {
+    gettoken v`i' : `i' , parse(":")
+    _diparm `v`i'' , label("`v`i''") prob `level'
+  }
+  di as text "Var[error]{col 14}{c |}"
+  forvalues i = 1/`q' {
+    _diparm `v`i''_v , label("`v`i''") prob `level'
+  }
+  di as text "Means{col 14}{c |}"
+  forvalues i = 1/`q' {
+    _diparm `v`i''_m , label("`v`i''") prob `level'
+  }
+  di as text "Var[latent]{col 14}{c |}"
+  _diparm phi , label("phi1") prob
+
+  di as text "{hline 13}{c +}{hline 64}"
+  di as text "R2{col 14}{c |}"
+  forvalues i = 1/`q' {
+    di as text %12s "`v`i''" "{col 14}{c |}{col 20}" ///
+       as res %6.4f (_b[`v`i'':_cons]^2*_b[phi:_cons]) / ///
+              (_b[`v`i'':_cons]^2*_b[phi:_cons] + _b[`v`i''_v:_cons])
+  }
+
+
+  di as text "{hline 13}{c BT}{hline 64}"
+
+  if e(df_u)>0 {
+     di as text _n "Goodness of fit test: LR = " as res %6.3f e(lr_u) ///
+        as text _col(40) "; Prob[chi2(" as res %2.0f e(df_u) as text ") > LR] = " as res %6.4f e(p_u)
+  }
+  else {
+     di as text "No degrees of freedom to perform the goodness of fit test"
+  }
+  di as text "Test vs independence: LR = " as res %6.3f e(lr_indep) ///
+     as text _col(40) "; Prob[chi2(" as res %2.0f e(df_indep) as text ") > LR] = " as res %6.4f e(p_indep)
+
+  if "`e(vce)'" == "SatorraBentler" & e(df_u)>0 {
+     * need to report all those corrected statistics
+
+     di as text _n "Satorra-Bentler Tbar" _col(26) "= " as res %6.3f e(Tscaled) ///
+        as text _col(40) "; Prob[chi2(" as res %2.0f e(df_u) as text ") > Tbar] = " as res %6.4f e(p_Tscaled)
+
+     di as text "Satorra-Bentler Tbarbar" _col(26) "= " as res %6.3f e(Tadj) ///
+        as text _col(40) "; Prob[chi2(" as res %4.1f e(SBd) as text ") > Tbarbar] = " as res %6.4f e(p_Tadj)
+
+     di as text "Yuan-Bentler T2" _col(26) "= " as res %6.3f e(T2) ///
+        as text _col(40) "; Prob[chi2(" as res %2.0f e(df_u) as text ") > T2] = " as res %6.4f e(p_T2)
+  }
+
+  if "`posvar'" ~= "" {
+     * just estimated?
+     if "`llu'" == "" {
+        di as err "cannot specify -posvar- option, need to refit the whole model"
+     }
+     else {
+      if e(df_zerov)>0 {
+        di as text "Likelihood ratio against negative variances: LR = " as res %6.3f e(lr_zerov)
+        di as text "Conservative Prob[chi2(" as res %2.0f e(df_zerov) as text ") > LR] = " ///
+           as res %6.4f chi2tail(e(df_zerov),e(lr_zerov))
+      }
+      else {
+        di as text "All variances are non-negative, no need to test against zero variances"
+      }
+     }
+  }
+
+end
+
+program define Parse , rclass
+  * takes the list of variables and returns the appropriate ml model statement
+  syntax varlist , [unitvar]
+
+  global CFA1arg
+  global CFA1theta
+  global CFA1vars
+  local q : word count `varlist'
+
+  * lambdas
+  forvalues i = 1/`q' {
+     local toml `toml' (``i'': ``i'' = )
+     local tostart `tostart' 1
+     global CFA1arg $CFA1arg g_``i''
+     global CFA1theta $CFA1theta l_`i'
+     global CFA1vars $CFA1vars ``i''
+  }
+
+  * variances
+  forvalues i = 1/`q' {
+     local toml `toml' (``i''_v: )
+     local tostart `tostart'  1
+     global CFA1arg $CFA1arg g_``i''_v
+     global CFA1theta $CFA1theta v_`i'
+  }
+
+  * means
+  forvalues i = 1/`q' {
+     local toml `toml' (``i''_m: )
+     qui sum ``i'', mean
+     local mean = r(mean)
+     local tostart `tostart' `mean'
+     global CFA1arg $CFA1arg g_``i''_m
+     global CFA1theta $CFA1theta m_`i'
+  }
+
+  * variance of the factor
+  local toml `toml' (phi: )
+  local tostart `tostart' 1
+  global CFA1arg $CFA1arg g_Phi
+  global CFA1theta $CFA1theta phi
+
+  * done!
+  return local toml `toml'
+  return local tostart `tostart'
+
+end
+
+
+**************************** Satorra-Bentler covariance matrix code
+
+program SatorraBentler, rclass
+   version 9.1
+   syntax [, noisily]
+   * assume the maximization completed, the results are in memory as -ereturn data-
+   * we shall just return the resulting matrix
+
+   if "`e(normalized)'" == "" {
+      di as err "cannot compute Satorra-Bentler variance estimator with arbitrary identification... yet"
+      exit 198
+   }
+
+   * assume sample is restricted to e(sample)
+   * preserve
+   * keep if e(sample)
+
+   * get the variable names
+   tempname VV bb
+   mat `VV' = e(V)
+   local q = rowsof(`VV')
+   local p = (`q'-1)/3
+   local eqlist : coleq `VV'
+   tokenize `eqlist'
+   forvalues k=1/`p' {
+     local varlist `varlist' ``k''
+   }
+
+   * compute the implied covariance matrix
+   tempname Lambda Theta phi Sigma
+   mat `bb' = e(b)
+   mat `Lambda' = `bb'[1,1..`p']
+   mat `Theta' = `bb'[1,`p'+1..2*`p']
+   scalar `phi' = `bb'[1,`q']
+   mat `Sigma' = `Lambda''*`phi'*`Lambda' + diag(`Theta')
+
+   * compute the empirical cov matrix
+   tempname SampleCov
+   qui mat accum `SampleCov' = `varlist' , nocons dev
+   * weights!!!
+   mat `SampleCov' = `SampleCov' / (r(N)-1)
+
+   * compute the matrix Gamma
+   `noisily' di as text "Computing the Gamma matrix of fourth moments..."
+   tempname Gamma
+   SBGamma `varlist'
+   mat `Gamma' = r(Gamma)
+   return add
+
+   * compute the duplication matrix
+   * Dupl `p'
+   * let's call it from within SBV!
+
+   * compute the V matrix
+   `noisily' di as text "Computing the V matrix..."
+   SBV `SampleCov' `noisily'
+   tempname V
+   mat `V' = r(SBV)
+   return add
+
+   * compute the Delta matrix
+   `noisily' di as text "Computing the Delta matrix..."
+   tempname Delta
+   mata : SBDelta("`bb'","`Delta'")
+
+   *** put the pieces together now
+
+   tempname DeltaId
+
+   * enact the constraints!
+   SBconstr `bb'
+   mat `DeltaId' = `Delta' * diag( r(Fixed) )
+
+   * those should be in there, but it never hurts to fix!
+   if "`e(normalized)'" == "Latent Variance" {
+      * make the last column null
+      mat `DeltaId' = ( `DeltaId'[1...,1...3*`p'] , J(rowsof(`Delta'), 1, 0)  )
+   }
+   else if "`e(normalized)'" ~= "" {
+      * normalization by first variable
+      local idvar `e(normalized)'
+      if "`idvar'" ~= "`1'" {
+         di as err "cannot figure out the identification variable"
+         exit 198
+      }
+      mat `DeltaId' = ( J(rowsof(`Delta'), 1, 0) , `DeltaId'[1...,2...] )
+   }
+   local dcnames : colfullnames `bb'
+   local drnames : rownames `Gamma'
+   mat colnames `DeltaId' = `dcnames'
+   mat rownames `DeltaId' = `drnames'
+   return matrix Delta = `DeltaId', copy
+
+   tempname VVV
+   mat `VVV' = ( `DeltaId'' * `V' * `DeltaId' )
+   mat `VVV' = syminv(`VVV')
+   mat `VVV' = `VVV' * ( `DeltaId'' * `V' * `Gamma' * `V' * `DeltaId' ) * `VVV'
+
+   * add the covariance matrix for the means, which is just Sigma/_N
+   * weights!
+   tempname CovM
+   mat `CovM' = ( J(2*`p',colsof(`bb'),0) \ J(`p',2*`p',0) , `Sigma', J(`p',1,0) \ J(1, colsof(`bb'), 0) )
+
+   mat `VVV' = (`VVV' + `CovM')/_N
+   return matrix SBVar = `VVV'
+
+end
+* of satorrabentler
+
+program define SBGamma, rclass
+   syntax varlist
+   unab varlist : `varlist'
+   tokenize `varlist'
+
+   local p: word count `varlist'
+
+   forvalues k=1/`p' {
+     * make up the deviations
+     * weights!!!
+     qui sum ``k'', meanonly
+     tempvar d`k'
+     qui g double `d`k'' = ``k'' - r(mean)
+     local dlist `dlist' `d`k''
+   }
+
+   local pstar = `p'*(`p'+1)/2
+   forvalues k=1/`pstar' {
+      tempvar b`k'
+      qui g double `b`k'' = .
+      local blist `blist' `b`k''
+   }
+
+
+   * convert into vech (z_i-bar z)(z_i-bar z)'
+   mata : SBvechZZtoB("`dlist'","`blist'")
+
+   * blist now should contain the moments around the sample means
+   * we need to get their covariance matrix
+
+   tempname Gamma
+   qui mat accum `Gamma' = `blist', dev nocons
+   * weights!
+   mat `Gamma' = `Gamma'/(_N-1)
+   mata : Gamma = st_matrix( "`Gamma'" )
+
+   * make nice row and column names
+   forvalues i=1/`p' {
+     forvalues j=`i'/`p' {
+        local namelist `namelist' ``i''_X_``j''
+     }
+   }
+   mat colnames `Gamma' = `namelist'
+   mat rownames `Gamma' = `namelist'
+
+   return matrix Gamma = `Gamma'
+
+end
+* of computing Gamma
+
+program define SBV, rclass
+   args A noisily
+   tempname D Ainv V
+   local p = rowsof(`A')
+   `noisily' di as text "Computing the duplication matrix..."
+   mata : Dupl(`p',"`D'")
+   mat `Ainv' = syminv(`A')
+   mat `V' = .5*`D''* (`Ainv' # `Ainv') * `D'
+   return matrix SBV = `V'
+end
+* of computing V
+
+   * need to figure out whether a constraint has the form parameter = value,
+   * and to nullify the corresponding column
+program define SBconstr, rclass
+   args bb
+   tempname Iq
+   mat `Iq' = J(1,colsof(`bb'),1)
+   tokenize $CFA1constr
+   while "`1'" ~= "" {
+     constraint get `1'
+     local constr `r(contents)'
+     gettoken param value  : constr, parse("=")
+     * is the RHS indeed a number?
+     local value = substr("`value'",2,.)
+     confirm number `value'
+     * parse the square brackets and turn them into colon
+     * replace the opening brackets with nothing, and closing brackets, with :
+     local param = subinstr("`param'","["," ",1)
+     local param = subinstr("`param'","]",":",1)
+     local param = trim("`param'")
+     local coln = colnumb(`bb',"`param'" )
+     mat `Iq'[1,`coln']=0
+
+     mac shift
+   }
+   return matrix Fixed = `Iq'
+end
+
+
+cap mata : mata drop SBvechZZtoB()
+cap mata : mata drop Dupl()
+cap mata : mata drop SBDelta()
+
+mata:
+void SBvechZZtoB(string dlist, string blist) {
+   // view the deviation variables
+   st_view(data=.,.,tokens(dlist))
+   // view the moment variables
+   // blist=st_local("blist")
+   st_view(moments=.,.,tokens(blist))
+   // vectorize!
+   for(i=1; i<=rows(data); i++) {
+     B = data[i,.]'*data[i,.]
+     moments[i,.] = vech(B)'
+   }
+}
+
+void Dupl(scalar p, string Dname) {
+   pstar = p*(p+1)/2
+   Ipstar = I(pstar)
+   D = J(p*p,0,.)
+   for(k=1;k<=pstar;k++) {
+      D = (D, vec(invvech(Ipstar[.,k])))
+   }
+   st_matrix(Dname,D)
+}
+
+void SBDelta(string bbname, string DeltaName) {
+   bb = st_matrix(bbname)
+   p = (cols(bb)-1)/3
+   Lambda = bb[1,1..p]
+   Theta = bb[1,p+1..2*p]
+   phi = bb[1,cols(bb)]
+   Delta = J(0,cols(bb),.)
+   for(i=1;i<=p;i++) {
+     for(j=i;j<=p;j++) {
+       DeltaRow = J(1,cols(Delta),0)
+       for(k=1;k<=p;k++) {
+         // derivative wrt lambda_k
+         DeltaRow[k] = (k==i)*Lambda[j]*phi + (j==k)*Lambda[i]*phi
+         // derivative wrt sigma^2_k
+         DeltaRow[p+k] = (i==k)*(j==k)
+       }
+       DeltaRow[cols(Delta)] = Lambda[i]*Lambda[j]
+       Delta = Delta \ DeltaRow
+     }
+   }
+   st_matrix(DeltaName,Delta)
+}
+
+end
+* of mata piece
+
+***************************** end of Satorra-Bentler covariance matrix code
+
+exit
+
+History:
+   v.1.0 -- May 19, 2004: basic operation, method d0
+   v.1.1 -- May 19, 2004: identification by -constraint-
+                          common -cfa1_ll-
+                          from()
+   v.1.2 -- May 21, 2004: method -lf-, robust
+                          constraint free
+   v.1.3 -- unknown
+   v.1.4 -- Feb 15, 2005: pweights, arbitrary constraints
+   v.2.0 -- Feb 28, 2006: update to version 9 using Mata
+   v.2.1 -- Apr 11, 2006: whatever
+   v.2.2 -- Apr 13, 2006: Satorra-Bentler standard errors and test corrections
+                          -vce- option
+            Apr 14, 2006: degrees of freedom corrected for # constraints
+            July 5, 2006: minor issue with -from(, copy)-
diff --git a/Modules/ado/plus/c/cfa1.hlp b/Modules/ado/plus/c/cfa1.hlp
new file mode 100644
index 0000000..efe8ec3
--- /dev/null
+++ b/Modules/ado/plus/c/cfa1.hlp
@@ -0,0 +1,159 @@
+{smcl}
+{.-}
+help for {cmd:cfa1} {right:author: {browse "http://stas.kolenikov.name/":Stas Kolenikov}}
+{.-}
+
+{title:Confirmatory factor analysis with a single factor}
+
+{p 8 27}
+{cmd:cfa1}
+{it:varlist}
+[{cmd:if} {it:exp}] [{cmd:in} {it:range}]
+[{cmd:aw|pw =} {it:weight}]
+[{cmd:,}
+     {cmd:unitvar}
+     {cmd:free}
+     {cmdab:pos:var}
+     {cmdab:constr:aint(}{it:numlist}{cmd:)}
+     {cmdab:lev:el(}{it:#}{cmd:)}
+     {cmdab:rob:ust}
+     {cmd:vce(robust|oim|opg|sbentler}{cmd:)}
+     {cmd:cluster(}{it:varname}{cmd:)}
+     {cmd:svy}
+     {cmdab:sea:rch(}{it:searchspec}{cmd:)}
+     {cmd:from(}{it:initspecs}{cmd:)}
+     {it:ml options}
+]
+
+{title:Description}
+
+{p}{cmd:cfa1} estimates simple confirmatory factor
+analysis model with a single factor. In this model,
+each of the variables is assumed to be an indicator
+of an underlying unobserved factor with a linear
+dependence between them:
+
+{center:{it:y_i = m_i + l_i xi + delta_i}}
+
+{p}where {it:y_i} is the {it:i}-th variable
+in the {it:varlist}, {it:m_i} is its mean,
+{it:l_i} is the latent variable loading,
+{it:xi} is the latent variable/factor,
+and {it:delta_i} is the measurement error.
+
+{p}The model is estimated by the maximum likelihood
+procedure.
+
+{p}As with all latent variable models, a number
+of identifying assumptions need to be made about
+the latent variable {it:xi}. It is assumed
+to have mean zero, and its scale is determined
+by the first variable in the {it:varlist}
+(i.e., l_1 is set to equal 1). Alternatively,
+identification can be achieved by setting the
+variance of the latent variable to 1 (with option
+{it:unitvar}). More sophisticated identification
+conditions can be achieved by specifying option
+{it:free} and then providing the necessary
+{it:constraint}.
+
+
+{title:Options}
+
+{ul:Identification:}
+
+{p 0 4}{cmd:unitvar} specifies identification by setting
+       the variance of the latent variable to 1.
+
+{p 0 4}{cmd:free} requests to relax all identifying constraints.
+       In this case, the user is responsible for provision
+       of such constraints; otherwise, the estimation process
+       won't converge.
+
+{p 0 4}{cmdab:pos:var} specifies that if one or more of the
+       measurement error variances were estimated to be
+       negative (known as Heywood cases), the model
+       needs to be automatically re-estimated by setting
+       those variances to zero. The likelihood ratio test
+       is then reported comparing the models with and without
+       constraints. If there is only one offending estimate,
+       the proper distribution to refer this likelihood
+       ratio to is a mixture of chi-squares; see
+       {help j_chibar:chi-bar test}. A conservative
+       test is provided by a reference to the chi-square
+       distribution with the largest degrees of freedom.
+       The p-value is then overstated.
+
+{p 0 4}{cmdab:constr:aint(}{it:numlist}{cmd:)} can be used
+       to supply additional constraints. The degrees of freedom
+       of the model may be wrong, then.
+
+{p 0 4}{cmdab:lev:el(}{it:#}{cmd:)} -- see
+       {help estimation_options##level():estimation options}
+
+{ul:Standard error estimation:}
+
+{p 0 4}{cmd:vce(oim|opg|robust|sbentler}
+       specifies the way to estimate the standard errors.
+       See {help vce_option}. {cmd:vce(sbentler)} is an
+       additional Satorra-Bentler estimator popular in
+       structural equation modeling literature that relaxes
+       the assumption of multivariate normality while
+       keeping the assumption of proper structural specification.
+
+{p 0 4}{cmd:robust} is a synonum for {cmd:vce(robust)}.
+
+{p 0 4}{cmd:cluster(}{it:varname}{cmd:)}
+
+{p 0 4}{cmd:svy} instructs {cmd:cfa1} to respect the complex
+       survey design, if one is specified.
+
+{ul:Maximization options: see {help maximize}}
+
+{title:Returned values}
+
+{p}Beside the standard {help estcom:estimation results}, {cmd:cfa1}
+also performs the overall goodness of fit test with results
+saved in {cmd:e(lr_u)}, {cmd:e(df_u)} and {cmd:e(p_u)}
+for the test statistic, its goodness of fit, and the resulting
+p-value. A test vs. the model with the independent data
+is provided with the {help ereturn} results with {cmd:indep}
+suffix. Here, under the null hypothesis,
+the covariance matrix is assumed diagonal.
+
+{p}When {cmd:sbentler} is specified, Satorra-Bentler
+standard errors are computed and posted as {cmd:e(V)},
+with intermediate matrices saved in {cmd:e(SBU)},
+{cmd:e(SBV)}, {cmd:e(SBGamma)} and {cmd:e(SBDelta)}.
+Also, a number of corrected overall fit test statistics
+is reported and saved: T-scaled ({cmd:ereturn} results
+with {cmd:Tscaled} suffix) and T-adjusted
+({cmd:ereturn} resuls with {cmd:Tadj} suffix;
+also, {cmd:e(SBc)} and {cmd:e(SBd)} are the
+scaling constants, with the latter also
+being the approximate degrees of freedom
+of the chi-square test)
+from Satorra and Bentler (1994), and T-double
+bar from Yuan and Bentler (1997)
+(with {cmd:T2} suffix).
+
+
+{title:References}
+
+{p 0 4}{bind:}Satorra, A. and Bentler, P. M. (1994)
+  Corrections to test statistics and standard errors in covariance structure analysis,
+  in: {it:Latent variables analysis}, SAGE.
+
+{p 0 4}{bind:}
+    Yuan, K. H.,  and Bentler, P. M. (1997)
+    Mean and Covariance Structure Analysis: Theoretical and Practical Improvements.
+    {it:JASA}, {bf:92} (438), pp. 767--774.
+
+
+{title:Also see}
+
+{p 0 21}{bind:}Online:    help for {help factor}
+
+{title:Contact}
+
+Stas Kolenikov, kolenikovs {it:at} missouri.edu
diff --git a/Modules/ado/plus/c/cfa1_lf.ado b/Modules/ado/plus/c/cfa1_lf.ado
new file mode 100644
index 0000000..72671c7
--- /dev/null
+++ b/Modules/ado/plus/c/cfa1_lf.ado
@@ -0,0 +1,69 @@
+*! Log likelihood for cfa1: linear form; v.2.1
+program define cfa1_lf
+
+   args lnf $CFA1theta
+   * $CFA1theta contains all the names needed:
+   * $CFA1theta == l_1 ... l_q v_1 ... v_q m_1 ... m_q phi
+
+   gettoken lnf allthenames : 0
+
+   tempvar lnl
+   qui g double `lnl' = .
+
+   nobreak mata: CFA1_NormalLKHDr( "`allthenames'", "$CFA1vars", "`lnl'")
+
+   qui replace `lnf' = `lnl'
+
+end
+
+*! NormalLKHDr: normal likelihood with normal deviates in variables
+*! v.2.1 Stas Kolenikov skolenik@gmail.com
+cap mata: mata drop CFA1_NormalLKHDr()
+mata:
+void CFA1_NormalLKHDr(
+       string parnames, // the parameter names
+       string varnames, // the variables
+       string loglkhd // where the stuff is to be returned
+       ) {
+
+   // declarations
+   real matrix data, lnl, parms // views of the data
+   real matrix lambda, means, vars, phi // parameters
+   real matrix Sigma, WorkSigma, InvWorkSigma, SS // the covariance matrices and temp matrix
+   real scalar p, n // dimension, no. obs
+
+   // get the data in
+   st_view(data=., ., tokens(varnames) )
+   st_view(lnl=., ., tokens(loglkhd) )
+   st_view(parms=., 1, tokens(parnames) )
+
+   n=rows(data)
+   p=cols(data)
+
+   // get the parameters in
+   lambda= parms[1,1..p]
+   vars  = parms[1,p+1..2*p]
+   means = parms[1,2*p+1..3*p]
+   phi   = parms[1,3*p+1]
+
+   Sigma = lambda'*lambda*phi + diag(vars)
+
+   SS = cholesky(Sigma)
+   InvWorkSigma = solvelower(SS,I(rows(SS)))
+   InvWorkSigma = solveupper(SS',InvWorkSigma)
+   ldetWS = 2*ln(dettriangular(SS))
+
+   for( i=1; i<=n; i++ ) {
+      lnl[i,1] = -.5*(data[i,.]-means)*InvWorkSigma*(data[i,.]-means)' - .5*ldetWS - .5*p*ln(2*pi())
+   }
+
+}
+
+end
+
+
+exit
+
+History:
+v.2.0 March 10, 2006 -- re-written for Stata 9 and Mata
+v.2.1 March 10, 2006 -- everything is moved to Mata
diff --git a/Modules/ado/plus/c/checkfor2.ado b/Modules/ado/plus/c/checkfor2.ado
new file mode 100644
index 0000000..088165c
--- /dev/null
+++ b/Modules/ado/plus/c/checkfor2.ado
@@ -0,0 +1,169 @@
+*!Data management utility: check for existence of variables in a dataset.
+*!Version 1.1 by Amadou B. DIALLO.
+*!This version 1.2 . Updated by Amadou B. DIALLO and Jean-Benoit HARDOUIN.
+*!Authors: Amadou Bassirou DIALLO (Poverty Division, World Bank) and Jean-Benoit HARDOUIN (Regional Health Observatory of Orléans).
+
+program checkfor2 , rclass
+version 8
+syntax anything [if] [in] [, noList Tolerance(real 0) TAble noSUm GENMiss(namelist min=1 max=1) MISsing(string)]
+
+marksample touse
+tempname rat
+local av
+local unav
+local manymissings
+local avnum
+
+quietly count if `touse'
+local tot = r(N)
+
+qui isvar `anything'
+local badlist `r(badlist)'
+local varlist `r(varlist)'
+
+di _n
+if "`table'"!="" {
+   if "`badlist'"!="" {
+      di _col(4) in green "{hline 39}"
+      di _col(4)in green "Unavailable variables: " 
+      foreach i of local badlist {
+        di _col(4) in ye "`i'" 
+      }
+      di _col(4) in green "{hline 39}"
+      di
+   }
+   di _col(4) in green "{hline 39}"
+   display _col(4) in gr "Existing" _col(15) in gr "Rate of"
+   display _col(4) in gr "Variable"  _col(14) "missings" _col(26) "Type" _col(34) "Available"
+   di _col(4) in green "{hline 39}"
+}
+
+tokenize `varlist'
+local nbvar : word count `varlist'
+
+forvalues i=1/`nbvar' {
+   capture assert missing(``i'')  if `touse'
+      local ty: type ``i''
+      local tty = substr("`ty'", 1, 3)
+      if !_rc { 
+             if "`table'"=="" {
+                 display in ye "``i''" in gr " is empty in the database." in ye " ``i''" in gr " is not added to the available list."
+             }
+             else {
+                 display _col(4) in gr "`=abbrev("``i''",8)'" _col(15) in ye "100.00%"  _col(26) "`ty'"
+             }
+             local manymissings `manymissings' ``i''
+      }
+      else { 
+             if "`table'"=="" {
+                display in ye "``i''" in gr " exists and is not empty."
+             }
+             *Consider type
+             if "`tty'" == "str" {
+               qui count if (``i'' == ""|``i''=="`missing'") & `touse'
+               local num = r(N)
+               scalar `rat' = (`num'/`tot')*100
+              }
+             else {
+               local avnum `avnum' ``i''
+               capture confirm number `missing'
+               if _rc!=0 {
+                  quietly count if ``i'' >= . & `touse'
+               }
+               else  {
+                  quietly count if (``i'' >= .|``i''==`missing') & `touse'
+               }
+               local num = r(N)
+               scalar `rat' = (`num'/`tot')*100
+              }
+              if "`table'"=="" {
+                  display in ye "``i''" in gr " has " in ye r(N) in gr " missings."
+                  display in gr "Ratio number of missings of" in ye " ``i''" in gr " to total number of observations: " in ye %6.2f `rat' "%"
+               }
+
+               if `rat' <= `tolerance' {
+                  local av `av' ``i''
+                  if "`table'"=="" {
+                     display in ye "``i''" in gr " is added to the available list."
+                  }
+                  else {
+                     display _col(4) in gr "`=abbrev("``i''",8)'" in ye _col(15) %6.2f `rat' "%" _col(26) "`ty'" _col(34) "X"
+                  }
+               }
+               else {
+                  local manymissings `manymissings' ``i''
+                  if "`table'"=="" {
+                     display in ye "``i''" in gr " has too many missings, compared to the tolerance level."
+                     display in ye "``i''" in gr " is not added to the available list."
+                  }
+                  else {
+                     display _col(4) in gr "`=abbrev("``i''",8)'" _col(15) in ye %6.2f `rat' "%" _col(26) "`ty'"
+                  }
+               }
+      }
+      if "`table'"=="" {
+          di
+      }
+}
+
+if "`table'"!="" {
+   di _col(4) in green "{hline 39}"
+}
+
+return local available `av'
+return local unavailable `badlist'
+return local manymissings `manymissings'
+
+if "`avnum'" ~= ""&"`sum'"=="" {
+   display _newline
+   display in ye _col(14) "Unweighted summary statistics for available variables:" _n
+   capture confirm number `missing'
+   if _rc!=0 {
+      summarize `avnum'  if `touse'
+   }
+   else {
+      foreach i of local avnum {
+         summarize `i'  if `touse'&`i'!=`missing'
+      }
+   }
+}
+
+if "`list'"== "" {
+   display _newline
+   display in ye _d(97) "_"
+   display _newline
+   if "`badlist'"~="" {
+      display in gr "Unavailable variables: " in ye _col(45) "`badlist'" _n
+   }
+   if "`av'"~="" {
+      display in gr "Available variables: " in ye _col(45) "`av'" _n
+   }
+   if "`manymissings'"~="" {
+      display in gr "Available variables but with too missings: " in ye _col(45) "`manymissings'" _n
+   }
+   display in ye _d(97) "_"
+}
+
+if "`genmiss'" !="" {
+   capture confirm variable `genmiss'
+   if _rc!=0 {
+      qui gen `genmiss' = 0
+      local nbav : word count `av'
+      tokenize `av'
+      forvalues i=1/`nbav' {
+          local ty: type ``i''
+          local tty = substr("`ty'", 1, 3)
+          if "`tty'" == "str" {
+            qui replace `genmiss'=`genmiss'+1 if ``i''=="."
+          }
+          else {
+            qui replace `genmiss'=`genmiss'+1 if ``i''>=.
+          }
+      }
+   }
+   else {
+      di in green "The variable" in ye " `genmiss' " in green "already exists".
+   }
+}
+
+end
diff --git a/Modules/ado/plus/c/checkfor2.hlp b/Modules/ado/plus/c/checkfor2.hlp
new file mode 100644
index 0000000..9a6104e
--- /dev/null
+++ b/Modules/ado/plus/c/checkfor2.hlp
@@ -0,0 +1,88 @@
+{smcl}
+{hline}
+help for {cmd:checkfor2} {right:Amadou B. DIALLO}
+                         {right:Jean-Benoit HARDOUIN}
+{hline}
+
+{title:Module to check whether a variable exists or not in a dataset.}
+
+{p 4 8 2}{cmd:checkfor2} {it:anything} [{cmd:,}
+ {cmdab:t:olerance}({it:#}) {cmdab:ta:ble} {cmdab:nol:ist} {cmdab:nosu:m} 
+ {cmdab:genm:iss}({it:newvarname}) {cmdab:mis:sing}({it:string})]
+
+{title:Description}
+
+{p 4 4 2}{cmd:checkfor2} is a data management routine to check for existence of variables
+within a (usually big) data set.
+
+{p 4 4 2}{cmd:checkfor2} searchs through the data whether each variable exists.
+The variables are clustered between unavailable variables, available variables with 
+a little amount of missing values and available variables with too many missing values.
+
+{p 4 4 2}{cmd:isvar} must be installed ({stata ssc install isvar:ssc install isvar}).
+
+{title:Options}
+
+{p 4 4 2}{it:anything} is composed of variable names or lists of variables,
+
+{p 4 4 2}{cmd:tolerance} is the tolerance level (in percentage) to consider a variable as available, with default 0,
+
+{p 4 4 2}{cmd:nolist} avoids displaying availability status at the end of the process,
+
+{p 4 4 2}{cmd:nosum} avoids displaying summary statistics of available variables,
+
+{p 4 4 2}{cmd:table} displays the results in a table (instead as text),
+
+{p 4 4 2}{cmd:genmiss} creates a new variable containing the number of missing values among the available variables,
+
+{p 4 4 2}{cmd:missing} defines a specific value or string considered as a missing value.
+
+
+{title:Saved results}
+
+{p 4 4 2} {cmd:r(unavailable)} names of unavailable variables.{p_end}
+
+{p 4 4 2} {cmd:r(available)}   names of available variables with a small amount of missing values.{p_end}
+
+{p 4 4 2} {cmd:r(manymissings)} names of variables present but with too missings.{p_end}
+
+{title:Examples}
+
+{p 4 4 2}{cmd:. use mydata, clear  }{p_end}
+
+{p 4 4 2}{cmd:. checkfor2 x y z , mis(99) genmiss(countmiss) }{p_end}
+
+{p 4 4 2}{cmd:. su `r(available)' }{p_end}
+
+{p 4 4 2}{cmd:. tab countmiss }{p_end}
+
+{p 4 4 2}{cmd:. u bigdataset in 1/100, clear // Big data set}{p_end}
+
+{p 4 4 2}{cmd:. checkfor2 v1 v2 v3 xx yy , nosum tol(5) tab}{p_end}
+
+{p 4 4 2}{cmd:. use `r(available)' using bigdataset, clear }{p_end}
+
+{title:Remarks}
+
+{p 4 4 2}{cmd:checkfor2} and its primary version ({cmd:checkfor}) have been primarily written for comparable surveys such as the Demography and 
+Health Surveys (DHS) or the Multiple Indicator Cluster Surveys (MICS). But this could easily applied 
+to any other survey.
+
+{title:Authors}
+
+{p 4 4 2}Amadou Bassirou DIALLO.
+Poverty and Health Division, PREM, The World Bank.{p_end}
+{p 4 4 2}Email: {browse "mailto:adiallo5@worldbank.org":adiallo5@worldbank.org}
+
+{p 4 4 2}Jean-Benoit HARDOUIN.
+Regional Health Observatory of Orléans, France.{p_end}
+{p 4 4 2}Email: {browse "mailto:jean-benoit.hardouin@orscentre.org":jean-benoit.hardouin@orscentre.org}
+ 
+{title:Aknowledgements}
+
+{p 4 4 2}We would like to thank Christophe Rockmore and also Nick Cox 
+and Kit Baum for their comments.
+
+{title:Also see}
+
+{p 4 13 2}Online:   help for {help checkfor}, {help isvar}, {help nmissing}, {help npresent}, {help missing} and {help dropmiss} if installed.{p_end}
diff --git a/Modules/ado/plus/c/choplist.ado b/Modules/ado/plus/c/choplist.ado
new file mode 100644
index 0000000..1cd6ff9
--- /dev/null
+++ b/Modules/ado/plus/c/choplist.ado
@@ -0,0 +1,140 @@
+program def choplist, rclass
+*! NJC 1.4.0 13 December 2000 
+* NJC 1.3.0 29 June 2000 
+* NJC 1.2.0 7 June 2000 
+* NJC 1.1.0 22 Dec 1999 
+* NJC 1.0.0 20 Dec 1999 after discussion with Kit Baum  	
+	version 6.0 
+	gettoken list 0 : 0, parse(",")
+	if "`list'" == "" | "`list'" == "," { 
+		di in r "nothing in list" 
+		exit 198 
+	}
+	syntax , [ Pos(str) Value(str asis) Length(str) Char(int 0) /* 
+	*/ Noisily Global(str) ]
+
+	if "`global'" != "" { 
+		tokenize `global' 
+		args global1 global2 global3 
+		if "`global3'" != "" { 
+			di in r "global( ) must contain at most 2 names"
+			exit 198 
+		} 
+		if (length("`global1'") > 8) | (length("`global2'") > 8)  { 
+			di in r "global name must be <=8 characters" 
+			exit 198 
+		} 	
+	} 	
+
+	local nopts = /* 
+        */ ("`pos'" != "") + (`"`value'"' != "") + /* 
+	*/ ("`length'" != "") + (`char' != 0) 
+	if `nopts' != 1 { 
+		di in r "must specify pos( ), value( ), length( ) or char( )" 
+		exit 198 
+	}
+	
+ 	* as string <= contains quote 
+	local asstr = index(`"`value'"', `"""') 
+
+	tokenize `list'
+	local n : word count `list'
+	
+	if "`length'" != "" | `char' != 0 { 
+		local i = 1 
+		while `i' <= `n' { 	
+			local len = length("``i''") 
+			if `len' > 80 { 
+				di in r "cannot handle word length > 80"
+				exit 498 
+			}
+			local i = `i' + 1 
+		}	
+	}	
+
+	local i = 1 
+	if "`pos'" != "" {
+		local negsign = index("`pos'", "-") 
+		if `negsign' { 
+			local pos1 = substr("`pos'",1,`negsign' - 1) 
+			local pos2 = substr("`pos'",`negsign', .) 
+			local pos2 = `n' + 1 + `pos2' 
+			local pos "`pos1'`pos2'" 
+			capture confirm integer number `pos' 
+			if _rc == 0 { local pos ">= `pos'" } 
+		} 	
+		else { 
+			capture confirm integer number `pos' 
+			if _rc == 0 { local pos "<= `pos'" }
+		} 	
+		while `i' <= `n' { 
+			if `i' `pos' { local list1 "`list1' ``i''" }
+			else local list2 "`list2' ``i''" 
+			local i = `i' + 1 
+		}
+	} 
+	else if "`value'" != "" { 
+		capture confirm number `value' 
+		if _rc == 0 { local value "<= `value'" }  
+		if `asstr' { 
+			while `i' <= `n' {
+				if "``i''" `value' { 
+					local list1 `"`list1' ``i''"' 
+				}
+				else local list2 `"`list2' ``i''"' 
+				local i = `i' + 1 
+			}
+		}	
+		else { 
+			while `i' <= `n' { 
+				if ``i'' `value' { 
+					local list1 "`list1' ``i''" 
+				}
+				else local list2 "`list2' ``i''" 
+				local i = `i' + 1
+			}
+		}	
+	} 		
+	else if "`length'" != "" { 
+		capture confirm number `length' 
+		if _rc == 0 { local length "<= `length'" }  
+		while `i' <= `n' { 
+			if length("``i''") `length' { 
+				local list1 "`list1' ``i''" 
+			}
+			else local list2 "`list2' ``i''" 
+			local i = `i' + 1
+		}
+	} 	
+	else { 
+		if `char' >= 0 { 
+			while `i' <= `n' { 
+				local one = substr("``i''",1,`char')
+				local two = substr("``i''",`char'+1,.) 
+				local list1 "`list1' `one'" 
+				local list2 "`list2' `two'" 
+				local i = `i' + 1 
+			} 
+		} 
+		else if `char' < 0 { 
+			while `i' <= `n' { 
+				local one = substr("``i''",`char',.)
+				local ltwo = length("``i''") + `char' 
+				local two = substr("``i''",1,`ltwo') 
+				local list1 "`list1' `one'" 
+				local list2 "`list2' `two'" 
+				local i = `i' + 1 
+			}
+		}
+	}
+	
+	if "`noisily'" != "" { 
+		di in g "list 1: " in y `"`list1'"' 
+		di in g "list 2: " in y `"`list2'"' 
+	}
+	if "`global1'" != "" { global `global1' `"`list1'"' } 
+	if "`global2'" != "" { global `global2' `"`list2'"' } 
+	return local list1 `"`list1'"'
+	return local list2 `"`list2'"'  
+end 	
+			
diff --git a/Modules/ado/plus/c/choplist.hlp b/Modules/ado/plus/c/choplist.hlp
new file mode 100644
index 0000000..eacf780
--- /dev/null
+++ b/Modules/ado/plus/c/choplist.hlp
@@ -0,0 +1,2 @@
+.h listutil
+
diff --git a/Modules/ado/plus/c/cmdchk.ado b/Modules/ado/plus/c/cmdchk.ado
new file mode 100644
index 0000000..56c0776
--- /dev/null
+++ b/Modules/ado/plus/c/cmdchk.ado
@@ -0,0 +1,66 @@
+*! version 1.0.4 PR 30sep2005
+* Based on private version 6.1.4 of frac_chk, PR 25aug2004
+program define cmdchk, sclass
+	version 7
+	local cmd `1'
+	mac shift
+	local cmds `*'
+	sret clear
+	if substr("`cmd'",1,3)=="reg" {
+		local cmd regress
+	}
+	if "`cmds'"=="" {
+		tokenize clogit cnreg cox ereg fit glm logistic logit poisson probit /*
+		*/ qreg regress rreg weibull xtgee streg stcox stpm stpmrs /*
+		*/ ologit oprobit mlogit nbreg
+	}
+	else tokenize `cmds'
+	sret local bad 0
+	local done 0
+	while "`1'"!="" & !`done' {
+		if "`1'"=="`cmd'" {
+			local done 1
+		}
+		mac shift
+	}
+	if !`done' {
+		sret local bad 1
+		*exit
+	}
+	/*
+		dist=0 (normal), 1 (binomial), 2 (poisson), 3 (cox), 4 (glm),
+		5 (xtgee), 6 (ereg/weibull), 7 (stcox, streg, stpm, stpmrs).
+	*/
+	if "`cmd'"=="logit" | "`cmd'"=="probit" /*
+ 	*/ |"`cmd'"=="clogit"| "`cmd'"=="logistic" /*
+ 	*/ |"`cmd'"=="mlogit"| "`cmd'"=="ologit" | "`cmd'"=="oprobit" {
+						sret local dist 1
+	}
+	else if "`cmd'"=="poisson" {
+						sret local dist 2
+	}
+	else if "`cmd'"=="cox" {
+						sret local dist 3
+	}
+	else if "`cmd'"=="glm" {
+						sret local dist 4
+	}
+	else if "`cmd'"=="xtgee" {
+						sret local dist 5
+	}
+	else if "`cmd'"=="cnreg" | "`cmd'"=="ereg" | "`cmd'"=="weibull" | "`cmd'"=="nbreg" {
+						sret local dist 6
+	}
+	else if "`cmd'"=="stcox" | "`cmd'"=="streg" | "`cmd'"=="stpm" | "`cmd'"=="stpmrs" {
+						sret local dist 7
+	}
+	else if substr("`cmd'",1,2)=="st" {
+						sret local dist 7
+	}
+	else					sret local dist 0
+
+	sret local isglm  = (`s(dist)'==4)
+	sret local isqreg = ("`cmd'"=="qreg")
+	sret local isxtgee= (`s(dist)'==5)
+	sret local isnorm = ("`cmd'"=="regress"|"`cmd'"=="fit"|"`cmd'"=="rreg") 
+end
diff --git a/Modules/ado/plus/c/collist.ado b/Modules/ado/plus/c/collist.ado
new file mode 100644
index 0000000..8e216e8
--- /dev/null
+++ b/Modules/ado/plus/c/collist.ado
@@ -0,0 +1,33 @@
+program def collist
+*! NJC 1.0.0 22 Dec 1999 
+	version 6
+	gettoken list 0 : 0, parse(",") 
+	if "`list'" == "" | "`list'" == "," { 
+		di in r "nothing in list"
+		exit 198 
+	}	
+	syntax [ , Format(str) NUmber ] 
+
+	tokenize `list'
+	
+        if "`number'" != "" { 	
+		local n : word count `list' 
+		local ndigits = length("`n'") 
+		local number = 0 
+	}
+
+	* asstr  >0    string format 
+	* asstr   0    numeric format 
+	* asstr  -1    default 
+	local asstr = cond("`format'" != "",index("`format'", "s"), -1) 
+	
+	while "`1'" != "" { 
+		if "`number'" != "" { 
+			local number = `number' + 1 
+			local num : di %`ndigits'.0f `number' ". " 
+		} 	
+		if `asstr' { di in g "`num'" `format' in y `"`1'"' } 
+		else di in g "`num'" `format' in y `1' 
+		mac shift 
+	}
+end 
diff --git a/Modules/ado/plus/c/collist.hlp b/Modules/ado/plus/c/collist.hlp
new file mode 100644
index 0000000..eacf780
--- /dev/null
+++ b/Modules/ado/plus/c/collist.hlp
@@ -0,0 +1,2 @@
+.h listutil
+
diff --git a/Modules/ado/plus/c/concord.ado b/Modules/ado/plus/c/concord.ado
new file mode 100644
index 0000000..39e0f3b
--- /dev/null
+++ b/Modules/ado/plus/c/concord.ado
@@ -0,0 +1,433 @@
+*! 3.0.7  9aug2007  TJS & NJC fixed Stata 10 bug by adding missing -version- 
+*  3.0.6 14may2006  TJS & NJC fixed Stata 9 bug with -by()- 
+// 3.0.5 22aug2005  Stata 8 - fixed legend(off)
+// 3.0.4 27jan2005  TJS & NJC rewrite for Stata 8 + more for graphs
+// 3.0.3  6oct2004  TJS & NJC rewrite for Stata 8
+// 3.0.2  6oct2004  TJS & NJC rewrite for Stata 8
+// 3.0.1  4oct2004  TJS & NJC rewrite for Stata 8 + fixes + noref
+// 3.0.0 27jul2004  TJS & NJC rewrite for Stata 8
+// 3.0.0 19jul2004  TJS & NJC rewrite for Stata 8
+// 2.2.9 14jan2003  TJS & NJC handling of [ ] within connect()
+// 2.2.8  2jan2003  TJS & NJC handling of [ ] within symbol()
+// 2.2.7 30jan2002  TJS & NJC rho_se corrected  (SJ2-2: st0015)
+// 2.2.6 10dec2001  TJS & NJC bug fixes (labels, diag line)
+// 2.2.5 23apr2001  TJS & NJC sortpreserve
+// 2.2.4 24jan2001  TJS & NJC l1title for loa
+// 2.2.3  8sep2000  TJS & NJC bug fixes & mods  (STB-58: sg84.3)
+// 2.2.0 16dec1999  TJS & NJC version 6 changes (STB-54: sg84.2)
+// 2.1.6 18jun1998  TJS & NJC STB-45 sg84.1
+// 2.0.2  6mar1998  TJS & NJC STB-43 sg84
+//
+// syntax:	concord vary varx [fw] [if] [in] [,
+//			BY(varname) Summary LEvel(real `c(level)')
+//			CCC(str) LOA(str) QNORMD(str) ]
+
+program concord, rclass sortpreserve
+// Syntax help
+	if "`1'" == "" {
+		di "{p}{txt}Syntax is: {inp:concord} "						///
+		"{it:vary varx} [{it:weight}] "								///
+		"[{inp:if} {it:exp}] [{inp:in} {it:range}] "				///
+		"[, {inp:by(}{it:byvar}{inp:)} "							///
+		"{inp:summary level(}{it:#}{inp:)} "						///
+		"{inp:ccc}[{inp:(noref} {it:ccc_options}{inp:)}] "			///
+		"{inp:loa}[{inp:(noref regline} {it:loa_options}{inp:)}] "	///
+		"{inp:qnormd}[{inp:(}{it:qnormd_options}{inp:)}] {p_end}"
+		exit 0
+	}
+
+// Setup
+	version 8 
+	syntax varlist(numeric min=2 max=2)	///
+	[fw]								///
+	[if] [in]							///
+	[ , BY(varname)						///
+	Summary								///
+	LEvel(real `c(level)')				///
+	ccc(str asis)						///
+	CCC2								///
+	loa(str asis)						///
+	LOA2								///
+	qnormd(str asis)					///
+	QNORMD2 * ]
+
+	marksample touse
+	qui count if `touse'
+	if r(N) == 0 error 2000
+
+	tokenize `varlist'
+
+// Set temporary names
+	tempvar d d2 db dll dul m byg kk bylabel
+	tempname dsd zv k xb yb sx2 sy2 r rp sxy p u sep z zp
+	tempname t set ll ul llt ult rdm Fdm zt ztp sd1 sd2 sl
+
+// Set up wgt
+	if "`weight'" != "" local wgt "[`weight'`exp']"
+
+// Generate CI z-value and label from Level()
+	if `level' < 1 local level = `level' * 100
+	scalar `zv' = -1 * invnorm((1 - `level' / 100) / 2)
+	local rl = `level'
+	local level : di %7.0g `level'
+	local level = ltrim("`level'")
+
+// Generate BY groups
+	qui {
+		bysort `touse' `by' : gen byte `byg' = _n == 1 if `touse'
+		if "`by'" != "" gen `kk' = _n if `byg' == 1
+		replace `byg' = sum(`byg')
+		local byn = `byg'[_N]
+
+// Generate `by' labels -- if required
+		if "`by'" != "" {
+			capture decode `by', gen(`bylabel')
+			if _rc != 0 {
+				local type : type `by'
+				gen `type' `bylabel' = `by'
+			}
+		}
+	}
+
+// Print title
+	di
+	di as txt "Concordance correlation coefficient (Lin, 1989, 2000):"
+
+// Do calculations
+	forval j = 1/`byn' {  /* start of loop for each `by' group */
+		di
+		if "`by'" != "" {
+			sort `kk'
+			di as txt "{hline}"
+			di as txt "-> `by' = " `bylabel'[`j'] _n
+			local byl : di "`by' = " `bylabel'[`j']
+		}
+
+// LOA (Bland & Altman) calculations
+		qui {
+			gen `d' = `1' - `2'
+			gen `d2' = `d'^2
+			su `d' if `byg' == `j' `wgt'
+			gen `db' = r(mean)
+			scalar `dsd' = r(sd)
+			gen `dll' = `db' - `zv' * `dsd'
+			gen `dul' = `db' + `zv' * `dsd'
+			gen `m' = (`1' + `2') / 2
+		}
+
+// Concordance calculations
+		qui su `1' if `byg' == `j' `wgt'
+		scalar `k'   = r(N)
+		scalar `yb'  = r(mean)
+		scalar `sy2' = r(Var) * (`k' - 1) / `k'
+		scalar `sd1' = r(sd)
+
+		qui su `2' if `byg' == `j' `wgt'
+		scalar `xb'  = r(mean)
+		scalar `sx2' = r(Var) * (`k' - 1) / `k'
+		scalar `sd2' = r(sd)
+
+		qui corr `1' `2' if `byg' == `j' `wgt'
+		scalar `r'  = r(rho)
+		scalar `sl' = sign(`r') * `sd1' / `sd2'
+
+		scalar `rp'  = min(tprob(r(N) - 2, r(rho) * sqrt(r(N) -  2) ///
+		               / sqrt(1 - r(rho)^2)) ,1)
+		scalar `sxy' = `r' * sqrt(`sx2' * `sy2')
+		scalar `p'   = 2 * `sxy' / (`sx2' + `sy2' + (`yb' - `xb')^2)
+		scalar `u'   = (`yb' - `xb') / (`sx2' * `sy2')^.25
+
+// --- variance, test, and CI for asymptotic normal approximation
+		//   scalar `sep' = sqrt(((1 - ((`r')^2)) * (`p')^2 * (1 -
+		//     ((`p')^2)) / (`r')^2 + (4 * (`p')^3 * (1 - `p') * (`u')^2
+		//     / `r') - 2 * (`p')^4 * (`u')^4 / (`r')^2 ) / (`k' - 2))
+// Corrected se: per Lin (March 2000) Biometrics 56:325-5.
+		#delimit ;
+		scalar `sep' = sqrt(((1 - ((`r')^2)) * (`p')^2 * (1 -
+		  ((`p')^2)) / (`r')^2 + (2 * (`p')^3 * (1 - `p') * (`u')^2
+		  / `r') - .5 * (`p')^4 * (`u')^4 / (`r')^2 ) / (`k' - 2));
+		#delimit cr
+		scalar `z'  = `p' / `sep'
+		scalar `zp' = 2 * (1 - normprob(abs(`z')))
+		scalar `ll' = `p' - `zv' * `sep'
+		scalar `ul' = `p' + `zv' * `sep'
+
+// --- statistic, variance, test, and CI for inverse hyperbolic
+//      tangent transform to improve asymptotic normality
+		scalar `t'   = ln((1 + `p') / (1 - `p')) / 2
+		scalar `set' = `sep' / (1 - ((`p')^2))
+		scalar `zt'  = `t' / `set'
+		scalar `ztp' = 2 * (1 - normprob(abs(`zt')))
+		scalar `llt' = `t' - `zv' * `set'
+		scalar `ult' = `t' + `zv' * `set'
+		scalar `llt' = (exp(2 * `llt') - 1) / (exp(2 * `llt') + 1)
+		scalar `ult' = (exp(2 * `ult') - 1) / (exp(2 * `ult') + 1)
+
+// Print output
+		di as txt " rho_c   SE(rho_c)   Obs    [" _c
+		if index("`level'",".") {
+			di as txt %6.1f `level' "% CI  ]     P        CI type"
+		}
+		else di as txt "   `level'% CI   ]     P        CI type"
+
+		di as txt "{hline 63}"
+		di as res %6.3f `p' %10.3f `sep' %8.0f `k' %10.3f `ll' _c
+		di as res %7.3f `ul' %9.3f `zp' as txt "   asymptotic"
+		di as res _dup(24) " " %10.3f `llt' %7.3f `ult' %9.3f `ztp' _c
+		di as txt "  z-transform"
+
+		di _n as txt "Pearson's r =" as res %7.3f `r' _c
+		di    as txt "  Pr(r = 0) =" as res %6.3f `rp' _c
+		di    as txt "  C_b = rho_c/r =" as res %7.3f `p' / `r'
+		di    as txt "Reduced major axis:   Slope = " as res %9.3f `sl' _c
+		di    as txt "   Intercept = " as res %9.3f `yb'-`xb'*`sl'
+		di _n as txt "Difference = `1' - `2'"
+		di _n as txt "        Difference" _c
+		if index("`level'", ".") {
+		     di _col(33) as txt %6.1f `level' "% Limits Of Agreement"
+		}
+		else di _col(33) as txt     "   `level'% Limits Of Agreement"
+		di as txt "   Average     Std Dev.             (Bland & Altman, 1986)"
+		di as txt "{hline 63}"
+		di as res %10.3f `db' %12.3f `dsd' _c
+		di as res "            " %11.3f `dll' %11.3f `dul'
+
+		qui corr `d' `m' if `byg' == `j' `wgt'
+		scalar `rdm' = r(rho)
+		di _n as txt "Correlation between difference and mean =" _c
+		local fmt = cond(r(rho) < 0, "%7.3f", "%6.3f")
+		di as res `fmt' r(rho)
+
+		su `d2' if `byg' == `j' `wgt', meanonly
+		local sumd2 = r(sum)
+		qui reg `d' `m' if `byg' == `j' `wgt'
+		scalar `Fdm' = ((`sumd2' - e(rss)) / 2) / (e(rss) / e(df_r))
+		di _n as txt "Bradley-Blackwood F = " ///
+		      as res %4.3f `Fdm' ///
+		      as txt " (P = " %6.5f ///
+		      as res 1 - F(2, e(df_r), `Fdm') ///
+		      as txt ")"
+
+		if "`summary'" != "" su `1' `2' if `byg' == `j' `wgt'
+
+// setup local options for passing to graph routines
+		if "`byl'"   != "" local byls byl("`byl'")
+		if "`level'" != "" local levs level(`level')
+
+// set more if needed		
+		if (`"`loa'`loa2'"' != "" & `"`qnormd'`qnormd2'"' != "") |    ///
+		   (`"`loa'`loa2'"' != "" & `"`ccc'`ccc2'"'       != "") |    ///
+		   (`"`ccc'`ccc2'"' != "" & `"`qnormd'`qnormd2'"' != "")   {
+		   
+		   local moreflag "more"
+		}
+		    
+// loa graph
+		if `"`loa'`loa2'"' != "" {
+			gphloa `2' `1' `dll' `db' `dul' `d' `m' `byg' ///
+			`wgt', j(`j') byn(`byn') `byls' `levs' `loa' `options'
+			
+            `moreflag'
+		}
+
+// qnormd graph
+		if `"`qnormd'`qnormd2'"' != "" {
+			gphqnormd `2' `1' `d' `byg' ///
+			`wgt', j(`j') byn(`byn') `byls' `levs' `qnormd' `options'
+			
+            `moreflag'
+		}
+
+// ccc graph
+		if `"`ccc'`ccc2'"' != "" {
+			local sll = `sl'
+			local xbl = `xb'
+			local ybl = `yb'
+			gphccc `1' `2' `byg' `wgt', j(`j') ///
+			xb(`xbl') yb(`ybl') sl(`sll') byn(`byn') `byls' `ccc' `options'
+		}
+
+		if `byn' > 1 {
+			capture drop `d' 
+			capture drop `d2' 
+			capture drop `db' 
+			capture drop `dll' 
+			capture drop `dul'
+			capture drop `m'
+		}	
+
+	} /* end of loop for each `by' group */
+
+// save globals
+	if `byn' == 1 {
+		return scalar        N = `k'
+		return scalar    rho_c = `p'
+		return scalar se_rho_c = `sep'
+		return scalar  asym_ll = `ll'
+		return scalar  asym_ul = `ul'
+		return scalar  z_tr_ll = `llt'
+		return scalar  z_tr_ul = `ult'
+		return scalar      C_b = `p' / `r'
+		return scalar     diff = `db'
+		return scalar  sd_diff = `dsd'
+		return scalar   LOA_ll = `dll'
+		return scalar   LOA_ul = `dul'
+		return scalar      rdm = `rdm'
+		return scalar      Fdm = `Fdm'
+
+// double save globals
+// now undocumented as of 3.0.0
+		global S_1  = `k'
+		global S_2  = `p'
+		global S_3  = `sep'
+		global S_4  = `ll'
+		global S_5  = `ul'
+		global S_6  = `llt'
+		global S_7  = `ult'
+		global S_8  = `p' / `r'
+		global S_9  = `db'
+		global S_10 = `dsd'
+		global S_11 = `dll'
+		global S_12 = `dul'
+	}
+end
+
+program gphloa
+// loa graph
+	version 8
+	syntax varlist(numeric min=2) [fw]								///
+	[ , J(int 1) BYN(int 1) BYL(str) REGline LEvel(real `c(level)')	///
+	plot(str asis) noREF * ]
+
+	tokenize `varlist'
+	args two one dll db dul d m byg
+	if "`weight'" != "" local wgt "[`weight'`exp']"
+
+	if `"`byl'"' != "" local t2title `"t2title(`byl')"'
+
+	local name2 : variable label `2'
+	local name1 : variable label `1'
+	local lnth = length(`"`name2'"') + length(`"`name1'"')
+	if `"`name2'"' == `""' | `lnth' > 50 local name2 "`2'"
+	if `"`name1'"' == `""' | `lnth' > 50 local name1 "`1'"
+
+	qui if "`regline'" != "" {
+		tempvar fit
+		regress `d' `m' if `byg' == `j' `wgt'
+		predict `fit'
+	}
+
+	if "`ref'" == "" {
+	   local ord 2 3
+	   if "`regline'" != "" local ord 2 3 4
+	   local zero yli(0, lstyle(refline)) yscale(range(0)) ylabel(0, add)	///
+	   legend(on order(`ord') label(2 observed average agreement)			///
+	   label(3 `"`level'% limits of agreement"') label(4 regression line))	///
+	   caption("y=0 is line of perfect average agreement")
+	}
+    	
+	graph twoway line `dll' `db' `dul' `fit' `m' if `byg' == `j',		///
+		clcolor(red purple red green) sort								///
+		|| scatter `d' `m' if `byg' == `j'								///
+		, ms(oh) `t2title'												///
+		yti(`"Difference of `name2' and `name1'"')						///
+		xti(`"Mean of `name2' and `name1'"')							///
+		caption("`level'% Limits Of Agreement") legend(off) `zero'      ///
+		`options' ///
+	|| `plot'
+
+	if `byn' > 1 more
+end
+
+program gphqnormd, sort
+// normal prob plot
+// note: logic pilfered from qnorm
+	version 8
+	syntax varlist(numeric min=2) [fw]							///
+	[ , J(int 1) BYN(int 1) BYL(str) LEvel(real `c(level)')		///
+	plot(str asis) * ]
+
+	args two one d byg
+	if "`weight'" != "" local wgt "[`weight'`exp']"
+	else local exp 1
+
+	local name2 : variable label `2'
+	local name1 : variable label `1'
+	local lnth = length(`"`name2'"') + length(`"`name1'"')
+	if `"`name2'"' == `""' | `lnth' > 50 local name2 "`2'"
+	if `"`name1'"' == `""' | `lnth' > 50 local name1 "`1'"
+
+	tempvar Z Psubi touse2
+	mark `touse2' if `byg' == `j'
+	qui {
+		gsort -`touse2' `d'
+		gen `Psubi' = sum(`touse2' * `exp')
+		replace `Psubi' = cond(`touse2' == 0, ., `Psubi'/(`Psubi'[_N] + 1))
+		su `d' if `touse2' == 1 `wgt'
+		gen float `Z' = invnorm(`Psubi') * r(sd) + r(mean)
+		label var `Z' "Inverse Normal"
+		local xttl : var label `Z'
+		local yttl `"Difference of `name2' and `name1'"'
+	}
+
+	if `"`byl'"' != "" local t2title `"t2title(`byl')"'
+
+	graph twoway						///
+		(scatter `d' `Z',				///
+			sort						///
+			ytitle(`"`yttl'"')			///
+			xtitle(`"`xttl'"')			///
+			`t2title'					///
+			`options'					///
+		)								///
+		(function y=x,					///
+			range(`Z')					///
+			n(2)						///
+			clstyle(refline)			///
+			yvarlabel("Reference")		///
+			yvarformat(`fmt')			///
+		)								///
+		, legend(off)					///
+	|| `plot'
+
+	if `byn' > 1 more
+end
+
+program gphccc
+	version 8
+//-----------------------------------------------------
+// ccc graph
+// ----------------------------------------------------
+	syntax varlist(numeric min=2) [fw] [ , J(int 1) XB(real 0) noREF ///
+	YB(real 0) SL(real 0) BYN(int 1) BYL(str) plot(str asis) LEGEND(str) * ]
+
+	tokenize `varlist'
+	tempvar byg rmaxis
+	local byg `3'
+	if "`weight'" != "" local wgt "[`weight'`exp']"
+
+	local yttl : variable label `1'
+	if `"`yttl'"' == "" local yttl "`1'"
+	local xttl : variable label `2'
+	if `"`xttl'"' == "" local xttl "`2'"
+
+    if "`ref'" == "" local lopc || function y = x, ra(`2') clstyle(refline) ///
+      legend(on order(2 "reduced major axis" 3 "line of perfect concordance"))
+
+    if "`legend'" != "" {
+      local legnd "legend(`legend')"
+    }
+          
+// Graph concordance plot
+	qui gen `rmaxis' = `sl' * (`2' - `xb') + `yb'
+
+	graph twoway scatter `1' `rmaxis' `2'						///
+		if `byg' == `j' `wgt',									///
+		sort connect(none line) ms(oh none)						///
+		yti(`"`yttl'"') xti(`"`xttl'"') legend(off) `lopc'      ///
+		`options'	///
+	|| `plot'
+
+	if `byn' > 1 more
+end
+
diff --git a/Modules/ado/plus/c/concord.dlg b/Modules/ado/plus/c/concord.dlg
new file mode 100644
index 0000000..b4b230b
--- /dev/null
+++ b/Modules/ado/plus/c/concord.dlg
@@ -0,0 +1,183 @@
+/* Dialog (Version 3.0.1) by: T. J. Steichen, steichen@triad.rr.com
+
+concord       VERSION 3.0.3  6oct2004
+
+ syntax: concord vary varx [fw] [if] [in] [,
+         BY(varname) Summary LEvel(real 95) ccc[(noREF ccc_graph_options)]
+         loa[(noREF REGline loa_graph_options)] qnormd[(qnormd_graph_options}] ]
+
+
+Install in User Statistics menu via:
+  . window menu append item "stUserStatistics" "&concord (Concordance correlation coefficient)" "db concord3"
+  . window menu refresh
+To permanently install, place the commands in your -profile.do- file.
+*/
+
+VERSION 8.0
+
+INCLUDE _std_small
+INCLUDE header
+
+HELP hlp1, view("help concord")
+RESET res1
+
+DIALOG main, label("concord - Concordance correlation coefficient") tabtitle("Main")
+BEGIN
+  TEXT     tx_yvar            _lft      _top      150      .,     ///
+     label("Y Variable:")
+  VARNAME  vn_yvar            @         _ss       @        .,     ///
+     label("Y Variable")
+  TEXT     tx_xvar            180       _top      150      .,     ///
+     label("X Variable:")
+  VARNAME  vn_xvar            @         _ss       @        .,     ///
+     label("X Variable")
+
+  CHECKBOX cb_by          10  70  50 .,                           ///
+     label("By:")                                                 ///
+     onclickon(main.vn_by.enable)                                 ///
+     onclickoff(main.vn_by.disable)
+  VARNAME  vn_by          60  70  270 .,                          ///
+     label("By Variable")                                         ///
+     option("by")
+
+  CHECKBOX cb_summary     10 100  300 .,                          ///
+     label("Show Summary")                                        ///
+     option("summary")
+
+  CHECKBOX cb_level       10 130   50 .,                          ///
+     label("Level:")                                              ///
+     onclickon(main.ed_level.enable)                              ///
+     onclickoff(main.ed_level.disable)
+  EDIT     ed_level       60   @   40 .,                          ///
+     label("Level")                                               ///
+     numonly default(global S_level)                              ///
+     option("level")
+END
+
+INCLUDE ifin
+INCLUDE weights_f
+
+DIALOG graph, tabtitle("Graph")
+BEGIN
+  CHECKBOX cb_ccc       20  10  150 .,                            ///
+     label("Concordance")                                         ///
+     onclickon(script ccc_on)                                     ///
+     onclickoff(script ccc_off)                                   ///
+     option("ccc")
+  CHECKBOX cb_ccc_ref   40  30  140 .,                            ///
+     label("No CCC Reference Line")
+  CHECKBOX cb_ccc_opt   40  50   90 .,                            ///
+     label("CCC Options:")                                        ///
+     onclickon(graph.ed_ccc_opt.enable)                           ///
+     onclickoff(graph.ed_ccc_opt.disable)
+  EDIT     ed_ccc_opt  130  50  200 .,                            ///
+     label("CCC Opts")
+
+  CHECKBOX cb_loa       20  70  150 .,                            ///
+     label("Limits of Agreement")                                 ///
+     onclickon(script loa_on)                                     ///
+     onclickoff(script loa_off)                                   ///
+     option("loa")
+  CHECKBOX cb_loa_ref   40  90  140 .,                            ///
+     label("No LOA Reference Line")
+  CHECKBOX cb_loa_reg   40 110  140 .,                            ///
+     label("Regression Line")
+  CHECKBOX cb_loa_opt   40 130   90 .,                            ///
+     label("LOA Options:")                                        ///
+     onclickon(graph.ed_loa_opt.enable)                           ///
+     onclickoff(graph.ed_loa_opt.disable)
+  EDIT     ed_loa_opt  130 130  200 .,                            ///
+     label("LOA Opts")
+
+  CHECKBOX cb_qnormd    20 150  150 .,                            ///
+     label("Differences Normal plot")                             ///
+     onclickon(graph.cb_qnormd_opt.enable)                        ///
+     onclickoff(graph.cb_qnormd_opt.disable)                      ///
+     option("qnormd")
+  CHECKBOX cb_qnormd_opt   40 170   90 .,                         ///
+     label("QND Options:")                                        ///
+     onclickon(graph.ed_qnormd_opt.enable)                        ///
+     onclickoff(graph.ed_qnormd_opt.disable)
+  EDIT   ed_qnormd_opt 130 170  200 .,                            ///
+     label("QND Opts")
+END
+
+SCRIPT ccc_on
+BEGIN
+  graph.cb_ccc_ref.enable
+  graph.cb_ccc_opt.enable
+END
+
+SCRIPT ccc_off
+BEGIN
+  graph.cb_ccc_ref.disable
+  graph.cb_ccc_opt.disable
+END
+
+SCRIPT loa_on
+BEGIN
+  graph.cb_loa_ref.enable
+  graph.cb_loa_reg.enable
+  graph.cb_loa_opt.enable
+END
+
+SCRIPT loa_off
+BEGIN
+  graph.cb_loa_ref.disable
+  graph.cb_loa_reg.disable
+  graph.cb_loa_opt.disable
+END
+
+PROGRAM command
+BEGIN
+  put "concord "
+  varlist main.vn_yvar main.vn_xvar
+  INCLUDE _weights_pr
+  INCLUDE _ifin_pr
+  beginoptions
+     optionarg main.vn_by
+     option    main.cb_summary
+     optionarg main.ed_level
+     if graph.cb_ccc {
+        put "ccc"
+        if graph.cb_ccc_ref | graph.cb_ccc_opt {
+           put "("
+        }
+        if graph.cb_ccc_ref {
+           put "noref "
+        }
+        if graph.cb_ccc_opt {
+           put graph.ed_ccc_opt
+        }
+        if graph.cb_ccc_ref | graph.cb_ccc_opt {
+           put ") "
+        }
+     }
+     if graph.cb_loa {
+        put "loa"
+        if graph.cb_loa_ref | graph.cb_loa_opt | graph.cb_loa_reg {
+           put "("
+        }
+        if graph.cb_loa_ref {
+           put "noref "
+        }
+        if graph.cb_loa_reg {
+           put "regline "
+        }
+        if graph.cb_loa_opt {
+           put graph.ed_loa_opt
+        }
+        if graph.cb_loa_ref | graph.cb_loa_opt | graph.cb_loa_reg {
+           put ") "
+        }
+     }
+     if graph.cb_qnormd {
+        put "qnormd"
+        if graph.cb_qnormd_opt {
+           put "("
+           put graph.ed_qnormd_opt
+           put ") "
+        }
+     }
+  endoptions
+END
diff --git a/Modules/ado/plus/c/concord.hlp b/Modules/ado/plus/c/concord.hlp
new file mode 100644
index 0000000..8d29923
--- /dev/null
+++ b/Modules/ado/plus/c/concord.hlp
@@ -0,0 +1,275 @@
+{smcl}
+{* 6oct2004/23aug2005/14may2006/9aug2007}
+{hline}
+{hi:help concord} {right:(SJ7-3: st0015_4)}
+{hline}
+
+{title:Title}
+
+{p2colset 5 16 18 2}{...}
+{p2col:{hi:concord} {hline 2}}Concordance correlation coefficient and associated measures, tests, and graphs{p_end}
+{p2colreset}{...}
+
+
+{title:Syntax}
+
+{p 8 17 2}
+{cmd:concord}
+{it:vary} {it:varx}
+{ifin}
+{weight}
+[{cmd:,}
+{cmd:by(}{it:byvar}{cmd:)}
+{cmdab:s:ummary}
+{cmdab:le:vel(}{it:#}{cmd:)}
+{cmd:ccc}[{cmd:(noref} {it:ccc_options}{cmd:)}]
+{cmd:loa}[{cmd:(noref} {cmdab:reg:line} {it:loa_options}{cmd:)}]
+{cmd:qnormd}[{cmd:(}{it:qnormd_options}{cmd:)}]]
+
+
+{title:Description}
+
+{p 4 4 2}
+{cmd:concord} computes Lin's (1989, 2000) concordance correlation coefficient
+for agreement on a continuous measure obtained by two persons or methods. (The
+measure was introduced earlier by Krippendorff (1970).) The concordance
+correlation coefficient combines measures of both precision and accuracy to
+determine how far the observed data deviate from the line of perfect
+concordance (i.e., the line at 45 degrees on a square scatter plot). Lin's
+coefficient increases in value as a function of the nearness of the data's
+reduced major axis to the line of perfect concordance (the accuracy of the
+data) and of the tightness of the data about its reduced major axis (the
+precision of the data).  The Pearson correlation coefficient, r, the
+bias-correction factor, C_b, and the equation of the reduced major axis are
+reported to show these components.  Note that the concordance correlation
+coefficient, rho_c, can be expressed as the product of r, the measure of
+precision, and C_b, the measure of accuracy.
+
+{p 4 4 2}
+{cmd:concord} also provides results for Bland and Altman's
+limits-of-agreement, "loa", procedure (1986). The loa, a data-scale assessment
+of the degree of agreement, is a complementary approach to the
+relationship-scale approach of Lin.
+
+{p 4 4 2}
+Finally, two other results are reported:
+
+{p 8 8 2}
+1. The correlation between difference and mean. In one interpretation
+this is a test statistic for a null hypothesis of equal variances given
+bivariate normality (Pitman 1939; also see Snedecor and Cochran 1989, 192-193).
+Alternatively, it is an exploratory diagnostic.
+A value near zero implies concordance.
+
+{p 8 8 2}
+2. An F test of equality of means and variances. Note that this too
+assumes bivariate normality (Bradley and Blackwood 1989).
+See also Hsu (1940) and Reynolds and Gregoire (1991).
+Nonsignificance implies concordance.
+
+{p 4 4 2}
+The user provides the pairs of measurements for a single property as
+observations in variables {it:vary} and {it:varx}.  Frequency weights may be
+specified and used. Missing values (if any) are deleted in a casewise manner.
+
+{p 4 4 2}
+Various associated graphs may be obtained through options.
+See below for explanations of the options {cmd:ccc}, {cmd:loa}, and 
+{cmd:qnormd}.
+
+
+{title:Options}
+
+{p 4 8 2}
+{cmd:by(}{it:byvar}{cmd:)} produces separate results for groups of
+observations defined by {it:byvar}.
+
+{p 4 8 2}
+{cmd:summary} requests summary statistics.
+
+{p 4 8 2}
+{cmd:level(}{it:#}{cmd:)} sets the confidence level % for the CI; default is
+{cmd:c(level)}.
+
+{p 4 8 2}
+{cmd:ccc} requests a graphical display of the data and the reduced major axis
+of the data. The reduced major axis or SD line goes through the intersection of
+the means and has slope given by the sign of Pearson's r and the ratio of the
+standard deviations. The SD line serves as a summary of the center of the data.
+
+{p 8 8 2}
+{cmd:ccc()} suboption {cmd:noref} suppresses the reference line of
+perfect concordance, y=x.
+
+{p 8 8 2}
+{cmd:ccc()} may also be specified with other options, which should
+be options of {helpb scatter}. For example, the scheme may be changed by a
+call such as {cmd:ccc(scheme(lean1)}.
+
+{p 4 8 2}
+{cmd:loa} requests a graphical display of the loa, the mean difference, and
+the data presented as paired differences plotted against pair-wise means.
+
+{p 8 8 2}
+{cmd:loa()} suboption {cmd:noref} suppresses the reference line of perfect
+average agreement, y=0.
+
+{p 8 8 2}
+{cmd:loa()} suboption {cmd:regline} adds a regression line to the loa plot
+fitting the paired differences to the pair-wise means.
+
+{p 8 8 2}
+{cmd:loa()} may also be specified with other options, which should normally
+be options of {helpb scatter}.  For example,
+the reference line of perfect average agreement was generated as
+{cmd:loa(yline(0, lstyle(refline)) yscale(range(0)) ylabel(0, add))}.
+
+{p 4 8 2}
+{cmd:qnormd} requests a normal plot of differences.
+
+{p 8 8 2}
+{cmd:qnormd()} may also be specified with options, which should
+be options of {helpb scatter}. For example,
+{cmd:qnormd(title(Normal plot of differences))} adds a title to the graph.
+
+
+{title:Comments}
+
+{p 4 4 2}
+Lin (2000) reported typographical errors in his original 1989 paper
+that affected calculation of the standard error of rho_c. These corrections
+were included in {cmd:concord} in version 2.2.7 (January 2002) when the erratum
+was brought to the attention of the program authors by Dr. Benjamin Littenberg.
+We thank Dr. Littenberg.
+
+{p 4 4 2}Kevan Polkinghorne pointed out a problem with {cmd:loa()}. 
+Mark Marshall pointed out a problem with {cmd:by()} under Stata 9. 
+
+{p 4 4 2}
+Dunn (2004) contains a bibliography on related work.
+Cox (2004) discusses other graphical approaches to this and related
+problems. Cox (2006) discusses concordance correlation and 
+other numerical and graphical methods for assessing agreement
+with various scientific examples. 
+
+
+{title:Saved results}
+
+{p 4 4 2}
+The following items are returned in {cmd:r()}, if the {cmd:by()} option was
+not used:
+
+{p 8 18}{cmd:r(N)}{space 9}number of observations compared{p_end}
+{p 8 18}{cmd:r(rho_c)}{space 5}concordance correlation coefficient rho_c{p_end}
+{p 8 18}{cmd:r(se_rho_c)}{space 2}standard error of rho_c{p_end}
+{p 8 18}{cmd:r(asym_ll)}{space 3}lower CI limit (asymptotic){p_end}
+{p 8 18}{cmd:r(asym_ul)}{space 3}upper CI limit (asymptotic){p_end}
+{p 8 18}{cmd:r(z_tr_ll)}{space 3}lower CI limit (z-transform){p_end}
+{p 8 18}{cmd:r(z_tr_ul)}{space 3}upper CI limit (z-transform){p_end}
+{p 8 18}{cmd:r(C_b)}{space 7}bias-correction factor C_b{p_end}
+{p 8 18}{cmd:r(diff)}{space 6}mean difference{p_end}
+{p 8 18}{cmd:r(sd_diff)}{space 3}standard deviation of mean difference{p_end}
+{p 8 18}{cmd:r(LOA_ll)}{space 4}lower loa CI limit{p_end}
+{p 8 18}{cmd:r(LOA_ul)}{space 4}upper loa CI limit{p_end}
+{p 8 18}{cmd:r(rdm)}{space 7}correlation between difference and mean{p_end}
+{p 8 18}{cmd:r(Fdm)}{space 7}F from Bradley-Blackwood test{p_end}
+
+
+{title:Examples}
+
+{p 4 8 2}
+{cmd:. concord rater1 rater2}
+
+{p 4 8 2}
+{cmd:. concord rater1 rater2 [fw=freq]}
+
+{p 4 8 2}
+{cmd:. concord rater1 rater2, summary ccc}
+
+{p 4 8 2}
+{cmd:. concord rater1 rater2, summary ccc(noref)}
+
+{p 4 8 2}
+{cmd:. concord rater1 rater2, level(90) by(grp)}
+
+{p 4 8 2}
+{cmd:. concord rater1 rater2, loa(regline noref)}
+
+{p 4 8 2}
+{cmd:. concord rater1 rater2, qnormd(title(Normal plot))}
+
+
+{title:Authors}
+
+{p 4 4 2}
+Thomas J. Steichen, Winston-Salem, NC, USA, steichen@triad.rr.com
+
+{p 4 4 2}
+Nicholas J. Cox, Durham University, UK, n.j.cox@durham.ac.uk
+
+
+{title:References}
+
+{p 4 8 2}
+Bland, J. M., and D. G. Altman.  1986. Statistical methods for assessing
+agreement between two methods of clinical measurement. {it:Lancet} I:
+307{c -}310.
+
+{p 4 8 2}
+Bradley, E. L., and L. G. Blackwood. 1989. Comparing paired data:
+a simultaneous test for means and variances. {it:American Statistician}
+43: 234{c -}235.
+
+{p 4 8 2}
+Cox, N. J. 2004. Graphing agreement and disagreement.
+{it:Stata Journal} 4: 329{c -}349.
+
+{p 4 8 2}
+------. 2006. 
+Assessing agreement of measurements and predictions in geomorphology. 
+{it:Geomorphology} 76: 332{c -}346. 
+
+{p 4 8 2}
+Dunn, G. 2004.
+{it: Statistical Evaluation of Measurement Errors: Design and Analysis of Reliability Studies.}
+London: Arnold.
+
+{p 4 8 2}
+Hsu, C. T. 1940. On samples from a normal bivariate population.
+{it:Annals of Mathematical Statistics} 11: 410{c -}426.
+
+{p 4 8 2}
+Krippendorff, K. 1970. Bivariate agreement coefficients for reliability of data.
+In Borgatta, E.F. and G.W. Bohrnstedt (eds)
+{it:Sociological Methodology}. San Francisco: Jossey-Bass, 139{c -}150.
+[a.k.a. {it:Sociological Methodology} 2: 139{c -}150]
+
+{p 4 8 2}
+Lin, L. I-K. 1989. A concordance correlation coefficient to evaluate
+reproducibility. {it:Biometrics} 45: 255{c -}268.
+
+{p 4 8 2}
+------. 2000. A note on the concordance correlation coefficient.
+{it:Biometrics} 56: 324{c -}325.
+
+{p 4 8 2}
+Pitman, E. J. G. 1939. A note on normal correlation.
+{it:Biometrika} 31: 9{c -}12.
+
+{p 4 8 2}
+Reynolds, M., and T. G. Gregoire. 1991. Comment on Bradley and Blackwood.
+{it:American Statistician} 45: 163{c -}164.
+
+{p 4 8 2}
+Snedecor, G. W., and W. G. Cochran. 1989. {it:Statistical Methods.}
+Ames, IA: Iowa State University Press.
+
+
+{title:Also see}
+
+{p 4 13 2}
+STB:  STB-43 sg84; STB-45 sg84.1; STB-54 sg84.2; STB-58 sg84.3
+
+{psee}
+SJ:{space 3}SJ2-2 st0015; SJ4-4 st0015_1; SJ5-3: st0015_2; SJ6-2: st0015_3
+{p_end}
diff --git a/Modules/ado/plus/c/confa.ado b/Modules/ado/plus/c/confa.ado
new file mode 100644
index 0000000..4359119
--- /dev/null
+++ b/Modules/ado/plus/c/confa.ado
@@ -0,0 +1,1090 @@
+*! v.2.0.2 Confirmatory factor analysis, by Stas Kolenikov, skolenik at gmail dot com, 08 Sep 2009
+program define confa, eclass properties( svyr svyb svyj ) sortpreserve
+  version 10.0
+
+  if replay() {
+     if ("`e(cmd)'" != "confa") error 301
+     Replay `0'
+  }
+
+  else {
+    Estimate `0'
+  }
+
+end
+
+program define Estimate, eclass properties( svyr svyb svyj )
+
+  syntax anything [if] [in] [aw pw iw/ ], [ ///
+     UNITvar(str) /// provides the list of factors where unit variance identification is used
+     FREE /// estimate all parameters as free -- the user provides identification through constraints
+     CONSTRaint(numlist)  /// see the previous one
+     FROM(str) /// starting values, compliant with -ml init- syntax
+     LEVel(int $S_level) ROBust VCE(string) CLUster(passthru) /// standard errors and inference
+     LOGLEVel(int 1) /// logging level
+     CORRelated(string) /// correlated measurement errors
+     SUBtractone /// subtract one from the sample size in places
+     USENames ///
+     MISSing /// allow for special treatment of missing data
+     SVY  * ]
+
+  * preliminary work
+  global CONFA_loglevel = `loglevel'
+
+  cap bothlist a \ b, global( CONFA_t )
+  if _rc==199 {
+     * listutil not installed
+     di as err "listutil not found, trying to install from SSC..."
+     ssc install listutil
+  }
+
+  if "`subtractone'"~="" local subtractone -1
+
+  *** MISSING
+  tempvar touse
+  marksample touse, zeroweight
+  global CONFA_touse `touse'
+  if $CONFA_loglevel > 2 tab $CONFA_touse
+
+  * weights?
+  if "`weight'" ~= "" {
+     global CONFA_wgt [`weight'=`exp']
+     global CONFA_wgti [iw=`exp']
+  }
+
+  * initial values?
+  if "`from'"~="" {
+    if "`from'" == "iv" | "`from'" == "IV" | "`from'" == "ivreg" | "`from'" == "2SLS" {
+      if "`unitvar'" ~= "" {
+         di as err "cannot specify from(`from') and unitvar at the same time"
+         CleanIt
+         exit 198
+      }
+      else global CONFA_init IV
+    }
+    else if "`from'" == "ones" global CONFA_init ones
+    else if "`from'" == "smart" global CONFA_init smart
+    else {
+       gettoken isitmat isitnot : from , parse(",")
+       cap confirm matrix `isitmat'
+       if _rc {
+          di "{err}Warning: matrix `isitmat' not found"
+          * do something sensible instead
+          global CONFA_init smart
+       }
+       else {
+          * do nothing --- let the hell break loose
+          global CONFA_init
+       }
+    }
+  }
+
+  * vce?
+  if "`vce'" ~= "" {
+    gettoken vce1 rest : vce, parse(" ,")
+    CheckVCE , `vce1'
+    local lvce = length("`vce'")
+    if `"`vce'"' != substr("sbentler", 1, max(2, `lvce')) ///
+       & `"`vce'"' != substr("satorrabentler", 1, max(3, `lvce')) {
+       local vceopt vce(`vce')
+    }
+  }
+
+  if $CONFA_loglevel > 2 di as text "Parsing..."
+  cap noi Parse `anything'
+  if _rc {
+     CleanIt
+     exit 198
+  }
+
+  * copy everything down -- -ivreg- cleans -sreturn-
+  local obsvar=s(obsvar)
+  global CONFA_obsvar `obsvar'
+
+  local nobsvar : word count `obsvar'
+  local nfactors = s(nfactors)
+  forvalues k=1/`nfactors' {
+    local indicators`k' = s(indicators`k')
+    local name`k' = s(name`k')
+    local factorlist `factorlist' `name`k''
+  }
+
+  * begin collecting the equations, starting values, bounds, and model structure
+  if $CONFA_loglevel > 2 di as text "Setting the structure up..."
+  Structure, unitvar(`unitvar') correlated(`correlated') `usenames'
+  local nicecorr $CONFA_t
+  * produces a bunch of globals
+
+  * did we need all this starting values business at all?
+  gettoken isitmat isitnot : from , parse(",")
+  cap confirm matrix `isitmat'
+  if ~_rc | strpos("`from'",",") {
+     * the user has provided the starting values
+     global CONFA_start `from'
+  }
+  else {
+    * not a matrix, no comma: use our ugly computations
+    global CONFA_start $CONFA_start, copy
+  }
+*  if "$CONFA_bounds" ~= "" global CONFA_bounds bounds($CONFA_bounds)
+
+  if $CONFA_loglevel > 3 di `"  ml model lf confa_lf $CONFA_toML $CONFA_wgt, constraint($CONFA_constr `constraint') `svy' `robust' `cluster' init($CONFA_start) bounds($CONFA_bounds) `options' maximize"'
+
+  tempvar misspat touse1
+  global CONFA_miss `misspat'
+  qui gen byte `touse1' = 1-$CONFA_touse
+  if "`missing'" != "" {
+     if $CONFA_loglevel > 1 di "{txt}Working on missing values..."
+     * cycle over the observed variables, create missing indicators
+     forvalues k=1/`nobsvar' {
+         local thisvar : word `k' of `obsvar'
+         tempvar miss`k'
+         qui gen byte `miss`k'' = mi( `thisvar' ) if $CONFA_touse
+         local misslist `misslist' `miss`k''
+     }
+
+     * sort by pattern: relevant observations first
+     * when $CONFA_touse==0 `misslist' will be missing
+     qui {
+       bysort `touse1' `misslist' : gen long $CONFA_miss = (_n==1)
+       replace $CONFA_miss = sum( $CONFA_miss )
+       replace $CONFA_miss = . if mi( $CONFA_touse )
+     }
+     cap assert $CONFA_miss == 1 if $CONFA_touse
+     local anymissing = _rc
+     if !`anymissing' {
+        di "{txt}Option missing specified, but no missing data found"
+     }
+     else {
+        qui tab $CONFA_miss
+        di _n "{txt}Note: {res}" r(r) "{txt} patterns of missing data found"
+     }
+     if $CONFA_loglevel > 3 li $CONFA_miss `misslist'
+  }
+*  if "`anymissing'"=="0" | "`missing'" == "" {
+  else {
+     * -missing- option is omitted
+     if $CONFA_loglevel > 1 di "{err}NOT {txt}working on missing values"
+     markout $CONFA_touse `obsvar'
+     qui gen byte $CONFA_miss = 1 if $CONFA_touse
+     if $CONFA_loglevel > 2 {
+        sum `obsvar' if $CONFA_touse
+        tab $CONFA_miss, missing
+     }
+  }
+
+
+  cap noi ml model lf confa_lfm $CONFA_toML $CONFA_wgt if $CONFA_touse, ///
+      constraint($CONFA_constr `constraint') `svy' `robust' `cluster' `vceopt' ///
+      init($CONFA_start) bounds($CONFA_bounds) `options' `missing' ///
+      maximize
+
+  local mlrc = _rc
+  if `mlrc' {
+     CleanIt
+     error `mlrc'
+  }
+
+  * parametric matrices
+  tempname bb
+  mat `bb' = e(b)
+  global CONFA_loglevel -1
+  * to indicate to CONFA_StrucToSigma() that the matrices should be posted to Stata
+  qui mata : CONFA_StrucToSigma(st_matrix("`bb'"))
+  global CONFA_loglevel `loglevel'
+  * now, post all those matrices to ereturn
+
+  mat rownames CONFA_Sigma = `obsvar'
+  mat colnames CONFA_Sigma = `obsvar'
+  mat rownames CONFA_Lambda = `obsvar'
+  mat colnames CONFA_Lambda = `factorlist'
+  mat rownames CONFA_Phi = `factorlist'
+  mat colnames CONFA_Phi = `factorlist'
+  mat colnames CONFA_Theta = `obsvar'
+  mat rownames CONFA_Theta = `obsvar'
+  ereturn matrix Sigma = CONFA_Sigma, copy
+  ereturn matrix Lambda = CONFA_Lambda, copy
+  ereturn matrix Phi = CONFA_Phi, copy
+  ereturn matrix Theta = CONFA_Theta, copy
+
+  if "`missing'"!= "" ereturn local missing missing
+
+  eret local observed `obsvar'
+  eret local factors  `factorlist'
+  if "`unitvar'" ~= "" {
+     * need to unwrap the contents of `unitvar'...
+     * or change its defintion from passthru to string
+     if "`unitvar'" == "_all" eret local unitvar `factorlist'
+     else eret local unitvar `unitvar'
+  }
+  forvalues k=1/`nfactors' {
+    eret local factor`k' `name`k'' : `indicators`k''
+  }
+  if "`correlated'"!="" eret local correlated `nicecorr'
+
+  if "`svy'`cluster'`exp'`robust'" == "" & "`vce'"!="robust" & substr("`vce'",1,2)!="cl" & "`missing'"=="" {
+
+     * if the data are not i.i.d., LRT is not applicable
+     * don't know what to do with missing data
+
+     tempname S Sindep trind
+     qui mat accum `S' = `obsvar' $CONFA_wgti if $CONFA_touse, dev nocons
+     mat `S' = `S' / ( e(N) `subtractone' )
+     mat `Sindep' = diag(vecdiag(`S'))
+
+     * degrees of freedom
+     local nconstr = `: word count $CONFA_constr' + `: word count `constraint''
+     local pstar = `nobsvar' * (`nobsvar' + 1) / 2
+     local df_m  = rowsof(CONFA_Struc) - `nobsvar' - `nconstr'
+     ereturn scalar pstar = `pstar'
+
+     * test against independence
+     mat `trind' = trace( syminv(`Sindep') * `S' )
+     local trind = `trind'[1,1]
+     ereturn scalar ll_indep = -0.5 * `nobsvar' * e(N) * ln(2*_pi) - 0.5 * e(N) * ln(det(`Sindep')) - 0.5 * e(N) * `trind'
+     ereturn scalar lr_indep = 2*(e(ll)-e(ll_indep))
+     ereturn scalar df_indep = `pstar' - `nobsvar'
+     ereturn scalar p_indep  = chi2tail(e(df_indep),e(lr_indep))
+
+     * goodness of fit test
+     ereturn scalar ll_0 = -0.5 * `nobsvar' * e(N) * ln(2*_pi) - 0.5 * e(N) * ln(det(`S')) - 0.5 * `nobsvar' * e(N)
+     ereturn scalar df_u = `pstar' - `df_m'
+     ereturn scalar lr_u = cond(e(df_u)==0,0,-2*(e(ll)-e(ll_0)))
+     ereturn scalar p_u  = chi2tail(e(df_u),e(lr_u))
+
+     * make the g.o.f. test the default test
+     ereturn scalar df_m = `df_m'
+     ereturn local chi2type LR
+     ereturn scalar chi2 = e(lr_u)
+     ereturn scalar p = e(p_u)
+
+     * other crap
+     ereturn matrix S = `S'
+
+     if `"`vce'"'==substr("satorrabentler",1,max(3, length("`vce'"))) ///
+       | "`vce'" ==substr("sbentler",1,max(4, length("`vce'"))) {
+        * repost Satorra-Bentler covariance matrix
+        * not defined for complex survey data,
+
+        cap noi SatorraBentler, constraint(`constraint') `missing'
+
+        if _rc {
+           di as err "Satorra-Bentler standard errors are not supported; revert to vce(oim)"
+        }
+        else {
+
+          tempname SBVar SBV Delta Gamma VV U trUG2 Tdf
+          mat `SBVar' = r(SBVar)
+          mat `Delta' = r(Delta)
+          mat `Gamma' = r(Gamma)
+          mat `SBV'   = r(SBV)
+          mat `VV'    = e(V)
+          mat `SBVar' = ( `VV'[1..`nobsvar',1..`nobsvar'], `VV'[1..`nobsvar',`nobsvar'+1 ...] ///
+                        \ `VV'[`nobsvar'+1...,1..`nobsvar'], `SBVar'[`nobsvar'+1...,`nobsvar'+1...] )
+          ereturn repost V = `SBVar'
+          ereturn matrix SBGamma = `Gamma', copy
+          ereturn matrix SBDelta = `Delta', copy
+          ereturn matrix SBV = `SBV', copy
+          ereturn local vce SatorraBentler
+          ereturn local vcetype "Satorra-Bentler"
+
+          * compute the corrected tests, too
+          * only takes care of the covariance structure
+          * Satorra-Bentler 1994
+          mat `U' = `SBV' - `SBV'*`Delta'*syminv(`Delta''*`SBV'*`Delta')*`Delta''*`SBV'
+          ereturn matrix SBU = `U'
+          mat `U' = trace( e(SBU)*e(SBGamma) )
+          ereturn scalar SBc = `U'[1,1]/e(df_u)
+          ereturn scalar Tsc = e(lr_u)/e(SBc) * (e(N) `subtractone' ) / e(N)
+          ereturn scalar p_Tsc = chi2tail( e(df_u), e(Tsc) )
+
+          mat `trUG2' = trace( e(SBU)*`Gamma'*e(SBU)*`Gamma')
+          ereturn scalar SBd = `U'[1,1]*`U'[1,1]/`trUG2'[1,1]
+          ereturn scalar Tadj = ( e(SBd)/`U'[1,1]) * e(lr_u) * (e(N) `subtractone' ) / e(N)
+          ereturn scalar p_Tadj = chi2tail( e(SBd), e(Tadj) )
+
+* saddlepoint approximation comes here!!!
+
+          * Yuan-Bentler 1997
+          ereturn scalar T2 = e(lr_u)/(1+e(lr_u)/e(N) )
+          ereturn scalar p_T2 = chi2tail( e(df_u), e(T2) )
+
+        }
+     }
+  }
+
+  * are we done yet?
+  ereturn matrix CONFA_Struc = CONFA_Struc
+  ereturn local predict confa_p
+  ereturn local estat_cmd confa_estat
+  ereturn local cmd confa
+
+  Replay
+
+  CleanIt
+
+end
+
+program define CleanIt
+  * just in case
+  return clear
+
+  * release the constraints
+  constr drop $CONFA_constr
+
+  * clear the globals
+  if $CONFA_loglevel < 3 {
+     global CONFA_constr
+     global CONFA_init
+     global CONFA_loglevel
+     global CONFA_toML
+     global CONFA_start
+     global CONFA_bounds
+     global CONFA_args
+     global CONFA_constr
+     global CONFA_obsvar
+     global CONFA_t
+     global CONFA_wgt
+     global CONFA_wgti
+  }
+end
+
+program define Parse, sclass
+
+   * number of factors?
+   local input `0'
+
+   mata: st_local("nfactors",strofreal(CONFA_NF(`"`input'"')))
+
+   if `nfactors' == 0 {
+     * something terrible happened
+     di as err "incorrect factor specification"
+     exit 198
+   }
+
+   sreturn local nfactors = `nfactors'
+
+   tokenize `input', parse("()")
+
+   local k = 0
+   while "`1'"~="" {
+     * right now, `1' should contain an opening bracket
+     if "`1'"~="(" {
+        * the first character is not a "("
+        di as err "incorrect factor specification"
+        exit 198
+     }
+     else {
+        * the first character IS a "("
+        mac shift
+        * right now, `1' should contain a factor-type statement
+        local ++k
+        local factor`k' `1'
+        mac shift
+        * right now, `1' should contain a closing bracket
+        if "`1'"~=")" {
+           * the first character is not a ")"
+           di as err "incorrect factor specification"
+           exit 198
+        }
+        else mac shift
+        * it may contain a space, I guess
+        * then -mac shift- it again
+        if trim("`1'")=="" mac shift
+     }
+   }
+   forvalues k=1/`nfactors' {
+     * now, parse each factor statement
+     tokenize `factor`k'', parse(":")
+     sreturn local name`k' `1'
+     * `2' is the colon
+     unab indicators : `3'
+     sreturn local indicators`k' `indicators'
+     local obsvar `obsvar' `indicators'
+   }
+
+   cap uniqlist `obsvar'
+   if _rc == 199 {
+     * uniqlist not found
+     di as err "uniqlist not found, trying to install from SSC..."
+     ssc install listutil
+     uniqlist `obsvar'
+   }
+   local obsvar = r(list)
+
+* mata: st_local("obsvar",CONFA_UL(`"`obsvar'"'))
+
+   sreturn local obsvar `obsvar'
+   sreturn local nobsvar = `: word count `obsvar''
+
+end
+
+program define Structure
+
+  syntax , [unitvar(str) correlated(str) usenames]
+
+  * implement usenames:
+  * the parameters go along with the factor and variable names
+  * rather than matrix indices
+
+  * utilize all the sreturn results
+  if $CONFA_loglevel > 3 sreturn list
+
+  * copy everything down -- -ivreg- cleans -sreturn-
+  local obsvar=s(obsvar)
+  local nobsvar : word count `obsvar'
+  local nfactors = s(nfactors)
+
+  forvalues k=1/`nfactors' {
+    local indicators`k' = s(indicators`k')
+    local name`k' = s(name`k')
+    local factorlist `factorlist' `name`k''
+  }
+
+  if "`unitvar'" == "_all" {
+     local unitvar `factorlist'
+  }
+
+  * set up the labeling system
+  if "`usenames'" != "" {
+    * give the parameters varname labels
+    forvalues k=1/`nobsvar' {
+      local o`k' : word `k' of `obsvar'
+    }
+    forvalues k=1/`nfactors' {
+      local f`k' `name`k''
+    }
+  }
+  else {
+    * give the parameters numberic lables
+    forvalues k=1/`nobsvar' {
+      local o`k' `k'
+    }
+    forvalues k=1/`nfactors' {
+      local f`k' `k'
+    }
+  }
+
+  * returns:
+  * - ML equations
+  * - ML bounds
+  * - the structure matrix
+  * - ML statement for the likelihood evaluator
+
+  * initialize everything
+  local eqno = 0
+  global CONFA_toML
+  global CONFA_start
+  global CONFA_args
+  global CONFA_constr
+  global CONFA_bounds
+  mata : CONFA_Struc = J(0,4,.)
+
+  * process the means first
+  tokenize `obsvar'
+  forvalues j=1/`nobsvar' {
+     * 1. equations to ML
+     local ++eqno
+     global CONFA_toML $CONFA_toML (mean_`o`j'':)
+     * 2. starting values
+     sum ``j'', mean
+     global CONFA_start $CONFA_start `r(mean)'
+     * 3. confa_lf arguments
+     global CONFA_args $CONFA_args mean_`o`j''
+     * 4. CONFA structure
+     mata : CONFA_Struc = CONFA_Struc \ (1, `eqno', `j', 0)
+  }
+
+  * next, process lambda's
+  forvalues k=1/`nfactors' {
+    * determine if unitvar is needed here
+    bothlist `name`k'' \ `unitvar', global(CONFA_t)
+    if "$CONFA_t" ~= "" {
+       * identification by unit variance, no scaling variables
+       local scalevar
+    }
+    else {
+       * identification by the scaling variable: the 1st one on the list
+       local scalevar : word 1 of `indicators`k''
+    }
+    forvalues j=1/`nobsvar' {
+      * determine whether `k'-th factor loads on `j'-th variable
+      if strpos( "`indicators`k''", "``j''") {
+         * 1. equations to ML
+         local ++eqno
+         global CONFA_toML $CONFA_toML (lambda_`o`j''_`f`k'':)
+         * 2. starting values
+         local r2_`j' = 0.5
+         if "``j''" == "`scalevar'" {
+            * the current one is the scaling variable
+            * set up the constraints, initialize to 1
+            global CONFA_start $CONFA_start 1
+            constraint free
+            local nconstr = r(free)
+            constraint `nconstr' [lambda_`o`j''_`f`k'']_cons = 1
+            global CONFA_constr $CONFA_constr `nconstr'
+         }
+         else if "$CONFA_init" == "IV" {
+              * initialize by a simple version of instrumental variables
+              * use the remaining indicators of this factor as instruments
+              dellist `indicators`k'', delete(`scalevar' ``j'')
+              local ivlist = r(list)
+              if "`ivlist'" == "." {
+                di as err "Warning: no instruments available for ``j''"
+                local ivl = 1
+              }
+              else {
+                qui ivreg ``j'' (`scalevar' = `ivlist')
+                local ivl = _b[`scalevar']
+              }
+              global CONFA_start $CONFA_start `ivl'
+              if !mi(e(r2)) local r2_`j' = e(r2)
+         }
+         else if "$CONFA_init" == "ones" {
+            global CONFA_start $CONFA_start 1
+         }
+         else {
+            * no init options
+            global CONFA_start $CONFA_start 0
+         }
+         global CONFA_bounds $CONFA_bounds /lambda_`o`j''_`f`k'' -100 100
+         * 3. confa_lf arguments
+         global CONFA_args $CONFA_args lambda_`o`j''_`f`k''
+         * 4. CONFA structure
+         mata : CONFA_Struc = CONFA_Struc \ (2, `eqno', `j', `k')
+      }
+    }
+  }
+
+  * next, process Phi matrix
+  forvalues k=1/`nfactors' {
+    local scalevar1 : word 1 of `indicators`k''
+
+    foreach kk of numlist `k'/1 {
+      * 1. equations to ML
+      local ++eqno
+      global CONFA_toML $CONFA_toML (phi_`f`kk''_`f`k'':)
+      * 2. starting values
+      if `k' == `kk' {
+         * diagonal entry
+         bothlist `name`k'' \ `unitvar', global(CONFA_t)
+         if "$CONFA_t" ~= "" {
+            * identification by unit variance
+            constraint free
+            local nconstr = r(free)
+            constraint `nconstr' [phi_`f`k''_`f`k'']_cons = 1
+            global CONFA_constr $CONFA_constr `nconstr'
+            local v`k' = 1
+         }
+         else {
+            * identification by the scaling variable
+            if "$CONFA_init" == "smart" | "$CONFA_init" == "IV" {
+              qui sum `scalevar1'
+              local v`k' = r(Var)*0.5
+            }
+            else if "$CONFA_init" == "ones" local v`k' = 1
+            else local v`k' = 0
+         }
+         global CONFA_start $CONFA_start `v`k''
+         global CONFA_bounds $CONFA_bounds /phi_`f`k''_`f`kk'' 0 1000
+      }
+      else {
+        * off-diagonal entry
+         if "$CONFA_init" == "smart" | "$CONFA_init" == "IV" {
+            local scalevar2 : word 1 of `indicators`kk''
+            qui corr `scalevar1' `scalevar2'
+            local v = 0.5*r(rho)*sqrt(`v`k''*`v`kk'')
+         }
+         else if "$CONFA_init" == "ones" local v = 0.5
+              else local v = 0
+         local vv = 1.5*abs(`v') + 0.01
+         global CONFA_start $CONFA_start `v'
+         global CONFA_bounds $CONFA_bounds /phi_`f`kk''_`f`k'' -`vv' `vv'
+      }
+      * 3. confa_lf arguments
+      global CONFA_args $CONFA_args phi_`f`kk''_`f`k''
+      * 4. CONFA structure
+      mata : CONFA_Struc = CONFA_Struc \ (3, `eqno', `kk', `k')
+    }
+
+  }
+
+  * residual variances
+  forvalues j=1/`nobsvar' {
+     * 1. equations to ML
+     local ++eqno
+     global CONFA_toML $CONFA_toML (theta_`o`j'':)
+     * 2. starting values
+     if "$CONFA_init" == "ones" {
+        local v_`j' = 1
+     }
+     else if "$CONFA_init" == "IV" | "$CONFA_init" == "smart" {
+       qui sum ``j''
+       local v_`j' = r(Var)*(1-`r2_`j'')
+     }
+     else local v_`j' = 0.01
+     global CONFA_start $CONFA_start `v_`j''
+     global CONFA_bounds $CONFA_bounds /theta_`o`j'' 0 1000
+     * 3. confa_lf arguments
+     global CONFA_args $CONFA_args theta_`o`j''
+     * 4. CONFA structure
+     mata : CONFA_Struc = CONFA_Struc \ (4, `eqno', `j', 0)
+  }
+
+  * the error correlations
+  while "`correlated'" != "" {
+     gettoken corrpair correlated : correlated , match(m)
+     gettoken corr1 corrpair : corrpair, parse(":")
+     unab corr1 : `corr1'
+     gettoken sc corr2 : corrpair, parse(":")
+     unab corr2 : `corr2'
+
+     * make sure both are present in the list of observed variables
+
+     poslist `obsvar' \ `corr1', global(CONFA_t)
+     local k1 = $CONFA_t
+     if `k1' == 0 {
+        di as err "`corr1' is not among the observed variables"
+        CleanIt
+        exit 198
+     }
+     poslist `obsvar' \ `corr2', global(CONFA_t)
+     local k2 = $CONFA_t
+     if `k2' == 0 {
+        di as err "`corr2' is not among the observed variables"
+        CleanIt
+        exit 198
+     }
+
+     * will be empty @ the first call
+     local nicecorr `nicecorr' (`corr1':`corr2')
+
+     * 1. equations to ML
+     local ++eqno
+     global CONFA_toML $CONFA_toML (theta_`o`k1''_`o`k2'':)
+     * 2. starting values
+     global CONFA_start $CONFA_start 0
+     local vv = sqrt(`v_`k1''*`v_`k2'')
+     global CONFA_bounds $CONFA_bounds /theta_`o`k1''_`o`k2'' -`vv' `vv'
+     * 3. confa_lf arguments
+     global CONFA_args $CONFA_args theta_`o`k1''_`o`k2''
+     * 4. CONFA structure
+     mata : CONFA_Struc = CONFA_Struc \ (5, `eqno', `k1', `k2')
+  }
+  if "`nicecorr'"!="" global CONFA_t `nicecorr'
+
+  if $CONFA_loglevel > 3 {
+     di as text "ML input (" as res `: word count $CONFA_toML' as text "): " as res "$CONFA_toML"
+     di as text "Starting values (" as res `: word count $CONFA_start' as text "): " as res "$CONFA_start"
+     di as text "Likelihood evaluator (" as res `: word count $CONFA_args' as text"): " as res "$CONFA_args"
+     di as text "Constraints (" as res `nfactors' as text "): " as res "$CONFA_constr"
+     di as text "Correlated errors: " as res "`nicecorr'"
+     constraint dir $CONFA_constr
+     mata : CONFA_Struc
+  }
+  mata : st_matrix("CONFA_Struc",CONFA_Struc)
+
+
+end
+
+program define Replay
+
+  syntax, [posvar llu(str) level(passthru)]
+
+  * get the implied matrix
+  tempname bb Sigma
+  mat `bb' = e(b)
+  * mata : st_matrix("Sigma",CONFA_StrucToSigma(st_matrix("`bb'")))
+  mat `Sigma' = e(Sigma)
+  mat CONFA_Struc = e(CONFA_Struc)
+
+  * determine what kind of labeling has been used
+  * RATHER FRAGILE: checking for mean_1 rather than trying to find
+  * whether option usenames was specified
+  cap local whatis = [mean_1]_cons
+  if _rc {
+    * mean_1 not found => labeling by names
+    forvalues k=1/`: word count `e(observed)' ' {
+      local o`k' : word `k' of `e(observed)'
+    }
+    forvalues k=1/`: word count `e(factors)' ' {
+      local f`k' : word `k' of `e(factors)'
+    }
+  }
+  else {
+    * mean_1 was found => labeling by numbers
+    forvalues k=1/`: word count `e(observed)' ' {
+      local o`k' `k'
+    }
+    forvalues k=1/`: word count `e(factors)' ' {
+      local f`k' `k'
+    }
+  }
+
+  * header
+  di _n as text "`e(crittype)' = " as res e(ll) _col(59) as text "Number of obs = " as res e(N)
+  di as text "{hline 13}{c TT}{hline 64}"
+  if "`e(vcetype)'" ~= "" {
+  di as text "             {c |}           {center 15:`e(vcetype)'}"
+  }
+  di as text "             {c |}      Coef.   Std. Err.      z    P>|z|     [$S_level% Conf. Interval]"
+  di as text "{hline 13}{c +}{hline 64}"
+
+  tokenize `e(observed)'
+  local nobsvar : word count `e(observed)'
+
+  * let's go equation by equation
+  local eqno = 0
+
+  * Means
+  _diparm __lab__, label("Means") eqlabel
+  forvalues j = 1/`nobsvar' {
+    local ++eqno
+    _diparm mean_`o`j'' , label("``j''") prob `level'
+  }
+
+  * Loadings
+  _diparm __lab__, label("Loadings") eqlabel
+  local ++eqno // to point to the next line
+  forvalues k=1/`: word count `e(factors)' ' {
+     _diparm __lab__ , label("`: word `k' of `e(factors)' '")
+     while CONFA_Struc[`eqno',1]<=2 & CONFA_Struc[`eqno',4]==`k' {
+       local j = CONFA_Struc[`eqno',3]
+       _diparm lambda_`o`j''_`f`k'', label("``j''") prob `level'
+       local ++eqno
+     }
+  }
+
+  * Factor covariance
+  _diparm __lab__, label("Factor cov.") eqlabel
+  forvalues k=1/`: word count `e(factors)'' {
+    foreach kk of numlist `k'/1 {
+      _diparm phi_`f`kk''_`f`k'', label("`: word `kk' of `e(factors)''-`: word `k' of `e(factors)''") prob `level'
+      local ++eqno
+    }
+  }
+
+  * Error variances
+  _diparm __lab__, label("Var[error]") eqlabel
+  forvalues j= 1/`nobsvar' {
+     _diparm theta_`o`j'' , label("``j''") prob `level'
+     local ++eqno
+  }
+
+  * Error correlations
+  if `eqno' <= rowsof(CONFA_Struc) & CONFA_Struc[`eqno',1] == 5 {
+    _diparm __lab__, label("Cov[error]") eqlabel
+    while (`eqno' <= rowsof(CONFA_Struc) & CONFA_Struc[`eqno',1] == 5) {
+      local k1 = CONFA_Struc[`eqno',3]
+      local k2 = CONFA_Struc[`eqno',4]
+      _diparm theta_`o`k1''_`o`k2'', label("``k1''-``k2''") prob `level'
+      * range check: what am I supposed to check here? Hm...
+      local ++eqno
+    }
+  }
+
+  if "`e(vcetype)'"~="Robust" & "`e(missing)'"=="" {
+     di as text "{hline 13}{c +}{hline 64}"
+     di as text "R2{col 14}{c |}"
+     forvalues j = 1/`nobsvar' {
+       qui sum ``j'' if e(sample)
+       local r2 = (`Sigma'[`j',`j']-_b[theta_`o`j'':_cons])/r(Var)
+       di as text %12s "``j''" "{col 14}{c |}{col 20}" as res %6.4f `r2'
+     }
+  }
+
+
+  di as text "{hline 13}{c BT}{hline 64}"
+
+  if e(df_u)>0 {
+     di as text _n "Goodness of fit test: LR = " as res %6.3f e(lr_u) ///
+        as text _col(40) "; Prob[chi2(" as res %2.0f e(df_u) as text ") > LR] = " as res %6.4f e(p_u)
+  }
+  else {
+     di as text "No degrees of freedom to perform the goodness of fit test"
+  }
+  di as text "Test vs independence: LR = " as res %6.3f e(lr_indep) ///
+     as text _col(40) "; Prob[chi2(" as res %2.0f e(df_indep) as text ") > LR] = " as res %6.4f e(p_indep)
+
+  if "`e(vce)'" == "SatorraBentler" & e(df_u)>0 {
+     * need to report all those corrected statistics
+
+     di as text _n "Satorra-Bentler Tsc" _col(26) "= " as res %6.3f e(Tsc) ///
+        as text _col(40) "; Prob[chi2(" as res %2.0f e(df_u) as text ")   > Tsc ] = " as res %6.4f e(p_Tsc)
+
+     di as text "Satorra-Bentler Tadj" _col(26) "= " as res %6.3f e(Tadj) ///
+        as text _col(40) "; Prob[chi2(" as res %4.1f e(SBd) as text ") > Tadj] = " as res %6.4f e(p_Tadj)
+
+     di as text "Yuan-Bentler T2" _col(26) "= " as res %6.3f e(T2) ///
+        as text _col(40) "; Prob[chi2(" as res %2.0f e(df_u) as text ")   > T2  ] = " as res %6.4f e(p_T2)
+  }
+
+  if "`e(vce)'" == "BollenStine" {
+     * need to report Bollen-Stine measures
+     di as text _n "Bollen-Stine simulated Prob[ LR > " as res %6.4f e(lr_u) as text " ] = " as res %6.4f e(p_u_BS) ///
+        as text _n "Based on " as res e(B_BS) as text " replications. " ///
+        as text "The bootstrap 90% interval: (" as res %6.3f e(T_BS_05) as text "," ///
+        as res %6.3f e(T_BS_95) as text ")"
+
+
+  }
+
+  mat drop CONFA_Struc
+
+end
+
+**************************** Satorra-Bentler covariance matrix code
+
+program SatorraBentler, rclass
+   syntax [, noisily constraint(numlist) missing]
+
+   if "`missing'"!="" {
+      di "{err}cannot specify Satorra-Bentler standard errors with missing data"
+      exit 198
+   }
+
+   * assume the maximization completed, the results are in memory as -ereturn data-
+   * we shall just return the resulting matrix
+
+   * assume sample is restricted to e(sample)
+   * preserve
+   * keep if e(sample)
+
+   * get the variable names
+   tempname VV bb
+   mat `bb' = e(b)
+   mat `VV' = e(V)
+   local p : word count $CONFA_obsvar
+   qui count if $CONFA_touse
+   local NN = r(N)
+
+   * compute the implied covariance matrix
+   tempname Lambda Theta Phi Sigma
+   mata : st_matrix("`Sigma'",CONFA_StrucToSigma(st_matrix("`bb'")))
+
+   * compute the empirical cov matrix
+   tempname SampleCov
+   qui mat accum `SampleCov' = $CONFA_obsvar $CONFA_wgti if $CONFA_touse , nocons dev
+   * divide by sum of weights instead???
+   mat `SampleCov' = `SampleCov' / (`NN'-1)
+
+   * compute the matrix Gamma (fourth moments)
+   if $CONFA_loglevel > 4 {
+       di as text "Computing the Gamma matrix of fourth moments..."
+   }
+   tempname Gamma
+   SBGamma $CONFA_obsvar if $CONFA_touse
+   mat `Gamma' = r(Gamma)
+   return add
+
+   * compute the V matrix, the normal theory weight
+   if $CONFA_loglevel > 4 {
+      di as text "Computing the V matrix..."
+   }
+   SBV `SampleCov' `noisily'
+   if !mi(r(needmatsize)) {
+     di as err "matsize too small; need at least " r(needmatsize)
+     exit 908
+   }
+   tempname V
+   mat `V' = r(SBV)
+   return add
+
+   * compute the Delta matrix
+   if $CONFA_loglevel > 4 {
+      di as text "Computing the Delta matrix..."
+   }
+
+   tempname Delta DeltaId
+   noi mata : SBStrucToDelta("`Delta'")
+
+   *** put the pieces together now
+
+   * enact the constraints!
+   SBconstr `bb', constraint(`constraint')
+
+   * zero out the rows of Delta that correspond to fixed parameters
+   mat `DeltaId' = `Delta' * diag( r(Fixed) )
+
+   local dcnames : colfullnames `bb'
+   local drnames : rownames `Gamma'
+   mat colnames `DeltaId' = `dcnames'
+   mat rownames `DeltaId' = `drnames'
+   return matrix Delta = `DeltaId', copy
+
+   tempname VVV
+   mat `VVV' = ( `DeltaId'' * `V' * `DeltaId' )
+   mat `VVV' = syminv(`VVV')
+   mat `VVV' = `VVV' * ( `DeltaId'' * `V' * `Gamma' * `V' * `DeltaId' ) * `VVV'/`NN'
+
+   * add the covariance matrix for the means, which is just Sigma/_N
+   * weights!
+   * third moments!
+   return matrix SBVar = `VVV'
+
+end
+* of satorrabentler
+
+* Compute Gamma: the fourth moments matrix -- check!
+program define SBGamma, rclass
+   syntax varlist [if] [in]
+   unab varlist : `varlist'
+   tokenize `varlist'
+
+   marksample touse
+
+   local p: word count `varlist'
+
+   forvalues k=1/`p' {
+     * make up the deviations; weights are used in a weird way
+     *** MISSING: change r(mean) to _b[whatever] ?
+     qui sum ``k'' $CONFA_wgti if `touse', meanonly
+     tempvar d`k'
+     qui g double `d`k'' = ``k'' - r(mean) if `touse'
+     local dlist `dlist' `d`k''
+   }
+
+   local pstar = `p'*(`p'+1)/2
+   forvalues k=1/`pstar' {
+      tempvar b`k'
+      qui g double `b`k'' = .
+      local blist `blist' `b`k''
+   }
+
+
+   * convert into vech (z_i-bar z)(z_i-bar z)'
+   mata : SBvechZZtoB("`dlist'","`blist'")
+
+   * blist now should contain the moments around the sample means
+   * we need to get their covariance matrix
+
+   tempname Gamma
+   qui mat accum `Gamma' = `blist' $CONFA_wgti if `touse', dev nocons
+   mat `Gamma' = `Gamma'/(r(N)-1)
+   mata : Gamma = st_matrix( "`Gamma'" )
+
+   * make nice row and column names
+   forvalues i=1/`p' {
+     forvalues j=`i'/`p' {
+        local namelist `namelist' ``i''_X_``j''
+     }
+   }
+   mat colnames `Gamma' = `namelist'
+   mat rownames `Gamma' = `namelist'
+
+   return matrix Gamma = `Gamma'
+
+end
+* of computing Gamma
+
+* compute V = 1/2 D' (Sigma \otimes Sigma) D
+* normal theory weight matrix, see Satorra (1992), eq (24) -- check!
+program define SBV, rclass
+   args A noisily
+   tempname D Ainv V
+   local p = rowsof(`A')
+   if $CONFA_loglevel > 3 di as text "Computing the duplication matrix..."
+   mata : Dupl(`p',"`D'")
+   mat `Ainv' = syminv(`A')
+   cap mat `V' = .5*`D''* (`Ainv' # `Ainv') * `D'
+   if _rc == 908 {
+     * need a larger matrix
+     return scalar needmatsize = rowsof(`A')*rowsof(`A')
+   }
+   else {
+     return matrix SBV = `V'
+   }
+end
+* of computing V
+
+program define SBconstr, rclass
+   * need to figure out whether a constraint has the form [parameter]_cons = value,
+   * and to nullify the corresponding column
+   syntax anything, [constraint(numlist)]
+   local bb `anything'
+   * that's the name of the parameter vector, a copy of e(b)
+   tempname Iq
+   mat `Iq' = J(1,colsof(`bb'),1)
+   tokenize $CONFA_constr `constraint'
+   while "`1'" ~= "" {
+     constraint get `1'
+     local constr `r(contents)'
+     gettoken param value  : constr, parse("=")
+     * is the RHS indeed a number?
+     local value = substr("`value'",2,.)
+     confirm number `value'
+     * parse the square brackets and turn them into colon
+     * replace the opening brackets with nothing, and closing brackets, with colon
+     * that way, we will get "parameter:_cons", which is the format of e(b) labels
+     local param = subinstr("`param'","["," ",1)
+     local param = subinstr("`param'","]",":",1)
+     local param = trim("`param'")
+     local coln = colnumb(`bb',"`param'" )
+     mat `Iq'[1,`coln']=0
+
+     mac shift
+   }
+   return matrix Fixed = `Iq'
+end
+
+program define CheckVCE
+  syntax [anything] , [ROBust CLuster oim opg SBentler SATorrabentler BOOTstrap JACKknife]
+  if "`bootstrap'" ~= "" {
+    di "{err}vce(bootstrap) not allowed, but you can run {inp}bootstrap ... : confa ... {err}instead."
+    CleanIt
+    exit 198
+  }
+  if "`jackknife'" ~= "" {
+    di "{err}vce(jackknife) not allowed, but you can run {inp}jackknife ... : confa ... {err}instead."
+    CleanIt
+    exit 198
+  }
+end
+
+exit
+
+if "$SOCST" == "c:\-socialstat" {
+  // at home, run the Mata file
+  do C:\-Mizzou\CONFA\confa.mata
+}
+else {
+   // for public release, add Mata code
+   mata : mata mlib index
+}
+
+Globals used:
+CONFA_init     -- initialization type
+CONFA_loglevel -- detail level
+CONFA_toML     -- model statement for -ml model-
+CONFA_start    -- default starting values
+CONFA_bounds   -- ml search bounds
+CONFA_args     -- the list of parameters, to appear in -confa_lf-
+CONFA_constr   -- the list of constraints
+CONFA_obsvar   -- the list of observed variables
+CONFA_wgt      -- weight specification
+CONFA_wgti     -- iweight
+CONFA_t        -- temporary global for -listutil-
+
+Structure matrix:
+CONFA_Struc    -- the model structure: (parameter type, equation number, index1, index2)
+
+History:
+v.1.0 -- Jan 09, 2008
+      -- basic formulation without -cluster-, -robust-, -weights-, -svy-
+v.1.1 -- Mar 21, 2008
+      -- Satorra-Bentler?
+v.1.2 -- Sep 16, 2008
+      -- Ken Higbee comments
+v.1.5 -- usenames
+      -- Mata moved to lconfa.mlib
+      -- survey-compatible
+v.1.6 -- listwise deletion for missing data
+      -- what kind of idiot should Stas be to not pay attention to this???
+      -- informative message about matsize in Satorra-Bentler calculations
+v.2.0 -- FIML missing data
+      -- prepared for revision in SJ
+v.2.0.1 -- fixed -if- in Satorra-Bentler calculations
+v.2.0.2 -- fixed reporting of correlations with -unitvar-: confa.ado, confa_estat.ado
+v.2.1 -- someday?
+      -- Bartlett correction: (N - 1 - (2p+4m+5)/6)
+      -- F-statistic in place of chi-square, both normal theory and S-B
diff --git a/Modules/ado/plus/c/confa.mata b/Modules/ado/plus/c/confa.mata
new file mode 100644
index 0000000..ec56fd7
--- /dev/null
+++ b/Modules/ado/plus/c/confa.mata
@@ -0,0 +1,503 @@
+*! Mata definitions for confa package; 3 March 2009; v.2.0
+
+set matalnum on
+
+mata:
+
+mata set matastrict on
+mata clear
+
+//////////////////////////////////////////////
+// needed by confa.ado
+
+real CONFA_NF( string input ) {
+   real scalar nopenpar, nclosepar, ncolon;
+   // opening and closing parentheses
+
+   nopenpar  = length(tokens(input, ")" ))
+   nclosepar = length(tokens(input, "(" ))
+   // n*par will be 2*nf
+   ncolon    = length(tokens(input, ":" ))
+   // ncolon will be 2*nf + 1
+
+   if ( (nopenpar == nclosepar) & (nopenpar == ncolon-1 ) ) {
+      if (mod(nopenpar,2) == 0) {
+          return( nopenpar/2 )
+      }
+   }
+
+   // if everything was OK, should've exited by now
+   // if something's wrong, return zero
+   return(0)
+}
+
+matrix CONFA_StrucToSigma(real vector parms) {
+   real scalar CONFA_loglevel, nobsvar, nfactors, eqno;
+   real matrix Lambda, Phi, Theta, Sigma, CONFA_Struc;
+
+   // loglevel
+   CONFA_loglevel = strtoreal( st_global("CONFA_loglevel"))
+
+   CONFA_Struc = st_matrix("CONFA_Struc")
+   if (CONFA_loglevel>4) CONFA_Struc
+
+   if (CONFA_loglevel>4) {
+      printf("{txt}Current parameter values:\n")
+      parms
+   }
+
+   // the length should coinicde with the # pars from CONFA_Struc
+   if ( cols(parms) ~= rows(CONFA_Struc) ) {
+      // something's wrong, let's just drop out with an empty matrix
+      if (CONFA_loglevel>4) {
+         printf("{txt}Expected parameters: {res}%3.0f{txt}; received parameters: {res}%3.0f\n",
+                rows(CONFA_Struc),cols(parms))
+      }
+      return(J(0,0,0))
+   }
+
+   // # observed variables: max entry in the number of means
+   nobsvar = colmax( select(CONFA_Struc[,3], !(CONFA_Struc[,1]-J(rows(CONFA_Struc),1,1)) ) )
+   if (CONFA_loglevel>4) printf("{txt}No. of observed variables: {res}%3.0f\n",nobsvar)
+
+   // # observed factors: max entry in the phi indices
+   nfactors = colmax( select(CONFA_Struc[,3], !(CONFA_Struc[,1]-J(rows(CONFA_Struc),1,3)) ) )
+   if (CONFA_loglevel>4) printf("{txt}No. of latent factors: {res}%3.0f\n",nfactors)
+
+   // set up the matrices
+   Lambda = J(nobsvar,nfactors,0)
+   Phi    = J(nfactors,nfactors,0)
+   Theta  = J(nobsvar,nobsvar,0)
+
+   // fill the stuff in
+   for(eqno=nobsvar+1;eqno<=rows(CONFA_Struc);eqno++) {
+      if (CONFA_Struc[eqno,1] == 2) {
+         // a lambda-type entry
+         Lambda[ CONFA_Struc[eqno,3], CONFA_Struc[eqno,4] ] = parms[eqno]
+      }
+      if (CONFA_Struc[eqno,1] == 3) {
+         // a phi-type entry
+         Phi[ CONFA_Struc[eqno,3], CONFA_Struc[eqno,4] ] = parms[eqno]
+         Phi[ CONFA_Struc[eqno,4], CONFA_Struc[eqno,3] ] = parms[eqno]
+      }
+      if (CONFA_Struc[eqno,1] == 4) {
+         // a theta-type entry
+         Theta[ CONFA_Struc[eqno,3], CONFA_Struc[eqno,3] ] = parms[eqno]
+      }
+      if (CONFA_Struc[eqno,1] == 5) {
+         // a theta-type correlated errors entry
+         Theta[ CONFA_Struc[eqno,3], CONFA_Struc[eqno, 4] ] = parms[eqno]
+         Theta[ CONFA_Struc[eqno,4], CONFA_Struc[eqno, 3] ] = parms[eqno]
+      }
+   }
+   if (CONFA_loglevel > 4) {
+      printf("{txt}Loadings:\n")
+      Lambda
+      printf("{txt}Factor covariances:\n")
+      Phi
+      printf("{txt}Residual variances:\n")
+      Theta
+   }
+   Sigma = Lambda*Phi*Lambda' + Theta
+   if (CONFA_loglevel > 4) {
+      printf("{txt}Implied moments:\n")
+      Sigma
+   }
+
+   if (CONFA_loglevel == -1) {
+      // post matrices to Stata
+      st_matrix("CONFA_Lambda",Lambda)
+      st_matrix("CONFA_Phi",Phi)
+      st_matrix("CONFA_Theta",Theta)
+      st_matrix("CONFA_Sigma",Sigma)
+   }
+
+   // done with model structure, compute and return implied matrix
+   return( Sigma )
+}
+
+// vech covariance matrix, for Satorra-Bentler
+void SBvechZZtoB(string dlist, string blist) {
+   real matrix data, moments, B;
+   real scalar i;
+
+   // view the deviation variables
+   st_view(data=.,.,tokens(dlist))
+   // view the moment variables
+   // blist=st_local("blist")
+   st_view(moments=.,.,tokens(blist))
+   // vectorize!
+   for(i=1; i<=rows(data); i++) {
+     B = data[i,.]'*data[i,.]
+     moments[i,.] = vech(B)'
+   }
+}
+
+// duplication matrix, for Satorra-Bentler
+void Dupl(scalar p, string Dname) {
+   real scalar pstar, k;
+   real matrix Ipstar, D;
+
+   pstar = p*(p+1)/2
+   Ipstar = I(pstar)
+   D = J(p*p,0,.)
+   for(k=1;k<=pstar;k++) {
+      D = (D, vec(invvech(Ipstar[.,k])))
+   }
+   st_matrix(Dname,D)
+}
+
+// Satorra-Bentler Delta matrix
+// Delta = \frac \partial{\partial \theta} vech \Sigma(\theta)
+void SBStrucToDelta(string DeltaName) {
+   real scalar CONFA_loglevel, p, t, varno, facno, i, j, k, fac1, fac2, k1, k2;
+   // log level, # obs vars, # parameters, current var, current factor, cycle indices, temp indices
+   real matrix Lambda, Phi, Theta, Sigma, CONFA_Struc, Delta, DeltaRow;
+   // must be self-explanatory
+   real matrix U, E;
+   // identity matrices of the size #factors and #obs vars
+
+   // loglevel
+
+   CONFA_loglevel = strtoreal( st_global("CONFA_loglevel"))
+
+   // need the CONFA matrices
+   CONFA_Struc = st_matrix("CONFA_Struc")
+   Sigma  = st_matrix("CONFA_Sigma")
+   Lambda = st_matrix("CONFA_Lambda")
+   Phi    = st_matrix("CONFA_Phi")
+   // Theta  = st_matrix("CONFA_Theta")
+
+   if (CONFA_loglevel>4) CONFA_Struc
+
+   // # parameters in the model
+   t = rows(CONFA_Struc)
+
+   // cols(Delta) = t = # pars
+   // rows(Delta) = pstar = p*(p+1)/2 = length( vech( Sigma ) )
+   // but that should be accumulated one by one...
+   Delta = J(0,t,.)
+
+   // sources of u and e vectors
+   p = rows( Sigma )
+   U = I( p )
+   E = I( rows(Phi) )
+
+   for(i=1;i<=p;i++) {
+     for(j=i;j<=p;j++) {
+       if (CONFA_loglevel > 4) printf("{txt}Working with pair ({res}%2.0f{txt},{res}%2.0f{txt})\n",i,j)
+       DeltaRow = J(1,t,0)
+       // parse Struc matrix and see how each parameter affects Cov(X_i,X_j)
+       for(k=1;k<=t;k++) {
+          if (CONFA_Struc[k,1] == 1) {
+             // a mean-type entry
+             // for the moment, assume it does not affect anything
+          }
+          if (CONFA_Struc[k,1] == 2) {
+             // a lambda-type entry
+             // CONFA_Struc[k,.] = (2, equation #, variable #, factor #)
+             varno = CONFA_Struc[k,3]
+             facno = CONFA_Struc[k,4]
+             DeltaRow[1,k] = U[i,.] * U[.,varno] * E[facno,.] * Phi * Lambda' * U[.,j] +
+                             U[i,.] * Lambda * Phi * E[.,facno] * U[varno,.] * U[.,j]
+          }
+          if (CONFA_Struc[k,1] == 3) {
+             // a phi-type entry
+             // CONFA_Struc[k,.] = (3, equation #, `factor`kk'', `factor`k'')
+             fac1 = CONFA_Struc[k,3]
+             fac2 = CONFA_Struc[k,4]
+             DeltaRow[1,k] = U[i,.] * Lambda * E[.,fac1] * E[fac2,.] * Lambda' * U[.,j]
+          }
+          if (CONFA_Struc[k,1] == 4) {
+             // a theta-type entry
+             // CONFA_Struc[k,.] = (4, equation #, variable #, 0)
+             varno = CONFA_Struc[k,3]
+             DeltaRow[1,k] = (i==j) & (i==varno)
+          }
+          if (CONFA_Struc[k,1] == 5) {
+             // a theta_{jk}-type entry
+             // CONFA_Struc[k,.] = (5, equation #, variable k1, variable k2)
+             k1 = CONFA_Struc[k,3]
+             k2 = CONFA_Struc[k,4]
+             DeltaRow[1,k] = ((i==k1) & (j==k2) ) | ((i==k2) & (j==k1))
+          }
+       }
+       Delta = Delta \ DeltaRow
+     }
+   }
+
+   st_matrix(DeltaName,Delta)
+}
+
+
+///////////////////////////////////////////
+// needed by confa_p.ado
+
+void CONFA_P_EB(string Fnames, string ObsVarNames, string ToUseName) {
+  real matrix ff, xx;
+  // views
+  real matrix bb, Sigma, Lambda, Theta, Phi;
+  // substantive matrices
+  real scalar p
+
+  // view on the newly generated factors
+  st_view(ff=.,.,tokens(Fnames),ToUseName)
+
+  // view on the observed variables
+  st_view(xx=.,.,tokens(ObsVarNames),ToUseName)
+
+  // get the estimated matrices
+  bb = st_matrix("e(b)")
+  Sigma = st_matrix("e(Sigma)")
+  Theta = st_matrix("e(Theta)")
+  Lambda = st_matrix("e(Lambda)")
+  Phi = st_matrix("e(Phi)")
+
+  // # observed vars
+  p = rows(Sigma)
+
+  // prediction
+  ff[,] = (xx-J(rows(xx),1,1)*bb[1..p]) * invsym(Sigma) * Lambda * Phi
+}
+
+void CONFA_P_MLE(string Fnames, string ObsVarNames, string ToUseName) {
+  real matrix ff, xx;
+  // views
+  real matrix bb, Sigma, Lambda, Theta, Phi, ThetaInv;
+  // substantive matrices
+  real scalar p
+
+  // view on the newly generated factors
+  st_view(ff=.,.,tokens(Fnames),ToUseName)
+
+  // view on the observed variables
+  st_view(xx=.,.,tokens(ObsVarNames),ToUseName)
+
+  // get the estimated matrices
+  bb = st_matrix("e(b)")
+  Sigma = st_matrix("e(Sigma)")
+  Theta = st_matrix("e(Theta)")
+  Lambda = st_matrix("e(Lambda)")
+  Phi = st_matrix("e(Phi)")
+
+  // # observed vars
+  p = rows(Sigma)
+
+  // Theta is the vector of diagonal elements,
+  // so the inverse is easy!
+  ThetaInv = diag( 1:/Theta )
+
+  // prediction
+  ff[,] = (xx-J(rows(xx),1,1)*bb[1..p]) * ThetaInv * Lambda * invsym(Lambda' * ThetaInv * Lambda)
+}
+
+//////////////////////////////////
+// needed by confa_lf.ado
+
+void CONFA_NormalLKHDr( string ParsName, string lnfname) {
+   // ParsName are the parameters
+   // lnfname is the name of the likelihood variable
+   // the observed variables are in $CONFA_obsvar
+
+   real scalar CONFA_loglevel, nobsvar, ldetWS, i;
+   // log level, # obs vars, log determinant, cycle index
+   real matrix Sigma, means, SS, InvWorkSigma;
+   // intermediate computations
+   string scalar obsvar, touse;
+   // list of observed variables
+   real matrix data, lnl, parms;
+   // views
+
+   CONFA_loglevel = strtoreal( st_global("CONFA_loglevel"))
+
+   obsvar = st_global("CONFA_obsvar")
+   nobsvar = length(tokens(obsvar))
+
+   touse = st_global("CONFA_touse")
+
+   st_view(data=., ., tokens(obsvar), touse )
+   st_view(lnl=., ., tokens(lnfname), touse)
+   st_view(parms=., ., tokens(ParsName), touse)
+
+   // using the set up where the means are the first nobsvar entries of the parameter vector,
+   means = parms[1,1..nobsvar]
+
+   Sigma = CONFA_StrucToSigma(parms[1,.])
+
+   if (CONFA_loglevel > 2) {
+      parms[1,.]
+      means
+      Sigma
+   }
+
+// do some equilibration??
+
+   SS = cholesky(Sigma)
+   InvWorkSigma = solvelower(SS,I(rows(SS)))
+   InvWorkSigma = solveupper(SS',InvWorkSigma)
+   ldetWS = 2*ln(dettriangular(SS))
+
+   for( i=1; i<=rows(data); i++ ) {
+      lnl[i,1] = -.5*(data[i,.]-means)*InvWorkSigma*(data[i,.]-means)' - .5*ldetWS - .5*nobsvar*ln(2*pi())
+   }
+
+   if (CONFA_loglevel>2) {
+      sum(lnl)
+   }
+
+}
+
+// normal likelihood with missing data
+void CONFA_NormalLKHDrMiss( string ParsName, string lnfname) {
+   // ParsName are the parameters
+   // lnfname is the name of the likelihood variable
+   // the observed variables are in $CONFA_obsvar
+
+
+   real scalar CONFA_loglevel, nobsvar, thisldetWS, i, j;
+   // log level, # obs vars, log determinant, cycle index
+   real matrix Sigma, means, thisSigma, thisSS, thisInvSigma, thispattern, parms;
+   // intermediate computations
+   string scalar obsvar, misspat, touse;
+   // list of observed variables; the names of the missing patterns and touse tempvars
+   real matrix data, lnl, parmview, pattern, mdata, mlnl, info;
+   // views
+
+   CONFA_loglevel = strtoreal( st_global("CONFA_loglevel"))
+
+   obsvar = st_global("CONFA_obsvar")
+   nobsvar = length(tokens(obsvar))
+
+   misspat = st_global("CONFA_miss")
+   touse   = st_global("CONFA_touse")
+
+   st_view(pattern=., ., misspat, touse )
+   st_view(data=., ., tokens(obsvar), touse )
+   st_view(lnl=., ., lnfname, touse )
+
+   // STILL USING THE FIRST OBSERVATIONS TO GET THE PARAMETERS!!!
+   st_view(parmview=., ., tokens(ParsName), touse )
+   parms = parmview[1,1..cols(parmview)]
+
+   if (CONFA_loglevel>2) {
+        obsvar
+        parms
+   }
+
+   // using the set up where the means are the first nobsvar entries of the parameter vector,
+   means = parms[1..nobsvar]
+
+   Sigma = CONFA_StrucToSigma(parms)
+
+   // utilize an existing set up of the missing data patterns
+   // data assumed to be sorted by the patterns of missing data
+
+   info = panelsetup( pattern, 1 )
+
+   for (i=1; i<=rows(info); i++) {
+           panelsubview(mdata=., data, i, info)
+           panelsubview(mlnl=., lnl, i, info)
+           // mdata should contain the portion of the data with the same missing data pattern
+           // mlnl will be conforming to mdata
+
+           // OK, now need to figure out that pattern
+           thispattern = J(1, cols(data), 1) - colmissing( mdata[1,] )
+           if (CONFA_loglevel > 2) {
+               printf("{txt}Pattern #{res}%5.0f{txt} :", i)
+               thispattern
+           };
+
+           // modify the matrices
+
+           thisSigma = select( select( Sigma, thispattern), thispattern' )
+           thisSS = cholesky(thisSigma)
+           thisInvSigma = solvelower(thisSS,I(rows(thisSS)))
+           thisInvSigma = solveupper(thisSS',thisInvSigma)
+           thisldetWS = 2*ln(dettriangular(thisSS))
+
+           if (CONFA_loglevel > 3) {
+              thisSigma
+              thisInvSigma
+           };
+
+           for( j=1; j<=rows(mdata); j++ ) {
+              // this is actually a single line broken by arithmetic operator signs
+              // that's bad style but it works
+              mlnl[j,1] = -.5*(select(data[j,.],thispattern)-select(means,thispattern)) *
+                              thisInvSigma *
+                              (select(data[j,.],thispattern)-select(means,thispattern))' -
+                              .5*thisldetWS - .5*sum(thispattern)*ln(2*pi())
+           }
+
+           if (CONFA_loglevel>3) {
+              mlnl
+           };
+
+   }
+
+
+}
+
+// Bollen-Stine bootstrap rotation
+void CONFA_BSrotate(
+       string SigmaName, // the parameter matrix name
+       string varnames // the variable names
+       ) {
+
+   // declarations
+   real matrix data  // views of the data
+   real matrix Sigma, SS, S2, SS2  // the covariance matrices and temp matrices
+   real matrix means // the means -- need modifications for weighted data!!!
+   real scalar n // dimension, no. obs
+
+   // get the data in
+   st_view(data=., ., tokens(varnames) )
+   n=rows(data)
+
+   Sigma = st_matrix(SigmaName)
+
+   // probability weights!!!
+   means = colsum(data)/n
+   SS = (cross(data,data)-n*means'*means)/(n-1)
+
+   S2 = cholesky(Sigma)
+   SS2 = cholesky(SS)
+   SS2 = solveupper(SS2',I(rows(SS)))
+
+   data[,] = data*SS2*S2'
+
+}
+
+
+// build a library
+mata mlib create lconfa, replace
+mata mlib add lconfa *()
+mata mlib index
+
+end
+// of mata
+
+exit
+
+// don't need this:
+
+string scalar CONFA_UL( string input ) {
+
+  string rowvector s;
+  real scalar i,j,n;
+
+  // tokenize input into a string vector
+  s = tokens( input )
+  n = cols( s )
+  for(i=1;i<=n;i++) {
+    // as I go over the elements, compare to the previous ones
+    for(j=1;j1 {
+     * display the factor correlations
+
+     di as text "{hline 13}{c TT}{hline 64}"
+     if "`e(vcetype)'" ~= "" {
+     di as text "             {c |}           {center 15:`e(vcetype)'}"
+     }
+     di as text "             {c |}      Coef.   Std. Err.      z    P>|z|     [$S_level% Conf. Interval]"
+     di as text "{hline 13}{c +}{hline 64}"
+
+     * parse the factor names
+     local fnames : rownames e(Phi)
+     * parse the unitvar list to be used in -inlist-
+     local unitvarlist = `"""' + subinstr("`e(unitvar)'"," ",`"",""',.) + `"""'
+
+     _diparm __lab__ , label("Factors") eqlabel
+
+     forvalues i=1/`q' {
+        local i1 = `i'+1
+        forvalues j=`i1'/`q' {
+          if inlist("`: word `i' of `fnames''", `unitvarlist') & inlist("`: word `j' of `fnames''", `unitvarlist') {
+             * both factor variances are constrained at 1, display as is
+             _diparm phi_`i'_`j' , prob label("`: word `i' of `fnames''-`: word `j' of `fnames''") `level' `bound'
+          }
+          else if inlist("`: word `i' of `fnames''", `unitvarlist') & !inlist("`: word `j' of `fnames''", `unitvarlist') {
+             * `i' is restricted unit variance, `j' is not
+          _diparm phi_`i'_`j' phi_`j'_`j', ///
+             function( @1/sqrt(@2) ) d( 1/sqrt(@2) -0.5*@1/sqrt(@2*@2*@2) ) ///
+             prob label("`: word `i' of `fnames''-`: word `j' of `fnames''") `level' `bound'
+          }
+          else if !inlist("`: word `i' of `fnames''", `unitvarlist') & inlist("`: word `j' of `fnames''", `unitvarlist') {
+             * `j' is restricted unit variance, `i' is not
+          _diparm phi_`i'_`j' phi_`i'_`i', ///
+             function( @1/sqrt(@2) ) d( 1/sqrt(@2) -0.5*@1/sqrt(@2*@2*@2) ) ///
+             prob label("`: word `i' of `fnames''-`: word `j' of `fnames''") `level' `bound'
+          }
+          else {
+             * display correlation transform
+          _diparm phi_`i'_`j' phi_`i'_`i' phi_`j'_`j', ///
+             function( @1/sqrt(@2*@3) ) d( 1/sqrt(@2*@3) -0.5*@1/sqrt(@2*@2*@2*@3) -0.5*@1/sqrt(@2*@3*@3*@3) ) ///
+             prob label("`: word `i' of `fnames''-`: word `j' of `fnames''") `level' `bound'
+          }
+        }
+     }
+
+   }
+
+
+   if "`e(correlated)'" ~= "" {
+
+     if `q' < 2 {
+        * need to display the header
+
+        di as text "{hline 13}{c TT}{hline 64}"
+        if "`e(vcetype)'" ~= "" {
+        di as text "             {c |}           {center 15:`e(vcetype)'}"
+        }
+        di as text "             {c |}      Coef.   Std. Err.      z    P>|z|     [$S_level% Conf. Interval]"
+        di as text "{hline 13}{c +}{hline 64}"
+     }
+
+     * print out correlated measurement errors
+     _diparm __lab__ , label("Errors") eqlabel
+     local correlated `e(correlated)'
+     local obsvar `e(observed)'
+     while "`correlated'" != "" {
+        gettoken corrpair correlated : correlated , match(m)
+        gettoken corr1 corrpair : corrpair, parse(":")
+        unab corr1 : `corr1'
+        gettoken sc corr2 : corrpair, parse(":")
+        unab corr2 : `corr2'
+
+        poslist `obsvar' \ `corr1', global(CFA_temp)
+        local k1 = $CFA_temp
+        poslist `obsvar' \ `corr2', global(CFA_temp)
+        local k2 = $CFA_temp
+
+        _diparm theta_`k1'_`k2' theta_`k1' theta_`k2', ///
+           function( @1/sqrt(@2*@3) ) d( 1/sqrt(@2*@3) -0.5*@1/sqrt(@2*@2*@2*@3) -0.5*@1/sqrt(@2*@3*@3*@3) ) ///
+           prob label("`corr1'-`corr2'") `level' `bound'
+
+     }
+
+   }
+   else if `q'<2 {
+      di as text _n "Nothing to display" _n
+   }
+
+   di as text "{hline 13}{c BT}{hline 64}"
+
+   global CFA_temp
+
+end
+
+program FitIndices, rclass
+
+   syntax , [all tli rmsea rmsr aic bic]
+
+   di _n "{txt}  Fit indices" _n
+   return add
+
+   * all, by default
+   if "`*'" == "" local all 1
+
+   * the fundamentals
+   local p = `: word count `e(obsvar)''
+
+   if "`rmsea'`all'"~="" {
+      return scalar RMSEA = sqrt( max( (e(lr_u)-e(df_u))/(e(N)-1), 0 )/e(df_u) )
+      tempname ll lu
+      scalar `ll' = cond(chi2(e(df_u),e(lr_u))>0.95,npnchi2(e(df_u),e(lr_u),0.95),0)
+      scalar `lu' = cond(chi2(e(df_u),e(lr_u))>0.05,npnchi2(e(df_u),e(lr_u),0.05),0)
+      return scalar RMSEA05 = sqrt( `ll'/( (e(N)-1)*e(df_u) ) )
+      return scalar RMSEA95 = sqrt( `lu'/( (e(N)-1)*e(df_u) ) )
+      di "{txt}RMSEA {col 8}= {res}" %6.4f return(RMSEA) _c
+      di "{txt}, 90% CI{col 8}= ({res}" %6.4f return(RMSEA05) "{txt}, {res}" %6.4f return(RMSEA95) "{txt})"
+   }
+
+   if "`rmsr'`all'"~="" {
+      cap mat li e(S)
+      if _rc {
+         * no matrix posted
+         return scalar RMSR = .
+      }
+      else {
+         tempname res
+         mata : st_numscalar("`res'",norm(vech(st_matrix("e(Sigma)") - st_matrix("e(S)"))) )
+         return scalar RMSR = `res'/sqrt(e(pstar) )
+      }
+      di "{txt}RMSR {col 8}= {res}" %6.4f return(RMSR)
+   }
+
+   if "`tli'`all'"~="" {
+      return scalar TLI = (e(lr_indep)/e(df_indep)-e(lr_u)/e(df_u))/(e(lr_indep)/e(df_indep)-1)
+      di "{txt}TLI {col 8}= {res}" %6.4f return(TLI)
+   }
+
+   if "`cfi'`all'"~="" {
+      return scalar CFI = 1 - max( e(lr_u)-e(df_u),0 )/max( e(lr_u)-e(df_u), e(lr_indep)-e(df_indep),0 )
+      di "{txt}CFI {col 8}= {res}" %6.4f return(CFI)
+   }
+
+   if "`aic'`all'"~="" {
+      if "`e(wexp)'" == "" & "`e(vcetype)'"~="Robust" return scalar AIC = -2*e(ll) + 2*e(df_m)
+      else return scalar AIC = .
+      di "{txt}AIC {col 8}= {res}" %8.3f return(AIC)
+   }
+
+   if "`bic'`all'"~="" {
+      if "`e(wexp)'" == "" & "`e(vcetype)'"~="Robust"  return scalar BIC = -2*e(ll) + e(df_m)*ln( e(N) )
+      else return scalar BIC = .
+      di "{txt}BIC {col 8}= {res}" %8.3f return(BIC)
+   }
+
+end
+
+exit
+
+Version history:
+1.0.0 9 Jan 2008  -- Correlate
+                     FitIndices
+1.0.1 12 Sep 2008 -- AIC, BIC
+1.0.2    Oct 2008 -- bound for Correlate CI
+                     correlated measurement errors
+                     CI for RMSEA
diff --git a/Modules/ado/plus/c/confa_estat.sthlp b/Modules/ado/plus/c/confa_estat.sthlp
new file mode 100644
index 0000000..090cd9b
--- /dev/null
+++ b/Modules/ado/plus/c/confa_estat.sthlp
@@ -0,0 +1,205 @@
+{smcl}
+{* *! version 1.1.13  04jun2007}{...}
+{cmd:help confa postestimation}{right: ({browse "http://www.stata-journal.com/article.html?article=st0169":SJ9-3: st0169})}
+{hline}
+
+{title:Title}
+
+{p2colset 5 29 31 2}{...}
+{p2col :{hi:confa postestimation} {hline 2}}Postestimation tools for confa{p_end}
+{p2colreset}{...}
+
+
+{title:Description}
+
+{pstd}The following commands are available after {helpb confa}:{p_end}
+
+{synoptset 17}{...}
+{p2coldent :command}description{p_end}
+{synoptline}
+{synopt :{helpb confa_estat##fit:estat fitindices}}fit indices{p_end}
+{synopt :{helpb confa_estat##ic:estat aic}}AIC{p_end}
+{synopt :{helpb confa_estat##ic:estat bic}}BIC{p_end}
+{synopt :{helpb confa_estat##corr:estat correlate}}correlations of factors and measurement errors{p_end}
+{synopt :{helpb confa_estat##predict:predict}}factor scores{p_end}
+{synopt :{helpb bollenstine}}Bollen-Stine bootstrap{p_end}
+{synoptline}
+{p2colreset}{...}
+
+
+{marker fit}{...}
+{title:The estat fitindices command}
+
+    {title:Syntax}
+
+{p 8 15 2}
+{cmd:estat} {cmdab:fit:indices}
+[{cmd:,} {it:options}]
+
+{p2colset 9 27 29 2}{...}
+{p2col:{it:options}}fit index{p_end}
+{p2line}
+{p2col :{opt aic}}Akaike information criterion{p_end}
+{p2col :{opt bic}}Schwarz Bayesian information criterion{p_end}
+{p2col :{opt cfi}}comparative fit index{p_end}
+{p2col :{opt rmsea}}root mean squared error of approximation{p_end}
+{p2col :{opt rmsr}}root mean squared residual{p_end}
+{p2col :{opt tli}}Tucker-Lewis index{p_end}
+{p2col :{opt _all}}all the above indices, the default{p_end}
+{p2line}
+{p2colreset}{...}
+
+    {title:Description}
+
+{pmore}{opt estat }{cmd:fitindices} computes, prints, and saves into
+{cmd:r()} results several traditional fit indices.
+
+    {title:Options}
+
+{phang2}
+{opt aic} requests the Akaike information criterion (AIC).
+
+{phang2}
+{opt bic} requests the Schwarz Bayesian information criterion (BIC).
+
+{phang2}
+{opt cfi} requests the CFI (Bentler 1990b).
+
+{phang2}
+{opt rmsea} requests the RMSEA (Browne and Cudeck 1993).
+
+{phang2}
+{opt rmsr} requests the RMSR.
+
+{phang2}
+{opt tli} requests the TLI (Tucker and Lewis 1973).
+
+{phang2}
+{opt _all} requests all the above indices. This is the default
+behavior if no option is specified.
+
+
+{marker ic}{...}
+{title:The estat aic and estat bic commands}
+
+    {title:Syntax}
+
+{p 8 15 2}
+{cmd:estat} {cmd:aic}
+
+{p 8 15 2}
+{cmd:estat} {cmd:aic}
+
+    {title:Description}
+
+{pmore}{cmd:estat aic} and {cmd:estat bic} compute the Akaike and Schwarz
+Bayesian information criteria, respectively.
+
+
+{title:The estat correlate command}
+
+    {title:Syntax}
+
+{p 8 15 2}
+{cmd:estat} {cmdab:corr:elate}
+[{cmd:,}
+{opt level(#)}
+{opt bound}]
+
+    {title:Description}
+
+{marker corr}{...}
+{pmore}{opt estat} {cmd:correlate} transforms the covariance parameters into
+correlations for factor covariances and measurement-error covariances.  The
+delta method standard errors are given; for correlations close to plus or
+minus 1, the confidence intervals may extend beyond the range of admissible
+values.{p_end}
+
+    {title:Options}
+
+{phang2}{opt level(#)} changes the confidence level for confidence-interval
+reporting.{p_end}
+
+{phang2}{cmd:bound} provides an alternative confidence interval based on
+Fisher's z transform of the correlation coefficient. It guarantees
+that the end points of the interval are in the (-1,1) range, provided the
+estimate itself is in this range.
+
+
+{marker predict}{...}
+{title:The predict command}
+
+    {title:Syntax}
+
+{p 8 19 2}
+{cmd:predict} {dtype} {it:{help newvarlist}} {ifin} [{cmd:,} {it:scoring_method}]
+
+{p2colset 9 27 29 2}{...}
+{p2col:{it:scoring_method}}factor scoring method{p_end}
+{p2line}
+{p2col:{cmdab:reg:ression}}regression, or empirical Bayes, score{p_end}
+{p2col:{cmdab:emp:iricalbayes}}alias for {cmd:regression}{p_end}
+{p2col:{cmdab:eb:ayes}}alias for {cmd:regression}{p_end}
+{p2col:{opt mle}}MLE, or Bartlett score{p_end}
+{p2col:{cmdab:bart:lett}}alias for {cmd:mle}{p_end}
+{p2line}
+{p2colreset}{...}
+
+    {title:Description}
+
+{pmore} {cmd:predict} can be used to create factor scores following {cmd:confa}.
+The number of variables in {it:newvarlist} must be the same as the number of
+factors in the model specification; all factors are predicted at once by the
+relevant matrix formula.
+
+    {title:Options}
+
+{phang2}
+{opt regression}, {opt empiricalbayes}, or {opt ebayes}
+requests regression, or empirical Bayes, factor scoring procedure.
+
+{phang2}
+{opt mle} or {opt bartlett} requests Bartlett scoring procedure.
+
+
+{title:Example}
+
+{phang}{cmd:. use hs-cfa}{p_end}
+{phang}{cmd:. confa (vis: x1 x2 x3) (text: x4 x5 x6) (math: x7 x8 x9), from(iv) corr(x7:x8)}{p_end}
+{phang}{cmd:. estat fit}{p_end}
+{phang}{cmd:. estat corr}{p_end}
+{phang}{cmd:. estat corr, bound}{p_end}
+{phang}{cmd:. predict fa1-fa3, reg}{p_end}
+{phang}{cmd:. predict fb1-fb3, bart}{p_end}
+
+
+{title:References}
+
+{phang}
+Bentler, P. M. 1990. Comparative fit indexes in structural models. 
+{it:Psychological Bulletin} 107: 238-246.
+
+{phang}
+Browne, M. W., and R. Cudeck. 1993. Alternative ways of assessing model fit.
+In {it:Testing Structural Equation Models}, ed. K. A. Bollen and J. S. Long,
+136-162. Newbury Park, CA: Sage.
+
+{phang}
+Tucker, L. R., and C. Lewis. 1973. A reliability coefficient for maximum likelihood factor analysis. {it:Psychometrika} 38: 1-10.
+
+
+{title:Author}
+
+{pstd}Stanislav Kolenikov{p_end}
+{pstd}Department of Statistics{p_end}
+{pstd}University of Missouri{p_end}
+{pstd}Columbia, MO{p_end}
+{pstd}kolenikovs@missouri.edu{p_end}
+
+
+{title:Also see}
+
+{psee}
+Article: {it:Stata Journal}, volume 9, number 3: {browse "http://www.stata-journal.com/article.html?article=st0169":st0169}
+
+{psee}Online: {helpb confa}, {helpb bollenstine}{p_end}
diff --git a/Modules/ado/plus/c/confa_lf.ado b/Modules/ado/plus/c/confa_lf.ado
new file mode 100644
index 0000000..9b968c3
--- /dev/null
+++ b/Modules/ado/plus/c/confa_lf.ado
@@ -0,0 +1,20 @@
+*! Log likelihood for confa: linear form; part of confa suite; 16 Oct 2008
+program define confa_lf
+
+   args lnf $CONFA_args
+   * $CONFA_args contains the names of the equations, but
+   * we need the variable names
+   gettoken lnf allthenames : 0
+
+   tempvar lnl
+   qui g double `lnl' = .
+
+   mata: CONFA_NormalLKHDr( "`allthenames'", "`lnl'")
+
+   qui replace `lnf' = `lnl'
+
+   if $CONFA_loglevel > 3 li `lnl'
+
+end
+
+exit
diff --git a/Modules/ado/plus/c/confa_lfm.ado b/Modules/ado/plus/c/confa_lfm.ado
new file mode 100644
index 0000000..0dfabfb
--- /dev/null
+++ b/Modules/ado/plus/c/confa_lfm.ado
@@ -0,0 +1,20 @@
+*! Log likelihood for confa: linear form; part of confa suite; 23 Apr 2009
+program define confa_lfm
+
+   args lnf $CONFA_args
+   * $CONFA_args contains the names of the equations, but
+   * we need the variable names
+   gettoken lnf allthenames : 0
+
+   tempvar lnl
+   qui g double `lnl' = .
+
+   mata: CONFA_NormalLKHDrMiss( "`allthenames'", "`lnl'")
+
+   qui replace `lnf' = `lnl'
+
+   if $CONFA_loglevel > 3 li `lnl'
+
+end
+
+exit
diff --git a/Modules/ado/plus/c/confa_p.ado b/Modules/ado/plus/c/confa_p.ado
new file mode 100644
index 0000000..99e2a71
--- /dev/null
+++ b/Modules/ado/plus/c/confa_p.ado
@@ -0,0 +1,89 @@
+*! v.1.0 -- prediction commands for confa suite; 16 Oct 2008
+program define confa_p
+  version 10
+
+* set trace on
+
+* di as inp "`0'"
+
+  syntax anything [if] [in], [EBayes EMPiricalbayes REGression MLE BARTlett SCores]
+
+* fork to equation scores or factor scores
+
+  if "`scores'"!="" EqScores `0'
+  else if "`ebayes'`empiricalbayes'`regression'`mle'`bartlett'" != "" FScores `0'
+  else {
+     di as err "cannot figure those options out"
+     exit 198
+  }
+
+end
+
+program define EqScores
+
+  * implicitly used by _robust and svy
+  * typical request: predict stub*, scores
+  * stub* is not parsed well by newvarlist, have to use anything
+  syntax anything [if] [in], scores
+  marksample touse, novarlist
+  ml score `anything' if `touse'
+end
+
+program define FScores
+
+  * user requested factor predictions
+
+  syntax newvarlist [if] [in], [EBayes EMPiricalbayes REGression MLE BARTlett]
+
+  marksample touse, novarlist
+
+  if "`ebayes'`empiricalbayes'`regression'`mle'`bartlett'" == "" | ///
+     ( ("`ebayes'`empiricalbayes'`regression'"~="" ) & ("`mle'`bartlett'"~="" ) ) {
+
+      di as err "One and only one factor scoring option must be specified"
+      exit 198
+  }
+  else {
+
+     local nfactors = rowsof( e(Phi) )
+
+     if "`: word count `varlist''" ~= "`nfactors'" {
+        di as err "Must specify as many new variables as there were factors in confa model"
+        exit 198
+     }
+
+     * generate new variables
+     forvalues k=1/`nfactors' {
+       tempname f`k'
+       qui gen double `f`k'' = .
+       local flist `flist' `f`k''
+     }
+
+     if "`ebayes'`empiricalbayes'`regression`" ~= "" {
+        * Empirical Bayes:
+        mata : CONFA_P_EB("`flist'", "`e(observed)'", "`touse'")
+     }
+
+     if "`mle'`bartlett'" ~= "" {
+        * MLE/Bartlett scoring:
+        mata : CONFA_P_MLE("`flist'", "`e(observed)'", "`touse'")
+     }
+
+     nobreak {
+       forvalues k=1/`nfactors' {
+         local type : word `k' of `typlist'
+         local name : word `k' of `varlist'
+         qui gen `type' `name' = `f`k'' if `touse'
+         label var `name' `"`e(factor`k')', `ebayes'`empiricalbayes'`regression'`mle'`bartlett' method"'
+       }
+     }
+
+  }
+
+
+end
+
+exit
+
+History:
+v.1.0 -- June 12, 2008: Empirical Bayes and MLE scoring
diff --git a/Modules/ado/plus/c/confirmdir.ado b/Modules/ado/plus/c/confirmdir.ado
new file mode 100644
index 0000000..b0088cd
--- /dev/null
+++ b/Modules/ado/plus/c/confirmdir.ado
@@ -0,0 +1,18 @@
+*! comfirmdir Version 1.1 dan.blanchette@duke.edu  22Jan2009
+*! Center of Entrepreneurship and Innovation Duke University's Fuqua School of Business
+* confirmdir Version 1.1 dan_blanchette@unc.edu  17Jan2008
+* research computing, unc-ch
+*  - made it handle long directory names
+** confirmdir Version 1.0 dan_blanchette@unc.edu  05Oct2003
+** the carolina population center, unc-ch
+
+program define confirmdir, rclass
+ version 8
+ 
+ local cwd `"`c(pwd)'"'
+ quietly capture cd `"`1'"'
+ local confirmdir=_rc 
+ quietly cd `"`cwd'"'
+ return local confirmdir `"`confirmdir'"'
+ 
+end 
diff --git a/Modules/ado/plus/c/confirmdir.hlp b/Modules/ado/plus/c/confirmdir.hlp
new file mode 100644
index 0000000..78c2c98
--- /dev/null
+++ b/Modules/ado/plus/c/confirmdir.hlp
@@ -0,0 +1,54 @@
+{smcl}
+{* 17Jan2008}{...}
+{* 28Oct2004}{...}
+{* 19Nov2003}{...}
+{hline}
+help for {hi:confirmdir} {right:manual:  {hi:[R] none}}
+{right:dialog:  {hi: none}    }
+{hline}
+
+
+{title:Confirms if directory exists}
+
+{p 8 17 2}
+{cmd:confirmdir} {it:full direcotory name}
+{p_end}
+
+        
+{title:Description}
+
+{p 4 4 2}{cmd:confirmdir} is designed for programmers who want to know if a directory exists.
+This is just like {cmd:confirm} command when used to confirm a file.  If Stata allowed their
+{cmd:confirm} command to also have the "dir" option, this program would not have been 
+written.  Stata's {cmd:confirm file} will confirm a directory in UNIX/Linux but not in Windows.
+{cmd:confirmdir} works in all operating systems.{p_end}
+
+{title:Examples}
+
+{p 4 8 2}{cmd:.  confirmdir "c:\My Favorite Directory\Where I Keep Stuff\"}{p_end}
+
+{p 4 8 2}{cmd:.  confirmdir /projects/ethiopia/survey2002/data/}{p_end}
+
+
+{title:Saved Results}
+
+{p 4 8 2}The {cmd:confirmdir} command saves in {cmd:r()}:{p_end}
+ 
+{synoptset 20 tabbed}{...}
+{p2col 5 20 24 2: Macros}{p_end}
+{synopt:{cmd:r(confirmdir)}}return code returned by the {help cd:cd} command.{p_end}
+
+
+{title:Author}
+
+{p 4 4 2}
+Dan Blanchette {break}
+Center of Entrepreneurship and Innovation {break}
+Duke University's Fuqua School of Business {break}
+Dan.Blanchette@Duke.edu{p_end} 
+
+
+{title:Also see}
+
+{p 4 13 2}On-line: {help confirm:confirm} {help cd:cd}, {help tmpdir:tmpdir} (if installed){p_end}
+
diff --git a/Modules/ado/plus/c/convlist.ado b/Modules/ado/plus/c/convlist.ado
new file mode 100644
index 0000000..9d59d11
--- /dev/null
+++ b/Modules/ado/plus/c/convlist.ado
@@ -0,0 +1,62 @@
+program def convlist, rclass
+*! NJC 1.0.0 9 April 2001 
+	version 6.0 
+	gettoken lists 0 : 0, parse(",")
+	if "`lists'" == "" | "`lists'" == "," {  
+		di in r "no lists specified" 
+		exit 198 
+	}
+	
+	tokenize "`lists'", parse("\") 
+	if "`4'" != "" | "`2'" != "\" { 
+		di in r "incorrect syntax" 
+		exit 198 
+	} 	
+	numlist "`1'"                         
+	local list1 `r(numlist)'
+	local n1 : word count `list1' 
+	numlist "`3'"  
+	local list2 `r(numlist)' 
+	local n2 : word count `list2' 
+	
+	syntax [ , Global(str) Noisily ]
+	
+	if length("`global'") > 8 { 
+		di in r "global name must be <=8 characters" 
+		exit 198 
+	} 	
+
+	local n3 = `n1' + `n2' - 1 
+	local k = 1 
+	while `k' <= `n3' { 
+		tempname c`k' 
+		scalar `c`k'' = 0 
+		local k = `k' + 1
+	} 	
+
+	tokenize `list1' 
+
+	local i = 1 
+	while `i' <= `n1' { 
+		local j = 1 
+		while `j' <= `n2' {
+			local b`j' : word `j' of `list2' 
+			local k = `i' + `j' - 1
+			scalar `c`k'' = `c`k'' + (``i'' * `b`j'') 
+			local j = `j' + 1 
+		} 
+		local i = `i' + 1
+	}
+	
+	local k = 1 
+	while `k' <= `n3' {
+		local this = `c`k'' 
+		local newlist "`newlist'`this' " 
+		local k = `k' + 1
+	} 	
+
+	if "`noisily'" != "" { di "`newlist'" } 
+	if "`global'" != "" { global `global' "`newlist'" } 
+	return local list `newlist' 
+end 	
+			 
diff --git a/Modules/ado/plus/c/convlist.hlp b/Modules/ado/plus/c/convlist.hlp
new file mode 100644
index 0000000..eacf780
--- /dev/null
+++ b/Modules/ado/plus/c/convlist.hlp
@@ -0,0 +1,2 @@
+.h listutil
+
diff --git a/Modules/ado/plus/c/countfit.ado b/Modules/ado/plus/c/countfit.ado
new file mode 100644
index 0000000..4e1103b
--- /dev/null
+++ b/Modules/ado/plus/c/countfit.ado
@@ -0,0 +1,877 @@
+*! version 0.8.1 - 2009-07-31
+*   work around S11 bug in estimates table
+
+*  To do:
+*   1) add weights
+*   2) use returns rather than scalars
+
+// compare count models
+
+capture program drop countfit
+program define countfit, rclass
+    version 9.0
+    
+    * 2009-07-31
+    local vwidth = 32 // causes error in Stata 11 
+    local vwidth = 30
+
+    syntax varlist [if] [in] ///
+    , [Generate(string)  replace ///
+      INFlate(string) /// inflation variables
+      MAXcount(integer 9) ///
+      NOGraph /// suppress graph of differences in predicted probabilities
+      NODifferences /// suppress table of differences in predicted probabilities
+      NOEstimates /// suppress table of estimated parameters
+      NOFit /// suppress table of fit statistics
+      Prm Nbreg ZIP ZINb ///
+      nodash ///
+      NOConstant ///
+      NOPRTable ///
+      note(string) /// note for graph
+      GRAPHexport(string) /// options passed to graph export
+      NOIsily ///
+      ]
+
+// trap weights
+
+    if "`e(wtype)'"!="" {
+        di in r "-countfix- does not work with weights."
+        exit
+    }
+
+//  define variable lists
+
+    * inflate is same as rhs if not specified
+    if "`inflate'"=="" {
+        ** better way to do this?
+        local nvars : word count `varlist'
+        foreach i of numlist 2(1)`nvars' {
+            local var : word `i' of `varlist'
+            local inflate "`inflate' `var'"
+        }
+    }
+
+// set up printing
+
+    local f83 "%8.3f"
+    local f93 "%9.3f"
+    local f93l "%-9.3f"
+    local f103 "%10.3f"
+    local dash ""
+    if "`nodash'"=="" {
+        local dash ///
+        "--------------------------------------------------------------------------"
+    }
+
+// construct information on models being assessed
+
+    * defalult name is CF for variables created
+    if "`generate'"=="" local set "CF"
+    local set "`generate'" // label for sets of models
+    local modellist "" // list of types of models estimated
+    local mdlnmlist "" // like modellist but begin with generate prefix _
+    local pltsym "" // symbols used in the plot
+    local plty "" // y variables to plot
+    local pltx "" // x variables to plot
+    local mdlnum = 1 // number associated with each model
+
+    * set up information for all models specified
+    if "`prm'"=="prm" {
+        local mdlnmlist "`mdlnmlist' `set'PRM"
+        local modellist "PRM "
+        local pltx "`set'PRMval"
+        local plty "`set'PRMdif "
+        local pltsym "Th "
+        local pltleg1 "`set'PRM"
+        local mdlnum = `mdlnum' + 1
+    }
+    if "`nbreg'"=="nbreg" {
+        local mdlnmlist "`mdlnmlist' `set'NBRM"
+        local modellist "`modellist'NBRM "
+        local pltx "`set'NBRMval"
+        local plty "`plty' `set'NBRMdif "
+        local pltsym "`pltsym' Sh "
+        local pltleg`mdlnum' "`set'NBRM"
+        local mdlnum = `mdlnum' + 1
+    }
+    if "`zip'"=="zip" {
+        local mdlnmlist "`mdlnmlist' `set'ZIP"
+        local modellist "`modellist'ZIP "
+        local pltx "`set'ZIPval"
+        local plty "`plty' `set'ZIPdif "
+        local pltsym "`pltsym' T "
+        local pltleg`mdlnum' "`set'ZIP"
+        local mdlnum = `mdlnum' + 1
+    }
+    if "`zinb'"=="zinb" {
+        local mdlnmlist "`mdlnmlist' `set'ZINB"
+        local modellist "`modellist'ZINB "
+        local pltx "`set'ZINBval"
+        local plty "`plty' `set'ZINBdif "
+        local pltsym "`pltsym' S "
+        local pltleg`mdlnum' "`set'ZINB"
+        local mdlnum = `mdlnum' + 1
+    }
+    * if none, then all
+    if "`prm'"=="" & "`nbreg'"=="" & "`zip'"=="" & "`zinb'"=="" {
+        local pltx "`set'PRMval"
+        local plty "`set'PRMdif `set'NBRMdif `set'ZIPdif `set'ZINBdif"
+        local pltsym "Th Sh T S"
+        local pltleg1 "`set'PRM"
+        local pltleg2 "`set'NBRM"
+        local pltleg3 "`set'ZIP"
+        local pltleg4 "`set'ZINB"
+        local mdlnmlist "`set'PRM `set'NBRM `set'ZIP `set'ZINB"
+        local modellist "PRM NBRM ZIP ZINB"
+        local prm "prm"
+        local nbreg "nbreg"
+        local zip "zip"
+        local zinb "zinb"
+        * drop? local alphaopt "drop(lnalpha:_cons)"
+    }
+
+// estimate models
+
+    * 2009-07-31
+    _count_estimate `varlist' `if' `in' [`fweight' `pweight' `iweight'], ///
+        max(`maxcount') gen(`generate') `replace' inflate(`inflate') ///
+        `prm' `nbreg' `zip' `zinb' `noconstant' `noisily'
+
+// table of estimates
+
+
+    if "`noestimates'"=="" {
+        estimates table `mdlnmlist', eform ///
+            b(%9.3f) t(%7.2f) label varwidth(`vwidth') ///
+            stats(alpha N ll bic aic)
+    }
+
+// summary table of mean observed - predicted probabilities
+
+    local c1 = 10
+    local c2 = 25
+    local c3 = 31
+    local c4 = 47
+
+    if "`nodifferences'"=="" {
+
+        di in g "Comparison of Mean Observed and Predicted Count"
+        di
+        di in g "     " _col(`c1') "   Maximum"    ///
+            _col(`c2') "  At" ///
+            _col(`c3') "    Mean"
+        di in g "Model" _col(`c1') " Difference" ///
+            _col(`c2') "Value" ///
+            _col(`c3') "   |Diff|"
+        di in g "---------------------------------------------"
+    }
+
+    * loop through models and compute differences
+    foreach m in `modellist' {
+
+        local modelnm "`set'`m'"
+
+        * stats on difference
+        qui sum `modelnm'dif
+        local toplot "`toplot' `modelnm'dif"
+        local `m'difsd = r(sd) // sd of obs-pred
+        local `m'difmin = r(min) // min
+        local `m'difmax = r(max) // max
+
+        * stats on mean absolute difference
+        capture drop `modelnm'difabs
+        qui gen `modelnm'absdif = abs(`modelnm'dif)
+        qui sum `modelnm'absdif
+        local `m'absdifmax = r(max) // max
+        scalar absdifsd`m' = r(sd) // sd
+        scalar absdifmn`m' = r(mean) // mean
+        * find values for largest difference
+        tempname difval
+        qui gen `difval' = (`modelnm'absdif>``m'absdifmax'-.00001)*_n ///
+                if `modelnm'absdif!=.
+        qui sum `difval'
+        local `m'absdifmaxval = r(max) - 1
+
+        * sign of deviation
+        tempname maxdif // 0.8.0
+        if ``m'absdifmax' == abs(``m'difmin') {
+        *local maxdif = ``m'difmin' // 0.8.0
+            scalar `maxdif' = ``m'difmin'
+        }
+        if ``m'absdifmax' == abs(``m'difmax') {
+        *local maxdif = ``m'difmax' // 0.8.0
+            scalar `maxdif' = ``m'difmax'
+        }
+
+        if "`nodifferences'"=="" {
+            * print summary of differences from predictions
+            di in y "`modelnm'" _col(`c1') in y `f83' `maxdif' ///
+                _col(`c2') `f83' "  ``m'absdifmaxval'" ///
+                _col(`c3') `f83' absdifmn`m'
+        }
+
+    } // loop through models
+
+// TABLES OF OBSERVED AND PREDICTED COUNTS
+
+    if "`noprtable'" == "" {
+
+        foreach t in `mdlnmlist' {
+
+            qui {
+                sum `t'absdif
+                local max = r(N) - 1 // largest count
+                tempname sumde sumpe sumob sumpr // 0.8.0
+                scalar `sumde' = r(sum) // sum of abs dif
+                sum `t'pearson
+                scalar `sumpe' = r(sum) // sum of pearson dif
+                sum `t'obeq
+                scalar `sumob' = r(sum) // sum of pr observed
+                sum `t'preq
+                scalar `sumpr' = r(sum) // sum of pr predicted
+            } // qui
+            local c1 = 7
+            local c2 = 19
+            local c3 = 30
+            local c4 = 40
+            local c5 = 50
+            di
+            di in y "`t'" in g ": Predicted and actual probabilities"
+            di
+            di in g "Count" _col(`c1') "  Actual" ///
+                _col(`c2') "Predicted" ///
+                _col(`c3') "  |Diff|" ///
+                _col(`c4') " Pearson"
+
+            local dash ""
+            if "`nodash'"=="" {
+                local dash ///
+                "------------------------------------------------"
+            }
+
+            di in g "`dash'"
+
+            foreach c of numlist 0(1)`max' {
+                local i = `c' + 1
+                tempname ob pr de pe // 0.8.0
+                scalar `ob' = `t'obeq[`i']
+                scalar `pr' = `t'preq[`i']
+                scalar `de' = abs(`t'dif[`i'])
+                scalar `pe' = `t'pearson[`i']
+
+                di in y "`c'" ///
+                    _col(`c1') `f83' `ob' ///
+                    _col(`c2') `f83' `pr' ///
+                    _col(`c3') `f83' `de' ///
+                    _col(`c4') `f83' `pe'
+
+            } // loop through counts
+
+            di in g "`dash'"
+            di in y "Sum" ///
+                _col(`c1') `f83' `sumob' ///
+                _col(`c2') `f83' `sumpr' ///
+                _col(`c3') `f83' `sumde' ///
+                _col(`c4') `f83' `sumpe'
+
+        } // loop through modellist
+
+    } // print table of predictions
+
+// PLOT DIFFERENCES
+
+    if "`nograph'"=="" {
+
+        twoway (connected `plty' `pltx', ///
+            msymbol(`pltsym') ///
+            clpat(tight_dot tight_dot tight_dot tight_dot ) ///
+            ytitle("Observed-Predicted") ///
+            subtitle("Note: positive deviations show underpredictions.",  ///
+            pos(11) size(small)) ///
+            ylabel(-.10(.05).10, grid gmax gmin) ///
+            xlabel(0(1)`maxcount') ///
+            note(`note') ///
+            ysize(3.5) xsize(4.5) ///
+            legend(order(1 "`pltleg1'" 2 "`pltleg2'" ///
+            3 "`pltleg3'" 4 "`pltleg4'")) ///
+        )
+
+        * export graph
+        if "`graphexport'" != "" {
+            qui graph export `graphexport'
+        }
+
+    }
+
+// COMPARE FIT STATISTICS
+
+    if "`nofit'"=="" {
+
+        local dash ""
+        if "`nodash'"=="" {
+        local dash ///
+    "-------------------------------------------------------------------------"
+        }
+        local c1 = 16
+        local c2 = 32
+        local c3 = 48
+        local c4 = 56
+        local c5 = 62
+
+        di _n in g "Tests and Fit Statistics"
+        di
+        tempname aicd  // 0.8.0
+
+        * base PRM
+        if "`prm'"!="" {
+            local mdl1 "`set'PRM"
+            local mdl1type "PRM"
+            di in y "`mdl1'" ///
+                _col(`c1') in g "BIC=" in y `f103' bic`mdl1' ///
+                _col(`c2') in g "AIC=" in y `f103' aic`mdl1' ///
+                _col(`c3') in g "Prefer" ///
+                _col(`c4') in g "Over" ///
+                _col(`c5') in g "Evidence"
+
+            * prm vs nbreg
+            if "`nbreg'"!="" {
+                local mdl2 "`set'NBRM"
+                local mdl2type "NBRM"
+                global bic1 = bic`mdl1'
+                global bic2 = bic`mdl2'
+                _count_bic_dif
+                local pref = $bicpref
+                local nopref = $bicnopref
+                di "`dash'"
+                * bic
+                di in y " " in g " vs " in y "`mdl2'" ///
+                    _col(`c1') in g "BIC=" in y `f103' bic`mdl2' ///
+                    _col(`c2') in g "dif=" in y `f103' $bicdif ///
+                    _col(`c3') in y "`mdl`pref'type'" ///
+                    _col(`c4') in y "`mdl`nopref'type'" ///
+                    _col(`c5') in y "$bicsup"
+                * aic
+                scalar `aicd' = aic`mdl1' - aic`mdl2'
+                local aicfav "`mdl2type'"
+                local aicnofav "`mdl1type'"
+                if aic`mdl1' < aic`mdl2' {
+                    local aicfav "`mdl1type'"
+                    local aicnofav "`mdl2type'"
+                }
+                di  _col(`c1') in g "AIC=" in y `f103' aic`mdl2' ///
+                    _col(`c2') in g "dif=" in y `f103' `aicd' ///
+                    _col(`c3') in y "`aicfav'" ///
+                    _col(`c4') in y "`aicnofav'"
+                * lr test
+                local lrfav "`mdl1type'"
+                local lrnofav "`mdl2type'"
+                if lrnb_prmp < .05 {
+                    local lrfav "`mdl2type'"
+                    local lrnofav "`mdl1type'"
+                }
+                di _col(`c1') in g "LRX2=" in y `f93' lrnb_prm ///
+                    _col(`c2') in g "prob=" in y `f93' lrnb_prmp in g ///
+                    _col(`c3') in y "`lrfav'" ///
+                    _col(`c4') in y "`lrnofav'" ///
+                    _col(`c5') in y "p=" `f93l' lrnb_prmp
+            } // no nbreg vs prm
+
+            * prm vs zip
+            if "`zip'"!="" {
+                local mdl2 "`set'ZIP"
+                local mdl2type "ZIP"
+                * bic
+                global bic1 = bic`mdl1'
+                global bic2 = bic`mdl2'
+                _count_bic_dif
+                local pref = $bicpref
+                local nopref = $bicnopref
+                di in g "`dash'"
+                di in y " " in g " vs " in y "`mdl2'" ///
+                    _col(`c1') in g "BIC=" in y `f103' bic`mdl2' ///
+                    _col(`c2') in g "dif=" in y `f103' $bicdif ///
+                    _col(`c3') in y "`mdl`pref'type'" ///
+                    _col(`c4') in y "`mdl`nopref'type'" ///
+                    _col(`c5') in y "$bicsup"
+                * aic
+                tempname aicd // 0.8.0
+                scalar `aicd' = aic`mdl1' - aic`mdl2'
+                local aicfav "`mdl2type'"
+                local aicnofav "`mdl1type'"
+                if aic`mdl1' < aic`mdl2' {
+                    local aicfav "`mdl1type'"
+                    local aicnofav "`mdl2type'"
+                }
+                di _col(`c1') in g "AIC=" in y `f103' aic`mdl2' ///
+                        _col(`c2') in g "dif=" in y `f103' `aicd' ///
+                        _col(`c3') in y "`aicfav'" ///
+                        _col(`c4') in y "`aicnofav'"
+                * vuong test
+                local vufav "`mdl1type'"
+                local vunofav "`mdl2type'"
+                if vu`mdl2'>0  {
+                    local vufav "`mdl2type'"
+                    local vunofav "`mdl1type'"
+                }
+                di _col(`c1') in g "Vuong=" in y `f83' vu`mdl2' ///
+                    _col(`c2') in g "prob=" in y `f93' vu`mdl2'p in g ///
+                    _col(`c3') in y "`vufav'" ///
+                    _col(`c4') in y "`vunofav'" ///
+                    _col(`c5') in y "p=" `f93l' vu`mdl2'p
+            } // no zip vs prm
+
+            * prm vs zinb
+            if "`zinb'"!="" {
+                local mdl2 "`set'ZINB"
+                local mdl2type "ZINB"
+                * bic
+                global bic1 = bic`mdl1'
+                global bic2 = bic`mdl2'
+                _count_bic_dif
+                local pref = $bicpref
+                local nopref = $bicnopref
+                di in g "`dash'"
+                di in y " " in g " vs " in y "`mdl2'" ///
+                    _col(`c1') in g "BIC=" in y `f103' bic`mdl2' ///
+                    _col(`c2') in g "dif=" in y `f103' $bicdif ///
+                    _col(`c3') in y "`mdl`pref'type'" ///
+                    _col(`c4') in y "`mdl`nopref'type'" ///
+                    _col(`c5') in y "$bicsup"
+                * aic
+                scalar `aicd' = aic`mdl1' - aic`mdl2'
+                local aicfav "`mdl2type'"
+                local aicnofav "`mdl1type'"
+
+                if aic`mdl1' < aic`mdl2' {
+                    local aicfav "`mdl1type'"
+                    local aicnofav "`mdl2type'"
+                }
+                di _col(`c1') in g "AIC=" in y `f103' aic`mdl2' ///
+                    _col(`c2') in g "dif=" in y `f103' `aicd' ///
+                    _col(`c3') in y "`aicfav'" ///
+                    _col(`c4') in y "`aicnofav'"
+            } // no zinb vs prm
+
+        } // if no prm
+
+        * base nbreg
+        if "`nbreg'"!="" {
+            local mdl1 "`set'NBRM"
+            local mdl1type "NBRM"
+            di in g "`dash'"
+            di in y "`mdl1'" ///
+                _col(`c1') in g "BIC=" in y `f103' bic`mdl1' ///
+                _col(`c2') in g "AIC=" in y `f103' aic`mdl1' ///
+                _col(`c3') in g "Prefer" ///
+                _col(`c4') in g "Over" ///
+                _col(`c5') in g "Evidence"
+
+            * nbreg vs zip
+            if "`zip'"!="" {
+                local mdl2 "`set'ZIP"
+                local mdl2type "ZIP"
+                * bic
+                global bic1 = bic`mdl1'
+                global bic2 = bic`mdl2'
+                _count_bic_dif
+                local pref = $bicpref
+                local nopref = $bicnopref
+                di in g "`dash'"
+                di in y " " in g " vs " in y "`mdl2'" ///
+                    _col(`c1') in g "BIC=" in y `f103' bic`mdl2' ///
+                    _col(`c2') in g "dif=" in y `f103' $bicdif ///
+                    _col(`c3') in y "`mdl`pref'type'" ///
+                    _col(`c4') in y "`mdl`nopref'type'" ///
+                    _col(`c5') in y "$bicsup"
+                * aic
+                scalar `aicd' = aic`mdl1' - aic`mdl2'
+                local aicfav "`mdl2type'"
+                local aicnofav "`mdl1type'"
+
+                if aic`mdl1' < aic`mdl2' {
+                    local aicfav "`mdl1type'"
+                    local aicnofav "`mdl2type'"
+                }
+                di _col(`c1') in g "AIC=" in y `f103' aic`mdl2' ///
+                    _col(`c2') in g "dif=" in y `f103' `aicd' ///
+                    _col(`c3') in y "`aicfav'" ///
+                    _col(`c4') in y "`aicnofav'"
+             } // no zip vs nbreg
+
+            * nbreg vs zinb
+            if "`zinb'"!="" {
+                local mdl2 "`set'ZINB"
+                local mdl2type "ZINB"
+                * bic
+                global bic1 = bic`mdl1'
+                global bic2 = bic`mdl2'
+                _count_bic_dif
+                local pref = $bicpref
+                local nopref = $bicnopref
+                di in g "`dash'"
+                di in y " " in g " vs " in y "`mdl2'" ///
+                    _col(`c1') in g "BIC=" in y `f103' bic`mdl2' ///
+                    _col(`c2') in g "dif=" in y `f103' $bicdif ///
+                    _col(`c3') in y "`mdl`pref'type'" ///
+                    _col(`c4') in y "`mdl`nopref'type'" ///
+                    _col(`c5') in y "$bicsup"
+                * aic
+                scalar `aicd' = aic`mdl1' - aic`mdl2'
+                local aicfav "`mdl2type'"
+                local aicnofav "`mdl1type'"
+                if aic`mdl1' < aic`mdl2' {
+                    local aicfav "`mdl1type'"
+                    local aicnofav "`mdl2type'"
+                }
+                di _col(`c1') in g "AIC=" in y `f103' aic`mdl2' ///
+                    _col(`c2') in g "dif=" in y `f103' `aicd' ///
+                    _col(`c3') in y "`aicfav'" ///
+                    _col(`c4') in y "`aicnofav'"
+                * vuong test
+                local vufav "`mdl1type'"
+                local vunofav "`mdl2type'"
+                if vu`mdl2'>0  {
+                    local vufav "`mdl2type'"
+                    local vunofav "`mdl1type'"
+                }
+                di _col(`c1') in g "Vuong=" in y `f83' vu`mdl2' ///
+                    _col(`c2') in g "prob=" in y `f93' vu`mdl2'p in g ///
+                    _col(`c3') in y "`vufav'" ///
+                    _col(`c4') in y "`vunofav'" ///
+                    _col(`c5') in y "p=" `f93l' vu`mdl2'p
+
+            } // no zinb vs nbreg
+
+        } // if no nbreg
+
+        if "`zip'"!="" {
+
+            local mdl1 "`set'ZIP"
+            local mdl1type "ZIP"
+            di in g "`dash'"
+            di in y "`mdl1'" ///
+                _col(`c1') in g "BIC=" in y `f103' bic`mdl1' ///
+                _col(`c2') in g "AIC=" in y `f103' aic`mdl1' ///
+                _col(`c3') in g "Prefer" ///
+                _col(`c4') in g "Over" ///
+                _col(`c5') in g "Evidence"
+
+            * zip vs zinb
+            if "`zinb'"!="" {
+                local mdl2 "`set'ZINB"
+                local mdl2type "ZINB"
+                * bic
+                global bic1 = bic`mdl1'
+                global bic2 = bic`mdl2'
+                _count_bic_dif
+                local pref = $bicpref
+                local nopref = $bicnopref
+                di in g "`dash'"
+                di in y " " in g " vs " in y "`mdl2'" ///
+                    _col(`c1') in g "BIC=" in y `f103' bic`mdl2' ///
+                    _col(`c2') in g "dif=" in y `f103' $bicdif ///
+                    _col(`c3') in y "`mdl`pref'type'" ///
+                    _col(`c4') in y "`mdl`nopref'type'" ///
+                    _col(`c5') in y "$bicsup"
+                * aic
+                scalar `aicd' = aic`mdl1' - aic`mdl2'
+                local aicfav "`mdl2type'"
+                local aicnofav "`mdl1type'"
+                if aic`mdl1' < aic`mdl2' {
+                    local aicfav "`mdl1type'"
+                    local aicnofav "`mdl2type'"
+                }
+                di _col(`c1') in g "AIC=" in y `f103' aic`mdl2' ///
+                    _col(`c2') in g "dif=" in y `f103' `aicd' ///
+                    _col(`c3') in y "`aicfav'" ///
+                    _col(`c4') in y "`aicnofav'"
+                * lr test
+                local lrfav "`mdl1type'"
+                local lrnofav "`mdl2type'"
+                if lrnb_prmp < .05 {
+                    local lrfav "`mdl2type'"
+                    local lrnofav "`mdl1type'"
+                }
+                di _col(`c1') in g "LRX2=" in y `f93' lrzip_zinb ///
+                    _col(`c2') in g "prob=" in y `f93' lrzip_zinbp in g ///
+                    _col(`c3') in y "`lrfav'" ///
+                    _col(`c4') in y "`lrnofav'" ///
+                    _col(`c5') in y "p=" `f93l' lrnb_prmp
+                di in g "`dash'"
+
+            } // no zinb vs zip
+
+        } // no zip
+
+}  // no fit
+
+end
+
+// compute strength of bic difference?
+
+capture program drop _count_bic_dif
+program define _count_bic_dif
+
+    * compute bin diff from model 1 and model 2
+    global bicdif = $bic1 - $bic2
+    tempname bicdabs // 0.8.0
+    scalar `bicdabs' = abs($bicdif)
+
+    * evaluate support based on bic difference
+    if `bicdabs'~=. {
+        global bicsup "Very strong"
+        if `bicdabs'<= .0000000001 {
+            global bicsup "no"
+            }
+        else if `bicdabs' <=2      {
+            global bicsup "Weak"
+        }
+        else if `bicdabs' <=6      {
+            global bicsup "Positive"
+        }
+        else if `bicdabs' <=10     {
+            global bicsup "Strong"
+        }
+        global bicpref = 2
+        global bicnopref = 1
+        if $bicdif < 0 {
+            global bicpref = 1
+            global bicnopref = 2
+        }
+        if `bicdabs'< .0000000001 & `bicdabs'>-.0000000001 {
+            global bicpref = 0
+        }
+
+    }
+end
+
+// ESTIMATE MODELS AND STORE RESULTS
+
+capture program drop _count_estimate
+program define _count_estimate, rclass
+
+    syntax varlist [if] [in] [,     ///
+      inflate(varlist) ///
+      MAXcount(integer 9) Generate(string) replace ///
+      Prm Nbreg ZIP ZINb NOConstant ///
+      NOIsily ]
+
+// estimate models & create globals with stats
+
+    local set "`generate'"
+    tempname n
+
+    local noise ""
+    if "`noisily'"=="noisily" {
+        local noise "noisily"
+    }
+
+// prm
+
+    if "`prm'"!="" {
+        qui {
+            local modelnm "PRM"
+            local fullnm "`set'`modelnm'"
+            `noise' poisson `varlist' `if' `in', `noconstant'
+            estimates store `fullnm'
+            scalar ll`fullnm' = e(ll) // log lik
+            fitstat, bic
+            scalar bicp`fullnm' = r(bic_p) // bic'
+            return scalar bicp`fullnm' = r(bic_p) // 0.8.0
+            scalar aic`fullnm' = r(aic) // aic
+            scalar x2`fullnm' = r(lrx2) // lrx2 all b=0
+            scalar x2p`fullnm' = r(lrx2_p)
+            scalar bic`fullnm' =  r(bic) // bic
+            if "`replace'"=="replace" {
+                capture drop `fullnm'rate
+                capture drop `fullnm'prgt
+                capture drop `fullnm'val
+                capture drop `fullnm'obeq
+                capture drop `fullnm'preq
+                capture drop `fullnm'prle
+                capture drop `fullnm'oble
+                capture drop `fullnm'absdif
+                capture drop `fullnm'dif
+                capture drop `fullnm'pearson
+                local i = 0
+                while `i'<=`maxcount' {
+                    capture drop `fullnm'pr`i'
+                    capture drop `fullnm'cu`i'
+                    local i = `i' + 1
+                }
+            }
+            prcounts `fullnm', plot max(`maxcount') // predicted counts
+            label var `fullnm'preq "`modelnm' predicted" // predicted Pr(y)
+            gen `fullnm'dif = `fullnm'obeq - `fullnm'preq // obs - predicted
+            label var `fullnm'dif  "`modelnm' obs - pred"
+            * 2004-10-29 add CT 5.34
+            scalar `n' = e(N) // sample size
+            gen `fullnm'pearson = ///
+                (`n' * `fullnm'dif * `fullnm'dif) / `fullnm'preq
+            label var `fullnm'pearson "`modelnm' contribution to Pearson X2"
+            sum `fullnm'pearson
+        } // qui
+    }
+
+// nbreg
+
+    if "`nbreg'"!="" {
+        qui {
+            local modelnm "NBRM"
+            local fullnm "`set'`modelnm'"
+            `noise' nbreg `varlist' `if' `in', `noconstant'
+            estimates store `fullnm'
+            scalar ll`fullnm' = e(ll) // log lik
+
+            scalar lrnb_prm = e(chi2_c) // lrx2 of nb vs prm
+            scalar lrnb_prmp = chiprob(1, e(chi2_c))*0.5
+
+            fitstat, bic
+            scalar bicp`fullnm' = r(bic_p) // bic'
+            scalar aic`fullnm' = r(aic) // aic
+            scalar x2`fullnm' = r(lrx2) // lrx2 all b=0
+            scalar x2p`fullnm' = r(lrx2_p)
+            scalar bic`fullnm' =  r(bic) // bic
+
+            if "`replace'"=="replace" {
+                capture drop `fullnm'rate
+                capture drop `fullnm'prgt
+                capture drop `fullnm'val
+                capture drop `fullnm'obeq
+                capture drop `fullnm'preq
+                capture drop `fullnm'prle
+                capture drop `fullnm'oble
+                capture drop `fullnm'dif
+                capture drop `fullnm'absdif
+                capture drop `fullnm'pearson
+                local i = 0
+                while `i'<=`maxcount' {
+                    capture drop `fullnm'pr`i'
+                    capture drop `fullnm'cu`i'
+                    local i = `i' + 1
+                }
+            }
+
+            prcounts `fullnm', plot max(`maxcount') // predicted counts
+                label var `fullnm'preq "`modelnm' predicted"
+            gen `fullnm'dif = `fullnm'obeq - `fullnm'preq
+                label var `fullnm'dif  "`modelnm' obs - pred"
+            * 2004-10-29 add CT 5.34
+            scalar `n' = e(N) // sample size
+            gen `fullnm'pearson = ///
+                (`n' * `fullnm'dif * `fullnm'dif) / `fullnm'preq
+            label var `fullnm'pearson "`modelnm' contribution to Pearson X2"
+            sum `fullnm'pearson
+        } // qui
+    }
+
+// zip
+
+    if "`zip'"!="" {
+        qui {
+            local modelnm "ZIP"
+            local fullnm "`set'`modelnm'"
+            `noise' zip `varlist' `if' `in', ///
+                inf(`inflate') vuong `noconstant'
+            estimates store `fullnm'
+            scalar vu`fullnm' = e(vuong) // vuong vs prm
+            scalar vu`fullnm'p = 1-norm(abs(e(vuong)))
+            scalar ll`fullnm' = e(ll) // log lik
+            fitstat, bic
+            scalar bicp`fullnm' = r(bic_p) // bic'
+            scalar aic`fullnm' = r(aic) // aic
+            scalar x2`fullnm' = r(lrx2) // lrx2 all b=0
+            scalar x2p`fullnm' = r(lrx2_p)
+            scalar bic`fullnm' =  r(bic) // bic
+            if "`replace'"=="replace" {
+                capture drop `fullnm'rate
+                capture drop `fullnm'prgt
+                capture drop `fullnm'val
+                capture drop `fullnm'obeq
+                capture drop `fullnm'preq
+                capture drop `fullnm'prle
+                capture drop `fullnm'oble
+                capture drop `fullnm'all0
+                capture drop `fullnm'dif
+                capture drop `fullnm'absdif
+                capture drop `fullnm'pearson
+                local i = 0
+                while `i'<=`maxcount' {
+                    capture drop `fullnm'pr`i'
+                    capture drop `fullnm'cu`i'
+                    local i = `i' + 1
+                }
+            }
+
+            prcounts `fullnm', plot max(`maxcount') // predicted counts
+            label var `fullnm'preq "`modelnm' predicted"
+            gen `fullnm'dif = `fullnm'obeq - `fullnm'preq
+            label var `fullnm'dif  "`modelnm' obs - pred"
+            * 2004-10-29 add CT 5.34
+            scalar `n' = e(N) // sample size
+            gen `fullnm'pearson = ///
+                (`n' * `fullnm'dif * `fullnm'dif) / `fullnm'preq
+            label var `fullnm'pearson "`modelnm' contribution to Pearson X2"
+            qui sum `fullnm'pearson
+        } // qui
+    }
+
+// zinb
+
+    if "`zinb'"!="" {
+        qui {
+            local modelnm "ZINB"
+            local fullnm "`set'`modelnm'"
+            `noise' zinb `varlist'  `if' `in', ///
+                inf(`inflate') vuong zip `noconstant'
+            estimates store `fullnm'
+            scalar vu`fullnm' = e(vuong) // vuong vs nbreg
+            scalar vu`fullnm'p = 1-norm(abs(e(vuong)))
+            scalar ll`fullnm' = e(ll) // loglik
+            scalar lrzip_zinb = e(chi2_cp) // lrx2 zinb vs zip
+            scalar lrzip_zinbp = chiprob(1, e(chi2_cp))*0.5
+            fitstat, bic
+            scalar bicp`fullnm' = r(bic_p) // bic'
+            scalar aic`fullnm' = r(aic) // aic
+            scalar x2`fullnm' = r(lrx2) // lrx2 all b=0
+            scalar x2p`fullnm' = r(lrx2_p)
+            scalar bic`fullnm' =  r(bic) // bic
+            if "`replace'"=="replace" {
+                capture drop `fullnm'rate
+                capture drop `fullnm'prgt
+                capture drop `fullnm'val
+                capture drop `fullnm'obeq
+                capture drop `fullnm'preq
+                capture drop `fullnm'prle
+                capture drop `fullnm'oble
+                capture drop `fullnm'absdif
+                capture drop `fullnm'dif
+                capture drop `fullnm'all0
+                capture drop `fullnm'pearson
+                local i = 0
+                while `i'<=`maxcount' {
+                    capture drop `fullnm'pr`i'
+                    capture drop `fullnm'cu`i'
+                    local i = `i' + 1
+                }
+            }
+
+            prcounts `fullnm', plot max(`maxcount') // predicted counts
+            label var `fullnm'preq "`modelnm' predicted"
+            gen `fullnm'dif = `fullnm'obeq - `fullnm'preq
+            label var `fullnm'dif  "`modelnm' obs - pred"
+            * 2004-10-29 add CT 5.34
+            scalar `n' = e(N) // sample size
+            gen `fullnm'pearson = ///
+                (`n' * `fullnm'dif * `fullnm'dif) / `fullnm'preq
+            label var `fullnm'pearson "`modelnm' contribution to Pearson X2"
+            qui sum `fullnm'pearson
+        } // qui
+    }
+
+end // _count_estimate
+
+exit
+* version 0.8.0 fix pr bug
+* version 0.2.1 13Apr2005 add replace; trap weights
+* version 0.2.0 27Feb2005 first documented version
diff --git a/Modules/ado/plus/c/countfit.hlp b/Modules/ado/plus/c/countfit.hlp
new file mode 100644
index 0000000..4fac473
--- /dev/null
+++ b/Modules/ado/plus/c/countfit.hlp
@@ -0,0 +1,86 @@
+.-
+help for ^countfit^ - 03Nov2005
+.-
+
+Compare fit of alternive count models
+-------------------------------------
+
+    ^countfit^ varlist [if] [in]^,^ [^inf^late^(^varlist2^)^ ^noc^onstant ^p^rm ^n^breg
+        ^zip^ ^zin^b ^g^enerate^(^prefix^)^ ^replace^ ^note(^string^)^
+        ^graph^export^(^filename[^, replace^]^)^ ^nog^raph ^nod^ifferences ^noprt^able
+        ^noe^stimates ^nof^it ^nodash^ ^max^count(#) ^noi^sily]
+
+Description
+-----------
+
+^countfit^ compares the fit of the Poissin, negative binomial, zero-inflated
+Poisson and zero-inflated negative binomial models, generateing a table of
+estimates, a table of differences between observed and average estimated
+probabilities for each count, a graph of these differences, and various tests
+and measures used to compare the fit of count models.
+
+Specifying the model
+--------------------
+Immediately afer the command name ^countfit^ you specify the dependent and
+independent variables as you would with ^poisson^ or the other models. For
+zero-inflated models, the ^inflate^ option is used in the same was as in the
+^zip^ and ^zinb^ commands. ^noconstant^ can be used to exclude the constant
+term.
+
+Options to select the models to fit
+-----------------------------------
+By default, ^poisson^, ^nbreg^, ^zip^ and ^zinb^ are estimated. If you
+only want some of these models, specify the modesl you want with:
+
+    ^prm^ - include ^poisson^
+    ^nbreg^ - include ^nbreg^
+    ^zip^ - include ^poisson^
+    ^zinb^ - include ^poisson^
+
+Options to label results
+------------------------
+^generate()^ is up to five letters to name the variables that are created
+     and to label the models in the output. This name is placed in front
+     of the type of model (e.g., namePRM). This is optional but will help
+     keep track of results from multiple specifications of models.
+
+^replace^ will replace variables created with the ^generate^ option if they
+    already exist.
+
+^note()^ is a label added to the graph that is saved.
+
+^graphexport()^ contains options to be sent to the ^graph export^ command to
+    export the graph that is create. For example, ^graph(mdl.emf, replace)^
+    would save the file mdl.emf and replace it if it exists. If this option
+    is not included, the graph is not saved.
+
+Options controlling what is printed
+-----------------------------------
+^noisily^ shows the output from the estimation commands called by ^countfit^.
+^nograph^ suppress graph of differences from observed counts.
+^nodifferences^ suppress table of differences from observed counts.
+^noprtable^ suppresses table of predictions for each model.
+^noestimates^ suppress table of estimated coefficients.
+^nofit^ suppress table of fit statistics and test of fit
+^nodash^ suppress dashed lines between measures of fit
+^maxcount()^ number of counts to evaluate.
+^noisily^ includes output from Stata estimation commands; without this option
+    the results are only shown in the ^estimates table^ output.
+
+Notes
+-----
+
+^countfit^ is based on the results from the Stata models described above,
+the predictions computed by ^prcounts^, and the fit measures computed by
+^fitstat^.
+
+Examples
+--------
+
+    ^. use couart2^
+    ^. countfit art fem mar kid5 phd ment, inf(ment fem) nbreg zinb nograph^
+
+.-
+Author: J. Scott Long and Jeremy Freese
+        www.indiana.edu/~jslsoc/spost.htm
+        spostsup@@indiana.edu
diff --git a/Modules/ado/plus/c/cseplist.ado b/Modules/ado/plus/c/cseplist.ado
new file mode 100644
index 0000000..6a59800
--- /dev/null
+++ b/Modules/ado/plus/c/cseplist.ado
@@ -0,0 +1,29 @@
+program def cseplist, rclass
+*! NJC 1.0.0 31 August 2000 
+	version 6.0 
+	gettoken list 0 : 0, parse(",")
+	if "`list'" == "" | "`list'" == "," { 
+		di in r "nothing in list" 
+		exit 198 
+	}
+	syntax , [ Global(str) Noisily ]  
+	
+	if length("`global'") > 8 { 
+		di in r "global name must be <=8 characters" 
+		exit 198 
+	} 	
+
+	tokenize `list' 
+	local n : word count `list' 
+	local i = 1 
+	while `i' < `n' { 
+		local newlist "`newlist'``i'',"
+		local i = `i' + 1 
+	}
+	local newlist "`newlist'``n''" 
+
+	if "`noisily'" != "" { di "`newlist'" } 
+	if "`global'" != "" { global `global' "`newlist'" } 
+	return local list `newlist'
+end 	
+			
diff --git a/Modules/ado/plus/c/cseplist.hlp b/Modules/ado/plus/c/cseplist.hlp
new file mode 100644
index 0000000..eacf780
--- /dev/null
+++ b/Modules/ado/plus/c/cseplist.hlp
@@ -0,0 +1,2 @@
+.h listutil
+
diff --git a/Modules/ado/plus/c/cvarlist.ado b/Modules/ado/plus/c/cvarlist.ado
new file mode 100644
index 0000000..986c1cb
--- /dev/null
+++ b/Modules/ado/plus/c/cvarlist.ado
@@ -0,0 +1,54 @@
+program def cvarlist, rclass
+*! NJC 1.0.0 18 August 2000 
+	version 6.0 
+	gettoken list 0 : 0, parse(",")
+	if "`list'" == "" | "`list'" == "," { 
+		di in r "nothing in list" 
+		exit 198 
+	}
+	syntax , [ new NUmeric String Noisily Global(str)] 
+
+	local nopts : word count `new' `numeric' `string' 
+	if `nopts' > 1 { 
+		di in r "use just one of options new, numeric, string"
+		exit 198 
+	} 
+	
+	if "`global'" != "" { 
+		tokenize `global' 
+		args global1 global2 global3 
+		if "`global3'" != "" { 
+			di in r "global( ) must contain at most 2 names"
+			exit 198 
+		} 
+		if (length("`global1'") > 8) | (length("`global2'") > 8)  { 
+			di in r "global name must be <=8 characters" 
+			exit 198 
+		} 	
+	} 	
+
+	tokenize `list'
+	local nwords : word count `list' 
+	local i = 1 
+	while `i' <= `nwords' { 	
+		capture confirm `new' `numeric' `string' variable ``i'' 	
+		if _rc == 0 { local newlist "`newlist'``i'' " } 
+		else local badlist "`badlist'``i'' " 
+		local i = `i' + 1 
+	} 
+	
+	if "`noisily'" != "" { 
+		if "`newlist'" != "" { 
+			di in g "list 1: " in y "`newlist'" 
+		} 
+		if "`badlist'" != "" { 
+			di in g "list 2: " in y "`badlist'" 
+		}
+	}
+	
+	if "`global1'" != "" { global `global1' "`newlist'" } 
+	if "`global2'" != "" { global `global2' "`badlist'" } 
+	return local list1 `newlist'
+	return local list2 `badlist' 
+end 	
+			
diff --git a/Modules/ado/plus/c/cvarlist.hlp b/Modules/ado/plus/c/cvarlist.hlp
new file mode 100644
index 0000000..eacf780
--- /dev/null
+++ b/Modules/ado/plus/c/cvarlist.hlp
@@ -0,0 +1,2 @@
+.h listutil
+
diff --git a/Modules/ado/plus/d/dellist.ado b/Modules/ado/plus/d/dellist.ado
new file mode 100644
index 0000000..96af1dd
--- /dev/null
+++ b/Modules/ado/plus/d/dellist.ado
@@ -0,0 +1,119 @@
+program def dellist, rclass
+*! NJC 1.5.0 14 December 2000 
+* NJC 1.4.0 6 Sept 2000 
+* NJC 1.3.0 6 June 2000 
+* NJC 1.2.0 31 Jan 2000 
+* NJC 1.1.0 22 Dec 1999 
+* NJC 1.0.0 22 Sept 1999 	
+	version 6.0 
+	gettoken list 0 : 0, parse(",")
+	if "`list'" == "" | "`list'" == "," { 
+		di in r "nothing in list" 
+		exit 198 
+	}
+	
+	local nlist : word count `list' 
+
+	syntax , [ Delete(str) Pos(numlist sort int >=-`nlist' <=`nlist') /* 
+	*/ Exact All Global(str) Noisily ]
+
+	local nopts = ("`delete'" != "") + ("`pos'" != "") 
+	if `nopts' != 1 { 
+		di in r "must specify one of delete( ) and pos( )" 
+		exit 198 
+	} 
+
+	if length("`global'") > 8 { 
+		di in r "global name must be <=8 characters" 
+		exit 198 
+	} 	
+	
+	if "`exact'" != "" & "`all'" != ""  { 
+		di in r "all option not allowed with exact option" 
+		exit 198 
+	} 
+	
+	tokenize `list'
+
+	if "`delete'" != "" { 
+		local i = 1 
+		while `i' <= `nlist' { 	
+			local len = length("``i''") 
+			if `len' > 80 { 
+				di in r "cannot handle word length > 80"
+				exit 498 
+			}
+			local i = `i' + 1 
+		}	
+	
+		tknz `delete', s(d) 
+		local nd : word count `delete' 
+
+		if "`exact'" != "" { 
+			while "`1'" != "" { 
+				local i = 1 
+				local OK = 0 
+				while `i' <= `nd' & !`OK' { 
+					local OK = "`1'" == "`d`i''" 
+					local i = `i' + 1 
+				} 	
+				if !`OK' { local newlist "`newlist'`1' " } 
+				mac shift
+			}
+		} 
+		else { 
+			while "`1'" != "" {
+				local i = 1 
+				local OK = 0 
+				while `i' <= `nd' { 
+					local thisOK = /* 
+					*/ index("`1'", "`d`i''") > 0 
+					local OK = `OK' + `thisOK'
+					local i = `i' + 1 
+				} 	
+				if "`all'" != "" { local OK = `OK' == `nd' } 
+	 			if !`OK' { local newlist "`newlist'`1' " }
+				mac shift
+			}
+		} 	
+	}	
+	else { 
+		local np1 = `nlist' + 1 
+		tknz `pos' `np1', s(p)  
+		local np : word count `pos'
+
+		* negative indexes to positive 
+		local i = 1 
+		while `p`i'' < 0 { 
+			local p`i' = `nlist' + 1 + `p`i'' 
+			local i = `i' + 1 
+		} 	
+
+		local i = 1 
+		local j = 1 
+		while `i' <= `nlist' { 
+			if `i' == `p`j'' { local j = `j' + 1 } 
+			else local newlist "`newlist'``i'' "  
+			local i = `i' + 1 
+		} 	
+	} 	
+		
+	if "`noisily'" != "" { di "`newlist'" } 
+	if "`global'" != "" { global `global' "`newlist'" } 
+	return local list `newlist'
+end
+
+program def tknz, rclass 
+* NJC 1.1.0 2 June 2000 
+	version 6.0 
+	gettoken list 0 : 0, parse(",") 
+	syntax , Stub(str) [ * ] 
+	tokenize `"`list'"' , `options'  
+		
+	local i = 1 	
+	while "``i''" != "" { 
+		c_local `stub'`i' `"``i''"'  
+		local i = `i' + 1 
+	} 
+end 	
+			
diff --git a/Modules/ado/plus/d/dellist.hlp b/Modules/ado/plus/d/dellist.hlp
new file mode 100644
index 0000000..eacf780
--- /dev/null
+++ b/Modules/ado/plus/d/dellist.hlp
@@ -0,0 +1,2 @@
+.h listutil
+
diff --git a/Modules/ado/plus/d/delta.ado b/Modules/ado/plus/d/delta.ado
new file mode 100644
index 0000000..5f431bf
--- /dev/null
+++ b/Modules/ado/plus/d/delta.ado
@@ -0,0 +1,108 @@
+*! Delta version 1.5 - 5 March 2008
+*! Jean-Benoit Hardouin
+************************************************************************************************************
+* DELTA: delta coefficient
+* Version 1.5: March 5, 2008
+*
+* Historic
+* Version 1 (2007-05-21): Jean-Benoit Hardouin
+* Version 1.1 (2007-05-22): Jean-Benoit Hardouin /* if in and possibility to use the score*/
+* Version 1.2 (2007-05-22): Jean-Benoit Hardouin /*bug when a score is missing*/
+* Version 1.3 (2007-06-16): Jean-Benoit Hardouin /*change in the options*/
+* Version 1.4 (2007-07-03): Jean-Benoit Hardouin /*correct a bug in the options*/
+* Version 1.5 (2008-03-05): Jean-Benoit Hardouin /*correct a bug in the ci option*/
+*
+* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France
+* jean-benoit.hardouin@univ-nantes.fr
+*
+* News about this program : http://www.anaqol.org
+* FreeIRT Project : http://www.freeirt.org
+*
+* Copyright 2007-2008 Jean-Benoit Hardouin
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+************************************************************************************************************
+
+program define delta , rclass
+version 7.0
+syntax varlist(min=1 numeric) [if] [in] [,ci(integer 0) noDots  MINscore(int 0) MAXscore(int 0)]
+
+preserve
+tempfile deltafile
+qui save `deltafile'
+if "`if'"!=""|"`in'"!="" {
+   qui keep `if' `in'
+}
+
+local nbitems:word count `varlist'
+tokenize `varlist'
+
+local scoremin=`minscore'
+local scoremax=`maxscore'
+
+
+
+tempvar score
+if `nbitems'==1&`scoremax'==0 {
+   di in red "If you indicate only the score variable, you must define the {cmd:scoremax} option"
+   error 198
+}
+else if `nbitems'==1&`scoremax'!=0 {
+   qui gen `score'=`varlist'
+}
+else {
+   qui genscore `varlist',score(`score')
+}
+qui drop if `score'==.
+qui count
+local nbind=r(N)
+
+if `scoremax'==0 {
+   qui su `score'
+   local scoremax=r(max)
+}
+
+tempname error
+gen `error'=`score'<`scoremin'|`score'>`scoremax'
+qui count if `error'==1
+local err=r(N)
+if `err'!=0 {
+   di in red "`err' individuals has(have) a score inferior to `scoremin' or superior to `scoremax'"
+   error 198
+}
+
+local sumsqscore=0
+forvalues i=`scoremin'/`scoremax' {
+   qui count if `score'==`i'
+   local score`i'=r(N)
+   local sumsqscore=`sumsqscore'+`score`i''^2
+}
+local delta=(1+`scoremax')*(`nbind'^2-`sumsqscore')/(`nbind'^2*`scoremax')
+
+di in green "Range of the scores : " in ye `scoremin' in gr "/" in ye `scoremax'
+di in green "Number of used individuals : " in ye `nbind'
+
+if `ci'!=0 {
+   bootstrap delta=r(delta), reps(`ci') nowarn noheader nolegend `dots': delta `varlist' ,minscore(`scoremin') maxscore(`scoremax')
+}
+else {
+   display in green "Delta=  " in yellow %8.6f `delta'
+}
+return scalar delta=`delta'
+qui use `deltafile',clear
+restore,not
+
+end
diff --git a/Modules/ado/plus/d/delta.hlp b/Modules/ado/plus/d/delta.hlp
new file mode 100644
index 0000000..511bcab
--- /dev/null
+++ b/Modules/ado/plus/d/delta.hlp
@@ -0,0 +1,61 @@
+{smcl}
+{* 16may2007}{...}
+{hline}
+help for {hi:delta}{right:Jean-Benoit Hardouin}
+{hline}
+
+{title:Syntax}
+
+{p 8 14 2}{cmd:delta} {it:varlist} [{cmd:if} {it:exp}] [{cmd:in} {it:range}] [, {cmdab:ci}({it:#}) {cmdab:nod:ots} {cmdab:min:score}({it:#}) {cmdab:max:score}({it:#})]
+
+{title:Description}
+
+{p 4 8 2}{cmd:delta} computes the generalized delta index of scale  discrimination developed by Hankins (2007) based on the original work  of Ferguson (1949). This index measures the scale's ability to  distinguish between individuals. 
+A value of 1 indicates that the test  has maximal discrimination (all possible scores occur with the same  frequency) and a value of 0 means that the test has minimal  discrimination (all the respondents have the same score). 
+A value of  0.9 results from a set of scores that is normally distributed. A  value of 1 is observed if the scores follow a uniform distribution. Individuals with a missing score are omitted.
+
+{title:Options}
+
+{p 4 8 2}If {it:varlist} is composed of only one variable, the {cmd:delta} module considers that this variable is the score of the individuals.
+
+{p 4 8 2}{cmd:ci}({it:#}) estimates the confidence interval by  boostrap. {it:#} is the number of replications to be performed. By  default, no confidence interval is calculated.
+
+{p 4 8 2}{cmd:nodots} avoids displaying a dot for each replication (only with  {cmd:ci}).
+
+{p 4 8 2}{cmd:minscore}({it:#}) defines the minimal value of the score. By default, this value is fixed to 0.
+
+{p 4 8 2}{cmd:maxscore}({it:#}) defines the maximal value of the score. By default, the maximal observed score is used.
+
+{title:Output}
+
+{p 4 8 2}{cmd:r(delta)}: Observed value of the delta index.
+
+{title:Examples}
+
+{p 4 8 2}{cmd: . delta itemA*}
+
+{p 4 8 2}{cmd: . delta itemA*, ci(500) dots}
+
+{p 4 8 2}{cmd: . delta score, scoremax(8)}
+
+{title: References}
+
+{p 4 8 2}Ferguson G. A. (1949) On the theory of test discrimination.  {it:Psychometrika}, 14: 61-68.
+
+{p 4 8 2}Hankins M. (2007) Questionnaire discrimination: (re)- introducting coefficient delta. {it:BMC Medical Research  Methodology}, 7: 19.
+
+{title:Author}
+
+{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
+{p 4 8 2}Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences{p_end}
+{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end}
+{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end}
+{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end}
+{p 4 8 2}Email:
+{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end}
+{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol}
+and {browse "http://www.freeirt.org":FreeIRT}
+
+{title:Also see}
+
+{p 4 13 2}Online: help for {help alpha} and {help loevH} if installed.{p_end}
diff --git a/Modules/ado/plus/d/difflist.ado b/Modules/ado/plus/d/difflist.ado
new file mode 100644
index 0000000..b3f98e9
--- /dev/null
+++ b/Modules/ado/plus/d/difflist.ado
@@ -0,0 +1,90 @@
+program def difflist, rclass
+*! NJC 1.4.0 6 June 2000 
+* NJC 1.3.0 31 Jan 2000 
+* NJC 1.2.0 22 Dec 1999
+* NJC 1.1.0 21 Dec 1999 
+* NJC 1.0.0 14 Oct 1999 	
+	version 6.0 
+	gettoken lists 0 : 0, parse(",")
+	if "`lists'" == "" | "`lists'" == "," { /* no \ */ 
+		di in r "incorrect syntax: no separator" 
+		exit 198 
+	}
+	
+	tokenize "`lists'", parse("\") 
+	if "`4'" != "" { 
+		di in r "incorrect syntax: too much stuff" 
+		exit 198 
+	} 	
+	if "`1'" == "\" { /* list1 empty */ 
+		if "`2'" == "\" { 
+			di in r "incorrect syntax: one \ only" 
+			exit 198
+		}	
+		local list2 "`2'" /* might be empty */ 
+	} 
+	else if "`2'" == "\" { 
+		local list1 "`1'" 
+		local list2 "`3'" /* might be empty */ 
+	} 	
+	else { 
+		di in r "incorrect syntax: what to compare?" 
+		exit 198 
+	}
+	
+	syntax [ , Global(str) Noisily ]
+	
+	if length("`global'") > 8 { 
+		di in r "global name must be <=8 characters" 
+		exit 198 
+	} 	
+
+	* remove duplicates from `list1' 
+
+	tokenize `list1' 
+	local list1 "`1'" 
+	mac shift 
+	 
+	while "`1'" != "" { 
+		local n1 : word count `list1' 
+		local i = 1 
+		local putin = 1 
+		while `i' <= `n1' { 
+			local word : word `i' of `list1' 
+			if "`word'" == "`1'" { 
+				local putin = 0 
+				local i = `n1' 
+			} 
+			local i = `i' + 1 
+		} 	
+		if `putin' { local list1 "`list1' `1'" } 
+		mac shift
+	}
+	
+	* what is in `list1' but not `list2'? 
+
+	local n1 : word count `list1' 
+	tokenize `list1'
+	local n2 : word count `list2' 
+
+	local i = 1 
+	while `i' <= `n1' { 
+		local j = 1 
+		local putin = 1 
+		while `j' <= `n2' { 
+			local word : word `j' of `list2' 
+			if "`word'" == "``i''" { 
+				local putin = 0 
+				local j = `n2' 
+			} 
+			local j = `j' + 1 
+		} 
+		if `putin' { local newlist "`newlist' ``i''" } 
+		local i = `i' + 1
+	}
+
+	if "`noisily'" != "" { di "`newlist'" } 
+	if "`global'" != "" { global `global' "`newlist'" } 
+	return local list `newlist' 
+end 	
+			 
diff --git a/Modules/ado/plus/d/difflist.hlp b/Modules/ado/plus/d/difflist.hlp
new file mode 100644
index 0000000..eacf780
--- /dev/null
+++ b/Modules/ado/plus/d/difflist.hlp
@@ -0,0 +1,2 @@
+.h listutil
+
diff --git a/Modules/ado/plus/d/discrim2.ado b/Modules/ado/plus/d/discrim2.ado
new file mode 100644
index 0000000..391a519
--- /dev/null
+++ b/Modules/ado/plus/d/discrim2.ado
@@ -0,0 +1,269 @@
+*! version 2.0 : Oct1995 : Joseph Hilbe
+*  Dichotomous Discriminate Anaylsis
+*  Based on version 1, written by Hilbe 12-7-91, published: STB-5 (Jan1992)
+
+program define discrim2
+  version 5.0
+    local varlist "req ex"
+    local options "Detail Graph Anova Predict Keep"
+    local in "opt"
+    local if "opt"
+    parse "`*'"
+    parse "`varlist'",parse(" ")
+    qui summ `1'
+
+    if (_result(6)<0 | _result(6)>1)  {
+       noi di in red "Error: Group variable must be 0/1"
+       exit
+    }
+    if "`keep'"=="" {
+      preserve
+    }
+    qui {
+    dropmiss `varlist'     
+    tempvar prob0 prob1 dummy D nvar obs obs1 obs0 c0 c1 prop D cntall
+     gen `cntall'=_n     
+     local group `1'
+     local y "`1'"
+     mac shift
+     qui count
+     gen `obs' = _result(1)
+     count if `group'==0
+     gen `obs0'= _result(1)
+     count if `group'==1
+     gen `obs1'= _result(1)
+     tempvar c0
+     gen `c0' =`obs1'/`obs'
+     gen `c1' = -(`obs0'/`obs')
+     gen `prob0' = `obs1'/`obs'
+     gen `dummy' = `c0' if `group'==0
+     replace `dummy' = `c1' if `group'==1
+     reg `dummy' `*', noheader
+     global nvar = _result(3)
+     cap drop `dummy' `c0' `c1'
+     global rsquare = _result(7)
+     global mahala=($rsquare/(1-$rsquare))*((`obs'*(`obs'-2))/(`obs0'*`obs1'))
+     gen `prop' = $rsquare/$mahala
+     gen `D' = sqrt($mahala)
+     
+*  Calc discriminant scores
+     local i = 1
+     while "``i''"!= ""  {
+        tempvar cof`i' dis`i'
+        gen `cof`i'' = _b[``i'']
+        gen `dis`i'' = `cof`i''/`prop'
+        local i = `i'+1
+     }
+
+*   Calc main values */
+    local j = 1
+    local i = 1
+    tempvar konst usdfk dscorep dscore dsFp dfun
+    gen `usdfk'=0
+    gen `konst' = 0
+    gen `dscorep'=0
+    gen `dscore'=0
+    gen `dsFp'=0
+    gen `dfun'=0
+    while "``i''"!="" {
+       tempvar mean`j' mn0`j' mn1`j' mndff`j' usdf`j'
+       summ ``i''
+       gen `mean`j'' = _result(3)
+       summ ``i'' if `group'==0
+       gen `mn0`j'' = _result(3)
+       summ ``i'' if `group'==1
+       gen `mn1`j'' = _result(3)
+       gen `mndff`j'' = `mn0`j'' + `mn1`j''
+       replace `konst' = `dis`i''*`mndff`j''+`konst'
+       gen `usdf`i''=`dis`i''/-`D'
+       replace `usdfk'=`usdf`j'' * `mean`j'' + `usdfk'
+       replace `dscorep'=`usdf`i''*``i''
+       replace `dscore'=`dscore'+`dscorep'
+       replace `dsFp'=`dis`i''*``i''
+       replace `dfun'=`dfun'+`dsFp'
+       local i = `i'+1
+       local j = `j'+1
+    }
+    replace `usdfk'=`usdfk'* -1 
+    replace `dscore'=`dscore'+`usdfk'
+    replace `konst'=`konst'*-.5
+    replace `dfun' = `dfun'+`konst'
+    local tsquare = $mahala*((`obs0'*`obs1')/`obs')
+    local F = `tsquare'*(`obs'-$nvar)/(($nvar-1)*(`obs'-2))
+    global cnt0 = -`D'*(`obs1'/`obs')
+    global cnt1 = `D'*(`obs0'/`obs')
+    noi di _n
+    noi di in gr _col(20) "Dichotomous Discriminant Analysis"
+    noi di "                                                 "
+    #delimit ;
+    noi di in gr "Observations    = " in ye `obs'
+       in gr _col(50) "Obs Group 0 = " in ye %9.0g `obs0';
+    noi di in gr "Indep variables = " in ye $nvar
+       in gr _col(50) "Obs Group 1 = " in ye %9.0g  `obs1';
+    noi di "                                                  ";
+    noi di in gr "Centroid 0  = " in ye %9.4f $cnt0
+       in gr _col(50) "R-square    = " in ye %9.4f $rsquare;
+    noi di in gr "Centroid 1  = " in ye %9.4f $cnt1
+       in gr _col(50) "Mahalanobis = " in ye %9.4f $mahala;
+    noi di in gr "Grand Cntd  = " in ye %9.4f 
+       ((`obs1'*$cnt0)+(`obs0'*$cnt1))/`obs';
+    noi di "                                                  ";        
+    #delimit cr
+    oneway `dscore' `group'
+    global eigen  = _result(2)/_result(4)
+    global ccor   = sqrt(_result(2)/(_result(2)+_result(4)))
+    global lambda = _result(4)/(_result(2)+_result(4))
+    global chisq  = log($lambda)* -((`obs'-($nvar+2)/2)-1)
+    #delimit ;
+    noi di in gr "Eigenvalue   = " in ye %9.4f $eigen
+       in gr _col(50) "Wilk's Lambda = " in ye %7.4f $lambda;
+    noi di in gr "Canon. Corr. = " in ye %9.4f $ccor
+       in gr _col(50) "Chi-square    = " in ye %7.4f $chisq;
+    noi di in gr "Eta Squared  = " in ye %9.4f $ccor^2
+       in gr _col(50) "Sign Chi2     = " in ye %7.4f chiprob($nvar,$chisq);
+    #delimit cr
+
+* DISPLAY COEFFICIENTS     
+     noi di _n(1)
+     noi di in gr _col(26) "Discrim Function" _col(46) "Unstandardized"
+     noi di in gr _col(11) /*  
+       */ "Variable" _col(28) "Coefficients" _col(48) "Coefficients"
+     noi di in gr _col(11) _dup(49) "-"
+     local i=1
+     while "``i''"!=""  {
+     noi di in gr _col(11) "``i''" in ye _col(28) %9.4f `dis`i'' /*  
+       */ _col(51) %9.4f `usdf`i''
+     local i = `i'+1
+     }
+     noi di in gr _col(11) "constant" in ye _col(28) %9.4f `konst' /* 
+       */ _col(51) %9.4f `usdfk' 
+
+     tempvar lprob grpred cell
+     gen `lprob'    = 1/(1+exp(`dfun'))
+     gen `grpred'     = 1 if `lprob'>=0.5
+     replace `grpred' = 0 if `lprob'<0.5
+     gen `cell' = 1
+     summ `cell' if `group'==0 & `lprob'<0.5
+     local aa=_result(2)
+     summ `cell' if `group'==0 & `lprob'>=0.5
+     local bb=_result(2)
+     summ `cell' if `group'==1 & `lprob'<0.5
+     local cc=_result(2)
+     summ `cell' if `group'==1 & `lprob'>=0.5
+     local dd=_result(2)
+     local tot = `aa'+`bb'+`cc'+`dd'
+
+* CONFUSION MATRIX AND RELATED STATS OPTION
+if "`predict'" !=""  {
+    noi di _n "                                                     "
+    noi di in gr _col(25) "----- Predicted -----"
+    noi di in gr _col(13) "Actual   |  Group 0         Group 1 |   Total"
+    noi di in gr _col(13) "---------+" _dup(26) "-" "+--------"
+    noi di in gr _col(13) "Group 0  |" in ye _col(26) %6.0g `aa' /*
+     */ _col(40) %6.0g `bb' in gr _col(49) "|" in ye _col(52) %6.0g `aa'+`bb'
+    noi di in gr _col(13) "Group 1  |" in ye _col(26) %6.0g `cc' /*
+     */ _col(40) %6.0g `dd' in gr _col(49) "|" in ye _col(52) %6.0g `cc'+`dd'
+    noi di in gr _col(13) "---------+" _dup(26) "-" "+--------"
+    noi di in gr _col(13) "Total    |" in ye _col(26) %6.0g `aa'+`cc' /*
+      */ _col(40) %6.0g `bb'+`dd' in gr _col(49) "|" in ye _col(52) /*
+      */ %6.0g `tot'
+    noi di in gr _col(13) "---------+" _dup(26) "-" "+--------"
+    noi di "                                                  "
+    noi di in gr _col(21) "Correctly predicted = " in ye /*
+      */ %6.2f ((`aa'+`dd')/`tot')*100 " %"
+    noi di in gr _col(21) "Model sensitivity   = " in ye /*
+      */ %6.2f (`aa'/(`aa'+`bb'))*100 " %"
+    noi di in gr _col(21) "Model specificity   = " in ye /*
+      */ %6.2f (`dd'/(`cc'+`dd'))*100 " %"
+    noi di in gr _col(21) "False positive      = " in ye /*
+      */ %6.2f (`cc'/(`aa'+`cc'))*100 " %"
+    noi di in gr _col(21) "False negative      = " in ye /*
+      */ %6.2f (`bb'/(`bb'+`dd'))*100 " %"
+}     
+
+* ANOVA OPTION
+  if "`anova'"!="" {
+    noi di _n(1)
+    noi di in gr _col(18) "Discriminant Scores v Group Variable"
+    noi oneway `dscore' `group'
+  }
+
+* GRAPH OPTION
+  if "`graph'"!="" {
+    tempvar lnp lnm
+    gen `lnp'=`lprob' if (`lprob'>=0.5 & `group'==1) | /* 
+      */ (`lprob'<0.5 & `group'==0)
+    gen `lnm'=`lprob' if `lnp'==.
+    lab var `lnp' "Classified"
+    lab var `lnm' "Misclassified"
+    lab var `dfun' "Discriminant Index"
+    noi gr `lnp' `lnm' `dfun', s(.p) xlab ylab(.1,.3,.4,.5,.6,.7,.9) /*
+      */ border yline(.5) ti("      Probability of Classification")
+    cap drop `lnp' `lnm'
+  }
+
+* INDIVIDUAL CLASSIFICATION STATISTICS OPTION: SAVES WITH SAVE OPTION
+   if "`detail'"!="" {
+   cap drop PRED DscScore DscIndex LnProb1 Group DIFF
+   sort `cntall'
+   noi di _n(2)
+   gen PRED=`grpred'
+   gen DscScore  = `dscore'
+   gen DscIndex  = `dfun'
+   gen LnProb1   = `lprob'
+   gen Group     = `group'
+   compress Group PRED
+   gen str2 DIFF = " *" if `group'!=PRED
+   format DIFF %2s
+   format DscIndex DscScore LnProb1 %9.4f
+ noi di in gr " PRED    = Predicted Group       DIFF     = Misclassification"
+ noi di in gr " LnProb1 = Probability Gr 1      DscScore = Discriminant Score"
+ noi di in gr "                                 DscIndex = Discriminant Index"
+   noi di in gr _dup(63) "-"
+   di "                                           "
+   noi l `y' PRED DIFF LnProb1 DscIndex DscScore, nol
+ }
+
+global S_E_var $nvar
+global S_E_obs `obs'
+global S_E_ob0 `obs0'
+global S_E_ob1 `obs1'
+global S_E_cn0 $cnt0
+global S_E_cn1 $cnt1
+global S_E_cng  ((`obs1'*$cnt0)+(`obs0'*$cnt1))/`obs'
+global S_E_r2  $rsquare
+global S_E_mah $mahala
+global S_E_eig $eigen
+global S_E_lam $lamda
+global S_E_cc  $ccor
+global S_E_chi $chisq
+global S_E_e2  $ccor^2
+global S_E_cmd "discrim"
+
+}
+
+if "`keep'"!="" {
+  noi di _n in bl " Caution: data changed in memory"
+  }
+if "`keep'"=="" {
+  restore
+}
+
+end
+
+
+
+* DROP MISSING VALUES
+  capture program drop dropmiss
+  program define dropmiss
+  local varlist "req ex"
+  parse "`*'"
+  parse "`varlist'", parse(" ")
+  local i= 1
+  while "``i''"!=""  {
+    drop if ``i''==.
+    local i=`i'+1
+  }
+end
+
+
diff --git a/Modules/ado/plus/d/discrim2.hlp b/Modules/ado/plus/d/discrim2.hlp
new file mode 100644
index 0000000..1aee917
--- /dev/null
+++ b/Modules/ado/plus/d/discrim2.hlp
@@ -0,0 +1,77 @@
+.-
+help for ^discrim^                                                    (STB-x)
+.-
+ 
+Dichotomous Discriminant Analysis
+---------------------------------
+ 
+  ^discrim^ grpvar [varlist] [^, p^redict^ a^nova^ g^raph^ d^etail^ k^eep]
+
+Description
+-----------
+^discrim^ allows the user to perform a discriminant analysis on a Bernoulli
+distributed response of grouping variable (1/0).
+
+Output includes table with the following statistics and their global 
+designation for post-estimation use when applicable:
+ 
+    1. Observations    [S_E_obs]       2. Independent vars  [S_E_var] 
+    3. Obs: group==0   [S_E_ob0]       4. Obs: group==1     [S_E_ob1]
+    5. Centroid 0      [S_E_cn0]       6. Centroid 1        [S_E_cn1]
+    7. Grand centroid  [S_E_cng]       8. R-square          [S_E_r2]
+    9. Mahalanobis     [S_E_mah]      10. Eigenvalue        [S_E_eig]
+   11. Canon. Correl   [S_E_cc]       12. Eta squared       [S_E_e2]   
+   13. Wilk's lambda   [S_E_lam]      14. Chi-square        [S_E_chi]
+
+Output also includes a table displaying both the Discriminant Function and
+Unstandardized Coefficients.
+
+Cases in which a variable has a missing value are dropped from estimation.
+The ^keep^ command does not restore such cases to active memory.
+
+Options
+-------
+^predict^ provides a confusion matrix of actual vs predicted group cell 
+   counts. Also included is a listing of the following percentages:
+      1. Correctly predicted         2. Model sensitivity
+      3. Model specificity           4. False Positive
+      5. False Negative
+
+^anova^ provides an ANOVA of discriminant scores vs the group variable.
+   Bartlett's test for equal variances in included.
+
+^graph^ provides a classification graph showing correctly and incorrectly 
+   classified cases.
+
+^detail^ creates and lists the following for each retained case:
+      1. Group    : actual group value                 
+      2. PRED     : predicted group value
+      3. DIFF     : a star indicating misclassified cases
+      4. LnProb1  : logistic probability of grouyp 1 membership
+      5. DscIndex : discriminant index
+      6. DscScore : discriminant score
+  
+^keep^ allows the user to keep the variables created in the Detail option.
+  The data set in memory is altered, so care must be taken when saving the
+  resultant file to disk.
+        
+Examples
+--------
+        . ^discrim foreign price mpg length^
+        
+        . ^discrim foreign price mpg length, p a gr d^
+
+        . ^discrim foreign price mpg length, detail keep^ 
+
+Also see
+--------
+STB-5 (Jan1992): smv3 - Hilbe, "Regression based dichotomous discriminant 
+  analysis".  
+Selvin, Steve (1995, 1996) "Practical Biostatistical Methods", Chap 6.
+  Explanation and use of the 1st version of the ^discrim^ command. 
+
+Additional help
+---------------
+Joseph Hilbe, Dept of Sociology, Arizona State University
+Email: atjmh@@asuvm.inre.asu.edu
+
diff --git a/Modules/ado/plus/d/dropvars.ado b/Modules/ado/plus/d/dropvars.ado
new file mode 100644
index 0000000..7fc2f42
--- /dev/null
+++ b/Modules/ado/plus/d/dropvars.ado
@@ -0,0 +1,15 @@
+*! 1.0.1  14mar2000  jw/ics
+program define dropvars
+	version 6
+
+	while "`1'" != "" {
+		capture drop `1'
+		if _rc { 
+			local nodropv "`nodropv' `1'"
+		}       
+		mac shift
+	}
+	if "`nodropv'" != "" {
+		di in gr "Unable to drop" in ye "`nodropv'"
+	}                
+end
diff --git a/Modules/ado/plus/d/dropvars.hlp b/Modules/ado/plus/d/dropvars.hlp
new file mode 100644
index 0000000..9b15a80
--- /dev/null
+++ b/Modules/ado/plus/d/dropvars.hlp
@@ -0,0 +1,35 @@
+.-
+help for ^dropvars^                                             [jw] Mar 14, 2000
+.-
+
+Drop variables
+--------------
+
+     ^dropvars^ list 
+
+
+Description
+-----------
+
+^dropvars^ drops the variables that match the varlist specifications in list.
+In contrast with ^drop^, ^dropvars^ allows terms in list that do not match 
+any variables; ^drop^ complain if any variable does not exist, and then 
+drops nothing.
+
+^dropvars list^ is equivalent to
+
+      ^for any list : capture drop X^
+
+
+Example
+-------
+
+    . ^dropvars a* b*^  
+      drop all variables that start with either a or b.
+	   
+	   
+Also see
+--------
+
+ Manual:  ^[R] drop^
+On-line:  help for @drop@
diff --git a/Modules/ado/plus/e/elapse.ado b/Modules/ado/plus/e/elapse.ado
new file mode 100644
index 0000000..1153bb9
--- /dev/null
+++ b/Modules/ado/plus/e/elapse.ado
@@ -0,0 +1,81 @@
+
+/* elapse.ado   10/24/97 */
+
+program define elapse 		/* start_time  name_of_operation (optional)*/
+
+	version 5.0
+	local hdiff = real(substr("$S_TIME",1,2)) - real(substr("`1'",1,2))
+	local mdiff = real(substr("$S_TIME",4,2)) - real(substr("`1'",4,2))
+	local sdiff = real(substr("$S_TIME",7,2)) - real(substr("`1'",7,2))
+	if `sdiff' < 0 {
+		local sdiff = `sdiff' + 60
+		local mdiff = `mdiff' -1
+	}
+	if `mdiff' < 0  {
+		local mdiff = `mdiff' + 60
+		local hdiff = `hdiff' -1
+	}
+	if `hdiff' < 0 {
+		local hdiff = `hdiff' + 24
+	}
+	local selap = 10000 * `hdiff' + 100 * `mdiff' + `sdiff'
+	global S_elap = `selap'
+
+	local hdiff = string(`hdiff')
+	local mdiff = string(`mdiff')
+	local sdiff = string(`sdiff')
+
+	if "`2'" == "" {
+		if `hdiff' > 0 {
+			di in ye "Elapsed time was " in wh "`hdiff'" _c
+			if `hdiff' > 1 {di in ye " hours, " _c}
+			else { di in ye " hour, " _c}  
+			di in wh "`mdiff'" _c
+			if `mdiff' > 1 {di in ye " minutes, " _c}
+			else {di in ye " minute, " _c}
+			di  in wh "`sdiff'" _c
+			if `sdiff' > 1 {di in ye " seconds."}
+			else {di in ye " second."}
+	   	}
+		else if `mdiff' > 0 {
+			di in ye "Elapsed time was " in wh "`mdiff'" _c
+			if `mdiff' > 1 {di in ye " minutes, " _c}
+			else {di in ye " minute, " _c}
+			di  in wh "`sdiff'" _c
+			if `sdiff' > 1 {di in ye " seconds."}
+			else {di in ye " second."}
+		}
+		else {
+			di in ye "Elapsed time was " in wh "`sdiff'" _c
+			if `sdiff' > 1 {di in ye " seconds."}
+			else {di in ye " second."}
+		}
+	}
+	else {
+		if `hdiff' > 0 {
+			di in ye "`2' took " in wh "`hdiff'" _c
+			if `hdiff' > 1 {di in ye " hours, " _c}
+			else { di in ye " hour, " _c}  
+			di in wh "`mdiff'" _c
+			if `mdiff' > 1 {di in ye " minutes, " _c}
+			else {di in ye " minute, " _c}
+			di  in wh "`sdiff'" _c
+			if `sdiff' > 1 {di in ye " seconds."}
+			else {di in ye " second."}
+	   	}
+		else if `mdiff' > 0 {
+			di in ye "`2' took " in wh "`mdiff'" _c
+			if `mdiff' > 1 {di in ye " minutes, " _c}
+			else {di in ye " minute, " _c}
+			di  in wh "`sdiff'" _c
+			if `sdiff' > 1 {di in ye " seconds."}
+			else {di in ye " second."}
+		}
+		else {
+			di in ye "`2' took " in wh "`sdiff'" _c
+			if `sdiff' > 1 {di in ye " seconds."}
+			else {di in ye " second."}
+		}
+	}
+
+end
diff --git a/Modules/ado/plus/e/elapse.hlp b/Modules/ado/plus/e/elapse.hlp
new file mode 100644
index 0000000..d07ec9a
--- /dev/null
+++ b/Modules/ado/plus/e/elapse.hlp
@@ -0,0 +1,68 @@
+..-
+help for ^elapse^
+..-
+
+Timing portions of a program
+- ----------------------------
+
+	^elapse^ start_time [name_of_operation]
+
+
+Where start_time is a previously defined macro equal to 
+the global system macro S_TIME at some earlier point, and 
+name_of_operation is a string.
+
+
+Description
+- -----------
+
+^Elapse^ displays a string with the name of the operation, 
+if specified, and the time elapsed between start_time and 
+current time.
+
+
+
+Options
+- -------
+
+name_of_operation is a user-defined string.
+
+
+Remarks
+- -------
+
+^Elapse^ automates the procedure of timing a piece of code 
+or an entire program.  It is accurate over midnight, but not 
+over several days.  It also creates a global S_elap, which is 
+a numerical macro of the form hhmmss, where hh is the number 
+of hours, mm the number of minutes, and ss the number of seconds.
+
+
+Examples
+- --------
+
+	^local st = "$S_TIME"^
+	^...^
+	^local oper "Maximum likelihood estimation"^
+	^elapse "`st'" "`oper'"^
+	- Maximum likelihood estimation took 7 minutes, 15 seconds.
+
+	^elapse `st'^
+	- Elapsed time was 1 hour, 10 minutes, 32 seconds.
+
+	^quietly elapse `st'^
+	^if $S_elap > 4500 { mat xx = startxx }^
+
+
+Saved Results
+- -------------
+
+S_elap (see above).
+
+
+Author
+- ------
+
+	Frederic Zimmerman
+	Food Research Institute
+	Stanford University
diff --git a/Modules/ado/plus/e/eq_g.hlp b/Modules/ado/plus/e/eq_g.hlp
new file mode 100644
index 0000000..dd55366
--- /dev/null
+++ b/Modules/ado/plus/e/eq_g.hlp
@@ -0,0 +1,81 @@
+.-
+help for ^eq^                                                                                                  
+.-
+
+Define and list equations
+-------------------------
+
+	^eq^ [^define^] eqtn
+	^eq^ [^define^] eqname ^:^ [eqtn]
+
+	^eq dir^  [^_all^ | eqname [eqname ..]]
+	^eq list^ [^_all^ | eqname [eqname ..]]
+
+	^eq drop^ {^_all^ | eqname [eqname ..]}
+
+
+Description
+-----------
+
+^eq define^ is used to define equations in ^gllamm^. In Stata 5 and earlier this
+was also used by Stata's own multivariate estimation commands. The command
+continues to work in Stata 8 but is no longer documented.
+
+^eq dir^ and ^eq list^ are used to review equations that
+have been defined.  ^eq drop^ is used to eliminate previously defined equations.
+
+^gllamm^ has options ^eqs(eqnames)^ ^geqs(eqnames)^ ^peqs(eqname)^ and ^s(eqname)^
+where eqnames is a list of equation names and eqname is an equation name.  
+You first define equations using ^eq^ and then estimate the model.  
+
+Equations are named and usually define a variable list. For instance,
+to estimate a factor model in ^gllamm^, an equation of the following
+kind must be defined:
+
+	. ^eq load: d1 d2 d3^
+
+where d1, d2 and d3 are dummy variables for three variables or items
+loading on one of the factors. You can abbreviate variable names and 
+take all the other shortcuts you would when specifying a varlist in a 
+command: 
+
+	. ^eq load: d1-d3^
+
+When you do not specify the equation name followed by a colon, the first name
+is taken both as the equation name and as part of the contents of the equation.
+
+There is one exception to this rule.  You may not type 
+
+	. ^eq price^
+
+You must type instead
+
+	. ^eq price: price^
+
+(Such nearly empty equations are not silly; it could mean that price is to
+be estimated by an intercept-only equation.)  One can also define completely
+empty equations in this way:
+
+	. ^eq price: ^
+
+Note the distinction:  "^eq price: price^" defines equation price to contain 
+"price"; "^eq price:^" defines price to contain nothing.
+
+Equations can be dropped, 
+
+	. ^eq drop load^
+	. ^eq load: d1 d2 d3^
+
+or you can redefine equations without bothering to drop them first.
+
+Equations may be listed for review:
+
+	. ^eq list load^
+	. ^eq list load1 load2^
+	. ^eq list^
+
+You can list just the equation names using ^eq dir^:
+
+	. ^eq dir^
+
+
diff --git a/Modules/ado/plus/e/eqlist.ado b/Modules/ado/plus/e/eqlist.ado
new file mode 100644
index 0000000..8fc2b09
--- /dev/null
+++ b/Modules/ado/plus/e/eqlist.ado
@@ -0,0 +1,64 @@
+program def eqlist, rclass
+*! NJC 1.1.0 23 January 2001 
+* NJC 1.0.0 5 January 2001 
+	version 6.0 
+	gettoken lists 0 : 0, parse(",")
+	if "`lists'" == "" | "`lists'" == "," { /* no \ */ 
+		di in r "incorrect syntax: no separator" 
+		exit 198 
+	}
+	
+	tokenize "`lists'", parse("\") 
+	if "`4'" != "" { 
+		di in r "incorrect syntax: too much stuff" 
+		exit 198 
+	} 	
+	if "`1'" == "\" { /* list1 empty */ 
+		if "`2'" == "\" { 
+			di in r "incorrect syntax: one \ only" 
+			exit 198
+		}	
+		local list2 "`2'" /* might be empty */ 
+	} 
+	else if "`2'" == "\" { 
+		local list1 "`1'" 
+		local list2 "`3'" /* might be empty */ 
+	} 	
+	else { 
+		di in r "incorrect syntax: what to compare?" 
+		exit 198 
+	}
+	
+	syntax [ , Global(str) Noisily ]
+	
+	if length("`global'") > 8 { 
+		di in r "global name must be <=8 characters" 
+		exit 198 
+	} 	
+
+	local n1 : word count `list1' 
+	tokenize `list1'
+	local n2 : word count `list2'
+
+	if `n1' != `n2' {
+		local iseq = 0 
+	} 	
+	else { 
+		local iseq = 1 
+		local i = 1 
+		while `i' <= `n1' & `iseq' { 
+			local word : word `i' of `list2'
+			if length("``i''") > 80 | length("`word'") > 80 { 
+				di in r "cannot handle word length > 80"
+				exit 498 
+			}	
+			if "`word'" != "``i''" { local iseq 0 } 
+			local i = `i' + 1
+		}
+	} 	
+
+	if "`noisily'" != "" { di `iseq' } 
+	if "`global'" != "" { global `global' = `iseq' } 
+	return local iseq = `iseq' 
+end 	
+			 
diff --git a/Modules/ado/plus/e/eqlist.hlp b/Modules/ado/plus/e/eqlist.hlp
new file mode 100644
index 0000000..eacf780
--- /dev/null
+++ b/Modules/ado/plus/e/eqlist.hlp
@@ -0,0 +1,2 @@
+.h listutil
+
diff --git a/Modules/ado/plus/e/espoisson.ado b/Modules/ado/plus/e/espoisson.ado
new file mode 100644
index 0000000..731377b
--- /dev/null
+++ b/Modules/ado/plus/e/espoisson.ado
@@ -0,0 +1,128 @@
+*! version 1.0 Alfonso Miranda-Caso-Luengo, November 26 2002    (SJ4-1: st0057)
+*! FIML endogenous-switch Poisson Regression
+
+program define espoisson, eclass 
+	version 6
+	if replay() { 
+		if "`e(cmd)'" != "espoisson" { error 301 }
+		else espDisplay `0'
+ 		}
+	else espEstimate `0'	
+end
+
+program define espEstimate, eclass
+	syntax varlist [if] [in] , EDummy(varname) /*
+	*/ [Switch(varlist) Quadrature(integer 6) /*
+	*/ SIGMA0(real 1) RHO0(real 0.1) /*
+        */ EXS *] 
+	
+	/* Obtaining dependent variable and explanatory variables */  
+
+	gettoken endgv exogv : varlist, parse("")
+
+	/* Selecting sample */  
+
+	marksample touse
+	markout `touse' `varlist'
+
+	/* defining some globals */ 
+	  	
+   	 global S_quad   "`quadrature'"
+	 global S_edum "`edummy'"
+
+
+	/* Diverting to exsp if EXS option active */
+	
+	if "`exs'"!="" {
+			#delimit ;
+			exspoisson `endgv' `exogv' `if' `in', edummy(`edummy') 
+			s(`switch') q(`quadrature') 
+			sigma0(`sigma0') ;
+			#delimit cr
+			exit
+			}
+	
+	/* Get points and weights for Gaussian-Hermite quadrature. */
+	
+	tempvar  x w
+	qui gen double `x' = 0 
+	qui gen double `w' = 0 
+  	ghquad `x' `w', n(`quadrature')
+	local j = `quadrature'
+	while `j' >0 { 
+				    scalar x`j' = `x'[`j']
+				    local j = `j' -1
+				  }
+	local j = `quadrature'
+	while `j' >0 {
+				   scalar w`j' = `w'[`j']
+				   local j = `j' - 1 
+				  }
+	
+
+	/* GETTING INITIAL VALUES */ 
+	
+	 di _skip(3)
+	 qui probit `edummy' `switch' if `touse'  
+
+	 tempname b b1 b2 ch cr b0 bi
+	 
+	 mat `b'=e(b)
+	 xcolnames `b', head(switch)
+	 
+	 di as txt "Getting Initial Values:"
+	 qui poisson  `endgv' `exogv' if `touse'
+	
+	 mat `b1' = e(b)
+	 mat `b2' = (`b1',`b')
+	 matrix `ch' = ln(`sigma0') 
+	 matrix colnames `ch' = lnsigma:_cons
+	 matrix `cr' = `rho0'
+	 matrix colnames `cr' = rho:_cons
+	 matrix `b0' = (`b2',`ch',`cr')
+
+	 ml model d0 espoisson_ll ("`endgv'": `endgv' = `exogv') /* 
+	 */ (switch:`switch')(lnsigma:)(rho:) /* 
+         */ if `touse', init(`b0')
+
+	 qui ml search rho: 14 -14
+	 mat `cr' = ML_b[1,"rho:_cons"]
+	 mat `bi' = (`b2',`ch',`cr')
+	 
+         /* FITTING FULL MODEL */ 
+	
+	 di _skip(3)
+	 di in gr "Fitting Full model:"
+	 
+	 ml model d0 espoisson_ll ("`endgv'": `endgv' = `exogv') /* 
+	 */ (switch:`switch')(lnsigma:)(rho:)/* 
+         */ if `touse', init(`bi', skip) max `options' search(off)  
+
+	 estimates local cmd "espoisson"
+	 estimates local edummy "`edummy'"
+	 est local predict "espoisson_p"
+	 est local quad "`quadrature'"
+	  	
+	/* Display Results */
+
+	espDisplay 
+end
+	
+	
+program define espDisplay 
+
+      	di _skip(12)
+	di _n as txt /*
+	*/ "Endogenous-Switch Poisson Regression"
+	di as text "(`e(quad)' quadrature points)"  
+   	
+	ml di, neq(2)plus
+	_diparm lnsigma, exp pr label("sigma")
+      _diparm rho, f((exp(2*@)-1)/(exp(2*@)+1)) /*       
+      */ d(4*exp(2*@)/(exp(2*@)+1)^2) label("rho") pr
+	di in gre in smcl "{hline 13}{c BT}{hline 64}" 
+end
+
+
+
+	
diff --git a/Modules/ado/plus/e/espoisson.hlp b/Modules/ado/plus/e/espoisson.hlp
new file mode 100644
index 0000000..b59ee3d
--- /dev/null
+++ b/Modules/ado/plus/e/espoisson.hlp
@@ -0,0 +1,84 @@
+{smcl}
+{hline}
+help for {hi:espoisson} {right:(SJ4-1: st0057)}
+{hline}
+
+{title:FIML endogenous switching Poisson model}
+
+{p 8 13 2}{cmd:espoisson}{space 2}{it:depvar} [{it:varlist}] 
+	[{cmd:if} {it:exp}] [{cmd:in} {it:range}] {cmd:,}
+	{cmdab:ed:ummy(}{it:varname}{cmd:)} [ {cmdab:s:witch(}{it:varlist}{cmd:)}
+        {cmdab:q:uadrature(}{it:#}{cmd:)} {cmd:rho0(}{it:#}{cmd:)} 
+	{cmd:sigma0(}{it:#}{cmd:)} {cmd:exs} {it:maximize_options}]
+
+{p 8 8 2}Note: the vector {it:varlist} should include the switch variable
+(endogenous dummy) as one of its elements.{p_end}
+
+{p 4 4 2} The syntax of {help predict} after {cmd:espoisson} is
+
+{p 8 16 2}{cmd:predict} {it:newvar} [{cmd:if} {it:exp}]
+	[{cmd:in} {it:range}] [{cmd:,} n ]
+
+{p 4 4 2}where,
+
+{p 8 21 2}{cmd:n}{space 9}predicted number of events (default){p_end}
+	
+
+{title:Description}
+
+{p 4 4 2}{cmd:espoisson} fits a FIML endogenous switching Poisson model.
+An endogenous dummy variable is present in the vector of explanatory
+variables, and there is unobserved individual heterogeneity. The endogenous
+dummy variable indicates the realization of two different regimes. The
+endogenous switching model corrects for the  simultaneous equation bias that
+the presence of the endogenous dummy may induce in a standard exogenous-switch
+count model. 
+
+{p 4 4 2}This program uses {cmd:ml d0} method. 
+
+
+{title:Options}
+
+{p 4 8 2}{cmd:edummy(}{it:varname}{cmd:)} (required) specifies the endogenous
+dummy variable.
+
+{p 4 8 2} {cmd:switch(}{it:varlist}{cmd:)} specifies explanatory variables for
+the index function governing the endogenous dummy. If {cmd:switch()} is
+unspecified then a constant-only model is fitted.
+
+{p 4 8 2}{cmd:quadrature(}{it:#}{cmd:)} specifies the number of quadrature
+points for the Gauss-Hermite integral. Six points are used by default.
+
+{p 4 8 2}{cmd:rho0(}{it:#}{cmd:)} specifies initial value for rho. If
+unspecified, {cmd:rho0()}=0.01.
+
+{p 4 8 2}{cmdab:sigma0(}{it:#}{cmdab:)} specifies initial value for sigma. If
+unspecified, {cmd:sigma0()}=1.0.
+
+{p 4 8 2}{cmdab:exs} causes the program to fit an exogenous switching
+model.
+
+
+{title:Examples}
+
+{p 8 12 2}{cmd:. espoisson  y x1 x2, ed(x2) s(x1) q(16)}{p_end}
+{p 8 12 2}{cmd:. predict yhat, n}{p_end}
+
+{p 8 12 2}{cmd:. espoisson  y x1 x2, ed(x2) s(x1) q(16) exs}{p_end}
+{p 8 12 2}{cmd:. predict yhat, n}{p_end}
+
+
+{title:Author}
+
+{p 4 8 2}{bf: Alfonso Miranda}{p_end}
+{p 4 8 2} Economics Department, Warwick University, CV4 7AL, UK.{p_end}
+{p 4 8 2}E-mail: Alfonso.Miranda-Caso-Luengo@warwick.ac.uk{p_end}
+
+
+{title:Also see}
+
+{p 4 14 2}Manual:  {hi:[U] 23 Estimation and post-estimation commands},{p_end}
+{p 13 13 2}{hi:[U] 29 Overview of model estimation in Stata},{p_end}
+{p 13 13 2}{hi:[R] poisson}
+{p 4 13 2}Online:  help for {help ml}, {help glm}, {help nbreg}, {help svypois},
+{help xtpois}, {help zip}
diff --git a/Modules/ado/plus/e/espoisson_ll.ado b/Modules/ado/plus/e/espoisson_ll.ado
new file mode 100644
index 0000000..1a5c0c1
--- /dev/null
+++ b/Modules/ado/plus/e/espoisson_ll.ado
@@ -0,0 +1,74 @@
+*! Alfonso Miranda Caso Luengo                                  (SJ4-1: st0057)
+*! Version 1.0 November 21 2002
+
+program define espoisson_ll
+ 
+ args todo b f
+
+ tempname lnsigma kappa delta 
+ tempvar xb zb 
+
+ local y "$ML_y1"
+ local d "$S_edum"
+ 
+ mleval `xb' = `b', eq(1)
+ mleval `zb' = `b', eq(2)
+ mleval `lnsigma' = `b', eq(3) scalar
+ mleval `kappa' = `b', eq(4) scalar
+
+ 
+ scalar `lnsigma' = cond(`lnsigma'<-20,-20,`lnsigma')
+
+ if `kappa' <-14 { 
+			scalar `kappa' = -14
+			}
+ if `kappa' > 14 { 
+			scalar `kappa' = 14 
+			}
+ 
+ tempname sma u rho
+ 
+ scalar `sma' = exp(`lnsigma')  
+ scalar `rho' = (exp(2*`kappa')-1)/(exp(2*`kappa')+1)
+
+ tempvar F p r1 r2 r3 r4 r5 r6
+ 
+ qui { 
+	gen double `F' = . if  $ML_samp
+
+	gen double `p' = 0 if $ML_samp
+	gen double `r1' = 0 if $ML_samp
+	gen double `r2' = 0 if $ML_samp 
+	gen double `r3' = 0 if $ML_samp
+	gen double `r4' = 0 if $ML_samp
+	gen double `r5' = 0 if $ML_samp
+	gen double `r6' = 0 if $ML_samp
+
+	local m = 1
+        while `m' <= $S_quad {
+	                       scalar `u' = sqrt(2)*`sma'*scalar(x`m')
+                               replace `r1' = `xb' +  `u' if $ML_samp 
+			       replace `r2' = exp(`r1')^(`y')*exp(-exp(`r1')) if $ML_samp
+			       replace `r3' = `r2'/exp(lngamma(`y'+1)) if $ML_samp
+			       replace `r4' = `zb' + sqrt(2)*`rho'*scalar(x`m') if $ML_samp
+			       replace `r5' = `r4'/(sqrt(1-`rho'^2)) if $ML_samp
+			       replace `r6' = `d'*norm(`r5') + /*
+				 */ (1-`d')*norm(-`r5') if $ML_samp
+			       replace `F' = `r3'*`r6' if $ML_samp
+			       replace `p' = `p' + scalar(w`m')*`F' if $ML_samp
+			       local m = `m' + 1
+                 	      }
+	replace `p'= (1/sqrt(_pi))*`p' if $ML_samp
+        replace `F' = log(`p') if $ML_samp
+	mlsum `f' = `F' if $ML_samp
+	}
+end
+exit
+
+	                
+
+	                
+	     
+	     	     	     
+                          
+  	 
diff --git a/Modules/ado/plus/e/espoisson_p.ado b/Modules/ado/plus/e/espoisson_p.ado
new file mode 100644
index 0000000..a433478
--- /dev/null
+++ b/Modules/ado/plus/e/espoisson_p.ado
@@ -0,0 +1,50 @@
+*! version 1.0  Alfonso Miranda-Caso-Luengo, June 2003          (SJ4-1: st0057)
+program define espoisson_p, sort
+	version 7
+
+	local myopts "n"
+
+	_pred_se "`myopts'" `0'
+	if `s(done)' { exit }
+	local vtyp  `s(typ)'
+	local varn `s(varn)'
+	local 0 `"`s(rest)'"'
+
+	syntax [if] [in] [, `myopts' noOFFset]
+
+	local type "`n'"
+	marksample touse 
+	
+	if  "`type'"=="n" | "`type'"=="" {
+		
+	tempname mu zu lnsigma kappa 
+	qui _predict double `mu' if `touse', xb `offset' eq(#1)
+	qui _predict double `zu' if `touse', xb `offset' eq(#2)
+	qui _predict double `lnsigma' if `touse', xb eq(#3)
+	qui _predict double `kappa' if `touse', xb eq(#4)
+
+	local d "`e(edummy)'"
+
+	tempvar sma u rho
+ 	gen double `sma' = exp(`lnsigma')  
+ 	gen double `rho' = (exp(2*`kappa')-1)/(exp(2*`kappa')+1)
+	
+	tempvar p eta 
+	gen double `p'=0 if `touse'
+	gen double `eta'=0 if `touse'
+	qui replace `mu'=exp(`mu'-0.5*`sma'^2) if `touse'
+	#delimit ;
+	qui replace `eta' = `d'*(norm(`zu' +`rho'*`sma')/norm(`zu'))               
+	+ (1-`d')*(norm(-(`zu'+`rho'*`sma'))/norm(-(`zu'))) if `touse'	;
+	#delimit cr
+	qui replace `p'=`mu'*`eta' if `touse'
+	qui gen `vtyp' `varn'=`p' if `touse'
+	label var `varn' "predicted number of events of `e(depvar)'"
+	exit
+	}
+end
+
+
+
+
+
diff --git a/Modules/ado/plus/e/estadd.ado b/Modules/ado/plus/e/estadd.ado
new file mode 100644
index 0000000..6098764
--- /dev/null
+++ b/Modules/ado/plus/e/estadd.ado
@@ -0,0 +1,2457 @@
+*! version 2.3.1  07oct2009  Ben Jann
+*  1. estadd and helpers
+*  2. estadd_local
+*  3. estadd_scalar
+*  4. estadd_matrix
+*  5. estadd_mean
+*  6. estadd_sd
+*  7. estadd_beta
+*  8. estadd_coxsnell
+*  9. estadd_nagelkerke
+* 10. estadd_ysumm
+* 11. estadd_summ
+* 12. estadd_vif
+* 13. estadd_ebsd
+* 14. estadd_expb
+* 15. estadd_pcorr
+* 16. estadd_lrtest
+* 17. estadd_brent
+* 18. estadd_fitstat
+* 19. estadd_listcoef
+* 20. estadd_mlogtest
+* 21. estadd_prchange
+* 22. estadd_prvalue
+* 23. estadd_asprvalue
+* 24. estadd_margins
+* 99. copy of erepost.ado
+
+* 1.
+program estadd
+    version 8.2
+    local caller : di _caller()
+    capt _on_colon_parse `0'
+    if !_rc {
+        local 0 `"`s(before)'"'
+        local names `"`s(after)'"'
+    }
+    syntax anything(equalok id="subcommand") [if] [in] [fw aw iw pw] [, * ]
+    if regexm(`"`anything'"',"^r\((.*)\)$") {  // check -estadd r(name)-
+        capt confirm scalar `anything'
+        if _rc {
+            capt confirm matrix `anything'
+            if _rc {
+                di as err `"`anything' not found"'
+                exit 111
+            }
+            else {
+                local anything `"matrix `anything'"'
+            }
+        }
+        else {
+            local anything `"scalar `anything'"'
+        }
+    }
+    gettoken subcommand : anything
+    capt confirm name `subcommand'
+    if _rc {
+        di as err "invalid subcommand"
+        exit 198
+    }
+    if `"`options'"'!="" local options `", `options'"'
+    if `"`weight'`exp'"'!="" local wgtexp `"[`weight'`exp']"'
+
+//expand estimates names and backup current estimates if necessary
+    tempname rcurrent ecurrent
+    capt _return drop `rcurrent'
+    _return hold `rcurrent'
+    capt noisily {
+        local names: list retok names
+        if "`names'"=="" {
+            local names "."
+            local qui
+        }
+        else local qui quietly
+        foreach name of local names {
+            if "`name'"=="." {
+                capt est_expand "`name'"
+                if _rc local enames "`enames'`name' "
+                else local enames "`enames'`r(names)' "
+            }
+            else {
+                est_expand "`name'" //=> error if estimates not found
+                local enames "`enames'`r(names)' "
+            }
+        }
+        local names: list uniq enames
+        if "`names'"=="." local active
+        else {
+            capt est_expand .
+            if _rc local active "."
+            else local active "`r(names)'"
+            if "`active'"=="." | `:list posof "`active'" in names'==0 {
+                local active
+                _est hold `ecurrent', restore estsystem nullok
+            }
+        }
+    }
+    if _rc {
+        _return restore `rcurrent'
+        exit _rc
+    }
+    _return restore `rcurrent', hold
+
+// cases:
+// - if active estimates not stored yet and "`names'"==".": simply execute
+//   estadd_subcmd to active estimates
+// - else if active estimates not stored yet: backup/restore active estimates
+// - else if active estimates stored but not in `names': backup/restore active estimates
+// - else if active estimates stored: no backup but restore at end
+
+//loop over estimates names and run subcommand
+    nobreak {
+        foreach m of local names {
+            if "`names'"!="." {
+                if "`m'"=="." _est unhold `ecurrent'
+                else {
+                    capt confirm new var _est_`m' // fix e(sample)
+                    if _rc qui replace _est_`m' = 0 if _est_`m' >=.
+                    _est unhold `m'
+                }
+            }
+            backup_estimates_name
+            capt n break `qui' version `caller': estadd_`anything' `if' `in' `wgtexp' `options'
+            local rc = _rc
+            restore_estimates_name
+            if "`names'"!="." {
+                if "`m'"=="." _est hold `ecurrent', restore estsystem nullok
+                else _est hold `m', estimates varname(_est_`m')
+            }
+            if `rc' continue, break
+        }
+        if "`active'"!="" estimates restore `active', noh
+    }
+    _return restore `rcurrent'
+    if `rc' {
+        if `rc' == 199 di as error "invalid subcommand"
+        exit `rc'
+    }
+end
+
+program define backup_estimates_name, eclass
+    ereturn local _estadd_estimates_name `"`e(_estimates_name)'"'
+    ereturn local _estimates_name ""
+end
+program define restore_estimates_name, eclass
+    ereturn local _estimates_name `"`e(_estadd_estimates_name)'"'
+    ereturn local _estadd_estimates_name ""
+end
+
+program confirm_new_ename
+    capture confirm existence `e(`0')'
+    if !_rc {
+        di as err "e(`0') already defined"
+        exit 110
+    }
+end
+
+program confirm_esample
+    local efun: e(functions)
+    if `:list posof "sample" in efun'==0 {
+        di as err "e(sample) information not available"
+        exit 498
+    }
+end
+
+program confirm_numvar
+    args var
+    local ts = index("`var'",".")
+    confirm numeric variable `=substr("`var'",`ts'+1,.)'
+end
+
+program define added_macro
+    args name
+    di as txt %25s `"e(`name') : "' `""{res:`e(`name')'}""'
+end
+
+program define added_scalar
+    args name label
+    di as txt %25s `"e(`name') = "' " " as res e(`name') _c
+    if `"`label'"'!="" {
+        di as txt _col(38) `"(`label')"'
+    }
+    else di ""
+end
+
+program define added_matrix
+    args name label
+    capture {
+        local r = rowsof(e(`name'))
+        local c = colsof(e(`name'))
+    }
+    if _rc {
+        tempname tmp
+        mat `tmp' = e(`name')
+        local r = rowsof(`tmp')
+        local c = colsof(`tmp')
+    }
+    di as txt %25s `"e(`name') : "' " " ///
+        as res "`r' x `c'" _c
+    if `"`label'"'=="_rown" {
+        local thelabel: rownames e(`name')
+        local thelabel: list retok thelabel
+        if `r'>1 {
+            local thelabel: subinstr local thelabel " " ", ", all
+        }
+        di as txt _col(38) `"(`thelabel')"'
+    }
+    else if `"`label'"'!="" {
+        di as txt _col(38) `"(`label')"'
+    }
+    else di ""
+end
+
+* 2.
+* -estadd- subroutine: add local
+program estadd_loc
+    estadd_local `0'
+end
+program estadd_loca
+    estadd_local `0'
+end
+program estadd_local, eclass
+    version 8.2
+    syntax anything(equalok) [, Prefix(name) Replace Quietly ]
+    gettoken name def : anything , parse(" =:")
+    if "`replace'"=="" {
+        confirm_new_ename `prefix'`name'
+    }
+    ereturn local `prefix'`name'`def'
+    di _n as txt "added macro:"
+    added_macro `prefix'`name'
+end
+
+* 3.
+* -estadd- subroutine: add scalar
+program estadd_sca
+    estadd_scalar `0'
+end
+program estadd_scal
+    estadd_scalar `0'
+end
+program estadd_scala
+    estadd_scalar `0'
+end
+program estadd_scalar, eclass
+    version 8.2
+    syntax anything(equalok) [, Prefix(name) Replace Quietly ]
+    if regexm("`anything'","^r\((.*)\)$") {     // estadd scalar r(name)
+        local name = regexs(1)
+        capt confirm name `name'
+        confirm scalar `anything'
+        if _rc error 198
+        local equ  "`anything'"
+    }
+    else {
+        local isname 0
+        gettoken name equ0: anything, parse(" =")
+        capt confirm name `name'
+        if _rc error 198
+        else if `"`equ0'"'==""  {               // estadd scalar name
+            local isname 1
+            local equ  "scalar(`name')"
+        }
+        else {                                  // estadd scalar name [=] exp
+            gettoken trash equ : equ0, parse(" =")
+            if `"`trash'"'!="=" {
+                local equ `"`equ0'"'
+            }
+        }
+    }
+    if "`replace'"=="" {
+        confirm_new_ename `prefix'`name'
+    }
+    ereturn scalar `prefix'`name' = `equ'
+    di _n as txt "added scalar:"
+    added_scalar `prefix'`name'
+end
+
+* 4.
+* -estadd- subroutine: add matrix
+program estadd_mat
+    estadd_matrix `0'
+end
+program estadd_matr
+    estadd_matrix `0'
+end
+program estadd_matri
+    estadd_matrix `0'
+end
+program estadd_matrix, eclass
+    version 8.2
+    syntax anything(equalok) [, Prefix(name) Replace Quietly ]
+    if regexm("`anything'","^r\((.*)\)$") {     // estadd matrix r(name)
+        local name = regexs(1)
+        capt confirm name `name'
+        if _rc error 198
+        confirm matrix `anything'
+        local equ  "`anything'"
+    }
+    else {
+        local isname 0
+        gettoken name equ0: anything, parse(" =")
+        capt confirm name `name'
+        if _rc error 198
+        else if `"`equ0'"'==""  {               // estadd matrix name
+            local isname 1
+            local equ  "`name'"
+        }
+        else {                                  // estadd matrix name [=] exp
+            gettoken trash equ : equ0, parse(" =")
+            if `"`trash'"'!="=" {
+                local equ `"`equ0'"'
+            }
+        }
+    }
+    if "`replace'"=="" {
+        confirm_new_ename `prefix'`name'
+    }
+    tempname M
+    mat `M' = `equ'
+    ereturn matrix `prefix'`name' = `M'
+    di _n as txt "added matrix:"
+    added_matrix `prefix'`name'
+end
+
+* 5.
+* -estadd- subroutine: means of regressors
+program define estadd_mean, eclass
+    version 8.2
+    syntax [, Prefix(name) Replace Quietly ]
+//check availability of e(sample)
+    confirm_esample
+//check e()-names
+    if "`replace'"=="" confirm_new_ename `prefix'mean
+//use aweights with -summarize-
+    local wtype `e(wtype)'
+    if "`wtype'"=="pweight" local wtype aweight
+//subpop?
+    local subpop "`e(subpop)'"
+    if "`subpop'"=="" local subpop 1
+//copy coefficients matrix and determine varnames
+    tempname results
+    mat `results' = e(b)
+    local vars: colnames `results'
+//loop over variables: calculate -mean-
+    local j 0
+    foreach var of local vars {
+        local ++j
+        capture confirm_numvar `var'
+        if _rc mat `results'[1,`j'] = .z
+        else {
+            capt su `var' [`wtype'`e(wexp)'] if e(sample) & `subpop', meanonly
+            mat `results'[1,`j'] = cond(_rc,.,r(mean))
+        }
+    }
+//return the results
+    ereturn matrix `prefix'mean = `results'
+    di _n as txt "added matrix:"
+    added_matrix `prefix'mean
+end
+
+* 6.
+* -estadd- subroutine: standard deviations of regressors
+program define estadd_sd, eclass
+    version 8.2
+    syntax [, noBinary Prefix(name) Replace Quietly ]
+//check availability of e(sample)
+    confirm_esample
+//check e()-names
+    if "`replace'"=="" confirm_new_ename `prefix'sd
+//use aweights with -summarize-
+    local wtype `e(wtype)'
+    if "`wtype'"=="pweight" local wtype aweight
+//subpop?
+    local subpop "`e(subpop)'"
+    if "`subpop'"=="" local subpop 1
+//copy coefficients matrix and determine varnames
+    tempname results
+    mat `results' = e(b)
+    local vars: colnames `results'
+//loop over variables: calculate -mean-
+    local j 0
+    foreach var of local vars {
+        local ++j
+        capture confirm_numvar `var'
+        if _rc mat `results'[1,`j'] = .z
+        else {
+            capture assert `var'==0 | `var'==1 if e(sample) & `subpop'
+            if _rc | "`binary'"=="" {
+                capt su `var' [`wtype'`e(wexp)'] if e(sample) & `subpop'
+                mat `results'[1,`j'] = cond(_rc,.,r(sd))
+            }
+            else mat `results'[1,`j'] = .z
+        }
+    }
+//return the results
+    ereturn matrix `prefix'sd = `results'
+    di _n as txt "added matrix:"
+    added_matrix `prefix'sd
+end
+
+* 7.
+* -estadd- subroutine: standardized coefficients
+program define estadd_beta, eclass
+    version 8.2
+    syntax [, Prefix(name) Replace Quietly ]
+//check availability of e(sample)
+    confirm_esample
+//check e()-names
+    if "`replace'"=="" confirm_new_ename `prefix'beta
+//use aweights with -summarize-
+    local wtype `e(wtype)'
+    if "`wtype'"=="pweight" local wtype aweight
+//subpop?
+    local subpop "`e(subpop)'"
+    if "`subpop'"=="" local subpop 1
+//copy coefficients matrix and determine varnames
+    tempname results sddep
+    mat `results' = e(b)
+    local vars: colnames `results'
+    local eqs: coleq `results', q
+    local depv "`e(depvar)'"
+//loop over variables: calculate -beta-
+    local j 0
+    local lastdepvar
+    foreach var of local vars {
+        local depvar: word `++j' of `eqs'
+        if "`depvar'"=="_" local depvar "`depv'"
+        capture confirm_numvar `depvar'
+        if _rc mat `results'[1,`j'] = .z
+        else {
+            if "`depvar'"!="`lastdepvar'" {
+                capt su `depvar' [`wtype'`e(wexp)'] if e(sample) & `subpop'
+                scalar `sddep' = cond(_rc,.,r(sd))
+            }
+            capture confirm_numvar `var'
+            if _rc mat `results'[1,`j'] = .z
+            else {
+                capt su `var' [`wtype'`e(wexp)'] if e(sample) & `subpop'
+                mat `results'[1,`j'] = cond(_rc,.,`results'[1,`j'] * r(sd) / `sddep')
+            }
+        }
+        local lastdepvar "`depvar'"
+    }
+//return the results
+    ereturn matrix `prefix'beta = `results'
+    di _n as txt "added matrix:"
+    added_matrix `prefix'beta
+end
+
+* 8.
+* -estadd- subroutine: Cox & Snell Pseudo R-Squared
+program define estadd_coxsnell, eclass
+    version 8.2
+    syntax [, Prefix(name) Replace Quietly ]
+//check e()-names
+    if "`replace'"=="" confirm_new_ename `prefix'coxsnell
+//compute statistic
+    tempname results
+    scalar `results' = 1 - exp((e(ll_0)-e(ll))*2/e(N))  // = 1 - exp(e(ll_0)-e(ll))^(2/e(N))
+//return the results
+    *di as txt "Cox & Snell Pseudo R2 = " as res `results'
+    ereturn scalar `prefix'coxsnell = `results'
+    di _n as txt "added scalar:"
+    added_scalar `prefix'coxsnell
+end
+
+* 9.
+* -estadd- subroutine: Nagelkerke Pseudo R-Squared
+program define estadd_nagelkerke, eclass
+    version 8.2
+    syntax [, Prefix(name) Replace Quietly ]
+//check e()-names
+    if "`replace'"=="" confirm_new_ename `prefix'nagelkerke
+//compute statistic
+    tempname results
+    scalar `results' = (1 - exp((e(ll_0)-e(ll))*2/e(N))) / (1 - exp(e(ll_0)*2/e(N)))
+        // = (1 - exp(e(ll_0)-e(ll))^(2/e(N))) / (1 - exp(e(ll_0))^(2/e(N)))
+//return the results
+    *di as txt "Nagelkerke Pseudo R2 = " as res `results'
+    ereturn scalar `prefix'nagelkerke = `results'
+    di _n as txt "added scalar:"
+    added_scalar `prefix'nagelkerke
+end
+
+* 10.
+* -estadd- subroutine: summary statistics for dependent variable
+program define estadd_ysumm, eclass
+    version 8.2
+    syntax [, MEan SUm MIn MAx RAnge sd Var cv SEMean SKewness ///
+     Kurtosis MEDian p1 p5 p10 p25 p50 p75 p90 p95 p99 iqr q all ///
+     Prefix(passthru) Replace Quietly ]
+//check availability of e(sample)
+    confirm_esample
+//default prefix
+    if `"`prefix'"'=="" local prefix y
+    else {
+        local 0 ", `prefix'"
+        syntax [, prefix(name) ]
+    }
+//use aweights with -summarize-
+    local wtype `e(wtype)'
+    if "`wtype'"=="pweight" local wtype aweight
+//subpop?
+    local subpop "`e(subpop)'"
+    if "`subpop'"=="" local subpop 1
+//determine list of stats
+    tempname results
+    local Stats p99 p95 p90 p75 p50 p25 p10 p5 p1 kurtosis ///
+     skewness var sd max min sum mean
+    if "`all'"!="" {
+        local stats `Stats'
+        local range range
+        local cv cv
+        local semean semean
+        local iqr iqr
+        local sumtype detail
+    }
+    else {
+        if "`q'"!="" {
+            local p25 p25
+            local p50 p50
+            local p75 p75
+        }
+        if "`median'"!="" local p50 p50
+        foreach stat of local Stats {
+            if "``stat''"!="" {
+                local stats: list stats | stat
+            }
+        }
+        if "`stats'"=="" & "`range'"=="" & "`cv'"=="" & ///
+         "`semean'"=="" & "`iqr'"=="" local stats sd max min mean
+        local sumtype sum mean min max
+        if "`:list stats - sumtype'"=="" & "`cv'"=="" & ///
+         "`semean'"=="" & "`iqr'"=="" local sumtype meanonly
+        else {
+            local sumtype `sumtype' Var sd
+            if "`:list stats - sumtype'"=="" & "`iqr'"=="" local sumtype
+            else local sumtype detail
+        }
+    }
+    local Stats: subinstr local stats "var" "Var"
+    local nstats: word count `iqr' `semean' `cv' `range' `stats'
+    if "`replace'"=="" {
+        foreach stat in `iqr' `semean' `cv' `range' `stats' {
+            confirm_new_ename `prefix'`=lower("`stat'")'
+        }
+    }
+//calculate stats
+    local var: word 1 of `e(depvar)'
+    mat `results' = J(`nstats',1,.z)
+    qui su `var' [`wtype'`e(wexp)'] if e(sample) & `subpop', `sumtype'
+    local i 0
+    if "`iqr'"!="" {
+        mat `results'[`++i',1] = r(p75) - r(p25)
+    }
+    if "`semean'"!="" {
+        mat `results'[`++i',1] = r(sd) / sqrt(r(N))
+    }
+    if "`cv'"!="" {
+        mat `results'[`++i',1] = r(sd) / r(mean)
+    }
+    if "`range'"!="" {
+        mat `results'[`++i',1] = r(max) - r(min)
+    }
+    foreach stat of local Stats {
+        mat `results'[`++i',1] = r(`stat')
+    }
+//return the results
+    local i 0
+    di as txt _n "added scalars:"
+    foreach stat in `iqr' `semean' `cv' `range' `stats' {
+        local sname = lower("`stat'")
+        ereturn scalar `prefix'`sname' = `results'[`++i',1]
+        added_scalar `prefix'`sname'
+    }
+end
+
+* 11.
+* -estadd- subroutine: various summary statistics
+program define estadd_summ, eclass
+    version 8.2
+    syntax [, MEan SUm MIn MAx RAnge sd Var cv SEMean SKewness ///
+     Kurtosis MEDian p1 p5 p10 p25 p50 p75 p90 p95 p99 iqr q all ///
+     Prefix(name) Replace Quietly ]
+//check availability of e(sample)
+    confirm_esample
+//use aweights with -summarize-
+    local wtype `e(wtype)'
+    if "`wtype'"=="pweight" local wtype aweight
+//subpop?
+    local subpop "`e(subpop)'"
+    if "`subpop'"=="" local subpop 1
+//determine list of stats
+    tempname results results2
+    local Stats p99 p95 p90 p75 p50 p25 p10 p5 p1 kurtosis ///
+     skewness var sd max min sum mean
+    if "`all'"!="" {
+        local stats `Stats'
+        local range range
+        local cv cv
+        local semean semean
+        local iqr iqr
+        local sumtype detail
+    }
+    else {
+        if "`q'"!="" {
+            local p25 p25
+            local p50 p50
+            local p75 p75
+        }
+        if "`median'"!="" local p50 p50
+        foreach stat of local Stats {
+            if "``stat''"!="" {
+                local stats: list stats | stat
+            }
+        }
+        if "`stats'"=="" & "`range'"=="" & "`cv'"=="" & ///
+         "`semean'"=="" & "`iqr'"=="" local stats sd max min mean
+        local sumtype sum mean min max
+        if "`:list stats - sumtype'"=="" & "`cv'"=="" & ///
+         "`semean'"=="" & "`iqr'"=="" local sumtype meanonly
+        else {
+            local sumtype `sumtype' Var sd
+            if "`:list stats - sumtype'"=="" & "`iqr'"=="" local sumtype
+            else local sumtype detail
+        }
+    }
+    local Stats: subinstr local stats "var" "Var"
+    local nstats: word count `iqr' `semean' `cv' `range' `stats'
+    if "`replace'"=="" {
+        foreach stat in `iqr' `semean' `cv' `range' `stats' {
+            confirm_new_ename `prefix'`=lower("`stat'")'
+        }
+    }
+//copy coefficients matrix and determine varnames
+    mat `results' = e(b)
+    local vars: colnames `results'
+    if `nstats'>1 {
+        mat `results' = `results' \ J(`nstats'-1,colsof(`results'),.z)
+    }
+//loop over variables: calculate stats
+    local j 0
+    foreach var of local vars {
+        local ++j
+        capture confirm_numvar `var'
+        if _rc mat `results'[1,`j'] = .z
+        else {
+            capt su `var' [`wtype'`e(wexp)'] if e(sample) & `subpop', `sumtype'
+            local i 0
+            if "`iqr'"!="" {
+                mat `results'[`++i',`j'] = cond(_rc,.,r(p75) - r(p25))
+            }
+            if "`semean'"!="" {
+                mat `results'[`++i',`j'] = cond(_rc,.,r(sd) / sqrt(r(N)))
+            }
+            if "`cv'"!="" {
+                mat `results'[`++i',`j'] = cond(_rc,.,r(sd) / r(mean))
+            }
+            if "`range'"!="" {
+                mat `results'[`++i',`j'] = cond(_rc,.,r(max) - r(min))
+            }
+            foreach stat of local Stats {
+                mat `results'[`++i',`j'] = cond(_rc,.,r(`stat'))
+            }
+        }
+    }
+//return the results
+    local i 0
+    di as txt _n "added matrices:"
+    foreach stat in `iqr' `semean' `cv' `range' `stats' {
+        local sname = lower("`stat'")
+        mat `results2' = `results'[`++i',1...]
+        ereturn matrix `prefix'`sname' = `results2'
+        added_matrix `prefix'`sname'
+    }
+end
+
+* 12.
+* -estadd- subroutine: variance inflation factors
+program define estadd_vif, eclass
+    version 8.2
+    local caller : di _caller()
+    syntax [, TOLerance SQRvif Prefix(name) Replace Quietly ]
+//check availability of e(sample)
+    confirm_esample
+//check e()-names
+    if "`replace'"=="" {
+        confirm_new_ename `prefix'vif
+        if "`tolerance'"!="" confirm_new_ename `prefix'tolerance
+        if "`sqrvif'"!="" confirm_new_ename `prefix'sqrvif
+    }
+//copy coefficients matrix and set to .z
+    tempname results results2 results3
+    matrix `results' = e(b)
+    forv j = 1/`=colsof(`results')' {
+        mat `results'[1,`j'] = .z
+    }
+    if "`tolerance'"!="" mat `results2' = `results'
+    if "`sqrvif'"!="" mat `results3' = `results'
+//compute VIF and add to results vector
+    capt n `quietly' version `caller': vif
+    if _rc {
+        if _rc == 301 di as err "-estadd:vif- can only be used after -regress-"
+        exit _rc
+    }
+    local i 0
+    local name "`r(name_`++i')'"
+    while "`name'"!="" {
+        local j = colnumb(`results',"`name'")
+        if `j'<. {
+            matrix `results'[1,`j'] = r(vif_`i')
+            if "`tolerance'"!="" matrix `results2'[1,`j'] = 1 / r(vif_`i')
+            if "`sqrvif'"!="" matrix `results3'[1,`j'] = sqrt( r(vif_`i') )
+        }
+        local name "`r(name_`++i')'"
+    }
+//return the results
+    if "`sqrvif'"!="" | "`tolerance'"!="" di as txt _n "added matrices:"
+    else di as txt _n "added matrix:"
+    if "`sqrvif'"!="" {
+        ereturn matrix `prefix'sqrvif = `results3'
+        added_matrix `prefix'sqrvif
+    }
+    if "`tolerance'"!="" {
+        ereturn matrix `prefix'tolerance = `results2'
+        added_matrix `prefix'tolerance
+    }
+    ereturn matrix `prefix'vif = `results'
+    added_matrix `prefix'vif
+end
+
+* 13.
+* -estadd- subroutine: standardized factor change coefficients
+program define estadd_ebsd, eclass
+    version 8.2
+    syntax [, Prefix(name) Replace Quietly ]
+//check availability of e(sample)
+    confirm_esample
+//check e()-names
+    if "`replace'"=="" confirm_new_ename `prefix'ebsd
+//use aweights with -summarize-
+    local wtype `e(wtype)'
+    if "`wtype'"=="pweight" local wtype aweight
+//subpop?
+    local subpop "`e(subpop)'"
+    if "`subpop'"=="" local subpop 1
+//copy coefficients matrix and determine varnames
+    tempname results
+    mat `results' = e(b)
+    local vars: colnames `results'
+//loop over variables: calculate -mean-
+    local j 0
+    foreach var of local vars {
+        local ++j
+        capture confirm_numvar `var'
+        if _rc mat `results'[1,`j'] = .z
+        else {
+            capt su `var' [`wtype'`e(wexp)'] if e(sample) & `subpop'
+            mat `results'[1,`j'] = cond(_rc,.,exp( `results'[1,`j'] * r(sd)))
+        }
+    }
+//return the results
+    ereturn matrix `prefix'ebsd = `results'
+    di _n as txt "added matrix:"
+    added_matrix `prefix'ebsd
+end
+
+* 14.
+* -estadd- subroutine: exponentiated coefficients
+program define estadd_expb, eclass
+    version 8.2
+    syntax [, noCONStant Prefix(name) Replace Quietly ]
+//check e()-names
+    if "`replace'"=="" confirm_new_ename `prefix'expb
+//copy coefficients matrix and determine names of coefficients
+    tempname results
+    mat `results' = e(b)
+    local coefs: colnames `results'
+//loop over coefficients
+    local j 0
+    foreach coef of local coefs {
+        local ++j
+        if `"`constant'"'!="" & `"`coef'"'=="_cons" {
+            mat `results'[1,`j'] = .z
+        }
+        else {
+            mat `results'[1,`j'] = exp(`results'[1,`j'])
+        }
+    }
+//return the results
+    ereturn matrix `prefix'expb = `results'
+    di _n as txt "added matrix:"
+    added_matrix `prefix'expb
+end
+
+* 15.
+* -estadd- subroutine: partial and semi-partial correlations
+program define estadd_pcorr, eclass
+    version 8.2
+    syntax [, semi Prefix(name) Replace Quietly ]
+//check availability of e(sample)
+    confirm_esample
+//check e()-names
+    if "`replace'"=="" {
+        if "`semi'"!="" confirm_new_ename `prefix'spcorr
+        confirm_new_ename `prefix'pcorr
+    }
+//copy coefficients matrix and set to .z
+    tempname results results2
+    matrix `results' = e(b)
+    forv j = 1/`=colsof(`results')' {
+        mat `results'[1,`j'] = .z
+    }
+    local eqs: coleq `results', quoted
+    local eq: word 1 of `eqs'
+    mat `results2' = `results'[1,"`eq':"]
+    local vars: colnames `results2'
+    foreach var of local vars {
+        capt confirm numeric var `var'
+        if !_rc local temp "`temp'`var' "
+    }
+    local vars "`temp'"
+    if "`semi'"!="" mat `results2' = `results'
+    else {
+        mat drop `results2'
+        local results2
+    }
+    local depv: word 1 of `e(depvar)'
+//compute statistics and add to results vector
+    local wtype `e(wtype)'
+    if inlist("`wtype'","pweight","iweight") local wtype aweight
+    _estadd_pcorr_compute `depv' `vars' [`wtype'`e(wexp)'] if e(sample), ///
+     eq(`eq') results(`results') results2(`results2')
+//return the results
+    if "`semi'"!="" {
+        di as txt _n "added matrices:"
+        ereturn matrix `prefix'spcorr = `results2'
+        added_matrix `prefix'spcorr
+    }
+    else di as txt _n "added matrix:"
+    ereturn matrix `prefix'pcorr = `results'
+    added_matrix `prefix'pcorr
+end
+program define _estadd_pcorr_compute // based on pcorr.ado by StataCorp
+                                     // and pcorr2.ado by Richard Williams
+    syntax varlist(min=1) [aw fw] [if], eq(str) results(str) [ results2(str) ]
+    marksample touse
+    tempname hcurrent
+    _est hold `hcurrent', restore
+    quietly reg `varlist' [`weight'`exp'] if `touse'
+    if (e(N)==0 | e(N)>=.) error 2000
+    local NmK = e(df_r)
+    local R2 = e(r2)
+    gettoken depv varlist: varlist
+    foreach var of local varlist {
+        quietly test `var'
+        if r(F)<. {
+            local s "1"
+            if _b[`var']<0 local s "-1"
+            local c = colnumb(`results',"`eq':`var'")
+            mat `results'[1,`c'] = `s' * sqrt(r(F)/(r(F)+`NmK'))
+            if "`results2'"!="" {
+                mat `results2'[1,`c'] = `s' * sqrt(r(F)*((1-`R2')/`NmK'))
+            }
+        }
+    }
+end
+
+* 16.
+* -estadd- subroutine: Likelihood-ratio test
+program define estadd_lrtest, eclass
+    version 8.2
+    local caller : di _caller()
+    syntax anything(id="model") [, Name(name) Prefix(name) Replace Quietly * ]
+    if "`name'"=="" local name lrtest_
+//check e()-names
+    if "`replace'"=="" {
+        confirm_new_ename `prefix'`name'p
+        confirm_new_ename `prefix'`name'chi2
+        confirm_new_ename `prefix'`name'df
+    }
+//compute statistics
+    `quietly' version `caller': lrtest `anything', `options'
+//return the results
+    ereturn scalar `prefix'`name'p = r(p)
+    ereturn scalar `prefix'`name'chi2 = r(chi2)
+    ereturn scalar `prefix'`name'df = r(df)
+    di _n as txt "added scalars:"
+    added_scalar `prefix'`name'p
+    added_scalar `prefix'`name'chi2
+    added_scalar `prefix'`name'df
+end
+
+* 17.
+* -estadd- subroutine: support for -brant- by Long and Freese
+* (see http://www.indiana.edu/~jslsoc/spost.htm)
+program define estadd_brant, eclass
+    version 8.2
+    local caller : di _caller()
+    syntax [ , Prefix(name) Replace Quietly * ]
+    capt findfile brant.ado
+    if _rc {
+        di as error "fitstat.ado from the -spost9_ado- package by Long and Freese required"
+        di as error `"type {stata "net from http://www.indiana.edu/~jslsoc/stata"}"'
+        error 499
+    }
+// check names
+    if "`replace'"=="" {
+        foreach name in brant_chi2 brant_df brant_p brant {
+            confirm_new_ename `prefix'`name'
+        }
+    }
+// compute and return the results
+    `quietly' version `caller': brant, `options'
+    di as txt _n "added scalars:"
+    foreach stat in chi2 df p {
+        ereturn scalar `prefix'brant_`stat' = r(`stat')
+        added_scalar `prefix'brant_`stat'
+    }
+    tempname mat
+    matrix `mat' = r(ivtests)
+    matrix `mat' = `mat''
+    ereturn matrix `prefix'brant = `mat'
+    di as txt _n "added matrix:"
+    added_matrix `prefix'brant _rown
+end
+
+* 18.
+* -estadd- subroutine: support for -fitstat- by Long and Freese
+* (see http://www.indiana.edu/~jslsoc/spost.htm)
+program define estadd_fitstat, eclass
+    version 8.2
+    local caller : di _caller()
+    syntax [ , Prefix(name) Replace Quietly Bic * ]
+    capt findfile fitstat.ado
+    if _rc {
+        di as error "fitstat.ado from the -spost9_ado- package by Long and Freese required"
+        di as error `"type {stata "net from http://www.indiana.edu/~jslsoc/stata"}"'
+        error 499
+    }
+    `quietly' version `caller': fitstat, `bic' `options'
+    local stats: r(scalars)
+    local allstats                                                  ///
+        dev dev_df lrx2 lrx2_df lrx2_p r2_adj r2_mf r2_mfadj r2_ml  ///
+        r2_cu r2_mz r2_ef v_ystar v_error r2_ct r2_ctadj aic aic_n  ///
+        bic bic_p statabic stataaic n_rhs n_parm
+    local stats: list allstats & stats
+    if "`bic'"!="" {
+        local bic aic aic_n bic bic_p statabic stataaic
+        local stats: list bic & stats
+    }
+
+
+// check names
+    if "`replace'"=="" {
+        foreach stat of local stats {
+            if inlist("`stat'", "bic", "aic") local rname `stat'0
+            else local rname `stat'
+            confirm_new_ename `prefix'`rname'
+        }
+    }
+
+// return the results
+    di as txt _n "added scalars:"
+    foreach stat of local stats {
+        if inlist("`stat'", "bic", "aic") local rname `stat'0
+        else local rname `stat'
+        ereturn scalar `prefix'`rname' = r(`stat')
+        added_scalar `prefix'`rname'
+    }
+end
+
+* 19.
+* -estadd- subroutine: support for -listcoef- by Long and Freese
+* (see http://www.indiana.edu/~jslsoc/spost.htm)
+program define estadd_listcoef, eclass
+    version 8.2
+    local caller : di _caller()
+    syntax [anything] [ , Prefix(name) Replace Quietly ///
+     nosd gt lt ADJacent Matrix EXpand * ]
+
+// handle some options and look for e(sample)
+    if `"`matrix'"'!="" {
+        local matrix matrix
+    }
+    if `"`e(cmd)'"'=="slogit" & "`expand'"!="" {
+        di as err "-expand- option not supported"
+        exit 198
+    }
+    confirm_esample
+
+// set some constants
+    local listcoef_matrices  "xs ys std fact facts pct pcts"
+    if "`sd'"=="" local listcoef_matrices "`listcoef_matrices' sdx"
+
+// run listcoef
+    capt findfile listcoef.ado
+    if _rc {
+        di as error "-listcoef- from the -spost9_ado- package by Long and Freese required"
+        di as error `"type {stata "net from http://www.indiana.edu/~jslsoc/stata"}"'
+        error 499
+    }
+    `quietly' version `caller': listcoef `anything' , matrix `gt' `lt' `adjacent' `options'
+
+// check existing e()'s
+    if "`replace'"=="" {
+        confirm_new_ename `prefix'pvalue
+        foreach matrix of local listcoef_matrices {
+            _estadd_listcoef_ChkEName b_`matrix', prefix(`prefix')
+        }
+    }
+
+// grab r()-results and post in e()
+    di as txt _n "added matrices:"
+    if inlist(`"`e(cmd)'"',"mlogit","mprobit") {
+        _estadd_listcoef_AddResToNomModl `listcoef_matrices', prefix(`prefix') `gt' `lt' `adjacent'
+    }
+    else {
+        foreach matrix of local listcoef_matrices {
+            _estadd_listcoef_AddMatToE `matrix', prefix(`prefix')
+        }
+    }
+end
+program define _estadd_listcoef_ChkEName
+    syntax name [, prefix(str) ]
+    capt confirm matrix r(`namelist')
+    if _rc exit
+    confirm_new_ename `prefix'`namelist'
+end
+program define _estadd_listcoef_AddMatToE, eclass
+    syntax name [, prefix(str) ]
+    capt confirm matrix r(b_`namelist')
+    if _rc exit
+    tempname tmp
+    matrix `tmp' = r(b_`namelist')
+    capt confirm matrix r(b2_`namelist')
+    if _rc==0 {
+        local eqnames: coleq e(b), quoted
+        local eqnames: list uniq eqnames
+        local eqname: word 1 of `eqnames'
+        mat coleq `tmp' = `"`eqname'"'
+        tempname tmp2
+        matrix `tmp2' = r(b2_`namelist')
+        local eqname: word 2 of `eqnames'
+        mat coleq `tmp2' = `"`eqname'"'
+        mat `tmp' = `tmp' , `tmp2'
+        mat drop `tmp2'
+    }
+    ereturn matrix `prefix'b_`namelist' = `tmp'
+    added_matrix `prefix'b_`namelist' _rown
+end
+program define _estadd_listcoef_AddResToNomModl, eclass
+    syntax anything(name=listcoef_matrices) [, prefix(str) gt lt ADJacent ]
+    if "`lt'"=="" & "`gt'"=="" {
+        local lt lt
+        local gt gt
+    }
+    local adjacent = "`adjacent'"!=""
+    local lt = "`lt'"!=""
+    local gt = "`gt'"!=""
+
+// outcomes and labels
+    tempname outcomes
+    if `"`e(cmd)'"'=="mlogit" {
+        if c(stata_version) < 9 local type cat
+        else                    local type out
+        mat `outcomes' = e(`type')
+        local noutcomes = colsof(`outcomes')
+        local eqnames `"`e(eqnames)'"'
+        if (`:list sizeof eqnames'<`noutcomes') {
+            local ibase = e(ibase`type')
+        }
+        else local ibase 0
+        forv i = 1/`noutcomes' {
+            if `i'==`ibase' {
+                local outcomelab`i' `"`e(baselab)'"'
+            }
+            else {
+                gettoken eq eqnames : eqnames
+                local outcomelab`i' `"`eq'"'
+            }
+            if `"`outcomelab`i''"'=="" {
+                local outcomelab`i': di `outcomes'[1,`i']
+            }
+        }
+    }
+    else if `"`e(cmd)'"'=="mprobit" {
+        mat `outcomes' = e(outcomes)'
+        local noutcomes = colsof(`outcomes')
+        forv i = 1/`noutcomes' {
+            local outcomelab`i' `"`e(out`i')'"'
+        }
+    }
+    else {
+        di as err `"`e(cmd)' not supported"
+        exit 499
+    }
+
+// collect vectors
+    tempname stats
+    mat `stats' = r(b) \ r(b_z) \ r(b_z) \ r(b_p)
+    forv i = 1/`=colsof(`stats')' {
+        mat `stats'[2,`i'] = `stats'[1,`i'] / `stats'[3,`i']
+    }
+    mat rown `stats' = "b" "se" "z" "P>|z|"
+    local enames "b_raw b_se b_z b_p"
+    foreach matrix of local listcoef_matrices {
+        capt confirm matrix r(b_`matrix')
+        if _rc continue
+        mat `stats' = `stats' \ r(b_`matrix')
+        local enames `"`enames' b_`matrix'"'
+    }
+
+// select/reorder contrasts of interest
+    local contrast "r(contrast)"
+    local ncontrast = colsof(`contrast')
+    tempname stats0 temp
+    matrix rename `stats' `stats0'
+    forv i = 1/`noutcomes' {
+        local out1 = `outcomes'[1, `i']
+        local j 0
+        forv j = 1/`noutcomes' {
+            local out2 = `outcomes'[1, `j']
+            if `out1'==`out2' continue
+            if `adjacent' & abs(`i'-`j')>1 continue
+            if `lt'==0 & `out1'<`out2' continue
+            if `gt'==0 & `out1'>`out2' continue
+            forv l = 1/`ncontrast' {
+                if el(`contrast',1,`l')!=`out1' continue
+                if el(`contrast',2,`l')!=`out2' continue
+                mat `temp' = `stats0'[1..., `l']
+                mat coleq `temp' = `"`outcomelab`i''-`outcomelab`j'"'
+                mat `stats' = nullmat(`stats'), `temp'
+            }
+        }
+    }
+    capt mat drop `stats0'
+
+// post rows to e()
+    local i 0
+    foreach ename of local enames {
+        local ++i
+        mat `temp' = `stats'[`i', 1...]
+        ereturn matrix `prefix'`ename' = `temp'
+        added_matrix `prefix'`ename' _rown
+    }
+end
+
+* 20.
+* -estadd- subroutine: support for -mlogtest- by Long and Freese
+* (see http://www.indiana.edu/~jslsoc/spost.htm)
+program define estadd_mlogtest, eclass
+    version 8.2
+    local caller : di _caller()
+    syntax [anything] [ , Prefix(name) Replace Quietly set(passthru) * ]
+    `quietly' version `caller': mlogtest `anything' , `set' `options'
+    local rmat: r(matrices)
+
+    // check names
+    if `"`replace'"'=="" {
+        foreach m in combine lrcomb {
+            if `:list m in rmat'==0 continue
+            forv r = 1/`=rowsof(r(`m'))' {
+                local cat1 = el(r(`m'),`r',1)
+                local cat2 = el(r(`m'),`r',2)
+                confirm_new_ename `prefix'`m'_`cat1'_`cat2'_chi2
+                confirm_new_ename `prefix'`m'_`cat1'_`cat2'_df
+                confirm_new_ename `prefix'`m'_`cat1'_`cat2'_p
+            }
+        }
+        foreach m in hausman suest smhsiao {
+            if `:list m in rmat'==0 continue
+            forv r = 1/`=rowsof(r(`m'))' {
+                local cat = el(r(`m'),`r',1)
+                confirm_new_ename `prefix'`m'_`cat'_chi2
+                confirm_new_ename `prefix'`m'_`cat'_df
+                confirm_new_ename `prefix'`m'_`cat'_p
+            }
+        }
+        if `"`set'"'!="" {
+            foreach m in wald lrtest {
+                if `:list m in rmat'==0 continue
+                local i 0
+                local r = rownumb(r(`m'),"set_`++i'")
+                while(`r'<.) {
+                    confirm_new_ename `prefix'`m'_set`i'_chi2
+                    confirm_new_ename `prefix'`m'_set`i'_df
+                    confirm_new_ename `prefix'`m'_set`i'_p
+                    local r = rownumb(r(`m'),"set_`++i'")
+                }
+            }
+        }
+        foreach m in wald lrtest {
+            if `:list m in rmat'==0 continue
+            local r .
+            if `"`set'"'!="" local r = rownumb(r(`m'),"set_1")-1
+            if `r'<1 continue
+            confirm_new_ename `prefix'`m'
+       }
+    }
+
+    local di_added_scalars `"di _n as txt "added scalars:"'
+    // combine
+    foreach m in combine lrcomb {
+        if `:list m in rmat'==0 continue
+        `di_added_scalars'
+        local di_added_scalars
+        forv r = 1/`=rowsof(r(`m'))' {
+            local cat1 = el(r(`m'),`r',1)
+            local cat2 = el(r(`m'),`r',2)
+            eret scalar `prefix'`m'_`cat1'_`cat2'_chi2 = el(r(`m'),`r',3)
+            added_scalar `prefix'`m'_`cat1'_`cat2'_chi2
+            eret scalar `prefix'`m'_`cat1'_`cat2'_df   = el(r(`m'),`r',4)
+            added_scalar `prefix'`m'_`cat1'_`cat2'_df
+            eret scalar `prefix'`m'_`cat1'_`cat2'_p    = el(r(`m'),`r',5)
+            added_scalar `prefix'`m'_`cat1'_`cat2'_p
+        }
+    }
+    // iia
+    foreach m in hausman suest smhsiao {
+        if `:list m in rmat'==0 continue
+        `di_added_scalars'
+        local di_added_scalars
+        if "`m'"=="smhsiao" local skip 2
+        else                local skip 0
+        forv r = 1/`=rowsof(r(`m'))' {
+            local cat = el(r(`m'),`r',1)
+            eret scalar `prefix'`m'_`cat'_chi2 = el(r(`m'),`r',2+`skip')
+            added_scalar `prefix'`m'_`cat'_chi2
+            eret scalar `prefix'`m'_`cat'_df   = el(r(`m'),`r',3+`skip')
+            added_scalar `prefix'`m'_`cat'_df
+            eret scalar `prefix'`m'_`cat'_p    = el(r(`m'),`r',4+`skip')
+            added_scalar `prefix'`m'_`cat'_p
+        }
+    }
+
+    // wald/lrtest
+    tempname tmp
+    if `"`set'"'!="" {
+        foreach m in wald lrtest {
+            if `:list m in rmat'==0 continue
+            local i 0
+            local r = rownumb(r(`m'),"set_`++i'")
+            if `r'>=. continue
+            `di_added_scalars'
+            local di_added_scalars
+            while(`r'<.) {
+                eret scalar `prefix'`m'_set`i'_chi2 = el(r(`m'),`r',1)
+                added_scalar `prefix'`m'_set`i'_chi2
+                eret scalar `prefix'`m'_set`i'_df   = el(r(`m'),`r',2)
+                added_scalar `prefix'`m'_set`i'_df
+                eret scalar `prefix'`m'_set`i'_p    = el(r(`m'),`r',3)
+                added_scalar `prefix'`m'_set`i'_p
+                local r = rownumb(r(`m'),"set_`++i'")
+            }
+        }
+    }
+    local di_added_matrices `"di _n as txt "added matrices:"'
+    foreach m in wald lrtest {
+        if `:list m in rmat'==0 continue
+        local r .
+        if `"`set'"'!="" local r = rownumb(r(`m'),"set_1")-1
+        if `r'<1 continue
+        `di_added_matrices'
+        local di_added_matrices
+        mat `tmp' = r(`m')
+        mat `tmp' = `tmp'[1..`r',1...]'
+        eret mat `prefix'`m' = `tmp'
+        added_matrix `prefix'`m' _rown
+    }
+
+end
+
+
+* 21.
+* -estadd- subroutine: support for -prchange- by Long and Freese
+* (see http://www.indiana.edu/~jslsoc/spost.htm)
+program define estadd_prchange
+    version 8.2
+    local caller : di _caller()
+    syntax [anything] [if] [in] [ , Prefix(name) Replace Quietly ///
+        PAttern(str) Binary(str) Continuous(str) NOAvg Avg split SPLIT2(name) ///
+            adapt /// old syntax; now works as synonym for noavg
+        Outcome(passthru) Fromto noBAse * ]
+
+// handle some options
+    if `"`split2'"'!="" local split split
+    if "`split'"!="" & `"`outcome'"'!="" {
+        di as err "split and outcome() not both allowed"
+        exit 198
+    }
+    if "`split'"!="" & `"`avg'`noavg'"'!="" {
+        di as err "split and avg not both allowed"
+        exit 198
+    }
+    if "`avg'"!="" & `"`outcome'"'!="" {
+        di as err "avg and outcome not both allowed"
+        exit 198
+    }
+    if "`avg'"!="" & "`noavg'"!="" {
+        di as err "avg and noavg not both allowed"
+        exit 198
+    }
+    if `"`adapt'"'!=""  local noavg noavg
+    if `:list sizeof binary'>1 | `:list sizeof continuous'>1  error 198
+    estadd_prchange_ExpandType binary `"`binary'"'
+    estadd_prchange_ExpandType continuous `"`continuous'"'
+    if `"`binary'"'==""     local binary 2
+    if `"`continuous'"'=="" local continuous 4
+    if `"`pattern'"'!="" {
+        estadd_prchange_ExpandType pattern `"`pattern'"'
+    }
+
+// check e(sample)
+    confirm_esample
+
+// run prchange
+    capt findfile prchange.ado
+    if _rc {
+        di as error "-prchange- from the -spost9_ado- package by Long and Freese required"
+        di as error `"type {stata "net from http://www.indiana.edu/~jslsoc/stata"}"'
+        error 499
+    }
+    `quietly' version `caller': prchange `anything' `if' `in', `base' `outcome' `fromto' `options'
+
+// determine type of model (ordinal: nomord = 1; nominal: nomord = 2)
+    local nomord = (r(modeltype)=="typical nomord")
+    if inlist(`"`e(cmd)'"',"mlogit","mprobit") local nomord = 2
+    if "`avg'`noavg'"!="" {
+        if `nomord'==0 {
+            di as err "avg not allowed with this model"
+            exit 198
+        }
+    }
+    if !`nomord' & "`split'"!="" {
+        di as err "split not allowed with this model"
+        exit 198
+    }
+
+// determine outcome number (in prchange-returns)
+    if `"`outcome'"'!="" {
+        if `nomord' {
+            forv i = 1/`=colsof(r(catval))' {
+                if el(r(catval), 1, `i') == r(outcome) {
+                    local outcomenum `i'
+                    continue, break
+                }
+            }
+            if "`outcomenum'"=="" { // should never happen
+                di as err `"outcome `outcome' not found"'
+                exit 499
+            }
+        }
+        else {
+            local outcomenum =  colnumb(r(predval), `"`r(outcome)'"')
+        }
+    }
+
+// check names
+    if "`replace'"=="" {
+        if `"`outcome'"'!="" | "`split'"!="" | `nomord'==0 {
+            confirm_new_ename `prefix'predval
+            if `"`outcome'"'!="" | "`split'"!="" {
+                confirm_new_ename `prefix'outcome
+            }
+        }
+        else {
+            forv i = 1/`=colsof(r(catval))' {
+                local theoutcome: di el(r(catval),1,`i')
+                confirm_new_ename `prefix'predval`theoutcome'
+            }
+        }
+        confirm_new_ename `prefix'delta
+        confirm_new_ename `prefix'centered
+        confirm_new_ename `prefix'dc
+        if "`fromto'"!="" {
+            confirm_new_ename `prefix'dcfrom
+            confirm_new_ename `prefix'dcto
+        }
+        if "`nobase'"=="" {
+            confirm_new_ename `prefix'X
+        }
+    }
+
+// grab r()-results and post in e()
+    if "`split'"!="" {
+        if `"`split2'"'=="" {
+            local split2 `"`e(_estadd_estimates_name)'"'
+            if `"`split2'"'=="" {
+                local split2 `"`e(cmd)'"'
+            }
+            local split2 `"`split2'_"'
+        }
+        _estadd_prchange_StoreEachOutc `split2' , nomord(`nomord') ///
+            pattern(`pattern') binary(`binary') continuous(`continuous') ///
+            `base' `fromto' prefix(`prefix')
+    }
+    else {
+        _estadd_prchange_AddStuffToE, nomord(`nomord') outcome(`outcomenum') ///
+            pattern(`pattern') binary(`binary') continuous(`continuous') ///
+            `avg' `noavg' `base' `fromto' prefix(`prefix')
+    }
+end
+program estadd_prchange_ExpandType
+    args name list
+    foreach l of local list {
+        local w = length(`"`l'"')
+        if      `"`l'"'==substr("minmax",1,max(2,`w'))      local type 1
+        else if `"`l'"'==substr("01",1,max(1,`w'))          local type 2
+        else if `"`l'"'==substr("delta",1,max(1,`w'))       local type 3
+        else if `"`l'"'==substr("sd",1,max(1,`w'))          local type 4
+        else if `"`l'"'==substr("margefct",1,max(1,`w'))    local type 5
+        else {
+            di as err `"'`l'' not allowed"'
+            exit 198
+        }
+        local newlist `newlist' `type'
+    }
+    c_local `name' `newlist'
+end
+program define _estadd_prchange_AddStuffToE, eclass
+//      input                            add
+// =========================    ========================================
+// outcome() nomord    opt      change changenm change# predval  outcome
+//   no        0        -         x                      last
+//   yes       0        -         x                       x        x
+//   no       1/2       -                 x       all    all
+//   yes      1/2       -                          x      x        x
+//   no       1/2      avg                x              all
+//   no       1/2     noavg                       all    all
+//  nobase==""  => add X, SD, Min, Max
+//  all models  => add centered, delta
+    syntax , nomord(str) [ pattern(passthru) binary(passthru) continuous(passthru) ///
+        outcome(str) NOAVG avg nobase fromto prefix(str) ] //
+// prepare predval and determine value of outcome
+    if `"`outcome'"'!="" {
+        tempname predv
+        mat `predv' = r(predval)
+        mat `predv' = `predv'[1...,`outcome']
+        if `nomord' {
+            local theoutcome: di el(r(catval),1,`outcome')
+        }
+        else {
+            local theoutcome: colnames `predv'
+        }
+    }
+// add scalars
+    di _n as txt "added scalars:"
+// - predval and outcome
+    local cpredval = colsof(r(predval))
+    if `"`outcome'"'!="" {
+        ereturn scalar `prefix'predval = `predv'[1,1]
+        added_scalar `prefix'predval `"`lab_predval'"'
+        ereturn scalar `prefix'outcome = `theoutcome'
+        added_scalar `prefix'outcome
+    }
+    else if `nomord' { // add all
+        forv i=1/`cpredval' {
+            local theoutcome: di el(r(catval),1,`i')
+            ereturn scalar `prefix'predval`theoutcome' = el(r(predval),1,`i')
+            added_scalar `prefix'predval`theoutcome'
+        }
+    }
+    else { // add last
+        ereturn scalar `prefix'predval = el(r(predval),1,`cpredval')
+        added_scalar `prefix'predval
+    }
+// - delta and centered
+    ereturn scalar `prefix'delta = r(delta)
+    added_scalar `prefix'delta
+    ereturn scalar `prefix'centered = r(centered)
+    added_scalar `prefix'centered
+// add matrices
+    di _n as txt "added matrices:"
+    if `nomord'==0 {
+        if r(modeltype)=="twoeq count" & "`test'"=="" {
+            local eq: coleq e(b)
+            local eq: word 1 of `eq'
+        }
+        _estadd_prchange_PostMat r(change), prefix(`prefix') ///
+            name(dc) `pattern' `binary' `continuous' `fromto' eq(`eq')
+    }
+    else {
+        if `"`outcome'"'=="" {
+            if "`avg'"!="" local nomordmat "r(changemn)"
+            else {
+                tempname nomordmat
+                _estadd_prchange_GatherNomChMat `nomordmat' `noavg'
+            }
+            _estadd_prchange_PostMat `nomordmat', prefix(`prefix') ///
+                name(dc) `pattern' `binary' `continuous' `fromto'
+        }
+        else {
+            if `nomord'==2 {
+                _estadd_prchange_GetEqnmNomModl `theoutcome'
+            }
+            _estadd_prchange_PostMat r(change`theoutcome'), prefix(`prefix') ///
+                name(dc) `pattern' `binary' `continuous' `fromto' eq(`eq')
+        }
+    }
+    if `"`base'"'=="" {
+        _estadd_prchange_PostMat r(baseval), prefix(`prefix') name(X)
+    }
+    if `"`pattern'"'=="" {
+        _estadd_prchange_dcNote, prefix(`prefix') name(dc) `binary' `continuous'
+    }
+end
+program define _estadd_prchange_dcNote
+    syntax [ , prefix(str) name(str) binary(str) continuous(str) ]
+    local res `""{res:minmax} change" "{res:01} change" "{res:delta} change" "{res:sd} change" "{res:margefct}""'
+    local bres: word `binary' of `res'
+    local cres: word `continuous' of `res'
+    di _n as txt `"first row in e(dc) contains:"'
+    di _n `"  `bres' for binary variables"'
+    di    `"  `cres' for continuous variables"'
+end
+program define _estadd_prchange_PostMat, eclass
+    syntax anything, name(str) [ Fromto eq(str) prefix(str) ///
+        pattern(passthru) binary(passthru) continuous(passthru) ]
+    capt confirm matrix `anything'
+    if _rc exit
+    tempname tmp1
+    local nmlist "`name'"
+    matrix `tmp1' = `anything'
+    if `"`eq'"'!="" {
+        mat coleq `tmp1' = `"`eq'"'
+    }
+    if `"`pattern'`binary'`continuous'"'!="" {
+        tempname pattmat
+        _estadd_prchange_Merge `tmp1', pattmat(`pattmat') `pattern' `binary' `continuous' `fromto'
+    }
+    if "`fromto'"!="" {
+        local nmlist "`nmlist' `name'from `name'to"
+        tempname tmp tmp2 tmp3
+        mat rename `tmp1' `tmp'
+        local r = rowsof(`tmp')
+        local i = 1
+        while (`i'<=`r') {
+            if (`r'-`i')>=2 {
+                mat `tmp2' = nullmat(`tmp2') \ `tmp'[`i++',1...] // from
+                mat `tmp3' = nullmat(`tmp3') \ `tmp'[`i++',1...] // to
+            }
+            mat `tmp1' = nullmat(`tmp1') \ `tmp'[`i++',1...]
+        }
+        mat drop `tmp'
+    }
+    local i 0
+    foreach nm of local nmlist {
+        local ++i
+        local rown: rown `tmp`i''
+        mat rown `tmp`i'' = `rown'  // fix problem with leading blanks in equations
+        ereturn matrix `prefix'`nm' = `tmp`i''
+        added_matrix `prefix'`nm' _rown
+    }
+    if `"`pattmat'"'!="" {
+        ereturn matrix `prefix'pattern = `pattmat'
+        added_matrix `prefix'pattern
+    }
+end
+program define _estadd_prchange_Merge
+    syntax name(name=tmp1) [, pattmat(str) pattern(str) binary(str) continuous(str) fromto ]
+    tempname tmp
+    mat rename `tmp1' `tmp'
+    local r = cond("`fromto'"!="", 3, 1)
+    mat `tmp1' = `tmp'[1..`r',1...]*.
+    mat `pattmat' = `tmp'[1,1...]*.
+    local rtot = rowsof(`tmp')
+    mat rown `tmp1' = main
+    mat rown `pattmat' = :type
+    local vars: colnames `tmp1'
+    local eqs: coleq `tmp1', quoted
+    local j 0
+    foreach var of local vars {
+        local ++j
+        gettoken eq eqs : eqs
+        if `"`eq'"'!=`"`lasteq'"' gettoken type rest : pattern
+        else                      gettoken type rest : rest
+        local lasteq `"`eq'"'
+        if `"`type'"'=="" {
+            capt assert `var'==0|`var'==1 if e(sample) & `var'<.
+            if _rc local type `continuous'
+            else   local type `binary'
+        }
+        local ii = (`type'-1)*`r'+1
+        forv i = 1/`r' {
+            if `r'>1 & `i'<3 & `ii'>=`rtot' {
+                mat `tmp1'[`i',`j'] = .z
+            }
+            else {
+                mat `tmp1'[`i',`j'] = `tmp'[`ii++',`j']
+            }
+        }
+        mat `pattmat'[1,`j'] = `type'
+    }
+    mat `tmp1' = `tmp1' \ `tmp'
+end
+program define _estadd_prchange_GatherNomChMat
+    args mat noavg
+    local cmd `"`e(cmd)'"'
+    tempname tmpmat
+    if `"`noavg'"'=="" {
+        mat `tmpmat' = r(changemn)
+        mat coleq `tmpmat' = `"Avg|Chg|"'
+        mat `mat' = `tmpmat'
+    }
+    if `"`cmd'"'=="mlogit" {
+        if c(stata_version) < 9 local outcat cat
+        else local outcat out
+        local k_cat = e(k_`outcat')
+        local eqnames `"`e(eqnames)'"'
+        if `k_cat'>`:list sizeof eqnames' { // no base equation
+            local ibase = e(ibase`outcat')
+            local baselab `"`e(baselab)'"'
+            if `"`baselab'"'=="" {
+                local baselab `"`e(base`outcat')'"'
+            }
+            forv i = 1/`k_cat' {
+                if `i'==`ibase' {
+                    local eq `"`"`baselab'"'"'
+                }
+                else gettoken eq eqnames : eqnames, quotes
+                local temp `"`temp' `eq'"'
+            }
+            local eqnames: list retok temp
+        }
+        local i 0
+        foreach eq of local eqnames {
+            local ++i
+            local theoutcome: di el(e(`outcat'),1,`i')
+            mat `tmpmat' = r(change`theoutcome')
+            mat coleq `tmpmat' = `"`eq'"'
+            mat `mat' = nullmat(`mat'), `tmpmat'
+        }
+    }
+    else if `"`cmd'"'=="mprobit" {
+        local eqnames `"`e(outeqs)'"'
+        local i 0
+        foreach eq of local eqnames {
+            local ++i
+            local theoutcome: di el(e(outcomes),`i',1)
+            mat `tmpmat' = r(change`theoutcome')
+            mat coleq `tmpmat' = `"`eq'"'
+            mat `mat' = nullmat(`mat'), `tmpmat'
+        }
+    }
+    else { // ordered models
+        local eqnames : colnames r(catval)
+        local i 0
+        foreach eq of local eqnames {
+            local ++i
+            local theoutcome: di el(r(catval),1,`i')
+            mat `tmpmat' = r(change`theoutcome')
+            mat coleq `tmpmat' = `"`eq'"'
+            mat `mat' = nullmat(`mat'), `tmpmat'
+        }
+    }
+end
+program define _estadd_prchange_GetEqnmNomModl
+    args theoutcome
+    local cmd `"`e(cmd)'"'
+    if `"`cmd'"'=="mlogit" {
+        if c(stata_version) < 9 local outcat cat
+        else local outcat out
+        local k_cat = e(k_`outcat')
+        local eqnames `"`e(eqnames)'"'
+        local nobase = (`k_cat'>`:list sizeof eqnames')
+        if `nobase' {
+            local ibase = e(ibase`outcat')
+            local baselab `"`e(baselab)'"'
+        }
+        forv i = 1/`k_cat' {
+            if `nobase' {
+                if `i'==`ibase' {
+                    local eq `"`baselab'"'
+                }
+                else gettoken eq eqnames : eqnames
+            }
+            else gettoken eq eqnames : eqnames
+            if el(e(`outcat'),1,`i')==`theoutcome' {
+                local value `"`eq'"'
+                continue, break
+            }
+        }
+    }
+    else if `"`cmd'"'=="mprobit" {
+        local eqnames `"`e(outeqs)'"'
+        local i 0
+        foreach eq of local eqnames {
+            if el(e(outcomes),`++i',1)==`theoutcome' {
+                local value `"`eq'"'
+                continue, break
+            }
+        }
+    }
+    if `"`value'"'=="" local value `theoutcome'
+    c_local eq `"`value'"'
+end
+program define _estadd_prchange_StoreEachOutc // only for nomord models
+    syntax anything [, nomord(str) nobase fromto prefix(passthru) ///
+        pattern(passthru) binary(passthru) continuous(passthru) ]
+// backup estimates
+    tempname hcurrent
+    _est hold `hcurrent', copy restore estsystem
+    if `"`nomord'"'=="2" {  // backup b and V
+        tempname b bi V Vi
+        mat `b' = e(b)
+        mat `V' = e(V)
+    }
+// cycle through categories
+    local k_kat = colsof(r(predval))
+    tempname catval catvali
+    mat `catval' = r(catval)
+    forv i=1/`k_kat' {
+        mat `catvali' = `catval'[1...,`i']
+        local catlabi: colnames `catvali'
+        local catnumi: di `catvali'[1,1]
+        if `"`nomord'"'=="2" {
+            _estadd_prchange_GetEqnmNomModl `catnumi'
+            if colnumb(`b', `"`eq':"')<. {
+                mat `bi' = `b'[1...,`"`eq':"']
+                mat `Vi' = `V'[`"`eq':"',`"`eq':"']
+            }
+            else {  // base outcome; get first eq and set zero
+                local tmp : coleq `b', q
+                gettoken tmp : tmp
+                mat `bi' = `b'[1...,`"`tmp':"'] * 0
+                mat `Vi' = `V'[`"`tmp':"',`"`tmp':"'] * 0
+            }
+            mat coleq `bi' = ""
+            mat coleq `Vi' = ""
+            mat roweq `Vi' = ""
+            erepost b=`bi' V=`Vi'
+        }
+        `qui' _estadd_prchange_AddStuffToE, nomord(1) outcome(`i')  ///
+            `base' `fromto' `pattern' `binary' `continuous' `prefix'
+        `qui' di ""
+        local qui qui
+        _eststo `anything'`catnumi', title(`"`catlabi'"') // store without e(sample)
+        di as txt "results for outcome " as res `catnumi' ///
+         as txt " stored as " as res "`anything'`catnumi'"
+    }
+// retore estimates
+    _est unhold `hcurrent'
+end
+
+* 22.
+* -estadd- subroutine: support for -prvalue- by Long and Freese
+* (see http://www.indiana.edu/~jslsoc/spost.htm)
+program define estadd_prvalue, eclass
+    version 9.2
+    local caller : di _caller()
+    syntax [anything] [if] [in] [ , Prefix(passthru) Replace Quietly ///
+        LABel(str) Title(passthru) swap Diff * ]
+
+// post
+    if `"`anything'"'!="" {
+        gettoken post post2 : anything
+        if `"`post'"'!="post" {
+            di as err `"`post' not allowed"'
+            exit 198
+        }
+        else if `"`label'"'!="" {
+            di as err "label() not allowed"
+            exit 198
+        }
+        _estadd_prvalue_Post `post2' `if' `in', `prefix' `replace' `quietly' ///
+            `title' `swap' `diff' `options'
+        exit
+    }
+    else if `"`title'"'!="" {
+        di as err "title() not allowed"
+        exit 198
+    }
+    else if "`swap'"!="" {
+        di as err "swap not allowed"
+        exit 198
+    }
+
+// look for e(sample)
+    confirm_esample
+
+// run prvalue
+    capt findfile prvalue.ado
+    if _rc {
+        di as error "-prvalue- from the -spost9_ado- package by Long and Freese required"
+        di as error `"type {stata "net from http://www.indiana.edu/~jslsoc/stata"}"'
+        error 499
+    }
+    `quietly' version `caller': prvalue `if' `in', `diff' `options'
+
+// append?
+    capture confirm existence `e(_estadd_prvalue)'
+    local append = (_rc==0) & ("`replace'"=="")
+    tempname prvalue prvalue_x prvalue_x2
+    if `append' {
+        mat `prvalue'   = e(_estadd_prvalue)
+        mat `prvalue_x' = e(_estadd_prvalue_x)
+        capt mat `prvalue_x2' = e(_estadd_prvalue_x2)
+        local ires = rowsof(`prvalue') + 1
+    }
+    else local ires 1
+    if `"`label'"'=="" {
+        local label "pred`ires'"
+    }
+    else {
+        local label = substr(`"`label'"', 1, 30)  // 30 characters max
+        local problemchars `": . `"""'"'
+        foreach char of local problemchars {
+            local label: subinstr local label `"`char'"' "_", all
+        }
+    }
+
+// collect results
+    tempname pred
+    mat `pred' = r(pred)
+    if `"`diff'"'!="" {
+        _estadd_prvalue_GetRidOfD `pred'
+    }
+    _estadd_prvalue_ReshapePred `pred', label(`label')
+    _estadd_prvalue_AddPred `prvalue' `pred' `append'
+    _estadd_prvalue_AddX `prvalue_x', label(`label')
+    capture confirm matrix r(x2)
+    local hasx2 = _rc==0
+    if `hasx2' {
+        _estadd_prvalue_AddX `prvalue_x2', label(`label') two
+    }
+
+// post in e()
+    di as txt _n cond(`append',"updated","added") " matrices:"
+    ereturn matrix _estadd_prvalue = `prvalue'
+    added_matrix _estadd_prvalue
+    ereturn matrix _estadd_prvalue_x = `prvalue_x'
+    added_matrix _estadd_prvalue_x
+    if `hasx2' {
+        ereturn matrix _estadd_prvalue_x2 = `prvalue_x2'
+        added_matrix _estadd_prvalue_x2
+    }
+end
+program _estadd_prvalue_GetRidOfD
+    args pred
+    local coln: colnames `pred'
+    local firstcol: word 1 of `coln'
+    local nfirstcol = substr("`firstcol'",2,.)
+    local coln : subinstr local coln "`firstcol'" "`nfirstcol'" , word
+    mat coln `pred' = `coln'
+end
+program _estadd_prvalue_ReshapePred
+    syntax anything, label(str)
+    tempname tmp res
+    local r = rowsof(`anything')
+    forv i=1/`r' {
+        mat `tmp' = `anything'[`i',1...]
+        local nm: rownames `tmp'
+        mat coleq `tmp' = `"`nm'"'
+        mat `res' = nullmat(`res'), `tmp'
+    }
+    mat rown `res' = `"`label'"'
+    mat `anything' = `res'
+end
+program _estadd_prvalue_AddPred
+    args prvalue pred append
+    if `append' {
+        local coln1: colfullnames `prvalue'
+        local coln2: colfullnames `pred'
+        if `"`coln1'"'!=`"`coln2'"' {
+            di as err "incompatible prvalue results"
+            exit 498
+        }
+    }
+    mat `prvalue' = nullmat(`prvalue') \ `pred'
+end
+program  _estadd_prvalue_AddX
+    syntax anything, label(str) [ two ]
+    if "`two'"!="" local two 2
+    tempname tmp
+    mat `tmp' = r(x`two')
+    mat rown `tmp' = `"`label'"'
+    mat `anything' = nullmat(`anything') \ `tmp'
+end
+program _estadd_prvalue_Post, eclass
+    syntax [name(name=post2)] [ , Prefix(name) Replace Quietly ///
+        Title(passthru) swap ]
+    capture confirm matrix e(_estadd_prvalue)
+    if _rc {
+        di as err "prvalue results not found"
+        exit 498
+    }
+// backup estimates
+    tempname hcurrent
+    _est hold `hcurrent', copy restore estsystem
+    local cmd = e(cmd)
+    local depvar = e(depvar)
+    local N = e(N)
+    local estname `"`e(_estadd_estimates_name)'"'
+
+// get results
+    tempname prvalue prvalue_x prvalue_x2
+    mat `prvalue' = e(_estadd_prvalue)
+    mat `prvalue_x' = e(_estadd_prvalue_x)
+    capture confirm matrix e(_estadd_prvalue_x2)
+    local hasx2 = _rc==0
+    if `hasx2' {
+        mat `prvalue_x2' = e(_estadd_prvalue_x2)
+    }
+
+// return prvalues
+    tempname tmp tmp2 b se
+    if "`swap'"=="" {
+        local eqs: coleq `prvalue', q
+        local eqs: list uniq eqs
+        foreach eq of local eqs {
+            mat `tmp' = `prvalue'[1...,`"`eq':"']
+            mat `tmp2' = `tmp'[1...,1]'
+            mat coleq `tmp2' = `"`eq'"'
+            mat roweq `tmp2' = ""
+            mat `b' = nullmat(`b'), `tmp2'
+            mat `tmp2' = `tmp'[1...,`"`eq':SE"']'
+            mat coleq `tmp2' = `"`eq'"'
+            mat roweq `tmp2' = ""
+            mat `se' = nullmat(`se'), `tmp2'
+        }
+        mat drop `tmp' `tmp2'
+    }
+    else {
+        local r = rowsof(`prvalue')
+        local c = colsof(`prvalue')
+        local coln: colnames `prvalue'
+        local eqs: coleq `prvalue', q
+        mat coln `prvalue' = `eqs'
+        mat coleq `prvalue' = `coln'
+        local coln: list uniq coln
+        local ncol: list sizeof coln
+        local icol: list posof "SE" in coln
+        forv i=1/`r' {
+            mat `tmp' = `prvalue'[`i',1...]
+            local labl : rownames `tmp'
+            forv j=1(`ncol')`c' {
+                mat `tmp2' = nullmat(`tmp2'), `tmp'[1...,`j']
+            }
+            mat coleq `tmp2' = `"`labl'"'
+            mat `b' = nullmat(`b'), `tmp2'
+            mat drop `tmp2'
+            forv j=`icol'(`ncol')`c' {
+                mat `tmp2' = nullmat(`tmp2'), `tmp'[1...,`j']
+            }
+            mat coleq `tmp2' = `"`labl'"'
+            mat `se' = nullmat(`se'), `tmp2'
+            mat drop `tmp2'
+        }
+        mat drop `tmp'
+    }
+    ereturn post `b', obs(`N')
+    ereturn local model "`cmd'"
+    ereturn local cmd "estadd_prvalue"
+    ereturn local depvar "`depvar'"
+    di as txt _n "scalars:"
+    added_scalar N
+    di as txt _n "macros:"
+    added_macro depvar
+    added_macro cmd
+    added_macro model
+    added_macro properties
+    di as txt _n "matrices:"
+    added_matrix b "predictions"
+    ereturn matrix se = `se'
+    added_matrix se "standard errors"
+    local istat 0
+    foreach stat in LB UB Category Cond {
+        local elabel: word `++istat' of "lower CI bounds" "upper CI bounds" ///
+            "outcome values" "conditional predictions"
+        if "`swap'"=="" {
+            foreach eq of local eqs {
+                local colnumb = colnumb(`prvalue',`"`eq':`stat'"')
+                if `colnumb'>=. continue
+                mat `tmp2' = `prvalue'[1...,`colnumb']'
+                mat coleq `tmp2' = `"`eq'"'
+                mat roweq `tmp2' = ""
+                mat `tmp' = nullmat(`tmp'), `tmp2'
+            }
+        }
+        else {
+            local icol: list posof "`stat'" in coln
+            if `icol'==0 continue
+            forv i=1/`r' {
+                mat `tmp2' = `prvalue'[`i',1...]
+                local labl : rownames `tmp2'
+                mat coleq `tmp2' = `"`labl'"'
+                forv j=`icol'(`ncol')`c' {
+                    mat `tmp' = nullmat(`tmp'), `tmp2'[1...,`j']
+                }
+            }
+            mat drop `tmp2'
+        }
+        capt confirm matrix `tmp'
+        if _rc==0 {
+            ereturn matrix `prefix'`stat' = `tmp'
+            added_matrix `prefix'`stat' "`elabel'"
+        }
+    }
+
+// return x-values
+    matrix `prvalue_x' = `prvalue_x''
+    ereturn matrix `prefix'X = `prvalue_x'
+    added_matrix `prefix'X _rown
+    if `hasx2' {
+        matrix `prvalue_x2' = `prvalue_x2''
+        ereturn matrix `prefix'X2 = `prvalue_x2'
+        added_matrix `prefix'X2 _rown
+    }
+
+// store
+    if "`post2'"!="" {
+        _eststo `estname'`post2', `title'
+        di as txt _n "results stored as " as res "`estname'`post2'"
+    }
+    else if `"`title'"'!="" {
+        estimates change ., `title'
+    }
+
+// retore estimates
+    if "`post2'"!="" {
+        _est unhold `hcurrent'
+    }
+    else {
+        _est unhold `hcurrent', not
+    }
+end
+
+* 23.
+* -estadd- subroutine: support for -asprvalue- by Long and Freese
+* (see http://www.indiana.edu/~jslsoc/spost.htm)
+program define estadd_asprvalue, eclass
+    version 9.2
+    local caller : di _caller()
+    syntax [anything] [ , Prefix(passthru) Replace Quietly ///
+        LABel(str) Title(passthru) swap * ]
+
+// post
+    if `"`anything'"'!="" {
+        gettoken post post2 : anything
+        if `"`post'"'!="post" {
+            di as err `"`post' not allowed"'
+            exit 198
+        }
+        else if `"`label'"'!="" {
+            di as err "label() not allowed"
+            exit 198
+        }
+        _estadd_asprvalue_Post `post2' , `prefix' `replace' `quietly' ///
+            `title' `swap' `options'
+        exit
+    }
+    else if `"`title'"'!="" {
+        di as err "title() not allowed"
+        exit 198
+    }
+    else if "`swap'"!="" {
+        di as err "swap not allowed"
+        exit 198
+    }
+
+// look for e(sample)
+    confirm_esample
+
+// run prvalue
+    capt findfile asprvalue.ado
+    if _rc {
+        di as error "-asprvalue- from the -spost9_ado- package by Long and Freese required"
+        di as error `"type {stata "net from http://www.indiana.edu/~jslsoc/stata"}"'
+        error 499
+    }
+    `quietly' version `caller': asprvalue , `options'
+
+// append?
+    capture confirm existence `e(_estadd_asprval)'
+    local append = (_rc==0) & ("`replace'"=="")
+    tempname asprval asprval_asv asprval_csv
+    if `append' {
+        mat `asprval'          = e(_estadd_asprval)
+        capt mat `asprval_asv' = e(_estadd_asprval_asv)
+        capt mat `asprval_csv' = e(_estadd_asprval_csv)
+        local ires = rowsof(`asprval') + 1
+    }
+    else local ires 1
+    if `"`label'"'=="" {
+        local label "pred`ires'"
+    }
+    else {
+        local label = substr(`"`label'"', 1, 30)  // 30 characters max
+        local problemchars `": . `"""'"'
+        foreach char of local problemchars {
+            local label: subinstr local label `"`char'"' "_", all
+        }
+    }
+
+// collect results
+    tempname res
+    mat `res' = r(p)
+    _estadd_asprvalue_Reshape `res', label(`label')
+    _estadd_asprvalue_Add `asprval' `res' `append'
+    capture confirm matrix r(asv)
+    local hasasv = _rc==0
+    if `hasasv' {
+        mat `res' = r(asv)
+        _estadd_asprvalue_Reshape `res', label(`label')
+        _estadd_asprvalue_Add `asprval_asv' `res' `append'
+    }
+    capture confirm matrix r(csv)
+    local hascsv = _rc==0
+    if `hascsv' {
+        _estadd_asprvalue_AddCsv `asprval_csv', label(`label')
+    }
+
+// post in e()
+    di as txt _n cond(`append',"updated","added") " matrices:"
+    ereturn matrix _estadd_asprval = `asprval'
+    added_matrix _estadd_asprval
+    if `hasasv' {
+        ereturn matrix _estadd_asprval_asv = `asprval_asv'
+        added_matrix _estadd_asprval_asv
+    }
+    if `hascsv' {
+        ereturn matrix _estadd_asprval_csv = `asprval_csv'
+        added_matrix _estadd_asprval_csv
+    }
+end
+program _estadd_asprvalue_Reshape
+    syntax anything, label(str)
+    tempname tmp res
+    local r = rowsof(`anything')
+    forv i=1/`r' {
+        mat `tmp' = `anything'[`i',1...]
+        local nm: rownames `tmp'
+        mat coleq `tmp' = `"`nm'"'
+        mat `res' = nullmat(`res'), `tmp'
+    }
+    mat rown `res' = `"`label'"'
+    mat `anything' = `res'
+end
+program _estadd_asprvalue_Add
+    args master using append
+    if `append' {
+        local coln1: colfullnames `master'
+        local coln2: colfullnames `using'
+        if `"`coln1'"'!=`"`coln2'"' {
+            di as err "incompatible asprvalue results"
+            exit 498
+        }
+    }
+    mat `master' = nullmat(`master') \ `using'
+end
+program _estadd_asprvalue_AddCsv
+    syntax anything, label(str)
+    tempname tmp
+    mat `tmp' = r(csv)
+    mat rown `tmp' = `"`label'"'
+    mat `anything' = nullmat(`anything') \ `tmp'
+end
+program _estadd_asprvalue_Post, eclass
+    syntax [name(name=post2)] [ , Prefix(name) Replace Quietly ///
+        Title(passthru) swap ]
+    capture confirm matrix e(_estadd_asprval)
+    if _rc {
+        di as err "asprvalue results not found"
+        exit 498
+    }
+
+// backup estimates
+    tempname hcurrent
+    _est hold `hcurrent', copy restore estsystem
+    local cmd = e(cmd)
+    local depvar = e(depvar)
+    local N = e(N)
+    local estname `"`e(_estadd_estimates_name)'"'
+
+// get results
+    tempname asprval asprval_asv asprval_csv
+    mat `asprval' = e(_estadd_asprval)
+    capture confirm matrix e(_estadd_asprval_asv)
+    local hasasv = _rc==0
+    if `hasasv' {
+        mat `asprval_asv' = e(_estadd_asprval_asv)
+    }
+    capture confirm matrix e(_estadd_asprval_csv)
+    local hascsv = _rc==0
+    if `hascsv' {
+        mat `asprval_csv' = e(_estadd_asprval_csv)
+    }
+
+// return predictions
+    tempname tmp tmp2 b
+    if "`swap'"=="" {
+        local eqs: coleq `asprval', q
+        local eqs: list uniq eqs
+        foreach eq of local eqs {
+            mat `tmp' = `asprval'[1...,`"`eq':"']
+            mat `tmp2' = `tmp'[1...,1]'
+            mat coleq `tmp2' = `"`eq'"'
+            mat roweq `tmp2' = ""
+            mat `b' = nullmat(`b'), `tmp2'
+        }
+        mat drop `tmp' `tmp2'
+    }
+    else {
+        local r = rowsof(`asprval')
+        local coln: colnames `asprval'
+        local eqs: coleq `asprval', q
+        mat coln `asprval' = `eqs'
+        forv i=1/`r' {
+            mat `tmp' = `asprval'[`i',1...]
+            local labl : rownames `tmp'
+            mat coleq `tmp' = `"`labl'"'
+            mat `b' = nullmat(`b'), `tmp'
+        }
+        mat drop `tmp'
+    }
+    ereturn post `b', obs(`N')
+    ereturn local model "`cmd'"
+    ereturn local cmd "estadd_asprvalue"
+    ereturn local depvar "`depvar'"
+    di as txt _n "scalars:"
+    added_scalar N
+    di as txt _n "macros:"
+    added_macro depvar
+    added_macro cmd
+    added_macro model
+    added_macro properties
+    di as txt _n "matrices:"
+    added_matrix b "predictions"
+
+// return asv-values
+    if `hasasv' {
+        if "`swap'"=="" {
+            local vars: coleq `asprval_asv'
+            local vars: list uniq vars
+            local cats: colnames `asprval_asv'
+            local cats: list uniq cats
+            foreach var of local vars {
+                foreach cat of local cats {
+                    mat `tmp2' = `asprval_asv'[1...,`"`var':`cat'"']'
+                    mat coleq `tmp2' = `"`cat'"'
+                    mat roweq `tmp2' = ""
+                    mat `tmp' = nullmat(`tmp'), `tmp2'
+                }
+                mat rown `tmp' = `"`var'"'
+                mat `b' = nullmat(`b') \ `tmp'
+                mat drop `tmp'
+            }
+        }
+        else {
+            local r = rowsof(`asprval_asv')
+            local vars: coleq `asprval_asv'
+            local vars: list uniq vars
+            forv i=1/`r' {
+                foreach var of local vars {
+                    mat `tmp2' = `asprval_asv'[`i',`"`var':"']
+                    local lbl: rownames `tmp2'
+                    mat coleq `tmp2' = `"`lbl'"'
+                    mat rown `tmp2' = `"`var'"'
+                    mat `tmp' = nullmat(`tmp') \ `tmp2'
+                }
+                mat `b' = nullmat(`b') , `tmp'
+                mat drop `tmp'
+            }
+        }
+        ereturn matrix `prefix'asv = `b'
+        added_matrix `prefix'asv _rown
+    }
+// return csv-values
+    if `hascsv' {
+        matrix `asprval_csv' = `asprval_csv''
+        ereturn matrix `prefix'csv = `asprval_csv'
+        added_matrix `prefix'csv _rown
+    }
+
+// store
+    if "`post2'"!="" {
+        _eststo `estname'`post2', `title'
+        di as txt _n "results stored as " as res "`estname'`post2'"
+    }
+    else if `"`title'"'!="" {
+        estimates change ., `title'
+    }
+
+// retore estimates
+    if "`post2'"!="" {
+        _est unhold `hcurrent'
+    }
+    else {
+        _est unhold `hcurrent', not
+    }
+end
+
+* 24. estadd_margins
+program define estadd_margins, eclass
+    version 11.0
+    local caller : di _caller()
+    syntax [ anything(everything equalok)] [fw aw iw pw] [, Prefix(name) Replace Quietly * ]
+
+// set default prefix
+    if "`prefix'"=="" local prefix "margins_"
+
+// compute and return the results
+    if `"`weight'`exp'"'!="" local wgtexp `"[`weight'`exp']"'
+    `quietly' version `caller': margins `anything' `wgtexp', `options'
+
+// check names
+    local rscalars: r(scalars)
+    local rmacros: r(macros)
+    local rmatrices: r(matrices)
+    local rmatrices: subinstr local rmatrices "V" "se", word
+    if "`replace'"=="" {
+        foreach nmlist in rscalars rmacros rmatrices  {
+            foreach name of local `nmlist' {
+                confirm_new_ename `prefix'`name'
+            }
+        }
+    }
+
+// add results
+    di as txt _n "added scalars:"
+    foreach name of local rscalars {
+        ereturn scalar `prefix'`name' = r(`name')
+        added_scalar `prefix'`name'
+    }
+    di as txt _n "added macros:"
+    foreach name of local rmacros {
+        ereturn local `prefix'`name' `"`r(`name')'"'
+        added_macro `prefix'`name'
+    }
+    di as txt _n "added matrices:"
+    tempname tmpmat
+    foreach name of local rmatrices {
+        if "`name'"=="se" {
+            mat `tmpmat' = vecdiag(r(V))
+            forv i = 1/`=colsof(`tmpmat')' {
+                mat `tmpmat'[1,`i'] = sqrt(`tmpmat'[1,`i'])
+            }
+        }
+        else {
+            mat `tmpmat' = r(`name')
+        }
+        eret matrix `prefix'`name' = `tmpmat'
+        added_matrix `prefix'`name'
+    }
+end
+
+* 99.
+* copy of erepost.ado, version 1.0.1, Ben Jann, 30jul2007
+* used by estadd_listcoef and estadd_prchange
+prog erepost, eclass
+    version 8.2
+    syntax [anything(equalok)] [, cmd(str) noEsample Esample2(varname) REName ///
+        Obs(passthru) Dof(passthru) PROPerties(passthru) * ]
+    if "`esample'"!="" & "`esample2'"!="" {
+        di as err "only one allowed of noesample and esample()"
+        exit 198
+    }
+// parse [b = b] [V = V]
+    if `"`anything'"'!="" {
+        tokenize `"`anything'"', parse(" =")
+        if `"`7'"'!="" error 198
+        if `"`1'"'=="b" {
+            if `"`2'"'=="=" & `"`3'"'!="" {
+                local b `"`3'"'
+                confirm matrix `b'
+            }
+            else error 198
+            if `"`4'"'=="V" {
+                if `"`5'"'=="=" & `"`6'"'!="" {
+                    local v `"`6'"'
+                    confirm matrix `b'
+                }
+                else error 198
+            }
+            else if `"`4'"'!="" error 198
+        }
+        else if `"`1'"'=="V" {
+            if `"`4'"'!="" error 198
+            if `"`2'"'=="=" & `"`3'"'!="" {
+                local v `"`3'"'
+                confirm matrix `v'
+            }
+            else error 198
+        }
+        else error 198
+    }
+//backup existing e()'s
+    if "`esample2'"!="" {
+        local sample "`esample2'"
+    }
+    else if "`esample'"=="" {
+        tempvar sample
+        gen byte `sample' = e(sample)
+    }
+    local emacros: e(macros)
+    if `"`properties'"'!="" {
+        local emacros: subinstr local emacros "properties" "", word
+    }
+    foreach emacro of local emacros {
+        local e_`emacro' `"`e(`emacro')'"'
+    }
+    local escalars: e(scalars)
+    if `"`obs'"'!="" {
+        local escalars: subinstr local escalars "N" "", word
+    }
+    if `"`dof'"'!="" {
+        local escalars: subinstr local escalars "df_r" "", word
+    }
+    foreach escalar of local escalars {
+        tempname e_`escalar'
+        scalar `e_`escalar'' = e(`escalar')
+    }
+    local ematrices: e(matrices)
+    if "`b'"=="" & `:list posof "b" in ematrices' {
+        tempname b
+        mat `b' = e(b)
+    }
+    if "`v'"=="" & `:list posof "V" in ematrices' {
+        tempname v
+        mat `v' = e(V)
+    }
+    local bV "b V"
+    local ematrices: list ematrices - bV
+    foreach ematrix of local ematrices {
+        tempname e_`ematrix'
+        matrix `e_`ematrix'' = e(`ematrix')
+    }
+// rename
+    if "`b'"!="" & "`v'"!="" & "`rename'"!="" {
+        local eqnames: coleq `b', q
+        local vnames: colnames `b'
+        mat coleq `v' = `eqnames'
+        mat coln `v' = `vnames'
+        mat roweq `v' = `eqnames'
+        mat rown `v' = `vnames'
+    }
+// post results
+    if "`esample'"=="" {
+        eret post `b' `v', esample(`sample') `obs' `dof' `properties' `options'
+    }
+    else {
+        eret post `b' `v', `obs' `dof' `properties' `options'
+    }
+    foreach emacro of local emacros {
+        eret local `emacro' `"`e_`emacro''"'
+    }
+    if `"`cmd'"'!="" {
+        eret local cmd `"`cmd'"'
+    }
+    foreach escalar of local escalars {
+        eret scalar `escalar' = scalar(`e_`escalar'')
+    }
+    foreach ematrix of local ematrices {
+        eret matrix `ematrix' = `e_`ematrix''
+    }
+end
diff --git a/Modules/ado/plus/e/estadd.hlp b/Modules/ado/plus/e/estadd.hlp
new file mode 100644
index 0000000..b9b1f16
--- /dev/null
+++ b/Modules/ado/plus/e/estadd.hlp
@@ -0,0 +1,935 @@
+{smcl}
+{* 08oct2009}{...}
+{hi:help estadd}{right:also see: {helpb esttab}, {helpb estout}, {helpb eststo}, {helpb estpost}}
+{right: {browse "http://repec.org/bocode/e/estout"}}
+{hline}
+
+{title:Title}
+
+{p 4 4 2}{hi:estadd} {hline 2} Add results to (stored) estimates
+
+
+{title:Syntax}
+
+{p 8 15 2}
+{cmd:estadd} {it:{help estadd##subcommands:subcommand}} [{cmd:,}
+{it:{help estadd##opts:options}} ] [ {cmd::} {it:namelist} ]
+
+
+    where {it:namelist} is {cmd:_all} | {cmd:*} | {it:name} [{it:name} ...]
+
+{marker subcommands}
+    {it:subcommands}{col 26}description
+    {hline 64}
+    Elementary
+      {helpb estadd##local:{ul:loc}al} {it:name ...}{col 26}{...}
+add a macro
+      {helpb estadd##scalar:{ul:sca}lar} {it:name} {cmd:=} {it:exp}{col 26}{...}
+add a scalar
+      {helpb estadd##matrix:{ul:mat}rix} {it:name} {cmd:=} {it:mat}{col 26}{...}
+add a matrix
+      {helpb estadd##rreturn:r({it:name})}{col 26}{...}
+add contents of {cmd:r(}{it:name}{cmd:)} (matrix or scalar)
+
+    Statistics for each
+    coefficient
+      {helpb estadd##beta:beta}{col 26}{...}
+standardized coefficients
+      {helpb estadd##vif:vif}{col 26}{...}
+variance inflation factors (after {cmd:regress})
+      {helpb estadd##pcorr:pcorr}{col 26}{...}
+partial (and semi-partial) correlations
+      {helpb estadd##expb:expb}{col 26}{...}
+exponentiated coefficients
+      {helpb estadd##ebsd:ebsd}{col 26}{...}
+standardized factor change coefficients
+      {helpb estadd##mean:mean}{col 26}{...}
+means of regressors
+      {helpb estadd##sd:sd}{col 26}{...}
+standard deviations of regressors
+      {helpb estadd##summ:summ}{col 26}{...}
+various descriptives of the regressors
+
+    Summary statistics
+      {helpb estadd##coxsnell:coxsnell}{col 26}{...}
+Cox & Snell's pseudo R-squared
+      {helpb estadd##nagelkerke:nagelkerke}{col 26}{...}
+Nagelkerke's pseudo R-squared
+      {helpb estadd##lrtest:lrtest} {it:model}{col 26}{...}
+likelihood-ratio test
+      {helpb estadd##ysumm:ysumm}{col 26}{...}
+descriptives of the dependent variable
+
+    Other
+      {helpb estadd##margins:margins}{col 26}{...}
+add results from {cmd:margins} (Stata 11)
+
+    {help estadd##spost:SPost}
+      {helpb estadd##brant:brant}{col 26}{...}
+add results from {cmd:brant} (if installed)
+      {helpb estadd##fitstat:fitstat}{col 26}{...}
+add results from {cmd:fitstat} (if installed)
+      {helpb estadd##listcoef:listcoef}{col 26}{...}
+add results from {cmd:listcoef} (if installed)
+      {helpb estadd##mlogtest:mlogtest}{col 26}{...}
+add results from {cmd:mlogtest} (if installed)
+      {helpb estadd##prchange:prchange}{col 26}{...}
+add results from {cmd:prchange} (if installed)
+      {helpb estadd##prvalue:prvalue}{col 26}{...}
+add results from {cmd:prvalue} (if installed)
+      {helpb estadd##asprvalue:asprvalue}{col 26}{...}
+add results from {cmd:asprvalue} (if installed)
+    {hline 64}
+
+{marker opts}
+    {it:{help estadd##options:options}}{col 26}description
+    {hline 64}
+      {cmdab:r:eplace}{col 26}{...}
+permit overwriting existing {cmd:e()}'s
+      {cmdab:p:refix(}{it:string}{cmd:)}{col 26}{...}
+specify prefix for names of added results
+      {cmdab:q:uietly}{col 26}{...}
+suppress output from subcommand (if any)
+      {it:subcmdopts}{col 26}{...}
+subcommand specific options
+    {hline 64}
+
+
+{title:Description}
+
+{p 4 4 2}
+{cmd:estadd} adds additional results to the {cmd:e()}-returns of an
+estimation command (see help {help estcom}, help {helpb ereturn}). If no
+{it:namelist} is provided, then the results are added to the
+currently active estimates (i.e. the model fit last). If these
+estimates have been previously stored, the stored copy of the
+estimates will also be modified. Alternatively, if {it:namelist} is
+provided after the colon, results are added to all indicated sets of
+stored estimates (see help {helpb estimates store} or help
+{helpb eststo}). You may use the {cmd:*} and {cmd:?}
+wildcards in {it:namelist}. Execution is silent if {it:namelist} is
+provided.
+
+{p 4 4 2}
+Adding additional results to the {cmd:e()}-returns is useful, for example,
+if the estimates be tabulated by commands such as {helpb estout}
+or {helpb esttab}. See the {help estadd##examples:Examples} section below for
+illustration of the usage of {cmd:estadd}.
+
+{p 4 4 2}Technical note: Some of the subcommands below make use of the
+information contained in {cmd:e(sample)} to determine estimation sample.
+These subcommands return error if the estimates do not contain
+{cmd:e(sample)}.
+
+
+{title:Subcommands}
+
+{dlgtab:Elementary}
+{marker local}
+{p 4 8 2}
+{cmd:estadd} {cmdab:loc:al} {it:name ...}
+
+{p 8 8 2}
+adds in macro {cmd:e(}{it:name}{cmd:)} the specified contents (also
+see help {helpb ereturn}).
+
+{marker scalar}
+{p 4 8 2}
+{cmd:estadd} {cmdab:sca:lar} {it:name} {cmd:=} {it:exp}
+
+{p 8 8 2}
+adds in scalar {cmd:e(}{it:name}{cmd:)} the evaluation of {it:exp}
+(also see help {helpb ereturn}).
+
+{p 4 8 2}
+{cmd:estadd} {cmdab:sca:lar} {cmd:r(}{it:name}{cmd:)}
+
+{p 8 8 2}
+adds in scalar {cmd:e(}{it:name}{cmd:)} the value of scalar {cmd:r(}{it:name}{cmd:)}.
+
+{p 4 8 2}
+{cmd:estadd} {cmdab:sca:lar} {it:name}
+
+{p 8 8 2}
+adds in scalar {cmd:e(}{it:name}{cmd:)} the the value of scalar {it:name}.
+
+{marker matrix}
+{p 4 8 2}
+{cmd:estadd} {cmdab:mat:rix} {it:name} {cmd:=} {it:matrix_expression}
+
+{p 8 8 2}
+adds in matrix {cmd:e(}{it:name}{cmd:)} the evaluation of {it:matrix_expression}
+(also see help {helpb matrix define}).
+
+{p 4 8 2}
+{cmd:estadd} {cmdab:mat:rix} {cmd:r(}{it:name}{cmd:)}
+
+{p 8 8 2}
+adds in matrix {cmd:e(}{it:name}{cmd:)} a copy of matrix {cmd:r(}{it:name}{cmd:)}.
+
+{p 4 8 2}
+{cmd:estadd} {cmdab:mat:rix} {it:name}
+
+{p 8 8 2}
+adds in matrix {cmd:e(}{it:name}{cmd:)} a copy of matrix {it:name}.
+
+{marker rreturn}
+{p 4 8 2}
+{cmd:estadd} {cmd:r(}{it:name}{cmd:)}
+
+{p 8 8 2}
+adds in {cmd:e(}{it:name}{cmd:)} the value of scalar {cmd:r(}{it:name}{cmd:)}
+or a copy of matrix {cmd:r(}{it:name}{cmd:)}, depending on the nature of
+{cmd:r(}{it:name}{cmd:)}.
+
+
+{dlgtab:Statistics for each coefficient}
+{marker beta}
+{p 4 8 2}
+{cmd:estadd} {cmd:beta}
+
+{p 8 8 2}
+adds in {cmd:e(beta)} the standardized beta coefficients.
+
+{marker vif}
+{p 4 8 2}
+{cmd:estadd} {cmd:vif} [{cmd:,} {cmdab:tol:erance} {cmdab:sqr:vif} ]
+
+{p 8 8 2}
+adds in {cmd:e(vif)} the variance inflation factors (VIFs) for the
+regressors (see help {helpb vif}). Note that {cmd:vif} only works
+with estimates produced by {helpb regress}. {cmd:tolerance}
+additionally adds the tolerances (1/VIF) in {cmd:e(tolerance)}.
+{cmd:sqrvif} additionally adds the square roots of the VIFs in
+{cmd:e(sqrvif)}.
+
+{marker pcorr}
+{p 4 8 2}
+{cmd:estadd} {cmd:pcorr} [{cmd:, semi} ]
+
+{p 8 8 2}
+adds the partial correlations (see help {helpb pcorr}) and,
+optionally, the semi-partial correlations between the dependent
+variable and the individual regressors (see, e.g., the {cmd:pcorr2}
+package from the SSC Archive). In the case of multiple-equations
+models, the results are computed for the first equation only. The
+partial correlations will be returned in {cmd:e(pcorr)} and, if
+{cmd:semi} is specified, the semi-partial correlations will be
+returned in {cmd:e(spcorr)}.
+
+{marker expb}
+{p 4 8 2}
+{cmd:estadd} {cmd:expb} [{cmd:,} {cmdab:nocons:tant} ]
+
+{p 8 8 2}
+adds in {cmd:e(expb)} the exponentiated coefficients (see the help
+{it:{help eform_option}}). {cmd:noconstant} excludes the constant
+from the added results.
+
+{marker ebsd}
+{p 4 8 2}
+{cmd:estadd} {cmd:ebsd}
+
+{p 8 8 2}
+adds in {cmd:e(ebsd)} the standardized factor change coefficients,
+i.e. exp(b_jS_j), where b_j is the raw coefficient and S_j is the
+standard deviation of regressor j, that are sometimes reported for
+logistic regression (see Long 1997).
+
+{marker mean}
+{p 4 8 2}
+{cmd:estadd} {cmd:mean}
+
+{p 8 8 2}
+adds in {cmd:e(mean)} the means of the regressors.
+
+{marker sd}
+{p 4 8 2}
+{cmd:estadd} {cmd:sd} [{cmd:,} {cmdab:nob:inary} ]
+
+{p 8 8 2}
+adds in {cmd:e(sd)} the standard deviations of the regressors.
+{cmd:nobinary} suppresses the computation of the standard deviation
+for 0/1 variables.
+
+{marker summ}
+{p 4 8 2}
+{cmd:estadd} {cmd:summ} [{cmd:,} {it:stats} ]
+
+{p 8 8 2}
+adds vectors of the regressors' descriptive statistics to the
+estimates. The following {it:stats} are available:
+{p_end}
+{marker stats}
+        {it:stats}{col 26}description
+        {hline 59}
+          {cmdab:me:an}{col 26}mean
+          {cmdab:su:m}{col 26}sum
+          {cmdab:mi:n}{col 26}minimum
+          {cmdab:ma:x}{col 26}maximum
+          {cmdab:ra:nge}{col 26}range = max - min
+          {cmd:sd}{col 26}standard deviation
+          {cmdab:v:ar}{col 26}variance
+          {cmd:cv}{col 26}coefficient of variation (sd/mean)
+          {cmdab:sem:ean}{col 26}standard error of mean = sd/sqrt(n)
+          {cmdab:sk:ewness}{col 26}skewness
+          {cmdab:k:urtosis}{col 26}kurtosis
+          {cmd:p1}{col 26}1st percentile
+          {cmd:p5}{col 26}5th percentile
+          {cmd:p10}{col 26}10th percentile
+          {cmd:p25}{col 26}25th percentile
+          {cmd:p50}{col 26}50th percentile
+          {cmd:p75}{col 26}75th percentile
+          {cmd:p90}{col 26}90th percentile
+          {cmd:p95}{col 26}95th percentile
+          {cmd:p99}{col 26}99th percentile
+          {cmd:iqr}{col 26}interquartile range = p75 - p25
+          {cmd:all}{col 26}all of the above
+          {cmdab:med:ian}{col 26}equivalent to specifying "{cmd:p50}"
+          {cmd:q}{col 26}equivalent to specifying "{cmd:p25 p50 p75}"
+        {hline 59}
+
+{p 8 8 2}
+The default is {cmd:mean sd min max}. Alternatively, indicate the
+desired statistics. For example, to add information on the
+regressors' skewness and kurtosis, type
+
+            {inp:. estadd summ, skewness kurtosis}
+
+{p 8 8 2}
+The statistics names are used as the names for the returned {cmd:e()}
+matrices. For example, {cmd:estadd summ, mean} will store the means
+of the regressors in {cmd:e(mean)}.
+
+
+{dlgtab:Summary statistics}
+{marker coxsnell}
+{p 4 8 2}
+{cmd:estadd} {cmd:coxsnell}
+
+{p 8 8 2}
+adds in {cmd:e(coxsnell)} the Cox & Snell pseudo R-squared, which is
+defined as
+
+{p 12 12 2}
+r2_coxsnell = 1 - ( L0 / L1 )^(2/N)
+
+{p 8 8 2}
+where L0 is the likelihood of the model without regressors, L1 the
+likelihood of the full model, and N is the sample size.
+
+{marker nagelkerke}
+{p 4 8 2}
+{cmd:estadd} {cmd:nagelkerke}
+
+{p 8 8 2}
+adds in {cmd:e(nagelkerke)} the Nagelkerke pseudo R-squared (or Cragg
+& Uhler pseudo R-squared), which is defined as
+
+{p 12 12 2}
+r2_nagelkerke = r2_coxsnell / (1 - L0^(2/N))
+
+{marker lrtest}
+{p 4 8 2}
+{cmd:estadd} {cmd:lrtest} {it:model} [{cmd:,} {cmdab:n:ame:(}{it:string}{cmd:)}
+{it:{help lrtest:lrtest_options}} ]
+
+{p 8 8 2}
+adds the results from a likelihood-ratio test, where {it:model} is
+the comparison model (see help {helpb lrtest}). Added are
+{cmd:e(lrtest_chi2)}, {cmd:e(lrtest_df)}, and {cmd:e(lrtest_p)}. The
+names may be modified using the {cmd:name()} option. Specify
+{cmd:name(}{it:myname}{cmd:)} to add {cmd:e(}{it:myname}{cmd:chi2)},
+{cmd:e(}{it:myname}{cmd:df)}, and {cmd:e(}{it:myname}{cmd:p)}. See
+help {helpb lrtest} for the {it:lrtest_options}.
+
+{marker ysumm}
+{p 4 8 2}
+{cmd:estadd} {cmd:ysumm} [{cmd:,} {it:stats} ]
+
+{p 8 8 2}
+adds descriptive statistics of the dependent variable. See the
+{helpb estadd##summ:summ} subcommand above for a list of the available
+{it:stats}. The default is {cmd:mean sd min max}. The default prefix
+for the names of the added scalars is {cmd:y} (e.g. the mean of the
+dependent variable will be returned in {cmd:e(ymean)}). Use
+{cmd:estadd}'s {cmd:prefix()} option to change the prefix. If a model
+has multiple dependent variables, results for the first variable will
+be added.
+
+{dlgtab:Other}
+{marker margins}
+{p 4 8 2}
+{cmd:estadd} {cmd:margins} [{it:marginlist}] [{it:if}] [{it:in}] [{it:weight}] [, {it:options} ]
+
+{p 8 8 2} 
+adds results from the {cmd:margins} command, which was introduced 
+in Stata 11. See help {helpb margins} for options. All results returned by 
+{cmd:margins} except {cmd:e(V)} are added using "{cmd:margins_}" as a default 
+prefix. For example, the margins are added in {cmd:e(margins_b)}. The 
+standard errors are added in {cmd:e(margins_se)}. Use the {helpb estadd##opts:prefix()} 
+option to change the default prefix.
+
+{marker spost}
+{dlgtab:SPost}
+
+{p 4 4 2} The following subcommands are wrappers for
+commands from Long and Freese's {helpb SPost} package (see
+{browse "http://www.indiana.edu/~jslsoc/spost.htm":http://www.indiana.edu/~jslsoc/spost.htm}). Type
+
+        . {net "from http://www.indiana.edu/~jslsoc/stata":net from http://www.indiana.edu/~jslsoc/stata}
+
+{p 4 4 2}
+to obtain the latest {cmd:SPost} version (spost9_ado). {cmd:SPost} for Stata 8 (spostado) is not
+supported.
+
+{p 4 4 2}For examples on using the subcommands see
+{browse "http://repec.org/bocode/e/estout/spost.html":http://repec.org/bocode/e/estout/spost.html}.
+
+{marker brant}
+{p 4 8 2}
+{cmd:estadd brant} [{cmd:,} {it:{help brant:brant_options}} ]
+
+{p 8 8 2}
+applies {helpb brant} from Long and
+Freese's {helpb SPost} package and adds the returned results to
+{cmd:e()}. You may specify {it:brant_options} as described in
+help {helpb brant}. The following results are added:
+
+        {cmd:e(}{it:...}{cmd:)}        Contents
+        {hline 60}
+        Scalars
+          {cmd:brant_chi2}  Chi-squared of overall Brant test
+          {cmd:brant_df}    Degrees of freedom of overall Brant test
+          {cmd:brant_p}     P-value of overall Brant test
+
+        Matrix
+          {cmd:brant}       Test results for individual regressors
+                      (rows: chi2, p LR or Wald X2
+        {cmd:r2_adj}        Adjusted R2
+        {cmd:r2_mf}         McFadden's R2
+        {cmd:r2_mfadj}      McFadden's Adj R2
+        {cmd:r2_ml}         ML (Cox-Snell) R2
+        {cmd:r2_cu}         Cragg-Uhler(Nagelkerke) R2
+        {cmd:r2_mz}         McKelvey & Zavoina's R2
+        {cmd:r2_ef}         Efron's R2
+        {cmd:v_ystar}       Variance of y*
+        {cmd:v_error}       Variance of error
+        {cmd:r2_ct}         Count R2
+        {cmd:r2_ctadj}      Adj Count R2
+        {cmd:aic0}          AIC
+        {cmd:aic_n}         AIC*n
+        {cmd:bic0}          BIC
+        {cmd:bic_p}         BIC'
+        {cmd:statabic}      BIC used by Stata
+        {cmd:stataaic}      AIC used by Stata
+        {cmd:n_rhs}         Number of rhs variables
+        {cmd:n_parm}        Number of parameters
+        {hline 60}
+
+{marker listcoef}
+{p 4 8 2}
+{cmd:estadd listcoef} [{it:varlist}] [{cmd:,} {cmd:nosd} {it:{help listcoef:listcoef_options}} ]
+
+{p 8 8 2}
+applies {helpb listcoef} from Long and
+Freese's {helpb SPost} package and adds the returned results to
+{cmd:e()}. You may specify {it:listcoef_options} as described in
+help {helpb listcoef}. Furthermore,  option {cmd:nosd} suppresses 
+adding the standard deviations of the variables in {cmd:e(b_sdx)}.
+
+{p 8 8 2}Depending on the estimation command and options, several of the
+following matrices are added:
+
+        {cmd:e(}{it:...}{cmd:)}        Contents
+        {hline 60}
+        {cmd:b_xs}          x-standardized coefficients
+        {cmd:b_ys}          y-standardized coefficients
+        {cmd:b_std}         Fully standardized coefficients
+        {cmd:b_fact}        Factor change coefficients
+        {cmd:b_facts}       Standardized factor change coefficients
+        {cmd:b_pct}         Percent change coefficients
+        {cmd:b_pcts}        Standardized percent change coefficients
+        {cmd:b_sdx}         Standard deviation of the Xs
+        {hline 60}
+
+{p 8 8 2}For nominal models ({helpb mlogit}, {helpb mprobit}) the 
+original parametrization of {cmd:e(b)} may not match the contrasts 
+computed by {cmd:listcoef}. To be able to tabulate standardized 
+coefficients along with the raw coefficients for the requested 
+contrasts, the following additional matrices are added for 
+these models:
+
+        {cmd:e(}{it:...}{cmd:)}        Contents
+        {hline 60}
+        {cmd:b_raw}         raw coefficients
+        {cmd:b_se}          standard errors of raw coefficients
+        {cmd:b_z}           z statistics
+        {cmd:b_p}           p-values
+        {hline 60}
+
+{marker mlogtest}
+{p 4 8 2}
+{cmd:estadd mlogtest} [{it:varlist}] [{cmd:,} {it:{help mlogtest:mlogtest_options}} ]
+
+{p 8 8 2}
+applies {helpb mlogtest} from Long and
+Freese's {helpb SPost} package and adds the returned results to
+{cmd:e()}. You may specify {it:mlogtest_options} as described in
+help {helpb mlogtest}.
+
+{p 8 8 2}Depending on the specified options, a selection of the following
+returns are added:
+
+        {cmd:e(}{it:...}{cmd:)}               Contents
+        {hline 60}
+        Scalars
+          {cmd:hausman_set}{it:#}{cmd:_chi2}  Hausman IIA tests using {helpb hausman}
+          {cmd:hausman_set}{it:#}{cmd:_df}
+          {cmd:hausman_set}{it:#}{cmd:_p}
+
+          {cmd:suest_set}{it:#}{cmd:_chi2}    Hausman IIA tests using {helpb suest}
+          {cmd:suest_set}{it:#}{cmd:_df}
+          {cmd:suest_set}{it:#}{cmd:_p}
+
+          {cmd:smhsiao_set}{it:#}{cmd:_chi2}  Small-Hsiao IIA tests
+          {cmd:smhsiao_set}{it:#}{cmd:_df}
+          {cmd:smhsiao_set}{it:#}{cmd:_p}
+
+          {cmd:combine_}{it:#1}{cmd:_}{it:#2}{cmd:_chi2} Wald tests for combination of outcomes
+          {cmd:combine_}{it:#1}{cmd:_}{it:#2}{cmd:_df}
+          {cmd:combine_}{it:#1}{cmd:_}{it:#2}{cmd:_p}
+
+          {cmd:lrcomb_}{it:#1}{cmd:_}{it:#2}{cmd:_chi2}  LR tests for combination of outcomes
+          {cmd:lrcomb_}{it:#1}{cmd:_}{it:#2}{cmd:_df}
+          {cmd:lrcomb_}{it:#1}{cmd:_}{it:#2}{cmd:_p}
+
+          {cmd:wald_set}{it:#}{cmd:_chi2}     Wald tests for sets of independent
+          {cmd:wald_set}{it:#}{cmd:_df}       variables
+          {cmd:wald_set}{it:#}{cmd:_p}
+
+          {cmd:lrtest_set}{it:#}{cmd:_chi2}   LR tests for sets of independent
+          {cmd:lrtest_set}{it:#}{cmd:_df}     variables
+          {cmd:lrtest_set}{it:#}{cmd:_p}
+
+        Matrices
+          {cmd:wald}               Wald tests for individual variables
+                             (rows: chi2, df, p)
+          {cmd:lrtest}             LR tests for individual variables
+                             (rows: chi2, df, p)
+        {hline 60}
+
+{p 4 4 2}To address the rows of {cmd:e(wald)} and {cmd:e(lrtest)} in {helpb estout}'s 
+{cmd:cells()} option type the row names in brackets, for example, {cmd:wald[p]} or 
+{cmd:lrtest[chi2]}.
+
+{marker prchange}
+{p 4 8 2}
+{cmd:estadd prchange} [{it:varlist}] [{cmd:if} {it:exp}] [{cmd:in} {it:range}] [{cmd:,}
+ {cmdab:pa:ttern(}{it:typepattern}{cmd:)} {cmdab:b:inary(}{it:type}{cmd:)} {cmdab:c:ontinuous(}{it:type}{cmd:)}
+ [{cmd:no}]{cmdab:a:vg} {cmd:split}[{cmd:(}{it:prefix}{cmd:)}] {it:{help prchange:prchange_options}} ]
+
+{p 8 8 2}
+applies {helpb prchange} from Long and
+Freese's {helpb SPost} package and adds the returned results to
+{cmd:e()}. You may specify {it:prchange_options} as described in
+help {helpb prchange}. In particular, the {cmd:outcome()} option may be
+used with models for count, ordered, or nominal outcomes
+to request results for a specific outcome. Further options are:
+
+{p 8 12 2}{cmd:pattern(}{it:typepattern}{cmd:)}, {cmd:binary(}{it:type}{cmd:)}, and
+{cmd:continuous(}{it:type}{cmd:)} to determine which types of discrete change
+effects are added as the main results. The default is to add the 0 to 1
+change effect for binary variables and the standard deviation change effect
+for continuous variables. Use {cmd:binary(}{it:type}{cmd:)} and
+{cmd:continuous(}{it:type}{cmd:)} to change these defaults. Available
+types are:
+
+                {it:type}        Description
+                {hline 48}
+                {cmdab:mi:nmax}      minimum to maximum change effect
+                {cmdab:0:1}          0 to 1 change effect
+                {cmdab:d:elta}       {cmd:delta()} change effect
+                {cmdab:s:d}          standard deviation change effect
+                {cmdab:m:argefct}    marginal effect (some models only)
+                {hline 48}
+
+{p 12 12 2}Use {cmd:pattern(}{it:typepattern}{cmd:)} if you want to determine the
+type of the added effects individually for each regressor. For example,
+{bind:{cmd:pattern(minmax sd delta)}} would add {cmd:minmax} for the first regressor,
+{cmd:sd} for the second, and {cmd:delta} for the third, and then proceed
+using the defaults for the remaining variables.
+
+{p 8 12 2}{cmd:avg} to request that only the average results over 
+all outcomes are added if applied to ordered
+or nominal models ({helpb ologit}, {helpb oprobit}, {helpb slogit}, {helpb mlogit}, {helpb mprobit}). The 
+default is to add the average results as well as the individual results for 
+the different outcomes (unless {helpb prchange}'s {cmd:outcome()} option is 
+specified, in which case only results for the indicated outcome are 
+added). Furthermore, specify {cmd:noavg} to suppress the average results 
+and only add the outcome-specific results. {cmd:avg} cannot be combined with {cmd:split} 
+or {cmd:outcome()}. 
+
+{p 8 12 2}{cmd:split}[{cmd:(}{it:prefix}{cmd:)}] to save 
+each outcome's results in a separate estimation set if applied to ordered
+or nominal models ({helpb ologit}, {helpb oprobit}, {helpb slogit}, {helpb mlogit},
+{helpb mprobit}). The estimation sets are named
+{it:prefix}{it:#}, where {it:#} is the value of the outcome at hand. If no
+{it:prefix} is provided, the name of the estimation set followed by an
+underscore is used as the prefix. If the estimation set has no name
+(because it has not been stored yet) the name of the estimation command
+followed by an underscore is used as the prefix (e.g. {cmd:ologit_}). The
+estimation sets stored by the {cmd:split} option are intended for
+tabulation only and should not be used with other post-estimation
+commands.
+
+{p 8 8 2}Depending on model and options, several of the following matrices
+and scalars are added:
+
+        {cmd:e(}{it:...}{cmd:)}        Contents
+        {hline 60}
+        Scalars
+          {cmd:centered}    {cmd:1} if effects are centered, {cmd:0} else
+          {cmd:delta}       Value of {cmd:delta()}
+          {cmd:predval}[{it:#}]  Prediction(s) at the base values
+          {cmd:outcome}     Outcome value ({cmd:outcome()}/{cmd:split} only)
+
+        Matrices
+          {cmd:dc}          Discrete change effects (rows: main, minmax,
+                      01, delta, sd [, margefct])
+          {cmd:pattern}     Types of effects in the main row of {cmd:e(dc)}
+          {cmd:X}           Base values and descriptive statistics
+                      (rows: X, SD, Min, Max)
+        {hline 60}
+
+{p 8 8 2}The {cmd:e(dc)} and {cmd:e(X)} matrices have multiple rows. The
+{cmd:e(dc)} matrix contains the main results as determined by
+{cmd:pattern()}, {cmd:binary()}, and {cmd:continuous()} in the first row.
+The second and following rows contain the separate results for each type of
+effect using the labels provided by {cmd:prchange} as row names. Type
+{cmd:dc[}{it:#}{cmd:]} or {cmd:dc[}{it:rowname}{cmd:]} to address the rows
+in {helpb estout}'s {cmd:cells()} option, where {it:#} is the row number 
+or {it:rowname} is the
+row name. For example, type {cmd:dc[-+sd/2]} to address the centered
+standard deviation change effects. To tabulate the main results (1st row),
+simply type {cmd:dc}. {cmd:e(pattern)} indicates the types of effects
+contained in the main row of {cmd:e(dc)} using numeric codes. The codes are 1
+for the minimum to maximum change effect, 2 for the 0 to 1 change effect, 3
+for the {cmd:delta()} change effect, 4 for the standard deviation change
+effect, and 5 for the marginal effect. {cmd:e(X)} has four rows
+containing the base values, standard deviations, minimums, and maximums. If
+the {cmd:fromto} option is specified, two additional matrices,
+{cmd:e(dcfrom)} and {cmd:e(dcto)} are added. 
+
+{marker prvalue}
+{p 4 8 2}
+{cmd:estadd prvalue} [{cmd:if} {it:exp}] [{cmd:in} {it:range}] [{cmd:,} {cmdab:lab:el:(}{it:string}{cmd:)}
+{it:{help prvalue:prvalue_options}} ]
+
+{p 4 8 2}
+{cmd:estadd prvalue} {cmd:post} [{it:name}] [{cmd:,} {cmdab:t:itle:(}{it:string}{cmd:)} {cmd:swap} ]
+
+{p 8 8 2} applies {helpb prvalue} from Long and Freese's {helpb SPost}
+package and adds the returned results to {cmd:e()}. The procedure is to
+first collect a series of predictions by repeated calls to
+{cmd:estadd prvalue} and then apply {cmd:estadd prvalue post} to prepare the results
+for tabulation as in the following example:
+
+            {com}. logit lfp k5 k618 age wc hc lwg inc
+            . estadd prvalue, x(inc 10) label(low inc)
+            . estadd prvalue, x(inc 20) label(med inc)
+            . estadd prvalue, x(inc 30) label(high inc)
+            . estadd prvalue post
+            . estout{txt}
+
+{p 8 8 2} You may specify {it:prvalue_options} with {cmd:estadd prvalue} as
+described in help {helpb prvalue}. For example, use {cmd:x()} and
+{cmd:rest()} to set the values of the independent variables. Use
+{cmd:label()} to label the single calls. "pred#" is used as label if
+{cmd:label()} is omitted, where # is the number of the call. Labels may
+contain spaces but they will be trimmed to a maximum
+length of 30 characters and some characters ({cmd::},
+{cmd:.}, {cmd:"}) will be replaced by underscore. The results
+from the single calls are collected in matrix {cmd:e(_estadd_prvalue)}
+(predictions) and matrix {cmd:e(_estadd_prvalue_x)} (x-values). Specify
+{cmd:replace} to drop results from previous calls.
+
+{p 8 8 2}
+{cmd:estadd prvalue post} posts the collected predictions in {cmd:e(b)}
+so that they can be tabulated. The following results are saved:
+
+        {cmd:e(}{it:...}{cmd:)}        Contents
+        {hline 60}
+        Scalars
+          {cmd:N}           number of observations
+
+        Macros
+          {cmd:depvar}      name of dependent variable
+          {cmd:cmd}         {cmd:estadd_prvalue}
+          {cmd:model}       model estimation command
+          {cmd:properties}  {cmd:b}
+
+        Matrices
+          {cmd:b}           predictions
+          {cmd:se}          standard errors
+          {cmd:LB}          lower confidence interval bounds
+          {cmd:UB}          upper confidence interval bounds
+          {cmd:Category}    outcome values
+          {cmd:Cond}        conditional predictions (some models only)
+          {cmd:X}           values of predictors (for each prediction)
+          {cmd:X2}          second equation predictors (some models only)
+        {hline 60}
+
+{p 8 8 2} {cmd:estadd prvalue post} replaces the current model unless
+{it:name} is specified, in which case the results are stored under {it:name} and the model
+remains active. However, if the model has a name
+(because it has been stored), the name of the model is used as a prefix.
+If, for example, the model has been stored as {cmd:model1}, then
+{cmd:estadd prvalue post} stores its results under {cmd:model1}{it:name}.
+Use {cmd:title()} to specify a title for the stored results.
+
+{p 8 8 2}The default for {cmd:estadd prvalue post} is to arrange
+{cmd:e(b)} in a way so that predictions are grouped by outcome (i.e. outcome labels are used
+as equations). Alternatively, specify {cmd:swap} to group predictions by
+{cmd:prvalue} calls (i.e. to use the prediction labels as equations).
+
+{p 8 8 2}{cmd:e(X)} contains one row for each independent variable. To address the rows in
+{helpb estout}'s {cmd:cells()} option type {cmd:X[}{it:varname}{cmd:]}, where {it:varname} is
+the name of the variable of interest. {cmd:e(X2)}, if provided, is analogous to {cmd:e(X)}.
+
+{marker asprvalue}
+{p 4 8 2}
+{cmd:estadd asprvalue} [{cmd:,} {cmdab:lab:el:(}{it:string}{cmd:)}
+{it:{help asprvalue:asprvalue_options}} ]
+
+{p 4 8 2}
+{cmd:estadd asprvalue} {cmd:post} [{it:name}] [{cmd:,} {cmdab:t:itle:(}{it:string}{cmd:)} {cmd:swap} ]
+
+{p 8 8 2} applies {helpb asprvalue} from Long and Freese's {helpb SPost}
+package and adds the returned results to {cmd:e()}. The procedure is to
+first collect a series of predictions by repeated calls to
+{cmd:estadd asprvalue} and then apply {cmd:estadd asprvalue post} to prepare the results
+for tabulation as in the following example:
+
+            {com}. clogit choice train bus time invc, group(id)
+            . estadd asprvalue, cat(train bus) label(at means)
+            . estadd asprvalue, cat(train bus) rest(asmean) label(at asmeans)
+            . estadd asprvalue post
+            . estout{txt}
+
+{p 8 8 2} You may specify {it:asprvalue_options} with {cmd:estadd asprvalue} as
+described in help {helpb asprvalue}. For example, use {cmd:x()} and
+{cmd:rest()} to set the values of the independent variables.  Use
+{cmd:label()} to label the single calls. "pred#" is used as label if
+{cmd:label()} is omitted, where # is the number of the call.  Labels may
+contain spaces but they will be trimmed to a maximum
+length of 30 characters and some characters ({cmd::},
+{cmd:.}, {cmd:"}) will be replaced by underscore. The results
+from the single calls are collected in matrices {cmd:e(_estadd_asprval)}
+(predictions), {cmd:e(_estadd_asprval_asv)} (values of alternative-specific
+variables), and {cmd:e(_estadd_asprval_csv)} (values of case-specific
+variables). Specify {cmd:replace} to drop results from previous calls.
+
+{p 8 8 2}
+{cmd:estadd asprvalue post} posts the collected predictions in {cmd:e(b)}
+so that they can be tabulated. The following results are saved:
+
+        {cmd:e(}{it:...}{cmd:)}        Contents
+        {hline 60}
+        Scalars
+          {cmd:N}           number of observations
+
+        Macros
+          {cmd:depvar}      name of dependent variable
+          {cmd:cmd}         {cmd:estadd_asprvalue}
+          {cmd:model}       model estimation command
+          {cmd:properties}  {cmd:b}
+
+        Matrices
+          {cmd:b}           predictions
+          {cmd:asv}         alternative-specific variables (if available)
+          {cmd:csv}         case-specific variables (if available)
+        {hline 60}
+
+{p 8 8 2} {cmd:estadd asprvalue post} replaces the current model unless
+{it:name} is specified, in which case the results are stored under
+{it:name} and the model remains active. However, if the model has a name
+(because it has been stored), the name of the model is used as a prefix.
+If, for example, the model has been stored as {cmd:model1}, then
+{cmd:estadd asprvalue post} stores its results under {cmd:model1}{it:name}.
+Use {cmd:title()} to specify a title for the stored results.
+
+{p 8 8 2}The default for {cmd:estadd asprvalue post} is to arrange
+{cmd:e(b)} in a way so that predictions are grouped by outcome (i.e. outcome labels are used
+as equations). Alternatively, specify {cmd:swap} to group predictions by
+{cmd:prvalue} calls (i.e. to use the prediction labels as equations).
+
+{p 8 8 2}{cmd:e(asv)} and {cmd:e(csv)} contain one row for each variable.
+To address the rows in {helpb estout}'s {cmd:cells()} option type
+{cmd:asv[}{it:varname}{cmd:]} or {cmd:csv[}{it:varname}{cmd:]}, where
+{it:varname} is the name of the variable of interest.
+
+{marker options}
+{title:Options}
+
+{p 4 8 2}
+{cmd:replace} permits {cmd:estadd} to overwrite existing {cmd:e()}
+macros, scalars, or matrices.
+
+{p 4 8 2}
+{cmd:prefix(}{it:string}{cmd:)} denotes a prefix for the names of the
+added results. The default prefix is an empty string. For example, if
+{cmd:prefix(}{it:string}{cmd:)} is specified, the {cmd:beta}
+subcommand will return the matrix {cmd:e(}{it:string}{cmd:beta)}.
+
+{p 4 8 2}{cmd:quietly} suppresses the output from the called subcommand and displays only
+the list of added results. Note that many of {cmd:estadd}'s subcommands do not generate
+output, in which case {cmd:quietly} has no effect.
+
+{p 4 8 2}
+{it:subcmdopts} are subcommand specific options. See the descriptions
+of the subcommands above.
+
+{marker examples}
+{title:Examples}
+
+{p 4 4 2}Example 1: Add {cmd:r()}-returns from other programs to the
+current estimates
+
+        {com}. sysuse auto
+        {txt}(1978 Automobile Data)
+
+        {com}. quietly regress price mpg weight
+        {txt}
+        {com}. test mpg=weight
+
+        {txt} ( 1)  {res}mpg - weight = 0
+
+        {txt}       F(  1,    71) ={res}    0.36
+        {txt}{col 13}Prob > F ={res}    0.5514
+        {txt}
+        {com}. estadd scalar p_diff = r(p)
+
+        {txt}added scalar:
+                     e(p_diff) =  {res}.55138216
+        {txt}
+        {com}. estout, stats(p_diff)
+        {res}
+        {txt}{hline 25}
+        {txt}                        b
+        {txt}{hline 25}
+        {txt}mpg         {res}    -49.51222{txt}
+        {txt}weight      {res}     1.746559{txt}
+        {txt}_cons       {res}     1946.069{txt}
+        {txt}{hline 25}
+        {txt}p_diff      {res}     .5513822{txt}
+        {txt}{hline 25}
+
+
+{p 4 4 2}Example 2: Add means and standard deviations of the model's regressors
+to the current estimates
+
+        {com}. quietly logit foreign price mpg
+        {txt}
+        {com}. estadd summ, mean sd
+
+        {txt}added matrices:
+                         e(sd) :  {res}1 x 3
+                       {txt}e(mean) :  {res}1 x 3
+        {txt}
+        {com}. estout, cells("mean sd") drop(_cons)
+        {res}
+        {txt}{hline 38}
+        {txt}                     mean           sd
+        {txt}{hline 38}
+        {txt}price       {res}     6165.257     2949.496{txt}
+        {txt}mpg         {res}      21.2973     5.785503{txt}
+        {txt}{hline 38}
+
+
+{p 4 4 2}
+Example 3: Add standardized beta coefficients to stored estimates
+
+        {com}. eststo: quietly regress price mpg
+        {txt}({res}est1{txt} stored)
+
+        {com}. eststo: quietly regress price mpg foreign
+        {txt}({res}est2{txt} stored)
+
+        {com}. estadd beta: *
+        {txt}
+        {com}. estout, cells(beta)  drop(_cons)
+        {res}
+        {txt}{hline 38}
+        {txt}                     est1         est2
+        {txt}                     beta         beta
+        {txt}{hline 38}
+        {txt}mpg         {res}    -.4685967    -.5770712{txt}
+        {txt}foreign     {res}                  .2757378{txt}
+        {txt}{hline 38}
+
+
+{p 4 4 2}See
+{browse "http://repec.org/bocode/e/estout":http://repec.org/bocode/e/estout}
+for additional examples.
+
+
+{title:Writing one's own subcommands}
+
+{p 4 4 2}
+A program providing a new {cmd:estadd} subcommand should be called
+{cmd:estadd_}{it:mysubcommand} (see help {helpb program} for advice
+on defining programs). {it:mysubcommand} will be available to {cmd:estadd} as a new
+{it:subcommand} after the program definition has been executed or
+saved to a file called "estadd_{it:mysubcommand}.ado" in either the
+current directory or somewhere else in the {cmd:adopath}
+(see help {helpb sysdir}).
+
+{p 4 4 2}
+Use the subcommands provided within "estadd.ado" as a starting
+point for writing new subcommands. See
+{browse "http://repec.org/bocode/e/estout/estadd.html#estadd007":http://repec.org/bocode/e/estout/estadd.html#estadd007}
+for an example.
+
+
+{title:Author}
+
+{p 4 4 2} Ben Jann, ETH Zurich, jannb@ethz.ch
+
+
+{title:Also see}
+
+    Manual:  {hi:[R] estimates}
+
+{p 4 13 2}Online:  help for
+ {helpb estimates},
+ {helpb ereturn},
+ {helpb program},
+ {helpb esttab}, 
+ {helpb estout}, 
+ {helpb eststo}, 
+ {helpb estpost}
+{p_end}
diff --git a/Modules/ado/plus/e/estout.ado b/Modules/ado/plus/e/estout.ado
new file mode 100644
index 0000000..e1ed449
--- /dev/null
+++ b/Modules/ado/plus/e/estout.ado
@@ -0,0 +1,4495 @@
+*! version 3.13  06aug2009  Ben Jann
+
+program define estout, rclass
+    version 8.2
+    return local cmdline estout `macval(0)'
+    syntax [anything] [using] [ , ///
+        Cells(string asis) ///
+        Drop(string asis)  ///
+        Keep(string asis) ///
+        Order(string asis) ///
+        REName(passthru) ///
+        Indicate(string asis) ///
+        TRansform(string asis) ///
+        EQuations(passthru) ///
+        NOEFORM eform EFORM2(string) ///
+        NOMargin Margin Margin2(string) ///
+        NODIscrete DIscrete(string asis) ///
+        MEQs(string) ///
+        NODROPPED dropped DROPPED2(string) ///
+        level(numlist max=1 int >=10 <=99) ///
+        Stats(string asis) ///
+        STARLevels(string asis) ///
+        NOSTARDetach STARDetach ///
+        STARKeep(string asis) ///
+        STARDrop(string asis) ///
+        VARwidth(numlist max=1 int >=0) ///
+        MODELwidth(numlist int >=0) ///
+        NOABbrev ABbrev ///
+        NOUNStack UNStack ///
+        EXTRAcols(numlist sort) ///
+        BEGin(string asis) ///
+        DELimiter(string asis) ///
+        INCELLdelimiter(string asis) ///
+        end(string asis) ///
+        DMarker(string) ///
+        MSign(string) ///
+        NOLZ lz ///
+        SUBstitute(string asis) ///
+        TItle(string) ///
+        note(string) ///
+        NOLEgend LEgend ///
+        PREHead(string asis) ///
+        POSTHead(string asis) ///
+        PREFoot(string asis) ///
+        POSTFoot(string asis) ///
+        HLinechar(string) ///
+        NOLabel Label ///
+        VARLabels(string asis) ///
+        REFcat(string asis) ///
+        MLabels(string asis) ///
+        NONUMbers NUMbers NUMbers2(string asis) ///
+        COLLabels(string asis) ///
+        EQLabels(string asis) ///
+        MGRoups(string asis) ///
+        LABCOL2(string asis) ///
+        TOPfile(string) ///
+        BOTtomfile(string) ///
+        STYle(string) ///
+        DEFaults(string) ///
+        * ///
+        ]
+    MoreOptions, `options'
+    if "`style'"!="" local defaults "`style'"
+
+*Matrix mode
+    MatrixMode, `anything' `rename' // resets the cells argument
+        // and returns r(coefs) etc. and local 'matrixmode'
+
+*Parse suboptions
+    local elnum 0
+    if `"`cells'"'!="none" {
+        gettoken row rest: cells, bind match(par) qed(qed)
+        if `"`par'"'=="(" local qed 1
+        local cells
+        while `"`row'"'!="" {
+            local newrow
+            gettoken opt row: row, parse(" ([&")
+            if `"`macval(row)'"'=="" & `qed'==0 {
+                local row0
+                gettoken trash: rest, parse("[")
+                if `"`trash'"'=="[" {
+                    gettoken trash rest: rest, parse("[")
+                    gettoken mrow rest: rest, parse("]") q
+                    gettoken trash rest: rest, parse("]")
+                    if `"`trash'"'!="]" {
+                        error 198
+                    }
+                }
+                gettoken trash: rest, match(par)
+                if `"`par'"'=="(" {
+                    gettoken opt2 rest: rest, match(par)
+                }
+                else local opt2
+            }
+            else {
+                gettoken trash: row, parse("[")
+                if `"`trash'"'=="[" {
+                    gettoken trash row: row, parse("[")
+                    gettoken mrow row: row, parse("]") q
+                    gettoken trash row: row, parse("]")
+                    if `"`trash'"'!="]" {
+                        error 198
+                    }
+                }
+                gettoken trash row0: row, match(par)
+                gettoken opt2: row, match(par)
+            }
+            while "`opt'"!="" {
+                if "`opt'"!="&" & "`opt'"!="." {
+                    local `opt'_tname "el`++elnum'"
+                    local ``opt'_tname'_ "`opt'"
+                    local newrow `"`newrow' ``opt'_tname'"'
+                    if `"`par'"'!="(" local opt2
+                    ParseValueSubopts ``opt'_tname' `opt', mrow(`mrow') `macval(opt2)'
+                    local mrow
+                }
+                else {
+                    if `"`par'"'=="(" | `"`mrow'"'!="" error 198
+                    local newrow `"`newrow' `opt'"'
+                }
+                if `"`par'"'!="(" {
+                    gettoken opt row: row, parse(" ([&")
+                }
+                else {
+                    gettoken opt row: row0, parse(" ([&")
+                }
+                gettoken trash: row, parse("[")
+                if `"`trash'"'=="[" {
+                    gettoken trash row: row, parse("[")
+                    gettoken mrow row: row, parse("]") q
+                    gettoken trash row: row, parse("]")
+                    if `"`trash'"'!="]" {
+                        error 198
+                    }
+                }
+                gettoken trash row0: row, match(par)
+                gettoken opt2: row, match(par)
+            }
+            local newrow: list retok newrow
+            if `qed' local cells `"`cells'"`newrow'" "'
+            else local cells `"`cells'`newrow' "'
+            gettoken row rest: rest, bind match(par) qed(qed)
+            if `"`par'"'=="(" local qed 1
+        }
+        local cells: list retok cells
+    }
+    if "`eform2'"!="" {
+        local eform "`eform2'"
+        local eform2
+    }
+    if `"`transform'"'!="" {
+        ParseTransformSubopts `transform'
+    }
+    if "`margin2'"!="" {
+        local margin "`margin2'"
+        local margin2
+    }
+    if `"`dropped'"'!="" local dropped "(dropped)"
+    if `"`macval(dropped2)'"'!="" {
+        local dropped `"`macval(dropped2)'"'
+        local dropped2
+    }
+    if `"`macval(stats)'"'!="" {
+        ParseStatsSubopts `macval(stats)'
+        if `"`macval(statslabels)'"'!="" {
+            if trim(`"`statslabels'"')=="none" {
+                local statslabelsnone none
+                local statslabels
+            }
+            else {
+                ParseLabelsSubopts statslabels `macval(statslabels)'
+            }
+        }
+    }
+    foreach opt in mgroups mlabels eqlabels collabels varlabels {
+        if `"`macval(`opt')'"'!="" {
+            if trim(`"``opt''"')=="none" {
+                local `opt'none none
+                local `opt'
+            }
+            else {
+                ParseLabelsSubopts `opt' `macval(`opt')'
+            }
+        }
+    }
+    if `"`macval(numbers2)'"'!="" {
+        local numbers `"`macval(numbers2)'"'
+        local numbers2
+    }
+    if `"`macval(indicate)'"'!="" {
+        ParseIndicateOpts `macval(indicate)'
+    }
+    if `"`macval(refcat)'"'!="" {
+        ParseRefcatOpts `macval(refcat)'
+    }
+    if `"`macval(starlevels)'"'!="" {
+        ParseStarlevels `macval(starlevels)'
+    }
+    if `"`macval(labcol2)'"'!="" {
+        ParseLabCol2 `macval(labcol2)'
+    }
+
+*Process No-Options
+    foreach opt in unstack eform margin dropped discrete stardetach wrap ///
+     legend label refcatlabel numbers lz abbrev replace append type showtabs ///
+     smcltags smclrules smclmidrules smcleqrules asis outfilenoteoff {
+        if "`no`opt''"!="" local `opt'
+    }
+
+*Defaults
+    if "`defaults'"=="esttab"               local defaults "tab"
+    if "`defaults'"=="" & `"`using'"'==""   local defaults "smcl"
+    if inlist("`defaults'", "", "smcl", "tab", "fixed", "tex", "html","mmd")  {
+        local varwidthfactor = (1 + ("`eqlabelsmerge'"!="" & "`unstack'"=="")*.5)
+        if inlist("`defaults'", "", "tab") {
+            if `"`macval(delimiter)'"'=="" local delimiter _tab
+        }
+        else if "`defaults'"=="smcl" {
+            if "`varwidth'"==""            local varwidth = cond("`label'"=="", 12, 20) * `varwidthfactor'
+            if "`modelwidth'"==""          local modelwidth 12
+            if "`noabbrev'"==""            local abbrev abbrev
+            if `"`macval(delimiter)'"'=="" local delimiter `"" ""'
+            if "`nosmcltags'"==""          local smcltags smcltags
+            if "`nosmclrules'"==""         local smclrules smclrules
+            if "`asis'"==""                local noasis noasis
+        }
+        else if "`defaults'"=="fixed" {
+            if "`varwidth'"==""            local varwidth = cond("`label'"=="", 12, 20) * `varwidthfactor'
+            if "`modelwidth'"==""          local modelwidth 12
+            if "`noabbrev'"==""            local abbrev abbrev
+            if `"`macval(delimiter)'"'=="" local delimiter `"" ""'
+        }
+        else if "`defaults'"=="tex" {
+            if "`varwidth'"==""            local varwidth = cond("`label'"=="", 12, 20) * `varwidthfactor'
+            if "`modelwidth'"==""          local modelwidth 12
+            if `"`macval(delimiter)'"'=="" local delimiter &
+            if `"`macval(end)'"'=="" {
+                local end \\\
+            }
+        }
+        else if "`defaults'"=="html" {
+            if "`varwidth'"==""            local varwidth = cond("`label'"=="", 12, 20) * `varwidthfactor'
+            if "`modelwidth'"==""          local modelwidth 12
+            if `"`macval(begin)'"'==""     local begin 
+            if `"`macval(delimiter)'"'=="" local delimiter 
+            if `"`macval(end)'"'==""       local end 
+        }
+        else if "`defaults'"=="mmd" {
+            if "`varwidth'"==""            local varwidth = cond("`label'"=="", 12, 20) * `varwidthfactor'
+            if "`modelwidth'"==""          local modelwidth 12
+            if `"`macval(begin)'"'==""     local begin "| "
+            if `"`macval(delimiter)'"'=="" local delimiter " | "
+            if `"`macval(end)'"'==""       local end " |"
+        }
+        if "`nostatslabelsfirst'"=="" local statslabelsfirst first
+        if "`nostatslabelslast'"==""  local statslabelslast last
+        if "`novarlabelsfirst'"==""   local varlabelsfirst first
+        if "`novarlabelslast'"==""    local varlabelslast last
+        if "`noeqlabelsfirst'"==""    local eqlabelsfirst first
+        if "`noeqlabelslast'"==""     local eqlabelslast last
+        if "`nolz'"==""               local lz lz
+        if `"`macval(discrete)'"'=="" & "`nodiscrete'"=="" {
+            local discrete `"" (d)" for discrete change of dummy variable from 0 to 1"'
+        }
+        if `"`macval(indicatelabels)'"'=="" local indicatelabels "Yes No"
+        if `"`macval(refcatlabel)'"'=="" & "`norefcatlabel'"==""    local refcatlabel "ref."
+        if `"`macval(incelldelimiter)'"'=="" local incelldelimiter " "
+    }
+    else {
+        capture findfile estout_`defaults'.def
+        if _rc {
+            di as error `"`defaults' style not available "' ///
+             `"(file estout_`defaults'.def not found)"'
+            exit 601
+        }
+        else {
+            tempname file
+            file open `file' using `"`r(fn)'"', read text
+            if c(SE) local max 244
+            else local max 80
+            while 1 {
+                ReadLine `max' `file'
+                if `"`line'"'=="" continue, break
+                gettoken opt line: line
+                else if index(`"`opt'"',"_") {
+                    gettoken opt0 opt1: opt, parse("_")
+                    if `"``opt0'_tname'"'!="" {
+                        local opt `"``opt0'_tname'`opt1'"'
+                    }
+                }
+                if `"`macval(`opt')'"'=="" & `"`no`opt''"'=="" {
+                    if `"`opt'"'=="cells" {
+                        local newline
+                        gettoken row rest: line, match(par) qed(qed)
+                        if `"`par'"'=="(" local qed 1
+                        while `"`row'"'!="" {
+                            local newrow
+                            gettoken el row: row, parse(" &")
+                            while `"`el'"'!="" {
+                                if `"`el'"'!="." & `"`el'"'!="&" {
+                                    local `el'_tname "el`++elnum'"
+                                    local ``el'_tname'_ "`el'"
+                                    local newrow "`newrow' ``el'_tname'"
+                                }
+                                else {
+                                    local newrow "`newrow' `el'"
+                                }
+                                gettoken el row: row, parse(" &")
+                            }
+                            local newrow: list retok newrow
+                            if `qed' local newline `"`newline'"`newrow'" "'
+                            else local newline `"`newline'`newrow' "'
+                            gettoken row rest: rest, match(par) qed(qed)
+                            if `"`par'"'=="(" local qed 1
+                        }
+                        local line `"`newline'"'
+                    }
+                    local line: list retok line
+                    local `opt' `"`macval(line)'"'
+                }
+            }
+            file close `file'
+        }
+    }
+    if "`notype'"=="" & `"`using'"'=="" local type type
+    if "`smcltags'"=="" & "`noasis'"=="" local asis asis
+    if "`asis'"!="" local asis "_asis"
+    if "`smclrules'"!="" & "`nosmclmidrules'"=="" local smclmidrules smclmidrules
+    if "`smclmidrules'"!="" & "`nosmcleqrules'"=="" local smcleqrules smcleqrules
+    local haslabcol2 = (`"`macval(labcol2)'"'!="")
+
+*title/notes option
+    if `"`macval(prehead)'`macval(posthead)'`macval(prefoot)'`macval(postfoot)'"'=="" {
+        if `"`macval(title)'"'!="" {
+            local prehead `"`"`macval(title)'"'"'
+        }
+        if `"`macval(note)'"'!="" {
+            local postfoot `"`"`macval(note)'"'"'
+        }
+    }
+
+*Generate/clean-up cell contents
+    if `"`:list clean cells'"'=="" {
+        local cells b
+        local b_tname "b"
+        local b_ "b"
+    }
+    else if `"`:list clean cells'"'=="none" {
+        local cells
+    }
+    CellsCheck `"`cells'"'
+    if `:list sizeof incelldelimiter'==1 gettoken incelldelimiter: incelldelimiter
+
+*Special treatment of confidence intervalls
+    if "`level'"=="" local level $S_level
+    if `level'<10 | `level'>99 {
+        di as error "level(`level') invalid"
+        exit 198
+    }
+    if "`ci_tname'"!="" {
+        if `"`macval(`ci_tname'_label)'"'=="" {
+            local `ci_tname'_label "ci`level'"
+        }
+        if `"`macval(`ci_tname'_par)'"'=="" {
+            local `ci_tname'_par `""" , """'
+        }
+        gettoken 1 2 : `ci_tname'_par
+        gettoken 2 3 : 2
+        gettoken 3 : 3
+        local `ci_tname'_l_par `""`macval(1)'" "`macval(2)'""'
+        local `ci_tname'_u_par `""" "`macval(3)'""'
+    }
+    if "`ci_l_tname'"!="" {
+        if `"`macval(`ci_l_tname'_label)'"'=="" {
+            local `ci_l_tname'_label "min`level'"
+        }
+    }
+    if "`ci_u_tname'"!="" {
+        if `"`macval(`ci_u_tname'_label)'"'=="" {
+            local `ci_u_tname'_label "max`level'"
+        }
+    }
+
+*Formats
+    local firstv: word 1 of `values'
+    if "`firstv'"=="" local firstv "b"
+    if "``firstv'_fmt'"=="" local `firstv'_fmt %9.0g
+    foreach v of local values {
+        if "``v'_fmt'"=="" local `v'_fmt "``firstv'_fmt'"
+        if `"`macval(`v'_label)'"'=="" {
+            local `v'_label "``v'_'"
+        }
+    }
+
+*Check margin option / prepare discrete option / prepare dropped option
+    if "`margin'"!="" {
+        if !inlist("`margin'","margin","u","c","p") {
+            di as error "margin(`margin') invalid"
+            exit 198
+        }
+        if `"`macval(discrete)'"'!="" {
+            gettoken discrete discrete2: discrete
+        }
+    }
+    else local discrete
+    local droppedison = (`"`macval(dropped)'"'!="")
+
+*Formats/labels/stars for statistics
+    if "`statsfmt'"=="" local statsfmt: word 1 of ``firstv'_fmt'
+    ProcessStatslayout `"`stats'"' `"`statsfmt'"' `"`statsstar'"' ///
+     `"`statslayout'"' `"`statspchar'"'
+    local stats: list uniq stats
+    if "`statsstar'"!="" local p " p"
+    else local p
+
+*Significance stars
+    local tablehasstars 0
+    foreach v of local values {
+        local el "``v'_'"
+        if "``v'_star'"!="" | inlist("`el'","_star","_sigsign") {
+            if "``v'_pvalue'"=="" local `v'_pvalue p
+            local tablehasstars 1
+        }
+    }
+
+*Check/define starlevels/make levelslegend
+    if `tablehasstars' | `"`statsstar'"'!="" {
+        if `"`macval(starlevels)'"'=="" ///
+         local starlevels "* 0.05 ** 0.01 *** 0.001"
+        CheckStarvals `"`macval(starlevels)'"' `"`macval(starlevelslabel)'"' ///
+         `"`macval(starlevelsdelimiter)'"'
+    }
+
+*Get coefficients/variances/statistics: _estout_getres
+*   - prepare transform/eform
+    if `"`transform'"'=="" {  // transform() overwrites eform()
+        if "`eform'"!="" {
+            local transform "exp(@) exp(@)"
+            if "`eform'"!="eform" {
+                local transformpattern "`eform'"
+            }
+        }
+    }
+    foreach m of local transformpattern {
+        if !( "`m'"=="1" | "`m'"=="0" ) {
+            di as error "invalid pattern in transform(,pattern()) or eform()"
+            exit 198
+        }
+    }
+*   - handle pvalue() suboption
+    if `tablehasstars' {
+        local temp
+        foreach v of local values {
+            local temp: list temp | `v'_pvalue
+        }
+        foreach v of local temp {
+            if `"``v'_tname'"'=="" {
+                local `v'_tname "el`++elnum'"
+                local ``v'_tname'_ "`v'"
+                local values: list values | `v'_tname
+            }
+        }
+    }
+*   - prepare list of results to get from e()-matrices
+    if "`ci_tname'"!="" {
+        local values: subinstr local values "`ci_tname'" "`ci_tname'_l `ci_tname'_u", word
+        local `ci_tname'_l_ "ci_l"
+        local ci_l_tname "`ci_tname'_l"
+        local `ci_tname'_u_ ci_u
+        local ci_u_tname "`ci_tname'_u"
+    }
+    foreach v of local values {
+        local temp = ("``v'_transpose'"!="")
+        local values1mrow `"`values1mrow' `"``v'_' `temp' ``v'_mrow'"'"'
+    }
+    tempname B D St
+    if `matrixmode'==0 {
+*   - expand model names
+        if `"`anything'"'=="" {
+            capt est_expand $eststo
+            if !_rc {
+                local anything `"$eststo"'
+            }
+        }
+        if `"`anything'"'=="" local anything "."
+        capt est_expand `"`anything'"'
+        if _rc {
+            if _rc==301 {  // add e(cmd)="." to current estimates if undefined
+                if `:list posof "." in anything' & `"`e(cmd)'"'=="" {
+                    if `"`: e(scalars)'`: e(macros)'`: e(matrices)'`: e(functions)'"'!="" {
+                        qui estadd local cmd "."
+                    }
+                }
+            }
+            est_expand `"`anything'"'
+        }
+        local models `r(names)'
+        // could not happen, ...
+        if "`models'" == "" {
+            exit
+        }
+*   - get results
+        local temp names(`models') coefs(`values1mrow') stats(`stats'`p') ///
+            `rename' margin(`margin') meqs(`meqs') dropped(`droppedison') level(`level') ///
+            transform(`transform') transformpattern(`transformpattern')
+        _estout_getres, `equations' `temp'
+        local ccols = r(ccols)
+        if `"`equations'"'=="" & "`unstack'"=="" & `ccols'>0 { // specify equations("") to deactivate
+            TableIsAMess
+            if `value' {
+                _estout_getres, equations(main=1) `temp'
+            }
+        }
+        mat `St' = r(stats)
+    }
+    else { // matrix mode
+        local models `r(names)'
+        // define `St' so that code does not break
+        if `"`stats'"'!="" {
+            mat `St' = J(`:list sizeof stats',1,.z)
+            mat coln `St' = `models'
+            mat rown `St' = `stats'
+        }
+    }
+    local nmodels = r(nmodels)
+    local ccols = r(ccols)
+    if `ccols'>0 {
+        mat `B'  = r(coefs)
+    }
+    return add
+*   - process order() option
+    if `"`order'"' != "" {
+        ExpandEqVarlist `"`order'"' `B' append
+        local order `"`value'"'
+        Order `B' `"`order'"'
+    }
+*   - process indicate() option
+    local nindicate 0
+    foreach indi of local indicate {
+        local ++nindicate
+        ProcessIndicateGrp `nindicate' `B' `nmodels' "`unstack'" ///
+        `"`macval(indicatelabels)'"' `"`macval(indi)'"'
+    }
+*   - process keep() option
+    if `"`keep'"' != "" {
+        ExpandEqVarlist `"`keep'"' `B'
+        DropOrKeep 1 `B' `"`value'"'
+    }
+*   - process drop() option
+    if `"`drop'"' != "" {
+        ExpandEqVarlist `"`drop'"' `B'
+        DropOrKeep 0 `B' `"`value'"'
+    }
+
+*   - names and equations of final set
+    capt confirm matrix `B'
+    if _rc {
+        return local coefs  ""  // erase r(coefs)
+        return local ccols  ""
+        local R 0
+        local varlist       ""
+        local eqlist        ""
+        local eqs           "_"
+        local fullvarlist   ""
+    }
+    else {
+        return matrix coefs = `B', copy // replace r(coefs)
+        local R = rowsof(`B')
+        local C = colsof(`B')
+        QuotedRowNames `B'
+        local varlist `"`value'"'
+        local eqlist: roweq `B', q
+        local eqlist: list clean eqlist
+        UniqEqsAndDims `"`eqlist'"'
+        MakeQuotedFullnames `"`varlist'"' `"`eqlist'"'
+        local fullvarlist `"`value'"'
+*   - dropped coefs
+        local droppedpos = `ccols'
+        if "`margin'"!="" {
+            local droppedpos `droppedpos' - 1
+        }
+*   - 0/1-variable indicators (for marginals)
+        mat `D' = `B'[1...,1], J(`R',1,0)  // so that row names are copied from `B'
+        mat `D' = `D'[1...,2]
+        if "`margin'"!="" {
+            forv i = 1/`R' {    // last colum for each model contains _dummy info
+                forv j = `ccols'(`ccols')`C' {
+                    if `B'[`i',`j']==1 {
+                        mat `D'[`i',1] = 1
+                    }
+                }
+            }
+        }
+    }
+
+*Prepare element specific keep/drop
+    local dash
+    tempname tmpmat
+    foreach v in star `values' {
+        local temp `"`fullvarlist'"'
+        if "`unstack'"!="" {
+            local temp2: list uniq eqs
+            local `v'`dash'eqdrop: list uniq eqs
+        }
+        if `"``v'`dash'keep'"'!="" {
+            capt mat `tmpmat' = `B'
+            ExpandEqVarlist `"``v'`dash'keep'"' `tmpmat'
+            DropOrKeep 1 `tmpmat' `"`value'"'
+            capt confirm matrix `tmpmat'
+            if _rc local temp
+            else {
+                QuotedRowNames `tmpmat'
+                MakeQuotedFullnames `"`value'"' `"`: roweq `tmpmat', q'"'
+                local temp: list temp & value
+                if "`unstack'"!="" {
+                    local value: roweq `tmpmat', q
+                    local value: list uniq value
+                    local temp2: list temp2 & value
+                }
+            }
+        }
+        if `"``v'`dash'drop'"'!="" {
+            capt mat `tmpmat' = `B'
+            ExpandEqVarlist `"``v'`dash'drop'"' `tmpmat'
+            DropOrKeep 0 `tmpmat' `"`value'"'
+            capt confirm matrix `tmpmat'
+            if _rc local temp
+            else {
+                QuotedRowNames `tmpmat'
+                MakeQuotedFullnames `"`value'"' `"`: roweq `tmpmat', q'"'
+                local temp: list temp & value
+                if "`unstack'"!="" {
+                    local value: roweq `tmpmat', q
+                    local value: list uniq value
+                    local temp2: list temp2 & value
+                }
+            }
+        }
+        local `v'`dash'drop: list fullvarlist - temp
+        if "`unstack'"!="" {
+            local `v'`dash'eqdrop: list `v'`dash'eqdrop - temp2
+        }
+        local dash "_"
+    }
+    capt mat drop `tmpmat'
+
+*Prepare unstack
+    if "`unstack'"!="" & `R'>0 {
+        local varlist: list uniq varlist
+        GetVarnamesFromOrder `"`order'"'
+        local temp: list value & varlist
+        local varlist: list temp | varlist
+        local cons _cons
+        if `:list cons in value'==0 {
+            if `:list cons in varlist' {
+                local varlist: list varlist - cons
+                local varlist: list varlist | cons
+            }
+        }
+        local R: word count `varlist'
+        local eqswide: list uniq eqs
+        forv i=1/`nindicate' {
+            ReorderEqsInIndicate `"`nmodels'"' `"`eqswide'"' ///
+             `"`indicate`i'eqs'"' `"`macval(indicate`i'lbls)'"'
+            local indicate`i'lbls `"`macval(value)'"'
+        }
+    }
+    else local eqswide "_"
+
+*Prepare coefs for tabulation
+    if `R'>0 {
+        local i 0
+        foreach v of local values {
+            local ++i
+            tempname _`v'
+            forv j = 1/`nmodels' {
+                mat `_`v'' = nullmat(`_`v''), `B'[1..., (`j'-1)*`ccols'+`i']
+            }
+            mat coln `_`v'' = `models'
+            mat coleq `_`v'' = `models'
+            if inlist("``v'_'", "t", "z") {
+                if `"``v'_abs'"'!="" {  // absolute t-values
+                    forv r = 1/`R' {
+                        forv j = 1/`nmodels' {
+                            if `_`v''[`r',`j']>=. continue
+                            mat `_`v''[`r',`j'] = abs(`_`v''[`r',`j'])
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+*Model labels
+    if "`nomlabelstitles'"=="" & "`label'"!="" local mlabelstitles titles
+    local tmp: list sizeof mlabels
+    local i 0
+    foreach model of local models {
+        local ++i
+        if `i'<=`tmp' continue
+        local lab
+        if "`mlabelsdepvars'"!="" {
+            local var `"`return(m`i'_depname)'"'
+            if "`label'"!="" {
+                local temp = index(`"`var'"',".")
+                local temp2  = substr(`"`var'"',`temp'+1,.)
+                capture local lab: var l `temp2'
+                if _rc | `"`lab'"'=="" {
+                    local lab `"`temp2'"'
+                }
+                local temp2 = substr(`"`var'"',1,`temp')
+                local lab `"`temp2'`macval(lab)'"'
+            }
+            else local lab `"`var'"'
+        }
+        else if "`mlabelstitles'"!="" {
+                local lab `"`return(m`i'_estimates_title)'"'
+                if `"`lab'"'=="" local lab "`model'"
+        }
+        else {
+            local lab "`model'"
+        }
+        local mlabels `"`macval(mlabels)' `"`macval(lab)'"'"'
+    }
+    if "`mlabelsnumbers'"!="" {
+        NumberMlabels `nmodels' `"`macval(mlabels)'"'
+    }
+
+*Equations labels
+    local eqconssubok = (`"`macval(eqlabels)'"'!=`""""')
+    local numeqs: list sizeof eqs
+    local temp: list sizeof eqlabels
+    if `temp'<`numeqs' {
+        forv i = `=`temp'+1'/`numeqs' {
+            local eq: word `i' of `eqs'
+            local value
+            if "`label'"!="" {
+                capture confirm variable `eq'
+                if !_rc {
+                    local value: var l `eq'
+                }
+            }
+            if `"`value'"'=="" local value "`eq'"
+            local eqlabels `"`macval(eqlabels)' `"`value'"'"'
+        }
+    }
+    if `eqconssubok' {
+        if "`eqlabelsnone'"!="" & `numeqs'>1 & "`unstack'"=="" {
+            EqReplaceCons `"`varlist'"' `"`eqlist'"' `"`eqlabels'"' `"`macval(varlabels)'"'
+            if `"`macval(value)'"'!="" {
+                local varlabels `"`macval(value)' `macval(varlabels)'"'
+            }
+        }
+    }
+
+*Column labels
+    if `"`macval(collabels)'"'=="" {
+        forv j = 1/`ncols' {
+            local temp
+            forv i = 1/`nrows' {
+                local v: word `i' of `cells'
+                local v: word `j' of `v'
+                local v: subinstr local v "&" " ", all
+                local v: subinstr local v "." "", all
+                local v: list retok v
+                foreach vi of local v {
+                    if `"`macval(temp)'"'!="" {
+                        local temp `"`macval(temp)'/"'
+                    }
+                    local temp `"`macval(temp)'`macval(`vi'_label)'"'
+                }
+            }
+            local collabels `"`macval(collabels)'`"`macval(temp)'"' "'
+        }
+    }
+
+*Prepare refcat()
+    if `"`macval(refcat)'"'!="" {
+        PrepareRefcat `"`macval(refcat)'"'
+    }
+
+*Determine table layout
+    local m 1
+    local starcol 0
+    foreach model of local models {
+        local e 0
+        foreach eq of local eqswide {
+            local stc 0
+            local ++e
+            if "`unstack'"!="" & `R'>0 {
+                ModelEqCheck `B' `"`eq'"' `m' `ccols'
+                if !`value' continue
+            }
+            local eqsrow "`eqsrow'`e' "
+            local modelsrow "`modelsrow'`m' "
+            local k 0
+            local something 0
+            forv j = 1/`ncols' {
+                local col
+                local nocol 1
+                local colhasstats 0
+                forv i = 1/`nrows' {
+                    local row: word `i' of `cells'
+                    local v: word `j' of `row'
+                    local v: subinstr local v "&" " ", all
+                    foreach vi in `v' {
+                        if "`vi'"=="." continue
+                        local colhasstats 1
+                        if "`unstack'"!="" {
+                            if `:list eq in `vi'_eqdrop' continue
+                        }
+                        if "`:word `m' of ``vi'_pattern''"=="0" {
+                            local v: subinstr local v "`vi'" ".`vi'", word
+                        }
+                        else {
+                            local nocol 0
+                            if `"``vi'_star'"'!="" local starcol 1
+                        }
+                    }
+                    local v: subinstr local v " " "&", all
+                    if "`v'"=="" local v "."
+                    local col "`col'`v' "
+                }
+                if `colhasstats'==0 local nocol 0
+                if !`nocol' {
+                    local colsrow "`colsrow'`j' "
+                    if `++k'>1 {
+                        local modelsrow "`modelsrow'`m' "
+                        local eqsrow "`eqsrow'`e' "
+                    }
+                    if `"`: word `++stc' of `statscolstar''"'=="1" local starcol 1
+                    local starsrow "`starsrow'`starcol' "
+                    local starcol 0
+                    Add2Vblock `"`vblock'"' "`col'"
+                    local something 1
+                }
+            }
+            if !`something' {
+                local col
+                forv i = 1/`nrows' {
+                    local col "`col'. "
+                }
+                Add2Vblock `"`vblock'"' "`col'"
+                local colsrow "`colsrow'1 "
+                if `"`: word `++stc' of `statscolstar''"'=="1" local starcol 1
+                local starsrow "`starsrow'`starcol' "
+                local starcol 0
+            }
+        }
+        local ++m
+    }
+    CountNofEqs "`modelsrow'" "`eqsrow'"
+    local neqs `value'
+    if `"`extracols'"'!="" {
+        foreach row in model eq col star {
+            InsertAtCols `"`extracols'"' `"``row'srow'"'
+            local `row'srow `"`value'"'
+        }
+        foreach row of local vblock {
+            InsertAtCols `"`extracols'"' `"`row'"'
+            local nvblock `"`nvblock' `"`value'"'"'
+        }
+        local vblock: list clean nvblock
+    }
+    local ncols = `: word count `starsrow'' + 1 + `haslabcol2'
+
+*Modelwidth/varwidth/starwidth
+    if "`modelwidth'"=="" local modelwidth 0
+    if "`varwidth'"=="" local varwidth 0
+    local nmodelwidth: list sizeof modelwidth
+    local modelwidthzero: list uniq modelwidth
+    local modelwidthzero = ("`modelwidth'"=="0")
+    if "`labcol2width'"=="" local labcol2width `: word 1 of `modelwidth''
+    local starwidth 0
+    if `modelwidthzero'==0 {
+        if `tablehasstars' | `"`statsstar'"'!="" {
+            Starwidth `"`macval(starlevels)'"'
+            local starwidth `value'
+        }
+    }
+    if `varwidth'<2 local wrap
+
+* totcharwidth / hline
+    local totcharwidth `varwidth'
+    capture {
+        local delwidth = length(`macval(delimiter)')
+    }
+    if _rc {
+        local delwidth = length(`"`macval(delimiter)'"')
+    }
+    if `haslabcol2' {
+        local totcharwidth = `totcharwidth' + `delwidth' + `labcol2width'
+    }
+    local j 0
+    foreach i of local starsrow {
+        local modelwidthj: word `=1 + mod(`j++',`nmodelwidth')' of `modelwidth'
+        local totcharwidth = `totcharwidth' + `delwidth' + `modelwidthj'
+        if `i' {
+            if "`stardetach'"!="" {
+                local ++ncols
+                local totcharwidth = `totcharwidth' + `delwidth'
+            }
+            local totcharwidth = `totcharwidth' + `starwidth'
+        }
+    }
+    IsInString "@hline" `"`0'"'  // sets local strcount
+    if `strcount' {
+        local hline `totcharwidth'
+        if `hline'>400 local hline 400 // _dup(400) is limit
+        if `"`macval(hlinechar)'"'=="" local hlinechar "-"
+        local hline: di _dup(`hline') `"`macval(hlinechar)'"'
+    }
+    else local hline
+
+* check begin, delimiter, end
+    tempfile tfile
+    tempname file
+    file open `file' using `"`tfile'"', write text
+    foreach opt in begin delimiter end {
+        capture file write `file' `macval(`opt')'
+        if _rc {
+            local `opt' `"`"`macval(`opt')'"'"'
+        }
+    }
+    file close `file'
+
+* RTF support: set macros rtfrowdef, rtfrowdefbrdrt, rtfrowdefbrdrb, rtfemptyrow
+    local hasrtfbrdr 0
+    local rtfbrdron 0
+    IsInString "@rtfrowdef" `"`begin'"' // sets local strcount
+    local hasrtf = `strcount'
+    if `hasrtf' {
+        MakeRtfRowdefs `"`macval(begin)'"' `"`starsrow'"' "`stardetach'" ///
+            `varwidth' "`modelwidth'" `haslabcol2' `labcol2width'
+        local varwidth 0
+        local wrap
+        local modelwidth 0
+        local nmodelwidth 1
+        local modelwidthzero 1
+        local starwidth 0
+        local labcol2width 0
+        IsInString "@rtfrowdefbrdr" `"`begin'"' // sets local strcount
+        if `strcount' {
+            local hasrtfbrdr 1
+            local rtfbeginbak `"`macval(begin)'"'
+            local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdefbrdrt'"'
+            local rtfbrdron 1
+        }
+        else {
+            local begin: subinstr local begin "@rtfrowdef" `"`rtfrowdef'"'
+        }
+    }
+
+* set widths
+    if `starwidth'>0 local fmt_stw "%-`starwidth's"
+    if `varwidth'>0 local fmt_v "%-`varwidth's"
+    if `labcol2width'>0 local fmt_l2 "%~`labcol2width's"
+    if "`mgroupsspan'`mlabelsspan'`eqlabelsspan'`collabelsspan'"!="" {
+        if `modelwidthzero'==0 {
+            file open `file' using `"`tfile'"', write text replace
+            file write `file' `macval(delimiter)'
+            file close `file'
+            file open `file' using `"`tfile'"', read text
+            file read `file' delwidth
+            file close `file'
+            local delwidth = length(`"`macval(delwidth)'"')
+        }
+        else local delwidth 0
+    }
+    local stardetachon = ("`stardetach'"!="")
+    if `stardetachon' {
+        local stardetach `"`macval(delimiter)'"'
+    }
+
+*Prepare @-Variables
+    local atvars2 `""`nmodels'" "`neqs'" "`totcharwidth'" `"`macval(hline)'"' `hasrtf' `"`rtfrowdefbrdrt'"' `"`rtfrowdefbrdrb'"' `"`rtfrowdef'"' `"`rtfemptyrow'"'"'
+    local atvars3 `"`"`macval(title)'"' `"`macval(note)'"' `"`macval(discrete)'`macval(discrete2)'"' `"`macval(starlegend)'"'"'
+
+*Open output file
+    file open `file' using `"`tfile'"', write text replace
+
+*Write prehead
+    if `"`macval(prehead)'"'!="" {
+        if index(`"`macval(prehead)'"',`"""')==0 {
+            local prehead `"`"`macval(prehead)'"'"'
+        }
+    }
+    foreach line of local prehead {
+        if "`smcltags'"!="" file write `file' "{txt}"
+        InsertAtVariables `"`macval(line)'"' 0 "`ncols'" `macval(atvars2)' `macval(atvars3)'
+        file write `file' `"`macval(value)'"' _n
+    }
+    local hasheader 0
+    if "`smcltags'"!="" local thesmclrule "{txt}{hline `totcharwidth'}"
+    else                local thesmclrule "{hline `totcharwidth'}"
+    if "`smclrules'"!="" {
+        file write `file' `"`thesmclrule'"' _n
+    }
+
+*Labcol2 - title
+    if `haslabcol2' {
+        IsInString `"""' `"`macval(labcol2title)'"' // sets local strcount
+        if `strcount'==0 {
+            local labcol2chunk `"`macval(labcol2title)'"'
+            local labcol2rest ""
+        }
+        else {
+            gettoken labcol2chunk labcol2rest : labcol2title
+        }
+    }
+
+*Write head: Models groups
+    if "`mgroupsnone'"=="" & `"`macval(mgroups)'"'!="" {
+        local hasheader 1
+        if "`smcltags'"!="" file write `file' "{txt}"
+        InsertAtVariables `"`macval(mgroupsbegin)'"' 2 "`ncols'" `macval(atvars2)'
+        local mgroupsbegin `"`macval(value)'"'
+        InsertAtVariables `"`macval(mgroupsend)'"' 2 "`ncols'" `macval(atvars2)'
+        local mgroupsend `"`macval(value)'"'
+        local tmpbegin `"`macval(begin)'"'
+        local tmpend `"`macval(end)'"'
+        if "`mgroupsreplace'"!="" {
+            if `"`macval(mgroupsbegin)'"'!="" local tmpbegin
+            if `"`macval(mgroupsend)'"'!=""  local tmpend
+        }
+        MgroupsPattern "`modelsrow'" "`mgroupspattern'"
+        Abbrev `varwidth' `"`macval(mgroupslhs)'"' "`abbrev'"
+        WriteBegin `"`file'"' `"`macval(mgroupsbegin)'"' `"`macval(tmpbegin)'"' ///
+         `"`fmt_v' (`"`macval(value)'"')"'
+        if `haslabcol2' {
+            Abbrev `labcol2width' `"`macval(labcol2chunk)'"' "`abbrev'"
+            file write `file' `macval(delimiter)' `fmt_l2' (`"`macval(value)'"')
+        }
+        WriteCaption `"`file'"' `"`macval(delimiter)'"' ///
+            `"`macval(stardetach)'"' "`mgroupspattern'" "`mgroupspattern'" ///
+            `"`macval(mgroups)'"' "`starsrow'" "`mgroupsspan'" "`abbrev'" ///
+            "`modelwidth'" "`delwidth'" "`starwidth'" ///
+            `"`macval(mgroupserepeat)'"' `"`macval(mgroupsprefix)'"' ///
+            `"`macval(mgroupssuffix)'"'
+        WriteEnd `"`file'"' `"`macval(tmpend)'"' `"`macval(mgroupsend)'"' ///
+         `"`"`macval(value)'"'"'
+        if `hasrtfbrdr' & `rtfbrdron' {
+            local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdef'"'
+            local rtfbrdron 0
+        }
+        gettoken labcol2chunk labcol2rest : labcol2rest
+    }
+
+*Write head: Models numbers
+    if `"`macval(numbers)'"'!="" {
+        local hasheader 1
+        if "`smcltags'"!="" file write `file' "{txt}"
+        if `"`macval(numbers)'"'=="numbers" local numbers "( )"
+        file write `file' `macval(begin)' `fmt_v' (`""')
+        if `haslabcol2' {
+            Abbrev `labcol2width' `"`macval(labcol2chunk)'"' "`abbrev'"
+            file write `file' `macval(delimiter)' `fmt_l2' (`"`macval(value)'"')
+        }
+        tokenize `"`macval(numbers)'"'
+        numlist `"1/`nmodels'"'
+        WriteCaption `"`file'"' `"`macval(delimiter)'"' ///
+            `"`macval(stardetach)'"' "`modelsrow'" "`modelsrow'"  ///
+            "`r(numlist)'" "`starsrow'" "`mlabelsspan'" "`abbrev'"  ///
+            "`modelwidth'" "`delwidth'" "`starwidth'" ///
+            `""' `"`macval(1)'"' `"`macval(2)'"'
+        file write `file' `macval(end)' _n
+        if `hasrtfbrdr' & `rtfbrdron' {
+            local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdef'"'
+            local rtfbrdron 0
+        }
+        gettoken labcol2chunk labcol2rest : labcol2rest
+    }
+
+*Write head: Models captions
+    if "`nomlabelsnone'"=="" & "`models'"=="." & `"`macval(mlabels)'"'=="." local mlabelsnone "none"
+    if "`mlabelsnone'"=="" {
+        local hasheader 1
+        if "`smcltags'"!="" file write `file' "{txt}"
+        InsertAtVariables `"`macval(mlabelsbegin)'"' 2 "`ncols'" `macval(atvars2)'
+        local mlabelsbegin `"`macval(value)'"'
+        InsertAtVariables `"`macval(mlabelsend)'"' 2 "`ncols'" `macval(atvars2)''
+        local mlabelsend `"`macval(value)'"'
+        local tmpbegin `"`macval(begin)'"'
+        local tmpend `"`macval(end)'"'
+        if "`mlabelsreplace'"!="" {
+            if `"`macval(mlabelsbegin)'"'!="" local tmpbegin
+            if `"`macval(mlabelsend)'"'!=""  local tmpend
+        }
+        Abbrev `varwidth' `"`macval(mlabelslhs)'"' "`abbrev'"
+        WriteBegin `"`file'"' `"`macval(mlabelsbegin)'"' `"`macval(tmpbegin)'"' ///
+         `"`fmt_v' (`"`macval(value)'"')"'
+        if `haslabcol2' {
+            Abbrev `labcol2width' `"`macval(labcol2chunk)'"' "`abbrev'"
+            file write `file' `macval(delimiter)' `fmt_l2' (`"`macval(value)'"')
+        }
+        WriteCaption `"`file'"' `"`macval(delimiter)'"' ///
+            `"`macval(stardetach)'"' "`modelsrow'" "`modelsrow'"  ///
+            `"`macval(mlabels)'"' "`starsrow'" "`mlabelsspan'" "`abbrev'"  ///
+            "`modelwidth'" "`delwidth'" "`starwidth'" ///
+            `"`macval(mlabelserepeat)'"' `"`macval(mlabelsprefix)'"' ///
+            `"`macval(mlabelssuffix)'"'
+        WriteEnd `"`file'"' `"`macval(tmpend)'"' `"`macval(mlabelsend)'"' ///
+         `"`"`macval(value)'"'"'
+        if `hasrtfbrdr' & `rtfbrdron' {
+            local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdef'"'
+            local rtfbrdron 0
+        }
+        gettoken labcol2chunk labcol2rest : labcol2rest
+    }
+
+*Write head: Equations captions
+    if "`eqlabelsnone'"=="" {
+        InsertAtVariables `"`macval(eqlabelsbegin)'"' 2 "`ncols'" `macval(atvars2)'
+        local eqlabelsbegin `"`macval(value)'"'
+        InsertAtVariables `"`macval(eqlabelsend)'"' 2 "`ncols'" `macval(atvars2)'
+        local eqlabelsend `"`macval(value)'"'
+    }
+    if `"`eqswide'"'!="_" & "`eqlabelsnone'"=="" {
+        local hasheader 1
+        local tmpbegin `"`macval(begin)'"'
+        local tmpend `"`macval(end)'"'
+        if "`eqlabelsreplace'"!="" {
+            if `"`macval(eqlabelsbegin)'"'!="" local tmpbegin
+            if `"`macval(eqlabelsend)'"'!=""  local tmpend
+        }
+        if "`smcltags'"!="" file write `file' "{txt}"
+        Abbrev `varwidth' `"`macval(eqlabelslhs)'"' "`abbrev'"
+        WriteBegin `"`file'"' `"`macval(eqlabelsbegin)'"' `"`macval(tmpbegin)'"' ///
+         `"`fmt_v' (`"`macval(value)'"')"'
+        if `haslabcol2' {
+            Abbrev `labcol2width' `"`macval(labcol2chunk)'"' "`abbrev'"
+            file write `file' `macval(delimiter)' `fmt_l2' (`"`macval(value)'"')
+        }
+        WriteCaption `"`file'"' `"`macval(delimiter)'"' ///
+            `"`macval(stardetach)'"' "`eqsrow'" "`modelsrow'" ///
+            `"`macval(eqlabels)'"' "`starsrow'" "`eqlabelsspan'"  "`abbrev'" ///
+            "`modelwidth'" "`delwidth'" "`starwidth'" ///
+            `"`macval(eqlabelserepeat)'"' `"`macval(eqlabelsprefix)'"' ///
+            `"`macval(eqlabelssuffix)'"'
+        WriteEnd `"`file'"' `"`macval(tmpend)'"' `"`macval(eqlabelsend)'"' ///
+         `"`"`macval(value)'"'"'
+        if `hasrtfbrdr' & `rtfbrdron' {
+            local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdef'"'
+            local rtfbrdron 0
+        }
+        gettoken labcol2chunk labcol2rest : labcol2rest
+    }
+
+*Write head: Columns captions
+    if `"`macval(collabels)'"'!="" & "`collabelsnone'"=="" {
+        local hasheader 1
+        if "`smcltags'"!="" file write `file' "{txt}"
+        InsertAtVariables `"`macval(collabelsbegin)'"' 2 "`ncols'" `macval(atvars2)'
+        local collabelsbegin `"`macval(value)'"'
+        InsertAtVariables `"`macval(collabelsend)'"' 2 "`ncols'" `macval(atvars2)'
+        local collabelsend `"`macval(value)'"'
+        local tmpbegin `"`macval(begin)'"'
+        local tmpend `"`macval(end)'"'
+        if "`collabelsreplace'"!="" {
+            if `"`macval(collabelsbegin)'"'!="" local tmpbegin
+            if `"`macval(collabelsend)'"'!=""  local tmpend
+        }
+        Abbrev `varwidth' `"`macval(collabelslhs)'"' "`abbrev'"
+        WriteBegin `"`file'"' `"`macval(collabelsbegin)'"' `"`macval(tmpbegin)'"' ///
+         `"`fmt_v' (`"`macval(value)'"')"'
+        if `haslabcol2' {
+            Abbrev `labcol2width' `"`macval(labcol2chunk)'"' "`abbrev'"
+            file write `file' `macval(delimiter)' `fmt_l2' (`"`macval(value)'"')
+        }
+        WriteCaption `"`file'"' `"`macval(delimiter)'"' ///
+            `"`macval(stardetach)'"' "`colsrow'" "" `"`macval(collabels)'"' ///
+            "`starsrow'" "`collabelsspan'" "`abbrev'" "`modelwidth'" ///
+            "`delwidth'" "`starwidth'" `"`macval(collabelserepeat)'"' ///
+            `"`macval(collabelsprefix)'"' `"`macval(collabelssuffix)'"'
+        WriteEnd `"`file'"' `"`macval(tmpend)'"' `"`macval(collabelsend)'"' ///
+         `"`"`macval(value)'"'"'
+        if `hasrtfbrdr' & `rtfbrdron' {
+            local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdef'"'
+            local rtfbrdron 0
+        }
+        gettoken labcol2chunk labcol2rest : labcol2rest
+    }
+
+*Write posthead
+    if `hasheader' & "`smclmidrules'"!="" {
+        file write `file' `"`thesmclrule'"' _n
+    }
+    if `"`macval(posthead)'"'!="" {
+        if index(`"`macval(posthead)'"',`"""')==0 {
+            local posthead `"`"`macval(posthead)'"'"'
+        }
+    }
+    foreach line of local posthead {
+        if "`smcltags'"!="" file write `file' "{txt}"
+        InsertAtVariables `"`macval(line)'"' 0 "`ncols'" `macval(atvars2)' `macval(atvars3)'
+        file write `file' `"`macval(value)'"' _n
+    }
+
+* Create mmd alignment/divider line
+    if `"`defaults'"'=="mmd" {
+        MakeMMDdef "`varwidth'" "`haslabcol2'" "`labcol2width'" ///
+            "`modelwidth'" "`starsrow'" "`stardetachon'" "`starwidth'"
+        file write `file' `"`macval(value)'"' _n
+    }
+
+*Write body of table
+*Loop over table rows
+    InsertAtVariables `"`macval(varlabelsbegin)'"' 2 "`ncols'" `macval(atvars2)'
+    local varlabelsbegin `"`macval(value)'"'
+    InsertAtVariables `"`macval(varlabelsend)'"' 2 "`ncols'" `macval(atvars2)'
+    local varlabelsend `"`macval(value)'"'
+    tempname first
+    if `"`vblock'"'!="" {
+        local RI = `R' + `nindicate'
+        local e 0
+        local eqdim = `R' + `nindicate'
+        local weqcnt 0
+        local theeqlabel
+        if `hasrtfbrdr' {
+            local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdefbrdrt'"'
+            local rtfbrdron 1
+        }
+        local varlabelsbegin0 `"`macval(varlabelsbegin)'"'
+        local eqlabelsbegin0 `"`macval(eqlabelsbegin)'"'
+        if "`eqlabelsfirst'"=="" local eqlabelsbegin0
+        forv r = 1/`R' {
+            local varlabelsend0 `"`macval(varlabelsend)'"'
+            local var: word `r' of `varlist'
+
+*Write equation name/label
+            if "`unstack'"=="" {
+                local eqvar: word `r' of `fullvarlist'
+                if `"`eqs'"'!="_" {
+                    local eqrlast `"`eqr'"'
+                    local eqr: word `r' of `eqlist'
+                    if `"`eqr'"'!=`"`eqrlast'"' & "`eqlabelsnone'"=="" {
+                        local value: word `++e' of `macval(eqlabels)'
+                        local eqdim: word `e' of `macval(eqsdims)'
+                        local weqcnt 0
+                        if `e'==`numeqs' {
+                            if "`eqlabelslast'"=="" local eqlabelsend
+                            local eqdim = `eqdim' + `nindicate'
+                        }
+                        if "`eqlabelsmerge'"!="" {
+                            local theeqlabel `"`macval(eqlabelsprefix)'`macval(value)'`macval(eqlabelssuffix)'"'
+                        }
+                        else {
+                            local tmpbegin `"`macval(begin)'"'
+                            local tmpend `"`macval(end)'"'
+                            if "`eqlabelsreplace'"!="" {
+                                if `"`macval(eqlabelsbegin0)'"'!="" local tmpbegin
+                                if `"`macval(eqlabelsend)'"'!=""  local tmpend
+                            }
+                            if `e'>1 & "`smcleqrules'"!="" {
+                                file write `file' `"`thesmclrule'"' _n
+                            }
+                            WriteBegin `"`file'"' `"`macval(eqlabelsbegin0)'"' `"`macval(tmpbegin)'"'
+                            if "`smcltags'"!="" file write `file' "{res}"
+                            WriteEqrow `"`file'"' `"`macval(delimiter)'"' ///
+                                `"`macval(stardetach)'"' `"`macval(value)'"' "`starsrow'" ///
+                                "`eqlabelsspan'" "`varwidth'" "`fmt_v'" "`abbrev'" ///
+                                "`modelwidth'" "`delwidth'" "`starwidth'" ///
+                                `"`macval(eqlabelsprefix)'"' `"`macval(eqlabelssuffix)'"' ///
+                                "`haslabcol2'" "`labcol2width'" "`fmt_l2'"
+                            if "`smcltags'"!="" file write `file' "{txt}"
+                            WriteEnd `"`file'"' `"`macval(tmpend)'"' `"`macval(eqlabelsend)'"'
+                            if `hasrtfbrdr' & `rtfbrdron' {
+                                local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdef'"'
+                                local rtfbrdron 0
+                            }
+                            local eqlabelsbegin0 `"`macval(eqlabelsbegin)'"'
+                        }
+                    }
+                }
+            }
+            local ++weqcnt
+            if `weqcnt'==1 {
+                if "`varlabelsfirst'"=="" local varlabelsbegin0
+            }
+
+*Determine rows to be written
+            local rvblock
+            foreach row of local vblock {
+                local c 0
+                local skiprow 1
+                local rowhasstats 0
+                foreach v of local row {
+                    local ++c
+                    if "`unstack'"!="" {
+                        local eqr: word `:word `c' of `eqsrow'' of `eqs'
+                        if `"`eqr'"'!="" local eqvar `"`eqr':`var'"'
+                        else local eqvar "`var'"
+                    }
+                    local v: subinstr local v "&" " ", all
+                    foreach vi of local v {
+                        if "`vi'"=="." continue
+                        if rownumb(`B',`"`eqvar'"')<. {
+                            local rowhasstats 1
+                            if index("`vi'",".")==1 continue
+                            if `: list eqvar in `vi'_drop' continue
+                            local skiprow 0
+                            continue, break
+                        }
+                    }
+                    if `skiprow'==0 continue, break
+                }
+                if `rowhasstats'==0 local skiprow 0
+                if `"`ferest()'"'=="" & `"`rvblock'"'=="" local skiprow 0
+                if `skiprow' continue
+                local rvblock `"`rvblock'"`row'" "'
+            }
+            local nrvblock: list sizeof rvblock
+
+*Insert refcat() (unless refcatbelow)
+            if `"`macval(refcat)'"'!="" {
+                local isref: list posof "`var'" in refcatcoefs
+                if `isref' {
+                    if "`unstack'"=="" {
+                        local temp `"`eqr'"'
+                        if `"`temp'"'=="" local temp "_"
+                    }
+                    else local temp `"`eqswide'"'
+                    GenerateRefcatRow `B' `ccols' "`var'" `"`temp'"' `"`macval(refcatlabel)'"'
+                    local refcatrow `"`macval(value)'"'
+                }
+            }
+            else local isref 0
+            if `isref' & `"`refcatbelow'"'=="" {
+                if "`smcltags'"!="" file write `file' "{txt}"
+                local tmpbegin `"`macval(begin)'"'
+                local tmpend `"`macval(end)'"'
+                if "`varlabelsreplace'"!="" {
+                    if `"`macval(varlabelsbegin0)'"'!="" local tmpbegin
+                    if `"`macval(varlabelsend0)'"'!=""  local tmpend
+                }
+                if "`varlabelsnone'"=="" {
+                    local value: word `isref' of `macval(refcatnames)'
+                    Abbrev `varwidth' `"`macval(value)'"' "`abbrev'"
+                }
+                else local value
+                WriteBegin `"`file'"' `"`macval(varlabelsbegin0)'"' `"`macval(tmpbegin)'"' ///
+                 `"`fmt_v' (`"`macval(varlabelsprefix)'`macval(value)'`macval(varlabelssuffix)'"')"'
+                if `haslabcol2' {
+                    gettoken labcol2chunk labcol2 : labcol2
+                    Abbrev `labcol2width' `"`macval(labcol2chunk)'"' "`abbrev'"
+                    file write `file' `macval(delimiter)' `fmt_l2' (`"`macval(value)'"')
+                }
+                if "`smcltags'"!="" file write `file' "{res}"
+                WriteStrRow `"`file'"' "`modelsrow'" `"`eqsrow'"' `"`: list sizeof eqswide'"' ///
+                    `"`macval(refcatrow)'"' `"`macval(delimiter)'"' ///
+                    `"`macval(stardetach)'"' "`starsrow'" "`abbrev'"  ///
+                    "`modelwidth'" "`delwidth'" "`starwidth'"
+                if "`smcltags'"!="" file write `file' "{txt}"
+                WriteEnd `"`file'"' `"`macval(tmpend)'"' `"`macval(varlabelsend0)'"'
+                if `hasrtfbrdr' & `rtfbrdron' {
+                    local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdef'"'
+                    local rtfbrdron 0
+                }
+                local varlabelsbegin0 `"`macval(varlabelsbegin)'"'
+            }
+
+*Write variable name/label
+            if "`smcltags'"!="" file write `file' "{txt}"
+            local tmpbegin `"`macval(begin)'"'
+            if "`varlabelsnone'"=="" {
+                VarInList `"`var'"' "`unstack'" `"`eqvar'"' ///
+                 `"`eqr'"' `"`macval(varlabelsblist)'"'
+                if `"`macval(value)'"'!="" {
+                    IsInString `"""' `"`value'"' // sets local strcount
+                    if `strcount'==0 {
+                        local value `"`"`macval(value)'"'"'
+                    }
+                    InsertAtVariables `"`macval(value)'"' 2 "`ncols'" `macval(atvars2)'
+                    WriteStrLines `"`file'"' `"`macval(value)'"'
+                    if "`varlabelsreplace'"!="" {
+                        local tmpbegin
+                        local varlabelsbegin0
+                    }
+                }
+                if "`label'"!="" {
+                    local temp = index("`var'",".")
+                    local temp2  = substr(`"`var'"',`temp'+1,.)
+                    capture local varl: var l `temp2'
+                    if _rc | `"`varl'"'=="" {
+                        local varl `"`temp2'"'
+                    }
+                    local temp2 = substr(`"`var'"',1,`temp')
+                    local varl `"`temp2'`macval(varl)'"'
+                }
+                else local varl `var'
+                VarInList `"`var'"' "`unstack'" `"`eqvar'"' ///
+                 `"`eqr'"' `"`macval(varlabels)'"'
+                if `"`macval(value)'"'!="" {
+                    local varl `"`macval(value)'"'
+                }
+                if `"`macval(discrete)'"'!="" {
+                    local temp 0
+                    if "`unstack'"=="" {
+                        if `D'[`r',1]==1 local temp 1
+                    }
+                    else {
+                        foreach eqr of local eqswide {
+                            if `D'[rownumb(`D',`"`eqr':`var'"'),1]==1 local temp 1
+                        }
+                    }
+                    if `temp'==1 & `temp'<. {
+                        local varl `"`macval(varl)'`macval(discrete)'"'
+                    }
+                }
+            }
+            else local varl
+            if `hasrtfbrdr' & `r'==`RI' & !(`isref' & `"`refcatbelow'"'!="") {
+                if `nrvblock'==1 {
+                    local tmpbegin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdefbrdrb'"'
+                    local rtfbrdron 1
+                }
+            }
+            if "`varlabelsreplace'"!="" {
+                if `"`macval(varlabelsbegin0)'"'!="" local tmpbegin
+            }
+            if "`wrap'"!="" & `nrvblock'>1 {
+                local wrap_i 1
+                local value: piece `wrap_i' `varwidth' of `"`macval(theeqlabel)'`macval(varl)'"', nobreak
+                Abbrev `varwidth' `"`macval(value)'"' "`abbrev'"
+            }
+            else {
+                Abbrev `varwidth' `"`macval(theeqlabel)'`macval(varl)'"' "`abbrev'"
+            }
+            WriteBegin `"`file'"' `"`macval(varlabelsbegin0)'"' `"`macval(tmpbegin)'"' ///
+             `"`fmt_v' (`"`macval(varlabelsprefix)'`macval(value)'`macval(varlabelssuffix)'"')"'
+            if `haslabcol2' {
+                gettoken labcol2chunk labcol2 : labcol2
+                Abbrev `labcol2width' `"`macval(labcol2chunk)'"' "`abbrev'"
+                file write `file' `macval(delimiter)' `fmt_l2' (`"`macval(value)'"')
+            }
+            if `hasrtfbrdr' & `rtfbrdron' {
+                local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdef'"'
+                local rtfbrdron 0
+            }
+            local varlabelsbegin0 `"`macval(varlabelsbegin)'"'
+
+*Write table cells
+            if "`smcltags'"!="" file write `file' "{res}"
+            local newrow 0
+            mat `first'=J(1,`nmodels',1)
+            foreach row of local rvblock {
+                if `hasrtfbrdr' & `r'==`RI' & !(`isref' & `"`refcatbelow'"'!="") {
+                    if `"`ferest()'"'=="" {
+                        local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdefbrdrb'"'
+                        local rtfbrdron 1
+                    }
+                }
+                local c 0
+                foreach v of local row {
+                    local m: word `++c' of `modelsrow'
+                    local unstackskipcoef 0
+                    if "`unstack'"!="" {
+                        capt local eqr: word `:word `c' of `eqsrow'' of `eqs'
+                        local rr=rownumb(`B',`"`eqr':`var'"')
+                        if `"`eqr'"'!="" local eqvar `"`eqr':`var'"'
+                        else local eqvar "`var'"
+                        if `rr'>=. local unstackskipcoef 1 // local v "."
+                    }
+                    else local rr `r'
+                    if `newrow' & `c'==1 {
+                        if "`smcltags'"!="" file write `file' "{txt}"
+                        if "`wrap'"!="" & `nrvblock'>1 {
+                            local value
+                            local space
+                            while (1) {
+                                local temp: piece `++wrap_i' `varwidth' of `"`macval(varl)'"', nobreak
+                                if `"`macval(temp)'"'=="" continue, break
+                                local value `"`macval(value)'`space'`macval(temp)'"'
+                                if `wrap_i'<`nrvblock' continue, break
+                                local space " "
+                            }
+                            Abbrev `varwidth' `"`macval(value)'"' "`abbrev'"
+                            local value `"`fmt_v' (`"`macval(varlabelsprefix)'`macval(value)'`macval(varlabelssuffix)'"')"'
+                        }
+                        else local value "_skip(`varwidth')"
+                        file write `file' `macval(end)' _n `macval(begin)' `value'
+                        if `haslabcol2' {
+                            file write `file' `macval(delimiter)' `fmt_l2' ("")
+                        }
+                        if "`smcltags'"!="" file write `file' "{res}"
+                    }
+                    local v: subinstr local v "&" " ", all
+                    local modelwidthj: word `=1+mod(`c'-1,`nmodelwidth')' of `modelwidth'
+                    if `modelwidthj'>0 local fmt_m "%`modelwidthj's"
+                    else local fmt_m
+                    local thevalue
+                    foreach vi of local v {
+                        if index("`vi'",".")!=1 {
+                            if `: list eqvar in `vi'_drop' local vi "..`vi'"
+                            else {
+                                local vipar: subinstr local `vi'_par "@modelwidth" "`modelwidthj'", all
+                            }
+                        }
+                        if index("`vi'",".")==1 {
+                            local value
+                        }
+                        else if `unstackskipcoef' {
+                            local value `"``vi'_vacant'"'
+                        }
+                        else if `B'[`rr',`m'*`droppedpos']==1 & `droppedison' {
+                            if `first'[1,`m'] {
+                                local value `"`macval(dropped)'"'
+                                mat `first'[1,`m']=0
+                            }
+                            else local value
+                        }
+                        else if "``vi'_'"=="ci" {
+                            if `_`vi'_l'[`rr',`m']>=.y local value `"``vi'_vacant'"'
+                            else {
+                                local format: word `r' of `ci_fmt'
+                                if "`format'"=="" {
+                                    local format: word `:word count ``vi'_fmt'' of ``vi'_fmt'
+                                }
+                                local value = `_`vi'_l'[`rr',`m']
+                                local vipar: subinstr local `vi'_l_par "@modelwidth" "`modelwidthj'", all
+                                vFormat `value' `format' "`lz'" `"`macval(dmarker)'"' ///
+                                    `"`macval(msign)'"' `"`macval(vipar)'"'
+                                local temp "`macval(value)'"
+                                local value = `_`vi'_u'[`rr',`m']
+                                local vipar: subinstr local `vi'_u_par "@modelwidth" "`modelwidthj'", all
+                                vFormat `value' `format' "`lz'" `"`macval(dmarker)'"' ///
+                                    `"`macval(msign)'"' `"`macval(vipar)'"'
+                                local value `"`macval(temp)'`macval(value)'"'
+                            }
+                        }
+                        else if `_`vi''[`rr',`m']>=.y   local value `"``vi'_vacant'"'
+                        //else if `_`vi''[`rr',`m']>=.    local value .
+                        else if "``vi'_'"=="_star" {
+                            CellStars `"`macval(starlevels)'"' `_```vi'_pvalue'_tname''[`rr',`m'] `"`macval(vipar)'"'
+                        }
+                        else if "``vi'_'"=="_sign" {
+                            MakeSign `_`vi''[`rr',`m'] `"`macval(msign)'"' `"`macval(vipar)'"'
+                        }
+                        else if "``vi'_'"=="_sigsign" {
+                            MakeSign `_`vi''[`rr',`m'] `"`macval(msign)'"' `"`macval(vipar)'"' ///
+                                `"`macval(starlevels)'"' `_```vi'_pvalue'_tname''[`rr',`m']
+                        }
+                        else {
+                            local format: word `r' of ``vi'_fmt'
+                            if "`format'"=="" {
+                                local format: word `:word count ``vi'_fmt'' of ``vi'_fmt'
+                            }
+                            local value = `_`vi''[`rr',`m']
+                            vFormat `value' `format' "`lz'" `"`macval(dmarker)'"' ///
+                                `"`macval(msign)'"' `"`macval(vipar)'"'
+                        }
+                        local thevalue `"`macval(thevalue)'`macval(value)'"'
+                        if !`stardetachon' & `:word `c' of `starsrow''==1 {
+                            if `modelwidthj'>0 | `starwidth'>0 local fmt_m "%`=`modelwidthj'+`starwidth''s"
+                            local value
+                            if index("`vi'",".")!=1 & `"``vi'_star'"'!="" {
+                                if !`: list eqvar in stardrop' {
+                                    Stars `"`macval(starlevels)'"' `_```vi'_pvalue'_tname''[`rr',`m']
+                                }
+                            }
+                            if "`ferest()'"=="" {
+                                local value: di `fmt_stw' `"`macval(value)'"'
+                            }
+                            local thevalue `"`macval(thevalue)'`macval(value)'"'
+                        }
+                        if "`ferest()'"!="" & index("`vi'","..")!=1  {
+                            local thevalue `"`macval(thevalue)'`macval(incelldelimiter)'"'
+                        }
+                    }
+                    file write `file' `macval(delimiter)' `fmt_m' (`"`macval(thevalue)'"')
+                    if `stardetachon' & `:word `c' of `starsrow''==1 {
+                        local thevalue
+                        foreach vi of local v {
+                            if index("`vi'",".")!=1 {
+                                if `: list eqvar in `vi'_drop' local vi "..`vi'"
+                            }
+                            if index("`vi'",".")!=1 & `"``vi'_star'"'!="" {
+                                if `: list eqvar in stardrop' local value
+                                else {
+                                    Stars `"`macval(starlevels)'"' `_```vi'_pvalue'_tname''[`rr',`m']
+                                }
+                                local thevalue `"`macval(thevalue)'`macval(value)'"'
+                            }
+                            if "`ferest()'"!="" & index("`vi'","..")!=1  {
+                                local thevalue `"`macval(thevalue)'`macval(incelldelimiter)'"'
+                            }
+                        }
+                        file write `file' `macval(stardetach)' `fmt_stw' (`"`macval(thevalue)'"')
+                    }
+                }
+                local newrow 1
+            }
+
+*End of table row
+            if "`smcltags'"!="" file write `file' "{txt}"
+            if `weqcnt'==`eqdim' & "`varlabelslast'"=="" ///
+             & !(`isref' & `"`refcatbelow'"'!="") local varlabelsend0
+            local tmpend `"`macval(end)'"'
+            if "`varlabelsreplace'"!="" {
+                if `"`macval(varlabelsend0)'"'!=""  local tmpend
+            }
+            VarInList `"`var'"' "`unstack'" `"`eqvar'"' `"`eqr'"' ///
+             `"`macval(varlabelselist)'"'
+            if `"`macval(value)'"'!="" {
+                IsInString `"""' `"`value'"' // sets local strcount
+                if `strcount'==0 {
+                    local value `"`"`macval(value)'"'"'
+                }
+                InsertAtVariables `"`macval(value)'"' 2 "`ncols'" `macval(atvars2)'
+                if "`varlabelsreplace'"!="" local varlabelsend0
+            }
+            WriteEnd `"`file'"' `"`macval(tmpend)'"' `"`macval(varlabelsend0)'"' ///
+             `"`macval(value)'"'
+* insert refcat() (if refcatbelow)
+            if `isref' & `"`refcatbelow'"'!="" {
+            if "`smcltags'"!="" file write `file' "{txt}"
+                if `hasrtfbrdr' & `r'==`RI' {
+                    local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdefbrdrb'"'
+                    local rtfbrdron 1
+                }
+                if `weqcnt'==`eqdim' & "`varlabelslast'"=="" local varlabelsend0
+                local tmpbegin `"`macval(begin)'"'
+                local tmpend `"`macval(end)'"'
+                if "`varlabelsreplace'"!="" {
+                    if `"`macval(varlabelsbegin0)'"'!="" local tmpbegin
+                    if `"`macval(varlabelsend0)'"'!=""  local tmpend
+                }
+                if "`varlabelsnone'"=="" {
+                    local value: word `isref' of `macval(refcatnames)'
+                    Abbrev `varwidth' `"`macval(value)'"' "`abbrev'"
+                }
+                else local value
+                WriteBegin `"`file'"' `"`macval(varlabelsbegin0)'"' `"`macval(tmpbegin)'"' ///
+                 `"`fmt_v' (`"`macval(varlabelsprefix)'`macval(value)'`macval(varlabelssuffix)'"')"'
+                if `haslabcol2' {
+                    gettoken labcol2chunk labcol2 : labcol2
+                    Abbrev `labcol2width' `"`macval(labcol2chunk)'"' "`abbrev'"
+                    file write `file' `macval(delimiter)' `fmt_l2' (`"`macval(value)'"')
+                }
+                if "`smcltags'"!="" file write `file' "{res}"
+                WriteStrRow `"`file'"' "`modelsrow'" `"`eqsrow'"' `"`: list sizeof eqswide'"' ///
+                    `"`macval(refcatrow)'"' `"`macval(delimiter)'"' ///
+                    `"`macval(stardetach)'"' "`starsrow'" "`abbrev'"  ///
+                    "`modelwidth'" "`delwidth'" "`starwidth'"
+                if "`smcltags'"!="" file write `file' "{txt}"
+                WriteEnd `"`file'"' `"`macval(tmpend)'"' `"`macval(varlabelsend0)'"'
+            }
+* end insert refcat()
+        }
+    }
+
+*Write indicator sets
+    forv i=1/`nindicate' {
+        if `hasrtfbrdr' & `i'==`nindicate' {
+            local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdefbrdrb'"'
+            local rtfbrdron 1
+        }
+        if `i'==`nindicate' & "`varlabelslast'"=="" local varlabelsend
+        local tmpbegin `"`macval(begin)'"'
+        local tmpend `"`macval(end)'"'
+        if "`varlabelsreplace'"!="" {
+            if `"`macval(varlabelsbegin0)'"'!="" local tmpbegin
+            if `"`macval(varlabelsend)'"'!=""  local tmpend
+        }
+        if "`varlabelsnone'"=="" {
+            Abbrev `varwidth' `"`macval(indicate`i'name)'"' "`abbrev'"
+        }
+        else local value
+        if "`smcltags'"!="" file write `file' "{txt}"
+        WriteBegin `"`file'"' `"`macval(varlabelsbegin0)'"' `"`macval(tmpbegin)'"' ///
+         `"`fmt_v' (`"`macval(varlabelsprefix)'`macval(value)'`macval(varlabelssuffix)'"')"'
+        if `haslabcol2' {
+            gettoken labcol2chunk labcol2 : labcol2
+            Abbrev `labcol2width' `"`macval(labcol2chunk)'"' "`abbrev'"
+            file write `file' `macval(delimiter)' `fmt_l2' (`"`macval(value)'"')
+        }
+        if "`smcltags'"!="" file write `file' "{res}"
+        WriteStrRow `"`file'"' "`modelsrow'" `"`eqsrow'"' `"`: list sizeof eqswide'"' ///
+            `"`macval(indicate`i'lbls)'"' `"`macval(delimiter)'"' ///
+            `"`macval(stardetach)'"' "`starsrow'" "`abbrev'"  ///
+            "`modelwidth'" "`delwidth'" "`starwidth'"
+        if "`smcltags'"!="" file write `file' "{txt}"
+        WriteEnd `"`file'"' `"`macval(tmpend)'"' `"`macval(varlabelsend)'"'
+    }
+
+*Write prefoot
+    if `"`macval(prefoot)'"'!="" {
+        if index(`"`macval(prefoot)'"',`"""')==0 {
+            local prefoot `"`"`macval(prefoot)'"'"'
+        }
+    }
+    foreach line of local prefoot {
+        if "`smcltags'"!="" file write `file' "{txt}"
+        InsertAtVariables `"`macval(line)'"' 0 "`ncols'" `macval(atvars2)' `macval(atvars3)'
+        file write `file' `"`macval(value)'"' _n
+    }
+    if ((`"`vblock'"'!="" & `R'>0) | `nindicate'>0) & "`smclmidrules'"!="" {
+        if `"`macval(statsarray)'"'!="" {
+            file write `file' `"`thesmclrule'"' _n
+        }
+    }
+
+*Write foot of table (statistics)
+    InsertAtVariables `"`macval(statslabelsbegin)'"' 2 "`ncols'" `macval(atvars2)'
+    local statslabelsbegin `"`macval(value)'"'
+    InsertAtVariables `"`macval(statslabelsend)'"' 2 "`ncols'" `macval(atvars2)'
+    local statslabelsend `"`macval(value)'"'
+    local statslabelsbegin0 `"`macval(statslabelsbegin)'"'
+    local S: list sizeof statsarray
+    local eqr "_"
+    if `hasrtfbrdr' {
+        local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdefbrdrt'"'
+        local rtfbrdron 1
+    }
+    forv r = 1/`S' {
+        if `r'==`S' & `hasrtfbrdr' {
+            local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdefbrdrb'"'
+            local rtfbrdron 1
+        }
+        local stat: word `r' of `macval(statslabels)'
+        if `"`stat'"'=="" local stat: word `r' of `statsrowlbls'
+        if "`statslabelsnone'"!="" local stat
+        if "`smcltags'"!="" file write `file' "{txt}"
+        if `r'==1 & "`statslabelsfirst'"=="" local statslabelsbegin0
+        local tmpbegin `"`macval(begin)'"'
+        if "`statslabelsreplace'"!="" {
+            if `"`macval(statslabelsbegin0)'"'!="" local tmpbegin
+        }
+        Abbrev `varwidth' `"`macval(stat)'"' "`abbrev'"
+        WriteBegin `"`file'"' `"`macval(statslabelsbegin0)'"' `"`macval(tmpbegin)'"' ///
+         `"`fmt_v' (`"`macval(statslabelsprefix)'`macval(value)'`macval(statslabelssuffix)'"')"'
+        if `r'==1 & "`statslabelsfirst'"=="" {
+            local statslabelsbegin0 `"`macval(statslabelsbegin)'"'
+        }
+        if `haslabcol2' {
+            gettoken labcol2chunk labcol2 : labcol2
+            Abbrev `labcol2width' `"`macval(labcol2chunk)'"' "`abbrev'"
+            file write `file' `macval(delimiter)' `fmt_l2' (`"`macval(value)'"')
+        }
+        if "`smcltags'"!="" file write `file' "{res}"
+        local strow: word `r' of `statsarray'
+        local strowlay: word `r' of `macval(statslayout)'
+        local strowfmt: word `r' of  `statsrowfmt'
+        local strowstar: word `r' of  `statsrowstar'
+        local lastm
+        local lasteq
+        local c 0
+        local mpos 0
+        foreach m of local modelsrow {
+            local ++c
+            local modelwidthj: word `=1+mod(`c'-1,`nmodelwidth')' of `modelwidth'
+            if `modelwidthj'>0 local fmt_m "%`modelwidthj's"
+            else local fmt_m
+            if "`m'"=="." {
+                file write `file' `macval(delimiter)' `fmt_m' (`""')
+                continue
+            }
+            local value
+            local eq: word `:word `c' of `eqsrow'' of `eqs'
+            if "`m'"!="`lastm'" {
+                local stc 0
+                local hasmestats 0
+            }
+            if "`m'"!="`lastm'" | `"`eq'"'!="`lasteq'"  local stc_eq 0
+            local usemestats 0
+            local ++stc_eq
+            local stcell: word `++stc' of `strow'
+            local stcelllay: word `stc' of `macval(strowlay)'
+            local stcellfmt: word `stc' of `strowfmt'
+            local stcellstar: word `stc' of `strowstar'
+            local cellhasstat 0
+            foreach stat of local stcell {
+                gettoken format stcellfmt: stcellfmt
+                local rr = rownumb(`St',`"`stat'"')
+                local value = `St'[`rr',`m']
+                if `value'==.y {
+                    local value `"`return(m`m'_`stat')'"'
+                    if `"`value'"'!="" {
+                        local cellhasstat 1
+                        local stcelllay: subinstr local stcelllay `"`statspchar'"' ///
+                        `"`value'"'
+                    }
+                }
+                else if `value'==.x {
+                    local hasmestats 1
+                }
+                else if `value'<.x {
+                    local cellhasstat 1
+                    vFormat `value' "`format'" "`lz'" `"`macval(dmarker)'"' ///
+                    `"`macval(msign)'"'
+                    local stcelllay: subinstr local stcelllay `"`statspchar'"' ///
+                    `"`macval(value)'"'
+                }
+            }
+            if `cellhasstat'==0 & `hasmestats' {
+                local stcell: word `stc_eq' of `strow'
+                local stcelllay: word `stc_eq' of `macval(strowlay)'
+                local stcellfmt: word `stc_eq' of `strowfmt'
+                local stcellstar: word `stc_eq' of `strowstar'
+                local cellhasstat 0
+                foreach stat of local stcell {
+                    gettoken format stcellfmt: stcellfmt
+                    local rr = rownumb(`St',`"`eq':`stat'"')
+                    if `rr'>=. local value .z
+                    else local value = `St'[`rr',`m']
+                    if `value'!=.z {
+                        local cellhasstat 1
+                        vFormat `value' "`format'" "`lz'" `"`macval(dmarker)'"' ///
+                         `"`macval(msign)'"'
+                        local stcelllay: subinstr local stcelllay `"`statspchar'"' `"`macval(value)'"'
+                    }
+                }
+                if `cellhasstat' local usemestats 1
+            }
+            if `cellhasstat'==0 local stcelllay
+            file write `file' `macval(delimiter)' `fmt_m' (`"`macval(stcelllay)'"')
+            if `:word `c' of `starsrow''==1 {
+                if "`stcellstar'"=="1" & `cellhasstat' {
+                    if `usemestats' {
+                        local rr=rownumb(`St',`"`eq':p"')
+                    }
+                    else {
+                        local rr=rownumb(`St',"p")
+                    }
+                    Stars `"`macval(starlevels)'"' `St'[`rr',`m']
+                    file write `file' `macval(stardetach)' `fmt_stw' (`"`macval(value)'"')
+                }
+                else {
+                    file write `file' `macval(stardetach)' _skip(`starwidth')
+                }
+            }
+            local lastm "`m'"
+            local lasteq `"`eq'"'
+        }
+        if `r'==`S' & "`statslabelslast'"=="" local statslabelsend
+        local tmpend `"`macval(end)'"'
+        if "`statslabelsreplace'"!="" {
+            if `"`macval(statslabelsend)'"'!="" local tmpend
+        }
+        if "`smcltags'"!="" file write `file' "{txt}"
+        WriteEnd `"`file'"' `"`macval(tmpend)'"' `"`macval(statslabelsend)'"'
+        if `hasrtfbrdr' & `rtfbrdron' {
+            local begin: subinstr local rtfbeginbak "@rtfrowdefbrdr" `"`rtfrowdef'"'
+            local rtfbrdron 0
+        }
+    }
+
+*Write postfoot
+    if "`smclrules'"!="" {
+        file write `file' `"`thesmclrule'"' _n
+    }
+    local discrete: list retok discrete
+    if `"`macval(postfoot)'"'!="" {
+        if index(`"`macval(postfoot)'"',`"""')==0 {
+            local postfoot `"`"`macval(postfoot)'"'"'
+        }
+    }
+    foreach line of local postfoot {
+        if "`smcltags'"!="" file write `file' "{txt}"
+        InsertAtVariables `"`macval(line)'"' 0 "`ncols'" `macval(atvars2)' `macval(atvars3)'
+        file write `file' `"`macval(value)'"' _n
+    }
+
+*Write legend (starlevels, marginals)
+    if "`legend'"!="" {
+        if `"`macval(discrete2)'"'!="" {
+            mat `D' = `D''*`D'
+            if `D'[1,1]!=0 {
+                if "`smcltags'"!="" file write `file' "{txt}"
+                file write `file' `"`macval(discrete)'`macval(discrete2)'"' _n
+            }
+        }
+        if `"`macval(starlegend)'"'!="" {
+            if "`smcltags'"!="" file write `file' "{txt}"
+            file write `file' `"`macval(starlegend)'"' _n
+        }
+    }
+
+*Finish: copy tempfile to user file / type to screen
+    file close `file'
+    local S: word count `macval(substitute)'
+    if `"`topfile'"'!="" {
+        confirm file `"`topfile'"'
+    }
+    if `"`bottomfile'"'!="" {
+        confirm file `"`bottomfile'"'
+    }
+    if `"`using'"'!="" {
+        tempname file2
+        file open `file2' `using', write text `replace' `append'
+    }
+    if "`type'"!="" di as res ""
+    if `"`topfile'"'!="" {
+        file open `file' using `"`topfile'"', read text
+        file read `file' temp
+        while r(eof)==0 {
+            if `"`using'"'!="" {
+                file write `file2' `"`macval(temp)'"' _n
+            }
+            if "`type'"!="" {
+                if "`showtabs'"!="" {
+                    local temp: subinstr local temp "`=char(9)'" "", all
+                }
+                di `asis' `"`macval(temp)'"'
+            }
+            file read `file' temp
+        }
+        file close `file'
+    }
+    file open `file' using `"`tfile'"', read text
+    file read `file' temp
+    while r(eof)==0 {
+        forv s = 1(2)`S' {
+            local from: word `s' of `macval(substitute)'
+            local to:  word `=`s'+1' of `macval(substitute)'
+            if `"`macval(from)'`macval(to)'"'!="" {
+                local temp: subinstr local temp `"`macval(from)'"' `"`macval(to)'"', all
+            }
+        }
+        if `"`using'"'!="" {
+            file write `file2' `"`macval(temp)'"' _n
+        }
+        if "`type'"!="" {
+            if "`showtabs'"!="" {
+                local temp: subinstr local temp "`=char(9)'" "", all
+            }
+            di `asis' `"`macval(temp)'"'
+        }
+        file read `file' temp
+    }
+    file close `file'
+    if `"`bottomfile'"'!="" {
+        file open `file' using `"`bottomfile'"', read text
+        file read `file' temp
+        while r(eof)==0 {
+            if `"`using'"'!="" {
+                file write `file2' `"`macval(temp)'"' _n
+            }
+            if "`type'"!="" {
+                if "`showtabs'"!="" {
+                    local temp: subinstr local temp "`=char(9)'" "", all
+                }
+                di `asis' `"`macval(temp)'"'
+            }
+            file read `file' temp
+        }
+        file close `file'
+    }
+    if `"`using'"'!="" {
+        file close `file2'
+        gettoken junk using0 : using
+        return local fn `using0'
+        if "`outfilenoteoff'"=="" {
+            di as txt `"(output written to {browse `using0'})"'
+        }
+    }
+end
+
+program MoreOptions
+// estout has more options than -syntax- can handle; a subroutine is used
+// here (rather than a second syntax call) to preserve the 'using' macro
+// from the first syntax call
+// MoreOptions is intended for options without arguments only
+    local theoptions ///
+        NOReplace Replace ///
+        NOAppend Append ///
+        NOTYpe TYpe ///
+        NOSHOWTABS showtabs ///
+        NOASIS asis ///
+        NOWRAP wrap ///
+        NOSMCLTags SMCLTags ///
+        NOSMCLRules SMCLRules ///
+        NOSMCLMIDRules SMCLMIDRules ///
+        NOSMCLEQRules SMCLEQRules ///
+        NOOUTFILENOTEOFF outfilenoteoff
+    syntax [, `theoptions' ]
+    foreach opt of local theoptions {
+        local opt = lower("`opt'")
+        c_local `opt' "``opt''"
+    }
+    c_local options
+end
+
+program ParseValueSubopts
+    syntax anything [ , mrow(string asis) NOTranspose Transpose ///
+        NOStar Star PVALue(string) Fmt(string) Label(string) Vacant(string) ///
+        NOPAR par PAR2(string asis) Keep(string asis) Drop(string asis) ///
+        PATtern(string) NOABS abs ]
+    local el: word 1 of `anything'
+    local elname: word 2 of `anything'
+    CheckPattern `"`pattern'"' "`elname'"
+    if `"`macval(par2)'"'!="" {
+        local par `"`macval(par2)'"'
+    }
+    else if "`par'"!="" {
+        if "`elname'"=="ci" local par "[ , ]"
+        else if "`elname'"=="ci_l" local par `"[ """'
+        else if "`elname'"=="ci_u" local par `""" ]"'
+        else local par "( )"
+    }
+    if `"`mrow'"'!="" {
+        capt confirm integer number `mrow'
+        if _rc==0 {
+            if `mrow'>=1 {
+                if `"`macval(label)'"'=="" {
+                    local label "`elname'[`mrow']"
+                }
+            }
+            else {
+                local mrow `""`mrow'""'
+                if `"`macval(label)'"'=="" {
+                    local label `mrow'
+                }
+            }
+        }
+        else {
+            gettoken trash : mrow, qed(qed)
+            if `qed'==0 {
+                local mrow `"`"`mrow'"'"'
+            }
+            if `"`macval(label)'"'=="" {
+                local label `mrow'
+            }
+        }
+    }
+    foreach opt in transpose star par abs {
+        if "`no`opt''"!="" c_local no`el'_`opt' 1
+        else c_local `el'_`opt' "``opt''"
+    }
+    foreach opt in mrow pvalue fmt label vacant keep drop pattern {
+        c_local `el'_`opt' `"`macval(`opt')'"'
+    }
+end
+
+program CheckPattern
+    args pattern option
+    foreach p of local pattern {
+        if !( "`p'"=="1" | "`p'"=="0" ) {
+            di as error `""`pattern'" invalid in `option'(... pattern())"'
+            exit 198
+        }
+    }
+end
+
+program ParseStatsSubopts
+    syntax [anything] [ , Fmt(string) Labels(string asis) ///
+     NOStar Star Star2(string) LAYout(string asis) PChar(string) ]
+    foreach opt in fmt labels layout pchar {
+        c_local stats`opt' `"`macval(`opt')'"'
+    }
+    if "`nostar'"!="" c_local nostatsstar 1
+    else if "`star2'"!="" {
+        local anything: list anything | star2
+        c_local statsstar "`star2'"
+    }
+    else if "`star'"!="" {
+        local star2: word 1 of `anything'
+        c_local statsstar "`star2'"
+    }
+    c_local stats "`anything'"
+    c_local stats2
+end
+
+prog ProcessStatslayout // returns statsarray, -rowlbls, -rowfmt, -rowstar, -colstar, -layout
+    args stats statsfmt statsstar statslayout statspchar
+    local format "%9.0g"
+    if `"`statspchar'"'=="" {
+        local statspchar "@"
+        c_local statspchar "@"
+    }
+    local statsarray
+    local statsrowlbls
+    local statsrowfmt
+    local statsrowstar
+    local space1
+    local i 0
+    local wmax 0
+    foreach row of local statslayout {
+        local statsrow
+        local statsrowlbl
+        local statsrfmt
+        local statsrstar
+        local space2
+        local w = 0
+        foreach cell of local row {
+            local ++w
+            local statscell
+            local statsclbl `"`cell'"'
+            local statscfmt
+            local statscstar 0
+            local space3
+            local trash: subinstr local cell `"`statspchar'"' "", all count(local cnt)
+            forv j=1/`cnt' {
+                local stat: word `++i' of `stats'
+                local statscell `"`statscell'`space3'`stat'"'
+                local statsclbl: subinstr local statsclbl `"`statspchar'"' "`stat'"
+                local tmp: word `i' of `statsfmt'
+                if `"`tmp'"'!="" local format `"`tmp'"'
+                local statscfmt `"`statscfmt'`space3'`format'"'
+                if `:list stat in statsstar' {
+                    local statscstar 1
+                    local statscol_`w' 1
+                }
+                local space3 " "
+            }
+            local statsrow `"`statsrow'`space2'"`statscell'""'
+            local statsrowlbl `"`statsrowlbl'`space2'`statsclbl'"'
+            local statsrfmt `"`statsrfmt'`space2'"`statscfmt'""'
+            local statsrstar "`statsrstar'`space2'`statscstar'"
+            local space2 " "
+        }
+        local statsarray `"`statsarray'`space1'`"`statsrow'"'"'
+        local statsrowlbls `"`statsrowlbls'`space1'`"`statsrowlbl'"'"'
+        local statsrowfmt `"`statsrowfmt'`space1'`"`statsrfmt'"'"'
+        local statsrowstar `"`statsrowstar'`space1'`"`statsrstar'"'"'
+        local space1 " "
+        local wmax = max(`w',`wmax')
+    }
+    while (1) {
+        local stat: word `++i' of `stats'
+        if `"`stat'"'=="" continue, break
+        local tmp: word `i' of `statsfmt'
+        if `"`tmp'"'!="" local format `"`tmp'"'
+        local statscstar: list stat in statsstar
+        if `statscstar' local statscol_1 1
+        local statsarray `"`statsarray'`space1'`"`stat'"'"'
+        local statsrowlbls `"`statsrowlbls'`space1'`"`stat'"'"'
+        local statsrowfmt `"`statsrowfmt'`space1'`"`format'"'"'
+        local statsrowstar `"`statsrowstar'`space1'`"`statscstar'"'"'
+        local statslayout `"`statslayout'`space1'`statspchar'"'
+        local space1 " "
+        local wmax = max(1,`wmax')
+    }
+    local statscolstar
+    local space
+    forv w = 1/`wmax' {
+        if "`statscol_`w''"=="" local statscol_`w' 0
+        local statscolstar "`statscolstar'`space'`statscol_`w''"
+        local space " "
+    }
+    c_local statsarray   `"`statsarray'"'
+    c_local statsrowlbls `"`statsrowlbls'"'
+    c_local statsrowfmt  `"`statsrowfmt'"'
+    c_local statsrowstar `"`statsrowstar'"'
+    c_local statscolstar `"`statscolstar'"'
+    c_local statslayout  `"`statslayout'"'
+end
+
+program ParseLabelsSubopts
+    gettoken type 0: 0
+    local lblsubopts
+    syntax [anything] [ , NONUMbers NUMbers NOTItles TItles NODEPvars DEPvars ///
+     NONONE NONE NOSPAN span Prefix(string) Suffix(string) Begin(string asis) ///
+     End(string asis) NOReplace Replace BList(string asis) EList(string asis) ///
+     ERepeat(string) NOFirst First NOLast Last lhs(string) PATtern(string) ///
+     NOMerge Merge ]
+    CheckPattern `"`pattern'"' "`type'"
+    if "`merge'"!="" & "`nomerge'`macval(suffix)'"=="" local suffix ":"
+    foreach opt in begin end {
+        if `"`macval(`opt')'"'!="" {
+            if index(`"`macval(`opt')'"', `"""')==0 {
+                local `opt' `"`"`macval(`opt')'"'"'
+            }
+        }
+    }
+    foreach opt in prefix suffix begin end blist elist erepeat lhs pattern {
+        c_local `type'`opt' `"`macval(`opt')'"'
+    }
+    foreach opt in numbers titles depvars span replace none first last merge {
+        if "`no`opt''"!="" c_local no`type'`opt' 1
+        else c_local `type'`opt' "``opt''"
+    }
+    c_local `type' `"`macval(anything)'"'
+end
+
+program ReadLine
+    args max file
+    local end 0
+    file read `file' temp1
+    local temp1: subinstr local temp1 "`=char(9)'" "    ", all
+    while r(eof)==0 {
+        local j 1
+        local temp2
+        local temp3: piece `j++' `max' of `"`macval(temp1)'"'
+        if `"`temp3'"'=="" | index(`"`temp3'"',"*")==1 ///
+         | index(`"`temp3'"',"//")==1 {
+            file read `file' temp1
+            local temp1: subinstr local temp1 "`=char(9)'" "    ", all
+            continue
+        }
+        while `"`temp3'"'!="" {
+            local comment=index(`"`macval(temp3)'"'," ///")
+            if `comment' {
+                local temp3=substr(`"`macval(temp3)'"',1,`comment')
+                local temp2 `"`macval(temp2)'`macval(temp3)'"'
+                local end 0
+                continue, break
+            }
+            local comment=index(`"`macval(temp3)'"'," //")
+            if `comment' {
+                local temp3=substr(`"`macval(temp3)'"',1,`comment')
+                local temp2 `"`macval(temp2)'`macval(temp3)'"'
+                local end 1
+                continue, break
+            }
+            local temp2 `"`macval(temp2)'`macval(temp3)'"'
+            local temp3: piece `j++' `max' of `"`macval(temp1)'"'
+            local end 1
+        }
+        if `end' {
+            local line `"`macval(line)'`macval(temp2)'"'
+            continue, break
+        }
+        else {
+            local line `"`macval(line)'`macval(temp2)'"'
+            file read `file' temp1
+            local temp1: subinstr local temp1 "`=char(9)'" "    ", all
+        }
+    }
+    c_local line `"`macval(line)'"'
+end
+
+program CellsCheck
+    args cells
+    local ncols 0
+    local nrows 0
+    local cells: subinstr local cells "& " "&", all
+    local cells: subinstr local cells " &" "&", all
+    local cells: subinstr local cells `"&""' `"& ""', all
+    local cells: subinstr local cells `""&"' `"" &"', all
+    foreach row of local cells {
+        local newrow
+        foreach col of local row {
+            local vals: subinstr local col "&" " ", all
+            //local vals: list vals - values
+            local values: list values | vals
+            local vals: list retok vals
+            local vals: subinstr local vals " " "&", all
+            //local newrow: list newrow | vals
+            local newrow `"`newrow'`vals' "'
+        }
+        local newrow: list retok newrow
+        if "`newrow'"!="" {
+            local ncols = max(`ncols',`:list sizeof newrow')
+            local newcells `"`newcells'"`newrow'" "'
+            local ++nrows
+        }
+    }
+    local newcells: list retok newcells
+    c_local cells `"`newcells'"'
+    c_local ncols `ncols'
+    c_local nrows `nrows'
+    local dot "."
+    c_local values: list values - dot
+end
+
+program Star2Cells
+    args cells star
+    local newcells
+    foreach row of local cells {
+        local newrow
+        foreach col of local row {
+            if "`col'"=="`star'" {
+                local col "`col'star"
+            }
+            local newrow: list newrow | col
+        }
+        local newcells `"`newcells'"`newrow'" "'
+    }
+    local newcells: list retok newcells
+    c_local cells `"`newcells'"'
+end
+
+prog ParseStarlevels
+    syntax [anything(equalok)] [ , Label(str) Delimiter(str) ]
+    c_local starlevels `"`macval(anything)'"'
+    c_local starlevelslabel `"`macval(label)'"'
+    c_local starlevelsdelimiter `"`macval(delimiter)'"'
+end
+
+program CheckStarvals
+    args starlevels label del
+    if `"`macval(label)'"'=="" local label " p<"
+    if `"`macval(del)'"'=="" local del ", "
+    local nstar: word count `macval(starlevels)'
+    local nstar = `nstar'/2
+    capture confirm integer number `nstar'
+    if _rc {
+        di as error "unmatched list of significance symbols and levels"
+        exit 198
+    }
+    local istar 1
+    forv i = 1/`nstar' {
+        local iistar: word `=`i'*2' of `macval(starlevels)'
+        confirm number `iistar'
+        if `iistar'>`istar' | `iistar'<=0 {
+            di as error "significance levels out of order or out of range (0,1]"
+            exit 198
+        }
+        local istar `iistar'
+        local isym: word `=`i'*2-1' of `macval(starlevels)'
+        if `"`macval(legend)'"'!="" {
+            local legend `"`macval(legend)'`macval(del)'"'
+        }
+        local ilabel: subinstr local label "@" "`istar'", count(local hasat)
+        if `hasat'==0 {
+            local ilabel `"`macval(label)'`istar'"'
+        }
+        local legend `"`macval(legend)'`macval(isym)'`macval(ilabel)'"'
+    }
+    c_local starlegend `"`macval(legend)'"'
+end
+
+program Starwidth
+    args starlevels
+    local nstar: word count `macval(starlevels)'
+    forv i = 2(2)`nstar' {
+        local istar: word `=`i'-1' of `macval(starlevels)'
+        local width = max(length("`width'"),length(`"`macval(istar)'"'))
+    }
+    c_local value `width'
+end
+
+// Loosely based on Mkemat from est_table.ado, but with heavy modifications
+program _estout_getres, rclass
+    syntax, names(str) [ coefs(str asis) stats(str asis) equations(str) ///
+        rename(str asis) margin(str asis) meqs(str asis) ///
+        dropped(int 0) level(int 95) ///
+        transform(str asis)  transformpattern(str asis) ]
+    // coefs: coef "coef O/1 #" `"coef O/1 "rowname""' etc...
+
+    tempname bc bbc bs bbs st
+
+    local nnames : word count `names'
+    local rename : subinstr local rename "," "", all
+    if `"`stats'"' != "" {
+        local stats : subinstr local stats "," "", all
+        confirm names `stats'
+        local stats : list uniq stats
+        local nstat : list sizeof stats
+        mat `bbs' = J(`nstat', `nnames', .z)
+        mat colnames `bbs' = `: subinstr local names "." "active", all word'
+        mat rownames `bbs' = `stats'
+    }
+
+    if "`equations'" != "" {
+        MatchNames "`equations'"
+        local eqspec  `r(eqspec)'
+        local eqnames `r(eqnames)'
+    }
+
+    local ncoefs 0
+    foreach coefn of local coefs {
+        local ++ncoefs
+        gettoken coef : coefn
+        local coefnms `"`coefnms' `coef'"' // use more informative label? (coefn => error in Stata 8 and 10)
+    }
+    local bVs "b se var t z p ci_l ci_u _star _sign _sigsign"
+    local hasbVs = `"`: list coefnms & bVs'"'!=""
+    local hastransform = (`"`transform'"'!="") & `hasbVs'
+    local getbV = cond(`hasbVs' | `dropped', "b var ", "")
+
+    tempname hcurrent esample
+    local estcycle = ("`names'"!=".")
+    if `estcycle' {
+        _est hold `hcurrent', restore nullok estsystem
+    }
+
+    local ni 0
+    local hasbbc 0
+    local ccols = `ncoefs' + ("`margin'"!="") + `dropped'
+    foreach name of local names {
+        local ++ni
+        local hasbc 0
+        local hasmargin 0
+        nobreak {
+            if "`name'" != "." {
+                local eqname `name'
+                *est_unhold `name' `esample'        // (why preserve missings in esample?)
+                capt confirm new var _est_`name'    // fix e(sample) if obs have been added
+                if _rc qui replace _est_`name' = 0 if _est_`name' >=.
+                _est unhold `name'
+            }
+            else    {
+                local eqname active
+                if `estcycle' {
+                    _est unhold `hcurrent'
+                }
+            }
+
+            // get coefficients
+            capture noisily break {
+                CheckEqs `"`getbV'`coefs'"'                 // sets local seqmerge
+                GetCoefs `bc' `seqmerge' `"`getbV'`coefs'"' // sets local hasbc
+                if `hasbc' {
+                    mat coln `bc' = `getbV'`coefnms'
+                }
+            }
+            local rc = _rc
+
+            // set equation names and get marginal effects
+            if `hasbc' & `rc'==0 {
+                capture noisily break {
+                    if `dropped' {
+                        DroppedCoefs `bc'
+                    }
+                    if "`equations'"!="" {
+                        AdjustRowEq `bc' `ni' `nnames' "`eqspec'" "`eqnames'"
+                    }
+                    if "`margin'"!="" & `hasbVs' {
+                        GetMarginals `bc' "`margin'" `"`meqs'"' // resets local hasmargin
+                    }
+                    if `hasbVs' {
+                        ComputeCoefs `bc' `hasmargin' `"`coefnms'"' `level'
+                    }
+                    if `hastransform' & `hasbVs' {
+                        if `"`transformpattern'"'!="" {
+                            local transformthis: word `ni' of `transformpattern'
+                        }
+                        else local transformthis 1
+                        if `"`transformthis'"'=="1" {
+                            TransformCoefs `bc' `"`coefnms'"' `"`transform'"'
+                        }
+                    }
+                    if "`getbV'"!="" {
+                        mat `bc' = `bc'[1...,3...] // remove b and var
+                    }
+                }
+                local rc = _rc
+            }
+
+            // get stats
+            if `rc'==0 {
+                capture noisily break {
+                    if "`stats'" != "" {
+                        GetStats "`stats'" `bbs' `ni'
+                        if `hasbc'>0 & inlist(`"`e(cmd)'"', "reg3", "sureg", "mvreg") {
+                            GetEQStats "`stats'" `bbs' `ni' `bc'
+                        }
+                        return add
+                    }
+                }
+                local rc = _rc
+            }
+
+            local depname: word 1 of `e(depvar)'
+            return local m`ni'_depname "`depname'"
+
+            local title `"`e(estimates_title)'"'
+            if `"`title'"'=="" local title `"`e(_estimates_title)'"'  // prior to Stata 10
+            return local m`ni'_estimates_title `"`title'"'
+
+            if "`name'" != "." {
+                *est_hold `name' `esample'
+                _est hold `name', estimates varname(_est_`name')
+            }
+            else {
+                if `estcycle' {
+                    _est hold `hcurrent', restore nullok estsystem
+                }
+            }
+        }
+
+        if `rc' {
+            exit `rc'
+        }
+
+        if `hasbc'>0 {
+            mat coleq `bc' = `eqname'
+            if `"`rename'"'!="" {
+                RenameCoefs `bc' `"`rename'"'
+            }
+            if `hasbbc' {
+                mat_capp `bbc' : `bbc' `bc', miss(.z) cons ts
+            }
+            else {
+                mat `bbc' = `bc'
+                if `ni'>1 { // add previous empty models
+                    mat `bc' = (1, `bc'[1,1...]) \ ( `bc'[1...,1], J(rowsof(`bc'), colsof(`bc'), .z))
+                    mat `bc' = `bc'[2...,2...]
+                    forv nj = 1/`ni' {
+                        if `nj'==`ni' continue
+                        local eqname: word `nj' of `names'
+                        if `"`eqname'"'=="." {
+                            local eqname active
+                        }
+                        mat coleq `bc' = `eqname'
+                        mat `bbc' = `bc', `bbc'
+                    }
+                }
+            }
+            local hasbbc 1
+        }
+        else {
+            if `hasbbc' { // add empty model if bbc exists
+                mat `bc' = `bbc'[1...,1..`ccols']
+                mat `bc' = (1, `bc'[1,1...]) \ ( `bc'[1...,1], J(rowsof(`bc'), colsof(`bc'), .z))
+                mat `bc' = `bc'[2...,2...]
+                mat coleq `bc' = `eqname'
+                mat `bbc' = `bbc', `bc'
+            }
+        }
+    }
+
+    if `hasbbc' {
+        return matrix coefs = `bbc'
+        return scalar ccols = `ccols'
+    }
+    else {
+        return scalar ccols = 0  // indicates that r(coefs) is missing
+    }
+    if "`stats'" != "" {
+        return matrix stats = `bbs'
+    }
+    return local names `names'
+    return scalar nmodels = `ni'
+end
+
+program DroppedCoefs // identify dropped coeffficients
+    args bc
+    tempname tmp
+    mat `tmp' = `bc'[1..., 1] * 0
+    mat coln `tmp' = "_dropped"
+    local r = rowsof(`bc')
+    forv i = 1/`r' {
+        if `bc'[`i',1]==0 & `bc'[`i',2]==0 { // b=0 and var=0
+            mat `tmp'[`i',1] = 1
+        }
+    }
+    mat `bc' = `bc', `tmp'
+end
+
+program RenameCoefs
+    args bc rename
+    local Stata11 = cond(c(stata_version)>=11, "version 11:", "")
+    tempname tmp
+    local eqs: roweq `bc', q
+    local eqs: list clean eqs
+    local eqs: list uniq eqs
+    local newnames
+    foreach eq of local eqs {
+        mat `tmp' = `bc'[`"`eq':"',1]
+        QuotedRowNames `tmp'
+        local vars `"`value'"'
+        gettoken from rest : rename
+        gettoken to rest : rest
+        while (`"`from'`to'"'!="") {
+            if index(`"`to'"',":") | `"`to'"'=="" {
+                di as err "invalid rename()"
+                exit 198
+            }
+            local hasfrom = rownumb(`tmp', `"`from'"')
+            if `hasfrom'<. {
+                local hasto = rownumb(`tmp', `"`to'"')
+                if `hasto'<. {
+                    di as err `"`to' already exists in equation; cannot rename"'
+                    exit 110
+                }
+                local colonpos = index(`"`from'"',":")
+                if index(`"`from'"',":") { // remove equation
+                    gettoken chunk from : from, parse(":") // eq
+                    gettoken chunk from : from, parse(":") // :
+                    gettoken from : from
+                    if `"`from'"'=="" {
+                        di as err "invalid rename()"
+                        exit 190
+                    }
+                }
+                local vars: subinstr local vars `"`from'"' `"`"`to'"'"', word
+                `Stata11' mat rown `tmp' = `vars'
+            }
+            gettoken from rest : rest
+            gettoken to rest : rest
+        }
+        local newnames `"`newnames'`vars' "'
+    }
+    `Stata11' mat rown `bc' = `newnames'
+end
+
+// Source: est_table.ado  version 1.1.4  09oct2008  (unmodified)
+program MatchNames, rclass
+    args eqspec
+
+    local eqspec  : subinstr local eqspec ":" " ", all
+    local eqspec0 : subinstr local eqspec "#" "" , all
+
+    local iterm 0
+    gettoken term eqspec : eqspec0 , parse(",")
+    while "`term'" != "" {
+        local ++iterm
+
+        // term = [name =] { # | #-list }
+        gettoken eqname oprest: term, parse("=")
+        gettoken op rest : oprest, parse("=")
+        if trim(`"`op'"') == "=" {
+            confirm name `eqname'
+            local term `rest'
+        }
+        else {
+            local eqname #`iterm'
+        }
+        local eqnames `eqnames' `eqname'
+
+        if "`eqspec'" == "" {
+            continue, break
+        }
+        gettoken term eqspec: eqspec , parse(",")
+        assert "`term'" == ","
+        gettoken term eqspec: eqspec , parse(",")
+    }
+
+    if `"`:list dups eqnames'"' != "" {
+        dis as err "duplicate matched equation names"
+        exit 198
+    }
+
+    return local eqspec   `eqspec0'
+    return local eqnames  `eqnames'
+end
+
+// Source: est_table.ado  version 1.1.4  09oct2008  (unmodified)
+program AdjustRowEq
+    args b ni nmodel eqspec eqnames
+
+    local beqn : roweq `b', quote
+    local beqn : list clean beqn
+    local beq  : list uniq beqn
+
+    if `"`:list beq & eqnames'"' != "" {
+        dis as err "option equations() invalid"
+        dis as err "specified equation name already occurs in model `ni'"
+        exit 198
+    }
+
+    local iterm 0
+    gettoken term eqspec : eqspec , parse(",")
+    while "`term'" != "" {
+        // dis as txt "term:|`term'|"
+        local ++iterm
+
+        // term = [name =] { # | #-list }
+        gettoken eqname oprest: term, parse("=")
+        gettoken op rest : oprest, parse("=")
+        if trim(`"`op'"') == "=" {
+            local term `rest'
+        }
+        else {
+            local eqname #`iterm'
+        }
+
+        local nword : list sizeof term
+        if !inlist(`nword', 1, `nmodel') {
+            dis as err "option equations() invalid"
+            dis as err "a term should consist of either 1 or `nmodel' equation numbers"
+            exit 198
+        }
+        if `nword' > 1 {
+            local term  : word `ni' of `term'
+        }
+
+        if trim("`term'") != "." {
+            capt confirm integer number `term'
+            if _rc {
+                dis as err "option equations() invalid"
+                dis as err "`term' was found, while an integer equation number was expected"
+                exit 198
+            }
+            if !inrange(`term',1,`:list sizeof beq') {
+                dis as err "option equations() invalid"
+                dis as err "equation number `term' for model `ni' out of range"
+                exit 198
+            }
+            if `:list posof "`eqname'" in beq' != 0 {
+                dis as err "impossible to name equation `eqname'"
+                dis as err "you should provide (another) equation name"
+                exit 198
+            }
+
+            local beqn : subinstr local beqn  ///
+                `"`:word `term'  of `beq''"'    ///
+                "`eqname'" , word all
+        }
+
+        if "`eqspec'" == "" {
+            continue, break
+        }
+        gettoken term eqspec: eqspec , parse(",")
+        assert "`term'" == ","
+        gettoken term eqspec: eqspec , parse(",")
+    }
+    matrix roweq `b' = `beqn'
+end
+
+// Source: est_table.ado  version 1.1.4  09oct2008  (modified)
+// Modification: returns string scalars in r(m`ni'_name) (and sets `bbs' = .y)
+program GetStats, rclass
+    args stats bbs ni
+    tempname rank st V
+    local escalars : e(scalars)
+    local emacros : e(macros)
+    local is 0
+    foreach stat of local stats {
+        local ++is
+        if inlist("`stat'", "aic", "bic", "rank") {
+            if "`hasrank'" == "" {
+                capt mat `V' = syminv(e(V))
+                local rc = _rc
+                if `rc' == 0 {
+                    scalar `rank' = colsof(`V') - diag0cnt(`V')
+                }
+                else if `rc' == 111 {
+                    scalar `rank' = 0
+                }
+                else {
+                    // rc<>0; show error message
+                    mat `V' = syminv(e(V))
+                }
+                local hasrank 1
+            }
+            if "`stat'" == "aic" {
+                scalar `st' = -2*e(ll) + 2*`rank'
+            }
+            else if "`stat'" == "bic" {
+                scalar `st' = -2*e(ll) + log(e(N)) * `rank'
+            }
+            else if "`stat'" == "rank" {
+                scalar `st' = `rank'
+            }
+        }
+        else {
+            if `:list stat in escalars' > 0 {
+                scalar `st' = e(`stat')
+            }
+            else if "`stat'"=="p" {
+                if e(F)<. {
+                    scalar `st' = Ftail(e(df_m), e(df_r), e(F))
+                }
+                else if e(chi2)<. {
+                    scalar `st' = chi2tail(e(df_m), e(chi2))
+                }
+            }
+            else if `:list stat in emacros' > 0 {
+                scalar `st' = .y
+                capt return local m`ni'_`stat' `"`e(`stat')'"'  // name might be too long
+            }
+            else {
+                scalar `st' = .z
+            }
+        }
+        mat `bbs'[`is',`ni'] = `st'
+    }
+end
+
+program GetEQStats, rclass  // eq-specific stats for reg3, sureg, and mvreg (sets `bbs' = .x)
+    args stats bbs ni bc
+    return add
+    tempname addrow
+    local ic "aic bic rank"
+    local eqs: roweq `bc', q
+    local eqs: list clean eqs
+    local eqs: list uniq eqs
+    local s 0
+    foreach stat of local stats {
+        local ++s
+        if inlist(`"`stat'"', "aic", "bic", "rank") continue
+        if `bbs'[`s',`ni']<.y  continue
+        local e 0
+        local found 0
+        foreach eq of local eqs {
+            local ++e
+            if e(cmd)=="mvreg" {
+                if "`stat'"=="p" local value: word `e' of `e(p_F)'
+                else local value: word `e' of `e(`stat')'
+            }
+            else if "`stat'"=="df_m" {
+                local value `"`e(`stat'`e')'"'
+            }
+            else {
+                local value `"`e(`stat'_`e')'"'
+            }
+            capture confirm number `value'
+            if _rc==0 {
+                local found 1
+                local r = rownumb(`bbs', `"`eq':`stat'"')
+                if `r'>=. {
+                    mat `addrow' = J(1, colsof(`bbs'), .z)
+                    mat rown `addrow' = `"`eq':`stat'"'
+                    mat `bbs' = `bbs' \ `addrow'
+                    local r = rownumb(`bbs', `"`eq':`stat'"')
+                }
+                mat `bbs'[`r',`ni'] = `value'
+            }
+        }
+        if `found' {
+            if `bbs'[`s',`ni']==.y {
+                capt return local m`ni'_`stat' ""
+            }
+            mat `bbs'[`s',`ni'] = .x
+        }
+    }
+end
+
+program CheckEqs
+    args coefs
+    tempname tmp
+    local j 0
+    local bVs "b _star _sign _sigsign"
+    local seqmerge 0
+    local hasseqs 0
+    foreach coefn in `coefs' {
+        local ++j
+        gettoken coef row : coefn
+        gettoken transpose row : row
+        gettoken row : row, q
+        if `"`coef'"'=="b" & `j'==1 {
+            capt confirm mat e(`coef')
+            if _rc continue
+            mat `tmp' = e(`coef')
+            local eqs: coleq `tmp', q
+            if `:list posof "_" in eqs'==0 {
+                local seqmerge 1
+            }
+            else continue, break
+        }
+        if `:list coef in bVs' continue
+        capt confirm mat e(`coef')
+        if _rc continue
+        mat `tmp' = e(`coef')
+        if `transpose' {
+            mat `tmp' = `tmp''
+        }
+        if `"`row'"'=="" local row 1
+        capt confirm number `row'
+        if _rc {
+            local row = rownumb(`tmp',`row')
+        }
+        if `row'>rowsof(`tmp') continue
+        local eqs: coleq `tmp', q
+        if `:list posof "_" in eqs' {
+            local eqs: list uniq eqs
+            local eqs: list clean eqs
+            if `"`eqs'"'!="_" { // => contains "_" but also others
+                local local seqmerge 0
+                continue, break
+            }
+            else local hasseqs 1
+        }
+        else {
+            local seqmerge 1
+        }
+    }
+    if `hasseqs'==0 local seqmerge 0
+    c_local seqmerge `seqmerge'
+end
+
+program GetCoefs
+    args bc seqmerge coefs
+    tempname tmp
+    local hasbc 0
+    local j 0
+    local bVs "b _star _sign _sigsign"
+    foreach coefn of local coefs {
+        local ++j
+        gettoken coef row : coefn
+        gettoken transpose row : row
+        gettoken row : row, q
+        local isinbVs: list coef in bVs
+        if `isinbVs' & `j'>2 {
+            if `hasbc'==0  continue
+            mat `bc' = `bc', J(rowsof(`bc'),1, .y)
+            continue
+        }
+        if `j'==2 & `"`coef'"'=="var" {
+            local isinbVs 1
+            capt mat `tmp' = vecdiag(e(V))
+            if _rc {
+                capt confirm mat e(se)
+                if _rc==0 {
+                    mat `tmp' = e(se)
+                    forv i = 1/`=colsof(`tmp')' {
+                        mat `tmp'[1, `i'] = `tmp'[1, `i']^2
+                    }
+                }
+            }
+        }
+        else {
+            capt confirm mat e(`coef')
+            if _rc==0 {
+                mat `tmp' = e(`coef')
+            }
+        }
+        if _rc {
+            if `hasbc'==0  continue
+            mat `bc' = `bc', J(rowsof(`bc'),1, .y)
+            continue
+        }
+        if `isinbVs'==0 { // => not b or var
+            if `transpose' {
+                mat `tmp' = `tmp''
+            }
+            if `"`row'"'=="" local row 1
+            capt confirm number `row'
+            if _rc {
+                local row = rownumb(`tmp',`row')
+            }
+            if `row'>rowsof(`tmp') {
+                if `hasbc'==0  continue
+                mat `bc' = `bc', J(rowsof(`bc'),1, .y)
+                continue
+            }
+            mat `tmp' = `tmp'[`row', 1...]
+        }
+        local bcols = colsof(`tmp')
+        if `bcols'==0 {
+            if `hasbc'==0  continue
+            mat `bc' = `bc', J(rowsof(`bc'),1, .y)
+            continue
+        }
+        mat `tmp' = `tmp''
+        if `seqmerge' & `isinbVs'==0 {
+            local eqs: roweq `tmp', q
+            local eqs: list uniq eqs
+            local eqs: list clean eqs
+            if `"`eqs'"'=="_" {
+                local seqmergejs `seqmergejs' `j'
+                local seqmergecoefs `"`seqmergecoefs'`"`coefn'"' "'
+                if `hasbc'==0  continue
+                mat `bc' = `bc', J(rowsof(`bc'),1, .y)
+                continue
+            }
+        }
+        if `hasbc'==0 {
+            mat `bc' = `tmp'
+            local hasbc 1
+            if `j'>1 {
+                mat `bc' = `bc', J(`bcols',`j'-1, .y), `bc'
+                mat `bc' = `bc'[1...,2...]
+            }
+        }
+        else {
+            mat_capp `bc' : `bc' `tmp', miss(.y) cons ts
+        }
+    }
+    foreach coefn of local seqmergecoefs {
+        gettoken j seqmergejs : seqmergejs
+        gettoken coef row : coefn
+        gettoken transpose row : row
+        gettoken row : row, q
+        mat `tmp' = e(`coef')
+        if `transpose' {
+            mat `tmp' = `tmp''
+        }
+        if `"`row'"'=="" local row 1
+        capt confirm number `row'
+        if _rc {
+            local row = rownumb(`tmp',`row')
+        }
+        mat `tmp' = `tmp'[`row', 1...]
+        SEQMerge `bc' `j' `tmp'
+    }
+    c_local hasbc `hasbc'
+end
+
+program SEQMerge
+    args bc j x
+    tempname tmp
+    local r = rowsof(`bc')
+    forv i = 1/`r' {
+        mat `tmp' = `bc'[`i',1...]
+        local v: rown `tmp'
+        local c = colnumb(`x', `"`v'"')
+        if `c'<. {
+            mat `bc'[`i',`j'] = `x'[1,`c']
+        }
+    }
+end
+
+program ComputeCoefs
+    args bc hasmargin coefs level
+    local bVs1 "b _star _sign _sigsign"
+    local bVs2 "se var t z p ci_l ci_u"
+    local c = colsof(`bc')
+    forv j = 3/`c' {
+        gettoken v coefs : coefs
+        if `"`v'"'=="" continue, break
+        if `: list v in bVs1' {
+            ComputeCoefs_`v' `bc' `j' `level'
+            continue
+        }
+        if `: list v in bVs2' {
+            if `hasmargin' {
+                ComputeCoefs_`v' `bc' `j' `level'
+                continue
+            }
+            capt confirm matrix e(`v')
+            if _rc {
+                ComputeCoefs_`v' `bc' `j' `level'
+            }
+        }
+    }
+end
+
+program CopyColFromTo
+    args m from to cname
+    tempname tmp
+    mat `tmp' = `m'[1...,`from']
+    mat coln `tmp' = `cname'
+    local c = colsof(`m')
+    if `to'==`c' {
+        mat `m' = `m'[1...,1..`c'-1], `tmp'
+        exit
+    }
+    mat `m' = `m'[1...,1..`to'-1], `tmp', `m'[1...,`to'+1..`c']
+end
+
+program ComputeCoefs_b
+    args bc j
+    CopyColFromTo `bc' 1 `j' "b"
+end
+
+program ComputeCoefs_se
+    args bc j
+    local r = rowsof(`bc')
+    forv i = 1/`r' {
+            local var `bc'[`i',2]
+            local res `bc'[`i',`j']
+            if `var'>=.      mat `res' = `var'
+            else if `var'==0 mat `res' = .
+            else             mat `res' = sqrt(`var')
+    }
+end
+
+program ComputeCoefs_var
+    args bc j
+    CopyColFromTo `bc' 2 `j' "var"
+end
+
+program ComputeCoefs_t
+    args bc j
+    local r = rowsof(`bc')
+    forv i = 1/`r' {
+            local b   `bc'[`i',1]
+            local var `bc'[`i',2]
+            local res `bc'[`i',`j']
+            if `b'>=.        mat `res' = `b'
+            else if `var'>=. mat `res' = `var'
+            else             mat `res' = `b'/sqrt(`var')
+    }
+end
+
+program ComputeCoefs_z
+    ComputeCoefs_t `0'
+end
+
+program ComputeCoefs_p
+    args bc j
+    local r = rowsof(`bc')
+    local df_r = e(df_r)
+    forv i = 1/`r' {
+            local b   `bc'[`i',1]
+            local var `bc'[`i',2]
+            local res `bc'[`i',`j']
+            if `b'>=.        mat `res' = `b'
+            else if `var'>=. mat `res' = `var'
+            else if `df_r'<. mat `res' = ttail(`df_r',abs(`b'/sqrt(`var'))) * 2
+            else             mat `res' = (1 - norm(abs(`b'/sqrt(`var')))) * 2
+    }
+end
+
+program ComputeCoefs_ci_l
+    args bc j
+    ComputeCoefs_ci - `0'
+end
+
+program ComputeCoefs_ci_u
+    args bc j
+    ComputeCoefs_ci + `0'
+end
+
+program ComputeCoefs_ci
+    args sign bc j level
+    local r = rowsof(`bc')
+    local df_r = e(df_r)
+    forv i = 1/`r' {
+            local b   `bc'[`i',1]
+            local var `bc'[`i',2]
+            local res `bc'[`i',`j']
+            if `b'>=.        mat `res' = `b'
+            else if `var'>=. mat `res' = `var'
+            else if `df_r'<. mat `res' = `b' `sign' ///
+                                invttail(`df_r',(100-`level')/200) * sqrt(`var')
+            else             mat `res' = `b' `sign' ///
+                                invnorm(1-(100-`level')/200) * sqrt(`var')
+    }
+end
+
+program ComputeCoefs__star
+    args bc j
+    CopyColFromTo `bc' 1 `j' "_star"
+end
+
+program ComputeCoefs__sign
+    args bc j
+    CopyColFromTo `bc' 1 `j' "_sign"
+end
+
+program ComputeCoefs__sigsign
+    args bc j
+    CopyColFromTo `bc' 1 `j' "_sigsign"
+end
+
+program GetMarginals
+    args bc margin meqs
+    tempname D dfdx
+    mat `D' = `bc'[1...,1]*0
+    mat coln `D' = "_dummy"
+    local type `e(Xmfx_type)'
+    if "`type'"!="" {
+        mat `dfdx' = e(Xmfx_`type')
+        capture confirm matrix e(Xmfx_se_`type')
+        if _rc==0 {
+            mat `dfdx' = `dfdx' \ e(Xmfx_se_`type')
+        }
+        if "`e(Xmfx_discrete)'"=="discrete" local dummy `e(Xmfx_dummy)'
+    }
+    else if "`e(cmd)'"=="dprobit" {
+        mat `dfdx' = e(dfdx) \ e(se_dfdx)
+        local dummy `e(dummy)'
+    }
+    else if "`e(cmd)'"=="tobit" & inlist("`margin'","u","c","p") {
+        capture confirm matrix e(dfdx_`margin')
+        if _rc==0 {
+            mat `dfdx' = e(dfdx_`margin') \ e(se_`margin')
+        }
+        local dummy `e(dummy)'
+    }
+    else if "`e(cmd)'"=="truncreg" {
+        capture confirm matrix e(dfdx)
+        if _rc==0 {
+            tempname V se
+            mat `V' = e(V_dfdx)
+            forv k= 1/`=rowsof(`V')' {
+                mat `se' = nullmat(`se') , sqrt(`V'[`k',`k'])
+            }
+            mat `dfdx' = e(dfdx) \ `se'
+        }
+    }
+    capture confirm matrix `dfdx'
+    if _rc==0 {
+        QuotedRowNames `bc'
+        local rnames `"`value'"'
+        if `"`meqs'"'!="" local reqs: roweq `bc', q
+        local i 1
+        foreach row of loc rnames {
+            if `"`meqs'"'!="" {
+                local eq: word `i' of `reqs'
+            }
+            local col = colnumb(`dfdx',"`row'")
+            if `col'>=. | !`:list eq in meqs' {
+                mat `bc'[`i',1] = .y
+                mat `bc'[`i',2] = .y
+            }
+            else {
+                mat `bc'[`i',1] =`dfdx'[1,`col']
+                mat `bc'[`i',2] = (`dfdx'[2,`col'])^2
+                if "`:word `col' of `dummy''"=="1" mat `D'[`i',1] = 1
+            }
+            local ++i
+        }
+        c_local hasmargin 1
+    }
+    mat `bc' = `bc', `D'
+end
+
+program TransformCoefs
+    args bc coefs transform
+    local c = colsof(`bc')
+    forv j = 3/`c' {
+        gettoken v coefs : coefs
+        if inlist("`v'", "b", "ci_l", "ci_u") {
+            _TransformCoefs `bc' `j' 0 "" "" `"`transform'"'
+        }
+        else if "`v'"=="se" {
+            _TransformCoefs `bc' `j' 1 "abs" "" `"`transform'"'
+        }
+        else if "`v'"=="var" {
+            _TransformCoefs `bc' `j' 1 "" "^2" `"`transform'"'
+        }
+    }
+end
+
+program _TransformCoefs
+    args bc j usedf abs sq transform
+    local r = rowsof(`bc')
+    gettoken coef rest : transform
+    gettoken f rest : rest
+    gettoken df rest : rest
+    while `"`coef'`f'`df'"'!="" {
+        if `"`df'`rest'"'=="" { // last element of list may be without coef
+            local df   `"`f'"'
+            local f    `"`coef'"'
+            local coef ""
+        }
+        local trcoefs `"`trcoefs'`"`coef'"' "'
+        if `usedf' {
+            local trs `"`trs'`"`df'"' "'
+        }
+        else {
+            local trs `"`trs'`"`f'"' "'
+        }
+        gettoken coef rest : rest
+        gettoken f rest : rest
+        gettoken df rest : rest
+    }
+    local trs : subinstr local trs  "@" "\`b'", all
+    forv i = 1/`r' {
+        gettoken coef coefrest : trcoefs
+        gettoken tr trrest : trs
+        while `"`coef'`tr'"'!="" {
+            MatchCoef `"`coef'"' `bc' `i'
+            if `match' {
+                if `usedf' {
+                    local b   `bc'[`i',1]
+                    local res `bc'[`i',`j']
+                    if `res'<. {
+                        mat `res' = `res' * `abs'(`tr')`sq'
+                    }
+                }
+                else {
+                    local b `bc'[`i',`j']
+                    if `b'<. {
+                        mat `b' = (`tr')
+                    }
+                }
+                continue, break
+            }
+            gettoken coef coefrest : coefrest
+            gettoken tr trrest : trrest
+        }
+    }
+end
+
+program MatchCoef
+    args eqx b i
+    if inlist(trim(`"`eqx'"'),"","*") {
+        c_local match 1
+        exit
+    }
+    tempname tmp
+    mat `tmp' = `b'[`i',1...]
+    local eqi: roweq `tmp'
+    local xi: rown `tmp'
+    gettoken eq x : eqx, parse(:)
+    local eq: list clean eq
+    if `"`eq'"'==":" {    // case 1: ":[varname]"
+        local eq
+    }
+    else if `"`x'"'=="" { // case 2: "varname"
+        local x `"`eq'"'
+        local eq
+    }
+    else {                // case 3. "eqname:[varname]"
+        gettoken colon x : x, parse(:)
+        local x: list clean x
+    }
+    if `"`eq'"'=="" local eq "*"
+    if `"`x'"'=="" local x "*"
+    c_local match = match(`"`eqi'"', `"`eq'"') & match(`"`xi'"', `"`x'"')
+end
+
+program NumberMlabels
+    args M mlabels
+    forv m = 1/`M' {
+        local num "(`m')"
+        local lab: word `m' of `macval(mlabels)'
+        if `"`macval(lab)'"'!="" {
+            local lab `"`num' `macval(lab)'"'
+        }
+        else local lab `num'
+        local labels `"`macval(labels)'`"`macval(lab)'"' "'
+    }
+    c_local mlabels `"`macval(labels)'"'
+end
+
+program ModelEqCheck
+    args B eq m ccols
+    tempname Bsub
+    mat `Bsub' = `B'["`eq':",(`m'-1)*`ccols'+1]
+    local R = rowsof(`Bsub')
+    local value 0
+    forv r = 1/`R' {
+        if `Bsub'[`r',1]<. {
+            local value 1
+            continue, break
+        }
+    }
+    c_local value `value'
+end
+
+program Add2Vblock
+    args block col
+    foreach v of local col {
+        gettoken row block: block
+        local row "`row' `v'"
+        local row: list retok row
+        local vblock `"`vblock'"`row'" "'
+    }
+    c_local vblock `"`vblock'"'
+end
+
+program CountNofEqs
+    args ms es
+    local m0 0
+    local e0 0
+    local i 0
+    local eqs 0
+    foreach m of local ms {
+        local ++i
+        local e: word `i' of `es'
+        if `m'!=`m0' | `e'!=`e0' {
+            local ++eqs
+        }
+        local m0 `m'
+        local e0 `e'
+    }
+    c_local value `eqs'
+end
+
+program InsertAtVariables
+    args value type span M E width hline rtf rtfrowdefbrdrt rtfrowdefbrdrb rtfrowdef rtfemptyrow ///
+        title note discrete starlegend
+    if `type'==1 local atvars span
+    else {
+        local atvars span M E width hline
+        if `rtf' local atvars `atvars' rtfrowdefbrdrt rtfrowdefbrdrb rtfrowdef rtfemptyrow
+        if `type'!=2  local atvars `atvars' title note discrete starlegend
+    }
+    foreach atvar of local atvars {
+        capt local value: subinstr local value "@`atvar'" `"`macval(`atvar')'"', all
+         // note: returns error if length of  is more than 502 characters
+    }
+    c_local value `"`macval(value)'"'
+end
+
+program Abbrev
+    args width value abbrev
+    if "`abbrev'"!="" {
+        if `width'>32 {
+            local value = substr(`"`macval(value)'"',1,`width')
+        }
+        else if `width'>0 {
+            if length(`"`macval(value)'"')>`width' {
+                local value = abbrev(`"`macval(value)'"',`width')
+            }
+        }
+    }
+    c_local value `"`macval(value)'"'
+end
+
+program MgroupsPattern
+    args mrow pattern
+    local i 0
+    local m0 0
+    local j 0
+    foreach m of local mrow {
+        if `m'>=. {
+            local newpattern `newpattern' .
+            continue
+        }
+        if `m'!=`m0' {
+            local p: word `++i' of `pattern'
+            if `i'==1 local p 1
+            if "`p'"=="1" local j = `j' + 1
+        }
+        local newpattern `newpattern' `j'
+        local m0 `m'
+    }
+    c_local mgroupspattern `newpattern'
+end
+
+program WriteCaption
+    args file delimiter stardetach row rowtwo labels starsrow span  ///
+     abbrev colwidth delwidth starwidth repeat prefix suffix
+    local c 0
+    local nspan 0
+    local c0 2
+    local spanwidth -`delwidth'
+    local spanfmt
+    local ncolwidth: list sizeof colwidth
+    foreach r of local row {
+        local rtwo: word `++c' of `rowtwo'
+        local colwidthj: word `=1+mod(`c'-1,`ncolwidth')' of `colwidth'
+        if `colwidthj'>0 local colfmt "%`colwidthj's"
+        else local colfmt
+        if "`r'"=="." {
+            local ++c0
+            file write `file' `macval(delimiter)' `colfmt' (`""')
+        }
+        else if `"`span'"'=="" {
+            if ( "`r'"!="`lastr'" | "`rtwo'"!="`lastrtwo'" | `"`rowtwo'"'=="" ) {
+                local value: word `r' of `macval(labels)'
+                Abbrev `colwidthj' `"`macval(value)'"' "`abbrev'"
+                local value `"`macval(prefix)'`macval(value)'`macval(suffix)'"'
+                InsertAtVariables `"`macval(value)'"' 1 "1"
+            }
+            else local value
+            file write `file' `macval(delimiter)' `colfmt' (`"`macval(value)'"')
+            if `:word `c' of `starsrow''==1 {
+                file write `file' `macval(stardetach)' _skip(`starwidth')
+            }
+            local lastr "`r'"
+            local lastrtwo "`rtwo'"
+        }
+        else {
+            local ++nspan
+            local spanwidth=`spanwidth'+`colwidthj'+`delwidth'
+            if `:word `c' of `starsrow''==1 {
+                local spanwidth = `spanwidth' + `starwidth'
+                if `"`macval(stardetach)'"'!="" {
+                    local ++nspan
+                    local spanwidth = `spanwidth' + `delwidth'
+                }
+            }
+            local nextrtwo: word `=`c'+1' of `rowtwo'
+            local nextr: word `=`c'+1' of `row'
+            if "`r'"!="." & ///
+             ("`r'"!="`nextr'" | "`rtwo'"!="`nextrtwo'" | `"`rowtwo'"'=="") {
+                local value: word `r' of `macval(labels)'
+                Abbrev `spanwidth' `"`macval(value)'"' "`abbrev'"
+                local value `"`macval(prefix)'`macval(value)'`macval(suffix)'"'
+                InsertAtVariables `"`macval(value)'"' 1 "`nspan'"
+                if `spanwidth'>0 local spanfmt "%-`spanwidth's"
+                file write `file' `macval(delimiter)' `spanfmt' (`"`macval(value)'"')
+                InsertAtVariables `"`macval(repeat)'"' 1 "`c0'-`=`c0'+`nspan'-1'"
+                local repeatlist `"`macval(repeatlist)'`macval(value)'"'
+                local c0 = `c0' + `nspan'
+                local nspan 0
+                local spanwidth -`delwidth'
+            }
+        }
+    }
+    c_local value `"`macval(repeatlist)'"'
+end
+
+program WriteBegin
+    args file pre begin post
+    foreach line of local pre {
+        file write `file' `newline' `"`macval(line)'"'
+        local newline _n
+    }
+    file write `file' `macval(begin)' `macval(post)'
+end
+
+program WriteEnd
+    args file end post post2
+    file write `file' `macval(end)'
+    WriteStrLines `"`file'"' `"`macval(post)'"'
+    WriteStrLines `"`file'"' `"`macval(post2)'"'
+    file write `file' _n
+end
+
+program WriteStrLines
+    args file lines
+    foreach line of local lines {
+        file write `file' `newline' `"`macval(line)'"'
+        local newline _n
+    }
+end
+
+program WriteEqrow
+    args file delimiter stardetach value row span vwidth fmt_v ///
+     abbrev mwidth delwidth starwidth prefix suffix ///
+     haslabcol2 labcolwidth fmt_l2
+    local nspan 1
+    local spanwidth `vwidth'
+    local spanfmt
+    local c 0
+    local nmwidth: list sizeof mwidth
+    if `"`span'"'=="" {
+        Abbrev `vwidth' `"`macval(value)'"' "`abbrev'"
+        local value `"`macval(prefix)'`macval(value)'`macval(suffix)'"'
+        InsertAtVariables `"`macval(value)'"' 1 "1"
+        file write `file' `fmt_v' (`"`macval(value)'"')
+        if `haslabcol2' {
+            file write `file' `macval(delimiter)' `fmt_l2' ("")
+        }
+        foreach r of local row {
+            local mwidthj: word `=1+mod(`c++',`nmwidth')' of `mwidth'
+            if `mwidthj'>0 local fmt_m "%`mwidthj's"
+            else local fmt_m
+            file write `file' `macval(delimiter)' `fmt_m' ("")
+            if `r'==1 {
+                file write `file' `macval(stardetach)' _skip(`starwidth')
+            }
+        }
+    }
+    else {
+        if `haslabcol2' {
+            local ++nspan
+            local spanwidth = `spanwidth' + `delwidth' + `labcolwidth'
+        }
+        foreach r of local row {
+            local mwidthj: word `=1+mod(`c++',`nmwidth')' of `mwidth'
+            local ++nspan
+            local spanwidth = `spanwidth' + `delwidth' + `mwidthj'
+            if `r'==1 {
+                local spanwidth = `spanwidth' + `starwidth'
+                if `"`macval(stardetach)'"'!="" {
+                    local ++nspan
+                    local spanwidth = `spanwidth' + `delwidth'
+                }
+            }
+        }
+        Abbrev `spanwidth' `"`macval(value)'"' "`abbrev'"
+        local value `"`macval(prefix)'`macval(value)'`macval(suffix)'"'
+        InsertAtVariables `"`macval(value)'"' 1 "`nspan'"
+        if `spanwidth'>0 local spanfmt "%-`spanwidth's"
+        file write `file' `spanfmt' (`"`macval(value)'"')
+    }
+end
+
+prog WriteStrRow
+    args file mrow eqrow neq labels delimiter stardetach starsrow  ///
+     abbrev colwidth delwidth starwidth
+    local c 0
+    local ncolwidth: list sizeof colwidth
+    foreach mnum of local mrow {
+        local eqnum: word `++c' of `eqrow'
+        local colwidthj: word `=1+mod(`c'-1,`ncolwidth')' of `colwidth'
+        if `colwidthj'>0 local colfmt "%`colwidthj's"
+        else local colfmt
+        if "`mnum'"=="." {
+            file write `file' `macval(delimiter)' `colfmt' (`""')
+            continue
+        }
+        if ( "`mnum'"!="`lastmnum'" | "`eqnum'"!="`lasteqnum'" ) {
+            local value: word `=(`mnum'-1)*`neq'+`eqnum'' of `macval(labels)'
+            Abbrev `colwidthj' `"`macval(value)'"' "`abbrev'"
+        }
+        else local value
+        file write `file' `macval(delimiter)' `colfmt' (`"`macval(value)'"')
+        if `:word `c' of `starsrow''==1 {
+            file write `file' `macval(stardetach)' _skip(`starwidth')
+        }
+        local lastmnum "`mnum'"
+        local lasteqnum "`eqnum'"
+    }
+end
+
+program VarInList
+    args var unstack eqvar eq list
+    local value
+    local L: word count `macval(list)'
+    forv l = 1(2)`L' {
+        local lvar: word `l' of `macval(list)'
+        local lab: word `=`l'+1' of `macval(list)'
+        if "`unstack'"!="" {
+            if `"`var'"'==`"`lvar'"' {
+                local value `"`macval(lab)'"'
+                continue, break
+            }
+        }
+        else {
+            if inlist(`"`lvar'"',`"`var'"',`"`eqvar'"',`"`eq':"') {
+                local value `"`macval(lab)'"'
+                continue, break
+            }
+        }
+    }
+    c_local value `"`macval(value)'"'
+end
+
+program vFormat
+    args value fmt lz dmarker msign par
+    if substr(`"`fmt'"',1,1)=="a" {
+        SignificantDigits `fmt' `value'
+    }
+    else {
+        capt confirm integer number `fmt'
+        if !_rc {
+            local fmt %`=`fmt'+9'.`fmt'f
+        }
+    }
+    else if `"`fmt'"'=="%g" | `"`fmt'"'=="g" local fmt "%9.0g"
+    else if substr(`"`fmt'"',1,1)!="%" {
+        di as err `"`fmt': invalid format"'
+        exit 198
+    }
+    local value: di `fmt' `value'
+    local value: list retok value
+    if "`lz'"=="" {
+        if index("`value'","0.")==1 | index("`value'","-0.") {
+            local value: subinstr local value "0." "."
+        }
+    }
+    if `"`macval(dmarker)'"'!="" {
+        if "`: set dp'"=="comma" local dp ,
+        else local dp .
+        local val: subinstr local value "`dp'" `"`macval(dmarker)'"'
+    }
+    else local val `"`value'"'
+    if `"`msign'"'!="" {
+        if index("`value'","-")==1 {
+            local val: subinstr local val "-" `"`macval(msign)'"'
+        }
+    }
+    if `"`par'"'!="" {
+        tokenize `"`macval(par)'"'
+        local val `"`macval(1)'`macval(val)'`macval(2)'"'
+    }
+    c_local value `"`macval(val)'"'
+end
+
+program SignificantDigits // idea stolen from outreg2.ado
+    args fmt value
+    local d = substr("`fmt'", 2, .)
+    if `"`d'"'=="" local d 3
+    capt confirm integer number `d'
+    if _rc {
+        di as err `"`fmt': invalid format"'
+        exit 198
+    }
+// missing: format does not matter
+    if `value'>=. local fmt "%9.0g"
+// integer: print no decimal places
+    else if (`value'-int(`value'))==0 {
+        local fmt "%12.0f"
+    }
+// value in (-1,1): display up to 9 decimal places with d significant
+// digits, then switch to e-format with d-1 decimal places
+    else if abs(`value')<1 {
+        local right = -int(log10(abs(`value'-int(`value')))) // zeros after dp
+        local dec = max(1,`d' + `right')
+        if `dec'<=9 {
+            local fmt "%12.`dec'f"
+        }
+        else {
+            local fmt "%12.`=min(9,`d'-1)'e"
+        }
+    }
+// |values|>=1: display d+1 significant digits or more with at least one
+// decimal place and up to nine digits before the decimal point, then
+// switch to e-format
+    else {
+        local left = int(log10(abs(`value'))+1) // digits before dp
+        if `left'<=9 {
+            local fmt "%12.`=max(1,`d' - `left' + 1)'f"
+        }
+        else {
+            local fmt "%12.0e" // alternatively: "%12.`=min(9,`d'-1)'e"
+        }
+    }
+    c_local fmt "`fmt'"
+end
+
+program Stars
+    args starlevels P
+    if inrange(`P',0,1) {
+        local nstar: word count `macval(starlevels)'
+        forv i=1(2)`nstar' {
+            local istarsym: word `i' of `macval(starlevels)'
+            local istar: word `=`i'+1' of `macval(starlevels)'
+            if `istar'<=`P' continue, break
+            local value "`macval(istarsym)'"
+        }
+    }
+    c_local value `"`macval(value)'"'
+end
+
+program CellStars
+    args starlevels P par
+    Stars `"`macval(starlevels)'"' `P'
+    if `"`par'"'!="" {
+        tokenize `"`macval(par)'"'
+        local value `"`macval(1)'`macval(value)'`macval(2)'"'
+    }
+    c_local value `"`macval(value)'"'
+end
+
+prog MakeSign
+    args value msign par starlevels P
+    if "`P'"!="" {
+        local factor = 0
+        while 1 {
+            gettoken istar starlevels : starlevels
+            gettoken istar starlevels : starlevels
+            if `"`istar'"'=="" continue, break
+            if `P'<`istar' local factor = `factor' + 1
+            else if `istar'==1 local factor = 1
+        }
+    }
+    else local factor 1
+    if `"`macval(msign)'"'=="" local msign "-"
+    if `value'<0 {
+        local val: di _dup(`factor') `"`macval(msign)'"'
+    }
+    else if `value'==0 local val: di _dup(`factor') "0"
+    else if `value'>0 & `value'<. local val: di _dup(`factor') "+"
+    else local val `value'
+    if `"`par'"'!="" {
+        tokenize `"`macval(par)'"'
+        local val `"`macval(1)'`macval(val)'`macval(2)'"'
+    }
+    c_local value `"`macval(val)'"'
+end
+
+program DropOrKeep
+    args type b spec // type=0: drop; type=1: keep
+    capt confirm matrix `b'
+    if _rc {
+        exit
+    }
+    tempname res bt
+    local R = rowsof(`b')
+    forv i=1/`R' {
+        local hit 0
+        mat `bt' = `b'[`i',1...]
+        foreach sp of local spec {
+            if rownumb(`bt', `"`sp'"')==1 {
+                local hit 1
+                continue, break
+            }
+        }
+        if `hit'==`type' mat `res' = nullmat(`res') \ `bt'
+    }
+    capt mat drop `b'
+    capt mat rename `res' `b'
+end
+
+program Order
+    args b spec
+    capt confirm matrix `b'
+    if _rc {
+        exit
+    }
+    tempname bt res
+    local eqlist: roweq `b', q
+    local eqlist: list uniq eqlist
+    mat `bt' = `b'
+    gettoken spi rest : spec
+    while `"`spi'"'!="" {
+        gettoken spinext rest : rest
+        if !index(`"`spi'"',":") {
+            local vars `"`vars'`"`spi'"' "'
+            if `"`spinext'"'!="" & !index(`"`spinext'"',":") {
+                local spi `"`spinext'"'
+                continue
+            }
+            foreach eq of local eqlist {
+                foreach var of local vars {
+                    local splist `"`splist'`"`eq':`var'"' "'
+                }
+                local splist `"`splist'`"`eq':"' "' // rest
+            }
+            local vars
+        }
+        else local splist `"`spi'"'
+        gettoken sp splist : splist
+        while `"`sp'"'!="" {
+            local isp = rownumb(`bt', "`sp'")
+            if `isp' >= . {
+                gettoken sp splist : splist
+                continue
+            }
+            while `isp' < . {
+                mat `res' = nullmat(`res') \ `bt'[`isp',1...]
+                local nb = rowsof(`bt')
+                if `nb' == 1 { // no rows left in `bt'
+                    capt mat drop `b'
+                    capt mat rename `res' `b'
+                    exit
+                }
+                if `isp' == 1 {
+                    mat `bt' = `bt'[2...,1...]
+                }
+                else if `isp' == `nb' {
+                    mat `bt' = `bt'[1..`=`nb'-1',1...]
+                }
+                else {
+                    mat `bt' = `bt'[1..`=`isp'-1',1...] \ `bt'[`=`isp'+1'...,1...]
+                }
+                local isp = rownumb(`bt', "`sp'")
+            }
+            gettoken sp splist : splist
+        }
+        local spi `"`spinext'"'
+    }
+    capt mat `res' = nullmat(`res') \ `bt'
+    capt mat drop `b'
+    capt mat rename `res' `b'
+end
+
+prog MakeQuotedFullnames
+    args names eqs
+    foreach name of local names {
+        gettoken eq eqs : eqs
+        local value `"`value'`"`eq':`name'"' "'
+    }
+    c_local value: list clean value
+end
+
+program define QuotedRowNames
+    args matrix
+    capt confirm matrix `matrix'
+    if _rc {
+        c_local value ""
+        exit
+    }
+    tempname extract
+    if substr(`"`matrix'"',1,2)=="r(" {
+        local matrix0 `"`matrix'"'
+        tempname matrix
+        mat `matrix' = `matrix0'
+    }
+    local R = rowsof(`matrix')
+    forv r = 1/`R' {
+        mat `extract' = `matrix'[`r',1...]
+        local name: rownames `extract'
+        local value `"`value'`"`name'"' "'
+    }
+    c_local value: list clean value
+end
+
+prog EqReplaceCons
+    args names eqlist eqlabels varlabels
+    local skip 0
+    foreach v of local varlabels {
+        if `skip' {
+            local skip 0
+            continue
+        }
+        local vlabv `"`vlabv'`"`v'"' "'
+        local skip 1
+    }
+    local deqs: list dups eqlist
+    local deqs: list uniq deqs
+    local i 0
+    foreach eq of local eqlist {
+        local ++i
+        if `"`eq'"'!=`"`last'"' {
+            gettoken eqlab eqlabels : eqlabels
+        }
+        local last `"`eq'"'
+        if `:list eq in deqs' | `"`eq'"'=="_" continue
+        local name: word `i' of `names'
+        local isinvlabv: list posof `"`eq':`name'"' in vlabv
+        if `"`name'"'=="_cons" & `isinvlabv'==0 {
+            local value `"`value'`space'`"`eq':`name'"' `"`eqlab'"'"'
+            local space " "
+        }
+    }
+    c_local value `"`value'"'
+end
+
+prog UniqEqsAndDims
+    local n 0
+    foreach el of local 1 {
+        if `"`macval(el)'"'!=`"`macval(last)'"' {
+            if `n'>0 local eqsdims "`eqsdims' `n'"
+            local eqs `"`macval(eqs)' `"`macval(el)'"'"'
+            local n 0
+        }
+        local ++n
+        local last `"`macval(el)'"'
+    }
+    local eqsdims "`eqsdims' `n'"
+    c_local eqsdims: list clean eqsdims
+    c_local eqs: list clean eqs
+end
+
+prog InsertAtCols
+    args colnums row symb
+    if `"`symb'"'=="" local symb .
+    gettoken c rest : colnums
+    local i 0
+    foreach r of local row {
+        local ++i
+        while `"`c'"'!="" {
+            if `c'<=`i' {
+                local value `"`value' `symb'"'
+                gettoken c rest : rest
+            }
+            else continue, break
+        }
+        local value `"`value' `"`r'"'"'
+    }
+    while `"`c'"'!="" {
+        local value `"`value' `symb'"'
+        gettoken c rest : rest
+    }
+    c_local value: list clean value
+end
+
+prog GetVarnamesFromOrder
+    foreach sp of local 1 {
+        if index(`"`sp'"', ":") {
+            gettoken trash sp: sp, parse(:)
+            if `"`trash'"'!=":" {
+                gettoken trash sp: sp, parse(:)
+            }
+        }
+        local value `"`value'`space'`sp'"'
+        local space " "
+    }
+    c_local value `"`value'"'
+end
+
+prog ParseIndicateOpts
+    syntax [anything(equalok)] [, Labels(str asis) ]
+    gettoken tok rest : anything, parse(" =")
+    while `"`macval(tok)'"'!="" {
+        if `"`macval(tok)'"'=="=" {
+            local anything `"`"`macval(anything)'"'"'
+            continue, break
+        }
+        gettoken tok rest : rest, parse(" =")
+    }
+    c_local indicate `"`macval(anything)'"'
+    c_local indicatelabels `"`macval(labels)'"'
+end
+
+prog ProcessIndicateGrp
+    args i B nmodels unstack yesno indicate
+    gettoken yes no : yesno
+    gettoken no : no
+    gettoken tok rest : indicate, parse(=)
+    while `"`macval(tok)'"'!="" {
+        if `"`macval(rest)'"'=="" {
+            local vars `"`indicate'"'
+            continue, break
+        }
+        if `"`macval(tok)'"'=="=" {
+            local vars `"`rest'"'
+            continue, break
+        }
+        local name `"`macval(name)'`space'`macval(tok)'"'
+        local space " "
+        gettoken tok rest : rest, parse(=)
+    }
+    if `"`macval(name)'"'=="" {
+        local name: word 1 of `"`vars'"'
+    }
+    ExpandEqVarlist `"`vars'"' `B'
+    local evars `"`value'"'
+    IsInModels `B' `nmodels' "`unstack'" `"`macval(yes)'"' `"`macval(no)'"' `"`evars'"'
+    local lbls `"`macval(value)'"'
+    DropOrKeep 0 `B' `"`evars'"'
+    c_local indicate`i'name `"`macval(name)'"'
+    c_local indicate`i'lbls `"`macval(lbls)'"'
+    c_local indicate`i'eqs `"`eqs'"'
+end
+
+prog IsInModels
+    args B nmodels unstack yes no vars
+    capt confirm matrix `B'
+    if _rc {
+        forv i = 1/`nmodels' {
+            local lbls `"`macval(lbls)' `"`macval(no)'"'"'
+        }
+        c_local value `"`macval(lbls)'"'
+        if `"`unstack'"'!="" {
+            c_local eqs "_"
+        }
+        exit
+    }
+    local models: coleq `B', q
+    local models: list uniq models
+    local eqs: roweq `B', q
+    local eqs: list uniq eqs
+    tempname Bt Btt Bttt
+    foreach model of local models {
+        local stop 0
+        mat `Bt' = `B'[1...,"`model':"]
+        foreach eq of local eqs {
+            mat `Btt' = `Bt'[`"`eq':"',1]
+            if `"`unstack'"'!="" local stop 0
+            foreach var of local vars {
+                if !index(`"`var'"',":") {
+                    local var `"`eq':`var'"'
+                }
+                capt mat `Bttt' = `Btt'["`var'",1]
+                if _rc continue
+                forv i = 1/`= rowsof(`Bttt')' {
+                    if `Bttt'[`i',1]<.z {
+                        local lbls `"`macval(lbls)' `"`macval(yes)'"'"'
+                        local stop 1
+                        continue, break
+                    }
+                }
+                if `stop' continue, break
+            }
+            if `"`unstack'"'!="" {
+                if `stop'==0 {
+                    local lbls `"`macval(lbls)' `"`macval(no)'"'"'
+                }
+            }
+            else if `stop' continue, break
+        }
+        if `"`unstack'"'=="" & `stop'==0 {
+            local lbls `"`macval(lbls)' `"`macval(no)'"'"'
+        }
+    }
+    c_local value `"`macval(lbls)'"'
+    if `"`unstack'"'!="" {
+        c_local eqs `"`eqs'"'
+    }
+end
+
+prog ReorderEqsInIndicate
+    args nmodels eqs ieqs lbls
+    local neq: list sizeof ieqs
+    foreach eq of local eqs {
+        local i: list posof `"`eq'"' in ieqs
+        if `i' {
+            local pos `pos' `i'
+        }
+    }
+    forv m=1/`nmodels' {
+        foreach i of local pos {
+            local mi = (`m'-1)*`neq' + `i'
+            local lbl: word `mi' of `macval(lbls)'
+            local value `"`macval(value)'`"`macval(lbl)'"' "'
+        }
+    }
+    c_local value `"`macval(value)'"'
+end
+
+prog ParseRefcatOpts
+    syntax [anything(equalok)] [, NOLabel Label(str) Below ]
+    c_local refcatbelow "`below'"
+    c_local norefcatlabel "`nolabel'"
+    c_local refcatlabel `"`macval(label)'"'
+    c_local refcat `"`macval(anything)'"'
+end
+
+prog PrepareRefcat
+    gettoken coef rest : 1
+    gettoken name rest : rest
+    while `"`macval(coef)'"'!="" {
+        local coefs `"`coefs'`coef' "'
+        local names `"`macval(names)'`"`macval(name)'"' "'
+        gettoken coef rest : rest
+        gettoken name rest : rest
+    }
+    c_local refcatcoefs `"`coefs'"'
+    c_local refcatnames `"`macval(names)'"'
+end
+
+prog GenerateRefcatRow
+    args B ccols var eqs label
+    local models: coleq `B', q
+    local models: list uniq models
+    local col 1
+    foreach model of local models {
+        foreach eq of local eqs {
+            local eqvar `"`eq':`var'"'
+            local row = rownumb(`B',"`eqvar'")
+            if `B'[`row', `col']<.z {
+                local value `"`macval(value)'`"`macval(label)'"' "'
+            }
+            else {
+                local value `"`macval(value)'`""' "'
+            }
+        }
+        local col = `col' + `ccols'
+    }
+    c_local value `"`macval(value)'"'
+end
+
+prog ParseTransformSubopts
+    syntax anything(equalok) [, Pattern(string) ]
+    c_local transform `"`anything'"'
+    c_local transformpattern "`pattern'"
+end
+
+prog MakeTransformList
+    args B transform
+    local R = rowsof(`B')
+    if `:list sizeof transform'<=2 {
+        gettoken f rest : transform
+        gettoken df : rest
+        forv i = 1/`R' {
+            local valuef `"`valuef'`f' "'
+            local valuedf `"`valuedf'`df' "'
+        }
+        c_local valuef: list retok valuef
+        c_local valuedf: list retok valuedf
+        exit
+    }
+    gettoken coef rest : transform
+    gettoken f rest : rest
+    gettoken df rest : rest
+    while (`"`coef'"'!="") {
+        if (`"`df'`rest'"'!="") { // last element of list may be without coef
+            ExpandEqVarlist `"`coef'"' `B'
+            local coef `"`value'"'
+        }
+        local coefs `"`coefs'`"`coef'"' "'
+        local fs `"`fs'`"`f'"' "'
+        local dfs `"`dfs'`"`df'"' "'
+        gettoken coef rest : rest
+        gettoken f rest : rest
+        gettoken df rest : rest
+    }
+    tempname b
+    local value
+    forv i = 1/`R' {
+        mat `b' = `B'[`i',1...]
+        local i 0
+        local hit 0
+        foreach coef of local coefs {
+            local f: word `++i' of `fs'
+            local df: word `i' of `dfs'
+            if (`"`df'`rest'"'=="") {
+                local valuef `"`valuef'`"`coef'"' "'  // sic! (see above)
+                local valuedf `"`valuedf'`"`f'"' "'
+                local hit 1
+                continue, break
+            }
+            foreach c of local coef {
+                if rownumb(`b', `"`c'"')==1 {
+                    local valuef `"`valuef'`"`f'"' "'
+                    local valuedf `"`valuedf'`"`df'"' "'
+                    local hit 1
+                    continue, break
+                }
+            }
+            if `hit' continue, break
+        }
+        if `hit'==0 {
+            local valuef `"`valuef'"" "'
+            local valuedf `"`valuedf'"" "'
+        }
+    }
+    c_local valuef: list retok valuef
+    c_local valuedf: list retok valuedf
+end
+
+prog TableIsAMess
+    local ccols = r(ccols)
+    local eq: roweq r(coefs), q
+    local eq: list uniq eq
+    if `: list sizeof eq'<=1 {
+        c_local value 0
+        exit
+    }
+    tempname b bt
+    mat `b' = r(coefs)
+    gettoken eq : eq
+    mat `b' = `b'[`"`eq':"', 1...]
+    local R = rowsof(`b')
+    local models: coleq `b', q
+    local models: list uniq models
+    local value 0
+    local i = 1 - `ccols'
+    foreach model of local models {
+        local i = `i' + `ccols'
+        if `i'==1 continue // skip first model
+        mat `bt' = `b'[1...,`i']
+        local allz 1
+        forv r = 1/`R' {
+            if `bt'[`r',1]<.z {
+                local allz 0
+                continue, break
+            }
+        }
+        if `allz' {
+            local value 1
+            continue, break
+        }
+    }
+    c_local value `value'
+end
+
+prog ExpandEqVarlist
+    args list B append
+    ParseEqVarlistRelax `list'
+    QuotedRowNames `B'
+    local coefs `"`value'"'
+    local value
+    local ucoefs: list uniq coefs
+    capt confirm matrix `B'
+    if _rc==0 {
+        local eqs: roweq `B', q
+    }
+    else local eqs "_"
+    local ueqs: list uniq eqs
+    while `"`list'"'!="" {
+// get next element
+        gettoken eqx list : list
+// separate eq and x
+        gettoken eq x : eqx, parse(:)
+        local eq: list clean eq
+        if `"`eq'"'==":" {    // case 1: ":[varname]"
+            local eq
+        }
+        else if `"`x'"'=="" { // case 2: "varname"
+            local x `"`eq'"'
+            local eq
+        }
+        else {                // case 3. "eqname:[varname]"
+            gettoken colon x : x, parse(:)
+            local x: list clean x
+        }
+// match equations
+        local eqmatch
+        if `:list eq in ueqs' { // (note: evaluates to 1 if eq empty)
+            local eqmatch `"`eq'"'
+        }
+        else {
+            foreach e of local ueqs {
+                if match(`"`e'"', `"`eq'"') {
+                    local eqmatch `"`eqmatch' `"`e'"'"'
+                }
+            }
+            if `"`eqmatch'"'=="" & "`relax'"=="" {
+                if !("`append'"!="" & `"`x'"'!="") {
+                    di as err `"equation `eq' not found"'
+                    exit 111
+                }
+            }
+            local eqmatch: list clean eqmatch
+        }
+        if `"`x'"'=="" {
+            foreach e of local eqmatch {
+                local value `"`value' `"`e':"'"'
+            }
+            continue
+        }
+// match coefficients
+        local vlist
+// - without equation
+        if `"`eq'"'=="" {
+            if `:list x in ucoefs' {
+                local value `"`value' `"`x'"'"'
+                continue
+            }
+            foreach coef of local ucoefs {
+                if match(`"`coef'"', `"`x'"') {
+                    local vlist `"`vlist' `"`coef'"'"'
+                }
+            }
+            if `"`vlist'"'=="" {
+                if "`append'"!="" {
+                    local appendlist `"`appendlist' `"`x'"'"'
+                    local value `"`value' `"`x'"'"'
+                }
+                else if "`relax'"=="" {
+                    di as err `"coefficient `x' not found"'
+                    exit 111
+                }
+            }
+            else {
+                local value `"`value' `vlist'"'
+            }
+            continue
+        }
+// - within equations
+        local rest `"`eqs'"'
+        foreach coef of local coefs {
+            gettoken e rest : rest
+            if !`:list e in eqmatch' {
+                continue
+            }
+            if match(`"`coef'"', `"`x'"') {
+                local vlist `"`vlist' `"`e':`coef'"'"'
+            }
+        }
+        if `"`vlist'"'=="" {
+            if "`append'"!="" {
+                local appendlist `"`appendlist' `"`eq':`x'"'"'
+                local value `"`value' `"`eq':`x'"'"'
+            }
+            else if "`relax'"=="" {
+                di as err `"coefficient `eq':`x' not found"'
+                exit 111
+            }
+        }
+        else {
+            local value `"`value' `vlist'"'
+        }
+    }
+    if "`append'"!="" {
+        local nappend : list sizeof appendlist
+        if `nappend'>0 {
+            capt confirm matrix `B'
+            if _rc==0 {
+                tempname tmp
+                mat `tmp' = J(`nappend', colsof(`B'), .z)
+                mat rown `tmp' = `appendlist'
+                matrix `B' = `B' \ `tmp'
+            }
+        }
+    }
+    c_local value: list clean value
+end
+
+program ParseEqVarlistRelax
+    syntax [anything] [, Relax ]
+    c_local list `"`anything'"'
+    c_local relax `relax'
+end
+
+program IsInString //, rclass
+    args needle haystack
+    local trash: subinstr local haystack `"`needle'"' "", count(local count)
+    c_local strcount = `count'
+end
+
+program MakeRtfRowdefs
+    args str srow sdetach vwidth mwidth haslc2 lc2width
+    local factor 120
+    ParseRtfcmdNum `"`str'"' "trgaph" 0
+    ParseRtfcmdNum `"`str'"' "trleft" 0
+    if `vwidth'<=0 local vwidth 12
+    if real(`"`trgaph'"')>=. local trgaph 0
+    if real(`"`trleft'"')>=. local trleft 0
+    local swidth = 3
+    local vtwips = `vwidth'*`factor'
+    local stwips = `swidth'*`factor'
+    local ipos = `vtwips' + 2*`trgaph' + (`trleft')
+    local brdrt "\clbrdrt\brdrw10\brdrs"
+    local brdrb "\clbrdrb\brdrw10\brdrs"
+    local emptycell "\pard\intbl\ql\cell"
+    local rtfdef "\cellx`ipos'"
+    local rtfdefbrdrt "`brdrt'\cellx`ipos'"
+    local rtfdefbrdrb "`brdrb'\cellx`ipos'"
+    local rtfrow "`emptycell'"
+    if `haslc2' {
+        if `lc2width'<=0 local lc2width 12
+        local lc2twips = `lc2width'*`factor'
+        local ipos = `ipos' + `lc2twips' + 2*`trgaph'
+        local rtfdef "`rtfdef'\cellx`ipos'"
+        local rtfdefbrdrt "`rtfdefbrdrt'`brdrt'\cellx`ipos'"
+        local rtfdefbrdrb "`rtfdefbrdrb'`brdrb'\cellx`ipos'"
+        local rtfrow "`rtfrow'`emptycell'"
+    }
+    local j 0
+    local nmwidth: list sizeof mwidth
+    foreach i of local srow {
+        local mwidthj: word `=1 + mod(`j++',`nmwidth')' of `mwidth'
+        if `mwidthj'<=0 local mwidthj 12
+        local mtwips = `mwidthj'*`factor'
+        local ipos = `ipos' + `mtwips' + 2*`trgaph'
+        if `i' & "`sdetach'"=="" local ipos = `ipos' + `stwips'
+        local rtfdef "`rtfdef'\cellx`ipos'"
+        local rtfdefbrdrt "`rtfdefbrdrt'`brdrt'\cellx`ipos'"
+        local rtfdefbrdrb "`rtfdefbrdrb'`brdrb'\cellx`ipos'"
+        local rtfrow "`rtfrow'`emptycell'"
+        if `i' & "`sdetach'"!="" {
+            local ipos = `ipos' + `stwips' + 2*`trgaph'
+            local rtfdef "`rtfdef'\cellx`ipos'"
+            local rtfdefbrdrt "`rtfdefbrdrt'`brdrt'\cellx`ipos'"
+            local rtfdefbrdrb "`rtfdefbrdrb'`brdrb'\cellx`ipos'"
+            local rtfrow "`rtfrow'`emptycell'"
+        }
+    }
+    c_local rtfrowdef "`rtfdef'"
+    c_local rtfrowdefbrdrt "`rtfdefbrdrt'"
+    c_local rtfrowdefbrdrb "`rtfdefbrdrb'"
+    c_local rtfemptyrow "`rtfdef'`rtfrow'"
+end
+
+prog ParseRtfcmdNum
+    args str cmd default
+    local pos = index(`"`str'"', `"\\`cmd'"')
+    if `pos' {
+        local pos = `pos' + strlen(`"`cmd'"') + 1
+        local digit = substr(`"`str'"',`pos',1)
+        if `"`digit'"'=="-" {
+            local value "`digit'"
+            local digit = substr(`"`str'"',`++pos',1)
+        }
+        while real(`"`digit'"')<. {
+            local value "`value'`digit'"
+            local digit = substr(`"`str'"',`++pos',1)
+        }
+    }
+    local value = real(`"`value'"')
+    if `value'>=. local value = `default'
+    c_local `cmd' `"`value'"'
+end
+
+prog ParseLabCol2
+    syntax [anything(equalok)] [ , Title(str asis) Width(numlist max=1 int >=0) ]
+    c_local labcol2 `"`macval(anything)'"'
+    c_local labcol2title `"`macval(title)'"'
+    c_local labcol2width `"`width'"'
+end
+
+prog MakeMMDdef
+    args varw labcol2 labcol2w modelw starsrow stardetachon starw
+    if "`varw'"=="0"     | "`varw'"==""     local varw 1
+    if "`labcol2w'"=="0" | "`labcol2w'"=="" local labcol2w 1
+    if "`modelw'"=="0"   | "`modelw'"==""   local modelw 1
+    if "`starw'"=="0"    | "`starw'"==""    local starw 1
+    local varw      = max(1,`varw')
+    local labcol2w  = max(1,`labcol2w'-2)
+    if "`stardetachon'"=="1" local starw = max(1,`starw'-2)
+    else                     local starw = max(1,`starw')
+
+    local mmddef `"| `:di _dup(`varw') "-"'"'
+    if "`labcol2'"=="1" {
+        local mmddef `"`mmddef' | :`:di _dup(`labcol2w') "-"':"'
+    }
+    local nmodelw: list sizeof modelw
+    local c 0
+    foreach col of local starsrow {
+        local modelwj: word `=1+mod(`c++',`nmodelw')' of `modelw'
+        local modelwj = max(1,`modelwj'-2)
+        local mmddef `"`mmddef' | :`:di _dup(`modelwj') "-"'"'
+        if "`col'"=="1" {
+            if "`stardetachon'"=="1" {
+                local mmddef `"`mmddef': | :"'
+            }
+            local mmddef `"`mmddef'`:di _dup(`starw') "-"'"'
+        }
+        local mmddef `"`mmddef':"'
+    }
+    c_local value `"`mmddef' |"'
+end
+
+program MatrixMode, rclass
+    capt syntax [, Matrix(str asis) e(str asis) r(str asis) rename(str asis) ]
+    if _rc | `"`matrix'`e'`r'"'=="" {
+        c_local matrixmode 0
+        exit
+    }
+    if ((`"`matrix'"'!="") + (`"`e'"'!="") + (`"`r'"'!=""))>1 {
+        di as err "only one of matrix(), e(), or r() allowed"
+        exit 198
+    }
+    ParseMatrixOpt `matrix'`e'`r'
+    if `"`e'"'!="" {
+        local name "e(`name')"
+    }
+    else if `"`r'"'!="" {
+        local name "r(`name')"
+    }
+    confirm matrix `name'
+    tempname bc
+    if "`transpose'"=="" {
+        mat `bc' = `name''
+    }
+    else {
+        mat `bc' = `name'
+    }
+    QuotedRowNames `bc'
+    local rnames `"`value'"'
+    local eqs: roweq `bc', q
+    mat `bc' = `bc''
+    local cols = colsof(`bc')
+    local cells
+    local space
+    gettoken fmti fmtrest : fmt, match(par)
+    gettoken rname rnames : rnames
+    gettoken eq eqs : eqs
+    forv i = 1/`cols' {
+        if `"`fmti'"'!="" {
+            local fmtopt `"f(`fmti') "'
+            gettoken fmti fmtrest : fmtrest, match(par)
+            if `"`fmti'"'=="" & `"`fmtrest'"'=="" { // recycle
+                gettoken fmti fmtrest : fmt, match(par)
+            }
+        }
+        else local fmtopt
+        if `"`eq'"'=="_" {
+            local lbl `"l(`"`rname'"')"'
+        }
+        else {
+            local lbl `"l(`"`eq':`rname'"')"'
+        }
+        local cells `"`cells'`space'c`i'(`fmtopt'`lbl')"'
+        local space " "
+        gettoken rname rnames : rnames
+        gettoken eq eqs : eqs
+    }
+    if `"`rename'"'!="" {
+        local rename : subinstr local rename "," "", all
+        RenameCoefs `bc' `"`rename'"'
+    }
+    return local names      "`name'"
+    return scalar nmodels   = 1
+    return scalar ccols     = `cols'
+    return matrix coefs     = `bc'
+    c_local matrixmode      1
+    c_local cells           (`cells')
+end
+
+program ParseMatrixOpt
+    syntax name [, Fmt(str asis) Transpose ]
+    c_local name `"`namelist'"'
+    c_local fmt `"`fmt'"'
+    c_local transpose `"`transpose'"'
+end
diff --git a/Modules/ado/plus/e/estout.hlp b/Modules/ado/plus/e/estout.hlp
new file mode 100644
index 0000000..eba9543
--- /dev/null
+++ b/Modules/ado/plus/e/estout.hlp
@@ -0,0 +1,2438 @@
+{smcl}
+{* 09mar2009}{...}
+{cmd:help estout}{right:also see: {helpb esttab}, {helpb eststo}, {helpb estadd}, {helpb estpost}}
+{right: {browse "http://repec.org/bocode/e/estout"}}
+{hline}
+
+{title:Title}
+
+{p 4 4 2}{hi:estout} {hline 2} Making regression tables from stored estimates
+
+
+{title:Table of contents}
+
+    {help estout##syn:Syntax}
+    {help estout##des:Description}
+    {help estout##opt:Options}
+    {help estout##exa:Examples}
+    {help estout##rem:Remarks}
+    {help estout##ret:Saved results}
+    {help estout##ref:Backmatter}
+
+{marker syn}
+{title:Syntax}
+
+{p 8 15 2}
+{cmd:estout} [ {help estout##what:{it:what}} ]
+    [ {cmd:using} {it:filename} ]
+    [ {cmd:,} {help estout##opt0:{it:options}} ]
+
+{marker what}
+    {it:what}{col 30}description
+    {hline 70}
+    {it:namelist}{col 30}{...}
+tabulate stored estimation sets; {it:namelist} is
+{col 32}a name, a list of names, or {cmd:_all}; the {cmd:*} and
+{col 32}{cmd:?} wildcards are allowed; a name may also be
+{col 32}{cmd:.}, meaning the current (active) estimates
+
+    {cmdab:m:atrix:(}{it:name}[{cmd:,} {it:subopts}]{cmd:)}{col 30}{...}
+tabulate matrix {it:name}
+    {cmd:e(}{it:name}[{cmd:,} {it:subopts}]{cmd:)}{col 30}{...}
+tabulate matrix {cmd:e(}{it:name}{cmd:)}
+    {cmd:r(}{it:name}[{cmd:,} {it:subopts}]{cmd:)}{col 30}{...}
+tabulate matrix {cmd:r(}{it:name}{cmd:)}
+      {it:subopts}:
+        {helpb estout##mfmt:{ul:f}mt}{cmd:(}{it:fmtlist}{cmd:)}{col 30}{...}
+set the display format(s)
+        {helpb estout##mtranspose:{ul:t}ranspose}{col 30}{...}
+tabulate transposed matrix
+    {hline 70}
+
+{marker opt0}
+    {it:options}{col 38}description
+    {hline 70}
+    Parameter statistics
+      {helpb estout##cells:{ul:c}ells}{cmd:(}{it:elements and subopts}{cmd:)}{col 38}{...}
+contents of the table cells, where
+{col 40}an {it:element}'s {it:subopts} are in paren-
+{col 40}theses, i.e. {it:element}[{cmd:(}{it:subopts}{cmd:)}]
+          {it:elements}:
+          {cmd:b}{col 38}raw coefficient (point estimate)
+          {cmd:se}{col 38}standard error
+          {cmd:var}{col 38}variance
+          {cmd:t}{col 38}t or z statistic
+          {cmd:z}{col 38}t or z statistic (synonym for {cmd:t})
+          {cmd:p}{col 38}p-value
+          {cmd:ci}{col 38}confidence interval
+          {cmd:ci_l}{col 38}lower bound of confidence interval
+          {cmd:ci_u}{col 38}upper bound of confidence interval
+          {cmd:_star}{col 38}"significance stars"
+          {cmd:_sign}{col 38}sign of point estimate
+          {cmd:_sigsign}{col 38}sign and significance of estimate
+          {cmd:.}{col 38}null element (empty cell)
+          {cmd:&}{col 38}combine elements in single cell
+          {it:myel}{col 38}results from {cmd:e(}{it:myel}{cmd:)}
+          {it:myel}{cmd:[}{it:#}{cmd:]}{col 38}results from row {it:#} in {cmd:e(}{it:myel}{cmd:)}
+          {it:myel}{cmd:[}{it:rowname}{cmd:]}{col 38}results from row {it:rowname} in {cmd:e(}{it:myel}{cmd:)}
+
+
+          {it:subopts} (for each {it:element},
+                except for {cmd:.} and {cmd:&}):
+          [{cmdab:no:}]{helpb estout##cstar:{ul:s}tar}{col 38}{...}
+attach "significance stars"
+          {helpb estout##cfmt:{ul:f}mt}{cmd:(}{it:{help estout##fmt:fmt}} [{it:{help estout##fmt:fmt}} ...]{cmd:)}{col 38}{...}
+set the display format(s)
+          {helpb estout##clabel:{ul:l}abel}{cmd:(}{it:string}{cmd:)}{col 38}{...}
+define a label for {it:element}
+          {helpb estout##cpar:par}[{cmd:(}{it:l} {it:r}{cmd:)}] | {cmd:nopar}{col 38}{...}
+place results in parentheses
+          {helpb estout##cvacant:{ul:v}acant}{cmd:(}{it:string}{cmd:)}{col 38}{...}
+print {it:string} if coefficient is absent
+          {helpb estout##cdrop:{ul:d}rop}{cmd:(}{it:droplist}{cmd:)}{col 38}{...}
+drop certain individual results
+          {helpb estout##ckeep:{ul:k}eep}{cmd:(}{it:keeplist}{cmd:)}{col 38}{...}
+keep certain individual results
+          {helpb estout##cpattern:{ul:pat}tern}{cmd:(}{it:pattern}{cmd:)}{col 38}{...}
+model selection
+          {helpb estout##cpvalue:{ul:pval}ue}{cmd:(}{it:name}{cmd:)}{col 38}{...}
+set p-values for {cmd:star} (default: {cmd:p})
+          [{cmd:no}]{helpb estout##cabs:abs}{col 38}{...}
+use absolute t-statistics
+          [{cmdab:no:}]{helpb estout##ctranspose:{ul:t}ranspose}{col 38}{...}
+transpose {cmd:e(}{it:myel}{cmd:)} for tabulation
+
+      {helpb estout##drop:{ul:d}rop}{cmd:(}{it:droplist}{cmd:)}{col 38}{...}
+drop individual coefficients
+      {helpb estout##keep:{ul:k}eep}{cmd:(}{it:keeplist}{cmd:)}{col 38}{...}
+keep individual coefficients
+      {helpb estout##order:{ul:o}rder}{cmd:(}{it:orderlist}{cmd:)}{col 38}{...}
+change order of coefficients
+      {helpb estout##indicate:{ul:i}ndicate}{cmd:(}{it:groups} [{cmd:,} {it:subopt}]{cmd:)}{col 38}{...}
+indicate presence of parameters
+        {it:subopt}: {cmdab:l:abels(}{it:yes} {it:no}{cmd:)}{col 38}{...}
+redefine "Yes" and "No" labels
+      {helpb estout##rename:{ul:ren}ame}{cmd:(}{it:old} {it:new} [{it:old} {it:new} ...]{cmd:)}{col 38}{...}
+rename individual coefficients
+      {helpb estout##equations:{ul:eq}uations}{cmd:(}{it:eqmatchlist}{cmd:)}{col 38}{...}
+match the models' equations
+      {helpb estout##eform:eform}[{cmd:(}{it:pattern}{cmd:)}] | {cmd:noeform}{col 38}{...}
+report exponentiated coefficients
+      {helpb estout##transform:{ul:tr}ansform}{cmd:(}{it:list} [{cmd:,} {it:subopt}]{cmd:)}{col 38}{...}
+apply transformations to coefficients
+        {it:subopt}: {cmdab:p:attern:(}{it:pattern}{cmd:)}]{cmd:)}{col 38}{...}
+select models
+      {helpb estout##margin:{ul:m}argin}[{cmd:(}{cmd:u}|{cmd:c}|{cmd:p}{cmd:)}] | {cmdab:nom:argin}{col 38}{...}
+report marginal effects/elasticities
+      {helpb estout##discrete:{ul:di}screte}{cmd:(}{it:string}{cmd:)} | {cmdab:nodi:screte}{col 38}{...}
+identify 0/1 variables (if {cmd:margin})
+      {helpb estout##meqs:{ul:meq}s}{cmd:(}{it:eq_list}{cmd:)}{col 38}{...}
+select equations for marginal effects
+      {helpb estout##dropped:dropped}[{cmd:(}{it:string}{cmd:)}] | {cmd:nodropped}{col 38}{...}
+indicate null coefficients as dropped
+      {helpb estout##level:level}{cmd:(}{it:#}{cmd:)}{col 38}{...}
+set level for confidence intervals
+
+    Summary statistics
+      {helpb estout##stats:{ul:s}tats}{cmd:(}{it:scalarlist}[{cmd:,} {it:subopts}]{cmd:)}{col 38}{...}
+display summary statistics at the
+{col 38}bottom of the table
+        {it:subopts}:
+          {helpb estout##statsfmt:{ul:f}mt}{cmd:(}{it:{help estout##fmt:fmt}} [{it:{help estout##fmt:fmt}} ...]{cmd:)}{col 38}{...}
+set the display formats
+          {helpb estout##statslabels:{ul:l}abels}{cmd:(}{it:strlist}[{cmd:,} {col 38}{...}
+label the summary statistics
+             {it:{help estout##lsub0:label_subopts}}]{cmd:)}
+          {helpb estout##statsstar:{ul:s}tar}[{cmd:(}{it:sca'list}{cmd:)}] | {cmdab:nos:tar}{col 38}{...}
+denote the model significance
+          {helpb estout##statslayout:{ul:lay}out}{cmd:(}{it:array}{cmd:)}{col 38}{...}
+arrange the summary statistics
+          {helpb estout##statspchar:{ul:pc}har}{cmd:(}{it:symbol}{cmd:)}{col 38}{...}
+placeholder in {cmdab:layout()}; default is {cmd:@}
+
+    Significance stars
+      {helpb estout##starlevels:{ul:starl}evels}{cmd:(}{it:levelslist}{cmd:)}{col 38}{...}
+define thresholds and symbols,
+{col 40}where '{it:levelslist}' is '{it:symbol} {it:#}
+{col 40}[{it:symbol} {it:#} ...]' with {it:#} in (0,1] and
+{col 40}listed in descending order
+      {helpb estout##stardrop:{ul:stard}rop}{cmd:(}{it:droplist}{cmd:)}{col 38}{...}
+drop stars for individual coefs
+      {helpb estout##starkeep:{ul:stark}eep}{cmd:(}{it:keeplist}{cmd:)}{col 38}{...}
+keep stars for individual coefs
+      [{cmdab:no:}]{helpb estout##stardetach:{ul:stard}etach}{col 38}{...}
+display the stars in their own column
+
+    Layout
+      {helpb estout##varwidth:{ul:var}width}{cmd:(}{it:#}{cmd:)}{col 38}{...}
+set width of the table's left stub
+      {helpb estout##modelwidth:{ul:model}width}{cmd:(}{it:#} [{it:#} ...]{cmd:)}{col 38}{...}
+set width of the results columns
+      [{cmdab:no:}]{helpb estout##unstack:{ul:uns}tack}{col 38}{...}
+place equations from multiple-
+{col 40}equation models in separate columns
+      {helpb estout##begin:{ul:beg}in}{cmd:(}{it:string}{cmd:)}{col 38}{...}
+specify the beginning of the rows
+      {helpb estout##delimiter:{ul:del}imiter}{cmd:(}{it:string}{cmd:)}{col 38}{...}
+specify the column delimiter
+      {helpb estout##end:end}{cmd:(}{it:string}{cmd:)}{col 38}{...}
+specify the ending of the table rows
+      {helpb estout##incelldel:{ul:incell}delimiter}{cmd:(}{it:string}{cmd:)}{col 38}{...}
+specify delimiter within cell
+      {helpb estout##dmarker:{ul:dm}arker}{cmd:(}{it:string}{cmd:)}{col 38}{...}
+define the decimal marker
+      {helpb estout##msign:{ul:ms}ign}{cmd:(}{it:string}{cmd:)}{col 38}{...}
+define the minus sign
+      [{cmd:no}]{helpb estout##lz:lz}{col 38}{...}
+print the leading zero of fixed
+{col 40}format numbers in (-1,1)
+      {helpb estout##extracols:{ul:extra}cols}{cmd:(}{it:numlist}{cmd:)}{col 38}{...}
+add empty column to the table
+      {helpb estout##substitute:{ul:sub}stitute}{cmd:(}{it:subst}{cmd:)}{col 38}{...}
+apply end-of-pipe substitutions, where
+{col 40}'{it:subst}' is '{it:from} {it:to} [{it:from} {it:to} ... ]'
+
+    Labeling
+      [{cmdab:no:}]{helpb estout##label:{ul:l}abel}{col 38}{...}
+make use of variable labels
+      [{cmdab:no:}]{helpb estout##abbrev:{ul:ab}brev}{col 38}{...}
+abbreviate long names and labels
+      [{cmdab:no:}]{helpb estout##wrap:wrap}{col 38}{...}
+wrap long labels (if space permits)
+      {helpb estout##title:{ul:ti}tle}{cmd:(}{it:string}{cmd:)}{col 38}{...}
+specify a title for the table
+      {helpb estout##note:note}{cmd:(}{it:string}{cmd:)}{col 38}{...}
+specify a note for the table
+      [{cmdab:no:}]{helpb estout##legend:{ul:le}gend}{col 38}{...}
+add a significance symbols legend
+      {helpb estout##prehead:{ul:preh}ead}{cmd:(}{it:strlist}{cmd:)}{col 38}{...}
+add text before the table heading
+      {helpb estout##prehead:{ul:posth}ead}{cmd:(}{it:strlist}{cmd:)}{col 38}{...}
+add text after the table heading
+      {helpb estout##prehead:{ul:pref}oot}{cmd:(}{it:strlist}{cmd:)}{col 38}{...}
+add text before the table footer
+      {helpb estout##prehead:{ul:postf}oot}{cmd:(}{it:strlist}{cmd:)}{col 38}{...}
+add text after the table footer
+      {helpb estout##hlinechar:{ul:hl}inechar}{cmd:(}{it:string}{cmd:)}{col 38}{...}
+specify look of {cmd:@hline}
+      {helpb estout##varlabels:{ul:varl}abels}{cmd:(}{it:matchlist}[{cmd:,} {it:sub.}]{cmd:)} {col 38}{...}
+relabel the parameters
+        {it:subopts}:
+          {cmdab:bl:ist:(}{it:matchlist}{cmd:)}{col 38}{...}
+assign prefixes to certain rows
+          {cmdab:el:ist:(}{it:matchlist}{cmd:)}{col 38}{...}
+assign suffixes to certain rows
+          {it:{help estout##lsub0:label_subopts}}
+      {helpb estout##labcol2:{ul:labcol}2}{cmd:(}{it:strlist}[{cmd:,} {it:subopts}]{cmd:)} {col 38}{...}
+add a second labeling column
+        {it:subopts}:
+          {cmdab:t:itle:(}{it:strlist}{cmd:)}{col 38}{...}
+add column title in table header
+          {cmdab:w:idth:(}{it:#}{cmd:)}{col 38}{...}
+set width of column
+      {helpb estout##refcat:{ul:ref}cat}{cmd:(}{it:matchlist}[{cmd:,} {it:subopts}]{cmd:)} {col 38}{...}
+add reference category information
+        {it:subopts}:
+          {cmdab:l:abel:(}{it:string}{cmd:)} | {cmdab:nol:abel}{col 38}{...}
+redefine the "ref." label
+          {cmdab:b:elow}{col 38}{...}
+change positioning of refcat
+      {helpb estout##mlabels:{ul:ml}abels}{cmd:(}{it:strlist}[{cmd:,} {it:subopts}]{cmd:)}{col 38}{...}
+label the models
+        {it:subopts}:
+          [{cmdab:no:}]{cmdab:dep:vars}{col 38}{...}
+use the name/label of the dependent
+{col 42}variable as model label
+          [{cmdab:no:}]{cmdab:ti:tles}{col 38}{...}
+use estimates title as model label
+          [{cmdab:no:}]{cmdab:num:bers}{col 38}{...}
+number models labels consecutively
+          {it:{help estout##lsub0:label_subopts}}
+      {helpb estout##collabels:{ul:coll}abels}{cmd:(}{it:strlist}[{cmd:,} {col 38}{...}
+label the columns within models
+        {it:{help estout##lsub0:label_subopts}}]{cmd:)}
+      {helpb estout##eqlabels:{ul:eql}abels}{cmd:(}{it:strlist}[{cmd:,} {it:subopts}]{cmd:)}{col 38}{...}
+label the equations
+        {it:subopts}:
+          [{cmdab:no:}]{cmdab:m:erge}{col 38}{...}
+merge equation and parameter labels
+          {it:{help estout##lsub0:label_subopts}}
+      {helpb estout##mgroups:{ul:mgr}oups}{cmd:(}{it:strlist}[{cmd:,} {it:subopts}]{cmd:)}{col 38}{...}
+define and label groups of models
+        {it:subopts}:
+          {cmdab:pat:tern:(}{it:pattern}{cmd:)}{col 38}{...}
+define the grouping of the models
+          {it:{help estout##lsub0:label_subopts}}
+      {helpb estout##numbers:{ul:num}bers}[{cmd:(}{it:l} {it:r}{cmd:)}] | {cmdab:nonum:bers}{col 38}{...}
+add a row containing model numbers
+
+    Output
+      [{cmdab:no:}]{helpb estout##replace:{ul:r}eplace}{col 38}{...}
+overwrite an existing file
+      [{cmdab:no:}]{helpb estout##append:{ul:a}ppend}{col 38}{...}
+append the output to an existing file
+      [{cmdab:no:}]{helpb estout##type:{ul:ty}pe}{col 38}{...}
+print the table in the results window
+      [{cmd:no}]{helpb estout##showtabs:showtabs}{col 38}{...}
+display tabs as {cmd:}s
+      {helpb estout##topfile:{ul:top}file}{cmd:(}{it:filename}{cmd:)}{col 38}{...}
+insert file contents above table
+      {helpb estout##topfile:{ul:bot}tomfile}{cmd:(}{it:filename}{cmd:)}{col 38}{...}
+insert file contents below table
+
+    Defaults
+      {helpb estout##style:{ul:sty}le}{cmd:(}{it:style}{cmd:)}{col 38}{...}
+specify a style for the output table
+
+        {it:styles}:
+          {cmd:smcl}{col 38}SMCL formatted table (screen default)
+          {cmd:tab}{col 38}tab delimited table (export default)
+          {cmd:fixed}{col 38}fixed format table
+          {cmd:tex}{col 38}table for use with LaTeX
+          {cmd:html}{col 38}table for use with HTML
+          {it:mystyle}{col 38}user defined addition
+    {hline 70}
+
+{marker lsub0}
+    {it:{help estout##lsub:label_subopts}}{col 38}Description
+    {hline 70}
+      [{cmd:no}]{cmd:none}{col 38}{...}
+suppress the labels
+      {cmdab:p:refix:(}{it:string}{cmd:)}{col 38}{...}
+add a common prefix
+      {cmdab:s:uffix:(}{it:string}{cmd:)}{col 38}{...}
+add a common suffix
+      {cmdab:b:egin:(}{it:strlist}{cmd:)}{col 38}{...}
+add an overall prefix
+      [{cmdab:no:}]{cmdab:f:irst}{col 38}{...}
+print the first occurrence of {cmd:begin()}
+      {cmdab:e:nd:(}{it:strlist}{cmd:)}{col 38}{...}
+add an overall suffix
+      [{cmdab:no:}]{cmdab:l:ast}{col 38}{...}
+print the last occurrence of {cmd:end()}
+      {cmdab:r:eplace}{col 38}{...}
+replace global {cmd:begin()}/{cmd:end()}
+      [{cmd:no}]{cmd:span}{col 38}{...}
+span columns if appropriate
+      {cmdab:er:epeat:(}{it:string}{cmd:)}{col 38}{...}
+add a "span" suffix
+      {cmd:lhs(}{it:string}{cmd:)}{col 38}{...}
+label the table's left stub
+    {hline 70}
+
+{marker des}
+{title:Description}
+
+{p 4 4 2}
+    {cmd:estout} assembles a table of coefficients, "significance
+    stars", summary statistics, standard errors, t- or z-statistics, p-values,
+    confidence intervals, and other statistics for one or more models
+    previously fitted and stored by {helpb estimates store} or {helpb eststo}.
+    It then displays the table in Stata's results window or writes it to a text
+    file specified by {cmd:using}. The default is to use {help smcl:SMCL}
+    formatting tags and horizontal lines to structure the table. However,
+    if {cmd:using} is specified, a tab-delimited table without lines
+    is produced.
+
+{p 4 4 2}
+    {it:namelist} provides the names of the stored estimation
+    sets to be tabulated. You may use the {cmd:*} and {cmd:?} wildcards in
+    {it:namelist}. The results estimated last may be indicated by a period
+    ({cmd:.}), even if they have not yet been stored. If no model is
+    specified, {cmd:estout} tabulates the estimation sets stored by
+    {cmd:eststo} (see help {helpb eststo}) or, if no such estimates are
+    present, the currently active estimates (i.e. the model fit last).
+    {cmd:estout} may be used after any estimation command that
+    returns its results in {cmd:e()}.
+
+{p 4 4 2}
+    See the {help estout##intro:Introduction} in the
+    {help estout##exa:Examples} section for an introduction on using
+    {cmd:estout}. See help {helpb estimates} for general information
+    about managing estimation results. Furthermore, see help {helpb eststo}
+    for an alternative to the {cmd:estimates store} command.
+
+{p 4 4 2}
+    The default for {cmd:estout} is to produce a plain
+    table containing point estimates. Producing a fully formatted
+    end-product may involve specifying many options. However, note that a
+    simple-to-use {cmd:estout} wrapper producing pre-formatted
+    publication style tables is available as {helpb esttab}. Furthermore,
+    use {helpb estadd} to make additional results available for
+    tabulation (such as the standardized coefficients or the means and
+    standard deviations of the regressors) and {helpb estpost} to
+    tabulate results from non-estimation commands such as {helpb summarize}
+    or {helpb tabulate}.
+
+{p 4 4 2}
+    {cmd:estout} can also be used to tabulate the contents of a Stata
+    matrix (see help {helpb matrix}). Type {cmd:estout marix(}{it:name}{cmd:)},
+    where {it:name} is the name of the matrix, instead of providing a
+    {it:namelist} of stored estimation sets. See the
+    {help estout##ex7:examples} below. Alternatively, you may also specify
+    {cmd:e(}{it:name}{cmd:)} or {cmd:r(}{it:name}{cmd:)} to tabulate an
+    {cmd:e()}-matrix or an {cmd:r()}-matrix. The {cmd:cells()} option is
+    disabled if tabulating a matrix.
+
+{p 4 4 2}
+    Programms similar to {cmd:estout} include {cmd:outreg} by John Luke
+    Gallup, {cmd:outreg2} by Roy Wada, {cmd:modltbl} by John H. Tyler,
+    {cmd:mktab} by Nicholas Winter, {cmd:outtex} by Antoine Terracol, or
+    {cmd:est2tex} by Marc Muendler. Also see Newson (2003) for a very
+    appealing approach.
+
+{marker opt}
+{title:Options}
+
+    Contents
+
+        {help estout##par:Parameter statistics}
+        {help estout##sum:Summary statistics}
+        {help estout##sig:Significance stars}
+        {help estout##lay:Layout}
+        {help estout##lab:Labeling}
+        {help estout##out:Output}
+        {help estout##def:Defaults}
+        {it:{help estout##lsub:label_subopts}}
+        {it:{help estout##msub:matrix_subopts}}
+{marker par}
+{dlgtab:Parameter statistics}
+{marker cells}
+{p 4 8 2}
+    {cmd:cells(}{it:array}{cmd:)} specifies the parameter statistics to be
+    reported and how they are to be arranged. The default is for cells to
+    report point estimates only, i.e. {cmd:cells(b)}. {cmd:cells(none)} may
+    be used to completely suppress the printing of parameter statistics.
+    Alternatively, {cmd:cells(b se)} would result in the reporting of point
+    estimates and standard errors. Multiple statistics are placed in
+    separate rows beneath one another by default. However, elements of
+    {it:array} that are listed in quotes or in parentheses, e.g.
+    {bind:{cmd:"b se"}} or {bind:{cmd:`"b se"'}} or {bind:{cmd:(b se)}},
+    are placed beside one another. For example, {bind:{cmd:cells("b p" se)}}
+    or, equivalently, {bind:{cmd:cells((b p) se)}} would produce a
+    table with point estimates and p-values beside one another in first row
+    and standard errors in the second row beneath the point estimates.
+
+{p 8 8 2}
+    The parameter statistics available are {cmd:b} (point estimates),
+    {cmd:se} (standard errors), {cmd:var} (variance), {cmd:t}
+    (t/z-statistics), {cmd:z} (synonym for {cmd:t}), {cmd:p} (p-values), and
+    {cmd:ci} (confidence
+    intervals; to display the lower and upper bounds in separate cells use
+    {cmd:ci_l} and {cmd:ci_u}). Any additional parameter statistics
+    included in the {cmd:e()}-returns for the models can be tabulated as
+    well. If, for example, {cmd:e(beta)} contains the standardized
+    coefficients, type {cmd:cells(beta)} to tabulate them (use
+    {helpb estadd} to add statistics such as the standardized coefficients to the
+    {cmd:e()}-returns of a model). The syntax {it:name}{cmd:[}{it:#}{cmd:]}
+    or {it:name}{cmd:[}{it:rowname}{cmd:]} can be used to refer to specific
+    rows in {cmd:e(}{it:name}{cmd:)}. For example, type {cmd:cell(ci_bc[1] ci_bc[2])}
+    or {cmd:cell(ci_bc[ll] ci_bc[ul])} to tabulate the lower and upper
+    bounds of the bias-corrected confidence intervals after {helpb bootstrap}.
+    The default is to report the results from the first row.
+    Also see the {cmd:eform} and {cmd:margin} options for more information
+    on the kinds of statistics that can be displayed.
+
+{p 8 8 2}
+    Further available elements in {it:array} are {cmd:_star},
+    {cmd:_sign}, and {cmd:_sigsign}. {cmd:_star} causes stars denoting the
+    significance of the coefficients to be printed (* for p<.05, ** for p<.01,
+    and *** for p<.001; customizable via the {cmd:starlevels()} option below).
+    {cmd:_star} places the significance stars in their own cells. See the
+    {cmd:star} suboption below if you want to attach the stars to another
+    element. {cmd:_sign} prints the signs of the coefficients ("+", "-", or
+    "0"). {cmd:_sigsign}, a combination of {cmd:_star} and {cmd:_sign}, repeats
+    the signs of the coefficients where the number of repetitions reflects the
+    level of significance (non-significant coefficients are left empty;
+    however, you may set the first level to 1 in the {cmd:starlevels()}
+    option).
+
+{p 8 8 2}
+    Finally, {cmd:.} and {cmd:&} may be used in {it:array}. {cmd:.} inserts a
+    "null" element. Use this to add empty cells. For example,
+    {cmd:cells("b p" ". se")} would produce a table with point estimates in the
+    first column and p-values and standard errors beneath one another in the
+    second column. {cmd:&} is used to combine elements in the same cell. Use
+    the {helpb estout##incelldel:incelldelimiter()} option to specify the text to
+    be printed between the combined elements (the default is to print a
+    single blank). For example, in HTML, use {cmd:cell(b & se)} and
+    {cmd:incelldelimiter(
)} to include point estimates and standard + errors in a single cell and insert a line break between them. + +{p 8 8 2} + A set of suboptions may be specified in parentheses for each + element named in {it:array} (except for {cmd:.} and {cmd:&}). For example, + to add significance stars to the coefficients and place the standard errors + in parentheses, specify {bind:{cmd:cells(b(star) se(par))}}. The following + suboptions are available. Use: + {p_end} +{marker cstar} +{p 12 16 2} + {cmd:star} to specify that stars denoting the significance of the + coefficients be attached to the statistic: {cmd:*} for p<.05, + {cmd:**} for p<.01, and {cmd:***} for p<.001. The symbols and the + values for the thresholds and the number of levels are fully customizable + (see the {help estout##sig:Significance stars} options). + {p_end} +{marker cfmt} +{p 12 16 2} + {cmd:fmt(}{it:{help estout##fmt:fmt}} [{it:{help estout##fmt:fmt}} ...]{cmd:)} + to specify the display format(s) of a statistic. It + defaults to {cmd:%9.0g} or the format for the first statistic in + {cmd:cells()}. If only one format is specified, it is used for all + occurrences of the statistic. For example, type + +{p 20 20 2} + {inp:. estout} {it:...}{inp:, cells("b(fmt(3)) t(fmt(2))")} + +{p 16 16 2} + to print coefficients and t-values beside one another using three + decimal places for coefficients and two decimal places for + t-values. If multiple formats are specified, the first format is + used for the first regressor in the estimates table, the second + format for the second regressor, and so on. The last format is used + for the remaining regressors if the number of regressors in the + table is greater than the number of specified formats. For + instance, type + +{p 20 20 2} + {inp:. estout} {it:...}{inp:, cells(b(fmt(3 4 2)))} + +{p 16 16 2} + to use three decimal places for the first coefficient, four decimal + places for the second, and two decimal places for all remaining + coefficients. Note that, regardless of the display format chosen, + leading and trailing blanks are removed from the numbers. White + space can be added by specifying a {cmd:modelwidth()} (see the + {help estout##lay:Layout} options). {it:{help estout##fmt:fmt}} may + be any of Stata's numerical display formats, e.g., {cmd:%9.0g} or + {cmd:%8.2f}, an integer {it:#} such as {cmd:1} or {cmd:3} to use a + fixed format with {it:#} decimal places, or {cmd:a}{it:#} such as + {cmd:a1} or {cmd:a3} to use {cmd:estout}'s adaptive display format + (see {help estout##fmt:Numerical formats} in the + {help estout##rem:Remarks} section for details). + {p_end} +{marker clabel} +{p 12 16 2} + {cmd:label(}{it:string}{cmd:)} to specify a label to appear in the + column heading. The default is the name of the statistic. + {p_end} +{marker cpar} +{p 12 16 2} + {cmd:par}[{cmd:(}{it:l} {it:r}{cmd:)}] to specify that the + statistic in question be placed in parentheses. It is also possible + to specify custom "parentheses". For example, {cmd:se(par({ }))} + would display the standard errors in curly brackets. Or, + {cmd:se(par(`"="("' `")""'))} will write parentheses in a way that + Excel can recognize. For {cmd:ci} the syntax is: + +{p 20 20 2} + {cmd:ci(par}[{cmd:(}{it:l} {it:m} {it:r}{cmd:)}]{cmd:)} + {p_end} +{marker cvacant} +{p 12 16 2} + {cmd:vacant(}{it:string}{cmd:)} to print {it:string} if a + coefficient is not in the model. The default is to leave such cells + empty. + {p_end} +{marker cdrop} +{p 12 16 2} + {cmd:drop(}{it:droplist} [{cmd:, relax}]{cmd:)} to cause certain + individual statistics to be dropped. For example, specifying + {cmd:t(drop(_cons))} suppresses the t-statistics for the constants. + {it:droplist} is specified as in the global + {helpb estout##drop:drop()} option (see below). + {p_end} +{marker ckeep} +{p 12 16 2} + {cmd:keep(}{it:keeplist} [{cmd:, relax}]{cmd:)} to cause certain + individual statistics to be kept. For example, the specification + {cmd:t(keep(mpg))} would display the t-statistics exclusively for + the variable {cmd:mpg}. {it:keeplist} is specified analogous to + {it:droplist} in {helpb estout##drop:drop()} (see below). + {p_end} +{marker cpattern} +{p 12 16 2} + {cmd:pattern(}{it:pattern}{cmd:)} to designate a pattern of models + for which the statistics are to be reported, where the {it:pattern} + consists of zeros and ones. A {cmd:1} indicates that the statistic + be printed; {cmd:0} indicates that it be suppressed. For example + {cmd:beta(pattern(1 0 1))} would result in {cmd:beta} being + reported for the first and third models, but not for the second. + {p_end} +{marker cpvalue} +{p 12 16 2} + {cmd:pvalue(}{it:name}{cmd:)} to specify the p-values used to + determine the significance stars (see {cmd:star} above). The + default is {cmd:pvalue(p)}, indicating that the standard p-values + are to be used (i.e. the p-values computed form the coefficients + vector and the variance matrix). Alternatively, specify + {cmd:pvalue(}{it:mypvalue}{cmd:)}, in which case the significance + stars will be determined from the values in + {cmd:e(}{it:mypvalue}{cmd:)}. Values outside [0,1] will be ignored. + {p_end} +{marker cabs} +{p 12 16 2} + {cmd:abs} to specify that absolute t-statistics be used instead of + regular t-statistics (relevant only if used with {cmd:t()}). + {p_end} +{marker ctranspose} +{p 12 16 2} + {cmd:transpose} to specify that {cmd:e(}{it:myel}{cmd:)} be transposed + for tabulation. + {p_end} +{marker drop} +{p 4 8 2} + {cmd:drop(}{it:droplist} [{cmd:, relax}]{cmd:)} identifies the coefficients + to be dropped from the table. A {it:droplist} comprises one or more + specifications, separated by white space. A specification can be either a + parameter name (e.g. {cmd:price}), an equation name followed by a colon + (e.g. {cmd:mean:}), or a full name (e.g. {cmd:mean:price}). You may use the + {cmd:*} and {cmd:?} wildcards in equation names and parameter names. Be sure + to refer to the matched equation names, and not to the original equation names + in the models, when using the {cmd:equations()} option to match equations. + Specify the {cmd:relax} suboption to allow {it:droplist} to contain elements + for which no match can be found. + {p_end} +{marker keep} +{p 4 8 2} + {cmd:keep(}{it:keeplist} [{cmd:, relax}]{cmd:)} selects the coefficients to + be included in the table. {it:keeplist} is specified analogous to {it:droplist} in + {helpb estout##drop:drop()} (see above). Note that {cmd:keep()} does {it:not} change the + the order of the coefficients. Use {cmd:order()} to change the order + of coefficients. + {p_end} +{marker order} +{p 4 8 2} + {cmd:order(}{it:orderlist}{cmd:)} changes the order of the + coefficients and equations within the table. {it:orderlist} is specified + analogous to {it:droplist} in {cmd:drop()} (see above). Reordering of + coefficients is performed equation by equation, unless equations are + explicitly specified. Coefficients and equations that do not appear in + {it:orderlist} are placed last (in their original order). Extra table rows + are inserted for elements in {it:orderlist} that are not found in the + table. + {p_end} +{marker indicate} +{p 4 8 2} + {cmd:indicate(}{it:groups} [{cmd:,} {cmdab:l:abels(}{it:yes} + {it:no}{cmd:)}]{cmd:)} indicates for each model (or, if {cmd:unstack} + is specified, for each equation) the presence of certain groups of + coefficients at the end of the table body. The syntax for {it:groups} + is + + {it:group} [ {it:group} {it:...} ] + +{p 8 8 2} + where a {it:group} is + + [{it:name} = ] {it:list} + +{p 8 8 2} + and {it:list} is a list of coefficient specifications as defined in + {cmd:drop()} above. The single groups should be enclosed in quotes + unless there is only one group and "{it:name} =" is specified. If + "{it:name} =" is omitted, the first element of {it:list} is used as + name. Note that {it:name} may contain spaces. + +{p 8 8 2} + For example, if some of the models contain a set of year + dummies, say {cmd:y1 y2 y3}, specify + + {com}estout{txt} {it:...}{com}, indicate(year effects = y1 y2 y3){txt} + +{p 8 8 2} + to drop the dummies from the table and add a "year effects" row + containing "Yes" for models in which {it:at least one} of the dummies + is present, and "No" for the other models. + +{p 8 8 2} + Use the {cmd:labels()} suboption to redefine the indication labels to + be printed in the table. The default is {cmd:labels(Yes No)}. Use + quotes if the labels include spaces, + e.g. {bind:{cmd:labels("in model" "not in model")}}. + {p_end} +{marker rename} +{p 4 8 2} + {cmd:rename(}{it:matchlist}{cmd:)} changes the names of individual + coefficients, where {it:matchlist} is + +{p 12 12 2} + {it:oldname} {it:newname} [{it:oldname} {it:newname} ...] + +{p 8 8 2} + {it:oldname} can be a parameter name (e.g. {cmd:price}) or a full + name including an equation specification (e.g. {cmd:mean:price}) + (abbreviation and wildcards not allowed); {it:newname} is a name without + equation specification and must not already occur in a model's equation. + {cmd:rename()} is applied before matching the models and equations and can + therefore be used to merge different coefficients across models (or + equations if {cmd:unstack} is specified) into a single table row. See the + {cmd:varlabels()} option if you are interested in relabeling coefficients + after matching models and equations. + {p_end} +{marker equations} +{p 4 8 2} + {cmd:equations(}{it:matchlist}{cmd:)} specifies how the models' equations are + to be matched. The default is to match all first equations into one equation + (named {cmd:main}, if the equations have different names) and match the remaining + equations by name. Specify {cmd:equations("")} to match all equations by + name. Alternatively, specify {it:matchlist}, which has the syntax + + {it:term} [{cmd:,} {it:term} ... ] + +{p 8 8 2} + where {it:term} is + + [{it:eqname} {cmd:=}] {it:#}{cmd::}{it:#}...{cmd::}{it:#}{col 50}(syntax 1) + + [{it:eqname} {cmd:=}] {it:#}{col 50}(syntax 2) + +{p 8 8 2} + In syntax 1, each {it:#} is a number or a period ({cmd:.}). If a number, it + specifies the position of the equation in the corresponding model; + {cmd:1:3:1} would indicate that equation 1 in the first model matches equation + 3 in the second, which matches equation 1 in the third. A period indicates + that there is no corresponding equation in the model; {cmd:1:.:1} indicates + that equation 1 in the first matches equation 1 in the third. + +{p 8 8 2} + In syntax 2, you specify just one number, say, {cmd:1} or {cmd:2}, and that + is shorthand for {cmd:1:1}...{cmd::1} or {cmd:2:2}...{cmd::2}, meaning that + equation 1 matches across all models specified or that equation 2 matches + across all models specified. + +{p 8 8 2} + {it:eqname} is used to name the matched equations. If it is suppressed, + a name such as {cmd:#1} or {cmd:#2} etc. is used, depending on the position + of the {it:term}. For example, {cmd:equations(1)} + indicates that all first equations are to be matched into one equation + named {cmd:#1}. All equations not matched by position are + matched by name. + {p_end} +{marker eform} +{p 4 8 2} + {cmd:eform}[{cmd:(}{it:pattern}{cmd:)}] displays the coefficient table in + exponentiated form. The exponent of {cmd:b} is displayed in lieu of the + untransformed coefficient; standard errors and confidence intervals are + transformed as well. Specify a {it:pattern} if the exponentiation is to be + applied only for certain models. For instance, {cmd:eform(1 0 1)} would + transform the statistics for Models 1 and 3, but not for Model 2. Note that, + unlike {cmd:regress} and {cmd:estimates table}, {cmd:estout} in + eform-mode does not suppress the display of the intercept. To drop the + intercept in eform-mode, specify {cmd:drop(_cons)}. Note: {cmd:eform} is + implemented via the {cmd:transform()} option. If both options are specified, + {cmd:transform()} takes precedence over {cmd:eform}. + {p_end} +{marker transform} +{p 4 8 2} + {cmd:transform(}{it:list} [, {cmd:pattern(}{it:pattern}{cmd:)}]{cmd:)} + displays transformed coefficients, standard errors and + confidence intervals. {it:list} may be + + {it:fx} {it:dfx} + +{p 8 8 2} + where {it:fx} is the transformation function and {it:dfx} is its first + derivative. {it:fx} is applied to coefficients and confidence + intervals, that is, {it:fx}({cmd:b}) and {it:fx}({cmd:ci}) is displayed + instead of {cmd:b} and {cmd:ci}. {it:dfx} is used to delta transform + standard errors, i.e. {cmd:se}*{it:dfx}({cmd:b}) is displayed instead + of {cmd:se}. Use {cmd:@} as a placeholder for the function's argument + in {it:fx} and {it:dfx}. For example, type + + {com}estout{txt} {it:...}{com}, transform(exp(@) exp(@)){txt} + +{p 8 8 2} + to report exponentiated results (this is equivalent to specifying + the {cmd:eform} option). + +{p 8 8 2} + Alternatively, {it:list} may be specified as + +{p 12 12 2} + {it:coefs} {it:fx} {it:dfx} [ {it:...} [{it:coefs}] {it:fx} {it:dfx} ] + +{p 8 8 2} + where {it:coefs} identifies the coefficients + to be transformed. Syntax for {it:coefs} is as explained above in the + description of the {cmd:drop()} option (however, include {it:coefs} + in quotes if it contains multiple elements). Say, a model has + two equations, {cmd:price} and {cmd:select}, and you want to + exponentiate the {cmd:price} equation but not the {cmd:select} + equation. You could then type + + {com}estout{txt} {it:...}{com}, transform(price: exp(@) exp(@)){txt} + +{p 8 8 2} + Note that omitting {it:coef} in the last transformation + specification causes the last transformation to be applied to + all remaining coefficients. + +{p 8 8 2} + Specify the {cmd:pattern()} suboption if the transformations are to be + applied only for certain models. For instance, {cmd:pattern(1 0 1)} would + apply the transformation to Models 1 and 3, but not Model 2. + {p_end} +{marker margin} +{p 4 8 2} + {cmd:margin}[{cmd:(}{cmd:u}|{cmd:c}|{cmd:p}{cmd:)}] indicates that the + marginal effects or elasticities be reported instead of the raw + coefficients. This option has an effect only if {cmd:mfx} has been + applied to a model before its results were stored (see help {helpb mfx}) or if a + {cmd:dprobit} (see help {helpb probit}), {cmd:truncreg,marginal} + (help {helpb truncreg}), or {cmd:dtobit} (Cong 2000) model is estimated. One + of the parameters {cmd:u}, {cmd:c}, or {cmd:p}, corresponding to the + unconditional, conditional, and probability marginal effects, respectively, + is required for {cmd:dtobit}. Note that the standard errors, confidence + intervals, t-statistics, and p-values are transformed as well. + +{p 8 8 2} + Using the {cmd:margin} option with multiple-equation models can be tricky. + The marginal effects of variables that are used in several equations are + printed repeatedly for each equation because the equations per se are + meaningless for {cmd:mfx}. To display the effects for certain equations only, + specify the {cmd:meqs()} option. Alternatively, use the {cmd:keep()} and + {cmd:drop()} options to eliminate redundant rows. The {cmd:equations()} + option might also be of help here. + {p_end} +{marker discrete} +{p 4 8 2} + {cmd:discrete(}{it:string}{cmd:)} may be used to override the default symbol and + explanatory text used to identify dummy variables when reporting marginal + effects. The first token in {it:string} is used as the symbol. The default is: + +{p 12 12 2} + {inp:discrete(" (d)" for discrete change of dummy variable from 0 to 1)} + +{p 8 8 2} + To display explanatory text, specify either the {cmd:legend} option or use + the {cmd:@discrete} variable (see the + {help estout##atvar:Remarks on using @-variables}). + +{p 8 8 2} + Use {cmd:nodiscrete} to disable the identification of dummy variables as + such. The default is to indicate the dummy variables unless they have been + interpreted as continuous variables in all of the models for which results are + reported (for {cmd:dprobit} and {cmd:dtobit}, however, dummy variables will + always be listed as discrete variables unless {cmd:nodiscrete} is specified). + {p_end} +{marker meqs} +{p 4 8 2} + {cmd:meqs(}{it:eq_list}{cmd:)} specifies that marginals be printed only for the + equations in {it:eq_list}. Specifying this option does not affect how the + marginals are calculated. An {it:eq_list} comprises one or more equation + names (without colons) separated by white space. If you use the + {cmd:equations()} option to match equations, be sure to refer to the matched + equation names and not to the original equation names in the models. + {p_end} +{marker dropped} +{p 4 8 2} + {cmd:dropped}[{cmd:(}{it:string}{cmd:)}] causes null coefficients + (coefficients for which {cmd:e(b)} and {cmd:e(V)} is zero) to be indicated + as dropped. {it:string} specifies the text to be printed in place of + the estimates. The default text is "(dropped)". + {p_end} +{marker level} +{p 4 8 2} + {cmd:level(}{it:#}{cmd:)} assigns the confidence level, in percent, for + the confidence intervals of the coefficients (see help {help level}). + +{marker sum} +{dlgtab:Summary statistics} +{marker stats} +{p 4 8 2} + {cmd:stats(}{it:scalarlist}[{cmd:,} {it:stats_subopts}]{cmd:)} specifies + one or more scalar statistics - separated by white space - to be displayed + at the bottom of the table. The {it:scalarlist} may contain numeric + {cmd:e()}-scalars such as, e.g., {cmd:N}, {cmd:r2}, or {cmd:chi2}, but also + string {cmd:e()}-macros such as {cmd:cmd} or {cmd:depvar}. In + addition, the following statistics are available: + +{p 12 24 2} + {cmd:aic}{space 5}Akaike's information criterion{p_end} +{p 12 24 2} + {cmd:bic}{space 5}Schwarz's information criterion{p_end} +{p 12 24 2} + {cmd:rank}{space 4}rank of {cmd:e(V)}, i.e. the number of free + parameters in model{p_end} +{p 12 24 2} + {cmd:p}{space 7}the p-value of the model (overall model significance) + +{p 8 8 2} + See {bf:[R] estimates table} for details on the {cmd:aic} and {cmd:bic} statistics. + The rules for the determination of {cmd:p} are as follows (note that although + the procedure outlined below is appropriate for most models, there might be + some models for which it is not): + +{p 12 15 2} + 1) p-value provided: If the {cmd:e(p)} scalar is provided by the + estimation command, it will be interpreted as indicating the p-value + of the model. + +{p 12 15 2} + 2) F test: If {cmd:e(p)} is not provided, {cmd:estout} checks for the + presence of the {cmd:e(df_m)}, {cmd:e(df_r)}, and {cmd:e(F)} + scalars and, if they are present, the p-value of the model will be + calculated as {cmd:Ftail(df_m,df_r,F)}. This p-value corresponds to + the standard overall F test of linear regression. + +{p 12 15 2} + 3) chi2 test: Otherwise, if neither {cmd:e(p)} nor {cmd:e(F)} is + provided, {cmd:estout} checks for the presence of {cmd:e(df_m)} and + {cmd:e(chi2)} and, if they are present, calculates the p-value as + {cmd:chi2tail(df_m,chi2)}. This p-value corresponds to the + Likelihood-Ratio or Wald chi2 test. + +{p 12 15 2} + 4) If neither {cmd:e(p)}, {cmd:e(F)}, nor {cmd:e(chi2)} + is available, no p-value will be reported. + +{p 8 8 2} + Type {cmd:ereturn list} after estimating a model to see a list of + the returned {cmd:e()}-scalars and macros (see help {helpb ereturn}). Use + the {helpb estadd} command to add extra statistics and + other information to the {cmd:e()}-returns. + +{p 8 8 2} + The following {it:stats_subopts} are available. Use: + {p_end} +{marker statsfmt} +{p 12 16 2} + {cmd:fmt(}{it:{help estout##fmt:fmt}} [{it:{help estout##fmt:fmt}} {it:...}]{cmd:)} + to set the display formats for the scalars statistics in {it:scalarlist}. + {it:{help estout##fmt:fmt}} may be any of Stata's numerical display + formats, e.g., {cmd:%9.0g} or {cmd:%8.2f}, an integer {it:#} such as + {cmd:1} or {cmd:3} to use a fixed format with {it:#} decimal places, or + {cmd:a}{it:#} such as {cmd:a1} or {cmd:a3} to use {cmd:estout}'s adaptive + display format (see {help estout##fmt:Numerical formats} in the {help + estout##rem:Remarks} section for details). For example, {cmd:fmt(3 0)} + would be suitable for {cmd:stats(r2_a N)}. Note that the last specified + format is used for the remaining scalars if the list of scalars is longer + than the list of formats. Thus, only one format needs to be specified if + all scalars are to be displayed in the same format. If no format is + specified, the default format is the display format of the coefficients. + {p_end} +{marker statslabels} +{p 12 16 2} + {cmd:labels(}{it:strlist}[{cmd:,} {it:{help estout##lsub:label_subopts}}]{cmd:)} + to specify labels for rows containing the scalar statistics. If + specified, the labels are used instead of the scalar names. For example: + +{p 20 20 2} + {inp:. estout} {it:...}{inp:, stats(r2_a N, labels("Adj. R-Square" "Number of Cases"))} + +{p 16 16 2} + Note that names like {cmd:r2_a} produce an error in LaTeX because the + underscore character has a special meaning in LaTeX (to print the + underscore in LaTeX, type {cmd:\_}). Use the {cmd:label()} suboption to + rename such statistics, e.g. {cmd:stats(r2_a, labels(r2\_a))}. An alternative + approach is to use {cmd:estout}'s {cmd:substitute()} option (see the + {help estout##lay:Layout} options). + {p_end} +{marker statsstar} +{p 12 16 2} + {cmd:star}[{cmd:(}{it:scalarlist}{cmd:)}] to specify that the overall + significance of the model be denoted by stars. The stars are attached to + the scalar statistics specified in {it:scalarlist}. If + {it:scalarlist} is omitted, the stars are attached to the first + reported scalar statistic. The printing of the stars is suppressed in + empty results cells (i.e. if the scalar statistic in question is missing + for a certain model). The determination of the model significance is + based on the p-value of the model (see above). + +{p 16 16 2} + Hint: It is possible to attach the stars to different scalar statistics + within the same table. For example, specify + {cmd:stats(,star(r2_a r2_p))} + when tabulating OLS estimates and, say, probit estimates. For + the OLS models, the F test will be carried out and the significance + stars will be attached to the {cmd:r2_a}; for the probit models, the + chi2 test will be used and the stars will appear next to the + {cmd:r2_p}. + {p_end} +{marker statslayout} +{p 12 16 2} + {cmd:layout(}{it:array}{cmd:)} to rearrange the summary statistics. The default + is to print the statistics in separate rows beneath one another (in + each model's first column). The syntax for {it:array} is + + <{it:row}> [ <{it:row}> ... ] + +{p 16 16 2} + where {it:row} is + + <{it:cell}> [ <{it:cell}> ... ] + +{p 16 16 2} + and {cmd:@} is used as a placeholder for the statistics, one + after another. Rows and cells that contain blanks + have to be embraced in quotes. For example, + + {com} ... stats(chi2 df_m N, layout("@ @" @)){txt} + +{p 16 16 2} + prints for each model in row 1/column 1 the chi-squared, in + row1/column 2 the degrees of freedom, and in row 2/column 1 the number of + observations. Cells may contain multiple statistics and text other than + the placeholder symbol is printed as is (provided the cells' statistics are part + of the model). For example, + + {com} ... stats(chi2 df_m N, layout(`""@ (@)""' @)){txt} + +{p 16 16 2} + prints a cell containing "chi2 (df_m)" in the first row and the + number of observations in the second row. Note that the number of columns + in the table only depends on the {cmd:cells()} option (see above) and not + on the {cmd:layout()} suboption. If, for example, the table has two columns + per model and you specify three columns of summary statistics, the summary statistics + in the third column are not printed. + {p_end} +{marker statspchar} +{p 12 16 2} + {cmd:pchar(}{it:symbol}{cmd:)} to specify the placeholder symbol + used in {cmdab:layout()}. The default placeholder is {cmd:@}. + +{marker sig} +{dlgtab:Significance stars} +{marker starlevels} +{p 4 8 2} + {cmd:starlevels(}{it:levelslist}{cmd:)} overrides the default thresholds and + symbols for "significance stars". For instance, + {bind:{cmd:starlevels(+ 0.10 * 0.05)}} + sets the following thresholds: {cmd:+} for p<.10 and {cmd:*} for + p<.05. Note that the thresholds must lie in the (0,1] interval and must be + specified in descending order. To, for example, denote insignificant + results, type {bind:{cmd:starlevels(* 1 "" 0.05)}}. + {p_end} +{marker stardrop} +{p 4 8 2} + {cmd:stardrop(}{it:droplist} [{cmd:, relax}]{cmd:)} + identifies the coefficients for which the significance stars be + suppressed. {it:droplist} is specified as in + {helpb estout##drop:drop()} (see above). + {p_end} +{marker starkeep} +{p 4 8 2} + {cmd:starkeep(}{it:keeplist} [{cmd:, relax}]{cmd:)} selects the coefficients + for which the significance stars, if requested, be printed. {it:keeplist} + is specified analogous to {it:droplist} in + {helpb estout##drop:drop()} (see above). + {p_end} +{marker stardetach} +{p 4 8 2} + {cmd:stardetach} specifies that a delimiter be placed between the statistics + and the significance stars (i.e. that the stars are to be displayed in their + own column). + +{marker lay} +{dlgtab:Layout} +{marker varwidth} +{p 4 8 2} + {cmd:varwidth(}{it:#}{cmd:)} specifies the number of characters used to display + the names (labels) of regressors and statistics (i.e. {cmd:varwidth} + specifies the width of the table's left stub). Long names (labels) are + abbreviated (depending on the {cmd:abbrev} option) and short or empty + cells are padded out with blanks to fit the width specified by the user. + {cmd:varwidth} set to 0 means that the names are not + abbreviated and no white space is added. Specifying low values may cause + misalignment. + {p_end} +{marker modelwidth} +{p 4 8 2} + {cmd:modelwidth(}{it:#} [{it:#} ...]{cmd:)} designates the number of characters + used to display the results columns. If a non-zero {cmd:modelwidth} is + specified, model names are abbreviated if necessary (depending on the + {cmd:abbrev} option) and short or empty results cells are padded out + with blanks. In contrast, {cmd:modelwidth} does not shorten or truncate + the display of the results themselves (coefficients, t-statistics, + summary statistics, etc.) although it may add blanks if needed. + {cmd:modelwidth} set to 0 means that the model names are not + abbreviated and no white space is added. Specifying low values may + cause misalignment. Specify a list of numbers in {cmd:modelwidth()} to + assign individual widths to the different results columns (the list is + recycled if there are more columns than numbers). + +{p 8 8 2} + The purpose of {cmd:modelwidth} is to be able to construct a fixed-format + table and thus make the raw table more readable. Be aware, however, that the + added blanks may cause problems with the conversion to a table in word + processors or spreadsheets. + {p_end} +{marker unstack} +{p 4 8 2} + {cmd:unstack} specifies that the individual equations from multiple-equation + models (e.g. {cmd:mlogit}, {cmd:reg3}, {cmd:heckman}) be placed in + separate columns. The default is to place the equations below one another in a + single column. Summary statistics will be reported for each equation if + {cmd:unstack} is specified and the estimation command is either {cmd:reg3}, + {cmd:sureg}, or {cmd:mvreg} (see help {helpb reg3}, help {helpb sureg}, + help {helpb mvreg}). + {p_end} +{marker begin} +{p 4 8 2} + {cmd:begin(}{it:string}{cmd:)} specifies a string to be printed at the + beginning of every table row. It is possible to + use special functions such as {cmd:_tab} or {cmd:_skip} in + {cmd:begin()}. For more information on using such functions, see the + description of the functions in help {helpb file}. + {p_end} +{marker delimiter} +{p 4 8 2} + {cmd:delimiter(}{it:string}{cmd:)} designates the delimiter used between the + table columns. See the {cmd:begin} option above for further details. + {p_end} +{marker end} +{p 4 8 2} + {cmd:end(}{it:string}{cmd:)} specifies a string to be printed at the end of + every table row. See the {cmd:begin} option above for further details. + {p_end} +{marker incelldel} +{p 4 8 2} + {cmd:incelldelimiter(}{it:string}{cmd:)} specifies text to be printed + between parameter statistics that have been combined in a single cell + by the {cmd:&} operator. See the {helpb estout##par:cells()} option + for details. The default string is a single blank. + {p_end} +{marker dmarker} +{p 4 8 2} + {cmd:dmarker(}{it:string}{cmd:)} specifies the form of the decimal marker. The + standard decimal symbol (a period or a comma, depending on the input provided + to {cmd:set dp}; see help {help format}) is replaced by {it:string}. + {p_end} +{marker msign} +{p 4 8 2} + {cmd:msign(}{it:string}{cmd:)} determines the form of the minus sign. The + standard minus sign ({cmd:-}) is replaced by {it:string}. + {p_end} +{marker lz} +{p 4 8 2} + {cmd:lz} specifies that the leading zero of fixed format numbers in the + interval (-1,1) be printed. This is the default. Use {cmd:nolz} to advise + {cmd:estout} to omit the leading zeros (that is, to print numbers like + {cmd:0.021} or {cmd:-0.33} as {cmd:.021} and {cmd:-.33}). + {p_end} +{marker extracols} +{p 4 8 2} + {cmd:extracols(}{it:{help numlist}}{cmd:)} inserts empty table columns + at the indicated positions. For example, {cmd:extracols(1)} adds + an extra column between the left stub of the table and the first + column. + {p_end} +{marker substitute} +{p 4 8 2} + {cmd:substitute(}{it:subst_list}{cmd:)} specifies that the substitutions + specified in {it:subst_list} be applied to the estimates table after it has + been created. Specify {it:subst_list} as a list of substitution pairs, that + is: + +{p 12 12 2} + {it:from} {it:to} [{it:from} {it:to} ...] + +{p 8 8 2} + For example, specify {cmd:substitute(_ \_)} to replace the underscore + character (as in {cmd:_cons} or {cmd:F_p}) with it's LaTeX equivalent {cmd:\_}. + +{marker lab} +{dlgtab:Labeling} +{marker label} +{p 4 8 2} + {cmd:label} specifies that variable labels be displayed instead of variable + names in the left stub of the table. + {p_end} +{marker abbrev} +{p 4 8 2} + {cmd:abbrev} specifies that long names and labels be abbreviated if + a {cmd:modelwidth()} and/or a {cmd:varwidth()} is specified. + {p_end} +{marker wrap} +{p 4 8 2} + {cmd:wrap} causes long variable labels to be wrapped if space permits and + a {cmd:varwidth()} is specified. The {cmd:wrap} option is only useful if + several parameter statistics are printed beneath one another and, therefore, + white space is available beneath the labels. + {p_end} +{marker title} +{p 4 8 2} + {cmd:title(}{it:string}{cmd:)} may be used to specify a title for the table. + The {it:string} is printed at the top of the table unless {cmd:prehead()}, + {cmd:posthead()}, {cmd:prefoot()}, or {cmd:postfoot()} is specified. In + the latter case, the variable {cmd:@title} can be used to insert the title. + {p_end} +{marker note} +{p 4 8 2} + {cmd:note(}{it:string}{cmd:)} may be used to specify a note for the table. + The {it:string} is printed at the bottom, of the table unless {cmd:prehead()}, + {cmd:posthead()}, {cmd:prefoot()}, or {cmd:postfoot()} is specified. In + the latter case, the variable {cmd:@note} can be used to insert the note. + {p_end} +{marker legend} +{p 4 8 2} + {cmd:legend} adds a legend explaining the significance symbols and + thresholds. + {p_end} +{marker prehead} +{p 4 8 2} + {cmd:prehead(}{it:strlist}{cmd:)}, {cmd:posthead(}{it:strlist}{cmd:)}, + {cmd:prefoot(}{it:strlist}{cmd:)}, and {cmd:postfoot(}{it:strlist}{cmd:)} may + be used to define lists of text lines to appear before and after the table + heading or the table footer. For example, the specification + +{p 12 12 2} + {inp:. estout} {it:...}{inp:, prehead("\S_DATE \S_TIME" "")} + +{p 8 8 2} + would add a line containing the current date and time followed by + an empty line before the table. Various substitution functions can be used + as part of the text lines specified in {it:strlist} (see the + {help estout##atvar:Remarks on using @-variables}). For example, + {cmd:@hline} plots a horizontal "line" (series of dashes, by default; see + the {cmd:hlinechar()} option) or {cmd:@M} inserts the number of models + in the table. {cmd:@M} could be used in a LaTeX table heading + as follows: + +{p 12 12 2} + {inp:. estout} {it:...}{inp:, prehead(\begin{tabular}{l*{@M}{r}})} + {p_end} +{marker hlinechar} +{p 4 8 2} + {cmd:hlinechar(}{it:string}{cmd:)} specifies the character(s) to be + used in {cmd:@hline}. The default is {cmd:hlinechar(-)}, resulting in a + dashed line. To produce a solid line, specify {cmd:hlinechar(`=char(151)')} + (Windows only; other systems may use other codes). + {p_end} +{marker varlabels} +{p 4 8 2} + {cmd:varlabels(}{it:matchlist}[{cmd:,} {it:suboptions}]{cmd:)} may be used to + relabel the regressors from the models, where {it:matchlist} is + +{p 12 12 2} + {it:name} {it:label} [{it:name} {it:label} ...] + +{p 8 8 2} + A {it:name} is a parameter name (e.g. {cmd:price}) or a full name + (e.g. {cmd:mean:price}) (abbreviation and wildcards + not allowed). For example, specify {cmd:varlabels(_cons Constant)} to replace + each occurrence of {cmd:_cons} with {cmd:Constant}. (Note that, in LaTeX, + the underscore character produces an error unless it is specified as + {cmd:\_}. Thus, names such as {cmd:_cons} should always be changed if + the estimates table is to be used with LaTeX. The {cmd:substitute()} may also be + helpful; see the {help estout##lay:Layout} options.) The {it:suboptions} are: + +{p 12 16 2} + {cmd:blist(}{it:matchlist}{cmd:)} to assign specific prefixes to + certain rows in the table body. Specify the {it:matchlist} as pairs of + regressors and prefixes, that is: + +{p 20 20 2} + {it:name} {it:prefix} [{it:name} {it:prefix} ...] + +{p 16 16 2} + A {it:name} is a parameter name (e.g. {cmd:price}), an equation name + followed by a colon (e.g. {cmd:mean:}), or a full name + (e.g. {cmd:mean:price}) (abbreviation and wildcards + not allowed). Note that equation names cannot be used if the + {cmd:unstack} option is specified. + +{p 12 16 2} + {cmd:elist(}{it:matchlist}{cmd:)} to assign specific suffixes to + certain rows in the table body (see the analogous {cmd:blist()} option + above). This option may, for example, be useful for separating + thematic blocks of variables by + adding vertical space at the end of each block. A LaTeX example: + +{p 20 20 2} + {inp:. estout} {it:...}{inp:, varlabels(,elist(price \addlinespace mpg \addlinespace))} + +{p 16 16 2} + (the macro {cmd:\addlinespace} is provided by the + {cmd:booktabs} package in LaTeX) + +{p 12 16 2} + {it:{help estout##lsub:label_subopts}}, which are + explained in their own section. + {p_end} +{marker labcol2} +{p 4 8 2} + {cmd:labcol2(}{it:strlist}[{cmd:,} {it:suboptions}]{cmd:)} adds a second column + containing additional labels for the coefficients and summary statistics. Labels + containing spaces should be embraced in double quotes ({bind:{cmd:"}{it:label 1}{cmd:"}} + {bind:{cmd:"}{it:label 2}{cmd:"}} etc.). An example would be to add a column + indicating the hypothesized directions of effects, e.g., + + {com}. estout {txt}{it:...}{com}, labcol2(+ - +/- + 0){txt} + +{p 8 8 2} + The {it:suboptions} are: + +{p 12 16 2} + {cmd:title(}{it:strlist}{cmd:)} to add text in the table header above + the column. Use double quotes to break the title into several + rows (given there are multiple header rows), i.e. specify {it:strlist} + as {bind:{cmd:"}{it:line 1}{cmd:"}} {bind:{cmd:"}{it:line 2}{cmd:"}} etc. + +{p 12 16 2} + {cmd:width(}{it:#}{cmd:)} to set the width, in number of characters, of the + column. The default is the value of {cmd:modelwidth()}. + {p_end} +{marker refcat} +{p 4 8 2} + {cmd:refcat(}{it:matchlist}[{cmd:,} {it:suboptions}]{cmd:)} may be used to + insert a row containing information on the reference category + of a categorical variable in the model. {it:matchlist} is + +{p 12 12 2} + {it:name} {it:refcat} [{it:name} {it:refcat} ...] + +{p 8 8 2} + A {it:name} is a parameter name (e.g. {cmd:_Irep78_2}) + (abbreviation and wildcards not allowed). For + example, assume that you include the categorical variable {cmd:rep78} + ("Repair Record 1978" from the auto dataset) in some of your models + using {cmd:xi} (see help {helpb xi}). Since {cmd:rep78} has five + levels, 1 through 5, {cmd:xi} will create 4 dummy variables, + {cmd:_Irep78_2} through {cmd:_Irep78_5}. You can now type + +{p 12 12 2} + {inp:. estout} {it:...}{inp:, refcat(_Irep78_2 _Irep78_1)} + +{p 8 8 2} + to add a table row containing "_Irep78_1" in the left stub and + "ref." in each column in which the {cmd:_Irep78_2} + dummy appears. The {it:suboptions} are: + +{p 12 16 2} + {cmd:label(}{it:string}{cmd:)} to specify the label that is printed + in the table columns. The default is {cmd:label(ref.)}. Type {cmd:nolabel} + to suppress the default label. + +{p 12 16 2} + {cmd:below} to position the reference category row below the specified + coefficient's row. The default is above. For example, if the 5th + category of {cmd:rep78} is used as reference category, i.e. if + {cmd:_Irep78_1} through {cmd:_Irep78_4} are included in the models, + you might want to type {cmd:refcat(_Irep78_4 _Irep78_5, below)}. + {p_end} +{marker mlabels} +{p 4 8 2} + {cmd:mlabels(}{it:strlist}[{cmd:,} {it:suboptions}]{cmd:)} determines the + model captions printed in the table heading. The default is to use the names of + the stored estimation sets (or their titles, if the {cmd:label} option is + specified and titles are available). The {it:suboptions} for use with + {cmd:mlabels} are: + +{p 12 16 2} + {cmd:depvars} to specify that the name (or label) of the (first) dependent + variable of the model be used as model label. + +{p 12 16 2} + {cmd:titles} to specify that, if available, the title of the stored + estimation set be used as the model label. Note that the {cmd:label} option + implies {cmd:titles} (unless {cmd:notitles} is specified). {cmd:depvars} + takes precedence over {cmd:titles}. + +{p 12 16 2} + {cmd:numbers} to cause the model labels to be numbered consecutively. + +{p 12 16 2} + {it:{help estout##lsub:label_subopts}}, which are explained in their own section. + {p_end} +{marker collabels} +{p 4 8 2} + {cmd:collabels(}{it:strlist}[{cmd:,} {it:{help estout##lsub:label_subopts}}]{cmd:)} + specifies labels for the columns within models or equations. The + default is to compose a label from the names or labels of the + statistics printed in the cells of that column. The {it:label_subopts} + are explained in their own section below. + {p_end} +{marker eqlabels} +{p 4 8 2} + {cmd:eqlabels(}{it:strlist}[{cmd:,} {it:suboptions}]{cmd:)} + labels the equations. The default is to use the equation names as + stored by the estimation command, or to use the variable labels if the + equation names correspond to individual variables and the {cmd:label} + option is specified. The {it:suboptions} for use with {cmd:eqlabels} + are: + +{p 12 16 2} + {cmd:merge} to merge equation labels and parameter labels instead of + printing equation labels in separate rows. Equation and parameter labels + will be separated by ":" unless another delimiter is specified via the + {cmd:suffix()} suboption (see {it:{help estout##lsub:label_subopts}}). + {cmd:merge} has no effect if {cmd:unstack} is specified. + +{p 12 16 2} + {it:{help estout##lsub:label_subopts}}, which are explained in their own + section. Note that {bind:{cmd:eqlabels(none)}} causes {cmd:_cons} to be + replaced with the equation name or label, if {cmd:_cons} is the only + parameter in an equation. This is useful, e.g., for tabulating + {cmd:ologit} or {cmd:oprobit} results in Stata 9. Specify + {bind:{cmd:eqlabels("", none)}} to not replace {cmd:_cons}. + {p_end} +{marker mgroups} +{p 4 8 2} + {cmd:mgroups(}{it:strlist}[{cmd:,} {it:suboptions}]{cmd:)} may be used to + labels groups of (consecutive) models at the top of the table heading. The + labels are placed in the first physical column of the output for the group of + models to which they apply. The {it:suboptions} for use with {cmd:mgroups} + are: + +{p 12 16 2} + {cmd:pattern(}{it:pattern}{cmd:)} to establish how the models are to be grouped. + {it:pattern} should be a list of zeros and ones, with ones indicating the + start of a new group of models. For example, + +{p 20 20 2} + {inp:. estout} {it:...}{inp:, mgroups("Group 1" "Group 2", pattern(1 0 0 1 0))} + +{p 16 16 2} + would group Models 1, 2, and 3 together and then groups Models 4 and 5 + together as well. Note that the first group will always start with the first + model regardless of whether the first token of {it:pattern} is a one or a + zero. + +{p 12 16 2} + {it:{help estout##lsub:label_subopts}}, which are explained + in their own section. In + particular, the {cmd:span} suboption might be of interest here. + {p_end} +{marker numbers} +{p 4 8 2} + {cmd:numbers}[{cmd:(}{it:l} {it:r}{cmd:)}] adds a row to the table header + displaying consecutive model numbers. The default is to + enclose the numbers in parentheses, i.e. {cmd:(1)}, {cmd:(2)}, etc. + Alternatively, specify {it:l} and {it:r} to change the tokens on the + left and right of each number. For example, {cmd:numbers("" ")")} + would result in {cmd:1)}, {cmd:2)}, etc. + +{marker out} +{dlgtab:Output} +{marker replace} +{p 4 8 2} + {cmd:replace} permits {cmd:estout} to overwrite an existing file. + {p_end} +{marker append} +{p 4 8 2} + {cmd:append} specifies that the output be appended to an existing file. It + may be used even if the file does not yet exist. + {p_end} +{marker type} +{p 4 8 2} + {cmd:type} specifies that the assembled estimates table be printed in the + results window and the log file. This is the default unless {cmd:using} is + specified. Use {cmd:notype} to suppress the display of the table. + {p_end} +{marker showtabs} +{p 4 8 2} + {cmd:showtabs} requests that tabs be displayed as {cmd:}s in both the + results window and the log file instead of in expanded form. This option does + not affect how tabs are written to the text file specified by {cmd:using}. + {p_end} +{marker topfile} +{p 4 8 2} + {cmd:topfile(}{it:filename}{cmd:)} and + {cmd:bottomfile(}{it:filename}{cmd:)} may be used to insert text before + and after the table, where the text is imported from a file on disk. Note that + {cmd:substitute()} does not apply to text inserted by {cmd:topfile()} or + {cmdab:bottomfile()}. + +{marker def} +{dlgtab:Defaults} +{marker style} +{p 4 8 2} + {cmd:style(}{it:style}{cmd:)} specifies a "style" for the output + table. {cmdab:def:aults:(}{it:style}{cmd:)} is a synonym for + {cmd:style(}{it:style}{cmd:)}. A "style" is a named combination of options + that is saved in an auxiliary file called {cmd:estout_}{it:style}{cmd:.def}. + In addition, there are five internal styles called {cmd:smcl} + (default for screen display), {cmd:tab} (export default), {cmd:fixed}, + {cmd:tex}, and {cmd:html}. The {cmd:smcl} style is suitable for displaying + the table in Stata's results window and is the default unless + {cmd:using} is specified. It includes {help smcl:SMCL} formatting tags and + horizontal lines to structure the table. The particulars of the other styles are: + + settings {col 38}styles + {col 26}{cmd:tab}{col 34}{cmd:fixed}{col 42}{cmd:tex}{col 50}{cmd:html} + {hline 47} + {cmd:begin} {col 50}{cmd:} + {cmd:delimiter} {col 26}{cmd:_tab}{col 34}{cmd:" "}{col 42}{cmd:&}{col 50}{cmd:} + {cmd:end} {col 42}{cmd:\\}{col 50}{cmd:} + {cmd:varwidth} {col 26}{cmd:0}{col 34}{cmd:12/20}*{col 42}{cmd:12/20}*{col 50}{cmd:12/20}* + {cmd:modelwidth}{col 26}{cmd:0}{col 34}{cmd:12}{col 42}{cmd:12}{col 50}{cmd:12} + {cmd:abbrev} {col 26}off{col 34}on{col 42}off{col 50}off + (* if {cmd:label} is on) + +{p 8 8 2} + {cmd:tab} is the default export style (i.e. if {cmd:using} is specified). + +{p 8 8 2} + Note that explicitly specified options take precedence + over settings provided by a style. For example, if you type + + {com}. estout, delimiter("") style(tab){txt} + +{p 8 8 2} + then the column delimiter will be set to empty string since the + {cmd:delimiter()} option overwrites the default from the {cmd:tab} + style. Similarly, specifying + {cmd:noabbrev} will turn abbreviation off if using the {cmd:fixed} + style. + +{p 8 8 2} + See {help estout##defaults:Defaults files} in the + {help estout##rem:Remarks} section to make available your own style. + +{marker lsub} +{it:{dlgtab:label_subopts}} + +{p 4 4 2} +The following suboptions may be used within the {cmd:mgroups()}, +{cmd:mlabels()}, {cmd:collabels()}, {cmd:eqlabels()}, +{cmd:varlabels()}, and {cmd:stats(, labels())} options: + +{p 4 8 2} + {cmd:none} suppresses the printing of the labels or drops the + part of the table heading to which it applies. Note that instead of + typing {bind:{it:option}{cmd:(, none)}} you may simply specify + {it:option}{cmd:(none)}. + +{p 4 8 2} + {cmd:prefix(}{it:string}{cmd:)} specifies a common prefix to be added to each + label. + +{p 4 8 2} + {cmd:suffix(}{it:string}{cmd:)} specifies a common suffix to be added to each + label. + +{p 4 8 2} + {cmd:begin(}{it:strlist}{cmd:)} specifies a prefix to be printed at the + beginning of the part of the table to which it applies. If {cmd:begin} is + specified in {cmd:varlabels()} or {cmd:stats(,labels())}, the prefix will + be repeated for each regressor or summary statistic. + +{p 4 8 2} + {cmd:first} specifies that the first occurrence of the {cmd:begin()}-prefix in + {cmd:varlabels()} or {cmd:stats(,labels())} be printed. This + is the default. Use {cmd:nofirst} to suppress the first occurrence of the + prefix. In {cmd:varlabels()}, {cmd:nofirst} applies equation-wise, i.e., the first + {cmd:begin()}-prefix in each equation is suppressed (unless {cmd:unstack} is + specified). + +{p 4 8 2} + {cmd:end(}{it:strlist}{cmd:)} specifies a suffix to be printed at the end of the + part of the table to which it applies. If {cmd:end} is specified in + {cmd:varlabels()} or {cmd:stats(,labels())}, the suffix will be repeated + for each regressor or summary statistic. + +{p 4 8 2} + {cmd:last} specifies that the last occurrence of the {cmd:end()}-suffix in + {cmd:varlabels()} or {cmd:stats(,labels())} be printed. This + is the default. Use {cmd:nolast} to suppress the last occurrence of the + suffix. In {cmd:varlabels()}, {cmd:nolast} applies equation-wise, i.e., the last + {cmd:end()}-suffix in each equation is suppressed (unless {cmd:unstack} is + specified). + +{p 4 8 2} + {cmd:replace} causes the label suboption {cmd:begin()}-prefix and {cmd:end()}-suffix + to be used instead of the global {cmd:begin()} and {cmd:end()} strings. The default + is to print both. {cmd:replace} also applies to {cmd:blist()} and {cmd:elist()} + if specified in {cmd:varlabels()}. + +{p 4 8 2} + {cmd:span} causes labels to span columns, i.e. extends the labels across + several columns, if appropriate. This suboption is relevant only for the + {cmd:mgroups()}, {cmd:mlabels()}, {cmd:eqlabels()}, and + {cmd:collabels()} options. The {cmd:@span} string returns the number of + spanned columns if it is included in the label, prefix, or suffix. A LaTeX example: + +{p 8 8 2} + {inp:. estout} {it:...}{inp:, mlabels(, span prefix(\multicolumn{@span}{c}{) suffix(}))} + +{p 4 8 2} + {cmd:erepeat(}{it:string}{cmd:)} specifies a string that is repeated for each + group of spanned columns at the very end of the row if the {cmd:span} + suboption is specified. This suboption is relevant only for the + {cmd:mgroups()}, {cmd:mlabels()}, {cmd:eqlabels()}, and + {cmd:collabels()} options. If the {cmd:@span} string is included in + {it:string} it will be replaced by the range of columns spanned. A LaTeX example: + +{p 8 8 2} + {inp:. estout} {it:...}{inp:, mlabels(, span erepeat(\cline{@span}))} + +{p 4 8 2} + {cmd:lhs(}{it:string}{cmd:)} inserts {it:string} into the otherwise empty cell + in the left stub of the row of the table heading to which it applies. This + suboption is relevant only for the {cmd:mgroups()}, {cmd:mlabels()}, + {cmd:eqlabels()}, and {cmd:collabels()} options. + +{marker msub} +{it:{dlgtab:matrix_subopts}} + +{p 4 4 2} +The following suboptions may be applied within the {cmd:matrix()}, +{cmd:e()}, or {cmd:r()} argument used to tabulate a matrix: + {p_end} +{marker mfmt} +{p 4 8 2} + {cmd:fmt(}{it:fmtlist}{cmd:)} sets the display formats for the matrix. + {it:fmtlist} contains a list of format specifications, one for each + column of the matrix. {it:fmtlist} is recycled if it supplies less + specifications than there are columns in the matrix. A format + specification may be a single {it:{help estout##fmt:fmt}} such as, + e.g., {cmd:%9.0g} or {cmd:a3} (see {help estout##fmt:Numerical formats} + in the {help estout##rem:Remarks} section for details) to be applied to + all cells in the column. Alternatively, a format specification may be + a list of {it:{help estout##fmt:fmt}}s, enclosed in double quotes, to be + used for the cells in the column one by one. The last format in the + list is used for the remaining cells if the number of cells in the + column is greater than the number of formats in the list. Also see the + {help estout##ex7:examples} below. + {p_end} +{marker mtranspose} +{p 4 8 2} + {cmd:transpose} causes the matrix to be transposed for tabulation. + +{marker exa} +{title:Examples} + + Contents + {help estout##intro:Introduction} + {help estout##ex1:Publication style table} + {help estout##ex2:t-statistics for selected variables only} + {help estout##ex3:Summary statistics only} + {help estout##ex4:Table of descriptives} + {help estout##ex5:Unstack multiple equations} + {help estout##ex6:Marginal effects} + {help estout##ex7:Tabulating a matrix} + +{p 4 4 2} Please first read the {help estout##intro:Introduction}. The +other examples are more advanced and intended for users +already familiar with the basic features of +{cmd:estout}. Additional examples can be found in Jann (2005) and at +{browse "http://repec.org/bocode/e/estout"}. + +{marker intro} +{dlgtab:Introduction} + +{p 4 4 2} +The full syntax of {cmd:estout} is rather complex and is to be found +above. However, consider the following basic syntax, which +includes only the most important options: + +{p 8 15 2} +{cmd:estout} [ {it:namelist} ] [ {cmd:using} {it:filename} ] [ {cmd:,} + {cmdab:c:ells:(}{it:array}{cmd:)} + {cmdab:s:tats:(}{it:scalarlist}{cmd:)} + {cmdab:sty:le:(}{it:style}{cmd:)} + {it:more_options} + ] + +{p 4 4 2} +where {it:namelist} is a list of the names of stored estimation sets (the name +list can be entered as {cmd:*} to refer to all stored estimates). The +{cmd:cells()} and {cmd:stats()} options determine the primary contents of +the table. The {cmd:style()} option determines the basic formatting of the +table. + +{p 4 4 2}{ul:Basic usage} + +{p 4 4 2} +The general procedure for using {cmd:estout} is to first store several +models using the {cmd:estimates store} or the {helpb eststo} command and then apply +{cmd:estout} to display or save a table of the estimates. By default, +{cmd:estout} displays a plain table of the coefficients of the models and +uses {help SMCL} tags and horizontal lines to structure the table: + + {com}. sysuse auto + {txt}(1978 Automobile Data) + + {com}. replace price = price / 1000 + {txt}price was {res}int{txt} now {res}float + {txt}(74 real changes made) + + {com}. replace weight = weight / 1000 + {txt}weight was {res}int{txt} now {res}float + {txt}(74 real changes made) + + {com}. quietly regress price weight mpg + {txt} + {com}. estimates store m1, title(Model 1) + {txt} + {com}. generate forXmpg = foreign * mpg + {txt} + {com}. quietly regress price weight mpg forXmpg foreign + {txt} + {com}. estimates store m2, title(Model 2) + {txt} + {com}. estout m1 m2 + {res} + {txt}{hline 38} + {txt} m1 m2 + {txt} b b + {txt}{hline 38} + {txt}weight {res} 1.746559 4.613589{txt} + {txt}mpg {res} -.0495122 .2631875{txt} + {txt}forXmpg {res} -.3072165{txt} + {txt}foreign {res} 11.24033{txt} + {txt}_cons {res} 1.946068 -14.44958{txt} + {txt}{hline 38} + +{p 4 4 2}Alternatively, if {cmd:using} is specified, {cmd:estout} writes a +raw tab-delimited table (without SMCL tags and without lines) to the +indicated file ({cmd:*} is used in the following example to indicate that +all stored models be tabulated): + + {com}. estout * using example.txt + {txt}(output written to {browse `"example.txt"'}) + + {com}. type example.txt + {res} m1 m2 + b b + weight 1.746559 4.613589 + mpg -.0495122 .2631875 + forXmpg -.3072165 + foreign 11.24033 + _cons 1.946068 -14.44958 + {txt} +{p 4 4 2} The table looks messy in the Stata results window or the Stata +log because the columns are tab-separated (note that tab characters are not +preserved in the results window or the log). However, the table would look +tidy if "example.txt" were opened, for example, in a spreadsheet program. + +{p 4 4 2}{ul:Choosing a style} + +{p 4 4 2}{cmd:estout} has a {cmd:style()} option to set the basic format of +the table. The default style for screen display is the {cmd:smcl} style. +The default export style (i.e. if {cmd:using} is specified) is the +{cmd:tab} style. (See the examples above.) Other predefined styles are +{cmd:fixed}, {cmd:tex}, and {cmd:html}, but it is also possible to define +one's own styles (see {help estout##defaults:Defaults files} in the +{help estout##rem:Remarks} section). The {cmd:tex} style, for example, modifies +the output table for use with LaTeX's tabular environment: + + {com}. estout *, style(tex) varlabels(_cons \_cons) + {res} + & m1& m2\\ + & b& b\\ + weight & 1.746559& 4.613589\\ + mpg & -.0495122& .2631875\\ + forXmpg & & -.3072165\\ + foreign & & 11.24033\\ + \_cons & 1.946068& -14.44958\\ + {txt} +{p 4 4 2} +Note that {cmd:_cons} has been replaced by its LaTeX equivalent in the example above +using the {cmd:varlabels()} option (the underscore character produces an +error in LaTeX unless it is preceded by a backslash). For more +information on the {cmd:varlabels()} option, see {cmd:estout}'s +{help estout##lab:Labeling} options. + +{p 4 4 2}{ul:The cells option} + +{p 4 4 2} +Use the {cmd:cells()} option to specify the parameter statistics to be +tabulated and how they are to be arranged. The parameter statistics +available are {cmd:b} (point estimates; the default), {cmd:se} (standard +errors), {cmd:t} (t-/z-statistics), {cmd:p} (p-values), {cmd:ci} +(confidence intervals; to display the lower and upper bounds in separate +cells use {cmd:ci_l} and {cmd:ci_u}), as well as any additional +parameter statistics included in the {cmd:e()}-returns for the models +(see {cmd:estout}'s {help estout##par:Parameter Statistics} options). For +example, {cmd:cells(b se)} results +in the reporting of point estimates and standard errors: + + {com}. estout *, cells(b se) + {res} + {txt}{hline 38} + {txt} m1 m2 + {txt} b/se b/se + {txt}{hline 38} + {txt}weight {res} 1.746559 4.613589{txt} + {res} .6413538 .7254961{txt} + {txt}mpg {res} -.0495122 .2631875{txt} + {res} .086156 .1107961{txt} + {txt}forXmpg {res} -.3072165{txt} + {res} .1085307{txt} + {txt}foreign {res} 11.24033{txt} + {res} 2.751681{txt} + {txt}_cons {res} 1.946068 -14.44958{txt} + {res} 3.59705 4.42572{txt} + {txt}{hline 38} + +{p 4 4 2} +Multiple statistics are placed in separate rows beneath one another by +default as in the example above. However, elements that are listed in +quotes or in parentheses are placed beside one another. For +example, specifying {bind:{cmd:cells("b se t p")}} or, equivalently, +{bind:{cmd:cells((b se t p))}} produces the following table: + + {com}. estout m2, cells("b se t p") + {res} + {txt}{hline 64} + {txt} m2 + {txt} b se t p + {txt}{hline 64} + {txt}weight {res} 4.613589 .7254961 6.359219 1.89e-08{txt} + {txt}mpg {res} .2631875 .1107961 2.375421 .0203122{txt} + {txt}forXmpg {res} -.3072165 .1085307 -2.830687 .0060799{txt} + {txt}foreign {res} 11.24033 2.751681 4.084896 .0001171{txt} + {txt}_cons {res} -14.44958 4.42572 -3.26491 .0017061{txt} + {txt}{hline 64} + +{p 4 4 2} +The two approaches can be combined. For example, {cmd:cells("b p" se)} +would produce a table with point estimates and standard errors beneath one +another in the first column and p-values in the top row of the second +column for each model. + +{p 4 4 2} +Note that for each statistic named in the {cmd:cells()} option a set of +suboptions may be specified in parentheses. For example, in social sciences +it is common to report standard errors or t-statistics in parentheses beneath +the coefficients and to indicate the significance of individual +coefficients with stars. Furthermore, the results are rounded. Just such a +table can be created using the following procedure: + + {com}. estout *, cells(b(star fmt(3)) t(par fmt(2))) + {res} + {txt}{hline 44} + {txt} m1 m2 + {txt} b/t b/t + {txt}{hline 44} + {txt}weight {res} 1.747** 4.614***{txt} + {res} (2.72) (6.36) {txt} + {txt}mpg {res} -0.050 0.263* {txt} + {res} (-0.57) (2.38) {txt} + {txt}forXmpg {res} -0.307** {txt} + {res} (-2.83) {txt} + {txt}foreign {res} 11.240***{txt} + {res} (4.08) {txt} + {txt}_cons {res} 1.946 -14.450** {txt} + {res} (0.54) (-3.26) {txt} + {txt}{hline 44} + +{p 4 4 2} +The {cmd:estout} default is to display {cmd:*} for p<.05, +{cmd:**} for p<.01, and {cmd:***} for p<.001. However, note that +the significance thresholds and symbols are fully customizable (see {cmd:estout}'s +{help estout##sig:Significance stars} options). + +{p 4 4 2}{ul:The stats option} + +{p 4 4 2} +Finally, use the {cmd:stats()} option to specify scalar +statistics to be displayed for each model in the table footer. The +available scalar statistics are {cmd:aic} (Akaike's information criterion), +{cmd:bic} (Schwarz's information criterion), {cmd:rank} (the rank of +{cmd:e(V)}, i.e. the number of free parameters in model), {cmd:p} (the +p-value of the model), as well as any numeric or string scalars contained in the +{cmd:e()}-returns for the models (see +{cmd:estout}'s +{help estout##sum:Summary statistics} options). For example, specify +{cmd:stats(r2 bic N)} to add the R-squared, BIC, and the number of cases: + + {com}. estout *, stats(r2 bic N) + {res} + {txt}{hline 38} + {txt} m1 m2 + {txt} b b + {txt}{hline 38} + {txt}weight {res} 1.746559 4.613589{txt} + {txt}mpg {res} -.0495122 .2631875{txt} + {txt}forXmpg {res} -.3072165{txt} + {txt}foreign {res} 11.24033{txt} + {txt}_cons {res} 1.946068 -14.44958{txt} + {txt}{hline 38} + {txt}r2 {res} .2933891 .5516277{txt} + {txt}bic {res} 356.2918 331.2406{txt} + {txt}N {res} 74 74{txt} + {txt}{hline 38} +{marker ex1} +{dlgtab:Publication style table} + + {com}. label variable foreign "Foreign car type" + {txt} + {com}. label variable forXmpg "Foreign*Mileage" + {txt} + {com}. estout *, cells(b(star fmt(%9.3f)) se(par)) /// + > stats(r2_a N, fmt(%9.3f %9.0g) labels(R-squared)) /// + > legend label collabels(none) varlabels(_cons Constant) + {res} + {txt}{hline 52} + {txt} Model 1 Model 2 + {txt}{hline 52} + {txt}Weight (lbs.) {res} 1.747** 4.614***{txt} + {res} (0.641) (0.725) {txt} + {txt}Mileage (mpg) {res} -0.050 0.263* {txt} + {res} (0.086) (0.111) {txt} + {txt}Foreign*Mileage {res} -0.307** {txt} + {res} (0.109) {txt} + {txt}Foreign car type {res} 11.240***{txt} + {res} (2.752) {txt} + {txt}Constant {res} 1.946 -14.450** {txt} + {res} (3.597) (4.426) {txt} + {txt}{hline 52} + {txt}R-squared {res} 0.273 0.526 {txt} + {txt}N {res} 74 74 {txt} + {txt}{hline 52} + {txt}* p<0.05, ** p<0.01, *** p<0.001 +{marker ex2} +{dlgtab:t-statistics for selected variables only} + + {com}. estout *, cells(b(star) t(par keep(mpg))) + {res} + {txt}{hline 44} + {txt} m1 m2 + {txt} b/t b/t + {txt}{hline 44} + {txt}weight {res} 1.746559** 4.613589***{txt} + {txt}mpg {res} -.0495122 .2631875* {txt} + {res} (-.5746806) (2.375421) {txt} + {txt}forXmpg {res} -.3072165** {txt} + {txt}foreign {res} 11.24033***{txt} + {txt}_cons {res} 1.946068 -14.44958** {txt} + {txt}{hline 44} +{marker ex3} +{dlgtab:Summary statistics only} + + {com}. estout *, cells(none) stats(r2_a bic N, star) + {res} + {txt}{hline 44} + {txt} m1 m2 + {txt}{hline 44} + {txt}r2_a {res} .2734846*** .5256351***{txt} + {txt}bic {res} 356.2918 331.2406 {txt} + {txt}N {res} 74 74 {txt} + {txt}{hline 44} +{marker ex4} +{dlgtab:Table of descriptives} + + {com}. quietly generate x = uniform() + {txt} + {com}. quietly regress x price weight mpg foreign + {txt} + {com}. estadd mean + + {txt}added matrix: + e(mean) : {res}1 x 5 + {txt} + {com}. estadd sd, nobinary + + {txt}added matrix: + e(sd) : {res}1 x 5 + {txt} + {com}. estout, cells("mean sd") stats(N) mlabels(,none) drop(_cons) + {res} + {txt}{hline 38} + {txt} mean sd + {txt}{hline 38} + {txt}price {res} 6.165257 2.949496{txt} + {txt}weight {res} 3.019459 .7771936{txt} + {txt}mpg {res} 21.2973 5.785503{txt} + {txt}foreign {res} .2972973 {txt} + {txt}{hline 38} + {txt}N {res} 74 {txt} + {txt}{hline 38} +{marker ex5} +{dlgtab:Unstack multiple equations} + + {com}. quietly sureg (price foreign weight length) /// + > (mpg displ = foreign weight) + {txt} + {com}. estout, cells(b t(par)) stats(r2 chi2 p) unstack + {res} + {txt}{hline 51} + {txt} price mpg displacement + {txt} b/t b/t b/t + {txt}{hline 51} + {txt}foreign {res} 3.57526 -1.650029 -25.6127{txt} + {res} (5.749891) (-1.565555) (-2.047999){txt} + {txt}weight {res} 5.691462 -6.587886 96.75485{txt} + {res} (6.182983) (-10.55641) (13.06594){txt} + {txt}length {res} -.0882711 {txt} + {res} (-2.809689) {txt} + {txt}_cons {res} 4.506212 41.6797 -87.23547{txt} + {res} (1.255897) (19.64914) (-3.46585){txt} + {txt}{hline 51} + {txt}r2 {res} .548808 .6627029 .8115213{txt} + {txt}chi2 {res} 89.73586 145.3912 318.6174{txt} + {txt}p {res} 2.50e-19 2.68e-32 6.50e-70{txt} + {txt}{hline 51} +{marker ex6} +{dlgtab:Marginal effects} + + {com}. generate record = 0 + {txt} + {com}. replace record = 1 if rep > 3 + {txt}(34 real changes made) + + {com}. eststo raw: quietly logit foreign mpg record + {txt} + {com}. eststo mfx: quietly mfx + {txt} + {com}. estout raw mfx, cells("b Xmfx_X(pattern(0 1))" se(par)) margin legend + {res} + {txt}{hline 51} + {txt} raw mfx + {txt} b/se b/se Xmfx_X + {txt}{hline 51} + {txt}mpg {res} .1079219 .0184528 21.2973{txt} + {res} (.0565077) (.0101674) {txt} + {txt}record (d) {res} 2.435068 .4271707 .4594595{txt} + {res} (.7128444) (.1043178) {txt} + {txt}_cons {res} -4.689347 {txt} + {res} (1.326547) {txt} + {txt}{hline 51} + {txt}(d) for discrete change of dummy variable from 0 to 1 +{marker ex7} +{dlgtab:Tabulating a matrix} + +{p 4 4 2} + Use {cmd:estout matrix(}{it:matname}{cmd:)} to tabulate Stata matrix + {it:matname}. Example: + + {com}. set seed 123 + {txt} + {com}. matrix A = matuniform(3,2) + {txt} + {com}. matrix list A + + {txt}A[3,2] + c1 c2 + r1 {res}.91204397 .0075452 + {txt}r2 {res}.28085881 .46027868 + {txt}r3 {res}.56010592 .67319061 + {txt} + {com}. estout matrix(A) + {res} + {txt}{hline 38} + {txt} A + {txt} c1 c2 + {txt}{hline 38} + {txt}r1 {res} .912044 .0075452{txt} + {txt}r2 {res} .2808588 .4602787{txt} + {txt}r3 {res} .5601059 .6731906{txt} + {txt}{hline 38} + +{p 4 4 2} + Numeric formats for the columns can be set using the {cmd:fmt()} + suboption: + + {com}. estout matrix(A, fmt(2 3)) + {res} + {txt}{hline 38} + {txt} A + {txt} c1 c2 + {txt}{hline 38} + {txt}r1 {res} 0.91 0.008{txt} + {txt}r2 {res} 0.28 0.460{txt} + {txt}r3 {res} 0.56 0.673{txt} + {txt}{hline 38} + +{p 4 4 2} + A list of formats can be specified for each column: + + {com}. estout matrix(A, fmt("2 3 4" "4 3 2")) + {res} + {txt}{hline 38} + {txt} A + {txt} c1 c2 + {txt}{hline 38} + {txt}r1 {res} 0.91 0.0075{txt} + {txt}r2 {res} 0.281 0.460{txt} + {txt}r3 {res} 0.5601 0.67{txt} + {txt}{hline 38} +{marker rem} +{title:Remarks} + + Contents + + {help estout##fmt:Numerical formats} + {help estout##spchar:Special characters} + {help estout##atvar:Using @-variables} + {help estout##defaults:Defaults files} +{marker fmt} +{dlgtab:Numerical formats} + +{p 4 4 2} +Numerical display formats may be specified in {cmd:estout} +as follows: + +{p 5 8 2} +1. Official Stata's display formats: You may specify formats, such as +{cmd:%9.0g} or {cmd:%8.2f}. See help {help format} for a list +of available formats. {cmd:%g} or {cmd:g} may be used as a +synonym for {cmd:%9.0g}. + +{p 5 8 2} +2. Fixed format: You may specify an integer value such as {cmd:0}, +{cmd:1}, {cmd:2}, etc. to request a display format with a fixed number +of decimal places. For example, {cmd:cells(t(fmt(3)))} would display +t-statistics with three decimal places. + +{p 5 8 2} +3. Automatic format: You may specify {cmd:a1}, {cmd:a2}, ..., or +{cmd:a9} to cause {cmd:esttab} to choose a reasonable display format for +each number depending on the number's value. {cmd:a} may be used as a +synonym for {cmd:a3}. The {it:#} in +{cmd:a}{it:#} determines the minimum precision according to the +following rules: + +{p 10 12 2} +o Absolute numbers smaller than 1 are displayed with {it:#} +significant decimal places (i.e. with {it:#} decimal places ignoring +any leading zeros after the decimal point). For example, +{cmd:0.00123456} is displayed as {cmd:0.00123} if the format is +{cmd:a3}. + +{p 10 12 2} +o Absolute numbers greater than 1 are displayed with as many digits +required to retain at least one decimal place and are displayed with +a minimum of ({it:#} + 1) digits. For example, if the format is +{cmd:a3}, {cmd:1.23456} is displayed as {cmd:1.235}, {cmd:12.3456} is +displayed as {cmd:12.35}, and {cmd:1234.56} is displayed as +{cmd:1234.6}. + +{p 10 12 2} +o In any case, integers are displayed with zero decimal places, and +very large or very small absolute numbers are displayed in +exponential format. + +{marker spchar} +{dlgtab:Special characters} + +{p 4 4 2} +The {cmd:\} and {cmd:$} characters and quotation marks have +special meanings in Stata. You should therefore consider the following +instructions if you, for example, intend to specify akward delimiters or +specify special characters in labels: + +{p 6 8 2}- Strings containing unmatched quotes should be enclosed in compound double +quotes (thus, {cmd:delimiter(`"""')} results in columns +delimited by {cmd:"}, while {cmd:delimiter(")} produces an error). + +{p 6 8 2}- The backslash character is used to delay macro expansion in +Stata. Specifying {cmd:\\} in Stata 8 just results in the printing of {cmd:\}. To get +a double backslash in Stata 8 (the {cmd:\newline} command in TeX), type {cmd:\\\}. + +{p 6 8 2}- The dollar sign is used for global macro expansion in Stata. Thus, +{cmd:$x} would result in the display of the contents of global macro +{cmd:x} (or nothing, if the macro is empty). Therefore, use +{cmd:\$} to produce {cmd:$} in the output. For math mode in LaTeX I +recommend using {cmd:\(}...{cmd:\)} instead of {cmd:$}...{cmd:$}. + +{p 4 4 2} +Stata's {cmd:char()} function may also be used to specify odd characters +(see help {help strfun}). In particular, {cmd:"`=char(9)'"} +results in a tab character and {cmd:"`=char(13)'"} results +in a carriage return. For example, {bind:{cmd:delimiter(" `=char(9)' ")}} +specifies that a tab character with a leading and +a trailing blank be used as delimiter. + +{p 4 4 2} {it:Tip:} It is sometimes very useful to set the format of all cells in a +spreadsheet to "Text" before pasting the estimates table. This prevents the +spreadsheet program from trying to interpret the cells and ensures that the contents +of the table remain unchanged. + +{marker atvar} +{dlgtab:Using @-variables} + +{p 4 4 2} +{cmd:estout} features several variables that can be used within string +specifications. The following list provides an overview of these variables. + +{p 5 8 2}o{space 2}In {cmd:prehead()}, {cmd:posthead()}, {cmd:prefoot()}, + and {cmd:postfoot()}, in the {cmd:begin()} and {cmd:end()} label + suboptions, and in the {cmd:blist()} and {cmd:elist()} suboptions + in {cmd:varlabels()}: + +{p 12 16 2}{cmd:@span} to return the value of a count variable for the total number of physical + columns of the table. + +{p 12 16 2}{cmd:@M} to return the number of models in the table. + +{p 12 16 2}{cmd:@E} to return the total number columns containing separate equations. + +{p 12 16 2}{cmd:@width} to return the total width of the table (number of characters). + +{p 12 16 2}{cmd:@hline} to return a horizontal line (series of dashes, by default; + see the {cmd:hlinechar()} option). + +{p 5 8 2}o{space 2}In {cmd:prehead()}, {cmd:posthead()}, {cmd:prefoot()}, + and {cmd:postfoot()}: + +{p 12 16 2}{cmd:@title} to return the title specified with the {cmd:title()} option. + +{p 12 16 2}{cmd:@note} to return the note specified with the {cmd:note()} option. + +{p 12 16 2}{cmd:@discrete} to return the explanations provided by the + {cmd:discrete()} option (provided that the {cmd:margin} option is activated). + +{p 12 16 2}{cmd:@starlegend} to return a legend explaining the significance symbols. + +{p 5 8 2}o{space 2}In the {cmd:prefix()} and {cmd:suffix()} suboptions of {cmd:mgroups()}, + {cmd:mlabels()}, {cmd:eqlabels()}, and + {cmd:collabels()}, and in the labels specified in these options: + +{p 12 16 2}{cmd:@span} to return the number of spanned columns. + +{p 5 8 2}o{space 2}In the {cmd:erepeat()} suboption of + {cmd:mgroups()}, {cmd:mlabels()}, {cmd:eqlabels()}, and + {cmd:collabels()}: + +{p 12 16 2}{cmd:@span} to return the range of spanned columns (e.g. {cmd:2-4} if columns 2, 3 and 4 + are spanned). + +{marker defaults} +{dlgtab:Defaults files} + +{p 4 4 2}{ul:Creating new defaults files:} + +{p 4 4 2} +To make available an own set +of default options, proceed as follows: + +{p 8 11 2} +1. Download "estout_mystyle.def" from the SSC +Archive (click +{stata "copy http://fmwww.bc.edu/repec/bocode/e/estout_mystyle.def estout_mystyle.def, text":here} +to copy the file from SSC and store it in the working directory). + +{p 8 11 2} +2. Open "estout_mystyle.def" in a text editor and make the desired modifications +(click {stata "doedit estout_mystyle.def":here} to open "estout_mystyle.def" in Stata's Do-File +Editor). + +{p 8 11 2} +3. Save the file in the current directory or elsewhere +in the ado-file path as {cmd:estout_}{it:newstyle}{cmd:.def} (see help {help sysdir}). + +{p 4 4 2}To use the new options set in {cmd:estout}, then type: + + {inp:. estout} {it:...} {inp:, style(}{it:newstyle}{inp:)} + + +{p 4 4 2}{ul:Defaults files syntax:} + +{p 4 4 2} +{cmd:estout} has two main types of options, which are treated differentially +in defaults files. On the one hand, there are simple on/off options without +arguments, like {cmd:legend} or {cmd:showtabs}. To turn such an option on, +enter the option followed by the options name as an argument, i.e. add the line + + {it:option} {it:option} + +{p 4 4 2} +to the defaults file. For example, + + {inp:legend legend} + +{p 4 4 2} +specifies that a legend be printed in the table footer. Otherwise, if you want +to turn the option of, just delete or comment out the line that contains it (or +specify {it:option} without an argument). + +{p 4 4 2} +To temporarily turn off an option that has been activated in a defaults file, +specify {cmd:no}{it:option} in the command line (do not, however, use +{cmd:no}{it:option} in defaults files). For example, if the legend has been +turned on in the defaults file, but you want to suppress it in a specific call of +{cmd:estout}, type + + {inp:. estout} {it:...}{inp:, nolegend} + +{p 4 4 2} +On the other hand, there are options that take arguments, such as +{cmd:prehead(}{it:args}{cmd:)}, {cmd:delimiter(}{it:args}{cmd:)}, or +{cmd:stats(}{it:args}{cmd:,} {it:...}{cmd:)}. Such options are specified as + + {it:option} {it:args} + +{p 4 4 2} +in the defaults file (where {it:args} must not include suboptions; see +below). Specifying an option in the command line overwrites the settings from +the defaults file. However, note that a {cmd:no} form, which exists for the +first options type, is not available here. + +{p 4 4 2} +Last but not least, there are two options that reflect a combination of the first +and second types: {cmd:eform}[{cmd:(}{it:args}{cmd:)}] and +{cmd:margin}[{cmd:(}{it:args}{cmd:)}]. These options can be specified +as either + + {it:option} {it:option} + +{p 4 4 2} +or + + {it:option} {it:args} + +{p 4 4 2} +in the defaults file; the {cmd:no} form is allowed. + +{p 4 4 2} +Many {cmd:estout} options have suboptions, i.e., an option might take the +form {it:option}{cmd:(}{it:...}{cmd:,} {it:suboption}{cmd:)} or +{it:option}{cmd:(}{it:...}{cmd:,} {it:suboption}{cmd:(}{it:args}{cmd:))}. In +the defaults file, the suboptions cannot be included in the +definition of a higher-level option. Instead, they must be +specified in their own lines, as either + + {it:optionsuboption} {it:suboption} + +{p 4 4 2} +or + + {it:optionsuboption} {it:args} + +{p 4 4 2} +In the case of a two-level nesting of options, the name +used to refer to the suboption is a concatenation of the option's name and the +suboption's name, +i.e. {cmd:"}{it:optionsuboption}{cmd:"="}{it:option}{cmd:"+"}{it:suboption}{cmd:"}. For +example, the {cmd:labels()} suboption of the {cmd:stats()} option would be +set by the term {cmd:statslabels}. Analogously, the three level nesting in +the {cmd:stats()} option yields suboption names composed of three names. For +instance, the suboption called by the command + + {inp:. estout} {it:...}{inp:, stats(}{it:...}{inp:, labels(}{it:...}{inp:, prefix(}{it:args}{inp:)))} + +{p 4 4 2} +would be referred to as + + {inp:statslabelsprefix} {it:args} + +{p 4 4 2} +in the defaults file. The {cmd:cells()} option represents an exception to +this rule. It may be defined in the defaults file using +only a plain array of cells elements without suboptions, e.g. + + {inp:cells "b se" p} + +{p 4 4 2} +However, the suboptions of the cells elements may be referred to as +{it:el_suboption}, for example + + {inp:b_star star} + +{p 4 4 2} +or + + {inp:se_par [ ]} + + +{p 4 4 2}{ul:Comments in defaults files:} + +{p 4 4 2} +Be aware that the support for comments in defaults files is limited. In +particular, the {cmd:/*} and {cmd:*/} comment indicators cannot be used. +The other comment indicators work (more or less) as usual, that is: + +{p 5 8 2} + o{space 2}Empty lines and lines beginning with {cmd:*} (with or without preceding +blanks) will be ignored. + +{p 5 8 2} + o{space 2}{cmd://} preceded by one or more blanks indicates that the rest of the +line should be ignored. Lines beginning with {cmd://} (with or without preceding +blanks) will be ignored. + +{p 5 8 2} + o{space 2}{cmd:///} preceded by one or more blanks indicates that the rest of the +line should be ignored and the part of the line preceding it should be added to +the next line. In other words, {cmd:///} can be used to split commands into +two or more lines of code. + +{marker ret} +{title:Saved results} + +{p 4 4 2} +{cmd:estout} saves the following in {cmd:r()}: + +{p 4 4 2}Scalars + {p_end} +{p 6 20 2}{cmd:r(nmodels)}{space 4}number of models + {p_end} +{p 6 20 2}{cmd:r(ccols)}{space 6}number of columns per model in {cmd:r(coefs)} + {p_end} + +{p 4 4 2}Macros + {p_end} +{p 6 20 2}{cmd:r(cmdline)}{space 4}command as typed + {p_end} +{p 6 20 2}{cmd:r(names)}{space 6}names of models + {p_end} +{p 6 20 2}{cmd:r(m}{it:#}{cmd:_}{it:name}{cmd:)}{space 4}model-specific +macros where {it:#} is the model number and {it:name} is macro name + {p_end} + +{p 4 4 2}Matrices + {p_end} +{p 6 20 2}{cmd:r(coefs)}{space 6}coefficients + {p_end} +{p 6 20 2}{cmd:r(stats)}{space 6}summary statistics + {p_end} + +{marker ref} +{title:References} + +{p 4 8 2}Cong, R. (2000). sg144: Marginal effects of the tobit model. +{it:Stata Technical Bulletin} 56: 27-34. + +{p 4 8 2}Jann, B. (2005). Making regression tables from stored estimates. +{it:The Stata Journal} 5(3): 288-308. + +{p 4 8 2}Jann, B. (2007). Making regression tables simplified. +{it:The Stata Journal} 7(2): 227-244. + +{p 4 8 2}Newson, R. (2003). Confidence intervals and p-values for delivery to the end +user. {it:The Stata Journal} 3(3): 245-269. + +{marker ack} +{title:Acknowledgements} + +{p 4 4 2}I would like to thank numerous people +for their comments and suggestions. Among them +are +Joao Pedro Azevedo, +Kit Baum, +Elisabeth Coutts, +Henriette Engelhardt, +Jonathan Gardnerand, +Simone Hirschvogl, +Daniel Hoechle, +Friedrich Huebler, +Maren Kandulla, +J. Scott Long, +David Newhouse, +Clive Nicholas, +Fredrik Wallenberg, +Ian Watson, and +Vince Wiggins. + +{marker aut} +{title:Author} + + Ben Jann, ETH Zurich, jannb@ethz.ch + +{marker als} +{title:Also see} + + Manual: {hi:[R] estimates} + + SJ: SJ5-3 st0085 (Jann 2005) + SJ7-2 st0085_1 (Jann 2007) + +{p 4 13 2}Online: help for + {helpb estimates}, + {help estcom}, + {helpb est_table:estimates table}, + {helpb ereturn}, + {help format}, + {helpb file}, + {helpb mfx}, + {helpb eststo}, + {helpb esttab}, + {helpb estadd}, + {helpb estpost} +{p_end} diff --git a/Modules/ado/plus/e/estpost.ado b/Modules/ado/plus/e/estpost.ado new file mode 100644 index 0000000..7cb7bd7 --- /dev/null +++ b/Modules/ado/plus/e/estpost.ado @@ -0,0 +1,1839 @@ +*! version 1.1.5 08oct2009 Ben Jann +* 1. estpost +* 2. estpost_summarize +* 3. estpost_tabulate +* 4. estpost_tabstat +* 5. estpost_ttest +* 6. estpost_correlate +* 7. estpost_stci (Stata 9 required) +* 8. estpost_ci +* 9. estpost_prtest +* 10. estpost__svy_tabulate +* 99. _erepost + +* 1. estpost +program estpost, rclass // rclass => remove r()'s left behind by subcommand + version 8.2 + local caller : di _caller() + capt syntax [, * ] + if _rc==0 { // => for bootstrap + _coef_table_header + ereturn display, `options' + exit + } + gettoken subcommand rest : 0, parse(" ,:") + capt confirm name `subcommand' + if _rc { + di as err "invalid subcommand" + exit 198 + } + + local l = length(`"`subcommand'"') + if `"`subcommand'"'==substr("summarize",1,max(2,`l')) local subcommand "summarize" + else if `"`subcommand'"'==substr("tabulate",1,max(2,`l')) local subcommand "tabulate" + else if `"`subcommand'"'==substr("correlate",1,max(3,`l')) local subcommand "correlate" + else if `"`subcommand'"'=="svy" { + _estpost_parse_svy `macval(rest)' + } + else if substr(`"`subcommand'"',1,5)=="_svy_" { + di as err "invalid subcommand" + exit 198 + } + + capt local junk: properties estpost_`subcommand' // does not work in Stata 8 + if _rc==199 { + di as err "invalid subcommand" + exit 198 + } + + version `caller': estpost_`subcommand' `macval(rest)' + //eret list +end +program _estpost_markout2 // marks out obs that are missing on *all* variables + gettoken touse varlist: 0 + if `:list sizeof varlist'>0 { + tempname touse2 + gen byte `touse2' = 0 + foreach var of local varlist { + qui replace `touse2' = 1 if !missing(`var') + } + qui replace `touse' = 0 if `touse2'==0 + } +end +program _estpost_parse_svy + version 9.2 + _on_colon_parse `0' + local 0 `"`s(after)'"' + gettoken subcommand rest : 0, parse(" ,") + local l = length(`"`subcommand'"') + if `"`subcommand'"'==substr("tabulate",1,max(2,`l')) local subcommand "tabulate" + c_local subcommand `"_svy_`subcommand'"' + c_local rest `"`s(before)' : `rest'"' +end +program _estpost_namesandlabels // used by some routines such as estpost_tabulate + version 8.2 // returns locals names, savenames, and labels + args varname values0 labels0 + if `"`values0'"'=="" { // generate values: 1 2 3 ... + local i 0 + foreach label of local labels0 { + local values0 `values0' `++i' + } + } + local haslabels 0 + if `"`labels0'"'=="" & "`varname'"!="" { + local vallab: value label `varname' + } + while (1) { + gettoken value values0 : values0 + if "`value'"=="" continue, break //=> exit loop + if `"`vallab'"'!="" { + local lbl: label `vallab' `value', strict + } + else { + gettoken lbl labels0 : labels0 + } + if index("`value'",".") { + local haslabels 1 + if `"`lbl'"'=="" { + local lbl "`value'" + } + local value: subinstr local value "." "_missing_" + } + local names0 `names0' `value' + if `"`lbl'"'!="" { + local labels `"`labels'`lblspace'`value' `"`lbl'"'"' + local lblspace " " + } + if `haslabels' continue + if `"`lbl'"'=="" { + local names `"`names'`space'`value'"' + local savenames `"`savenames'`space'`value'"' + } + else { + if regexm(`"`lbl'"', `"[:."]"') local haslabels 1 + else if length(`"`lbl'"')>30 local haslabels 1 + else { + local names `"`names'`space'`"`lbl'"'"' + local lbl: subinstr local lbl " " "_", all + local savenames `"`savenames'`space'`lbl'"' + } + } + local space " " + } + if `haslabels' { + local names `names0' + local savenames `names0' + } + c_local names `"`names'"' // to be used as matrix row- or colnames + c_local savenames `"`savenames'"' // names without spaces (for matlist) + if `haslabels' { + c_local labels `"`labels'"' // label dictionary + } + else c_local labels "" +end +program _estpost_eqnamesandlabels // used by some routines such as estpost_tabulate + version 8.2 // returns locals eqnames and eqlabels + args varname values0 labels0 + if `"`values0'"'=="" { // generate values: 1 2 3 ... + local i 0 + foreach label of local labels0 { + local values0 `values0' `++i' + } + } + local haslabels 0 + if `"`labels0'"'=="" & "`varname'"!="" { + local vallab: value label `varname' + } + while (1) { + gettoken value values0 : values0 + if "`value'"=="" continue, break //=> exit loop + if `"`vallab'"'!="" { + local lbl: label `vallab' `value', strict + } + else { + gettoken lbl labels0 : labels0 + } + if index("`value'",".") { + local haslabels 1 + if `"`lbl'"'=="" { + local lbl "`value'" + } + local value: subinstr local value "." "_missing_" + } + local names0 `names0' `value' + if `"`lbl'"'=="" local lbl "`value'" + local labels `"`labels'`lblspace'`"`lbl'"'"' + local lblspace " " + if `haslabels' continue + if `"`lbl'"'=="" { + local names `"`names'`space'`value'"' + } + else { + if regexm(`"`lbl'"', `"[:."]"') local haslabels 1 + else if length(`"`lbl'"')>30 local haslabels 1 + else { + local names `"`names'`space'`"`lbl'"'"' + } + } + local space " " + } + if `haslabels' { + local names `names0' + } + c_local eqnames `"`names'"' // to be used as matrix roweqs or coleqs + if `haslabels' { + c_local eqlabels `"`labels'"' // list of labels + } + else c_local eqlabels "" +end + +* 2. estpost_summarize: wrapper for -summarize- +prog estpost_summarize, eclass + version 8.2 + local caller : di _caller() // not used + + // syntax + syntax [varlist] [if] [in] [aw fw iw] [, ESample Quietly /// + LISTwise CASEwise Detail MEANonly ] + if "`casewise'"!="" local listwise listwise + + // sample + if "`listwise'"!="" marksample touse + else { + marksample touse, nov + _estpost_markout2 `touse' `varlist' + } + qui count if `touse' + local N = r(N) + if `N'==0 error 2000 + + // gather results + local nvars: list sizeof varlist + tempname emptymat + mat `emptymat' = J(1, `nvars', .) + mat coln `emptymat' = `varlist' + local i 0 + local rnames "" + foreach v of local varlist { + local ++i + qui summarize `v' if `touse' [`weight'`exp'], `detail' `meanonly' + local rnamesi: r(scalars) + local rnamesi: list rnamesi - rnames + if `"`rnamesi'"'!="" { + foreach name of local rnamesi { + tempname _`name' + mat `_`name'' = `emptymat' + } + local rnames: list rnames | rnamesi + } + foreach rname of local rnames { + mat `_`rname''[1,`i'] = r(`rname') + } + } + + // display + if "`quietly'"=="" { + tempname res + local rescoln + foreach rname of local rnames { + mat `res' = nullmat(`res'), `_`rname''' + if "`rname'"=="N" { + local rescoln `rescoln' e(count) + } + else { + local rescoln `rescoln' e(`rname') + } + } + mat coln `res' = `rescoln' + if c(stata_version)<9 { + mat list `res', noheader nohalf format(%9.0g) + } + else { + matlist `res', nohalf lines(oneline) + } + mat drop `res' + } + + // post results + local b + local V + if c(stata_version)<9 { // b and V required in Stata 8 + tempname b V + mat `b' = J(1, `nvars', 0) + mat coln `b' = `varlist' + mat `V' = `b'' * `b' + } + if "`esample'"!="" local esample esample(`touse') + eret post `b' `V', obs(`N') `esample' + + eret scalar k = `nvars' + + eret local wexp `"`exp'"' + eret local wtype `"`weight'"' + eret local subcmd "summarize" + eret local cmd "estpost" + + local nmat: list sizeof rnames + forv i=`nmat'(-1)1 { + local rname: word `i' of `rnames' + if "`rname'"=="N" { + eret matrix count = `_N' + continue + } + eret matrix `rname' = `_`rname'' + } +end + + +* 2. estpost_tabulate: wrapper for -tabulate- +prog estpost_tabulate, eclass + version 8.2 + local caller : di _caller() // not used + syntax varlist(min=1 max=2) [if] [in] [fw aw iw pw] [, * ] + if `:list sizeof varlist'==1 { + version `caller': estpost_tabulate_oneway `0' + } + else { + version `caller': estpost_tabulate_twoway `0' + } +end +prog estpost_tabulate_oneway, eclass + version 8.2 + local caller : di _caller() // not used + + // syntax + syntax varname [if] [in] [fw aw iw] [, ESample Quietly /// + noTOTal subpop(passthru) Missing sort noLabel ] + + // sample + if "`missing'"!="" marksample touse, nov strok + else marksample touse, strok + qui count if `touse' + local N = r(N) + if `N'==0 error 2000 + + // handle string variables + capt confirm numeric variable `varlist' + if _rc { + tempname varname + qui encode `varlist' if `touse', generate(`varname') + } + else local varname `varlist' + + // gather results + tempname count vals + tab `varname' if `touse' [`weight'`exp'], nofreq /// + matcell(`count') matrow(`vals') `subpop' `missing' `sort' + local N = r(N) + mat `count' = `count'' + local R = r(r) + forv r = 1/`R' { + local value: di `vals'[`r',1] + local values `values' `value' + } + if "`label'"=="" { + _estpost_namesandlabels `varname' "`values'" // sets names, savenames, labels + } + else { + _estpost_namesandlabels "" "`values'" + } + if "`total'"=="" { + mat `count' = `count', `N' + local names `"`names' Total"' + local savenames `"`savenames' Total"' + local linesopt "lines(rowtotal)" + } + mat colname `count' = `names' + tempname percent cum + mat `percent' = `count'/`N'*100 + mat `cum' = J(1, colsof(`count'), .z) + mat colname `cum' = `names' + mat `cum'[1,1] = `count'[1,1] + forv r = 2/`R' { + mat `cum'[1,`r'] = `cum'[1,`r'-1] + `count'[1,`r'] + } + mat `cum' = `cum'/`N'*100 + + // display + if "`quietly'"=="" { + tempname res + mat `res' = `count'', `percent'', `cum'' + mat coln `res' = e(b) e(pct) e(cumpct) + if c(stata_version)<9 { + mat list `res', noheader nohalf format(%9.0g) nodotz + } + else { + mat rown `res' = `savenames' + matlist `res', nohalf `linesopt' rowtitle(`varlist') nodotz + } + mat drop `res' + if `"`labels'"'!="" { + di _n as txt "row labels saved in macro e(labels)" + } + } + + // post results + local V + if c(stata_version)<9 { // V required in Stata 8 + tempname V + mat `V' = `count'' * `count' * 0 + } + if "`esample'"!="" local esample esample(`touse') + eret post `count' `V', depname(`varlist') obs(`N') `esample' + eret scalar r = r(r) + eret local wexp `"`exp'"' + eret local wtype `"`weight'"' + eret local labels `"`labels'"' + eret local depvar "`varlist'" + eret local subcmd "tabulate" + eret local cmd "estpost" + eret mat cumpct = `cum' + eret mat pct = `percent' +end +prog estpost_tabulate_twoway, eclass + version 8.2 + local caller : di _caller() // not used + + // syntax + syntax varlist(min=2 max=2) [if] [in] [fw aw iw] [, ESample Quietly /// + noTOTal Missing noLabel /// + CHi2 Exact Exact2(passthru) Gamma LRchi2 Taub v All noLOg ] + local v = upper("`v'") + local qui2 "`quietly'" + local hastests = `"`chi2'`exact'`exact2'`gamma'`lrchi2'`taub'`v'`all'"'!="" + if `hastests' local nofreq nofreq + else local qui2 "quietly" + + // sample + if "`missing'"!="" marksample touse, nov strok + else marksample touse, strok + qui count if `touse' + local N = r(N) + if `N'==0 error 2000 + + // handle string variables + gettoken rvar cvar : varlist + gettoken cvar : cvar + foreach d in r c { + capt confirm numeric variable ``d'var' + if _rc { + tempname `d'varname + qui encode ``d'var' if `touse', generate(``d'varname') + } + else local `d'varname ``d'var' + } + + // gather results + tempname cell rvals cvals + if `hastests' { + `quietly' di "" + } + `qui2' tab `rvarname' `cvarname' if `touse' [`weight'`exp'], `nofreq' /// + matcell(`cell') matrow(`rvals') matcol(`cvals') `missing' /// + `chi2' `exact' `exact2' `gamma' `lrchi2' `taub' `v' `all' `log' + mat `cvals' = `cvals'' + local N = r(N) + tempname rtot ctot + mat `ctot' = J(1,rowsof(`cell'),1) * `cell' + mat `rtot' = `cell' * J(colsof(`cell'),1,1) + foreach d in r c { + local I = r(`d') + forv i = 1/`I' { + local value: di ``d'vals'[`i',1] + local `d'values ``d'values' `value' + } + } + if "`label'"=="" { + _estpost_namesandlabels `rvarname' "`rvalues'" // sets names, savenames, labels + _estpost_eqnamesandlabels `cvarname' "`cvalues'" // sets eqnames, eqlabels + } + else { + _estpost_namesandlabels "" "`rvalues'" // sets names, savenames, labels + _estpost_eqnamesandlabels "" "`cvalues'" // sets eqnames, eqlabels + } + local savenames0 `"`savenames'"' + local savenames + if "`total'"=="" { + mat `ctot' = `ctot', `N' + mat `cell' = (`cell', `rtot') \ `ctot' + mat `rtot' = `rtot' \ `N' + local names `"`names' Total"' + local savenames0 `"`savenames0' Total"' + local eqnames `"`eqnames' Total"' + } + mat rowname `cell' = `names' + tempname count col row tot tmp + forv i = 1/`=colsof(`cell')' { + gettoken eq eqnames : eqnames + mat `tmp' = `cell'[1...,`i'] + mat roweq `tmp' = `"`eq'"' + mat `tmp' = `tmp'' + mat `count' = nullmat(`count'), `tmp' + mat `col' = nullmat(`col'), `tmp' / `ctot'[1,`i']*100 + forv j = 1/`=colsof(`tmp')' { + mat `tmp'[1,`j'] = `tmp'[1,`j'] / `rtot'[`j',1]*100 + } + mat `row' = nullmat(`row'), `tmp' + local savenames `"`savenames' `savenames0'"' + } + mat `tot' = `count' / `N'*100 + + // display + if "`quietly'"=="" { + tempname res + mat `res' = `count'', `tot'', `col'', `row'' + mat coln `res' = e(b) e(pct) e(colpct) e(rowpct) + if c(stata_version)<9 { + mat list `res', noheader nohalf format(%9.0g) + } + else { + mat rown `res' = `savenames' + di _n as res %-12s abbrev("`cvar'",12) as txt " {c |}{space 44}" + matlist `res', twidth(12) format(%9.0g) noblank nohalf rowtitle(`rvar') + } + mat drop `res' + if `"`labels'`eqlabels'"'!="" { + di "" + if `"`labels'"'!="" { + di as txt "row labels saved in macro e(labels)" + } + if `"`eqlabels'"'!="" { + di as txt "column labels saved in macro e(eqlabels)" + } + } + } + + // post results + local V + if c(stata_version)<9 { // V required in Stata 8 + tempname V + mat `V' = `count'' * `count' * 0 + } + if "`esample'"!="" local esample esample(`touse') + eret post `count' `V', obs(`N') `esample' + local rscalars: r(scalars) + local rscalars: subinstr local rscalars "N" "", word + foreach rsc of local rscalars { + eret scalar `rsc' = r(`rsc') + } + eret local wexp `"`exp'"' + eret local wtype `"`weight'"' + eret local labels `"`labels'"' + eret local eqlabels `"`eqlabels'"' + eret local colvar "`cvar'" + eret local rowvar "`rvar'" + eret local subcmd "tabulate" + eret local cmd "estpost" + eret mat rowpct = `row' + eret mat colpct = `col' + eret mat pct = `tot' +end + + +* 4. estpost_tabstat: wrapper for -tabstat- +prog estpost_tabstat, eclass + version 8.2 + local caller : di _caller() // not used + + // syntax + syntax varlist [if] [in] [aw fw] [, ESample Quietly /// + Statistics(passthru) stats(passthru) LISTwise CASEwise /// + by(varname) noTotal Missing Columns(str) ] + if "`casewise'"!="" local listwise listwise + local l = length(`"`columns'"') + if `"`columns'"'==substr("variables",1,max(1,`l')) local columns "variables" + else if `"`columns'"'==substr("statistics",1,max(1,`l')) local columns "statistics" + else if `"`columns'"'=="stats" local columns "statistics" + else if `"`columns'"'=="" { + if `:list sizeof varlist'>1 local columns "variables" + else local columns "statistics" + } + else { + di as err `"columns(`columns') invalid"' + exit 198 + } + + // sample + if "`listwise'"!="" marksample touse + else { + marksample touse, nov + _estpost_markout2 `touse' `varlist' + } + if "`by'"!="" { + if "`missing'"=="" markout `touse' `by', strok + local byopt "by(`by')" + } + qui count if `touse' + local N = r(N) + if `N'==0 error 2000 + + // gather results + if "`total'"!="" & "`by'"=="" { + di as txt "nothing to post" + eret clear + exit + } + qui tabstat `varlist' if `touse' [`weight'`exp'], save /// + `statistics' `stats' `byopt' `total' `missing' columns(`columns') + tempname tmp + capt confirm matrix r(StatTot) + if _rc { + mat `tmp' = r(Stat1) + } + else { + mat `tmp' = r(StatTot) + } + if `"`columns'"'=="statistics" { + local cnames: rownames `tmp' + local cnames: subinstr local cnames "N" "count", word all + local cnames: subinstr local cnames "se(mean)" "semean", word all + local R = colsof(`tmp') + local stats "`cnames'" + local vars: colnames `tmp' + } + else { + local cnames: colnames `tmp' + local R = rowsof(`tmp') + local stats: rownames `tmp' + local stats: subinstr local stats "N" "count", word all + local stats: subinstr local stats "se(mean)" "semean", word all + local vars "`cnames'" + local cnames: subinstr local cnames "b" "_b", word all + local cnames: subinstr local cnames "V" "_V", word all + } + local j 0 + foreach cname of local cnames { + tempname _`++j' + } + local groups: r(macros) + local g: list sizeof groups + local space + local labels + forv i = 1/`g' { + local labels `"`labels'`space'`"`r(name`i')'"'"' + } + if `R'==1 { + _estpost_namesandlabels "" "" `"`labels'"' // sets names, savenames, labels + } + else { + _estpost_eqnamesandlabels "" "" `"`labels'"' // sets eqnames, eqlabels + local names `"`eqnames'"' + local labels `"`eqlabels'"' + } + forv i = 1/`g' { + gettoken name names : names + mat `tmp' = r(Stat`i') + mat rown `tmp' = `stats' + if `"`columns'"'=="statistics" { + mat `tmp' = `tmp'' + } + if `R'==1 { + mat rown `tmp' = `"`name'"' + } + else { + mat roweq `tmp' = `"`name'"' + } + local j 0 + foreach cname of local cnames { + local ++j + mat `_`j'' = nullmat(`_`j''), `tmp'[1..., `j']' + } + } + if "`total'"=="" { + mat `tmp' = r(StatTot) + mat rown `tmp' = `stats' + if `"`columns'"'=="statistics" { + mat `tmp' = `tmp'' + } + if `g'>0 { + if `R'==1 { + mat rown `tmp' = "Total" + local savenames `"`savenames' Total"' + local rowtotal "lines(rowtotal)" + } + else { + mat roweq `tmp' = "Total" + if `"`labels'"'!="" { + local labels `"`labels' Total"' + } + } + } + local j 0 + foreach cname of local cnames { + local ++j + mat `_`j'' = nullmat(`_`j''), `tmp'[1..., `j']' + } + } + + // display + if "`quietly'"=="" { + tempname res + local rescoln + local j 0 + foreach cname of local cnames { + local ++j + mat `res' = nullmat(`res'), `_`j''' + local rescoln `rescoln' e(`cname') + } + mat coln `res' = `rescoln' + di _n as txt "Summary statistics: `stats'" + di as txt " for variables: `vars'" + if "`by'"!="" { + di as txt " by categories of: `by'" + } + if c(stata_version)<9 { + mat list `res', noheader nohalf format(%9.0g) + } + else { + if `R'==1 & `g'>0 { + mat rown `res' = `savenames' + } + matlist `res', nohalf `rowtotal' rowtitle(`by') + } + if `"`labels'"'!="" { + di _n as txt "category labels saved in macro e(labels)" + } + mat drop `res' + } + + // post results + local b + local V + if c(stata_version)<9 { // b and V required in Stata 8 + tempname b V + mat `b' = `_1' \ J(1, colsof(`_1'), 0) + mat `b' = `b'[2,1...] + mat `V' = `b'' * `b' + } + if "`esample'"!="" local esample esample(`touse') + eret post `b' `V', obs(`N') `esample' + + eret local labels `"`labels'"' + eret local byvar "`by'" + eret local vars "`vars'" + eret local stats "`stats'" + eret local wexp `"`exp'"' + eret local wtype `"`weight'"' + eret local subcmd "tabstat" + eret local cmd "estpost" + + local nmat: list sizeof cnames + forv j=`nmat'(-1)1 { + local cname: word `j' of `cnames' + eret matrix `cname' = `_`j'' + } +end + + +* 5. estpost_ttest: wrapper for -ttest- (two-sample) +prog estpost_ttest, eclass + version 8.2 + local caller : di _caller() // not used + + // syntax + syntax varlist(numeric) [if] [in] , by(varname) [ ESample Quietly /// + LISTwise CASEwise UNEqual Welch ] + if "`casewise'"!="" local listwise listwise + + // sample + if "`listwise'"!="" marksample touse + else { + marksample touse, nov + _estpost_markout2 `touse' `varlist' + } + markout `touse' `by', strok + qui count if `touse' + local N = r(N) + if `N'==0 error 2000 + + // gather results + local nvars: list sizeof varlist + tempname diff count + mat `diff' = J(1, `nvars', .) + mat coln `diff' = `varlist' + mat `count' = `diff' + local mnames se /*sd*/ t df_t p_l p p_u N_1 mu_1 /*sd_1*/ N_2 mu_2 /*sd_2*/ + foreach m of local mnames { + tempname `m' + mat ``m'' = `diff' + } + local i 0 + foreach v of local varlist { + local ++i + qui ttest `v' if `touse', by(`by') `unequal' `welch' + mat `diff'[1,`i'] = r(mu_1) - r(mu_2) + mat `count'[1,`i'] = r(N_1) + r(N_2) + foreach m of local mnames { + mat ``m''[1,`i'] = r(`m') + } + } + + // display + if "`quietly'"=="" { + tempname res + mat `res' = `diff'', `count'' + local rescoln "e(b) e(count)" + foreach m of local mnames { + mat `res' = `res', ``m''' + local rescoln `rescoln' e(`m') + } + mat coln `res' = `rescoln' + if c(stata_version)<9 { + mat list `res', noheader nohalf format(%9.0g) + } + else { + matlist `res', nohalf lines(oneline) + } + mat drop `res' + } + + // post results + local V + if c(stata_version)<9 { // b and V required in Stata 8 + tempname V + mat `V' = diag(vecdiag(`se'' * `se')) + } + if "`esample'"!="" local esample esample(`touse') + eret post `diff' `V', obs(`N') `esample' + + eret scalar k = `nvars' + + eret local wexp `"`exp'"' + eret local wtype `"`weight'"' + eret local welch "`welch'" + eret local unequal "`unequal'" + eret local byvar "`by'" + eret local subcmd "ttest" + eret local cmd "estpost" + + local nmat: list sizeof mnames + forv i=`nmat'(-1)1 { + local m: word `i' of `mnames' + eret matrix `m' = ``m'' + } + eret matrix count = `count' +end + + +* 6. estpost_correlate: wrapper for -correlate- +prog estpost_correlate, eclass + version 8.2 + local caller : di _caller() // not used + + // syntax + syntax varlist [if] [in] [aw fw iw pw] [, ESample Quietly /// + LISTwise CASEwise /// + Matrix noHalf Print(real 1) /*Covariance*/ Bonferroni SIDak ] + if "`casewise'"!="" local listwise listwise + if "`bonferroni'"!="" & "`sidak'"!="" { + di as err "only one of bonferroni and sidak allowed" + exit 198 + } + local pw = ("`weight'"=="pweight") + if `:list sizeof varlist'<=1 & `"`matrix'"'=="" { + di as err "too few variables specified" + exit 102 + } + if `"`matrix'"'!="" & `"`half'"'!="" local fullmatrix fullmatrix + + // sample + if "`listwise'"!="" marksample touse + else { + marksample touse, nov + _estpost_markout2 `touse' `varlist' + } + qui count if `touse' + local N = r(N) + if `N'==0 error 2000 + + // gather results + tempname b rho pval count + if "`bonferroni'`sidak'"!="" { + local nvars : list sizeof varlist + local k = `nvars' * (`nvars'-1) / 2 + } + foreach depvar of local varlist { + if `"`fullmatrix'"'!="" { + local indepvars `varlist' + } + else if `"`matrix'"'!="" { + local indepvars `depvar' `ferest()' + } + else { + local indepvars `ferest()' + } + foreach v of local indepvars { + qui reg `depvar' `v' [`weight'`exp'] if `touse' + local r = sqrt(e(r2)) * (-1)^(_b[`v']<0) + local n = e(N) + mat `b' = nullmat(`b'), `r' + if "`depvar'"=="`v'" { + mat `rho' = nullmat(`rho'), `r' + mat `count' = nullmat(`count'), `n' + mat `pval' = nullmat(`pval'), .z + continue + } + local p = Ftail(e(df_m), e(df_r), e(F)) + if `pw' { + qui reg `v' `depvar' [`weight'`exp'] if `touse' + local p = max(`p', Ftail(e(df_m), e(df_r), e(F))) + } + if "`bonferroni'"!="" { + local p = min(1, `k'*`p') + } + else if "`sidak'"!="" { + local p = min(1, 1 - (1-`p')^`k') + } + if `p'>`print' { + local r .z + local n .z + local p .z + } + mat `rho' = nullmat(`rho'), `r' + mat `count' = nullmat(`count'), `n' + mat `pval' = nullmat(`pval'), `p' + } + if `"`matrix'`fullmatrix'"'=="" { + local colnames `indepvars' + local depname `depvar' + continue, break + } + foreach v of local indepvars { + local colnames `"`colnames'`depvar':`v' "' + } + } + mat coln `b' = `colnames' + mat coln `rho' = `colnames' + mat coln `count' = `colnames' + mat coln `pval' = `colnames' + local vce `"`e(vce)'"' // from last -regress- call + local vcetype `"`e(vcetype)'"' + + // display + if "`quietly'"=="" { + tempname res + mat `res' = `b'', `rho'', `pval'', `count'' + mat coln `res' = e(b) e(rho) e(p) e(count) + if c(stata_version)<9 { + mat list `res', noheader nohalf format(%9.0g) nodotz + } + else { + matlist `res', nohalf lines(oneline) rowtitle(`depname') nodotz + } + mat drop `res' + } + + // post results + local V + if c(stata_version)<9 { // b and V required in Stata 8 + tempname b + mat `V' = `b'' * `b' * 0 + } + if "`esample'"!="" local esample esample(`touse') + eret post `b' `V', depname(`depname') obs(`N') `esample' + eret local vcetype `"`vcetype'"' + eret local vce `"`vce'"' + eret local wexp `"`exp'"' + eret local wtype `"`weight'"' + eret local depvar `depname' + eret local subcmd "correlate" + eret local cmd "estpost" + eret matrix count = `count' + eret matrix p = `pval' + eret matrix rho = `rho' +end + + +* 7. estpost_stci: wrapper for -stci- +prog estpost_stci, eclass + version 9.2 // Stata 8 not supported because levelsof is used + local caller : di _caller() // not used + + // syntax + syntax [if] [in] [ , ESample Quietly by(varname) /// + Median Rmean Emean p(numlist >0 <100 integer max=1) /// + CCorr Level(real `c(level)') ] + local stat "p50" + if `"`p'"'!="" { + local stat `"p`p'"' + local p `"p(`p')"' + } + else if "`rmean'"!="" local stat "rmean" + else if "`emean'"!="" local stat "emean" + + // sample + marksample touse + if `"`by'"'!="" { + markout `touse' `by', strok + } + qui count if `touse' + local N = r(N) + if `N'==0 error 2000 + + // get results + tempname _`stat' se N_sub lb ub + if "`by'"!="" { + qui levelsof `by' if `touse', local(levels) + capt confirm string variable `by' + if _rc { + local vallab: value label `by' + if `"`vallab'"'!="" { + _estpost_namesandlabels `by' `"`levels'"' // sets names, savenames, labels + } + else { + local names `"`levels'"' + local savenames `"`levels'"' + } + } + else { + _estpost_namesandlabels `by' "" `"`levels'"' // sets names, savenames, labels + } + } + local levels `"`levels' "total""' + local names `"`names' "total""' + local savenames `"`savenames' "total""' + gettoken l rest : levels, quotes + while (`"`l'"'!="") { + if `"`rest'"'=="" local lcond + else local lcond `" & `by'==`l'"' + qui stci if `touse'`lcond', `median' `rmean' `emean' `p' `ccorr' level(`level') + mat `_`stat'' = nullmat(`_`stat''), r(`stat') + mat `se' = nullmat(`se'), r(se) + mat `N_sub' = nullmat(`N_sub'), r(N_sub) + mat `lb' = nullmat(`lb'), r(lb) + mat `ub' = nullmat(`ub'), r(ub) + gettoken l rest : rest, quotes + } + foreach m in _`stat' se N_sub lb ub { + mat coln ``m'' = `names' + } + + // display + if "`quietly'"=="" { + tempname res + mat `res' = `N_sub'', `_`stat''', `se'', `lb'', `ub'' + mat coln `res' = e(count) e(`stat') e(se) e(lb) e(ub) + di as txt "(confidence level is " `level' "%)" + if c(stata_version)<9 { + mat list `res', noheader nohalf format(%9.0g) nodotz + } + else { + mat rown `res' = `savenames' + matlist `res', nohalf lines(rowtotal) nodotz + } + mat drop `res' + if `"`labels'"'!="" { + di _n as txt "labels saved in macro e(labels)" + } + } + + // post results + local b + local V + if c(stata_version)<9 { // b and V required in Stata 8 + tempname b V + mat `b' = `_`stat'' \ J(1, colsof(`_`stat''), 0) + mat `b' = `b'[2,1...] + mat `V' = `b'' * `b' + } + if "`esample'"!="" local esample esample(`touse') + eret post `b' `V', obs(`N') `esample' + eret scalar level = `level' + + eret local ccorr `ccorr' + eret local labels `"`labels'"' + eret local subcmd "stci" + eret local cmd "estpost" + + eret matrix ub = `ub' + eret matrix lb = `lb' + eret matrix se = `se' + eret matrix `stat' = `_`stat'' + eret matrix count = `N_sub' +end + + +* 8. estpost_ci: wrapper for -ci- +prog estpost_ci, eclass + version 8.2 + local caller : di _caller() // not used + + // syntax + syntax [varlist] [if] [in] [aw fw], [ ESample Quietly /// + LISTwise CASEwise Level(real `c(level)') /// + Binomial EXAct WAld Wilson Agresti Jeffreys /// + Poisson Exposure(varname) /// + ] + if "`casewise'"!="" local listwise listwise + if "`exposure'"!="" local exposureopt "exposure(`exposure')" + if "`binomial'"!="" & "`exact'`wald'`wilson'`agresti'`jeffreys'"=="" local exact exact + + // sample + if "`listwise'"!="" marksample touse + else { + marksample touse, nov + _estpost_markout2 `touse' `varlist' + } + qui count if `touse' + local N = r(N) + if `N'==0 error 2000 + + // gather results + local mnames se lb ub + tempname mean count `mnames' + local i 0 + foreach v of local varlist { + local ++i + qui ci `v' if `touse' [`weight'`exp'], level(`level') /// + `binomial' `exact' `wald' `wilson' `agresti' `jeffreys' /// + `poisson' `exposureopt' + if r(N)>=. continue + mat `mean' = nullmat(`mean'), r(mean) + mat `count' = nullmat(`count'), r(N) + foreach m of local mnames { + mat ``m'' = nullmat(``m''), r(`m') + } + local rnames "`rnames' `v'" + } + capt confirm matrix `count' + if _rc { + di as txt "nothing to post" + eret clear + exit + } + foreach m in mean count `mnames' { + mat coln ``m'' = `rnames' + } + if "`listwise'"=="" { // update sample + if colsof(`count') < `: list sizeof varlist' { + _estpost_markout2 `touse' `rnames' + qui count if `touse' + local N = r(N) + } + } + + // display + if "`quietly'"=="" { + tempname res + mat `res' = `mean'', `count'' + local rescoln "e(b) e(count)" + foreach m of local mnames { + mat `res' = `res', ``m''' + local rescoln `rescoln' e(`m') + } + mat coln `res' = `rescoln' + di as txt "(confidence level is " `level' "%)" + if c(stata_version)<9 { + mat list `res', noheader nohalf format(%9.0g) + } + else { + matlist `res', nohalf lines(oneline) + } + mat drop `res' + } + + // post results + local V + if c(stata_version)<9 { // b and V required in Stata 8 + tempname V + mat `V' = diag(vecdiag(`se'' * `se')) + } + if "`esample'"!="" local esample esample(`touse') + eret post `mean' `V', obs(`N') `esample' + + eret scalar k = colsof(`count') + eret scalar level = `level' + + eret local wexp `"`exp'"' + eret local wtype `"`weight'"' + eret local exposure "`exposure'" + eret local poisson "`poisson'" + eret local binomial "`exact'`wald'`wilson'`agresti'`jeffreys'" + eret local subcmd "ci" + eret local cmd "estpost" + + local nmat: list sizeof mnames + forv i=`nmat'(-1)1 { + local m: word `i' of `mnames' + eret matrix `m' = ``m'' + } + eret matrix count = `count' +end + + +* 9. estpost_prtest: wrapper for -prtest- (two-sample) +prog estpost_prtest, eclass + version 8.2 + local caller : di _caller() // not used + + // syntax + syntax varlist(numeric) [if] [in] , by(varname) [ ESample Quietly /// + LISTwise CASEwise ] + if "`casewise'"!="" local listwise listwise + + // sample + if "`listwise'"!="" marksample touse + else { + marksample touse, nov + _estpost_markout2 `touse' `varlist' + } + markout `touse' `by', strok + qui count if `touse' + local N = r(N) + if `N'==0 error 2000 + + // gather results + local nvars: list sizeof varlist + tempname diff count + mat `count' = J(1, `nvars', .) + mat coln `count' = `varlist' + mat `diff' = `count' + local mnames se se0 z p_l p p_u N_1 P_1 N_2 P_2 + foreach m of local mnames { + tempname `m' + mat ``m'' = `count' + } + local i 0 + foreach v of local varlist { + local ++i + qui prtest `v' if `touse', by(`by') + mat `count'[1,`i'] = r(N_1) + r(N_2) + mat `diff'[1,`i'] = r(P_1) - r(P_2) + mat `se'[1,`i'] = sqrt(r(P_1)*(1-r(P_1))/r(N_1) + r(P_2)*(1-r(P_2))/r(N_2)) + mat `se0'[1,`i'] = `diff'[1,`i'] / r(z) + mat `p_l'[1,`i'] = normal(r(z)) + mat `p'[1,`i'] = (1-normal(abs(r(z))))*2 + mat `p_u'[1,`i'] = 1-normal(r(z)) + foreach m in z N_1 P_1 N_2 P_2 { + mat ``m''[1,`i'] = r(`m') + } + } + + // display + if "`quietly'"=="" { + tempname res + mat `res' = `diff'', `count'' + local rescoln "e(b) e(count)" + foreach m of local mnames { + mat `res' = `res', ``m''' + local rescoln `rescoln' e(`m') + } + mat coln `res' = `rescoln' + if c(stata_version)<9 { + mat list `res', noheader nohalf format(%9.0g) + } + else { + matlist `res', nohalf lines(oneline) + } + mat drop `res' + } + + // post results + local V + if c(stata_version)<9 { // b and V required in Stata 8 + tempname V + mat `V' = diag(vecdiag(`se'' * `se')) + } + if "`esample'"!="" local esample esample(`touse') + eret post `diff' `V', obs(`N') `esample' + + eret scalar k = `nvars' + + eret local wexp `"`exp'"' + eret local wtype `"`weight'"' + eret local byvar "`by'" + eret local subcmd "prtest" + eret local cmd "estpost" + + local nmat: list sizeof mnames + forv i=`nmat'(-1)1 { + local m: word `i' of `mnames' + eret matrix `m' = ``m'' + } + eret matrix count = `count' +end + + +* 10. estpost__svy_tabulate: wrapper for -svy:tabulate- +prog estpost__svy_tabulate + version 9.2 + local caller : di _caller() + _on_colon_parse `0' + local svyopts `"svyopts(`s(before)')"' + local 0 `"`s(after)'"' + syntax varlist(min=1 max=2) [if] [in] [ , * ] + if `:list sizeof varlist'==1 { + version `caller': _svy_tabulate_oneway `varlist' `if' `in', /// + `svyopts' `options' + } + else { + version `caller': _svy_tabulate_twoway `varlist' `if' `in', /// + `svyopts' `options' + } +end +prog _svy_tabulate_oneway + version 9.2 + local caller : di _caller() // not used + + // syntax + syntax varname [if] [in] [, ESample Quietly /// + svyopts(str asis) MISSing Level(cilevel) /// + noTOTal noMARGinals noLabel PROPortion PERcent /// + CELl COUnt se ci deff deft * ] + if "`marginals'"!="" local total "nototal" + else if "`total'"!="" local marginals "nomarginals" + + // run svy:tabulate + `quietly' svy `svyopts' : tabulate `varlist' `if' `in', /// + level(`level') `cell' `count' `se' `ci' `deff' `deft' /// + `missing' `marginals' `label' `proportion' `percent' `options' + if "`count'"!="" & "`cell'`se'`ci'`deff'`deft'"=="" { // => return count in e(b) + quietly svy `svyopts' : tabulate `varlist' `if' `in', count se /// + level(`level') `missing' `marginals' `label' `proportion' `percent' `options' + } + + // get labels + qui levelsof `varlist' if e(sample), `missing' local(levels) + local R : list sizeof levels + if e(r)!=`R' { + di as err "unexpected error; number of rows unequal number of levels" + exit 499 + } + capt confirm string variable `varlist' + if _rc { + if "`label'"=="" { + _estpost_namesandlabels `varlist' "`levels'" // sets names, savenames, labels + } + else { + _estpost_namesandlabels "" "`levels'" // sets names, savenames, labels + } + } + else { + _estpost_namesandlabels "" "" `"`levels'"' // sets names, savenames, labels + } + + // collect results + tempname cell count obs b se lb ub deff deft + local N_pop = cond(e(N_subpop)<., e(N_subpop), e(N_pop)) + local N_obs = cond(e(N_sub)<., e(N_sub), e(N)) + local tval = invttail(e(df_r), (100-`level')/200) + mat `cell' = e(Prop)' + mat `count' = `cell' * `N_pop' + capture confirm matrix e(ObsSub) + if _rc { + mat `obs' = e(Obs)' + } + else { + mat `obs' = e(ObsSub)' + } + capture confirm matrix e(Deff) + if _rc local DEFF "" + else { + local DEFF deff + mat `deff' = e(Deff) + } + capture confirm matrix e(Deft) + if _rc local DEFT "" + else { + local DEFT deft + mat `deft' = e(Deft) + } + mat `b' = e(b) + mata: st_matrix(st_local("se"), sqrt(diagonal(st_matrix("e(V)")))') + if "`total'"=="" { + mat `cell' = `cell', 1 + mat `count' = `count', `N_pop' + mat `obs' = `obs', `N_obs' + if "`DEFF'"!="" mat `deff' = `deff', .z + if "`DEFT'"!="" mat `deft' = `deft', .z + if e(setype)=="count" { + mat `b' = `b', `N_pop' + mat `se' = `se', sqrt(el(e(V_col),1,1)) + } + else { // e(setype)=="cell" + mat `b' = `b', 1 + mat `se' = `se', 0 + } + local names `"`names' "Total""' + local savenames `"`savenames' "Total""' + local linesopt "lines(rowtotal)" + + } + if e(setype)!="count" { + mata: st_matrix( st_local("lb"), invlogit( /// + logit(st_matrix(st_local("b"))) - strtoreal(st_local("tval")) * /// + st_matrix(st_local("se")) :/ /// + (st_matrix(st_local("b")) :* (1 :- st_matrix(st_local("b")))))) + mata: st_matrix( st_local("ub"), invlogit( /// + logit(st_matrix(st_local("b"))) + strtoreal(st_local("tval")) * /// + st_matrix(st_local("se")) :/ /// + (st_matrix(st_local("b")) :* (1 :- st_matrix(st_local("b")))))) + if "`total'"=="" { + mat `lb'[1, colsof(`lb')] = .z + mat `ub'[1, colsof(`ub')] = .z + } + } + else { + mata: st_matrix( st_local("lb"), st_matrix(st_local("b")) - /// + strtoreal(st_local("tval")) * st_matrix(st_local("se")) ) + mata: st_matrix( st_local("ub"), st_matrix(st_local("b")) + /// + strtoreal(st_local("tval")) * st_matrix(st_local("se")) ) + } + foreach m in cell count obs b se lb ub `DEFF' `DEFT' { + capt mat coln ``m'' = `names' + } + if "`percent'"!="" { + mat `cell' = `cell' * 100 + if e(setype)!="count" { + mat `b' = `b' * 100 + mat `se' = `se' * 100 + mat `lb' = `lb' * 100 + mat `ub' = `ub' * 100 + } + } + + // display + if "`quietly'"=="" { + /* + tempname res + mat `res' = `b'', `se'', `lb'', `ub'', `deff'', `deft'' ///, `cell'', `count'', `obs'' + mat coln `res' = e(b) e(se) e(lb) e(ub) e(deff) e(deft) /// e(cell) e(count) e(obs) + if c(stata_version)<9 { + mat list `res', noheader nohalf format(%9.0g) nodotz + } + else { + mat rown `res' = `savenames' + matlist `res', nohalf `linesopt' rowtitle(`varlist') nodotz + } + mat drop `res' + */ + local plabel = cond("`percent'"!="","percentages","proportions") + local blabel = cond("`e(setype)'"=="count", "weighted counts", "`e(setype)' `plabel'") + di _n as txt "saved vectors:" + di as txt %20s "e(b) = " " " as res "`blabel'" + di as txt %20s "e(se) = " " " as res "standard errors of `blabel'" + di as txt %20s "e(lb) = " " " as res "lower `level'% confidence bounds for `blabel'" + di as txt %20s "e(ub) = " " " as res "upper `level'% confidence bounds for `blabel'" + if "`DEFF'"!="" /// + di as txt %20s "e(deff) = " " " as res "deff for variances of `blabel'" + if "`DEFT'"!="" /// + di as txt %20s "e(deft) = " " " as res "deft for variances of `blabel'" + di as txt %20s "e(cell) = " " " as res "cell `plabel'" + di as txt %20s "e(count) = " " " as res "weighted counts" + di as txt %20s "e(obs) = " " " as res "number of observations" + if `"`labels'"'!="" { + di _n as txt "row labels saved in macro e(labels)" + } + } + + // post results + erepost b=`b', cmd(estpost) nov `esample' + qui estadd local labels `"`labels'"' + qui estadd local subcmd "tabulate" + qui estadd scalar level = `level' + foreach m in obs count cell `DEFT' `DEFF' ub lb se { + qui estadd matrix `m' = ``m'', replace + } +end +prog _svy_tabulate_twoway + version 9.2 + local caller : di _caller() // not used + + // syntax + syntax varlist(min=1 max=2) [if] [in] [, ESample Quietly /// + svyopts(str asis) MISSing Level(cilevel) /// + noTOTal noMARGinals noLabel PROPortion PERcent /// + CELl COUnt COLumn row se ci deff deft * ] + if "`marginals'"!="" local total "nototal" + else if "`total'"!="" local marginals "nomarginals" + + // run svy:tabulate + `quietly' svy `svyopts' : tabulate `varlist' `if' `in', /// + level(`level') `cell' `count' `column' `row' `se' `ci' `deff' `deft' /// + `missing' `marginals' `label' `proportion' `percent' `options' + if `: word count `count' `column' `row''==1 & "`cell'`se'`ci'`deff'`deft'"=="" { + quietly svy `svyopts' : tabulate `varlist' `if' `in', `count' `column' `row' se /// + level(`level') `missing' `marginals' `label' `proportion' `percent' `options' + } + + // get labels + local rvar `"`e(rowvar)'"' + qui levelsof `rvar' if e(sample), `missing' local(levels) + local R : list sizeof levels + if e(r)!=`R' { + di as err "unexpected error; number of rows unequal number of rowvar levels" + exit 499 + } + capt confirm string variable `rvar' + if _rc { + if "`label'"=="" { + _estpost_namesandlabels `rvar' "`levels'" // sets names, savenames, labels + } + else { + _estpost_namesandlabels "" "`levels'" // sets names, savenames, labels + } + } + else { + _estpost_namesandlabels "" "" `"`levels'"' // sets names, savenames, labels + } + local cvar `"`e(colvar)'"' + qui levelsof `cvar' if e(sample), `missing' local(levels) + local C : list sizeof levels + if e(c)!=`C' { + di as err "unexpected error; number of column unequal number of colvar levels" + exit 499 + } + local savenames0 `"`savenames'"' + local savenames + capt confirm string variable `cvar' + if _rc { + if "`label'"=="" { + _estpost_eqnamesandlabels `cvar' "`levels'" // sets eqnames, eqlabels + } + else { + _estpost_eqnamesandlabels "" "`levels'" // sets eqnames, eqlabels + } + } + else { + _estpost_eqnamesandlabels "" "" `"`levels'"' // sets eqnames, eqlabels + } + + // collect results + tempname tmp cell row col count obs b se lb ub deff deft + local N_pop = cond(e(N_subpop)<., e(N_subpop), e(N_pop)) + local N_obs = cond(e(N_sub)<., e(N_sub), e(N)) + local tval = invttail(e(df_r), (100-`level')/200) + mat `cell' = e(Prop) // r x c matrix + mat `cell' = (`cell', `cell' * J(`C',1,1)) \ (J(1,`R',1) * `cell', 1) + mat `count' = `cell' * `N_pop' + mat `tmp' = `cell'[1..., `C'+1] + mata: st_matrix(st_local("row"), st_matrix(st_local("cell")) :/ /// + st_matrix(st_local("tmp"))) + mat `tmp' = `cell'[`R'+1, 1...] + mata: st_matrix(st_local("col"), st_matrix(st_local("cell")) :/ /// + st_matrix(st_local("tmp"))) + mat drop `tmp' + capture confirm matrix e(ObsSub) + if _rc { + mat `obs' = e(Obs) // r x c matrix + } + else { + mat `obs' = e(ObsSub) // r x c matrix + } + capt confirm matrix e(Deff) + if _rc local DEFF "" + else { + local DEFF deff + mat `deff' = e(Deff) // vector + } + capt confirm matrix e(Deft) + if _rc local DEFT "" + else { + local DEFT deft + mat `deft' = e(Deft) // vector + } + mat `b' = e(b) // vector + mata: st_matrix(st_local("se"), sqrt(diagonal(st_matrix("e(V)")))') // vector + if e(setype)=="count" local btype count + else if e(setype)=="row" local btype row + else if e(setype)=="column" local btype col + else local btype cell + foreach m in `DEFF' `DEFT' b se { // vector -> r x c matrix + forv r = 1/`R' { + local from = (`r'-1)*`C' + 1 + local to = `r'*`C' + mat `tmp' = nullmat(`tmp') \ ``m''[1, `from'..`to'] + } + mat drop ``m'' + mat rename `tmp' ``m'' + } + if "`total'"=="" { + mat `obs' = (`obs', `obs' * J(`C',1,1)) \ (J(1,`R',1) * `obs', `N_obs') + if "`DEFF'"!="" mat `deff' = (`deff', e(Deff_row)') \ (e(Deff_col), .z) + if "`DEFT'"!="" mat `deft' = (`deft', e(Deft_row)') \ (e(Deft_col), .z) + mat `b' = (`b', ``btype''[1..`R',`C'+1]) \ ``btype''[`R'+1,1...] + mata: st_matrix(st_local("se"), /// + ((st_matrix(st_local("se")), sqrt(diagonal(st_matrix("e(V_row)")))) /// + \ (sqrt(diagonal(st_matrix("e(V_col)")))', .z))) + if "`btype'"=="row" { + mat `se' = `se'[1..., 1..`C'], J(`R'+1, 1, .z) + } + else if "`btype'"=="col" { + mat `se' = `se'[1..`R', 1...] \ J(1, `C'+1, .z) + } + local names `"`names' "Total""' + local savenames0 `"`savenames0' "Total""' + local eqnames `"`eqnames' "Total""' + } + else { + mat `cell' = `cell'[1..`R', 1..`C'] + mat `count' = `count'[1..`R', 1..`C'] + mat `row' = `row'[1..`R', 1..`C'] + mat `col' = `col'[1..`R', 1..`C'] + } + if "`btype'"!="count" { + mata: st_matrix( st_local("lb"), invlogit( /// + logit(st_matrix(st_local("b"))) - strtoreal(st_local("tval")) * /// + st_matrix(st_local("se")) :/ /// + (st_matrix(st_local("b")) :* (1 :- st_matrix(st_local("b")))))) + mata: st_matrix( st_local("ub"), invlogit( /// + logit(st_matrix(st_local("b"))) + strtoreal(st_local("tval")) * /// + st_matrix(st_local("se")) :/ /// + (st_matrix(st_local("b")) :* (1 :- st_matrix(st_local("b")))))) + } + else { + mata: st_matrix( st_local("lb"), st_matrix(st_local("b")) - /// + strtoreal(st_local("tval")) * st_matrix(st_local("se")) ) + mata: st_matrix( st_local("ub"), st_matrix(st_local("b")) + /// + strtoreal(st_local("tval")) * st_matrix(st_local("se")) ) + } + if "`total'"=="" { + if "`btype'"=="row" { + mat `lb' = `lb'[1..., 1..`C'] , J(`R'+1, 1, .z) + mat `ub' = `ub'[1..., 1..`C'] , J(`R'+1, 1, .z) + } + else if "`btype'"=="col" { + mat `lb' = `lb'[1..`R', 1...] \ J(1, `C'+1, .z) + mat `ub' = `ub'[1..`R', 1...] \ J(1, `C'+1, .z) + } + else { + mat `lb'[`R'+1, `C'+1] = .z + mat `ub'[`R'+1, `C'+1] = .z + } + } + foreach m in cell count obs row col `DEFF' `DEFT' b se lb ub { // r x c matrix -> vector + mat rown ``m'' = `names' + gettoken eq rest : eqnames + forv c = 1/`=colsof(``m'')' { + mat roweq ``m'' = `"`eq'"' + mat `tmp' = nullmat(`tmp'), ``m''[1...,`c']' + gettoken eq rest : rest + } + mat drop ``m'' + mat rename `tmp' ``m'' + } + if "`percent'"!="" { + mat `cell' = `cell' * 100 + mat `col' = `col' * 100 + mat `row' = `row' * 100 + if e(setype)!="count" { + mat `b' = `b' * 100 + mat `se' = `se' * 100 + mat `lb' = `lb' * 100 + mat `ub' = `ub' * 100 + } + } + + // display + if "`quietly'"=="" { + /* + forv c = 1/`=colsof(`cell')' { + local savenames `"`savenames' `savenames0'"' + } + tempname res + mat `res' = `b'', `se'', `lb'', `ub'', `deff'', `deft'', `cell'', `row'', `col'', `count'', `obs'' + mat coln `res' = e(b) e(se) e(lb) e(ub) e(deff) e(deft) e(cell) e(row) e(col) e(count) e(obs) + if c(stata_version)<9 { + mat list `res', noheader nohalf format(%9.0g) nodotz + } + else { + mat rown `res' = `savenames' + di _n as res %-12s abbrev("`cvar'",12) as txt " {c |}{space 44}" + matlist `res', twidth(12) format(%9.0g) noblank nohalf /// + rowtitle(`rvar') nodotz + } + mat drop `res' + */ + local plabel = cond("`percent'"!="","percentages","proportions") + local blabel = cond("`e(setype)'"=="count", "weighted counts", "`e(setype)' `plabel'") + di _n as txt "saved vectors:" + di as txt %20s "e(b) = " " " as res "`blabel'" + di as txt %20s "e(se) = " " " as res "standard errors of `blabel'" + di as txt %20s "e(lb) = " " " as res "lower `level'% confidence bounds for `blabel'" + di as txt %20s "e(ub) = " " " as res "upper `level'% confidence bounds for `blabel'" + if "`DEFF'"!="" /// + di as txt %20s "e(deff) = " " " as res "deff for variances of `blabel'" + if "`DEFT'"!="" /// + di as txt %20s "e(deft) = " " " as res "deft for variances of `blabel'" + di as txt %20s "e(cell) = " " " as res "cell `plabel'" + di as txt %20s "e(row) = " " " as res "row `plabel'" + di as txt %20s "e(col) = " " " as res "column `plabel'" + di as txt %20s "e(count) = " " " as res "weighted counts" + di as txt %20s "e(obs) = " " " as res "number of observations" + if `"`labels'`eqlabels'"'!="" { + di "" + if `"`labels'"'!="" { + di as txt "row labels saved in macro e(labels)" + } + if `"`eqlabels'"'!="" { + di as txt "column labels saved in macro e(eqlabels)" + } + } + } + + // post results + erepost b=`b', cmd(estpost) nov `esample' + qui estadd local eqlabels `"`eqlabels'"' + qui estadd local labels `"`labels'"' + qui estadd local subcmd "tabulate" + qui estadd scalar level = `level' + foreach m in obs count row col cell `DEFT' `DEFF' ub lb se { + qui estadd matrix `m' = ``m'', replace + } +end + +* 11. estpost_margins: wrapper for -margins- (Stata 11) +prog estpost_margins, eclass + version 11 + local caller : di _caller() + + // syntax + _parse comma anything 0 : 0 + syntax [ , /*ESample*/ Quietly /// + post * ] + if "`post'"!="" { + di as err "post not allowed" + exit 198 + } + + // run margins + `quietly' version `caller': margins `anything', `options' + + // post results + capt postrtoe, noclear resize + if _rc<=1 { // -postrtoe- does not work, e.g., with -regress- + error _rc // _rc=1 (break) + exit + } + tempname b V + mat `b' = r(b) + mat `V' = r(V) + erepost b = `b' V = `V' /*, `esample'*/ + foreach r in `:r(scalars)' { + eret scalar `r' = r(`r') + } + foreach r in `:r(macros)' { + eret local `r' `"`r(`r')'"' + } + tempname tmp + foreach r in `:r(matrices)' { + if inlist("`r'", "b", "V") continue + mat `tmp' = r(`r') + eret matrix `r' = `tmp' + } +end + +* 99. +* copy of erepost.ado, version 1.0.1, Ben Jann, 30jul2007 +* 14jan2009: noV option added => repost e(b) and remove e(V) if not specified +prog erepost, eclass + version 8.2 + syntax [anything(equalok)] [, NOV cmd(str) noEsample Esample2(varname) REName /// + Obs(passthru) Dof(passthru) PROPerties(passthru) * ] + if "`esample'"!="" & "`esample2'"!="" { + di as err "only one allowed of noesample and esample()" + exit 198 + } +// parse [b = b] [V = V] + if `"`anything'"'!="" { + tokenize `"`anything'"', parse(" =") + if `"`7'"'!="" error 198 + if `"`1'"'=="b" { + if `"`2'"'=="=" & `"`3'"'!="" { + local b `"`3'"' + confirm matrix `b' + } + else error 198 + if `"`4'"'=="V" { + if `"`5'"'=="=" & `"`6'"'!="" { + local v `"`6'"' + confirm matrix `b' + } + else error 198 + } + else if `"`4'"'!="" error 198 + } + else if `"`1'"'=="V" { + if `"`4'"'!="" error 198 + if `"`2'"'=="=" & `"`3'"'!="" { + local v `"`3'"' + confirm matrix `v' + } + else error 198 + } + else error 198 + } +//backup existing e()'s + if "`esample2'"!="" { + local sample "`esample2'" + } + else if "`esample'"=="" { + tempvar sample + gen byte `sample' = e(sample) + } + local emacros: e(macros) + if `"`properties'"'!="" { + local emacros: subinstr local emacros "properties" "", word + } + foreach emacro of local emacros { + local e_`emacro' `"`e(`emacro')'"' + } + local escalars: e(scalars) + if `"`obs'"'!="" { + local escalars: subinstr local escalars "N" "", word + } + if `"`dof'"'!="" { + local escalars: subinstr local escalars "df_r" "", word + } + foreach escalar of local escalars { + tempname e_`escalar' + scalar `e_`escalar'' = e(`escalar') + } + local ematrices: e(matrices) + if "`v'"=="" & "`nov'"!="" { // added 14jan2009 + local nov V + local ematrices : list ematrices - nov + } + if "`b'"=="" & `:list posof "b" in ematrices' { + tempname b + mat `b' = e(b) + } + if "`v'"=="" & `:list posof "V" in ematrices' { + tempname v + mat `v' = e(V) + } + local bV "b V" + local ematrices: list ematrices - bV + foreach ematrix of local ematrices { + tempname e_`ematrix' + matrix `e_`ematrix'' = e(`ematrix') + } +// rename + if "`b'"!="" & "`v'"!="" & "`rename'"!="" { + local eqnames: coleq `b', q + local vnames: colnames `b' + mat coleq `v' = `eqnames' + mat coln `v' = `vnames' + mat roweq `v' = `eqnames' + mat rown `v' = `vnames' + } +// post results + if "`esample'"=="" { + eret post `b' `v', esample(`sample') `obs' `dof' `properties' `options' + } + else { + eret post `b' `v', `obs' `dof' `properties' `options' + } + foreach emacro of local emacros { + eret local `emacro' `"`e_`emacro''"' + } + if `"`cmd'"'!="" { + eret local cmd `"`cmd'"' + } + foreach escalar of local escalars { + eret scalar `escalar' = scalar(`e_`escalar'') + } + foreach ematrix of local ematrices { + eret matrix `ematrix' = `e_`ematrix'' + } +end diff --git a/Modules/ado/plus/e/estpost.hlp b/Modules/ado/plus/e/estpost.hlp new file mode 100644 index 0000000..81454a6 --- /dev/null +++ b/Modules/ado/plus/e/estpost.hlp @@ -0,0 +1,1322 @@ +{smcl} +{* 08oct2009}{...} +{hi:help estpost}{right:also see: {helpb esttab}, {helpb estout}, {helpb eststo}, {helpb estadd}} +{right: {browse "http://repec.org/bocode/e/estout"}} +{hline} + +{title:Title} + +{p 4 4 2}{hi:estpost} {hline 2} Post results from various commands in {cmd:e()} + + +{title:Syntax} + +{p 8 15 2} +{cmd:estpost} {it:{help estpost##commands:command}} [...] + +{marker commands} + {it:command}{col 26}description + {hline 64} + {helpb estpost##summarize:{ul:su}mmarize}{col 26}{...} +post summary statistics + {helpb estpost##tabstat:tabstat}{col 26}{...} +post summary statistics + {helpb estpost##ttest:ttest}{col 26}{...} +post two-group mean-comparison tests + {helpb estpost##prtest:prtest}{col 26}{...} +post two-group tests of proportions + {helpb estpost##tabulate:{ul:ta}bulate}{col 26}{...} +post one-way or two-way frequency table + {helpb estpost##svy_tabulate:svy: {ul:ta}bulate}{col 26}{...} +post frequency table for survey data + {helpb estpost##correlate:{ul:cor}relate}{col 26}{...} +post correlations + {helpb estpost##ci:ci}{col 26}{...} +post confidence intervals for means, + {col 26}{...} + proportions, or counts + {helpb estpost##stci:stci}{col 26}{...} +post confidence intervals for means + {col 26}{...} + and percentiles of survival time + {helpb estpost##margins:margins}{col 26}{...} +post results from {cmd:margins} (Stata 11) + {hline 64} + + +{title:Description} + +{p 4 4 2} +{cmd:estpost} posts results from various Stata commands in {cmd:e()} +so that they can be tabulated using {helpb esttab} or {helpb estout}. Type +{helpb ereturn:ereturn list} after {cmd:estpost} to list the elements saved +in {cmd:e()}. + + +{title:Commands} +{marker summarize} +{dlgtab:summarize} + +{p 4 15 2} +{cmd:estpost} {cmdab:su:mmarize} + [{it:{help varlist}}] [{it:{help if}}] [{it:{help in}}] [{it:{help weight}}] + [{cmd:,} + {cmdab:d:etail} + {cmdab:mean:only} + {cmdab:list:wise} + {cmdab:case:wise} + {cmdab:q:uietly} + {cmdab:es:ample} + ] + +{p 4 4 2} + posts summary statistics computed by {helpb summarize}. If no + {it:varlist} is specified, summary statistics are calculated for all + variables in the dataset. + +{p 4 4 2} + {cmd:aweight}s, {cmd:fweight}s, and {cmd:iweight}s are allowed + (however, {cmd:iweight}s may not be used with the {cmd:detail} option); + see {help weight}. + +{p 4 4 2} + Options are: + +{p 8 12 2} + {cmd:detail} and {cmd:meanonly} as described in help {helpb summarize}. + +{p 8 12 2} + {cmd:listwise} to handle missing values through listwise deletion, + meaning that an observation is omitted from the estimation + sample if any of the variables in {it:varlist} is missing for that + observation. The default is to determine the used observations for + each variable separately without regard to whether other variables + are missing. {cmd:casewise} is a synonym for {cmd:listwise}. + +{p 8 12 2} + {cmd:quietly} to suppress the output. + +{p 8 12 2} + {cmd:esample} to mark the estimation sample in {cmd:e(sample)}. + +{p 4 4 2}The following results vectors are saved in {cmd:e()}: + + {lalign 13:{cmd:e(count)}}number of observations + {lalign 13:{cmd:e(mean)}}mean + {lalign 13:{cmd:e(min)}}minimum + {lalign 13:{cmd:e(max)}}maximum + {lalign 13:{cmd:e(sum)}}sum of variable + {lalign 13:{cmd:e(sum_w)}}sum of the weights + {lalign 13:{cmd:e(Var)}}variance (unless {cmd:meanonly}) + {lalign 13:{cmd:e(sd)}}standard deviation (unless {cmd:meanonly}) + {lalign 13:{cmd:e(p1)}}1st percentile ({cmd:detail} only) + {lalign 13:{cmd:e(p5)}}5th percentile ({cmd:detail} only) + {lalign 13:{cmd:e(p10)}}10th percentile ({cmd:detail} only) + {lalign 13:{cmd:e(p25)}}25th percentile ({cmd:detail} only) + {lalign 13:{cmd:e(p50)}}50th percentile ({cmd:detail} only) + {lalign 13:{cmd:e(p75)}}75th percentile ({cmd:detail} only) + {lalign 13:{cmd:e(p90)}}90th percentile ({cmd:detail} only) + {lalign 13:{cmd:e(p95)}}95th percentile ({cmd:detail} only) + {lalign 13:{cmd:e(p99)}}99th percentile ({cmd:detail} only) + {lalign 13:{cmd:e(skewness)}}skewness ({cmd:detail} only) + {lalign 13:{cmd:e(kurtosis)}}kurtosis ({cmd:detail} only) + +{p 4 4 2} + Example: + +{* begin example summarize }{...} + {com}. sysuse auto, clear + {txt}(1978 Automobile Data) + + {com}. estpost summarize price mpg rep78 foreign + + {txt}{ralign 12:} {c |} {ralign 9:e(count)} {ralign 9:e(sum_w)} {ralign 9:e(mean)} {ralign 9:e(Var)} {ralign 9:e(sd)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:price} {c |} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: 6165.257}}} {ralign 9:{res:{sf: 8699526}}} {ralign 9:{res:{sf: 2949.496}}} + {ralign 12:mpg} {c |} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: 21.2973}}} {ralign 9:{res:{sf: 33.47205}}} {ralign 9:{res:{sf: 5.785503}}} + {ralign 12:rep78} {c |} {ralign 9:{res:{sf: 69}}} {ralign 9:{res:{sf: 69}}} {ralign 9:{res:{sf: 3.405797}}} {ralign 9:{res:{sf: .9799659}}} {ralign 9:{res:{sf: .9899323}}} + {ralign 12:foreign} {c |} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: .2972973}}} {ralign 9:{res:{sf: .2117734}}} {ralign 9:{res:{sf: .4601885}}} + + {ralign 12:} {c |} {ralign 9:e(min)} {ralign 9:e(max)} {ralign 9:e(sum)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11} + {ralign 12:price} {c |} {ralign 9:{res:{sf: 3291}}} {ralign 9:{res:{sf: 15906}}} {ralign 9:{res:{sf: 456229}}} + {ralign 12:mpg} {c |} {ralign 9:{res:{sf: 12}}} {ralign 9:{res:{sf: 41}}} {ralign 9:{res:{sf: 1576}}} + {ralign 12:rep78} {c |} {ralign 9:{res:{sf: 1}}} {ralign 9:{res:{sf: 5}}} {ralign 9:{res:{sf: 235}}} + {ralign 12:foreign} {c |} {ralign 9:{res:{sf: 0}}} {ralign 9:{res:{sf: 1}}} {ralign 9:{res:{sf: 22}}} + + {com}. esttab ., cells("mean sd count") noobs + {res} + {txt}{hline 51} + {txt} (1) + {txt} + {txt} mean sd count + {txt}{hline 51} + {txt}price {res} 6165.257 2949.496 74{txt} + {txt}mpg {res} 21.2973 5.785503 74{txt} + {txt}rep78 {res} 3.405797 .9899323 69{txt} + {txt}foreign {res} .2972973 .4601885 74{txt} + {txt}{hline 51} +{* end example }{txt}{...} + +{marker tabstat} +{dlgtab:tabstat} + +{p 4 15 2} +{cmd:estpost} {cmdab:tabstat} + {it:{help varlist}} [{it:{help if}}] [{it:{help in}}] [{it:{help weight}}] + [{cmd:,} + {cmdab:s:tatistics:(}{it:{help tabstat##statname:statname}} [{it:...}]{cmd:)} + {cmdab:c:olumns:(}{cmdab:v:ariables}|{cmdab:s:tatistics:)} + {cmd:by(}{it:varname}{cmd:)} + {cmdab:not:otal} + {cmdab:m:issing} + {cmdab:list:wise} + {cmdab:case:wise} + {cmdab:q:uietly} + {cmdab:es:ample} + ] + +{p 4 4 2} + posts summary statistics computed by {helpb tabstat}. {cmd:aweight}s and + {cmd:fweight}s are allowed; see {help weight}. + +{p 4 4 2} + Options are: + +{p 8 12 2} + {cmd:statistics()}, {cmd:columns()}, {cmd:by()}, {cmd:nototal}, + and {cmd:missing} as described in help {helpb tabstat}. + +{p 8 12 2} + {cmd:listwise} to handle missing values through listwise deletion, + meaning that an observation is omitted from the estimation + sample if any of the variables in {it:varlist} is missing for that + observation. The default is to determine the used observations for + each variable separately without regard to whether other variables + are missing. {cmd:casewise} is a synonym for {cmd:listwise}. + +{p 8 12 2} + {cmd:quietly} to suppress the output. + +{p 8 12 2} + {cmd:esample} to mark the estimation sample in {cmd:e(sample)}. + +{p 4 4 2}A vector of results is saved in {cmd:e()} for each specified +variable or statistic, depending on {cmd:columns()}. + +{p 4 4 2} + Examples: + +{* begin example tabstat }{...} + {com}. sysuse auto, clear + {txt}(1978 Automobile Data) + + {com}. estpost tabstat price mpg rep78, listwise /// + > statistics(mean sd) + + {txt}Summary statistics: mean sd + for variables: price mpg rep78 + + {ralign 12:} {c |} {ralign 9:e(price)} {ralign 9:e(mpg)} {ralign 9:e(rep78)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11} + {ralign 12:mean} {c |} {ralign 9:{res:{sf: 6146.043}}} {ralign 9:{res:{sf: 21.28986}}} {ralign 9:{res:{sf: 3.405797}}} + {ralign 12:sd} {c |} {ralign 9:{res:{sf: 2912.44}}} {ralign 9:{res:{sf: 5.866408}}} {ralign 9:{res:{sf: .9899323}}} + + {com}. esttab ., cells("price mpg rep78") + {res} + {txt}{hline 51} + {txt} (1) + {txt} + {txt} price mpg rep78 + {txt}{hline 51} + {txt}mean {res} 6146.043 21.28986 3.405797{txt} + {txt}sd {res} 2912.44 5.866408 .9899323{txt} + {txt}{hline 51} + {txt}N {res} 69 {txt} + {txt}{hline 51} + + {com}. estpost tabstat price mpg rep78, listwise /// + > statistics(mean sd) columns(statistics) + + {txt}Summary statistics: mean sd + for variables: price mpg rep78 + + {ralign 12:} {c |} {ralign 9:e(mean)} {ralign 9:e(sd)} + {hline 13}{c +}{hline 11}{hline 11} + {ralign 12:price} {c |} {ralign 9:{res:{sf: 6146.043}}} {ralign 9:{res:{sf: 2912.44}}} + {ralign 12:mpg} {c |} {ralign 9:{res:{sf: 21.28986}}} {ralign 9:{res:{sf: 5.866408}}} + {ralign 12:rep78} {c |} {ralign 9:{res:{sf: 3.405797}}} {ralign 9:{res:{sf: .9899323}}} + + {com}. esttab ., cells("mean(fmt(a3)) sd") + {res} + {txt}{hline 38} + {txt} (1) + {txt} + {txt} mean sd + {txt}{hline 38} + {txt}price {res} 6146.0 2912.4{txt} + {txt}mpg {res} 21.29 5.866{txt} + {txt}rep78 {res} 3.406 0.990{txt} + {txt}{hline 38} + {txt}N {res} 69 {txt} + {txt}{hline 38} + + {com}. estpost tabstat price mpg rep78, by(foreign) /// + > statistics(mean sd) columns(statistics) listwise + + {txt}Summary statistics: mean sd + for variables: price mpg rep78 + by categories of: foreign + + {ralign 12:foreign} {c |} {ralign 9:e(mean)} {ralign 9:e(sd)} + {hline 13}{c +}{hline 11}{hline 11} + {res:{lalign 13:Domestic}}{c |}{space 11}{space 11} + {ralign 12:price} {c |} {ralign 9:{res:{sf: 6179.25}}} {ralign 9:{res:{sf: 3188.969}}} + {ralign 12:mpg} {c |} {ralign 9:{res:{sf: 19.54167}}} {ralign 9:{res:{sf: 4.753312}}} + {ralign 12:rep78} {c |} {ralign 9:{res:{sf: 3.020833}}} {ralign 9:{res:{sf: .837666}}} + {hline 13}{c +}{hline 11}{hline 11} + {res:{lalign 13:Foreign}}{c |}{space 11}{space 11} + {ralign 12:price} {c |} {ralign 9:{res:{sf: 6070.143}}} {ralign 9:{res:{sf: 2220.984}}} + {ralign 12:mpg} {c |} {ralign 9:{res:{sf: 25.28571}}} {ralign 9:{res:{sf: 6.309856}}} + {ralign 12:rep78} {c |} {ralign 9:{res:{sf: 4.285714}}} {ralign 9:{res:{sf: .7171372}}} + {hline 13}{c +}{hline 11}{hline 11} + {res:{lalign 13:Total}}{c |}{space 11}{space 11} + {ralign 12:price} {c |} {ralign 9:{res:{sf: 6146.043}}} {ralign 9:{res:{sf: 2912.44}}} + {ralign 12:mpg} {c |} {ralign 9:{res:{sf: 21.28986}}} {ralign 9:{res:{sf: 5.866408}}} + {ralign 12:rep78} {c |} {ralign 9:{res:{sf: 3.405797}}} {ralign 9:{res:{sf: .9899323}}} + + {com}. esttab ., main(mean) aux(sd) nostar unstack /// + > noobs nonote label + {res} + {txt}{hline 59} + {txt} (1) + {txt} + {txt} Domestic Foreign Total + {txt}{hline 59} + {txt}Price {res} 6179.3 6070.1 6146.0{txt} + {res} {ralign 12:{txt:(}3189.0{txt:)}} {ralign 12:{txt:(}2221.0{txt:)}} {ralign 12:{txt:(}2912.4{txt:)}}{txt} + + {txt}Mileage (mpg) {res} 19.54 25.29 21.29{txt} + {res} {ralign 12:{txt:(}4.753{txt:)}} {ralign 12:{txt:(}6.310{txt:)}} {ralign 12:{txt:(}5.866{txt:)}}{txt} + + {txt}Repair Record 1978 {res} 3.021 4.286 3.406{txt} + {res} {ralign 12:{txt:(}0.838{txt:)}} {ralign 12:{txt:(}0.717{txt:)}} {ralign 12:{txt:(}0.990{txt:)}}{txt} + {txt}{hline 59} +{* end example }{txt}{...} + +{marker ttest} +{dlgtab:ttest} + +{p 4 15 2} +{cmd:estpost} {cmdab:ttest} + {it:{help varlist}} [{it:{help if}}] [{it:{help in}}]{cmd:,} + {cmd:by(}{it:groupvar}{cmd:)} + [ + {cmdab:une:qual} {cmdab:w:elch} + {cmdab:list:wise} + {cmdab:case:wise} + {cmdab:q:uietly} + {cmdab:es:ample} + ] + +{p 4 4 2} + posts two-group mean-comparison tests computed by {helpb ttest}. + +{p 4 4 2} + Options are: + +{p 8 12 2} + {cmd:by()}, {cmd:unequal}, and {cmd:welch} as described in + help {helpb ttest}. + +{p 8 12 2} + {cmd:listwise} to handle missing values through listwise deletion, + meaning that an observation is omitted from the estimation + sample if any of the variables in {it:varlist} is missing for that + observation. The default is to determine the used observations for + each variable separately without regard to whether other variables + are missing. {cmd:casewise} is a synonym for {cmd:listwise}. + +{p 8 12 2} + {cmd:quietly} to suppress the output. + +{p 8 12 2} + {cmd:esample} to mark the estimation sample in {cmd:e(sample)}. + +{p 4 4 2}The following results vectors are saved in {cmd:e()}: + + {lalign 13:{cmd:e(b)}}mean difference + {lalign 13:{cmd:e(count)}}number of observations + {lalign 13:{cmd:e(se)}}standard error of difference + {lalign 13:{cmd:e(t)}}t statistic + {lalign 13:{cmd:e(df_t)}}degrees of freedom + {lalign 13:{cmd:e(p_l)}}lower one-sided p-value + {lalign 13:{cmd:e(p)}}two-sided p-value + {lalign 13:{cmd:e(p_u)}}upper one-sided p-value + {lalign 13:{cmd:e(N_1)}}number of observations in group 1 + {lalign 13:{cmd:e(mu_1)}}mean in group 1 + {lalign 13:{cmd:e(N_2)}}number of observations in group 2 + {lalign 13:{cmd:e(mu_2)}}mean in group 2 + +{p 4 4 2} + Example: + +{* begin example ttest }{...} + {com}. sysuse auto, clear + {txt}(1978 Automobile Data) + + {com}. estpost ttest price mpg headroom trunk, by(foreign) + + {txt}{ralign 12:} {c |} {ralign 9:e(b)} {ralign 9:e(count)} {ralign 9:e(se)} {ralign 9:e(t)} {ralign 9:e(df_t)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:price} {c |} {ralign 9:{res:{sf:-312.2587}}} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: 754.4488}}} {ralign 9:{res:{sf:-.4138899}}} {ralign 9:{res:{sf: 72}}} + {ralign 12:mpg} {c |} {ralign 9:{res:{sf:-4.945804}}} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: 1.362162}}} {ralign 9:{res:{sf:-3.630848}}} {ralign 9:{res:{sf: 72}}} + {ralign 12:headroom} {c |} {ralign 9:{res:{sf: .5402098}}} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: .2070884}}} {ralign 9:{res:{sf: 2.608596}}} {ralign 9:{res:{sf: 72}}} + {ralign 12:trunk} {c |} {ralign 9:{res:{sf: 3.340909}}} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: 1.022208}}} {ralign 9:{res:{sf: 3.268327}}} {ralign 9:{res:{sf: 72}}} + + {ralign 12:} {c |} {ralign 9:e(p_l)} {ralign 9:e(p)} {ralign 9:e(p_u)} {ralign 9:e(N_1)} {ralign 9:e(mu_1)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:price} {c |} {ralign 9:{res:{sf: .3400925}}} {ralign 9:{res:{sf: .6801851}}} {ralign 9:{res:{sf: .6599075}}} {ralign 9:{res:{sf: 52}}} {ralign 9:{res:{sf: 6072.423}}} + {ralign 12:mpg} {c |} {ralign 9:{res:{sf: .0002627}}} {ralign 9:{res:{sf: .0005254}}} {ralign 9:{res:{sf: .9997373}}} {ralign 9:{res:{sf: 52}}} {ralign 9:{res:{sf: 19.82692}}} + {ralign 12:headroom} {c |} {ralign 9:{res:{sf: .9944757}}} {ralign 9:{res:{sf: .0110486}}} {ralign 9:{res:{sf: .0055243}}} {ralign 9:{res:{sf: 52}}} {ralign 9:{res:{sf: 3.153846}}} + {ralign 12:trunk} {c |} {ralign 9:{res:{sf: .99917}}} {ralign 9:{res:{sf: .00166}}} {ralign 9:{res:{sf: .00083}}} {ralign 9:{res:{sf: 52}}} {ralign 9:{res:{sf: 14.75}}} + + {ralign 12:} {c |} {ralign 9:e(N_2)} {ralign 9:e(mu_2)} + {hline 13}{c +}{hline 11}{hline 11} + {ralign 12:price} {c |} {ralign 9:{res:{sf: 22}}} {ralign 9:{res:{sf: 6384.682}}} + {ralign 12:mpg} {c |} {ralign 9:{res:{sf: 22}}} {ralign 9:{res:{sf: 24.77273}}} + {ralign 12:headroom} {c |} {ralign 9:{res:{sf: 22}}} {ralign 9:{res:{sf: 2.613636}}} + {ralign 12:trunk} {c |} {ralign 9:{res:{sf: 22}}} {ralign 9:{res:{sf: 11.40909}}} + + {com}. esttab ., wide + {res} + {txt}{hline 41} + {txt} (1) + {txt} + {txt}{hline 41} + {txt}price {res} -312.3 {ralign 12:{txt:(}-0.41{txt:)}}{txt} + {txt}mpg {res} -4.946*** {ralign 12:{txt:(}-3.63{txt:)}}{txt} + {txt}headroom {res} 0.540* {ralign 12:{txt:(}2.61{txt:)}}{txt} + {txt}trunk {res} 3.341** {ralign 12:{txt:(}3.27{txt:)}}{txt} + {txt}{hline 41} + {txt}N {res} 74 {txt} + {txt}{hline 41} + {txt}t statistics in parentheses + {txt}* p<0.05, ** p<0.01, *** p<0.001 +{* end example }{txt}{...} + +{marker prtest} +{dlgtab:prtest} + +{p 4 15 2} +{cmd:estpost} {cmdab:prtest} + {it:{help varlist}} [{it:{help if}}] [{it:{help in}}]{cmd:,} + {cmd:by(}{it:groupvar}{cmd:)} + [ + {cmdab:list:wise} + {cmdab:case:wise} + {cmdab:q:uietly} + {cmdab:es:ample} + ] + +{p 4 4 2} + posts two-group tests of proportions computed by {helpb prtest}. + +{p 4 4 2} + Options are: + +{p 8 12 2} + {cmd:by()} as described in + help {helpb prtest}. + +{p 8 12 2} + {cmd:listwise} to handle missing values through listwise deletion, + meaning that an observation is omitted from the estimation + sample if any of the variables in {it:varlist} is missing for that + observation. The default is to determine the used observations for + each variable separately without regard to whether other variables + are missing. {cmd:casewise} is a synonym for {cmd:listwise}. + +{p 8 12 2} + {cmd:quietly} to suppress the output. + +{p 8 12 2} + {cmd:esample} to mark the estimation sample in {cmd:e(sample)}. + +{p 4 4 2}The following results vectors are saved in {cmd:e()}: + + {lalign 13:{cmd:e(b)}}difference in proportions + {lalign 13:{cmd:e(count)}}number of observations + {lalign 13:{cmd:e(se)}}standard error of difference + {lalign 13:{cmd:e(se0)}}standard error under Ho + {lalign 13:{cmd:e(z)}}z statistic + {lalign 13:{cmd:e(p_l)}}lower one-sided p-value + {lalign 13:{cmd:e(p)}}two-sided p-value + {lalign 13:{cmd:e(p_u)}}upper one-sided p-value + {lalign 13:{cmd:e(N_1)}}number of observations in group 1 + {lalign 13:{cmd:e(P_1)}}proportion in group 1 + {lalign 13:{cmd:e(N_2)}}number of observations in group 2 + {lalign 13:{cmd:e(P_2)}}proportion in group 2 + +{p 4 4 2} + Example: + +{* begin example prtest }{...} + {com}. webuse cure2, clear + {txt} + {com}. estpost prtest cure, by(sex) + + {txt}{ralign 12:} {c |} {ralign 9:e(b)} {ralign 9:e(count)} {ralign 9:e(se)} {ralign 9:e(se0)} {ralign 9:e(z)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:cure} {c |} {ralign 9:{res:{sf:-.0729167}}} {ralign 9:{res:{sf: 109}}} {ralign 9:{res:{sf: .0933123}}} {ralign 9:{res:{sf: .0942404}}} {ralign 9:{res:{sf:-.7737309}}} + + {ralign 12:} {c |} {ralign 9:e(p_l)} {ralign 9:e(p)} {ralign 9:e(p_u)} {ralign 9:e(N_1)} {ralign 9:e(P_1)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:cure} {c |} {ralign 9:{res:{sf: .219545}}} {ralign 9:{res:{sf: .43909}}} {ralign 9:{res:{sf: .780455}}} {ralign 9:{res:{sf: 64}}} {ralign 9:{res:{sf: .59375}}} + + {ralign 12:} {c |} {ralign 9:e(N_2)} {ralign 9:e(P_2)} + {hline 13}{c +}{hline 11}{hline 11} + {ralign 12:cure} {c |} {ralign 9:{res:{sf: 45}}} {ralign 9:{res:{sf: .6666667}}} + + {com}. esttab ., cell("b se0 z p") + {res} + {txt}{hline 64} + {txt} (1) + {txt} + {txt} b se0 z p + {txt}{hline 64} + {txt}cure {res} -.0729167 .0942404 -.7737309 .43909{txt} + {txt}{hline 64} + {txt}N {res} 109 {txt} + {txt}{hline 64} +{* end example }{txt}{...} + +{marker tabulate} +{dlgtab:tabulate} + +{p 4 4 2}One-way table: + +{p 8 15 2} +{cmd:estpost} {cmdab:ta:bulate} + {it:varname} [{it:{help if}}] [{it:{help in}}] [{it:{help weight}}] + [{cmd:,} + {cmdab:m:issing} + {cmdab:nol:abel} + {cmd:sort} + {cmd:subpop(}{it:varname}{cmd:)} + {cmdab:notot:al} + {cmdab:q:uietly} + {cmdab:es:ample} + ] + +{p 4 4 2}Two-way table: + +{p 8 15 2} +{cmd:estpost} {cmdab:ta:bulate} + {it:varname1} {it:varname2} [{it:{help if}}] [{it:{help in}}] [{it:{help weight}}] + [{cmd:,} + {cmdab:m:issing} + {cmdab:nol:abel} + {cmdab:ch:i2} + {cmdab:e:xact}[{cmd:(}{it:#}{cmd:)}] + {cmdab:g:amma} + {cmdab:lr:chi2} + {cmdab:t:aub} + {cmdab:v} + {cmdab:notot:al} + {cmdab:q:uietly} + {cmdab:es:ample} + ] + +{p 4 4 2} + {cmd:estpost tabulate} posts a one-way or two-way table + computed by {helpb tabulate}. {cmd:aweight}s, {cmd:fweight}s, + and {cmd:iweight}s are allowed; see {help weight}. + +{p 4 4 2} + Options are: + +{p 8 12 2} + {cmd:missing}, + {cmd:nolabel}, + {cmd:sort}, + {cmd:subpop()}, + {cmd:chi2}, + {cmd:exact}, + {cmd:gamma}, + {cmd:lrchi2}, + {cmd:taub}, and + {cmd:v} + as described in help {helpb tabulate}. + +{p 8 12 2} + {cmdab:nototal} to omit row and column totals. + +{p 8 12 2} + {cmd:quietly} to suppress the output. + +{p 8 12 2} + {cmd:esample} to mark the estimation sample in {cmd:e(sample)}. + +{p 4 4 2}The following vectors are saved in {cmd:e()}: + + {lalign 13:{cmd:e(b)}}frequency counts + {lalign 13:{cmd:e(pct)}}percent + {lalign 13:{cmd:e(cumpct)}}cumulative percent (one-way only) + {lalign 13:{cmd:e(colpct)}}column percent (two-way only) + {lalign 13:{cmd:e(rowpct)}}row percent (two-way only) + +{p 4 4 2}If two-way options such as, e.g., {cmd:chi2} or {cmd:exact} are +specified, the results of the tests added as scalars in {cmd:e()} using the +names documented in {helpb tabulate:{bind:[R] tabulate}}. + +{p 4 4 2}The value labels of the row variable are stored as names in the +saved vectors, unless +no label exceeds 30 characters or contains unsuitable characters in which case +the labels are stored in macro {cmd:e(labels)}. Type +{cmd:varlabels(`e(labels)')} in {helpb esttab} or {helpb estout} to +use the labels stored {cmd:e(labels)}. The value labels of the column variable +are stored as equation names or, alternatively, +in macro {cmd:e(eqlabels)}. Type {cmd:eqlabels(`e(eqlabels)')} in +{helpb esttab} or {helpb estout} to use the labels stored in {cmd:e(eqlabels)}. + +{p 4 4 2}Examples: + +{* begin example tabulate }{...} + {com}. sysuse auto, clear + {txt}(1978 Automobile Data) + + {com}. estpost tabulate foreign + + {txt}{ralign 12:foreign} {c |} {ralign 9:e(b)} {ralign 9:e(pct)} {ralign 9:e(cumpct)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11} + {ralign 12:Domestic} {c |} {ralign 9:{res:{sf: 52}}} {ralign 9:{res:{sf: 70.27027}}} {ralign 9:{res:{sf: 70.27027}}} + {ralign 12:Foreign} {c |} {ralign 9:{res:{sf: 22}}} {ralign 9:{res:{sf: 29.72973}}} {ralign 9:{res:{sf: 100}}} + {hline 13}{c +}{hline 11}{hline 11}{hline 11} + {ralign 12:Total} {c |} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: 100}}} {ralign 9:{res:{sf:{space 9}}}} + + {com}. esttab ., cells("b pct(fmt(2)) cumpct(fmt(2))") noobs + {res} + {txt}{hline 51} + {txt} (1) + {txt} foreign + {txt} b pct cumpct + {txt}{hline 51} + {txt}Domestic {res} 52 70.27 70.27{txt} + {txt}Foreign {res} 22 29.73 100.00{txt} + {txt}Total {res} 74 100.00 {txt} + {txt}{hline 51} + + {com}. estpost tabulate rep78 foreign + + {res}foreign {txt} {c |}{space 44} + {ralign 12:rep78} {c |} {ralign 9:e(b)} {ralign 9:e(pct)} {ralign 9:e(colpct)} {ralign 9:e(rowpct)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11} + {res:{lalign 13:Domestic}}{c |}{space 11}{space 11}{space 11}{space 11} + {ralign 12:1} {c |} {ralign 9:{res:{sf: 2}}} {ralign 9:{res:{sf: 2.898551}}} {ralign 9:{res:{sf: 4.166667}}} {ralign 9:{res:{sf: 100}}} + {ralign 12:2} {c |} {ralign 9:{res:{sf: 8}}} {ralign 9:{res:{sf: 11.5942}}} {ralign 9:{res:{sf: 16.66667}}} {ralign 9:{res:{sf: 100}}} + {ralign 12:3} {c |} {ralign 9:{res:{sf: 27}}} {ralign 9:{res:{sf: 39.13043}}} {ralign 9:{res:{sf: 56.25}}} {ralign 9:{res:{sf: 90}}} + {ralign 12:4} {c |} {ralign 9:{res:{sf: 9}}} {ralign 9:{res:{sf: 13.04348}}} {ralign 9:{res:{sf: 18.75}}} {ralign 9:{res:{sf: 50}}} + {ralign 12:5} {c |} {ralign 9:{res:{sf: 2}}} {ralign 9:{res:{sf: 2.898551}}} {ralign 9:{res:{sf: 4.166667}}} {ralign 9:{res:{sf: 18.18182}}} + {ralign 12:Total} {c |} {ralign 9:{res:{sf: 48}}} {ralign 9:{res:{sf: 69.56522}}} {ralign 9:{res:{sf: 100}}} {ralign 9:{res:{sf: 69.56522}}} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11} + {res:{lalign 13:Foreign}}{c |}{space 11}{space 11}{space 11}{space 11} + {ralign 12:1} {c |} {ralign 9:{res:{sf: 0}}} {ralign 9:{res:{sf: 0}}} {ralign 9:{res:{sf: 0}}} {ralign 9:{res:{sf: 0}}} + {ralign 12:2} {c |} {ralign 9:{res:{sf: 0}}} {ralign 9:{res:{sf: 0}}} {ralign 9:{res:{sf: 0}}} {ralign 9:{res:{sf: 0}}} + {ralign 12:3} {c |} {ralign 9:{res:{sf: 3}}} {ralign 9:{res:{sf: 4.347826}}} {ralign 9:{res:{sf: 14.28571}}} {ralign 9:{res:{sf: 10}}} + {ralign 12:4} {c |} {ralign 9:{res:{sf: 9}}} {ralign 9:{res:{sf: 13.04348}}} {ralign 9:{res:{sf: 42.85714}}} {ralign 9:{res:{sf: 50}}} + {ralign 12:5} {c |} {ralign 9:{res:{sf: 9}}} {ralign 9:{res:{sf: 13.04348}}} {ralign 9:{res:{sf: 42.85714}}} {ralign 9:{res:{sf: 81.81818}}} + {ralign 12:Total} {c |} {ralign 9:{res:{sf: 21}}} {ralign 9:{res:{sf: 30.43478}}} {ralign 9:{res:{sf: 100}}} {ralign 9:{res:{sf: 30.43478}}} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11} + {res:{lalign 13:Total}}{c |}{space 11}{space 11}{space 11}{space 11} + {ralign 12:1} {c |} {ralign 9:{res:{sf: 2}}} {ralign 9:{res:{sf: 2.898551}}} {ralign 9:{res:{sf: 2.898551}}} {ralign 9:{res:{sf: 100}}} + {ralign 12:2} {c |} {ralign 9:{res:{sf: 8}}} {ralign 9:{res:{sf: 11.5942}}} {ralign 9:{res:{sf: 11.5942}}} {ralign 9:{res:{sf: 100}}} + {ralign 12:3} {c |} {ralign 9:{res:{sf: 30}}} {ralign 9:{res:{sf: 43.47826}}} {ralign 9:{res:{sf: 43.47826}}} {ralign 9:{res:{sf: 100}}} + {ralign 12:4} {c |} {ralign 9:{res:{sf: 18}}} {ralign 9:{res:{sf: 26.08696}}} {ralign 9:{res:{sf: 26.08696}}} {ralign 9:{res:{sf: 100}}} + {ralign 12:5} {c |} {ralign 9:{res:{sf: 11}}} {ralign 9:{res:{sf: 15.94203}}} {ralign 9:{res:{sf: 15.94203}}} {ralign 9:{res:{sf: 100}}} + {ralign 12:Total} {c |} {ralign 9:{res:{sf: 69}}} {ralign 9:{res:{sf: 100}}} {ralign 9:{res:{sf: 100}}} {ralign 9:{res:{sf: 100}}} + + {com}. esttab ., cell(colpct(fmt(2))) unstack noobs + {res} + {txt}{hline 51} + {txt} (1) + {txt} + {txt} Domestic Foreign Total + {txt} colpct colpct colpct + {txt}{hline 51} + {txt}1 {res} 4.17 0.00 2.90{txt} + {txt}2 {res} 16.67 0.00 11.59{txt} + {txt}3 {res} 56.25 14.29 43.48{txt} + {txt}4 {res} 18.75 42.86 26.09{txt} + {txt}5 {res} 4.17 42.86 15.94{txt} + {txt}Total {res} 100.00 100.00 100.00{txt} + {txt}{hline 51} + + {com}. esttab ., cell(colpct(fmt(2)) count(fmt(g) par keep(Total))) /// + > collabels(none) unstack noobs nonumber nomtitle /// + > eqlabels(, lhs("Repair Rec.")) /// + > varlabels(, blist(Total "{c -(}hline @width{c )-}{c -(}break{c )-}")) + {res} + {txt}{hline 51} + {txt}Repair Rec. Domestic Foreign Total + {txt}{hline 51} + {txt}1 {res} 4.17 0.00 2.90{txt} + {txt}2 {res} 16.67 0.00 11.59{txt} + {txt}3 {res} 56.25 14.29 43.48{txt} + {txt}4 {res} 18.75 42.86 26.09{txt} + {txt}5 {res} 4.17 42.86 15.94{txt} + {txt}{hline 51}{break} Total {res} 100.00 100.00 100.00{txt} + {res} {txt} + {txt}{hline 51} +{* end example }{txt}{...} + +{marker svy_tabulate} +{dlgtab:svy: tabulate} + +{p 4 4 2}One-way table: + +{p 8 15 2} +{cmd:estpost} {cmd:svy} [{it:vcetype}] [, {it:svy_options}] {cmd::} {cmdab:ta:bulate} + {it:varname} [{it:{help if}}] [{it:{help in}}] + [{cmd:,} + {cmdab:notot:al} + {cmdab:q:uietly} + {cmdab:es:ample} + {help svy_tabulate_oneway:{it:svy_tabulate_opts}} + ] + +{p 4 4 2}Two-way table: + +{p 8 15 2} +{cmd:estpost} {cmd:svy} [{it:vcetype}] [, {it:svy_options}] {cmd::} {cmdab:ta:bulate} + {it:varname1} {it:varname2} [{it:{help if}}] [{it:{help in}}] + [{cmd:,} + {cmdab:notot:al} + {cmdab:q:uietly} + {cmdab:es:ample} + {help svy_tabulate_oneway:{it:svy_tabulate_opts}} + ] + +{p 4 4 2} + {cmd:estpost svy: tabulate} posts a one-way or two-way table + for complex survey data computed by {helpb svy_tabulate:svy: tabulate}. Stata 9 or newer + is required. + +{p 4 4 2} + Options are as described in {helpb svy_tabulate_oneway:[SVY] svy: tabulate oneway} or + {helpb svy_tabulate_twoway:[SVY] svy: tabulate twoway}, respectively, and: + +{p 8 12 2} + {cmdab:nototal} to omit row and column totals (synonym for {cmd:nomarginals}). + +{p 8 12 2} + {cmd:quietly} to suppress the output. + +{p 8 12 2} + {cmd:esample} to mark the estimation sample in {cmd:e(sample)}. + +{p 4 4 2}{cmd:estpost svy: tabulate} posts results in {cmd:e()} (except {cmd:e(V)}) +as documented in {helpb svy_tabulate_oneway:[SVY] svy: tabulate oneway} and +{helpb svy_tabulate_twoway:[SVY] svy: tabulate twoway}, respectively, +and adds or replaces the following matrices: + + {lalign 10:{cmd:e(b)}}cell, column, or row proportions or percentages, + or weighted counts, depending on options + {lalign 10:{cmd:e(se)}}standard errors of {cmd:e(b)} + {lalign 10:{cmd:e(lb)}}lower confidence bounds for {cmd:e(b)} + {lalign 10:{cmd:e(ub)}}upper confidence bounds for {cmd:e(b)} + {lalign 10:{cmd:e(deff)}}deff for variances of {cmd:e(b)} + {lalign 10:{cmd:e(deft)}}deft for variances of {cmd:e(b)} + {lalign 10:{cmd:e(cell)}}cell proportion or percentages + {lalign 10:{cmd:e(row)}}row proportion or percentages (two-way only) + {lalign 10:{cmd:e(col)}}column proportion or percentages (two-way only) + {lalign 10:{cmd:e(count)}}weighted counts + {lalign 10:{cmd:e(obs)}}number of observations + +{p 4 4 2}The value labels of the row variable are stored as names in the +saved vectors, unless +no label exceeds 30 characters or contains unsuitable characters in which case +the labels are stored in macro {cmd:e(labels)}. Type +{cmd:varlabels(`e(labels)')} in {helpb esttab} or {helpb estout} to +use the labels stored {cmd:e(labels)}. The value labels of the column variable +are stored as equation names or, alternatively, +in macro {cmd:e(eqlabels)}. Type {cmd:eqlabels(`e(eqlabels)')} in +{helpb esttab} or {helpb estout} to use the labels stored in {cmd:e(eqlabels)}. + +{p 4 4 2}Examples: + +{* begin example svy_tabulate }{...} + {com}. webuse nhanes2b, clear + {txt} + {com}. svyset psuid [pweight=finalwgt], strata(stratid) + + {txt}pweight:{col 16}{res}finalwgt + {txt}VCE:{col 16}{res}linearized + {txt}Single unit:{col 16}{res}missing + {txt}Strata 1:{col 16}{res}stratid + {txt}SU 1:{col 16}{res}psuid + {txt}FPC 1:{col 16} + {p2colreset}{...} + + {com}. estpost svy: tabulate race + {txt}(running tabulate on estimation sample) + + {col 1}Number of strata{col 20}= {res} 31{txt}{col 48}Number of obs{col 67}= {res} 10351 + {txt}{col 1}Number of PSUs{col 20}= {res} 62{txt}{col 48}Population size{col 67}={res} 117157513 + {txt}{col 48}Design df{col 67}= {res} 31 + + {txt}{hline 10}{c TT}{hline 12} + 1=white, {c |} + 2=black, {c |} + 3=other {c |} proportions + {hline 10}{c +}{hline 12} + White {c |} {res}.8792 + {txt}Black {c |} {res}.0955 + {txt}Other {c |} {res}.0253 + {txt}{c |} + Total {c |} {res}1 + {txt}{hline 10}{c BT}{hline 12} + Key: {col 1}proportions = {res}cell proportions + + {txt}saved vectors: + e(b) = {res}cell proportions + {txt}e(se) = {res}standard errors of cell proportions + {txt}e(lb) = {res}lower 95% confidence bounds for cell proportions + {txt}e(ub) = {res}upper 95% confidence bounds for cell proportions + {txt}e(deff) = {res}deff for variances of cell proportions + {txt}e(deft) = {res}deft for variances of cell proportions + {txt}e(cell) = {res}cell proportions + {txt}e(count) = {res}weighted counts + {txt}e(obs) = {res}number of observations + {txt} + {com}. esttab ., cell("b(f(4)) se deft") + {res} + {txt}{hline 51} + {txt} (1) + {txt} + {txt} b se deft + {txt}{hline 51} + {txt}White {res} 0.8792 0.0167 5.2090{txt} + {txt}Black {res} 0.0955 0.0127 4.4130{txt} + {txt}Other {res} 0.0253 0.0105 6.8246{txt} + {txt}Total {res} 1.0000 0.0000 {txt} + {txt}{hline 51} + {txt}N {res} 10351 {txt} + {txt}{hline 51} + + {com}. estpost svy: tabulate race diabetes, row percent + {txt}(running tabulate on estimation sample) + + {col 1}Number of strata{col 20}= {res} 31{txt}{col 48}Number of obs{col 67}= {res} 10349 + {txt}{col 1}Number of PSUs{col 20}= {res} 62{txt}{col 48}Population size{col 67}={res} 117131111 + {txt}{col 48}Design df{col 67}= {res} 31 + + {txt}{hline 10}{c TT}{hline 20} + 1=white, {c |} diabetes, 1=yes, + 2=black, {c |} 0=no + 3=other {c |} 0 1 Total + {hline 10}{c +}{hline 20} + White {c |} {res}96.8 3.195 100 + {txt}Black {c |} {res}94.1 5.903 100 + {txt}Other {c |} {res}97.97 2.034 100 + {txt}{c |} + Total {c |} {res}96.58 3.425 100 + {txt}{hline 10}{c BT}{hline 20} + Key: {col 1}{res}row percentages + + {txt} Pearson: + {col 5}Uncorrected{col 19}chi2({res}2{txt}){col 35}= {res} 21.3483 + {txt}{col 5}Design-based{col 19}F({res}1.52{txt}, {res}47.26{txt}){col 35}= {res} 15.0056{col 51}{txt}P = {res}0.0000 + + {txt}saved vectors: + e(b) = {res}row percentages + {txt}e(se) = {res}standard errors of row percentages + {txt}e(lb) = {res}lower 95% confidence bounds for row percentages + {txt}e(ub) = {res}upper 95% confidence bounds for row percentages + {txt}e(deff) = {res}deff for variances of row percentages + {txt}e(deft) = {res}deft for variances of row percentages + {txt}e(cell) = {res}cell percentages + {txt}e(row) = {res}row percentages + {txt}e(col) = {res}column percentages + {txt}e(count) = {res}weighted counts + {txt}e(obs) = {res}number of observations + {txt} + {com}. esttab ., b(2) se(2) scalars(F_Pear) nostar unstack /// + > mtitle(`e(colvar)') + {res} + {txt}{hline 51} + {txt} (1) + {txt} diabetes + {txt} 0 1 Total + {txt}{hline 51} + {txt}White {res} 96.80 3.20 100.00{txt} + {res} {ralign 12:{txt:(}0.20{txt:)}} {ralign 12:{txt:(}0.20{txt:)}} {txt} + + {txt}Black {res} 94.10 5.90 100.00{txt} + {res} {ralign 12:{txt:(}0.61{txt:)}} {ralign 12:{txt:(}0.61{txt:)}} {txt} + + {txt}Other {res} 97.97 2.03 100.00{txt} + {res} {ralign 12:{txt:(}0.76{txt:)}} {ralign 12:{txt:(}0.76{txt:)}} {txt} + + {txt}Total {res} 96.58 3.42 100.00{txt} + {res} {ralign 12:{txt:(}0.18{txt:)}} {ralign 12:{txt:(}0.18{txt:)}} {txt} + {txt}{hline 51} + {txt}N {res} 10349 {txt} + {txt}F_Pear {res} 15.01 {txt} + {txt}{hline 51} + {txt}Standard errors in parentheses +{* end example }{txt}{...} + +{marker correlate} +{dlgtab:correlate} + +{p 4 15 2} +{cmd:estpost} {cmdab:cor:relate} + {it:{help varlist}} [{it:{help if}}] [{it:{help in}}] [{it:{help weight}}] + [{cmd:,} + {cmdab:m:atrix} + {cmdab:noh:alf} + {cmdab:print:(}{it:#}{cmd:)} + {cmdab:b:onferroni} + {cmdab:sid:ak} + {cmdab:list:wise} + {cmdab:case:wise} + {cmdab:q:uietly} + {cmdab:es:ample} + ] + +{p 4 4 2} + posts the pairwise correlations between the first variable in + {it:varlist} and the remaining variables. Alternatively, if the + {cmd:matrix} option is specified, all pairwise correlations among the + variable in {it:varlist} are posted. + +{p 4 4 2} + {cmd:aweight}s, {cmd:fweight}s, + {cmd:iweight}s and {cmd:pweight}s are allowed; see {help weight}. + +{p 4 4 2} + Methods and formulas are as described in + {helpb correlate:{bind:[R] correlate}}. However, if {cmd:pweight}s + are specified, the p-values of the correlations are computed + as suggested in the Stata FAQ on + {browse "http://www.stata.com/support/faqs/stat/survey.html":"Estimating correlations with survey data"}. + +{p 4 4 2} + Options are: + +{p 8 12 2} + {cmd:matrix} to return the (lower triangle) of the correlation + matrix of the variables in {it:varlist}. The default is to return + the pairwise correlations between the first variable in + {it:varlist} and the remaining variables. + +{p 8 12 2} + {cmd:nohalf} to return the full correlation matrix rather than just + the lower triangle. {cmd:nohalf} has no effect unless {cmd:matrix} + is specified. + +{p 8 12 2} + {cmd:print(}{it:#}{cmd:)} to suppress (leave blank) + correlation coefficients with a p-value larger than + {it:#}. {cmd:print()} only affects what is saved in + {cmd:e(rho)}, {cmd:e(p)}, and {cmd:e(count)}, but + not what is saved in {cmd:e(b)}. + +{p 8 12 2} + {cmd:bonferroni} to apply the Bonferroni adjustment to the + p-values. + +{p 8 12 2} + {cmd:sidak} to apply the Sidak adjustment to the + p-values. + +{p 8 12 2} + {cmd:listwise} to handle missing values through listwise deletion, + meaning that an observation is omitted from the estimation sample + if any of the variables in {it:varlist} is missing for that + observation. The default is to handle missing values by pairwise + deletion, i.e. all available observations are used to calculate a + pairwise correlation without regard to whether variables outside + that pair are missing. {cmd:casewise} is a synonym for + {cmd:listwise}. + +{p 8 12 2} + {cmd:quietly} to suppress the output. + +{p 8 12 2} + {cmd:esample} to mark the estimation sample in {cmd:e(sample)}. + +{p 4 4 2}The following vectors are saved in {cmd:e()}: + + {lalign 13:{cmd:e(b)}}correlation coefficients + {lalign 13:{cmd:e(rho)}}correlation coefficients + {lalign 13:{cmd:e(p)}}p-values + {lalign 13:{cmd:e(count)}}number of observations + +{p 4 4 2}Examples: + +{* begin example correlate }{...} + {com}. sysuse auto, clear + {txt}(1978 Automobile Data) + + {com}. estpost correlate price mpg turn foreign, matrix + + {txt}{ralign 12:} {c |} {ralign 9:e(b)} {ralign 9:e(rho)} {ralign 9:e(p)} {ralign 9:e(count)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11} + {res:{lalign 13:price}}{c |}{space 11}{space 11}{space 11}{space 11} + {ralign 12:price} {c |} {ralign 9:{res:{sf: 1}}} {ralign 9:{res:{sf: 1}}} {ralign 9:{res:{sf:{space 9}}}} {ralign 9:{res:{sf: 74}}} + {ralign 12:mpg} {c |} {ralign 9:{res:{sf:-.4685967}}} {ralign 9:{res:{sf:-.4685967}}} {ralign 9:{res:{sf: .0000255}}} {ralign 9:{res:{sf: 74}}} + {ralign 12:turn} {c |} {ralign 9:{res:{sf: .3096174}}} {ralign 9:{res:{sf: .3096174}}} {ralign 9:{res:{sf: .0072662}}} {ralign 9:{res:{sf: 74}}} + {ralign 12:foreign} {c |} {ralign 9:{res:{sf: .0487195}}} {ralign 9:{res:{sf: .0487195}}} {ralign 9:{res:{sf: .6801851}}} {ralign 9:{res:{sf: 74}}} + {res:{lalign 13:mpg}}{c |}{space 11}{space 11}{space 11}{space 11} + {ralign 12:mpg} {c |} {ralign 9:{res:{sf: 1}}} {ralign 9:{res:{sf: 1}}} {ralign 9:{res:{sf:{space 9}}}} {ralign 9:{res:{sf: 74}}} + {ralign 12:turn} {c |} {ralign 9:{res:{sf:-.7191863}}} {ralign 9:{res:{sf:-.7191863}}} {ralign 9:{res:{sf: 5.30e-13}}} {ralign 9:{res:{sf: 74}}} + {ralign 12:foreign} {c |} {ralign 9:{res:{sf: .3933974}}} {ralign 9:{res:{sf: .3933974}}} {ralign 9:{res:{sf: .0005254}}} {ralign 9:{res:{sf: 74}}} + {res:{lalign 13:turn}}{c |}{space 11}{space 11}{space 11}{space 11} + {ralign 12:turn} {c |} {ralign 9:{res:{sf: 1}}} {ralign 9:{res:{sf: 1}}} {ralign 9:{res:{sf:{space 9}}}} {ralign 9:{res:{sf: 74}}} + {ralign 12:foreign} {c |} {ralign 9:{res:{sf:-.6310965}}} {ralign 9:{res:{sf:-.6310965}}} {ralign 9:{res:{sf: 1.66e-09}}} {ralign 9:{res:{sf: 74}}} + {res:{lalign 13:foreign}}{c |}{space 11}{space 11}{space 11}{space 11} + {ralign 12:foreign} {c |} {ralign 9:{res:{sf: 1}}} {ralign 9:{res:{sf: 1}}} {ralign 9:{res:{sf:{space 9}}}} {ralign 9:{res:{sf: 74}}} + + {com}. esttab ., not unstack compress noobs + {res} + {txt}{hline 62} + {txt} (1) + {txt} + {txt} price mpg turn foreign + {txt}{hline 62} + {txt}price {res} 1 {txt} + {txt}mpg {res} -0.469*** 1 {txt} + {txt}turn {res} 0.310** -0.719*** 1 {txt} + {txt}foreign {res} 0.0487 0.393*** -0.631*** 1 {txt} + {txt}{hline 62} + {txt}* p<0.05, ** p<0.01, *** p<0.001 + + {com}. bysort foreign: eststo: /// + > estpost correlate price turn weight rep78, listwise + + {txt}{hline 60} + -> Domestic + + {ralign 12:price} {c |} {ralign 9:e(b)} {ralign 9:e(rho)} {ralign 9:e(p)} {ralign 9:e(count)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:turn} {c |} {ralign 9:{res:{sf: .4328091}}} {ralign 9:{res:{sf: .4328091}}} {ralign 9:{res:{sf: .0021229}}} {ralign 9:{res:{sf: 48}}} + {ralign 12:weight} {c |} {ralign 9:{res:{sf: .6864719}}} {ralign 9:{res:{sf: .6864719}}} {ralign 9:{res:{sf: 7.19e-08}}} {ralign 9:{res:{sf: 48}}} + {ralign 12:rep78} {c |} {ralign 9:{res:{sf:-.0193249}}} {ralign 9:{res:{sf:-.0193249}}} {ralign 9:{res:{sf: .8962741}}} {ralign 9:{res:{sf: 48}}} + ({res}est1{txt} stored) + + {hline 60} + -> Foreign + + {ralign 12:price} {c |} {ralign 9:e(b)} {ralign 9:e(rho)} {ralign 9:e(p)} {ralign 9:e(count)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:turn} {c |} {ralign 9:{res:{sf: .5102425}}} {ralign 9:{res:{sf: .5102425}}} {ralign 9:{res:{sf: .0181155}}} {ralign 9:{res:{sf: 21}}} + {ralign 12:weight} {c |} {ralign 9:{res:{sf: .8315886}}} {ralign 9:{res:{sf: .8315886}}} {ralign 9:{res:{sf: 2.99e-06}}} {ralign 9:{res:{sf: 21}}} + {ralign 12:rep78} {c |} {ralign 9:{res:{sf: .1797879}}} {ralign 9:{res:{sf: .1797879}}} {ralign 9:{res:{sf: .4354917}}} {ralign 9:{res:{sf: 21}}} + ({res}est2{txt} stored) + + {com}. esttab est1 est2, not mtitles + {res} + {txt}{hline 44} + {txt} (1) (2) + {txt} Domestic Foreign + {txt}{hline 44} + {txt}turn {res} 0.433** 0.510* {txt} + {txt}weight {res} 0.686*** 0.832***{txt} + {txt}rep78 {res} -0.0193 0.180 {txt} + {txt}{hline 44} + {txt}N {res} 48 21 {txt} + {txt}{hline 44} + {txt}* p<0.05, ** p<0.01, *** p<0.001 +{* end example }{txt}{...} + +{marker ci} +{dlgtab:ci} + +{p 4 15 2} +{cmd:estpost} {cmdab:ci} + [{it:{help varlist}}] [{it:{help if}}] [{it:{help in}}] [{it:{help weight}}] + [{cmd:,} + {cmdab:b:inomial} + {cmdab:p:oisson} {cmdab:e:xposure:(}{it:varname}{cmd:)} + {cmdab:ex:act} {cmdab:wa:ld} {cmdab:w:ilson} {cmdab:a:gresti} {cmdab:j:effreys} + {cmdab:l:evel:(}{it:#}{cmd:)} + {cmdab:list:wise} + {cmdab:case:wise} + {cmdab:q:uietly} + {cmdab:es:ample} + ] + +{p 4 4 2} + posts standard errors and confidence intervals computed by + {helpb ci}. {cmd:aweight}s and {cmd:fweight}s are allowed, + but {cmd:aweight}s may not be specified with options + {cmd:binomial} or {cmd:poisson}; + see {help weight}. + +{p 4 4 2} + Options are: + +{p 8 12 2} + {cmd:binomial}, {cmd:poisson}, {cmd:exposure()}, + {cmd:exact}, {cmd:wald}, {cmd:wilson}, {cmd:agresti}, + {cmd:jeffreys}, and {cmd:level()} + as described in help {helpb ci}. + +{p 8 12 2} + {cmd:listwise} to handle missing values through listwise deletion, + meaning that an observation is omitted from the estimation + sample if any of the variables in {it:varlist} is missing for that + observation. The default is to determine the used observations for + each variable separately without regard to whether other variables + are missing. {cmd:casewise} is a synonym for {cmd:listwise}. + +{p 8 12 2} + {cmd:quietly} to suppress the output. + +{p 8 12 2} + {cmd:esample} to mark the estimation sample in {cmd:e(sample)}. + +{p 4 4 2}The following results vectors are saved in {cmd:e()}: + + {lalign 13:{cmd:e(b)}}mean + {lalign 13:{cmd:e(count)}}number of observations + {lalign 13:{cmd:e(se)}}estimate of standard error + {lalign 13:{cmd:e(lb)}}lower bound of confidence interval + {lalign 13:{cmd:e(ub)}}upper bound of confidence interval + +{p 4 4 2} + Examples: + +{* begin example ci }{...} + {com}. sysuse auto, clear + {txt}(1978 Automobile Data) + + {com}. estpost ci price mpg rep78, listwise + {txt}(confidence level is 95%) + + {ralign 12:} {c |} {ralign 9:e(b)} {ralign 9:e(count)} {ralign 9:e(se)} {ralign 9:e(lb)} {ralign 9:e(ub)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:price} {c |} {ralign 9:{res:{sf: 6146.043}}} {ralign 9:{res:{sf: 69}}} {ralign 9:{res:{sf: 350.6166}}} {ralign 9:{res:{sf: 5446.399}}} {ralign 9:{res:{sf: 6845.688}}} + {ralign 12:mpg} {c |} {ralign 9:{res:{sf: 21.28986}}} {ralign 9:{res:{sf: 69}}} {ralign 9:{res:{sf: .7062326}}} {ralign 9:{res:{sf: 19.88059}}} {ralign 9:{res:{sf: 22.69912}}} + {ralign 12:rep78} {c |} {ralign 9:{res:{sf: 3.405797}}} {ralign 9:{res:{sf: 69}}} {ralign 9:{res:{sf: .1191738}}} {ralign 9:{res:{sf: 3.167989}}} {ralign 9:{res:{sf: 3.643605}}} + + {com}. esttab ., cells("b lb ub") label + {res} + {txt}{hline 59} + {txt} (1) + {txt} + {txt} b lb ub + {txt}{hline 59} + {txt}Price {res} 6146.043 5446.399 6845.688{txt} + {txt}Mileage (mpg) {res} 21.28986 19.88059 22.69912{txt} + {txt}Repair Record 1978 {res} 3.405797 3.167989 3.643605{txt} + {txt}{hline 59} + {txt}Observations {res} 69 {txt} + {txt}{hline 59} + + {com}. eststo exact: estpost ci foreign, binomial exact + {txt}(confidence level is 95%) + + {ralign 12:} {c |} {ralign 9:e(b)} {ralign 9:e(count)} {ralign 9:e(se)} {ralign 9:e(lb)} {ralign 9:e(ub)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:foreign} {c |} {ralign 9:{res:{sf: .2972973}}} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: .0531331}}} {ralign 9:{res:{sf: .196584}}} {ralign 9:{res:{sf: .4148353}}} + + {com}. eststo agresti: estpost ci foreign, binomial agresti + {txt}(confidence level is 95%) + + {ralign 12:} {c |} {ralign 9:e(b)} {ralign 9:e(count)} {ralign 9:e(se)} {ralign 9:e(lb)} {ralign 9:e(ub)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:foreign} {c |} {ralign 9:{res:{sf: .2972973}}} {ralign 9:{res:{sf: 74}}} {ralign 9:{res:{sf: .0531331}}} {ralign 9:{res:{sf: .204807}}} {ralign 9:{res:{sf: .4097942}}} + + {com}. esttab exact agresti, cells(lb ub) mtitles + {res} + {txt}{hline 38} + {txt} (1) (2) + {txt} exact agresti + {txt} lb/ub lb/ub + {txt}{hline 38} + {txt}foreign {res} .196584 .204807{txt} + {res} .4148353 .4097942{txt} + {txt}{hline 38} + {txt}N {res} 74 74{txt} + {txt}{hline 38} +{* end example }{txt}{...} + +{marker stci} +{dlgtab:stci} + +{p 4 15 2} +{cmd:estpost} {cmd:stci} + [{it:{help if}}] [{it:{help in}}] + [{cmd:,} + {cmd:by(}{it:groupvar}{cmd:)} + {cmdab:m:edian} + {cmdab:r:mean} + {cmdab:e:mean} + {cmd:p(}{it:#}{cmd:)} + {cmdab:cc:orr} + {cmdab:l:evel:(}{it:#}{cmd:)} + {cmdab:q:uietly} + {cmdab:es:ample} + ] + +{p 4 4 2} + posts confidence intervals for means + and percentiles of survival time computed by {helpb stci}. Stata 9 or + newer is required. + +{p 4 4 2} + Options are: + +{p 8 12 2} + {cmd:by(}{it:groupvar}{cmd:)} + to report separate summaries for each group defined by + {it:groupvar}, along with an overall total. + +{p 8 12 2} + {cmd:median}, + {cmd:rmean}, + {cmd:emean}, + {cmd:p()}, + {cmd:ccorr}, and + {cmd:level()} + as described in help {helpb stci}. + +{p 8 12 2} + {cmd:quietly} to suppress the output. + +{p 8 12 2} + {cmd:esample} to mark the estimation sample in {cmd:e(sample)}. + +{p 4 4 2}The following vectors are saved in {cmd:e()}: + + {lalign 13:{cmd:e(count)}}number of subjects + {lalign 13:{cmd:e(p50)}}median (if {cmd:median} specified; the default) + {lalign 13:{cmd:e(p}{it:#}{cmd:)}}#th percentile (if {cmd:p(}{it:#}{cmd:)} specified) + {lalign 13:{cmd:e(rmean)}}restricted mean (if {cmd:rmean} specified) + {lalign 13:{cmd:e(emean)}}extended mean (if {cmd:emean} specified) + {lalign 13:{cmd:e(se)}}standard error + {lalign 13:{cmd:e(lb)}}lower bound of CI + {lalign 13:{cmd:e(ub)}}upper bound of CI + +{p 4 4 2} + Examples: + +{* begin example stci }{...} + {com}. webuse page2, clear + {txt} + {com}. estpost stci + {txt}(confidence level is 95%) + + {ralign 12:} {c |} {ralign 9:e(count)} {ralign 9:e(p50)} {ralign 9:e(se)} {ralign 9:e(lb)} {ralign 9:e(ub)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:total} {c |} {ralign 9:{res:{sf: 40}}} {ralign 9:{res:{sf: 232}}} {ralign 9:{res:{sf: 2.562933}}} {ralign 9:{res:{sf: 213}}} {ralign 9:{res:{sf: 239}}} + + {com}. esttab ., cell("count p50 se lb ub") noobs compress + {res} + {txt}{hline 60} + {txt} (1) + {txt} + {txt} count p50 se lb ub + {txt}{hline 60} + {txt}total {res} 40 232 2.562933 213 239{txt} + {txt}{hline 60} + + {com}. estpost stci, by(group) + {txt}(confidence level is 95%) + + {ralign 12:} {c |} {ralign 9:e(count)} {ralign 9:e(p50)} {ralign 9:e(se)} {ralign 9:e(lb)} {ralign 9:e(ub)} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:1} {c |} {ralign 9:{res:{sf: 19}}} {ralign 9:{res:{sf: 216}}} {ralign 9:{res:{sf: 5.171042}}} {ralign 9:{res:{sf: 190}}} {ralign 9:{res:{sf: 234}}} + {ralign 12:2} {c |} {ralign 9:{res:{sf: 21}}} {ralign 9:{res:{sf: 233}}} {ralign 9:{res:{sf: 2.179595}}} {ralign 9:{res:{sf: 232}}} {ralign 9:{res:{sf: 280}}} + {hline 13}{c +}{hline 11}{hline 11}{hline 11}{hline 11}{hline 11} + {ralign 12:total} {c |} {ralign 9:{res:{sf: 40}}} {ralign 9:{res:{sf: 232}}} {ralign 9:{res:{sf: 2.562933}}} {ralign 9:{res:{sf: 213}}} {ralign 9:{res:{sf: 239}}} + + {com}. esttab ., cell("count p50 se lb ub") noobs compress + {res} + {txt}{hline 60} + {txt} (1) + {txt} + {txt} count p50 se lb ub + {txt}{hline 60} + {txt}1 {res} 19 216 5.171042 190 234{txt} + {txt}2 {res} 21 233 2.179595 232 280{txt} + {txt}total {res} 40 232 2.562933 213 239{txt} + {txt}{hline 60} +{* end example }{txt}{...} + +{marker margins} +{dlgtab:margins} + +{p 4 15 2} +{cmd:estpost} {cmd:margins} + [{it:{help fvvarlist:marginlist}}] [{it:{help if}}] [{it:{help in}}] [{it:{help weight}}] + [{cmd:,} + {cmdab:q:uietly} + {it:{help margins:margins_opions}} + ] + +{p 4 4 2} + posts results from the {helpb margins} command, that was introduced in + Stata 11. + +{p 4 4 2} + Options are: + +{p 8 12 2} + {cmd:quietly} to suppress the output. + +{p 8 12 2} + {it:margins_opions} as described in help {helpb margins} (except {cmd:post}). + +{p 4 4 2}{cmd:estpost margins} replaces the current {cmd:e(b)} and +{cmd:e(V)} with {cmd:r(b)} and {cmd:r(V)} from {helpb margins} and +also copies all other matrixes, scalars, and macros from {helpb margins} into +{cmd:e()} (possibly replacing identically named existing entries). + +{p 4 4 2} + Examples: + +{* begin example margins }{...} + {com}. sysuse auto, clear + {txt}(1978 Automobile Data) + + {com}. quietly logit foreign price mpg weight + {txt} + {com}. estpost margins, dydx(*) quietly + {txt} + {com}. esttab ., cell("b se") pr2 + {res} + {txt}{hline 38} + {txt} (1) + {txt} foreign + {txt} b se + {txt}{hline 38} + {txt}price {res} .0000686 .0000136{txt} + {txt}mpg {res} -.0089607 .006596{txt} + {txt}weight {res} -.0005069 .000055{txt} + {txt}{hline 38} + {txt}N {res} 74 {txt} + {txt}pseudo R-sq {res} 0.619 {txt} + {txt}{hline 38} +{* end example }{txt}{...} + + +{title:Author} + +{p 4 4 2} Ben Jann, ETH Zurich, jannb@ethz.ch + + +{title:Also see} + + Manual: {hi:[R] estimates} + +{p 4 13 2}Online: help for + {helpb estimates}, + {helpb estout}, + {helpb esttab}, + {helpb eststo}, + {helpb estadd} +{p_end} diff --git a/Modules/ado/plus/e/eststo.ado b/Modules/ado/plus/e/eststo.ado new file mode 100644 index 0000000..6298d71 --- /dev/null +++ b/Modules/ado/plus/e/eststo.ado @@ -0,0 +1,343 @@ +*! version 1.1.0 05nov2008 Ben Jann + +program define eststo, byable(onecall) + version 8.2 + local caller : di _caller() +// --- eststo clear --- + if `"`1'"'=="clear" { + if `"`0'"'!="clear" { + di as err "invalid syntax" + exit 198 + } + if "`_byvars'"!="" error 190 + _eststo_clear + exit + } +// --- update globals --- + _eststo_cleanglobal +// --- eststo dir --- + if `"`1'"'=="dir" { + if `"`0'"'!="dir" { + di as err "invalid syntax" + exit 198 + } + if "`_byvars'"!="" error 190 + _eststo_dir + exit + } +// --- eststo drop --- + if `"`1'"'=="drop" { + if "`_byvars'"!="" error 190 + _eststo_`0' + exit + } +// --- eststo store (no by) --- + if "`_byvars'"=="" { + version `caller': _eststo_store `0' + exit + } +// --- eststo store (by) --- +// - check sorting + local sortedby : sortedby + local i 0 + foreach byvar of local _byvars { + local sortedbyi : word `++i' of `sortedby' + if "`byvar'"!="`sortedbyi'" error 5 + } +// - parse command on if qualified + capt _on_colon_parse `0' + if _rc error 190 + if `"`s(after)'"'=="" error 190 + local estcom `"`s(after)'"' + local 0 `"`s(before)'"' + if substr(trim(`"`estcom'"'),1,3)=="svy" { + di as err "svy commands not allowed with by ...: eststo:" + exit 190 + } + AddBygrpToIfqualifier `estcom' +// - parse syntax of _eststo_store call in order to determine +// whether title() or missing was specified (note that +// -estimates change- cannot be used to set the titles since +// it does not work with -noesample-) + TitleAndMissing `0' +// - generate byindex + tempname _byindex + qui egen long `_byindex' = group(`_byvars'), label `missing' + qui su `_byindex', meanonly + if r(N)==0 error 2000 + local Nby = r(max) +// - loop over bygroups + forv i = 1/`Nby' { + local ibylab: label (`_byindex') `i' + di as txt _n "{hline}" + di as txt `"-> `ibylab'"' // could be improved + if `titleopt'==0 local ibytitle + else if `titleopt'==1 local ibytitle `" title(`ibylab')"' + else if `titleopt'==2 local ibytitle `", title(`ibylab')"' + capture noisily { + version `caller': _eststo_store `0'`ibytitle' : `estcmd' + } + if _rc { + if "`_byrc0'"=="" error _rc + } + } +end + +prog TitleAndMissing + capt syntax [anything] , Title(string) [ MISsing * ] + if _rc==0 { + c_local titleopt 0 + c_local missing "`missing'" + } + else { + syntax [anything] [ , MISsing * ] + if `"`missing'`options'"'!="" c_local titleopt 1 + else c_local titleopt 2 + c_local missing "`missing'" + } +end + +program AddBygrpToIfqualifier + syntax anything(equalok) [if/] [in] [using] [fw aw pw iw] [, * ] + local estcom `"`macval(anything)' if (\`_byindex'==\`i')"' + if `"`macval(if)'"'!="" { + local estcom `"`macval(estcom)' & (`macval(if)')"' + } + if `"`macval(in)'"'!="" { + local estcom `"`macval(estcom)' `macval(in)'"' + } + if `"`macval(using)'"'!="" { + local estcom `"`macval(estcom)' `macval(using)'"' + } + if `"`macval(weight)'"'!="" { + local estcom `"`macval(estcom)' [`macval(weight)'`macval(exp)']"' + } + if `"`macval(options)'"'!="" { + local estcom `"`macval(estcom)', `macval(options)'"' + } + c_local estcmd `"`macval(estcom)'"' +end + +program define _eststo_clear + local names $eststo + foreach name of local names { + capt estimates drop `name' + } + global eststo + global eststo_counter +end + +program define _eststo_dir + if `"$eststo"'!="" { + estimates dir $eststo + } +end + +program define _eststo_cleanglobal + local enames $eststo + if `"`enames'"'!="" { + tempname hcurrent + _return hold `hcurrent' + qui _estimates dir + local snames `r(names)' + _return restore `hcurrent' + } + local names: list enames & snames + global eststo `names' + if "`names'"=="" global eststo_counter +end + +program define _eststo_drop + local droplist `0' + if `"`droplist'"'=="" { + di as error "someting required" + exit 198 + } + local names $eststo + foreach item of local droplist { + capt confirm integer number `item' + if _rc { + local dropname `item' + } + else { + if `item'<1 { + di as error "`item' not allowed" + exit 198 + } + local dropname est`item' + } + local found 0 + foreach name in `names' { + if match("`name'",`"`dropname'"') { + local found 1 + estimates drop `name' + local names: list names - name + di as txt "(" as res "`name'" as txt " dropped)" + } + } + if `found'==0 { + di as txt "(no matches found for " as res `"`dropname'"' as txt ")" + } + } + global eststo `names' +end + + +program define _eststo_store, eclass + local caller : di _caller() + capt _on_colon_parse `0' + if !_rc { + local command `"`s(after)'"' + local 0 `"`s(before)'"' + } + syntax [name] [, /// + Title(passthru) /// + Prefix(name) /// + Refresh Refresh2(numlist integer max=1 >0) /// + ADDscalars(string asis) /// + noEsample /// + noCopy /// + MISsing svy /// doesn't do anything + ] + if `"`prefix'"'=="" local prefix "est" + +// get previous eststo names and counter + local names $eststo + local counter $eststo_counter + if `"`counter'"'=="" local counter 0 + +// if name provided; set refresh on if name already in list + if "`namelist'"!="" { + if "`refresh2'"!="" { + di as error "refresh() not allowed" + exit 198 + } + local name `namelist' + if `:list name in names' local refresh refresh + else { + if "`refresh'"!="" { + di as txt "(" as res "`name'" as txt " not found)" + } + local refresh + } + if "`refresh'"=="" local ++counter + } +// if no name provided + else { + if "`refresh2'"!="" local refresh refresh + if "`refresh'"!="" { +// refresh2 not provided => refresh last (if available) + if "`refresh2'"=="" { + if "`names'"=="" { + di as txt "(nothing to refresh)" + local refresh + } + else local name: word `:list sizeof names' of `names' + } +// refresh2 provided => check availability + else { + if `:list posof "`prefix'`refresh2'" in names' { + local name `prefix'`refresh2' + } + else { + di as txt "(" as res "`prefix'`refresh2'" as txt " not found)" + local refresh + } + } + } + if "`refresh'"=="" local ++counter +// set default name + if "`name'"=="" local name `prefix'`counter' + } + +// run estimation command if provided + if `"`command'"'!="" { + version `caller': `command' + } + +// add scalars to e() + if `"`addscalars'"'!="" { + capt ParseAddscalars `addscalars' + if _rc { + di as err `"addscalars() invalid"' + exit 198 + } + if "`replace'"=="" { + local elist `: e(scalars)' `: e(macros)' `: e(matrices)' `: e(functions)' + } + local forbidden b V sample + while (1) { + gettoken lhs rest: rest + if `:list lhs in forbidden' { + di as err `"`lhs' not allowed in addscalars()"' + exit 198 + } + if "`replace'"=="" { + if `:list lhs in elist' { + di as err `"e(`lhs') already defined"' + exit 110 + } + } + gettoken rhs rest: rest, bind + capt eret scalar `lhs' = `rhs' + if _rc { + di as err `"addscalars() invalid"' + exit 198 + } + capture local result = e(`lhs') + di as txt "(e(" as res `"`lhs'"' as txt ") = " /// + as res `result' as txt " added)" + if `"`rest'"'=="" continue, break + } + } +// add e(cmd) if missing + if `"`e(cmd)'"'=="" { + if `"`: e(scalars)'`: e(macros)'`: e(matrices)'`: e(functions)'"'!="" { + eret local cmd "." + } + } + +// store estimates with e(sample) + estimates store `name' , `copy' `title' + +// remove e(sample) if -noesample- specified + if "`esample'"!="" { + capt confirm new var _est_`name' + if _rc { + tempname hcurrent + _est hold `hcurrent', restore estsystem nullok + qui replace _est_`name' = . in 1 + _est unhold `name' + capt confirm new var _est_`name' + if _rc qui drop _est_`name' + else { + di as error "somethings wrong; please contact author of -eststo- " /// + "(see e-mail in help {help eststo})" + exit 498 + } + _est hold `name', estimates varname(_est_`name') + // varname() only needed so that _est hold does not return error + // if variable `name' exists + } + } + +// report + if "`refresh'"=="" { + global eststo `names' `name' + global eststo_counter `counter' + if `"`namelist'"'=="" { + di as txt "(" as res "`name'" as txt " stored)" + } + } + else { + if `"`namelist'"'=="" { + di as txt "(" as res "`name'" as txt " refreshed)" + } + } +end + +program ParseAddscalars + syntax anything [ , Replace ] + c_local rest `"`anything'"' + c_local replace `replace' +end diff --git a/Modules/ado/plus/e/eststo.hlp b/Modules/ado/plus/e/eststo.hlp new file mode 100644 index 0000000..bde4b30 --- /dev/null +++ b/Modules/ado/plus/e/eststo.hlp @@ -0,0 +1,347 @@ +{smcl} +{* 07jan2009}{...} +{hi:help eststo}{right:also see: {helpb esttab}, {helpb estout}, {helpb estadd}, {helpb estpost}} +{right: {browse "http://repec.org/bocode/e/estout"}} +{hline} + +{title:Title} + +{p 4 4 2}{hi:eststo} {hline 2} Store estimates + + +{title:Syntax}{smcl} + +{p 8 15 2} +[{cmd:_}]{cmd:eststo} [{it:name}] +[{cmd:,} {it:{help eststo##options:options}} ] +[ {cmd::} {it:{help estimation_command}} ] + +{p 8 15 2} +[{cmd:_}]{cmd:eststo dir} + +{p 8 15 2} +[{cmd:_}]{cmd:eststo drop} {{it:#}|{it:name}} [ {{it:#}|{it:name}} ... ] + +{p 8 15 2} +[{cmd:_}]{cmd:eststo clear} + +{marker options} + {it:options}{col 23}description + {hline 56} + [{ul:{cmd:no}}]{cmdab:e:sample}{col 23}{...} +do not/do store {cmd:e(sample)} + {cmdab:t:itle:(}{it:string}{cmd:)}{col 23}{...} +specify a title for the stored set + {cmdab:p:refix:(}{it:prefix}{cmd:)}{col 23}{...} +specify a name prefix; default is {cmd:est} + {cmdab:add:scalars(}{it:...}{cmd:)}{col 23}{...} +add scalar statistics + {cmdab:r:efresh}[{cmd:(}{it:#}{cmd:)}]{col 23}{...} +overwrite a previously stored set + {cmdab:noc:opy}{col 23}{...} +clear {cmd:e()} after storing the set + {cmdab:mis:sing}{col 23}{...} +use missing values in the {cmd:by} groups + {hline 56} + +{p 4 4 2} +{cmd:by} is allowed with {cmd:eststo} if {cmd:eststo} +is used as a prefix command, i.e. specify + + {cmd:by} {it:...} {cmd::} {cmd:eststo} {it:...} {cmd::} {it:estimation_command} + +{p 4 4 2} +to apply {it:estimation_command} to each {cmd:by} group and store an estimation +set for each group; see help {help by}. Note that the implementation of {cmd:by} +with {cmd:eststo} requires {it:estimation_command} +to follow {help language:standard Stata syntax} and +allow the {it:{help if}} qualifier. Do not use the +{bind:{cmd:by} {it:...}{cmd:: eststo:}} construct with +{cmd:svy} commands. + + +{title:Description} + +{p 4 4 2} +{cmd:eststo} stores a copy of the active estimation results for later +tabulation. If {it:name} is provided, the estimation set is stored +under {it:name}. If {it:name} is not provided, the estimation set is +stored under {cmd:est}{it:#}, where {it:#} is a counter for the +number of stored estimation sets. + +{p 4 4 2} +{cmd:eststo} may be used in two ways: Either after fitting a model as +in + + {com}. regress y x + . eststo{txt} + +{p 4 4 2} +or as a prefix command (see help {help prefix}): + + {com}. eststo: regress y x{txt} + +{p 4 4 2} +{cmd:_eststo} is a variant on {cmd:eststo} that, by default, does not +store the estimation sample information contained in {cmd:e(sample)}. +Essentially, {cmd:_eststo} is a shortcut to {cmd:eststo, noesample}. + +{p 4 4 2} +{cmd:eststo dir} displays a list of the stored estimates. + +{p 4 4 2} +{cmd:eststo drop} drops estimation sets stored by {cmd:eststo}. If {it:name} is +provided, the estimation set stored under {it:name} +is dropped (if {cmd:*} or {cmd:?} wildcards are used {it:name}, +all matching sets are dropped). Alternatively, if {it:#} is provided, +the estimation set stored as {cmd:est}{it:#} is dropped. + +{p 4 4 2} +{cmd:eststo clear} drops all estimation sets stored by {cmd:eststo} (and clears +{cmd:eststo}'s global macros). + +{p 4 4 2} +{cmd:eststo} is an alternative to official Stata's +{helpb estimates store}. The main differences are: + +{p 8 12 2} +{space 1}o{space 2}{cmd:eststo} does not require the user to specify a +name for the stored estimation set. + +{p 8 12 2} +{space 1}o{space 2}{cmd:eststo} may be used as a prefix command (see +help {help prefix}). + +{p 8 12 2} +{space 1}o{space 2}{cmd:eststo} provides the possibility to store +estimates without the {cmd:e(sample)} function (either specify the +{cmd:noesample} option or use the {cmd:_eststo} command). Omitting +{cmd:e(sample)} saves memory and also speeds up tabulation programs +such as {helpb estimates table}, {helpb estout} or {helpb esttab}. +{hi:Warning:} Some post-estimation commands may not work with +estimation sets that do not contain the {cmd:e(sample)}. + +{p 8 12 2} +{space 1}o{space 2}{cmd:eststo} can add additional scalar statistics to +be stored with the estimation set. + + +{title:Options} +{marker esample} +{p 4 8 2} +{cmd:esample} causes the information in {cmd:e(sample)} to be stored +with the estimates. This is the default in {cmd:eststo}. Type +{cmd:noesample} or use the {cmd:_eststo} command to omit the +{cmd:e(sample)}. Note that some post-estimation commands may not be +working correctly with estimation sets that have been stored without +{cmd:e(sample)}. + +{p 4 8 2} +{cmd:title(}{it:string}{cmd:)} specifies a title for the stored +estimation set. +{p_end} +{marker addscalars} +{p 4 8 2} +{cmd:addscalars(}{it:name exp} [{it:...}] [{cmd:,} {cmdab:r:eplace}]{cmd:)} +may be used to add additional results to the {cmd:e()}-scalars of the +estimation set before storing it. Specify the names and values of the +scalars in pairs. For example, {cmd:addscalars(one 1 two 2)} would +add {cmd:e(one)} = {cmd:1} and {cmd:e(two)} = {cmd:2}. See below for +an example. The {cmd:replace} suboption permits overwriting existing +{cmd:e()}-returns. Not allowed as names are "b", "V", or "sample". +See {helpb estadd} for a more sophisticated tool to add additional +results to {cmd:e()}-returns. + +{p 4 8 2} +{cmd:prefix(}{it:prefix}{cmd:)} specifies a custom prefix for the +automatic names of the stored estimation sets. The default prefix +is {cmd:est}. + +{p 4 8 2} +{cmd:refresh}[{cmd:(}{it:#}{cmd:)}] may be used to overwrite a +previously stored estimation set instead of storing the estimates +under a new name. {cmd:refresh}, specified without argument, will +overwrite the last saved set. Alternatively, +{cmd:refresh(}{it:#}{cmd:)} will overwrite the set named +{cmd:est}{it:#} if it exists. If {it:name} is provided to {cmd:eststo}, +existing sets of the same name will always be overwritten whether or +not {cmd:refresh} is specified. {cmd:refresh()} with argument is not +allowed in this case. + +{p 4 8 2} +{cmd:nocopy} specifies that after the estimation set has been stored, +it no longer be available as the active estimation set. + +{p 4 8 2} +{cmd:missing} is for use of {cmd:eststo} with the {cmd:by} prefix command and +causes missing values to be treated like any other values in the {cmd:by} +variables. The default is to discard observations with missing values in the +{cmd:by} variables. + + +{title:Examples} + +{p 4 4 2} +Applying {cmd:eststo} after fiting a model to store the model's results, +as in the following example: + + {com}. sysuse auto + {txt}(1978 Automobile Data) + + {com}. quietly regress price weight + {txt} + {com}. eststo model1 + {txt} + {com}. quietly regress turn weight foreign + {txt} + {com}. eststo model2 + {txt} + {com}. estout + {res} + {txt}{hline 38} + {txt} model1 model2 + {txt} b b + {txt}{hline 38} + {txt}weight {res} 2.044063 .0042183{txt} + {txt}foreign {res} -1.809802{txt} + {txt}_cons {res} -6.707353 27.44963{txt} + {txt}{hline 38} + + +{p 4 4 2} +Applying {cmd:eststo} as a prefix commmand to fit and store a model in one step: + + {com}. eststo model1: quietly regress price weight + {txt} + {com}. eststo model2: quietly regress turn weight foreign + {txt} + {com}. estout + {res} + {txt}{hline 38} + {txt} model1 model2 + {txt} b b + {txt}{hline 38} + {txt}weight {res} 2.044063 .0042183{txt} + {txt}foreign {res} -1.809802{txt} + {txt}_cons {res} -6.707353 27.44963{txt} + {txt}{hline 38} + + +{p 4 4 2} +Using {cmd:eststo} with automatic names: + + {com}. eststo clear + {txt} + {com}. eststo: quietly regress price weight + {txt}({res}est1{txt} stored) + + {com}. eststo: quietly regress turn weight foreign + {txt}({res}est2{txt} stored) + + {com}. estout + {res} + {txt}{hline 38} + {txt} est1 est2 + {txt} b b + {txt}{hline 38} + {txt}weight {res} 2.044063 .0042183{txt} + {txt}foreign {res} -1.809802{txt} + {txt}_cons {res} -6.707353 27.44963{txt} + {txt}{hline 38} + + +{p 4 4 2} +Adding ancillary statistics: + + {com}. eststo clear + {txt} + {com}. quietly regress price weight mpg + {txt} + {com}. test weight = mpg + + {txt} ( 1) {res}weight - mpg = 0 + + {txt} F( 1, 71) ={res} 0.36 + {txt}{col 13}Prob > F ={res} 0.5514 + {txt} + {com}. eststo, add(p_diff r(p)) + {txt}(e({res}p_diff{txt}) = {res}.55138216{txt} added) + ({res}est1{txt} stored) + + {com}. estout, stat(p_diff) + {res} + {txt}{hline 25} + {txt} est1 + {txt} b + {txt}{hline 25} + {txt}weight {res} 1.746559{txt} + {txt}mpg {res} -49.51222{txt} + {txt}_cons {res} 1946.069{txt} + {txt}{hline 25} + {txt}p_diff {res} .5513822{txt} + {txt}{hline 25} + + +{p 4 4 2} +Using the {cmd:by} prefix to store subbroup models: + + {com}. eststo clear + {txt} + {com}. quietly by foreign: eststo: quietly reg price weight mpg + {txt} + {com}. esttab, label nodepvar nonumber + {res} + {txt}{hline 52} + {txt} Domestic Foreign + {txt}{hline 52} + {txt}Weight (lbs.) {res} 4.415*** 5.156***{txt} + {res} {ralign 12:{txt:(}4.66{txt:)}} {ralign 12:{txt:(}5.85{txt:)}} {txt} + + {txt}Mileage (mpg) {res} 237.7 -19.78 {txt} + {res} {ralign 12:{txt:(}1.71{txt:)}} {ralign 12:{txt:(}-0.34{txt:)}} {txt} + + {txt}Constant {res} -13285.4* -5065.8 {txt} + {res} {ralign 12:{txt:(}-2.32{txt:)}} {ralign 12:{txt:(}-1.58{txt:)}} {txt} + {txt}{hline 52} + {txt}Observations {res} 52 22 {txt} + {txt}{hline 52} + {txt}t statistics in parentheses + {txt}* p<0.05, ** p<0.01, *** p<0.001 + + +{title:Returned results} + +{p 4 4 2} +The name under which an estimation set is stored, is added to the set in +{cmd:e(_estimates_name)}. + +{p 4 4 2} +In addition, {cmd:eststo} maintains two global macros. {cmd:$eststo} contains a list +of the names of the stored estimation sets. {cmd:$eststo_counter} +contains the count of stored estimation sets. + + +{title:Acknowledgements} + +{p 4 4 2} +Bill Gould suggested to make {cmd:eststo} "byable". + + +{title:Author} + +{p 4 4 2} +Ben Jann, ETH Zurich, jannb@ethz.ch + + +{title:Also see} + + Manual: {hi:[R] estimates} + +{p 4 13 2}Online: help for + {helpb estimates}, + {helpb esttab}, + {helpb estout}, + {helpb estadd}, + {helpb estpost} +{p_end} + diff --git a/Modules/ado/plus/e/esttab.ado b/Modules/ado/plus/e/esttab.ado new file mode 100644 index 0000000..88ddb52 --- /dev/null +++ b/Modules/ado/plus/e/esttab.ado @@ -0,0 +1,1199 @@ +*! version 2.0.5 09mar2009 Ben Jann +*! wrapper for estout + +program define esttab + version 8.2 + local caller : di _caller() + +// mode specific defaults + local cdate "`c(current_date)'" + local ctime "`c(current_time)'" +// - fixed + local fixed_open0 `""% `cdate' `ctime'""' + local fixed_close0 `""""' + local fixed_open `""' + local fixed_close `""' + local fixed_caption `""@title""' + local fixed_open2 `""' + local fixed_close2 `""' + local fixed_toprule `""@hline""' + local fixed_midrule `""@hline""' + local fixed_bottomrule `""@hline""' + local fixed_topgap `""""' + local fixed_midgap `""""' + local fixed_bottomgap `""""' + local fixed_eqrule `"begin(@hline "")"' + local fixed_ssl `"N R-sq "adj. R-sq" "pseudo R-sq" AIC BIC"' + local fixed_lsl `"Observations R-squared "Adjusted R-squared" "Pseudo R-squared" AIC BIC"' + local fixed_starlevels `"* 0.05 ** 0.01 *** 0.001"' + local fixed_starlevlab `""' + local fixed_begin `""' + local fixed_delimiter `"" ""' + local fixed_end `""' + local fixed_incelldel `"" ""' + local fixed_varwidth `"\`= cond("\`label'"=="", 12, 20)'"' + local fixed_modelwidth `"12"' + local fixed_abbrev `"abbrev"' + local fixed_substitute `""' + local fixed_tstatlab `"t statistics"' + local fixed_zstatlab `"z statistics"' + local fixed_pvallab `"p-values"' + local fixed_cilab `"\`level'% confidence intervals"' +// - smcl + local smcl_open0 `"{smcl} "{* % `cdate' `ctime'}{...}""' + local smcl_close0 `""""' + local smcl_open `""' + local smcl_close `""' + local smcl_caption `""@title""' + local smcl_open2 `""' + local smcl_close2 `""' + local smcl_toprule `""{hline @width}""' + local smcl_midrule `""{hline @width}""' + local smcl_bottomrule `""{hline @width}""' + local smcl_topgap `""""' + local smcl_midgap `""""' + local smcl_bottomgap `""""' + local smcl_eqrule `"begin("{hline @width}" "")"' + local smcl_ssl `"`macval(fixed_ssl)'"' + local smcl_lsl `"`macval(fixed_lsl)'"' + local smcl_starlevels `"`macval(fixed_starlevels)'"' + local smcl_starlevlab `""' + local smcl_begin `""' + local smcl_delimiter `"" ""' + local smcl_end `""' + local smcl_incelldel `"" ""' + local smcl_varwidth `"`macval(fixed_varwidth)'"' + local smcl_modelwidth `"`macval(fixed_modelwidth)'"' + local smcl_abbrev `"`macval(fixed_abbrev)'"' + local smcl_substitute `""' + local smcl_tstatlab `"`macval(fixed_tstatlab)'"' + local smcl_zstatlab `"`macval(fixed_zstatlab)'"' + local smcl_pvallab `"`macval(fixed_pvallab)'"' + local smcl_cilab `"`macval(fixed_cilab)'"' +// - tab + local tab_open0 `"`macval(fixed_open0)'"' + local tab_close0 `""""' + local tab_open `""' + local tab_close `""' + local tab_caption `""@title""' + local tab_open2 `""' + local tab_close2 `""' + local tab_topgap `""""' + local tab_midgap `""""' + local tab_bottomgap `""""' + local tab_ssl `"`macval(fixed_ssl)'"' + local tab_lsl `"`macval(fixed_lsl)'"' + local tab_starlevels `"`macval(fixed_starlevels)'"' + local tab_starlevlab `""' + local tab_begin `""' + local tab_delimiter `"_tab"' + local tab_end `""' + local tab_incelldel `"" ""' + local tab_varwidth `""' + local tab_modelwidth `""' + local tab_abbrev `""' + local tab_substitute `""' + local tab_tstatlab `"`macval(fixed_tstatlab)'"' + local tab_zstatlab `"`macval(fixed_zstatlab)'"' + local tab_pvallab `"`macval(fixed_pvallab)'"' + local tab_cilab `"`macval(fixed_cilab)'"' +// - csv + local csv_open0 `"`"\`csvlhs'% `cdate' `ctime'""'"' + local csv_close0 `""""' + local csv_open `""' + local csv_close `""' + local csv_caption `"`"\`csvlhs'@title""'"' + local csv_open2 `""' + local csv_close2 `""' + local csv_topgap `""""' + local csv_midgap `""""' + local csv_bottomgap `""""' + local csv_ssl `"`macval(fixed_ssl)'"' + local csv_lsl `"`macval(fixed_lsl)'"' + local csv_starlevels `"`macval(fixed_starlevels)'"' + local csv_starlevlab `""' + local csv_begin `"`"\`csvlhs'"'"' + local csv_delimiter `"`"",\`csvlhs'"'"' + local scsv_delimiter `"`"";\`csvlhs'"'"' + local csv_end `"`"""'"' + local csv_incelldel `"" ""' + local csv_varwidth `""' + local csv_modelwidth `""' + local csv_abbrev `""' + local csv_substitute `""' + local csv_tstatlab `"`macval(fixed_tstatlab)'"' + local csv_zstatlab `"`macval(fixed_zstatlab)'"' + local csv_pvallab `"`macval(fixed_pvallab)'"' + local csv_cilab `"`macval(fixed_cilab)'"' +// - rtf + local rtf_open0 `""' + local rtf_close0 `""' + local rtf_ct `"\yr`=year(d(`cdate'))'\mo`=month(d(`cdate'))'\dy`=day(d(`cdate'))'\hr`=substr("`ctime'",1,2)'\min`=substr("`ctime'",4,2)'"' + local rtf_open_l1 `"`"{\rtf1`=cond("`c(os)'"=="MacOSX", "\mac", "\ansi")'\deff0 {\fonttbl{\f0\fnil Times New Roman;}}"'"' + local rtf_open_l2 `" `"{\info {\author .}{\company .}{\title .}{\creatim`rtf_ct'}}"'"' + local rtf_open_l3 `" `"\deflang1033\plain\fs24"'"' + local rtf_open_l4 `" `"{\footer\pard\qc\plain\f0\fs24\chpgn\par}"'"' + local rtf_open `"`rtf_open_l1'`rtf_open_l2'`rtf_open_l3'`rtf_open_l4'"' + local rtf_close `""{\pard \par}" "}""' + local rtf_caption `"`"{\pard\keepn\ql @title\par}"'"' + local rtf_open2 `""{""' + local rtf_close2 `""}""' + local rtf_toprule `""' + local rtf_midrule `""' + local rtf_bottomrule `""' + local rtf_topgap `""' + local rtf_midgap `"{\trowd\trgaph108\trleft-108@rtfemptyrow\row}"' + local rtf_bottomgap `""' + local rtf_eqrule `"begin("{\trowd\trgaph108\trleft-108@rtfrowdefbrdrt\pard\intbl\ql {") replace"' + local rtf_ssl `""{\i N}" "{\i R}{\super 2}" "adj. {\i R}{\super 2}" "pseudo {\i R}{\super 2}" "{\i AIC}" "{\i BIC}""' + local rtf_lsl `"Observations "{\i R}{\super 2}" "Adjusted {\i R}{\super 2}" "Pseudo {\i R}{\super 2}" "{\i AIC}" "{\i BIC}""' + local rtf_starlevels `""{\super *}" 0.05 "{\super **}" 0.01 "{\super ***}" 0.001"' + local rtf_starlevlab `", label(" {\i p} < ")"' + local rtf_rowdef `"\`=cond("\`lines'"=="", "@rtfrowdef", "@rtfrowdefbrdr")'"' + local rtf_begin `"{\trowd\trgaph108\trleft-108\`rtf_rowdef'\pard\intbl\ql {"' + local rtf_delimiter `"}\cell \pard\intbl\q\`=cond(`"\`alignment'"'!="", `"\`alignment'"', "c")' {"' + local rtf_end `"}\cell\row}"' + local rtf_incelldel `""\line ""' + local rtf_varwidth `"\`= cond("\`label'"=="", 12, 20)'"' + local rtf_modelwidth `"12"' + local rtf_abbrev `""' + local rtf_substitute `""' + local rtf_tstatlab `"{\i t} statistics"' + local rtf_zstatlab `"{\i z} statistics"' + local rtf_pvallab `"{\i p}-values"' + local rtf_cilab `"\`level'% confidence intervals"' +// - html + local html_open0 `" "`=cond(`"\`macval(title)'"'=="","estimates table, created `cdate' `ctime'","@title")'" """' + local html_close0 `""" """' + local html_open `"`""'"' + local html_close `""
""' + local html_caption `""@title""' + local html_open2 `""' + local html_close2 `""' + local html_toprule `""
""' + local html_midrule `""
""' + local html_bottomrule `""
""' + local html_topgap `""' + local html_midgap `"" ""' + local html_bottomgap `""' + local html_eqrule `"begin("
" "")"' + local html_ssl `"N R2 "adj. R2" "pseudo R2" AIC BIC"' + local html_lsl `"Observations R2 "Adjusted R2" "Pseudo R2" AIC BIC"' + local html_starlevels `"* 0.05 ** 0.01 *** 0.001"' + local html_starlevlab `", label(" p < ")"' + local html_begin `""' + local html_delimiter `""' + local html_end `""' + local html_incelldel `"
"' + local html_varwidth `"\`= cond("\`label'"=="", 12, 20)'"' + local html_modelwidth `"12"' + local html_abbrev `""' + local html_substitute `""' + local html_tstatlab `"t statistics"' + local html_zstatlab `"z statistics"' + local html_pvallab `"p-values"' + local html_cilab `"\`level'% confidence intervals"' +// - tex + local tex_open0 `""% `cdate' `ctime'" \documentclass{article} \`texpkgs' \`=cond("\`longtable'"!="","\usepackage{longtable}","")' \begin{document} """' + local tex_close0 `""" \end{document} """' + local tex_open `"\`=cond("\`longtable'"=="", "\begin{table}[htbp]\centering", `"{"')'"' + local tex_close `"\`=cond("\`longtable'"=="", "\end{table}", "}")'"' + local tex_caption `"\caption{@title}"' + local tex_open2 `"\`=cond("\`longtable'"!="", "\begin{longtable}", "\begin{tabular" + cond("\`width'"=="", "}", "*}{\`width'}"))'"' + local tex_close2 `"\`=cond("\`longtable'"!="", "\end{longtable}", "\end{tabular" + cond("\`width'"=="", "}", "*}"))'"' + local tex_toprule `"\`="\hline\hline" + cond("\`longtable'"!="", "\endfirsthead\hline\endhead\hline\endfoot\endlastfoot", "")'"' + local tex_midrule `""\hline""' + local tex_bottomrule `""\hline\hline""' + local tex_topgap `""' + local tex_midgap `"[1em]"' // `"\\\"' + local tex_bottomgap `""' + local tex_eqrule `"begin("\hline" "")"' + local tex_ssl `"\(N\) \(R^{2}\) "adj. \(R^{2}\)" "pseudo \(R^{2}\)" \textit{AIC} \textit{BIC}"' + local tex_lsl `"Observations \(R^{2}\) "Adjusted \(R^{2}\)" "Pseudo \(R^{2}\)" \textit{AIC} \textit{BIC}"' + local tex_starlevels `"\sym{*} 0.05 \sym{**} 0.01 \sym{***} 0.001"' + local tex_starlevlab `", label(" \(p<@\)")"' + local tex_begin `""' + local tex_delimiter `"&"' + local tex_end `"\\\"' + local tex_incelldel `"" ""' + local tex_varwidth `"\`= cond("\`label'"=="", 12, 20)'"' + local tex_modelwidth `"12"' + local tex_abbrev `""' + local tex_tstatlab `"\textit{t} statistics"' + local tex_zstatlab `"\textit{z} statistics"' + local tex_pvallab `"\textit{p}-values"' + local tex_cilab `"\`level'\% confidence intervals"' + local tex_substitute `"_ \_ "\_cons " \_cons"' +// - booktabs + local booktabs_open0 `""% `cdate' `ctime'" \documentclass{article} \`texpkgs' \usepackage{booktabs} \`=cond("\`longtable'"!="","\usepackage{longtable}","")' \begin{document} """' + local booktabs_close0 `"`macval(tex_close0)'"' + local booktabs_open `"`macval(tex_open)'"' + local booktabs_close `"`macval(tex_close)'"' + local booktabs_caption `"`macval(tex_caption)'"' + local booktabs_open2 `"`macval(tex_open2)'"' + local booktabs_close2 `"`macval(tex_close2)'"' + local booktabs_toprule `"\`="\toprule" + cond("\`longtable'"!="", "\endfirsthead\midrule\endhead\midrule\endfoot\endlastfoot", "")'"' + local booktabs_midrule `""\midrule""' + local booktabs_bottomrule `""\bottomrule""' + local booktabs_topgap `"`macval(tex_topgap)'"' + local booktabs_midgap `"\addlinespace"' + local booktabs_bottomgap `"`macval(tex_bottomgap)'"' + local booktabs_eqrule `"begin("\midrule" "")"' + local booktabs_ssl `"`macval(tex_ssl)'"' + local booktabs_lsl `"`macval(tex_lsl)'"' + local booktabs_starlevels `"`macval(tex_starlevels)'"' + local booktabs_starlevlab `"`macval(tex_starlevlab)'"' + local booktabs_begin `"`macval(tex_begin)'"' + local booktabs_delimiter `"`macval(tex_delimiter)'"' + local booktabs_end `"`macval(tex_end)'"' + local booktabs_incelldel `"`macval(tex_incelldel)'"' + local booktabs_varwidth `"`macval(tex_varwidth)'"' + local booktabs_modelwidth `"`macval(tex_modelwidth)'"' + local booktabs_abbrev `"`macval(tex_abbrev)'"' + local booktabs_tstatlab `"`macval(tex_tstatlab)'"' + local booktabs_zstatlab `"`macval(tex_zstatlab)'"' + local booktabs_pvallab `"`macval(tex_pvallab)'"' + local booktabs_cilab `"`macval(tex_cilab)'"' + local booktabs_substitute `"`macval(tex_substitute)'"' + +// syntax + syntax [anything] [using] [ , /// + /// coefficients and t-stats, se, etc. + b Bfmt(string) /// + noT Tfmt(string) /// + z Zfmt(string) /// + se SEfmt(string) /// + p Pfmt(string) /// + ci CIfmt(string) /// + BEta BEtafmt(string) /// + main(string) /// syntax: name format + aux(string) /// syntax: name format + abs /// absolute t-values + wide /// + NOSTAr STAR STAR2(string asis) /// + staraux /// + NOCONstant CONstant /// + COEFlabels(string asis) /// + /// summary statistics + noOBS obslast /// + r2 R2fmt(string) ar2 AR2fmt(string) pr2 PR2fmt(string) /// + aic AICfmt(string) bic BICfmt(string) /// + SCAlars(string asis) /// syntax: "name1 [label1]" "name2 [label2]" etc. + sfmt(string) /// + /// layout + NOMTItles MTItles MTItles2(string asis) /// + NOGAPs GAPs /// + NOLInes LInes /// + ADDNotes(string asis) /// + COMpress /// + plain /// + smcl FIXed tab csv SCsv rtf HTMl tex BOOKTabs /// + Fragment /// + page PAGE2(str) /// + ALIGNment(str asis) /// + width(str asis) /// + /// other + Noisily /// + * ] + _more_syntax , `macval(options)' + _estout_options , `macval(options)' + +// matrix mode + MatrixMode, `anything' + +// syntax consistency etc + gettoken chunk using0: using + if `"`macval(star2)'"'!="" local star star + foreach opt in constant gaps lines star abbrev depvars numbers parentheses /// + notes mtitles type outfilenoteoff { + NotBothAllowed "``opt''" `no`opt'' + } + NotBothAllowed "`staraux'" `nostar' + if `"`macval(mtitles2)'"'!="" NotBothAllowed "mtitles" `nomtitles' + if `"`page2'"'!="" local page page + NotBothAllowed "`fragment'" `page' + if `"`pfmt'"'!="" local p p + if `"`zfmt'"'!="" local z z + if `"`sefmt'"'!="" local se se + if `"`cifmt'"'!="" local ci ci + if `"`betafmt'"'!="" local beta beta + if "`level'"=="" local level $S_level + if ((("`margin'"!="" | `"`margin2'"'!="") & "`nomargin'"=="") | /// + ("`beta'"!="") | ("`eform'"!="" & "`noeform'"=="")) /// + & "`constant'"=="" local noconstant noconstant + if `"`r2fmt'"'!="" local r2 r2 + if `"`ar2fmt'"'!="" local ar2 ar2 + if `"`pr2fmt'"'!="" local pr2 pr2 + if `"`aicfmt'"'!="" local aic aic + if `"`bicfmt'"'!="" local bic bic + if "`type'"=="" & `"`using'"'!="" local notype notype + local nocellsopt = `"`macval(cells)'"'=="" + if `"`width'"'!="" & `"`longtable'"'!="" { + di as err "width() and longtable not both allowed" + exit 198 + } + +// format modes + local mode `smcl' `fixed' `tab' `csv' `scsv' `rtf' `html' `tex' `booktabs' + if `:list sizeof mode'>1 { + di as err "only one allowed of smcl, fixed, tab, csv, scsv, rtf, html, tex, or booktabs" + exit 198 + } + if `"`using'"'!="" { + _getfilename `"`using0'"' + local fn `"`r(filename)'"' + _getfilesuffix `"`fn'"' + local suffix `"`r(suffix)'"' + } + if "`mode'"=="" { + if `"`using'"'!="" { + if inlist(`"`suffix'"', ".html", ".htm") local mode html + else if `"`suffix'"'==".tex" local mode tex + else if `"`suffix'"'==".csv" local mode csv + else if `"`suffix'"'==".rtf" local mode rtf + else if `"`suffix'"'==".smcl" local mode smcl + else local mode fixed + } + else local mode smcl + } + else { + if "`mode'"=="scsv" { + local csv_delimiter `"`macval(`mode'_delimiter)'"' + local mode "csv" + } + } + if `"`using'"'!="" & `"`suffix'"'=="" { + if inlist("`mode'","fixed","tab") local suffix ".txt" + else if inlist("`mode'","csv","scsv") local suffix ".csv" + else if "`mode'"=="rtf" local suffix ".rtf" + else if "`mode'"=="html" local suffix ".html" + else if inlist("`mode'","tex","booktabs") local suffix ".tex" + else if "`mode'"=="smcl" local suffix ".smcl" + local using `"using `"`fn'`suffix'"'"' + local using0 `" `"`fn'`suffix'"'"' + } + if "`mode'"=="smcl" local smcltags smcltags + local mode0 `mode' + if "`mode0'"=="booktabs" local mode0 tex + else if "`mode0'"=="csv" { + if "`plain'"=="" local csvlhs `"=""' + else local csvlhs `"""' + } + if "`compress'"!="" { + if "``mode'_modelwidth'"!="" { + local `mode'_modelwidth = ``mode'_modelwidth' - 3 + } + if "``mode'_varwidth'"!="" { + local `mode'_varwidth = ``mode'_varwidth' - cond("`label'"!="", 4, 2) + } + } + if `"`modelwidth'"'=="" { + if `nocellsopt' & `"``mode'_modelwidth'"'!="" & "`ci'"!="" { + local modelwidth = 2*``mode'_modelwidth' - 2 + if "`wide'"!="" local modelwidth "``mode'_modelwidth' `modelwidth'" + } + else { + local modelwidth "``mode'_modelwidth'" + } + } + if `"`varwidth'"'=="" { + local varwidth "``mode'_varwidth'" + } + if "`plain'"=="" & `matrixmode'==0 { + foreach opt in star depvars numbers parentheses notes { + SwitchOnIfEmpty `opt' `no`opt'' + } + if "`wide'"=="" & ("`t'"=="" | "`z'`se'`p'`ci'`aux'"!="") & `nocellsopt'==1 /// + SwitchOnIfEmpty gaps `nogaps' + } + if "`plain'"=="" { + SwitchOnIfEmpty lines `nolines' + } + if `"`lines'"'!="" { + SwitchOnIfEmpty eqlines `noeqlines' + } + if inlist("`mode0'", "tab", "csv") { + local lines + local eqlines + } + if "`notes'"!="" & "`nolegend'"=="" & `nocellsopt'==1 & `matrixmode'==0 local legend legend + if "`plain'"!="" { + if "`bfmt'"=="" local bfmt %9.0g + if "`tfmt'"=="" local tfmt `bfmt' + if "`zfmt'"=="" local zfmt `bfmt' + if "`sefmt'"=="" local sefmt `bfmt' + if "`pfmt'"=="" local pfmt `bfmt' + if "`cifmt'"=="" local cifmt `bfmt' + if "`betafmt'"=="" local betafmt `bfmt' + } + //if "`nomtitles'"!="" local depvars + //else if "`depvars'"=="" local mtitles mtitles + +// prepare append for rtf, tex, and html + local outfilenoteoff2 "`outfilenoteoff'" + if "`outfilenoteoff2'"=="" local outfilenoteoff2 "`nooutfilenoteoff'" + if `"`using'"'!="" & "`append'"!="" & /// + (("`mode0'"=="rtf" & "`fragment'"=="") | /// + ("`page'"!="" & inlist("`mode0'", "tex", "html"))) { + capture confirm file `using0' + if _rc==0 { + tempfile appendfile + if "`mode'"=="rtf" local `mode'_open + else local `mode'_open0 + local append + if "`outfilenoteoff2'"=="" local outfilenoteoff2 outfilenoteoff + } + } + +// cells() option + if "`notes'"!="" { + if ("`margin'"!="" | `"`margin2'"'!="") & "`nomargin'"=="" /// + local thenote "`thenote'Marginal effects" + if "`eform'"!="" & "`noeform'"=="" /// + local thenote "`thenote'Exponentiated coefficients" + } + if "`bfmt'"=="" local bfmt a3 + if `nocellsopt' & `matrixmode'==0 { + if "`star'"!="" & "`staraux'"=="" local bstar star + if "`beta'"!="" { + if "`main'"!="" { + di as err "beta() and main() not allowed both" + exit 198 + } + if "`betafmt'"=="" local betafmt 3 + local cells fmt(`betafmt') `bstar' + local cells beta(`cells') + if "`notes'"!="" { + if `"`thenote'"'!="" local thenote "`thenote'; " + local thenote "`thenote'Standardized beta coefficients" + } + } + else if "`main'"!="" { + tokenize "`main'" + if "`2'"=="" local 2 "`bfmt'" + local cells fmt(`2') `bstar' + local cells `1'(`cells') + if "`notes'"!="" { + if `"`thenote'"'!="" local thenote "`thenote'; " + local thenote "`thenote'`1' coefficients" + } + } + else { + local cells fmt(`bfmt') `bstar' + local cells b(`cells') + } + if "`t'"=="" | "`z'`se'`p'`ci'`aux'"!="" { + if "`onecell'"!="" { + local cells `cells' & + } +// parse aux option + tokenize "`aux'" + local auxname `1' + local auxfmt `2' +// type of auxiliary statistic + local aux `z' `se' `p' `ci' `auxname' + if `"`aux'"'=="" local aux t + else { + if `:list sizeof aux'>1 { + di as err "only one allowed of z, se, p, ci, and aux()" + exit 198 + } + } + if !inlist(`"`aux'"', "t", "z") local abs +// parentheses/brackets + if "`parentheses'"!="" | "`brackets'"!="" { + if `"`aux'"'=="ci" { + local brackets brackets + if "`mode'"!="smcl" | "`onecell'"!="" local paren par + else local paren `"par("{ralign @modelwidth:{txt:[}" "{txt:,}" "{txt:]}}")"' + } + else if "`brackets'"!="" { + if "`mode'"!="smcl" | "`onecell'"!="" local paren "par([ ])" + else local paren `"par("{ralign @modelwidth:{txt:[}" "{txt:]}}")"' + } + else { + if "`mode'"!="smcl" | "`onecell'"!="" local paren par + else local paren `"par("{ralign @modelwidth:{txt:(}" "{txt:)}}")"' + } + } +// compose note + if "`notes'"!="" { + if `"`thenote'"'!="" local thenote "`thenote'; " + if `"`auxname'"'!="" { + local thenote `"`macval(thenote)'`auxname'"' + } + else if inlist(`"`aux'"', "t", "z") { + if "`abs'"!="" local thenote `"`macval(thenote)'Absolute "' + local thenote `"`macval(thenote)'``mode'_`aux'statlab'"' + } + else if `"`aux'"'=="se" { + local thenote `"`macval(thenote)'Standard errors"' + } + else if `"`aux'"'=="p" { + local thenote `"`macval(thenote)'``mode'_pvallab'"' + } + else if `"`aux'"'=="ci" { + local thenote `"`macval(thenote)'``mode'_cilab'"' + } + if "`parentheses'"=="" { + if "`wide'"=="" local thenote `"`macval(thenote)' in second row"' + else local thenote `"`macval(thenote)' in second column"' + } + else if "`brackets'"!="" { + local thenote `"`macval(thenote)' in brackets"' + } + else local thenote `"`macval(thenote)' in parentheses"' + } +// formats + if "`tfmt'"=="" local tfmt 2 + if "`zfmt'"=="" local zfmt 2 + if "`sefmt'"=="" local sefmt `bfmt' + if "`pfmt'"=="" local pfmt 3 + if "`cifmt'"=="" local cifmt `bfmt' + if `"`auxfmt'"'=="" local auxfmt `bfmt' + if `"`auxname'"'=="" { + local auxfmt ``aux'fmt' + } +// stars + if "`staraux'"!="" local staraux star +// put together + local temp fmt(`auxfmt') `paren' `abs' `staraux' + local cells `cells' `aux'(`temp') + } + if "`wide'"!="" local cells cells(`"`cells'"') + else local cells cells(`cells') + } + +// stats() option + if `"`macval(stats)'"'=="" & `matrixmode'==0 { + if `"`sfmt'"'=="" local sfmt `bfmt' + if `"`r2fmt'"'=="" local r2fmt = cond("`plain'"!="", "`bfmt'", "3") + if `"`ar2fmt'"'=="" local ar2fmt = cond("`plain'"!="", "`bfmt'", "3") + if `"`pr2fmt'"'=="" local pr2fmt = cond("`plain'"!="", "`bfmt'", "3") + if `"`aicfmt'"'=="" local aicfmt `bfmt' + if `"`bicfmt'"'=="" local bicfmt `bfmt' + if "`label'"=="" { + local stalabs `"``mode'_ssl'"' + } + else { + local stalabs `"``mode'_lsl'"' + } + gettoken obslab stalabs: stalabs + if "`obs'"=="" & "`obslast'"=="" { + local sta N + local stalab `"`"`macval(obslab)'"'"' + local stafmt %18.0g + } + local i 0 + foreach s in r2 ar2 pr2 aic bic { + local ++i + if "``s''"!="" { + local sta `sta' `:word `i' of r2 r2_a r2_p aic bic' + local chunk: word `i' of `macval(stalabs)' + local stalab `"`macval(stalab)' `"`macval(chunk)'"'"' + local stafmt `stafmt' ``s'fmt' + } + } + local i 0 + CheckScalarOpt `macval(scalars)' + foreach addstat of local scalars { + local ++i + gettoken addstatname addstatlabel: addstat + local addstatlabel = substr(`"`macval(addstatlabel)'"',2,.) + if `: list posof `"`addstatname'"' in sta' continue + if `"`addstatname'"'=="N" & "`obs'"=="" & "`obslast'"!="" continue + if trim(`"`macval(addstatlabel)'"')=="" local addstatlabel `addstatname' + local addstatfmt: word `i' of `sfmt' + if `"`addstatfmt'"'=="" { + local addstatfmt: word `: list sizeof sfmt' of `sfmt' + } + local sta `sta' `addstatname' + local stalab `"`macval(stalab)' `"`macval(addstatlabel)'"'"' + local stafmt `stafmt' `addstatfmt' + } + if "`obs'"=="" & "`obslast'"!="" { + local sta `sta' N + local stalab `"`macval(stalab)' `"`macval(obslab)'"'"' + local stafmt `stafmt' %18.0g + } + if "`sta'"!="" { + local stats stats(`sta', fmt(`stafmt') labels(`macval(stalab)')) + } + } + +// table header + if `"`macval(mlabels)'"'=="" { + if "`mode0'"=="tex" local mspan " span prefix(\multicolumn{@span}{c}{) suffix(})" + if `"`depvars'"'!="" { + local mlabels `"mlabels(, depvar`mspan')"' + } + if `"`nomtitles'"'!="" local mlabels `"mlabels(none)"' + if "`mtitles'"!="" { + local mlabels `"mlabels(, titles`mspan')"' + } + if `"`macval(mtitles2)'"'!="" { + local mlabels `"mlabels(`macval(mtitles2)', titles`mspan')"' + } + } + if `"`macval(collabels)'"'=="" & `nocellsopt' & `matrixmode'==0 & "`plain'"=="" { + local collabels `"collabels(none)"' + } + if "`mode0'"=="tex" & "`numbers'"!="" { + local numbers "numbers(\multicolumn{@span}{c}{( )})" + } + +// pre-/posthead, pre-/postfoot, gaps and lines +// - complete note + if `"`macval(thenote)'"'!="" { + local thenote `"`"`macval(thenote)'"'"' + } + if `"`macval(note)'"'!="" { + local thenote `""@note""' + } + if `"`macval(addnotes)'"'!="" { + if index(`"`macval(addnotes)'"', `"""')==0 { + local addnotes `"`"`macval(addnotes)'"'"' + } + local thenote `"`macval(thenote)' `macval(addnotes)'"' + } + if "`legend'"!="" { + if ("`margin'"!="" | `"`margin2'"'!="") & /// + "`nomargin'"=="" & "`nodiscrete'"=="" { + local thenote `"`macval(thenote)' "@discrete""' + } + if "`star'"!="" | `nocellsopt'==0 { + local thenote `"`macval(thenote)' "@starlegend""' + } + } +// - mode specific settings + if "`star'"!="" { + if `"`macval(star2)'"'!="" { + FormatStarSym "`mode0'" `"`macval(star2)'"' + local `mode'_starlevels `"`macval(star2)'"' + } + if `"`macval(starlevels)'"'=="" { + local starlevels `"starlevels(`macval(`mode'_starlevels)'`macval(`mode'_starlevlab)')"' + } + } + foreach opt in begin delimiter end substitute { + if `"`macval(`opt')'"'=="" & `"``mode'_`opt''"'!="" { + local `opt' `"`opt'(``mode'_`opt'')"' + } + } + if "`onecell'"!="" { + if `"`macval(incelldelimiter)'"'=="" { + local incelldelimiter `"incelldelimiter(``mode'_incelldel')"' + } + } + if "`noabbrev'`abbrev'"=="" { + local abbrev ``mode'_abbrev' + } + if `"`fragment'"'=="" { + if "`page'"!="" { + if `"`page2'"'!="" { + local texpkgs `""\usepackage{`page2'}""' + } + local opening `"``mode'_open0'"' + } + if `"`macval(title)'"'!="" { + local opening `"`macval(opening)' ``mode'_open'"' + if "`mode0'"=="tex" & "`star'"!="" { + local opening `"`macval(opening)' "\def\sym#1{\ifmmode^{#1}\else\(^{#1}\)\fi}""' + } + if !("`longtable'"!="" & "`mode0'"=="tex") { + local opening `"`macval(opening)' ``mode'_caption'"' + } + } + else if "`mode0'"=="tex" & "`star'"!="" { + local opening `"`macval(opening)' "{" "\def\sym#1{\ifmmode^{#1}\else\(^{#1}\)\fi}""' + } + else if "`mode0'"!="tex" { + local opening `"`macval(opening)' ``mode'_open'"' + } + local opening `"`macval(opening)' ``mode'_open2'"' + if "`mode0'"=="tex" { + if `"`labcol2'"'!="" local lstubtex "lc" + else local lstubtex "l" + if `"`width'"'!="" local extracolsep "@{\hskip\tabcolsep\extracolsep\fill}" + if `"`macval(alignment)'"'!="" { + local opening `"`macval(opening)'{`extracolsep'`lstubtex'*{@E}{`macval(alignment)'}}"' + } + else { + if `nocellsopt' { + MakeTeXColspec "`wide'" "`not'" "`star'" "`stardetach'" "`staraux'" + } + else { + MakeTeXColspecAlt, `cells' + } + local opening `"`macval(opening)'{`extracolsep'`lstubtex'*{@E}{`value'}}"' + } + if "`longtable'"!="" { + if `"`macval(title)'"'!="" { + local opening `"`macval(opening)' ``mode'_caption'\\\"' + } + } + } + if "`mode0'"=="html" { + local brr + foreach chunk of local thenote { + local closing `"`macval(closing)' `"`brr'`macval(chunk)'"'"' + local brr "
" + } + if `"`macval(closing)'"'!="" { + local closing `""" `macval(closing)' """' + } + } + else if "`mode0'"=="tex" { + foreach chunk of local thenote { + local closing `"`macval(closing)' `"\multicolumn{@span}{l}{\footnotesize `macval(chunk)'}\\\"'"' + } + } + else if "`mode0'"=="csv" { + foreach chunk of local thenote { + local closing `"`macval(closing)' `"`csvlhs'`macval(chunk)'""'"' + } + } + else if "`mode0'"=="rtf" { + foreach chunk of local thenote { + local closing `"`macval(closing)' `"{\pard\ql\fs20 `macval(chunk)'\par}"'"' + } + } + else { + local closing `"`macval(thenote)'"' + } + local closing `"`macval(closing)' ``mode'_close2'"' + if `"`macval(title)'"'!="" | "`mode0'"!="tex" { + local closing `"`macval(closing)' ``mode'_close'"' + } + else if "`mode0'"=="tex" & "`star'"!="" { + local closing `"`macval(closing)' }"' + } + if "`page'"!="" { + local closing `"`macval(closing)' ``mode'_close0'"' + } + local toprule `"``mode'_toprule'"' + local bottomrule `"``mode'_bottomrule'"' + local topgap `"``mode'_topgap'"' + local bottomgap `"``mode'_bottomgap'"' + } + local midrule `"``mode'_midrule'"' + local midgap `"``mode'_midgap'"' + local eqrule `"``mode'_eqrule'"' +// - compose prehead() + if `"`macval(prehead)'"'=="" { + if `"`lines'"'!="" { + local opening `"`macval(opening)' `macval(toprule)'"' + } + else if `"`gaps'"'!="" { + local opening `"`macval(opening)' `macval(topgap)'"' + } + SaveRetok `macval(opening)' + local opening `"`macval(value)'"' + if `"`macval(opening)'"'!="" { + local prehead `"prehead(`macval(opening)')"' + } + } +// - compose posthead() + if `"`macval(posthead)'"'=="" { + if `"`lines'"'!="" { + local posthead `"posthead(`macval(midrule)')"' + } + else if `"`gaps'"'!="" { + local posthead `"posthead(`macval(midgap)')"' + } + } +// - compose prefoot() + if `"`macval(prefoot)'"'=="" & `"`macval(stats)'"'!="" { + if `"`lines'"'!="" { + local prefoot `"prefoot(`macval(midrule)')"' + } + else if `"`gaps'"'!="" { + local prefoot `"prefoot(`macval(midgap)')"' + } + if `"`cells'"'=="cells(none)" local prefoot + } +// - compose postfoot() + if `"`macval(postfoot)'"'=="" { + if `"`lines'"'!="" { + local closing `"`macval(bottomrule)' `macval(closing)'"' + } + else if `"`gaps'"'!="" { + local closing `"`macval(bottomgap)' `macval(closing)'"' + } + SaveRetok `macval(closing)' + local closing `"`macval(value)'"' + if `"`macval(closing)'"'!="" { + local postfoot postfoot(`macval(closing)') + } + } +// - varlabels + if `"`macval(varlabels)'"'=="" { + if `"`gaps'"'!="" { + local varl `", end("" `macval(midgap)') nolast"' + } + if "`label'"!="" { + local varl `"_cons Constant`macval(varl)'"' + } + if `"`macval(coeflabels)'"'!="" { + local varl `"`macval(coeflabels)' `macval(varl)'"' + } + if trim(`"`macval(varl)'"')!="" { + local varlabels varlabels(`macval(varl)') + } + } +// - equation labels + if ("`eqlines'"!="" | `"`gaps'"'!="") & "`unstack'"=="" { + if trim(`"`eqlabels'"')!="none" { + ParseEqLabels `macval(eqlabels)' + if `eqlabelsok' { + _parse comma eqllhs eqlrhs : eqlabels + if `"`eqlrhs'"'=="" local eqlabelscomma ", " + else local eqlabelscomma " " + if "`eqlines'"!=""{ + local eqlabels `"`macval(eqlabels)'`eqlabelscomma'`macval(eqrule)' nofirst"' + } + else if `"`gaps'"'!="" { + local eqlabels `"`macval(eqlabels)'`eqlabelscomma'begin(`macval(midgap)' "") nofirst"' + } + } + } + } + if `"`macval(eqlabels)'"'!="" { + local eqlabels `"eqlabels(`macval(eqlabels)')"' + } + +// noconstant option + if `"`drop'"'=="" { + if "`noconstant'"!="" { + local drop drop(_cons, relax) + } + } + +// compute beta coefficients (run estadd to add e(beta)) + if "`beta'"!="" { + local estnames `"`anything'"' + if `"`estnames'"'=="" { + capt est_expand $eststo + if !_rc { + local estnames `"$eststo"' + } + } + version `caller': estadd beta, replace: `estnames' + } + +// use tempfile for new table + if `"`appendfile'"'!="" { + local using `"using `"`appendfile'"'"' + } + +// execute estout + if `"`varwidth'"'!="" local varwidth `"varwidth(`varwidth')"' + if `"`modelwidth'"'!="" local modelwidth `"modelwidth(`modelwidth')"' + if `"`style'"'=="" local style "style(esttab)" + CleanEstoutCmd `anything' `using' , /// + `macval(cells)' `drop' `nomargin' `margin' `margin2' `noeform' `eform' /// + `nodiscrete' `macval(stats)' `stardetach' `macval(starlevels)' /// + `varwidth' `modelwidth' `noabbrev' `abbrev' `unstack' `macval(begin)' /// + `macval(delimiter)' `macval(end)' `macval(incelldelimiter)' `smcltags' /// + `macval(title)' `macval(prehead)' `macval(posthead)' `macval(prefoot)' /// + `macval(postfoot)' `label' `macval(varlabels)' `macval(mlabels)' `nonumbers' /// + `numbers' `macval(collabels)' `macval(eqlabels)' `macval(mgroups)' /// + `macval(note)' `macval(labcol2)' `macval(substitute)' `append' /// + `notype'`type' `outfilenoteoff2' level(`level') `style' `macval(options)' + if "`noisily'"!="" { + gettoken chunk rest: cmd, parse(",") + di as txt _asis `"`chunk'"' _c + gettoken chunk rest: rest, bind + while `"`macval(chunk)'"'!="" { + di as txt _asis `" `macval(chunk)'"' + gettoken chunk rest: rest, bind + } + } + `macval(cmd)' + +// insert new table into existing document (tex, html, rtf) + if `"`appendfile'"'!="" { + local enddoctex "\end{document}" + local enddochtml "" + local enddocrtf "}" + local enddoc "`enddoc`mode0''" + tempname fh + file open `fh' using `using0', read write + file seek `fh' query + local loc = r(loc) + file read `fh' line + while r(eof)==0 { + if `"`line'"'=="`enddoc'" { + if "`mode'"=="rtf" { + file seek `fh' query + local loc0 = r(loc) + file read `fh' line + if r(eof)==0 { + local loc = `loc0' + continue + } + } + continue, break + } + file seek `fh' query + local loc = r(loc) + file read `fh' line + } + file seek `fh' `loc' + tempname new + file open `new' `using', read + file read `new' line + while r(eof)==0 { + file write `fh' `"`macval(line)'"' _n + file read `new' line + } + file close `fh' + file close `new' + if "`outfilenoteoff'"=="" { + di as txt `"(output written to {browse `using0'})"' + } + } +end + +program _more_syntax +// using subroutine (rather than second syntax call) to preserve 'using' + local theoptions /// + NODEPvars DEPvars /// + NOPArentheses PArentheses /// + BRackets /// + NONOTEs NOTEs /// without s in helpfile + LONGtable /// + ONEcell /// + NOEQLInes /// + NOOUTFILENOTEOFF outfilenoteoff + syntax [, `theoptions' * ] + foreach opt of local theoptions { + local opt = lower("`opt'") + c_local `opt' "``opt''" + } + c_local options `"`macval(options)'"' +end + +program _estout_options + syntax [, /// + Cells(passthru) /// + Drop(passthru) /// + /// Keep(string asis) /// + /// Order(string asis) /// + /// REName(passthru) /// + /// Indicate(string asis) /// + /// TRansform(string asis) /// + /// EQuations(passthru) /// + NOEFORM eform ///EFORM2(string) /// + NOMargin Margin Margin2(passthru) /// + NODIscrete /// DIscrete(string asis) /// + /// MEQs(string) /// + /// NODROPPED dropped DROPPED2(string) /// + level(numlist max=1 int >=10 <=99) /// + Stats(passthru) /// + STARLevels(passthru) /// + /// NOSTARDetach /// + STARDetach /// + /// STARKeep(string asis) /// + /// STARDrop(string asis) /// + VARwidth(str) /// + MODELwidth(str) /// + NOABbrev ABbrev /// + /// NOUNStack + UNStack /// + BEGin(passthru) /// + DELimiter(passthru) /// + INCELLdelimiter(passthru) /// + end(passthru) /// + /// DMarker(string) /// + /// MSign(string) /// + /// NOLZ lz /// + SUBstitute(passthru) /// + TItle(passthru) /// + NOLEgend LEgend /// + PREHead(passthru) /// + POSTHead(passthru) /// + PREFoot(passthru) /// + POSTFoot(passthru) /// + /// HLinechar(string) /// + /// NOLabel + Label /// + VARLabels(passthru) /// + /// REFcat(string asis) /// + MLabels(passthru) /// + NONUMbers NUMbers ///NUMbers2(string asis) /// + COLLabels(passthru) /// + EQLabels(string asis) /// + MGRoups(passthru) /// + LABCOL2(passthru) /// + /// NOReplace Replace /// + /// NOAppend + Append /// + NOTYpe TYpe /// + /// NOSHOWTABS showtabs /// + /// TOPfile(string) /// + /// BOTtomfile(string) /// + STYle(passthru) /// + /// DEFaults(string) /// + /// NOASIS asis /// + /// NOWRAP wrap /// + /// NOSMCLTAGS smcltags /// + /// NOSMCLRules SMCLRules /// + /// NOSMCLMIDRules SMCLMIDRules /// + /// NOSMCLEQRules SMCLEQRules /// + note(passthru) /// + * ] + foreach opt in /// + cells drop noeform eform nomargin margin margin2 nodiscrete /// + level stats starlevels stardetach varwidth modelwidth unstack /// + noabbrev abbrev begin delimiter incelldelimiter end substitute title nolegend /// + legend prehead posthead prefoot postfoot label varlabels mlabels labcol2 /// + nonumbers numbers collabels eqlabels mgroups append notype type style note /// + options { + c_local `opt' `"`macval(`opt')'"' + } +end + +program MatrixMode + capt syntax [, Matrix(str asis) e(str asis) r(str asis) rename(str asis) ] + if _rc | `"`matrix'`e'`r'"'=="" { + c_local matrixmode 0 + exit + } + c_local matrixmode 1 +end + +prog NotBothAllowed + args opt1 opt2 + if `"`opt1'"'!="" { + if `"`opt2'"'!="" { + di as err `"options `opt1' and `opt2' not both allowed"' + exit 198 + } + } +end + +prog SwitchOnIfEmpty + args opt1 opt2 + if `"`opt2'"'=="" { + c_local `opt1' `opt1' + } +end + +prog _getfilesuffix, rclass // based on official _getfilename.ado + version 8 + gettoken filename rest : 0 + if `"`rest'"' != "" { + exit 198 + } + local hassuffix 0 + gettoken word rest : filename, parse(".") + while `"`rest'"' != "" { + local hassuffix 1 + gettoken word rest : rest, parse(".") + } + if `"`word'"'=="." { + di as err `"incomplete filename; ends in ."' + exit 198 + } + if index(`"`word'"',"/") | index(`"`word'"',"\") local hassuffix 0 + if `hassuffix' return local suffix `".`word'"' + else return local suffix "" +end + +prog FormatStarSym + args mode list + if inlist("`mode'","rtf","html","tex") { + if "`mode'"=="rtf" { + local prefix "{\super " + local suffix "}" + } + else if "`mode'"=="html" { + local prefix "" + local suffix "" + } + else if "`mode'"=="tex" { + local prefix "\sym{" + local suffix "}" + } + local odd 1 + foreach l of local list { + if `odd' { + local l `"`"`prefix'`macval(l)'`suffix'"'"' + local odd 0 + } + else local odd 1 + local newlist `"`macval(newlist)'`space'`macval(l)'"' + local space " " + } + c_local star2 `"`macval(newlist)'"' + } + //else do noting +end + +prog CheckScalarOpt + capt syntax [anything] + if _rc error 198 +end + +prog MakeTeXColspec + args wide not star detach aux + if "`star'"!="" & "`detach'"!="" & "`aux'"=="" local value "r@{}l" + else local value "c" + if "`wide'"!="" & "`not'"=="" { + if "`star'"!="" & "`detach'"!="" & "`aux'"!="" local value "`value'r@{}l" + else local value "`value'c" + } + c_local value "`value'" +end + +prog MakeTeXColspecAlt + syntax, cells(string asis) + local count 1 + while `count' { + local cells: subinstr local cells " (" "(", all count(local count) + } + local count 1 + while `"`macval(cells)'"'!="" { + gettoken row cells : cells, bind + local size 0 + gettoken chunk row : row, bind + while `"`macval(chunk)'"'!="" { + local ++size + gettoken chunk row : row, bind + } + local count = max(`count',`size') + } + c_local value: di _dup(`count') "c" +end + +prog SaveRetok + gettoken chunk 0: 0, q + local value `"`macval(chunk)'"' + gettoken chunk 0: 0, q + while `"`macval(chunk)'"'!="" { + local value `"`macval(value)' `macval(chunk)'"' + gettoken chunk 0: 0, q + } + c_local value `"`macval(value)'"' +end + +prog CleanEstoutCmd + syntax [anything] [using] [ , * ] + local cmd estout + if `"`macval(anything)'"'!="" { + local cmd `"`macval(cmd)' `macval(anything)'"' + } + if `"`macval(using)'"'!="" { + local cmd `"`macval(cmd)' `macval(using)'"' + } + if `"`macval(options)'"'!="" { + local cmd `"`macval(cmd)', `macval(options)'"' + } + c_local cmd `"`macval(cmd)'"' +end + +prog ParseEqLabels + syntax [anything] [, Begin(passthru) NOReplace Replace NOFirst First * ] + c_local eqlabelsok = `"`begin'`noreplace'`replace'`nofirst'`first'"'=="" +end diff --git a/Modules/ado/plus/e/esttab.hlp b/Modules/ado/plus/e/esttab.hlp new file mode 100644 index 0000000..a2adb9d --- /dev/null +++ b/Modules/ado/plus/e/esttab.hlp @@ -0,0 +1,905 @@ +{smcl} +{* 08oct2009}{...} +{hi:help esttab}{right:also see: {helpb estout}, {helpb eststo}, {helpb estadd}, {helpb estpost}} +{right: {browse "http://repec.org/bocode/e/estout"}} +{hline} + +{title:Title} + +{p 4 4 2}{hi:esttab} {hline 2} Display formatted regression table + + +{title:Table of contents} + + {help esttab##syn:Syntax} + {help esttab##des:Description} + {help esttab##opt:Options} + {help esttab##exa:Examples} + {help esttab##aut:Backmatter} + +{marker syn} +{title:Syntax} + +{p 8 15 2} +{cmd:esttab} [ {it:namelist} ] [ {cmd:using} {it:filename} ] [ {cmd:,} +{it:options} ] + + +{p 4 4 2}where {it:namelist} is a name, a list of names, or {cmd:_all}. The +{cmd:*} and {cmd:?} wildcards are allowed in {it:namelist}. A name may also be {cmd:.}, +meaning the current (active) estimates. + + + {it:options}{col 26}description + {hline 70} + {help esttab##main:Main} + {cmd:b(}{it:{help esttab##fmt:fmt}}{cmd:)}{col 26}{...} +specify format for point estimates + {cmd:beta}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}]{col 26}{...} +display beta coefficients instead of point est's + {cmd:main(}{it:name} [{it:{help esttab##fmt:fmt}}]{cmd:)}{col 26}{...} +display contents of {cmd:e(}{it:name}{cmd:)} instead of point e's + {cmd:t(}{it:{help esttab##fmt:fmt}}{cmd:)}{col 26}{...} +specify format for t-statistics + {cmd:abs}{col 26}{...} +use absolute value of t-statistics + {cmd:not}{col 26}{...} +suppress t-statistics + {cmd:z}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}]{col 26}{...} +display z-statistics (affects label only) + {cmd:se}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}]{col 26}{...} +display standard errors instead of t-statistics + {cmd:p}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}]{col 26}{...} +display p-values instead of t-statistics + {cmd:ci}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}]{col 26}{...} +display confidence intervals instead of t-stat's + {cmd:aux(}{it:name} [{it:{help esttab##fmt:fmt}}]{cmd:)}{col 26}{...} +display contents of {cmd:e(}{it:name}{cmd:)} instead of t-stat's + [{ul:{cmd:no}}]{cmdab:con:stant}{col 26}{...} +do not/do report the intercept + + {help esttab##stars:Significance stars} + [{cmd:no}]{cmd:star}[{cmd:(}{it:list}{cmd:)}]{col 26}{...} +do not/do report significance stars + {cmd:staraux}{col 26}{...} +attach stars to t-stat's instead of point est's + + {help esttab##stat:Summary statistics} + {cmd:r2}|{cmd:ar2}|{cmd:pr2}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}]{col 26}{...} +display (adjusted, pseudo) R-squared + {cmd:aic}|{cmd:bic}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}]{col 26}{...} +display Akaike's or Schwarz's information crit. + {cmdab:sca:lars:(}{it:list}{cmd:)}{col 26}{...} +display any other scalars contained in {cmd:e()} + {cmd:sfmt(}{it:{help esttab##fmt:fmt}} [{it:...}]{cmd:)}{col 26}{...} +set format(s) for {cmd:scalars()} + {cmd:noobs}{col 26}{...} +do not display the number of observations + {cmd:obslast}{col 26}{...} +place the number of observations last + + {help esttab##layout:Layout} + {cmd:wide}{col 26}{...} +place point est's and t-stat's beside one another + {cmdab:one:cell}{col 26}{...} +combine point est's and t-stat's in a single cell + [{ul:{cmd:no}}]{cmdab:pa:rentheses}{col 26}{...} +do not/do print parentheses around t-statistics + {cmdab:br:ackets}{col 26}{...} +use brackets instead of parentheses + [{ul:{cmd:no}}]{cmdab:gap:s}{col 26}{...} +suppress/add vertical spacing + [{ul:{cmd:no}}]{cmdab:li:nes}{col 26}{...} +suppress/add horizontal lines + {cmdab:noeqli:nes}{col 26}{...} +suppress lines between equations + {cmd:compress}{col 26}{...} +reduce horizontal spacing + {cmd:plain}{col 26}{...} +produce a minimally formatted table + + {help esttab##label:Labeling} + {cmdab:l:abel}{col 26}{...} +make use of variable labels + {cmdab:ti:tle:(}{it:string}{cmd:)}{col 26}{...} +specify a title for the table + {cmdab:mti:tles}[{cmd:(}{it:list}{cmd:)}]{col 26}{...} +specify model titles to appear in table header + {cmdab:nomti:tles}{col 26}{...} +disable model titles + [{ul:{cmd:no}}]{cmdab:dep:vars}{col 26}{...} +do not/do use dependent variables as model titles + [{ul:{cmd:no}}]{cmdab:num:bers}{col 26}{...} +do not/do print model numbers in table header + {cmdab:coef:labels:(}{it:list}{cmd:)}{col 26}{...} +specify labels for coefficients + [{ul:{cmd:no}}]{cmdab:note:s}{col 26}{...} +suppress/add notes in the table footer + {cmdab:addn:otes:(}{it:list}{cmd:)}{col 26}{...} +add lines at the end of the table + + {help esttab##format:Document format} + {cmd:smcl} | {cmdab:fix:ed} | {cmd:tab} | {cmd:csv} | {cmdab:sc:sv} | {cmd:rtf} | {cmdab:htm:l} | {cmd:tex} | {cmdab:bookt:abs} + {col 26}{...} +set the document format ({cmd:smcl} is the default) + {cmdab:f:ragment}{col 26}{...} +suppress table opening and closing (LaTeX, HTML) + {cmd:page}[{cmd:(}{it:packages}{cmd:)}]{col 26}{...} +add page opening and closing (LaTeX, HTML) + {cmdab:align:ment(}{it:string}{cmd:)}{col 26}{...} +set alignment within columns (LaTeX, HTML, RTF) + {cmdab:width(}{it:string}{cmd:)}{col 26}{...} +set width of table (LaTeX, HTML) + {cmdab:long:table}{col 26}{...} +multi-page table (LaTeX) + + {help esttab##output:Output} + {cmdab:r:eplace}{col 26}{...} +overwrite an existing file + {cmdab:a:ppend}{col 26}{...} +append the output to an existing file + {cmdab:ty:pe}{col 26}{...} +force prining the table in the results window + {cmdab:n:oisily}{col 26}{...} +display the executed {helpb estout} command + + {help esttab##advanced:Advanced} + {cmdab:d:rop:(}{it:list}{cmd:)}{col 26}{...} +drop individual coefficients + {cmdab:k:eep:(}{it:list}{cmd:)}{col 26}{...} +keep individual coefficients + {cmdab:o:rder:(}{it:list}{cmd:)}{col 26}{...} +change order of coefficients + {cmdab:eq:uations:(}{it:list}{cmd:)}{col 26}{...} +match the models' equations + {cmd:eform}{col 26}{...} +report exponentiated coefficients + {cmdab:m:argin}{col 26}{...} +report marginal effects/elasticities + {cmdab:uns:tack}{col 26}{...} +place multiple equations in separate columns + {it:estout_options}{col 26}{...} +any other {helpb estout} options + {hline 70} + +{marker des} +{title:Description} + +{p 4 4 2} +{cmd:esttab} is a wrapper for {helpb estout}. It produces a +pretty-looking publication-style regression table from stored +estimates without much typing. The compiled table is displayed in the +Stata results window or, optionally, written to a text file specified +by {cmd:using} {it:filename}. If {it:filename} is specified without +suffix, a default suffix is added depending on the specified document +format (".smcl" for {cmd:smcl}, ".txt" for {cmd:fixed} and {cmd:tab}, ".csv" for {cmd:csv} +and {cmd:scsv}, ".rtf" for {cmd:rft}, ".html" for {cmd:html}, and +".tex" for {cmd:tex} and {cmd:booktabs}). + +{p 4 4 2} +{it:namelist} provides the names of the stored estimation sets to be +tabulated. You may use the {cmd:*} and {cmd:?} wildcards in +{it:namelist}. If {it:namelist} is omitted, {cmd:esttab} tabulates the +estimation sets stored by {cmd:eststo} (see help {helpb eststo}) +or, if no such estimates are present, the currently active +estimates (i.e. the model fit last). + +{p 4 4 2} +See help {helpb estimates} for information about storing estimation +results. An alternative to the {cmd:estimates store} command is +provided by {helpb eststo}. + +{p 4 4 2} +{cmd:esttab} can also be used to tabulate a Stata matrix applying syntax +{bind:{cmd:esttab} {cmdab:m:atrix:(}{it:name}{cmd:)}}, where {it:name} +is the name of the matrix. Furthermore, an {cmd:e()}-matrix or {cmd:r()}-matrix +can be tabulated specifying {cmd:esttab e(}{it:name}{cmd:)} or +{cmd:esttab r(}{it:name}{cmd:)}. Most options under the headings +'Main', 'Significance stars', and 'Summary statistics' are irrelevant +in this case. See help {helpb estout} for further details on tabulating matrices. + +{marker opt} +{title:Options} +{marker main} +{dlgtab:Main} + +{p 4 8 2} +{cmd:b(}{it:{help esttab##fmt:fmt}}{cmd:)} sets the numerical display format +for the point estimates. The default format is {cmd:a3}. (See +{help esttab##fmt:Numerical formats} below for details on available +formats.) + +{p 4 8 2} +{cmd:beta}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}] requests that +standardized beta coefficients be displayed in place of the raw point +estimates and, optionally, sets the display format (the default is to +print three decimal places). Note that {cmd:beta} causes the +intercept to be dropped from the table (unless {cmd:constant} is +specified).{p_end} +{marker main} +{p 4 8 2} +{cmd:main(}{it:name} [{it:{help esttab##fmt:fmt}}]{cmd:)} requests that +the statistics stored in {cmd:e(}{it:name}{cmd:)} be displayed in +place of the point estimates and, optionally, sets the display format +(the default is to use the display format for point estimates). For +example, {cmd:e(}{it:name}{cmd:)} may contain statistics added by +{cmd:estadd} (see help {helpb estadd}). + +{p 4 8 2} +{cmd:t(}{it:{help esttab##fmt:fmt}}{cmd:)} sets the display format for +t-statistics. The default is to display two decimal places. + +{p 4 8 2} +{cmd:abs} causes absolute values of t-statistics to be reported. + +{p 4 8 2} +{cmd:not} suppresses the printing of t-statistics. + +{p 4 8 2} +{cmd:z}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}] requests that +z-statistics be displayed. z-statistics are the same as t-statistics. Hence, +specifying {cmd:z} does not change the table contents, it only changes the +label. + +{p 4 8 2} +{cmd:se}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}] requests that +standard errors be displayed in place of t-statistics and, +optionally, sets the display format (the default is to use the +display format for point estimates). + +{p 4 8 2} +{cmd:p}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}] requests that +p-values be displayed in place of t-statistics and, optionally, sets +the display format (the default is to print three decimal places) + +{p 4 8 2} +{cmd:ci}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}] requests that +confidence intervals be displayed in place of t-statistics and, +optionally, sets the display format (the default is to use the +display format for point estimates). {cmd:level(}{it:#}{cmd:)} +assigns the confidence level, in percent. The default is +{cmd:level(95)} or as set by {helpb set level}.{p_end} +{marker aux} +{p 4 8 2} +{cmd:aux(}{it:name} [{it:{help esttab##fmt:fmt}}]{cmd:)} requests that +the statistics stored in {cmd:e(}{it:name}{cmd:)} be displayed in +place of t-statistics and, optionally, sets the display format (the +default is to use the display format for point estimates). For +example, {cmd:e(}{it:name}{cmd:)} may contain statistics added by +{cmd:estadd} (see help {helpb estadd}, if installed). + +{p 4 8 2} +{cmd:noconstant} causes the intercept be dropped from the table. +Specify {cmd:constant} to include the constant in situations where it +is dropped by default. + +{marker stars} +{dlgtab:Significance stars} + +{p 4 8 2} +{cmd:star}[{cmd:(}{it:symbol} {it:level} [{it:...}]{cmd:)}] causes +stars denoting the significance of the coefficients to be printed +next to the point estimates. This is the default. Type {cmd:nostar} +to suppress the stars. The default symbols and thresholds are: +{cmd:*} for p<.05, {cmd:**} for p<.01, and {cmd:***} for p<.001. +Alternatively, for example, type {bind:{cmd:star(+ 0.10 * 0.05)}} to +set the following thresholds: {cmd:+} for p<.10 and {cmd:*} for +p<.05. Note that the thresholds must lie in the (0,1] interval and +must be specified in descending order. + +{p 4 8 2} +{cmd:staraux} causes the significance stars be printed next to the +t-statistics (or standard errors, etc.) instead of the point estimates. + +{marker stat} +{dlgtab:Summary statistics} + +{p 4 8 2} +{cmd:r2}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}], +{cmd:ar2}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}], and +{cmd:pr2}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}] +include the R-squared, the adjusted R-squared, and the +pseudo-R-squared in the table footer and, optionally, set the +corresponding display formats (the default is to display three +decimal places). + +{p 4 8 2} +{cmd:aic}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}] and +{cmd:bic}[{cmd:(}{it:{help esttab##fmt:fmt}}{cmd:)}] +include Akaike's and Schwarz's information criterion in the table +footer and, optionally, set the corresponding display formats (the +default is to use the display format for point estimates).{p_end} +{marker scalars} +{p 4 8 2} +{cmd:scalars(}{it:list}{cmd:)} may be used to add other +{cmd:e()}-scalars to the table footer (type {cmd:ereturn list} to +display a list of available {cmd:e()}-scalars after fitting a model; +see help {helpb ereturn}). For example, {cmd:scalars(df_m)} would +report the model degrees of freedom for each model. {it:list} may be +a simple list of names of {cmd:e()}-scalars, e.g. + + {com}. esttab, scalars(ll_0 ll chi2){txt} + +{p 8 8 2} +or, alternatively, a list of quoted name-label pairs, e.g. + + {com}. esttab, scalars({bind:"ll Log lik."} {bind:"chi2 Chi-squared"}){txt} + +{p 4 8 2} +{cmd:sfmt(}{it:{help esttab##fmt:fmt}} [{it:...}]{cmd:)} sets the +display format(s) for the statistics specified in {cmd:scalars()} +(the default is to use the display format for point estimates). If +{cmd:sfmt()} contains less elements than {cmd:scalars()}, the last +specified format is used for the remaining scalars. That is, only one +format needs to be specified if the same format be used for all +scalars. + +{p 4 8 2} +{cmd:noobs} suppresses displaying information on the number of +observations. The default is to report the number of observations for +each model in the table footer. + +{p 4 8 2} +{cmd:obslast} displays the number of observations in the last row of +the table footer. The default is to use the first row. + +{marker layout} +{dlgtab:Layout} +{marker wide} +{p 4 8 2} +{cmd:wide} causes point estimates and t-statistics (or standard errors, +etc.) to be printed beside one another instead of beneath one another. +{p_end} +{marker onecell} +{p 4 8 2} +{cmd:onecell} causes point estimates and t-statistics (or standard errors, +etc.) to be combined in a single table cell. This option is useful primarily +in {cmd:rtf} or {cmd:html} mode. In these modes a line break is +inserted between the two statistics. The benefit from using {cmd:onecell} +in {cmd:rtf} or {cmd:html} mode is that long coefficients labels do not +derange the table layout. The default for other modes is to insert +a blank between the statistics. Use {cmd:estout}'s +{helpb estout##incelldel:incelldelimiter()} option to change this. + +{p 4 8 2} +{cmd:parentheses} encloses t-statistics (or standard errors, etc.) in +parentheses. This is the default. Specify {cmd:noparentheses} to +suppress the parentheses. + +{p 4 8 2} +{cmd:brackets} uses square brackets, [], instead of parentheses. Note +that brackets are the default for confidence intervals. + +{p 4 8 2} +{cmd:gaps} adds empty rows (or, more generally, additional vertical +space) between coefficients to increase readability (empty rows are +also inserted between the table's header, body, and footer, unless +{cmd:lines} is activated). This is the default unless {cmd:wide} or +{cmd:not} is specified. Type {cmd:nogaps} to suppress the extra +spacing. + +{p 4 8 2} +{cmd:lines} adds horizontal lines to the table separating the table's +header, body, and footer and, in the case of multiple +equation models, the equations. This is the default. Specify {cmd:nolines} +to suppress the lines. Lines are always suppressed in the {cmd:tab} +and {cmd:csv} modes. + +{p 4 8 2} +{cmd:noeqlines} suppresses the horizontal lines between equations +in the case of multiple equation models.{p_end} +{marker compress} +{p 4 8 2} +{cmd:compress} reduces the amount of horizontal spacing (so that more +models fit on screen without line breaking). The option has no effect +in the {cmd:tab} and {cmd:csv} modes. Furthermore, note that in the +TeX and HTML modes the {cmd:compress} option only changes the +arrangement the table's code, but not the look of the compiled +end-product. In {cmd:rtf}, however, {cmd:compress} changes the look +of the formatted table.{p_end} +{marker plain} +{p 4 8 2} +{cmd:plain} produces a minimally formatted table. It is a shorthand +to specifying {cmd:nostar}, {cmd:nodepvars}, {cmd:nonumbers}, +{cmd:noparentheses}, {cmd:nogaps}, {cmd:nolines} and {cmd:nonotes} +and setting all formats to {cmd:%9.0g}. Note that the disabled +options can be switched on again. For example, type + + {com}. esttab, plain star{txt} + +{p 8 8 2} +to produce a plain table including significance stars. + +{marker label} +{dlgtab:Labeling} + +{p 4 8 2} +{cmd:label} specifies that variable labels be used instead of +variable names (and estimation set titles be used instead of +estimation set names). Furthermore, {cmd:label} prints "Constant" +instead of "_cons". +{p_end} +{marker title} +{p 4 8 2} +{cmd:title(}{it:string}{cmd:)} may be used to provide a title for the +table. If specified, {it:string} is printed at the top of the table. +Note that specifying a title causes the table to be set up as a +floating object in LaTeX mode. You may want to set a label for +referencing in this case. For example, if you type +{cmd:title(...\label{tab1})}, then "\ref{tab1}" could be used in the +LaTeX document to point to the table. + +{p 4 8 2} +{cmd:mtitles}, without argument, specifies that for each model the title +(or, if empty, the name) of the stored estimation set be printed as the model's +title in the table header. If {cmd:mtitles} is omitted, the default is to +use name or label of the dependent variable as the model's title (see the +{cmd:depvar} option). Alternatively, use {cmd:mtitles(}{it:list}{cmd:)} +specifies a list of model titles. Enclose the titles +in double quotes if they contain spaces, +e.g. {bind:{cmd:mtitles("Model 1" "Model 2")}}. + +{p 4 8 2} +{cmd:nomtitles} suppresses printing of model titles. + +{p 4 8 2} +{cmd:depvars} prints the name (or label) of the (first) dependent +variable of a model as the model's title in the table header. This is +the default. Specify {cmd:nodepvars} to use the names of +the stored estimation sets as titles. + +{p 4 8 2} +{cmd:numbers} includes a row containing consecutive model numbers in +the table header. This is the default. Specify {cmd:nonumbers} to +suppress printing the model numbers. + +{p 4 8 2} +{cmd:coeflabels(}{it:name} {it:label} [...]{cmd:)} specifies labels +for the coefficients. Specify names and labels in pairs and, if +necessary, enclose labels in double quotes, +e.g. {cmd:coeflabels(mpg Milage rep78 {bind:"Repair Record"})}. + +{p 4 8 2} +{cmd:notes} prints notes at the end of the table explaining the +significance symbols and the type of displayed statistics. This is +the default. Specify {cmd:nonotes} to suppress the notes. + +{p 4 8 2} +{cmd:addnotes(}{it:list}{cmd:)} may be used to add further lines of +text at the bottom of the table. Lines containing blanks must be +enclosed in double quotes, +e.g. {cmd:addnotes({bind:"Line 1"} {bind:"Line 2"})}. + +{marker format} +{dlgtab:Document format} + +{p 4 8 2} +{cmd:smcl}, {cmd:fixed}, {cmd:tab}, {cmd:csv}, {cmd:scsv}, {cmd:rtf}, +{cmd:html}, {cmd:tex}, and {cmd:booktabs} choose the table's basic +output format. The default format is {cmd:smcl} unless +{cmd:using} is specified, in which case the default format +depends on the filename's suffix ({cmd:smcl} for ".smcl", {cmd:csv} +for ".csv", {cmd:rtf} for ".rtf", +{cmd:html} for ".htm" or ".html", {cmd:tex} for ".tex", and {cmd:fixed} +for all other filenames). + +{p 8 8 2} +{cmd:smcl} produces a {help SMCL} formatted table to be displayed in the +Stata results window or the Stata viewer. + +{p 8 8 2} +{cmd:fixed} produces a fixed-format ASCII table. This is suitable, +for example, if the table be displayed in a text editor. + +{p 8 8 2} +{cmd:tab} produces a tab-delimited ASCII table. +{p_end} +{marker csv} +{p 8 8 2} +{cmd:csv} produces a CSV ({ul:C}omma {ul:S}eparated {ul:V}alue +format) table for use with Microsoft Excel. Delimiter is a comma. In +order to prevent Excel from interpreting the contents of the table +cells, they are enclosed double quotes preceded by an equal sign +(i.e. ="..."). However, if the {cmd:plain} option is specified, the +table cells are enclosed in double quotes without the leading equal +sign. The first method is appropriate if you want to preserve the +table's formatting. The second method is appropriate if you want to +use the table's contents for further computations in Excel. +{p_end} +{marker scsv} +{p 8 8 2} +{cmd:scsv} is a variant on the CSV format that uses a semicolon as +the delimiter. This is appropriate for some non-English versions of +Excel (e.g. the German version). +{p_end} +{marker rtf} +{p 8 8 2} +{cmd:rtf} produces a Rich Text Format table for use with word +processors. + +{p 8 8 2} +{cmd:html} produces a simple HTML formatted table. + +{p 8 8 2} +{cmd:tex} produces a LaTeX formatted table. +{p_end} +{marker booktabs} +{p 8 8 2} +{cmd:booktabs} produces a LaTeX formatted table for use with LaTeX's +{it:booktabs} package. +{p_end} +{marker fragment} +{p 4 8 2} +{cmd:fragment} causes the table's opening and closing specifications +to be suppressed. This is relevant primarily in LaTeX and HTML mode. + +{p 4 8 2} +{cmd:page}[{cmd:(}{it:packages}{cmd:)}] adds opening and closing code +to define a whole LaTeX or HTML document. The default is to produce a +raw table that can then be included into an existing LaTeX or HTML +document. Specifying {it:packages} in parentheses causes +{cmd:\usepackage{c -(}}{it:packages}{cmd:{c )-}} to be added to the +preamble of the LaTeX document (note that the {it:booktabs} package +is automatically loaded if {cmd:booktabs} is specified). + +{p 4 8 2} +{cmd:alignment(}{it:string}{cmd:)} may be used to specify the +alignment of the models' columns in LaTeX, HTML, or RTF mode. + +{p 8 8 2} +In LaTeX mode {it:string} should be a LaTeX column specifier. The +default is to center the columns. To produce right-aligned columns, +for example, type {cmd:alignment(r)}. If the table contains multiple +columns per model/equation, the alignment specification should define +all columns. For example, if the {cmd:wide} option is specified, you +could type {cmd:alignment(cr)} to, say, center the point estimates +and right-align the t-statistics. Note that more sophisticated column +definitions are often needed to produce appealing results. In +particular, LaTeX's {it:dcolumn} package proves useful to align +columns on the decimal point. + +{p 8 8 2} +In HTML mode {it:string} should be a HTML alignment specifier. The +default is to omit alignment specification, which results in left +aligned columns. To center the columns in HTML, for example, specify +{cmd:alignment(center)}. Other than in LaTeX mode, the same alignment +is used for all columns if the table contains multiple columns per +model/equation in the HTML mode. + +{p 8 8 2} +In RTF mode {it:string} should be one of {cmd:l}, {cmd:c}, {cmd:r}, +and {cmd:j}. The default is to center the columns. To produce +right-aligned columns, for example, type {cmd:alignment(r)}. The same +alignment is used for all columns if the table contains multiple +columns per model/equation in the RTF mode. + +{p 8 8 2} +Note that {cmd:alignment()} does not change the alignment of the +variable names/labels in the left stub of the table. They are always +left-aligned. + +{p 4 8 2} +{cmd:width(}{it:string}{cmd:)} sets the overall width of the table in +LaTeX or HTML. {it:string} should be LaTeX or HTML literal. For +example, specify {cmd:width(\hsize)} in LaTeX or {cmd:width(100%)} in +HTML to span the whole page. The table columns will spread regularly +over the specified width. Note that in RTF mode {helpb estout}'s +{cmd:varwidth()} and {cmd:modelwidth()} options may be used to change +the width of the table columns. + +{p 4 8 2} +{cmdab:longtable} causes the {it:longtable} environment to be used in +LaTeX. Use {cmdab:longtable} for tables that are too +long to fit on a single page. {cmdab:longtable} cannot be combined +with {cmd:width()}. Make sure to load the {it:longtable} package +in the LaTeX document, i.e. include {cmd:\usepackage{longtable}} in the +document's preamble. + +{marker output} +{dlgtab:Output} + +{p 4 8 2} +{cmd:replace} permits {cmd:esttab} to overwrite an existing file. + +{p 4 8 2} +{cmd:append} specifies that the output be appended to an existing +file. It may be used even if the file does not yet exist. Specifying +{cmd:append} together with {cmd:page} in TeX or HTML mode causes the +new table to be inserted at the end of the body of an existing +document ({cmd:esttab} seeks a line reading "\end{document}" or +"", respectively, and starts appending from there; +contents after this line will be overwritten). In RTF mode, existing +documents are assumed to end with a line containing a single "}". + +{p 4 8 2} +{cmd:type} specifies that the assembled table be printed in the +results window and the log file. This is the default unless +{cmd:using} is specified. + +{p 4 8 2} +{cmd:noisily} displays the executed {helpb estout} command. + +{marker advanced} +{dlgtab:Advanced} + +{p 4 8 2} +{cmd:drop(}{it:droplist}{cmd:)} identifies the coefficients to be +dropped from the table. A {it:droplist} comprises one or more +specifications, separated by white space. A specification can be +either a parameter name (e.g. {cmd:price}), an equation name followed +by a colon (e.g. {cmd:mean:}), or a full name +(e.g. {cmd:mean:price}). You may use the {cmd:*} and {cmd:?} wildcards +in equation names and parameter names. Be sure to refer to the matched +equation names, and not to the original equation names in the models, +when using the {cmd:equations()} option to match equations. + +{p 4 8 2} +{cmd:keep(}{it:keeplist}{cmd:)} selects the coefficients to be +included in the table. {it:keeplist} is specified analogous to +{it:droplist} in {cmd:drop()} (see above). + +{p 4 8 2} +{cmd:order(}{it:orderlist}{cmd:)} changes the order of the +coefficients and equations within the table. {it:orderlist} is +specified analogous to {it:droplist} in {cmd:drop()} (see above). +Coefficients and equations that do not appear in {it:orderlist} are +placed last (in their original order). + +{p 4 8 2} +{cmd:equations(}{it:eqmatchlist}{cmd:)} specifies how the models' +equations are to be matched. This option is passed to the internal +call of {cmd:estimates table}. See help {helpb estimates} on how to +specify this option. The most common usage is {cmd:equations(1)} to +match all the first equations in the models. + +{p 4 8 2} +{cmd:eform} displays the regression table in exponentiated form. The +exponent of a coefficient is displayed in lieu of the untransformed +coefficient; standard errors and confidence intervals are transformed +as well. Note that the intercept is dropped in eform-mode, unless +{cmd:constant} is specified. + +{p 4 8 2} +{cmd:margin} indicates that the marginal effects or elasticities be +reported instead of the raw coefficients. A prerequisite for this +option to work correctly is that {cmd:mfx} has been applied to a +model prior to storing its results (see help {helpb mfx}). Note that +the standard errors, etc. are transformed as well. Furthermore, the +intercept is dropped, unless {cmd:constant} is specified. + +{p 4 8 2} +{cmd:unstack} specifies that the individual equations from +multiple-equation models (e.g. {cmd:mlogit}, {cmd:reg3}, +{cmd:heckman}) be placed in separate columns. The default is to place +the equations below one another in a single column. + +{p 4 8 2} +{it:estout_options} are any other {cmd:estout} options (see help +{helpb estout}). Note that {cmd:estout} options take precedence over +{cmd:esttab} options. For example, + +{p 8 20 2} +{cmd:cells()}{space 5}disables {cmd:b()}, {cmd:beta()}, {cmd:main()}, +{cmd:t()}, {cmd:abs}, {cmd:not}, {cmd:se()}, {cmd:p()}, {cmd:ci()}, +{cmd:aux()}, {cmd:star}, {cmd:staraux}, {cmd:wide}, {cmd:onecell}, +{cmd:parentheses}, and {cmd:brackets}, + +{p 8 20 2} +{cmd:stats()}{space 5}disables {cmd:r2()}, {cmd:ar2()}, {cmd:pr2()}, +{cmd:aic()}, {cmd:bic()}, {cmd:scalars()}, {cmd:sfmt()}, {cmd:noobs}, +and {cmd:obslast}. + +{p 8 8 2} +Other {cmd:estout} options that should be used with care are +{cmd:begin()}, {cmd:delimiter()}, {cmd:end()}, {cmd:prehead()}, +{cmd:posthead()}, {cmd:prefoot()}, {cmd:postfoot()}, {cmd:mlabels()}, +and {cmd:varlabels()}. + +{marker fmt} +{dlgtab:Numerical formats} + +{p 4 4 2} +Numerical display formats may be specified in {cmd:esttab} as follows: + +{p 5 8 2} +1. Official Stata's display formats: You may specify formats, such as +{cmd:%9.0g} or {cmd:%8.2f}. See help {help format} for a list +of available formats. {cmd:%g} or {cmd:g} may be used as a +synonym for {cmd:%9.0g}. + +{p 5 8 2} +2. Fixed format: You may specify an integer value such as {cmd:0}, +{cmd:1}, {cmd:2}, etc. to request a display format with a fixed number +of decimal places. For example, {cmd:t(3)} would display t-statistics +with three decimal places. + +{p 5 8 2} +3. Automatic format: You may specify {cmd:a1}, {cmd:a2}, ..., or +{cmd:a9} to cause {cmd:esttab} to choose a reasonable display format for +each number depending on the number's value. {cmd:a} may be used as a +synonym for {cmd:a3}. The {it:#} in +{cmd:a}{it:#} determines the minimum precision according to the +following rules: + +{p 10 12 2} +o Absolute numbers smaller than 1 are displayed with {it:#} +significant decimal places (i.e. with {it:#} decimal places ignoring +any leading zeros after the decimal point). For example, +{cmd:0.00123456} is displayed as {cmd:0.00123} if the format is +{cmd:a3}. + +{p 10 12 2} +o Absolute numbers greater than 1 are displayed with as many digits +required to retain at least one decimal place and are displayed with +a minimum of ({it:#} + 1) digits. For example, if the format is +{cmd:a3}, {cmd:1.23456} is displayed as {cmd:1.235}, {cmd:12.3456} is +displayed as {cmd:12.35}, and {cmd:1234.56} is displayed as +{cmd:1234.6}. + +{p 10 12 2} +o In any case, integers are displayed with zero decimal places, and +very large or very small absolute numbers are displayed in +exponential format. + +{marker exa} +{title:Examples} + +{p 4 4 2} +The following examples are intended to illustrate the basic usage of +{cmd:esttab}. Additional examples can be found at +{browse "http://repec.org/bocode/e/estout"}. + +{p 4 4 2} The procedure is to first fit and store some models (see {helpb eststo}) and then apply +{cmd:esttab} to these stored estimates: + + {com}. eststo clear + {txt} + {com}. sysuse auto + {txt}(1978 Automobile Data) + + {com}. eststo: quietly regress price weight mpg + {txt}({res}est1{txt} stored) + + {com}. eststo: quietly regress price weight mpg foreign + {txt}({res}est2{txt} stored) + + {com}. esttab, ar2 + {res} + {txt}{hline 44} + {txt} (1) (2) + {txt} price price + {txt}{hline 44} + {txt}weight {res} 1.747** 3.465***{txt} + {res} {ralign 12:{txt:(}2.72{txt:)}} {ralign 12:{txt:(}5.49{txt:)}} {txt} + + {txt}mpg {res} -49.51 21.85 {txt} + {res} {ralign 12:{txt:(}-0.57{txt:)}} {ralign 12:{txt:(}0.29{txt:)}} {txt} + + {txt}foreign {res} 3673.1***{txt} + {res} {ralign 12:{txt:(}5.37{txt:)}} {txt} + + {txt}_cons {res} 1946.1 -5853.7 {txt} + {res} {ralign 12:{txt:(}0.54{txt:)}} {ralign 12:{txt:(}-1.73{txt:)}} {txt} + {txt}{hline 44} + {txt}N {res} 74 74 {txt} + {txt}adj. R-sq {res} 0.273 0.478 {txt} + {txt}{hline 44} + {txt}t statistics in parentheses + {txt}* p<0.05, ** p<0.01, *** p<0.001 + + +{p 4 4 2} +The same table using labels: + + {com}. esttab, ar2 label + {res} + {txt}{hline 52} + {txt} (1) (2) + {txt} Price Price + {txt}{hline 52} + {txt}Weight (lbs.) {res} 1.747** 3.465***{txt} + {res} {ralign 12:{txt:(}2.72{txt:)}} {ralign 12:{txt:(}5.49{txt:)}} {txt} + + {txt}Mileage (mpg) {res} -49.51 21.85 {txt} + {res} {ralign 12:{txt:(}-0.57{txt:)}} {ralign 12:{txt:(}0.29{txt:)}} {txt} + + {txt}Car type {res} 3673.1***{txt} + {res} {ralign 12:{txt:(}5.37{txt:)}} {txt} + + {txt}Constant {res} 1946.1 -5853.7 {txt} + {res} {ralign 12:{txt:(}0.54{txt:)}} {ralign 12:{txt:(}-1.73{txt:)}} {txt} + {txt}{hline 52} + {txt}Observations {res} 74 74 {txt} + {txt}Adjusted R-squared {res} 0.273 0.478 {txt} + {txt}{hline 52} + {txt}t statistics in parentheses + {txt}* p<0.05, ** p<0.01, *** p<0.001 + + +{p 4 4 2} +Plain table: + + {com}. esttab, ar2 plain + {res} + {txt} est1 est2 + {txt} b/t b/t + {txt}weight {res} 1.746559 3.464706{txt} + {res} 2.723238 5.493003{txt} + {txt}mpg {res} -49.51222 21.8536{txt} + {res} -.5746808 .2944391{txt} + {txt}foreign {res} 3673.06{txt} + {res} 5.370142{txt} + {txt}_cons {res} 1946.069 -5853.696{txt} + {res} .541018 -1.733408{txt} + {txt}N {res} 74 74{txt} + {txt}adj. R-sq {res} .2734846 .4781119{txt} + + +{p 4 4 2} +Using standard errors in brackets and suppress significance stars: + + {com}. esttab, se nostar brackets + {res} + {txt}{hline 38} + {txt} (1) (2) + {txt} price price + {txt}{hline 38} + {txt}weight {res} 1.747 3.465{txt} + {res} {ralign 12:{txt:[}0.641{txt:]}} {ralign 12:{txt:[}0.631{txt:]}}{txt} + + {txt}mpg {res} -49.51 21.85{txt} + {res} {ralign 12:{txt:[}86.16{txt:]}} {ralign 12:{txt:[}74.22{txt:]}}{txt} + + {txt}foreign {res} 3673.1{txt} + {res} {ralign 12:{txt:[}684.0{txt:]}}{txt} + + {txt}_cons {res} 1946.1 -5853.7{txt} + {res} {ralign 12:{txt:[}3597.0{txt:]}} {ralign 12:{txt:[}3377.0{txt:]}}{txt} + {txt}{hline 38} + {txt}N {res} 74 74{txt} + {txt}{hline 38} + {txt}Standard errors in brackets + + +{p 4 4 2} +Printing beta coefficients: + + {com}. esttab, beta + {res} + {txt}{hline 44} + {txt} (1) (2) + {txt} price price + {txt}{hline 44} + {txt}weight {res} 0.460** 0.913***{txt} + {res} {ralign 12:{txt:(}2.72{txt:)}} {ralign 12:{txt:(}5.49{txt:)}} {txt} + + {txt}mpg {res} -0.097 0.043 {txt} + {res} {ralign 12:{txt:(}-0.57{txt:)}} {ralign 12:{txt:(}0.29{txt:)}} {txt} + + {txt}foreign {res} 0.573***{txt} + {res} {ralign 12:{txt:(}5.37{txt:)}} {txt} + {txt}{hline 44} + {txt}N {res} 74 74 {txt} + {txt}{hline 44} + {txt}Standardized beta coefficients; t statistics in parentheses + {txt}* p<0.05, ** p<0.01, *** p<0.001 + +{marker aut} +{title:Author} + +{p 4 4 2} +Ben Jann, ETH Zurich, jannb@ethz.ch + +{marker als} +{title:Also see} + + Manual: {hi:[R] estimates} + +{p 4 13 2}Online: help for + {helpb estimates}, + {help estcom}, + {helpb estout}, + {helpb eststo}, + {helpb estadd}, + {helpb estpost} +{p_end} diff --git a/Modules/ado/plus/e/exspoisson.ado b/Modules/ado/plus/e/exspoisson.ado new file mode 100644 index 0000000..e74c691 --- /dev/null +++ b/Modules/ado/plus/e/exspoisson.ado @@ -0,0 +1,104 @@ +*! Alfonso Miranda-Caso-Luengo (SJ4-1: st0057) +*! FIML exogenous sitching Poisson +*! version 2.0 June 26 2003 + +program define exspoisson, eclass + version 6 + if replay() { + if "`e(cmd)'" != "exspoisson" { error 301 } + else exspDisplay `0' + } + else exsEstimate `0' +end + +program define exsEstimate, eclass + syntax varlist [if] [in] , EDummy(varname) /* + */ [Switch(varlist) Quadrature(integer 6) /* + */ SIGMA0(real 1) *] + + /* Obtaining dependent variable and explanatory variables */ + + gettoken endgv exogv : varlist, parse("") + + /* Selecting sample */ + + marksample touse + markout `touse' `varlist' + + /* defining some globals */ + + global S_quad "`quadrature'" + global S_edum "`edummy'" + + /* Get points and weights for Gaussian-Hermite quadrature. */ + + tempvar x w + qui gen double `x' = 0 + qui gen double `w' = 0 + ghquad `x' `w', n(`quadrature') + local j = `quadrature' + while `j' >0 { + scalar x`j' = `x'[`j'] + local j = `j' -1 + } + local j = `quadrature' + while `j' >0 { + scalar w`j' = `w'[`j'] + local j = `j' - 1 } + + + + /* GETTING INITIAL VALUES */ + + di _skip(3) + qui probit `edummy' `switch' if `touse' + + + tempname b b1 b2 bi ch + + mat `b'=e(b) + xcolnames `b', head(switch) + di as txt "Getting Initial Values:" + qui poisson `endgv' `exogv' if `touse' + + mat `b1' = e(b) + mat `b2' = (`b1',`b') + matrix `ch' = ln(`sigma0') + matrix colnames `ch' = lnsigma:_cons + matrix `bi' = (`b2',`ch') + + /* FITTING FULL MODEL */ + + di _skip(3) + di in gr "Fitting Full model:" + + ml model d0 exspoisson_ll ("`endgv'": `endgv' = `exogv') /* + */ (switch:`switch')(lnsigma:) /* + */ if `touse', init(`bi', skip) max difficult search(off) `options' + + estimates local cmd "exspoisson" + est local predict "exspoisson_p" + est local quad "`quadrature'" + + /* Display Results */ + + exspDisplay + +end + +program define exspDisplay + + di _skip(12) + di _n as txt /* + */ "Exogenous-Switch Poisson Regression" + di as text "(`e(quad)' quadrature points)" + + ml di, neq(2)plus + _diparm lnsigma, exp pr label("sigma") + di in gre in smcl "{hline 13}{c BT}{hline 64}" + +end +exit + + + diff --git a/Modules/ado/plus/e/exspoisson_ll.ado b/Modules/ado/plus/e/exspoisson_ll.ado new file mode 100644 index 0000000..b470556 --- /dev/null +++ b/Modules/ado/plus/e/exspoisson_ll.ado @@ -0,0 +1,58 @@ +*! Alfonso Miranda Caso Luengo (SJ4-1: st0057) +*! Version 2.0 June 26 2003 + +program define exspoisson_ll + + args todo b f + + tempname lnsigma + tempvar xb zb + + local y "$ML_y1" + local d "$S_edum" + + mleval `xb' = `b', eq(1) + mleval `zb' = `b', eq(2) + mleval `lnsigma' = `b', eq(3) + + scalar `lnsigma' = cond(`lnsigma'<-20,-20,`lnsigma') + + tempname sma u + scalar `sma' = exp(`lnsigma') + + tempvar F p r1 r2 r3 r4 + + qui { + gen double `F' = . if $ML_samp + + gen double `p' = 0 if $ML_samp + gen double `r1' = 0 if $ML_samp + gen double `r2' = 0 if $ML_samp + gen double `r3' = 0 if $ML_samp + gen double `r4' = 0 if $ML_samp + + local m = 1 + while `m' <= $S_quad { + scalar `u' = sqrt(2)*`sma'*scalar(x`m') + replace `r1' = `xb' + `u' if $ML_samp + replace `r2' = exp(`r1')^(`y')*exp(-exp(`r1')) if $ML_samp + replace `r3' = `r2'/exp(lngamma(`y'+1)) if $ML_samp + replace `r4' = `d'*norm(`zb') + (1-`d')*norm(-`zb') + replace `F' = `r3'*`r4' if $ML_samp + replace `p' = `p' + scalar(w`m')*`F' if $ML_samp + local m = `m' + 1 + } + replace `p'= (1/sqrt(_pi))*`p' if $ML_samp + replace `F' = log(`p') if $ML_samp + mlsum `f' = `F' if $ML_samp + } +end +exit + + + + + + + + diff --git a/Modules/ado/plus/e/exspoisson_p.ado b/Modules/ado/plus/e/exspoisson_p.ado new file mode 100644 index 0000000..0c67380 --- /dev/null +++ b/Modules/ado/plus/e/exspoisson_p.ado @@ -0,0 +1,45 @@ +*! version 1.0 Alfonso Miranda-Caso-Luengo, June 2003 (SJ4-1: st0057) +program define exspoisson_p, sort + version 7 + + local myopts "n" + + _pred_se "`myopts'" `0' + if `s(done)' { exit } + local vtyp `s(typ)' + local varn `s(varn)' + local 0 `"`s(rest)'"' + + syntax [if] [in] [, `myopts' noOFFset] + + local type "`n'" + marksample touse + + if "`type'"=="n" | "`type'"=="" { + + tempname mu zu lnsigma kappa + qui _predict double `mu' if `touse', xb `offset' eq(#1) + qui _predict double `zu' if `touse', xb `offset' eq(#2) + qui _predict double `lnsigma' if `touse', xb eq(#3) + + local d "`e(edummy)'" + + tempvar sma u rho + gen double `sma' = exp(`lnsigma') + + tempvar p eta + gen double `p'=0 if `touse' + gen double `eta'=0 if `touse' + qui replace `mu'=exp(`mu'-0.5*`sma'^2) if `touse' + qui replace `eta' = 1 + qui replace `p'=`mu'*`eta' if `touse' + qui gen `vtyp' `varn'=`p' if `touse' + label var `varn' "predicted number of events of `e(depvar)'" + exit + } +end + + + + + diff --git a/Modules/ado/plus/f/fitstat.ado b/Modules/ado/plus/f/fitstat.ado new file mode 100644 index 0000000..8d9b6f5 --- /dev/null +++ b/Modules/ado/plus/f/fitstat.ado @@ -0,0 +1,835 @@ +*! version 1.9.0 2012-07-29 fixes for o. in stata 11+ +capture program drop fitstat +program define fitstat, rclass + + local ecmdversion = c(version) // 190 + + version 9.0 + local cmd `e(cmd)' + if ( "`cmd'"!="regress" & "`cmd'"!="logit" & "`cmd'"!="probit" /// + & "`cmd'"!="logistic" & "`cmd'"!="cloglog" & "`cmd'"!="ologit" /// + & "`cmd'"!="oprobit" & "`cmd'"!="gologit" & "`cmd'"!="mlogit" /// + & "`cmd'"!="clogit" & "`cmd'"!="tobit" & "`cmd'"!="cnreg" /// + & "`cmd'"!="intreg" & "`cmd'"!="poisson" & "`cmd'"!="nbreg" /// + & "`cmd'"!="zip" & "`cmd'"!="zinb" /// + & "`cmd'"!="ztp" & "`cmd'"!="ztnb" & "`cmd'"!="slogit" /// + & "`cmd'"!="mprobit" & "`cmd'"!="rologit" /// + ) { + di in r "fitstat does not work with the last model estimated." + exit + } + + tempname n_obs n_obs2 n_parm llF llR df x2 r2 b v_ystar v v_y v_x v_e + tempname factor r2mcf r2mcfa r2mz r2ml r2cu r2 r2ef r2adj aic aicn bicx + tempname bicp isbin isord isvare isystar islgt ispbt ssr dev lrx2 lrx2p + tempname depv2 maxtmp uniqgrp n_obs2 depvgrp ifin v_error bicdif fllR + tempname bnocon phat yphat ydev predpr predcat wrong hiprob fbicp fn_obs + tempname totcor totone maxrow cntr2 cntr2a chkobs d d2 prevval prevdf + tempname results erank Vb noomit + + syntax [if] [in] /// + [, Saving(string) Using(string) SAVE Diff FORCE Bic NOSTATA /// + Debug(integer 0) /// + ] + + * 181 mat `b' = get(_b) + * 190: remove o. from beta matrix + mat `b' = get(_b) + mat `Vb' = e(V) + local colfn : colfullnames `b' + local coln : colnames `b' + local coleq : coleq `b' + _ms_omit_info `b' // remove columns of zeros from b + local cols = colsof(`b') + mat `noomit' = J(1,`cols',1) - r(omit) + forvalues i = 1/`cols' { // double clear for 0 std error + if `Vb'[`i',`i'] == 0 & `noomit'[1,`i']==1 { + mat `noomit'[1,`i']==0 + } + } + mata: newbeta = /// + select(st_matrix(st_local("b")), (st_matrix(st_local("noomit")))) + mata: st_matrix(st_local("b"),newbeta) + // reassign column names to b + local i = 0 + foreach var of local coln { + local ++i + local nmvar : word `i' of `coln' + local nmeq : word `i' of `coleq' + local nmfn : word `i' of `colfn' + _ms_parse_parts `var' + if "`nmvar'"=="`nmfn'" { // no eq nm + local nmeq "" + } + else { // eq nm + local nmeq "[`nmeq']" + } + if !`r(omit)' & `nmeq'_se[`nmvar']!=0 { + local coln2 `coln2' `nmfn' + } + } + version 11: matrix colnames `b' = `coln2' + + local depv `e(depvar)' + + if "`nostata'"!="nostata" { // stata bic and aic + tempname stataic statabic stataaic + qui estat ic + mat `stataic' = r(S) + scalar `statabic' = `stataic'[1,6] + scalar `stataaic' = `stataic'[1,5] + } + + if ("`save'"!="") local saving 0 + if ("`diff'"!="") local using 0 + +*-> get information from last model estimated + + local wtis "" + local iswgt "no" + if "`e(wtype)'"!="" { + local iswgt "yes" + local wtis "[`e(wtype)'`e(wexp)']" + } + + mat `v_e' = J(1,1,1) + sca `n_obs' = e(N) + sca `llF' = e(ll) + sca `llR' = e(ll_0) + sca `df' = e(df_m) + if "`cmd'"~="regress" & "`cmd'"~="tobit" & "`cmd'"~="cnreg" { + sca `x2' = e(chi2) + } + if "`cmd'"=="tobit" | "`cmd'"=="cnreg" { + sca `x2' = e(F) + } + if "`cmd'"=="regress" { + sca `ssr' = e(rss) + sca `r2' = e(r2) + sca `r2adj' = e(r2_a) + mat `v_e'[1,1] = (e(rmse)*e(rmse)*e(df_r)/e(N)) + } + if "`cmd'"=="clogit" { + if "`e(wtype)'"=="iweight" |"`e(wtype)'"=="pweight" /// + | "`e(wtype)'"=="aweight" { + di in r "cannot use fitstat after clogit with `e(wtype)'" + exit + } + qui egen `uniqgrp' = rank(_n) if e(sample)==1, by(`e(group)') + qui replace `uniqgrp' = . if `uniqgrp' ~= 1 + qui sum `uniqgrp' `wtis', meanonly + sca `n_obs' = r(sum_w) + } + +*-> classify type of model + + * binary? + local isbin "no" + if ("`cmd'"=="probit") local isbin "yes" + if ("`cmd'"=="logit") local isbin "yes" + if ("`cmd'"=="logistic") local isbin "yes" + if ("`cmd'"=="cloglog") local isbin "yes" + * ordinal? + local isord "no" + if ("`cmd'"=="oprobit") local isord "yes" + if ("`cmd'"=="ologit") local isord "yes" + * var(e) assumed? + local isvare "no" + if ("`cmd'"=="probit") local isvare "yes" + if ("`cmd'"=="logit") local isvare "yes" + if ("`cmd'"=="logistic") local isvare "yes" + if ("`cmd'"=="oprobit") local isvare "yes" + if ("`cmd'"=="ologit") local isvare "yes" + * is there a ystar? + local isystar "`isvare'" + if ("`cmd'"=="tobit") local isystar "yes" + if ("`cmd'"=="intreg") local isystar "yes" + if ("`cmd'"=="cnreg") local isystar "yes" + * logit model? + local islgt "no" + if ("`cmd'"=="logit") local islgt "yes" + if ("`cmd'"=="ologit") local islgt "yes" + if ("`cmd'"=="logistic") local islgt "yes" + * probit model? + local ispbt "no" + if ("`cmd'"=="probit") local ispbt "yes" + if ("`cmd'"=="oprobit") local ispbt "yes" + * zip/zinb? + local iszi "no" + if ("`cmd'"=="zip") local iszi "yes" + if ("`cmd'"=="zinb") local iszi "yes" + * provide pseudoR2 measures - jf 20Jun2005 + local pseudo "yes" + if ("`cmd'"=="regress") local pseudo "no" + if ("`cmd'"=="rologit") local pseudo "no" + if ("`cmd'"=="slogit") local pseudo "no" + if ("`cmd'"=="mprobit") local pseudo "no" + * log-lik intercept only - jf 20Jun2005 + local llio "yes" + if ("`cmd'"=="rologit") local llio "no" + if ("`cmd'"=="slogit") local llio "no" + if ("`cmd'"=="mprobit") local llio "no" + + +*-> compute numbers of variables and parameters + + sca `n_parm' = colsof(`b') + local n_cat = e(k_cat) + * version 1.8.1 2007-09-18 - stata 10 changed returns for some commands + if c(stata_version) >= 10 { + local n_cat = e(k_out) + if ("`cmd'"=="ologit" | "`cmd'"=="oprobit") local n_cat = e(k_cat) + } + + if "`n_cat'"=="." { + local n_cat = 2 + } + local n_rhs = `n_parm' - `n_cat' + 1 + if "`cmd'"=="mlogit" { + local n_rhs = (`n_parm'/(`n_cat'-1)) - 1 + } + if "`cmd'"=="tobit" | "`cmd'"=="intreg" /// for var(e) + | "`cmd'"=="nbreg" | "`cmd'"=="cnreg" /// for alpha + | "`cmd'"=="zip" /// for 2nd intercept + { + local n_rhs = `n_rhs' - 1 + } + if "`cmd'"=="zinb" { + local n_rhs = `n_rhs' - 2 + } // 2nd int & alpha + + local varlist : colnames(`b') + parse "`varlist'", parse (" ") + local rhsnam "" + if "`isord'"=="yes" { + local i 1 + while "``i''"!= "" { + local j = substr("``i''",1,4) + * pre1.7.0 050216 if "`j'"!="_cut" { + * 050216 for Stata 9 + if "`j'"!="_con" { + local rhsnam "`rhsnam' ``i''" + } + local i = `i' + 1 + } + } + if "`isbin'"=="yes" | "`cmd'"=="mlogit" | "`cmd'"=="regress" /* + */ | "`cmd'"=="tobit" | "`cmd'"=="intreg" | "`cmd'"=="cnreg" /* + */ | "`cmd'"=="poisson" | "`cmd'"=="nbreg" { + local i 1 + while "``i''"!= "" { + if "``i''"!="_cons" & "``i''"!="_se" { + local rhsnam "`rhsnam' ``i''" + } + local i = `i' + 1 + } + } + +*-> compute ll0 for zip and zinb (ll0 is for model with two intercepts) + + if "`iszi'"=="yes" { + tempname res zill0 + tempvar insamp + sca `df' = `n_parm' - 2 + if "`cmd'"=="zinb" { + * remove alpha parameter + sca `df' = `n_parm' - 3 + } + gen `insamp' = e(sample) + local inftyp "`e(inflate)'" + if "`inftyp'"=="logit" local inftyp "" + local doit "`e(cmd)' `e(depvar)' if `insamp' `wtis',inf(_cons) `inftyp'" + _estimates hold `res' + quietly `doit' + sca `llR' = e(ll) /* sic: not ll_0 */ + _estimates unhold `res' + sca `x2' = -2*(`llR'-`llF') + } // iszi model + + if "`bic'" == "" { + di _newline in g "Measures of Fit for " in y "`cmd'" in g " of " /// + in y "`depv'" _newline + } + + if "`isbin'" == "yes" | "`isord'" == "yes" | "`cmd'" == "mlogit" /// + | "`cmd'" == "mprobit" { + + * sum does not allow pweights or iweights + if "`e(wtype)'"=="pweight" | "`e(wtype)'"=="iweight" { + sca `cntr2a' = . + sca `cntr2' = . + if "`isbin'" == "yes" { + sca `r2ef' = . + } + if "`isbin'"=="yes" { + di _n in blu /* + */ "(Efron's R2, Count R2, and Adj Count R2 not calculated if " /* + */ in whi "`e(wtype)'" in blu " used)" + } + else { + di _n in blu /* + */ "(Count R2 and Adj Count R2 not calculated if " /* + */ in whi "`e(wtype)'" in blu " used)" + } + } + * can compute measures if aweight, fweight or no weight + else quietly { + egen `depvgrp' = group(`depv') if e(sample)==1 + sca `maxrow' = 0 + gen `hiprob' = 0 if e(sample)==1 + gen `predcat' = 0 if e(sample)==1 + local counter = 1 + + * BRM - Efron R2 and Count R2s + if "`isbin'" == "yes" { + * Efron R2 + * convert 0/!0 to 0/1 for binary outcomes + gen `depv2' = (`depv'!=0) if e(sample)==1 + predict `phat' if e(sample)==1 + sum `depv2' `wtis' if e(sample)==1 + local mn = r(mean) + gen `yphat' = (`depv2' - `phat')^2 if e(sample)==1 + gen `ydev' = (`depv2' - `mn')^2 if e(sample)==1 + sum `yphat' `wtis' if e(sample)==1 + local num = r(mean) + sum `ydev' `wtis' if e(sample)==1 + local den = r(mean) + scalar `r2ef' = 1 - (`num'/`den') + * Count R2 and Adjusted Count R2 + replace `predcat' = round(`phat', 1) if e(sample)==1 + gen `wrong' = (`predcat'~=`depv2') if e(sample)==1 + sum `depv2' `wtis' if `depv2' == 1 & e(sample)==1 + sca `totone' = r(N) + if `totone' > (`n_obs'-`totone') { + sca `maxrow' = `totone' + } + else { + sca `maxrow' = `n_obs' - `totone' + } + } + + * ORM - Count R2s + if "`isord'" == "yes" { + forvalues counter = 1(1)`n_cat' { + * ctnam is argument for ologitp/oprobitp + tempvar ct`counter' + local ctnam "`ctnam' `ct`counter''" + * find frequency of the modal category (for adj count R2) + sum `depvgrp' if (`depvgrp'==`counter') & (e(sample)==1) `wtis' + if r(N) > `maxrow' { + sca `maxrow' = r(N) + } + } + predict `ctnam' if e(sample) == 1 + forvalues counter = 1(1)`n_cat' { + replace `predcat' = `counter' /// + if (`ct`counter''>`hiprob') & (e(sample)==1) + replace `hiprob' = `ct`counter'' /// + if (`ct`counter''>`hiprob') & (e(sample)==1) + } + gen `wrong' = (`predcat'~=`depvgrp') if e(sample)==1 + } + + * MNLM & and MPROBIT - Count R2s + + if "`cmd'" == "mlogit" /// + | "`cmd'" == "mprobit" { + while `counter' <= `n_cat' { + tempvar ct`counter' + sum `depv' `wtis' /// + if (`depvgrp'==`counter') & (e(sample)==1), meanonly + local outcm = r(mean) + predict `ct`counter'', outcome(`outcm') + sum `depv' if (`depv'==`outcm') & (e(sample)==1) `wtis' + if r(N) > `maxrow' { + sca `maxrow' = r(N) + } + replace `predcat' = `outcm' /// + if (`ct`counter''>`hiprob') & (e(sample)==1) + replace `hiprob' = `ct`counter'' /// + if (`ct`counter''>`hiprob') & (e(sample)==1) + local counter = `counter' + 1 + } + gen `wrong' = (`predcat'~=`depv') if e(sample)==1 + } + * compute count R2s + sum `wrong' if `wrong' == 0 & e(sample) == 1 `wtis' + sca `totcor' = r(N) + sca `cntr2' = `totcor'/`n_obs' + sca `cntr2a' = (`totcor'-`maxrow')/(`n_obs'-`maxrow') + } + + } // is binary, ordinal or nominal + + * CLOGIT - Count R2s + if "`cmd'"=="clogit" { + quietly { + tempname cntr2 clphat clhi clpick clpred clwrong clright /* + */ posval motest1 motest2 mptest1 + * generate predicted outcomes for each group + predict `clphat' if e(sample) == 1 + egen `clhi' = max(`clphat') if e(sample) == 1, by(`e(group)') + gen `clpred' = 1 if `clhi'==`clphat' & e(sample)==1 + replace `clpred' = 0 if `clhi'!=`clphat' & e(sample)==1 + * check if multiple predicted 1's per group + egen `mptest1' = sum(`clpred') if e(sample), by(`e(group)') + * weight of multiple predicted 1's per group split among each 1 + replace `clpred' = `clpred'/`mptest1' if `clpred'==1 & e(sample)==1 + * calculate count R2 + sum `clpred' `wtis' if `clpred'>0 & `clpred'~=. & `depv'==0 & e(sample)==1 + sca `clwrong' = r(sum) + sum `clpred' `wtis' if `clpred'>0 & `clpred'~=. & `depv'!=0 & e(sample)==1 + sca `clright' = r(sum) + sca `cntr2' = `clright' / (`clwrong'+`clright') + * warn user if multiple outcomes per group + gen `posval'=1 if `depv'!=0 & `depv'~=. & e(sample)==1 + egen `motest1' = sum(`posval') if `posval'==1, by(`e(group)') + sum `motest1' + sca `motest2' = r(max) + if `motest2' > 1 { + noi di in blu "(Multiple outcomes per group for clogit: Count R2 may not be valid)" + } + } // quietly + } // clogit + +*-> compute Var(y*) using cov_x + + if "`isystar'"=="yes" { + sca `factor' = 1/(`n_obs'-1) + quietly mat accum `v_x' = `depv' `rhsnam' `wtis' if e(sample), /// + deviations noconstant + sca `v_y' = `factor' * `v_x'[1,1] // sum y/(n-1) + mat `v_x' = `factor' * `v_x'[2...,2...] // cov matrix of rhs vars + + if "`e(cmd)'"=="intreg" { + mat `v_x' = `v_x'[2...,2...] + } + mat `bnocon' = `b'[1,1..`n_rhs'] // trim off _con + mat `v' = `bnocon' * `v_x' * `bnocon'' + if "`ispbt'"=="yes" { + mat `v_e'[1,1] = 1 + } + if "`islgt'"=="yes" { + mat `v_e'[1,1] = (_pi*_pi)/3 + } + if "`e(cmd)'"=="intreg" { + mat `v_e'[1,1] = e(sigma)*e(sigma) + } + if "`e(cmd)'"=="tobit" | "`e(cmd)'"=="cnreg" { + mat `v_e'[1,1] = `b'[1,"sigma:_cons"]*`b'[1,"sigma:_cons"] + } + mat `v' = `v' + `v_e' + sca `v_ystar' = `v'[1,1] + } + +*-> information measures + + sca `aicn' = ((-2*`llF') + (2*`n_parm')) + sca `aic' = `aicn'/`n_obs' + sca `dev' = -2*`llF' + local devdf = `n_obs'-`n_parm' + sca `lrx2' = 2*(`llF'-`llR') + local lrx2df = e(df_m) + if "`iszi'"=="yes" { + local lrx2df = `df' + } + if "`cmd'"=="mprobit" { + scalar `lrx2' = e(chi2) + } + + sca `lrx2p' = chiprob(`lrx2df',`lrx2') + + if "`cmd'"=="slogit" { + scalar `lrx2' = e(chi2) + sca `lrx2p' = e(p) + } + sca `bicx' = `dev' - (`devdf'*ln(`n_obs')) + sca `bicp' = -`lrx2' + (e(df_m)*ln(`n_obs')) + capture return scalar dev_df = `devdf' + capture return scalar lrx2_df = `lrx2df' + + if "`iszi'"=="yes" { + * df = # rhs in both equations + sca `bicp' = -`lrx2' + (`df'*ln(e(N))) + } + + * these equal usual R2 in regress + if "`pseudo'"=="yes" { + sca `r2mcf' = 1 - (`llF'/`llR') + sca `r2mcfa' = 1 - ((`llF'-`n_parm')/`llR') + sca `n_obs2' = 2/`n_obs' + sca `r2ml' = 1 - exp(2*(`llR'-`llF')/`n_obs') + sca `r2cu' = (`r2ml')/(1-exp(2*`llR'/`n_obs')) + } + + if "`isystar'"=="yes" { + sca `r2mz' = (`v_ystar' - `v_e'[1,1])/`v_ystar' + sca `v_error' = `v_e'[1,1] + } + +*-> output + + * define output macros with format where / is parse character: + * output_text/tempname_of_scalar/abbrev_for_r() + * /df?/width/half(1, 2 or ? for either) + local stat2 "Log-Lik Intercept Only/llR/ll_0/no/11/1" + local stat3 "Log-Lik Full Model/llF/ll/no/11/2" + local stat4 "D/dev/dev/yes/11/1" + local stat6 "LR/lrx2/lrx2/yes/11/2" + local stat8 "Prob > LR/lrx2p/lrx2_p/no/9/2" + local stat9 "McFadden's R2/r2mcf/r2_mf/no/9/1" + local stat10 "McFadden's Adj R2/r2mcfa/r2_mfadj/no/9/2" + local stat11 "ML (Cox-Snell) R2/r2ml/r2_ml/no/9/1" + local stat12 "Cragg-Uhler(Nagelkerke) R2/r2cu/r2_cu/no/7/2" + local stat13 "McKelvey & Zavoina's R2/r2mz/r2_mz/no/9/?" + local stat14 "Efron's R2/r2ef/r2_ef/no/9/?" + local stat15 "Variance of y*/v_ystar/v_ystar/no/11/1" + local stat16 "Variance of error/v_error/v_error/no/11/2" + local stat17 "Count R2/cntr2/r2_ct/no/9/1" + local stat18 "Adj Count R2/cntr2a/r2_ctadj/no/9/2" + local stat19 "R2/r2/r2/no/9/1" + local stat20 "Adjusted R2/r2adj/r2_adj/no/9/2" + local stat21 "AIC/aic/aic/no/11/1" + local stat22 "AIC*n/aicn/aic_n/no/11/2" + local stat23 "BIC/bicx/bic/no/11/1" + local stat24 "BIC'/bicp/bic_p/no/11/2" + local stat25 "BIC used by Stata/statabic/statabic/no/11/1" + local stat26 "AIC used by Stata/stataaic/stataaic/no/11/2" + if "`llio'"=="no" { + local stat2 "" + local stat3 "Log-Lik Full Model/llF/ll/no/11/1" + local stat4 "D/dev/dev/yes/11/2" + } + if "`cmd'"=="slogit" local stat24 "" + if "`cmd'"=="mprobit" | "`cmd'"=="slogit" { + local stat6 "Wald X2/lrx2/lrx2/yes/11/1" + } + if "`cmd'"=="mprobit" | "`cmd'"=="slogit" { + local stat8 "Prob > X2/lrx2p/lrx2_p/no/9/2" + } + +*-> check models for using and saving + + if "`saving'" != "" { + if (length("`saving'")>4) { + di in red "saving() name must be < 5 characters long" + exit 198 + } + } + if "`using'"!= "" { + if (length("`using'")>4) { + di in red "using() name must be < 5 characters long" + exit 198 + } + qui capture mat list fs_`using' + if _rc == 111 { + di in red "Incorrect using() option: no indices saved as `using'" + exit 111 + } + * if the using option has been set, prepare comparison macros + sca `fn_obs' = fs_`using'[1,1] + if `fn_obs' == -9999 { + sca `fn_obs' = . + } + + * estimate command saved as row name + local fcmd : rownames(fs_`using') + local fcmd : word 1 of `fcmd' + + * test if current and using are same type of model + local same "no" + if ("`fcmd'"=="logit"&"`e(cmd)'"=="logistic") | /// + ("`fcmd'"=="logistic"&"`e(cmd)'"=="logit") { + local same "yes" + } + if ("`fcmd'"!="`e(cmd)'" & "`same'"=="no") & "`force'"=="" { + di in r "Current model estimated by `e(cmd)'" /// + in r ", but saved model estimated by `fcmd'." + di in r "To make the comparisons anyway, use the " /// + "force option." + exit + } + + if ("`fcmd'"!="`e(cmd)'" & "`same'"=="no") { + di in y "Warning: Current model estimated by " /* + */ "`e(cmd)', but saved model estimated by `fcmd'" + di + } + if `n_obs' != `fn_obs' & "`force'"=="force" { + di in y "Warning: N's do not match." + di + } + + di in g _col(30) %9s "Current" _col(48) " Saved" /// + _col(65) "Difference" + di in g "Model:" _col(30) %9s in y "`e(cmd)'" /// + %9s _col(48) in y "`fcmd'" + di in g "N:" _col(30) %9.0f in y `n_obs' /// + %9.0f _col(48) in y `fn_obs' /// + %9.0f _col(66) in y (`n_obs' - `fn_obs') + + * test if N's match + if `n_obs' != `fn_obs' & "`force'"=="" { + di _newline in r "N's do not match. To make the comparisons, use the " /// + in y "force" in r " option." + exit + } + + * test of ll0 match + sca `fllR' = fs_`using'[1,2] + if `fllR'==-9999 { + sca `fllR' = . + } + + if abs(`llR'-`fllR') > .0001 & (`llR'-`fllR') ~= . & "`force'"=="" { + di _newline in r /* + */ "Log-likelihoods for intercept model differ for current and saved models." + di in r "To make the comparisons, use the " in y "force" in r " option." + exit + } + } /* if "`using'"!="" */ + + capture return scalar n_parm = `n_parm' + capture return scalar n_rhs = `n_rhs' + capture return scalar N = `n_obs' + +*-> create matrices and macros containing results + + local nstats = 24 // number of stats reported in output matrix + if "`nostata'"!="stata" local nstats = `nstats' + 2 + + mat `results' = J(1, `nstats'+2, .) + mat `results'[1,1] = `n_obs' + mat `results'[1,`nstats'+1] = `n_parm' + mat `results'[1,`nstats'+2] = `n_rhs' + local cnames "N" // start bulding column names for output matrix + + forvalues i = 2(1)`nstats' { + + * read individual stats + tokenize "`stat`i''", parse(/) + * outtxt - name of statistic + local outtxt`i' "`1'" + * scalnm - name of scalar holding value of statistic + local scalnm`i' "`3'" + * abnm - name of statistic for return value + local abnm`i' "`5'" + * df - whether statistic has df + local df`i' "`7'" + * outwid - width of output - TO DO: try to delete this + local outwid`i' "`9'" + * outhalf - need to be in first or second half + local outhalf`i' "`11'" + * cnames - macro of column names for output + local cnames "`cnames' `abnm`i''" + if "`df`i''"=="yes" { + local cnames "`cnames' `abnm`i''_df" + } + + * see if scalar exists, if not, no output + capture return scalar `abnm`i'' = ``scalnm`i''' + if _rc != 0 { + if "`outtxt`i''" != "" { + mat `results'[1, `i'] = .x + if "`df`i''"=="yes" { + mat `results'[1,`i'+1] = .x + } + } + } + if _rc == 0 { + * add to results matrix + mat `results'[1, `i'] = ``scalnm`i''' + if "`df`i''"=="yes" { + mat `results'[1,`i'+1] = ``scalnm`i''df' + } + + } // if _rc == 0 + if "`df`i''"=="yes" { + local i = `i' + 1 + } + } // forvalues i + + +*-> loop through to print results if using option not used + + if "`using'"=="" { + + * arrange numbers in rows and columns for printing + + local trow = 1 + local tcol = 1 + forvalues i = 2(1)`nstats' { + * figure out if result should be in output + if `results'[1,`i']!=.x & "`outtxt`i''" != "" & /// + ("`bic'"=="" | `i' >= 21) { + + * figure out if need to advance to next row of table + if "`outhalf`i''" == "1" & `tcol' == 3 { + local ++trow + local tcol = 1 + } + if "`outhalf`i''" == "2" & `tcol' == 1 { + local tcol = 3 + } + + local op`trow'_`tcol' = "`outtxt`i''" + if "`df`i''" == "yes" { + local temp = ``scalnm`i''df' + local op`trow'_`tcol' = "`op`trow'_`tcol''(`temp')" + } + local op`trow'_`tcol' = "`op`trow'_`tcol'':" + + local ++tcol + local op`trow'_`tcol' = ``scalnm`i''' + + * take care of output width + local fmt`trow'_`tcol' = "%`outwid`i''.3f" + + // move to next column + local ++tcol + if `tcol' == 5 { // if needed, move to next row + local tcol = 1 + local ++trow + } + } + } // forvalues i + + * print rows and columns + + local numrows = `trow' + if `tcol' == 1 { + local numrows = `trow' - 1 + } + + forvalues i = 1(1)`numrows' { + di in g "`op`i'_1'" _col(28) in y %11.3f `op`i'_2' /// + _col(42) in g "`op`i'_3'" _col(69) in y %11.3f `op`i'_4' + } + + } // using option not used + + +*-> loop through to print results if using option has been used + + if "`using'"!="" { + + local trow = 1 + forvalues i = 2(1)`nstats' { + * figure out if result should be in output + if `results'[1,`i']!=.x & ("`bic'"=="" | `i' >= 21) { + + * calculate differences + sca `prevval' = fs_`using'[1,`i'] + tempname difvals + sca `difvals' = ``scalnm`i'''-`prevval' + + * for LR prob give LR prob -- computed during LR loop + if "`outtxt`i''"=="Prob > LR" { + sca `difvals' = `LRchip' + } + + * print results + if "`df`i''" == "no" { + di in g "`outtxt`i''" /// + _col(28) in y %11.3f ``scalnm`i''' /// + _col(46) in y %11.3f `prevval' /// + _col(64) in y %11.3f `difvals' + } + + if "`df`i''" == "yes" { + local tmp_curdf = ``scalnm`i''df' + sca `prevdf' = fs_`using'[1,(`i'+ 1)] + local tmp_prevdf = `prevdf' + local tmp_difdf = abs(`tmp_curdf' - `tmp_prevdf') + + * for D remove the negative sign from the difference + if "`outtxt`i''"=="D" { + sca `difvals' = abs(`difvals') + } + + * for LR statistic compute LR test prob + if "`outtxt`i''"=="LR" | "`outtxt`i''"=="Wald LR" { + tempname LRdif LRdf LRchip + sca `difvals' = abs(``scalnm`i''' - `prevval') + sca `LRdf' = abs(``scalnm`i''df'-`prevdf') + sca `LRchip' = chiprob(`LRdf', `difvals') + } + + di in g "`outtxt`i''" /// + _col(28) in y %11.3f ``scalnm`i''' in g "(`tmp_curdf')" /// + _col(46) in y %11.3f `prevval' in g "(`tmp_prevdf')" /// + _col(64) in y %11.3f `difvals' in g "(`tmp_difdf')" + } + + } + + } // forvalues i + + } + + + *-> BIC comparisons + if "`using'" != "" { + if abs(`llR'-`fllR') < .0001 { /* check that LL0s are the same */ + sca `fbicp' = fs_`using'[1, 24] + sca `bicdif' = abs(`bicp'-`fbicp') + if `bicdif'~=. { + local sup "very strong" + if `bicdif'<= .0000000001 { + local sup "no" + } + else if `bicdif' <=2 { + local sup "weak" + } + else if `bicdif' <=6 { + local sup "positive" + } + else if `bicdif' <=10 { + local sup "strong" + } + local modpref "current" + if `bicp' > `fbicp' { + local modpref "saved" + } + if `bicdif'< .0000000001 & `bicdif'>-.0000000001 /* + */ { + local modpref "either" + } + di _newline in g "Difference of " %8.3f in y `bicdif' in g /* + */ " in BIC' provides " in y "`sup'" /* + */ in g " support for " in y "`modpref'" in g " model." + } + } /* if `llR' == `fllR' */ + } /* if "`using'" != "" */ + + if "`bic'"=="" & "`using'" != "" { + di _n in g "Note: p-value for difference in LR is only valid if models are nested." + } + local cnames "`cnames' n_parm n_rhs" + mat rownames `results' = `e(cmd)' + mat colnames `results' = `cnames' + if "`saving'" != "" { + capture mat drop fs_`saving' + mat fs_`saving' = `results' + di _n in blu "(Indices saved in matrix fs_`saving')" + } + + quietly `cmd' +end + +exit +* version 1.8.1 2007-09-18 returns for some commands changed in Stata 10 +* version 1.8.0 19Jun2006 df correction in lrtest for zinb +* version 1.7.9 26Oct2005 fix slogit and mprobit output for LR to Wald X2 +* version 1.7.8b 20Jun2005 small fix to new output routine +* version 1.7.8 20Jun2005 new output routine +* version 1.7.7 17Jun2005 streamlined/stata9 improvements to code +* version 1.7.6 15Jun2005 added rologit +* version 1.7.5 10Jun2005 clogit, tobit, cnreg, Cragg-Uhler (Nagelkerke) R2 for dif, ztp, ztnb +* version 1.7.4 10Jun2005 align Variance of y* +* version 1.7.2 13Apr2005 +* version 1.7.1 28Feb2005 mprobit; fixed bic'; added count R2 +* version 1.7.0 16Feb2005 slogit mprobit ztp, ztnb, format on others +* version 1.6.9 12Feb2005 add stata bic and aic +* version 1.6.8 07Feb2005 add ztp and ztnb +* version 1.6.7 22Jan2005 change LRX2 diff --git a/Modules/ado/plus/f/fitstat.hlp b/Modules/ado/plus/f/fitstat.hlp new file mode 100644 index 0000000..d15caae --- /dev/null +++ b/Modules/ado/plus/f/fitstat.hlp @@ -0,0 +1,79 @@ +.- +help for ^fitstat^ - 03Nov2005 +.- + +To document: ztp and ztnb + : option nostata to supress bic aic based on stata formula + +Compute fit statistics for single equation regression models. +------------------------------------------------------------- + + ^fitstat^ [^, s^aving^(name)^ ^u^sing^(name)^ ^b^ic ^force^ ^save^ ^diff^] + +Description +----------- + +^fitstat^ is a post-estimation command that computes a variety of measures +of fit for many kinds of regression models. It works after the following: +^clogit^, ^cnreg^, ^cloglog^, ^intreg^, ^logistic^, ^logit^, ^mlogit^, ^nbreg^, ^ocratio^, +^ologit^, ^oprobit^, ^poisson^, ^probit^, ^regress^, ^zinb^, and ^zip^. With the ^s^aving^()^ +and ^u^sing^()^ options, it can also be used to compare fit measures for two +different models. + +For all models, ^fitstat^ reports the log-likelihoods of the full and +intercept-only models, the deviance (D), the likelihood ratio chi-square +(G2), Akaike's Information Criterion (AIC), AIC*N, the Bayesian Information +Criterion (BIC), and BIC'. + +For all models except ^regress^, ^fitstat^ reports McFadden's R2, McFadden's +adjusted R2, the maximum likelihood R2, and Cragg & Uhler's R2. These +measures all equal R2 for OLS regression. ^fitstat^ reports R2 and the +adjusted R2 after ^regress^. + +fitstat reports the regular and adjusted count R2 for categorical data models. +For ordered or binary logit or probit models, as well as models for censored +data (^tobit^, ^cnreg^, or ^intreg^), it also reports McKelvey and Zavonia's R2. +In addition, it reports Efron's R2 for ^logit^ or ^probit^. + +Not all measures are provided for models estimated with ^pweight^s or ^iweight^s. + +Options +------- + +^saving(^name^)^ saves the computed measures in a matrix for subsequent + comparisons. Name cannot be longer than 4 characters. + +^using(^name^)^ compares the fit measures for the current model with those of + the model saved as name. Name cannot be longer than 4 characters. + +^bic^ only presents information measures. + +^force^ will compare two models even when the number of observations or the + estimation method varies between the two models. + +^save^ and ^diff^ are equivalents of saving(0) and using(0) and do not require + the user to provide model names. + +Examples +-------- + +To compute fit statistics for a single model: + + . ^use mroz,clear^ + . ^logit lfp k5 k618 age wc hc lwg inc^ + . ^fitstat^ + +To compute and save fit measures: + + . ^logit lfp k5 k618 age wc hc lwg inc^ + . ^fitstat, saving(mod1)^ + +To compare saved model to current model: + + . ^logit lfp k5 k618 age age2 wc hc lwg inc^ + . ^fitstat, using(mod1)^ + +.- +Authors: J. Scott Long and Jeremy Freese + www.indiana.edu/~jslsoc/spost.htm + spostsup@@indiana.edu diff --git a/Modules/ado/plus/f/fitstat_ers.ado b/Modules/ado/plus/f/fitstat_ers.ado new file mode 100644 index 0000000..ea4e0a7 --- /dev/null +++ b/Modules/ado/plus/f/fitstat_ers.ado @@ -0,0 +1,214 @@ +capture program drop fitstat_ers + +*!version 1.0 22aug 2011 +*!christian a. gregory, economic research service + +*********************************************************************************************** +*this program computes outfit and infit statistics for the conditional maximum likelihood (cml) +*rasch model, using formulas outlined in the documentation. these fit statistics differ from +*those computed by the raschtest. for more information on the fit statistics, see documentation +*or contact mark nord @ marknord@ers.usda.gov, or christian gregory @ cgregory@ers.usda.gov. +************************************************************************************************ +*the gammasym module is required to run this program. to get this module, type "findit gammasym" +*in stata. if you wish to keep the fit statistics in an excel file, install xml_tab.ado; if you wish +*to keep them in a LaTex file, install outtable.ado. +************************************************************************************************ + +program define fitstat_ers, rclass +version 9.0 +syntax varlist(min=2) [if] [in], /// + [excel(string) /// + latex(string) /// + replace ] + + +tempfile fitstat +qui save `fitstat', replace +marksample touse +qui keep if `touse' +qui keep `varlist' + +*compute score +tempvar score +genscore `varlist', score(`score') + + +*prep data to reshape +g id = _n +local r 0 +foreach x of local varlist { + local `++r' + rename `x' item`r' + } +local nbitems: word count `varlist' + +*total obs before reshape +qui count if `score'!=0 & `score'!=`nbitems' +local totalobs = r(N) + + +*get size of groups by score +forvalues i=0/`nbitems' { + qui count if `score'==`i' //& item==1 + local realscore`i'=r(N) + } + +local t = `nbitems'-1 + +*reshape +qui reshape long item, i(id) j(rep) + +forvalues i = 1/`nbitems' { + qui { + g item`i' = rep==`i' + replace item`i' = -item`i' + } +} + + +*estimate parameters +qui clogit item item1-item`t', group(id) + +matrix beta = e(b) + +forvalues i=1/`t' { + local beta`i' = beta[1,`i'] + } +local beta`nbitems' = 0 + + + +tempname Pi +matrix define `Pi'=J(`nbitems',`t',0) + + +tempname Obs Obs2 Th Th2 +matrix define `Obs'=J(`nbitems',`t',0) +matrix define `Th'=J(`nbitems',`t',0) +local listofitemsc + +****************************************************************************************************** +*estimation of the gamma symetrical functions. i use these to calculate the expected values of the +*model, conditional on the score. hardouin (07) and glas(88) use these forms. the current stata module +*-raschtest- uses them for general cml models and R tests. +******************************************************************************************************* +forvalues j=1/`nbitems' { + local listini`j' + local listofitemsc "`listofitemsc' `beta`j''" + forvalues k=1/`nbitems' { + local listini`j'k`k' + if `k'!=`j' { + local listini`j' "`listini`j'' `beta`k''" //vector w/o current item paramter--diags of vcv + } + forvalues l=1/`nbitems' { + if `l'!=`j'&`l'!=`k' { + local listini`j'k`k' "`listini`j'k`k'' `beta`l''" //vector w/o current item parameter--off diags of vcv + } + } + } + } + + qui gammasym `listofitemsc' //gamma function of full vector of difficulty parameters + +*estimation of probabilities (pi) and expected (th), as well as observed (obs) + forvalues s=1/`nbitems' { + local denom`s'=r(gamma`s') + } + local m = `nbitems'-1 + local p = `m'-1 + forvalues j=1/`nbitems' { + forvalues s=1/`m' { + local r=`s'-1 + qui count if rep==`j'& item==1 &`score'==`s' + matrix `Obs'[`j',`s']=r(N) + gammasym `listini`j'' + local num`j'=r(gamma `r') //gamma function of vector w/o item j, for score s-1 + matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s'' + matrix `Th'[`j',`s']=`Pi'[`j',`s']*`realscore`s'' + } + } + +//local totalobs = _N +matrix outstat = J(`nbitems',2,0) + +forvalues j = 1/`nbitems' { + local outfit_j = 0 + local infit_j = 0 + local outfit_num = 0 + local outfit_denom = 0 + local infit_num = 0 + local infit_denom = 0 + forvalues s = 1/`m' { + local n_score = `realscore`s'' + disp "frac score = " `n_score'/`totalobs' + local obs_js = `Obs'[`j',`s'] + local pred_js = `Th'[`j',`s'] + local p_obs_js = `obs_js'/`n_score' + local p_exp_js = `pred_js'/`n_score' + local fitnum = `p_obs_js'*(1-`p_exp_js')^2 + (1-`p_obs_js')*`p_exp_js'^2 + local fitdenom = `p_exp_js'*(1-`p_exp_js') + local outfit_j = `outfit_j'+ ((`n_score'/`totalobs')*(`fitnum'/`fitdenom')) + local infit_num = `infit_num'+ (`n_score'/`totalobs')*(`fitnum') + local infit_denom = `infit_denom'+ (`n_score'/`totalobs')*(`fitdenom') + } + local infit_j = `infit_j' + (`infit_num'/`infit_denom') + local outfit_j = `outfit_j' + matrix outstat[`j',1] = `outfit_j' + matrix outstat[`j',2] = `infit_j' +} + + + + +matrix rownames outstat = `varlist' +matrix colnames outstat = Outfit Infit + + +if "`excel'"!="" { + local rand = round(1000*runiform(),1) + if "`replace'"!="" { + xml_tab outstat, save(`excel') replace + } + else { + capture confirm new file `excel' + if _rc { + xml_tab outstat, save(outstat`rand') + di in green "`excel' already exists; results saved in outstat`rand'.xml" + } + else { + xml_tab outstat, save(`excel') + } + } + } + +if "`latex'"!=""{ + local rand = round(1000*runiform(),1) + if "`replace'"!="" { + outtable using `latex', mat(outstat) nobox replace + } + else { + capture confirm new file `latex'.tex + if _rc { + outtable using `latex'`rand', mat(outstat) nobox + di in green "`latex' already exists; results saved in outstat`rand'.tex" + } + else { + outtable using `latex'`rand', mat(outstat) nobox + } + } + } + + +return matrix outstat = outstat + +use `fitstat', clear + + +end + + + + + + + diff --git a/Modules/ado/plus/f/fitstat_ers.hlp b/Modules/ado/plus/f/fitstat_ers.hlp new file mode 100644 index 0000000..b66a460 --- /dev/null +++ b/Modules/ado/plus/f/fitstat_ers.hlp @@ -0,0 +1,27 @@ +{smcl} +{* *!version 1.0.0 16dec2011}{...} +{cmd: help fitstat_ers} +{hline} + +{title:Title} +{phang} +{bf: fitstat_ers} {hline 2} computes outfit and infit statistics for the conditional maximum likelihood (cml) +Rasch model as outlined by Linacre and Wright (2004). See {browse "http://www.rasch.org/rmt/rmt82a.htm"}. + +{title:Syntax} +{phang} +{cmd:fitstat_ers} varlist {ifin} {opt ,} [{opt excel(filename)} {opt latex(name)}] +{p_end} + +{title:Description} +{pstd} +{cmd:fitstat_ers} estimates fit statistics for conditional likelihood models, proceeding as if Rasch +model assumptions are met. The current Stata module {cmd:raschtest} calculates infit and outfit statistics transformed +to be normal random variates; this module estimates the un-transformed infit and outfit statistics as outlined +by Linacre and Wright (1994). + + +{title:Options} +{phang} +{opt excel(filename)} and {opt latex(filename)} output the infit and outfit statistics to tables in their respective +formats. In order to use these options {cmd: xml_tab} and {cmd:outtable} should be installed, respectively. diff --git a/Modules/ado/plus/f/fmtlist.ado b/Modules/ado/plus/f/fmtlist.ado new file mode 100644 index 0000000..8fc5c96 --- /dev/null +++ b/Modules/ado/plus/f/fmtlist.ado @@ -0,0 +1,31 @@ +program def fmtlist, rclass +*! NJC 1.0.0 22 August 2000 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax , Format(str) [ Global(str) Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tokenize `list' + while "`1'" != "" { + capture local 1 : di `format' `1' + if _rc { + di in r "inappropriate argument or format?" + exit _rc + } + local newlist "`newlist'`1' " + mac shift + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/f/fmtlist.hlp b/Modules/ado/plus/f/fmtlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/f/fmtlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/f/funnel.dlg b/Modules/ado/plus/f/funnel.dlg new file mode 100644 index 0000000..8d071c3 --- /dev/null +++ b/Modules/ado/plus/f/funnel.dlg @@ -0,0 +1,103 @@ +/* + +*! funnel dialog version 1.0.0, 13 May 2003, T. J. Steichen, steichen@triad.rr.com +*! for funnel version 1.04, May 2001, M. J. Bradburn, mike.bradburn@cancer.org.uk + +Metan-based Funnel Graph +------------------------ + +Syntax: funnel [varlist] [if exp] [in range] [, ysqrt sample overall(#) + graph_options ] + +To install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "Metan-based Funnel Graph (&funnel)" "db funnel" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. + +*/ + +VERSION 8.0 + +INCLUDE _std_small +INCLUDE header + +HELP hlp1, view("help metan") +RESET res1, label("Reset") + +DIALOG main, label("funnel 1.04 - Metan-based Funnel Graph") tabtitle("Main") +BEGIN + CHECKBOX cb_effect 10 5 310 ., /// + label("Enter Variables (else use _ES and _seES") /// + onclickon(script vars_on) /// + onclickoff(script vars_off) + TEXT tx_effect 10 25 330 ., /// + label("Vars for Effect Sizes: theta, se(theta), in that order") + VARLIST vl_effect @ _ss @ ., /// + label("Effect Sizes: theta, se(theta)") + +/* end vars */ + + CHECKBOX cb_ysqrt 10 70 270 ., /// + label("Y-axis is Square-root Scaled") /// + option("ysqrt") + + CHECKBOX cb_sample 10 90 270 ., /// + label("Y-axis is Sample Size (not SE)") /// + onclickon(main.cb_invert.disable) /// + onclickoff(main.cb_invert.enable) /// + option("sample") + + CHECKBOX cb_invert 10 110 270 ., /// + label("Precision (SE) not inverted") /// + option("noinvert") + + CHECKBOX cb_overall 10 130 130 ., /// + label("Line at Effect Size:") /// + onclickon(main.ed_overall.enable) /// + onclickoff(main.ed_overall.disable) + EDIT ed_overall 145 130 50 ., /// + label("overall") /// + numonly /// + option("overall") + +/* end switches and sets */ + + GROUPBOX gb_gopts7 10 155 330 _ht1h, /// + label("Allowed Graph7 Options:") + EDIT ed_gopts7 15 175 320 ., /// + label("Graph7 Options") + +/* end Graph7 opts */ + +END + +INCLUDE ifin +INCLUDE weights_a + +SCRIPT vars_on +BEGIN + main.tx_effect.enable + main.vl_effect.enable +END + +SCRIPT vars_off +BEGIN + main.tx_effect.disable + main.vl_effect.disable +END + + +PROGRAM command +BEGIN + put "funnel " + varlist [main.vl_effect] + INCLUDE _weights_pr + INCLUDE _ifin_pr + beginoptions + option main.cb_ysqrt + option main.cb_sample + option main.cb_invert + optionarg main.ed_overall + put main.ed_gopts7 + endoptions +END diff --git a/Modules/ado/plus/g/galbr.ado b/Modules/ado/plus/g/galbr.ado new file mode 100644 index 0000000..95ac3ed --- /dev/null +++ b/Modules/ado/plus/g/galbr.ado @@ -0,0 +1,58 @@ +* !galbr.ado AT v2.0, Marc 2000 (STB-56: sbe20.1) +* galbr.ado AT v1.15, June/October 1997 + +program def galbr + version 6.0 + syntax varlist(min=2 max=2 numeric) [if] [in] [, id(varname) `options' *] + tokenize `varlist' + local E `1' + local SE `2' + preserve + if ("`if'"!="") { + qui keep `if' + } + if ("`in'"!="") { + qui keep `in' + } + if "`id'"=="" { + local id "O" + } + else { + local id "[`id']" + } + tempvar x y p ulp llp + qui gen `x'=1/`SE' + qui gen `y'=`E'/`SE' + label var `x' "1/se(b)" + label var `y' "b/se(b)" + qui reg `y' `x', noconstant + qui predict `p' + qui gen `llp'=`p'-2 + qui gen `ulp'=`p'+2 + qui sum `x', detail + local mxx=r(max) + qui sum `llp', detail + if r(min)>=-2 { + local mny=-2 + } + else { + local mny=r(min) + } + qui sum `ulp', detail + if _result(6)<=2 { + local mxy=2 + } + else { + local mxy=r(max) + } + local new=_N+1 + qui set obs `new' + qui replace `y'=0 in l + qui replace `x'=0 in l + qui replace `p'=0 in l + qui replace `llp'=-2 in l + qui replace `ulp'=2 in l + graph `y' `p' `ulp' `llp' `x', ylab(`mny',-2,0,2,`mxy') /* + */ xscale(0,`mxx') ysca(`mny',`mxy') pen(1922) /* + */ sy(`id'iii) c(.lll) sort `options' +end diff --git a/Modules/ado/plus/g/galbr.dlg b/Modules/ado/plus/g/galbr.dlg new file mode 100644 index 0000000..95907de --- /dev/null +++ b/Modules/ado/plus/g/galbr.dlg @@ -0,0 +1,57 @@ +/* + +*! galbr dialog version 1.0.0, 13 May 2003, T. J. Steichen, steichen@triad.rr.com +*! for galbr version 2.0, Mar 2000, Aurelio Tobias, atobias@isciii.es + +Galbraith Plot for Heterogeneity +-------------------------------- + +galbr theta setheta [if exp] [in range] [ , id(strvar) graph_options ] + +To install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "Galbraith Plot for Heterogeneity (&galbr)" "db galbr" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. +*/ + +VERSION 8.0 + +INCLUDE _std_small +INCLUDE header + +HELP hlp1, view("help galbr") +RESET res1, label("Reset") + +DIALOG main, label("galbr 2.0 - Galbraith Plot for Heterogeneity") tabtitle("Main") +BEGIN + TEXT tx_se 10 10 330 ., /// + label("Vars for theta, se(theta), in that order") + VARLIST vl_se @ _ss @ ., /// + label("Vars for theta, se(theta)") + + CHECKBOX cb_id 10 70 100 ., /// + label("ID Variable:") /// + onclickon(main.vn_id.enable) /// + onclickoff(main.vn_id.disable) + VARNAME vn_id 110 70 230 ., /// + label("ID Variable") /// + option("id") + + GROUPBOX gb_gopts7 10 155 330 _ht1h, /// + label("Allowed Graph7 Options:") + EDIT ed_gopts7 15 175 320 ., /// + label("Graph7 Options") +END + +INCLUDE ifin + +PROGRAM command +BEGIN + put "galbr " + varlist main.vl_se + INCLUDE _ifin_pr + beginoptions + optionarg main.vn_id + put main.ed_gopts7 + endoptions +END diff --git a/Modules/ado/plus/g/galbr.hlp b/Modules/ado/plus/g/galbr.hlp new file mode 100644 index 0000000..8b92fba --- /dev/null +++ b/Modules/ado/plus/g/galbr.hlp @@ -0,0 +1,74 @@ +.- +help for ^galbr^ (STB-41: sbe20; STB-56: sbe20.1) +.- + +Assessing heterogeneity in meta-analysis: the Galbraith plot +------------------------------------------------------------ + +^galbr^ theta setheta [^if^ exp] [^in^ range] [, ^id(^strvar^)^ graph_options] + + +Description +----------- + +^galbr^ provides a graphical display to get a visual impression of the amount of +heterogeneity from a meta-analysis. For each trial, the z statistic +^theta/setheta^ is plotted against the reciprocal standard error ^1/setheta^. +The (unweighted) regression line constrained through the origin, with its 95% +confidence interval, has a slope equal to the overall log rate ratio, +or log odds ratio, or log hazard ratio in a fixed effects meta-analysis. +The position of each trial on the horizontal axis gives an indication of the +weight allocated to it in a meta-analysis. The position on the vertical axis +gives the contribution of each trial to the Q statistic for heterogeneity. +In the absence of heterogeneity we could expect all the points to lie within +the confidence bounds (positioned 2 units over and below the regression line). + +^theta^ is the effect estimated from the individual study, and ^setheta^ is +its standard error. For example theta might be a difference in means, a +log rate ratio, a log odds ratio or a log hazard ratio. + +If you have a dataset which contains data for all studies, then the @byvar@ +command can be used to derive the effect estimates and standard errors for the +individual studies. For example: + +. ^sort study^ +. ^byvar study, coef(group) se(group) generate:^ +. ^quietly poisson cases group, e(pyrs)^ +. ^sort study^ +. ^qui by study: keep if _n==1^ +. ^rename _C_1 logrr^ +. ^rename _S_1 se^ +. ^galbr logrr se, id(study) yline(0)^ + +Alternatively, the @collapse@ command may be useful. + + +Options +------- + +Graph options are allowed, but ^ylabel()^, ^yscale()^, ^xscale()^, ^symbol()^ +are not suggested. + +^id(^labelvar^)^ supplied any variable, which is used to label the studies. +If the data contains a labeled numeric variable, it can also be used. + +^yline(^0^)^ is a useful to check it with the direction and intensity of the +overall effect estimated in a fixed effects meta-analysis by the slope +of the (unweighted) regression line constrained through the origin. + + +Author +------- + + Aurelio Tobias + Universidad Miguel Hernandez, Alicante, Spain + email: bledatobias@@ctv.es + + +Also see +-------- + + STB: STB-41 sbe20, STB-38 sbe16 +On-line: help for @graph@, @byvar@, @collapse@, @for@, @meta@ (if installed), + @metareg@ (if installed), @metabias@ (if installed), @metacum@ (if + installed), @metainf@ (if installed) diff --git a/Modules/ado/plus/g/ghquad.ado b/Modules/ado/plus/g/ghquad.ado new file mode 100644 index 0000000..cd574bc --- /dev/null +++ b/Modules/ado/plus/g/ghquad.ado @@ -0,0 +1,38 @@ +*! Version 2.0, October 2002. (SJ4-1: st0057) + +program define ghquad + version 7.0 + syntax [varlist(min=2 max=2)] [, N(integer 10)] + tokenize `varlist' + local x "`1'" + local w "`2'" + if `n' + 2 > _N { + di in red /* + */ "`n' + 2 observations needed to compute quadrature points" + exit 2001 + } + tempname xx ww + + local i 1 + local m = int((`n' + 1)/2) + while `i' <= `m' { + if `i' == 1 { + scalar `xx' = sqrt(2*`n'+1)-1.85575*(2*`n'+1)^(-1/6) + } + else if `i' == 2 { scalar `xx' = `xx'-1.14*`n'^0.426/`xx' } + else if `i' == 3 { scalar `xx' = 1.86*`xx'-0.86*`x'[1] } + else if `i' == 4 { scalar `xx' = 1.91*`xx'-0.91*`x'[2] } + else { scalar `xx' = 2*`xx'-`x'[`i'-2] } + hermite `n' `xx' `ww' + qui replace `x' = `xx' in `i' + qui replace `w' = `ww' in `i' + local i = `i' + 1 + } + if mod(`n', 2) == 1 { qui replace `x' = 0 in `m' } + qui replace `x' = -`x'[`n'+1-_n] in `i'/`n' + qui replace `w' = `w'[`n'+1-_n] in `i'/`n' +end +exit + + + diff --git a/Modules/ado/plus/g/ghquadm.ado b/Modules/ado/plus/g/ghquadm.ado new file mode 100644 index 0000000..c64290f --- /dev/null +++ b/Modules/ado/plus/g/ghquadm.ado @@ -0,0 +1,85 @@ +program define ghquadm +* stolen from gllamm6 who stole it from rfprobit (Bill Sribney) + version 4.0 + + parse "`*'", parse(" ") + local n = `1' + if `n' + 2 > _N { + di in red /* + */ "`n' + 2 observations needed to compute quadrature points" + exit 2001 + } + + tempname x w xx ww a b + local i 1 + local m = int((`n' + 1)/2) + matrix x = J(1,`m',0) + matrix w = x + while `i' <= `m' { + if `i' == 1 { + scalar `xx' = sqrt(2*`n'+1)-1.85575*(2*`n'+1)^(-1/6) + } + else if `i' == 2 { scalar `xx' = `xx'-1.14*`n'^0.426/`xx' } + else if `i' == 3 { scalar `xx' = 1.86*`xx'-0.86*x[1,1] } + else if `i' == 4 { scalar `xx' = 1.91*`xx'-0.91*x[1,2] } + else { + local im2 = `i' -2 + scalar `xx' = 2*`xx'-x[1,`im2'] + } + hermite `n' `xx' `ww' + matrix x[1,`i'] = `xx' + matrix w[1,`i'] = `ww' + local i = `i' + 1 + } + if mod(`n', 2) == 1 { matrix x[1,`m'] = 0} +/* start in tails */ + matrix `b' = (1,1) + matrix w = w#`b' + matrix w = w[1,1..`n'] + matrix `b' = (1,-1) + matrix x = x#`b' + matrix x = x[1,1..`n'] +/* other alternative (left to right) */ +/* + above: matrix x = J(1,`n',0) + while ( `i'<=`n'){ + matrix x[1, `i'] = -x[1, `n'+1-`i'] + matrix w[1, `i'] = w[1, `n'+1-`i'] + local i = `i' + 1 + } +*/ + matrix `2' = x + matrix `3' = w +end + + +program define hermite /* integer n, scalar x, scalar w */ +* stolen from gllamm6 who stole it from rfprobit (Bill Sribney) + version 4.0 + local n "`1'" + local x "`2'" + local w "`3'" + local last = `n' + 2 + tempname i p + matrix `p' = J(1,`last',0) + scalar `i' = 1 + while `i' <= 10 { + matrix `p'[1,1]=0 + matrix `p'[1,2] = _pi^(-0.25) + local k = 3 + while `k'<=`last'{ + matrix `p'[1,`k'] = `x'*sqrt(2/(`k'-2))*`p'[1,`k'-1] /* + */ - sqrt((`k'-3)/(`k'-2))*`p'[1,`k'-2] + local k = `k' + 1 + } + scalar `w' = sqrt(2*`n')*`p'[1,`last'-1] + scalar `x' = `x' - `p'[1,`last']/`w' + if abs(`p'[1,`last']/`w') < 3e-14 { + scalar `w' = 2/(`w'*`w') + exit + } + scalar `i' = `i' + 1 + } + di in red "hermite did not converge" + exit 499 +end diff --git a/Modules/ado/plus/g/ghquadm.hlp b/Modules/ado/plus/g/ghquadm.hlp new file mode 100644 index 0000000..addc21a --- /dev/null +++ b/Modules/ado/plus/g/ghquadm.hlp @@ -0,0 +1,22 @@ +.- +help for ^ghquadm^ +.- + +Gauss-Hermite weights and absisae +--------------------------------- + + ^ghquadm^ n a w + +Description +----------- + +^ghquadm^ produces the weights (w) and absisae (a) -- stored as 2 matrices -- +to perform Gauss-Hermite quadrature with n quadrature points. This is a +modification of the @gllamm6@ modification of Bill Sribney's ^ghquad^. + + +Examples +-------- + + . ^ghquadm 12 abs weight^ + diff --git a/Modules/ado/plus/g/gllam_ll.ado b/Modules/ado/plus/g/gllam_ll.ado new file mode 100644 index 0000000..813d3ec --- /dev/null +++ b/Modules/ado/plus/g/gllam_ll.ado @@ -0,0 +1,1534 @@ +*! version 2.2.21 SRH 7 Sept 2011 +program define gllam_ll +version 7.0 +*disp in re "version 7.0" +args todo bo lnf junk1 junk2 what res +* what = 1: update posterior means and standard deviations +* what = 2: posterior probabilities +* what = 3: cluster likelihood contributions*cluster frequency weights +* what = 4: cluster likelihood contributions +* what = 5-7: posterior mean of statistic +/* +noi disp " " +noi disp $HG_SD1[$which] +noi disp $HG_SD2[$which] +noi disp $HG_C21[$which] +noi disp " " +*/ + +if "`what'"==""{ + local what = 0 +} +if `what' == 1 { + global HG_zip zipg1 + if $HG_free{ + global HG_zip zipf1 + } +} +else if $HG_adapt{ + global HG_zip zipga +} + +*matrix list `bo' +if $HG_dots { + noi disp in gr "." _c +} + +/* ----------------------------------------------------------------------------- */ +/* set up variables and macros needed */ + +tempname b mzlc + +local toplev = $HG_tplv +local topi = $HG_tpi +local clus $HG_clus + +sort `clus' + +* reset the the clock and reset znow +local i = 1 +matrix M_ip[1,1] = 1 /* in case topi=0 */ +while (`i' <= `topi'){ + matrix M_ip[1,`i'] = 1 + local i = `i' + 1 +} + +/* -------------------------------------------------------------------------------- */ +/* set up lprod1 ... lint1 */ + +local i=1 +tempvar extra +quietly gen double `extra'=0 +while `i' <= `toplev'{ + tempvar lint`i' + gen double `lint`i'' = 0.0 /* used to integrate, therefore must be zero */ + tempvar lfac`i' + quietly gen double `lfac`i'' = 0 + if (`i'>1){ + tempvar lprod`i' + quietly gen double `lprod`i'' = . + tempvar lfac`i' + quietly gen double `lfac`i'' = 0 + } + local i = `i' + 1 +} + +/* set up names for HG_xb`i' */ +local i = 1 +while (`i' <= $HG_tpff){ + tempname junk + global HG_xb`i' "`junk'" + local i = `i' + 1 +} +/* set up names for HG_s`i' */ +local i = 1 +while (`i'<=$HG_tprf){ + tempname junk + global HG_s`i' "`junk'" + local i = `i'+1 +} + + +if $HG_free{ +/* set up names for HG_p`lev'`k' */ + local lev = 2 + while `lev'<=$HG_tplv{ + local npar = M_np[1,`lev'] + if `npar'>0{ + local k = 1 + while `k'<=M_nip[1, `lev']{ + * disp in re "creating HG_p`lev'`k'" + tempname junk + global HG_p`lev'`k' "`junk'" + local k = `k' + 1 + } + } + local lev = `lev' + 1 + } +} + + +/* set up names for HG_E`rf'`lev' and HG_V`rf'`lev' */ +if `what'==1{ + local lev = 1 + while `lev'<=$HG_tplv{ + if `lev'<$HG_tplv{ + local maxrf =M_nrfc[2,`lev'+1] + } + else{ + local maxrf =M_nrfc[2,$HG_tplv] + } + + local rf = 1 + while `rf'<`maxrf'{ + * disp in re "creating HG_V`rf'`rf'`lev'" + tempname junk + global HG_E`rf'`lev' "`junk'" + gen double ${HG_E`rf'`lev'}=0 + tempname junk + global HG_V`rf'`rf'`lev' "`junk'" + gen double ${HG_V`rf'`rf'`lev'}=0 + local rf2 = `rf' + 1 + while `rf2'<$HG_tprf{ /* lower diagonal elements */ + * disp in re "creating HG_V`rf2'`rf'`lev'" + tempname junk + global HG_V`rf2'`rf'`lev' "`junk'" + gen double ${HG_V`rf2'`rf'`lev'}=0 + local rf2 = `rf2' + 1 + } + local rf = `rf' + 1 + } + + local lev = `lev' + 1 + } +} +else if $HG_adapt{ + local llev = 1 + while `llev'<$HG_tplv{ + local lrf = M_nrfc[2,`llev'] + while `lrf'=5{ + tempvar lpred + local lev = 1 + while `lev'<=$HG_tplv{ + tempname junk + global HG_stat`lev' "`junk'" + gen double ${HG_stat`lev'}=0 + local lev =`lev' + 1 + } +} + + +qui remcor "`bo'" + +if $HP_prior{ + qui calc_prior +} + +*noi matrix list `bo' +/* +if `npar'>0{ +disp in re "after remcor: HG_p21[$which] = " $HG_p21[$which] +disp in re "after remcor: HG_p22[$which] = " $HG_p22[$which] +} +*/ + +if $HG_error==1{ + disp in re "error in remcor" + scalar `lnf' = . + exit +} + +if "$HG_post"!=""{ /* for predictions */ + *noi tab $HG_ind + tempvar mssvls + * disp in re "`mssvls'" + qui gen byte `mssvls' = 0 + qui replace `mssvls' = 1 if ($ML_y1>=.) & $HG_ind>0 + local ffs = 1 + while `ffs' <= $HG_tpff { + qui replace `mssvls' = 1 if ${HG_xb`ffs'} >=. & $HG_ind>0 + local ffs = `ffs' + 1 + } + if M_nbrf[1,1]>0{ + qui replace `mssvls' = 1 if $HG_s1>=. & $HG_ind>0 + } +} + +* disp "HG_xb1 after remcor: HG_xb1[$which] = " $HG_xb1[$which] +* disp "HG_s2 after remcor: HG_s2[$which] = " $HG_s2[$which] +* disp "HG_s1 after remcor: HG_s1[$which] = $HG_s1 = " $HG_s1[$which] + +if $HG_adapt{ + *noi disp " " + local i = $HG_tprf - 1 + while `i' >= 1 { + local ip = `i' + 1 + local k = `i' - 1 + while `k' >= 1 { + local kp = `k' + 1 + * disp in re "replace HG_s`ip' = HG_s`ip' + HG_C`i'`k'*HG_s`kp'" + qui replace ${HG_s`ip'} = ${HG_s`ip'} + ${HG_C`i'`k'}*${HG_s`kp'} + local k = `k' - 1 + } + local i = `i' - 1 + } + + local i = 2 + tempname junk + global HG_zuoff "`junk'" + qui gen double $HG_zuoff = 0 + while `i'<=$HG_tprf{ + local im = `i' - 1 + * disp in re "replace HG_zuoff = HG_zuoff + HG_s`i'*HG_MU`im'" + qui replace $HG_zuoff = $HG_zuoff + ${HG_s`i'}*${HG_MU`im'} + + * disp in re "replace HG_s`i' = HG_SD`im'*HG_s`i'" + qui replace ${HG_s`i'} = ${HG_SD`im'}*${HG_s`i'} + + local i = `i' + 1 + } + *dis in re "HG_zuoff[$which] = " $HG_zuoff[$which] +} + + +local i = `toplev' +while `i' > 1 { + *noi disp "$HG_zip `i'$ + quietly $HG_zip `i' + local i = `i' - 1 +} + + +timer on 2 +* disp "STARTING LOOP" +/* --------------------------------------------------------------------------------- */ +/* recursive loop through r.effs (levels) */ +/* topi nested loops: irf from 1 ro nip(rf) */ +/* ip is "clock": (irf) stages of loops */ + +local levno = `toplev' +local rf = `topi' +while (`rf' <= `topi') { /* for each r.eff */ + +/* ----------------------------------------------------------------------------------*/ +/* reset ip to 1st point for all lower r.effs... */ +/* update znow */ + * disp "reset ip up to random effect " `rf' + while (`rf' > 1) { + local rf = `rf' - 1 + * disp `rf' + matrix M_ip[1,`rf'] = 1 + } + while (`levno' > 1){ + /* update znow for all new ips */ + *noi disp "$HG_zip `levno'$ + $HG_zip `levno' + local levno = `levno' - 1 + } +/* --------------------------------------------------------------------------------- */ +/* set lint1 to lpyz for new znow */ + + local rf = 1 + local levno = 1 + local sortlst `clus' /* cluster variables to aggregate over */ + + *matrix list M_ip + timer on 3 + qui lpyz `lint1' + timer off 3 + + * noi disp in re " after lpyz lint1[" $which "] = " `lint1'[$which] " and HG_ind = " $HG_ind[$which] + + if "$HG_post"!=""{/* for presictions */ + qui replace `lint1' = 0 if `mssvls'==1 + } + + * noi disp in re " after lpyz lint1 = " `lint1'[$which] " and HG_ind = " $HG_ind[$which] + + if `what'>=5{ + if $HG_tplv>1{ + matrix score double `lpred' = M_znow + } + else{ + qui gen double `lpred' = 0 + } + if $HG_adapt{ + qui replace `lpred' = $HG_xb1 + $HG_zuoff + `lpred' - $HG_offs + } + else{ + qui replace `lpred' = $HG_xb1 + `lpred' - $HG_offs + } + timer on 5 + gllas_yu $HG_stat1 `lpred' `res' `what' + sort `sortlst' /* added Oct 2004 */ + timer off 5 + qui drop `lpred' + } + + *noi summ `lint1' if `lint1'==-100 + quietly count if `lint1'==.& $HG_ind>0 + + * noi disp in re "number missing: " r(N) + if r(N) > 0{ + * overflow problem + * disp in re "overflow at level 1 ( " r(N) " missing values)" + * list $HG_clus if `lint1'==. + *matrix list `bo' + *lpyz `lint1' + if `what'!=3 { /* what = 3 used by robust & need valid ll contributions */ + scalar `lnf' = . + exit + } + } + quietly replace `lint1' = `lint1' * $HG_wt1 + +/* --------------------------------------------------------------------------------- */ +/* update lint for all completed levels up to */ +/* highest completed level, reset lower lints */ +/* to zero (for models including a random effect) */ + + while (M_ip[1,`rf'] == M_nip[1,`rf'] & `rf' <= `topi'){ + * digit equals its max => increment next digit + if (`rf' == M_nrfc[1,`levno'] & `levno' < `toplev'){ + * done last r.eff of current level + * disp "********** level " `levno' " complete ************" + + * next level + local lprev = `levno' + local levno = `levno' + 1 + + /* change sortlst */ + local prvsort `sortlst' + local l = `toplev' - `levno' + 2 + tokenize "`sortlst'" + * take away var. of level to sum over + local `l' " " + local sortlst "`*'" +/*------------------------------------------------------------------------------------ */ +/* change lprod`levno' and */ +/* update lint`levno' */ + + if "`f`levno''"==""{ /* first term for lint`levno' */ + local f`levno'=1 + * disp "first term for level `levno'" + } + else{ + local f`levno'=0 + * disp "next term for level `levno'" + } +timer on 4 +if $HG_noC1 { + lnupdate `levno' `lint`levno'' `lint`lprev'' `lprod`levno'' /* + */ `lfac`levno'' `lfac`lprev'' `extra' /* + */ `lnf' "`prvsort'" "`sortlst'" `f`levno'' `what' +} +else { + _gllamm_lnu, levno(`levno') lintlv(`lint`levno'') /* + */ lintprv(`lint`lprev'') lprodlv(`lprod`levno'') /* + */ lfaclv(`lfac`levno'') lfacprv(`lfac`lprev'') extra(`extra') /* + */ lnf(`lnf') prvsort(`prvsort') sortlst(`sortlst') /* + */ first(`f`levno'') what(`what') +} +timer off 4 + + local f`lprev' + +*args levno lintlv lintprv lprodlv lfaclv lfacprv extra lnf prevsort sortlst first +/* ------------------------------------------------------------------------------------------- */ + } /* next digit */ + local rf = `rf' + 1 + } + * rf is first r.eff that is not complete + * increase clock in lowest incomplete digit + * disp "update rf = " `rf' + matrix M_ip[1,`rf'] = M_ip[1,`rf'] + 1 +} +timer off 2 +*quietly{ + *now rf too high + *!! disp "********** level " `toplev' " complete ************" + * noi disp "lint" `toplev' "[" $which "] = " `lint`toplev''[$which] + if(`toplev'>1){ + if `what'==1{ + local rf = 1 + while `rf'< $HG_tprf{ + * disp in re "setting HG_MU`rf' and HG_SD`rf'" + * disp in re "by `sortlst': replace HG_MU`rf' = HG_E`rf'`toplev'/lint`toplev'[_N]" + qui by `sortlst': replace ${HG_MU`rf'} = ${HG_E`rf'`toplev'}/`lint`toplev''[_N] + qui by `sortlst': replace ${HG_SD`rf'} = ${HG_V`rf'`rf'`toplev'}/`lint`toplev''[_N] - ${HG_MU`rf'}^2 + qui replace ${HG_SD`rf'} = cond(${HG_SD`rf'}>0,sqrt(${HG_SD`rf'}),0) + *noi disp " " + *noi disp "HG_MU`rf'[$which] = " ${HG_MU`rf'}[$which] + *summ ${HG_MU`rf'} + *noi disp "HG_SD`rf'[$which] = " ${HG_SD`rf'}[$which] + *summ ${HG_SD`rf'} + local rf2 = 1 + while `rf2' < `rf'{ /* must use MU's that are already calculated */ + qui by `sortlst': replace ${HG_C`rf'`rf2'} = ${HG_V`rf'`rf2'`toplev'}/`lint`toplev''[_N] - (${HG_MU`rf2'}*${HG_MU`rf'}) + *noi disp "HG_C`rf'`rf2'[$which] = " ${HG_C`rf'`rf2'}[$which] + *summ ${HG_C`rf'`rf2'} + local rf2 = `rf2' + 1 + } + local rf = `rf' + 1 + } + if $HG_adapt==1{ /* have recalculated means and covariances and need diff. ones for adaptive */ + prepadpt + } + } + else if `what'>=5{ + if $HG_post{ + qui by `sortlst': replace ${HG_stat`toplev'} = ${HG_stat`toplev'}/`lint`toplev''[_N] + } + } + else if `what'==2{ + local i = 1 + while `i'<= M_nip[1,2] { + qui by `sortlst': replace ${HG_p`i'} = ${HG_p`i'}/`lint`toplev''[_N] + local i = `i' + 1 + } + } + *a disp "taking log of lint" `toplev' " = " `lint`toplev''[$which] + *a disp "subtracting " `lfac`toplev''[$which] + + ** begin junk (conditional log-likelihood for capture-recapture) +/* + qui replace `lint`toplev'' = exp(ln(`lint`toplev'')-`lfac`toplev'') + qui summ `lint`toplev'', meanonly + qui replace `lint`toplev'' = ${HG_wt`toplev'}*(ln(`lint`toplev'') - ln(r(sum))) +*/ + ** end junk + + quietly replace `lint`toplev'' = (ln(`lint`toplev'')-`lfac`toplev'')* ${HG_wt`toplev'} + } + * noi display "lint" `toplev' "[" $which "] = " `lint`toplev''[$which] + if `what'==3{ + if `toplev'==1{ /* by sorlst won't work for composite link */ + qui replace `res' = `lint`toplev'' + } + else{ + qui by `sortlst': replace `res' = `lint`toplev''[_N] + } + if $HP_prior { + qui replace `res' = `res' + $HP_res/ M_nu[1,$HG_tplv] + } + } + else if `what'==4{ + if `toplev'==1{ /* by sorlst won't work for composite link */ + qui replace `res' = `lint`toplev''/ ${HG_wt`toplev'} + } + else{ + qui by `sortlst': replace `res' = `lint`toplev''[_N]/ ${HG_wt`toplev'} + } + if $HP_prior { + qui replace `res' = `res' + $HP_res / M_nu[1,$HG_tplv] + } + } + else if `what'>=5{ + qui replace `res' = ${HG_stat`toplev'} + } + qui by `sortlst': replace `extra' = cond(_n==_N,1,0) + *mlsum `lnf' = `lint`toplev'' if `extra' == 1 /* can only use this when program called by ML */ + *noi summ `lint`toplev'' if `extra' == 1 + *list $HG_clus `lint`toplev'' if `extra' ==1 & `lint`toplev''< -300 + + qui count if `extra' == 1 + local n = r(N) + summarize `lint`toplev'', meanonly + if `n' > r(N) { + * noi disp "there are " r(N) " values of likelihood, should be " `n' + * noi list $HG_clus if `extra' == 1& `lint`toplev''==. + * noi matrix list `bo' + * noi disp "lnf equal to missing in last step" + scalar `lnf' = . + exit + } + scalar `lnf' = r(sum) + if $HP_prior{ + if $HP_sprd == 1 & `what'== 0 { + scalar `lnf' = `lnf' + $HP_res / M_nu[1,$HG_tplv] + } + else{ + * disp in re $HP_res + scalar `lnf' = `lnf' + $HP_res + } + } + * display in re "total lnf = " `lnf' + * capture drop lint`toplev' + * gen double lint`toplev' = `lint`toplev'' +*} /* qui */ +end + +program define prepadpt +*qui replace $HG_C21 = 0 +*qui replace $HG_MU1 = 0 +*qui replace $HG_MU2 = 0 +*qui replace $HG_SD1 = 1 +*qui replace $HG_SD2 = 1 +*qui replace $HG_C31 = 0 +*qui replace $HG_C32 = 0 +*disp in re " " + + local tplv = $HG_tplv + + local i = $HG_tprf - 1 + while `i' >= 1 { + * disp in re " " + qui replace ${HG_MU`i'} = 0 if ${HG_MU`i'} ==. + *qui replace ${HG_SD`i'} = 1e-05 if ${HG_SD`i'} < 1e-25 | ${HG_SD`i'} ==. + qui replace ${HG_SD`i'} = 1e-05 if ${HG_SD`i'} < 1e-05 | ${HG_SD`i'} ==. +* variance + * disp in re "HG_V`i'`i'`tplv' = HG_SD`i'^2" + qui replace ${HG_V`i'`i'`tplv'} = ${HG_SD`i'}^2 + local j = $HG_tprf - 1 + while `j' > `i'{ + * disp in re "HG_V`i'`i'`tplv' = HG_V`i'`i'`tplv' - HG_C`j'`i'*HG_V`j'`i'`tplv' " + ** new + qui replace ${HG_C`j'`i'} = 0 if ${HG_V`i'`i'`tplv'} - ${HG_C`j'`i'}*${HG_V`j'`i'`tplv'} < 0 + qui replace ${HG_V`i'`i'`tplv'} = ${HG_V`i'`i'`tplv'} - ${HG_C`j'`i'}*${HG_V`j'`i'`tplv'} + + qui replace ${HG_MU`i'} = ${HG_MU`i'} - ${HG_C`j'`i'}*${HG_MU`j'} + * disp in re "HG_MU`i' = HG_MU`i' - HG_C`j'`i'*HG_MU`j' = " in ye ${HG_MU`i'}[$which] + * noi summ ${HG_MU`i'} + local j = `j' - 1 + } + + * disp in re "negative variances" + * noi summ ${HG_V`i'`i'`tplv'} if ${HG_V`i'`i'`tplv'} <0 + * noi list $HG_clus ${HG_V`i'`i'`tplv'} if ${HG_V`i'`i'`tplv'} <0 + * qui replace ${HG_V`i'`i'`tplv'} = 1e-10 if ${HG_V`i'`i'`tplv'} <0 + qui replace ${HG_SD`i'} = sqrt(${HG_V`i'`i'`tplv'}) + *disp in re "HG_MU`i' = " in ye in ye ${HG_MU`i'}[$which] + *disp in re "HG_SD`i' = " in ye ${HG_SD`i'}[$which] + * noi summ ${HG_SD`i'} + +* covariances and betas + local k = `i' - 1 + while `k' >= 1 { + qui replace ${HG_V`i'`k'`tplv'} = ${HG_C`i'`k'} + * disp in re "HG_V`i'`k'`tplv' = HG_C`k'`i'" + local j = $HG_tprf - 1 + while `j' > `i'{ + *disp in re "HG_V`i'`k'`tplv' = HG_V`i'`k'`tplv' - HG_C`j'`i'*HG_V`j'`k'`tplv'" + + qui replace ${HG_V`i'`k'`tplv'} = ${HG_V`i'`k'`tplv'} - ${HG_C`j'`i'}*${HG_V`j'`k'`tplv'} + local j = `j' - 1 + } + qui replace ${HG_C`i'`k'} = ${HG_V`i'`k'`tplv'}/${HG_V`i'`i'`tplv'} + * noi summ ${HG_C`i'`k'} + *disp in re "HG_C`i'`k' = " in ye ${HG_C`i'`k'}[$which] + local k = `k' - 1 + } + + local i = `i' - 1 + } +*qui replace $HG_C21 = 0 +/* +qui replace $HG_MU2 = .57022599 +qui replace $HG_SD2 = .83303331 +qui replace $HG_MU1 = -.55565732 +qui replace $HG_SD1 = .65728191 +*/ +end + +program define lnupdate +version 7.0 +args levno lintlv lintprv lprodlv lfaclv lfacprv extra lnf prvsort sortlst first what +tempvar lpkpl +quietly{ + * disp in re "!!! update level " `levno' + * noi matrix list M_znow + + /* set previous lint to ln(lint) */ + local lprev = `levno' - 1 + if(`levno' > 2){ + *!! disp " replace lint" `lprev' " by ln(lint" `lprev' ")" + quietly count if `lintprv' < 1e-308 + if r(N) > 0{ + /* overflow problem */ + * noi disp "overflow at level " `lprev' + scalar `lnf' = . + exit + } + if `what'==1{ + local rf = 1 + while `rf'< M_nrfc[2,`lprev']{ + * disp "by `prvsort': replace HG_E`rf'`lprev' = HG_E`rf'`lprev'/lintprv[_N]" + qui by `prvsort': replace ${HG_E`rf'`lprev'} = ${HG_E`rf'`lprev'}/`lintprv'[_N] + * disp in re "by `prvsort': replace HG_V`rf'`rf'`lprev' = HG_V`rf'`rf'`lprev'/lintprv[_N]" + qui by `prvsort': replace ${HG_V`rf'`rf'`lprev'} = ${HG_V`rf'`rf'`lprev'}/`lintprv'[_N] + local rf2 = `rf' + 1 + while `rf2' < $HG_tprf{ + * disp in re "by `prvsort': replace HG_V`rf2'`rf'`lprev' = HG_V`rf2'`rf'`lprev'/lintprv[_N]" + qui by `prvsort': replace ${HG_V`rf2'`rf'`lprev'} = ${HG_V`rf2'`rf'`lprev'}/`lintprv'[_N] + local rf2 = `rf2' + 1 + } + local rf = `rf' + 1 + } + + } + if `what'>=5{ + if $HG_post{ + qui by `prvsort': replace ${HG_stat`lprev'} = ${HG_stat`lprev'}/`lintprv'[_N] + } + } + quietly replace `lintprv' = ln(`lintprv') + quietly replace `lintprv' = (`lintprv'-`lfacprv')*${HG_wt`lprev'} + } + + /* sum previous lprod within cluster at current level */ + *!! disp " " + * noi disp "by `sortlst': replace lprod" `levno' "=cond(_n==N, sum(lint" `lprev' "))" + * noi summ `lintprv' + quietly by `sortlst': replace `lprodlv' = cond(_n==_N,sum(`lintprv'),.) + * noi disp " " + * noi disp "lprod" `levno' " = " `lprodlv'[$which] + * noi disp "lintprv[" $which "]= " `lintprv'[$which] + + /* accumulate terms for integral */ + + /* get lpkpl: log of product of r.effs at level */ + qui $HG_lzpr `levno' `lpkpl' + * noi disp "exp(lprod`leno'+lpkpl) = " exp(`lpkpl'[$which]+`lprodlv'[$which]) + + if `first' { /* first term for lint`levno' */ + quietly replace `extra' = 0 + quietly replace `lfaclv' = -`lprodlv' - `lpkpl' + *a noi disp " " + * noi disp "lfac`levno' = " `lfaclv'[$which] + * noi disp "lintlv = 1" + qui replace `lintlv' = 1 + } + else{ + local max = 500 + quietly replace `extra' = cond(`lprodlv'+ `lpkpl'+`lfaclv'>`max', /* + */ -(`lprodlv'+`lpkpl'+`lfaclv')+`max',0) + * noi disp "extra = " `extra'[$which] + quietly replace `lfaclv'=`lfaclv'+`extra' + * noi disp "lfac`levno' = " `lfaclv'[$which] + + /* increment lint at current level using lprod at previous level */ + * noi disp "increase lint" `levno' " by exp(lprodlv + lpkpl +lfaclv)" + quietly replace `lintlv' = exp(`extra')*`lintlv' + exp(`lprodlv'+ `lpkpl'+`lfaclv') + * noi disp "increase by " exp(`lprodlv'[$which]+`lpkpl'[$which]+`lfaclv'[$which]) " to " `lintlv'[$which] + } + + +/* posterior means and variances*/ + if `what'==1{ + local rf = 1 + while `rf'< M_nrfc[2,`levno'] { + * noi disp "update `rf' `levno'" + quietly by `sortlst': replace ${HG_E`rf'`levno'}=/* + */ exp(`extra'[_N])*${HG_E`rf'`levno'}+ ${HG_E`rf'`lprev'}*exp(`lprodlv'[_N]+`lpkpl'+`lfaclv'[_N]) + * noi disp "HG_E" `rf' `levno' "[" $which "] = " ${HG_E`rf'`levno'}[$which] + quietly by `sortlst': replace ${HG_V`rf'`rf'`levno'}=/* + */ exp(`extra'[_N])*${HG_V`rf'`rf'`levno'}+ ${HG_V`rf'`rf'`lprev'}*exp(`lprodlv'[_N]+`lpkpl'+`lfaclv'[_N]) + *noi disp "HG_V" `rf' `rf' `levno' "[" $which "] = " ${HG_V`rf'`rf'`levno'}[$which] + local rf2 = `rf' + 1 + while `rf2' < $HG_tprf { + * noi disp "HG_V`rf2'`rf'`levno' is ${HG_V`rf2'`rf'`levno'}" + quietly by `sortlst': replace ${HG_V`rf2'`rf'`levno'}=/* + */ exp(`extra'[_N])*${HG_V`rf2'`rf'`levno'}+ ${HG_V`rf2'`rf'`lprev'}*exp(`lprodlv'[_N]+`lpkpl'+`lfaclv'[_N]) + * noi disp "HG_V" `rf2' `rf' `levno' "[" $which "] = " ${HG_V`rf2'`rf'`levno'}[$which] + local rf2 = `rf2' + 1 + } + local rf = `rf' + 1 + } + + } + if `what'>=5{ + if $HG_post{ + * disp in re "sortlist: `sortlst'" + *sort `sortlst' /* removed oct 2004 */ + quietly by `sortlst': replace ${HG_stat`levno'}=/* + */ exp(`extra'[_N])*${HG_stat`levno'}+ /* + */ ${HG_stat`lprev'}*exp(`lprodlv'[_N]+`lpkpl'+`lfaclv'[_N]) + } + else{ + *disp in re "HG_stat`levno'[1] = " ${HG_stat`levno'}[1] " + " ${HG_stat`lprev'}[1] " * " exp(`lpkpl') + qui replace ${HG_stat`levno'} = ${HG_stat`levno'} + ${HG_stat`lprev'}*exp(`lpkpl') + } + } + + else if `what'==2{ + * noi matrix list M_ip + local i = M_ip[1,2] + local j = 1 + while `j'<`i'{ + quietly by `sortlst': replace ${HG_p`j'} = exp(`extra'[_N])*${HG_p`j'} + local j = `j' + 1 + } + quietly by `sortlst': replace ${HG_p`i'} = exp(`lprodlv'[_N]+`lpkpl'+`lfaclv'[_N]) + } + /* reset previous lint to zero */ + if `levno'>2{ + if `what'==1{ + local rf = 1 + while `rf'=5{ + *disp in re "setting HG_stat" `lprev' " to zero" + quietly replace ${HG_stat`lprev'} = 0 + } + } + } /* qui */ +end + +program define zipf + version 7.0 + * updates znow + * matrix list M_ip + args levno + + * disp "in zip, levno is " `levno' + local i = M_nrfc[2,`levno'-1] + 1 + + *!! disp "update" + * same class for all random effects + local k = M_nrfc[1,`levno'] + local k = M_ip[1,`k'] + local last = M_nrfc[2,`levno'] + while `i' <= `last'{ + local npt = M_nip[2,`i'] + local im = `i' - 1 + * disp " "`im' "th z to " `which' "th location" + * disp " using M_zlc`npt' " + matrix M_znow[1,`im'] = M_zlc`npt'[1,`k'] + local i = `i' + 1 + } +end + +program define zipf1 + version 7.0 + * updates znow + * matrix list M_ip + args levno + tempname mzlc + + * disp "in zip, levno is " `levno' + local i = M_nrfc[2,`levno'-1] + 1 + + *!! disp "update" + * same class for all random effects + local k = M_nrfc[1,`levno'] + local k = M_ip[1,`k'] + local last = M_nrfc[2,`levno'] + while `i' <= `last'{ + local npt = M_nip[2,`i'] + local im = `i' - 1 + * disp " "`im' "th z to " `which' "th location" + * disp " using M_zlc`npt' " + matrix M_znow[1,`im'] = M_zlc`npt'[1,`k'] + local i = `i' + 1 + } + local llev = `levno' - 1 + local im = M_nrfc[2,`llev'] + while `im' < `last'{ +* change HG_E and HG_V + scalar `mzlc' = M_znow[1,`im'] + qui replace ${HG_E`im'`llev'} = ${HG_MU`im'} + ${HG_SD`im'}*`mzlc' + local im2 = $HG_tprf - 1 + while `im2' > `im'{ + scalar `mzlc' = M_znow[1,`im2'] + * disp in re "replace HG_E`im'`llev' = HG_E`im'`llev' + HG_C`im2'`im'*(HG_MU`im2' + HG_SD`im2'*`mzlc')" + qui replace ${HG_E`im'`llev'} = ${HG_E`im'`llev'} + ${HG_C`im2'`im'}*(${HG_MU`im2'} + ${HG_SD`im2'}*`mzlc') + local im2 = `im2' - 1 + } + * noi disp "HG_E`im'`llev'[$which] = " ${HG_E`im'`llev'}[$which] + qui replace ${HG_V`im'`im'`llev'} = ${HG_E`im'`llev'}^2 + + local im = `im' + 1 + } + local im = M_nrfc[2,`llev'] + while `im' < `last'{ +* covariances with same level and higher level effects + local llev2 = `llev' + local im2 = `im' + 1 + while `llev2'<$HG_tplv{ + while `im2' < M_nrfc[2,`llev2' + 1]{ + qui replace ${HG_V`im2'`im'`llev'} = ${HG_E`im'`llev'}*${HG_E`im2'`llev2'} + * disp in re "HG_V`im2'`im'`llev' = HG_E`im'`llev'*HG_E`im2'`llev2' = " in ye ${HG_V`im2'`im'`llev'}[$which] + local im2 = `im2' + 1 + } + local llev2 = `llev2' + 1 + } + local im = `im' + 1 + } +end + +program define zipg + version 7.0 + * updates znow + * matrix list M_ip + args levno + + * disp "in zip, levno is " `levno' + local i = M_nrfc[2,`levno'-1] + 1 + + *!! disp "update" + if $HG_mult{ + *local npt = M_nip[2,`i'] + local npt = M_nip[2,`levno'] + local k = M_nrfc[1,`levno'] + local k = M_ip[1,`k'] + local f = M_nrfc[2,`levno'-1] + } + + local last = M_nrfc[2,`levno'] + while `i' <= `last'{ + local im = `i' - 1 + + if $HG_mult{ + matrix M_znow[1,`im'] = M_zlc`npt'[`i'-`f',`k'] + } + else{ + local npt = M_nip[2,`i'] + local which = M_ip[1,`i'] + * disp " "`im' "th z to " `which' "th location" + * disp " using M_zlc`npt' " + matrix M_znow[1,`im'] = M_zlc`npt'[1,`which'] + } + + *!! disp M_znow[1,`im'] + local i = `i' + 1 + } +end + + +program define zipga + version 7.0 + * updates znow + * matrix list M_ip + args levno + tempname mzlc + + * disp "in zip, levno is " `levno' + local llev = `levno' - 1 + local i = M_nrfc[2,`llev'] + 1 + + *!! disp "update" + if $HG_mult{ + *local npt = M_nip[2,`i'] + local npt = M_nip[2,`levno'] + local k = M_nrfc[1,`levno'] + local k = M_ip[1,`k'] + local f = M_nrfc[2,`levno'-1] + } + local last = M_nrfc[2,`levno'] + + while `i' <= `last'{ + *local npt = M_nip[2,`i'] + local im = `i' - 1 + + if $HG_mult{ + matrix M_znow[1,`im'] = M_zlc`npt'[`i'-`f',`k'] + } + else{ + local npt = M_nip[2,`i'] + local which = M_ip[1,`i'] + * disp " "`im' "th z to " `which' "th location" + * disp " using M_zlc`npt' " + matrix M_znow[1,`im'] = M_zlc`npt'[1,`which'] + } + local i = `i' + 1 + } + local im = M_nrfc[2,`llev'] + while `im' < `last'{ + +* change HG_E + scalar `mzlc' = M_znow[1,`im'] + qui replace ${HG_E`im'`llev'} = ${HG_MU`im'} + ${HG_SD`im'}*`mzlc' + *local im2 = M_nrfc[2,`llev'] + + local im2 = $HG_tprf - 1 + while `im2' > `im'{ + scalar `mzlc' = M_znow[1,`im2'] + * disp in re "replace HG_E`im'`llev' = HG_E`im'`llev' + HG_C`im2'`im'*(HG_MU`im2' + HG_SD`im2'*`mzlc')" + qui replace ${HG_E`im'`llev'} = ${HG_E`im'`llev'} + ${HG_C`im2'`im'}*(${HG_MU`im2'} + ${HG_SD`im2'}*`mzlc') + local im2 = `im2' - 1 + } + * noi disp "HG_E`im'`llev'[$which] = " ${HG_E`im'`llev'}[$which] + + *!! disp M_znow[1,`im'] + local im = `im' + 1 + } +end + + +program define zipg1 + version 7.0 + * updates znow + * matrix list M_ip + args levno + tempname mzlc + + * noi disp "in zip, levno is " `levno' + local llev = `levno' - 1 + local i = M_nrfc[2,`llev'] + 1 + + *!! disp "update" + if $HG_mult{ + *local npt = M_nip[2,`i'] + local npt = M_nip[2,`levno'] + local k = M_nrfc[1,`levno'] + local k = M_ip[1,`k'] + local f = M_nrfc[2,`levno'-1] + } + local last = M_nrfc[2,`levno'] + + while `i' <= `last'{ + local im = `i' - 1 + *local npt = M_nip[2,`i'] + if $HG_mult{ + * disp in re "M_znow[1,`im'] = M_zlc`npt'[`i'-`f',`k']" + matrix M_znow[1,`im'] = M_zlc`npt'[`i'-`f',`k'] + } + else{ + local npt = M_nip[2,`i'] + local which = M_ip[1,`i'] + * disp " "`im' "th z to " `which' "th location" + * disp " using M_zlc`npt' " + matrix M_znow[1,`im'] = M_zlc`npt'[1,`which'] + } + + local i = `i' + 1 + } + local im = M_nrfc[2,`llev'] + while `im' < `last'{ +* change HG_E and HG_V + scalar `mzlc' = M_znow[1,`im'] + qui replace ${HG_E`im'`llev'} = ${HG_MU`im'} + ${HG_SD`im'}*`mzlc' + local im2 = $HG_tprf - 1 + while `im2' > `im'{ + scalar `mzlc' = M_znow[1,`im2'] + * disp in re "replace HG_E`im'`llev' = HG_E`im'`llev' + HG_C`im2'`im'*(HG_MU`im2' + HG_SD`im2'*`mzlc')" + qui replace ${HG_E`im'`llev'} = ${HG_E`im'`llev'} + ${HG_C`im2'`im'}*(${HG_MU`im2'} + ${HG_SD`im2'}*`mzlc') + local im2 = `im2' - 1 + } + * noi disp "HG_E`im'`llev'[$which] = " ${HG_E`im'`llev'}[$which] + qui replace ${HG_V`im'`im'`llev'} = ${HG_E`im'`llev'}^2 + + local im = `im' + 1 + } + local im = M_nrfc[2,`llev'] + while `im' < `last'{ +* covariances with same level and higher level effects + local llev2 = `llev' + local im2 = `im' + 1 + while `llev2'<$HG_tplv{ + while `im2' < M_nrfc[2,`llev2' + 1]{ + qui replace ${HG_V`im2'`im'`llev'} = ${HG_E`im'`llev'}*${HG_E`im2'`llev2'} + * disp in re "HG_V`im2'`im'`llev' = HG_E`im'`llev'*HG_E`im2'`llev2' = " in ye ${HG_V`im2'`im'`llev'}[$which] + local im2 = `im2' + 1 + } + local llev2 = `llev2' + 1 + } + local im = `im' + 1 + } +end + + +program define lzprobf + version 7.0 + * for free masses + * returns product of pk needed for integration at level lev for current ip + args levno lpkpl + tempname mzps mznow + * disp in re "in zprob, levno is " `levno' + + local i=M_nrfc[1,`levno'-1] + 1 + + *!! disp "-----------lpkpl: sum of log of" + + local npt = M_nip[2,`i'] + * disp " prob for " `i' "th r.eff: " `which' "th weight" + * disp " using M_zps`npt' " + + local which = M_ip[1,`i'] + if M_np[1,`levno']>0{ + qui gen double `lpkpl' = ${HG_p`npt'`which'} + } + else{ + qui gen double `lpkpl' = M_zps`npt'[1,`which'] + } + + * disp in re "lpkpl[$which] = " `lpkpl'[$which] +end + +program define lzprobg + version 7.0 + * product gaussian quadrature + * returns product of pk needed for integration at level lev for current ip + args levno lpkpl + tempname mzps mznow + * disp in re "in zprob, levno is " `levno' + qui gen double `lpkpl' = 0 + local lv = `levno' - 1 + local i=M_nrfc[1,`lv'] + 1 + + *!! disp "-----------lpkpl: sum of log of" + local last = M_nrfc[1,`levno'] + while `i' <= `last'{ + local npt = M_nip[2,`i'] + * disp " prob for " `i' "th r.eff: " `which' "th weight" + * disp " using M_zps`npt' " + + local which = M_ip[1,`i'] + local im = `i' - 1 + scalar `mzps' = M_zps`npt'[1,`which'] + qui replace `lpkpl' = `lpkpl'+ `mzps' + if $HG_adapt{ + scalar `mznow' = M_znow[1,`im'] + *qui replace `lpkpl' = `lpkpl' + ln(${HG_SD`im'}) + `mznow'^2/2 - (${HG_MU`im'} + ${HG_SD`im'}*`mznow')^2/2 + qui replace `lpkpl' = `lpkpl' + ln(${HG_SD`im'}) + `mznow'^2/2 - (${HG_E`im'`lv'})^2/2 + } + local i=`i'+1 + } + * disp in re "lpkpl[$which] = " `lpkpl'[$which] +end + +program define lzprobm + version 7.0 + * mult version + * returns product of pk needed for integration at level lev for current ip + args levno lpkpl + tempname mzps mznow + * disp in re "in zprob, levno is " `levno' + + local lv = `levno' - 1 + local i=M_nrfc[1,`lv'] + 1 + + *!! disp "-----------lpkpl: sum of log of" + + local npt = M_nip[2,`i'] + * disp " prob for " `i' "th r.eff: " `which' "th weight" + * disp " using M_zps`npt' " + + local which = M_ip[1,`i'] + scalar `mzps' = M_zps`npt'[1,`which'] + qui gen double `lpkpl' = `mzps' + + if $HG_adapt{ + local i=M_nrfc[2,`lv'] + 1 + local last = M_nrfc[2,`levno'] + while `i' <= `last'{ + local im = `i' - 1 + scalar `mznow' = M_znow[1,`im'] + qui replace `lpkpl' = `lpkpl' + ln(${HG_SD`im'}) + `mznow'^2/2 - (${HG_E`im'`lv'})^2/2 + *disp in re "HG_E`im'`lv'[$which] = " ${HG_E`im'`lv'}[$which] + local i = `i' + 1 + } + } + *disp in re "lpkpl[$which] = " `lpkpl'[$which] +end + + +program define lpyz + version 7.0 +* returns log of prob of obs. given znow + args lpyz + + * disp "-----------------called lpyz" + + tempvar zu xb mu /* linear predictor and zu: r.eff*design matrix for r.eff */ + +/* ----------------------------------------------------------------------------- */ +*quietly{ + + + if $HG_tprf>1{ + + matrix score double `zu' = M_znow + if $HG_adapt{ + qui replace `zu' = $HG_zuoff + `zu' + *qui replace `zu' = $HG_E11*$HG_s2 + $HG_E21*$HG_s3 + } + + + } + else{ + qui gen double `zu' = 0 + } + + * matrix list M_znow + * disp "ML_y1: $ML_y1 " $ML_y1[$which] + * matrix list M_ip + disp " xb1 = " $HG_xb1[$which] + disp " zu = " `zu'[$which] + + + if $HG_mlog>0{ + nominal `lpyz' `zu' + } + + if $HG_oth{ + local myand + if "$HG_lv"~=""&($HG_nolog>0|$HG_mlog>0){ + local myand $HG_lvolo~=1 + } + quietly gen double `mu' = 0 + *if $HG_noC|$HG_comp>0 { + if $HG_noC { + link "$HG_link" `mu' $HG_xb1 `zu' $HG_s1 + if $HG_comp>0 { + compos `mu' "`myand'" + } + *disp " mu = " `mu'[$which] + if $HG_comp>0{ + if "`myand'"~=""{ + local myand `myand' & $HG_ind>0 + } + else{ + local myand $HG_ind>0 + } + } + family "$HG_famil" `lpyz' `mu' "`myand'" + } + + else { + if $HG_lev1 != 0 { + local s1opt "st($HG_s1)" + } + if "$HG_denom" != "" { + local denopt "denom($HG_denom)" + } + if "$HG_fv" != "" { + local fvopt "fv($HG_fv)" + } + if "$HG_lv" != "" { + local lvopt "lv($HG_lv)" + local othopt "oth(M_oth)" + } + if "`myand'" != "" { + local ifopt "if `myand'" + } + if $HG_comp > 0 { /* only got here if new Stata 8 */ + local comp "comp($HG_comp)" + local cclus "cluster($HG_clus)" + } + noi _gllamm_fl `lpyz' `mu' `ifopt', `s1opt' /* + */ link($HG_link) family($HG_famil) `denopt' `fvopt' /* + */ `lvopt' xb($HG_xb1) zu(`zu') /* + */ y($ML_y1) `othopt' `comp' `cclus' + } + disp " mu = " `mu'[$which] + } + + if $HG_nolog>0{ + if $HG_noC { + ordinal `lpyz' `zu' + } + else { + if $HG_lev1 != 0 { + local stopt st($HG_s1) + } + if "$HG_lv"!="" { + local lvopt lv($HG_lv) + } + local j 1 + while `j'<=$HG_tpff { + local xbeta `xbeta' ${HG_xb`j'} + local j = `j' + 1 + } + _gllamm_ord `lpyz', y($ML_y1) xb(`xbeta') /* + */ zu(`zu') link($HG_linko) nlog($HG_nolog) /* + */ olog(M_olog) nresp(M_nresp) resp(M_resp) /* + */ `stopt' `lvopt' + } + } + +*} /* qui */ +end + +program define compos + version 7.0 + args mu und + + tempvar junk mu2 + local ifs + if "`und'"~=""{ + local ifs if `und' + } + gen double `junk'=0 + gen double `mu2'=. + local i = 1 + *disp in re "in compos: HG_clus is: $HG_clus" + while `i'<= $HG_comp{ + *disp in re "in compos: variable HG_co`i' is: ${HG_co`i'}" + replace `junk' = `mu'*${HG_co`i'} + qui by $HG_clus: replace `junk' = sum(`junk') + qui by $HG_clus: replace `mu2' = `junk'[_N] if $HG_ind==`i' + local i = `i' + 1 + } + qui replace `mu' = `mu2' `ifs' +end + +program define nominal + version 7.0 + args lpyz zu + tempvar mu + + if $HG_smlog{ + local s $HG_s1 + } + else{ + local s = 1 + } + local and + if "$HG_lv"~=""{ + local and & $HG_lv == $HG_mlog + local mlif if $HG_lv == $HG_mlog + } + disp "mlogit link `mlif'" + if $HG_exp==1&$HG_expf==0{ + qui gen double `mu' = exp(`zu'/`s') if $ML_y1==M_respm[1,1] `and' + local n=rowsof(M_respm) + local i=2 + while `i'<=`n'{ + local prev = `i' - 1 + * disp "xb`prev':" ${HG_xb`prev'}[$which] + qui replace `mu' = exp((${HG_xb`prev'} + `zu')/`s') if $ML_y1==M_respm[`i',1] `and' + local i = `i' + 1 + } + + sort $HG_clus $HG_ind + qui by $HG_clus: replace `lpyz'=cond(_n==_N,sum(`mu'),.) `mlif' + qui replace `lpyz' = ln(`mu'/`lpyz') `mlif' +/* skip sort + qui by $HG_clus: replace `lpyz' = sum(`mu') `mlif' + qui by $HG_clus: replace `lpyz' = cond($HG_ind>0,ln(`mu'/`lpyz'[_N]),.) `mlif' + +*/ + } + else if $HG_exp==1&$HG_expf==1{ + qui gen double `mu' = exp(($HG_xb1 + `zu')/`s') `mlif' + sort $HG_clus $HG_ind + * disp "sort $HG_clus $HG_ind" + qui by $HG_clus: replace `lpyz'=cond(_n==_N,sum(`mu'),.) `mlif' + * disp "denom = " `lpyz'[$which] + qui replace `lpyz' = ln(`mu'/`lpyz') `mlif' + } + else{ + tempvar den tmp + local n=rowsof(M_respm) + local i = 2 + qui gen double `mu' = 1 if $ML_y1==M_respm[1,1] `mlif' + qui gen double `den' = 1 + qui gen double `tmp' = 0 + while `i'<= `n'{ + local prev = `i' - 1 + qui replace `tmp' = exp((${HG_xb`prev'} + `zu')/`s') `mlif' + qui replace `mu' = `tmp' if $ML_y1==M_respm[`i',1] `mlif' + replace `den' = `den' + `tmp' `mlif' + local i = `i' + 1 + } + replace `lpyz' = ln(`mu'/`den') `mlif' + } +end + +program define ordinal + version 7.0 + args lpyz zu + local no = 1 + local xbind = 2 + tempvar mu p1 p2 + qui gen double `p1' = 0 + qui gen double `p2' = 0 + qui gen double `mu' = 0 + + while `no' <= $HG_nolog{ + local olog = M_olog[1,`no'] + local lnk: word `no' of $HG_linko + + if "`lnk'"=="ologit"{ + local func logitl + } + else if "`lnk'"=="oprobit"{ + local func probitl + } + else if "`lnk'"=="ocll"{ + local func cll + } + else if "`lnk'"=="soprobit"{ + local func sprobitl + } + local and + if "$HG_lv"~=""&$HG_nolog>0{ + local and & $HG_lv == `olog' + } + * disp "ordinal link is `lnk', and = `and'" + local n=M_nresp[1,`no'] + + * disp "HG_xb1: " $HG_xb1 + * disp "xbind = " `xbind' + * disp ${HG_xb`xbind'}[$which] + + qui replace `mu' = $HG_xb1+`zu'-${HG_xb`xbind'} + `func' `mu' `p1' + qui replace `lpyz' = ln(1-`p1') /* + */ if $ML_y1==M_resp[1,`no'] `and' + qui replace `p2' = `p1' + local i = 2 + while `i' < `n'{ + local nxt = `xbind' + `i' - 1 + + * disp "nxt = " `nxt' + * disp ${HG_xb`nxt'}[$which] + + qui replace `mu' = $HG_xb1+`zu'-${HG_xb`nxt'} + `func' `mu' `p2' + + * disp "p1 and p2: " `p1'[$which] " " `p2'[$which] + + qui replace `lpyz' = ln(`p1' -`p2') /* + */ if $ML_y1==M_resp[`i',`no'] `and' + qui replace `p1' = `p2' + local i = `i' + 1 + } + local xbind = `xbind' + `n' -1 + qui replace `lpyz' = ln(`p2') /* + */ if $ML_y1==M_resp[`n',`no'] `and' + local no = `no' + 1 + } /* next ordinal response */ + *tab $ML_y1 if `lpyz'==. `and' + qui replace `lpyz' = -100 if `lpyz'==. `and' +end + +program define logitl + version 7.0 + args mu p + qui replace `p' = 1/(1+exp(-`mu')) +end + +program define cll + version 7.0 + args mu p + qui replace `p' = 1-exp(-exp(`mu')) +end + +program define probitl + version 7.0 + args mu p + qui replace `p' = normprob(`mu') +end + +program define sprobitl + version 7.0 + args mu p + qui replace `p' = normprob(`mu'/$HG_s1) +end + + +program define link + version 7.0 +* returns mu for requested link + args which mu xb zu s1 + * disp " in link, which is `which' " + + tokenize "`which'" + local i=1 + local ifs + while "`1'"~=""{ + if "$HG_lv" ~= ""{ + local oth = M_oth[1,`i'] + local ifs if $HG_lv==`oth' + } + * disp "`1' link `ifs'" + + if ("`1'" == "logit"){ + quietly replace `mu' = 1/(1+exp(-`xb'-`zu')) `ifs' + } + else if ("`1'" == "probit"){ + * disp "doing probit " + quietly replace `mu' = normprob((`xb'+`zu')) `ifs' + } + else if ("`1'" == "sprobit"){ + quietly replace `mu' = normprob((`xb'+`zu')/`s1') `ifs' + } + else if ("`1'" == "log"){ + * disp "doing log " + quietly replace `mu' = exp(`xb'+`zu') `ifs' + } + else if ("`1'" == "recip"){ + * disp "doing recip " + quietly replace `mu' = 1/(`xb'+`zu') `ifs' + } + else if ("`1'" == "cll"){ + * disp "doing cll " + quietly replace `mu' = 1 - exp(-exp(`xb'+`zu')) `ifs' + } + else if ("`1'" == "ll"){ + quietly replace `mu' = exp(-exp(`xb'+`zu')) `ifs' + } + else if ("`1'" == "ident"){ + quietly replace `mu' = `xb'+`zu' `ifs' + } + local i = `i' + 1 + mac shift + } + +end + +program define family + version 7.0 + args which lpyz mu und + + tokenize "`which'" + local i=1 + * disp "in family, und = `und'" + if "$HG_fv" == ""{ + local ifs + if "`und'"~=""{local und if `und'} + } + else{ + if "`und'"~=""{local und & `und'} + } + while "`1'"~=""{ + if "$HG_fv" ~=""{ + local ifs if $HG_fv == `i' + } + if ("`1'" == "binom"){ + famb `lpyz' `mu' "`ifs'" "`und'" + } + else if ("`1'" == "poiss"){ + famp `lpyz' `mu' "`ifs'" "`und'" + } + else if ("`1'" == "gauss") { + *disp in re "famg lpyz mu $HG_s1 `ifs' `und'" + famg `lpyz' `mu' $HG_s1 "`ifs'" "`und'" /* get log of conditional prob. */ + } + else if ("`1'" == "gamma"){ + famga `lpyz' `mu' $HG_s1 "`ifs'" "`und'" + } + else{ + disp in re "unknown family in gllam_ll" + exit 198 + } + local i = `i' + 1 + mac shift + } +end + +program define famg + version 7.0 +* returns log of normal density conditional on r.effs + args lpyz mu s1 if and + * disp "running famg `if' `and'" + * disp "s1 = " `s1'[$which] ", mu = " `mu'[$which] " and Y = " $ML_y1[$which] + quietly replace `lpyz' = /* + */ -(ln(2*_pi*`s1'^2) + (($ML_y1-`mu')/`s1')^2)/2 `if' `and' +end + +program define famb + version 7.0 +* returns log of binomial density conditional on r.effs +* $HG_denom is denominator + args lpyz mu if and + * disp "running famb `if' `and'" + * disp "mu = " `mu'[$which] " and Y = " $ML_y1[$which] + qui replace `lpyz' = cond($ML_y1>0,$ML_y1*ln(`mu'),0) /* + */ + cond($HG_denom-$ML_y1>0,($HG_denom-$ML_y1)*ln(1-`mu'),0) /* + */ + cond($HG_denom>1,lngamma($HG_denom+1)-lngamma($ML_y1+1) /* + */ - lngamma($HG_denom-$ML_y1+1),0) `if' `and' + *tab $ML_y1 `if' `and' & `lpyz'==. + qui replace `lpyz' = cond(`lpyz'==.,-100,`lpyz') `if' `and' + * disp "done famb" +end + +program define famp + version 7.0 +* returns log of poisson density conditional on r.effs + args lpyz mu if and + *!! disp "running famp `if'" + * disp in re "if and: `if' `and'" + quietly replace `lpyz' = /* + */ $ML_y1*(ln(`mu'))-`mu'-lngamma($ML_y1+1) `if' `and' + * qui replace `lpyz' = cond(`lpyz'==.,-100,`lpyz') `if' `and' + * disp "done famp" +end + +program define famga + version 7.0 +* returns log of gamma density conditional on r.effs + args lpyz mu s1 if and + *!! disp "running famg `if'" + *!! disp "mu = " `mu'[$which] + *!! disp "s1 = " `s1'[$which] + qui replace `mu' = 0.0001 if `mu' <= 0 + tempvar nu + qui gen double `nu' = `s1'^(-2) + quietly replace `lpyz' = /* + */ `nu'*(ln(`nu')-ln(`mu')) - lngamma(`nu')/* + */ + (`nu'-1)*ln($ML_y1) - `nu'*$ML_y1/`mu' `if' `and' +end + +program define timer +version 7.0 +end diff --git a/Modules/ado/plus/g/gllamm.ado b/Modules/ado/plus/g/gllamm.ado new file mode 100644 index 0000000..fbfc2b4 --- /dev/null +++ b/Modules/ado/plus/g/gllamm.ado @@ -0,0 +1,4749 @@ +*! version 2.3.20 SRH 7 Sept 2011 +program define gllamm, eclass + version 7.0 + timer on 1 + + if replay() { + if "`e(cmd)'" ~= "gllamm" { + di in red "gllamm was not the last command" + error 301 + } + Replay `0' + } + else { + Estimate `0' + } + timer off 1 +end + +program define procstr, eclass + version 6.0 + tempname bc b Vc Vr V ll esamp + noi disp "processing constraints" + + scalar `ll' = e(ll) + local df = e(df_m) + local dof + if "`df'"~="."{ + local dof "dof(`df')" + } + local k = e(k) + capture matrix `Vr' = e(Vr) + capture robclus "`e(robclus)'" + matrix `bc' = e(b) + matrix `Vc' = e(V) + local y = "`e(depvar)'" + matrix `b' = `bc'*M_T' + M_a + matrix colnames `b' = $HG_coln + matrix coleq `b' = $HG_cole + * matrix list `b' + * matrix list `Vc' + matrix `V' = M_T*`Vc'*M_T' + * disp "computed V" + * matrix list `V' + estimates post `b' `V' M_C, $HG_obs `dof' + est local ll =`ll' + est local k = `k' + est local depvar "`y'" + capture est matrix Vr `Vr' + capture est local robclus "`robclus'" + * disp "posted results" +end + +program define Replay, eclass + version 6.0 + syntax [, Level(real $S_level) EFORM ALLC ROBUST CLUSTER(varname) DOTS SCorefil(passthru) noROb noDISplay EVAL] + tempname M_nffc M_nu Vs + + if "`eval'"==""{ + if "`e(pweight)'"~="" { + local robust robust + } + if "`robust'"~=""|"`cluster'"~=""{ + if "`cluster'"~=""{ + local cluster cluster(`cluster') + } + gllarob, `cluster' `dots' `scorefil' `rob' + } + if ("`robust'"==""|"`rob'"~="")&"`cluster'"==""{ + * disp "reposting model-based standard errors" + matrix `Vs' = e(Vs) + estimates repost V =`Vs' + } + } + + if "`display'"==""{ + + local const = e(const) + local tplv = e(tplv) + matrix `M_nffc' = e(nffc) + capture matrix `M_nu' = e(nu) + * capture matrix list `M_nu' + if _rc == 0{ + disp " " + local j = 1 + while `j' <= `tplv'{ + disp in gr "number of level `j' units = " in ye `M_nu'[1,`j'] + local j = `j' + 1 + } + disp " " + } + local cn = e(cn) + if `cn'>0{ + disp in gr "Condition Number = " in ye `cn' + } + else{ + disp in gr "Condition Number could not be computed" + } + disp " " + + + * matrix list `M_nffc' + local numeq = colsof(`M_nffc') + if `M_nffc'[1,1]==0{ + local numeq = `numeq' -1 + } + if `numeq' > 1{ + local first neq(`numeq') + } + else{ + local first first + } + local primess + if `e(prior)' == 1 { + local primess "with prior " + } + if e(ll_0)==.|`M_nffc'[1,1]==0{ + local nohead "noheader" + if `const'==0{ + disp in gr "gllamm model `primess'" + } + else{ + disp in gre "gllamm model `primess'with constraints" + *matrix dispCns + } + disp " " + if `e(prior)' == 1 { + disp in gr "log posterior = " in ye e(ll) + disp in gr "log likelihood = " in ye e(a_ll) + } + else{ + disp in gr "log likelihood = " in ye e(ll) + } + } + if "`eform'"~=""{ + local eform "eform(exp(b))" + } + disp " " + if "`cluster'"~=""|("`robust'"~=""&"`rob'"==""){ + if "`cluster'"~=""{ + disp "Robust standard errors for clustered data: `cluster'" + } + else{ + disp "Robust standard errors" + } + } + + if `M_nffc'[1,1]>0|`numeq'>0 { + quietly q born + if $S_1>15502{ /* version 8 or later */ + _coef_table, level(`level') `first' `eform' + } + else{ /* older versions */ + if `const' == 0{ + noi ml display, level(`level') `nohead' `first' `eform' + } + else{ + matrix dispCns + noi estimates display, level(`level') `first' `eform' + } + } + } + else{ + disp in gr "No fixed effects" + } + noi disprand + if "`allc'"~=""{ + if `const' == 0{ + noi ml display, level(`level') `nohead' + } + else{ + noi estimates display, level(`level') + } + } + } +end + +program define Estimate, eclass + version 6.0 + syntax varlist(min=1) [if] [in] , I(string) [NRf(numlist integer min=1 >=1) /* + */ Eqs(string) GEqs(string) PEqs(string) /* + */ noCORrel noCOnstant BMATrix(string) INTER(string) FRLoad(numlist integer min=1 >=1) /* + */ Family(string) DEnom(varname numeric min=1) Link(string) EXpanded(string) /* + */ Offset(varname numeric) Basecategory(integer 999) /* + */ THresh(string) ETHresh(string) COMPosite(varlist numeric min=3) * ] + *disp in re "`opt'" + *disp in re "1: `varlist'" + local origif `"`if'"' + local origin `"`in'"' + local origvar `"`varlist'"' + local opt "`options'" + local 0 "`origvar' `origif' `origin', `opt'" + syntax varlist(min=1) [if] [in] [, /* + */ Weightf(string) LV(varname numeric min=1) FV(varname numeric min=1) S(string) /* + */ NATS IP(string) NIp(numlist integer min=1 >=1) ADapt Constraints(numlist) /* + */ FRom(string) LONG Gateaux(passthru) LF0(passthru) SEarch(passthru) /* + */ ROBust CLuster(varname) PWeight(string) ITerate(passthru)/* + */ DOts noLOg TRace noDISplay noESt EVal Level(real $S_level) INit noDIFficult /* + */ EFORM ALLC ADOONLY SKIP COPY PRior(passthru) ] /* does not allow extra options! */ + *disp in re "2: `varlist'" + *disp in re "i: `i'" + *disp in re "frload: `frload'" + *disp in re "display: `display'" + *disp in re "iterate: `iterate'" + + tempname mat mnip mnbrf + global HG_error=0 + +/* deal with adoonly */ + + global HG_noC = 0 + global HG_noC1 = 0 + global HG_noC2 = 0 + if "`adoonly'"=="" { + qui q born + if $S_1 < 16350 { + global HG_noC2 = 1 + if $S_1 < 15722 { + noi di + noi di in gr "You must have the Stata 8 executable updated on or after " _c + noi di in ye %d 15722 + noi di in gr "in order to use all internal routines" + global HG_noC1 = 1 + if $S_1 < 15274 { + global HG_noC = 1 + noi di in gr "Option adoonly assumed." + noi di + } + } + } + } + + if "`adoonly'"!="" { + global HG_noC = 1 /* link and family */ + global HG_noC1 = 1 /* lnupdate */ + global HG_noC2 = 1 /* don't want to set HG_noC to 0 */ + } + + +/* deal with trace */ + + if "`trace'"!="" { local noi "noisily" } + +/* deal with dots */ + + global HG_dots = 0 + if "`dots'"!="" { + global HG_dots = 1 + } + +/* deal with init */ + + global HG_init=0 + if "`init'"~="" { + global HG_init=1 + } + +/* deal with if and in */ + marksample touse + + qui count if `touse' + if _result(1) <= 1 { + di in red "insufficient observations" + exit 2001 + } + + /* deal with varlist */ + tokenize `varlist' + local y "`1'" + + macro shift /* `*' is list of dependent variables */ + local indep "`*'" + + local num: word count `indep' /* number of independent variables */ + + markout `touse' `y' `indep' + +/* deal with Link and Family */ + global HG_lev1=0 + global HG_famil + global HG_linko + global HG_link + matrix M_olog=(0) + capture matrix drop M_oth + global HG_mlog=0 + global HG_nolog = 0 + global HG_lv + global HG_fv + global HG_smlog=0 + global HG_oth = 0 + local l: word count `family' + if `l'>1 { + `noi' qui disp "more than one family" + if "`fv'"==""{ + disp in re "need fv option" + exit 198 + } + else{ + confirm variable `fv' + global HG_fv `fv' + } + parse "`family'", parse(" ") + local n=1 + while "`1'"~=""{ + qui count if `fv'==`n' + if _result(1)==0{ + disp "family `1' not used" + } + fm "`1'" + if "$S_2"=="gauss"{ + if $HG_lev1==0{ + global HG_lev1=1 + } + else if $HG_lev1==2{ + global HG_lev1=3 + } + } + else if "$S_2"=="gamma"{ + if $HG_lev1==0{ + global HG_lev1=2 + } + else if $HG_lev1==1{ + global HG_lev1=3 + } + } + global HG_famil "$HG_famil $S_2" + local n = `n'+1 + mac shift + } + + } + + local k: word count `link' + local mll = 0 + if `k'>1{ + `noi' qui disp "more than one link" + if "`lv'"==""{ + disp in re "need lv option" + exit 198 + } + else{ + confirm variable `lv' + global HG_lv `lv' + } + parse "`link'", parse(" ") + local n=1 + while "`1'"~=""{ + qui count if $HG_lv==`n' + if _result(1)==0{ + disp "link `1' not used" + } + lnk "`1'" + if "$S_1"=="sprobit"|"$S_1"=="soprobit"{ + if $HG_lev1 == 2{ + global HG_lev1 = 3 + } + else{ + global HG_lev1 = 1 + } + } + if "$S_1"=="ll"{ + global HG_noC = $HG_noC2 + } +/* nominal */ + if "$S_1"=="mlogit"|"$S_1"=="smlogit"{ + if $HG_mlog>0{ + disp in re "can only have one mlogit link" + exit 198 + } + global HG_mlog=`n' + if "$S_1"=="smlogit"{ + if $HG_lev1 == 2{ + global HG_lev1 = 3 + } + else{ + global HG_lev1 = 1 + } + } + tempvar first + sort `touse' $HG_lv `y' + qui by `touse' $HG_lv `y': gen byte `first' = cond(_n==1,1,0) + mkmat `y' if `first' == 1 & `touse' & $HG_lv == `n', mat(M_respm) + if "$S_1"=="smlogit"{global HG_smlog=1} + } +/* ordinal */ + else if "$S_1"=="ologit"|"$S_1"=="oprobit"|"$S_1"=="ocll"|"$S_1"=="soprobit"{ + global HG_linko "$HG_linko $S_1" + if $HG_nolog>0{ + * disp "more than one ordinal response" + matrix M_olog = M_olog,`n' + } + else{ + capture matrix drop M_nresp + matrix M_olog[1,1] = `n' + tempvar first + sort `touse' $HG_lv `y' + qui by `touse' $HG_lv `y': gen byte `first' = cond(_n==1,1,0) + } + mkmat `y' if `first' == 1 & `touse' & $HG_lv == `n', mat(`mat') + local ll = rowsof(`mat') + * matrix list `mat' + * disp "adding `ll' to M_nresp" + matrix M_nresp = nullmat(M_nresp),`ll' + if `ll'>`mll'{ + local mll = `ll' + } + global HG_nolog = $HG_nolog + 1 + } +/* other */ + else { + global HG_link "$HG_link $S_1" + matrix M_oth = nullmat(M_oth),`n' + global HG_oth=1 + } + local n = `n'+1 + mac shift + } + if $HG_nolog>0{ + tempname junk + global HG_lvolo "`junk'" + qui gen byte $HG_lvolo = 0 + matrix M_resp = J(`mll',$HG_nolog,0) + local no = 1 + local totresp = 0 + while `no'<=$HG_nolog{ + local olog = M_olog[1,`no'] + qui replace $HG_lvolo = 1 if $HG_lv == `olog' + mkmat `y' if `first' == 1 & `touse' & $HG_lv == `olog', mat(`mat') + local ii = 1 + while `ii'<= M_nresp[1,`no']{ + * disp "M_resp[`ii',`no'] = mat[`ii',1]" + matrix M_resp[`ii',`no'] = `mat'[`ii',1] + local ii = `ii' + 1 + } + local totresp = `totresp' + M_nresp[1,`no'] + local no = `no' + 1 + } + } + if $HG_mlog>0{ + if $HG_nolog==0{ + tempname junk + global HG_lvolo "`junk'" + qui gen byte $HG_lvolo = 0 + } + qui replace $HG_lvolo = 1 if $HG_lv == $HG_mlog + } + } + else if `k'<=1&`l'<=1{ /* no more than one link and one family given */ + lnkfm "`link'" "`family'" + global HG_link = "$S_1" + global HG_famil = "$S_2" + if "$HG_link"=="ologit"|"$HG_link"=="oprobit"|"$HG_link"=="ocll"|"$HG_link"=="soprobit"{ + global HG_linko = "$HG_link" + global HG_nolog = 1 + matrix M_olog[1,1] = 1 + } + if "$HG_link"=="smlogit"|"$HG_link"=="mlogit"{global HG_mlog=1} + if "$HG_famil"=="gauss"{global HG_lev1=1} + if "$HG_famil"=="gamma"{global HG_lev1=2} + if "$HG_link"=="sprobit"{global HG_lev1=1} + if "$HG_link"=="soprobit"{global HG_lev1=1} + if "$HG_link"=="smlogit"{global HG_lev1=1} + if "$HG_link"=="ll"{global HG_noC = $HG_noC2 } + if $HG_mlog==0&$HG_nolog==0{global HG_oth = 1} + } + else if `k'==1{ + lnk "`lnk'" + global HG_link = "$S_1" + if "$HG_link"=="ologit"|"$HG_link"=="oprobit"|"$HG_link"=="ocll"|"$HG_link"=="soprobit"{ + global HG_nolog = 1 + matrix M_olog[1,1] = 1 + global HG_linko = "$HG_link" + } + if "$HG_link"=="smlogit"|"$HG_link"=="mlogit"{global HG_mlog=1} + if "$HG_link"=="sprobit"{global HG_lev1=1} + if "$HG_link"=="smlogit"{global HG_lev1=1} + if "$HG_link"=="soprobit"{global HG_lev1=1} + if "$HG_link"=="ll"{global HG_noC = $HG_noC2 } + if $HG_mlog==0&$HG_nolog==0{global HG_oth = 1} + } + if `l'==1{ + fm "`family'" + global HG_famil = "$S_2" + if "$HG_famil"=="gauss"{global HG_lev1=1} + if "$HG_famil"=="gamma"{global HG_lev1=2} + if $HG_mlog==0&$HG_nolog==0{global HG_oth = 1} + } + if ((`k'>1&`l'==0)|(`l'>1&`k'==0))&$HG_oth==1{ + disp in re /* + */ "both link() and fam() required for multiple links or families" + exit 198 + } + + markout `touse' $HG_lv $HG_fv + + +/* deal with noCORrel */ + global HG_cor = 1 + if "`correl'"~=""{ + global HG_cor = 0 + } + +/* deal with DEnom */ + global HG_denom + local f=0 + parse "$HG_famil", parse(" ") + while "`1'"~=""&`f'==0{ + if "`1'"=="binom"{ + local f=1 + } + mac shift + } + if `f'==1{ + if "`denom'"~=""{ + confirm variable `denom' + global HG_denom "`denom'" + } + else{ + tempvar den + quietly gen byte `den'=1 + global HG_denom "`den'" + } + } + else{ + if "`denom'"~=""{ + disp in blue/* + */"option denom(`denom') given but binomial family not used" + } + } + + markout `touse' `denom' + +/* deal with offset */ + global HG_off + if "`offset'"~=""{ + global HG_off "`offset'" + local offset "offset(`offset')" + } + + markout `touse' $HG_off + +/* deal with ip */ + global HG_gauss = 1 + global HG_free = 0 + global HG_cip = 1 + global HG_mult = 0 + if "`ip'"~=""{ + if "`ip'"=="g"{ + global HG_gauss = 1 + } + else if "`ip'"=="l"{ + global HG_gauss = 0 + } + else if "`ip'"=="f"{ + global HG_free = 1 + } + else if "`ip'"=="m"{ + global HG_mult = 1 + global HG_gauss = 0 + } + else if "`ip'"=="fn"{ + global HG_free = 1 + global HG_cip = 0 + } + else { + disp in re "ip option `ip' not valid" + exit 198 + } + } + + global HG_lzpr lzprobg + global HG_zip zipg + + * disp in re "HG_mult = " $HG_mult + if $HG_mult{ + global HG_lzpr lzprobm + } + else if $HG_free{ + global HG_lzpr lzprobf + global HG_zip zipf + } + + +/* deal with expanded */ + global HG_ind + global HG_exp = 0 + global HG_expf = 0 + if "`expanded'"~=""{ + global HG_exp = 1 + if $HG_mlog==0{ + disp in re "expanded option only valid with mlogit link" + exit 198 + } + local k: word count `expanded' + if `k'~=3{ + disp in re "expanded option must have three arguments" + } + local exp: word 1 of `expanded' + confirm variable `exp' + global HG_mlg `exp' + local k: word 2 of `expanded' + * 11/11/06 + confirm variable `k' + global HG_ind `k' + local k: word 3 of `expanded' + if "`k'"=="o"{ + global HG_expf=1 + } + else{ + if "$HG_link"~="mlogit"&"$HG_link"~="smlogit"{ + disp in re "must use o in expanded option when combining mlogit with other links" + exit 198 + } + } + * 11/11/06 + markout `touse' $HG_mlg $HG_ind + } + else{ + if $HG_mlog>0&"$HG_link"~="mlogit"&"$HG_link"~="smlogit"{ + disp in re "must use expanded option when combining mlogit with other links" + exit 198 + } + tempvar ind + gen byte `ind' = 1 + global HG_ind `ind' + global HG_exp = 0 + } + + +/* deal with composite */ + global HG_comp = 0 + global HG_coall + if "`composite'"~=""{ + local k: word count `composite' + global HG_comp = `k' - 2 + local k: word 1 of `composite' + global HG_mlg `k' + local k: word 2 of `composite' + global HG_ind `k' + local kk = 1 + while `kk'<= $HG_comp { + local jj = `kk' + 2 + local k: word `jj' of `composite' + global HG_co`kk' `k' + global HG_coall $HG_coall `k' + local kk = `kk' + 1 + } + global HG_noC = $HG_noC2 /* use ado-code for link if not latest Stata 8 */ + } + + + +/* deal with I (turn list around)*/ + if ("`i'"==""){ + disp in red "i() required" + global HG_error=1 + exit 198 + + } + + local tplv: word count `i' + global HG_tplv = `tplv'+1 + global HG_clus + local k = `tplv' + while `k'>=1{ + local clus: word `k' of `i' + confirm numeric variable `clus' + markout `touse' `clus', strok + local k=`k'-1 + global HG_clus "$HG_clus `clus'" + } + + + if "`expanded'"==""&"`composite'"==""{ + tempvar id + gen long `id'=_n + global HG_clus "$HG_clus `id'" + } + else{ + global HG_clus "$HG_clus $HG_mlg" + } + +/* deal with weightf */ + tempvar wt + quietly gen double `wt'=1 + local j = 1 + if "`weightf'"==""{ + while (`j'<=$HG_tplv){ + tempname junk + global HG_wt`j' "`junk'" + gen double ${HG_wt`j'}=1 + local j = `j' + 1 + } + global HG_weigh + } + else{ + global HG_weigh "`weightf'" + local wtvars + local found = 0 + while (`j'<=$HG_tplv){ + capture confirm variable `weightf'`j' /* frequency weight */ + if _rc ~= 0 { + tempname junk + global HG_wt`j' "`junk'" + gen double ${HG_wt`j'} = 1 /* can become non-integeger later */ + } + else{ + tempname junk + global HG_wt`j' "`junk'" + gen double ${HG_wt`j'}=`weightf'`j' + local wtvars `wtvars' `weightf'`j' + quietly replace `wt'=`wt'*${HG_wt`j'} + local found = `found' + 1 + } + local j = `j' + 1 + } + if `found' == 0 { + disp in red "weight variables `weightf' not found" + global HG_error=1 + exit 111 + } + markout `touse' `wtvars' + } + +/* deal with probability weights */ + local pw + local wtvars + if "`pweight'"~=""{ + local robust robust + tempname wtp + local pw pweight + global HG_pwt "`pweight'" + quietly gen double `wtp' = 1 + local j = 1 + local found = 0 + while (`j'<=$HG_tplv){ + capture confirm variable `pweight'`j' /* probability weight */ + if _rc == 0 { + quietly replace `wtp'=`wtp'*`pweight'`j' + local wtvars `wtvars' `pweight'`j' + local found = `found' + 1 + } + local j = `j' + 1 + } + if `found' == 0 { + disp in red "probability weight variables not found" + global HG_error=1 + exit 111 + } + markout `touse' `wtvars' + } + +/* deal with cluster */ + + if "`cluster'"~=""{ +* check that top-level cluster does not vary within cluster? + local k: word count $HG_clus + local top: word 1 of $HG_clus + qui sort `top' `cluster' + capture qui by `top' : assert `cluster'[1]==`cluster'[_N] + if _rc>0{ + disp in re "`cluster' varies within `top'" + exit 198 + } + markout `touse' `cluster' + local cluster cluster(`cluster') + } + +/* deal with categorical response variables */ + + if "$HG_link" == "mlogit"|"$HG_link" == "smlogit"{ + sort `touse' `y' + tempvar first + qui by `touse' `y': gen byte `first' = cond(_n==1,1,0) + mkmat `y' if `first' == 1 & `touse', mat(M_respm) + } + else if /* + */ "$HG_link" == "ologit"|"$HG_link" == "ocll"|"$HG_link" == "oprobit"|"$HG_link"=="soprobit"{ + sort `touse' `y' + tempvar first + qui by `touse' `y': gen byte `first' = cond(_n==1,1,0) + mkmat `y' if `first' == 1 & `touse', mat(M_resp) + local totresp = rowsof(M_resp) + matrix M_nresp = (`totresp') + } + +/* deal with base-category */ + + if `basecategory'~=999{ + if "$HG_link" ~= "mlogit"&"$HG_link" ~= "smlogit"{ + disp in red "basecategory ignored because response not nominal" + } + } + if $HG_mlog>0&$HG_expf==0{ + tempname bas + if `basecategory'==999{ + scalar `bas' = M_respm[1,1] + matrix `bas' = (`bas') + local basecat = M_respm[1,1] + * disp in re "`basecat'" + } + else{ + matrix `bas' = (`basecategory') + local basecat = `basecategory' + } + + local n = rowsof(M_respm) + local j = 1 + local found = 0 + while `j'<=`n'{ + local el = M_respm[`j',1] + if `el'==`basecat'{ + local found = 1 + } + else{ + matrix `bas' = `bas'\ `el' + } + local j = `j' + 1 + } + if `found' == 0 { + disp in re "basecategory = `basecat' not one of the categories" + exit 198 + } + matrix M_respm = `bas' + local el = M_respm[1,1] + local basecat basecat(`el') + } + + +/* deal with noCOns */ + + if "`constant'"~=""{ + if $HG_nolog>0{ + disp in re "noconstant option not allowed for ordinal links:" _n "This is the default because all thresholds estimated" + exit 198 + } + local cns + } + else{ + if $HG_cip == 0{ + disp in re "are you sure you need a constant with ip(fn) option?" + } + + local num=`num'+1 + local cns "_cons" + } + matrix M_nffc=(`num') + + + if `num'>0 { + global HG_fixe (`y': `y'=`indep', `constant') + local dep + } + else{ + global HG_fixe + local dep "`y'=" + } + +/* fixed effects matrix */ + + global HG_ethr = 0 + + if `num' > 0 { + matrix M_initf=J(1,`num',0) + matrix coleq M_initf=`y' + matrix colnames M_initf=`indep' `cns' + } + else{ + cap matrix drop M_initf + } + + if $HG_nolog==0{ + if "`thresh'"~=""{ disp in re "thresh option ignored" } + if "`ethresh'"~=""{ disp in re "ethresh option ignored" } + } + else if $HG_nolog>0{ + + if "`ethresh'"~=""{ + if "`thresh'"~=""{ + disp in re "cannot use both ethresh() and thresh() options! + exit 198 + } + global HG_ethr = 1 + local thresh `ethresh' + + } + if "`thresh'"~=""{ + local k: word count `thresh' + if `k'~=$HG_nolog{ + disp in re "number of threshold equations should be " $HG_nolog + exit 198 + } + + } + global HG_fixe + local n = rowsof(M_resp) + matrix M_nffc[1,1] = `num'-1 + if `num'>1{ + global HG_fixe (`y': `y'=`indep', nocons) + matrix `mat' = M_initf[1,1..`num'-1] + local ce: coleq(`mat') + local cn `indep' + matrix M_initf=J(1,`num'-1,0) + } + else{ + capture matrix drop M_initf + } + local el = M_nffc[1,1] + local ii = 1 + local nxt = M_nffc[1,1] + 1 + local ntr = 1 + local vars + local rhs "_cons" + while `ii'<= $HG_nolog{ + local j = 1 + if "`thresh'"~=""{ + local eqnam: word `ii' of `thresh' + eq ? "`eqnam'" + local vars "$S_1" + markout `touse' `vars' + local ntr: word count `vars' + local ntr = `ntr' + 1 + local rhs "`vars' _cons" + } + while `j'< M_nresp[1,`ii']{ + * disp "`ii'th ordinal response, level `j'" + local el = `el' + `ntr' + matrix M_nffc = M_nffc, `el' + matrix `mat'=J(1,`ntr',0) + matrix coleq `mat' = _cut`ii'`j' + local cee: coleq(`mat') + local ce `ce' `cee' + local cn `cn' `rhs' + global HG_fixe $HG_fixe (_cut`ii'`j':`vars') + if `j' == 1 & `ii'==1 & `num' == 1{ + global HG_fixe (_cut`ii'`j':`y'= `vars') + } + local j = `j' + 1 + if $HG_ethr{ + matrix `mat'[1,`ntr'] = - 0.5 + } + else{ + matrix `mat'[1,`ntr'] = `j' - (M_nresp[1,`ii']+1)/2 + } + matrix M_initf = nullmat(M_initf), `mat' + local nxt = `nxt' + 1 + } + local ii = `ii' + 1 + } + matrix colnames M_initf=`cn' + matrix coleq M_initf=`ce' + * matrix list M_initf + } + + if ($HG_mlog>0)&$HG_expf==0{ + global HG_fixe + local n = rowsof(M_respm) + matrix `bas'=M_initf + matrix drop M_initf + matrix drop M_nffc + local j = 2 + while `j'<=`n'{ + local el = M_respm[`j',1] + matrix coleq `bas' = c`el' + matrix M_initf = nullmat(M_initf), `bas' + matrix M_nffc = nullmat(M_nffc), (`j'-1)*`num' + if `j' == 2{ + global HG_fixe $HG_fixe ( c`el':`y' = `indep', `constant') + } + else{ + global HG_fixe $HG_fixe ( c`el':`indep', `constant') + } + local j = `j' + 1 + } + local num = `num'*(`n' - 1) + } + + * matrix list M_nffc + * matrix list M_initf + + +/* display information */ + quietly `noi'{ + disp " " + disp in gr "General model information" + *disp in smcl in gr "{hline 78}" _n + di in gr _dup(78) "-" _n + disp in gr "dependent variable:" in ye " `y'" + if $HG_oth{ + disp in gr "family:" in ye " $HG_famil" + disp in gr "link:" in ye " $HG_link" + } + if "$HG_linko"~=""{ + disp in gr "ordinal responses:" in ye " $HG_linko" + } + if $HG_mlog>0{ + if $HG_smlog==1 { + disp in gr "nominal responses:" in ye " smlogit" + } + else{ + disp in gr "nominal responses:" in ye " mlogit" + } + } + if "$HG_denom"~=""{ + if "`denom'"~=""{ + disp in gr "denominator:" in ye " `denom'" + } + else{ + disp in gr "denominator:" in ye " 1" + } + } + if "`offset'"~=""{ + disp in gr "offset:" in ye " $HG_off" + } + local m = colsof(M_nffc) + if `m'==1&M_nffc[1,1]>0{ + local cuts: colnames(M_initf) + disp in gr "equation for fixed effects " in ye " `cuts'" + } + else if `m'==1{ + disp in gr "equation for fixed effects " in ye " none" + } + else{ + disp in gr "equations for fixed effects" + local j = 1 + local nxt = 1 + local prev = 0 + while `j'<=`m'{ + local n = M_nffc[1,`j'] - `prev' + if `n'>0{ + local prev = M_nffc[1,`j'] + matrix `mat' = M_initf[1,`nxt'..`nxt'+`n'-1] + local nxt = `nxt' + `n' + local ce: coleq(`mat') + local ce: word 1 of `ce' + local cn: colnames(`mat') + disp in gr " `ce': " in ye " `cn'" + } + local j = `j' + 1 + } + disp " " + } + } /* end qui `noi' */ + + +/* deal with inter */ + + global HG_inter = 0 + if "`inter'"~=""{ + global HG_inter=1 + local j: word count `inter' + if `j'~=2{ + disp in red "inter should have two arguments" + exit 198 + } + local j: word 1 of `inter' + capture confirm number `j' + if _rc>0{ + disp in red "arguments of inter must be numbers" + exit 198 + } + global HG_l = `j' + local j: word 2 of `inter' + capture confirm number `j' + if _rc>0{ + disp in red "arguments of inter must be numbers" + exit 198 + } + global HG_r = `j' + } + +/* initialise macros */ + quietly `noi' initmacs "`nrf'" "`nip'" "`eqs'" "`geqs'" "`peqs'" "`s'" "`nats'" "`bmatrix'" "`touse'" "`dep'" "`frload'" + qui count if `touse' + if _result(1) <= 1 { + di in red "insufficient observations" + exit 2001 + } + +/* deal with noESt */ + if "`est'"~=""{ + exit 0 + } +/* only use observations satisfying if and in and having nonmissing values */ + preserve + quietly keep if `touse' + +/* work out number of units at each level */ + + qui summ `wt' if `touse', meanonly + local lobs = r(sum) + tempvar cw f + qui gen double `cw' = `wt' + qui gen byte `f' = 1 + matrix M_nu=J(1,$HG_tplv,0) + matrix M_nu[1,1]=`lobs' + local sortlst $HG_clus + local j = 1 + local k = $HG_tplv + quietly `noi' disp in gr "number of level 1 units = " in ye `lobs' + while `j'<$HG_tplv{ + *disp "sort `sortlst'" + sort `sortlst' + tokenize "`sortlst'" + local `k' " " + local sortlst "`*'" + *disp "replace cw = cw/wt`j'" + qui replace `cw' = `cw'/${HG_wt`j'} + *disp "by `sortlst': replace f=_n==1" + qui by `sortlst': replace `f' = _n==1 + qui summ `cw' if `f' ==1, meanonly + local lobs = r(sum) + quietly `noi' disp in gr "number of level " `j'+1 " units = " in ye `lobs' + matrix M_nu[1,`j'+1] = `lobs' + local j = `j' + 1 + local k = `k' - 1 + } + +/* use pweights */ + + if "`pw'"~=""{ + local j = 1 + while (`j'<=$HG_tplv){ + capture confirm variable `pweight'`j' /* probability weight */ + if _rc == 0 { + quietly replace ${HG_wt`j'}=${HG_wt`j'}*`pweight'`j' + } + local j = `j' + 1 + } + } + +/* check if weights are integer */ + + qui cap summ `y' if `touse' [fweight=`wt'], meanonly + if _rc>0 { + global HG_obs + local ftype pweight + disp in re "weights are non-integer" + } + else { + local lobs = M_nu[1,1] + global HG_obs obs(`lobs') + local ftype fweight + } + if "`pweight'"~=""{ + quietly replace `wt' = `wt'*`wtp' + local ftype pweight + + } + + +/* deal with from */ + if "`from'"~=""{ + capture qui matrix list `from' /* do not comment out this line! */ + local rc=_rc + if `rc'>1{ + disp in red "`from' not a matrix" + exit 111 + } + tempname amat + matrix `amat' = `from' + local from "`amat'" + } + +/* deal with eval */ + if "`eval'"~=""{ + if "`from'"==""{ + disp in re "eval not valid without from option" + exit 198 + } + } + +/* deal with constraints (and from long) */ + + global HG_const = 0 + if "`constra'"~=""{ + global HG_const = 1 + if $HG_init==0{ + tempname b V + matrix `b' = nullmat(M_initf), nullmat(M_initr) + * noi matrix list `b' + if "`from'"~=""& "`long'"~=""{ + local nb = colsof(`b') + local nf = colsof("`from'") + * disp "nb = " `nb' + * disp "nf = " `nf' + if "`gateaux'"~=""{ + local tprf=M_nrfc[2,$HG_tplv]-M_nrfc[2,$HG_tplv-1] + local nnf = `nf' + `tprf' + 1 + if `nnf'~=`nb'{ + disp in re "from matrix has `nf' columns and should have " `nb'-`tprf'-1 + exit 198 + } + matrix `from' = `from',`b'[1,`nf'+1...] +** +* local lfix = `M_nffc'[1,colsof(`M_nffc')] +* matrix `from' = `from'[1,1..`lfix'],`b'[1,`nf'+1..`nf'+`tprf'+1],`from'[1,`lfix'+1...] +* noi matrix list `from' + } + else{ + capture ml model d0 gllam_ll $HG_fixe $HG_eqs, /* + */ noscvars waldtest(0) nopreserve missing collinear + + * disp "ml init from, `skip' `copy'" + ml init `from', `skip' `copy' + matrix `from' = ML_b + } + matrix `b' = `from' + * matrix list `b' + } + global HG_coln: colnames(`b') + global HG_cole: coleq(`b') + * matrix list `b' + matrix `V' = `b''*`b' + estimates post `b' `V' + matrix `b' = e(b) + matrix makeCns `constra' + qui `noi' disp in gr "Constraints:" + qui `noi' matrix dispCns + qui `noi' disp " " + matcproc M_T M_a M_C + matrix M_inshrt = `b'*M_T + local n = colsof(M_inshrt) + qui `noi' disp "estimating `n' parameters" + local i = 1 + local lst "`y'" + gen byte __0066 = 1 + while `i'< `n'{ + local lst `lst' "eq`i'" + local i = `i' + 1 + } + global HG_eqs + matrix coleq M_inshrt = `lst' + matrix colnames M_inshrt = __0066 + + *matrix list M_inshrt + *matrix `b' = M_inshrt*M_T' + M_a + *matrix list `b' + if "`gateaux'"~=""{ + local nf = `nf' - (`nb' - `n') + matrix `from' = M_inshrt[1,1..`nf'] + } + else if "`from'"~=""&"`long'"~=""{ + matrix `from' = M_inshrt + } + } + } + + if "`from'"~=""{ + local from "from(`from')" + } + +/* deal with prior */ + + global HP_prior = 0 + + if "`prior'"!=""{ + if "`noi'"!=""{ local loud "loud" } + *disp in re "prior loud is `prior' `loud'" + init_prior, `prior' `loud' + global HP_sprd = 0 + } + + * disp in re "HP_prior: " $HP_prior + +/* deal with adapt */ + global HG_adapt=0 + if "`adapt'"~=""{ + if $HG_free==1|($HG_gauss==0&$HG_mult==0){ + disp in re "adapt can only be used with ip(g) or ip(m) option" + exit 198 + } + global HG_adapt = 1 + } + + /* Nothing to estimate if init option and no fixed effects or level-1 variance */ + if $HG_init==1&M_nffc[1,$HG_tpff]==0&$HG_lev1==0{ + disp in re "Nothing to estimate" + exit 498 + } + + local fit = 0 + if (M_nffc[1,$HG_tpff]>0|$HG_lev1>0)&$HG_init==0&"`from'"==""&$HG_comp==0{ +/* initial values for fixed effects using Stata's commands */ + local lnk $HG_link + if "$HG_link"=="recip"{ + local lnk pow -1 + } + qui `noi' disp " " + qui `noi' disp in gr "Initial values for fixed effects" + if $HG_const&$HG_init==0 { + qui `noi' disp in gr "(Not applying constraints at this point)" + } + qui `noi' disp " " + if ("$HG_famil"=="gauss")&("$HG_link"=="ident")& "`s'"==""{ + tempvar yn + if "`offset'"~=""{ + quietly gen double `yn' = `y' - $HG_off + } + else{ + gen `yn' = `y' + } + quietly `noi' reg `yn' `indep' [`ftype'=`wt'], `constant' + matrix M_initr[1,1]=ln(_result(9)) + local fit = 1 + qui drop `yn' + } + else if ($HG_nolog+$HG_oth+$HG_mlog==1)&("$HG_famil"=="binom"|$HG_nolog==1|/* + */ $HG_mlog==1)&$HG_exp==0{ + local fit = 1 + local mnd = 1 + if "$HG_denom"~=""{ + qui summ $HG_denom, meanonly + local mnd = r(mean) + } + if `mnd'>1 { + if $HG_mlog>0 { + disp in re "can't have denominator > 1 for mlogit" + exit 198 + } + if ($HG_nolog>0) { + disp in re "can't have denominator > 1 for ordinal response" + exit 198 + } + qui `noi' glm `y' `indep' [`ftype'=`wt'], link(`lnk') /* + */ fam(binom `denom') `constant' `offset' `log' + } + else{ + if "$HG_link"=="logit"{ + qui `noi' logit `y' `indep' [`ftype'=`wt'], `constant' `offset' `log' + } + else if "$HG_link"=="probit"{ + qui `noi' probit `y' `indep' [`ftype'=`wt'], `constant' `offset' `log' + } + else if "$HG_link"=="cll"{ + qui `noi' cloglog `y' `indep' [`ftype'=`wt'], `constant' `offset' `log' + } + else if "$HG_link"=="ll"{ + tempvar yn + qui gen `yn' = 1-`y' + qui `noi' cloglog `yn' `indep' [`ftype'=`wt'], `constant' `offset' `log' + } + else if $HG_mlog==1{ + qui `noi' mlogit `y' `indep' [`ftype'=`wt'] if $HG_ind==1, `constant' `basecat' `log' + } + else if "$HG_linko"=="ologit"&"`thresh'"==""{ + qui `noi' ologit `y' `indep' [`ftype'=`wt'], `offset' `log' + } + else if "$HG_linko"=="oprobit"&"`thresh'"==""{ + qui `noi' oprobit `y' `indep' [`ftype'=`wt'], `offset' `log' + } + else if "$HG_linko"=="ocll"|"$HG_link"=="sprobit"|"$HG_linko"=="soprobit"|$HG_nolog>1|"`thresh'"~=""{ + local fit = 0 + } + else{ + qui `noi' glm `y' `indep' [`ftype'=`wt'], link(`lnk') /* + */ fam(binom `denom') `constant' `offset' `log' + local fit = 1 + } + + } + } + else if ("$HG_famil"=="poiss")&("$HG_link"=="log"){ + qui `noi' poisson `y' `indep' [`ftype'=`wt'], `constant' `offset' `log' + local fit = 1 + } + else if ("$HG_famil"=="gamma"& M_nbrf[1,1]==1){ + qui `noi' glm `y' `indep' [`ftype'=`wt'], link(`lnk')/* + */ fam(gamma) `constant' `offset' `log' + matrix M_initr[1,1]= -ln($S_E_dc) + local fit = 1 + } + } + if `fit' == 0 &("`from'"==""|$HG_init==1)& (M_nffc[1,$HG_tpff]>0|$HG_lev1>0) { +/* fit level 1 model using gllamm */ + /* preserve macros */ + qui `noi' disp in green "(using gllamm for inital values)" + local eqs "$HG_eqs" + local tprf = $HG_tprf + local tplv = $HG_tplv + local tpi = $HG_tpi + local const = $HG_const + local link $HG_link + local linko $HG_linko + local lev1 = $HG_lev1 + local ngeqs = $HG_ngeqs + local sprior = $HP_prior + tempvar keep + quietly gen int `keep' = $HG_wt1 + quietly replace $HG_wt1 = `wt' + matrix `mnip' = M_nip + matrix `mnbrf' = M_nbrf + local adapt = $HG_adapt + + + /* change global macros */ + local frm + if $HG_init==0{ + global HG_const = 0 + } + global HG_ngeqs = 0 + + if $HG_init==0{ + /* scale of probit usually not identified without random effects */ + global HG_link + local k: word count `link' + local kk = 1 + while `kk' <= `k'{ + local ll: word `kk' of `link' + + if "`ll'" == "sprobit"{ + global HG_link "$HG_link probit" + } + else{ + global HG_link $HG_link `ll' + } + local kk = `kk' + 1 + } + *disp in re "links were `link' and are $HG_link" + + + global HG_linko + local k: word count `linko' + local kk = 1 + while `kk' <= `k'{ + local ll: word `kk' of `linko' + + if "`ll'" == "soprobit"{ + global HG_linko "$HG_linko oprobit" + } + else{ + global HG_linko "$HG_linko `ll'" + } + local kk = `kk' + 1 + } + *disp in re "ordinal links were `linko' and are $HG_linko" + + if $HG_lev1>0{ /* check if any of the families is the normal or gamma*/ + local found = 0 + local k: word count $HG_famil + local kk = 1 + while `kk'<= `k'{ + local ll: word `kk' of $HG_famil + if "`ll'"=="gauss"| "`ll'"=="gamma"{ + local found = 1 + } + local kk = `kk' + 1 + } + if `found'==0{ + global HG_lev1 = 0 + matrix M_nbrf = (0) + } + } + } + + matrix M_nip=(1,1\1,1) + if $HG_lev1>0{ + global HG_eqs $HG_s1 + global HG_tprf=1 + global HG_tpi=1 + global HP_prior=0 + } + else{ + global HG_eqs + global HG_tprf=0 + global HG_tpi=1 + } + if "`from'"~=""{ + local frm `from' + } + + global HG_adapt = 0 + + /* fit model for initial values */ + global HG_tplv=1 /* Level 1 model */ + local opt + if $HG_init{ /* apply constraints if init option is used */ + if $HG_const==1{ + tempname b V + matrix `b' = M_initf, M_initr + + capture ml model d0 gllam_ll $HG_fixe $HG_eqs, /* + */ noscvars waldtest(0) nopreserve missing collinear + + *matrix list `b' + ml init `b', skip /* uses parameters needed for model above */ + matrix `b' = ML_b /* unconstrained param., no random effects */ + + global HG_coln: colnames(`b') + global HG_cole: coleq(`b') + + if "`from'"~=""& "`long'"~=""{ /* assumes copy option */ + local nb = colsof(`b') + local nf = colsof(`amat') + if `nb'~=`nf'{ + disp in re "from matrix must be dimension " `nb' + exit 189 + } + disp in gr "(copy option assumed for from matrix)" + matrix `b' = `amat' + matrix coleq `b' = $HG_cole + matrix coln `b' = $HG_coln + } + + matrix `V' = `b''*`b' + estimates post `b' `V' + matrix `b' = e(b) + matrix makeCns `constra' + qui `noi' disp in gr "Constraints:" + qui `noi' matrix dispCns + qui `noi' disp " " + matcproc M_T M_a M_C + matrix M_inshrt = `b'*M_T /* constrained parameters, no r. effects */ + local n = colsof(M_inshrt) + qui `noi' disp "estimating `n' parameters" + if "`from'"~=""&"`long'"==""{ + local nf = colsof(`amat') + if `n'~=`nf'{ + disp in re "from matrix must be dimension " `n' + exit 189 + } + matrix M_inshrt = `amat' + } + local i = 1 + local lst "`y'" + gen byte __0066 = 1 + while `i'< `n'{ + local lst `lst' "eq`i'" + local i = `i' + 1 + } + global HG_eqs + matrix coleq M_inshrt = `lst' + matrix colnames M_inshrt = __0066 + + local frm "from(M_inshrt)" + + matrix coleq M_inshrt = `lst' + matrix colnames M_inshrt = __0066 + local n = colsof(M_inshrt) + global HG_fixe (`y': `y' =__0066, nocons) + local i = 1 + while `i'< `n'{ + global HG_fixe $HG_fixe (eq`i': __0066, nocons) + local i = `i' + 1 + } + } + local opt `options' + } + + * noi + qui `noi' hglm_ml `y', /* + */ $HG_obs `log' title("fixed effects model") /* + */ `frm' `trace' skip `difficult' `opt' `copy' `iterate' `eval' + local fit = 1 + if $HG_init==0 { + quietly `noi' ml display, level(`level') nohead + } + + if $HG_init{ + if $HG_error==0{ + if "`eval'"~=""{ + local robust + local cluster + local pw + } + noi prepare, `robust' `cluster' `pw' `dots' `noi' + * disp in re "running delmacs" + delmacs + restore + estimates repost, esample(`touse') + estimate local cmd "gllamm" + estimate local predict "gllapred" + * disp in re "running replay" + noi Replay, level(`level') `eform' `allc' `robust' `cluster' `display' `eval' + exit 0 + } + } + + if $HG_lev1>0{ + local num=M_nbrf[1,1] + matrix `mat'=e(b) + if $HG_nats{ + matrix `mat'=`mat'[1,"s1:"] + } + else{ + matrix `mat'=`mat'[1,"lns1:"] + } + local i=1 + while `i'<=`num'{ + matrix M_initr[1,`i']=`mat'[1,`i'] + local i=`i'+1 + } + } + if $HG_init{ + delmacs + restore + estimates repost, esample(`touse') + estimate local cmd "gllamm" + estimate local predict "gllapred" + exit 0 + } + + /* restore global macros */ + global HG_tplv=`tplv' + global HG_eqs "`eqs'" + global HG_tprf=`tprf' + global HP_prior=`sprior' + global HG_tpi=`tpi' + global HG_link "`link'" + global HG_linko "`linko'" + global HG_ngeqs = `ngeqs' + quietly replace $HG_wt1=`keep' + matrix M_nip=`mnip' + matrix M_nbrf = `mnbrf' + global HG_const = `const' + global HG_lev1 = `lev1' + global HG_adapt = `adapt' + + } + if `fit'{ + /* put estimates in `b' */ + local cn: colnames(M_initf) + local ce: coleq(M_initf) + matrix M_initf=e(b) + capture matrix colnames M_initf = `cn' + capture matrix coleq M_initf = `ce' + local num=M_nffc[1,$HG_tpff] + if `num'>0 { + local nn=colsof(M_initf) + if `nn'<`num'{ + disp in re "variables have been dropped, can't continue" + exit 198 + } + matrix M_initf=M_initf[1,1..`num'] + * matrix list M_initf + } + if $HG_const==1{ + matrix `b' = nullmat(M_initf), nullmat(M_initr) + matrix M_inshrt = `b'*M_T + } + if $HG_error==1{ + exit + } + } +/* estimation */ + + *qui `noi' disp in smcl in gr "{hline 78}" _n + qui `noi' di in gr _dup(78) "-" _n + qui `noi' dis + qui `noi' dis "start running on $S_DATE at $S_TIME" + +* check this: + *local skip + if $HG_const==1{ + matrix coleq M_inshrt = `lst' + matrix colnames M_inshrt = __0066 + local n = colsof(M_inshrt) + global HG_fixe (`y': `y' =__0066, nocons) + local i = 1 + while `i'< `n'{ + global HG_fixe $HG_fixe (eq`i': __0066, nocons) + local i = `i' + 1 + } + } + + * disp "`trace' `options' " + * disp "$HG_obs `log' `from'" + * disp "`search' `lf0' `gateaux' `skip' `difficult' `eval' " + +/* means and sds for adapt */ + if $HG_adapt{ + local rf = 1 + while `rf'<=$HG_tprf{ + tempname junk + global HG_MU`rf' "`junk'" + tempname junk + global HG_SD`rf' "`junk'" + gen double ${HG_MU`rf'}=0 + gen double ${HG_SD`rf'}=1 + local rf2 = `rf' + 1 + while `rf2' < $HG_tprf { + tempname junk + global HG_C`rf2'`rf' "`junk'" + gen double ${HG_C`rf2'`rf'}=0 + local rf2 = `rf2' + 1 + } + local rf = `rf' + 1 + } + + } + + * noi capture noi + capture noi hglm_ml `y', `trace' `options' /* + */ $HG_obs `log' title("gllamm model") `from' `iterate'/* + */ `search' `lf0' `gateaux' `skip' `copy' `difficult' `eval' + if _rc>0{ global HG_error=1 } + + qui `noi' dis "finish running on $S_DATE at $S_TIME" + qui `noi' dis " " + if $HG_error==0{ + if "`eval'"~=""{ /* do not want to compute robust standard errors */ + local robust + local cluster + local pw + } + noi prepare, `robust' `cluster' `pw' `dots' `noi' + * disp "running delmacs" + delmacs + * disp "restore" + restore + estimates repost, esample(`touse') + estimate local cmd "gllamm" + estimate local predict "gllapred" + * disp "running replay" + noi Replay, level(`level') `eform' `allc' `robust' `cluster' `display' `eval' + } +end + +program define prepare +syntax [, ROBUST CLUSTER(varname) PWEIGHT DOTS NOISILY] +* disp "options are: `robust' `cluster' `pweight' `dots' `noisily'" + tempname b v X U + matrix `b' = e(b) + local n = colsof(`b') + matrix M_Vs = e(V) + capture matrix `v' = inv(M_Vs) + if _rc==0{ + matrix symeigen `X' `U' = `v' + global HG_cn = sqrt(`U'[1,1]/`U'[1,`n']) + } + else{ + global HG_cn = -1 + } + if $HG_const { + matrix M_Vs = M_T*M_Vs*M_T' + } + +/* deal with robust */ + + if "`robust'"~=""|"`cluster'"~=""|"`pweight'"~=""{ + if "`cluster'"~=""{ + global HG_rbcls "`cluster'" + *disp "HG_rbcls is $HG_rbcls" + local cluster cluster(`cluster') + } + * disp "calling gllarob" + qui `noisily' gllarob, first macs `cluster' `dots' + } + * disp "HG_const = " $HG_const + * disp "running remcor" + + qui remcor `b' + + if $HG_const { + * disp "running procstr" + qui procstr + } +end + +program define hglm_ml + version 6.0 + syntax varlist(min=1)[, TITLE(passthru) LF0(numlist) noLOg TRace /* + */ OBS(passthru) FROM(string) SEarch(integer 0) Gateaux(numlist min=3 max=3) skip copy/* + */ noDIFficult EVal ITerate(numlist) *] + + *disp in re "running hglm_ml" + *disp in re "iterate: `iterate'" + + if "`log'"=="" { + local log "noisily" + } + else{ + local log + } + + if "`trace'"~="" { + local noi "noisily" + } + + parse "`varlist'", parse(" ") + local y "`1'" + + tempvar mysamp + tempname b f V M_init M_initr a lnf mlnf ip deriv + + local adapt = $HG_adapt + + if "`from'"~=""{ + matrix `M_init'=`from' + if "`eval'"~=""|`adapt'==1{ + + *noi disp "$HG_fixe $HG_eqs" + ml model d0 gllam_ll $HG_fixe $HG_eqs, /* + */ noscvars waldtest(0) nopreserve missing collinear + + *disp "ml init M_init, `skip' `copy'" + ml init `M_init', `skip' `copy' + matrix ML_g=ML_b + + if `adapt'==0{ + qui `noi' capture ml maximize, search(off) /* + */ iterate(0) novce nooutput nowarn /* `options' */ + disp in gr "log-likelihood = " in ye e(ll) + exit 0 + } + else{ + matrix `M_init' = ML_b + global ML_y1 `y' + noi gllam_ll 1 "`M_init'" "`lnf'" "junk" "junk" 1 + } + * matrix list `M_init' + } + if "`gateaux'"~=""&$HG_free==0{ + disp in re "option gateaux not allowed (ignored) for fixed integration points" + } + else if "`gateaux'"~=""&$HG_free==1{ + qui `noi' disp in gr "Gateaux derivative" + if $HG_tplv>2{ + disp "searching for additional point at level " $HG_tplv + } + local ll=$HG_tplv-1 + local tprf=M_nrfc[2,$HG_tplv]-M_nrfc[2,`ll'] /* number of locations */ + capture local mf = colsof(M_initf) + if _rc>0 {local mf = 0} + capture local mr = colsof(M_initr) + if _rc>0 {local mr = 0} + if $HG_const{ + local nreq = colsof(M_inshrt) - `tprf' - 1 + local cn: colnames(M_inshrt) + local ce: coleq(M_inshrt) + } + else{ + local nreq = `mf'+`mr'-`tprf'-1 + } + + if `nreq'~=colsof(`M_init'){ + disp in re "initial value vector should have length `nreq'" + matrix list `from' + global HG_error=1 + exit 198 + } + + *set trace on + local l = `mr' - `tprf'-1 /* length of previous M_initr */ + local locp = $HG_befB - `mf' + local beg = `locp'-`tprf' /* position of first new mass-point parameter */ + * matrix list M_initr + matrix `a' = M_initr[1,`beg'..`locp'] /* new mass-point parameters */ + * noi disp "new mass-point par" + * matrix list `a' + + if $HG_cip==0{ /* new point is one before last since last has no prob. par. */ + local locp = `locp' - `tprf' + } + + local befB = $HG_befB - `tprf' - 1 /* befB for previous parameter vector */ + global HG_befB + if `nreq' > `befB' { + matrix `M_init' = `M_init'[1,1..`befB'],`a',`M_init'[1,`befB'+1...] + } + else { + matrix `M_init' = `M_init'[1,1..`befB'],`a' + } + * matrix list `M_init' + local locp = `mf' + `locp' + *disp "position of new p-parameter = " `locp' + local nreq = `locp' - `tprf' -1 + *disp "position of first new location parameter = " `nreq'+1 + + if $HG_cip==0{ + * new point must be one before last since new probability tiny + local jl = 1 + while `jl'<=`tprf'{ + matrix `M_init'[1,`locp'+`jl']=`M_init'[1,`nreq'+`jl'] + local jl = `jl' + 1 + } + } + *matrix list `M_init' + + + tokenize "`gateaux'" + local min = `1' + local max = `2' + local num = `3' + local stp = (`max'-`min')/(`num'-1) + matrix `M_init'[1,`locp']=-6 /* mass of new masspoint */ + scalar `mlnf'=0 + matrix `ip'=M_ip + matrix `ip'[1,1]=1 + *recursive loop + matrix `ip'[1,`tprf']=1 + local k = `nreq' + `tprf' + matrix `M_init'[1,`k']=`min' + local nxtrf = `tprf'+1 + matrix `ip'[1,`nxtrf']=`num' + local rf = `tprf' + while `rf' <= `tprf'{ + *reset ip up to random effect `rf' + while (`rf'>1) { + local rf = `rf'-1 + matrix `ip'[1,`rf'] = 1 + local k = `nreq' + `rf' + matrix `M_init'[1,`k']=`min' + } + * update lowest digit + local rf = 1 + while `ip'[1,`rf'] <= `num'{ + local k = `nreq' + `rf' + matrix `M_init'[1,`k'] = `min' + (`ip'[1,`rf']-1)*`stp' + * matrix list `M_init' + global ML_y1 `y' + gllam_ll 0 "`M_init'" "`lnf'" + noi di in gr "." _c + * noisily disp "likelihood=" `lnf' + if (`lnf'>`mlnf'|`mlnf'==0)&`lnf'~=.{ + scalar `mlnf'=`lnf' + matrix M_initr=`M_init' + } + matrix `ip'[1,`rf'] = `ip'[1,`rf'] + 1 + } + matrix `ip'[1,`rf'] = `num' /* lowest digit has reached the top */ + while `ip'[1,`rf']==`num'&`rf'<=`tprf'{ + local rf = `rf' + 1 + } + * rf is first r.eff that is not complete or rf>nrf + if `rf'<=`tprf'{ + matrix `ip'[1,`rf'] = `ip'[1,`rf'] + 1 + local k = `nreq' + `rf' + matrix `M_init'[1,`k'] = `min' + (`ip'[1,`rf']-1)*`stp' + } + } + if "`lf0'"~=""{ + local junk: word 2 of `lf0' + * disp in re "junk = " `junk' + * disp in re "mlnf - lf0 is " `mlnf' " - " `junk' + scalar `deriv' = `mlnf'-`junk' + disp " " + disp in ye "maximum gateaux derivative is " `deriv' + * matrix list `M_initr' + if `deriv'<0.00001{ + disp in re "maximum gateaux derivative less than 0.00001" + global HG_error=1 + exit + } + } + else{ + disp in ye "no gateaux derivarives could be calculated without lf0() option" + matrix list `M_initr' + } + + matrix `M_init' = M_initr +* starting log odds for new location + matrix `M_init'[1,`locp']=-3 + if $HG_const{ + matrix colnames `M_init' = `cn' + matrix coleq `M_init' = `ce' + } + * matrix list `M_init' + } /* end if gateaux */ + } /* end if from */ + else{ /* no from() */ + if "`gateaux'"~=""{ + disp in red "gateaux can't be used without option from()" + exit 198 + } + if "`eval'"~=""{ + disp in red "eval option only allowed with from()" + exit 198 + } + capture matrix `M_init'=M_initf + if $HG_tprf|$HG_lev1>1{ + matrix `M_initr'=M_initr + local max=3 + local min=0 + scalar `mlnf' = 0 + local f1= M_nbrf[1,1]+1 + local l=colsof(M_initr) + local m=1 + if `search'>1{ + if $HG_const==1{ + disp in re "search option does not work yet with constraints" + exit 198 + } + else{ + qui `noi' disp in gr /* + */ "searching for initial values for random effects" + qui `noi' disp "likelihood:" + } + } + while `m'<=`search'{ /* begin search */ + * matrix list M_initr + matrix `a'=`M_init',M_initr + *matrix list `a' + global ML_y1 `y' + noisily gllam_ll 0 "`a'" "`lnf'" + + qui `noi' disp in ye %10.0g `lnf' " " _c + if mod(`m',6)==0 {qui `noi' disp } + + *qui `noi' disp "likelihood=" `lnf' + if (`lnf'>`mlnf'|`m'==1)&`lnf'~=. { + scalar `mlnf'=`lnf' + matrix `M_initr'=M_initr + } + local k=`f1' + while `k'<=`l'{ + matrix M_initr[1,`k']=`min' + (`max'-`min')*uniform() + local k=`k'+1 + } + local m = `m' + 1 + } /* end search */ + matrix `M_init' = nullmat(`M_init'),`M_initr' + } + if $HG_const{ + matrix `M_init' = M_inshrt + } + } + if "`difficult'"~=""{ + local difficu /* erase macro */ + } + else{ + local difficu "difficult" /* default */ + } + * disp "$HG_fixe $HG_eqs, init(`M_init',`skip') " + * disp "`lf0' `obs' `trace' `difficu' `options'" + *matrix list `M_init' + if "`lf0'"~="" { local lf0 "lf0(`lf0')" } + + * matrix list `M_init' + + if `adapt'{ + tempname pa1 + tempname pa2 + tempname ad1 + tempname ad2 ad0 + + * global HG_adapt=0 + global ML_y1 `y' + if "`from'"==""{ + noi gllam_ll 1 "`M_init'" "`lnf'" "junk" "junk" 1 + } + scalar `ad2' = `lnf' + + scalar `ad1' = 0 + local i = 2 + + qui `log' di in gr _n "Running adaptive quadrature" + qui `noi' di in gr _dup(78) "-" _n "Iteration 0 of adaptive quadrature:" + *qui `noi' di in smcl in gr "{hline 78}" _n "Iteration 0 of adaptive quadrature:" + qui `noi' di in gr "Initial parameters:" _n + qui `noi' mat list `M_init', noheader noblank format(%9.0g) + +/* first calculation of adaptive quadrature points ==> ad2 */ + + global HG_adapt=1 + qui `noi' disp in gr _n "Updated log likelihood:" + qui `noi' disp in ye %10.0g `ad2' " " _c + while abs((`ad1'-`ad2')/`ad2')>1e-8&`i'<120&`ad2'~=.{ + scalar `ad1' = `ad2' + noi gllam_ll 1 "`M_init'" "`ad2'" "junk" "junk" 1 + qui `noi' disp in ye %10.0g `ad2' " " _c + if mod(`i',6)==0 {qui `noi' disp } + local i = `i' + 1 + } + if `i'>=120{ + disp in re "Convergence not achieved: try with more quadrature points" + global HG_error=1 + exit + } + if `ad2'==.{ + disp in re "Log-likelihood cannot be computed" + global HG_error=1 + exit + } + + qui `noi' di in gr _n _col(52) "log likelihood = " in ye %10.0g /* + */ scalar(`ad2') + + if "`noi'"==""{ + qui `log' di in gr "Iteration 0: log likelihood = " in ye %10.0g /* + */ scalar(`ad2') + } + + if "`eval'"~=""{ + qui `noi' di in gr _dup(78) "-" + *qui `noi' di in smcl in gr "{hline 78}" + di in gr "log likelihood = " in ye %10.0g /* + */ scalar(`ad2') _n + + qui `noi' capture ml maximize, search(off) /* + */ iterate(0) novce nooutput nowarn /* `options' */ + + *delmacs + *exit 1 + exit 0 + } + + if "`iterate'"~=""{ + local iter=`iterate' + } + else{ + local iter=150 + } + + + global HG_adapt=1 + + +/* loop, update parameters then adaptive quadrature */ + + capture `log' ml model d0 gllam_ll $HG_fixe $HG_eqs, /* + */ noscvars `lf0' `obs' `title' /* + */ waldtest(0) nopreserve missing collinear + + if `iter'==0{ + qui `noi' di in gr _dup(78) "-" + disp in green "Adaptive quadrature has not converged" + + ml init `M_init', `skip' `copy' + + capture ml maximize, search(off) `difficu' /* + */ `trace' iterate(0) nolog /* + */ nooutput noclear /* `options' */ + exit 0 + } + + local it = 0 + scalar `ad0' = `ad2'*1.2 + scalar `pa2' = 0 + local only1 iteronly1 + local fst = 0 + + while abs((`ad0'-`ad2')/`ad0')>1e-6&`it'<`iter'{ + scalar `ad0' = `ad2' + local it = `it' + 1 + qui `noi' di in gr _dup(78) "-" _n "Iteration `it' of adaptive quadrature:" + *qui `noi' di in smcl in gr "{hline 78}" _n "Iteration `it' of adaptive quadrature:" + qui `noi' disp in gr "Updated parameters:" _n + +/* update parameters ==> pa2 */ + + ml init `M_init', `skip' `copy' + *ml report + + * noi capture noi + capture ml maximize, search(off) `difficu' /* + */ `trace' iterate(1) nolog /* + */ nooutput noclear `only1' hessian gradient /* `options' */ + * + + local rc = _rc + if `rc' == 198&`fst'==0{ + local only1 + *noi capture noi + capture ml maximize, search(off) `difficu' /* + */ `trace' iterate(1) nolog /* + */ nooutput noclear `only1' /* `options' technique(bfgs) */ + local rc = _rc + local fst = 1 + } + if `rc'>1 { + di in red "(error occurred in ML computation)" + di in red "(use trace option and check correctness " /* + */ "of initial model)" + global HG_error=1 + exit `rc' + } + + qui `noi' mat list $ML_b, noheader noblank format(%9.0g) + qui `noi' di /* blank line */ + + scalar `pa1' = `pa2' + scalar `pa2' = e(ll) + matrix `M_init'=e(b) + +/* update adaptive quadrature ==> ad2 */ + + local j = 2 + scalar `ad1' = `pa2' + + qui `noi' disp in gr "Updated log likelihood: " + qui `noi' disp in ye %10.0g `ad1' " " _c + + while (abs((`ad1'-`ad2')/`ad2')>1e-8)&`j'<120&`ad2'~=.{ + global ML_y1 `y' + scalar `ad1' = `ad2' + noi gllam_ll 1 "`M_init'" "`ad2'" "junk" "junk" 1 + qui `noi' disp in ye %10.0g `ad2' " " _c + if mod(`j',6)==0 { qui `noi' disp } + local j = `j' + 1 + } + if `ad2'==.{ + disp in re "Log-likelihood cannot be computed" + global HG_error=1 + exit + } + qui `noi' di in gr _n _col(52) "log likelihood = " in ye %10.0g /* + */ scalar(`ad2') + + if "`noi'"==""{ + qui `log' di in gr "Iteration " `it' ": log likelihood = " in ye %10.0g /* + */ scalar(`ad2') + } + + *qui `noi' disp in gr "log-likelihood is " in ye `ad2' in gre /* + */ " and was " in ye `ad0' in gre ", relative change: " /* + */ in ye abs((`ad2'-`ad0')/`ad0') + } + qui `noi' di in gr _dup(78) "-" _n + *qui `noi' di in smcl in gr "{hline 78}" _n + + *tempname v + *capture matrix `v'=e(V) + *capture matrix `v' = inv(`v') + *if _rc>0{ + if `it'==`iter'&((`ad0'-`ad2')/`ad0')>1e-6 { + disp in green "Adaptive quadrature did not converge in `iter' iterations" + exit 0 + } + qui `log' disp in gr _n _n "Adaptive quadrature has converged, running Newton-Raphson" _c + ml init `M_init', skip copy + capture `log' ml maximize, search(off) `difficu' /* + */ `trace' nooutput iterate(`iter') /* `options' */ + local rc = _rc + if `rc'>1 { + di in red "(error occurred in ML computation)" + di in red "(use trace option and check correctness " /* + */ "of initial model)" + global HG_error=1 + exit `rc' + } + *} + } + else{ /* not adaptive */ + if "`iterate'"~=""{ + local iter "iterate(`iterate')" + } + else{ + local iter + } + capture `log' ml model d0 gllam_ll $HG_fixe $HG_eqs, /* + */ maximize search(off) /* + */ init(`M_init', `skip' `copy') noscvars `lf0' `obs' `title' `trace' /* + */ waldtest(0) nopreserve missing `difficu' collinear `iter'/* `options' */ + * technique(bfgs) gtol(1e-4) + } + + local rc = _rc + if `rc'>1 { + di in red "(error occurred in ML computation)" + di in red "(use trace option and check correctness " /* + */ "of initial model)" + global HG_error=1 + exit `rc' + } + if `rc'==1 { + di in red /* + */ "(Maximization aborted)" + delmacs + global HG_error=1 + exit 1 + } + else if $HG_error==1{ + disp in red "some error has occurred" + exit + } +end + +program define lnkfm + version 6.0 + args link fam + + global S_1 /* link */ + global S_2 /* family */ + + + lnk "`1'" + fm "`2'" + + if "$S_1" == "" { + if "$S_2" == "gauss" { global S_1 "ident" } + if "$S_2" == "poiss" { global S_1 "log" } + if "$S_2" == "binom" { global S_1 "logit" } + if "$S_2" == "gamma" { global S_1 "recip" } + } + +/* + if ("$S_1"=="mlogit"|"$S_1"=="smlogit")&"$S_2"~="binom"{ + disp in red "mlogit link must be combined with binomial probability" + exit 198 + } +*/ + if ("$S_1"=="mlogit"|"$S_1"=="smlogit"|"$S_1"=="ologit"|"$S_1"=="oprobit"|"$S_1"=="soprobit"|"$S_1"=="ocll"){ + global S_2 + } +end + +program define fm + version 6.0 + args fam + local f = lower(trim("`fam'")) + local l = length("`f'") + + if "`f'" == substr("gaussian",1,max(`l',3)) { global S_2 "gauss" } + else if "`f'" == substr("normal",1,max(`l',3)) { global S_2 "gauss" } + else if "`f'" == substr("poisson",1,max(`l',3)) { global S_2 "poiss" } + else if "`f'" == substr("binomial",1,max(`l',3)) { global S_2 "binom" } + else if "`f'" == substr("gamma",1,max(`l',3)) { global S_2 "gamma" } + else if "`f'" != "" { + noi di in red "unknown family() `fam'" + exit 198 + } + + if "$S_2" == "" { + global S_2 "gauss" + } +end + +program define lnk + version 6.0 + args link + local f = lower(trim("`link'")) + local l = length("`f'") + + if "`f'" == substr("identity",1,max(`l',2)) { global S_1 "ident" } + else if "`f'" == substr("log",1,max(`l',3)) { global S_1 "log" } + else if "`f'" == substr("logit",1,max(`l',4)) { global S_1 "logit" } + else if "`f'" == substr("mlogit",1,max(`l',3)) { global S_1 "mlogit" } + else if "`f'" == substr("smlogit",1,max(`l',3)) { global S_1 "smlogit" } + else if "`f'" == substr("ologit",1,max(`l',3)) { global S_1 "ologit" } + else if "`f'" == substr("oprobit",1,max(`l',3)) { global S_1 "oprobit" } + else if "`f'" == substr("probit",1,max(`l',3)) { global S_1 "probit"} + else if "`f'" == substr("ocll",1,max(`l',3)) { global S_1 "ocll"} + else if "`f'" == substr("cll",1,max(`l',3)) { global S_1 "cll"} + else if "`f'" == substr("ll",1,max(`l',2)) { global S_1 "ll"} + else if "`f'" == substr("sprobit",1,max(`l',3)) { global S_1 "sprobit"} + else if "`f'" == substr("soprobit",1,max(`l',3)) { global S_1 "soprobit"} + else if "`f'"==substr("reciprocal",1,max(`l',3)) { global S_1 "recip" } + else if "`f'" != "" { + noi di in red "unknown link() `link'" + exit 198 + } +end + +program define delmacs, eclass + version 6.0 +/* deletes all global macros and matrices and store some results in e()*/ + tempname var + if "$HG_tplv"==""{ + * macros already gone + exit + } + local nrfold = M_nrfc[2,1] + local lev = 2 + while (`lev'<=$HG_tplv){ + local i2 = M_nrfc[2,`lev'] + local i1 = `nrfold'+1 + local i = `i1' + local nrfold = M_nrfc[2,`lev'] + local n = M_nrfc[1,`lev'] + local n = M_nip[2,`n'] + capture est matrix zps`n' M_zps`n' + while `i' <= `i2'{ + local n = M_nip[2,`i'] + capture est matrix zlc`n' M_zlc`n' + capture est matrix zps`n' M_zps`n' + local i = `i' + 1 + } + local lev = `lev' + 1 + } + + + if $HG_free==0&$HG_init==0{ + est matrix chol CHmat + } + if $HG_free{ + est matrix mnp M_np + } + est matrix nrfc M_nrfc + est matrix nffc M_nffc + est matrix nbrf M_nbrf + est matrix nu M_nu + capture est matrix Vs M_Vs + capture est matrix mresp M_resp + capture est matrix mrespm M_respm + capture est matrix frld M_frld + if $HG_ngeqs>0{ + est matrix mngeqs M_ngeqs + } + matrix drop M_ip + est matrix nip M_nip + capture est matrix mb M_b + matrix drop M_znow + capture matrix drop M_initf + capture matrix drop M_initr + capture matrix drop M_chol + capture est matrix mb M_b + est matrix olog M_olog + capture est matrix moth M_oth + if $HG_const == 1{ + capture drop __0066 + est matrix a M_a + * est matrix C M_C + est matrix T M_T + est local coln $HG_coln + est local cole $HG_cole + global HG_coln + global HG_cole + } + + /* globals defined in gllam_ll */ + local i=1 + while (`i'<=$HG_tpff){ + global HG_xb`i' + local i= `i'+1 + } + local i = 1 + while (`i'<=$HG_tprf){ + global HG_s`i' + local i= `i'+1 + } + local i = 1 + while (`i'<=$HG_tplv){ + global HG_wt`i' + local i = `i' + 1 + } + if $HG_adapt{ + macro drop HG_zuoff + macro drop HG_SD* + macro drop HG_MU* + macro drop HG_E* + macro drop HG_V* + macro drop HG_C* + } + + macro drop HG_zip + macro drop HG_lzpr + est local nats=$HG_nats + global HG_nats + est local noC=$HG_noC + global HG_noC + est local noC1=$HG_noC1 + global HG_noC1 + global HG_noC2 + est local adapt=$HG_adapt + global HG_adapt + est local const = $HG_const + global HG_const + global HG_fixe + est local inter = $HG_inter + global HG_inter + global HG_dots + est local ngeqs = $HG_ngeqs + global HG_ngeqs + est local nolog = $HG_nolog + if $HG_nolog>0{ + est local k_eform = 1 /* controls how many eqns are exponentiated */ + } + else{ + est local k_eform = $HG_tpff + } + global HG_nolog + est local ethr = $HG_ethr + global HG_ethr + est local mlog = $HG_mlog + global HG_mlog + est local smlog = $HG_smlog + global HG_smlog + global HG_lvolo + est local oth = $HG_oth + global HG_oth + est local lev1 = $HG_lev1 + global HG_lev1 + est local bmat = $HG_bmat + global HG_bmat + est local tplv = $HG_tplv + global HG_tplv + est local tprf = $HG_tprf + global HG_tprf + est local prior = $HP_prior + if $HP_prior == 1{ + local a_ll = `e(ll)' - $HP_res + est local a_ll = `a_ll' + est local lpr = $HP_res + global HP_res + + if $HP_invga==1{ + est local invga $HP_invga + est local shape $shape + est local rate $rate + global HP_invga + global shape + global rate + } + if $HP_invwi==1{ + est local invwi $HP_invwi + est local df $df + est matrix scale scale + global HP_invwi + global df + } + if $HP_foldt==1{ + est local foldt $HP_foldt + est local df $df + est local scale $scale + est local location $location + global HP_foldt + global df + global scale + global location + } + if $HP_logno==1{ + est local logno $HP_logno + est local meanlog $meanlong + est local sdlog $sdlog + global HP_logno + global meanlog + global sdlog + } + if $HP_gamma==1{ + est local gamma $HP_gamma + est local scale $HP_scale + est local var $HP_var + est local shape $HP_shape + global HP_gamma + global HP_scale + global HP_var + global HP_shape + } + if $HP_corre==1{ + est local corre $HP_corre + est local alpha $alpha + est local beta $beta + global HP_corre + global alpha + global beta + } + if $HP_boxco==1{ + est local boxdo $HP_boxco + est local scale $scale + est local lambda $lambda + global HP_boxco + global scale + global lambda + } + if $HP_spect==1{ + est local spect $HP_spect + est local alpha $alpha + est local beta $beta + global HP_spect + global alpha + global beta + } + if $HP_wisha==1{ + est local wisha $HP_wisha + est local df $df + est matrix scale scale + global HP_wisha + global df + } + + } + global HP_prior + est local tpi = $HG_tpi + global HG_tpi + est local tpff = $HG_tpff + global HG_tpff + est local clus "$HG_clus" + global HG_clus + est local weight "$HG_weigh" + global HG_weigh + est local pweight "$HG_pwt" + global HG_pwt + global which + global HG_gauss + est local free = $HG_free + global HG_free + est local mult = $HG_mult + global HG_mult + est local cip = $HG_cip + est local famil "$HG_famil" + global HG_famil + est local link "$HG_link" + global HG_link + est local linko "$HG_linko" + global HG_linko + capture est local exp $HG_exp + global HG_exp + capture est local expf $HG_expf + global HG_expf + est local lv "$HG_lv" + global HG_lv + est local fv "$HG_fv" + global HG_fv + global HG_nump + global HG_eqs + global HG_obs + est local offset "$HG_off" + global HG_off + est local denom "$HG_denom" + global HG_denom + est local cor = $HG_cor + global HG_cor + est local s1 "$HG_s1" + global HG_s1 + capture est local init $HG_init + global HG_init + capture est local ind "$HG_ind" + global HG_ind + capture est local comp $HG_comp + global HG_comp + capture est local coall "$HG_coall" + global HG_coall + capture est local cn = $HG_cn + global HG_cn + capture est local robclus "$HG_rbcls" + global HG_rbcls + global HG_befB + global HG_cip +end + +program define initmacs +version 6.0 +/* defines all global macros */ +args nrf nip eqs geqs peqs s nats bmatrix touse dep frload + +tempname mat + +disp " " +disp in gr "Random effects information for" in ye " $HG_tplv" in gr " level model" +*disp in smcl in gr "{hline 78}" _n +di in gr _dup(78) "-" _n + +/* deal with nrf */ + matrix M_nrfc=J(2,$HG_tplv,1) + if "`nrf'"==""|$HG_free|$HG_mult{ + local k=1 + while (`k'<=$HG_tplv){ + matrix M_nrfc[1,`k']=`k' + matrix M_nrfc[2,`k']=`k' + local k=`k'+1 + } + } + if "`nrf'"~=""{ + local greater = 0 + local k: word count `nrf' + if `k'~=$HG_tplv-1 { + if $HG_tplv==1{ + disp in red "option nrf is meaningless for 1-level model" + } + else{ + disp in red "option nrf() does not contain " $HG_tplv-1 " argument(s)" + } + exit 198 + } + parse "`nrf'", parse(" ") + local k=2 + while (`k'<=$HG_tplv){ + matrix M_nrfc[2,`k']=`1' + if `1'>1{ + local greater=1 + } + local k=`k'+1 + mac shift + } + /* make cumulative */ + local k=2 + while (`k'<=$HG_tplv){ + matrix M_nrfc[2,`k']=M_nrfc[2,`k'-1]+M_nrfc[2,`k'] + if $HG_free==0&$HG_mult==0{matrix M_nrfc[1,`k']=M_nrfc[2,`k']} + local k=`k'+1 + } + if `greater'>0{ + if "`eqs'"==""{ + disp in re "eqs() option required" + exit 198 + } + } + } + * matrix list M_nrfc + global HG_tprf=M_nrfc[2,$HG_tplv] /* number of random effects */ + global HG_tpi=M_nrfc[1,$HG_tplv] /* number of integration loops + 1 */ + if $HG_tplv==$HG_tprf{ + if $HG_cor==0{ + disp "option nocorrel ignored because no multiple r. effects per level" + } + } + + +/* deal with nip and set up zloc and zps */ + + if "`nip'"~=""{ + local k: word count `nip' + if `k'==1{ + if `nip' == 1{ + matrix M_nip=J(2,$HG_tprf,1) + if $HG_free { + if $HG_cip==1 { + global HG_init=1 + } + } + else{ + disp in re "(co)variances of latent variables will not be identified with nip(1)" + ghquad 1 + } + } + } + + if `k'>1 | $HG_tpi == 2 { + if `k'~=$HG_tpi-1{ + disp in red "option nip() has `k' arguments, need 1 or " $HG_tpi-1 + exit 198 + } + matrix M_nip=J(2,$HG_tprf,1) + local i=1 + while `i'<$HG_tpi{ + local k: word `i' of `nip' + local l = `i' + 1 + matrix M_nip[1,`l']= `k' + if $HG_mult{ + * disp in re "k = `k'" + local n = M_nrfc[2,`l'] - M_nrfc[2,`l'-1] + if `n'>1 { + mint `n' `k' + matrix M_nip[1,`l'] = $S_1 + } + else{ + local kk = (`k' + 1)/2 + if int(`kk')~=`kk'{ + disp in re "arguments in nip() option must be odd with ip(m)" + exit 198 + } + ghquad `kk' + matrix M_nip[1,`l']= `kk' + } + } + else if $HG_free==0{ + if $HG_gauss{ + ghquad `k' + } + else{ + lebesque `k' + } + } + local i = `i' + 1 + } /* end i */ + } + else{ /* one argument given for more than one loop */ + matrix M_nip=J(2,$HG_tprf,`nip') + matrix M_nip[1,1] = 1 + if $HG_mult{ + local l = 2 + while `l' <= $HG_tpi{ + local n = M_nrfc[2,`l'] - M_nrfc[2,`l'-1] + if `n'>1{ + mint `n' `nip' + matrix M_nip[1,`l'] = $S_1 + } + else{ + local kk = (`nip' + 1)/2 + if int(`kk')~=`kk'{ + disp in re "arguments in nip() option must be odd with ip(m)" + exit 198 + } + ghquad `kk' + matrix M_nip[1,`l']= `kk' + } + local l = `l' + 1 + } + } + else if $HG_free==0{ + if $HG_gauss{ + ghquad `nip' + } + else{ + lebesque `nip' + } + } + } + } + else{ /* no nip argument given */ + matrix M_nip=J(2,$HG_tprf,8) + matrix M_nip[1,1] = 1 + if $HG_mult{ + local l = 2 + while `l' <= $HG_tpi{ + local n = M_nrfc[2,`l'] - M_nrfc[2,`l'-1] + if `n'>1{ + sphern `n' + matrix M_nip[1,`l'] = $S_1 + } + else{ + matrix M_nip[1,`l'] = 8 + ghquad 8 + } + local l = `l' + 1 + } + } + else if $HG_free==0{ + if $HG_gauss{ + ghquad 8 + } + else{ + lebesque 8 + } + } + } + + local i = M_nrfc[2,1]+1 + while `i'<= $HG_tprf{ + if $HG_free{ + matrix M_nip[2,`i'] = `i' + } + else{ + matrix M_nip[2,`i'] = M_nip[1,`i'] + } + local i = `i' + 1 + } + + * noi matrix list M_nip + capture matrix drop M_initr + + *matrix M_zlc8 = J(1,8,1) + *matrix M_zps8 = J(1,8,ln(1/8)) + +/* deal with Eqs */ + matrix M_frld = J(1,$HG_tprf,0) + local depv `dep' + matrix M_nbrf=(0) + global HG_eqs + global HG_nats = 0 + local lns1 lns1 + local log log + if $HG_lev1>0{ + if "`nats'"~=""{ + global HG_nats = 1 + local lns1 s1 + local log + } + disp in gr "***level 1 equation:" + if "`s'"~=""{ + eq ? "`s'" + local vars "$S_1" + markout `touse' `vars' + global HG_eqs "$HG_eqs (`lns1': `depv' `vars',nocons)" + global HG_s1 "(`lns1': `depv' `vars',nocons)" + + } + else{ + local vars "_cons" + global HG_eqs "$HG_eqs (`lns1': `depv')" + global HG_s1 "(`lns1': `depv')" + } + local depv + disp " " + if $HG_lev1==1{disp in gr " `log' standard deviation"} + else if $HG_lev1==2{disp in gr " `log' coefficient of variation"} + else if $HG_lev1==3{disp in gr " `log'(sqrt(phi))"} + disp in ye " `lns1': `vars'" + local num: word count `vars' + matrix M_nbrf=(`num') + matrix `mat'=J(1,`num',-1) + matrix colnames `mat'=`vars' + matrix coleq `mat'=`lns1' + matrix M_initr=nullmat(M_initr),`mat' + } + else{ + matrix M_nbrf=(0) + if "`s'"~=""{ + disp in re "s() option ignored because families do not include dispersion parameters" + } + if "`nats'"~=""{ + disp in re "nats option ignored because families do not include dispersion parameters" + } + } + + matrix M_np = J(1,$HG_tpi,0) + if "`peqs'" ~= ""{ + local k: word count `peqs' + if $HG_free == 0 { + disp in re "peqs() argument meaningless for quadrature estimation, ignored" + } + else if `k'~=$HG_tpi-1{ + disp in red `k' " equations specified for prior probabilities: `peqs', need" $HG_tpi - 1 + exit 198 + } + global HG_noC1 = $HG_noC2 + } + + if "`eqs'"~=""{ + local k: word count `eqs' + if `k'~=$HG_tprf-1{ + disp in red `k' " equations specified: `eqs', need " $HG_tprf-1 + exit 198 + } + * check that they are equations and find number of variables in each: nbrf + local lev=2 + local l=1 + local ic=0 + while (`lev'<=$HG_tplv){ + disp " " + local m=$HG_tplv-`lev'+1 + local clusnam: word `m' of $HG_clus + disp " " + disp in gr "***level `lev' (" in ye "`clusnam'" in gr ") equation(s):" + if $HG_init==1{ + di in gr "(init option: parameters will not be estimated)" + di " " + } + local clusnam=substr("`clusnam'",1,3) + local lv = `lev'-1 + local clusnam "`clusnam'`lv'_" + local i1=M_nrfc[2, `lev'-1] + local j1=M_nrfc[2, `lev'] + local nrf=`j1'-`i1' + disp " (`nrf' random effect(s))" + disp " " + local rfl = 1 +/* MASS POINTS */ + if $HG_free { + tempname pmat + if $HG_cor==0{ + disp "option nocorrel irrelevant for free masses" + } + local k = 1 + local nloc = M_nip[1, `lev'] + if $HG_cip{ local nloc = `nloc' - 1} +* new + local pnum = 0 + local pvars _cons + matrix `pmat' = J(1,1,0) + if "`peqs'"~=""{ + local levm = `lev' - 1 + local peqn: word `levm' of `peqs' + eq ? "`peqn'" + local pvars "$S_1" + markout `touse' `pvars' + local pnum: word count `pvars' + matrix M_np[1,`lev'] = `pnum' + 1 + matrix `pmat' = J(1, `pnum', 0) + } + matrix colnames `pmat' = `pvars' +* end new + + while `k' <= `nloc'{ + disp " " + disp in gre "class `k'" + local j = `i1' + while `j'< `j1'{ + local eqnam: word `j' of `eqs' + eq ? "`eqnam'" + local vars "$S_1" + markout `touse' `vars' + local num: word count `vars' + + local ex = 0 + if "`frload'"~=""{ + local nex: word count `frload' + local iex = 1 + while `iex'<=`nex'{ + local aex: word `iex' of `frload' + if `aex' == `j'{ + local ex = 1 + } + local iex = `iex' + 1 + } + if `ex'{ + matrix M_frld[1,`j'+1] = 1 + local num = `num' + 1 + } + } + + + matrix `mat'=(`num') + matrix M_nbrf=M_nbrf,`mat' + if (`num'>1){ + parse "`vars'", parse(" ") + local vars1 "`1'" + if `k'==1{ + if `ex'==0{ + mac shift + } + local vars2 "`*'" + local eqnaml "`clusnam'`rfl'l" + eq "`eqnaml': `vars2'" + eq ? "`eqnaml'" + disp " " + disp in gr " lambdas for random effect " in ye `j' + disp in ye " `eqnaml': `vars2'" + global HG_eqs "$HG_eqs (`eqnaml': `depv' `vars2', nocons)" + local depv + local num=`num'-1 + * initial loading on masspoints + local lod = 1.1 + (`j'-1)*(-1)^(`j')/5 + matrix `mat'=J(1,`num',`lod') + matrix colnames `mat'= `vars2' + matrix coleq `mat'=`eqnaml' + matrix M_initr = nullmat(M_initr), `mat' + } + + } + else{local vars1 `vars'} + disp " " + disp in gr " location for random effect " in ye `j' + local eqnam "z`lev'_`j'_`k'" + if `nrf'==1{ + local eqnam "z`lev'_1_`k'" + } + eq "`eqnam'":`vars1' + eq ? "`eqnam'" + disp in ye " `eqnam': `vars1'" + global HG_eqs "$HG_eqs (`eqnam': `depv' `vars1', nocons)" + local depv + markout `touse' `vars1' + * initial locations of mass points + *local val = int((`k'+1)/2)*(-1)^`k'/10 + local val = int((`k'+1)/2)*(-1)^`k' + matrix `mat'=(`val') + matrix colnames `mat'=`vars1' + matrix coleq `mat'=`eqnam' + matrix M_initr=nullmat(M_initr),`mat' + local j = `j' + 1 + local rfl = `rfl' + 1 + } + if `k'< M_nip[1, `lev']{ + local eqnam "p`lev'_`k'" + eq "`eqnam'": + eq ? "`eqnam'" + disp " " + disp in gr " log odds for level " in ye `lev' + + if `pnum'>0{ + disp in ye " `eqnam': `pvars' _cons" + global HG_eqs "$HG_eqs (`eqnam':`pvars')" + matrix coleq `pmat'=`eqnam' + matrix M_initr=nullmat(M_initr),`pmat' + } + else{ + disp in ye " `eqnam': _cons" + global HG_eqs "$HG_eqs (`eqnam': `depv')" + local depv + * initial log odds for masspoints + } + * set constant + matrix `mat'=(-.4) + matrix colnames `mat'=_cons + matrix coleq `mat'=`eqnam' + matrix M_initr=nullmat(M_initr),`mat' + } + local k = `k' + 1 + } + * matrix list M_initr + * disp "$HG_eqs" + } +/* STD DEVS */ + else{ + local j = `i1' + while (`j'<`j1'){ + local eqnam: word `l' of `eqs' + eq ? "`eqnam'" + local vars "$S_1" + local num: word count `vars' + local ex = 0 + if "`frload'"~=""{ + local nex: word count `frload' + local iex = 1 + while `iex'<=`nex'{ + local aex: word `iex' of `frload' + if `aex' == `j'{ + local ex = 1 + } + local iex = `iex' + 1 + } + if `ex'{ + matrix M_frld[1,`j'+1] = 1 + local num = `num' + 1 + } + } + matrix `mat'=(`num') + matrix M_nbrf=M_nbrf,`mat' + markout `touse' `vars' + if "`vars'"==""{ local vars "_cons"} + if `num'>1{ + * vars1 is variable of first loading (fix at one) + parse "`vars'", parse(" ") + local vars1 "`1'" + if `ex'==0{ + mac shift + } + local vars "`*'" + local eqnaml "`clusnam'`rfl'l" + eq "`eqnaml'": `vars' + eq ? "`eqnaml'" + disp " " + disp in gr " lambdas for random effect " in ye `j' + disp in ye " `eqnaml': `vars'" + global HG_eqs "$HG_eqs (`eqnaml': `depv' `vars', nocons)" + local depv + * initial values of loadings + local lod = 1.1 + (`j'-1)*(-1)^(`j')/5 /*different loading for diff r.eff*/ + matrix `mat'=J(1,`num'-1,`lod') + matrix colnames `mat'=`vars' + matrix coleq `mat'=`eqnaml' + matrix M_initr=nullmat(M_initr),`mat' + } + else{ + local vars1 `vars' + } + * variance + local eqnam "`clusnam'`rfl'" + eq "`eqnam'": `vars1' + if `nrf'==1|$HG_cor==0{ + disp in gr " standard deviation for random effect " in ye `j' + } + else{ + disp " " + disp in gr /* + */" diagonal element of cholesky decomp. of covariance matrix" + } + disp in ye " `eqnam' : `vars1'" + global HG_eqs "$HG_eqs (`eqnam': `depv' `vars1', nocons)" + local depv + * initial value of standard deviation + matrix `mat' = (0.5) + matrix colnames `mat' = `vars1' + matrix coleq `mat' = `eqnam' + matrix M_initr=nullmat(M_initr),`mat' + local l=`l'+1 + local j=`j'+1 + local rfl = `rfl' + 1 + } + if `nrf' > 1&$HG_cor==1{ + /* generate equations for covariance parameters */ + disp " " + disp in gr " off-diagonal elements" + local ii=2 + *local num = $HG_tplv-`lev'+1 + *local eqnam: word `num' of $HG_clus + *local eqnam = substr("`eqnam'",1,4) + while (`ii'<=`nrf'){ + local jj=1 + while (`jj'<`ii'){ + local eqnaml "`clusnam'`ii'_`jj'" + eq "`eqnaml'": + eq ? "`eqnaml'" + disp in ye " `eqnaml': _cons" + global HG_eqs "$HG_eqs (`eqnaml':)" + matrix `mat'=(0) + matrix colnames `mat'=_cons + matrix coleq `mat'=`eqnaml' + matrix M_initr=nullmat(M_initr),`mat' + local jj = `jj' + 1 + } + local ii=`ii'+1 + } + } + } /* end else $HG_free */ + local lev=`lev'+1 + } /* lev loop */ + + } /* endif equ given */ + else{ + /* random intercepts */ + if M_nrfc[1,$HG_tplv]~=$HG_tplv{ + "must specify equations for random effects" + exit 198 + } + local k=$HG_tprf-1 + matrix `mat'=J(1,`k',1) + matrix M_nbrf=M_nbrf,`mat' + local lev=2 + disp " " + while (`lev'<=$HG_tplv){ + local l=$HG_tplv-`lev'+1 + local clusnam: word `l' of $HG_clus + disp " " + disp in gr "***level `lev' (" in ye "`clusnam'" in gr ") equation(s):" + if $HG_init==1{ + di in gr "(init option: parameters will not be estimated)" + di " " + } + local clusnam = substr("`clusnam'",1,4) + local lv = `lev' - 1 + local clusnam "`clusnam'`lv'" +/*MASS POINTS */ + if ($HG_free){ + local k = 1 + local nloc = M_nip[1, `lev'] + if $HG_cip{ local nloc = `nloc' - 1} + +* new + local pnum = 0 + local pvars _cons + tempname pmat + matrix `pmat' = J(1,1,0) + if "`peqs'"~=""{ + local levm = `lev' - 1 + local peqn: word `levm' of `peqs' + eq ? "`peqn'" + local pvars "$S_1" + markout `touse' `pvars' + local pnum: word count `pvars' + matrix M_np[1,`lev'] = `pnum' + 1 + matrix `pmat' = J(1, `pnum', 0) + } + matrix colnames `pmat' = `pvars' +* end new + while `k' <= `nloc'{ + disp " " + disp in gre "class `k'" + local j = 1 + + local eqnam "z`lev'_1_`k'" + disp in gr " location for random effect" + disp in ye " `eqnam': _cons" + global HG_eqs "$HG_eqs (`eqnam': `depv')" + local depv + * initial locations of mass points + *local val = int((`k'+1)/2)*(-1)^`k'/10 + local val = int((`k'+1)/2)*(-1)^`k' + matrix `mat'=(`val') + matrix colnames `mat'=_cons + matrix coleq `mat'=`eqnam' + matrix M_initr=nullmat(M_initr),`mat' + + if `k'0{ + disp in ye " `eqnam': `pvars' _cons" + global HG_eqs "$HG_eqs (`eqnam':`pvars')" + matrix coleq `pmat'=`eqnam' + matrix M_initr=nullmat(M_initr),`pmat' + } + else{ + disp in ye " `eqnam': _cons" + global HG_eqs "$HG_eqs (`eqnam':)" + * initial log odds for masspoints + } + * set constant + matrix `mat'=(-.4) + matrix colnames `mat'=_cons + matrix coleq `mat'=`eqnam' + matrix M_initr=nullmat(M_initr),`mat' + } + local k = `k' + 1 + } + } +/* ST. DEVS */ + else{ + local eqnam "`clusnam'" + disp " " + disp in gr " standard deviation of random effect" + disp in ye " `eqnam': _cons" + global HG_eqs "$HG_eqs (`eqnam':`depv')" + local depv + * initial value for sd + matrix `mat'=(0.5) + matrix colnames `mat'=_cons + matrix coleq `mat'=`eqnam' + matrix M_initr=nullmat(M_initr),`mat' + local cons `cons'1 + } + local lev=`lev'+1 + } + } + disp " " + + matrix `mat' = nullmat(M_initr), nullmat(M_initf) /* M_initr may not exist */ + global HG_befB = colsof(`mat') +/* deal with Bmatrix */ + + global HG_bmat = 0 + if "`bmatrix'"~=""{ + if $HG_tprf<2{ + disp in re "bmatrix can only be used for more than 1 random effect" + exit 198 + } + * capture matrix list `bmatrix' + if _rc>0{ + disp in re "bmatrix is not a matrix" + exit 198 + } + local bn = colsof(`bmatrix') + if rowsof(`bmatrix')~=`bn'{ + disp in re "bmatrix must be square" + exit 198 + } + if `bn'~=$HG_tprf-1{ + disp in re "number of rows and columns of B matrix must be " $HG_tprf-1 + exit 198 + } + matrix M_b=`bmatrix' + global HG_bmat = 1 + disp in gr "B-matrix:" + local i = 1 + while `i' <= `bn'{ + local j = 1 + while `j'<= `bn'{ + if M_b[`i',`j']>0{ + local eqnam b`i'_`j' + disp " " + disp in ye " `eqnam': _cons" + global HG_eqs "$HG_eqs (`eqnam':)" + * initial value for sd + matrix `mat'=(0.5) + matrix colnames `mat'=_cons + matrix coleq `mat'=`eqnam' + matrix M_initr=nullmat(M_initr),`mat' + local cons `cons'1 + } + local j = `j' + 1 + } + local i = `i' + 1 + } + disp " " + } + +/* total number of fixed linear predictors */ + global HG_tpff = colsof(M_nffc) + +/* deal with geqs */ + global HG_ngeqs = 0 + if "`geqs'"~=""{ + * M_ngeqs: first row says which random effect, second how many terms + local num: word count `geqs' + global HG_ngeqs = `num' + matrix M_ngeqs=J(3,`num',0) + local nxt = M_nffc[1,$HG_tpff] + colsof(M_initr) + 1 + disp in gr "Regressions of random effects on covariates:" + tokenize `geqs' + local i = 1 + while "`1'"~="" { + local k = substr("`1'",2,1) + local k = `k' + 1 + if `k'>$HG_tprf { + disp in red "eq `1' refers to a random effects that does not exist" + exit 198 + } + local j = 1 + while `j'<=`i'{ + if M_ngeqs[1,`j']==`k' { + disp in red "more than one geq given for random effect" `k'-1 + exit 198 + } + local j = `j' + 1 + } + eq ? "`1'" + local vars "$S_1" + local num: word count `vars' + matrix `mat'=J(1,`num',0) + matrix colnames `mat'=`vars' + matrix coleq `mat'=`1' + matrix M_initr=nullmat(M_initr),`mat' + markout `touse' `vars' + disp in gr " equation for random effect " in ye `k'-1 + disp in ye " `1': `vars'" + global HG_eqs "$HG_eqs (`1': `vars', nocons)" + matrix M_ngeqs[1,`i']=`k' + matrix M_ngeqs[2,`i']=`num' + matrix M_ngeqs[3,`i']=`nxt' + local nxt = `nxt' + `num' + local i = `i' + 1 + mac shift + } + disp " " + } + + global which = 15 + +/* the "clock" ip and znow*/ + local k = $HG_tprf+2 + matrix M_ip = J(1,`k',1) + local k = $HG_tprf - 1 + matrix M_znow =J(1,`k',1) + +end + + + +program define mint +args n k + if `k' == 5 { + multn `n' + } + else if `k' == 7 { + sphern `n' + } + else if `n'==2&(`k' == 9|`k' == 11|`k' == 15){ + int2k `k' + } + else{ + disp in re "nip must be 5 or 7 if dim >2 and 5, 7, 9, 11 or 15 if dim=2" + exit 198 + } +end + +program define sphern +version 6.0 +/* degree 7 rule for n>=3 used by Naylor and Smith */ +args n + if `n' == 2 { + spher2 + } + else if `n' == 3{ + spher3 + } + else if `n' == 6{ + spher6 + } +/* + else if `n' == 4{ + spher4 + } +*/ + else{ + tempname r s t B C D r1 r2 A1 A2 x X y a norm im + + local num =2*( 2^`n' + 2*`n'^2) + +* generate U_n: 7-1 page 295 + scalar `r' = sqrt(2) + scalar `s' = sqrt(2/`n') + scalar `t' = 1 + scalar `B' = ln(8-`n') - ln(`n') - ln(`n'+2) - ln(`n'+4) + ln(2) - lngamma(`n'/2) + scalar `C' = -`n'*ln(2) + 3*ln(`n') - ln(`n') - ln(`n'+2) - ln(`n'+4) + ln(2) - lngamma(`n'/2) + scalar `D' = ln(4) - ln(`n') - ln(`n'+2) - ln(`n'+4) + ln(2) - lngamma(`n'/2) + scalar `r2' = sqrt( (`n' + 2 - sqrt(2*(`n'+2)))/2 ) + scalar `r1' = sqrt( (`n' + 2 + sqrt(2*(`n'+2)))/2 ) + scalar `A2' = ln( ( `n' + 2 + sqrt(2*(`n'+2)) )/(4*(`n'+2)) )+ lngamma(`n'/2) + scalar `A1' = ln( ( `n' + 2 - sqrt(2*(`n'+2)) )/(4*(`n'+2)) )+ lngamma(`n'/2) + + +* Do r and B + matrix `x' = J(1,`n',0) + local ir = 1 + while `ir' <= `n'{ + local j = 1 + while `j' <= 2 { + matrix `x'[1,`ir'] = (-1)^`j'*`r' + matrix `X' = nullmat(`X')\ `x' + matrix `y' = nullmat(`y'),`B' + matrix `x'[1,`ir'] = 0 + local j = `j' + 1 + } + local ir = `ir' + 1 + } + +* Do t and D + matrix `x' = J(1,`n',0) + local it1 = 1 + while `it1' <= `n'{ + local j1 = 1 + while `j1' <= 2{ + matrix `x'[1,`it1'] = (-1)^`j1'*`t' + local it2 = `it1' + 1 + while `it2' <= `n'{ + local j2 = 1 + while `j2' <= 2{ + * disp "it1 = `it1' and it2 = `it2'" + matrix `x'[1,`it2'] = (-1)^`j2'*`t' + matrix `X' = `X'\ `x' + matrix `y' = `y', `D' + matrix `x'[1,`it2'] = 0 + local j2 = `j2' + 1 + } + local it2 = `it2' + 1 + } + matrix `x'[1,`it1'] = 0 + local j1 = `j1' + 1 + + } + local it1 = `it1' + 1 + } + +* Do s and C + matrix `x' = J(1,`n',`s') + matrix `im' = J(1,`n'+1,0) + matrix `im'[1,1] = 1 + + local pm = `n'+1 + while `pm' <= `n'+1{ + /* set previous digits to 0 */ + while `pm'>1{ + matrix `x'[1,`pm'-1] = `s' + matrix `im'[1,`pm'] = 0 + local pm = `pm' - 1 + } + matrix `X' = `X'\ `x' + matrix `y' = `y', `C' + * matrix list `im' + + local pm = 1 + while `im'[1,`pm'] == 1{ + local pm = `pm' + 1 + } + * disp "pm = " `pm' + /* pm is first incomplete digit */ + if `pm'<= `n' + 1{ + matrix `im'[1,`pm'] = 1 + matrix `x'[1,`pm'-1] = -`s' + local pm = `pm' - 1 + } + } + + *matrix list `X' + *matrix list `y' + matrix M_zlc`num' = `X'*`r1'\ `X'*`r2' + matrix M_zlc`num' = M_zlc`num'' + matrix `a'= J(1,`num'/2,`A1'),J(1,`num'/2,`A2') + matrix M_zps`num' = `y',`y' + matrix M_zps`num' = M_zps`num'+`a' + global S_1 = `num' + } /* end else */ +end + + +program define spher2 +version 6.0 +*p. 324, 7-1 + tempname r s t A B C x + capture matrix drop M_zlc12 + capture matrix drop M_zps12 + + scalar `r' = sqrt(6) + scalar `s' = sqrt((9-3*sqrt(5))/4) + scalar `t' = sqrt((9+3*sqrt(5))/4) + scalar `A' = ln(1/36) + scalar `B' = ln(5 + 2*sqrt(5)) - ln(45) + scalar `C' = ln(5 - 2*sqrt(5)) - ln(45) + +*r + matrix `x' = J(1,2,0) + local ir = 1 + while `ir' <= 2{ + local j = 1 + while `j' <= 2{ + matrix `x'[1,`ir'] = (-1)^`j'*`r' + matrix M_zlc12 = nullmat(M_zlc12)\ `x' + matrix M_zps12 = nullmat(M_zps12), `A' + matrix `x'[1,`ir'] = 0 + local j = `j' + 1 + } + local ir = `ir' + 1 + } + +*t + matrix `x' = J(1,2,`t') + matrix M_zlc12 = M_zlc12\ `x' + matrix M_zps12 = M_zps12, `C' + local m = 1 /* number of - */ + while `m' <= 2{ + local i = 1 /* pos of first - */ + while `i'<= 2{ + matrix `x'[1,`i'] = -`t' + local j = `i' + 1 + if `m'>1{ + while `j' <= 2 { + matrix `x'[1,`j'] = -`t' + matrix M_zlc12 = M_zlc12\ `x' + matrix M_zps12 = M_zps12, `C' + matrix `x'[1,`j'] = `t' + local j = `j' + 1 + } + } + else{ + matrix M_zlc12 = M_zlc12\ `x' + matrix M_zps12 = M_zps12, `C' + } + matrix `x'[1, `i'] = `t' + local i = `i' + 1 + } + local m = `m' + 1 + } + +* s + matrix `x' = J(1,2,`s') + matrix M_zps12 = M_zps12, `B' + matrix M_zlc12 = M_zlc12\ `x' + + local m = 1 /* number of - */ + while `m' <= 2{ + local i = 1 /* pos of first - */ + while `i'<= 2{ + matrix `x'[1,`i'] = -`s' + local j = `i' + 1 + if `m'>1{ + while `j' <= 2 { + matrix `x'[1,`j'] = -`s' + matrix M_zlc12 = M_zlc12\ `x' + matrix M_zps12 = M_zps12, `B' + matrix `x'[1,`j'] = `s' + local j = `j' + 1 + } + } + else{ + matrix M_zlc12 = M_zlc12\ `x' + matrix M_zps12 = M_zps12, `B' + } + matrix `x'[1, `i'] = `s' + local i = `i' + 1 + } + local m = `m' + 1 + } + matrix M_zlc12 = M_zlc12' + global S_1 = 12 +end + +program define spher3 + version 6.0 +* Stroud (1971) p. 327, E_3^{r^2} 7-1 + args n + tempname r s t A B C D x im + local num = 27 + capture matrix drop M_zlc27 + capture matrix drop M_zps27 + + scalar `r' = sqrt((15 + sqrt(15))/2) + scalar `s' = sqrt(6 - sqrt(15)) + scalar `t' = sqrt(9 + 2*sqrt(15)) + scalar `A' = ln(720 + 8*sqrt(15)) - ln(2205) + scalar `B' = ln(270 - 46*sqrt(15)) - ln(15435) + scalar `C' = ln(162 + 41*sqrt(15)) - ln(6174) + scalar `D' = ln(783 - 202*sqrt(15)) - ln(24696) + + local n = 3 +* D + matrix `x' = J(1,`n',`t') + matrix `im' = J(1,`n'+1,0) + matrix `im'[1,1] = 1 + + local pm = `n'+1 + while `pm' <= `n'+1{ + /* set previous digits to 0 */ + while `pm'>1{ + matrix `x'[1,`pm'-1] = `t' + matrix `im'[1,`pm'] = 0 + local pm = `pm' - 1 + } + matrix M_zlc`num' = nullmat(M_zlc`num')\ `x' + matrix M_zps`num' = nullmat(M_zps`num'), `D' + * matrix list `im' + + local pm = 1 + while `im'[1,`pm'] == 1{ + local pm = `pm' + 1 + } + * disp "pm = " `pm' + /* pm is first incomplete digit */ + if `pm'<= `n' + 1{ + matrix `im'[1,`pm'] = 1 + matrix `x'[1,`pm'-1] = -`t' + local pm = `pm' - 1 + } + } + +* B + matrix `x' = J(1,`n',0) + local ir = 1 + while `ir' <= `n'{ + local j = 1 + while `j' <= 2{ + matrix `x'[1,`ir'] = (-1)^`j'*`r' + matrix M_zlc`num' = M_zlc`num'\ `x' + matrix M_zps`num' = M_zps`num',`B' + matrix `x'[1,`ir'] = 0 + local j = `j' + 1 + } + local ir = `ir' + 1 + } + +* C + matrix `x' = J(1,`n',0) + local is1 = 1 + while `is1' <= `n'{ + local j1 = 1 + while `j1' <= 2{ + matrix `x'[1,`is1'] = (-1)^`j1'*`s' + local is2 = `is1' + 1 + while `is2' <= `n'{ + local j2 = 1 + while `j2' <= 2{ + * disp "is1 = `is1' and is2 = `is2'" + matrix `x'[1,`is2'] = (-1)^`j2'*`s' + matrix M_zlc`num' = M_zlc`num'\ `x' + matrix M_zps`num' = M_zps`num',`C' + matrix `x'[1,`is2'] = 0 + local j2 = `j2' + 1 + } + local is2 = `is2' + 1 + } + matrix `x'[1,`is1'] = 0 + local j1 = `j1' + 1 + + } + local is1 = `is1' + 1 + } +* A + matrix M_zps`num' = M_zps`num',`A' + matrix `x' = J(1,`n',0) + matrix M_zlc`num' = M_zlc`num'\ `x' + matrix M_zlc`num' = M_zlc`num'' + global S_1 = `num' +end + + +program define spher4 + version 6.0 +* Stroud (1971) p. 329, E_4^{r^2} 7-1 + args n + tempname r s t A B C D x im + local num = 49 + capture matrix drop M_zlc`num' + capture matrix drop M_zps`num' + + scalar `s' = sqrt(3 - sqrt(3)) + scalar `r' = 2*`s' + scalar `t' = sqrt(6 + 2*sqrt(3)) + scalar `A' = -ln(4) + scalar `B' = ln(9 + 5*sqrt(3)) - ln(576) + scalar `C' = ln(9 + -5*sqrt(3)) - ln(576) + + local n = 4 +* C and t + matrix `x' = J(1,`n',0) + local is1 = 1 + while `is1' <= `n'{ + local j1 = 1 + while `j1' <= 2{ + matrix `x'[1,`is1'] = (-1)^`j1'*`t' + local is2 = `is1' + 1 + while `is2' <= `n'{ + local j2 = 1 + while `j2' <= 2{ + * disp "is1 = `is1' and is2 = `is2'" + matrix `x'[1,`is2'] = (-1)^`j2'*`t' + matrix M_zlc`num' = nullmat(M_zlc`num')\ `x' + matrix M_zps`num' = nullmat(M_zps`num'),`C' + matrix `x'[1,`is2'] = 0 + local j2 = `j2' + 1 + } + local is2 = `is2' + 1 + } + matrix `x'[1,`is1'] = 0 + local j1 = `j1' + 1 + + } + local is1 = `is1' + 1 + } + +* B and s + matrix `x' = J(1,`n',`s') + matrix `im' = J(1,`n'+1,0) + matrix `im'[1,1] = 1 + + local pm = `n'+1 + while `pm' <= `n'+1{ + /* set previous digits to 0 */ + while `pm'>1{ + matrix `x'[1,`pm'-1] = `s' + matrix `im'[1,`pm'] = 0 + local pm = `pm' - 1 + } + matrix M_zlc`num' = nullmat(M_zlc`num')\ `x' + matrix M_zps`num' = nullmat(M_zps`num'), `B' + * matrix list `im' + + local pm = 1 + while `im'[1,`pm'] == 1{ + local pm = `pm' + 1 + } + * disp "pm = " `pm' + /* pm is first incomplete digit */ + if `pm'<= `n' + 1{ + matrix `im'[1,`pm'] = 1 + matrix `x'[1,`pm'-1] = -`s' + local pm = `pm' - 1 + } + } + +* B and r + matrix `x' = J(1,`n',0) + local ir = 1 + while `ir' <= `n'{ + local j = 1 + while `j' <= 2{ + matrix `x'[1,`ir'] = (-1)^`j'*`r' + matrix M_zlc`num' = M_zlc`num'\ `x' + matrix M_zps`num' = M_zps`num',`B' + matrix `x'[1,`ir'] = 0 + local j = `j' + 1 + } + local ir = `ir' + 1 + } +* A + matrix M_zps`num' = M_zps`num',`A' + matrix `x' = J(1,`n',0) + matrix M_zlc`num' = M_zlc`num'\ `x' + matrix M_zlc`num' = M_zlc`num'' + global S_1 = `num' +end + + +capture program drop spher6 +program define spher6 +* Stroud 7-1 (p. 318) + tempname r s t B C D A x X y a norm im + + local n = 6 + local num = 2^`n' + 2*`n'^2 + 1 + + capture matrix drop M_zlc`num' + capture matrix drop M_zps`num' +/* + scalar `r' = sqrt( (3*(8-`n')-(`n'-2)*sqrt(3*(8-`n')))/(2*(5-`n')) ) + scalar `s' = sqrt( (3*`n' - 2*sqrt(3*(8-`n')))/(2*(3*`n' - 8)) ) + scalar `t' = sqrt( (6+sqrt(3*(8-`n')))/2 ) + scalar `B' = (8-`n')/( 8*`r'^6) *2/exp(lngamma(`n'/2)) + scalar `C' = 1 /( 2^(`n'+3)*`s'^6) *2/exp(lngamma(`n'/2)) + scalar `D' = 1/(16*`t'^6) *2/exp(lngamma(`n'/2)) + scalar `A' = 2/exp(lngamma(`n'/2)) - 2*`n'*`B' - 2^`n'*`C' - 2*`n'*(`n'-1)*`D' + disp in re "r = " `r' " s = " `s' " t = " `t' + disp in re "A = " `A' " B = " `B' " C = " `C' " D = " `D' +*/ + +* - - + + scalar `r' = sqrt( (3*(8-`n')-(`n'-2)*sqrt(3*(8-`n')))/(5-`n') ) + scalar `s' = sqrt( (3*`n' - 2*sqrt(3*(8-`n')))/(3*`n' - 8) ) + scalar `t' = sqrt( 6+sqrt(3*(8-`n')) ) + scalar `B' = ln(8-`n') - ln(8) - 6*( ln(`r') - ln(2)/2 ) + ln(2) - lngamma(`n'/2) + scalar `C' = -(`n'+ 3)*ln(2)-6*( ln(`s') - ln(2)/2 ) + ln(2) - lngamma(`n'/2) + scalar `D' = -ln(16) - 6*( ln(`t') - ln(2)/2 ) + ln(2) - lngamma(`n'/2) + scalar `A' = ln( 2/exp(lngamma(`n'/2)) - 2*`n'*exp(`B') - 2^`n'*exp(`C') - 2*`n'*(`n'-1)*exp(`D') ) + *disp in re "r = " `r' " s = " `s' " t = " `t' + *disp in re "A = " `A' " B = " `B' " C = " `C' " D = " `D' + + + +* A + matrix `X' = J(1,`n',0) + matrix `y' = (`A') + +* Do r and B + matrix `x' = J(1,`n',0) + local ir = 1 + while `ir' <= `n'{ + local j = 1 + while `j' <= 2 { + matrix `x'[1,`ir'] = (-1)^`j'*`r' + matrix `X' = nullmat(`X')\ `x' + matrix `y' = nullmat(`y'),`B' + matrix `x'[1,`ir'] = 0 + local j = `j' + 1 + } + local ir = `ir' + 1 + } + +* Do t and D + matrix `x' = J(1,`n',0) + local it1 = 1 + while `it1' <= `n'{ + local j1 = 1 + while `j1' <= 2{ + matrix `x'[1,`it1'] = (-1)^`j1'*`t' + local it2 = `it1' + 1 + while `it2' <= `n'{ + local j2 = 1 + while `j2' <= 2{ + * disp "it1 = `it1' and it2 = `it2'" + matrix `x'[1,`it2'] = (-1)^`j2'*`t' + matrix `X' = `X'\ `x' + matrix `y' = `y', `D' + matrix `x'[1,`it2'] = 0 + local j2 = `j2' + 1 + } + local it2 = `it2' + 1 + } + matrix `x'[1,`it1'] = 0 + local j1 = `j1' + 1 + + } + local it1 = `it1' + 1 + } + +* Do s and C + matrix `x' = J(1,`n',`s') + matrix `im' = J(1,`n'+1,0) + matrix `im'[1,1] = 1 + + local pm = `n'+1 + while `pm' <= `n'+1{ + /* set previous digits to 0 */ + while `pm'>1{ + matrix `x'[1,`pm'-1] = `s' + matrix `im'[1,`pm'] = 0 + local pm = `pm' - 1 + } + matrix `X' = `X'\ `x' + matrix `y' = `y', `C' + * matrix list `im' + + local pm = 1 + while `im'[1,`pm'] == 1{ + local pm = `pm' + 1 + } + * disp "pm = " `pm' + /* pm is first incomplete digit */ + if `pm'<= `n' + 1{ + matrix `im'[1,`pm'] = 1 + matrix `x'[1,`pm'-1] = -`s' + local pm = `pm' - 1 + } + } + + matrix M_zlc`num' = `X' + matrix M_zps`num' = `y' + matrix M_zlc`num' = M_zlc`num'' + global S_1 = `num' +end + + +program define fsrs + version 6.0 + args r s x n + if abs(`s')<1e-10&abs(`r')<1e-10{ + matrix `x' = (0,0) + scalar `n' = 1 + } + else if abs(`s')<1e-10{ + matrix `x' = (`r',0\ -`r',0\ 0,`r'\ 0,-`r') + scalar `n' = 4 + } + else if abs(`r'-`s')<1e-10{ + matrix `x' = (`r',`s'\ -`r',`s'\ `r',-`s'\ -`r',-`s') + scalar `n' = 4 + } + else{ + matrix `x' = (`r',`s'\ -`r',`s'\ `r',-`s'\ -`r',-`s'\ `s',`r'\ -`s',`r'\ `s',-`r'\ -`s',-`r') + scalar `n' = 8 + } +end + +program define int2k + version 6.0 + args k + if `k' == 9{ + *E_2^{r^2}: 9-1 + local l = 4 + local num = 20 + tempname r1 r2 r3 r4 s1 s2 s3 s4 B1 B2 B3 B4 +/* + scalar `r1' = 1.538189001320852*sqrt(2) + scalar `r2' = 1.224744871391589*sqrt(2) + scalar `r3' = 0.4817165220011443*sqrt(2) + scalar `r4' = 2.607349811958554*sqrt(2) + scalar `s4' = 0.9663217712794149*sqrt(2) + scalar `s1' = 0 + scalar `s2' = `r2' + scalar `s3' = `r3' + scalar `B1' = ln(0.1237222328857347) - ln(_pi) + scalar `B2' = ln(0.06544984694978697) - ln(_pi) + scalar `B3' = ln(0.5935280476180875) - ln(_pi) + scalar `B4' = ln(0.001349017971918148) - ln(_pi) +*/ + scalar `r3' = 1.538189001320852*sqrt(2) + scalar `r2' = 1.224744871391589*sqrt(2) + scalar `r4' = 0.4817165220011443*sqrt(2) + scalar `r1' = 2.607349811958554*sqrt(2) + scalar `s1' = 0.9663217712794149*sqrt(2) + scalar `s3' = 0 + scalar `s2' = `r2' + scalar `s4' = `r4' + scalar `B3' = ln(0.1237222328857347) - ln(_pi) + scalar `B2' = ln(0.06544984694978697) - ln(_pi) + scalar `B4' = ln(0.5935280476180875) - ln(_pi) + scalar `B1' = ln(0.001349017971918148) - ln(_pi) + } + if `k' == 11{ + *E_2^{r^2}: 11-1 + local l = 5 + local num = 28 + tempname r1 r2 r3 r4 r5 s1 s2 s3 s4 s5 B1 B2 B3 B4 B5 +/* + scalar `r1' = 2.757816396257008*sqrt(2) + scalar `r2' = 1.732050807568877*sqrt(2) + scalar `r3' = 0.6280515301597559*sqrt(2) + scalar `r4' = 1.224744871391589*sqrt(2) + scalar `r5' = 0.7071067811865475*sqrt(2) + scalar `s4' = 2.121320343559643*sqrt(2) + scalar `s5' = 1.224744871391589*sqrt(2) + scalar `s1' = 0 + scalar `s2' = 0 + scalar `s3' = 0 + scalar `B1' = ln(0.0008176645817675417) - ln(_pi) + scalar `B2' = ln(0.04363323129985824) - ln(_pi) + scalar `B3' = ln(0.5373255214498174) - ln(_pi) + scalar `B4' = ln(0.003636102608321520) - ln(_pi) + scalar `B5' = ln(0.09817477042468103) - ln(_pi) +*/ + scalar `r1' = 2.757816396257008*sqrt(2) + scalar `r3' = 1.732050807568877*sqrt(2) + scalar `r5' = 0.6280515301597559*sqrt(2) + scalar `r2' = 1.224744871391589*sqrt(2) + scalar `r4' = 0.7071067811865475*sqrt(2) + scalar `s2' = 2.121320343559643*sqrt(2) + scalar `s4' = 1.224744871391589*sqrt(2) + scalar `s1' = 0 + scalar `s3' = 0 + scalar `s5' = 0 + scalar `B1' = ln(0.0008176645817675417) - ln(_pi) + scalar `B3' = ln(0.04363323129985824) - ln(_pi) + scalar `B5' = ln(0.5373255214498174) - ln(_pi) + scalar `B2' = ln(0.003636102608321520) - ln(_pi) + scalar `B4' = ln(0.09817477042468103) - ln(_pi) + } + if `k' == 15{ + *E_2^{r^2}: 15-1 + local l = 9 + local num = 44 + tempname r1 r2 r3 r4 r5 r6 r7 r8 r9 s1 s2 s3 s4 s5 s6 s7 s8 s9 B1 B2 B3 B4 B5 B6 B7 B8 B9 +/* + scalar `r1' = 3.538388728121807*sqrt(2) + scalar `r2' = 2.359676416877929*sqrt(2) + scalar `r3' = 1.312801844620926*sqrt(2) + scalar `r4' = 0.5389559482114205*sqrt(2) + scalar `r5' = 2.300279949805658*sqrt(2) + scalar `r6' = 1.581138830084189*sqrt(2) + scalar `r7' = 0.8418504335819279*sqrt(2) + scalar `r8' = 2.685533581755341*sqrt(2) + scalar `r9' = 1.740847514397403*sqrt(2) + scalar `s8' = 1.112384431771456*sqrt(2) + scalar `s9' = 0.7210826504868960*sqrt(2) + scalar `s1' = 0 + scalar `s2' = 0 + scalar `s3' = 0 + scalar `s4' = 0 + scalar `s5' = `r5' + scalar `s6' = `r6' + scalar `s7' = `r7' + scalar `B1' = ln(0.000008006483569659628) - ln(_pi) + scalar `B2' = ln(0.003604577420838264) - ln(_pi) + scalar `B3' = ln(0.1187609330759137) - ln(_pi) + scalar `B4' = ln(0.4372488543791402) - ln(_pi) + scalar `B5' = ln(0.00003671735075832989) - ln(_pi) + scalar `B6' = ln(0.005654866776461627) - ln(_pi) + scalar `B7' = ln(0.1777774268424240) - ln(_pi) + scalar `B8' = ln(0.0002735449647853290) - ln(_pi) + scalar `B9' = ln(0.02087984556938594) - ln(_pi) +*/ + scalar `r1' = 3.538388728121807*sqrt(2) + scalar `r4' = 2.359676416877929*sqrt(2) + scalar `r7' = 1.312801844620926*sqrt(2) + scalar `r9' = 0.5389559482114205*sqrt(2) + scalar `r2' = 2.300279949805658*sqrt(2) + scalar `r5' = 1.581138830084189*sqrt(2) + scalar `r8' = 0.8418504335819279*sqrt(2) + scalar `r3' = 2.685533581755341*sqrt(2) + scalar `r6' = 1.740847514397403*sqrt(2) + scalar `s3' = 1.112384431771456*sqrt(2) + scalar `s6' = 0.7210826504868960*sqrt(2) + scalar `s1' = 0 + scalar `s4' = 0 + scalar `s7' = 0 + scalar `s9' = 0 + scalar `s2' = `r2' + scalar `s5' = `r5' + scalar `s8' = `r8' + scalar `B1' = ln(0.000008006483569659628) - ln(_pi) + scalar `B4' = ln(0.003604577420838264) - ln(_pi) + scalar `B7' = ln(0.1187609330759137) - ln(_pi) + scalar `B9' = ln(0.4372488543791402) - ln(_pi) + scalar `B2' = ln(0.00003671735075832989) - ln(_pi) + scalar `B5' = ln(0.005654866776461627) - ln(_pi) + scalar `B8' = ln(0.1777774268424240) - ln(_pi) + scalar `B3' = ln(0.0002735449647853290) - ln(_pi) + scalar `B6' = ln(0.02087984556938594) - ln(_pi) + } + tempname x n + capture matrix drop M_zlc`num' + local i = 1 + while `i'<=`l'{ + fsrs `r`i'' `s`i'' `x' `n' + * matrix list `x' + matrix M_zlc`num' = nullmat(M_zlc`num')\ `x' + matrix `x' = J(1,`n',`B`i'') + matrix M_zps`num' = nullmat(M_zps`num'), `x' + local i = `i' + 1 + } + matrix M_zlc`num' = M_zlc`num'' + global S_1 = `num' +end + +program define multn +version 6.0 +* Stroud (1971) p. 317, 5-2 + args n + tempname r s A B C x + local num = 2*`n'^2 + 1 + + capture matrix drop M_zlc`num' + capture matrix drop M_zps`num' + + scalar `r' = sqrt((`n'+2)) + scalar `s' = sqrt((`n'+2)/2) + scalar `A' = ln(2) - ln(`n'+2) + scalar `B' = ln(4-`n')-ln(2) -2*ln(`n'+2) + scalar `C' = -2*ln(`n'+2) + + matrix M_zps`num' = (`A') + matrix `x' = J(1,`n',0) + matrix M_zlc`num' = `x' + local ir = 1 + while `ir' <= `n'{ + local j = 1 + while `j' <= 2{ + matrix `x'[1,`ir'] = (-1)^`j'*`r' + matrix M_zlc`num' = M_zlc`num'\ `x' + matrix M_zps`num' = M_zps`num',`B' + matrix `x'[1,`ir'] = 0 + local j = `j' + 1 + } + local ir = `ir' + 1 + } + + local is1 = 1 + while `is1' <= `n'{ + local j1 = 1 + while `j1' <= 2{ + matrix `x'[1,`is1'] = (-1)^`j1'*`s' + local is2 = `is1' + 1 + while `is2' <= `n'{ + local j2 = 1 + while `j2' <= 2{ + * disp "is1 = `is1' and is2 = `is2'" + matrix `x'[1,`is2'] = (-1)^`j2'*`s' + matrix M_zlc`num' = M_zlc`num'\ `x' + matrix M_zps`num' = M_zps`num',`C' + matrix `x'[1,`is2'] = 0 + local j2 = `j2' + 1 + } + local is2 = `is2' + 1 + } + matrix `x'[1,`is1'] = 0 + local j1 = `j1' + 1 + + } + local is1 = `is1' + 1 + } + matrix M_zlc`num' = M_zlc`num'' + global S_1 = `num' +end + +program define ghquad +* stolen from rfprobit (Bill Sribney) + version 4.0 + local n `1' + tempname xx ww a b + local i 1 + local m = int((`n' + 1)/2) + matrix M_zlc`n' = J(1,`m',0) + matrix M_zps`n' = M_zlc`n' + while `i' <= `m' { + if `i' == 1 { + scalar `xx' = sqrt(2*`n'+1)-1.85575*(2*`n'+1)^(-1/6) + } + else if `i' == 2 { scalar `xx' = `xx'-1.14*`n'^0.426/`xx' } + else if `i' == 3 { scalar `xx' = 1.86*`xx'-0.86*M_zlc`n'[1,1] } + else if `i' == 4 { scalar `xx' = 1.91*`xx'-0.91*M_zlc`n'[1,2] } + else { + local im2 = `i' -2 + scalar `xx' = 2*`xx'-M_zlc`n'[1,`im2'] + } + hermite `n' `xx' `ww' + matrix M_zlc`n'[1,`i'] = `xx' + matrix M_zps`n'[1,`i'] = ln(`ww') - ln(_pi)/2 + local i = `i' + 1 + } + if mod(`n', 2) == 1 { matrix M_zlc`n'[1,`m'] = 0} +/* start in tails */ + matrix `b' = (1,1) + matrix M_zps`n' = M_zps`n'#`b' + matrix M_zps`n' = M_zps`n'[1,1..`n'] + matrix `b' = (1,-1) + matrix M_zlc`n' = M_zlc`n'#`b' + matrix M_zlc`n' = M_zlc`n'[1,1..`n'] + +/* other alternative (start in centre) */ +/* + matrix `b' = J(1,`n',0) + local i = 1 + while ( `i'<=`n'){ + matrix `b'[1, `i'] = M_zlc`n'[1, `n'+1-`i'] + local i = `i' + 1 + } + matrix M_zlc`n' = `b' + local i = 1 + while ( `i'<=`n'){ + matrix `b'[1, `i'] = M_zps`n'[1, `n'+1-`i'] + local i = `i' + 1 + } + matrix M_zps`n' = `b' +*/ +/* end other alternative */ + matrix M_zlc`n' = M_zlc`n'* sqrt(2) +end + + +program define hermite /* integer n, scalar x, scalar w */ +* stolen from rfprobit (Bill Sribney) + version 4.0 + local n "`1'" + local x "`2'" + local w "`3'" + local last = `n' + 2 + tempname i p + matrix `p' = J(1,`last',0) + scalar `i' = 1 + while `i' <= 10 { + matrix `p'[1,1]=0 + matrix `p'[1,2] = _pi^(-0.25) + local k = 3 + while `k'<=`last'{ + matrix `p'[1,`k'] = `x'*sqrt(2/(`k'-2))*`p'[1,`k'-1] /* + */ - sqrt((`k'-3)/(`k'-2))*`p'[1,`k'-2] + local k = `k' + 1 + } + scalar `w' = sqrt(2*`n')*`p'[1,`last'-1] + scalar `x' = `x' - `p'[1,`last']/`w' + if abs(`p'[1,`last']/`w') < 3e-14 { + scalar `w' = 2/(`w'*`w') + exit + } + scalar `i' = `i' + 1 + } + di in red "hermite did not converge" + exit 499 +end + + +program define lebesque + version 5.0 + local n `1' + tempname pt a b + scalar `a' = 1/`n' + matrix M_zps`n' = J(1,`n',`a') + local i = 1 + local m = int((`n' + 1)/2) + matrix M_zlc`n' = J(1,`m',0) + while(`i'<=`m'){ + scalar `pt' = `i'/`n' -1/(2*`n') + matrix M_zlc`n'[1,`i']=invnorm(`pt') + local i = `i' + 1 + } +/* start in tails */ + matrix `b' = (1,-1) + matrix M_zlc`n' = M_zlc`n'#`b' + matrix M_zlc`n' = M_zlc`n'[1,1..`n'] +/* other alternative: left to right */ +/* + while ( `i'<=`n'){ + matrix M_zlc`n'[1, `i'] = -M_zlc`n'[1, `n'+1-`i'] + local i = `i' + 1 + } +*/ +end + +program define disprand +version 6.0 +* displays additional information about random effects +* disp "running disprand " +disp " " +if "e(tplv)" == ""{ + * estimates not found + exit +} +tempname var b se cor mn0 mm0 +matrix `b' = e(b) +local names: colnames(`b') +tempname M_nrfc M_nip M_nbrf M_nffc M_b V M_frld + +matrix `V' = e(V) +matrix `M_nrfc' = e(nrfc) +matrix `M_nip' = e(nip) +matrix `M_nbrf' = e(nbrf) +matrix `M_nffc' = e(nffc) +matrix `M_frld' = e(frld) +local ngeqs = e(ngeqs) +local bmat = e(bmat) +if `bmat' ==1{matrix `M_b' = e(mb)} +local bmat = e(bmat) +local iscor = e(cor) +local nxt = `M_nffc'[1,colsof(`M_nffc')]+1 +local free = e(free) +local tplv = e(tplv) +local lev1 = e(lev1) +local tprf = e(tprf) +local cip = e(cip) +local nats = e(nats) +if `free'{ + tempname M_np + matrix `M_np' = e(mnp) +} + +local nrfold = `M_nrfc'[2,1] +if `M_nbrf'[1,1]>0{ + if `lev1' == 1 {disp in gr "Variance at level 1"} + else if `lev1' == 2 {disp in gr "Squared Coefficient of Variation"} + else if `lev1' == 3 {disp in gr "Dispersion at level 1"} + *disp in smcl in gr "{hline 78}" _n + di in gr _dup(78) "-" _n + if `M_nbrf'[1,1]==1{ + if `nats'{ + scalar `var' = `b'[1, `nxt']^2 + scalar `se' = 2*sqrt(`var'*`V'[`nxt',`nxt']) + disp in gr " " in ye `var' " (" `se' ")" + } + else{ + scalar `var' = exp(2*`b'[1, `nxt']) + scalar `se' = 2*`var'*sqrt(`V'[`nxt',`nxt']) + disp in gr " " in ye `var' " (" `se' ")" + } + local nxt = `nxt' + 1 + } + else{ + local log "log " + if `nats'{ + local log + } + disp " " + if `lev1'==1{disp in gr " equation for `log'standard deviation: "} + else if `lev1'==2{disp in gr " equation for `log'coefficient of variation"} + else if `lev1'==3{disp in gr " equation for `log'(sqrt(phi))"} + disp " " + local i = 1 + while `i' <= `M_nbrf'[1,1]{ + scalar `var' = `b'[1,`nxt'] + scalar `se' = sqrt(`V'[`nxt',`nxt']) + local nna: word `nxt' of `names' + disp in gr " `nna': " in ye `var' " (" `se' ")" + local i = `i' + 1 + local nxt = `nxt' + 1 + } + } +} + +if `tplv' > 1{ +local lev = 2 +if `free' == 1{ + disp " " + disp in gr "Probabilities and locations of random effects" +} +else{ + disp " " + disp in gr "Variances and covariances of random effects" +} +*disp in smcl in gr "{hline 78}" _n +di in gr _dup(78) "-" _n +*disp in gr "-----------------------------------------------------------------------------" +while (`lev' <= `tplv'){ + local nip = `M_nip'[1,`lev'] + local sof = `M_nrfc'[2,`lev'-1] /* `M_nrfc'[1,`lev'-1] */ + disp " " + local cl = `tplv' - `lev' + 1 + local cl: word `cl' of `e(clus)' + disp in gr "***level `lev' (" in ye "`cl'" in gr ")" + if `free' == 1{ + tempname M_zps`lev' + matrix `M_zps`lev'' = e(zps`lev') + } + local i2 = `M_nrfc'[2,`lev'] + local i1 = `nrfold'+1 + local num = `i2' -`i1' + 1 /* number of random effects */ + if `free'==0{ + * get standard errors of variances from those of cholesky decomp. + *disp "sechol `lev' `num' `nxt'" + qui sechol `lev' `num' `nxt' + } + local k = 1 + local i = `i1' + local ii = 1 + local nrfold = `M_nrfc'[2,`lev'] + while `i'<= `i2'{ + local n=`M_nip'[2,`i'] + if `free'==1{ + tempname M_zlc`n' + matrix `M_zlc`n'' = e(zlc`n') + local j = 2 + local zz=string(`M_zlc`n''[1,1],"%7.0gc") + local mm "`zz'" + scalar `mn0' = `M_zlc`n''[1,1]*exp(`M_zps`lev''[1,1]) + while `j'<=`nip'{ + scalar `mn0' = `mn0' + `M_zlc`n''[1,`j']*exp(`M_zps`lev''[1,`j']) + local zz=string(`M_zlc`n''[1,`j'],"%7.0gc") + local mm "`mm'" ", " "`zz'" + local j = `j' + 1 + } + disp " " + disp in gr " loc`ii': " in ye "`mm'" + } + local j = `i1' + local jj = 1 + while (`j'<=`i'){ + if `free'==1{ + local m = `M_nip'[2,`j'] + capture tempname M_zlc`m' + matrix `M_zlc`m'' = e(zlc`m') + scalar `mm0'=0 + local mm = 1 + while `mm'<=`nip'{ + scalar `mm0' = `mm0' + `M_zlc`m''[1,`mm']*exp(`M_zps`lev''[1,`mm']) + local mm = `mm' + 1 + } + + local l = 1 + scalar `var' = 0 + while `l'<=`nip'{ + scalar `var' = `var' + /* + */ (`M_zlc`n''[1,`l']-`mn0')*(`M_zlc`m''[1,`l']-`mm0')*exp(`M_zps`lev''[1,`l']) + local l = `l' + 1 + } + if `i' == `j'{ + disp in gr " var(`ii'): " in ye `var' + local nb = `M_nbrf'[1,`ii'+`sof'] + if `nb'>1{ + disp " " + disp in gr " loadings for random effect " `ii' + local load = `nxt' + `nb' - 1 + if `M_frld'[1,`j']==0{ + local nna: word `load' of `names' + disp in gr " `nna': " in ye 1 " (fixed)" + } + + *disp in gr " coefficient of" + local load = 1 + while `load'<=`nb'-1{ + local nna: word `nxt' of `names' + scalar `var'=`b'[1,`nxt'] + scalar `se' = sqrt(`V'[`nxt',`nxt']) + disp in gr " `nna': " in ye `var' " (" `se' ")" + local nxt = `nxt' + 1 + local load = `load' + 1 + } + disp " " + } + local nxt = `nxt' + 1 /* skip location parameter */ + * disp "increased nxt to" `nxt' + if `i'==`i2'{ + local l = 2 + local zz=string(exp(`M_zps`lev''[1,1]),"%6.0gc") + if `nip'>1{ + local mm "0`zz'" + } + else{ + local mm "1" + } + + while `l'<=`nip'{ + local zz=string(exp(`M_zps`lev''[1,`l']),"%6.0gc") + local mm "`mm'" ", " "0`zz'" + local l = `l' + 1 + } + disp in gr " prob: " in ye "`mm'" + + *new + *** display log odds with standard errors + local npar = `M_np'[1,`lev'] + if `npar' == 0 { local npar = 1} + if `npar'>1{ + disp " " + disp in gr " log odds parameters" + } + local l = 1 + while `l'< `nip'{ + if `npar'>1{ + if `l'>1 { + disp " " + } + disp in gr " class `l'" + } + local load = 1 + local ncur = `nxt' + (`l' - 1)*`num' + (`l' - 1)*`npar' - 1 + while `load'<=`npar'{ + local ncur = `ncur' + 1 + * disp "nxt = `nxt', nb = `nb', num = `num' and ncur = `ncur'" + local nna: word `ncur' of `names' + scalar `var'=`b'[1,`ncur'] + scalar `se' = sqrt(`V'[`ncur',`ncur']) + if `npar'>1{ + disp in gr " `nna': " in ye `var' " (" `se' ")" + } + local load = `load' + 1 + } + local l = `l' + 1 + } + local nxt = `ncur' + 1 + } +* end new + } + else{ + disp in gr "cov(`ii',`jj'): " in ye `var' + } + } + else{/* free=0 */ + * disp "k= " `k' ", i= " `i' ", j= " `j' ", ii= " `ii' ", jj= " `jj' + + scalar `var' = M_cov[`ii', `jj'] + scalar `se' = sqrt(M_se[`k', `k']) + if `i' == `j'{ + disp " " + disp in gr " var(`ii'): " in ye `var' " (" `se' ")" + local nb = `M_nbrf'[1,`ii'+`sof'] + if `nb'>1{ + disp " " + disp in gr " loadings for random effect " `ii' + local load = `nxt' + `nb' -1 + if `M_frld'[1,`j']==0{ + local nna: word `load' of `names' + disp in gr " `nna': " in ye 1 " (fixed)" + } + + * disp in gr " coefficient of" + local load = 1 + while `load'<=`nb'-1{ + local nna: word `nxt' of `names' + * disp "nxt = " `nxt' + scalar `var'=`b'[1,`nxt'] + scalar `se' = sqrt(`V'[`nxt',`nxt']) + disp in gr " `nna': " in ye `var' " (" `se' ")" + local nxt = `nxt' + 1 + local load = `load' + 1 + } + disp " " + } + * skip variance parameter + local nxt = `nxt' + 1 + } + else{ + if `iscor'==0{ + disp in gr " cov(`ii',`jj'): " in ye "fixed at 0" + } + else{ + scalar `cor' = `var'/sqrt(M_cov[`ii',`ii']*M_cov[`jj',`jj']) + disp in gr " cov(`ii',`jj'): " in ye `var' " (" `se' ")" /* + */ " cor(`ii',`jj'): " `cor' + *local nxt = `nxt' + 1 + } + } + } + + local j = `j' + 1 + local jj = `jj' + 1 + local k = `k' + 1 + } + local i = `i' + 1 + local ii = `ii' + 1 + } +local lev = `lev' + 1 +/* skip off-diagonal cholesky parameters */ +if `iscor'~=0&`free'==0{local nxt = `nxt' + `num'*(`num'-1)/2} /* -1? */ +*disp "next nxt is " `nxt' +/* +if `free'{ + local nxt = `nxt'+(`nip'-1)*(`num'+1) + if `cip'==0{ + local nxt = `nxt'+`num' + } + local nxt = `nxt' - 1 +} +*/ +*disp "next nxt is " `nxt' +} +if `tprf'>1&`bmat'==1{ + disp " " + disp in gr "B-matrix:" + *disp in smcl in gr "{hline 78}" _n + di in gr _dup(78) "-" _n + disp " " + disp " " + * disp "nxt = " `nxt' + local i = 1 + while `i'<`tprf'{ + local j = 1 + while `j' < `tprf'{ + if `M_b'[`i',`j']>0{ + scalar `var' =`b'[1,`nxt'] + scalar `se' = sqrt(`V'[`nxt',`nxt']) + disp in gr " B(`i',`j'): " in ye `var' " (" `se' ")" + local nxt = `nxt' + 1 + } + local j = `j' + 1 + } + local i = `i' + 1 + } +} +if `ngeqs'>0{ + disp " " + disp in gr "Regressions of latent variables on covariates" + *disp in smcl in gr "{hline 78}" _n + di in gr _dup(78) "-" _n + disp " " + tempname mngeqs + matrix `mngeqs' = e(mngeqs) + local i = 1 + while `i'<=`ngeqs'{ + local k = `mngeqs'[1,`i'] + local n = `mngeqs'[2,`i'] + disp in gr " random effect " in ye `k'-1 in gr " has " in ye `n' in gr " covariates:" + local nxt2 = `nxt'+`n'-1 + local j = 1 + while `j' <= `n'{ + local nna: word `nxt' of `names' + scalar `var'=`b'[1,`nxt'] + scalar `se' = sqrt(`V'[`nxt',`nxt']) + disp in gr " `nna': " in ye `var' " (" `se' ")" + local nxt = `nxt' + 1 + local j = `j' + 1 + } + local i = `i' + 1 + } +} +*disp in smcl in gr "{hline 78}" _n +di in gr _dup(78) "-" _n +disp " " +} /* endif toplv >1 */ +end + +program define sechol + version 6.0 + args lev num nxt + * num is number of random effects + local l = `num'*(`num' + 1)/2 + *disp "lev = `lev' num = `num' nxt = `nxt' l= `l'" + tempname b V C L zero a H M_nbrf M_nrfc ind + + matrix `M_nbrf' = e(nbrf) + matrix `M_nrfc' = e(nrfc) + local iscor = e(cor) + matrix `b' = e(b) + matrix `V' = e(V) + local sof = `M_nrfc'[2,`lev'-1] /* was `M_nrfc'[1,`lev'-1] */ + local i = 1 + local k = 1 + matrix `C' = J(`l',`l',0) + matrix `L' = J(`num',`num',0) + matrix `ind' = `L' + * get L matrix + while `i' <= `num'{ + * skip loading parameters + local nb = `M_nbrf'[1,`i'+`sof'] + local nxt = `nxt' + `nb' -1 + disp "nxt = " `nxt' + matrix `L'[`i',`i'] = `b'[1, `nxt'] + * matrix list `L' + matrix `ind'[`i',`i'] = `nxt' + local nxt = `nxt' + 1 + local i = `i' + 1 + } + local i = 2 + while `i' <= `num'&`iscor'==1{ + local j = 1 + while `j' < `i'{ + matrix `L'[`i',`j'] = `b'[1, `nxt'] + matrix `ind'[`i',`j'] = `nxt' + local nxt = `nxt' + 1 + local j = `j' + 1 + } + local i = `i' + 1 + } + * disp "L and ind" + * matrix list `L' + * matrix list `ind' + * get C matrix + local ll1 = 1 + local i = 1 + while `i' <= `num'{ + local j = 1 + while `j' <= `i'{ + local nxt1 = `ind'[`i', `j'] + local ll2 = 1 + local ii = 1 + while `ii' <= `num'{ + local jj = 1 + while `jj' <= `ii'{ + local nxt2 = `ind'[`ii', `jj'] + disp "ll1 = " `ll1' " ll2 = " `ll2' " nxt1 = " `nxt1' " nxt2 = " `nxt2' + if `iscor' == 1{ + matrix `C'[`ll1', `ll2'] = `V'[`nxt1',`nxt2'] + matrix `C'[`ll2', `ll1'] = `C'[`ll1', `ll2'] + } + else if `i'==`j'&`ii'==`jj'{ + matrix `C'[`ll1', `ll2'] = `V'[`nxt1',`nxt2'] + matrix `C'[`ll2', `ll1'] = `C'[`ll1', `ll2'] + } + local ll2 = `ll2' + 1 + local jj = `jj' + 1 + } + local ii = `ii' + 1 + } + local ll1 = `ll1' + 1 + local j = `j' + 1 + } + local i = `i' + 1 + } + + * disp "C" + * matrix list `C' + matrix `zero' = J(`num', `num', 0) + local k = 1 + local i = 1 + local n = `num' * (`num' + 1)/2 + matrix `H' = J(`n',`n',0) + while `i' <= `num' { + local j = 1 + while `j' <= `i'{ + * derivative of LL' with respect to i,j th element of L + mat `a' = `zero' + mat `a'[`i',`j'] = 1 + mat `a' = `a'*(`L')' + mat `a' = `a' + (`a')' + disp "a" + * matrix list `a' + local ii = 1 + local kk = 1 + while `ii'<=`num'{ + local jj = 1 + while `jj' <= `ii'{ + matrix `H'[`kk',`k'] = `a'[`ii',`jj'] + local jj = `jj' + 1 + local kk = `kk' + 1 + } + local ii= `ii' + 1 + } + local j = `j' + 1 + local k = `k' + 1 + } + local i = `i' + 1 + } + * disp "H" + * matrix list `H' + matrix M_se = `H'*`C'*(`H')' + matrix M_cov = `L'*(`L')' + * matrix list M_se + * matrix list M_cov + +end + +program define timer +version 6.0 +end diff --git a/Modules/ado/plus/g/gllamm.hlp b/Modules/ado/plus/g/gllamm.hlp new file mode 100644 index 0000000..85ebaaf --- /dev/null +++ b/Modules/ado/plus/g/gllamm.hlp @@ -0,0 +1,497 @@ +.- +help for ^gllamm^ +.- + +Generalised linear latent and mixed models +------------------------------------------- + +^gllamm^ depvar [varlist] [^if^ exp] [^in^ range] ^,^ ^i(^varlist^)^ + [ ^nocons^tant ^o^ffset^(^varname^)^ ^nr^f^(^#^,^...^,^#^)^ + ^e^qs^(^eqnames^)^ ^frload^(^#^,^...^,^#^)^ + ^ip(^string^)^ ^ni^p^(^#^,^...^,^#^)^ ^pe^qs^(^eqname^)^ + ^bmat^rix^(^matrix^)^ ^ge^qs^(^eqnames^)^ ^nocor^rel + ^c^onstraints^(^clist^)^ ^we^ight^(^varname^)^ ^pwe^ight^(^varname^)^ + ^f^amily^(^family^)^ ^fv(^varname^)^ ^de^nom^(^varname^)^ + ^s(^eqname^)^ ^l^ink^(^link^)^ ^lv(^varname^)^ + ^expa^nded^(^varname varname string^)^ ^b^asecategory^(^#^)^ + ^comp^osite^(^varnames^)^ ^th^resh^(^eqnames^)^ ^eth^resh^(^eqnames^)^ + ^fr^om^(^matrix^)^ ^copy^ ^skip^ ^long^ + ^lf0(^#^ ^#^)^ ^ga^teaux^(^#^ ^#^ ^#^)^ ^se^arch^(^#^)^ + ^noe^st ^ev^al ^in^it ^it^erate^(^#^)^ ^adoonly^ ^adapt^ + ^rob^ust ^clu^ster^(^varname^)^ + ^l^evel^(^#^)^ ^eform^ ^allc^ ^tr^ace ^nolo^g ^nodis^play ^do^ts + ] + +where family is and link is + ^gau^ssian ^id^entity + ^poi^sson ^log^ + ^gam^ma ^rec^iprocal + ^bin^omial ^logi^t + ^pro^bit + ^cll^ (complementary log-log) + ^ll^ (log-log) + ^olo^git (o stands for ordinal) + ^opr^obit + ^ocl^l + ^mlo^git + ^spr^obit (scaled probit) + ^sop^robit + + +and clist is of the form #[^-^#][^,^ #[^-^#] ...] + + + +^gllamm^ shares the features of all estimation commands; see help @est@. + +^gllamm^ typed without arguments redisplays previous results. + +Predictions of the latent variables or random effects (and many other +quantities) can be obtained using @gllapred@ and the models can be +simulated using @gllasim@ + + +Description +----------- + +^gllamm^ estimates ^G^eneralized ^L^inear ^L^atent ^A^nd ^M^ixed ^M^odels. +These models include multilevel (hierarchical) regression models +with an arbitrary number of levels, generalized linear mixed models, +multilevel factor models and some types of latent class models. +We refer to the random effects (random intercepts, slopes or coefficients), +factors, etc. as latent variables or random effects. + +If the latent variables are assumed to be multivariate normal, +^gllamm^ uses Gauss-Hermite quadrature, or adaptive quadrature +if the ^adapt^ option is also specified. Adaptive quadrature +can be considerably more accurate than ordinary quadrature, +see first reference at the bottom of this help file. + +With the ^ip(^f^)^ option, the latent variables are specified +as discrete with freely estimated probabilities (masses) and locations. + +More information on the models is available from + +http://www.gllamm.org + + + +Options +-------- + +(a) Structure of the model +--------------------------------------------------------------------------- + +^i(^varlist^)^ gives the variables that define the hierarchical, nested + clusters, from the lowest level (finest clusters) to the highest level, + e.g. i(pupil class school). + +^noconstant^ omits the constant term from the fixed effects equation. + +^offset(^varname^)^ specifies a variable to be added to the linear predictor + without estimating a corresponding regression coefficient (e.g. log + exposure for Poisson regression). + +^nrf(^#^,^...^,^#^)^ specifies the number of random effects for each level, + i.e., for each variable in ^i(^varlist^)^. The default is nrf(1,...,1). + +^eqs(^eqnames^)^ specifies equation names (defined before running gllamm) + for the linear predictors multiplying the latent variables; see help @eq_g@. + If required, constants should be explicitly included in the equation + definitions using variables equal to 1. If the option is not used, the + latent variables are assumed to be random intercepts and only one random + effect is allowed per level. The first lambda coefficient is set to one + unless the ^frload()^ option is specified. The other coefficients are + estimated together with the (co)variance(s) of the random effect(s). + +^frload(^#^,^...^,^#^)^ lists the latent variables for which the first + factor loading should be freely estimated along with the other + factor loadings. It is up to the user to define appropriate constraints + to identify the model. Here the latent variables are referred to + as 1 2 3 etc. in the order in which they are defined by the ^eqs()^ + option. + +^ip(^sting^)^ if string is g, Gaussian quadrature points are used and if + string is f, the mass-points are freely estimated. The default is + Gaussian quadrature. The ^ip(^f^)^ option causes nip-1 locations to + be estimated, the nipth mass being determined by setting the mean + location to 0 so that an intercept can be included in the fixed + effects equation. The ^ip(^fn^)^ option can be used to set the last mass + to 0 instead of to the mean. If string is m, spherical quadrature rules + are used for multidimensional integrals. + +^nip(^#^,^...^,^#^)^ specifies the number of integration points or masses + to be used for each integral or summation. When quadrature is used, + a value may be given for each random effect. When freely estimated masses + are used, a value may be given for each level of the model. If only one + argument is given, the same number of integration points will be used for + each summation. Combined with the ^ip(m)^ option, ^nip()^ specifies + the degree of the approximation instead of the number of points. Only the + following degrees are available: for two random effects, 5, 7, 9, 11, 15 + and for more than two random effects 5, 7. + +^peqs(^eqname^)^ can be used with the ^ip(^f^)^ or ^ip(^fn^)^ options + to allow the (prior) latent class probabilities to depend on covariates. + The model for the latent class probabilities is a multinomial logit model + with the last latent class as reference category. A constant is + automatically included in addition to the covariates specified in the + equation command; see help @eq_g@. + +^geqs(^eqnames^)^ specifies regressions of latent variables on explanatory variables. + The second character of the equation name indicates which latent + variable is regressed on the variables used in the equation definition, e.g. + eq f1: a b means that the first latent variable is regressed on a and b (without + a constant); see help @eq_g@. + +^bmatrix(^matrix^)^ specifies a matrix B of regression coefficients for the + dependence of the latent variables on other latent variables. The matrix + must be upper diagonal and have number of rows and columns equal to the + total number of random effects. + +^nocorrel^ may be used to constrain all correlations to zero + if there are several random effects at any of the levels and if these are + modeled as multivariate normal. + +^constraint(^clist^)^ specifies the constraint numbers of the constraints to + be applied. Constraints are defined using the ^constraint^ command; see + help @constraint@. To find out the equation names needed to specify the + constraints, run gllamm with the noest option. + +^weight(^varname^)^ specifies that variables varname1, varname2, etc. contain + frequency weights. The suffixes determine at what level each weight applies. + For example, if the level 1 units are subjects, the level 2 units are + families, and the result is binary, we can collapse dataset A into + dataset B as follows: + + A B + family subject result family subject result wt1 wt2 + 1 1 0 1 1 0 2 1 + 1 2 0 2 3 1 1 2 + 2 3 1 2 4 0 1 2 + 2 4 0 + 3 5 1 + 3 6 0 + + The level 1 weight, wt1, indicates that subject 1 in dataset B + represents two subjects within family 1 in dataset A, whereas subjects + 3 and 4 in dataset B represent single subjects within family 2 in + dataset A. The level 2 weight wt2 indicates that family 1 in dataset B + represents one family and family 2 represents two families, i.e. all + the data for family 2 are replicated once. Collapsing the data in this + way can make gllamm run considerably faster. + +^pweight(^varname^)^ specifies that variables varname1, varname2, etc. contain + sampling weights for levels 1, 2, etc. As far as the estimates and + log-likelihood are concerned, the effect of specifying these + weights is the same as for frequency weights, but the standard errors + will be different. Robust standard errors will automatically be provided. + This should be used with caution if the sampling weights apply + to units at a lower level than the highest level in the multilevel model. + The weights are not rescaled; scaling is the responsibility of the user. + +(b) Densities, links, etc. for the response model +------------------------------------------------------------------------------ + +^family(^families^)^ specifies the families to be used for the conditional + densities. The default is ^family(^gauss^)^. Several families may be given + in which case the variable allocating families to observations must be + given using ^fv(^varname^)^. + +^fv(^varname^)^ is required if mixed responses requiring more than a single + family of conditional distributions are analyzed. The variable indicates + which family applies to which observation. A value of one refers to the + first family etc. + +^denom(^varname^)^ gives the variable containing the binomial denominator for + the responses whose family is specified as binomial. The default + denominator is 1. + +^s(^eqname^)^ specifies that the log of the standard deviation (or coefficient + of variation) at level 1 for normally (or gamma) distributed responses + should be given by the linear predictor defined by eqname. This is + necessary if the level-1 variance is heteroscedastic. For example, if + dummy variables for groups are used, different variances are estimated + for different groups. + +^link(^link^)^ specifies the links to be used for the conditional densities. If + a single family is specified, the default link is the canonical link. + Several links may be given in which case the variable allocating links to + observations must be given using ^lv(^varname^)^. This option is currently + not available if the ordinal or mlogit links are used. Numerically + feasible choices of link depend upon the distributions of the covariates + and choice of conditional error and random effects distributions. The + sprobit link is only identified in special cases; it may be used for + Heckman-type selection models or to model floor or ceiling effects. + +^lv(^varname^)^ is the variable whose values indicate which link applies to + which observation. + +^expanded(^varname varname string^)^ is used together with the mlogit + link and specifies that the data have been expanded as illustrated + below: + + A B + choice response altern selected + 1 1 1 1 + 2 1 2 0 + 1 3 0 + 2 1 0 + 2 2 1 + 2 3 0 + + where the variable "choice" is the multinomial response + (possible values 1,2,3), the "response" labels the original lines + of data, "altern" gives the possible responses or alternatives + and "selected" is an indicator for the option that was selected. + The syntax would be expanded(response selected m) and the variable + "altern" would be used as the dependent variable. This expanded + form allows the user to use different random effects etc. for + different categories of the multinomial response. The third + argument is o if one set of coefficients should be estimated + for the explanatory variables and m if one set of coefficients + is to be estimated for each category of the response except the + reference category. + +^basecategory^(^#^)^ When the mlogit link is used, this specifies the + value of the response to be used as the reference category. This option is + ignored if the expanded() option is used with the third argument equal + to m. + +^composite^(varname varname varname [more varnames]) specifies that a + composite link is used. The first variable is a cluster identifier + ("cluster" below) so that linear predictors within the cluster can + be combined into a single composite link. The second variable + ("ind" below) indicates to which response the composite links defined + by the susequent weight variables belong. Observations with ind=0 + have a missing link. The remaining variables ("c1" and "c2" below) + specify weights for the composite links. The composite link based on + the first weight variable will go to where ind=1, etc. + + Example: + + + Data setup with form of inverse link Interpretation of + h_i determined by link() and lv(): composite(cluster ind c1 c2) + + cluster ind c1 c2 inverse link cluster composite link + 1 1 1 0 h_1 1 h_1 - h_2 + 1 2 -1 1 h_2 1 n_2 + h_3 + 1 0 0 1 h_3 ==> 1 missing + 2 1 1 0 h_4 2 h_4 + h_5 + 2 2 1 1 h_5 2 h_5 + 2*h_6 + 2 0 0 2 h_6 2 missing + + +^thresh(^eqnames^)^ specifies equation(s) for the thresholds for ordinal + response(s); see help @eq_g@. One equation is specified for each + ordinal response. The purpose of this option is to allow the effects of some + covariates to be different for different categories of the ordinal variable + rather than assumming a constant effect - the proportional odds assumption + if the ologit link is used. Variables used in the model for the + thresholds cannot appear in the fixed part of the linear predictor. + +^ethresh(^eqnames^)^ is the same as ^thresh(^eqnames^)^ except that + a different parameterization is used for the threshold model. To + ensure that k_{s-1} <= k_{s}, the model is k_{s} = k_{s-1} + exp(xb), + for response categories s=2,...,S. + +(c) Starting values +----------------------------------------------------------------------------- + +^from(^matrix^)^ specifies the matrix to be used for the initial values. + Note that the column-names and equation-names have to be correct + (see help @matrname@, @matrix@), unless the ^copy^ option is specified. + The matrix may be obtained from a previous estimation command using e(b). + This is useful if the number of quadrature points needs to be increased + or of a new explanatory variable is added. Use the ^skip^ option if + the matrix of has extra parameters. + +^copy^ and ^skip^ see above. + +^long^ may be used with the from(matrix) option when constraints are used + to indicate that the matrix of initial values has as many elements + as would be needed for the unconstrained model, i.e. more elements + than will be estimated. + +^lf0(^# #^)^ gives the number of parameters and the log-likelihood for a + likelihood ratio test to compare the model to be estimated with a simpler + model. A likelihood ratio chi-squared test is only performed if the + ^lf0(^# #^)^ option is used. + +^gateaux(^min^,^max^,^n^)^ may be used with method ip(f) to increase the + number of mass-points by one from a previous solution with parameter + estimates specified using from(matrix) and number of parameters and + log-likelihood specified by lf0(# #). The program searches for the + location of the new mass-point by placing a very small mass at the + location given by the first argument and moving it to the second argument + in the number of steps specified by the third argument. (If there are + several random effects, this search is done in each dimension resulting + in a regular grid of search points.) If the maximum increase in likelihood + is greater than 0, the location corresponding to this maximum is used as + the initial value of the new location, otherwise the program stops. When + this happens, it can be shown that for certain models the current solution + represents the non-parametric maximum likelihood estimate. + +^search(^#^)^ causes the program to search for initial values for the random + effects at level 2 (in range 0 to 3). The argument specifies the number + of random searches. This option may only be used with ^ip(^g^)^ and when + ^fr^om^(^matrix^)^ is not used. + +(d) Estimation and output options +------------------------------------------------------------------------------ + +^noest^ is used to prevent the program from carrying out the estimation. This + may be used with the trace option to check that the model is correct and + get the information needed to set up a matrix of initial values. Global + macros are available that are normally deleted. Particularly useful may + be M_initf and M_initr, matrices for the parameters (fixed part and + random part respectively). + +^eval^ causes the program to simply evaluate the loglikelihood for values passed + to it using the from(matrix) option. + +^init^ causes the program to compute initial estimates of fixed effects + only, setting all latent variables to zero. gllamm will be used for + estimating initial values even if a Stata command is available for the + model (without the init option, gllamm uses Stata commands for initial values + whenever they are available). + +^iterate(^#^)^ specifies the (maximum) number of iterations. With the ^adapt^ + option, use of the ^iterate(^#^)^ option will cause ^gllamm^ to skip the + "Newton Raphson" iterations usually performed at the end without updating + the quadrature locations. ^iterate(^0^)^ is like ^eval^ except that standard + errors are computed. + +^adoonly^ causes all gllamm to use only ado-code. Gllamm will be faster if + if it uses internalised versions of some of the functions available in + Stata 7 if updated on or after 26oct2001 + +^nip(^#^,^...^,^#^)^ when quadrature is used, this specifies the number + of quadrature points (integration points) to be used. A value may be + given for each random effect. If only one argument is given, the + same number of quadrature points will be used for each summation. + +^adapt^ causes adaptive quadrature to be used instead of ordinary quadrature. + This option cannot be used with the ^ip(^f^)^ or ^ip(^f0^)^ options. + +^robust^ specifies that the Huber/White/sandwich estimator of the covariance + matrix of the parameter estimates is to be used. If a model has been + estimated without the ^robust^ option, the robust standard errors can be + obtained by simply typing ^gllamm, robust^. + +^cluster(^varname^)^ specifies that the highest level units of the GLLAMM + model are nested in even higher level clusters where ^varname^ contains + the cluster identifier. Robust standard errors will be provided that + take this clustering into account. If a model has been estimated without + this option, the robust standard errors for clustered data can be obtained + using the command ^gllamm, cluster(varname)^. + +^level(^#^)^ specifies the confidence level in percent for confidence + intervals of the coefficients. + +^eform^ causes the expnentiated coefficients and confidence intervals to be + displayed. + +^allc^ causes all estimated parameters to be displayed in a regression table + (including the raw parameters for the random effects) in addition to the + usual output. + +^trace^ causes more output to be displayed. Before estimation begins, + details of the specified model are displayed. In addition, a + detailed iteration log is shown including parameter estimates + and log-likelihood values for each iteration. + +^nolog^ suppresses output for maximum likelihood iterations. + +^nodisplay^ suppresses output of the estimates but still shows iteration log + unless ^nolog^ is used. + +^dots^ causes a dot to be printed (if used together with trace) every time the + likelihood evaluation program is called by ml. This helps to assess how long + gllamm is likely to take to run and reassures the user that it is making + some progress when it is very slow. + + + +Examples +-------- + +(a) 3-level random intercept model +---------------------------------- +Some response "resp" and covariate "x" are available for pupils +in different schools. "id" is the identifier or label for the pupils +and "school" is the identifier for the schools. A linear model +with random intercepts at the pupil and school levels can be specified +as follows: + + . ^gllamm resp x, i(id school) adapt trace^ + + +(b) 2-level random coefficient model - growth curve model +--------------------------------------------------------- +subjects identified by "id" have been measured repeatedly over +time giving responses in "resp". "cons" is a variable equal to 1 +and "time" contains the time-points. A model with a random +intercept and slope for time is specified as follows: + + . ^eq int: cons^ + . ^eq slope: time^ + . ^gllamm resp time, i(id) nrf(2) eqs(int slope) adapt trace ^ + + +(c) two-parameter logistic item-response model +---------------------------------------------- +variable "resp" contains responses to 5 items (e.g. 5 test questions) +for each subject. The subject identifier is "id". There are five +dummy variables "i1" to "i5" for the items, e.g. "i1" is equal +to 1 if the item is item 1 and 0 otherwise. + + . ^eq discrim: i1 i2 i3 i4 i5^ + . ^gllamm resp i1 i2 i3 i4 i5, link(logit) fam(binom) nocons /*^ + ^*/ i(id) eqs(discrim) adapt trace^ + + +Author +------ +Sophia Rabe-Hesketh (sophiarh@@berkeley.edu) +as part of joint work with Andrew Pickles and Anders Skrondal. +We would like to acknowledge Colin Taylor for helping in the +early stages of gllamm development. We are also very grateful +to Stata Corporation for helping us to speed up gllamm. + +Web-page +-------- +http://www.gllamm.org + + +References (available from sophiarh@@berkeley.edu) +---------- +Rabe-Hesketh, S. and Skrondal, A. (2005). Multilevel and Longitudinal +Modeling using Stata. College Station, TX: Stata Press. + +Rabe-Hesketh, S., Pickles, A. and Skrondal, S. (2004). +GLLAMM Manual. U.C. Berkeley Division of Biostatistics Working +Paper Series. Working Paper 160. +see http://www.bepress.com/ucbbiostat/paper160/ + +Rabe-Hesketh, S., Skrondal, A. and Pickles, A. (2005). Maximum +likelihood estimation of limited and discrete dependent variable +models with nested random effects. Journal of Econometrics 128, 301-323. + +Rabe-Hesketh, S., Skrondal, A. and Pickles, A. (2002). +Reliable estimation of generalized linear mixed models +using adaptive quadrature. The Stata Journal 2, 1-21. + +Rabe-Hesketh, S., Skrondal, A. and Pickles, A. (2004). +Generalised multilevel structural equation modelling. +Psychometrika 69 , 167-190. + + +Also see +-------- + +Manual: ^[U] 23 Estimation and post-estimation commands^ + ^[U] 29 Overview of model estimation in Stata^ + +On-line: help for @gllapred@, @gllasim@, @ml@, @glm@, @xtreg@, + @xtlogit@, @xtpois@, @quadchk@, @test@ diff --git a/Modules/ado/plus/g/gllapred.ado b/Modules/ado/plus/g/gllapred.ado new file mode 100644 index 0000000..ab7d507 --- /dev/null +++ b/Modules/ado/plus/g/gllapred.ado @@ -0,0 +1,1237 @@ +*! version 2.3.8 SRH 7 Sept 2011 +program define gllapred + version 6.0 + + if "`e(cmd)'" ~= "gllamm" { + di in red "gllamm was not the last command" + exit 301 + } + + *syntax anything(name=pref id="prefix for variable(s)") [if] [in] + syntax newvarname [if] [in] /* + */ [,XB U USTD P S LInpred MU ADapt LL FAC Deviance PEarson Anscombe COoksd SCorefil(string) /* DFBeta + */ MArginal OUTcome(int -99) ABove(numlist integer) US(string) CORR noOFFset FSAMPLE ADOONLY FRom(string)] + local nopt = ("`u'"~="") + ("`ustd'"~="") + ("`p'"~="") + ("`xb'"~="") + ("`s'"~="") /* + */ + ("`linpred'"~="") + ("`mu'"~="") + ("`ll'"~="") + ("`fac'"~="") /* + */ + ("`deviance'"~="") + ("`pearson'"~="") + ("`anscombe'"~="") /* + */ + ("`dfbeta'"~="") + ("`cooksd'"~="") + + global HG_final = 0 + local pref `varlist' + + if `nopt'>1 { + disp in re "only one of these options allowed: xb, u, fac, linpred, mu, ll, p, s, deviance, pearson, anscombe, dfbeta" + exit 198 + } +** 11/4/06 + if "`corr'"~=""&"`u'"==""{ + disp in re "corr option allowed only with u option" + exit 198 + } + local tplv = e(tplv) + local tprf = e(tprf) + local vars + if `nopt'==0 { + local xb "xb" + } + if "`ustd'"~=""{ + local u "u" + } + if "`xb'"~=""|"`s'"~=""{ + local what = 0 + local vars `pref' + if "`xb'"~=""{ + disp in gr "(xb will be stored in `pref')" + } + else{ + disp in gr "(s will be stored in `pref')" + } + } + else if "`p'"~="" { + if `tplv' < 2{ + disp in re "p option not valid for 1 level model" + exit 198 + } + local what = 2 + tempname mat + matrix `mat'=e(nip) + local nip = `mat'[1,2] + local i = 1 + while `i'<=`nip'{ + local vars `vars' `pref'`i' + local i = `i' + 1 + } + disp in gr "(probabilities will be stored in `vars')" + global HG_post = 1 + } + else if "`ll'"~="" { + local what = 4 + local vars `pref' + disp in gr "(ll will be stored in `pref')" + global HG_post = 1 + if "`fsample'"!=""{ + disp in gr "Note: conditional response probability/density set to 1"" + disp in gr " for observartions with missing values" + disp " " + } + } + else if "`mu'"~=""{ + local what = 5 + local vars `pref' + disp in gr "(mu will be stored in `pref')" + global HG_post = 1 + if "`marginal'"~=""{ + global HG_post = 0 + } + } + else if "`deviance'"~=""|"`pearson'"~=""|"`anscombe'"~=""{ + local vars `pref' + disp in gr "(residuals will be stored in `pref')" + if "`pearson'"~="" { + local what = 6 + } + else if "`deviance'"~=""{ + local what = 7 + } + else{ + local what = 8 + } + global HG_post = 1 + if "`marginal'"~=""{ + global HG_post = 0 + } + } + else if "`u'"~=""|"`linpred'"~=""|"`fac'"~=""{ + local what = 1 + global HG_post = 1 /* added Jan 12 2008: signals that gllapred called gllam_ll */ + if `tplv' < 2{ + if "`u'"~=""|"`fac'"~=""{ + disp in re "u, and fac options not valid for 1-level model" + exit 198 + } + else if "`linpred'"~=""{ + disp in re "linpred option equivalent to xb for this model" + local xb "xb" + local what = 0 + } + * else if "`mu'"~=""? + } + if "`fac'"~=""{ + local i = 1 + while `i' < `tprf'{ + local vars `vars' `pref'm`i' + local i = `i' + 1 + } + disp in gr "(means will be stored in `vars')" + } + else if "`u'"~=""{ + local i = 1 + while `i' < `tprf'{ + local vars `vars' `pref'm`i' `pref's`i' + local i = `i' + 1 + } + disp in gr "(means and standard deviations will be stored in `vars')" +**11/4/06 + if "`corr'"~=""{ + local corvars + local i = 1 + while `i' < `tprf'{ + local rfs = 1 + while `rfs' < `i'{ + local vars `vars' `pref'c`i'`rfs' + local corvars `corvars' `pref'c`i'`rfs' + local rfs = `rfs' + 1 + } + local i = `i' + 1 + } + disp in gr "(correlations will be stored in `corvars')" + } + } + else if "`linpred'"~=""{ + local vars `pref' + disp in gr "(linear predictor will be stored in `pref')" + } + } + else if "`dfbeta'"~=""{ + local k = e(k) + local i = 1 + while `i'<= `k'{ + local vars `vars' `pref'`i' + local i = `i' + 1 + } + disp in gr "(dfbetas will be stored in `vars')" + } + else if "`cooksd'"~=""{ + local vars `vars' `pref' + disp in gr "(Cook's D will be stored in `vars')" + } + if "`offset'"~=""{ + if "`linpred'"==""&"`xb'"==""&"`mu'"==""{ + disp in re "nooffset option only allowed with xb, mu or linpred options" + exit 198 + } + } + + if "`us'"~="" { + if `what'<5{ + disp in re "us() option only valid with mu, pearson, deviance or anscombe" + exit 198 + } + } + +/* check if variables already exist */ + + confirm new var `vars' + +/* restrict to estimation sample */ + + tempvar idno + gen long `idno' = _n + preserve + if "`fsample'"==""{ + qui keep if e(sample) + } + +/* interpret if and in */ + marksample touse, novarlist + qui count if `touse' + if _result(1) < 1 { + di in red "insufficient observations" + exit 2001 + } + qui keep if `touse' + + tempfile file + +/* influence statistics (don't need macros) */ + + if "`dfbeta'"~=""|"`cooksd'"~=""{ + *disp in re "`e(scorefil)'" + if "`e(scorefil)'"~=""{ + local fil2 "`e(scorefil)'" + } + else if "`scorefil'"~=""{ + local fil2 "`scorefil'" + } + else{ + tempfile fil2 + } + + if "`e(scorefil)'"==""{ + if "`scorefil'"~=""{ + gllarob, scorefil(`fil2') norob + } + else{ + gllarob, scorefil(`fil2') temp norob + } + } + local clus `e(clus)' + if `e(tplv)'==1{ + local top `idno' + } + else{ + local top: word 1 of `clus' + } + sort `top' + qui save "`file'", replace + tempname H d junk junk1 + matrix `H' = e(Vs) + + if `e(const)' { + * disp "constraints used" + * matrix `b' = `b'*M_T + matrix `H' = M_T'*`H'*M_T + } + + capture matrix `H' = inv(`H') + if _rc>0{ + disp in re "parameter covariance matrix not invertible" + exit(198) + } + use `fil2', clear + tempvar cons + qui gen byte `cons' = 1 + local k = colsof(`H') + local N = _N + matrix `d' = vecdiag(`H') + matrix `d' = diag(`d') + matrix `junk' = `d'*`d'' + scalar `junk1' = trace(`junk') + scalar `junk1' = sqrt(`junk1') + matrix `d' = `d'/`N' + matrix `H' = `H'*(`N'-1)/`N' + `d' + if "`dfbeta'"~=""{ + tempname Hi covi dbi sumi + local j = 1 + while `j'<=`k'{ + qui gen `pref'`j' = . + local j = `j' + 1 + } + qui gen `pref'0 = . + local i = 1 + while `i'<=`N'{ + mkmat s1-s`k' if _n==`i', matrix(`Hi') + matrix `Hi' = diag(`Hi') + matrix `junk' = `Hi' + `d' + matrix `junk' = `junk'*`junk'' + matrix `junk' = trace(`junk') + qui replace `pref'0 = 100*sqrt(`junk'[1,1])/`junk1' in `i' + matrix `covi' = `H' + `Hi' + *if `i'==49{matrix list `covi'} + matrix vecaccum `sumi' = `cons' d1-d`k' if _n~=`i', nocons + *if `i'==49{matrix list `sumi'} + matrix `dbi' = inv(`covi')*`sumi'' + matrix `Hi' = e(Vs) + local j = 1 + while `j'<=`k'{ + qui replace `pref'`j' = `dbi'[`j',1]/sqrt(`Hi'[`j',`j']) in `i' + local j = `j' + 1 + } + local i = `i' + 1 + } + local vars `vars' `pref'0 + } + else{ /* Cook's D */ + *disp in re "calculating cook's d" + matrix `H' = inv(`H') + tempname scorei ci + qui gen `pref' = . + local i = 1 + while `i'<=`N'{ + mkmat d1-d`k' if _n==`i', matrix(`scorei') + *matrix list `scorei' + matrix `ci' = 2*`scorei'*`H'*`scorei'' + *matrix list `ci' + qui replace `pref' = `ci'[1,1] in `i' + local i = `i' + 1 + } + } + if `e(tplv)'==1{ + rename __idno `top' + } + keep `top' `vars' + sort `top' + tempvar mrge + merge `top' using "`file'", _merge(`mrge') + qui drop `mrge' + sort `idno' + } + else{ + +/* set all global macros needed by gllam_ll */ + setmacs `what' + + if "`offset'"~=""{ /* nooffset not specified: will subtract HG_offs=HG_off */ + global HG_offs $HG_off + } + else{ + tempvar offs + global HG_offs `offs' + gen `offs'=0 + } + + +/* deal with outcome() and above() */ + if `what'>=5&$HG_nolog>0{ /* mu or residuals */ + if "`above'"==""{ + disp in re "must specify above() option for ordinal responses" + exit 198 + } + else{ + matrix M_above = J(1,$HG_nolog,0) + local num: word count `above' + if `num'>1&`num'~=$HG_nolog{ + disp in re "wrong length of numlist in above() option" + exit 198 + } + local no = 1 + local k = 1 + while `no' <= $HG_nolog{ + if `num'>1{ + local k = `no' + } + local ab: word `k' of `above' + * disp in re "`no'th ordinal response, above = `ab'" + local n=M_nresp[1,`no'] + local i = 1 + local found = 0 + while `i'<= `n'&`found'==0{ + if M_resp[`i',`no']==`ab'{ + local found=`i' + matrix M_above[1,`no']=`i' + } + local i = `i' + 1 + } + if `found'==0{ + disp in re "`ab' not a category for `no'th ordinal response" + exit 198 + } + else if `found' == `n'{ + disp in re "`ab' is highest category for `no'th ordinal response" + exit 198 + } + local no = `no' + 1 + } + } + * noi matrix list M_above + } + if `what'>=5&$HG_mlog>0{ /* mu or residuals */ + if `outcome'==-99&$HG_exp==0{ + disp in re "must specify outcome() option for nominal responses unless data in expanded form" + exit 198 + } + if $HG_exp==0{ + local n=rowsof(M_respm) + local found = 0 + local i = 1 + while `i'<= `n'&`found'==0{ + if M_respm[`i',1]==`outcome'{ + local found=`i' + } + local i = `i' + 1 + } + if `found'==0{ + disp in re "`outcome not a category of the nominal response'" + exit 198 + } + global HG_outc=`outcome' + } + } + + if "`adoonly'"!="" { + global HG_noC = 1 + global HG_noC1 = 1 + } + + *disp "HG_free = " $HG_free + + tempname b + matrix `b'=e(b) + +/* deal with from */ + if "`from'"~=""{ + capture qui matrix list `from' + local rc=_rc + if `rc'>1{ + disp in red "`from' not a matrix" + exit 111 + } + local ncol = colsof(`from') + local nrow = rowsof(`from') + local ncolb = colsof(`b') + if `ncolb'~=`ncol'{ + disp in re "from matrix has `ncol' columns but should have `ncolb'" + exit 111 + } + if `nrow'~=1{ + disp in re "from matrix has more than one row" + exit 111 + } + local coln: colnames(`b') + local cole: coleq(`b') + matrix `b' = `from' + matrix colnames `b' = `coln' + matrix coleq `b' = `cole' + } + + if "`s'"~=""|"`xb'"~=""|"`us'"~=""{ + /* run remcor */ + /* set up names for HG_xb`i' */ + local i = 1 + while (`i' <= $HG_tpff){ + tempname junk + global HG_xb`i' "`junk'" + local i = `i' + 1 + } + /* set up names for HG_s`i' */ + local i = 1 + while (`i'<=$HG_tprf){ + tempname junk + global HG_s`i' "`junk'" + local i = `i'+1 + } + + qui remcor "`b'" "`us'" + + if "`s'"~=""{ + qui gen double `pref' = ${HG_s1} + } + else if "`xb'"~=""{ + qui gen double `pref' = $HG_xb1 + if "`offset'"~=""&"$HG_off"~=""{ /* nooffset specified - changed oct 2004 */ + qui replace `pref' = `pref' - $HG_off + } + } + else if "`us'"~="" { + tempvar lpred muu + local j = 1 + qui gen double `lpred' = $HG_xb1 + if "`offset'"~=""&"$HG_off"~=""{ + qui replace `lpred' = `lpred' - $HG_off + } + while `j'<$HG_tprf{ + capture confirm variable `us'`j' + if _rc~=0{ + disp in re "variable `us'`j' not found" + exit 111 + } + local jp = `j' + 1 + qui replace `lpred' = `lpred' + `us'`j' * ${HG_s`jp'} + local j = `j' + 1 + } + } + } + if "`s'"==""&"`xb'"==""{ +/* sort out temporary variables for gllas_yu or gllam_ll */ +/* sort out denom */ + local denom "`e(denom)'" + if "`denom'"~=""{ + *capture confirm variable `denom' + *if _rc>0{ + if substr("`denom'",1,2)=="__" { /*sort this out in future! */ + tempvar den + qui gen byte `den'=1 + global HG_denom "`den'" + } + else{ + * disp in re "denom given" + global HG_denom `denom' + } + } + + /* sort out HG_ind */ + *capture confirm variable $HG_ind + *if _rc>0{ + if substr("$HG_ind",1,2)=="__" { /*sort this out in future! */ + tempname junk + global HG_ind "`junk'" + gen byte $HG_ind=1 + } + /* sort out HG_lvolo */ + if $HG_nolog>0{ + tempname junk + global HG_lvolo "`junk'" + qui gen byte $HG_lvolo = 0 + local no = 1 + if "$HG_lv"==""{ + local olog = M_olog[1,`no'] + qui replace $HG_lvolo = 1 + } + else{ + while `no'<=$HG_nolog{ + local olog = M_olog[1,`no'] + qui replace $HG_lvolo = 1 if $HG_lv == `olog' + local no = `no' + 1 + } + } + } + +/** added this 24th feb 2004 **/ + if $HG_mlog>0{ + if $HG_nolog==0{ + tempname junk + global HG_lvolo "`junk'" + qui gen byte $HG_lvolo = 0 + } + if "$HG_lv"~=""{ /* more than one link */ + qui replace $HG_lvolo = 1 if $HG_lv == $HG_mlog + } + else{ + qui replace $HG_lvolo = 1 + } + } +/** end added this **/ + + + /* sort out level 1 clus variable */ + local clus `e(clus)' + global HG_clus `clus' + tempvar id + if $HG_exp~=1&$HG_comp==0{ + gen long `id'=_n + tokenize "`clus'" + local l= $HG_tplv + local `l' "`id'" + if $HG_tplv>1{ + global HG_clus "`*'" + } + else{ + global HG_clus "`1'" + } + } + *disp "HG_clus: $HG_clus" + + if "`us'"~=""{ + qui gen double `muu' = 0 + qui gen double `pref' = 0 + sort $HG_clus + gllas_yu `pref' `lpred' `muu' `what' + } + } + if "`s'"==""&"`xb'"==""&"`us'"==""{ /* need to call gllam_ll */ +/* sort out temporary variables for gllam_ll */ +/* sort out weight */ + local weight "`e(weight)'" + local pweight "`e(pweight)'" +*10/29/06 + local numlv: word count `e(clus)' + tempvar wt + quietly gen double `wt'=1 +*End 10/29/06 + local i = 1 + while `i'<= `numlv'{ /* 10/29/06 not $HG_tplv{ because wrong for init option */ + tempvar wt`i' + qui gen double `wt`i''=1 + global HG_wt`i' "`wt`i''" + capture confirm variable `weight'`i' + if _rc==0 { + qui replace `wt`i'' = `wt`i'' * `weight'`i' + } + capture confirm variable `pweight'`i' + if _rc==0{ + qui replace `wt`i'' = `wt`i'' * `pweight'`i' + } +*10/29/06 + qui replace `wt' = `wt'*`wt`i'' + local i = `i'+1 + } +*10/29/06 + if `e(init)'{ + qui replace `wt1' = `wt' + } + + tempname lnf + + +/* deal with adapt */ + if "`adapt'"~=""{ + local adapt = 1 + } + else if $HG_adapt==0{ + local adapt = 0 + } + if $HG_adapt==1{ + local adapt = 1 + } + if `what'==2{ /* posterior probs */ + if $HG_tplv~=2{ + disp in re "cannot compute posterior probabilities in higher level models" + exit 301 + } + else if $HG_free~=1{ + if $HG_tprf>2{ + disp in re "cannot compute posterior probabilities for more than 1 continuous latent variable" + exit 301 + } + } + else{ + local i=1 + while `i'<=M_nip[1,2]{ + global HG_p`i' `pref'`i' + qui gen double `pref'`i' = 0 + local i = `i' + 1 + } + noi gllam_ll 1 `b' "`lnf'" "junk" "junk" `what' + disp in gr "log-likelihood:" in ye `lnf' + } + } + if `what'>=4|(`what'==2&$HG_free~=1){ /* ll, mu or resids or posterior probs */ + if `adapt'&$HG_post{ /* want posterior quant., therefore adaptive good */ + local rf = 1 + while `rf'<=$HG_tprf{ + tempname junk + global HG_MU`rf' "`junk'" + tempname junk + global HG_SD`rf' "`junk'" + gen double ${HG_MU`rf'}=0 + gen double ${HG_SD`rf'}=1 + local rf2 = `rf' + 1 + while `rf2' < $HG_tprf { + tempname junk + global HG_C`rf2'`rf' "`junk'" + gen double ${HG_C`rf2'`rf'}=0 + local rf2 = `rf2' + 1 + } + local rf = `rf' + 1 + } + noi gllam_ll 1 `b' "`lnf'" "junk" "junk" 1 + + tempname last + disp in gre "Non-adaptive log-likelihood: " in ye `lnf' + global HG_adapt=1 + tempname last + scalar `last' = 0 + local i = 1 + qui `noi' disp in gr "Updating posterior means and variances" + qui `noi' disp in gr "log-likelihood: " + while abs((`last'-`lnf')/`lnf')>1e-8&`i'<60&`lnf'~=.{ + scalar `last' = `lnf' + qui gllam_ll 1 "`b'" "`lnf'" "junk" "junk" 1 + disp in ye %10.4f `lnf' " " _c + if mod(`i',6)==0 {disp " " } + local j = 1 + local i = `i' + 1 + } + if mod(`i',6)~=1{disp " "} + } /* end if adapt */ + else{ /* want marginal quantity, use ordinary quad */ + global HG_adapt = 0 + } + if `what'>=5{ + global HG_noC1 = 1 + } + if `what'==2{ + local i=1 + while `i'<=M_nip[1,2]{ + *disp in re "making `pref'`i'" + global HG_p`i' `pref'`i' + qui gen double `pref'`i' = 0 + local i = `i' + 1 + } + *noi gllam_ll 1 `b' "`lnf'" "junk" "junk" `what' + *disp in gr "log-likelihood:" in ye `lnf' + } + else { + qui gen double `pref' = 0 + } +**Test + global HG_final = 1 + noi gllam_ll 1 `b' "`lnf'" "junk" "junk" `what' `pref' + if `lnf'==.{ + disp in re "log-likelihood cannot be computed" + disp in re "for observations that should not contribute to posterior or ll," + disp in re " set response variable to missing" + exit 198 + } + if `adapt'==0|(`adapt'==1&$HG_post==1){ + disp in gr "log-likelihood:" in ye `lnf' + } + } + else if `what'==1 { /* u, fac or linpred */ + local rf = 1 + while `rf'<=$HG_tprf{ + tempname junk + global HG_MU`rf' "`junk'" + tempname junk + global HG_SD`rf' "`junk'" + gen double ${HG_MU`rf'}=0 + gen double ${HG_SD`rf'}=1 + local rf2 = `rf' + 1 + while `rf2' < $HG_tprf { + tempname junk + global HG_C`rf2'`rf' "`junk'" + gen double ${HG_C`rf2'`rf'}=0 + local rf2 = `rf2' + 1 + } + local rf = `rf' + 1 + } + + noi gllam_ll 1 `b' "`lnf'" "junk" "junk" `what' + if `lnf'==.{ + disp in re "log-likelihood cannot be computed" + disp in re "for observations that should not contribute to posterior," + disp in re " set response variable to missing" + exit 198 + } + if `adapt'{ + tempname last + disp in gre "Non-adaptive log-likelihood: " in ye `lnf' + global HG_adapt=1 + tempname last + scalar `last' = 0 + local i = 1 + qui `noi' disp in gr "Updating posterior means and variances" + qui `noi' disp in gr "log-likelihood: " + while abs((`last'-`lnf')/`lnf')>1e-8&`i'<60&`lnf'~=.{ + scalar `last' = `lnf' + qui gllam_ll 1 "`b'" "`lnf'" "junk" "junk" 1 + disp in ye %10.4f `lnf' " " _c + if mod(`i',6)==0 {disp " " } + local j = 1 + local i = `i' + 1 + } + if mod(`i',6)~=1{disp " "} + disp in gr "log-likelihood:" in ye `lnf' + * disp in re "call gllam_ll without running prepadpt" + global HG_adapt = 2 +**Test + global HG_final = 1 + qui gllam_ll 1 "`b'" "`lnf'" "junk" "junk" 1 + if `lnf'==.{ + disp in re "log-likelihood cannot be computed" + disp in re "for observations that should not contribute to posterior," + disp in re " set response variable to missing" + exit 198 + } + } + if "`u'"~=""|"`fac'"~=""{ + * noi matrix list CHmat + tempname vari + if $HG_free==0{ + local lv = 2 + local rf = 1 + while `lv'<=$HG_tplv{ + local minrf = `rf' + local maxrf = M_nrfc[2,`lv'] + while `rf'<`maxrf'{ + qui gen double `pref'm`rf'=0 + qui gen double `pref's`rf'=0 /* will be deleted later if option is fac */ + scalar `vari' = 0 + local rf2 = `minrf' + while `rf2'<=`rf'{ /* lower block triangular matrix */ + * disp in re "`pref'm`rf' = `pref'm`rf' + CHmat[`rf',`rf2']*HG_MU`rf2'" + qui replace `pref'm`rf'=`pref'm`rf'+CHmat[`rf',`rf2']*${HG_MU`rf2'} + * disp in re "`pref's`rf' = `pref's`rf' + CHmat[`rf',`rf2']^2*HG_SD`rf2'^2" + qui replace `pref's`rf'=`pref's`rf'+CHmat[`rf',`rf2']^2*${HG_SD`rf2'}^2 + * was scalar `vari' = `vari' + CHmat[`rf',`rf2']*CHmat[`rf2',`rf'] + scalar `vari' = `vari' + CHmat[`rf',`rf2']*CHmat[`rf',`rf2'] + local rf3 = `minrf' + while `rf3'<`rf2'{ + * disp in re "`pref's`rf' = `pref's`rf' + 2*CHmat[`rf',`rf2']*CHmat[`rf',`rf3']*HG_C`rf2'`rf3'" + qui replace `pref's`rf'=`pref's`rf'+2*CHmat[`rf',`rf2']*CHmat[`rf',`rf3']*${HG_C`rf2'`rf3'} + local rf3 = `rf3' + 1 + } + local rf2 = `rf2' + 1 + } + if "`ustd'"~=""{ + *disp in re "variance = " `vari' + qui replace `pref's`rf' = sqrt(`vari'-`pref's`rf') + qui replace `pref'm`rf' = `pref'm`rf'/`pref's`rf' + } + else{ + qui replace `pref's`rf' = sqrt(`pref's`rf') + } + ** 11/4/06 + if "`corr'"~=""{ + *set trace on + local rfs = 1 + while `rfs'<`rf'{ + *disp in re "generating `pref'c`rf'`rfs'" + qui gen double `pref'c`rf'`rfs'=0 + local rf2 = `minrf' + while `rf2'<= `rf' { + local rf3 = 1 + while `rf3'<= `rfs'{ + *disp in re "add CHmat[`rf',`rf2']*CHmat[`rfs',`rf3']*HG_C`rf2'`rf3'" + if `rf3'<`rf2'{ + qui replace `pref'c`rf'`rfs' = `pref'c`rf'`rfs' + CHmat[`rf',`rf2']*CHmat[`rfs',`rf3']*${HG_C`rf2'`rf3'} + } + else if `rf3'==`rf2'{ + qui replace `pref'c`rf'`rfs' = `pref'c`rf'`rfs' + CHmat[`rf',`rf2']*CHmat[`rfs',`rf3']*${HG_SD`rf2'}^2 + } + else{ + qui replace `pref'c`rf'`rfs' = `pref'c`rf'`rfs' + CHmat[`rf',`rf2']*CHmat[`rfs',`rf3']*${HG_C`rf3'`rf2'} + } + local rf3 = `rf3' + 1 + } + local rf2 = `rf2' + 1 + } + qui replace `pref'c`rf'`rfs' = `pref'c`rf'`rfs'/(`pref's`rf'*`pref's`rfs') + local rfs = `rfs' + 1 + } + *set trace off + } + local rf = `rf' + 1 + } + local lv = `lv' + 1 + } + } + else{ /* not $HG_free */ + local i = 1 + while `i'<$HG_tprf{ + qui gen double `pref'm`i'=${HG_MU`i'} + qui gen double `pref's`i'=${HG_SD`i'} + local rf2 = 1 + while `rf2'<`i'{ + qui gen double `pref'c`i'`rf2' = ${HG_C`i'`rf2'}/(`pref's`i'*`pref's`rf2') + local rf2 = `rf2' + 1 + } + local i = `i' + 1 + } + } + if "`fac'"~=""{ + *disp "dealing with geqs" + tempname junk s1 + local i = 1 + while `i'<=$HG_ngeqs{ + local k = M_ngeqs[1,`i'] + local n = M_ngeqs[2,`i'] + local nxt = M_ngeqs[3,`i'] + * disp "random effect `k'-1 has `n' covariates" + local nxt2 = `nxt'+`n'-1 + matrix `s1' = `b'[1,`nxt'..`nxt2'] + * matrix list `s1' + local nxt = `nxt2' + 1 + capture drop `junk' + matrix score double `junk' = `s1' + local rf = `k' - 1 + qui replace `pref'm`rf' = `pref'm`rf' + `junk' + local i = `i' + 1 + } + *disp "dealing with bmat" + if $HG_bmat{ + local rf = $HG_tprf - 1 + /* commands for sds are wrong: qui replace `pref's`rf' = `pref's`rf'^2 */ + local rf = $HG_tprf - 2 + while `rf'>0{ + * qui replace `pref's`rf' = `pref's`rf'^2 + local rf2 = `rf'+1 + while `rf2'<=$HG_tprf - 1 { /* upper triangular matrix */ + *disp in re "`pref'm`rf'=`pref'm`rf'+Bmat[`rf',`rf2']*`pref'm`rf2'" + qui replace `pref'm`rf'=`pref'm`rf'+Bmat[`rf',`rf2']*`pref'm`rf2' + *qui replace `pref's`rf'=`pref's`rf'+Bmat[`rf',`rf2']^2*`pref's`rf2'/* + * */ + 2*Bmat[`rf',`rf2']*CHmat[`rf2',`rf2']*CHmat[`rf',`rf']${HG_C`rf2'`rf'} + *local rf3 = `rf' + 1 + *while `rf3'<`rf2'{ + * qui replace `pref's`rf'=`pref's`rf' /* + * */ + 2*Bmat[`rf',`rf2']*Bmat[`rf',`rf3']*CHmat[`rf2',`rf2']*CHmat[`rf3',`rf3']${HG_C`rf2'`rf3'} + * local rf3 = `rf3' + 1 + *} + local rf2 = `rf2' + 1 + } + local rf = `rf' -1 + } + local rf = 1 + while `rf'<=$HG_tprf - 1{ + * qui replace `pref's`rf' = sqrt(`pref's`rf') + drop `pref's`rf' + local rf = `rf' + 1 + } + } + } + } + else if "`linpred'"~="" { /* linpred */ + /* set up variable names $HG_xb1 for remcor */ + local i = 1 + while (`i' <= $HG_tpff){ + tempname junk + global HG_xb`i' "`junk'" + local i = `i' + 1 + } + /* set up names for HG_s`i' */ + local i = 1 + while (`i'<=$HG_tprf){ + tempname junk + global HG_s`i' "`junk'" + local i = `i'+1 + } + + qui remcor `b' + * fixed part + + qui gen double `pref' = $HG_xb1 + if "`offset'"~=""&"$HG_off"~=""{ + qui replace `pref' = `pref' - $HG_off + } + + * add random part + local i = 2 + while (`i' <= $HG_tprf){ + local im = `i' - 1 + qui replace `pref' = `pref' + ${HG_MU`im'} * ${HG_s`i'} + local i = `i' + 1 + } + } + } + } +/* delete macros */ + delmacs + } /* endelse influence */ + qui keep `idno' `vars' + qui sort `idno' + qui save "`file'", replace + restore + sort `idno' + tempvar mrge + qui merge `idno' using "`file'", _merge(`mrge') + qui drop `mrge' +end + +program define setmacs +version 6.0 +args what +/* sort out depvar */ + local depv "`e(depvar)'" + global ML_y1 "`depv'" + + +/* link and family-related macros */ + global HG_famil "`e(famil)'" + global HG_link "`e(link)'" + global HG_linko "`e(linko)'" + global HG_nolog = `e(nolog)' + global HG_ethr = `e(ethr)' + global HG_mlog = `e(mlog)' + global HG_smlog = `e(smlog)' + global HG_oth = `e(oth)' + global HG_lv "`e(lv)'" + global HG_fv "`e(fv)'" + capture matrix M_resp=e(mresp) + capture matrix M_respm=e(mrespm) + capture matrix M_frld=e(frld) + capture matrix M_olog=e(olog) + capture matrix M_oth=e(moth) + global HG_exp = e(exp) + global HG_expf = e(expf) + global HG_ind = "`e(ind)'" + global HG_lev1 = e(lev1) + global HG_comp = e(comp) + capture local coall "`e(coall)'" + if $HG_comp~=0{ + local i = 1 + while `i'<=$HG_comp{ + local k: word `i' of `coall' + global HG_co`i' `k' + local i = `i' + 1 + } + } + +/* macros related to priors */ + global HP_prior = 0 /* assume that we never use the prior in gllapred */ + +/* set all other global macros */ + global HG_nats = `e(nats)' + global HG_noC = `e(noC)' + global HG_noC1 = `e(noC1)' + global HG_adapt = `e(adapt)' + global HG_tplv = e(tplv) + global HG_tpff = `e(tpff)' + global HG_tpi = `e(tpi)' + global HG_tprf = e(tprf) + local tprf = $HG_tprf + global HG_free = e(free) + global HG_mult = e(mult) + global HG_lzpr lzprobg + global HG_zip zipg + if $HG_mult{ + global HG_lzpr lzprobm + } + else if $HG_free{ + global HG_lzpr lzprobf + global HG_zip zipf + matrix M_np=e(mnp) + } + global HG_cip = e(cip) + global which = 1 + global HG_off "`e(offset)'" + global HG_error = 0 + global HG_cor = `e(cor)' + global HG_bmat = e(bmat) + global HG_const = 0 + global HG_ngeqs = e(ngeqs) + global HG_inter = e(inter) + global HG_dots = 0 + global HG_init = e(init) + matrix M_nbrf = e(nbrf) + matrix M_nrfc = e(nrfc) + matrix M_ip = J(1,$HG_tprf+2,1) + matrix M_nffc = e(nffc) + if $HG_tprf<2{ local tprf = 2} + matrix M_znow =J(1,`tprf'-1,1) + matrix M_nip = e(nip) + capture matrix M_ngeqs = e(mngeqs) + capture matrix M_b=e(mb) + capture matrix M_chol = e(chol) +local lev = 2 +while `lev'<=$HG_tplv{ + local l = M_nrfc[1,`lev'-1] + 1 /* loop */ + local k = M_nrfc[2,`lev'-1] + 1 /* r. eff. */ + while `l'<=M_nrfc[1,`lev']&$HG_tplv>1{ + local tp = M_nrfc[2,`lev'] + if $HG_mult{ + local tp = `k' /* only one z-matrix per level */ + } + while `k'<=`tp'{ + *disp "loop " `l' " random effect " `k' + local kk = `k' + if $HG_mult{ + local kk = `l' + } + local w = M_nip[2,`kk'] + + /* same loc and prob as before? */ + local found = 0 + local ii=M_nrfc[2,1] + 1 + while `ii'<`kk'{ + if `w'==M_nip[2,`ii']{ + local found = 1 + } + local ii = `ii'+1 + } + + + capture matrix M_zps`w' =e(zps`w') + *matrix list M_zps`w' + if `what'==2{ + if $HG_free { + if `k' == M_nrfc[1,`l']{ + local nip = colsof(M_zps`w') + noi disp in gr "prior probabilities" + + + local j = 2 + local zz=string(exp(M_zps`w'[1,1]),"%6.0gc") + if `nip'>1{ + local mm "0`zz'" + } + else{ + local mm "1" + } + + while `j'<=`nip'{ + local zz=string(exp(M_zps`w'[1,`j']),"%6.0gc") + local mm "`mm'" ", " "0`zz'" + local j = `j' + 1 + } + disp in gr " prob: " in ye "`mm'" + + disp " " + } + } + else if `found'==0{ + *noi disp in gr "probabilities for `w' quad. points" + *noi matrix list M_zps`w' + *disp " " + } + } + * disp "M_zlc`w'" + matrix M_zlc`w'=e(zlc`w') + *matrix list M_zlc`w' + if `what'==2{ + if $HG_free{ + noi disp in gr "locations for random effect " `w'-1 + local mm=string(M_zlc`w'[1,1],"%6.0gc") + local j = 2 + while `j'<= `nip'{ + local zz=string(M_zlc`w'[1,`j'],"%6.0gc") + local mm "`mm'" ", " "`zz'" + local j = `j' + 1 + } + disp in gr " loc: " in ye "`mm'" + disp " " + } + else if `found'==0{ + *noi disp in gr "locations for `w' quadrature points" + *noi matrix list M_zlc`w' + *disp " " + } + + } + local k = `k' + 1 + } + local l = `l' + 1 + } +local lev = `lev' + 1 +} +end + +program define delmacs + version 6.0 +/* deletes all global macros and matrices*/ + tempname var + if "$HG_tplv"==""{ + * macros already gone + exit + } + local nrfold = M_nrfc[2,1] + local lev = 2 + while (`lev'<=$HG_tplv){ + local i2 = M_nrfc[2,`lev'] + local i1 = `nrfold'+1 + local i = `i1' + local nrfold = M_nrfc[2,`lev'] + while `i' <= `i2'{ + local n = M_nip[2,`i'] + if `i' <= M_nrfc[1,`lev']{ + capture matrix drop M_zps`n' + } + capture matrix drop M_zlc`n' + local i = `i' + 1 + } + local lev = `lev' + 1 + } + if $HG_free==0&$HG_init==0{ + matrix drop M_chol + } + matrix drop M_nrfc + matrix drop M_nffc + matrix drop M_nbrf + matrix drop M_ip + capture matrix drop M_b + capture matrix drop M_resp + capture matrix drop M_respm + capture matrix drop M_frld + matrix drop M_nip + matrix drop M_znow + capture matrix drop M_ngeqs + capture matrix drop CHmat + + /* globals defined in gllam_ll */ + local i=1 + while (`i'<=$HG_tpff){ + global HG_xb`i' + local i= `i'+1 + } + local i = 1 + while (`i'<=$HG_tprf){ + global HG_s`i' + local i= `i'+1 + } + local i = 1 + while (`i'<=$HG_tplv){ + global HG_wt`i' + local i = `i' + 1 + } + global HG_nats + global HG_noC + global HG_noC1 + global HG_adapt + global HG_fixe + global HG_lev1 + global HG_bmat + global HG_tplv + global HG_tprf + global HG_tpi + global HG_tpff + global HG_clus + global HG_weigh + global which + global HG_gauss + global HG_free + global HG_famil + global HG_link + global HG_nolog + global HG_olog + global HG_mlog + global HG_smlog + global HG_oth + global HG_exp + global HG_expf + global HG_lv + global HG_fv + global HG_nump + global HG_eqs + global HG_obs + global HG_off + global HG_offs + global HG_denom + global HG_cor + global HG_s1 + global HG_init + global HG_ind + global HG_const + global HG_dots + global HG_inter + global HG_ngeqs + global HG_ethr + global HG_mult + global HG_lzpr + global HG_zip + global HG_cip + global HG_post + global HG_outc + global HG_comp + global HG_final + capture macro drop HG_co* + capture matrix drop M_above +end diff --git a/Modules/ado/plus/g/gllapred.hlp b/Modules/ado/plus/g/gllapred.hlp new file mode 100644 index 0000000..ed4f1fa --- /dev/null +++ b/Modules/ado/plus/g/gllapred.hlp @@ -0,0 +1,252 @@ +.- +help for ^gllapred^ +.- + +Predict command for gllamm +--------------------------- + +^gllapred^ varname [^if^ exp] [^in^ range] [,^u^ ^fac^ ^p^ ^xb^ + ^ustd^ ^co^oksd ^li^npred ^mu^ ^ma^rginal ^us(^varname^)^ + ^out^come^(^#^)^ ^ab^ove^(^#^,^...^,^#^)^ + ^pe^arson ^d^eviance ^a^nscombe + ^s^ ^ll^ ^fsample^ ^nooff^set + ^adapt^ ^adoonly^ ^fr^om^(^matrix^)^ ] + +where only one of ^xb^ ^u^ ^fac^ ^p^ ^li^npred ^mu^ + ^pe^arson ^d^eviance ^a^nscombe ^s^ ^ll^ +may be specified at a time. + + +Description +----------- + +^gllapred^ is a prediction command for @gllamm@. It computes + +-- Posterior means (empirical Bayes predictions) and standard +deviations of the latent variables or random effects for models +estimated using gllamm (see ^u^ and ^fac^ options). + +-- Posterior probabilities for two level models with discrete +latent variables or random effects (see ^p^ option). + +-- The fixed part of the linear predictor (^xb^ option) or the +entire linear predictor (^linpred^ option) with empirical Bayes +estimates substituted for the latent variables or random effects. + +-- The expectation of the response (see ^mu^ option). By default, +the expectation is with respect to the posterior distribution +of the latent variables, but the ^marginal^ option gives the +expectation with respect to the prior distribution. +The ^us()^ option can be used to get the conditional expectation +for specified values of the latent variables. + +--- Pearson, Deviance or Anscombe residuals. By default, +the posterior expectation, but the ^us^ option gives the +residuals for specified values of the latent variables. + +-- The level 1 standard deviation (see ^s^ option). + +-- Log-likelihood contributions of the highest level clusters +(see ^ll^ option). + +In some cases the log-likelihood is also returned. +By default prediction is restricted to the estimation sample. +In this case (and if the ^if^ and ^in^ options are not specified), +the log-likelihood returned by gllapred should be the same +as that previously returned by gllamm. + + + +Options +-------- + +^u^ the posterior means and standard deviation of the latent + variables or random effects are returned in "varname"m1, + "varname"m2, etc., and "varname"s1, "varname"s2, etc., + respectively, where the order of the latent variables is + the same as in the call to gllamm (in the order of the + equations in the eqs() option). In the case of continuos + latent variables, the number of quadrature points used + is also the same as in the previous call to gllamm. If + the gllamm model includes equations for the latent variables + (geqs and/or bmatrix), the posterior means and standard + deviations of the disturbances are returned. + +^corr^ the posterior correlations of the random effects + or latent variables are returned in "varname"c21, etc. + This option only works together with the ^u^ option. If + the model includes equations for the latent variables, + posterior correlations of the disturbances are calculated. + +^fac^ If the gllamm model includes equations for the latent + variables (^geqs()^ and/or ^bmatrix()^), ^fac^ causes + predictions of the latent variables (e.g. factors) to be + returned in "varname"m1, "varname"m2, etc. instead of the + disturbances. In other words, predictions of the latent + variables on the left-hand side of the equations are returned. + +^p^ can only be used for two-level models estimated using the + ip(f) option. gllapred returns the posterior probabilities + in "varname"1, "varname"2, etc., giving the probabilities + of classes 1,2, etc. gllapred also prints out the (prior) + probability and location matrices to help interpret the + posterior probabilities. + +^xb^ the linear predictor for the fixed effects is returned. This + includes the offset (if there is one in the gllamm model) + unless the ^nooffset^ option is specified. + +^ustd^ standardized posterior mean - approximate sampling + standard deviation is used, sqrt(prior var. - posterior var.) + +^cooksd^ Cook's distances for the top-level units. + +^linpred^ returns the linear predictor including both the fixed + and random parts where posterior means are substituted + for the latent variables or random effects in the random + part. The offset is included (if there is one in the + gllamm model) unless the ^nooffset^ option is specified. + +^mu^ returns the expecation of the response, for example + the predicted probability in the case of dichotomous + responses. By default, the expectation is with respect + to the posterior distribution of the latent variables, + but see ^marginal^ and ^us()^ options. The offset is included + (if there is one in the gllamm model) unless the + ^nooffset^ option is specified. + +^marginal^ together with the ^mu^ option gives the + expectation of the response with respect to the prior + distribution of the latent variables. This is useful + for looking at the 'marginal' or population average + effects of covariates. + +^us(^varname)^ can be used to specify values for the latent + variables to calculate conditional quantities, such as + the conditional mean of the responses (^mu^ option) + given the values of the latent variables. Here varname + specifies the stub-name (prefex) for the variables and + ^gllapred^ will look for "varname"1 "varname"2, etc. + +^outcome(^#^)^ specifies the outcome for which the predicted + probability should be returned (^mu^ option) if there + is a nominal response. This option is not necessary if the + ^expanded()^ option was used in ^gllamm^ since in this + case predicted probabilities are returned for all outcomes. + +^above(^#^,^...^,^#^)^ specifies the events for which the + predicted probabilities should be returned (^mu^ option) + if there are ordinal responses. The probability of + a value higher than that specified is returned for each + ordinal response. A single number can be given for all + ordinal responses. + +^pearson^ returns Pearson residuals. By default, the posterior + expectation with respect to the latent variables is + returned. The ^us()^ option can be used to obtain the + conditional residual when certain values are substituted + for the latent variables. + +^deviance^ returns deviance residuals. By default, the posterior + expectation with respect to the latent variables is + returned. The ^us()^ option can be used to obtain the + conditional residual when certain values are substituted + for the latent variables. + +^anscombe^ returns Anscombe residuals. By default, the posterior + expectation with respect to the latent variables is + returned. The ^us()^ option can be used to obtain the + conditional residual when certain values are substituted + for the latent variables. + +^s^ returns the scale or standard deviation. This is useful + if the ^s()^ option was used in gllamm to specify level 1 + heteroscedasticity. + +^ll^ returns the log-likelihood contributions of the highest + level (level L) units. + +^adapt^ if the gllamm command did not use the adapt option, + gllapred will use ordinary quadrature for computing the + posterior means and standard deviations unless the adapt + option is used in the gllapred command. + +^fsample^ causes gllapred to return predictions for the + full sample (except observations exluded due to the + if and in options), not just the estimation sample. + The returned log-likelihood may be missing since + gllapred will not exclude observations with missing + values on any of the variables used in the likelihood + calculation. It is up to the user to exclude these + observations using if or in. + +^nooffset^ can be used together with the ^xb^, ^linpred^ or + ^mu^ options to exclude the offset from the prediction. + It will only make a difference if the offset option + was used in gllamm. + +^adoonly^ causes all gllamm to use only ado-code. This option + is not necessary if gllamm was run with the adoonly option. + +^from(^matrix^)^ specifies a matrix of parameters for which + the predictions should be made. The column and equation + names will be ignored. Without this option, the parameter + estimates from the last gllamm model will be used. + +Examples +-------- + +Estimate parameters of a three level logistic regression model: + + . ^gllamm resp x, i(id school) adapt trace family(binom)^ + + +Predict random intercepts using empirical Bayes: + + . ^gllapred int, u^ + + +Predict marginal probability that resp=1 (with respect to random effects): + + . ^gllapred prob, mu marginal^ + + +Predict conditional probability that resp==1 if random intercepts are 0: + + . ^gen z1 = 0^ + . ^gen z2 = 0^ + . ^gllapred prob, us(z)^ + + +Predict posterior mean of Pearson residual + + . ^gllapred res, pearson^ + +Predict Pearson residual when random effects are equal to their posterior +means (note that ^gllapred int, u^ above produced empirical Bayes +predictions in intm1 intm2): + + . ^gllapred res, pearson us(intm)^ + + +Author +------ +Sophia Rabe-Hesketh (sophiarh@@berkeley.edu) +as part of joint work with Andrew Pickles and Anders Skrondal. + + +Web-page +-------- +http://www.gllamm.org + + +References +---------- +Rabe-Hesketh, S., Skrondal, A. and Pickles, A. (2004). GLLAMM Manual. +U.C. Berkeley Division of Biostatistics Working Paper Series. +Working Paper 160. + + +Also see +-------- +On-line: help for @gllamm@, @gllasim@ diff --git a/Modules/ado/plus/g/gllarob.ado b/Modules/ado/plus/g/gllarob.ado new file mode 100644 index 0000000..1b64c7d --- /dev/null +++ b/Modules/ado/plus/g/gllarob.ado @@ -0,0 +1,1168 @@ +*! version 2.2.5 SRH 7 Sept 2011 +program define gllarob, eclass + version 6.0 + + syntax [,CLuster(varname) DOts First Macs SCorefil(string) temp noROb] + + tempname Vr b V + matrix `V' = e(V) + matrix `b' = e(b) + +/* first: have not computed robust se before */ +/* macs: macros are already there */ +/* rob: do not compute/report robust ses */ + +*disp in re "first = `first' and mac= `macs' " + +/* sort out depvar */ + local depv "`e(depvar)'" + global ML_y1 "`depv'" + + +/* sort out scorefil */ + + if "`scorefil'"~=""{ + if "`e(scorefil)'"~=""{ + disp in re "There is already a score file `e(scorefil)', option ignored" + local score + } + else{ + * check if file can be opened + capture postfile junk a using "`scorefil'" + if _rc~=0{ + disp in re "cannot open `scorefil'.dta for writing" + exit 198 + } + postclose junk + local score "`scorefil'" + } + + } +/* sort out first and calc */ + if "`first'"~=""{ + local first = 1 + local calc = 1 + + } + else{ + local first = 0 + } + + local robu = 1 + if "`rob'"~=""{ + local robu = 0 + } + if `first' == 0 { + global HG_const = e(const) + matrix `V' = e(Vs) + local robclus "`e(robclus)'" + local calc = 0 + * disp "`robclus' == `cluster' ?" + capture matrix `Vr' = e(Vr) + if _rc>0|"`robclus'"~="`cluster'"{ + local calc = 1 + } + if "`score'"~=""{ + local calc = 1 + } + } + * disp "first = " `first' " and calc = " `calc' + *if `first'==0& `calc' { + if "`macs'"==""& `calc' { + if "`cluster'"~=""{ + qui count if `cluster'==.&e(sample) + if r(N)>0{ + disp in re "`cluster' has missing values in the estimation sample" + exit(198) + } + } + preserve + qui keep if e(sample) +/* set all global macros needed by gllam_ll */ + setmacs +/* sort out temporary variables */ +/* sort out weight */ + local weight "`e(weight)'" + global HG_weigh "`e(weight)'" + local pweight "`e(pweight)'" +*10/29/06 + local numlv: word count `e(clus)' + tempvar wt + quietly gen double `wt'=1 +*End 10/29/06 + local i = 1 + while `i'<= `numlv'{ /* 10/29/06 not $HG_tplv{ because wrong for init option */ + tempvar wt`i' + qui gen double `wt`i''=1 + global HG_wt`i' "`wt`i''" + capture confirm variable `weight'`i' + if _rc==0 { + qui replace `wt`i'' = `wt`i'' * `weight'`i' + } + capture confirm variable `pweight'`i' + if _rc==0{ + qui replace `wt`i'' = `wt`i'' * `pweight'`i' + } +*10/29/06 + qui replace `wt' = `wt'*`wt`i'' + local i = `i'+1 + } +*10/29/06 + if `e(init)'{ + qui replace `wt1' = `wt' + } + +/* sort out level 1 clus variable */ + local clus `e(clus)' + global HG_clus `clus' + tempvar id + if $HG_exp~=1&$HG_comp==0{ + gen long `id'=_n + if $HG_tplv == 1{ + global HG_clus "`id'" + } + else{ + tokenize "`clus'" + local l= $HG_tplv + local `l' "`id'" + global HG_clus "`*'" + } + } + * disp in re "HG_tplv = " $HG_tplv " and HG_clus: $HG_clus" +/* sort out denom */ + local denom "`e(denom)'" + if "`denom'"~=""{ + capture confirm variable `denom' + if _rc>0{ + tempvar den + qui gen byte `den'=1 + global HG_denom "`den'" + } + else{ + global HG_denom `denom' + } + } + +/* sort out HG_ind */ + capture confirm variable $HG_ind + if _rc>0{ + tempname junk + global HG_ind "`junk'" + gen byte $HG_ind=1 + } + +/* sort out HG_lvolo (from gllapred) */ + if $HG_nolog>0{ + tempname junk + global HG_lvolo "`junk'" + qui gen byte $HG_lvolo = 0 + local no = 1 + if "$HG_lv"==""{ + local olog = M_olog[1,`no'] + qui replace $HG_lvolo = 1 + } + else{ + while `no'<=$HG_nolog{ + local olog = M_olog[1,`no'] + qui replace $HG_lvolo = 1 if $HG_lv == `olog' + local no = `no' + 1 + } + } + } + +/** (from gllapred) **/ + if $HG_mlog>0{ + if $HG_nolog==0{ + tempname junk + global HG_lvolo "`junk'" + qui gen byte $HG_lvolo = 0 + } + if "$HG_lv"~=""{ /* more than one link */ + qui replace $HG_lvolo = 1 if $HG_lv == $HG_mlog + } + else{ + qui replace $HG_lvolo = 1 + } + } + + + +/* sort out constraints */ + if $HG_const { + * disp "constraints used" + matrix `b' = `b'*M_T + matrix `V' = M_T'*`V'*M_T + *matrix junk = M_T*`V'*M_T' + * matrix list junk + } + + tempname junk + capture matrix `junk' = inv(`V') + if _rc>0{ + disp in re "parameter covariance matrix not invertible" + exit(198) + } + +/* set up HG_MU, HG_SD and HG_Cij */ + local rf = 1 + while `rf'<=$HG_tprf{ + tempname junk + global HG_MU`rf' "`junk'" + tempname junk + global HG_SD`rf' "`junk'" + gen double ${HG_MU`rf'}=0 + gen double ${HG_SD`rf'}=1 + local rf2 = `rf' + 1 + while `rf2' < $HG_tprf { + tempname junk + global HG_C`rf2'`rf' "`junk'" + gen double ${HG_C`rf2'`rf'}=0 + local rf2 = `rf2' + 1 + } + local rf = `rf' + 1 + } + } + +/* endif set-up macros and variables */ + +/* compute scores and/or robust standard errors */ + if `calc'{ + *set trace on + tempvar tpwt + gen int `tpwt' = 1 + global HG_tpwt "`tpwt'" + local weight "$HG_weigh" +* 10/20/06 + if $HG_init{ + local numlv: word count `e(clus)' + local i = 1 + while `i'<=`numlv'{ + capture confirm variable `weight'`i' + if _rc==0{ + qui replace `tpwt' = `tpwt'*`weight'`i' + } + local i = `i' + 1 + } + } + else{ + local l = $HG_tplv + capture confirm variable `weight'`l' + if _rc==0 { + /* there are frequency weights at the top level */ + qui replace `tpwt' = `tpwt' * `weight'`l' + } + } + *summ `tpwt' + * disp "before comprob, HG_const = " $HG_const " and first = " `first' + noi cap noi comprob3 "`b'" "`V'" "`cluster'" "`score'" "`dots'" `robu' + if _rc>0{ + disp in re "something went wrong in comprob3" + delmacs + exit 198 + } + matrix `Vr' = `V' + } + +/* post results */ + *disp in re "temp = `temp' score = `score' " + if "`score'"~=""&"`temp'"==""{ + est local scorefil "`score'" + } + if `robu'{ + * disp "after comprob, HG_const = " $HG_const " and first = " `first' + if $HG_const&`first' == 0{ + matrix `V' = `Vr' + est matrix Vr `V' + tempname M_T + matrix `M_T'=e(T) + matrix `Vr' = `M_T'*`Vr'*`M_T'' + * matrix list `Vr' + } + else{ + matrix `V' = `Vr' + est matrix Vr `V' + * matrix list e(Vr) + } + estimates repost V = `Vr' + est local robclus "`cluster'" + } + if `first' == 0&`calc'{ + delmacs + } + +end + + +program define comprob3 +version 6.0 +args coeffs var cluster score dots rob +*set trace on + *disp in re "in comprob3: dots=`dots', score = `score', rob=`rob' " + if "`cluster'"~=""{ + local cluster cluster(`cluster') + } + *disp "cluster is `cluster'" + *matrix list `coeffs' + + tempvar where last + local l = $HG_tplv + local weight "$HG_tpwt" + + if $HG_tplv>1{ + local top: word 1 of $HG_clus + } + else{ + local k: word count $HG_clus + local top: word `k' of $HG_clus + } + sort `top' $HG_ind + qui by `top': gen byte `last' = _n==_N + qui by `top': gen int `where' = _n==1 + qui replace `where' = sum(`where') + local n = colsof(`coeffs') + +/* compute scores */ +if "`e(scorefil)'"==""{ + *disp "Computing scores" + tempname b1 lnf + tempname S g fm fp fm0 S0 h Sgoal0 Sgoal1 Sming + tempvar llp llm lls done dfvar ok goal0 goal1 mingoal + +/* sort out adapt */ + local adapt = 0 + if $HG_adapt==1{ + local adapt = 1 + } + if `adapt'{ + tempname llast lnf + global HG_adapt=1 + noi gllam_ll 1 `coeffs' "`lnf'" "junk" "junk" 1 + disp in gre "Non-adaptive log-likelihood: " in ye `lnf' + scalar `llast' = 0 + local i = 1 + qui `noi' disp in gr "Updating posterior means and variances" + qui `noi' disp in gr "log-likelihood: " + while abs((`llast'-`lnf')/`lnf')>1e-8&`i'<60{ + scalar `llast' = `lnf' + qui gllam_ll 1 "`coeffs'" "`lnf'" "junk" "junk" 1 + disp in ye %10.4f `lnf' " " _c + if mod(`i',6)==0 {disp " " } + local i = `i' + 1 + } + } + + qui gen double `llm'=. + qui gen double `llp'=. + qui gen double `lls'=. + gllam_ll 1 `coeffs' "`lnf'" "junk" "junk" 3 "`lls'" + * with mlogit link, all but last lls are missing: + sort `top' `last' + qui by `top': replace `lls' = `lls'[_N] + + if abs((`lnf'-`e(ll)')/`e(ll)')>1e-5{ + disp in re "can't get correct log-likelihood: " `lnf' " should be " `e(ll)' + exit 198 + } + + *disp in re "got the right likelihood: " `e(ll)' + + qui count if `last'>0 + local N = r(N) + + + local l 1e-8 + local u 1e-7 + local m 1e-10 + local epsf 1e-3 + local j = 1 + * disp "N = " `N' + + * CHANGED TO VARIABLES + gen double `goal0' = (abs(`lls')+`l')*`l' + gen double `goal1' = (abs(`lls')+`u')*`u' + gen double `mingoal' = (abs(`lls')+`m')*`m' + + qui gen byte `done' = 0 + qui gen byte `ok' = 0 + qui gen double `dfvar' = 0 + + local ds + local ss + + local i = 1 + while `i'<=`n'{ /* loop over parameters */ + * if "`dots'"~=""{ noi disp in gr "." _c} +*JUNK + * disp in re " " + * disp in re "parameter " `i' + scalar `S' = 1 /* ML_d0_S[1,`i'] */ + scalar `h' = (abs(`coeffs'[1,`i'])+`epsf')*`epsf' + matrix `b1' = `coeffs' + +/* find zero derivatives */ + + matrix `b1'[1,`i'] = `coeffs'[1,`i']+500*`h'*`S' +*JUNK +* noi matrix list `b1' + gllam_ll 1 `b1' "`lnf'" "junk" "junk" 3 "`llp'" + + matrix `b1'[1,`i'] = `coeffs'[1,`i']-500*`h'*`S' +*JUNK +* noi matrix list `b1' + gllam_ll 1 `b1' "`lnf'" "junk" "junk" 3 "`llm'" + + qui replace `done' = abs(`llp' - `llm')<`goal0' /* derivative is zero */ + sort `top' `last' + qui by `top': replace `done' = `done'[_N] + +*JUNK +* disp in re "non-zero derivatives for following clusters (showing lls llm llp and goal0) step = " 1000*`h'*`S' +* noi list `top' `lls' `llm' `llp' `goal0' if `last'==1&`done'==0 + + tempvar d`i' + qui gen double `d`i''= 0 if `done' == 1&`last'==1 + local ds "`ds' `d`i''" + + if "`score'"~=""{ + tempvar s`i' + qui gen double `s`i''= 0 if `done' == 1&`last'==1 + local ss "`ss' `s`i''" + } + + qui count if `done'==0&`last'==1 + local num = r(N) + + while `num'>0{ + **disp "`num' clusters left to do" + scalar `S' = 1 /* ML_d0_S[1,`i'] */ + if "`dots'"~=""{ noi disp in ye "." _c} + sort `done' `where' + local nxt = `where'[1] + scalar `lnf' = `lls'[1] + + scalar `Sgoal0' = (abs(scalar(`lnf'))+`l')*`l' + scalar `Sgoal1' = (abs(scalar(`lnf'))+`u')*`u' + scalar `Sming' = (abs(scalar(`lnf'))+`m')*`m' + + preserve + + ***disp in re " " +*JUNK +* disp in re "sorting out cluster `nxt': `top' = " `top'[1] + qui keep if `where' == `nxt' + +*JUNK +* if `nxt'==241{disp in re "lnf = " `lnf' " goal0 = " `Sgoal0' " goal1 = " `Sgoal1'} + * disp in re "got here!" + GetStep `coeffs' `h' `S' `i' `Sgoal0' `Sgoal1' `Sming' `lnf' /* "`coeffs'" */ +*JUNK +* if `nxt'==241{ disp in re "after GetStep: S = " `S' " h = " `h'} + + restore + matrix `b1'[1,`i'] = `coeffs'[1,`i']-`h'*`S' + gllam_ll 1 `b1' "`lnf'" "junk" "junk" 3 "`llm'" + matrix `b1'[1,`i'] = `coeffs'[1,`i']+`h'*`S' + gllam_ll 1 `b1' "`lnf'" "junk" "junk" 3 "`llp'" + qui replace `dfvar' = abs(`lls'-`llm') + qui replace `ok' = `goal0'<`dfvar'&`dfvar'<`goal1' +*JUNK +* if `nxt'==241{ +* disp in re "goal0 = " `Sgoal0' " goal1 = " `Sgoal1' +* noi list `goal0' `goal1' if `where'==`nxt' +* disp in re "llm llp lls" +* noi list `llm' `llp' `lls' if `where'==`nxt' +* } + * first derivatives + qui replace `d`i'' = (`llp' - `llm')/(2*`h'*`S'*`weight') if `ok' == 1&`last'==1 + if "`score'"~=""{ + * second derivatives + qui replace `s`i'' = (`llp' + `llm' -2*`lls' )/(`h'*`S'*`h'*`S'*`weight') /* + */ if `ok' == 1&`last'==1 + } + qui replace `done' = 1 if `ok'==1 + sort `top' `last' + qui by `top': replace `done' = `done'[_N] + +*JUNK? + * if program didn't crash, derivative for `nxt' is valid: + qui replace `done' = 1 if `where'==`nxt' +/* + qui summ `done' if `where' == `nxt', meanonly + if abs(r(mean)-1)>1e-3{ + disp in re "Problem with derivative for parameter `i', cluster `nxt'" + } +*/ + qui count if `done'==0&`last'==1 + local num = r(N) + } + *summ `d`i'' + local i = `i'+1 + } +*set trace on + if "`score'"~=""{ + preserve + format `ds' `ss' %16.11g + qui outfile `top' `ds' `ss' if `last'==1 using "`score'.dta", replace + local tp `top' + if $HG_tplv==1{ + local tp __idno + } + qui infile `tp' double (d1-d`n' s1-s`n') using "`score'.dta", clear + qui sort `tp' + qui save "`score'", replace + restore + } +} /*endif*/ +/* compute robust ses */ + if `rob'{ + local es + local dds + local i = 1 + while `i'<=`n'{ + local dds "`dds' d`i'" + local es "`es' e`i'" + local i = `i' + 1 + } + * disp " " + local eqs: coleq(`var') + local rown: rownames(`var') + local coln: colnames(`var') + * matrix list `var' + matrix coleq `var' = `es' + matrix roweq `var' = `es' + matrix colnames `var' = _cons + matrix rownames `var' = _cons + + if "`e(scorefil)'"~=""{ + preserve + local tp `top' + if $HG_tplv == 1{ + rename $HG_clus __idno + local tp __idno + } + sort `tp' `last' + merge `tp' using `e(scorefil)' + noi _robust `dds' [fweight=`weight'] if `last'>0, `cluster' variance(`var') + restore + } + else{ + * matrix list `var' + *disp "before _robust, _rc = " _rc + *corr `ds', cov + * disp "_robust `ds' [fweight=`weight'] if `last'>0, `cluster' variance(`var')" + noi _robust `ds' [fweight=`weight'] if `last'>0, `cluster' variance(`var') + *disp "after _robust, _rc = " _rc + * matrix list `var' + } + + * disp "setting equation names" + matrix coleq `var' = `eqs' + matrix roweq `var' = `eqs' + matrix colnames `var' = `coln' + matrix rownames `var' = `rown' + * matrix list `var' + } + exit(0) +end + +program define GetStep + version 6.0 + + args a h S i goal0 goal1 mingoal lnf /* coeffs */ + + ***disp in re "In GetStep: h = " `h' " S = " `S' " i = " `i' " goal0 = " `goal0' + ***disp in re "goal0 = " `goal1' " mingoal = " `mingoal' " lnf = " `lnf' + tempname b1 S0 fm0 fp fm coeffs + matrix `coeffs' = `a' + matrix `b1' = `coeffs' + * matrix list `coeffs' + ***disp in re " " + +/***** from here, stolen from ml_adj */ + matrix `b1'[1,`i'] = `coeffs'[1,`i']-`h'*`S' + gllam_ll 1 `b1' "`fm'" + ***disp in re "in iteration 0, lnf = " `lnf' " and fm = " `fm' + +/* Save initial values of S and fm. */ + + scalar `S0' = `S' + scalar `fm0' = `fm' + + if `fm'==.{ + * disp in re "calling MisStep now" + * disp in re "step before: " `S' + MisStep `coeffs' `h' `S' `i' `lnf' + * disp in re "step before: " `S' + exit + } + +/* Compute df. We want goal0 <= df <= goal1. */ + + local df = abs(scalar(`lnf')-`fm') + + local Sold1 0 + local dfold1 0 + local iter 1 + + local itmax = 20 + + while (`df'<`goal0' | `df'>`goal1') & `iter'<=`itmax' { + + GetS `mingoal' `goal0' `goal1' `S' `df' /* interpolate ... + */ `Sold1' `dfold1' `Sold2' `dfold2' + local Sold2 `Sold1' + local dfold2 `dfold1' + local Sold1 = `S' + local dfold1 `df' + + scalar `S' = r(S) + + matrix `b1'[1,`i'] = `coeffs'[1,`i']-`h'*`S' +*JUNK +* noi disp in re "changing paramter by " `h'*`S' " to " `b1'[1,`i'] + gllam_ll 1 `b1' "`fm'" +*JUNK +* disp in re "in iteration `iter', S= " `S' " fm = " `fm' + + if `fm'==. { + * disp in re "calling MisStep now" + * disp in re "step before: " `S' + MisStep `coeffs' `h' `S' `i' `lnf' + * disp in re "step after: " `S' + exit + } + + local df = abs(scalar(`lnf')-`fm') + local iter = `iter' + 1 + } + + if `df'<`goal0' | `df'>`goal1' { /* did not meet goal */ + scalar `S' = `S0' /* go back to initial values */ + scalar `fm' = `fm0' /* guaranteed to be nonmissing */ + } + + matrix `b1'[1,`i'] = `coeffs'[1,`i']+`h'*`S' + gllam_ll 1 `b1' "`fp'" + + if `fp'==. { + * disp in re "calling MisStep now" + * disp in re "step before: " `S' + MisStep `coeffs' `h' `S' `i' `lnf' + * disp in re "step after: " `S' + exit + } + + if `df'<`goal0' | `df'>`goal1' { /* did not meet goal; we redo + stepsize adjustment looking at + both sides; starting values are + guaranteed to be nonmissing + */ +*JUNK +* disp in re "calling TwoStep now, lnf = " `lnf' +* disp in re "lnf = " `lnf' " fm = " `fm' " df = " `df' + * disp in re "step before: " `S' + TwoStep `fp' `fm' `coeffs' `h' `S' `i' `lnf' + * disp in re "step after: " `S' + + } +/***** up to here, stolen from ml_adj */ +end + +program define GetS, rclass +* stolen from ml_adj + args mingoal goal0 goal1 S df Sold1 dfold1 Sold2 dfold2 + + if `df' < `mingoal' { + /* di "GetS: below mingoal, doubling S --> 2*S" */ /* diag */ + return scalar S = 2*`S' + exit + } + +/* Interpolate to get f(newS)=mgoal. + + When `Sold2' and `dfold2' are empty (on the first iteration), we do + linear interpolation of f(S)=df, f(0)=0. + + Thereafter, we do quadratic interpolation with the current and previous + two positions. +*/ + tempname newS + local mgoal = (`goal0' + `goal1')/2 + + Intpol `newS' `mgoal' `S' `df' `Sold1' `dfold1' `Sold2' `dfold2' + + if `newS'==. | `newS'<=0 | (`df'>`goal1' & `newS'>`S') /* + */ | (`df'<`goal0' & `newS'<`S') { + + return scalar S = `S'*cond(`df'<`goal0',2,.5) + } + else return scalar S = `newS' +end + + +program define Intpol +* stolen from ml_adj + args y x y0 x0 y1 x1 y2 x2 + + if "`y2'"=="" { local linear 1 } + else if `y2'==. | `x2'==. { local linear 1 } + + if "`linear'"!="" { + scalar `y' = ((`y1')-(`y0'))*((`x')-(`x0'))/((`x1')-(`x0')) /* + */ + (`y0') + exit + } + + scalar `y' = /* +*/ (`y0')*((`x')-(`x1'))*((`x')-(`x2'))/(((`x0')-(`x1'))*((`x0')-(`x2'))) /* +*/ + (`y1')*((`x')-(`x0'))*((`x')-(`x2'))/(((`x1')-(`x0'))*((`x1')-(`x2'))) /* +*/ + (`y2')*((`x')-(`x0'))*((`x')-(`x1'))/(((`x2')-(`x0'))*((`x2')-(`x1'))) +end + + + + +program define MisStep /* This routine is called if missing values were + encountered in GetStep. + */ + + /* di "in MisStep!" */ /* diag */ + *args h S caller i fpout fmout x0 + args coeffs h S i lnf + *macro shift 7 + *local list "`*'" + + local itmax 50 + + tempname fm fp b1 + scalar `fm' = . + scalar `fp' = . + local iter 1 + while (`fm'==. | `fp'==.) & `iter'<=`itmax' { + scalar `S' = `S'/2 + + matrix `b1' = `coeffs' + matrix `b1'[1,`i'] = `coeffs'[1,`i']-`h'*`S' + gllam_ll 1 `b1' "`fm'" + + if `fm'!=. { + matrix `b1'[1,`i'] = `coeffs'[1,`i']+`h'*`S' + gllam_ll 1 `b1' "`fp'" + } + + local iter = `iter' + 1 + } + + if `fm'==. | `fp'==. { + di as err "could not calculate numerical derivatives" _n /* + */ "discontinuous region with missing values encountered" + exit 430 + } + + TwoStep `fp' `fm' `coeffs' `h' `S' `i' `lnf' +end + +program define TwoStep /* This routine is called if + + (1) goal was not reached, or + + (2) missing values were encountered + and MisStep then found nonmissing + values. + + Note: Input is guaranteed to be nonmissing + on both sides. + */ + + /* di "in two-step" */ /* diag */ + *args fp fm h S caller i fpout fmout x0 + args fp fm coeffs h S i lnf + *macro shift 9 + *local list "`*'" + + tempname bestS b1 + + local ep0 1e-8 + local ep1 1e-7 + local epmin 1e-12 + local itmax 40 + + local goal0 = (abs(scalar(`lnf'))+`ep0')*`ep0' + local goal1 = (abs(scalar(`lnf'))+`ep1')*`ep1' + local mingoal = (abs(scalar(`lnf'))+`epmin')*`epmin' + + local df = (abs(scalar(`lnf')-`fp')+abs(scalar(`lnf')-`fm'))/2 + local bestdf `df' + scalar `bestS' = `S' + local Sold1 0 + local dfold1 0 + local iter 1 + + while (`df'<`goal0' | `df'>`goal1') & `iter'<=`itmax' { + +*di "TwoStep iter = `iter' df = " %12.4e `df' " S = " %12.3e `S' + + GetS `mingoal' `goal0' `goal1' `S' `df' /* interpolate ... + */ `Sold1' `dfold1' `Sold2' `dfold2' + + local Sold2 `Sold1' + local dfold2 `dfold1' + local Sold1 = `S' + local dfold1 `df' + + scalar `S' = r(S) + + matrix `b1' = `coeffs' + matrix `b1'[1,`i'] = `coeffs'[1,`i']-`h'*`S' + gllam_ll 1 `b1' "`fm'" + + *Lik`caller' -`h'*`S' `i' `fm' `fmout' `x0' `list' + + if `fm'!=. { + matrix `b1'[1,`i'] = `coeffs'[1,`i']+`h'*`S' + gllam_ll 1 `b1' "`fp'" + * Lik`caller' `h'*`S' `i' `fp' `fpout' `x0' `list' + } + if `fm'==. | `fp'==. { + if `bestdf' >= `mingoal' { /* go with best value */ + scalar `S' = `bestS' + + matrix `b1' = `coeffs' + matrix `b1'[1,`i'] = `coeffs'[1,`i']-`h'*`S' + gllam_ll 1 `b1' "`fm'" + matrix `b1'[1,`i'] = `coeffs'[1,`i']+`h'*`S' + gllam_ll 1 `b1' "`fp'" + + di as txt /* + */ "numerical derivatives are approximate" /* + */ _n "nearby values are missing" + exit + } + + di as err /* + */ "could not calculate numerical derivatives" /* + */ _n "missing values encountered" + exit 430 + } + + local df = (abs(scalar(`lnf')-`fp')+abs(scalar(`lnf')-`fm'))/2 + + if `df'>1.1*`bestdf' | (`df'>=0.9*`bestdf' & `S'<`bestS') { + local bestdf `df' + scalar `bestS' = `S' + } + + local iter = `iter' + 1 + } + +*JUNK +*disp in re "TwoStep df = " %12.4e `df' " S = " %12.3e `S' " goal0 = " `goal0' " goal1 = " `goal1' " lnf = " `lnf' + + if `df'<`goal0' | `df'>`goal1' { /* did not reach goal */ + +disp in re "TwoStep: did not reach goal" + + if `bestdf' >= `mingoal' { /* go with best value */ + scalar `S' = `bestS' + + matrix `b1' = `coeffs' + matrix `b1'[1,`i'] = `coeffs'[1,`i']-`h'*`S' + gllam_ll 1 `b1' "`fm'" + matrix `b1'[1,`i'] = `coeffs'[1,`i']+`h'*`S' + gllam_ll 1 `b1' "`fp'" + + di as txt "numerical derivatives are approximate" /* + */ _n "flat or discontinuous region encountered" + } + else { + di as err "could not calculate numerical derivatives" /* + */ _n "flat or discontinuous region encountered" + exit 430 + } + } +end + + + +program define setmacs +version 6.0 +/* may not work for higher level models yet */ +/* tplv */ + global HG_tplv = e(tplv) + +/* link and family-related macros */ + global HG_famil "`e(famil)'" + global HG_link "`e(link)'" + global HG_linko "`e(linko)'" + global HG_nolog = `e(nolog)' + global HG_ethr = `e(ethr)' + global HG_lv "`e(lv)'" + global HG_fv "`e(fv)'" + global HG_oth = e(oth) + global HG_mlog = e(mlog) + global HG_smlog = `e(smlog)' + capture matrix M_resp=e(mresp) + capture matrix M_respm=e(mrespm) + capture matrix M_frld=e(frld) + capture matrix M_olog=e(olog) + capture matrix M_oth=e(moth) + capture matrix ML_d0_S=e(do_S) + global HG_exp = e(exp) + global HG_expf = e(expf) + global HG_ind = "`e(ind)'" + global HG_init = e(init) + global HG_lev1 = e(lev1) + global HG_comp = e(comp) + capture local coall "`e(coall)'" + if $HG_comp~=0{ + local i = 1 + while `i'<=$HG_comp{ + local k: word `i' of `coall' + global HG_co`i' `k' + local i = `i' + 1 + } + } + +/* prior related global macros */ + global HP_prior = e(prior) + if $HP_prior == 1{ + global HP_sprd = 1 + global HP_invga = e(invga) + global HP_invwi = e(invwi) + global HP_foldt = e(foldt) + global HP_logno = e(logno) + global HP_gamma = e(gamma) + global HP_corre = e(corre) + global HP_boxco = e(boxco) + global HP_spect = e(spect) + global HP_wisha = e(wisha) + if $HP_invga==1{ + global shape = e(shape) + global rate = e(rate) + } + if $HP_invwi==1{ + global df = e(df) + matrix scale = e(scale) + } + if $HP_foldt==1{ + global df = e(df) + global scale = e(scale) + global location = e(location) + } + if $HP_logno==1{ + global meanlog = e(meanlog) + global sdlog = mean(sdlog) + } + if $HP_gamma==1{ + global HP_scale = e(scale) + global HP_var = e(var) + global HP_shape = e(shape) + } + if $HP_corre==1{ + global alpha = e(alpha) + global beta = e(beta) + } + if $HP_boxco==1{ + global scale = e(scale) + global lambda = e(lambda) + } + if $HP_spect==1{ + global alpha = e(alpha) + global beta = e(beta) + } + if $HP_wisha==1{ + global wisha = e(wisha) + global df = e(df) + matrix scale =e(scale) + } + matrix M_nu = e(nu) + } + + +/* set all other global macros */ + global HG_nats = `e(nats)' + global HG_noC = `e(noC)' + global HG_noC1 = `e(noC1)' + global HG_adapt = `e(adapt)' + global HG_tplv = e(tplv) + global HG_tpff = `e(tpff)' + global HG_tpi = `e(tpi)' + global HG_free = e(free) + global HG_mult = e(mult) + global HG_lzpr lzprobg + global HG_zip zipg + if $HG_mult{ + global HG_lzpr lzprobm + } + else if $HG_free{ + global HG_lzpr lzprobf + global HG_zip zipf + matrix M_np=e(mnp) + } + global HG_cip = e(cip) + global which = 4 + global HG_off "`e(offset)'" + global HG_error = 0 + global HG_cor = `e(cor)' + global HG_bmat = e(bmat) + global HG_tprf = e(tprf) + global HG_const = e(const) + if $HG_const==1{ + matrix M_T = e(T) + matrix M_a = e(a) + } + global HG_ngeqs = e(ngeqs) + global HG_inter = e(inter) + global HG_dots = 0 + matrix M_nbrf = e(nbrf) + matrix M_nrfc = e(nrfc) + matrix M_ip = J(1,$HG_tprf+2,1) + matrix M_nffc = e(nffc) + local tprf = $HG_tprf + if `tprf'<2 { local tprf = 2 } + matrix M_znow =J(1,`tprf'-1,1) + matrix M_nip = e(nip) + capture matrix M_ngeqs = e(mngeqs) + capture matrix M_b=e(mb) + *matrix M_chol = e(chol) + local l = M_nrfc[1,1] + 1 /* loop */ + local k = M_nrfc[2,1] + 1 /* r. eff. */ + if $HG_tplv>1{ + while `l'<=M_nrfc[1,2]{ + while `k'<=M_nrfc[2,2]{ + * disp "loop " `l' " random effect " `k' + local w = M_nip[2,`k'] + + /* same loc and prob as before? */ + local found = 0 + local ii=M_nrfc[2,1] + 1 + while `ii'<`k'{ + if `w'==M_nip[2,`ii']{ + local found = 1 + } + local ii = `ii'+1 + } + + + capture matrix M_zps`w' =e(zps`w') + + * disp "M_zlc`w'" + matrix M_zlc`w'=e(zlc`w') + local k = `k' + 1 + } + local l = `l' + 1 + } + } +end + +program define delmacs + version 6.0 +/* deletes all global macros and matrices*/ + tempname var + if "$HG_tplv"==""{ + * macros already gone + exit + } + local nrfold = M_nrfc[2,1] + local lev = 2 + while (`lev'<=$HG_tplv){ + local i2 = M_nrfc[2,`lev'] + local i1 = `nrfold'+1 + local i = `i1' + local nrfold = M_nrfc[2,`lev'] + while `i' <= `i2'{ + local n = M_nip[2,`i'] + if `i' <= M_nrfc[1,`lev']{ + capture matrix drop M_zps`n' + } + capture matrix drop M_zlc`n' + local i = `i' + 1 + } + local lev = `lev' + 1 + } + if $HG_free==0{ + capture matrix drop M_chol + } + matrix drop M_nrfc + matrix drop M_nffc + matrix drop M_nbrf + matrix drop M_ip + capture matrix drop M_b + capture matrix drop M_resp + capture matrix drop M_respm + capture matrix drop M_frld + matrix drop M_nip + matrix drop M_znow + capture matrix drop M_ngeqs + capture matrix drop CHmat + + /* globals defined in gllam_ll */ + local i=1 + while (`i'<=$HG_tpff){ + global HG_xb`i' + local i= `i'+1 + } + local i = 1 + while (`i'<=$HG_tprf){ + global HG_s`i' + local i= `i'+1 + } + local i = 1 + while (`i'<=$HG_tplv){ + global HG_wt`i' + local i = `i' + 1 + } + global HG_nats + global HG_noC + global HG_noC1 + global HG_noC2 + global HG_adapt + global HG_fixe + global HG_lev1 + global HG_bmat + global HG_tplv + global HG_tprf + global HG_tpi + global HG_tpff + global HG_clus + global HG_weigh + global which + global HG_gauss + global HG_free + global HG_famil + global HG_link + global HG_linko + global HG_nolog + global HG_lvolo + global HG_oth + global HG_mlog + global HG_exp + global HG_expf + global HG_lv + global HG_fv + global HG_nump + global HG_eqs + global HG_obs + global HG_off + global HG_denom + global HG_cor + global HG_s1 + global HG_init + global HG_ind + global HG_const + global HG_dots + global HG_inter + global HG_ngeqs + global HG_tpwt + global HG_ethr + global HG_mult + global HG_lzpr + global HG_zip + global HG_cip + global HG_comp + global HG_pwt + global HG_befB + global HG_smlog + global HG_cn + capture drop macro HG_co* +end diff --git a/Modules/ado/plus/g/gllas_yu.ado b/Modules/ado/plus/g/gllas_yu.ado new file mode 100644 index 0000000..ae2be3d --- /dev/null +++ b/Modules/ado/plus/g/gllas_yu.ado @@ -0,0 +1,662 @@ +*! version 1.0.4 SRH 12 September 2003 +program define gllas_yu + version 6.0 +* simulates y given u + args y lpred mu what + +if "`what'"==""{ + local what = 0 +} +* what=0: simulate y +* what=1: mu and y +* what=5: get mu, return in y +* what=6: Pearson residual +* what=7: Deviance residual +* what=8: Anscombe residual + + tempvar zu xb /* linear predictor and zu: r.eff*design matrix for r.eff */ + +/* ----------------------------------------------------------------------------- */ +*quietly{ + + * matrix list M_znow + * disp "ML_y1: $ML_y1 " $ML_y1[$which] + * matrix list M_ip + * disp " xb1 = " $HG_xb1[$which] + * disp " zu = " `zu'[$which] + + + if $HG_mlog>0{ + qui gen double `zu' = `lpred' - $HG_xb1 + if `what'<=1{ + simnom `y' `zu' + } + if `what'==1|`what'==5{ + nominal `mu' `zu' 5 + if `what'==5{ + qui replace `y' = `mu' + } + } + if `what'>5{ + nominal `y' `zu' `what' + } + } + + if $HG_oth{ + if "$HG_lv"~=""&($HG_nolog>0|$HG_mlog>0){ + local myand $HG_lvolo~=1 + } + *quietly gen double `mu' = 0 + link "$HG_link" `mu' `lpred' $HG_s1 + if $HG_comp>0{ + compos `mu' "`myand'" + } + if `what'==5{ + local ifs + if "`myand'"~=""{ + local ifs if `myand' + } + qui replace `y' = `mu' `ifs' + } + else{ + family "$HG_famil" `y' `mu' "`myand'" `what' + } + } + + if $HG_nolog>0{ + if `what'<=1{ + simord `y' `lpred' + } + if `what'==1|`what'==5{ + ordinal `mu' `lpred' 5 + if `what'==5{ + qui replace `y' = `mu' if $HG_lvolo==1 + } + } + if `what'>5{ + ordinal `y' `lpred' `what' + } + } + + + +*} /* qui */ +end + +program define compos + version 6.0 + args mu und + + tempvar junk mu2 + local ifs + if "`und'"~=""{ + local ifs if `und' + } + qui gen double `junk'=0 + qui gen double `mu2'=. + local i = 1 + *disp in re "in compos: HG_clus is: $HG_clus" + while `i'<= $HG_comp{ + *disp in re "in compos: variable HG_co`i' is: ${HG_co`i'}" + qui replace `junk' = `mu'*${HG_co`i'} + qui by $HG_clus: replace `junk' = sum(`junk') + qui by $HG_clus: replace `mu2' = `junk'[_N] if $HG_ind==`i' + local i = `i' + 1 + } + qui replace `mu' = `mu2' `ifs' +end + +program define nominal + version 6.0 + args res zu what + tempvar mu den + + if $HG_smlog{ + local s $HG_s1 + } + else{ + local s = 1 + } + local and + if "$HG_lv"~=""{ + local and & $HG_lv == $HG_mlog + local mlif if $HG_lv == $HG_mlog + } + * disp "mlogit link `mlif'" + if $HG_exp==1&$HG_expf==0{ + qui gen double `mu' = exp(`zu'/`s') if $ML_y1==M_respm[1,1] `and' + local n=rowsof(M_respm) + local i=2 + while `i'<=`n'{ + local prev = `i' - 1 + * disp "xb`prev':" ${HG_xb`prev'}[$which] + qui replace `mu' = exp( (${HG_xb`prev'} + `zu')/`s') if $ML_y1==M_respm[`i',1] `and' + local i = `i' + 1 + } + + sort $HG_clus $HG_ind + qui by $HG_clus: gen double `den'=sum(`mu') `mlif' + qui by $HG_clus: replace `mu' = `mu'/`den'[_N] `mlif' + if `what'>5{ + res_b `res' `mu' $HG_ind "`mlif'" " " `what' + * res_b res mu y if and what + } + } + else if $HG_exp==1&$HG_expf==1{ + qui gen double `mu' = exp(($HG_xb1 + `zu')/`s') `mlif' + sort $HG_clus $HG_ind + qui by $HG_clus: gen double `den'=sum(`mu') `mlif' + qui by $HG_clus: replace `mu' = `mu'/`den'[_N] `mlif' + if `what'>5{ + res_b `res' `mu' $HG_ind "`mlif'" " " `what' + } + } + else{ + tempvar den tmp + local n=rowsof(M_respm) + local i = 2 + qui gen double `mu' = 1 if $HG_outc==M_respm[1,1] `mlif' + qui gen double `den' = 1 + qui gen double `tmp' = 0 + while `i'<= `n'{ + local prev = `i' - 1 + qui replace `tmp' = exp((${HG_xb`prev'} + `zu')/`s') `mlif' + qui replace `mu' = `tmp' if $HG_outc==M_respm[`i',1] `mlif' + qui replace `den' = `den' + `tmp' `mlif' + local i = `i' + 1 + } + qui replace `mu' = `mu'/`den' `mlif' + if `what'>5{ + tempname y + qui gen `y' = $ML_y1==$HG_outc + res_b `res' `mu' `y' "`mlif'" " " `what' + } + } + if `what'==5{ + qui replace `res' = `mu' `mlif' + } + +end + +program define simnom + version 6.0 + args y zu + tempvar mu + tempvar r + qui gen double `r' = uniform() + + if $HG_smlog{ + local s $HG_s1 + } + else{ + local s = 1 + } + local and + if "$HG_lv"~=""{ + local and & $HG_lv == $HG_mlog + local mlif if $HG_lv == $HG_mlog + } + * disp "mlogit link `mlif'" + if $HG_exp==1&$HG_expf==0{ + qui gen double `mu' = `zu'/`s' -ln(-ln(`r')) if $ML_y1==M_respm[1,1] `and' + local n=rowsof(M_respm) + local i=2 + while `i'<=`n'{ + local prev = `i' - 1 + * disp "xb`prev':" ${HG_xb`prev'}[$which] + qui replace `mu' = (${HG_xb`prev'} + `zu')/`s' -ln(-ln(`r')) if $ML_y1==M_respm[`i',1] `and' + local i = `i' + 1 + } + + sort $HG_clus `mu' + qui by $HG_clus: replace `y'=_n==_N `mlif' + } + else if $HG_exp==1&$HG_expf==1{ + qui gen double `mu' = ($HG_xb1 + `zu')/`s' -ln(-ln(`r')) `mlif' + sort $HG_clus `mu' + qui by $HG_clus: replace `y'=_n==_N `mlif' + } + else{ + tempvar den tmp1 tmp2 + local n=rowsof(M_respm) + local i = 2 + qui gen double `mu' = 1 if $ML_y1==M_respm[1,1] `mlif' + qui gen double `den' = 1 + while `i'<= `n'{ + local prev = `i' - 1 + qui replace `den' = `den' + exp((${HG_xb`prev'} + `zu')/`s') `mlif' + local i = `i' + 1 + } + qui gen double `tmp1' = 1/`den' + qui replace `y' = M_respm[1,1] if `r'<`tmp1' `mlif' + qui gen double `tmp2' = `tmp1' + local i = 2 + while `i'< `n'{ + local prev = `i' - 1 + qui replace `tmp2' = `tmp1' + exp((${HG_xb`prev'} + `zu')/`s')/`den' `mlif' + qui replace `y' = M_respm[`i',1] if `r'<`tmp2' & `r'>=`tmp1' `mlif' + qui replace `tmp1' = `tmp2' + local i = `i' + 1 + } + qui replace `y' = M_respm[`n',1] if `r'>=`tmp2' `mlif' + } +end + +program define ordinal + version 6.0 + args res lpred what + local no = 1 + local xbind = 2 + tempvar mu mu1 l y + qui gen double `l' = 0 + qui gen double `mu' = 0 + qui gen double `mu1' = 0 + qui gen `y' = 0 + + local nxt = 0 + while `no' <= $HG_nolog{ + local olog = M_olog[1,`no'] + local lnk: word `no' of $HG_linko + + if "`lnk'"=="ologit"{ + local func logitl + } + else if "`lnk'"=="oprobit"{ + local func probitl + } + else if "`lnk'"=="ocll"{ + local func cll + } + else if "`lnk'"=="soprobit"{ + local func sprobitl + } + local if + if "$HG_lv"~=""&$HG_nolog>0{ + local if if $HG_lv == `olog' + } + local where = `nxt' + M_above[1,`no'] + 1 + * disp in re "no = `no', where = `where' if = `if' " + qui replace `l' = -`lpred'+${HG_xb`where'} + `func' `l' `mu1' + qui replace `mu' = 1-`mu1' `if' + if `what'>5{ + local ab = M_above[1,`no'] + local ab = M_resp[`ab',`no'] + * disp in re "replace y = y > `ab' `if' " + qui replace `y' = $ML_y1 > `ab' `if' + } + local n=M_nresp[1,`no'] + local nxt = `nxt' + `n' - 1 + local no = `no' + 1 + } /* next ordinal response */ + if `what'==5{ + qui replace `res' = `mu' if $HG_lvolo==1 + } + else{ + res_b `res' `mu' `y' "if $HG_lvolo==1" " " `what' + } +end + +program define simord + version 6.0 + args y lpred + local no = 1 + local xbind = 2 + tempvar mu p1 p2 r + qui gen double `p1' = 0 + qui gen double `p2' = 0 + qui gen double `mu' = 0 + qui gen double `r' = uniform() + + while `no' <= $HG_nolog{ + local olog = M_olog[1,`no'] + local lnk: word `no' of $HG_linko + + if "`lnk'"=="ologit"{ + local func logitl + } + else if "`lnk'"=="oprobit"{ + local func probitl + } + else if "`lnk'"=="ocll"{ + local func cll + } + else if "`lnk'"=="soprobit"{ + local func sprobitl + } + local and + if "$HG_lv"~=""&$HG_nolog>0{ + local and & $HG_lv == `olog' + } + * disp "ordinal link is `lnk', and = `and'" + local n=M_nresp[1,`no'] + + * disp "HG_xb1: " $HG_xb1 + * disp "xbind = " `xbind' + * disp ${HG_xb`xbind'}[$which] + + qui replace `mu' = -`lpred'+${HG_xb`xbind'} + `func' `mu' `p1' + qui replace `y' = M_resp[1,`no'] if `r'<`p1' `and' + qui replace `p2' = `p1' + local i = 2 + while `i' < `n'{ + local nxt = `xbind' + `i' - 1 + + *disp "response " M_resp[`i',`no'] + *disp "HG_xb`nxt' " ${HG_xb`nxt'}[$which] + + qui replace `mu' = -`lpred'+${HG_xb`nxt'} + *disp "mu " `mu'[$which] + `func' `mu' `p2' + + *disp "p1 and p2: " `p1'[$which] " " `p2'[$which] + + qui replace `y' = M_resp[`i',`no'] if `r'<`p2' & `r'>=`p1' `and' + qui replace `p1' = `p2' + local i = `i' + 1 + } + local xbind = `xbind' + `n' -1 + qui replace `y' = M_resp[`n',`no'] if `r'>=`p2' `and' + local no = `no' + 1 + } /* next ordinal response */ + *tab $ML_y1 if `y'==. `and' +end + +program define logitl + version 6.0 + args mu p + qui replace `p' = 1/(1+exp(-`mu')) +end + +program define cll + version 6.0 + args mu p + qui replace `p' = 1-exp(-exp(`mu')) +end + +program define probitl + version 6.0 + args mu p + qui replace `p' = normprob(`mu') +end + +program define sprobitl + version 6.0 + args mu p + qui replace `p' = normprob(`mu'/$HG_s1) +end + + +program define link + version 6.0 +* returns mu for requested link + args which mu lpred s1 + * disp " in link, which is `which' " + + tokenize "`which'" + local i=1 + local ifs + while "`1'"~=""{ + if "$HG_lv" ~= ""{ + local oth = M_oth[1,`i'] + local ifs if $HG_lv==`oth' + } + * disp "`1' link `ifs'" + + if ("`1'" == "logit"){ + quietly replace `mu' = 1/(1+exp(-`lpred')) `ifs' + } + else if ("`1'" == "probit"){ + * disp "doing probit " + quietly replace `mu' = normprob((`lpred')) `ifs' + } + else if ("`1'" == "sprobit"){ + quietly replace `mu' = normprob((`lpred')/`s1') `ifs' + } + else if ("`1'" == "log"){ + * disp "doing log " + quietly replace `mu' = exp(`lpred') `ifs' + } + else if ("`1'" == "recip"){ + * disp "doing recip " + quietly replace `mu' = 1/(`lpred') `ifs' + } + else if ("`1'" == "cll"){ + * disp "doing cll " + quietly replace `mu' = 1 - exp(-exp(`lpred')) `ifs' + } + else if ("`1'" == "ident"){ + quietly replace `mu' = `lpred' `ifs' + } + local i = `i' + 1 + mac shift + } + +end + +program define family + version 6.0 + args which y mu und what + + tokenize "`which'" + local i=1 + * disp "in family, und = `und'" + if "$HG_fv" == ""{ + local ifs + if "`und'"~=""{local und if `und'} + } + else{ + if "`und'"~=""{local und & `und'} + } + while "`1'"~=""{ + if "$HG_fv" ~=""{ + local ifs if $HG_fv == `i' + } + if ("`1'" == "binom"){ + if `what'==0{ + sim_b `y' `mu' "`ifs'" "`und'" + } + else{ + res_b `y' `mu' $ML_y1 "`ifs'" "`und'" `what' + } + } + else if ("`1'" == "poiss"){ + if `what'==0{ + sim_p `y' `mu' "`ifs'" "`und'" + } + else{ + res_p `y' `mu' "`ifs'" "`und'" `what' + } + } + else if ("`1'" == "gauss") { + if `what'==0{ + sim_g `y' `mu' $HG_s1 "`ifs'" "`und'" + } + else{ + res_g `y' `mu' $HG_s1 "`ifs'" "`und'" `what' + } + } + else if ("`1'" == "gamma"){ + if `what'==0{ + sim_ga `y' `mu' $HG_s1 "`ifs'" "`und'" + } + else{ + res_ga `y' `mu' $HG_s1 "`ifs'" "`und'" `what' + } + } + else{ + disp in re "unknown family in gllas_yu" + exit 198 + } + local i = `i' + 1 + mac shift + } +end + +program define res_g + version 6.0 + * stolen from glim_p and glim_v1 + args res mu s1 if and what + if `what'==6{ /* Pearson */ + qui replace `res' = ($ML_y1-`mu')/ `s1' `if' `and' + exit + } + else if `what'==7{ /* Deviance */ + *qui replace `res'= sign($ML_y1-`mu')*sqrt(($ML_y1-`mu')^2/ `s1'^2) `if' `and' + qui replace `res' = ($ML_y1-`mu')/ `s1' `if' `and' + exit + + } + else if `what'==8{ /* Anscombe */ + qui replace `res' = ($ML_y1-`mu')/ `s1' `if' `and' + } +end + +program define res_b + version 6.0 + * stolen from glim_p and glim_v2 + args res mu y if and what + tempvar mu_n + gen double `mu_n' = `mu'*$HG_denom + if `what'==6{ /* Pearson */ + qui replace `res' = (`y'-`mu_n')/sqrt(`mu_n'*(1-`mu')) `if' `and' + exit + } + else if `what'==7{ /* Deviance */ + *if $HG_denom == 1 { + * qui replace `res' = cond(`y', /* + * */ -2*ln(`mu_n'), -2*ln(1-`mu_n')) `if' `and' + *} + *else{ + qui replace `res' = cond(`y'>0 & `y'<$HG_denom, /* + */ 2*`y'*ln(`y'/`mu_n') + /* + */ 2*($HG_denom-`y') * /* + */ ln(($HG_denom-`y')/($HG_denom-`mu_n')), /* + */ cond(`y'==0, 2*$HG_denom * /* + */ ln($HG_denom/($HG_denom-`mu_n')), /* + */ 2*`y'*ln(`y'/`mu_n')) ) `if' `and' + *} + + qui replace `res'= sign(`y'-`mu_n')*sqrt(`res') `if' `and' + exit + + } + else if `what'==8{ /* Anscombe */ + tempname b23 + scalar `b23' = exp(2*lngamma(2/3)-lngamma(4/3)) + qui replace `res' = /* + */ 1.5*(`y'^(2/3)*_hyp2f1(`y'/$HG_denom) - /* + */ `mu_n'^(2/3)*_hyp2f1(`mu')) / /* + */ ((`mu_n'*(1-`mu'))^(1/6)) `if' `and' + } +end + +program define res_p + version 6.0 + * stolen from glim_p and glim_v3 + args res mu if and what + if `what'==6{ /* Pearson */ + qui replace `res' = ($ML_y1-`mu')/sqrt(`mu') `if' `and' + exit + } + else if `what'==7{ /* Deviance */ + qui replace `res' = cond($ML_y1==0, 2*`mu', /* + */ 2*($ML_y1*ln($ML_y1/`mu')-($ML_y1-`mu'))) `if' `and' + qui replace `res'= sign($ML_y1-`mu')*sqrt(`res') `if' `and' + exit + + } + else if `what'==8{ /* Anscombe */ + qui replace `res' = 1.5*($ML_y1^(2/3)-`mu'^(2/3)) / `mu'^(1/6) `if' `and' + } +end + +program define res_ga + version 6.0 + * stolen from glim_p and glim_v4 + args res mu s1 if and what + if `what'==6{ /* Pearson */ + qui replace `res' = ($ML_y1-`mu')/`mu' `if' `and' + exit + } + else if `what'==7{ /* Deviance */ + qui replace `res' = -2*(ln($ML_y1/`mu') - ($ML_y1-`mu')/`mu') + qui replace `res'= sign($ML_y1-`mu')*sqrt(`res') `if' `and' + exit + + } + else if `what'==8{ /* Anscombe */ + qui replace `res' = 3*($ML_y1^(1/3)-`mu'^(1/3))/`mu'^(1/3) `if' `and' + } +end + +program define sim_g + version 6.0 +* returns conditionally normally distributed y + args y mu s1 if and + * disp "running famg `if' `and'" + * disp "s1 = " `s1'[$which] ", mu = " `mu'[$which] " and Y = " $ML_y1[$which] + quietly replace `y' = invnorm(uniform())*`s1' + `mu' `if' `and' +end + +program define sim_b + version 6.0 +* returns y with binomial distribution conditional on r.effs +* $HG_denom is denominator + args y mu if and + * disp "running famb `if' `and'" + * disp "mu = " `mu'[$which] " and Y = " $ML_y1[$which] + qui replace `y' = uniform()<`mu' `if' `and' + qui summ $HG_denom `if' `and' + if r(N)>0{ + local max = r(max) + if `max'>1{ + tempvar left + qui gen int `left' = $HG_denom - 1 + local i = 1 + while `i'<`max'{ + qui replace `y' = `y' + (uniform()<`mu'&`left'>0) `if' `and' + qui replace `left' = `left' - 1 + local i = `i' + 1 + } + } + } +end + +program define sim_p + version 6.0 +* simulates counts from Poisson distribution + + args y mu if and + *!! disp "running famp `if'" + * disp in re "if and: `if' `and'" + + tempvar t p + qui gen double `t' = 0 `if' `and' + qui gen int `p' = 0 `if' `and' + local n = 1 + while `n' >0 { + qui replace `t' = `t' -ln(1-uniform())/`mu' `if' `and' + qui replace `p' = `p' + 1 if `t'<1 + qui count if `t' < 1 + local n = r(N) + } + quietly replace `y' = `p' `if' `and' + * disp "done famp" +end + +program define sim_ga + version 6.0 +* returns log of gamma density conditional on r.effs + args y mu s1 if and + *!! disp "running famg `if'" + *!! disp "mu = " `mu'[$which] + *!! disp "s1 = " `s1'[$which] + qui replace `mu' = 0.0001 if `mu' <= 0 + tempvar nu + qui gen double `nu' = `s1'^(-2) + quietly replace `y' = /* + */ `nu'*(ln(`nu')-ln(`mu')) - lngamma(`nu')/* + */ + (`nu'-1)*ln($ML_y1) - `nu'*$ML_y1/`mu' `if' `and' +end diff --git a/Modules/ado/plus/g/gllasim.ado b/Modules/ado/plus/g/gllasim.ado new file mode 100644 index 0000000..aa29d83 --- /dev/null +++ b/Modules/ado/plus/g/gllasim.ado @@ -0,0 +1,825 @@ +*! version 1.0.6 SRH 1 June 2003 +program define gllasim + version 6.0 + + if "`e(cmd)'" ~= "gllamm" { + di in red "gllamm was not the last command" + exit 301 + } + + *syntax anything(name=pref id="prefix for variable(s)") [if] [in] + syntax newvarname [if] [in] /* + */ [,Y U LInpred FAC FSAMPLE MU OUTcome(int -99) ABove(numlist integer) /* + */ noOFFset ADOONLY FRom(string) US(string)] + local nopt = ("`u'"!="") + ("`linpred'"!="") + ("`fac'"!="") + ("`mu'"!="") + + local pref `varlist' + if `nopt'>1 { + disp in re "only one of these option allowed: u, fac, linpred or mu" + exit 198 + } + local tplv = e(tplv) + local tprf = e(tprf) + if `nopt'==0 { + local y "y" + } + + if "`e(weight)'"~=""&"`y'"~=""{ + disp in re "weight option used in gllamm: It doesn't normally make sense to simulate responses for collapsed data" + } + + if `tplv' < 2{ + if "`u'"~="" | "`fac'"~="" { + disp in re "u and fac options not valid for 1 level model" + exit 198 + } + if "`linpred'"~="" & "`y'"=="" { + *disp in re "nothing to simulate. use gllapred, xb" + *exit 198 + } + + } + + local vars + if "`y'"~=""{ + local vars `pref' + local ysim `pref' + tempvar musim + local what=0 + disp in gr "(simulated responses will be stored in `pref')" + /* check if gamma family used */ + local found = 0 + local fm "`e(famil)'" + local num: word count `fm' + local k = 1 + while `k' < `num'{ + local ll: word `k' of `fm' + if "`ll'" == "gamma"{ + local found = 1 + } + local k = `k' + 1 + } + if `found' == 1{ + disp in re "cannot simulate from gamma yet" + exit 198 + } + } + + if "`u'"~=""|"`fac'"~=""{ + local i = 1 + while `i' < `tprf'{ + local vars `vars' `pref'p`i' + local i = `i' + 1 + } + disp in gr "(simulated scores will be stored in `vars')" + } + if "`linpred'"~=""{ + local vars `vars' `pref'p + local lpred `pref'p + disp in gr "(linear predictor will be stored in `pref'p)" + } + if "`mu'"~=""{ + local vars `vars' `pref'p + local musim `pref'p + tempvar lpred + tempvar ysim + if "`y'"~=""{ + local what = 1 + } + else{ + local what = 5 + } + disp in gr "(mu will be stored in `pref'p)" + } + else if "`y'"~=""{ + tempvar lpred + } + + if "`offset'"~=""{ + if "`linpred'"==""&"`mu'"==""{ + disp in re "nooffset option only allowed with linpred or mu option" + exit 198 + } + } + if "`us'"~=""& "`u'"~=""{ + disp in re "u option does not make sense with us() option" + exit 198 + } + * disp in re "setting macros" + +/* check if variables already exist */ + + confirm new var `vars' + +/* restrict to estimation sample */ + + tempvar idno + gen int `idno' = _n + preserve + if "`fsample'"==""{ + qui keep if e(sample) + } + +/* interpret if and in */ + marksample touse, novarlist + qui count if `touse' + if _result(1) <= 1 { + di in red "insufficient observations" + exit 2001 + } + qui keep if `touse' + + tempfile file + +/* set all global macros needed by gllam_ll */ + setmacs 0 + + if "`adoonly'"!="" { + global HG_noC=1 + global HG_noC1=1 + } + + *disp "HG_free = " $HG_free + + tempname b + matrix `b'=e(b) + +/* deal with from */ + if "`from'"~=""{ + capture qui matrix list `from' + local rc=_rc + if `rc'>1{ + disp in red "`from' not a matrix" + exit 111 + } + local ncol = colsof(`from') + local nrow = rowsof(`from') + local ncolb = colsof(`b') + if `ncolb'~=`ncol'{ + disp in re "from matrix has `ncol' columns but should have `ncolb'" + exit 111 + } + if `nrow'~=1{ + disp in re "from matrix has more than one row" + exit 111 + } + local coln: colnames(`b') + local cole: coleq(`b') + matrix `b' = `from' + matrix colnames `b' = `coln' + matrix coleq `b' = `cole' + } +/* deal with outcome() and above() */ + + if "`mu'"~=""&$HG_nolog>0{ + if "`above'"==""{ + disp in re "must specify above() option for ordinal responses" + exit 198 + } + else{ + matrix M_above = J(1,$HG_nolog,0) + local num: word count `above' + if `num'>1&`num'~=$HG_nolog{ + disp in re "wrong length of numlist in above() option" + exit 198 + } + local no = 1 + local k = 1 + while `no' <= $HG_nolog{ + if `num'>1{ + local k = `no' + } + local ab: word `k' of `above' + * disp in re "`no'th ordinal response, above = `ab'" + local n=M_nresp[1,`no'] + local i = 1 + local found = 0 + while `i'<= `n'&`found'==0{ + if M_resp[`i',`no']==`ab'{ + local found=`i' + matrix M_above[1,`no']=`i' + } + local i = `i' + 1 + } + if `found'==0{ + disp in re "`ab' not a category for `no'th ordinal response" + exit 198 + } + else if `found' == `n'{ + disp in re "`ab' is highest category for `no'th ordinal response" + exit 198 + } + local no = `no' + 1 + } + } + * noi matrix list M_above + } + if "`mu'"~=""&$HG_mlog>0{ + if `outcome'==-99&$HG_exp==0{ + disp in re "must specify outcome() option for nominal responses unless data in expanded form" + exit 198 + } + if $HG_exp==0{ + local n=rowsof(M_respm) + local found = 0 + local i = 1 + while `i'<= `n'&`found'==0{ + if M_respm[`i',1]==`outcome'{ + local found=`i' + } + local i = `i' + 1 + } + if `found'==0{ + disp in re "`outcome not a category of the nominal response'" + exit 198 + } + global HG_outc=`outcome' + } + } + + +/* run remcor */ + /* set up names for HG_xb`i' */ + local i = 1 + while (`i' <= $HG_tpff){ + tempname junk + global HG_xb`i' "`junk'" + local i = `i' + 1 + } + /* set up names for HG_s`i' */ + local i = 1 + while (`i'<=$HG_tprf){ + tempname junk + global HG_s`i' "`junk'" + local i = `i' + 1 + } + + if $HG_free{ /* names for HG_p`lev'`k' */ + local lev = 2 + while `lev'<=$HG_tplv{ + local npar = M_np[1,`lev'] + if `npar'>0{ + local k = 1 + while `k'<=M_nip[1, `lev']{ + * disp in re "creating HG_p`lev'`k'" + tempname junk + global HG_p`lev'`k' "`junk'" + local k = `k' + 1 + } + } + local lev = `lev' + 1 + } + } + qui remcor "`b'" `us' + +/* sort out level 1 clus variable */ + local clus `e(clus)' + global HG_clus `clus' + tempvar id + if $HG_exp~=1&$HG_comp==0{ + gen int `id'=_n + tokenize "`clus'" + local l= $HG_tplv + local `l' "`id'" + global HG_clus "`*'" + if $HG_tplv>1{ + global HG_clus "`*'" + } + else{ + global HG_clus "`1'" + } + } + * disp "HG_clus: $HG_clus" + +/* deal sith us */ + if "`us'"~="" { + local j = 1 + while `j'<$HG_tprf{ + capture confirm variable `us'`j' + if _rc~=0{ + disp in re "variable `us'`j' not found" + exit 111 + } + else{ + global HG_U`j' "`us'`j'" + } + local j = `j' + 1 + } + } + else { + if $HG_free{ + /* simulate discrete latent variables HG_U`rf'*/ + tempvar f r cum1 cum2 + qui gen double `r' = 0 + qui gen byte `f' = 0 + gen double `cum2' = 0 + gen double `cum1' = 0 + local sortlst $HG_clus + local lev = 2 + local rf = 1 + local k = $HG_tplv + while `lev'<=$HG_tplv{ + /* sortlist etc. */ + tokenize "`sortlst'" + local `k' " " + local sortlst "`*'" + sort $HG_clus + qui by `sortlst': replace `f' = _n==1 + qui replace `r' = cond(`f'==1,uniform(),.) + + /* define variables HG_V */ + local rf = M_nrfc[2,`lev'-1] + while `rf'0{ + qui replace `cum2' = `cum2' + exp(${HG_p`lev'`i'}) + } + else{ + qui replace `cum2' = `cum2' + exp(`probs'[1,`i']) + } + local rf = M_nrfc[2,`lev'-1] + while `rf' " `cum1' + qui replace ${HG_U`rf'} = `zlocs'[1,`i'] if `r'<=`cum2'&`r'>`cum1' + local rf = `rf' + 1 + } + local i = `i' + 1 + } + + /* set all values in same cluster equal to prediction */ + sort $HG_clus + local rf = M_nrfc[2,`lev'-1] + while `rf'0{ + local rf2 = `rf'+1 + while `rf2'<=$HG_tprf - 1 { /* upper diagonal matrix */ + *disp in re "`pref'p`rf'=`pref'p`rf'+Bmat[`rf',`rf2']*`pref'p`rf2'" + qui replace `pref'p`rf'=`pref'p`rf'+Bmat[`rf',`rf2']*`pref'p`rf2' + local rf2 = `rf2' + 1 + } + local rf = `rf' -1 + } + } + + *disp "dealing with geqs" + tempname junk s1 + local i = 1 + while `i'<=$HG_ngeqs{ + local k = M_ngeqs[1,`i'] + local n = M_ngeqs[2,`i'] + local nxt = M_ngeqs[3,`i'] + *disp "random effect `k'-1 has `n' covariates" + local nxt2 = `nxt'+`n'-1 + matrix `s1' = `b'[1,`nxt'..`nxt2'] + *matrix list `s1' + local nxt = `nxt2' + 1 + capture drop `junk' + matrix score double `junk' = `s1' + local rf = `k' - 1 + replace `pref'p`rf' = `pref'p`rf' + `junk' + local i = `i' + 1 + } + } + if "`y'"~=""|"`linpred'"~=""|"`mu'"~=""{ + qui gen double `lpred' = $HG_xb1 + local i = 2 + while (`i' <= $HG_tprf){ + local im = `i' - 1 + qui replace `lpred' = `lpred' + ${HG_U`im'} * ${HG_s`i'} + local i = `i' + 1 + } + if "`offset'"~=""&"$HG_off"~=""{ + qui replace `lpred' = `lpred' - $HG_off + } + } + + +/* simulate y */ + + if "`y'"~=""|"`mu'"~=""{ +/* sort out denom */ + local denom "`e(denom)'" + if "`denom'"~=""{ + capture confirm variable `denom' + if _rc>0{ + tempvar den + qui gen `den'=1 + global HG_denom "`den'" + } + else{ + global HG_denom `denom' + } + } + +/* sort out HG_ind */ + capture confirm variable $HG_ind + if _rc>0{ + tempname junk + global HG_ind "`junk'" + gen $HG_ind=1 + } +/* sort out HG_lvolo */ + if $HG_nolog>0{ + tempname junk + global HG_lvolo "`junk'" + qui gen $HG_lvolo = 0 + local no = 1 + if "$HG_lv"==""{ + local olog = M_olog[1,`no'] + qui replace $HG_lvolo = 1 + } + else{ + while `no'<=$HG_nolog{ + local olog = M_olog[1,`no'] + qui replace $HG_lvolo = 1 if $HG_lv == `olog' + local no = `no' + 1 + } + } + } + +/* call gllas_yu */ + qui gen double `ysim' = . + qui gen double `musim' = 0 + * disp in re "musim = `musim'" + sort $HG_clus + gllas_yu `ysim' `lpred' `musim' `what' + } +/* delete macros */ + delmacs + qui keep `idno' `vars' + qui sort `idno' + qui save "`file'", replace + restore + sort `idno' + qui merge `idno' using "`file'" + qui drop _merge + +end + +program define setmacs +version 6.0 +args what +/* sort out depvar */ + local depv "`e(depvar)'" + global ML_y1 "`depv'" + + +/* link and family-related macros */ + global HG_famil "`e(famil)'" + global HG_link "`e(link)'" + global HG_linko "`e(linko)'" + global HG_nolog = `e(nolog)' + global HG_ethr = `e(ethr)' + global HG_mlog = `e(mlog)' + global HG_smlog = `e(smlog)' + global HG_oth = `e(oth)' + global HG_lv "`e(lv)'" + global HG_fv "`e(fv)'" + capture matrix M_resp=e(mresp) + capture matrix M_respm=e(mrespm) + capture matrix M_frld=e(frld) + capture matrix M_olog=e(olog) + capture matrix M_oth=e(moth) + global HG_exp = e(exp) + global HG_expf = e(expf) + global HG_ind = "`e(ind)'" + global HG_lev1 = e(lev1) + global HG_comp = e(comp) + capture local coall "`e(coall)'" + if $HG_comp~=0{ + local i = 1 + while `i'<=$HG_comp{ + local k: word `i' of `coall' + global HG_co`i' `k' + local i = `i' + 1 + } + } + +/* set all other global macros */ + global HG_nats = `e(nats)' + global HG_noC = `e(noC)' + global HG_noC1 = `e(noC1)' + global HG_adapt = `e(adapt)' + global HG_tplv = e(tplv) + global HG_tpff = `e(tpff)' + global HG_tpi = `e(tpi)' + global HG_tprf = e(tprf) + local tprf = $HG_tprf + global HG_free = e(free) + global HG_mult = e(mult) + global HG_lzpr lzprobg + global HG_zip zipg + if $HG_mult{ + global HG_lzpr lzprobm + } + else if $HG_free{ + global HG_lzpr lzprobf + global HG_zip zipf + matrix M_np=e(mnp) + } + global HG_cip = e(cip) + global which = 9 + global HG_off "`e(offset)'" + global HG_error = 0 + global HG_cor = `e(cor)' + global HG_bmat = e(bmat) + global HG_const = 0 + global HG_ngeqs = e(ngeqs) + global HG_inter = e(inter) + global HG_dots = 0 + global HG_init = e(init) + matrix M_nbrf = e(nbrf) + matrix M_nrfc = e(nrfc) + matrix M_ip = J(1,$HG_tprf+2,1) + matrix M_nffc = e(nffc) + if $HG_tprf<2{ local tprf = 2} + matrix M_znow =J(1,`tprf'-1,1) + matrix M_nip = e(nip) + capture matrix M_ngeqs = e(mngeqs) + capture matrix M_b=e(mb) + *capture matrix M_chol = e(chol) + capture matrix CHmat = e(chol) + global HG_clus `e(clus)' +local lev = 2 +while `lev'<=$HG_tplv{ + local l = M_nrfc[1,`lev'-1] + 1 /* loop */ + local k = M_nrfc[2,`lev'-1] + 1 /* r. eff. */ + while `l'<=M_nrfc[1,`lev']&$HG_tplv>1{ + while `k'<=M_nrfc[2,`lev']{ + *disp "loop " `l' " random effect " `k' + local w = M_nip[2,`k'] + + /* same loc and prob as before? */ + local found = 0 + local ii=M_nrfc[2,1] + 1 + while `ii'<`k'{ + if `w'==M_nip[2,`ii']{ + local found = 1 + } + local ii = `ii'+1 + } + + + capture matrix M_zps`w' =e(zps`w') + *matrix list M_zps`w' + if `what'==2{ + if $HG_free { + if `k' == M_nrfc[1,`l']{ + local nip = colsof(M_zps`w') + noi disp in gr "prior probabilities" + + + local j = 2 + local zz=string(exp(M_zps`w'[1,1]),"%6.0gc") + if `nip'>1{ + local mm "0`zz'" + } + else{ + local mm "1" + } + + while `j'<=`nip'{ + local zz=string(exp(M_zps`w'[1,`j']),"%6.0gc") + local mm "`mm'" ", " "0`zz'" + local j = `j' + 1 + } + disp in gr " prob: " in ye "`mm'" + + disp " " + } + } + else if `found'==0{ + noi disp in gr "probabilities for `w' quad. points" + noi matrix list M_zps`w' + disp " " + } + } + * disp "M_zlc`w'" + matrix M_zlc`w'=e(zlc`w') + *matrix list M_zlc`w' + if `what'==2{ + if $HG_free{ + noi disp in gr "locations for random effect " `w'-1 + local mm=string(M_zlc`w'[1,1],"%6.0gc") + local j = 2 + while `j'<= `nip'{ + local zz=string(M_zlc`w'[1,`j'],"%6.0gc") + local mm "`mm'" ", " "`zz'" + local j = `j' + 1 + } + disp in gr " loc: " in ye "`mm'" + disp " " + } + else if `found'==0{ + noi disp in gr "locations for `w' quadrature points" + noi matrix list M_zlc`w' + disp " " + } + + } + local k = `k' + 1 + } + local l = `l' + 1 + } +local lev = `lev' + 1 +} +end + +program define delmacs + version 6.0 +/* deletes all global macros and matrices*/ + tempname var + if "$HG_tplv"==""{ + * macros already gone + exit + } + local nrfold = M_nrfc[2,1] + local lev = 2 + while (`lev'<=$HG_tplv){ + local i2 = M_nrfc[2,`lev'] + local i1 = `nrfold'+1 + local i = `i1' + local nrfold = M_nrfc[2,`lev'] + while `i' <= `i2'{ + local n = M_nip[2,`i'] + if `i' <= M_nrfc[1,`lev']{ + capture matrix drop M_zps`n' + } + capture matrix drop M_zlc`n' + local i = `i' + 1 + } + local lev = `lev' + 1 + } + if $HG_free==0&$HG_init==0{ + *matrix drop M_chol + matrix drop CHmat + } + matrix drop M_nrfc + matrix drop M_nffc + matrix drop M_nbrf + matrix drop M_ip + capture matrix drop M_b + capture matrix drop M_resp + capture matrix drop M_respm + capture matrix drop M_frld + matrix drop M_nip + matrix drop M_znow + capture matrix drop M_ngeqs + capture matrix drop CHmat + + /* globals defined in gllam_ll */ + local i=1 + while (`i'<=$HG_tpff){ + global HG_xb`i' + local i= `i'+1 + } + local i = 1 + while (`i'<=$HG_tprf){ + global HG_s`i' + global HG_U`i' + local i= `i'+1 + } + local i = 1 + while (`i'<=$HG_tplv){ + global HG_wt`i' + local i = `i' + 1 + } + global HG_nats + global HG_noC + global HG_noC1 + global HG_adapt + global HG_fixe + global HG_lev1 + global HG_bmat + global HG_tplv + global HG_tprf + global HG_tpi + global HG_tpff + global HG_clus + global HG_weigh + global which + global HG_gauss + global HG_free + global HG_famil + global HG_link + global HG_nolog + global HG_olog + global HG_mlog + global HG_smlog + global HG_oth + global HG_exp + global HG_expf + global HG_lv + global HG_fv + global HG_nump + global HG_eqs + global HG_obs + global HG_off + global HG_denom + global HG_cor + global HG_s1 + global HG_init + global HG_ind + global HG_const + global HG_dots + global HG_inter + global HG_ngeqs + global HG_ethr + global HG_mult + global HG_lzpr + global HG_zip + global HG_cip + global HG_comp + capture macro drop HG_co* +end + diff --git a/Modules/ado/plus/g/gllasim.hlp b/Modules/ado/plus/g/gllasim.hlp new file mode 100644 index 0000000..f5c3f58 --- /dev/null +++ b/Modules/ado/plus/g/gllasim.hlp @@ -0,0 +1,151 @@ +.- +help for ^gllasim^ +.- + +Simulate command for gllamm +--------------------------- + +^gllasim^ varname [^if^ exp] [^in^ range] [, ^y^ ^u^ ^fac^ ^li^npred + ^mu^ ^out^come^(^#^)^ ^ab^ove^(^#^,^...^,^#^)^ + ^adapt^ ^fsample^ ^nooff^set ^adoonly^ ^fr^om^(^matrix^)^ + ^us(^varname^)^ ] + +where only one of ^u^ ^fac^ ^li^npred ^mu^ may be used at a time. +^y^ can be specified in addition to one of the above. + + +Description +----------- + +^gllasim^ is a post-estimation command for @gllamm@. It simulates +the responses from to the model just estimated. + +By default responses are simulated for the estimation sample. +Use ^fsample^ to simulate responses for the full sample. + +If the data were collapsed and the ^weight()^ option used in +^gllamm^, it does not make sense to simulate responses unless +the data are first expanded. This is because each record +in the collapsed dataset represents several units who happened +to have the same response in the data and it would not +make sense to simulate the same response for all these units. + + +Options +-------- + +^y^ the simulated resonses are returned in "varname". This + option is only necessary if ^u^, ^fac^, ^linpred^ or ^mu^ + are also specified. + +^u^ the simulated latent variables or random effects are + returned in "varname"p1, "varname"p2, etc., where the + order of the latent variables is the same as in the + call to gllamm (in the order of the equations in the eqs() + option). If the gllamm model includes equations for the + latent variables (geqs and/or bmatrix), the simulated + disturbances are returned. + +^fac^ If the gllamm model includes equations for the latent + variables (^geqs()^ and/or ^bmatrix()^ options in ^gllamm^), + ^fac^ causes the simulated latent variables (e.g. factors) + to be returned in "varname"p1, "varname"p2, etc. instead of + the disturbances, that is, the latent variables on the + left-hand side of the structural model. + +^linpred^ returns the linear predictor including the fixed + and simulated random parts in "varname"p. The offset + is included (if there is one in the gllamm model) + unless the nooffset option is specified. + +^mu^ returns the expected value of the response conditional + on the simulated values for the latent variables, e.g. + a probability if the responses are dichotmous. + +^outcome(^#^)^ specifies the outcome for which the predicted + probability should be returned (^mu^ option) if there + is a nominal response and the ^expanded()^ option has not + been used in ^gllamm^ (with the ^expanded()^ option, predicted + probabilities are returned for all outcomes). + +^above(^#^,^...^,^#^)^ specifies the events for which the + predicted probabilities should be returned (^mu^ option) + if there are ordinal responses. The probability of + a value higher than that specified is returned for each + ordinal response. A single number can be given for all + ordinal responses. + +^nooffset^ can be used together with the ^linpred^ and ^mu^ + options to exclude the offset from the simulated value. + It will only make a difference if the ^offset()^ option + was used in gllamm. + +^fsample^ causes gllasim to simulate values for the + full sample (except observations exluded due to the + if and in options), not just the estimation sample. + +^adoonly^ causes all gllamm to use only ado-code. + This option is not necessary if ^gllamm^ was run with the + adoonly option. + +^from(^matrix^)^ specifies a matrix of parameters for which + the predictions should be made. The column and equation + names will be ignored. Without this option, the parameter + estimates from the last gllamm model will be used. + +^us(^varname^)^ specifies that, instead of simulating the + latent variables, gllasim should use the variables in + "varname"1, "varname"2, etc. + +Examples +-------- + +Estimate parameters of a three level logistic regression model: + + . ^gllamm resp x, i(id school) adapt trace family(binom)^ + + +Simulate the random intercepts + + . ^gllasim int, u^ + + +Simulate the responses + + . ^gllasim y^ + + +Simulate responses when the latent variables are equal to the values +previously simulated (note that ^gllasim int, u^ above stored the +random intercepts in intp1 and intp2): + + . ^gllasim y1, us(intp)^ + + +Simulate predicted probabilities, i.e. predicted probabilities for +simulated values of the latent variables: + + . ^gllasim prob, mu^ + + +Author +------ +Sophia Rabe-Hesketh (sophiarh@@berkeley.edu) +as part of joint work with Andrew Pickles and Anders Skrondal. + + +Web-page +-------- +http://www.gllamm.org + + +References +---------- +Rabe-Hesketh, S., Skrondal, A. and Pickles, A. (2004). GLLAMM Manual. +U.C. Berkeley Division of Biostatistics Working Paper Series. +Working Paper 160. + + +Also see +-------- +On-line: help for @gllamm@, @gllapred@ diff --git a/Modules/ado/plus/h/hermite.ado b/Modules/ado/plus/h/hermite.ado new file mode 100644 index 0000000..c241f70 --- /dev/null +++ b/Modules/ado/plus/h/hermite.ado @@ -0,0 +1,32 @@ +*! version 2.0, October 2002 (SJ4-1: st0057) + +program define hermite + version 7.0 + tokenize `0' + + local n "`1'" + local x "`2'" + local w "`3'" + local last = `n' + 2 + tempvar p + tempname i + qui gen double `p' = . + scalar `i' = 1 + while `i' <= 10 { + qui replace `p' = 0 in 1 + qui replace `p' = _pi^(-0.25) in 2 + qui replace `p' = `x'*sqrt(2/(_n-2))*`p'[_n-1] /* + */ - sqrt((_n-3)/(_n-2))*`p'[_n-2] in 3/`last' + scalar `w' = sqrt(2*`n')*`p'[`last'-1] + scalar `x' = `x' - `p'[`last']/`w' + if abs(`p'[`last']/`w') < 3e-14 { + scalar `w' = 2/(`w'*`w') + exit + } + scalar `i' = `i' + 1 + } + di in red "hermite did not converge" + exit 499 +end +exit + diff --git a/Modules/ado/plus/h/hotdeck.ado b/Modules/ado/plus/h/hotdeck.ado new file mode 100644 index 0000000..56626e2 --- /dev/null +++ b/Modules/ado/plus/h/hotdeck.ado @@ -0,0 +1,682 @@ +*! Date : 3 Sep 2007 +*! Version : 1.72 +*! Authors : Adrian Mander/David Clayton +*! Email : adrian.mander@mrc-hnr.cam.ac.uk +*! Description : Hotdeck imputation + +/* +25/07/06 version 1.67 - removed some = and investigated the set seed problem +16/3/07 version 1.68 - spruced up the displays +13/6/07 version 1.69 - Made sure set seed does what the masses want although it is truly the wrong thing to do +27/7/07 version 1.70 - The warnings were not strong enough about the strata information.. in fact I think when there is + no data to impute it still tries to combine results. Also a slight error in the output. +15/8/07 version 1.71 - Corrected the confidence intervals.. the tail probability was wrong + ALSO checked the calculation of T B Ubar Qbar by hand! +3/9/07 version 1.72 - Corrected the % lines missing to % lines complete +*/ + +program define hotdeck +version 9.0 +syntax [varlist] [if] [in] [using/], [BY(varlist) IMPute(integer 1) STORE GENerate(string) COMmand(string) PARMS(string asis) REPlace NOISE KEEP(varlist) SEED(string) QUIET INFILES(string) ] +tokenize "`varlist'" +local z "`1'" + +preserve +if "`if'"~="" qui keep `if' + +/* Check the seed option */ +if "`seed'"=="1" local seed 2 +if "`seed'"=="" { + local noseed "noseed" + local seed 1 +} + +confirm number `seed' +/* To generate a seed from the time note need to truncate the seed to be below 2^31-1 */ +if `seed'==1 { + local time "$S_TIME" + local date "$S_DATE" + tokenize "`time'", parse(":") + local seed1 "`1'`3'`5'" + tokenize "`date'", parse(" ") + local dat "`1'`2'`3'" + local dat1 = date("`dat'","dmy") + local seed1 "`seed1'`dat1'" + di + local l_seed "2^31-1" + local seed1 = mod(`seed1',`l_seed') + set seed `seed1' + local seed "`seed1'" /* Added to sort out the seed */ +} +di "{txt}Seed is set as {res} `seed'" + +estimates clear +tempfile olddata + +tempvar touse +mark `touse' `if' `in' +markout `touse' `by', strok + +di in green "DELETING all matrices...." +mat drop _all + +/* Display the patterns of missingness.. only on observed data not imputed */ +if "`infiles'"=="" { + if "`by'"=="" _misspat `varlist' `if' `in' + else _misspat `varlist' `if' `in', by(`by') + local nfill=r(nmiss) +} + + +qui save "`olddata'" + +/* Count the missing data for displaying later */ +if "`infiles'"=="" { + global allpat = r(allpat) + qui count if `touse' + local miss = (r(N)-`nfill')/r(N) +} + + +/* Make sure the users are using the right syntax.. lots of checks here to make sure*/ +if "`command'"=="" { + di in red "WARNING: When the option is not selected " + di in red "then no analysis is performed on the imputed datasets" + di + if "`store'"=="" { + di "ALSO STORE isnt selected so hotdeck will appear to do nothing" + exit(198) + } +} + +if `impute'<1 { + di in red "The number of imputations must be more than 0 not `impute'" + exit(198) +} + +if `impute'==1 & "`infiles'"=="" { + if "`store'"=="" | "`command'"~="" { + di in red "If one imputation is made then command option should NOT be used" + di in red "AND the store option must be specified" + exit(198) + } +} + + +if "`using'"~="" { + if "`store'"=="" { + di in red "To save datasets you must specify the STORE option" + exit(198) + } +} +if "`keep'"~="" { + if "`store'"=="" { + di in red "If you use the KEEP option you must specify the STORE option" + exit(198) + } +} + +if "`noise'"~="" & "`command'"=="" { + di in red "When specifying noise you must also specify the command option" + exit(198) +} +if "`command'"~="" { + if `"`parms'"'==`""' { + di in red "To obtain any output from the command option you must also specify " + di in red "the parameters of interest using the parms() option" + exit(198) + } +} + +/************************************************ + * Loop over the number of imputed data sets + * required + ************************************************/ + +if "`seed'"~="1" set seed `seed' + +/* This is the if statement that allows the input of imputed datafiles */ + +if "`infiles'"~="" { + local i 1 + tokenize "`infiles'" + while "`1'"~="" { + use "`1'",replace + mac shift 1 + if "`command'"=="" { + di in red "You must use the command option when using INFILES" + exit(198) + } + if "`noise'"~="" `command' + else qui `command' /* Do the analysis */ + _parms, parms(`"`parms'"') command(`command') iter(`i') /* Select Parameters of interest*/ + local i=`i'+1 + } + local impute=`i'-1 +} + + +/* If there are no INFILES .. then just have to create the imputed datasets and analyse them */ +else { + forv i =1/`impute' { + +/* Use original dataset */ + use "`olddata'",replace + qui keep if `touse' + +/* Impute values */ + if "`by'"~="" _hotdeck `varlist', by(`by') i((`seed'+`i')) `noseed' + else _hotdeck `varlist', i((`seed'+`i')) `noseed' + +/* Save imputed datasets */ + if "`store'"~="" { + if "`using'"=="" local using "imp" + if "`keep'"=="" { + qui keep `varlist' `by' + qui save `using'`i',replace + } + else { + mkvlist `varlist' `by', vlist(`keep') + qui keep `r(vlist)' + qui save `using'`i',replace + } + } + if "`command'"~="" { + +/* Do the analysis */ + if "`noise'"~="" `command' + else qui `command' + +/* Select Parameters of interest*/ + _parms, parms(`"`parms'"') command(`command') iter(`i') + } + + } +} + + +/******************************************************** + * Loop to calculate the estimates needed + * + * First get the dimensions of the parameter matrices + ********************************************************/ + +if "`command'"~="" { + local dim= rowsof(impV1) + mat Qbar = J(1,`dim',0) + mat Ubar = J(`dim',`dim',0) + +/* calc the averaging factor */ + local inv = 1/`impute' + +/* calc the average coef and variance qbar and ubar */ + forv i=1/`impute' { + mat Qbar= `inv'*impb`i'+ Qbar + mat Ubar= `inv'*impV`i'+ Ubar + } + +/* calc between variances */ + mat B=J(`dim',`dim',0) + local inv1 = 1/(`impute'-1) + + forv i=1/`impute' { + mat B= B + `inv1'*(impb`i' - Qbar)'*(impb`i' - Qbar) + } + +/* Calc total variance */ + mat T = Ubar+(1+1/`impute')*B + + cap mat tempmt=B*inv(Ubar) + if _rc==504 { + di as error "WARNING: Trying to invert variance matrix with zero elements?" + local ter = rowsof(Ubar) + mat temp = J(`ter',1,1) + mat temp2 = Ubar*temp + local tei 1 + local names: colfullnames impb1 + matrix rownames temp2 = `names' + while `tei'<=`ter' { + if temp2[`tei',1]==0 { + local var:word `tei' of "`names'" + di as txt "Variance for covariate `tei' is 0 !!" + } + local tei=`tei'+1 + } + mat tempmt=B*inv(Ubar) + } + + local trace=trace(tempmt) + +/* Everything hunky dorey until now... a strange 1 appears.. */ + local r1 = 1-((1+1/`impute')*`trace'/`dim') + +/************************************************ + * Just sorting out the matrix names + ************************************************/ + local names: rowfullnames impb1 + matrix rownames Qbar = `names' + local names: colfullnames impb1 + matrix colnames Qbar = `names' + local names: rowfullnames impV1 + matrix rownames T = `names' + matrix rownames B = `names' + matrix rownames Ubar = `names' + local names: colfullnames impV1 + matrix colnames T = `names' + matrix colnames B = `names' + matrix colnames Ubar = `names' + + mat Tsurr= `r1'*T + mat D = Qbar*inv(Tsurr)*Qbar' + + local D1 = D[1,1]/`dim' + local t=`dim'*(`impute'-1) + local v1= 4+(`t'-4)*(1+(1-2/`t')*1/`r1')^2 + local ftest= fprob(`dim',`v1',`D1') + +/******************************************************** + * The next will output the main results in Stata style + * if the normal approximation is good then you could + * use the matrix post command + ********************************************************/ + + if "`quiet'"=="" { + if `r1'<0 { + di in red "WARNING: between se larger than within se in one or more " + di in red "parameters invalidating the global F test" + } + if `t'<4 { + di in red "WARNING: t less than 4 invalid global test " + di in red "increase parameters OR imputations" + } + } + + di + di in gr _col(1) "Number of Obs.", _col(45) "= ", as res %5.0f _N + di in gr _col(1) "No. of Imputations", _col(45) "= ", as res %5.0f `impute' + + + if "`infiles'"=="" di in gr _col(1) "% Lines of Complete Data", _col(45) "= ", as res %10.4f `miss'*100, as text "%" + di in gr _col(1) "F(",%6.3f `v1',",`dim')", _col(45) "= ", as res %10.4f `D1' + di in gr _col(1) "Prob > F " , _col(45) "= ", as res %10.4f `ftest' + di "{text}{dup 14:{c -}}{c TT}{dup 68:{c -}}" + + local names: colfullnames impb1 + + +/* Transform the double quoted names to a macrolist */ + + di in gr _continue "Variable" _col(15) "{c |}",_col(17) "Average", _col(28) "Between", _col(38) "Within", _col(48) "Total", _col(58) "df", _col(68) "t", _col(77) "p-value" + di + di in gr _continue _col(15) "{c |}", _col(17) "Coef.",_col(28) "Imp. SE", _col(38) "Imp. SE", _col(47) " SE", _col(58) "", _col(68) "", _col(74) "" + di + di _continue "{text}{dup 14:{c -}}{c +}{dup 68:{c -}}" + + foreach name of local names { + di + mat qhat=Qbar[1,"`name'"] + mat b=B["`name'","`name'"] + mat u=Ubar["`name'","`name'"] + mat t=T["`name'","`name'"] + local df = (`impute'-1)*(1+(u[1,1])/((1+1/`impute')*b[1,1]))^2 + local ttest= qhat[1,1]/sqrt(t[1,1]) + di as text _continue "`name'",_col(15) "{c |}", as res _col(10) %7.4f qhat[1,1],_col(17) %9.3f sqrt(b[1,1]), _col(25) %9.3f sqrt(u[1,1]), _col(34) %9.3f sqrt(t[1,1]), _col(44) %9.1f `df', _col(53) %9.3f `ttest', _col(62) %9.3f tprob(`df',`ttest') + } + + +di +di _continue "{text}{dup 14:{c -}}{c +}{dup 68:{c -}}" +di +local name : word 1 of `names' +local i 1 +di in gr _continue "Variable", _col(15) "{c |}", _col(17) "[$S_level% Conf. Interval]" +di +di _continue "{text}{dup 14:{c -}}{c +}{dup 68:{c -}}" +while "`name'"~="" { + di + mat qhat=Qbar[1,"`name'"] + mat b=B["`name'","`name'"] + mat u=Ubar["`name'","`name'"] + mat t=T["`name'","`name'"] + local df = (`impute'-1)*(1+(u[1,1])/((1+1/`impute')*b[1,1]))^2 + local ttest= qhat[1,1]/sqrt(t[1,1]) + + local prob = 1-((100-$S_level)/2)/100 + local tvalue=abs( invttail(`df',`prob') ) +/* The t-distribution function could be very out here.... due to a version 6 bug! + version 6 : local tvalue = invt(`df',`prob') + +THIS HAS BEEN REMOVED 15Aug07 as the probability is calculated on adding the two tails AND it should have been +a single tailed value!!! +*/ + + + + local left = qhat[1,1]-`tvalue'*sqrt(t[1,1]) + local right = qhat[1,1]+`tvalue'*sqrt(t[1,1]) + di as text _continue "`name'",_col(15) "{c |}", as res %9.4f `left', %9.4f `right' + local i=`i'+1 + local name : word `i' of `names' +} +di "" +di "{text}{dup 14:{c -}}{c BT}{dup 68:{c -}}" + +} /* end of command if statement */ + +restore +end + +/**************************************************** + * The approximate Bayesian Bootstrap hotdecking + ****************************************************/ + +program define _hotdeck +version 9.0 +syntax [varlist] [using], [BY(string) Iseed(string) NOSEED] + +local iseed =`iseed' + +tokenize "`varlist'" +local z "ipattern" + +if "`by'"!="" confirm ex var `by' + +tempvar nobs bstrp b2strp temp temp2 + +local nold = _N +local nnew = _N + +/* This is the place of difference for a set seed command ..*/ + +if "`noseed'"=="" set seed `iseed' +qui sort `by' `z' `varlist' + + + + +qui gen long `nobs' = (`z'!=.) + +if "`by'"=="" { + qui replace `nobs' = sum(`nobs') + qui replace `nobs' = `nobs'[_N] + qui gen long `bstrp' = int(uniform()*`nobs'+1) + qui gen long `b2strp' = int(uniform()*`nobs'+1) + qui gen long `temp' = `bstrp'[`b2strp'] + qui replace `bstrp' = `temp' + qui replace `bstrp' = _n if _n<=`nobs' + qui tokenize "`varlist'" + while "`1'"~="" { + qui gen `temp2' = `1'[`bstrp'] + qui replace `1' = `temp2' + qui drop `temp2' + qui mac shift 1 + } +} +else { + qui by `by': replace `nobs' = sum(`nobs') + qui by `by': replace `nobs' = `nobs'[_N] + qui by `by': gen long `bstrp' = int(uniform()*`nobs'+1) + qui by `by': gen long `b2strp' = int(uniform()*`nobs'+1) + qui by `by': gen long `temp' = `bstrp'[`b2strp'] + qui by `by': replace `bstrp' = `temp' + qui by `by': replace `bstrp' = _n if _n<=`nobs' + + qui tokenize "`varlist'" + while "`1'"~="" { + qui by `by': gen `temp2' = `1'[`bstrp'] + qui by `by': replace `1' = `temp2' + qui mac shift 1 + qui drop `temp2' + } + +} + + +end + +/******************************************************************* + * Get the parameters or a subset of them from the + * model and the subset + * the covariance variance matrix as well + * Note that this section can also handle non-regression commands + * and macro lists + *******************************************************************/ + +program define _parms +syntax [varlist], [PARMS(string asis) ITER(integer 1) COMMAND(string) GENerate(string) REPlace] + + +/* + previously accepted a varlist in the parms string.. too many difficulties with multiple equation models + so this code below is being dropped + +* local 0 "`parms'" +* while "`parms'"~="" { +* gettoken 0 parms: parms , parse(" ,") +* cap syntax [varlist] +* if _rc~=0 { +* if "`0'"=="_cons" local vlist "`vlist' `0'" <-- just extract _cons +* else local plist "`plist' `0'" +* } +* else local vlist "`vlist' `varlist'" +* } +*/ + + +foreach item in `"`parms'"' { + local vlist `"`vlist' `item'"' +} + +/* if results were not part of a regression command */ + +if "`e(cmd)'"=="" { + local names "" + if `iter'==1 di in red "Using Non Regression Parameters and Command" + tokenize "`plist' `vlist'" + + local np=0 + while "`1'"~="" { + local names1 ="`names1' `1'" + local names2 ="`names2' `2'" + if "`2'"=="" { + di in red "Must supply variance estimate of `1'" + exit(302) + } + mac shift 2 + local `np++' + } + mat impb`iter' = J(1,`np',0) + mat impV`iter' = J(`np',`np',0) + + tokenize "`plist' `vlist'" + local np 1 + + while "`1'"~="" { + + if "$`1'"=="" & "``1''"=="" { + di in red "Global = $`1' Local = ``1''" + di in red "Global/local macro `1' is missing " + exit(198) + } + + if "``1''"~="" mat impb`iter'[1,`np'] = ``1'' + if "$`1'"~="" & "``1''"=="" mat impb`iter'[1,`np'] = $`1' + if "$`2'"=="" & "``2''"=="" { + di in red "Global = $`2' Local = ``2''" + di in red "Global/local macro `2' is missing " + exit(198) + } + if "``2''"~="" mat impV`iter'[`np',`np'] = ``2'' + if "$`2'"~="" & "``2''"=="" mat impV`iter'[`np',`np'] = $`2' + + local np=`np'+1 + mac shift 2 + } + + matrix colnames impb`iter'=`names1' + matrix colnames impV`iter'=`names1' + matrix rownames impV`iter'=`names1' +} + +/* The regression-type output part */ +else { + matrix myb = e(b) + matrix myV = e(V) + +/* This next statement is to handle double quoted strings.. otherwise parms will contain one item in a macro */ + + local teparms :di `parms' + local first 1 + foreach item of local teparms { + + if `first'==1 { + cap mat impb`iter' = myb[.,"`item'"] + if _rc==111 { + di as error `" Attempted to extract `item' from e(b) "' + mat list e(b) + di as error "Check the matrix of estimates and only include column names in the parameters NOT variable names" + exit(111) + } + mat impVt`iter'= myV[.,"`item'"] + } + else { + mat temp = myb[.,"`item'"] + mat impb`iter'= impb`iter' , temp + mat drop temp + + mat temp=myV[.,"`item'"] + mat impVt`iter'= impVt`iter' , temp + mat drop temp + } + + local `first++' + } + + local first 1 + foreach item of local teparms { + if `first'==1 mat impV`iter' = impVt`iter'["`item'",.] + else { + mat temp=impVt`iter'["`item'",.] + mat impV`iter'= impV`iter' \ temp + } + local `first++' + } + +} + +end + +/************************************************* + * Look at the missing pattern in the varlist + *************************************************/ + +program define _misspat,rclass +syntax varlist [if] [in] , [BY(string) ] +tokenize "`varlist'" +tempvar touse2 tempid + +qui gen long `tempid'=_n + +mark `touse2' `if' `in' +markout `touse2' + +qui gen str50 pattern="" + +local allstr "" +while "`1'"~="" { + qui replace pattern = cond(`1'==.,pattern+"*",pattern+"-") if `touse2' + local allstr="-`allstr'" + mac shift 1 +} + +qui compress pattern +sort pattern +lab var pattern "Missing pattern" +di +di in green "Missing Patterns" +di "{text}{dup 16:{c -}}" +di +di in green "Table of the Missing data patterns " +di in green " * signifies missing and - is not missing" +di +di "Varlist order: `varlist'" + +tab pattern if `touse2' +local n=r(N) + +qui count if pattern=="`allstr'" & `touse2' + +if r(N)==`n' { + di "There is no missing data in the varlist" + exit(198) +} + +return scalar nmiss = `n'-r(N) +return local allpat = "`allstr'" + +qui gen ipattern=cond(pattern=="`allstr'",1,.) if `touse2' + +/***************************************** + * Calculate stratum missing numbers + *****************************************/ + +if "`by'"~="" { + di + di "{text}STRATUM information" + di "{text}{dup 19:{c -}}" + di + di "{text} Listing the number observed (No_obs) and " + di in green "the number missing (No_miss) in each stratum" + tempvar cnt mcnt + qui sort `by' + qui by `by':gen `cnt'=sum(ipattern) + qui by `by':gen `mcnt'=sum(ipattern==.) + qui by `by': replace `cnt'=cond( _n==_N,`cnt',.) + qui by `by': replace `mcnt'=cond( _n==_N,`mcnt',.) + rename `cnt' No_obs + rename `mcnt' No_miss + l `by' No_obs No_miss if No_obs~=., noobs + di + qui count if No_obs==0 + if `r(N)'>0 { + di in red "WARNING: `r(N)' strata with NO complete records" + di + di "{error}This implies that within these strata the missing data will NOT be replaced " + di "and hence will give the wrong answers in the analysis because the analysis" + di "command will do casewise deletion" + } + qui count if No_obs==1 + if `r(N)'>0 di in blue "Note: `r(N)' strata with only 1 complete record" + qui count if (No_obs>1 & No_obs<6) + if `r(N)'>0 di in blue "Note: `r(N)' strata with 2-5 complete records" + di +} + +/* I thought that the following bit of command might've sorted out the seed problem :( but I don't think so */ +qui sort `tempid' +end + +/************************************************* + * Expand stata syntax + *************************************************/ + +program define mkvlist, rclass +syntax varlist, VLIST(string) + +local o_vlist "`varlist'" +local keep "`vlist'" +local 0 "`keep'" +while "`keep'"~="" { + gettoken 0 keep: keep , parse(" ,") + cap syntax [varlist] + if _rc~=0 { + if "`0'"=="_cons" local vlist "`vlist' `0'" + else local plist "`plist' `0'" + } + else local vlist "`vlist' `varlist'" +} +return local vlist "`o_vlist' `vlist'" + +end + + diff --git a/Modules/ado/plus/h/hotdeck.hlp b/Modules/ado/plus/h/hotdeck.hlp new file mode 100644 index 0000000..5ce9b70 --- /dev/null +++ b/Modules/ado/plus/h/hotdeck.hlp @@ -0,0 +1,220 @@ +{smcl} +{* 15 Aug 2007}{...} +{cmd:help hotdeck} +{hline} + +{title:Title} + + {hi:Impute missing values using the hotdeck method} + +{title:Syntax} + +{p 8 27} +{cmdab:hotdeck} +[{it:varlist}] [{cmd:using}] [{hi:if}{it: exp}] [{hi:in}{it: exp}] +, +[ +{cmdab:by}{cmd:(}{it:varlist}{cmd:)} +{cmdab:store} +{cmdab:imp:ute}{cmd:(}{it:varlist}{cmd:)} +{cmdab:noise} +{cmdab:keep}{cmd:(}{it:varlist}{cmd:)} +{cmdab:com:mand}{cmd:(}{it:command}{cmd:)} +{cmdab:parms}{cmd:(}{it:varlist}{cmd:)} +{cmdab:seed}{cmd:(}{it:#}{cmd:)} +{cmdab:infiles}{cmd:(}{it:filename filename ...}{cmd:)} +] + +{p} + +{title:Description} + +{pstd} +{hi:Hotdeck} will tabulate the missing data patterns within the {help varlist}. +A row of data with missing values in any of the variables in the {hi:varlist} + is defined as a `missing line' of data, similarly a `complete line' is one where all the +variables in the {hi:varlist} contain data. The {hi:hotdeck} procedure +replaces the {hi:varlist} variables in the `missing lines' with the +corresponding values in the `complete lines'. +{hi:Hotdeck} should be used several times within a multiple imputation +sequence since missing data +are imputed stochastically rather than deterministically. The {hi:nmiss} missing +lines in each stratum of the data described by the `by' option are replaced +by lines sampled from the {hi:nobs} complete lines in the same stratum. The +approximate Bayesian bootstrap method of Rubin and Schenker(1986) is used; +first a bootstrap sample of {hi:nobs} lines are sampled with replacement from +the complete lines, and the {hi:nmiss} missing lines are sampled at random +(again with replacement) from this bootstrap sample. + +{pstd} +A major assumption with the hotdeck procedure is +that the missing data are either missing completely at random (MCAR) or is +missing at random (MAR), the probability that a line is missing +varying only with respect to the categorical +variables specified in the `by' option. + +{pstd} +If a dataset contains many variables with missing values then +it is possible that many of the rows of data will contain at +least one missing value. The {hi:hotdeck} procedure will not work +very well in such circumstances. +There are more +elaborate methods that {bf:only} replace missing values, rather than the whole row, + for imputed values. +These multivariate multiple imputation methods are discussed by Schafer(1997). + +{pstd} +A critical point is that all variables that are used in the analysis should be included in +the variable list. This is particularly true for variables that have missing data! +Variables that predict missingness should be included in the +by option so missing data is imputed within strata. + +{title:Latest Version} + +{pstd} +The latest version is always kept on the SSC website. To install the latest version click +on the following link + +{phang} +{stata ssc install hotdeck, replace}. + +{title:Options} + +{phang} +{cmdab:using} specifies the root of the imputed datasets filenames. The default is +"imp" and hence the datasets will be saved as imp1.dta, imp2.dta, .... + +{phang} +{cmdab:by}{cmd:(}{it:varlist}{cmd:)} specifies categorical variables defining strata within which +the imputation is to be carried out. Missing values will be replaced by complete values only within the +strata. If within a strata there are no complete records then no data will be imputed and will lead +to the wrong answers. Make sure there are a reasonable number of complete records per strata. + +{phang} +{cmdab:store} specifies whether the imputed datasets are saved to disk. + +{phang} +{cmdab:imp:ute}{cmd:(}{it:varlist}{cmd:)} specifies the number of imputed datasets to generate. The number +needed varies according to the percentage missing and the type of data, but +generally 5 is sufficient. + +{phang} +{cmdab:noise} specifies whether the individual analyses, from the {hi:command()} option, +are displayed. + +{phang} +{cmdab:keep}{cmd:(}{it:varlist}{cmd:)} specifies the variables saved in the imputed datasets +in addition to the imputed variables and the by list. By default the imputed +variables and the by list are always saved. + +{phang} +{cmdab:com:mand}{cmd:(}{it:command}{cmd:)} specifies the analysis performed on every imputed dataset. + +{phang} +{cmdab:parms}{cmd:(}{it:varlist}{cmd:)} specifies the parameters of interest from the +analysis. If the {hi:command} is a regression command then the parameter list can +include a subset of the variables specified in the regression command.The +final output consists of the combined estimates of these parameters. +For non-standard commands that are "regression" commands the {hi:parms()} option +looks at the estimation matrix e(b) and requires the column names to identify +the coefficients of interest. + +{phang} +{cmdab:seed}{cmd:(}{it:#}{cmd:)} specifies the random number generator seed. When using the {hi:seed} option +the hotdeck command must be used in the correct way. The key point is that ALL variables in the analysis command +must be in the variable list, this ensures that the correlations between the variables are maintained post +imputation. + +{phang} +{cmdab:infiles}{cmd:(}{it:filename filename ...}{cmd:)} specifies a list of files that have missing +values replaced by imputed values. This is convenient when the user has +several imputed datasets and wants to analyse them and combine the results. + + +{title:Examples} + +Impute values for y in sex/age groups. + + {inp:hotdeck y, by(sex age) } + +Additionally to store the imputed datasets above as {hi:imp1.dta} and {hi:imp2.dta}. + + {inp:hotdeck y using imp,store by(sex age) impute(2)} + +{p 0 0} +Hotdeck can also use the stored imputed datafiles hi:imp1.dta} and {hi:imp2.dta} +and carry out the combined analysis. This analysis is displayed for the coefficient +of {hi:x} and constant term {hi:_cons}. + + {inp:hotdeck y using imp, command(logit y x) parms(x _cons) infiles(imp1 imp2)} + +{p 0 0} +Do not save imputed datasets to disk but carry out a logistic regression on the imputed +datasets and display the coefficients for {hi:x} and the constant term {hi:_cons} of the model. + + {inp:hotdeck y x, by(sex age) command(logit y x) parms(x _cons) impute(5)} + + +{title:Example - Multiple Equation Model} + +{p 0 0} +Multiple equation models require more complicated {hi:parms()} statements. +The example used can be applied to all multiple equation models. The only complication +is that the name of the coefficients are different. + +For the following command + +{inp:xtreg kgh f1, mle} + +Then inspect the matrix of coefficients + +{inp:mat list e(b)} + + e(b)[1,4] + kgh: kgh: sigma_u: sigma_e: + f1 _cons _cons _cons + y1 -1.6751401 77.792948 0 16.730843 + +Then the following command will do an imputation and analysis for the single parameter. + +{inp:hotdeck kgh, by(ethn) command(xtreg kgh f1, mle) parms(kgh:f1) impute(5)} + +{title:Example - mlogit} + +Use this web dataset for STATA release 9. + +{stata "use http://www.stata-press.com/data/r9/sysdsn3.dta"} + +The simple model without handling missing data + +{stata mlogit insure male} + +{p 0 0} +The estimated coefficients are put automatically by STATA into the matrix e(b), note the column +headings are the parameter names that {hi:hotdeck} uses. So you can not use the simple syntax +of just {hi:parms(male)} because this refers to two parameters. + +{stata mat list e(b)} + +{p 0 0} +So this syntax will handle the missing data using {hi:hotdeck} imputation. + +{stata "hotdeck insure male, command(mlogit insure male) parms(Prepaid:male) impute(5)"} + +{p 0 0} +{hi:NOTE} hotdeck will fail when using mlogit with spaces in the category labels. This is due +to the lack of functionality in STATA's matrix commands. + +{title:Author} + +{p} +Adrian Mander, MRC Human Nutrition Research, Cambridge, UK. + +Email {browse "mailto:adrian.mander@mrc-hnr.cam.ac.uk":adrian.mander@mrc-hnr.cam.ac.uk} + +{title:See Also} +Related commands + +HELP FILES Installation status SSC installation links Description + +{help whotdeck} (if installed) ({stata ssc install whotdeck}) Weighted version of Hotdeck diff --git a/Modules/ado/plus/h/hotdeck6.ado b/Modules/ado/plus/h/hotdeck6.ado new file mode 100644 index 0000000..7f76fc9 --- /dev/null +++ b/Modules/ado/plus/h/hotdeck6.ado @@ -0,0 +1,637 @@ +*! Date : 1 Aug 2005 +*! Version : 1.64 +*! Authors : Adrian Mander/David Clayton +*! Email : adrian.mander@mrc-hnr.cam.ac.uk +*! Description : Hotdeck imputation + +program define hotdeck6 +version 6.0 +syntax [varlist] [if] [in] [using/], [BY(varlist) IMPute(integer 1) STORE GENerate(string) COMmand(string) PARMS(string) REPlace NOISE KEEP(varlist) SEED(string) QUIET INFILES(string) ] +tokenize "`varlist'" +local z "`1'" + +preserve +if "`if'"~="" { + qui keep `if' +} + + +/* Check the seed option */ +if "`seed'"=="1" { local seed 2} +if "`seed'"=="" { local seed 1 } +confirm number `seed' + +/* To generate a seed from the time */ +if `seed'==1 { + local time = "$S_TIME" + local date = "$S_DATE" + tokenize "`time'", parse(":") + local seed1 "`1'`3'`5'" + tokenize "`date'", parse(" ") + local dat "`1'`2'`3'" + local dat1 = date("`dat'","dmy") + local seed1 "`seed1'`dat1'" + di + local l_seed "2^31-1" + local seed1 = mod(`seed1',`l_seed') + di in green "Seed is `seed1'" + set seed `seed1' + +} + + + +estimates clear +tempfile olddata + +/*NOT SURE if I must implement no strings in BY() option +tokenize "`by'" +while "`1'"~="" { + confirm numeric variable `1' + mac shift 1 +} +*/ + +tempvar touse +mark `touse' `if' `in' +markout `touse' `by', strok + +di in green "DELETING all matrices...." +mat drop _all + + +if "`infiles'"=="" { + if "`by'"=="" { _misspat `varlist' `if' `in' } + else { _misspat `varlist' `if' `in', by(`by') } + local nfill=r(nmiss) +} + +qui save "`olddata'" + +if "`infiles'"=="" { + global allpat = r(allpat) + count if `touse' + local miss = (r(N)-`nfill')/r(N) +} + +if "`command'"=="" { + di in red "WARNING: When the option is not selected " + di in red "then no analysis is performed on the imputed datasets" + di + if "`store'"=="" { + di "ALSO STORE isnt selected so hotdeck will appear to do nothing" + exit(198) + } +} + +if `impute'<1 { + di in red "The number of imputations must be more than 0 not `impute'" + exit(198) +} + +if `impute'==1 & "`infiles'"=="" { + if "`store'"=="" | "`command'"~="" { + di in red "If one imputation is made then command option should NOT be used" + di in red "AND the store option must be specified" + exit(198) + } +} + + +if "`using'"~="" { + if "`store'"=="" { + di in red "To save datasets you must specify the STORE option" + exit(198) + } +} +if "`keep'"~="" { + if "`store'"=="" { + di in red "If you use the KEEP option you must specify the STORE option" + exit(198) + } +} + +if "`noise'"~="" & "`command'"=="" { + di in red "When specifying noise you must also specify the command option" + exit(198) +} +if "`command'"~="" { + if "`parms'"=="" { + di in red "To obtain any output from the command option you must also specify " + di in red "the parameters of interest using the parms() option" + exit(198) + } +} + +/************************************************ + * Loop over the number of imputed data sets + * required + ************************************************/ + +if "`seed'"~="1" {set seed `seed'} + +/* This is the if statement that allows the input of imputed datafiles */ +if "`infiles'"~="" { + local i 1 + tokenize "`infiles'" + while "`1'"~="" { + use "`1'",replace + mac shift 1 + if "`command'"=="" { + di in red "You must use the command option when using INFILES" + exit(198) + } + if "`noise'"~="" { `command' } + else { qui `command' } /* Do the analysis */ + _parms, parms(`parms') command(`command') iter(`i') /* Select Parameters of interest*/ + local i =`i'+1 + } + local impute=`i'-1 +} + +else { + local i 1 + while `i'<= `impute' { + use "`olddata'",clear /* Use original dataset */ + qui keep if `touse' + + if "`by'"~="" { _hotdeck `varlist', by(`by') } + else { _hotdeck `varlist' } /* Impute values */ + if "`store'"~="" { /* Save imputed datasets */ + if "`using'"=="" { + local using "imp" + } + if "`keep'"=="" { + qui keep `varlist' `by' + qui save `using'`i',replace + } + else { + mkvlist `varlist' `by', vlist(`keep') + qui keep `r(vlist)' + qui save `using'`i',replace + } + } + if "`command'"~="" { + if "`noise'"~="" { `command' } + else { qui `command' } /* Do the analysis */ + _parms, parms(`parms') command(`command') iter(`i') /* Select Parameters of interest*/ + } + local i=`i'+1 + } +} + +if "`command'"~="" { + +/******************************************************** + * Loop to calculate the estimates needed + * + * First get the dimensions of the parameter matrices + ********************************************************/ + +local dim= rowsof(impV1) +mat Qbar = J(1,`dim',0) +mat Ubar = J(`dim',`dim',0) + +/* calc the averaging factor */ +local inv = 1/`impute' + +/* calc the average coef and variance qbar and ubar */ +local i 1 +while `i'<= `impute' { + mat Qbar= `inv'*impb`i'+ Qbar + mat Ubar= `inv'*impV`i'+ Ubar +local i=`i'+1 +} + +/* calc between variances */ +mat B=J(`dim',`dim',0) +local inv1 = 1/(`impute'-1) + +local i 1 +while `i'<= `impute' { + mat B= B + `inv1'*(impb`i' - Qbar)'*(impb`i' - Qbar) +local i=`i'+1 +} + +/* Calc total variance */ +mat T = Ubar+(1+1/`impute')*B + +cap mat tempmt=B*inv(Ubar) +if _rc==504 { + di as error "WARNING: Trying to invert variance matrix with zero elements?" + local ter = rowsof(Ubar) + mat temp = J(`ter',1,1) + mat temp2 = Ubar*temp + local tei 1 + local names: colfullnames(impb1) + matrix rownames temp2 = `names' + while `tei'<=`ter' { + if temp2[`tei',1]==0 { + local var:word `tei' of "`names'" + di as txt "Variance for covariate `tei' is 0 !!" + } + local tei=`tei'+1 + } + mat tempmt=B*inv(Ubar) +} + +local trace=trace(tempmt) +local r1 = 1-((1+1/`impute')*`trace'/`dim') +local names: rowfullnames(impb1) +matrix rownames Qbar = `names' +local names: colfullnames(impb1) +matrix colnames Qbar = `names' + +local names: rowfullnames(impV1) +matrix rownames T = `names' +matrix rownames B = `names' +matrix rownames Ubar = `names' +local names: colfullnames(impV1) +matrix colnames T = `names' +matrix colnames B = `names' +matrix colnames Ubar = `names' + +mat Tsurr= `r1'*T +mat D = Qbar*inv(Tsurr)*Qbar' + +local D1 = D[1,1]/`dim' +local t=`dim'*(`impute'-1) +local v1= 4+(`t'-4)*(1+(1-2/`t')*1/`r1')^2 +local ftest= fprob(`dim',`v1',`D1') + +/******************************************************** + * The next will output the main results in Stata style + * if the normal approximation is good then you could + * use the matrix post command + ********************************************************/ + +if "`quiet'"=="" { +if `r1'<0 { + di in red "WARNING: between se larger than within se in one or more " + di in red "parameters invalidating the global F test" +} +if `t'<4 { + di in red "WARNING: t less than 4 invalid global test increase " + di in red "parameters OR imputations" +} +} +di +di in gr _col(1) "Number of Obs.", _col(45) " = ", _N +di in gr _col(1) "No. of Imputations", _col(48) "= ", `impute' + +if "`infiles'"=="" { + di in gr _col(1) "% Lines of Missing Data", _col(45) " = ", `miss'*100,"%" +} + +di in gr _col(1) "F(",%6.3f `v1',",`dim')", _col(45) " = ", %9.4f `D1' +di in gr _col(1) "Prob > F " , _col(45) " = ", %9.4f `ftest' + + di in gr _dup(83) "-" + local names: colfullnames(impb1) + local name : word 1 of `names' + local i 1 + di in gr _continue "Variable |",_col(12) "Average",_col(21) "Between", _col(30) "Within", _col(40) "Total", _col(50) "df", _col(59) "t", _col(65) "p-value" + di + di in gr _continue" |",_col(12) "Coef.",_col(21) "Imp. SE", _col(30) "Imp. SE", _col(39) " SE", _col(50) "", _col(59) "", _col(65) "" + di + di in gr _continue "-------------+---------------------------------------------------------------------" + + while "`name'"~="" { + di + mat qhat=Qbar[1,"`name'"] + mat b=B["`name'","`name'"] + mat u=Ubar["`name'","`name'"] + mat t=T["`name'","`name'"] + local df = (`impute'-1)*(1+(u[1,1])/((1+1/`impute')*b[1,1]))^2 + local ttest= qhat[1,1]/sqrt(t[1,1]) + di _continue "`name'",_col(9) "|", _col(10) %7.4f qhat[1,1],_col(17) %9.3f sqrt(b[1,1]), _col(25) %9.3f sqrt(u[1,1]), _col(34) %9.3f sqrt(t[1,1]), _col(44) %9.1f `df', _col(53) %9.3f `ttest', _col(62) %9.3f tprob(`df',`ttest') + local i=`i'+1 + local name : word `i' of `names' + } + di + di in gr _continue "-------------+---------------------------------------------------------------------" + di + local name : word 1 of `names' + local i 1 + di in gr _continue "Variable |",_col(12) "[$S_level% Conf. Interval]" + di + di in gr _continue "-------------+---------------------------------------------------------------------" + while "`name'"~="" { + di + mat qhat=Qbar[1,"`name'"] + mat b=B["`name'","`name'"] + mat u=Ubar["`name'","`name'"] + mat t=T["`name'","`name'"] + local df = (`impute'-1)*(1+(u[1,1])/((1+1/`impute')*b[1,1]))^2 + local ttest= qhat[1,1]/sqrt(t[1,1]) + local prob = 1-((100-$S_level)/2)/100 + local tvalue = invt(`df',`prob') + local left = qhat[1,1]-`tvalue'*sqrt(t[1,1]) + local right = qhat[1,1]+`tvalue'*sqrt(t[1,1]) + di _continue "`name'",_col(9) "|", %9.4f `left', %9.4f `right' + local i=`i'+1 + local name : word `i' of `names' + } + di "" + di in gr _dup(83) "-" + +} /* end of command if statement */ + +restore +end + +/**************************************************** + * The approximate Bayesian Bootstrap hotdecking + ****************************************************/ + +program define _hotdeck +version 6.0 +syntax [varlist] [using], [BY(string)] +tokenize "`varlist'" +local z "ipattern" + +if "`by'"!="" { + confirm ex var `by' +} + +tempvar nobs bstrp b2strp temp temp2 + +qui { + local nold = _N + local nnew = _N + sort `by' `z' `varlist' + gen long `nobs' = (`z'!=.) + + if "`by'"=="" { + replace `nobs' = sum(`nobs') + replace `nobs' = `nobs'[_N] + gen long `bstrp' = int(uniform()*`nobs'+1) + gen long `b2strp' = int(uniform()*`nobs'+1) + gen long `temp' = `bstrp'[`b2strp'] + replace `bstrp' = `temp' + replace `bstrp' = _n if _n<=`nobs' + + tokenize "`varlist'" + while "`1'"~="" { + gen `temp2' = `1'[`bstrp'] + replace `1' = `temp2' + drop `temp2' + mac shift 1 + } + } + else { + by `by': replace `nobs' = sum(`nobs') + by `by': replace `nobs' = `nobs'[_N] + by `by': gen long `bstrp' = int(uniform()*`nobs'+1) + by `by': gen long `b2strp' = int(uniform()*`nobs'+1) + + by `by': gen long `temp' = `bstrp'[`b2strp'] + by `by': replace `bstrp' = `temp' + + by `by': replace `bstrp' = _n if _n<=`nobs' + + tokenize "`varlist'" + while "`1'"~="" { + by `by': gen `temp2' = `1'[`bstrp'] + + by `by': replace `1' = `temp2' + mac shift 1 + drop `temp2' + } + } +} + + +end + +/******************************************************************* + * Get the parameters or a subset of them from the + * model and the subset + * the covariance variance matrix as well + * Note that this section can also handle non-regression commands + * and macro lists + *******************************************************************/ + +program define _parms + syntax [varlist], [PARMS(string) ITER(integer 1) COMMAND(string) GENerate(string) REPlace] + +local 0 "`parms'" +while "`parms'"~="" { + gettoken 0 parms: parms , parse(" ,") + cap syntax [varlist] + if _rc~=0 { + if "`0'"=="_cons" { local vlist "`vlist' `0'" } + else { local plist "`plist' `0'" } + } + else { local vlist "`vlist' `varlist'" } +} + +* if results were not part of a regression command + +if "`e(cmd)'"=="" { + local names = "" + if `iter'==1 { di in red "Using Non Regression Parameters and Command" } + tokenize "`plist' `vlist'" + + local np=0 + while "`1'"~="" { + local names1 ="`names1' `1'" + local names2 ="`names2' `2'" + if "`2'"=="" { di in red "Must supply variance estimate of `1'" + exit(302) + } + mac shift 2 + local np = `np'+1 + } + mat impb`iter' = J(1,`np',0) + mat impV`iter' = J(`np',`np',0) + + tokenize "`plist' `vlist'" + local np 1 + + while "`1'"~="" { + + if "$`1'"=="" & "``1''"=="" { + di in red "Global = $`1' Local = ``1''" + di in red "Global/local macro `1' is missing " + exit(198) + } + + if "``1''"~="" { mat impb`iter'[1,`np'] = ``1'' } + if "$`1'"~="" & "``1''"=="" { mat impb`iter'[1,`np'] = $`1' } + if "$`2'"=="" & "``2''"=="" { + di in red "Global = $`2' Local = ``2''" + di in red "Global/local macro `2' is missing " + exit(198) + } + if "``2''"~="" { mat impV`iter'[`np',`np'] = ``2'' } + if "$`2'"~="" & "``2''"=="" { mat impV`iter'[`np',`np'] = $`2' } + + local np=`np'+1 + mac shift 2 + } + + matrix colnames impb`iter'=`names1' + matrix colnames impV`iter'=`names1' + matrix rownames impV`iter'=`names1' +} +else { + matrix myb = get(_b) + matrix myV = get(VCE) + tokenize "`vlist' `plist'" + if "`2'"~="" { + cap mat impb`iter' = myb[.,"`1'"] + if _rc==111 { + di as error "Are you sure `1' is in the model??" + di as error "Check the matrix of estimates and only include column names in the parameters NOT variable names" + exit(111) + } + mac shift 1 + while "`1'"~="" { + mat temp=myb[.,"`1'"] + mat impb`iter'= impb`iter' , temp + mac shift 1 + } + + tokenize "`vlist' `plist'", parse(" ") + mat impVt`iter' = myV[.,"`1'"] + mac shift 1 + while "`1'"~="" { + mat temp=myV[.,"`1'"] + mat impVt`iter'= impVt`iter' , temp + mac shift 1 + } + + tokenize "`vlist' `plist'", parse(" ") + mat impV`iter' = impVt`iter'["`1'",.] + mac shift 1 + while "`1'"~="" { + mat temp=impVt`iter'["`1'",.] + mat impV`iter'= impV`iter' \ temp + mac shift 1 + } + + mat drop myb + mat drop myV + mat drop impVt`iter' + mat drop temp + } + else { + cap mat impb`iter' = myb[.,"`1'"] + if _rc==111 { + di as error "Are you sure `1' is in the model??" + exit(111) + } + mat impVt`iter'=myV[.,"`1'"] + mat impV`iter' = impVt`iter'["`1'",.] + } +} +end + +/************************************************* + * Look at the missing pattern in the varlist + *************************************************/ + +program define _misspat,rclass +syntax varlist [if] [in] , [BY(string) ] +tokenize "`varlist'" +tempvar touse2 + +mark `touse2' `if' `in' +markout `touse2' + +qui gen str40 pattern="" + +local allstr "" +while "`1'"~="" { + qui replace pattern = cond(`1'==.,pattern+"*",pattern+"-") if `touse2' + local allstr="-`allstr'" +mac shift 1 +} +qui compress pattern +sort pattern +lab var pattern "Missing pattern" +di +di in green "Missing Patterns" +di in green "----------------" +di +di in green "Table of the Missing data patterns " +di in green " * signifies missing and - is not missing" +di +di "Varlist order: `varlist'" + +tab pattern if `touse2' +local n=r(N) + +qui count if pattern=="`allstr'" & `touse2' + +if r(N)==`n' { + di "There is no missing data in the varlist" + exit(198) +} + +return scalar nmiss = `n'-r(N) +return local allpat = "`allstr'" + +qui gen ipattern=cond(pattern=="`allstr'",1,.) if `touse2' + +/***************************************** + * Calculate stratum missing numbers + *****************************************/ + +if "`by'"~="" { + di + di in green "STRATUM information" + di in green "-------------------" + di + di in green "Listing the number observed (No_obs) and " + di in green "the number missing (No_miss) in each stratum" + tempvar cnt mcnt + qui sort `by' + qui by `by':gen `cnt'=sum(ipattern) + qui by `by':gen `mcnt'=sum(ipattern==.) + qui by `by': replace `cnt'=cond( _n==_N,`cnt',.) + qui by `by': replace `mcnt'=cond( _n==_N,`mcnt',.) + rename `cnt' No_obs + rename `mcnt' No_miss + l `by' No_obs No_miss if No_obs~=., noobs + di + qui count if No_obs==0 + if `r(N)'>0 { di in red "WARNING: `r(N)' strata with NO observed data" } + qui count if No_obs==1 + if `r(N)'>0 { di in blue "`r(N)' strata with only 1 observed data"} + qui count if (No_obs>1 & No_obs<6) + if `r(N)'>0 { di in blue "`r(N)' strata with 2-5 observed data"} + di +} + +end + +/************************************************* + * Expand stata syntax + *************************************************/ + +program define mkvlist, rclass +syntax varlist, VLIST(string) + +local o_vlist "`varlist'" +local keep "`vlist'" +local 0 "`keep'" +while "`keep'"~="" { + gettoken 0 keep: keep , parse(" ,") + cap syntax [varlist] + if _rc~=0 { + if "`0'"=="_cons" { + local vlist "`vlist' `0'" + } + else { local plist "`plist' `0'" } + } + else { + local vlist "`vlist' `varlist'" + } +} + return local vlist "`o_vlist' `vlist'" + +end + + diff --git a/Modules/ado/plus/h/hotdeck6.hlp b/Modules/ado/plus/h/hotdeck6.hlp new file mode 100644 index 0000000..ea2f149 --- /dev/null +++ b/Modules/ado/plus/h/hotdeck6.hlp @@ -0,0 +1 @@ +.h hotdeck diff --git a/Modules/ado/plus/h/hplot.ado b/Modules/ado/plus/h/hplot.ado new file mode 100644 index 0000000..596fa45 --- /dev/null +++ b/Modules/ado/plus/h/hplot.ado @@ -0,0 +1,625 @@ +*! 1.4.1 NJC 16 May 1999 +* 1.4.0 NJC 19 March 1999 +* Mike Bradburn unearthed bug marked `MB' +* 1.3.0 NJC 31 March 1998 +* Fred Wolfe unearthed bugs and suggested features marked `FW' +* 1.2.0 NJC 17 June 1997 +program define hplot + version 6.0 + + #delimit ; + syntax varlist(numeric) [if] [in] + [, BOrder SOrt(string) noXaxis noYaxis PEn(string) Symbol(string) + T1title(string) T2title(string) TItle(string) TTIck XLAbel(numlist) + XLIne(numlist) XSCale(str) XTIck(numlist) Axtol(int 600) Blank flipt + Format(string) FONTC(int 290) FONTR(int 570) FONTCB(int 444) + FONTRB(int 923) GAPMag(real 1) GAPs(numlist int) GLegend(string) + GLLJ GLPOS(int -1) t2m(int 0) Grid LAP Legend(string) LIne NIT2 + t1m(int 0) PTSize(int 275) Range TIM(int 0) Vat VATFmt(string) + VATPos(int 31500) Cstart(int -1) SAving(string) PENText(int 1) ] ; + #delimit cr + + qui { + tempvar touse order gleg gap dmin dmax dneg dpos z + mark `touse' `if' `in' + Markout2 `touse' `varlist' + gen `order' = _n + gsort - `touse' `sort' `order' + count if `touse' + loc nuse = r(N) + + * legend on left + if "`legend'" == "" { + tempvar legend + g str1 `legend' = " " + if "`blank'" == "" { + replace `legend' = string(_n) if `touse' + } + } + else { + confirm variable `legend' + capture confirm string variable `legend' + if _rc == 7 { + tempvar legend2 + capture decode `legend', g(`legend2') + if _rc { + gen str1 `legend2' = "" + replace `legend2' = string(`legend') + } + else { + replace `legend2' = string(`legend') /* + */ if missing(`legend2') + } + loc legend "`legend2'" + } + } + loc leglen : type `legend' + loc leglen = substr("`leglen'",4,.) + if `cstart' == -1 { + loc cstart = 2000 + int(9000 * `leglen' / 25) + } + + * axis scale + if "`xscale'" != "" { + tokenize "`xscale'", parse(",") + if "`4'" != "" | "`2'" != "," { + di in r "invalid xscale( ) option" + exit 198 + } + loc xscmin `1' + loc xscmax `3' + } + + if "`xscmin'" == "" { loc min 0 } + else loc min `xscmin' + if "`xscmax'" == "" { loc max 0 } + else loc max `xscmax' + + * xlabel xtick xline might extend graph range beyond data range + if "`xlabel'`xtick'`xline'" != "" { + numlist "`xlabel' `xtick' `xline'", sort + loc nn : word count `r(numlist)' + loc xmin : word 1 of `r(numlist)' + loc xmax : word `nn' of `r(numlist)' + loc min = min(`min', `xmin') + loc max = max(`max', `xmax') + } + + * gap legend? + g str1 `gleg' = " " + loc glj = cond("`gllj'" != "", -1, 1) + if "`glegend'" != "" { + tokenize "`glegend'", parse("!") + loc j 1 + while "`1'" != "" { + if "`1'" != "!" { + if "`1'" == "." { loc 1 " " } + loc gleg`j' "`1'" + loc j = `j' + 1 + } + mac shift + } + } + + * gaps between lines? + g byte `gap' = 0 + if "`gaps'" != "" { + loc j 1 + numlist "`gaps'", int range(>=0) + tokenize `r(numlist)' + while "`1'" != "" { + if "`1'" == "0" { + loc gleg0 "`gleg`j''" + if "`gleg0'" == "" { loc gleg0 " " } + } + else { + replace `gap' = 1 in `1' if `1' <= `nuse' + replace `gleg' = "`gleg`j''" in `1' if `1' <= `nuse' + } + loc j = `j' + 1 + mac shift + } + } + count if `gap' + loc ngaps = r(N) + ("`gleg0'" != "") + + * data range + tokenize `varlist' + loc nvars : word count `varlist' + g `dmin' = `1' + g `dmax' = `1' + if `nvars' >= 2 { + loc i 2 + while `i' <= `nvars' { + replace `dmin' = min(`dmin', ``i'') + replace `dmax' = max(`dmax', ``i'') + loc i = `i' + 1 + } + } + su `dmin' if `touse', meanonly + loc min = min(`min', r(min)) + su `dmax' if `touse', meanonly + loc max = max(`max', r(max)) + loc drange = `max' - `min' + loc zero = cond(`min' >= 0, max(0,`min'), min(0,`max')) + g `z' = `zero' + g `dneg' = min(`dmin', `z') + g `dpos' = max(`dmax', `z') + } + + * start of parameter block + + loc t1start 1000 /* row for t1title */ + loc t2start 1900 /* row for t2title */ + loc ybeg 2400 /* start of y-axis */ + loc ylength 17600 + + * `axtol' is space at ends of y-axis + * axtol too large => ystep negative FW + if `axtol' > `ylength' / 2 { + di in bl "axtol too large: reset to default 600" + loc axtol 600 + } + + * row where first line starts + loc ystart = `ybeg' + `axtol' + + * step between lines: one gap defaults to one line + loc ystep = /* + */ (`ylength' - 2 * `axtol')/(`nuse' - 1 + `ngaps' *`gapmag') + + loc yend = `ybeg' + `ylength' + loc ynudge = 200 * (`fontr'/570)^2 + /* text displaced downwards from lines */ + loc ytick 400 /* tick length */ + loc yleg 1000 /* labels down from axis */ + loc yleg = `yend' + `yleg' + loc ytitle 1400 /* title down from labels */ + loc ytitlef 900 /* title down from labels, flip titles */ + loc xstart `cstart' /* col where first line begins */ + loc xgap 400 /* gap between left legend and body of plot */ + loc xbeg = `xstart' - `xgap' + if `glpos' == -1 { loc glpos `xbeg' } + loc xlength = 30000 - `xstart' + /* horizontal extent of data region */ + loc xend = `xbeg' + `xgap' + `xlength' + loc xz = /* + */ `xbeg' + `xgap' + `xlength' * (`zero' - `min') / `drange' + loc mcent = (`cstart' + 30000)/2 + `tim' + /* col where main title centred */ + loc dotsp 150 /* spacing between dots */ + + if "`format'" == "" { loc format "%1.0f" } + if "`vatfmt'" == "" { loc vatfmt "%1.0f" } + loc ahl = 500 * `ptsize'/275 /* arrowhead length */ + loc aha = _pi/6 /* arrowhead angle, between head and stem */ + loc barht `ahl' /* bar height */ + + if "`symbol'" == "" { + if `nvars' < 6 { loc symbol "46253" } + else loc symbol : di _dup(`nvars') "4" + } + else if length("`symbol'") == 1 & `nvars' > 1 { + loc symbol : di _dup(`nvars') "`symbol'" + } + Gphtrans `symbol' + loc symbol "`r(symbol)'" + + if "`pen'" == "" { loc pen : di _dup(`nvars') "2" } + else if length("`pen'") == 1 & `nvars' > 1 { + loc pen : di _dup(`nvars') "`pen'" + } + + * end of parameter block + + * start gph + if "`saving'" != "" { loc saving ", saving(`saving')" } + gph open `saving' /* FW */ + gph pen `pentext' + gph font `fontr' `fontc' + + * y-axis + if "`yaxis'" == "" { gph line `ybeg' `xstart' `yend' `xstart' } + + * ttick => top ticks + loc ttick = "`ttick'" == "ttick" + * ttick should => border FW + if `ttick' { loc border "border" } + + * x-axis and labels + if "`xaxis'" == "" { + gph line `yend' `xstart' `yend' `xend' + loc ytick2 = `ybeg' - `ytick'/2 + loc ytick = `yend' + `ytick' + if "`xlabel'" == "" { + gph line `yend' `xstart' `ytick' `xstart' + gph line `yend' `xend' `ytick' `xend' + if `ttick' { + gph line `ybeg' `xstart' `ytick2' `xstart' + gph line `ybeg' `xend' `ytick2' `xend' /* FW */ + } + loc text = cond("`lap'" == "lap", abs(`min'), `min') + loc text : di `format' `text' + gph text `yleg' `xstart' 0 0 `text' + loc text = cond("`lap'" == "lap", abs(`max'), `max') + loc text : di `format' `text' + gph text `yleg' `xend' 0 0 `text' + } + else { + numlist "`xlabel'" + tokenize `r(numlist)' + while "`1'" != "" { + loc xtickp = /* + */ `xbeg' + `xgap' + `xlength' * (`1' - `min')/`drange' + gph line `yend' `xtickp' `ytick' `xtickp' + if `ttick' { + gph line `ybeg' `xtickp' `ytick2' `xtickp' + } + loc text = cond("`lap'" == "lap", abs(`1'), `1') + loc text : di `format' `text' + gph text `yleg' `xtickp' 0 0 `text' + mac shift + } + } + } + + * x-ticks + if "`xtick'" != "" { + numlist "`xtick'" + tokenize `r(numlist)' + while "`1'" != "" { + loc xtickp = /* + */ `xbeg' + `xgap' + `xlength' * (`1' - `min')/`drange' + gph line `yend' `xtickp' `ytick' `xtickp' + if `ttick' { + gph line `ybeg' `xtickp' `ytick2' `xtickp' + } + mac shift + } + } + + * x-lines + if "`xline'" != "" { + numlist "`xline'" + tokenize `r(numlist)' + while "`1'" != "" { + loc xli = /* + */ `xbeg' + `xgap' + `xlength' * (`1' - `min')/`drange' + gph line `yend' `xli' `ybeg' `xli' + mac shift + } + } + + * border + if "`border'" != "" { + gph line `ybeg' `xstart' `ybeg' `xend' + gph line `ybeg' `xend' `yend' `xend' + if "`xaxis'" != "" { gph line `yend' `xstart' `yend' `xend' } + } + + * gap legend above first data point + if "`gleg0'" != "" { + loc y2 = `ystart' + (`gapmag' - 1) * `ystep' + `ynudge' + gph text `y2' `glpos' 0 `glj' `gleg0' + } + + * for each variable + tokenize `varlist' + loc j 1 + while "`1'" != "" { + + loc data "`1'" + loc sy = substr("`symbol'",`j',1) + loc pe = substr("`pen'",`j',1) + loc y `ystart' + if "`gleg0'" != "" { loc y = `y' + `ystep' * `gapmag' } + + * for each observation + loc i 1 + while `i' <= `nuse' { + + * dots and/or lines + if `j' == 1 { + if "`range'" == "range" { + /* MB: next statement needed because largest value + could be negative, of course! */ + loc xmax = `xbeg' + `xgap' + /* + */ `xlength' * (`dmax'[`i'] - `min') / `drange' + loc xmin = `xbeg' + `xgap' + /* + */ `xlength' * (`dmin'[`i'] - `min') / `drange' + loc xz `xmin' + } + else { + loc xmax = `xbeg' + `xgap' + /* + */ `xlength' * (`dpos'[`i'] - `min') / `drange' + loc xmin = `xbeg' + `xgap' + /* + */ `xlength' * (`dneg'[`i'] - `min') / `drange' + } + if "`line'" == "line" { + gph line `y' `xmax' `y' `xz' + gph line `y' `xmin' `y' `xz' + } + if "`grid'" == "" { + loc xdot `xz' + loc ndots = int(abs(`xmax' - `xz') / `dotsp') + loc idot 1 + while `idot' <= `ndots' { + gph point `y' `xdot' `ptsize' 0 + if "`range'" == "range" { + loc xdot = `xdot' + `dotsp' + } + else loc xdot = /* + */ `xdot' + `dotsp' * sign(`dpos'[`i']) + loc idot = `idot' + 1 + } + loc xdot `xz' + loc ndots = int(abs(`xmin' - `xz') / `dotsp') + loc idot 1 + while `idot' <= `ndots' { + gph point `y' `xdot' `ptsize' 0 + loc xdot = `xdot' + `dotsp' * sign(`dneg'[`i']) + loc idot = `idot' + 1 + } + } + else { + loc xdot `xstart' + while `xdot' < `xend' { + gph point `y' `xdot' `ptsize' 0 + loc xdot = `xdot' + `dotsp' + } + } + } + + * data point + gph pen `pe' + loc x = `xbeg' + `xgap' + /* + */ `xlength' * (`data'[`i'] - `min') / `drange' + if `data'[`i'] < . & "`sy'" != "i" { + if "`sy'" == "a" { + if `j' == 1 { loc sign 1 } + else loc sign = sign(`data'[`i'] - `prev'[`i']) + Gphhah `y' `x' `sign' `ahl' `aha' + } + else if "`sy'" == ">" { Gphhah `y' `x' 1 `ahl' `aha' } + else if "`sy'" == "<" { Gphhah `y' `x' -1 `ahl' `aha' } + else Gphpt `sy' `y' `x' `barht' `ptsize' + } + + * text + gph pen `pentext' + loc y2 = `y' + `ynudge' + if "`vat'" != "" & `nvars' == 1 { + loc text : di `vatfmt' `data'[`i'] + gph text `y2' `vatpos' 0 1 `text' + } + if `j' == 1 { + loc text = `legend'[`i'] + gph text `y2' `xbeg' 0 1 `text' + } + + * gap + if `gap'[`i'] { + loc y = `y' + `ystep' * `gapmag' + if `j' == 1 { + loc text = `gleg'[`i'] + loc y2 = `y' + `ynudge' + gph text `y2' `glpos' 0 `glj' `text' + } + } + + loc y = `y' + `ystep' + loc i = `i' + 1 + } + * next observation + + loc prev `1' + loc j = `j' + 1 + mac shift + } + * next variable + + * t2title, left justified (defaults to key for 2 or more variables) + if "`t2title'" != "" & trim("`t2title'") == "" { + loc t2title + } + else if "`t2title'" != "" { + gph text `t2start' `xstart' 0 -1 `t2title' + } + else if `nvars' >= 2 { + loc t2 = `t2start' - `ynudge' + loc xjump = `xlength' / `nvars' + loc xjump2 = `xjump' / 50 + loc x = `xstart' + `xjump2' + `t2m' + loc j 1 + while `j' <= `nvars' { + loc sy = substr("`symbol'",`j',1) + loc pe = substr("`pen'",`j',1) + gph pen `pe' + if "`sy'" == "a" { + loc ahv = index("`symbol'","a") + if `ahv' > 1 { + loc this : word `ahv' of `varlist' + loc ahvm1 = `ahv' - 1 + local prev : word `ahvm1' of `varlist' + count if `this' >= `prev' & `touse' + loc majsign = cond(r(N) > `nuse'/2, 1, -1) + } + else loc majsign 1 + loc x3 = `x' + 0.6 * `ptsize' * `majsign' + Gphhah `t2' `x3' `majsign' `ahl' `aha' + } + else if "`sy'" == ">" { + loc x3 = `x' + 0.6 * `ptsize' + Gphhah `t2' `x3' 1 `ahl' `aha' + } + else if "`sy'" == "<" { + loc x3 = `x' - 0.6 * `ptsize' + Gphhah `t2' `x3' -1 `ahl' `aha' + } + else if "`sy'" != "i" { + Gphpt `sy' `t2' `x' `barht' `ptsize' + } + loc x2 = `x' + `xjump2' + loc var : word `j' of `varlist' + if "`nit2'" == "" { + loc text : variable label `var' + if "`text'" == "" { loc text "`var'" } + } + else loc text "`var'" + gph pen `pentext' + gph text `t2start' `x2' 0 -1 `text' + loc x = `x' + `xjump' + loc j = `j' + 1 + } + } + + * title and t1title + if "`title'" == "" & `nvars' == 1 { + loc title : variable label `data' + if "`title'" == "" { loc title "`data'" } + } + else if "`title'" != "" & trim("`title'") == "" { loc title } + + loc xL = `xstart' + `t1m' + if "`flipt'" == "" { /* default */ + * t1title, left justified + gph text `t1start' `xL' 0 -1 `t1title' + + * main title at bottom, centred + gph font `fontrb' `fontcb' + loc ytitle = `yleg' + `ytitle' + gph text `ytitle' `mcent' 0 0 `title' + } + else { /* flip titles from default */ + * bottom title, centred (and closer to axis than default) + loc ytitle = `yleg' + `ytitlef' + gph text `ytitle' `mcent' 0 0 `t1title' + + * main title at top, left justified + gph font `fontrb' `fontcb' + gph text `t1start' `xL' 0 -1 `title' + } + + gph close +end + +program define Gphhah /* horizontal arrow head */ +* `1' y position of tip +* `2' x position of tip +* `3' sign determines direction: 1 = >, -1 = < +* `4' arrowhead length +* `5' arrowhead interior angle (between shaft and head) +* 1.0.1 NJC 18 February 1999 +* 1.0.0 NJC 27 May 1997 + version 6.0 + loc ah1y = `1' - `3' * `4' * sin(`5') + loc ah1x = `2' - `3' * `4' * cos(`5') + loc ah2y = `1' + `3' * `4' * sin(`5') + loc ah2x = `2' - `3' * `4' * cos(`5') + gph line `ah1y' `ah1x' `1' `2' + gph line `ah2y' `ah2x' `1' `2' +end + +program define Gphbar /* vertical bar */ +* Gphbar yposition xposition bar_height +* 1.0.1 NJC 18 February 1999 +* 1.0.0 NJC 27 May 1997 + version 6.0 + loc by1 = `1' - 0.5 * `3' + loc by2 = `1' + 0.5 * `3' + gph line `by1' `2' `by2' `2' +end + +program define Gphcross /* cross X */ /* FW */ +* Gphcross yposition xposition bar_height +* 1.0.1 NJC 18 February 1999 +* 1.0.0 NJC 6 October 1997 + version 6.0 + loc Xy1 = `1' - 0.5 * `3' + loc Xy2 = `1' + 0.5 * `3' + loc Xx1 = `2' - 0.5 * `3' + loc Xx2 = `2' + 0.5 * `3' + gph line `Xy1' `Xx1' `Xy2' `Xx2' + gph line `Xy2' `Xx1' `Xy1' `Xx2' +end + +program def Markout2 /* marks out obs with all missing values */ +* 1.0.2 NJC 16 February 1999 +* 1.0.1 NJC 25 March 1998 + version 6.0 + syntax varlist(min=1) [, Strok ] + tokenize `varlist' + loc nvars : word count `varlist' + if `nvars' == 1 { exit 0 } + loc nvars = `nvars' - 1 + loc markvar `1' + mac shift + tempvar nmiss + gen `nmiss' = 0 + qui { + while "`1'" != "" { + loc type : type `1' + if substr("`type'",1,3) == "str" { + if "`strok'" != "" { + replace `nmiss' = `nmiss' + (`1' == "") + } + else replace `nmiss' = `nmiss' + 1 + } + else replace `nmiss' = `nmiss' + (`1' == .) + mac shift + } + replace `nmiss' = `nmiss' == `nvars' + replace `markvar' = 0 if `nmiss' + } +end + +program def Gphtrans, rclass /* transliterate ".OSTodp" -> "0123456" */ +* 1.0.2 NJC 1 March 1999 +* 1.0.0 NJC 31 March 1998 + version 6.0 + args argin + loc length = length("`argin'") + + loc i 1 + while `i' <= `length' { + loc s = substr("`argin'", `i', 1) + if "`s'" == "." { loc s 0 } + else if "`s'" == "O" { loc s 1 } + else if "`s'" == "S" { loc s 2 } + else if "`s'" == "T" { loc s 3 } + else if "`s'" == "o" { loc s 4 } + else if "`s'" == "d" { loc s 5 } + else if "`s'" == "p" { loc s 6 } + loc argout "`argout'`s'" + loc i = `i' + 1 + } + + return loc symbol `argout' +end + +program def Gphpt +* 1.2.2 NJC 24 February 1999 smaller big cross, bigger , +* 1.2.1 NJC 18 February 1999 +* 1.2.0 NJC 12 Jan 1999 +* 1.1.0 NJC 24 Sept 1998 +* 1.0.0 NJC 6 April 1998 + version 6.0 + args sy y x barht ptsize + + if "`sy'" == "|" { Gphbar `y' `x' `barht' } + else if "`sy'" == "," { Gphbar `y' `x' 0.6*`barht' } + else if "`sy'" == "X" { Gphcross `y' `x' 0.707*`barht' } + else if "`sy'" == "x" { Gphcross `y' `x' 0.5*`barht' } + else if "`sy'" == "-" { Gphhbar `y' `x' 0.5*`barht' } + else gph point `y' `x' `ptsize' `sy' +end + +program define Gphhbar /* horizontal bar */ +* Gphhbar yposition xposition bar_length +* 1.0.1 NJC 18 February 1999 +* 1.0.0 NJC 24 Sept 1998 + version 6.0 + loc bx1 = `2' - 0.5 * `3' + loc bx2 = `2' + 0.5 * `3' + gph line `1' `bx1' `1' `bx2' +end diff --git a/Modules/ado/plus/h/hplot.hlp b/Modules/ado/plus/h/hplot.hlp new file mode 100644 index 0000000..b51c01c --- /dev/null +++ b/Modules/ado/plus/h/hplot.hlp @@ -0,0 +1,307 @@ +.- +help for ^hplot^ +.- + +Horizontally labelled plots +--------------------------- + + ^hplot^ varlist [^if^ exp] [^in^ range] [ ^,^ + + ^a^xtol^(^#^) c^start^(^#^) gapm^ag^(^#^) gap^s^(^string^)^ + ^g^rid ^li^ne ^pts^ize ^r^ange ^so^rt^(^string^)^ + ^s^ymbol^(^string^)^ + + ^bo^rder ^f^ormat^(^format^) lap nox^axis ^noy^axis ^tti^ck + ^xla^bel^(^string^) xli^ne^(^string^) xsc^ale^(^string^)^ + ^xti^ck^(^string^)^ + + ^b^lank ^gl^egend^(^string^) gllj glpos(^#^) l^egend^(^legendvar^)^ + + ^flipt nit2 t1m(^#^) t1^title^(^string^) t2m(^#^)^ + ^t2^title^(^string^) tim(^#^) ti^tle^(^string^)^ + + ^fontr(^#^) fontc(^#^) fontrb(^#^) fontcb(^#^)^ + ^pe^n^(^string^) pent^ext^(^#^) sa^ving^(^graph_filename^)^ ] + +Description +----------- + +The basic form of ^hplot^ is a graph with one horizontal line for each +observation included. On that line are one or more point symbols +representing the values in varlist according to a common scale. + +^hplot^ can produce a variety of horizontally labelled plots for data, +including W.S. Cleveland's dot charts or dot plots; variations on them +with continuous rather than dotted lines; D.R. McNeil's horizontal +parallel line plots; and displays for showing key quantities with or +without confidence intervals. + +By default, the data in varlist are represented on horizontal dotted +lines with base at zero that extend to the maximum for each observation. +If negative values are present, dotted lines also extend to the minimum. +Point symbols are used to show actual values. + +If the ^grid^ option is used, the data are represented on horizontal +dotted lines that extend over the whole data region of the graph. + +If the ^line^ option is used, the data are represented on horizontal +continuous lines with base at the left-hand margin. This can be a lot +faster and may be adequate for exploratory analyses. + +If the ^range^ option is used, the data are represented on horizontal +dotted or continuous lines which extend only over the range of values +for each observation, from the smallest value to the largest value. + +If the data allow it, a different base may be forced using the ^xscale^ +option. + +A legend on the left of the data region can be from a specified +variable. If that variable is not specified, the order in the data will +be used; or, if that is not desired, the legend can be blank. The legend +is right-justified. The legend should look readable up to about 30 +observations. + +For understanding placement of material on the plot, it helps to know +that @gph@ draws in a space defined by 23063 rows and 32000 columns +with origin at top left. See help for @gph@. + + +Options +-------- + +Options controlling size, layout and symbol presentation: +--------------------------------------------------------- + +^axtol(^#^)^ controls the space between the x axis or the position of + the top border and the nearest data line. Default 600. + +^cstart(^#^)^ controls the column (horizontal position) of the start of + the lines. + +^gapmag(^#^)^ controls the magnitude of any gaps relative to the spacing + between lines. Default 1. + +^gaps(^string^)^ places gaps after lines. ^gaps(3,6)^ places gaps after + the 3rd and 6th lines as they appear on the graph, counting down + from the top. ^0^ means a gap before the first line. + +^grid^ places point symbols on horizontal dotted grid or guide lines + that extend all the way across the plot. This was originally + recommended by Cleveland if the base is not 0, and later used by him + in all examples. + +^sort(^string^)^ means that observations are to be plotted in the + vertical order determined by application of @gsort@. For example, + ^sort(^sortvar^)^ indicates sort in ascending order of sortvar + (highest values on bottom) and ^sort(- ^sortvar^)^ indicates + descending order (highest values on top). + +^line^ replaces dotted by continuous horizontal lines from the left-hand + margin to each data point. + +^ptsize(^#^)^ controls point symbol size. Default 275. + +^range^ restricts the dotted or continuous lines to extend from the + minimum to the maximum of those quantities plotted on each + horizontal line. + +^symbol(^#^)^ controls point symbols available. The list is most of the + standard list for @graph@, with some additions. + ^.^ dot + ^o^ small circle + ^O^ large circle + ^S^ square + ^T^ triangle + ^d^ diamond + ^p^ plus + ^i^ invisible + ^|^ vertical bar + ^,^ short vertical bar + ^-^ short horizontal bar + ^>^ arrow pointing right + ^<^ arrow pointing left + ^x^ small cross + ^X^ large cross + ^a^ arrow pointing from the value for the previous variable + to the value of the present variable + + ^symbol^ defaults to ^opSdT^ for up to 5 variables and ^o^ for every + variable for 6 or more variables. With 2 or more variables and a + single symbol specified, that symbol is used for every variable. + That is, ^hplot a b c, sy(|)^ expands to ^hplot a b c, sy(|||)^. + +Options controlling axes, lines, labels, ticks, border: +------------------------------------------------------- + +^border^ adds a border. + +^format(^format^)^ controls the format with which ^xlabel^s are shown. + Default %1.0f. + +^lap^ (^l^abels ^a^ll ^p^ositive) makes the labels as shown all + positive. ^xla(-40,-20,0,20,40) lap^ will place the labels + 40, 20, 0, 20, 40 at the axis positions for -40, -20, 0, 20, 40. + +^noxaxis^ suppresses the x axis. + +^noyaxis^ suppresses the y axis. + +^ttick^ produces short unlabelled ticks on the border above the x axis + that echo the labelled and unlabelled ticks on the x axis. Note that + (unlike the option in @graph@) ^ttick^ with a string is illegal, and + that ^ttick^ necessarily implies ^border^, but not conversely. + +^xlabel(^string^)^ controls the labelled ticks on the x axis. Note that + (unlike the option in @graph@) ^xlabel^ without a string is illegal. + numlists may be used, such as ^1/5^ for ^1,2,3,4,5^ and ^0(10)50^ + for ^0,10,20,30,40,50^. + +^xline(^string^)^ specifies lines drawn for constant values of x. Note + that (unlike the option in @graph@) ^xline^ without a string is + illegal. numlists may be used, such as ^1/5^ for ^1,2,3,4,5^ and + ^0(10)50^ for ^0,10,20,30,40,50^. + +^xscale(^string^)^ controls the scale of the graph, except that (like + the option in @graph@) it will not cause values to be omitted (for + which purpose use ^if^). + +^xtick(^string^)^ controls the unlabelled ticks on the x axis. Note that + (unlike the option in @graph@) ^xtick^ without a string is illegal. + numlists may be used, such as ^1/5^ for ^1,2,3,4,5^ and ^0(10)50^ + for ^0,10,20,30,40,50^. + +Options controlling legends to left and between gaps: +----------------------------------------------------- + +^blank^ blanks out any legend on the left of the data region. + +^glegend(^string^)^ places right-justified legend in the gaps between + lines. ^gaps(0,4) glegend(Males!Females)^ places ^Males^ in the gap + before line 1 and ^Females^ in the gap after line 4. Note that ^!^ + must be used to separate legends, which thus enables the use of + commas within the legend, but has the side-effect of disallowing the + use of exclamation marks. ^.^ has the special meaning of blank. + +^gllj^ makes ^glegend^ left-justified. + +^glpos(^#^)^ controls the horizontal position of ^glegend^ and defaults + to an alignment with the main legend. + +^legend(^legendvar^)^ specifies a variable to be used for the legend. If + legendvar is a numeric variable with labels, the labels will be used + in the legend. + +Options controlling titles (^t1title^, ^t2title^, ^title^): +----------------------------------------------------- + +^flipt^ flips titles: ^title^ will be shown at its (default larger) font + size and left-justified at the top of the graph, and ^t1title^ will + be shown at default font size and centred below the axis at the + bottom of the graph (but closer to the axis than the default). + +^nit2^: see ^t2title^ below. + +^t1title(^string^)^ controls the ^t1title^, shown at default font size + and left-justified at the top of the graph. But see ^flipt^ above. + +^t2m(^#^)^ moves the ^t2title^ bodily # to the right. The default is to + start hard left to allow plenty of space for several variable labels + or names in a key, but that default may seem too far left. + +^t2title(^string^)^ controls the ^t2title^, shown at default font size + and left-justified at the top of the graph. This defaults to a key + of point symbols if the number of variables is more than 2: the key, + however, is likely to be a mess if the number is more than 5. The + key uses variable labels, or variable names if either they do not + exist or the further option ^nit2^ is invoked. As with @graph@, + ^" "^ blanks out the title. + +^tim(^#^)^ moves the ^title^ bodily # to the right. The default is to + centre at whatever column would bisect the x axis. + +^title(^string^)^ controls the ^title^, shown at its (default larger) + font size and centred below the axis at the bottom of the graph. But + see ^flipt^ above. As with @graph@, ^" "^ blanks out the title. + +Other graph options: +-------------------- + +^fontr(^#^)^ and ^fontc(^#^)^ control the font used for all but the main + title and default to 570 and 290 (which is the default of @gph@). + Font sizes should be changed circumspectly. + +^fontrb(^#^)^ and ^fontcb(^#^)^ control the font used for the main + title and default to 923 and 444. + +^pen(^string^)^ controls the pens used for data. ^pen^ defaults to ^2^ + for every variable. With 2 or more variables and a single pen + specified, that pen is used for every variable. That is, + ^hplot a b c, pen(3)^ expands to ^hplot a b c, pen(333)^. + +^pentext(^#^)^ controls the pen used for text and other non-data + elements. + +^saving(^graph_filename^)^ saves the graph in a .gph file. + + +Examples +-------- + + . ^hplot reserves, l(area) xsc(0,30) xla(0(5)30)^ + ^t1(percent of total) ti(Oil reserves 1994) flipt border^ + + . ^hplot area, l(name) xsc(0,6) xla(0/6) t1(million^ + ^square km) ti(Areas of major drainage basins) flipt line^ + ^fontr(491) fontc(250)^ + + . ^hplot lcl mean ucl, l(name) xsc(0,6) xla(0/6)^ + ^t1(95% confidence intervals) sy(|O|) border^ + + +Remarks +------- + +In addition to the options above, many choices are coded into ^hplot^ +as parameter values. Users may want to copy ^hplot^ and then edit +these permanently or temporarily according to taste. + +Cleveland's dot plots are not the same as the histogram-like dotplots +implemented in @dotplot@. + + +References +---------- + +Cleveland, W.S. 1984. Graphical methods for data presentation: full +scale breaks, dot charts, and multibased logging. American Statistician +38, 270-80. + +Cleveland, W.S. 1994. The elements of graphing data. Hobart Press, +Summit, NJ. + +McNeil, D.R. 1992. On graphing paired data. American Statistician +46, 307-11. + +McNeil, D.R. 1996. Epidemiological research methods. Wiley, Chichester. + + +Author +------ + Nicholas J. Cox, University of Durham, U.K. + n.j.cox@@durham.ac.uk + + +Acknowledgments +--------------- + + Mike Bradburn, Arne Kolstad and Fred Wolfe made very helpful + comments. + + +Also see +-------- + +On-line: help for @graph@, @gph@, @format@, @gsort@, @dotplot@, + @hbar@ (if installed), @cihplot@ (if installed), + @tabhplot@ (if installed), @numlist@ + diff --git a/Modules/ado/plus/i/i2ci.ado b/Modules/ado/plus/i/i2ci.ado new file mode 100644 index 0000000..573ee90 --- /dev/null +++ b/Modules/ado/plus/i/i2ci.ado @@ -0,0 +1,31 @@ +*! Author: Ross Harris +*! Date: 1 August 2008 + +* Confidence interval for I-sq, to be run after metan + +version 8.0 +program i2ci + +local k = r(df)+1 +local q = r(het) + +if `q' > `k'{ + local selogH = 0.5 * ( ln(`q') - ln(`k'-1) ) / ( sqrt(2*`q') - sqrt(2*`k'-3) ) +} +else{ + local selogH = sqrt( (1/(2*(`k'-2))) * (1- (1/(3*(`k'-2)^2))) ) +} + +local H = sqrt(`q'/(`k'-1)) +local Hlow = exp(ln(`H')-1.96*`selogH') +local Hupp = exp(ln(`H')+1.96*`selogH') + +local I2 = string( r(i_sq) , "%5.1f") +local I2low = string( max( 100* ( (`Hlow'^2-1) / `Hlow'^2 ) , 0) , "%5.1f") +local I2upp = string( max( 100* ( (`Hupp'^2-1) / `Hupp'^2 ) , 0) , "%5.1f") + +di in ye "I-sq= `I2'%, 95% CI: `I2low'% to `I2upp'%" +di in whi "CI based on Higgins & Thompson, Statist. Med. 2002; 21:1539–1558, +di in whi "Appendix A2: Intervals based on the statistical significance of Q." + +end diff --git a/Modules/ado/plus/i/icc23.ado b/Modules/ado/plus/i/icc23.ado new file mode 100644 index 0000000..f392733 --- /dev/null +++ b/Modules/ado/plus/i/icc23.ado @@ -0,0 +1,146 @@ +*! version 17feb09 + +program define icc23, rclass + version 9 + syntax varlist(min=3 max=3) [if] [, MOdel(integer 2) LEvel(real .95)] + tokenize "`varlist'" + marksample touse + + local dv `1' + local rater `2' + local id `3' + + capture assert `model'==2 |`model'==3 + if _rc~=0 { + di + di in re "The ICC model must be specified as either 2 or 3" + exit 198 + } + + capture assert `level'>0 & `level'<1.0 + if _rc~=0 { + di + di in re "The CI level must be a value between 0 and 1.0" + exit 198 + } + + qui anova `dv' `rater' `id' `if', repeated(`rater') + + local f1 e(F_1) + local ss2 e(ss_2) + local df2 e(df_2) + local rss e(rss) + local dfr e(df_r) + local df1 e(df_1) + local ss1 e(ss_1) + local n e(N_bse) /* the number of subjects tested */ + local k = `df1'+1 /* the number of raters */ + +*Compute F-test for rater + local p_rater=Ftail(`df1',`dfr',`f1') + +*Compute components of ICC + + local bms = `ss2'/`df2' + local ems = `rss'/`dfr' + local jms = `ss1'/`df1' + local Fj = `jms'/`ems' + local alpha2 =1-((1-`level')/2) + local cilevel = `level'*100 + + + if `model' == 2 { + + *Compute ICC Model 2 for single observations (ICC21) and for means (ICC2k) + + local num21 = `bms'-`ems' + local dentmp = (`k'*(`jms'-`ems'))/`n' /* the ratio within the denominator */ + local den21 = `bms'+(`k'-1)*`ems'+`dentmp' + local icc21 = `num21'/`den21' + + *Compute ICC21 confidence intervals (values will be used for ICC2k confidence intervals) + + local nu_num21 = (`k'-1)*(`n'-1)*(`k'*`icc21'*`Fj'+`n'*(1+(`k'-1)*`icc21')-`k'*`icc21')^2 + local nu_den21 = (`n'-1)*(`k'^2)*((`icc21')^2)*((`Fj')^2)+(`n'*(1+(`k'-1)*`icc21')-`k'*`icc21')^2 + local nu21 = `nu_num21'/`nu_den21' + local Fsuper = invF(`df2',`nu21',`alpha2') + local Fsub = invF(`nu21',`df2',`alpha2') + local cilower = (`n'*(`bms'-`Fsuper'*`ems'))/(`Fsuper'*(`k'*`jms'+(`k'*`n'-`k'-`n')*`ems')+`n'*`bms') + local ciupper = (`n'*(`Fsub'*`bms'-`ems'))/(`k'*`jms'+(`k'*`n'-`k'-`n')*`ems'+`n'*`Fsub'*`bms') + + *Compute ICC2k and its confidence intervals + local num2k = `bms'-`ems' + local dentmp1 = (`jms'-`ems')/`n' /* the ratio within the denominator */ + local den2k = `bms'+`dentmp1' + local icc2k = `num2k'/`den2k' + local cilowerK = (`k'*`cilower')/(1+(`k'-1)*`cilower') + local ciupperK = (`k'*`ciupper')/(1+(`k'-1)*`ciupper') + + di + di in gr " **************************************************************************" + di in ye " Two-Way Random Effects Models: ICC[2,1] and ICC[2,k]" + di in gr " **************************************************************************" + di + di in gr " The total number of subjects is: " in ye %3.0f `n' + di in gr " The total number of raters is: " in ye %3.0f `k' + di + di in gr " Reliability of observations: ICC[2,1] = " in ye %4.3f `icc21' ", (" `cilevel' "% CI: " %5.3f `cilower' ", " %5.3f `ciupper' ")" + di + di in gr " Reliability of the mean: ICC[2,`k'] = " in ye %4.3f `icc2k' ", (" `cilevel' "% CI: " %5.3f `cilowerK' ", " %5.3f `ciupperK' ")" + di + di in gr " **************************************************************************" + di + if `p_rater' <= .05 { + di in red " Note: There is a significant `rater' effect: p = " %5.4f `p_rater' + } + } + + if `model' == 3 { + + * Compute ICC31 + + local num31 = `bms'-`ems' + local den31 = `bms'+(`k'-1)*`ems' + local icc31 = `num31'/`den31' + + *Compute ICC Model 3 Confidence Interval (Single Observations) + + local fzero = `bms'/`ems' + local fdistL = invF(`n'-1,(`n'-1)*(`k'-1),`alpha2') + local fdistU = invF((`n'-1)*(`k'-1),`n'-1,`alpha2') + local FL = `fzero'/`fdistL' + local FU = `fzero'*`fdistU' + local cilower = (`FL'-1)/(`FL'+(`k'-1)) + local ciupper = (`FU'-1)/(`FU'+(`k'-1)) + + *Compute ICC3k + + local num3k = `bms'-`ems' + local den3k = `bms' + local icc3k = `num3k'/`den3k' + + *Compute ICC3k confidence intervals + + local cilowerK = 1-(1/`FL') + local ciupperK = 1-(1/`FU') + + di + di in gr " **************************************************************************" + di in ye " Two-Way Mixed Effects Models: ICC[3,1] and ICC[3,k]" + di in gr " **************************************************************************" + di + di in gr " The total number of subjects is: " in ye %3.0f `n' + di in gr " The total number of raters is: " in ye %3.0f `k' + di + di in gr " Reliability of observations: ICC[3,1] = " in ye %4.3f `icc31' ", (" `cilevel' "% CI: " %5.3f `cilower' ", " %5.3f `ciupper' ")" + di + di in gr " Reliability of the mean: ICC[3,`k'] = " in ye %4.3f `icc3k' ", (" `cilevel' "% CI: " %5.3f `cilowerK' ", " %5.3f `ciupperK' ")" + di + di in gr " **************************************************************************" + di + + if `p_rater' <= .05 { + di in red " Note: There is a significant `rater' effect: p = " %5.4f `p_rater' + } + } +end diff --git a/Modules/ado/plus/i/icc23.hlp b/Modules/ado/plus/i/icc23.hlp new file mode 100644 index 0000000..3fd6679 --- /dev/null +++ b/Modules/ado/plus/i/icc23.hlp @@ -0,0 +1,110 @@ + +.- +help for ^icc23^ +.- + +^Calculation of ICC Models 2 and 3^ +^---------------------------------^ + + .^icc23^ , MOdel(#) LEvel(#) + + +^Description^ +^-----------^ + +^icc23^ computes the intra-class correlation for random effects models based on repeated +measures ANOVA. These models are ICC[2,1], ICC[2,k], ICC[3,1], and ICC[3,k], as described +by Shrout and Fleiss, 1979 (see reference below). (For the ICC[1,1] and ICC[1,k] models +based on a one-way ANOVA, see @loneway@). ^icc23^ runs a repeated measures ANOVA to derive +the appropriate estimates and degrees of freedom. In the event there is a significant F-test +for the ^classvar^ (e.g., a significant differernce among raters), the program will provide +the p-value from the ANOVA table. + +Data must be in the "long" format. If not, use the @reshape@ command to reconfigure the data. + +Four types of ICC models are considered: + + ICC[2,1]: reflects the case where the same group of subjects is rated by k raters, + interest is in the reliability of individual scores. In this model, raters + are considered a representative sample of a population of similar raters. This + model is a two-way random effects model. + + ICC[2,k]: is the same approach as ICC[2,1] above, but interest is in the reliability + of the MEAN score, rather than among single observations. + + ICC[3,1]: reflects the case where the same group of subjects is rated by k raters, + interest is in the reliability of individual scores. In this model, the only + raters of interest are those participating in the study (e.g., there is no + intention of generalizing the raters' scores to a larger population of raters). + This model is considered a "mixed" model (subjects are random, raters are fixed). + + ICC[3,k]: is the same approach as ICC[3,1] above, but interest is in the reliability + of the MEAN score, rather than among single observations. + +Three inputs are required: + + dv is the dependent variable + + classvar the class variable refers to factor that is repeated within subjects, e.g., raters, + devices, time points, etc., e.g., the variable which would be entered as the + repeated() variable in the ANOVA option. + + within_var refers to the "within subject" variable, e.g., subjects being assessed + + +^NOTE: The order of entry of the variables is critical!^ + + + +^Options^ +^-------^ + ^MO^del(#) refers to the type of model to be estimated. ICC model 2 is the default ( + producing ICC[2,1] and ICC[2,k] estimates). + + ^LE^vel(#) the degree of precision of the confidence interval, entered as a decimal. + The default is 95%, i.e., level(.95) + + +Examples +-------- + +For ICC[2,1] and ICC[2,k]: Two-way random effects (Subjects and raters are considered to be + sampled from larger populations); 95% CIs are assumed. + +^.icc23 score rater person_id^ + + + +For ICC[3,1] and ICC[3,k]: Two-way mixed model: Subjects are random, but raters are fixed + (i.e., the raters are not considered a sample -- they are the + only raters of interest); 90% CIs are requested. + +^.icc23 score rater person_id, model(3) level(.90)^ + + +References +---------- +Shrout PE, FLeiss JL. Intraclass correlation: uses in assessing rater reliability. Psychol +Bull, 1979; 86: 420-428. + +Portney LG, Watkins MP. Foundations of Clinical Research: Applications to Practice (2nd ed.). +Prentice-Hall, Inc: Upper Saddle River, NJ., 2000. + + +Author +------ +Paul F. Visintainer, PhD +Baystate Health System +Springfield, MA 01089 +visint46@gmail.com + +Luis C.Orozco, MD, MSc +Facultad de Salud +Universidad Industrial de Santander +Colombia +lcorovar@gmail.com + + +Also see +-------- +Manual or on-line help for: @loneway@, @reshape@, @iclassr@, @iclassr2@ diff --git a/Modules/ado/plus/i/iccconf.ado b/Modules/ado/plus/i/iccconf.ado new file mode 100644 index 0000000..163c41f --- /dev/null +++ b/Modules/ado/plus/i/iccconf.ado @@ -0,0 +1,55 @@ +*! November 5, 2008 by Paul F. Visintainer, PhD + +program define iccconf +version 8.0 +syntax anything [, level(real .95)] +tokenize "`anything'" + +local icc `1' +local k `2' /* number of observations */ +local reps `3' + + +confirm number `icc' +confirm integer number `k' +confirm integer number `reps' + +if `icc'<=0 | `icc'>=1 { + di + di in red "RE-enter " in ye "ICC" in red " between 0 and 1" + error 197 + } + +if `level' >=1.0 { + di + di in red " Confidence level must be between 0 and 1" + error 197 + } + +* Defining the components of the test +local alpha = 1 - `level' +local N = `k'*`reps' +local df1 = `k' - 1 +local df2 = `N' - `k' +local F = ((`icc'*`reps') - `icc' + 1)/(1-`icc') +local lFcrit = invF(`df1',`df2',(1-`alpha'/2)) +local uFcrit = invF(`df1',`df2',(`alpha'/2)) + +*Compute confidence limits based on Rosner, "Fundamental of Bios, 6th", pg. 615 + +local ul = (`F'/`uFcrit'-1)/(`reps'+(`F'/`uFcrit')-1) +local ll = (`F'/`lFcrit'-1)/(`reps'+(`F'/`lFcrit')-1) + + +di +di in gr " ******************************************************************************* " +di in ye " Confidence Interval for the INTRACLASS COEFFICIENT " +di in gr " ******************************************************************************* " +di +di in gr " The ICC with " in ye %3.0f `level'*100 "% " in gr "CI is: " %3.2f in ye `icc' " (" %3.2f in ye `ll' ", " %3.2f in ye `ul' ")" +di +di in gr " The number of subjects is: " %5.0f in ye `k' +di +di in gr " The number of repeated assessments is: " %2.0f in ye `reps' + +end diff --git a/Modules/ado/plus/i/iccconf.hlp b/Modules/ado/plus/i/iccconf.hlp new file mode 100644 index 0000000..7174e67 --- /dev/null +++ b/Modules/ado/plus/i/iccconf.hlp @@ -0,0 +1,62 @@ + +.- +help for ^iccconf^ +.- + +Confidence Interval for A Single Intraclass Correlation (ICC) +------------------------------------------------------------- + + .^iccconf , level(#)^ + + +^Description^ +^-----------^ + +^iccconf^ is an immediate command that computes a confidence interval for a +single intraclass correlation (ICC). The procedure is based on Rosner's approach +using the F-test. + +Three inputs are required: + + ^icc^ is the intraclass correlation. The input must be a value between 0 and 1 + + ^k^ is the number of subjects + + ^reps^ is the number of repeated assessments or "within" pair + measurements. + +^Option^ +^------^ + level(#) The level option allows the user to modify the confidence limit. + Use values between 0 and 1. The default is .95. + + +Example +-------- +To find a 95% confidence interval for an ICC of .914, based on 5 observations +with 2 replcations each: + + ^.iccconf .914 5 2^ + + +For a 90% confidence interval for the above example, type: + + ^.iccconf .914 5 2, level(.9)^ + + +References +---------- +Rosner, B. "Fundamentals of Biostatistics, 6th ed" Duxbury, Press (The Thompson + Company): Belmont, CA, 2006, pgs 615-616. + + +Author +------ +Paul F. Visintainer, PhD +Springfield, MA 01089 +visint46@gmail.com + + +Also see +-------- +Manual or on-line help for: @loneway@, @xtreg@, or ^bootcor^, ^xtrho^ if installed diff --git a/Modules/ado/plus/i/ice.ado b/Modules/ado/plus/i/ice.ado new file mode 100644 index 0000000..3b38ecf --- /dev/null +++ b/Modules/ado/plus/i/ice.ado @@ -0,0 +1,905 @@ +*! version 1.1.1 PR 23sep2005. +* +* History of ice +* 1.1.1 23sep2005 Better error trapping for passive() and substitute() options. +* 1.1.0 23aug2005 Replace -draw- option with -match-. Default becomes draw. +* Trace option documented, now has argument for filename. +* Report number of rows with 0, 1, 2, ... missing values. +* Arrange variables in increasing order of missingness when imputing. +* Split ties at random when more than one observation satisfies the +* prediction matching criterion +* 1.0.4 21jul2005 Trap and report error when running uvis +* 1.0.3 08jun2005 Tidy up display of equations when have multiple lines (long equations) +* 1.0.3 03jun2005 Silence file load/save +* 1.0.2 20may2005 Changed files containing imputations to tempfiles (standalone mode) +* (Angela Wood reported problem). +* 1.0.1 04may2005 Added a trace to a file (undocumented in help file). +* 1.0.0 18apr2005 First release, based on mice. +* +* History of mice +* 1.0.3 13apr2005 Minor tidying up, including recode of ChkIn and deletion of strdel. +* Check if prediction equations have a variable on both sides. +* 1.0.2 17feb2005 Added code to take care of inherited missingness of passive variables robustly. +* 1.0.1 21jan2005 Added display of regression command in showing prediction equations. +* 1.0.0 20jan2005 First release, based on mvis2/_mvis2. +* +* History of mvis +* 1.1.0 18jan2005 categoric() option removed. +* New options dryrun, passive(), substitute(), eq() added. +* Improvements to output showing actual prediction equations. +* 1.0.5 19nov2004 Delete dummy variables for categoric() variables with no missing data from output file +* Found problem with bsample in Stata 7 with "if" clause and boot option. +* Revert to Stata 8 for mvis, _mvis and uvis. +* 1.0.4 18nov2004 Weights not working (syntax error), fixed. +* 1.0.3 16nov2004 Categoric() option added to deal with unordered categoric +* covariates, updated default handling of such variables +* 1.0.2 16oct2004 Saving, using etc of file safest with compound quotes, fixed. +* +program define ice, rclass +version 8 +* Check for _I* variables, could be created by xi: +capture describe _I* +if _rc==0 { + di as err _n "Warning: _I* variables detected in the dataset - was xi: used?" + di as inp "Use of xi: with mvis is liable to give incorrect results." + di as inp "If you wish to model categoric covariates with dummy" + di as inp "variables, please recalculate the dummies via the passive() option" + di as inp "and use the substitute() option to identify the dummies as predictors." _n +} +local m `s(MI_m)' +if "`m'"!="" { + * Called by mi_impute + local mitools mitools + local mopt + local uopt + local fn0 `s(MI_tfile)' + local using `fn0' + forvalues i=1/`m' { + local fn`i' `s(MI_tfile`i')' + } +} +else { + * standalone + local mitools + local mopt "m(int 1)" + local uopt [using/] +} + +syntax varlist(min=2 numeric) [if] [in] [aweight fweight pweight iweight] `uopt', /* + */ [ `mopt' REPLACE Seed(int 0) BOot MAtch DRYrun * ] + +* Check if there are variables called boot and/or match +if "`boot'"=="boot" { + cap confirm var boot + if _rc local options `options' boot(`varlist') + else local options `options' boot(boot) +} +if "`match'"=="match" { + cap confirm var match + if _rc local options `options' match(`varlist') + else local options `options' match(match) +} +if `seed'>0 set seed `seed' +local first first +if "`dryrun'"!="" { + if `"`using'"'=="" { + tempname fn + local using `fn' + } + _ice `varlist' `if' `in' [`weight' `exp'] using `using', `options' first dryrun + di as text _n "End of dry run. No imputations were done, no files were created." + exit +} +preserve +if "`mitools'"=="" { + if `m'<1 { + di as err "number of imputations must be 1 or more" + exit 198 + } + if `"`using'"'=="" { + if "`dryrun'"=="" { + di as err "using required" + exit 100 + } + } + else { + if substr(`"`using'"',-4,.)!=".dta" { + local using `using'.dta + } + if "`replace'"=="" { + confirm new file `"`using'"' + } + } + forvalues i=1/`m' { + tempfile fn`i' + _ice `varlist' `if' `in' [`weight' `exp'] using `fn`i'', `options' `first' + di as text `i' ".." _cont + local first + } + * Join files of imputations vertically using code from mijoin.ado + quietly { + local J _j + forvalues j=1/`m' { + * could automate this part + use `"`fn`j''"', clear + chkrowid + local I `s(I)' + if "`I'"=="" { + * create row number + local I _i + cap drop `I' + gen long `I'=_n + lab var `I' "obs. number" + } + cap drop `J' + gen int `J'=`j' + lab var `J' "imputation number" + save `"`fn`j''"', replace + } + use `"`fn1'"', clear + forvalues j=2/`m' { + append using `"`fn`j''"' + } + char _dta[mi_id] `I' + } + save `"`using'"', `replace' +} +else { + * Save original data and imputations to tempfiles for mi_impute to stack + * fn0,...,fn`m' are local macros created by mi_impute and supplied as s() functions; + * they contain the actual names of tempfiles, hence the need for compound quotes. + local original original + forvalues i=0/`m' { + if "`replace'"!="" cap drop `"`fn`i''"' // !! bug - should be erase not cap drop? + _ice `varlist' `if' `in' [`weight' `exp'] using `"`fn`i''"', /// + `options' `first' `original' mitools + di as text `i' ".." _cont + local original + if `m'>0 local first + } +} +end + +program define chkrowid, sclass +version 8 +local I: char _dta[mi_id] +if "`I'"=="" exit +cap confirm var `I' +if _rc exit +sret local I `I' +end + +*! Based on _mvis2 version 1.0.2 PR 19jan2005. +program define _ice, rclass +version 8 +syntax varlist(min=2 numeric) [if] [in] [aw fw pw iw] using/, /* + */ [ BOot(varlist) CC(varlist) CMd(string) CYcles(int 10) noCONStant MAtch(varlist) /* + */ DRYrun EQ(string) first Genmiss(string) Id(string) mitools ON(varlist) original /* + */ PASsive(string) noSHoweq SUBstitute(string) TRace(string) ] + +if "`original'"!="" { + * Save original data + quietly save `"`using'"', replace + exit +} + +local nvar: word count `varlist' +if "`id'"!="" { + confirm new var `id' +} +else local id _i + +preserve +tempvar touse order +quietly { + marksample touse, novarlist + if "`cc'`on'"!="" { + markout `touse' `cc' `on' + } + +* Record sort order + gen long `order'=_n + lab var `order' "obs. number" + +* For standard operation (no `on' list), disregard any completely missing rows in varlist, among marked obs + if "`on'"=="" { + tempvar rmis + egen int `rmis'=rmiss(`varlist') if `touse'==1 + count if `rmis'==0 + replace `touse'=0 if `rmis'==`nvar' + replace `rmis'=. if `rmis'==`nvar' + lab var `rmis' "#missing values" + if "`first'"!="" & "`showeq'"=="" noi tab `rmis', missing + drop `rmis' + } +* Deal with weights + frac_wgt `"`exp'"' `touse' `"`weight'"' + local wgt `r(wgt)' + +* Sort out cmds (not checking if each cmd is valid - any garbage may be entered) + if "`cmd'"!="" { + * local cmds "regress logistic logit ologit mlogit" + detangle "`cmd'" cmd "`varlist'" + forvalues i=1/`nvar' { + if "${S_`i'}"!="" { + local cmd`i' ${S_`i'} + } + } + } + +* Default for all uvis operations is nomatch, meaning draw + if "`match'"!="" { + tokenize `match' + while "`1'"!="" { + ChkIn `1' "`varlist'" + if `s(k)'>0 { + local match`s(k)' match + } + mac shift + } + } + + if "`boot'"!="" { + tokenize `boot' + while "`1'"!="" { + ChkIn `1' "`varlist'" + if `s(k)'>0 { + local boot`s(k)' boot + } + mac shift + } + } + local anyerr 0 + if `"`passive'"'!="" { + tempvar passmiss + /* + Defines vars that are functions or transformations of others in varlist. + They are (may be) "passively imputed". "\" is an expression separator. + Default is comma. + Comma may not always be appropriate (i.e. may appear in an expression). + */ + detangle "`passive'" passive "`varlist'" \ + local haserr 0 + forvalues i=1/`nvar' { + if "${S_`i'}"!="" { + local exp`i' ${S_`i'} + ParsExp `exp`i'' + local exclude `s(result)' + if "`exclude'"!="" { + * Count missingness of this passive variable + egen int `passmiss'=rmiss(`exclude') if `touse' + count if `passmiss'>0 & `touse'==1 + local nimp`i'=r(N) + if `nimp`i''==0 { + local v: word `i' of `varlist' + noi di as err "passive definition `v' = (${S_`i'}) redundant: `exclude' has no missing data." + local ++haserr + } + drop `passmiss' + } + } + } + if `haserr'>0 { + di as err "`haserr' error(s) found in option " as inp "passive(`passive')" + local anyerr 1 + } + } + if "`substitute'"!="" { + * defines vars that are to be substituted in the recalc context + detangle "`substitute'" substitute "`varlist'" + local haserr 0 + forvalues i=1/`nvar' { + if "${S_`i'}"!="" { + local sub`i' ${S_`i'} + local v: word `i' of `varlist' + count if missing(`v') & `touse'==1 + if r(N)==0 { + noi di as err "substitute for variable `v' redundant: `v' has no missing data." + local ++haserr + } + } + } + if `haserr'>0 { + noi di as err "`haserr' error(s) found in option " as inp "substitute(`substitute')" + local anyerr 1 + } + } + if `"`eq'"'!="" { + * defines equations specified vars. + detangle "`eq'" equation "`varlist'" + forvalues i=1/`nvar' { + if "${S_`i'}"!="" { + local Eq`i' ${S_`i'} + * Check that eq vars are in mainvarlist + tokenize `Eq`i'' + while "`1'"!="" { + ChkIn `1' "`varlist'" + mac shift + } + } + } + } + if `anyerr' { + di as err _n "specification error(s) found." + exit 198 + } + count if `touse' + local n=r(N) +/* + Count potentially imputable missing values for each variable, + and where necessary create an equation for each +*/ + local to_imp 0 // actual number of vars with missing values to be imputed + local recalc 0 // number of passively imputed vars to be recalculated + tempvar xtmp // temporary holding area + local nimp // list of number of missing values for each variable + forvalues i=1/`nvar' { + local xvar: word `i' of `varlist' + if "`genmiss'"!="" { + tempvar mvar`i' + gen byte `mvar`i''=missing(`xvar') if `touse'==1 + lab var `mvar`i'' "1 if `xvar' missing, 0 otherwise" + } + local x`i' `xvar' + count if missing(`xvar') & `touse'==1 + * Create prediction equation for each active variable + if r(N)>0 & `"`exp`i''"'=="" { + local nimp`i'=r(N) + * active var: has missing obs, not passive + local ++to_imp + local main`i' 1 + * Keep missingness of the original variable + tempvar miss`i' + gen byte `miss`i''=missing(`xvar') if `touse'==1 + * Define equation for this variable - user definition from eq() takes precedence + if "`Eq`i''"!="" { + local eq`i' `Eq`i'' + } + else { + * Remove variable from mainvarlist + local eq`i': list varlist - xvar + } + if "`cmd`i''"=="" { +/* + Assign default cmd for vars not so far accounted for. + cmd is relevant only for vars requiring imputation, i.e. with >=1 missing values. + Use logit if 2 distinct values, mlogit if 3-5, otherwise regress. +*/ + inspect `xvar' if `touse' + local nuniq=r(N_unique) + if `nuniq'==1 { + noi di as err "only 1 distinct value of `xvar' found" + exit 2000 + } + if `nuniq'==2 { + count if `xvar'==0 & `touse'==1 + if r(N)==0 { + noi di as err "variable `xvar' unsuitable for imputation," + noi di as err "binary variables must include at least one 0 and one non-missing value" + exit 198 + } + local cmd`i' logit + } + else if `nuniq'<=5 { + local cmd`i' mlogit + } + else local cmd`i' regress + } + if "`cmd`i''"=="mlogit" { + * With mlogit, if xvar carries a score label, + * drop it since it causes prediction problems + local xlab: value label `xvar' + capture label drop `xlab' + } + if "`on'"=="" { + * Initially fill missing obs cyclically with nonmissing obs + sampmis `xtmp'=`xvar' + replace `xvar'=cond(`touse'==0, ., `xtmp') + drop `xtmp' + } + else replace `xvar'=. if `touse'==0 + local lab`i' `xvar' imput.`suffix' (`nimp`i'' values) + } + else { + local main`i' 0 + if "`nimp`i''"=="" { // may have been set earlier by consideration of ParsExp + local nimp`i'=r(N) + } + if `"`exp`i''"'!="" { + if "`Eq`i''"!="" { + noi di as err "equation" as input " `xvar':`Eq`i'' " /// + as err "invalid, `xvar' is passively imputed" + exit 198 + } + local ++recalc + } + } + local nimp `nimp' `nimp`i'' + } + if `to_imp'==0 { + noi di as err _n "All relevant cases are complete, no imputation required." + return scalar N=`n' + return scalar imputed=0 + exit 2000 + } +* Remove passivevars from equations as necessary + forvalues i=1/`nvar' { + if `"`exp`i''"'!="" { + ParsExp `exp`i'' + local exclude `s(result)' + * remove current passivevar from each relevant equation + local passive `x`i'' + tokenize `exclude' + while "`1'"!="" { + * identify which variable in mainvarlist we are looking at + ChkIn `1' "`varlist'" + local index `s(k)' + * Remove `passive' from equation of variable + * whose index in mainvarlist is `index' + * (only allowed to be done if there is no + * user equation Eq`' for var #`index') + if "`eq`index''"!="" & "`Eq`index''"=="" { + local eq`index': list eq`index' - passive + } + mac shift + } + } + } + if "`substitute'"!="" { + forvalues i=1/`nvar' { + if `main`i'' & "`sub`i''"!="" { + * substitute for this variable in all equations where it is a covariate + forvalues j=1/`nvar' { + if `main`j'' & (`j'!=`i') & "`Eq`j''"=="" { + local res: list eq`j' - x`i' + * substitute sub`i' if necessary i.e. if not already there + tokenize `sub`i'' + while "`1'"!="" { + cap ChkIn `1' "`res'" + if "`s(k)'"=="0" { + local res `res' `1' + } + mac shift + } + local eq`j' `res' + } + } + } + } + } + * Show prediction equations at first imputation + if "`first'"!="" { + local errs 0 + local longstring 55 // max display length of variables in equation + local off 13 // blanks to col 13 on continuation lines + if "`showeq'"=="" { + noi di as text _n " Variable {c |} Command {c |} Prediction equation" _n /// + "{hline 12}{c +}{hline 9}{c +}{hline `longstring'}" + } + forvalues i=1/`nvar' { + if "`exp`i''"!="" & `nimp`i''>0 { + local eq "[Passively imputed from `exp`i'']" + local formatoutput 0 + } + else if "`eq`i''"=="" { + local eq "[No missing data in estimation sample]" + local formatoutput 0 + } + else { + local eq `eq`i'' + local formatoutput 1 + } + if "`showeq'"=="" { + if `formatoutput' { + formatline, n(`eq') maxlen(`longstring') + local nlines=r(lines) + forvalues j=1/`nlines' { + if `j'==1 noi di as text %11s abbrev("`x`i''",11) /// + " {c |} " %-8s "`cmd`i''" "{c |} `r(line`j')'" + else noi di as text _col(`off') /// + "{c |}" _col(23) "{c |} `r(line`j')'" + } + } + else noi di as text %11s abbrev("`x`i''",11) /// + " {c |} " %-8s "`cmd`i''" "{c |} `eq'" + } + // Check for invalid equation - xvar on both sides + if "`eq`i''"!="" { + if `: list x`i' in eq`i'' { + noi di as err "Error!" as inp " `x`i''" /// + as err " found on both sides of prediction equation" + local ++errs + } + } + } + if `errs' { + di as err _n `errs' " error(s) found. Consider using the passive() option to fix the problem" + exit 198 + } + if "`dryrun'"!="" { + exit + } + noi di as text _n "Imputing " _cont + } + if `to_imp'==1 | "`on'"!="" { + local cycles 1 + } +* Update recalculated variables + if `"`passive'"'!="" & `recalc'>0 { + forvalues i=1/`nvar' { + if "`exp`i''"!="" { + replace `x`i''=`exp`i'' + } + } + } +* Impute sequentially `cycles' times by regression switching (van Buuren et al) + tempvar y imputed + * Sort variables on number of missing values, from low to high numbers. + * Of benefit to the mice algorithm since less missings get imputed first. + listsort "`nimp'" + forvalues i=1/`nvar' { + local r`i' `s(index`i')' + } + if `"`trace'"'!="" { + tempname tmp + * create names + local postvl cycle + forvalues r=1/`nvar' { + local i `r`r'' // antirank: vars with small #missing come first + if `main`i'' local postvl `postvl' `x`i''_mean + } + postfile `tmp' `postvl' using `"`trace'"', replace + } + forvalues j=1/`cycles' { + if `"`trace'"'!="" local posts (`j') + forvalues r=1/`nvar' { + local i `r`r'' // antirank, ensuring vars with small #missing come first + if `main`i'' { + * Each var is reimputed based on imputed values of other vars + local type: type `x`i'' + gen `type' `y'=`x`i'' if `miss`i''==0 & `touse'==1 + if "`on'"=="" { + local vars `eq`i'' + } + else local vars `on' + * uvis is derived from uvisamp4.ado + cap uvis `cmd`i'' `y' `vars' `wgt' if `touse', /// + gen(`imputed') `boot`i'' `match`i'' `constant' + if _rc { + noi di as err _n(2) "Error running -uvis-" + noi di as err "I detected a problem with running uvis with command `cmd`i'' on response `x`i''" + noi di as err "and covariates `vars'." + if "`cmd`i''"=="mlogit" { + noi di as inp "The troublesome regression command is mlogit." + noi di as inp "Try reducing the number of categories of `x`i'' or using ologit if appropriate" + } + exit 198 + } + if `"`trace'"'!="" { + summarize `imputed' if missing(`y') & `touse'==1 + local mean=r(mean) + local posts `posts' (`mean') +/* + noi di as text %11s abbrev("`x`i''",10) %7.0g `mean' _cont + foreach v of var `vars' { + if "`v'"=="`x`i''" { + noi di as result " ." _cont + } + else noi di as result _skip(1) %7.0g _b[`v'] _cont + } + noi di +*/ + } + replace `x`i''=`imputed' + drop `y' `imputed' + } + } + if `"`trace'"'!="" post `tmp' `posts' + if `recalc'>0 { // update covariates needing recalculation + forvalues i=1/`nvar' { + if "`exp`i''"!="" & `nimp`i''>0 { + replace `x`i''=`exp`i'' + } + } + } + if `to_imp'==1 & "`first'"!="" { + noi di as text _n "[Only 1 variable to be imputed, therefore no cycling needed.]" + } + } +} +if `"`trace'"'!="" postclose `tmp' +* Save to file with cases in original order +quietly { + local impvl /* list of newvars containing imputations */ + sort `order' + forvalues i=1/`nvar' { + return scalar ni`i'=`nimp`i'' + if "`genmiss'"!="" { + cap drop `genmiss'`x`i'' + rename `mvar`i'' `genmiss'`x`i'' + } + if `main`i'' { + local impvl `impvl' `x`i'' + lab var `x`i'' "`lab`i''" + cap drop `miss`i'' + } + } + drop `touse' + if "`mitools'"=="" { + * Save list of imputed variables with imputations to char _dta[mi_ivar] + char _dta[mi_ivar] `impvl' + char _dta[mi_id] `id' + rename `order' `id' + return local impvl `impvl' + return scalar imputed=`to_imp' + } + else drop `order' + save `"`using'"', replace +} +end + +*! v 1.0.0 PR 01Jun2001. +program define sampmis +version 7 +* Duplicates nonmissing obs of `exp' into missing ones, in random order. +* This routine always reproduces the same sort order among the missings. +* Note technique to avoid Stata creating arbitrary sort order for missing +* observations of `exp'; affects entire reproducibility of mvi sampling. +syntax newvarname =/exp +quietly { + tempvar u + * Sort non-missing data at random, sort missing data systematically + gen double `u'=cond(missing(`exp'), _n, uniform()) + sort `u' + count if !missing(`exp') + local nonmis=r(N) + drop `u' + local type: type `exp' + gen `type' `varlist'=`exp' + local blocks=int((_N-1)/`nonmis') + forvalues i=1/`blocks' { + local j=`nonmis'*`i' + local j1=`j'+1 + local j2=min(`j'+`nonmis',_N) + replace `varlist'=`exp'[_n-`j'] in `j1'/`j2' + } +} +end + +program define ChkIn, sclass +version 7 +* Returns s(k) = index # of target variable v in varlist, or 0 if not found. +args v varlist +sret clear +local k: list posof "`v'" in varlist +sret local k `k' +if `s(k)'==0 { + di as err "`v' is not a valid covariate" + exit 198 +} +end + +*! version 1.0.0 PR 20dec2004. +program define ParsExp, sclass +version 8 +tokenize `*', parse(" +-/^()[]{}.*=<>!$%&|~`'") +local vl +while "`1'"!="" { + cap confirm var `1' + if _rc==0 { + if index("`vl'", "`1'")==0 { + local vl `vl' `1' + } + } + mac shift +} +sreturn local result `vl' +end + +program define detangle +version 8 +/* + Disentangle varlist:string clusters---e.g. for DF. + Returns values in $S_*. + If `4' is null, `3' is assumed to contain rhs + and lowest and highest value checking is disabled. + Heavily based on frac_dis.ado, but "=" disallowed as separator + and "\" allowed (for use by passive()). +*/ +args target tname rhs separator +if "`separator'"=="" { + local separator "," +} +unab rhs:`rhs' +local nx: word count `rhs' +forvalues j=1/`nx' { + local n`j': word `j' of `rhs' +} +tokenize "`target'", parse("`separator'") +local ncl 0 /* # of separator-delimited clusters */ +while "`1'"!="" { + if "`1'"=="`separator'" { + mac shift + } + local ncl=`ncl'+1 + local clust`ncl' "`1'" + mac shift +} +if "`clust`ncl''"=="" { + local --ncl +} +if `ncl'>`nx' { + di as err "too many `tname'() values specified" + exit 198 +} +/* + Disentangle each varlist:string cluster +*/ +forvalues i=1/`ncl' { + tokenize "`clust`i''", parse(":") + if "`2'"!=":" { + if `i'>1 { + noi di as err "invalid `clust`i'' in `tname'() (syntax error)" + exit 198 + } + local 2 ":" + local 3 `1' + local 1 + forvalues j=1/`nx' { + local 1 `1' `n`j'' + } + } + local arg3 `3' + unab arg1:`1' + tokenize `arg1' + while "`1'"!="" { + ChkIn `1' "`rhs'" + local v`s(k)' `arg3' + mac shift + } +} +forvalues j=1/`nx' { + if "`v`j''"!="" { + global S_`j' `v`j'' + } + else global S_`j' +} +end + +*! Based on artformatnos.ado v 1.0.0 PR 26Feb2004 +program define formatline, rclass +version 8 +syntax, N(string) Maxlen(int) [ Format(string) Leading(int 1) Separator(string) ] + +if `leading'<0 { + di as err "invalid leading()" + exit 198 +} + +if "`separator'"!="" { + tokenize "`n'", parse("`separator'") +} +else tokenize "`n'" + +local n 0 +while "`1'"!="" { + if "`1'"!="`separator'" { + local ++n + local n`n' `1' + } + macro shift +} +local j 0 +local length 0 +forvalues i=1/`n' { +*noi di in red "format=`format' i=`i' item=`n`i''" + if "`format'"!="" { + capture local out: display `format' `n`i'' + if _rc { + di as err "invalid format attempted for: " `"`n`i''"' + exit 198 + } + } + else local out `n`i'' + if `leading'>0 { + local out " `out'" + } + local l1=length("`out'") + local l2=`length'+`l1' + if `l2'>`maxlen' { + local ++j + return local line`j'="`line'" + local line "`out'" + local length `l1' + } + else { + local length `l2' + local line "`line'`out'" + } +} +local ++j +return local line`j'="`line'" +return scalar lines=`j' +end +*! version 1.1.0 PR 02aug2005. +program define listsort, sclass +version 6 +gettoken p 0 : 0, parse(" ,") +if `"`p'"'=="" { + exit +} +sret clear +syntax , [ Reverse Lexicographic ] +local lex="`lexicog'"!="" +if "`reverse'"!="" { local comp < } +else local comp > +local np: word count `p' +local i 1 +while `i'<=`np' { + local p`i': word `i' of `p' + local index`i' `i' + if !`lex' { confirm number `p`i'' } + local i=`i'+1 +} +* Apply shell sort (Kernighan & Ritchie p 58) +local gap=int(`np'/2) +while `gap'>0 { + local i `gap' + while `i'<`np' { + local j=`i'-`gap' + while `j'>=0 { + local j1=`j'+1 + local j2=`j'+`gap'+1 + if `lex' { local swap=(`"`p`j1''"' `comp' `"`p`j2''"') } + else local swap=(`p`j1'' `comp' `p`j2'') + if `swap' { + local temp `p`j1'' + local p`j1' `p`j2'' + local p`j2' `temp' + * swap indexes + local temp `index`j1'' + local index`j1' `index`j2'' + local index`j2' `temp' + } + local j=`j'-`gap' + } + local i=`i'+1 + } + local gap=int(`gap'/2) +} +local p +local index +local i 1 +while `i'<=`np' { + sret local i`i' `p`i'' + sret local index`i' `index`i'' + local p `p' `p`i'' + local index `index' `index`i'' + local i=`i'+1 +} +/* Find antirank of each obs +forvalues i=1/`np' { + forvalues j=1/`np' { + if +*/ +sret local list `p' +sret local index `index' +end +exit + + sort `c' + local i 0 + while `i'<`nx' { + local i=`i'+1 +/* + Store positions of sorted predictors in user's list +*/ + local j 0 + while `j'<`nx' { + local j=`j'+1 + if `i'==`n'[`j'] { + local r`j' `i' + local j `nx' + } + } + } diff --git a/Modules/ado/plus/i/ice.hlp b/Modules/ado/plus/i/ice.hlp new file mode 100644 index 0000000..b40bcc3 --- /dev/null +++ b/Modules/ado/plus/i/ice.hlp @@ -0,0 +1,562 @@ +{smcl} +{* 30aug2005}{...} +{hline} +help for {hi:ice}, {hi:uvis}{right:(SJ5-4: st0067_2; SJ5-2: st0067_1; SJ4-3: st0067)} +{hline} + +{title:Multiple imputation by the MICE system of chained equations} + +{p 8 17 2} +{cmd:ice} +{it:mainvarlist} +{cmd:using} {it:filename}[{cmd:.dta}] +{ifin} +{weight} +[{cmd:,} +{cmdab:bo:ot}[{cmd:(}{it:varlist}{cmd:)}] +{cmd:cc(}{it:varlist}{cmd:)} +{cmdab:cm:d(}{it:cmdlist}{cmd:)} +{cmdab:cy:cles(}{it:#}{cmd:)} +{cmdab:dry:run} +{cmd:eq(}{it:eqlist}{cmd:)} +{cmdab:g:enmiss(}{it:string}{cmd:)} +{cmdab:i:d(}{it:string}{cmd:)} +{cmd:m(}{it:#}{cmd:)} +{cmdab:ma:tch}[{cmd:(}{it:varlist}{cmd:)}] +{cmdab:nocons:tant} +{cmdab:nosh:oweq} +{cmd:on(}{it:varlist}{cmd:)} +{cmdab:pass:ive(}{it:passivelist}{cmd:)} +{cmdab:sub:stitute(}{it:sublist}{cmd:)} +{cmd:replace} +{cmdab:se:ed(}{it:#}{cmd:)} +{cmdab:tr:ace(}{it:filename}{cmd:)}] + +{p 8 17 2} +{cmd:uvis} +{it:regression_cmd} +{it:yvar} +{it:xvarlist} +{ifin} +{weight} +{cmd:,} +{cmdab:g:en(}{it:newvarname}{cmd:)} +[{cmdab:bo:ot} +{cmdab:ma:tch} +{cmdab:nocons:tant} +{cmd:replace} +{cmdab:se:ed(}{it:#}{cmd:)}] + +{p 4 4 2} +where + +{p 8 8 2} +{it:regression_cmd} may be +{helpb logistic}, +{helpb logit}, +{helpb mlogit}, +{helpb ologit}, +or +{helpb regress}. + +{p 4 4 2} +All weight types supported by {it:regression_cmd} are allowed; see {help weight}. + + +{title:Description} + +{p 4 4 2} +{cmd:ice} imputes missing values +in {it:mainvarlist} by using switching regression, an iterative multivariable +regression technique. The abbreviation MICE means multiple imputation by +chained equations and was apparently coined by Steff van Buuren. {cmd:ice} +implements MICE for Stata. Sets of imputed and nonimputed variables are +stored to a new file called {it:filename}. Any number of complete imputations +may be created. + +{p 4 4 2} +{cmd:uvis} (univariate imputation sampling) imputes missing values in the +single variable {it:yvar} based on multiple regression on {it:xvarlist}. +{cmd:uvis} is called repeatedly by {cmd:ice} in a regression switching mode to +perform multivariate imputation. + +{p 4 4 2} +The missing observations are assumed to be missing at random (MAR) or +missing completely at random (MCAR), according to the jargon. See, for +example, van Buuren et al. (1999) for an explanation of these concepts. + +{p 4 4 2} +Please note that {cmd:ice} and {cmd:uvis} require Stata 8 or later. +There have been incompatibility issues with Stata 7 and earlier. + + +{title:Options for ice} + +{p 4 8 2} +{cmd:boot}[{cmd:(}{it:varlist}{cmd:)}] instructs that each member of +{it:varlist}, a subset of {it:mainvarlist}, be imputed with the {cmd:boot} +option of {cmd:uvis} activated. If {cmd:(}{it:varlist}{cmd:)} is omitted, +all members of {it:mainvarlist} with missing observations are imputed using +the {cmd:boot} option of {cmd:uvis}. + +{p 4 8 2} +{cmd:cc(}{it:varlist}{cmd:)} prevents imputation of missing data in +{it:mainvarlist} for cases in which any member of {it:varlist} has a missing +value. "cc" signifies "complete case". Note that members of {it:varlist} are +used for imputation if they appear in {it:mainvarlist}, but not otherwise. Use +of this option is equivalent to entering {cmd:if} +{cmd:~missing(}{it:var1}{cmd:) &} {cmd:~missing(}{it:var2}{cmd:)} ..., where +{it:var1}, {it:var2}, ... denote the members of {it:varlist}. + +{p 4 8 2} +{cmd:cmd(}{it:cmdlist}{cmd:)} defines the regression commands to be used for +each variable in {it:mainvarlist}, when it becomes the dependent variable in +the switching regression procedure used by {cmd:uvis} (see {hi:Remarks}). The +first item in {it:cmdlist} may be a command, such as {cmd:regress}, or may have +the syntax {it:varlist}{cmd::}{it:cmd}, specifying that command {it:cmd} +applies to all the variables in {it:varlist}. Subsequent items in +{it:cmdlist} must follow the latter syntax, and each item should be followed +by a comma. + +{p 8 8 2} +The default {it:cmd} for a variable is {cmd:logit} when there are two distinct +values, {cmd:mlogit} when there are 3-5 and {cmd:regress} otherwise. + +{p 8 18 2} Example: {cmd:cmd(regress)} specifies that all variables are +to be imputed by {cmd:regress}, overriding the defaults. + +{p 8 18 2} Example: {cmd:cmd(x1 x2:logit, x3:regress)} specifies that +{cmd:x1} and {cmd:x2} are to be imputed by {cmd:logit}, {cmd:x3} by +{cmd:regress} and all others by their default choices. + +{p 4 8 2} +{cmd:cycles(}{it:#}{cmd:)} determines the number of cycles of regression +switching to be carried out. The default is {cmd:cycles(10)}. + +{p 4 8 2} +{cmd:dryrun} does a "dry run"; that is, {cmd:ice} +reports the prediction equations it has constructed from the various +inputs. No imputation is done, and no files are created. It is not +mandatory to specify an output file with {cmd:using} for a dry run. +Sometimes the prediction equation set-up needs to be carefully +checked before running what may be a lengthy imputation process. + +{p 4 8 2} +{cmd:eq(}{it:eqlist}{cmd:)} allows one to define customized prediction +equations for any subset of variables in {it:mainvarlist}. The option, +particularly when used with {cmd:passive()}, allows +great flexibility in the possible imputation schemes. The +syntax of {it:eqlist} is {it:varname1}{cmd::}{it:varlist1} +[{cmd:,}{it:varname2}{cmd::}{it:varlist2} ...], where each +{it:varname#} (or {it:varlist#}) +is a member (or subset) of {it:mainvarlist}. It is your responsibility to ensure +that each equation is sensible. {cmd:ice} places no restrictions +except to check that all variables mentioned are indeed in +{it:mainvarlist} and that an equation is not defined +for a variable specified to be passively imputed +(see the {cmd:passive()} option. Note that {cmd:eq()} takes +precedence over all default definitions and assumptions about +the way a given variable in {cmd:mainvarlist} will be imputed. +The default, if the {cmd:passive()} and {cmd:substitute()} +options are not invoked, is that each +variable in {it:mainvarlist} with any missing data is imputed from all +the other variables in {it:mainvarlist}. + +{p 4 8 2} +{cmd:genmiss(}{it:string}{cmd:)} creates an indicator variable for the +missingness of data in any variable in {it:mainvarlist} for which at least one +value has been imputed. The indicator variable is set to missing for +observations excluded by {cmd:if}, {cmd:in}, etc. The indicator variable for +{it:xvar} is named {it:string}{it:xvar}. + +{p 4 8 2} +{cmd:id(}{it:string}{cmd:)} creates a variable called {it:string} containing +the original sort order of the data. The default {it:string} is {cmd:_i}. + +{p 4 8 2} +{cmd:m(}{it:#}{cmd:)} defines {it:#} as the number of imputations required +(minimum 1, no upper limit). The default is {cmd:m(1)}. + +{p 4 8 2} +{cmd:match}[{cmd:(}{it:varlist}{cmd:)}] instructs that each member of +{it:varlist} be imputed with the {cmd:match} option of {cmd:uvis}. +This provides prediction matching for each member of {it:varlist}. +If {cmd:(}{it:varlist}{cmd:)} is omitted then all relevant variables are +imputed with the {cmd:match} option of {cmd:uvis}. The default, if +{cmd:match()} is not specified, is to draw from the posterior +predictive distribution of each variable requiring imputation. + +{p 4 8 2} +{cmd:noconstant} suppresses the regression constant in all regressions. + +{p 4 8 2} +{cmd:noshoweq} suppresses the presentation of the prediction equations. + +{p 4 8 2} +{cmd:on(}{it:varlist}{cmd:)} changes the operation of {cmd:ice} in a major +way. With this option, {cmd:uvis} imputes each member of {it:mainvarlist} +univariately on {it:varlist}. This provides a convenient way of producing +multiple imputations when imputation for each variable in {it:mainvarlist} is +to be done univariately on a set of complete predictors. + +{p 4 8 2} +{cmd:passive(}{it:passivelist}{cmd:)} allows the use of "passive" imputation +of variables that depend on other variables, some of which are imputed. +The syntax of {it:passivelist} is {it:varname}{cmd::}{it:exp} +[{cmd:\}{it:varname}{cmd::}{it:exp} ...]. Notice the requirement to use +"\" as a separator between items in {it:passivelist}, rather than the usual comma; +the reason is that a comma may be a valid part of an expression. +The option is most easily explained by example. Suppose x1 is a categorical variable +with 3 levels, and that two dummy variables x1a, x1b have been created by the commands + +{p 8 8 2} + {cmd:. generate byte x1a=(x1==2)}{break} + {cmd:. generate byte x1b=(x1==3)} + +{p 8 8 2} +Now suppose that x1 is to be imputed by the {cmd:mlogit} command and is +to be treated as the two dummy variables x1a and x1b when predicting other +variables. Use of {cmd:mlogit} is achieved by the option +{cmd:cmd(x1:mlogit)}. When x1 is imputed, we want x1a and x1b to be updated +with new values which depend on the imputed values of x1. This may be +achieved by specifying {cmd:passive(x1a:x1==2 \ x1b:x1==3)}. It is necessary +also to remove x1 from the list of predictors when variables other than x1 are +being imputed, and this is done by using the {cmd:substitute()} option; in the +present example, you would specify {cmd:substitute(x1:x1a x1b)}. + +{p 8 8 2} +Note that although in this example x1a will take the (possibly +unintended) value of 0 when x1 is missing, {cmd:ice} is careful to +ensure that x1a (and x1b) inherit the missingness of x1 and are +passively imputed following active imputation of missing values +of x1. If this were not done, incorrect results could occur. The +responsibility of the user is to create x1a and x1b before running +{cmd:ice} such that their missing values are identical +to those of x1. + +{p 8 8 2} +A second example is multiplicative interactions between variables, for +example, between x1 and x2 (e.g., x12=x1*x2); this could be entered as +{cmd:passive(x12:x1*x2)}. It would cause the interaction term +x12 to be omitted when either x1 or x2 was being imputed, since it would +make no sense to impute x1 from its interaction with x2. +{cmd:substitute()} is not needed here. + +{p 8 8 2} +It should be stressed that variables to be imputed passively must already +exist and must be included in {it:mainvarlist}; otherwise, they will not be +recognized. + +{p 4 8 2} +{cmd:substitute(}{it:sublist}{cmd:)} is typically used with the +{cmd:passive()} option to represent multilevel categorical variables +as dummy variables in models for predicting other variables. See +{cmd:passive()} for more details. The syntax of {it:sublist} is +{it:varname}{cmd::}{it:dummyvarlist} +[{cmd:,}{it:varname}{cmd::}{it:dummyvarlist} ...], where {it:varname} is the +name of a variable to be substituted and {it:dummyvarlist} is the list of +dummy variables representing it. + +{p 4 8 2} +{cmd:replace} permits {it:filename} to be overwritten with new data. + +{p 4 8 2} +{cmd:seed(}{it:#}{cmd:)} sets the random-number seed to {it:#}. +To reproduce a set of imputations, the same random-number seed should be used. +The default is {cmd:seed(0)}, meaning no seed is set by the program. + +{p 4 8 2} +{cmd:trace(}{it:filename}{cmd:)} monitors the convergence of the imputation +algorithm. For each original variable with missing values, the mean of the +imputed values is stored as a variable in {it:filename}, together +with the cycle number at which that +mean was calculated. The results are stored only for the final imputation. +For diagnostic purposes, it is sensible to run {cmd:trace()} +with {cmd:m(1)} and many cycles, such as {cmd:cycles(100)}. +When the run is complete, it is helpful to load {it:filename} +into memory and plot the mean for each imputed +variable against the cycle number. If necessary, smoothing may be applied +to clarify any apparent pattern. Convergence is judged to have occurred +when the pattern of the imputed means is random. +The number of cycles needed for convergence is usually obvious from the appearance +of the plot. + + +{title:Options for uvis} + +{p 4 8 2} +{cmd:gen(}{it:newvar}{cmd:)} is not optional. {it:newvar} contains original +(nonmissing) and imputed (originally missing) values of {it:yvar}. + +{p 4 8 2} +{cmd:boot} invokes a bootstrap method for creating imputed values (see Remarks). + +{p 4 8 2} +{cmd:match} creates imputations by prediction matching. The default is to draw +imputations at random from the posterior distribution of the missing values of +{it:yvar}, conditional on the observed values and the members of +{it:xvarlist}. See Remarks for further details. + +{p 4 8 2} +{cmd:noconstant} suppresses the regression constant in all regressions. + +{p 4 8 2} +{cmd:replace} permits {it:newvar} (see {cmd:gen(}{it:newvar}{cmd:)}) +to be overwritten with new data. {cmd:replace} may not be abbreviated. + +{p 4 8 2} +{cmd:seed(}{it:#}{cmd:)} sets the random-number seed to {it:#}. +See {hi:Remarks} for comments on how to ensure reproducible imputations +by using the {cmd:seed()} option. +The default is {cmd:seed(0)}, meaning no seed is set by the program. + + +{title:Remarks} + +{p 4 4 2} +{cmd:uvis} imputes {it:yvar} from {it:xvarlist} according to the following +algorithm (see van Buuren et al. (1999, section 3.2) for further technical +details): + +{p 8 12 2} +1. Estimate the vector of coefficients (beta) and the residual variance +by regressing the nonmissing values of {it:yvar} on the current "completed" +version of {it:xvarlist}. Predict the fitted values {it:etaobs} at the +nonmissing observations of {it:yvar}. + +{p 8 12 2} +2. Draw at random a value (sigma_star) from the posterior distribution of the +residual standard deviation. + +{p 8 12 2} +3. Draw at random a value (beta_star) from the posterior distribution of beta, +allowing, through sigma_star, for uncertainty in beta. + +{p 8 12 2} +4. Use beta_star to predict the fitted values {it:etamis} +at the missing observations of {it:yvar}. + +{p 8 12 2} +5. The imputed values are predicted directly from beta_star, sigma_star and +the covariates. When imputation is by linear regression ({cmd:regress} +command), this step assumes that {it:yvar} is Normally distributed, given the +covariates. For other types of imputation, samples are drawn from the +appropriate distribution. + +{p 4 4 2} +With the {cmd:match} option, step 5 is replaced by the following. +For each missing observation of {it:yvar} with prediction {it:etamis}, +find the non-missing observation of {it:yvar} whose prediction +({it:etaobs}) on observed data is closest to {it:etamis}. This closest +non-missing observation is used to impute the missing value of {it:yvar}. + +{p 4 4 2} +The default draw method is not robust to departures from Normality and +may produce implausible imputations. For example, if the original distribution +is skew and positive-valued, the imputed distribution will not necessarily +have the appropriate amount of skewness, nor will all the imputed values +necessarily be positive. Log transformation of positive variables may greatly +improve the appropriateness of the imputations. + +{p 4 4 2} +The alternative {cmd:match} method is recommended only for continuous variables +when the Normality assumption is clearly untenable, even approximately. +It is not necessary, nor is it recommended, for binary, ordered categorical or +nominal variables. {cmd:match} may work well when the distribution of a +continuous variable is very non-Normal, but it may sometimes result in biased +imputations. + +{p 4 4 2} +With the {cmd:boot} option, steps 2-4 are replaced by a bootstrap estimation of +beta_star; beta_star +is estimated by regressing {it:yvar} on {it:xvarlist} after taking a bootstrap sample +of the non-missing observations. This has the advantage of robustness since the +distribution of beta is no longer assumed to be multivariate normal. + +{p 4 4 2} +Note that {cmd:uvis} will not impute observations for which a value +of a variable in {it:xvarlist} is missing. However, all original +(missing or nonmissing) observations of {it:yvar} will be copied into +{it:newvarname} in such cases. This is a change from the first release of +{cmd:uvis} (with {cmd:mvis}). Previously, {it:newvarname} would be set to +missing whenever a value of a variable in {it:xvarlist} was missing, +irrespective of the value of {it:yvar}. + +{p 4 4 2} +Missing data for ordered (or unordered) categorical covariates should +be imputed by using the {cmd:ologit} (or {cmd:mlogit}) command. In these cases, +prediction matching is done on the scale of the mean absolute difference +in the predicted class probabilities, preceded by logit transformation. + +{p 4 4 2} +{cmd:ice} carries out multivariate imputation in {it:mainvarlist} using +regression switching (van Buuren et al. 1999) as follows: + +{p 8 12 2} +1. Ignore any observations for which {it:mainvarlist} has only missing values, + or if the {cmd:ccvarlist(}{it:varlist}{cmd:)} option has been specified, for + which any member of {it:varlist} has a missing value. + +{p 8 12 2} +2. For each variable in {it:mainvarlist} with any missing data, randomly order + that variable and replicate the observed values across the missing cases. + This step initializes the iterative procedure by ensuing that no relevant + values are missing. + +{p 8 12 2} +3. For each variable in {it:mainvarlist} in turn, impute missing values by + applying {cmd:uvis} with the remaining variables as covariates. + +{p 8 12 2} +4. Repeat step 3 {cmd:cycles()} times, replacing the imputed values with updated + values at the end of each cycle. + +{p 4 4 2} +A single imputation sample is created for each variable with any relevant +missing values. + +{p 4 4 2} +Van Buuren recommends {cmd:cycles(20)} but goes on to say that 10 or even 5 +iterations are probably sufficient. We have chosen a compromise default of 10. + +{p 4 4 2} +"Multiple imputation" (MI) implies the creation and analysis of several +imputed datasets. To do this, one would run {cmd:ice} with {it:m} set +to a suitable number, for example 5. To obtain final estimates +of the parameters of interest and their standard errors, +one would fit a model in +each imputation and carry out the appropriate post-MI averaging procedure +on the results from the {it:m} separate imputations. A suitable +estimation tool for this purpose is {helpb micombine}. + +{title:Handling categorical variables} + +{p 4 4 2} +Binary variables present no difficulty: by default, in the MICE +procedure, when such a variable is the response, it is +predicted from other variables by using logistic regression; +when it is a covariate, it is modeled in the only way possible, +effectively as a single dummy variable. Categorical variables with 3 or +more levels may in principle be treated in different ways. +By default, in {cmd:ice} variables with 3-5 levels are modeled +using multinomial logistic regression ({cmd:mlogit} command) when +the response, and as a single linear term when a covariate. The +same behavior occurs with the ordered logistic model ({cmd:ologit} +command), requested via the {cmd:cmd()} option. The use of dummy variables +instead of a single linear term may be imposed as described under +the {cmd:passive()} option. The requisite dummy variables +must be created before {cmd:ice} is invoked. Variables with 6 or +more levels are treated as ordered and continuous, but again +different choices may be imposed by use of the {cmd:cmd()}, +{cmd:passive()} and {cmd:substitute()} options. + +{p 4 4 2} +You should be aware that +unless the dataset is large, use of the {cmd:mlogit} command may produce +unstable estimates if the number of levels is too large, and +may compromise the accuracy of the imputations. It is hard to +predict when this will occur. + +{p 4 4 2} +Note that due to a peculiarity of the way the {cmd:mlogit} command works, +variables with score labels cause problems to {cmd:ice} +and {cmd:uvis} when missing data are imputed using {cmd:mlogit}. +Score labels for such variables are removed in the file of imputed +data. See also the related comment on {hi:Postestimation prediction} in +{helpb micombine}. + + +{title:Further notes} + +{p 4 4 2} +{cmd:ice} determines the order of imputing variables in the round +of chained equations according to the amount of missing data. +Variables with the least missingness are imputed first. + +{p 4 4 2} +An important application of MI is to investigate possible models, for example +prognostic models, in which selection of influential variables is required +(Clark and Altman 2003). For example, the stability of the final model across +the imputation samples is of interest. This area of inquiry is in its infancy. + +{p 4 4 2} +In survival analysis, it is recommended to include the censoring indicator +and the log of the survival time in the variables to be used for imputation. +Van Buuren et al. (1999) give a detailed discussion of the different types +of covariate that can be included in the imputation model and discuss the +important issue of how to deal with variables which are missing completely at +random (MCAR), missing at random (MAR), and missing not at random (MNAR). + +{p 4 4 2} +See also Van Buuren's web site http://www.multiple-imputation.com for further +information and software sources. + + +{title:Examples} + +{p 4 10 2} +{cmd:. uvis regress y x1 x2 x3, gen(ym)} + +{p 4 10 2} +{cmd:. ice x1 x2 x3 using imputed, m(5)} + +{p 4 10 2} +{cmd:. ice x1 x2 x3 using imputed, m(5) cycles(20) cc(x4 x5)} + +{p 4 10 2} +{cmd:. ice x1-x5 using imputed, m(10) boot match(x1 x2 x3) cmd(x1 x2:mlogit, x3:ologit) id(pid) seed(101) genmiss(m_)} + +{p 4 10 2} +{cmd:. ice x1 x1a x1b x2 x3 x23 using imputed, m(5) cmd(x1:ologit) passive(x1a:x1==2 \x1b:x1==3 \x23=x2*x3) substitute(x1:x1a x1b)} + +{p 4 10 2} +{cmd:. ice y1 y2 y3 x1 x2 x3 x4 using imputed, m(5) eq(y1:x1 x2 y2, y2:y1 x3 x4, y3:y1 y2) match(y3)} + + +{title:Acknowledgement} + +{p 4 4 2} +I am grateful to Gillian Raab for pointing out certain issues with the prediction +matching approach, particularly that it is only useful with continuous variables. +As a result, the default imputation method has been +changed from matching to drawing from the predictive distribution. Gillian also +suggested imputing the variables in reverse order of the amount of missingness, +and selecting the imputed value at random from the set determined by the available +matching predictions. Both suggestions have been implemented in this software update. + + +{title:Author} + +{p 4 4 2} +Patrick Royston, MRC Clinical Trials Unit, London.{break} +patrick.royston@ctu.mrc.ac.uk + + +{title:References} + +{p 4 8 2} +van Buuren S., H. C. Boshuizen and D. L. Knook. 1999. Multiple imputation of + missing blood pressure covariates in survival analysis. + {it:Statistics in Medicine} {cmd:18}:681-694. + Also see http://www.multiple-imputation.com. + +{p 4 8 2} +Carlin J. B., N. Li, P. Greenwood, and C. Coffey. 2003. Tools for analyzing +multiple imputed datasets. {it:Stata Journal} 3(3): 226-244. + +{p 4 8 2} +Clark T. G. and D. G. Altman. 2003. Developing a prognostic model +in the presence of missing data: an ovarian cancer case-study. +{it:Journal of Clinical Epidemiology} 56: 28-37. + +{p 4 8 2} +Royston P. 2004. Multiple imputation of missing values. +{it:Stata Journal} 4(3): 227-241. + + +{title:Also see} + +{psee} +Online: {helpb mijoin}, {helpb micombine}, {helpb mitools}, and related programs, +if installed +{p_end} diff --git a/Modules/ado/plus/i/iclassr.ado b/Modules/ado/plus/i/iclassr.ado new file mode 100644 index 0000000..b4e3f89 --- /dev/null +++ b/Modules/ado/plus/i/iclassr.ado @@ -0,0 +1,53 @@ +*! version 1.1.1 STB-35 sg65 +program define iclassr + version 4.0 + local varlist "req ex min(2) max(2)" + local if "opt" + local in "opt" + local weight "aweight" + local options "Center(string) Ems NOIsily" + parse "`*'" + parse "`varlist'", parse(" ") + local weight "[`weight'`exp']" + local wt : word 2 of `exp' + + tempvar use + quietly { + mark `use' `if' `in' + markout `use' `varlist' `wt' + } + tempname gr df fm + if "`ems'" != "" { + preserve + qui keep if `use' + sort `2' + if "`wt'" == "" { + tempvar Wt + qui gen byte `Wt' = 1 + local wt "`Wt'" + } + tempvar sw + qui by `2': gen double `sw' = sum(`wt') + qui summ `sw' if `2' < `2'[_n+1] + scalar `df' = _result(1) - 1 + scalar `gr' = _result(1) * _result(3) + scalar `gr' = (`gr' - _result(3) - _result(4)*`df'/`gr')/`df' + capture `noisily' oneway `1' `2' `weight' + } + else { + capture `noisily' oneway `1' `2' `weight' if `use' + scalar `gr' = _result(1)/ (_result(3) + 1) + } + if _rc == 134 { error(134) } + scalar `df' = 1 + if "`center'" == "mean" { scalar `df' = _result(5)/(_result(5)-2) } + else if "`center'" == "med" { + scalar `df' = invfprob(_result(3), _result(5), 0.5) + } + scalar `fm' = max(_result(6) - `df', 0) + global S_1 = `fm' / (`fm' + `df'* `gr') + global S_2 = `fm' / (`fm' + `df') + di _new in gr "Intra-`2' r =" in ye %7.4f $S_1 _new in gr /* + */ "Estimated reliability of a `2' mean (n=" in ye %3.2f `gr' in gr /* + */ ") =" in ye %7.4f $S_2 +end diff --git a/Modules/ado/plus/i/iclassr.hlp b/Modules/ado/plus/i/iclassr.hlp new file mode 100644 index 0000000..1980e03 --- /dev/null +++ b/Modules/ado/plus/i/iclassr.hlp @@ -0,0 +1 @@ +.h l1way diff --git a/Modules/ado/plus/i/iclassr2.ado b/Modules/ado/plus/i/iclassr2.ado new file mode 100644 index 0000000..ff7ac48 --- /dev/null +++ b/Modules/ado/plus/i/iclassr2.ado @@ -0,0 +1,38 @@ +*! version 1.1.1 STB-35 sg65 +program define iclassr2 + version 4.0 + local varlist "req ex min(2) max(2)" + local if "opt" + local in "opt" + local options "Center(string)" + parse "`*'" + parse "`varlist'", parse(" ") + local weight "[`weight'`exp']" + + tempvar use + quietly { + mark `use' `if' `in' + markout `use' `varlist' + + tempname m k f + tempvar tt + gen `tt' = `1' + `2' if `use' + summ `tt' /* `weight' */ + if !_result(1) { error 2000 } + scalar `k' = _result(1) + scalar `f' = _result(4) + replace `tt' = `1' - `2' if `use' + summ `tt' /* `weight' */ + scalar `f' = `f'/((`k'-1)*_result(4)/`k' + _result(3)*_result(3)) + scalar `m' = 1 + if "`center'" == "mean" { scalar `m' = `k'/(`k'-2) } + else if "`center'" == "med" { + scalar `m' = invfprob(`k'-1, `k', 0.5) + } + global S_1 = (`f' - `m') / (`f' + `m') + global S_2 = (`f' - `m') / `f' + } + di _new in gr "Intra-class r =" in ye %7.4f $S_1 in gr /* + */ " Number of classes =", in ye `k' _new in gr /* + */ "Estimated reliability of a class mean (n=2) =" in ye %7.4f $S_2 +end diff --git a/Modules/ado/plus/i/iclassr2.hlp b/Modules/ado/plus/i/iclassr2.hlp new file mode 100644 index 0000000..10ee638 --- /dev/null +++ b/Modules/ado/plus/i/iclassr2.hlp @@ -0,0 +1,48 @@ +.- +help for ^iclassr2^ +.- + +Intra-class correlation for paired measures [STB-35 sg65] +------------------------------------------- + + ^iclassr^ response_var1 response_var2 [^if^ exp] [^in^ range] [^, c^enter^(^Fpos^)^] + + +Description +----------- + +^iclassr2^ calculates the intra-class correlation for paired measurements or as- +sessments stored in response_var1 and response_var2. ^iclassr2^ also reports the +reliability of the mean of the two measurements as estimated from the Spearman- +Brown prophecy formula. Missing values are handled by casewise deletion. + +@loneway@ also calculates intra-class correlations, but requires data in long, +rather than wide format. ^iclassr2^ is also much faster than ^loneway^, and offers +a small sample adjustment to the intra-class r; see the option ^center^, below. + + +Options +------- + +^center^ chooses a reference point in the F distribution to center the observed + F statistic in estimating the intra-class correlation. The argument Fpos + may be 1 (the default), or "med" or "mean" to choose the median or the mean + of the appropriate F distribution. This option has little effect unless the + number of pairs is small. + + +Examples +-------- + + . ^iclassr2 judge1 judge2^ (inter-judge reliability) + . ^iclassr2 judge1 judge2, c(med)^ (intra-judge reliability, center the ob- + served F on its median) + + +Also see +-------- + + STB: sg65 (STB-35) + Manual: ^[R] loneway^ +On-line: help for @loneway@ + diff --git a/Modules/ado/plus/i/imputeitems.ado b/Modules/ado/plus/i/imputeitems.ado new file mode 100644 index 0000000..bd5b6bb --- /dev/null +++ b/Modules/ado/plus/i/imputeitems.ado @@ -0,0 +1,188 @@ +*! version 2.1 24 November 2008 +*! Jean-Benoit Hardouin +************************************************************************************************************ +* imputeitems: Imputation of missing data of binary items +* +* Version 1 : November 25, 2006 (Jean-Benoit Hardouin) /*Dichotomous data*/ +* Version 1.1 : January 26, 2007 (Jean-Benoit Hardouin) /*Correction of a bug with the BIL method*/ +* Version 1.2 : March 9, 2007 (Jean-Benoit Hardouin) /*IF*/ +* Version 2 : June 30, 2008 (Jean-Benoit Hardouin) /*new names of the methods, MAX option*/ +* Version 2.1 : December 3, 2008 (Jean-Benoit Hardouin) /*correction of a bug with the MAX option*/ +* +* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France +* jean-benoit.hardouin@univ-nantes.fr +* +* News about this program : http://www.anaqol.org +* FreeIRT Project : http://www.freeirt.org +* +* Copyright 2006-2008 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + + +program define imputeitems +version 9 +syntax varlist(min=2 numeric) [if/] [, PREFix(string) METHod(string) RANDom max(int 0)] + +if "`if'"=="" { + local if=1 + local ifif +} +else { + local ifif if `if' +} + +*di "IF : `if' `ifif'" + +local nbitems : word count `varlist' +tokenize `varlist' + +if `max'==0 { + local max=`nbitems' +} + +forvalues i=1/`nbitems' { + qui su ``i'' `ifif' + if `r(min)'!=0&`r(max)'!=1 { + di in red "The {hi:imputeqol} command runs only with dichotomous items" + error + } + local p`i'=r(mean) +} + +if "`method'"=="" { + local method pms +} +if "`method'"!="pms"&"`method'"!="ims"&"`method'"!="cim"&"`method'"!="ics"&"`method'"!="bip"&"`method'"!="bil"&"`method'"!="bic"&"`method'"!="bii"&"`method'"!="log"&"`method'"!="worst" { + di in red "The method option is unknow (choose among pms, ims, cim, ics, log and worst)" + error +} +forvalues i=1/`nbitems'{ + qui su ``i'' `ifif' + local mean`i'=r(mean) +} + +if "`method'"=="pms"&"`random'"!="" { + local method bip +} +else if "`method'"=="ims"&"`random'"!="" { + local method bii +} +else if "`method'"=="log"&"`random'"!="" { + local method bil +} +else if "`method'"=="cim"&"`random'"!="" { + local method bic +} +else if ("`method'"=="ics"|"`method'"=="worst")&"`random'"!="" { + di in green "The random process is not available with the {hi:ics} or {hi:worst} methods. The {hi:random} option is ignored." + local random +} + + +forvalues i=1/`nbitems' { + tempvar imp`i' tmp`i' + if "`method'"=="pms"|"`method'"=="bip"|"`method'"=="cim"|"`method'"=="bic" { + qui egen `imp`i''=rowtotal(`varlist') `ifif' + qui egen `tmp`i''=rownonmiss(`varlist') `ifif' + qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif' + qui replace `imp`i''=``i'' if ``i''!=.&`if' + if "`method'"=="pms" { + qui replace `imp`i''=round(`imp`i'') `ifif' + } + else if "`method'"=="bip" { + qui replace `imp`i''=uniform()<`imp`i'' `ifif' + } + else if "`method'"=="cim"|"`method'"=="bic"{ + qui replace `imp`i''=`imp`i''*`tmp`i''*`mean`i'' `ifif' + qui replace `tmp`i''=0 `ifif' + forvalues j=1/`nbitems' { + qui replace `tmp`i''=`tmp`i''+`mean`j'' if ``j''!=.&`if' + } + qui replace `imp`i''=`imp`i''/`tmp`i'' `ifif' + qui replace `imp`i''=1 if `imp`i''>1&`imp`i''!=.&`if' + qui replace `imp`i''=0 if `imp`i''<0&`imp`i''!=.&`if' + if "`method'"=="cim" { + qui replace `imp`i''=round(`imp`i'') `ifif' + } + else if "`method'"=="bic" { + qui replace `imp`i''=uniform()<`imp`i'' `ifif' + } + } + } + else if "`method'"=="ims"|"`method'"=="bii" { + qui gen `imp`i''=`mean`i'' `ifif' + if "`method'"=="ims" { + qui replace `imp`i''=round(`imp`i'') `ifif' + } + else if "`method'"=="bii" { + qui replace `imp`i''=uniform()<`imp`i'' `ifif' + } + } + else if "`method'"=="ics" { + local item=0 + local corrmax=-2 + forvalues j=1/`nbitems' { + if `i'!=`j' { + qui corr ``i'' ``j'' `ifif' + if r(rho)>`corrmax'&r(rho)!=. { + local item `j' + local corrmax=r(rho) + } + } + } + di "A missing value for the item ``i'' is replaced by the value of the item `item'" + qui gen `imp`i''=``i'' `ifif' + qui replace `imp`i''=``item'' if ``i''==.&`if' + } + else if "`method'"=="log"|"`method'"=="bil" { + local liste`i' + forvalues j=1/`nbitems' { + if `i'!=`j' { + local liste`i' `liste`i'' ``j'' + } + } + qui sw ,pr(0.05): logit ``i'' `liste`i'' `ifif' + *local select :colnames e(b) + local select=substr("`:colnames e(b)'",1,length("`:colnames e(b)'")-5) + qui logit ``i'' `select' `ifif' + qui predict `imp`i'' `ifif' + if "`method'"=="log" { + qui replace `imp`i''=round(`imp`i'') if `imp`i''!=.&`if' + } + else if "`method'"=="bil" { + qui replace `imp`i''=uniform()<`imp`i'' if `imp`i''!=.&`if' + } + } + else if "`method'"=="worst" { + qui gen `imp`i''=0 `ifif' + } +} +forvalues i=1/`nbitems' { + qui replace `imp`i''=``i'' if ``i''!=.&`if' + if "`prefix'"=="" { + local prefix imp + } + qui gen `prefix'``i''=`imp`i'' `ifif' +} + +tempvar miss +qui egen `miss'=rowmiss(`varlist') +forvalues i=1/`nbitems' { + qui replace `prefix'``i''=. if ``i''==.&`miss'>`max' +} + +end diff --git a/Modules/ado/plus/i/imputeitems.hlp b/Modules/ado/plus/i/imputeitems.hlp new file mode 100644 index 0000000..a4236d0 --- /dev/null +++ b/Modules/ado/plus/i/imputeitems.hlp @@ -0,0 +1,68 @@ +{smcl} +{* 30June2008}{...} +{hline} +help for {hi:imputeitems}{right:Jean-Benoit Hardouin} +{hline} + +{title:Imputation of missing item responses} + +{p 8 14 2}{cmd:imputeitems} {it:varlist} [{it:if}] [,{cmdab:pref:ix}({it:string}) {cmdab:meth:od}({it:string}) {cmdab:rand:om} {cmdab:max}({it:#})] + + +{title:Description} + +{p 4 4 2}{cmd:imputeitems} imputes missing item responses by different ways : Item Mean Substitution (IMS), Person Mean Substitution (PMS), Corrected Item Mean Substiutution (CIM), Interitem Correlation Substitution (ICS), logistic model (LOG) and Worst Case (WORST). A random process can be added to several methods. + +{title:Options} + +{p 4 8 2}{cmd:prefix} defines the prefix to use to name the imputted variables (this prefix is followed by the name of the initial variable). By default, this prefix is "imp". + +{p 4 8 2}{cmd:method} defines the method to impute missing data : + +{p 8 8 2}{it:pms} computes the proportion of positive response of each individual on non missing items, and impute a deterministic result (if p<.5 then 0, else 1), + +{p 8 8 2}{it:ims} computes the proportion of positive response to each items, and impute a deterministic result (if p<.5 then 0, else 1), + +{p 8 8 2}{it:cim} computes the proportion of positive response to each items, corrected by the ability of the individual and impute a deterministic result (if p<.5 then 0, else 1), + +{p 8 8 2}{it:ics} searchs for each item the more correlated item and replaces a missing data by the data of this more correlated item (if the other response is missing too, there is no imputation), + +{p 8 8 2}{it:log} explains the responses of each item by a logistic model where the independent variables are the responses to the others items. Only significant variables are rettained (5%). These methods impute a deterministic result (if p<.5 then 0, else 1) [{it:log}] to missing responses (if the response to an independant variable is missing, there is no imputation), + +{p 8 8 2}{it:worst} replaces the missing data by a 0. + +{p 4 8 2}{cmd:random} adds a random effect to the imputation process (available only with {it:pms}, {it:ims}, {it:cim} or {it:log}). In these cases, the imputed value is randomly drawed from a binomial distribution using the parameter p. + +{p 4 8 2}{cmd:max} allows imputing missing values only for individuals with a maximal number of missing values defined with this option. + +{p 4 8 2}By default, {it:pms} method is working. + +{p 4 8 2}Old names of methods ({it:bip}, {bii}, {it:bic} and {it:bil} continues to run. They actually correspond to the add of the {cmd:random} option to the {it:pms}, {it:ims}, {it:cim} and {it:log} methods. + + +{title:Example} + + {cmd:. imputeitems itemA*} /*PMS method, IMP prefix*/ + + {cmd:. imputeitems itemA*, prefix(cim) method(cim)} + + {cmd:. imputeitems itemA*, method(log) random} + + +{title:Reference} + +{p 4 8 2}{cmd:Huisman M.} (2000), Imputation of missing item responses: some simple techniques. {it: Quality & Quantity}, {cmd:34}, 331-351. + + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end} +{p 4 8 2}EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"{p_end} +{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end} +{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end} +{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end} +{p 4 8 2}Email: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol} +and {browse "http://www.freeirt.org":FreeIRT} + diff --git a/Modules/ado/plus/i/inslist.ado b/Modules/ado/plus/i/inslist.ado new file mode 100644 index 0000000..38b4393 --- /dev/null +++ b/Modules/ado/plus/i/inslist.ado @@ -0,0 +1,78 @@ +program def inslist, rclass +*! NJC 1.1.0 14 December 2000 +* NJC 1.0.0 7 November 2000 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + + local nlist : word count `list' + + syntax , Insert(string) Pos(numlist sort int >=-`nlist' <=`nlist') /* + */ [ Global(str) Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + local np1 = `nlist' + 1 + tknz `pos' `np1', s(p) + local np : word count `pos' + + * negative indexes to positive + local i = 1 + while `p`i'' < 0 { + local p`i' = `nlist' + 1 + `p`i'' + local i = `i' + 1 + } + + local nins : word count `insert' + if `nins' < `np' { + local rep = 1 + int( `np' / `nins') + local insert : di _dup(`rep') "`insert' " + local nins : word count `insert' + } + + tknz `insert', s(i) + + local j = 1 + + while `p`j'' == 0 { + local newlist "`newlist'`i`j'' " + local j = `j' + 1 + } + + tokenize `list' + + local i = 1 + while `i' <= `nlist' { + local newlist "`newlist'``i'' " + while `i' == `p`j'' & `j' <= `np' { + local newlist "`newlist'`i`j'' " + local j = `j' + 1 + } + local i = `i' + 1 + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + +program def tknz, rclass +* NJC 1.1.0 2 June 2000 + version 6.0 + gettoken list 0 : 0, parse(",") + syntax , Stub(str) [ * ] + tokenize `"`list'"' , `options' + + local i = 1 + while "``i''" != "" { + c_local `stub'`i' `"``i''"' + local i = `i' + 1 + } +end + diff --git a/Modules/ado/plus/i/inslist.hlp b/Modules/ado/plus/i/inslist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/i/inslist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/i/isvar.ado b/Modules/ado/plus/i/isvar.ado new file mode 100644 index 0000000..fcdd3f4 --- /dev/null +++ b/Modules/ado/plus/i/isvar.ado @@ -0,0 +1,27 @@ +*! NJC 1.0.0 20 Sept 2005 +program isvar, rclass + version 8 + syntax anything + + foreach v of local anything { + capture unab V : `v' + if _rc == 0 local varlist `varlist' `V' + else local badlist `badlist' `v' + } + + di + + if "`varlist'" != "" { + local n : word count `varlist' + local what = plural(`n', "variable") + di as txt "{p}`what': " as res "`varlist'{p_end}" + return local varlist "`varlist'" + } + + if "`badlist'" != "" { + local n : word count `badlist' + local what = plural(`n', "not variable") + di as txt "{p}`what': " as res "`badlist'{p_end}" + return local badlist "`badlist'" + } +end diff --git a/Modules/ado/plus/i/isvar.hlp b/Modules/ado/plus/i/isvar.hlp new file mode 100644 index 0000000..dd17e4e --- /dev/null +++ b/Modules/ado/plus/i/isvar.hlp @@ -0,0 +1,56 @@ +{smcl} +{* 20sep2005}{...} +{hline} +help for {hi:isvar} +{hline} + +{title:Filter names into variable names and others} + +{p 8 17 2} +{cmdab:isvar} {it:possiblevarlist} + + +{title:Description} + +{p 4 4 2} +{cmd:isvar} takes a list of names that might name variables in +your dataset and filters it into a list of those names that are indeed +variable names and a list of the others. + +{p 4 4 2} +One application of {cmd:isvar} arises when you are moving between similar +datasets, especially if they are large, but are not sure which variables are +defined in which dataset. Commands such as {help describe} would fail at the +first name not in fact a variable name. {cmd:isvar} offers a more direct way to +establish existence or non-existence of several possible variables. + + +{title:Saved results} + +{p 4 8 2}r(varlist) names of variables in current dataset{p_end} +{p 4 8 2}r(badlist) names that do not correspond to variables in current dataset + + +{title:Examples} + +{p 4 8 2}{cmd:. isvar mpg rep78 rep77}{p_end} +{p 4 8 2}{cmd:. local OKlist "`r(varlist)'"}{p_end} +{p 4 8 2}{cmd:. su `OKlist'} + + +{title:Author} + +{p 4 4 2}Nicholas J. Cox, Durham University, U.K.{break} + n.j.cox@durham.ac.uk + + +{title:Acknowledgements} + +{p 4 4 2}This problem was suggested by Amadou Diallo. + + +{title:Also see} + +{p 4 13 2} +Online: help for {help describe}; {help unab} + diff --git a/Modules/ado/plus/j/joinlist.ado b/Modules/ado/plus/j/joinlist.ado new file mode 100644 index 0000000..86f173f --- /dev/null +++ b/Modules/ado/plus/j/joinlist.ado @@ -0,0 +1,65 @@ +program def joinlist, rclass +*! NJC 1.2.0 14 December 2000 +* -separate- option renamed -sep- for consistency +* NJC 1.1.0 6 June 2000 +* NJC 1.0.0 28 Jan 2000 + version 6.0 + gettoken lists 0 : 0, parse(",") + if "`lists'" == "" | "`lists'" == "," { + di in r "empty lists" + exit 198 + } + + tokenize "`lists'", parse("\") + args list1 bs list2 stuff + if "`stuff'" != "" { + di in r "incorrect syntax: too much stuff" + exit 198 + } + if "`list1'" == "\" { + di in r "empty list 1" + exit 198 + } + if "`list2'" == "" | "`list2'" == "\" { + di in r "empty list 2" + exit 198 + } + + syntax [ , Global(str) Noisily Sep ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + local n1 : word count `list1' + local n2 : word count `list2' + if `n1' != `n2' { + if `n1' == 1 { + local list1 : di _dup(`n2') "`list1' " + local n1 = `n2' + } + else if `n2' == 1 { + local list2 : di _dup(`n1') "`list2' " + } + else { + di in r "lists of unequal length" + exit 198 + } + } + + if "`sep'" != "" { local sep " " } + + local i = 1 + while `i' <= `n1' { + local w1 : word `i' of `list1' + local w2 : word `i' of `list2' + local newlist "`newlist'`w1'`sep'`w2' " + local i = `i' + 1 + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/j/joinlist.hlp b/Modules/ado/plus/j/joinlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/j/joinlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/l/l1way.ado b/Modules/ado/plus/l/l1way.ado new file mode 100644 index 0000000..ef5ba49 --- /dev/null +++ b/Modules/ado/plus/l/l1way.ado @@ -0,0 +1,92 @@ +*! version 1.1.1 STB-35 sg65 +program define l1way + version 4.0 + local varlist "req ex min(2) max(2)" + local if "opt" + local in "opt" + local weight "aweight" + local options "Center(string) Ems" + parse "`*'" + parse "`varlist'", parse(" ") + local weight "[`weight'`exp']" + local wt : word 2 of `exp' + + tempvar use + quietly { + mark `use' `if' `in' + markout `use' `varlist' `wt' + + preserve + keep if `use' + sort `2' + if "`wt'" == "" { + tempvar Wt + gen byte `Wt' = 1 + local wt "`Wt'" + } + summ `1' `weight' + tempname dft sst msa mse gr + scalar S_1 = _result(1) + scalar `dft' = _result(1) - 1 + scalar `sst' = `dft' * _result(4) + tempvar tt sw xm + gen double `sw' = `wt' in 1 /* sum the weights */ + replace `sw' = cond(`2' > `2'[_n-1], `wt', `sw'[_n-1] + `wt') in 2/l + gen double `xm' = `1' in 1 /* get group means */ + replace `xm' = cond(`2' > `2'[_n-1], `1', /* + */ `xm'[_n-1] + `wt'*(`1'-`xm'[_n-1])/`sw') in 2/l + drop if `2' >= `2'[_n+1] in 1/-2 + + summ `xm' [aw=`sw'] + scalar S_3 = _result(1) - 1 + scalar `msa' = _result(4) * scalar(S_1) / _result(1) + scalar S_2 = scalar(S_3) * `msa' + if "`ems'" != "" { + replace `sw' = sum(`sw'*`sw') + scalar `gr' = (_result(2) - `sw'[_N]/_result(2) )/ scalar(S_3) + } + else { scalar `gr' = scalar(S_1)/_result(1) } + } + scalar S_4 = `sst' - scalar(S_2) + scalar S_5 = `dft' - scalar(S_3) + scalar `mse' = scalar(S_4) / scalar(S_5) + scalar S_6 = `msa' / `mse' + + local lab : variable label `1' + local lbl /* + */ "One Way Analysis of Variance for `1': `lab'" + local indent = int((80-length("`lbl'"))/2) + noisily di _n _skip(`indent') in gr "`lbl'" + noisily di _n in gr /* + */ _col(5) "Source" _col(25) "SS" /* + */ _col(36) "df" _col(44) "MS" /* + */ _col(58) "F" _col(64) "Prob > F" /* + */ _n _dup(72) "-" + noisily di in gr "Between `2'" in yellow /* + */ _col(21) %10.0g scalar(S_2) /* + */ _col(32) %6.0f scalar(S_3) /* + */ _col(41) %10.0g `msa' /* + */ _col(52) %9.2f scalar(S_6) /* + */ _col(66) %6.4f fprob(scalar(S_3), scalar(S_5), scalar(S_6)) + noisily di in gr "Within `2'" in yellow /* + */ _col(21) %10.0g scalar(S_4) /* + */ _col(32) %6.0f scalar(S_5) /* + */ _col(41) %10.0g `mse' /* + */ _n in gr _dup(72) "-" + noisily di in gr "Total" in yellow /* + */ _col(21) %10.0g `sst' /* + */ _col(32) %6.0f `dft' /* + */ _col(41) %10.0g `sst'/`dft' + + scalar `sst' = 1 + if "`center'" == "mean" { scalar `sst' = scalar(S_5)/(scalar(S_5)-2) } + else if "`center'" == "med" { + scalar `sst' = invfprob(scalar(S_3), scalar(S_5), 0.5) + } + scalar `dft' = max(scalar(S_6) - `sst', 0) + global S_1 = `dft' / (`dft' + `sst'* `gr') + global S_2 = `dft' / (`dft' + `sst') + di _new in gr "Intra-`2' r =" in ye %7.4f $S_1 _new in gr /* + */ "Estimated reliability of a `2' mean (n=" in ye %3.2f `gr' in gr /* + */ ") =" in ye %7.4f $S_2 +end diff --git a/Modules/ado/plus/l/l1way.hlp b/Modules/ado/plus/l/l1way.hlp new file mode 100644 index 0000000..cfed556 --- /dev/null +++ b/Modules/ado/plus/l/l1way.hlp @@ -0,0 +1,68 @@ +.- +help for ^iclassr^, ^l1way^ +.- + +One-way ANOVA, random effects, and intra-class correlation [STB-35 sg65] +---------------------------------------------------------- + + ^iclassr^ response_var group_var [weight] [^if^ exp] [^in^ range] + [^, c^enter^(^Fpos^) e^ms ^noi^sily] + + ^l1way^ response_var group_var [weight] [^if^ exp] [^in^ range] + [^, c^enter^(^Fpos^) e^ms] + + +^aweight^s are allowed; see help @weights@. + + +Description +----------- + +^l1way^ and ^iclassr^ estimate one-way analysis of variance (ANOVA) models and use +the random effects ANOVA model to estimate the intra-class (within group) cor- +relation, and the reliability of group averages from the Spearman-Brown proph- +ecy formula. + +^l1way^ and ^iclassr^ are replacements for @loneway@; ^iclassr^ is faster than ^l1way^ +but limited to fewer than 376 values of group_var. Both are substantially fast- +er than ^loneway^, especially ^iclassr^, and both offer more accurate estimation of +the intra-class correlation in unbalanced designs or in weighted analyses; see +the option ^ems^, below. + + +Options +------- + +^center^ chooses a reference point in the F distribution to center the observed + F statistic in estimating the intra-class correlation. The argument Fpos + may be 1 (the default), or "med" or "mean" to choose the median or the mean + of the appropriate F distribution. This option has little effect except in + small samples. + +^ems^ uses the coefficient of the group variance in the expected value of the be- + tween group mean square to scale the estimated intra-class correlation. The + default, for compatibility with ^loneway^, is to use the average group size + instead. This option is ^very^ strongly recommended unless the design is + nearly balanced. + +^noisily^ causes ^iclassr^ to display the ANOVA summary table. + + +Examples +-------- + + . ^iclassr rating stimulus^ (intra-stimulus r, < 376 stimuli, equal n's) + . ^l1way rating stimulus^ (intra-stimulus r, ANOVA table, equal n's) + + . ^iclassr trait family, ems^ (intra-family r, < 376 families, unequal n's) + . ^l1way trait family, e c(med)^ (intra-family r, unequal n's, center the ob- + served F on the median of F) + + +Also see +-------- + + STB: sg65 (STB-35) + Manual: ^[R] loneway, oneway^ +On-line: help for @loneway@, @oneway@ + diff --git a/Modules/ado/plus/l/labbe.ado b/Modules/ado/plus/l/labbe.ado new file mode 100644 index 0000000..17a8a2d --- /dev/null +++ b/Modules/ado/plus/l/labbe.ado @@ -0,0 +1,511 @@ +// program runs old graph command in tandem +// should be able to use other Stata 10 graph options in `options' once removed +// allow labelling of data points? Can extra plots be added? + +*! version 1.22 Sep2003 +*! version 2.01 Jul2008 +*Can add lines corresponding to RR, OR and RD measures. Allows the analyst to see the +*line fitted to the points (p1,p0) +*Also has logit option added + +*2008 update by Ross Harris + +program define labbe +version 8 +syntax varlist(min=4 max=4) [if] [in] /* +*/ [, RR(string) RRN(string) RD(string) OR(string) NULL PERCent noWT XLOg YLOg /* +*/ SAving(string) YLAbel(string) XLAbel(string) YSCale(string) XSCale(string) LOGIT NOLEGend /* +*/ id(varname) CLOCKvar(varname) gap(real 1) textsize(real 1) symbol(string) wgt(varname) * ] + +local lines = 0 +local cmd_legend = "" + +preserve +if "`if'`in'"!="" { + qui keep `if' `in' +} +parse "`varlist'", parse(" ") +tempvar r1 r2 N /* id yrange xrange hsqrwt */ +if ~( `1'>=0 & `2'>=0 & `3'>=0 & `4'>=0 ) { + di in re "Negative cell counts encountered" + exit 198 +} +qui gen `r1'=`1'/(`1'+`2') +qui gen `r2'=`3'/(`3'+`4') +cap assert ((`r1'>=0 & `r1'<=1) | `r1'==.) & ((`r2'>=0 & `r2'<=1 ) | `r2'==. ) +if _rc!=0 { + di in re "Data incorrectly specified" + exit 198 +} +qui gen `N' =`1'+`2'+`3'+`4' +if "`wt'"=="" { + if "`wgt'" != ""{ + local weight "[weight=`wgt']" + } + else{ + local weight "[weight=`N']" + } +} + + +*display logit scale if needed +if "`logit'"!="" { + cap { + assert (`r1'>0) & (`r2'>0) + assert (`r1'<1) & (`r2'<1) + } + if _rc!=0 { + di in re "Non-finite values encountered" + exit + } + qui replace `r1'=log(`r1'/(1-`r1')) + qui replace `r2'=log(`r2'/(1-`r2')) + local subtitl ", logit scale" +} + +label var `r1' "Event rate group 1`subtitl'" +label var `r2' "Event rate group 2`subtitl'" +if strpos("`options'","xtitle(") == 0 & strpos("`options'","ytitle(") == 0{ + local ytitle "Event rate group 1`subtitl'" + local xtitle "Event rate group 2`subtitl'" +} + +if "`percent'"!="" { + if "`logit'"!="" { + di in re "percent option not valid with logit" + exit + } + qui replace `r1'=100*`r1' + qui replace `r2'=100*`r2' + local scale=100 + } + else { + local scale=1 +} + +if ("`xlog'`ylog'"!="") { + if ("`logit'"!="") { + di in re "Cannot use logit and xlog or ylog" + exit + } + if "`rr'`or'`rd'`rrn'"!="" { + di in re "Cannot use rr(), or(), rd() or rrn() with xlog or ylog" + exit + } +} + +if "`xlabel'`ylabel'`yscale'`xscale'"=="" { + local zero=0 + if "`percent'"!="" { + if "`xlog'`ylog'"!="" { + local zero=1 + } + local ylabel "ylabel(`zero',25,50,75,100)" + local xlabel "xlabel(`zero',25,50,75,100)" + } + if "`percent'"=="" & "`logit'"=="" { + if "`xlog'`ylog'"!="" { + local zero=0.01 + } + local ylabel "ylabel(`zero',0.25,0.5,0.75,1)" + local xlabel "xlabel(`zero',0.25,0.5,0.75,1)" + } + if "`percent'"=="" & "`logit'"!="" { +*make own labels if on logit scale + qui sum `r1' + local r1min=r(min) + local r1max=r(max) + qui sum `r2' + local r2min=r(min) + local r2max=r(max) + local lo=min(`r1min',`r2min') + local hi=max(`r1max',`r2max') + local ylabel "ylabel(`lo',`hi')" + local xlabel "xlabel(`lo',`hi')" + } +} + else { + if "`ylabel'"!="" { + local ylabel "ylabel(`ylabel')" + } + if "`xlabel'"!="" { + local xlabel "xlabel(`xlabel')" + } + if "`yscale'"!="" { + local yscale "yscale(range(`yscale'))" + } + if "`xscale'"!="" { + local xscale "xscale(range(`xscale'))" + } +} + +if "`saving'"!="" { + local saving "saving(`saving')" +} +*graph `r1' `r2' `weight' , `options' `xlog' `ylog' `xlabel' `ylabel' `xscale' `yscale' +*gph open, `saving' +*graph +local ay=r(ay) +local by=r(by) +local ax=r(ax) +local bx=r(bx) +local ymax=r(ymax) +local ymin=r(ymin) +local xmax=r(xmax) +local xmin=r(xmin) +local Grmax=min(`ymax', `xmax') +local Grmin=max(`ymin', `xmin') + +local xvals = subinstr("`xlabel'","xlabel(","",.) +local yvals = subinstr("`ylabel'","ylabel(","",.) +local xvals = subinstr("`xvals'",")","",.) +local yvals = subinstr("`yvals'",")","",.) +local xvals2 = subinstr("`xscale'","xscale(range(","",.) +local yvals2 = subinstr("`yscale'","yscale(range(","",.) +local xvals2 = subinstr("`xvals2'","))","",.) +local yvals2 = subinstr("`yvals2'","))","",.) + +// need to find graph widths etc. manually +qui summ `r1' +local ymin = r(min) +local ymax = r(max) +if "`yvals'" != ""{ + local ymin = min(`ymin',`yvals') + local ymax = max(`ymax',`yvals') +} +if "`yvals2'" != ""{ + local ymin = min(`ymin',`yvals2') + local ymax = max(`ymax',`yvals2') +} +qui summ `r2' +local xmin = r(min) +local xmax = r(max) +if "`xvals'" != ""{ + local xmin = min(`xmin',`xvals') + local xmax = max(`xmax',`xvals') +} +if "`xvals2'" != ""{ + local xmin = min(`xmin',`xvals2') + local xmax = max(`xmax',`xvals2') +} +local aspect = (`ymax'-`ymin')/(`xmax'-`xmin') + +*trap errors :RR, OR,RRN need to be positive; RD in range -1 to 1 +local flag= 0 + +*gph font 300 200 +if "`xlog'"!="" { + local xlog "log" +} +if "`ylog'"!="" { + local ylog "log" +} + +if "`null'"!="" { +*Draw null line + if `ymin' < `xmin'{ + local Axco0 = `xmin' + local Ayco0 = `xmin' + } + else{ + local Axco0 = `ymin' + local Ayco0 = `ymin' + } + if `ymax' > `xmax'{ + local Axco1 = `xmax' + local Ayco1 = `xmax' + } + else{ + local Axco1 = `ymax' + local Ayco1 = `ymax' + } + local cmd_null = "(scatteri `Ayco0' `Axco0' `Ayco1' `Axco1', recast(line) lpattern(dash) lcolor(gs6))" + local lines = `lines'+1 + local q = char(34) + local cmd_legend = "`cmd_legend' `lines' "+ `"`q'"' + "Null" + `"`q'"' + +} + +if "`or'"!="" & "`logit'"=="" { + *gph pen 5 + parse "`or'", parse(",") + while "`1'"!="" { + local or_gph=`1' + if (`or_gph'<=0 ) { + local flag=10 + } + else { + if `ymin' > `scale'*(`or_gph'*`xmin'/(`scale'*1-`xmin'+(`or_gph'*`xmin'))) { + local yco0=`ymin' + local xco0=`ymin'/(`scale'*`or_gph'+`ymin'-`ymin'*`or_gph') + } + else { + local yco0=`scale'*`or_gph'*`xmin'/(`scale'*1-`xmin'+(`or_gph'*`xmin')) + local xco0=`xmin' + } + local Ayco0=`ay'*`yco0' + `by' + local Axco0=`ax'*`xco0' + `bx' + if `xmax' < (`scale'*`ymax'/(`scale'*`or_gph'+`ymax'-(`or_gph'*`ymax'))) { + local cgermax = `xmax' + } + else { + local cgermax = (`scale'*`ymax'/(`scale'*`or_gph'+`ymax'-(`or_gph'*`ymax'))) + } + local cger=`xco0' + while `cger'<=`cgermax' { + local cger = `cger'+`scale'*0.005 + local tger = `scale'*`or_gph'*`cger'/(`scale'*1-`cger'+(`or_gph'*`cger')) + local Ayco1= `ay'*`tger'+`by' + local Axco1= `ax'*`cger'+`bx' + local sub_cmds "`sub_cmds' `tger' `cger'" + local Ayco0=`Ayco1' + local Axco0=`Axco1' + } + local cmd_or "(scatteri `sub_cmds', recast(line) lcolor(maroon))" + local lines = `lines'+1 + local q = char(34) + local cmd_legend = `"`cmd_legend'"' + " `lines' " + `"`q'"' + "Odds ratio" + `"`q'"' + } + mac shift 2 + } +} + +if "`or'"!="" & "`logit'"!="" { + *gph pen 9 + parse "`or'", parse(",") + while "`1'"!="" { + if (`1'<=0 ) { + local flag=10 + } + else { + local or_lgph=log(`1') + if `ymin' > `xmin'+`or_lgph' { + local yco0=`ymin' + local xco0=`ymin'-`or_lgph' + } + else { + local yco0=`xmin'+`or_lgph' + local xco0=`xmin' + } + if `ymax' >`xmax'+`or_lgph' { + local yco1=`xmax'+`or_lgph' + local xco1=`xmax' + } + else { + local yco1=`ymax' + local xco1=`ymax'-`or_lgph' + } + local Ayco0=`ay'*`yco0' + `by' + local Axco0=`ax'*`xco0' + `bx' + local Ayco1=`ay'*`yco1' + `by' + local Axco1=`ax'*`xco1' + `bx' + if ( (`ymax'>`yco0') & (`xmax'>`xco0') & (`ymin'<`yco1') & (`xmin'<`xco1') ) { + *gph line `Ayco0' `Axco0' `Ayco1' `Axco1' + local cmd_or2 = "(scatteri `yco0' `xco0' `yco1' `xco1', recast(line) lcolor(maroon))" + local lines = `lines'+1 + local q = char(34) + local cmd_legend = `"`cmd_legend'"' + " `lines' " + `"`q'"' + "Odds ratio" + `"`q'"' + } + } + mac shift 2 + } +} + +if "`rr'"!="" { + if "`logit'"!="" { + di in re "rr option not valid with logit" + exit + } + *gph pen 6 + parse "`rr'", parse(",") + while "`1'"!="" { + local rr_gph=`1' + if (`rr_gph'<=0 ) { + local flag=10 + } + else { + if `ymin' > `rr_gph'*`xmin' { + local yco0=`ymin' + local xco0=`ymin'/`rr_gph' + } + else { + local yco0=`rr_gph'*`xmin' + local xco0=`xmin' + } + if `ymax' > `rr_gph'*`xmax' { + local yco1=`rr_gph'*`xmax' + local xco1=`xmax' + } + else { + local yco1=`ymax' + local xco1=`ymax'/`rr_gph' + } + local Ayco0=`ay'*`yco0' + `by' + local Axco0=`ax'*`xco0' + `bx' + local Ayco1=`ay'*`yco1' + `by' + local Axco1=`ax'*`xco1' + `bx' + if ( (`ymax'>`yco0') & (`xmax'>`xco0') & (`ymin'<`yco1') & (`xmin'<`xco1') ) { + *gph line `Ayco0' `Axco0' `Ayco1' `Axco1' + local cmd_rr = "(scatteri `yco0' `xco0' `yco1' `xco1', recast(line) lcolor(dkgreen))" + local lines = `lines'+1 + local q = char(34) + local cmd_legend = `"`cmd_legend'"' + " `lines' " + `"`q'"' + "Risk ratio" + `"`q'"' + } + } + mac shift 2 + } +} + +if "`rrn'"!="" { + if "`logit'"!="" { + di in re "rrn option not valid with logit" + exit + } + *gph pen 7 + parse "`rrn'", parse(",") + while "`1'"!="" { + local rrn_gph=`1' + if (`rrn_gph'<=0 ) { + local flag=10 + } + else { + if `ymin' > (`scale'*(1 -`rrn_gph') + `rrn_gph'*`xmin') { + local yco0=`ymin' + local xco0=(`ymin'+`scale'*(`rrn_gph'-1))/`rrn_gph' + } + else { + local yco0=`scale'*(1-`rrn_gph') + `rrn_gph'*`xmin' + local xco0=`xmin' + } + if `ymax' >(`scale'*(1-`rrn_gph') + `rrn_gph'*`xmax' ) { + local yco1=`scale'*(1-`rrn_gph') + `rrn_gph'*`xmax' + local xco1=`xmax' + } + else { + local yco1=`ymax' + local xco1=(`ymax'+`scale'*(`rrn_gph'-1))/`rrn_gph' + } + local Ayco0=`ay'*`yco0' + `by' + local Axco0=`ax'*`xco0' + `bx' + local Ayco1=`ay'*`yco1' + `by' + local Axco1=`ax'*`xco1' + `bx' + if ( (`ymax'>`yco0') & (`xmax'>`xco0') & (`ymin'<`yco1') & (`xmin'<`xco1') ) { + *gph line `Ayco0' `Axco0' `Ayco1' `Axco1' + local cmd_rrn = "(scatteri `yco0' `xco0' `yco1' `xco1', recast(line) lcolor(ltgreen))" + local lines = `lines'+1 + local q = char(34) + local cmd_legend = `"`cmd_legend'"' + " `lines' " + `"`q'"' + "Risk ratio (non-event)" + `"`q'"' + } + } + mac shift 2 + } +} + +if "`rd'"!="" { + if "`logit'"!="" { + di in re "rd option not valid with logit" + exit + } + *gph pen 8 + parse "`rd'", parse(",") + while "`1'"!="" { + local rd_gph=`1' + if (`rd_gph'<=-1 | `rd_gph'>=1 ) { + local flag=10 + } + else { + if `ymin' > `xmin'+`scale'*`rd_gph' { + local yco0=`ymin' + local xco0=`ymin'-`scale'*`rd_gph' + } + else { + local yco0=`xmin'+`scale'*`rd_gph' + local xco0=`xmin' + } + if `ymax' >`xmax'+`rd_gph' { + local yco1=`xmax'+`scale'*`rd_gph' + local xco1=`xmax' + } + else { + local yco1=`ymax' + local xco1=`ymax'-`scale'*`rd_gph' + } + local Ayco0=`ay'*`yco0' + `by' + local Axco0=`ax'*`xco0' + `bx' + local Ayco1=`ay'*`yco1' + `by' + local Axco1=`ax'*`xco1' + `bx' + if ( (`ymax'>`yco0') & (`xmax'>`xco0') & (`ymin'<`yco1') & (`xmin'<`xco1') ) { + *gph line `Ayco0' `Axco0' `Ayco1' `Axco1' + local cmd_rd = "(scatteri `yco0' `xco0' `yco1' `xco1', recast(line) lcolor(olive))" + local lines = `lines'+1 + local q = char(34) + local cmd_legend = `"`cmd_legend'"' + " `lines' " + `"`q'"' + "Risk difference" + `"`q'"' + } + } + mac shift 2 + } +} + +*gph close +if `flag'>1 { + display _n "Note: some effect sizes are outside valid ranges" +} + +// RJH EDIT +// sort out xlabel etc. later + +local xlabel = subinstr("`xlabel'", "," ," " ,.) +local ylabel = subinstr("`ylabel'", "," ," " ,.) +local q = char(34) +local l2 = `lines'+1 +local cmd_legend = `"`cmd_legend'"' + " `l2' " + `"`q'"' + "Studies" + `"`q'"' +if `"`cmd_legend'"' != ""{ + local cmd_legend = "legend(order(" + `"`cmd_legend'"' + ") span)" +} +if "`nolegend'" != "" | (`lines' == 2 & "`null'" != "") | (`lines'<=1){ + local cmd_legend = "legend(off)" +} + +if "`id'" != ""{ + tempvar clockVar + local lsize = min(`textsize'*30/_N,2) + qui gen `clockVar' = `r2'<`r1' + qui replace `clockVar' = 3+`clockVar'*6 + if "`clockvar'" != ""{ + qui replace `clockVar' = `clockvar' if `clockvar' < . // user defined + } + tempvar r11 r22 radians + qui summ `N' + qui gen `radians' = (`clockVar'/12)*2*_pi + if `gap' == 0{ + local gap = 0.0001 + } + local invgap = 17/`gap' // smaller means more gap + qui gen `r11' = `r1' + `N'/r(max)*((`ymax'-`ymin')/`invgap')*cos(`radians') + qui gen `r22' = `r2' + `N'/r(max)*((`xmax'-`xmin')/`invgap')*sin(`radians') + + local cmd_lab "(scatter `r11' `r22', msymbol(none) mlabel(`id') mlabvposition(`clockVar') mlabcolor(black) mlabsize(`lsize'))" +} + +if "`symbol'" == ""{ + local s2 = "circle_hollow" +} +else{ + local s2 = "`symbol'" +} +if "`weight'" == ""{ + qui replace `r22' = `r2' + qui replace `r11' = `r1' + if "`symbol'" == ""{ + local s2 = "default" + } +} + +qui twoway `cmd_null' `cmd_or' `cmd_or2' `cmd_rr' `cmd_rrn' `cmd_rd' /// + (scatter `r1' `r2' `weight', msymbol(`s2') mcolor(navy)) `cmd_lab' /// + , `options' `xlog' `ylog' `xlabel' `ylabel' `xscale' `yscale' /// + `cmd_legend' xtitle("`xtitle'") ytitle("`ytitle'") aspect(`aspect') + +restore +end + diff --git a/Modules/ado/plus/l/labbe.dlg b/Modules/ado/plus/l/labbe.dlg new file mode 100644 index 0000000..6e64018 --- /dev/null +++ b/Modules/ado/plus/l/labbe.dlg @@ -0,0 +1,180 @@ +/* + +*! laabe dialog version 1.0.2, 3 Jun 2003, T. J. Steichen, steichen@triad.rr.com +*! for laabe version 1.21 24 Mar 2003 M. J. Bradburn, mike.bradburn@cancer.org.uk + +L'abbe Graph +------------ + +Syntax: labbe varlist [if exp] [in range] [weight] , [ nowt percent + or(#,...,#) rr(#,...,#) rd(#,...,#) rrn(#,...,#) null logit graph options ] + +To install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "Metan-based L'abbe Graph (&labbe)" "db labbe" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. + +*/ + +VERSION 8.0 + +INCLUDE _std_small +INCLUDE header + +HELP hlp1, view("help metan") +RESET res1, label("Reset") + +DIALOG main, label("labbe 1.21 - Metan-based L'abbe Graph") tabtitle("Main") +BEGIN + TEXT tx_binary 10 5 330 ., /// + label("Vars for Counts a, b, c, d, in that order") + VARLIST vl_binary @ _ss @ ., /// + label("Vars for a, b, c, d") + +/* end vars */ + + CHECKBOX cb_nowt 10 50 130 ., /// + label("Symbols not sized") /// + option("nowt") + + CHECKBOX cb_percent 10 70 130 ., /// + label("Event Rates in %") /// + option("percent") + + CHECKBOX cb_null 10 100 130 ., /// + label("Draw p1=p2 line") /// + option("null") + + CHECKBOX cb_logit 10 130 130 ., /// + label("Use logit scale") /// + option("logit") + +/* end switches */ + + GROUPBOX gb_lines 170 48 175 108, /// + label("Draw Lines at:") + + CHECKBOX cb_or 180 +20 80 ., /// + label("OR: (>0)") /// + onclickon(program or_on) /// + onclickoff(script or_off) + EDIT ed_or 265 @ 70 ., /// + label("or") /// + option("or") + + CHECKBOX cb_rd 180 +20 80 ., /// + label("RD: (-1,1)") /// + onclickon(script rd_on) /// + onclickoff(program rd_off) + EDIT ed_rd 265 @ 70 ., /// + label("rd") /// + option("rd") + + CHECKBOX cb_rr 180 +20 80 ., /// + label("RR: (>0)") /// + onclickon(script rr_on) /// + onclickoff(program rr_off) + EDIT ed_rr 265 @ 70 ., /// + label("rr") /// + option("rr") + + CHECKBOX cb_rrn 180 +20 80 ., /// + label("RRN: (>0)") /// + onclickon(script rrn_on) /// + onclickoff(program rrn_off) + EDIT ed_rrn 265 @ 70 ., /// + label("rrn") /// + option("rrn") + +/* end sets */ + + GROUPBOX gb_gopts7 10 155 330 _ht1h, /// + label("Allowed Graph7 Options:") + EDIT ed_gopts7 15 175 320 ., /// + label("Graph7 Options") + +/* end Graph7 opts */ + +END + +INCLUDE ifin +INCLUDE weights_a + +PROGRAM or_on +BEGIN + call main.ed_or.enable + if !(main.cb_rd | main.cb_rr | main.cb_rrn) { + call main.cb_logit.enable + } +END + +SCRIPT or_off +BEGIN + main.ed_or.disable + main.cb_logit.setoff + main.cb_logit.disable +END + +SCRIPT rd_on +BEGIN + main.ed_rd.enable + main.cb_logit.setoff + main.cb_logit.disable +END + +PROGRAM rd_off +BEGIN + call main.ed_rd.disable + if main.cb_or & !(main.cb_rr | main.cb_rrn) { + call main.cb_logit.enable + } +END + +SCRIPT rr_on +BEGIN + main.ed_rr.enable + main.cb_logit.setoff + main.cb_logit.disable +END + +PROGRAM rr_off +BEGIN + call main.ed_rr.disable + if main.cb_or & !(main.cb_rd | main.cb_rrn) { + call main.cb_logit.enable + } +END + +SCRIPT rrn_on +BEGIN + main.ed_rrn.enable + main.cb_logit.setoff + main.cb_logit.disable +END + +PROGRAM rrn_off +BEGIN + call main.ed_rrn.disable + if main.cb_or & !(main.cb_rd | main.cb_rr) { + call main.cb_logit.enable + } +END + +PROGRAM command +BEGIN + put "labbe " + varlist main.vl_binary + INCLUDE _weights_pr + INCLUDE _ifin_pr + beginoptions + option main.cb_nowt + option main.cb_percent + option main.cb_null + option main.cb_logit + optionarg main.ed_or + optionarg main.ed_rd + optionarg main.ed_rr + optionarg main.ed_rrn + put main.ed_gopts7 + endoptions +END diff --git a/Modules/ado/plus/l/labbe.hlp b/Modules/ado/plus/l/labbe.hlp new file mode 100644 index 0000000..4e3c125 --- /dev/null +++ b/Modules/ado/plus/l/labbe.hlp @@ -0,0 +1,2 @@ +.h metan + diff --git a/Modules/ado/plus/l/lclist.ado b/Modules/ado/plus/l/lclist.ado new file mode 100644 index 0000000..c9ed98d --- /dev/null +++ b/Modules/ado/plus/l/lclist.ado @@ -0,0 +1,32 @@ +program def lclist, rclass +*! NJC 1.0.0 29 June 2000 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax , [ Global(str) Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tokenize `list' + + while "`1'" != "" { + if length("`1'") > 80 { + di in r "cannot handle word length > 80" + exit 498 + } + local 1 = lower("`1'") + local newlist "`newlist'`1' " + mac shift + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/l/lclist.hlp b/Modules/ado/plus/l/lclist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/l/lclist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/l/lconfa.mlib b/Modules/ado/plus/l/lconfa.mlib new file mode 100644 index 0000000..c57bfeb Binary files /dev/null and b/Modules/ado/plus/l/lconfa.mlib differ diff --git a/Modules/ado/plus/l/leastlikely.ado b/Modules/ado/plus/l/leastlikely.ado new file mode 100644 index 0000000..0124551 --- /dev/null +++ b/Modules/ado/plus/l/leastlikely.ado @@ -0,0 +1,66 @@ +*! 1.0.2 - 9/28/02 - Jeremy Freese +capture program drop leastlikely +program define leastlikely + version 7.0 + + syntax [varlist(default=none)] [if] [in] [, n(integer 5) Generate(string) *] + + if "`e(cmd)'"=="clogit" | "`e(cmd)'"=="nlogit" | "`e(cmd)'"=="xtlogit" | /* + */ "`e(cmd)'"=="blogit" | "`e(cmd)'"=="bprobit" | "`e(cmd)'"=="glogit" | /* + */ "`e(cmd)'"=="gprobit" { + di _n as err "leastlikely not intended for use after `e(cmd)'" + exit 198 + } + + local erase "no" + tempname values prob touse + local depvar = "`e(depvar)'" + local depvarlabel : value label `depvar' + if "`generate'"=="" { + local generate "Prob" + local erase "yes" + } + quietly { + gen `touse' = e(sample) `if' `in' + gen `prob' = . + tabulate `depvar' if e(sample)==1, matrow(`values') + local temp : rownames `values' + local numcats : word count `temp' + forvalues i = 1(1)`numcats' { + local value`i' = `values'[`i', 1] + } + local isbin "no" + if `numcats'==2 & `value1'==0 & `value2'==1 { local isbin "yes" } + if "`isbin'" == "yes" { + tempname temp + predict `temp', p + replace `prob' = `temp' if `depvar'==1 & `touse'==1 + replace `prob' = (1-`temp') if `depvar'==0 & `touse'==1 + } + if "`isbin'" == "no" { + forvalues i = 1(1)`numcats' { + tempname temp + predict `temp', outcome(`value`i'') + replace `prob' = `temp' if `depvar'==`value`i'' & `touse'==1 + } + } + gen `generate' = `prob' + } + + forvalues i = 1(1)`numcats' { + local vallabel "" + if "`depvarlabel'"!="" { + local vallabel : label `depvarlabel' `value`i'' + if "`vallabel'"!="" { local vallabel = "(`vallabel')" } + } + di _n as txt "Outcome: " as res `value`i'' " `vallabel'" + + tempname temp + quietly egen `temp' = rank(`generate') if `depvar'==`value`i'' & `touse'==1, track + list `generate' `varlist' if `temp'<=`n' , `options' + } + + if "`erase'"=="yes" { drop `generate' } + +end + diff --git a/Modules/ado/plus/l/leastlikely.hlp b/Modules/ado/plus/l/leastlikely.hlp new file mode 100644 index 0000000..46171b4 --- /dev/null +++ b/Modules/ado/plus/l/leastlikely.hlp @@ -0,0 +1,85 @@ +{smcl} +{* 19nov2002}{...} +{hline} +help for {hi:leastlikely}{right:(SJ2-4: st0022_1)} +{hline} + +{title:List least likely observations} + +{p 8 13}{cmd:leastlikely} [{it:varlist}] [{cmd:if} {it:exp}] +[{cmd:in} {it:range}] +[{cmd:,} {cmd:n(}{it:#}{cmd:)} {cmdab:g:enerate(}{it:varname}{cmd:)} +[{cmdab:no:}]{cmdab:d:isplay} {cmdab:nol:abel} {cmdab:noo:bs} +{cmdab:do:ublespace}] + + +{title:Description} + +{p 4 4 2}For regression models for categorical dependent variables, +{cmd:leastlikely} lists the in-sample observations with the lowest +predicted probabilities of observing the outcome value that was +actually observed. For example, in a model with a binary dependent +variable, {cmd:leastlikely} lists the observations that have the lowest +predicted probability of {it:depvar=0} among those cases for which +{it:depvar=0}, and it lists the observations that have the lowest predicted +probability of {it: depvar=1} among those cases for which {it:depvar=1}. The +least likely values represent relatively deviant cases that may warrant +closer inspection. + +{p 4 4 2}{cmd:leastlikely} works with estimation commands for models of binary +outcomes in which option {cmd:p} after {cmd:predict} provides the predicted +probability of a positive outcome (e.g., {cmd:logit}, {cmd:probit}), but the +dependent variable must be coded as 0 and 1. Likewise, {cmd:leastlikely} +works with estimation commands for models of ordinal or nominal outcomes +in which option {cmd:outcome(}{it:#}{cmd:)} after {cmd: predict} provides the +predicted probability of outcome {it:#}. Exceptions are commands in which the +predicted probabilities are probabilities within groups or panels or for +"blocked" data; {cmd:leastlikely} will produce an error message if executed +after {cmd:blogit}, {cmd:bprobit}, {cmd:clogit}, {cmd:glogit}, +{cmd:gprobit}, {cmd:nlogit}, or {cmd:xtlogit}. + +{p 4 4 2}{cmd:leastlikely} lists the observation number and the +predicted probability (as Prob or as the variable name specified by the +{cmd:generate} option). Values of variables in {it:varlist} will also be +specified. + + +{title:Options} + +{p 4 8 2}{cmd:n(}{it:#}{cmd:)} specifies the number of observations to be listed +for each outcome. The default is 5. If multiple observations have the same +probabilities, more than the specified number will be listed to include all +of them. + +{p 4 8 2}{cmd:generate(}{it:varname}{cmd:)} specifies that the probabilities +of observing the outcome value that was observed should be stored in +{it:varname}. If not specified, the variable name {cmd:Prob} will be created +but dropped after the output is produced. + +{p 4 8 2}[{cmd:no}]{cmd:display} forces the format into {cmd:display} or +tabular ({cmd:nodisplay}) format. If you do not specify one of these two +options, then Stata chooses one based on its judgment of which would be most +readable. + +{p 4 8 2}{cmd:nolabel} causes the numeric codes rather than the label values +to be displayed. + +{p 4 8 2}{cmd:noobs} suppresses printing of the observation numbers. + +{p 4 8 2}{cmd:doublespace} produces a blank line between each observation in +the listing when in {cmd:nodisplay} mode; it has no effect in {cmd:display} +mode. + + +{title:Examples} + +{p 4 8 2}{cmd:. logit low age lwt race2 race3 smoke ptl ht ui}{p_end} +{p 4 8 2}{cmd:. leastlikely}{p_end} +{p 4 8 2}{cmd:. leastlikely age lwt, n(10) g(prob)}{p_end} + + +{title:Author} + + {browse "mailto:jfreese@ssc.wisc.edu":Jeremy Freese} + Department of Sociology, + University of Wisconsin-Madison diff --git a/Modules/ado/plus/l/listblck.ado b/Modules/ado/plus/l/listblck.ado new file mode 100644 index 0000000..d0f1612 --- /dev/null +++ b/Modules/ado/plus/l/listblck.ado @@ -0,0 +1,117 @@ +*! 1.0.0 10nov1998 Jeroen Weesie/ICS +program define listblck + version 6 + local dwidth : set display linesize + + syntax [varlist] [if] [in], [Repeat(int 0) Width(int `dwidth') noObs noLabel] + + * adjust width for displaying the observation numbers + if "`obs'" == "" { + local replen 3 + } + else { + local obs noobs + local replen -2 + } + + * repvar = list of repeated variables + * replen = total display width of repeated variables + tokenize `varlist' + local i 1 + while `i' <= `repeat' { + local repvar "`repvar' `1'" + widthvar `1' + local replen = `replen' + 2 + r(width) + local i = `i'+1 + mac shift + } + + local vlen `replen' + local vlist `repvar' + + while "`1'" ~= "" { + * ensured that at least one non-repeated variable is displayed! + widthvar `1' + local len1 = r(width) + if `vlen' + 2 + `len1' + 1 >= `dwidth' { + * display block + * di in gr _dup(`vlen') "-" + list `vlist' `in' `if', nodisplay `obs' `label' + + * start new block + local vlist "`repvar' `1'" + local vlen = `replen' + 2 + `len1' + } + else { + * add `1' to vlist + local vlist "`vlist' `1'" + local vlen = `vlen' + 2 + `len1' + } + mac shift + } + + * don't forget to display relast block + if "`vlist'" ~= "" { + *di in gr _dup(`vlen') "-" + list `vlist' `in' `if', nodisplay `obs' `label' + } + + * clear S_* macros + global S_1 +end + +program define widthvar, rclass + args v + local f : format `v' + local x : display `f' (`v'[1]) + return scalar width = length("`x'") +end +exit + +* code for version 5 +* returns in S_1 the display width of a variable in list-output +program define widthvar + args var vlab + + local fmt : format `var' + local pf = substr("`fmt'",-1,1) /* last char of display format */ + + if "`pf'" == "s" { + * string + local len1 = substr("`fmt'",2,length("`fmt'")-2) + } + else if "`pf'" == "d" { + * date, determine display width of "31 December 1960" + local d : display `fmt' 365 + local len1 = length("`d'") + } + else { + * numeric variable + local pp = index("`fmt'", ".") + if `pp' > 0 { + local len1 = substr("`fmt'",2,`pp'-2) + } + else local len1 = substr("`fmt'",2,length("`fmt'")-2) + + if "`vlab'" ~= "" { + * width is at least 8 if value-labeled + local vl : value label `var' + if "`vl'" ~= "" { local len1 = max(8,`len1') } + } + } + *global S_1 = max(length("`var'"), `len1') + global S_1 `len1' +end +exit + +Description + +list-like command that repeats list's with blocks of variables rather +than wrapping lines or using "display" mode. If the option -repeate- +is specified, the first k variable in varlist are repeated in each +block. + +Assumptions: + list leaves one space after observation numbers + list leaves 2 space between variables + list does not widen columns for long variables names diff --git a/Modules/ado/plus/l/listblck.hlp b/Modules/ado/plus/l/listblck.hlp new file mode 100644 index 0000000..fec950f --- /dev/null +++ b/Modules/ado/plus/l/listblck.hlp @@ -0,0 +1,59 @@ +.- +help for ^listblck^ [jw] Nov 10, 1998 +.- + +Block-wise display of values of variables +----------------- ------------------------ + + ^listblck^ [varlist] [^if^ exp] [^in^ range] + [^, r^epeat^(^#^) w^idth^(^#^) nol^abel ^noo^bs] + + +Description +----------- + +^listblck^ is an alternative to ^list^ that displays the values of variables +in varlist for selected cases in an "blocks-of-variables" format. If no varlist +is specified, the values of all the variables are displayed. + + +Options +------- + +^repeat(^#^)^ specifies the number of leading variables repeated at the + beginning of each block. Defaults to 0. + +^width(^#^)^ specifies the display linesize. By default, ^listblck^ uses the + current setting of ^display linesize^. + +^nol^abel causes the numeric codes rather than label values to be displayed. + +^noo^bs suppresses printing of the observation numbers. + + +Examples +-------- + + . ^listblck^ + . ^listblck make price turn length^ + . ^listblck make price turn length trunk mpg foreign in 1/20, rep(1)^ + + +Author +------ + + Jeroen Weesie + Dept of Sociology + Utrecht University + J.weesie@@fss.uu.nl + +This project was supported by grant PGS 50-370 of the Netherlands Organization +for Scientific Research. + + +Also See +-------- + + Manual: ^[R] list^ +On-line: help on @list@, @listby@, @stlist@, and @xtlist@ + diff --git a/Modules/ado/plus/l/listcoef.ado b/Modules/ado/plus/l/listcoef.ado new file mode 100644 index 0000000..c7542b7 --- /dev/null +++ b/Modules/ado/plus/l/listcoef.ado @@ -0,0 +1,1684 @@ +*! version 1.9.4 2012-07-25 bug in mprobit noted; format fix + +capture program drop listcoef +program define listcoef, rclass + + version 9 // 2007-06-29 + * 15Jun2005 - new labels used in Stata 9 + if c(stata_version) >= 9 { + tempname tmpb + mat `tmpb' = e(b) + local tmpcut : colnames `tmpb' + if index("`tmpcut'", "_cut1") != 0 { + local cut "_" + } + else { + local cut "/" + } + } + else { + local cut "_" + } + + version 6.0 + tempname b b1 b12 b2 bnocon bnocon2 bout bs bs2 bsx bsx2 bsy + tempname bsy2 btmp con2 conp2 contst2 dft eb eb2 + tempname bx ebx ebx2 enf factr lc lnalpha lr nobs nxtrow nxtsdx o + tempname one outb outb2 outbs outbsx outbsy outcon outeb outeb2 outebx + tempname outebx2 outmat outp outp2 outpb outpb2 outpbx outpbx2 outsdx + tempname outse outvx outz outz2 p p2 pb pb2 pbx pbx2 pct pctsd pcutoff + tempname prntit r2 rec_se resvec sd sd2 sdb sdb2 sdx sdx2 sdy sdyobs + tempname sdystar se st talpha v vare vi vx vx2 z zval zval2 + tempname mconb mcontz mconp + + local noprint = "yes" /* keeps track if no results are printed */ + local cmd "`e(cmd)'" + + capture version 7 + if _rc!=0 { + local vers7 "no" + local smcl "" + local dash "-" + local vline "|" + local plussgn "+" + local topt "-" + local bottomt "-" + } + else { + local vers7 "yes" + local smcl "in smcl " + local dash "{c -}" + local vline "{c |}" + local plussgn "{c +}" + local topt "{c TT}" + local bottomt "{c BT}" + } + version 6.0 + + if "`cmd'" == "" { + di _n in y "listcoef "/* + */ in r "must be run after your regression model is estimated." + exit + } + + syntax [varlist(default=none)] /* + */ [, PValue(real 0) Factor Percent Matrix Help /* + */ Constant Odds Std Reverse gt lt ADJacent NOLabel EXpand /* + */ Delta(real 1)] + +*-> define characteristics of each model to be listed +* +* coeftyp: which types of coefficients can be computed +* - bx beta x std +* - by beta y std +* - bxy beta xy std +* - eb exp(beta) +* - ebx exp(beta x std) +* - %b % +* - %bx % xstd +* - byopt +* modltyp: model class +* - tdist: use t not z for p-values +* - count: count model +* - zero: zero-inflated model +* - ystar: latent dependent variable +* - ystd: +* - special: own loop for calculating odds/std coefs +* - nosdx: do not report sdx +* - nocon: do not allow constant option +* defhead: default header type +* - std +* - odds +* - count + + if "`cmd'" == "regress" { + local coeftyp "bx by bxy" + local modltyp "tdist ystd" + local defhead "std" + } + if "`cmd'" == "logit" | "`cmd'" == "logistic" /* + */ | "`cmd'" == "ologit" { + local coeftyp "eb ebx byopt %b %bx bx by bxy" + local modltyp "ystar ystd reverse" + local defhead "odds" + } + if "`cmd'" == "probit" | "`cmd'" == "oprobit" { + local coeftyp "bx by bxy" + local modltyp "ystar ystd" + local defhead "std" + } + if "`cmd'" == "cloglog" { + local coeftyp "bx" + local modltyp "" + local defhead "std" + } + if "`cmd'" == "mlogit" { + local coeftyp "eb ebx byopt %b %bx" + local modltyp "special nocon" + local defhead "odds" + } + * 28Feb2005 + if "`cmd'" == "mprobit" { +di in red "Note: We are currently fixing a bug with mprobit. Contact" +di in red "jslong@indiana.edu for details." +exit + local coeftyp "bx" + local modltyp "special nocon" + local defhead "std" + } + * 23Mar2005 + if "`cmd'" == "slogit" { + local coeftyp "eb ebx byopt %b %bx" // no bx?? + local modltyp "nocon" + local defhead "odds" + + * do not allow if more than 1 dimension + if e(k_dim) != 1 { + di as err "listcoef only works for the one dimensional model slogit model" + exit + } + * outcome categories must not have skips + tempname slcat + mat `slcat' = e(outcomes) + local slncat = e(k_out) + local c1 = `slcat'[1,1] + foreach i of numlist 2/`slncat' { + local c1p1 = `c1' + 1 + local c2 = `slcat'[`i',1] + if `c2'!=`c1p1' { + di as err /// + "listcoef with slogit does not allows skips in outcome categories." + exit + } + local c1 = `c2' + } + } + + if "`cmd'" == "clogit" | "`cmd'" == "rologit" { + local coeftyp "eb byopt %b" + local modltyp "nosdx nocon reverse" + local defhead "odds" + } + if "`cmd'" == "tobit" | "`cmd'" == "cnreg" /* + */ | "`cmd'" == "intreg" { + local coeftyp "bx by bxy" + local modltyp "tdist ystar ystd" + local defhead "std" + } + *050207 - ztp and ztnb + * if "`cmd'" == "poisson" | "`cmd'" == "nbreg" { + if "`cmd'" == "poisson" | "`cmd'" == "nbreg" /// + | "`cmd'" == "ztp" | "`cmd'" == "ztnb" { + local coeftyp "eb ebx byopt %b %bx" + local modltyp "count" + local defhead "count" + } + if "`cmd'" == "zip" | "`cmd'" == "zinb" { + local coeftyp "eb ebx byopt %b %bx" + local modltyp "count zero" + local defhead "count" + } + + * exit out of non-supported commands + if "`coeftyp'" == "" { + di _n in r "listcoef does not work with models estimated with `e(cmd)'" + exit + } + + * 050123 contant in model? + _penocon + local isnocon = r(nocon) + +*-> unpack coeftyp + + local defopt = "yes" + local countto : word count `coeftyp' + local count = 1 + while `count' <= `countto' { + local token : word `count' of `coeftyp' + if "`token'" == "bx" { local dobx "`defopt'" } + if "`token'" == "by" { local doby "`defopt'" } + if "`token'" == "bxy" { local dobxy "`defopt'" } + if "`token'" == "%b" { local dopb "`defopt'" } + if "`token'" == "%bx" { local dopbx "`defopt'" } + if "`token'" == "eb" { local doeb "`defopt'" } + if "`token'" == "ebx" { local doebx "`defopt'" } + if "`token'" == "byopt" { local defopt "option" } + local count = `count' + 1 + } + +*-> parse options and check for errors + + local opterr "no" + if "`std'" == "std" { + if "`dobx'"=="option" { local dobx "yes" } + else if "`dobx'" == "" { local opterr "std" } + if "`doby'"=="option" { local doby "yes" } + if "`dobxy'"=="option" { local dobxy "yes" } + if "`cmd'" == "ologit" { local defhead "std" } + * if std, don't list these + local doeb "" + local doebx "" + local dopb "" + local dopbx "" + } + + if "`percent'" == "percent" & "`factor'" == "factor" { + di in r "options " in y "percent" in r " and " in y "factor" /* + */ in r " cannot both be specified together" + exit 198 + } + if "`std'" == "std" & "`factor'" == "factor" { + di in r "options " in y "std" in r " and " in y "factor" /* + */ in r " cannot both be specified together" + exit 198 + } + if "`std'" == "std" & "`percent'" == "percent" { + di in r "options " in y "std" in r " and " in y "percent" /* + */ in r " cannot both be specified together" + exit 198 + } + if "`percent'" == "percent" { + if "`dopb'"=="option" { + local dopb "yes" + if "`doeb'"=="yes" { local doeb "" } + } + else if "`dopb'" == "" { local opterr "percent" } + if "`dopbx'"=="option" { + local dopbx "yes" + if "`doebx'"=="yes" { local doebx "" } + } + } + if "`factor'" == "factor" { + if "`doeb'"=="option" { + local doeb "yes" + if "`dopb'"=="yes" { local dopb "" } + } + else if "`doeb'" == "" { local opterr "odds" } + if "`doebx'"=="option" { + local doebx "yes" + if "`dopbx'"=="yes" { local dopbx "" } + } + } + if "`opterr'" != "no" { + di in r "option " in y "`opterr'" in r " not allowed after " in y "`cmd'" + exit 198 + } + +*-> unpack mldtyp: define what to do for each type of model + + if index("`modltyp'", "tdist") == 0 { local tz "z" } + else { local tz "t" } + if index("`modltyp'", "count") == 0 { local iscount "no" } + else { local iscount "yes" } + if index("`modltyp'", "zero") == 0 { local iszero "no" } + else { local iszero "yes" } + if index("`modltyp'", "ystar") == 0 { local isystar "no" } + else { local isystar "yes" } + if index("`modltyp'", "ystd") == 0 { local isystd "no" } + else { local isystd "yes" } + if index("`modltyp'", "special") == 0 { local isspec "no" } + else { local isspec "yes" } + if index("`modltyp'", "nosdx") == 0 { local isnosdx "no" } + else { local isnosdx "yes" } + if index("`modltyp'", "nocon") == 0 { local iscon "yes" } + else { local iscon "no" } + if index("`modltyp'", "reverse") == 0 { local isrev "no" } + else { local isrev "yes" } + + if "`constant'"!="" & "`iscon'"=="no" { + di in y "constant" in r " option not allowed for this model" + exit 198 + } + if "`reverse'"!="" & "`isrev'"=="no" { + di in y "reverse" in r " option not allowed for this model" + exit 198 + } + +*-> add checks for any special cases + + * zip/zinb only work with logit inflation + if "`cmd'"=="zip" | "`cmd'"=="zinb" { + if "`e(inflate)'"!="logit" { + di _n in y "listcoef " in r "requires " in y "logit " /* + */ in r "inflation for " in y "`cmd'" + exit 198 + } + } + +*-> get basic model information + + scalar `nobs' = e(N) + local lhsnm "`e(depvar)'" + * -intreg- has two lhs vars; select only 1st one + if "`cmd'"=="intreg" { + local lhsnm2 : word 2 of `lhsnm' + local lhsnm : word 1 of `lhsnm' + } + + * information on rhs variables + _perhs + local rhsnam "`r(rhsnms)'" + local rhsnum "`r(nrhs)'" + + if "`iszero'"=="yes" { + local rhsnam2 "`r(rhsnms2)'" + local rhsnum2 "`r(nrhs2)'" + } + + * information on outcome categories + _pecats + + local ncats = r(numcats) + if "`cmd'"=="logit" | "`e(cmd)'"=="logistic" | "`e(cmd)'"=="clogit" { + local nm1 : word 2 of `r(catnms8)' + local nm2 : word 1 of `r(catnms8)' + } + * >m & <=m for ologit + if "`cmd'" == "ologit" { + local nm1 ">m" + local nm2 "<=m" + } + + * 16Jun2005 - ranked ahead and ranked behind for rologit + if "`cmd'" == "rologit" { + local nm1 "ranked ahead" + local nm2 "ranked behind" + } + + * 05Apr2005 - grab all needed info about slogit + version 9 + if "`cmd'" == "slogit" { + * grab information about current model + tempname slb slV slbeta slphi sltheta slcatnum slthetaV + local slnvars = e(df_m) // # of rhs variables + mat `slb' = e(b) + mat `slV' = e(V) + local slncat = e(k_out) + local slncatm1 = e(k_out) - 1 + local slnphi = e(k_out) - 1 + local slntheta = `slnphi' + local slrefnum = e(i_base) // number of reference category + local slrefnm `e(out`slrefnum')' + * which row in e(outcomes)? + mat `slcatnum' = e(outcomes) // values for categories regardless of base + mat `slcatnum' = `slcatnum'' + local slrefrow = 0 + foreach i of numlist 1/`slncat' { + local cati = `slcatnum'[1,`i'] + if `slrefnum'==`cati' { + local slrefrow = `i' + } + } + * if 1 is reference then from category is 2 + local slfromnum = 1 + if `slrefnum'==1 { + local slfromnum = 2 + } + local slfromnm `e(out`slfromnum')' + mat `slbeta' = `slb'[1,1..`slnvars'] + mat `slphi' = e(b) + mat `slphi' = `slphi'[1,`slnvars'+1..`slnvars'+`slncatm1'],(0) + mat `sltheta' = e(b) + mat `sltheta' = `sltheta'[1,`slnvars'+`slncatm1'+1..`slnvars'+2*`slncatm1'],(0) + mat `slthetaV' = `slV'[`slnvars'+`slncatm1'+1..`slnvars'+2*`slncatm1',.] + mat `slthetaV' = `slthetaV'[.,`slnvars'+`slncatm1'+1..`slnvars'+2*`slncatm1'] + * get theta# and phi#_# names + local slphinm : coleq `slphi' + local slthetanm : coleq `sltheta' + * local slphifull : colfullnames slphi + * local slphinm : colnames slphi + * basecategory for which phi=0 and theta=0 + *local nm2 "`slrefnm'" + local nm1 "`slrefnm'" // 10Aug2005 + * comparison category for beta's + *local nm1 "`slfromnm'" + local nm2 "`slfromnm'" // 10Aug2005 + } // getting slogit information + version 6 + + if "`reverse'"!="" { + local temp "`nm1'" + local nm1 "`nm2'" + local nm2 "`temp'" + } + + * category labels for mlogit, mprobit + if "`cmd'" == "mlogit" /// + | "`cmd'" == "mprobit" { + local catnm `r(catnms8)' /* names of categories, ref is last name */ + local catnums `r(catvals)' + * 24Feb2005 + if "`nolabel'"=="nolabel" { + local catnm `catnums' + } + local refcat = r(refval) /* number of reference category */ + local refnm : word `ncats' of `catnm' + } + + * information about weights + if "`e(wtype)'"=="iweight" { + di _n in r "cannot use " in y "listcoef" /* + */ in r " for models with iweights" + exit 198 + } + local wtis "" + if "`e(wtype)'"!="" { + local wtis "[`e(wtype)'`e(wexp)']" + } + if "`e(wtype)'"=="pweight" { + local wtis "[aweight`e(wexp)']" + di in blu "(pweights not compatible with " in y "summarize" /* + */ in blu "; weights will be treated as aweights)" + } + * information about b + + * v1.8.4 code + * if "`e(cmd)'"=="mlogit" { + * nobreak { + * version 5.0 + * mat `b' = e(b) + * mat `v' = e(V) + * } + * version 6.0 + * } + + * 2009-10-07 1.9.0 use ben jann's _get_mlogit_bv + * for stata 11 return of b and V + if "`e(cmd)'"=="mlogit" { + _get_mlogit_bv `b' `v' + } + else if "`e(cmd)'"=="mprobit" { + nobreak { + * reshape matrix b + tempname bold vold + mat `bold' = e(b) + mat `v' = e(V) + local rows = e(k_out)-1 + local cells = colsof(`bold') + local cols = `cells'/`rows' + mat `b' = J(`rows', `cols', 0) + local i = 1 + forvalues r = 1(1)`rows' { + local rownames = "`rownames' y`r'" + forvalues c = 1(1)`cols' { + mat `b'[`r', `c'] = `bold'[1, `i'] + local i = `i' + 1 + } + } + local colnames : colnames `bold' + local colnames : list uniq colnames + mat rownames `b' = `rownames' + mat colnames `b' = `colnames' + } // nobreak + } + else { + mat `b' = e(b) + local nb = colsof(`b') + mat `sdb' = e(V) + mat `sdb' = vecdiag(`sdb') + mat `bnocon' = `b'[1,1..`rhsnum'] /* trim off _con */ + mat coleq `bnocon' = _ + * 050123 old code: if "`iscon'"=="yes" + * if model estimated w/o constant, same as iscon==yes + if "`iscon'"=="yes" & `isnocon'!=1 { + * get constants + mat `mconb' = `b'[1,`rhsnum'+1..`rhsnum'+`ncats'-1] + mat `mcontz' = `mconb' + mat `mconp' = `mconb' + local i = 1 + while `i' < `ncats' { + mat `mcontz'[1,`i'] = `mconb'[1,`i'] / /* + */ sqrt(`sdb'[1,`rhsnum'+`i']) + if "`tz'"=="t" { + scalar `dft' = `nobs'-e(df_m)-1 + mat `mconp'[1,`i'] = tprob(`dft',-abs(`mcontz'[1,`i'])) + } + else { mat `mconp'[1,`i'] = 2*normprob(-abs(`mcontz'[1,`i'])) } + local i = `i' + 1 + } + } /* is a constant */ + } /* is not mlogit */ + + * coefficients for 2nd equation for -zip- & -zinb- + if "`iszero'"=="yes" { + scalar `con2' = `b'[1,`rhsnum'+2+`rhsnum2'] + scalar `contst2' = `con2'/sqrt(`sdb'[1,`rhsnum'+2+`rhsnum2']) + scalar `conp2' = 2*normprob(-abs(`contst2')) + mat def `bnocon2' = `b'[1,(`rhsnum'+2)..(`rhsnum'+`rhsnum2'+1)] + mat coleq `bnocon2' = _ + mat def `sdb2' = `sdb'[1,(`rhsnum'+2)..(`rhsnum'+`rhsnum2'+1)] + _pesum `wtis' if e(sample)==1,two + mat `sd2' = r(Ssd) + mat `sd2' = `sd2'[1,2...] /* trim off lhs variable */ + } + + * sd_x and sdy + _pesum `wtis' if e(sample) == 1 + mat `sd' = r(Ssd) + scalar `sdy' = `sd'[1,1] + scalar `sdyobs' = `sdy' + mat `sd' = `sd'[1,2...] /* trim off lhs variable */ + +*-> parse varlist + + * prnlist is list and order of variables to print + * prnnums is number of variable in matrices + if "`varlist'" == "" { + local prnlist "`rhsnam'" + local count = 1 + while `count' <= `rhsnum' { + local prnnums "`prnnums' `count'" + local count = `count' + 1 + } + if "`iszero'"=="yes" { + local prnlis2 "`rhsnam2'" + local count = 1 + while `count' <= `rhsnum2' { + local prnnum2 "`prnnum2' `count'" + local count = `count' + 1 + } + } + } + * if varlist specified, print output in varlist order + else { + local count = 1 + local countto : word count `varlist' + tokenize `varlist' + while `count' <= `countto' { + local count2 = 1 + local found = "no" + while `count2' <= `rhsnum' { + local rhstmp : word `count2' of `rhsnam' + if "``count''" == "`rhstmp'" { + local prnlist "`prnlist' `rhstmp'" + local prnnums "`prnnums' `count2'" + local found = "yes" + } + local count2 = `count2' + 1 + } + if "`iszero'"=="yes" { + local count2 = 1 + while `count2' <= `rhsnum2' { + local rhstmp : word `count2' of `rhsnam2' + if "``count''" == "`rhstmp'" { + local prnlis2 "`prnlis2' `rhstmp'" + local prnnum2 "`prnnum2' `count2'" + local found = "yes" + } + local count2 = `count2' + 1 + } + } + if "`found'" == "no" { + di in y "``count'' " in r "is not an independent variable" + exit 198 + } + local count = `count' + 1 + } + } /* if a varlist has been specified */ + +*-> parse pvalue option + + sca `pcutoff' = `pvalue' + * allow pcutoff(5) to represent pcutoff(.05) + if `pcutoff' >= 1 & `pcutoff' <= 100 { sca `pcutoff' = `pcutoff' / 100 } + if `pcutoff' == 0 { sca `pcutoff' = 1.00 } + if `pcutoff' < 0 | `pcutoff' > 1 { + di in y "pvalue()" in r " must be valid nonzero probability" + exit 198 + } + +*** Start if not special case ************************************** + if "`isspec'"=="no" { /* only if not special cases */ + +*-> compute sd(y*) + + if "`isystar'"=="yes" { + * get cov(rhs) for computing var(y*) + quietly mat accum `vx' = `lhsnm' `rhsnam' `wtis' if e(sample)==1/* + */ `in', deviations noconstant + mat `vx' = `vx'[2...,2...] /* trim off lhs variable */ + scalar `factr' = 1/(`nobs'-1) /* 1 over nobs - 1 */ + mat `vx' = `factr' * `vx' + mat def `sdystar' = `bnocon' * `vx' + mat `sdystar' = `sdystar' * `bnocon'' + mat `vare' = J(1,1,1) /* default for probit */ + scalar `factr' = 1 +* 1.9.2 if "`e(cmd)'"=="logit" | "`e(cmd)'"=="ologit" { + * 1.9.3 + if "`e(cmd)'"=="logit" | "`e(cmd)'"=="ologit" /* + */ | "`cmd'" == "logistic" { + scalar `factr' = (_pi*_pi)/3 + } + if "`e(cmd)'"=="tobit" | "`e(cmd)'"=="intreg" | "`e(cmd)'"=="cnreg" { + scalar `factr' = `b'[1,(`rhsnum'+2)]*`b'[1,(`rhsnum'+2)] + } + mat `vare' = `factr' * `vare' + mat `sdystar' = `sdystar' + `vare' + scalar `sdy' = sqrt(`sdystar'[1,1]) + } + +*-> compute standardized coefficients, t's, z's and p's + + local nx = colsof(`sd') + mat `bsy' = `bnocon' + mat `bsx' = `bnocon' + mat `bs' = `bnocon' + mat `eb' = `bnocon' + mat `ebx' = `bnocon' + mat `pb' = `bnocon' + mat `pbx' = `bnocon' + mat `zval' = `bnocon' + mat `p' = `bnocon' + scalar `factr' = 1/`sdy' + mat `bsy' = `factr' * `bsy' /* y-standardized betas */ + + * loop through x's + local i = 1 + while `i'<=`nx' { + mat `sdb'[1,`i'] = sqrt(`sdb'[1,`i']) /* sd of b's */ + scalar `sdx' = `sd'[1,`i'] + * 13Apr2005 delta - change by delta, not 1 sd + if `delta'!=1 { + scalar `sdx' = `delta' + } + mat `bsx'[1,`i'] = `bnocon'[1,`i']*`sdx' /* b*sd_x */ + mat `bs'[1,`i'] = `bsy'[1,`i']*`sdx' /* b*sd_x/sd_y) */ + scalar `b1' = `b'[1,`i'] + * factor change + mat `eb'[1,`i'] = exp(`b1') + mat `ebx'[1,`i'] = exp(`b1'*`sdx') + * percent change + mat `pb'[1,`i'] = (exp(`b1')-1)*100 + mat `pbx'[1,`i'] = (exp(`b1'*`sdx')-1)*100 + if "`reverse'"!="" { + * factor change + mat `eb'[1,`i'] = 1/exp(`b1') + mat `ebx'[1,`i'] = 1/exp(`b1'*`sdx') + * percent change + mat `pb'[1,`i'] = ((1/exp(`b1'))-1)*100 + mat `pbx'[1,`i'] = ((1/exp(`b1'*`sdx'))-1)*100 + } + * z, t, and p + mat `zval'[1,`i'] = `bnocon'[1,`i']/`sdb'[1,`i'] /* t/z of b */ + if "`tz'"=="t" { + scalar `dft' = `nobs'-e(df_m)-1 + mat `p'[1,`i'] = tprob(`dft',-abs(`zval'[1,`i'])) + } + else { mat `p'[1,`i'] = 2*normprob(-abs(`zval'[1,`i'])) } + local i=`i'+1 + } + + * coefficients for -zip- and -zinb- + if "`iszero'"=="yes" { + mat `zval2' = `bnocon2' + mat `p2' = `bnocon2' + mat def `eb2' = `bnocon2' + mat def `ebx2' = `bnocon2' + mat def `pb2' = `bnocon2' + mat def `pbx2' = `bnocon2' + local nx2 = colsof(`sd2') + local i = 1 + while `i'<=`nx2' { + mat `sdb2'[1,`i'] = sqrt(`sdb2'[1,`i']) /* sd of b's */ + mat `zval2'[1,`i'] = `bnocon2'[1,`i']/`sdb2'[1,`i'] + mat `p2'[1,`i'] = 2*normprob(-abs(`zval2'[1,`i'])) + mat `eb2'[1,`i'] = exp(`bnocon2'[1,`i']) + mat `ebx2'[1,`i'] = exp(`bnocon2'[1,`i']*`sd2'[1,`i']) + mat `pb2'[1,`i'] = (exp(`bnocon2'[1,`i'])-1)*100 + mat `pbx2'[1,`i'] = (exp(`bnocon2'[1,`i']*`sd2'[1,`i'])-1)*100 + local i=`i'+1 + } + } + +*-> Print Headers + + di _n in g "`cmd' (N=" in y `nobs' in g "): " _c + * header for std results + if "`defhead'"=="std" | "`std'"=="std" { + di in g "Unstandardized and Standardized Estimates " _c + if `pcutoff' < 1 & `pcutoff' >= .01 { + di in g "when P>|`tz'| < " in y %3.2f `pcutoff' _c + } + else if `pcutoff' < .01 & `pcutoff' > 0 { + di in g "when P>|`tz'| < " in y `pcutoff' _c + } + di + } + * header for odds or count outcomes + else { + local header "Factor" + if "`percent'" == "percent" { local header "Percentage" } + if "`defhead'"=="odds" | "`factor'"=="factor" { + di in g "`header' Change in Odds " _c + if `pcutoff' < 1 & `pcutoff' >= .01 { + di in g "when P>|`tz'| < " in y %3.2f `pcutoff' _c + } + if `pcutoff' < .01 & `pcutoff' > 0 { + di in g "when P>|`tz'| < " in y `pcutoff' _c + } + di + } + else if "`defhead'"=="count" { + di in g "`header' Change in Expected Count " _c + if `pcutoff' < 1 & `pcutoff' >= .01 { + di in g "when P>|`tz'| < " in y %3.2f `pcutoff' _c + } + if `pcutoff' < .01 & `pcutoff' > 0 { + di in g "when P>|`tz'| < " in y `pcutoff' _c + } + di + } + } + + * print lhs exception for intreg + if "`cmd'"=="intreg" { + di _n in gr " LHS vars: " in y "`e(depvar)'" _c + } + + * list sdy's or contrast for odds + if ("`defhead'"=="std" | "`std'"=="std") | ("`defhead'"=="count") { + di _n in gr " Observed SD: " in y `sdyobs' + if "`isystar'"=="yes" { di in g " Latent SD: " in y `sdy' } + } + + * sd of error + if "`cmd'" == "regress" { + di in gr " SD of Error: " in y e(rmse) + } + if "`cmd'" == "tobit" | "`cmd'" == "cnreg" | "`cmd'" == "intreg" { + local sde = `b'[1,`rhsnum'+2] + di in gr " SD of Error: " in y `sde' + } + + if "`defhead'"=="odds" | "`factor'"=="factor" { + di _n in g " Odds of: " in y "`nm1'" in g " vs " in y "`nm2'" + } + + if "`iszero'"=="yes" { + local header "Factor" + if "`percent'" == "percent" { local header "Percentage" } + di _n in g "Count Equation: `header' Change in Expected " /* + */ "Count for Those Not Always 0" + } + +*-> Print Header for Columns + + local head2 " b `tz' P>|`tz'|" + + * 13Apr2005 + if `delta'!=1 { // delta option + if "`dobx'"=="yes" { local head2 "`head2' bDeltaX" } + if "`doby'"=="yes" { local head2 "`head2' bStdY" } + if "`dobxy'"=="yes" { local head2 "`head2' bDeltaStdY" } + if "`doeb'"=="yes" { local head2 "`head2' e^b " } + if "`doebx'"=="yes" { local head2 "`head2' e^bDelta" } + if "`dopb'"=="yes" { local head2 "`head2' % " } + if "`dopbx'"=="yes" { local head2 "`head2' %StdX" } + if "`doby'"=="yes" { // std coef + if "`isnosdx'"!="yes" { local head2 "`head2' Delta" } + } + else { // e(b) + if "`isnosdx'"!="yes" { local head2 "`head2' Delta" } + } + } + else{ // no delta option + if "`dobx'"=="yes" { local head2 "`head2' bStdX" } + if "`doby'"=="yes" { local head2 "`head2' bStdY" } + if "`dobxy'"=="yes" { local head2 "`head2' bStdXY" } + if "`doeb'"=="yes" { local head2 "`head2' e^b " } + if "`doebx'"=="yes" { local head2 "`head2' e^bStdX" } + if "`dopb'"=="yes" { local head2 "`head2' % " } + if "`dopbx'"=="yes" { local head2 "`head2' %StdX" } + if "`isnosdx'"!="yes" { local head2 "`head2' SDofX" } + } + + local todup = length("`head2'") + di in g `smcl' _n _dup(13) "`dash'" "`topt'" _dup(`todup') "`dash'" + *added for stata 7 compatibility + if "`vers7'"=="yes" { local lhsnm = abbrev("`lhsnm'", 12) } + * no lhs for for intreg + if "`cmd'"=="intreg" { di in g _col(14) `smcl' "`vline'`head2'" } + else { di in g %12s "`lhsnm'" _col(14) `smcl' "`vline'`head2'" } + di in g `smcl' _dup(13) "`dash'" "`plussgn'" _dup(`todup') "`dash'" + +*-> Print Coefficients + + tokenize `prnnums' + local count = 1 + while "``count''" != "" { + local indx: word `count' of `prnnums' + local vname: word `count' of `prnlist' + *added for stata 7 compatibility + if "`vers7'"=="yes" { local vname = abbrev("`vname'", 12) } + if `p'[1, `indx']<`pcutoff' { + local noprint "no" + di in g `smcl' %12s "`vname'" in g _col(14) "`vline'" in y /* + */ %10.5f `bnocon'[1,`indx'] %9.3f `zval'[1,`indx'] /* + */ %8.3f `p'[1,`indx'] _c + if "`dobx'" == "yes" { di %9.4f `bsx'[1,`indx'] _c } + if "`doby'" == "yes" { di %9.4f `bsy'[1,`indx'] _c } + if "`dobxy'" == "yes" { di %9.4f `bs'[1,`indx'] _c } + if "`doeb'" == "yes" { di %9.4f `eb'[1,`indx'] _c } + if "`doebx'" == "yes" { di %9.4f `ebx'[1,`indx'] _c } + if "`dopb'" == "yes" { di %9.1f `pb'[1,`indx'] _c } + if "`dopbx'" == "yes" { di %9.1f `pbx'[1,`indx'] _c } + + * 13Apr2005 + if `delta'!=1 { // delta option + if "`isnosdx'"!="yes" { + di %11.4f `delta' + } + else { + di + } /* need to advance to next line if isnosdx */ + } + else { // no delta option + if "`isnosdx'"!="yes" { + di %11.4f `sd'[1,`indx'] + } + else { + di + } /* need to advance to next line if isnosdx */ + } + + * enter values in matrices to be returned + if "`matrix'"!="" { + matrix `nxtrow' = `bnocon'[1, `indx'] + matrix rownames `nxtrow' = `vname' + matrix `outb' = (nullmat(`outb') \ `nxtrow') + matrix `outz' = (nullmat(`outz') \ `zval'[1,`indx']) + matrix `outp' = (nullmat(`outp') \ `p'[1, `indx']) + matrix `outsdx' = (nullmat(`outsdx') \ `sd'[1, `indx']) + if "`dobx'" == "yes" { + mat `outbsx' = (nullmat(`outbsx') \ `bsx'[1,`indx']) } + if "`doby'" == "yes" { + mat `outbsy' = (nullmat(`outbsy') \ `bsy'[1,`indx']) } + if "`dobxy'" == "yes" { + mat `outbs' = (nullmat(`outbs') \ `bs'[1,`indx']) } + if "`doeb'" == "yes" { + mat `outeb' = (nullmat(`outeb') \ `eb'[1,`indx']) } + if "`doebx'" == "yes" { + mat `outebx' = (nullmat(`outebx') \ `ebx'[1,`indx']) } + if "`dopb'" == "yes" { + mat `outpb' = (nullmat(`outpb') \ `pb'[1,`indx']) } + if "`dopbx'" == "yes" { + mat `outpbx' = (nullmat(`outpbx') \ `pbx'[1,`indx']) } + } + } /* if `p'[1, `indx']<`pcutoff' */ + + local count = `count' + 1 + + } /* loop through varlist: while "``count''" != "" */ + + if "`constant'"=="constant" & "`iscon'"=="yes" { + if `ncats'==2 { + di in g `smcl' %12s "_cons" in g _col(14) "`vline'" in y %10.5f /* + */ `mconb'[1,1] %9.3f `mcontz'[1,1] %8.3f `mconp'[1,1] + if "`matrix'"!="" { + return scalar cons = `mconb'[1,1] + return scalar cons_z = `mcontz'[1,1] + return scalar cons_p = `mconp'[1,1] + } + } + else { + di in g `smcl' _dup(13) "`dash'" "`plussgn'" _dup(`todup') "`dash'" + local i = 1 + while `i' < `ncats' { + local cnm "`cut'cut" + di in g `smcl' %12s "`cnm'`i'" in g _col(14) "`vline'" in y /* + */ %10.5f `mconb'[1,`i'] %9.3f `mcontz'[1,`i'] /* + */ %8.3f `mconp'[1,`i'] + local i = `i' + 1 + } + } /* more than one constant */ + } + + * alpha for neg bin models + *if "`e(cmd)'"=="nbreg" | "`e(cmd)'"=="zinb" { + if "`cmd'"=="zinb" | "`cmd'"=="nbreg" /// + | "`cmd'"=="ztnb" { + di in g `smcl' _dup(13) "`dash'" "`plussgn'" _dup(`todup') "`dash'" + sca `lnalpha' = `b'[1,`nb'] + quietly _diparm lnalpha, exp label("alpha") noprob + di `smcl' in g " ln alpha" _col(14) "`vline'" /* + */ in y %10.5f `lnalpha' + di `smcl' in g " alpha" _col(14) "`vline'" /* + */ in y %10.5f r(est) in g " SE(alpha) = " in y %-9.5f r(se) + } + + * 3/24/05 - phi and theta for slogit models + if "`e(cmd)'" == "slogit" { + + * change to -version 9- (slogit introduced with v9) + version 9 + tempname b V + mat `b' = e(b) + mat `V' = e(V) + + * print phis + di in g `smcl' _dup(13) "`dash'" "`plussgn'" _dup(`todup') "`dash'" + forvalues num = 1(1)`slnphi' { + tempname phi Vphi sdphi zphi pphi + sca `phi' = `b'[1, `i'] // grab phi + local phinm : word `num' of `slphinm' + sca `Vphi' = `V'[`i', `i'] + sca `sdphi' = sqrt(`Vphi') + sca `zphi' = `phi'/`sdphi' + sca `pphi' = 2*normprob(-abs(`zphi')) + di as txt %12s "`phinm'" _col(14) "`vline'" as res %10.5f `phi' /// + %9.3f `zphi' %8.3f `pphi' + local i = `i' + 1 + } + + * print thetas + di in g `smcl' _dup(13) "`dash'" "`plussgn'" _dup(`todup') "`dash'" + forvalues num = 1(1)`slntheta' { + tempname thetamat theta thetaVmat thetaV thetasd thetaz thetap + local thetanm : word `num' of `slthetanm' + sca `theta' = `sltheta'[1,`num'] + sca `thetaV' = `slthetaV'[`num',`num'] + sca `thetasd' = sqrt(`thetaV') + sca `thetaz' = `theta' / `thetasd' + sca `thetap' = 2*normprob(-abs(`thetaz')) + di as txt %12s "`thetanm'" _col(14) "`vline'" as res %10.5f `theta' /// + %9.3f `thetaz' %8.3f `thetap' + local i = `i' + 1 + } + * change back to -version 6- + version 6 + } // end slogit - non expanded output + + * bottom border + di in g `smcl' _dup(13) "`dash'" "`bottomt'" _dup(`todup') "`dash'" + + * LR test: code based on nbreg.ado version 3.3.9 06dec2000 + *050207 + if "`e(cmd)'"=="nbreg" | "`cmd'" == "ztnb" { + if ((e(chi2_c) > 0.005) & (e(chi2_c)<1e4)) | (ln(e(alpha)) < -20) { + local fmt "%-8.2f" + } + else local fmt "%-8.2e" + tempname pval + scalar `pval' = chiprob(1, e(chi2_c))*0.5 + if ln(e(alpha)) < -20 { scalar `pval'= 1 } + di in g `smcl' " LR test of alpha=0: " /* + */ in y `fmt' e(chi2_c) in g " Prob>=LRX2 = " in y %5.3f /* + */ `pval' + di in g `smcl' _dup(14) "`dash'" _dup(`todup') "`dash'" + } + } /* if "`isspec'"=="no" */ +*** End if not special case ************************************** + + +*-> special model--mlogit + + if "`cmd'" == "mlogit" { + di _n in g "`cmd' (N=" in y `nobs' in g "): " _c + local pcttext "Factor" + if "`percent'" == "percent" { local pcttext = "Percentage" } + di in g "`pcttext' Change in the Odds of " in y "`lhsnm' " _c + if `pcutoff' < 1 & `pcutoff' >= .01 { + di in g "when P>|z| < " in y %3.2f `pcutoff' _c + } + if `pcutoff' < .01 & `pcutoff' > 0 { + di in g "when P>|z| < " in y `pcutoff' _c + } + di + tokenize "`prnnums'" + local count = 1 + while "``count''" != "" { + + local ivar = "``count''" + scalar `sdx' = `sd'[1,`ivar'] + local vname: word `ivar' of `rhsnam' + di _n in g "Variable: " in y "`vname' " /* + * 1.6.7 jsl 1/3/2004 + */ in g "(sd=" in y `sdx' in g ")" + * 1.6.6: in g "(sd=" in y %8.2g `sdx' in g ")" + local head2 " b z P>|z|" + if "`doeb'" == "yes" { local head2 "`head2' e^b " } + else { local head2 "`head2' % " } + if "`doebx'" == "yes" { local head2 "`head2' e^bStdX" } + else { local head2 "`head2' %StdX" } + local todup = length("`head2'") + * 1.8.0 + di _n in g `smcl' %-18s "Odds comparing" _col(19) "`vline'" + * 2008-06-15 missing " + di in g `smcl' %-18s "Alternative 1" _col(19) "`vline'" + di in g `smcl' %-18s "to Alternative 2" _col(19) "`vline'`head2'" + di in g `smcl' _dup(18) "`dash'" "`plussgn'" _dup(`todup') "`dash'" + * loop through all contrasts + local i1 1 + local i2 1 + while `i1' <= `ncats' { + local num1 : word `i1' of `catnums' + local name1 : word `i1' of `catnm' + while `i2' <= `ncats' { + * get betas for i1 and i2, zero if refcat + if `i1'==`ncats' { scalar `b1' = 0 } + else { scalar `b1' = `b'[`i1',`ivar'] } + if `i2'==`ncats' { scalar `b2' = 0 } + else { scalar `b2' = `b'[`i2',`ivar'] } + scalar `b12' = `b1'-`b2' + scalar `eb' = exp(`b12') + scalar `ebx' = exp(`b12'*`sdx') + scalar `pb' = (`eb'-1)*100 + scalar `pbx' = (`ebx'-1)*100 + local l2 = ((`i2'-1)*(`rhsnum'+1))+`ivar' + if `i1'!=`ncats' & `i2' == `ncats' { + local l1 = ((`i1'-1)*(`rhsnum'+1))+`ivar' + scalar `se' = sqrt(`v'[`l1',`l1']) + } + if `i1'!=`ncats' & `i2' != `ncats' { + local l1 = ((`i1'-1)*(`rhsnum'+1))+`ivar' + scalar `se' = sqrt(`v'[`l1',`l1'] + /* + */ `v'[`l2',`l2'] - 2*`v'[`l1',`l2']) + } + if `i1'==`ncats' & `i2' != `ncats' { + scalar `se' = sqrt(`v'[`l2',`l2']) + } + + scalar `rec_se' = 1/`se' + scalar `z' = `rec_se'*`b12' + scalar `p' = 2*normprob(-abs(`z')) + if `p' <= `pcutoff' { + local noprint = "no" + * get outcome value of second outcome + local num2: word `i2' of `catnums' + local name2 : word `i2' of `catnm' + if "`matrix'"!="" { + matrix `nxtrow' = `b12' + matrix rownames `nxtrow' = `vname' + matrix `outb' = (nullmat(`outb') \ `nxtrow') + matrix `outcon' = (nullmat(`outcon') /* + */ \ `num1', `num2') + matrix `outsdx' = (nullmat(`outsdx') \ `sdx') + matrix `outeb' = (nullmat(`outeb') \ `eb') + matrix `outebx' = (nullmat(`outebx') \ `ebx') + matrix `outpb' = (nullmat(`outpb') \ `pb') + matrix `outpbx' = (nullmat(`outpbx') \ `pbx') + matrix `outz' = (nullmat(`outz') \ `z') + matrix `outp' = (nullmat(`outp') \ `p') + matrix `outse' = (nullmat(`outse') \ `se') + } /* matrix */ + + * 050110 jsl gt option & adjacent + if ("`gt'"!="gt" & "`lt'"!="lt") /* + */ | ("`gt'"=="gt") & (`num1'>`num2') /* + */ | ("`lt'"=="lt") & (`num1'<`num2') { + local absdif = abs(`num1'-`num2') + if ("`adjacent'"=="adjacent" & `absdif'==1) /* + */ | "`adjacent'"!="adjacent" { + di in g `smcl' "`name1'" _col(9) /* + */ "-`name2'" _col(19) "`vline'" in y /* + */ %10.5f `b12' %9.3f `z' /* + */ %8.3f `p' _c + if "`doeb'" == "yes" { di %9.4f `eb' _c } + else { di %9.1f `pb' _c } + if "`doebx'" == "yes" { di %9.4f `ebx' } + else { di %9.1f `pbx' } + } /* adjacent option */ + } /* gt lt option */ + } /* `p' <= `pcutoff' */ + local i2 = `i2' + 1 + if `i1' == `i2' { local i2 = `i2' + 1 } + } /* while `i2' <= `ncats' */ + local i2 1 + local i1 = `i1' + 1 + } /* i1 */ + + di in g `smcl' _dup(18) "`dash'" "`bottomt'" _dup(`todup') "`dash'" + local count = `count' + 1 + } /* while count */ + + } /* if "`cmd'" == "mlogit" */ + +*-> special model--mprobit + + if "`cmd'" == "mprobit" { + + di _n in g "`cmd' (N=" in y `nobs' in g "): " _c + + di in g "Unstandardized and Standardized Estimates for " in y "`lhsnm' " _c + if `pcutoff' < 1 & `pcutoff' >= .01 { + di in g "when P>|z| < " in y %3.2f `pcutoff' _c + } + if `pcutoff' < .01 & `pcutoff' > 0 { + di in g "when P>|z| < " in y `pcutoff' _c + } + di + tokenize "`prnnums'" + local count = 1 + while "``count''" != "" { + + local ivar = "``count''" + scalar `sdx' = `sd'[1,`ivar'] + local vname: word `ivar' of `rhsnam' + di _n in g "Variable: " in y "`vname' " /* + */ in g "(sd=" in y `sdx' in g ")" + local head2 " b z P>|z| bStdX" + local todup = length("`head2'") + di _n in g `smcl' %18s "Comparing " _col(19) "`vline'" + di in g `smcl' %18s "Group 1 vs Group 2" _col(19) "`vline'`head2'" + di in g `smcl' _dup(18) "`dash'" "`plussgn'" _dup(`todup') "`dash'" + + * loop through all contrasts + local i1 1 + local i2 1 + while `i1' <= `ncats' { + local num1 : word `i1' of `catnums' + local name1 : word `i1' of `catnm' + while `i2' <= `ncats' { + * get betas for i1 and i2, zero if refcat + if `i1'==`ncats' { scalar `b1' = 0 } + else { scalar `b1' = `b'[`i1',`ivar'] } + if `i2'==`ncats' { scalar `b2' = 0 } + else { scalar `b2' = `b'[`i2',`ivar'] } + + scalar `b12' = `b1'-`b2' + scalar `bx' = `b12'*`sdx' + local l2 = ((`i2'-1)*(`rhsnum'+1))+`ivar' + if `i1'!=`ncats' & `i2' == `ncats' { + local l1 = ((`i1'-1)*(`rhsnum'+1))+`ivar' + scalar `se' = sqrt(`v'[`l1',`l1']) + } + if `i1'!=`ncats' & `i2' != `ncats' { + local l1 = ((`i1'-1)*(`rhsnum'+1))+`ivar' + scalar `se' = sqrt(`v'[`l1',`l1'] + /* + */ `v'[`l2',`l2'] - 2*`v'[`l1',`l2']) + } + if `i1'==`ncats' & `i2' != `ncats' { + scalar `se' = sqrt(`v'[`l2',`l2']) + } + + scalar `rec_se' = 1/`se' + scalar `z' = `rec_se'*`b12' + scalar `p' = 2*normprob(-abs(`z')) + + if `p' <= `pcutoff' { + local noprint = "no" + * get outcome value of second outcome + local num2: word `i2' of `catnums' + local name2 : word `i2' of `catnm' + if "`matrix'"!="" { + matrix `nxtrow' = `b12' + matrix rownames `nxtrow' = `vname' + matrix `outb' = (nullmat(`outb') \ `nxtrow') + matrix `outcon' = (nullmat(`outcon') /* + */ \ `num1', `num2') + matrix `outsdx' = (nullmat(`outsdx') \ `sdx') +* 2008-06-15 - mprobit does not compute these +* matrix `outebx' = (nullmat(`outebx') \ `bx') +* matrix `outpb' = (nullmat(`outpb') \ `pb') +* matrix `outpbx' = (nullmat(`outpbx') \ `pbx') +* 2008-06-15 add std b coef + matrix `outbsx' = (nullmat(`outbsx') \ `bx') + matrix `outz' = (nullmat(`outz') \ `z') + matrix `outp' = (nullmat(`outp') \ `p') + matrix `outse' = (nullmat(`outse') \ `se') + } /* matrix */ + * 050110 jsl gt option & adjacent + if ("`gt'"!="gt" & "`lt'"!="lt") /* + */ | ("`gt'"=="gt") & (`num1'>`num2') /* + */ | ("`lt'"=="lt") & (`num1'<`num2') { + local absdif = abs(`num1'-`num2') + if ("`adjacent'"=="adjacent" & `absdif'==1) /* + */ | "`adjacent'"!="adjacent" { + di in g `smcl' "`name1'" _col(9) /* + */ "-`name2'" _col(19) "`vline'" in y /* + */ %10.5f `b12' %9.3f `z' /* + */ %8.3f `p' _c + di %10.5f `bx' + } /* adjacent option */ + } /* gt lt option */ + } /* `p' <= `pcutoff' */ + local i2 = `i2' + 1 + if `i1' == `i2' { local i2 = `i2' + 1 } + } /* while `i2' <= `ncats' */ + local i2 1 + local i1 = `i1' + 1 + } /* i1 */ + + di in g `smcl' _dup(18) "`dash'" "`bottomt'" _dup(`todup') "`dash'" + local count = `count' + 1 + } /* while count */ + + } /* if "`cmd'" == "mprobit" 2008-06-15*/ + +*-> special model--slogit // print expanded coefficients + + if "`cmd'" == "slogit" & "`expand'"=="expand" { + version 9 + di _n in g "`cmd' (N=" in y `nobs' in g "): " _c + local pcttext "Factor" + if "`percent'" == "percent" { + local pcttext = "Percentage" + } + di in g "`pcttext' Change in the Odds of " in y "`lhsnm' " _c + if `pcutoff' < 1 & `pcutoff' >= .01 { + di in g "when P>|z| < " in y %3.2f `pcutoff' _c + } + + di + * loop through rhs variables to print + tokenize "`prnnums'" + local count = 1 + while "``count''" != "" { // loop through rhs variales + + local ivar = "``count''" + scalar `sdx' = `sd'[1,`ivar'] + local vname: word `ivar' of `rhsnam' + + * compute (phi_i - phi_j) * beta + tempname phiBest phiBse estsl est se + mat `phiBest' = J(`slncat',`slncat',0) + mat `phiBse' = `phiBest' + local i = 1 + * # cat - 1 since base is not in coef matrix + foreach i of numlist 1(1)`slncatm1' { // index for 1st phi + * get phi # in case different base is used + local phinm1 : word `i' of `slphinm' // name of ith parameter + local phirow = substr("`phinm1'",6,.) // + foreach j of numlist 1(1)`slncatm1' { // index for 2nd phi + local phinm2 : word `j' of `slphinm' + local phicol = substr("`phinm2'",6,.) + * di " `i' (row `phirow') - `j' (col `phicol')" + * hold estimates from current model, leaving values in memory + _estimates hold `estsl', copy + * compute contrasts + qui nlcom ([`phinm1']_b[_cons] /// + - [`phinm2']_b[_cons])*_b[`vname'], post + mat `est' = e(b) + mat `se' = e(V) + _estimates unhold `estsl' + * 12Apr2005 + mat `phiBest'[`phirow',`phicol'] = -1*`est'[1,1] + mat `phiBse'[`phirow',`phicol'] = sqrt(`se'[1,1]) + } + _estimates hold `estsl', copy + qui nlcom ([`phinm1']_b[_cons]) * _b[`vname'], post + mat `est' = e(b) + mat `se' = e(V) + _estimates unhold `estsl' + * 12Apr2005 + mat `phiBest'[`phirow',`slrefrow'] = -1*`est'[1,1] + mat `phiBse'[`phirow',`slrefrow'] = sqrt(`se'[1,1]) + * 12Apr2005 + mat `phiBest'[`slrefrow',`phirow'] = `est'[1,1] + mat `phiBse'[`slrefrow',`phirow'] = sqrt(`se'[1,1]) + } + + di _n in g "Variable: " in y "`vname' " /* + */ in g "(sd=" in y `sdx' in g ")" + local head2 " b z P>|z|" + if "`doeb'" == "yes" { + local head2 "`head2' e^b " + } + else { + local head2 "`head2' % " + } + if "`doebx'" == "yes" { + local head2 "`head2' e^bStdX" + } + else { + local head2 "`head2' %StdX" + } + local todup = length("`head2'") + di _n in g `smcl' %18s "Odds comparing" _col(19) "`vline'" + di in g `smcl' %18s "Group 1 vs Group 2" _col(19) "`vline'`head2'" + di in g `smcl' _dup(18) "`dash'" "`plussgn'" _dup(`todup') "`dash'" + + * loop through all contrasts + local i1 1 + local i2 1 + while `i1' <= `slncat' { + local num1 = `slcatnum'[1,`i1'] + local name1 "`e(out`i1')'" + while `i2' <= `slncat' { + scalar `b12' = `phiBest'[`i1',`i2'] + scalar `se' = `phiBse'[`i1',`i2'] + scalar `eb' = exp(`b12') + scalar `ebx' = exp(`b12'*`sdx') + scalar `pb' = (`eb'-1)*100 + scalar `pbx' = (`ebx'-1)*100 + scalar `rec_se' = 1/`se' + scalar `z' = `rec_se'*`b12' + scalar `p' = 2*normprob(-abs(`z')) + if `p' <= `pcutoff' { + local noprint = "no" + * get outcome value of second outcome + local num2 = `slcatnum'[1,`i2'] + local name2 "`e(out`i2')'" + if ("`gt'"!="gt" & "`lt'"!="lt") /* + */ | ("`gt'"=="gt") & (`num1'>`num2') /* + */ | ("`lt'"=="lt") & (`num1'<`num2') { + local absdif = abs(`num1'-`num2') + if ("`adjacent'"=="adjacent" & `absdif'==1) /* + */ | "`adjacent'"!="adjacent" { + di in g `smcl' "`name1'" _col(9) /* + */ "-`name2'" _col(19) "`vline'" in y /* + */ %10.5f `b12' %9.3f `z' /* + */ %8.3f `p' _c + if "`doeb'" == "yes" { + di %9.4f `eb' _c + } + else { + di %9.1f `pb' _c + } + if "`doebx'" == "yes" { + di %9.4f `ebx' + } + else { + di %9.1f `pbx' + } + } /* adjacent option */ + } /* gt lt option */ + } /* `p' <= `pcutoff' */ + local i2 = `i2' + 1 + if `i1' == `i2' { + local i2 = `i2' + 1 + } + } /* while `i2' <= `slncats' */ + local i2 1 + local i1 = `i1' + 1 + } /* i1 */ + + di in g `smcl' _dup(18) "`dash'" "`bottomt'" _dup(`todup') "`dash'" + local count = `count' + 1 + } // loop through variables + version 6.0 + + } /* if "`cmd'" == "slogit" expanded */ + +*-> help + + if "`help'"=="help" { + di in g " b = raw coefficient" + di in g " `tz' = `tz'-score for test of b=0" + di in g " P>|`tz'| = p-value for `tz'-test" + local std "standardized" + if "`dobx'" == "yes" { di in g " bStdX = x-`std' coefficient" } + if "`doby'" == "yes" { di in g " bStdY = y-`std' coefficient" } + if "`dobxy'" == "yes" { di in g " bStdXY = fully `std' coefficient" } + if "`doeb'" == "yes" { + if "`iscount'"=="yes" { + di in g " e^b = exp(b) = factor "/* + */ "change in expected count for unit increase in X" + } + else { + di in g " e^b = exp(b) = factor "/* + */ "change in odds for unit increase in X" + } + } + if "`doebx'" == "yes" { + if "`iscount'"=="yes" { + di in g " e^bStdX = exp(b*SD of X) = "/* + */ "change in expected count for SD increase in X" + } + else { + di in g " e^bStdX = exp(b*SD of X) = "/* + */ "change in odds for SD increase in X" + } + } + if "`dopb'" == "yes" { + if "`iscount'"=="yes" { di in g " % = percent change in"/* + */ " expected count for unit increase in X" } + else { di in g " % = percent change in odds for unit"/* + */ " increase in X" } + } + if "`dopbx'" == "yes" { + if "`iscount'"=="yes" { di in g " %StdX = percent change in"/* + */ " expected count for SD increase in X" } + else { di in g " %StdX = percent change in odds for SD"/* + */ " increase in X" } + } + if "`cmd'" != "mlogit" { di in g " SDofX = standard deviation of X" } + } /* if "`help'"=="help" */ + +*-> do binary equation for zip zinb + + if "`iszero'"=="yes" { + di _n in g "Binary Equation: Factor Change in Odds of Always 0" + local todupz = length("`head2'") + di in g `smcl' _n _dup(13) "`dash'" "`topt'" _dup(`todupz') "`dash'" + di in g `smcl' %12s "Always0" _col(14) "`vline'`head2'" + di in g `smcl' _dup(13) "`dash'" "`plussgn'" _dup(`todupz') "`dash'" + + tokenize `prnnum2' + local count = 1 + while "``count''" != "" { +* 1.9.1 add indx and change count to indx in matrices + local indx: word `count' of `prnnum2' // 1.9.2 + local vname : word `count' of `prnlis2' + if `p2'[1, `indx'] < `pcutoff' { + local noprint "no" + di in g `smcl' %12s "`vname'" in g _col(14) "`vline'" in y /* + */ %10.5f `bnocon2'[1,`indx'] %9.3f `zval2'[1,`indx'] /* + */ %8.3f `p2'[1,`indx'] _c + if "`doeb'" == "yes" { + di %9.4f `eb2'[1,`indx'] %9.4f `ebx2'[1,`indx'] _c + } + if "`dopb'" == "yes" { + di %9.1f `pb2'[1,`indx'] %9.1f `pbx2'[1,`indx'] _c + } + di %11.4f `sd2'[1, `indx'] + + if "`matrix'"!="" { + matrix `nxtrow' = `bnocon2'[1, `indx'] + matrix rownames `nxtrow' = `vname' + matrix `outb2' = (nullmat(`outb2') \ `nxtrow') + matrix `outz2' = (nullmat(`outz2') \ `zval2'[1,`indx']) + matrix `outp2' = (nullmat(`outp2') \ `p2'[1,`indx']) + + if "`doeb'" == "yes" { + mat `outeb2' = (nullmat(`outeb2') \ `eb2'[1,`indx']) + mat `outebx2' = (nullmat(`outebx2') \ /* + */ `ebx2'[1,`indx']) + } + if "`dopb'" == "yes" { + mat `outpb2' = (nullmat(`outpb2') \ `pb2'[1,`indx']) + mat `outpbx2' = (nullmat(`outpbx2') \ /* + */ `pbx2'[1,`indx']) + } + } + } /* if `p'[1, `indx'] < `pcutoff' */ +/* 1.9.0 + if `p2'[1, `count'] < `pcutoff' { + local noprint "no" + di in g `smcl' %12s "`vname'" in g _col(14) "`vline'" in y /* + */ %10.5f `bnocon2'[1,`count'] %9.3f `zval2'[1,`count'] /* + */ %8.3f `p2'[1,`count'] _c + if "`doeb'" == "yes" { + di %9.4f `eb2'[1,`count'] %9.4f `ebx2'[1,`count'] _c + } + if "`dopb'" == "yes" { + di %9.1f `pb2'[1,`count'] %9.1f `pbx2'[1,`count'] _c + } + di %11.4f `sd2'[1, `count'] + + if "`matrix'"!="" { + matrix `nxtrow' = `bnocon2'[1, `count'] + matrix rownames `nxtrow' = `vname' + matrix `outb2' = (nullmat(`outb2') \ `nxtrow') + matrix `outz2' = (nullmat(`outz2') \ `zval2'[1,`count']) + matrix `outp2' = (nullmat(`outp2') \ `p2'[1,`count']) + + if "`doeb'" == "yes" { + mat `outeb2' = (nullmat(`outeb2') \ `eb2'[1,`count']) + mat `outebx2' = (nullmat(`outebx2') \ /* + */ `ebx2'[1,`count']) + } + if "`dopb'" == "yes" { + mat `outpb2' = (nullmat(`outpb2') \ `pb2'[1,`count']) + mat `outpbx2' = (nullmat(`outpbx2') \ /* + */ `pbx2'[1,`count']) + } + } + } /* if `p'[1, `count'] < `pcutoff' */ +1.9.0 */ + local count = `count' + 1 + } /* while count */ + + if "`constant'"=="constant" { + di in g `smcl' %12s "_cons" in g _col(14) "`vline'" in y /* + */ %10.5f `con2' %9.3f `contst2' %8.3f `conp2' + if "`matrix'"!="" { + return scalar cons2 = `con2' + return scalar cons2_z = `contst2' + return scalar cons2_p = `conp2' + } + } + di in g `smcl' _dup(13) "`dash'" "`bottomt'" _dup(`todupz') "`dash'" + +* vuong + if e(vuong)~=. { + local favor "" + if e(vuong) > 0 { + local p = normprob(-e(vuong)) + if e(cmd)=="zip" { + if `p'<.10 {local favor "favoring ZIP over PRM."} + } + else { + if `p'<.10 {local favor "favoring ZINB over NBRM."} + } + } + else { + local p = normprob(e(vuong)) + if e(cmd)=="zip" { + if `p'<.10 {local favor "favoring PRM over ZIP."} + } + else { + if `p'<.10 {local favor "favoring NBRM over ZINB."} + } + } + + di in green " Vuong Test =" in y %6.2f e(vuong) in green /* + */ " (p=" in ye %4.3f `p' in g ") `favor'" + di in g `smcl' _dup(14) "`dash'" _dup(`todupz') "`dash'" + + } /* vuong */ + + + if "`help'"=="help" { + di in g " b = raw coefficient" + di in g " z = z-score for test of b=0" + di in g " P>|z| = p-value for z-test" + if "`doeb'" == "yes" { + di in g " e^b = exp(b) = factor " /* + */ "change in odds for unit increase in X" + di in g " e^bStdX = exp(b*SD of X) = "/* + */ "change in odds for SD increase in X" + } + if "`dopb'" == "yes" { + di in g " % = percent change in odds for unit"/* + */ " increase in X" + di in g " %StdX = percent change in odds for SD"/* + */ " increase in X" + } + di in g " SDofX = standard deviation of X" + } /* if "`help'"=="help" */ + } /* is -zip- or -zinb- */ + +*-> returns + + return local cmd `cmd' + return scalar pvalue = `pcutoff' + + if "`noprint'" == "yes" { + di _n in blu "(No results in which p < " %3.2f `pcutoff' ")" + exit + } + + if "`matrix'" == "" { exit } + + local allrows : rownames(`outb') + + if inlist("`e(cmd)'", "mlogit", "mprobit") { //! changed bj 23jul2008 + mat rownames `outcon' = `allrows' + mat colnames `outcon' = Group_1 Group_2 + mat `outcon' = `outcon'' + return matrix contrast `outcon' + } + + mat colnames `outb' = b + mat `outb' = `outb'' + return matrix b `outb' + mat rownames `outp' = `allrows' + mat colnames `outp' = p>|z| + mat `outp' = `outp'' + return matrix b_p `outp' + mat rownames `outz' = `allrows' + mat colnames `outz' = z + mat `outz' = `outz'' + return matrix b_z `outz' + if "`isnosdx'"!="yes" { + mat rownames `outsdx' = `allrows' + mat colnames `outsdx' = SDofX + mat `outsdx' = `outsdx'' + return matrix b_sdx `outsdx' + } + if "`dobx'"=="yes" { + mat rownames `outbsx' = `allrows' + mat colnames `outbsx' = bStdX + mat `outbsx' = `outbsx'' + return matrix b_xs `outbsx' + } + if "`doby'"=="yes" { + mat rownames `outbsy' = `allrows' + mat colnames `outbsy' = bStdY + mat `outbsy' = `outbsy'' + return matrix b_ys `outbsy' + } + if "`dobxy'"=="yes" { + mat rownames `outbs' = `allrows' + mat colnames `outbs' = bStdXY + mat `outbs' = `outbs'' + return matrix b_std `outbs' + } + if "`doeb'"=="yes" { + mat rownames `outeb' = `allrows' + mat colnames `outeb' = e^b + mat `outeb' = `outeb'' + return matrix b_fact `outeb' + } + if "`doebx'"=="yes" { + mat rownames `outebx' = `allrows' + mat colnames `outebx' = e^bStdX + mat `outebx' = `outebx'' + return matrix b_facts `outebx' + + } + if "`dopb'"=="yes" { + mat rownames `outpb' = `allrows' + mat colnames `outpb' = % + mat `outpb' = `outpb'' + return matrix b_pct `outpb' + } + if "`dopbx'"=="yes" { + mat rownames `outpbx' = `allrows' + mat colnames `outpbx' = %StdX + mat `outpbx' = `outpbx'' + return matrix b_pcts `outpbx' + } + + if "`iszero'"=="yes" { + capture local allrows : rownames(`outb2') + if _rc == 111 { + exit 0 + } + mat colnames `outb2' = b + mat `outb2' = `outb2'' + return matrix b2 `outb2' + mat rownames `outp2' = `allrows' + mat colnames `outp2' = p>|z| + mat `outp2' = `outp2'' + return matrix b2_p `outp2' + mat rownames `outz2' = `allrows' + mat colnames `outz2' = z + mat `outz2' = `outz2'' + return matrix b2_z `outz2' + if "`doeb'"=="yes" { + mat rownames `outeb2' = `allrows' + mat colnames `outeb2' = e^b + mat `outeb2' = `outeb2'' + return matrix b2_fact `outeb2' + } + if "`doebx'"=="yes" { + mat rownames `outebx2' = `allrows' + mat colnames `outebx2' = e^bStdX + mat `outebx2' = `outebx2'' + return matrix b2_facts `outebx2' + } + if "`dopb'"=="yes" { + mat rownames `outpb2' = `allrows' + mat colnames `outpb2' = % + mat `outpb2' = `outpb2'' + return matrix b2_pct `outpb2' + } + if "`dopbx'"=="yes" { + mat rownames `outpbx2' = `allrows' + mat colnames `outpbx2' = %StdX + mat `outpbx2' = `outpbx2'' + return matrix b2_pcts `outpbx2' + } + } /* if "`iszero'"=="yes" */ +end + +exit +* version 1.8.0 09Aug2005 change nominal terminology +* version 1.8.1 10Aug2005 fix label for slogit +* version 1.8.3b estout changes changes bj 23jul2008 +* version 1.8.3 2008-06-15 jsl +* - fix listcoef, matrix with mprobit +* version 1.8.4 2009-03-14 +* - esttab changes with bj 23jul2008 +* version 1.8.6 2009-10-07 benn jann +* - stata11 fix for mlogit +* version 1.9.0 2009-10-07 scott long +* - stata11 fix for mlogit +* version 1.9.1 2010-06-04 scott long +* - listcoef with selected vars for zi models +* version 1.9.2 2010-06-05 scott long +* - listcoef with selected vars for zi models +* version 1.9.3 2010-12-21 jsl fix std after logistic diff --git a/Modules/ado/plus/l/listcoef.hlp b/Modules/ado/plus/l/listcoef.hlp new file mode 100644 index 0000000..9c8dacb --- /dev/null +++ b/Modules/ado/plus/l/listcoef.hlp @@ -0,0 +1,96 @@ +.- +help for ^listcoef^ - 03Nov2005 +.- + +List transformed regression coefficients and guidelines for interpretation +-------------------------------------------------------------------------- + + ^listcoef^ [varlist], [^pv^alue(#) [^f^actor|^p^ercent|^s^td] ^c^onstant + ^r^everse ^gt^ ^lt^ ^adj^acent ^nol^abel ^ex^pand ^m^atrix ^h^elp] + +Description +----------- + +^listcoef^ lists the estimated coefficients for a variety of regression models. +Options allow you to specify different transformations of the coefficients, +such as factor change and percent change. Coefficients can be standardized for +a unit variance in the independent and/or dependent variables. For ^mlogit^, +coefficients for all comparisions among outcomes are included. + +NOTE: For models with categorical outcomes, the output is much clearer if you +assign value labels to the dependent variable. + +Options +------- + +^varlist^ indicates that coefficients for only these variables are to be listed + If no ^varlist^ is given, coefficients for all variables are listed. + +^pvalue^ specifies that only coefficients with a this significance level or + smaller will be printed. + +^factor^ specifies that factor change coefficients should be listed. + +^percent^ specifies that percent change coefficients should be listed. + +^std^ specifies that coefficients standardized to a unit variance for the + independent and/or dependent variables should be listed. + +^constant^ includes the constants in the output. + +^reverse^ reverses the comparison implied by the computation of factor or + percent change coefficients for ^logit^, ^ologit^, ^clogit^, or ^rologit^; + that is, it presents results indicating the change in the odds of b vs. a + instead of a vs. b. + +^matrix^ returns results in r() class matrices. + +^help^ includes details on the meaning of each coefficient. + +Options for ^mlogit^ and/or ^slogit^ +--------------------------------- + +^gt^ specifies that only comparisons where the first category has a larger + value than the second will be printed (e.g., comparing outcome 2 + versus 1, but not 1 versus 2). + +^lt^ specifies that only comparisons where the first category has a smaller + value than the second will be printed (e.g., comparing outcome 1 versus + 2, but not 2 versus 1). + +^adjacent^ specifies that only comparisons where the two category values are + adjacent will be printed (e.g., comparing outcome 1 versus 2 or 2 versus + 1, but not 1 versus 3). + +^nolabel^ requests that category numbers rather than value labels be used + in the output. + +^expand^ requests expanded output comparing all pairs of outcome categories + for ^slogit^. + +Compatable Models +----------------- + +^listcoef^ can be used with: ^clogit^, ^cloglog^, ^cnreg^, ^intreg^, ^logistic^, ^logit^, +^mlogit^, ^mprobit^, ^nbreg^, ^ologit^, ^oprobit^, ^poisson^, ^probit^, ^regress^, ^rologit^, +^slogit^, ^tobit^, ^zinb^, ^zip^, ^ztnb^, and ^ztp^. + +Examples +-------- + +To compute standardized regression coefficients for only those variables that +are significant at the .05 level, including the constant: + + . ^regress job fem phd ment fel art cit^ + . ^listcoef,constant pv(.05)^ + +For mlogit, to compute the percentage change in the odds for white with help +on the interpretation: + + . ^mlogit occ white ed exp^ + . ^listcoef white, percent help^ + +.- +Authors: J. Scott Long and Jeremy Freese + www.indiana.edu/~jslsoc/spost.htm + spostsup@@indiana.edu diff --git a/Modules/ado/plus/l/listutil.hlp b/Modules/ado/plus/l/listutil.hlp new file mode 100644 index 0000000..b83b344 --- /dev/null +++ b/Modules/ado/plus/l/listutil.hlp @@ -0,0 +1,744 @@ +.- +help for various list utilities +.- + +Manipulating lists of words +--------------------------- + + ^alphlist^ [ ^, c^apitals ^u^nderscore ^n^oisily ^g^lobal^(^macname^)^ ] + + ^binolist , k(^#^)^ [ ^n^oisily ^g^lobal^(^macname^)^ ] + + ^bothlist^ list1 ^\^ list2 [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^choplist^ list ^,^ { ^p^os^(^criterion^)^ | ^l^ength^(^criterion^)^ + | ^v^alue^(^criterion^)^ | ^c^har^(^#^)^ } [ ^n^oisily ^g^lobal^(^macname(s)^)^ ] + + ^collist^ list [ ^, f^ormat^(^format^) nu^mber ] + + ^convlist^ numlist1 ^\^ numlist2 [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^cseplist^ list [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^cvarlist^ list ^,^ [ { ^new^ | ^nu^meric | ^s^tring } + ^n^oisily ^g^lobal^(^macname(s)^)^ ] + + ^dellist^ list ^,^ { ^d^elete^(^string^)^ | ^p^os^(^numlist of positions^)^ } + [ ^e^xact ^a^ll ^n^oisily ^g^lobal^(^macname^)^ ] + + ^difflist^ list1 ^\^ list2 [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^eqlist^ list1 ^\^ list2 [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^fmtlist^ list ^, f^ormat^(^format^)^ [ ^n^oisily ^g^lobal^(^macname^)^ ] + + ^inslist^ list ^, i^nsert^(^words^) p^os^(^numlist of positions^)^ + [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^joinlist^ list1 ^\^ list2 [ ^, s^ep ^n^oisily ^g^lobal^(^macname^)^ ] + + ^lclist^ list [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^maplist^ list ^, m^ap^(^expression^)^ [ ^s^ymbol^(^string^) n^oisily ^g^lobal^(^macname^)^ ] + + ^mnthlist^ [ ^, b^egin^(^str^) n^umber^(^#^) s^tep^(^#^) l^ong ^c^aplc ^u^ppercase + ^y^ear ^n^oisily ^g^lobal^(^macname^)^ ] + + ^poslist^ list1 ^\^ list2 [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^postlist^ list ^, p^ost^(^string^)^ [ ^s^ep^ n^oisily ^g^lobal^(^macname^)^ ] + + ^prelist^ list ^, p^re^(^string^)^ [ ^n^oisily ^g^lobal^(^macname^)^ ] + + ^prodlist^ numlist [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^replist^ list ^, c^opies^(^#^)^ [ ^b^lock ^n^oisily ^g^lobal^(^macname^)^ ] + + ^revlist^ list [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^rotlist^ list ^, r^ot^(^#^)^ [ ^n^oisily ^g^lobal^(^macname^)^ ] + + ^sellist^ list ^, s^elect^(^string^)^ [ ^e^xact ^a^ll ^pre^fix ^post^fix ^suf^fix + ^n^oisily ^g^lobal^(^macname^)^ ] + + ^seqlist^ stub ^, c^opies^(^#^)^ [ ^s^tart^(^#^) p^refix ^post^fix^(^string^)^ + ^n^oisily ^g^lobal^(^macname^)^ ] + + ^sortlist^ list [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^sublist^ list ^, f^rom^(^string^)^ [ ^t^o^(^string^) all n^oisily ^g^lobal^(^macname^)^ ] + + ^sumlist^ numlist [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^takelist^ list ^, p^os^(^numlist of positions^)^ [ ^n^oisily ^g^lobal^(^macname^)^ ] + + ^trnclist^ list ^,^ { ^l^ength^(^#^)^ | ^n^umber^(^#^)^ } [ ^n^oisily ^g^lobal^(^macname^)^ ] + + ^uclist^ list [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^uniqlist^ list [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^varflist^ list ^, g^enerate^(^newvar^)^ [ { ^sc^alar | ^g^lobal } + ^st^ring ^t^ype^(^variable_type^)^ ] + + ^vectlist^ vector [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^wclist^ list [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + ^xorlist^ list1 ^\^ list2 [ ^, n^oisily ^g^lobal^(^macname^)^ ] + + +Description +----------- + +^alphlist^ produces the letters of the English alphabet ^a^ ... ^z^ [ ^_^ ] +or ^A^ ... ^Z^ [ ^_^] as a list of separate words. + +^binolist^ produces binomial coefficients as a list of separate words. + +^bothlist^ produces the list of words that are in both list1 and list2. +Repeated occurrences are selected only once. ^bothlist a b c d \ d e g^ +produces ^d^. + +^choplist^ chops a list of words into two lists according to a stated +criterion. + +^collist^ displays a list in column form: each word is printed starting on +a new line. + +^convlist^ produces the convolution of two numlists. Given a_1, ... , a_m +and b_1, ... , b_n the convolution is c_k, k = 1, ... , m + n - 1, where c_k +is the sum of products a_i * b_j such that i + j - 1 = k. More graphically, +consider this table of indexes k for a list of 3 items, indexed by i, and a +list of 4 items, indexed by j. + + j + 1 2 3 4 + +----------- + 1 | 1 2 3 4 + i 2 | 2 3 4 5 + 3 | 3 4 5 6 + +In words, form a multiplication table, and take sums over rising +diagonals. Thus the convolution of 1 2 1 and 1 3 3 1 is +1 (2 + 3) (1 + 6 + 3) (3 + 6 + 1) (3 + 2) 1 = 1 5 10 10 5 1. + +^cseplist^ interpolates commas as separators between words in the list. + +^cvarlist^ selects from a list of words those that are names of variables. + +^dellist^ deletes from a list of words any that contain one or more +specified words, or any at specified positions. + +^difflist^ produces a list of words that are in list1 but not in list2. +Repeated occurrences are selected only once. ^difflist a b c \ b^ +produces ^a c^. + +^eqlist^ determines whether two lists are equal, that is, have the +same words in the same order. + +^fmtlist^ produces a list of words displayed according to a specified +format. Most commonly, this is used for rounding to a specified number +of decimal places. + +^inslist^ inserts words in the list at specified positions. + +^joinlist^ joins or juxtaposes corresponding words from two lists. The lists +should have equal numbers of words, except that any list of length 1 is +repeated to match the other. Given ^a1 a2 a3 \ b1 b2 b3^, ^joinlist^ produces +^a1b1 a2b2 a3b3^ by default and ^a1 b1 a2 b2 a3 b3^ with the ^sep^ option. +Given ^a1 a2 a3 \ X^, it produces ^a1X a2X a3X^ by default. + +^lclist^ converts each word in the list to lower case. + +^maplist^ evaluates an expression substituting each word in turn. The +expression may return a numeric or a string result. + +^mnthlist^ produces a list of months. + +^poslist^ produces a list of positions of words in list1 that are in list2. +The position is that of the first occurrence of a word in list2. Words in list2 +that are not in list1 are assigned position ^0^. ^poslist a b c c d \ b c e^ +produces ^2 3 0^. + +^postlist^ produces a list of words all followed by the specified string. +^postlist a b c, p(70)^ produces ^a70 b70 c70^. + +^prelist^ produces a list of words all preceded by the specified string. +^prelist a b c, p(70)^ produces ^70a 70b 70c^. + +^prodlist^ produces the product of a numlist. + +^replist^ replicates a list of words. + +^revlist^ reverses a list of words. + +^rotlist^ rotates a list of words. + +^sellist^ selects from a list of words any that contain one or more specified +words. + +^seqlist^ produces by default a list of words suffixed by successive integers, +such as stub^1^, stub^2^, ... Note that stub can be blank (an empty string). +For further details see under Options. + +^sortlist^ sorts a list of words into alphabetic order. + +^sublist^ removes the string specified by ^from( )^ from each of the +words in the list provided. It replaces that string by any string specified +by ^to( )^. ^to( )^ defaults to an empty string. If the string specified by +^from( )^ is equal to the whole word, it is in effect removed from the list. + +^sumlist^ produces the sum of a numlist. + +^takelist^ yields the words at the specified positions in the list. + +^trnclist^ truncates each word, either so that it is no longer than ^length( )^ +characters, or so that the last ^number( )^ characters are dropped. + +^uclist^ converts each word in the list to upper case. + +^uniqlist^ deletes from a list of words any but the first occurrence +of each word in the list. + +^varflist^ generates a new variable from a list, putting successive words +in successive observations, starting at 1. + +^vectlist^ puts the elements of a named vector into a list. + +^wclist^ counts the number of words in a list. + +^xorlist^ selects words that occur in either but not both of two lists +(symmetric difference of sets). ^xorlist a b c \ c d e^ selects ^a b d e^. +Note that ^xorlist^ yields an empty list if and only if two lists +contain the same words (not necessarily in the same order). + + +Remarks +------- + +`Words' are separated by spaces. No significance is attached to the number +of spaces. No commas or ^" "^ should be included. In the case of ^bothlist^, +^convlist^, ^difflist^, ^eqlist^, ^joinlist^, ^poslist^ and ^xorlist^, ^\^ +should not be included. Hence ^a b c^ is a list of three words, ^a^, ^b^ +and ^c^. Similarly, ^1 2 3^ is a list of three words, ^1^, ^2^ and ^3^. + +Position in the list is best explained by example. In the list ^a b c^, the +words ^a^, ^b^, ^c^ have positions ^1^, ^2^, ^3^, and also ^-3^, ^-2^, ^-1^. Thus +negative positions are counted backwards from the end of the list and +position ^-1^ refers to the last word. It is not an error to refer to +position ^0^ but the result is empty. + +^choplist^ with ^length( )^ or ^char( )^, ^dellist, delete( )^, ^eqlist^, ^lclist^, +^sellist^, ^sortlist^, ^sublist^, ^trnclist^, ^uclist^ and ^varflist^ cannot +handle lists containing any individual word longer than 80 characters. + +^maplist^ may produce undesired results if expressions returning string +results contain or would return any strings longer than 80 characters. +Expressions are not currently checked for this problem. + +Any list given as input may be specified by one or more local or global +macros. + +The list might be a list of variable names, for example, but note that +these programs do not treat wild cards or dashes in variable lists in +any special way. Similarly, as a general rule, these programs do not +expand number lists (numlists) given as the main argument. Exceptions +are ^convlist^, ^prodlist^ and ^sumlist^. + +A word contains a string if ^index("^word^","^string^") > 0^. + +^wclist^ allows two statements of the form + + ^local nw : word count^ list + ^di `nw'^ + +to be replaced by one statement. + +^lclist^ and ^uclist^ are needed for lists more than 80 characters long, +because, for example, ^local lower = lower("^string^")^ truncates strings +that long. However, for the same reason, ^lclist^ and ^uclist^ cannot handle +individual words more than 80 characters long. Naturally, this is less +of a restriction. + + +Options +------- + +- options for all commands except ^collist^ and ^varflist^ + +^noisily^ specifies that the resulting list(s) should be displayed. + +^global( )^ specifies a global macro name to hold the resulting list. + +However, the ^global^ option of ^choplist^ and ^cvarlist^ may contain either +one or two names. The first name (of either one or two) will be used to hold +the words selected by the stated criterion. Any second name will be used to +hold the words not selected. + +Note that the ^global^ option of ^varflist^, which does not take +an argument, has a different function. + +- options specific to ^alphlist^ + +^capitals^ specifies that the list should be ^A^ ... ^Z^ rather than the +default ^a^ ... ^z^. + +^underscore^ adds ^_^ to the list. + +- option specific to ^binolist^ + +^k(^#^)^ specifies that the binomal coefficients should be ^comb(^k - 1, i - 1^)^ +for i = 1, ... , k and integer k >= 1. ^k(5)^ produces ^1 4 6 4 1^. It is a +required option. + +- options specific to ^choplist^ + +^pos( )^ specifies a criterion for selecting words according to their +positions. ^pos(<=3)^ puts the first three words in list 1, and any others +in list 2. + +^length( )^ specifies a criterion for selecting words according to their +lengths. ^length(7)^ puts words of length <= 7 in list 1, and any others in +list 2. + +^value( )^ specifies a criterion for selecting words according to their +values. Words may be compared according to their numeric or string order. + +^char(^#^)^ specifies that the first # characters of each word be selected. +^char(1)^ puts the first character of each word in list 1, and any others +in list 2. If # is negative, the last # characters of each word will be +selected. ^char(-1)^ puts the last character of each word in list 1, and +any others in list 2. Note that list 1 and list 2 will contain the same +number of words if and only if every word is at least two characters long. + +Precisely one of ^pos( )^, ^length( )^, ^value( )^ or ^char( )^ should be +specified. With the first three options, if just a number is specified, +^<=^ is prefixed, except that with ^pos( )^ if a negative sign is detected, +^>=^ is prefixed. ^pos(3)^ and ^pos(<=3)^ are thus equivalent, as are +similar choices with ^length( )^ and ^value( )^. ^pos(-1)^ puts the last +word in list 1, and all others in list 2. + +- options specific to ^collist^ + +^format( )^ specifies a format to use for each word. See help for @format@. + +^number^ specifies that words should be numbered from 1 upwards. + +- options specific to ^cvarlist^ + +^new^, ^numeric^ and ^string^ specify that words are to be selected if they +are the names of new, numeric or string variables respectively. Only one +of these options may be specified. Otherwise the names of variables in +memory will be selected. + +- options specific to ^dellist^ + +^delete(^string^)^ specifies the words to be deleted. By default a word in +the list is deleted if it contains any of the words in ^delete( )^. Thus +^dellist abc bcd c d e, d(a b c)^ deletes ^abc bcd c^. + +^all^ specifies that to be deleted each word must contain all the words +in ^delete( )^. Thus ^dellist abc bcd c d e, d(a b c) all^ deletes ^abc^. + +^exact^ specifies that exact matches are required. Words will be deleted +only if they equal the specified word. + +^all^ may not be specified with ^exact^. + +^pos( )^ should contain a numlist of positions of words to be deleted. + +Either ^delete( )^ or ^pos( )^ must be specified. + +- option specific to ^fmtlist^ + +^format(^format^)^ specifies a format. It is a required option. +See help for @format@. + +- options specific to ^inslist^ + +^inslist^ inserts words from ^insert( )^ as separate words at positions +in the original list given by ^pos( )^. + +^insert( )^ should contain one or more space-separated words. + +^pos( )^ should contain a numlist of positions. Position # means after word # +in the original list or before word # + 1. Thus ^0^ means before word 1, ^1^ means +after word 1, and ^-1^ means after the last word. Numbers may be repeated. + +If the number of words in ^insert( )^ is less than the number +of positions, ^insert( )^ is expanded as required. + +For example, ^inslist a b c d e f g h , i(x) p(1/7)^ produces + +^a x b x c x d x e x f x g x h^ + +while ^inslist a b c d e f g h , i(( )) p(0 4 4 8)^ produces + +^( a b c d ) ( e f g h)^ + +- option specific to ^joinlist^ + +^sep^ specifies that words produced are to be separate, that is, +juxtaposed not joined. + +- options specific to ^maplist^ + +^map(^expression^)^ specifies an expression which is evaluated using each word +in turn. It is a required option. The expression may return either a numeric +or a string result. The expression must contain a particular symbol (default +^@@^) which is used as a placeholder for the word. Thus ^map(-@@)^ negates each +word; ^map(sqrt(@@))^ calculates the square root of each word; ^map("foo @@")^ +interpolates ^foo^ as a separate word before each word in the list. + +^symbol(^string^)^ specifies an alternative to ^@@^ as a placeholder for +each word. Thus ^map(sqrt(X)) sy(X)^ is equivalent to ^map(sqrt(@@))^. + +- options specific to ^mnthlist^ + +^begin(^str^)^ specifies a month to start the sequence. str can be an integer +between 1 and 12, indicating a month from January (1) to December (12), or +an unambiguous English month name or abbreviation (case is not important). +Thus a string starting with any of "ja", "Ja", "JA", or "jA" is taken to mean +January. January is the default. + +^number(^#^)^ specifies the number of months in the list. 12 is the default. + +^step(^#^)^ specifies the step between successive months in the list. +1 is the default. + +^long^ indicates long names (january ... december or January ... December). +Three letter abbreviations jan ... dec are the default. + +^caplc^ indicates an initial capital followed by lower case, as in January ... +December or Jan ... Dec. All lower case is the default. + +^uppercase^ indicates all upper case, as in JANUARY ... DECEMBER or +JAN ... DEC. All lower case is the default. + +^year^ indicates the year in which in the first month occurs. Years will +be appended to each month. + +Thus ^mnthlist^ produces ^jan feb mar apr may jun jul aug sep oct nov dec^. + +^mnthlist, n(49) b(3) s(12) year(1952) caplc^ produces the 49 months +^Mar1952 Mar1953^ ... ^Mar1999 Mar2000^. + +- options specific to ^postlist^ + +^post(^string^)^ specifies the string to be postfixed. It is a required +option. + +^sep^ specifies that whatever is postfixed by ^postlist^ is a separator +and should not appear after the last word in the list. +^postlist a b c, p(,) sep^ produces the list ^"a, b, c"^. + +- option specific to ^prelist^ + +^pre(^string^)^ specifies the string to be prefixed. It is a required +option. + +- options specific to ^replist^ + +^copies(^#^)^ specifies the number of copies to be produced. +By itself ^copies(3)^ produces ^a a a b b b c c c^ given ^a b c^. +It is a required option. + +^block^ specifies that the list is to be replicated as a block. +^copies(3) block^ produces ^a b c a b c a b c^ given ^a b c^. + +- option specific to ^rotlist^ + +^rot(^#^)^ rotates the list as follows. Suppose there are n words in the +list and ^rot(^r^)^ is specified. If r >= 0, the new list is the last n - r +words of the list followed by the first r words: that is, r words from +the start of the list are moved to the end. If r < 0, the new list is the +last r words of the list followed by the first n - r words: that is, r words +from the end of the list are moved to the start. Thus given ^1 2 3 4 5^, +^rot(1)^ produces ^2 3 4 5 1^ and ^rot(-1)^ produces ^5 1 2 3 4^. For any +integer r, ^mod(^r^,^n^)^ is used. + +- options specific to ^sellist^ + +^select(^string^)^ specifies the words to be selected. It is a required +option. By default a word in the list is selected if it contains any +of the words in ^select( )^. Thus ^sellist abc bcd c d e, s(a b c)^ +produces ^abc bcd c^. With any of ^prefix^, ^postfix^ or ^suffix select( )^ +must contain only a single word. + +^exact^ specifies that exact matches are required. Words will be selected +only if they equal the specified word. + +^all^ specifies that to be selected each word must contain all the words +in ^select^. Thus ^sellist abc bcd c d e, s(a b c) all^ produces ^abc^. + +^all^ may not be specified with ^exact^. + +^prefix^ specifies that to be selected each word must contain the single +word in ^select( )^ as a prefix, at its start. +Thus ^sellist abc bcd c d e, s(c) pre^ produces ^c^. + +^postfix^ or ^suffix^ specifies that to be selected each word must contain +the single word in ^select( )^ as a postfix or suffix, at its end. +Thus ^sellist abc bcd c d e, s(c) post^ produces ^abc c^. + +^prefix^ may not be combined with ^postfix^ or ^suffix^. None of these options +may be combined with ^exact^ or ^all^. + +- options specific to ^seqlist^ + +^copies(^#^)^ specifies the number of words in the list to be produced. +By itself ^copies(3)^ produces stub^1^ stub^2^ stub^3^. It is a required +option. + +^start(^#^)^ specifies a starting number other than 1. ^copies(3) start(3)^ +produces stub^3^ stub^4^ stub^5^. + +^prefix^ specifies that numbers are to be attached as prefixes. +^copies(3) prefix^ produces ^1^stub ^2^stub ^3^stub. + +^postfix(^string^)^ specifies a postfix to be added to all words. +^post(b)^ adds ^b^ to the end of each word. + +- options specific to ^sublist^ + +^from(^string^)^ specifies the string to be substituted. It is a required +option. + +^to(^string^)^ optionally specifies a replacement string to be used by +^sublist^. In other words, it defaults to an empty string, and in that case +^sublist^ deletes the argument of ^from( )^ from each word in the list +without replacing it. + +^all^ specifies that all occurrences of string in each word are to +be substituted by ^sublist^. The default is to substitute the first +occurrence only. + +- option specific to ^takelist^ + +^pos(^numlist of positions^)^ specifies the positions of the words to be taken +from the list. + +- options specific to ^trnclist^ + +^length(^#^)^ specifies the maximum length of word acceptable. With +^length(8)^, for example, words of 8 or fewer characters are unchanged, +while words of 9 or more characters are truncated to the first 8 +characters. + +^number(^#^)^ specifies the number of characters to be dropped from the +end of each word. ^number(^1^)^ drops the last character from each word. +Dropping # characters from a word # or fewer characters long blanks it out. + +- options specific to ^varflist^ + +^generate(^newvar^)^ specifies the name of a new variable to receive +values. It is a required option. + +^global^ indicates that the list is of global names, whose values are to be +put in the new variable. ^varflist a b c, g(foo) global^ is equivalent to +^varflist $a $b $c, g(foo)^. Conversely, to put the names of globals ^a b c^ +in a new variable, do not specify ^global^. + +^scalar^ indicates that the list is of scalar names, whose values are to be +put in the new variable. ^varflist a b c, g(foo) scalar^ puts the values of +scalars with names ^a b c^ in ^foo^. Conversely, to put the names of scalars +^a b c^ in a new variable, do not specify ^scalar^. + +^global^ and ^scalar^ may not be combined. + +^string^ specifies that the new variable is to be a string variable. +^string^ without ^type( )^ implies ^str1^, so that ^type( )^ is not required +with ^string^. However, a numeric data type must not be specified with +^string^. + +^type(^variable_type^)^ specifies the type as which the new variable is +first created. See ^string^ above. + + +Saved results +------------- + +Note that, except for ^collist^ and ^varflist^, in each case global macros may +also be set using ^global( )^. + +^alphlist^: ^r(list)^ contains a set of letters of the alphabet as separate +words. + +^binolist^: ^r(list)^ contains binomial coefficients as separate words. + +^bothlist^: ^r(list)^ contains the intersection, those words in list1 and +in list2. + +^choplist^: ^r(list1)^ contains the words selected by the stated criterion. +^r(list2)^ contains the words not selected. + +^collist^ : none. + +^convlist^: ^r(list)^ contains the convolution of the two numlists +supplied. + +^cseplist^: ^r(list)^ contains the words of the original list separated by +commas. ^cseplist 1 2 3 4 5^ returns ^1,2,3,4,5^ as its result. + +^cvarlist^: ^r(list1)^ contains the words that are variable names. +^r(list2)^ contains the words that are not. + +^dellist^: ^r(list)^ contains the original list minus those words deleted. + +^difflist^: ^r(list)^ contains the difference set, those words in list1 not +in list2. + +^eqlist^: ^r(iseq)^ is 1 if list1 and list2 are equal and 0 otherwise. + +^fmtlist^: ^r(list)^ contains the list of words displayed using the specified +format. + +^inslist^: ^r(list)^ contains the list after insertion. + +^joinlist^: ^r(list)^ contains the list of joined or juxtaposed words. + +^lclist^: ^r(list)^ contains the list in lower case. + +^maplist^: ^r(list)^ contains the results of evaluating the expression +supplied with each word substituted in turn. + +^mnthlist^: ^r(list)^ contains the list of months specified. + +^poslist^: ^r(list)^ contains the indexes of the words in list2 within list1. + +^postlist^: ^r(list)^ contains the original list with each word followed by +the specified string (unless the ^sep^ option is specified). + +^prelist^: ^r(list)^ contains the original list with each word preceded by +the specified string. + +^prodlist^: ^r(prod)^ contains the product of the list. + +^replist^: ^r(list)^ contains the replicated list. + +^revlist^: ^r(list)^ contains the reverse of the original list (last word +first, etc.) + +^rotlist^: ^r(list)^ contains the rotated list. + +^sellist^: ^r(list)^ contains those words selected from the original list. + +^seqlist^: ^r(list)^ contains a list of words suffixed (optionally, prefixed) +by successive integers. + +^sortlist^: ^r(list)^ contains the words from list sorted into alphabetic order. + +^sublist^: ^r(list)^ contains the original list with each word modified by +substitution of the argument of ^to( )^ for the argument of ^from( )^. + +^sumlist^: ^r(sum)^ contains the sum of the list. + +^takelist^: ^r(list)^ contains words which were at specified positions in the +list. + +^trnclist^: ^r(list)^ contains the original list, except that either each word +more than ^length( )^ characters long is truncated to its first ^length( )^ +characters, or the last ^number( )^ characters have been dropped. + +^uclist^: ^r(list)^ contains the list in upper case. + +^uniqlist^: ^r(list)^ contains the first occurrence of each word from list. + +^varflist^: none. + +^vectlist^: ^r(list)^ contains the elements of a vector as a list of words. + +^wclist^: ^r(nw)^ contains the number of words in list. + +^xorlist^: ^r(list)^ contains the symmetric difference set, those words in +either list1 or list2, but not both. + + +Examples +-------- + + . ^binolist, k(5)^ + + . ^choplist 1 2 3 4 5 6 7, p(<=3)^ + . ^choplist 1 2 3 4 5 6 7, p(3)^ + . ^choplist 7 6 5 4 3 2 1, v(>=3)^ + . ^choplist 7 6 5 4 3 2 1, v(3)^ + + any variable names of 8 characters, which cannot be lengthened + in Stata 6? + + . ^unab list : _all^ + . ^choplist `list', l(==8) n^ + . ^choplist `list', l(==8) g(eightch)^ + + ^$eightch^ will hold all names 8 characters long. + + . ^ds2^ + . ^sellist `r(varlist)', s(age)^ + . ^local age `r(list)'^ + . ^l `age'^ + . ^su `age'^ + + . ^ds2^ + . ^sellist `r(varlist)', s(age)^ + . ^sortlist `r(list)'^ + . command ^`r(list)'^ + + . ^maplist 1 2 3 4 5, m(sqrt(@@))^ + . ^fmtlist `r(list)', f(%4.3f)^ + + every 1 April for 20 years: + . ^mnthlist, n(20) b(4) y(1981) s(12)^ + . ^maplist `r(list)', map(d(1@@))^ + . ^graph price date, xla(`r(list)')^ + + . ^local list inc exp profit^ + . ^postlist `list', post(70)^ + . ^for var `list' \ new `r(list)' : rename X Y^ + + . ^seqlist a, c(10)^ + + chances of k (1 <= k <= 20) heads in a row: + . ^seqlist , c(20) n^ + . ^maplist `r(list)' , map(0.5^^@@) n^ + + instead of + . ^graph using l1g1 l1g2 l1g3 l1g4 l1g5 l1g6 l1g7 l1g8 l1g9 l1g10^ + type + . ^seqlist l1g, c(10)^ + . ^graph using `r(list)'^ + + to put a set of scalar names and corresponding values in a variable: + . ^varflist a b c d e f g h, gen(names) string^ + . ^varflist a b c d e f g h, gen(values) scalar type(double)^ + + to put a little data set in a variable: + . ^varflist -1 0 1 2.71828 3.1459 42, gen(data)^ + + +Acknowledgements +---------------- + +This set of programs has benefitted from questions and comments from +several members of Statalist, especially Kit Baum, for encouragement +and suggestions; Austin Frakt, for unearthing an important bug; and +Fred Wolfe, who provided the stimulus to extend ^dellist^ and ^sellist^. + + +Author +------ + + Nicholas J. Cox, University of Durham, U.K. + n.j.cox@@durham.ac.uk + + +Also see +-------- + +On-line: help for @format@, @numlist@, @nlist@, @unab@, @ds2@ (if installed), + @vallist@ (if installed) + Manual: ^[U] 21.3 Macros^, ^[R] unab^ + + + diff --git a/Modules/ado/plus/l/log2html.ado b/Modules/ado/plus/l/log2html.ado new file mode 100644 index 0000000..6146ac3 --- /dev/null +++ b/Modules/ado/plus/l/log2html.ado @@ -0,0 +1,175 @@ +*! log2html 1.2.9 cfb/njc/br 08jun2006 +*! log2html 1.2.8 cfb/njc/br 09feb2005 +*! log2html 1.2.7 cfb/njc/br 12oct2004 +*! log2html 1.2.6 cfb/njc/br 2oct2003 +*! log2html 1.2.5 cfb/njc/br 17Jun2003 +*! log2html 1.2.0 cfb/njc 3Mar2003 +*! log2html 1.1.1 cfb/njc 17Dec2001 +program log2html + version 8.0 + syntax anything(name=smclfile id="The name of a .smcl logfile is") /// + [, ERASE replace TItle(str) INput(str) Result(str) BG(str) LINEsize(integer `c(linesize)') /// + TExt(str) ERRor(str) PERcentsize(integer 100) BOLD CSS(str) SCHeme(str)] + + // syntax processing + + if "`css'" != "" & `"`input'`result'`text'`error'`bg'`scheme'"' != "" { + di as err "if CSS is specified, you may not specify any colors" + exit 198 + } + + if "`scheme'" != "" { + if `"`input'`result'`text'`error'`bg'"' != "" { + di as err /// + "if a scheme is specified, you may not specify any colors" + exit 198 + } + + local names "bg input result text error" + local cblack "000000 ffffff ffff00 00ff00 ff0000" + local cwhite "ffffff 000000 000000 000000 ff0000" + local cblue "000090 ffffff ffff00 00ff00 ff0000" + local cugly "ff00ff 9999ff ff99ff 00ff00 cccc00" + local cyellow "ffffcc cc00cc 0000cc 000000 ff0000" + + local cnt 1 + foreach name of local names { + local `name' : word `cnt++' of `c`scheme'' + } + if "`bg'"=="" { + display as error "scheme `scheme' does not exist! Available schemes are " + display as error " black, white, blue, and yellow." + exit 198 + } + + } + + else { + if "`input'" == "" local input "CC6600" + if "`result'" == "" local result "000099" + if "`text'" == "" local text "000000" + if "`error'" == "" local error "dd0000" + if "`bg'" == "" local bg "ffffff" + else { + if "`bg'" == "gray" | "`bg'" == "grey" { + local bg "cccccc" + } + } + } + + if !inrange(`linesize', 40, 255) { + display as err "linesize must be between 40 and 255" + exit 125 + } + + if `percentsize' <= 0 { + display as err "percentsize() must be a positive integer" + exit 198 + } + + // filenames and handles + + tempname hi ho + tempfile htmlfile + local origfile `smclfile' + if (!index(lower("`origfile'"),".smcl")) { + local origfile "`origfile'.smcl" + } + local smclfile : subinstr local smclfile ".smcl" "" + local smclfile : subinstr local smclfile ".SMCL" "" + local smclfile : subinstr local smclfile `"""' "", all /* '"' (for fooling emacs) */ + local smclfile : subinstr local smclfile "`" "", all + local smclfile : subinstr local smclfile "'" "", all + local outfile `"`smclfile'.html"' + local ll "ll(`linesize')" + qui log html `"`origfile'"' `"`htmlfile'"', `replace' yebf whbf `ll' + + // line-by-line processing + + file open `hi' using `"`htmlfile'"', r + file open `ho' using `"`outfile'"', w `replace' + file write `ho' _n + file write `ho' "" _n "" _n + if `"`title'"' ~= "" { + file write `ho' `"`title'"' _n + } + file write `ho' `""' _newline + file write `ho' `""' _newline + if "`css'" == "" { + file write `ho' `"" _newline + } + else { + file write `ho' `""' _newline + } + file write `ho' "" _newline + file write `ho' "" _newline + if `"`title'"' != "" { + file write `ho' `"

`title'

"' _n + } + + file read `hi' line + + local cprev = 0 + + while r(eof) == 0 { + + // change

(which should be a div) to a

+ local line : /// + subinstr local line "

" "

", all + + local line: /// + subinstr local line ". " ". ", count(local c) + + // catch continuation lines + local word1 : word 1 of `"`line'"' + if substr(`"`word1'"',1,7) == ">" & `cprev' { + local line : /// + subinstr local line "" "", count(local c) + } + else { + local line: /// + subinstr local line "" "", all + } + + *local line : subinstr local line "---" "___", all + local line: subinstr local line "" "", all + + // check for error number + if substr(`"`word1'"',1,2) == "r(" { + if real(substr(`"`word1'"',3,index(`"`word1'"',")")-3)) < . { + local line `"

`line'
"' + } + } + local tmp=substr("`line'",1,18) + di "first character : `tmp'" + if "`tmp'"!="" { + file write `ho' `"`macval(line)'"' _n + } + local cprev = `c' + file read `hi' line + } + + file write `ho' "" _n "" _n + file close `ho' + + di _n `"HTML log file `outfile' created"' + if "`erase'" ~= "" { + erase `"`origfile'"' + } +end + + diff --git a/Modules/ado/plus/l/log2html.hlp b/Modules/ado/plus/l/log2html.hlp new file mode 100644 index 0000000..fc89744 --- /dev/null +++ b/Modules/ado/plus/l/log2html.hlp @@ -0,0 +1,182 @@ +{smcl} +{* 8jun2006}{...} +{hline} +help for {hi:log2html}{right:SSC distribution 8 June 2006} +{hline} + +{title:Translate a SMCL log file into HTML} + +{p 8 17 2}{cmd:log2html} +{it:smclfile} +[{cmd:,} +{cmd:replace} +{cmd:erase} +{cmdab:ti:tle}{cmd:(}{it:string}{cmd:)} +{cmdab:line:size(}{it:#}{cmd:)}{break} +{cmdab:per:centsize(}{it:integer}{cmd:)} +{cmd:bold}{break} +{cmdab:sch:eme}{cmd:(}{it:string}{cmd:)} +{cmd:css(}{it:string}{cmd:)}{break} +{cmdab:in:put}{cmd:(}{it:string}{cmd:)} +{cmdab:r:esult}{cmd:(}{it:string}{cmd:)} +{cmdab:err:or}{cmd:(}{it:string}{cmd:)} +{cmdab:te:xt}{cmd:(}{it:string}{cmd:)} +{cmd:bg(}{it:string}{cmd:)} +] + + +{title:Description} + +{p 4 4 2}{cmd:log2html} translates Stata log files or other +files in SMCL to HTML. + +{title:Remarks} + +{p 4 4 2}{cmd:log2html} is primarily for use after {cmd:log}; see {help log}. + +{p 4 4 2}{cmd:log2html} makes use of an undocumented command in Stata version 7 +up, {cmd:log html}, which generates HTML files from SMCL (e.g. log) files. +SMCL, the Stata Markup and Control Language {help smcl}, is the default log +file format introduced with version 7, and contains markup (similar to HTML) +around elements of the log file. To use {cmd:log2html} on log files, you must +first generate the default SMCL log file, not a text log file, with the file +extension {cmd:.smcl}. Thus if you have {cmd:set logtype text} to prevent the +generation of SMCL log files, you must either turn it off or explicitly state +that a SMCL log file is to be produced, as by {cmd: log using my.smcl}. + +{p 4 4 2}{cmd:log2html} requires only the base name of a logfile: +e.g. {cmd:my}, if the logfile is named {cmd:my.smcl}. The name of the HTML file +produced will be this base name with {cmd:.html} appended, e.g. {cmd:my.html}. + +{p 4 4 2}{cmd:log2html} requires Stata version 8 at least. + +{p 4 4 2}{cmd:loghtml} produces a complete HTML page (i.e. with and + tags). By default, the page will have a white background; input lines +(those resulting from user input) are rendered in RGB color "CC6600" (a shade +of brown); and highlighted result-window lines are rendered in RGB color +"000099" (a shade of blue). The options permit other choices for these three +colors. For best results, one of the 216 "web safe" colors that display +properly in web browsers on all computers in 256-color mode should be used. +Also note that some combinations of colors are not workable; e.g. a black +("000000") background will cause all normally-rendered text to disappear. + +{p 4 4 2}Colors are specified as hexadecimal RGB colors ranging from 000000 +(black) to FFFFFF (white), where FF0000 is red, 00FF00 is green, and 0000FF is +blue. It is best to use web-safe colors, where both digits of each color pair +match and are divisible by 3 (i.e. 00 33 66 99 CC or FF). + +{p 4 4 2}Those wanting to include the CSS classes used by {cmd:log2html} should +make an HTML file with the CSS option, and then look at the resulting +page in a text editor. It will give more insight than any explanation here +could give. + + +{title:Options} + +{p 4 8 2}{cmd:replace} specifies that if the HTML file exists, it is to be +replaced. + +{p 4 8 2}{cmd:erase} specifies that the SMCL log file is to be erased (deleted) +after processing. + +{p 4 8 2}{cmd:title()} specifies a string to be placed in the of the +HTML page, and on the first line of the body of the page, using a <H2> +heading. + +{p 4 8 2}{cmd:linesize()} specifies a maximum line size for the result, +i.e. the width in characters of rendered HTML lines. The argument +must be between 40 and 255 inclusive. Default is the current linesize. + +{p 4 4 2}The remaining options pertain to setting how the HTML page will appear +when rendered in a browser. + +{p 4 8 2}{cmd:percentsize()} specifies the scaling of the font to be used on +the resulting HTML page as a percentage of the default. (The +actual size is not specified, since it is typically specified by +the person using the browser, not the person sharing the +information.) This affects all text on the page. + +{p 4 8 2}{cmd:bold} specifies that input lines (those resulting from +user input), results from Stata, and error numbers be displayed as +bold text. + +{p 4 8 2}{cmd:scheme()} is the simplest way to change the colors of the +resulting web page. The allowable schemes are + +{p 8 10 12}{cmd:black}, {cmd:white}, or {cmd:blue}, which correspond closely +to the colors of Stata's color schemes for the results window. + +{p 8 10 12}{cmd:yellow}, which makes an easy-on-the-eyes page with +a faint yellow background. + +{p 4 8 2}{cmd:input()}, {cmd:result()}, {cmd:text()}, and {cmd:error()} can be +used independently to set the foreground color of the text which corresponds to +user input, Stata results, plain text output, and error numbers. + +{p 4 8 2}{cmd:bg()} specifies the color of the background of the +page. For convenience, this can be given as "grey" or "gray". + +{p 4 8 2}{cmd:css()} specifies the cascading style sheet for the web +page. This is an advanced option for people who use CSS for +standardizing the appearance of their web sites. If you do not know +what CSS means, there is no need to worry: if this option is +omitted, {cmd:log2html} will put the proper information into the +HTML file it creates. + + +{title:Examples} + +{p 4 8 2}{inp:. log using autostudy, replace}{p_end} +{p 4 8 2}{inp:. use auto}{p_end} +{p 4 8 2}{inp:. desc}{p_end} +{p 4 8 2}{inp:. summ}{p_end} +{p 4 8 2}{inp:. regress price mpg rep78}{p_end} +{p 4 8 2}{inp:. log close} + +{p 4 8 2}{inp:. log2html autostudy, replace} + +{p 4 8 2}{inp:. log2html autostudy, replace ti(Automobile study)} + +{p 4 8 2}{inp:. log2html autostudy, replace ti(Automobile study) scheme(black)} + +{p 4 8 2}{inp:. log2html autostudy, replace in(ff3300) res(003333) bg(grey)} + +{p 4 8 2}{inp:. log2html autostudy, replace ti(Automobile study) css("./mystyles.css")} + + +{title:References} + +{p 4 4 2}Priester, Gary W. 2000. All you need to know about web safe colors.{break} +{browse "http://www.webdevelopersjournal.com/articles/websafe1/websafe_colors.html"}{p_end} + +{p 4 4 2}Richmond, Alan. Introduction to style sheets.{break} +{browse "http://www.wdvl.com/Authoring/Style/Sheets/Tutorial.html"}{p_end} + + +{title:Acknowledgements} + + {p 4 4 2}Ken Higbee helped with the documentation + of {cmd:log html} and made suggestions for improvement of this routine. + Renzo Comolli drew our attention to problems arising with long lines + and quoted filenames. Friedrich Huebler also raised the issue of + line size and Alan Riley and Joseph Coveney showed how to tackle it. + + +{title:Authors} + + {p 4 4 2}Christopher F Baum, Boston College, USA{break} + baum@bc.edu{p_end} + + {p 4 4 2}Nicholas J. Cox, Durham University, UK{break} + n.j.cox@durham.ac.uk{p_end} + + {p 4 4 2}Bill Rising, Bellarmine University, USA{break} + wrising@bellarmine.edu{p_end} + + +{title:Also see} + +{p 4 13 2}Manual: {hi:[R] log}, {hi:[P] smcl} + +{p 4 13 2}On-line: help for {help log}, {help smcl} + diff --git a/Modules/ado/plus/l/log2html7.ado b/Modules/ado/plus/l/log2html7.ado new file mode 100644 index 0000000..7a0bb73 --- /dev/null +++ b/Modules/ado/plus/l/log2html7.ado @@ -0,0 +1,61 @@ +*! log2html 1.1.1 cfb/njc 17Dec2001 +program define log2html7, rclass + version 7.0 + syntax anything(name=smclfile id="The name of a .smcl logfile is") /* + */ [, replace TItle(string asis) INput(string) Result(string) BG(string)] + + tempname hi ho + tempfile htmlfile + local smclfile : subinstr local smclfile ".smcl" "" + local smclfile : subinstr local smclfile ".SMCL" "" + local outfile `"`smclfile'.html"' + qui log html `"`smclfile'"' `"`htmlfile'"', `replace' yebf whbf + + local cinput = cond("`input'" == "", "CC6600", "`input'") + local cresult = cond("`result'" == "", "000099", "`result'") + + local cbg "ffffff" + if "`bg'" ~= "" { + if "`bg'" == "gray" | "`bg'" == "grey" { local bg "cccccc" } + local cbg `bg' + } + + file open `hi' using `"`htmlfile'"', r + file open `ho' using `"`outfile'"', w `replace' + file write `ho' _n + file write `ho' "<html>" _n "<head>" _n + if `"`title'"' ~= "" { + file write `ho' `"<title>`title'"' _n + file write `ho' `"

`title'

"' _n + } + file write `ho' "" _n + file write `ho' "" _n + file read `hi' line + + local cprev = 0 + + while r(eof)==0 { + * command lines + local line: /* + */ subinstr local line ". " ". ", count(local c) + + * catch continuation lines + if substr(`"`line'"',1,7) == ">" & `cprev' { + local line : /* + */ subinstr local line "" "", count(local c) + } + else { + local line: /* + */ subinstr local line "" "", all + } + + local line: subinstr local line "" "", all + file write `ho' `"`line'"' _n + local cprev = `c' + file read `hi' line + } + file write `ho' "" _n "" _n + file close `ho' + di _n `"HTML log file `outfile' created"' +end + diff --git a/Modules/ado/plus/l/log2html7.hlp b/Modules/ado/plus/l/log2html7.hlp new file mode 100644 index 0000000..496a129 --- /dev/null +++ b/Modules/ado/plus/l/log2html7.hlp @@ -0,0 +1,137 @@ +{smcl} +{* 12 Dec 2001/25 March 2003}{...} +{hline} +help for {hi:log2html7}{right:SSC distribution 25 March 2003} +{hline} + +{title:Translate a SMCL log file into HTML} + +{p 8 12}{cmd:log2html7} +{it:smclfile} +[{cmd:,} +{cmd:replace} +{cmdab:ti:tle}{cmd:(}{it:string}{cmd:)} +{cmdab:in:put}{cmd:(}{it:string}{cmd:)} +{cmdab:r:esult}{cmd:(}{it:string}{cmd:)} +{cmd:bg(}{it:string}{cmd:)} +] + + +{title:Description} + +{p} +{cmd:log2html7} is for use after {cmd:log}; see {help log}. If +you are using Stata 8 or later, use {cmd:log2html} instead. + +{p} {cmd:log2html7} makes use of an undocumented command in Stata version 7, +{cmd:log html}, which generates HTML log files from SMCL log files. SMCL, the +Stata Markup and Control Language {help smcl}, is the default log file format +introduced with version 7, and contains markup (similar to HTML) around +elements of the log file. To use {cmd:log2html7}, you must first generate the +default SMCL log file, not a text log file, with the file extension +{cmd:.smcl}. Thus if you have {cmd:set logtype text} to prevent the generation +of SMCL log files, you must either turn it off or explicitly state that a SMCL +log file is to be produced, as by {cmd: log using my.smcl}. + +{p} {cmd:log2html7} requires only the base name of the logfile: e.g. {cmd:my}, +if the logfile is named {cmd:my.smcl}. The name of the HTML file produced will +be this base name with {cmd:.html} appended, e.g. {cmd:my.html}. + +{p} {cmd:log2html7} requires that at least the 6 December 2001 update to Stata +version 7 be installed. If a message "Invalid syntax" is encountered, please +ensure that {cmd:query born} returns a date no earlier than 06 Dec 2001. + + +{title:Limitation} + +{p} {cmd:log2html7} cannot reliably echo {it:names} of local or global macros +given on command lines in the log. This is because before being passed +to the Stata command {cmd:file}, which does most of the hard work within +{cmd:log2html7}, they are caught by Stata's parser and substituted with +their current {it:contents}, if any. The usual result is to replace macro names +with empty strings, although on occasion you may be fortunate enough to have +the correct contents of a macro substituted, or unfortunate enough to +have something quite different substituted, if the contents of a macro have +changed since the log was created. This behavior is outside the +control of the program authors, who know of no work-around in Stata 7. +The limitation does not apply to {cmd:log2html} used in conjunction +with Stata 8 or higher. + + +{title:Options} + +{p 0 4} +{cmd:replace} specifies that if the HTML file exists, it is to be replaced. + +{p 0 4} +{cmd:title()} specifies a string to be placed in the of the HTML page, +and on the first line of the body of the page, using a <H2> heading. + +{p} +The remaining options pertain to color choices. By default, +{cmd:loghtml} produces a complete HTML page (i.e. with <HTML> and <BODY> tags) +with a white background. Input lines (those resulting from user input) are +rendered in RGB color "CC6600" (a shade of brown) and highlighted +result-window lines are rendered in RGB color "000099" (a shade of blue). +The options permit other choices for these three colors. For best results, +one of the 216 "web safe" colors that display properly in web browsers on +all computers in 256-color mode should be used. Also note that some +combinations of colors are not workable; e.g. a black ("000000") background +will cause all normally-rendered text to disappear. + +{p 0 4} +{cmd:input()} allows the specification of a different color for the user input +lines, in standard RGB notation (three duples of two bytes, each 00-FF). + +{p 0 4} +{cmd:result()} allows the specification of a different color for the + highlighted result lines, in standard RGB notation. + +{p 0 4} +{cmd:bg()} allows the specification of a different color for the background, in +standard RGB notation. For convenience, the argument may be given as "gray" +or "grey", approximating most browsers' default behavior. + + +{title:Examples} + +{p 4 8}{inp:. log using autostudy, replace}{p_end} +{p 4 8}{inp:. use auto}{p_end} +{p 4 8}{inp:. desc}{p_end} +{p 4 8}{inp:. summ}{p_end} +{p 4 8}{inp:. regress price mpg rep78}{p_end} +{p 4 8}{inp:. log close} + +{p 4 8}{inp:. log2html7 autostudy, replace} + +{p 4 8}{inp:. log2html7 autostudy, replace ti("Automobile study")} + +{p 4 8}{inp:. log2html7 autostudy, replace in(ff3300) res(003333) bg(grey)} + + +{title:Reference} + + Priester, Gary W. 2000. All you need to know about web safe colors. + {browse "http://www.webdevelopersjournal.com/articles/websafe1/websafe_colors.html"} + + +{title:Acknowledgements} + + We acknowledge Ken Higbee's assistance with the documentation of + {cmd:log html} and suggestions for improvement of this routine. + + +{title:Authors} + + Christopher F Baum, Boston College, USA + baum@bc.edu + + Nicholas J. Cox, University of Durham, UK + n.j.cox@durham.ac.uk + + +{title:Also see} + + Manual: {hi:[R] log}, {hi:[P] smcl} +On-line: help for {help log}, {help smcl} + diff --git a/Modules/ado/plus/l/logout.ado b/Modules/ado/plus/l/logout.ado new file mode 100644 index 0000000..4a72ea4 --- /dev/null +++ b/Modules/ado/plus/l/logout.ado @@ -0,0 +1,2672 @@ +*! version 1.0.4 05nov2009 logout by roywada@hotmail.com +*! Converts log or ASCII files into various output formats + +program define logout + +local _original `0' + + versionSet + version `version' + +/* "using" no longer used +* encase the colon in file name in quotes, avoiding string function length limits + +local behind `"`0'"' +local 0 "" +gettoken front behind: behind, parse(" ,") +local 0 "" +local done 0 +while `"`front'"'~="" & `done'==0 { + if `"`front'"'=="using" { + + gettoken rest behind: behind, parse(" ,") + * strip off quotes + gettoken first second: rest, parse(" ") + cap local rest: list clean local(rest) + + * take off colon at the end + local goldfish "" + if index(`"`rest'"',":")~=0 { + local end=substr(`"`rest'"',length(`"`rest'"'),length(`"`rest'"')) + if "`end'"==":" { + local rest=substr(`"`rest'"',1,`=length(`"`rest'"')-1') + local goldfish " : " + } + } + + * colon reattached with a space at the end + * .txt attached here for seeout working with _pref.ado + local rabbit `"""' + if index(`"`rest'"', ".")==0 { + local using `"`rabbit'`rest'.txt`rabbit'`goldfish'"' + } + else { + local using `"`rabbit'`rest'`rabbit'`goldfish'"' + } + local 0 `"`0' using `using' `behind'"' + local done 1 + } + else { + local 0 `"`0' `front'"' + gettoken front behind: behind, parse(" ,") + } +} +*/ + + +gettoken first second : 0, parse(":") `bind' match(par) quotes +local 0 `"`first'"' +while `"`first'"'~=":" & `"`first'"'~="" { + gettoken first second : second, parse(":") `bind' match(par) quotes +} +if `"`0'"'==":" { + * colon only when shorthand combined with prefix + local 0 +} +else { + * not used + local _0 `"`0'"' +} + +*** shorthand syntax if use file is missing +syntax[, use(string) save(string) FIX1(numlist) clear FIX fixcut(numlist) text smcl* range(string asis)] + + if "`fixcut'"~="" { + local fix fix + } + + if "`clear'"~="clear" { + preserve + } + + if "`fix1'"~="" { + local fix "fix" + } + + if "`Version7'"=="" & "`fix'"=="" { + * must be fix + local fix fix + noi di in yellow "fix option inserted" + } + + * regular stuff + if `"`use'"'~="" { + * with use file + * `second' could contain " " only ??? + + gettoken a b : second, parse(" ") + if `"`a'"'~="" { + noi di in red "cannot combine {opt use( )} with command statements at end; use one or the other" + exit 198 + } + + if "`fix1'"=="" { + local fix1 5 + } + + *`second' + if `"`range'"'~="" { + tempfile capfile2 + gettoken one two: range, parse("/") + gettoken splash two: two, parse("/") + _chewfile using `"`use'"', save(`capfile2') replace begin(`one') end(`two') + + _logout, use(`"`capfile2'"') save(`"`save'"') `options' fix1(`fix1') `clear' `fix' fixcut(`fixcut') original(`_original') range(`range') + } + else { + _logout, use(`"`use'"') save(`"`save'"') `options' fix1(`fix1') `clear' `fix' fixcut(`fixcut') original(`_original') range(`range') + } + } + else { + * with temporary file + tempfile capfile + local tempfile tempfile + + if "`Version7'"=="" { + * a permanent file name for version 7 + local capfile "logout.txt" + } + + * `second' could contain " " only + gettoken a b : second, parse(" ") + if `"`a'"'~="" { + cap unabcmd `a' + if _rc==0 { + * it's a command + if (`"`r(cmd)'"'=="table" | `"`r(cmd)'"'=="tabstat") & "`fix1'"=="" { + local fix1 1 + } + } + if "`fix1'"=="" { + local fix1 5 + } + + noi caplog using `"`capfile'"', tempfile replace `text' `smcl' subspace: `second' + + if `"`range'"'~="" { + tempfile capfile2 + gettoken one two: range, parse("/") + gettoken splash two: two, parse("/") + _chewfile using `"`capfile'"', save(`capfile2') replace begin(`one') end(`two') + + _logout, use(`"`capfile2'"') save(`"`save'"') `options' fix1(`fix1') tempfile `clear' `fix' fixcut(`fixcut') original(`_original') range(`range') + } + else { + _logout, use(`"`capfile'"') save(`"`save'"') `options' fix1(`fix1') tempfile `clear' `fix' fixcut(`fixcut') original(`_original') range(`range') + } + } + else { + + if "`fix1'"=="" { + local fix1 5 + } + + * range needs to be activated here for dataout functionality + _logout, save(`"`save'"') `options' fix1(`fix1') `clear' `fix' fixcut(`fixcut') original(`_original') range(`range') + } + } +end + + +******************************************************************************************** + + +program define _logout + + versionSet + version `version' + +*syntax [using/] , [save(string) nounwrap excel word tex col row ignore(string) drop(string) clear dta ] +syntax, [ save(string) use(string) nounwrap NOWIPE excel dta tex word clear /* + */ NOAUTO raw right FIX FIX1(numlist >=-100 <=100 max=1) replace tempfile /* + */ auto(integer 3) dec(numlist int >=0 <=11) fixcut(numlist) range(str asis)] original(str asis) + +* note: options original and range are not really used here: + +qui { + +local colsizeMax 1 +if `"`save'"'~="" { + * assign save name + local beg_dot = index(`"`save'"',".") + if `beg_dot'~=0 { + local strippedname = substr(`"`save'"',1,`=`beg_dot'-1') + local save `"`strippedname'.txt"' + } + else { + * `save' has no extension + local strippedname `"`save'"' + local save `"`save'.txt"' + } + + cap confirm file `"`save'"' + if !_rc & "`replace'"~="replace" { + * it exists + noi di in red `"`save' exists; specify {opt replace}"' + exit 198 + } +} +else { + tempfile tempsave + local save `"`tempsave'"' +} + +if "`use'"~="" { + + if "`tempfile'"~="tempfile" { + local beg_dot = index(`"`use'"',".") + if `beg_dot'~=0 { + local strippedname1 = substr(`"`use'"',1,`=`beg_dot'-1') + + * no need to reassign name + *local use `"`strippedname1'.txt"' + } + else { + * `use' has no extension + local strippedname1 `"`use'"' + local use `"`use'.txt"' + } + } + + if "`drop'"~="" { + if "`unwrap'"=="nounwrap" { + noi di in red "Cannot combine {opt nounwrap} and {opt drop( )}" + exit 198 + } + else { + local unwrap "unwrap" + } + } + + + clear + + cap file close _all + + *local 0 `"using `0'"' + tempname source saving + + if "`unwrap'"~="nounwrap" { + *** wrapping text problem ONLY + + local linenum = 0 + + file open `source' using `"`use'"', read + file open `saving' using `"`save'"', write text replace + + file read `source' line + + * first line + if r(eof)==0 { + local linenum = `linenum' + 1 + local last_macvalline `"`macval(line)'"' + file read `source' line + } + + * subsequent lines + local _n + while r(eof)==0 { + + local linenum = `linenum' + 1 + cap tokenize `"`macval(last_macvalline)'"', parse(" []:") + + * handle the grave accent thing + if _rc~=0 { + noi di in yel `"line `linenum' contains a grave accent (or something), attempt was made to convert it into "grave_accent""' + local last_macvalline : subinstr local last_macvalline "`" "grave_accent", all + + gettoken 1 2 : last_macvalline, parse(" []:") + } + + if `"`1'"'==">" { + * remove the first instance of ">" + local last_macvalline : subinstr local last_macvalline "> " "" + file write `saving' `"`macval(last_macvalline)'"' + } + else { + file write `saving' `_n' + cap file write `saving' `"`macval(last_macvalline)'"' + if _rc~=0 { + noi di in yel `"line `linenum' was unable to be written, left blank"' + file write `saving' "" + } + } + local _n "_n" + + local last_macvalline `"`macval(line)'"' + file read `source' line + } + * the last line + + local linenum = `linenum' + 1 + cap tokenize `"`macval(last_macvalline)'"', parse(" []:") + + * handle the grave accent thing + if _rc~=0 { + noi di in yel `"line `linenum' contains a grave accent (or something), attempt was made to convert it into "grave_accent""' + local last_macvalline : subinstr local last_macvalline "`" "grave_accent", all + + gettoken 1 2 : last_macvalline, parse(" []:") + } + + if `"`1'"'==">" { + * remove the first instance of ">" + local last_macvalline : subinstr local last_macvalline ">" "" + file write `saving' `"`macval(last_macvalline)'"' + } + else { + file write `saving' `_n' + cap file write `saving' `"`macval(last_macvalline)'"' + if _rc~=0 { + noi di in yel `"line `linenum' was unable to be written, left blank"' + file write `saving' "" + } + } + local _n "_n" + + * close out with the last line + file write `saving' _n + + file close `source' + file close `saving' + } + + + if "`unwrap'"~="nounwrap" { + file open `source' using `"`save'"', read + } + else { + file open `source' using `"`use'"', read + } + + if "`fix'"=="fix" { + *** fix files + _logfix, use(`use') fix1(`fix1') fixcut(`fixcut') + } + else { + *** delimited files + + local col_size 98 + + local linenum = 1 + + file read `source' line + local OBS 50 + set obs `OBS' + + + if "`raw'"=="raw" { + gen str7 raw="" + replace raw=`"`line'"' in 1 + + local _format= "`: format raw'" + local _widths=substr("`_format'",2,length(trim("`_format'"))-2) + format raw %-`_widths's + } + + + gen rowLine=. + gen tokenMax=. + + * this adjusted + forval num=1/`colsizeMax' { + gen str2 t`num'="" + } + + + while r(eof)==0 { + if `linenum'>`OBS'-1 { + local OBS=`OBS'+50 + cap set obs `OBS' + if _rc==198 { + noi di in red "Cannot increase observation number beyond `OBS': probably need more memory" + } + } + + *display %4.0f `linenum' _asis `" `macval(line)'"' + + local checking=substr(trim(`"`macval(line)'"'),1,5) + *noi di `"`checking'"' + + if `"`checking'"'=="-----" { + replace rowLine=`linenum' in `linenum' + replace t1=`"`checking'"' in `linenum' + } + else { + local macvalline `"`macval(line)'"' + local macvalline : subinstr local macvalline "Prob > chi2" "Prob>chi2", all + local macvalline : subinstr local macvalline "Number of groups" "Number_of_groups", all + local macvalline : subinstr local macvalline "Obs per group: min" "Obs_per_group_min", all + + local macvalline : subinstr local macvalline "Number of obs" "Number_of_obs", all + local macvalline : subinstr local macvalline "Root MSE" "Root_MSE", all + local macvalline : subinstr local macvalline "Prob > F" "Prob>F", all + + local macvalline : subinstr local macvalline "Std. Err." "Std.Err.", all + local macvalline : subinstr local macvalline "Std. Dev." "Std.Dev.", all + local macvalline : subinstr local macvalline "95% Conf." "95%_Conf.", all + local macvalline : subinstr local macvalline "Sum of Wgt." "Sum_of_Wgt.", all + local macvalline : subinstr local macvalline "log pseudolikelihood" "log_pseudolikelihood", all + + cap tokenize `"`macvalline'"', parse(" []:`=char(9)'") + + * handle the grave accent thing + if _rc~=0 { + noi di in yel `"line `linenum' contains a grave accent (or something), attempt was made to convert it into "grave_accent""' + local macvalline : subinstr local macvalline "`" "grave_accent", all + + tokenize `"`macvalline'"', parse(" []:`=char(9)'") + } + + * numToken is the token number + * numCol is the column number + local numToken=1 + local numCol=1 + + local stop "" + replace rowLine=`linenum' in `linenum' + while `"``numToken''"'~="" & "`stop'"~="stop" { + + if `"``numToken''"'~="[" & /* + */ `"``numToken''"'~="]" & /* + */ `"``numToken''"'~=":" & /* + */ `"``numToken''"'~="|" & /* + */ `"``numToken''"'~="`=char(9)'" { + + * add more columns if necessary + if `numToken'>=`colsizeMax' { + local colsizeMax=`colsizeMax'+1 + gen str2 t`colsizeMax'="" + if "`c(flavor)'"=="small" & `colsizeMax'>=`col_size' { + noi di in yel `"Stata flavor "small", unable to have more than 99 columns"' + local stop stop + } + } + + *noi di in red `"``numToken''"' _c + *noi di in green "" + + replace t`numCol'=`"``numToken''"' in `linenum' + + /* + * auto-digits + local check = `"``numToken''"' + capture confirm number `check' + + *noi di in green "`=_rc'" + + if _rc==0 & "`noauto'"~="noauto" { + + * only if a number + autodigits2 `"``numToken''"' `auto' + local valstr = string(`check',"%12.`r(valstr)'") + + *noi di in yel `"`valstr'"' + + /* prevent adding non-signnificant 0 at the end + ****** does NOT handle scientific notations, or does it? + local beg_dot1 = index(`"``numToken''"',".") + local stripped1 = substr(`"``numToken''"',`=`beg_dot1'+1',.) + local length1 : length local stripped1 + + local beg_dot2 = index(`"`valstr'"',".") + local stripped2 = substr(`"`valstr'"',`=`beg_dot2'+1',.) + local length2 : length local stripped2 + + if `length2'<=`length1' & `length2'~=0 & `beg_dot2'~=0 & `length1'>0 { + replace t`numCol'=`"`valstr'"' in `linenum' + } + else { + replace t`numCol'=`"``numToken''"' in `linenum' + } */ + + replace t`numCol'=`"`valstr'"' in `linenum' + } + else { + * only if not a number + replace t`numCol'=`"``numToken''"' in `linenum' + } + */ + replace tokenMax=`numCol' in `linenum' + local numCol=`numCol'+1 + } + local numToken=`numToken'+1 + } + } + file read `source' line + + * noi di `"`macval(line)' dd `r(eof)'"' + + local linenum = `linenum' + 1 + if "`raw'"=="raw" { + replace raw=`"`macval(line)'"' in `linenum' + } + } + + + /* works with pre-tokenized columns, but not used because tokenize better if already unwrapped as above, + * mostly due to the handling of rabbit-ears poking out + + * wrapping text problem + if "`unwrap'"~="nounwrap" { + * skip first line + forval num=`=_N'(-1)2 { + if token1==">" in `num' { + * counter keeps track of which column being moved to the right end of the previous row + * token1 is skipped since it has < + forval counter=2/`=tokenMax[`num']' { + replace t`=tokenMax[`num'-1]+`=`counter'-1''=t`counter'[`num'] in `=`num'-1' + } + replace tokenMax=tokenMax[`num'-1]+tokenMax[`num'] in `=`num'-1' + } + } + } + */ + + /* this is slow + local num `colsizeMax' + local stop "" + while `num' > 1 & "`stop'"=="" { + count if t`num'=="" + if r(N)==_N { + drop t`num' + } + else { + local stop "stop" + } + local num=`num'-1 + } + */ + + + * clean up + if "`row'"~="row" { + drop rowLine + } + if "`col'"~="col" { + drop tokenMax + } + + * drop extra columns indiscriminately + * this is slow + foreach var of varlist _all { + count if `var'=="" + if r(N)==_N { + drop `var' + } + } + + * drop from top + gen rowmiss=0 + foreach var of varlist _all { + * cap because rowmiss is non-string + cap replace rowmiss=rowmiss+1 if `var'~="" & "`var'"~="rowmiss" + } + local N=_N + local oldN + while "`N'"~="`oldN'" { + local oldN=_N + drop in 1 if rowmiss==0 + local N=_N + } + + * drop from bottom + local N=_N + local oldN + while "`N'"~="`oldN'" { + local oldN=_N + drop in `oldN' if rowmiss==0 + local N=_N + } + drop rowmiss + + file close `source' + file close _all + } /*** delimited files */ +} /* if "`using'"~="" */ + + +if "`nowipe'"~="nowipe" & "`fix'"~="fix" { + cap drop if t1=="-----" | t1=="opened" | t1=="log" | t1=="." | t1=="closed" +} + + +/* workaround to see if heading should be reported +local noheading 0 +local test 0 +foreach var of varlist + local temp=instr("`var'",1,2) + capture confirm string `temp' + if _rc==0 { + local * only if a string + local test 1 + } + } + local temp=instr("`var'",2,3) + capture confirm number `temp' + if _rc==0 & "`test'"=="1" { + * only if a number + local noheading=`noheading'+1 + } + } +} +*/ + +* replace the gap holders for value labels +* heading for _dataout +if "`use'"~="" | "`clear'"=="clear" { + * not being used as dataout + local head "head" + foreach var of varlist _all { + replace `var'= subinstr(`var',"_"," ",.) + local heading "nohead" + } + else { + *local heading "head" + * make it always nohead + local heading "nohead" + } +} + + +local heading "nohead" + + +} /* quietly */ + + +* display the fix command +if "`fixcutCollect'"~="" { + *di in yel `" logcut`original' fixcut(`fixcutCollect')"' + gettoken one two: fixcutCollect, parse(" ") + di in yel `" fixcut(`one'`two')"' +} + + +* display unless temp file was used or not given at all (used the current file in memory) +if "`tempfile'"~="tempfile" & `"`usingTerm'"'~="" { + local usingTerm `"`use'"' + local cl_text `"{browse `"`usingTerm'"'}"' + noi di as txt `"`cl_text'"' +} + +* export files +local doit +local doit "`doit'`excel'" +local doit "`doit'`word'" +local doit "`doit'`tex'" +local doit "`doit'`dta'" + +if `"`doit'"'~="" { + di + + * add one row if 2 or less + local N=_N + if `N'<3 { + qui { + tempvar order + if `N'==0 { + set obs 3 + } + else { + * `N'==1 | `N'==2 + gen `order'=_n + set obs 3 + local N=_N + replace `order'=0 in `N' + sort `order' + drop `order' + } + } + } + + if "`dec'"~="" { + local noauto "noauto" + } + + if "`save'"=="" { + noi di in red "must specify {opt save( )}" + exit 198 + } + + * workaround for names + ds8 + local names `"`r(varlist)'"' + + local strippednameUse `"`strippedname'"' + if `"`strippedname'"'=="" { + local strippednameUse `"`strippedname1'"' + } + + _dataout, save(`"`strippednameUse'"') `excel' `tex' `word' `dta' `replace' `heading' `noauto' auto(`auto') dec(`dec') + + * folder + _cdout + + local num 1 + foreach var of varlist _all { + local temp: word `num' of `names' + ren `var' `temp' + local num=`num'+1 + } +} + +/* +file open `saving' using `save', write text replace +forval linenum=1/`=_N' { + local content=raw[`linenum'] + file write `saving' `"`macval(content)'"' _n + local linenum = `linenum' + 1 +} +file close _all +*/ + + +end + + +******************************************************************************************** + + +program define _logfix + + versionSet + version `version' + +qui { + +syntax, use(string) FIX1(numlist) [fixcut(numlist)] + + *** determine the widths of file + local infix + forval num=1/45 { + local infix "`infix' str1 t`num' `num'-`num'" + } + infix `infix' using `"`use'"', clear + local col_size 45 + + * checking the end of file: + count if t41~="" + local rN41 `r(N)' + + count if t42~="" + local rN42 `r(N)' + + count if t43~="" + local rN43 `r(N)' + + count if t44~="" + local rN44 `r(N)' + + count if t45~="" + local rN45 `r(N)' + + local count=`rN41'+`rN42'+`rN43'+`rN44'+`rN45' + if `count'~=0 { + * do over + local infix + forval num=1/495 { + local infix "`infix' str1 t`num' `num'-`num'" + } + infix `infix' using `"`use'"', clear + local col_size 495 + } + + *drop if t1=="-" & t2=="-" & t3=="-" & t4=="-" & t5=="-" + + _infix, use(`use') fix1(`fix1') col_size(`col_size') fixcut(`fixcut') + + /* example + gen indicate=1 if rowmiss==0 + replace indicate=sum(indicate) + + + + *logout, save(mystuff1) excel fix(10) replace noauto: reg price mpg rep78 head + *logout, save(mystuff2) excel nowipe replace noauto: reg price mpg rep78 head + + _infix in 8/`=_N', use(`use') fix1(10) col_size(`col_size') fixcut(`fixcut') + + gen wave=2 + save fixing, replace + + _infix in 1/7, use(`use') fix1(19) col_size(`col_size') fixcut(`fixcut') + + append using fixing + replace wave=1 if wave==. + + aorder t* + browse + logleft, wave_top(1) wave_bot(2) + browse + */ + + + cap drop rowmiss + cap drop indicate +} + +* return +c_local fixcutCollect `"`fixcutCollect'"' + +end /* logfix */ + + +******************************************************************************************** + + +program define logleft + + syntax, wave_top(numlist) wave_bot(numlist) + unab varList: t* + tokenize `varList' + local varCount: word count varList + local var1 1 + local var2 2 + + while "``var2''"~="" { + count if ``var1''~="" & wave==`wave_top' + local rN1_top=r(N) + count if ``var1''~="" & wave==`wave_bot' + local rN1_bot=r(N) + + count if ``var2''~="" & wave==`wave_top' + local rN2_top=r(N) + count if ``var2''~="" & wave==`wave_bot' + local rN2_bot=r(N) + + if `rN1_top'~=0 & `rN1_bot'==0 & `rN2_top'==0 & `rN2_bot'~=0 { + replace ``var1''=``var2'' if wave==`wave_bot' + drop ``var2'' + local var1=`var1'+1 + local var2=`var2'+1 + } + else if `rN1_top'==0 & `rN1_bot'~=0 & `rN2_top'~=0 & `rN2_bot'==0 { + replace ``var1''=``var2'' if wave==`wave_top' + drop ``var2'' + local var1=`var1'+1 + local var2=`var2'+1 + } + else if `rN1_top'==0 & `rN1_bot'==0 { + drop ``var1'' + } + local var1=`var1'+1 + local var2=`var2'+1 + } + +end + + +******************************************************************************************** + + +program define _infix + + versionSet + version `version' + +qui { + +syntax [in], use(string) FIX1(numlist) col_size(numlist) [fixcut(numlist)] + local infix + forval num=1/`col_size' { + local infix "`infix' str1 t`num' `num'-`num'" + } + infix `infix' `in' using `"`use'"', clear + +* must be beyond square +local N=_N +if `N'<`col_size' { + local new_size=`col_size'+5 + set obs `new_size' +} + +* replace the lines +ds8 + +tokenize `dsVarlist' +local num 0 +local one=1+`num' +local two=2+`num' +local three=3+`num' + +* 165, 127, 216 +while "``three''"~="" { + + replace ``one''="„Ű" if ``one''=="-" & ``two''=="-" & ``three''=="-" + replace ``two''="„Ű" if ``one''=="„Ű" & ``two''=="-" & ``three''=="-" + replace ``three''="„Ű" if ``one''=="„Ű" & ``two''=="„Ű" & ``three''=="-" + replace ``three''="„Ű" if ``one''=="„Ű" & ``two''=="„Ű" & ``three''=="+" + + local num=`num'+1 + local one=1+`num' + local two=2+`num' + local three=3+`num' +} + +ds8 +local thisMany: word count `dsVarlist' + + +gen height=. +forval num=1/`col_size' { + qui count if t`num'~="" & t`num'~="„Ű" + di "`r(N)' " _c + replace height=`r(N)' in `num' +} + +/* +gen id=_n if _n<=100 +line height id + +sort height +drop id +gen id=_n if _n<=100 +line height id +*/ + +sum height, det + + +forval wave=1/50 { + + * limit + local times=`fix1'/1000*`wave' + local parameter=`r(max)'*`times' + + gen trend`wave'=. + replace trend`wave'=-1 if (height<height[_n-1]-`parameter' & height[_n-1]~=.) + + gen minima`wave'=. + *replace minima`wave'=1 if trend`wave'==-1 & height<`parameter' + replace minima`wave'=1 if trend`wave'==-1 + + * replace if still dropping in height + forval num=1/10 { + replace minima`wave'=0 if minima`wave'==1 & height>=height[_n+1]==1 + replace minima`wave'=1 if minima`wave'[_n-1]==0 & minima`wave'==. + } +} + +egen minima=rsum(minima*) +order minima* + +*tab minima + +/* +local infix +local begin 1 + +forval num=1/`thisMany' { + local content=minima[`num'] + if `content'>25 { + local width=`num'-`begin'+1 + local infix "`infix' str`width' t`num' `begin'-`num'" + local begin=`num'+1 + } +} +* noi di "`infix'" + +infix `infix' `in' using `"`use'"', clear +*/ + +local infix +local fixcutCollect +local begin 1 + +* automatically infix +forval num=1/`thisMany' { + local content=minima[`num'] + if `content'>25 { + local width=`num'-`begin'+1 + local infix "`infix' str`width' t`num' `begin'-`num'" + local fixcutCollect "`fixcutCollect' `num'" + local begin=`num'+1 + } +} +*noi di in red "`infix'" +*noi di in red "`fixcutCollect'" +infix `infix' `in' using `"`use'"', clear + +if "`fixcut'"~="" { + + local infix + local fixcutCollect + local begin 1 + + * manually infix + local num 1 + tokenize `fixcut' + while "``num''"~="" { + local width=``num''-`begin'+1 + local infix "`infix' str`width' t``num'' `begin'-``num''" + local fixcutCollect "`fixcutCollect' ``num''" + local begin=``num''+1 + local num=`num'+1 + } + *noi di in red "`infix'" + *noi di in red "`fixcutCollect'" + infix `infix' `in' using `"`use'"', clear + local fixcut fixcutCollect +} + +* drop verticals first +local N=_N +foreach var of varlist _all { + count if `var'=="|" + if `r(N)'>.5*`N' { + drop `var' + } +} + +* stronger codes for manual infix as well +* replace the horizontal lines +tempvar length test +cap gen `length'=. +cap gen `test'=. +foreach var of varlist _all { + cap replace `length'=length(`var') + cap replace `test'=(`length'-length(subinstr(`var',"-","",.)))/`length' if `length'>2 + cap replace `var'="" if `test'>=0.5 +} +drop `length' `test' + + /* older + * replace the horizontal lines + tempvar length test + cap gen `length'=. + cap gen str7 `test'="" + foreach var of varlist _all { + cap replace `length'=length(`var') + cap replace `test'=subinstr(`var',"-","",.) if `length'>2 + cap replace `var'="" if `test'=="" + } + drop `length' `test' + */ + + /* oldest + replace the horizontal lines + foreach var of varlist _all { + local N=_N + forval num=1/`N' { + local content=`var'[`num'] + local length=length(`"`content'"') + if `length'>2 { + local test : subinstr local content "-" "", all + if "`test'"=="" { + replace `var'="" in `num' + } + } + } + } + */ + +compress + + +} /* quietly */ + +************ needs to cut at left if not rising anymore + +* drop extra columns indiscriminately +* this is slow +foreach var of varlist _all { + count if `var'=="" + if r(N)==_N { + drop `var' + } +} + + +* drop from top +gen rowmiss=0 +foreach var of varlist _all { + * cap because rowmiss is non-string + cap replace rowmiss=rowmiss+1 if `var'~="" & "`var'"~="rowmiss" +} +local N=_N +local oldN +while "`N'"~="`oldN'" { + local oldN=_N + drop in 1 if rowmiss==0 + local N=_N +} + + + +* drop from bottom +local N=_N +local oldN +while "`N'"~="`oldN'" { + local oldN=_N + drop in `oldN' if rowmiss==0 + local N=_N +} + + +* return +c_local fixcutCollect `"`fixcutCollect'"' + +end /* _infix */ + + +******************************************************************************************** + + +*** ripped from dataout Apr 2008 +program define _dataout + +syntax [using/], [save(string) excel tex word dta NOHEAD HEAD replace NOAUTO auto(integer 3) dec(numlist int >=0 <=11)] +version 7 + +if "`fix1'"~="" { + local fix "fix" +} + +if `"`using'"'=="" & "`save'"=="" { + noi di in red "must specify {opt using} or {opt save( )}" + exit 198 +} + +if "`using'"~="" { + * attach .txt if nothing attached + local beg_dot = index(`"`using'"',".") + if `beg_dot'==0 { + local using `"`using'.txt"' + } +} + + +if "`save'"=="" { + * assign save name + local beg_dot = index(`"`using'"',".") + local strippedname = substr(`"`using'"',1,`=`beg_dot'-1') + local save "`strippedname'_logout.txt" +} +else { + * assign save name + local beg_dot = index(`"`save'"',".") + if `beg_dot'~=0 { + local strippedname = substr(`"`save'"',1,`=`beg_dot'-1') + local save `"`strippedname'.txt"' + } + else { + * `save' has no extension + local strippedname `"`save'"' + local save `"`save'.txt"' + } + + + if `"`using'"'=="" { + * if using file was not specified but save was: + local beg_dot = index(`"`save'"',".") + if `beg_dot'~=0 { + local strippedname = substr(`"`save'"',1,`=`beg_dot'-1') + } + else { + local strippedname `"`save'"' + } + } +} + + +qui { + +if `"`using'"'~="" { + preserve + qui insheet using `"`using'"', noname clear +} + +*foreach var of varlist _all { +* tostring `var', replace force +*} +stringMaker + +if "`dec'"~="" { + * apply decimals + foreach var of varlist _all { + local N=_N + forval num=1/`N' { + local content=`var'[`num'] + + capture confirm number `content' + if _rc==0 { + * only if a number + replace `var' = string(`content',"%12.`dec'fc") in `num' + } + else { + * only if not a number + *replace `var'=`"`content'"' in `num' + } + } + } +} + + + +if "`noauto'"~="noauto" & "`dec'"=="" { + * apply autodigits + foreach var of varlist _all { + local N=_N + forval num=1/`N' { + local content=`var'[`num'] + + capture confirm number `content' + if _rc==0 { + * only if a number + autodigits2 `content' `auto' `less' + replace `var' = string(`content',"%12.`r(valstr)'") in `num' + } + else { + * only if not a number + *replace `var'=`"`content'"' in `num' + } + } + } +} + + +if ("`nohead'"~="nohead" & `"`using'"'=="") | "`head'"=="head" { + * moves the variable names down + local N=_N+1 + tempvar id + gen `id'=_n + set obs `N' + replace `id'=0 in `N' + sort `id' + drop `id' + local num 1 + foreach var of varlist _all { + replace `var'="`var'" in 1 + } +} + + +* needs to be renamed regardless +local num 1 +foreach var of varlist _all { + ren `var' v`num' + local num=`num'+1 +} + + + + +*** dta file thing +if "`dta'"=="dta" { + cap confirm file `"`strippedname'.dta"' + if !_rc & "`replace'"~="replace" { + * it exists + noi di in red `"`strippedname'.dta exists; specify {opt replace}"' + exit 198 + } + + save `"`strippedname'"', replace + + *local usingTerm `"`strippedname'.dta"' + *local cl `"{browse logout, seefile(`"`usingTerm'"'):`usingTerm'}"' + *noi di as txt `"`cl'"' +} + + +*** Excel xml file thing +if "`excel'"=="excel" { + tempfile file1 + + cap confirm file `"`strippedname'.xml"' + if !_rc & "`replace'"~="replace" { + * it exists + noi di in red `"`strippedname'.xml exists; specify {opt replace}"' + exit 198 + } + + save `file1', replace + if "`raw'"=="raw" { + replace raw=`"""' + raw + `"""' + } + +local titleWide 0 +local headBorder 1 +local N=_N +local bottomBorder `N' + + *use `outing',clear +* _xmlout using `"`strippedname'"', excelFile(`excelFile') nonames titleWide(`titleWide') /* +* */ headBorder(`headBorder') bottomBorder(`bottomBorder') + + local N=_N + + _xmlout using `"`strippedname'"', nonames headBorder(1) bottomBorder(`N') + local usingTerm `"`strippedname'.xml"' + local cl `"{browse `"`usingTerm'"'}"' + noi di as txt `"`cl'"' + + use `file1', clear +} + + +if "`word'"=="word" | "`tex'"=="tex" { + cap preserve + if ("`nohead'"=="nohead" & `"`using'"'~="") & "`head'"~="head" { + * `using' indicates + * files not yet named v* + local num 1 + foreach var of varlist _all { + ren `var' v`num' + local num=`num'+1 + } + } + +*** Word rtf file thing +if "`word'"=="word" { + + cap confirm file `"`strippedname'.rtf"' + if !_rc & "`replace'"~="replace" { + * it exists + noi di in red `"`strippedname'.rtf exists; specify {opt replace}"' + exit 198 + } + +local titleWide 0 +local headBorder 2 +local N=_N +local bottomBorder `N' + +local totrows `N' + + * there must be varlist to avoid error + *_wordout v* `"`using'"', titleWide(`titleWide') headBorder(`headBorder') bottomBorder(`bottomBorder') replace nopretty + _wordout v* using `"`strippedname'"', wordFile(`wordFile') titleWide(`titleWide') /* + */ headBorder(`headBorder') bottomBorder(`bottomBorder') replace nopretty + local temp `r(documentname)' + + * strip off "using" and quotes + gettoken part rest: temp, parse(" ") + gettoken usingTerm second: rest, parse(" ") + + local cl_word `"{browse `"`usingTerm'"'}"' + noi di as txt `"`cl_word'"' + +} + +*** LaTeX thing +*** (will mess up the original file) +if "`tex'"=="tex" { + +local titleWide 0 +local headBorder 1 +local N=_N +local bottomBorder `N' + + cap confirm file `"`strippedname'.tex"' + if !_rc & "`replace'"~="replace" { + * it exists + noi di in red `"`strippedname'.tex exists; specify {opt replace}"' + exit 198 + } + + * make certain `1' is not `"`using'"' (another context) + + _texout v* using `"`strippedname'"', texFile(`texFile') titleWide(`titleWide') headBorder(`headBorder') bottomBorder(`bottomBorder') `texopts' replace + + if `"`texFile'"'=="" { + local endName "tex" + } + else { + local endName "`texFile'" + } + + local usingTerm `"`strippedname'.`endName'"' + local cl_tex `"{browse `"`usingTerm'"'}"' + noi di as txt `"`cl_tex'"' + +} +} + +} /* quietly */ + +end + + +******************************************************************************************** + + +*** ripped from outreg2 Mar 2008 +program define autodigits2, rclass +version 7.0 + +* getting the significant digits +args input auto less + +if `input'~=. { + local times=0 + local left=0 + + * integer checked by modified mod function + if round((`input' - int(`input')),0.0000000001)==0 { + local whole=1 + } + else { + local whole=0 + * non-interger + if `input'<. { + + * digits that need to be moved if it were only decimals: take the ceiling of log 10 of absolute value of decimals + local times=abs(int(ln(abs(`input'-int(`input')))/ln(10)-1)) + + * the whole number: take the ceiling of log 10 of absolute value + local left=int(ln(abs(`input'))/ln(10)+1) + } + } + + + * assign the fixed decimal values into aadec + if `whole'==1 { + local aadec=0 + } + else if .>`left' & `left'>0 { + * reduce the left by one if more than zero to accept one extra digit + if `left'<=`auto' { + local aadec=`auto'-`left'+1 + } + else { + local aadec=0 + } + } + else { + local aadec=`times'+`auto'-1 + } + + if "`less'"=="" { + * needs to between 0 and 11 + if `aadec'<0 { + local aadec=0 + } + *if `aadec'<11 { + if `aadec'<7 { + * use fixed + local valstr "`aadec'f" + } + else { + * use exponential + local valstr "`=`auto'-1'e" + } + } + else { + * needs to between 0 and 11 + local aadec=`aadec'-`less' + if `aadec'<0 { + local aadec=0 + } + *if `aadec'<10 { + if `aadec'<7 { + * use fixed + local valstr "`aadec'f" + } + else { + * use exponential + local valstr "`=`auto'-1'e" + } + } + + * make it exponential if too big + if `input'>1000000 & `input'<. { + local valstr "`=`auto'-0'e" + } + + * make it exponential if too negative (small) + if `input'<-1000000 & `input'<. { + local valstr "`=`auto'-0'e" + } + + return scalar value=`aadec' + return local valstr="`valstr'" +} +else { + * it is a missing value + return scalar value=. + return local valstr="missing" +} +end + + +******************************************************************************************** + + +* ripped from outreg2 on Apr2009 +* 27oct2009 nopretty fixed + +program define _texout, sortpreserve +* based on out2tex version 0.9 4oct01 by john_gallup@alum.swarthmore.edu +version 7.0 + + * add one if only one v* column exists + unab list: v* + local count: word count `list' + if `count'==1 { + gen str v2="" + order v* + } + if `count'==0 { + exit + } + + if "`1'" == "using" { + syntax using/ [, texFile(string) Landscape Fragment NOPRetty PRetty /* + */ Fontsize(numlist integer max=1 >=10 <=12) noBorder Cellborder /* + */ Appendpage noPAgenum a4 a5 b5 LETter LEGal EXecutive replace /* + */ Fast ] + + if "`pretty'"=="pretty" { + local nopretty "" + } + + if "`fast'" == "" { + preserve + } + + loadout using `"`using'"', clear + local numcol = `r(numcol)' + local titleWide = `r(titleWide)' + local headBorder = `r(headBorder)' + local bottomBorder = `r(bottomBorder)' + local totrows = _N + + local varname "v1" + unab statvars : v2-v`numcol' + } + else { + syntax varlist using/, titleWide(int) headBorder(int) bottomBorder(int) /* + */ [texFile(string) TOtrows(int 0) Landscape Fragment NOPRetty PRetty /* + */ Fontsize(numlist integer max=1 >=10 <=12) noBorder Cellborder /* + */ Appendpage noPAgenum a4 a5 b5 LETter LEGal EXecutive replace ] + if `totrows'==0 { + local totrows = _N + } + local numcols : word count `varlist' + gettoken varname statvars : varlist + local fast 1 + } + + if "`pretty'"=="pretty" { + local pretty "" + } + else { + local pretty "NOT PRETTY AT ALL" + } + + local colhead1 = `titleWide' + 1 + local strow1 = `headBorder' + 1 + + * insert $<$ to be handled in LaTeX conversion + local N=_N + forval num=`bottomBorder'/`N' { + local temp=v1[`num'] + tokenize `"`temp'"', parse (" <") + local count 1 + local newTex "" + local noSpace 0 + while `"``count''"'~="" { + if `"``count''"'=="<" { + local `count' "$<$" + local newTex `"`newTex'``count''"' + local noSpace 1 + } + else { + if `noSpace'~=1 { + local newTex `"`newTex' ``count''"' + } + else { + local newTex `"`newTex'``count''"' + local noSpace 0 + } + } + local count=`count'+1 + } + replace v1=`"`newTex'"' in `num' + } + + *** replace if equation column present + count if v1=="EQUATION" + if `r(N)'~=0 { + tempvar myvar + * use v2 instead + replace v1 = v2 in `=`bottomBorder'+1'/`totrows' + replace v2 = "" in `=`bottomBorder'+1'/`totrows' + + * change the string length + gen str5 `myvar' ="" + replace `myvar' =v2 + drop v2 + ren `myvar' v2 + order v1 v2 + } + + /* if file extension specified in `"`using'"', replace it with ".tex" for output + local next_dot = index(`"`using'"', ".") + if `next_dot' { + local using = substr("`using'",1,`=`next_dot'-1') + } + */ + + if `"`texFile'"'=="" { + local endName "tex" + } + else { + local endName "`texFile'" + } + + local using `"using "`using'.`endName'""' + local fsize = ("`fontsize'" != "") + if `fsize' { + local fontsize "`fontsize'pt" + } + local lscp = ("`landscape'" != "") + if (`lscp' & `fsize') { + local landscape ",landscape" + } + local pretty = ("`pretty'" == "") + local cborder = ("`cellborder'" != "") + local noborder = ("`border'" != "") + local nopagen = ("`pagenum'" != "") + local nofrag = ("`fragment'" == "") + + if `cborder' & `noborder' { + di in red "may not specify both cellborder and noborder options" + exit 198 + } + + local nopt : word count `a4' `a5' `b5' `letter' `legal' `executive' + if `nopt' > 1 { + di in red "choose only one of a4, a5, b5, letter, legal, executive" + exit 198 + } + local pagesize "`a4'`a5'`b5'`letter'`legal'`executive'" + if "`pagesize'"=="" | "`letter'"!="" { + local pwidth "8.5in" + local pheight "11in" + } + else if "`legal'"!="" { + local pwidth "8.5in" + local pheight "14in" + } + else if "`executive'"!="" { + local pwidth "7.25in" + local pheight "10.5in" + } + else if "`a4'"!="" { + local pwidth "210mm" + local pheight "297mm" + } + else if "`a5'"!="" { + local pwidth "148mm" + local pheight "210mm" + } + else if "`b5'"!="" { + local pwidth "176mm" + local pheight "250mm" + } + if `lscp' { + local temp "`pwidth'" + local pwidth "`pheight'" + local pheight "`temp'" + } + if "`pagesize'"!="" { + local pagesize "`pagesize'paper" + if (`lscp' | `fsize') { + local pagesize ",`pagesize'" + } + } + if `cborder' & `noborder' { + di in red "may not specify both cellborder and noborder options" + exit 198 + } + + quietly { + tempvar has_eqn st2_row last_st pad0 pad1 pad2_n padN order + + * replace % with \%, and _ with \_ if <2 $'s (i.e. not an inline equation: $...$ + * has_eqn indicates that varname has 2+ $'s + + gen byte `has_eqn' = index(`varname',"$") + + * make sure there are 2+ "$" in varname + replace `has_eqn' = index(substr(`varname',`has_eqn'+1,.),"$")>0 if `has_eqn'>0 + replace `varname'= subinstr(`varname',"_", "\_", .) if !`has_eqn' + replace `varname'= subinstr(`varname',"%", "\%", .) + + if `pretty' { + replace `varname'= subinword(`varname',"R-squared", "\$R^2$", 1) in `strow1'/`bottomBorder' + replace `varname'= subinstr(`varname'," t stat", " \em t \em stat", 1) in `bottomBorder'/`totrows' + replace `varname'= subinstr(`varname'," z stat", " \em z \em stat", 1) in `bottomBorder'/`totrows' + } + + foreach svar of local statvars { /* make replacements for column headings rows of statvars */ + replace `has_eqn' = index(`svar',"$") in `colhead1'/`headBorder' + replace `has_eqn' = index(substr(`svar',`has_eqn'+1,.),"$")>0 in `colhead1'/`headBorder' if `has_eqn'>0 + replace `svar'= subinstr(`svar',"_", "\_", .) in `colhead1'/`headBorder' if !`has_eqn' + replace `svar'= subinstr(`svar',"%", "\%", .) in `colhead1'/`headBorder' + + /* replace <, >, {, }, | with $<$, $>$, \{, \}, and $|$ in stats rows */ + /* which can be used as brackets by outstat */ + replace `svar'= subinstr(`svar',"<", "$<$", .) in `strow1'/`bottomBorder' + replace `svar'= subinstr(`svar',">", "$>$", .) in `strow1'/`bottomBorder' + replace `svar'= subinstr(`svar',"{", "\{", .) in `strow1'/`bottomBorder' + replace `svar'= subinstr(`svar',"}", "\}", .) in `strow1'/`bottomBorder' + replace `svar'= subinstr(`svar',"|", "$|$", .) in `strow1'/`bottomBorder' + } + + if `pretty' { /* make title fonts large; notes & t stats small */ + local blarge "\begin{large}" + local elarge "\end{large}" + local bfnsize "\begin{footnotesize}" + local efnsize "\end{footnotesize}" + } + if `cborder' { + local vline "|" + } + gen str20 `pad0' = "" + gen str20 `padN' = "" + if `titleWide' { + replace `pad0' = "\multicolumn{`numcols'}{`vline'c`vline'}{`blarge'" in 1 / `titleWide' + replace `padN' = "`elarge'} \\\" in 1 / `titleWide' + } + if `bottomBorder' < `totrows' { + local noterow1 = `bottomBorder' + 1 + replace `pad0' = "\multicolumn{`numcols'}{`vline'c`vline'}{`bfnsize'" in `noterow1' / l + replace `padN' = "`efnsize'} \\\" in `noterow1' / l + } + + gen str3 `pad1' = " & " in `colhead1' / `bottomBorder' + if `numcols' > 2 { + gen str3 `pad2_n' = `pad1' + } + if `pretty' { /* make stats 2-N small font */ + local strow1 = `headBorder' + 1 + gen byte `st2_row' = 0 + replace `st2_row' = (trim(`varname') == "") in `strow1' / `bottomBorder' /* only stats 2+ */ + gen byte `last_st' = (`st2_row' & `varname'[_n+1] != "") /* last stats row */ + if !`cborder' { + replace `pad0' = "\vspace{4pt}" if `last_st' + } + replace `pad1' = `pad1' + "`bfnsize'" if `st2_row' + if `numcols' > 2 { + replace `pad2_n' = "`efnsize'" + `pad2_n' + "`bfnsize'" if `st2_row' + } + replace `padN' = "`efnsize'" if `st2_row' + } + + replace `padN' = `padN' + " \\\" in `colhead1' / `bottomBorder' + if `cborder' { + replace `padN' = `padN' + " \hline" + } + else { + if !`noborder' { + if `headBorder' { + if `titleWide' { + replace `padN' = `padN' + " \hline" in `titleWide' + } + replace `padN' = `padN' + " \hline" in `headBorder' + } + replace `padN' = `padN' + " \hline" in `bottomBorder' + } + } + + local vlist "`pad0' `varname' `pad1'" + tokenize `statvars' + local ncols_1 = `numcols' - 1 + local ncols_2 = `ncols_1' - 1 + forvalues v = 1/`ncols_2' { + local vlist "`vlist' ``v'' `pad2_n'" + } + local vlist "`vlist' ``ncols_1'' `padN'" + + local texheadfootrows = `nofrag' + `pretty' + 1 /* in both headers and footers */ + local texheadrow = 2 * `nofrag' + `nopagen' + `texheadfootrows' + local texfootrow = `texheadfootrows' + local newtotrows = `totrows' + `texheadrow' + `texfootrow' + if `newtotrows' > _N { + local oldN = _N + set obs `newtotrows' + } + else { + local oldN = 0 + } + gen long `order' = _n + `texheadrow' in 1 / `totrows' + local newtexhrow1 = `totrows' + 1 + local newtexhrowN = `totrows' + `texheadrow' + replace `order' = _n - `totrows' in `newtexhrow1' / `newtexhrowN' + sort `order' + + + * insert TeX header lines + local ccc : display _dup(`ncols_1') "`vline'c" + if `nofrag' { + replace `pad0' = "\documentclass[`fontsize'`landscape'`pagesize']{article}" in 1 + replace `pad0' = "\setlength{\pdfpagewidth}{`pwidth'} \setlength{\pdfpageheight}{`pheight'}" in 2 + replace `pad0' = "\begin{document}" in 3 + replace `pad0' = "\end{document}" in `newtotrows' + } + if `nopagen' { + local row = `texheadrow' - 1 - `pretty' + replace `pad0' = "\thispagestyle{empty}" in `row' + } + if `pretty' { + local row = `texheadrow' - 1 + replace `pad0' = "\begin{center}" in `row' + local row = `newtotrows' - `texfootrow' + 2 + replace `pad0' = "\end{center}" in `row' + } + local row = `texheadrow' + replace `pad0' = "\begin{tabular}{`vline'l`ccc'`vline'}" in `row' + if (!`titleWide' | `cborder') & !`noborder' { + replace `pad0' = `pad0' + " \hline" in `row' + } + local row = `newtotrows' - `texfootrow' + 1 + replace `pad0' = "\end{tabular}" in `row' + + outfile `vlist' `using' in 1/`newtotrows', `replace' runtogether + + * delete new rows created for TeX table, if any + if `oldN' { + keep in 1/`totrows' + } + } /* quietly */ +end /* end _texout */ + + +******************************************************************************************** + + +* ripped from outreg2 on Mar2009 +program define _wordout, sortpreserve rclass +version 7.0 +* based on version 0.9 4oct01 by john_gallup@alum.swarthmore.edu + if "`1'" == "using" { + syntax using/ [, wordFile(string) Landscape Fragment noPRetty /* + */ Fontsize(numlist max=1 >0) noBorder Cellborder /* + */ Appendpage PAgesize(string) /* + */ Lmargin(numlist max=1 >=0.5) Rmargin(numlist max=1 >=0.5) /* + */ Tmargin(numlist max=1 >=0.5) Bmargin(numlist max=1 >=0.5) /* + */ replace Fast] + + if "`fast'" == "" {preserve} + loadout using `"`using'"', clear + local numcol = `r(numcol)' + local titleWide = `r(titleWide)' + local headBorder = `r(headBorder)' + local bottomBorder = `r(bottomBorder)' + local totrows = _N + local varname "v1" + unab statvars : v2-v`numcol' + } + else { + syntax varlist using/, titleWide(int) headBorder(int) bottomBorder(int) /* + */ [wordFile(string) TOtrows(int 0) Landscape Fragment noPRetty /* + */ Fontsize(numlist max=1 >0) noBorder Cellborder /* + */ Appendpage PAgesize(string) /* + */ Lmargin(numlist max=1 >=0.5) Rmargin(numlist max=1 >=0.5) /* + */ Tmargin(numlist max=1 >=0.5) Bmargin(numlist max=1 >=0.5) /* + */ replace] + if `totrows'==0 { + local totrows = _N + } + local numcols : word count `varlist' + gettoken varname statvars : varlist + local fast 1 + } + + local colhead1 = `titleWide' + 1 + local strow1 = `headBorder' + 1 + + + *** replace if equation column present + local hack 0 + count if v1=="EQUATION" + if `r(N)'~=0 { + * use v2 instead + replace v1 = v2 in `=`bottomBorder'+1'/`totrows' + replace v2 = "" in `=`bottomBorder'+1'/`totrows' + + * change the string length + gen str5 myvar ="" + replace myvar =v2 + drop v2 + ren myvar v2 + order v1 v2 + + local hack 1 + } + + /* if file extension specified in `"`using'"', replace it with ".rtf" for output + local next_dot = index(`"`using'"', ".") + if `next_dot' { + local using = substr(`"`using'"',1,`=`next_dot'-1') + } + */ + + if `"`wordFile'"'=="" { + local endName "rtf" + } + else { + local endName "`wordFile'" + } + + local using `"using "`using'.`endName'""' + return local documentname `"`using'"' + + if "`fontsize'" == "" { + local fontsize "12" + } + + local lscp = ("`landscape'" != "") + local pretty = ("`pretty'" == "") + local cborder = ("`cellborder'" != "") + local noborder = ("`border'" != "") + local stdborder = (!`noborder' & !`cborder') + local nopagen = ("`pagenum'" != "") + local nofrag = ("`fragment'" == "") + + + if `cborder' & !`noborder' { + di in red "may not specify both cellborder and noborder options" + exit 198 + } + + * reformat "R-squared" and italicize "t" or "z" + if `pretty' { + quietly { + replace `varname'= subinword(`varname',"R-squared", "{\i R{\super 2}}", 1) in `strow1'/`bottomBorder' + replace `varname'= subinstr(`varname'," t stat", " {\i t} stat", 1) in `bottomBorder'/`totrows' + replace `varname'= subinstr(`varname'," z stat", " {\i z} stat", 1) in `bottomBorder'/`totrows' + } + } + + * font sizes in points*2 + local font2 = int(`fontsize'*2) + if `pretty' { + /* make title fonts large; notes & t stats small */ + local fslarge = "\fs" + string(int(`font2' * 1.2)) + local fsmed = "\fs" + string(`font2') + local fssmall = "\fs" + string(int(`font2' * 0.8)) + local sa0 "\sa0" /* put space after t stats rows */ + local gapsize = int(`fontsize'*0.4*20) /* 40% of point size converted to twips */ + local sa_gap "\sa`gapsize'" + } + else { + local fs0 = "\fs" + string(`font2') + } + + local onecolhead = (`headBorder' - `titleWide' == 1) + /* onecolhead = true if only one row of column headings */ + if `stdborder' { + if !`onecolhead' { + * runs here + *local trbrdrt "\clbrdrt\brdrs" /* table top is overlined */ + *local trbrdrt "\trbrdrt\brdrs" /* table top is overlined */ + + local clbrdr_uo "\clbrdrt\brdrs" /* cells are overlined */ + local clbrdr_ul "\clbrdrb\brdrs" /* cells are underlined */ + } + else { + /* cells are over- and underlined */ + local clbrdr_ul "\clbrdrt\brdrs\clbrdrb\brdrs" + + } + local trbrdrb "\trbrdrb\brdrs" + } + if `cborder' { + /* if !cborder then clbrdr is blank */ + local clbrdr "\clbrdrt\brdrs\clbrdrb\brdrs\clbrdrl\brdrs\clbrdrr\brdrs" + } + + * figure out max str widths to make cell boundaries + * cell width in twips = (max str width) * (pt size) * 12 + * (12 found by trial and error) + local twipconst = int(`fontsize' * 12 ) + tempvar newvarname + qui gen str80 `newvarname' = `varname' in `strow1'/`bottomBorder' + + local newvarlist "`newvarname' `statvars'" + qui compress `newvarlist' + local cellpos = 0 + foreach avar of local newvarlist { + local strwidth : type `avar' + local strwidth = subinstr("`strwidth'", "str", "", .) + local strwidth = `strwidth' + 1 /* add buffer */ + local cellpos = `cellpos' + `strwidth'*`twipconst' + + * hacking + if `hack'==1 & "`avar'"=="`newvarname'" & `cellpos'<1350 { + local cellpos=1350 + } + local clwidths "`clwidths'`clbrdr'\cellx`cellpos'" + + * put in underline at bottom of header in clwidth_ul + local clwidth_ul "`clwidth_ul'`clbrdr_ul'\cellx`cellpos'" + + * put in overline + local clwidth_ol "`clwidth_ol'`clbrdr_uo'\cellx`cellpos'" + } + + if `stdborder' { + if `onecolhead' { + local clwidth1 "`clwidth_ul'" + } + else { + local clwidth1 "`clwidths'" + local clwidth2 "`clwidth_ul'" + } + local clwidth3 "`clwidths'" + } + else{ + local clwidth1 "`clwidths'" + } + + * statistics row formatting + tempvar prettyfmt + qui gen str12 `prettyfmt' = "" /* empty unless `pretty' */ + if `pretty' { + * make stats 2-N small font + tempvar st2_row last_st + quietly { + gen byte `st2_row' = 0 + replace `st2_row' = (trim(`varname') == "") in `strow1' / `bottomBorder' /* only stats 2+ */ + gen byte `last_st' = (`st2_row' & `varname'[_n+1] != "") /* last stats row */ + replace `prettyfmt' = "`sa0'" in `strow1' / `bottomBorder' + replace `prettyfmt' = "`sa_gap'" if `last_st' in `strow1' / `bottomBorder' + replace `prettyfmt' = `prettyfmt' + "`fsmed'" if !`st2_row' in `strow1' / `bottomBorder' + replace `prettyfmt' = `prettyfmt' + "`fssmall'" if `st2_row' in `strow1' / `bottomBorder' + } + } + + * create macros with file write contents + + forvalues row = `colhead1'/`bottomBorder' { + local svarfmt`row' `"(`prettyfmt'[`row']) "\ql " (`varname'[`row']) "\cell""' + foreach avar of local statvars { + local svarfmt`row' `"`svarfmt`row''"\qc " (`avar'[`row']) "\cell""' + } + local svarfmt`row' `"`svarfmt`row''"\row" _n"' + } + + * write file + tempname rtfile + file open `rtfile' `using', write `replace' + file write `rtfile' "{\rtf1`fs0'" _n /* change if not roman: \deff0{\fonttbl{\f0\froman}} */ + + * title + if `titleWide' { + file write `rtfile' "\pard\qc`fslarge'" _n + forvalues row = 1/`titleWide' { + file write `rtfile' (`varname'[`row']) "\par" _n + } + } + + * The top line + file write `rtfile' "\trowd\trgaph75\trleft-75\intbl\trqc`fsmed'`trbrdrt'`clwidth_ol'" _n + *file write `rtfile' "\trowd\trgaph75\trleft-75\intbl\trqc`fsmed'`trbrdrt'`clwidth1'" _n + + local headBorder_1 = `headBorder' - 1 + * write header rows 1 to N-1 + + forvalues row = `colhead1'/`headBorder_1' { + file write `rtfile' `svarfmt`row'' + * turn off the overlining the first time it's run + file write `rtfile' "\trowd\trgaph75\trleft-75\trqc`clwidth3'" _n + } + file write `rtfile' "\trowd\trgaph75\trleft-75\trqc`clwidth2'" _n + + * write last header row + file write `rtfile' `svarfmt`headBorder'' + + local bottomBorder_1 = `bottomBorder' - 1 + /* turn off cell underlining */ + file write `rtfile' "\trowd\trgaph75\trleft-75\trqc`clwidth3'" _n + + * table contents + forvalues row = `strow1'/`bottomBorder_1' { + file write `rtfile' `svarfmt`row'' + } + + if `stdborder' { + /* write last row */ + *file write `rtfile' "\trowd\trgaph75\trleft-75\trqc`trbrdrb'`clwidths'" _n + * make it underline + file write `rtfile' "\trowd\trgaph75\trleft-75\trqc`trbrdrb'`clwidth_ul'" _n + file write `rtfile' `svarfmt`bottomBorder'' + } + + /* write notes rows */ + if `bottomBorder' < `totrows' { + local noterow1 = `bottomBorder' + 1 + file write `rtfile' "\pard\qc`fssmall'" _n + forvalues row = `noterow1'/`totrows' { + file write `rtfile' (`varname'[`row']) "\par" _n + } + } + + * write closing curly bracket + file write `rtfile' "}" +end /* end _wordout */ + + +******************************************************************************************** + + +* ripped from outreg2 on Mar2009 +program define _xmlout +version 7.0 + + versionSet + version `version' + +* emulates the output produced by xmlsave: +* xmlsave myfile, replace doctype(excel) legible + +syntax using/ [, excelFile(string) LEGible noNAMes titleWide(integer 0) /* + */ headBorder(integer 10) bottomBorder(integer 10) ] + +* assumes all columns are string; if numbers, then the format needs to be checked + +*local legible legible + +if "`legible'"=="legible" { + local _n "_n" +} + +tempname source saving + +if `"`excelFile'"'=="" { + local endName "xml" +} +else { + local endName "`excelFile'" +} + +local save `"`using'.`endName'"' + +*file open `source' using `"`using'"', read +file open `saving' using `"`save'"', write text replace + +*file write `saving' `"`macval(line)'"' +file write `saving' `"<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>"' `_n' +file write `saving' `"<?mso-application progid="Excel.Sheet"?>"' `_n' +file write `saving' `"<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet""' `_n' +file write `saving' `" xmlns:o="urn:schemas-microsoft-com:office:office""' `_n' +file write `saving' `" xmlns:x="urn:schemas-microsoft-com:office:excel""' `_n' +file write `saving' `" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet""' `_n' +file write `saving' `" xmlns:html="http://www.w3.org/TR/REC-html40">"' `_n' +file write `saving' `"<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">"' `_n' +file write `saving' `"<Author></Author>"' `_n' +file write `saving' `"<LastAuthor></LastAuthor>"' `_n' +file write `saving' `"<Created></Created>"' `_n' +file write `saving' `"<LastSaved></LastSaved>"' `_n' +file write `saving' `"<Company></Company>"' `_n' +file write `saving' `"<Version></Version>"' `_n' +file write `saving' `"</DocumentProperties>"' `_n' +file write `saving' `"<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">"' `_n' +file write `saving' `"<ProtectStructure>False</ProtectStructure>"' `_n' +file write `saving' `"<ProtectWindows>False</ProtectWindows>"' `_n' +file write `saving' `"</ExcelWorkbook>"' `_n' +file write `saving' `"<Styles>"' `_n' + +* styles +file write `saving' `"<Style ss:ID="Default" ss:Name="Normal">"' `_n' +file write `saving' `"<Alignment ss:Vertical="Bottom"/>"' `_n' +file write `saving' `"<Borders/>"' `_n' +file write `saving' `"<Font/>"' `_n' +file write `saving' `"<Interior/>"' `_n' +file write `saving' `"<NumberFormat/>"' `_n' +file write `saving' `"<Protection/>"' `_n' +file write `saving' `"</Style>"' `_n' + +* bold & (center) +file write `saving' `"<Style ss:ID="s1">"' `_n' +*file write `saving' `"<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>"' `_n' +file write `saving' `"<Font ss:Bold="1" ss:Size='12'/>"' `_n' +file write `saving' `"<NumberFormat/>"' `_n' +file write `saving' `"</Style>"' `_n' + +* top border & center +file write `saving' `"<Style ss:ID="s21">"' `_n' +file write `saving' `"<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>"' `_n' +file write `saving' `"<NumberFormat/>"' `_n' +file write `saving' `"<Borders>"' `_n' +file write `saving' `"<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>"' `_n' +file write `saving' `"</Borders>"' `_n' +file write `saving' `"</Style>"' `_n' + +* main body (no border) & center +file write `saving' `"<Style ss:ID="s22">"' `_n' +file write `saving' `"<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>"' `_n' +file write `saving' `"<NumberFormat/>"' `_n' +file write `saving' `"</Style>"' `_n' + +* bottom border & center +file write `saving' `"<Style ss:ID="s23">"' `_n' +file write `saving' `"<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>"' `_n' +file write `saving' `"<NumberFormat/>"' `_n' +file write `saving' `"<Borders>"' `_n' +file write `saving' `"<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>"' `_n' +file write `saving' `"</Borders>"' `_n' +file write `saving' `"</Style>"' `_n' + +* goldfish (no border, left-justified) +file write `saving' `"<Style ss:ID="s24">"' `_n' +file write `saving' `"<NumberFormat/>"' `_n' +file write `saving' `"</Style>"' `_n' + +* top border +file write `saving' `"<Style ss:ID="s31">"' `_n' +file write `saving' `"<Borders>"' `_n' +file write `saving' `"<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>"' `_n' +file write `saving' `"</Borders>"' `_n' +file write `saving' `"</Style>"' `_n' + +* main body (no border) +file write `saving' `"<Style ss:ID="s32">"' `_n' +file write `saving' `"<Borders/>"' `_n' +file write `saving' `"</Style>"' `_n' + +* bottom border & center +file write `saving' `"<Style ss:ID="s33">"' `_n' +file write `saving' `"<Borders>"' `_n' +file write `saving' `"<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>"' `_n' +file write `saving' `"</Borders>"' `_n' +file write `saving' `"</Style>"' `_n' + +file write `saving' `"</Styles>"' `_n' +file write `saving' `"<Names>"' `_n' +file write `saving' `"</Names>"' `_n' +file write `saving' `"<Worksheet ss:Name="Sheet1">"' `_n' + +* set up file size +qui describe, short + +local N=_N +local tableN `N' + +if "`names'"~="nonames" { + * add one if variable names are to be inserted + local tableN=`N'+1 +} +else { + * add one for the look + local tableN=`N'+1 +} + +file write `saving' `"<Table ss:ExpandedColumnCount="`r(k)'" ss:ExpandedRowCount="`tableN'""' `_n' +file write `saving' `" x:FullColumns="1" x:FullRows="1">"' `_n' + +* should be tostring and format here if dealing with numbers + + ds8 + + * write the variable names at the top or empty row + if "`names'"~="nonames" { + file write `saving' `"<Row>"' `_n' + foreach var in `dsVarlist' { + if "`Version7'"~="" { + file write `saving' `"<Cell ss:StyleID="s1"><Data ss:Type="String">`macval(var)'</Data></Cell>"' _n + } + else { + file write `saving' `"<Cell ss:StyleID="s1"><Data ss:Type="String">`var'</Data></Cell>"' _n + } + } + file write `saving' `"</Row>"' `_n' + } + else { + file write `saving' `"<Row>"' `_n' + file write `saving' `"</Row>"' `_n' + } + +* title +local count `titleWide' +local total 1 +while `count'~=0 { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`total') n(`N') style(`" ss:StyleID="s1""') style1(`" ss:StyleID="s1""') + local count=`count'-1 + local total=`total'+1 +} + +* top border +local count=`total' +forval num=`count'/`count' { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`num') n(`N') style(`" ss:StyleID="s21""') style1(`" ss:StyleID="s31""') + local total=`total'+1 +} + +* ctitle +local count=`total' +forval num=`count'/`headBorder' { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`num') n(`N') style(`" ss:StyleID="s22""') style1(`" ss:StyleID="s32""') + local total=`total'+1 +} + +* top border (closes ctitle) +local count=`total' +forval num=`count'/`count' { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`num') n(`N') style(`" ss:StyleID="s21""') style1(`" ss:StyleID="s31""') + local total=`total'+1 +} + +* body +local count=`total' +forval num=`count'/`=`bottomBorder'-1' { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`num') n(`N') style(`" ss:StyleID="s22""') style1(`" ss:StyleID="s32""') + local total=`total'+1 +} + +* bottom border (closes body) +local count=`total' +forval num=`count'/`count' { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`num') n(`N') style(`" ss:StyleID="s23""') style1(`" ss:StyleID="s33""') + local total=`total'+1 +} + +* goldfish +if `N'>`total' { + local count=`total' + forval num=`count'/`N' { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`num') n(`N') style(`" ss:StyleID="s24""') style1(`" ss:StyleID="s24""') + local total=`total'+1 + } +} + +/* +forval num=1/`N' { + + file write `saving' `"<Row>"' `_n' + + *foreach var in `=r(varlist)' { + foreach var in `dsVarlist' { + + *local stuff `=`var'[`num']' + local stuff=`var' in `num' + + local stuff : subinstr local stuff "<" "<", all + local stuff : subinstr local stuff ">" ">", all + + * the main body + if "`Version7'"~="" { + file write `saving' `"<Cell`style'><Data ss:Type="String">`macval(stuff)'</Data></Cell>"' `_n' + } + else { + file write `saving' `"<Cell`style'><Data ss:Type="String">`stuff'</Data></Cell>"' `_n' + } + } + file write `saving' `"</Row>"' `_n' +} +*/ + +file write `saving' `"</Table>"' `_n' +file write `saving' `"<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">"' `_n' +file write `saving' `"<ProtectedObjects>False</ProtectedObjects>"' `_n' +file write `saving' `"<ProtectedScenarios>False</ProtectedScenarios>"' `_n' +file write `saving' `"</WorksheetOptions>"' `_n' +file write `saving' `"</Worksheet>"' `_n' +file write `saving' `"</Workbook>"' `_n' + +* close out with the last line +*file write `saving' _n +*file close `source' + +file close `saving' + +end /* _xmlout */ + + +******************************************************************************************** + +* ripped from outreg2 on Mar2009 +program define xmlstack + +syntax, saving(string) dsVarlist(string) num(numlist) n(numlist) style(string) style1(string) + +local N `n' + +*forval num=1/`N' { + + file write `saving' `"<Row>"' `_n' + + local count 0 + + *foreach var in `=r(varlist)' { + foreach var in `dsVarlist' { + + if `count'==0 { + local STYLE `"`style1'"' + } + else { + local STYLE `"`style'"' + } + + *local stuff `=`var'[`num']' + local stuff=`var' in `num' + + local stuff : subinstr local stuff "<" "<", all + local stuff : subinstr local stuff ">" ">", all + + * the main body + if "`Version7'"~="" { + file write `saving' `"<Cell`STYLE'><Data ss:Type="String">`macval(stuff)'</Data></Cell>"' `_n' + } + else { + file write `saving' `"<Cell`STYLE'><Data ss:Type="String">`stuff'</Data></Cell>"' `_n' + } + + local count=`count'+1 + } + file write `saving' `"</Row>"' `_n' +*} + +end /* xmlstack */ + + +******************************************************************************************** + + +*** ripped from outreg2 Mar 2009 +program define ds8 + * get you the list of variable like -ds- does for version 8 + version 7.0 + qui ds + if "`r(varlist)'"=="" { + local dsVarlist "" + foreach var of varlist _all { + local dsVarlist "`dsVarlist' `var'" + } + c_local dsVarlist `dsVarlist' + } + else { + c_local dsVarlist `r(varlist)' + } +end + + +******************************************************************************************** + + +program define stringMaker + * makes a string out variables + tempvar temp + foreach var of varlist _all { + cap confirm string var `var' + if _rc { + * not a string + gen str2 `temp'="" + replace `temp' = string(`var') + move `var' `temp' + drop `var' + ren `temp' `var' + } + } +end + + +******************************************************************************************** + + +* cdout 1.0.1 Apr2009 by roywada@hotmail.com +* opens the current directory for your viewing pleasure + +* the following disabled 14oct2009: cap winexec cmd /c start . +* displays "current directory" instead of cdout or the folder location +* displays dir" instead of cdout or the folder location + +program define _cdout +cap version 7.0 + +*cap winexec cmd /c start . +*cap !start cmd /c start . + +if _rc~=0 { + * version 6 or earlier + di `"{stata `"cdout"':dir}"' +} +else { + * invisible to Stata 7 + local Version7 + local Version7 `c(stata_version)' + + if "`Version7'"=="" { + * it is version 7 or earlier + di `"{stata `"cdout"':dir}"' + } + else if `Version7'>=8.0 { + version 8.0 + di `"{browse `"`c(pwd)'"':dir}"' + } +} + +end + + +******************************************************************************************** + + +* chewfile version 1.0.1 17Aug2009 by roywada@hotmail.com +* quick and easy way to chew and digest excessive large ASCII file + +program define _chewfile +version 8.0 + +syntax using/, [save(string) begin(numlist max=1) end(string) clear parse(string) replace semiclear] + +if `"`parse'"'=="" { + local parse `"`=char(9)'"' +} + +if "`begin'"=="" { + local begin 1 +} + +if "`end'"=="" { + local end . +} + +if "`clear'"=="" & `"`save'"'=="" { + if "`semiclear'"=="" { + noi di in red "must specify {opt clear} or {opt save( )} + exit 198 + } +} + +if "`semiclear'"=="semiclear" { + qui drop * + qui set obs 0 +} +else if "`clear'"=="clear" { + clear + qui set obs 0 +} + +if `"`save'"'=="" { + tempfile dump + local save `dump' +} + +tempname fh outout +local linenum = 0 +file open `fh' using `"`using'"', read + +qui file open `outout' using `"`save'"', write `replace' + +file read `fh' line + +while r(eof)==0 { + local linenum = `linenum' + 1 + local addedRow 0 + if `linenum'>=`begin' & `linenum'<=`end' { + if `addedRow'==0 { + qui set obs `=`=_N'+1' + } + + *display %4.0f `linenum' _asis `"`macval(line)'"' + file write `outout' `"`macval(line)'"' _n + + if "`clear'"=="clear" | "`semiclear'"=="semiclear" { + tokenize `"`macval(line)'"', parse(`"`parse'"') + local num 1 + local colnum 1 + while "``num''"~="" { + local needOneMore 0 + if `"``num''"'~=`"`parse'"' { + cap gen str3 var`colnum'="" + cap replace var`colnum'="``num''" in `linenum' + if _rc~=0 { + qui set obs `=`=_N'+1' + cap replace var`colnum'="``num''" in `linenum' + local addedRow 1 + } + *local colnum=`colnum'+1 + } + else { + cap gen str3 var`colnum'="" + local colnum=`colnum'+1 + } + local num=`num'+1 + } + } + } + file read `fh' line +} + +file close `fh' +file close `outout' +end + + +******************************************************************************************** + + +* 03nov2009, ripped from outreg2 on 05nov2009 +prog define versionSet + * sends back the version as c_local + version 7.0 + + * invisible to Stata 7 + cap local Version7 `c(stata_version)' + c_local Version7 `Version7' + + if "`Version7'"=="" { + * it is version 7 + c_local version 7 + } + else if `Version7'>=8.2 { + version 8.2 + c_local version 8.2 + } + + if "`Version7'"=="" { + c_local bind "" + } + else { + c_local bind "bind" + } + +end + +exit + + + +* version 1.0.1 May2009 logout by roywada@hotmail.com +cap no longer takes off the bottom line +noauto auto( ) dec( ) hooked up +_logfix split into _infix, unfinished +logleft done, not implemented +caplog has correct version control, enabling eret list +value labels handled as proposed by Karl Keesman at sales@survey-design.com.au +fix handles the horizontal lines + +*ssc de version 1.0.2 05May2009 logout by roywada@hotmail.com +the bottomline no longer taken off by unwrap function +the horizontal lines starting in the middle handled during delimited routine + +* version 1.0.3 14oct2009 +fixed the compound quotes for `save' +unwraps correctly (previously left an extra space) +fixcut( ) option +_cdout inserted +_chewfile inserted +range( ) option + +* 1.0.4 +di before _cdout +nopretty for _texout fixed?? +versionSet +error with fixcut( ) rectified +_infix drop vertical lines before horizontal line + + +needs work: +logout, save(mytable) excel replace: eret list +plus the ":" wipe or not +user specified infix + + +dataout circa Apr 2009 needs to be replaced with version 1.0.4 07sep2009 + + diff --git a/Modules/ado/plus/l/logout.hlp b/Modules/ado/plus/l/logout.hlp new file mode 100644 index 0000000..4ea6192 --- /dev/null +++ b/Modules/ado/plus/l/logout.hlp @@ -0,0 +1,193 @@ +{smcl} +{* 05ov2009}{...} +{cmd:help logout} + +{hline} + +{title:Title} + +{p2colset 5 15 22 2}{...} +{p2col :{hi: logout} {hline 2}}Converts log or ASCII files into various output formats{p_end} + +{marker s_Syntax} +{title:Syntax} + +{p 4 10 6} +{cmdab:logout}, [{it:options} : {it:command}] + +{marker s_Description} +{title:Description} + +{p 4 4 6} +{cmd:logout} provides a fast and easy way to convert log or ASCII files into various output +formats compatible with Word, Excel, LaTex, or Stata datafile. Can be used as a prefix or by itself +after a log file has been created. + +{p 4 4 6} +More specifically, {cmd:logout} will import plain-text files into tab-delimited format, +which is then converted into the output format of choice. The default method is tab/space-delimited, +along with a list of usual suspects. Alternatively, infix method can be used when the column position is meaningful. + +{p 4 4 6} +Can also be used to chew through dirty files such as html, etc. Will also chew through any ASCII log files, +including those produced SAS, SPSS, etc. In Stata, you can use {cmd:{help caplog}} to create log files on +the fly. + +{p 4 4 6} +{cmd:table} and {cmd:tabstat} are automatically handled by {opt fix} method. + + +{marker s_Options} +{title:Command} + +{p 4 12 6}Any command accepted, i.e. { help estimation commands}, tabulation, summary, descrition, etc. + +{marker s_Options} +{title:Options} + +{dlgtab:Main} + +{p 4 12 6}{opt clear} Replace the current data in memory, then manipulate the file as a Stata data. {p_end} + +{p 4 12 6}{opt save( )} The name of output file. logout.txt is assigned if {opt clear} or temporary file is not used. {p_end} + +{p 4 12 6}{opt use( )} The name of input file to be converted. {p_end} + +{p 4 12 6}{opt raw} Raw file is diplayed in the first column (up to 244 character limit). {p_end} + + +{p 4 12 6}{opt fix} Use automatic fixed method (i.e. infix) to read the file. {p_end} + +{p 4 12 6}{opt fix(#)} Adjust the sensitivity of {opt fix} method. Default is 5. Try 1 for narrower +parsings.{p_end} + +{p 4 12 6}{opt fixcut(# # ...)} Use manual fixed method (i.e. infix) to read the file. Something like fixcut(3 5 10 15). Drop a number +if you want to merge columns there. A suggestion is displayed whenever fixed method is run{p_end} + + +{p 4 12 6}{opt auto( )} The number of automatically formatted decimals to be reported. Default is 3. {p_end} + +{p 4 12 6}{opt noauto} Turns off the automatic formatting of decimals.{p_end} + +{p 4 12 6}{opt dec( )} Fixed number of decimals. Turns off automatic formating.{p_end} + +{p 4 12 6}{opt word} Convert into Word compatible file. {p_end} + +{p 4 12 6}{opt excel} Convert into Excel compatible file. {p_end} + +{p 4 12 6}{opt tex} Convert into Latex or tex compatible file. {p_end} + +{p 4 12 6}{opt dta} Convert into .dta file for Stata. {p_end} + + +{p 4 12 6}{opt nowipe} Do not apply minimal cleaning, which are: {p_end} + +{p 8 12 6} .drop if t1=="-----" | t1=="opened" | t1=="log" | t1=="." | t1=="closed" {p_end} + + +{marker s_0} +{title:Examples} + +{p 4 10 6}{cmd:* summary}{p_end} +{p 4 10 6}{stata sysuse auto, clear}{p_end} +{p 4 10 6}{stata `"logout, save(myfile) excel replace: sum"'}{p_end} + + +{p 4 10 6}{cmd:* summary, MANUALLY clean it}{p_end} +{p 4 10 6}{stata sysuse auto, clear}{p_end} +{p 4 10 6}{stata `"logout, clear: sum"'}{p_end} +{p 4 10 6}{stata drop t2 t5 t6}{p_end} +{p 4 10 6}{stata logout, save(myfile) excel replace}{p_end} + + +{p 4 10 6}{cmd:* summary, detail}{p_end} +{p 4 10 6}{stata sysuse auto, clear}{p_end} +{p 4 10 6}{stata `"logout, save(mystuff) excel word replace: sum, detail"'}{p_end} + + +{p 4 10 6}{cmd:* one-way tabulation with value labels}{p_end} +{p 4 10 6}{stata sysuse auto, clear}{p_end} +{p 4 10 6}{stata `"logout, clear excel dta tex save(myfile) replace: tab foreign rep78"'}{p_end} + + +{p 4 10 6}{cmd:* one-way tabulation}{p_end} +{p 4 10 6}{stata sysuse auto, clear}{p_end} +{p 4 10 6}{stata `"caplog using mystuff.txt, replace: tabulate price [aweight=turn], summarize(headroom)"'}{p_end} +{p 4 10 6}{stata logout, use(mystuff.txt) save(mytable) clear excel tex dta replace}{p_end} + + +{p 4 10 6}{cmd:* two-way tabulation}{p_end} +{p 4 10 6}{stata sysuse auto, clear}{p_end} +{p 4 10 6}{stata `"logout, clear: tab mpg foreign"'}{p_end} +{p 4 10 6}{stata logout, save(mytable) clear excel tex dta replace}{p_end} + + +{p 4 10 6}{cmd:* table, combined it with -fix- method}{p_end} +{p 4 10 6}{stata sysuse auto, clear}{p_end} +{p 4 10 6}{stata `"logout, save(mystuff) excel fix replace: table trunk rep78, c(n mpg mean mpg sd mpg median mpg) stubwidth(25)"'}{p_end} + + +{p 4 10 6}{cmd:* table, MANUALLY clean it after using -fix- or -fix(1)-}{p_end} +{p 4 10 6}{stata sysuse auto, clear}{p_end} +{p 4 10 6}{stata `"caplog using mystuff.txt, replace: table trunk rep78 , c(n mpg mean mpg sd mpg median mpg)"'}{p_end} +{p 4 10 6}{stata logout, use(mystuff.txt) fix(1) replace clear}{p_end} +{p 4 10 6}{stata drop in 1/2}{p_end} +{p 4 10 6}{stata logout, save(mystuff.txt) excel replace clear}{p_end} + + +{p 4 10 6}{cmd:* regress}{p_end} +{p 4 10 6}{stata sysuse auto, clear}{p_end} +{p 4 10 6}{stata `"logout, save(myfile) excel dec(3) replace: reg price mpg rep78 headroom"'}{p_end} + + +{p 4 10 6}{cmd:* tabstat}{p_end} +{p 4 10 6}{stata sysuse auto, clear}{p_end} +{p 4 10 6}{stata `"logout, save(mytable) excel replace: tabstat price mpg rep78, stats( max p1 mean)"'}{p_end} + + +{p 4 10 6}{cmd:* The following three are more or less equivalent:}{p_end} +{p 4 10 6}{stata webuse dose, clear}{p_end} +{p 4 10 6}{stata `"caplog using mylog.txt, replace: tab dose function, col"'}{p_end} +{p 4 10 6}{stata chewfile using mylog.txt, begin(10) end(.) save(chewed.txt) replace}{p_end} +{p 4 10 6}{stata `"logout, use(chewed.txt) clear fix"'}{p_end} +{p 4 10 6}{stata `"logout, save(C:\mytable) tex excel replace"'}{p_end} + +{p 4 10 6}{stata `"logout, save(C:\mytable) tex excel replace range(10/.) fix: tab dose function, col"'}{p_end} + +{p 4 10 6}{stata `"logout, save(C:\mytable) tex excel replace range(10/.) fixcut(11 16 27 38 45 50 67): tab dose function, col"'}{p_end} + +{p 4 10 6}{cmd:** Merging two columns by skipping a fixcut number:}{p_end} +{p 4 10 6}{stata `"logout, save(C:\mytable) tex excel replace range(10/.) fixcut(11 27 38 45 50 67): tab dose function, col"'}{p_end} + + +{title:Hints} + +{p 4 10 6}The default is space/tab-delimited.{p_end} +{p 4 10 6}For semi-ordered file, try using {opt fix} and values less than 5 for {opt fix( )}.{p_end} + + +{title:Remarks} + +{p 4 10 6}"Detailed" suggestions should be sent to the email address below.{p_end} +{p 4 10 6}{opt fix} erases rows with many dashes as a horizontal line{p_end} +{p 4 10 6}May not handle an exceptionally large log file.{p_end} +{p 4 10 6}Small Stata may have a problem with the column limits.{p_end} +{p 4 10 6}ASCII character "_" is used to handle space delimited value labels.{p_end} +{p 4 10 6}version 7: do not include colon characters (:) in the file path. Use {helpb cd} instead.{p_end} +{p 4 10 6}version 7: range( ) option not available.{p_end} + + +{title:Acknowledgements} + +{p 4 10 6}The codes for {opt word} and {opt tex} are traced back to John Gallup's +{cmd:outreg} through {cmd:outreg2}.{p_end} +{p 4 10 6}{opt excel} is implemented as a facsimile of {cmd:xmlsave}.{p_end} +{p 4 10 6}Value labels are handled as proposed by Karl Keesman at sales@survey-design.com.au{p_end} + + +{title:Author} + +{p 4 10 6}Roy Wada{p_end} +{p 4 10 6}roywada@hotmail.com{p_end} + + diff --git a/Modules/ado/plus/m/maplist.ado b/Modules/ado/plus/m/maplist.ado new file mode 100644 index 0000000..e3cdc02 --- /dev/null +++ b/Modules/ado/plus/m/maplist.ado @@ -0,0 +1,39 @@ +program def maplist, rclass +*! NJC 1.0.0 22 August 2000 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax , Map(str asis) [ Global(str) Noisily Symbol(str) ] + + if "`symbol'" == "" { local symbol "@" } + + if !index(`"`map'"',"`symbol'") { + di in r "map( ) does not contain `symbol'" + exit 198 + } + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tokenize `list' + while "`1'" != "" { + local result : subinstr local map "`symbol'" "`1'", all + capture local 1 = `result' + if _rc { + di in r "inappropriate map?" + exit _rc + } + local newlist "`newlist'`1' " + mac shift + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/m/maplist.hlp b/Modules/ado/plus/m/maplist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/m/maplist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/m/meta.dlg b/Modules/ado/plus/m/meta.dlg new file mode 100644 index 0000000..85a3e4c --- /dev/null +++ b/Modules/ado/plus/m/meta.dlg @@ -0,0 +1,321 @@ +/* + +*! meta dialog version 1.0.1, 13 May 2003, T. J. Steichen, steichen@triad.rr.com +*! for meta version 2.06, Mar 1998, Stephen Sharp, stephen.j.sharp@gsk.com +*! Jonathan Sterne, jonathan.sterne@bristol.ac.uk + +Fixed and random-effects meta-analysis, with graphics +----------------------------------------------------- + +Syntax: meta { theta | exp(theta) } { se_theta | var_theta | ll ul [cl] } + [if exp] [in range] [ , id(strvar) var ci graph(f|r|e) eform print + ebayes level(#) fmult(#) boxysca(#) boxshad(#) cline ltrunc(#) rtrunc(#)] + +To install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "Meta-analysis of Effects (&meta)" "db meta" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. +*/ + +VERSION 8.0 + +INCLUDE _std_small +INCLUDE header + +HELP hlp1, view("help meta") +RESET res1, label("Reset") + +DIALOG main, label("meta 2.06 - Meta-analysis of Effects") tabtitle("Main") +BEGIN + GROUPBOX gb_data 10 5 330 _ht5h, /// + label("Type of Data:") + RADIO r_se 15 25 100 ., /// + label("Theta, SE") first /// + onclickon(script main_se_on) /// + onclickoff(script main_se_off) /// + option(NONE) + RADIO r_var 115 25 100 ., /// + label("Theta, Var") middle /// + onclickon(script main_var_on) /// + onclickoff(script main_var_off) /// + option("var") + RADIO r_ci 215 25 110 ., /// + label("exp(Theta), CI") last /// + onclickon(script main_ci_on) /// + onclickoff(script main_ci_off) /// + option("ci") + + TEXT tx_se 15 45 320 ., /// + label("Vars for theta, se(theta), in that order") + VARLIST vl_se @ _ss @ ., /// + label("Vars for theta, se(theta)") + + TEXT tx_var @ 45 320 ., /// + label("Vars for theta, var(theta), in that order") + VARLIST vl_var @ _ss @ ., /// + label("Vars for theta, var(theta)") + + TEXT tx_ci @ 45 320 ., /// + label("Vars for exp(theta), CI_LL, CI_UL, in that order") + VARLIST vl_ci @ _ss @ ., /// + label("Vars for exp(theta), CI_LL, CI_UL") + + CHECKBOX cb_id 10 100 100 ., /// + label("ID Variable:") /// + onclickon(main.vn_id.enable) /// + onclickoff(main.vn_id.disable) + VARNAME vn_id 110 100 230 ., /// + label("ID Variable") /// + option("id") + + CHECKBOX cb_eform 10 130 150 ., /// + label("Use exp(theta)") /// + option("eform") + CHECKBOX cb_print 10 150 150 ., /// + label("Print details") /// + option("print") + CHECKBOX cb_ebayes 10 170 300 ., /// + label("Generate Empirical Bayes variables") /// + option("ebayes") + + CHECKBOX cb_level 220 130 75 ., /// + label("CI Level:") /// + onclickon(main.ed_level.enable) /// + onclickoff(main.ed_level.disable) + EDIT ed_level 300 @ 40 ., /// + label("Level") numonly default(95) /// + option("level") +END + +DIALOG graph, tabtitle("Graph Options") +BEGIN + GROUPBOX gb_graph 10 10 330 _ht2h, /// + label("Graph Estimates:") + RADIO r_none 15 30 65 ., /// + label("None") first /// + onclickon(program graph_off) /// + onclickoff(program graph_on) /// + option(NONE) + RADIO r_fixed 80 30 65 ., /// + label("Fixed") middle /// + option("graph(f)") + RADIO r_random 145 30 75 ., /// + label("Random") middle /// + option("graph(r)") + RADIO r_ebayes 230 30 95 ., /// + label("Emp. Bayes") last /// + option("graph(e)") + + CHECKBOX cb_cline 15 80 150 ., /// + label("Draw Estimate line") /// + option("cline") + + CHECKBOX cb_fmult 200 80 95 ., /// + label("Font scale:") /// + onclickon(graph.ed_fmult.enable) /// + onclickoff(graph.ed_fmult.disable) + EDIT ed_fmult 300 @ 40 ., /// + label("Font scale") numonly default(1) /// + option("fmult") + + CHECKBOX cb_boxy 200 110 95 ., /// + label("Box yscale:") /// + onclickon(graph.ed_boxy.enable) /// + onclickoff(graph.ed_boxy.disable) + EDIT ed_boxy 300 @ 40 ., /// + label("Box yscale") numonly default(1) /// + option("boxysca") + + CHECKBOX cb_boxs 200 130 95 ., /// + label("Box shade:") /// + onclickon(graph.ed_boxs.enable) /// + onclickoff(graph.ed_boxs.disable) + EDIT ed_boxs 300 @ 40 ., /// + label("Box shading") numonly default(0) /// + option("boxshad") + + CHECKBOX cb_ltrunc 15 110 95 ., /// + label("Left truncate:") /// + onclickon(graph.ed_ltrunc.enable) /// + onclickoff(graph.ed_ltrunc.disable) + EDIT ed_ltrunc 125 @ 40 ., /// + label("Left truncate") numonly /// + option("ltrunc") + + CHECKBOX cb_rtrunc 15 130 105 ., /// + label("Right truncate:") /// + onclickon(graph.ed_rtrunc.enable) /// + onclickoff(graph.ed_rtrunc.disable) + EDIT ed_rtrunc 125 @ 40 ., /// + label("Right truncate") numonly /// + option("rtrunc") + + GROUPBOX gb_gopts7 10 155 330 _ht1h, /// + label("Allowed Graph7 Options:") + EDIT ed_gopts7 15 175 320 ., /// + label("Graph7 Options") +END + +INCLUDE ifin + +SCRIPT main_se_on +BEGIN + main.tx_se.show + main.vl_se.show + main.tx_se.enable + main.vl_se.enable + + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide + + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +SCRIPT main_se_off +BEGIN + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide +END + +SCRIPT main_var_on +BEGIN + main.tx_var.show + main.vl_var.show + main.tx_var.enable + main.vl_var.enable + + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide + + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +SCRIPT main_var_off +BEGIN + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide +END + +SCRIPT main_ci_on +BEGIN + main.tx_ci.show + main.vl_ci.show + main.tx_ci.enable + main.vl_ci.enable + + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide + + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide +END + +SCRIPT main_ci_off +BEGIN + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +PROGRAM graph_on +BEGIN + call graph.cb_cline.enable + call graph.cb_fmult.enable + call graph.cb_boxy.enable + call graph.cb_boxs.enable + call graph.cb_ltrunc.enable + call graph.cb_rtrunc.enable + call graph.gb_gopts7.enable + call graph.ed_gopts7.enable + if graph.cb_fmult { + call graph.ed_fmult.enable + } + if graph.cb_boxy { + call graph.ed_boxy.enable + } + if graph.cb_boxs { + call graph.ed_boxs.enable + } + if graph.cb_ltrunc { + call graph.ed_ltrunc.enable + } + if graph.cb_rtrunc { + call graph.ed_rtrunc.enable + } +END + +PROGRAM graph_off +BEGIN + call graph.cb_cline.disable + call graph.cb_fmult.disable + call graph.cb_boxy.disable + call graph.cb_boxs.disable + call graph.cb_ltrunc.disable + call graph.cb_rtrunc.disable + call graph.gb_gopts7.disable + call graph.ed_gopts7.disable + if graph.cb_fmult { + call graph.ed_fmult.disable + } + if graph.cb_boxy { + call graph.ed_boxy.disable + } + if graph.cb_boxs { + call graph.ed_boxs.disable + } + if graph.cb_ltrunc { + call graph.ed_ltrunc.disable + } + if graph.cb_rtrunc { + call graph.ed_rtrunc.disable + } +END + +PROGRAM command +BEGIN + put "meta " + if main.r_se { + varlist main.vl_se + } + if main.r_var { + varlist main.vl_var + } + if main.r_ci { + varlist main.vl_ci + } + INCLUDE _ifin_pr + beginoptions + option radio(main r_se r_var r_ci) + optionarg main.vn_id + option radio(graph r_none r_fixed r_random r_ebayes) + option main.cb_eform + option main.cb_print + option main.cb_ebayes + option graph.cb_cline + optionarg graph.ed_fmult + optionarg graph.ed_boxy + optionarg graph.ed_boxs + optionarg graph.ed_ltrunc + optionarg graph.ed_rtrunc + put graph.ed_gopts7 + endoptions +END diff --git a/Modules/ado/plus/m/meta_dialog.hlp b/Modules/ado/plus/m/meta_dialog.hlp new file mode 100644 index 0000000..afefa11 --- /dev/null +++ b/Modules/ado/plus/m/meta_dialog.hlp @@ -0,0 +1,118 @@ +{smcl} +{* 12apr2004}{...} +{hline} +help for {cmd:meta_dialog}{right:(SJ4-2: pr0012)} +{hline} + + +{title:Submenu and dialogs for meta-analysis commands} {result:(Stata 8 only)} + + +{title:Description} + +{p 4 4 2} +The {cmd:meta_dialog} package provides Stata 8 dialog boxes ({cmd:.dlg} files) +and the commands needed to create a {hi:Meta-Analysis} submenu that contains +the publicly available meta-analysis commands. The 14 commands included +in this package that may be placed on the menu are {cmd:meta}, {cmd:metan}, +{cmd:metap}, {cmd:metareg}, {cmd:metacum}, {cmd:funnel}, {cmd:metafunnel}, +{cmd:labbe}, {cmd:metannt}, {cmd:metaninf}, {cmd:metainf}, {cmd:galbr}, +{cmd:metabias}, and {cmd:metatrim}. + +{p 4 4 2} +The menu commands (shown below) are placed in your personal Stata +{cmd:profile.do} file. They create the submenu on the +StataCorp-defined {hi:User} menu. + +{p 4 4 2} +You can determine if you have defined a {cmd:profile.do} file by starting +Stata and observing whether a line of the form + +{p 8}{result:running C:\data\stata\profile.do} ... + +{p 4 4 2} +appears on the screen as part of the initiation sequence. If it does, +add the commands below to that file and resave the file. If the +line does not appear, you have not defined a profile. Create a +plain text file containing the commands below, name it {cmd:profile.do}, and +save it somewhere in the Stata path. + +{p 4 4 2} +You may choose not to create the menu and run the dialogs directly +from the Stata 8 command line via the {cmd:db {it:name}} command. If so, + +{col 5}{hline 69} +{col 5}command...{col 19}runs...{col 36}description... +{col 5}{hline 69} +{col 5}{dialog meta:db meta}{col 19}{help meta:meta 2.06}{col 36}Meta-analysis of Effects +{col 5}{dialog metan:db metan}{col 19}{help metan:metan 1.74}{col 36}Meta-analysis of Binary and Continuous +{col 5}{dialog metap:db metap}{col 19}{help metap:metap 2.0.0}{col 36}Meta-analysis of p-values +{col 5}{dialog metareg:db metareg}{col 19}{help metareg:metareg 1.06}{col 36}Meta-analysis Regression +{col 5}{dialog metacum:db metacum}{col 19}{help metacum:metacum 1.02}{col 36}Cumulative Meta-analysis +{col 5}{dialog funnel:db funnel}{col 19}{help funnel:funnel 1.04}{col 36}Metan-based Funnel Graph +{col 5}{dialog metafunnel:db metafunnel}{col 19}{help metafunnel:metafunnel 1.02}{col 36}Funnel Graph (vertical) +{col 5}{dialog labbe:db labbe}{col 19}{help labbe:labbe 1.21}{col 36}Metan-based L'abbe Graph +{col 5}{dialog metannt:db metannt}{col 19}{help metannt:metannt 1.0}{col 36}Metan-based NNT +{col 5}{dialog metaninf:db metaninf}{col 19}{help metaninf:metaninf 1.0.1}{col 36}Metan-based Influence Analysis +{col 5}{dialog metainf:db metainf}{col 19}{help metainf:metainf 3.0.0}{col 36}Meta-based Influence Analysis +{col 5}{dialog galbr:db galbr}{col 19}{help galbr:galbr 2.0}{col 36}Galbraith Plot for Heterogeneity +{col 5}{dialog metabias:db metabias}{col 19}{help metabias:metabias 1.2.2}{col 36}Publication Bias in Meta-analysis +{col 5}{dialog metatrim:db metatrim}{col 19}{help metatrim:metatrim 1.0.5}{col 36}Trim and Fill Analysis +{col 5}{hline 69} + + +{title:Menu creation commands} + +{p 4 4 2} +Put the following commands in your {cmd:profile.do} (the lines are long and may wrap on the screen):{input} + +{hline}{asis} + +if _caller() >= 8 { + window menu clear + window menu append submenu "stUser" "&Meta-Analysis" + window menu append item "Meta-Analysis" "Of Binary and Continuous (meta&n)" "db metan" + window menu append item "Meta-Analysis" "Of Effects (&meta)" "db meta" + window menu append item "Meta-Analysis" "Of p-values (meta&p)" "db metap" + window menu append item "Meta-Analysis" "Cumulative (meta&cum)" "db metacum" + window menu append item "Meta-Analysis" "Regression (meta®)" "db metareg" + window menu append item "Meta-Analysis" "Funnel Graph, metan-based (f&unnel)" "db funnel" + window menu append item "Meta-Analysis" "Funnel Graph, &vertical (metafunnel)" "db metafunnel" + window menu append item "Meta-Analysis" "L'abbe Graph, metan-based (&labbe)" "db labbe" + window menu append item "Meta-Analysis" "NNT, metan-based (metann&t)" "db metannt" + window menu append item "Meta-Analysis" "Influence Analysis, metan-based (metan&inf)" "db metaninf" + window menu append item "Meta-Analysis" "Influence Analysis, meta-based (metain&f)" "db metainf" + window menu append item "Meta-Analysis" "Galbraith Plot for Heterogeneity (&galbr)" "db galbr" + window menu append item "Meta-Analysis" "Publication Bias (meta&bias)" "db metabias" + window menu append item "Meta-Analysis" "Trim and Fill Analysis (metatrim)" "db met&atrim" + window menu refresh +} + + +{smcl} +{hline} +{sf}{txt} +{title:Notes} + +{p 4 4 2} +Dialogs are available only in Stata 8 or later; thus, the leading +{cmd:if _caller() >= 8 {c -(}} and trailing {cmd:{c )-}} lines above are +needed only if you also run Stata 7. Leaving these lines in will not cause +problems. + +{p 4 4 2} +The easiest way to capture these commands is to open this help file in your +text editor, copy the lines, and then paste them into {cmd:profile.do}. + + +{title:Author} + +{p 4 8 2} +Thomas J. Steichen, steichen@triad.rr.com + + +{title:Also see} + + Manual: {hi:[P] dialogs; [P] window menu; [R] db} + +{p 4 13 2}Online: help for {help dialogs}; {help window}; {help db} diff --git a/Modules/ado/plus/m/metabias.ado b/Modules/ado/plus/m/metabias.ado new file mode 100644 index 0000000..df11113 --- /dev/null +++ b/Modules/ado/plus/m/metabias.ado @@ -0,0 +1,918 @@ +*! metabias version 1.2.2 07feb01 TJS (STB-61: sbe19.4) +program define metabias, rclass +version 6.0 +* version 1.0.0 24oct97 TJS STB-41 sbe19 +* version 1.1.2 21apr98 TJS Unweighted Egger analysis only STB-44 sbe19.1 +* version 1.1.3 1oct99 TJS fixed stratified bug STB-44 sbe19.1 +* version 1.2.0 17feb00 TJS Version 6 and gweight option (STB-57: sbe19.2) +* version 1.2.1 31jan01 TJS touched for version 7.0 +* +*! syntax: metabias varlist [if] [in] +*! [ , Graph(str) GWeight Vari CI BY(varname) LEvel(real 95) * ] + +if ("`*'" == "") { + di "Syntax is:" + di in wh "metabias " in gr "{ theta { se | var } | " _c + di in gr "exp(theta) | ll ul [cl] } [" _c + di in wh "if " in gr "exp] [" in wh "in " in gr "range]" + di in gr " [ " in wh ", by(" in gr "by_var"in wh ")" _c + di in gr " { " in wh "v" in gr "ar | " in wh "ci" in gr " } " _c + di in wh "g" in gr "raph" in wh "(" in gr "{ " in wh "b" _c + di in gr "egg | " in wh "e" in gr "gger }" in wh ")" + di in wh " gw" in gr "eight" in wh " lev" _c + di in gr "el" in wh "(" in gr "#" in wh ") " in gr "graph_options ]" + di _n in gr " where { a | b |...} means choose" _c + di in gr " one and only one of {a, b, ...}" + exit +} + +* Setup +syntax varlist(numeric min=2 max=4) [if] [in] /* + */ [ , Graph(str) Vari CI BY(varname) LEvel(real 95) * ] +* Note: option GWeight is passed via * directly to the graphics subs +marksample touse +tokenize `varlist' + +tempvar byg theta setheta var w sw vt wtheta swtheta +tempvar zz Ts wl swl RRm bylabel +tempname k ks sdks p zu pcc zcc c sks svks sk oe sbv sv +* v7 fix +tempvar bylabl + +local theta `1' +if "`3'" == "" { local setheta `2' } +else { + tempvar ll ul cl + local ll `2' + local ul `3' + local cl `4' +} + +* input error traps +if "`ci'" != "" & "`vari'" != "" { + di _n in re "Error: options 'ci' and 'var' cannot " _c + di in re "be specified together." + exit +} +if "`ci'" == "ci" & "`ul'" != "" { + di _n in bl "Note: option 'ci' specified." +} +if "`ci'" == "ci" & "`ul'" == "" { + di _n in re "Error: option 'ci' specified but varlist " _c + di in re "has only 2 variables." + exit +} +if "`ci'" != "ci" & "`vari'" != "vari" & "`ul'" != "" { + di _n in bl "Warning: varlist has 3 variables but option " _c + di in bl "'ci' not specified; 'ci' assumed." + local ci "ci" + local vari "" +} +if "`vari'" == "vari" & "`ul'" != "" { + di _n in re "Error: option 'var' specified but varlist " _c + di in re "has more than 2 variables." + exit +} +if "`vari'" == "vari" & "`ul'" == "" { + di _n in bl "Note: option 'var' specified." +} +if "`vari'" != "vari" & "`ul'" == "" { + di _n in bl "Note: default data input format (theta, " _c + di in bl "se_theta) assumed." +} + +* Select data to analyze +if "`ul'" == "" { markout `touse' `theta' `setheta' } + else { markout `touse' `theta' `ll' `ul' } + +preserve /* Note: data preserved here */ + +* Generate `by' groups +if "`by'" != "" { + confirm var `by' + sort `by' + qui by `by': gen byte `byg' = _n==1 + qui replace `byg' = sum(`byg') + local byn = `byg'[_N] +} +else { + qui gen byte `byg' = 1 + local byn = 1 +} + +* Generate `by' labels -- if required +if ("`by'" != "") { + capture decode `by', gen(`bylabel') + if _rc != 0 { + local type : type `by' + if substr("`type'",1,3) != "str" { + qui gen str8 `bylabel' = string(`by') + } + else { qui gen `type' `bylabel' = `by' } + } +* v7 fix +encode `bylabel', gen(`bylabl') +} + +* Do calculations +* initial calculations... +if "`vari'" == "vari" { qui replace `setheta' = sqrt(`setheta')} + +if "`ci'" == "ci" { + capture confirm variable `cl' + if _rc~=0 { qui gen `zz' = invnorm(.975) } + else { + qui replace `cl' = `cl' * 100 if `cl' < 1 + qui gen `zz' = -1 * invnorm((1- `cl' / 100) / 2 ) + qui replace `zz' = invnorm(.025) if `zz'==. + } + qui gen `setheta' = ( ln(`ul') - ln(`ll')) / 2 / `zz' + qui replace `theta' = ln(`theta') +} + +if "`if'" != "" { ifexp "`if'" } + +if "`by'" != "" { + scalar `sk' = 0 + scalar `sks' = 0 + scalar `svks' = 0 + scalar `sbv' = 0 + scalar `sv' = 0 +} + +* loop through by-values +local j = 1 +while `j' <= `byn' { /* start of loop for each `by' group */ + + summ `touse' if `touse' & `byg' == `j', meanonly + local data = _result(1) + +* Calculate stats + qui { + gen `var' = `setheta'^2 + gen `w' = 1/`var' + egen `sw' = sum(`w') if `touse' & `byg' == `j' + gen `vt' = `var' - 1 / `sw' + gen `wtheta' = `w' * `theta' + egen `swtheta' = sum(`wtheta') if `touse' & `byg' == `j' + gen `Ts' = (`theta' - `swtheta' / `sw') / sqrt(`vt') + gen `wl' = `w' * `theta' + egen `swl' = sum(`wl') if `touse' & `byg' == `j' + gen `RRm' = `swl' / `sw' + scalar `oe' = `RRm' + } + + qui capture ktau2 `var' `Ts' if `touse' & `byg' == `j' + if _rc == 0 { + scalar `k' = $S_1 + scalar `ks' = $S_4 + scalar `sdks' = $S_5 + scalar `p' = $S_6 + scalar `zu' = $S_7 + scalar `pcc' = $S_8 + scalar `zcc' = $S_9 + scalar `c' = $S_10 + } + else if _rc == 2001 { + scalar `k' = `data' + scalar `ks' = . + scalar `sdks' = . + scalar `p' = . + scalar `zu' = . + scalar `pcc' = . + scalar `zcc' = . + scalar `c' = . + } + else { + di in re "error " _rc " in call to ktau2" + exit + } + + if "`by'" != "" & `k' > 1 { + scalar `sk' = `sk' + `k' + scalar `sks' = `sks' + `ks' + scalar `svks' = `svks' + `sdks'^2 + } + +* Egger's bias test + tempvar prec snd + qui gen `prec'= 1 / `setheta' + qui gen `snd' = `theta' / `setheta' + qui regr `snd' `prec' if `touse' & `byg' == `j' + capture matrix b = get(_b) + if _rc == 0 { + local df = e(N) - 2 + local bias = b[1,2] + capture matrix V = get(VCE) + if _rc == 0 { + local pb = tprob(`df', b[1,2] / sqrt(V[2,2])) +* 1.1.3 fix +* if "`by'" != "" { + if "`by'" != "" & V[2,2] != 0 & `data' > 0 { + scalar `sbv' = `sbv' + `bias' / V[2,2] + scalar `sv' = `sv' + 1 / V[2,2] + } + } + } + else { + local bias = . + local pb = . + } + +* Display results + if "`by'" != "" { +* use this display if a by_var was specified... +* .....display output header + if `j' == 1 { + di " " + di in gr "Tests for Publication Bias" + di " " + local sp = 8 - length("`by'") + #delimit ; + di in gr "-------------------------------------------------" + "------------------------------" ; + di in gr " | | Begg's Begg's" + " cont. corr. | Egger's " ; + di in gr _skip(`sp') "`by' | n | score s.d. z" + " p z p | bias p" ; + di in gr "---------+------+--------------------------------" + "---------------+--------------" ; + #delimit cr + local scs " " + } +* v7 fix +* local sp = 8 - length(`bylabel') + local blab: label (`bylabl') `j' + local sp = 8 - length("`blab'") + + if `c' == 1 { + local cs "*" + local scs "*" + } + else {local cs " "} +* .....display results for each by-value + if `data' > 0 { +* v7 fix + di in gr _skip(`sp') "`blab' | " in ye %4.0f `k' _c +* di in gr _skip(`sp') `bylabel' " | " in ye %4.0f `k' _c + di in gr " |" in ye %4.0f `ks' in gr "`cs' " _c + di in ye %6.3f `sdks' " " %6.2f `zu' " " %6.3f `p' " " _c + di in ye %6.2f `zcc' " " %6.3f `pcc' in gr " |" _c + di in ye %6.2f `bias' " " %6.3f `pb' + } +* .....do stratified calculations + if `j' == `byn' { + scalar `zu' = `sks' / sqrt(`svks') + scalar `p' = 2 * (1 - normprob(abs(`zu'))) + scalar `zcc' = sign(`sks')*(abs(`sks') - 1) / sqrt(`svks') + scalar `pcc' = 2 * (1 - normprob(abs(`zcc'))) + scalar `k' = `sk' + scalar `ks' = `sks' + scalar `sdks' = sqrt(`svks') + drop `sw' `wl' `swl' `RRm' + qui egen `sw' = sum(`w') if `touse' + qui gen `wl' = `w' * `theta' + qui egen `swl' = sum(`wl') if `touse' + qui gen `RRm' = `swl' / `sw' + scalar `oe' = `RRm' + + qui regr `snd' `prec' if `touse' + capture matrix b = get(_b) + if _rc == 0 { + matrix V = get(VCE) + local df = e(N) - 2 + local bias = b[1,2] + local pb = tprob(`df', b[1,2]/sqrt(V[2,2])) + } + else { + local bias = . + local pb = . + } + + local bias = `sbv' / `sv' + local pb = 1 - normprob(`bias' / sqrt(1 / `sv')) + +* .....and display overall (stratified) results + di in gr "---------+------+----------------------------" _c + di in gr "-------------------+--------------" + di in gr " overall | " in ye %4.0f `sk' _c + di in gr " |" in ye %4.0f `sks' in gr "`scs' " _c + di in ye %6.3f sqrt(`svks') " " %6.2f `zu' " " %6.3f `p' _c + di in ye " " %6.2f `zcc' " " %6.3f `pcc' in gr " |" _c + di in ye %6.2f `bias' " " %6.3f `pb' + di in gr "---------------------------------------------" _c + di in gr "----------------------------------" + if "`scs'" == "*" { + di in gr _skip(21) "`scs' (corrected for ties)" + } + } + } + + else { + +* use this display if no by_var was specified... +* Begg's + di _n in gr "Tests for Publication Bias" + di _n in gr "Begg's Test" + di " " + di in gr " adj. Kendall's Score (P-Q) = " in ye %7.0f `ks' + di _c in gr " Std. Dev. of Score = " in ye %7.2f `sdks' + if `c' == 1 { di in gr " (corrected for ties)" } + else { di " " } + di in gr " Number of Studies = " in ye %7.0f `k' + di in gr " z = " in ye %7.2f `zu' + di in gr " Pr > |z| = " in ye %7.3f `p' + di _c in gr " z = " in ye %7.2f `zcc' + di in gr " (continuity corrected)" + di _c in gr " Pr > |z| = " in ye %7.3f `pcc' + di in gr " (continuity corrected)" + +* Egger's + tempvar prec snd + qui gen `prec'= 1 / `setheta' + qui gen `snd' = `theta' / `setheta' + qui regr `snd' `prec' if `touse' + capture matrix b = get(_b) + if _rc == 0 { + matrix V = get(VCE) + local obs = e(N) + local df = `obs' - 2 + matrix colnames b = slope bias + matrix rownames V = slope bias + matrix colnames V = slope bias + matrix post b V, dep(Std_Eff) dof(`df') obs(`obs') + di _n in gr "Egger's test" + matrix mlout, level(`level') + } + else { + di _n in gr "Egger's Test" _n + di in ye " - undefined for only 1 study" + } + } + + cap drop `var' `w' `sw' `vt' `wtheta' `swtheta' + cap drop `Ts' `wl' `swl' `RRm' + local j = `j' + 1 + +} /* end of loop for each `by' group */ + +* Graph a bias plot +local g = lower(substr("`graph'",1,1)) +if "`g'" == "b" { + beggph `theta' `setheta' `touse', level(`level') `ci' `options' +} +if "`g'" == "e" { + egggph `theta' `setheta' `touse', level(`level') `options' +} + +* Save globals +global S_1 = `k' +global S_2 = `ks' +global S_3 = `sdks' +global S_4 = `p' +global S_5 = `pcc' +global S_6 = `bias' +global S_7 = `pb' +global S_8 = `oe' + +* return globals +return scalar k = `k' +return scalar score = `ks' +return scalar score_sd = `sdks' +return scalar Begg_p = `p' +return scalar Begg_pcc = `pcc' +return scalar Egger_bc = `bias' +return scalar Egger_p = `pb' +return scalar effect = `oe' + +exit +end + +* *************************************************** + +program define beggph +version 6.0 + +* creates the Begg funnel plot graph + +* Setup + +syntax varlist(min=3 max=3) [if] [in] [, CI L1title(str) /* + */ L2title(str) Connect(str) Symbol(str) SOrt Pen(str) /* + */ T2title(str) B2title(str) YLAbel(str) XLAbel(str) /* + */ LEVel(integer $S_level) GAp(str) GWeight * ] +tokenize `varlist' + +tempvar touse theta setheta + +local theta `1' +local setheta `2' +local touse `3' + +preserve + +* Graph options +if "`connect'" == "" { local connect "lll." } +else { + local lll = length("`connect'") + if `lll' == 1 { local connect "`connect'll." } + else if `lll' == 2 { local connect "`connect'l." } + else if `lll' == 3 { local connect "`connect'." } +} +local connect "co(`connect')" + +if "`symbol'" == "" { local symbol "iiio" } +else { + local lll = length("`symbol'") + if `lll' == 1 { local symbol "`symbol'iio" } + else if `lll' == 2 { local symbol "`symbol'io" } + else if `lll' == 3 { local symbol "`symbol'o" } +} +local symbol "sy(`symbol')" + +if "`pen'" == "" { local pen "3552" } +else { + local lll = length("`pen'") + if `lll' == 1 { local pen "`pen'552" } + else if `lll' == 2 { + local pen = "`pen'" + substr("`pen'",2,1) + "2" + } + else if `lll' == 3 { local pen "`pen'2" } +} +local pen "pen(`pen')" + +if "`l2title'" == "" { + local l2title : variable label `theta' + if "`l2title'" == "" { local l2title "`theta'" } +} +if "`ci'" == "" { local l2title "l2(`l2title')" } + else { local l2title "l2(log[`l2title'])" } + +if "`l1title'" == "" { local l1title "" "" } +local l1title "l1(`l1title')" + +if "`b2title'" == "" { + local b2title : variable label `theta' + if "`b2title'" == "" { local b2title "`theta'" } +} +if "`ci'" == "" { local b2title = "b2(s.e. of: `b2title')" } + else { local b2title = "b2(s.e. of: log[`b2title'])" } + +if `"`t2title'"' == `""' { + local t2title = "Begg's funnel plot with pseudo" + local t2title = "`t2title' `level'% confidence limits" + local t2title "t2(`"`t2title'"')" +} +else if `"`t2title'"' == `"."' { local t2title } +else { local t2title "t2(`"`t2title'"')" } + +if "`xlabel'" == "" { local xlabel "xla" } + else { local xlabel "xlabel(`xlabel')" } + +if "`ylabel'" == "" { local ylabel "yla" } + else { local ylabel "ylabel(`ylabel')" } + +if "`sort'" == "" { local sort "sort" } + +if "`gap'" == "" { local gap "gap(3)" } + else { local gap "gap(`gap')" } + +tempvar ll2 ul2 z mmm var w sw wl swl RRm +tempname oe + +qui { + if `level' < 1 { local `level' =`level' * 100 } + local z = -1 * invnorm((1 - `level' / 100) / 2) + local obs1=_N+1 + set obs `obs1' + replace `setheta'=0 in `obs1' + replace `theta' = . in `obs1' + gen `var' = `setheta'^2 + gen `w' = 1/`var' + egen `sw' = sum(`w') if `touse' + gen `wl' = `w' * `theta' + egen `swl' = sum(`wl') if `touse' + gen `RRm' = `swl' / `sw' + scalar `oe' = `RRm' + egen `mmm' = min(`RRm') + replace `RRm' = `mmm' if `setheta' == 0 + gen `ll2' = `RRm' - `z' * `setheta' + gen `ul2' = `RRm' + `z' * `setheta' +} + +if "`gweight'" != "" { + tempvar ww + qui gen `ww' = `w' + qui replace `ww' = 1 if `setheta' == 0 + local gw "[w=`ww']" +} +else { local gw "" } + +#delimit ; + graph `RRm' `ll2' `ul2' `theta' `setheta' `gw' if `touse', + `connect' `symbol' `t2title' `l2title' `b2title' + `l1title' `xlabel' `ylabel' `sort' `pen' `gap' `options'; +#delimit cr + +exit +end + +* *************************************************** + +program define egggph +version 6.0 + +* creates the Egger regression asymmetry plot graph + +* Setup + +syntax varlist(min=3 max=3) [if] [in] [, LEVel(integer 95) GWeight /* + */ GAp(str) Connect(str) Symbol(str) SOrt Pen(str) T2title(str) /* + */ B2title(str) YLAbel(str) XLAbel(str) L1title(str) L2title(str) *] + +tokenize `varlist' + +tempvar touse theta setheta + +local theta `1' +local setheta `2' +local touse `3' + +preserve + +* Graph options +if "`connect'" == "" { local connect ".ll" } +else { + local lll = length("`connect'") + if `lll' == 1 { local connect "`connect'll" } + else if `lll' == 2 { local connect "`connect'l" } +} +local connect "co(`connect')" + +if "`symbol'" == "" { local symbol "oid" } +else { + local lll = length("`symbol'") + if `lll' == 1 { local symbol "`symbol'id" } + else if `lll' == 2 { local symbol "`symbol'd" } +} +local symbol "sy(`symbol')" + +if "`pen'" == "" { local pen "233" } +else { + local lll = length("`pen'") + if `lll' == 1 { local pen "`pen'33" } + else if `lll' == 2 {local pen = "`pen'" + substr("`pen'",2,1)} +} +local pen "pen(`pen')" + +if "`l2title'" == "" { local l2title "standardized effect" } +local l2title "l2(`l2title')" + +if "`l1title'" == "" { local l1title "" "" } +local l1title "l1(`l1title')" + +if "`b2title'" == "" { local b2title "precision" } +local b2title = "b2(`b2title')" + +if `"`t2title'"' == `""' { + local t2title = "Egger's publication bias plot" + local t2title "t2(`"`t2title'"')" +} +else if `"`t2title'"' == `"."' { local t2title t2(" ")} +else { local t2title "t2(`"`t2title'"')" } + + +if "`xlabel'" == "" { local xlabel "xla" } + else { local xlabel "xlabel(`xlabel')" } + +if "`ylabel'" == "" { local ylabel "yla" } + else { local ylabel "ylabel(`ylabel')" } + +if "`sort'" == "" { local sort "sort" } + +if "`gap'" == "" { local gap "gap(3)" } + else { local gap "gap(`gap')" } + +qui { + local obs1 = _N + 1 + local obs2 = _N + 2 + local obs3 = _N + 3 + set obs `obs3' + replace `setheta' = 0 in `obs1'/`obs3' + replace `theta' = . in `obs1'/`obs3' + tempvar prec snd + gen `prec' = 1 / `setheta' if `setheta' > 0 + gen `snd' = `theta' / `setheta' if `setheta' > 0 + replace `prec' = 0 if `prec' == . + regr `snd' `prec' if `touse' + tempvar reg ci + capture matrix b = get(_b) + if _rc == 0 { + matrix V = get(VCE) + local df = e(N) - 2 + gen `reg' = b[1,2] + `prec' * b[1,1] + gen `ci' = . + #delimit ; + replace `ci' = b[1,2] - sqrt(V[2,2]) + * invt(`df', `level'/100) in `obs2' ; + replace `ci' = b[1,2] + sqrt(V[2,2]) + * invt(`df', `level'/100) in `obs3' ; + #delimit cr + } + else { + gen `reg' = . + gen `ci' = . + } +} + +if "`gweight'" != "" { + tempvar ww + qui gen `ww' = 1 / `setheta'^2 + qui replace `ww' = 1 if `setheta' == 0 + local gw "[w=`ww']" +} +else { local gw "" } + +#delimit ; + graph `snd' `reg' `ci' `prec' `gw' if `touse', yli(0) xli(0) + `connect' `symbol' `t2title' `l2title' `b2title' + `l1title' `xlabel' `ylabel' `sort' `pen' `gap' `options'; +#delimit cr + +exit +end + +* *************************************************** + +*! ktau2 version 4.1.0 26sep97 TJS +program define ktau2 +version 4.0 + +* modification of ktau to allow N==2, un-continuity-corrected +* z and p values, and to pass more parameters + +local varlist "req ex min(2) max(2)" +local if "opt" +local in "opt" +parse "`*'" +parse "`varlist'", parse(" ") +local x "`1'" +local y "`2'" +tempname k N NN pval score se tau_a tau_b +tempname xt xt2 xt3 yt yt2 yt3 +tempvar doit nobs order work +mark `doit' `in' `if' +markout `doit' `x' `y' +quietly count if `doit' +scalar `N' = _result(1) +if `N' < 2 { error 2001 } +local Nmac = `N' +qui { + gen long `order' = _n /* restore ordering at end */ + replace `doit' = -`doit' + sort `doit' /* put obs for computation first */ + gen double `work' = 0 /* using type double is fastest */ + scalar `k' = 2 + while (`k' <= `N') { + local kk = `k' - 1 + #delimit ; + replace `work' = `work' + + sign((`x' - `x'[`k'])*(`y' - `y'[`k'])) + in 1/`kk' ; /* using "in" is fastest */ + #delimit cr + scalar `k' = `k' + 1 + } + replace `work' = sum(`work') in 1/`Nmac' + scalar `score' = `work'[`N'] +/* Calculate ties on `x' */ + egen long `nobs' = count(`x') in 1/`Nmac', by(`x') + tempvar nobsxm + egen `nobsxm' = max(`nobs') +/* Calculate correction term for ties on `x' */ + replace `work' = sum((`nobs' - 1)*(2*`nobs' + 5)) in 1/`Nmac' + scalar `xt' = `work'[`N'] +/* Calculate correction term for pairs of ties on `x' */ + replace `work' = sum(`nobs' - 1) in 1/`Nmac' + scalar `xt2' = `work'[`N'] +/* Calculate correction term for triplets of ties on `x' */ + replace `work' = sum((`nobs' - 1)*(`nobs' - 2)) in 1/`Nmac' + scalar `xt3' = `work'[`N'] +/* Calculate ties on `y' */ + drop `nobs' + egen long `nobs' = count(`y') in 1/`Nmac', by(`y') + tempvar nobsym + egen `nobsym' = max(`nobs') +/* Calculate correction term for ties on `y' */ + replace `work' = sum((`nobs' - 1)*(2*`nobs' + 5)) in 1/`Nmac' + scalar `yt' = `work'[`N'] +/* Calculate correction term for pairs of ties on `y' */ + replace `work' = sum(`nobs' - 1) in 1/`Nmac' + scalar `yt2' = `work'[`N'] +/* Calculate correction term for triplets of ties on `y' */ + replace `work' = sum((`nobs' - 1)*(`nobs' - 2)) in 1/`Nmac' + scalar `yt3' = `work'[`N'] +/* Compute Kendall's tau-a, tau-b, s.e. of score, and pval */ + scalar `NN' = `N'*(`N' - 1) + scalar `tau_a' = 2*`score'/`NN' + scalar `tau_b' = 2*`score'/sqrt((`NN' - `xt2')*(`NN' - `yt2')) + #delimit ; + scalar `se' = `NN'*(2*`N' + 5); + tempname tmax; + scalar `tmax' = max(`nobsxm', `nobsym'); + if `tmax' > 1 { scalar `se' = `se' + - (`xt' - `yt') + + `xt3'*`yt3'/(9*`NN'*(`N' - 2)) + + `xt2'*`yt2'/(2*`NN') } ; + scalar `se' = sqrt((1/18)*`se'); + #delimit cr + local zcc = (abs(`score') - 1) / `se' + local z = `score '/ `se' + tempname pvalcc + if `score' == 0 { + scalar `pval' = 1 + scalar `pvalcc' = 1 + } + else scalar `pvalcc' = 2*(1 - normprob((abs(`score') - 1)/`se')) + else scalar `pval' = 2*(1 - normprob(abs(`score')/`se')) +/* Restore original ordering of data set */ + sort `order' +} +/* Print results */ +#delimit ; + di _n + in gr " Number of obs = " in ye %7.0f `N' _n + in gr "Kendall's tau-a = " in ye %12.4f `tau_a' _n + in gr "Kendall's tau-b = " in ye %12.4f `tau_b' _n + in gr "Kendall's score = " in ye %7.0f `score' _n + in gr " SE of score = " in ye %11.3f `se' _c ; + if `xt2' > 0 | `yt2' > 0 { di in gr " (corrected for ties)" _c } ; + di _n(2) + in gr "Test of Ho: `x' and `y' independent" _n + in gr " z = " in ye %12.2f `z' _n + in gr " Pr > |z| = " in ye %12.4f = `pval' _n(2) + in gr " z = " in ye %12.2f sign(`score')*`zcc' _n + in gr " Pr > |z| = " in ye %12.4f = `pvalcc' + in gr " (continuity corrected)" ; +#delimit cr +local c = 0 +if `xt2' > 0 | `yt2' > 0 { local c = 1 } +global S_1 = `N' +global S_2 = `tau_a' +global S_3 = `tau_b' +global S_4 = `score' +global S_5 = `se' +global S_6 = `pval' +global S_7 = `z' +global S_8 = `pvalcc' +global S_9 = `zcc' +global S_10 = `c' +end + +* *************************************************** + +*! ifexp version 1.2.1 19nov98 TJS +program define ifexp +version 5.0 + +while substr("`1'",1,2) != "if" { + macro shift +} + +local if "required" +local options "noVARlabel noVALlabel noUNabbrev noSPace Color(str)" +parse "`*'" +parse "`if'", parse(" ><=&|!()") + +if "`color'" == "" {local color = "b"} /* set display color */ +local color = lower(substr("`color'",1,1)) +if index("wbgyr","`color'") == 0 {local color = "b"} + +if "`if'" != "" { + local ifst " if " /* handle leading "if " */ + local lif = 5 + macro shift + + if "`space'" != "nospace" { /* set up space */ + local sp " " + local sp1 = 1 + } + else { local sp1 = 0 } + + di + while "`1'" != "" { /* start main loop on tokens */ + capture confirm variable `1' /* var name ? */ + local rc _rc + + local m = 0 + local n = length("`1'") + if `n' + `lif' > 78 { /* no room for token ? */ + di in `color' "`ifst'" + local ifst "> " + local lif = 5 + local n = 0 + } + /* is punctuation */ + if "`1'" == "==" { local ifst "`ifst'`1'`sp'" } + else if "`1'" == "<=" { local ifst "`ifst'`1'`sp'" } + else if "`1'" == ">=" { local ifst "`ifst'`1'`sp'" } + else if "`1'" == "!=" { local ifst "`ifst'`1'`sp'" } + else if "`1'" == "<" { local ifst "`ifst'`1'`sp'" } + else if "`1'" == ">" { local ifst "`ifst'`1'`sp'" } + else if "`1'" == "=" { local ifst "`ifst'`1'`sp'" } + else if "`1'" == "&" { local ifst "`ifst'`1'`sp'" } + else if "`1'" == "|" { local ifst "`ifst'`1'`sp'" } + else if "`1'" == "!" { local ifst "`ifst'`1'`sp'" } + else if "`1'" == "(" { local ifst "`ifst'`1'`sp'" } + else if "`1'" == ")" { local ifst "`ifst'`1'`sp'" } + + else if `rc' == 0 { /* is a variable name */ + local tif "`1'" + if "`unabbrev'" != "nounabbrev" { /* allow unabbrev */ + unabbrev `1' + local tif "$S_1" + } + if "`varlabel'" != "novarlabel" { /* allow var label ? */ + local vrl : variable label `1' + if "`vrl'" != "" { local tif "`vrl'" } /* var label ? */ + } + + local wc: word count `tif' /* process > 1 word in label */ + local w 1 + while `w' < `wc' { + local wif: word `w' of `tif' + local wm = length("`wif'") + if `wm' + `lif' > 78 { + di in `color' "`ifst'" + local ifst "> " + local lif = 5 + local n = `m' + local m = 0 + } + else { + local lif = `lif' + `wm' + `sp1' + local ifst "`ifst'`wif'`sp'" + local w = `w' + 1 + } + } + local tif: word `wc' of `tif' /* do last or only word */ + + local m = length("`tif'") /* no room for token ? */ + if `m' + `lif' > 78 { + di in `color' "`ifst'" + local ifst "> " + local lif = 5 + local n = `m' + local m = 0 + } + local ifst "`ifst'`tif'`sp'" + local vll : value label `1' + } + + else { /* is a value */ + local tif "`1'" /* allow value label ? */ + if "`vll'" != "" & "`vallabel'" != "novallabel" { + local lv : label `vll' `1' + if "`lv'" != "" { local tif "`lv'" } /* value label ? */ + } + + local wc: word count `tif' /* process > 1 word in label */ + local w 1 + while `w' < `wc' { + local wif: word `w' of `tif' + local wm = length("`wif'") + if `wm' + `lif' > 78 { + di in `color' "`ifst'" + local ifst "> " + local lif = 5 + local n = `m' + local m = 0 + } + else { + local lif = `lif' + `wm' + `sp1' + local ifst "`ifst'`wif'`sp'" + local w = `w' + 1 + } + } + local tif: word `wc' of `tif' /* do last or only word */ + + local m = length("`tif'") /* no room for token ? */ + if `m' + `lif' > 78 { + di in `color' "`ifst'" + local ifst "> " + local lif = 5 + local n = `m' + local m = 0 + } + local ifst "`ifst'`tif'`sp'" + } + /* set new line length */ + if `m' > 0 { local lif = `lif' + `m' + `sp1' } + else { local lif = `lif' + `n' + `sp1' } + macro shift /* next token */ + } /* end main loop on tokens */ + +di in `color' "`ifst'" /* display expanded if */ + +global S_1 "`ifst'" +exit +end diff --git a/Modules/ado/plus/m/metabias.dlg b/Modules/ado/plus/m/metabias.dlg new file mode 100644 index 0000000..c698244 --- /dev/null +++ b/Modules/ado/plus/m/metabias.dlg @@ -0,0 +1,188 @@ +/* +*! metabias dialog version 1.0.1, 13 May 2003, T. J. Steichen, steichen@triad.rr.com +*! for metabias version 1.2.4, 08 Sep 2003, T. J. Steichen, steichen@triad.rr.com + +Tests for publication bias in meta-analysis +------------------------------------------- + +Syntax: metabias { theta { se_theta | var_theta } | exp(theta) ll ul [cl] } + [ if exp ] [ in range ] [, by(by_var) { var | ci } + graph({ begg | egger }) gweight level(#) graph_options ] + +Install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "meta&bias (Publication Bias in Meta-analysis)" "db metabias" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. +*/ + +VERSION 8.0 + +INCLUDE _std_small +INCLUDE header + +HELP hlp1, view("help metabias") +RESET res1, label("Reset") + +DIALOG main, label("metabias 1.2.4 - Publication Bias in Meta-analysis") tabtitle("Main") +BEGIN + GROUPBOX gb_data 10 5 330 _ht5h, /// + label("Type of Data:") + RADIO r_se 15 25 100 ., /// + label("Theta, SE") first /// + onclickon(script main_se_on) /// + onclickoff(script main_se_off) /// + option(NONE) + RADIO r_var 115 25 100 ., /// + label("Theta, Var") middle /// + onclickon(script main_var_on) /// + onclickoff(script main_var_off) /// + option("var") + RADIO r_ci 215 25 110 ., /// + label("exp(Theta), CI") last /// + onclickon(script main_ci_on) /// + onclickoff(script main_ci_off) /// + option("ci") + + TEXT tx_se 15 45 320 ., /// + label("Vars for theta, se(theta), in that order") + VARLIST vl_se @ _ss @ ., /// + label("Vars for theta, se(theta)") + + TEXT tx_var @ 45 320 ., /// + label("Vars for theta, var(theta), in that order") + VARLIST vl_var @ _ss @ ., /// + label("Vars for theta, var(theta)") + + TEXT tx_ci @ 45 320 ., /// + label("Vars for exp(theta), CI_LL, CI_UL, in that order") + VARLIST vl_ci @ _ss @ ., /// + label("Vars for exp(theta), CI_LL, CI_UL") + + CHECKBOX cb_by 10 100 100 ., /// + label("By Variable:") /// + onclickon(main.vn_by.enable) /// + onclickoff(main.vn_by.disable) + VARNAME vn_by 110 100 230 ., /// + label("By Variable") /// + option("by") + + GROUPBOX gb_graph 10 130 330 _ht3h, /// + label("Graph:") + RADIO r_none 15 150 100 ., /// + label("None") first /// + onclickon(main.cb_gwt.disable) /// + option(NONE) + RADIO r_begg 115 150 100 ., /// + label("Begg") middle /// + onclickon(main.cb_gwt.enable) /// + option("graph(begg)") + RADIO r_egger 215 150 100 ., /// + label("Egger") last /// + onclickon(main.cb_gwt.enable) /// + option("graph(egger)") + + CHECKBOX cb_gwt 15 175 300 ., /// + label("Size Graph Symbol by Weights") /// + option("gweight") +END + +INCLUDE ifin + +SCRIPT main_se_on +BEGIN + main.tx_se.show + main.vl_se.show + main.tx_se.enable + main.vl_se.enable + + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide + + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +SCRIPT main_se_off +BEGIN + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide +END + +SCRIPT main_var_on +BEGIN + main.tx_var.show + main.vl_var.show + main.tx_var.enable + main.vl_var.enable + + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide + + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +SCRIPT main_var_off +BEGIN + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide +END + +SCRIPT main_ci_on +BEGIN + main.tx_ci.show + main.vl_ci.show + main.tx_ci.enable + main.vl_ci.enable + + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide + + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide +END + +SCRIPT main_ci_off +BEGIN + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +PROGRAM command +BEGIN + put "metabias " + if main.r_se { + varlist main.vl_se + } + if main.r_var { + varlist main.vl_var + } + if main.r_ci { + varlist main.vl_ci + } + INCLUDE _ifin_pr + beginoptions + option radio(main r_se r_var r_ci) + optionarg main.vn_by + option radio(main r_none r_begg r_egger) + option main.cb_gwt + endoptions +END diff --git a/Modules/ado/plus/m/metabias.hlp b/Modules/ado/plus/m/metabias.hlp new file mode 100644 index 0000000..1a54aff --- /dev/null +++ b/Modules/ado/plus/m/metabias.hlp @@ -0,0 +1,211 @@ +.- + help for ^metabias^ (STB-41: sbe19; STB-44: sbe19.1; STB-57: sbe19.2; + STB-58: sbe19.3; STB-61: sbe19.4) +.- + +Tests for publication bias in meta-analysis +------------------------------------------- + + ^metabias^ { theta { se_theta | var_theta } | exp(theta) ll ul [cl] } + [ ^if^ exp ] [ ^in^ range ] [^, by(^by_var^)^ { ^v^ar | ^ci^ } + ^g^raph^(b^egg | ^e^gger^) gw^eight ^l^evel^(^#^)^ graph_options ] + + where { a | b |...} means choose one and only one of {a, b, ...}. + + +Description +----------- + +^metabias^ performs the Begg and Mazumdar adjusted rank correlation test for +publication bias and performs the Egger, et al., regression asymmetry test for +publication bias. As options, it provides a funnel graph of the data or the +regression asymmetry plot. + +The Begg adjusted rank correlation test is a direct statistical analogue of +the visual funnel graph. Note that both the test and the funnel graph have +low power for detecting publication bias. The Begg and Mazumdar procedure +tests for publication bias by determining if there is a significant +correlation between the effect estimates and their variances. ^metabias^ +carries out this test by, first, standardizing the effect estimates to +stabilize the variances and, second, performing an adjusted rank correlation +test based on Kendall's tau. + +The Egger, et al., regression asymmetry test and the regression asymmetry plot +tend to suggest the presence of publication bias more frequently than the Begg +approach. The Egger test detects funnel plot asymmetry by determining whether +the intercept deviates significantly from zero in a regression of the +standardized effect estimates against their precision. + +Egger, et al., claim that the test predicts the discordance (if any) of +meta-analytic results and single large trials, but no formal analysis of +coverage (i.e., nominal significance level) or power has been performed. + +The user provides the effect estimate, ^theta^, to ^metabias^ as a log +risk ratio, log odds ratio, or other direct measure of effect. Along +with theta, the user supplies a measure of theta's variability (i.e., +its standard error, ^se_theta^, or its variance, ^var_theta^). +Alternatively, the user may provide the exponentiated form, +^exp(theta)^, (i.e., a risk ratio or odds ratio) and its confidence +interval, ^(ll, ul)^. + +The funnel graph plots ^theta^ versus ^se_theta^. Guide lines to assist in +visualizing the funnel are plotted at the variance-weighted (fixed effects) +meta-analytic effect estimate and at pseudo confidence interval limits about +that effect estimate (i.e., at ^theta +/- z * se_theta^, where ^z^ is the +standard Normal variate for the confidence level specified by option ^level()^. +Asymmetry on the right of the graph (where studies with high standard error +are plotted) may give evidence of publication bias. + +The regression asymmetry graph plots the standardized effect estimates, +^theta / se_theta^, versus precision, ^1 / se_theta^, along with the +regression line and the confidence interval about the intercept. Failure of +this confidence interval to include zero indicates asymmetry in the funnel +plot and may give evidence of publication bias. Guide lines at x = 0 and +y = 0 are plotted to assist in visually determining if zero is in the +confidence interval. + +^metabias^ will perform stratified versions of both the Begg and Mazumdar test +and the Egger regression asymmetry test when option ^by(by_var)^ is specified. +Variable ^by_var^ indicates the categorical variable that defines the strata. +The procedure reports results for each strata and for the stratified tests. +The graphs, if selected, plot only the combined unstratified data. + + +Options +------- + +^by(by_var)^ requests that the stratified tests be carried out with + strata defined by ^by_var^. + +^var^ indicates that ^var_theta^ was supplied on the command line + instead of ^se_theta^. Option ^ci^ should not be specified when + option ^var^ is specified. + +^ci^ indicates that ^exp(theta)^ and its confidence interval, ^(ll, + ul)^, were supplied on the command line instead of ^theta^ and + ^se_theta^. Option ^var^ should not be specified when option ^ci^ is + specified. + +^graph(begg)^ requests the Begg funnel graph showing the data, the + fixed-effects (variance-weighted) meta-analytic effect, and the pseudo + confidence interval limits about the meta-analytic effect. + +^graph(egger)^ requests the Egger regression asymmetry plot showing the + standardized effect estimates versus precision, the regression line, and + the confidence interval about the intercept. + +^gweight^ requests that the graphic symbols representing the data in the + plot be sized proportional to the inverse variance. + +^level()^ sets the confidence level % for the pseudo confidence intervals; + the default is 95%. + +^graph_options^ are those allowed with ^graph, twoway^. For + ^graph(begg)^, the default graph_options include ^connect(lll.)^, + ^symbol(iiio)^, and ^pen(3552)^ for displaying the meta-analytic + effect, the pseudo confidence interval limits (two lines), and the + data points, respectively. For ^graph(egger)^, the default + graph_options include ^connect(.ll)^, ^symbol(oid)^, and ^pen(233)^ + for displaying the data points, regression line, and the confidence + interval about the intercept, respectively. Setting ^t2title(.)^ + blanks out the default ^t2title^ in either graph. + + +Required input variables +------------------------ + + ^theta^ the effect estimate + ^se_theta^ the corresponding standard error + + or + + ^theta^ the effect estimate + ^var_theta^ the corresponding variance + + or + + ^exp(theta)^ the risk (or odds) ratio + ^ll^ the lower limit of the risk ratio's confidence interval + ^ul^ the upper limit of the risk ratio's confidence interval + [^cl^] optional (see below) + + +Optional input variable +----------------------- + +^cl^ contains the confidence level of the confidence interval defined by ^ll^ +and ^ul^. If ^cl^ is not provided, the procedure assumes that each confidence +interval is at the 95% confidence level. ^cl^ allows the user to provide the +confidence level, by study, when the confidence interval is not at the default +level. ^cl^ can be specified with or without a decimal point. For example, +90 and .90 are equivalent and may be mixed (i.e., 90, .95, 80, .90 etc.). + + +Note +---- + +If your data are in raw count format, program ^metan^ can be used to +facilitate conversion to effect format. ^metan^ automatically adds +^exp(theta)^ and ^se_theta^ variables to the dataset, calling them +^_ES^ and ^_seES^. You must manually generate ^theta^ as the natural +log of ^_ES^ (for example, ^gen _lnES = ln(_ES)^) then input the +effect-format variables, ^_lnES^ and ^_seES^, using ^metabias^'s +default input method. + + + +Saved values +------------ + +The following items are saved in the global ^S_^# macros and are returned in ^r()^. + + ^S_1 r(k)^ number of studies + ^S_2 r(score)^ Begg's score + ^S_3 r(score_sd)^ s.d. of Begg's score + ^S_4 r(Begg_p)^ Begg's p value + ^S_5 r(Begg_pcc)^ Begg's p, continuity corrected + ^S_6 r(Egger_bc)^ Egger's bias coefficient + ^S_7 r(Egger_p)^ Egger's p value + ^S_8 r(effect)^ overall effect (log scale) + + +Examples +-------- + + . ^metabias logrr selogrr, graph(begg)^ + . ^metabias logrr varlogrr if site==3, var graph(egger)^ + . ^metabias rr ll ul, ci by(site)^ + . ^metabias logor selogor if region==4, graph(egger) level(90)^ + + +Note +---- + +^metabias^ calls program ^ktau2^, a modification of the ^ktau^ program +supplied with Stata. ^ktau2^ is included in the distribution files +for this version of ^metabias^. + + +References +---------- + +Begg, C. B., Mazumdar, M., 1994. Operating characteristics of a rank +correlation test for publication bias. Biometrics 50: 1088-1101. + +Egger, M., Smith, G. D., Schneider, M., Minder, C., 1997. Bias in +meta-analysis detected by a simple, graphical test. British Medical +Journal 315: 629-634. + + +Author +------ + +Thomas J. Steichen, RJRT, steicht@@rjrt.com + + +Also see +-------- + + STB: STB-41 sbe19; STB-44 sbe19.1 + Manual: [R] spearman +On-line: help for @meta@, @metan@, and @ktau@ (if installed) diff --git a/Modules/ado/plus/m/metacum.dlg b/Modules/ado/plus/m/metacum.dlg new file mode 100644 index 0000000..ce3eced --- /dev/null +++ b/Modules/ado/plus/m/metacum.dlg @@ -0,0 +1,302 @@ +/* + +*! metacum dialog version 1.0.1, 13 May 2003, T. J. Steichen, steichen@triad.rr.com +*! for metacum version 1.02, Jan 1998, Jonathan Sterne, jonathan.sterne@bristol.ac.uk + +metacum VERSION 1.02 jan1998 + +Cumulative meta-analysis, with graphics +--------------------------------------- + +Syntax: metacum { theta | exp(theta) } { se_theta | var_theta | ll ul [cl] } + [if exp] [in range] effect(f|r) [ , id(strvar) var ci eform level(#) + graph cline ltrunc(#) rtrunc(#) csize(#) fmult(#) ] + +To install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "Cumulative meta-analysis (meta&cum)" "db metacum" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. +*/ + +VERSION 8.0 + +INCLUDE _std_small +INCLUDE header + +HELP hlp1, view("help metacum") +RESET res1, label("Reset") + +DIALOG main, label("metacum 1.02 - Cumulative Meta-analysis") tabtitle("Main") +BEGIN + GROUPBOX gb_data 10 5 330 _ht5h, /// + label("Type of Data:") + RADIO r_se 15 25 100 ., /// + label("Theta, SE") first /// + onclickon(script main_se_on) /// + onclickoff(script main_se_off) /// + option(NONE) + RADIO r_var 115 25 100 ., /// + label("Theta, Var") middle /// + onclickon(script main_var_on) /// + onclickoff(script main_var_off) /// + option("var") + RADIO r_ci 215 25 110 ., /// + label("exp(Theta), CI") last /// + onclickon(script main_ci_on) /// + onclickoff(script main_ci_off) /// + option("ci") + + TEXT tx_se 15 45 320 ., /// + label("Vars for theta, se(theta), in that order") + VARLIST vl_se @ _ss @ ., /// + label("Vars for theta, se(theta)") + + TEXT tx_var @ 45 320 ., /// + label("Vars for theta, var(theta), in that order") + VARLIST vl_var @ _ss @ ., /// + label("Vars for theta, var(theta)") + + TEXT tx_ci @ 45 320 ., /// + label("Vars for exp(theta), CI_LL, CI_UL, in that order") + VARLIST vl_ci @ _ss @ ., /// + label("Vars for exp(theta), CI_LL, CI_UL") + + CHECKBOX cb_id 10 100 100 ., /// + label("ID Variable:") /// + onclickon(main.vn_id.enable) /// + onclickoff(main.vn_id.disable) + VARNAME vn_id 110 100 230 ., /// + label("ID Variable") /// + option("id") + + GROUPBOX gb_effect 10 130 110 _ht3h, /// + label("Pooling Model:") + RADIO r_fixed 15 145 65 ., /// + label("Fixed") first /// + option("effect(f)") + RADIO r_random 15 165 75 ., /// + label("Random") last /// + option("effect(r)") + + CHECKBOX cb_level 160 145 75 ., /// + label("CI Level:") /// + onclickon(main.ed_level.enable) /// + onclickoff(main.ed_level.disable) + EDIT ed_level 240 @ 40 ., /// + label("Level") /// + numonly default(95) /// + option("level") + + CHECKBOX cb_eform 160 165 120 ., /// + label("Use exp(theta)") /// + option("eform") +END + + +DIALOG graph, tabtitle("Graph") +BEGIN + CHECKBOX cb_graph 10 10 330 _ht7h, /// + groupbox /// + onclickon(program graph_on) /// + onclickoff(program graph_off) /// + label("Draw Graph:") /// + option("graph") + + CHECKBOX cb_cline 20 35 150 ., /// + label("Draw Estimate line") /// + option("cline") + + CHECKBOX cb_ltrunc 20 60 95 ., /// + label("Left truncate:") /// + onclickon(graph.ed_ltrunc.enable) /// + onclickoff(graph.ed_ltrunc.disable) + EDIT ed_ltrunc 130 @ 40 ., /// + label("Left truncate") numonly /// + option("ltrunc") + + CHECKBOX cb_rtrunc 20 80 105 ., /// + label("Right truncate:") /// + onclickon(graph.ed_rtrunc.enable) /// + onclickoff(graph.ed_rtrunc.disable) + EDIT ed_rtrunc 130 @ 40 ., /// + label("Right truncate") numonly /// + option("rtrunc") + + CHECKBOX cb_fmult 195 60 95 ., /// + label("Font scale:") /// + onclickon(graph.ed_fmult.enable) /// + onclickoff(graph.ed_fmult.disable) + EDIT ed_fmult 290 60 40 ., /// + label("Font scale") /// + numonly default("1") /// + option("fmult") + + CHECKBOX cb_csize 195 80 95 ., /// + label("Circle size:") /// + onclickon(graph.ed_csize.enable) /// + onclickoff(graph.ed_csize.disable) + EDIT ed_csize 290 80 40 ., /// + label("Circle size") /// + numonly default("180") /// + option("csize") + + GROUPBOX gb_gopts7 10 145 330 _ht2h, /// + label("Allowed Graph7 Options:") + EDIT ed_gopts7 15 165 320 ., /// + label("Graph7 Options") +END + +INCLUDE ifin + +SCRIPT main_se_on +BEGIN + main.tx_se.show + main.vl_se.show + main.tx_se.enable + main.vl_se.enable + + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide + + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +SCRIPT main_se_off +BEGIN + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide +END + +SCRIPT main_var_on +BEGIN + main.tx_var.show + main.vl_var.show + main.tx_var.enable + main.vl_var.enable + + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide + + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +SCRIPT main_var_off +BEGIN + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide +END + +SCRIPT main_ci_on +BEGIN + main.tx_ci.show + main.vl_ci.show + main.tx_ci.enable + main.vl_ci.enable + + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide + + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide +END + +SCRIPT main_ci_off +BEGIN + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +PROGRAM graph_on +BEGIN + call graph.cb_cline.enable + call graph.cb_fmult.enable + call graph.cb_ltrunc.enable + call graph.cb_rtrunc.enable + call graph.cb_csize.enable + call graph.gb_gopts7.enable + call graph.ed_gopts7.enable + if graph.cb_fmult { + call graph.ed_fmult.enable + } + if graph.cb_ltrunc { + call graph.ed_ltrunc.enable + } + if graph.cb_rtrunc { + call graph.ed_rtrunc.enable + } + if graph.cb_csize { + call graph.ed_csize.enable + } +END + +PROGRAM graph_off +BEGIN + call graph.cb_cline.disable + call graph.cb_fmult.disable + call graph.cb_ltrunc.disable + call graph.cb_rtrunc.disable + call graph.cb_csize.disable + call graph.gb_gopts7.disable + call graph.ed_gopts7.disable + if graph.cb_fmult { + call graph.ed_fmult.disable + } + if graph.cb_ltrunc { + call graph.ed_ltrunc.disable + } + if graph.cb_rtrunc { + call graph.ed_rtrunc.disable + } + if graph.cb_csize { + call graph.ed_csize.disable + } +END + +PROGRAM command +BEGIN + put "metacum " + if main.r_se { + varlist main.vl_se + } + if main.r_var { + varlist main.vl_var + } + if main.r_ci { + varlist main.vl_ci + } + INCLUDE _ifin_pr + beginoptions + option radio(main r_se r_var r_ci) + optionarg main.vn_id + option radio(main r_fixed r_random) + option main.cb_eform + optionarg main.ed_level + option graph.cb_graph + option graph.cb_cline + optionarg graph.ed_ltrunc + optionarg graph.ed_rtrunc + optionarg graph.ed_fmult + optionarg graph.ed_csize + put graph.ed_gopts7 + endoptions +END diff --git a/Modules/ado/plus/m/metafunnel.ado b/Modules/ado/plus/m/metafunnel.ado new file mode 100644 index 0000000..84f3a8b --- /dev/null +++ b/Modules/ado/plus/m/metafunnel.ado @@ -0,0 +1,349 @@ +*! Version 1.0.2, JACS, 18 August 2003 +program define metafunnel + version 8.1 + * Graphs funnel plot, with standard error on the vertical axis + + if ("`*'" == "") { + di "Syntax is:" + di in wh "metafunnel " in gr "{ theta { se | var } | " _c + di in gr "exp(theta) | ll ul [cl] } [" _c + di in wh "if " in gr "exp] [" in wh "in " in gr "range]" + di in gr " [ " in wh ", by(" in gr "by_var"in wh ")" _c + di in gr " { " in wh "v" in gr "ar | " in wh "ci" in gr " } " _c + di in wh "nol" in gr "ines " in wh "forc" in gr "enull " _c + di in wh "rev" in gr "erse " in wh "ef" in gr "orm" + di in gr " graph_options ]" + + exit + } + + syntax varlist(numeric min=2 max=4) [if] [in], [ by(varname) /// + Var CI SUbtitle(str) NOLines FORCenull REVerse EForm /// + XTitle(string) YTitle(string) XScale(string) YScale(string) /// + MSymbol(string) * ] + + tempvar touse theta setheta etheta zz + tempvar ll2 ul2 vl z mmm vvar w sw wl swl RRm orign + tempname oe + + tokenize `varlist' + local theta `1' + + if "`3'" == "" { + local setheta `2' + } + else { + tempvar ll ul cl + local ll `2' + local ul `3' + local cl `4' + } + + * input error traps + if "`ci'" != "" & "`var'" != "" { + di _n as error "Error: options 'ci' and 'var' cannot " _c + di as error "be specified together." + exit + } + if "`ci'" == "ci" & "`ul'" != "" { + di _n as text "Note: option 'ci' specified." + } + if "`ci'" == "ci" & "`ul'" == "" { + di _n as error "Error: option 'ci' specified but varlist " _c + di as error "has only 2 variables." + exit + } + if "`ci'" != "ci" & "`var'" != "var" & "`ul'" != "" { + di _n as text "Warning: varlist has 3 variables but option " _c + di as text "'ci' not specified; 'ci' assumed." + local ci "ci" + local var "" + } + if "`var'" == "var" & "`ul'" != "" { + di _n as error "Error: option 'var' specified but varlist " _c + di as error "has more than 2 variables." + exit + } + if "`var'" == "var" & "`ul'" == "" { + di _n as text "Note: option 'var' specified." + } + if "`var'" != "var" & "`ul'" == "" { + di _n as text "Note: default data input format (theta, " _c + di as text "se_theta) assumed." + } + + * Select data to analyze + mark `touse' `if' `in' + if "`ul'" == "" { + markout `touse' `theta' `setheta' + } + else { + markout `touse' `theta' `ll' `ul' + } + + preserve + quietly keep if `touse' + quietly count + if r(N)==0 { + di as error "No observations with nonmissing values of `by'" + exit 999 + } + + + * initial calculations... + if "`var'" == "var" { + qui replace `setheta' = sqrt(`setheta') + } + + if "`ci'" == "ci" { + di _n as text "Warning: ci option assumes that ratio measures are being used" + capture confirm variable `cl' + if _rc~=0 { + qui gen `zz' = invnorm(.975) + } + else { + qui replace `cl' = `cl' * 100 if `cl' < 1 + qui gen `zz' = -1 * invnorm((1- `cl' / 100) / 2 ) + qui replace `zz' = invnorm(.025) if `zz'==. + } + qui gen `setheta' = ( ln(`ul') - ln(`ll')) / 2 / `zz' + qui replace `theta' = ln(`theta') + } + + * Graph options + + if "`xtitle'" == "" { + local xti : variable label `theta' + if "`xti'" == "" { + local xti "`theta'" + } + } + else if "`xtitle'" ~= "" { + local xti "`xtitle'" + } + + if "`ytitle'" == "" { + local yti : variable label `setheta' + if "`yti'" == "" { + local yti "s.e. of `theta'" + } + } + else if "`ytitle'" ~= "" { + local yti "`ytitle'" + } + + capture assert "`ysca'"=="" + if _rc~=0 { + display as error "ysca option not permitted" + exit 999 + } + + if "`yscale'"~="" { + local chkrev=index("`yscale'","rev") + display "chkrev: `chkrev'" + if `chkrev'~=0 & "`reverse'"=="" { + local ysca "`yscale'" + } + if `chkrev'==0 & "`reverse'"=="" { + local ysca "`yscale' reverse" + } + if `chkrev'~=0 & "`reverse'"~="" { + display "Parsing yscale: ,`yscale' " + tokenize `yscale' + while "`1'"~="" { + if index("`1'","rev")==0 { + local ysca "`ysca' `1'" + } + mac shift + } + } + if `chkrev'==0 & "`reverse'"~="" { + local ysca "`yscale'" + } + } + if "`yscale'"=="" { + if "`reverse'"=="" { + local ysca "reverse" + } + if "`reverse'"~="" { + local ysca "noreverse" + } + } + + if "`subtitle'" == "" { + local subtitle = "Funnel plot with pseudo 95% confidence limits" + } + else if "`subtitle'" == "." { /* "." means blank it out */ + local subtitle "" "" + } + local subtitle "subtitle(`subtitle')" + + if "`msymbol'"=="" { + local symopt "O T S D + X Oh Th Sh Dh o t s d x oh th sh dh p" + } + if "`msymbol'"~="" { + local symopt "`msymbol'" + } + local msymbol "msymbol(`symopt')" + + qui { + gen `orign'=_n + + gen `vvar' = `setheta'^2 + gen `w' = 1/`vvar' + egen `sw' = sum(`w') if `touse' + gen `wl' = `w' * `theta' + egen `swl' = sum(`wl') if `touse' + sort `orign' + gen `RRm' = `swl' / `sw' + local rxl=`RRm'[1] + scalar `oe' = `RRm' + egen `mmm' = min(`RRm') + replace `RRm' = `mmm' if `setheta' == 0 + + if "`forcenull'"~="" { + local rxl=0 + } + + sort `orign' + local obs1=_N+1 + local obs2=_N+2 + local obs3=_N+3 + local obs4=_N+4 + local obs5=_N+5 + local obs6=_N+6 + set obs `obs6' + replace `orign'=_n + replace `theta'=`rxl' in `obs1' + replace `theta'=`rxl' in `obs3' + gen `ll2' = 0 in `obs1' + gen `ul2' = 0 in `obs3' + + sort `orign' + qui summ `setheta' + local maxse=r(max) + replace `theta' = `rxl'-(1.96*`maxse') in `obs2' + replace `theta' = `rxl'+(1.96*`maxse') in `obs4' + replace `ll2' = `maxse' in `obs2' + replace `ul2' = `maxse' in `obs4' + + gen `vl' = 0 in `obs5' + replace `vl' = `maxse' in `obs6' + replace `theta' = `rxl' in `obs5' + replace `theta' = `rxl' in `obs6' + + label var `ll2' "Lower CI" + label var `ul2' "Lower CI" + label var `vl' "Pooled" + if "`forcenull'"~="" { + label var `vl' "No effect" + } + + } + + * list `setheta' `ll2' `ul2' `vl' `theta' `orign' + * display "RRm: `rxl'" + + local funopt "yscale(`ysca') `subtitle' ytitle("`yti'") xtitle("`xti'")" + + if "`by'"=="" { + local yvar "`setheta'" + local legopt "legend(off)" + } + + if "`by'"~="" { + + qui levels `by', local(bylev) + local lev: word count `bylev' + if `lev'>20 { + di as text "Note: distinct group markers available for only 19 groups" + } + sort `orign' + qui drop if `by'==.&_n<`obs1' + qui count if `by'~=. + if r(N)==0 { + di as error "No observations with nonmissing values of `by'" + exit 999 + } + + forvalues b=1/`lev' { + local bylab "" + local bygroup: word `b' of `bylev' + tempname bg`b' + qui gen `bg`b''=`setheta' if `by'==`bygroup' + local bylab: label (`by') `b' + if "`bylab"=="" { + label variable `bg`b'' "`by'=`b'" + } + if "`bylab"~="" { + label variable `bg`b'' "`bylab'" + } + } + local yvar "`bg1'-`bg`lev''" + + } /* end by processing */ + + if "`nolines'"=="nolines"&"`eform'"=="" { +* display "clause 1" + twoway (scatter `yvar' `theta', `legopt' `msymbol') /// + if `touse', `funopt' `options' + } + + if "`nolines'"==""&"`eform'"=="" { +* display "clause 2" + twoway (scatter `yvar' `theta', `legopt' `msymbol') /// + (line `ll2' `ul2' `vl' `theta', msymbol(none none none) /// + clcolor(black black black) clpat(dash dash solid) /// + clwidth(medium medium medium)) /// + if `touse', `funopt' `options' + } + + if "`eform'"~="" { + gen `etheta'=exp(`theta') + if "`xtitle'"=="" { + local xti : variable label `theta' + if "`xti'" == "" { + local xti "exp(`theta'), log scale" + } + else if "`xti'" ~= "" { + local xti "exp(`xti'), log scale" + } + } + + capture assert "`xsca'"=="" + if _rc~=0 { + display as error "xsca option not permitted" + exit 999 + } + if "`xscale'"~="" { + local chklog=index("`xscale'","log") + if `chklog'==0 { + local xsca "`xscale' log" + } + else if `chklog'~=0 { + local xsca "`xscale'" + } + } + else if "`xscale'"=="" { + local xsca "log" + } + + if "`nolines'"=="nolines" { +* display "clause 3" + + twoway (scatter `yvar' `etheta', `legopt' `msymbol') /// + if `touse', `funopt' xscale(`xsca') `options' + } + + if "`nolines'"=="" { +* display "clause 4" + local rxl=exp(`rxl') + twoway (scatter `yvar' `etheta', `legopt' `msymbol') /// + (line `ll2' `ul2' `vl' `etheta', msymbol(none none none) /// + clcolor(black black black) clpat(dash dash solid) /// + clwidth(medium medium medium)) /// + if `touse', `funopt' xscale(`xsca') `options' + } + } +end + diff --git a/Modules/ado/plus/m/metafunnel.dlg b/Modules/ado/plus/m/metafunnel.dlg new file mode 100644 index 0000000..a6e7912 --- /dev/null +++ b/Modules/ado/plus/m/metafunnel.dlg @@ -0,0 +1,250 @@ +/* +*! metafunnel dialog version 1.0.1, 20 Aug 2003, T. J. Steichen, steichen@triad.rr.com +*! for metafunnel version 1.0.2, 18 Aug 2003, J.A.C. Sterne, Jonathan.Sterne@bristol.ac.uk + +Graphs funnel plot, with standard error on the vertical axis +------------------------------------------------------------ + +Syntax: metafunnel { theta {se|var} | exp(theta) ll ul [cl] } [ if exp ] [ in range ] [, + BY(varname) Var CI + SUbtitle(str) NOLines FORCEnull REVerse EForm + XTitle(string) YTitle(string) XScale(string) + YScale(string) MSymbol(string) * ] + + +Install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "metafunn&el (Funnel Graph, vertical)" "db metafunnel" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. +*/ + +VERSION 8.0 + +INCLUDE _std_medium +INCLUDE header + +HELP hlp1, view("help metafunnel") +RESET res1, label("Reset") + +DIALOG main, label("metafunnel 1.0.2 - Funnel Graph, vertical") tabtitle("Main") +BEGIN + + GROUPBOX gb_data 10 5 390 _ht5h, /// + label("Type of Data:") + RADIO r_se 15 25 100 ., /// + label("Theta, SE") first /// + onclickon(script main_se_on) /// + onclickoff(script main_se_off) /// + option(NONE) + RADIO r_var 115 25 100 ., /// + label("Theta, Var") middle /// + onclickon(script main_var_on) /// + onclickoff(script main_var_off) /// + option("var") + RADIO r_ci 215 25 110 ., /// + label("exp(Theta), CI") last /// + onclickon(script main_ci_on) /// + onclickoff(script main_ci_off) /// + option("ci") + + TEXT tx_se 15 45 380 ., /// + label("Vars for theta, se(theta), in that order") + VARLIST vl_se @ _ss @ ., /// + label("Vars for theta, se(theta)") + + TEXT tx_var @ 45 380 ., /// + label("Vars for theta, var(theta), in that order") + VARLIST vl_var @ _ss @ ., /// + label("Vars for theta, var(theta)") + + TEXT tx_ci @ 45 380 ., /// + label("Vars for exp(theta), CI_LL, CI_UL, in that order") + VARLIST vl_ci @ _ss @ ., /// + label("Vars for exp(theta), CI_LL, CI_UL") + + CHECKBOX cb_by 10 100 100 ., /// + label("By Variable:") /// + onclickon(main.vn_by.enable) /// + onclickoff(main.vn_by.disable) + VARNAME vn_by 110 100 290 ., /// + label("By Variable") /// + option("by") + + CHECKBOX ck_subtitle 10 130 55 ., /// + label("Title:") /// + onclickon(main.ed_subtitle.enable) /// + onclickoff(main.ed_subtitle.disable) + EDIT ed_subtitle 70 @ 330 ., /// + label("Title") /// + option("subtitle") + + CHECKBOX ck_xtitle 10 155 55 ., /// + label("X: title") /// + onclickon(main.ed_xtitle.enable) /// + onclickoff(main.ed_xtitle.disable) + EDIT ed_xtitle 70 @ 160 ., /// + label("X title") /// + option("xtitle") + + CHECKBOX ck_xscale 240 @ 60 ., /// + label("scale") /// + onclickon(main.ed_xscale.enable) /// + onclickoff(main.ed_xscale.disable) + EDIT ed_xscale 300 @ 100 ., /// + label("X scale") /// + option("xscale") + + CHECKBOX ck_ytitle 10 175 55 ., /// + label("Y: title") /// + onclickon(main.ed_ytitle.enable) /// + onclickoff(main.ed_ytitle.disable) + EDIT ed_ytitle 70 @ 160 ., /// + label("Y title") /// + option("ytitle") + + CHECKBOX ck_yscale 240 @ 60 ., /// + label("scale") /// + onclickon(main.ed_yscale.enable) /// + onclickoff(main.ed_yscale.disable) + EDIT ed_yscale 300 @ 100 ., /// + label("Y scale") /// + option("yscale") + + + CHECKBOX ck_reverse 10 200 120 ., /// + label("Reverse y-axis") /// + option("reverse") + + CHECKBOX ck_nolines 10 220 120 ., /// + label("Suppress lines") /// + option("nolines") + + CHECKBOX ck_eform 150 200 120 ., /// + label("Exponential form") /// + option("eform") + + CHECKBOX ck_forcenull 150 220 120 ., /// + label("Force null") /// + option("forcenull") + + + CHECKBOX ck_msymbol 290 200 110 ., /// + label("Marker Symb:") /// + onclickon(main.ed_msymbol.enable) /// + onclickoff(main.ed_msymbol.disable) + EDIT ed_msymbol 290 220 110 ., /// + label("M Symbol") /// + option("msymbol") + + + +END + +INCLUDE ifin + +SCRIPT main_se_on +BEGIN + main.tx_se.show + main.vl_se.show + main.tx_se.enable + main.vl_se.enable + + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide + + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +SCRIPT main_se_off +BEGIN + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide +END + +SCRIPT main_var_on +BEGIN + main.tx_var.show + main.vl_var.show + main.tx_var.enable + main.vl_var.enable + + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide + + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +SCRIPT main_var_off +BEGIN + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide +END + +SCRIPT main_ci_on +BEGIN + main.tx_ci.show + main.vl_ci.show + main.tx_ci.enable + main.vl_ci.enable + + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide + + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide +END + +SCRIPT main_ci_off +BEGIN + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +PROGRAM command +BEGIN + put "metafunnel " + if main.r_se { + varlist main.vl_se + } + if main.r_var { + varlist main.vl_var + } + if main.r_ci { + varlist main.vl_ci + } + INCLUDE _ifin_pr + beginoptions + option radio(main r_se r_var r_ci) + optionarg main.vn_by + optionarg main.ed_subtitle + optionarg main.ed_xtitle + optionarg main.ed_ytitle + optionarg main.ed_xscale + optionarg main.ed_yscale + option main.ck_nolines + option main.ck_forcenull + option main.ck_eform + option main.ck_reverse + optionarg main.ed_msymbol + endoptions +END diff --git a/Modules/ado/plus/m/metafunnel.hlp b/Modules/ado/plus/m/metafunnel.hlp new file mode 100644 index 0000000..c87c5a4 --- /dev/null +++ b/Modules/ado/plus/m/metafunnel.hlp @@ -0,0 +1,167 @@ +{smcl} +{* 19aug2003}{...} +{hline} +help for {hi:metafunnel} {right:dialog: {dialog metafunnel}{space 20}} +{hline} + +{title:Funnel plots for meta-analysis} + +{p 8 15 2} +{cmd:metafunnel} +{it:{ theta { se | var } | exp(theta) ll ul [cl] }} +[{cmd:if} {it:exp}] +[{cmd:in} {it:range}] +[{cmd:,} +{cmdab:ef:orm} +{cmdab:nol:ine} +{cmdab:rev:erse} +{cmdab:forc:enull} +{cmdab:graph_options} +] + + +{title:Description} + +{p 4 4 2} +{cmd:metafunnel} plots funnel plots. These graphical displays are used to +examine whether the results of a meta-analysis may have been affected by +publication or other types of bias. + + +{title:Options} + +{p 4 8 2} +{cmd:by(}{it:byvarname}{cmd:)} displays subgroups according to the value +of {it: byvarname}. The legend +displays the value labels for the levels of {it: byvarname} if these are +present; otherwise it displays the value of each level of{it: byvarname}. + +{p 4 8 2} +{cmd:eform} exponentiates the treatment effect theta and displays the +horizontal axis (treatment effect) on a log scale. This is useful for +displaying ratio measures such as odds ratios and risk ratios. + +{p 4 8 2} +{cmd:reverse} inverts the funnel plot so that larger studies are displayed +at the bottom of the plot with smaller studies at the top. +This may also be achieved by specifying {cmd:noreverse} as part of the +{cmd: yscale(}{it:axis_description}{cmd:)} graphics option. + +{p 4 8 2} +{cmd:noline} specifies that pseudo 95% confidence interval lines +should not be included in the plot. The default is to include them. + +{p 4 8 2} +{cmd:forcenull} forces the vertical line at the centre of the funnel +to be plotted at the null treatment effect of zero (1 when the treatment +effect is exponentiated). The default is for the line to be plotted at +the value of the fixed effect summary estimate. + +{title:Remarks} + +{p 4 4 2} +Funnel plots are simple graphical displays of a measure of study size +on the vertical axis against intervention or treatment effect on the +horizontal axis. The name "funnel plot" is based on the fact that the +precision in the estimation of the underlying intervention or treatment +effect will increase as the size of component studies increases. Results +from small studies will therefore scatter more widely, with the spread +narrowing among larger studies. In the absence of bias the plot will +resemble a symmetrical inverted funnel. + +{p 4 4 2} +If there is bias, for example because smaller studies showing no +statistically significant effects remain unpublished, then such +publication bias will lead to an asymmetrical appearance of the funnel +plot. It should be noted that although funnel plots have traditionally +been used to examine evidence for publication bias, funnel plot asymmetry +may reflect other types of bias, or even result from the true intervention +or treatment effect differing between small and large studies. They should +thus be seen as displaying the evidence for "small study effects" in general +rather than publication bias in particular. These issues are discussed by +Egger {it: et al.} (1997) and Sterne {it:et al.} (2001a). + +{p 4 4 2} +{cmd:metafunnel} uses the same syntax as other meta-analysis commands +such as {help meta}, {help metabias}, {help metainf} and {help metatrim}. +The user provides an estimate of the treatment or intervention effect, +{it: theta}, together with its associated standard error {it: se_theta} +(the default) or variance {it: var_theta}, (in which case the {cmd: var} +option should be specified). Alternatively, the user provides {it:exp(theta)} +(i.e., a risk ratio or odds ratio) and its confidence interval, +{it: (ll, ul)}). + +{p 4 4 2} +The funnel plots are displayed in line with meta-analytic convention and +the recommendations of Sterne et al. (2001b). The effect of the +treatment or intervention in each study (horizontal axis) is plotted +against the study size, as measured by the standard error of the treatment +or intervention effect. +(vertical axis). The vertical axis is reversed so that larger studies are +displayed towards the top of the graph (this behaviour may be changed using +the {cmd: reverse} option). Users who wish to plot the treatment effect on the vertical axis should use the {cmd:graph(begg)} option of +the {help metabias} command. The {help funnel} command, which is part +of the {help metan} package, also provides an alternative way to draw +funnel plots. + +{p 4 4 2} +The plots include pseudo-95% confidence interval lines, which are +drawn around the summary fixed-effect estimate of the intervention or +treatment effect. The lines may be omitted using the {cmd:nolines} option. +The user may also specify that the pseudo confidence limits are centred +around a zero intervention effect using the {cmd:forcenull} option. + +{p 4 4 2} +When the {cmd:eform} option is used, the label of the horizontal axis +(treatment effect, {it:theta}) is +changed accordingly, unless there is a variable label for {cmd: theta} or +the {cmd: xtitle(}{it:axis_title}{cmd:)} graphics option is used. + +{p 4 4 2} +By default, the subtitle "Funnel plot with pseudo 95% confidence limits" +is displayed. This may be changed using the graphics option +{cmd:subtitle(}{it:tinfo}{cmd:)}. + + +{title:Examples} + +{p 4 8 2}{cmd:. metafunnel meandiff semeandiff} + +{p 4 8 2}{cmd:. metafunnel logor selogor, eform xtitle("Odds ratio (log scale)")} + +{p 4 8 2}{cmd:. metafunnel sttd stderr, by(dose) subtitle(Funnel plot with subgroups) forcenull} + +{p 4 8 2}{cmd:. metafunnel logor varlogor, var reverse nolines xtitle(log odds ratio)} + + + +{title:Acknowledgements} + +{p 4 4 2} +{cmd:metafunnel} was written by Jonathan Sterne, University of Bristol. +Portions of the code were originally written by Tom Steichen, who also +gave helpful comments on an early version of the command and provided +the dialog. + + +{title:References} + +{p 4 8 2}Egger, M., Davey Smith, G., Schneider, M., & Minder, C. (1997). +Bias in meta-analysis detected by a simple, graphical test. +{it:British Medical Journal} 315: 629-634 + +{p 4 8 2}Sterne, J.A.C., Egger, M. and Davey Smith, G. (2001a). +Investigating and dealing with publication and other biases +in meta-analysis. {it: British Medical Journal} 323: 101-105 + +{p 4 8 2}Sterne, J.A.C. & Egger, M. (2001b). Funnel plots for detecting +bias in meta-analysis: guidelines on choice of axis. +{it: Journal of Clinical Epidemiology} 54: 1046-1055 + + +{title:Also see} + +{p 4 13 2} +Online: help for {help meta}, {help metabias}, +{help metainf}, {help metatrim}, {help metan}, {help funnel} (if installed) +{p_end} diff --git a/Modules/ado/plus/m/metainf.ado b/Modules/ado/plus/m/metainf.ado new file mode 100644 index 0000000..cf68de0 --- /dev/null +++ b/Modules/ado/plus/m/metainf.ado @@ -0,0 +1,146 @@ +*! metainf.ado AT version 3.0.0 March 2000 (STB-56: sbe26.1) +* metainf.ado AT version 2.0.0 November 1998 +* metainf.ado AT version 1.0.0 February 1998 + +program define metainf + version 6.0 + syntax varlist(min=2 max=2 numeric) [if] [in] [, id(varname) /* + */ random eform t1(str) t2(str) Format(str) print `options' *] + tokenize `varlist' + local E `1' + local SE `2' + preserve + + * Dealing with if and in options + if ("`if'"!="") { + qui keep `if' + } + if ("`in'"!="") { + qui keep `in' + } + + * Overall estimates + qui meta `E' `SE', `eform' + if "`random'"=="random" { + local ove=$S_7 + local ll=$S_9 + * Global macro should be updated if meta change it name + local ul=$S_0 + } + else { + local ove=$S_1 + local ll=$S_3 + local ul=$S_4 + } + + * Meta-analysis estimate ommiting one study each step + tempvar theta setheta ulth llth + qui sum `E', detail + local n=_result(1) + qui { + gen `theta'=. + gen `setheta'=. + gen `ulth'=. + gen `llth'=. + } + local i=1 + tempvar s + qui gen `s'=_n + while (`i'<=`n') { + qui { + meta `E' `SE' if `s'!=`i', `eform' + if "`random'"=="random" { + replace `theta'=$S_7 in `i' + replace `llth'=$S_9 in `i' + replace `ulth'=$S_0 in `i' + } + else { + replace `theta'=$S_1 in `i' + replace `llth'=$S_3 in `i' + replace `ulth'=$S_4 in `i' + } + } + local i=`i'+1 + } + + * Maximum and minimum CI values + qui sum `llth', detail + local mnx=r(min) + qui sum `ulth', detail + local mxx=r(max) + + * Labeling plot + if "`t2'" == "" { + local t2 "Study ommited" + } + if "`t1'" == "" { + if "`eform'"=="eform" & "`random'"=="" { + local t1 "Meta-analysis fixed-effects estimates (exponential form)" + } + if "`eform'"=="" & "`random'"=="" { + local t1 "Meta-analysis fixed-effects estimates (linear form)" + } + if "`eform'"=="eform" & "`random'"=="random" { + local t1 "Meta-analysis random-effects estimates (exponential form)" + } + if "`eform'"=="" & "`random'"=="random" { + local t1 "Meta-analysis random-effects estimates (linear form)" + } + } + + * Numeric format + if "`format'" == "" { + local format "%5.2f" + } + + * Print option + if "`print'"=="print" & "`eform'"=="" { + dis + dis in gre "`lab'" + dis in gr "------------------------------------------------------------------------------" + dis in gr _col(2) "Study ommited" _col(20) "|" _col(24) "Coef." _col(39) "[95% Conf. Interval]" + dis in gr "-------------------+----------------------------------------------------------" + local i=1 + while `i'<=`n' { + if "`id'"=="" { local a=`s' in `i' } + else { local a=`id' in `i'} + local b=`theta' in `i' + local c=`llth' in `i' + local d=`ulth' in `i' + display _col(2) "`a'" _col(20) in gr "|" in ye _col(24) `b' _col(39) `c' _col(52) `d' + local i=`i'+1 + } + dis in gr "-------------------+----------------------------------------------------------" + dis _col(2) "Combined" _col(20) in gr "|" in ye _col(24) `ove' _col(39) `ll' _col(52) `ul' + dis in gr "------------------------------------------------------------------------------" + } + else if "`print'"=="print" & "`eform'"=="eform" { + dis + dis in gre "`lab'" + dis in gr "------------------------------------------------------------------------------" + dis in gr _col(2) "Study ommited" _col(20) "|" _col(24) "e^coef." _col(39) "[95% Conf. Interval]" + dis in gr "-------------------+----------------------------------------------------------" + local i=1 + while `i'<=`n' { + if "`id'"=="" { + local a=`s' in `i' + } + else { + local a=`id' in `i' + } + local b=`theta' in `i' + local c=`llth' in `i' + local d=`ulth' in `i' + display _col(2) "`a'" _col(20) in gr "|" in ye _col(24) `b' _col(39) `c' _col(52) `d' + local i=`i'+1 + } + dis in gr "-------------------+----------------------------------------------------------" + display _col(2) "Combined" _col(20) in gr "|" in ye _col(24) `ove' _col(39) `ll' _col(52) `ul' + dis in gr "------------------------------------------------------------------------------" + } + + * Displaying plot + hplot `theta' `llth' `ulth', r sy(o||) l("`id'") t1(`t1') t2(`t2') f(`format') /* + */ xline(`ove',`ll',`ul') xlab(`mnx',`ove',`ll',`ul',`mxx') xti(`ove',`ll',`ul') /* + */ xscale(`mnx',`mxx') +end diff --git a/Modules/ado/plus/m/metainf.dlg b/Modules/ado/plus/m/metainf.dlg new file mode 100644 index 0000000..b2b2d84 --- /dev/null +++ b/Modules/ado/plus/m/metainf.dlg @@ -0,0 +1,79 @@ +/* + +*! metainf dialog version 1.0.0, 13 May 2003, T. J. Steichen, steichen@triad.rr.com +*! for metainf version 3.0.0, Mar 2000, Aurelio Tobias, atobias@isciii.es + +Influence of a single study in meta-analysis estimation +------------------------------------------------------- + +Syntax: metainf theta setheta [if exp] [in range] + [, id(labvar) eform random print graph_options] + + +To install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "Meta-based Influence Analysis (metain&f)" "db metainf" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. +*/ + +VERSION 8.0 + +INCLUDE _std_small +INCLUDE header + +HELP hlp1, view("help metainf") +RESET res1, label("Reset") + +DIALOG main, label("metainf 3.0.0 - Meta-based Influence Analysis") tabtitle("Main") +BEGIN + TEXT tx_effect 10 5 330 ., /// + label("Vars for Effect Sizes: theta, se(theta), in that order") + VARLIST vl_effect @ _ss @ ., /// + label("Effect Sizes: theta, se(theta)") + + CHECKBOX cb_id 10 60 40 ., /// + label("ID:") /// + onclickon(main.vn_id.enable) /// + onclickoff(main.vn_id.disable) + VARNAME vn_id 50 60 290 ., /// + label("ID Variable") /// + option("id") + + GROUPBOX gb_pool 10 85 195 _ht3h, /// + label("Pooling Model") + RADIO r_fixed 15 100 185 ., /// + label("Fixed, Inverse Variance") first /// + option("fixed") + RADIO r_random @ 125 @ ., /// + label("Random, Inverse Variance") last /// + option("random") + + CHECKBOX cb_eform 230 95 200 ., /// + label("Use exp(theta)") /// + option("eform") + CHECKBOX cb_print 230 125 200 ., /// + label("Print Details") /// + option("print") + + GROUPBOX gb_hpopts 10 155 330 _ht1h, /// + label("Allowed hplot Options:") + EDIT ed_hpopts 15 175 320 ., /// + label("hplot Options") +END + +INCLUDE ifin + + +PROGRAM command +BEGIN + put "metainf " + varlist main.vl_effect + INCLUDE _ifin_pr + beginoptions + option radio(main r_fixed r_random) + optionarg main.vn_id + option main.cb_eform + option main.cb_print + put main.ed_hpopts + endoptions +END diff --git a/Modules/ado/plus/m/metainf.hlp b/Modules/ado/plus/m/metainf.hlp new file mode 100644 index 0000000..3e7a765 --- /dev/null +++ b/Modules/ado/plus/m/metainf.hlp @@ -0,0 +1,96 @@ +.- +help for ^metainf^ (STB-47: sbe26; STB-56: sbe26.1) +.- + +Influence of a single study in the meta-analysis estimates +---------------------------------------------------------- + + ^metainf^ theta setheta [^if^ exp] [^in^ range] [,^id(^labvar^)^ ^eform^ ^random^ + ^print^ graph_options] + + +Description +----------- + +^metainf^ investigate the influence of a single study on the overall meta- +analysis estimate. This command shows graphically the results of an influence +analysis, in which the meta-analysis estimates are computed omitting one study +in each turn. + +^theta^ is the effect estimated from the individual study, and ^setheta^ is its +standard error. For example theta might be a difference in means, a log rate +ratio, a log odds ratio, or a log hazard ratio. + +If you have a dataset which contains data for all studies, then the @byvar@ +command can be used to derive the effect estimates and standard errors for the +individual studies. For example: + + . ^sort study^ + . ^byvar study, coef(group) se(group) generate:^ + . ^quietly poisson cases group, e(pyrs)^ + . ^sort study^ + . ^qui by study: keep if _n==1^ + . ^rename _C_1 logrr^ + . ^rename _S_1 logse^ + . ^metainf logrr logse, id(study)^ + +Alternatively, the @collapse@ command may be useful. + + +Options +------- + +^id(^labvar^)^ is a variable which is used to label the studies. + +^eform^ requests that the output is exponentiated. + +^random^ request random-effects estimates. By default fixed-effects estimates +are computed. + +^print^ shows the estimates, and their 95% confidence interval, of the meta- +analysis estimates omitting one study in each turn. These values are used to +make the graphic. + +All ^hplot^ options are also available. + + +Note +---- + +To run the ^metainf^ command, the ^meta^ [STB-43 sbe16.2, STB-42 sbe16.1, +STB-38 sbe16] and the ^hplot^ (Cox 1999a, 1999b) command must be installed. + + +Examples +-------- + + . ^metainf logrr logse, print id(studyid)^ + . ^metainf logrr logse, random print id(studyid)^ + . ^metainf logrr logse, random eform id(studyid) format(%4.2f)^ + + +References +---------- + + Cox NJ (1999a). -hplot- and -hbar- for presentation graphics. Proceedings + of the 5th Stata UK user group meeting, London, UK. + + Cox NJ (1999b). De tablas a gráficos, presentaciones en Stata. Proceedings + of the 1st Iberian user group meeting, Cordoba, Spain. + + +Author +------ + + Aurelio Tobias + Universidad Miguel Hernandez, Alicante, Spain + email: bledatobias@@ctv.es + + +Also see +-------- + +On-line: help for @byvar@, @collapse@, @for@, @meta@ (if installed), @metareg@ (if + installed), @metabias@ (if installed), @metacum@ (if installed), @galbr@ + (if installed), metap (if installed), @hplot@ (if installed) + diff --git a/Modules/ado/plus/m/metan.ado b/Modules/ado/plus/m/metan.ado new file mode 100644 index 0000000..7b48c72 --- /dev/null +++ b/Modules/ado/plus/m/metan.ado @@ -0,0 +1,4454 @@ +*! 3.02 13Nov2008 +* 13 Nov 2008- fixed counts option, was using str20 and truncating in `rawdata' +* decimal place option dp() +* Based on 2.34 11May2007 +* Based on previous version: 1.86 1Apr2004 +* + +/*Revision list at end + +Syntax: +a) binary data: + metan #events_group1 #nonevents_group1 #events_group2 #nonevents_group2 , ... +b) cts data: + metan #group1 mean1 sd1 #group2 mean2 sd2 , ... +c) generic effect size+st error: + metan theta se_theta , ... +d) generic effect size+ci: + metan theta lowerlimit upperlimit , ... + +*/ + +program define metan, rclass + +version 9.0 +#delimit ; +syntax varlist(min=2 max=6 default=none numeric) [if] [in] [, BY(string) + ILevel(integer $S_level) OLevel(integer $S_level) CC(string) + OR RR RD FIXED FIXEDI RANDOM RANDOMI PETO COHEN HEDGES GLASS noSTANDARD + CHI2 CORNFIELD LOG BRESLOW EFORM noINTeger noOVERALL noSUBGROUP SGWEIGHT + SORTBY(passthru) noKEEP noGRAPH noTABLE LABEL(string) noBOX + XLAbel(passthru) XTick(passthru) FORCE BOXSCA(real 100.0) BOXSHA(integer 4) + TEXTSize(real 100.0) noWT noSTATS COUNTS WGT(varlist numeric max=1) + GROUP1(string) GROUP2(string) EFFECT(string) + /* new additions */ + LCOLS(varlist) RCOLS(varlist) ASTEXT(integer 50) DOUBLE NOHET NULL(real 999) RFDIST SUMMARYONLY + SECOND(string) NOSECSUB SECONDSTATS(string) FAVOURS(string) FIRST(string) FIRSTSTATS(string) + BOXOPT(string) DIAMOPT(string) POINTOPT(string) CIOPT(string) OLINEOPT(string) + CLASSIC NOWARNING NULLOFF EFFICACY RFLevel(integer $S_level) DP(integer 2) + * ]; + +#delimit cr + + +global MA_OTHEROPTS `"`options'"' +global MA_BOXOPT `"`boxopt'"' +global MA_DIAMOPT `"`diamopt'"' +global MA_POINTOPT `"`pointopt'"' +global MA_CIOPT `"`ciopt'"' +global MA_OLINEOPT `"`olineopt'"' + +global MA_DOUBLE "`double'" +global MA_FAVOURS "`favours'" +global MA_secondstats "`secondstats'" +global MA_firststats "`firststats'" +global MA_nohet "`nohet'" +global MA_rfdist "`rfdist'" +global MA_summaryonly "`summaryonly'" +global MA_classic "`classic'" +global MA_nowarning "`nowarning'" +global MA_nulloff "`nulloff'" +global MA_efficacy "`efficacy'" +global MA_dp = "`dp'" + +if `null' != 999{ + global MA_NULL = "`null'" +} +else{ + global MA_NULL = "" +} + +global MA_FBSC `boxsca' +global MA_ESLA "`effect'" +global MA_params = 0 // set as appropriate in variable set-up + +if "`legend'"!="" { + global S_TX "`legend'" +} +else { + global S_TX "Study" +} + +global MA_AS_TEXT `astext' // new option- percentage of graph as text +global MA_TEXT_SCA `textsize' // oops, that was in already + +if `astext' > 90 | `astext' < 10 { + di as error "Percentage of graph as text (ASTEXT) must be within 10-90%" + di as error "Must have some space for text and graph" + exit +} +if `textsize' < 20 | `textsize' > 500 { + di as error "Text scale (TEXTSize) must be within 20-500" + di as error "Value is character size relative to graph" + di as error "Outside range will either be unreadable or too large" + exit +} + +*label groups +if "`group1'"=="" { + global MA_G1L "Treatment" +} +else { + global MA_G1L "`group1'" +} +if "`group2'"=="" { + global MA_G2L "Control" +} +else { + global MA_G2L "`group2'" +} +if "`legend'"!="" { + global S_TX "`legend'" +} + +global MA_FTSI `textsize' +if ("`by'"=="" & "`overall'"!="") { + local wt "nowt" +} +if `ilevel'<1 { + local ilevel `ilevel'*100 +} +if `ilevel'>99 | `ilevel'<10 { + local ilevel $S_level +} + +global ZIND -invnorm((100-`ilevel')/200) + +if `olevel'<1 { + local olevel `olevel'*100 +} +if `olevel'>99 | `olevel'<10 { + local olevel $S_level +} + +global ZOVE -invnorm((100-`olevel')/200) +global IND `ilevel' +global OVE `olevel' + +if `rflevel'<1 { + local rflevel `rflevel'*100 +} +if `rflevel'>99 | `olevel'<10 { + local rflevel $S_level +} +global RFL `rflevel' + +forvalues i = 1/12{ + global S_`i' . +} +global MA_rjhby "`by'" + +*If not using own weights set fixed as default + +if "`fixed'`random'`fixedi'`randomi'`peto'"=="" & ( "`wgt'"=="" ) { + local fixed "fixed" +} + +*declare study labels for display +if "`label'"!="" { + tokenize "`label'", parse("=,") + while "`1'"!="" { + cap confirm var `3' + if _rc!=0 { + di as err "Variable `3' not defined" + exit + } + local `1' "`3'" + mac shift 4 + } +} + +tempvar code + +qui { +*put name/year variables into appropriate macros + +if "`namevar'"!="" { + local lbnvl : value label `namevar' + if "`lbnvl'"!="" { + quietly decode `namevar', gen(`code') + } + else { + gen str10 `code'="" + cap confirm string variable `namevar' + if _rc==0 { + replace `code'=`namevar' + } + else if _rc==7 { + replace `code'=string(`namevar') + } + } +} +if "`namevar'"=="" & "`lcols'" != ""{ + local var1 = word("`lcols'",1) + cap confirm var `var1' + if _rc!=0 { + di in re "Variable `var1' not defined" + exit _rc + } + local namevar "`var1'" + local lbnvl : value label `namevar' + if "`lbnvl'"!="" { + quietly decode `namevar', gen(`code') + } + else { + gen str10 `code'="" + cap confirm string variable `namevar' + if _rc==0 { + replace `code'=`namevar' + } + else if _rc==7 { + replace `code'=string(`namevar') + } + } +} +if "`namevar'"=="" & "`lcols'" == ""{ + gen str3 `code'=string(_n) +} + +if "`yearvar'"!="" { + local yearvar "`yearvar'" + cap confirm string variable `yearvar' + if _rc==7 { + local str "string" + } + if "`namevar'"=="" { + replace `code'=`str'(`yearvar') + } + else { + replace `code'=`code'+" ("+`str'(`yearvar')+")" + } +} + +if "`wgt'"!="" { +*User defined weights verification + if "`fixed'`random'`fixedi'`randomi'`peto'"!="" { + di as err "Option invalid with user-defined weights" + exit + } + confirm numeric variable `wgt' + local wgt "wgt(`wgt')" +} + +} /* End of quietly loop */ + + +tokenize "`varlist'", parse(" ") + +if "`6'"=="" { + + if "`4'"=="" { + + *Input is {theta setheta} or {theta lowerci upperci} => UDW, IV or D+L weighting + if "`3'"!="" { + *input is theta lci uci + cap assert ((`3'>=`1') & (`1'>=`2')) + if _rc!=0 { + di in bl "Effect size and confidence intervals invalid:" + di in bl "order should be {effect size, lower ci limit, upper ci limit}" + exit _rc + } + global MA_params = 3 + } + else{ + global MA_params = 2 + } + + cap assert "`log'"=="" + if _rc!=0 { + di in bl "Log option not available without raw data counts: if necessary, transform both" + di in bl "effect and standard error using " in wh "generate" in bl " and re-issue the metan command" + exit _rc + } + + cap assert "`chi2'`cornfield'`peto'`breslow'`counts'`or'`rr'`rd'`standard'`hedges'`glass'`cohen'"=="" + if _rc!=0 { + di as err "Option not available without raw data counts" + exit _rc + } + if "`wgt'"!="" { + local method "*" + } + else { + if "`random'`randomi'"!="" { + local randomi + local random "random" + local method "D+L" + } + if "`fixed'`fixedi'"!="" { + local fixedi + local fixed "fixed" + local method "I-V" + } + cap assert ("`random'"=="") + ("`fixed'"=="")==1 + if _rc!=0 { + di as err "Specify fixed or random effect/s model" + exit _rc + } + } + + cap assert "`cc'"=="" + if _rc!=0 { + di as err "Continuity correction not valid with unless individual counts specified" + exit _rc + } + + local callalg "iv_init" + local sumstat "ES" + +} /*end of 2&3-variable set-up */ + + if "`4'"!="" { + *Input is 2x2 tables: MH, Peto, IV, D+L or user defined weighting allowed + cap assert "`5'"=="" + if _rc!=0 { + di as err "Wrong number of variables specified" + exit _rc + } + if "`integer'"=="" { + cap { + assert int(`1')==`1' + assert int(`2')==`2' + assert int(`3')==`3' + assert int(`4')==`4' + } + if _rc!=0 { + di as err "Non integer cell counts found" + exit _rc + } + + } + cap assert ( (`1'>=0) & (`2'>=0) & (`3'>=0) & (`4'>=0) ) + if _rc!=0 { + di as err "Non-positive cell counts found" + exit _rc + } + if "`cc'"!="" { + *Ensure Continuity correction is valid + if "`peto'"!="" { + di as err "Peto method not valid with continuity correction" + exit + } + *Currently, allows user to define own constant [0,1) to add to all cells + cap confirm number `cc' + if _rc!=0 { + di as err "Invalid continuity correction: specify a constant number eg metan ... , cc(0.166667)" + exit + } + cap assert (`cc'>=0) & (`cc'<1) + if _rc!=0 { + di as err "Invalid continuity correction: must be in range [0,1)" + exit + } + } + else { + local cc "0.5" + } + if "`peto'"=="" { + local cont "cc(`cc')" + } + if "`peto'"!="" { + local or "or" + } + capture { + assert ( ("`or'"!="")+("`rr'"!="")+("`rd'"!="") <=1 ) + assert ("`fixed'"!="")+("`fixedi'"!="")+("`random'"!="")+ /* + */ ("`randomi'"!="")+("`peto'"!="")+("`wgt'"!="") <=1 + assert "`standard'`hedges'`glass'`cohen'"=="" + } + if _rc!=0 { + di as err "Invalid specifications for combining trials" + exit + } + *Default is set at pooling RRs. + if "`or'"!="" { + local sumstat "OR" + } + else if "`rd'"!="" { + local sumstat "RD" + } + else { + local sumstat "RR" + } + if "`wgt'"!="" { + local method "*" + } + else if "`random'`randomi'"!="" { + local method "D+L" + } + else if "`peto'"!="" { + local method "Peto" + } + else if "`fixedi'"!="" { + local method "I-V" + } + else { + local method "M-H" + } + if "`peto'"!="" { + local callalg "Peto" + } + else { + local callalg "`sumstat'" + } + if ("`sumstat'"!="OR" | "`method'"=="D+L") & "`chi2'"!="" { + di as err "Chi-squared option invalid for `method' `sumstat'" + exit + } + if ("`sumstat'"!="OR" | "`method'"=="D+L" | "`method'"=="Peto" ) & "`breslow'"!="" { + di as err "Breslow-Day heterogeneity option not available for `method' `sumstat'" + exit + } + if ("`sumstat'"!="OR" & "`sumstat'"!="RR") & "`log'"!="" { + di as err "Log option not appropriate for `sumstat'" + exit + } + if "`keep'"=="" { + cap drop _SS + qui gen _SS =`1'+`2'+`3'+`4' + } + + global MA_params = 4 + + } /* end of binary variable setup */ + +} /* end of all non-6 variable set up */ + + +if "`6'"!="" { + + *Input is form N mean SD for continuous data: IV, D+L or user defined weighting allowed + cap assert "`7'"=="" + if _rc!=0 { + di as err "Wrong number of variables specified" + exit _rc + } + if "`integer'"=="" { + cap assert ((int(`1')==`1') & (int(`4')==`4')) + if _rc!=0 { + di as err "Non integer sample sizes found" + exit _rc + } + } + cap assert (`1'>0 & `4'>0) + if _rc!=0 { + di as err "Non positive sample sizes found" + exit _rc + } + if "`random'`randomi'"!="" { + local randomi + local random "random" + } + if "`fixed'`fixedi'"!="" { + local fixedi + local fixed "fixed" + } + cap{ + assert ("`hedges'"!="")+ ("`glass'"!="")+ ("`cohen'"!="")+ ("`standard'"!="")<=1 + assert ("`random'"!="")+ ("`fixed'"!="") <=1 + assert "`or'`rr'`rd'`peto'`log'`cornfield'`chi2'`breslow'`eform'"=="" + } + if _rc!=0 { + di as err "Invalid specifications for combining trials" + exit + } + if "`standard'"!="" { + local sumstat "WMD" + local stand "none" + } + else { + if "`hedges'"!="" { + local stand "hedges" + } + else if "`glass'"!="" { + local stand "glass" + } + else { + local stand "cohen" + } + local sumstat "SMD" + } + local stand "standard(`stand')" + if "`wgt'"!="" { + local method "*" + } + else if "`random'"!="" { + local method "D+L" + } + else { + local method "I-V" + } + /* CAN NOW HAVE THIS + if "`counts'"!="" { + di in bl "Data option counts not available with continuous data" + local counts + } + */ + if "`cc'"!="" { + di as err "Continuity correction not available with continuous data" + exit + } + local callalg "MD" + if "`keep'"=="" { + cap drop _SS + qui gen _SS =`1'+`4' + } + global MA_params = 6 + +} /*end of 6-var set-up*/ + + +if "`by'"!="" { + cap confirm var `by' + if _rc!=0 { + di in red "Variable `by' does not exist" + exit _rc + } + local by "by(`by')" + local nextcall "nextcall(`callalg')" + local callalg "metanby" + local sstat "sumstat(`sumstat')" +} + +if "$MA_efficacy" != ""{ + cap assert "`sumstat'" == "RR" | "`sumstat'" == "OR" + if _rc!=0 { + di in red "Efficacy statistics only possible with odds ratios and risk ratios" + exit _rc + } +} + +// RJH- code for second effect estimate +global MA_method1 "" +global MA_method2 "" // MAKE BLANK OR MAY BE KEPT FROM PREV + + +// CODE AND CONDITIONS FOR USER DEFINED "FIRST" ANALYSIS +// FIRST DITCH ANY MACROS WE DON'T WANT + +foreach globule in MA_userES MA_userCIlow MA_userCIupp MA_userDesc MA_userESM /// + MA_userCIlowM MA_userCIuppM MA_userDescM MA_ODC { + global `globule' = . +} + +if "`first'" != ""{ + cap assert real(word("`first'",1)) != . & real(word("`first'",2)) != . /// + & real(word("`first'",3)) != . + if _rc != 0{ + di as err "Must supply estimate with confidence intervals: ES CIlow CIupp" + di as err "with user-defined main analysis" + exit + } + cap assert "`wgt'" != "" + if _rc != 0{ + di as err "Must supply weight variable with option WGT(varname)" + di as err "with user-defined main analysis" + exit + } + cap assert "`by'"=="" + if _rc != 0{ + di as err "Cannot use option BY() with user-defined main analysis" + exit + } + cap assert $MA_params == 2 | $MA_params == 3 + if _rc != 0{ + di as err "Variable input must be 2 or 3 parameters, i.e., + di as err "{theta se_theta} or {ES CIupp CIlow}" + di as err "with user-defined main analysis" + exit + } + + global MA_userESM = real(word("`first'",1)) + global MA_userCIlowM = real(word("`first'",2)) + global MA_userCIuppM = real(word("`first'",3)) + if "`eform'" != ""{ + foreach glob in MA_userESM MA_userCIlowM MA_userCIuppM{ + global `glob' = exp($`glob') + } + } + if $MA_userESM < $MA_userCIlowM | $MA_userESM > $MA_userCIuppM{ + di as err "Must supply estimate with confidence interval in the order: ES CIlow CIupp" + exit + } + global MA_userDescM = substr("`first'", (strpos("`first'",word("`first'",4))), /// + (length("`first'")-strpos("`first'",word("`first'",4))+1) ) + if word("`first'",4) == "" { + global MA_userDescM = "USER DEFN" + } + local method "USER" + +} + + +if "`second'" != ""{ + + // METHODS + // RANDOM- D+L + // FIXED- M-H only available with cell counts + // RANDOMI- D+L + // FIXEDI- I-V + + if "`second'" == "random" | "`second'" == "randomi" { + local method_2 "D+L" + } + else if "`second'" == "fixed" & "`4'" != "" & "`6'" == ""{ + local method_2 "M-H" + } + else if "`second'" == "peto" & "`4'" != "" & "`6'" == ""{ + local method_2 "Peto" + } + else if "`second'" == "fixedi" | ( ("`4'" == "" | "`6'" != "") & "`second'" == "fixed" ) /// + | ( ("`4'" == "" | "`6'" != "") & "`second'" == "peto" ){ + local method_2 "I-V" + } + else{ + cap assert real(word("`second'",1)) != . & real(word("`second'",2)) != . /// + & real(word("`second'",3)) != . + if _rc != 0{ + di as err "Choose appropriate method for second analysis, or supply user-" + di as err "defined estimate with confidence intervals: ES CIlow CIupp" + exit + } + global MA_userES = real(word("`second'",1)) + global MA_userCIlow = real(word("`second'",2)) + global MA_userCIupp = real(word("`second'",3)) + if "`eform'" != ""{ + foreach glob in MA_userES MA_userCIlow MA_userCIupp{ + global `glob' = exp($`glob') + } + } + if $MA_userES < $MA_userCIlow | $MA_userES > $MA_userCIupp{ + di as err "Must supply estimate with confidence interval in the order: ES CIlow CIupp" + } + global MA_userDesc = substr("`second'", (strpos("`second'",word("`second'",4))), /// + (length("`second'")-strpos("`second'",word("`second'",4))+1) ) + if word("`second'",4) == ""{ + global MA_userDesc = "USER DEFN" + } + local nosecsub "nosecsub" + local method_2 "USER" + } +} + +if "`method'" == "USER" & "`method_2'" != "USER" & "`method_2'" != ""{ + di as err "Cannot have user defined analysis as main analysis and standard analysis + di as err "as second analysis. You can do it the other way round, or have two user" + di as err "defined analyses, but you can't do this particular thing." + di as err "Sorry, that's just the way it is." + exit +} + +global MA_method1 "`method'" +global MA_method2 "`method_2'" +global MA_SECOND_ES . +global MA_SECOND_LCI . +global MA_SECOND_UCI . +global MA_SECOND_SE_ES . +global MA_SECOND_TAU2 . +global MA_first_TAU2 . +global MA_SECOND_DF . +global MA_first_DF . + +if "`second'" != ""{ + if "`callalg'" != "metanby"{ // just run through twice + + `callalg' `varlist' `if' `in', `by' label(`code') `keep' /* + */ method(`method_2') `randomi' `cont' `stand' `chi2' `cornfield' /* + */ `log' `breslow' `eform' `wgt' `overall' `subgroup' `sgweight' /* + */ `sortby' `saving' `xlabel' `xtick' `force' `wt' `stats' `counts' `box' /* + */ t1(".`t1title'") t2(".`t2title'") b1(".`b1title'") b2(".`b2title'") lcols("`lcols'") rcols("`rcols'") /* + */ `groupla' `nextcall' `sstat' notable nograph rjhsecond + + global MA_second_ES = $S_1 // IF NO BY JUST KEEP ESTIMATES AND STICK IN SOMEWHERE LATER + global MA_second_SE_ES = $S_2 + global MA_second_LCI = $S_3 + global MA_second_UCI = $S_4 + global MA_second_TAU2 = $S_12 + global MA_second_DF = $S_8 + + `callalg' `varlist' `if' `in', `by' label(`code') `keep' `table' `graph' /* + */ method(`method') `randomi' `cont' `stand' `chi2' `cornfield' /* + */ `log' `breslow' `eform' `wgt' `overall' `subgroup' `sgweight' /* + */ `sortby' `saving' `xlabel' `xtick' `force' `wt' `stats' `counts' `box' /* + */ t1(".`t1title'") t2(".`t2title'") b1(".`b1title'") b2(".`b2title'") lcols("`lcols'") rcols("`rcols'") /* + */ `groupla' `nextcall' `sstat' + + } + + if "`callalg'" == "metanby"{ // if by, then send to metanby and sort out there + + `callalg' `varlist' `if' `in', `by' label(`code') `keep' `table' `graph' /* + */ method(`method') method2(`method_2') `randomi' `cont' `stand' `chi2' `cornfield' /* + */ `log' `breslow' `eform' `wgt' `overall' `subgroup' `sgweight' /* + */ `sortby' `saving' `xlabel' `xtick' `force' `wt' `stats' `counts' `box' /* + */ t1(".`t1title'") t2(".`t2title'") b1(".`b1title'") b2(".`b2title'") lcols("`lcols'") rcols("`rcols'") /* + */ `groupla' `nextcall' `sstat' `nosecsub' + } + +} + +if "`second'" == ""{ + + if "`callalg'" != "metanby"{ + `callalg' `varlist' `if' `in', `by' label(`code') `keep' `table' `graph' /* + */ method(`method') `randomi' `cont' `stand' `chi2' `cornfield' /* + */ `log' `breslow' `eform' `wgt' `overall' `subgroup' `sgweight' /* + */ `sortby' `saving' `xlabel' `xtick' `force' `wt' `stats' `counts' `box' /* + */ t1(".`t1title'") t2(".`t2title'") b1(".`b1title'") b2(".`b2title'") lcols("`lcols'") rcols("`rcols'") /* + */ `groupla' `nextcall' `sstat' + + } + if "`callalg'" == "metanby"{ + `callalg' `varlist' `if' `in', `by' label(`code') `keep' `table' `graph' /* + */ method(`method') `randomi' `cont' `stand' `chi2' `cornfield' /* + */ `log' `breslow' `eform' `wgt' `overall' `subgroup' `sgweight' /* + */ `sortby' `saving' `xlabel' `xtick' `force' `wt' `stats' `counts' `box' /* + */ t1(".`t1title'") t2(".`t2title'") b1(".`b1title'") b2(".`b2title'") lcols("`lcols'") rcols("`rcols'") /* + */ `groupla' `nextcall' `sstat' + } + +} + +if $S_8<0 { + di as err "Insufficient data to perform this meta-analysis" +} + +*return log or eform as appropriate for OR/RR + +return scalar ES=$S_1 +if "$MA_method2" != ""{ + return scalar ES_2=$MA_second_ES + return local method_1 "$MA_method1" + return local method_2 "$MA_method2" +} + +if ("`sumstat'"=="OR" | "`sumstat'"=="RR") & ("`log'"=="") { + return scalar selogES=$S_2 + if "$MA_method2" != ""{ + return scalar selogES_2=$MA_second_SE_ES + } +} + +else if ("`sumstat'"=="ES" & "`eform'"!="") { + return scalar selogES=$S_2 + if "$MA_method2" != ""{ + return scalar selogES_2=$MA_second_SE_ES + } +} + +else { + return scalar seES=$S_2 + if "$MA_method2" != ""{ + return scalar seES_2=$MA_second_SE_ES + } +} + +return scalar ci_low=$S_3 +return scalar ci_upp=$S_4 +if "$MA_method2" != ""{ + return scalar ci_low_2=$MA_second_LCI + return scalar ci_upp_2=$MA_second_UCI +} +return scalar z=$S_5 +return scalar p_z=$S_6 +return scalar i_sq=$S_51 // ADDED I2 IN RETURN +return scalar het=$S_7 +return scalar df=$S_8 +return scalar p_het=$S_9 +return scalar chi2=$S_10 +return scalar p_chi2=$S_11 +return scalar tau2=$S_12 +return local measure "`log'`sumstat'" +if ("`sumstat'"=="RR" | "`sumstat'"=="OR" | "`sumstat'"=="RD") { + return scalar tger=$S_13 + return scalar cger=$S_14 +} + +end + + + + +program define OR + +version 9.0 +#delimit ; +syntax varlist(min=4 max=4 default=none numeric) [if] [in] [, + LABEL(string) SORTBY(passthru) noGRAPH noTABLE CHI2 RANDOMI CC(string) + METHOD(string) XLAbel(passthru) XTICK(passthru) FORCE CORNFIELD noKEEP + SAVING(passthru) noBOX T1(string) T2(string) B1(string) B2(string) LCOLS(string) RCOLS(string) + noOVERALL noWT noSTATS LOG BRESLOW COUNTS WGT(varlist numeric max=1) noGROUPLA RJHSECOND] ; + +#delimit cr + +qui { + +tempvar a b c d use zeros r1 r2 c1 c2 t or lnor es v se ill iul ea /* + */ va weight qhet id rawdata cont_a cont_b cont_c cont_d +tempname ernum erden R S PR PS QR QS W OR lnOR selnOR A EA VA +tokenize "`varlist'", parse(" ") +if "`log'"!="" { + local exp +} +else { + local exp "exp" +} +gen double `a' =`1' +gen double `b' =`2' +gen double `c' =`3' +gen double `d' =`4' +gen double `r1'=`a'+`b' +gen double `r2'=`c'+`d' +gen double `c1'=`a'+`c' +gen double `c2'=`b'+`d' +gen byte `use'=1 `if' `in' +replace `use'=9 if `use'==. +replace `use'=9 if (`r1'==.) | (`r2'==.) +replace `use'=2 if (`use'==1) & (`r1'==0 | `r2'==0 ) +replace `use'=2 if (`use'==1) & (`c1'==0 | `c2'==0 ) +count if `use'==1 +global S_8 =r(N)-1 +if $S_8<0 { + exit +} +if "`counts'"!="" { + *Display raw counts + gen str `rawdata'= string(`a') + "/" + string(`r1') +";" + /* + */ string(`c') + "/"+ string(`r2') if `use'!=9 + replace `rawdata'= trim(`rawdata') + if "`overall'"=="" { + sum `a' if (`use'==1 | `use'==2) + local sum1 = r(sum) + sum `r1' if (`use'==1 | `use'==2) + local sum2 = r(sum) + sum `c' if (`use'==1 | `use'==2) + local sum3 = r(sum) + sum `r2' if (`use'==1 | `use'==2) + local sum4 =r(sum) + global MA_ODC "`sum1'/`sum2';`sum3'/`sum4'" + } +} +else { + gen str1 `rawdata'="." +} + +if "`method'"=="D+L" & ($S_8==0) { + local method "M-H" +} + +*Get average event rate for each group (before any 0.5 adjustments or excluding 0-0 studies) +sum `a' if `use'<3 +scalar `ernum'=r(sum) +sum `r1' if `use'<3 +scalar `erden'=r(sum) +global S_13=`ernum'/`erden' +sum `c' if `use'<3 +scalar `ernum'=r(sum) +sum `r2' if `use'<3 +scalar `erden'=r(sum) +global S_14=`ernum'/`erden' + +*Remove "uninformative" studies +replace `a'=. if `use'!=1 +replace `b'=. if `use'!=1 +replace `c'=. if `use'!=1 +replace `d'=. if `use'!=1 +replace `r1'=. if `use'!=1 +replace `r2'=. if `use'!=1 +gen double `t' =`r1'+`r2' + +* Chi-squared test for effect +sum `a',meanonly +scalar `A'=r(sum) +gen double `ea'=(`r1'*`c1')/`t' +gen double `va'=`r1'*`r2'*`c1'*(`b'+`d')/(`t'*`t'*(`t'-1)) +sum `ea',meanonly +scalar `EA'=r(sum) +sum `va',meanonly +scalar `VA'=r(sum) +global S_10=( (`A'-`EA')^2 )/`VA' /* chi2 effect value */ +global S_11=chiprob(1,$S_10) /* p(chi2) */ + +if "`cornfield'"!="" { + *Compute Cornfield CI + gen `ill'=. + gen `iul'=. + local j = 1 + tempname i al aj c1j r1j r2j alold + while `j'<=_N { + if `use'[`j']==1 { + scalar `i' = 0 + scalar `al' =`a'[`j'] + scalar `aj' =`a'[`j'] + scalar `c1j'=`c1'[`j'] + scalar `r1j'=`r1'[`j'] + scalar `r2j'=`r2'[`j'] + scalar `alold'= . + while abs(`al'-`alold')>.001 & `al'!=. { + scalar `alold' = `al' + scalar `al'=`aj'-($ZIND)/sqrt( (1/`al') + 1/(`c1j'-`al') + /* + */ 1/(`r1j'-`al') + 1/(`r2j'-`c1j'+`al') ) + if `al'==. { + scalar `i'=`i'+1 + scalar `al'=`aj'-`i' + if (`al'<0 | (`r2j'-`c1j'+`al')<0) {scalar `al'= . } + } + } + + if `al'==. { + scalar `al'= 0 + } + replace `ill'=`log'( `al'*(`r2j'-`c1j'+`al')/((`c1j'-`al')*(`r1j'-`al')) ) in `j' + scalar `al'= `a'[`j'] + scalar `alold'= . + scalar `i'= 0 + while abs(`al'-`alold')>.001 & `al'!=. { + scalar `alold'= `al' + scalar `al'=`aj'+($ZIND)/sqrt( (1/`al')+ 1/(`c1j'-`al') + /* + */ 1/(`r1j'-`al') + 1/(`r2j'-`c1j'+`al') ) + if `al'==. { + scalar `i'=`i'+1 + scalar `al'=`aj'+`i' + if (`al'>`r1j' | `al'>`c1j' ) { + scalar `al' = . + } + } + } + + replace `iul'=`log'( `al'*(`r2j'-`c1j'+`al')/((`c1j'-`al')*(`r1j'-`al')) ) in `j' + } + + local j=`j'+1 + + } // end while + +} // end Cornfield + + +*Adjustment for zero cells in calcn of OR and var(OR) +gen `zeros'=1 if `use'==1 & (`a'==0 | `b'==0 | `c'==0 | `d'==0 ) +gen `cont_a'=`cc' +gen `cont_b'=`cc' +gen `cont_c'=`cc' +gen `cont_d'=`cc' +replace `a'=`a'+`cont_a' if `zeros'==1 +replace `b'=`b'+`cont_b' if `zeros'==1 +replace `c'=`c'+`cont_c' if `zeros'==1 +replace `d'=`d'+`cont_d' if `zeros'==1 +replace `r1'=`r1'+(`cont_a'+`cont_b') if `zeros'==1 +replace `r2'=`r2'+(`cont_c'+`cont_d') if `zeros'==1 +replace `t' =`t' +(`cont_a'+`cont_b')+(`cont_c'+`cont_d') if `zeros'==1 +gen double `or' =(`a'*`d')/(`b'*`c') +gen double `lnor'=log(`or') +gen double `v' =1/`a' +1/`b' +1/`c' + 1/`d' +gen double `es' =`log'(`or') +gen double `se' =sqrt(`v') + +if "`cornfield'"=="" { + gen `ill' =`exp'(`lnor'-$ZIND*`se') + gen `iul' =`exp'(`lnor'+$ZIND*`se') +} + +if "`method'"=="M-H" | ( "`method'"=="D+L" & "`randomi'"=="" ) { + tempname p q r s pr ps qr qs + gen double `r' =`a'*`d'/`t' + gen double `s' =`b'*`c'/`t' + sum `r', meanonly + scalar `R' =r(sum) + sum `s', meanonly + scalar `S' =r(sum) + + *Calculate pooled MH- OR + scalar `OR' =`R'/`S' + scalar `lnOR'=log(`OR') + + *Calculate variance/SE of lnOR and weights + gen double `p' =(`a'+`d')/`t' + gen double `q' =(`b'+`c')/`t' + gen double `pr' =`p'*`r' + gen double `ps' =`p'*`s' + gen double `qr' =`q'*`r' + gen double `qs' =`q'*`s' + sum `pr', meanonly + scalar `PR' =r(sum) + sum `ps', meanonly + scalar `PS' =r(sum) + sum `qr', meanonly + scalar `QR' =r(sum) + sum `qs', meanonly + scalar `QS' =r(sum) + scalar `selnOR'= sqrt( (`PR'/(`R'*`R') + (`PS'+`QR')/(`R'*`S') + /* + */ `QS'/(`S'*`S'))/2 ) + gen `weight'=100*`s'/`S' + + *Store results in global macros, on log scale if requested + global S_1 =`log'(`OR') + global S_2 =`selnOR' + global S_3 =`exp'(`lnOR' -$ZOVE*`selnOR') + global S_4 =`exp'(`lnOR' +$ZOVE*`selnOR') + global S_5 =abs(`lnOR')/(`selnOR') + global S_6 =normprob(-abs($S_5))*2 + drop `p' `q' `r' `pr' `ps' `qr' `qs' + + *Calculate heterogeneity + if "`breslow'"=="" { + gen double `qhet' =( (`lnor'-`lnOR')^2 )/`v' + sum `qhet', meanonly + global S_7 =r(sum) /*Chi-squared */ + global S_9 =chiprob($S_8,$S_7) /*p(chi2 het) */ + global S_51 =max(0, ( 100*($S_7-$S_8))/($S_7) ) + } +} /* end M-H method */ + +if "`wgt'"!="" { + cap gen `weight'=. + udw `lnor' `v' , wgt(`wgt') `exp' + replace `weight'=`wgt'*100/$MA_W + local udwind "wgt(`wgt')" + } +else if "`method'"!="M-H" & "`method'"!= "USER"{ + cap gen `weight'=. + iv `lnor' `v', method(`method') `randomi' `exp' + replace `weight'=100/( (`v'+$S_12)*($MA_W) ) +} + +if "`breslow'"!="" { + + *Calculate heterogeneity by Breslow-Day test: need to reset zero cells and margins + if "`log'"=="" { + local bexp + } + else { + local bexp "exp" + } + + replace `a'=`a'-`cont_a' if `zeros'==1 + replace `b'=`b'-`cont_b' if `zeros'==1 + replace `c'=`c'-`cont_c' if `zeros'==1 + replace `d'=`d'-`cont_d' if `zeros'==1 + replace `r1'=`r1'-(`cont_a'+`cont_b') if `zeros'==1 + replace `r2'=`r2'-(`cont_c'+`cont_d') if `zeros'==1 + replace `t' =`t' -(`cont_a'+`cont_b')-(`cont_c'+`cont_d') if `zeros'==1 + + if abs(`bexp'($S_1) - 1)<0.0001 { + gen afit = `r1'*`c1'/`t' + gen bfit = `r1'*`c2'/`t' + gen cfit = `r2'*`c1'/`t' + gen dfit = `r2'*`c2'/`t' + } + else { + tempvar sterm cterm root1 root2 afit bfit cfit dfit bresd_q + tempname qterm + scalar `qterm' = 1-`bexp'($S_1) + gen `sterm' = `r2' - `c1' + (`bexp'($S_1))*(`r1'+`c1') + gen `cterm' = -(`bexp'($S_1))*`c1'*`r1' + gen `root1' = (-`sterm' + sqrt(`sterm'*`sterm' - 4*`qterm'*`cterm'))/(2*`qterm') + gen `root2' = (-`sterm' - sqrt(`sterm'*`sterm' - 4*`qterm'*`cterm'))/(2*`qterm') + gen `afit' = `root1' if `root2'<0 + replace `afit' = `root2' if `root1'<0 + replace `afit' = `root1' if (`root2'>`c1') | (`root2'>`r1') + replace `afit' = `root2' if (`root1'>`c1') | (`root1'>`r1') + gen `bfit' = `r1' - `afit' + gen `cfit' = `c1' - `afit' + gen `dfit' = `r2' - `cfit' + } + + gen `qhet' = ((`a'-`afit')^2)*((1/`afit')+(1/`bfit')+(1/`cfit')+(1/`dfit')) + sum `qhet', meanonly + global S_7 =r(sum) /*Het. Chi-squared */ + global S_9 =chiprob($S_8,$S_7) /*p(chi2 het) */ + global S_51 =max(0, ( 100*($S_7-$S_8))/($S_7) ) +} + +if "`method'" == "USER"{ + forvalues i = 1/15{ + global S_`i' = . + } + cap drop `weight' + gen `weight'=. + if "`rjhsecond'" != ""{ + global S_1 = $MA_userES + global S_3 = $MA_userCIlow + global S_4 = $MA_userCIupp + } + else{ + global S_1 = $MA_userESM + global S_3 = $MA_userCIlowM + global S_4 = $MA_userCIuppM + } +} +replace `weight'=0 if `weight'==. + + +} /* End of "quietly" loop */ + + +_disptab `es' `se' `ill' `iul' `weight' `use' `label' `rawdata', `keep' `sortby' /* +*/ `table' method(`method') sumstat(OR) `chi2' `xlabel' `xtick' `force' `graph' /* +*/ `box' `saving' t1("`t1'") t2("`t2'") b1("`b1'") b2("`b2'") lcols("`lcols'") rcols("`rcols'") `overall' `wt' /* +*/ `stats' `counts' `log' `groupla' `udwind' `cornfield' `rjhsecond' + +end + + + +program define Peto + +version 9.0 + +#delimit ; +syntax varlist(min=4 max=4 default=none numeric) [if] [in] [, + LABEL(string) ORDER(string) noGRAPH METHOD(string) CHI2 XLAbel(passthru) + XTICK(passthru) FORCE noKEEP SAVING(passthru) noBOX noTABLE SORTBY(passthru) T1(string) + T2(string) B1(string) B2(string) LCOLS(string) RCOLS(string) noOVERALL noWT noSTATS LOG COUNTS RJHSECOND] ; + +#delimit cr + +qui { + +tempvar a b c d use r1 r2 t ea olesse v lnor or es se /* + */ ill iul p weight id rawdata +tempname ernum erden OLESSE V SE P lnOR A C R1 R2 + +tokenize "`varlist'", parse(" ") + +if "`log'"!="" { + local exp +} +else { + local exp "exp" +} + +gen double `a' =`1' `if' `in' +gen double `b' =`2' `if' `in' +gen double `c' =`3' `if' `in' +gen double `d' =`4' `if' `in' +gen double `r1' =`a'+`b' +gen double `r2' =`c'+`d' +gen byte `use'=1 `if' `in' +replace `use'=9 if `use'==. +replace `use'=9 if (`r1'==.) | (`r2'==.) +replace `use'=2 if (`use'==1) & (`r1'==0 | `r2'==0 ) +replace `use'=2 if (`use'==1) & ((`a'==0 & `c'==0 ) | (`b'==0 & `d'==0)) +count if `use'==1 +global S_8 =r(N)-1 + +if $S_8<0 { + exit +} + +if "`counts'"!="" { + *Display raw counts + gen str `rawdata'= string(`a') + "/" + string(`r1') +";" + /* + */ string(`c') + "/"+ string(`r2') if `use'!=9 + replace `rawdata'= trim(`rawdata') + if "`overall'"=="" { + sum `a' if (`use'==1 | `use'==2) + local sum1 =r(sum) + sum `r1' if (`use'==1 | `use'==2) + local sum2 =r(sum) + sum `c' if (`use'==1 | `use'==2) + local sum3 =r(sum) + sum `r2' if (`use'==1 | `use'==2) + local sum4 =r(sum) + global MA_ODC "`sum1'/`sum2';`sum3'/`sum4'" + } +} + +else { + gen str1 `rawdata'="." +} /* end counts */ + +*Get average event rate for each group (before any 0.5 adjustments or excluding 0-0 studies) +sum `a' if `use'<3 +scalar `ernum'=r(sum) +sum `r1' if `use'<3 +scalar `erden'=r(sum) +global S_13=`ernum'/`erden' +sum `c' if `use'<3 +scalar `ernum'=r(sum) +sum `r2' if `use'<3 +scalar `erden'=r(sum) +global S_14=`ernum'/`erden' + +*Remove "uninformative" studies +replace `a'=. if `use'!=1 +replace `b'=. if `use'!=1 +replace `c'=. if `use'!=1 +replace `d'=. if `use'!=1 +replace `r1'=. if `use'!=1 +replace `r2'=. if `use'!=1 +gen double `t' =`r1'+`r2' +gen double `ea' =`r1'*(`a'+`c')/`t' +gen double `olesse'=`a'-`ea' +gen double `v' =`r1'*`r2'*(`a'+`c')*(`b'+`d')/( `t'*`t'*(`t'-1) ) +gen double `lnor' =`olesse'/`v' +gen double `es' = `exp'(`lnor') +gen double `se' = 1/(sqrt(`v')) +gen double `ill' = `exp'(`lnor'-$ZIND*`se') +gen double `iul' = `exp'(`lnor'+$ZIND*`se') +gen double `p' =(`olesse')*(`olesse')/`v' +sum `olesse', meanonly +scalar `OLESSE'=r(sum) +sum `v', meanonly +scalar `V' =r(sum) +sum `p', meanonly +scalar `P' =r(sum) +scalar `lnOR' =`OLESSE'/`V' +global S_1 =`exp'(`lnOR') +global S_2 =1/sqrt(`V') +global S_3 =`exp'(`lnOR'-$ZOVE*($S_2)) +global S_4 =`exp'(`lnOR'+$ZOVE*($S_2)) +sum `a', meanonly +scalar `A' =r(sum) +sum `c', meanonly +scalar `C' =r(sum) +sum `r1', meanonly +scalar `R1' =r(sum) +sum `r2', meanonly +scalar `R2' =r(sum) +global S_10 =(`OLESSE'^2)/`V' /*Chi-squared effect*/ +global S_11 =chiprob(1,$S_10) +global S_5 =abs(`lnOR')/($S_2) +global S_6 =normprob(-abs($S_5))*2 + +/*Heterogeneity */ +global S_7=`P'-$S_10 +global S_9 =chiprob($S_8,$S_7) +global S_51 =max(0, ( 100*($S_7-$S_8))/($S_7) ) +gen `weight' =100*`v'/`V' + +if "`method'" == "USER"{ + forvalues i = 1/15{ + global S_`i' = . + } + cap drop `weight' + gen `weight'=. + if "`rjhsecond'" != ""{ + global S_1 = $MA_userES + global S_3 = $MA_userCIlow + global S_4 = $MA_userCIupp + } + else{ + global S_1 = $MA_userESM + global S_3 = $MA_userCIlowM + global S_4 = $MA_userCIuppM + } +} +replace `weight'=0 if `weight'==. + +} /* End of quietly loop */ + +_disptab `es' `se' `ill' `iul' `weight' `use' `label' `rawdata' , `keep' `sortby' /* + */ `table' method(`method') sumstat(OR) `chi2' `xlabel' `xtick' `force' `graph' `box' /* + */ `saving' t1("`t1'") t2("`t2'") b1("`b1'") b2("`b2'") lcols("`lcols'") rcols("`rcols'") /* + */ `rjhsecond' `overall' `wt' `stats' `counts' `log' + +end + + + + +program define RR +version 9.0 +#delimit ; +syntax varlist(min=4 max=4 default=none numeric) [if] [in] [, + LABEL(string) SORTBY(passthru) noGRAPH noTABLE RANDOMI METHOD(string) CC(string) + XLAbel(passthru) XTICK(passthru) FORCE noKEEP SAVING(passthru) noBOX T1(string) + T2(string) B1(string) B2(string) LCOLS(string) RCOLS(string) noOVERALL noWT noSTATS LOG COUNTS RJHSECOND + WGT(varlist numeric max=1) ] ; +#delimit cr + +qui { + +tempvar a b c d use zeros r1 r2 t p r s rr lnrr es v se ill iul q /* + */ weight id rawdata cont_a cont_b cont_c cont_d +tempname ernum erden P R S RR lnRR vlnRR + +tokenize "`varlist'", parse(" ") + +if "`log'"!="" { + local exp +} +else { + local exp "exp" +} + +gen double `a' =`1' +gen double `b' =`2' +gen double `c' =`3' +gen double `d' =`4' +gen double `r1' =`a'+`b' +gen double `r2' =`c'+`d' +gen byte `use'=1 `if' `in' +replace `use'=9 if `use'==. +replace `use'=9 if (`r1'==.) | (`r2'==.) +replace `use'=2 if (`use'==1) & (`r1'==0 | `r2'==0 ) +replace `use'=2 if (`use'==1) & ((`a'==0 & `c'==0 ) | (`b'==0 & `d'==0)) +count if `use'==1 +global S_8 =r(N)-1 +if $S_8<0 { + exit +} + +if "`counts'"!="" { + *Display raw counts + gen str `rawdata'= string(`a') + "/" + string(`r1') +";" + /* + */ string(`c') + "/"+ string(`r2') if `use'!=9 + replace `rawdata'= trim(`rawdata') + if "`overall'"=="" { + sum `a' if (`use'==1 | `use'==2) + local sum1 =r(sum) + sum `r1' if (`use'==1 | `use'==2) + local sum2 =r(sum) + sum `c' if (`use'==1 | `use'==2) + local sum3 =r(sum) + sum `r2' if (`use'==1 | `use'==2) + local sum4 =r(sum) + global MA_ODC "`sum1'/`sum2';`sum3'/`sum4'" + } +} + +else { + gen str1 `rawdata'="." +} /* end counts */ + +if "`method'"=="D+L" & ($S_8==0) { + local method "M-H" +} + +*Get average event rate for each group (before any 0.5 adjustments or excluding 0-0 studies) +sum `a' if `use'<3 +scalar `ernum'=r(sum) +sum `r1' if `use'<3 +scalar `erden'=r(sum) +global S_13=`ernum'/`erden' +sum `c' if `use'<3 +scalar `ernum'=r(sum) +sum `r2' if `use'<3 +scalar `erden'=r(sum) +global S_14=`ernum'/`erden' + +*Adjustment for zero cells in calcn of OR and var(OR) +gen `zeros'=1 if `use'==1 & (`a'==0 | `b'==0 | `c'==0 | `d'==0 ) +gen `cont_a'=`cc' +gen `cont_b'=`cc' +gen `cont_c'=`cc' +gen `cont_d'=`cc' +replace `a'=`a'+`cont_a' if `zeros'==1 +replace `b'=`b'+`cont_b' if `zeros'==1 +replace `c'=`c'+`cont_c' if `zeros'==1 +replace `d'=`d'+`cont_d' if `zeros'==1 +replace `r1'=`r1'+(`cont_a'+`cont_b') if `zeros'==1 +replace `r2'=`r2'+(`cont_c'+`cont_d') if `zeros'==1 + +*Remove "uninformative" studies +replace `a'=. if `use'!=1 +replace `b'=. if `use'!=1 +replace `c'=. if `use'!=1 +replace `d'=. if `use'!=1 +replace `r1'=. if `use'!=1 +replace `r2'=. if `use'!=1 + +gen double `t' =`r1'+`r2' +gen double `r' =`a'*`r2'/`t' +gen double `s' =`c'*`r1'/`t' +gen double `rr' =`r'/`s' +gen double `lnrr'=log(`rr') +gen double `es' =`log'(`rr') +gen double `v' =1/`a' +1/`c' - 1/`r1' - 1/`r2' +gen double `se' =sqrt(`v') +gen double `ill' =`exp'(`lnrr'-$ZIND*`se') +gen double `iul' =`exp'(`lnrr'+$ZIND*`se') + +if "`method'"=="M-H" | "`method'"=="D+L" & "`randomi'"=="" { + *MH method for pooling/calculating heterogeneity in DL method + gen double `p' =`r1'*`r2'*(`a'+`c')/(`t'*`t') - `a'*`c'/`t' + sum `p', meanonly + scalar `P' =r(sum) + sum `r', meanonly + scalar `R' =r(sum) + sum `s', meanonly + scalar `S' =r(sum) + scalar `RR'=`R'/`S' + scalar `lnRR'=log(`RR') + + * Heterogeneity + gen double `q' =( (`lnrr'-`lnRR')^2 )/`v' + sum `q', meanonly + global S_7 =r(sum) + global S_9 =chiprob($S_8,$S_7) + global S_51 =max(0, ( 100*($S_7-$S_8))/($S_7) ) + gen `weight'=100*`s'/`S' + global S_1 =`log'(`RR') + global S_2 =sqrt( `P'/(`R'*`S') ) + global S_3 =`exp'(`lnRR' -$ZOVE*($S_2)) + global S_4 =`exp'(`lnRR' +$ZOVE*($S_2)) + global S_5 =abs(`lnRR')/($S_2) + global S_6 =normprob(-abs($S_5))*2 +} + +if "`wgt'"!="" { + cap gen `weight'=. + udw `lnrr' `v' , wgt(`wgt') `exp' + replace `weight'=`wgt'*100/$MA_W + local udwind "wgt(`wgt')" +} + +else if "`method'"!="M-H" & "`method'"!="USER"{ + cap gen `weight'=. + iv `lnrr' `v', method(`method') `randomi' `exp' + replace `weight'=100/( (`v'+$S_12)*($MA_W) ) +} + + +if "`method'" == "USER"{ + forvalues i = 1/15{ + global S_`i' = . + } + cap drop `weight' + gen `weight'=. + if "`rjhsecond'" != ""{ + global S_1 = $MA_userES + global S_3 = $MA_userCIlow + global S_4 = $MA_userCIupp + } + else{ + global S_1 = $MA_userESM + global S_3 = $MA_userCIlowM + global S_4 = $MA_userCIuppM + } +} +replace `weight'=0 if `weight'==. + + + + +} /* End of "quietly" loop */ + + +_disptab `es' `se' `ill' `iul' `weight' `use' `label' `rawdata' , `keep' `sortby' /* + */ `table' method(`method') sumstat(RR) `xlabel' `xtick' `force' `graph' `box' /* + */ `saving' t1("`t1'") t2("`t2'") b1("`b1'") b2("`b2'") lcols("`lcols'") rcols("`rcols'") `overall' `wt' /* + */ `stats' `counts' `log' `udwind' `rjhsecond' + +end + + + +program define RD + +version 9.0 + +#delimit ; +syntax varlist(min=4 max=4 default=none numeric) [if] [in] [, + LABEL(string) SORTBY(passthru) noGRAPH noTABLE RANDOMI METHOD(string) CC(string) noKEEP + SAVING(passthru) XLAbel(passthru) XTICK(passthru) noBOX FORCE T1(string) T2(string) + B1(string) B2(string) LCOLS(string) RCOLS(string) noOVERALL noWT noSTATS COUNTS WGT(varlist numeric max=1) RJHSECOND ] ; +#delimit cr + +qui { + +tempvar a b c d use zeros r1 r2 t rd weight rdnum v se ill iul vnum q /* + */ id w rawdata cont_a cont_b cont_c cont_d +tempname ernum erden RDNUM VNUM W + +tokenize "`varlist'", parse(" ") +gen double `a' =`1' +gen double `b' =`2' +gen double `c' =`3' +gen double `d' =`4' +gen double `r1' =`a'+`b' +gen double `r2' =`c'+`d' +gen byte `use'=1 `if' `in' +replace `use'=9 if `use'==. +replace `use'=9 if (`r1'==.) | (`r2'==.) +replace `use'=2 if ( `use'==1) & (`r1'==0 | `r2'==0 ) +count if `use'==1 +global S_8 =r(N)-1 + +if $S_8<0 { + exit +} + +if "`counts'"!="" { + *Display raw counts + gen str `rawdata'= string(`a') + "/" + string(`r1') +";" + /* + */ string(`c') + "/"+ string(`r2') if `use'!=9 + replace `rawdata'= trim(`rawdata') + + if "`overall'"=="" { + sum `a' if (`use'==1 | `use'==2) + local sum1 =r(sum) + sum `r1' if (`use'==1 | `use'==2) + local sum2 =r(sum) + sum `c' if (`use'==1 | `use'==2) + local sum3 =r(sum) + sum `r2' if (`use'==1 | `use'==2) + local sum4 =r(sum) + global MA_ODC "`sum1'/`sum2';`sum3'/`sum4'" + } +} + +else { + gen str1 `rawdata'="." +} /* end counts */ + +if "`method'"=="D+L" & ($S_8==0) { + local method "M-H" +} + +*Get average event rate for each group (before any cont adjustments or excluding 0-0 studies) +sum `a' if `use'<3 +scalar `ernum'=r(sum) +sum `r1' if `use'<3 +scalar `erden'=r(sum) +global S_13=`ernum'/`erden' +sum `c' if `use'<3 +scalar `ernum'=r(sum) +sum `r2' if `use'<3 +scalar `erden'=r(sum) +global S_14=`ernum'/`erden' + +*Remove "uninformative" studies +replace `a'=. if `use'!=1 +replace `b'=. if `use'!=1 +replace `c'=. if `use'!=1 +replace `d'=. if `use'!=1 +replace `r1'=. if `use'!=1 +replace `r2'=. if `use'!=1 +gen double `t' =`r1'+`r2' +gen double `rd' =`a'/`r1' - `c'/`r2' +gen `weight'=`r1'*`r2'/`t' +sum `weight',meanonly +scalar `W' =r(sum) +gen double `rdnum'=( (`a'*`r2')-(`c'*`r1') )/`t' + +* Zero cell adjustments, placed here to ensure 0/n1 v 0/n2 really IS RD=0 +*Adjustment for zero cells in calcn of OR and var(OR) + +gen `zeros'=1 if `use'==1 & (`a'==0 | `b'==0 | `c'==0 | `d'==0 ) +gen `cont_a'=`cc' +gen `cont_b'=`cc' +gen `cont_c'=`cc' +gen `cont_d'=`cc' +replace `a'=`a'+`cont_a' if `zeros'==1 +replace `b'=`b'+`cont_b' if `zeros'==1 +replace `c'=`c'+`cont_c' if `zeros'==1 +replace `d'=`d'+`cont_d' if `zeros'==1 +replace `r1'=`r1'+(`cont_a'+`cont_b') if `zeros'==1 +replace `r2'=`r2'+(`cont_c'+`cont_d') if `zeros'==1 +replace `t' =`t' +(`cont_a'+`cont_b')+(`cont_c'+`cont_d') if `zeros'==1 + +gen double `v' =`a'*`b'/(`r1'^3)+`c'*`d'/(`r2'^3) +gen double `se' =sqrt(`v') +gen double `ill' = `rd'-$ZIND*`se' +gen double `iul' = `rd'+$ZIND*`se' + +if "`method'"=="M-H" | ("`method'"=="D+L" & "`randomi'"=="" ) { + sum `rdnum',meanonly + scalar `RDNUM'=r(sum) + global S_1 =`RDNUM'/`W' + gen double `q' =( (`rd'-$S_1)^2 )/`v' + sum `q', meanonly + global S_7 =r(sum) + global S_9 =chiprob($S_8,$S_7) + global S_51 =max(0, ( 100*($S_7-$S_8))/($S_7) ) + gen double `vnum'=( (`a'*`b'*(`r2'^3) )+(`c'*`d'*(`r1'^3))) /* + */ /(`r1'*`r2'*`t'*`t') + sum `vnum',meanonly + scalar `VNUM'=r(sum) + global S_2 =sqrt( `VNUM'/(`W'*`W') ) + replace `weight'=`weight'*100/`W' + global S_3 =$S_1 -$ZOVE*($S_2) + global S_4 =$S_1 +$ZOVE*($S_2) + global S_5 =abs($S_1)/($S_2) + global S_6 =normprob(-abs($S_5))*2 +} + +if "`wgt'"!="" { + udw `rd' `v' ,wgt(`wgt') + replace `weight'=`wgt'*100/$MA_W + local udwind "wgt(`wgt')" +} +else if "`method'"!="M-H" & "`method'"!= "USER" { + iv `rd' `v', method(`method') `randomi' + replace `weight'=100/( (`v'+$S_12)*($MA_W) ) +} + +if "`method'" == "USER"{ + forvalues i = 1/15{ + global S_`i' = . + } + cap drop `weight' + gen `weight'=. + if "`rjhsecond'" != ""{ + global S_1 = $MA_userES + global S_3 = $MA_userCIlow + global S_4 = $MA_userCIupp + } + else{ + global S_1 = $MA_userESM + global S_3 = $MA_userCIlowM + global S_4 = $MA_userCIuppM + } +} +replace `weight'=0 if `weight'==. + +} /* End of "quietly" loop */ + + +_disptab `rd' `se' `ill' `iul' `weight' `use' `label' `rawdata', `keep' `sortby' /* + */ `table' method(`method') sumstat(RD) `xlabel' `xtick'`force' `graph' `box' /* + */ `saving' t1("`t1'") t2("`t2'") b1("`b1'") b2("`b2'") lcols("`lcols'") rcols("`rcols'") /* + */ `rjhsecond' `overall' `wt' `stats' `counts' `udwind' + +end + + + + +program define MD + +version 9.0 + +#delimit ; + +syntax varlist(min=6 max=6 default=none numeric) [if] [in] [, + LABEL(string) SORTBY(passthru) noGRAPH METHOD(string) noKEEP SAVING(passthru) noBOX + noTABLE STANDARD(string) XLAbel(passthru) XTICK(passthru) FORCE T1(string) T2(string) + B1(string) B2(string) LCOLS(string) RCOLS(string) noOVERALL noWT noSTATS COUNTS WGT(string) RJHSECOND ] ; + +#delimit cr + +qui { + +tempvar n1 x1 sd1 n2 x2 sd2 use n s md v se ill iul weight id qhet rawdata +tokenize "`varlist'", parse(" ") +gen double `n1' =`1' +gen double `x1' =`2' +gen double `sd1'=`3' +gen double `n2' =`4' +gen double `x2' =`5' +gen double `sd2'=`6' + +gen `use'=1 `if' `in' + +replace `use'=9 if `use'==. +replace `use'=9 if (`n1'==.) | (`n2'==.) | (`x1'==.) | (`x2'==.) | /* + */ (`sd1'==.) | (`sd2'==.) +replace `use'=2 if ( `use'==1) & (`n1' <2 | `n2' <2 ) +replace `use'=2 if ( `use'==1) & (`sd1'<=0 | `sd2'<=0 ) +count if `use'==1 +global S_8 =r(N)-1 + +if $S_8<0 { + exit +} + +if "`counts'"!="" { + *Display raw counts instead of default + gen `rawdata'= string(`n1') + ", " + string(`x1',"%7.3g") +" (" + string(`sd1',"%7.3g") + /* + */ ") ; " + string(`n2') + ", " + string(`x2',"%7.3g") +" (" + string(`sd2',"%7.3g") +") " + replace `rawdata'= trim(`rawdata') + qui summ `n1' + local sum1 = r(sum) + qui summ `n2' + local sum2 = r(sum) + global MA_ODC = string(`sum1') + "; " + string(`sum2') +} +else { + gen str1 `rawdata'="." +} /* end counts */ + +if "`method'"=="D+L" & ($S_8==0) { + local method "I-V" +} + +replace `n1' =. if `use'!=1 +replace `x1' =. if `use'!=1 +replace `sd1'=. if `use'!=1 +replace `n2' =. if `use'!=1 +replace `x2' =. if `use'!=1 +replace `sd2'=. if `use'!=1 +gen double `n' =`n1'+`n2' + +if "`standard'"=="none" { + gen double `md' =`x1'-`x2' + gen double `v'=(`sd1'^2)/`n1' + (`sd2'^2)/`n2' + local prefix "W" +} +else { + gen double `s'=sqrt( ((`n1'-1)*(`sd1'^2)+(`n2'-1)*(`sd2'^2) )/(`n'-2) ) + if "`standard'"=="cohen" { + gen double `md' = (`x1'-`x2')/`s' + gen double `v'= ( `n'/(`n1'*`n2') )+( (`md'^2)/(2*(`n'-2)) ) + } + else if "`standard'"=="hedges" { + gen double `md' =( (`x1'-`x2')/`s' )*( 1- 3/(4*`n'-9) ) + gen double `v'=( `n'/(`n1'*`n2') ) + ( (`md'^2)/(2*(`n'-3.94)) ) + } + else if "`standard'"=="glass" { + gen double `md' = (`x1'-`x2')/`sd2' + gen double `v'= (`n'/(`n1'*`n2')) + ( (`md'^2)/(2*(`n2'-1)) ) + } + local prefix "S" +} + +gen double `se' =sqrt(`v') +gen double `ill' =`md'-$ZIND*`se' +gen double `iul' =`md'+$ZIND*`se' +if "`wgt'"!="" { + udw `md' `v' , wgt(`wgt') + gen `weight'=`wgt'*100/$MA_W + local udwind "wgt(`wgt')" +} + +else { + iv `md' `v', method(`method') randomi + gen `weight'=100/( (`v'+$S_12)*($MA_W) ) +} + + +if "`method'" == "USER"{ + forvalues i = 1/15{ + global S_`i' = . + } + cap drop `weight' + gen `weight'=. + if "`rjhsecond'" != ""{ + global S_1 = $MA_userES + global S_3 = $MA_userCIlow + global S_4 = $MA_userCIupp + } + else{ + global S_1 = $MA_userESM + global S_3 = $MA_userCIlowM + global S_4 = $MA_userCIuppM + } +} +replace `weight'=0 if `weight'==. + +} /* End of quietly loop */ + + +_disptab `md' `se' `ill' `iul' `weight' `use' `label' `rawdata', `keep' `sortby' /* + */ `table' method(`method') sumstat(`prefix'MD) `xlabel' `xtick' `force' `graph' /* + */ `box' `saving' t1("`t1'") t2("`t2'") b1("`b1'") b2("`b2'") lcols("`lcols'") rcols("`rcols'") /* + */ `rjhsecond' `overall' `wt' `stats' `udwind' `counts' + +end + + + +program define iv_init + +version 9.0 + +#delimit ; + +syntax varlist(min=2 max=3 default=none numeric) [if] [in] [, + LABEL(string) SORTBY(passthru) noGRAPH METHOD(string) noKEEP SAVING(passthru) noBOX + noTABLE XLAbel(passthru) XTICK(passthru) FORCE T1(string) T2(string) B1(string) + B2(string) LCOLS(string) RCOLS(string) noOVERALL noWT noSTATS EFORM WGT(string) RJHSECOND ] ; + +#delimit cr + +qui { + +tempvar es se use v ill iul weight id rawdata +tokenize "`varlist'", parse(" ") +gen `es'=`1' +if "`eform'"!="" { + local exp "exp" +} + +if "`3'"=="" { + gen double `se'=`2' + gen double `ill' =`exp'(`es'-$ZIND*`se' ) + gen double `iul' =`exp'(`es'+$ZIND*`se' ) +} + +if "`3'"!="" { + gen double `se'=(`3'-`2')/($ZIND*2) + gen double `ill' =`exp'(`2') + gen double `iul' =`exp'(`3') + local var3 "var3" +} + +gen double `use'=1 `if' `in' +replace `use'=9 if `use'==. +replace `use'=9 if (`es'==. | `se'==.) +replace `use'=2 if (`use'==1 & `se'<=0 ) +count if `use'==1 +global S_8 =r(N)-1 + +if $S_8<0 { + exit +} + +if "`method'"=="D+L" & ($S_8==0) { + local method "I-V" +} + +replace `es' =. if `use'!=1 +replace `se' =. if `use'!=1 +gen double `v'=(`se')^2 +gen str1 `rawdata'="." + +if "`wgt'"!=""{ + cap drop `weight' + gen `weight' = `wgt' if `use'==1 + udw `es' `v', wgt(`weight') `exp' `rjhsecond' + replace `weight'=100*`wgt'/($MA_W) + local udwind "wgt(`wgt')" +} +else { + iv `es' `v', method(`method') `exp' randomi `rjhsecond' + *NB randomi necc to calculate heterogeneity + gen `weight'=100/( (`v'+$S_12)*($MA_W) ) +} + + +replace `weight'=0 if `weight'==. +replace `es'=`exp'(`es') + +} /* End of quietly loop */ + +_disptab `es' `se' `ill' `iul' `weight' `use' `label' `rawdata', `keep' `sortby' /* + */`table' method(`method') sumstat(ES) `xlabel' `xtick' `force' `graph' `box' /* + */ `saving' t1("`t1'") t2("`t2'") b1("`b1'") b2("`b2'") lcols("`lcols'") rcols("`rcols'") `overall' `wt' `stats' `eform' /* + */ `var3' `udwind' `rjhsecond' + +end + + + + +program define iv + +version 9.0 + +#delimit ; + +syntax varlist(min=2 max=2 default=none numeric) [if] [in] [, + METHOD(string) RANDOMI EXP RJHSECOND ] ; + +#delimit cr + +tempvar stat v w qhet w2 wnew e_w e_wnew +tempname W W2 C T2 E_W E_WNEW OV vOV QHET + +tokenize "`varlist'", parse(" ") +gen `stat'=`1' +gen `v' =`2' +gen `w' =1/`v' +sum `w',meanonly +scalar `W'=r(sum) +global S_12=0 +global MA_W =`W' + +if ("`randomi'"=="" & "`method'"=="D+L") { + scalar `QHET'=$S_7 +} +else { + gen `e_w' =`stat'*`w' + sum `e_w',meanonly + scalar `E_W'=r(sum) + scalar `OV' =`E_W'/`W' + + * Heterogeneity + gen `qhet' =( (`stat'-`OV')^2 )/`v' + sum `qhet', meanonly + scalar `QHET'=r(sum) + global S_7=`QHET' +} + +if "`method'"=="D+L" { + gen `w2' =`w'*`w' + sum `w2',meanonly + scalar `W2' =r(sum) + scalar `C' =`W' - `W2'/`W' + global S_12 =max(0, ((`QHET'-$S_8)/`C') ) + global RJH_TAU2 = $S_12 + gen `wnew' =1/(`v'+$S_12) + gen `e_wnew'=`stat'*`wnew' + sum `wnew',meanonly + global MA_W =r(sum) + sum `e_wnew',meanonly + scalar `E_WNEW'=r(sum) + scalar `OV' =`E_WNEW'/$MA_W +} + + +global S_1 =`exp'(`OV') +global S_2 =sqrt( 1/$MA_W ) +global S_3 =`exp'(`OV' -$ZOVE*($S_2)) +global S_4 =`exp'(`OV' +$ZOVE*($S_2)) +global S_5 =abs(`OV')/($S_2) +global S_6 =normprob(-abs($S_5))*2 +global S_9 =chiprob($S_8,$S_7) +global S_51 =max(0, ( 100*($S_7-$S_8))/($S_7) ) + +if "`method'" == "USER"{ + forvalues i = 1/15{ + global S_`i' = . + } + cap drop `weight' + tempvar weight + gen `weight'=. + if "`rjhsecond'" != ""{ + global S_1 = $MA_userES + global S_3 = $MA_userCIlow + global S_4 = $MA_userCIupp + } + else{ + global S_1 = $MA_userESM + global S_3 = $MA_userCIlowM + global S_4 = $MA_userCIuppM + } +} +end + + +program define udw + +* user defined weights to combine trials + +version 9.0 +#delimit ; + +syntax varlist(min=2 max=2 default=none numeric) [if] [in] [, + METHOD(string) EXP WGT(varlist numeric max=1) RJHSECOND ] ; + +#delimit cr +tempvar stat v w e_w varcomp qhet +tempname W E_W OV W2 Vnum V QHET + +tokenize "`varlist'", parse(" ") +gen `stat'=`1' +gen `v' =`2' +gen `w' =`wgt' if `stat'!=. +sum `w',meanonly +scalar `W'=r(sum) +if `W'==0 { + di as err "Usable weights sum to zero: the table below will probably be nonsense" +} + +global MA_W =`W' + +*eff size = SIGMA(wi * thetai)/SIGMA(wi) +gen `e_w' =`stat'*`w' +sum `e_w',meanonly +scalar `E_W'=r(sum) +scalar `OV' =`E_W'/`W' + +*VAR = SIGMA{wi^2 * var(thetai) }/[SIGMA(wi)]^2 +sum `w',meanonly +scalar `W2'=(r(sum))^2 +gen `varcomp' = `w'*`w'*`v' +sum `varcomp' ,meanonly +scalar `Vnum'=r(sum) +scalar `V' =`Vnum'/`W2' + +*Heterogeneity (need to use variance weights here - BUT use ES=wgt*es/wgt, not necc var wts) +gen `qhet' =( (`stat'-`OV')^2 )/`v' +sum `qhet', meanonly +scalar `QHET'=r(sum) + +global S_1 =`exp'(`OV') +global S_2 =sqrt( `V' ) +global S_3 =`exp'(`OV' -$ZOVE*($S_2)) +global S_4 =`exp'(`OV' +$ZOVE*($S_2)) +global S_5 =abs(`OV')/($S_2) +global S_6 =normprob(-abs($S_5))*2 +global S_7=`QHET' +global S_9 =chiprob($S_8,$S_7) +global S_51 =max(0, ( 100*($S_7-$S_8))/($S_7) ) + +if "$MA_method1" == "USER"{ + cap drop `weight' + tempvar weight + gen `weight'=. + forvalues i = 1/15{ + global S_`i' = . + } + if "`rjhsecond'" != ""{ + global S_1 = $MA_userES + global S_3 = $MA_userCIlow + global S_4 = $MA_userCIupp + } + else{ + global S_1 = $MA_userESM + global S_3 = $MA_userCIlowM + global S_4 = $MA_userCIuppM + } + global S_8 = 0 +} + +end + + +program define _disptab + +version 9.0 + +#delimit ; + +syntax varlist(min=7 max=8 default=none) [if] [in] [, + XLAbel(passthru) XTICK(passthru) FORCE noKEEP SAVING(passthru) noBOX noTABLE + noGRAPH METHOD(string) SUMSTAT(string) CHI2 T1(string) T2(string) B1(string) + B2(string) LCOLS(string) RCOLS(string) noOVERALL noWT noSTATS COUNTS LOG EFORM noGROUPLA SORTBY(string) + WGT(string) VAR3 CORNFIELD /* RJH */ RJHSECOND ] ; + +#delimit cr + +tempvar effect se lci uci weight use label tlabel rawdata id tau2 df +tokenize "`varlist'", parse(" ") + +qui { + +gen `effect'=`1' +gen `se' =`2' +gen `lci' =`3' +gen `uci' =`4' +gen `weight'=`5' +gen byte `use'=`6' +format `weight' %5.1f +gen str10 `label'="" +replace `label'=`7' +global IND: displ %2.0f $IND +gen `rawdata' = `8' +gen `tau2' = . +gen `df' = . + +if "`keep'"=="" { + + if ("`sumstat'"=="OR" | "`sumstat'"=="RR") & ("`log'"=="") { + local ln "log" + } + else { + local ln + } + + cap drop _ES + cap drop _seES + cap drop _selogES + + if "`sumstat'"!="ES" { + replace _SS =. if `use'!=1 + label var _SS "Sample size" + gen _ES =`effect' + label var _ES "`log'`sumstat'" + gen _se`ln'ES=`se' + label var _se`ln'ES "se(`ln'`log'`sumstat')" + } + + cap drop _LCI + cap drop _UCI + cap drop _WT + gen _LCI =`lci' + label var _LCI "Lower CI (`log'`sumstat')" + gen _UCI =`uci' + label var _UCI "Upper CI (`log'`sumstat')" + gen _WT=`weight' + label var _WT "`method' weight" + +} /* end if-keep */ + +preserve + +if "`overall'"=="" & "`rjhsecond'" == ""{ // only do this on main run + + **If overall figure requested, add an extra line to contain overall stats + + local nobs1=_N+1 + set obs `nobs1' + replace `weight'=100 in `nobs1' + replace `effect'= ($S_1) in `nobs1' + replace `lci'=($S_3) in `nobs1' + replace `uci'=($S_4) in `nobs1' + replace `use'=5 in `nobs1' + replace `tau2' = $S_12 in `nobs1' + replace `df' = $S_8 in `nobs1' + + if "`counts'"!="" { + replace `rawdata'="$MA_ODC" in `nobs1' + } + local i2=max(0, (100*($S_7-$S_8)/($S_7)) ) + local hetp=$S_9 + replace `label' = "Overall (I-squared = " + string(`i2', "%5.1f")+ "%, p = " + /// + string(`hetp', "%5.3f") + ")" in `nobs1' + + * RJH code for second method + if "$MA_method2" != "" { + local nobs1=_N+1 + set obs `nobs1' + replace `weight'=100 in `nobs1' + replace `effect'= $MA_second_ES in `nobs1' + replace `lci'=$MA_second_LCI in `nobs1' + replace `uci'=$MA_second_UCI in `nobs1' + replace `use'=17 in `nobs1' + if "$MA_second_TAU2" != ""{ + replace `tau2' = $MA_second_TAU2 in `nobs1' + replace `df' = $MA_second_DF in `nobs1' + } + replace `label' = "Overall" in `nobs1' + } + +} /* end overall stuff */ + +local usetot=$S_8+1 +count if `use'==2 +local alltot=r(N)+`usetot' +gen `id'=_n + +tempvar rjhorder +qui gen `rjhorder' = `use' +qui replace `rjhorder' = 3.5 if `use' == 19 // SWAP ROUND SO BLANK IN RIGHT PLACE +sort `rjhorder' `sortby' `id' + + +} /* End of quietly loop */ + + +if "`table'"=="" { + + qui gen str20 `tlabel'=`7' /*needs to be own label so as not to overrun!*/ + + if "`overall'`wt'"=="" { + local ww "% Weight" + } + + if $IND!=$OVE { + global OVE: displ %2.0f $OVE + local insert "[$OVE% Conf. Interval]" + } + else { + local insert "--------------------" + } + + di _n in gr _col(12) "Study" _col(22) "|" _col(24) "`log'" _col(28) "`sumstat'" /* + */ _col(34) "[$IND% Conf. Interval]" _col(59) "`ww'" _n _dup(21) "-" "+" _dup(51) "-" + + + local i=1 + while `i'<=_N { // BEGIN WHILE LOOP + + if "`overall'`wt'"=="" { + local ww=`weight'[`i'] + } + else { + local ww + } + if (`use'[`i'])==2 { + *excluded trial + di in gr `tlabel'[`i'] _col(22) "| (Excluded)" + } + + * IF NORMAL TRIAL, OR OVERALL EFFECT + if ( (`use'[`i']==1) | (`use'[`i']==5) | `use'[`i'] == 17 ) { + if (`use'[`i'])==1 { + *trial results + di in gr `tlabel'[`i'] _cont + } + else { + *overall + // RJH + if `use'[`i'] == 5 { + local dispM1 = "$MA_method1" + if "$MA_method1" == "USER"{ + local dispM1 = "$MA_userDescM" + } + di in gr _dup(21) "-" "+" _dup(11) "-" "`insert'" _dup(20) "-" _n /* + */ "`dispM1' pooled `log'`sumstat'" _cont + } + if `use'[`i'] == 17{ // SECOND EST + local dispM2 = "$MA_method2" + if "$MA_method2" == "USER"{ + local dispM2 = "$MA_userDesc" + } + di in gr "`dispM2' pooled `log'`sumstat'" _cont + } + } // end else + + di in gr _col(22) "|" in ye %7.3f `effect'[`i'] /* + */ _col(35) %7.3f `lci'[`i'] " " %7.3f `uci'[`i'] _col(60) %6.2f `ww' + } + local i=`i'+1 + + } /* END WHILE */ + + di in gr _dup(21) "-" "+" _dup(51) "-" + + if "`overall'"=="" & "$MA_method1" != "USER"{ + + if ("`method'"=="*" | "`var3'"!="") { + + if "`method'"=="*" { + di in gr "* note: trials pooled by user defined weight `wgt'" + } + + di in gr " Heterogeneity calculated by formula" _n /* + */ " Q = SIGMA_i{ (1/variance_i)*(effect_i - effect_pooled)^2 } " + + if "`var3'"!="" { + di in gr "where variance_i = ((upper limit - lower limit)/(2*z))^2 " + } + + } + + *Heterogeneity etc + if ( ("`sumstat'"=="OR" | "`sumstat'"=="RR") & "`log'"=="") { + local h0=1 + } + else if ("`sumstat'"=="ES" & "`eform'"!="") { + local h0=1 + } + else { + local h0=0 + } + + di _n in gr " Heterogeneity chi-squared = " in ye %6.2f $S_7 in gr /* + */ " (d.f. = " in ye $S_8 in gr ") p = " in ye %4.3f $S_9 + local i2=max(0, (100*($S_7-$S_8)/($S_7)) ) + if $S_8<1 { + local i2=. + } + di in gr " I-squared (variation in `sumstat' attributable to " /* + */ "heterogeneity) =" in ye %6.1f `i2' "%" + + if "`method'"=="D+L" { + di in gr " Estimate of between-study variance " /* + */ "Tau-squared = " in ye %7.4f $S_12 + } + + if "`chi2'"!="" { + di _n in gr " Test of OR=1: chi-squared = " in ye %4.2f /* + */ $S_10 in gr " (d.f. = 1) p = " in ye %4.3f $S_11 + } + else { + di _n in gr " Test of `log'`sumstat'=`h0' : z= " in ye %6.2f $S_5 /* + */ in gr " p = " in ye %4.3f $S_6 + } + } + + *capture only 1 trial scenario + + qui { + count + + if r(N)==1 { + set obs 2 + replace `use'=99 in 2 + replace `weight'=0 if `use'==99 + } + + } /*end of qui. */ + +} // end if table + +if "`graph'"=="" & `usetot'>0 { + +qui drop if `use' == 9 + + + _dispgby `effect' `lci' `uci' `weight' `use' `label' `rawdata' `tau2' `df', `log' /* + */ `xlabel' `xtick' `force' sumstat(`sumstat') `saving' `box' t1("`t1'") /* + */ t2("`t2'") b1("`b1'") b2("`b2'") lcols("`lcols'") rcols("`rcols'") `overall' `wt' `stats' `counts' `eform' /* + */ `groupla' `cornfield' + +} + + +restore + +end + + +program define metanby + +version 9.0 + +#delimit ; + +syntax varlist(min=2 max=6 default=none numeric) [if] [in] [, BY(string) + LABEL(string) SORTBY(string) noGRAPH noTABLE noKEEP NEXTCALL(string) + METHOD(string) METHOD2(string) SUMSTAT(string) RANDOMI WGT(passthru) noSUBGROUP SGWEIGHT + CORNFIELD CHI2 CC(passthru) STANDARD(passthru) noOVERALL LOG EFORM BRESLOW + XLAbel(passthru) XTICK(passthru) FORCE SAVING(passthru) T1(string) T2(string) + B1(string) B2(string) LCOLS(string) RCOLS(string) noWT noSTATS COUNTS noBOX noGROUPLA NOSECSUB ] ; + +#delimit cr + +if ("`subgroup'"!="" & "`overall'`sgweight'"!="") { + local wt "nowt" +} + +tempvar use by2 newby r1 r2 rawdata effect se lci uci weight wtdisp /* + */ hetc hetdf hetp i2 tau2 df tsig psig expand tlabel id + +qui { + +gen `use'=1 `if' `in' +replace `use'=9 if `use'==. + +gen str1 `rawdata'="." + +tokenize `varlist' + +if ("`nextcall'"=="RR" | "`nextcall'"=="OR" | "`nextcall'"=="RD" |"`nextcall'"=="Peto" ) { + + *Sort out r1 & r2 for 2x2 table: might be needed in counts and mh/use + gen `r1' = `1'+`2' + gen `r2' = `3'+`4' + replace `use'=2 if ((`use'==1) & (`r1'==0 | `r2'==0 )) + replace `use'=2 if ((`use'==1) & ((`1'+`3'==0) | (`2'+`4'==0) ) & "`nextcall'"!="RD") + replace `use'=9 if (`r1'==.) | (`r2'==.) + + if "`counts'"!="" { + *create new variable with count data (if requested) + replace `rawdata'= trim( string(`1') + "/" + string(`r1') +";" + /* + */ string(`3') + "/"+ string(`r2') ) if `use'!=9 + } + +} + +if "`nextcall'"=="MD" { + + *Sort out n1 & n2 + replace `use'=9 if (`1'==.) | (`2'==.) | (`3'==.) | (`4'==.) | (`5'==.) | (`6'==.) + replace `use'=2 if ( `use'==1) & (`1' <2 | `4' <2 ) + replace `use'=2 if ( `use'==1) & (`3'<=0 | `6'<=0 ) + + if "`counts'"!="" { + replace `rawdata'= string(`1') + ", " + string(`2',"%7.3g") +" (" + string(`3',"%7.3g") + /* + */ ") ; " + string(`4') + ", " + string(`5',"%7.3g") +" (" + string(`6',"%7.3g") +") " + replace `rawdata'= trim(`rawdata') if `use' != 9 + } +} + +if "`nextcall'"=="iv_init" { + replace `use'=9 if (`1'==. | `2'==.) + if "`3'"=="" { + replace `use'=2 if (`use'==1 & `2'<=0 ) + } + else { + replace `use'=9 if (`3'==.) + replace `use'=2 if ( `2'>`1' | `3'<`1' | `3'<`2') + } +} + +if (("`sumstat'"=="OR" | "`sumstat'"=="RR") & "`log'"=="" ) { + local h0=1 +} +else if ("`sumstat'"=="ES" & "`eform'"!="") { + local h0=1 +} +else { + local h0=0 +} + + +if "`eform'"!="" { + local exp "exp" +} + + +*RJH- second estimate + +if "`method2'" != ""{ + + `nextcall' `varlist' if `use'==1, nograph notable method(`method2') `randomi' /* + */ label(`label') `wgt' `cornfield' `chi2' `cc' `standard' `log' `eform' `breslow' rjhsecond + + global MA_second_ES = $S_1 // KEEP ESTIMATES AND STICK IN SOMEWHERE LATER + global MA_second_SE_ES = $S_2 + global MA_second_LCI = $S_3 + global MA_second_UCI = $S_4 + global MA_second_TAU2 = $S_12 + global MA_second_DF = $S_8 + +} + +*Get the individual trial stats +`nextcall' `varlist' if `use'==1, nograph notable method(`method') `randomi' /* +*/ label(`label') `wgt' `cornfield' `chi2' `cc' `standard' `log' `eform' `breslow' + +if $S_8<0 { + *no trials - bomb out + exit +} + +local nostud=$S_8 + + +*need to calculate from variable itself if only 2 variables (ES, SE(ES) syntax used) +if "`sumstat'"=="ES" { + gen `effect'=`exp'(`1') + if "`3'"=="" { + gen `se'=`2' + } + else { + gen `se'=. + local var3 "var3" + } +} +else { + gen `effect'=_ES + if `h0'<0.01 { + gen `se'=_seES + } + else { + gen `se'=_selogES + } +} + +gen `lci'=_LCI +gen `uci'=_UCI +gen `weight'=_WT + +*put overall weight into var if requested +if ("`sgweight'"=="" & "`overall'"=="" ) { + gen `wtdisp'=_WT +} +else { + gen `wtdisp'=. +} + +gen `id'=_n + +*Convert "by" variable to string +* modified July 2008- keeps original order if by variable is numeric (was ignored before) +cap confirm numeric var `by' +if _rc == 0{ + tempvar by_num + cap decode `by', gen(`by_num') + if _rc != 0{ + local f: format `by' + gen `by_num' = string(`by', "`f'") + } + qui drop `by' + rename `by_num' `by' +} +cap confirm numeric var `by' + +* This replaces the old encode statement +* The _by variable is generated according to the original +* sort order of the data, and not done alpha-numerically + +qui count +local N = r(N) +gen `by2' = 1 in 1 +local lab = `by'[1] +cap label drop bylab +label define bylab 1 "`lab'" +local found1 "`lab'" +local max = 1 +forvalues i = 2/`N'{ + + local thisval = `by'[`i'] + local already = 0 + forvalues j = 1/`max'{ + if "`thisval'" == "`found`j''"{ + local already = `j' + } + } + if `already' > 0{ + replace `by2' = `already' in `i' + } + else{ + local max = `max' + 1 + replace `by2' = `max' in `i' + local lab = `by'[`i'] + label define bylab `max' "`lab'", modify + local found`max' "`lab'" + } +} + +label values `by2' bylab + + + +*Keep only neccesary data (have to put preserve here in order to keep _ES etc) +preserve + +sort `by2' `sortby' `id' +qui drop if `use' == 9 + +*Can now forget about the if/in conditions specified: unnecc rows have been removed + +*Keep tger and cger here (otherwise it ends up in last subgroup only) +if ("`sumstat'"=="OR" | "`sumstat'"=="RR" | "`sumstat'"=="RD" ) { + local tger=$S_13 + local cger=$S_14 +} + +*subgroup component of heterogeneity +gen `hetc'=. +gen `hetdf'=. +gen `hetp'=. +gen `i2'=. +gen `tau2'=. +gen `df' = . +gen `tsig'=. +gen `psig'=. + + +*Create new "by" variable to take on codes 1,2,3.. +gen `newby'=(`by2'>`by2'[_n-1]) +replace `newby'=1+sum(`newby') +local ngroups=`newby'[_N] + +if "`overall'"=="" { + + *If requested, add an extra line to contain overall stats + local nobs1=_N+1 + set obs `nobs1' + replace `use'=5 in `nobs1' + replace `newby'=`ngroups'+1 in `nobs1' + replace `effect'= ($S_1) in `nobs1' + replace `lci'=($S_3) in `nobs1' + replace `uci'=($S_4) in `nobs1' + *RJH plus another line if second estimate + if "`method2'" != ""{ + local nobs2=_N+1 + set obs `nobs2' + replace `use'=17 in `nobs2' + replace `newby'=`ngroups'+1 in `nobs2' + replace `effect'= ($MA_second_ES) in `nobs2' + replace `lci'=($MA_second_LCI) in `nobs2' + replace `uci'=($MA_second_UCI) in `nobs2' + if "`method2'" == "D+L"{ + replace `tau2' = $MA_second_TAU2 in `nobs2' + replace `hetdf' = $MA_second_DF in `nobs2' + } + } + + *Put cell counts in subtotal row + if ("`counts'"!="") { + if "`nextcall'"!="MD"{ + *put up overall binary count data + sum `1' if (`use'==1 | `use'==2) + local sum1 =r(sum) + sum `r1' if (`use'==1 | `use'==2) + local sum2 =r(sum) + sum `3' if (`use'==1 | `use'==2) + local sum3 =r(sum) + sum `r2' if (`use'==1 | `use'==2) + local sum4 =r(sum) + replace `rawdata'= "`sum1'/`sum2';`sum3'/`sum4'" in `nobs1' + } + if "`nextcall'"=="MD" { + sum `1' if (`use'==1 | `use'==2) + local sum1 =r(sum) + sum `4' if (`use'==1 | `use'==2) + local sum2 =r(sum) + replace `rawdata'= "`sum1'; `sum2'" in `nobs1' + } + } + replace `hetc' =($S_7) in `nobs1' + replace `hetdf'=($S_8) in `nobs1' + replace `hetp' =($S_9) in `nobs1' + replace `i2'=max(0, ( 100*($S_7-$S_8))/($S_7) ) in `nobs1' + if $S_8<1 { + replace `i2'=. in `nobs1' + } + replace `tau2' = $S_12 in `nobs1' + replace `df' = $S_8 in `nobs1' + replace `se'=$S_2 in `nobs1' + if "`chi2'"!="" { + replace `tsig'=$S_10 in `nobs1' + replace `psig'=$S_11 in `nobs1' + local z=$S_5 + local pz=$S_6 + } + else { + replace `tsig'=$S_5 in `nobs1' + replace `psig'=$S_6 in `nobs1' + local echi2 =$S_10 + local pchi2=$S_11 + } + replace `label' = "Overall" in `nobs1' + if "`sgweight'"=="" { + replace `wtdisp'=100 in `nobs1' + } + +} /* end if overall */ + + +*Create extra 2 or 3 lines per bygroup: one to label, one for gap +*and one for overall effect size (unless no subgroup combining is done) +*RJH- add another line if SECOND sub estimates + +sort `newby' `use' `sortby' `id' + +by `newby': gen `expand'=1 + 2*(_n==1) + (_n==1 & "`subgroup'"=="") /// + + (_n==1 & "`method2'"!="" & "`nosecsub'"=="") +replace `expand'=1 if `use'==5 | `use' == 17 +expand `expand' +gsort `newby' -`expand' `use' `sortby' `id' +by `newby': replace `use'=0 if `expand'>1 & _n==2 /* row for by label */ +by `newby': replace `use'=4 if `expand'>1 & _n==3 /* row for blank line */ +by `newby': replace `use'=3 if `expand'>1 & _n==4 /* (if specified) row to hold subgp effect sizes */ +by `newby': replace `use'=19 if `expand'>1 & _n==5 /* (if specified) RJH extra line for second estimate */ + +* blank out effect sizes in new rows +replace `effect'=. if `expand'>1 & `use'!=1 +replace `lci'=. if `expand'>1 & `use'!=1 +replace `uci'=. if `expand'>1 & `use'!=1 +replace `weight' =. if `expand'>1 & `use'!=1 +replace `rawdata' ="." if `expand'>1 & `use'!=1 + + +*Perform subgroup analyses + +local j=1 +while `j'<=`ngroups' { // HUGE LOOP THROUGH EACH SUBGROUP + + if "`subgroup'"=="" { + *First ensure the by() category has any data + count if (`newby'==`j' & `use'==1) + + if r(N)==0 { + *No data in subgroup=> fill variables with missing and move on + replace `effect'=. if (`use'==3 & `newby'==`j') + replace `lci'=. if (`use'==3 & `newby'==`j') + replace `uci'=. if (`use'==3 & `newby'==`j') + replace `wtdisp'=0 if `newby'==`j' + replace `weight'=0 if `newby'==`j' + replace `hetc'=. if `newby'==`j' + replace `hetdf'=. if `newby'==`j' + replace `hetp'=. if `newby'==`j' + replace `i2'=. if `newby'==`j' + replace `tsig'=. if `newby'==`j' + replace `psig'=. if `newby'==`j' + replace `tau2'=. if `newby'==`j' + } + else { + + /* SECOND SUB-ESTIMATES */ + if "`method2'" != "" & "`nosecsub'" == ""{ + `nextcall' `varlist' if (`newby'==`j' & `use'==1) , nograph /* + */ notable label(`label') method(`method2') `randomi' `wgt' `cornfield' `chi2' /* + */ `cc' `standard' `log' `eform' `breslow' + replace `effect'=($S_1) if `use'==19 & `newby'==`j' + replace `lci'=($S_3) if `use'==19 & `newby'==`j' + replace `uci'=($S_4) if `use'==19 & `newby'==`j' + replace `hetdf' = $S_8 if `use'==19 & `newby'==`j' + if "`method2'"=="D+L" { + replace `tau2' = $S_12 if `use'==19 & `newby'==`j' + } + } + + /* THEN GET REGULAR ESTIMATES AS USUAL */ + `nextcall' `varlist' if (`newby'==`j' & `use'==1) , nograph /* + */ notable label(`label') method(`method') `randomi' `wgt' `cornfield' `chi2' /* + */ `cc' `standard' `log' `eform' `breslow' + replace `effect'=($S_1) if `use'==3 & `newby'==`j' + replace `lci'=($S_3) if `use'==3 & `newby'==`j' + replace `uci'=($S_4) if `use'==3 & `newby'==`j' + + *Put within-subg weights in if nooverall or sgweight options specified + if ("`overall'`sgweight'"!="" ) { + replace `wtdisp'=_WT if `newby'==`j' + replace `wtdisp'=100 if (`use'==3 & `newby'==`j') + } + else { + qui sum `wtdisp' if (`use'==1 & `newby'==`j') + replace `wtdisp'=r(sum) if (`use'==3 & `newby'==`j') + } + + sum `weight' if `newby'==`j' + replace `weight'= r(sum) if `use'==3 & `newby'==`j' + replace `hetc' =($S_7) if `use'==3 & `newby'==`j' + replace `hetdf'=($S_8) if `use'==3 & `newby'==`j' + replace `hetp' =($S_9) if `use'==3 & `newby'==`j' + replace `i2'=max(0, ( 100*($S_7-$S_8))/($S_7) ) if `use'==3 & `newby'==`j' + + if $S_8<1 { + replace `i2'=. if `use'==3 & `newby'==`j' + } + if "`chi2'"!="" { + replace `tsig'=($S_10) if `use'==3 & `newby'==`j' + replace `psig'=($S_11) if `use'==3 & `newby'==`j' + } + else { + replace `tsig'=($S_5) if `use'==3 & `newby'==`j' + replace `psig'=($S_6) if `use'==3 & `newby'==`j' + } + if "`method'"=="D+L" { + replace `tau2' = $S_12 if `use'==3 & `newby'==`j' + } + + } /* END OF IF SUBGROUP N > 0 */ + + *Whether data or not - put cell counts in subtotal row if requested (will be 0/n1;0/n2 or blank if all use>1) + if "`counts'"!="" { + + *don't put up anything for MDs: + *1 Cochrane just put up N_gi. Not sure whether weighted mean should be in.. + *2 justifying N_gi is tedious! + if "`nextcall'"!="MD" { + sum `1' if (`use'==1 | `use'==2) & (`newby'==`j') + local sum1 =r(sum) + sum `r1' if (`use'==1 | `use'==2) & (`newby'==`j') + local sum2 =r(sum) + sum `3' if (`use'==1 | `use'==2) & (`newby'==`j') + local sum3 =r(sum) + sum `r2' if (`use'==1 | `use'==2) & (`newby'==`j') + local sum4 =r(sum) + replace `rawdata'= "`sum1'/`sum2';`sum3'/`sum4'" if (`use'==3 & `newby'==`j') + } + if "`nextcall'"=="MD" { + sum `1' if (`use'==1 | `use'==2) & (`newby'==`j') + local sum1 =r(sum) + sum `4' if (`use'==1 | `use'==2) & (`newby'==`j') + local sum2 =r(sum) + replace `rawdata'= "`sum1'; `sum2'" if (`use'==3 & `newby'==`j') + } + } + + } /* END OF if "`subgroup'" == "" */ + + *Label attatched (if any) to byvar + + local lbl: value label `by2' + sum `by2' if `newby'==`j' + local byvlu=r(mean) + + if "`lbl'"=="" { + local lab "`by2'==`byvlu'" + } + else { + local lab: label `lbl' `byvlu' + } + + replace `label' = "`lab'" if ( `use'==0 & `newby'==`j') + replace `label' = "Subtotal" if ( `use'==3 & `newby'==`j') + + /* RMH I-squared added in next line + RJH- also p-val as recommended by Mike Bradburn */ + + replace `label' = "Subtotal (I-squared = " + string(`i2', "%5.1f")+ "%, p = " + /// + string(`hetp', "%5.3f") + ")" if ( `use'==3 & `newby'==`j' & "$MA_nohet" == "") + local j=`j'+1 + +} /* FINALLY, THE END OF THE WHILE LOOP! */ + +replace `label' = "Overall (I-squared = " + string(`i2', "%5.1f")+ "%, p = " + /// + string(`hetp', "%5.3f") + ")" if ( `use'==5 & "$MA_nohet" == "") + +if "`subgroup'"==""{ + qui sum `hetc' if `use' == 5 + local rjhet = r(mean) + qui sum `hetc' if `use'==3 + local btwghet = (`rjhet') -r(sum) + local df = `ngroups'-1 + global rjhHetGrp = chiprob(`df',`btwghet') +} + +} /*End of quietly loop*/ + + + +*Put table up (if requested) + +tempvar rjhorder +qui gen `rjhorder' = `use' +qui replace `rjhorder' = 3.5 if `use' == 19 // SWAP ROUND SO BLANK IN RIGHT PLACE +sort `newby' `rjhorder' `sortby' `id' + +// need to ditch this if SECOND specified +if "`subgroup'" != ""{ + qui drop if `use' == 3 | `use' == 19 +} + + +if "`table'"=="" { + qui gen str20 `tlabel'=`label' + if "`overall'`wt'"=="" { + local ww "% Weight" + } + di _n in gr _col(12) "Study" _col(22) "|" _col(24) "`log'" _col(28) "`sumstat'" /* + */ _col(34) "[$IND% Conf. Interval]" _col(59) "`ww'" + di _dup(21) "-" "+" _dup(51) "-" + + + *legend for pooled confidence intervals + + local i=1 + while `i'<= _N { + + if (`use'[`i'])==0 { + *by label + di _col(6) in gr `tlabel'[`i'] + } + if "`overall'`wt'"=="" { + local ww=`wtdisp'[`i'] + } + else { + local ww + } + + if (`use'[`i'])==1 { + *trial results + di in gr `tlabel'[`i'] _col(22) "| " in ye %7.3f `effect'[`i'] /* + */ _col(35) %7.3f `lci'[`i'] " " %7.3f `uci'[`i'] _col(60) %6.2f `ww' + } + + if (`use'[`i'])==2 { + *excluded trial + di in gr `tlabel'[`i'] _col(22) "| (Excluded)" + } + + if ((`use'[`i']==3 | `use'[`i']==19) & "`subgroup'"=="") | (`use'[`i']==5 | `use'[`i']==17) { + + *Subgroup effect size or overall effect size + if (`use'[`i'])==3 { + di in gr " Sub-total" _col(22) "|" + } + if `use'[`i']==17 | `use'[`i']==5{ + if $IND!=$OVE { + local insert "[$OVE% Conf. Interval]" + } + if `use'[`i'] == 5{ + di in gr "Overall" _col(22) "|" _col(34) "`insert'" + } + } + + if "`ww'"=="." { + local ww + } + + // RJH + if `use'[`i'] == 3 | `use'[`i'] == 5{ + di in gr " `method' pooled `log'`sumstat'" _col(22) "| " in ye %7.3f /* + */ `effect'[`i'] _col(35) %7.3f `lci'[`i'] " " %7.3f `uci'[`i'] _col(60) %6.2f `ww' + } + if `use'[`i'] == 19 | `use'[`i'] == 17{ + di in gr " $MA_method2 pooled `log'`sumstat'" _col(22) "| " in ye %7.3f /* + */ `effect'[`i'] _col(35) %7.3f `lci'[`i'] " " %7.3f `uci'[`i'] + } + if (`use'[`i'])==5 & "$MA_method2" == "" | `use'[`i'] == 17{ + di in gr _dup(21) "-" "+" _dup(51) "-" + } + } + + if (`use'[`i'])==4 { + *blank line separator (need to put line here in case nosubgroup was selected) + di in gr _dup(21) "-" "+" _dup(51) "-" + } + + local i=`i'+1 + + } /* END OF WHILE LOOP */ + + *Skip next bits if nooverall AND nosubgroup + if ("`subgroup'"=="" | "`overall'"=="") { + + *part 2: user defined weight notes and heterogeneity + if ("`method'"=="*" | "`var3'"!="") { + if "`method'"=="*" { + di in gr "* note: trials pooled by user defined weight `wgt'" + } + di in bl " Heterogeneity calculated by formula" _n /* + */ " Q = SIGMA_i{ (1/variance_i)*(effect_i - effect_pooled)^2 } " + if "`var3'"!="" { + di in bl "where variance_i = ((upper limit - lower limit)/(2*z))^2 " + } + } + + di in gr _n "Test(s) of heterogeneity:" _n _col(16) "Heterogeneity degrees of" + di in gr _col(18) "statistic freedom P I-squared**" _cont + if "`method'"=="D+L" { + di in gr " Tau-squared" + } + + local maxHet = 0 + local i=1 + while `i'<= _N { + if ("`subgroup'"=="" & (`use'[`i'])==0) | ( (`use'[`i'])==5) { + if `use'[`i'] != 5{ + di in gr _n `tlabel'[`i'] _cont + } + else{ + di in gr _n "Overall" _cont + } + } + if ( ((`use'[`i'])==3) | ((`use'[`i'])==5) ) { + di in ye _col(20) %6.2f `hetc'[`i'] _col(35) %2.0f `hetdf'[`i'] /* + */ _col(43) %4.3f `hetp'[`i'] _col(51) %6.1f `i2'[`i'] "%" _cont + if `use'[`i'] == 3{ + local maxHet = max(`maxHet',`i2'[`i']) + } + if `use'[`i'] == 5{ + local ovHet = `i2'[`i'] + } + if "`method'"=="D+L" { + di in ye " " %7.4f `tau2'[`i'] _cont + } + if (`use'[`i']==5) & ("`subgroup'"=="") & ("$MA_method1" == "I-V") { // FIXED I-V ONLY + qui sum `hetc' if `use'==3 + local btwghet = (`hetc'[`i']) -r(sum) + local df = `ngroups'-1 + di _n in gr "Overall Test for heterogeneity between sub-groups: " _n /* + */ in ye _col(20) %6.2f `btwghet' _col(35) %2.0f `df' _col(43) %4.3f /* + */ (chiprob(`df',`btwghet')) + + } + } + local i=`i'+1 + } + + di _n in gr "** I-squared: the variation in `sumstat' attributable to heterogeneity)" _n + + // DISPLAY BETWEEN-GROUP TEST WARNINGS + if "`overall'" == ""{ + if `maxHet' < 50 & `maxHet' > 0 & ("$MA_method1" == "I-V"){ + di in gr "Some heterogeneity observed (up to "%4.1f `maxHet' "%) in one or more sub-groups," + di in gr "Test for heterogeneity between sub-groups may be invalid" + } + if `maxHet' < 75 & `maxHet' >= 50 & ("$MA_method1" == "I-V"){ + di in gr "Moderate heterogeneity observed (up to "%4.1f `maxHet' "%) in one or more sub-groups," + di in gr "Test for heterogeneity between sub-groups likely to be invalid" + } + if `maxHet' < . & `maxHet' >= 75 & ("$MA_method1" == "I-V"){ + di in gr "Considerable heterogeneity observed (up to "%4.1f `maxHet' "%) in one or more sub-groups," + di in gr "Test for heterogeneity between sub-groups likely to be invalid" + } + if "$MA_method1" != "I-V"{ + di in gr "Note: between group heterogeneity not calculated;" + di in gr "only valid with inverse variance method" + } + } + *part 3: test statistics + di _n in gr "Significance test(s) of `log'`sumstat'=`h0'" + + local i=1 + while `i'<= _N { + + if ("`subgroup'"=="" & (`use'[`i'])==0) | ( (`use'[`i'])==5) { + if `use'[`i'] != 5{ + di in gr _n `tlabel'[`i'] _cont + } + else{ + di in gr _n "Overall" _cont + } + } + + if ( ((`use'[`i'])==3) | ((`use'[`i'])==5) ) { + if "`chi2'"!="" { + di in gr _col(20) "chi-squared = " in ye %5.2f `tsig'[`i'] /* + */ in gr _col(35) " (d.f. = 1) p = " in ye %4.3f `psig'[`i'] _cont + } + else { + di in gr _col(23) "z= " in ye %5.2f `tsig'[`i'] _col(35) in gr /* + */ " p = " in ye %4.3f `psig'[`i'] _cont + } + } + local i=`i'+1 + } + di _n in gr _dup(73) "-" + + } /* end of if ("`subgroup'"=="" | "`overall'"=="") */ + +} /* end of table display */ + + + +if "`overall'"=="" { + + *need to return overall effect to $S_1 macros and so on... + local N = _N + if "$MA_method2" != ""{ + local N = _N-1 + } + + global S_1=`effect'[`N'] + global S_2=`se'[`N'] + global S_3=`lci'[`N'] + global S_4=`uci'[`N'] + global S_7=`hetc'[`N'] + global S_8=`hetdf'[`N'] + global S_9=`hetp'[`N'] + global S_51 =`i2'[`N'] + + if "`chi2'"!="" { + global S_10=`tsig'[`N'] + global S_11=`psig'[`N'] + global S_5=`z' + global S_6=`pz' + } + else { + global S_5=`tsig'[`N'] + global S_6=`psig'[`N'] + global S_10=`echi2' + global S_11=`pchi2' + } + + global S_12=`tau2'[`N'] + if ("`sumstat'"=="OR" | "`sumstat'"=="RR" | "`sumstat'"=="RD" ) { + global S_13=`tger' + global S_14=`cger' + } + +} /* end if overall */ + +else { + forvalues i = 1/14{ + global S_`i' . + } +} + + +if "`graph'"=="" { + + _dispgby `effect' `lci' `uci' `weight' `use' `label' `rawdata' `wtdisp' `tau2' `hetdf', /* + */ `log' `xlabel' `xtick' `force' sumstat(`sumstat') `saving' `box' t1("`t1'") /* + */ t2("`t2'") b1("`b1'") b2("`b2'") lcols("`lcols'") rcols("`rcols'") `overall' `wt' `stats' `counts' `eform' /* + */ `groupla' `cornfield' + +} + +restore + +if "`keep'"=="" { + + qui{ + + if ("`sumstat'"=="OR" | "`sumstat'"=="RR") & ("`log'"=="") { + local ln "log" + } + else { + local ln + } + + cap drop _ES + cap drop _seES + cap drop _selogES + + if "`sumstat'"!="ES" { + #delimit ; + replace _SS =. if `use'!=1; label var _SS "Sample size"; + gen _ES =`effect';label var _ES "`log'`sumstat'"; + gen _se`ln'ES=`se';label var _se`ln'ES "se(`ln'`log'`sumstat')"; + #delimit cr + } + #delimit ; + cap drop _LCI ; cap drop _UCI; cap drop _WT; + gen _LCI =`lci'; label var _LCI "Lower CI (`log'`sumstat')"; + gen _UCI =`uci'; label var _UCI "Upper CI (`log'`sumstat')"; + #delimit cr + + *correct weight if subgroup weights given + if ("`sgweight'"=="" & "`overall'"=="" ) { + gen _WT=`weight' + } + else if "`subgroup'"=="" & ("`overall'`sgweight'"!="" ) { + tempvar tempsum ordering + gen `ordering' = _n + bysort `by2': gen `tempsum'=sum(`weight') + + local N = _N + if "$MA_method2" != ""{ + local N = _N-1 + } + bysort `by2': replace `tempsum'=`tempsum'[`N'] + gen _WT=`weight'*100/`tempsum' + local sg "(subgroup) " + sort `ordering' + } + cap label var _WT "`method' `sg'% weight" + + } /* end qui */ + +} /* end if keep */ + +end + + + +********************************************************** +*** *** +*** NEW *** +*** _DISPGBY PROGRAM *** +*** ROSS HARRIS *** +*** JULY 2006 *** +*** * * * *** +*** *** +********************************************************** + +program define _dispgby +version 9.0 + +// AXmin AXmax ARE THE OVERALL LEFT AND RIGHT COORDS +// DXmin dxMAX ARE THE LEFT AND RIGHT COORDS OF THE GRAPH PART + +#delimit ; +syntax varlist(min=6 max=10 default=none ) [if] [in] [, + LOG XLAbel(string) XTICK(string) FORCE SAVING(string) noBOX SUMSTAT(string) + T1(string) T2(string) B1(string) B2(string) LCOLS(string) /* JUNK NOW */ + RCOLS(string) noOVERALL noWT noSTATS COUNTS EFORM + noGROUPLA CORNFIELD]; +#delimit cr +tempvar effect lci uci weight wtdisp use label tlabel id yrange xrange Ghsqrwt rawdata i2 mylabel +tokenize "`varlist'", parse(" ") + +qui{ + +gen `effect'=`1' +gen `lci' =`2' + +gen `uci' =`3' +gen `weight'=`4' // was 4 +gen byte `use'=`5' +gen str `label'=`6' +gen str `mylabel'=`6' + +if "`lcols'" == ""{ + local lcols "`mylabel'" + label var `mylabel' "Study ID" +} + +gen str80 `rawdata' = `7' +compress `rawdata' + +if "`8'"!="" & "$MA_rjhby" != ""{ + gen `wtdisp'=`8' +} +else { + gen `wtdisp'=`weight' +} + +if "`10'" != "" & "$MA_rjhby" != ""{ + tempvar tau2 df + gen `tau2' = `9' + gen `df' = `10' +} +if "`9'" != "" & "$MA_rjhby" == ""{ // DIFFERENT IF FROM metan OR metanby + tempvar tau2 df + gen `tau2' = `8' + gen `df' = `9' +} +replace `weight' = `wtdisp' // bodge solu for SG weights + +if "$MA_summaryonly" != ""{ + drop if `use' == 1 +} + +// SET UP EXTENDED CIs FOR RANDOM EFFECTS DISTRIBUTION +// THIS CODE IS A BIT NASTY AS I SET THIS UP BADLY INITIALLY +// REQUIRES MAJOR REWORK IDEALLY... + +tempvar tauLCI tauUCI SE tauLCIinf tauUCIinf +*replace `tau2' = .a if `tau2' == 0 // no heterogeneity +replace `tau2' = .b if `df'-1 == 0 // inestimable predictive distribution +replace `tau2' = . if (`use' == 5 | `use' == 3) & "$MA_method1" != "D+L" +replace `tau2' = . if (`use' == 17 | `use' == 19) & "$MA_method2" != "D+L" + +gen `tauLCI' = . +gen `tauUCI' = . +gen `tauLCIinf' = . +gen `tauUCIinf' = . +gen `SE' = . + + +// modified so rf CI (rflevel) used +if "$MA_rfdist" != ""{ + if ( ("`sumstat'"=="OR" | "`sumstat'"=="RR") & ("`log'"=="") ) | ("`eform'"!="") { + replace `SE' = (ln(`uci')-ln(`lci')) / (invnorm($RFL/200+0.5)*2) + replace `tauLCI' = exp( ln(`effect') - invttail((`df'-1), 0.5-$RFL/200)*sqrt( `tau2' +`SE'^2 ) ) + replace `tauUCI' = exp( ln(`effect') + invttail((`df'-1), 0.5-$RFL/200)*sqrt( `tau2' +`SE'^2 ) ) + replace `tauLCI' = 1e-9 if `tau2' == .b + replace `tauUCI' = 1e9 if `tau2' == .b + } + else{ + replace `SE' = (`uci'-`lci') / ($RFL/200+0.5) + replace `tauLCI' = `effect'-invttail((`df'-1), 0.5-$RFL/200)*sqrt(`tau2'+`SE'^2) + replace `tauUCI' = `effect'+invttail((`df'-1), 0.5-$RFL/200)*sqrt(`tau2'+`SE'^2) + replace `tauLCI' = -1e9 if `tau2' == .b + replace `tauUCI' = 1e9 if `tau2' == .b + } +} + + +if "$MA_rfdist" != ""{ + qui count + local prevN = r(N) + tempvar expTau orderTau + gen `orderTau' = _n + gen `expTau' = 1 + replace `expTau' = 2 if `tau2' != . // but expand if .a or .b + expand `expTau' + replace `use' = 4 if _n > `prevN' + replace `orderTau' = `orderTau' + 0.5 if _n > `prevN' + sort `orderTau' +} + +tempvar estText weightText RFdistText RFdistLabel +local dp = $MA_dp +gen str `estText' = string(`effect', "%10.`dp'f") + " (" + string(`lci', "%10.`dp'f") + ", " +string(`uci', "%10.`dp'f") + ")" +replace `estText' = "(Excluded)" if `use' == 2 + +// don't show effect size again, just CI +gen `RFdistLabel' = "with estimated predictive interval" if `use' == 4 & `tau2' < . +gen `RFdistText' = /* string(`effect', "%10.`dp'f") + */ ". (" + string(`tauLCI', "%10.`dp'f") + ", " +string(`tauUCI', "%10.`dp'f") /// + + ")" if `use' == 4 & `tau2' < . + +/* not used +replace `RFdistLabel' = "No observed heterogeneity" if `use' == 4 & `tau2' == .a +replace `RFdistText' = string(`effect', "%10.`dp'f") + " (" + string(`lci', "%10.`dp'f") + ", " +string(`uci', "%10.`dp'f") /// + + ")" if `use' == 4 & `tau2' == .a +*/ + +// don't show effect size again, just CI +replace `RFdistLabel' = "Inestimable predictive distribution with <3 studies" if `use' == 4 & `tau2' == .b +replace `RFdistText' = /* string(`effect', "%4.2f") + */ ". ( - , - )" if `use' == 4 & `tau2' == .b + + +qui replace `estText' = " " + `estText' if `effect' >= 0 & `use' != 4 +gen str `weightText' = string(`weight', "%4.2f") + +replace `weightText' = "" if `use' == 17 | `use' == 19 // can cause confusion and not necessary +replace `rawdata' = "" if `use' == 17 | `use' == 19 + +if "`counts'" != ""{ + if $MA_params == 6{ + local type "N, mean (SD);" + } + else{ + local type "Events," + } + tempvar raw1 raw2 + gen str `raw1' = substr(`rawdata',1,(strpos(`rawdata',";")-1) ) + gen str `raw2' = substr(`rawdata',(strpos(`rawdata',";")+1), (length(`rawdata')) ) + label var `raw1' "`type' $MA_G1L" + label var `raw2' "`type' $MA_G2L" +} + + +/* RJH - probably a better way to get this but I've just used globals from earlier */ + +if "`overall'" == "" & "$MA_nohet" == ""{ + if "$MA_method1" == "USER"{ + if "$MA_firststats" != ""{ + replace `label' = "Overall ($MA_firststats)" if `use'==5 + } + else{ + replace `label' = "Overall" if `use'==5 + } + } + replace `label' = "Overall ($MA_secondstats)" if `use' == 17 & "$MA_method2" == "USER" & "$MA_secondstats" != "" + replace `label' = "Overall" if `use' == 17 & "$MA_method2" == "USER" & "$MA_secondstats" == "" +} +if "`overall'" == "" & "$MA_nohet" != ""{ + replace `label' = "Overall" if `use' == 5 | `use' == 17 +} + +tempvar hetGroupLabel expandOverall orderOverall +if "$MA_rjhby" != "" & "$MA_nohet" == "" & "$MA_method1" == "I-V"{ +* replace `label' = `label' + ";" if `use' == 5 + qui count + local prevMax = r(N) + gen `orderOverall' = _n + gen `expandOverall' = 1 + replace `expandOverall' = 2 if `use' == 5 + expand `expandOverall' + replace `orderOverall' = `orderOverall' -0.5 if _n > `prevMax' + gen `hetGroupLabel' = "Heterogeneity between groups: p = " + /// + string($rjhHetGrp, "%5.3f") if _n > `prevMax' + replace `use' = 4 if _n > `prevMax' + sort `orderOverall' +} +else{ + gen `hetGroupLabel' = . +} + +replace `label' = "Overall" if `use' == 17 & "$MA_method2" != "USER" +replace `label' = "Subtotal" if `use' == 19 + +qui count if (`use'==1 | `use'==2) +local ntrials=r(N) +qui count if (`use'>=0 & `use'<=5) +local ymax=r(N) +gen `id'=`ymax'-_n+1 if `use'<9 | `use' == 17 | `use' == 19 + +if "$MA_method2" != "" | "$MA_method1" == "USER" { + local dispM1 = "$MA_method1" + local dispM2 = "$MA_method2" + if "$MA_method1" == "USER"{ + local dispM1 "$MA_userDescM" + } + if "$MA_method2" == "USER"{ + local dispM2 "$MA_userDesc" + } + replace `label' = "`dispM1'" + " " + `label' if (`use' == 3 | `use' == 5) & substr(`label',1,3) != "het" + replace `label' = "`dispM2'" + " " + `label' if `use' == 17 | `use' == 19 +} + + +// GET MIN AND MAX DISPLAY +// SORT OUT TICKS- CODE PINCHED FROM MIKE AND FIDDLED. TURNS OUT I'VE BEEN USING SIMILAR NAMES... +// AS SUGGESTED BY JS JUST ACCEPT ANYTHING AS TICKS AND RESPONSIBILITY IS TO USER! + +qui summ `lci', detail +local DXmin = r(min) +qui summ `uci', detail +local DXmax = r(max) +local h0 = 0 + +// MIKE MAKES A MAX VALUE IF SOMETHING EXTREME OCCURS... +if (( ("`sumstat'"=="OR" | "`sumstat'"=="RR") & ("`log'"=="") ) | ("`eform'"!="")) { + local h0=1 + local Glog "xlog" + local xlog "log" + local xexp "exp" + replace `lci'=1e-9 if `lci'<1e-8 + replace `lci'=1e9 if `lci'>1e8 & `lci'!=. + replace `uci'=1e-9 if `uci'<1e-8 + replace `uci'=1e9 if `uci'>1e8 & `uci'!=. + if `DXmin'<1e-8 { + local DXmin=1e-8 + } + if `DXmax'>1e8 { + local DXmax=1e8 + } +} +if "$MA_NULL" != ""{ + local h0 = $MA_NULL +} +if `h0' != 0 & `h0' != 1{ + noi di "Null specified as `h0' in graph- for most effect measures null is 0 or 1" +} + +if "`cornfield'"!="" { + replace `lci'=`log'(1e-9) if ( (`lci'==. | `lci'==0) & (`effect'!=. & `use'==1) ) + replace `uci'=`log'(1e9) if ( (`uci'==.) & (`effect'!=. & `use'==1) ) +} + +// THIS BIT CHANGED- THE USER CAN PUT ANYTHING IN + +local flag1=0 +if ("`xlabel'"=="" | "`xtick'" == "") & "$MA_nulloff" == ""{ // if no xlabel or tick + local xtick "`h0'" +} + +if "`xlabel'"==""{ + local Gmodxhi=max( abs(`xlog'(`DXmin')),abs(`xlog'(`DXmax'))) + if `Gmodxhi'==. { + local Gmodxhi=2 + } + local DXmin=`xexp'(-`Gmodxhi') + local DXmax=`xexp'( `Gmodxhi') + if "$MA_nulloff" == ""{ + local xlabel "`DXmin',`h0',`DXmax'" + } + else{ + local xlabel "`DXmin',`DXmax'" + } +} + +local DXmin2 = min(`xlabel',`DXmin') +local DXmax2 = max(`xlabel',`DXmax') +if "`force'" == ""{ + local Gmodxhi=max( abs(`xlog'(`DXmin')), abs(`xlog'(`DXmax')), /// + abs(`xlog'(`DXmin2')), abs(`xlog'(`DXmax2')) ) + if `Gmodxhi'==. { + local Gmodxhi=2 + } + local DXmin=`xexp'(-`Gmodxhi') + local DXmax=`xexp'( `Gmodxhi') + if "`xlabel'" != "" & "$MA_nulloff" == ""{ + local xlabel "`h0',`xlabel'" + } +} + +if "`force'" != ""{ + local DXmin = min(`xlabel') + local DXmax = max(`xlabel') + if "$MA_nulloff" == ""{ + local xlabel "`h0',`xlabel'" + } +} + +// LABELS- DON'T ALLOW SILLY NO. OF DECIMAL PLACES + +local lblcmd "" +tokenize "`xlabel'", parse(",") +while "`1'" != ""{ + if "`1'" != ","{ + local lbl = string(`1',"%7.3g") + local val = `1' + local lblcmd `lblcmd' `val' "`lbl'" + } + mac shift +} +if "`xtick'" == ""{ + local xtick = "`xlabel'" +} + +local xtick2 = "" +tokenize "`xtick'", parse(",") +while "`1'" != ""{ + if "`1'" != ","{ + local xtick2 = "`xtick2' " + string(`1') + } + if "`1'" == ","{ + local xtick2 = "`xtick2'`1'" + } + mac shift +} +local xtick = "`xtick2'" + +local DXmin=`xlog'(min(`xlabel',`xtick',`DXmin')) +local DXmax=`xlog'(max(`xlabel',`xtick',`DXmax')) + +if ("`eform'" != "" | "`xlog'" != "") { + local lblcmd "" + tokenize "`xlabel'", parse(",") + while "`1'" != ""{ + if "`1'" != ","{ + local lbl = string(`1',"%7.3g") + local val = ln(`1') + local lblcmd `lblcmd' `val' "`lbl'" + } + mac shift + } + + replace `effect' = ln(`effect') + replace `lci' = ln(`lci') + replace `uci' = ln(`uci') + replace `tauLCI' = ln(`tauLCI') + replace `tauUCI' = ln(`tauUCI') + local xtick2 "" + tokenize "`xtick'", parse(",") + while "`1'" != ""{ + if "`1'" != ","{ + local ln = ln(`1') + local xtick2 "`xtick2' `ln'" + } + if "`1'" == ","{ + local xtick2 "`xtick2'`1'" + } + mac shift + } + local xtick "`xtick2'" + local h0 = 0 +} + +// JUNK +*noi di "min: `DXmin', `DXminLab'; h0: `h0', `h0Lab'; max: `DXmax', `DXmaxLab'" + +local DXwidth = `DXmax'-`DXmin' +if `DXmin' > 0{ + local h0 = 1 +} + +} // END QUI + +// END OF TICKS AND LABLES + +// MAKE OFF-SCALE ARROWS + +qui{ +tempvar offLeftX offLeftX2 offRightX offRightX2 offYlo offYhi + +local arrowWidth = 0.02 // FRACTION OF GRAPH WIDTH +local arrowHeight = 0.5/2 // Y SCALE IS JUST ORDERED NUMBER- 2x0.25 IS 0.5 OF AVAILABLE SPACE + +gen `offLeftX' = `DXmin' if `lci' < `DXmin' | `tauLCI' < `DXmin' +gen `offLeftX2' = `DXmin' + `DXwidth'*`arrowWidth' if `lci' < `DXmin' | `tauLCI' < `DXmin' + +gen `offRightX' = `DXmax' if `uci' > `DXmax' | (`tauUCI' > `DXmax' & `tauLCI' < .) +gen `offRightX2' = `DXmax' - `DXwidth'*`arrowWidth' if `uci' > `DXmax' | (`tauUCI' > `DXmax' & `tauLCI' < .) + +gen `offYlo' = `id' - `arrowHeight' +gen `offYhi' = `id' + `arrowHeight' + +replace `lci' = `DXmin' if `lci' < `DXmin' & (`use' == 1 | `use' == 2) +replace `uci' = `DXmax' if `uci' > `DXmax' & (`use' == 1 | `use' == 2) +replace `lci' = . if `uci' < `DXmin' & (`use' == 1 | `use' == 2) +replace `uci' = . if `lci' > `DXmax' & (`use' == 1 | `use' == 2) +replace `effect' = . if `effect' < `DXmin' & (`use' == 1 | `use' == 2) +replace `effect' = . if `effect' > `DXmax' & (`use' == 1 | `use' == 2) +} // end qui + +************************ +** COLUMNS ** +************************ + +// OPTIONS FOR L-R JUSTIFY? +// HAVE ONE MORE COL POSITION THAN NECESSARY, COULD THEN R-JUSTIFY +// BY ADDING 1 TO LOOP, ALSO HAVE MAX DIST FOR OUTER EDGE +// HAVE USER SPECIFY % OF GRAPH USED FOR TEXT? + +qui{ // KEEP QUIET UNTIL AFTER DIAMONDS +local titleOff = 0 + +if "`lcols'" == ""{ + local lcols = "`label'" + local titleOff = 1 +} + +// DOUBLE LINE OPTION +if "$MA_DOUBLE" != "" & ("`lcols'" != "" | "`rcols'" != ""){ + tempvar expand orig + gen `orig' = _n + gen `expand' = 1 + replace `expand' = 2 if `use' == 1 + expand `expand' + sort `orig' + replace `id' = `id' - 0.45 if `id' == `id'[_n-1] + replace `use' = 2 if mod(`id',1) != 0 & `use' != 5 + replace `effect' = . if mod(`id',1) != 0 + replace `lci' = . if mod(`id',1) != 0 + replace `uci' = . if mod(`id',1) != 0 + replace `estText' = "" if mod(`id',1) != 0 + cap replace `raw1' = "" if mod(`id',1) != 0 + cap replace `raw2' = "" if mod(`id',1) != 0 + replace `weightText' = "" if mod(`id',1) != 0 + + foreach var of varlist `lcols' `rcols'{ + cap confirm string var `var' + if _rc == 0{ + + tempvar length words tosplit splitwhere best + gen `splitwhere' = 0 + gen `best' = . + gen `length' = length(`var') + summ `length', det + gen `words' = wordcount(`var') + gen `tosplit' = 1 if `length' > r(max)/2+1 & `words' >= 2 + summ `words', det + local max = r(max) + forvalues i = 1/`max'{ + replace `splitwhere' = strpos(`var',word(`var',`i')) /// + if abs( strpos(`var',word(`var',`i')) - length(`var')/2 ) < `best' /// + & `tosplit' == 1 + replace `best' = abs(strpos(`var',word(`var',`i')) - length(`var')/2) /// + if abs(strpos(`var',word(`var',`i')) - length(`var')/2) < `best' + } + + replace `var' = substr(`var',1,(`splitwhere'-1)) if `tosplit' == 1 & mod(`id',1) == 0 + replace `var' = substr(`var',`splitwhere',length(`var')) if `tosplit' == 1 & mod(`id',1) != 0 + replace `var' = "" if `tosplit' != 1 & mod(`id',1) != 0 & `use' != 5 + drop `length' `words' `tosplit' `splitwhere' `best' + } + if _rc != 0{ + replace `var' = . if mod(`id',1) != 0 & `use' != 5 + } + } +} + +summ `id' if `use' != 9 +local max = r(max) +local new = r(N)+4 +if `new' > _N { + set obs `new' +} + +forvalues i = 1/4{ // up to four lines for titles + local multip = 1 + local add = 0 + if "$MA_DOUBLE" != ""{ // DOUBLE OPTION- CLOSER TOGETHER, GAP BENEATH + local multip = 0.45 + local add = 0.5 + } + local idNew`i' = `max' + `i'*`multip' + `add' + local Nnew`i'=r(N)+`i' + local tmp = `Nnew`i'' + replace `id' = `idNew`i'' + 1 in `tmp' + replace `use' = 1 in `tmp' + if `i' == 1{ + global borderline = `idNew`i''-0.25 + } +} + +local maxline = 1 +if "`lcols'" != ""{ + tokenize "`lcols'" + local lcolsN = 0 + + while "`1'" != ""{ + cap confirm var `1' + if _rc!=0 { + di in re "Variable `1' not defined" + exit _rc + } + local lcolsN = `lcolsN' + 1 + tempvar left`lcolsN' leftLB`lcolsN' leftWD`lcolsN' + cap confirm string var `1' + if _rc == 0{ + gen str `leftLB`lcolsN'' = `1' + } + if _rc != 0{ + cap decode `1', gen(`leftLB`lcolsN'') + if _rc != 0{ + local f: format `1' + gen str `leftLB`lcolsN'' = string(`1', "`f'") + replace `leftLB`lcolsN'' = "" if `leftLB`lcolsN'' == "." + } + } + replace `leftLB`lcolsN'' = "" if (`use' != 1 & `use' != 2) + local colName: variable label `1' + if "`colName'"==""{ + local colName = "`1'" + } + + // WORK OUT IF TITLE IS BIGGER THAN THE VARIABLE + // SPREAD OVER UP TO FOUR LINES IF NECESSARY + local titleln = length("`colName'") + tempvar tmpln + gen `tmpln' = length(`leftLB`lcolsN'') + qui summ `tmpln' if `use' != 0 + local otherln = r(max) + drop `tmpln' + // NOW HAVE LENGTH OF TITLE AND MAX LENGTH OF VARIABLE + local spread = int(`titleln'/`otherln')+1 + if `spread'>4{ + local spread = 4 + } + + local line = 1 + local end = 0 + local count = -1 + local c2 = -2 + + local first = word("`colName'",1) + local last = word("`colName'",`count') + local nextlast = word("`colName'",`c2') + + while `end' == 0{ + replace `leftLB`lcolsN'' = "`last'" + " " + `leftLB`lcolsN'' in `Nnew`line'' + local check = `leftLB`lcolsN''[`Nnew`line''] + " `nextlast'" // what next will be + + local count = `count'-1 + local last = word("`colName'",`count') + if "`last'" == ""{ + local end = 1 + } + + if length(`leftLB`lcolsN''[`Nnew`line'']) > `titleln'/`spread' | /// + length("`check'") > `titleln'/`spread' & "`first'" == "`nextlast'"{ + if `end' == 0{ + local line = `line'+1 + } + } + } + if `line' > `maxline'{ + local maxline = `line' + } + + mac shift + } +} + +if `titleOff' == 1 { + forvalues i = 1/4{ + replace `leftLB1' = "" in `Nnew`i'' // get rid of horrible __var name + } +} +replace `leftLB1' = `label' if `use' != 1 & `use' != 2 // put titles back in (overall, sub est etc.) + +// STUFF ADDED FOR JS TO INCLUDE EFFICACY AS COLUMN WITH OVERALL + +*effect lci uci tempvars +if "$MA_efficacy" != ""{ + tempvar vetemp ucivetemp lcivetemp vaccine_efficacy + qui { + gen `vetemp'=100*(1-exp(`effect')) + tostring `vetemp', replace force format(%4.0f) + + gen `ucivetemp'=100*(1-exp(`lci')) + tostring `ucivetemp', replace force format(%4.0f) + + gen `lcivetemp'=100*(1-exp(`uci')) + tostring `lcivetemp', replace force format(%4.0f) + + gen str30 `vaccine_efficacy'=`vetemp'+" ("+`lcivetemp'+", "+`ucivetemp'+")" if `effect' != . + label var `vaccine_efficacy' "Vaccine efficacy (%)" + + local rcols = "`vaccine_efficacy' " + "`rcols' " + + } +} + +if "`wt'" == ""{ + local rcols = "`weightText' " + "`rcols'" + if "$MA_method2" != ""{ + label var `weightText' "% Weight ($MA_method1)" + } + else{ + label var `weightText' "% Weight" + } +} +if "`counts'" != ""{ + local rcols = "`raw1' " + "`raw2' " + "`rcols'" +} +if "`stats'" == ""{ + local rcols = "`estText' " + "`rcols'" + if "$MA_ESLA" == ""{ + global MA_ESLA = "`sumstat'" + } + label var `estText' "$MA_ESLA ($IND% CI)" +} + +tempvar extra +gen `extra' = "" +label var `extra' " " +local rcols = "`rcols' `extra'" + +local rcolsN = 0 +if "`rcols'" != ""{ + tokenize "`rcols'" + local rcolsN = 0 + while "`1'" != ""{ + cap confirm var `1' + if _rc!=0 { + di in re "Variable `1' not defined" + exit _rc + } + local rcolsN = `rcolsN' + 1 + tempvar right`rcolsN' rightLB`rcolsN' rightWD`rcolsN' + cap confirm string var `1' + if _rc == 0{ + gen str `rightLB`rcolsN'' = `1' + } + if _rc != 0{ + local f: format `1' + gen str `rightLB`rcolsN'' = string(`1', "`f'") + replace `rightLB`rcolsN'' = "" if `rightLB`rcolsN'' == "." + } + local colName: variable label `1' + if "`colName'"==""{ + local colName = "`1'" + } + + // WORK OUT IF TITLE IS BIGGER THAN THE VARIABLE + // SPREAD OVER UP TO FOUR LINES IF NECESSARY + local titleln = length("`colName'") + tempvar tmpln + gen `tmpln' = length(`rightLB`rcolsN'') + qui summ `tmpln' if `use' != 0 + local otherln = r(max) + drop `tmpln' + // NOW HAVE LENGTH OF TITLE AND MAX LENGTH OF VARIABLE + local spread = int(`titleln'/`otherln')+1 + if `spread'>4{ + local spread = 4 + } + + local line = 1 + local end = 0 + local count = -1 + local c2 = -2 + + local first = word("`colName'",1) + local last = word("`colName'",`count') + local nextlast = word("`colName'",`c2') + + while `end' == 0{ + replace `rightLB`rcolsN'' = "`last'" + " " + `rightLB`rcolsN'' in `Nnew`line'' + local check = `rightLB`rcolsN''[`Nnew`line''] + " `nextlast'" // what next will be + + local count = `count'-1 + local last = word("`colName'",`count') + if "`last'" == ""{ + local end = 1 + } + if length(`rightLB`rcolsN''[`Nnew`line'']) > `titleln'/`spread' | /// + length("`check'") > `titleln'/`spread' & "`first'" == "`nextlast'"{ + if `end' == 0{ + local line = `line'+1 + } + } + } + if `line' > `maxline'{ + local maxline = `line' + } + + mac shift + } +} + +// now get rid of extra title rows if they weren't used + + +if `maxline'==3{ + drop in `Nnew4' +} +if `maxline'==2{ + drop in `Nnew3'/`Nnew4' +} +if `maxline'==1{ + drop in `Nnew2'/`Nnew4' +} + + +/* BODGE SOLU- EXTRA COLS */ +while `rcolsN' < 2{ + local rcolsN = `rcolsN' + 1 + tempvar right`rcolsN' rightLB`rcolsN' rightWD`rcolsN' + gen str `rightLB`rcolsN'' = " " +} + + +local skip = 1 +if "`stats'" == "" & "`wt'" == ""{ // sort out titles for stats and weight, if there + local skip = 3 +} + +if "`stats'" != "" & "`wt'" == ""{ + local skip = 2 +} +if "`stats'" == "" & "`wt'" != ""{ + local skip = 2 +} +if "`counts'" != ""{ + local skip = `skip' + 2 +} +if "$MA_efficacy" != ""{ + local skip = `skip' + 1 +} + +/* SET TWO DUMMY RCOLS IF NOSTATS NOWEIGHT */ + +forvalues i = `skip'/`rcolsN'{ // get rid of junk if not weight, stats or counts + replace `rightLB`i'' = "" if (`use' != 1 & `use' != 2) +} +forvalues i = 1/`rcolsN'{ + replace `rightLB`i'' = "" if (`use' ==0) +} + +local leftWDtot = 0 +local rightWDtot = 0 +local leftWDtotNoTi = 0 + +forvalues i = 1/`lcolsN'{ + getWidth `leftLB`i'' `leftWD`i'' + qui summ `leftWD`i'' if `use' != 0 & `use' != 4 & `use' != 3 & `use' != 5 & /// + `use' != 17 & `use' != 19 // DON'T INCLUDE OVERALL STATS AT THIS POINT + local maxL = r(max) + local leftWDtotNoTi = `leftWDtotNoTi' + `maxL' + replace `leftWD`i'' = `maxL' +} +tempvar titleLN // CHECK IF OVERALL LENGTH BIGGER THAN REST OF LCOLS +getWidth `leftLB1' `titleLN' +qui summ `titleLN' if `use' != 0 & `use' != 4 +local leftWDtot = max(`leftWDtotNoTi', r(max)) + +forvalues i = 1/`rcolsN'{ + getWidth `rightLB`i'' `rightWD`i'' + qui summ `rightWD`i'' if `use' != 0 & `use' != 4 + replace `rightWD`i'' = r(max) + local rightWDtot = `rightWDtot' + r(max) +} + +// CHECK IF NOT WIDE ENOUGH (I.E., OVERALL INFO TOO WIDE) +// LOOK FOR EDGE OF DIAMOND summ `lci' if `use' == ... + +tempvar maxLeft +getWidth `leftLB1' `maxLeft' +qui count if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19 +if r(N) > 0{ + summ `maxLeft' if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19 // NOT TITLES THOUGH! + local max = r(max) + if `max' > `leftWDtotNoTi'{ + // WORK OUT HOW FAR INTO PLOT CAN EXTEND + // WIDTH OF LEFT COLUMNS AS FRACTION OF WHOLE GRAPH + local x = `leftWDtot'*($MA_AS_TEXT/100)/(`leftWDtot'+`rightWDtot') + tempvar y + // SPACE TO LEFT OF DIAMOND WITHIN PLOT (FRAC OF GRAPH) + gen `y' = ((100-$MA_AS_TEXT)/100)*(`lci'-`DXmin') / (`DXmax'-`DXmin') + qui summ `y' if `use' == 3 | `use' == 5 + local extend = 1*(r(min)+`x')/`x' + local leftWDtot = max(`leftWDtot'/`extend',`leftWDtotNoTi') // TRIM TO KEEP ON SAFE SIDE + // ALSO MAKE SURE NOT LESS THAN BEFORE! + } + +} + +global LEFT_WD = `leftWDtot' +global RIGHT_WD = `rightWDtot' + + +local ratio = $MA_AS_TEXT // USER SPECIFIED- % OF GRAPH TAKEN BY TEXT (ELSE NUM COLS CALC?) +local textWD = (`DXwidth'/(1-`ratio'/100)-`DXwidth') /(`leftWDtot'+`rightWDtot') + +forvalues i = 1/`lcolsN'{ + gen `left`i'' = `DXmin' - `leftWDtot'*`textWD' + local leftWDtot = `leftWDtot'-`leftWD`i'' +} + +gen `right1' = `DXmax' +forvalues i = 2/`rcolsN'{ + local r2 = `i'-1 + gen `right`i'' = `right`r2'' + `rightWD`r2''*`textWD' +} + +local AXmin = `left1' +local AXmax = `DXmax' + `rightWDtot'*`textWD' + +foreach type in "" "inf"{ + replace `tauLCI`inf'' = `DXmin' if `tauLCI' < `DXmin' & `tauLCI`inf'' != . + replace `tauLCI`inf'' = . if `lci' < `DXmin' + replace `tauLCI`inf'' = . if `tauLCI`inf'' > `lci' + + replace `tauUCI`inf'' = `DXmax' if `tauUCI`inf'' > `DXmax' & `tauUCI`inf'' != . + replace `tauUCI`inf'' = . if `uci' > `DXmax' + replace `tauUCI`inf'' = . if `tauUCI`inf'' < `uci' + + replace `tauLCI`inf'' = . if (`use' == 3 | `use' == 5) & "$MA_method1" != "D+L" + replace `tauUCI`inf'' = . if (`use' == 3 | `use' == 5) & "$MA_method1" != "D+L" + replace `tauLCI`inf'' = . if (`use' == 17 | `use' == 19) & "$MA_method2" != "D+L" + replace `tauUCI`inf'' = . if (`use' == 17 | `use' == 19) & "$MA_method2" != "D+L" +} + + +// DIAMONDS TAKE FOREVER...I DON'T THINK THIS IS WHAT MIKE DID +tempvar DIAMleftX DIAMrightX DIAMbottomX DIAMtopX DIAMleftY1 DIAMrightY1 DIAMleftY2 DIAMrightY2 DIAMbottomY DIAMtopY + +gen `DIAMleftX' = `lci' if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19 +replace `DIAMleftX' = `DXmin' if `lci' < `DXmin' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +replace `DIAMleftX' = . if `effect' < `DXmin' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +gen `DIAMleftY1' = `id' if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19 +replace `DIAMleftY1' = `id' + 0.4*( abs((`DXmin'-`lci')/(`effect'-`lci')) ) if `lci' < `DXmin' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +replace `DIAMleftY1' = . if `effect' < `DXmin' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +gen `DIAMleftY2' = `id' if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19 +replace `DIAMleftY2' = `id' - 0.4*( abs((`DXmin'-`lci')/(`effect'-`lci')) ) if `lci' < `DXmin' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +replace `DIAMleftY2' = . if `effect' < `DXmin' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) + +gen `DIAMrightX' = `uci' if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19 +replace `DIAMrightX' = `DXmax' if `uci' > `DXmax' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +replace `DIAMrightX' = . if `effect' > `DXmax' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +gen `DIAMrightY1' = `id' if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19 +replace `DIAMrightY1' = `id' + 0.4*( abs((`uci'-`DXmax')/(`uci'-`effect')) ) if `uci' > `DXmax' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +replace `DIAMrightY1' = . if `effect' > `DXmax' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +gen `DIAMrightY2' = `id' if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19 +replace `DIAMrightY2' = `id' - 0.4*( abs((`uci'-`DXmax')/(`uci'-`effect')) ) if `uci' > `DXmax' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) + +replace `DIAMrightY2' = . if `effect' > `DXmax' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +gen `DIAMbottomY' = `id' - 0.4 if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19 +replace `DIAMbottomY' = `id' - 0.4*( abs((`uci'-`DXmin')/(`uci'-`effect')) ) if `effect' < `DXmin' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +replace `DIAMbottomY' = `id' - 0.4*( abs((`DXmax'-`lci')/(`effect'-`lci')) ) if `effect' > `DXmax' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +gen `DIAMtopY' = `id' + 0.4 if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19 +replace `DIAMtopY' = `id' + 0.4*( abs((`uci'-`DXmin')/(`uci'-`effect')) ) if `effect' < `DXmin' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +replace `DIAMtopY' = `id' + 0.4*( abs((`DXmax'-`lci')/(`effect'-`lci')) ) if `effect' > `DXmax' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) + +gen `DIAMtopX' = `effect' if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19 +replace `DIAMtopX' = `DXmin' if `effect' < `DXmin' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +replace `DIAMtopX' = `DXmax' if `effect' > `DXmax' & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +replace `DIAMtopX' = . if (`uci' < `DXmin' | `lci' > `DXmax') & (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) +gen `DIAMbottomX' = `DIAMtopX' + +} // END QUI + +// v1.11 TEXT SIZE SOLU +// v1.16 TRYING AGAIN! +// IF aspect IS USED IN "$MA_OTHEROPTS" (OTHER GRAPH OPTS) THEN THIS HELPS TO CALCULATE TEXT SIZE +// IF NO ASPECT, BUT xsize AND ysize USED THEN FIND RATIO MANUALLY +// STATA ALWAYS TRIES TO PRODUCE A GRAPH WITH ASPECT ABOUT 0.77 - TRY TO FIND "NATURAL ASPECT" + +local aspect = . + +if strpos(`"$MA_OTHEROPTS"',"aspect") > 0{ + local aspectTXT = substr( `"$MA_OTHEROPTS"', (strpos(`"$MA_OTHEROPTS"',"aspect")), (length(`"$MA_OTHEROPTS"')) ) + local aspectTXT = substr( "`aspectTXT'", 1, ( strpos("`aspectTXT'",")")) ) + local aspect = real( substr( "`aspectTXT'", ( strpos("`aspectTXT'","(") +1 ), /// + ( strpos("`aspectTXT'",")") - strpos("`aspectTXT'","(") -1 ) )) +} + +if strpos(`"$MA_OTHEROPTS"',"xsize") > 0 /// + & strpos(`"$MA_OTHEROPTS"',"ysize") > 0 /// + & strpos(`"$MA_OTHEROPTS"',"aspect") == 0{ + + local xsizeTXT = substr( `"$MA_OTHEROPTS"', (strpos(`"$MA_OTHEROPTS"',"xsize")), (length(`"$MA_OTHEROPTS"')) ) + + // Ian White's bug fix! + local xsizeTXT = substr( `"`xsizeTXT'"', 1, ( strpos(`"`xsizeTXT'"',")")) ) + local xsize = real( substr( `"`xsizeTXT'"', ( strpos(`"`xsizeTXT'"',"(") +1 ), /// + ( strpos(`"`xsizeTXT'"',")") - strpos(`"`xsizeTXT'"',"(") -1 ) )) + local ysizeTXT = substr( `"$MA_OTHEROPTS"', (strpos(`"$MA_OTHEROPTS"',"ysize")), (length(`"$MA_OTHEROPTS"')) ) + local ysizeTXT = substr( `"`ysizeTXT'"', 1, ( strpos(`"`ysizeTXT'"',")")) ) + local ysize = real( substr( `"`ysizeTXT'"', ( strpos(`"`ysizeTXT'"',"(") +1 ), /// + ( strpos(`"`ysizeTXT'"',")") - strpos(`"`ysizeTXT'"',"(") -1 ) )) + + local aspect = `ysize'/`xsize' +} +local approx_chars = ($LEFT_WD + $RIGHT_WD)/($MA_AS_TEXT/100) +qui count if `use' != 9 +local height = r(N) +local natu_aspect = 1.3*`height'/`approx_chars' + + +if `aspect' == .{ + // sort out relative to text, but not to ridiculous degree + local new_asp = 0.5*`natu_aspect' + 0.5*1 + global MA_OTHEROPTS `"$MA_OTHEROPTS aspect(`new_asp')"' + local aspectRat = max( `new_asp'/`natu_aspect' , `natu_aspect'/`new_asp' ) +} +if `aspect' != .{ + local aspectRat = max( `aspect'/`natu_aspect' , `natu_aspect'/`aspect' ) +} +local adj = 1.25 +if `natu_aspect' > 0.7{ + local adj = 1/(`natu_aspect'^1.3+0.2) +} + +local textSize = `adj' * $MA_TEXT_SCA / (`approx_chars' * sqrt(`aspectRat') ) +local textSize2 = `adj' * $MA_TEXT_SCA / (`approx_chars' * sqrt(`aspectRat') ) + +forvalues i = 1/`lcolsN'{ + local lcolCommands`i' "(scatter `id' `left`i'' if `use' != 4, msymbol(none) mlabel(`leftLB`i'') mlabcolor(black) mlabpos(3) mlabsize(`textSize')) " +} +forvalues i = 1/`rcolsN'{ + local rcolCommands`i' "(scatter `id' `right`i'' if `use' != 4, msymbol(none) mlabel(`rightLB`i'') mlabcolor(black) mlabpos(3) mlabsize(`textSize')) " +} +if "$MA_rfdist" != ""{ + if "`stats'" == ""{ + local predIntCmd "(scatter `id' `right1' if `use' == 4, msymbol(none) mlabel(`RFdistText') mlabcolor(black) mlabpos(3) mlabsize(`textSize')) " + } + if "$MA_nohet" == ""{ + local predIntCmd2 "(scatter `id' `left1' if `use' == 4, msymbol(none) mlabel(`RFdistLabel') mlabcolor(black) mlabpos(3) mlabsize(`textSize')) " + } +} +if "$MA_nohet" == "" & "$MA_rjhby" != ""{ + local hetGroupCmd "(scatter `id' `left1' if `use' == 4, msymbol(none) mlabel(`hetGroupLabel') mlabcolor(black) mlabpos(3) mlabsize(`textSize')) " +} + +// OTHER BITS AND BOBS + +local dispBox "none" +if "`nobox'" == ""{ + local dispBox "square " +} + +local boxsize = $MA_FBSC/150 + +if "$MA_FAVOURS" != ""{ + local pos = strpos("$MA_FAVOURS", "#") + local leftfav = substr("$MA_FAVOURS",1,(`pos'-1)) + local rightfav = substr("$MA_FAVOURS",(`pos'+1),(length("$MA_FAVOURS")-`pos'+1) ) +} +if `h0' != . & "$MA_nulloff" == ""{ + local leftfp = `DXmin' + (`h0'-`DXmin')/2 + local rightfp = `h0' + (`DXmax'-`h0')/2 +} +else{ + local leftfp = `DXmin' + local rightfp = `DXmax' +} + + +// GRAPH APPEARANCE OPTIONS- ADDED v1.15 + +/* +if `"$MA_OPT"' != "" & strpos(`"$MA_OPT"',"m") == 0{( + global MA_OPT = `"$MA_OPT m()"' +} +*/ + +if `"$MA_BOXOPT"' != "" & strpos(`"$MA_BOXOPT"',"msymbol") == 0{ // make defaults if unspecified + global MA_BOXOPT = `"$MA_BOXOPT msymbol(square)"' +} +if `"$MA_BOXOPT"' != "" & strpos(`"$MA_BOXOPT"',"mcolor") == 0{ // make defaults if unspecified + global MA_BOXOPT = `"$MA_BOXOPT mcolor("180 180 180")"' +} +if `"$MA_BOXOPT"' == ""{ + local boxopt "msymbol(`dispBox') msize(`boxsize') mcolor("180 180 180")" +} +else{ + if strpos(`"$MA_BOXOPT"',"mla") != 0{ + di as error "Option mlabel() not allowed in boxopt()" + exit + } + if strpos(`"$MA_BOXOPT"',"msi") != 0{ + di as error "Option msize() not allowed in boxopt()" + exit + } + local boxopt `"$MA_BOXOPT msize(`boxsize')"' +} +if "$MA_classic" != ""{ + local boxopt "mcolor(black) msymbol(square) msize(`boxsize')" +} +if "`box'" != ""{ + local boxopt "msymbol(none)" +} + + + +if `"$MA_DIAMOPT"' == ""{ + local diamopt "lcolor("0 0 100")" +} +else{ + if strpos(`"$MA_DIAMOPT"',"hor") != 0 | strpos(`"$MA_DIAMOPT"',"vert") != 0{ + di as error "Options horizontal/vertical not allowed in diamopt()" + exit + } + if strpos(`"$MA_DIAMOPT"',"con") != 0{ + di as error "Option connect() not allowed in diamopt()" + exit + } + if strpos(`"$MA_DIAMOPT"',"lp") != 0{ + di as error "Option lpattern() not allowed in diamopt()" + exit + } + local diamopt `"$MA_DIAMOPT"' +} + + + +if `"$MA_POINTOPT"' != "" & strpos(`"$MA_POINTOPT"',"msymbol") == 0{( + global MA_POINTOPT = `"$MA_POINTOPT msymbol(diamond)"' +} +if `"$MA_POINTOPT"' != "" & strpos(`"$MA_POINTOPT"',"msize") == 0{( + global MA_POINTOPT = `"$MA_POINTOPT msize(vsmall)"' +} +if `"$MA_POINTOPT"' != "" & strpos(`"$MA_POINTOPT"',"mcolor") == 0{( + global MA_POINTOPT = `"$MA_POINTOPT mcolor(black)"' +} +if `"$MA_POINTOPT"' == ""{ + local pointopt "msymbol(diamond) msize(vsmall) mcolor("0 0 0")" +} +else{ + local pointopt `"$MA_POINTOPT"' +} +if "$MA_classic" != "" & "`box'" == ""{ + local pointopt "msymbol(none)" +} + + + +if `"$MA_CIOPT"' != "" & strpos(`"$MA_CIOPT"',"lcolor") == 0{( + global MA_CIOPT = `"$MA_CIOPT lcolor(black)"' +} +if `"$MA_CIOPT"' == ""{ + local ciopt "lcolor("0 0 0")" +} +else{ + if strpos(`"$MA_CIOPT"',"hor") != 0 | strpos(`"$MA_CIOPT"',"vert") != 0{ + di as error "Options horizontal/vertical not allowed in ciopt()" + exit + } + if strpos(`"$MA_CIOPT"',"con") != 0{ + di as error "Option connect() not allowed in ciopt()" + exit + } + if strpos(`"$MA_CIOPT"',"lp") != 0{ + di as error "Option lpattern() not allowed in ciopt()" + exit + } + local ciopt `"$MA_CIOPT"' +} + + +// END GRAPH OPTS + + + +if "$MA_method1" == "D+L"{ + tempvar noteposx noteposy notelab + qui{ + summ `id' + gen `noteposy' = r(min) -1.5 in 1 + summ `left1' + gen `noteposx' = r(mean) in 1 + gen `notelab' = "NOTE: Weights are from random effects analysis" in 1 + local notecmd "(scatter `noteposy' `noteposx', msymbol(none) mlabel(`notelab') mlabcolor(black) mlabpos(3) mlabsize(`textSize')) " + } + if "$MA_nowarning" != ""{ + local notecmd + } +} + + +if "`overall'" != ""{ + local overallCommand "" + qui drop if `use' == 5 + qui summ `id' + local DYmin = r(min) + cap replace `noteposy' = r(min) -.5 in 1 +} + +// quick bodge to get overall- can't find log version! +tempvar tempOv ovLine ovMin ovMax h0Line +qui gen `tempOv' = `effect' if `use' == 5 +sort `tempOv' +qui summ `id' +local DYmin = r(min)-2 +local DYmax = r(max)+1 + +qui gen `ovLine' = `tempOv' in 1 +qui gen `ovMin' = r(min)-2 in 1 +qui gen `ovMax' = $borderline in 1 +qui gen `h0Line' = `h0' in 1 + +if `"$MA_OLINEOPT"' == ""{ + local overallCommand " (pcspike `ovMin' `ovLine' `ovMax' `ovLine', lwidth(thin) lcolor(maroon) lpattern(shortdash)) " +} +else{ + local overallCommand `" (pcspike `ovMin' `ovLine' `ovMax' `ovLine', $MA_OLINEOPT) "' +} +if `ovLine' > `DXmax' | `ovLine' < `DXmin' | "`overall'" != ""{ // ditch if not on graph + local overallCommand "" +} + +local nullCommand " (pcspike `ovMin' `h0Line' `ovMax' `h0Line', lwidth(thin) lcolor(black) ) " + +// gap if "favours" used +if "`leftfav'" != "" | "`rightfav'" != ""{ + local gap = "labgap(5)" +} + +// if summary only must not have weights +local awweight "[aw= `weight']" +if "$MA_summaryonly" != ""{ + local awweight "" +} +qui summ `weight' +if r(N) == 0{ + local awweight "" +} + +// rfdist off scale arrows only used when appropriate +qui{ +tempvar rfarrow +gen `rfarrow' = 0 +if "$MA_rfdist" != ""{ + if "$MA_method1" == "D+L"{ + replace `rfarrow' = 1 if `use' == 3 | `use' == 5 + } + if "$MA_method2" == "D+L"{ + replace `rfarrow' = 1 if `use' == 17 | `use' == 19 + } +} +} // end qui + + +// final addition- if aspect() given but not xsize() ysize(), put these in to get rid of gaps +// need to fiddle to allow space for bottom title +// should this just replace the aspect option? +// suppose good to keep- most people hopefully using xsize and ysize and can always change themselves if using aspect + +if strpos(`"$MA_OTHEROPTS"',"xsize") == 0 & strpos(`"$MA_OTHEROPTS"',"ysize") == 0 /// + & strpos(`"$MA_OTHEROPTS"',"aspect") > 0 { + + local aspct = substr(`"$MA_OTHEROPTS"', (strpos(`"$MA_OTHEROPTS"',"aspect(")+7 ) , length(`"$MA_OTHEROPTS"') ) + local aspct = substr(`"`aspct'"', 1, (strpos(`"`aspct'"',")")-1) ) + if `aspct' > 1{ + local xx = (11.5+(2-2*1/`aspct'))/`aspct' + local yy = 12 + } + if `aspct' <= 1{ + local yy = 12*`aspct' + local xx = 11.5-(2-2*`aspct') + } + global MA_OTHEROPTS = `"$MA_OTHEROPTS"' + " xsize(`xx') ysize(`yy')" + +} + +// switch off null if wanted +if "$MA_nulloff" != ""{ + local nullCommand "" +} + +*************************** +*** GRAPH *** +*************************** + +#delimit ; + +twoway +/* NOTE FOR RF, OVERALL AND NULL LINES FIRST */ + `notecmd' `overallCommand' `nullCommand' `predIntCmd' `predIntCmd2' `hetGroupCmd' +/* PLOT BOXES AND PUT ALL THE GRAPH OPTIONS IN THERE */ + (scatter `id' `effect' `awweight' if `use' == 1, + `boxopt' + yscale(range(`DYmin' `DYmax') noline ) + ylabel(none) ytitle("") + xscale(range(`AXmin' `AXmax')) + xlabel(`lblcmd', labsize(`textSize2') ) + yline($borderline, lwidth(thin) lcolor(gs12)) +/* THIS BIT DOES favours. NOTE SPACES TO SUPPRESS IF THIS IS NOT USED */ + xmlabel(`leftfp' "`leftfav' " `rightfp' "`rightfav' ", noticks labels labsize(`textSize') + `gap' /* PUT LABELS UNDER xticks? Yes as labels now extended */ ) + xtitle("") legend(off) xtick("`xtick'") ) +/* END OF FIRST SCATTER */ +/* HERE ARE THE CONFIDENCE INTERVALS */ + (pcspike `id' `lci' `id' `uci' if `use' == 1, `ciopt') +/* ADD ARROWS IF OFFSCALE USING offLeftX offLeftX2 offRightX offRightX2 offYlo offYhi */ + (pcspike `id' `offLeftX' `offYlo' `offLeftX2' if `use' == 1, `ciopt') + (pcspike `id' `offLeftX' `offYhi' `offLeftX2' if `use' == 1, `ciopt') + (pcspike `id' `offRightX' `offYlo' `offRightX2' if `use' == 1, `ciopt') + (pcspike `id' `offRightX' `offYhi' `offRightX2' if `use' == 1, `ciopt') +/* DIAMONDS FOR SUMMARY ESTIMATES -START FROM 9 O'CLOCK */ + (pcspike `DIAMleftY1' `DIAMleftX' `DIAMtopY' `DIAMtopX' if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19, `diamopt') + (pcspike `DIAMtopY' `DIAMtopX' `DIAMrightY1' `DIAMrightX' if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19, `diamopt') + (pcspike `DIAMrightY2' `DIAMrightX' `DIAMbottomY' `DIAMbottomX' if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19, `diamopt') + (pcspike `DIAMbottomY' `DIAMbottomX' `DIAMleftY2' `DIAMleftX' if `use' == 3 | `use' == 5 | `use' == 17 | `use' == 19, `diamopt') +/* EXTENDED CI FOR RANDOM EFFECTS, SHOW DISTRIBUTION AS RECOMMENDED BY JULIAN HIGGINS + DOTTED LINES FOR INESTIMABLE DISTRIBUTION */ + (pcspike `DIAMleftY1' `DIAMleftX' `DIAMleftY1' `tauLCI' if (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) & `tau2' < ., `diamopt') + (pcspike `DIAMrightY1' `DIAMrightX' `DIAMrightY1' `tauUCI' if (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) & `tau2' < ., `diamopt') + (pcspike `DIAMleftY1' `DIAMleftX' `DIAMleftY1' `tauLCI' if (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) & `tau2' ==.b, `diamopt' lpattern(shortdash)) + (pcspike `DIAMrightY1' `DIAMrightX' `DIAMrightY1' `tauUCI' if (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) & `tau2' ==.b, `diamopt' lpattern(shortdash)) +/* DIAMOND EXTENSION FOR RF DIST ALSO HAS ARROWS... */ + (pcspike `id' `offLeftX' `offYlo' `offLeftX2' if (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) & `rfarrow' == 1, `diamopt') + (pcspike `id' `offLeftX' `offYhi' `offLeftX2' if (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) & `rfarrow' == 1, `diamopt') + (pcspike `id' `offRightX' `offYlo' `offRightX2' if (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) & `rfarrow' == 1, `diamopt') + (pcspike `id' `offRightX' `offYhi' `offRightX2' if (`use' == 3 | `use' == 5 | `use' == 17 | `use' == 19) & `rfarrow' == 1, `diamopt') +/* COLUMN VARIBLES */ + `lcolCommands1' `lcolCommands2' `lcolCommands3' `lcolCommands4' `lcolCommands5' `lcolCommands6' + `lcolCommands7' `lcolCommands8' `lcolCommands9' `lcolCommands10' `lcolCommands11' `lcolCommands12' + `rcolCommands1' `rcolCommands2' `rcolCommands3' `rcolCommands4' `rcolCommands5' `rcolCommands6' + `rcolCommands7' `rcolCommands8' `rcolCommands9' `rcolCommands10' `rcolCommands11' `rcolCommands12' + (scatter `id' `right1' if `use' != 4 & `use' != 0, + msymbol(none) mlabel(`rightLB1') mlabcolor("0 0 0") mlabpos(3) mlabsize(`textSize')) + (scatter `id' `right2' if `use' != 4 & `use' != 0, + msymbol(none) mlabel(`rightLB2') mlabcolor("0 0 0") mlabpos(3) mlabsize(`textSize')) +/* (scatter `id' `right2', mlabel(`use')) JUNK, TO SEE WHAT'S WHERE */ +/* LAST OF ALL PLOT EFFECT MARKERS TO CLARIFY AND OVERALL EFFECT LINE */ + (scatter `id' `effect' if `use' == 1, `pointopt' ) + , $MA_OTHEROPTS /* RMH added */ plotregion(margin(zero)); + +#delimit cr + +end + + + + + +program define getWidth +version 9.0 + +// ROSS HARRIS, 13TH JULY 2006 +// TEXT SIZES VARY DEPENDING ON CHARACTER +// THIS PROGRAM GENERATES APPROXIMATE DISPLAY WIDTH OF A STRING +// FIRST ARG IS STRING TO MEASURE, SECOND THE NEW VARIABLE + +// PREVIOUS CODE DROPPED COMPLETELY AND REPLACED WITH SUGGESTION +// FROM Jeff Pitblado + +qui{ + +gen `2' = 0 +count +local N = r(N) +forvalues i = 1/`N'{ + local this = `1'[`i'] + local width: _length "`this'" + replace `2' = `width' +1 in `i' +} + +} // end qui + +end + + + +exit + +// METAN UPDATE +// ROSS HARRIS, DEC 2006 +// MAIN UPDATE IS GRAPHICS IN THE _dispgby PROGRAM +// ADDITIONAL OPTIONS ARE lcols AND rcols +// THESE AFFECT DISPLAY ONLY AND ALLOW USER TO SPECIFY +// VARIABLES AS A FORM OF TABLE. THIS EXTENDS THE label(namevar yearvar) +// SYNTAX, ALLOWING AS MANY LEFT COLUMNS AS REQUIRED (WELL, LIMIT IS 10) +// IF rcols IS OMMITTED DEFAULT IS THE STUDY EFFECT (95% CI) AND WEIGHT +// AS BEFORE- THESE ARE ALWAYS IN UNLESS OMITTED USING OPTIONS +// ANYTHING ADDED TO rcols COMES AFTER THIS. + +// v1.4 WAS GETTING THERE +// v1.5 SORT OUT EXTRA LINE AT THE TOP AND ALLOW "DOUBLE LINES" +// FOR FIXED AND RANDOM EFFECTS + +// SOMETHING TO ADD- RETURN ES_2? +// v1.7 - TRY TO SORT OUT LABELLING +// CHANGED LABELS TO 7.3g -WORKS NICELY +// "FAVOURS" NOW WORKS- USES xmlabel +// v1.8 ADDED IN COUNTS OPTION, SORTED OUT TEXTSIZE, PROPER DEFINITION AND SPLIT OF VAR LABELS + +// v1.9 DELETE UNECESSARY OPTIONS +// OH, AND ADD effect OPTION +// v1.10 FINAL TIDYING, USED Jeff Pitblado's SUGGESTION FOR getWidth + +// v1.11 USE label() OPTIONS IF NO lcols rcols, WORK ON AUTO FIT TEXT +// v1.12 FURTHER WORK... + +// v1.14 DONE ON 12TH OCTOBER, FINALLY DISCOVERED WHAT IS CAUSING PROBLEM +// WITH "NON-MATCHING CLOSE BRACE" AT END OF FILE- NO v7 STYLE IF STATEMENTS! +// EVERYTHING GOES ON A SEPARATE LINE NOW. PHEW. + +// v1.15 NOW ADDING IN OPTIONS TO CONTROL BOXES, CI LINES, OVERALL +// TITLES WEREN'T SPREADING ACROSS SINCE OPTION TO CONTROL OVERALL TEXT- FIXED AGAIN + +// v1.16 LAST ATTEMPT TO GET TEXT SIZE RIGHT! WORK OUT WHAT ASPECT SHOULD BE AND USE +// IF ASPECT DEFINED THEN DECREASE TEXT SIZE BY RATIO TO IDEAL ASPECT + +// TEXT SCALING WORKING BETTER NOW +// LAST THING TO TRY TO SORT IS LOOK FOR LEFT OF DIAMOND AND MOVE HET STATS +// COULD PUT UNDERNEATH IF NOT MUCH SPACE? THIS WOULD BE GOOD v1.17 +// STILL DEBATING WHETHER TO PUT favours BIT BELOW xticks... + +// V19 LOTS OF COMMENTS FROM JONATHAN AND BITS TO DO. SUMMARY: +// aspect Y +// note if random weights Y +// update to v8 Y +// graph in mono Y +// extend overall text into plot Y +// labels Y +// help file not v8 yet + +// v1.21 EVERY PROGRAM NOW CONVERTED TO v9.0, NO "CODE FOLLOWS BRACES!" + +// WHAT ELSE DID PATRICK DO TO UPDATE TO v8? + +// NO "#delimit ;" - I QUITE LIKE THIS THOUGH! +// GLOBALS ARE DECLARED WITHOUT = SIGN - EXCEPT WHEN USING STRING FUNCTION ETC. IT DOESN'T LIKE THIS! +// - WILL THIS EVER CAUSE PROBLEMS? +// - CAN'T BE BOTHERED TO CHANGE ALL THE NUMERIC ONES +// USE TOKENIZE INSTEAD OF PARSE - DONE +// USE di as err NOT in red, EXIT - DONE, PROPER RETURN CODES STILL NEEDED, MAYBE SOMEDAY! +// DECENT HELP FILE - USED, JUST ADD IN NEW BITS + +// v1.22 ENCODE STUFF FOR metanby NOW LABORIOUSLY RECODED SO THAT GROUPS ARE IN ORIGINAL SORT ORDER +// THIS IS USEFUL IF YOU DON'T WANT STUFF IN ALPHA-NUMERIC ORDER, OR TO PUT "1..." "2..." ETC. + +// counts OPTION DOES NOT WORK WITH MEAN DIFFERENCES- AND LOOKS LIKE IT NEVER DID- PUT IN +// DO OWN LINES FOR OVERALL ETC. EXTENDS TOO FAR +// LABELS NEVER RUN TO FOUR LINES- SORT OUT- QUICK SOLU- DO FIVE TIMES AND DROP ONE! + +// v1.23 USES pcspike FOR OVERALL AND NULL LINES TO PREVENT OVER-EXTENDING +// NOW HAS OPTION FOR USER DEFINED "SECOND" ANALYSIS + +// v1.24 ALLOW USER TO COMPLETELY DEFINE ANALYSIS WITH WEIGHTS + +// v2.34 problem with nosubgroup nooverall sorted out (this combination failed) + +******************** +** May 2007 fixes ** +******************** + +// "nostandard" had disappeared from help file- back in +// I sq. in return list +// sorted out the extra top line that appears in column labels +// fixed when using aspect ratio using xsize and ysize so inner bit matches graph area- i.e., get rid of spaces for long/wide graphs +// variable display format preserved for lcols and rcols +// abbreviated varlist now allowed +// between groups het. only available with fixed +// warnings if any heterogeneity with fixed (for between group het if any sub group has het, overall est if any het) +// nulloff option to get rid of line + diff --git a/Modules/ado/plus/m/metan.dlg b/Modules/ado/plus/m/metan.dlg new file mode 100644 index 0000000..2ac5d92 --- /dev/null +++ b/Modules/ado/plus/m/metan.dlg @@ -0,0 +1,838 @@ +/* + +*! metan dialog version 1.0.5, 1 Apr 2004, T. J. Steichen, steichen@triad.rr.com +*! for metan version 1.85, 15 Mar 2004, M. J. Bradburn, mike.bradburn@cancer.org.uk + +Fixed and random effects meta-analysis +-------------------------------------- +Syntax: metan varlist [if exp] [in range] [, + label(namevar=name, yearvar=year) + fixed random fixedi randomi peto + rr or rd cornfield chi2 breslow notable nograph + cohen hedges glass nostandard + log sortby(sort_vars) ilevel(#) olevel(#) nokeep + xlabel(#,..,#) force t1title(#,..,#) boxsha(#) boxsca(#) texts(#) + saving(filename) nowt counts nostats nooverall + group1(text) group2(text) effect(text) nobox eform + wgt(weightvar) xtick(#,..,#) + t2title(#,..,#) b1title(#,..,#) b2title(#,..,#) + nointeger cc(#) by(byvar) nosubgroup sgweight legend(text) ] + +To install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "Meta-analysis of Binary and Continuous Data (meta&n)" "db metan" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. + +*/ + +VERSION 8.0 + +INCLUDE _std_medium +INCLUDE _ht300 +DEFINE _dlgwd 450 +INCLUDE header + +HELP hlp1, view("help metan") +RESET res1, label("Reset") + +DIALOG main, label("metan 1.85 - Meta-analysis of Binary & Continuous") tabtitle("Main") +BEGIN + GROUPBOX gb_data 10 5 310 _ht1h, /// + label("Type of Data:") + RADIO r_binary 15 25 60 ., /// + label(" Count") first /// + onclickon(script main_binary_on) /// + onclickoff(script main_binary_off) + RADIO r_continuous 75 25 90 ., /// + label("Continuous") middle /// + onclickon(script main_continuous_on) /// + onclickoff(script main_continuous_off) + RADIO r_effect_ci 165 25 75 ., /// + label("Effect/CI") middle /// + onclickon(script main_effect_ci_on) /// + onclickoff(script main_effect_ci.off) + RADIO r_effect_se 240 25 75 ., /// + label("Effect/SE") last /// + onclickon(script main_effect_se_on) /// + onclickoff(script main_effect_se_off) + +/* end GROUPBOX gb_data */ + + TEXT tx_binary 10 50 310 ., /// + label("Vars for Counts: a, b, c, d, in that order") + VARLIST vl_binary @ _ss @ ., /// + label("Vars for a, b, c, d") + + TEXT tx_contin_exp @ 50 310 ., /// + label("Vars for Exp. Group: n, mean, sd, in that order") + VARLIST vl_contin_exp @ _ss @ ., /// + label("Experimental Group: n, mean, sd") + TEXT tx_contin_ctl @ _ss 310 ., /// + label("Vars for Control Group: n, mean, sd, in that order") + VARLIST vl_contin_ctl @ _ss @ ., /// + label("Control Group: n, mean, sd") + + TEXT tx_effect_ci @ 50 310 ., /// + label("Vars for Effects: theta, lowerCI, upperCI, in that order") + VARLIST vl_effect_ci @ _ss @ ., /// + label("Effect Sizes: theta, lowerCI, upperCI") + + TEXT tx_effect_se @ 50 310 ., /// + label("Vars for Effects: theta, se(theta), in that order") + VARLIST vl_effect_se @ _ss @ ., /// + label("Effect Sizes: theta, se(theta)") + +/* end vars */ + + GROUPBOX gb_labels 10 130 310 _ht3h, /// + label("Labels for Data:") + CHECKBOX cb_name 20 150 70 ., /// + label("Name:") /// + onclickon(main.vn_name.enable) /// + onclickoff(main.vn_name.disable) + VARNAME vn_name 100 150 210 ., /// + label("Name Variable") + CHECKBOX cb_year 20 170 70 ., /// + label("Year:") /// + onclickon(main.vn_year.enable) /// + onclickoff(main.vn_year.disable) + VARNAME vn_year 100 170 210 ., /// + label("Year Variable") + +/* end GROUPBOX gb_labels */ + + GROUPBOX gb_by 10 200 310 45, /// + label("By Variable:") + CHECKBOX cb_by 20 220 70 ., /// + label(" By:") /// + onclickon(script main_by_on) /// + onclickoff(script main_by_off) + VARLIST vl_by 100 220 210 ., /// + label("By Variable") /// + option("by") + +/* end GROUPBOX gb_by */ + + GROUPBOX gb_sortby 10 250 310 45, /// + label("Sort Data:") + CHECKBOX cb_sortby 20 270 70 ., /// + label(" By:") /// + onclickon(main.vl_sortby.enable) /// + onclickoff(main.vl_sortby.disable) + VARLIST vl_sortby 100 270 210 ., /// + label("Name Variable") /// + option("sortby") + +/* end GROUPBOX gb_sortby */ + + GROUPBOX gb_opts 325 5 120 85, /// + label("General Options:") + + CHECKBOX cb_nokeep 330 25 70 ., /// + label("noKeep") /// + option("nokeep") + + CHECKBOX cb_ilevel 330 45 60 ., /// + label("ilevel:") /// + onclickon(main.ed_ilevel.enable) /// + onclickoff(main.ed_ilevel.disable) + EDIT ed_ilevel 400 45 40 ., /// + label("ilevel") /// + numonly default(global S_level) /// + option("ilevel") + + CHECKBOX cb_olevel 330 65 60 ., /// + label("olevel:") /// + onclickon(main.ed_olevel.enable) /// + onclickoff(main.ed_olevel.disable) + EDIT ed_olevel 400 65 40 ., /// + label("olevel") /// + numonly default(global S_level) /// + option("olevel") + +/* end GROUPBOX gb_opts */ + + FRAME fr_wgt 325 95 120 60 + CHECKBOX cb_wgt 330 100 110 ., /// + label("Weight Var") /// + onclickon(main.vn_wgt.enable) /// + onclickoff(main.vn_wgt.disable) + VARNAME vn_wgt 330 121 110 ., /// + label("Weight Variable") /// + option("wgt") + +/* end wgt */ + + GROUPBOX gb_by_opts 325 200 120 61, /// + label("By Options:") + + CHECKBOX cb_nosubgroup 330 220 100 ., /// + label("noSubGroup") /// + option("nosubgroup") + + CHECKBOX cb_sgweight 330 240 100 ., /// + label("sgWeight") /// + option("sgweight") + +/* end GROUPBOX gb_by_opts */ + +END + +DIALOG metan_b, tabtitle("Binary...") +BEGIN + GROUPBOX gb_pool 0 10 210 _ht9h, /// + label("Pooling Model") + RADIO r_fixed 10 30 190 ., /// + label("Fixed, Mantel-Haenszel") first /// + onclickoff(program metan_b_bd) /// + option("fixed") + RADIO r_fixedi @ _ss @ ., /// + label("Fixed, Inverse Variance") middle /// + onclickoff(program metan_b_bd) /// + option("fixedi") + RADIO r_random @ _ss 195 ., /// + label("Random (M-H heterogeneity)") middle /// + onclickon(script metan_b_random_on) /// + onclickoff(program metan_b_chi2) /// + option("random") + RADIO r_randomi @ _ss @ ., /// + label("Random (I-V heterogeneity)") middle /// + onclickon(script metan_b_random_on) /// + onclickoff(program metan_b_chi2) /// + option("randomi") + RADIO r_peto @ _ss @ ., /// + label("Peto") last /// + onclickon(script metan_b_peto_on) /// + onclickoff(program metan_b_cornfield) /// + option("peto") + + GROUPBOX gb_stat 220 10 120 _ht5h, /// + label("Statistic") + RADIO r_rr 230 30 80 ., /// + label("RR") first /// + onclickon(script metan_b_rr_on) /// + onclickoff(program metan_b_rr_off) /// + option("rr") + RADIO r_or @ _ss @ ., /// + label("OR") middle /// + onclickon(program metan_b_or_on) /// + onclickoff(program metan_b_or_off) /// + option("or") + RADIO r_rd @ _ss @ ., /// + label("RD") last /// + option("rd") + + CHECKBOX cb_cornfield 10 140 200 ., /// + label("Use Cornfield CI's") /// + option("cornfield") + CHECKBOX cb_chi2 10 160 200 ., /// + label("Use Chi-2 Statistic") /// + option("chi2") + CHECKBOX cb_breslow 10 180 200 ., /// + label("Use Breslow-Day test") /// + option("breslow") + + CHECKBOX cb_log 230 100 200 ., /// + label("Log scaled") /// + option("log") + + CHECKBOX cb_eform 230 120 200 ., /// + label("Exponentiate") /// + option("eform") + + CHECKBOX cb_notable 230 140 200 ., /// + label("noTable") /// + option("notable") + CHECKBOX cb_nograph 230 160 200 ., /// + label("noGraph") /// + option("nograph") + + CHECKBOX cb_cc 10 260 150 ., /// + label("Continuity Correction:") /// + onclickon(metan_b.ed_cc.enable) /// + onclickoff(metan_b.ed_cc.disable) + EDIT ed_cc 160 260 65 ., /// + label("Continuity Correction") /// + option("cc") + + CHECKBOX cb_nointeger 230 260 200 ., /// + label("noInteger") /// + option("nointeger") +END + +DIALOG metan_c, tabtitle("Continuous...") +BEGIN + GROUPBOX gb_pool 0 10 210 _ht3h, /// + label("Pooling Model") + RADIO r_fixed 10 30 190 ., /// + label("Fixed, Inverse Variance") first /// + option("fixed") + RADIO r_random @ _ss @ ., /// + label("Random (I-V heterogeneity)") last /// + option("random") + + GROUPBOX gb_stat 220 10 120 _ht7h, /// + label("Statistic") + RADIO r_cohen 230 30 100 ., /// + label("Cohen") first /// + option("cohen") + RADIO r_hedges @ _ss @ ., /// + label("Hedges") middle /// + option("hedges") + RADIO r_glass @ _ss @ ., /// + label("Glass") middle /// + option("glass") + RADIO r_nostandard @ _ss @ ., /// + label("noStandard") last /// + option("nostandard") + + CHECKBOX cb_notable 230 140 200 ., /// + label("noTable") /// + option("notable") + CHECKBOX cb_nograph 230 160 200 ., /// + label("noGraph") /// + option("nograph") + + CHECKBOX cb_nointeger 230 260 200 ., /// + label("noInteger") /// + option("nointeger") + +END + +DIALOG metan_e, tabtitle("Effect...") +BEGIN + GROUPBOX gb_pool 0 10 210 _ht3h, /// + label("Pooling Model") + RADIO r_fixed 10 30 190 ., /// + label("Fixed, Inverse Variance") first /// + option("fixed") + RADIO r_random @ _ss @ ., /// + label("Random (I-V heterogeneity)") last /// + option("random") + + CHECKBOX cb_notable 230 140 200 ., /// + label("noTable") /// + option("notable") + CHECKBOX cb_nograph 230 160 200 ., /// + label("noGraph") /// + option("nograph") + + CHECKBOX cb_effect 10 110 100 ., /// + label("Effect Label:") /// + onclickon(metan_e.ed_effect.enable) /// + onclickoff(metan_e.ed_effect.disable) + EDIT ed_effect 115 @ 225 ., /// + label("effect label") /// + option("effect") + +END + +DIALOG graph, tabtitle("Graph Opts") +BEGIN + + CHECKBOX cb_saving 10 10 100 ., /// + label("Save graph:") /// + onclickon(graph.fi_saving.enable) /// + onclickoff(graph.fi_saving.disable) + FILE fi_saving 110 10 240 ., /// + label("File Name") /// + error("Save filename") /// + dialogtitle("Save graph") /// + filter("Stata Graphs|*.gph") /// + save /// + option("saving") + +/* end saving */ + + GROUPBOX gb_xlabel 10 40 330 _ht3h, /// + label("X-axis Tick Labels (comma between):") + + CHECKBOX cb_xlabel 15 60 45 ., /// + label("Set:") /// + onclickon(script graph_xlabel_on) /// + onclickoff(script graph_xlabel_off) + EDIT ed_xlabel 65 @ 270 ., /// + label("X Tick labels") /// + option("xlabel") + + CHECKBOX cb_force 15 80 320 ., /// + label("Force Scale to Tick Range") /// + option("force") + +/* end tick labels */ + + CHECKBOX cb_counts 15 115 65 ., /// + label("Counts") /// + onclickon(script graph_counts_on) /// + onclickoff(script graph_counts_off) /// + option("counts") + + CHECKBOX cb_nowt 15 145 85 ., /// + label("noWeights") /// + option("nowt") + + CHECKBOX cb_nostats 15 165 85 ., /// + label("noStats") /// + option("nostats") + + CHECKBOX cb_nooverall 115 145 85 ., /// + label("noOverall") /// + option("nooverall") + + CHECKBOX cb_nobox 115 165 85 ., /// + label("noBox") /// + option("nobox") + +/* end switches */ + + CHECKBOX cb_legend 115 185 70 ., /// + label("Legend:") /// + onclickon(graph.ed_legend.enable) /// + onclickoff(graph.ed_legend.disable) + EDIT ed_legend 190 @ 55 ., /// + label("legend") /// + option("legend") + + CHECKBOX cb_grp1 85 115 55 ., /// + label("Grp 1:") /// + onclickon(graph.ed_grp1.enable) /// + onclickoff(graph.ed_grp1.disable) + EDIT ed_grp1 145 @ 90 ., /// + label("Grp1") /// + option("group1") + + CHECKBOX cb_grp2 245 115 55 ., /// + label("Grp 2:") /// + onclickon(graph.ed_grp2.enable) /// + onclickoff(graph.ed_grp2.disable) + EDIT ed_grp2 305 @ 90 ., /// + label("Grp2") /// + option("group2") + + CHECKBOX cb_boxy 255 145 95 ., /// + label("Box yscale:") /// + onclickon(graph.ed_boxy.enable) /// + onclickoff(graph.ed_boxy.disable) + EDIT ed_boxy 355 @ 40 ., /// + label("Box yscale") numonly default(1) /// + option("boxsca") + + CHECKBOX cb_boxs 255 165 95 ., /// + label("Box shade:") /// + onclickon(graph.ed_boxs.enable) /// + onclickoff(graph.ed_boxs.disable) + EDIT ed_boxs 355 @ 40 ., /// + label("Box shading") numonly default(4) /// + option("boxsha") + + CHECKBOX cb_texts 255 185 95 ., /// + label("Font scale:") /// + onclickon(graph.ed_texts.enable) /// + onclickoff(graph.ed_texts.disable) + EDIT ed_texts 355 @ 40 ., /// + label("Font scale") numonly default(1) /// + option("texts") + +/* end sets */ + + GROUPBOX gb_gopts7 10 205 390 _ht1h, /// + label("Allowed Graph7 Options:") + EDIT ed_gopts7 15 225 380 ., /// + label("Graph7 Options") + + CHECKBOX cb_b1 15 255 390 ., /// + label("Effect Direction Labels, option b1( ):") /// + onclickon(script graph_b1_on) /// + onclickoff(script graph_b1_off) + TEXT tx_b1_l 10 275 25 ., /// + label("Left:") + EDIT ed_b1_l 35 275 160 ., /// + label(" Left") + TEXT tx_b1_r 205 275 35 ., /// + label("Right:") + EDIT ed_b1_r 240 275 160 ., /// + label("Right") + +/* end Graph7 opts */ + +END + +INCLUDE ifin + +SCRIPT main_binary_on +BEGIN + main.tx_binary.show + main.vl_binary.show + main.tx_binary.enable + main.vl_binary.enable + + main.tx_effect_ci.disable + main.vl_effect_ci.disable + main.tx_effect_ci.hide + main.vl_effect_ci.hide + + main.tx_effect_se.disable + main.vl_effect_se.disable + main.tx_effect_se.hide + main.vl_effect_se.hide + + main.tx_contin_exp.disable + main.vl_contin_exp.disable + main.tx_contin_exp.hide + main.vl_contin_exp.hide + + main.tx_contin_ctl.disable + main.vl_contin_ctl.disable + main.tx_contin_ctl.hide + main.vl_contin_ctl.hide + + graph.cb_counts.enable +END + +SCRIPT main_binary_off +BEGIN + main.tx_binary.disable + main.vl_binary.disable + main.tx_binary.hide + main.vl_binary.hide + + graph.cb_counts.disable +END + +SCRIPT main_continuous_on +BEGIN + main.tx_contin_exp.show + main.vl_contin_exp.show + main.tx_contin_exp.enable + main.vl_contin_exp.enable + + main.tx_contin_ctl.show + main.vl_contin_ctl.show + main.tx_contin_ctl.enable + main.vl_contin_ctl.enable + + main.tx_binary.disable + main.vl_binary.disable + main.tx_binary.hide + main.vl_binary.hide + + main.tx_effect_ci.disable + main.vl_effect_ci.disable + main.tx_effect_ci.hide + main.vl_effect_ci.hide + + main.tx_effect_se.disable + main.vl_effect_se.disable + main.tx_effect_se.hide + main.vl_effect_se.hide +END + +SCRIPT main_continuous_off +BEGIN + main.tx_contin_exp.disable + main.vl_contin_exp.disable + main.tx_contin_exp.hide + main.vl_contin_exp.hide + + main.tx_contin_ctl.disable + main.vl_contin_ctl.disable + main.tx_contin_ctl.hide + main.vl_contin_ctl.hide +END + +SCRIPT main_effect_ci_on +BEGIN + main.tx_effect_ci.show + main.vl_effect_ci.show + main.tx_effect_ci.enable + main.vl_effect_ci.enable + + main.tx_effect_se.disable + main.vl_effect_se.disable + main.tx_effect_se.hide + main.vl_effect_se.hide + + main.tx_binary.disable + main.vl_binary.disable + main.tx_binary.hide + main.vl_binary.hide + + main.tx_contin_exp.disable + main.vl_contin_exp.disable + main.tx_contin_exp.hide + main.vl_contin_exp.hide + + main.tx_contin_ctl.disable + main.vl_contin_ctl.disable + main.tx_contin_ctl.hide + main.vl_contin_ctl.hide +END + +SCRIPT main_effect_ci_off +BEGIN + main.tx_effect_ci.disable + main.vl_effect_ci.disable + main.tx_effect_ci.hide + main.vl_effect_ci.hide +END + +SCRIPT main_effect_se_on +BEGIN + main.tx_effect_se.show + main.vl_effect_se.show + main.tx_effect_se.enable + main.vl_effect_se.enable + + main.tx_effect_ci.disable + main.vl_effect_ci.disable + main.tx_effect_ci.hide + main.vl_effect_ci.hide + + main.tx_binary.disable + main.vl_binary.disable + main.tx_binary.hide + main.vl_binary.hide + + main.tx_contin_exp.disable + main.vl_contin_exp.disable + main.tx_contin_exp.hide + main.vl_contin_exp.hide + + main.tx_contin_ctl.disable + main.vl_contin_ctl.disable + main.tx_contin_ctl.hide + main.vl_contin_ctl.hide +END + +SCRIPT main_effect_se_off +BEGIN + main.tx_effect_se.disable + main.vl_effect_se.disable + main.tx_effect_se.hide + main.vl_effect_se.hide +END + +SCRIPT main_by_on +BEGIN + main.vl_by.enable + main.gb_by_opts.enable + main.cb_nosubgroup.enable + main.cb_sgweight.enable +END + +SCRIPT main_by_off +BEGIN + main.vl_by.disable + main.gb_by_opts.disable + main.cb_nosubgroup.disable + main.cb_sgweight.disable +END + +SCRIPT metan_b_random_on +BEGIN + metan_b.cb_breslow.disable + metan_b.cb_chi2.disable +END + +SCRIPT metan_b_peto_on +BEGIN + metan_b.cb_breslow.disable + metan_b.cb_cornfield.disable +END + +PROGRAM metan_b_bd +BEGIN + if metan_b.r_or { + call metan_b.cb_breslow.enable + } +END + +PROGRAM metan_b_chi2 +BEGIN + if metan_b.r_or & !(metan_b.r_random | metan_b.r_randomi) { + call metan_b.cb_chi2.enable + } +END + +PROGRAM metan_b_cornfield +BEGIN + if metan_b.r_or { + call metan_b.cb_cornfield.enable + } +END + +SCRIPT metan_b_rr_on +BEGIN + metan_b.cb_log.enable + metan_b.cb_eform.enable +END + +PROGRAM metan_b_or_on +BEGIN + call metan_b.cb_log.enable + call metan_b.cb_eform.enable + call metan_b.r_peto.enable + if !metan_b.r_peto { + call metan_b.cb_cornfield.enable + } + if !(metan_b.r_random | metan_b.r_randomi) { + call metan_b.cb_chi2.enable + } + call metan_b.cb_breslow.enable +END + +PROGRAM metan_b_or_off +BEGIN + if !metan_b.r_rr { + call metan_b.cb_log.disable + call metan_b.cb_eform.disable + } + call metan_b.r_peto.disable + call metan_b.cb_cornfield.disable + call metan_b.cb_chi2.disable + call metan_b.cb_breslow.disable +END + +PROGRAM metan_b_rr_off +BEGIN + if !metan_b.r_or { + call metan_b.cb_log.disable + call metan_b.cb_eform.disable + } +END + +SCRIPT graph_xlabel_on +BEGIN + graph.ed_xlabel.enable + graph.cb_force.enable +END + +SCRIPT graph_xlabel_off +BEGIN + graph.ed_xlabel.disable + graph.cb_force.disable +END + +SCRIPT graph_counts_on +BEGIN + graph.cb_grp1.enable + graph.cb_grp2.enable +END + +SCRIPT graph_counts_off +BEGIN + graph.cb_grp1.disable + graph.cb_grp2.disable + graph.cb_grp1.setoff + graph.cb_grp2.setoff + graph.ed_grp1.disable + graph.ed_grp2.disable +END + +SCRIPT graph_b1_on +BEGIN + graph.tx_b1_l.enable + graph.ed_b1_l.enable + graph.tx_b1_r.enable + graph.ed_b1_r.enable +END + +SCRIPT graph_b1_off +BEGIN + graph.tx_b1_l.disable + graph.ed_b1_l.disable + graph.tx_b1_r.disable + graph.ed_b1_r.disable +END + + +PROGRAM command +BEGIN + put " metan " + if main.r_binary { + varlist main.vl_binary + } + if main.r_continuous { + varlist main.vl_contin_exp main.vl_contin_ctl + } + if main.r_effect_ci { + varlist main.vl_effect_ci + } + if main.r_effect_se { + varlist main.vl_effect_se + } + INCLUDE _ifin_pr + beginoptions + if main.cb_name | main.cb_year { + put "label(" + if main.cb_name { + put "namevar=" main.vn_name + } + if main.cb_name & main.cb_year { + put ", " + } + if main.cb_year { + put "yearvar=" main.vn_year + } + put ") " + } + optionarg main.vl_sortby + optionarg main.vl_by + optionarg main.ed_ilevel + optionarg main.ed_olevel + optionarg main.vn_wgt + option main.cb_nokeep + option main.cb_nosubgroup + option main.cb_sgweight + if main.r_binary { + if !main.vn_wgt { + option radio(metan_b r_fixed r_fixedi r_random r_randomi r_peto) + } + option radio(metan_b r_rr r_or r_rd) + option metan_b.cb_cornfield + option metan_b.cb_chi2 + option metan_b.cb_breslow + option metan_b.cb_log + option metan_b.cb_eform + option metan_b.cb_nograph + option metan_b.cb_notable + optionarg metan_b.ed_cc + option metan_b.cb_nointeger + } + if main.r_continuous { + if !main.vn_wgt { + option radio(metan_c r_fixed r_random) + } + option radio(metan_c r_cohen r_hedges r_glass r_nostandard) + option metan_c.cb_nograph + option metan_c.cb_notable + option metan_c.cb_nointeger + } + if main.r_effect_se | main.r_effect_ci { + if !main.vn_wgt { + option radio(metan_e r_fixed r_random) + } + optionarg metan_e.ed_effect + option metan_e.cb_nograph + option metan_e.cb_notable + } + optionarg graph.fi_saving + optionarg graph.ed_xlabel + option graph.cb_force + option graph.cb_counts + option graph.cb_nowt + option graph.cb_nostats + option graph.cb_nooverall + option graph.cb_nobox + optionarg graph.ed_grp1 + optionarg graph.ed_grp2 + optionarg graph.ed_texts + optionarg graph.ed_legend + optionarg graph.ed_boxy + optionarg graph.ed_boxs + put graph.ed_gopts7 " " + if graph.cb_b1 { + put "b1(*I:" graph.ed_b1_l "*" graph.ed_b1_r ") " + } + endoptions +END diff --git a/Modules/ado/plus/m/metan.hlp b/Modules/ado/plus/m/metan.hlp new file mode 100644 index 0000000..8a99249 --- /dev/null +++ b/Modules/ado/plus/m/metan.hlp @@ -0,0 +1,919 @@ +{smcl} +{* 7Jul2008}{...} +{hline} +help for {hi:metan}, {hi:labbe} +{hline} + + +{title:Fixed and random effects meta-analysis} + +{p 8 12 2} +{cmd:metan} +{it:varlist} +[{cmd:if} {it:exp}] +[{cmd:in} {it:range}] +[{it:weight}] +[{cmd:,} +{it:measure_and_model_options} +{it:options_for_continuous_data} +{it:output_options} +{it:forest_plot_options} +] + +{p 12 12 2} +where {it:measure_and_model_options} may be + +{p 12 12 2} +{cmd:or} +{cmd:rr} +{cmd:rd} +{cmd:fixed} +{cmd:random} +{cmd:fixedi} +{cmd:peto} +{cmd:cornfield} +{cmd:chi2} +{cmd:breslow} +{cmdab:noint:eger} +{cmd:cc(}{it:#}{cmd:)} +{cmd:wgt(}{it:weightvar}{cmd:)} +{cmd:second(}{it:model} or {it:estimates and description}{cmd:)} +{cmd:first(}{it:estimates and description}{cmd:)} + +{p 12 12 2} +and where {it:options_for_continuous_data} may be + +{p 12 12 2} +{cmd:cohen} +{cmd:hedges} +{cmd:glass} +{cmd:nostandard} +{cmd:fixed} +{cmd:random} + +{p 12 12 2} +and where {it:output_options} may be + +{p 12 12 2} +{cmd:by(}{it:byvar}{cmd:)} +{cmd:nosubgroup} +{cmd:sgweight} +{cmd:log} +{cmd:eform} +{cmd:efficacy} +{cmdab:il:evel(}{it:#}{cmd:)} +{cmdab:ol:evel(}{it:#}{cmd:)} +{cmd:sortby(}{it:varlist}{cmd:)} +{cmd:label(}{it:namevar yearvar}{cmd:)} +{cmd:nokeep} +{cmd:notable} +{cmd:nograph} +{cmd:nosecsub} + +{p 12 12 2} +and where {it:forest_plot_options} may be + +{p 12 12 2} +{cmd:legend(}{it:string}{cmd:)} +{cmdab:xla:bel(}{it:#},...{cmd:)} +{cmdab:xt:ick(}{it:#},...{cmd:)} +{cmd:boxsca(}{it:#}{cmd:)} +{cmd:nobox} +{cmd:nooverall} +{cmd:nowt} +{cmd:nostats} +{cmd:group1(}{it:string}{cmd:)} +{cmd:group2(}{it:string}{cmd:)} +{cmd:effect(}{it:string}{cmd:)} +{cmd:force} + +{p 12 12 2} +...with further {it:forest_plot_options} in the version 9 update + +{p 12 12 2} +{cmd:lcols(}{it:varlist}{cmd:)} +{cmd:rcols(}{it:varlist}{cmd:)} +{cmd:astext(}{it:#}{cmd:)} +{cmd:double} +{cmd:nohet} +{cmd:summaryonly} +{cmd:rfdist} +{cmdab:rfl:evel(}{it:#}{cmd:)} +{cmd:null(}{it:#}{cmd:)} +{cmd:nulloff} +{cmd:favours(}{it:string} # {it:string}{cmd:)} +{cmd:firststats(}{it:string}{cmd:)} +{cmd:secondstats(}{it:string}{cmd:)} +{cmd:boxopt(}{it:}{cmd:)} +{cmd:diamopt(}{it:}{cmd:)} +{cmd:pointopt(}{it:}{cmd:)} +{cmd:ciopt(}{it:}{cmd:)} +{cmd:olineopt(}{it:}{cmd:)} +{cmd:classic} +{cmd:nowarning} +{cmd:dp(}{it:#}{cmd:)} +{it:graph_options} + + +{p 8 12 2} +{cmd:labbe} +{it:varlist} +[{cmd:if} {it:exp}] +[{cmd:in} {it:range}] +[{it:weight}] +[{cmd:,} +{cmd:nowt} +{cmdab:per:cent} +{cmd:or(}{it:#}{cmd:)} +{cmd:rr(}{it:#}{cmd:)} +{cmd:rd(}{it:#}{cmd:)} +{cmd:null} +{cmd:logit} +{cmd:wgt(}{it:weightvar}{cmd:)} +{cmd:symbol(}{it:symbolstyle}{cmd:)} +{cmd:nolegend} +{cmd:id(}{it:idvar}{cmd:)} +{cmd:textsize(}{it:#}{cmd:)} +{cmd:clockvar(}{it:clockvar}{cmd:)} +{cmd:gap(}{it:#}{cmd:)} +{it:graph_options} + + +{title:Description} + +{p 4 4 2} +These routines provide facilities to conduct meta-analyses of data from +more than one study and to graph the results. Either binary (event) or +continuous data from two groups may be combined using the {cmd:metan} +command. Additionally, intervention effect estimates with corresponding +standard errors or confidence intervals may be meta-analysed. Several +meta-analytic methods are available, and the results may be displayed +graphically in a Forest plot. A test of whether +the summary effect measure is equal to the null is given, +as well as a test for heterogeneity, i.e., whether the true effect in all +studies is the same. Heterogeneity is also quantified using the I-squared +measure (Higgins et al 2003). + +{p 4 4 2} +{cmd:metan} (the main meta-analysis routine) requires either two, three, four +or six variables to be declared. When four variables are specified +these correspond to the number of events and non-events in the experimental group +followed by those of the control group, and +analysis of binary data is performed on the 2x2 table. +With six variables, the data are assumed +continuous and to be the sample size, mean and standard deviation of +the experimental group followed by those of the control group. +If three variables are specified these are assumed to be the effect estimate and +its lower and upper confidence interval, and it is suggested that these are +log transformed for odds ratios or risk ratios and the {cmd: eform} option used. +If two variables are specified these are assumed to be the effect estimate and standard +error; again, it is recommended that odds ratios or risk ratios are log transformed. + +{p 4 4 2} +{cmd:labbe} draws a L'Abbe plot for event data (proportion of successes in the +two groups). This is an alternative to the graph produced by {cmd:metan}. + +{p 4 4 2} +{cmd:funnel} may be used for producing a "funnel plot", a graph of either the +study sample size, standard error or precision (inverse of s.e.) against +the effect size. + +{p 4 4 2} +Note that the {cmd:metan} command now requires +Stata version 9 and has been updated +with several new options. Changes are mainly to graphics options which +are collected in the section {it: Further options in the v9 update for metan: Forest plot}, +or otherwise marked {it:v9 update}. The previous version is still available under +the name -metan7- + + +{title:Remarks on funnel (discontinued)} + +{p 4 4 2} +The {cmd:metafunnel} command has more options for +funnel plots and version 8 graphics; as such {cmd:funnel} has been removed. +See {help metafunnel} (if installed) + + + +{title:Options for metan} + +{dlgtab:Specifying the measure and model} + +{p 4 4 2} +These options apply to binary data. + +{p 4 8 2} +{cmd:rr} pools risk ratios (the default). + +{p 4 8 2} +{cmd:or} pools odds ratios. + +{p 4 8 2} +{cmd:rd} pools risk differences. + +{p 4 8 2} +{cmd:fixed} specifies a fixed effect model using the method of + Mantel and Haenszel (the default). + +{p 4 8 2} +{cmd:fixedi} specifies a fixed effect model using the inverse variance method. + +{p 4 8 2} +{cmd:peto} specifies that Peto's method is used to pool odds ratios. + +{p 4 8 2} +{cmd:random} specifies a random effects model using the method of + DerSimonian & Laird. + +{p 4 8 2} +{cmd:cornfield} computes confidence intervals for odds ratios by method of + Cornfield, rather than the (default) Woolf method. + +{p 4 8 2} +{cmd:chi2} displays chi-squared statistic (instead of z) for the test + of significance of the pooled effect size. This is available only for + odds ratios pooled using Peto or Mantel-Haenszel methods. + +{p 4 8 2} +{cmd:breslow} produces Breslow-Day test for homogeneity of ORs. + +{p 4 8 2} +{cmd:cc(}{it:#}{cmd:)} defines a fixed continuity correction to add in the case where + a study contains a zero cell. By default, {cmd:metan} + adds 0.5 to each cell of a trial where a zero is encountered when + using Inverse-Variance, Der-Simonian & Laird or Mantel-Haenszel + weighting to enable finite variance estimators to be derived. + However, the {cmd:cc()} option allows the use of other constants + (including none). See also the {cmd:nointeger} option. + +{p 4 8 2} +{cmd:nointeger} allows the cell counts to be non-integers. This may be useful + when a variable continuity correction is sought for studies containing + zero cells, but also may be used in other circumstances, such as where a + cluster-randomised trial is to be incorporated and the "effective sample + size" is less than the total number of observations. + +{p 4 8 2} +{cmd:wgt(}{it:weightvar}{cmd:)} specifies alternative weighting + for any data type. The effect size is to be computed by assigning + a weight of {it:weightvar} to the studies. When RRs or ORs are declared, + their logarithms are weighted. You should only use this option if you are + satisfied that the weights are meaningful. + +{p 4 8 2} +{cmd:second(}{it:model} or {it:estimates and description}{cmd:)} ({it:v9 update}) + A second analysis may be performed using another method, using {cmd:fixed}, + {cmd:random} or {cmd:peto}. Alternatively, the user may define their own + estimate and 95% CI based on calculations performed externally to {cmd:metan}, + along with a description of their method, in the format + {it: es lci uci description}. The results of this analysis are then displayed + in the table and forest plot. Note that if {cmd:by} is used then sub-estimates + from the second method are not displayed with user defined estimates, for + obvious reasons. + +{p 4 8 2} +{cmd:first(}{it:estimates and description}{cmd:)} ({it:v9 update}) + Use of this command completely changes the way {cmd:metan} operates, as results + are no longer based on any standard methods. The user defines their own + estimate, 95% CI and description as in the above, and must supply their own + weightings using {cmd:wgt(}{it:weightvar}{cmd:)} to control display of box sizes. Note + that data must be supplied in the 2 or 3 variable syntax + ({it:theta se_theta} or {it:es lci uci}) and + {cmd:by} may not be used used for obvious reasons. + +{dlgtab:Continuous data} + +{p 4 8 2} +{cmd:cohen} pools standardised mean differences by the method of Cohen + (the default). + +{p 4 8 2} +{cmd:hedges} pools standardised mean differences by the method of Hedges. + +{p 4 8 2} +{cmd:glass} pools standardised mean differences by the method of Glass. + +{p 4 8 2} +{cmd:nostandard} pools unstandardised mean differences. + +{p 4 8 2} +{cmd:fixed} specifies a fixed effect model using the inverse variance method + (the default). + +{p 4 8 2} +{cmd:random} specifies a random effects model using the DerSimonian & Laird + method. + +{p 4 8 2} +{cmd:nointeger} denotes that the number of observations in each arm does not + need to be an integer. By default, the first and fourth variables specified + (containing N_intervention and N_control respectively) may occasionally be + non-integer (see entry for {cmd:nointeger} under binary data). + +{dlgtab:Output} + +{p 4 8 2} +{cmd:by()} specifies that the meta-analysis is to be stratified + according to the variable declared. + +{p 4 8 2} +{cmd:sgweight} specifies that the display is to present the percentage + weights within each subgroup separately. By default {cmd:metan} presents + weights as a percentage of the overall total. + +{p 4 8 2} +{cmd:log} reports the results on the log scale + (valid for OR and RR analyses from raw data counts only). + +{p 4 8 2} +{cmd:nosubgroup} indicates that no within-group results are to be + presented. By default {cmd:metan} pools trials both within and across + all studies. + +{p 4 8 2} +{cmd:eform} exponentiates all effect sizes and confidence intervals + (valid only when the input variables are log odds ratios or log + hazard ratios with standard error or confidence intervals). + +{p 4 8 2} +{cmd:efficacy} expresses results as the vaccine efficacy (the proportion + of cases that would have been prevented in the placebo group that + would have been prevented had they received the vaccination). + Only available with odds ratios (OR) or risk ratios (RR). + +{p 4 8 2} +{cmd:ilevel(}{it:#}{cmd:)} specifies the coverage (eg 90,95,99 percent) for the + individual trial confidence intervals. Default: {cmd:$S_level}. + {cmd:ilevel()} and {cmd:olevel()} need not be the same. See {help set level}. + +{p 4 8 2} +{cmd:olevel(}{it:#}{cmd:)} specifies the coverage (eg 90,95,99 percent) for the + overall (pooled) trial confidence intervals. Default: {cmd:$S_level}. + {cmd:ilevel()} and {cmd:olevel()} need not be the same. See {help set level}. + +{p 4 8 2} +{cmd:sortby(}{it:varlist}{cmd:)} sorts by variable(s) in {it:varlist} + +{p 4 8 2} +{cmd:label([namevar=}{it:namevar}{cmd:], [yearvar=}{it:yearvar}{cmd:])} + labels the data by its name, year or both. Either or both option/s + may be left blank. For the table display the overall length of the + label is restricted to 20 characters. The option {cmd:lcols()} will + override this if invoked. + +{p 4 8 2} +{cmd:nokeep} prevents the retention of study parameters in permanent + variables (see saved results below). + +{p 4 8 2} +{cmd:notable} prevents display of table of results. + +{p 4 8 2} +{cmd:nograph} prevents display of graph. + +{p 4 8 2} +{cmd:nosecsub} ({it:v9 update}) prevents the display of sub-estimates + using the second method if {cmd:second()} + is used. Note that this is invoked automatically with user-defined + estimates. + +{dlgtab:Forest plot} + +{p 4 8 2} +{cmd:effect()} may be used when the effect size and its standard error + are declared. This allows the graph to name the summary statistic used. + +{p 4 8 2} +{cmd:nooverall} revents display of overall effect size on graph + (automatically enforces the {cmd:nowt} option). + +{p 4 8 2} +{cmd:nowt} prevents display of study weight on the graph. + +{p 4 8 2} +{cmd:nostats} prevents display of study statistics on graph. + +{p 4 8 2} +{cmd:counts} ({it:v9 update}) displays data counts (n/N) for each group when using + binary data, or the sample size, mean and SD for each group if mean + differences are used (the latter is a new feature). + +{p 4 8 2} +{cmd:group1(}{it:string}{cmd:)}, {cmd:group2(}{it:string}{cmd:)} may be + used with the {cmd:counts} option: the text should contain the + names of the two groups. + +{p 4 8 2} +{cmd:xlabel()} ({it:v9 update}) defines x-axis labels. This has been modified + so that any number of points may defined. Also, there are no + longer any checks made as to whether these points are sensible, so the + user may define anything if the {cmd:force} option is used. Points must + be comma separated. + +{p 4 8 2} +{cmd:xtick()} adds tick marks to the x-axis. Points must + be comma separated. + +{p 4 8 2} +{cmd:force} forces the x-axis scale to be in the range specified + by {cmd:xlabel()}. + +{p 4 8 2} +{cmd:boxsca()} ({it:v9 update}) controls box scaling. + This has been modified slightly so that the default is 100 (as in a + percentage) and may be increased or decreased as such (e.g., 80 or 120 for + 20% smaller or larger respectively) + +{p 4 8 2} +{cmd:nobox} prevents a "weighted box" being drawn for each study + and markers for point estimates only are shown. + +{p 4 8 2} +{cmd:texts()} ({it:v9 update}) specifies font size for text display on graph. + This has been modified slightly so that the default is 100 (as in a + percentage) and may be increased or decreased as such (e.g., 80 or 120 for + 20% smaller or larger respectively) + +{dlgtab:Further options for the forest plot in the v9 update} + +{p 4 8 2} +{cmd:lcols(}{it:varlist}{cmd:)}, {cmd:rcols(}{it:varlist}{cmd:)} + define columns of additional data to + the left or right of the graph. The first two columns on the right are + automatically set to effect size and weight, unless suppressed using + the options {cmd:nostats} and {cmd:nowt}. If {cmd:counts} is used this + will be set as the third column. {cmd:textsize()} can be used to fine-tune + the size of the text in order to acheive a satisfactory appearance. + The columns are labelled with the variable label, or the variable name + if this is not defined. The first variable specified in {cmd:lcols()} is assumed to be + the study identifier and this is used in the table output. + +{p 4 8 2} +{cmd:astext(}{it:#}{cmd:)} + specifies the percentage of the graph to be taken up by text. + The default is 50 and the percentage must be in the range 10-90. + +{p 4 8 2} +{cmd:double} + allows variables specified in {cmd:lcols} and {cmd:rcols} to run over two + lines in the plot. This may be of use if long strings are to be used. + +{p 4 8 2} +{cmd:nohet} + prevents display of heterogeneity statistics in the graph. + +{p 4 8 2} +{cmd:summaryonly} + shows only summary estimates in the graph (may be of use for multiple + subgroup analyses) + +{p 4 8 2} +{cmd:rfdist} + displays the confidence interval of the approximate predictive + distribution of a future trial, based on the extent of heterogeneity. + This incorporates uncertainty in the location and spread of the random + effects distribution using the formula {cmd: t(df) x sqrt(se2 + tau2)} + where t is the t-distribution with k-2 degrees of freedom, se2 is the + squared standard error and tau2 the heterogeneity statistic. + The CI is then displayed with lines extending from the diamond. Note that + with <3 studies the distribution is inestimable and effectively infinite, thus + displayed with dotted lines, and where heterogeneity is zero there is still + a slight extension as the t-statistic is always greater than the corresponding + normal deviate. For further information see Higgins JPT, Thompson SG (2006) + +{p 4 8 2} +{cmd:rflevel(}{it:#}{cmd:)} specifies the coverage (eg 90,95,99 percent) for the + confidence interval of the predictive distribution. Default: {cmd:$S_level}. + See {help set level}. + +{p 4 8 2} +{cmd:null(}{it:#}{cmd:)} + displays the null line at a user-defined value rather than 0 or 1. + +{p 4 8 2} +{cmd:nulloff} + removes the null hypothesis line from the graph + +{p 4 8 2} +{cmd:favours(}{it:string} # {it:string}{cmd:)} + applies a label saying something about the treatment effect to either + side of the graph (strings are separated by the # symbol). This replaces + the feature available in {cmd:b1title} in the previous version of metan. + +{p 4 8 2} +{cmd:firststats(}{it:string}{cmd:)}, {cmd:secondstats(}{it:string}{cmd:)} + labels overall user-defined estimates when these have been specified. + Labels are displayed in the position usually given to the heterogeneity + statistics. + +{p 4 8 2} +{cmd:boxopt()}, {cmd:diamopt()}, {cmd:pointopt()}, {cmd:ciopt()}, {cmd:olineopt()} + specify options for the graph routines within the program, allowing the + user to alter the appearance of the graph. Any options associated with a + particular graph command may be used, except some that would cause incorrect + graph appearance. For example, diamonds are plotted using the {help twoway pcspike} + command, so options for line styles are available (see {help line options}); + however, altering the x-y + orientation with the option {cmd:horizontal} or {cmd:vertical} is not + allowed. So, {cmd:diamopt(lcolor(green) lwidth(thick))} feeds into a command + such as {cmd:pcspike(y1 x1 y2 x2, lcolor(green) lwidth(thick))} + +{p 8 8 2} +{cmd:boxopt()} controls the boxes and uses options for a weighted marker +(e.g., shape, colour; but not size). See {help marker options} + +{p 8 8 2} +{cmd:diamopt()} controls the diamonds and uses options for pcspike (not horizontal/vertical). +See {help line options} + +{p 8 8 2} +{cmd:pointopt()} controls the point estimate using marker options. +See {help marker options} and {help marker label options} + +{p 8 8 2} +{cmd:ciopt()} controls the confidence intervals for studies using options +for pcspike (not horizontal/vertical). See {help line options} + +{p 8 8 2} +{cmd:olineopt()} controls the overall effect line with options for an additional +line (not position). See {help line options} + +{p 4 8 2} +{cmd:classic} specifies that solid black boxes without point estimate markers are used as +in the previous version of metan. + +{p 4 8 2} +{cmd:nowarning} switches off the default display of a note warning that studies are +weighted from random effects anaylses. + +{p 4 8 2} +{cmd:dp(}{it:#}{cmd:)} sets the number of decimal places that effect estimates are displayed with +(default is 2). + +{p 4 8 2} +{it:graph_options} + specifies overall graph options that would appear at the end of a {cmd:twoway} + graph command. This allows the addition of titles, subtitles, captions etc., + control of margins, plot regions, graph size, aspect ratio and the use of schemes. + As titles may be added in this way previous options {cmd:b2title} etc. are no + longer necessary. See {search graph options} + + +{title:Options for labbe} + +{p 4 8 2} +{cmd:nowt} declares that the plotted data points are to be the same size. + +{p 4 8 2} +{cmd:percent} displays the event rates as percentages rather than proportions. + +{p 4 8 2} +{cmd:null} draws a line corresponding to a null effect (ie p1=p2). + +{p 4 8 2} +{cmd:or(}{it:#}{cmd:)} draws a line corresponding to a fixed odds ratio of + {it:#}. + +{p 4 8 2} +{cmd:rd(}{it:#}{cmd:)} draws a line corresponding to a fixed risk difference of + {it:#}. + +{p 4 8 2} +{cmd:rr(}{it:#}{cmd:)} draws a line corresponding to a fixed risk ratio + of {it:#}. See also the {cmd:rrn()} option. + +{p 4 8 2} +{cmd:rrn(}{it:#}{cmd:)} draws a line corresponding to a fixed risk ratio + (for the non-event) of {it:#}. + The {cmd:rr()} and {cmd:rrn()} options may require explanation. + Whereas the OR and RD are invariant to the definition of which of + the binary outcomes is the "event" and which is the "non-event", + the RR is not. That is, while the command {cmd:metan a b c d , or} + gives the same result as {cmd:metan b a d c , or} (with direction + changed), an RR analysis does not. The L'Abbe plot allows the display + of either or both to be superimposed risk difference. + +{p 4 8 2} +{cmd:logit} is for use with the {cmd:or()} option; it displays the + probabilities on the logit scale ie log(p/1-p). On the logit scale the + odds ratio is a linear effect, and so this makes it easier to assess the + "fit" of the line. + +{p 4 8 2} +{cmd:wgt(}{it:weightvar}{cmd:)} specifies alternative weighting by the specified variable +(default is sample size). + +{p 4 8 2} +{cmd:symbol(}{it:symbolstyle}{cmd:)} allows the symbol to be changed (see help {help symbolstyle}) the +default being hollow circles (or points if weights are not used). + +{p 4 8 2} +{cmd:nolegend} suppresses a legend being displayed (the default if more than one +line corresponding to effect measures are specified). + +{p 4 8 2} +{cmd:id(}{it:idvar}{cmd:)} displays marker labels with the specified ID variable {it:idvar}. +{cmd:clockvar()} and {cmd:gap()} may be used to fine-tune the display, which may become +unreadable if studies are clustered together in the graph. + +{p 4 8 2} +{cmd:textsize(}{it:#}{cmd:)} increases or decreases the text size of the id label by specifying +{it:#} to be more or less than unity. The default is usually satisfactory, but may need to be adjusted. + +{p 4 8 2} +{cmd:clockvar(}{it:clockvar}{cmd:)} specifies the position of {it:idvar} around the +study point, as if it were a clock face (values must be integers- see {help clockposstyle}). +This may be used to organise labels where studies are clustered together. By default, labels are positioned +to the left (9 o'clock) if above the null and to the right (3 o'clock) if below. Missing values +in {it:clockvar} will be assigned the default position, so this need not be specified for all observations. + +{p 4 8 2} +{cmd:gap(}{it:#}{cmd:)} increases or decreases the gap between the study marker and the id label by specifying +{it:#} to be more or less than unity. The default is usually satisfactory, but may need to be adjusted. + +{p 4 8 2} +{it:graph_options} are options for Stata 8 graphs (see help on {help graph}). + + +{title:Remarks on metan} + +{p 4 4 2} +For two or three variables, a variance-weighted analysis is performed in +a similar fashion to the {help meta} command; the two variable syntax +is {it:theta} and {it:SE(theta)}. The 3 variable syntax is {it:theta}, +{it:lower ci (theta)}, {it:upper ci (theta)}. Note that in this situation +"{it:theta}" is taken to be the logarithm of the effect size if the odds +ratio or risk ratio is used. {hi:This differs from the equivalent in the {cmd:meta} command}. +This program does not assume the three variables need log transformation: +if odds ratios or risk ratios are combined, it is up to the user to +log-transform them first. The {cmd:eform} option may be used to change +back to the original scale if needed. By default the confidence +intervals are assumed symmetric, and the studies are pooled by taking +the variance to be equal to (CI width)/2z. + +{p 4 4 2} +Note that for graphs on the log scale (that is, ORs or RRs), values +outside the range [10e-8,10e8] are not displayed, and similarly graphs of +other measures (log ORs, RDs, SMDs) are restricted to the range [-10e8,10e8]. +A confidence interval which extends beyond this, or the specified scale +if {cmd:force} is used, will have an arrow added at the end of the range. + +{p 4 4 2} +{hi: Further notes on v9 update:} If {cmd:by} is used with a string variable the +stratification variable is not sorted alpha-numerically and the original +order that the groups appear in the data is preserved. This may be of use if +a particular display order is required; if not, {cmd:sortby} may be used. +The option {cmd:counts} is now available for continuous data and displays +sample size, mean and SD in each group. The estimate for heterogeneity between +groups from a stratified analysis using the Mantel-Haenszel method, and +arguably the Peto method, is invalid. Therefore this is not displayed in the +output for either of these methods. + +{p 4 4 2} +Note that there is a small add-on program to calculate the confidence interval for +the I-squared statistic- type {cmd:i2ci} after running metan. This uses the method +described by Higgins & Thompson (2002), Appendix A2. + + +{title:Remarks on labbe} + +{p 4 4 2} +By default the size of the plotting symbol is proportional to the sample +size of the study. If weights are specified the plotting size will be +proportional to the weight variable. Note that {cmd:labbe} has now been updated to version 8 graphics. +All options work the same as in the previous version, and some minor graphics options have been added. + + + +{title:Stored} + +By default, {cmd:metan} adds the following new variables to the data set: + + _ES Effect size (ES) + _seES Standard error of ES + or, when OR or RR are specfied: + _selogES the standard error of its logarithm + _LCI Lower confidence limit for ES + _UCI Upper confidence limit for ES + _WT Study percentage weight + _SS Study sample size + + +{title:Examples} + +{p 4 8 2} +All examples use a simulated example dataset (Ross Harris 2006) + +{p 8 12 2} +{stata "use http://fmwww.bc.edu/repec/bocode/m/metan_example_data":. use http://fmwww.bc.edu/repec/bocode/m/metan_example_data} + +{p 4 8 2} +Risk difference from raw cell counts, random effects model, "label" specification with counts displayed + +{p 8 12 2} +{cmd:. metan tdeath tnodeath cdeath cnodeath, } +{p_end} +{p 12 12 2} +{cmd:rd random label(namevar=id, yearid=year) counts} +{p_end} +{p 12 12 2} +{it:({stata "metan_examples metan_example_basic":click to run})} + +{p 4 8 2} +Sort by year, use data columns syntax. Text size increased, specify percentage of graph as text and +two lines per study; suppress stats, weight, heterogeneity stats and table. + + +{p 8 12 2} +{cmd:. metan tdeath tnodeath cdeath cnodeath, } +{p_end} +{p 12 12 2} +{cmd:sortby(year) lcols(id year country) rcols (population) } +{p_end} +{p 12 12 2} +{cmd:textsize(110) astext(60) double nostats nowt nohet notable} +{p_end} +{p 12 12 2} +{it:({stata "metan_examples metan_example_cols":click to run})} + +{p 4 8 2} +Analyse continuous data (6 parameter syntax), stratify by type of study, with weights summing to 100 within sub group, +second analysis specified, display random effects distribution, show raw data counts, display +"favours treatment vs. favours control" labels + +{p 8 12 2} +{cmd:. metan tsample tmean tsd csample cmean csd, } +{p_end} +{p 12 12 2} +{cmd:by(type_study) sgweight fixed second(random) rfdist } +{p_end} +{p 12 12 2} +{cmd:counts label(namevar = id) } +{p_end} +{p 12 12 2} +{cmd:favours(Treatment reduces blood pressure # Treatment increases blood pressure)} +{p_end} +{p 12 12 2} +{it:({stata "metan_examples metan_example_by":click to run})} + +{p 4 8 2} +Generate log odds ratio and standard error, analyse with 2 parameter syntax. Graph has exponential form, +scale is forced within set limits and ticks added, effect label specified. + +{p 8 12 2} +{cmd:. gen logor = ln( (tdeath*cnodeath)/(tnodeath*cdeath) )} + +{p 8 12 2} +{cmd:. gen selogor = sqrt( (1/tdeath) + (1/tnodeath) + (1/cdeath) + (1/cnodeath) )} + +{p 8 12 2} +{cmd:. metan logor selogor, eform xlabel(0.5, 1, 1.5, 2, 2.5) } +{p_end} +{p 12 12 2} +{cmd:force xtick(0.75, 1.25, 1.75, 2.25) effect(Odds ratio)} +{p_end} +{p 12 12 2} +{it:({stata "metan_examples metan_example_2param":click to run})} + +{p 4 8 2} +Display diagnostic test data with 3 parameter syntax. Weight is number of positive diagnoses, axis label set +and null specified at 50%. Overall effect estimate is not displayed, graph for visual examination only. + +{p 8 12 2} +{cmd:. metan percent lowerci upperci, wgt(n_positives) } +{p_end} +{p 12 12 2} +{cmd:xlabel(0,10,20,30,40,50,60,70,80,90,100) force } +{p_end} +{p 12 12 2} +{cmd:null(50) label(namevar=id) nooverall notable } +{p_end} +{p 12 12 2} +{cmd:title(Sensitivity, position(6))} +{p_end} +{p 12 12 2} +{it:({stata "metan_examples metan_example_diag":click to run})} + +{p 4 8 2} +User has analysed data with a non-standard technique and supplied effect estimates, weights and description of statistics. +The scheme "Economist" has been used. + +{p 8 12 2} +{cmd:. metan OR ORlci ORuci, wgt(bweight) } +{p_end} +{p 12 12 2} +{cmd:first(0.924 0.753 1.095 Bayesian) } +{p_end} +{p 12 12 2} +{cmd:firststats(param V=3.86, p=0.012) } +{p_end} +{p 12 12 2} +{cmd:label(namevar=id) } +{p_end} +{p 12 12 2} +{cmd:xlabel(0.25, 0.5, 1, 2, 4) force } +{p_end} +{p 12 12 2} +{cmd:null(1) aspect(1.2) scheme(economist)} +{p_end} +{p 12 12 2} +{it:({stata "metan_examples metan_example_user":click to run})} + +{p 4 8 2} +Variable "counts" defined showing raw data. Options to change the box, effect estimate marker and confidence interval used, +and the counts variable has been attached to the estimate marker as a label. + +{p 8 12 2} +{cmd:. gen counts = ". " + string(tdeath) + "/" + string(tdeath+tnodeath) } +{p_end} +{p 12 12 2} +{cmd:+ ", " + string(cdeath) + "/" + string(cdeath+cnodeath)} + +{p 8 12 2} +{cmd: . metan tdeath tnodeath cdeath cnodeath, } +{p_end} +{p 12 12 2} +{cmd:lcols(id year) notable } +{p_end} +{p 12 12 2} +{cmd:boxopt( mcolor(forest_green) msymbol(triangle) ) } +{p_end} +{p 12 12 2} +{cmd:pointopt( msymbol(triangle) mcolor(gold) msize(tiny) } +{p_end} +{p 12 12 2} +{cmd:mlabel(counts) mlabsize(vsmall) mlabcolor(forest_green) mlabposition(1) ) } +{p_end} +{p 12 12 2} +{cmd:ciopt( lcolor(sienna) lwidth(medium) )} +{p_end} +{p 12 12 2} +{it:({stata "metan_examples metan_example_custom":click to run})} + +{p 4 8 2} +L'Abbe plot with labelled axes and display of risk ratio and risk difference. + +{p 8 12 2} +{cmd:. labbe tdeath tnodeath cdeath cnodeath, } +{p_end} +{p 12 12 2} +{cmd:xlabel(0,0.25,0.5,0.75,1) ylabel(0,0.25,0.5,0.75,1) } +{p_end} +{p 12 12 2} +{cmd:rr(1.029) rd(0.014) null} +{p_end} +{p 12 12 2} +{it:({stata "metan_examples labbe_example":click to run})} + + + +{title:Authors} + +{p 4 4 0} +Michael J Bradburn, Jonathan J Deeks, Douglas G Altman. +Centre for Statistics in Medicine, University of Oxford, +Wolfson College Annexe, Linton Road, Oxford, OX2 6UD, UK + +{title:Version 9 update} + +{p 4 4 0} +Ross J Harris, Roger M Harbord, Jonathan A C Sterne. +Department of Social Medicine, University of Bristol, +Canynge Hall, Whiteladies Road, Bristol BS8 2PR, UK + +{title:Other updates and improvements to code and help file} + +{p 4 4 0} +Patrick Royston. MRC Clinical Trials Unit, 222 Euston Road, +London, NW1 2DA + +{title:Acknowledgements} + +{p 4 4 0} +Thanks to Vince Wiggins, Kit Baum and Jeff Pitblado of Statacorp +who offered advice and helped facilitate the version 9 update. +Thanks also to all the people who helped with beta-testing and +made comments and suggested improvements. + +{title:References} + +{p 4 4 0} +Higgins JPT, Thompson SG, Deeks JJ, +Altman DG. Measuring inconsistency in meta-analyses. BMJ +2003; 327:557-560. {browse "http://dx.doi.org/10.1136/bmj.327.7414.557":http://dx.doi.org/10.1136/bmj.327.7414.557} + +{p 4 4 0} +Higgins JPT, Thompson SG (2006) Presenting random effects meta-analyses: +where we are going wrong? (from presentation, work in preparation) + + +{title:Also see} + + STB: STB-44 sbe24 +On-line: help for {help metan7}, {help metannt} + {help meta} (if installed), {help metacum} (if installed), + {help metareg} (if installed), {help metabias} (if installed), + {help metatrim} (if installed), {help metainf} (if installed), + {help galbr} (if installed), {help metafunnel} (if installed) + diff --git a/Modules/ado/plus/m/metan7.ado b/Modules/ado/plus/m/metan7.ado new file mode 100644 index 0000000..9fe0743 --- /dev/null +++ b/Modules/ado/plus/m/metan7.ado @@ -0,0 +1,2507 @@ +*! version 1.86 1Apr2004 + +/*Revision list at end + +Syntax: +a) binary data: + metan #events_group1 #nonevents_group1 #events_group2 #nonevents_group2 , ... +b) cts data: + metan #group1 mean1 sd1 #group2 mean2 sd2 , ... +c) generic effect size+st error: + metan theta se_theta , ... +d) generic effect size+ci: + metan theta lowerlimit upperlimit , ... + +*/ + +program define metan7 , rclass + version 7.0 + #delimit ; + syntax varlist(min=2 max=6 default=none numeric) [if] [in] [, BY(string) + ILevel(integer $S_level) OLevel(integer $S_level) CC(string) + OR RR RD FIXED FIXEDI RANDOM RANDOMI PETO COHEN HEDGES GLASS noSTANDARD + CHI2 CORNFIELD LOG BRESLOW EFORM noINTeger noOVERALL noSUBGROUP SGWEIGHT + SORTBY(passthru) noKEEP noGRAPH noTABLE LABEL(string) SAVING(passthru) noBOX + XLAbel(passthru) XTick(passthru) FORCE BOXSCA(real 1.0) BOXSHA(integer 4) + TEXTS(real 1.0) T1title(string) T2title(string) LEGEND(string) + B1title(string) B2title(string) noWT noSTATS COUNTS WGT(varlist numeric max=1) + GROUP1(string) GROUP2(string) EFFECT(string) ] ; + #delimit cr + + + global MA_FBSH=`boxsha' + global MA_FBSC=`boxsca' + global MA_ESLA="`effect'" + if "`legend'"!="" { global S_TX="`legend'" } + else { global S_TX "Study" } + +*label groups + if "`group1'"=="" { global MA_G1L "Treatment" } + else { global MA_G1L "`group1'" } + if "`group2'"=="" { global MA_G2L "Control" } + else { global MA_G2L "`group2'" } + if "`legend'"!="" { global S_TX "`legend'" } + + if (`texts'>2 | `texts'<0.1 ) {local texts=1} + global MA_FTSI=`texts' + if ("`by'"=="" & "`overall'"!="") {local wt "nowt"} + if `ilevel'<1 {local ilevel=`ilevel'*100 } + if `ilevel'>99 | `ilevel'<10 { local ilevel $S_level } + global ZIND= -invnorm((100-`ilevel')/200) + if `olevel'<1 {local olevel=`olevel'*100 } + if `olevel'>99 | `olevel'<10 { local olevel $S_level } + global ZOVE= -invnorm((100-`olevel')/200) + global IND=`ilevel' + global OVE=`olevel' + #delimit ; + global S_1 "."; global S_2 "."; global S_3 "."; global S_4 "."; + global S_5 "."; global S_6 "."; global S_7 "."; global S_8 "."; + global S_9 "."; global S_10 ".";global S_11 ".";global S_12 "."; + #delimit cr + +*If not using own weights set fixed as default + if "`fixed'`random'`fixedi'`randomi'`peto'"=="" & ( "`wgt'"=="" ) { local fixed "fixed" } +*declare study labels for display + if "`label'"!="" { + parse "`label'", parse("=,") + while "`1'"!="" { + cap confirm var `3' + if _rc!=0 { + di in re "Variable `3' not defined" + exit _rc + } + local `1' "`3'" + mac shift 4 + } + } + tempvar code + qui { +*put name/year variables into appropriate macros + if "`namevar'"!="" { + local lbnvl : value label `namevar' + if "`lbnvl'"!="" { quietly decode `namevar', gen(`code') } + else { + gen str10 `code'="" + cap confirm string variable `namevar' + if _rc==0 { replace `code'=`namevar' } + else if _rc==7 { replace `code'=string(`namevar') } + } + } + else { gen str3 `code'=string(_n) } + if "`yearvar'"!="" { + local yearvar "`yearvar'" + cap confirm string variable `yearvar' + if _rc==7 { local str "string" } + if "`namevar'"=="" { replace `code'=`str'(`yearvar') } + else { replace `code'=`code'+" ("+`str'(`yearvar')+")" } + } + if "`wgt'"!="" { +*User defined weights verification + if "`fixed'`random'`fixedi'`randomi'`peto'"!="" { + di in re "Option invalid with user-defined weights" + exit _rc + } + confirm numeric variable `wgt' + local wgt "wgt(`wgt')" + } + } /* End of quietly loop */ + parse "`varlist'", parse(" ") + if "`6'"=="" { + if "`4'"=="" { +*Input is {theta setheta} or {theta lowerci upperci} => UDW, IV or D+L weighting + if "`3'"!="" { +*input is theta lci uci + cap assert ((`3'>=`1') & (`1'>=`2')) + if _rc!=0 { + di in bl "Effect size and confidence intervals invalid:" + di in bl "order should be {effect size, lower ci limit, upper ci limit}" + exit _rc + } + } + cap assert "`log'"=="" + if _rc!=0 { + di in bl "Log option not available without raw data counts: if necessary, transform both" + di in bl "effect and standard error using " in wh "generate" in bl " and re-issue the metan command" + exit _rc + } + + cap assert "`chi2'`cornfield'`peto'`breslow'`counts'`or'`rr'`rd'`standard'`hedges'`glass'`cohen'"=="" + if _rc!=0 { + di in re "Option not available without raw data counts" + exit _rc + } + if "`wgt'"!="" { local method "*" } + else { + if "`random'`randomi'"!="" { + local randomi + local random "random" + local method "D+L" + } + if "`fixed'`fixedi'"!="" { + local fixedi + local fixed "fixed" + local method "I-V" + } + cap assert ("`random'"=="") + ("`fixed'"=="")==1 + if _rc!=0 { + di in re "Specify fixed or random effect/s model" + exit _rc + } + } + cap assert "`cc'"=="" + if _rc!=0 { + di in re "Continuity correction not valid with unless individual counts specified" + exit _rc + } + local callalg "iv_init" + local sumstat "ES" + } /*end of 2-variable set-up */ + if "`4'"!="" { +*Input is 2x2 tables: MH, Peto, IV, D+L or user defined weighting allowed + cap assert "`5'"=="" + if _rc!=0 { + di in re "Wrong number of variables specified" + exit _rc + } + if "`integer'"=="" { + cap { + assert int(`1')==`1' + assert int(`2')==`2' + assert int(`3')==`3' + assert int(`4')==`4' + } + if _rc!=0 { + di in re "Non integer cell counts found" + exit _rc + } + + } + cap assert ( (`1'>=0) & (`2'>=0) & (`3'>=0) & (`4'>=0) ) + if _rc!=0 { + di in re "Non-positive cell counts found" + exit _rc + } + if "`cc'"!="" { +*Ensure Continuity correction is valid + if "`peto'"!="" { + di in re "Peto method not valid with continuity correction" + exit + } +*Currently, allows user to define own constant [0,1) to add to all cells + cap confirm number `cc' + if _rc!=0 { + di in re "Invalid continuity correction: specify a constant number eg metan ... , cc(0.166667)" + exit + } + cap assert (`cc'>=0) & (`cc'<1) + if _rc!=0 { + di in re "Invalid continuity correction: must be in range [0,1)" + exit + } + } + else { local cc "0.5" } + if "`peto'"=="" { local cont "cc(`cc')" } + if "`peto'"!="" { local or "or" } + capture { + assert ( ("`or'"!="")+("`rr'"!="")+("`rd'"!="") <=1 ) + assert ("`fixed'"!="")+("`fixedi'"!="")+("`random'"!="")+ /* + */ ("`randomi'"!="")+("`peto'"!="")+("`wgt'"!="") <=1 + assert "`standard'`hedges'`glass'`cohen'"=="" + } + if _rc!=0 { + di in re "Invalid specifications for combining trials" + exit 198 + } +*Default is set at pooling RRs. + if "`or'"!="" {local sumstat "OR" } + else if "`rd'"!="" {local sumstat "RD" } + else {local sumstat "RR" } + if "`wgt'"!="" { local method "*" } + else if "`random'`randomi'"!="" {local method "D+L" } + else if "`peto'"!="" {local method "Peto"} + else if "`fixedi'"!="" {local method "I-V"} + else {local method "M-H" } + if "`peto'"!="" {local callalg "Peto"} + else {local callalg "`sumstat'"} + if ("`sumstat'"!="OR" | "`method'"=="D+L") & "`chi2'"!="" { + di in re "Chi-squared option invalid for `method' `sumstat'" + exit + } + if ("`sumstat'"!="OR" | "`method'"=="D+L" | "`method'"=="Peto" ) & "`breslow'"!="" { + di in re "Breslow-Day heterogeneity option not available for `method' `sumstat'" + exit + } + if ("`sumstat'"!="OR" & "`sumstat'"!="RR") & "`log'"!="" { + di in re "Log option not appropriate for `sumstat'" + exit + } + if "`keep'"=="" { + cap drop _SS + qui gen _SS =`1'+`2'+`3'+`4' + } + } /* end of binary variable setup */ + } + if "`6'"!="" { +*Input is form N mean SD for continuous data: IV, D+L or user defined weighting allowed + cap assert "`7'"=="" + if _rc!=0 { + di in re "Wrong number of variables specified" + exit _rc + } + if "`integer'"=="" { + cap assert ((int(`1')==`1') & (int(`4')==`4')) + if _rc!=0 { + di in re "Non integer sample sizes found" + exit _rc + } + } + cap assert (`1'>0 & `4'>0) + if _rc!=0 { + di in re "Non positive sample sizes found" + exit _rc + } + if "`random'`randomi'"!="" { + local randomi + local random "random" + } + if "`fixed'`fixedi'"!="" { + local fixedi + local fixed "fixed" + } + cap{ + assert ("`hedges'"!="")+ ("`glass'"!="")+ ("`cohen'"!="")+ ("`standard'"!="")<=1 + assert ("`random'"!="")+ ("`fixed'"!="") <=1 + assert "`or'`rr'`rd'`peto'`log'`cornfield'`chi2'`breslow'`eform'"=="" + } + if _rc!=0 { + di in re "Invalid specifications for combining trials" + exit 198 + } + if "`standard'"!="" { + local sumstat "WMD" + local stand "none" + } + else { + if "`hedges'"!="" {local stand "hedges"} + else if "`glass'"!="" {local stand "glass" } + else {local stand "cohen"} + local sumstat "SMD" + } + local stand "standard(`stand')" + if "`wgt'"!="" { local method "*" } + else if "`random'"!="" { local method "D+L" } + else { local method "I-V" } + if "`counts'"!="" { + di in bl "Data option counts not available with continuous data" + local counts + } + if "`cc'"!="" { + di in re "Continuity correction not available with continuous data" + exit + } + local callalg "MD" + if "`keep'"=="" { + cap drop _SS + qui gen _SS =`1'+`4' + } + } /*end of 6-var set-up*/ + if "`by'"!="" { + cap confirm var `by' + if _rc!=0 { + di in red "Variable `by' does not exist" + exit _rc + } + local by "by(`by')" + local nextcall "nextcall(`callalg')" + local callalg "metanby" + local sstat "sumstat(`sumstat')" + } + + `callalg' `varlist' `if' `in', `by' label(`code') `keep' `table' `graph' /* + */ method(`method') `randomi' `cont' `stand' `chi2' `cornfield' /* + */ `log' `breslow' `eform' `wgt' `overall' `subgroup' `sgweight' /* + */ `sortby' `saving' `xlabel' `xtick' `force' `wt' `stats' `counts' `box' /* + */ t1(".`t1title'") t2(".`t2title'") b1(".`b1title'") b2(".`b2title'") /* + */ `groupla' `nextcall' `sstat' + + if $S_8<0 { + di in re "Insufficient data to perform this meta-analysis" + } + +/*Saved results: to keep compatible with v5 have retained $S_. macros. +Now assign also to r() macros + +The macro names and descriptions in the prev version are + +Name v7.0 v5.0 +pooled ES r(ES) $S_1* +se(ES) - not if RR or OR r(seES) $S_2 +se(logES) - only if RR/OR, non-logged + r(selogES) $S_2 +lower CI of pooled ES r(ci_low) $S_3 +upper CI of pooled ES r(ci_upp) $S_4 +Z-value for ES r(z) $S_5 +p(Z) r(p_z) $S_6 +chi2 heterogeneity r(het) $S_7 +df (#studies-1) r(df) $S_8 +p(chi2 heterogeneity) r(p_het) $S_9 +Chi2 for ES (OR only) r(chi2) $S_10 +p(chi2) (OR only) r(p_chi2) $S_11 +Estimated tau^2(D&L only) r(tau2) $S_12 +Effect measure (RR,SMD..) r(measure) - + *unless log option used.. +Overall event rate [binary data; group 1) + r(tger) - +Overall event rate [binary data; group 2) + r(cger) - +*/ + + +*return log or eform as appropriate for OR/RR + return scalar ES=$S_1 + if ("`sumstat'"=="OR" | "`sumstat'"=="RR") & ("`log'"=="") { return scalar selogES=$S_2 } + else if ("`sumstat'"=="ES" & "`eform'"!="") { return scalar selogES=$S_2 } + else { return scalar seES=$S_2 } + return scalar ci_low=$S_3 + return scalar ci_upp=$S_4 + return scalar z=$S_5 + return scalar p_z=$S_6 + return scalar het=$S_7 + return scalar df=$S_8 + return scalar p_het=$S_9 + return scalar chi2=$S_10 + return scalar p_chi2=$S_11 + return scalar tau2=$S_12 + return local measure "`log'`sumstat'" + if ("`sumstat'"=="RR" | "`sumstat'"=="OR" | "`sumstat'"=="RD") { + return scalar tger=$S_13 + return scalar cger=$S_14 + } + +end + +program define OR + version 7.0 + #delimit ; + syntax varlist(min=4 max=4 default=none numeric) [if] [in] [, + LABEL(string) SORTBY(passthru) noGRAPH noTABLE CHI2 RANDOMI CC(string) + METHOD(string) XLAbel(passthru) XTICK(passthru) FORCE CORNFIELD noKEEP + SAVING(passthru) noBOX T1(string) T2(string) B1(string) B2(string) noOVERALL + noWT noSTATS LOG BRESLOW COUNTS WGT(varlist numeric max=1) noGROUPLA ] ; + #delimit cr + qui { + tempvar a b c d use zeros r1 r2 c1 c2 t or lnor es v se ill iul ea /* + */ va weight qhet id rawdata cont_a cont_b cont_c cont_d + tempname ernum erden R S PR PS QR QS W OR lnOR selnOR A EA VA + parse "`varlist'", parse(" ") + if "`log'"!="" { local exp } + else { local exp "exp"} + gen double `a' =`1' + gen double `b' =`2' + gen double `c' =`3' + gen double `d' =`4' + gen double `r1'=`a'+`b' + gen double `r2'=`c'+`d' + gen double `c1'=`a'+`c' + gen double `c2'=`b'+`d' + gen byte `use'=1 `if' `in' + replace `use'=9 if `use'==. + replace `use'=9 if (`r1'==.) | (`r2'==.) + replace `use'=2 if (`use'==1) & (`r1'==0 | `r2'==0 ) + replace `use'=2 if (`use'==1) & (`c1'==0 | `c2'==0 ) + count if `use'==1 + global S_8 =r(N)-1 + if $S_8<0 { exit } + if "`counts'"!="" { +*Display raw counts + gen str20 `rawdata'= string(`a') + "/" + string(`r1') +";" + /* +*/ string(`c') + "/"+ string(`r2') if `use'!=9 + replace `rawdata'= trim(`rawdata') + if "`overall'"=="" { + sum `a' if (`use'==1 | `use'==2) + local sum1=r(sum) + sum `r1' if (`use'==1 | `use'==2) + local sum2=r(sum) + sum `c' if (`use'==1 | `use'==2) + local sum3=r(sum) + sum `r2' if (`use'==1 | `use'==2) + local sum4=r(sum) + global MA_ODC = "`sum1'/`sum2';`sum3'/`sum4'" + } + } + else {gen str1 `rawdata'="."} + if "`method'"=="D+L" & ($S_8==0) { local method "M-H"} +*Get average event rate for each group (before any 0.5 adjustments or excluding 0-0 studies) + sum `a' if `use'<3 + scalar `ernum'=r(sum) + sum `r1' if `use'<3 + scalar `erden'=r(sum) + global S_13=`ernum'/`erden' + sum `c' if `use'<3 + scalar `ernum'=r(sum) + sum `r2' if `use'<3 + scalar `erden'=r(sum) + global S_14=`ernum'/`erden' + +*Remove "uninformative" studies + replace `a'=. if `use'!=1 + replace `b'=. if `use'!=1 + replace `c'=. if `use'!=1 + replace `d'=. if `use'!=1 + replace `r1'=. if `use'!=1 + replace `r2'=. if `use'!=1 + gen double `t' =`r1'+`r2' +* Chi-squared test for effect + sum `a',meanonly + scalar `A'=r(sum) + gen double `ea'=(`r1'*`c1')/`t' + gen double `va'=`r1'*`r2'*`c1'*(`b'+`d')/(`t'*`t'*(`t'-1)) + sum `ea',meanonly + scalar `EA'=r(sum) + sum `va',meanonly + scalar `VA'=r(sum) + global S_10=( (`A'-`EA')^2 )/`VA' /* chi2 effect value */ + global S_11=chiprob(1,$S_10) /* p(chi2) */ + + if "`cornfield'"!="" { +*Compute Cornfield CI + gen `ill'=. + gen `iul'=. + local j=1 + tempname i al aj c1j r1j r2j alold + while `j'<=_N { + if `use'[`j']==1 { + scalar `i' = 0 + scalar `al' =`a'[`j'] + scalar `aj' =`a'[`j'] + scalar `c1j'=`c1'[`j'] + scalar `r1j'=`r1'[`j'] + scalar `r2j'=`r2'[`j'] + scalar `alold'= . + while abs(`al'-`alold')>.001 & `al'!=. { + scalar `alold' = `al' + scalar `al'=`aj'-($ZIND)/sqrt( (1/`al') + 1/(`c1j'-`al') + /* + */ 1/(`r1j'-`al') + 1/(`r2j'-`c1j'+`al') ) + if `al'==. { + scalar `i'=`i'+1 + scalar `al'=`aj'-`i' + if (`al'<0 | (`r2j'-`c1j'+`al')<0) {scalar `al'= . } + } + } + if `al'==. { scalar `al'= 0 } + replace `ill'=`log'( `al'*(`r2j'-`c1j'+`al')/((`c1j'-`al')*(`r1j'-`al')) ) in `j' + scalar `al'= `a'[`j'] + scalar `alold'= . + scalar `i'= 0 + while abs(`al'-`alold')>.001 & `al'!=. { + scalar `alold'= `al' + scalar `al'=`aj'+($ZIND)/sqrt( (1/`al')+ 1/(`c1j'-`al') + /* + */ 1/(`r1j'-`al') + 1/(`r2j'-`c1j'+`al') ) + if `al'==. { + scalar `i'=`i'+1 + scalar `al'=`aj'+`i' + if (`al'>`r1j' | `al'>`c1j' ) { scalar `al' = . } + } + } + replace `iul'=`log'( `al'*(`r2j'-`c1j'+`al')/((`c1j'-`al')*(`r1j'-`al')) ) in `j' + } + local j=`j'+1 + } + } +*Adjustment for zero cells in calcn of OR and var(OR) + gen `zeros'=1 if `use'==1 & (`a'==0 | `b'==0 | `c'==0 | `d'==0 ) + gen `cont_a'=`cc' + gen `cont_b'=`cc' + gen `cont_c'=`cc' + gen `cont_d'=`cc' + replace `a'=`a'+`cont_a' if `zeros'==1 + replace `b'=`b'+`cont_b' if `zeros'==1 + replace `c'=`c'+`cont_c' if `zeros'==1 + replace `d'=`d'+`cont_d' if `zeros'==1 + replace `r1'=`r1'+(`cont_a'+`cont_b') if `zeros'==1 + replace `r2'=`r2'+(`cont_c'+`cont_d') if `zeros'==1 + replace `t' =`t' +(`cont_a'+`cont_b')+(`cont_c'+`cont_d') if `zeros'==1 + gen double `or' =(`a'*`d')/(`b'*`c') + gen double `lnor'=log(`or') + gen double `v' =1/`a' +1/`b' +1/`c' + 1/`d' + gen double `es' =`log'(`or') + gen double `se' =sqrt(`v') + if "`cornfield'"=="" { + gen `ill' =`exp'(`lnor'-$ZIND*`se') + gen `iul' =`exp'(`lnor'+$ZIND*`se') + } + if "`method'"=="M-H" | ( "`method'"=="D+L" & "`randomi'"=="" ) { + tempname p q r s pr ps qr qs + gen double `r' =`a'*`d'/`t' + gen double `s' =`b'*`c'/`t' + sum `r', meanonly + scalar `R' =r(sum) + sum `s', meanonly + scalar `S' =r(sum) +*Calculate pooled MH- OR + scalar `OR' =`R'/`S' + scalar `lnOR'=log(`OR') +*Calculate variance/SE of lnOR and weights + gen double `p' =(`a'+`d')/`t' + gen double `q' =(`b'+`c')/`t' + gen double `pr' =`p'*`r' + gen double `ps' =`p'*`s' + gen double `qr' =`q'*`r' + gen double `qs' =`q'*`s' + sum `pr', meanonly + scalar `PR' =r(sum) + sum `ps', meanonly + scalar `PS' =r(sum) + sum `qr', meanonly + scalar `QR' =r(sum) + sum `qs', meanonly + scalar `QS' =r(sum) + scalar `selnOR'= sqrt( (`PR'/(`R'*`R') + (`PS'+`QR')/(`R'*`S') + /* + */ `QS'/(`S'*`S'))/2 ) + gen `weight'=100*`s'/`S' +*Store results in global macros, on log scale if requested + global S_1 =`log'(`OR') + global S_2 =`selnOR' + global S_3 =`exp'(`lnOR' -$ZOVE*`selnOR') + global S_4 =`exp'(`lnOR' +$ZOVE*`selnOR') + global S_5 =abs(`lnOR')/(`selnOR') + global S_6 =normprob(-abs($S_5))*2 + drop `p' `q' `r' `pr' `ps' `qr' `qs' +*Calculate heterogeneity + if "`breslow'"=="" { + gen double `qhet' =( (`lnor'-`lnOR')^2 )/`v' + sum `qhet', meanonly + global S_7 =r(sum) /*Chi-squared */ + global S_9 =chiprob($S_8,$S_7) /*p(chi2 het) */ + } + } + if "`wgt'"!="" { + cap gen `weight'=. + udw `lnor' `v' , wgt(`wgt') `exp' + replace `weight'=`wgt'*100/$MA_W + local udwind "wgt(`wgt')" + } + else if "`method'"!="M-H" { + cap gen `weight'=. + iv `lnor' `v', method(`method') `randomi' `exp' + replace `weight'=100/( (`v'+$S_12)*($MA_W) ) + } + + if "`breslow'"!="" { +*Calculate heterogeneity by Breslow-Day test: need to reset zero cells and margins + + if "`log'"=="" {local bexp } + else {local bexp "exp" } + replace `a'=`a'-`cont_a' if `zeros'==1 + replace `b'=`b'-`cont_b' if `zeros'==1 + replace `c'=`c'-`cont_c' if `zeros'==1 + replace `d'=`d'-`cont_d' if `zeros'==1 + replace `r1'=`r1'-(`cont_a'+`cont_b') if `zeros'==1 + replace `r2'=`r2'-(`cont_c'+`cont_d') if `zeros'==1 + replace `t' =`t' -(`cont_a'+`cont_b')-(`cont_c'+`cont_d') if `zeros'==1 + if abs(`bexp'($S_1) - 1)<0.0001 { + gen afit = `r1'*`c1'/`t' + gen bfit = `r1'*`c2'/`t' + gen cfit = `r2'*`c1'/`t' + gen dfit = `r2'*`c2'/`t' + } + else { + tempvar sterm cterm root1 root2 afit bfit cfit dfit bresd_q + tempname qterm + scalar `qterm' = 1-`bexp'($S_1) + gen `sterm' = `r2' - `c1' + (`bexp'($S_1))*(`r1'+`c1') + gen `cterm' = -(`bexp'($S_1))*`c1'*`r1' + gen `root1' = (-`sterm' + sqrt(`sterm'*`sterm' - 4*`qterm'*`cterm'))/(2*`qterm') + gen `root2' = (-`sterm' - sqrt(`sterm'*`sterm' - 4*`qterm'*`cterm'))/(2*`qterm') + gen `afit' = `root1' if `root2'<0 + replace `afit' = `root2' if `root1'<0 + replace `afit' = `root1' if (`root2'>`c1') | (`root2'>`r1') + replace `afit' = `root2' if (`root1'>`c1') | (`root1'>`r1') + gen `bfit' = `r1' - `afit' + gen `cfit' = `c1' - `afit' + gen `dfit' = `r2' - `cfit' + } + gen `qhet' = ((`a'-`afit')^2)*((1/`afit')+(1/`bfit')+(1/`cfit')+(1/`dfit')) + sum `qhet', meanonly + global S_7 =r(sum) /*Het. Chi-squared */ + global S_9 =chiprob($S_8,$S_7) /*p(chi2 het) */ + } + replace `weight'=0 if `weight'==. + } /* End of "quietly" loop */ + _disptab `es' `se' `ill' `iul' `weight' `use' `label' `rawdata', `keep' `sortby' /* + */ `table' method(`method') sumstat(OR) `chi2' `xlabel' `xtick' `force' `graph' /* + */ `box' `saving' t1("`t1'") t2("`t2'") b1("`b1'") b2("`b2'") `overall' `wt' /* + */ `stats' `counts' `log' `groupla' `udwind' `cornfield' +end + +program define Peto + version 7.0 + #delimit ; + syntax varlist(min=4 max=4 default=none numeric) [if] [in] [, + LABEL(string) ORDER(string) noGRAPH METHOD(string) CHI2 XLAbel(passthru) + XTICK(passthru) FORCE noKEEP SAVING(passthru) noBOX noTABLE SORTBY(passthru) T1(string) + T2(string) B1(string) B2(string) noOVERALL noWT noSTATS LOG COUNTS ] ; + #delimit cr + qui { + tempvar a b c d use r1 r2 t ea olesse v lnor or es se /* + */ ill iul p weight id rawdata + tempname ernum erden OLESSE V SE P lnOR A C R1 R2 + parse "`varlist'", parse(" ") + if "`log'"!="" { local exp } + else { local exp "exp"} + gen double `a' =`1' `if' `in' + gen double `b' =`2' `if' `in' + gen double `c' =`3' `if' `in' + gen double `d' =`4' `if' `in' + gen double `r1' =`a'+`b' + gen double `r2' =`c'+`d' + gen byte `use'=1 `if' `in' + replace `use'=9 if `use'==. + replace `use'=9 if (`r1'==.) | (`r2'==.) + replace `use'=2 if (`use'==1) & (`r1'==0 | `r2'==0 ) + replace `use'=2 if (`use'==1) & ((`a'==0 & `c'==0 ) | (`b'==0 & `d'==0)) + count if `use'==1 + global S_8 =r(N)-1 + if $S_8<0 { exit } + if "`counts'"!="" { +*Display raw counts + gen str20 `rawdata'= string(`a') + "/" + string(`r1') +";" + /* +*/ string(`c') + "/"+ string(`r2') if `use'!=9 + replace `rawdata'= trim(`rawdata') + if "`overall'"=="" { + sum `a' if (`use'==1 | `use'==2) + local sum1=r(sum) + sum `r1' if (`use'==1 | `use'==2) + local sum2=r(sum) + sum `c' if (`use'==1 | `use'==2) + local sum3=r(sum) + sum `r2' if (`use'==1 | `use'==2) + local sum4=r(sum) + global MA_ODC = "`sum1'/`sum2';`sum3'/`sum4'" + } + } + else {gen str1 `rawdata'="."} +*Get average event rate for each group (before any 0.5 adjustments or excluding 0-0 studies) + sum `a' if `use'<3 + scalar `ernum'=r(sum) + sum `r1' if `use'<3 + scalar `erden'=r(sum) + global S_13=`ernum'/`erden' + sum `c' if `use'<3 + scalar `ernum'=r(sum) + sum `r2' if `use'<3 + scalar `erden'=r(sum) + global S_14=`ernum'/`erden' + +*Remove "uninformative" studies + replace `a'=. if `use'!=1 + replace `b'=. if `use'!=1 + replace `c'=. if `use'!=1 + replace `d'=. if `use'!=1 + replace `r1'=. if `use'!=1 + replace `r2'=. if `use'!=1 + gen double `t' =`r1'+`r2' + gen double `ea' =`r1'*(`a'+`c')/`t' + gen double `olesse'=`a'-`ea' + gen double `v' =`r1'*`r2'*(`a'+`c')*(`b'+`d')/( `t'*`t'*(`t'-1) ) + gen double `lnor' =`olesse'/`v' + gen double `es' = `exp'(`lnor') + gen double `se' = 1/(sqrt(`v')) + gen double `ill' = `exp'(`lnor'-$ZIND*`se') + gen double `iul' = `exp'(`lnor'+$ZIND*`se') + gen double `p' =(`olesse')*(`olesse')/`v' + sum `olesse', meanonly + scalar `OLESSE'=r(sum) + sum `v', meanonly + scalar `V' =r(sum) + sum `p', meanonly + scalar `P' =r(sum) + scalar `lnOR' =`OLESSE'/`V' + global S_1 =`exp'(`lnOR') + global S_2 =1/sqrt(`V') + global S_3 =`exp'(`lnOR'-$ZOVE*($S_2)) + global S_4 =`exp'(`lnOR'+$ZOVE*($S_2)) + sum `a', meanonly + scalar `A' =r(sum) + sum `c', meanonly + scalar `C' =r(sum) + sum `r1', meanonly + scalar `R1' =r(sum) + sum `r2', meanonly + scalar `R2' =r(sum) + global S_10 =(`OLESSE'^2)/`V' /*Chi-squared effect*/ + global S_11 =chiprob(1,$S_10) + global S_5 =abs(`lnOR')/($S_2) + global S_6 =normprob(-abs($S_5))*2 +/*Heterogeneity */ + global S_7=`P'-$S_10 + global S_9 =chiprob($S_8,$S_7) + gen `weight' =100*`v'/`V' + replace `weight'=0 if `weight'==. + } /* End of quietly loop */ + + +_disptab `es' `se' `ill' `iul' `weight' `use' `label' `rawdata' , `keep' `sortby' /* + */ `table' method(`method') sumstat(OR) `chi2' `xlabel' `xtick' `force' `graph' `box' /* + */ `saving' t1("`t1'") t2("`t2'") b1("`b1'") b2("`b2'") `overall' `wt' `stats' `counts' `log' +end + +program define RR + version 7.0 + #delimit ; + syntax varlist(min=4 max=4 default=none numeric) [if] [in] [, + LABEL(string) SORTBY(passthru) noGRAPH noTABLE RANDOMI METHOD(string) CC(string) + XLAbel(passthru) XTICK(passthru) FORCE noKEEP SAVING(passthru) noBOX T1(string) + T2(string) B1(string) B2(string) noOVERALL noWT noSTATS LOG COUNTS + WGT(varlist numeric max=1) ] ; + #delimit cr + qui { + tempvar a b c d use zeros r1 r2 t p r s rr lnrr es v se ill iul q /* + */ weight id rawdata cont_a cont_b cont_c cont_d + tempname ernum erden P R S RR lnRR vlnRR + parse "`varlist'", parse(" ") + if "`log'"!="" { local exp } + else { local exp "exp"} + gen double `a' =`1' + gen double `b' =`2' + gen double `c' =`3' + gen double `d' =`4' + gen double `r1' =`a'+`b' + gen double `r2' =`c'+`d' + gen byte `use'=1 `if' `in' + replace `use'=9 if `use'==. + replace `use'=9 if (`r1'==.) | (`r2'==.) + replace `use'=2 if (`use'==1) & (`r1'==0 | `r2'==0 ) + replace `use'=2 if (`use'==1) & ((`a'==0 & `c'==0 ) | (`b'==0 & `d'==0)) + count if `use'==1 + global S_8 =r(N)-1 + if $S_8<0 { exit } + if "`counts'"!="" { +*Display raw counts + gen str20 `rawdata'= string(`a') + "/" + string(`r1') +";" + /* +*/ string(`c') + "/"+ string(`r2') if `use'!=9 + replace `rawdata'= trim(`rawdata') + if "`overall'"=="" { + sum `a' if (`use'==1 | `use'==2) + local sum1=r(sum) + sum `r1' if (`use'==1 | `use'==2) + local sum2=r(sum) + sum `c' if (`use'==1 | `use'==2) + local sum3=r(sum) + sum `r2' if (`use'==1 | `use'==2) + local sum4=r(sum) + global MA_ODC = "`sum1'/`sum2';`sum3'/`sum4'" + } + } + else {gen str1 `rawdata'="."} + if "`method'"=="D+L" & ($S_8==0) { local method "M-H"} +*Get average event rate for each group (before any 0.5 adjustments or excluding 0-0 studies) + sum `a' if `use'<3 + scalar `ernum'=r(sum) + sum `r1' if `use'<3 + scalar `erden'=r(sum) + global S_13=`ernum'/`erden' + sum `c' if `use'<3 + scalar `ernum'=r(sum) + sum `r2' if `use'<3 + scalar `erden'=r(sum) + global S_14=`ernum'/`erden' + +*Adjustment for zero cells in calcn of OR and var(OR) + gen `zeros'=1 if `use'==1 & (`a'==0 | `b'==0 | `c'==0 | `d'==0 ) + gen `cont_a'=`cc' + gen `cont_b'=`cc' + gen `cont_c'=`cc' + gen `cont_d'=`cc' + replace `a'=`a'+`cont_a' if `zeros'==1 + replace `b'=`b'+`cont_b' if `zeros'==1 + replace `c'=`c'+`cont_c' if `zeros'==1 + replace `d'=`d'+`cont_d' if `zeros'==1 + replace `r1'=`r1'+(`cont_a'+`cont_b') if `zeros'==1 + replace `r2'=`r2'+(`cont_c'+`cont_d') if `zeros'==1 + +*Remove "uninformative" studies + replace `a'=. if `use'!=1 + replace `b'=. if `use'!=1 + replace `c'=. if `use'!=1 + replace `d'=. if `use'!=1 + replace `r1'=. if `use'!=1 + replace `r2'=. if `use'!=1 + + gen double `t' =`r1'+`r2' + gen double `r' =`a'*`r2'/`t' + gen double `s' =`c'*`r1'/`t' + gen double `rr' =`r'/`s' + gen double `lnrr'=log(`rr') + gen double `es' =`log'(`rr') + gen double `v' =1/`a' +1/`c' - 1/`r1' - 1/`r2' + gen double `se' =sqrt(`v') + gen double `ill' =`exp'(`lnrr'-$ZIND*`se') + gen double `iul' =`exp'(`lnrr'+$ZIND*`se') + if "`method'"=="M-H" | "`method'"=="D+L" & "`randomi'"=="" { +*MH method for pooling/calculating heterogeneity in DL method + gen double `p' =`r1'*`r2'*(`a'+`c')/(`t'*`t') - `a'*`c'/`t' + sum `p', meanonly + scalar `P' =r(sum) + sum `r', meanonly + scalar `R' =r(sum) + sum `s', meanonly + scalar `S' =r(sum) + scalar `RR'=`R'/`S' + scalar `lnRR'=log(`RR') +* Heterogeneity + gen double `q' =( (`lnrr'-`lnRR')^2 )/`v' + sum `q', meanonly + global S_7 =r(sum) + global S_9 =chiprob($S_8,$S_7) + gen `weight'=100*`s'/`S' + global S_1 =`log'(`RR') + global S_2 =sqrt( `P'/(`R'*`S') ) + global S_3 =`exp'(`lnRR' -$ZOVE*($S_2)) + global S_4 =`exp'(`lnRR' +$ZOVE*($S_2)) + global S_5 =abs(`lnRR')/($S_2) + global S_6 =normprob(-abs($S_5))*2 + } + if "`wgt'"!="" { + cap gen `weight'=. + udw `lnrr' `v' , wgt(`wgt') `exp' + replace `weight'=`wgt'*100/$MA_W + local udwind "wgt(`wgt')" + } + else if "`method'"!="M-H" { + cap gen `weight'=. + iv `lnrr' `v', method(`method') `randomi' `exp' + replace `weight'=100/( (`v'+$S_12)*($MA_W) ) + } + replace `weight'=0 if `weight'==. + } /* End of "quietly" loop */ + _disptab `es' `se' `ill' `iul' `weight' `use' `label' `rawdata' , `keep' `sortby' /* + */ `table' method(`method') sumstat(RR) `xlabel' `xtick' `force' `graph' `box' /* + */ `saving' t1("`t1'") t2("`t2'") b1("`b1'") b2("`b2'") `overall' `wt' /* + */ `stats' `counts' `log' `udwind' + +end + +program define RD + version 7.0 + #delimit ; + syntax varlist(min=4 max=4 default=none numeric) [if] [in] [, + LABEL(string) SORTBY(passthru) noGRAPH noTABLE RANDOMI METHOD(string) CC(string) noKEEP + SAVING(passthru) XLAbel(passthru) XTICK(passthru) noBOX FORCE T1(string) T2(string) + B1(string) B2(string) noOVERALL noWT noSTATS COUNTS WGT(varlist numeric max=1) ] ; + #delimit cr + qui { + tempvar a b c d use zeros r1 r2 t rd weight rdnum v se ill iul vnum q /* + */ id w rawdata cont_a cont_b cont_c cont_d + tempname ernum erden RDNUM VNUM W + parse "`varlist'", parse(" ") + gen double `a' =`1' + gen double `b' =`2' + gen double `c' =`3' + gen double `d' =`4' + gen double `r1' =`a'+`b' + gen double `r2' =`c'+`d' + gen byte `use'=1 `if' `in' + replace `use'=9 if `use'==. + replace `use'=9 if (`r1'==.) | (`r2'==.) + replace `use'=2 if ( `use'==1) & (`r1'==0 | `r2'==0 ) + count if `use'==1 + global S_8 =r(N)-1 + if $S_8<0 { exit } + if "`counts'"!="" { +*Display raw counts + gen str20 `rawdata'= string(`a') + "/" + string(`r1') +";" + /* +*/ string(`c') + "/"+ string(`r2') if `use'!=9 + replace `rawdata'= trim(`rawdata') + if "`overall'"=="" { + sum `a' if (`use'==1 | `use'==2) + local sum1=r(sum) + sum `r1' if (`use'==1 | `use'==2) + local sum2=r(sum) + sum `c' if (`use'==1 | `use'==2) + local sum3=r(sum) + sum `r2' if (`use'==1 | `use'==2) + local sum4=r(sum) + global MA_ODC = "`sum1'/`sum2';`sum3'/`sum4'" + } + } + else {gen str1 `rawdata'="."} + if "`method'"=="D+L" & ($S_8==0) { local method "M-H"} +*Get average event rate for each group (before any cont adjustments or excluding 0-0 studies) + sum `a' if `use'<3 + scalar `ernum'=r(sum) + sum `r1' if `use'<3 + scalar `erden'=r(sum) + global S_13=`ernum'/`erden' + sum `c' if `use'<3 + scalar `ernum'=r(sum) + sum `r2' if `use'<3 + scalar `erden'=r(sum) + global S_14=`ernum'/`erden' + +*Remove "uninformative" studies + replace `a'=. if `use'!=1 + replace `b'=. if `use'!=1 + replace `c'=. if `use'!=1 + replace `d'=. if `use'!=1 + replace `r1'=. if `use'!=1 + replace `r2'=. if `use'!=1 + gen double `t' =`r1'+`r2' + gen double `rd' =`a'/`r1' - `c'/`r2' + gen `weight'=`r1'*`r2'/`t' + sum `weight',meanonly + scalar `W' =r(sum) + gen double `rdnum'=( (`a'*`r2')-(`c'*`r1') )/`t' +* Zero cell adjustments, placed here to ensure 0/n1 v 0/n2 really IS RD=0 +*Adjustment for zero cells in calcn of OR and var(OR) + gen `zeros'=1 if `use'==1 & (`a'==0 | `b'==0 | `c'==0 | `d'==0 ) + gen `cont_a'=`cc' + gen `cont_b'=`cc' + gen `cont_c'=`cc' + gen `cont_d'=`cc' + replace `a'=`a'+`cont_a' if `zeros'==1 + replace `b'=`b'+`cont_b' if `zeros'==1 + replace `c'=`c'+`cont_c' if `zeros'==1 + replace `d'=`d'+`cont_d' if `zeros'==1 + replace `r1'=`r1'+(`cont_a'+`cont_b') if `zeros'==1 + replace `r2'=`r2'+(`cont_c'+`cont_d') if `zeros'==1 + replace `t' =`t' +(`cont_a'+`cont_b')+(`cont_c'+`cont_d') if `zeros'==1 + + gen double `v' =`a'*`b'/(`r1'^3)+`c'*`d'/(`r2'^3) + gen double `se' =sqrt(`v') + gen double `ill' = `rd'-$ZIND*`se' + gen double `iul' = `rd'+$ZIND*`se' + + if "`method'"=="M-H" | ("`method'"=="D+L" & "`randomi'"=="" ) { + sum `rdnum',meanonly + scalar `RDNUM'=r(sum) + global S_1 =`RDNUM'/`W' + gen double `q' =( (`rd'-$S_1)^2 )/`v' + sum `q', meanonly + global S_7 =r(sum) + global S_9 =chiprob($S_8,$S_7) + gen double `vnum'=( (`a'*`b'*(`r2'^3) )+(`c'*`d'*(`r1'^3))) /* + */ /(`r1'*`r2'*`t'*`t') + sum `vnum',meanonly + scalar `VNUM'=r(sum) + global S_2 =sqrt( `VNUM'/(`W'*`W') ) + replace `weight'=`weight'*100/`W' + global S_3 =$S_1 -$ZOVE*($S_2) + global S_4 =$S_1 +$ZOVE*($S_2) + global S_5 =abs($S_1)/($S_2) + global S_6 =normprob(-abs($S_5))*2 + } + if "`wgt'"!="" { + udw `rd' `v' ,wgt(`wgt') + replace `weight'=`wgt'*100/$MA_W + local udwind "wgt(`wgt')" + } + else if "`method'"!="M-H" { + iv `rd' `v', method(`method') `randomi' + replace `weight'=100/( (`v'+$S_12)*($MA_W) ) + } + replace `weight'=0 if `weight'==. + } /* End of "quietly" loop */ + _disptab `rd' `se' `ill' `iul' `weight' `use' `label' `rawdata', `keep' `sortby' /* + */ `table' method(`method') sumstat(RD) `xlabel' `xtick'`force' `graph' `box' /* + */ `saving' t1("`t1'") t2("`t2'") b1("`b1'") b2("`b2'") `overall' `wt' `stats' `counts' `udwind' + +end + +program define MD + version 7.0 + #delimit ; + syntax varlist(min=6 max=6 default=none numeric) [if] [in] [, + LABEL(string) SORTBY(passthru) noGRAPH METHOD(string) noKEEP SAVING(passthru) noBOX + noTABLE STANDARD(string) XLAbel(passthru) XTICK(passthru) FORCE T1(string) T2(string) + B1(string) B2(string) noOVERALL noWT noSTATS COUNTS WGT(string) ] ; + #delimit cr + qui { + tempvar n1 x1 sd1 n2 x2 sd2 use n s md v se ill iul weight id qhet rawdata + parse "`varlist'", parse(" ") + gen double `n1' =`1' + gen double `x1' =`2' + gen double `sd1'=`3' + gen double `n2' =`4' + gen double `x2' =`5' + gen double `sd2'=`6' + + gen `use'=1 `if' `in' + replace `use'=9 if `use'==. + replace `use'=9 if (`n1'==.) | (`n2'==.) | (`x1'==.) | (`x2'==.) | /* + */ (`sd1'==.) | (`sd2'==.) + replace `use'=2 if ( `use'==1) & (`n1' <2 | `n2' <2 ) + replace `use'=2 if ( `use'==1) & (`sd1'<=0 | `sd2'<=0 ) + count if `use'==1 + global S_8 =r(N)-1 + if $S_8<0 { exit } + if "`counts'"!="" { +*Display raw counts instead of default + gen str40 `rawdata'= string(`n1') + " " + string(`x1') +" (" + string(`sd1') + /* + */ ") ; " + string(`n2') + " " + string(`x2') +" (" + string(`sd2') +") " + replace `rawdata'= trim(`rawdata') + } + else {gen str1 `rawdata'="."} + if "`method'"=="D+L" & ($S_8==0) { local method "I-V"} + replace `n1' =. if `use'!=1 + replace `x1' =. if `use'!=1 + replace `sd1'=. if `use'!=1 + replace `n2' =. if `use'!=1 + replace `x2' =. if `use'!=1 + replace `sd2'=. if `use'!=1 + gen double `n' =`n1'+`n2' + if "`standard'"=="none" { + gen double `md' =`x1'-`x2' + gen double `v'=(`sd1'^2)/`n1' + (`sd2'^2)/`n2' + local prefix "W" + } + else { + gen double `s'=sqrt( ((`n1'-1)*(`sd1'^2)+(`n2'-1)*(`sd2'^2) )/(`n'-2) ) + if "`standard'"=="cohen" { + gen double `md' = (`x1'-`x2')/`s' + gen double `v'= ( `n'/(`n1'*`n2') )+( (`md'^2)/(2*(`n'-2)) ) + } + else if "`standard'"=="hedges" { + gen double `md' =( (`x1'-`x2')/`s' )*( 1- 3/(4*`n'-9) ) + gen double `v'=( `n'/(`n1'*`n2') ) + ( (`md'^2)/(2*(`n'-3.94)) ) + } + else if "`standard'"=="glass" { + gen double `md' = (`x1'-`x2')/`sd2' + gen double `v'= (`n'/(`n1'*`n2')) + ( (`md'^2)/(2*(`n2'-1)) ) + } + local prefix "S" + } + gen double `se' =sqrt(`v') + gen double `ill' =`md'-$ZIND*`se' + gen double `iul' =`md'+$ZIND*`se' + if "`wgt'"!="" { + udw `md' `v' , wgt(`wgt') + gen `weight'=`wgt'*100/$MA_W + local udwind "wgt(`wgt')" + } + else { + iv `md' `v', method(`method') randomi + gen `weight'=100/( (`v'+$S_12)*($MA_W) ) + } + replace `weight'=0 if `weight'==. + } /* End of quietly loop */ + _disptab `md' `se' `ill' `iul' `weight' `use' `label' `rawdata', `keep' `sortby' /* + */ `table' method(`method') sumstat(`prefix'MD) `xlabel' `xtick' `force' `graph' /* + */ `box' `saving' t1("`t1'") t2("`t2'") b1("`b1'") b2("`b2'") `overall' `wt' `stats' `udwind' +end + +program define iv_init + version 7.0 + #delimit ; + syntax varlist(min=2 max=3 default=none numeric) [if] [in] [, + LABEL(string) SORTBY(passthru) noGRAPH METHOD(string) noKEEP SAVING(passthru) noBOX + noTABLE XLAbel(passthru) XTICK(passthru) FORCE T1(string) T2(string) B1(string) + B2(string) noOVERALL noWT noSTATS EFORM WGT(string) ] ; + #delimit cr + qui { + tempvar es se use v ill iul weight id rawdata + parse "`varlist'", parse(" ") + gen `es'=`1' + if "`eform'"!="" { local exp "exp" } + if "`3'"=="" { + gen double `se'=`2' + gen double `ill' =`exp'(`es'-$ZIND*`se' ) + gen double `iul' =`exp'(`es'+$ZIND*`se' ) + } + if "`3'"!="" { + gen double `se'=(`3'-`2')/($ZIND*2) + gen double `ill' =`exp'(`2') + gen double `iul' =`exp'(`3') + local var3 "var3" + } + gen double `use'=1 `if' `in' + replace `use'=9 if `use'==. + replace `use'=9 if (`es'==. | `se'==.) + replace `use'=2 if (`use'==1 & `se'<=0 ) + count if `use'==1 + global S_8 =r(N)-1 + if $S_8<0 { exit } + + if "`method'"=="D+L" & ($S_8==0) { local method "I-V"} + replace `es' =. if `use'!=1 + replace `se' =. if `use'!=1 + gen double `v'=(`se')^2 + gen str1 `rawdata'="." + if "`wgt'"!="" { + gen `weight' = `wgt' if `use'==1 + udw `es' `v', wgt(`weight') `exp' + replace `weight'=100*`wgt'/($MA_W) + local udwind "wgt(`wgt')" + } + else { + iv `es' `v', method(`method') `exp' randomi +*NB randomi necc to calculate heterogeneity + gen `weight'=100/( (`v'+$S_12)*($MA_W) ) + } + replace `weight'=0 if `weight'==. + replace `es'=`exp'(`es') + + } /* End of quietly loop */ + _disptab `es' `se' `ill' `iul' `weight' `use' `label' `rawdata', `keep' `sortby' /* + */`table' method(`method') sumstat(ES) `xlabel' `xtick' `force' `graph' `box' /* + */ `saving' t1("`t1'") t2("`t2'") b1("`b1'") b2("`b2'") `overall' `wt' `stats' `eform' /* + */ `var3' `udwind' + +end + + +program define iv + version 7.0 + #delimit ; + syntax varlist(min=2 max=2 default=none numeric) [if] [in] [, + METHOD(string) RANDOMI EXP ] ; + #delimit cr + tempvar stat v w qhet w2 wnew e_w e_wnew + tempname W W2 C T2 E_W E_WNEW OV vOV QHET + parse "`varlist'", parse(" ") + gen `stat'=`1' + gen `v' =`2' + gen `w' =1/`v' + sum `w',meanonly + scalar `W'=r(sum) + global S_12=0 + global MA_W =`W' + if ("`randomi'"=="" & "`method'"=="D+L") { scalar `QHET'=$S_7 } + else { + gen `e_w' =`stat'*`w' + sum `e_w',meanonly + scalar `E_W'=r(sum) + scalar `OV' =`E_W'/`W' +* Heterogeneity + gen `qhet' =( (`stat'-`OV')^2 )/`v' + sum `qhet', meanonly + scalar `QHET'=r(sum) + global S_7=`QHET' + } + if "`method'"=="D+L" { + gen `w2' =`w'*`w' + sum `w2',meanonly + scalar `W2' =r(sum) + scalar `C' =`W' - `W2'/`W' + global S_12 =max(0, ((`QHET'-$S_8)/`C') ) + gen `wnew' =1/(`v'+$S_12) + gen `e_wnew'=`stat'*`wnew' + sum `wnew',meanonly + global MA_W =r(sum) + sum `e_wnew',meanonly + scalar `E_WNEW'=r(sum) + scalar `OV' =`E_WNEW'/$MA_W + } + global S_1 =`exp'(`OV') + global S_2 =sqrt( 1/$MA_W ) + global S_3 =`exp'(`OV' -$ZOVE*($S_2)) + global S_4 =`exp'(`OV' +$ZOVE*($S_2)) + global S_5 =abs(`OV')/($S_2) + global S_6 =normprob(-abs($S_5))*2 + global S_9 =chiprob($S_8,$S_7) +end + + +program define udw +* user defined weights to combine trials + version 7.0 + #delimit ; + syntax varlist(min=2 max=2 default=none numeric) [if] [in] [, + METHOD(string) EXP WGT(varlist numeric max=1) ] ; + #delimit cr + tempvar stat v w e_w varcomp qhet + + tempname W E_W OV W2 Vnum V QHET + parse "`varlist'", parse(" ") + gen `stat'=`1' + gen `v' =`2' + gen `w' =`wgt' if `stat'!=. + sum `w',meanonly + scalar `W'=r(sum) + if `W'==0 { + di in re "Usable weights sum to zero: the table below will probably be nonsense" + } + global MA_W =`W' +*eff size = SIGMA(wi * thetai)/SIGMA(wi) + gen `e_w' =`stat'*`w' + sum `e_w',meanonly + scalar `E_W'=r(sum) + scalar `OV' =`E_W'/`W' +*VAR = SIGMA{wi^2 * var(thetai) }/[SIGMA(wi)]^2 + sum `w',meanonly + scalar `W2'=(r(sum))^2 + gen `varcomp' = `w'*`w'*`v' + sum `varcomp' ,meanonly + scalar `Vnum'=r(sum) + scalar `V' =`Vnum'/`W2' + +*Heterogeneity (need to use variance weights here - BUT use ES=wgt*es/wgt, not necc var wts) + gen `qhet' =( (`stat'-`OV')^2 )/`v' + sum `qhet', meanonly + scalar `QHET'=r(sum) + + global S_1 =`exp'(`OV') + global S_2 =sqrt( `V' ) + global S_3 =`exp'(`OV' -$ZOVE*($S_2)) + global S_4 =`exp'(`OV' +$ZOVE*($S_2)) + global S_5 =abs(`OV')/($S_2) + global S_6 =normprob(-abs($S_5))*2 + global S_7=`QHET' + global S_9 =chiprob($S_8,$S_7) +end + + +program define _disptab + version 7.0 + #delimit ; + syntax varlist(min=7 max=8 default=none) [if] [in] [, + XLAbel(passthru) XTICK(passthru) FORCE noKEEP SAVING(passthru) noBOX noTABLE + noGRAPH METHOD(string) SUMSTAT(string) CHI2 T1(string) T2(string) B1(string) + B2(string) noOVERALL noWT noSTATS COUNTS LOG EFORM noGROUPLA SORTBY(string) + WGT(string) VAR3 CORNFIELD ] ; + #delimit cr + tempvar effect se lci uci weight use label tlabel rawdata id + parse "`varlist'", parse(" ") + qui { + gen `effect'=`1' + gen `se' =`2' + gen `lci' =`3' + gen `uci' =`4' + gen `weight'=`5' + gen byte `use'=`6' + format `weight' %5.1f + gen str10 `label'="" + replace `label'=`7' + global IND: displ %2.0f $IND + gen str40 `rawdata' = `8' + if "`keep'"=="" { + if ("`sumstat'"=="OR" | "`sumstat'"=="RR") & ("`log'"=="") { local ln "log"} + else { local ln } + cap drop _ES + cap drop _seES + cap drop _selogES + if "`sumstat'"!="ES" { + #delimit ; + replace _SS =. if `use'!=1; label var _SS "Sample size"; + gen _ES =`effect';label var _ES "`log'`sumstat'"; + gen _se`ln'ES=`se';label var _se`ln'ES "se(`ln'`log'`sumstat')"; + #delimit cr + } + #delimit ; + cap drop _LCI ; cap drop _UCI; cap drop _WT; + gen _LCI =`lci'; label var _LCI "Lower CI (`log'`sumstat')"; + gen _UCI =`uci'; label var _UCI "Upper CI (`log'`sumstat')"; + gen _WT=`weight';label var _WT "`method' weight"; + #delimit cr + } + + preserve + if "`overall'"=="" { +**If overall figure requested, add an extra line to contain overall stats + qui { + local nobs1=_N+1 + set obs `nobs1' + replace `effect'= ($S_1) in `nobs1' + replace `lci'=($S_3) in `nobs1' + replace `uci'=($S_4) in `nobs1' + replace `weight'=100 in `nobs1' + replace `use'=5 in `nobs1' + replace `label' = "Overall" in `nobs1' + if "`counts'"!="" { replace `rawdata'="$MA_ODC" in `nobs1' } + replace `label' = "Overall" in `nobs1' + } + } + local usetot=$S_8+1 + count if `use'==2 + local alltot=r(N)+`usetot' + gen `id'=_n + sort `use' `sortby' `id' + + + } /* End of quietly loop */ + if "`table'"=="" { + qui gen str20 `tlabel'=`7' /*needs to be own label so as not to overrun!*/ + if "`overall'`wt'"=="" { + local ww "% Weight" + } + + if $IND!=$OVE { + global OVE: displ %2.0f $OVE + local insert "[$OVE% Conf. Interval]" + } + else { local insert "--------------------" } + + di _n in gr _col(12) "Study" _col(22) "|" _col(24) "`log'" _col(28) "`sumstat'" /* + */ _col(34) "[$IND% Conf. Interval]" _col(59) "`ww'" _n _dup(21) "-" "+" _dup(51) "-" + local i=1 + while `i'<=_N { + if "`overall'`wt'"=="" { local ww=`weight'[`i'] } + else { local ww } + + if (`use'[`i'])==2 { +*excluded trial + di in gr `tlabel'[`i'] _col(22) "| (Excluded)" + } + if ( (`use'[`i']==1) | (`use'[`i']==5) ) { + if (`use'[`i'])==1 { +*trial results + di in gr `tlabel'[`i'] _cont + } + else { +*overall + di in gr _dup(21) "-" "+" _dup(11) "-" "`insert'" _dup(20) "-" _n /* +*/ "`method' pooled `log'`sumstat'" _cont + } + di in gr _col(22) "|" in ye %7.3f `effect'[`i'] /* + */ _col(35) %7.3f `lci'[`i'] " " %7.3f `uci'[`i'] _col(60) %6.2f `ww' + } + local i=`i'+1 + } + di in gr _dup(21) "-" "+" _dup(51) "-" + if "`overall'"=="" { + if ("`method'"=="*" | "`var3'"!="") { + if "`method'"=="*" { + di in gr "* note: trials pooled by user defined weight `wgt'" + } + di in gr " Heterogeneity calculated by formula" _n /* + */ " Q = SIGMA_i{ (1/variance_i)*(effect_i - effect_pooled)^2 } " + if "`var3'"!="" { + di in gr "where variance_i = ((upper limit - lower limit)/(2*z))^2 " + } + } +*Heterogeneity etc + if ( ("`sumstat'"=="OR" | "`sumstat'"=="RR") & "`log'"=="") {local h0=1} + else if ("`sumstat'"=="ES" & "`eform'"!="") {local h0=1} + else {local h0=0} + di _n in gr " Heterogeneity chi-squared = " in ye %6.2f $S_7 in gr /* + */ " (d.f. = " in ye $S_8 in gr ") p = " in ye %4.3f $S_9 + local i2=max(0, (100*($S_7-$S_8)/($S_7)) ) + if $S_8<1 { local i2=. } + di in gr " I-squared (variation in `sumstat' attributable to " /* + */ "heterogeneity) =" in ye %6.1f `i2' "%" + if "`method'"=="D+L" { di in gr " Estimate of between-study variance " /* + */ "Tau-squared = " in ye %7.4f $S_12 } + + if "`chi2'"!="" { di _n in gr " Test of OR=1: chi-squared = " in ye %4.2f /* + */ $S_10 in gr " (d.f. = 1) p = " in ye %4.3f $S_11 } + else { di _n in gr " Test of `log'`sumstat'=`h0' : z= " in ye %6.2f $S_5 /* + */ in gr " p = " in ye %4.3f $S_6 } + } + } + +*capture only 1 trial scenario + qui { + count + if r(N)==1 { + set obs 2 + replace `use'=99 in 2 + replace `weight'=0 if `use'==99 + } + } /*end of qui. */ + if "`graph'"=="" & `usetot'>0 { + _dispgby `effect' `lci' `uci' `weight' `use' `label' `rawdata', `log' /* + */ `xlabel' `xtick' `force' sumstat(`sumstat') `saving' `box' t1("`t1'") /* + */ t2("`t2'") b1("`b1'") b2("`b2'") `overall' `wt' `stats' `counts' `eform' /* + */ `groupla' `cornfield' + } + restore +end + + +program define metanby + version 7.0 + #delimit ; + syntax varlist(min=2 max=6 default=none numeric) [if] [in] [, BY(string) + LABEL(string) SORTBY(string) noGRAPH noTABLE noKEEP NEXTCALL(string) + METHOD(string) SUMSTAT(string) RANDOMI WGT(passthru) noSUBGROUP SGWEIGHT + CORNFIELD CHI2 CC(passthru) STANDARD(passthru) noOVERALL LOG EFORM BRESLOW + XLAbel(passthru) XTICK(passthru) FORCE SAVING(passthru) T1(string) T2(string) + B1(string) B2(string) noWT noSTATS COUNTS noBOX noGROUPLA ] ; + #delimit cr + if ("`subgroup'"!="" & "`overall'`sgweight'"!="") { local wt "nowt" } + tempvar use by2 newby r1 r2 rawdata effect se lci uci weight wtdisp /* + */ hetc hetdf hetp i2 tau2 tsig psig expand tlabel id + + qui { + gen `use'=1 `if' `in' + replace `use'=9 if `use'==. + gen str1 `rawdata'="." + + tokenize `varlist' + if ("`nextcall'"=="RR" | "`nextcall'"=="OR" | "`nextcall'"=="RD" |"`nextcall'"=="Peto" ) { +*Sort out r1 & r2 for 2x2 table: might be needed in counts and mh/use + gen `r1' = `1'+`2' + gen `r2' = `3'+`4' + replace `use'=2 if ((`use'==1) & (`r1'==0 | `r2'==0 )) + replace `use'=2 if ((`use'==1) & ((`1'+`3'==0) | (`2'+`4'==0) ) & "`nextcall'"!="RD") + replace `use'=9 if (`r1'==.) | (`r2'==.) + if "`counts'"!="" { +*create new variable with count data (if requested) + replace `rawdata'= trim( string(`1') + "/" + string(`r1') +";" + /* +*/ string(`3') + "/"+ string(`r2') ) if `use'!=9 + } + } + if "`nextcall'"=="MD" { +*Sort out n1 & n2 + replace `use'=9 if (`1'==.) | (`2'==.) | (`3'==.) | (`4'==.) | (`5'==.) | (`6'==.) + replace `use'=2 if ( `use'==1) & (`1' <2 | `4' <2 ) + replace `use'=2 if ( `use'==1) & (`3'<=0 | `6'<=0 ) + } + if "`nextcall'"=="iv_init" { + replace `use'=9 if (`1'==. | `2'==.) + if "`3'"=="" { + replace `use'=2 if (`use'==1 & `2'<=0 ) + } + else { + replace `use'=9 if (`3'==.) + replace `use'=2 if ( `2'>`1' | `3'<`1' | `3'<`2') + } + } + + if (("`sumstat'"=="OR" | "`sumstat'"=="RR") & "`log'"=="" ) {local h0=1} + else if ("`sumstat'"=="ES" & "`eform'"!="") {local h0=1} + else {local h0=0} + if "`eform'"!="" { local exp "exp" } + +*Get the individual trial stats + `nextcall' `varlist' if `use'==1, nograph notable method(`method') `randomi' /* + */ label(`label') `wgt' `cornfield' `chi2' `cc' `standard' `log' `eform' `breslow' + if $S_8<0 { +*no trials - bomb out + exit + } + local nostud=$S_8 +*need to calculate from variable itself if only 2 variables (ES, SE(ES) syntax used) + if "`sumstat'"=="ES" { + gen `effect'=`exp'(`1') + if "`3'"=="" { + gen `se'=`2' + } + else { + gen `se'=. + local var3 "var3" + } + } + else { + gen `effect'=_ES + if `h0'<0.01 { gen `se'=_seES } + else { gen `se'=_selogES } + } + gen `lci'=_LCI + gen `uci'=_UCI + gen `weight'=_WT +*put overall weight into var if requested + if ("`sgweight'"=="" & "`overall'"=="" ) { + gen `wtdisp'=_WT + } + else { + gen `wtdisp'=. + } + gen `id'=_n + sort `by' `sortby' `id' +*Keep only neccesary data (have to put preserve here in order to keep _ES etc) + preserve + drop if `use'==9 +*Can now forget about the if/in conditions specified: unnecc rows have been removed + +*Keep tger and cger here (otherwise it ends up in last subgroup only) + if ("`sumstat'"=="OR" | "`sumstat'"=="RR" | "`sumstat'"=="RD" ) { + local tger=$S_13 + local cger=$S_14 + } + +*subgroup component of heterogeneity + gen `hetc'=. + gen `hetdf'=. + gen `hetp'=. + gen `i2'=. + gen `tau2'=. + gen `tsig'=. + gen `psig'=. +*Convert "by" variable to numeric if its a string variable + cap confirm numeric var `by' + if _rc>0 { + encode `by', gen(`by2') + drop `by' + rename `by2' `by' + } +*Create new "by" variable to take on codes 1,2,3.. + gen `newby'=(`by'>`by'[_n-1]) + replace `newby'=1+sum(`newby') + local ngroups=`newby'[_N] + + if "`overall'"=="" { +*If requested, add an extra line to contain overall stats + local nobs1=_N+1 + set obs `nobs1' + + replace `use'=5 in `nobs1' + replace `newby'=`ngroups'+1 in `nobs1' + replace `effect'= ($S_1) in `nobs1' + replace `lci'=($S_3) in `nobs1' + replace `uci'=($S_4) in `nobs1' +*Put cell counts in subtotal row + if ("`counts'"!="" & "`nextcall'"!="MD") { +*put up overall binary count data + sum `1' if (`use'==1 | `use'==2) + local sum1=r(sum) + sum `r1' if (`use'==1 | `use'==2) + local sum2=r(sum) + sum `3' if (`use'==1 | `use'==2) + local sum3=r(sum) + sum `r2' if (`use'==1 | `use'==2) + local sum4=r(sum) + replace `rawdata'= "`sum1'/`sum2';`sum3'/`sum4'" in `nobs1' + } + replace `hetc' =($S_7) in `nobs1' + replace `hetdf'=($S_8) in `nobs1' + replace `hetp' =($S_9) in `nobs1' + replace `i2'=max(0, ( 100*($S_7-$S_8))/($S_7) ) in `nobs1' + if $S_8<1 { replace `i2'=. in `nobs1' } + replace `tau2' =$S_12 in `nobs1' + replace `se'=$S_2 in `nobs1' + if "`chi2'"!="" { + replace `tsig'=$S_10 in `nobs1' + replace `psig'=$S_11 in `nobs1' + local z=$S_5 + local pz=$S_6 + } + else { + replace `tsig'=$S_5 in `nobs1' + replace `psig'=$S_6 in `nobs1' + local echi2 =$S_10 + local pchi2=$S_11 + } + replace `label' = "Overall" in `nobs1' + if "`sgweight'"=="" { replace `wtdisp'=100 in `nobs1' } + } + +*Create extra 2 or 3 lines per bygroup: one to label, one for gap +*and one for overall effect size (unless no subgroup combining is done) + sort `newby' `use' `sortby' `id' + by `newby': gen `expand'=1 + 2*(_n==1) + (_n==1 & "`subgroup'"=="") + replace `expand'=1 if `use'==5 + expand `expand' + gsort `newby' -`expand' `use' `sortby' `id' + by `newby': replace `use'=0 if `expand'>1 & _n==2 /* row for by label */ + by `newby': replace `use'=4 if `expand'>1 & _n==3 /* row for blank line */ + by `newby': replace `use'=3 if `expand'>1 & _n==4 /* (if specified) row to hold subgp effect sizes */ + +* blank out effect sizes in new rows + replace `effect'=. if `expand'>1 & `use'!=1 + replace `lci'=. if `expand'>1 & `use'!=1 + replace `uci'=. if `expand'>1 & `use'!=1 + replace `weight' =. if `expand'>1 & `use'!=1 + replace `rawdata' ="." if `expand'>1 & `use'!=1 +*Perform subgroup analyses + local j=1 + while `j'<=`ngroups' { + if "`subgroup'"=="" { +*First ensure the by() category has any data + count if (`newby'==`j' & `use'==1) + if r(N)==0 { +*No data in subgroup=> fill variables with missing and move on + replace `effect'=. if (`use'==3 & `newby'==`j') + replace `lci'=. if (`use'==3 & `newby'==`j') + replace `uci'=. if (`use'==3 & `newby'==`j') + replace `wtdisp'=0 if `newby'==`j' + replace `weight'=0 if `newby'==`j' + replace `hetc'=. if `newby'==`j' + replace `hetdf'=. if `newby'==`j' + replace `hetp'=. if `newby'==`j' + replace `i2'=. if `newby'==`j' + replace `tsig'=. if `newby'==`j' + replace `psig'=. if `newby'==`j' + replace `tau2'=. if `newby'==`j' + } + else { + + `nextcall' `varlist' if (`newby'==`j' & `use'==1) , nograph /* + */ notable label(`label') method(`method') `randomi' `wgt' `cornfield' `chi2' /* + */ `cc' `standard' `log' `eform' `breslow' + replace `effect'=($S_1) if `use'==3 & `newby'==`j' + replace `lci'=($S_3) if `use'==3 & `newby'==`j' + replace `uci'=($S_4) if `use'==3 & `newby'==`j' +*Put within-subg weights in if nooverall or sgweight options specified + if ("`overall'`sgweight'"!="" ) { + replace `wtdisp'=_WT if `newby'==`j' + replace `wtdisp'=100 if (`use'==3 & `newby'==`j') + } + else { + qui sum `wtdisp' if (`use'==1 & `newby'==`j') + replace `wtdisp'=r(sum) if (`use'==3 & `newby'==`j') + } + sum `weight' if `newby'==`j' + replace `weight'= r(sum) if `use'==3 & `newby'==`j' + replace `hetc' =($S_7) if `use'==3 & `newby'==`j' + replace `hetdf'=($S_8) if `use'==3 & `newby'==`j' + replace `hetp' =($S_9) if `use'==3 & `newby'==`j' + replace `i2'=max(0, ( 100*($S_7-$S_8))/($S_7) ) if `use'==3 & `newby'==`j' + if $S_8<1 { replace `i2'=. if `use'==3 & `newby'==`j' } + if "`chi2'"!="" { + replace `tsig'=($S_10) if `use'==3 & `newby'==`j' + replace `psig'=($S_11) if `use'==3 & `newby'==`j' + } + else { + replace `tsig'=($S_5) if `use'==3 & `newby'==`j' + replace `psig'=($S_6) if `use'==3 & `newby'==`j' + } + if "`method'"=="D+L" { + replace `tau2' =($S_12) if `use'==3 & `newby'==`j' + } + } + +*Whether data or not - put cell counts in subtotal row if requested (will be 0/n1;0/n2 or blank if all use>1) + if "`counts'"!="" { +*don't put up anything for MDs: +*1 Cochrane just put up N_gi. Not sure whether weighted mean should be in.. +*2 justifying N_gi is tedious! + if "`nextcall'"!="MD" { + sum `1' if (`use'==1 | `use'==2) & (`newby'==`j') + local sum1=r(sum) + sum `r1' if (`use'==1 | `use'==2) & (`newby'==`j') + local sum2=r(sum) + sum `3' if (`use'==1 | `use'==2) & (`newby'==`j') + local sum3=r(sum) + sum `r2' if (`use'==1 | `use'==2) & (`newby'==`j') + local sum4=r(sum) + replace `rawdata'= "`sum1'/`sum2';`sum3'/`sum4'" if (`use'==3 & `newby'==`j') + } + } + } +*Label attatched (if any) to byvar + local lbl: value label `by' + sum `by' if `newby'==`j' + local byvlu=r(mean) + if "`lbl'"=="" { local lab "`by'==`byvlu'" } + else { local lab: label `lbl' `byvlu' } + replace `label' = "`lab'" if ( `use'==0 & `newby'==`j') + replace `label' = "Subtotal" if ( `use'==3 & `newby'==`j') + local j=`j'+1 + } + + } /*End of quietly loop*/ + + +*Put table up (if requested) + sort `newby' `use' `sortby' `id' + + if "`table'"=="" { + qui gen str20 `tlabel'=`label' + if "`overall'`wt'"=="" { + local ww "% Weight" + } + di _n in gr _col(12) "Study" _col(22) "|" _col(24) "`log'" _col(28) "`sumstat'" /* + */ _col(34) "[$IND% Conf. Interval]" _col(59) "`ww'" + di _dup(21) "-" "+" _dup(51) "-" +*legend for pooled confidence intervals + + local i=1 + while `i'<= _N { + if (`use'[`i'])==0 { +*by label + di _col(6) in gr `tlabel'[`i'] + } + if "`overall'`wt'"=="" { local ww=`wtdisp'[`i'] } + else { local ww } + if (`use'[`i'])==1 { +*trial results + di in gr `tlabel'[`i'] _col(22) "| " in ye %7.3f `effect'[`i'] /* + */ _col(35) %7.3f `lci'[`i'] " " %7.3f `uci'[`i'] _col(60) %6.2f `ww' + } + if (`use'[`i'])==2 { +*excluded trial + di in gr `tlabel'[`i'] _col(22) "| (Excluded)" + } + if ((`use'[`i']==3) & "`subgroup'"=="") | (`use'[`i']==5) { +*Subgroup effect size or overall effect size + if (`use'[`i'])==3 { + di in gr " Sub-total" _col(22) "|" + } + if (`use'[`i'])==5 { + if $IND!=$OVE { + local insert "[$OVE% Conf. Interval]" + } + di in gr "Overall" _col(22) "|" _col(34) "`insert'" + } + if "`ww'"=="." { local ww } + di in gr " `method' pooled `log'`sumstat'" _col(22) "| " in ye %7.3f /* + */ `effect'[`i'] _col(35) %7.3f `lci'[`i'] " " %7.3f `uci'[`i'] _col(60) %6.2f `ww' + if (`use'[`i'])==5 { + di in gr _dup(21) "-" "+" _dup(51) "-" + } + } + + if (`use'[`i'])==4 { +*blank line separator (need to put line here in case nosubgroup was selected) + di in gr _dup(21) "-" "+" _dup(51) "-" + } + + local i=`i'+1 + + } +*Skip next bits if nooverall AND nosubgroup + if ("`subgroup'"=="" | "`overall'"=="") { + +*part 2: user defined weight notes and heterogeneity + if ("`method'"=="*" | "`var3'"!="") { + if "`method'"=="*" { + di in gr "* note: trials pooled by user defined weight `wgt'" + } + di in bl " Heterogeneity calculated by formula" _n /* + */ " Q = SIGMA_i{ (1/variance_i)*(effect_i - effect_pooled)^2 } " + if "`var3'"!="" { + di in bl "where variance_i = ((upper limit - lower limit)/(2*z))^2 " + } + } + + di in gr _n "Test(s) of heterogeneity:" _n _col(16) "Heterogeneity degrees of" + di in gr _col(18) "statistic freedom P I-squared**" _cont + if "`method'"=="D+L" { di in gr " Tau-squared" } + di + local i=1 + while `i'<= _N { + if ("`subgroup'"=="" & (`use'[`i'])==0) | ( (`use'[`i'])==5) { + di in gr _n `tlabel'[`i'] _cont + } + if ( ((`use'[`i'])==3) | ((`use'[`i'])==5) ) { + + di in ye _col(20) %6.2f `hetc'[`i'] _col(35) %2.0f `hetdf'[`i'] /* + */ _col(43) %4.3f `hetp'[`i'] _col(51) %6.1f `i2'[`i'] "%" _cont + + if "`method'"=="D+L" { + di in ye " " %7.4f `tau2'[`i'] _cont + } + + if (`use'[`i']==5) & ("`subgroup'"=="") { + qui sum `hetc' if `use'==3 + local btwghet = (`hetc'[`i']) -r(sum) + local df = `ngroups'-1 + di _n in gr "Overall Test for heterogeneity between sub-groups : " _n /* + */ in ye _col(20) %6.2f `btwghet' _col(35) %2.0f `df' _col(43) %4.3f (chiprob(`df',`btwghet')) + } + } + local i=`i'+1 + } + di _n in gr "** I-squared: the variation in `sumstat' attributable to heterogeneity)" _n + +*part 3: test statistics + di _n in gr "Significance test(s) of `log'`sumstat'=`h0'" + local i=1 + while `i'<= _N { + if ("`subgroup'"=="" & (`use'[`i'])==0) | ( (`use'[`i'])==5) { + di _n in gr `tlabel'[`i'] _cont + } + if ( ((`use'[`i'])==3) | ((`use'[`i'])==5) ) { + + if "`chi2'"!="" { + di in gr _col(20) "chi-squared = " in ye %5.2f `tsig'[`i'] /* + */ in gr _col(35) " (d.f. = 1) p = " in ye %4.3f `psig'[`i'] _cont + } + else { + di in gr _col(23) "z= " in ye %5.2f `tsig'[`i'] _col(35) in gr /* + */ " p = " in ye %4.3f `psig'[`i'] _cont + } + } + local i=`i'+1 + } + di _n in gr _dup(73) "-" + } + + } /* end of table display */ + + if "`overall'"=="" { +*need to return overall effect to $S_1 macros and so on... + global S_1=`effect'[_N] + global S_2=`se'[_N] + global S_3=`lci'[_N] + global S_4=`uci'[_N] + global S_7=`hetc'[_N] + global S_8=`hetdf'[_N] + global S_9=`hetp'[_N] + if "`chi2'"!="" { + global S_10=`tsig'[_N] + global S_11=`psig'[_N] + global S_5=`z' + global S_6=`pz' + } + else { + global S_5=`tsig'[_N] + global S_6=`psig'[_N] + global S_10=`echi2' + global S_11=`pchi2' + } + global S_12=`tau2'[_N] + if ("`sumstat'"=="OR" | "`sumstat'"=="RR" | "`sumstat'"=="RD" ) { + global S_13=`tger' + global S_14=`cger' + } + } + else { + #delimit ; + global S_1 "."; global S_2 "."; global S_3 "."; global S_4 "."; + global S_5 "."; global S_6 "."; global S_7 "."; global S_8= `nostud'; + global S_9 "."; global S_10 ".";global S_11 ".";global S_12 "."; + global S_13 ".";global S_14 "."; + #delimit cr + } + + if "`graph'"=="" { + _dispgby `effect' `lci' `uci' `weight' `use' `label' `rawdata' `wtdisp', /* + */ `log' `xlabel' `xtick' `force' sumstat(`sumstat') `saving' `box' t1("`t1'") /* + */ t2("`t2'") b1("`b1'") b2("`b2'") `overall' `wt' `stats' `counts' `eform' /* + */ `groupla' `cornfield' + } + + restore + if "`keep'"=="" { + qui{ + if ("`sumstat'"=="OR" | "`sumstat'"=="RR") & ("`log'"=="") { local ln "log"} + else { local ln } + cap drop _ES + cap drop _seES + cap drop _selogES + if "`sumstat'"!="ES" { + #delimit ; + replace _SS =. if `use'!=1; label var _SS "Sample size"; + gen _ES =`effect';label var _ES "`log'`sumstat'"; + gen _se`ln'ES=`se';label var _se`ln'ES "se(`ln'`log'`sumstat')"; + #delimit cr + } + #delimit ; + cap drop _LCI ; cap drop _UCI; cap drop _WT; + gen _LCI =`lci'; label var _LCI "Lower CI (`log'`sumstat')"; + gen _UCI =`uci'; label var _UCI "Upper CI (`log'`sumstat')"; + #delimit cr + +*correct weight if subgroup weights given + if ("`sgweight'"=="" & "`overall'"=="" ) { gen _WT=`weight' } + else if "`subgroup'"=="" & ("`overall'`sgweight'"!="" ) { + tempvar tempsum + by `by': gen `tempsum'=sum(`weight') + by `by': replace `tempsum'=`tempsum'[_N] + gen _WT=`weight'*100/`tempsum' + local sg "(subgroup) " + } + cap label var _WT "`method' `sg'% weight" + } + } +end + + +program define _dispgby + version 7.0 + #delimit ; + syntax varlist(min=6 max=8 default=none ) [if] [in] [, + LOG XLAbel(string) XTICK(string) FORCE SAVING(string) noBOX SUMSTAT(string) + T1(string) T2(string) B1(string) B2(string) noOVERALL noWT noSTATS COUNTS EFORM + noGROUPLA CORNFIELD ]; + #delimit cr + tempvar effect lci uci weight wtdisp use label tlabel id yrange xrange Ghsqrwt rawdata + parse "`varlist'", parse(" ") + qui { + gen `effect'=`1' + gen `lci' =`2' + gen `uci' =`3' + gen `weight'=`4' + gen byte `use'=`5' +*Use is now coded: +*0: blank line, except for text containing "by" +*1: trial +*2: excluded trial +*3. subgroup effect (in which case `label' or `6' is to contain the name of the subgroup) +*4. blank line +*5. overall effect +*9. missed/not considered +*As before effect sizes are held elsewhere + + gen str10 `label'="" + replace `label'=`6' + count if (`use'==1 | `use'==2) + local ntrials=r(N) + count if (`use'>=0 & `use'<=5) + local ymax=r(N) + gen `id'=`ymax'-_n+1 if `use'<9 + gen str40 `rawdata' = `7' + compress `rawdata' + if "`8'"!="" { + gen `wtdisp'=`8' + } + else { + gen `wtdisp'=`weight' + } + format `wtdisp' %5.1f + sum `lci' + local Gxlo=r(min) /* minimum of CIs*/ + sum `uci' + local Gxhi=r(max) /* maximum of CIs*/ + local h0=0 + if (("`sumstat'"=="OR" | "`sumstat'"=="RR") & ("`log'"=="")) | ("`eform'"!="") { + local h0=1 + local Glog "xlog" + local xlog "log" + local xexp "exp" + replace `lci'=1e-9 if `lci'<1e-8 + replace `lci'=1e9 if `lci'>1e8 & `lci'!=. + replace `uci'=1e-9 if `uci'<1e-8 + replace `uci'=1e9 if `uci'>1e8 & `uci'!=. + if `Gxlo'<1e-8 {local Gxlo=1e-8} + if `Gxhi'>1e8 {local Gxhi=1e8} + } + if "`cornfield'"!="" { + replace `lci'=`log'(1e-9) if ( (`lci'==. | `lci'==0) & (`effect'!=. & `use'==1) ) + replace `uci'=`log'(1e9) if ( (`uci'==.) & (`effect'!=. & `use'==1) ) + } + local flag1=0 + if "`xtick'"!="" { +* capture inappropriate tick + cap assert ("`xlog'"=="" ) | /* + */ ( ( min(`xtick' ,`Gxhi')>1e-8 ) & (max(`xtick' ,`Gxlo')<1e8) ) + if _rc!=0 { + local flag1=10 + local xtick "`h0'" + } + } + else { + local xtick "`h0'" + } + if "`xlabel'"!="" { +* capture inappropriate label + cap { + assert ("`xlog'"=="" ) | /* + */ ( ( min(`xlabel',`Gxhi')>1e-8 ) & (max(`xlabel',`Gxlo')<1e8) ) + } + if _rc!=0 { + local flag1=10 + local xlabel + } + else { + if "`force'"!="" { + parse "`xlabel'", parse(",") + if "`3'"!="" { + local Gxlo=`h0' + local Gxhi=`h0' + } + } + } + } + + if "`xlabel'"=="" | (`flag1'>1) { + local Gmodxhi=max( abs(`xlog'(`Gxlo')),abs(`xlog'(`Gxhi'))) + if `Gmodxhi'==. {local Gmodxhi=2} + local Gxlo=`xexp'(-`Gmodxhi') + local Gxhi=`xexp'( `Gmodxhi') + local xlabel "`Gxlo',`h0',`Gxhi'" + } + local Gxlo=`xlog'(min(`xlabel',`xtick',`Gxlo')) + local Gxhi=`xlog'(max(`xlabel',`xtick',`Gxhi')) + + local Gxlo1=`Gxlo'-0.1*`Gxhi' + local Gxrange=(`Gxhi'-`Gxlo') + local Gyhi=`id'[1] + + local Gxh20=`Gxhi'+`Gxrange'*0.2 + local Gxh40=`Gxhi'+`Gxrange'*0.4 + local Gxh60=`Gxhi'+`Gxrange'*0.6 + local Gxh80=`Gxhi'+`Gxrange'*0.8 + local Gxh100=`Gxhi'+`Gxrange'*1.0 + gen `xrange'=`xexp'(`Gxlo') in 1 + +*If user wants no counts (c), stats (s) or weights (w) , use entire window for trial plots + if ("`stats'"!="" & "`wt'"!="" & "`counts'"=="" ) { + local Txhi=`Gxhi' + } +*If user wants s&w (default) or c&w use Gxh60 (60% of graph range) for figures + if (("`stats'"=="" & "`wt'"=="" & "`counts'"=="" ) | ("`stats'"!="" & "`wt'"=="" & "`counts'"!="" )) { + local Txhi=`Gxh60' + } +*If user wants s or c alone use Gxh40 (40% of range) + if (("`stats'"=="" & "`wt'"!="" & "`counts'"=="" ) | ("`stats'"!="" & "`wt'"!="" & "`counts'"!="" )) { + local Txhi=`Gxh40' + } +*If user wants w alone use Gxh20 + if ("`stats'"!="" & "`wt'"=="" & "`counts'"=="" ) { + local Txhi=`Gxh20' + } +*If user wants s&c use Gxh80 + if ("`stats'"=="" & "`wt'"!="" & "`counts'"!="" ) { + local Txhi=`Gxh80' + } +*If user wants all 3 use Gxh100 + if ("`stats'"=="" & "`wt'"=="" & "`counts'"!="" ) { + local Txhi=`Gxh100' + } + replace `xrange'=`xexp'(`Txhi') in 2 + + gen `yrange'=0 in 1 + replace `yrange'=`Gyhi'+2 in 2 + cap label drop tmpyl + cap label drop tmpxl +* Study legend now removed + label define tmpyl 0 " " + label define tmpxl `h0' " " + + label values `yrange' tmpyl + label values `xrange' tmpxl +*Label x-axis and top right *if stats requested + if "`sumstat'"=="OR" {local sscale "`log' Odds ratio"} + else if "`sumstat'"=="RR" {local sscale "`log' Risk ratio"} + else if "`sumstat'"=="RD" {local sscale "Risk difference"} + else if "`sumstat'"=="WMD" {local sscale "Mean difference"} + else if "`sumstat'"=="SMD" {local sscale "Standardised mean difference"} + else if ("`sumstat'"=="ES" & "$MA_ESLA"!="") { local sscale "$MA_ESLA" } + else if "`sumstat'"=="ES" {local sscale "Effect size"} + + if "`t1'"=="." {local t1 } + else { + local t1=substr("`t1'",2,.) + local t1 "t1(`t1')" + } + if "`t2'"=="." {local t2 } + else { + local t2=substr("`t2'",2,.) + local t2 "t2(`t2')" + } + if "`b2'"=="." { local b2 "`sscale'"} + else { +*Revise position of b2 title: graph command doesn't put it in the right place + local b2=substr("`b2'",2,.) + } + if "`saving'"!="" {local saving "saving(`saving')" } + else { local saving } + gph open, `saving' + + if "`b1'"=="." { + graph `yrange' `xrange', s(i) xli(`h0') `Glog' xlabel(`h0') /* + */ noaxis yla(0) gap(10) `t1' `t2' b2(" ") + } + else { + graph `yrange' `xrange', s(i) xli(`h0') `Glog' xlabel(`h0') /* + */ noaxis yla(0) gap(10) `t1' `t2' b1(" ") b2(" ") + } + + + local r5=r(ay) + local r6=r(by) + local r7=r(ax) + local r8=r(bx) + local Aytexs=($MA_FTSI)*max(200, min(700, (600-20*(`ymax'-15)) ) ) + local Axtexs=($MA_FTSI)*max(130, min(360,(0.6*`Aytexs')) ) + + gph font `Aytexs' `Axtexs' + gph pen 1 + local Axh0 =`r7'*(`xlog'(`h0'))+`r8' + local Axlo =`r7'*(`Gxlo') +`r8' + local Axloe =`r7'*(`Gxlo') +`r8' -1500 + local Axhi =`r7'*(`Gxhi') +`r8' + local Axhie =`r7'*(`Gxhi') +`r8' + 1500*( ("`wt'"=="") | ("`stats'"=="") | ("`counts'"!="") ) + local Axh20 =`r7'*(`Gxh20') +`r8' + local Axh40 =`r7'*(`Gxh40') +`r8' + local Axh60 =`r7'*(`Gxh60') +`r8' + local Axh80 =`r7'*(`Gxh80') +`r8' + local Axh100=`r7'*(`Gxh100')+`r8' +*add x-axis line and label manually + + gph line `r6' `Axloe' `r6' `Axhie' + local yb=`r6'+1000 + gph line `r6' `Axh0' `yb' `Axh0' + local yb=`r6'+2400+max(0,(1000-100*`ymax')) + gph text `yb' `Axh0' 0 0 `b2' + if "`b1'"!="." { + local yb=`r6'+3000+max(0,(1200-100*`ymax')) + local b1=substr("`b1'",2,.) + if substr("`b1'",1,3)=="*I:" { +*"Favours ..." labels + local flab= substr("`b1'",4,.) + tokenize "`flab'" , parse(*) + if "`1'"!="" { + local xt=`Axh0'-1000 + gph text `yb' `xt' 0 1 `1' + } + if "`3'"!="" { + local xt=`Axh0'+1000 + gph text `yb' `xt' 0 -1 `3' + } + } + else { + gph text `yb' `Axh0' 0 0 `b1' + } + } + + +*add xtick & xlabel manually + tokenize "`xlabel'", parse(,) + while "`1'"!="" { + local x=`1' + if (`x'>10e8) { local x="10e8" } + if ((`x'<=-10e8) & (`h0'==0)) { local x="-10e8" } + local Ax=`r7'*(`xlog'(`x')) +`r8' + local Ayh=`r6' + local Ayl=`r6'+400 + local Ayt=`r6'+1700 + gph line `Ayh' `Ax' `Ayl' `Ax' + if ((`x'<10e-6) & (`h0'==1)) { local x="0.00000" } + if ((`x'<10e4) & (`x'>-10e4)) { local x=substr("`x'",1,7) } + gph text `Ayt' `Ax' 0 0 `x' + mac shift 2 + } + + tokenize "`xtick'", parse(,) + while "`1'"!="" { + local Ax=`r7'*(`xlog'(`1')) + `r8' + local Ayh=`r6' + local Ayl=`r6'+400 + local Ayt=`r6'+1000 + gph line `Ayh' `Ax' `Ayl' `Ax' + mac shift 2 + } + +*Add legend + local Ayhi =(`Gyhi'+2)*`r5'+`r6' + local Axtexh=50+max(0,min(2400,`ymax'*60-700)) + local Ayhead=`r5'*(`ymax'+1) + `r6' + + gph text `Ayhead' `Axtexh' 0 -1 $S_TX + + +/*Order of text: stats, counts, weights (where selected)*/ +*New positionings reduce gaps between stats/weight/counts + + if ("`stats'"=="") { +*Align stats first at Axhi. Use prev line if `sscale' too long (>12chrs) +* local lenssc=length("`sscale'") +* if `lenssc'<13 { +* gph text `Ayhead' `Axhi' 0 -1 `sscale' ($IND% CI) +* } +* else { + local Ayhead2=`r5'*(`ymax'+1.65) + `r6' + gph text `Ayhead2' `Axhi' 0 -1 `sscale' + gph text `Ayhead' `Axhi' 0 -1 ($IND% CI) +* } + } + if ("`counts'"!="") { +*Align counts 2nd if both stats & weight + if ("`stats'"=="") { + local Ax2hi1=`Axh20'+(`Axh60'-`Axh20')*(max(0.4, min(1,2-0.07*`ymax') ) ) + local Ax2hi2=`Axh20'+(`Axh80'-`Axh20')*(max(0.4, min(1,2-0.07*`ymax') ) ) +*local Ax2hi1=`Axh60' +*local Ax2hi2=`Axh80' + } + else { + local Ax2hi1=`Axhi'+(`Axh20'-`Axhi')*(max(0.4, min(1,2-0.07*`ymax') ) ) + local Ax2hi2=`Axhi'+(`Axh40'-`Axhi')*(max(0.4, min(1,2-0.07*`ymax') ) ) +*local Ax2hi1=`Axh20' +*local Ax2hi2=`Axh40' + } + local yt=`Ayhead'-max(200, min(1000,1600-40*`ymax')) + gph text `yt' `Ax2hi1' 0 0 No. of events +* gph font 500 270 + gph text `Ayhead' `Ax2hi1' 0 1 $MA_G1L + gph text `Ayhead' `Ax2hi2' 0 1 $MA_G2L + } + if ("`wt'"=="") { + if ("`stats'"=="" & "`counts'"!="") { +*local Ax3hi=`Axh100' + local Ax3hi=`Axh20'+(`Axh100'-`Axh20')*(max(0.4, min(1,2-0.07*`ymax') ) ) + } + else if ("`stats'"!="" & "`counts'"=="") { + local Ax3hi=`Axh20' + } + else { +*local Ax3hi=`Axh60' + local Ax3hi=`Axh20'+(`Axh60'-`Axh20')*(max(0.4, min(1,2-0.07*`ymax') ) ) + } + gph text `Ayhead' `Ax3hi' 0 1 % Weight + } + gen `Ghsqrwt'=0.5*sqrt(`weight')/2 + local flag=0 + while `flag'<1 { + cap assert `Ghsqrwt'<0.5 if (`use'==1) + if _rc!=0 { replace `Ghsqrwt'=0.9*`Ghsqrwt' } + else { local flag=10} + } + replace `Ghsqrwt'=($MA_FBSC)*`Ghsqrwt' + local flag2=0 + local flag3=0 + local i=1 + gph pen 2 + + while `i'<=`ymax' { + local Aytcen= `r5'*(`id'[`i']-0.2)+`r6' /* text label centre */ + local Aygcen= `r5'*(`id'[`i'])+`r6' /* graphics label centre */ + + +*label to put on left hand + local tx = `label'[`i'] + local Axtexs=`Axtexh'+400 + +*use=0 => blank line except for "by" legend + if (`use'[`i']==0) { + gph pen 3 + gph text `Aytcen' `Axtexh' 0 -1 `tx' + } + +*use=1 => individual trial + if `use'[`i']==1 { + gph pen 2 + gph text `Aytcen' `Axtexs' 0 -1 `tx' + if `lci'[`i']==. | `uci'[`i']==. { local flag2=10 } + else { +* Define lower/upper points on x-line, and centre on y-axis + local Axlpt= `r7'*(`xlog'( `lci'[`i'] ))+`r8' + local Axupt= `r7'*(`xlog'( `uci'[`i'] ))+`r8' + if (`Axupt' < `Axlo') | (`Axlpt' > `Axhi') { +* If CI is totally off scale draw (triangular) arrow + local Ayco1=`r5'*(`id'[`i']-0.2)+`r6' + local Ayco2=`r5'*(`id'[`i']+0.2)+`r6' + if `Axupt'<=`Axlo' { + local Axlpt =`Axlo' + local Axco1=`r7'*(`Gxlo')+`r8' + local Axco2=`r7'*(`Gxlo')+`r8'+450 + } + if `Axlpt'>=`Axhi' { + local Axupt =`Axhi' + local Axco1=`r7'*(`Gxhi')+`r8' + local Axco2=`r7'*(`Gxhi')+`r8'-450 + } + gph line `Aygcen' `Axco1' `Ayco2' `Axco2' + gph line `Ayco2' `Axco2' `Ayco1' `Axco2' + gph line `Ayco1' `Axco2' `Aygcen' `Axco1' + } + else { + local Axcen =`r7'*`xlog'(`effect'[`i'])+`r8' +* Define box size + local Ahboxl =abs(`r5'*( `Ghsqrwt'[`i'] )) + local Ay1cord=`Aygcen'+`Ahboxl' + local Ax1cord=`Axcen' -`Ahboxl' + local Ay2cord=`Aygcen'-`Ahboxl' + local Ax2cord=`Axcen' +`Ahboxl' + if (`Axlpt' < `Axlo') | (`Axupt' > `Axhi') { +* CI is on but not totaly on scale: draw arrow at end of CI + local Ayco1=`r5'*(`id'[`i']-0.1)+`r6' + local Ayco2=`r5'*(`id'[`i']+0.1)+`r6' + if `Axlpt' < `Axlo' { + local Axlpt =`Axlo' + local Axco1=`r7'*(`Gxlo')+`r8' + local Axco2=`r7'*(`Gxlo')+`r8'+350 + gph line `Aygcen' `Axco1' `Ayco1' `Axco2' + gph line `Aygcen' `Axco1' `Ayco2' `Axco2' + } + if `Axupt' > `Axhi' { + local Axupt =`Axhi' + local Axco1=`r7'*(`Gxhi')+`r8' + local Axco2=`r7'*(`Gxhi')+`r8'-350 + gph line `Aygcen' `Axco1' `Ayco1' `Axco2' + gph line `Aygcen' `Axco1' `Ayco2' `Axco2' + } + } + +*draw line for CI + gph line `Aygcen' `Axlpt' `Aygcen' `Axupt' +*either draw box for ES/weight... + if "`box'"=="" { + if (`Ax1cord' >=`Axlo') & (`Ax2cord'<=`Axhi') { + gph box `Ay1cord' `Ax1cord' `Ay2cord' `Ax2cord' $MA_FBSH + } + else {local flag2=10} + } +*...or simply plot ES (as circle) instead of box + if "`box'"!="" { + if (`Ax1cord' >=`Axlo') & (`Ax2cord'<=`Axhi') { + local ptsize=250*$MA_FBSC + gph point `Aygcen' `Axcen' `ptsize' 1 + } + else {local flag2=10} + } + } + } + } + +*use=2 => Excluded trial + if (`use'[`i']==2) { + gph text `Aytcen' `Axtexs' 0 -1 `tx' + } +*use=4 => blank line: no text or graphic necessary (above displays nothing) + +*use=3 => subgroup effect size (display by default), or... +*use=5 => overall effect size (display by default) + + if ( ((`use'[`i']==3) & ("`subgrp'"=="")) | /* + */ ((`use'[`i']==5) & ("`overall'"=="")) ) { + + if (`use'[`i']==3) { gph pen 3 } + if (`use'[`i']==5) { gph pen 5 } + gph text `Aytcen' `Axtexh' 0 -1 `tx' + local Aycol=`r5'*((`id'[`i'])-0.2)+`r6' + local Aycoh= `r5'*((`id'[`i'])+0.2)+`r6' +*the following 4 are necc in case diamond is chopped off + local Aycenl1=`Aygcen' + local Aycenl2=`Aygcen' + local Aycenh1=`Aygcen' + local Aycenh2=`Aygcen' + local Axcol=`r7'*(`xlog'(`lci'[`i']))+`r8' + local Axcen=`r7'*(`xlog'(`effect'[`i']))+`r8' + local Axcoh=`r7'*(`xlog'(`uci'[`i']))+`r8' + if (`Axcen'<`Axlo') | (`Axcen'>`Axhi') { +*diamond is off the scale! + local flag3=10 + } + else { +* phi is angle between diamond slope and y=id in right angle triangle; use this +* fact to get y where diamond is chopped off at + if `Axcol'<`Axlo' { + local flag3=10 + local tanphi=(0.2*`r5')/(`Axcen'-`Axcol') + local Aydiff=(`Axlo'-`Axcol')*`tanphi' + local Aycenl1=`Aygcen'-`Aydiff' + local Aycenl2=`Aygcen'+`Aydiff' + local Axcol=`Axlo' + gph line `Aycenl1' `Axcol' `Aycenl2' `Axcol' + } + if `Axcoh'>`Axhi' { + local flag3=10 + local tanphi=(0.2*`r5')/(`Axcoh'-`Axcen') + local Aydiff=(`Axcoh'-`Axhi')*`tanphi' + local Aycenh1=`Aygcen'-`Aydiff' + local Aycenh2=`Aygcen'+`Aydiff' + local Axcoh=`Axhi' + gph line `Aycenh1' `Axcoh' `Aycenh2' `Axcoh' + } + gph line `Aycoh' `Axcen' `Aycenh2' `Axcoh' + gph line `Aycenh1' `Axcoh' `Aycol' `Axcen' + gph line `Aycol' `Axcen' `Aycenl1' `Axcol' + gph line `Aycenl2' `Axcol' `Aycoh' `Axcen' +*Overall line (if specified) + if ((`use'[`i'])==5 & "`line'"=="" ) { + gph pen 5 + local Adashl=`r5'*(`Gyhi'-1)/100 + local Ayhi =`r5'*`Gyhi'+`r6' + local j =`r5'+`r6' + while `j'>`Ayhi' { + local Aycol=`j' + local Aycoh=`j'+`Adashl' + gph line `Aycol' `Axcen' `Aycoh' `Axcen' + local j=`j'+2*`Adashl' + } + } + + } + } +*use=9 => excluded, ignore (will have been sorted to bottom of data) + +*Diamonds or boxes&lines are now drawn - put text on the end + + if ( `use'[`i']==1 | `use'[`i']==3 | `use'[`i']==5 ) { +*put text at end of graph (if requested) + if "`stats'"=="" { +*effect sizes + local e1=`effect'[`i'] + local e2=`lci'[`i'] + local e3=`uci'[`i'] +*Make allowance for alignment where es<0 + local sp1 + if (`e1'>0) {local sp1 " "} + local sp2 + if (`e2'>0) {local sp2 " "} + local sp3 + if (`e3'>0) {local sp3 " "} + if (`e1'<1e-8) & "`Glog'"!="" {local e1 "<10^-8"} + else if (`e1'>1e8) & (`e1'!=.) & "`Glog'"!="" { + local e1 ">10^8" + } + else { local e1: displ %4.2f `e1' } + if (`e2'<1e-8) & ("`Glog'"!="" | "`cornfield'"!="") { + local e2 "<10^-8" + } + else if (`e2'>1e8) & (`e2'!=.) & "`Glog'"!="" {local e2 ">10^8"} + else { local e2: displ %4.2f `e2' } + if (`e3'<1e-8) & "`Glog'"!="" {local e3 "<10^-8"} + else if (`e3'>1e8) & (`e3'!=.) & ("`Glog'"!="" | "`cornfield'"!="") { + local e3 ">10^8" + } + else { local e3: displ %4.2f `e3' } + + local esize "`sp1'`e1' (`sp2'`e2',`sp3'`e3')" + gph text `Aytcen' `Axhi' 0 -1 `esize' + } + if "`wt'"=="" { + local weit: displ %4.1f `wtdisp'[`i'] + if `weit'!=. { gph text `Aytcen' `Ax3hi' 0 1 `weit' } + } + if "`counts'"!="" { + local nm: displ `rawdata'[`i'] + if "`nm'"!="." { + parse "`nm'" , parse(";") + local nm1 "`1'" + local nm2 "`3'" + gph text `Aytcen' `Ax2hi1' 0 1 `nm1' + gph text `Aytcen' `Ax2hi2' 0 1 `nm2' + } + } + } + if `use'[`i']==2 & "`stats'"=="" { + gph text `Aytcen' `Axhi' 0 -1 (Excluded) + if "`counts'"!="" { + local nm: displ `rawdata'[`i'] + if "`nm'"!="." { + parse "`nm'" , parse(";") + local nm1 "`1'" + local nm2 "`3'" + gph text `Aytcen' `Ax2hi1' 0 1 `nm1' + gph text `Aytcen' `Ax2hi2' 0 1 `nm2' + } + } + } + local i=`i'+1 + } + + + gph close + } /* end of qui section*/ + #delimit ; + if `flag1'>1 { di in bl _n "Note: invalid xlabel() or xtick(): graph has been rescaled"}; + if `flag2'>1 { di in bl _n "Warning: Some trials cannot be +represented graphically (may contain" _n "inestimable effects). Consider using different xlabel()"}; + if `flag3'>1 { di in bl _n "Warning: Overall (or subgroup) effect size not fully +represented graphically." _n "Consider using xlabel()"}; + #delimit cr +end + +exit + +Revision history +*Log option added: can display Log(ORs,RRs) on table & graph. +*graph appears when only 1 trial. +*nomenclature for _ES changed when OR or RR selected +*std err of estimate /log est in saved results is renamed and labelled so is clearer +*can handle 2 variables (ES, seES), exponentiated with new eform option +*Max label length for table is now 20chrs +*Breslow Day test for OR heterogeneity added +*Can display n/N for trials, with and without weights/stats. +*Groups can be labelled when using the counts option with group1() and group2() +*User-defined weight option: +* - can't use with fixed or random option +* - metan ... , wgt(wt) == metan ... , fixedi if wt=1/v ie IV weighting +* - however will differ if RE: +* - no tau2 involved in weights ie variance est differs: wgt=1/(vi+t) but SIGMA{1/wgt}=/= SIGMA{wi^2 * var(thetai) }/[SIGMA(wi)]^2 +* - pooled ES=SIGMA{wgt*es}/SIGMA{wgt} =/= FE weighted, so heterogeneity not equal +*Can plot the ES alone without the box (nobox) +*Option to change "Study" label to something else +*Display a bit nicer (table formatted 3 rather than up to 7 dec places) +*Removed "Study -" from top; by default is replaced with "Study". Annoying "tick" next to it removed +*Added I^2 (Higgins & Thompson 2003) +*xtick, b2title options added can add "Favours ..." below graph with prefix and asterisk in b1(*I: .... * ....) +*Nointeger: allows sample size to be non-integer if requested. +*Adding continuity correction: currently allows user-defined const (or via nointeger opt) +*r(sumstat) now displays with S/WMD (did forget to was long standing bug) +*by() option added!!! +*r(tger) and r(cger) corrected from prev by() versions; overall ERs were not reported (were from the last by subg) +*bug with by() removed: wasn't keeping _ES etc +*allows CI syntax (3 variables: theta lower_limit upper_limit), BUT: +* - does not follow "meta" syntax, ie does not assume log transform needed +* - default is to assume symmetry and calculate se=0.5*(upper-lower)/z, but allows asymmetry +* - bug with udw and missing data fixed 1Mar04 +*minor bugs fixed: trial labelling with by() on table, extended line to right of graph with +*options nostats nowt counts all specified, sortby w/o by() option, junk text if by() subgroup +*contained no informative trials, erroneous lack of overall summary on graph in some situations. + diff --git a/Modules/ado/plus/m/metan7.dlg b/Modules/ado/plus/m/metan7.dlg new file mode 100644 index 0000000..7c513dc --- /dev/null +++ b/Modules/ado/plus/m/metan7.dlg @@ -0,0 +1,838 @@ +/* + +*! metan7 dialog version 1.0.5, 1 Apr 2004, T. J. Steichen, steichen@triad.rr.com +*! for metan7 version 1.85, 15 Mar 2004, M. J. Bradburn, mike.bradburn@cancer.org.uk + +Fixed and random effects meta-analysis +-------------------------------------- +Syntax: metan7 varlist [if exp] [in range] [, + label(namevar=name, yearvar=year) + fixed random fixedi randomi peto + rr or rd cornfield chi2 breslow notable nograph + cohen hedges glass nostandard + log sortby(sort_vars) ilevel(#) olevel(#) nokeep + xlabel(#,..,#) force t1title(#,..,#) boxsha(#) boxsca(#) texts(#) + saving(filename) nowt counts nostats nooverall + group1(text) group2(text) effect(text) nobox eform + wgt(weightvar) xtick(#,..,#) + t2title(#,..,#) b1title(#,..,#) b2title(#,..,#) + nointeger cc(#) by(byvar) nosubgroup sgweight legend(text) ] + +To install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "Meta-analysis of Binary and Continuous Data (meta&n)" "db metan7" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. + +*/ + +VERSION 8.0 + +INCLUDE _std_medium +INCLUDE _ht300 +DEFINE _dlgwd 450 +INCLUDE header + +HELP hlp1, view("help metan7") +RESET res1, label("Reset") + +DIALOG main, label("metan7 1.85 - Meta-analysis of Binary & Continuous") tabtitle("Main") +BEGIN + GROUPBOX gb_data 10 5 310 _ht1h, /// + label("Type of Data:") + RADIO r_binary 15 25 60 ., /// + label(" Count") first /// + onclickon(script main_binary_on) /// + onclickoff(script main_binary_off) + RADIO r_continuous 75 25 90 ., /// + label("Continuous") middle /// + onclickon(script main_continuous_on) /// + onclickoff(script main_continuous_off) + RADIO r_effect_ci 165 25 75 ., /// + label("Effect/CI") middle /// + onclickon(script main_effect_ci_on) /// + onclickoff(script main_effect_ci.off) + RADIO r_effect_se 240 25 75 ., /// + label("Effect/SE") last /// + onclickon(script main_effect_se_on) /// + onclickoff(script main_effect_se_off) + +/* end GROUPBOX gb_data */ + + TEXT tx_binary 10 50 310 ., /// + label("Vars for Counts: a, b, c, d, in that order") + VARLIST vl_binary @ _ss @ ., /// + label("Vars for a, b, c, d") + + TEXT tx_contin_exp @ 50 310 ., /// + label("Vars for Exp. Group: n, mean, sd, in that order") + VARLIST vl_contin_exp @ _ss @ ., /// + label("Experimental Group: n, mean, sd") + TEXT tx_contin_ctl @ _ss 310 ., /// + label("Vars for Control Group: n, mean, sd, in that order") + VARLIST vl_contin_ctl @ _ss @ ., /// + label("Control Group: n, mean, sd") + + TEXT tx_effect_ci @ 50 310 ., /// + label("Vars for Effects: theta, lowerCI, upperCI, in that order") + VARLIST vl_effect_ci @ _ss @ ., /// + label("Effect Sizes: theta, lowerCI, upperCI") + + TEXT tx_effect_se @ 50 310 ., /// + label("Vars for Effects: theta, se(theta), in that order") + VARLIST vl_effect_se @ _ss @ ., /// + label("Effect Sizes: theta, se(theta)") + +/* end vars */ + + GROUPBOX gb_labels 10 130 310 _ht3h, /// + label("Labels for Data:") + CHECKBOX cb_name 20 150 70 ., /// + label("Name:") /// + onclickon(main.vn_name.enable) /// + onclickoff(main.vn_name.disable) + VARNAME vn_name 100 150 210 ., /// + label("Name Variable") + CHECKBOX cb_year 20 170 70 ., /// + label("Year:") /// + onclickon(main.vn_year.enable) /// + onclickoff(main.vn_year.disable) + VARNAME vn_year 100 170 210 ., /// + label("Year Variable") + +/* end GROUPBOX gb_labels */ + + GROUPBOX gb_by 10 200 310 45, /// + label("By Variable:") + CHECKBOX cb_by 20 220 70 ., /// + label(" By:") /// + onclickon(script main_by_on) /// + onclickoff(script main_by_off) + VARLIST vl_by 100 220 210 ., /// + label("By Variable") /// + option("by") + +/* end GROUPBOX gb_by */ + + GROUPBOX gb_sortby 10 250 310 45, /// + label("Sort Data:") + CHECKBOX cb_sortby 20 270 70 ., /// + label(" By:") /// + onclickon(main.vl_sortby.enable) /// + onclickoff(main.vl_sortby.disable) + VARLIST vl_sortby 100 270 210 ., /// + label("Name Variable") /// + option("sortby") + +/* end GROUPBOX gb_sortby */ + + GROUPBOX gb_opts 325 5 120 85, /// + label("General Options:") + + CHECKBOX cb_nokeep 330 25 70 ., /// + label("noKeep") /// + option("nokeep") + + CHECKBOX cb_ilevel 330 45 60 ., /// + label("ilevel:") /// + onclickon(main.ed_ilevel.enable) /// + onclickoff(main.ed_ilevel.disable) + EDIT ed_ilevel 400 45 40 ., /// + label("ilevel") /// + numonly default(global S_level) /// + option("ilevel") + + CHECKBOX cb_olevel 330 65 60 ., /// + label("olevel:") /// + onclickon(main.ed_olevel.enable) /// + onclickoff(main.ed_olevel.disable) + EDIT ed_olevel 400 65 40 ., /// + label("olevel") /// + numonly default(global S_level) /// + option("olevel") + +/* end GROUPBOX gb_opts */ + + FRAME fr_wgt 325 95 120 60 + CHECKBOX cb_wgt 330 100 110 ., /// + label("Weight Var") /// + onclickon(main.vn_wgt.enable) /// + onclickoff(main.vn_wgt.disable) + VARNAME vn_wgt 330 121 110 ., /// + label("Weight Variable") /// + option("wgt") + +/* end wgt */ + + GROUPBOX gb_by_opts 325 200 120 61, /// + label("By Options:") + + CHECKBOX cb_nosubgroup 330 220 100 ., /// + label("noSubGroup") /// + option("nosubgroup") + + CHECKBOX cb_sgweight 330 240 100 ., /// + label("sgWeight") /// + option("sgweight") + +/* end GROUPBOX gb_by_opts */ + +END + +DIALOG metan7_b, tabtitle("Binary...") +BEGIN + GROUPBOX gb_pool 0 10 210 _ht9h, /// + label("Pooling Model") + RADIO r_fixed 10 30 190 ., /// + label("Fixed, Mantel-Haenszel") first /// + onclickoff(program metan7_b_bd) /// + option("fixed") + RADIO r_fixedi @ _ss @ ., /// + label("Fixed, Inverse Variance") middle /// + onclickoff(program metan7_b_bd) /// + option("fixedi") + RADIO r_random @ _ss 195 ., /// + label("Random (M-H heterogeneity)") middle /// + onclickon(script metan7_b_random_on) /// + onclickoff(program metan7_b_chi2) /// + option("random") + RADIO r_randomi @ _ss @ ., /// + label("Random (I-V heterogeneity)") middle /// + onclickon(script metan7_b_random_on) /// + onclickoff(program metan7_b_chi2) /// + option("randomi") + RADIO r_peto @ _ss @ ., /// + label("Peto") last /// + onclickon(script metan7_b_peto_on) /// + onclickoff(program metan7_b_cornfield) /// + option("peto") + + GROUPBOX gb_stat 220 10 120 _ht5h, /// + label("Statistic") + RADIO r_rr 230 30 80 ., /// + label("RR") first /// + onclickon(script metan7_b_rr_on) /// + onclickoff(program metan7_b_rr_off) /// + option("rr") + RADIO r_or @ _ss @ ., /// + label("OR") middle /// + onclickon(program metan7_b_or_on) /// + onclickoff(program metan7_b_or_off) /// + option("or") + RADIO r_rd @ _ss @ ., /// + label("RD") last /// + option("rd") + + CHECKBOX cb_cornfield 10 140 200 ., /// + label("Use Cornfield CI's") /// + option("cornfield") + CHECKBOX cb_chi2 10 160 200 ., /// + label("Use Chi-2 Statistic") /// + option("chi2") + CHECKBOX cb_breslow 10 180 200 ., /// + label("Use Breslow-Day test") /// + option("breslow") + + CHECKBOX cb_log 230 100 200 ., /// + label("Log scaled") /// + option("log") + + CHECKBOX cb_eform 230 120 200 ., /// + label("Exponentiate") /// + option("eform") + + CHECKBOX cb_notable 230 140 200 ., /// + label("noTable") /// + option("notable") + CHECKBOX cb_nograph 230 160 200 ., /// + label("noGraph") /// + option("nograph") + + CHECKBOX cb_cc 10 260 150 ., /// + label("Continuity Correction:") /// + onclickon(metan7_b.ed_cc.enable) /// + onclickoff(metan7_b.ed_cc.disable) + EDIT ed_cc 160 260 65 ., /// + label("Continuity Correction") /// + option("cc") + + CHECKBOX cb_nointeger 230 260 200 ., /// + label("noInteger") /// + option("nointeger") +END + +DIALOG metan7_c, tabtitle("Continuous...") +BEGIN + GROUPBOX gb_pool 0 10 210 _ht3h, /// + label("Pooling Model") + RADIO r_fixed 10 30 190 ., /// + label("Fixed, Inverse Variance") first /// + option("fixed") + RADIO r_random @ _ss @ ., /// + label("Random (I-V heterogeneity)") last /// + option("random") + + GROUPBOX gb_stat 220 10 120 _ht7h, /// + label("Statistic") + RADIO r_cohen 230 30 100 ., /// + label("Cohen") first /// + option("cohen") + RADIO r_hedges @ _ss @ ., /// + label("Hedges") middle /// + option("hedges") + RADIO r_glass @ _ss @ ., /// + label("Glass") middle /// + option("glass") + RADIO r_nostandard @ _ss @ ., /// + label("noStandard") last /// + option("nostandard") + + CHECKBOX cb_notable 230 140 200 ., /// + label("noTable") /// + option("notable") + CHECKBOX cb_nograph 230 160 200 ., /// + label("noGraph") /// + option("nograph") + + CHECKBOX cb_nointeger 230 260 200 ., /// + label("noInteger") /// + option("nointeger") + +END + +DIALOG metan7_e, tabtitle("Effect...") +BEGIN + GROUPBOX gb_pool 0 10 210 _ht3h, /// + label("Pooling Model") + RADIO r_fixed 10 30 190 ., /// + label("Fixed, Inverse Variance") first /// + option("fixed") + RADIO r_random @ _ss @ ., /// + label("Random (I-V heterogeneity)") last /// + option("random") + + CHECKBOX cb_notable 230 140 200 ., /// + label("noTable") /// + option("notable") + CHECKBOX cb_nograph 230 160 200 ., /// + label("noGraph") /// + option("nograph") + + CHECKBOX cb_effect 10 110 100 ., /// + label("Effect Label:") /// + onclickon(metan7_e.ed_effect.enable) /// + onclickoff(metan7_e.ed_effect.disable) + EDIT ed_effect 115 @ 225 ., /// + label("effect label") /// + option("effect") + +END + +DIALOG graph, tabtitle("Graph Opts") +BEGIN + + CHECKBOX cb_saving 10 10 100 ., /// + label("Save graph:") /// + onclickon(graph.fi_saving.enable) /// + onclickoff(graph.fi_saving.disable) + FILE fi_saving 110 10 240 ., /// + label("File Name") /// + error("Save filename") /// + dialogtitle("Save graph") /// + filter("Stata Graphs|*.gph") /// + save /// + option("saving") + +/* end saving */ + + GROUPBOX gb_xlabel 10 40 330 _ht3h, /// + label("X-axis Tick Labels (comma between):") + + CHECKBOX cb_xlabel 15 60 45 ., /// + label("Set:") /// + onclickon(script graph_xlabel_on) /// + onclickoff(script graph_xlabel_off) + EDIT ed_xlabel 65 @ 270 ., /// + label("X Tick labels") /// + option("xlabel") + + CHECKBOX cb_force 15 80 320 ., /// + label("Force Scale to Tick Range") /// + option("force") + +/* end tick labels */ + + CHECKBOX cb_counts 15 115 65 ., /// + label("Counts") /// + onclickon(script graph_counts_on) /// + onclickoff(script graph_counts_off) /// + option("counts") + + CHECKBOX cb_nowt 15 145 85 ., /// + label("noWeights") /// + option("nowt") + + CHECKBOX cb_nostats 15 165 85 ., /// + label("noStats") /// + option("nostats") + + CHECKBOX cb_nooverall 115 145 85 ., /// + label("noOverall") /// + option("nooverall") + + CHECKBOX cb_nobox 115 165 85 ., /// + label("noBox") /// + option("nobox") + +/* end switches */ + + CHECKBOX cb_legend 115 185 70 ., /// + label("Legend:") /// + onclickon(graph.ed_legend.enable) /// + onclickoff(graph.ed_legend.disable) + EDIT ed_legend 190 @ 55 ., /// + label("legend") /// + option("legend") + + CHECKBOX cb_grp1 85 115 55 ., /// + label("Grp 1:") /// + onclickon(graph.ed_grp1.enable) /// + onclickoff(graph.ed_grp1.disable) + EDIT ed_grp1 145 @ 90 ., /// + label("Grp1") /// + option("group1") + + CHECKBOX cb_grp2 245 115 55 ., /// + label("Grp 2:") /// + onclickon(graph.ed_grp2.enable) /// + onclickoff(graph.ed_grp2.disable) + EDIT ed_grp2 305 @ 90 ., /// + label("Grp2") /// + option("group2") + + CHECKBOX cb_boxy 255 145 95 ., /// + label("Box yscale:") /// + onclickon(graph.ed_boxy.enable) /// + onclickoff(graph.ed_boxy.disable) + EDIT ed_boxy 355 @ 40 ., /// + label("Box yscale") numonly default(1) /// + option("boxsca") + + CHECKBOX cb_boxs 255 165 95 ., /// + label("Box shade:") /// + onclickon(graph.ed_boxs.enable) /// + onclickoff(graph.ed_boxs.disable) + EDIT ed_boxs 355 @ 40 ., /// + label("Box shading") numonly default(4) /// + option("boxsha") + + CHECKBOX cb_texts 255 185 95 ., /// + label("Font scale:") /// + onclickon(graph.ed_texts.enable) /// + onclickoff(graph.ed_texts.disable) + EDIT ed_texts 355 @ 40 ., /// + label("Font scale") numonly default(1) /// + option("texts") + +/* end sets */ + + GROUPBOX gb_gopts7 10 205 390 _ht1h, /// + label("Allowed Graph7 Options:") + EDIT ed_gopts7 15 225 380 ., /// + label("Graph7 Options") + + CHECKBOX cb_b1 15 255 390 ., /// + label("Effect Direction Labels, option b1( ):") /// + onclickon(script graph_b1_on) /// + onclickoff(script graph_b1_off) + TEXT tx_b1_l 10 275 25 ., /// + label("Left:") + EDIT ed_b1_l 35 275 160 ., /// + label(" Left") + TEXT tx_b1_r 205 275 35 ., /// + label("Right:") + EDIT ed_b1_r 240 275 160 ., /// + label("Right") + +/* end Graph7 opts */ + +END + +INCLUDE ifin + +SCRIPT main_binary_on +BEGIN + main.tx_binary.show + main.vl_binary.show + main.tx_binary.enable + main.vl_binary.enable + + main.tx_effect_ci.disable + main.vl_effect_ci.disable + main.tx_effect_ci.hide + main.vl_effect_ci.hide + + main.tx_effect_se.disable + main.vl_effect_se.disable + main.tx_effect_se.hide + main.vl_effect_se.hide + + main.tx_contin_exp.disable + main.vl_contin_exp.disable + main.tx_contin_exp.hide + main.vl_contin_exp.hide + + main.tx_contin_ctl.disable + main.vl_contin_ctl.disable + main.tx_contin_ctl.hide + main.vl_contin_ctl.hide + + graph.cb_counts.enable +END + +SCRIPT main_binary_off +BEGIN + main.tx_binary.disable + main.vl_binary.disable + main.tx_binary.hide + main.vl_binary.hide + + graph.cb_counts.disable +END + +SCRIPT main_continuous_on +BEGIN + main.tx_contin_exp.show + main.vl_contin_exp.show + main.tx_contin_exp.enable + main.vl_contin_exp.enable + + main.tx_contin_ctl.show + main.vl_contin_ctl.show + main.tx_contin_ctl.enable + main.vl_contin_ctl.enable + + main.tx_binary.disable + main.vl_binary.disable + main.tx_binary.hide + main.vl_binary.hide + + main.tx_effect_ci.disable + main.vl_effect_ci.disable + main.tx_effect_ci.hide + main.vl_effect_ci.hide + + main.tx_effect_se.disable + main.vl_effect_se.disable + main.tx_effect_se.hide + main.vl_effect_se.hide +END + +SCRIPT main_continuous_off +BEGIN + main.tx_contin_exp.disable + main.vl_contin_exp.disable + main.tx_contin_exp.hide + main.vl_contin_exp.hide + + main.tx_contin_ctl.disable + main.vl_contin_ctl.disable + main.tx_contin_ctl.hide + main.vl_contin_ctl.hide +END + +SCRIPT main_effect_ci_on +BEGIN + main.tx_effect_ci.show + main.vl_effect_ci.show + main.tx_effect_ci.enable + main.vl_effect_ci.enable + + main.tx_effect_se.disable + main.vl_effect_se.disable + main.tx_effect_se.hide + main.vl_effect_se.hide + + main.tx_binary.disable + main.vl_binary.disable + main.tx_binary.hide + main.vl_binary.hide + + main.tx_contin_exp.disable + main.vl_contin_exp.disable + main.tx_contin_exp.hide + main.vl_contin_exp.hide + + main.tx_contin_ctl.disable + main.vl_contin_ctl.disable + main.tx_contin_ctl.hide + main.vl_contin_ctl.hide +END + +SCRIPT main_effect_ci_off +BEGIN + main.tx_effect_ci.disable + main.vl_effect_ci.disable + main.tx_effect_ci.hide + main.vl_effect_ci.hide +END + +SCRIPT main_effect_se_on +BEGIN + main.tx_effect_se.show + main.vl_effect_se.show + main.tx_effect_se.enable + main.vl_effect_se.enable + + main.tx_effect_ci.disable + main.vl_effect_ci.disable + main.tx_effect_ci.hide + main.vl_effect_ci.hide + + main.tx_binary.disable + main.vl_binary.disable + main.tx_binary.hide + main.vl_binary.hide + + main.tx_contin_exp.disable + main.vl_contin_exp.disable + main.tx_contin_exp.hide + main.vl_contin_exp.hide + + main.tx_contin_ctl.disable + main.vl_contin_ctl.disable + main.tx_contin_ctl.hide + main.vl_contin_ctl.hide +END + +SCRIPT main_effect_se_off +BEGIN + main.tx_effect_se.disable + main.vl_effect_se.disable + main.tx_effect_se.hide + main.vl_effect_se.hide +END + +SCRIPT main_by_on +BEGIN + main.vl_by.enable + main.gb_by_opts.enable + main.cb_nosubgroup.enable + main.cb_sgweight.enable +END + +SCRIPT main_by_off +BEGIN + main.vl_by.disable + main.gb_by_opts.disable + main.cb_nosubgroup.disable + main.cb_sgweight.disable +END + +SCRIPT metan7_b_random_on +BEGIN + metan7_b.cb_breslow.disable + metan7_b.cb_chi2.disable +END + +SCRIPT metan7_b_peto_on +BEGIN + metan7_b.cb_breslow.disable + metan7_b.cb_cornfield.disable +END + +PROGRAM metan7_b_bd +BEGIN + if metan7_b.r_or { + call metan7_b.cb_breslow.enable + } +END + +PROGRAM metan7_b_chi2 +BEGIN + if metan7_b.r_or & !(metan7_b.r_random | metan7_b.r_randomi) { + call metan7_b.cb_chi2.enable + } +END + +PROGRAM metan7_b_cornfield +BEGIN + if metan7_b.r_or { + call metan7_b.cb_cornfield.enable + } +END + +SCRIPT metan7_b_rr_on +BEGIN + metan7_b.cb_log.enable + metan7_b.cb_eform.enable +END + +PROGRAM metan7_b_or_on +BEGIN + call metan7_b.cb_log.enable + call metan7_b.cb_eform.enable + call metan7_b.r_peto.enable + if !metan7_b.r_peto { + call metan7_b.cb_cornfield.enable + } + if !(metan7_b.r_random | metan7_b.r_randomi) { + call metan7_b.cb_chi2.enable + } + call metan7_b.cb_breslow.enable +END + +PROGRAM metan7_b_or_off +BEGIN + if !metan7_b.r_rr { + call metan7_b.cb_log.disable + call metan7_b.cb_eform.disable + } + call metan7_b.r_peto.disable + call metan7_b.cb_cornfield.disable + call metan7_b.cb_chi2.disable + call metan7_b.cb_breslow.disable +END + +PROGRAM metan7_b_rr_off +BEGIN + if !metan7_b.r_or { + call metan7_b.cb_log.disable + call metan7_b.cb_eform.disable + } +END + +SCRIPT graph_xlabel_on +BEGIN + graph.ed_xlabel.enable + graph.cb_force.enable +END + +SCRIPT graph_xlabel_off +BEGIN + graph.ed_xlabel.disable + graph.cb_force.disable +END + +SCRIPT graph_counts_on +BEGIN + graph.cb_grp1.enable + graph.cb_grp2.enable +END + +SCRIPT graph_counts_off +BEGIN + graph.cb_grp1.disable + graph.cb_grp2.disable + graph.cb_grp1.setoff + graph.cb_grp2.setoff + graph.ed_grp1.disable + graph.ed_grp2.disable +END + +SCRIPT graph_b1_on +BEGIN + graph.tx_b1_l.enable + graph.ed_b1_l.enable + graph.tx_b1_r.enable + graph.ed_b1_r.enable +END + +SCRIPT graph_b1_off +BEGIN + graph.tx_b1_l.disable + graph.ed_b1_l.disable + graph.tx_b1_r.disable + graph.ed_b1_r.disable +END + + +PROGRAM command +BEGIN + put " metan7 " + if main.r_binary { + varlist main.vl_binary + } + if main.r_continuous { + varlist main.vl_contin_exp main.vl_contin_ctl + } + if main.r_effect_ci { + varlist main.vl_effect_ci + } + if main.r_effect_se { + varlist main.vl_effect_se + } + INCLUDE _ifin_pr + beginoptions + if main.cb_name | main.cb_year { + put "label(" + if main.cb_name { + put "namevar=" main.vn_name + } + if main.cb_name & main.cb_year { + put ", " + } + if main.cb_year { + put "yearvar=" main.vn_year + } + put ") " + } + optionarg main.vl_sortby + optionarg main.vl_by + optionarg main.ed_ilevel + optionarg main.ed_olevel + optionarg main.vn_wgt + option main.cb_nokeep + option main.cb_nosubgroup + option main.cb_sgweight + if main.r_binary { + if !main.vn_wgt { + option radio(metan7_b r_fixed r_fixedi r_random r_randomi r_peto) + } + option radio(metan7_b r_rr r_or r_rd) + option metan7_b.cb_cornfield + option metan7_b.cb_chi2 + option metan7_b.cb_breslow + option metan7_b.cb_log + option metan7_b.cb_eform + option metan7_b.cb_nograph + option metan7_b.cb_notable + optionarg metan7_b.ed_cc + option metan7_b.cb_nointeger + } + if main.r_continuous { + if !main.vn_wgt { + option radio(metan7_c r_fixed r_random) + } + option radio(metan7_c r_cohen r_hedges r_glass r_nostandard) + option metan7_c.cb_nograph + option metan7_c.cb_notable + option metan7_c.cb_nointeger + } + if main.r_effect_se | main.r_effect_ci { + if !main.vn_wgt { + option radio(metan7_e r_fixed r_random) + } + optionarg metan7_e.ed_effect + option metan7_e.cb_nograph + option metan7_e.cb_notable + } + optionarg graph.fi_saving + optionarg graph.ed_xlabel + option graph.cb_force + option graph.cb_counts + option graph.cb_nowt + option graph.cb_nostats + option graph.cb_nooverall + option graph.cb_nobox + optionarg graph.ed_grp1 + optionarg graph.ed_grp2 + optionarg graph.ed_texts + optionarg graph.ed_legend + optionarg graph.ed_boxy + optionarg graph.ed_boxs + put graph.ed_gopts7 " " + if graph.cb_b1 { + put "b1(*I:" graph.ed_b1_l "*" graph.ed_b1_r ") " + } + endoptions +END diff --git a/Modules/ado/plus/m/metan7.hlp b/Modules/ado/plus/m/metan7.hlp new file mode 100644 index 0000000..586c181 --- /dev/null +++ b/Modules/ado/plus/m/metan7.hlp @@ -0,0 +1,369 @@ +.- +help for ^metan7^, ^labbe^, ^funnel^ +.- + +Fixed and random effects meta-analysis +-------------------------------------- + + + ^metan7^ varlist [^if^ exp] [^in^ range] + [, ^rr or rd cohen hedges glass nosta^ndard + ^fixed random fixedi randomi peto wgt(^weightvar^) nooverall^ + ^cornfield chi2 breslow log eform noint^eger^ cc(^#^)^ + ^by(^byvar^) nosubgroup sgweight ilevel(^#^) olevel(^#^)^ + ^label(namevar=^name^, yearvar=^year^) legend(^text^)^ + ^sortby(^sort_vars^) nokeep notable nograph^ + ^xt^ick^(^#,..,#^) xla^bel^(^#,..,#^) force^ + ^t1title(^#,..,#^) t2title(^#,..,#^) b1title(^#,..,#^) b2title(^#,..,#^)^ + ^boxsha(^#^) boxsca(^#^) nobox texts(^#^) nowt nostats counts^ + ^group1(^text^) group2(^text^) effect(^text^) saving(^filename^)^ ] + + + ^labbe^ varlist [^if^ exp] [^in^ range] [^weight^] + [ , ^nowt per^cent ^or(^#^) rr(^#^) rd(^#^) rrn(^#^) null logit^ + graph_options ] + + ^funnel^ [varlist] [^if^ exp] [^in^ range] [^weight^] + [, ^ysq^rt ^sa^mple ^ov^erall(#) graph_options ] + +Description +----------- + +These routines provide methods for the meta-analysis of aggregate level +data. Either binary (event) or continuous data from two groups may be +combined using the ^metan7^ command. Additionally, pre-calculated effect +sizes may be pooled. Several meta-analytic methods are available, and +the results may be displayed graphically in a Forest plot. A test for +the statistical significance of the overall effect size is also provided, +along with a test for excess between-trial variation (heterogeneity) +and the I-squared measure which is an alternative summary of this +(Higgins & Thompson 2002). Note that this command has been updated- +see ^metan^ + +^labbe^ draws a L'Abbe plot for event data (proportion of successes in the +two groups). This is an alternative to the graph produced by ^metan7^ + +^funnel^ may be used for producing a "funnel plot", a graph of either the +study sample size, standard error or precision (inverse of s.e.) against +the effect size. + + +Options for ^metan7^ +----------------- + +The main meta-analysis routine ^metan7^ requires either two, three, four +or six variables to be declared. + +When four variables are specified, analysis of binary data is performed +on the 2x2 table with cell counts denoted by the variable list. + +With six variables, the data are assumed continuous and to be the sample +size, mean and standard deviation of the experimental group followed by +those of the control group. + +For two or three variables, a variance-weighted analysis is performed in +a similar fashion to the @meta@ command; + the two variable syntax is <theta> and <SE(theta)>. + the 3 variable syntax is <theta>, <lower ci (theta)>, <upper ci (theta)> +Note that in this situation "theta" is taken to be the logarithm of the +effect size if the odds ratio or risk ratio is used. ^This differs from^ +^the equivalent in the meta command^. This program does not assume the +three variables need log transformation: if odds ratios or risk ratios +are combines, it is up to the user to log-transform them first. The +^eform^ option can be used to change back to the original scale if needed. +By default the confidence intervals are assumed symmetric, and the studies +are pooled by taking the variance to be equal to (CI width)/2z. + + + Specifying the measure and model with which to pool the data + ------------------------------------------------------------ + + +Options for binary data (4 variables) + +^rr^ pools risk ratios [default] +^or^ pools odds ratios +^rd^ pools risk differences + + +^fixed^ specifies a fixed effect model using the method of + Mantel and Haenszel [default] +^fixedi^ specifies a fixed effect model using the inverse variance method +^peto^ specifies that Peto's method is used to pool odds ratios +^random^ specifies a random effects model using the method of + DerSimonian & Laird, with the estimate of heterogeneity being taken + from the Mantel-Haenszel model +^randomi^ specifies a random effects model using the method of + DerSimonian & Laird, with the estimate of heterogeneity being taken + from the inverse variance fixed effect model + +^cornfield^ computes confidence intervals for odds ratios by method of + Cornfield, rather than the (default) Woolf method +^chi2^ displays chi-squared statistic (instead of z) for the test + of significance of the pooled effect size. This is available only for + odds ratios pooled using Peto or Mantel-Haenszel methods +^breslow^ produces Breslow-Day test for homogeneity of ORs + +^cc(^#^)^ defines a fixed continuity correction to add in the case where + a study contains a zero cell. By default, metan7 adds 0.5 to each cell of + a trial where a zero is encountered when using Inverse-Variance, + Der-Simonian & Laird or Mantel-Haenszel weighting to enable finite + variance estimators to be derived. However, the cc option allows the use + of other constants (including none). See also the ^nointeger^ option below. + +^nointeger^ allows the cell counts to be non-integers. This may be useful + when a variable continuity correction is sought for studies containing + zero cells, but also may be used in other circumstances, such as where a + cluster-randomised trial is to be incorporated and the "effective sample + size" is less than the total number of observations. + + +Options for continuous data + +^cohen^ pools standardised mean differences by the method of Cohen + [default] +^hedges^ pools standardised mean differences by the method of Hedges +^glass^ pools standardised mean differences by the method of Glass +^nostandard^ pools unstandardised mean differences + +^fixed^ specifies a fixed effect model using the inverse variance method + [default] +^random^ specifies a random effects model using the DerSimonian & Laird + method + +^nointeger^ denotes that the number of observations in each arm does not + need to be an integer. By default, the first and fourth variables specified +(containing N_intervention and N_control respectively) may occasionally be +non-integer (see above entry under binary data) + + + +Alternative weighting (for all data types) + +^wgt(^wgtvar^)^ denotes that the effect size is to be computed by assigning + a weight of wgtvar to the studies. When RRs or ORs are declared, their + logarithms are weighted. You should only use this option if you are + satisfied that the weights are meaningful. + + + Output + ------ + +General + +^by^ specifies that the meta-analysis is to be stratified + according to the variable declared. + +^sgweight^ specifies that the display is to present the percentage + weights within each subgroup separately. By default metan7 presents + weights as a percentage of the overall total. +^nosubgroup^ indicates that no within-group results are to be + presented. By default metan7 pools trials both within and across + all studies + +^log^ reports the results on the log scale + (valid for OR and RR analyses only) +^eform^ exponentiates all effect sizes and confidence intervals + (valid only for analyses of odds ratios or risk ratios) +^ilevel()^ specifies the significance level (eg 90,95,99) for the + individual trial confidence intervals +^olevel()^ specifies the significance level (eg 90,95,99) for the + overall (pooled) confidence intervals +^ilevel^ and ^olevel^ need not be the same, and by default are equal + to the significance level specified using the ^set level^ command + +^sortby(^varlist^)^ sorts by one or more variables ^varlist^ +^label(^ [^namevar^=namevar] [^,yearvar^=yearvar] ^)^ + labels the data by its name, year or both. Either or both option/s + may be left blank. For the table display the overall length of the + label is restricted to 20 characters +^nokeep^ prevents the retention of study parameters in permanent + variables (see saved results below) +^notable^ prevents display of table of results +^nograph^ prevents display of graph + + + +Graph display options for forest plot + +^legend()^ specifies a label to be used for the study identifiers at + the top of the graph. This is a rename of the ^stext()^ option that + appeared in some previous versions of metan7. +^effect()^ may be used when the effect size and its standard error + are declared. This allows the graph to name the summary statistic used + +^nooverall^ prevents display of overall effect size on graph + (automatically enforces the ^nowt^ option) +^nowt^ prevents display of study weight on graph +^nostats^ prevents display of study statistics on graph +^counts^ displays data counts (n/N) for each group when using + binary data + +^group1()^, ^group2()^ can be used with the counts option: the text should + contain the names of the two groups. + +^xlabel()^ defines x-axis labels +^xtick()^ adds tick marks to the x-axis + +^force()^ forces the x-axis scale to be in the range specified + by ^xlabel()^ + +^t1title(..)^, ^t2title(..)^, ^b1title(..)^, ^b2title(..)^ + adds titles to graph in the usual manner, but ^b1title(..)^ has an added + feature. If the text starts with "*I:" and contains an asterisk, metan7 + interprets this as meaning the label declares something about the effect + sizes. For example, + + . ^metan7^ [varlist] ^, b1title(*I:^Favours treatment ^*^ Favours control^)^ + + displays a legend under the graph denoting that studies with effect sizes + to the left of the graph (eg below odds ratios of less than 1) denote a + beneficial treatment, whilst those finding effects to the right indicate + a negative treatment effect. + +^boxsha()^ controls box shading intensity, between 0 and 4. The default + is 4, which produces a filled box +^boxsca()^ controls box scaling, which by default is 1 +^nobox^ prevents a "weighted box" being drawn for each study, instead + displaying effect sizes as identically sized circles +^texts()^ specifies font size for text display on graph. The default + size is 1 + +^saving(^filename^)^ saves the forest plot to the specified file + +Note that for graphs on the log scale (that is, ORs or RRs), values +outside the range [10e-8,10e8] are not displayed. A confidence interval +which extends beyond this will have an arrow added at the end of the range; +should the effect size and confidence interval be completely off this +scale, they will be represented as a single (triangle-shaped) arrow. + +By default, ^metan7^ adds the following new variables to the data set: + + ^_ES^ Effect size (ES) + ^_seES^ Standard error of ES + or, when OR or RR are specfied: + ^_selogES^ the standard error of its logarithm + ^_LCI^ Lower confidence limit for ES + ^_UCI^ Upper confidence limit for ES + ^_WT^ Study percentage weight + ^_SS^ Study sample size + + +Options for ^funnel^ +------------------ + +If the ^funnel^ command is invoked following ^metan7^ with no parameters +specified it will produce a standard funnel plot of precision (1/SE) +against treatment effect. Addition of the ^noinvert^ option will produce +a plot of standard error against treatment effect. The alternative +sample size version of the funnel plot can be obtained by using the +^sample^ option (this automatically selects the ^noinvert^ option). +Alternative plots can be created by specifying ^precision_var^ and +^effect_size^. If the effect size is a relative risk or odds ratio, +the ^xlog^ option should be used to create a symmetrical plot. + + +All options for graph are valid. Additionally, + +^sample^ denotes that the y-axis is the sample size and not a + standard error +^noinvert^ prevents the values of the precision variable from being + inverted +^ysqrt^ represent y-axis on square root scale +^overall(^x^)^ draws a dashed vertical line at overall effect size given by x + + +Options for ^labbe^ +----------------- + +By default the size of the plotting symbol is proportional to the sample +size of the study. If weight is specified the plotting size will be +proportional to the weight variable. +All options for graph are valid. Additionally, the following options may +be used + +^nowt^ declares that the plotted data points are to be the same size +^percent^ display the event rates as percentages rather than proportions + +^null^ draws a line corresponding to a null effect (ie p1=p2) +^or(^x1^)^ draws a line corresponding to a fixed odds ratio of x1 +^rd(^x2^)^ draws a line corresponding to a fixed risk difference of x2 +^rr(^x3^)^ draws a line corresponding to a fixed risk ratio + (for the event) of x3 +^rrn(^x4^)^ draws a line corresponding to a fixed risk ratio + (for the non-event) of x4 + +The latter two may require explanation: whereas the OR and RD are +invariant to the definition of which of the binary outcomes is the "event" +and which is the "non-event", the RR is not. That is, whilst the command +^metan7 a b c d , or^ gives the same result as ^metan7 b a d c , or^ +(with direction changed), an RR analysis does not. The L'Abbe plot allows +the display of either or both be superimposed + +^logit^ is for use when the ^or()^ option has been used; it displays the + probabilities on the logit scale ie log(p/1-p). On the logit scale the + odds ratio is a linear effect, and so this makes it easier to assess the + "fit" of the line. + +One note of caution: depending on the size of the studies, you may need to +rescale the graph (by means of the ^psize()^ option) + +Examples +-------- + + . ^metan7 tdeath tnodeath cdeath cnodeath, or chi2 label(namevar=trialid)^ + . ^metan7 tdeath tnodeath cdeath cnodeath, rd random^ + . ^metan7 tdeath tnodeath cdeath cnodeath, olevel(99) ilevel(95)^ /* + /* ^sortby(year) label(namevar=trialid, yearid=year) nostats nowt^ + + . ^metan7 n1 mean1 sd1 n2 mean2 sd2, by(trialtype)^ /* + */ ^b1(*I:Treatment reduces blood pressure * Treatment increases blood pressure)^ + + . ^gen logor = (a*d)/(b*c)^ + . ^gen selogor = sqrt( (1/a) + (1/b) + (1/c) + (1/d) )^ + . ^metan7 logor selogor , eform effect(Odds ratio) ^ + + . ^metan7 percentlowerci upperci , wgt(n_positives) b1(Sensitivity)^ /* + */ ^xlabel(0,20,40,60,80,100) nooverall^ + + + . ^local ovratio=r(ES)^ + . ^funnel , sample ysqrt xlabel(0.1,0.5,1,5,10) ylabel(0,500,1000)^ /* + */ ^overall(`ovratio')^ + . ^funnel or selogor, xlabel(0.1,0.5,1,5,10) ylabel(0,0.05,0.1) xlog^ + + . ^labbe tdeath tnodeath cdeath cnodeath, xlabel(0,0.25,0.5,0.75,1)^ /* + */ ^ylabel(0,0.25,0.5,0.75,1) rr(0.91) rd(-0.021) ^ + + . ^metan7 n1 m1 sd1 n2 m2 sd2, nostandard^ + . ^metan7 n1 m1 sd1 n2 m2 sd2, random xla(-2,-1,0,1,2) force saving(metagrph)^ + + + + +Authors +------- + + Michael J Bradburn, Jonathan J Deeks, Douglas G Altman. + Centre for Statistics in Medicine, University of Oxford, + Old Road Campus, Headington, Oxford OX3 7LF, UK. + + email mike.bradburn@@cancer.org.uk + + +References +---------- + +Higgins JPT, Thompson SG (2002) Quantifying heterogeneity in a meta-analysis. +Statistics in Medicine 21:1539-1558 + + +Also see +-------- + + STB: STB-44 sbe24 +On-line: help for @meta@ (if installed), @metacum@ (if installed), + @metareg@ (if installed), @metabias@ (if installed), + @metatrim@ (if installed), @metainf@ (if installed), + @galbr@ (if installed) + diff --git a/Modules/ado/plus/m/metan_examples.ado b/Modules/ado/plus/m/metan_examples.ado new file mode 100644 index 0000000..2c1c4f2 --- /dev/null +++ b/Modules/ado/plus/m/metan_examples.ado @@ -0,0 +1,191 @@ +program metan_examples + version 9.0 + `1' +end + +program define metan_example_basic + preserve + di "" + use http://fmwww.bc.edu/repec/bocode/m/metan_example_data.dta, clear + di in wh "" + di ". metan tdeath tnodeath cdeath cnodeath, rd random" + di "> label(namevar=id, yearid=year) counts" + + metan tdeath tnodeath cdeath cnodeath, rd random /// + label(namevar=id, yearid=year) counts + restore +end + +program define metan_example_cols + preserve + di "" + use http://fmwww.bc.edu/repec/bocode/m/metan_example_data.dta, clear + di in wh "" + di ". metan tdeath tnodeath cdeath cnodeath," + di "> sortby(year) lcols(id year country) rcols(population)" + di "> textsize(110) astext(60) double nostats nowt nohet notable" + + metan tdeath tnodeath cdeath cnodeath, /// + sortby(year) lcols(id year country) rcols(population) /// + textsize(110) astext(60) double nostats nowt nohet notable + restore +end + +program define metan_example_by + preserve + di "" + use http://fmwww.bc.edu/repec/bocode/m/metan_example_data.dta, clear + di in whi "" + di ". metan tsample tmean tsd csample cmean csd," + di "> by(type_study) sgweight fixed second(random)" + di "> rfdist counts label(namevar = id)" + di "> favours(Treatment reduces blood pressure # Treatment increases blood pressure)" + + metan tsample tmean tsd csample cmean csd, /// + by(type_study) sgweight fixed second(random) /// + rfdist counts label(namevar = id) /// + favours(Treatment reduces blood pressure # Treatment increases blood pressure) + restore +end + +program metan_example_2param + preserve + di "" + use http://fmwww.bc.edu/repec/bocode/m/metan_example_data.dta, clear + di in whi "" + di "" + di ". gen logor = ln( (tdeath*cnodeath)/(tnodeath*cdeath) ) )" + di "" + di ". gen selogor = sqrt( (1/tdeath) + (1/tnodeath) + (1/cdeath) + (1/cnodeath) )" + di "" + di ". metan logor selogor, eform xlabel(0.5, 1, 1.5, 2, 2.5)" + di "> force xtick(0.75, 1.25, 1.75, 2.25) effect(Odds ratio)" + + gen logor = ln( (tdeath*cnodeath)/(tnodeath*cdeath) ) + gen selogor = sqrt( (1/tdeath) + (1/tnodeath) + (1/cdeath) + (1/cnodeath) ) + metan logor selogor, eform xlabel(0.5, 1, 1.5, 2, 2.5) /// + force xtick(0.75, 1.25, 1.75, 2.25) effect(Odds ratio) + restore +end + +program define metan_example_diag + preserve + di "" + use http://fmwww.bc.edu/repec/bocode/m/metan_example_data.dta, clear + di in whi "" + di ". metan percent lowerci upperci, wgt(n_positives)" + di "> xlabel(0,10,20,30,40,50,60,70,80,90,100) force" + di "> null(50) label(namevar=id) nooverall notable" + di "> title(Sensitivity, position(6))" + di in gr "" + + metan percent lowerci upperci, wgt(n_positives) /// + xlabel(0,10,20,30,40,50,60,70,80,90,100) force /// + null(50) label(namevar=id) nooverall notable /// + title(Sensitivity, position(6)) + restore +end + +program define metan_example_user + preserve + di "" + use http://fmwww.bc.edu/repec/bocode/m/metan_example_data.dta, clear + di in whi "" + di ". metan OR ORlci ORuci, wgt(bweight)" + di "> first(0.924 0.753 1.095 Bayesian)" + di "> firststats(param V=3.86, p=0.012)" + di "> label(namevar=id)" + di "> xlabel(0.25, 0.5, 1, 2, 4) force" + di "> null(1) aspect(1.2) scheme(economist)" + + metan OR ORlci ORuci, wgt(bweight) /// + first(0.924 0.753 1.095 Bayesian) /// + firststats(param V=3.86, p=0.012) /// + label(namevar=id) /// + xlabel(0.25, 0.5, 1, 2, 4) force /// + null(1) aspect(1.2) scheme(economist) + restore +end + +program define metan_example_custom + preserve + di "" + use http://fmwww.bc.edu/repec/bocode/m/metan_example_data.dta, clear + di in whi "" + di "" + di `". gen counts = ". " + string(tdeath) + "/" + string(tdeath+tnodeath)"' + di `"> + ", " + string(cdeath) + "/" + string(cdeath+cnodeath)"' + di "" + di ". metan tdeath tnodeath cdeath cnodeath," + di "> lcols(id year) notable" + di "> boxopt( mcolor(forest_green) msymbol(triangle) )" + di "> pointopt( msymbol(triangle) mcolor(gold) msize(tiny)" + di "> mlabel(counts) mlabsize(vsmall) mlabcolor(forest_green) mlabposition(1) )" + di "> ciopt( lcolor(sienna) lwidth(medium) )" + + gen counts = ". " + string(tdeath) + "/" + string(tdeath+tnodeath) /// + + ", " + string(cdeath) + "/" + string(cdeath+cnodeath) + metan tdeath tnodeath cdeath cnodeath, /// + lcols(id year) notable /// + boxopt( mcolor(forest_green) msymbol(triangle) ) /// + pointopt( msymbol(triangle) mcolor(gold) msize(tiny) /// + mlabel(counts) mlabsize(vsmall) mlabcolor(forest_green) mlabposition(1) ) /// + ciopt( lcolor(sienna) lwidth(medium) ) + restore +end + +program define funnel_example_immed + preserve + di "" + use http://fmwww.bc.edu/repec/bocode/m/metan_example_data.dta, clear + di in whi "" + di ". metan tdeath tnodeath cdeath cnodeath, nograph notable" + di "" + di ". local ovratio=r(ES)" + di "" + di ". funnel, sample ysqrt xlabel(0.1,0.5,1,5,10)" + di "> ylabel(0,500,1000) overall(`ovratio')" + + metan tdeath tnodeath cdeath cnodeath, nograph notable + local ovratio=r(ES) + funnel, sample ysqrt xlabel(0.1,0.5,1,5,10) /// + ylabel(0,500,1000) overall(`ovratio') + restore +end + +program define funnel_example_param + preserve + di "" + use http://fmwww.bc.edu/repec/bocode/m/metan_example_data.dta, clear + di in whi "" + di ". gen logor = ln( (tdeath*cnodeath)/(tnodeath*cdeath) ) )" + di "" + di ". gen selogor = sqrt( (1/tdeath) + (1/tnodeath) + (1/cdeath) + (1/cnodeath) )" + di "" + di ". funnel OR selogor, xlabel(0.1,0.5,1,5,10)" + di "> ylabel(0,1,2,3,4,5) xlog" + + gen logor = ln( (tdeath*cnodeath)/(tnodeath*cdeath) ) + gen selogor = sqrt( (1/tdeath) + (1/tnodeath) + (1/cdeath) + (1/cnodeath) ) + funnel OR selogor, xlabel(0.1,0.5,1,5,10) /// + ylabel(0,1,2,3,4,5) xlog + restore +end + +program define labbe_example + preserve + di "" + use http://fmwww.bc.edu/repec/bocode/m/metan_example_data.dta, clear + di in whi "" + di ". labbe tdeath tnodeath cdeath cnodeath," + di "> xlabel(0,0.25,0.5,0.75,1) ylabel(0,0.25,0.5,0.75,1)" + di "> rr(1.029) rd(0.014) null" + + labbe tdeath tnodeath cdeath cnodeath, /// + xlabel(0,0.25,0.5,0.75,1) ylabel(0,0.25,0.5,0.75,1) /// + rr(1.029) rd(0.014) null + restore +end + + + diff --git a/Modules/ado/plus/m/metaninf.ado b/Modules/ado/plus/m/metaninf.ado new file mode 100644 index 0000000..e41ca34 --- /dev/null +++ b/Modules/ado/plus/m/metaninf.ado @@ -0,0 +1,166 @@ +*! 1.0.2 TJS 29 Feb 2004 Saves jackknived estimates +* 1.0.1 TJS 20 Jul 2001 +* 1.0.0 TJS 22 May 2001 +*! based on: metainf 3.0.0 AT Mar 2000 (STB-56: sbe26.1) + +program define metaninf + version 6.0 + syntax varlist(min=2 max=6 numeric) [if] [in] [, id(varname) noGRAPH /* + */ LABEL(string) SAVe(string) t1(str) t2(str) Format(str) noTABLE `options' *] + tokenize `varlist' + +* preserve + + local est = "`1'" + + if "`label'" != "" { + parse "`label'", parse("=,") + while "`1'" != "" { + cap confirm var `3' + if _rc != 0 { + di in re "Variable `3' not defined" + exit _rc + } + local `1' "`3'" + mac shift 4 + } + } + tempvar code + qui { + if "`namevar'" != "" { + local lbnvl : value label `namevar' + if "`lbnvl'" != "" { quietly decode `namevar', gen(`code') } + else { + gen str10 `code' = "" + cap confirm string variable `namevar' + if _rc == 0 { replace `code' = `namevar' } + else if _rc == 7 { replace `code' = string(`namevar') } + } + } + else { gen str3 `code' = string(_n) } + if "`yearvar'" != "" { + local yearvar "`yearvar'" + cap confirm string variable `yearvar' + if _rc == 7 { local str "string" } + if "`namevar'" == "" { replace `code' = `str'(`yearvar') } + else { replace `code' = `code' + " (" + `str'(`yearvar') + ")" } + } + } + local id "`code'" + + preserve + + +* Dealing with if and in options + if ("`if'" != "") { qui keep `if' } + if ("`in'" != "") { qui keep `in' } + if _N <= 1 { error 2001 } + +* Overall estimates + tempvar so + qui gen `so' = _n + qui metan `varlist', nograph `options' + local ove = $S_1 + local ll = $S_3 + local ul = $S_4 + sort `so' + +* Meta-analysis estimate omiting one study each step + tempvar theta setheta ulth llth + qui sum `1', detail + local n = _result(1) + qui { + gen `theta' = . + gen `setheta' = . + gen `ulth' = . + gen `llth' = . + label var `theta' "Estimate" + label var `llth' "Lower CI Limit" + label var `ulth' "Upper CI Limit" + } + + local i = 1 + tempvar s + qui gen `s' = _n + while (`i' <= `n') { + qui { + metan `varlist' if `s' != `i', `options' nograph + sort `so' + replace `theta' = $S_1 in `i' + replace `llth' = $S_3 in `i' + replace `ulth' = $S_4 in `i' + } + local i = `i' + 1 + } + +* Maximum and minimum CI values + qui sum `llth', detail + local mnx = r(min) + qui sum `ulth', detail + local mxx = r(max) + +* Labeling plot + if "`t2'" == "" { local t2 `""' } + if "`t1'" == "" { local t1 "Meta-analysis estimates, given named study is omitted" } + +* Numeric format + if "`format'" == "" { local format "%5.2f" } + +* Print option + if "`table'" != "notable" { + di + di in gr "------------------------------------------------------------------------------" + di in gr _col(2) "Study omitted" _col(20) "|" _col(24) "Estimate" _col(39) "[95% Conf. Interval]" + di in gr "-------------------+----------------------------------------------------------" + local i = 1 + while `i' <= `n' { + if "`id'" == "" { local a = `s' in `i' } + else { local a = `id' in `i' } + local b = `theta' in `i' + local c = `llth' in `i' + local d = `ulth' in `i' + di _col(2) "`a'" _col(20) in gr "|" in ye _col(24) `b' _col(39) `c' _col(52) `d' + local i=`i'+1 + } + di in gr "-------------------+----------------------------------------------------------" + di _col(2) "Combined" _col(20) in gr "|" in ye _col(24) `ove' _col(39) `ll' _col(52) `ul' + di in gr "------------------------------------------------------------------------------" + } + +* Display plot + if "`graph'" != "nograph" { + mhplot `llth' `theta' `ulth', r sy(|o|) l("`id'") t1(`t1') t2(`t2') /* + */ f(`format') xline(`ove',`ll',`ul') xlab(`mnx',`ove',`ll',`ul',`mxx') /* + */ xti(`ove',`ll',`ul') xscale(`mnx',`mxx') + } + +if "`save'" != "" { + local c = index("`save'",",") + if `c' != 0 { + local save = substr("`save'",1,`c'-1) + " " + substr("`save'",`c'+1, .) + } + local save1 : word 1 of `save' + local replace : word 2 of `save' + if "`replace'" == "replace" { + capture drop `save1' + } + capture confirm new var `save1' + if _rc { + local rc = _rc + di in re "`save1' exists. Use 'replace' option: save(save_var, replace)." + exit `rc' + } + qui { + gen `save1' = `theta' + sort `id' + tempfile saved + save `saved' + restore + sort `id' + merge `id' using `saved', keep(`save1') update replace nokeep + drop if _merge==2 + drop _merge + } + label var `save1' "jackknifed `est' (metaninf)" + +end diff --git a/Modules/ado/plus/m/metaninf.dlg b/Modules/ado/plus/m/metaninf.dlg new file mode 100644 index 0000000..2cfb092 --- /dev/null +++ b/Modules/ado/plus/m/metaninf.dlg @@ -0,0 +1,377 @@ +/* + +*! metaninf dialog version 1.0.2, 29 Feb 2004, T. J. Steichen, steichen@triad.rr.com +*! for metaninf version 1.0.2, 29 Feb 2004, T. J. Steichen, steichen@triad.rr.com + +Influence of a single study in meta-analysis estimation +------------------------------------------------------- + +Syntax: metaninf varlist [if exp] [in range] [, fixed fixedi random randomi + rr or rd peto cornfield hedges cohen glass nostandard + label(namevar=namevar[, yearvar=yearvar]) + ilevel(#) olevel(#) notable nograph save(varname [, replace]) ] + +Install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "metan&inf (Metan-based Influence Analysis)" "db metaninf" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. +*/ + +VERSION 8.0 + +INCLUDE _std_small +INCLUDE _ht240 +INCLUDE header + +HELP hlp1, view("help metaninf") +RESET res1, label("Reset") + +DIALOG main, label("metaninf 1.0.2 - Metan-based Influence Analysis") tabtitle("Main") +BEGIN + GROUPBOX gb_data 10 5 330 _ht1h, /// + label("Type of Data:") + RADIO r_binary 15 25 100 ., /// + label("Binary Count") first /// + onclickon(script main_binary_on) /// + onclickoff(script main_binary_off) + RADIO r_continuous 125 25 100 ., /// + label("Continuous") middle /// + onclickon(script main_continuous_on) /// + onclickoff(script main_continuous_off) + RADIO r_effect 235 25 100 ., /// + label("Effect Size") last /// + onclickon(script main_effect_on) /// + onclickoff(script main_effect_off) + + TEXT tx_binary 10 50 _iwd ., /// + label("Vars for Counts a, b, c, d, in that order") + VARLIST vl_binary @ _ss @ ., /// + label("Vars for a, b, c, d") + + TEXT tx_contin_exp @ 50 _iwd ., /// + label("Vars for Experimental Group: n, mean, sd, in that order") + VARLIST vl_contin_exp @ _ss @ ., /// + label("Experimental Group: n, mean, sd") + TEXT tx_contin_ctl @ _ss _iwd ., /// + label("Vars for Control Group: n, mean, sd, in that order") + VARLIST vl_contin_ctl @ _ss @ ., /// + label("Control Group: n, mean, sd") + + TEXT tx_effect @ 50 _iwd ., /// + label("Vars for Effect Sizes: theta, se(theta), in that order") + VARLIST vl_effect @ _ss @ ., /// + label("Effect Sizes: theta, se(theta)") + + GROUPBOX gb_labels 10 130 330 _ht3h, /// + label("Labels for Data:") + CHECKBOX cb_name 20 150 70 ., /// + label("Name:") /// + onclickon(main.vn_name.enable) /// + onclickoff(main.vn_name.disable) /// + option("id") + VARNAME vn_name 100 150 230 ., /// + label("Name Variable") + CHECKBOX cb_year 20 170 70 ., /// + label("Year:") /// + onclickon(main.vn_year.enable) /// + onclickoff(main.vn_year.disable) /// + option("id") + VARNAME vn_year 100 170 230 ., /// + label("Year Variable") + + CHECKBOX cb_save_jk 10 200 330 ., /// + label("Save jack-knived estimates: varname [, replace]") /// + onclickon(main.vn_save_jk.enable) /// + onclickoff(main.vn_save_jk.disable) + VARNAME vn_save_jk 10 220 330 ., /// + label("Save estimates Variable") /// + option("save") + +END + +DIALOG metan_b, tabtitle("Binary Opts") +BEGIN + GROUPBOX gb_pool 0 10 210 _ht9h, /// + label("Pooling Model") + RADIO r_fixed 10 30 190 ., /// + label("Fixed, Mantel Haenzel") first /// + option("fixed") + RADIO r_fixedi @ _ss @ ., /// + label("Fixed, Inverse Variance") middle /// + option("fixedi") + RADIO r_random @ _ss @ ., /// + label("Random, Mantel Haenzel") middle /// + option("random") + RADIO r_randomi @ _ss @ ., /// + label("Random, Inverse Variance") middle /// + option("randomi") + RADIO r_peto @ _ss @ ., /// + label("Peto") last /// + option("peto") + + GROUPBOX gb_stat 220 10 120 _ht5h, /// + label("Statistic") + RADIO r_rr 230 30 80 ., /// + label("RR") first /// + option("rr") + RADIO r_or @ _ss @ ., /// + label("OR") middle /// + onclickon(script metan_b_or_on) /// + onclickoff(script metan_b_or_off) /// + option("or") + RADIO r_rd @ _ss @ ., /// + label("RD") last /// + option("rd") + + CHECKBOX cb_cornfield 10 140 200 ., /// + label("Use Cornfield CI's") /// + option("cornfield") + CHECKBOX cb_chi2 10 160 200 ., /// + label("Use Chi-2 Statistic") /// + option("chi2") + CHECKBOX cb_breslow 10 180 200 ., /// + label("Use Breslow-Day test") /// + option("breslow") + + CHECKBOX cb_notable 230 140 200 ., /// + label("noTable") /// + option("notable") + CHECKBOX cb_nograph 230 160 200 ., /// + label("noGraph") /// + option("nograph") +END + +DIALOG metan_c, tabtitle("Contin. Opts") +BEGIN + GROUPBOX gb_pool 0 10 210 _ht3h, /// + label("Pooling Model") + RADIO r_fixed 10 30 190 ., /// + label("Fixed, Inverse Variance") first /// + option("fixed") + RADIO r_random @ _ss @ ., /// + label("Random, Inverse Variance") last /// + option("random") + + GROUPBOX gb_stat 220 10 120 _ht7h, /// + label("Statistic") + RADIO r_cohen 230 30 100 ., /// + label("Cohen") first /// + option("cohen") + RADIO r_hedges @ _ss @ ., /// + label("Hedges") middle /// + option("hedges") + RADIO r_glass @ _ss @ ., /// + label("Glass") middle /// + option("glass") + RADIO r_nostandard @ _ss @ ., /// + label("noStandard") last /// + option("nostandard") + + CHECKBOX cb_notable 230 140 200 ., /// + label("noTable") /// + option("notable") + CHECKBOX cb_nograph 230 160 200 ., /// + label("noGraph") /// + option("nograph") +END + +DIALOG metan_e, tabtitle("Effect Opts") +BEGIN + GROUPBOX gb_pool 0 10 210 _ht3h, /// + label("Pooling Model") + RADIO r_fixed 10 30 190 ., /// + label("Fixed, Inverse Variance") first /// + option("fixed") + RADIO r_random @ _ss @ ., /// + label("Random, Inverse Variance") last /// + option("random") +/* + GROUPBOX gb_stat 220 10 120 _ht5h, /// + label("Statistic") + RADIO r_rr 230 30 80 ., /// + label("RR") first /// + option("rr") + RADIO r_or @ _ss @ ., /// + label("OR") middle /// + option("or") + RADIO r_rd @ _ss @ ., /// + label("RD") last /// + option("rd") +*/ + + CHECKBOX cb_notable 230 140 200 ., /// + label("noTable") /// + option("notable") + CHECKBOX cb_nograph 230 160 200 ., /// + label("noGraph") /// + option("nograph") +END + +INCLUDE ifin + +SCRIPT main_binary_on +BEGIN + main.tx_binary.show + main.vl_binary.show + main.tx_binary.enable + main.vl_binary.enable + + main.tx_effect.disable + main.vl_effect.disable + main.tx_effect.hide + main.vl_effect.hide + + main.tx_contin_exp.disable + main.vl_contin_exp.disable + main.tx_contin_exp.hide + main.vl_contin_exp.hide + + main.tx_contin_ctl.disable + main.vl_contin_ctl.disable + main.tx_contin_ctl.hide + main.vl_contin_ctl.hide + +END + +SCRIPT main_binary_off +BEGIN + main.tx_binary.disable + main.vl_binary.disable + main.tx_binary.hide + main.vl_binary.hide +END + +SCRIPT main_continuous_on +BEGIN + main.tx_contin_exp.show + main.vl_contin_exp.show + main.tx_contin_exp.enable + main.vl_contin_exp.enable + + main.tx_contin_ctl.show + main.vl_contin_ctl.show + main.tx_contin_ctl.enable + main.vl_contin_ctl.enable + + main.tx_binary.disable + main.vl_binary.disable + main.tx_binary.hide + main.vl_binary.hide + + main.tx_effect.disable + main.vl_effect.disable + main.tx_effect.hide + main.vl_effect.hide +END + +SCRIPT main_continuous_off +BEGIN + main.tx_contin_exp.disable + main.vl_contin_exp.disable + main.tx_contin_exp.hide + main.vl_contin_exp.hide + + main.tx_contin_ctl.disable + main.vl_contin_ctl.disable + main.tx_contin_ctl.hide + main.vl_contin_ctl.hide +END + +SCRIPT main_effect_on +BEGIN + main.tx_effect.show + main.vl_effect.show + main.tx_effect.enable + main.vl_effect.enable + + main.tx_binary.disable + main.vl_binary.disable + main.tx_binary.hide + main.vl_binary.hide + + main.tx_contin_exp.disable + main.vl_contin_exp.disable + main.tx_contin_exp.hide + main.vl_contin_exp.hide + + main.tx_contin_ctl.disable + main.vl_contin_ctl.disable + main.tx_contin_ctl.hide + main.vl_contin_ctl.hide +END + +SCRIPT main_effect_off +BEGIN + main.tx_effect.disable + main.vl_effect.disable + main.tx_effect.hide + main.vl_effect.hide +END + +SCRIPT metan_b_or_on +BEGIN + metan_b.r_peto.enable + metan_b.cb_cornfield.enable + metan_b.cb_chi2.enable + metan_b.cb_breslow.enable +END + +SCRIPT metan_b_or_off +BEGIN + metan_b.r_peto.disable + metan_b.cb_cornfield.disable + metan_b.cb_chi2.disable + metan_b.cb_breslow.disable +END + +PROGRAM command +BEGIN + put "metaninf " + if main.r_binary { + varlist main.vl_binary + } + if main.r_continuous { + varlist main.vl_contin_exp main.vl_contin_ctl + } + if main.r_effect { + varlist main.vl_effect + } + INCLUDE _ifin_pr + beginoptions + if main.cb_name | main.cb_year { + put "label(" + if main.cb_name { + put "namevar=" main.vn_name + } + if main.cb_name & main.cb_year { + put ", " + } + if main.cb_year { + put "yearvar=" main.vn_year + } + put ") " + } + if main.r_binary { + option radio(metan_b r_fixed r_fixedi r_random r_randomi) + option radio(metan_b r_rr r_or r_rd) + option metan_b.cb_cornfield + option metan_b.cb_chi2 + option metan_b.cb_breslow + option metan_b.cb_nograph + option metan_b.cb_notable + } + if main.r_continuous { + option radio(metan_c r_fixed r_random) + option radio(metan_c r_cohen r_hedges r_glass r_nostandard) + option metan_c.cb_nograph + option metan_c.cb_notable + } + if main.r_effect { + option radio(metan_e r_fixed r_random) +/* option radio(metan_e r_rr r_or r_rd) */ + option metan_e.cb_nograph + option metan_e.cb_notable + } + optionarg main.vn_save_jk + endoptions +END diff --git a/Modules/ado/plus/m/metaninf.hlp b/Modules/ado/plus/m/metaninf.hlp new file mode 100644 index 0000000..169c3c0 --- /dev/null +++ b/Modules/ado/plus/m/metaninf.hlp @@ -0,0 +1,174 @@ +.- +help for ^metaninf^ version 1.0.2 +.- + +Influence of a single study in meta-analysis estimation +------------------------------------------------------- + + ^metaninf^ varlist [^if^ exp] [^in^ range] [, ^fixed fixedi random randomi^ + ^rr or rd peto cornfield hedges cohen glass nosta^ndard + ^label(^label_vars^) il^evel^(^#^) ol^evel^(^#^) notable nograph^ + ^sav^e^(^varname [^, replace^]^)^ ] + + +Description +----------- + +^metaninf^ investigates the influence of each individual study on the overall +meta-analysis summary estimate. The command presents a table and a graph of +the results of an influence analysis in which the meta-analysis is reestimated +omitting each study in turn. + +The table numerically provides the results, with the rows of the table being +the meta-analysis of all studies except the "omitted" study named in that row, +and the usual, full meta-analysis (omitting none of the studies) being given +as the "combined" results at the bottom of the table. + +The graph visually provides the same results in a plot, naming the omitted +study on the left margin and presenting the resulting "omitted" meta-analytic +summary statistics as a horizontal confidence interval. The full, "combined" +results are shown as the solid vertical lines. + +No formal test of influence is given; rather, the program provides and displays +results to which some general guidelines can be applied to assess influence. +One such guideline is that an individual study is suspected of excessive +influence if the point estimate of its "omitted" analysis lies outside the +confidence interval of the "combined" analysis. Another quideline is that a +study is excessively influential if its "omitted" meta-analytic estimate +differs in significance relative to the "combined" analysis. Neither of these +quidelines provides definitive proof that such a study should, or should not, +be removed from the analysis; they merely provide a suggestion that some +attention be paid to potential reasons for its influence. + +^metaninf^ uses program ^metan^ as its meta-analysis engine and its options are +a direct subset of ^metan^'s. It is expected that users will merely edit a ^metan^ +command line by adding the "inf" suffix to the program name to run ^metaninf^. + +Like ^metan^, ^metaninf^ requires either four or six variables to be declared. +When four variables are specified, analysis of binary data is performed. +When six variables are specified, the data are assumed continuous. + +Binary data is presented as the 4 cell counts (a b c d) of a 2x2 table where +a and b are the number of event & no-event subjects in the intervention group +and c and d are similar numbers for the control group. + + . ^metaninf a b c d^ + +Continuous data is presented as 6 values: the n, mean and sd for the treatment +(or intervention) group followed by similar values for the control group. + + . ^metaninf nt mt sdt nc mc sdc^ + + +Options +------- + +Scaling and pooling options +--------------------------- + +Options for binary data + + ^rr^ pools risk ratios (the default). + + ^or^ pools odds ratios. + + ^rd^ pools risk differences. + + ^fixed^ specifies a fixed effect model using the method of Mantel & Haenszel + (the default). + + ^fixedi^ specifies a fixed effect model using the inverse variance method. + + ^peto^ specifies that Peto's assumption free method is used to pool odds + ratios. + + ^random^ specifies a random effects model using the method of DerSimonian & + Laird, with the estimate of heterogeneity being taken from the + Mantel-Haenszel model. + + ^randomi^ specifies a random effects model using the method of DerSimonian & + Laird, with the estimate of heterogeneity being taken from the inverse + variance fixed effect model. + + ^cornfield^ computes confidence intervals for odds ratios by the method of + Cornfield, rather than the (default) Woolf method. + + +Options for continuous data + + ^cohen^ pools standardized mean differences by the method of Cohen + (the default). + + ^hedges^ pools standardized mean differences by the method of Hedges. + + ^glass^ pools standardized mean differences by the method of Glass. + + ^nostandard^ pools unstandardized mean differences. + + ^fixed^ specifies a fixed effect model using the inverse variance method + (the default). + + ^random^ specifies a random effects model using the DerSimonian & Laird + method. + + +General output options +---------------------- + + ^label(^[^namevar^=namevar] [^, yearvar^=yearvar]^)^ + labels the data by its name, year or both. However, neither option + is required. For the table display the overall length of the label is + restricted to 16 characters. + + ^ilevel()^ specifies the significance level (eg 90,95,99) for the + individual trial confidence intervals. + + ^olevel()^ specifies the significance level (eg 90,95,99) for the + overall (pooled) confidence intervals. + + ^ilevel^ and ^olevel^ need not be the same, and by default are equal + to the significance level specified using the ^set level^ command. + + ^notable^ prevents display of the table of results. + + ^nograph^ prevents display of the graph. + + ^save(^varname [^, replace^]^)^ saves the jackknifed estimates. + + +Note +---- + +To run ^metaninf^, the ^metan^ command [STB-44: sbe24] must be installed. + + +Acknowledgements +---------------- + +^metaninf^ is a direct rip-off of ^metainf^ (by Aurelio Tobias; see STB-47: sbe26; +STB-56: sbe26.1). It blatently uses ^metan^ (by Michael J Bradburn, Jonathan J +Deeks and Douglas G Altman; see STB-44: sbe24) as its meta-analysis calculation +engine and ^mhplot^, a slight variation of ^hplot^ (by Nicolas Cox), as its +graphic engine. The current author is indebted to the above authors for all +their hard work, thus allowing this program to be written with no apparent +personal intellectual input. Thanks guys! + + +Examples +-------- + + . ^metaninf a b c d, fixedi or label(namevar=studyid, yearvar=year)^ + . ^metaninf nt mt sdt nc mc sdc, cohen notable^ + + +Author +------ + + Thomas J Steichen, steichen@triad.rr.com + + +Also see +-------- + +On-line: help for @metan@, and if installed: @metainf@, @meta@, @metareg@, @metacum@, + @metabias@, @metatrim@, @metap@, @galbr@, @funnel@, @labbe@, and @hplot@. diff --git a/Modules/ado/plus/m/metannt.ado b/Modules/ado/plus/m/metannt.ado new file mode 100644 index 0000000..67ae5ca --- /dev/null +++ b/Modules/ado/plus/m/metannt.ado @@ -0,0 +1,160 @@ +*!version 1.0 MJB 9 May 2003 + +cap program drop metannt +program define metannt , rclass + version 7.0 + syntax [, measure(string) size(string) confint(string) baseline(string)] +*If measure size & confint left unspecified, assume that these are as stored +*from previous metan/meta-analysis in r(ES) etc + +if "`measure'`size'`confint'"=="" { +*Get effect size, conf intervals and type of summary measure from metan + local measure = r(measure) + local size = r(ES) + local conf_l= r(ci_low) + local conf_u= r(ci_upp) + } + else { +*otherwise, user is assumed to have specified them: conf interval needs parsing (and is optional) + local measure=upper("`measure'") + if "`confint'"!="" { + tokenize "`confint'", parse(",") + local conf_l=`1' + local conf_u=`3' + } +} + +cap { + if ("`measure'"=="SMD" | "`measure'"=="WMD" | "`measure'"=="ES") + di in re "metannt valid only after binary data meta-analysis" + exit +} +cap { + assert ("`measure'"=="OR" | "`measure'"=="RR" | "`measure'"=="RD") + assert `size'>-1 + assert `size'>0 if ("`measure'"=="OR" |"`measure'"=="RR") + assert `size'<1 if "`measure'"=="RD" + assert `size'!=. +} +if _rc!=0 { + di in re "Specify a valid measure AND effect size using measure( ) and size( ) options," + di in re " or use last estimates from metan" + exit +} + +if "`conf_l'"!="" { + cap { + assert `conf_l'>=-1 + assert `conf_l'>0 if "`measure'"!="RD" + assert `conf_u'<=1 if "`measure'"=="RD" + assert `size'>`conf_l' + assert `size'<`conf_u' + } + if _rc!=0 { + di in re "Invalid confidence interval" + exit + } +} +if "`baseline'"=="" { + local baseline =r(cger) + local note2 "**" /* to reinforce estimation of CGER from data */ +} + +if ( (`size'>0 & "`measure'"=="RD") | (`size'>1 & "`measure'"!="RD") ) { + local directn "excess" + local nntstub "H" + } + else { + local directn "avoided" + local nntstub "B" +} +if "`conf_l'"!="" { + local ci "(CI)" + local cont "_cont" +} +di _n in gr " Control group | Treatment group |" _col(43) "| No. of `directn' " +di in gr " event rate | event rate *" _col(34) "| NNT`nntstub'* | events per 1000 `ci'*" +di in gr _dup(15) "-" "+" _dup(17) "-" "+" _dup(8) "-" "+" _dup(26) "-" + + +*error check +local flag=0 + + +parse "`baseline'", parse(",") +while "`1'"!="" { + local cger=`1' +*calculate tger then NNT / events from d-a + if "`measure'"=="RD" { + local tger=`cger'+`size' + if "`ci'"!="" { + local tger_ll = `cger'+`conf_l' + local tger_ul = `cger'+`conf_u' + } + } + + if "`measure'"=="RR" { + local tger=(`cger'*`size') + if "`ci'"!="" { + local tger_ll =(`cger'*`conf_l') + local tger_ul =(`cger'*`conf_u') + } + } + + if "`measure'"=="OR" { + local tger=(`size'*`cger')/(1-`cger'+`cger'*`size') + if "`ci'"!="" { + local tger_ll =(`conf_l'*`cger')/(1-`cger'+`cger'*`conf_l') + local tger_ul =(`conf_u'*`cger')/(1-`cger'+`cger'*`conf_u') + } + } + if (`tger'>=0 & `tger'<=1 & `cger'>=0 & `cger'<=1) { + + local nnt = abs(1/(`cger'-`tger')) + local np1000=abs(1000*(`cger'-`tger')) + if "`ci'"!="" { +*direction is important for CI + if `cger'>`tger' { +*events avoided: CI goes from (cg-max_tg to cg-min_tg) + local np1k_ll =(1000*(`cger'-`tger_ul')) + local np1k_ul =(1000*(`cger'-`tger_ll')) + } + else { +*events excess: CI goes from (tg_min-cg to tg_max-cg) + local np1k_ll =(1000*(`tger_ll'-`cger')) + local np1k_ul =(1000*(`tger_ul'-`cger')) + } + } + + } + else { + local flag=10 + local nnt =. + local np1000 =. + } + + di in ye _col(5) %6.3f `cger' " `note2'" _col(23) %6.3f `tger' _col(35) %6.1f `nnt' /* +*/ _col(48) %5.1f `np1000' `cont' + + if "`ci'"!="" { + di in ye " (" %5.1f `np1k_ll' " , " %5.1f `np1k_ul' ") + local tger_ll = `cger'+`conf_u' + } + + + + mac shift 2 +} + +if `flag'>1 { di in bl "Note some baseline/event rate combinations are invalid"} +di _n in bl "* based on `measure'=" %5.3f `size' " applied to the control group event rate(s)" +if "`note2'"=="**" { + di in bl "** based on an assumed average control group event rate of `cger'" + +return scalar cger= `cger' +return scalar tger= `tger' +return scalar nnt= `nnt' +return scalar ep1000= `np1000' + +end + diff --git a/Modules/ado/plus/m/metannt.dlg b/Modules/ado/plus/m/metannt.dlg new file mode 100644 index 0000000..6627530 --- /dev/null +++ b/Modules/ado/plus/m/metannt.dlg @@ -0,0 +1,123 @@ +/* + +*! metannt dialog version 1.0.1, 13 May 2003, T. J. Steichen, steichen@triad.rr.com +*! for metannt version 1.0, 9 May 2003, M. J. Bradburn, mike.bradburn@cancer.org.uk + +Metan-based estimates of absolute benefit or risk +------------------------------------------------- + +Syntax: metannt , baseline(#[,#...#]) [ measure(or|rr|rd) size(#) confint(#,#) ] + +To install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "Metan-based NNT (metann&t)" "db metannt" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. + +*/ + +VERSION 8.0 + +INCLUDE _std_small +INCLUDE header + +HELP hlp1, view("help metannt") +RESET res1, label("Reset") + +DIALOG main, label("metannt 1.0 - Metan-based NNT") tabtitle("Main") +BEGIN + TEXT tx_base 10 10 150 ., /// + label("Baseline(s): # , # , ...") + EDIT ed_base 10 30 330 ., /// + label("Baseline value(s)") /// + option("baseline") + + CHECKBOX cb_effect 10 65 310 ., /// + label("Enter Values (default: use metan values)") /// + onclickon(script main_opts_on) /// + onclickoff(script main_opts_off) + + FRAME fr_enter 10 90 330 100 + + GROUPBOX gb_stat 20 95 70 _ht5h, /// + label("Measure") + RADIO r_rr 25 115 50 ., /// + label("RR") first /// + onclickon(script main_rr_on) /// + option("measure(rr)") + RADIO r_or @ _ss @ ., /// + label("OR") middle /// + onclickon(script main_or_on) /// + option("measure(or)") + RADIO r_rd @ _ss @ ., /// + label("RD") last /// + onclickon(script main_rd_on) /// + option("measure(rd)") + + TEXT tx_size 180 115 150 ., /// + label("Effect Size: #") + EDIT ed_size 100 @ 40 ., /// + label("Effect Size") /// + numonly /// + option("size") + + TEXT tx_ci 180 140 150 ., /// + label("Effect Size CI: # , #") + EDIT ed_ci 100 @ 70 ., /// + label("Effect Size CI") /// + option("confint") +END + +SCRIPT main_opts_on +BEGIN + main.gb_stat.enable + main.r_rr.enable + main.r_or.enable + main.r_rd.enable + main.tx_ci.enable + main.ed_ci.enable + main.tx_size.enable + main.ed_size.enable +END + +SCRIPT main_opts_off +BEGIN + main.gb_stat.disable + main.r_rr.disable + main.r_or.disable + main.r_rd.disable + main.tx_ci.disable + main.ed_ci.disable + main.tx_size.disable + main.ed_size.disable +END + +SCRIPT main_rr_on +BEGIN + main.tx_size.setlabel "Effect Size: # > 0" + main.tx_ci.setlabel "Effect Size CI: 0 < # , #" +END + +SCRIPT main_or_on +BEGIN + main.tx_size.setlabel "Effect Size: # > 0" + main.tx_ci.setlabel "Effect Size CI: 0 < # , #" +END + +SCRIPT main_rd_on +BEGIN + main.tx_size.setlabel "Effect Size: -1 < # < 1" + main.tx_ci.setlabel "Effect Size CI: -1 < # < 1" +END + +PROGRAM command +BEGIN + require main.ed_base + require main.ed_size + put "metannt " + beginoptions + option radio(main r_rr r_or r_rd) + optionarg main.ed_base + optionarg main.ed_size + optionarg main.ed_ci + endoptions +END diff --git a/Modules/ado/plus/m/metannt.hlp b/Modules/ado/plus/m/metannt.hlp new file mode 100644 index 0000000..cac0cce --- /dev/null +++ b/Modules/ado/plus/m/metannt.hlp @@ -0,0 +1,86 @@ +.- +help for ^metannt^ +.- + +Estimates of absolute benefit or risk from meta-analysis +-------------------------------------------------------- + + + ^metannt , measure(^or|rr|rd^) size(^#^) confint(^#,#^) baseline(^#[,#...#]^)^ + + +Description +----------- + +This program is intended to aid interpretation of meta-analyses of binary +data by presenting the effect sizes in absolute terms. Both the number +needed to treat (NNT) and the number of events avoided (or added) per +1000 are presented. + +The ^Number Needed to Treat (NNT)^ is the number of individuals required +to experience the intervention in order to expect there to be one +additional event to be observed. Assuming the event is undesireable, this +is termed the "number needed to treat to benefit" (NNTB). If the +intervention arm experiences more events, this is commonly refered to as +the "number needed to treat to harm" (NNTH). + +^metannt^ calculates this by deriving an effect size (e.g. a risk ratio), +applying it to a population with a given event prevalance, and from this +deriving a projected event rate if the population were to receive the +intervention. The NNT is equal to +1/(control group event rate - treatment group event rate). + +The ^number of avoided or excess events (respectively) per 1000 population^ +is the difference between the two event rates multiplied by 1000. The +intervention group event rate is calculated in the same manner as with +the NNT. Optionally a confidence interval is also presented, using the +confidence limits of the effect size applied to the control group event +rate. + +Options for ^metannt^ +------------------- + +^baseline()^ specifies the baseline (ie. control group) event rates, from +which the NNT and number of events avoided are computed from. More than +one baseline event rate may be specified. + +^measure(^rr|or|rd^)^ specifies whether the estimated effect size pooled is +a risk ratio, odds ratio or (absolute) risk difference. + +^size(^#^)^ denotes the size of the effect + +^confint(^#,#^)^ denotes the confidence interval around the effect size. + +By default the saved results from the r() macros within @metan@ are used to +derive the control group event rate, the effect measure, the effect size and +its confidence interval. However, unless a recent version of metan (1.71 +onwards) was used immediately beforehand, the first three options must be +specified. The confidence interval is optional. + + +Examples +-------- + + . ^metannt , measure(rr) size(0.2) baseline(0.1,0.2,0.3)^ + + . ^metan tdeath tnodeath cdeath cnodeath, or^ + . ^metannt , baseline(0.15)^ + + + + +Authors +------- + + Michael J Bradburn, Jonathan J Deeks, Douglas G Altman. + Centre for Statistics in Medicine, Institute of Health Sciences, + Old Road, Headington, Oxford OX3 7LF, UK. + + email mike.bradburn@@cancer.org.uk + +Also see +-------- + +On-line: help for @metan@ (if installed), @meta@ (if installed) + + diff --git a/Modules/ado/plus/m/metap.dlg b/Modules/ado/plus/m/metap.dlg new file mode 100644 index 0000000..76bca3a --- /dev/null +++ b/Modules/ado/plus/m/metap.dlg @@ -0,0 +1,55 @@ +/* + +*! metap dialog version 1.0.0, 13 May 2003, T. J. Steichen, steichen@triad.rr.com +*! for metap version 2.0.0, Mar 2000, Aurelio Tobias, atobias@isciii.es + +Meta-analysis of p-values +------------------------- + +Syntax: metap pvar [if exp] [in range] [ , method(#) ] + +To install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "Meta-analysis of p-values (meta&p)" "db metap" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. +*/ + +VERSION 8.0 + +INCLUDE _std_small +INCLUDE header + +HELP hlp1, view("help metap") +RESET res1, label("Reset") + +DIALOG main, label("metap 2.0.0 - Meta-analysis of p-values") tabtitle("Main") +BEGIN + TEXT tx_p 10 10 145 ., /// + label("Variable for p-values:") + VARNAME vn_p 150 @ 190 ., /// + label("Variable for p-values") + + GROUPBOX gb_method 10 40 330 _ht5h, /// + label("Method:") + RADIO r_f 15 55 200 ., /// + label("Fisher's") first /// + option(NONE) + RADIO r_ea 15 75 200 ., /// + label("Edgington's additive") middle /// + option("method(ea)") + RADIO r_en 15 95 200 ., /// + label("Edgington's normal curve") last /// + option("method(en)") +END + +INCLUDE ifin + +PROGRAM command +BEGIN + put "metap " + varlist main.vn_p + INCLUDE _ifin_pr + beginoptions + option radio(main r_f r_ea r_en) + endoptions +END diff --git a/Modules/ado/plus/m/metareg.ado b/Modules/ado/plus/m/metareg.ado new file mode 100644 index 0000000..fd6d913 --- /dev/null +++ b/Modules/ado/plus/m/metareg.ado @@ -0,0 +1,916 @@ +*! v2.6.1 Roger Harbord 4 Nov 2008 + +program define metareg, eclass byable(recall) +version 7 + if replay() { + if "`e(cmd)'" !="metareg" { + error 301 /* last estimates not found */ + } + if _by() { + error 190 /* request may not be combined with by */ + } + Display `0' + exit + } + + syntax varlist(min=1 numeric) [if] [in] , [ /* +*/ wsse(varname numeric) /* +*/ EForm /* +*/ NOCONStant /* +*/ MM /* +*/ REML /* +*/ EB /* +*/ Knapphartung /* +*/ z /* standard normal w/o K-H modification to variance +*/ Level(passthru) /* +*/ PERMute(string) /* +*/ Graph /* produce a bubble plot +*/ RAndomsize /* marker size according to random-effects weights +*/ TAU2test /* tests for tau2=0 residual het test +*/ LOg /* maximize_option +*/ TOLerance(real 1e-6) /* maximize_option also used by eb method +*/ ITERate(integer 100) /* maximize_option - default 16000 is too large! +*/ wsvar(varname numeric)/* undoc'd, for compat with v1 ( wsvar = wsse^2 ) +*/ bsest(string) /* undoc'd, for compat with v1 +*/ tdist /* undoc'd, use t-distib w/o K-H variance mod'n +*/ ORIGinal /* undoc'd, use version 1 (metareg_orig) +*/ LRtau2 /* undoc'd, for compat with v.2.2 on SSC +*/ NOITer /* passed through to metareg_orig +*/ NOTAUComp /* no comparison of tau2 with constant-only model; + for use by permute() option +*/ * /* other `options', parsed by -mlopts- +*/ ] + + marksample touse + tokenize `varlist' + local y `1' /* study estimate */ + qui count if `touse' + local nobs = r(N) + if r(N) == 0 { + error 2000 /* no observations */ + } + if r(N) <= `: word count `*'' { + error 2001 /* insufficient observations */ + } + macro shift 1 + _rmcoll `*' if `touse', `noconstant' + local xvars `r(varlist)' + + mlopts mlopts, `options' iterate(`iterate') /* Parse maximize_options */ + + if "`wsse'"=="" & "`wsvar'"=="" { + di as error "wsse() option required" + exit 100 + } + + if "`wsse'"!="" & "`wsvar'"!="" { + di as error "options wsse() and wsvar() cannot both be specified" + exit 198 + } + + if "`wsse'"!="" { + capture assert `wsse' > 0 if `touse' + if _rc { + di as error "zero or negative wsse() not allowed" + exit 499 + } + tempvar wsvar + qui gen `wsvar' = `wsse'^2 if `touse' + } + + if "`wsvar'"!="" { + capture assert `wsvar' > 0 if `touse' + if _rc { + di as error "zero or negative wsvar() not allowed" + exit 499 + } + } + + if "`noconstant'"!="" { + /* local nvar : word count `varlist' */ + if `: word count `varlist'' == 1 { + di as error "independent variables required with " /* +*/ "noconstant option" + exit 102 + } + } + + local wc : word count "`mm' `reml' `eb'" + if `wc' > 1 { + di as error "Only one of options mm, reml and eb can be specified" + exit 198 + } + + local wc : word count "`mm' `reml' `eb' `bsest'" + if `wc' > 1 { + di as error "Option bsest() cannot be used with options mm, reml or eb" + exit 198 + } + + if "`bsest'"!="reml" & "`bsest'"!="ml" & "`bsest'"!="eb" /* +*/ & "`bsest'"!="mm" & "`bsest'"!="" { + di as error "Between study variance estimation method invalid:" + di as error "should be either reml, ml, eb or mm" + exit 198 + } + + if "`bsest'" == "" { + if "`mm'" != "" | "`permute'" != "" { /* MM is default with permute */ + local bsest "mm" + } + else if "`eb'" != "" { + local bsest "eb" + } + else { /* REML is default otherwise */ + local bsest "reml" + } + } + + if "`bsest'" =="ml" { + di as text /* +*/ "Option bsest(ml) not supported by version 2 of metareg." + di as text "Calling version 1.06 (sbe23):" _n(1) + metareg_orig `0' + exit + } + + if "`knapphartung'" !="" & "`z'" != "" { + di as error "Options knapphartung and z cannot both be specified" + exit 198 + } + + if "`tdist'" != "" & ( "`z'" != "" | "`knapphartung'" !="" ) { + di as error "Option t cannot be specified with options knapphartung or z" + exit 198 + } + + if "`original'" =="original" { + di as text "Calling metareg version 1.06 (sbe23):" _n(1) + metareg_orig `0' + exit + } + + if "`log'"=="" { + local log "nolog" + } + + if "`lrtau2'" != "" { + local tau2test tau2test + } + + if "`permute'" != "" { + if "`xvars'" == "" { + di as error "Option permute() requires at least one covariate" + exit 198 + } + Permute, y(`y') xvars(`xvars') wsvar(`wsvar') permute(`permute') /// + nobs(`nobs') `noconstant' /// + bsest(`bsest') `knapphartung' `z' /// + level(`level') touse(`touse') + exit + } + + + /*** begin main code ***/ + tempvar w hat v resid + tempname remll_c remll sumw tau2 tau2mm b V Q df_Q tau2_0 + + quietly { + + /** (get starting values using) method-of-moments **/ + gen `w'=1/`wsvar' if `touse' + summ `w' if `touse', meanonly + scalar `sumw'=r(sum) + /* use regress not vwls so can predict hat */ + regress `y' `xvars' [iw=`w'] if `touse', `noconstant' + predict `hat' if `touse', hat + /* H_ii where H = X(X'WX)^{-1}X', W=diag(w) */ + replace `hat'=`hat'*`w'^2 if `touse' /* Tr( WX(X'WX)^{-1}X'W ) */ + /* iweights mess up residual df so compute it : */ + scalar `df_Q' = `nobs' - e(df_m) - ("`noconstant'" == "") + scalar `Q' = e(rss) + summ `hat' if `touse', meanonly + scalar `tau2' = (`Q' - `df_Q') / ( `sumw' - r(sum)) + /* truncate at zero */ + scalar `tau2' = max(`tau2', 0) + + /* Fit constant-only model to compare tau2 + NB can't compare different fixed-effect models using REML log-L */ + if "`noconstant'" == "" & "`notaucomp'"=="" & "`xvars'" != "" { + metareg `y' if `touse', wsvar(`wsvar') bsest(`bsest') notaucomp + scalar `tau2_0' = e(tau2) + } + } /* end quietly */ + + if "`bsest'" == "reml" { /* *** REML start *** */ + + global REML_x `xvars' /* betas not estimated by ml so pass X as global*/ + global REML_nocons `noconstant' /* have to pass as global too */ + + /* fit comparison fixed-effect (tau2=0) model*/ + ml model d0 metareg_ll (`y' `wsvar' = ) /* +*/ if `touse', maximize init(_cons=0) /* +*/ search(off) iterate(0) nowarning nolog + scalar `remll_c' = e(ll) /* log-L, comparison model */ + + /* estimate tau2 using ml */ + local tau2mm = max(`tau2', 1e-4) /* init doesn't work with scalar */ + ml model d0 metareg_ll (`y' `wsvar' = ) if `touse',/* +*/ maximize init(_cons=`tau2mm') search(off) nopreserve noscvars /* +*/ `log' tolerance(`tolerance') `mlopts' + + if "`e(converged)'" != "1" { + di as error "WARNING: REML estimation of tau2 failed to converge." + di as error "Estimates may be wrong." + di as error "Try adding mm option to use method-of-moments". + } + + macro drop REML_x + macro drop REML_nocons + + scalar `tau2' = max( _b[_cons], 0) + if `tau2' > 0 { + scalar `remll' = e(ll) + } + else { + scalar `remll' = `remll_c' + } + + } /* REML end */ + + if "`bsest'" == "eb" { /* *** EB start *** */ + local oldtau2=-1 + local j=0 + + while abs((`tau2'-`oldtau2')/(`oldtau2'+1e-8)) >= `tolerance' { + local j = `j'+1 + tempvar wt ypred wtsq numi + local oldtau2=`tau2' + qui { + gen `wt'=(`wsvar'+`tau2')^-1 if `touse' + regress `y' `xvars' [aw=`wt'] if `touse' + predict `ypred' if `touse' + gen `wtsq'=`wt'^2 if `touse' + gen `numi'=(`wt')*(((e(N)/e(df_r))*((`y'-`ypred')^2))-`wsvar') if `touse' + summ `numi' if `touse', meanonly + local num=r(sum) + summ `wt', meanonly + local tau2=`num'/r(sum) + } + if "`log'" == "log" { + di as txt "Iteration " `j' ": tau^2 = " as res `tau2' + } + } + local tau2 = max(`tau2',0) + } /* EB end*/ + + /** estimate final model by weighted LS **/ + quietly { + gen `v' = `wsvar' + `tau2' + regress `y' `xvars' [iw=1/`v'] if `touse', mse1 `noconstant' + matrix `b' = e(b) + matrix `V' = e(V) + local df_m = e(df_m) + + /** knapp and hartung variance adjustment **/ + if "`z'" == "" & "`tdist'" == "" { + tempname vkh + predict `resid' if `touse', resid + replace `resid' = `resid'*`resid' / `v' if `touse' + summarize `resid' if `touse', meanonly + local qkh = r(sum) / `df_Q' + matrix `V' = `V' * max(1, `qkh') + } + + } /* end quietly */ + + + estimates post `b' `V', depname(`y') obs(`nobs') esample(`touse') + estimates scalar tau2 = `tau2' + estimates scalar df_m = `df_m' + estimates scalar Q = `Q' + estimates scalar df_Q = `df_Q' + estimates scalar I2 = max( ( `Q' - `df_Q' ) / `Q', 0 ) + if "`z'" == "" { /* post df_r so get t & F tests not z and chi2 */ + estimates scalar df_r = `df_Q' + } + if "`tdist'" =="" & "`z'" == "" { + estimates scalar q_KH = `qkh' + } + if "`wsse'" == "" { + estimates local wsvar "`wsvar'" + } + else { + estimates local wsse "`wsse'" + } + + if "`bsest'" == "mm" { + estimates local method "Method of moments" + } + if "`bsest'" == "eb" { + estimates local method "Empirical Bayes" + } + if "`bsest'" == "reml" { + estimates local method "REML" + /* return reml log-l in e(remll) NOT e(ll) + to ensure can't do inappropriate lrtest of fixed effects */ + estimates scalar remll = `remll' + if "`remll_c'" != "" { + estimates scalar remll_c = `remll_c' + if (e(remll) < e(remll_c)) | (`tau2' <= 0) { + estimates scalar chi2_c = 0 + } + else { + estimates scalar chi2_c = 2*(e(remll)-e(remll_c)) + } + } + } + + if "`noconstant'" == "" & "`notaucomp'"=="" & "`xvars'" != "" { + estimates scalar tau2_0 = `tau2_0' + } + + /* overall F (or chi2) test */ + if "`xvars'" != "" { + qui test `xvars' + if "`r(chi2)'" != "" { + estimates scalar chi2 = r(chi2) + } + else { + estimates scalar F = r(F) + } + } + + estimates local predict "metareg_p" + estimates local depvar "`y'" + estimates local cmd "metareg" + + Display, `level' `eform' `tau2test' + + + if "`graph'" != "" { + if `: word count `xvars'' != 1 { + di as error in smcl /// + "graph option works only with a single {it:indepvar}" + } + else Graph `y' `xvars' `v' `w' `randomsize' + } + +end + +program define Graph + version 8.2 + args y xvars v w randomsize + + tempvar fit + qui predict `fit' + if "`randomsize'" == "" { + local size `w' + } + else { + local size 1/`v' + } + local yti : variable label `y' + if "`yti'" == "" { + local yti `y' + } + scatter `y' `xvars' [aw=`size'], msymbol(oh) /// + || line `fit' `xvars', sort /// + ||, legend(off) ytitle( `yti') + +end + + +program define Display +version 7 + syntax [, Level(int $S_level) EForm Tau2test q] + tempname pval i2 + if "`eform'" == "eform" { + local eform eform(exp(b)) + } + scalar `pval' = chi2tail(e(df_Q), e(Q)) + + di as txt _n "Meta-regression" /* +*/ _col(55) "Number of obs" _col(70) "= " as res %7.0f e(N) + di as res "`e(method)'" /* +*/ as txt " estimate of between-study variance" /* +*/ _col(55) "tau2" _col(70) "=" as res %8.4g e(tau2) + di as txt "% residual variation due to heterogeneity" /* +*/ _col(55) "I-squared_res" _col(70) "= " as res %6.2f 100 * e(I2) "%" + + + if "`e(tau2_0)'" != "" { + di as txt "Proportion of between-study variance explained" /* +*/ _col(55) "Adj R-squared " _col(70) "= " _c + di as res %6.2f 100 * ( 1 - e(tau2) / e(tau2_0) ) "%" + } + + /* Overall model fit */ + if e(df_m) > 1 { + di as txt "Joint test for all covariates" _c + if "`e(df_r)'" == "" { + di as txt _col(55) "Model chi2(" as res e(df_m) as txt ")" /* +*/ _col(70) "= " as res %7.2f e(chi2) + } + else { + di as txt _col(55) "Model F(" as res e(df_m) as txt "," /* +*/ as res e(df_r) as txt ")" _col(70) "= " /* +*/ as res %7.2f e(F) + } + } + + + di as res "With" _c + if "`e(q_KH)'" == "" { + di as res "out" _c + } + di as txt " Knapp-Hartung modification" _c + + if e(df_m) > 1 { + if "`e(df_r)'" == "" { + di as txt _col(55) "Prob > chi2" _col(70) "= " /* +*/ as res %7.4f chi2tail( e(df_m), e(chi2) ) + } + else { + di as txt _col(55) "Prob > F" _col(70) "= " /* +*/ as res %7.4f Ftail( e(df_m), e(df_r), e(F) ) + } + } + else { + di /* end line */ + } + + + estimates display, level(`level') `eform' + + if "`tau2test'" != "" { + di as txt "Test for residual between-study variance (of tau2=0)" /* +*/ _col(55) "Q_res (" as res %1.0f e(df_Q) as txt " df)" /* +*/ _col(70) "= " as res %7.2f e(Q) + di as txt _col(55) "Prob > Q_res" _col(70) "= " as res %7.4f `pval' + + if "`e(method)'" == "REML" { + scalar `pval' = chi2tail(1, e(chi2_c))*0.5 + if e(chi2_c) <=0 { + scalar `pval'= 1 + } + di in smcl as txt "Likelihood-ratio test of tau2=0: " /* + */ as txt "{help j_chibar:chibar2(01) =}" as res %6.2f e(chi2_c) /* + */ as txt " Prob > chibar2 = " as res %7.4f `pval' + } + + } + +end + + +program define Permute, rclass +version 7 + syntax, y(varname numeric) xvars(varlist numeric) wsvar(varname numeric) /// + permute(string) nobs(integer) [noconstant bsest(string) knapphartung z /// + level(passthru) touse(varname numeric)] + + gettoken reps 0 : permute, parse(",") + confirm integer number `reps' + if `reps' < 1 { + di as err "permute() must be a positive integer" + exit 198 + } + + syntax [, Univariable Detail Verbose NOISily Joint(string) * ] + + if "`verbose'" != "" { /* verbose is undoc'd synonym for detail */ + local detail detail + } + + if "`xvars'" == "" { + di as error "permute() option not allowed when no covariates" + exit 198 + } + + if "`joint'" != "" & "`univariable'" != "" { + di as error "options univariable and joint() cannot both be specified" + exit 198 + } + + if `:word count `xvars'' == 1 { + local univariable /* ensure unset if only one xvar */ + } + + if "`univariable'" == "" { + di as txt _n(1) "Monte Carlo permutation test for meta-regression" + } + else { + di as txt _n(1) in smcl /* +*/ "Monte Carlo permutation test for {it:single covariate} meta-regressions" + } + + if "`bsest'" == "" { + local bsest "mm" /* mm is default for permutation test */ + } + if "`bsest'" == "mm" { + di as res _n "Moment-based " _c + } + else { + di as res _n "REML " _c + } + di as txt "estimate of between-study variance" + + if "`knapphartung'" == "" { + local z "z" /* z is default for for permutation test */ + di as res "Without " _c + } + else { + di as res "With " _c + } + di as txt "Knapp & Hartung modification to standard errors" + + + if "`noconstant'" != "" { + di as error "Permutation test inappropriate with no constant" + exit 198 + } + + local permopts `univariable' `noconstant' `bsest' `knapphartung' `z' + + preserve + qui keep if `touse' + + foreach x of varlist `xvars' { + local explist "`explist' `x'=r(z_`x')" + local xlist "`xlist' `x'" + } + + /* parse varlists in joint() option separated by \ / or | */ + local jt `joint' + local nj 0 + while "`jt'" != "" { + gettoken tmp jt : jt, parse("\/|") + if strpos("\/|", "`tmp'") { + continue + } + local 0 `tmp' + syntax varlist + local nj = `nj' + 1 + local joint`nj' `varlist' + di as txt "joint`nj' : " as res "`joint`nj''" + local explistj "`explistj' joint`nj'=r(chi2`nj')" + local jlist "`jlist' joint`nj'" + } + + tempvar n + qui gen `n' = _n if `touse' + + tempfile pm pmadj + if "`noisily'" =="" { + local quietly quietly + /* quietly permute then replay (if detail specified) + to suppress full -permute- header */ + } + `quietly' permute `n' /* +*/ "metareg_pm `y' `wsvar' `n', xvars(`xvars') joint(`joint') `permopts'" /* +*/ `explist' `explistj', /* +*/ reps(`reps') saving(`pm') replace `options' + + + tempname R C P B + matrix `R' = r(reps) + matrix `C' = r(c) + matrix `P' = `C' * inv(diag(`R')) + + local nx : word count `xvars' + forvalues i = 1/`nx' { + local minreps = min(`reps',`R'[1,`i']) + } + if `minreps' != `reps' { + di as txt "WARNING: some permutations returned missing values" _c + di as txt "See detail below:" + local detail detail + } + + /* to get adjusted p-values from -permute-, + replace z-statistics by their largest absolute values + for each permutation */ + quietly { + use `pm', clear + tempvar max + gen `max' = 0 + foreach v of varlist `xlist' { + replace `max' = abs(`v') if abs(`v') > `max' + } + foreach v of varlist `xlist' { + replace `v' = `max' + } + drop `max' + save `pmadj', replace + permute `xlist' `jlist' using `pmadj', `level' + } // end quietly + + matrix `B' = r(b) + matrix `R' = `R' \ r(reps) + matrix `C' = `C' \ r(c) + matrix `P' = `P' \ r(c) * inv(diag(r(reps))) + foreach M in `R' `C' `P' { + matrix rownames `M' = unadj multadj + if "`joint'" != "" { + /* set matrix entries for adjusted joint tests (N/A) to missing */ + matrix `M'[2, colnumb(`M',"joint1")] = J(1,`nj',.) + } + } + + /* clear results from last permutation so not available to user */ + estimates clear + restore + + /*** Display results of permutation test ****/ + + if `nx' == 1 { /* only one xvar */ + local sep = sqrt(`P'[1,1]*(1-`P'[1,1])/`reps') + if `sep' == 0 { + local sep . + } + di as txt _n _col(9) "Number of obs =" as res %8.0f _N + di as txt _col(9) "Permutations =" as res %8.0f `reps' + di in smcl as txt "{hline 13}{c TT}{hline 17}" + di in smcl as txt /* +*/ %12s "`y'" " {c |}" _s(1) /* +*/ %6s "p" _s(4) /* +*/ %6s "SE(p)" + + di in smcl as txt "{hline 13}{c +}{hline 17}" + di in smcl as txt /* +*/ %12s abbrev(`"`xvars'"',10) /* +*/ " {c |}" _s(2) /* +*/ as result %7.3f `P'[1,1] _s(1) /* +*/ as result %7.4f `sep' + di in smcl as txt "{hline 13}{c BT}{hline 17}" + } + + else { /* more than one xvar */ + + /* Table Head */ + di as txt _n "P-values unadjusted and adjusted for multiple testing" + di as txt _n _col(14) "Number of obs =" as res %8.0f `nobs' + di as txt _col(14) "Permutations =" as res %8.0f `reps' + di in smcl as txt "{hline 13}{c TT}{hline 22}" + di in smcl as txt _s(13) "{c |}" _s(12) "P" + di in smcl as txt /* +*/ %12s abbrev("`y'",10) " {c |}" /* +*/ %11s "Unadjusted" %11s "Adjusted" + di in smcl as txt "{hline 13}{c +}{hline 22}" + + foreach x of local xvars { + local i = `i' + 1 + di in smcl as txt /* +*/ %12s abbrev(`"`x'"',10) /* +*/ " {c |}" _s(4) /* +*/ as result %7.3f `P'[1,`i'] _s(4) /* +*/ %7.3f `P'[2,`i'] + } + + if "`joint'" != "" { + di in smcl as txt "{hline 13}{c +}{hline 22}" + forvalues j = 1/`nj' { + di in smcl as txt /* +*/ %12s "joint`j'" /* +*/ " {c |}" _s(4) /* +*/ as result %7.3f `P'[1,`nx'+`j'] + } + } + + /* Table Foot */ + di in smcl as txt "{hline 13}{c BT}{hline 22}" + /* largest SE(p) = sqrt( max( p(1-p)/n ) ) */ + local maxvarp 0 + forvalues i = 1/2 { + forvalues j = 1/`=colsof(`P')'{ + local maxvarp = max( `maxvarp', /// + `P'[`i',`j'] * (1 - `P'[`i',`j']) / `R'[`i',`j'] ) + } + } + if `maxvarp' == 0 { + local maxvarp . + } + di as txt "largest Monte Carlo SE(P) =" /* +*/ as res %7.4f sqrt(`maxvarp') + } + + /* Detailed results if requested, as displayed by -permute- */ + if "`detail'" != "" { + di as txt in smcl _n(2) "{title:Unadjusted}" + permute `xlist' `jlist' using `pm', `level' + + if `nx' > 1 { + di as txt in smcl _n(2) "{title:Adjusted for multiple testing}" + permute `xlist' using `pmadj', `level' + } + } + + di as txt _n "WARNING:" + di as txt "Monte Carlo methods use random numbers, so results may differ between runs." + di as txt "Ensure you specify enough permutations to obtain the desired precision." + + return scalar N = `nobs' + return matrix reps = `R' + return matrix c = `C' + return matrix p = `P' + return matrix b = `B' + +end + + + +program define metareg_orig +*! v1.06 copyright Stephen Sharp January 1998 STB-42 sbe23 +version 5.0 + local varlist "req ex min(1)" + local if "opt" + local in "opt" + local options "WSSe(string) WSVar(string) BSest(string) TOLeran(integer 4) Level(integer $S_level)" + local options "`options' NOITer ORIGinal" /* original added by RMH */ + + parse "`*'" + if "`wsse'"=="" & "`wsvar'"=="" { + di in re "Must specify a variable containing estimate of precision" + di in re "within each trial, using either wsse() or wsvar() option" + exit 198 + } + if "`wsse'"~="" & "`wsvar'"~=""{ + confirm variable `wsse' + confirm variable `wsvar' + local i=1 + while `i'<=_N { + if abs(`wsse[`i']'^2-`wsvar[`i']')>0.00001 { + di in re "Within study variance should be square of within study standard error" + exit 198 + } + local i=`i'+1 + } + } + if "`wsvar'"~="" { + confirm variable `wsvar' + } + if "`wsse'"~="" { + confirm variable `wsse' + tempvar wsvar + qui gen `wsvar'=`wsse'^2 + } + if "`bsest'"=="" { + local bsest "reml" + } + if "`bsest'"~="reml" & "`bsest'"~="ml" & "`bsest'"~="eb" & "`bsest'"~="mm" & "`bsest'"~="" { + di in re "Between study variance estimation method invalid:" + di in re "should be either reml, ml, eb or mm" + exit 198 + } + if "`noiter'"~="" & "`bsest'"=="mm" { + di in bl "Warning: mm is a non-iterative method, noiter option ignored" + } + parse "`varlist'", parse(" ") + + local y "`1'" + mac shift + local xvars "`*'" + + tempvar touse + preserve + qui { + mark `touse' `if' `in' + markout `touse' `y' `xvars' + keep if `touse' + } + + qui regress `y' `xvars' + local p=_result(3) + local N=_result(1) + + if "`bsest'"=="mm" { + tempvar wt ypred numi one + qui { + gen `wt'=`wsvar'^-1 + regress `y' `xvars' [aw=`wt'] + predict `ypred' + gen `one'=1 + tempname X C Xt C1 XtC1 A A1 A1XtC1 C1X B + mkmat `one' `xvars', matrix(`X') + matrix `C'=J(`N',`N',0) + local i=1 + while `i'<=_N { + matrix `C'[`i',`i']=`wsvar'[`i'] + local i=`i'+1 + } + mat `Xt'=`X'' + mat `C1'=inv(`C') + mat `XtC1'=`Xt'*`C1' + mat `A'=`XtC1'*`X' + mat `A1'=inv(`A') + mat `A1XtC1'=`A1'*`XtC1' + mat `C1X'=`C1'*`X' + mat `B'=`C1X'*`A1XtC1' + local trB=trace(`B') + summ `wt' + local denom=_result(18)-`trB' + gen `numi'=`wt'*((`y'-`ypred')^2) + summ `numi' + local num=max(_result(18)-(`N'-(`p'+1)),0) + local newtsq=`num'/`denom' + } + } + + if "`bsest'"~="mm" { + + local tsq=0.1 + local newtsq=0 + local j=1 + + while abs(`tsq'-`newtsq')>=10^(-`toleran') { + tempvar wt ypred wtsq numi + local tsq=`newtsq' + if "`noiter'"=="" { + di in gr "Iteration " `j' ": tau^2 = " in ye `tsq' + } + qui { + gen `wt'=(`wsvar'+`tsq')^-1 + regress `y' `xvars' [aw=`wt'] + predict `ypred' + gen `wtsq'=`wt'^2 + } + if "`bsest'"=="reml" { + qui { + gen `numi'=(`wtsq')*(((`N'/(`N'-(`p'+1)))*((`y'-`ypred')^2))-`wsvar') + summ `numi' + local num=max(_result(18),0) + summ `wtsq' + local denom=_result(18) + local newtsq=`num'/`denom' + } + } + + if "`bsest'"=="ml" { + qui { + gen `numi'=(`wtsq')*(((`y'-`ypred')^2)-`wsvar') + summ `numi' + local num=max(_result(18),0) + summ `wtsq' + local denom=_result(18) + local newtsq=`num'/`denom' + } + } + + if "`bsest'"=="eb" { + qui { + gen `numi'=(`wt')*(((`N'/(`N'-(`p'+1)))*((`y'-`ypred')^2))-`wsvar') + summ `numi' + local num=max(_result(18),0) + summ `wt' + local denom=_result(18) + local newtsq=`num'/`denom' + } + } + + local j=`j'+1 + + } + } + + tempvar wt + qui { + gen `wt'=(`wsvar'+`newtsq')^-1 + summ `wt' + } + local sumwt=_result(18) + +#delimit ; + di _n + in gr "Meta-analysis regression" + _col(56) "No of studies = " in ye `N' _n + in gr _col(56) "tau^2 method " in ye "`bsest'" _n + in gr _col(56) "tau^2 estimate = " in ye %6.5g `newtsq' _n ; +#delimit cr + if "`bsest'"=="ml" | "`bsest'"=="reml" | "`bsest'"=="eb" { + di in bl "Successive values of tau^2 differ by less than 10^-"`toleran' " :convergence achieved" + } + + qui regress `y' `xvars' [aw=`wt'] + + local scpar=(`sumwt'*(_result(9)^2))/_result(1) + local scpar1=(1/`scpar') + + matrix V=get(VCE) + matrix b=get(_b) + + matrix v=`scpar1'*V + + + mat post b v + mat mlout, level(`level') + + global S_1 = `N' + global S_2 = `newtsq' + + restore + +end + + + exit diff --git a/Modules/ado/plus/m/metareg.dlg b/Modules/ado/plus/m/metareg.dlg new file mode 100644 index 0000000..56c3815 --- /dev/null +++ b/Modules/ado/plus/m/metareg.dlg @@ -0,0 +1,113 @@ +/* + +*! metareg dialog version 1.0.1, 13 May 2003, T. J. Steichen, steichen@triad.rr.com +*! for metareg version 1.06, Jan 1998, Stephen Sharp, stephen.j.sharp@gsk.com + +Meta-analysis regression +------------------------ + +Syntax: metareg y varlist [if exp] [in range] , { wsse(varname)| wsvar(varname) } + [ bsest(string) toleran(#) level(#) noiter ] + +To install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "Meta-analysis Regression (meta®)" "db metareg" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. +*/ + +VERSION 8.0 + +INCLUDE _std_small +INCLUDE header + +HELP hlp1, view("help metareg") +RESET res1, label("Reset") + +DIALOG main, label("metareg 1.06 - Meta-analysis Regression") tabtitle("Main") +BEGIN + TEXT tx_theta 10 5 110 ., /// + label("Dependent (y):") + VARNAME vn_theta 110 5 230 ., /// + label("Var for theta") + + CHECKBOX cb_id 10 35 100 ., /// + label("Covariates:") /// + onclickon(main.vl_covar.enable) /// + onclickoff(main.vl_covar.disable) + VARLIST vl_covar 110 35 230 ., /// + label("Vars for covariates") + + GROUPBOX gb_ws 5 60 340 _ht3h, /// + label("Within-study Varibility:") + RADIO r_se 15 80 85 ., /// + label("Std. Error") first /// + option("wsse") + RADIO r_var 155 80 75 ., /// + label("Variance") last /// + option("wsvar") + TEXT tx_ws 10 100 110 ., /// + label("Variable name:") + VARNAME vn_ws 110 100 230 ., /// + label("WS Variable") + + + GROUPBOX gb_bsest 5 130 175 _ht3h, /// + label("BS Method") + RADIO r_reml 15 150 55 ., /// + label("ReML") first /// + option("bsest(reml)") + RADIO r_ml 15 170 55 ., /// + label("ML") middle /// + option("bsest(ml)") + RADIO r_eb 85 150 85 ., /// + label("EmBayes") middle /// + option("bsest(eb)") + RADIO r_mm 85 170 85 ., /// + label("Moments") last /// + option("bsest(mm)") + + CHECKBOX cb_noiter 210 135 95 ., /// + label("No Iteration") /// + option("noiter") + + CHECKBOX cb_level 210 155 85 ., /// + label("CI Level:") /// + onclickon(main.ed_level.enable) /// + onclickoff(main.ed_level.disable) + EDIT ed_level 300 @ 40 ., /// + label("Level") /// + numonly default(95) /// + option("level") + + CHECKBOX cb_tol 210 175 85 ., /// + label("Tolerance:") /// + onclickon(main.ed_tol.enable) /// + onclickoff(main.ed_tol.disable) + EDIT ed_tol 300 @ 40 ., /// + label("Tolerance") /// + numonly default(4) /// + option("toleran") +END + +INCLUDE ifin + +PROGRAM command +BEGIN + put "metareg " + varlist main.vn_theta [main.vl_covar] + INCLUDE _ifin_pr + beginoptions + if main.r_se { + put "wsse(" + } + if main.r_var { + put "wsvar(" + } + put main.vn_ws + put ")" + option radio(main r_reml r_ml r_eb r_mm) + option main.cb_noiter + optionarg main.ed_level + optionarg main.ed_tol + endoptions +END diff --git a/Modules/ado/plus/m/metareg.hlp b/Modules/ado/plus/m/metareg.hlp new file mode 100644 index 0000000..f5bb74d --- /dev/null +++ b/Modules/ado/plus/m/metareg.hlp @@ -0,0 +1,368 @@ +{smcl} +{* 31oct2008}{...} +{cmd:help metareg}{right: ({browse "http://www.stata-journal.com/article.html?article=up0023":SJ8-4: sbe23_1})} +{hline} + +{title:Title} + +{p2colset 5 16 18 2}{...} +{p2col :{hi:metareg} {hline 2}}Meta-analysis regression (revised){p_end} +{p2colreset}{...} + + +{title:Syntax} + +{p 8 15 2} +{cmd: metareg} +{it:{help varname:depvar}} [{it:{help varlist:indepvars}}] +{ifin} {cmd:wsse(}{it:varname}{cmd:)} +[, {cmdab:ef:orm} +{cmdab:g:raph} +{cmdab:ra:ndomsize} +{cmdab:nocons:tant} +{cmd:mm} {cmd:reml} {cmd:eb} +{cmdab:k:napphartung} {cmd:z} +{cmdab:tau:2test} +{cmdab:l:evel(}{it:#}{cmd:)} +{cmdab:perm:ute(}{it:#} [{cmd:,} {cmdab:u:nivariable} {cmdab:d:etail} +{cmdab:j:oint(}{it:varlist1} [{cmd:|} {it:varlist2} ...]{cmd:)}]{cmd:)} +{cmd:log} +{it:maximize_options}] + +{pstd} +{cmd:by} can be used with {cmd:metareg}; see {manhelp by D}. + + +{title:Description} + +{pstd} +{cmd:metareg} performs random-effects meta-regression +using aggregate-level data. + +{pstd} +From a more abstract perspective, it extends {helpb vwls} +by estimating an extra additive component of variance tau2: + +{p 8 17 2} +y_i = a + B*x_i + u_i + e_i + +{pstd} where a is a constant, u_i is a normal error term with known standard deviations +wsse_i that may vary across units, and e_i is a normal error with variance +tau2 to be estimated, assumed equal across units. This is a similar model to +those fit by the {helpb xt} commands, except that the within-unit data have +been summarized by an effect estimate and its standard error for each unit i. + + +{title:Options} + +{phang}{cmd:wsse(}{it:varname}{cmd:)} specifies the variable +containing the standard error of {it:depvar} within each study +({ul:w}ithin-{ul:s}tudy {ul:s}tandard {ul:e}rror). All values of {it:varname} +must be greater than zero. {cmd:wsse()} is required. + +{phang}{cmd:eform} indicates to output the exponentiated form of the +coefficients and to suppress reporting of the constant. This option may +be useful when {it:depvar} is the logarithm of a ratio measure, such as a log +odds-ratio or a log risk-ratio. + +{phang}{cmd:graph} requests a line graph of fitted values +plotted against the first covariate in {it:indepvars}, +together with the estimates from each study represented by circles. +By default, the circle sizes depend on the precision of each estimate +(the inverse of its within-study variance), +which is the weight given to each study in the fixed-effects model. + +{phang}{cmd:randomsize} is for use with the {cmd:graph} option. It +specifies that the size of the circles will depend on the weights in the +random-effects model rather than the precision of each estimate. These +random-effects weights depend on the estimate of tau2. + +{pstd} The remaining options will mainly be of interest to more advanced users: + +{phang}{cmd:noconstant} suppresses the constant term (intercept). +This is rarely appropriate in meta-regression. + +{pstd} The {cmd:mm}, {cmd:reml}, and {cmd:eb} options are alternatives +that specify the method of estimation +of the additive (between-study) component of variance tau2. + +{phang}{cmd:mm} specifies the use of method of moments to estimate the +additive (between-study) component of variance tau2; this is a generalization +of the DerSimonian and Laird (1986) method commonly used for random-effects +meta-analysis. For speed, this is the default when the {cmd:permute()} option +is specified, because it is the only noniterative method. + +{phang}{cmd:reml} specifies the use of residual maximum likelihood (REML) to estimate the additive +(between-study) component of variance tau2. This is the default unless the +{cmd:permute()} option is specified. This revised version uses +Stata's maximum likelihood facilities to maximize the REML +log likelihood. It will therefore not give identical results to the previous +version of {cmd:metareg}, which used an approximate iterative method. + +{phang}{cmd:eb} specifies the use of the "empirical Bayes" method +to estimate tau2 (Morris 1983). + +{phang}{cmd:knapphartung} makes a modification to the variance of the +estimated coefficients suggested by Knapp and Hartung (2003), accompanied by +the use of a t distribution in place of the standard normal distribution when +calculating p-values and confidence intervals. This is the default unless the +{cmd:permute()} option is specified. + +{phang}{cmd:z} requests that the {cmd:knapphartung} modification not be +applied and that the standard normal distribution be used to calculate +p-values and confidence intervals. This is the default when the +{cmd:permute()} option is specified with a fixed-effects model. + +{phang}{cmd:tau2test} adds to the output two tests of tau2 = 0. The first is +based on the residual heterogeneity statistic, Q_res. The second (not +available if the {cmd:mm} option is also +specified) is a likelihood-ratio test based on the REML log likelihood. These +are two tests of the same null hypothesis (the fixed-effects model with tau2 += 0), but the alternative hypotheses are different, as are the distributions of +the test statistics under the null, so close agreement of the two tests is not +guaranteed. Both tests are typically of little interest because it is more +helpful to quantify heterogeneity than to test for it. + +{phang} {opt level(#)} specifies the confidence level, as a percentage, for +confidence intervals. The default is {cmd:level(95)} or as set by +{helpb set level}. + +{phang} {cmd:permute(}...{cmd:)} calculates p-values by using a Monte Carlo permutation +test. See {help metareg##permute:Option for permutation test} for more information about the option. + +{phang}{cmd:log} requests the display of the iteration log during estimation of +tau2. This is ignored if the {cmd:mm} option is specified, because this uses a +noniterative method. + +{phang}{it:maximize_options} are ignored unless estimation of tau2 is by REML. +These options control the maximization process; see {helpb maximize}. You +should never need to specify them; they are supported only in case problems in +the REML estimation of tau2 are ever reported or suspected. + + +{marker permute}{...} +{title:Option for permutation test} + +{pstd} The {cmd:permute()} option calculates p-values by using a Monte +Carlo permutation test, as recommended by Higgins and +Thompson (2004). To address multiple testing, {cmd:permute()} also calculates +p-values for the most- to least-significant covariates, as the same +authors also recommend. + +{pstd} +The syntax of {cmd:permute()} is + +{p 8 15 2}{cmd:permute(}{it:#} +[{cmd:,} + {cmd:univariable} + {cmd:detail} + {cmd:joint(}{it:varlist1} [{cmd:|} {it:varlist2} ...]{cmd:)}]{cmd:)} + +{pstd} +where {it:#} is required and specifies the number of random permutations to +perform. Larger values give more precise p-values but take longer. + +{pstd} +There are three suboptions: + +{phang}{cmd:univariable} indicates that p-values should be calculated for a +series of single covariate meta-regressions of each covariate in {it:varlist} +separately, instead of a multiple meta-regression of all covariates in +{it:varlist} simultaneously. + +{phang}{cmd:detail} requests more detailed output in the style given by +{helpb permute}. + +{phang}{cmd:joint(}{it:varlist1} [{cmd:|} {it:varlist2} ...]{cmd:)} +specifies that a permutation p-value should also be computed for a joint +test of the variables in each {help varlist}. + +{pstd}The {cmd:eform}, {cmd:level()}, and {cmd:z} options have +no effect when the {cmd:permute()} option is specified. + + +{title:Syntax of predict} + +{p 4 4} +The syntax of {helpb predict} following {cmd:metareg} is + +{p 8 15 2}{cmd:predict} [{it:type}] {it:newvar} {ifin} [{cmd:,} {it:statistic}] + +{pstd} +where {it:statistic} is + +{p 8 25}{cmd:xb}{space 11}fitted values; the default{p_end} +{p 8 25}{cmd:stdp}{space 9}standard error of the prediction{p_end} +{p 8 25}{cmd:stdf}{space 9}standard error of the forecast{p_end} +{p 8 25}{cmd:u}{space 12}predicted random effects{p_end} +{p 8 25}{cmdab:usta:ndard}{space 4}standardized predicted random effects{p_end} +{p 8 25}{cmd:xbu}{space 10}prediction including random effects{p_end} +{p 8 25}{cmd:stdxbu}{space 7}standard error of xbu{p_end} +{p 8 25}{cmdab:h:at}{space 10}leverage (diagonal elements of hat matrix) + +{pstd} +These statistics are available both in and out of sample; +type {cmd:predict ... if e(sample) ...} if wanted only for the estimation sample. + + +{title:Options for predict} + +{phang}{cmd:xb}, the default, calculates the linear prediction, x_i*b, that is, the fitted values excluding the random effects. + +{phang}{cmd:stdp} calculates the standard error of the prediction +(the standard error of the fitted values excluding the random effects). + +{phang}{cmd:stdf} calculates the standard error of the forecast. +This gives the standard deviation of the predicted distribution +of the true value of {it:depvar} in a future study, +with the covariates given by {it:varlist}. +{break}stdf^2 = stdp^2 + tau2. + +{phang}{cmd:u} calculates the predicted random effects, u_i. These are the +best linear unbiased predictions of the random effects, also known as +the empirical Bayes (or posterior mean) estimates of the random effects, +or as shrunken residuals. + +{phang}{cmd:ustandard} calculates the standardized predicted random effects, +i.e., the predicted random effects, u_i, +divided by their (unconditional) standard errors. +These may be useful for diagnostics and model checking. + +{phang}{cmd:xbu} calculates the prediction including random effects, a + +B*x_i + u_i, also known as the empirical Bayes estimates of the effects for +each study. + +{phang}{cmd:stdxbu} calculates the standard error of the prediction including +random effects. + +{phang}{cmd:hat} calculates the leverages (the diagonal elements of the +projection hat matrix). + + +{title:Saved results} + +{pstd}When the {cmd:permute()} option is not specified, {cmd:metareg} saves +the following in {cmd:e()}: + +{synoptset 20 tabbed}{...} +{p2col 5 20 24 2: Scalars}{p_end} +{synopt:{cmd:e(N)}}number of observations{p_end} +{synopt:{cmd:e(df_m)}}model degrees of freedom{p_end} +{synopt:{cmd:e(df_Q)}}degrees of freedom for test of Q=0{p_end} +{synopt:{cmd:e(df_r)}}residual degrees of freedom (if t tests used){p_end} +{synopt:{cmd:e(remll)}}REML log likelihood{p_end} +{synopt:{cmd:e(chi2_c)}}chi^2 for comparison test{p_end} +{synopt:{cmd:e(F)}}model F statistic{p_end} +{synopt:{cmd:e(tau2)}}estimate of tau2{p_end} +{synopt:{cmd:e(Q)}}Cochran's Q{p_end} +{synopt:{cmd:e(I2)}}I-squared{p_end} +{synopt:{cmd:e(q_KH)}}Knapp-Hartung variance modification factor{p_end} +{synopt:{cmd:e(remll_c)}}REML log likelihood, comparison model{p_end} +{synopt:{cmd:e(tau2_0)}}tau2, constant-only model{p_end} +{synopt:{cmd:e(chi2)}}model chi^2{p_end} + +{synoptset 20 tabbed}{...} +{p2col 5 20 24 2: Macros}{p_end} +{synopt:{cmd:e(cmd)}}{cmd:metareg}{p_end} +{synopt:{cmd:e(predict)}}program used to implement {cmd:predict}{p_end} +{synopt:{cmd:e(wsse)}}name of {cmd:wsse()} variable{p_end} +{synopt:{cmd:e(depvar)}}name of dependent variable{p_end} +{synopt:{cmd:e(method)}}{cmd:REML}, {cmd:Method of moments}, or + {cmd:Empirical Bayes}{p_end} +{synopt:{cmd:e(properties)}}{cmd:b V}{p_end} + +{synoptset 20 tabbed}{...} +{p2col 5 20 24 2: Matrices}{p_end} +{synopt:{cmd:e(b)}}coefficient vector{p_end} +{synopt:{cmd:e(V)}}variance-covariance matrix of estimators{p_end} + +{synoptset 20 tabbed}{...} +{p2col 5 20 24 2: Functions}{p_end} +{synopt:{cmd:e(sample)}}marks estimation sample{p_end} +{p2colreset}{...} + + +{title:Examples} + +{phang}{cmd:. metareg logrr latitude, wsse(selogrr) eform} + +{phang}{cmd:. metareg logrr latitude, wsse(selogrr) graph} + +{phang}{cmd:. metareg smd abstract duration itt, wsse(sesmd) permute(10000)} + +{phang}{cmd:. metareg smd abstract duration itt, wsse(sesmd) permute(1000,} + {cmd: univariable)} + +{phang}{cmd:. xi: metareg logor i.group, wsse(selogor) permute(1000, joint(i.group))} + + +{title:Note} + +{pstd} {cmd:metareg} is programmed as a Stata estimation command and so +supports many of the commands listed under {helpb estcom} and +{helpb postest} (except when the {cmd:permute()} option is used). One +deliberate exception is {helpb lrtest}, which is not appropriate after +{cmd:metareg} (because the REML log likelihood cannot be used to compare models +with different fixed effects, while the method of moments is not based on a +likelihood). For this reason, when the REML method is used, the iteration log +showing the log likelihood is suppressed by default; specify +the {cmd:log} option if you wish to see it. + + +{title:References} + +{phang}DerSimonian, R., and N. Laird. 1986. Meta analysis in clinical trials. +{it:Controlled Clinical Trials} 7: 177-188. + +{phang} Higgins, J. P. T, and S. G. Thompson. 2004. Controlling the risk of +spurious findings from meta-regression. {it:Statistics in Medicine} 23: +1663-1682. + +{phang} Knapp, G., and J. Hartung. 2003. Improved tests for a random effects +meta-regression with a single covariate. {it:Statistics in Medicine} 22: +2693-2710. + +{phang} Morris, C. N. 1983. Parametric empirical Bayes inference: Theory and +applications. {it:Journal of the American Statistical Association} 78: 47-55. + +{phang} Sharp, S. 1998. sbe23: Meta-analysis regression. {it:Stata Technical Bulletin} 42: 16-22. Reprinted in {it:Stata Technical Bulletin Reprints}, vol. 7, pp. 148-155. College Station, TX: Stata Press. + + +{title:Author} + +{pstd}Roger M. Harbord{p_end} +{pstd}Department of Social Medicine{p_end} +{pstd}University of Bristol, UK{p_end} +{pstd}{browse "mailto:roger.harbord@bristol.ac.uk":roger.harbord@bristol.ac.uk}{p_end} + + +{title:Acknowledgments} + +{pstd} +This is a substantial revision of the original version of {cmd:metareg} +written by Stephen Sharp (1998), who gave his permission to release this +version under the same name and to incorporate his code. Julian Higgins gave +advice on the permutation test. Aijing Shang tested early versions and made +helpful suggestions. Portions of the new code borrow ideas from official +Stata commands such as {cmd:nbreg}, and I thank StataCorp for making such code +visible to the user. + +{pstd} +A dialog box, written by Thomas J. Steichen, is available for the original +version of the {cmd:metareg} command. + + +{title:Also see} + +{psee} +Article: {it:Stata Journal}, volume 8, number 4: {browse "http://www.stata-journal.com/article.html?article=up0023":sbe23_1},{break} + {it:Stata Technical Bulletin} 42: {browse "http://www.stata.com/products/stb/journals/stb42.pdf":sbe23} + +{psee} +Manual: {hi:[R] meta},{break} +{hi:[R] permute} + +{psee} +Online: {manhelp vwls R}, {manhelp permute R}, {helpb meta} (if installed), +{helpb metan} (if installed), {help meta_dialog} (if installed) +{p_end} diff --git a/Modules/ado/plus/m/metareg_ll.ado b/Modules/ado/plus/m/metareg_ll.ado new file mode 100644 index 0000000..8930cf6 --- /dev/null +++ b/Modules/ado/plus/m/metareg_ll.ado @@ -0,0 +1,35 @@ +*! v 1.1 26Oct2004 +*! Roger Harbord +/* +log-likelihood evaluator (method d0) for metareg v2. +Estimates tau2 by REML. +Variables : +$ML_y1 holds the y-vector of study estimates, +$ML_y2 holds the within-study variances +$REML_x holds the covariates +$REML_nocons is flag "" or "noconstant" +*/ + +program define metareg_ll +version 7 + args todo b lnf + tempvar lnfj v r + tempname R tau2 + mleval `tau2' = `b', scalar + quietly { + gen double `v' = $ML_y2 +`tau2' /* v_i = sigma_i^2 + tau^2 */ + capture regress $ML_y1 $REML_x [iw=1/`v'] if $ML_samp, $REML_nocons + if _rc == 0 { + predict double `r' if $ML_samp, resid + gen double `lnfj' = `r'^2/`v' +log(`v') + mlsum `lnf' = `lnfj' + matrix accum R = $REML_x [iw=1/`v'] if $ML_samp, $REML_nocons + /* R = X'V^-1X is reml correction to -2logL */ + scalar `lnf' = -0.5 * ( `lnf' +log( det(R) ) ) + } + else { + scalar `lnf' = . + } + } + +end diff --git a/Modules/ado/plus/m/metareg_p.ado b/Modules/ado/plus/m/metareg_p.ado new file mode 100644 index 0000000..66d8102 --- /dev/null +++ b/Modules/ado/plus/m/metareg_p.ado @@ -0,0 +1,101 @@ +*! version 1.21 March 23, 2007 @ 17:05:47 +*! Roger Harbord + /* + code based on example in _pred_se.hlp + v1.21 fixed stdxbu + */ + +program define metareg_p +version 7 + local myopts "STDF U USTAndard XBU STDXBU Hat" + _pred_se "`myopts'" `0' /* handles xp and stdp */ + if `s(done)' { + exit + } + local typ `s(typ)' + local varn `s(varn)' + local 0 `"`s(rest)'"' + syntax [if] [in] [, `myopts' noOFFset] + + /* concatenate switch options together */ + local type "`stdf'`u'`ustandard'`xbu'`stdxbu'`hat'" + + /* quickly process default case */ + if "`type'"=="" { + di as txt "(option xb assumed; fitted values)" + _predict `typ' `varn' `if' `in', xb `offset' + exit + } + + /* mark sample */ + marksample touse + + if "`type'"=="u" | "`type'"=="xbu" | "`type'" == "ustandard" { + tempvar xb + qui _predict double `xb' if `touse', xb `offset' + } + + if "`type'" == "stdf" | "`type'" == "stdxbu" | "`type'" == "ustandard" /* +*/ | "`type'" == "hat" { + tempvar stdp + qui _predict double `stdp' if `touse', stdp `offset' + } + + if "`type'" == "u" | "`type'" == "xbu" | "`type'" == "stdxbu" /* +*/ | "`type'" =="ustandard" | "`type'" =="hat" { + tempvar wsvar + if "`e(wsvar)'" !="" { + qui gen `wsvar' = `e(wsvar)' if `touse' + } + else { + qui gen `wsvar' = `e(wsse)'^2 if `touse' + } + } + + if "`type'" == "u" | "`type'" == "xbu" | "`type'" == "stdxbu" { + tempvar B /* Bayes shrinkage factor */ + qui gen double `B' = e(tau2) / ( e(tau2) + `wsvar' ) if `touse' + } + + + if "`type'" == "u" { + gen `typ' `varn' = `B' * ( `e(depvar)' - `xb' ) if `touse' + label var `varn' "Predicted random effects" + exit + } + + if "`type'" == "xbu" { + gen `typ' `varn' = `B' * `e(depvar)' + (1-`B') * `xb' if `touse' + label var `varn' "Prediction including random effects" + exit + } + + if "`type'" == "stdf" { + gen `typ' `varn' = sqrt( `stdp'^2 + e(tau2) ) if `touse' + label var `varn' "S.E. of the forecast" + exit + } + + if "`type'" == "stdxbu" { + gen `typ' `varn' = sqrt( `B'^2 * ( `wsvar' + e(tau2) ) /// + + (1-`B'^2) * `stdp'^2 ) if `touse' + label var `varn' "S.E. of prediction incl. random effects" + exit + } + + if "`type'" == "ustandard" { + gen `typ' `varn' = ( `e(depvar)' - `xb' ) / /* +*/ sqrt( `wsvar' + e(tau2) - `stdp'^2 ) if `touse' + label var `varn' "Standardized predicted random effects" + exit + } + + if "`type'" == "hat" { + gen `typ' `varn' = `stdp'^2 / ( `wsvar' + e(tau2) ) if `touse' + label var `varn' "Leverage" + exit + } + + + error 198 +end diff --git a/Modules/ado/plus/m/metareg_pm.ado b/Modules/ado/plus/m/metareg_pm.ado new file mode 100644 index 0000000..554f6e1 --- /dev/null +++ b/Modules/ado/plus/m/metareg_pm.ado @@ -0,0 +1,58 @@ +*! v1.3.0 8Sep2005 +/* added "joint" option to go with metareg.ado v2.3.1 */ +program define metareg_pm, rclass +version 7 + syntax varlist [if], xvars(varlist numeric) [ univariable joint(string) ] * + tokenize `varlist' + args y wsvar n + marksample touse + tempvar xp z zabs + tempname zi + + foreach x of varlist `xvars' { + gen `: type `x'' `xp' = `x'[`n'] if `touse' + drop `x' + rename `xp' `x' + } + + if "`univariable'" == "" { /* single multiple meta-regression */ + metareg `y' `xvars' if `touse', wsvar(`wsvar') notaucomp `options' + + foreach x of varlist `xvars' { + scalar `zi' = _b[`x'] / _se[`x'] + return scalar z_`x' = `zi' + } + } + + else { /* separate univariable meta-regressions */ + foreach x of varlist `xvars' { + metareg `y' `x' if `touse', wsvar(`wsvar') notaucomp `options' + scalar `zi' = _b[`x'] / _se[`x'] + return scalar z_`x' = `zi' + } + } + + + while "`joint'" != "" { + gettoken tmp joint : joint, parse("\/|") + if strpos("\/|", "`tmp'") { + continue + } + local 0 `tmp' + syntax varlist + local j = `j' + 1 + qui test `varlist' + if "`r(chi2)'" != "" { + return scalar chi2`j' = r(chi2) + } + else { + return scalar chi2`j' = r(F) * r(df) + } + } + + +end + + + + diff --git a/Modules/ado/plus/m/metatrim.dlg b/Modules/ado/plus/m/metatrim.dlg new file mode 100644 index 0000000..7f3ef9e --- /dev/null +++ b/Modules/ado/plus/m/metatrim.dlg @@ -0,0 +1,255 @@ +/* + +*! metatrim dialog version 1.0.2, 22 Jul 2003, T. J. Steichen, steichen@triad.rr.com +*! for metatrim version 1.0.5, 18 Oct 2002, T. J. Steichen, steichen@triad.rr.com + +Nonparametric "trim and fill" analysis of publication bias in meta-analysis +--------------------------------------------------------------------------- + +syntax: metatrim varlist [if] [in] + [ , Vari CI REffect PRint Funnel EForm LEvel(real 95) ESTimat(R|L|Q) + GRaph IDvar(varname) FLIP MIXED SAve(filename [, REPLACE]) * ] + +Install in User Statistics menu via Stata commands: + . window menu append item "stUserStatistics" "meta&trim ("Trim and Fill" Analysis)" "db metatrim" + . window menu refresh +To permanently install, place the commands in your -profile.do- file. +*/ + +VERSION 8.0 + +INCLUDE _std_small +DEFINE _dlght 230 +INCLUDE header + +HELP hlp1, view("help metatrim") +RESET res1, label("Reset") + +DIALOG main, label(`"metatrim 1.0.5 - "Trim and Fill" Analysis"') tabtitle("Main") +BEGIN + GROUPBOX gb_data 10 5 330 85, /// + label("Type of Data") + RADIO r_se 15 20 100 ., /// + label("Theta, SE") first /// + onclickon(script main_se_on) /// + option(NONE) + RADIO r_var 115 @ 100 ., /// + label("Theta, Var") middle /// + onclickon(script main_var_on) /// + option("var") + RADIO r_ci 215 @ 110 ., /// + label("exp(Theta), CI") last /// + onclickon(script main_ci_on) /// + option("ci") + + TEXT tx_se 15 40 320 ., /// + label("Vars for theta, se(theta), in that order") + VARLIST vl_se @ _ss @ ., /// + label("Vars for theta, se(theta)") + TEXT tx_var @ 40 320 ., /// + label("Vars for theta, var(theta), in that order") + VARLIST vl_var @ _ss @ ., /// + label("Vars for theta, var(theta)") + TEXT tx_ci @ 40 320 ., /// + label("Vars for exp(theta), CI_LL, CI_UL, in that order") + VARLIST vl_ci @ _ss @ ., /// + label("Vars for exp(theta), CI_LL, CI_UL") + + GROUPBOX gb_estimat 10 95 90 80, /// + label("Estimate") + RADIO r_linear 15 110 80 ., /// + label("Linear") first /// + option(NONE) + RADIO r_run @ 130 @ ., /// + label("Run") middle /// + option("est(run)") + RADIO r_quadratic @ 150 @ ., /// + label("Quadratic") last /// + option("est(quadratic)") + + GROUPBOX gb_pool 105 95 90 60, /// + label("Pooling") + RADIO r_fixed 110 110 80 ., /// + label("Fixed") first /// + option(NONE) + RADIO r_random @ 130 @ ., /// + label("Random") last /// + option("reffect") + + CHECKBOX cb_eform 205 100 70 ., /// + label("Eform") /// + option("eform") + + CHECKBOX cb_flip 205 120 70 ., /// + label("Flip") /// + option("flip") + + CHECKBOX cb_mixed 205 140 70 ., /// + label("Mixed") /// + option("mixed") + + CHECKBOX cb_graph 275 100 70 ., /// + label("Graph") /// + onclickon(program main_cb_graph_on) /// + onclickoff(program main_cb_graph_off) /// + option("graph") + + CHECKBOX cb_funnel 275 120 70 ., /// + label("Funnel") /// + option("funnel") + + CHECKBOX cb_print 275 140 70 ., /// + label("Print") /// + option("print") /// + onclickon(program main_cb_print_on) /// + onclickoff(program main_cb_print_off) + + CHECKBOX cb_id 110 157 100 ., /// + label("ID Variable:") /// + onclickon(main.vn_id.enable) /// + onclickoff(main.vn_id.disable) + VARNAME vn_id 210 160 130 ., /// + label("ID Variable") /// + option("id") + + CHECKBOX cb_fill_save 10 185 90 ., /// + label("Save filled:") /// + onclickon(main.fi_fill_save.enable) /// + onclickoff(main.fi_fill_save.disable) + FILE fi_fill_save 110 185 230 ., /// + save /// + label("File Name") /// + error("Save File Name") /// + dialogtitle("Save file") /// + filter("Stata Data|*.dta") /// + option("save") + + CHECKBOX cb_gph_save 10 210 90 ., /// + label("Save gph:") /// + onclickon(main.fi_gph_save.enable) /// + onclickoff(main.fi_gph_save.disable) + FILE fi_gph_save 110 210 230 ., /// + save /// + label("File Name") /// + error("Saving File Name") /// + dialogtitle("Saving file") /// + filter("Stata Graphs|*.gph") /// + option("saving") +END + +INCLUDE ifin + +PROGRAM main_cb_graph_on +BEGIN + call main.cb_id.enable + if main.cb_id { + call main.vn_id.enable + } +END + +PROGRAM main_cb_graph_off +BEGIN + if !main.cb_print { + call main.cb_id.disable + call main.vn_id.disable + } +END + +PROGRAM main_cb_print_on +BEGIN + call main.cb_id.enable + if main.cb_id { + call main.vn_id.enable + } +END + +PROGRAM main_cb_print_off +BEGIN + if !main.cb_graph { + call main.cb_id.disable + call main.vn_id.disable + } +END + +SCRIPT main_se_on +BEGIN + main.tx_se.show + main.vl_se.show + main.tx_se.enable + main.vl_se.enable + + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide + + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +SCRIPT main_var_on +BEGIN + main.tx_var.show + main.vl_var.show + main.tx_var.enable + main.vl_var.enable + + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide + + main.tx_ci.disable + main.vl_ci.disable + main.tx_ci.hide + main.vl_ci.hide +END + +SCRIPT main_ci_on +BEGIN + main.tx_ci.show + main.vl_ci.show + main.tx_ci.enable + main.vl_ci.enable + + main.tx_se.disable + main.vl_se.disable + main.tx_se.hide + main.vl_se.hide + + main.tx_var.disable + main.vl_var.disable + main.tx_var.hide + main.vl_var.hide +END + +PROGRAM command +BEGIN + put "metatrim " + if main.r_se { + varlist main.vl_se + } + if main.r_var { + varlist main.vl_var + } + if main.r_ci { + varlist main.vl_ci + } + INCLUDE _ifin_pr + beginoptions + option radio(main r_se r_var r_ci) + option radio(main r_linear r_run r_quadratic) + option radio(main r_fixed r_random) + option main.cb_eform + option main.cb_flip + option main.cb_mixed + option main.cb_print + option main.cb_graph + option main.cb_funnel + optionarg main.vn_id + optionarg main.fi_fill_save + optionarg main.fi_gph_save + endoptions +END diff --git a/Modules/ado/plus/m/mhplot.ado b/Modules/ado/plus/m/mhplot.ado new file mode 100644 index 0000000..d40ba66 --- /dev/null +++ b/Modules/ado/plus/m/mhplot.ado @@ -0,0 +1,628 @@ +*! 1.4.5 TJS 24 May 2001 +* based on hplot 1.4.4 NJC 23 May 2001 +program define mhplot + version 6.0 + + #delimit ; + syntax varlist(numeric) [if] [in] + [, BOrder SOrt(string) noXaxis noYaxis PEn(string) Symbol(string) + T1title(string) T2title(string asis) TItle(str asis) TTIck VALLBL(varname) + XLAbel(numlist) XLIne(numlist) XSCale(str) XTIck(numlist) Axtol(int 600) + Blank flipt Format(string) FONTC(int 290) FONTR(int 570) FONTCB(int 444) + FONTRB(int 923) GAPMag(real 1) GAPs(numlist int) GLegend(string) + GLLJ GLPOS(int -1) t2m(int 0) Grid LAP Legend(string) LIne NIT2 + t1m(int 0) PTSize(int 275) Range RLegend(varname) rllj RLPos(int 31500) + TIM(int 0) Vat VATFmt(string) VATPos(int 31500) Cstart(int -1) + SAving(string) PENText(int 1) ] ; + #delimit cr + + qui { + tempvar touse order gleg gap dmin dmax dneg dpos z + mark `touse' `if' `in' + Markout2 `touse' `varlist' + gen `order' = _n + gsort - `touse' `sort' `order' + count if `touse' + local nuse = r(N) + + * legend on left + if "`legend'" == "" { + tempvar legend + gen str1 `legend' = " " + if "`blank'" == "" { replace `legend' = string(_n) if `touse' } + } + else { + confirm variable `legend' + capture confirm string variable `legend' + if _rc == 7 { + tempvar legend2 + capture decode `legend', gen(`legend2') + if _rc { + gen str1 `legend2' = "" + replace `legend2' = string(`legend') + } + else { replace `legend2' = string(`legend') if missing(`legend2') } + local legend "`legend2'" + } + } + local leglen : type `legend' + local leglen = substr("`leglen'", 4, .) + if `cstart' == -1 { + local cstart = 2000 + int(9000 * `leglen' / 25) + } + + * legend on right + if "`rlegend'" != "" { + capture confirm string variable `rlegend' + if _rc == 7 { + tempvar rleg2 + capture decode `rlegend', gen(`rleg2') + if _rc == 0 { + replace `rleg2' = string(`rlegend') if missing(`rleg2') + local rlegend "`rleg2'" + } + } + } + + * axis scale + if "`xscale'" != "" { + tokenize "`xscale'", parse(",") + if "`4'" != "" | "`2'" != "," { + di in r "invalid xscale( ) option" + exit 198 + } + local xscmin `1' + local xscmax `3' + } + + if "`xscmin'" == "" { local min 0 } + else local min `xscmin' + if "`xscmax'" == "" { local max 0 } + else local max `xscmax' + + * xlabel xtick xline might extend graph range beyond data range + if "`xlabel'`xtick'`xline'" != "" { + numlist "`xlabel' `xtick' `xline'", sort + local nn : word count `r(numlist)' + local xmin : word 1 of `r(numlist)' + local xmax : word `nn' of `r(numlist)' + local min = min(`min', `xmin') + local max = max(`max', `xmax') + } + + * gap legend? + gen str1 `gleg' = " " + local glj = cond("`gllj'" != "", -1, 1) + if "`glegend'" != "" { + tokenize "`glegend'", parse("!") + local j 1 + while "`1'" != "" { + if "`1'" != "!" { + if "`1'" == "." { local 1 " " } + local gleg`j' "`1'" + local j = `j' + 1 + } + mac shift + } + } + + * gaps between lines? + gen byte `gap' = 0 + if "`gaps'" != "" { + local j 1 + numlist "`gaps'", int range(>=0) + tokenize `r(numlist)' + while "`1'" != "" { + if "`1'" == "0" { + local gleg0 "`gleg`j''" + if "`gleg0'" == "" { local gleg0 " " } + } + else { + replace `gap' = 1 in `1' if `1' <= `nuse' + replace `gleg' = "`gleg`j''" in `1' if `1' <= `nuse' + } + local j = `j' + 1 + mac shift + } + } + count if `gap' + local ngaps = r(N) + ("`gleg0'" != "") + + * data range + tokenize `varlist' + local nvars : word count `varlist' + gen `dmin' = `1' + gen `dmax' = `1' + if `nvars' >= 2 { + local i 2 + while `i' <= `nvars' { + replace `dmin' = min(`dmin', ``i'') + replace `dmax' = max(`dmax', ``i'') + local i = `i' + 1 + } + } + su `dmin' if `touse', meanonly + local min = min(`min', r(min)) + su `dmax' if `touse', meanonly + local max = max(`max', r(max)) + local drange = `max' - `min' + local zero = cond(`min' >= 0, max(0, `min'), min(0, `max')) + gen `z' = `zero' + gen `dneg' = min(`dmin', `z') + gen `dpos' = max(`dmax', `z') + } + + * start of parameter block + + local t1start 1000 /* row for t1title */ + local t2start 1900 /* row for t2title */ + local ybeg 2400 /* start of y-axis */ + local ylength 17600 + + * `axtol' is space at ends of y-axis + * axtol too large => ystep negative FW + if `axtol' > `ylength' / 2 { + di in bl "axtol too large: reset to default 600" + local axtol 600 + } + + * row where first line starts + local ystart = `ybeg' + `axtol' + + * step between lines: one gap defaults to one line + local ystep = (`ylength' - 2 * `axtol') / (`nuse' - 1 + `ngaps' *`gapmag') + + local yend = `ybeg' + `ylength' + local ynudge = 200 * (`fontr' / 570)^2 + /* text displaced downwards from lines */ + local ytick 400 /* tick length */ + local yleg 1000 /* labels down from axis */ + local yleg = `yend' + `yleg' + local ytitle 1400 /* title down from labels */ + local ytitlef 900 /* title down from labels, flip titles */ + local xstart `cstart' /* col where first line begins */ + local xgap 400 /* gap between left legend and body of plot */ + local xbeg = `xstart' - `xgap' + if `glpos' == -1 { local glpos `xbeg' } + local xlength = 30000 - `xstart' + /* horizontal extent of data region */ + local xend = `xbeg' + `xgap' + `xlength' + local xz = `xbeg' + `xgap' + `xlength' * (`zero' - `min') / `drange' + local mcent = (`cstart' + 30000) / 2 + `tim' + /* col where main title centred */ + local dotsp 150 /* spacing between dots */ + + if "`format'" == "" { local format "%1.0f" } + if "`vatfmt'" == "" { local vatfmt "%1.0f" } + local ahl = 500 * `ptsize' / 275 /* arrowhead length */ + local aha = _pi / 6 /* arrowhead angle, between head and stem */ + local barht `ahl' /* bar height */ + + if "`symbol'" == "" { + if `nvars' < 6 { local symbol "46253" } + else local symbol : di _dup(`nvars') "4" + } + else if length("`symbol'") == 1 & `nvars' > 1 { + local symbol : di _dup(`nvars') "`symbol'" + } + Gphtrans `symbol' + local symbol "`r(symbol)'" + + if "`pen'" == "" { local pen : di _dup(`nvars') "2" } + else if length("`pen'") == 1 & `nvars' > 1 { + local pen : di _dup(`nvars') "`pen'" + } + + * end of parameter block + + * start gph + if "`saving'" != "" { local saving ", saving(`saving')" } + gph open `saving' /* FW */ + gph pen `pentext' + gph font `fontr' `fontc' + + * y-axis + if "`yaxis'" == "" { gph line `ybeg' `xstart' `yend' `xstart' } + + * ttick => top ticks + local ttick = "`ttick'" == "ttick" + * ttick should => border FW + if `ttick' { local border "border" } + + * x-axis and labels + if "`xaxis'" == "" { + gph line `yend' `xstart' `yend' `xend' + local ytick2 = `ybeg' - `ytick' / 2 + local ytick = `yend' + `ytick' + if "`xlabel'" == "" { + gph line `yend' `xstart' `ytick' `xstart' + gph line `yend' `xend' `ytick' `xend' + if `ttick' { + gph line `ybeg' `xstart' `ytick2' `xstart' + gph line `ybeg' `xend' `ytick2' `xend' /* FW */ + } + local text = cond("`lap'" == "lap", abs(`min'), `min') + local text : di `format' `text' + gph text `yleg' `xstart' 0 0 `text' + local text = cond("`lap'" == "lap", abs(`max'), `max') + local text : di `format' `text' + gph text `yleg' `xend' 0 0 `text' + } + else { + numlist "`xlabel'" + tokenize `r(numlist)' + if "`vallbl'" != "" { local vallbl : value label `vallbl' } + while "`1'" != "" { + local xtickp = `xbeg' + `xgap' + `xlength' * (`1' - `min') / `drange' + gph line `yend' `xtickp' `ytick' `xtickp' + if `ttick' { gph line `ybeg' `xtickp' `ytick2' `xtickp' } + local text = cond("`lap'" == "lap", abs(`1'), `1') + if "`vallbl'" != "" { + local label : label `vallbl' `text' + if "`label'" != "" { local text "`label'" } + } + else local text : di `format' `text' + gph text `yleg' `xtickp' 0 0 `text' + mac shift + } + } + } + + * x-ticks + if "`xtick'" != "" { + numlist "`xtick'" + tokenize `r(numlist)' + while "`1'" != "" { + local xtickp = `xbeg' + `xgap' + `xlength' * (`1' - `min') / `drange' + gph line `yend' `xtickp' `ytick' `xtickp' + if `ttick' { gph line `ybeg' `xtickp' `ytick2' `xtickp' } + mac shift + } + } + + * x-lines + if "`xline'" != "" { + numlist "`xline'" + tokenize `r(numlist)' + while "`1'" != "" { + local xli = `xbeg' + `xgap' + `xlength' * (`1' - `min') / `drange' + gph line `yend' `xli' `ybeg' `xli' + mac shift + } + } + + * border + if "`border'" != "" { + gph line `ybeg' `xstart' `ybeg' `xend' + gph line `ybeg' `xend' `yend' `xend' + if "`xaxis'" != "" { gph line `yend' `xstart' `yend' `xend' } + } + + * gap legend above first data point + if "`gleg0'" != "" { + local y2 = `ystart' + (`gapmag' - 1) * `ystep' + `ynudge' + gph text `y2' `glpos' 0 `glj' `gleg0' + } + + * for each variable + tokenize `varlist' + local j 1 + while "`1'" != "" { + + local data "`1'" + local sy = substr("`symbol'", `j', 1) + local pe = substr("`pen'", `j', 1) + local y `ystart' + if "`gleg0'" != "" { local y = `y' + `ystep' * `gapmag' } + + * for each observation + local i 1 + while `i' <= `nuse' { + +/* tjs code */ + * dots and/or lines + if `j' == 1 { + + local xmax = `xbeg' + `xgap' + /* + */ `xlength' * (`dmax'[`i'] - `min') / `drange' + local xmin = `xbeg' + `xgap' + /* + */ `xlength' * (`dmin'[`i'] - `min') / `drange' + + if "`line'" == "line" { gph line `y' `xmin' `y' `xmax' } + + if "`line'`grid'" == "" { + if "`range'" == "range" { + local ndots = int(abs(`xmax' - `xmin') / `dotsp') + tempvar ys xs + if `ndots' > _N { qui set obs `ndots' } + qui gen `ys' = `y' + qui gen `xs' = _n + qui replace `xs' = `xmin' + (`xs' - 1) * `dotsp' + qui replace `xs' = . if `xs' < `xmin' | `xs' > `xmax' + gph vpoint `ys' `xs', size(`ptsize') symbol(0) + } + else { + local ndots = int(abs(`xmax' - `xz') / `dotsp') + tempvar ys xs + if `ndots' > _N { qui set obs `ndots' } + qui gen `ys' = `y' + qui gen `xs' = _n + qui replace `xs' = `xz' + (`xs' - 1) * `dotsp' * sign(`dpos'[`i']) + qui replace `xs' = . if `xs' < `xmin' | `xs' > `xmax' + gph vpoint `ys' `xs', size(`ptsize') symbol(0) + + local ndots = int(abs(`xmin' - `xz') / `dotsp') + tempvar ys xs + if `ndots' > _N { qui set obs `ndots' } + qui gen `ys' = `y' + qui gen `xs' = _n + qui replace `xs' = `xz' + (`xs' - 1) * `dotsp' * sign(`dneg'[`i']) + qui replace `xs' = . if `xs' < `xmin' | `xs' > `xmax' + gph vpoint `ys' `xs', size(`ptsize') symbol(0) + } + } + + if "`grid'" != "" { + tempvar ys xs + local ndots = int(abs(`xstart' - `xend') / `dotsp') + if `ndots' > _N { qui set obs `ndots' } + qui gen `ys' = `y' + qui gen `xs' = _n + qui replace `xs' = `xstart' + (`xs' - 1) * `dotsp' + qui replace `xs' = . if `xs' > `xend' + gph vpoint `ys' `xs', size(`ptsize') symbol(0) + } + } +/* tjs code end */ + + * data point + gph pen `pe' + local x = `xbeg' + `xgap' + `xlength' * (`data'[`i'] - `min') / `drange' + if `data'[`i'] < . & "`sy'" != "i" { + if "`sy'" == "a" { + if `j' == 1 { local sign 1 } + else local sign = sign(`data'[`i'] - `prev'[`i']) + Gphhah `y' `x' `sign' `ahl' `aha' + } + else if "`sy'" == ">" { Gphhah `y' `x' 1 `ahl' `aha' } + else if "`sy'" == "<" { Gphhah `y' `x' -1 `ahl' `aha' } + else Gphpt `sy' `y' `x' `barht' `ptsize' + } + + * text + gph pen `pentext' + local y2 = `y' + `ynudge' + if "`vat'" != "" & `nvars' == 1 { + local text : di `vatfmt' `data'[`i'] + gph text `y2' `vatpos' 0 1 `text' + } + if `j' == 1 { + local text = `legend'[`i'] + gph text `y2' `xbeg' 0 1 `text' + } + if `j' == 1 & "`rlegend'" != "" { + local text = `rlegend'[`i'] + local rlj = cond("`rllj'" != "", -1, 1) + gph text `y2' `rlpos' 0 `rlj' `text' + } + + * gap + if `gap'[`i'] { + local y = `y' + `ystep' * `gapmag' + if `j' == 1 { + local text = `gleg'[`i'] + local y2 = `y' + `ynudge' + gph text `y2' `glpos' 0 `glj' `text' + } + } + + local y = `y' + `ystep' + local i = `i' + 1 + } + * next observation + + local prev `1' + local j = `j' + 1 + mac shift + } + * next variable + + * t2title, left justified (defaults to key for 2 or more variables) + if "`t2title'" != "" & trim("`t2title'") == "" { local t2title } + else if "`t2title'" != "" { gph text `t2start' `xstart' 0 -1 `t2title' } + else if `nvars' >= 2 { + local t2 = `t2start' - `ynudge' + local xjump = `xlength' / `nvars' + local xjump2 = `xjump' / 50 + local x = `xstart' + `xjump2' + `t2m' + local j 1 + while `j' <= `nvars' { + local sy = substr("`symbol'", `j', 1) + local pe = substr("`pen'", `j', 1) + gph pen `pe' + if "`sy'" == "a" { + local ahv = index("`symbol'", "a") + if `ahv' > 1 { + local this : word `ahv' of `varlist' + local ahvm1 = `ahv' - 1 + local prev : word `ahvm1' of `varlist' + count if `this' >= `prev' & `touse' + local majsign = cond(r(N) > `nuse' / 2, 1, -1) + } + else local majsign 1 + local x3 = `x' + 0.6 * `ptsize' * `majsign' + Gphhah `t2' `x3' `majsign' `ahl' `aha' + } + else if "`sy'" == ">" { + local x3 = `x' + 0.6 * `ptsize' + Gphhah `t2' `x3' 1 `ahl' `aha' + } + else if "`sy'" == "<" { + local x3 = `x' - 0.6 * `ptsize' + Gphhah `t2' `x3' -1 `ahl' `aha' + } + else if "`sy'" != "i" { + Gphpt `sy' `t2' `x' `barht' `ptsize' + } + local x2 = `x' + `xjump2' + local var : word `j' of `varlist' + if "`nit2'" == "" { + local text : variable label `var' + if "`text'" == "" { local text "`var'" } + } + else local text "`var'" + gph pen `pentext' + gph text `t2start' `x2' 0 -1 `text' + local x = `x' + `xjump' + local j = `j' + 1 + } + } + + * title and t1title + if `"`title'"' == `""' & `nvars' == 1 { + local title : variable label `data' + if "`title'" == "" { local title "`data'" } + } + else if `"`title'"' != `""' { local title `title' } + + local xL = `xstart' + `t1m' + if "`flipt'" == "" { /* default */ + * t1title, left justified + gph text `t1start' `xL' 0 -1 `t1title' + + * main title at bottom, centred + gph font `fontrb' `fontcb' + local ytitle = `yleg' + `ytitle' + gph text `ytitle' `mcent' 0 0 `title' + } + else { /* flip titles from default */ + * bottom title, centred (and closer to axis than default) + local ytitle = `yleg' + `ytitlef' + gph text `ytitle' `mcent' 0 0 `t1title' + + * main title at top, left justified + gph font `fontrb' `fontcb' + gph text `t1start' `xL' 0 -1 `title' + } + + gph close +end + +program define Gphhah /* horizontal arrow head */ +* `1' y position of tip +* `2' x position of tip +* `3' sign determines direction: 1 = >, -1 = < +* `4' arrowhead length +* `5' arrowhead interior angle (between shaft and head) +* 1.0.1 NJC 18 February 1999 +* 1.0.0 NJC 27 May 1997 + version 6.0 + local ah1y = `1' - `3' * `4' * sin(`5') + local ah1x = `2' - `3' * `4' * cos(`5') + local ah2y = `1' + `3' * `4' * sin(`5') + local ah2x = `2' - `3' * `4' * cos(`5') + gph line `ah1y' `ah1x' `1' `2' + gph line `ah2y' `ah2x' `1' `2' +end + +program define Gphbar /* vertical bar */ +* Gphbar yposition xposition bar_height +* 1.0.1 NJC 18 February 1999 +* 1.0.0 NJC 27 May 1997 + version 6.0 + local by1 = `1' - 0.5 * `3' + local by2 = `1' + 0.5 * `3' + gph line `by1' `2' `by2' `2' +end + +program define Gphcross /* cross X */ /* FW */ +* Gphcross yposition xposition bar_height +* 1.0.1 NJC 18 February 1999 +* 1.0.0 NJC 6 October 1997 + version 6.0 + local Xy1 = `1' - 0.5 * `3' + local Xy2 = `1' + 0.5 * `3' + local Xx1 = `2' - 0.5 * `3' + local Xx2 = `2' + 0.5 * `3' + gph line `Xy1' `Xx1' `Xy2' `Xx2' + gph line `Xy2' `Xx1' `Xy1' `Xx2' +end + +program def Markout2 /* marks out obs with all missing values */ +* 1.0.2 NJC 16 February 1999 +* 1.0.1 NJC 25 March 1998 + version 6.0 + syntax varlist(min=1) [, Strok ] + tokenize `varlist' + local nvars : word count `varlist' + if `nvars' == 1 { exit 0 } + local nvars = `nvars' - 1 + local markvar `1' + mac shift + tempvar nmiss + gen `nmiss' = 0 + qui { + while "`1'" != "" { + local type : type `1' + if substr("`type'", 1, 3) == "str" { + if "`strok'" != "" { replace `nmiss' = `nmiss' + (`1' == "") } + else replace `nmiss' = `nmiss' + 1 + } + else replace `nmiss' = `nmiss' + (`1' == .) + mac shift + } + replace `nmiss' = `nmiss' == `nvars' + replace `markvar' = 0 if `nmiss' + } +end + +program def Gphtrans, rclass /* transliterate ".OSTodp" -> "0123456" */ +* 1.0.2 NJC 1 March 1999 +* 1.0.0 NJC 31 March 1998 + version 6.0 + args argin + local length = length("`argin'") + + local i 1 + while `i' <= `length' { + local s = substr("`argin'", `i', 1) + if "`s'" == "." { local s 0 } + else if "`s'" == "O" { local s 1 } + else if "`s'" == "S" { local s 2 } + else if "`s'" == "T" { local s 3 } + else if "`s'" == "o" { local s 4 } + else if "`s'" == "d" { local s 5 } + else if "`s'" == "p" { local s 6 } + local argout "`argout'`s'" + local i = `i' + 1 + } + + return local symbol `argout' +end + +program def Gphpt +* 1.2.2 NJC 24 February 1999 smaller big cross, bigger , +* 1.2.1 NJC 18 February 1999 +* 1.2.0 NJC 12 Jan 1999 +* 1.1.0 NJC 24 Sept 1998 +* 1.0.0 NJC 6 April 1998 + version 6.0 + args sy y x barht ptsize + + if "`sy'" == "|" { Gphbar `y' `x' `barht' } + else if "`sy'" == "," { Gphbar `y' `x' 0.6*`barht' } + else if "`sy'" == "X" { Gphcross `y' `x' 0.707*`barht' } + else if "`sy'" == "x" { Gphcross `y' `x' 0.5*`barht' } + else if "`sy'" == "-" { Gphhbar `y' `x' 0.5*`barht' } + else gph point `y' `x' `ptsize' `sy' +end + +program define Gphhbar /* horizontal bar */ +* Gphhbar yposition xposition bar_length +* 1.0.1 NJC 18 February 1999 +* 1.0.0 NJC 24 Sept 1998 + version 6.0 + local bx1 = `2' - 0.5 * `3' + local bx2 = `2' + 0.5 * `3' + gph line `1' `bx1' `1' `bx2' +end diff --git a/Modules/ado/plus/m/micombine.ado b/Modules/ado/plus/m/micombine.ado new file mode 100644 index 0000000..084a291 --- /dev/null +++ b/Modules/ado/plus/m/micombine.ado @@ -0,0 +1,437 @@ +*! version 1.1.1 PR 28nov2005 +/* +History + +1.1.1 28nov2005 eform and eform() option styles now allowed. + nowarning option to suppress warning message about supported regression cmds. +1.1.0 30sep2005 Generalization of supported commands (cmdchk.ado also modified). + Version <=7 no longer supported. +1.0.9 18apr2005 Default rowid variable becomes _i. + If not found, take from char _dta[MI_obsid] then char _dta[mi_id]. + Default impid variable is _j. If not found, take from _dta[MI_impid]. + These changes are for future compatibility with MItools. +1.0.8 04mar2005 Fixed problem with eform on redisplay +1.0.7 28jan2005 Fixed problem with null model estimation + Fixed bug with noconstant option +1.0.6 25jan2005 e(sample) now correct for all imputations, via ereturn post. + Add d.f. quantities from Barnard & Rubin (1999) Biometrika 86:948-955 eq (3)-(5). + Minor additions to ereturn quantities for compatibility with misw. + Allow null model and model only with constant for benefit of misw. +1.0.5 16nov2004 Update calculations of quantities stored for Li et al (1991) F test. +1.0.4 13oct2004 Change e(cmd) to `cmd', make e(cmd2)="micombine" (for use after mfx). + Implementation of mean log likelihood and chisquare statistic saved + (note undocumented -noclear- but v. useful option to ereturn post/estimates post). +*/ +program define micombine, eclass + +if _caller()<=7 { + di as error "version 7 and earlier not supported" + exit 9 +} + +if replay() { + if `"`e(cmd2)'"'!="micombine" { + error 301 + } + syntax[, EForm EForm2(string)] + if "`eform2'"!="" { + if "`eform'"!="" di as err "[eform ignored]" + local eform eform(`eform2') + } + else if "`eform'"!="" local eform eform("exp(b)") + di as text _n "Multiple imputation parameter estimates (" as res e(m) as text " imputations)" + capture ereturn display, `eform' + local rc=_rc + if `rc'>0 { + * Null model, or model with cc() only + if `"`e(cmd)'"'!="stcox" { + `e(cmd)' `0' + } + else di as text "[Null model - no estimates]" + } + else ereturn display, `eform' + di as result e(N) as text " observations." + exit +} + +gettoken cmd 0 : 0 +if "`cmd'"=="stpm" { + local dist 7 + local bad 0 +} +else { + cmdchk `cmd' + local cmdnotknown `s(bad)' + /* + dist=0 (normal), 1 (binomial), 2 (poisson), 3 (cox), 4 (glm), + 5 (xtgee), 6(ereg/weibull). + */ + local dist `s(dist)' +} +syntax [anything] [if] [in] [aw fw pw iw] , [ IMPid(string) BR CC(varlist) noCONStant /// + DEAD(varname) DETail EForm EForm2(string) GENxb(string) LRR noWARning OBSid(string) * ] + +if `cmdnotknown' & "`warning'"!="nowarning" { + di as err _n "Warning: " as inp "`cmd'" as err " is not a certified regression command for micombine." + di as err "micombine will continue mechanically, but correct results are not guaranteed." + di as err "You must take responsibility that Rubin's rules are appropriate here." _n +} + +if "`eform2'"!="" { + if "`eform'"!="" di as err "[eform ignored]" + local eform eform(`eform2') +} +else if "`eform'"!="" local eform eform("exp(b)") + +* Check for possible impid characteristic. If it does not exist use default _j +if "`impid'"=="" { + local impid: char _dta[MI_impid] + if "`impid'"=="" local impid _j +} +cap confirm var `impid' +if _rc { + di as err "imputation identifier `impid' not found" + exit 601 +} + +* Check for possible obsid chars. If none exist use default _i +if "`obsid'"=="" { + local I: char _dta[MI_obsid] + if "`I'"=="" local I: char _dta[mi_id] + if "`I'"=="" local I _i +} +else local I `obsid' +cap confirm var `I' +if _rc { + di as err "observation identifier `I' not found" + exit 601 +} + +if "`detail'"!="" { + local detail noisily +} +else local detail + +*Change here 11/15/05, commenting out the line below !! PR DELETED XIAO CHEN'S EDIT, NOV 05 +frac_cox "`dead'" `dist' + +if "`constant'"=="noconstant" { + if "`cmd'"=="fit" | "`cmd'"=="stcox" | "`cmd'"=="cox" { + di as error "noconstant invalid with `cmd'" + exit 198 + } +} + +*Change here 11/15/05, `dist' could be null.... !! PR DELETED XIAO CHEN'S EDIT, NOV 05 +*if "`dist'" =="7" { /* stcox, streg, stpm */ +if `dist'==7 { + local y + local yname _t + local xvars `anything' +} +else { + gettoken y xvars : anything + gettoken xvars left: xvars, parse("(") + local yname `y' +} + +tempvar touse +quietly { + marksample touse + markout `touse' `varlist' `dead' `cc' + if "`dead'"!="" { + local dead "dead(`dead')" + } + +* Deal with weights. + frac_wgt `"`exp'"' `touse' `"`weight'"' + local wgt `r(wgt)' + + tempvar J + * Important (compatibility with mitools): ignore rows for which impid=0 + egen int `J'=group(`impid') if `touse'==1 & `impid'>0 & !missing(`impid') + sum `J', meanonly + local m=r(max) + if `m'<2 { + di as error "there must be at least 2 imputations" + exit 198 + } + + local nxvar: word count `xvars' +/* + if `nxvar'<1 { + di as err "there must be at least one covariate" + exit 198 + } +*/ + local ncc: word count `cc' /* could legitimately be zero */ + local nvar=`nxvar'+`ncc' /* number of covariates in model */ + + count if `touse'==1 & `J'==1 + local nobs=r(N) + +* Null Cox model (or model with only ccvars): fit on final imputation only, and quit + if "`xvars'"=="" & ("`cmd'"=="cox" | "`cmd'"=="stcox") { + if "`cmd'"=="stcox" & "`cc'"=="" { + local options `options' estimate + } + `detail' `cmd' `y' `cc' if `touse'==1 & `J'==`m' `wgt', `options' `dead' `constant' + noi `cmd' + di as result `nobs' as text " observations." + ereturn scalar m=`m' + ereturn local impid `impid' + ereturn local cmd `cmd' + ereturn local cmd2 micombine + exit + } + +* Compute model over m imputations + tempname W Q B T QQ + if "`genxb'"!="" { + tempvar xb xbtmp + gen `xb'=. + } + * Estimate mean LR chisquare statistic (where possible) + tempname chi2 ell ell0 nucom + scalar `chi2'=0 + scalar `ell'=0 + scalar `ell0'=0 + forvalues i=1/`m' { + tempname Q`i' + `detail' `cmd' `y' `xvars' `cc' `left' if `touse'==1 & `J'==`i' `wgt', /// + `options' `dead' `constant' + scalar `nucom'=e(df_r) // complete-data residual degrees of freedom + if `nucom'==. { + scalar `nucom'=100000 + } + scalar `ell'=`ell'+e(ll) + scalar `ell0'=`ell0'+e(ll_0) + scalar `chi2'=`chi2'-2*(e(ll_0)-e(ll)) + if "`genxb'"!="" { + predict `xbtmp' if `touse'==1 & `J'==`i', xb + replace `xb'=`xbtmp' if `touse'==1 & `J'==`i' + drop `xbtmp' + } + matrix `Q`i''=e(b) + if `i'==1 { + matrix `Q'=e(b) + matrix `W'=e(V) + } + else { + matrix `Q'=`Q'+e(b) + matrix `W'=`W'+e(V) + } + + } + if "`genxb'"!="" { + sort `touse' `I' `J' + by `touse' `I': gen `genxb'=sum(`xb')/`m' if `touse'==1 + by `touse' `I': replace `genxb'=`genxb'[_N] if _n<_N + lab var `genxb' "Mean Linear Predictor (`m' imputations)" + } + matrix `Q'=`Q'/`m' /* MI param estimates */ + matrix `W'=`W'/`m' + scalar `chi2'=`chi2'/`m' + scalar `ell'=`ell'/`m' + scalar `ell0'=`ell0'/`m' + local k=colsof(`Q') + matrix `B'=J(`k',`k',0) + forvalues i=1/`m' { + matrix `QQ'=`Q`i''-`Q' + if `i'==1 { + matrix `B'=`QQ''*`QQ' + } + else matrix `B'=`B'+`QQ''*`QQ' + } + matrix `B'=`B'/(`m'-1) + matrix `T'=`W'+(1+1/`m')*`B' /* estimated VCE matrix */ + /* + Relative increase in variance due to missing information (r) for + each variable, and df and lambda, the fraction of missing information. + All measures are unstable for low m. See Schafer (1997) p. 110. + + Note that BIF = sqrt(T/W) = sqrt(1 + (B/W)*(1+1/m)) = sqrt(1+r) + is the between-imputation imprecision factor, i.e. the ratio + of the SE derived from T to the SE derived from W, + ignoring between-imputation variation in parameter estimates. + */ + tempname r t lambda nu BIF + matrix `r'=J(1,`k',0) + matrix `lambda'=J(1,`k',0) + matrix `nu'=J(1,`k',0) + matrix `BIF'=J(1,`k',0) + scalar `t'=`m'-1 + * Next few lines assign quantities for tests of individual (1 df) components of Q (=beta) + forvalues j=1/`k' { + matrix `r'[1,`j']=(1+1/`m')*`B'[`j',`j']/`W'[`j',`j'] + matrix `nu'[1,`j']=cond(`t'>4, 4+(`t'-4)*(1+(1-2/`t')/`r'[1,`j'])^2, `t'*(1+1/`r'[1,`j'])^2) + matrix `lambda'[1,`j']=(`r'[1,`j']+2/(`nu'[1,`j']+3))/(`r'[1,`j']+1) + matrix `BIF'[1,`j']=sqrt(1+`r'[1,`j']) /* = sqrt(`T'[`j',`j']/`W'[`j',`j']) */ + } + * Next few lines assign quantities for d.f. from Barnard & Rubin 1999 B'ka 86(4): 948-955. + tempname nutilde num nuobs gamma + matrix `nutilde'=J(1,`k',0) + matrix `num'=J(1,`k',0) + matrix `nuobs'=J(1,`k',0) + matrix `gamma'=J(1,`k',0) + forvalues j=1/`k' { + matrix `gamma'[1,`j']=(1+1/`m')*`B'[`j',`j']/`T'[`j',`j'] + matrix `nuobs'[1,`j']=((`nucom'+1)/(`nucom'+3))*`nucom'*(1-`gamma'[1,`j']) + matrix `num'[1,`j']=(`m'-1)*`gamma'[1,`j']^-2 + matrix `nutilde'[1,`j']=1/((1/`num'[1,`j']+1/`nuobs'[1,`j'])) + } + * use all varnames + local names: colnames(`Q1') + matrix colnames `r'=`names' + matrix colnames `nu'=`names' + matrix colnames `lambda'=`names' + matrix colnames `BIF'=`names' + + matrix colnames `gamma'=`names' + matrix colnames `nuobs'=`names' + matrix colnames `num'=`names' + matrix colnames `nutilde'=`names' + + * Li, Raghunathan & Rubin (1991) estimates of T and nu1 + * for F test of Q=0 on k,nu1 degrees of freedom + tempname r1 t1 BW TLRR + matrix `BW'=`B'*syminv(`W') + scalar `r1'=trace(`BW')*(1+1/`m')/`k' + matrix `TLRR'=`W'*(1+`r1') + scalar `t1'=`k'*(`m'-1) + matrix colnames `Q'=`names' + matrix rownames `T'=`names' + matrix colnames `T'=`names' + matrix rownames `B'=`names' + matrix colnames `B'=`names' + matrix rownames `TLRR'=`names' + matrix colnames `TLRR'=`names' + +} +di as text _n "Multiple imputation parameter estimates (`m' imputations)" +if "`lrr'"!="" { + di as text "[Using Li-Raghunathan-Rubin (LRR) estimate of VCE matrix]" + ereturn post `Q' `TLRR', depname(`yname') obs(`nobs') esample(`touse') noclear + ereturn matrix T `T' +} +else { + ereturn post `Q' `T', depname(`yname') obs(`nobs') esample(`touse') noclear + ereturn matrix TLRR `TLRR' +} +if "`br'"=="" { + ereturn display, `eform' + di as result `nobs' as text " observations." +} +ereturn matrix B `B' +ereturn matrix W `W' +ereturn matrix r `r' +ereturn matrix nu `nu' +ereturn matrix lambda `lambda' +ereturn matrix BIF `BIF' + +* Quantities for calculating df `nutilde' according to Barnard & Rubin (1999) +ereturn matrix gamma `gamma' +ereturn matrix nuobs `nuobs' +ereturn matrix num `num' +ereturn matrix nutilde `nutilde' + +ereturn scalar r1=`r1' +ereturn scalar nu1=cond(`t1'>4, 4+(`t1'-4)*(1+(1-2/`t1')/`r1')^2, 0.5*`t1'*(1+1/`k')*(1+1/`r1')^2) +ereturn scalar m=`m' +ereturn scalar chi2=`chi2' +ereturn scalar ll=`ell' +ereturn scalar ll_0=`ell0' +ereturn local eform `eform' +ereturn local impid `impid' +ereturn local cmd `cmd' +ereturn local cmd2 micombine +if "`br'"!="" { + display_t + di as result `nobs' as text " observations." +} +end + +program define display_t +* Display results with t-statistics estimated according to Barnard & Rubin (1999) + tempname V Q nu + matrix `V'=e(V) + matrix `Q'=e(b) + matrix `nu'=e(nutilde) + local yname `e(depvar)' + local xs: colnames `Q' + local k=colsof(`Q') + di as text _n "Intervals and inference based on d.f. from Barnard & Rubin (1999)" + di as txt "{hline 13}{c TT}{hline 64}" + local t0 = abbrev("`yname'",12) + if `"`e(eform)'"'!="" { + local tt "Odds Ratio" + } + else { + local tt " Coef." + } + + #delimit ; + di as text + %12s "`t0'" _col(14)"{c |}`tt' Std. Err. t P>|t| [$S_level% Conf. Intvl] MI.df" + _n "{hline 13}{c +}{hline 64}" ; + #delimit cr + tempname df mn se t p invt l u + forvalues i=1/`k' { + local x: word `i' of `xs' + if "`x'"!="_cons" { + local fmt : format `x' + if substr("`fmt'",-1,1)=="f" { + local fmt="%8."+substr("`fmt'",-2,2) + } + else if substr("`fmt'",-2,2)=="fc" { + local fmt="%8."+substr("`fmt'",-3,3) + } + else local fmt "%8.0g" + local fmt`i' `fmt' + } + else local fmt "%8.0g" + scalar `df' =`nu'[1,`i'] + scalar `mn' = `Q'[1,`i'] + scalar `se' = sqrt(`V'[`i',`i']) + scalar `t' = `mn'/`se' + scalar `p' = 2* ttail(`df', abs(`t')) + scalar `invt' = invttail(`df', (1-$S_level/100)/2) + scalar `l' = `mn' - `invt'*`se' + scalar `u' = `mn' + `invt'*`se' + if `"`e(eform)'"'!="" { + scalar `mn' = exp(`mn') + scalar `se' = `mn'*`se' + scalar `l' = exp(`l') + scalar `u' = exp(`u') + } + if `df'>99999 { + local fmtdf %9.2e + } + else local fmtdf %9.2f + di as text /* + */ %12s abbrev("`x'",12) _col(14) "{c |}" /* + */ _col(17) as res `fmt' `mn' /* + */ _col(27) `fmt' `se' /* + */ _col(36) %7.2f `t' /* + */ _col(42) %7.3f `p' /* + */ _col(52) `fmt' `l' /* + */ _col(61) `fmt' `u' /* + */ _col(70) `fmtdf' `df' + } + di as text "{hline 13}{c BT}{hline 64}" +end + +program define chkrowid, sclass +local I: char _dta[mi_id] +if "`I'"=="" { + di as error "no row-identifier variable found - data may have incorrect format" + exit 198 +} +cap confirm var `I' +local rc=_rc +if `rc' { + di as error "row-identifier variable `I' not found" + exit `rc' +} +sret local I `I' +end diff --git a/Modules/ado/plus/m/micombine.hlp b/Modules/ado/plus/m/micombine.hlp new file mode 100644 index 0000000..a3eaa26 --- /dev/null +++ b/Modules/ado/plus/m/micombine.hlp @@ -0,0 +1,284 @@ +{smcl} +{* 28nov2005}{...} +{hline} +help for {hi:micombine}{right:(SJ5-4: st0067_2; SJ5-2: st0067_1; SJ4-3: st0067)} +{hline} + +{title:Estimation of regression models with multiply imputed samples} + + +{p 8 18 2} +{cmd:micombine} +{{it:supported_regression_cmd} | {it:other_regression_cmd}} +[{it:yvar}] +[{it:covarlist}] +[{it:other_stuff]} +{ifin} +{weight} +[{cmd:,} +{cmd:br} +{cmdab:nocons:tant} +{cmdab:det:ail} +{cmdab:ef:orm}[{cmd:(}{it:string}{cmd:)}] +{cmdab:g:enxb(}{it:newvarname}{cmd:)} +{cmdab:imp:id(}{it:varname}{cmd:)} +{cmd:lrr} +{cmdab:nowar:ning} +{cmdab:obs:id(}{it:varname}{cmd:)} +{it:regression_cmd_options}] + +{p 4 4 2} +where + +{p 8 8 2} +{it:supported_regression_cmd}s are +{helpb clogit}, +{helpb cnreg}, +{helpb glm}, +{helpb logistic}, +{helpb logit}, +{helpb mlogit}, +{helpb ologit}, +{helpb oprobit}, +{helpb poisson}, +{helpb probit}, +{helpb qreg}, +{helpb regress}, +{helpb rreg}, +{helpb stcox}, +{helpb streg}, +or +{helpb xtgee}, and {it:other_regression_cmd} is any other Stata regression command +(see Remarks). + +{p 4 4 2} +{cmd:micombine} shares a subset of the features of all {help estcom:estimation commands}; +see {it:Remarks}. + +{p 4 4 2} +All weight types supported by {it:regression_cmd} are allowed; see +{help weight}. + + +{title:Description} + +{p 4 4 2} +{cmd:micombine} estimates the parameters of a regression model whose +type is determined by {it:supported_regression_cmd} or {it:other_regression_cmd}. +Parameter estimates are combined +across several replicates obtained previously by multiple imputation, +e.g. by using {helpb ice} to create a file of imputed data. +See {it:Remarks} for a brief account of how {cmd:micombine} combines +the estimates and obtains standard errors. + + +{title:Options} + +{p 4 8 2} +{cmd:br} calculates degrees of freedom and tests of significance for each predictor +according to the formulae (3)-(5) of Barnard & Rubin (1999). +After estimation, the required degrees of freedom are stored in a matrix +(column vector) {cmd:e(nutilde)}. Note that if {cmd:test} +is used after {cmd:micombine} for significance testing of regression +coefficients, such tests assume that the degrees of freedom are +equal to the number of observations minus the number of parameters +estimated, not those given in {cmd:e(nutilde)}. + +{p 4 8 2} +{cmd:noconstant} suppresses the regression constant in all regressions. + +{p 4 8 2} +{cmd:detail} gives details of the regression model for each imputation. + +{p 4 8 2} +{cmd:eform}[{cmd:(}{it:string}{cmd:)}] specifies that the exponentiated form +of the coefficients be output and that the constant not be reported. +The exponentiated coefficients are labeled {cmd:exp(b)}, unless +the optional {it:string} is used. + +{p 4 8 2} +{cmd:genxb(}{it:newvarname}{cmd:)} creates {it:newvarname} to hold the +linear predictor from each regression model, averaged over all the +imputations. + +{p 4 8 2} +{cmd:impid(}{it:varname}{cmd:)} specifies that {it:varname} is the variable +identifying the imputations. The number of imputations is determined as +the number of unique values of {it:varname}. All observations for which +{it:varname} takes the value zero are ignored in the analysis. +The default {it:varname} is {cmd:_j}. + +{p 4 8 2} +{cmd:lrr} specifies that the Li-Raghunathan-Rubin (LRR) robust estimate of the +variance-covariance matrix of the regression coefficients be used. + +{p 4 8 2} +{cmd:nowarning} suppresses the warning message about the use +of {it:other_regression_cmd}s (see {it:Remarks}). + +{p 4 8 2} +{cmd:obsid(}{it:varname}{cmd:)} is provided to allow {cmd:micombine} to analyze +datasets created by programs other than {cmd:ice}. {it:varname} specifies the name +of a variable holding the "observation ID", i.e. the sequence number of each +observation in a given imputation. The number of observations should +be identical between imputations, as should the order of the observations. +{it:varname} should run 1,...,N for imputation 1, 1,...,N for imputation 2, and +so on. {cmd:ice} automatically stores the information with the data, so this +option is not required. The default {it:varname} is {cmd:_i}. + +{p 4 8 2} +{it:regression_cmd_options} may be any of the options appropriate to +{it:regression_cmd}. + + +{title:Remarks} + +{p 4 4 2} +Details of statistical inference from multiple imputed datasets are nicely +described in a recent Stata Journal article by John Carlin and colleagues +(Carlin et al. 2003). Here, with due acknowledgment to John, I give an edited +version of section 2 of his article. + +{p 4 4 2} +A simple method of combining estimates from several models was derived by +Rubin (1987). Suppose initially that primary interest lies in estimating a +scalar quantity, Q. Here, Q is a regression coefficient, for example, the log +hazard ratio in a proportional hazards model. Suppose that we have imputed m +complete datasets using an appropriate model. In each dataset, standard +complete-data methods are used to obtain an estimate of Q with an associated +standard error. Let Q(k) and U(k) denote the point estimate and variance +respectively from the kth (k = 1, 2, ... , m) dataset. The point estimate Q^ +of Q from multiple imputation is simply the arithmetic mean of Q(1),...,Q(k). + +{p 4 4 2} +Obtaining a valid standard error for this estimate of Q^ requires combining +information on within-imputation and between-imputation variation. The latter +is important in reflecting uncertainty due to variability between imputation +samples. First, a within-imputation variance component, W, is obtained as the +mean of the complete-data variance estimates, Q(1),....,Q(k). Second, a +between-imputation variance component, B, is calculated as the sum of squares +of Q(1),....,Q(k) about Q^, divided by m-1. The (total) variance T of Q^ is +given by + +{p 8 12 2} +T = W + B * (1 + 1/m) + +{p 4 4 2} +Rubin (1987) showed that (Q - Q^)/sqrt(T) is distributed approximately +as Student's t on nu degrees of freedom, where + +{p 8 12 2} +nu = (m - 1) * (1 + W /(B * (1 + 1/m)))^2 + +{p 4 4 2} +The (1 + 1/m) term in these expressions indicates that it is not necessary to +a create large number of imputed datasets, particularly when B is much smaller +than W. The condition will be satisfied unless there is much missing data and +the parameter estimates within each dataset are very precise. + + {title:Available regression commands} + +{p 4 4 2} +{cmd:micombine} has been tested with the commands listed under +{it:supported_regression_cmd} at the beginning of this help file. +{cmd:micombine} {it:may} work satisfactorily with {it:other_regression_cmd}s, +but this cannot be guaranteed. This facility is provided so that the +researcher familiar with a particular Stata command has a fighting chance of +obtaining correct MI estimates and standard errors. HOWEVER, THE AUTHOR +DISCLAIMS ALL RESPONSIBILITY FOR THE CORRECTNESS OF RESULTS ARISING FROM USE +OF AN {it:other_regression_cmd}. Note that {it:other_stuff} in the syntax +diagram is code that may be required by some {it:other_regression_cmd}s, for +example {cmd:ivreg} wants {cmd:(}{it:varlist2}{cmd: = }{it:varlist_iv}{cmd:)}. +{cmd:micombine} parses for the occurrence of an opening parenthesis. There may +be other syntaxes that are not accommodated by this approach; if so, please +contact the author with details. + + {title:Postestimation prediction} + +{p 4 4 2} +The {cmd:predict} command {it:may} work as you expect after {cmd:micombine}, +but this feature should be regarded as under development and should be +treated with caution. {cmd:micombine} stores the quantities needed by +{cmd:predict} at the last execution of the regression command, that is at the +final imputation, but prediction following some regression commands has +non-standard features that are hard to emulate accurately. +Known issues are as follows: + +{p 8 12 2} +1. After {cmd:micombine mlogit}: {cmd:predict} may require that the outcome + levels are known as 0, 1, 2, ... , so it may be necessary to drop the + score label for the outcome variable, if such a label is defined. + This is KNOWN to be a problem using {cmd:mfx} following {cmd:micombine mlogit}. + For example, {cmd:mfx compute, predict(outcome(0))} will work only if + the lowest level of the outcome is 0, and is not labeled. + +{p 8 12 2} +2. After {cmd:micombine} with a restricted sample (i.e. using {cmd:if}, + {cmd:in} or zero weights for some observations, or some members + of {it:covarlist} still have missing values), the system variable + {cmd:e(sample)} is defined as you would expect it to be + only for the final imputation. In all earlier imputations it + is zero. Although not necessarily convenient for use of + {cmd:e(sample)} in data analysis, the behavior is correct for the + purposes of {cmd:predict}, since the relevant sample size and + estimation sample are properties of (any) one imputation, + but not of the complete assembly of imputations. + + +{title:Examples} + +{p 4 8 2}{cmd:. ice y x1 x2 x3 using imp, m(10) genmiss(m_)}{p_end} +{p 4 8 2}{cmd:. use imp, clear}{p_end} +{p 4 8 2}{cmd:. micombine regress y x1 x2 x3}{p_end} +{p 4 8 2}{cmd:. stset time, failure(cens)}{p_end} +{p 4 8 2}{cmd:. micombine stcox x1 x2 x3, genxb(index)}{p_end} +{p 4 8 2}{cmd:. test x2==1}{p_end} +{p 4 8 2}{cmd:. testparm x1 x2}{p_end} + + +{title:Author} + +{p 4 4 2} +Patrick Royston, MRC Clinical Trials Unit, London. +patrick.royston@ctu.mrc.ac.uk + + +{title:References} + +{p 4 8 2} +Barnard, J. and D. B. Rubin. 1999. Small-sample degrees of freedom with +multiple imputation. {it:Biometrika} 86: 948-955. + +{p 4 8 2} +Carlin, J. B., N. Li, P. Greenwood, and C. Coffey. 2003. +Tools for analyzing multiple imputed datasets. {it:Stata Journal} 3(3): 226-244. + +{p 4 8 2} +Carlin, J. B., N. Li, P. Greenwood, and C. Coffey. 2003. +Tools for analyzing multiple imputed datasets. {it:Stata Journal} 3(3): 226-244. + +{p 4 8 2} +Li, K., T. Raghunathan, and D. Rubin. 1991. Large sample significance levels +from multiply-imputed data using moment-based statistics and an F reference +distribution. {it:Journal of the American Statistical Association} 86: 1065-1073. + +{p 4 8 2} +Rubin, D. 1987. {it:Multiple Imputation for Nonresponse in Surveys}. New York: +Wiley. + +{p 4 8 2} +Schafer, J. 1997. {it:Analysis of Incomplete Multivariate Data}. London: +Chapman & Hall. + +{p 4 8 2} +van Buuren, S., H. C. Boshuizen and D. L. Knook. 1999. Multiple imputation of + missing blood pressure covariates in survival analysis. + {it:Statistics in Medicine} 18: 681-694. + (Also see http://www.multiple-imputation.com.) + + +{title:Also see} + +{psee} +Online: {helpb ice} +{p_end} diff --git a/Modules/ado/plus/m/mijoin.ado b/Modules/ado/plus/m/mijoin.ado new file mode 100644 index 0000000..411fb6e --- /dev/null +++ b/Modules/ado/plus/m/mijoin.ado @@ -0,0 +1,73 @@ +*! version 1.0.3 PR 16oct2004. +* History +* 1.0.3 16oct2004 Saving, using etc of file safest with compound quotes, fixed. + +program define mijoin, rclass +version 7 + +syntax [anything(name=filestub)], CLEAR [ IMPid(string) m(int 0) ] + +if "`filestub'"=="" { + capture assert "$mimps"!="" & "$mi_sf"!="" + if _rc { + di as error "please set up your data with -{help miset}-, or specify a filename stub" + exit 198 + } + local filestub $mi_sf + if `m'>$mimps { + di as err "m cannot exceed its -miset- value of $mimps" + exit 198 + } + if `m'==0 { + local m $mimps + } +} + +if `m'<=0 { + di as err "number of imputations m(), if specified, must be a positive integer" + exit 198 +} + +if "`impid'"=="" { + local J _j +} +else local J `impid' +preserve +quietly { + forvalues j=1/`m' { + use `"`filestub'`j'"', clear + chkrowid + local I `s(I)' + if "`I'"=="" { + * create row number + local I _i + cap drop `I' + gen long `I'=_n + lab var `I' "obs. number" + } + cap drop `J' + gen int `J'=`j' + lab var `J' "imputation number" + tempfile tmp`j' + save `"`tmp`j''"' + } + use `"`tmp1'"', clear + forvalues j=2/`m' { + append using `"`tmp`j''"' + } + char _dta[mi_id] `I' +} +restore, not +end + +program define chkrowid, sclass +local I: char _dta[mi_id] +if "`I'"=="" { + exit +} +cap confirm var `I' +if _rc { + exit +} +sret local I `I' +end diff --git a/Modules/ado/plus/m/mijoin.hlp b/Modules/ado/plus/m/mijoin.hlp new file mode 100644 index 0000000..47ea12a --- /dev/null +++ b/Modules/ado/plus/m/mijoin.hlp @@ -0,0 +1,102 @@ +{smcl} +{* 11jun2004}{...} +{hline} +help for {cmd:mijoin}, {cmd:misplit}{right:(SJ5-4: st0067_2; SJ5-2: st0067_1; SJ4-3: st0067)} +{hline} + +{title:Join or split multiple imputed datasets} + + +{p 8 17 2} +{c -(}{cmd:mijoin} [{it:filestubname}] | {cmd:misplit}{c )-}{cmd:,} +{cmd:clear} +[{cmd:m(}{it:#}{cmd:)} +{cmdab:imp:id(}{it:varname}{cmd:)}] + + +{title:Description} + +{p 4 4 2} +{cmd:mijoin} converts datasets prepared by Carlin's {helpb miset} routine +to {helpb mvis} format, for analysis by {helpb micombine}. The component +datasets are stacked (joined vertically). If {it:filestubname} is +specified then the program will look for files called +{it:filestubname}{cmd:1.dta}, {it:filestubname}{cmd:2.dta},..., +{it:filestubname}{cmd:m.dta} where {cmd:m} is determined by +the {cmd:m()} option. + +{p 4 4 2} +{cmd:misplit} converts a dataset prepared by {helpb mvis} +to {helpb miset} format, for analysis +by {helpb mifit} and other utilities. You should {cmd:use} +the dataset first. + +{p 4 4 2} +The operations performed by {cmd:mijoin} and {cmd:misplit} +are reciprocal. + + +{title:Options} + +{p 4 8 2} +{cmd:clear} is not optional and confirms that you are willing to replace the +data in memory. + +{p 4 8 2} +{cmd:m(}{it:#}{cmd:)} sets the number of imputed datasets to {it:#}. + +{p 4 8 2} +{cmd:impid(}{it:varname}{cmd:)} sets the name of the variable identifying the +imputations to {it:varname} (default is {cmd:_j}). {cmd:mijoin} creates +{it:varname} whereas {cmd:misplit} expects it to exist already. + + +{title:Remarks} + +{p 4 4 2} +After {cmd:mijoin} has been executed, the data are ready for immediate use by +{cmd:micombine}. However, to save the data permanently you would +need to issue a {helpb save} command. + +{p 4 4 2} +After {cmd:misplit} has been executed, the data are ready for immediate use by +Carlin's routines. However, to save the data permanently you would +need to issue a {helpb misave} command followed by {helpb miset} on the next use. + + +{title:Examples} + +{p 4 8 2}{cmd:. mvis y x1 x2 x3 using imp, m(3)}{p_end} +{p 4 8 2}{cmd:. use imp, clear}{p_end} +{p 4 8 2}{cmd:. misplit, clear}{p_end} +{p 4 8 2}{cmd:. mifit regress y x1 x2 x3} + +{p 4 8 2}{cmd:. miset using imp, clear mimps(5)}{p_end} +{p 4 8 2}{cmd:. mijoin, clear}{p_end} +{p 4 8 2}{cmd:. micombine regress y x1 x2 x3} + +{p 4 8 2}{cmd:. mijoin imp, clear m(5)}{p_end} +{p 4 8 2}{cmd:. save imp_mvis}{p_end} +{p 4 8 2}{cmd:. micombine regress y x1 x2 x3} + + +{title:Author} + +{p 4 4 2} +Patrick Royston, MRC Clinical Trials Unit, London. +patrick.royston@ctu.mrc.ac.uk + + +{title:References} + +{p 4 8 2} +Carlin, J. B., N. Li, P. Greenwood, and C. Coffey. 2003. +Tools for analyzing multiple imputed datasets. {it:Stata Journal} 3(3): +226-244. + + +{title:Also see} + +{p 4 13 2} +Online: {helpb mvis}, {helpb micombine}, {helpb miset} (if installed) +{p_end} diff --git a/Modules/ado/plus/m/misplit.ado b/Modules/ado/plus/m/misplit.ado new file mode 100644 index 0000000..9041513 --- /dev/null +++ b/Modules/ado/plus/m/misplit.ado @@ -0,0 +1,53 @@ +*! version 1.0.1 PR 01oct2004. +program define misplit, rclass +version 7 +syntax, CLEAR [ IMPid(string) m(int 5) ] +cap assert `m'>1 +if _rc { + di "{err}more than one imputation is required" + exit 198 +} +if "`impid'"=="" { + local impid _j +} +cap confirm var `impid' +if _rc { + di as err "imputation identifier `impid' not found in file `using'" + exit 601 +} +tempvar J +egen int `J'=group(`impid') +sum `J', meanonly +local m=r(max) +if r(max)<2 { + di as error "more than one imputation is required" + exit 198 +} +if r(max)<`m' { + local m=r(max) + di as text "[note: data for only `m' imputations found in file]" +} +preserve +quietly { + forvalues j=1/`m' { + keep if `J'==`j' + drop `J' + cap erase "_mitemp`j'.dta" + save "_mitemp`j'.dta" + restore, preserve + *egen int `J'=group(`impid') + } + global mi_uf `using' + global mi_sf _mitemp + global mimps `m' + + use _mitemp1.dta, clear +} +if $mimps==2 { + di "{p}{txt}data for $mimps imputations have been copied to _mitemp1.dta and _mitemp$mimps.dta" +} +else { + di _n "{p}{txt}Data for $mimps imputations have been copied to ${mi_sf}1.dta to $mi_sf$mimps.dta" +} +restore, not +end diff --git a/Modules/ado/plus/m/misplit.hlp b/Modules/ado/plus/m/misplit.hlp new file mode 100644 index 0000000..2a7941f --- /dev/null +++ b/Modules/ado/plus/m/misplit.hlp @@ -0,0 +1 @@ +.h mijoin diff --git a/Modules/ado/plus/m/misschk.ado b/Modules/ado/plus/m/misschk.ado new file mode 100644 index 0000000..b9aaaa8 --- /dev/null +++ b/Modules/ado/plus/m/misschk.ado @@ -0,0 +1,211 @@ +*! version 1.1.0 2009-12-22 +* - add extended missing values - s. rohrman + +capture program drop misschk +program define misschk + version 9.0 // 2009-12-22 + syntax [varlist] [if] [in] /// + , [GENerate(string)] /// stub for indicator variables + [dummy] /// dummy indicator variables + [replace] /// replace variables if they exist + [NONUMber] /// . in table for missing, not # + [NOSort] /// Don't sort pattern list + [help] /// explain what is going on + [SPace] /// blank rather than _ if not missing + [EXTmiss] // show extended missing // 1.1.0 + + tempvar ifin + mark `ifin' `if' `in' + + local notmissstr "_" + if ("`space'"=="space") { + local notmissstr " " + } + else if "`nonumber'"=="nonumber" | "`extmiss'"=="extmiss" { // 1.1.0 + local notmissstr "-" + } + local sort "sort" + if "`nosort'"=="nosort" { + local sort "" + } + +// using extmiss and nonumber options together = error // 1.1.0 + + if "`nonumber'"=="nonumber" & "`extmiss'"=="extmiss" { + di in red "Error: cannot use nonumber and extmiss options together." + exit + } + +// if dummy variable option + + if "`dummy'"~="" { + if "`generate'"=="" { + di in red "Error: dummy options requires use of generate option." + exit + } + capture label def lmisschk 0 NotMissing 1 Missing + } + local gennm = "`generate'" + +// information on individual variables + + di _n in g "Variables examined for missing values" + if "`if'" ~="" | "`in'"~="" { + di in g "For sample defined by: " in y "`if' `in'" + } + +// strip off string variables + + parse "`varlist'", parse(" ") + local vars + while "`1'" != "" { // loop through variables + capture confirm numeric variable `1' + if _rc==0 { + local vars "`vars' `1'" + } + mac shift + } + + local varlist "`vars'" + parse "`varlist'", parse(" ") + + local nvar = 0 + + di _n in g " # Variable # Missing % Missing" + di in g "--------------------------------------------" + + quietly tab `ifin' + local total = r(N) + + while "`1'" != "" { // loop through variables + local ++nvar + qui count if `1'>=. & `ifin' // count missing; changed == 1.1.0 + * create binary variables indicating if observation is missing + if "`dummy'"~="" { + if "`replace'"=="replace" { + capture drop `gennm'`1' + } + quietly gen `gennm'`1' = (`1'>=.) if `ifin' // changed == 1.1.0 + label var `gennm'`1' "Missing value for `1'?" + label val `gennm'`1' lmisschk + } + * list # and percent missing + di in y %3.0f " `nvar' " _col(7) "`1'" /// + _col(23) %7.0f r(N) _col(36) %6.1f 100*r(N)/`total' + mac shift + + } // loop through list of variables + + parse "`varlist'", parse(" ") + +// loop through all variables and count missing + + tempvar ismissn ismissw missw missn + quietly gen `missn' = 0 if `ifin' + label var `missn' "Missing for how many variables?" + quietly gen str1 `missw' = "" if `ifin' + label var `missw' "Missing for which variables?" + + local nvar = 0 + local i = 0 + local ext "a b c d e f g h i j k l m n o p q r s t u v w x y z" // 1.1.0 + while "`1'" != "" { + local ++nvar + * ones has only one's digit of variable number + local ones = mod(`nvar',10) + + * drop tempvars from last loop + capture drop `ismissn' `ismissw' + + * 1 if mssing, else 0; . if not in if in + capture quietly gen `ismissn' = (`1'>=.) if `ifin' // changed == 1.1.0 + + * string with indicator of missing status. Space if no missing; + * then if missing, either . or digit number. + capture quietly gen str1 `ismissw' = "`notmissstr'" + if "`nonumber'"=="nonumber" & "`extmiss'"=="" { // 1.1.0 + quietly replace `ismissw' = "." if `1'>=. & `ifin' // changed == 1.1.0 + } + else if "`extmiss'"=="extmiss" & "`nonumber'"=="" { // changed == 1.1.0 + quietly replace `ismissw' = "." if `1'==. & `ifin' + foreach ltr in `ext' { + quietly replace `ismissw' = "`ltr'" if `1'==.`ltr' & `ifin' + } + } + else if "`nonumber'"=="" & "`extmiss'"=="" { + quietly replace `ismissw' = "`ones'" if `1'>=. & `ifin' // changed == 1.1.0 + } + + * add blank every 5th variable + if mod(`nvar'-1,5) == 0 { + quietly replace `missw' = `missw' + " " + } + + * build string with pattern of missing data + quietly replace `missw' = `missw' + `ismissw' + * count total number of missing for given case + quietly replace `missn' = `missn' + `ismissn' + mac shift + } + capture drop `ismissn' `ismissw' + +// List results + + * patterns of missing data + if "`extmiss'"=="" { // 1.1.0 + di _n in y "Warning: " in g /// + "this output does not differentiate among extended missing." + di in g /// + "To generate patterns for extended missing, use extmiss option." + } + if "`help'"=="help" { + di in g _n /// + "The columns in the table below correspond to the # in the table above." + di in g /// + "If a column is blank, there were no missing cases for that variable." + } + if "`help'"=="help" & "`extmiss'"=="extmiss" { //1.1.0 + di _n + di _n in g /// + "Letters in each column refer to the extended missing for the" + di in g /// + "corresponding variable" + } + tab `missw' if `ifin', `nosort' + + * number missing for given observations + if "`help'"=="help" { + di _n in g /// + "Table indicates the number of variables for which an observation" + di in g /// + "has missing data." + } + tab `missn' if `ifin' + +// create variables with pattern and number of missing cases + + if "`generate'" != "" { + + if "`replace'"=="replace" { + capture drop `gennm'pattern + capture drop `gennm'number + } + + clonevar `gennm'pattern = `missw' + clonevar `gennm'number = `missn' + if "`help'"=="help" { + di _n in g "Variables created:" // added end quote 1.1.0 + di in y " `gennm'pattern" in g /// + " is a string variable showing the pattern of missing data." + di in y " `gennm'number" in g /// + " is the number of variables for which a case has missing data." + di in y " `gennm'<varnm>" in g /// + " is a binary variable indicating missing data for <varnm>." + + } + } + +end +exit +* version 1.0.1 06Jul2005 +* version 1.0.0 13Apr2005 diff --git a/Modules/ado/plus/m/misschk.sthlp b/Modules/ado/plus/m/misschk.sthlp new file mode 100644 index 0000000..81ee214 --- /dev/null +++ b/Modules/ado/plus/m/misschk.sthlp @@ -0,0 +1,87 @@ +{smcl} +{* 22Dec2009}{...} +{cmd:help misschk}: Help for misschk - 2009-12-22 +{hline} +{p2colset 4 14 14 2}{...} + +{title:Overview} + +{p 4 4 2 75} +The command {cmd:misschk} examines patterns of missing data for a set of variables. +pattern of missing data. + +{title:Syntax} + +{p 8 13 2} +{cmdab:misschk} [{varlist}] +{ifin} +{weight} +[{cmd:,} +{it:options}] + , [GENerate(string)] /// stub for indicator variables + [dummy] /// dummy indicator variables + [replace] /// replace variables if they exist + [NONUMber] /// . in table for missing, not # + [NOSort] /// Don't sort pattern list + [help] /// explain what is going on + [SPace] /// blank rather than _ if not missing + [EXTmiss] // show extended missing // 1.1.0 + +{synoptset 15 tabbed}{...} +{synopthdr} +{synoptline} + +{synopt:{opt ext:miss}}Each type of extended missing values is indicated +with the letter for that missing value (e.g., {bf:c} for {bf:.c}). By +default all missing values are treated simply as missing and +indicated by a {bf:.}.{p_end} + +{synopt:{opt gen:erate(rootname)}}is the root for the variables created with +information about missing data. If this option is not used, +temporary variables are created that are deleted when the program is +finsihed. The variables created are: + + {it:rootname}{bf:n} is the number of variables from the variable-list for which + a given observation has missing data. For example, a value of 5 would + mean that that observation had missing data for five of the variables + in the list. + + {it:rootname}{bf:which} indicates the pattern of missing values. This is a + string variable with a {bf:_} indicating valid data for a variable + and a number indicating missing data for that variable. For + example, {bf:_____ __8__ _} is the pattern in which there is no + missing data for the first seven variables in the variablae + list, missing data for the eighth, and no missing data for the + ninth through eleventh variable.{p_end} + +{synopt:{opt dummy}}requests that dummy variables be created for each +variable in the variable list. The dummy variable begins with the +stem specified with the {bf:gen()} options, then adds the name of the +variable. A value of 1 indicates missing data for that case, 0 indicates +data is not missing. For example, with the options {bf:gen(M_) dummy}, +variables such as M_female M_income would be generated.{p_end} + +{synopt:{opt nonumber}}specifies that a variable that has missing cases will be +indicated by a {bf:.} rather than by a single digit number corresponding +to the sequence number of that variable. For example, without the +{bf:nonumber} option, a missing data pattern might look like +{bf:_2_4_ 6___} to indicate missing data in the 2nd, 4th and 6th +variables. With the {bf:nonumber} option, the pattern +would be {bf:_._._ .___} .{p_end} + +{synopt:{opt nosort}}specifies that the list of patterns of missing data +should not be sorted with the most common pattern listed first. With +{bf:nosort}, the patterns are listed according to the pattern, not the +frequency of missing data.{p_end} + +{synopt:{opt replace}}replaces existing variables {it:rootname}{bf:n} +and {it:rootname}{bf:which} if they already exist.{p_end} + +{synopt:{opt space}}indicates that in the summary table a space rather than +a {bf:_} will be used to indicate when a variable does not have missing data.{p_end} + + +{synopt:{opt help}}requests a description of each part of the output.{p_end} + +{synoptline} +INCLUDE help spost_footer diff --git a/Modules/ado/plus/m/mlogplot.ado b/Modules/ado/plus/m/mlogplot.ado new file mode 100644 index 0000000..07eab57 --- /dev/null +++ b/Modules/ado/plus/m/mlogplot.ado @@ -0,0 +1,958 @@ +*! version 2.5.0 2009-10-28 jsl +* - stata 11 update for returns from -mlogit- + +capture program drop mlogplot +capture program drop lp_plt +capture program drop getprob + +program define mlogplot + version 6.0 + tempname tmp b sd bstd sdrhs 01rhs sdi ch0 chu chs _lpstdt _lpplt isdum + * if 1, then auto exit of mlogview + global PE_mlerr = 0 + +/* 06Apr2006 - trap 0 category + mat `tmp' = e(cat) + local ncat = e(k_cat) + local i = 1 + while `i' <= `ncat' { + local v = `tmp'[`i',1] + if `v' <= 0 { + di in r "outcome categories cannot be 0 or negative." + di in r "recode outcome variable to begin at 1." + exit + } + local i = `i' + 1 + } +*/ + * 18Nov2005 + local maxvar = 7 + syntax [varlist(default=none)], [/* + */ ORatio DChange Prob(real 1) packed labels /* + */ min(real -99999) max(real 99999) /* + */ matrix Std(string) Vars(string) /* + */ dcadd(real 0) dcbase(real .1) NTics(real 7) /* + */ Basecategory(real -1) Note(string) VALues] /* + */ [saving(string)] [sign] + + * create saving option + local gphopen "gph open" + if "`saving'"~="" { local gphopen "gph open, saving(`saving')" } + + local varis `varlist' + if "`varis'"=="" & "`matrix'"~="matrix" { + _perhs + local varis "`r(rhsnms)'" + } + if `min'>=`max' { + di in r "the minimum is larger than the maximum" + exit + } + * dcplot=1 if dc plot + local dcplot = 0 + if "`dchange'"=="dchange" & "`oratio'"~="oratio" { + local dcplot = 1 + local packed packed + } + * mavar depends on whether there is packing + if "`packed'" == "packed" { + local maxvar = 11 /* max # to plot in packed graph */ + } + +*=> matrix input + + if "`matrix'" == "matrix" { + if `prob'~=1 { + di in r "with matrix input the prob " /* + */ "option does not work." + local prob = 1 + } + if "`dchange'" == "dchange" { + if "`oratio'" ~= "oratio" { + di in r "dchange plots are not " /* + */ "possible with matrix input." + exit + } + di in r "dchange option does not work " /* + */ "with matrix output. option was ignored." + local dchange "" + } + + local depvar "$mnldepnm" + * names of variables to plot + local varis `vars' + * in b, cols are variables, rows are contrasts + mat `b' = mnlbeta + mat `sdrhs' = mnlsd + local nvarp1 = colsof(`b') + 1 /* with constant */ + *todo: check if # of bvarnm is same as cols of b + * variables associated with rows of betas + local bvarnm "$mnlname" + *todo: if doesn't exist, make it all 1's + * columns correspond to columns in betas + mat `sd' = mnlsd + * check size of beta and sd's + local n1 = colsof(`b') + local n2 = colsof(`sd') + if `n1'~=`n2' { + di in r "# of columns in mnlbeta and mnlsd must be equal" + exit + } + } /* if matrix */ + +*=> get information from mlogit + + else { + if "`e(cmd)'"!="mlogit" { + di in r "mlogplot must be run after mlogit or with matrix input" + exit + } + local depvar = e(depvar) + version 5 + mat `b' = get(_b) + version 6 + * 2009-10-28 + tempname eV + _get_mlogit_bv `b' `eV' +*mat list `b' +*mat list `eV' + local bvarnm : colnames(`b') + parse "`bvarnm'", parse (" ") + quietly _pesum, dummy + mat `sdrhs' = r(Ssd) + mat `sdrhs' = `sdrhs'[1,2...] + mat `01rhs' = r(Sdummy) + mat `01rhs' = `01rhs'[1,2...] + + * 16Nov2005 1.6.8 - get range + tempname rngrhs + mat `rngrhs' = r(Smax) - r(Smin) + mat `rngrhs' = `rngrhs'[1,2...] + *< + local nvarp1 = colsof(`b') /* with constant */ + } + local nvar = `nvarp1' - 1 /* excludes constant */ + local ncat = rowsof(`b') + 1 + local maxnvar = 3*`nvar' /* allows each var plotted 3 times */ + /* 0->1, +-1, +-sd */ + if `basecategory' > `ncat' { + di in r "specified base category exceeds number of categories" + exit + } + +*=> get discrete change coefficints +* +* Note: PE_dc - each variable has 5 rows +* row 1: 0->1 (16Nov2005 1.6.8 not min->max) +* row 2: min->max (16Nov2005 1.6.8 which can be 0->1) +* row 3: -/+ 1 +* row 4: -/+ sd +* row 5: not used +* row label is void if coefficient not computed + + * 16Nov2005 1.6.8 - discrete change over range + tempname chr + mat `chr' = J(`nvar',`ncat',0) + + mat `ch0' = J(`nvar',`ncat',0) + mat `chu' = J(`nvar',`ncat',0) + mat `chs' = J(`nvar',`ncat',0) + if "`dchange'" == "dchange" { + + capture local ncol = colsof(PE_dc) + capture local nrow = rowsof(PE_dc) + + if "`ncol'"=="" { + di in r "you must run prchange before " /* + */ "plotting discrete changes" + global PE_mlerr = 1 + exit + } + local nr = `nvar'*5 + +/* TEST: + di "nvar: `nvar'" + di "nvarp1: `nvarp1'" + di "ncat: `ncat'" + di "maxnvar:`maxnvar'" + di "ncol: `ncol'" + di "nrow: `nrow'" + di "nr: `nr'" +END TEST */ + + * size of PE_dc is wrong; probably old PE_dc hanging around + * 26Nov2006 - or prchange run on only some of the rhs variables + if `ncol'~=`ncat' | `nrow'~=`nr' { + di in r "There is a problem with the discrete change " /// + "coefficients. Rerun " in w "prchange" in r "." + di in r "Note that " in w "prchange" in r " must include " /// + "all variables. For example, for the model " + di in w "mlogit occ white ed exper" in r ", run " /// + in w "prchange" in r ", not " in w "prchange white ed" /// + in r "." + global PE_mlerr = 1 + exit + } + local ivar = 1 + local r = 1 + while `ivar' <= `nvar' { + local c = 1 + * loop over outcome categories + while `c' <= `ncat' { + * 16Nov2005 1.6.8 - retrieve dc over range + scalar `tmp' = PE_dc[`r'+1,`c'] + mat `chr'[`ivar',`c'] = `tmp' + * 16Nov2005 1.6.8 retrieve dc from 0 to 1 (same as dc over range) + scalar `tmp' = PE_dc[`r',`c'] + *scalar `tmp' = PE_dc[`r'+1,`c'] + mat `ch0'[`ivar',`c'] = `tmp' + * -/+ 1 + scalar `tmp' = PE_dc[`r'+2,`c'] + mat `chu'[`ivar',`c'] = `tmp' + * -/+ sd + scalar `tmp' = PE_dc[`r'+3,`c'] + mat `chs'[`ivar',`c'] = `tmp' + local c = `c' + 1 + } + local ivar = `ivar' + 1 + local r = `r' + 5 + } + } /* if dchange */ + +*=> parse variables to plot and check if dummy variable + mat `_lpplt' = J(`maxnvar',1,0) /* 1 if plot this coef */ + mat `isdum' = J(`maxnvar',1,0) /* 1 if dummy variable */ + parse "`varis'",parse(" ") /* varis==variables to be plot */ + local ntoplot = 0 + while "`1'"~="" { + if `ntoplot' >= `maxvar' { + di in r "only `maxvar' variables can be " /* + */ "plotted in one graph" + exit + } + * check selected name is in beta matrix + local i 1 + local okvarn = 0 + while `i' <= `nvar' { + * bvarnm contains names from beta matrix + local vnm : word `i' of `bvarnm' + if "`1'"=="`vnm'" { local okvarn = `i' } + local i = `i' + 1 + } + if `okvarn'==0 { + di in red "`1' was not a variable in mlogit" + exit + } + local ntoplot = `ntoplot' + 1 + if "`matrix'" ~= "matrix" { + mat `isdum'[`ntoplot',1] = `01rhs'[1,`okvarn'] + } + * plot variables in this order + mat `_lpplt'[`ntoplot',1] = `okvarn' + macro shift + } + +*=> parse standardization type for each variable + + mat `_lpstdt' = J(`maxnvar',1,0) /* Plot: 1=unstd; 3=std; 2=0/1 */ + local i 1 + local nstd = length("`std'") + while `i' <= `nstd' { + local stdi = substr("`std'",`i',1) + + * 16Nov2005 1.6.8 - allow r as an option for how to plot variable + if "`stdi'"~="r" & "`stdi'"~="s" & "`stdi'"~="u" & "`stdi'"~="0" { + di in r "std() options must be s, r, u or 0" + * if "`stdi'"~="s" & "`stdi'"~="u" & "`stdi'"~="0" { + * di in r "std() options must be s, u or 0" + exit + } + mat `_lpstdt'[`i',1] = 1 /* unstd */ + if "`stdi'" == "s" { + mat `_lpstdt'[`i',1] = 3 /* std */ + } + + * 16Nov2005 1.6.8 - if range, type 4 coefficients + if "`stdi'" == "r" { + mat `_lpstdt'[`i',1] = 4 /* min max */ + } + + if "`stdi'" == "0" { + mat `_lpstdt'[`i',1] = 2 /* dummy */ + if `isdum'[`i',1]~=1 { + di in r "variable specified as std(0) " /* + */ "is not a binary variable" + exit + } + } + * warning if isdum and not 0 + if `isdum'[`i',1]==1 & `_lpstdt'[`i',1]~=2 { + local tmp = `_lpplt'[`i',1] + local vnm : word `tmp' of `bvarnm' + di in r "warning: variable `vnm'" /* + */ " is binary, but std(0) was not used" + } + local i = `i' + 1 + } + if `ntoplot'~=`nstd' { + di in r "# of variables does not match # of " /* + */ "std() values specified" + exit + } + +*=> set up matrices with plot data + + tempname _lpbplt _lpbvar _lpbcat _lpboff _lpbtyp _lpbchk _lpbchp + local tmp = `ntoplot' * `ncat' /* # coefs to plot */ + matrix `_lpbplt' = J(`tmp',1,0) /* coef to plot */ + matrix `_lpbchp' = `_lpbplt' /* values of discrete change */ + matrix `_lpboff' = `_lpbplt' /* vertical offset */ + matrix `_lpbvar' = `_lpbplt' /* variable number */ + matrix `_lpbcat' = `_lpbplt' /* category */ + matrix `_lpbtyp' = `_lpbplt' /* type of standardization */ + + * compute standardized betas + mat `bstd' = `b' + local ivar = 1 + while `ivar' < `nvarp1' { + scalar `sdi' = `sdrhs'[1,`ivar'] + * loop over categories and fill in border + local icat = 1 + while `icat' < `ncat' { + mat `bstd'[`icat',`ivar'] = `b'[`icat',`ivar'] * `sdi' + local icat = `icat' + 1 + } + local ivar = `ivar' + 1 + } + + * 2007-06-29 + if "`matrix'" != "matrix" { + * 16Nov2005 1.6.8 - compute beta*range + tempname brng + mat `brng' = `b' + local ivar = 1 + while `ivar' < `nvarp1' { + scalar `sdi' = `rngrhs'[1,`ivar'] + * loop over categories and fill in border + local icat = 1 + while `icat' < `ncat' { + mat `brng'[`icat',`ivar'] = `b'[`icat',`ivar'] * `sdi' + local icat = `icat' + 1 + } + local ivar = `ivar' + 1 + } + } + else { + // make range missing since it is not used + tempname brng + mat `brng' = `bstd' * . + } // 2007-06-29 + + * determine basecategory + if "`matrix'"~="matrix" { + _pecats `e(depvar)' + local catnm "`r(catnms)'" + * 30Mar2005 1.6.6 + if "`values'"=="values" { + local catnm "`r(catvals)'" + } + + * refnum is value of the reference category for the estiamted betas + * 2007-06-29 stata 10 + if c(stata_version) < 10 { + local refnum = e(basecat) + } + else { + local refnum = e(baseout) + } + + * 1.7.0 08Apr2006 - fix when refnum is 0 + if `refnum'==0 { + local refnum = 1 + } + + * names of outcome categories in order of matrix + * all but the last correspond to the rows in b + } + + if "`matrix'"=="matrix" { + local catnm "$mnlcatnm" + local refnum "`ncat'" + } + +*=> stack b coefficients to plot into _lpbplt vector + + * determine offset for plot + * baserow has the row in b with beta's for new base category + local baserow = 0 + * `basecategory' has the # of the specified base + if `basecategory'~=`refnum' & `basecategory'~=-1 { + local baserow = `basecategory' + if `basecategory' > `refnum' { local baserow = `baserow' - 1 } + } + * loop through variables, decide on std and unstd to plot + local iloc = 1 + local ivar = 1 + while `ivar' <= `ntoplot' { + local icat = 1 + local varnum = `_lpplt'[`ivar',1] + * find b values for changing basecategory + local bbase = 0 + local bbstd = 0 + * 16Nov2005 1.6.8 + local bbrng = 0 + + if `baserow' ~= 0 { + local bbase = `b'[`baserow',`varnum'] + local bbstd = `bstd'[`baserow',`varnum'] + * 16Nov2005 1.6.8 + local bbrng = `brng'[`baserow',`varnum'] + } + * compute _lpbplt + while `icat' <= `ncat' { + if `icat' < `ncat' { + matrix `_lpbplt'[`iloc',1] = `b'[`icat',`varnum'] - `bbase' + } + else { + matrix `_lpbplt'[`iloc',1] = 0 - `bbase'/* ref category */ + } + matrix `_lpbtyp'[`iloc',1] = 1 + matrix `_lpbchp'[`iloc',1] = `chu'[`varnum',`icat'] + if `_lpstdt'[`ivar',1] == 2 { + matrix `_lpbtyp'[`iloc',1] = 2 + matrix `_lpbchp'[`iloc',1] = `ch0'[`varnum',`icat'] + } + if `_lpstdt'[`ivar',1] == 3 { + if `icat' < `ncat' { + matrix `_lpbplt'[`iloc',1] = /* + */ `bstd'[`icat',`varnum'] - `bbstd' + } + else { + matrix `_lpbplt'[`iloc',1] = /* + */ 0 - `bbstd' /* reference category */ + } + matrix `_lpbtyp'[`iloc',1] = 3 + matrix `_lpbchp'[`iloc',1] = `chs'[`varnum',`icat'] + } + + * 16Nov2005 1.6.8 - coefficients when change over range + if `_lpstdt'[`ivar',1] == 4 { + if `icat' < `ncat' { + matrix `_lpbplt'[`iloc',1] = /* + */ `brng'[`icat',`varnum'] - `bbrng' + } + else { + matrix `_lpbplt'[`iloc',1] = /* + */ 0 - `bbrng' /* reference category */ + } + matrix `_lpbtyp'[`iloc',1] = 4 + matrix `_lpbchp'[`iloc',1] = `chr'[`varnum',`icat'] + } + + * _lpbplt now has coefficients to be plotted + matrix `_lpbvar'[`iloc',1] = `ivar' /* var# for given coef */ + matrix `_lpbcat'[`iloc',1] = `icat' /* cat# for tiven coef */ + local iloc = `iloc' + 1 + local icat = `icat' + 1 + } + local ivar = `ivar' + 1 + } + + if `dcplot' == 1 { /* dcplot , so plot _lpbchp */ + matrix `_lpbplt' = `_lpbchp' + } + +*=> determine offsets for letters + +* algorithm is use offsets of 0,1,2,0,1,2 as coefficients are ordered +* from smallest to largerst. The code is messy, but works... + + * if packed, use 0's already in _lpboff + if "`packed'" ~= "packed" { + local iloc = 1 + local ivar = 1 + while `ivar' <= `ntoplot' { + local varnum = `_lpplt'[`ivar',1] + * grab coefficients for given variable in _lpbplt + local istrt = ((`ivar'-1)*`ncat') + 1 + local iend = `istrt' + `ncat' - 1 + matrix `_lpbchk' = `_lpbplt'[`istrt'..`iend',1] + local icat = 1 + while `icat' <= `ncat' { + local icat2 = 1 + local minn = 99999999 + * find smallest coef that hasn't been used + while `icat2' <= `ncat' { + if `_lpbchk'[`icat2',1] < `minn' { + local minn = `_lpbchk'[`icat2',1] + local minloc = `icat2' + } + local icat2 = `icat2' + 1 + } + * this is current smallest + local updown = mod(`icat'+2,3) + * change to big values so won't select again + mat `_lpbchk'[`minloc',1] = 99999999 + local minn = 99999999 + * this is the location in the stored variables + local ichng = `istrt' + `minloc' - 1 + mat `_lpboff'[`ichng',1] = `updown' + local iloc = `iloc' + 1 + local icat = `icat' + 1 + } + local ivar = `ivar' + 1 + } + } + +*=> create variables from the matrices + + mat colnames `_lpbplt' = _lpbplt + mat colnames `_lpbvar' = _lpbvar + mat colnames `_lpbcat' = _lpbcat + mat colnames `_lpboff' = _lpboff + mat colnames `_lpbtyp' = _lpbtyp + mat colnames `_lpbchp' = _lpbchp + mat colnames `_lpplt' = _lpplt + mat colnames `_lpstdt' = _lpstdt + + svmat `_lpbplt', names(col) + svmat `_lpbvar', names(col) + svmat `_lpbcat', names(col) + svmat `_lpboff', names(col) + svmat `_lpbtyp', names(col) + svmat `_lpbchp', names(col) + svmat `_lpplt', names(col) + svmat `_lpstdt', names(col) + +*=> generate variable with first letter of category names + + if "`matrix'"~="matrix" { + local ltr : word `refnum' of `catnm' + local ltr = upper(substr("`ltr'",1,1)) + quietly generate str1 _lpbltr = "`ltr'" + local icat = 1 + while `icat' <= `ncat' { + if `icat'==`refnum' { + local refnm: word `ncat' of `catnm' + if `baserow'~=0 { + local refnm: word `baserow' of `catnm' + } + } + if `icat'!=`refnum' { + local nm: word `icat' of `catnm' + local ltr = upper(substr("`nm'",1,1)) + quietly replace _lpbltr = "`ltr'" if _lpbcat == `icat' + } + local icat = `icat' + 1 + } + } + + if "`matrix'"=="matrix" { + * this is the reference category in the betas + local ltr : word `ncat' of `catnm' + local ltr = upper(substr("`ltr'",1,1)) + quietly generate str1 _lpbltr = "`ltr'" + * get letter for reference category + local baserow = `basecategory' + if `baserow' == -1 { local baserow = `ncat' } + local refnm : word `baserow' of `catnm' + * place correct letters to plot + local icat = 1 + while `icat' <= `ncat' { + if `icat'!=`refnum' { + local nm: word `icat' of `catnm' + local ltr = upper(substr("`nm'",1,1)) + quietly replace _lpbltr = "`ltr'" if _lpbcat == `icat' + } + local icat = `icat' + 1 + } + } + +*=> data to pass to plot program + + global S_1 = `dcplot' + global S_2 = `min' + global S_3 = `max' + global S_4 "`packed'" + global S_5 = `ntoplot' + global S_6 = `dcadd' + global S_7 = `dcbase' + global S_8 = `ncat' + global S_9 "`labels'" + global S_10 "`dchange'" + global S_11 "`bvarnm'" + global S_12 = `prob' + global S_13 "`refnm'" + global S_14 = `ntics' + global S_15 "`note'" + global S_16 "`depvar'" + global S_17 "`gphopen'" + * 16Nov2005 sign + global S_18 = 0 + if "`sign'"=="sign" { + global S_18 = 1 + } + lp_plt + capture drop _lpbplt-_lprowb +end + +program define lp_plt + * decode information from calling program + local dcplot = $S_1 + local min = $S_2 + local max = $S_3 + local packed "$S_4" + local ntoplot = $S_5 + local dcadd = $S_6 + local dcbase = $S_7 + local ncat = $S_8 + local labels "$S_9" + local dchange "$S_10" + local bvarnm "$S_11" + local prob = $S_12 + local refnm "$S_13" + local ntics = $S_14 + local note "$S_15" + local depvar "$S_16" + local gphopen "$S_17" + * 16Nov2005 sign + local addsign = $S_18 + + * coordinate used: + * + * (0,0) (0,cstrt) (0,cend) + * + * (rhead,cstrt) data (rhead,cend) + * + * (rhead+rvar,cstrt) (rhead+rvar,cend) + * + local cstrt = 10000 /* first column in plot space */ + local cborder = 1000 /* border at ends of plot space */ + local cend = 31500 /* right most column of plot space */ + local crange = `cend' - `cstrt' - (2*`cborder') + local cname = `cstrt' - 700 /* name of variable ends here */ + *local rhead = 2000 /* header space for factor change scale */ + local rhead = 1800 /* header space for factor change scale */ + if `dcplot'==1 { local rhead = 1000 } + if "`note'"~="" { + local rhead = `rhead' + 1000 + } + + * rows per variable in plot space + * local rvar = 3600 /* maxvar = 5 */ + * local rvar = 3200 /* maxvar = 6 */ + local rvar = 2800 /* maxvar = 7 */ + + if "`packed'" == "packed" { local rvar = 1700 } + + local rnmoff = 1000 - `rvar' /* vert offset for listing name */ + + * vert offset within horizontal lines (larger adds vertical compression + local rltoff = 800 + + * rescale to metric used in columns of plot and find 0 location + quietly sum _lpbplt /* get min and max of coefficients being plotted */ + local minb = _result(5) + if `min'~=-99999 & `min'<`minb' { local minb = `min' } + local maxb = _result(6) + if `max'~=99999 & `max'>`maxb' { local maxb = `max' } + local rng = `maxb' - `minb' + * change range to [0-1] + quietly generate _lpcolb = (_lpbplt - `minb')/`rng' + local c0 = (0 - `minb')/`rng' + * min and max column for plotting area + local minn = `cstrt' + `cborder' + local maxx = `cend' - `cborder' + local rng = `maxx' - `minn' + quietly replace _lpcolb = (_lpcolb * `rng') + `minn' + local c0 = (`c0' * `rng') + `minn' + + * rescale metric for rows in plot + * # of rows to contain letters + local rltr = `rvar' - `rltoff' - `rltoff' + if "`packed'" ~= "packed" { + quietly sum _lpboff + local minn = _result(5) + local maxx = _result(6) + local rng = `maxx' - `minn' + * change to range of 0--1 + quietly generate _lprowb = (_lpboff - `minn')/`rng' + * expand to range of rltr + quietly replace _lprowb = _lprowb * `rltr' /* offsets as # of rows */ + * determine row position + #delimit ; + quietly replace _lprowb = _lprowb + + `rhead' /* skip over header */ + + ((_lpbvar-1)*`rvar') /* space over prior variables */ + + `rltoff' /* space before letters begin */ + ; + #delimit cr + quietly sum _lprowb + } + else if "`packed'" == "packed" { + local rltoff = 925 /* vert offset top & bot for letters */ + * determine row position + #delimit ; + quietly generate _lprowb = `rhead' /* skip over header */ + + ((_lpbvar-1)*`rvar') /* space over prior variables */ + + `rltoff' /* space before letters begin */ + ; + #delimit cr + } + + `gphopen' + gph font 600 300 + if "`note'"~="" { + local tmp = `cstrt' - 400 + gph text 480 `tmp' 0 -1 `note' + } + local rloc = `rhead' - 200 + * axis at top of graph + gph line `rloc' `cstrt' `rloc' `cend' + * add labels at top and bottom + gph font 500 250 + local rloc = `rhead' - 1400 + if `dcplot' == 0 { + local ltr "`refnm'" + * move top label down a smidge + local rloctmp = `rloc' + 250 + gph text `rloctmp' `cstrt' 0 -1 /* + */ Factor Change Scale Relative to Category `ltr' + local rloc = `rhead' + (`ntoplot'*`rvar') + 1200 + local tmp "" + * if "`depvar'" ~= "" { local tmp " of `depvar'" } + local ltr "`refnm' `tmp'" + gph text `rloc' `cstrt' 0 -1 /* + */ Logit Coefficient Scale Relative to Category `ltr' + } + if `dcplot' == 1 { + local rloc = `rhead' + (`ntoplot'*`rvar') + 1200 + *! version 1.6.5 2/24/2003 - correct typo in graph + local tmp "Change in Predicted Probability for $S_16" + gph text `rloc' `cstrt' 0 -1 `tmp' + } + * add tic marks + local nper = (`maxb' - `minb')/(`ntics' - 1) + local itic = 1 + local minn = `cstrt' + `cborder' + local maxx = `cend' - `cborder' + local cper = (`maxx' - `minn')/(`ntics' - 1) + while `itic' <= `ntics' { + local ticval : display round(exp(`minb' + ((`itic'-1)*`nper')),.01) + local cval = `minn' + ((`itic'-1)*`cper') + local rloc = `rhead' - 600 + * write tic value at top + local rloctmp = `rloc' + 200 /* move it down a smidge */ + if `dcplot' ==0 { gph text `rloctmp' `cval' 0 0 `ticval' } + * add tic marks + local rlst = `rhead' - 200 + local rlend = `rlst' + 150 + gph line `rlst' `cval' `rlend' `cval' + local rlst = `rhead' + (`ntoplot'*`rvar') - 200 + local rlend = `rlst' - 150 + gph line `rlst' `cval' `rlend' `cval' + local ticval : display round(`minb' + ((`itic'-1)*`nper'),.01) + local itic = `itic' + 1 + local rloc = `rhead' + (`ntoplot'*`rvar') + 400 + gph text `rloc' `cval' 0 0 `ticval' + } + local rloc = `rhead' + (`ntoplot'*`rvar') - 200 + gph line `rloc' `cstrt' `rloc' `cend' + if `dcplot' == 1 { + local rt = `rhead' - 200 + gph line `rt' `c0' `rloc' `c0' + } + + * plot letters + local i 0 + local ivar 1 + local dcbase = sqrt(`dcbase') + while `ivar' <= `ntoplot' { /* loop over variables */ + local icat 1 + while `icat' <= `ncat' { /* loop over categories within vars */ + local i = `i' + 1 + * get point to plot + local r = _lprowb[`i'] + local c = _lpcolb[`i'] + local l = _lpbltr[`i'] + local siz 1 + if "`dchange'" == "dchange" & `dcplot' == 0 { + local siz = sqrt(`dcadd'+abs(_lpbchp[`i']))/`dcbase' + } + local fr = `siz'*700 + local fc = `siz'*350 + gph font `fr' `fc' + + * 16Nov2005 option sign + if _lpbchp[`i']<0 & `addsign'==1 { + gph text `r' `c' 0 0 _ + * local l "-`l'" + } + + gph text `r' `c' 0 0 `l' + local icat = `icat' + 1 + } + local ivar = `ivar' + 1 + } + + * add names and dividing lines + local ivar = 1 + while `ivar' <= `ntoplot' { + * name of variable + local varnum = _lpplt[`ivar'] + if `dcplot' == 0 & `prob'~= 1 { + * get prob values + global S_1 = `varnum' /* variable number */ + global S_2 = `ncat' + getprob + local cat1 2 + while `cat1' <= `ncat' { + * location in data set of coordinates for this coef + local loc1 = ((`ivar'-1)*`ncat')+`cat1' + local r1 = _lprowb[`loc1'] + local c1 = _lpcolb[`loc1'] + local cat2 1 + while `cat2' < `cat1' { + local loc2 = ((`ivar'-1)*`ncat')+`cat2' + local r2 = _lprowb[`loc2'] + local c2 = _lpcolb[`loc2'] + local p = mlplt_p[`cat1',`cat2'] + if `p' > `prob' { gph line `r1' `c1' `r2' `c2' } + local cat2 = `cat2' + 1 + } /* `cat2' < `cat1' */ + local cat1 = `cat1' + 1 + } /* `cat1' < `ncat' */ + } /* if get prob */ + local vname: word `varnum' of `bvarnm' + if "`labels'" == "labels" & "`matrix'"~="matrix" { + local vname2 : variable label `vname' + if "`vname2'"!="" { local vname "`vname2'"} + } + local rloc = `rhead' + `rnmoff' + (`ivar'*`rvar') + gph font 700 350 + local _lpstdt = _lpstdt[`ivar'] + if "`packed'" == "packed" { + if `_lpstdt' == 3 { + gph text `rloc' `cname' 0 1 `vname'-std + } + else if `_lpstdt' == 2 { + gph text `rloc' `cname' 0 1 `vname'-0/1 + } + else if `_lpstdt' == 1 { + gph text `rloc' `cname' 0 1 `vname' + } + * 16Nov2005 1.6.8 - label for dc over range + else if `_lpstdt' == 4 { + gph text `rloc' `cname' 0 1 `vname'-range + } + } + if "`packed'" ~= "packed" { + gph text `rloc' `cname' 0 1 `vname' + gph font 400 200 + local rloc = `rhead' + `rnmoff' + (`ivar'*`rvar') + 900 + if `_lpstdt' == 1 { + gph text `rloc' `cname' 0 1 UnStd Coef + } + if `_lpstdt' == 2 { + gph text `rloc' `cname' 0 1 0/1 + } + if `_lpstdt' == 3 { + gph text `rloc' `cname' 0 1 Std Coef + } + * 16Nov2005 1.6.8 - label for or over range + else if `_lpstdt' == 4 { + gph text `rloc' `cname' 0 1 Range Coef + } + } + * dividing line + if `ivar' != 1 { + local rloc = `rhead' + ((`ivar'-1)*`rvar') - 200 + gph line `rloc' `cstrt' `rloc' `cend' + } + local ivar = `ivar' + 1 + } + gph close +end + +program define getprob + * get the prob values for all contrasts + version 5.0 + tempname b v b1 b2 b12 se z p + local ivar = $S_1 + local ncat = $S_2 + matrix `b' = get(_b) + local nvars = colsof(`b') + mat `v' = get(VCE) + * 2009-10-28 - fix for stata 11 returns + nobreak { + _get_mlogit_bv `b' `v' + local nvars = colsof(`b') + } +/* TEST + di "nvars: `nvars'" + di "ncat: `ncat'" + di "v with fix" + mat list `v' + di "b with fix" + mat list `b' +END TEST */ + matrix mlplt_p = J(`ncat',`ncat',1) + * loop through all pairs of categories + local cat1 1 + local cat2 1 + while `cat1' <= `ncat' { + while `cat2' <= `cat1' { + if `cat1'!=`cat2' { + * 1st element of contrast is not ref cat + if `cat1'!=`ncat' { + if `cat2'==`ncat' { scalar `b2' = 0 } + else { scalar `b2' = `b'[`cat2',`ivar'] } + scalar `b1' = `b'[`cat1',`ivar'] + scalar `b12' = `b1'-`b2' + local loc2 = ((`cat2'-1)*`nvars')+`ivar' + if `cat2'==`ncat' { + scalar `se' = sqrt(`v'[`loc1',`loc1']) + } + else { + local loc1 = ((`cat1'-1)*`nvars')+`ivar' + scalar `se' = sqrt(`v'[`loc1',`loc1'] + /* + */ `v'[`loc2',`loc2'] - 2*`v'[`loc1',`loc2']) + } + } /* `cat1'!=`ncat' */ + * first element of contrast is reference category + if `cat1'==`ncat' { + if `cat2'==`ncat' { scalar `b2' = 0 } + else { scalar `b2' = `b'[`cat2',`ivar'] } + scalar `b1' = 0 /*`b'[`cat1',`ivar']*/ + scalar `b12' = `b1'-`b2' + local loc2 = ((`cat2'-1)*`nvars')+`ivar' + scalar `se' = sqrt(`v'[`loc2',`loc2']) + } + scalar `se' = 1/`se' + scalar `z' = `se'*`b12' + scalar `p' = 2*normprob(-abs(`z')) + matrix mlplt_p[`cat1',`cat2'] = `p' + matrix mlplt_p[`cat2',`cat1'] = `p' + } /* if `cat1'!=`cat2' */ + local cat2 = `cat2' + 1 + } /* while `cat2' <= `ncat' */ + local cat2 1 + local cat1 = `cat1' + 1 + } /* cat1 */ + +end +exit + +* version 1.6.4 3/22/2001 +* version 1.6.5 2/24/2003 - correct typo in graph +* version 1.6.6 30Mar2005 - add values option +* version 1.6.7 13Apr2005 +* version 1.6.8 allow plots for change over range 16Nov2005 +* add: option sign: underline negative discrete change +* option r : for range +* version 1.6.9 error if outcome cat <= 0 +* version 1.7.0 08Apr2006 fixed when basecategory is 0! +* version 1.7.1 26Nov2006 +* improve error message when prchange is a problem. +* version 1.7.2 29Jun2007 // fix range problem if data is a matrix +* version 1.7.3 29Jun2007 // stata 10 revisions diff --git a/Modules/ado/plus/m/mlogplot.hlp b/Modules/ado/plus/m/mlogplot.hlp new file mode 100644 index 0000000..a87b9b8 --- /dev/null +++ b/Modules/ado/plus/m/mlogplot.hlp @@ -0,0 +1,157 @@ +.- +help for ^mlogplot^ - 03Nov2005 +.- + +Odds ratio and discrete change plots for multinomial logit +---------------------------------------------------------- + +For odds ratio plots, the results of ^mlogit^ must be in memory; for discrete +change plots or odds ratio plots using discrete change the results of ^prchange^ +must be in memory. The syntax is: + + ^mlogplot^ [varlist] [^, or^atio ^dc^hange ^s^td^(^[^s^|^u^|^0^]...[^s^|^u^|^0^]^)^ + ^min(^#^) max(^#^) packed labels p^rob^(^#^) b^asecategory^(^#^)^ + nt^ics^(^#^) n^ote^(^string^)^ ^val^ues ^dcadd(^#^) ^saving(^filename[^,replace^]^)^] + +To create odds ratio plots with coefficients that you have placed into +matrices (e.g.,to plot coefficients from a published paper): + + ^mlogplot,^ ^matrix v^ars^(^varlist^)^ ^s^td^(^[^s^|^u^|^0^]...[^s^|^u^|^0^]^)^ + [^min(^#^) max(^#^) packed labels b^asecategory^(^#^) nt^ics^(^#^) n^ote^(^string^)^ + ^saving(^filename[^,replace^]^)^] + +The matrices you must create are discussed below. + +Description +----------- + +^mlogplot^ takes coefficients either from ^mlogit^ or from other programs that +estimate the multinomial logit model. When estimates from other programs are +used they must be passed to ^mlogplot^ as matrices. ^mlogplot^ then plots the +odds ratios (i.e., exp(b)) and/or the discrete change coefficients. You can +list the same variable more than once if you want both standardized and +unstandardized coefficients to be plotted in the same graph. A variety of +options control the way the final graph looks. The dialog box program ^mlogview^ +provides a convenient front end that allows you to use this program +interactively. + +^IMPORTANT^: When using coefficients from ^mlogit^, you must be sure that the +value labels for the dependent variable begin with different letters or +numbers. Otherwise, the plot might be misleading. + +Options for Plotting Estimates from ^mlogit^ +--------------------------------------------- + +^oratio^ indicates that you want to plot the odds ratios (i.e., exp(b)). + +^dchange^ requests plots involving discrete change. To use this option, you + must have first run ^prchange^. This option does not work with the ^matrix^ + option. + + If ^oratio^ has been specified, this options plots the size of the letters + proportional to the size of the corresponding discrete change coefficient. + See ^dcadd^ and ^dcbase^ for further details. + + If ^oratio^ is not specified, ^dchange^ indicates that you want to plot the + discrete change coefficients. + +^basecategory^ is used for an odds ratio plot to specify which category of + the outcome measure is to be used as the reference point. + +^labels^ uses variable labels to label each row of the plot. You might need to + revise your variable labels to make them fit the graph. This option does + not work with the ^matrix^ option. + +^min(^#^) and max(^#^)^ specify the minimum value and the maximum value on which + the coefficients are plotted. This is useful if you want to compare + coefficients from different logits, or produces several plots from the + same logit. + +^ntics^ sets the number of tic marks to show on the axes. Used along with ^min^ + and ^max^, this allows you to determine the numbering on the axes and the + location of tic marks. + +^packed^ removes the vertical spacing among the outcome categories. This allows + up to 11 variables on a single graph. Otherwise, the maximum is 5. + +^prob^ is used for an odds ratio plot to specify that if a coefficient + contrasting two outcomes is not signficant at this level, a line is to + be drawn connecting the letters. + +^std(^[^s^|^u^|^0^]...[^s^|^u^|^0^]^)^ specifies the type of coefficient to plot. s specifies + standardized coefficients; u specifies unstandardized coefficients; 0 + specifies changes from 0 to 1 in discrete change plots. For example, + std(u0su) indicates that the first variable is unstandardized, the second + is binary, the third standardized, and the last is unstandardized. + +^dcadd(^#^)^ is rarely used. In odds ratio plots where + the ^dchange^ option is specified, the size of the letter corresponds to + the square root of the size of the discrete change coefficient. ^dcadd^ adds + an amount to each discrete change making the size of all letters larger, + making it easier to see the letters for small discrete changes. By + default this quantity is 0. If your letters print too small, you might + want to increase this by a small amount, say ^dcadd(.03)^. + +Plotting Estimates from Matrices +-------------------------------- + +The ^matrix^ option indicates that estimates are to be obtained from global +matrices, which are described below. When this option is used, the options +^prob^ and ^dchange^ are not allowed. All other options can be used. + +^vars(varlist)^ contains the names of the variables whose coefficients you + want to plot. The names must be in the order you want to plot them and + must be included in the global ^mnlname^. + +Globals for Plotting Matrices +----------------------------- + +^mnlbeta^ contains the betas in a matrix where element (i,j) is the j-th + variable for comparison i relative to the reference category. That is, + columns are for variables; rows for different contrasts. Note that + constants are NOT included. + +^mnlname^ contains the names of the variables corresponding to the columns of + mnlbeta. + +^mnlcatnm^ is a string with labels for the outcome categories. The + 1st category corresponds to the 1st column of mnlbeta, the 2nd to the + 2nd, etc. The label for the reference category should be last. Thus, + mnlcatnm provides labels for the rows of mnlbeta. The option + ^basecategory^ references which letter in this string represents the + base category. + +^mnlrefn^ is the number of the category in mnlcatnm that is the reference + category for the contrasts contained in mnlbeta. + +^mnldepnm^ contains name of dependent variable. + +^mnlsd^ contains the standard deviations for the variables that correspond + to columns of mnlbeta + +Example using mlogit +-------------------- + + . ^mlogit occ white ed exper,basecategory(5)^ + . ^prchange^ + . ^mlogplot white ed exper, dc std(0ss) min(-2.75) max(.55)^ + +Example using matrices +---------------------- + + . ^matrix mnlsd = (2.946427, 13.95936, 2.946427, 13.95936)^ + . ^global mnlname = "W_Educ W_Exper NW_Educ NW_Exper"^ + . ^global mnlrefn = 5^ + . ^global mnlcatnm = "Menial BlueC Craft WhiteC Prof"^ + . ^matrix mnlbeta = (-.83075, -.92255, -.68761, -.41964 \ /*^ + > ^*/ -.03380, -.03145, -.00026, .00085 \ /*^ + > ^*/ -.70126, -.56070, -.88250, -.53115 \ /*^ + > ^*/ -.11084, -.02611, -.15979, -.05209 )^ + . ^matrix mnlbeta = mnlbeta'^ + . ^mlogplot, vars(W_Educ NW_Educ W_Exper NW_Exper) matrix /*^ + > ^*/ std(ssss) note("Effects of Education") + +.- +Authors: J. Scott Long and Jeremy Freese + www.indiana.edu/~jsl650/spost.htm + spostsup@@indiana.edu diff --git a/Modules/ado/plus/m/mlogtest.ado b/Modules/ado/plus/m/mlogtest.ado new file mode 100644 index 0000000..1883fa5 --- /dev/null +++ b/Modules/ado/plus/m/mlogtest.ado @@ -0,0 +1,1067 @@ +*! version 1.7.6 jsl 2009-10-18 +* - stata 11 minor revisions + +capture program drop mlogtest +program define mlogtest, rclass + version 9 + tempname numrhs sample numcats omit chisq df pval + tempname matiia matsuiia matlr matwald matcomb matlrc nxtrow testn newbase + tempvar tmp count + + local n = e(N) + local n "(N=`n')" + local vers7 "yes" + local smcl "in smcl " + local dash "{c -}" + local vline "{c |}" + local plussgn "{c +}" + local topt "{c TT}" + local bottomt "{c BT}" + + * version 6 + * 13Feb2005 + syntax [varlist(default=none)][, Detail Iia /// + Hausman Lr Wald Combine LRComb SMhsiao /// + SUest Set(string) All Base] + + if "`e(cmd)'" != "mlogit" { + di _newline in y "mlogtest" in r " only works after " in y "mlogit." + exit + } + + * store estimation results from original mlogit as _X + qui estimates store _X + +*-> set defaults + local dolr = "no" + if "`lr'"!="" { + local dolr = "yes" + } + local doiia = "no" + if "`hausman'"!="" | "`iia'"!="" { + local doiia = "yes" + } + local doshiia = "no" + if "`smhsiao'"!="" | "`iia'"!="" { + local doshiia = "yes" + } + local dosuiia = "no" + if "`suest'"!="" | "`iia'"!="" { + local dosuiia = "yes" + } + local dowald = "no" + if "`wald'"!="" { + local dowald = "yes" + } + local docomb = "no" + if "`combine'"!="" { + local docomb = "yes" + } + local dolrcom = "no" + if "`lrcomb'"!="" { + local dolrcom = "yes" + } + if "`all'"!="" { + local dolr = "yes" + local doiia = "yes" + local doshiia = "yes" +* local dosuiia = "yes" + local dowald = "yes" + local docomb = "yes" + local dolrcom = "yes" + } + +*-> get weight info from last mlogit + local wtis "" + if "`e(wtype)'"!="" { + local wtis "[`e(wtype)'`e(wexp)']" + } + +*-> check that estimation sample matches n from regression + qui gen `sample' = e(sample) + if "`e(wtype)'"=="" | "`e(wtype)'"=="aweight" | "`e(wtype)'"=="pweight" { + qui count if `sample' == 1 + scalar `testn' = r(N) + } + if "`e(wtype)'"=="fweight" | "`e(wtype)'"=="iweight" { + local wtexp = substr("`e(wexp)'", 3, .) + gen `tmp' = (`wtexp')*`sample' + qui su `tmp', meanonly + scalar `testn' = round(r(sum),1) + } + if e(N) ~= `testn' { + di _newline in r "Data has been altered since " /* + */ in y "mlogit" in r " was estimated." + exit + } + +*-> get information about the mlogit + local depvar = "`e(depvar)'" + + local printdv = abbrev("`printdv'", 8) + + _perhs + local rhsnam "`r(rhsnms)'" + scalar `numrhs' = `r(nrhs)' + _pecats + local catnms8 "`r(catnms8)'" + local catvals "`r(catvals)'" + local catnms "`r(catnms)'" + scalar `numcats' = r(numcats) + + * 2007-06-29 stata 10 + if c(stata_version) < 10 { + local basecat = e(basecat) /* or r(refval) */ + } + else { + local basecat = e(baseout) /* or r(refval) */ + } + local refnm "`r(refnm)'" + local check : word count `catvals' + if `numcats' ~= real("`check'") { + di _newline in r "Problem determining number of categories." + } + +*-> parse out sets if set option on + local numset = 0 + if "`set'" ~= "" { + tokenize "`set'", parse("\") + local count = 1 + while "``count''"!="" { + if "``count''"=="\" { + macro shift + } + else { + local set`count' "``count''" + capture unab set`count': /* + */ `set`count'', min(2) name(defining sets) + local setl`count': word count `set`count'' + * check if all variables in set are rhs variables + local count2 = 1 + while `count2' <= `setl`count'' { + local count3 = 1 + local inrhs "no" + local setvar : word `count2' of `set`count'' + while `count3' <= `numrhs' { + local ivar : word `count3' of `rhsnam' + if "`setvar'"=="`ivar'" { + local inrhs "yes" + } + local count3 = `count3' + 1 + } + if "`inrhs'" == "no" { + di _newline in r "variable " in y "`setvar'" in r /* + */ " specified in set() but is not in model." + exit + } + local count2 = `count2' + 1 + } /* while count2 <= `setl`count' */ + return local set_`count' "`set`count''" + local count = `count' + 1 + } /* else */ + } /* while "``count''"!="" */ + local numset = `count' - 1 + } /* if "`set'" ~= "" */ + +*-> LR test of independent variables + + version 7 + if "`dolr'"=="yes" & `numrhs' == 0 { + di _n in r "LR test cannot be computed on intercept-only model." + } + else if "`dolr'"=="yes" { + di _newline in g /* + */ "**** Likelihood-ratio tests for independent variables `n'" + di _newline in g /* + */ " Ho: All coefficients associated with given variable(s) are 0." + di `smcl' _newline in g %12s "`printdv'" _col(14) "`vline'" /* + */ _col(22) "chi2" _col(29) "df" _col(34) "P>chi2" + di `smcl' in g _dup(13) "`dash'" "`plussgn'" _dup(25) "`dash'" + + lrtest, saving(0) + + * 13Feb2005 - allow tests of specified # of variables + if "`varlist'"!="" { // if var list + local nvlist : word count `varlist' + local ntests = `nvlist' // use this as the # of rhsvars + local testnms "`varlist'" + } + else { + local testnms "`rhsnam'" + local ntests = `numrhs' + } + tokenize "`rhsnam'" // tokenize list, rather than rhs vars + + * 13Feb2005 replace numrhs with ntests below + * loop over all rhs + specified sets + local count = 1 + while `count' <= `ntests'+`numset' { + local testvar : word `count' of `testnms' + * for individual independent variables + if `count' <= `ntests' { + local var`count' : word `count' of `testnms' + * create varlist with all vars but count variable + local count2 = 1 + local lrrhs = "" + while `count2' <= `numrhs' { // loop through all variables + if "`testvar'"!="``count2''" { + local lrrhs "`lrrhs' ``count2''" + } + local count2 = `count2' + 1 + } + } /* if `count' <= `ntests' */ + + * for sets of independent variables + if `count' > `ntests' { + local thisset = `count'-`ntests' + * for matrix & output rowname + local var`count' "set_`thisset'" + * for count3 loop + local countto : word count `set`thisset'' + local count2 = 1 + local lrrhs = "" + while `count2' <= `ntests' { + local count3 = 1 + local inset "no" + while `count3' <= `countto' { + local setvar : word `count3' of `set`thisset'' + if "``count2''"=="`setvar'" { + local inset "yes" + } + local count3 = `count3' + 1 + } + if "`inset'" == "no" { + local lrrhs "`lrrhs' ``count2''" + } + local count2 = `count2' + 1 + } + } /* if `count' > `ntests' */ + + qui mlogit `depvar' `lrrhs' `wtis' /* + */ if `sample' == 1, b(`basecat') + * quietly lrtest, using(0) + qui lrtest, using(0) + * put results in matrix + scalar `chisq' = r(chi2) + scalar `df' = r(df) + scalar `pval' = r(p) + if `pval' == . { + scalar `pval' = -9999 + } + mat `nxtrow' = `chisq', `df', `pval' + mat rownames `nxtrow' = "`var`count''" + mat `matlr' = nullmat(`matlr') \ `nxtrow' + local count = `count' + 1 + } /* while `count' <= `ntests' */ + + mat colnames `matlr' = chi2 df p + * cycle through row by row of output matrix and print + local countto = rowsof(`matlr') + local count = 1 + while `count' <= `countto' { + scalar `chisq' = `matlr'[`count', 1] + scalar `df' = `matlr'[`count', 2] + scalar `pval' = `matlr'[`count', 3] + if `pval' == -9999 { + scalar `pval' = . + } + * tests of individual variables + if `count' <= `ntests' { + * name to print + local printnm "`var`count''" + local printnm = abbrev("`printnm'", 12) + di `smcl' in y %12s "`printnm'" _col(14) in g "`vline'" /* + */ _col(17) %9.3f in y `chisq' /* + */ _col(26) %5.0f `df' /* + */ _col(35) %4.3f `pval' + } + * tests of sets + if `count' > `ntests' { + local thisset = `count' - `ntests' + di `smcl' in g _dup(13) "`dash'" "`plussgn'" _dup(25) "`dash'" + * name to print + local printnm "`var`count''" + local printnm = abbrev("`printnm'", 12) + di `smcl' in g %12s "`printnm':" _col(14) in g "`vline'" /* + */ _col(17) %9.3f in y `chisq' /* + */ _col(26) %5.0f `df' /* + */ _col(35) %4.3f `pval' + local count2 = 1 + local countt2 : word count `set`thisset'' + while `count2' <= `countt2' { + local setvar : word `count2' of `set`thisset'' + * name to print + local printnm "`setvar'" + if "`vers7'"=="yes" { local printnm = abbrev("`printnm'", 12) } + di `smcl' %12s in y "`printnm'" _col(14) in g "`vline'" + local count2 = `count2' + 1 + } + } + local count = `count' + 1 + } /* while `count' <= `countto' */ + di `smcl' in g _dup(13) "`dash'" "`bottomt'" _dup(25) "`dash'" + + qui version 9: estimates restore _X + return matrix lrtest `matlr' + + } /* if "`dolr'"=="yes" */ + +*-> WALD test of independent variables + + version 7 + * 13Feb2005 - allow tests of specified # of variables + if "`varlist'"!="" { // if var list + local nvlist : word count `varlist' + local testnms "`varlist'" + local ntests = `nvlist' // use this as the # of rhsvars + } + else { + local ntests = `numrhs' + local testnms "`rhsnam'" + } + + if "`dowald'"=="yes" & `ntests' == 0 { + di _n in r "Wald test cannot be computed on intercept-only model." + } + else if "`dowald'"=="yes" { + * 13Feb2005 replace numrhs with ntests below + tokenize "`testnms'" + di _newline in g /* + */ "**** Wald tests for independent variables `n'" + di _newline in g /* + */ " Ho: All coefficients associated with given variable(s) are 0." + di `smcl' _newline in g %12s "`printdv'" _col(14) "`vline'" /* + */ _col(22) "chi2" _col(29) "df" _col(34) "P>chi2" + di `smcl' in g _dup(13) "`dash'" "`plussgn'" _dup(25) "`dash'" + + * loop over all rhs + specified sets + local count = 1 + while `count' <= `ntests'+`numset' { + * for individual independent variables + if `count' <= `ntests' { + * 13Feb2005 + local var`count' : word `count' of `testnms' + qui test `var`count'' + } + * tests of sets + if `count' > `ntests' { + local thisset = `count'-`ntests' + *get set name/number for matrix&output + local var`count' "set_`thisset'" + qui test `set`thisset'' + } + scalar `chisq' = r(chi2) + scalar `df' = r(df) + scalar `pval' = r(p) + if `pval' == . { scalar `pval' = -9999 } + mat `nxtrow' = `chisq', `df', `pval' + mat rownames `nxtrow' = "`var`count''" + mat `matwald' = nullmat(`matwald') \ `nxtrow' + local count = `count' + 1 + } /* while `count' <= `ntests' */ + + mat colnames `matwald' = chi2 df p + local countto = rowsof(`matwald') + local count = 1 + while `count' <= `countto' { + scalar `chisq' = `matwald'[`count', 1] + scalar `df' = `matwald'[`count', 2] + scalar `pval' = `matwald'[`count', 3] + if `pval' == -9999 { scalar `pval' = . } + if `count' <= `ntests' { + *added for stata 7 compatibility + local printnm "`var`count''" + local printnm = abbrev("`printnm'", 12) + di `smcl' in y %12s "`printnm'" _col(14) in g "`vline'" /* + */ _col(17) %9.3f in y `chisq' /* + */ _col(26) %5.0f `df' /* + */ _col(35) %4.3f `pval' + } + if `count' > `ntests' { + local thisset = `count' - `ntests' + di `smcl' in g _dup(13) "`dash'" "`plussgn'" _dup(25) "`dash'" + *added for stata 7 compatibility + local printnm "`var`count''" + local printnm = abbrev("`printnm'", 12) + di `smcl' in g %12s "`printnm':" _col(14) in g "`vline'" /* + */ _col(17) %9.3f in y `chisq' /* + */ _col(26) %5.0f `df' /* + */ _col(35) %4.3f `pval' + local count2 = 1 + local countt2 : word count `set`thisset'' + while `count2' <= `countt2' { + local setvar : word `count2' of `set`thisset'' + *added for stata 7 compatibility + local printnm "`setvar'" + if "`vers7'"=="yes" { + local printnm = abbrev("`printnm'", 12) + } + di `smcl' %12s in y "`printnm'" _col(14) in g "`vline'" + local count2 = `count2' + 1 + } + } + local count = `count' + 1 + } /* while `count' <= `countto' */ + di `smcl' in g _dup(13) "`dash'" "`bottomt'" _dup(25) "`dash'" + return matrix wald `matwald' + } /* if "`dowald'"=="yes" */ + +*-> HAUSMAN IIA Test + + version 9 + * can't do if only two categories + if "`doiia'"=="yes" & `numcats' == 2 { + di _n in r /* + */ "Hausman IIA test requires at least 3 dependent categories." + } + else if "`doiia'"=="yes" { + di _newline in g /* + */ "**** Hausman tests of IIA assumption `n'" + di _newline in g /* + */ " Ho: Odds(Outcome-J vs Outcome-K) are independent of "/* + */ "other alternatives." + + * cycle through all alternatives + tokenize "`catvals'" + local count = 1 + while real("`count'") <= `numcats' { + local lab`count' : word `count' of `catnms' + local slab`count' : word `count' of `catnms8' + scalar `omit' = real("``count''") + if "`detail'" == "detail" { + if "`lab`count''"!="``count''" { + di _newline in g/* + */ "Hausman test when omitted alternative is " in y `omit' /* + */ in g " (" in y "`lab`count''" in g ")" +/* di _newline in g/* + */ "Hausman test when omitted outcome is " in y `omit' /* + */ in g " (" in y "`lab`count''" in g ")" +*/ + } + else { + di in g _newline /* + */ "Hausman test when omitted alternative is " in y `omit' + } + } /* if "`detail'" == "detail" */ + if `omit'==real("`basecat'") & "`base'" != "" { + * IIA for basecategory requires estimating mlogit with + * new basecategory. Make new basecat the largest category + * of the dependent variable that is not the original basecat + local maxcnt = 0 + local count2 = 1 + while `count2' <= `numcats' { + if real("``count2''") != `omit' { + qui count if `depvar'==``count2'' & `sample'==1 + if r(N)>`maxcnt' { + local newbase = ``count2'' + local maxcnt = r(N) + local tmplab : word `count2' of `catnms' + } + } + local count2 = `count2' + 1 + } /* while count2 <= `numcats' */ + + * estimates of old logit are held in _X + qui mlogit `depvar' `rhsnam' `wtis' /* + */ if `sample' == 1, b(`newbase') + qui estimates store _Xnb + + qui mlogit `depvar' `rhsnam' `wtis' /* + */ if `sample'==1 & `depvar'!=`omit', b(`newbase') + if "`detail'"=="detail" { + if "`lab`count''"!="``count''" { + di in g "(Using category " in g "`newbase' " /* + */ in g "(" in g "`tmplab'" in g /* + */ ") as comparison group)" + } + else { + di in g "(Using category " in g "`newbase' " /* + */ in g "as comparison group)" + } + hausman . _Xnb, alleq constant + } + else { + qui hausman . _Xnb, alleq constant + } + scalar `chisq' = r(chi2) + scalar `df' = r(df) + scalar `pval' = r(p) + if `pval' == . | `chisq' < 0 { + scalar `pval' = -9999 + } + + *put things back and then hold them again + qui estimates restore _X + mat `nxtrow' = `omit', `chisq', `df', `pval' + mat rownames `nxtrow' = "`slab`count''" + mat `matiia' = nullmat(`matiia') \ `nxtrow' + } /* if `omit'==real("`basecat'") */ + else if `omit'!=real("`basecat'") { + quietly mlogit `depvar' `rhsnam' `wtis' /* + */ if `sample' == 1 & `depvar' != `omit', b(`basecat') + if "`detail'"=="detail" { + hausman . _X, alleq constant + } + else { + qui hausman . _X, alleq constant + } + scalar `chisq' = r(chi2) + scalar `df' = r(df) + scalar `pval' = r(p) + if `pval' == . | `chisq' < 0 { + scalar `pval' = -9999 + } + mat `nxtrow' = `omit', `chisq', `df', `pval' + mat rownames `nxtrow' = "`slab`count''" + mat `matiia' = nullmat(`matiia') \ `nxtrow' + } /* else if `omit'!=real("`basecat'") */ + local count = `count' + 1 + } /* while real("`count'") <= `numcats' */ + + mat colnames `matiia' = omitted chi2 df p + if "`detail'" == "detail" { + di in g _newline "*** Summary of results" + } + + * only print explainer if negative chi2 observed + local anyneg = "no" + local countto = rowsof(`matiia') + local count = 1 + + di _newline `smcl' in g " Omitted" _col(10) "`vline'" /* + */ _col(17) "chi2" _col(24) "df" _col(29) "P>chi2" _col(38) "evidence" + di `smcl' in g _dup(9) "`dash'" "`plussgn'" _dup(36) "`dash'" + + *cycle through row by row of output matrix and print + while `count' <= `countto' { + scalar `chisq' = `matiia'[`count', 2] + scalar `df' = `matiia'[`count', 3] + scalar `pval' = `matiia'[`count', 4] + if `pval' == -9999 { + local anyneg "yes" + local implies "---" + + *added for stata 7 compatibility + local printnm "`slab`count''" + local printnm = abbrev("`printnm'", 8) + + di `smcl' in y %8s "`printnm'" _col(10) in g "`vline'" /* + */ _col(13) %8.3f in y `chisq' /* + */ _col(21) %5.0f `df' /* + */ _col(30) " ---" /* + */ _col(38) %-10s "`implies'" + } + else { + local implies "for Ho" + if `pval' < .05 { + local implies "against Ho" + } + *added for stata 7 compatibility + local printnm "`slab`count''" + local printnm = abbrev("`printnm'", 12) + + di `smcl' %8s in y "`printnm'" _col(10) in g "`vline'" /* + */ _col(13) %8.3f in y `chisq' /* + */ _col(21) %5.0f `df' /* + */ _col(30) %4.3f `pval' /* + */ _col(38) %-10s "`implies'" + } + local count = `count' + 1 + } /* while `count' <= `countto' */ + di `smcl' in g _dup(9) "`dash'" "`bottomt'" _dup(36) "`dash'" + + if "`anyneg'" == "yes" { + di in g " Note: If chi2<0, the estimated model does not" + di in g " meet asymptotic assumptions of the test." + } + + qui estimates restore _X + return matrix hausman `matiia' + + } /* if "`doiia'"=="no" */ + +*-> suest-based HAUSMAN IIA Test + + version 9 + * see if cluster has been used and, if so, this can be incorporated in suest + local clustvar = e(clustvar) + * can't do if only two categories + if "`dosuiia'"=="yes" & `numcats' == 2 { + di _n in r /// + "suest-based Hausman IIA test requires at least 3 dependent categories." + } + else if ("`clustvar'" != "." & "`clustvar'" != "") { + di _n as err /// + "suest-based Hausman IIA test must be estimated differently when cluster()" + di as err "is specified, see [R] suest" + } + else if "`dosuiia'"=="yes" { + di _newline in g /* + */ "**** suest-based Hausman tests of IIA assumption `n'" + di _newline in g /* + */ " Ho: Odds(Outcome-J vs Outcome-K) are independent of "/* + */ "other alternatives." + + * cycle through all alternatives + tokenize "`catvals'" + local count = 1 + while real("`count'") <= `numcats' { + local lab`count' : word `count' of `catnms' + local slab`count' : word `count' of `catnms8' + scalar `omit' = real("``count''") + if `omit'==real("`basecat'") & "`base'" != "" { + * IIA for basecategory requires estimating mlogit with + * new basecategory. Make new basecat the largest category + * of the dependent variable that is not the original basecat + local maxcnt = 0 + local count2 = 1 + while `count2' <= `numcats' { + if real("``count2''") != `omit' { + qui count if `depvar'==``count2'' & `sample'==1 + if r(N)>`maxcnt' { + local newbase = ``count2'' + local maxcnt = r(N) + local tmplab : word `count2' of `catnms' + } + } + local count2 = `count2' + 1 + } /* while count2 <= `numcats' */ + + * estimates of old logit are held in _X + qui mlogit `depvar' `rhsnam' `wtis' /* + */ if `sample' == 1, b(`newbase') + qui estimates store _Xnb + + qui mlogit `depvar' `rhsnam' `wtis' /* + */ if `sample'==1 & `depvar'!=`omit', b(`newbase') + qui estimates store _Y + local eqnames = e(eqnames) + qui estimates store _Y + qui suest _Y _Xnb + qui estimates store _suest + + foreach name in `eqnames' { + * di `"`eqnames'"' + qui test [_Xnb_`name' = _Y_`name'], cons accum + } + if "`detail'"=="detail" { + suest + test + } + + scalar `chisq' = r(chi2) + scalar `df' = r(df) + scalar `pval' = r(p) + if `pval' == . | `chisq' < 0 { + scalar `pval' = -9999 + } + + *put things back and then hold them again + qui estimates restore _X + mat `nxtrow' = `omit', `chisq', `df', `pval' + mat rownames `nxtrow' = "`slab`count''" + mat `matsuiia' = nullmat(`matsuiia') \ `nxtrow' + + } /* if `omit'==real("`basecat'") */ + else if `omit'!=real("`basecat'") { + quietly mlogit `depvar' `rhsnam' `wtis' /* + */ if `sample' == 1 & `depvar' != `omit', b(`basecat') + local eqnames = e(eqnames) + qui estimates store _Y + qui suest _Y _X + qui estimates store _suest + + ** execute tests + foreach name in `eqnames' { + * di `"`eqnames'"' + qui test [_X_`name' = _Y_`name'], cons accum + } + if "`detail'"=="detail" { + suest + test + } + scalar `chisq' = r(chi2) + scalar `df' = r(df) + scalar `pval' = r(p) + if `pval' == . | `chisq' < 0 { + scalar `pval' = -9999 + } + qui estimates restore _X + mat `nxtrow' = `omit', `chisq', `df', `pval' + mat rownames `nxtrow' = "`slab`count''" + mat `matsuiia' = nullmat(`matsuiia') \ `nxtrow' + } /* else if `omit'!=real("`basecat'") */ + local count = `count' + 1 + } /* while real("`count'") <= `numcats' */ + + mat colnames `matsuiia' = omitted chi2 df p + local anyneg = "no" + local countto = rowsof(`matsuiia') + local count = 1 + + di _newline `smcl' in g " Omitted" _col(10) "`vline'" /* + */ _col(17) "chi2" _col(24) "df" _col(29) "P>chi2" _col(38) "evidence" + di `smcl' in g _dup(9) "`dash'" "`plussgn'" _dup(36) "`dash'" + + *cycle through row by row of output matrix and print + while `count' <= `countto' { + scalar `chisq' = `matsuiia'[`count', 2] + scalar `df' = `matsuiia'[`count', 3] + scalar `pval' = `matsuiia'[`count', 4] + if `pval' == -9999 { + local anyneg "yes" + local implies "---" + *added for stata 7 compatibility + local printnm "`slab`count''" + local printnm = abbrev("`printnm'", 8) + + di `smcl' in y %8s "`printnm'" _col(10) in g "`vline'" /* + */ _col(13) %8.3f in y `chisq' /* + */ _col(21) %5.0f `df' /* + */ _col(30) " ---" /* + */ _col(38) %-10s "`implies'" + } + else { + local implies "for Ho" + if `pval' < .05 { + local implies "against Ho" + } + *added for stata 7 compatibility + local printnm "`slab`count''" + local printnm = abbrev("`printnm'", 12) + + di `smcl' %8s in y "`printnm'" _col(10) in g "`vline'" /* + */ _col(13) %8.3f in y `chisq' /* + */ _col(21) %5.0f `df' /* + */ _col(30) %4.3f `pval' /* + */ _col(38) %-10s "`implies'" + } + local count = `count' + 1 + } /* while `count' <= `countto' */ + di `smcl' in g _dup(9) "`dash'" "`bottomt'" _dup(36) "`dash'" + + qui estimates restore _X + return matrix suest `matsuiia' + } /* if "`doiia'"=="no" */ + +*-> Small-Hsiao test of iia + + version 7 + * NOTE: THE CODE FOR COMPUTING THE SMALL-HSIAO TEST IS ADAPTED + * FROM CODE WRITTEN BY NICK WINTER (IN HIS -SMHSIAO- COMMAND) + + * 050219 fix error in df for sh test + + *can't do if only two categories + if "`doshiia'"=="yes" & `numcats' == 2 { + di _n in r "Small-Hsiao IIA test requires at least 3 dependent categories." + } + else if "`doshiia'"=="yes" { + tempname rowres matsh touse + di _newline in g /* + */ "**** Small-Hsiao tests of IIA assumption `n'" + di _newline in g /* + */ " Ho: Odds(Outcome-J vs Outcome-K) are independent of other alternatives." + qui gen `touse' = e(sample) + + tempvar samp + qui gen `samp'=round(uniform(),1)+1 if `touse' + local y `e(depvar)' + tempvar tempy + qui gen `tempy' = `depvar' + local varlist "`tempy' `rhsnam'" + *local dof = `numrhs' + 1 + qui ta `tempy' if `touse' & `samp'==1 + local cat1 `r(r)' + qui ta `tempy' if `touse' & `samp'==2 + local cat2 `r(r)' + if `cat1'!=`numcats' | `cat2'!=`numcats' { + di in r /* + */ "Random draw yielded empty cells for some categories of `y' in" + di in r /* + */ "one of the half-samples. Could not estimate Small-Hsiao test." + error 148 + } + + local count = 1 + local countto = `numcats' - 1 + if "`base'"!="" { + local countto = `numcats' + } + while `count' <= `countto' { + local bcat "b(`basecat')" + if `count'==`numcats' { + local bcat "" + } + local elim : word `count' of `catvals' + local ielim `elim' + tempname Vals + qui tab `tempy' if `touse', matrow(`Vals') + local nEvals = `numcats'-1 + local Yvals = "" + local EYvals = "" + local EYeqs = "" + local i = 1 + while `i' <= `numcats' { + local Yval`i' = `Vals'[`i',1] + local Yvals "`Yvals' `Yval`i''" + if `Yval`i'' != `elim' { + local EYvals "`EYvals' `Yval`i''" + local EYeqs "`EYeqs' `i'" + local Ylab`i' `Yval`i'' + } + local i = `i' + 1 + } + + tempvar lnL denom + tempname b0a b0b b0ab b1b + + qui mlogit `varlist' /* + */ if (`touse' & `samp'==2 & `tempy'!=`elim') `wtis', `bcat' + *spost9 df for SH 19Feb2005 + tempname v + mat `v' = e(V) + local dof = rowsof(`v') + local lnL_1 = e(ll) + if `count'==`numcats' { + local tmpbcat "`e(basecat)'" + local bcat "b(`tmpbcat')" + } + *ESTIMATE MODELS FOR EACH HALF SAMPLE + qui mlogit `varlist' if `touse' & `samp'==1 `wtis', `bcat' + mat `b0a' = e(b) + qui mlogit `varlist' if `touse' & `samp'==2 `wtis', `bcat' + mat `b0b' = e(b) + * Zhang & Hoffman eq. 9 + mat `b0ab' = (0.70710678)*(`b0a') + (0.29289322)*(`b0b') + + * get LnL for amalgamated coefficients + *get XBs & assemble denominator + qui gen double `denom' = 0 if `touse' + local i 1 + * cycle through values (w/o eliminated one) + while `i' <= (`numcats'-1) { + local cury : word `i' of `EYvals' + local cureq : word `i' of `EYeqs' + tempvar xb`cureq' + if `cury' != `basecat' & "`cury'" != "`tmpbcat'" { + matrix score double `xb`cureq'' = `b0ab' /* + */ if `touse', eq(`Ylab`cureq'') + } + else { + qui gen double `xb`cureq''=0 /* because (exp(0)=1) */ + } + qui replace `denom'=`denom' + exp(`xb`cureq'') if `touse' + local i=`i'+1 + } + + * create Log likelihood using amalgamated coeff. + qui gen double `lnL' = . if `touse' + local i 1 + while `i'<=`nEvals' { + local cureq : word `i' of `EYeqs' + local cury : word `i' of `EYvals' + qui replace `lnL' = ln(exp(`xb`cureq'')/(`denom')) /* + */ if `tempy'==`cury' & `touse' + local i=`i'+1 + } + + * GET LnL, only for observations in the 2d sample + * and without eliminated observations: + sum `lnL' if `touse' & `samp'==2 & `tempy'!=`elim', meanonly + local lnL_0 = r(sum) + local SH = -2 * (`lnL_0' - `lnL_1') + local p = chiprob(`dof',`SH') + mat `rowres' = `elim' , `lnL_0' , `lnL_1' , `SH' , `dof' , `p' + mat rownames `rowres' = "test `count'" + mat colnames `rowres' = elim_cat lnL_0 lnL_1 chi2 df p + mat `matsh' = nullmat(`matsh') \ `rowres' + local count = `count' + 1 + } + + di _newline `smcl' in g " Omitted" _col(10) "`vline'" /* + */ _col(13) "lnL(full)" _col(24) "lnL(omit)" /* + */ _col(37) "chi2" _col(44) "df" _col(49) "P>chi2" _col(58) "evidence" + di `smcl' in g _dup(9) "`dash'" "`plussgn'" _dup(57) "`dash'" + local count = 1 + local countto = rowsof(`matsh') + while `count' <= `countto' { + local elim = `matsh'[`count', 1] + local elimnm8 : word `count' of `catnms8' + local lnL_0 = `matsh'[`count', 2] + local lnL_1 = `matsh'[`count', 3] + local SH = `matsh'[`count', 4] + scalar `df' = `matsh'[`count', 5] + scalar `pval' = `matsh'[`count', 6] + local count = `count' + 1 + local implies "for Ho" + if `pval' < .05 { + local implies "against Ho" + } + di `smcl' in y %8s "`elimnm8'" _col(10) in g "`vline'" /* + */ _col(13) %9.3f in y `lnL_0' /* + */ _col(24) %9.3f `lnL_1' /* + */ _col(33) %8.3f `SH' /* + */ _col(41) %5.0f `df' /* + */ _col(50) %4.3f `pval' /* + */ _col(58) %-10s "`implies'" + } + di `smcl' in g _dup(9) "`dash'" "`bottomt'" _dup(57) "`dash'" + + qui mat list `matsh' + qui version 9: estimates restore _X + return matrix smhsiao `matsh' + } /* if "`doshiia'"=="no" */ + +*-> Wald tests for combining categories + + if "`docomb'"=="yes" & `numcats' == 2 { + di in r "Test requires at least 3 dependent categories." + } + else if "`docomb'"=="yes" { + di _newline in g /* + */ "**** Wald tests for combining alternatives `n'" + di _newline in g /* + */ " Ho: All coefficients except intercepts associated " /* + */ "with a given pair" + di in g /* + */ " of alternatives are 0 (i.e., alternatives can be combined)." + di `smcl' _newline in g %17s "Alternatives tested" _col(20) "`vline'" /* + */ _col(26) "chi2" _col(33) "df" _col(38) "P>chi2" + di `smcl' in g _dup(19) "`dash'" "`plussgn'" _dup(24) "`dash'" + + tokenize "`catvals'" + qui version 9: estimates restore _X + + * cycle through all pairs of outcomes + local count1 = 1 + while `count1' <= (`numcats'-1) { + local count2 = `count1' + 1 + while `count2' <= `numcats' { + if "``count1''"=="`basecat'" { + quietly test [``count2''] + } + else if "``count2''"=="`basecat'" { + quietly test [``count1''] + } + else { + quietly test [``count2''=``count1''] + } + scalar `chisq' = r(chi2) + scalar `df' = r(df) + scalar `pval' = r(p) + local numrow = `numrow' + 1 + local s1`numrow' : word `count1' of `catnms8' + local s2`numrow' : word `count2' of `catnms8' + if `pval' == . { scalar `pval' = -9999 } + mat `nxtrow' = ``count1'', ``count2'', /* + */ `chisq', `df', `pval' + mat roweq `nxtrow' = "`s1`numrow''" + mat rownames `nxtrow' = "`s2`numrow''" + mat `matcomb' = nullmat(`matcomb') \ `nxtrow' + local count2 = `count2' + 1 + } + local count1 = `count1' + 1 + } /* while `count1' <= `numcats' */ + + mat colnames `matcomb' = cat1 cat2 chi2 df p + local countto = rowsof(`matcomb') + local count = 1 + while `count' <= `countto' { + scalar `chisq' = `matcomb'[`count', 3] + scalar `df' = `matcomb'[`count', 4] + scalar `pval' = `matcomb'[`count', 5] + if `pval' == -9999 { scalar `pval' = . } + di `smcl' in y %8s "`s1`count''" _col(9) "-" %8s "`s2`count''" /* + */ _col(20) in g "`vline'" /* + */ _col(21) %9.3f in y `chisq' /* + */ _col(30) %5.0f `df' /* + */ _col(39) %4.3f `pval' + local count = `count' + 1 + } + di `smcl' in g _dup(19) "`dash'" "`bottomt'" _dup(24) "`dash'" + qui version 9: estimates restore _X + return matrix combine `matcomb' + } /* if "`docomb'"=="yes" */ + +*-> LR tests for combining categories + + if "`dolrcom'"=="yes" & `numcats' == 2 { + di in r "Test requires at least 3 dependent categories." + } + else if "`dolrcom'"=="yes" { + di _newline in g /* + */ "**** LR tests for combining alternatives `n'" + di _newline in g /* + */ " Ho: All coefficients except intercepts associated" /* + */ " with a given pair" + di in g /* + */ " of alternatives are 0 (i.e., alternatives can be collapsed)." + di `smcl' _newline in g %17s "Alternatives tested" _col(20) "`vline'" /* + */ _col(26) "chi2" _col(33) "df" _col(38) "P>chi2" + di `smcl' in g _dup(19) "`dash'" "`plussgn'" _dup(24) "`dash'" + + lrtest, saving(lrc) + tokenize "`catvals'" + + * cycle through all pairs of outcomes + local count1 = 1 + while `count1' <= (`numcats'-1) { + local count2 = `count1'+1 + while `count2' <= `numcats' { + constraint define 999 [``count1''] + qui mlogit `depvar' `rhsnam' `wtis' /* + */ if `sample' == 1, base(``count2'') constr(999) + qui lrtest, using(lrc) + scalar `chisq' = r(chi2) + scalar `df' = r(df) + scalar `pval' = r(p) + local numrow = `numrow' + 1 + local s1`numrow' : word `count1' of `catnms8' + local s2`numrow' : word `count2' of `catnms8' + if `pval' == . { scalar `pval' = -9999 } + mat `nxtrow' = ``count1'', ``count2'', `chisq', `df', `pval' + mat roweq `nxtrow' = "`s1`numrow''" + mat rownames `nxtrow' = "`s2`numrow''" + mat `matlrc' = nullmat(`matlrc') \ `nxtrow' + local count2 = `count2' + 1 + } + local count1 = `count1' + 1 + } /* while `count1' <= `numcats' */ + + mat colnames `matlrc' = cat1 cat2 chi2 df p + local countto = rowsof(`matlrc') + local count = 1 + while `count' <= `countto' { + scalar `chisq' = `matlrc'[`count', 3] + scalar `df' = `matlrc'[`count', 4] + scalar `pval' = `matlrc'[`count', 5] + if `pval' == -9999 { scalar `pval' = . } + di `smcl' in y %8s "`s1`count''" _col(9) "-" %8s "`s2`count''" /* + */ _col(20) in g "`vline'" /* + */ _col(21) %9.3f in y `chisq' /* + */ _col(30) %5.0f `df' /* + */ _col(39) %4.3f `pval' + local count = `count' + 1 + } + di `smcl' in g _dup(19) "`dash'" "`bottomt'" _dup(24) "`dash'" + + qui version 9: estimates restore _X + return matrix lrcomb `matlrc' + } /* if "`dolrcom'"=="yes" */ + + qui version 9: estimates restore _X + * drop estimates stored in program + capture estimates drop _X + capture estimates drop _Xnb + capture estimates drop _Y + capture estimates drop _suest + +end +exit +* version 1.6.9 09Aug2005 - change terminology for alternatives +* version 1.7.0 22Jun2006 - fix warning for hausman; use estimates restore; add suest (undocumented) +* version 1.7.1 29Jun2006 - add suest as documented +* version 1.7.2 18Aug2006 - fix mlogit program name bug +* version 1.7.4 8Dec2006 - suest bug fix +* version 1.7.5 2007-06-29 stata 10 fixes diff --git a/Modules/ado/plus/m/mlogtest.sthlp b/Modules/ado/plus/m/mlogtest.sthlp new file mode 100644 index 0000000..1a7cc68 --- /dev/null +++ b/Modules/ado/plus/m/mlogtest.sthlp @@ -0,0 +1,120 @@ +{smcl} +{* 20Oct2009 version 1.7.6 jsl}{...} +{cmd:help mlogtest}: Help for tests for the multinomial logit model - 2009-10-20 +{hline} +{p2colset 4 14 14 2}{...} + +{title:Overview} + +{p 4 4 2 78} +The command {cmd:mlogtest} computes a variety of tests for the multinomial logit model. +The user selects the tests they want by specifying the appropriate options. For each +independent variable, {cmd:mlogtest} can perform either a LR or Wald test of the +null hypothesis that the coefficients of the variable equal zero across all equations. +{cmd:mlogtest} can also perform Wald or LR tests of whether any pair of outcome +categories can be combined. In addition, {cmd:mlogtest} computes the Hausman and +Small-Hsiao tests of the assumption of the independence of irrelevance alternatives (IIA) +for each possible omitted category. + +{title:Syntax} + +{p 8 13 2} +{cmd:mlogtest} [{it:varlist}] +[{cmd:,} {it:options}] + +{synoptset 15 tabbed}{...} +{synopthdr} +{synoptline} +{syntab:{it:Tests of variables}} + +{synopt:{opt varlist}}Selects variables to test with the wald or lr options. +By default, all variables in the model are tested.{p_end} + +{synopt:{opt w:ald}}Use Wald tests for each variable.{p_end} + +{synopt:{opt lr}}Use LR test for each variable.{p_end} + +{synopt:{opt set}{bf:(}{it:varlist} [{bf:\} {it:varlist}]{bf:)}} +Specify a set of variables is to be tested with {cmd:lrtest} or +{cmd:lr}. The slash {bf:\} specifies multiple sets of variables. +This option is particularly useful when a categorical variable is +included as a set of dummy variables, allowing that the coefficients for +all of the dummy variables are zero across all equations.{p_end} + +{syntab:{it:Tests for combining categories}} + +{synopt:{opt c:ombine}}Compute Wald tests of whether two outcomes can be +combined.{p_end} + +{synopt:{opt lrc:ombine}}Compute LR tests of whether two outcomes can be +combined.{p_end} + +{syntab:{it:Tests of IIA}} + +{synopt:{opt h:ausman}} Compute Hausman-McFadden tests using Stata's {cmd:hausman} +command.{p_end} + +{synopt:{opt d:etail}}Detailed results for {cmd:hausman} option are given.{p_end} + +{synopt:{opt sm:hsiao}}Compute Small-Hsiao tests{p_end} + +{synopt:{opt su:est}}Compute Hausman-McFadden tests using Stata's {cmd:suest} +command.{p_end} + +{synopt:{opt i:ia}}All of the IIA tests should be computed.{p_end} + +{synopt:{opt b:ase}}Conduct IIA test omitting the base category of the original +{cmd:mlogit} estimation. This is done by re-estimating the model using the largest +remaining category as the base category. The original estimates are +restored to memory.{p_end} + +{syntab:{it:Other}} + +{synopt:{opt a:ll}}All tests should be performed.{p_end} + +{synoptline} + +{title:Examples} + +{bf: . mlogit whoclass income dad_educ male black hispanic asian} +{bf: . * compute all tests} +{bf: . mlogtest, all} + +{bf: . mlogit whoclass income dad_educ male black hispanic asian singlpar} +{bf: > stepmommlogit whoclass income dad_educ male black hispanic asian} +{bf: . * teset groups of dummy variables} +{bf: . mlogtest, lr set(black hispanic asian \ singlpar stepmom stepdad)} + +{title:Returned matrices} + +{p 4 4} +{bf:r(combine)}: results of Wald tests to combine categories. Rows represent all +contrasts among categories; columns indicates the categories contrasted, the +chisq, df, and p of test. + +{p 4 4} +{bf:r(lrcomb)}: results of LR tests to combine categories. Rows represent all +contrasts among categories; columns indicates the categories contrasted, the +chisq, df, and p of test. + +{p 4 4} +{bf:r(hausman)}: results of Hausman tests of IIA assumption. Each row is one test. +Columns indicate the omitted category of a given test, the chisq, df, and p. + +{p 4 4} +{bf:r(smhsiao)}: results of Small-Hsiao tests of IIA assumption. + +{p 4 4} +{bf:r(wald)}: results of Wald test that all coefficients of an independent variable +equals zero + +{p 4 4} +{bf:r(lrtest)}: results of likelihood-ratio test that all coefficients of an +independent variable equals zero + +{title:Acknowledgment} + +{p 4 4} +The code used for the Small-Hsiao test is based on a program by Nick Winter. +INCLUDE help spost_footer + diff --git a/Modules/ado/plus/m/mlogview.ado b/Modules/ado/plus/m/mlogview.ado new file mode 100644 index 0000000..dd81c42 --- /dev/null +++ b/Modules/ado/plus/m/mlogview.ado @@ -0,0 +1,423 @@ +*! version 2.5.0 2009-10-28 jsl +* - stata 11 update for returns from -mlogit- + +window control clear + +capture program drop mlogview +capture program drop _mlgetv +capture program drop _mlinit +capture program drop _mlplot +capture program drop _mlnxt7 +capture program drop _mlprnt +capture program drop _mlhlp + +program define mlogview + if "`e(cmd)'"!="mlogit" { + di in r "mlogview must be run after mlogit" + exit + } + version 6.0 + +*=> Initialize + global mlopts "`*'" + _mlinit + global ml_lbl "" + +*=> List variables to plot + local r1 = 2 + local c1 = 5 + local d1 = 12 + * c's are columns for radio buttons + local c2 = `c1' + 55 + local c3 = `c2' + 20 + local c4 = `c3' + 28 + local c5 = `c4' + 24 +* 18Nov2005 - add button for range + local c6 = `c5' + 36 + +* global ml_wi "Select Variables Select Amount of Change" +* window control static ml_wi `c1' `r1' 146 9 + global ml_wi "Select Variables" + window control static ml_wi `c1' `r1' 146 9 + global ml_wi2 "Select Amount of Change" + local c12 = `c1' + 56 + window control static ml_wi2 `c12' `r1' 146 9 + local r1 = `r1' + `d1' - 1 + +* var#1 + local n1 = 1 + window control scombo ml_rhsnm `c1' `r1' 50 50 ml_v`n1' + window control radbegin "+1" `c2' `r1' 20 9 ml_v`n1'r + window control radio "+SD" `c3' `r1' 24 9 ml_v`n1'r + window control radio "0/1" `c4' `r1' 24 9 ml_v`n1'r +* 18Nov2005 - add Range option +* window control radend "Don't Plot" `c5' `r1' 40 9 ml_v`n1'r + +window control radio "Range" `c5' `r1' 32 9 ml_v`n1'r +window control radend "Don't Plot" `c6' `r1' 40 9 ml_v`n1'r + local r1 = `r1' + `d1' +* var#2 + local n1 = 2 + window control scombo ml_rhsnm `c1' `r1' 50 50 ml_v`n1' + window control radbegin "+1" `c2' `r1' 20 9 ml_v`n1'r + window control radio "+SD" `c3' `r1' 24 9 ml_v`n1'r + window control radio "0/1" `c4' `r1' 24 9 ml_v`n1'r +* 18Nov2005 +* window control radend "Don't Plot" `c5' `r1' 40 9 ml_v`n1'r +window control radio "Range" `c5' `r1' 32 9 ml_v`n1'r +window control radend "Don't Plot" `c6' `r1' 40 9 ml_v`n1'r + local r1 = `r1' + `d1' +* var#3 + local n1 = 3 + window control scombo ml_rhsnm `c1' `r1' 50 50 ml_v`n1' + window control radbegin "+1" `c2' `r1' 20 9 ml_v`n1'r + window control radio "+SD" `c3' `r1' 24 9 ml_v`n1'r + window control radio "0/1" `c4' `r1' 24 9 ml_v`n1'r +* 18Nov2005 +* window control radend "Don't Plot" `c5' `r1' 40 9 ml_v`n1'r +window control radio "Range" `c5' `r1' 32 9 ml_v`n1'r +window control radend "Don't Plot" `c6' `r1' 40 9 ml_v`n1'r + local r1 = `r1' + `d1' +* var#4 + local n1 = 4 + window control scombo ml_rhsnm `c1' `r1' 50 50 ml_v`n1' + window control radbegin "+1" `c2' `r1' 20 9 ml_v`n1'r + window control radio "+SD" `c3' `r1' 24 9 ml_v`n1'r + window control radio "0/1" `c4' `r1' 24 9 ml_v`n1'r +* 18Nov2005 +* window control radend "Don't Plot" `c5' `r1' 40 9 ml_v`n1'r +window control radio "Range" `c5' `r1' 32 9 ml_v`n1'r +window control radend "Don't Plot" `c6' `r1' 40 9 ml_v`n1'r + local r1 = `r1' + `d1' +* var#5 + local n1 = 5 + window control scombo ml_rhsnm `c1' `r1' 50 50 ml_v`n1' + window control radbegin "+1" `c2' `r1' 20 9 ml_v`n1'r + window control radio "+SD" `c3' `r1' 24 9 ml_v`n1'r + window control radio "0/1" `c4' `r1' 24 9 ml_v`n1'r +* 18Nov2005 +* window control radend "Don't Plot" `c5' `r1' 40 9 ml_v`n1'r +window control radio "Range" `c5' `r1' 32 9 ml_v`n1'r +window control radend "Don't Plot" `c6' `r1' 40 9 ml_v`n1'r +* var#6 + local r1 = `r1' + `d1' + local n1 = 6 + window control scombo ml_rhsnm `c1' `r1' 50 50 ml_v`n1' + window control radbegin "+1" `c2' `r1' 20 9 ml_v`n1'r + window control radio "+SD" `c3' `r1' 24 9 ml_v`n1'r + window control radio "0/1" `c4' `r1' 24 9 ml_v`n1'r +* 18Nov2005 +* window control radend "Don't Plot" `c5' `r1' 40 9 ml_v`n1'r +window control radio "Range" `c5' `r1' 32 9 ml_v`n1'r +window control radend "Don't Plot" `c6' `r1' 40 9 ml_v`n1'r + +*> 18Nov2005 - Add 7th variable +* var#7 + local r1 = `r1' + `d1' + local n1 = 7 + window control scombo ml_rhsnm `c1' `r1' 50 50 ml_v`n1' + window control radbegin "+1" `c2' `r1' 20 9 ml_v`n1'r + window control radio "+SD" `c3' `r1' 24 9 ml_v`n1'r + window control radio "0/1" `c4' `r1' 24 9 ml_v`n1'r + window control radio "Range" `c5' `r1' 32 9 ml_v`n1'r + window control radend "Don't Plot" `c6' `r1' 40 9 ml_v`n1'r +*< + +*=> Define buttons that execute the plot program + local r1 = `r1' + `d1' +/* 18Nov2005 - change size + window control button "DC Plot" 2 `r1' 40 13 ml_dc + global ml_dc "_mlplot 1" + window control button "OR Plot" 46 `r1' 40 13 ml_or + global ml_or "_mlplot 2" + window control button "OR+DC Plot" 90 `r1' 40 13 ml_od + global ml_od "_mlplot 3" + window control button "Next 6" 134 `r1' 40 13 ml_nxt7 + global ml_nxt7 "_mlnxt7" +*/ + local w = 52 + local w1 = `w' + 4 + local w2 = `w' + `w' + 4 + local w3 = `w' + `w' + `w' + 4 + + window control button "DC Plot" 2 `r1' `w' 13 ml_dc + global ml_dc "_mlplot 1" + window control button "OR Plot" `w1' `r1' `w' 13 ml_or + global ml_or "_mlplot 2" + window control button "OR+DC Plot" `w2' `r1' `w' 13 ml_od + global ml_od "_mlplot 3" + window control button "Next 7" `w3' `r1' `w' 13 ml_nxt7 + global ml_nxt7 "_mlnxt7" + + +*=> Add a note to graph + local r1 = `r1' + `d1' + 7 + local r2 = `r1' + global ml_wlbl "Note" + window control static ml_wlbl 5 `r1' 18 9 + window control edit 25 `r2' 148 8 ml_lbl + +*=> Plot options + local r1 = `r1' + `d1' + 3 + global ml_opt "Plot Options" + * window control static ml_opt 2 `r1' 173 40 blackframe + * version 1.6.5 + * window control static ml_opt 2 `r1' 173 50 blackframe + +* 17Nov2005 +window control static ml_opt 2 `r1' 210 60 blackframe + + local r1 = `r1' - 3 + window control static ml_opt 5 `r1' 40 8 + local r1 = `r1' + `d1' - 3 + local r2 = `r1' + * tics + global ml_wtic "Number of tics" + window control static ml_wtic 5 `r1' 47 8 + window control edit 50 `r2' 25 8 ml_tic + * range of plot + global ml_wmin "Plot from" + window control static ml_wmin 90 `r1' 28 8 + window control edit 120 `r1' 17 8 ml_xmin + global ml_wmax "to" + window control static ml_wmax 140 `r1' 6 8 + window control edit 149 `r1' 17 8 ml_xmax + * connect if p> + local r1 = `r1' + `d1' + local r2 = `r1' + global ml_wpgt "Connect if p>=" + window control static ml_wpgt 5 `r1' 42 8 + window control edit 50 `r2' 25 8 ml_pval + * set base category + global ml_wb "Base category" + window control static ml_wb 90 `r1' 45 8 + window control edit 137 `r2' 28 8 ml_bcat + * pack odds and use variable labels + local r1 = `r1' + `d1' - 2 + window control check "Pack odds ratio plot" 5 `r1' 80 10 ml_pack + window control check "Use variable labels" 90 `r1' 75 10 ml_vlbl + * pack odds and use variable labels + local r1 = `r1' + `d1' - 2 + window control check "Use category values for plot symbols" 5 `r1' 180 10 ml_valu + +* 17Nov2005 - add underline option for OR+DC plots + local r1 = `r1' + `d1' - 2 + window control check "Underline indicates negative change" 5 `r1' 180 10 ml_under + +*=> Buttons for odds and ends + local r1 = `r1' + 15 +* 18Nov2005 - drop help button - no longer works +* window control button "Help" 46 `r1' 40 13 ml_help +* global ml_help "_mlhlp" +* 18Nov2005 +* window control button "Exit" 2 `r1' 40 13 ml_ex +* window control button "Print" 90 `r1' 83 13 ml_print + + local w = 103 + local wx = `w' + 5 + window control button "Exit" 2 `r1' `w' 13 ml_ex + global ml_ex "exit 3000" + window control button "Print" `wx' `r1' `w' 13 ml_print + global ml_print "_mlprnt" + +* window dialog "Multinomial Logit Plots" 10 10 180 192 +* window dialog "Multinomial Logit Plots" 230 80 180 192 +* version 1.6.5 + *window dialog "Multinomial Logit Plots" 230 80 180 202 +* 17Nov2005 +*window dialog "Multinomial Logit Plots" 10 10 320 302 +* x y +*window dialog "Multinomial Logit Plots" 10 10 220 302 + +window dialog "Multinomial Logit Plots" 10 10 220 225 + +end + +program define _mlplot + if "`1'" ~= "" { + global ml_ordc = `1' + } + +*=> construct list of vars from the scombo boxes 1 through 6 +*=> construct list of vars from the scombo boxes 1 through 7 +* 18Nov2005 + local i = 1 + local varlst "" + local stdlst "" + while `i' < 8 { +* while `i' < 7 { + * type of plot: unstd, std, or 0 to 1 + local tmp "ml_v`i'r" + * name of variable + local tmpnm "ml_v`i'" + if $`tmp'==1 { + local varlst "`varlst' $`tmpnm'" + local stdlst "`stdlst'u" + } + if $`tmp'==2 { + local varlst "`varlst' $`tmpnm'" + local stdlst "`stdlst's" + } + if $`tmp'==3 { + local varlst "`varlst' $`tmpnm'" + local stdlst "`stdlst'0" + } +* 18Nov2005 + if $`tmp'==4 { + local varlst "`varlst' $`tmpnm'" + local stdlst "`stdlst'r" + } +* 18Nov2005 +* if type is not 1, 2, 3, or 4 it is not plotted + * if type is not 1, 2, or 3, it is not plotted + local i = `i' + 1 + } + +*=> build options to pass to mlogplot + local opts "std(`stdlst')" + if "$ml_bcat"~="" { + local opts "`opts' b($ml_bcat)" + } + local opts "`opts' p($ml_pval)" + if "$ml_xmin"~="min" { + local opts "`opts' min($ml_xmin)" + } + if "$ml_xmax"~="max" { + local opts "`opts' max($ml_xmax)" + } + if "$ml_lbl" ~= "" { + local opts "`opts' note($ml_lbl)" + } + if $ml_ordc>=2 { + local opts "`opts' or" + } + if $ml_ordc~=2 { + local opts "`opts' dc" + } + if $ml_pack==1 { + local opts "`opts' packed" + } + if $ml_vlbl==1 { + local opts "`opts' labels" + } + * 1.6.5 + if $ml_valu==1 { + local opts "`opts' values" + } +* 18Nov2005 + if $ml_under==1 { + local opts "`opts' sign" + } + + local opts "`opts' ntics($ml_tic)" + local opts "`opts' $mlopts" + di in white ". mlogplot `varlst', `opts'" + mlogplot `varlst',`opts' +* if $PE_mlerr==1 { +* exit 3000 +* } +end + +program define _mlinit + +*=> set radio buttons + local i = 1 + while `i' < 6 { + global ml_v`i'r = 1 + local i = `i' + 1 + } + +*=> defaults for check box + global ml_rng = 1 /* use observed range */ + global ml_ordc = 1 /* DC plot */ + global ml_pack = 0 /* don't pack plot */ + global ml_vlbl = 0 /* don't plot value labels */ +* 17Nov2005 +global ml_under = 0 /* underline negative changes */ + + * 1.6.5 + global ml_valu = 0 /* don't plot value labels */ + global ml_pval = .1 /* connect if p> */ + global ml_tic = 9 + global ml_lbl "" + global ml_xmin "min" /* plot from min to max */ + global ml_xmax "max" + + *=> get b from logit + /* 2009-10-28 + version 5.0 + mat ml_b = get(_b) + version 6.0 + */ + tempname v + _get_mlogit_bv ml_b `v' + global ml_nvars = colsof(ml_b) - 1 + +*=> get names of variables + global ml_rhsnm : colnames(ml_b) + global ml_nvar : word count $ml_rhsnm + global ml_nvar = $ml_nvar - 1 + global ml_lastv = 1 + global ml_lastv = 0 + _mlgetv +end + +* get the names of variables to fill in the scombo boxes +program define _mlgetv + * get number of last variable in box; 0 if none plotted before. + * if this is called from Next 6, this will not be 0. + local k = $ml_lastv + local i = 1 +* 18Nov2005 + * loop through up to 6 new variables +* while `i' < 7 { +* loop through up to 7 new variables +while `i' < 8 { + local k = `k' + 1 + * if exceed max number of vars, do fill remaining scombo boxes + if `k' > $ml_nvar { + * do not plot +*18Nov2005 +* global ml_v`i'r = 4 +global ml_v`i'r = 5 + * no name + global ml_v`i' "" + } + * else, get next in list of variables + else { + global ml_v`i' : word `k' of $ml_rhsnm + local tmp "ml_v`i'" + _pedum $`tmp' + global ml_v`i'r = 1 + if r(dummy) == 1 { global ml_v`i'r = 3 } + } + local i = `i' + 1 + } + * ok that this can be larger than n vars in model +* 18Nov2005 + *global ml_lastv = $ml_lastv + 6 + global ml_lastv = $ml_lastv + 7 +end + +program define _mlnxt7 + * if last var from _mlgetv > n vars in model, reset + if $ml_lastv > $ml_nvar { + global ml_lastv = 0 + } + _mlgetv + _mlplot +end + +program define _mlprnt + gphprint,nologo +end +exit + +* version 1.6.3 11Mar2001 +* version 1.6.4 19Nov2003 - for stata 8, change where box opens +* version 1.6.5 30Mar2005 plot values not labels +* version 1.6.6 13Apr2005 plot values not labels +* version 1.7.0 18Nov2005 add sign and more variables - mlogview +* version 1.7.1 01Apr2006 +* - fix dialog box + diff --git a/Modules/ado/plus/m/mlogview.hlp b/Modules/ado/plus/m/mlogview.hlp new file mode 100644 index 0000000..a268974 --- /dev/null +++ b/Modules/ado/plus/m/mlogview.hlp @@ -0,0 +1,52 @@ +.- +help for ^mlogview^ - 1.6.1 - 2/22/01 +.- + +Plots odds ratios and discrete change coefficients from the +multinomial logit model. +------------------------------------------------------------ + +^Select variables^: select independent variables to include in plot + +^Select amount of change^: amount of discrete change to plot for each variable + ^+1^: unit change + ^+SD^: standard deviation change + ^0->1^: change from 0 to 1 + ^Don't plot^: exclude variable from plot +(Starting values for discrete change taken from output from ^prchange^, which +must be executed prior to executing ^mlogview^ if discrete change is to be +plotted.) + +^DC Plot^: draw discrete change plot + +^OR Plot^: draw odds ratio plot + +^OR+DC Plot^: draw odds ratio plot in which the size of the letters +indicates the discrete change + +^Next 6^: list next 6 independent variables for packed plot + +^Note^: title for plot + +^Number of tics^: # of tic marks on x axis of plot + +^Plot from^: minimum and maximum values of x axis for plot + +^Connect if^: for odds ratio plots, connect lines if not significant at + specified level + +^Base category^: value of category to use as base category for odds ratio plot + +^Pack odds ratio plot^: eliminate extra vertical space in odds ratio plot + +^Use variable labels^: use variable labels instead of names to identify +variables in plot + +^Print^: send plot to printer + +.- +Author: J. Scott Long + www.indiana.edu/~jslsoc/spost.htm + spostsup@@indiana.edu + + diff --git a/Modules/ado/plus/m/mnthlist.ado b/Modules/ado/plus/m/mnthlist.ado new file mode 100644 index 0000000..05d70b4 --- /dev/null +++ b/Modules/ado/plus/m/mnthlist.ado @@ -0,0 +1,123 @@ +program def mnthlist, rclass +*! NJC 1.0.0 9 January 2001 + version 6.0 + #delimit ; + syntax , [ Global(str) Noisily Caplc Uppercase Long + Number(int 12) Begin(str) Step(numlist int max=1 >=1) + Year(numlist int max=1 >100 <10000) ] ; + #delimit cr + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + if "`caplc'" != "" & "`uppercase'" != "" { + di in r "must choose between cap/lc and uppercase" + exit 198 + } + + if "`begin'" == "" { + local begin 1 + } + else { + capture confirm integer number `begin' + if _rc == 0 { + if `begin' < 1 | `begin' > 12 { + di in r "invalid begin( ) option" + exit 198 + } + } + else { /* grind through possible abbreviations */ + local b = lower(trim("`begin'")) + if substr("`b'",1,2) == "ja" { + local begin 1 + } + else if substr("`b'",1,1) == "f" { + local begin 2 + } + else if substr("`b'",1,3) == "mar" { + local begin 3 + } + else if substr("`b'",1,2) == "ap" { + local begin 4 + } + else if substr("`b'",1,3) == "may" { + local begin 5 + } + else if substr("`b'",1,3) == "jun" { + local begin 6 + } + else if substr("`b'",1,3) == "jul" { + local begin 7 + } + else if substr("`b'",1,2) == "au" { + local begin 8 + } + else if substr("`b'",1,1) == "s" { + local begin 9 + } + else if substr("`b'",1,1) == "o" { + local begin 10 + } + else if substr("`b'",1,1) == "n" { + local begin 11 + } + else if substr("`b'",1,1) == "d" { + local begin 12 + } + else { + di in r "invalid begin( ) option" + exit 198 + } + } + } + + if "`step'" == "" { local step = 1 } + + * upper( ) and lower( ) won't take strings >80 chars + if "`long'" != "" { + local m1 "January February March April May June" + local m2 "July August September October November December" + } + else { + local m1 "Jan Feb Mar Apr May Jun" + local m2 "Jul Aug Sep Oct Nov Dec" + } + + if "`caplc'" == "" { + local m1 = lower("`m1'") + local m2 = lower("`m2'") + } + + if "`uppercase'" != "" { + local m1 = upper("`m1'") + local m2 = upper("`m2'") + } + + local m "`m1' `m2'" + local i = 1 + local j = `begin' + if "`year'" != "" { + local y = `year' + (`begin' - 0.5) / 12 + } + + while `i' <= `number' { + local mnth : word `j' of `m' + local newlist "`newlist'`mnth'`year' " + local j = mod(`j' + `step', 12) + local j = cond(`j' == 0, 12, `j') + + if "`year'" != "" { + local y = `y' + `step' / 12 + local year = int(`y') + } + + local i = `i' + 1 + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/m/mnthlist.hlp b/Modules/ado/plus/m/mnthlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/m/mnthlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/m/mvtab1.ado b/Modules/ado/plus/m/mvtab1.ado new file mode 100644 index 0000000..485bf05 --- /dev/null +++ b/Modules/ado/plus/m/mvtab1.ado @@ -0,0 +1,30 @@ +*! version 1.0.0 \ scott long 2007-08-05 + +// task: tabulate only missing values +// project: workflow chapter 4 +// author: scott long \ 2007-08-05 + +// based on tab1.ado version 2.2.4 29sep2004 by StataCorp + +program define mvtab1, byable(recall) + version 6, missing + syntax varlist [if] [in] [fweight] [, *] + tokenize `varlist' + local stop : word count `varlist' + local i 1 + tempvar touse + mark `touse' `if' `in' [`weight'`exp'] + + local weight "[`weight'`exp']" + capture { + while `i' <= `stop' { + noisily di _n `"-> tabulation of ``i'' `if' `in'"' + * VVVVVVVV VVVV + cap noisily tab ``i'' if `touse' & ``i''>=. `weight' , `options' miss + if _rc!=0 & _rc!=1001 { exit _rc } + local i = `i' + 1 + } + } + error _rc +end +exit diff --git a/Modules/ado/plus/m/mvtab1.hlp b/Modules/ado/plus/m/mvtab1.hlp new file mode 100644 index 0000000..9a557bf --- /dev/null +++ b/Modules/ado/plus/m/mvtab1.hlp @@ -0,0 +1,22 @@ +.- +help for ^mvtab1^ :: 2008-03-07 +.- + +Tabulate missing values +----------------------- + + ^mvtab1^ varlist^,^ (see options for ^tab1^) + +Description +----------- + + ^mvtab1^ operates just like ^tab1^ except that it only prints frequency + distributions for missing values. + +Options +------- + + See ^tab1^ for a listing of options. + +.- +Author: Scott Long - www.indiana.edu/~jslsoc/workflow.htm diff --git a/Modules/ado/plus/n/nct.ado b/Modules/ado/plus/n/nct.ado new file mode 100644 index 0000000..2fc7dcd --- /dev/null +++ b/Modules/ado/plus/n/nct.ado @@ -0,0 +1,16 @@ +*! version 1.0.0 TJS 9jun2000 +program define nct + version 6.0 + +di _n in bl "nct is not an executable program." +di _n in bl "Available non-central t programs are:" +di _n in wh " nctprob t' delta df" in bl " /* yields p" +di _n in wh " nctinv p delta df" in bl " /* yields t'" +di _n in wh " nctncp t' p df" in bl " /* yields delta" +di _n in wh " nctn t' delta p" in bl " /* yields v2" +di _n in wh " nct2 t' delta df" in bl " /* yields two-sided p" +di _n in wh " nct2inv p delta df" in bl " /* yields two-sided t'" +di +exit 119 +end + diff --git a/Modules/ado/plus/n/nct.hlp b/Modules/ado/plus/n/nct.hlp new file mode 100644 index 0000000..a814e5f --- /dev/null +++ b/Modules/ado/plus/n/nct.hlp @@ -0,0 +1,124 @@ +.- +help for ^nct^ +.- + +Non-central t programs +---------------------- + + ^nctprob^ t' delta df /* yields p + + ^nctinv^ p delta df /* yields t' + + ^nctncp^ t' p df /* yields delta + + ^nctn^ t' delta p /* yields df + 1 + + ^nct2^ t' delta df /* yields two-sided p + + ^nct2inv^ p delta df /* yields two-sided t' + +where + + ^t'^ is the observed t-value + ^delta^ is the noncentrality parameter + ^df^ is the degrees of freedom (^df^ is a positive integer) + ^p^ is the probability (0 < ^p^ < 1) + +For each program, entering the program name with no parameters displays +the command syntax. + + +Description +----------- + +Let Y and Z be independent random variables, where + + Z ~ N(delta,1) (Z is distributed Normal with mean delta and variance 1) + Y ~ ChiSq(n) (Y is distributed chi-square with degrees of freedom n). + +Then, X = Z / sqrt(Y/n) is said to have a noncentral t distribution with +noncentrality delta and degrees of freedom n. + +That is, X ~ t(delta, n). + + +^nct^xxxx is a family of immediate programs, all related to the noncentral t +distribution. Each one-sided program computes a missing parameter, given +the other parameters, such that P(t<=^t'^| ^delta^, ^df^) = ^p^. + + for | use +------+-------------------------------------------------------- + ^p^ | ^nctprob^ -- Cumulative non-central t probabilities + ^t'^ | ^nctinv^ -- Inverse cumulative non-central t values +^delta^ | ^nctncp^ -- Noncentrality parameter of the non-central t + ^df^ | ^nctn^ -- Sample size for the cumulative non-central t + +There are also two programs that yield two-sided values from a noncentral t, +defined such that P(|t|<=^t'^| ^delta^, ^df^) = 1 - ^p^. + + for | use +------+-------------------------------------------------------- + ^p^ | ^nct2^ -- 2-sided non-central t probabilities + ^t'^ | ^nct2inv^ -- Inverse 2-sided non-central t values + +The core program, ^nctprob^, computes probabilities from the cumulative +non-central t distribution from negative infinity to ^t'^ for noncentrality +parameter, ^delta^, and positive, integer degrees of freedom, ^df^. +That is, ^nctprob^ computes ^p^ such that P(t<=^t'^| ^delta^, ^df^) = ^p^. + +Each program prints its computed value and returns it in global ^S_1^ and in +a result ^r()^. The value computed and the name of the returned parameter +for each program are: + +^nctprob^ -- ^r(p)^ -- the probability p +^nctinv^ -- ^r(t)^ -- the critical t' +^nctncp^ -- ^r(delta)^ -- the noncentrality parameter delta +^nctn^ -- ^r(n)^ -- the minimum n +^nct2^ -- ^r(p)^ -- the two-sided tail probability +^nct2inv^ -- ^r(t)^ -- the two-sided critical t' + +^nctn^ computes the minimum ^n^ such that, for ^df^ = ^n^ - 1, + when ^p^ < 0.5, P(t<=^t'^|^delta^, ^df^) <= ^p^, and + when ^p^ > 0.5, 1 - P(t<=^t'^|^delta^, ^df^) <= ^p^. + +Warning: Convergence time for ^nctn^ is a function of the computed minimum +^n^ and increases greatly when that ^n^ gets large. Because the limit of +the noncentral t (as n gets large) is the noncentral z, a comparison +of the desired probability ^p^ to P(z < ^t'^ - ^delta^) is informative. +If these values are within .005 of each other, convergence time will +be noticably non-negligible. + + +Notes +----- + +These programs call ^integ^. The user is cautioned that the initial +Stata 6.0 release of ^integ^ (version 3.0.4) has a bug. Please install +version 3.0.5 or later. + +Some of these programs require installation of programs ^ridder^ +(see STB-24, insert ssi5.4 for ^ridder^). + + +Author +------ + +Thomas J. Steichen <steicht@@rjrt.com> + + +Examples +-------- + + . ^nctprob 3.6 3.0 11^ > gives p for t' = 3.6, delta = 3.0, df = 11 + + . ^nctinv .95 2.0 17^ > gives t' for p = .95, delta = 2.0, df = 17 + + . ^nctncp 4.045 .95 17^ > gives delta for t' = 4.045, p = .95, df = 17 + + . ^nctinv 4 2 .95^ > gives n for t' = 4, delta = 2, p = .95 + + . ^nct2 3.1 2.0 17^ > gives p for |t'| = 3.1, delta = 2.0, df = 17 + + . ^nct2inv .05 2.0 17^ > gives |t'| for p = .05, delta = 2.0, df = 17 + + . ^nctprob^ > displays the command syntax diff --git a/Modules/ado/plus/n/nct2.ado b/Modules/ado/plus/n/nct2.ado new file mode 100644 index 0000000..7c9da1b --- /dev/null +++ b/Modules/ado/plus/n/nct2.ado @@ -0,0 +1,62 @@ +*! version 1.0.0 TJS 9jun2000 +program define nct2, rclass +version 6.0 + args t delta df + tempname p1 p2 ps + +if "`df'" == "" { + di in gr "Syntax for " in wh "nct2" in gr " is: " _n + di in wh " nct2 " in gr "t' delta df" _n + di in gr " where " in wh "t' " in gr "is the observed t" + di in wh " delta " in gr "is the noncentrality parameter" + di in wh " df " in gr "is the degrees of freedom" _n + di in wh " nct2 " in gr "computes " in wh "p" _c + di in gr " such that P(|t|<=" in wh "t'" in gr "| " in wh "delta" _c + di in gr ", " in wh "df" in gr ") = 1 - " in wh "p" + di in gr " and returns the value in result " _c + di in wh "r(p) " in gr "and global " in wh "S_1" in gr "." + + global S_1 = . + return scalar p = . + exit 9 + } + +capture which nctprob +if _rc == 111 { + di in re "nct2 requires installation of program nctprob." + di in wh " (contact T. J. Steichen at steicht@rjrt.com for nctprob)." + global S_1 = . + return scalar p = . + exit 111 + } + +qui nctprob `t' `delta' `df' +if _rc == 198 { + di in re "nct2 requires version 3.0.5 or later of integ." + di in wh " (use " in ye "which integ " _c + di in wh "to check version number)." + global S_1 = . + return scalar p = . + exit 198 + } +scalar `p2' = 1 - $S_1 + +local t = -`t' +qui nctprob `t' `delta' `df' +scalar `p1' = $S_1 + +scalar `ps' = `p2' + `p1' +global S_1 = `ps' +return scalar p = `ps' +local t = -`t' + +di _n in gr " P( t <= " -`t' " | delta = " _c +di in gr `2' ", df = " `3' ") = " in ye `p1' + +di in gr " P( t >= " `t' " | delta = " _c +di in gr `2' ", df = " `3' ") = " in ye `p2' + +di in gr " P(|t| <= " `t' " | delta = " _c +di in gr `2' ", df = " `3' ") = " in ye `ps' + +end diff --git a/Modules/ado/plus/n/nct2.hlp b/Modules/ado/plus/n/nct2.hlp new file mode 100644 index 0000000..b8ee446 --- /dev/null +++ b/Modules/ado/plus/n/nct2.hlp @@ -0,0 +1 @@ +.h nct diff --git a/Modules/ado/plus/n/nct2inv.ado b/Modules/ado/plus/n/nct2inv.ado new file mode 100644 index 0000000..48b1de8 --- /dev/null +++ b/Modules/ado/plus/n/nct2inv.ado @@ -0,0 +1,103 @@ +*! version 1.0.0 TJS 9jun2000 +program define nct2inv, rclass + version 6.0 + args p delta df + +di +if "`p'" == "" { + di in gr "Syntax for " in wh "nct2inv " in gr "is: " _n + di in wh " nct2inv " in gr "p delta df" _n + di in gr " where " in wh "p " _c + di in gr "is the desired total probability in the tails" + di in wh " delta " in gr "is the noncentrality parameter" + di in wh " df " in gr "is the degrees of freedom" _n + di in wh " nct2inv " in gr "computes " in wh "t'" _c + di in gr " such that P(|t| <= " in wh "t'" in gr " | " in wh "delta" _c + di in gr ", " in wh "df" in gr ") = 1 - " in wh "p" + di in gr " and returns the value in result " _c + di in wh "r(t) " in gr "and global " in wh "S_1" in gr "." + global S_1 = . + return scalar t = . + exit 9 + } + +if `p' < 0 | `p' > .5 { + di in re "p must be between 0 and .5" + global S_1 = . + return scalar t = . + exit 498 + } + +if `df' != int(`df') | `df' < 1 { + di in re "degrees of freedom must be a positive integer" + global S_1 = . + return scalar t = . + exit 498 + } + +capture which nct2 +if _rc == 111 { + di in re "nct2inv requires installation of helper program nct2." + di in wh " (nct2 is included with the distribution files " _c + di in wh "for nct2inv" + di in wh " or can be obtained by contacting T. J. Steichen " _c + di in wh "at steicht@rjrt.com)." + global S_1 = . + return scalar t = . + exit 111 + } +capture which ridder +if _rc == 111 { + di in re "nct2inv requires installation of program ridder." + di in wh " (see STB-24, insert ssi5.4 for ridder)." + global S_1 = . + return scalar t = . + exit 111 + } +capture which nctprob +if _rc == 111 { + di in re "nct2inv requires installation of program nctprob." + di in wh " (contact T. J. Steichen at steicht@rjrt.com for nctprob)." + global S_1 = . + return scalar t = . + exit 111 + } + +local min = `delta' +local max = `delta' + 100 / sqrt(`df') + +cap ridder nct2 X `delta' `df' returns macro S_1 = `p' /* + */ from `min' to `max' +if _rc == 430 { + local min = $S_1 - 1 + local max = $S_1 + 1 + qui ridder nct2 X `delta' `df' returns macro S_1 = `p' /* + */from `min' to `max' + } +if _rc == 409 { + di in re "internal error in guessing range: solution not bounded." + di in wh " (please report this error to T. J. Steichen at " + di in wh " steicht@rjrt.com, along with command attempted)." + global S_1 = . + return scalar t = . + exit 409 + } +if _rc == 198 { + di in re "nct2inv requires version 3.0.5 or later of integ." + di in wh " (use " in ye "which integ " _c + di in wh "to check version number)." + global S_1 = . + return scalar t = . + exit 198 + } + +global S_1 = abs($S_1) +return scalar t = $S_1 + +di _n in gr " |t'| =" in ye %10.6f $S_1 + +di _n in gr " P(|t| <= " in ye $S_1 in gr " | delta = " _c +di in gr `delta' ", df = " `df' ") = 1 - " `p' + + +end diff --git a/Modules/ado/plus/n/nct2inv.hlp b/Modules/ado/plus/n/nct2inv.hlp new file mode 100644 index 0000000..b8ee446 --- /dev/null +++ b/Modules/ado/plus/n/nct2inv.hlp @@ -0,0 +1 @@ +.h nct diff --git a/Modules/ado/plus/n/nctinv.ado b/Modules/ado/plus/n/nctinv.ado new file mode 100644 index 0000000..68f10ee --- /dev/null +++ b/Modules/ado/plus/n/nctinv.ado @@ -0,0 +1,94 @@ +*! version 1.0.1 TJS 9jun2000 +program define nctinv, rclass + version 6.0 + + args p delta df + +if "`p'" == "" { + di in gr "Syntax for " in wh "nctinv" _c + di in gr ", the inverse cumulative non-central t distribution, is:" _n + di in wh " nctinv " in gr "p delta df" _n + di in gr " where " in wh "p " in gr " is the probability" + di in wh " delta " in gr "is the noncentrality parameter" + di in wh " df " in gr " is the degrees of freedom" _n + di in wh " nctinv " in gr "computes " in wh "t'" in gr " such that" _c + di in gr " P(t<=" in wh "t'" in gr "| " in wh "delta" in gr ", " _c + di in wh "df" in gr ") = " in wh "p" + di in gr " and returns the value in result " _c + di in wh "r(t) " in gr "and global " in wh "S_1" in gr "." + global S_1 = . + return scalar t = . + exit 9 + } + +if `p' < 0 | `p' > 1 { + di in re "p must be between 0 and 1" + global S_1 = . + return scalar t = . + exit 498 + } + +if `df' != int(`df') | `df' < 1 { + di in re "degrees of freedom must be a positive integer" + global S_1 = . + return scalar t = . + exit 498 + } + +capture which ridder +if _rc == 111 { + di in re "nctinv requires installation of program ridder." + di in wh " (see STB-24, insert ssi5.4 for ridder)." + global S_1 = . + return scalar t = . + exit 111 + } +capture which nctprob +if _rc == 111 { + di in re "nctinv requires installation of program nctprob." + di in wh " (contact T. J. Steichen at steicht@rjrt.com for nctprob)." + global S_1 = . + return scalar t = . + exit 111 + } + +local min = `delta' - 100 / (`df'^.44) +local max = `delta' + 100 / (`df'^.44) +if `p' < 0.5 { local max = `delta' } +else { local min = `delta' } + +cap ridder nctprob X `delta' `df' returns macro S_1 = `p' /* + */ from `min' to `max' +if _rc == 430 { + local min = $S_1 - 1 + local max = $S_1 + 1 + qui ridder nctprob X `delta' `df' returns macro S_1 = `p' /* + */ from `min' to `max' + } +if _rc == 409 { + di in re "internal error in guessing range: solution not bounded." + di in wh " (please report this error to T. J. Steichen at " + di in wh " steicht@rjrt.com, along with command attempted)." + global S_1 = . + return scalar t = . + exit 409 + } +if _rc == 198 { + di in re "nctinv requires version 3.0.5 or later of integ." + di in wh " (use " in ye "which integ " _c + di in wh "to check version number)." + global S_1 = . + return scalar t = . + exit 198 + } + +return scalar t = $S_1 + +di _n in gr " t' =" in ye %10.6f $S_1 + +di _n in gr " P(t <= " in ye $S_1 in gr " | delta = " _c +di in gr `delta' ", df = " `df' _c +di in gr ") = " `p' + + +end diff --git a/Modules/ado/plus/n/nctinv.hlp b/Modules/ado/plus/n/nctinv.hlp new file mode 100644 index 0000000..b8ee446 --- /dev/null +++ b/Modules/ado/plus/n/nctinv.hlp @@ -0,0 +1 @@ +.h nct diff --git a/Modules/ado/plus/n/nctn.ado b/Modules/ado/plus/n/nctn.ado new file mode 100644 index 0000000..fc80feb --- /dev/null +++ b/Modules/ado/plus/n/nctn.ado @@ -0,0 +1,112 @@ +*! version 1.0.0 TJS 9jun2000 +program define nctn, rclass + version 6.0 + +args t delta p st +if "`st'" != "step" {local star "*"} +if lower("`st'") == "z" { local zstar " "} +else {local zstar "*"} + +if "`p'" == "" { + di in gr "Syntax for " in wh "nctn" in gr " is:" _n + di in wh " nctn " in gr "t' delta p" _n + di in gr " where " in wh "t' " in gr "is the observed t" + di in wh " delta " in gr "is the noncentrality parameter" + di in wh " p " in gr "is the probability" _n + di in wh " nctn " in gr "computes the minimum " in wh "n" _c + di in gr " such that, for " in wh "df " in gr "= " in wh "n" _c + di in gr " - 1, " + di in gr " when " in wh "p" in gr " < 0.5," _c + di in gr " P(t<=" in wh "t'" in gr "|" in wh "delta" _c + di in gr ", " in wh "df" in gr ") <= " in wh "p" in gr ", and " + di in gr " when " in wh "p" in gr " > 0.5," _c + di in gr " 1 - P(t<=" in wh "t'" in gr "|" in wh "delta" _c + di in gr ", " in wh "df" in gr ") <= " in wh "p" in gr "." _n + di in gr " The minimum " in wh "n" in gr " is returned in result " _c + di in wh "r(n) " in gr "and global " in wh "S_1" in gr "." + global S_1 = . + return scalar n = . + exit 9 + } + +capture which nctprob +if _rc == 111 { + di in re "nctn requires installation of program nctprob." + di in wh " (contact T. J. Steichen at steicht@rjrt.com for nctprob)." + global S_1 = . + return scalar n = . + exit 111 + } + +local z = `t' - `delta' +qui nctprob `t' `delta' 1 +local pr = r(p) +local zp = normprob(`z') +`star' di "nctprob(1):" `pr' +`star' di "z(inf):" `zp' +local mn = min(`pr', `zp') +local mx = max(`pr', `zp') +if `mn' > `p' | `mx' < `p' { + di in re "inconsistent parameters, no solution possible" + di in bl "note: permissible range for p given t' and delta is " _c + di in bl %6.4f `mn' " to " %6.4f `mx' + global S_1 = . + return scalar n = . + exit 459 + } + +`zstar' di in bl "note: if " in wh "p" in bl " = "_c +`zstar' di in ye %6.4f `p' in bl " approaches " _c +`zstar' di in ye %6.4f `zp' in bl " = P(z < " _c +`zstar' di in wh "t'" in bl " - " in wh "delta" in bl ")," +`zstar' di in wh "n " in bl "approaches infinity and " _c +`zstar' di in bl "convergence time increases greatly." +`zstar' global S_1 = . +`zstar' return scalar n = . +`zstar' exit 9 + +local sign "<" +local df = 1 +local pr = 1 +qui nctprob `t' `delta' 1 +local pr1 = r(p) +qui nctprob `t' `delta' 2 +local pr2 = r(p) +if `pr2' > `pr1' { + local sign ">" + local pr = 0 + } + +local step = int(abs(`zp' - `pr1') / abs(`zp' - `p')) +local df = `step' + +local f 0 + +while `f' == 0 { + qui nctprob `t' `delta' `df' + local pr0 = `pr' + local pr = r(p) + `star' di "df: " `df' " step: " `step' " p: " `pr' + if `p' `sign' `pr' { local df = `df' + `step' } + else { + if `step' == 1 & sign((`pr'-`p')/(`pr0'-`p')) < 0 { local f 1 } + else { + local step = max(1, int(`step' / 2)) + local df = `df' - `step' + } + } + } + +di in gr "for n = " in ye `df' + 1 in gr ", df = " in ye `df' _c +if `pr' < `p' { + di in gr " and p = " `pr' _c + di in gr " <= " `p' "." + } +else { + di in gr " and 1 - p = " 1 - `pr' _c + di in gr " <= " 1 - `p' " = 1 - " `p' "." + } +global S_1 = `df' +return scalar n = `df' + +end diff --git a/Modules/ado/plus/n/nctn.hlp b/Modules/ado/plus/n/nctn.hlp new file mode 100644 index 0000000..575aef8 --- /dev/null +++ b/Modules/ado/plus/n/nctn.hlp @@ -0,0 +1,2 @@ +.h nct + diff --git a/Modules/ado/plus/n/nctncp.ado b/Modules/ado/plus/n/nctncp.ado new file mode 100644 index 0000000..c1f3ae4 --- /dev/null +++ b/Modules/ado/plus/n/nctncp.ado @@ -0,0 +1,92 @@ +*! version 1.0.0 TJS 9jun2000 +program define nctncp, rclass + version 6.0 + + args t p df + +if "`p'" == "" { + di in gr "Syntax for " in wh "nctncp" in gr " is:" _n + di in wh " nctncp " in gr "t' p df" _n + di in gr " where " in wh "t' " in gr "is the observed t" + di in wh " p " in gr "is the probability" + di in wh " df " in gr "is the degrees of freedom" _n + di in wh " nctncp " in gr "computes " in wh "delta" _c + di in gr " such that P(t<=" in wh "t'" in gr "| " in wh "delta" _c + di in gr ", " in wh "df" in gr ") = " in wh "p" + di in gr " and returns the value in result " _c + di in wh "r(delta) " in gr "and global " in wh "S_1" in gr "." + global S_1 = . + return scalar delta = . + exit 9 + } + +if `p' < 0 | `p' > 1 { + di in re "p must be between 0 and 1" + global S_1 = . + return scalar delta = . + exit 498 + } + +if `df' != int(`df') | `df' < 1 { + di in re "degrees of freedom must be a positive integer" + global S_1 = . + return scalar delta = . + exit 498 + } + +capture which ridder +if _rc == 111 { + di in re "nctncp requires installation of program ridder." + di in wh " (see STB-24, insert ssi5.4 for ridder)." + global S_1 = . + return scalar delta = . + exit 111 + } +capture which nctprob +if _rc == 111 { + di in re "nctncp requires installation of program nctprob." + di in wh " (contact T. J. Steichen at steicht@rjrt.com for nctprob)." + global S_1 = . + return scalar delta = . + exit 111 + } + +local min = `t' - 100 / (`df'^.44) +local max = `t' + 100 / (`df'^.44) +if `p' > 0.5 { local max = `t' } +else { local min = `t' } + +cap ridder nctprob `t' X `df' returns macro S_1 = `p' /* + */ from `min' to `max' +if _rc == 430 { + local min = $S_1 - 1 + local max = $S_1 + 1 + qui ridder nctprob `t' X `df' returns macro S_1 = `p' /* + */ from `min' to `max' + } +if _rc == 409 { + di in re "internal error in guessing range: solution not bounded." + di in wh " (please report this error to T. J. Steichen at " + di in wh " steicht@rjrt.com, along with command attempted)." + global S_1 = . + return scalar delta = . + exit 409 + } +if _rc == 198 { + di in re "nctncp requires version 3.0.5 or later of integ." + di in wh " (use " in ye "which integ " _c + di in wh "to check version number)." + global S_1 = . + return scalar delta = . + exit 198 + } + +return scalar delta = $S_1 + +di _n in gr " delta =" in ye %10.6f $S_1 + +di _n in gr " P(t <= " `t' " | delta = " _c +di in ye $S_1 in gr ", df = " `df' _c +di in gr ") = " `p' + +end diff --git a/Modules/ado/plus/n/nctncp.hlp b/Modules/ado/plus/n/nctncp.hlp new file mode 100644 index 0000000..b8ee446 --- /dev/null +++ b/Modules/ado/plus/n/nctncp.hlp @@ -0,0 +1 @@ +.h nct diff --git a/Modules/ado/plus/n/nctprob.ado b/Modules/ado/plus/n/nctprob.ado new file mode 100644 index 0000000..c2e803a --- /dev/null +++ b/Modules/ado/plus/n/nctprob.ado @@ -0,0 +1,198 @@ +*! version 1.0.1 TJS 9jun2000 +program define nctprob, rclass + version 6.0 + args t delta df extra + +if "`df'" == "" | "`extra'" != "" { + di in gr "Syntax for " in wh "nctprob" _c + di in gr ", the cumulative non-central t" + di in gr "distribution from negative infinity to t', is: " _n + di in wh " nctprob " in gr "t' delta df" _n + di in gr " where " in wh "t' " in gr "is the observed t" + di in wh " delta " in gr "is the noncentrality parameter" + di in wh " df " in gr "is the degrees of freedom" _n + di in wh " nctprob " in gr "computes " in wh "p" _c + di in gr " such that P(t<=" in wh "t'" in gr "| " in wh "delta" _c + di in gr ", " in wh "df" in gr ") = " in wh "p" + di in gr " and returns the value in result " _c + di in wh "r(p) " in gr "and global " in wh "S_1" in gr "." + global S_1 = . + return scalar p = . + exit 9 + } + +if `df' != int(`df') | `df' < 1 { + di in re "degrees of freedom must be a positive integer" + global S_1 = . + return scalar p = . + exit 498 + } + +local even = mod(`df',2) == 0 + +/* numerical calculation of C(h,a) requires -preserve- + but C(h,a) is only needed for odd df's */ +if !`even' { preserve } + +tempname A B h a p C M0 M1 M2 ak Mo Me k Mk +tempvar x y + +scalar `A' = `t' / sqrt(`df') +scalar `B' = `df' / (`df' + (`t')^2) +scalar `h' = `delta' * sqrt(`B') + +if `even' { scalar `p' = normprob(-(`delta')) } +else { + scalar `p' = normprob(-(`delta' * sqrt(`B'))) + scalar `a' = abs(`A') + qui range `x' 0 `a' 1001 + gen `y' = exp(-((`h')^2 / 2) * (1 + (`x')^2)) / (1 + (`x')^2) + qui integ `y' `x' + scalar `C' = r(integral)/ (2 * _pi) + scalar `p' = `p' + 2 * `C' * sign(`A') + } +if `df' == 1 { + di _n in gr " p =" in ye %10.6f `p' + di _n in gr " P(t <= " `t' " | delta = " _c + di in gr `delta' ", df = " `df' _c + di in gr ") = " in ye `p' + global S_1 = `p' + return scalar p = `p' + exit + } + +scalar `M0' = `A' * sqrt(`B') * normd(`delta' * sqrt(`B')) +scalar `M0' = `M0' * normprob(`delta' * `A' * sqrt(`B')) +if `df' == 2 { + scalar `p' = `p' + sqrt(2 * _pi) * `M0' + di _n in gr " p =" in ye %10.6f `p' + di _n in gr " P(t <= " `t' " | delta = " _c + di in gr `delta' ", df = " `df' _c + di in gr ") = " in ye `p' + global S_1 = `p' + return scalar p = `p' + exit + } + +scalar `M1' = `A' * normd(`delta') / sqrt(2 * _pi) +scalar `M1' = `B' * (`delta' * `A' * `M0' + `M1') +if `df' == 3 { + scalar `p' = `p' + 2 * `M1' + di _n in gr " p =" in ye %10.6f `p' + di _n in gr " P(t <= " `t' " | delta = " _c + di in gr `delta' ", df = " `df' _c + di in gr ") = " in ye `p' + global S_1 = `p' + return scalar p = `p' + exit + } + +scalar `M2' = `B' * ( `delta' * `A' * `M1' + `M0') / 2 +if `df' == 4 { + scalar `p' = `p' + sqrt(2 * _pi) * (`M0' + `M2') + di _n in gr " p =" in ye %10.6f `p' + di _n in gr " P(t <= " `t' " | delta = " _c + di in gr `delta' ", df = " `df' _c + di in gr ") = " in ye `p' + global S_1 = `p' + return scalar p = `p' + exit + } + +* calculate Mk's for k = 3 to `df'-2 and sum odds and evens +scalar `ak' = 1 +scalar `Mo' = `M1' +scalar `Me' = `M0' + `M2' +scalar `k' = 3 +while `k' <= `df' - 2 { + scalar `ak' = 1 / ((`k' - 2) * `ak') + scalar `Mk' = `ak' * `delta' * `A' * `M2' + `M1' + scalar `Mk' = (`k'-1) * `B' * `Mk' / `k' + if mod(`k',2) == 0 { scalar `Me' = `Me' + `Mk' } + else { scalar `Mo' = `Mo' + `Mk' } + scalar `M1' = `M2' + scalar `M2' = `Mk' + scalar `k' = `k' + 1 + } +if `even' { scalar `p' = `p' + sqrt(2 * _pi) * `Me' } +else { scalar `p' = `p' + 2 * `Mo' } + +di _n in gr " p =" in ye %10.6f `p' +di _n in gr " P(t <= " `t' " | delta = " _c +di in gr `delta' ", df = " `df' _c +di in gr ") = " in ye `p' + +global S_1 = `p' +return scalar p = `p' + +exit +end + +/* ------------------------------------------------------------ + +Note: formula implemented above is from + D. B. Owen (Technometrics 10(3):445-478, 1968) + + +Let + t be the observed t-value + d be the non-centrality parameter + v be the degrees of freedom + + G(z) be the cumulative standard Normal distribution + G'(z) be the standard Normal density function + +Define + + A = t / sqrt(v) + + B = v / (v + t^2) + +then + + M = 0 + -1 + + M = A * sqrt(B) * G'(d * sqrt(B)) * G(d * A * sqrt(B)) + 0 + + M = B * [ d * A * M + A * G'(d) / sqrt(2 * pi)] + 1 0 + + M = B * [ d * A * M + M ] + 2 0 1 + +and, for k>= 3, + + M = (k - 1) * B * [ a * d * A * M + M ] / k + k k k-1 k-2 + + where a = 1 / [(k - 2) * a ] and a = 1 + k k-1 2 + + +Finally, for even df's, + +P{T <= t | d, v} = + G(-d) + sqrt(2 * pi) * [M + M + ... + M ] + 0 2 v-2 + +and for odd df's, + +P{T <= t | d, v} = + G(-d * sqrt(B)) + 2 * C(d * sqrt(B), A) + 2 * [M + M + ... + M ] + 1 3 v-2 + + + where + abs(a) + 1 / exp[-h^2 / 2 * (1 + x^2)] + C(h,a) = sign(a) -------- | --------------------------- dx + 2 * pi / 1 + x^2 + x=0 + + +Note: integral C(h,a) is computed numerically in this program. + +------------------------------------------------------------ */ + diff --git a/Modules/ado/plus/n/nctprob.hlp b/Modules/ado/plus/n/nctprob.hlp new file mode 100644 index 0000000..b8ee446 --- /dev/null +++ b/Modules/ado/plus/n/nctprob.hlp @@ -0,0 +1 @@ +.h nct diff --git a/Modules/ado/plus/n/nicenum.ado b/Modules/ado/plus/n/nicenum.ado new file mode 100644 index 0000000..eab3d93 --- /dev/null +++ b/Modules/ado/plus/n/nicenum.ado @@ -0,0 +1,138 @@ +*! version 1.1.0 11/4/94 (STB-25: dm28) +program define nicenum + version 4.0 + local mac "`1'" + if "`2'" != "=" { + di in red /* + */ "nicenum macroname = arglist [if expr] [in range], Number(#)" + error 198 + } + mac shift 2 + local remain "`*'" + parse "`*'", parse(",") + local arglist "`1'" + local opts "`3'" + + parse "`arglist'", parse(" ") + while "`1'" != "" & "`1'" != "if" & "`1'" != "in" { + capture confirm var `1' + if _rc != 0 { + local numlist "`numlist' `1'" + } + else { local varlist "`varlist' `1'" } + mac shift + } + tempvar use + mark `use' `*' + markout `use' `varlist' + + tempname gmin gmax + scalar `gmin' = . /* uninitialized state */ + scalar `gmax' = . + if "`varlist'" != "" { + parse "`varlist'", parse(" ") + quietly summ `1' if `use' + scalar `gmin' = _result(5) + scalar `gmax' = _result(6) + mac shift + while "`1'" != "" { + quietly summ `1' if `use' + scalar `gmin'=cond(_result(5)<`gmin',_result(5),`gmin') + scalar `gmax'=cond(_result(6)>`gmax',_result(6),`gmax') + mac shift + } + } + + parse "`numlist'", parse(" ") + while "`1'" != "" { + if `gmin'==. { scalar `gmin' = `1' } + if `gmax'==. { scalar `gmax' = `1' } + scalar `gmin' = cond(`1'<`gmin',`1',`gmin') + scalar `gmax' = cond(`1'>`gmax',`1',`gmax') + mac shift + } + + local command "`*' , `opts'" + local varlist "opt" + local options "Number(int 4)" + + parse "`command'" + + if `number' < 1 | `number' > 19 { + di in red "number must be in [1,19]" + error 198 + } + local inter = `number' + 1 + + local ntick = `inter' + quietly { + tempname gran exp d f nf tmp1 tmp2 + + scalar `gran' = `gmax'-`gmin' + scalar `exp' = log10(`gran') + scalar `exp' = int(`exp') - (`exp'<0.0) + scalar `f' = `gran'/(10^`exp') + if `f' <= 1. { scalar `nf' = 1. } + else if `f' <= 2. { scalar `nf' = 2. } + else if `f' <= 5. { scalar `nf' = 5. } + else { scalar `nf' = 10. } + + scalar `gran' = `nf'*10^`exp' + + scalar `d' = `gran'/(`ntick'-1) + scalar `exp' = log10(`d') + scalar `exp' = int(`exp')-(`exp'<0.0) + scalar `f' = `d'/(10^`exp') + if `f' < 1.5 { scalar `nf' = 1. } + else if `f' < 3. { scalar `nf' = 2. } + else if `f' < 7. { scalar `nf' = 5. } + else { scalar `nf' = 10. } + + scalar `d' = `nf'*10^`exp' + + scalar `gmin' = `gmin'/`d' + scalar `gmin' = (int(`gmin') - (`gmin'<0.0))*`d' + scalar `tmp1' = `gmax'/`d' + scalar `tmp2' = int(`tmp1') + if `tmp2' < float(`tmp1') { scalar `tmp2' = `tmp2'+1 } + scalar `gmax' = `tmp2'*`d' + scalar `tmp1' = log10(`d') + local nfrac = int(-`tmp1')+(`tmp1'<0.0) + if `nfrac'<=0 { local nfrac = 0 } + + if `nfrac' > 20 { + noi di in red "numbers too small for nice labels" + error 198 + } + + global `mac' "" + + if `nfrac' == 0 { + scalar `tmp1' = `gmin' + } + else { + scalar `tmp1' = `gmin' + 1/(10^(`nfrac'+1)) + } + scalar `tmp2' = `gmax' + `d'/2 + local comma "" + while `tmp1' <= `tmp2' { + local stub = int(`tmp1') + if `nfrac' { + local gminb = int(`tmp1'*(10^`nfrac')) + local stubb = int(`stub'*(10^`nfrac')) + local frac = `gminb'-`stubb' + local frst = "00000000000000000000" + /* + */ string(`frac') + local fstr = substr("`frst'",-`nfrac',.) + global `mac' = "${`mac'}`comma'`stub'.`fstr'" + } + else { + local tstr = string(`tmp1') + global `mac' = "${`mac'}`comma'`tstr'" + } + scalar `tmp1' = `tmp1' + `d' + local comma "," + } + +end + diff --git a/Modules/ado/plus/n/nmlab.ado b/Modules/ado/plus/n/nmlab.ado new file mode 100644 index 0000000..7388f64 --- /dev/null +++ b/Modules/ado/plus/n/nmlab.ado @@ -0,0 +1,55 @@ +*! version 1.0.0 \ scott long 2007-08-05 + +// syntax: nmlab <list of variables>, column(for labels) number vl +// task: list variable names and labels +// project: workflow chapter 4 +// author: scott long \ 2007-08-05 + +capture program drop nmlab +program define nmlab + version 8, missing + syntax [varlist] [, COLumn(integer 0) NUMber vl] + tokenize `varlist' + local stop : word count `varlist' + + local len = 0 + local i 1 + while `i' <= `stop' { + local l = length("``i''") + if `l'>`len' local len = `l' + local i = `i' + 1 + } + if `column'==0 local column = `len' + 3 + + display + local i 1 + if "`number'"=="number" { + local column = `column' + 6 + } + else { + local n "" + } + + * value label location + if "`vl'"=="vl" { + local column2 = `column' + 11 // for labels + } + + while `i' <= `stop' { + local varlbl : variable label ``i'' // grab var label + local vallbl : value label ``i'' // grab value label + + if "`number'"=="number" { + local n = substr(string(`i',"%4.0f") + ". ",1,6) + } + if "`vl'"!="vl" { + display in green "`n'``i''" in y _col(`column') "`varlbl'" + } + else { // show value label + display in green "`n'``i''" in white _col(`column') /// + "`vallbl'" in y _col(`column2') "`varlbl'" + } + local i = `i' + 1 + } +end +exit diff --git a/Modules/ado/plus/n/nmlab.hlp b/Modules/ado/plus/n/nmlab.hlp new file mode 100644 index 0000000..baeb895 --- /dev/null +++ b/Modules/ado/plus/n/nmlab.hlp @@ -0,0 +1,49 @@ +.- +help for ^nmlab^ :: 2008-03-07 +.- + +Create a list of variable names and variable labels +--------------------------------------------------- + + ^nmlab^ varlist^,^ [ ^num^ber ^col(^#^)^ ^vl^ ] + +Description +----------- + + ^nmlab^ lists the names and variable labels for a list of variables + that you provide. + +Options +------- + + ^number^ produces a numbered list. + + ^col(^#^)^ indicates the column in which the variable label will begin. + By default, the label begins in column 12. + + ^vl^ lists the value label assigned to each variable. + +Examples +-------- + + . ^use wf-lfp^ + (Data from 1976 PSID-T Mroz) + + . ^nmlab lfp k5^ + lfp In paid labor force? 1=yes 0=no + k5 # kids < 6 + + . ^nmlab lfp k5, num^ + #1: lfp In paid labor force? 1=yes 0=no + #2: k5 # kids < 6 + + . ^nmlab lfp k5, num col(15)^ + #1: lfp In paid labor force? 1=yes 0=no + #2: k5 # kids < 6 + + . ^nmlabel lfp k5, vl^ + lfp lfp In paid labor force? 1=yes 0=no + k5 # kids < 6 + +.- +Author: Scott Long - www.indiana.edu/~jslsoc/workflow.htm diff --git a/Modules/ado/plus/o/outreg2.ado b/Modules/ado/plus/o/outreg2.ado new file mode 100644 index 0000000..6aa19eb --- /dev/null +++ b/Modules/ado/plus/o/outreg2.ado @@ -0,0 +1,8757 @@ +*! outreg2 2.2.2 18nov2009 by roywada@hotmail.com +*! based on outreg 3.0.6/4.0.0 by john_gallup@alum.swarthmore.edu + +program define outreg2, by(onecall) sortpreserve + versionSet + version `version' + +*** per Richard W., store the currently active estimates to be restored later +tempname coefActive +* capture for prior to Stata 8.2 +cap _estimates hold `coefActive', restore copy nullok + +* getting the colon : parsings +/* not version 7 friendly +_on_colon_parse `0' +local 0 `"`s(before)'"' +local rest `"`s(after)'"' +outreg2 : `"`rest'"' if `touse'==1 */ + +if "`Version7'"=="" { + local bind "" +} +else { + local bind "bind" +} + +local behind `"`0'"' +local 0 "" +gettoken front behind: behind, parse(" ,") +local 0 "" +local done 0 +while `"`front'"'~="" & `done'==0 { + if `"`front'"'=="using" { + + gettoken rest behind: behind, parse(" ,") + * strip off quotes + gettoken first second: rest, parse(" ") + cap local rest: list clean local(rest) + + * take off colon at the end + local goldfish "" + if index(`"`rest'"',":")~=0 { + local end=substr(`"`rest'"',length(`"`rest'"'),length(`"`rest'"')) + if "`end'"==":" { + local rest=substr(`"`rest'"',1,`=length(`"`rest'"')-1') + local goldfish " : " + } + } + + * colon reattached with a space at the end + * .txt attached here for seeout working with _pref.ado + local rabbit `"""' + if index(`"`rest'"', ".")==0 { + local using `"`rabbit'`rest'.txt`rabbit'`goldfish'"' + } + else { + local using `"`rabbit'`rest'`rabbit'`goldfish'"' + } + local 0 `"`0' using `using' `behind'"' + local done 1 + } + else { + local 0 `"`0' `front'"' + gettoken front behind: behind, parse(" ,") + } +} + + +gettoken first second : 0, parse(":") `bind' match(par) quotes +local 0 `"`first'"' +while `"`first'"'~=":" & `"`first'"'~="" { + gettoken first second : second, parse(":") `bind' match(par) quotes +} +if `"`0'"'==":" { + * colon only when shorthand combined with prefix + local 0 +} +else { + local _0 `"`0'"' +} + + +*** shorthand syntax if [using] is missing +syntax [anything] [using] [if] [in] [pweight aweight iweight] [, SEEout REPLACE NOSEEOUT NOREPLACE CROSStab AGAIN * ] + + +*** bys( ): by(onecall) indicated by `_byvars' only + +* goes with `second' +if `"`second'"'~="" { + local _colon ":" +} + +if "`_byvars'"~="" { + bys `_byvars' : outreg2_by `0' `_colon' `second' +} +else if "`crosstab'"~="" { + outreg2_by `0' `_colon' `second' +} +else { + * regular stuff + if `"`using'"'~="" { + * both prefix full syntax and regular non-prefix usage + * `second' could contain " " only + `second' + _outreg2 `0' + } + else { + * prefix shorthand synatx + syntax [anything] [, REPLACE SEEout APpend] + + `second' + + *** read the set preference if not out of date + + * NOTE: `0' is written over below + + cap quietly findfile outreg2.pref + if _rc~=0 & "`Version7'"~="" { + * create it if missing + findfile outreg2.ado + local place=substr(`"`r(fn)'"',1,`=length(`"`r(fn)'"')-11') + + tempname myplace + cap file open `myplace' using `"`place'outreg2.pref"', write text replace + cap file write `myplace' "" _n + cap file write `myplace' "" _n + cap file write `myplace' "" + cap file close `myplace' + } + + tempname myfile + cap file open `myfile' using `"`r(fn)'"', read text + cap file read `myfile' date + cap file read `myfile' pref + cap file read `myfile' options + cap file close `myfile' + + * fix _comma + local _comma "" + if `"`macval(options)'"'~="" | "`replace'"~="" | "`seeout'"~="" { + local _comma "," + } + + if "`date'"== "`c(current_date)'" { + local seecommand "outreg2" + local precommand "_outreg2" + foreach var in anything macval(pref) _comma macval(options) replace seeout { + if `"``var''"'~="" { + if `"``var''"'=="," { + local seecommand `"`seecommand'``var''"' + local precommand `"`precommand'``var''"' + } + else { + local seecommand `"`seecommand' ``var''"' + local precommand `"`precommand' ``var''"' + } + } + } + *local cl `"{stata `"`seecommand'"': `seecommand'}"' + *di as txt `"`cl'"' + di in white `" `seecommand'"' + `precommand' + } + else { + di in red "must specify the full syntax (the last preference has expired)" + exit 100 + } + } +} + +*** saving the current preferences +if `"`using'"'=="" { + local _0 `"`seecommand'"' +} + +local 0 `"`_0'"' + +* take out sum/crosstab and +* take out [if] [in] [pweight aweight iweight] +* take out non-user specified options: replace/noreplace seeout/noseeout +syntax [anything] [using] [if] [in] [pweight aweight iweight] [, REPLACE NOREPLACE SUM SUM2(string) CROSStab SEEout /* + */ NOSEEOUT CTTOP *] + +local pref `"`using'"' + +* NOTE: `0' has been overwritten long ago + + cap quietly findfile outreg2.pref + if _rc~=0 & "`Version7'"~="" { + * create it if missing + findfile outreg2.ado + local place=substr(`"`r(fn)'"',1,`=length(`"`r(fn)'"')-11') + + tempname myplace + cap file open `myplace' using `"`place'outreg2.pref"', write text replace + cap file write `myplace' "" _n + cap file write `myplace' "" _n + cap file write `myplace' "" + cap file close `myplace' + } + +cap quietly findfile outreg2.pref +tempname myfile + +* capture for write protected files +cap file open `myfile' using `"`r(fn)'"', write text replace +cap file write `myfile' `"`c(current_date)'"' _n +cap file write `myfile' `"`pref'"' _n +cap file write `myfile' `"`options'"' +cap file close `myfile' + +*** display clickables +foreach var in tex word excel { + if `"`cl_`var''"'~="" { + noi di as txt `"`cl_`var''"' + } +} + +*** cdout thing +noi _cdout, cont + +foreach var in see { + if `"`cl_`var''"'~="" { + noi di as txt `"`cl_`var''"' + } +} + + +* restoring the currently active estimate here +cap _estimates unhold `coefActive' + +end /* end of outreg2 */ + + +******************************************************************************************** + + +program define outreg2_by, by(recall, nohead) + versionSet + version `version' + +preserve + +gettoken first second : 0, parse(":") `bind' match(par) quotes +local 0 `"`first'"' +while `"`first'"'~=":" & `"`first'"'~="" { + gettoken first second : second, parse(":") `bind' match(par) quotes + +} + +if `"`0'"'==":" { + * colon only when shorthand combined with prefix + local 0 +} +else { + local _0 `"`0'"' +} + +*** shorthand syntax if [using] is missing +syntax [anything] [using] [if] [in] [pweight aweight iweight] [, SEEout REPLACE NOSEEOUT NOREPLACE CROSStab AGAIN * ] + +*** bys( ) clean up: touse, ctitle/cctop, replace/noreplace, seeout/noseeout +if `=_by()'==1 { + + marksample touse + + * generate column heading when -by- specified + if `"`cttop'"'~="" { + local cc=1 + + tokenize `_byvars' + while "``cc''"~="" { + + * should there be `touse' here? + qui sum ``cc'' if `_byindex' == `=_byindex()' & `touse', meanonly + if r(N)<. { + local actual`cc' =r(mean) + } + else { + local actual`cc' =. + } + + * place cttop in there + local _comma + if `cc'~=1 { + local _comma "," + } + + local cttop "`cttop'`_comma' ``cc'' `actual`cc'' " + *local cttop "`cttop'`_comma' ``cc'', `actual`cc'' " + local cc=`cc'+1 + } + } + else { + local cc=1 + local cttop "" + + tokenize `_byvars' + while "``cc''"~="" { + + * should there be `touse' here? + qui sum ``cc'' if `_byindex' == `=_byindex()' & `touse', meanonly + if `r(N)'<. { + local actual`cc' =r(mean) + } + else { + local actual`cc' =. + } + + * place cttop in there + local _comma + if `cc'~=1 { + local _comma "," + } + + local cttop "`cttop'`_comma' ``cc'' `actual`cc'' " + *local cttop "`cttop'`_comma' ``cc'', `actual`cc'' " + local cc=`cc'+1 + } + } + + * lazy + qui keep if `touse'==1 + + local 0 `0' cttop(`cttop') + + * drop bys( ) from ctitles + if "`drop'"=="" { + local drop `"`_byvars'"' + local 0 `0' drop(`drop') + } + + * replace first when -by- specified + if `=_byindex()'==1 { + local noreplace "" + } + else { + local noreplace "noreplace" + } + + * seeout last when -by- specified + if `=_bylastcall()'==0 { + local noseeout "noseeout" + } + else { + local noseeout "" + } + + + * pass an embedded indicator to the second runs + if "`again'"=="" { + local again "again" + } + + * simplify by dropping them + drop `touse' `_byindex' +} + +* this will include the outputs from bys( ) routine above: +local 0 `0' `noreplace' `noseeout' + +* for multiple tabs +local names `"`anything'"' +if "`crosstab'"=="crosstab" & `"`names'"'=="" { + noi di in red "varlist required for {opt crosstab} option" + exit 100 +} + +* separate the first variable from the rest, which are for the bys( ) +gettoken first rest : names, parse(" ") +if "`crosstab'"=="crosstab" & "`first'"~="" & "`rest'"~="" { + cap drop _fillin + cap fillin `rest' + if "`replace'"=="replace" { + + } + *local 0 `first' `if' `in' [`weight'`exp'] `using', `seeout' `replace' `crosstab' nonotes `options' cttop(`cttop') + local 0 `first' `using', `seeout' `replace' `crosstab' nonotes `options' cttop(`cttop') + + if `"`second'"'=="" { + qui bys `rest' : outreg2_by `0' + } + else { + noi bys `rest' : outreg2_by `0' : `second' + } +} +else { + * single tabs or no crosstab at all + if (`"`second'"'=="" | `"`second'"'==" ") & `"`using'"'~="" { + * non-prefix + _outreg2 `0' + } + else { + `second' + _outreg2 `0' + } +} /* no crosstab */ + + +*** pass it forward +foreach var in tex word excel see { + c_local cl_`var' `"`cl_`var''"' +} + +end /* end of outreg2_by */ + + +******************************************************************************************** + + +program define _outreg2 + * write formatted regression output to file + + versionSet + version `version' + +syntax [anything] using [if] [in] [pweight aweight iweight] [, /* +*/ eqdrop(string) eqkeep(string) drop(string) keep(string) /* +*/ matrix(string) noNOBS noOBS /* +*/ COEfastr APpend REPLACE NOREPLACE SEEout NOSEEOUT /* +*/ LABel LABelA(passthru) TItle(passthru) CTitle(string) CTTOP(string) /* +*/ TEX TEX1(passthru) WORD EXCEL TEXT EQuationsA(passthru) /* +*/ Onecol LONG SIDEway COMma Quote noNOTes ADDNote(passthru) /* +*/ STats(string asis) ESTATS(passthru) noSE TSTAT Pvalue CI BEta /* +*/ Level(integer $S_level) /* +*/ noPAren PARenthesis(string asis) BRacket BRacketA(string) *] + +local usingTemp `"`using'"' +local ifTemp `"`if'"' +local inTemp `"`in'"' +local weightTemp `"`weight'"' +local expTemp `"`exp'"' + +local cttop1 `"`cttop'"' +local cttop + +local drop1 `"`drop'"' +local drop + +* cascading options: +local 0 `", `options'"' +syntax [, noASter 2aster ALPHA(passthru) SYMbol(passthru) 10pct /* +*/ ASTERisk(passthru) /* +*/ noCONs noNI noR2 ADJr2 E(string) /* +*/ ADDStat(passthru) ADDText(string) /* +*/ EForm MFX Margin1 Margin2(string) /* +*/ SUM SUM2(string) CROSStab TAB3(string) /* +*/ sortcol(string) sortvar(string) groupvar(string) /* +*/ CTTOP(string) drop(string) /* +*/ again leave(string) /* +*/ pivot xpose slow(numlist) raw *] + +* cascading options: +local 0 `", `options'"' +syntax [, DEC(numlist int >=0 <=11 max=1) FMT(passthru) /* +*/ BDec(numlist int >=0 <=11) BFmt(string asis) /* +*/ SDec(numlist int >=0 <=11) SFmt(string asis) /* +*/ Tdec(numlist int >=0 <=11 max=1) TFmt(string asis) /* +*/ PDec(numlist int >=0 <=11 max=1) PFmt(string asis) /* +*/ CDec(numlist int >=0 <=11 max=1) CFmt(string asis) /* +*/ ADec(numlist int >=0 <=11 max=1) AFmt(string asis) /* +*/ RDec(numlist int >=0 <=11 max=1) RFmt(string asis) /* +*/ AUTO(integer 3) LESS(integer 0) NOAUTO ] + +local using `"`usingTemp'"' +local using `"`usingTemp'"' +local if `"`ifTemp'"' +local in `"`inTemp'"' +local weight `"`weightTemp'"' +local exp `"`expTemp'"' + +* consolidate twice-mentioned options by double bys( ) +if `"`cttop'"'=="" { + local cttop `"`cttop1'"' +} +else if `"`cttop1'"'~="" { + local cttop `"`cttop1', `cttop'"' +} + +if `"`drop'"'=="" { + local drop `"`drop1'"' +} +else if `"`drop1'"'~="" { + local drop `"`drop1', `drop'"' +} + +* name of 1st column containing variable names +local VARIABLES "VARIABLES" +local VARIABLES1 "VARIABLES" + +*** a partial list of original macro names +* neq is the number of equation +* numi is e(N_g), the xt number of groups +* noNI is user request to not to report xt number of groups +* ivar is the e(ivar), the id for xt + +*** the original ctitle +local ctitle0 `"`ctitle'"' + +*** replace/noreplace seeout/noseeout +if "`noreplace'"=="noreplace" { + local replace "" + local noreplace "" +} +if "`noseeout'"=="noseeout" { + local seeout "" + local noseeout "" +} + +*** default warnings +if "`replace'"=="replace" & "`append'"=="append" { + di in green "replaced when both {opt replace} and {opt append} chosen" + local replace "replace" + local append "" +} + +*** set default options +if "`replace'"=="" & "`append'"=="" { + local append "append" +} + +*** betaco option into beta +if "`betaco'"=="betaco" { + local beta "beta" { +} + +*** no observation +if "`nobs'"=="nonobs" { + * recycling the original outreg option + local obs "noobs" + local nobs "" +} +* casewise and raw +if "`raw'"=="raw" & "`casewise'"=="casewise" { + noi di in red "cannot choose {opt case:wise} and {opt raw} at the same time" + exit 198 +} +* laptop slowdown +if "`slow'"=="" { + local slow 1 +} + +*** separate the varist from the estimates names +local open=index("`anything'","[") +local close=index("`anything'","]") + +if `open'~=0 & `close'~=0 { + local estimates=trim(substr("`anything'",`open'+1,`close'-`open'-1)) + local temp1=trim(substr("`anything'",1,`open'-1)) + local temp2=trim(substr("`anything'",`close'+1,length("`anything'"))) + local varlist=trim("`temp1' `temp2'") +} +else { + local varlist "`anything'" +} + +*** varlist, keep, drop, eqkeep, eqdrop +if "`varlist'"~="" & "`keep'"~="" { + di in yellow "{opt keep( )} supersedes {opt varlist} when both specified" +} +if "`drop'"~="" & "`keep'"~="" { + di in red "cannot specify both {opt keep( )} and {opt drop( )}" + exit 198 +} + +/******* allow this for now due to drop(`_byvars') +if "`drop'"~="" & "`varlist'"~="" { + * crosstab exception for MISSING + if "`crosstab'"~="crosstab" { + di in red "cannot specify both {it:varlist} and {opt drop( )}" + exit 198 + } +} +*/ + +if "`eqdrop'"~="" & "`eqkeep'"~="" { + di in red "cannot specify both {opt eqkeep( )} and {opt eqdrop( )}" + exit 198 +} + +*** pre-clean (while data is available) +* unambiguate them +if "`keep'"~="" { + tsunab keep : `keep' + macroUnique `keep', names(keep) +} +if "`drop'"~="" { + * one by one to accomodate MISSING from _tab3 + foreach var in `drop' { + cap tsunab temp : `var' + local tempDrop "`tempDrop' `temp'" + } + local drop "`tempDrop'" + macroUnique `drop', names(drop) +} +if "`sortvar'"~="" { +/* gettoken first second: sortvar, parse(" ") + local sortvar + while `"`first'"'~="" { + cap tsunab temp : `sortvar' + if !_rc { + local sortvar `"`sortvar' `temp'"' + } + gettoken first second: second, parse(" ") + } +*/ + tokenize `sortvar' + local num 1 + local collect "" + while "``num''"~="" { + cap tsunab temp : ``num'' + if !_rc { + local collect "`collect' `temp'" + } + else { + local collect "`collect' ``num''" + } + local num=`num'+1 + } + local sortvar "`collect'" + macroUnique `sortvar', names(sortvar) +} +if "`sortvar'"~="" & "`groupvar'"~="" { + noi di in red "cannot choose both {opt sortvar} and {opt groupvar}" + exit 198 +} +if "`groupvar'"~="" { + tokenize `groupvar' + local num 1 + local collect "" + while "``num''"~="" { + cap tsunab temp : ``num'' + if !_rc { + local collect "`collect' `temp'" + } + else { + local collect "`collect' ``num''" + } + local num=`num'+1 + } + local groupvar "`collect'" + macroUnique `groupvar', names(groupvar) +} + +* unambiguate the names of stored estimates (wildcards) +if "`estimates'"~="" { + local collect "" + foreach var in `estimates' { + local temp "_est_`var'" + local collect "`collect' `temp'" + } + unab estimates : `collect' + local collect "" + foreach var in `estimates' { + local temp=substr("`var'",6,length("`var'")-4) + local collect "`collect'`temp' " + } + local estimates=trim("`collect'") +} + +* or use est_expand + + +tempname estnameUnique +* a place holding name to the current estimates that has no name entered into the outreg + +if "`estimates'"=="" { + local estStored 0 + local estimates="`estnameUnique'" +} +else { + if "`Version7'"=="" { + * it is version 7 + noi di in red "version 7 cannot specify stored estimates: " in white "`estimates'" + exit 198 + } + local estStored 1 + *cap local estimates: list uniq local(estimates) + macroUnique `estimates', names(estimates) +} + +*** checking sum and crosstab +local check1 `=("`crosstab'"~="" | "`tab3'"~="")' +local check2 `=("`sum'"~="" | "`sum2'"~="")' +local check3 `=("`mfx'"~="")' +local checks=`check1'+`check2'+`check3' + +if `checks'>=2 { + di in yel "cannot specify more than one of {opt sum}, {opt crosstab}, or {opt mfx} options" + exit 198 +} + + +if "`sum'"=="sum" & "`sum2'"=="" { + local sum2 "regress" +} + +*** get crosstab +if "`crosstab'"=="crosstab" { + qui _tab3 `varlist' `if' `in' [`weight'`exp'] + + local ebnames "e(freq)" + local eVnames "e(percent)" + local r2 "nor2" + local sortcol "name" + local obs "noobs" + if `"`addstat'"'=="" { + local addstat `"addstat("Total", e(total))"' + } + else { + gettoken part rest: addstat, parse(" (") + gettoken part rest: rest, parse(" (") /* strip off "addstat(" */ + local addstat `"addstat("Total", e(total), `rest'"' + } + + * augment (usually has bys( ) variables in them) + if `e(total)'==0 { + local drop `"MISSING `drop'"' + } + + if `"`ctitle0'"'=="" { + if `"`cttop'"'~="" { + * this is ugly; put in VARIABLES cell below + *local ctitle `"`cttop', `varlist'"' + } + else { + local ctitle `"`varlist'"' + } + } + + local VARIABLES `"`varlist'"' + local notes "nonotes" + + local varlist "" +} +else if "`sum2'"~="" { + + local r2 "nor2" + + * allowable: log regress noindep detail + optionSyntax, valid(log regress noindep detail) name(sum2) nameShow(sum( )) content(`sum2') + + if "`noindep'"=="noindep" & "`detail'"=="" { + local regress "regress" + } + + if "`log'"=="log" & "`detail'"=="detail" { + di in red "cannot use both {opt log} and {opt detail} for {opt sum( )} option" + exit 198 + } + if "`log'"=="log" { + + * always raw because e(sample) might be empty for version 11 + noi _sum2 `if' `in' [`weight'`exp'], `log' raw + + local r2 "nor2" + local notes "nonotes" + local aster "noaster" + local stats "coef" + local obs "noobs" + if `"`ctitle0'"'=="" { + local ctitle `"`cttop', \`depvar'"' + } + di + } + if "`detail'"=="detail" { + * always raw because e(sample) might be empty for version 11 + noi _sum2 `if' `in' [`weight'`exp'], `detail' raw + + local r2 "nor2" + local notes "nonotes" + local aster "noaster" + local stats "coef" + local obs "noobs" + if `"`ctitle0'"'=="" { + local ctitle `"`cttop', \`depvar'"' + } + di + } + if "`regress'"=="regress" { +******************** take off the number in the front for reg3 dependent variables 2price 3price etc +******************** unab, tsuab + + if "`e(depvar)'"~="" | "`e(depvar)'"~="." { + local sumVar1 `e(depvar)' + } + + * borrowed from below (for multiple equations) + * workaround for 8.0: e(b) must be converted to a regular matrix to get at it + tempname tempMatrix + mat `tempMatrix'=e(b) + local sumVar2: colnames `tempMatrix' + + * workaround for 8.0: e(b) must be converted to a regular matrix to get at it + local eqlist: coleq `tempMatrix' + + if "`Version7'"~="" { + local eqlist: list clean local(eqlist) + local eqlist: list uniq local(eqlist) + } + else { + * probably needed for the first character + local temp=index("`eqlist'","_") + if `temp'==1 { + local eqlist=subinstr("`eqlist'", "_", "", .) + } + * also make unique + macroUnique `eqlist', names(eqlist7) number(eqnum7) + local eqlist `eqlist7' + } + + * counting the number of equation + local eqnum: word count `eqlist' + * local eqnum : list sizeof eqlist + + * redundant subtractions + *local minus "_cons" + *local sumVar2: list sumVar2 - minus + * do it by hand: + tokenize `sumVar2' + local num 1 + local sumVar2 "" + while "``num''"~="" { + if "``num''"~="_cons" { + local sumVar2 "`sumVar2' ``num''" + } + local num=`num'+1 + } + + if "`noindep'"=="noindep" { + noi _sum2 `sumVar2' `if' `in' [`weight'`exp'], `raw' + } + else { + noi _sum2 `sumVar1' `sumVar2' `if' `in' [`weight'`exp'], `raw' + } + + if 1<`eqnum' & `eqnum'<. { + noi di in yel "Check your results; -sum- option not meant for multiple equation model" + } + } + + local ebnames "e(mean)" + local eVnames "e(Var)" + + if `"`ctitle'"'=="" { + if `"`cttop'"'=="" { + local cttop `"mean, (sd)"' + if `"`if'"'~="" { + gettoken first second: if, parse(" ") + local cttop `"`cttop', `second'"' + } + if `"`in'"'~="" { + local cttop `"`cttop', `in'"' + } + } + else { + local cttop `"`cttop', mean, (sd)"' + if `"`if'"'~="" { + gettoken first second: in, parse(" ") + local cttop `"`cttop', `second'"' + } + if `"`in'"'~="" { + local cttop `"`cttop', `in'"' + } + } + } + + loca sum_N + local r2 "nor2" + local notes "nonotes" + local aster "noaster" + local sortcol "later" +} +else { + +if "`matrix'"~="" { +*** matrix names + local ebnames "`matrix'" + local eVnames "e(V)" + + if "`stats'"=="" { + local stats "coef" + } + if "`r2'"=="" { + local r2 "nor2" + } + if "`aster'"=="" { + local aster "noaster" + } + if "`notes'"=="" { + local notes "nonotes" + } + if "`ctitle'"=="" { + local ctitle "`matrix'" + } + if "`obs'"=="" { + local obs "noobs" + } +} +else { + *** ereturn matrix names + if "`mfx'"~="mfx" { + cap confirm matrix e(b) + if _rc & "`Version7'"~="" & "`sum2'"=="" { + if "`varlist'"~="" { + * sets e(sample) + di in red "matrix e(b) not found; run or post a regression first" + exit 111 + *eretSet `varlist' + } + else { + * it does not exist + di in red "matrix e(b) not found; run or post a regression first" + exit 111 + } + } + } + *************************** get user specified matrices + local ebnames "e(b)" + local eVnames "e(V)" + + if "`mfx'"=="mfx" { + if "`Version7'"~="" { + cap confirm matrix e(Xmfx_dydx) + if _rc { + * it does not exist + di in red "matrix e(Xmfx_dydx) not found; need to run {cmd:mfx} first" + exit 111 + } + } + local ebnames "e(Xmfx_dydx)" + local eVnames "e(Xmfx_se_dydx)" + local eXnames "e(Xmfx_X)" + } +} +} + +* noSE: because se indicates stn.err, convert noSE into something else +if "`se'"=="nose" { + local se_skip "se_skip" +} + +* stats( ) is not compatible with two-column options +if "`stats'"~="" { + if "`se'"=="nose" { + di in red "cannot specify both {opt st:ats( )} and {opt nose} options" + exit 198 + } + if "`ci'"=="ci" { + di in red "cannot specify both {opt st:ats( )} and {opt ci} options" + exit 198 + } + if "`tstat'"=="tstat" { + di in red "cannot specify both {opt st:ats( )} and {opt tstat} options" + exit 198 + } + if "`pvalue'"=="pvalue" { + di in red "cannot specify both {opt st:ats( )} and {opt p:value} options" + exit 198 + } + if "`beta'"=="beta" { + di in red "cannot specify both {opt st:ats( )} and {opt be:ta} options" + exit 198 + } +} + +* always se instead of tstat +if "`tstat'"~="tstat" & "`pvalue'"~="pvalue" & "`ci'"~="ci" & "`beta'"~="beta" { + if "`stats'"=="" { + local se "se" + } +} +else { + local se "" +} + +if "`parenthesis'"=="" & "`paren'"~="noparen" { + if "`ci'"~="" { + local parenthesis "ci" + } + if "`pvalue'"~="" { + local parenthesis "pval" + } + if "`tstat'"~="" { + local parenthesis "tstat" + } + if "`beta'"~="" { + local parenthesis "beta" + } + if "`se'"=="se" { + local parenthesis "se" + } +} + + +*** clean up file name, enclose .txt if no file type is specified +*** else take care of user-specified extension names for excel tex word files +local rest "`using'" +* strip off "using" +gettoken part rest: rest, parse(" ") +* strip off quotes +gettoken first second: rest, parse(" ") +cap local rest: list clean local(rest) + +local rabbit `"""' +if index(`"`using'"', ".")==0 { + local file = `"`rabbit'`first'.txt`rabbit'"' + local using = `"using `file'"' +} +else { + local file = `"`rabbit'`first'`rabbit'"' + local using = `"using `file'"' + + * strip off quotes and extension + gettoken first second: file, parse(" ") + local temp = `"`first'"' + + local next_dot = index(`"`temp'"',".") + local next_strip = substr(`"`temp'"',1,`=`next_dot'-1') + local strippedname = substr(`"`temp'"',1,`=`next_dot'-1') + + * check for more dots + local change 0 + while `change'==0 { + local temp = substr(`"`temp'"',`=`next_dot'+1',.) + if index(`"`temp'"', ".")~=0 { + local next_dot = index(`"`temp'"',".") + local next_strip = substr(`"`temp'"',1,`=`next_dot'-1') + local strippedname = `"`strippedname'.`next_strip'"' + } + else { + * no change + local last_strip = `"`temp'"' + local change 1 + } + } + + *** check for manual rtf doc xlm xls csv extensions + if `"`last_strip'"'=="rtf" | `"`last_strip'"'=="doc" { + local word "word" + + local file = `"`rabbit'`strippedname'.txt`rabbit'"' + local using = `"using `file'"' + local wordFile "`last_strip'" + } + if `"`last_strip'"'=="xls" | `"`last_strip'"'=="xml" | `"`last_strip'"'=="xlm" | `"`last_strip'"'=="csv" { + local excel "excel" + + local file = `"`rabbit'`strippedname'.txt`rabbit'"' + local using = `"using `file'"' + local excelFile "`last_strip'" + } + if `"`last_strip'"'=="tex" { + if `"`tex1'"'=="" { + local tex "tex" + } + + local file = `"`rabbit'`strippedname'.txt`rabbit'"' + local using = `"using `file'"' + local texFile "`last_strip'" + } +} + +*noi di in red "`next_strip'" +*noi di in red "`last_strip'" +*noi di in red "`strippedname'" + + +*** confirm the output file existance, to be adjusted later +cap confirm file `file' +if !_rc { + * it exists + local fileExist 1 +} +else { + local fileExist 0 +} + +*** mainfile +* cleaning the user provided inputs + +if "`long'"=="long" & "`onecol'"=="onecol" { + di in yellow "{opt long} implies {opt o:necol} (no need to specify both)" +} +if "`long'"=="long" & "`onecol'"~="onecol" { + local onecol "onecol" +} + +if ("`tstat'"!="")+("`pvalue'"!="")+("`ci'"!="")+("`beta'"!="")>1 { + di in red "choose only one of tstat, pvalue, ci, or beta" + exit 198 +} + +if `level'<10 | `level'>99 { + di in red "level() invalid" + exit 198 +} + +if `"`paren'"'=="noparen" & `"`parenthesis'"'~="" { + di in red "cannot choose both {opt nopa:ren} and {opt paren:thesis()} option" + exit 198 +} +if `"`paren'"'=="noparen" & `"`bracketA'"'~="" { + di in red "cannot choose both {opt nopa:ren} and {opt br:acket()} option" + exit 198 +} +if `"`bracket'"'~="" & `"`bracketA'"'~="" { + di in red "cannot choose both {opt br:acket} and {opt br:acket()} option" + exit 198 +} + +if "`symbol'"=="" & "`sigsymb'"~= "" { + local symbol "`sigsymb'" +} +if `"`10pct'"'~="" & "`sigsymb'"~="" { + di in red "cannot choose both {opt 10pct} and {opt sigsymb( )}" + exit 198 +} + +if `"`10pct'"'~="" & "`symbol'"~="" { + di in red "cannot choose both {opt 10pct} and {opt symbol( )}" + exit 198 +} +if `"`10pct'"'~="" & "`symbol'"=="" { + local symbol `"symbol(**, *, +)"' +} +if "`aster'"=="noaster" & ("`asterisk'"~="" | "`symbol'"!="") { + if "`asterisk'"~="" { + di in red "cannot choose both {opt noaster} and {opt asterisk( )}" + } + else { + di in red "cannot choose both {opt noaster} and {opt symbol( )}" + } + exit 198 +} + +if (`"`addnote'"'!="" & "`append'"=="append" & `fileExist'==1) { + di in yellow "warning: addnote ignored in appended columns" +} + +*** LaTeX options +local tex = ("`tex'"!="") +if "`tex1'"!="" { + if `tex' { + di in red "may not specify both {opt tex} and {opt tex()} options" + exit 198 + } + local tex 1 + + gettoken part rest: tex1, parse(" (") + gettoken texopts zilch: rest, parse(" (") match(parns) /* strip off "tex1()" */ +} + +_texout_parse, `texopts' + +* insert nopretty +local check=index(`"`tex1'"',"nopretty") +if `check'==0 { + local check=index(`"`tex1'"',"pretty") + if `check'==0 { + * neither + local texopts "nopretty `texopts'" + } +} + + +*** label options +if "`label'"=="label" & "`labelA'"~="" { + di in red "cannot specify both {opt lab:el} and {opt lab:el()} options" + exit 198 +} +if "`labelA'"~="" { + gettoken part rest: labelA, parse(" (") + gettoken labelOption zilch: rest, parse(" (") match(parns) /* strip off "label()" */ + local labelOption=trim("`labelOption'") + if "`labelOption'"~="insert" { + di in red "cannot specify any option other than {opt insert} for {opt lab:el( )}" + exit 198 + } + else if "`labelOption'"~="insert" { + local label "label" + } +} + +*** equationsA options +if "`equationsA'"~="" { + gettoken part rest: equationsA, parse(" (") + gettoken equationsOption zilch: rest, parse(" (") match(parns) /* strip off "label()" */ + local equationsOption=trim("`equationsOption'") + + if "`equationsOption'"~="auto" { + di in red "cannot specify any option other than {opt auto} for {opt eq:uation( )}" + exit 198 + } + else if "`equationsOption'"~="auto" { + *local label "label" + } +} + + +if (`"`addstat'"'=="" & "`adec'"!="" & "`e'"=="" ) { + di in red "cannot choose adec option without addstat option" + exit 198 +} +if "`adec'"=="" { + * disabled + * local adec = `dec' +} + +if "`quote'"!="quote" { + local quote "noquote" +} + +tempname df_r + +if "`margin1'"~="" | "`margin2'"~="" { + if "`mfx'"=="mfx" { + di in red "cannot specify both {opt mfx} and {opt margin} options" + exit 198 + } + + local margin = "margin" + if "`margin2'"~="" { + local margucp "margucp(_`margin2')" + scalar `df_r' = . + if "`margin1'"~="" { + di in red "may not specify both margin and margin()" + exit 198 + } + } + else { + if "`cmd'"=="tobit" { + di in red "dtobit requires margin({u|c|p}) after dtobit command" + exit 198 + } + } +} + + +*** titlefile needs set out here +tempfile titlefile + + *** logistic reports coeffients in exponentiated form (odds ratios) + if "`cmd'"=="logistic" { + local eform "eform" + + * report no cons + if "`eform'"=="eform" { + local cons "nocons" + } + } + + *** stats( ) option cleanup : dealing with rows/stats to be reported per variable/coeff + local statsValid "coef se tstat pval ci aster blank beta ci_low ci_high N sum_w mean Var sd skewness kurtosis sum min max p1 p5 p10 p25 p50 p75 p90 p95 p99 corr pwcorr spearman " + + * level coef_eform se_eform coef_beta se_beta" + + local asterAsked 0 + local betaAsked "" + + /* + if `"`estats'"'~="" { + * the names of the available stats in e(matrices) + local ematrices "" + local var: e(matrices) + + *noi di in yellow "`var'" + + tokenize `var' + local i=1 + while "``i''"~="" { + *** di "e(``i'')" _col(25) "`e(``i'')'" + local ematrices="`ematrices'``i'' " + local i=`i'+1 + } + } + */ + + if `"`stats'"'~="" { + * take out commas + gettoken one two: stats, `bind' parse(", ") + gettoken comma rest: two, `bind' parse(", ") + if "`comma'"=="," { + local two `"`rest'"' + } + local tempList `"`one'"' + while `"`two'"'~="" { + gettoken one two: two, `bind' parse(", ") + gettoken comma rest: two, `bind' parse(", ") + if "`comma'"=="," { + local two `"`rest'"' + } + local tempList `"`tempList' `one'"' + } + local stats `"`tempList'"' + local tempList + + local matlist + + + * need to count using -gettoken, bind- instead of merely -local statsMany : word count `stats'- + + local num=1 + local statsMany 1 + + gettoken one two: stats, `bind' + local stats`num' `"`one'"' + local two=trim(`"`two'"') + + local stats`num' `"`one'"' + + * okay to add: + local statsList "`statsList' `stats`num''" + local two=trim(`"`two'"') + + while `"`two'"'~="" { + local num=`num'+1 + local statsMany=`statsMany'+1 + + gettoken one two: two, `bind' parse(", ") + gettoken comma rest: two, `bind' parse(", ") + if "`comma'"=="," { + local two `"`rest'"' + } + + local stats`num' `"`one'"' + + * it must be one of the list + local test 0 + foreach var in `statsValid' { + if "`var'"=="`stats`num''" & `test'==0 { + local test 1 + } + + * checking if aster/beta specified + if "`stats`num''"=="aster" { + local asterAsked 1 + } + if "`stats`num''"=="beta" { + local betaAsked "betaAsked" + } + } + if `test'==0 { + * not on the list of valid ones + capture confirm matrix `stats`num'' + if !_rc { + * matrix exists + local matlist `"`matlist' `stats`num''"' + } + else { + * send it to parser + cap _stats_parse, `stats`num'' + if _rc~=0 { + noi di in white "`stats`num''" in red " is not a valid sub-option, matrix, str( ), or cmd( ) for {opt stats( )}" + exit 198 + } + } + } + + * okay to add: + local statsList "`statsList' `stats`num''" + + local two=trim(`"`two'"') + } + } + else if "`se_skip'"=="se_skip" { + local statsMany 1 + local statsList "coef" + } + else { + local statsMany 2 + + if "`ci'"=="ci" { + if "`eform'"=="eform" { + local statsList "coefEform ciEform" + } + else { + local statsList "coef ci" + } + } + else if "`beta'"=="beta" { + local statsList "coef beta" + } + + * regular: tstat, pval, or se + else if "`eform'"=="eform" { + local statsList "coefEform seEform" + + if "`tstat'"=="tstat" { + local statsList "coefEform tstat" + } + else if "`pvalue'"=="pvalue" { + local statsList "coefEform pval" + } + } + else { + local statsList "coef se" + + if "`tstat'"=="tstat" { + local statsList "coef tstat" + } + else if "`pvalue'"=="pvalue" { + local statsList "coef pval" + } + } + } + + * when stats(aster) specified, aster( ) should not be attached to coef unless asked + if `asterAsked'==1 & "`asterisk'"=="" { + * the encased blank will trigger the parsing codes in makeFile + local asterisk " " + } + + + * update when eform specified + if "`eform'"=="eform" { + * blank at end + local statsList "`statsList' " + local statsList : subinstr local statsList "coef " "coefEform ", all + local statsList : subinstr local statsList "ci " "ciEform ", all + local statsList : subinstr local statsList "se " "seEform ", all + + local statsList : subinstr local statsList "ci_high " "ci_highEform ", all + local statsList : subinstr local statsList "ci_low " "ci_lowEform ", all + } + + * parenthesis locations moved to makeFile + + * check that nothing appears in parenthesis( ) does not appear in stats( ) + macroMinus `parenthesis', names(temp) subtract(`statsList' `stats') + if "`temp'"~="" & "`stats'"~="" { + noi di in red "`temp' appears in parenthesis( ) but not in stats( )" + exit 198 + } + + + + * clean up matlist + if `"`matlist'"'~="" { + tokenize `matlist' + local rnum 1 + local num 1 + while `"``num''"'~="" { + * take off the parenthesis crap + local temp + local temp = substr(`"``num''"',1,2) + if "`temp'"=="r(" { + * r( ) matrix + local content = substr(`"``num''"',3,length("``num''")-3) + * not currently accepting + di in red "r-class matrix " in white "``num''" in red " not accepted by {opt stats( )}" + exit 198 + local rnum=`rnum'+1 + } + if "`temp'"=="e(" { + * r( ) matrix + local content = substr(`"``num''"',3,length("``num''")-3) + * not currently accepting + di in red "e-class matrix " in white "``num''" in red " not accepted by {opt stats( )}" + exit 198 + local rnum=`rnum'+1 + } + local num=`num'+1 + } + } + + + *** expand statsList and statsMany according to vector/nonvec matrices + + * these two are collected, but not used here + local vectorList + local nonvecList + + if "`matlist'"~="" { + tempname matdown + foreach matname in `matlist' { + mat `matdown'=`matname' /* NOT transposed */ + local temp= colsof(`matdown') + + if `temp'==1 { + * it's a vector + local vectorList "`vectorList' `matname'" + } + else { + * it's a non-vector matrix + local cc= colsof(`matdown') + local temp0 : colnames(`matdown') + local temp + foreach var in `temp0' { + local temp "`temp' `matname'_`var'" + } + local nonvecList "`nonvecList' `temp'" + + * add the empty space at end + local statsList =`"`statsList' "' + local statsList =subinstr("`statsList'"," `matname' "," `temp' ",.) + local statsMany `=`statsMany'+`cc'-1' + } + } + } + + + *** run each estimates consecutively + local estmax: word count `estimates' + forval estnum=1/`estmax' { + local estname: word `estnum' of `estimates' + if "`estimates'"~="`estnameUnique'" { + qui estimates restore `estname' + } + * to avoid overwriting after the first time, append from the second time around (1 of 3) + if `estnum'==2 & "`replace'"=="replace" { + local append "append" + local replace "" + } + + * the names of the available stats in e( ) + local result "scalars" + * took out macros from the local result + local elist="" + foreach var in `result' { + local var: e(`var') + tokenize `var' + local i=1 + while "``i''"~="" { + *** di "e(``i'')" _col(25) "`e(``i'')'" + local elist="`elist'``i'' " + local i=`i'+1 + } + } + *cap local elist: list uniq local(elist) + macroUnique `elist', names(elist) + + * take out N (because it is always reported) + local subtract "N" + *cap local elist : list elist - subtract + macroMinus `elist', names(elist) subtract(`subtract') + + * r2 option + * save the original for the first run and restore prior to each subsequent run + if `estnum'==1 { + local r2Save `"`r2'"' + } + else { + local r2 `"`r2Save'"' + } + + *** e(all) option + * save the original for the first run and restore prior to each subsequent run + if `estnum'==1 { + local addstatSave `"`addstat'"' + } + else { + local addstat `"`addstatSave'"' + } + + *** dealing with e( ) option: put it through addstat( ) + * local = expression restricts the length + * requires a work-around to avoid subinstr/substr functions + + * looking for "all" anywhere + if "`Version7'"=="" { + local position=index("`e'","all") + } + else { + local position: list posof "all" in e + } + + if `"`addstat'"'~="" { + if "`e'"~="" { + local e: subinstr local e "," " ",all + *cap local e: list uniq local(e) + macroUnique `e', names(e) + + if `position'~=0 { + local count: word count `elist' + local addstat=substr("`addstat'",1,length("`addstat'")-1) + forval num=1/`count' { + local wordtemp: word `num' of `elist' + local addstat "`addstat',`wordtemp',e(`wordtemp')" + } + } + else { /* other than all */ + local count: word count `e' + local addstat=substr("`addstat'",1,length("`addstat'")-1) + forval num=1/`count' { + local wordtemp: word `num' of `e' + local addstat "`addstat',`wordtemp',e(`wordtemp')" + } + } + local addstat "`addstat')" + } + } + + * if addstat was previously empty + else if "`addstat'"=="" { + if "`e'"~="" { + local e: subinstr local e "," " ",all + *cap local e: list uniq local(e) + macroUnique `e', names(e) + if `position'~=0 { + local count: word count `elist' + local addstat "addstat(" + forval num=1/`count' { + local wordtemp: word `num' of `elist' + local addstat "`addstat'`wordtemp',e(`wordtemp')" + if `num'<`count' { + local addstat "`addstat'," + } + } + } + else { + local count: word count `e' + local addstat "addstat(" + forval num=1/`count' { + local wordtemp: word `num' of `e' + local addstat "`addstat'`wordtemp',e(`wordtemp')" + if `num'<`count' { + local addstat "`addstat'," + } + } + } + local addstat "`addstat')" + } + } + + *** dealing with single/multiple equations + *** also dealing with non-vector matrices, i.e. multiple columns + + + + + * getting equation names + tempname mainMatrix + mat `mainMatrix'=`ebnames' + + * workaround for 8.0: e(b) must be converted to a regular matrix to get at it + local eqlist: coleq `mainMatrix' + + if "`Version7'"~="" { + local eqlist: list clean local(eqlist) + local eqlist: list uniq local(eqlist) + } + else { + * probably needed for the first character + local temp=index("`eqlist'","_") + if `temp'==1 { + local eqlist=subinstr("`eqlist'", "_", "", .) + } + * also make unique + macroUnique `eqlist', names(eqlist7) number(eqnum7) + local eqlist `eqlist7' + } + + * counting before eqkeep/eqdrop + local eqnum_original: word count `eqlist' + + * drop some of multiple equations: 1 of 2 + + if "`eqdrop'"~="" { + * may not be a variable + cap tsunab eqdrop : `eqdrop' + *cap local eqlist : list eqlist - eqdrop + macroMinus `eqlist', names(eqlist) subtract(`eqdrop') + macroUnique `eqlist', names(eqlist) + } + + if "`eqkeep'"~="" { + * may not be a variable + cap tsunab eqkeep : `eqkeep' + local eqlist `"`eqkeep'"' + macroUnique `eqlist', names(eqlist) + } + + * counting the number of equation + local eqnum: word count `eqlist' + * local eqnum : list sizeof eqlist + + if "`Version7'"=="" { + local eqnum `eqnum7' + } + + * 0 if it is multiple equations; 1 if it is a single + *if 1<`eqnum' & `eqnum'<. { + if 1<`eqnum_original' & `eqnum_original'<. { + local univar=0 + } + else { + local univar=1 + } + + tempname regN rsq numi r2mat b vc b_alone convert + *coefcol varname + + **** snipped portion moved here from above + * for svy commands with subpop(), N_sub is # of obs used for estimation + local cmd = e(cmd) + + local svy = substr("`cmd'",1,3) + if "`svy'"=="svy" & e(N_sub) != . { + scalar `regN' = e(N_sub) + } + else { + if "`sum2'"=="" { + scalar `regN' = e(N) + } + else { + scalar `regN' = e(sum_N) + } + } + + scalar `df_r' = e(df_r) + local depvar = e(depvar) + + mat `b'=`ebnames' + mat `vc'=`eVnames' + + if "`mfx'"=="mfx" { + mat `vc' = `vc'' * `vc' + } + + local bcols=colsof(`b') /* cols of b */ + local bocols=`bcols' /* cols of b only, w/o other stats */ + + * the work around for xtmixed + if "`e(N_g)'"=="matrix" { + mat `convert'=e(N_g) + scalar `numi'=`convert'[1,1] + } + else { + scalar `numi' = e(N_g) + } + + local robust = e(vcetype) + if "`robust'"=="." { + local robust "none" + } + local ivar = e(ivar) + * equals one if true + capture local fracpol = (e(fp_cmd)=="fracpoly") + + + *** parse addstat to convert possible r(), e(), and s() macros to numbers + * (to avoid conflicts with r-class commands used in this program) + if `"`addstat'"'!="" { + *** PRE-PARSE with autodigit disabled because r( ) needs to be evaluated before r-class autodigit + local newadd="" + + gettoken part rest: addstat, parse(" (") + gettoken part rest: rest, parse(" (") /* strip off "addstat(" */ + local i = 1 + while `"`rest'"' != "" { + gettoken name rest : rest, parse(",") quote + if `"`name'"'=="" { + di in red "empty strings not allowed in addstat() option" + exit 6 + } + gettoken acomma rest : rest, parse(",") + gettoken valstr rest : rest, parse(",") + if `"`rest'"' == "" { /* strip off trailing parenthesis */ + local valstr = substr(`"`valstr'"',1,length(`"`valstr'"')-1) + local comma2 "" + } + else { + gettoken comma2 rest: rest, parse(",") + } + + * creating e(p) if missing + if ("`valstr'"=="e(p)" | trim("`valstr'")=="e(p)") & "`e(p)'"=="" { + if "`e(df_m)'"~="" & "`e(df_r)'"~="" & "`e(F)'"~="" { + local valstr = Ftail(`e(df_m)',`e(df_r)',`e(F)') + } + else if "`e(df_m)'"~="" & "`e(chi2)'"~="" { + local valstr = chi2tail(`e(df_m)',`e(chi2)') + } + * update if xtreg, fe is messing with it + if "`e(df_m)'"~="" & "`e(df_b)'"~="" & "`e(F)'"~="" { + local valstr = Ftail(`e(df_b)',`e(df_r)',`e(F)') + } + else if "`e(df_b)'"~="" & "`e(chi2)'"~="" { + local valstr = chi2tail(`e(df_b)',`e(chi2)') + } + } + + *local value = `valstr' + *capture confirm number `value' + *if _rc!=0 { + * * di in red `"`valstr' found where number expected in addstat() option"' + * * exit 7 + *} + + local value=`valstr' + capture confirm number `value' + + if _rc==0 { + * it's a number + + local value = `valstr' + + local count: word count `adec' + local aadec : word `i' of `adec' + + * coding check: di "adec `adec' i `i' count `count' name `name' value `value'" + * runs only if the user defined adec is absent for that number + if `i'>`count' & `i'<. { + + * auto-digits: auto( ) + *autodigits2 `value' `auto' + * needs to be less than 11 + *local valstr = string(`value',"%12.`r(valstr)'") + local valstr = string(`value') + if "`valstr'"=="" { + local valstr . + } + local newadd `"`newadd'`name'`acomma'`valstr'`comma2'"' + } + else { + * using previous ones if no other option + if "`aadec'"=="" { + local aadec `prvadec' + } + local valstr = string(`value',"%12.`aadec'f") + local newadd `"`newadd'`name'`acomma'`valstr'`comma2'"' + local prvadec = `aadec' + } + } + else { + * it's a non-number + local index=index(`"`valstr'"',"e(") + if `index'~=0 { + if `"``valstr''"'=="" { + * put a dot in there + local value `"`valstr'"' + local newadd `"`newadd'`name'`acomma'.`comma2'"' + noi di in yel `"check {stata eret list} for the existence of `valstr'"' + } + else { + * passthru `valstr' + local value `"`valstr'"' + local newadd `"`newadd'`name'`acomma'`valstr'`comma2'"' + } + } + else { + * evaluate ``valstr'' + local value `"`valstr'"' + local newadd `"`newadd'`name'`acomma'``valstr''`comma2'"' + } + } + + local i = `i'+1 + } + local addstat `"`newadd'"' + + *** do it again with autodigit enabled + local addstat `"addstat(`addstat')"' + + local newadd="" + gettoken part rest: addstat, parse(" (") + gettoken part rest: rest, parse(" (") /* strip off "addstat(" */ + local i = 1 + while `"`rest'"' != "" { + gettoken name rest : rest, parse(",") quote + if `"`name'"'=="" { + di in red "empty strings not allowed in addstat() option" + exit 6 + } + gettoken acomma rest : rest, parse(",") + gettoken valstr rest : rest, parse(",") + if `"`rest'"' == "" { /* strip off trailing parenthesis */ + local valstr = substr(`"`valstr'"',1,length(`"`valstr'"')-1) + local comma2 "" + } + else { + gettoken comma2 rest: rest, parse(",") + } + + * creating e(p) if missing + if ("`valstr'"=="e(p)" | trim("`valstr'")=="e(p)") & "`e(p)'"=="" { + if "`e(df_m)'"~="" & "`e(df_r)'"~="" & "`e(F)'"~="" { + local valstr = Ftail(`e(df_m)',`e(df_r)',`e(F)') + } + else if "`e(df_m)'"~="" & "`e(chi2)'"~="" { + local valstr = chi2tail(`e(df_m)',`e(chi2)') + } + * update if xtreg, fe is messing with it + if "`e(df_m)'"~="" & "`e(df_b)'"~="" & "`e(F)'"~="" { + local valstr = Ftail(`e(df_b)',`e(df_r)',`e(F)') + } + else if "`e(df_b)'"~="" & "`e(chi2)'"~="" { + local valstr = chi2tail(`e(df_b)',`e(chi2)') + } + } + + *local value = `valstr' + *capture confirm number `value' + *if _rc!=0 { + * * di in red `"`valstr' found where number expected in addstat() option"' + * * exit 7 + *} + + local value=`valstr' + capture confirm number `value' + + if _rc==0 { + * it's a number + + local value = `valstr' + + local count: word count `adec' + local aadec : word `i' of `adec' + + * coding check: di "adec `adec' i `i' count `count' name `name' value `value'" + * runs only if the user defined adec is absent for that number + if `i'>`count' & `i'<. { + + * auto-digits: auto( ) + autodigits2 `value' `auto' + * needs to be less than 11 + local valstr = string(`value',"%12.`r(valstr)'") + if "`valstr'"=="" { + local valstr . + } + local newadd `"`newadd'`name'`acomma'`valstr'`comma2'"' + } + else { + * using previous ones if no other option + if "`aadec'"=="" { + local aadec `prvadec' + } + local valstr = string(`value',"%12.`aadec'f") + local newadd `"`newadd'`name'`acomma'`valstr'`comma2'"' + local prvadec = `aadec' + } + } + else { + * it's a non-number + local index=index(`"`valstr'"',"e(") + if `index'~=0 { + if `"``valstr''"'=="" { + * put a dot in there + local value `"`valstr'"' + local newadd `"`newadd'`name'`acomma'.`comma2'"' + noi di in yel `"`valstr' does not exist; check {stata eret list}"' + } + else { + * passthru `valstr' + local value `"`valstr'"' + local newadd `"`newadd'`name'`acomma'``valstr''`comma2'"' + } + } + else { + * evaluate ``valstr'' + local value `"`valstr'"' + local newadd `"`newadd'`name'`acomma'`valstr'`comma2'"' + } + } + + local i = `i'+1 + } + local addstat `"`newadd'"' + } + + *** to deal with eq(auto) + if `univar'==0 & "`equationsOption'"=="auto" { + * this means run once, as if it was a single equation + local univar 1 + } + + /* + *** to deal with eq(auto) + if `univar'==0 & "`equationsOption'"=="auto" { + + forval count=1/`eqnum' { + + local temp_eqname: word `count' of `eqlist' + tempname temp_eq + mat `temp_eq' = `b'[.,"`temp_eqname':"] + + local these: coleq `temp_eq' + + + * remove roweq for explicit varlist + mat colnames `temp_eq' = _: + + local names: colnames `temp_eq' + *noi di "colnames `colnames'" + *local bocols = colsof(`b_eq') + } + } + */ + + if "`crosstab'"=="" & "`sum2'"=="" { + *** ad hoc fixes for various multi-equation models + if "`cmd'"=="mvreg" | "`cmd'"=="sureg" | "`cmd'"=="reg3" { + local univar = 0 /* multivariate regression (multiple equations) */ + if "`onecol'" != "onecol" { + mat `r2mat' = `ebnames' /* get column labels */ + local neq = e(k_eq) + local depvar = "`eqlist'" + if "`cmd'"=="mvreg" { + local r2list = e(r2) + } + local eq = 1 + while `eq' <= `neq' { + if "`cmd'"=="mvreg" { + local r2str: word `eq' of `r2list' + scalar `rsq' = real("`r2str'") + } + else { + scalar `rsq' = e(r2_`eq') + } + mat `r2mat'[1,`eq'] = `rsq' + local eq = `eq' + 1 + } + } + else { + /* if onecol */ + local r2 = "nor2" + scalar `rsq' = . + } + } /* `rsq' after `r2list' to avoid type mismatch */ + + else if "`adjr2'"=="adjr2" { + scalar `rsq' = e(r2_a) + if `rsq' == . { + di in red "Adjusted R-squared (e(r2_a)) not defined; cannot use adjr2 option" + exit 198 + } + } + else { + scalar `rsq' = e(r2) + } + + if ("`cmd'"=="intreg" | "`cmd'"=="svyintrg" | "`cmd'"=="xtintreg") { + local depvar : word 1 of `depvar' /* 2 depvars listed */ + } + + * nolabels for anova and fracpoly + if ("`cmd'"=="anova" | `fracpol' | "`cmd'"=="nl") { + /* e(fp_cmd)!=. means fracpoly */ + local cons "nocons" + } + + *** margin or dprobit: substitute marginal effects into b and vc + else if ("`cmd'"=="dprobit" | "`margin'"=="margin") { + if "`cmd'"=="dlogit2" | "`cmd'"=="dprobit2" | "`cmd'"=="dmlogit2" { + di in yellow "warning: margin option not needed" + } + else { + marginal2, b(`b') vc(`vc') `se' `margucp' + local bcols = colsof(`b') /* cols of b */ + local bocols = `bcols' /* cols of b only, w/o other stats */ + if "`cmd'"=="dprobit" { + local cons "nocons" + } + } + } + } /* not crosstab or sum */ + + + *** to handle single or multiple equations + local neq = `eqnum' + local eqlist "`eqlist'" + if "`onecol'"=="onecol" | `univar'==1 { + if "`depvar'"=="" { + local depvar: rowname `ebnames' + local depvar: word 1 of `depvar' + } + } + + + + *** the column title: + * save the original ctitle for the first run and restore prior to each subsequent run + if `estnum'==1 { + local ctitleSave `"`ctitle'"' + } + else { + local ctitle `"`ctitleSave'"' + } + + local ctitleList `"`ctitle'"' + + *** clean up column titles + * from current, non-stored estimates + if (`univar'==1 | "`onecol'"=="onecol") & `estStored'==0 { + if `"`ctitle0'"'=="" & `"`ctitleList'"'=="" { + if `"`cttop'"'~="" { + local ctitleList `"`cttop'"' + } + if `"`cttop'"'~="" & "`sum'"=="" & "`sum2'"=="" & "`crosstab'"=="" & "`tab3'"=="" { + local ctitleList `"`cttop', `depvar'"' + } + if `"`cttop'"'=="" & "`sum'"=="" & "`sum2'"=="" & "`crosstab'"=="" & "`tab3'"=="" { + * sometimes multiple depvar, i.e. reg3 + local count: word count `depvar' + if `count'>=1 & `count'<. { + local temp: word 1 of `depvar' + local ctitleList `"`ctitleList' `temp'"' + forval num=2/`count' { + local temp: word `num' of `depvar' + local ctitleList `"`ctitleList', `temp'"' + } + } + else { + local ctitleList `"`depvar'"' + } + } + } + } + else { + if `"`ctitle0'"'=="" & `estStored'==0 { + if "`eqname'"~="" { + * sometimes multiple depvar, i.e. reg3 + local count: word count `depvar' + if `count'>=1 & `count'<. { + local temp: word 1 of `depvar' + local ctitleList `"`eqname', `temp'"' + forval num=2/`count' { + local temp: word `num' of `depvar' + local ctitleList `"`ctitleList' ; `eqname', `temp'"' + } + } + } + else { + * sometimes multiple depvar, i.e. reg3 + local count: word count `depvar' + if `count'>=1 & `count'<. { + local temp: word 1 of `depvar' + local ctitleList `"`ctitleList' `temp'"' + forval num=2/`count' { + local temp: word `num' of `depvar' + local ctitleList `"`ctitleList' ; `temp'"' + } + } + } + } + else if `"`ctitle0'"'=="" { + * when from stored estimates + local ctitleList=`"`estname', `depvar'"' + if `"`eqname'"'~="" { + local ctitleList=`"`estname', `eqname', `depvar'"' + } + } + } + + if `"ctitleList'"'=="" { + local ctitleList `"`depvar'"' + } + + *** when `ebnames' includes extra statistics (which don't have variable labels) + capture mat `b_alone' = `b'[1,"`depvar':"] + + if _rc==0 { + local bocols = colsof(`b_alone') + } + else if ("`cmd'"=="ologit" | "`cmd'"=="oprobit") { + local bocols = e(df_m) + mat `b_alone' = `b'[1,1..`bocols'] + } + else if ("`cmd'"=="cnreg" | ("`cmd'"=="tobit" & "`margin'"~="margin")) { + local bocols = `bocols'-1 /* last element of `ebnames' is not est coef */ + mat `b_alone' = `b'[1,1..`bocols'] + } + else if ("`cmd'"=="intreg" | "`cmd'"=="svyintrg") { + mat `b_alone' = `b'[1,"model:"] + local bocols = colsof(`b_alone') + } + else if ("`cmd'"=="truncreg") { + mat `b_alone' = `b'[1,"eq1:"] + local bocols = colsof(`b_alone') + } + + * keep these here for sideway option + if "`statsListKeep'"=="" { + local statsListKeep "`statsList'" + local statsManyKeep "`statsMany'" + } + if "`ctitleListKeep'"=="" { + local ctitleListKeep "`ctitleList'" + } + + + if "`Version7'"=="" { + local eqlist "`eqlist7'" + } + + *** create table with makeFile and append to existing table + * NOTE: makeFile command is rclass + qui { + cap preserve + + *** make univariate regression table (single equation or single column) + if `univar'==1 | "`onecol'"=="onecol" { + + * changing the equation name of univariate case for housekeeping purposes + if `univar'==1 & "`onecol'"=="onecol" { + * attach equation marker for onecol output; it sorts better + mat colnames `b'= "`depvar':" + } + + *** sideway single equation + + if "`sideway'"=="sideway" { + local sidewayRun "`statsManyKeep'" + local statsMany 1 + } + else { + local sidewayRun 1 + } + + forval sidewayWave=1/`sidewayRun' { + if "`sideway'"=="sideway" { + * must do it by hand to handle cmd( ) - but "ad hoc" fix inside makeFile + *local var: word `sidewayWave' of `statsListKeep' + local statsTwo `"`statsListKeep'"' + forval temp=1/`sidewayWave' { + gettoken one statsTwo : statsTwo, `bind' + } + local var `"`one'"' + local statsList `"`var'"' + + * parsing ctitleList contents (1.1 of 2), parsing by ";" + local ctitleTwo `"`ctitleListKeep'"' + forval temp=1/`=`sidewayWave'*2-1' { + gettoken one ctitleTwo: ctitleTwo, `bind' parse(";") + } + local ctitleList `"`one'"' + + if "`crosstab'"=="crosstab" { + if `sidewayRun'==1 { + local ctitleList `"`cttop', Freq, (Percent)"' + } + else { + if `sidewayWave'==1 { + local ctitleList `"`cttop', Freq"' + } + else { + local ctitleList `"`cttop', Percent"' + } + } + } + else if `"`ctitleList'"'=="" & `"`cttop'"'~="" { + if `sidewayWave'==1 { + local ctitleList `"`cttop', `depvar', `var'"' + } + else { + local ctitleList `"`var'"' + } + } + else if `"`ctitleList'"'=="" { + if `sidewayWave'==1 { + local ctitleList "`depvar', `var'" + } + else { + local ctitleList `"`var'"' + } + } + if `"`ctitleList'"'=="" { + local ctitleList `"`ctitleListKeep'"' + } + } + + * to avoid overwriting after the first time, append from the second time around (2 of 3) + if `sidewayWave'==2 & "`replace'"=="replace" { + local append "append" + local replace "" + } + if "`Version7'"=="" { + * it is version 7 + * b(`b') instead of b(`b_eq'), vc(`vc') instead of vc(`vc_eq') + makeFile `varlist', equationsOption(`equationsOption') keep(`keep') drop(`drop') /* + */ eqkeep(`eqkeep') eqdrop(`eqdrop') eqlist(`eqlist') /* + */ `betaAsked' statsMany(`statsMany') statsList(`statsList') `se_skip' `beta' level(`level') /* + */ dec(`dec') fmt(`fmt') bdec(`bdec') bfmt(`bfmt') sdec(`sdec') sfmt(`sfmt') /* + */ tdec(`tdec') pdec(`pdec') /* + */ rdec(`rdec') adec(`adec') /* + */ `paren' parenthesis(`parenthesis') `bracket' /* + */ bracketA(`bracketA') `aster' `symbol' `cons' `eform' `obs' `ni' `r2' `adjr2' /* + */ ctitleList(`ctitleList') auto(`auto') `noauto' /* + */ addstat(`addstat') addtext(`addtext') `notes' /* + */ `addnote' `append' regN(`regN') df_r(`df_r') rsq(`rsq') numi(`numi') ivar(`ivar') depvar(`depvar') /* + */ robust(`robust') borows(`bocols') b(`b') vc(`vc') /* + */ univar(`univar') `onecol' estname(`estname') estnameUnique(`estnameUnique') /* + */ fileExist(`fileExist') less(`less') alpha(`alpha') asterisk(`asterisk') `2aster' /* + */ variables(`VARIABLES') matlist(`matlist') leave(`leave') sidewayWave(`sidewayWave') + * taken out: `se' `pvalue' `ci' `tstat' + } + else { + * b(`b') instead of b(`b_eq'), vc(`vc') instead of vc(`vc_eq') + makeFile `varlist', equationsOption(`equationsOption') keep(`keep') drop(`drop') /* + */ eqkeep(`eqkeep') eqdrop(`eqdrop') eqlist(`eqlist') /* + */ `betaAsked' statsMany(`statsMany') statsList(`statsList') `se_skip' `beta' level(`level') /* + */ dec(`dec') fmt(`fmt') bdec(`bdec') bfmt(`bfmt') sdec(`sdec') sfmt(`sfmt') /* + */ tdec(`tdec') tfmt(`tfmt') pdec(`pdec') pfmt(`pfmt') /* + */ rdec(`rdec') rfmt(`rfmt') adec(`adec') afmt(`afmt') /* + */ `paren' parenthesis(`parenthesis') `bracket' /* + */ bracketA(`bracketA') `aster' `symbol' `cons' `eform' `obs' `ni' `r2' `adjr2' /* + */ ctitleList(`ctitleList') auto(`auto') `noauto' /* + */ addstat(`addstat') addtext(`addtext') `notes' /* + */ `addnote' `append' regN(`regN') df_r(`df_r') rsq(`rsq') numi(`numi') ivar(`ivar') depvar(`depvar') /* + */ robust(`robust') borows(`bocols') b(`b') vc(`vc') /* + */ univar(`univar') `onecol' estname(`estname') estnameUnique(`estnameUnique') /* + */ fileExist(`fileExist') less(`less') alpha(`alpha') asterisk(`asterisk') `2aster' /* + */ variables(`VARIABLES') matlist(`matlist') leave(`leave') sidewayWave(`sidewayWave') + * taken out: `se' `pvalue' `ci' `tstat' + } + + *if "`append'"~="append" { + if "`append'"~="append" & `sidewayWave'==1 { + * replace + + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + outsheet nameCol reportCol `using', nonames `quote' `comma' replace + local fileExist 1 + } + + else { + *** appending + * confirm the existence of the output file + local rest "`using'" + * strip off "using" + gettoken part rest: rest, parse(" ") + if `fileExist'==1 { + appendFile `using', titlefile(`titlefile') /* + */`sideway' `onecol' sortcol(`sortcol') sortvar(`sortvar') groupvar(`groupvar') `quote' `comma' slow(`slow') + + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + outsheet v* reportCol `using', nonames `quote' `comma' replace + *drop v* + } + else { + * does not exist and therefore needs to be created + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + outsheet nameCol reportCol `using', nonames `quote' `comma' replace + local fileExist 1 + } + } + restore, preserve + } /* sideway single equation */ + } + + *** make multiple equation regression table + else { + + tempname b_eq vc_eq + + * getting the depvar list from eqlist + local eq = 1 + while `eq' <= `neq' { + + local eqname: word `eq' of `eqlist' + local depvar: word `eq' of `eqlist' + + if `eq'==1 { + if `estStored'==1 & "`estname'"~="" { + if `"`ctitle0'"'=="" & `eq'==1 { + *local ctitleList "`estname', `depvar'" + local ctitleList "`estname', `depvar'" + } + } + else { + if `"`cttop'"'~="" { + local ctitleList "`cttop', `depvar'" + } + else { + local ctitleList "`depvar'" + } + } + } + else { + * subsequent columns + if `estStored'==1 & "`estname'"~="" { + local ctitleList ", `depvar'" + } + else { + local ctitleList "`depvar'" + } + } + + *** r2mat doesn't exist for mlogit ="capture" + capture scalar `rsq' = `r2mat'[1,`eq'] + mat `b_eq' = `b'[.,"`eqname':"] + + * remove roweq from b_eq for explicit varlist + matrix colnames `b_eq' = _: + mat `vc_eq' = `vc'["`eqname':","`eqname':"] + local bocols = colsof(`b_eq') + + *** sideway multiple equation + + if "`sideway'"=="sideway" { + local sidewayRun "`statsManyKeep'" + local statsMany 1 + } + else { + local sidewayRun 1 + } + + forval sidewayWave=1/`sidewayRun' { + if "`sideway'"=="sideway" { + * must do it by hand to handle cmd( ) - but "ad hoc" fix inside makeFile + *local var: word `sidewayWave' of `statsListKeep' + local statsTwo `"`statsListKeep'"' + forval temp=1/`sidewayWave' { + gettoken one statsTwo : statsTwo, `bind' + } + local var `"`one'"' + local statsList "`var'" + + /* + * parsing ctitleList contents (1.2 of 2), parsing by ";" + local ctitleTwo `"`ctitleListKeep'"' + forval temp=1/`=`sidewayWave'*2-1' { + gettoken one ctitleTwo: ctitleTwo, `bind' parse(";") + } + local ctitleList1 `"`ctitleList', `one'"' + */ + + local ctitleList1 `"`ctitleList'"' + if `"`ctitleList1'"'=="" { + local ctitleList1 "`var'" + } + } + else { + local ctitleList1 `"`ctitleList'"' + } + + * to avoid overwriting after the first time, append from the second time around (3 of 3) + if `sidewayWave'==2 & "`replace'"=="replace" { + local append "append" + local replace "" + } + + if `eq'>1 & `sidewayWave'>1 { + local addstat "" + } + + if `eq' == 1 & "`append'"!="append" & `sidewayWave'==1 { + local apptmp "" + } + else { + local apptmp "append" + } + + if "`Version7'"=="" { + * it is version 7 + makeFile `varlist', equationsOption(`equationsOption') keep(`keep') drop(`drop') /* + */ eqkeep(`eqkeep') eqdrop(`eqdrop') eqlist(`eqlist') /* + */ `betaAsked' statsMany(`statsMany') statsList(`statsList') `se_skip' `beta' level(`level') /* + */ dec(`dec') fmt(`fmt') bdec(`bdec') bfmt(`bfmt') sdec(`sdec') sfmt(`sfmt') /* + */ tdec(`tdec') pdec(`pdec') /* + */ rdec(`rdec') adec(`adec') /* + */ `paren' parenthesis(`parenthesis') `bracket' /* + */ bracketA(`bracketA') `aster' `symbol' `cons' `eform' `obs' `ni' `r2' `adjr2' /* + */ ctitleList(`ctitleList1') auto(`auto') `noauto' /* + */ addstat(`addstat') addtext(`addtext') `notes' /* + */ `addnote' `apptmp' regN(`regN') df_r(`df_r') rsq(`rsq') numi(`numi') ivar(`ivar') depvar(`depvar') /* + */ robust(`robust') borows(`bocols') b(`b_eq') vc(`vc_eq') /* + */ univar(`univar') `onecol' estname(`estname') estnameUnique(`estnameUnique') /* + */ fileExist(`fileExist') less(`less') alpha(`alpha') asterisk(`asterisk') `2aster' /* + */ variables(`VARIABLES') matlist(`matlist') leave(`leave') sidewayWave(`sidewayWave') + * taken out: `se' `pvalue' `ci' `tstat' + } + else { + makeFile `varlist', equationsOption(`equationsOption') keep(`keep') drop(`drop') /* + */ eqkeep(`eqkeep') eqdrop(`eqdrop') eqlist(`eqlist') /* + */ `betaAsked' statsMany(`statsMany') statsList(`statsList') `se_skip' `beta' level(`level') /* + */ dec(`dec') fmt(`fmt') bdec(`bdec') bfmt(`bfmt') sdec(`sdec') sfmt(`sfmt') /* + */ tdec(`tdec') tfmt(`tfmt') pdec(`pdec') pfmt(`pfmt') /* + */ rdec(`rdec') rfmt(`rfmt') adec(`adec') afmt(`afmt') /* + */ `paren' parenthesis(`parenthesis') `bracket' /* + */ bracketA(`bracketA') `aster' `symbol' `cons' `eform' `obs' `ni' `r2' `adjr2' /* + */ ctitleList(`ctitleList1') auto(`auto') `noauto' /* + */ addstat(`addstat') addtext(`addtext') `notes' /* + */ `addnote' `apptmp' regN(`regN') df_r(`df_r') rsq(`rsq') numi(`numi') ivar(`ivar') depvar(`depvar') /* + */ robust(`robust') borows(`bocols') b(`b_eq') vc(`vc_eq') /* + */ univar(`univar') `onecol' estname(`estname') estnameUnique(`estnameUnique') /* + */ fileExist(`fileExist') less(`less') alpha(`alpha') asterisk(`asterisk') `2aster' /* + */ variables(`VARIABLES') matlist(`matlist') leave(`leave') sidewayWave(`sidewayWave') + * taken out: `se' `pvalue' `ci' `tstat' + } + + * create new file: replace and the first equation + if `eq' == 1 & "`append'"!="append" & `sidewayWave'==1 { + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + outsheet nameCol reportCol `using', nonames `quote' `comma' `replace' + local fileExist 1 + } + * appending here: another estimates or another equation + else { + * confirm the existence of the output file + local rest "`using'" + * strip off "using" + gettoken part rest: rest, parse(" ") + if `fileExist'==1 { + * it exists: keep on appending even if it's the first equation + appendFile `using', titlefile(`titlefile') `sideway' /* + */ `onecol' sortcol(`sortcol') sortvar(`sortvar') groupvar(`groupvar') `quote' `comma' slow(`slow') + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + outsheet v* reportCol `using', nonames `quote' `comma' replace + *drop v* + } + else { + * does not exist and specified append: need to be created for the first equation only + *if `eq' == 1 & "`append'"=="append" { + if `eq' == 1 & "`append'"=="append" & `sidewayWave'==1 { + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + outsheet nameCol reportCol `using', nonames `quote' `comma' `replace' + local fileExist 1 + } + } + } + + restore, preserve + } /* sideway multiple equation */ + + local eq = `eq' + 1 + + *restore, preserve /* to access var labels after first equation */ + } + } + } /* for quietly */ + } /* run each estimates consecutively */ + + + quietly { + + *** clean the files to be preared for output + if "`pivot'"=="pivot" { + + *** pivot and xpose here + _sxpose `using', `quote' `comma' title(`title') titlefile(`titlefile') `label' /* + */ labelOption(`labelOption') + * c_locals titleWide headRow bottomRow + } + else { + cleanFile `using', `quote' `comma' title(`title') titlefile(`titlefile') `label' /* + */ labelOption(`labelOption') slow(`slow') + * c_locals titleWide headRow bottomRow + } + + + *** preparing for outputs and seeout + ren v1 coef + cap ren v0 eq + + unab vlist : v* + local count: word count `vlist' + forval num=1/`count' { + local vname: word `num' of `vlist' + ren `vname' v`num' + } + + + * number of columns + describe, short + local numcol = `r(k)' + + + tempvar blanks rowmiss + gen int `blanks' = (trim(v1)=="") + + foreach var of varlist v* { + replace `blanks' = `blanks' & (trim(`var')=="") + } + + replace `blanks'=0 if coef==`"`VARIABLES'"' | coef[_n-1]==`"`VARIABLES'"' + + * fix blanks==1 for groupvar( ) + count if `blanks'==1 + local rN=`r(N)'+1 + forval num=1/`rN' { + replace `blanks'=0 if `blanks'[_n+1]==0 & `blanks'==1 + } + + * headBorder & bottomBorder + local headBorder=`headRow'+`titleWide' + local bottomBorder=`bottomRow'+`titleWide' /* add eqAdded later */ + + + *** making alternative output files + if "`long'"=="long" | `tex'==1 | "`word'"=="word" | "`excel'"=="excel" | "`text'"=="text" | "`pivot'"=="pivot" { + + if "`text'"=="text" | ("`long'"=="long" & "`onecol'"=="onecol") { + local dot=index(`"`using'"',".") + if `dot'~=0 { + local before=substr(`"`using'"',1,`dot'-1) + local after=substr(`"`using'"',`dot'+1,length("`using'")) + + *local usingLong=`"`before'_long.`after'"' + local usingLong=`"`before'_exact.`after'"' + } + } + + local eq_exist + capture confirm variable eq + *if _rc~=0 & "`long'"=="long" { + * noi di in yellow "equation not detected; {opt long} may not be needed" + *} + + *** convert the data into long format (insert the equation names if they exist) + if _rc==0 & "`long'"=="long" & "`onecol'"=="onecol" { + * a routine to insert equation names into coefficient column + count if `blanks'==0 & eq~="" & eq~="EQUATION" + + gen float id5=_n + local _firstN=_N + set obs `=_N+`r(N)'' + local times 1 + forval num=2/`_firstN' { + if eq[`num']~="" & eq[`num']~="EQUATION" { + replace id5=`num'-.5 in `=`_firstN'+`times'' + local times=`times'+1 + } + } + * eqAdded here: + local bottomBorder=`bottomBorder'+`r(N)' + + count if `blanks'==0 & eq~="" & eq~="EQUATION" + local _firstN=_N + set obs `=_N+`r(N)'' + local times 1 + forval num=2/`_firstN' { + if eq[`num']~="" & eq[`num']~="EQUATION" { + replace id5=`num'-.75 in `=`_firstN'+`times'' + replace coef=eq[`num'] in `=`_firstN'+`times'' + local times=`times'+1 + } + } + + + sort id5 + + drop eq id5 `blanks' + + * change `bottomBorder' by the number of equations inserted + local bottomBorder=`bottomBorder'+`r(N)' + + * v names + unab vlist : * + local count: word count `vlist' + forval num=1/`count' { + local vname: word `num' of `vlist' + ren `vname' c`num' + } + forval num=1/`count' { + local vname: word `num' of `vlist' + ren c`num' v`num' + } + + if "`text'"=="text" { + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + outsheet v* `usingLong', nonames `quote' `comma' replace + } + + } /* long format */ + + else { + drop `blanks' + + * v names + unab vlist : * + local count: word count `vlist' + forval num=1/`count' { + local vname: word `num' of `vlist' + ren `vname' c`num' + } + forval num=1/`count' { + local vname: word `num' of `vlist' + ren c`num' v`num' + } + } + + *** label replacement + if "`label'"=="label" { + if ("`long'"~="long" & "`onecol'"~="onecol") | ("`long'"=="long" & "`onecol'"=="onecol") { + replace v2=v1 if v2=="" + drop v1 + describe, short + forval num=1/`r(k)' { + ren v`=`num'+1' v`num' + } + + * change LABELS to VARIABLES in 1/3 + replace v1=`"`VARIABLES'"' if v1=="LABELS" + } + else if "`long'"~="long" & "`onecol'"=="onecol" { + replace v3=v2 if v3=="" + drop v2 + describe, short + forval num=2/`r(k)' { + ren v`=`num'+1' v`num' + } + + * change LABELS to VARIABLES + replace v2=`"`VARIABLES'"' if v2=="LABELS" + } + + * create new text file + * do it for _long file as well + if "`text'"=="text" { + + } + } + else if "`labelOption'"=="insert" { + * label inserted earlier + } + + tempfile outing + save `outing' + + + *** Pivot thing + if "`pivot'"=="pivot" { + * produce verbatim text + + } + + + *** Text thing + if "`text'"=="text" & "`label'"=="label" { + * produce verbatim text + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + outsheet v* `usingLong', nonames `quote' `comma' replace + } + + *** LaTeX thing + if `tex' { + + * make certain `1' is not `using' (another context) + + _texout v* using `"`strippedname'"', texFile(`texFile') titleWide(`titleWide') headBorder(`headBorder') bottomBorder(`bottomBorder') `texopts' replace + + if `"`texFile'"'=="" { + local endName "tex" + } + else { + local endName "`texFile'" + } + + local usingTerm `"`strippedname'.`endName'"' + + c_local cl_tex `"{stata `"shellout using `"`usingTerm'"'"':`usingTerm'}"' + *noi di as txt `"`cl_tex'"' + } + + *** Word rtf file thing + if "`word'"=="word" { + use `outing',clear + + * there must be varlist to avoid error + *out2rtf2 v* `using', titleWide(`titleWide') headBorder(`headBorder') bottomBorder(`bottomBorder') replace nopretty + out2rtf2 v* using `"`strippedname'"', wordFile(`wordFile') titleWide(`titleWide') /* + */ headBorder(`headBorder') bottomBorder(`bottomBorder') replace nopretty + local temp `r(documentname)' + + * strip off "using" and quotes + gettoken part rest: temp, parse(" ") + gettoken usingTerm second: rest, parse(" ") + + * from school + *local cl `"{stata shell winexec cmd /c tommy.rtf & exit `usingTerm' & EXIT :`usingTerm' }"' + * these work but leaves the window open + *local cl `"{stata winexec cmd /c "`usingTerm'" & EXIT :`usingTerm'}"' + *local cl `"{stata shell "`usingTerm'" & EXIT :`usingTerm'}"' + *local cl `"{stata shell cmd /c "`usingTerm'" & EXIT :`usingTerm'}"' + + c_local cl_word `"{stata `"shellout using `"`usingTerm'"'"':`usingTerm'}"' + *noi di as txt `"`cl_word'"' + } + + *** Excel xml file thing + if "`excel'"=="excel" { + use `outing',clear + + *tempfile fileXml + *xmlsave `"`strippedname'.xml"',doctype(excel) replace legible + + _xmlout using `"`strippedname'"', excelFile(`excelFile') nonames titleWide(`titleWide') /* + */ headBorder(`headBorder') bottomBorder(`bottomBorder') + + if `"`excelFile'"'=="" { + local endName "xml" + } + else { + local endName "`excelFile'" + } + + local usingTerm `"`strippedname'.`endName'"' + + *c_local cl_excel `"{stata `"shellout using `"`usingTerm'"'"':`usingTerm'}"' + c_local cl_excel `"{browse `"`usingTerm'"'}"' + *noi di as txt `"`cl_excel'"' + } + } /* output files */ + } /* quietly */ + + +*** see the output +if "`label'"=="label" | "`labelOption'"=="insert" { + if "`seeout'"=="seeout" { + if "`label'"=="label" { + seeing `using', label + } + else { + seeing `using', label(`labelOption') + } + } + if "`label'"=="label" { + c_local cl_see `"{stata `"seeout using `file', label"':seeout}"' + } + else { + c_local cl_see `"{stata `"seeout using `file', label(`labelOption')"':seeout}"' + } + *di as txt `"`cl'"' +} +else { + if "`seeout'"=="seeout" { + seeing `using' + } + c_local cl_see `"{stata `"seeout using `file'"':seeout}"' + *di as txt `"`cl'"' +} + +end /* end of _outreg2 */ + + +******************************************************************************************** + + +program define appendFile +* previously appfile2 + + versionSet + version `version' + +* append regression results to pre-existing file + +syntax using/, titlefile(string) [sideway onecol sortcol(string) sortvar(string) groupvar(string) /* + */ noQUOte comma slow(numlist)] + +*** take out VARIABLES as the column heading and restore later +*local VARIABLES2 "`variables'" + +* first name is the VARIABLES +local content +local num 1 +local N=_N +while `"`content'"'=="" & `num'<=`N' { + local content=nameCol[`num'] + local num=`num'+1 +} +local VARIABLES2 `"`content'"' +replace nameCol = "" if nameCol==`"`VARIABLES2'"' & rowtype2==-1 + + +* column number rows +* pre-create Vorder here +gen Vorder2=0 if rowtype2==0 +while Vorder2[1]==. { + replace Vorder2=Vorder2[_n+1]-1 if rowtype2==-1 +} +egen min=min(Vorder2) +replace Vorder2=-99 if Vorder2==min +drop min + +* Constant is now done as eqOrder0 + .5 +*replace Vorder2=2 if nameCol=="Constant" /* ok because equation names would still be attached if present */ + +* orders bottom row, Observations, r2, and else +replace Vorder2=3.8 if rowtype2>=2 +replace Vorder2=Vorder2[_n-1]+.0001 if Vorder2>=3.8 & rowtype2==3 +replace Vorder2=2 if rowtype2==2 +replace Vorder2=3.5 if nameCol=="Observations" +replace Vorder2=3.6 if nameCol=="R-squared" + +replace Vorder2=1 if Vorder2==. & (Vorder2[_n-1]<1 | Vorder2[_n-1]==1) +replace Vorder2=2.5 if nameCol=="" & (Vorder2[_n-1]==2 | Vorder2[_n-1]==2.5) + + +* genderate eq_order2 (handles Constant within each equation) +local N=_N +gen eq_order2=0 in 3/`N' if eqName~="" +replace eq_order2=1 in 3/`N' if eqName[_n]~=eqName[_n-1] & eqName~="" +replace eq_order2=eq_order2+eq_order2[_n-1] if eq_order2+eq_order2[_n-1]~=. + +* generating order within each coefficient, use sortvar( ) if available +gen Vorder2_0=. +local maxnum 1 +if "`sortvar'"~="" { + tokenize `sortvar' + local num 1 + while "``num''"~="" { + replace Vorder2_0=`num' if VarName=="``num''" + local num=`num'+1 + } + if `num'>`maxnum' { + local maxnum `num' + } +} + +* the evil twin of sortvar that will insert blanks/groups as well as order the existing variables +if "`groupvar'"~="" { + * stats rows per variable + count if nameCol~="" & rowtype2==1 + local nom `r(N)' + count if rowtype2==1 + if `nom'~=0 { + local rN=`r(N)' + *local many=int(round(`rN'/`nom')) + local many=int(round(`rN'/`nom',1)) + } + else { + local many 2 + } + + * eqnames for multiple equation + tab eqName if rowtype2==1 + local rr=`r(r)' + local tempList + local orderlist + if `rr'> 0 { + * get eq names + + gen str5 temp="" + replace temp=eqName if eqName~=eqName[_n-1] & rowtype2==1 + sort temp + local N=_N + forval num=1/`rr' { + local content=temp[`N'-`num'+1] + local tempList="`tempList' `content'" + local content=eq_order2[`N'-`num'+1] + local orderlist="`orderlist' `content'" + } + drop temp + sort mrgrow + local times `rr' + } + else { + * it's a single equation, run it once + local times 1 + } + + + tokenize `groupvar' + forval kk=1/`times' { + local order: word `kk' of `orderlist' + local temp: word `kk' of `tempList' + + local num 1 + local count0 0 + while "``num''"~="" { + replace Vorder2_0=`num' if VarName=="``num''" & eqName=="`temp'" + count if Vorder2_0~=. & eqName=="`temp'" + if `r(N)'==`count0' { + forval cc=1/`many' { + * insert this many blank var + local N=_N + set obs `=`N'+1' + local N=_N + if `cc'==1 { + replace nameCol="``num''" in `N' + } + replace VarName="``num''" in `N' + replace rowtype2=1 in `N' + replace Vorder2=1 in `N' + replace Vorder2_0=`num' in `N' + + * for multiple equation only + if `rr'>0 { + if `cc'==1 { + replace nameCol="`temp':" + nameCol in `N' + } + replace eq_order2=`order' in `N' + replace eqName="`temp'" in `N' + } + } + } + count if Vorder2_0~=. & eqName=="`temp'" + local count0 `r(N)' + local num=`num'+1 + } + if `num'>`maxnum' { + local maxnum `num' + } + } +} + + +* own column to handle sortvar (to handle in mutliple equation) +gen sortvarCol2=Vorder2_0 + +gen temp=_n +replace Vorder2_0 = temp+`maxnum' if Vorder2==1 & nameCol~="" & Vorder2_0==. +replace Vorder2_0 = Vorder2_0[_n-1] if Vorder2_0==. & Vorder2==1 +drop temp + +replace sortvarCol2=Vorder2_0 if sortvarCol2~=. + +gen double Vorder2_1 = Vorder2_0 if Vorder2==1 & nameCol~="" +replace Vorder2_1 = Vorder2_1[_n-1]+.01 if Vorder2_1==. & Vorder2==1 + +* for groupvar( ) above +sort Vorder2 eq_order2 Vorder2_1 mrgrow +replace mrgrow=_n + + +tempfile tmpf1 + +gen str8 mergeOn = "" +replace mergeOn = nameCol /* room for "!" at end */ + +gen str8 varsml="" +replace varsml = trim(mergeOn) + +* fill the spaces between the names +local N=_N + +replace mergeOn = mergeOn[_n-1]+"!" if varsml=="" +replace mergeOn = "bottomRow" if rowtype2==2 +replace mergeOn = "topRow" if rowtype2==0 +replace mergeOn = "_000" if rowtype2==-1 +gen varnum = Vorder2 if Vorder2<1 + +* add "!" to variable name to make it sort after previous variable name +* will cause bug if both "varname" and "varname!" already exist + +count if (varsml=="" | (varsml[_n+1]=="" & _n!=_N)) +local ncoeff2 = r(N) /* number of estimated coefficients in file 2 */ +local N2 = _N /* number of lines in file 2 */ +gen Vord2 = _n /* ordering variable for file 2 */ + +ren VarName VarName2 +ren eqName eqName2 + +drop varsml + +* eqName vs eqName2 +keep nameCol reportCol mergeOn varnum Vord2 Vorder2 Vorder2_0 Vorder2_1 VarName2 eqName2 eq_order2 rowtype2 sortvarCol2 + +tempfile mergeVarFile mergeEqFile +gen str8 mergeVar="" +gen str8 mergeEq="" + +* two sorting/merging mechanism +local N=_N +count if eqName2=="" | eqName2=="EQUATION" +if `N'==`r(N)' { + * single equation + local usingSingle 1 + replace mergeVar=mergeOn + + sort mergeVar varnum + save `mergeVarFile', replace +} +else { + * multiple equations + local usingSingle 0 + replace mergeEq=mergeOn + + replace mergeVar = mergeOn + replace mergeVar = VarName2 if VarName2~="" & Vorder2==1 + replace mergeVar = "Constant" if VarName2=="_cons" & Vorder2==1 + replace mergeVar = mergeVar[_n-1]+"!" if mergeVar==mergeVar[_n-1] & mergeVar~="" & Vorder2==1 + + sort mergeVar varnum + save `mergeVarFile', replace + + sort mergeEq varnum + save `mergeEqFile', replace +} + + + + +*** prepare the original file for merging + +if "`Version7'"=="" { + * it is version 7 + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + insheet using `"`using'"', nonames clear +} +else { + * requires 8 or above + _chewfile using `"`using'"', semiclear + local num 1 + foreach var of varlist _all { + ren `var' v`num' + local num=`num'+1 + } +} + +if "`sideway'"=="sideway" { + * if sideway, need to split eqname and varname, no label or title here + cleanFile using `"`using'"', `quote' `comma' notitle slow(`slow') + + * get ride of v0 in case of equation + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + insheet using `"`using'"', nonames clear +} + +*** save equation column if it exists before dropping it +local exists_eq=0 +count if v1=="EQUATION" +if `r(N)'~=0 { + gen str8 v0="" + replace v0=v1 + local exists_eq=1 + drop v1 + * count v0 as well + describe, short + forval num=2/`r(k)' { + ren v`num' v`=`num'-1' + } +} + +*** strip labels columns +count if v2=="LABELS" +if `r(N)'~=0 { + drop v2 + * count v0 as well + * cap is added to avoid the last column v0 being misnamed + describe, short + forval num=2/`r(k)' { + cap ren v`=`num'+1' v`num' + } +} + +*** save title first one only, before stripping coef columns +cap save `titlefile' + +*** must drop title first +if `exists_eq'==1 { + if v0[1]~="" { + * there may be a title + while v0[1]~="" & v2=="" { + drop in 1 + } + } +} +if v1[1]~="" { + * there may be a title + while v1[1]~="" & v2=="" { + drop in 1 + } +} + + +*local VARIABLES "`variables'" +* first name is the VARIABLES +local content +local num 1 +local N=_N +while `"`content'"'=="" & `num'<=`N' { + local content=v1[`num'] + local num=`num'+1 +} +local VARIABLES1 `"`content'"' + + +*** drop titles and establish the top row +*egen `rowmiss'=rowmiss(_all) +* rowmiss option not available in 8.2 or 8.0, do it by hand +gen rowmiss=0 +foreach var of varlist v* { + replace rowmiss=rowmiss+1 if `var'~="" +} + +* rowmiss will not catch if ctitles are blank for the first column (1), count down from the top (already done for VARIABLES1) +*replace rowmiss=1 if v1[_n-1]~="VARIABLES" +replace rowmiss=1 if v1[_n-1]~=`"`VARIABLES1'"' + +* NOTE: "VARIABLES" is no longer taken off; it merely gets written over in the same spot later on +while v1[1]~="" & rowmiss==1 { + drop in 1 +} + +*** finish cleaning the equation columns + +gen str8 VarName1="" +gen str8 eqName1="" + +gen rowtype1=-1 +replace rowtype1=0 if rowmiss==0 +replace rowtype1=999 if rowmiss[_n-1]==0 | rowtype1[_n-1]==999 +replace rowtype1=. if rowtype1==999 +drop rowmiss + + +*** establish the bottom row +local N=_N +local num = `N' +local temp=v1[`num'] +while `"`temp'"'~="" & `num'>=1 { + * keep counting until empty + local num=`num'-1 + local temp=v1[`num'] +} +else { + * already empty + local num=`num'-1 +} + +local num=`num' + 1 +replace rowtype1= 1 if rowtype1==. +replace rowtype1= 2 if _n==`num' +replace rowtype1= 3 if _n>`num' + + +if "`exists_eq'"=="1" { + *** Strip the equation names and slap it back onto the variable column + local N=_N + order v0 + + replace v0=v0[_n-1] if v0=="" & v0[_n-1]~="" & rowtype1==1 + gen eq_order1=0 if rowtype1==1 + replace eq_order1=1 if v0[_n]~=v0[_n-1] & v0~="" & rowtype1==1 + replace eq_order1=1 if v0[_n]~=v0[_n-1] & v0~="" & rowtype1==1 + + replace eq_order1=eq_order1+eq_order1[_n-1] if eq_order1+eq_order1[_n-1]~=. + + replace eqName1=v0 + replace VarName1=v1 + replace VarName1=VarName1[_n-1] if VarName1=="" & VarName1[_n-1]~="" & rowtype1==1 + replace v1=v0 + ":" + v1 if v0~="" & v1~="" & rowtype1==1 + + drop v0 +} + +* not needed, replaced with colonSplit +/*else if "`sideway'"=="sideway" & "`onecol'"=="onecol" { + * special case for sideway and onecol + * because sideway loops internally, EQUATION and LABELS columns does not exist + * eqName and VarName are still joined, they need to separated + * v1 is as it should be + + *** borrowed from: + *** clean up equation names, title, label + gen id1=_n + gen str8 equation="" + gen str8 variable="" + + local N=_N + forval num=1/`N' { + local name=trim(v1[`num']) + local column=index("`name'",":") + if `column'~=0 { + local equation=trim(substr("`name'",1,`column'-1)) + local variable=trim(substr("`name'",`column'+1,length("`name'"))) + replace equation="`equation'" in `num' + replace variable="`variable'" in `num' + } + } + replace equation=equation[_n-1] if equation=="" & equation[_n-1]~="" & rowtype1~=2 + + replace eqName1=equation if equation~="" + replace VarName1=variable if variable~="" + drop equation variable id1 + + local N=_N + gen eq_order1=0 in 3/`N' if eqName1~="" + replace eq_order1=1 in 3/`N' if eqName1[_n]~=eqName1[_n-1] & eqName1~="" + replace eq_order1=eq_order1+eq_order1[_n-1] if eq_order1+eq_order1[_n-1]~=. +} +*/ +else { + *** eq names not present + gen eq_order1=1 + replace eq_order1=. if rowtype1==2 +} + + + + +*** take out COEFFICIENT/VARIABLES as the column heading and restore later +replace v1 = "" if rowtype1==-1 + +* getting the characteristics +describe, short +*local numcol = `r(k)' /* number of columns already in file 1 */ + +* subtract 4 to account for eq_order1, VarName1, eqName1, rowtype1 +local numcol = `r(k)'-4 /* number of columns already in file 1 */ + +gen str8 mergeOn = "" +replace mergeOn=v1 +local titleWide = (v1[1]!="") + +* `titleWide' is assumed to be zero +local frstrow = 1 + `titleWide' /* first non-title row */ + +gen long Vord1 = _n +gen str8 v2plus = "" +replace v2plus=trim(v2) + +local col = 3 +if `col'<=`numcol' { + replace v2plus = v2plus + trim(v`col') + local col = `col'+1 +} + +gen topoff=1 if v1~="" +replace topoff=1 if topoff[_n-1]==1 +replace topoff=sum(topoff) +count if (topoff==0 | (v1=="" & v2plus!="") | (v1[_n+1]=="" & (v2plus[_n+1]!=""|_n==1) & _n!=_N)) +drop topoff + +local ncoeff1 = r(N) + +gen str8 varsml="" +replace varsml = trim(mergeOn) + +summ Vord1 if Vord1>`ncoeff1' & v2plus!="" /* v2plus for addstat */ +local endsta1 = r(max) /* calc last row of statistics before notes */ + +if `endsta1'==. { + local endsta1 = `ncoeff1' +} + +replace mergeOn = mergeOn[_n-1]+"!" if varsml=="" +replace mergeOn = "bottomRow" if rowtype1==2 +replace mergeOn = "topRow" if rowtype1==0 +replace mergeOn = "_000" if rowtype1==-1 + +* pre-create Vorder here +*gen Vorder1 = _n/100 if rowtype1==-1 +*replace Vorder1 = .99 if rowtype1==0 +gen Vorder1=0 if rowtype1==0 + +local mm 1 +while Vorder1[1]==. & `mm'<100 { + local mm=`mm'+1 + replace Vorder1=Vorder1[_n+1]-1 if rowtype1==-1 +} + +egen min=min(Vorder1) +replace Vorder1=-99 if Vorder1==min +drop min + +gen varnum = Vorder1 if Vorder1<1 + +* Constant is now done as eqOrder0 + .5 +*replace Vorder1=2 if v1=="Constant" /* ok because equation names would still be attached if present */ + +* orders bottom row, Observations, r2, and else +replace Vorder1=3.7 if rowtype1>=2 +replace Vorder1=Vorder1[_n-1]+.0001 if Vorder1>=3.7 & rowtype1==3 +replace Vorder1=2 if rowtype1==2 +replace Vorder1=3.5 if v1=="Observations" +replace Vorder1=3.6 if v1=="R-squared" + +replace Vorder1=1 if Vorder1==. & (Vorder1[_n-1]<1 | Vorder1[_n-1]==1) +* a fix for addstat sorting Jan 2009 +*replace Vorder1=4 if v2=="" & Vorder1==3.5 +replace Vorder1=4 if v2=="" & v2plus=="" & Vorder1>3.5 + +* Constant is now done as eqOrder0 + .5 +*replace Vorder1=2.5 if v1=="" & (Vorder1[_n-1]==2 | Vorder1[_n-1]==2.5) + +* generating order within each coefficient, use sortvar( ) if available +gen Vorder1_0=. +local maxnum 1 +if "`sortvar'"~="" { + tokenize `sortvar' + local num 1 + while "``num''"~="" { + replace Vorder1_0=`num' if v1=="``num''" | VarName1=="``num''" & Vorder1==1 + local num=`num'+1 + } + if `num'>`maxnum' { + local maxnum `num' + } +} + +* the evil twin of sortvar that will insert blanks/groups as well as order the existing variables +if "`groupvar'"~="" { + * stats rows per variable + count if v1~="" & rowtype1==1 + local nom `r(N)' + count if rowtype1==1 + if `nom'~=0 { + local many=int(round(`r(N)'/`nom'),1) + } + else { + local many 2 + } + + * eqnames for multiple equation + tab eqName if rowtype1==1 + local rr=`r(r)' + local tempList + local orderlist + if `rr'> 0 { + * get eq names + + gen str5 temp="" + replace temp=eqName if eqName~=eqName[_n-1] & rowtype1==1 + sort temp + local N=_N + forval num=1/`rr' { + local content=temp[`N'-`num'+1] + local tempList="`tempList' `content'" + local content=eq_order1[`N'-`num'+1] + local orderlist="`orderlist' `content'" + } + drop temp + sort Vord1 + local times `rr' + } + else { + * it's a single equation, run it once + local times 1 + } + + tokenize `groupvar' + forval kk=1/`times' { + local order: word `kk' of `orderlist' + local temp: word `kk' of `tempList' + + local num 1 + local count0 0 + while "``num''"~="" { + replace Vorder1_0=`num' if (v1=="``num''" | VarName1=="``num''" ) & eqName=="`temp'" + count if Vorder1_0~=. & eqName=="`temp'" + if `r(N)'==`count0' { + forval cc=1/`many' { + * insert this many blank var + local N=_N + set obs `=`N'+1' + local N=_N + if `cc'==1 { + replace v1="``num''" in `N' + } + replace VarName="``num''" in `N' + replace rowtype1=1 in `N' + replace Vorder1=1 in `N' + replace Vorder1_0=`num' in `N' + + * for multiple equation only + if `rr'>0 { + if `cc'==1 { + replace v1="`temp':" + v1 in `N' + } + replace eq_order1=`order' in `N' + replace eqName="`temp'" in `N' + } + } + } + count if Vorder1_0~=. & eqName=="`temp'" + local count0 `r(N)' + local num=`num'+1 + } + if `num'>`maxnum' { + local maxnum `num' + } + } +} + +* must be filled: +replace mergeOn=v1 if Vord1==. +replace mergeOn=mergeOn[_n-1]+"!" if Vord1==. & mergeOn=="" + +* own column to handle sortvar (to handle in mutliple equation) +gen sortvarCol1=Vorder1_0 + +gen temp=_n +replace Vorder1_0 = temp+`maxnum' if Vorder1==1 & varsml~="" & Vorder1_0==. +replace Vorder1_0 = Vorder1_0[_n-1] if Vorder1_0==. & Vorder1==1 +drop temp + +replace sortvarCol1=Vorder1_0 if Vorder1_0<`maxnum' + +gen double Vorder1_1 =Vorder1_0 if Vorder1==1 & v1~="" +replace Vorder1_1=Vorder1_1[_n-1]+.01 if Vorder1_1==. & Vorder1==1 + +* for groupvar( ) above +sort Vorder1 eq_order1 Vorder1_1 Vord1 +replace Vord1=_n + +drop varsml + + +*** merging the two files +* two sorting/merging mechanism +local N=_N +count if eqName1=="" & eqName1=="EQUATION" +local rN=`r(N)' +if `N'==`rN' & `usingSingle'==1 { + * single equation in both files + gen str8 mergeVar="" + replace mergeVar = mergeOn + sort mergeVar varnum + + merge mergeVar varnum using "`mergeVarFile'" + drop mergeEq mergeVar +} +else if `N'~=`rN' & `usingSingle'==1 { + * this one's multiple merged to earlier single + + gen str8 mergeVar="" + replace mergeVar = mergeOn + replace mergeVar = VarName1 if VarName1~="" & Vorder1==1 + replace mergeVar = "Constant" if VarName1=="_cons" & Vorder1==1 + replace mergeVar = mergeVar[_n-1]+"!" if mergeVar==mergeVar[_n-1] & mergeVar~="" & Vorder1==1 + sort mergeVar varnum + + merge mergeVar varnum using "`mergeVarFile'" + drop mergeEq mergeVar +} +else if `N'==`rN' & `usingSingle'==0 { + * this one's multiple merged to earlier single + gen str8 mergeVar="" + replace mergeVar = mergeOn + replace mergeVar = VarName1 if VarName1~="" & Vorder1==1 + replace mergeVar = "Constant" if VarName1=="_cons" & Vorder1==1 + replace mergeVar = mergeVar[_n-1]+"!" if mergeVar==mergeVar[_n-1] & mergeVar~="" & Vorder1==1 + sort mergeVar varnum + + merge mergeVar varnum using "`mergeVarFile'" + drop mergeEq mergeVar +} +else { + * both files are multiple equations + ren mergeOn mergeEq + sort mergeEq varnum + + merge mergeEq varnum using "`mergeEqFile'" + drop mergeEq mergeVar +} + + + +*** clean up and sort the merged files +* Vorder2 has the information for the top 0.01-0.03 +* but Vorder1 has the bottom notes +gen Vorder=Vorder2 +replace Vorder=Vorder1 if Vorder==. | (Vorder1>3.5 & Vorder1<4) + +gen byte merge2 = _merge==2 + +* Notes and defintions: +* Vorder2 _n for master file +* Vorder1 _n for using file + +* Vorder2_0 identifier for each coefficient (using _n for the top most stats) +* Vorder2_1 added 0.01 consequtively to bysort Vorder2_0 + +* Vorder1_0 identifier for each coefficient (using _n for the top most stats) +* Vorder1_1 added 0.01 consequtively to bysort Vorder1_0 + +*** this fills up the potential gaps in Vord1 and Vord2 if the number of stats( ) per coefficient is different +*order eq_order* Vorder Vord1 Vord2 Vord* + +sort eq_order2 Vorder2_1 +replace Vord1=Vord1[_n-1]+.01 if (Vorder2_0==Vorder2_0[_n-1] & Vorder2_0~=.) & (Vord1==. & Vord1[_n-1]~=.) & Vorder==1 + +sort eq_order1 Vorder1_1 +replace Vord2=Vord2[_n-1]+.01 if (Vorder1_0==Vorder1_0[_n-1] & Vorder1_0~=.) & (Vord2==. & Vord2[_n-1]~=.) & Vorder==1 + +* it's off by 1; replace them all +replace Vorder2_1=Vord2 if Vorder==1 +replace Vorder1_1=Vord1 if Vorder==1 + + +*** new sorting rules +*** June 2008 Version +gen str8 eqName0="" +replace eqName0=eqName2 +replace eqName0=eqName1 if eqName0=="" & eqName1~="" + +sort eqName0 Vorder1_1 +gen eq_order0=. +gen eq_temp=1 if eqName0[_n]~=eqName0[_n-1] & Vorder1_1~=. + +************ sort to the existing column? +sort eq_temp Vorder1_1 + +*** get all constant rows +local count 0 +gen constant=0 +replace constant=1 if (v1=="Constant" | v1=="_cons" | nameCol=="Constant" | nameCol=="_cons" | VarName1=="Constant" | VarName2=="Constant" | VarName1=="_cons" | VarName2=="_cons") & Vorder==1 +replace constant=1 if mergeOn==mergeOn[_n-1]+"!" & constant[_n-1]==1 & Vorder==1 + + +************* needs beter levelsof code? +if "`exists_eq'"=="1" | ("`sideway'"=="sideway" & "`onecol'"=="onecol") { + count if eq_temp==1 + if r(N)~=0 { + forval num=1/`=r(N)' { + local temp=eqName0[`num'] + + * collecting names + *local eqOrderList "`temp' `eqOrderList'" + replace eq_order0=`num' if eqName0=="`temp'" + } + replace eq_order0=eq_order0+.5 if constant==1 + } +} +else { + * pushes _cons toward the bottom + replace eq_order0=1 + replace eq_order0=eq_order0+.5 if constant==1 +} + + +count if Vorder2_0>=1 & Vorder2_0<. +local countV2=r(N) + +count if Vorder1_0>=1 & Vorder1_0<. +local countV1=r(N) + +*** sort( ) takes "name later" +* sort according to varname for _tab3 +if "`sortcol'"=="name" { + * do this by replacing these: + sort mergeOn + replace Vorder2_1=_n if Vorder==1 + replace Vorder1_1=_n if Vorder==1 +} + +* consolidate sortvarCol info +gen sortvarCol=sortvarCol1 +replace sortvarCol=sortvarCol2 if sortvarCol==. + + +* temporary fix for Partha Deb: Aug 2008 version +if `countV2'>`countV1' | "`sortcol'"=="later" { + *sort Vorder eq_order0 Vorder2_1 Vorder1_1 merge2 Vord2 + * Jan 2009 Mohl + *sort Vorder eq_order0 Vorder2_1 Vorder1_1 merge2 Vord2 Vord1 + sort Vorder eq_order0 sortvarCol Vorder2_1 Vorder1_1 merge2 Vord2 Vord1 +*order Vorder eq_order0 sortvarCol Vorder2_1 Vorder1_1 merge2 Vord2 Vord1 +*browse +} +else { + *sort Vorder eq_order0 Vorder1_1 Vorder2_1 merge2 Vord1 + * Jan 2009 Mohl + *sort Vorder eq_order0 Vorder1_1 Vorder2_1 merge2 Vord1 Vord2 + sort Vorder eq_order0 sortvarCol Vorder1_1 Vorder2_1 merge2 Vord1 Vord2 +*order Vorder eq_order0 sortvarCol Vorder1_1 Vorder2_1 merge2 Vord1 Vord2 +*browse +} + + + +*** fill in if it was a single equation combining with a multiple equation +count if eqName0~="EQUATION" & eqName0~="" +if `r(N)'>0 { + replace nameCol = "SINGLE:"+nameCol if Vorder==1 & eqName0=="" & nameCol~="" + replace v1 = "SINGLE:"+v1 if Vorder==1 & eqName0=="" & v1~="" +} + + + +replace v1 = nameCol if v1=="" & nameCol!="" +*drop nameCol mergeOn varsml Vorder Vord1 Vord2 merge2 _merge v2plus +drop nameCol mergeOn varnum Vorder Vord1 Vord2 merge2 _merge v2plus Vorder1* Vorder2* eq* *Name* +cap drop sort* +cap drop group* + + * add the head column numbers + if (`numcol'==2) { + replace v2 = "(1)" if _n==`frstrow' + replace reportCol = "(2)" if _n==`frstrow' + } + else { + replace reportCol = "(" + string(`numcol') + ")" if _n==`frstrow' + } + + + +*** restore COEFFICIENT and 0 head +replace v1=`"`VARIABLES2'"' if rowtype1[_n+1]==0 +replace v1=`"`VARIABLES2'"' if rowtype1==0 & v1[_n-1]~=`"`VARIABLES2'"' + +drop rowtype1 rowtype2 constant + +c_local VARIABLES `"`VARIABLES2'"' + +end /* appendFile */ + + +******************************************************************************************** + + +program define marginal2 + versionSet + version `version' + +* put marginal effects (dfdx) into b and vc matrices + +syntax , b(string) vc(string) [se margucp(string)] + +tempname dfdx se_dfdx new_vc dfdx_b2 +capture mat `dfdx' = e(dfdx`margucp') +if _rc==0 { + local cnam_b : colnames `dfdx' + local cnam_1 : word 1 of `cnam_b' +} +if _rc!=0 { + if "`cnam_1'"=="c1" { + di in yellow `"Update dprobit ado file: type "help update" in Stata"' + } + else { + di in yellow "{opt margin} option invalid: no marginal effects matrix e(dfdx`margucp') exists" + } + exit +} + +/* create matrix of diagonals for vc */ +if "`se'"=="se" { + if e(cmd)=="dprobit" | e(cmd)=="tobit" { + if e(cmd)=="dprobit" { + local margucp "_dfdx" + } + mat `se_dfdx' = e(se`margucp') + mat `vc' = diag(`se_dfdx') + mat `vc' = `vc' * `vc' + } + else { + mat `vc' = e(V_dfdx) + } + mat colnames `vc' = `cnam_b' +} +else { + /* if t or p stats reported then trick `cv' into giving the right t stat */ + local coldfdx = colsof(`dfdx') + mat `new_vc' = J(`coldfdx',`coldfdx',0) + local i = 1 + while `i' <= `coldfdx' { + scalar `dfdx_b2' = (el(`dfdx',1,`i')/el(`b',1,`i'))^2 + mat `new_vc'[`i',`i'] = `dfdx_b2'*`vc'[`i',`i'] + local i = `i'+1 + } + mat colnames `new_vc' = `cnam_b' + mat `vc' = `new_vc' +} +mat `b' = `dfdx' +end + + +******************************************************************************************** + + +program define partxtl2, rclass + versionSet + version `version' + + +*** parse text list to find number of text elements and return them + local ntxt = 0 + gettoken part rest: 1, parse(" (") + gettoken part rest: rest, parse(" (") /* strip off "option(" */ + while `"`rest'"' != "" { + local ntxt = `ntxt'+1 + gettoken part rest: rest, parse(",)") + return local txt`ntxt' `"`part'"' + gettoken part rest: rest, parse(",)") /* strip off "," or "(" */ + } + return local numtxt `ntxt' +end + + +******************************************************************************************** + + +*** this one avoids stripping the wrong parenthesis +program define partxtl3, rclass + versionSet + version `version' + + +*** parse text list to find number of text elements and return them + local ntxt = 0 + + * CANNOT use these functions because of string length limitation + *local begin = index(`"`1'"',`"("') + *local length : length local 1 + *local rest=substr(`"`1'"',`begin'+1,`length'-`begin'-1) + + local rest `"`1'"' + + gettoken part rest: 1, parse(" (") + gettoken part rest: rest, parse(" (") /* strip off "option(" */ + while `"`rest'"' != "" { + local ntxt = `ntxt'+1 + gettoken part rest: rest, parse(",") + return local txt`ntxt' `"`part'"' + local last_part `"`part'"' + gettoken part rest: rest, parse(",") + } + + * fix the last one by stripping the ending parenthesis + gettoken part last_part: last_part, parse(")") + + * takes off too much + if "`last_part'"=="))" { + local part `"`part')"' + } + return local txt`ntxt' `"`part'"' + + return local numtxt `ntxt' +end + + +******************************************************************************************** + + +program define makeFile +* previously coeftxt2 + versionSet + version `version' + +* getting the coefficient name, values, and t-statistics + +syntax [varlist(default=none ts)] , * + +syntax [varlist(default=none ts)] , variables(string) /* +*/ [equationsOption(string) /* +*/ keep(string) drop(string) eqkeep(string) eqdrop(string) /* +*/ eqlist(string) betaAsked /* +*/ statsMany(integer 2) statsList(str asis) se_skip /* +*/ BEta Level(integer $S_level) /* +*/ DEC(numlist) FMT(string) /* +*/ BDec(numlist) BFmt(string) /* +*/ SDec(numlist) SFmt(string) /* +*/ Tdec(numlist) TFmt(string) /* +*/ PDec(numlist) PFmt(string) /* +*/ CDec(numlist) CFmt(string) /* +*/ ADec(numlist) AFmt(string) /* +*/ RDec(numlist) RFmt(string) /* +*/ AUTO(integer 3) LESS(integer 0) NOAUTO /* +*/ noPAren parenthesis(str asis) BRacket BRacketA(passthru) /* +*/ noASter SYMbol(passthru) noCONs EForm noobs noNI /* +*/ noR2 ADJr2 ctitleList(string) *] + +local varlistTemp `"`varlist'"' + +* cascading options: +local 0 `", `options'"' +syntax [, ADDStat(passthru) ADDText(passthru) noNOTes /* +*/ ADDNote(passthru) APpend regN(string) df_r(string) rsq(string) /* +*/ numi(string) ivar(string) depvar(string) robust(string) /* +*/ BOROWS(string) b(string) vc(string) /* +*/ univar(string) Onecol estname(string) /* +*/ estnameUnique(string) fileExist(integer 1) /* +*/ ALPHA(string) asterisk(passthru) 2aster /* +*/ matlist(string) leave(string) sidewayWave(integer 1) ] + +* options taken out: SE Pvalue CI Tstat + +local varlist `"`varlistTemp'"' +local VARIABLES "`variables'" + +tempvar b_coefficient b_st_err +tempname b_alone vc_alon b_xtra vc_xtra + +* avoid re-transposing them later by giving distinct names +tempname b_transpose vc_diag_transpose + +mat `b_transpose' = `b'' +mat `vc_diag_transpose' = vecdiag(`vc') +mat `vc_diag_transpose' = `vc_diag_transpose'' + +local brows = rowsof(`b_transpose') + +*** xt options +if (`numi'!=. & "`ni'"!="noni") { + if `"`iname'"'=="" { + local iname "`ivar'" + } + if `"`iname'"'=="." { + local iname "groups" + } +} + +*** disabled, taken out xstats + + +*** replacement codes +* populate with values from e(b) and e(V) + +tempvar firstCol secondCol varKeepDrop nameCol + +*** fill in variables names column +gen str5 `nameCol' = "" +gen str5 `firstCol' = "" +gen str5 `secondCol' = "" + +local Names : rowfullnames(`b_transpose') +local Rows = rowsof(`b_transpose') + +* extender making sure the obs > columns & obs > `Rows' +local N=_N +if `Rows'>`N'+1 & `Rows'<. { + set obs `=`Rows'+1' +} +if `N'<1 { + set obs 1 +} + +forval num=1/`Rows' { + local temp : word `num' of `Names' + + tokenize "`temp'", parse(":") + + if "`2'"==":" { + replace `firstCol' = "`1'" in `num' + replace `secondCol' = "`3'" in `num' + } + else { + replace `secondCol' = "`temp'" in `num' + replace `nameCol' = "`temp'" in `num' + } +} +replace `nameCol' = "Constant" if `firstCol'=="" & `secondCol'=="_cons" +replace `nameCol' = `firstCol' + ":" + `secondCol' if `firstCol'~="" +replace `nameCol' = `firstCol' + ":Constant" if `firstCol'~="" & `secondCol'=="_cons" + +gen double `b_coefficient' = matrix(`b_transpose'[_n, 1]) in 1/`brows' +gen double `b_st_err' = matrix(`vc_diag_transpose'[_n, 1]) in 1/`brows' +replace `b_st_err' = sqrt(`b_st_err') + +*** beta coefficient here +if "`beta'"=="beta" | "`betaAsked'"=="betaAsked" | "`leave'"~="" { + tempname betcoef + + sum `depvar' if e(sample) + local betaSD `r(sd)' + gen `betcoef' =. + + forval num=1/`Rows' { + local temp=`secondCol'[`num'] + cap sum `temp' if e(sample) + replace `betcoef' = r(sd)/`betaSD' * `b_coefficient' if `num'==_n & `secondCol'~="_cons" + } + + if "`beta'"=="beta" | "`betaAsked'"=="betaAsked" { + * set nocons + local cons "nocons" + } +} + + + +*** marksample, version 11 decouples of e(b) from e(sample) +if "`varlist'"=="" & "`casewise'"=="casewise" { + noi di in red "{it:varlist} needs to be specified for use with {opt case:wise}" + exit 198 +} + +tempvar touse +mark `touse' `if' `in' [`weight'`exp'] + +/* +count if e(sample) +if `r(N)'==0 { + if "`raw'"=="raw" { + mark `touse' `if' `in' [`weight'`exp'] + } + else { + noi di in red "zero e(sample) count; run a regression or specify {opt raw} or {opt case:wise}" + exit 198 + } +} +else { + cap confirm matrix e(b) + if _rc==0 { + * always esample restricted + if `"`if'"'~="" { + mark `touse' `if' & e(sample) `in' [`weight'`exp'] + } + else { + mark `touse' if e(sample) `in' [`weight'`exp'] + } + } + else if "`raw'"=="raw" | "`casewise'"=="casewise" { + mark `touse' `if' `in' [`weight'`exp'] + } + else { + noi di in red "e(b) missing; post e-return matrices, run a regression, or specify {opt raw} or {opt case:wise}" + exit 198 + } +} +*/ + +******************** may not always be e(b), may be margins + + + + +******************* all of these may not work well with -long- and multiple equations; problems with reg3 depvar names +count if `secondCol'~="" +local varMany=`r(N)' + +if `varMany'>0 & `varMany'<. { + + local temp=lower(`"`statsList'"') + _stats_check, `temp' + + *** summary from stats( ) here + if "`sumAsked'"~="" { + local tempL0 + + if "`sumAsked'"=="regular" { + * summary + local sumList "N sum_w mean Var sd min max sum" + local detail + } + else { + * detail + local sumList "N sum_w mean Var sd skewness kurtosis sum min max p1 p5 p10 p25 p50 p75 p90 p95 p99" + local detail detail + } + + tempvar `sumList' + foreach stuff in `sumList' { + gen ``stuff'' = . + } + + forval num=1/`varMany' { + local content=`secondCol'[`num'] + foreach stuff in `sumList' { + cap sum `content' if `touse' [`weight'`exp'], `detail' + if _rc==0 & `r(N)'>0 & `r(N)'<. { + cap replace ``stuff'' = `r(`stuff')' in `num' + local tempL0 "`tempL0' ``stuff''" + } + } + } + } + + + *** stats( ) correlations + local tempL1 + + foreach cmd in corr pwcorr spearman { + + if "``cmd'Asked'"=="`cmd'" { + + tempvar `cmd' + gen ``cmd'' = . + + forval num=1/`varMany' { + local content=`secondCol'[`num'] +*********************** if no depvar, then use the varlist + cap `cmd' `depvar' `content' if `touse' [`weight'`exp'] + if _rc==0 { + cap replace ``cmd'' = `r(rho)' in `num' + } + } + local tempL1 "`tempL1' ``cmd''" + } + } + + + *** stats( ) cmd( ) + * take out cmd( ) from statsList and replace with cmd1 cmd2 ... + * also run the cmd( ) and get r( ) back out + + * `regVal1' `regVal2' ... tempvar name for the column containing the values + * cmd1 cmd2 ... name that appears in statsList and the column variable names + * cmd1 cmd2 ... also contain what each cmd are + + local tempL2 + local cmdList + + local tempList + local num 1 + local cc 0 + + gettoken one two: statsList, `bind' + local two=trim(`"`two'"') + + * if okay to add: + local check=substr(trim("`one'"),1,4) + if `"`check'"'=="cmd(" { + + * it's a cmd( ) + local cc=`cc'+1 + local cmd`cc'=`"`one'"' + + tempvar regVal`cc' + gen str7 `regVal`cc'' = "" + + * separate reporting from cmd requested inside: cmd( r( ) cmd) + gettoken reporting cmd: one, `bind' parse("(") + gettoken reporting cmd: cmd, `bind' parse("(") + gettoken reporting cmd: cmd, `bind' parse(":") + gettoken colon cmd: cmd, `bind' parse(":") + + local cmd=substr("`cmd'",1,length("`cmd'")-1) + gettoken cmd suboption: cmd , parse(",") + + local reg`cc'=`"`cmd'"' + + forval num=1/`varMany' { + local content=`secondCol'[`num'] +********************** if no depvar, then use the varlist + cap `cmd' `depvar' `content' if `touse' [`weight'`exp'] `suboption' + if _rc==0 { + cap replace `regVal`cc'' = `"``reporting''"' in `num' + } + } + local cmdList "`cmdList' cmd`cc'" + local tempL2 "`tempL2' `regVal`cc''" + local tempList "`tempList' cmd`cc'" + } + else { + local tempList "`tempList' `one'" + } + + while `"`two'"'~="" { + local num=`num'+1 + + gettoken one two: two, `bind' + local two=trim(`"`two'"') + + * if okay to add: + local check=substr(trim("`one'"),1,4) + if `"`check'"'=="cmd(" { + + * it's a cmd( ) + local cc=`cc'+1 + local cmd`cc'=`"`one'"' + + tempvar regVal`cc' + gen str7 `regVal`cc'' = "" + + * separate reporting from cmd requested inside: cmd( r( ) cmd) + gettoken reporting cmd: one, `bind' parse("(") + gettoken reporting cmd: cmd, `bind' parse("(") + gettoken reporting cmd: cmd, `bind' parse(":") + gettoken colon cmd: cmd, `bind' parse(":") + + local cmd=substr("`cmd'",1,length("`cmd'")-1) + gettoken cmd suboption: cmd , parse(",") + + local reg`cc'=`"`cmd'"' + + forval num=1/`varMany' { + local content=`secondCol'[`num'] + + ************************* disable varlist + ********************** if no depvar, then use the varlist + + cap `cmd' `depvar' `content' if `touse' [`weight'`exp'] `suboption' + if _rc==0 { + cap replace `regVal`cc'' = `"``reporting''"' in `num' + } + } + local cmdList "`cmdList' cmd`cc'" + local tempL2 "`tempL2' `regVal`cc''" + local tempList "`tempList' cmd`cc'" + } + else { + local tempList "`tempList' `one'" + } + } + local statsList `"`tempList'"' + + + + + *** stats( ) str( ) + * take out str( ) from statsList and replace with str1 str2 ... + + * `strVal1' `strVal2' ... tempvar name for the column containing the values + * string1 string2 ... name that appears in statsList and the column variable names + * string1 string2 ... also contain what each strings are + + local tempL3 + local strList + + local tempList + local num 1 + local cc 0 + + gettoken one two: statsList, `bind' + local two=trim(`"`two'"') + + * if okay to add: + local check=substr(trim("`one'"),1,4) + if `"`check'"'=="str(" { + + * it's a str( ) + local cc=`cc'+1 + local string`cc'=`"`one'"' + + tempvar strVal`cc' + gen str7 `strVal`cc'' = "" + + * separate reporting from str requested inside: str( r( ) str) + gettoken junk str: one, `bind' parse("(") + gettoken junk str: str, `bind' parse("(") + local str=substr("`str'",1,length("`str'")-1) + + forval num=1/`varMany' { + local content=`secondCol'[`num'] + replace `strVal`cc'' = `"`str'"' in `num' + } + local strList "`strList' string`cc'" + local tempL3 "`tempL3' `strVal`cc''" + local tempList "`tempList' string`cc'" + } + else { + local tempList "`tempList' `one'" + } + + while `"`two'"'~="" { + local num=`num'+1 + + gettoken one two: two, `bind' + local two=trim(`"`two'"') + + * if okay to add: + local check=substr(trim("`one'"),1,4) + if `"`check'"'=="str(" { + + * it's a str( ) + local cc=`cc'+1 + local string`cc'=`"`one'"' + + tempvar strVal`cc' + gen str7 `strVal`cc'' = "" + + * separate reporting from str requested inside: str( r( ) str) + gettoken junk str: one, `bind' parse("(") + gettoken junk str: str, `bind' parse("(") + local str=substr("`str'",1,length("`str'")-1) + + forval num=1/`varMany' { + local content=`secondCol'[`num'] + replace `strVal`cc'' = `"`str'"' in `num' + } + local strList "`strList' string`cc'" + local tempL3 "`tempL3' `strVal`cc''" + local tempList "`tempList' string`cc'" + } + else { + local tempList "`tempList' `one'" + } + } + local statsList `"`tempList'"' +} + + + + +keep `nameCol' `b_coefficient' `b_st_err' `betcoef' `firstCol' `secondCol' `tempL0' `tempL1' `tempL2' `tempL3' + + + + +*** get rid of original data since labels already accessed +*** rename them because the original data now gone + +ren `b_coefficient' coefVal +ren `b_st_err' seVal +ren `nameCol' nameCol + +if "`beta'"=="beta" | "`betaAsked'"=="betaAsked" | "`leave'"~="" { + ren `betcoef' betaVal +} + +ren `firstCol' eqName +ren `secondCol' VarName +keep if VarName~="" + +if `varMany'>0 & `varMany'<. { + if "`sumAsked'"~="" { + foreach var in `sumList' { + ren ``var'' `var' + } + } + foreach var in corr pwcorr spearman { + if "``var'Asked'"~="" { + ren ``var'' `var' + } + } + local cc 1 + foreach var in `cmdList' { + ren `regVal`cc'' cmd`cc' + local cc=`cc'+1 + } + local cc 1 + foreach var in `strList' { + ren `strVal`cc'' string`cc' + local cc=`cc'+1 + } +} + + + +*** starting to keep/drop here +* varlist/keep +if "`keep'"~="" { + local varlist "`keep'" +} + +* varlist +if "`varlist'"~="" { + gen str5 `varKeepDrop'="" + + * add the constant unless "nocons" is chosen + if "`cons'"~="nocons" { + local varlist "`varlist' _cons" + } + + local count: word count `varlist' + forval num=1/`count' { + local temp : word `num' of `varlist' + replace `varKeepDrop'="`temp'" if "`temp'"==VarName + } + + count if `varKeepDrop'=="" & VarName~="" + local brows=`brows'-r(N) + local borows=`borows'-r(N) + + drop if `varKeepDrop'=="" & VarName~="" + drop `varKeepDrop' +} + +* drop +if "`drop'"~="" { + gen str5 `varKeepDrop'="" + + local count: word count `drop' + forval num=1/`count' { + local temp : word `num' of `drop' + replace `varKeepDrop'="`temp'" if "`temp'"==VarName + } + + count if `varKeepDrop'~="" + local brows=`brows'-r(N) + local borows=`borows'-r(N) + + drop if `varKeepDrop'~="" + drop `varKeepDrop' +} + +*noi di in red "`brows'" +*noi di in red "`borows'" + +if "`cons'"=="nocons" { + gen count=1 if VarName=="_cons" + count if count==1 + local brows=`brows'-r(N) + local borows=`borows'-r(N) + drop if count==1 + drop count +} + +*noi di in red "`brows'" +*noi di in red "`borows'" + +* drop some of multiple equations: 2 of 2 +* (in case only one equation kept but `b' was passed thru inputed instead of `b_eq') + +************* technically this should be fixed (get the eqName non-empty, and use indicator if multi-equation called for) +if "`eqdrop'"~="" & "`long'"=="long" { + gen str5 `varKeepDrop'="" + + local count: word count `eqdrop' + forval num=1/`count' { + local temp : word `num' of `eqdrop' + replace `varKeepDrop'="`temp'" if "`temp'"==eqName + } + + count if `varKeepDrop'~="" + local brows=`brows'-r(N) + local borows=`borows'-r(N) + + drop if `varKeepDrop'~="" + drop `varKeepDrop' +} + +************* technically this should be fixed (get the eqName non-empty, and use indicator if multi-equation called for) +if "`eqkeep'"~="" & "`long'"=="long" { + gen str5 `varKeepDrop'="" + + local count: word count `eqkeep' + forval num=1/`count' { + local temp : word `num' of `eqkeep' + replace `varKeepDrop'="`temp'" if "`temp'"==eqName + } + + count if `varKeepDrop'~="" + local brows=`brows'-r(N) + local borows=`borows'-r(N) + + keep if `varKeepDrop'~="" + drop `varKeepDrop' +} + +* reset brows after dropping +count if nameCol~="" +local brows = `r(N)' + + +/* +matrix matrix1=level' + +*** enhancing with outside matrix +*** fill in variables names column +tempname matrix1 first1 second1 + +*gen str5 `matrix1' = "" +*gen str5 `first1' = "" +*gen str5 `second1' = "" + +*local Names : rowfullnames(`b_transpose') +*local Rows = rowsof(`b_transpose') + +gen str5 matrix1 = "" +gen str5 first1 = "" +gen str5 second1 = "" +gen str5 varname1 = "" +local Names : rowfullnames(matrix1) +local Rows = rowsof(matrix1) + +forval num=1/`Rows' { + local temp : word `num' of `Names' + + tokenize "`temp'", parse(":") + + if "`2'"==":" { + replace first1 = "`1'" in `num' + replace second1 = "`3'" in `num' + } + else { + replace second1 = "`temp'" in `num' + replace varname1 = "`temp'" in `num' + } +} +replace varname1 = "Constant" if first=="" & second=="_cons" +replace varname1 = first + ":" + second if first~="" +replace varname1 = first + ":Constant" if first~="" & second=="_cons" + +gen double b = matrix(matrix1[_n, 1]) in 1/`brows' +gen double s = matrix(matrix1[_n, 1]) in 1/`brows' +replace s = sqrt(s) +*/ + + +/* +*** rename variables for forced row matching +if `"`samevar'"'~="" { + gettoken first second: samevar, parse(",") +} +*/ + + +*** obtain the statistics of interest + +* tstatVal +gen double tstatVal = (coefVal/seVal) + + +* T_alpha for the Ci +if `df_r'==. { + gen double T_alpha = invnorm( 1-(1-`level' /100)/2 ) +} +else { + * replacement for invt( ) function under version 6 + * note the absolute sign: invttail is flipped from invnorm + gen double T_alpha = abs(invttail(`df_r', (1-`level' /100)/2)) +} + +* ci +gen double ci_lowVal=coefVal-T_alpha*seVal +gen double ci_highVal=coefVal+T_alpha*seVal + + * exponentiate beta and st_err + gen double coefEformVal = exp(coefVal) + gen double seEformVal = coefEformVal * seVal + gen double ci_lowEformVal = exp(coefVal - seEformVal * T_alpha / coefEformVal) + gen double ci_highEformVal = exp(coefVal + seEformVal * T_alpha / coefEformVal) + +* pvalVal +if `df_r'==. { + gen double pvalVal = 2*(1-normprob(abs(tstatVal))) +} +else { + gen double pvalVal = tprob(`df_r', abs(tstatVal)) +} + + +* calculate asterisks for t-stats (or standard errors) +local titleWide=0 +if "`append'"=="append" & `fileExist'==1 { + local appottl = 1 +} +else { + local appottl = `titleWide' +} + +* either an appended column (not the first regression) or has a title +* i.e. need an extra line above the coefficients +* added a second extra line above the coefficients: place 1 of 2 +gen mrgrow = 2*_n + 1 + `appottl' + 1 + +*** dealing with the asterisks +if "`aster'"!="noaster" { + + if "`alpha'"~="" { + * parse ALPHA + partxtl2 `"`alpha'"' + local alphaCount = r(numtxt) + local num=1 + while `num'<=`alphaCount' { + local alpha`num' `r(txt`num')' + capture confirm number `alpha`num'' + if _rc!=0 { + noi di in red `"`alpha`num'' found where number expected in {opt alpha()} option"' + exit 7 + } + local num = `num'+1 + } + } + else { + if "`2aster'"=="2aster" { + local alpha1=.01 + local alpha2=.05 + local alphaCount=2 + } + else { + local alpha1=.01 + local alpha2=.05 + local alpha3=.10 + local alphaCount=3 + } + } + + if `"`symbol'"'!="" { + * parse SYMBOL + partxtl2 `"`symbol'"' + local symbolCount = r(numtxt) + local num=1 + while `num'<=`symbolCount' { + local symbol`num' `r(txt`num')' + capture confirm number `symbol`num'' + if _rc==0{ + noi di in red `"`symbol`num'' found where non-number expected in {opt sym:bol()}"' + exit 7 + } + local num = `num'+1 + } + } + else { + *** assume 2aster when only two alpha was given + if "`2aster'"=="2aster" | `alphaCount'==2 { + * 1 and 5 % + local symbol1 "**" + local symbol2 "*" + local symbolCount=2 + } + else { + * 1, 5, and 10% + local symbol1 "***" + local symbol2 "**" + local symbol3 "*" + local symbolCount=3 + } + * when only SYMBOL was given + if "`alpha'"=="" { + + } + } + + if "`alpha'"~="" & `"`symbol'"'~="" { + if `symbolCount'~=`alphaCount' { + di in red "{opt alpha()} and {opt sym:bol()} must have the same number of elements" + exit 198 + } + } + + if "`alpha'"=="" & `"`symbol'"'~="" { + if `symbolCount'>=4 { + di in red "{opt alpha()} must be specified when more than 3 symbols are specified with {opt sym:bol()}" + exit 198 + } + } + + if "`alpha'"~="" & `"`symbol'"'=="" { + local symbolCount=`alphaCount' + if `alphaCount'>=4 { + di in red "{opt sym:bol()} must be specified when more than 3 levels are specified with {opt alpha()}" + exit 198 + } + } + + * fix the leading zero + local num=1 + while `num'<=`alphaCount' { + if index(trim("`alpha`num''"),".")==1 { + local alpha`num'="0`alpha`num''" + } + local num=`num'+1 + } + + * creating the notes for the alpha significance + local astrtxt `"`symbol1' p<`alpha1'"' + local num=2 + while `num'<=`symbolCount' { + local astrtxt `"`astrtxt', `symbol`num'' p<`alpha`num''"' + local num=`num'+1 + } + + * assign the SYMBOL + gen str12 astrix = `"`symbol1'"' if (abs(pvalVal)<`alpha1' & abs(pvalVal)!=.) + + local num=2 + while `num'<=`symbolCount' { + replace astrix = `"`symbol`num''"' if astrix=="" & (abs(pvalVal)<`alpha`num'' & abs(pvalVal)!=.) + local num=`num'+1 + } +} +else { + gen str2 astrix = "" +} + + + + +* add in matrix/vectors names if provided in stats( ) +* the values are to be autodigit later +* splits matlist into vectorList and nonvecList + +local vectorList +local nonvecList + +if "`matlist'"~="" { + tempname matdown + foreach matname in `matlist' { + mat `matdown'=`matname' /* NOT transposed */ + local temp= colsof(`matdown') + + * pre-save + count if eqName~="" + local masterEqExist=`r(N)' + + tempfile masterMultiFile masterSingleFile + + * original file is single equations + sort VarName + save `masterSingleFile', replace + + * original file is multiple equations + sort eqName VarName + save `masterMultiFile', replace + + * empties + drop * + + cap gen str5 nameCol = "" + cap gen str5 eqName = "" + cap gen str5 VarName= "" + + if `temp'==1 { + * it's a vector + local vectorList "`vectorList' `matname'" + + *** borrowed from: *** fill in variables names column + + local Names : rowfullnames(`matdown') + local Rows = rowsof(`matdown') + set obs `Rows' + + forval num=1/`Rows' { + local temp : word `num' of `Names' + + tokenize "`temp'", parse(":") + + if "`2'"==":" { + replace eqName = "`1'" in `num' + replace VarName= "`3'" in `num' + } + else { + replace VarName= "`temp'" in `num' + replace nameCol = "`temp'" in `num' + } + } + replace VarName= "_cons" if VarName=="Constant" + + replace nameCol = "Constant" if eqName=="" & VarName=="_cons" + replace nameCol = eqName + ":" + VarName if eqName~="" + replace nameCol = eqName + ":Constant" if eqName~="" & VarName=="_cons" + + svmat double `matdown', name(`matname') + + * take off 1's that's been slapped on + cap ren `matname'1 `matname' + } + else { + * it's a non-vector matrix + local cc= colsof(`matdown') + local temp0 : colnames(`matdown') + local temp + foreach var in `temp0' { + local temp "`temp' `matname'_`var'" + } + local nonvecList "`nonvecList' `temp'" + + *** borrowed from: *** fill in variables names column + + local Names : rowfullnames(`matdown') + local Rows = rowsof(`matdown') + set obs `Rows' + + forval num=1/`Rows' { + local temp : word `num' of `Names' + + tokenize "`temp'", parse(":") + + if "`2'"==":" { + replace eqName = "`1'" in `num' + replace VarName= "`3'" in `num' + } + else { + replace VarName= "`temp'" in `num' + replace nameCol = "`temp'" in `num' + } + } + replace VarName= "_cons" if VarName=="Constant" + + replace nameCol = "Constant" if eqName=="" & VarName=="_cons" + replace nameCol = eqName + ":" + VarName if eqName~="" + replace nameCol = eqName + ":Constant" if eqName~="" & VarName=="_cons" + + svmat double `matdown', name(col) + + * make it unique name + foreach var in `temp0' { + ren `var' `matname'_`var' + } + + * take off 1's that's been slapped on + *cap ren `matname'1 `matname' + } + + count if eqName~="" + local usingEqExist=`r(N)' + + * slap back to the original master files + if `masterEqExist'==0 | `usingEqExist'==0 { + * at least one single equation + sort VarName + merge VarName using "`masterSingleFile'" + } + else { + * both are multiple equations + sort eqName VarName + merge eqName VarName using "`masterMultiFile'" + } + sort mrgrow + cap drop _m + } + + tempvar order constCol + gen `order'=_n + gen `constCol'=0 + replace `constCol'=1 if VarName=="_cons" + sort `constCol' `order' + drop `constCol' `order' + + * slap on SINGLE if only some are missing equation names + local N=_N + count if eqName=="" + if `r(N)'~=`N' { + replace nameCol="SINGLE:"+VarName if eqName=="" + replace eqName="SINGLE" if eqName=="" + } + + * update + count if mrgrow==. + local brows=`brows'+`r(N)' + replace mrgrow = 2*_n + 1 + `appottl' + 1 + sort eqName VarName +} + +* leave matrices if user-provided suffix available +if "`leave'"~="" { + count if VarName~="" + local rN=r(N) + loca name + forval num=1/`rN' { + local temp=nameCol[`num'] + local name "`name' `temp'" + } + + foreach var in ci_highEform ci_lowEform seEform beta coefEform ci_high ci_low pval tstat se coef { + mkmat `var'Val in 1/`rN', matrix(`var'`leave') + mat colnames `var'`leave'=`var'`leave' + mat rownames `var'`leave'=`name' + } +} + + +*** putting together +* list of current column names other than user specified matrix: +* coefVal seVal nameCol (betaVal) tstatVal T_alpha ci_lowVal ci_highVal pvalVal mrgrow astrix + +gen str12 reportCol = "" + +* first prepare ancillary stats (tstat | se | ci | pvalue | beta) + +foreach var in coef coefEform beta /* + */ pval tstat se seEform /* + */ ci ciEform ci_low ci_lowEform ci_high ci_highEform /* + */ aster blank { + gen str12 `var'String = "" +} + +if `varMany'>0 & `varMany'<. & "`sumAsked'"~="" { + foreach var in `sumList' { + gen str12 `var'String = "" + } +} +foreach var in corr pwcorr spearman { + if `varMany'>0 & `varMany'<. & "``var'Asked'"~="" { + gen str12 `var'String = "" + } +} +if `varMany'>0 & `varMany'<. { + foreach var in `cmdList' { + gen str12 `var'String = "" + } + foreach var in `strList' { + gen str12 `var'String = "" + } +} + + +local N=_N +* autodigit matrix columns +if `"`vectorList'"'~="" { + foreach var in `vectorList' { + gen str12 `var'String = "" + } + + * autoformat all user-defined matrices + foreach name in `vectorList' { + autogen `name', replace(`name'String) auto(`auto') less(`less') fmt(`fmt') width(12) + } +} +if `"`nonvecList'"'~="" { + foreach var in `nonvecList' { + gen str12 `var'String = "" + } + + * autoformat all user-defined matrices + foreach name in `nonvecList' { + autogen `name', replace(`name'String) auto(`auto') less(`less') fmt(`fmt') width(12) + } +} + +replace asterString = astrix if astrix~="" + + +/* not effective b/c drop/keep done above, yet tstat is not define up there +*** set nocons if Constant row is empty +tempvar test1 test2 +gen `test1'=. +foreach var in `statsList' { + * capture 'cause might not exist + cap replace `test1'=1 if `var'~=. +} +gen `test2'=1 if `test1'==. & VarName=="_cons" +qui sum `test2', meanonly +if `r(N)'>0 { + local cons nocons +} +drop `test1' `test2' +*/ + + +*** decimals and formats (old) + +/* * parse bfmt + local fmttxt "e f g fc gc" + partxtl2 `"`bfmt'"' + local bfmtcnt = r(numtxt) + local b = 1 + while `b'<=`bfmtcnt' { + local bfmt`b' `r(txt`b')' + if index("`fmttxt'","`bfmt`b''")==0 { + di in red `"bfmt element "`bfmt`b''" is not a valid number format (f,fc,e,g or gc)"' + exit 198 + } + local b = `b'+1 + } + + *** fill in bdec(#) & bfmt(txt) + local b = 1 + while `b'<=_N { + local bdec`b' : word `b' of `bdec' + if "`bdec`b''"=="" { + local bdec`b' = `prvbdec' + } + local prvbdec "`bdec`b''" + local b = `b'+1 + } + * bfmt1 is already set above + local b = `bfmtcnt'+1 + while `b'<=_N { + local b_1 = `b'-1 + local bfmt`b' "`bfmt`b_1''" + local b = `b'+1 + } +*/ + +*** decimals and formats + +* originals +foreach thing in dec sdec bdec tdec pdec cdec rdec fmt sfmt bfmt tfmt pfmt cfmt rfmt { + local `thing'0 ``thing'' +} + +* decimlas +if "`dec'"=="" { + foreach stuff in dec sdec bdec tdec pdec cdec rdec { + if "``stuff''"=="" { + local `stuff' 3 + } + } +} +else { + foreach stuff in bdec sdec tdec pdec cdec rdec { + if "``stuff''"=="" { + local `stuff' `dec' + } + } +} + +* formats +if "`fmt'"=="" { + foreach stuff in fmt sfmt bfmt tfmt pfmt cfmt rfmt { + if "``stuff''"=="" { + local `stuff' fc + } + } +} +else { + foreach stuff in bfmt sfmt tfmt pfmt cfmt rfmt { + if "``stuff''"=="" { + local `stuff' `fmt' + } + } +} + + +* disable autofmt if dec or bdec given +if "`dec0'"~="" | "`bdec0'"~="" { + local noauto noauto +} + + +*** could possibly be empty +local N=_N +if `N'==0 { + set obs 1 +} + + + +*** for the (parenthesis) numbers + local N=_N + if "`tdec0'"=="" & "`noauto'"~="noauto" { + autogen tstatVal, replace(tstatString) auto(`auto') less(`less') fmt(`tfmt') width(12) + + + /* use autodigits + forval num=1/`N' { + autodigits2 tstatVal[`num'] `auto' `less' + replace tstatString = string(tstatVal,"%12.`r(valstr)'") in `num' + + *autofmt, input(`=tstatVal[`num']') auto(`auto') less(`less') + *replace tstatString = `"`r(output1)'"' in `num' + } + */ + } + else { + fmtgen tstatVal, replace(tstatString) dec(`tdec') fmt(`tfmt') width(12) + } + + if "`sdec0'"=="" & "`noauto'"~="noauto" { + autogen seVal, replace(seString) auto(`auto') less(`less') fmt(`sfmt') width(12) + autogen seEformVal, replace(seEformString) auto(`auto') less(`less') fmt(`sfmt') width(12) + } + else { + fmtgen seVal, replace(seString ) dec(`sdec') fmt(`sfmt') width(12) + fmtgen seEformVal, replace(seEformString ) dec(`sdec') fmt(`sfmt') width(12) + } + + if "`pdec0'"=="" & "`noauto'"~="noauto" { + autogen pvalVal, replace(pvalString) auto(`auto') less(`less') fmt(`pfmt') width(12) + } + else { + fmtgen pvalVal, replace(pvalString ) dec(`pdec') fmt(`pfmt') width(12) + } + + if "`cdec0'"=="" & "`noauto'"~="noauto" { + autogen ci_lowVal, replace(ci_lowString) auto(`auto') less(`less') fmt(`cfmt') width(12) + autogen ci_highVal, replace(ci_highString) auto(`auto') less(`less') fmt(`cfmt') width(12) + replace ciString = ci_lowString + " - " + ci_highString + + autogen ci_lowEformVal, replace(ci_lowEformString) auto(`auto') less(`less') fmt(`cfmt') width(12) + autogen ci_highEformVal, replace(ci_highEformString) auto(`auto') less(`less') fmt(`cfmt') width(12) + replace ciEformString = ci_lowEformString + " - " + ci_highEformString + } + else { + fmtgen ci_lowVal, replace(ci_lowString) dec(`cdec') fmt(`cfmt') width(12) + fmtgen ci_highVal, replace(ci_highString) dec(`cdec') fmt(`cfmt') width(12) + replace ciString = ci_lowString + " - " + ci_highString + + fmtgen ci_lowEformVal, replace(ci_lowEformString) dec(`cdec') fmt(`cfmt') width(12) + fmtgen ci_highEformVal, replace(ci_highEformString) dec(`cdec') fmt(`cfmt') width(12) + replace ciEformString = ci_lowEformString + " - " + ci_highEformString + } + + if "`beta'"=="beta" | "`betaAsked'"=="betaAsked" { + fmtgen betaVal, replace(betaString) dec(`cdec') fmt(`cfmt') width(12) + } + + *** prepare coefSring + if "`bdec0'"=="" & "`noauto'"~="noauto" { + autogen coefVal, replace(coefString) auto(`auto') less(`less') fmt(`bfmt') width(12) + autogen coefEformVal, replace(coefEformString) auto(`auto') less(`less') fmt(`bfmt') width(12) + + * beta here (with coef) + if "`beta'"=="beta" | "`betaAsked'"=="betaAsked" { + autogen betaVal, replace(betaString) auto(`auto') less(`less') fmt(`bfmt') width(12) + } + } + else { + fmtgen coefVal, replace(coefString) dec(`bdec') fmt(`bfmt') width(12) + fmtgen coefEformVal, replace(coefEformString) dec(`bdec') fmt(`bfmt') width(12) + + * beta here (with coef) + if "`beta'"=="beta" | "`betaAsked'"=="betaAsked" { + fmtgen betaEformVal, replace(betaString) dec(`bdec') fmt(`bfmt') width(12) + } + } + + +local N=_N +if `varMany'>0 & `varMany'<. & "`sumAsked'"~="" { + + *** digits and formats for sumAsked: + if "`dec0'"=="" & "`noauto'"~="noauto" { + foreach var in `sumList' { + autogen `var', replace(`var'String) auto(`auto') less(`less') fmt(`fmt') width(12) + } + else { + fmtgen `var', replace(`var'String) dec(`dec') fmt(`fmt') width(12) + } + } +} +foreach var in corr pwcorr spearman { + if `varMany'>0 & `varMany'<. & "``var'Asked'"~="" { + + *** digits and formats for stats( ) correlations: + if "`dec0'"=="" & "`noauto'"~="noauto" { + autogen `var', replace(`var'String) auto(`auto') less(`less') fmt(`fmt') width(12) + } + else { + fmtgen `var', replace(`var'String) dec(`dec') fmt(`fmt') width(12) + } + } +} +if `varMany'>0 & `varMany'<. { + foreach var in `cmdList' { + *** digits and formats for stats( ) cmd( ): + if "`dec0'"=="" & "`noauto'"~="noauto" { + autogen `var', replace(`var'String) auto(`auto') less(`less') fmt(`fmt') width(12) + } + else { + fmtgen `var', replace(`var'String) dec(`dec') fmt(`fmt') width(12) + } + } + foreach var in `strList' { + *** digits and formats for stats( ) str( ): + if "`dec0'"=="" & "`noauto'"~="noauto" { + autogen `var', replace(`var'String) auto(`auto') less(`less') fmt(`fmt') width(12) + } + else { + fmtgen `var', replace(`var'String) dec(`dec') fmt(`fmt') width(12) + } + } +} + + + + *** moved here from the main body + /* slap parenthesis for non-coef contents + if `"`bracketA'"'=="" & `"`bracket'"'=="" & `"`parenthesis'"'=="" & "`paren'"~="noparen" { + * blank at end + local statsList "`statsList' " + local parenthesis : subinstr local statsList "coef " "", all + local parenthesis : subinstr local parenthesis "coefEform " "", all + + * no parenthesis for blank row + local parenthesis : subinstr local parenthesis "blank " "", all + } + */ + + * slap parenthesis for non-blank, even rows (as in parity) + * this might be violated by -sideway- but -cap replace- prevents error + if `"`bracketA'"'=="" & `"`bracket'"'=="" & `"`parenthesis'"'=="" & "`paren'"~="noparen" { + gettoken one two: statsList + local odd 1 + while `"`two'"'~="" { + if `odd'==0 { + local parenthesis "`parenthesis' `one'" + local odd 1 + } + else { + local odd 0 + } + gettoken one two: two + } + if `odd'==0 { + local parenthesis "`parenthesis' `one'" + local odd 1 + } + else { + local odd 0 + } + } + +************ ad hoc fix +* take out Eform and put it back in +local parenthesis `"`parenthesis' "' +local parenthesis : subinstr local parenthesis "Eform " " ", all +local parenthesis =trim("`parenthesis'") + +if `"`paren'"'~="noparen" { + if `"`bracketA'"'=="" & `"`bracket'"'=="" & `"`parenthesis'"'=="" { + local parenthesis "se" + } + + if `"`parenthesis'"'~="" { + * other possible valid: level coef_eform se_eform coef_beta se_beta + * also added: seEform, etc + optionSyntax, valid(coef se tstat pval ci aster blank beta ci_low ci_high N sum_w mean Var /* + */ sd skewness kurtosis sum min max p1 p5 p10 p25 p50 p75 p90 p95 p99 corr pwcorr spearman `cmdList' `strList' ) /* + */ name(parenthesis) nameShow(paren:thesis( )) content(`parenthesis') passthru noreturn + local parenList `"`optionList'"' + local parenPerCoef `optionCount' + } + + * update when eform specified + if "`eform'"=="eform" { + local parenList "`parenList' " + * may be redundant + local parenList : subinstr local parenList "coef " "coefEform ", all + local parenList : subinstr local parenList "ci " "ciEform ", all + local parenList : subinstr local parenList "se " "seEform ", all + + local parenList : subinstr local parenList "ci_high " "ci_highEform ", all + local parenList : subinstr local parenList "ci_low " "ci_lowEform ", all + } + + if `"`bracketA'"'~="" { + *** bracketA( ) option cleanup + * other possible valid: level coef_eform se_eform coef_beta se_beta + optionSyntax, valid(coef se tstat pval ci aster blank beta ci_low ci_high N sum_w mean Var /* + */ sd skewness kurtosis sum min max p1 p5 p10 p25 p50 p75 p90 p95 p99 corr pwcorr spearman `cmdList' `strList' ) /* + */ name(bracketA) nameShow(br:acket( )) content(`bracketA') passthru noreturn + local bracketList `"`optionList'"' + local bracketPerCoef `optionCount' + } + + * update when eform specified + if "`eform'"=="eform" { + local bracketList "`bracketList' " + * may be redundant + local bracketList : subinstr local bracketList "coef " "coefEform ", all + local bracketList : subinstr local bracketList "ci " "ciEform ", all + local bracketList : subinstr local bracketList "se " "seEform ", all + } + + if "`bracket'"=="bracket" & "`parenthesis'"=="" { + replace tstatString = "[" + tstatString + "]" if tstatString ~="" + replace pvalString = "[" + pvalString + "]" if pvalString ~="" + replace ciString = "[" + ciString + "]" if ciString ~="" + replace ciEformString = "[" + ciEformString + "]" if ciEformString ~="" + + replace ci_lowString = "[" + ci_lowString + "]" if ci_lowString ~="" + replace ci_highString = "[" + ci_highString + "]" if ci_highString ~="" + replace ci_lowEformString = "[" + ci_lowEformString + "]" if ci_lowEformString ~="" + replace ci_highEformString = "[" + ci_highEformString + "]" if ci_highEformString ~="" + + replace betaString= "[" + betaString+ "]" if betaString ~="" + replace seString = "[" + seString + "]" if seString ~="" + replace seEformString = "[" + seEformString + "]" if seEformString ~="" + replace betaString= "[" + betaString+ "]" if betaString ~="" + } + else if "`bracket'"=="bracket" & "`parenthesis'"~="" { + local num 1 + while `num'<=`parenPerCoef' { + local temp : word `num' of `parenList' + replace `temp'String = "[" + `temp'String + "]" if `temp'String ~="" + local num=`num'+1 + } + } + else { + if "`parenthesis'"~="" { + local num 1 + while `num'<=`parenPerCoef' { + local temp : word `num' of `parenList' + cap replace `temp'String = "(" + `temp'String + ")" if `temp'String ~="" + local num=`num'+1 + } + } + if "`bracketA'"~="" { + local num 1 + while `num'<=`bracketPerCoef' { + local temp : word `num' of `bracketList' + cap replace `temp'String = "[" + `temp'String + "]" if `temp'String ~="" + local num=`num'+1 + } + } + } +} /* if `"`paren'"'~="noparen" */ + + + +* when no coefficient/cons are present (prevent subid from going undefined) +local N=_N +if `N'==0 { + set obs 1 +} + +gen id=_n +expand `statsMany' +bys id: gen subid=_n + +*replace nameCol = " " if subid~=1 /* no variable names next to tstats */ +replace nameCol = "" if subid~=1 /* no variable names next to tstats */ + + /* a little more complicated, not use optionSyntax + if `"`asterisk'"'~="" { + *** asterisk( ) option cleanup + * other possible valid: level coef_eform se_eform coef_beta se_beta + optionSyntax, valid(coef se tstat pval ci blank beta ci_low ci_high) /* + */ name(asterisk) nameShow(aster:isk( )) content(`asterisk') passthru noreturn + local asterList `"`optionList'"' + local asterPerCoef `optionCount' + } + */ + + if `"`asterisk'"'~="" { + + *** asterisk( ) option cleanup + local asterValid "coef se tstat pval ci blank beta ci_low ci_high" + * no aster here + * level coef_eform se_eform coef_beta se_beta" + + * take comma out + local asterisk : subinstr local asterisk "asterisk(" " ", all + local asterisk : subinstr local asterisk ")" " ", all + local asterisk : subinstr local asterisk "," " ", all + + local asterPerCoef : word count `asterisk' + local num=1 + local asterList "" + + while `num'<=`asterPerCoef' { + local aster`num' : word `num' of `asterisk' + + * it must be one of the list + local test 0 + foreach var in `asterValid' { + if "`var'"=="`aster`num''" & `test'==0 { + local test 1 + } + } + if `test'==0 { + noi di in red "{opt `aster`num''} is neither a valid option or matrix for {opt aster:isk( )}" + exit 198 + } + local asterList "`asterList' `aster`num''" + local num=`num'+1 + } + } + + * update when eform specified + if "`eform'"=="eform" { + local asterList "`asterList' " + local asterList : subinstr local asterList "coef " "coefEform ", all + local asterList : subinstr local asterList "ci " "ciEform ", all + local asterList : subinstr local asterList "se " "seEform ", all + + local asterList : subinstr local asterList "ci_high " "ci_highEform ", all + local asterList : subinstr local asterList "ci_low " "ci_lowEform ", all + } + + *** combining them into one column + + if "`asterisk'" == "" { + forval num=1/`statsMany' { + local var : word `num' of `statsList' + replace reportCol=`var'String if subid==`num' + + * attach asterString + replace reportCol=`var'String + asterString if subid==`num' & ("`var'"=="coef" | "`var'"=="coefEform") + } + } + else { + forval num=1/`statsMany' { + local var : word `num' of `statsList' + replace reportCol=`var'String if subid==`num' + + * attach asterString + forval nn=1/`asterPerCoef' { + replace reportCol=`var'String + asterString if subid==`num' & ("`var'"=="`aster`nn''" | "`var'"=="`aster`nn''Eform") + } + } + } + +* drops vector/matrices as well: +keep nameCol eqName VarName mrgrow reportCol + +local num=mrgrow[1]-2 +replace mrgrow=`num'+_n + +* first find number of new rows for addstat() +if `"`addstat'"'!="" { + partxtl3 `"`addstat'"' + local naddst = int((real(r(numtxt))+1)/2) + + local n = 1 + while `n'<=`naddst' { + local t = (`n'-1)*2+1 + local astnam`n' `r(txt`t')' + local t = `t'+1 + local astval`n' `r(txt`t')' /* pair: stat name & value */ + local n = `n'+1 + } +} +else { + local naddst=0 +} + +* find number of new rows for addnote() +if (`"`addnote'"'!="" & "`append'"!="append") | (`"`addnote'"'!="" & `fileExist'==0) { + partxtl2 `"`addnote'"' + local naddnt = r(numtxt) + local n = 1 + while `n'<=`naddnt' { + local anote`n' `r(txt`n')' + local n = `n'+1 + } +} +else { + local naddnt=0 +} + +* calculate total number of rows in table +* added a second extra line above the coefficients: place 2 of 2 +*local coefrow = 2*`brows'+1+`appottl' + 1 +local coefrow = `statsMany'*`brows'+1+`appottl' + 1 +*local totrows = `coefrow' + ("`nobs'"!="nonobs") + (`numi'!=.) + ("`r2'"!="nor2"&`rsq'!=.&`df_r'!=.) + `naddst' + ("`notes'"!="nonotes"&"`append'"!="append")*(1+("`aster'"!="noaster")) + `naddnt' +local totrows = 2 + 20 + `coefrow' + ("`nobs'"!="nonobs") + (`numi'!=.) + ("`r2'"!="nor2") + `naddst' + ("`notes'"!="nonotes"&"`append'"!="append")*(1+("`aster'"!="noaster")) + `naddnt' + ("`notes'"!="nonotes" & `fileExist'==0)*(1+("`aster'"!="noaster")) +* 2 added for the top and bottom row (empty), 20 added for the heck of it +* totrows calculation is apparently no longer accurate when no file exists; merely drop the extra row at the end + +* cap here because could be lower due to drop/nocons +cap set obs `totrows' + +* insert the top row (empty), rowtype2==0 +local N=_N +set obs `=`N'+1' +local N=_N +replace mrgrow = 1 in `N' + +gen rowtype2=0 in `N' + +local N=_N + +*** always add the head column numbers +if "`append'"=="append" & `fileExist'==1 { + replace mrgrow = 0.001 in `=`N'-2' + replace reportCol = "(1)" in `=`N'-2' +} +else { + replace mrgrow = 0.001 in `=`N'-2' + replace reportCol = "(1)" in `=`N'-2' + * add one back to make up for it + local coefrow = `coefrow'+1 +} + +local coefrow = `coefrow'-1 + +* there must be at least one ctitleList +if `"`ctitleList'"'=="" { + local ctitleList " " +} + + + +*** ad hoc fix for ctitleList, which is assigned by the main program from stats( ) contents +* ctitleList needs to fixed for -sideway- and str( ) or cmd( ) invoked +if "`cmd1'"=="`ctitleList'" & "`statsMany'"=="1" { + local ctitleList `"`reg1'"' +} +if "`string1'"=="`ctitleList'" & "`statsMany'"=="1" { + local ctitleList "string" +} + + + + +* parsing ctitleList contents (2 of 2), counts the first and the last comma and the consecutive commas +local rest `"`ctitleList'"' +local count 0 +while `"`rest'"'~="" { + gettoken first rest: rest, parse(",") + if `"`first'"'=="," & `count'==0 { + local count=`count'+1 + local txt`count' + } + if `"`first'"'~="," { + local count=`count'+1 + local txt`count' `"`first'"' + } + if `"`first'"'=="," & `"`previous'"'=="," { + local count=`count'+1 + local txt`count' + } + local previous `"`first'"' +} +if `"`first'"'=="," & `count'~=0 { + local count=`count'+1 + local txt`count' +} + +local numtxt `count' + +* adding more rows for ctitles +if `numtxt'>0 { + set obs `=`N'+`numtxt'' + local N=_N + forval num=1/`numtxt' { + replace mrgrow = `num'/100 in `=`N'-`num'+1' + + * insert ctitles + replace reportCol=`"`txt`num''"' in `=`N'-`num'+1' + + replace rowtype2=-1 in `=`N'-`num'+1' + local coefrow = `coefrow'+1 + } +} + +sort mrgrow +replace mrgrow = _n + +* the bottom row (empty), rowtype2==2 +local coefrow = `coefrow'+1 + +replace rowtype2=-1 if rowtype2[_n+1]==0 | rowtype2[_n+1]==-1 + +replace rowtype2=1 if _n<`coefrow' & rowtype2==. +replace rowtype2=2 if _n==`coefrow' +replace rowtype2=3 if _n>`coefrow' + + +* only if it's not sideway runons +if `sidewayWave'==1 { + + * number of observations + if "`obs'"!="noobs" { + local coefrow = `coefrow'+1 + replace nameCol = "Observations" if _n==`coefrow' + replace reportCol = string(`regN') if _n==`coefrow' + } + + if (`numi'!=. & "`ni'"!="noni") { + local coefrow = `coefrow'+1 + replace nameCol = "Number of " + rtrim(`"`iname'"') if _n==`coefrow' + replace reportCol = string(`numi') if _n==`coefrow' + } + + * scalar crap, no rsq if it's a dot + if "`r2'"~="nor2" { + if `=`rsq''==. { + local r2 "nor2" + } + } + + if "`r2'"!="nor2" { + /* if df_r=., not true r2 */ + local coefrow = `coefrow'+1 + replace reportCol = string(`rsq',"%12.`rdec'`rfmt'") if _n==`coefrow' + replace nameCol = "R-squared" if _n==`coefrow' + if "`adjr2'"=="adjr2" { + replace nameCol = "Adjusted " + nameCol if _n==`coefrow' + } + } + + *** addtext here + if `"`addtext'"'!="" { + partxtl2 `"`addtext'"' + local temp = int((real(r(numtxt))+1)/2) + + local n = 1 + while `n'<=`temp' { + local t = (`n'-1)*2+1 + local textName`n' `r(txt`t')' + local t = `t'+1 + local textValue`n' `r(txt`t')' /* pair: stat name & value */ + local n = `n'+1 + } + + local i 1 + while `i'<=`temp' { + * increase + local coefrow = `coefrow'+1 + local N=_N + set obs `=`N'+1' + + if `"`textValue`i''"'!="" { + replace reportCol = "`textValue`i''" if _n==`coefrow' + } + replace nameCol = trim(`"`textName`i''"') if _n==`coefrow' + local i = `i'+1 + } + + * cleanup counting + replace mrgrow=_n + } + + *** addstat here + if `"`addstat'"'!="" { + local i 1 + local adeccnt : word count `adec' + while `i'<=`naddst' { + local coefrow = `coefrow'+1 + local aadec : word `i' of `adec' + if "`aadec'"=="" { + local aadec `prvadec' + } + if `"`astval`i''"'!="" { + replace reportCol = "`astval`i''" if _n==`coefrow' + } + replace nameCol = trim(`"`astnam`i''"') if _n==`coefrow' + local i = `i'+1 + local prvadec `aadec' + } + } +} + +local parenList=trim(`"`parenList'"') + +if ("`notes'"!="nonotes" & "`append'"!="append") | ("`notes'"!="nonotes" & `fileExist'==0) { + if "`bracket'"=="bracket" | "`bracketA'" ~= "" { + local par_bra "brackets" + } + else { + local par_bra "parentheses" + } + + * notes + if "`statsList'"=="coef pval" { + local statxt "p-values" + } + else if "`statsList'"=="coef se" { + local statxt "Standard errors" + } + else if "`statsList'"=="coef pi" { + local statxt "`level'% confidence intervals" + } + else if "`beta'"=="beta" { + local statxt "Normalized beta coefficients" + } + else if "`parenList'"=="se" { + local statxt "Standard errors" + } + else if "`parenList'"=="tstat" { + if `df_r'!=. { + local t_or_z "t" + } + else { + local t_or_z "z" + } + local statxt "`t_or_z'-statistics" + } + + if "`robust'"=="Robust" { + local statxt = "Robust " + lower("`statxt'") + } + + * actually inserting + if ("`parenList'"~="" | "`bracketList'"~="" ) & "`statsList'"~="coef" { + if `"`paren'"'~="noparen" { + local coefrow = `coefrow'+1 + replace nameCol = "`statxt' in `par_bra'" if _n==`coefrow' + } + } + if "`aster'"!="noaster" { + local coefrow = `coefrow'+1 + replace nameCol = "`astrtxt'" if _n==`coefrow' + } +} + +if (`"`addnote'"'!="" & "`append'"!="append") | (`"`addnote'"'!="" & `fileExist'==0) { + local i 1 + while `i'<=`naddnt' { + local coefrow = `coefrow'+1 + replace nameCol = `"`anote`i''"' if _n==`coefrow' + local i = `i'+1 + } +} + +* attach the column name +replace nameCol=`"`VARIABLES'"' if rowtype2[_n+1]==0 +replace nameCol=`"`VARIABLES'"' if rowtype2==0 & nameCol[_n-1]~=`"`VARIABLES'"' + + +*** drop the extra rows at the end, if still exist, unless it is the bottom row +local N=_N +local temp=nameCol[`N'] +local check=rowtype2[`N'] +while "`temp'"=="" & `check'>2 { + drop in `N' + local N=_N + local temp=nameCol[`N'] + local check=rowtype2[`N'] +} + + +*** handle equationsA(auto) +if "`equationsOption'"=="auto" { + + *******************************cap set unabbr off + local N=_N + forval num=1/`N' { + local temp=eqName[`num'] + if "`temp'"~="" { + * check if this variable exists + cap sum `temp', meanonly + if _rc~=0 { + count if eqName=="`temp'" + local thisMany=r(N)/`statsMany' + if `thisMany'>1 & `thisMany'<. { + replace nameCol ="Constant" if eqName=="`temp'" & VarName=="_cons" & nameCol~="" + replace nameCol =VarName if eqName=="`temp'" & VarName~="_cons" & nameCol~="" + replace eqName="" if eqName=="`temp'" + } + else { + replace nameCol =eqName if eqName=="`temp'" & VarName=="_cons" & nameCol~="" + replace eqName="" if eqName=="`temp'" + } + } + } + } +} + +end /* makeFile */ + + +******************************************************************************************** + + +program define seeing + versionSet + version `version' + +quietly { + + * syntax using/[, Clear] + syntax using [, LABel LABelA(string) ] + + preserve + + insheet `using', nonames clear + describe, short + + + * number of columns + local numcol = `r(k)' + + tempvar blanks rowmiss + count if v1=="EQUATION" + if `r(N)'~=0 { + local eqPlace 1 + local varPlace 2 + count if v3=="LABELS" + if `r(N)'~=0 { + local labPlace 3 + local num=4 + } + else { + local labPlace 0 + local num=3 + } + } + else { + local eqPlace 0 + local varPlace 1 + + count if v2=="LABELS" + if `r(N)'~=0 { + local labPlace 2 + local num=3 + } + else { + local labPlace 0 + local num=2 + } + } + + gen int `blanks' = (trim(v`num')=="") + forvalues col = `num'/`numcol' { + replace `blanks' = `blanks' & (trim(v`col')=="") + } + + + * title rows + local titleWide = 0 + if v1[1]~="" | v2[1]~="" { + * there may be a title + if `labPlace'==0 & `varPlace'==1 { + while v1[`=`titleWide'+1']~="" & v2[`=`titleWide'+1']=="" { + local titleWide = `titleWide'+1 + } + } + if `labPlace'==0 & `varPlace'==2 { + while v2[`=`titleWide'+1']~="" & v3[`=`titleWide'+1']=="" { + local titleWide = `titleWide'+1 + } + } + if `labPlace'~=0 & `varPlace'==1 { + while v1[`=`titleWide'+1']~="" & v3[`=`titleWide'+1']=="" { + local titleWide = `titleWide'+1 + } + } + if `labPlace'~=0 & `varPlace'==2 { + while v2[`=`titleWide'+1']~="" & v4[`=`titleWide'+1']=="" { + local titleWide = `titleWide'+1 + } + } + } + + *local VARIABLES "VARIABLES" + * first name AFTER titles is the VARIABLES + local content + local num=`titleWide'+1 + local N=_N + while `"`content'"'=="" & `num'<=`N' { + local content=v`varPlace'[`num'] + local num=`num'+1 + } + local VARIABLES `"`content'"' + + replace `blanks'=0 if v1==`"`VARIABLES'"' | v1[_n-1]==`"`VARIABLES'"' | v2==`"`VARIABLES'"' | v2[_n-1]==`"`VARIABLES'"' + + + * getting bottomBorder (the bottom border), count up + gen rowmiss=0 + foreach var of varlist v* { + replace rowmiss=rowmiss+1 if `var'~="" + } + local N=_N + local content 1 + local num 0 + while `content'==1 & `num'<`N' { + local content rowmiss[`=`N'-`num''] + local num=`num'+1 + } + * do not have to add to titleWide + local bottomRow = `N'-`num'+1 + local bottomBorder=`bottomRow' + + * getting halfway to headBorder (the top border), count down + local content + local num=`titleWide'+1 + local N=_N + while `"`content'"'=="" & `num'<=`N' { + local content=v`varPlace'[`num'] + local num=`num'+1 + } + * do not have to add to titleWide + local headRow `num' + local headBorder=`headRow' + + drop rowmiss + + + * avoid counting space within each statistics row as missing + replace `blanks'=0 if `blanks'[_n+1]==0 & `blanks'==1 & _n >`titleWide' + + + * statistics rows + *count if `blanks'==0 + *local bottomBorder = `r(N)'+`titleWide' + + + * move the notes and titles to the top of a new column + gen str5 Notes_Titles="" + format Notes_Titles %-20s + count if v1=="EQUATION" + if `r(N)'==0 { + * EQUATION column does not exist + if `titleWide'>0 { + forval num=1/`titleWide' { + replace Notes_Titles=v1[`num'] in `num' + replace v1="" in `num' + } + } + + local one = 1 + local legend = v1[`bottomBorder'+`one'] + + + local place 1 + *while "`legend'"~="" { + local N=_N + while `place' <= `N' { + local place=`bottomBorder'+`one' + local legend = v1[`place'] + replace Notes_Titles="`legend'" in `=`one'+`titleWide'+1' + if "`legend'"~="" { + replace v1="" in `place' + } + local one = `one'+1 + } + + * insert label changes here, minus 2 from c(k) for `blanks' & Notes_Titles column + if "`label'"=="label" { + *if ("`long'"~="long" & "`onecol'"~="onecol") | ("`long'"=="long" & "`onecol'"=="onecol") { + replace v2=v1 if v2=="" + drop v1 + describe, short + forval num=1/`=`r(k)'-2' { + ren v`=`num'+1' v`num' + } + + * change LABELS to VARIABLES + replace v1=`"`VARIABLES'"' if v1=="LABELS" + *} + local label_adjust "-1" + } + + * change the string length + gen str5 temp="" + replace temp=v1 + drop v1 + ren temp v1 + order v1 + * format + foreach var of varlist v1 { + local _format= "`: format `var''" + local _widths=substr("`_format'",2,length(trim("`_format'"))-2) + format `var' %-`_widths's + } + } + else { + * equation column exists + if `titleWide'>0 { + forval num=1/`titleWide' { + replace Notes_Titles=v2[`num'] in `num' + replace v2="" in `num' + } + } + + local one = 1 + local legend = v2[`bottomBorder'+`one'] + while "`legend'"~="" { + local place=`bottomBorder'+`one' + local legend = v2[`place'] + replace Notes_Titles="`legend'" in `=`one'+`titleWide'+1' + if "`legend'"~="" { + replace v2="" in `place' + } + local one = `one'+1 + } + + * insert label changes here, minus 2 from c(k) for `blanks' & Notes_Titles column + if "`label'"=="label" { + *else if "`long'"~="long" & "`onecol'"=="onecol" { + replace v3=v2 if v3=="" + drop v2 + describe, short + forval num=2/`=`r(k)'-2' { + ren v`=`num'+1' v`num' + } + + * change LABELS to VARIABLES + replace v2=`"`VARIABLES'"' if v2=="LABELS" + *} + local label_adjust "-1" + } + + + * change the string length + gen str5 temp="" + replace temp=v2 + drop v2 + ren temp v2 + order v1 v2 + * format + foreach var of varlist v1 v2 { + local _format= "`: format `var''" + local _widths=substr("`_format'",2,length(trim("`_format'"))-2) + format `var' %-`_widths's + } + } + + * clean up + *egen `rowmiss'=rowmiss(_all) + * rowmiss option not available in 8.2 or 8.0, do it by hand + + gen `rowmiss'=0 + foreach var of varlist _all { + if "`var'"~="`rowmiss'" & "`var'"~="`blanks'" { + replace `rowmiss'=1+`rowmiss' if `var'=="" + } + } + + *drop if `rowmiss'==`numcol'+1 + + * adjust to handle label column droppings + *drop if `rowmiss'==`numcol'+1 & `blanks'==1 + + * fix blanks==1 for groupvar( ) + count if `blanks'==1 + local rN=`r(N)'+1 + forval num=1/`rN' { + replace `blanks'=0 if `blanks'[_n+1]==0 & `blanks'==1 + } + + drop if `rowmiss'==`numcol'+1 `label_adjust' & `blanks'==1 + drop `blanks' `rowmiss' + + browse + + if "`Version7'"=="" { + * it is version 7 + } + else if `Version7'>=11.0 { + noi di in yel "Hit Enter to continue" _request(junk) + } + + *restore, preserve +} +end /* end of seeing */ + + +******************************************************************************************** + + +* 02nov2009 to handle strings +prog define fmtgen + + syntax [varlist(default=none)] [in], replace(str asis) fmt(str asis) [dec(int 3) auto(int 3) less(int 0) width(int 12) gen(str asis) ] +if "`varlist'"~="" { + local varname `varlist' + replace `replace' = string(`varname',"%12.`dec'`fmt'") `in' +} +end + + +******************************************************************************************** + + +* 02nov2009 to handle strings and variables in addition to numbers +* 09nov2009 also accomodates various user-specified formats, including e +prog define autogen + versionSet + version `version' + + syntax [varlist(default=none)] [in], replace(str asis) [dec(int 3) fmt(str asis) auto(int 3) less(int 0) width(int 12) gen(str asis)] + +if "`fmt'"=="" { + local fmt f +} + +if "`varlist'"~="" { + local varname `varlist' + + if "`in'"~="" { + gettoken junk begin: in, parse(" ") + gettoken begin end: begin, parse("/") + gettoken slash end: end, parse("/") + } + else { + local begin 1 + local end=_N + } + + cap confirm numeric var `varname' + + if _rc==0 { + tempvar whole times left aadec aadecString valstr format + *gen `whole'=1 if round((`varname' - int(`varname')),0.0000000001)==0 + *gen `whole'=1 if float(`varname') - int(`varname')==0 + gen `whole'=1 if round(`varname' - int(round(`varname',0.0000000001)),0.0000000001)==0 + replace `whole'=0 if `whole'==. + + * digits that need to be moved if it were only decimals: take the ceiling of log 10 of absolute value of decimals + gen `times'=abs(int(ln(abs(`varname'-int(`varname')))/ln(10)-1)) if `whole'==0 + + * the whole number: take the ceiling of log 10 of absolute value + gen `left'=int(ln(abs(`varname'))/ln(10)+1) if `whole'==0 + + * assign the fixed decimal values into aadec + gen `aadec'=0 if `whole'==1 + + * reduce the left by one if more than zero to accept one extra digit + replace `aadec'=`auto'-`left'+1 if .>`left' & `left'>0 & `left'<=`auto' & `whole'==0 + replace `aadec'=`auto'-`left'-1 if .>`left' & `left'>0 & `left'>`auto' & `whole'==0 + + * else + replace `aadec'=`times'+`auto'-1 if (.<=`left' | `left'<=0) & `whole'==0 + + * needs to between 0 and 11 + replace `aadec'=`aadec'-`less' + replace `aadec'=0 if `aadec'<0 + + gen str12 `aadecString'=string(`aadec') + gen str12 `valstr'="" + + replace `valstr'=`aadecString'+"`fmt'" if `aadec'<7 & `aadec'~=. + if "`fmt'"=="e" { + replace `valstr'="`=`auto'-0'e" + } + + replace `valstr'="`=`auto'-1'e" if `aadec'>=7 & `aadec'~=. + + * make it exponential if too big or too negative (small) + replace `valstr' = "`=`auto'+0'e" if `varname'>1000000 & `varname'<. + replace `valstr' = "`=`auto'+0'e" if `varname'<-1000000 & `varname'<. + + gen str12 `format'= "%`width'." + `valstr' if `valstr'~="" + + forval num=`begin'/`end' { + local content=`format'[`num'] + replace `replace' = string(`varname',"`content'") in `num' + } + } + else { + * string variable, do it old-fashioned way + replace `replace'=`varname' + forval num=`begin'/`end' { + capture confirm number `=`varname'[`num']' + if _rc==0 { + autofmt, input(`=`varname'[`num']') dec(`auto') less(`less') + if "`=`varname'[`num']'"~="" { + replace `replace' = string(`=`varname'[`num']',"%`width'.`r(deci1)'`fmt'") if _n==`num' & "`r(deci1)'"~="." + } + /* + autodigits2 `=`varname'[`num']' `auto' `less' + if "`=`varname'[`num']'"~="" { + replace `replace' = string(`=`varname'[`num']',"%`width'.`r(valstr)'") if _n==`num' & "`r(valstr)'"~="." + } + */ + *autodigits2 tstatVal[`num'] `auto' `less' + *replace tstatString = string(tstatVal,"%12.`r(valstr)'") in `num' + } + } + } +} +else { + * not a variable + +} +end + + +******************************************************************************************** + + +* 03nov2009 integer check upgraded to handle more indeterminancy coming from string numerals +program define autodigits2, rclass + versionSet + version `version' + +* getting the significant digits +args input auto less + +if `input'~=. { + local times=0 + local left=0 + + * integer checked by modified mod function + *if round((`input' - int(`input')),0.0000000001)==0 { + if round(`input' - int(round(`input',0.0000000001)),0.0000000001)==0 { + local whole=1 + } + else { + local whole=0 + * non-interger + if `input'<. { + + * digits that need to be moved if it were only decimals: take the ceiling of log 10 of absolute value of decimals + local times=abs(int(ln(abs(`input'-int(`input')))/ln(10)-1)) + + * the whole number: take the ceiling of log 10 of absolute value + local left=int(ln(abs(`input'))/ln(10)+1) + } + } + + + * assign the fixed decimal values into aadec + if `whole'==1 { + local aadec=0 + } + else if .>`left' & `left'>0 { + * reduce the left by one if more than zero to accept one extra digit + if `left'<=`auto' { + local aadec=`auto'-`left'+1 + } + else { + local aadec=0 + } + } + else { + local aadec=`times'+`auto'-1 + } + + if "`less'"=="" { + * needs to between 0 and 11 + if `aadec'<0 { + local aadec=0 + } + *if `aadec'<11 { + if `aadec'<7 { + * use fixed + local valstr "`aadec'f" + } + else { + * use exponential + local valstr "`=`auto'-1'e" + } + } + else { + * needs to between 0 and 11 + local aadec=`aadec'-`less' + if `aadec'<0 { + local aadec=0 + } + *if `aadec'<10 { + if `aadec'<7 { + * use fixed + local valstr "`aadec'f" + } + else { + * use exponential + local valstr "`=`auto'-1'e" + } + } + + * make it exponential if too big + if `input'>1000000 & `input'<. { + local valstr "`=`auto'-0'e" + } + + * make it exponential if too negative (small) + if `input'<-1000000 & `input'<. { + local valstr "`=`auto'-0'e" + } + + return scalar value=`aadec' + return local valstr="`valstr'" +} +else { + * it is a missing value + return scalar value=. + return local valstr="missing" +} +end + + +******************************************************************************************** + +* ripped from autofmt on 09nov2009 +* autofmt 1.0.1 03nov2009 roywada@hotmail.com +* automatic formating of a significant number of digits + +program define autofmt, rclass +version 7.0 + +syntax, input(string) [dec(integer 3) less(integer 0) parse(string) strict] +* parse( ) takes only one character; " " is always included as a parse + +if `"`parse'"'=="" { + local parse " " +} + +local rest `"`input'"' +local count 0 + +if "`rest'"~="" { + * handles the possibility the first token is empty + gettoken first rest: rest, parse("`parse'") + local first=trim(`"`first'"') + if `"`first'"'==`"`parse'"' { + local count=`count'+1 + local input`count' "" + } + else { + local count=`count'+1 + local input`count' `"`first'"' + } +} +while "`rest'"~="" { + gettoken first rest: rest, parse("`parse'") + local first=trim(`"`first'"') + if `"`first'"'~=`"`parse'"' { + local count=`count'+1 + local input`count' `"`first'"' + } +} + +if `count'==0 { + * input( ) was left empty + exit +} + +if "`strict'"=="strict" { + local one 0 +} +else { + local one 1 +} + + +*** run as many times + +forval num=1/`count' { + + * confirm a number + capture confirm number `input`num'' + local rc=_rc + + * run if not missing and is a number + if "`input`num''"~="." & "`input`num''"~="" & `rc'==0 { + local times=0 + local left=0 + + * integer checked by modified mod function + *if round((`input`num'' - int(`input`num'')),0.0000000001)==0 { + if round(`input' - int(round(`input',0.0000000001)),0.0000000001)==0 { + local whole=1 + } + else { + local whole=0 + * non-interger + if `input`num''<. { + + * digits that need to be moved if it were only decimals: take the ceiling of log 10 of absolute value of decimals + local times=abs(int(ln(abs(`input`num''-int(`input`num'')))/ln(10)-1)) + + * the whole number: take the ceiling of log 10 of absolute value + local left=int(ln(abs(`input`num''))/ln(10)+1) + } + } + + + * assign the fixed decimal values into aadec + if `whole'==1 { + local aadec=0 + } + else if .>`left' & `left'>0 { + * reduce the left by one if more than zero to accept one extra digit + if `left'<=`dec' { + local aadec=`dec'-`left'+`one' + } + else { + local aadec=0 + } + } + else { + local aadec=`times'+`dec'-1 + } + + if "`less'"=="" { + * needs to between 0 and 11 + if `aadec'<0 { + local aadec=0 + } + *if `aadec'<11 { + if `aadec'<7 { + * use fixed + local fmt "`aadec'f" + } + else { + * use exponential + local fmt "`=`dec'-1'e" + } + } + else { + * needs to between 0 and 11 + local aadec=`aadec'-`less' + if `aadec'<0 { + local aadec=0 + } + *if `aadec'<10 { + if `aadec'<7 { + * use fixed + local fmt "`aadec'f" + } + else { + * use exponential + local fmt "`=`dec'-1'e" + } + } + + * make it exponential if too big + if `input`num''>1000000 & `input`num''<. { + local fmt "`=`dec'-0'e" + } + + * make it exponential if too negative (small) + if `input`num''<-1000000 & `input`num''<. { + local fmt "`=`dec'-0'e" + } + + local fmt`num' `fmt' + local aadec`num' `aadec' + + local output`num'=string(`input`num'',"%12.`fmt'") + + return scalar deci`num'=`aadec' + return local fmt`num'="`fmt'" + return local input`num'="`input`num''" + + return local output`num'=`"`output`num''"' + + } + else { + * it is a missing value, empty, or non-number + local output`num'=trim(`"`input`num''"') + + return scalar deci`num'=. + return local fmt`num'="." + if "`input`num''"=="" { + * return a dot when empty + return local input`num'="." + } + else { + return local input`num'="`input`num''" + } + + return local output`num'=`"`output`num''"' + + } +} +end + + +******************************************************************************************** + + +program define _texout, sortpreserve +* based on out2tex version 0.9 4oct01 by john_gallup@alum.swarthmore.edu + versionSet + version `version' + + * add one if only one v* column exists + unab list: v* + local count: word count `list' + if `count'==1 { + gen str v2="" + order v* + } + if `count'==0 { + exit + } + + syntax varlist using/, titleWide(int) headBorder(int) bottomBorder(int) /* + */ [texFile(string) TOtrows(int 0) Landscape Fragment NOPRetty PRetty /* + */ Fontsize(numlist integer max=1 >=10 <=12) noBorder Cellborder /* + */ Appendpage noPAgenum a4 a5 b5 LETter LEGal EXecutive replace ] + if `totrows'==0 { + local totrows = _N + } + local numcols : word count `varlist' + gettoken varname statvars : varlist + local fast 1 + + if "`pretty'"=="pretty" { + local pretty "" + } + else { + local pretty "NOT PRETTY AT ALL" + } + + local colhead1 = `titleWide' + 1 + local strow1 = `headBorder' + 1 + + * insert $<$ to be handled in LaTeX conversion + local N=_N + forval num=`bottomBorder'/`N' { + local temp=v1[`num'] + tokenize `"`temp'"', parse (" <") + local count 1 + local newTex "" + local noSpace 0 + while `"``count''"'~="" { + if `"``count''"'=="<" { + local `count' "$<$" + local newTex `"`newTex'``count''"' + local noSpace 1 + } + else { + if `noSpace'~=1 { + local newTex `"`newTex' ``count''"' + } + else { + local newTex `"`newTex'``count''"' + local noSpace 0 + } + } + local count=`count'+1 + } + replace v1=`"`newTex'"' in `num' + } + + *** replace if equation column present + count if v1=="EQUATION" + if `r(N)'~=0 { + tempvar myvar + * use v2 instead + replace v1 = v2 in `=`bottomBorder'+1'/`totrows' + replace v2 = "" in `=`bottomBorder'+1'/`totrows' + + * change the string length + gen str5 `myvar' ="" + replace `myvar' =v2 + drop v2 + ren `myvar' v2 + order v1 v2 + } + + /* if file extension specified in `"`using'"', replace it with ".tex" for output + local next_dot = index(`"`using'"', ".") + if `next_dot' { + local using = substr("`using'",1,`=`next_dot'-1') + } + */ + + if `"`texFile'"'=="" { + local endName "tex" + } + else { + local endName "`texFile'" + } + + local using `"using "`using'.`endName'""' + local fsize = ("`fontsize'" != "") + if `fsize' { + local fontsize "`fontsize'pt" + } + local lscp = ("`landscape'" != "") + if (`lscp' & `fsize') { + local landscape ",landscape" + } + local pretty = ("`pretty'" == "") + local cborder = ("`cellborder'" != "") + local noborder = ("`border'" != "") + local nopagen = ("`pagenum'" != "") + local nofrag = ("`fragment'" == "") + + if `cborder' & `noborder' { + di in red "may not specify both cellborder and noborder options" + exit 198 + } + + local nopt : word count `a4' `a5' `b5' `letter' `legal' `executive' + if `nopt' > 1 { + di in red "choose only one of a4, a5, b5, letter, legal, executive" + exit 198 + } + local pagesize "`a4'`a5'`b5'`letter'`legal'`executive'" + if "`pagesize'"=="" | "`letter'"!="" { + local pwidth "8.5in" + local pheight "11in" + } + else if "`legal'"!="" { + local pwidth "8.5in" + local pheight "14in" + } + else if "`executive'"!="" { + local pwidth "7.25in" + local pheight "10.5in" + } + else if "`a4'"!="" { + local pwidth "210mm" + local pheight "297mm" + } + else if "`a5'"!="" { + local pwidth "148mm" + local pheight "210mm" + } + else if "`b5'"!="" { + local pwidth "176mm" + local pheight "250mm" + } + if `lscp' { + local temp "`pwidth'" + local pwidth "`pheight'" + local pheight "`temp'" + } + if "`pagesize'"!="" { + local pagesize "`pagesize'paper" + if (`lscp' | `fsize') { + local pagesize ",`pagesize'" + } + } + if `cborder' & `noborder' { + di in red "may not specify both cellborder and noborder options" + exit 198 + } + + quietly { + tempvar has_eqn st2_row last_st pad0 pad1 pad2_n padN order + + * replace % with \%, and _ with \_ if <2 $'s (i.e. not an inline equation: $...$ + * has_eqn indicates that varname has 2+ $'s + + gen byte `has_eqn' = index(`varname',"$") + + * make sure there are 2+ "$" in varname + replace `has_eqn' = index(substr(`varname',`has_eqn'+1,.),"$")>0 if `has_eqn'>0 + replace `varname'= subinstr(`varname',"_", "\_", .) if !`has_eqn' + replace `varname'= subinstr(`varname',"%", "\%", .) + + if `pretty' { + replace `varname'= subinword(`varname',"R-squared", "\$R^2$", 1) in `strow1'/`bottomBorder' + replace `varname'= subinstr(`varname'," t stat", " \em t \em stat", 1) in `bottomBorder'/`totrows' + replace `varname'= subinstr(`varname'," z stat", " \em z \em stat", 1) in `bottomBorder'/`totrows' + } + + foreach svar of local statvars { /* make replacements for column headings rows of statvars */ + replace `has_eqn' = index(`svar',"$") in `colhead1'/`headBorder' + replace `has_eqn' = index(substr(`svar',`has_eqn'+1,.),"$")>0 in `colhead1'/`headBorder' if `has_eqn'>0 + replace `svar'= subinstr(`svar',"_", "\_", .) in `colhead1'/`headBorder' if !`has_eqn' + replace `svar'= subinstr(`svar',"%", "\%", .) in `colhead1'/`headBorder' + + /* replace <, >, {, }, | with $<$, $>$, \{, \}, and $|$ in stats rows */ + /* which can be used as brackets by outstat */ + replace `svar'= subinstr(`svar',"<", "$<$", .) in `strow1'/`bottomBorder' + replace `svar'= subinstr(`svar',">", "$>$", .) in `strow1'/`bottomBorder' + replace `svar'= subinstr(`svar',"{", "\{", .) in `strow1'/`bottomBorder' + replace `svar'= subinstr(`svar',"}", "\}", .) in `strow1'/`bottomBorder' + replace `svar'= subinstr(`svar',"|", "$|$", .) in `strow1'/`bottomBorder' + } + + if `pretty' { /* make title fonts large; notes & t stats small */ + local blarge "\begin{large}" + local elarge "\end{large}" + local bfnsize "\begin{footnotesize}" + local efnsize "\end{footnotesize}" + } + if `cborder' { + local vline "|" + } + gen str20 `pad0' = "" + gen str20 `padN' = "" + if `titleWide' { + replace `pad0' = "\multicolumn{`numcols'}{`vline'c`vline'}{`blarge'" in 1 / `titleWide' + replace `padN' = "`elarge'} \\\" in 1 / `titleWide' + } + if `bottomBorder' < `totrows' { + local noterow1 = `bottomBorder' + 1 + replace `pad0' = "\multicolumn{`numcols'}{`vline'c`vline'}{`bfnsize'" in `noterow1' / l + replace `padN' = "`efnsize'} \\\" in `noterow1' / l + } + + gen str3 `pad1' = " & " in `colhead1' / `bottomBorder' + if `numcols' > 2 { + gen str3 `pad2_n' = `pad1' + } + if `pretty' { /* make stats 2-N small font */ + local strow1 = `headBorder' + 1 + gen byte `st2_row' = 0 + replace `st2_row' = (trim(`varname') == "") in `strow1' / `bottomBorder' /* only stats 2+ */ + gen byte `last_st' = (`st2_row' & `varname'[_n+1] != "") /* last stats row */ + if !`cborder' { + replace `pad0' = "\vspace{4pt}" if `last_st' + } + replace `pad1' = `pad1' + "`bfnsize'" if `st2_row' + if `numcols' > 2 { + replace `pad2_n' = "`efnsize'" + `pad2_n' + "`bfnsize'" if `st2_row' + } + replace `padN' = "`efnsize'" if `st2_row' + } + + replace `padN' = `padN' + " \\\" in `colhead1' / `bottomBorder' + if `cborder' { + replace `padN' = `padN' + " \hline" + } + else { + if !`noborder' { + if `headBorder' { + if `titleWide' { + replace `padN' = `padN' + " \hline" in `titleWide' + } + replace `padN' = `padN' + " \hline" in `headBorder' + } + replace `padN' = `padN' + " \hline" in `bottomBorder' + } + } + + local vlist "`pad0' `varname' `pad1'" + tokenize `statvars' + local ncols_1 = `numcols' - 1 + local ncols_2 = `ncols_1' - 1 + forvalues v = 1/`ncols_2' { + local vlist "`vlist' ``v'' `pad2_n'" + } + local vlist "`vlist' ``ncols_1'' `padN'" + + local texheadfootrows = `nofrag' + `pretty' + 1 /* in both headers and footers */ + local texheadrow = 2 * `nofrag' + `nopagen' + `texheadfootrows' + local texfootrow = `texheadfootrows' + local newtotrows = `totrows' + `texheadrow' + `texfootrow' + if `newtotrows' > _N { + local oldN = _N + set obs `newtotrows' + } + else { + local oldN = 0 + } + gen long `order' = _n + `texheadrow' in 1 / `totrows' + local newtexhrow1 = `totrows' + 1 + local newtexhrowN = `totrows' + `texheadrow' + replace `order' = _n - `totrows' in `newtexhrow1' / `newtexhrowN' + sort `order' + + + * insert TeX header lines + local ccc : display _dup(`ncols_1') "`vline'c" + if `nofrag' { + replace `pad0' = "\documentclass[`fontsize'`landscape'`pagesize']{article}" in 1 + replace `pad0' = "\setlength{\pdfpagewidth}{`pwidth'} \setlength{\pdfpageheight}{`pheight'}" in 2 + replace `pad0' = "\begin{document}" in 3 + replace `pad0' = "\end{document}" in `newtotrows' + } + if `nopagen' { + local row = `texheadrow' - 1 - `pretty' + replace `pad0' = "\thispagestyle{empty}" in `row' + } + if `pretty' { + local row = `texheadrow' - 1 + replace `pad0' = "\begin{center}" in `row' + local row = `newtotrows' - `texfootrow' + 2 + replace `pad0' = "\end{center}" in `row' + } + local row = `texheadrow' + replace `pad0' = "\begin{tabular}{`vline'l`ccc'`vline'}" in `row' + if (!`titleWide' | `cborder') & !`noborder' { + replace `pad0' = `pad0' + " \hline" in `row' + } + local row = `newtotrows' - `texfootrow' + 1 + replace `pad0' = "\end{tabular}" in `row' + + outfile `vlist' `using' in 1/`newtotrows', `replace' runtogether + + * delete new rows created for TeX table, if any + if `oldN' { + keep in 1/`totrows' + } + } /* quietly */ +end /* end _texout */ + + +******************************************************************************************** + + +program define out2rtf2, sortpreserve rclass + + versionSet + version `version' + +* based on version 0.9 4oct01 by john_gallup@alum.swarthmore.edu + syntax varlist using/, titleWide(int) headBorder(int) bottomBorder(int) /* + */ [wordFile(string) TOtrows(int 0) Landscape Fragment noPRetty /* + */ Fontsize(numlist max=1 >0) noBorder Cellborder /* + */ Appendpage PAgesize(string) /* + */ Lmargin(numlist max=1 >=0.5) Rmargin(numlist max=1 >=0.5) /* + */ Tmargin(numlist max=1 >=0.5) Bmargin(numlist max=1 >=0.5) /* + */ replace] + if `totrows'==0 { + local totrows = _N + } + local numcols : word count `varlist' + gettoken varname statvars : varlist + local fast 1 + + local colhead1 = `titleWide' + 1 + local strow1 = `headBorder' + 1 + + + *** replace if equation column present + local hack 0 + count if v1=="EQUATION" + if `r(N)'~=0 { + * use v2 instead + replace v1 = v2 in `=`bottomBorder'+1'/`totrows' + replace v2 = "" in `=`bottomBorder'+1'/`totrows' + + * change the string length + gen str5 myvar ="" + replace myvar =v2 + drop v2 + ren myvar v2 + order v1 v2 + + local hack 1 + } + + /* if file extension specified in `using', replace it with ".rtf" for output + local next_dot = index("`using'", ".") + if `next_dot' { + local using = substr("`using'",1,`=`next_dot'-1') + } + */ + + if `"`wordFile'"'=="" { + local endName "rtf" + } + else { + local endName "`wordFile'" + } + + local using `"using "`using'.`endName'""' + return local documentname `"`using'"' + + if "`fontsize'" == "" { + local fontsize "12" + } + + local lscp = ("`landscape'" != "") + local pretty = ("`pretty'" == "") + local cborder = ("`cellborder'" != "") + local noborder = ("`border'" != "") + local stdborder = (!`noborder' & !`cborder') + local nopagen = ("`pagenum'" != "") + local nofrag = ("`fragment'" == "") + + + if `cborder' & !`noborder' { + di in red "may not specify both cellborder and noborder options" + exit 198 + } + + * reformat "R-squared" and italicize "t" or "z" + if `pretty' { + quietly { + replace `varname'= subinword(`varname',"R-squared", "{\i R{\super 2}}", 1) in `strow1'/`bottomBorder' + replace `varname'= subinstr(`varname'," t stat", " {\i t} stat", 1) in `bottomBorder'/`totrows' + replace `varname'= subinstr(`varname'," z stat", " {\i z} stat", 1) in `bottomBorder'/`totrows' + } + } + + * font sizes in points*2 + local font2 = int(`fontsize'*2) + if `pretty' { + /* make title fonts large; notes & t stats small */ + local fslarge = "\fs" + string(int(`font2' * 1.2)) + local fsmed = "\fs" + string(`font2') + local fssmall = "\fs" + string(int(`font2' * 0.8)) + local sa0 "\sa0" /* put space after t stats rows */ + local gapsize = int(`fontsize'*0.4*20) /* 40% of point size converted to twips */ + local sa_gap "\sa`gapsize'" + } + else { + local fs0 = "\fs" + string(`font2') + } + + local onecolhead = (`headBorder' - `titleWide' == 1) + /* onecolhead = true if only one row of column headings */ + if `stdborder' { + if !`onecolhead' { + * runs here + *local trbrdrt "\clbrdrt\brdrs" /* table top is overlined */ + *local trbrdrt "\trbrdrt\brdrs" /* table top is overlined */ + + local clbrdr_uo "\clbrdrt\brdrs" /* cells are overlined */ + local clbrdr_ul "\clbrdrb\brdrs" /* cells are underlined */ + } + else { + /* cells are over- and underlined */ + local clbrdr_ul "\clbrdrt\brdrs\clbrdrb\brdrs" + + } + local trbrdrb "\trbrdrb\brdrs" + } + if `cborder' { + /* if !cborder then clbrdr is blank */ + local clbrdr "\clbrdrt\brdrs\clbrdrb\brdrs\clbrdrl\brdrs\clbrdrr\brdrs" + } + + * figure out max str widths to make cell boundaries + * cell width in twips = (max str width) * (pt size) * 12 + * (12 found by trial and error) + local twipconst = int(`fontsize' * 12 ) + tempvar newvarname + qui gen str80 `newvarname' = `varname' in `strow1'/`bottomBorder' + + local newvarlist "`newvarname' `statvars'" + qui compress `newvarlist' + local cellpos = 0 + foreach avar of local newvarlist { + local strwidth : type `avar' + local strwidth = subinstr("`strwidth'", "str", "", .) + local strwidth = `strwidth' + 1 /* add buffer */ + local cellpos = `cellpos' + `strwidth'*`twipconst' + + * hacking + if `hack'==1 & "`avar'"=="`newvarname'" & `cellpos'<1350 { + local cellpos=1350 + } + local clwidths "`clwidths'`clbrdr'\cellx`cellpos'" + + * put in underline at bottom of header in clwidth_ul + local clwidth_ul "`clwidth_ul'`clbrdr_ul'\cellx`cellpos'" + + * put in overline + local clwidth_ol "`clwidth_ol'`clbrdr_uo'\cellx`cellpos'" + } + + if `stdborder' { + if `onecolhead' { + local clwidth1 "`clwidth_ul'" + } + else { + local clwidth1 "`clwidths'" + local clwidth2 "`clwidth_ul'" + } + local clwidth3 "`clwidths'" + } + else{ + local clwidth1 "`clwidths'" + } + + * statistics row formatting + tempvar prettyfmt + qui gen str12 `prettyfmt' = "" /* empty unless `pretty' */ + if `pretty' { + * make stats 2-N small font + tempvar st2_row last_st + quietly { + gen byte `st2_row' = 0 + replace `st2_row' = (trim(`varname') == "") in `strow1' / `bottomBorder' /* only stats 2+ */ + gen byte `last_st' = (`st2_row' & `varname'[_n+1] != "") /* last stats row */ + replace `prettyfmt' = "`sa0'" in `strow1' / `bottomBorder' + replace `prettyfmt' = "`sa_gap'" if `last_st' in `strow1' / `bottomBorder' + replace `prettyfmt' = `prettyfmt' + "`fsmed'" if !`st2_row' in `strow1' / `bottomBorder' + replace `prettyfmt' = `prettyfmt' + "`fssmall'" if `st2_row' in `strow1' / `bottomBorder' + } + } + + * create macros with file write contents + + forvalues row = `colhead1'/`bottomBorder' { + local svarfmt`row' `"(`prettyfmt'[`row']) "\ql " (`varname'[`row']) "\cell""' + foreach avar of local statvars { + local svarfmt`row' `"`svarfmt`row''"\qc " (`avar'[`row']) "\cell""' + } + local svarfmt`row' `"`svarfmt`row''"\row" _n"' + } + + * write file + tempname rtfile + cap file open `rtfile' `using', write `replace' + if _rc==608 { + noi di in red `"file `using' is read-only; cannot be modified or erased"' + noi di in red `"The file needs to be closed if being used by another software such as Word."' + exit 608 + } + + file write `rtfile' "{\rtf1`fs0'" _n /* change if not roman: \deff0{\fonttbl{\f0\froman}} */ + + * title + if `titleWide' { + file write `rtfile' "\pard\qc`fslarge'" _n + forvalues row = 1/`titleWide' { + file write `rtfile' (`varname'[`row']) "\par" _n + } + } + + * The top line + file write `rtfile' "\trowd\trgaph75\trleft-75\intbl\trqc`fsmed'`trbrdrt'`clwidth_ol'" _n + *file write `rtfile' "\trowd\trgaph75\trleft-75\intbl\trqc`fsmed'`trbrdrt'`clwidth1'" _n + + local headBorder_1 = `headBorder' - 1 + * write header rows 1 to N-1 + + forvalues row = `colhead1'/`headBorder_1' { + file write `rtfile' `svarfmt`row'' + * turn off the overlining the first time it's run + file write `rtfile' "\trowd\trgaph75\trleft-75\trqc`clwidth3'" _n + } + file write `rtfile' "\trowd\trgaph75\trleft-75\trqc`clwidth2'" _n + + * write last header row + file write `rtfile' `svarfmt`headBorder'' + + local bottomBorder_1 = `bottomBorder' - 1 + /* turn off cell underlining */ + file write `rtfile' "\trowd\trgaph75\trleft-75\trqc`clwidth3'" _n + + * table contents + forvalues row = `strow1'/`bottomBorder_1' { + file write `rtfile' `svarfmt`row'' + } + + if `stdborder' { + /* write last row */ + *file write `rtfile' "\trowd\trgaph75\trleft-75\trqc`trbrdrb'`clwidths'" _n + * make it underline + file write `rtfile' "\trowd\trgaph75\trleft-75\trqc`trbrdrb'`clwidth_ul'" _n + file write `rtfile' `svarfmt`bottomBorder'' + } + + /* write notes rows */ + if `bottomBorder' < `totrows' { + local noterow1 = `bottomBorder' + 1 + file write `rtfile' "\pard\qc`fssmall'" _n + forvalues row = `noterow1'/`totrows' { + file write `rtfile' (`varname'[`row']) "\par" _n + } + } + + * write closing curly bracket + file write `rtfile' "}" +end /* end out2rtf2 */ + + +******************************************************************************************** + + +program define _xmlout + versionSet + version `version' + +* emulates the output produced by xmlsave: +* xmlsave myfile, replace doctype(excel) legible + +syntax using/ [, excelFile(string) LEGible noNAMes titleWide(integer 0) /* + */ headBorder(integer 10) bottomBorder(integer 10) ] + +* assumes all columns are string; if numbers, then the format needs to be checked + +*local legible legible + +if "`legible'"=="legible" { + local _n "_n" +} + +tempname source saving + +if `"`excelFile'"'=="" { + local endName "xml" +} +else { + local endName "`excelFile'" +} + +local save `"`using'.`endName'"' + +*file open `source' using `"`using'"', read +cap file open `saving' using `"`save'"', write text replace + +if _rc==608 { + noi di in red `"file `save' is read-only; cannot be modified or erased"' + noi di in red `"The file needs to be closed if being used by another software such as Excel."' + exit 608 +} + +*file write `saving' `"`macval(line)'"' +file write `saving' `"<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>"' `_n' +file write `saving' `"<?mso-application progid="Excel.Sheet"?>"' `_n' +file write `saving' `"<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet""' `_n' +file write `saving' `" xmlns:o="urn:schemas-microsoft-com:office:office""' `_n' +file write `saving' `" xmlns:x="urn:schemas-microsoft-com:office:excel""' `_n' +file write `saving' `" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet""' `_n' +file write `saving' `" xmlns:html="http://www.w3.org/TR/REC-html40">"' `_n' +file write `saving' `"<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">"' `_n' +file write `saving' `"<Author></Author>"' `_n' +file write `saving' `"<LastAuthor></LastAuthor>"' `_n' +file write `saving' `"<Created></Created>"' `_n' +file write `saving' `"<LastSaved></LastSaved>"' `_n' +file write `saving' `"<Company></Company>"' `_n' +file write `saving' `"<Version></Version>"' `_n' +file write `saving' `"</DocumentProperties>"' `_n' +file write `saving' `"<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">"' `_n' +file write `saving' `"<ProtectStructure>False</ProtectStructure>"' `_n' +file write `saving' `"<ProtectWindows>False</ProtectWindows>"' `_n' +file write `saving' `"</ExcelWorkbook>"' `_n' +file write `saving' `"<Styles>"' `_n' + +* styles +file write `saving' `"<Style ss:ID="Default" ss:Name="Normal">"' `_n' +file write `saving' `"<Alignment ss:Vertical="Bottom"/>"' `_n' +file write `saving' `"<Borders/>"' `_n' +file write `saving' `"<Font/>"' `_n' +file write `saving' `"<Interior/>"' `_n' +file write `saving' `"<NumberFormat/>"' `_n' +file write `saving' `"<Protection/>"' `_n' +file write `saving' `"</Style>"' `_n' + +* bold & (center) +file write `saving' `"<Style ss:ID="s1">"' `_n' +*file write `saving' `"<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>"' `_n' +file write `saving' `"<Font ss:Bold="1" ss:Size='12'/>"' `_n' +file write `saving' `"<NumberFormat/>"' `_n' +file write `saving' `"</Style>"' `_n' + +* top border & center +file write `saving' `"<Style ss:ID="s21">"' `_n' +file write `saving' `"<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>"' `_n' +file write `saving' `"<NumberFormat/>"' `_n' +file write `saving' `"<Borders>"' `_n' +file write `saving' `"<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>"' `_n' +file write `saving' `"</Borders>"' `_n' +file write `saving' `"</Style>"' `_n' + +* main body (no border) & center +file write `saving' `"<Style ss:ID="s22">"' `_n' +file write `saving' `"<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>"' `_n' +file write `saving' `"<NumberFormat/>"' `_n' +file write `saving' `"</Style>"' `_n' + +* bottom border & center +file write `saving' `"<Style ss:ID="s23">"' `_n' +file write `saving' `"<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>"' `_n' +file write `saving' `"<NumberFormat/>"' `_n' +file write `saving' `"<Borders>"' `_n' +file write `saving' `"<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>"' `_n' +file write `saving' `"</Borders>"' `_n' +file write `saving' `"</Style>"' `_n' + +* goldfish (no border, left-justified) +file write `saving' `"<Style ss:ID="s24">"' `_n' +file write `saving' `"<NumberFormat/>"' `_n' +file write `saving' `"</Style>"' `_n' + +* top border +file write `saving' `"<Style ss:ID="s31">"' `_n' +file write `saving' `"<Borders>"' `_n' +file write `saving' `"<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>"' `_n' +file write `saving' `"</Borders>"' `_n' +file write `saving' `"</Style>"' `_n' + +* main body (no border) +file write `saving' `"<Style ss:ID="s32">"' `_n' +file write `saving' `"<Borders/>"' `_n' +file write `saving' `"</Style>"' `_n' + +* bottom border & center +file write `saving' `"<Style ss:ID="s33">"' `_n' +file write `saving' `"<Borders>"' `_n' +file write `saving' `"<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>"' `_n' +file write `saving' `"</Borders>"' `_n' +file write `saving' `"</Style>"' `_n' + +file write `saving' `"</Styles>"' `_n' +file write `saving' `"<Names>"' `_n' +file write `saving' `"</Names>"' `_n' +file write `saving' `"<Worksheet ss:Name="Sheet1">"' `_n' + +* set up file size +qui describe, short + +local N=_N +local tableN `N' + +if "`names'"~="nonames" { + * add one if variable names are to be inserted + local tableN=`N'+1 +} +else { + * add one for the look + local tableN=`N'+1 +} + +file write `saving' `"<Table ss:ExpandedColumnCount="`r(k)'" ss:ExpandedRowCount="`tableN'""' `_n' +file write `saving' `" x:FullColumns="1" x:FullRows="1">"' `_n' + +* should be tostring and format here if dealing with numbers + + ds8 + + * write the variable names at the top or empty row + if "`names'"~="nonames" { + file write `saving' `"<Row>"' `_n' + foreach var in `dsVarlist' { + if "`Version7'"~="" { + file write `saving' `"<Cell ss:StyleID="s1"><Data ss:Type="String">`macval(var)'</Data></Cell>"' _n + } + else { + file write `saving' `"<Cell ss:StyleID="s1"><Data ss:Type="String">`var'</Data></Cell>"' _n + } + } + file write `saving' `"</Row>"' `_n' + } + else { + file write `saving' `"<Row>"' `_n' + file write `saving' `"</Row>"' `_n' + } + + +* title +local count `titleWide' +local total 1 +while `count'~=0 { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`total') n(`N') style(`" ss:StyleID="s1""') style1(`" ss:StyleID="s1""') + local count=`count'-1 + local total=`total'+1 +} + +* top border +local count=`total' +forval num=`count'/`count' { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`num') n(`N') style(`" ss:StyleID="s21""') style1(`" ss:StyleID="s31""') + local total=`total'+1 +} + +* ctitle +local count=`total' +forval num=`count'/`headBorder' { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`num') n(`N') style(`" ss:StyleID="s22""') style1(`" ss:StyleID="s32""') + local total=`total'+1 +} + +* top border (closes ctitle) +local count=`total' +forval num=`count'/`count' { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`num') n(`N') style(`" ss:StyleID="s21""') style1(`" ss:StyleID="s31""') + local total=`total'+1 +} + +* body +local count=`total' +forval num=`count'/`=`bottomBorder'-1' { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`num') n(`N') style(`" ss:StyleID="s22""') style1(`" ss:StyleID="s32""') + local total=`total'+1 +} + +* bottom border (closes body) +local count=`total' +forval num=`count'/`count' { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`num') n(`N') style(`" ss:StyleID="s23""') style1(`" ss:StyleID="s33""') + local total=`total'+1 +} + +* goldfish +if `N'>`total' { + local count=`total' + forval num=`count'/`N' { + xmlstack, saving(`saving') dsVarlist(`dsVarlist') num(`num') n(`N') style(`" ss:StyleID="s24""') style1(`" ss:StyleID="s24""') + local total=`total'+1 + } +} + +/* +forval num=1/`N' { + + file write `saving' `"<Row>"' `_n' + + *foreach var in `=r(varlist)' { + foreach var in `dsVarlist' { + + *local stuff `=`var'[`num']' + local stuff=`var' in `num' + + local stuff : subinstr local stuff "<" "<", all + local stuff : subinstr local stuff ">" ">", all + + * the main body + if "`Version7'"~="" { + file write `saving' `"<Cell`style'><Data ss:Type="String">`macval(stuff)'</Data></Cell>"' `_n' + } + else { + file write `saving' `"<Cell`style'><Data ss:Type="String">`stuff'</Data></Cell>"' `_n' + } + } + file write `saving' `"</Row>"' `_n' +} +*/ + +file write `saving' `"</Table>"' `_n' +file write `saving' `"<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">"' `_n' +file write `saving' `"<ProtectedObjects>False</ProtectedObjects>"' `_n' +file write `saving' `"<ProtectedScenarios>False</ProtectedScenarios>"' `_n' +file write `saving' `"</WorksheetOptions>"' `_n' +file write `saving' `"</Worksheet>"' `_n' +file write `saving' `"</Workbook>"' `_n' + +* close out with the last line +*file write `saving' _n +*file close `source' + +file close `saving' + +end /* _xmlout */ + + +******************************************************************************************** + + +program define xmlstack + +syntax, saving(string) dsVarlist(string) num(numlist) n(numlist) style(string) style1(string) + +local N `n' + +*forval num=1/`N' { + + file write `saving' `"<Row>"' `_n' + + local count 0 + + *foreach var in `=r(varlist)' { + foreach var in `dsVarlist' { + + if `count'==0 { + local STYLE `"`style1'"' + } + else { + local STYLE `"`style'"' + } + + *local stuff `=`var'[`num']' + local stuff=`var' in `num' + + local stuff : subinstr local stuff "<" "<", all + local stuff : subinstr local stuff ">" ">", all + + * the main body + if "`Version7'"~="" { + file write `saving' `"<Cell`STYLE'><Data ss:Type="String">`macval(stuff)'</Data></Cell>"' `_n' + } + else { + file write `saving' `"<Cell`STYLE'><Data ss:Type="String">`stuff'</Data></Cell>"' `_n' + } + + local count=`count'+1 + } + file write `saving' `"</Row>"' `_n' +*} + +end /* xmlstack */ + + +******************************************************************************************** + + +program define dsCol + * gets you the number of columns like cret does for version 8 + * alternatively use -describe, short- and r(k) + + version 7.0 + cap local ck `c(k)' + + if "`ck'"=="" { + local ck 0 + foreach var of varlist _all { + local ck=`ck'+1 + } + } + c_local ck `ck' +end + + +******************************************************************************************** + + +program define ds8 + * get you the list of variable like -ds- does for version 8 + version 7.0 + qui ds + if "`r(varlist)'"=="" { + local dsVarlist "" + foreach var of varlist _all { + local dsVarlist "`dsVarlist' `var'" + } + c_local dsVarlist `dsVarlist' + } + else { + c_local dsVarlist `r(varlist)' + } +end + + +******************************************************************************************** + + +program define _tab3, eclass + * get you tabulations + versionSet + version `version' + +syntax varlist /* + */ [if] [in] [using] [, /* + */ APpend REPLACE esample drop(string) /* + */ DISplay log regress] + + +qui { + +if "`drop'"~="" { + ds `drop' + local drop `r(varlist)' + *cap local varlist: list varlist - drop + macroMinus `varlist', names(varlist) subtract(`drop') +} + +* checking the height +local varCount: word count `varlist' +if `=`varCount'*100'>=`=_N' { + preserve + set obs `=`varCount'*100+2' +} + + + +if `=_by()'==1 { + * eliminate -by- variables from varlist + local drop `_byvars' + *cap local varlist: list varlist - drop + macroMinus `varlist', names(varlist) subtract(`drop') +} + +*marksample touse +*marksample alluse, noby + +tempvar touse alluse + +mark `touse' `if' `in' [`weight'`exp'] +mark `alluse' `if' `in' [`weight'`exp'], noby + +** restricting to e(sample) +if "`noesample'"=="noesample" { + replace `touse'=0 if e(sample)~=1 + replace `alluse'=0 if e(sample)~=1 +} + +tempvar stacker name label frequency percent cumulative total +tempname val_mat freq_mat ebmat eVmat + + +gen `stacker'=. +gen str5 `name'="" + +gen `label'=. +gen `frequency'=. + +gen `percent'=. +gen `cumulative'=. + +gen `total'=. + + +local varname "" + +noi tabulate `varlist' [`weight'`exp'] if `touse', matrow(`val_mat') matcell(`freq_mat') + +if r(N)~=0 { + noi tabulate `varlist' [`weight'`exp'] if `touse', matrow(`val_mat') matcell(`freq_mat') + + local stuff `r(r)' + forval row=1/`stuff' { + *replace `name' = "r`row'" in `row' + + local content = `val_mat'[`row',1] + replace `label' =`content' in `row' + + replace `name' = string(`val_mat'[`row',1]) in `row' + local varname "`varname' `content'" + + local content = `freq_mat'[`row',1] + replace `frequency' =`content' in `row' + } + replace `total'=sum(`frequency') + qui sum `varlist', meanonly + replace `percent'=100*`frequency'/`r(N)' + replace `cumulative'=sum(`percent') if `label'~=. +} + + + +*mat list `val_mat' +*mat list `freq_mat' + + local colVarname "" + foreach col in obs mean sd min max { + foreach var in `varname' { + local colVarname "`colVarname' `col':`var'" + } + } + + count if `name'~="" + + replace `stacker'=`label' + forval num=1/`=r(N)' { + replace `stacker'=`frequency'[`num'] in `=r(N)+`num'' + replace `stacker'=`percent'[`num'] in `=r(N)*2+`num'' + replace `stacker'=`cumulative'[`num'] in `=r(N)*3+`num'' + } + + if "`display'"=="display" { + noi tabulate `varlist' [`weight'`exp'] if `touse' +} +if `=_by()'==1 { + * generate column heading when -by- specified + local cc=1 + local ctitleList "" + + tokenize `_byvars' + while "``cc''"~="" { + + * should there be `touse' here? + qui sum ``cc'' if `_byindex' == `=_byindex()' & `touse' + if r(N)<. { + local actual`cc' =r(mean) + } + else { + local actual`cc' =. + } + + * place ctitle in there + local ctitleList "`ctitleList' ``cc'' `actual`cc'' " + local cc=`cc'+1 + } + + * replace last if -by- specified + if `=_byindex()'~=1 & "`replace'"=="replace" { + local replace "" + } +} + +count if `stacker'~=. + +if r(N)>0 { + * recycling name: they exist in variables and matrix + + if "`log'"=="log" { + + + + mkmat `stacker' in 1/`=r(N)', matrix(`ebmat') + mkmat `empty' in 1/`=r(N)', matrix(`eVmat') + + mat rownames `ebmat'=`colVarname' + mat rownames `eVmat'=`colVarname' + + mat colnames `ebmat'=y1 + mat colnames `eVmat'=y1 + + mat `ebmat'=`ebmat'' + mat `eVmat'=(`eVmat'*`eVmat'') + } + else { + count if `name'~="" + + * `=r(N)' gets wiped out in version 7 + local rN=r(N) + + mkmat `frequency' in 1/`rN', matrix(`ebmat') + mkmat `percent' in 1/`rN', matrix(`eVmat') + + mat rownames `ebmat'=`varname' + mat rownames `eVmat'=`varname' + + mat colnames `ebmat'=y1 + mat colnames `eVmat'=y1 + + mat `ebmat'=`ebmat'' + mat `eVmat'=(`eVmat'*`eVmat'') + } + + if "`replace'"=="replace" { + if "`Version7'"=="" { + est mat freq `ebmat' + est mat percent `eVmat' + + count if `touse'==1 + est scalar total = `total'[_N] + } + else { + eret clear + *eret mat b=`ebmat' + *eret mat V=`eVmat' + + eret post b V + if `"`if'"'~="" { + eret local depvar `"`if'"' + } + else { + eret local depvar `"Tabulate"' + } + eret local cmd "tab3" + + count if `touse'==1 + eret scalar total = `total'[_N] + } + } + else { + if "`Version7'"=="" { + est mat freq `ebmat' + est mat percent `eVmat' + + count if `touse'==1 + est scalar total = `total'[_N] + } + else { + eret mat freq=`ebmat' + eret mat percent=`eVmat' + + count if `touse'==1 + eret scalar total = `total'[_N] + } + } +} +else { + * no observation + if "`Version7'"=="" { + mat def `ebmat'=(0) + mat def `eVmat'=(0) + mat colnames `ebmat'="MISSING" + mat colnames `eVmat'="MISSING" + est mat freq `ebmat' + est mat percent `eVmat' + est scalar total=0 + } + else { + mat def `ebmat'=(0) + mat def `eVmat'=(0) + mat colnames `ebmat'="MISSING" + mat colnames `eVmat'="MISSING" + eret mat freq=`ebmat' + eret mat percent=`eVmat' + eret scalar total=0 + } +} +} /* qui */ +noi di + +end /* _tab3 */ + + +******************************************************************************************** + + +* Jan2009 by roywada@hotmail.com +prog define optionSyntax + * cleans the options within parenthetical options of the form -option( )- + * clean c_locals of those content names as if they were the options + + * valid: allowed contents in parenthesis + * name: name of the option + * content: actual user input into the option + * passthru: if it was passtru rather than string + * nameShow: mesaage to user when invalid + + syntax, valid(string) name(string) nameShow(string) content(string) [PASSthru NORETURN] + + * take comma out + if "`passthru'"=="passthru" { + local content : subinstr local content "`name'(" " ", all + local content : subinstr local content ")" " ", all + local content : subinstr local content "," " ", all + } + else { + * just string + local content : subinstr local content "," " ", all + } + + local thisMany : word count `content' + local num=1 + local optionList "" + + while `num'<=`thisMany' { + local option`num' : word `num' of `content' + + * it must be one of the list + local test 0 + foreach var in `valid' { + if "`var'"=="`option`num''" & `test'==0 { + local test 1 + } + } + + if `test'==0 { + noi di in white "`option`num''" in red " is not a valid option or matrix for {opt `nameShow'}" + exit 198 + } + local optionList "`optionList' `option`num''" + local num=`num'+1 + } + + if "`noreturn'"~="noreturn" { + foreach var in `valid' { + * clears the c_locals + c_local `var' "" + } + + foreach var in `optionList' { + * inserts the c_locals + c_local `var' "`var'" + } + } + + c_local optionList `"`optionList'"' + c_local optionCount : word count `optionList' + +end + + +******************************************************************************************** + + +* sum2 1.0.0 Jan2009 by roywada@hotmail.com +* sum2 1.0.1 21oct2009 : gets the entire varlist if no e(b) exists +* raw option + +program define _sum2, eclass +*program define sum2, eclass by(recall) sortpreserve + versionSet + version `version' + +syntax [varlist] [using] [if] [in] [pweight aweight iweight] [, /* + */ APpend REPLACE esample drop(string) /* + */ noDISplay log REGress DETail NODEPendent raw] + + +local _0 `"`0'"' + + +qui { + + +if "`log'"=="log" & "`detail'"=="detail" { + noi di in red "cannot choose both {opt det:ail} and {opt log}" + exit 198 +} + +if "`log'"~="log" & "`detail'"~="detail" { + local regress "regress" +} + + +if "`regress'"=="regress" { + * check for prior sum2, replace + foreach var in eqlist { + if "`e(cmd)'"=="sum2, log" { + if "`Version7"~="" { + *eret list + } + else { + *est list + } + noi di in red "no regression detected; already replaced with summary" + exit 198 + } + } + + *** replace varlist with e(b) names + regList `_0' + + local varlist `r(varlist)' + local eqlist `r(eqlist)' + + local varnum `r(varnum)' + local eqnum `r(eqnum)' +} +else { + local varnum: word count `varlist' + local eqnum 0 + +} + +local varlist `"`eqlist' `varlist'"' + + +* take tempvars out +tsunab stuff : __00* + +macroMinus `varlist', names(varlist) subtract(`stuff') +local varnum: word count `varlist' + +* extender +local N=_N +version 7: describe, short +if `r(k)'>`N'+1 & `r(k)'<. { + set obs `r(k)' +} + + +if "`drop'"~="" { + ds `drop' + local drop `r(varlist)' + *cap local varlist: list varlist - drop + macroMinus `varlist', names(varlist) subtract(`drop') +} + + + +if `=_by()'==1 { + * eliminate -by- variables from varlist + local drop `_byvars' + *cap local varlist: list varlist - drop + macroMinus `varlist', names(varlist) subtract(`drop') +} + + +*marksample touse +*marksample alluse, noby +*tempvar touse alluse + +tempvar touse +*mark `alluse' `if' `in', noby + +cap confirm matrix e(b) +if _rc | "`raw'"=="raw" { + mark `touse' `if' `in' [`weight'`exp'] +} +else { + * always esample restricted + if `"`if'"'~="" { + mark `touse' `if' & e(sample) `in' [`weight'`exp'] + } + else { + mark `touse' if e(sample) `in' [`weight'`exp'] + } +} + +count if `touse'==1 +if `r(N)'==0 { + noi di in red "no observation left; check your if/in conditionals" + exit 198 +} + +*** must take out string variables prior to marking them +local stringList "" +local noobsList "" +local anyObs 0 +foreach var in `varlist' { + sum `var' if `touse' [`weight'`exp'], meanonly + if r(N)==0 { + local minus "`var'" + *cap local varlist: list varlist - minus + macroMinus `varlist', names(varlist) subtract(`minus') + + if "`Version7'"=="" { + local varlist=subinstr("`varlist'","`minus'","",.) + } + + local type: type `var' + local check= substr("`type'",1,3) + + * display later + if "`check'"=="str" { + *noi di in yellow "`var' is string, not included" + local stringList "`stringList' `var'" + } + else { + *noi di in yellow "`var' has no observation, not included" + local noobsList "`noobsList' `var'" + } + } + else { + local anyObs 1 + } + local varnum: word count `varlist' +} + +tempvar name N mean sd min max zeros +tempname ebmat eVmat +tempvar sum_w Var skewness kurtosis sum p1 p5 p10 p25 p50 p75 p90 p95 p99 + +local varname "" + +foreach var in `varlist' { + qui sum `var' if `touse' [`weight'`exp'], `detail' + if r(N)~=0 { + local varname "`varname' `var'" + local row=`row'+1 + + foreach var in mean sd N min max { + mat ``var'' = nullmat(``var'') \ r(`var') + } + mat `zeros' = nullmat(`zeros') \ 0 + } + if "`detail'"=="detail" & r(N)~=0 { + foreach var in sum_w Var skewness kurtosis sum p1 p5 p10 p25 p50 p75 p90 p95 p99 { + mat ``var'' = nullmat(``var'') \ r(`var') + } + } +} + +* rename them +if "`regress'"=="regress" { + foreach var in mean sd N min max { + mat rownames ``var''=`varname' + mat colnames ``var''=`var' + } +} +if "`log'"=="log" { + foreach var in N mean sd min max { + mat rownames ``var''=`varname' + mat roweq ``var''=`var' + mat colnames ``var''=`var' + } +} +if "`detail'"=="detail" { + foreach var in N mean sd min max sum_w Var skewness kurtosis sum p1 p5 p10 p25 p50 p75 p90 p95 p99 { + mat rownames ``var''=`varname' + mat roweq ``var''=`var' + mat colnames ``var''=`var' + } +} + +if "`display'"~="nodisplay" & `anyObs'==1 { + noi sum `varlist' if `touse' [`weight'`exp'], `detail' +} + + +if `=_by()'==1 { + * generate column heading when -by- specified + local cc=1 + local ctitleList "" + + tokenize `_byvars' + while "``cc''"~="" { + + * should there be `touse' here? + qui sum ``cc'' if `_byindex' == `=_byindex()' & `touse' + if r(N)<. { + local actual`cc' =r(mean) + } + else { + local actual`cc' =. + } + + * place ctitle in there + local ctitleList "`ctitleList' ``cc'' `actual`cc'' " + local cc=`cc'+1 + } + + * replace last if -by- specified + if `=_byindex()'~=1 & "`replace'"=="replace" { + local replace "" + } +} + + * exporting temp matrices + if "`regress'"=="regress" { + mat `ebmat' = `mean' + mat `eVmat' = `sd' + + mat `ebmat'=`ebmat'' + mat `eVmat'=(`eVmat'*`eVmat'') + } + else if "`log'"=="log" { + foreach var in N mean sd min max { + mat `ebmat' = nullmat(`ebmat') \ ``var'' + mat `eVmat' = nullmat(`eVmat') \ `zeros' + } + + * rename eVmat after ebmat + local colnames: colnames `ebmat' + local roweq: roweq `ebmat' + local rownames: rownames `ebmat' + + mat colnames `eVmat'=`colnames' + mat roweq `eVmat'=`roweq' + mat rownames `eVmat'=`rownames' + + mat `ebmat'=`ebmat'' + mat `eVmat'=(`eVmat'*`eVmat'') + } + else if "`detail'"=="detail" { + foreach var in N mean sd min max sum_w Var skewness kurtosis sum p1 p5 p10 p25 p50 p75 p90 p95 p99 { + mat `ebmat' = nullmat(`ebmat') \ ``var'' + mat `eVmat' = nullmat(`eVmat') \ `zeros' + } + + * rename eVmat after ebmat + local colnames: colnames `ebmat' + local roweq: roweq `ebmat' + local rownames: rownames `ebmat' + + mat colnames `eVmat'=`colnames' + mat roweq `eVmat'=`roweq' + mat rownames `eVmat'=`rownames' + + mat `ebmat'=`ebmat'' + mat `eVmat'=(`eVmat'*`eVmat'') + } + + if "`replace'"=="replace" { + if "`Version7'"=="" { + est mat mean `ebmat' + est mat Var `eVmat' + + count if `touse'==1 + est scalar N = r(N) + } + else { + eret clear + mat b=`ebmat' + mat V=`eVmat' + mat list b + eret post b V + if `"`if'"'~="" { + gettoken first second: if, parse(" ") + eret local depvar `"`second'"' + } + else { + eret local depvar `"Summary"' + } + eret local cmd "sum2, log" + + if "`regress'"=="regress" { + count if `touse'==1 + eret scalar N = r(N) + } + } + } + else { + if "`Version7'"=="" { + est mat mean `ebmat' + est mat Var `eVmat' + + if "`regress'"=="regress" { + count if `touse'==1 + est scalar sum_N = r(N) + } + } + else { + eret mat mean=`ebmat' + eret mat Var=`eVmat' + + if "`regress'"=="regress" { + count if `touse'==1 + eret scalar sum_N = r(N) + } + } + } + +/* +else { + if `=_by()'==1 { + noi di in yellow "no observations when variable = something" + } + else { + * `=_by()'~=1, not running by( ) + *noi di in red "no observations" + error 2000 + } +} +*/ + +noi di +if `"`stringList'"'~="" { + noi di in yellow "Following variable is string, not included: " + foreach var in `stringList' { + noi di in yellow "`var' " _c + } + di +} +if `"`noobsList'"'~="" { + noi di in yellow "Following variable has no observation, not included: " + foreach var in `noobsList' { + noi di in yellow "`var' " _c + } + di +} + +} /* qui */ +end /* sum2 */ + + +******************************************************************************************** + + +* regList Jan2009 by roywada@hotmail.com +* regList Jun2009 by roywada@hotmail.com verion 7 added + +program define regList, rclass +* get the name of equations and variables used in e(b) + versionSet + version `version' + + * [if] [in] ignored: + syntax [varlist(default=none)] [if] [in] [, NODEPendent *] + + * separate potential equation names from variable names + tempname b b_transpose + mat `b'=e(b) + mat `b_transpose' = `b'' + local varnames : rownames(`b_transpose') + +if "`nodependent'"~="nodependent" { + * indep variables, but the equations names are actually dep variables + * plus the dep var + local eqlist "`e(depvar)' `eqlist'" + macroUnique `eqlist', names(eqlist) number(eqnum) + +/* not reliable because not always a dependent variable, i.e. sqreg slaps on q10, q20, etc. + * take off numbers from the front (reg3 sometimes slaps them on) + foreach v in `eqlist' { + local first = substr(`"`v'"',1,1) + local test + cap local test = `first' * 1 + if "`test'"=="`first'" { + * a number + local wanted = substr(`"`v'"',2,.) + local collect "`collect' `wanted'" + } + else { + local collect "`collect' `v'" + } + } + local eqlist `collect' + macroUnique `eqlist', names(eqlist) number(eqnum) + + * repeat + foreach v in `eqlist' { + local first = substr(`"`v'"',1,1) + local test + cap local test = `first' * 1 + if "`test'"=="`first'" { + * a number + local wanted = substr(`"`v'"',2,.) + local collect "`collect' `wanted'" + } + else { + local collect "`collect' `v'" + } + } + local eqlist `collect' +*/ + + macroUnique `eqlist', names(eqlist) number(eqnum) +} + macroUnique `eqlist', names(eqlist) number(eqnum) + macroMinus `varnames', names(varlist) number(varnum) subtract(_cons) + macroUnique `varlist', names(varlist) number(varnum) + + return local eqlist `eqlist' + return local eqnum `eqnum' + return local varlist `varlist' + return local varnum `varnum' + +end /* regList */ + + +******************************************************************************************** + + +* macroUnique Jan2009 by roywada@hotmail.com +* macroUnique Jun2009 by roywada@hotmail.com version 7 added +program define macroUnique + +* gets you unique macro names & number of them (both c_locals) +* could be empty + +version 7.0 + +syntax [anything], names(string) [number(string)] + local collect "" + * just holding the place until the loop + local temp1: word 1 of `anything' + local temp2: word 2 of `anything' + + local total: word count `anything' + local cc 1 + local same "" + while "`temp1'"~="" { + local temp1: word `cc' of `anything' + local same "" + *di "try `temp1' at `cc'" + local kk=`cc'+1 + local temp2: word `kk' of `anything' + while "`temp2'"~="" & "`same'"=="" { + if "`temp1'"=="`temp2'" { + *di "`cc' is same as `kk'" + local same same + } + else { + local kk=`kk'+1 + } + local temp2: word `kk' of `anything' + } + if "`temp1'"~="" & "`temp2'"=="" & "`same'"~="same" { + *di "accept `temp1' at `cc' before " _c + local collect "`collect' `temp1'" + } + *di "reject `temp1' at `cc'" + local cc=`cc'+1 + } + + c_local `names' `collect' + if "`number'"~="" { + c_local `number' : word count `collect' + } +end + + +******************************************************************************************** + + +* macroMinus Jan2009 by roywada@hotmail.com +* macroMinus Jun2009 by roywada@hotmail.com version 7 added +program define macroMinus + +version 7.0 + +* gets you macro names subtracted & number of them (both c_locals) +* could be empty + +syntax [anything], names(string) [number(string asis) subtract(string)] + local collect "" + * just holding until the loop + local temp1: word 1 of `anything' + local temp2: word 1 of `subtract' + + local total: word count `anything' + local cc 1 + local same "" + while "`temp1'"~="" { + local temp1: word `cc' of `anything' + local same "" + *di "try `temp1' at `cc'" + local kk=1 + local temp2: word `kk' of `subtract' + while "`temp2'"~="" & "`same'"=="" { + if "`temp1'"=="`temp2'" { + *di "`temp1' is same as `temp2'" + local same same + } + else { + local kk=`kk'+1 + } + local temp2: word `kk' of `subtract' + } + if "`temp1'"~="" & "`temp2'"=="" & "`same'"~="same" { + *di "accept `temp1' at `cc' before " _c + local collect "`collect' `temp1'" + } + *di "reject `temp1' at `cc'" + local cc=`cc'+1 + } + + c_local `names' `collect' + if "`number'"~="" { + c_local `number' : word count `collect' + } + +end + + +******************************************************************************************** + + +* Jun2009 version 7 added + +program define cleanFile +* split possible eqnames from varnames +* gets labels +* get titles +* c_locals titleWide headRow bottomRow + + versionSet + version `version' + +syntax using [, noQUOte comma title(string) label labelOption(string) /* + */ titlefile(string) NOTITLE slow(numlist)] + + + *** get the label names + if "`label'"=="label" | "`labelOption'"=="insert" { + tempfile labelfile + + * extender making sure the obs > columns + local N=_N + describe, short + if `r(k)'>`N'+1 & `r(k)'<. { + set obs `r(k)' + } + + gen str8 var1="" + gen str8 labels="" + unab varlist_all : * + cap unab subtract: _est_* + *cap local varlist_only : list varlist_all - subtract + macroMinus `varlist_all', names(varlist_only) subtract(`subtract') + local count=1 + foreach var in `varlist_only' { + local lab "" + cap local lab: var label `var' + local lab=trim("`lab'") + if "`lab'"~="" { + replace var1="`var'" in `count' + replace labels="`lab'" in `count' + local count=`count'+1 + } + } + keep var1 labels + + drop if var1=="" + + * indicate no label contained + local N=_N + if `N'==0 { + local emptyLabel=1 + } + else { + local emptyLabel=0 + } + + * add constant + local newN=_N+1 + set obs `newN' + + local N=_N + replace labels="Constant" in `N' + replace var1="Constant" in `N' + + save `"`labelfile'"' + } + + + + *** clean up equation names, title, label + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + insheet `using', nonames clear + tempvar id1 id2 id3 id4 + + + *** bottom row (the bottom border), count up + gen rowmiss=0 + foreach var of varlist v* { + replace rowmiss=rowmiss+1 if `var'~="" + } + local N=_N + local content 1 + local num 0 + while `content'==1 & `num'<`N' { + local content rowmiss[`=`N'-`num''] + local num=`num'+1 + } + * add titleWide and eqAdded later to get bottomBorder + local bottomRow = `N'-`num'+1 + + + *** head row (the head border), count down + local content + local num 1 + local N=_N + while `"`content'"'=="" & `num'<=`N' { + local content=v1[`num'] + local num=`num'+1 + } + * add titleWide later to get headBorder + local headRow=`num'-1 + drop rowmiss + + + gen id1=_n + gen str8 equation="" + gen str8 variable="" + + * find the top & bottom empty row + gen rowmiss=0 + foreach var of varlist v* { + replace rowmiss=rowmiss+1 if `var'~="" + } + + + * take care if colon (:) that may appears in the notes by limiting the search to the above + local N=_N + local stuff=rowmiss[`N'] + local cc 0 + while `stuff'~=0 { + local stuff=rowmiss[`N'-`cc'] + local cc=`cc'+1 + } + + ********** this should be made faster in version 10 + forval num=1/`=`N'-`cc'' { + local name=trim(v1[`num']) + local column=index("`name'",":") + if `column'~=0 { + local equation=trim(substr("`name'",1,`column'-1)) + local variable=trim(substr("`name'",`column'+1,length("`name'"))) + replace equation="`equation'" in `num' + replace variable="`variable'" in `num' + } + } + + replace equation=equation[_n-1] if equation=="" & equation[_n-1]~="" & rowmiss~=0 + *replace equation=equation[_n-1] if equation=="" & equation[_n-1]~="" & v1~="Observations" + + * needs a workaround for blank inserted by user + gen str8 temp="" + replace temp=equation + replace temp=temp[_n-1] if temp[_n-1]~="" & temp[_n-1]~="." & temp=="" + gen str8 top="1" if temp[_n]~=temp[_n-1] & temp[_n]~="" + drop temp + + + * now only the top empty row + replace rowmiss=0 if rowmiss[_n-1]==0 + + count if equation~="" + if `r(N)'~=0 { + * move equation names, instead of inserting them + count if v1=="EQUATION" + if `r(N)'==0 { + gen str8 v0="" + replace v0=equation + replace v0="EQUATION" in `headRow' + order v0 + replace v1=variable if variable~="" + } + else { + replace v1=equation + replace v1="EQUATION" in `headRow' + } + } + drop rowmiss + + * strips the redundant equation names + * must be undone at the insheet that recall this file in appendFile + + count if equation~="" + if `r(N)'~=0 { + *** for one column option + replace v0="" if top=="" & v0~="EQUATION" + } + + drop id1 equation variable top + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + outsheet `using', nonames `quote' `comma' replace + + + + *** clean up labels + if "`label'"=="label" | "`labelOption'"=="insert" { + /* + local dotloc = index("`bname'", ".") + if `dotloc'!=0 { + /* deal w/time series prefixes */ + local tspref = substr("`bname'",1,`dotloc') + local bname = substr("`bname'",`dotloc'+1,.) + local blabel : var label `bname' + local blabel = `"`tspref' `blabel'"' + } + else { + local blabel : var label `bname' + } + */ + + ren v1 var1 + gen `id2'=_n + + * skip merging process if no label was contained + if `emptyLabel'==1 { + gen str8 labels="" + } + else { + joinby var1 using `"`labelfile'"', unmatched(master) + drop _merge + } + + sort `id2' + drop `id2' + order var1 labels + cap order v0 var1 labels + + replace labels="LABELS" in `headRow' + ren var1 v1 + } + + + + *** (re)attaches titles + if "`notitle'"=="" { + if `"`title'"'=="" { + * NOTE: v0- saved here + tempfile appending + tempvar tomato potato + gen `tomato' =_n+10000 + save `"`appending'"',replace + + *** Clean up titles + * just coef, no label, no equation + cap confirm file `titlefile' + if !_rc { + use `titlefile',clear + + *gen `id3'=1 if v1=="VARIABLES" + *gen `id3'=1 if v1==`"`VARIABLES1'"' + * find the top empty row + gen rowmiss=0 + foreach var of varlist v* { + replace rowmiss=rowmiss+1 if `var'~="" + } + replace rowmiss=0 if rowmiss[_n-1]==0 + + gen `id3'=1 if rowmiss[_n+1]==0 + replace `id3'=1 if `id3'[_n-1]==1 + + drop rowmiss + drop if `id3'==1 + keep if v1~="" + + local N=_N + if `N'~=0 { + keep v1 + gen `potato'=_n + local titleWide=_N + joinby v1 using `"`appending'"', unmatched(both) + sort `potato' `tomato' + drop _merge `potato' `tomato' + aorder + } + else { + use `"`appending'"',replace + drop `tomato' + } + } + cap drop `tomato' + + * reorder again + cap order v1 labels + cap order v0 v1 labels + } + else { + * parse title + partxtl2 `"`title'"' + local titleWide = `r(numtxt)' + local t = 1 + while `t'<=`titleWide' { + local titl`t' `r(txt`t')' + local t = `t'+1 + } + + local oldN=_N + set obs `=`r(numtxt)'+_N' + gen `id4'=_n+10000 + forval num=1/`r(numtxt)' { + replace v1="`r(txt`num')'" in `=`oldN'+`num'' + replace `id4'=`num' in `=`oldN'+`num'' + } + sort `id4' + drop `id4' + } + + if "`titleWide'"=="" { + local titleWide=0 + } + } + + * problem spot + sleep `slow' /* wait 1000 ms = 1 second before trying again */ + outsheet `using', nonames `quote' `comma' replace + + c_local bottomRow `bottomRow' + c_local headRow `headRow' + c_local titleWide `titleWide' + +end /* cleanFile */ + + +******************************************************************************************** + + +* chewfile version 1.0.1 17Aug2009 by roywada@hotmail.com +* borrowed on 17Aug2009 +program define _chewfile +version 8.0 + +syntax using/, [save(string) begin(numlist max=1) end(string) clear parse(string) replace semiclear] + +if `"`parse'"'=="" { + local parse `"`=char(9)'"' +} + +if "`begin'"=="" { + local begin 1 +} + +if "`end'"=="" { + local end . +} + +if "`clear'"=="" & `"`save'"'=="" { + if "`semiclear'"=="" { + noi di in red "must specify {opt clear} or {opt save( )} + exit 198 + } +} + +if "`semiclear'"=="semiclear" { + qui drop * + qui set obs 0 +} +else if "`clear'"=="clear" { + clear + qui set obs 0 +} + +if `"`save'"'=="" { + tempfile dump + local save `dump' +} + +tempname fh outout +local linenum = 0 +file open `fh' using `"`using'"', read + +qui file open `outout' using `"`save'"', write `replace' + +file read `fh' line + +while r(eof)==0 { + local linenum = `linenum' + 1 + local addedRow 0 + if `linenum'>=`begin' & `linenum'<=`end' { + if `addedRow'==0 { + qui set obs `=`=_N'+1' + } + + *display %4.0f `linenum' _asis `"`macval(line)'"' + file write `outout' `"`macval(line)'"' _n + + if "`clear'"=="clear" | "`semiclear'"=="semiclear" { + tokenize `"`macval(line)'"', parse(`"`parse'"') + local num 1 + local colnum 1 + while "``num''"~="" { + local needOneMore 0 + if `"``num''"'~=`"`parse'"' { + cap gen str3 var`colnum'="" + cap replace var`colnum'="``num''" in `linenum' + if _rc~=0 { + qui set obs `=`=_N'+1' + cap replace var`colnum'="``num''" in `linenum' + local addedRow 1 + } + *local colnum=`colnum'+1 + } + else { + cap gen str3 var`colnum'="" + local colnum=`colnum'+1 + } + local num=`num'+1 + } + } + } + file read `fh' line +} + +file close `fh' +file close `outout' +end + + +******************************************************************************************** + + +* cdout 1.0.1 Apr2009 by roywada@hotmail.com +* opens the current directory for your viewing pleasure + +* the following disabled 14oct2009: cap winexec cmd /c start . +* modified on 21oct2009: +* displays "dir" instead of cdout or the folder location +* cont option + +program define _cdout +cap version 7.0 + +syntax, [cont] + +if "`cont'"=="cont" { + local _c "_c" +} + + +*cap winexec cmd /c start . +*cap !start cmd /c start . + +if _rc~=0 { + * version 6 or earlier + di `"{stata `"cdout"':dir}"' `_c' +} +else { + * invisible to Stata 7 + local Version7 + local Version7 `c(stata_version)' + + if "`Version7'"=="" { + * it is version 7 or earlier + di `"{stata `"cdout"':dir}"' `_c' + } + else if `Version7'>=8.0 { + version 8.0 + di `"{browse `"`c(pwd)'"' :dir}"' `_c' + } +} + +if "`cont'"=="cont" { + di in white `" : "' _c +} + +end + + +******************************************************************************************** + +* oct2009 +* parse tex( ) options +prog define _texout_parse + version 7 + syntax, [FRagment NOPRetty PRetty Landscape] + c_local texopts "`fragment' `nopretty' `pretty' `landscape'" +end + + + +******************************************************************************************** + + +* oct2009 +* parse stats( ) options +prog define _stats_check + + * note: it will not prevent illegal options from entering (dumped into * `options') & allows multiple entry to be handled + * note: must be all lower case + + version 7 + + syntax, [coef se tstat pval ci aster blank beta ci_low ci_high /* + */ n sum_w mean var sd SKEWness KURTosis sum min max p1 p5 p10 p25 p50 p75 p90 p95 p99 corr pwcorr spearman *] + + c_local sumAsked "" + if `"`n'`sum_w'`mean'`var'`sd'`min'`max'`sum'"'~="" { + c_local sumAsked regular + } + if `"`skewness'`kurtosis'`p1'`p5'`p10'`p25'`p50'`p75'`p90'`p95'`p99'"'~="" { + c_local sumAsked detail + } + + + foreach var in corr pwcorr spearman { + c_local `var'Asked "" + if `"``var''"'~="" { + c_local `var'Asked `var' + } + } + +end + + +******************************************************************************************** + + +* oct2009 +* parse cmd( ), str( ), and r( ) from the contents of stats( ) option +prog define _stats_parse + + version 7 + + syntax, [cmd(str asis) str(str asis) r(str asis)] + +end + + +******************************************************************************************** + + +* 03nov2009 +prog define versionSet + * sends back the version as c_local + version 7.0 + + * invisible to Stata 7 + cap local Version7 `c(stata_version)' + c_local Version7 `Version7' + + if "`Version7'"=="" { + * it is version 7 + c_local version 7 + } + else if `Version7'>=8.2 { + version 8.2 + c_local version 8.2 + } + + if "`Version7'"=="" { + c_local bind "" + } + else { + c_local bind "bind" + } + +end + + +******************************************************************************************** + + +* 15nov2009 +prog define eretSet, eclass + versionSet + version `version' + + syntax varlist + cap reg `varlist' + if _rc==0 { + marksample touse + tempname ebmat eVmat + + mat `ebmat'=e(b) + mat `eVmat'=e(V) + + gettoken depvar rest: varlist + + if "`Version7'"=="" { + est mat b `ebmat' + est mat V `eVmat' + + count if `touse'==1 + est scalar N = r(N) + } + else { + tempvar sample + local N=e(N) + local depvar=e(depvar) + gen `sample'=e(sample) + eret clear + eret post `ebmat' `eVmat', e(`sample') + eret local depvar `"`depvar'"' + eret scalar N = `N' + } + } +end + +exit + +************* e(b) and e(V) in eretSet disabled +`tfmt typo corrected + + diff --git a/Modules/ado/plus/o/outreg2.hlp b/Modules/ado/plus/o/outreg2.hlp new file mode 100644 index 0000000..203472f --- /dev/null +++ b/Modules/ado/plus/o/outreg2.hlp @@ -0,0 +1,1124 @@ +{smcl} +{* 14nov2009}{...} +{cmd:help outreg2} + +{hline} + +{title:Title} + +{p2colset 5 16 22 2}{...} +{p2col :{hi: outreg2} {hline 2}}Arrange regression, summary, and tabulation outputs into an illustrative table{p_end} +{p2colset 5 16 22 2}{...} +{p2col :{hi: {help seeout}} {hline 2}}Opens a tab-delimited table in the data browser{p_end} +{p2colset 5 18 24 2}{...} +{p2col :{hi: {help shellout}} {hline 2}}Opens documents and their programs from inside Stata{p_end} + + +{title:Examples} + + {help outreg2##s_0:0. Basic game plan} {help outreg2##s_11:11. Marginal Effects} + {help outreg2##s_1:1. Prefix and bys( )} {help outreg2##s_12:12. Word or Excel files} + {help outreg2##s_2:2. Running loops} {help outreg2##s_13:13. TeX files} + {help outreg2##s_3:3. Stored estimates} {help outreg2##s_14:14. Adding column titles or notes} + {help outreg2##s_4:4. Shorthand} {help outreg2##s_15:15. n-way cross-tabulation} + {help outreg2##s_5:5. Decimal places} {help outreg2##s_16:16. Group summary table} + {help outreg2##s_6:6. Sideway display} {help outreg2##s_17:17. Fixed effects or legends} + {help outreg2##s_7:7. Summary tables} {help outreg2##s_18:18. Insert r-class cmd( ) outputs} + {help outreg2##s_8:8. Drop/keep/order variables} + {help outreg2##s_9:9. Adding r( ) e( ) scalars} + {help outreg2##s_10:10. Odds ratios and rrr} + +{p 4 4 6}{help outreg2##s_Differences:Different versions of {cmdab:outreg} and {cmdab:outreg2}} + +{p2colreset}{...} + +{hline} + +{marker s_Description} +{title:Description} + +{p 4 4 6} +{cmd:outreg2} provides a fast and easy way to produce an illustrative table +of regression outputs. The regression outputs are produced piecemeal and are +difficult to compare without some type of rearrangement. {cmd:outreg2} +automates this process by concatenating the successive regression ouputs in a +vertical format. The resulting table is saved to the disk in ASCII +format, which can be read by other programs. + +{p 4 4 6} +{cmd:outreg2} thus facilitates the convertion of regression outputs to a standard +format suitable for inclusion in a scholarly publication. The functionality of outreg2 +is based on the earlier package {help cmd:outreg}, by John Gallup. {help outreg2##s_Differences:Unlike} +{cmd:outreg}, {cmd:outreg2} is capable of writing LaTeX-format tables, as well as ASCII, MS Word +and MS Excel. + +{p 4 4 6} +{cmd:outreg2} can report any regression output, provided it conforms to +{it:the} {it:usual} {it:convention} for {help ereturn:ereturn list}. This includes +most regression commands in Stata 7 or later. {cmd:outreg2} will report the latest regression output +by default, or the list of {help estimates:stored estimates}. The ancillary statistics from from stored +{help return} can also be accessed using {opt e( )} or {opt adds:tat( )}. + +{p 4 4 6} +{cmd:outreg2} will also report the usual statistics such as standard error with the asterisks for the levels of +significance (1%, 5%, and 10%), t-statistics, p-values, the number of observations, +R-squareds, and the number of groups in a panel estimation. Standarized beta +coefficients, exponentially transformed coefficients (i.e. odds/risk ratios +or hazard rate). The user can add their own column titles with {opt ct:itle} and {opt addn:ote} options. + +{p 4 4 6} +An immediate access to the produced table is provided in the browser view with +{opt see} option. {cmd:outreg2} also comes with automatically formatted number of +significant digits, which avoids the awkward displays assoicated with the fixed +format. + + +{hline} + +{marker s_Syntax} +{title:Syntax} + +{synopt: Full syntax:}{p_end} + +{p 6 8 6} +{cmdab:outreg2} [{varlist}] [{cmd:[}{help estimates:{it:estlist}}{cmd:]}] +{helpb using} {it:filename} [{cmd:,} {it:options}] [{cmd::} {help estimation commands:{it:command}}] {p_end} + +{synopt: Shorthand:}{p_end} + +{p 6 8 6} +{cmdab:outreg2} [{varlist}] [{cmd:[}{help estimates:{it:estlist}}{cmd:]}] +[{cmd:,} replace seeout] +[{cmd::} {help estimation commands:{it:command}}] {p_end} + +{p 4 4 6} +where {it:command} takes one of {help estimation commands}. The shorthand works +only after a full syntax has been invoked.{p_end} + +{p 4 6 2} +Note that {it:filename} must be enclosed within double quotes if it contains embedded spaces.{p_end} + + +{marker s_Options} +{title:Options} + +{dlgtab:Main} + +{phang}{opt replace} create a new file or overwrite the existing file.{p_end} + +{phang}{opt see:out} display the regression table in the browser.{p_end} + +{phang}{opt lab:el} replace variable names with variable labels.{p_end} + +{phang}{cmd:label(insert)} insert labels next to variable names.{p_end} + +{phang}{opt side:way} specify sideway display (with standard error next to coefficient). Use {opt paren( )} +or {opt noparen} to control the location of parentheses.{p_end} + +{phang}{opt o:necol} specify one column to display multiple equations. The default is one +equation per column with the equation names separate from the variable names.{p_end} + +{phang}{opt long} interweave the equation names into the same column +with the variable names column. Combine it with {opt text} if you want a converted +file in the text format as well. {p_end} + +{phang}{opt ti:tle(list)} titles for your table; comma separated; use quotes for commas within a title. +Titles can be added at any time. To erase your title, encase a space between quotes like this: title(" "){p_end} + +{phang}{opt ct:itle(list)} column titles; comma separated for each additonal row; use quotes if comma is part of title. +Example: ctitle("Wage, Participation","Wage: Participation"). To specify empty column title, specify +ctitle(" ").{p_end} + +{phang}{opt cttop(list)} place additonal column titles on the top; comma separated, use quotes for multiple column titles.{p_end} + +{phang}{opt addn:ote(list)} add your own notes at the bottom. Must be specified in the first {cmd:outreg2} +call when regression results are appended together. A blank line can be inserted by including "" as a note.{p_end} + +{phang}{opt nonot:es} specifies that notes and legends explaining the standard errors, asterisks, etc., not be included.{p_end} + + +{dlgtab:Output Files} + +{phang}{opt word} produces rich text file (rft) compatible with {cmd:MS Word}. The file conversion can be +specified at any time (you should do it with the last appedning). The existing file must not be open for +it to be written over.{p_end} + +{phang}{opt excel} specifies an xml, xls, xlm, or cvs file compatible with a standard spreadsheet +like {cmd:MS Excel}. Any existing file with the same name must be closed to have it +replace with a new file.{p_end} + +{phang}{opt text} produces plain text file exactly. {opt long} or {opt label} will +sometimes cause the main output text file to be different from what might be +expected. Use this option to obtain exactly specified text file.{p_end} + +{phang}{opt tex} produces a stand-alone LaTeX compatible files suitable for loading into a TeX typesetting program +such as Scientific Word.{p_end} + +{phang}{cmd:tex( )} takes the following options for tex:{p_end} + +{p 8} {cmd:{ul:frag}}ment - a TeX fragment for inclusion in a larger document{p_end} +{p 8} {cmd:{ul:pr}}etty - with some italics and varying font sizes{p_end} +{p 8} {cmd:{ul:land}}scape - horizontally{p_end} + +{phang}{opt quote} specifies quotation marks to encase each observation, which can +be helpful for reading the output file in other software. See the {opt noquote} +option in {help outsheet} for more details (all the output of {cmd:outreg2} comes +from string variables). {opt quote} may cause problems appending tables together. {p_end} + +{phang}{opt comma} specifies that the ASCII file output be separated by commas +rather than by tabs. This can cause problems if any of the user-defined text has +commas in it (such as variable labels, {opt ct:itle}, {opt adds:tat}, or +{opt addn:ote}). If that is the case, consider using {opt quote} as well. {p_end} + + +{dlgtab:Auxiliary Statistics (for each variable)} + +{phang}{opt st:ats( )} contains statistics to be reported per variable, the default is +{cmd:stats(coef se)}. Space- or comma-delimited. Restricted to the estimation sample (single equation). Choose +in any order or frequency from these: + + {ul:regression} + coef se tstat pval ci ci_low + ci_high aster beta + + {ul:summary} + N sum_w mean Var sd sum + min max skewness kurtosis p1 p5 + p10 p25 p50 p75 p90 p95 + p99 + + {ul:correlations} + corr pwcorr spearman + + {ul:string} + blank + str({it:str}) where {it:str} is any string or numeric expression + + {ul:command} + cmd({it:macro}:{it:cmd}) where {it:macro} is to be produced by any {help outreg2##s_18:{it:cmd}} + cmd({it:r( )}:{it:cmd}) where {it:r( )} is to be produced by any r-class {help outreg2##s_18:{it:cmd}} + + +{phang}{opt nose} specifies no standard error; only coefficients are reported {p_end} + +{phang}{opt l:evel(integer)} specifies the confidence level, in percent, for +confidence intervals. The default is {opt level(95)} or as set by {help set level}, +{opt l:evel} does not affect the confidence levels of asterisks. {p_end} + +{phang}{opt ef:orm} the exponentiated form of the coefficients be reported. This corresponds to {opt or} option for +{help logit}, {help clogit}, and {help glogit} estimation, {opt irr} for {help poisson} estimation, {opt rrr} +for {help mlogit}, {opt hr} for {help cox} and {help stcox} hazard models, and +{opt eform} for {help xtgee}. The default form of {help stcox} is the hazard rate form; use the {opt eform} to report it. {p_end} + +{phang}{opt nocon:s} specifies that the intercept (constant) be not reported.{p_end} + +{phang}{opt noni} specifies that the number of groups in a panel data regression +not be reported (e.g. the number of groups specified by the i( ) variable in {help xtreg}).{p_end} + + +{phang}{ul:Assuming only 2 statistics reported per variable:}{p_end} + +{phang}{opt tstat} t-statistics rather than standard errors are reported. The decimal places displayed are set +by {opt auto( )} or {opt tdec}.{p_end} + +{phang}{opt pvalue} specifies that p-values (of t-statistics) rather than +standard errors are reported. The decimal places displayed are set by {opt auto( )} or {opt pdec}. {p_end} + +{phang}{opt ci} specifies that confidence intervals of coefficients rather than +standard error are reported. The decimal places displayed are those set by {opt auto( )} or {opt cdec}. {p_end} + +{phang}{opt be:ta} asks that normalized beta coefficients be reported rather than +standard errors (see the beta option of {help regress}). The decimal places +displayed are those set by {opt auto( )} or {opt bdec}.{p_end} + + +{dlgtab:Ancillary Statistics (for each regression)} + +{phang}{help ereturn:{opt e(scalars)} }report {help ereturn:e-class scalars} at the bottom of the table. +They may be requested individually, as in {cmd:e(N ll r2)}, or for all, by specifying {cmd:e(all)}. +The reported e-class statistics are automatically formated by auto-digits, unless {opt ade:c} +has been specified for it. {p_end} + +{phang}{opt adds:tat(list)} access {help ereturns:e-class}, {help return:r-class}, {help sreturn:s-class} +scalar statistics, or just plain numbers in new rows below the R-squared (if shown). Comma separted. +The user must specify both a name and a value for the statistic. Users can report significance levels +of test statistics as a second statistic to be shown on the line below the first statistic +(see example below). {p_end} + +{phang}{opt addtext(list)} specifies user-added text (including +numbers) to be displayed in new lines below the R-squared (if shown). Unlike {opt adds:tat}, +{opt addt:ext} will not format numbers nor try to interpret any e-class text (such as e(N) or e(title), which +{opt adds:tat} will translate into the number of observations or title). {p_end} + +{phang}{opt nor:2} specifies that no R-squared (or adjusted R-squared) be reported.{p_end} + +{phang}{opt ad:jr2} specifies that the adjusted R-squared be reported rather than the regular R-squared +when available.{p_end} + +{phang}{opt noobs} specifies no number of observations is to be reported.{p_end} + + +{dlgtab:Equations and Variables} + +{phang}{opt drop(varlist)} Do not report these variables. Do not include the dependent variable in this list.{p_end} + +{phang}{opt keep(varlist)} Keep and report these variables. {p_end} + +{phang}{opt eqdrop(eqlist)} Drop these equations from the table {p_end} + +{phang}{opt eqkeep(eqlist)} Keep and report these equations. {p_end} + +{phang}{opt sortvar(varlist)} Sort and order variables; non-existent variable names are ignored.{p_end} + +{phang}{opt groupvar(names)} Sort and order variable; non-existent names are inserted as super-rows or row-heading.{p_end} + + +{dlgtab:Displays} + +{phang}{opt par:enthesis( )} specifies parenthesis ( ) to be placed around any/many of these: +coef se tstat pval ci ci_low ci_high aster blank. Can be used with {opt br:acket( )}.{p_end} + +{phang}{opt nopa:ren} specifies no parentheses be placed around standard +errors, t-statistics, standard errors, etc. {p_end} + +{phang}{opt br:acket} specifies square brackets [ ] be used rather than +parentheses ( ) around standard errors, t-statistics, etc. {p_end} + +{phang}{opt br:acket( )} specifies square brackets [ ] to be placed around any/many of these: +of these: coef se tstat pval ci ci_low ci_high aster blank. Can be used with {opt par:enthesis( )}.{p_end} + +{phang}{opt alpha(numlist)} specifies the levels of significance, separated by comma +from the most significant to the least signficiant. Example: {opt alpha(0.001, 0.01, 0.05)}. Up to 3 are automatically +assigned asterisks. If more than 3 levels are defined, then the symbols must be specified with {opt sym:bol(text)}. {p_end} + +{phang}{opt sym:bol(text)} specifies symbols for the levels of significance from the most significant +to the least significant, the default {opt sym:bol(***, **, *)}.{p_end} + +{p 8 8 12}They will assigned the significance levels of 0.01, 0.05, and 0.10 +automatically in that order. If more than 3 symbols are assigned, then the same number of levels of significance must be specified using +{opt alpha}.{p_end} + +{phang}{opt aster:isk( )} specifies asterisks to be placed around some +of these: coef se tstat pval ci ci_low ci_high blank. {p_end} + +{phang}{opt noas:ter} no asterisks denoting statistical significance +levels be reported. {p_end} + +{phang}{opt 2aster} specifies 2 asterisks for 1% and 1 asterisk for 5%. +The default is 3 asterisks for 1%, 2 asterisks for 5%, and 1 asterisk for 10%. {p_end} + +{phang}{opt 10pct} equivalent to {opt sym:bol(**, *, +)}{p_end} + + +{dlgtab:Decimals and Formats} + +{phang}{opt auto(integer)} the number of automatically formatted decimals, the default is {cmd:auto(3)}, +i.e. three significant digits not counting the ones (i.e. the digit to the left of the decimal point). +This means 1.234 and 0.123 might be displayed, while 12.345 or 0.1234 will be trimmed. + +{p 8 8 12}A probable integer is reported without decimals. A very large or small number will be displayed in +exponential format. Specify {opt dec( )} or {opt bd:ec( )} to disable it. {p_end} + +{phang}{opt less(integer)} specifies how many less significant digits to be +displayed for the auxiliary (non-coefficient) statistics. The default is {cmd:less(0)}, meaning no less.{p_end} + + +{phang}{ul:fixed decimals}{p_end} + +{p 8}{opt dec(#)} fixed decimals for everything, default dec(3){p_end} + +{p 11} between 0 and 11, inclusive{p_end} + +{p 8}{opt bd:ec( )} for coefficient{p_end} +{p 8}{opt sd:ec( )} for standard error{p_end} +{p 8}{opt td:ec( )} for t-statistics{p_end} +{p 8}{opt pd:ec( )} for p-value{p_end} +{p 8}{opt cd:ec( )} for confidence intervals{p_end} +{p 8}{opt rd:ec( )} for r-square{p_end} +{p 8}{opt ad:ec( )} for addstat( ) numerals{p_end} + + +{phang}{ul:fixed format}{p_end} + +{p 8}{opt fmt(type)} format for everything, default fmt(fc){p_end} + +{p 11} e - scientific notation; e.g. 1.00e+3 {p_end} +{p 11} f or fc - fixed format (with commas for thousands with fc){p_end} +{p 11} g or gc - general format (with commas for thousands with gc) + +{p 8}{opt bf:mt( )} coefficient{p_end} +{p 8}{opt sf:mt( )} standard error{p_end} +{p 8}{opt tf:mt( )} t-statistics{p_end} +{p 8}{opt pf:mt( )} p-value{p_end} +{p 8}{opt cf:mt( )} confidence intervals{p_end} +{p 8}{opt rf:mt( )} r-square{p_end} +{p 8}{opt af:mt( )} addstat( ) numerals{p_end} + + +{dlgtab:Marginal effects} + +{phang}{opt mfx} reports marginal effects as computed by {help mfx}. It will reported marginal +effects instead of estiamted coefficients. {p_end} + +{phang}{opt m:argin(u|c|p)} the unconditional, conditional, and probability marginal +effects for {help truncreg}, {net_d:marginal} from STB 52, or {net_d:dtobit} from STB 56. +One of u, c, or p is required after {net_d:dtobit}, corresponding to the unconditional, +conditional, and probability marginal effects, respectively. It is not necessary to specify +{opt margin} after {help dprobit}, {net_d:dlogit2}, {net_d:dprobit2}, or {net_d:dmlogit2}.{p_end} + + +{dlgtab:Summary Statistics} + +{phang}{opt sum} summary be reported after a regression command, restricted to the estimation sample, i.e. e(sample)==1, +unless no regress exists or {opt raw} option specified. This is the same as {cmd:stats(mean sd)}.{p_end} + +{phang}{opt raw} do not restrict the sample to e(sample) or perform casewise dropping. Currently works only with sum. +The number of observation reported is the maximum.{p_end} + +{phang}{opt sum(log)} summary table just like the one from log file. Default is raw (no casewise dropping). +Use eqdrop() or eqkeep() to get what you want.{p_end} + +{phang}{opt sum(detail)} detailed summary table. Default is raw (no casewise dropping). +Use eqdrop() or eqkeep() to get what you want.{p_end} + + +{dlgtab:Tabulations} + +{phang}{opt cross:tab} n-way cross-tabulation. Varlist is required. The first +variable must be counting numbers, i.e. 0, 1, 2, etc., and the rest must be non-strings. See {help outreg2##s_15:example} below. {p_end} + + +{dlgtab:Rarely Used} + +{phang}{opt slow(#)} A milli-second delay. Specify slow(100) or larger if you are using a laptop with a throttled +harddrive that runs too slowly, causing "could not be openend r(603)" error.{p_end} + + +{hline} + +{marker s_0} +{title:Example 0. Basic game plan} + +{p 4 4 6}You should specify the current directory where all the files will be stored. +Alternatively, you can specify the complete pathway from within {cmd:outreg2}, but you must +encase it with quotations marks.{p_end} + +{p 4 4 6}{stata "cd c:\"}{p_end} +{p 4 4 6}{stata sysuse auto,clear}{p_end} +{p 4 4 6}{stata regress mpg foreign weight headroom trunk length turn displacement}{p_end} +{p 4 4 6}{stata outreg2 using myfile, replace cttop(full)}{p_end} +{p 4 4 6}{stata regress mpg foreign weight headroom}{p_end} +{p 4 4 6}{stata outreg2 using myfile, see}{p_end} + +{p 4 4 6}You can immedicately see the changes. The variable "weight" loses some of its significance +in the full specification. The estimated effect of weight can be shown to be downward-biased from +-0.00420 to -0.00647 by omitting a number of covariates. This is an easy way to check for +collinearity and misspecification.{p_end} + +{p 4 4 6}You can use {cmd:e( )} or {cmd:addstat( )} option to augment the standard +regression results with other e-class statistics (scalar only). {cmd:addstat} can handle +r-class and s-class results as well, if they exist. The following codes are equivalent +excpet in appearance.{p_end} + +{p 4 4 6}{stata outreg2 using myfile, e(r2 ll)}{p_end} +{p 4 4 6}{stata outreg2 using myfile, addstat(R-squared by hand, e(r2), Log Lik, e(ll))}{p_end} + +{p 4 4 6}If you want to see everything available in the e-class, do it like this:{p_end} + +{p 4 4 6}{stata outreg2 using myfile, e(all)}{p_end} + + +{marker s_1} +{title:Example 1. Prefix and bys( )} + + +{p 4 4 6}{cmd:outreg2} can be used in as a prfix.{p_end} + +{p 4 4 6}{stata sysuse auto, clear}{p_end} +{p 4 4 6}{stata "outreg2 using myfile, replace ti(Car stuff): reg price mpg weight turn"}{p_end} +{p 4 4 6}{stata "outreg2 using myfile, see excel: reg price mpg weight turn if price > 6100"}{p_end} + +{p 4 4 6}It is also byable with bys( ) prefix.{p_end} + +{p 4 4 6}{stata "bys foreign: outreg2 using myfile, side replace see: reg rep78 head weight gear len [aw=mpg]"}{p_end} + + +{marker s_2} +{title:Example 2. Running loops} + + +{p 4 4 6}Because this involves a loop, you must copy and paste into a do-file: + +{p 4 4 6}sysuse auto,clear{p_end} +{p 4 4 6}cap erase myfile.txt{p_end} +{p 4 4 6}forval num=0/1 {{p_end} +{p 8 8 6}regress mpg weight headroom if foreign==`num'{p_end} +{p 8 8 6}outreg2 using myfile{p_end} +{p 4 4 6}}{p_end} +{p 4 4 6}seeout{p_end} + + +{marker s_3} +{title:Example 3. Stored estimates} + + +{p 4 4 6}You can automatically recall the stored estimates by specifying them from +within {cmd:outreg2}. To distinguish them from the varlist, place the estlist +within a pair of {cmd:[}square brackets{cmd:]}.{p_end} + +{p 4 4 6}{stata sysuse auto,clear}{p_end} +{p 4 4 6}{stata regress mpg foreign weight headroom trunk length turn displacement}{p_end} + +{p 4 4 6}{stata estimates store Full}{p_end} +{p 4 4 6}{stata regress mpg foreign weight headroom}{p_end} + +{p 4 4 6}{stata estimates store Restricted1}{p_end} +{p 4 4 6}{stata regress mpg foreign weight}{p_end} + +{p 4 4 6}{stata estimates store Restricted2}{p_end} +{p 4 4 6}{stata outreg2 [Full Restricted1 Restricted2] using myfile, replace see}{p_end} + +{p 4 4 6}{cmd:outreg2} will take the stored estimates as wildcards (*). Try this: + +{p 4 4 6}{stata outreg2 [*] using myfile, see replace}{p_end} +{p 4 4 6}{stata outreg2 [R*] using myfile, see replace}{p_end} + +{p 4 4 6}The varlist may be combined with the estlist. The varlist will take the +wildcards as well, provided they exist in the estlist.{p_end} + +{p 4 4 6}{stata outreg2 foreign weight [*] using myfile, see replace}{p_end} + +{p 4 4 6}If you are specifying the varlist, you must make certain the desired varlist +exists in all the stored estiamtes. Since not all equations may contain the +specified varlist, it is usually a poor idea to combine the one column option +with the varlist.{p_end} + + +{marker s_4} +{title:Example 4. Shorthand} + + +{p 4 4 6}{cmd:outreg2} will remeber the last set of options you specified until the end of +the day. The stored command will expire at mid-night to prevent the possible +loss of finished table by inadvertantly writing over a finished file. The +following shorthand should be tried separately.{p_end} + +{p 4 4 6}{stata outreg2}{p_end} +{p 4 4 6}{stata outreg2, replace}{p_end} +{p 4 4 6}{stata outreg2, seeout}{p_end} + +{p 4 4 6}The following two options are excluded from the stored command: +seeout and replace. These two must be specified each time you invoke {cmd:outreg2} +through the shorthand. To change the stored options, you must invoke the full +syntax with the specified using file (i.e. outreg2 using myfile, etc). The varlist +and the stored estimates names are not stored with the command.{p_end} + +{p 4 4 6}For someone who is in a hurry, {cmd:outreg2} will take the following syntax, provided +the desired options have been stored by invoking them in the full syntax. The +varlist and/or the estlist are still allowed under this syntax. This +pre-command syntax is made available for the benefit of iterative users.{p_end} + +{p 4 4 6}{stata "outreg2 : reg mpg foreign weight headroom"}{p_end} +{p 4 4 6}{stata "outreg2, replace : reg mpg foreign weight headroom"}{p_end} +{p 4 4 6}{stata outreg2}{p_end} +{p 4 4 6}{stata seeout}{p_end} + + +{marker s_5} +{title:Example 5. Decimal places} + + +{p 4 4 6}By default the regression coefficients are shown with auto-digits, +but a user may wish to specify their own number of decimals places. We could use +the option dec(5) to display 5 decimal places for all statistics or bdec(5) +for just the coefficient, sdec(5) just for standard error, etc.{p_end} + +{p 4 4 6}{stata outreg2 using myfile, replace auto(4)}{p_end} +{p 4 4 6}{stata outreg2 using myfile, dec(5)}{p_end} +{p 4 4 6}{stata outreg2 using myfile, bdec(5) bfmt(f) sdec(7) sfmt(e) see}{p_end} + + +{marker s_6} +{title:Example 6. Sideway display} + +{p 4 4 6}Medical journals often requires the displays to go sideways. Use {opt side:way} to make this +happen. {opt side:way} is compatible with {opt st:ats( )}. + +{p 4 4 6}{stata outreg2 using myfile, sideway stats(coef aster se) noparen bdec(3) replace}{p_end} + +{p 4 4 6}Note the above code is equivalent to building the table one column at a time like this:{p_end} + +{p 4 4 6}{stata outreg2 using myfile, stats(coef) replace noparen bdec(3)}{p_end} +{p 4 4 6}{stata outreg2 using myfile, stats(aster) noparen bdec(3)}{p_end} +{p 4 4 6}{stata outreg2 using myfile, stats(se) noparen bdec(3)}{p_end} + +{p 4 4 6}Some journals often prefer t-statistics to standard errors +and don't use asterisks to denote statistical significance. Some people use brackets. The +title( ) option requires quotation marks when it contains a comma. Note that {opt bdec} decimal +option apply to both the coefficients and the standard errors.{p_end} + +{p 4 4 6}{stata regress mpg foreign weight}{p_end} +{p 4 4 6}{stata outreg2 using myfile, tstat bracket noaster title("No standard errors!")}{p_end} +{p 4 4 6}{stata seeout}{p_end} + + +{marker s_7} +{title:Example 7. Summary tables} + +{p 4 4 6}Use {opt sum} to place summary statistics into a table. The sample mean and the standard +deviation for the sample used in the earlier regression will be automatically displayed. + +{p 4 4 6}* After estimation{p_end} +{p 4 4 6}{stata sysuse auto, clear}{p_end} +{p 4 4 6}{stata reg mpg price rep weight length}{p_end} +{p 4 4 6}{stata outreg2 using myfile, sum replace}{p_end} +{p 4 4 6}{stata outreg2 using myfile, see}{p_end} + +{p 4 4 6}* Regular summary table{p_end} +{p 4 4 6}* note: version 11 and above requires clear* to prevent mismatch between e(b) and e(sample){p_end} +{p 4 4 6}{stata clear*}{p_end} +{p 4 4 6}{stata sysuse auto, clear}{p_end} +{p 4 4 6}{stata outreg2 using myfile, sum(log) replace eqdrop(N mean) see}{p_end} +{p 4 4 6}{stata outreg2 using myfile, sum(detail) replace eqkeep(N max min) see}{p_end} +{p 4 4 6}{stata outreg2 using myfile, sum(detail) replace see}{p_end} + + +{marker s_8} +{title:Example 8. Drop/keep/order variables} + + +{p 4 4 6}Specifying a varlist can be convenient to limit the output +table to only the essential coefficients. For example, we may want to control for +the influence of dummy variables, but not report their estimated coefficients.{p_end} + +{p 4 4 6}{stata sysuse auto, clear}{p_end} +{p 4 4 6}{stata tab rep78, gen(repair)}{p_end} +{p 4 4 6}{stata regress mpg foreign weight repair1-repair4}{p_end} +{p 4 4 6}{stata outreg2 weight foreign using myfile, drop(repair*)}{p_end} + +{p 4 4 6}Alternatively, {opt keep( )} and {opt drop( )} can be used to control the displayed +variables. Use {opt nocons} to drop constants. + +{p 4 4 6}{stata outreg2 using myfile, drop(repair*) replace}{p_end} +{p 4 4 6}{stata outreg2 using myfile, keep(mpg foreign)}{p_end} +{p 4 4 6}{stata outreg2 using myfile, nocons}{p_end} +{p 4 4 6}{stata seeout}{p_end} + +{p 4 4 6}There are several ways to order variables in the output. The first is +to order them when running regression. The second way is to specify varlist +from within {cmd:outreg2}. Or you might try {opt sortvar( )} or {opt groupvar( )}.{p_end} + +{p 4 4 6}* single equation{p_end} +{p 4 4 6}{stata reg mpg rep78 head trunk weight}{p_end} +{p 4 4 6}{stata outreg2 using myfile, replace sortvar(trunk turn)}{p_end} +{p 4 4 6}{stata reg mpg rep78 head weight turn disp gear}{p_end} +{p 4 4 6}{stata outreg2 using myfile, sortvar(trunk turn) see}{p_end} + +{p 4 4 6}* multiple equations{p_end} +{p 4 4 6}{stata reg3 (mpg rep78 head trunk weight) (head trunk weight rep78 gear)}{p_end} +{p 4 4 6}{stata outreg2 using myfile, replace long}{p_end} +{p 4 4 6}{stata reg3 (mpg rep78 head weight turn disp ) (mpg rep78 head trunk weight gear)}{p_end} +{p 4 4 6}{stata outreg2 using myfile, sortvar(trunk turn) see long}{p_end} + +{p 4 4 6}* groupvar( ) will create super-rows{p_end} +{p 4 4 6}{stata reg mpg rep78 head trunk weight}{p_end} +{p 4 4 6}{stata outreg2 using myfile, replace}{p_end} +{p 4 4 6}{stata reg mpg rep78 head weight turn disp gear}{p_end} +{p 4 4 6}{stata outreg2 using myfile, groupvar(Group1 trunk turn head weight Group2) see}{p_end} + + +{marker s_9} +{title:Example 9. Adding r( ) e( ) scalars} + + +{p 4 4 6}Additional statistics may be added with {opt adds:tat( )} or {opt addt:ext( )}. Values stored in +macros r(), e(), or s() can be included directly. You can see what values are available by typing +{cmd:ereturn list} or {cmd:return list}.{p_end} + +{p 4 4 6}To test the equality of two of the estimated coefficients and report the results in the table, note +that {cmd:test} will sometimes return chi-squared, then you would instead use {opt addstat(chi-square test, r(chi2))}: +{p_end} + +{p 4 4 6}{stata reg mpg foreign weight length}{p_end} +{p 4 4 6}{stata test foreign length}{p_end} +{p 4 4 6}{stata `"outreg2 using myfile, adds("F test: Type=Length=0", r(F), Prob > F, `r(p)') replace"'}{p_end} +{p 4 4 6}{stata seeout} {p_end} + +{p 4 4 6}To add results of lincom postestimation command to a table:{p_end} + +{p 4 4 6}{stata sysuse auto, clear}{p_end} +{p 4 4 6}{stata reg price mpg rep78 head}{p_end} +{p 4 4 6}{stata lincom mpg + rep}{p_end} +{p 4 4 6}{stata local tstat=r(estimate)/r(se)}{p_end} +{p 4 4 6}{stata local pval = tprob(r(df), abs(`tstat'))}{p_end} +{p 4 4 6}{stata outreg2 using "myfile", adds(joint, r(estimate), t-stat, `tstat', p-val,`pval') replace see}{p_end} + +{p 4 4 6}In some cases it is better to save the value of a previously calculated +statistic in a local macro and then put the macro value into {opt adds:tat( )}. Save the first F +statistic in a local macro:{p_end} + +{p 4 4 6}{stata regress mpg rep78 headroom}{p_end} +{p 4 4 6}{stata test rep78}{p_end} +{p 4 4 6}{stata local F1 = r(F)}{p_end} +{p 4 4 6}{stata test headroom}{p_end} +{p 4 4 6}{stata outreg2 using 2test, addstat(Test1 F, `F1', Test2 F, `r(F)')}{p_end} + +{p 4 4 6}It it is missing, {cmd:outreg2} will automatically calculate e(p), which is presumably +the F-test or chi-square-test of significance of a regression.{p_end} + +{p 4 4 6}{stata outreg2 using myfile, addstat(F test, e(p))}{p_end} + +{p 4 4 6}Another example would be to report a pseudo R-squared +after a logit estimation, which {cmd:outreg2} does not otherwise report.{p_end} + +{p 4 4 6}{stata logit foreign price trunk weight}{p_end} +{p 4 4 6}{stata outreg2 using myfile, addstat(Pseudo R-squared, `e(r2_p)')}{p_end} + + +{marker s_10} +{title:Example 10. Odds ratios and exponentials} + + +{p 4 4 6}Odds ratios are exponential transformations of coefficients. As noted above, +there is no way of knowing after an estimation command if the +user chose to report the exponentiated form of coefficients. The user must +choose the {opt eform} option in {cmd:outreg2} to get the same form of the coefficients +displayed by the estimation into the {cmd:outreg2} table.{p_end} + +{p 4 4 6}For duration models, the exponential form is known as the hazard ratio. For +other models it is known as odds ratio, relative risk ratio, or incidence rate +ratio.{p_end} + +{p 4 4 6}{stata sysuse auto,clear}{p_end} +{p 4 4 6}{stata logit foreign price mpg rep78, or}{p_end} +{p 4 4 6}{stata outreg2 using eform_example, replace cti(raw)}{p_end} +{p 4 4 6}{stata outreg2 using eform_example, eform cti(odds ratio) see}{p_end} + + +{marker s_11} +{title:Example 11. Marginal Effects} + +{p 4 4 6}{opt mfx} option can be used to report marginal effects after {help mfx} command +has been applied.{p_end} + +{p 4 4 6}{stata sysuse auto, clear}{p_end} +{p 4 4 6}{stata logit foreign mpg rep78 head}{p_end} +{p 4 4 6}{stata mfx compute}{p_end} +{p 4 4 6}{stata outreg2 using myfile, replace}{p_end} +{p 4 4 6}{stata outreg2 using myfile, mfx ctitle(mfx) see}{p_end} + +{p 4 4 6}For multiple outcomes, you may want to use {cmd:mfx2} by Ricahrd Williams or +{search margeff} by Tamas Bartus. They are both available from {help ssc}. {p_end} + +{p 4 4 6}{stata sysuse auto, clear}{p_end} +{p 4 4 6}{stata mlogit rep turn mpg price}{p_end} +{p 4 4 6}{stata margeff, at(mean) replace}{p_end} +{p 4 4 6}{stata outreg2 using myfile, cttop(margeff) see replace}{p_end} + +{p 4 4 6}{cmd:mfx2} runs a little slower:{p_end} +{p 4 4 6}{stata mlogit rep turn mpg price}{p_end} +{p 4 4 6}{stata mfx2, replace}{p_end} +{p 4 4 6}{stata outreg2 using myfile, long cttop(mfx2) see replace}{p_end} + +{p 4 4 6}The marginal effects reported by {search dprobit}, {net_d:dlogit2}, {net_d:dprobit2}, +and {search dmlogit2} are automatically reported by {cmd:outreg2}.{p_end} + +{p 4 4 6}Because {net_d:truncreg}, {net_d:marginal}, and {net_d:dtobit} report +both regression coefficients and marginal effects, the user must specify the +{opt margin} option for {cmd:outreg2} report the marginal effects.{p_end} + +{p 4 4 6}{search dtobit}, on the other hand, calculates three different marginal effects. +The user must specify which marginal effect, the unconditional, conditional, +or the probability uncensored, to be reported. Note that "version 6" must be set for +{cmd:dtobit} to work.{p_end} + +{p 4 4 6}{stata tobit mpg trunk weight, ll(17)}{p_end} +{p 4 4 6}{stata `"version 6: dtobit"'}{p_end} +{p 4 4 6}{stata outreg2 using myfile, margin(u) ctitle(Unconditional) nor2 replace}{p_end} +{p 4 4 6}{stata outreg2 using myfile, margin(c) ctitle(Conditional) nor2}{p_end} +{p 4 4 6}{stata outreg2 using myfile, margin(p) ctitle(Probability) nor2 see}{p_end} + + +{marker s_12} +{title:Example 12. Word or Excel files} + +{p 4 4 6} +Use {opt word} or {opt excel} for automatic generation of Word/Excel files: + +{p 4 4 6}{stata reg price mpg rep78 headroom trunk weight}{p_end} +{p 4 4 6}{stata outreg2 using myfile, word excel replace}{p_end} + +{p 4 4 6} +Follow these directions for manual conversions from .txt files: + +{p 4 4 6} +In {cmd:MS Word}, open or insert the file created by {cmd:outreg2}. Select the estimation text that +is in columns (not the notes at the bottom of the table or the title at the top, if any), and choose +Table, Convert Text to Table. + +{p 4 4 6}To shift the table within {cmd:MS Word}, highlight the entire table, choose Table +Properties (go the top menu, drag down on the Table option), and then click the alignment as +Left instead of Center. + +{p 4 4 6} +In {cmd:Excel}, open the file created by {cmd:outreg2} and follow the default choices +in the Text Import Wizard (if you do not see the file, choose All Files as the File Type). +Prevent the conversion of the parenthesis into a negative number (an accounting convention) +by doing the following: 1. import it as "Delimited", 2. choose Tab as the Delimiters, and +3. Choose "Text" as Column data format after Highlighting all the columns by shift-down, right-clicking. + +{p 4 4 6}If you wish to export the +.xml table to a word processor, you should separately copy the table and the notes +at the bottom of the table (prevents the notes from taking up too much space). You +can avoid this problem by opening the .txt file manually from inside {cmd:MS Excel}, +as detailed earlier, or copy and paste the notes into another cells in +{cmd:MS Excel}, which will cause them to be displayed properly. + +{p 4 4 6}To get rid of "green tabs" in Excel: From inisde Excel, Tools > Options > Error Checking. +When you get there, uncheck "Number stored as text". No more green triangles. + +{p 4 4 6} +You can also use {cmd:{browse "http://www.stata.com/support/faqs/data/convert2.html":Stat/Transfer}} +if you have one. Choose ASCII-Delimited as the input file and choose {cmd:Excel} +as the output file. You will need to adjust the column widths from inside +{cmd:Excel}. + + +{marker s_13} +{title:Example 13. TeX files} + + +{p 4 4 6} +{cmd:LaTeX} compatible table can be created with {opt tex} option. With the use +of free conversion software, such as MiKTeX, you can create Adobe PDF files of +the finished tables directly within Stata by invoking a shell command. + +{p 4 4 6}{stata regress mpg foreign weight}{p_end} +{p 4 4 6}{stata outreg2 using myfile, tex replace}{p_end} + +{p 4 4 6}{cmd:outreg2's} TeX tables are fully formatted, unlike the ASCII tables. This +requires free TeX to Adobe PDF conversion software, such as the MiKTeX +(www.miktek.org) for Windows or teTeX (www.tug.org/teTeX/) for Unix/Linux. The +whole process is automated in Stata with a shell command:{p_end} + +{p 4 4 6}{stata !texify -p -c -b --run-viewer myfile.tex} {using MiKTeX on Windows){p_end} +{p 4 4 6}{stata !pdflatex myfile} (using teTeX on Linux){p_end} + +{p 4 4 6}{cmd:outreg2} cannot append TeX format tables to one another, so regressions must be +appended in ASCII form until the last regression, which is appended with the +{opt tex} option.{_end} + +{p 4 4 6}The base font point size of tex in a TeX table can be specified with the {opt tex()} +parameter. TeX only allows font sizes of 10 and 11 points besides the default +of 12 point. The {opt texfrag} option creates a TeX fragment for inclusion in a larger +TeX document. For example, a TeX fragment table from the first regression above could be created with + +{p 4 4 6}{stata outreg2 using myfile, tex(frag)}{p_end} + +{p 4 4 6}and then be included in the following TeX document with the \input{myfile} +command:{p_end} + + \documentclass[10pt]{article} + \begin{document} + ... text before inclusion of table myfile.tex ... + \input{myfile} + ... text after inclusion of table myfile.tex ... + \end{document} + + +{p 4 4 6}Technical Note: Many of the non-alphanumeric characters have special meaning +in TeX, namely _, %, #, $, &, ~, ^^, \, {, }. If you want these characters to +be printed in TeX like any other character, include a \ in front of the +character. {cmd:outreg2} automatically does this for the first two, _ and %, +because _ often turns up in Stata variable names and % is common in variable +labels and explanatory notes. You can include the other characters in titles, +variable labels, or notes if you preceed them with with a \ in the Stata text. +The exception is \ itself; \ must be replaced with $\backslash$ to render +properly in TeX.{p_end} + +{p 4 4 6}In addition, in TeX the characters <, >, and | will only appear as themselves +in math mode, so they must be written as $<$, $>$, and $|$.{p_end} + +{p 4 4 6}TeX codes can be inserted into {cmd:outeg2} titles, variable labels, and added +notes. This requires understanding TeX formatting codes. The example below +creates a Greek letter chi with a squared exponent for a chi-squared test +statistic.{p_end} + +{phang2}{stata outreg2 using myfile0, addstat($\chi^2$, 22.1) tex}{p_end} + +{p 4 4 6}I said above that {cmd:outreg2} automatically converted _ to \_. An exception is +when it finds two $'s in the text, in which case it assumes the _ is a +subscript designator in a TeX inline equation. That means that if you want to +add text that includes an inline equation, but you really want the _ to appear +as such in the TeX table, you must replace it with a \_.{p_end} + +{p 4 4 6}Be careful when using $. When $ is immediately followed by a letter, Stata +will interpret this as a global macro. To get Stata to output a literal $, +precede it with "\": \$. If you want, for example, a properly TeX typeset +R-squared to survive in {cmd:outreg2}, rather than "$R^2$" you must use "\$R^2$". +$R would be evaluated by {cmd:outreg2} as the value of global macro R, which is +probably empty.{p_end} + +{p 4 4 6}Putting a literal "$" in TeX output can be confusing: to get "$US" in the TeX +output, for example, one needs "\$US" in the TeX input file, which requires +"\\\$US" in Stata text, because Stata resolves "\\" into "\" and "\$" into "$".{p_end} + +{p 4 4 6}A final quirk: you cannot use the results of the Stata macro $S_FN in {cmd:outreg2} +text for a TeX table if you use Microsoft Windows. $S_FN returns the path name +for the current data file which in Windows includes \ characters which will +prevent the TeX table from rendering properly.{p_end} + + +{marker s_14} +{title:Example 14. Adding column titles or notes} + + +{p 4 4 6}You can add a column title "Base case (mpg)" to distinguish this regression from a +second regression. No quotation marks are required around the column title because +it does not contain commas. Use {opt cttop( )} to add additional column title to the default column titles.{p_end} + +{p 4 4 6}{stata outreg2 using myfile, replace ctitle(Base case (mpg))}{p_end} +{p 4 4 6}{stata outreg2 using myfile, cttop(On top)}{p_end} + +{p 4 4 6}You can add explanatory note at the bottom of a column using the {opt addn:ote} option. +Note that since the text in {opt addn:ote} does not contain parentheses or commas +it does not need quotation marks.{p_end} + +{p 4 4 6}{stata outreg2 using myfile, addnote(Dummy variables not shown)} {p_end} + +{p 4 4 6}{opt addnote} for inserting a blank line, followed by the time the program was run (from the +built-in Stata functions $S_TIME and $S_DATE), and the dataset used by the +estimation (from the Stata function $S_FN).{p_end} + +{p 4 4 6}{stata regress mpg foreign weight length}{p_end} +{p 4 4 6}{stata `"outreg2 using myfile, addn("", "Time $S_TIME, $S_DATE", Data from $S_FN) replace"'} {p_end} + + +{marker s_15} +{title:Example 15. n-way cross-tabulation} + +{p 4 4 6}n-way tabulation likes of which are also produced by tab3way or table. It will take about a minute to run.{p_end} + +{p 4 4 6}* Prepare data{p_end} +{p 4 4 6}{stata sysuse auto, clear}{p_end} +{p 4 4 6}{stata egen mileage=cut(mpg), group(10)}{p_end} +{p 4 4 6}{stata egen paid=cut(price), group(3)}{p_end} +{p 4 4 6}{stata egen heavy=cut(weight), group(3)}{p_end} + +{p 4 4 6}* 3-way cross-tabulation{p_end} +{p 4 4 6}{stata outreg2 mileage paid heavy using myfile, see replace cross}{p_end} + +{p 4 4 6}* 3-way cross-tabulation sideway{p_end} +{p 4 4 6}{stata outreg2 mileage paid heavy using myfile, see replace cross side}{p_end} + +{p 4 4 6}* 5-way cross-tabulation without percentage{p_end} +{p 4 4 6}{stata outreg2 mileage paid foreign rep78 heavy using myfile, see replace cross stats(coef)}{p_end} + + +{marker s_16} +{title:Example 16. Group summary table} + +{p 4 8 8}{stata sysuse auto, clear}{p_end} +{p 4 8 8}{stata gen white=cond(uniform()>.5,1,0)}{p_end} +{p 4 8 8}{stata gen black=cond(white==1,0,1)}{p_end} +{p 4 8 8}{stata gen male=cond(uniform()>.5,1,0)}{p_end} +{p 4 8 8}{stata gen female=cond(male==1,0,1)}{p_end} + +{p 4 8 8}{stata outreg2 using myfile if white==1 & male==1, sum(log) eqkeep(mean N) cttop(white, male) drop(white male female) excel replace}{p_end} +{p 4 8 8}{stata outreg2 using myfile if white==1 & female==1, sum(log) eqkeep(mean N) cttop( , female) drop(white male female) excel}{p_end} +{p 4 8 8}{stata outreg2 using myfile if white==1, sum(log) eqkeep(mean N) cttop( , total) drop(white male female) excel}{p_end} +{p 4 8 8}{stata outreg2 using myfile if black==1 & male==1, sum(log) eqkeep(mean N) cttop(black, male) drop(white male female) excel}{p_end} +{p 4 8 8}{stata outreg2 using myfile if black==1 & female==1, sum(log) eqkeep(mean N) cttop( , female) drop(white male female) excel}{p_end} +{p 4 8 8}{stata outreg2 using myfile if black==1, sum(log) eqkeep(mean N) cttop( , total) drop(white male female) excel}{p_end} + + +{p 4 8 8}* or just do it as a -by:- command{p_end} +{p 4 8 8}{stata bys male black: outreg2 using myfile, sum(log) eqkeep(mean N) drop(white female male black) excel replace}{p_end} + + +{marker s_17} +{title:Example 17. Fixed effects or legends} + +{p 4 4 6}Two-way fixed-effects estimation with dummy indicators:{p_end} + +{p 4 4 6}* set up data{p_end} +{p 4 4 6}{stata sysuse auto, clear}{p_end} +{p 4 4 6}{stata ren rep78 state}{p_end} +{p 4 4 6}{stata ren turn id}{p_end} +{p 4 4 6}{stata keep id price mpg weight state}{p_end} +{p 4 4 6}{stata tab state, gen(ST)}{p_end} + +{p 4 4 6}* regress and report{p_end} +{p 4 4 6}{stata xtreg price mpg weight ST*, fe i(id)}{p_end} +{p 4 4 6}{stata outreg2 using myfile, replace drop(ST*) addtext(State FE, YES, Year FE, YES)}{p_end} +{p 4 4 6}{stata xtreg price mpg weight ST*, fe i(id)}{p_end} +{p 4 4 6}{stata outreg2 using myfile, drop(ST*) addtext(State FE, NO, Year FE, YES)}{p_end} +{p 4 4 6}{stata reg price mpg weight ST*}{p_end} +{p 4 4 6}{stata outreg2 using myfile, drop(ST*) addtext(State FE, NO, Year FE, NO)}{p_end} + +{p 4 4 6}* legend{p_end} +{p 4 4 6}{stata outreg2 using myfile, st(str(Coef) str(Stn Err) str(Spearman)) noparen ct(Legend) replace}{p_end} +{p 4 4 6}{stata outreg2 using myfile, st(coef se spearman blank)}{p_end} + + +{marker s_18} +{title:Example 18. Insert r-class cmd( ) outputs} + +{p 4 4 6}You can insert output from r-class command in the table body through cmd( : ) sub-option. Indep and dependent +variables will be fed to them.{p_end} + +{p 4 4 6}* outputs Kendall's tau-a and tau-b{p_end} +{p 4 4 6}sysuse auto, clear{p_end} +{p 4 4 6}reg rep78 headroom length turn gear_ratio{p_end} +{p 4 12 8}outreg2 using myfile, replace stats(corr, spearman, cmd(r(tau_a): ktau), /*{p_end} +{p 12 12 8}*/cmd(r(tau_b): ktau)){p_end} + +{p 4 4 6}* double-check{p_end} +{p 4 4 6}ktau rep78 headroom{p_end} +{p 4 4 6}ret list{p_end} + + +{p 4 4 6}{ul:Write and insert your own r-class output} + +{p 4 4 6}You can write your own r-class program and insert their outputs. A scalar should be returned +on two inputs: independent variable and dependent variable. It needs to accept [if] syntax. +c_local programs will work, too, but there might be a conflict.{p_end} + +{p 4 4 6}* r-class program that calculates coefficient of variation{p_end} +{p 4 4 6}cap prog drop coefvar{p_end} +{p 4 4 6}prog define coefvar, rclass{p_end} +{p 8 8 8}syntax varlist(max=2) [if]{p_end} +{p 8 8 8}gettoken dep indep : varlist{p_end} +{p 8 8 8}qui sum `indep' `if'{p_end} +{p 8 8 8}local variation=`r(sd)'/`r(mean)'*100{p_end} +{p 8 8 8}ret scalar variation=`variation'{p_end} +{p 4 4 6}end{p_end} + +{p 4 4 6}* test your r-class program{p_end} +{p 4 4 6}sysuse auto, clear{p_end} +{p 4 4 6}reg rep78 headroom length turn gear_ratio{p_end} +{p 4 4 6}coefvar rep78 headroom if e(sample){p_end} +{p 4 4 6}ret list{p_end} + +{p 4 4 6}* run them{p_end} +{p 4 4 6}sysuse auto, clear{p_end} +{p 4 4 6}reg rep78 headroom length turn gear_ratio{p_end} +{p 4 4 6}outreg2 using myfile, replace stats(coef, se, sd, cmd(r(variation): coefvar)){p_end} + + +{p 4 4 6}{ul:A c_local program with its own option}{p_end} + +{p 4 4 6}* calculates coefficient of variation{p_end} +{p 4 4 6}cap prog drop coefvar2{p_end} +{p 4 4 6}prog define coefvar2{p_end} +{p 8 8 8}syntax varlist(max=2) [if], [proportion]{p_end} +{p 8 8 8}gettoken dep indep : varlist{p_end} +{p 8 8 8}qui sum `indep' `if'{p_end} +{p 8 8 8}local hundred 100{p_end} +{p 8 8 8}if "`proportion'"=="proportion" {{p_end} +{p 12 12 8}local hundred 1{p_end} +{p 8 8 8}}{p_end} +{p 8 8 8}local variation=`r(sd)'/`r(mean)'*`hundred'{p_end} +{p 8 8 8} c_local variation=`variation'{p_end} +{p 4 4 6}end{p_end} + +{p 4 4 6}* run them{p_end} +{p 4 4 6}sysuse auto, clear{p_end} +{p 4 4 6}reg rep78 headroom length turn gear_ratio{p_end} +{p 4 4 6}outreg2 using myfile, stats(coef, se, sd, cmd(variation: coefvar2, proportion)){p_end} + + +{p 4 4 6}{ul:Send one to the e-mail address below} + +{p 4 4 6}If you can send me a program like these, and I agree it is useful, then it can made into +a sub-option out of it for inclusion the future versions of -outreg2-. Please note that it should be +something of interest to other people.{p_end} + + +{hline} + +{marker s_Differences} +{title:Different versions of {cmdab:outreg} and {cmdab:outreg2}} + +{p 4 4 6}{cmd:outreg2} will work under different versions of Stata:{p_end} + +{p 4 4 6}Stata 11.0: {cmd:seeout} will require an additional keyboard hit before moving on{p_end} +{p 4 4 6}Stata 8.2: full functionality{p_end} +{p 4 4 6}Stata 8.0: reported stored estimates will be left behind when they are specified{p_end} +{p 4 4 6}Stata 7.0: no stored estimated{p_end} +{p 15 15 15}no colon character ":" in your file path; use -cd- instead{p_end} +{p 15 15 15}Shorthand syntax for outreg2 or seeout will not work in versions earlier than 8.0.{p_end} +{p 15 15 15}tfmt(.), rfmt(.), pft(.), afmt(.) do not work{p_end} +{p 15 15 15}cmd( ) and str( ) do not work.{p_end} +{p 15 15 15}Other limitations may exit exist; best not to try anything complicated{p_end} + +{p 4 4 6} +Compared to the original {cmd:outreg}, {cmd:outreg2} implements the following as +the default: {opt append}, {opt 3aster}, {opt coefastr}, {opt se}, and {opt nolabel}. +{opt 2aster} and {opt tstat} provide the access to the old default options. {opt si:gsymb} +is replaced with {opt sym:bol}. {opt x:stats} is not supported.{p_end} + +{p 4 4 6} +The auxiliary statistics (standard error, etc) are no longer reported in +absolute values. The levels of significance are strictly less than the values +(used to be less than or equal to). bdec and bfmt no longer take multiple inputs. + +{p 4 4 6} +The embedded spaces in the folder names are now accepted. {opt ti:tle(list)} can be added anytime. +The .out extension is phased out in favor of .txt extension. A new file will be created if it did not exist. +The past restrictions on the number and the size of variable names have been +generally expanded to the system limit.{p_end} + +{p 4 4 6} +The newly available features are the access to {opt label}, +{help ereturn:{opt e(ereturn scalars)}}, automatically formatted digits +by {opt auto(integer)} and {opt less(integer)}, {opt alpha(numlist)} provides +user-defined test of hypothesis, {opt seeo:ut} calls up the pop up table in +the data browser view, the choice of equation names as wide or {opt long}, +the converted tables in {opt word}, {opt excel}, and {opt tex} with the +{cmd:shellout} commands for them placed on the screen.{p_end} + +{p 4 4 6} +The {cmd:[}{help estimates:{it:estlist}}{cmd:]}, which is a +list of stored estimates, is accepted with or without wildcard abbreviations. +The shorthand syntax with a limited option can now be implemented +as an independent command following a regression command, or as a pre-command +preceeding it.{p_end} + +{p 4 4 6} +The {cmd:seeout} shell is also placed on the screen. The +{cmd:seeout} command will work only after {cmd:outreg2}. A majority of options +should work with 8.2. The shell commands were designed with a Windows XP/NT. +They will not work on non-Windows platforms.{p_end} + + +{title:Author} + +{p 4 4 6}Roy Wada{p_end} +{p 4 4 6}roywada@hotmail.com{p_end} + +{p 4 4 6}based on the earlier works by{p_end} +{p 4 4 6}John Luke Gallup{p_end} +{p 4 4 6}john_gallup@alum.swarthmore.edu{p_end} + +{p 4 4 6}Thanks to Kit Baum for advice and providing access to John's later works. +I also thank those who have reported errors, making it possible to fix them in timely +fashion.{p_end} + + +{title:Also see} + +{p 3}STB: sg97 (STB-46, STB-49, STB-58){p_end} +{p}Manual: {bf:[U] Estimation and post-estimation commands}{p_end} +{p 9}{bf:[U] Overview of model estimation}{p_end} +{p 9}{bf:[R] Estimation commands}{p_end} + +{p }Online: {help est}, {help postfile}, {help outfile}, {help outsheet}, {help save}, +{search modltbl}, {search desrep} {p_end} + +{s6hlp} +{smcl} + + + + diff --git a/Modules/ado/plus/o/outreg2.pref b/Modules/ado/plus/o/outreg2.pref new file mode 100644 index 0000000..3cf314a --- /dev/null +++ b/Modules/ado/plus/o/outreg2.pref @@ -0,0 +1,2 @@ + 5 Dec 2009 +using `"myfile.txt"' diff --git a/Modules/ado/plus/o/outreg2_prf.ado b/Modules/ado/plus/o/outreg2_prf.ado new file mode 100644 index 0000000..f3f53bf --- /dev/null +++ b/Modules/ado/plus/o/outreg2_prf.ado @@ -0,0 +1,3 @@ +24 Oct 2005 +using "test.txt" +eform one less(2) diff --git a/Modules/ado/plus/p/polych_ll.ado b/Modules/ado/plus/p/polych_ll.ado new file mode 100644 index 0000000..fae370a --- /dev/null +++ b/Modules/ado/plus/p/polych_ll.ado @@ -0,0 +1,16 @@ +pro def polych_ll + version 8.1 + + args lf rho + + #delimit ; + qui replace __POLYpi = + binorm(__POLY1hi,__POLY2hi,`rho') - + binorm(__POLY1lo,__POLY2hi,`rho') - + binorm(__POLY1hi,__POLY2lo,`rho') + + binorm(__POLY1lo,__POLY2lo,`rho') + ; + #delimit cr + qui replace `lf' = ln( __POLYpi ) + +end diff --git a/Modules/ado/plus/p/polychoric.ado b/Modules/ado/plus/p/polychoric.ado new file mode 100644 index 0000000..45c4230 --- /dev/null +++ b/Modules/ado/plus/p/polychoric.ado @@ -0,0 +1,612 @@ +*! Polychoric correlations -- v.1.4.3, by Stas Kolenikov +program define polychoric, rclass + version 8.2 + + #delimit ; + syntax varlist(min=2 numeric) [if] [in] [aw fw pw /], + [pca pw VERBose NOLOG SCore(str) dots IMissing NSCore(int 0) noINIT *] + ; + #delimit cr + * PCA to perform PCA + * pw for pairwise correlations + * verbose to output the correlation type, rho, s.e., and goodness of fit if applicable + * NOLOG + * score to generate scores from PCA + * dots to entertain the user with % signs + * imissing to believe that the missing of an ordinal variables should be imputed zero + + if "`imissing'" == "" { + local imissing not + } + + if "`score'"=="" & `nscore'>0 { + di as err "cannot specify nscore without score" + exit 198 + } +* else local nscore=5 + + * this is a bit weird: what if the user specifies -score- + * without the name of the new variable? Then it gets into `options' + + if index("`options'","score") { + di as err "must specify new variable prefix with -score-" + exit 198 + } + + if `:word count `varlist'' == 2{ + local verbose verbose + } + + tempvar w1 + if "`weight'" ~= "" { + qui g double `w1' = `exp' + local www [`weight'=`w1'] + } + else { + qui g double `w1' = 1 + local www [pw=`w1'] + local exp `w1' + } + * that way, we always have weights + + if "`score'"~="" { + confirm new var `score'1 + } + + if "`pw'"==""{ + marksample touse + } + else { + marksample touse, novar + } + + tokenize `varlist' + local nvar: word count `varlist' + tempname corrmat + + mat `corrmat' = J(`nvar',`nvar',.) + forvalues i=1/`nvar' { + mat `corrmat'[`i',`i']=1 + } + + mat rown `corrmat' = `varlist' + mat coln `corrmat' = `varlist' + +* compress `varlist' + + local i=1 + local ndots = `nvar'*(`nvar'-1)/2 + local idots 0 + while "``i''"~="" { + local j = `i'+1 + while "``j''"~="" { + polych1 ``i'' ``j'' `www' if `touse' , `options' `init' + if "`dots'"~="" { + if int(`idots'/`ndots'*10)-int(`++idots'/`ndots'*10)~=0 { + di as text int(10*`idots'/`ndots') "0%" _c + } + else { + di as text "." _c + } + } + mat `corrmat'[`i',`j']=r(rho) + mat `corrmat'[`j',`i']=r(rho) + if "`verbose'"=="verbose" { + di _n /// + as text "Variables : " as res "``i'' ``j''" _n /// + as text "Type : " as res r(type) _n /// + as text "Rho = " as res r(rho) _n /// + as text "S.e. = " as res r(se_rho) + if "`r(type)'" == "polychoric" { + di as text "Goodness of fit tests:" _n /// + as text "Pearson G2 = " as res r(G2) /// + as text ", Prob( >chi2(" as res r(dfG2) as text")) = " as res r(pG2) _n /// + as text "LR X2 = " as res r(X2) /// + as text ", Prob( >chi2(" as res r(dfX2) as text")) = " as res r(pX2) + } + } + local `j++' + } + local i=`i'+1 + tokenize `varlist' + } + + return add + + if "`verbose'" == "" { + di as text _n "Polychoric correlation matrix" + mat li `corrmat', noheader + } + + if "`pca'"~="" { + return clear + polypca `corrmat' `touse' `www' `imissing' `nscore' `score' + return add +/* + if "`score'"~="" { + cap noi sum `score'* + } +*/ + } + return matrix R `corrmat' + +end + +prog def polypca, rclass + * perform PCA with the estimated matrix + + args corrmat touse www imissing nscore score + * the correlation matrix + + * parse the weights + tokenize `www' , parse(" [=]") + * should become `1' == [, `2' == weight type, `3' == "=", `4' == exp, `5' == ] + local exp `4' + + tempname X V value + if `nscore'==0 local nscore . + + mat symeigen `X' `V' = `corrmat' + * `V' are the eigenvalues, `X' are the eigenvectors + + local nvar = colsof(`corrmat') + local p = min(`nvar',`nscore') + di _n as text "Principal component analysis" _n(2) " k {c |} Eigenvalues {c |} Proportion explained {c |} Cum. explained" + di as text "{dup 4:{c -}}{c +}{dup 15:{c -}}{c +}{dup 24:{c -}}{c +}{dup 18:{c -}}" + local sum=0 + forvalues i=1/`nvar' { + return scalar lambda`i' = `V'[1,`i'] + local sum = `sum'+return(lambda`i') + #delimit ; + di as res " "`i' as text " {c |} " + as res %9.6f `V'[1,`i'] _col(21) as text "{c |} " + as res %9.6f `V'[1,`i']/`nvar' _col(46) as text "{c |} " + as res %8.6f `sum'/`nvar' + ; + #delimit cr + } + + if "`score'"~= "" { + +* set trace on + + local varlist : rownames `X' + tempvar tt ii +** mat li `X' + di as text _n _col(15) "{bf: Scoring coefficients}" _n(2) /// + " Variable {c |} Coeff. 1 {c |} Coeff. 2 {c |} Coeff. 3 " /// + _n "{dup 54:{c -}}" _c + qui foreach x of varlist `varlist' { + noi di _n as res " `x'" _col(16) _c + * is it continuous or discrete? + cap drop `tt' + cap drop __tt`x' +* cap confirm byte var `x' +* need to properly determine if continuous or discrete + + cap inspect `x' + if r(N_unique)>9 { + * continuous + * egen __tt`x' = std(`x') if `touse' + sum `x' [iw=`exp'] + g double __tt`x' = (`x'-r(mean))/r(sd) if `touse' + forvalues i=1/3 { + noi di as text " {c |} " as res %9.6f /* sqrt(`V'[1,`i'])* */`X'[rownumb(`X',"`x'"),`i'] " " _c + } + } + else { + /* + cap tab `x' if `touse' + if r(r) > 10 | _rc == 134 { + * quasi-continuous + * egen __tt`x' = std(`x') if `touse' + sum `x' [iw=`exp'] + g double __tt`x' = (`x'-r(mean))/r(sd) if `touse' + forvalues i=1/3 { + noi di as text " {c |} " as res %9.6f `X'[rownumb(`X',"`x'"),`i'] " " _c + } + } + else { + */ + * discrete; make it a centered categorized normal +** noi di as text " : ordinal" _c + local ncat = r(N_unique) + sum `exp', mean + local N = r(sum) + sort `touse' `x' + cap drop `ii' + egen byte `ii' = group(`x') if `touse' + local p0 = 0.1/`N' + local t0 = invnorm(`p0') +** noi di `t0' + forvalues k=1/`ncat' { + sum `exp' if `ii'<=`k' , mean + local p`k' = (r(sum)-0.5)/`N' + local t`k' = invnorm(`p`k'') +** noi di `t`k'' + } + local p`ncat' = (`N'-0.1)/`N' + local t`ncat' = invnorm(`p`ncat'') +** noi di `t`ncat'' + gen double __tt`x' = 0 if `touse' + forvalues k=1/`ncat' { + local k1 = `k'-1 + scalar `value' = ( exp(-.5*`t`k1''*`t`k1'') - exp(-.5*`t`k''*`t`k'') ) /// + /(sqrt(2*_pi)*(norm(`t`k'')-norm(`t`k1'') ) ) + replace __tt`x' = `value' if `touse' & `ii'==`k' + * need to determine what was the original category + sum `x' if `ii'==`k' + noi di _n _col(14) as res %-2.0f r(mean) _c + forvalues i=1/3 { + noi di as text " {c |} " as res %9.6f /* sqrt(`V'[1,`i'])* */ `X'[rownumb(`X',"`x'"),`i']*`value' " " _c + } + } + if "`imissing'" == "imissing" { + replace _tt`x' = 0 if `touse' & mi(`x') + } +** } + } + } + di + + nobreak { + qui forvalues i=1/`p' { + * we'll score `p' components prefixed by `score' + gen double `score'`i'=0 if `touse' + foreach x of varlist `varlist' { + replace `score'`i' = `score'`i' + /* sqrt(`V'[1,`i'])* */ `X'[rownumb(`X',"`x'"),`i']*__tt`x' if `touse' + } + } + } + } + + return matrix eigenvalues `V' + return matrix eigenvectors `X' + + polyquit + +end + +prog def polych1, rclass + + syntax varlist(numeric min=2 max=2) if [aw fw pw /] [, noINIT * ] + +*** !!! êàêèć-òî ăëțêè ń score nscore + + local www [`weight'=`exp'] + + marksample touse + + local x1 `1' + local x2 `2' + + forvalues i = 1/2 { + +/* prior to 1.3.2 + + cap confirm byte var `x`i'' + if _rc==7 { + local call `call'c + continue + } + cap tab `x`i'' + * if more than 10 categories -- treat as continuous + if r(r)>9 | _rc==134 { +*/ + + cap inspect `x`i'' + if r(N_unique)>9 { + local call `call'c + } + else { + local call `call'd + } + } + + if "`call'"=="cc" { + + * both are continuous +** qui corr `x1' `x2' `www' if `touse' + tempname A + qui mat accum `A' = `x1' `x2' `www' if `touse' , nocons dev + return scalar sum_w = r(N) + qui count if !mi(`x1') & !mi(`x2') & !mi(`exp') + return scalar N=r(N) + mat `A' = corr(`A') + return scalar rho = `A'[1,2] + return local type Pearson + return scalar se_rho = sqrt( (1-return(rho)*return(rho))/(return(N)-2) ) + exit + } + + if "`call'"=="dc" { + * the first variable has to be continuous, and the second, discrete + local call cd `x2' `x1' `www' if `touse' + return local type polyserial + } + + if "`call'"=="cd" { + * the first variable has to be continuous, and the second, discrete + local call cd `x1' `x2' `www' if `touse' + return local type polyserial + } + + if "`call'"=="dd" { + * the first variable has to be continuous, and the second, discrete + local call dd `x2' `x1' `www' if `touse' + return local type polychoric + } + + cap noi corr`call' , `init' `options' +*********** +* set trace off + + if _rc==1 { + polyquit + exit 1 + } + + return add + +end + +prog def corrdd, rclass sort + + * the module to compute the polychoric correlation + +**************** +* set tracedepth 2 +* set trace on + + syntax varlist(numeric min=2 max=2) if [aw fw pw /], [ * noINIT ITERate(int 50) SEArch(str) ] + + cap confirm integer number `search' + if !_rc { + local searchstr search(quietly) repeat(`search') + } + else { + if "`search'" == "" { + local searchstr search(off) + } + else { + local searchstr search(`search') + } + } + + marksample touse + * compute the thresholds + + tempvar x1 x2 + + cap drop __POLY* + eret clear + ret clear + + qui forvalues k = 1/2 { + sort `touse' ``k'' + egen `x`k'' = group(``k'') if `touse' + tab `x`k'' + local r`k' = r(r) + sum `exp' if `touse', meanonly + local N = r(sum) + return scalar sum_w = `N' + return scalar N = r(N) + gen __POLY`k'hi = . + gen __POLY`k'lo = . + forvalues h = 1/`r`k'' { + * create the variables: upper threshold - lower threshold + local h1 = `h'-1 + sum `exp' if `x`k''<=`h' & `touse', meanonly + replace __POLY`k'hi = cond(`h'==`r`k'',10,invnorm( (r(sum)-.5)/`N' ) ) if `x`k'' == `h' & `touse' + sum `exp' if `x`k'' <= `h1' & `touse', meanonly + replace __POLY`k'lo = cond(`h'==1,-10,invnorm( (r(sum)-.5)/`N' ) ) if `x`k'' == `h' & `touse' + } + } + qui corr `1' `2' if `touse' + + local mcorr = r(rho) + local mcorr = sign(`mcorr')*min(0.9, (1+abs(`mcorr'))/2) + if "`init'" == "noinit" { + local initstr init(_cons = `mcorr') + } + else { + local initstr + } + + * shouldn't -collapse- come somewhere here so that we don't have + * to compute a complicated bivariate distribution for too many observations? + * + * needed further: __POLY([1|2][hi|lo]&pi); sum of weights; `touse' + * no, for some reason, it did not work: the s.e.s are wrong + + qui gen double __POLYpi = . + + preserve + qui keep if `touse' + + cap ml model lf polych_ll (rho: `touse' =) if `touse' /// [fw=`counts'] + [`weight' = `exp'] /// + , maximize `options' search(off) bounds(rho: -1 1) init(_cons = 0) iter(0) nolog + + if _rc==1 { + polyquit + exit 1 + } + local ll0c = e(ll) + + cap noi ml model lf polych_ll (rho: `touse' =) if `touse' /// [fw=`counts'] + [`weight' = `exp'] /// + , maximize `options' `searchstr' bounds(rho: -1 1) /// + `initstr' iter(`iterate') nolog + + local rc=_rc + if `rc'==1 { + polyquit + exit 1 + } + else if `rc' { + cap noi ml model lf polych_ll (rho: `touse' =) if `touse' /// [fw=`counts'] + [`weight' = `exp'] /// + , maximize `options' search(quietly) repeat(10) bounds(rho: -1 1) /// + iter(`iterate') nolog + } + + return scalar rho = _b[_cons] + return scalar se_rho = _se[_cons] + + collapse (sum) `exp' (mean) `touse' (mean) __POLY* if `touse', by(`x1' `x2') + + * tests + * null hypothesis: no structure + local df0 = `r1'*`r2' - `r1' - `r2' + tempvar ll pp + + tempvar counts + qui g `ll' = sum( `exp'*ln(`exp'/`N') ) + local ll0 = `ll'[_N] + + * Likelihood ratio + return scalar G2 = 2*(`ll0'-e(ll)) + return scalar dfG2 = `df0' + return scalar pG2 = chi2tail(`df0',return(G2)) + + * Pearson chi-square + + qui g double `pp' = sum( ((`exp'/`N'-__POLYpi)^2)/__POLYpi ) + return scalar X2 = `pp'[_N]*`N' + return scalar dfX2 = `df0' + return scalar pX2 = chi2tail(`df0',return(X2)) + + restore + + * no correlation + return scalar LR0 = -2*(`ll0c'-e(ll)) + return scalar pLR0 = chi2tail(1,return(LR0)) + + polyquit + +end + +prog def corrcd, rclass + + * the module to compute the polyserial correlation + + syntax varlist(numeric min=2 max=2) if [aw fw pw /], [ * ITERate(int 50) noINIT SEArch(str) ] + * the first variable is continuous, the second is discrete + + cap confirm integer number `search' + if !_rc { + local searchstr search(quietly) repeat(`search') + } + else { + if "`search'" == "" { + local searchstr search(off) + } + else { + local searchstr search(`search') + } + } + + marksample touse + + * thresholds for the discrete part + + tempvar x1 x2 + + cap drop __POLY* + ret clear + + qui{ + * egen `x1' = std(`1') if `touse' + sum `1' [iw=`exp'] + g double `x1' = (`1'-r(mean))/r(sd) if `touse' + + sort `touse' `2' `1' + egen `x2' = group(`2') if `touse' + tab `x2' if `touse' + local r2 = r(r) + sum `exp' if `touse', mean + local N = r(sum) + return scalar N = r(N) + return scalar sum_w = `N' + gen __POLY2hi = . + gen __POLY2lo = . + forvalues h = 1/`r2' { + * create the variables: upper threshold - lower threshold + local h1 = `h'-1 + sum `exp' if `x2'<=`h' & `touse' + replace __POLY2hi = cond(`h'==`r2',10,invnorm( (r(sum)-.5)/`N' ) ) if `x2' == `h' & `touse' + sum `exp' if `x2' <= `h1' & `touse' + replace __POLY2lo = cond(`h'==1,-10,invnorm( (r(sum)-.5)/`N' ) ) if `x2' == `h' & `touse' + } + spearman `1' `2' if `touse' + local mcorr = r(rho) + } + + if "`init'" == "noinit" { + local initstr init(_cons = `mcorr') + } + else { + local initstr init(_cons = 0) + } + + eret clear + + cap ml model lf polyser_ll (rho: `x1' =) if `touse' [`weight'=`exp'] , /// + maximize `options' search(off) bounds(rho: -1 1) init(_cons = 0) iter(0) nolog + + if _rc==1 { + polyquit + exit 1 + } + local ll0c = e(ll) + + cap noi ml model lf polyser_ll (rho: `x1' =) if `touse' [`weight'=`exp'] , /// + maximize `options' `searchstr' bounds(rho: -1 1) `initstr' nolog iter(`iterate') + + local rc=_rc + if `rc'==1 { + polyquit + exit 1 + } + if `rc' { + cap noi ml model lf polyser_ll (rho: `x1' =) if `touse' [`weight'=`exp'] , /// + maximize `options' `bounds(rho: -1 1) nolog iter(`iterate') /// + search(quietly) repeat(10) + } + + * return the correlation coefficient + + return scalar rho = _b[_cons] + return scalar se_rho = _se[_cons] + + * no correlation + return scalar LR0 = -2*(`ll0c'-e(ll)) + return scalar pLR0 = chi2tail(1,return(LR0)) + +end + +pro def polyquit + cap drop __POLY* +end + +exit + +History: +v.1.1 -- Aug 2003 + The basic development of everything +v.1.2 -- November 2003 + -- weights accomodated + -- imissing option +v.1.3 -- February 2004 + -- polychoricpca as a separate command + -- nscore option added -- changed the order of arguments in polychoric.polypca +v.1.3.2 -- -inspect- is used to count the number of categories in place + of -tab-; no need to -compress- +v.1.3.3 -- iterate, search, and other stuff to failsafe convergence +v.1.3.4 -- init string changed, score option clarified +v.1.4 -- weights dealt with properly +v.1.4.1 -- April 27, 2004 + -- bug with PCA fixed (categorical variables not recognized properly) +v.1.4.2 -- output the original category numbers +v.1.4.3 -- the default matrix is filled with missing values rather than zeroes diff --git a/Modules/ado/plus/p/polychoric.hlp b/Modules/ado/plus/p/polychoric.hlp new file mode 100644 index 0000000..d2e47e1 --- /dev/null +++ b/Modules/ado/plus/p/polychoric.hlp @@ -0,0 +1,228 @@ +{smcl} +{.-} +help for {cmd:polychoric} and {cmd:polychoricpca} {right:author: {browse "http://www.komkon.org/~tacik/stata/":Stas Kolenikov}} +{.-} + +{title:Polychoric and polyserial correlations} + +{p 8 27} +{cmd:polychoric} +{it:varlist} +[{it:weight}] +[{cmd:if} {it:exp}] [{cmd:in} {it:range}] +[{cmd:,} + {cmd:pw} + {cmdab:verb:ose} + {cmd:nolog} + {cmd:dots} + ] + +{p 8 27} +{cmd:polychoricpca} +{it:varlist} +[{it:weight}] +[{cmd:if} {it:exp}] [{cmd:in} {it:range}] +[{cmd:,} + {cmdab:sc:ore}{cmd:(}{it:prefix}{cmd:)} + {cmdab:nsc:ore}{cmd:(}{it:#}{cmd:)} + ] + +{title:Description} + +{p}{cmd:polychoric} estimates polychoric and polyserial correlations, +and {cmd:polychoricpca} performs the principal component analysis on +the resulting correlation matrix. The current version (1.4) of the +routine requires Stata 8.2. + +{p}The polychoric correlation of two ordinal variables is derived as follows. +Suppose each of the ordinal variables was obtained by categorizing a normally +distributed underlying variable, and those two unobserved variables follow +a bivariate normal distribution. Then the (maximum likelihood) estimate +of that correlation is the polychoric correlation. If each of the ordinal +variables has only two categories, then the correlation between the two +variables is referred to as tetrachoric. + +{p}A closely related concept is that of a polyserial correlation. It is defined +in a similar manner when one variable is continuous (assumed normal) and +an ordinal variable. If there are only two categories of the latter, then +the correlation is referred to as biserial. + +{p}If the number of the categories of one of the variables is greater than +10, {cmd:polychoric} treats it is continuous, so the correlation of two +variables that have 10 categories each would be simply the usual +Pearson moment correlation found through {help correlate}. + +{p}Make sure you read {bf:Remarks} about the known problems +in the end of this help file! If you are coming from development/health +economics research literature, you would also benefit from having +a look at our paper on polychoric PCA. + +{title:Options of {cmd:polychoric}} + +{p 0 4}{cmd:dots} entertains the user by displaing dots for each + estimated correlation. + +{p 0 4}{cmd:nolog} suppresses the log from the maximum likelihood estimation. + +{p 0 4}{cmd:pw} fills the entries of the correlation matrix with the + pairwise correlation. If this option is not specified, then, similarly + to {help correlate}, it uses the same subsample for all of the + correlations. + +{p 0 4}{cmd:verbose} for each estimated correlation displays the + names of the variables, the type of the estimated correlation + (polychoric, polyserial, or Pearson moment correlation). + {cmd:polychoric} will default to this option if there are only + two input variables. If there are more than two variables, + {cmd:polychoric} will not show anything, so you would need + to address the returned values (see below). + +{title:Options of {cmd:polychoricpca}} + +{p 0 4}{cmd:score} is the prefix for the variables to be generated + to contain the principal component scores. + +{p 0 4}{cmd:nscore} specifies the number of score variables to be generated. + {cmd:polychoricpca} will show the output from the first three eigenvalues, + at most. + +{title:Returned values} + +{cmd:polychoric} sets the following set of {help return} values. + +{p 0 4}{cmd:r(R)} (matrix) is the estimated correlation matrix{p_end} +{p 0 4}{cmd:r(type)} (local) is the type of estimated correlation, one of + {it:polychoric}, {it:polyserial}, or {it:Pearson}{p_end} +{p 0 4}{cmd:r(rho)} is the estimated correlation{p_end} +{p 0 4}{cmd:r(se_rho)} is the estimated standard error of the correlation{p_end} +{p 0 4}{cmd:r(N)} is the number of observations used{p_end} +{p 0 4}{cmd:r(LR0)} and {cmd:r(pLR0)} are the results of the likelihood ratio + test of no correlation + +{p}In addition, if both variables are ordinal, the specification tests + on normality are performed that compare the empirical proportions of + the cells with the theoretical ones implied by normality, together + with estimated polychoric correlation. The tests are not available + for a 2x2 case as the tests have zero degrees of freedom. + The returned results are: + +{p 0 4}{cmd:r(X2)}, {cmd:r(dfX2)} and {cmd:r(pX2)} are the observed +test statistic, degrees of freedom, and the corresponding p-value of Pearson chi-square test: ;{p_end} +{p 0 4}{cmd:r(G2)}, {cmd:r(dfG2)} and {cmd:r(pG2)} are the observed +test statistic, degrees of freedom, and the corresponding p-value of the +likelihood ratio test.{p_end} + +{p}If there are more than two input variables, then the returned values +correspond to the last estimated pair, in the manner similar to +{help correlate}. + + +{p}{cmd:polychoricpca} returns the matrices of eigenvectors, eigenvalues, +and the correlation matrix, as well as a few largest eigenvalues corresponding +to the number of scores requested. + +{title:Example} + +{.-} +{com}. use c:\stata8\auto +{txt}(1978 Automobile Data) + +{com}. polychoric rep78 foreign + +{txt}Variables : {res}rep78 foreign +{txt}Type : {res}polychoric +{txt}Rho = {res}.80668059 +{txt}S.e. = {res}.07631279 +{txt}Goodness of fit tests: +Pearson G2 = {res}.43127115{txt}, Prob( >chi2({res}3{txt})) = {res}.93370948 +{txt}LR X2 = {res}.38908216{txt}, Prob( >chi2({res}3{txt})) = {res}.94248852 +{txt} +{com}. return list + +{txt}scalars: + r(pLR0) = {res}5.12057153705e-08 + {txt}r(LR0) = {res}29.67059428252011 + {txt}r(pX2) = {res}.9424885157334509 + {txt}r(dfX2) = {res}3 + {txt}r(X2) = {res}.3890821586898692 + {txt}r(pG2) = {res}.9337094786275901 + {txt}r(dfG2) = {res}3 + {txt}r(G2) = {res}.4312711544473018 + {txt}r(se_rho) = {res}.0763127851819864 + {txt}r(rho) = {res}.8066805935187174 + {txt}r(N) = {res}69 + {txt}r(sumw) = {res}69 + +{txt}macros: + r(type) : "{res}polychoric{txt}" + +matrices: + r(R) : {res} 2 x 2 +{txt} +{com}. polychoric foreign mpg + +{txt}Variables : {res}foreign mpg +{txt}Type : {res}polyserial +{txt}Rho = {res}.48603372 +{txt}S.e. = {res}.11286311 +{txt} +{com}. polychoricpca foreign mpg rep78 + +{txt} k {c |} Eigenvalues {c |} Proportion explained {c |} Cum. explained +{dup 4:{c -}}{c +}{dup 15:{c -}}{c +}{dup 24:{c -}}{c +}{dup 18:{c -}} +{res} 1{txt} {c |} {res} 2.206757{col 21}{txt}{c |} {res} 0.735586{col 46}{txt}{c |} {res}0.735586 + 2{txt} {c |} {res} 0.615445{col 21}{txt}{c |} {res} 0.205148{col 46}{txt}{c |} {res}0.940734 + 3{txt} {c |} {res} 0.177798{col 21}{txt}{c |} {res} 0.059266{col 46}{txt}{c |} {res}1.000000 +{txt} +{com}. return list + +{txt}scalars: + r(lambda3) = {res}.1777976956026297 + {txt}r(lambda2) = {res}.6154453299437229 + {txt}r(lambda1) = {res}2.206756974453646 + +{txt}matrices: + r(R) : {res} 3 x 3 + {txt}r(eigenvectors) : {res} 3 x 3 + {txt}r(eigenvalues) : {res} 1 x 3 +{txt} +{com}. matrix list r(R) + +{txt}symmetric r(R)[3,3] + foreign mpg rep78 +foreign {res} 1 +{txt} mpg {res}.55443556 1 +{txt} rep78 {res}.80668065 .42655387 1 +{txt} +{.-} + +{title:Remarks} + +{p}{cmd:polychoric} is a bit sloppy with options. It assumes +the user might want to specify some {help maximize:maximization options} +for the {help ml} command, so anything it does not recognize as its +own option is getting transferred to the {cmd:ml}. That may cause +an error in the latter. + +{p}The standard error for the Pearson moment correlation does not +account for weights properly. That will be fixed later if anybody +needs that standard error. + +{title:Reference} + +{p 0 4}{bind:}Kolenikov, S., and Angeles, G. (2004). The Use of Discrete Data +in Principal Component Analysis With Applications to Socio-Economic Indices. +CPC/MEASURE Working paper No. WP-04-85. +{browse "https://www.cpc.unc.edu/measure/publications/pdf/wp-04-85.pdf":Full text in PDF format} +{p_end} + + +{title:Also see} + +{p 0 21}{bind:}Online: help for {help correlate}, {help tetrac} (if installed) +{p_end} +{p 0 21}{bind:} Internet: {browse "http://www.google.com/search?q=polychoric%20correlation":Google search}{p_end} + +{title:Contact} + +Stas Kolenikov, skolenik@unc.edu diff --git a/Modules/ado/plus/p/polychoric.zip b/Modules/ado/plus/p/polychoric.zip new file mode 100644 index 0000000..ed23638 Binary files /dev/null and b/Modules/ado/plus/p/polychoric.zip differ diff --git a/Modules/ado/plus/p/polychoricpca.ado b/Modules/ado/plus/p/polychoricpca.ado new file mode 100644 index 0000000..5ca7d00 --- /dev/null +++ b/Modules/ado/plus/p/polychoricpca.ado @@ -0,0 +1,23 @@ +*! Principal component analysis based on polychoric correlations +*! Author: Stas Kolenikov, skolenik@unc.edu. Version 1.0 + +program define polychoricpca, rclass + + syntax varlist(numeric min=2) [aw pw fw /], [SCore(passthru) NSCore(passthru) nolog *] + + if "`score'"!="" & "`nscore'"=="" { + di as err "how many score variables?" + exit 198 + } + + if "`exp'"=="" { + tempvar ww + qui g byte `ww'=1 + local exp `ww' + local weight pw + } + + polychoric `varlist' [`weight'=`exp'] , pca nolog `score' `nscore' `options' + return add + +end diff --git a/Modules/ado/plus/p/polychoricpca.hlp b/Modules/ado/plus/p/polychoricpca.hlp new file mode 100644 index 0000000..d142d24 --- /dev/null +++ b/Modules/ado/plus/p/polychoricpca.hlp @@ -0,0 +1 @@ +.h polychoric diff --git a/Modules/ado/plus/p/polychoricpca.zip b/Modules/ado/plus/p/polychoricpca.zip new file mode 100644 index 0000000..544360e Binary files /dev/null and b/Modules/ado/plus/p/polychoricpca.zip differ diff --git a/Modules/ado/plus/p/polyser_ll.ado b/Modules/ado/plus/p/polyser_ll.ado new file mode 100644 index 0000000..cf47dcf --- /dev/null +++ b/Modules/ado/plus/p/polyser_ll.ado @@ -0,0 +1,17 @@ +program define polyser_ll + version 8.1 + + args lf rho + + #delimit ; + qui replace `lf' = + ln( + ( + norm( (__POLY2hi - `rho'*$ML_y1)/sqrt(1-`rho'*`rho') ) - + norm( (__POLY2lo - `rho'*$ML_y1)/sqrt(1-`rho'*`rho') ) + ) * normden($ML_y1) + ) + ; + #delimit cr + +end diff --git a/Modules/ado/plus/p/poslist.ado b/Modules/ado/plus/p/poslist.ado new file mode 100644 index 0000000..3364830 --- /dev/null +++ b/Modules/ado/plus/p/poslist.ado @@ -0,0 +1,64 @@ +program def poslist, rclass +*! was indlist +*! NJC 1.2.0 6 June 2000 +* NJC 1.1.0 22 Dec 1999 +* NJC 1.0.0 14 Oct 1999 + version 6.0 + gettoken lists 0 : 0, parse(",") + if "`lists'" == "" | "`lists'" == "," { /* no \ */ + di in r "incorrect syntax: no separator" + exit 198 + } + + tokenize "`lists'", parse("\") + if "`4'" != "" { + di in r "incorrect syntax: too much stuff" + exit 198 + } + if "`1'" == "\" { /* list1 empty */ + if "`2'" == "\" { + di in r "incorrect syntax: one \ only" + exit 198 + } + local list2 "`2'" /* might be empty */ + } + else if "`2'" == "\" { + local list1 "`1'" + local list2 "`3'" /* might be empty */ + } + else { + di in r "incorrect syntax: what to compare?" + exit 198 + } + + syntax [ , Global(str) Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + local n1 : word count `list1' + local n2 : word count `list2' + tokenize `list2' + + local j = 1 + while `j' <= `n2' { + local index 0 + local i = 1 + while `index' == 0 & `i' <= `n1' { + local word : word `i' of `list1' + if "`word'" == "``j''" { /* found it */ + local index = `i' + } + local i = `i' + 1 + } + local newlist "`newlist' `index'" + local j = `j' + 1 + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/p/poslist.hlp b/Modules/ado/plus/p/poslist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/p/poslist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/p/postlist.ado b/Modules/ado/plus/p/postlist.ado new file mode 100644 index 0000000..fe66a77 --- /dev/null +++ b/Modules/ado/plus/p/postlist.ado @@ -0,0 +1,37 @@ +program def postlist, rclass +*! NJC 1.3.0 6 June 2000 +* NJC 1.2.0 22 Dec 1999 +* NJC 1.0.0 12 Nov 1999 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax , Post(str) [ Global(str) Sep Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tokenize `list' + local n : word count `list' + if "`sep'" != "" { + local last = `n' + local n = `n' - 1 + } + + local i = 1 + while `i' <= `n' { + local newlist "`newlist'``i''`post' " + local i = `i' + 1 + } + + if "`sep'" != "" { local newlist "`newlist'``last''" } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/p/postlist.hlp b/Modules/ado/plus/p/postlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/p/postlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/p/praccum.ado b/Modules/ado/plus/p/praccum.ado new file mode 100644 index 0000000..e6a6e26 --- /dev/null +++ b/Modules/ado/plus/p/praccum.ado @@ -0,0 +1,237 @@ +*! version 1.7.2 2Nov2005 ztp ztnb +* version 1.7.1 13Apr2005 +* version 1.7.0 27Mar2004 slogit +* version 1.6.4 27Apr2001 change to work with forvalues +* version 1.6.3 17Mar2001 + +capture program drop praccum +program define praccum + version 6 + tempname newmat +*=> classify each valid type of model + if "`e(cmd)'"=="cloglog" { local io = "typical binary" } + if "`e(cmd)'"=="cnreg" { local io = "typical regress" } + if "`e(cmd)'"=="fit" { local io = "typical regress" } + if "`e(cmd)'"=="gologit" { local io = "typical mlogit" } + if "`e(cmd)'"=="intreg" { local io = "typical regress" } + if "`e(cmd)'"=="logistic" { local io = "typical none" } + if "`e(cmd)'"=="logit" { local io = "typical binary" } + if "`e(cmd)'"=="mlogit" { local io = "typical mlogit" } + if "`e(cmd)'"=="nbreg" { local io = "typical count" } + if "`e(cmd)'"=="ologit" { local io = "typical ordered" } + if "`e(cmd)'"=="oprobit" { local io = "typical ordered" } + if "`e(cmd)'"=="poisson" { local io = "typical count" } + if "`e(cmd)'"=="probit" { local io = "typical binary" } + if "`e(cmd)'"=="regress" { local io = "typical regress" } + if "`e(cmd)'"=="slogit" { local io = "typical ordered" } + if "`e(cmd)'"=="tobit" { local io = "typical regress" } + if "`e(cmd)'"=="zinb" { local io = "twoeq count" } + if "`e(cmd)'"=="zip" { local io = "twoeq count" } + if "`e(cmd)'"=="ztp" { local io = "typical count" } + if "`e(cmd)'"=="ztnb" { local io = "typical count" } + + if "`io'"=="" { + di + di in y "praccum" in r /* + */ " does not work for the last type of model estimated." + exit + } + local input : word 1 of `io' /* input routine to _pepred */ + local output : word 2 of `io' /* output routine */ + +*=> decode specified input + syntax [, Saving(string) Using(string) GENerate(string) XIS(string)] + +*truncate generate root if more than five characters + if "`generate'" ~= "" { + local gen = substr("`generate'",1,29) + cap version 7 + if _rc != 0 { local gen = substr("`gen'",1,5) } + version 6.0 + } + + + if "`output'" == "ordered" | "`output'" == "mlogit" { + tempname values + mat `values' = r(values) + local outcms = rowsof(r(probs)) + local count = 1 + while `count' <= `outcms' { + local k`count' = `values'[`count',1] + if `k`count'' < -9 | `k`count'' > 99 | int(`k`count'')!=`k`count'' { + di in red "category values must be integers between -9 and 99" + exit 198 + } + if `k`count'' < 0 { + local k`count' = abs(`k`count'') + local k`count' = "_`k`count''" + } + local count = `count' + 1 + } + } + + + if "`xis'"!="" { + tempname results + if "`output'" == "regress" { + matrix `results' = ( `xis' , r(xb) ) + } + if "`output'" == "binary" { + * grab output from binary model + matrix `results' = ( `xis' , r(p0) , r(p1) ) + } + if "`output'" == "ordered" | "`output'" == "mlogit" { + tempname probs newprob + mat `probs' = r(probs) + local outcms = rowsof(r(probs)) + matrix `results' = `xis' + local count = 1 + while `count' <= `outcms' { + matrix `newprob' = `probs'[`count', 1] + matrix `results' = `results' , `newprob' + local count = `count' + 1 + } + } + if "`output'" == "count" { + tempname probs newprob values + mat `values' = r(values) + mat `probs' = r(probs) + local outcms = rowsof(r(probs)) + local rmu = r(mu) + matrix `results' = `xis', `rmu' + local count = 1 + while `count' <= `outcms' { + matrix `newprob' = `probs'[`count', 1] + matrix `results' = `results' , `newprob' + local count = `count' + 1 + } + + } + if "`input'" == "twoeq" & "`output'"=="count" { + tempname az + matrix `az' = r(always0) + matrix `results' = `results' , `az' + } + + *=> saving is the initial run + if "`saving'" ~= "" { mat `saving' = `results' } + if "`using'" ~= "" { + cap mat list `using' + if _rc ~= 0 { + mat `using' = `results' + * OLD SYNTAX: error if `using' matrix does not already exist + * di in r "matrix `using' does not exist" + * exit 111 + } + else { mat `using' = (`using') \ (`results') } + } + } + +*=> generates creates the new variables + if "`gen'" ~= "" { + if "`output'" == "regress" { + local columns = "`gen'x `gen'xb" + } + if "`output'" == "binary" { + local columns = "`gen'x `gen'p0 `gen'p1" + } + if "`output'" == "ordered" | "`output'" == "mlogit" { + local columns "`gen'x" + local outcms = rowsof(r(probs)) + local count = 1 + while `count' <= `outcms' { + local columns "`columns' `gen'p`k`count''" + local count = `count' + 1 + } + } + if "`output'" == "count" { + local columns "`gen'x `gen'mu" + local outcms = rowsof(r(probs)) + local count = 0 + while `count' <= (`outcms'-1) { + local columns "`columns' `gen'p`count'" + local count = `count' + 1 + } + if "`input'"=="twoeq" { + local columns "`columns' `gen'inf" + } + } + * create new variables + matrix colnames `using' = `columns' + svmat `using', names(col) + + *=> label variables + label variable `gen'x "value of x" + if "`output'" == "regress" { + label variable `gen'xb "value of xb" + } + if "`output'" == "binary" { + label variable `gen'p0 "Pr(0)" + label variable `gen'p1 "Pr(1)" + } + if "`output'" == "ordered" { + tempname values + mat `values' = r(values) + local outcms = rowsof(r(probs)) + local count = 1 + while `count' <= `outcms' { + local count2 = `count' + label variable `gen'p`k`count'' "Pr(`k`count'')" + local count = `count' + 1 + } + } + if "`output'" == "mlogit" { + tempname values + mat `values' = r(values) + local outcms = rowsof(r(probs)) + local count = 1 + while `count' <= `outcms' { + local value = `values'[`count', 1] + local count2 = `count' + label variable `gen'p`k`count'' "Pr(`k`count'')" + local count = `count' + 1 + } + } + if "`output'" == "count" { + tempname values + mat `values' = r(values) + local outcms = rowsof(r(probs)) + local count = 1 + while `count' <= `outcms' { + local value = `values'[`count', 1] + label variable `gen'p`value' "Pr(`value')" + local count = `count' + 1 + } + if "`input'"=="twoeq" { + label variable `gen'inf "Pr(always0)" + } + } + +*=> for ordered and count variables, generate cumulative counts + if "`output'" == "ordered" { + local outcms = rowsof(r(probs)) + local count = 1 + while `count' <= `outcms' { + qui egen `gen's`k`count'' = rsum(`gen'p`k1'-`gen'p`k`count'') if `gen'p`k1'~=. + local cumul = "`cumul'`gen's`k`count'' " + label variable `gen's`k`count'' "Pr(<=`k`count'')" + local count = `count' + 1 + } + } + if "`output'" == "count" { + local outcms = rowsof(r(probs)) + local count = 0 + while `count' <= (`outcms'-1) { + qui egen `gen's`count' = rsum(`gen'p0-`gen'p`count') if `gen'p0~=. + local cumul = "`cumul'`gen's`count' " + label variable `gen's`count' "Pr(<=`count')" + local count = `count' + 1 + } + } + +*=> display new variables + di _n in g "New variables created by" in w " praccum" in y ":" + sum `columns' `cumul' + } /* generate */ +end + diff --git a/Modules/ado/plus/p/praccum.hlp b/Modules/ado/plus/p/praccum.hlp new file mode 100644 index 0000000..d5ad9b7 --- /dev/null +++ b/Modules/ado/plus/p/praccum.hlp @@ -0,0 +1,162 @@ +.- +help for ^praccum^ - 1.6.4 - 2Nov2005 +.- + +Accumulate results from ^prvalue^ +------------------------------- + + ^praccum^, [^xis(^value^)^ ^u^sing^(^matrixnm^)^ ^s^aving^(^matrixnm^)^ ^gen^erate^(^rootname^)^] + +where either saving() or using() are required. + +Description +----------- + +^praccum^ accumulates predictions from a series of calls to ^prvalue^ and +optionally saves these accumluated values to variables. These variables can +then be plotted. This command allows you to plot predicted values in +situations that cannot be handled by ^prgen^ (e.g., nonlinearities). + +The command works with cloglog, cnreg, intreg, logit, mlogit, mprobit, nbreg, +ologit, oprobit, poisson, probit, regress, slogit, tobit, zinb, zip, ztnb, +and ztp. + + +Options +------- + +^xis(^value^)^ specifies the value of the x-variable associated with the predicted + values that are being accumulated. If ^xis^ is not specified, new values + are not accumulated. + +^using(^matrixnm^)^ specifies the name of matrix to which accumulated results + should be added. ^matrixnm^ will be created if it does not exist. + +^saving(^matrixnm^)^: is only used to save the initial results and differs from + differs from ^using()^ in that it will overwrite ^matrixnm^ if it exists. + +^generate(^rootname^)^: root name of variables to be created from the matrix + specified by ^using^. This is only used when you are done accumulating + results and are ready to generate the variables. + +Examples of included squared terms +---------------------------------- + +Consider the logit: + +^. use binlfp,clear^ +^. gen age2 = age*age^ +^. logit lfp k5 k618 age age2 wc hc lwg inc^ + +If you want to plot the predictions against age, you cannot use ^prgen^ since +when age changes, age2 must also change. The command: + +^. prvalue , x(age=20 age2=400) rest(mean)^ + +computes predicted values for age=20 and age2=20*20=400. The command: + +^. praccum , saving(mage) xis(20)^ + +creates a matrix named mage that contains three columns. The first column will +have a 20 for the value of age; the second the probability of a 0 given the +values of the independent variables used in ^prvalue^, and the third column +will have the probability of a 1. We now change the value of age and add this +to the matrix mage: + +^. prvalue , x(age=25 age2=625) rest(mean)^ +^. praccum , using(mage) xis(25)^ + +Here we are just adding a row to mage. This process repeats for other values: + +^. prvalue , x(age=30 age2=900) rest(mean)^ +^. praccum , using(mage) xis(30)^ +^. prvalue , x(age=35 age2=1225) rest(mean)^ +^. praccum , using(mage) xis(35)^ +^. prvalue , x(age=40 age2=1600) rest(mean)^ +^. praccum , using(mage) xis(40)^ +^. prvalue , x(age=45 age2=2025) rest(mean)^ +^. praccum , using(mage) xis(45)^ +^. prvalue , x(age=50 age2=2500) rest(mean)^ +^. praccum , using(mage) xis(50)^ +^. prvalue , x(age=55 age2=3025) rest(mean)^ +^. praccum , using(mage) xis(55)^ +^. prvalue , x(age=60 age2=3600) rest(mean)^ +^. praccum , using(mage) xis(60) gen(agsq)^ + +Produces the output: + +^New variables created by praccum:^ + +^Variable | Obs Mean Std. Dev. Min Max^ +^---------+-----------------------------------------------------^ +^ agsqx | 9 40 13.69306 20 60^ +^ agsqp0 | 9 .4282142 .1752595 .2676314 .7479599^ +^ agsqp1 | 9 .5717858 .1752595 .2520402 .7323686 ^ + +Which can be plotted: + +^. graph agsqp1 agsqx,c(s)^ + +Example using ^forvalues^ +------------------------- + +The ^forvalues^ command makes using ^praccum^ much simpler. The +following yields the same output as the example above: + +^. capture matrix drop mage^ +^. forvalues count = 20(5)60 {^ +^. local countsq = `count'*`count'^ +^. prvalue, x(age `count' age2 `countsq') rest(mean) brief^ +^. praccum, using(mage) xis(`count')^ +^. }^ +^. praccum, using(mage) gen(agsq)^ + +Example using global macros +--------------------------- + +^forvalues^ is not available for Stata 6. Here, the task can still be +simplified by using global macros. The advantage of this approach is +that you can let Stata do the multiplying: + +^. global age = 20^ +^. global age2 = $age*$age^ +^. prvalue , x(age=$age age2=$age2) rest(mean)^ +^. praccum , saving(mage) xis($age)^ +^. global age = 25^ +^. global age2 = $age*$age^ +^. prvalue , x(age=$age age2=$age2) rest(mean)^ +^. praccum , using(mage) xis($age)^ +^. global age = 30^ +^. global age2 = $age*$age^ +^. prvalue , x(age=$age age2=$age2) rest(mean)^ +^. praccum , using(mage) xis($age)^ +^. global age = 35^ +^. global age2 = $age*$age^ +^. prvalue , x(age=$age age2=$age2) rest(mean)^ +^. praccum , using(mage) xis($age)^ +^. global age = 40^ +^. global age2 = $age*$age^ +^. prvalue , x(age=$age age2=$age2) rest(mean)^ +^. praccum , using(mage) xis($age)^ +^. global age = 45^ +^. global age2 = $age*$age^ +^. prvalue , x(age=$age age2=$age2) rest(mean)^ +^. praccum , using(mage) xis($age)^ +^. global age = 50^ +^. global age2 = $age*$age^ +^. prvalue , x(age=$age age2=$age2) rest(mean)^ +^. praccum , using(mage) xis($age)^ +^. global age = 55^ +^. global age2 = $age*$age^ +^. prvalue , x(age=$age age2=$age2) rest(mean)^ +^. praccum , using(mage) xis($age)^ +^. global age = 60^ +^. global age2 = $age*$age^ +^. prvalue , x(age=$age age2=$age2) rest(mean)^ +^. praccum , using(mage) xis($age) gen(agsq)^ +^. graph agsqp1 agsqx,c(s)^ + +.- +Authors: J. Scott Long - jslong@@indiana.edu + Jeremy Freese - jfreese@@ssc.wisc.edu + www.indiana.edu/~jslsoc/ diff --git a/Modules/ado/plus/p/prchange.ado b/Modules/ado/plus/p/prchange.ado new file mode 100644 index 0000000..a82be15 --- /dev/null +++ b/Modules/ado/plus/p/prchange.ado @@ -0,0 +1,1299 @@ +*! version 2.5.2 2009-12-11 jsl +* - deal with negative value in ologit for outcome option +* version 2.5.1 2009-12-10 jsl +* - deal with negative value in ologit + +capture program drop prchange +program define prchange, rclass + + * 1.9.0 + local caller = _caller() + + version 6 + tempname delthlf delt + tempname tobase tobase2 min max mean sd min2 max2 mean2 sd2 marg + tempname margout marg2 margou2 + tempname sdx sdxhalf minx maxx lobase hibase x_base xb xb_lo xb_hi mu + tempname p1 p_lo p_hi temp tmp tmp_lo tmp_hi vmarg vchange dchange basepr + tempname baseval basezi // 2006-02-18 for estout + mat def `baseval' = J(1,1,.) + mat def `basezi' = J(1,1,.) + tempname /*deltais*/ predis change // changed 05nov2007 bj + mat def `change' = J(1,1,.) + mat def `predis' = J(1,1,.) + tempname nomtemp + +*=> classify each valid type of model + + *zt 18Feb2005 + local iszt = 0 // + if ("`e(cmd)'"=="ztp" | "`e(cmd)'"=="ztnb") { + local iszt = 1 + } + if "`e(cmd)'"=="ztp" { local io = "typical count" } + if "`e(cmd)'"=="ztnb" { local io = "typical count" } + + if "`e(cmd)'"=="cloglog" { local io = "typical binary" } + if "`e(cmd)'"=="gologit" { local io = "typical ordered" } + if "`e(cmd)'"=="logistic" { local io = "typical binary" } + if "`e(cmd)'"=="logit" { local io = "typical binary" } + if "`e(cmd)'"=="mlogit" { local io = "typical nomord" } + if "`e(cmd)'"=="mprobit" { local io = "typical nomord" } // 16Feb2008 sl + if "`e(cmd)'"=="nbreg" { local io = "typical count" } + if "`e(cmd)'"=="ologit" { local io = "typical nomord" } + if "`e(cmd)'"=="oprobit" { local io = "typical nomord" } + if "`e(cmd)'"=="slogit" { local io = "typical nomord" } + if "`e(cmd)'"=="poisson" { local io = "typical count" } + if "`e(cmd)'"=="probit" { local io = "typical binary" } + if "`e(cmd)'"=="zinb" { local io = "twoeq count" } + if "`e(cmd)'"=="zip" { local io = "twoeq count" } + if "`io'"=="" { + di + di in y "prchange" in r " does not work for last model estimated." + exit + } + local input : word 1 of `io' /* input routine to _pepred */ + local output : word 2 of `io' /* output routine */ + +*=> get info about variables + + _perhs + local nrhs = `r(nrhs)' + local rhsnms "`r(rhsnms)'" + if "`input'"=="twoeq" { + local nrhs2 = `r(nrhs2)' + local rhsnms2 "`r(rhsnms2)'" + } + if "`output'" != "regress" & "`output'" != "tobit" { + _pecats + local ncats = r(numcats) + local catnms8 `r(catnms8)' + local catvals `r(catvals)' + local catnms `r(catnms)' + } + +*=> decode input + + syntax [varlist(default=none)] [if] [in] /* + */ [, x(passthru) Rest(passthru) Level(passthru) Delta(real 1) /* + */ UNCentered Fromto all Outcome(string) noBAse noLAbel Help Brief /* + */ CONditional ] + + *zt 19Feb2005 + if `iszt'==1 & "`conditional'"=="conditional" /// + & "`outcome'"=="0" { + di _n in r "conditional probabilities for outcome 0 are undefined." + exit + } + + *convert delta() to scalars + sca `delt' = `delta' + sca `delthlf' = `delt'/2 + + * _pebase handles input and sets base values + _pebase `if' `in', `x' `rest' `choices' `all' + mat `tobase' = r(pebase) + if "`input'"=="twoeq" { mat `tobase2' = r(pebase2) } + + * _peife combines `if' with e(sample)==1 if needed + _peife `if', `all' + local if "`r(if)'" + + * summary statistics on rhs variables + quietly _pesum `if' `in' + mat `min' = r(Smin) + mat `min' = `min'[1, 2...] + mat `max' = r(Smax) + mat `max' = `max'[1, 2...] + mat `mean' = r(Smean) + mat `mean' = `mean'[1, 2...] + mat `sd' = r(Ssd) + mat `sd' = `sd'[1, 2...] + + * 2006-02-18 - base values to be returned for estout + mat `baseval' = `mean' \ `sd' \ `min' \ `max' + mat rownames `baseval' = Mean SD Min "Max" + + if "`input'"=="twoeq" { + quietly _pesum `if' `in', two + mat `min2' = r(Smin) + mat `min2' = `min2'[1, 2...] + mat `max2' = r(Smax) + mat `max2' = `max2'[1, 2...] + mat `mean2' = r(Smean) + mat `mean2' = `mean2'[1, 2...] + mat `sd2' = r(Ssd) + mat `sd2' = `sd2'[1, 2...] + * 2006-02-18 - zip & zinb base values to be returned for estout + mat `basezi' = `mean2' \ `sd2' \ `min2' \ `max2' + mat rownames `basezi' = Mean SD Min Max + } + + * set values of PE_in, to be modified before sent to _pepred + capture mat drop PE_in + mat PE_in = `tobase' + if "`input'"=="twoeq" { + capture mat drop PE_in2 + mat PE_in2 = `tobase2' + } + + if "`varlist'" == "" { local varlist "`rhsnms'" } + +*=> handle outcome() option + + if "`outcome'"!="" { + if "`output'"=="binary" { + di in r "outcome() not allowed for prchange after `e(cmd)'" + exit 198 + } + if "`output'"=="nomord" { + local found "no" + * cycle through outcome categories + local i = 1 + while `i' <= `ncats' { + local valchk : word `i' of `catvals' + local nmchk : word `i' of `catnms' + * outcome() value to category value + if ("`outcome'"=="`valchk'") | ("`outcome'"=="`nmchk'") { + local found "yes" + local outcmv = "`valchk'" +* 2.5.2 +local outcmvnm "`outcmv'" +if `outcome'<0 { + local outcmvnm = abs(`outcmv') + local outcmvnm "_`outcmvnm'" +} + + if "`valchk'"!="`nmchk'" { local outcmnm " (`nmchk')" } + local outcome = `i' + local i = `ncats' + } + local i = `i' + 1 + } + if "`found'"=="no" { + di in r "`outcome' not category of `e(depvar)'" + exit 198 + } + } // output is nomord + + if "`output'"=="count" { + confirm integer number `outcome' + if `outcome' < 0 { exit 198 } + local outcmv "`outcome'" + } + } + +*=> compute marginal effects (_pemarg requires mat PE_base that was set by _pebase) + + * zt 19Feb2005 TO DO + * 1.8.0 _pemarg + _pemarg, caller(`caller') // 1.9.0 + local hasmarg = "`r(hasmarg)'" + if "`hasmarg'"=="yes" { + mat `marg' = r(marginal) + if "`output'"=="count" | "`output'"=="binary" { + mat `marg' = `marg'[2, 1...] + } + } + +*=> header information + + if "`brief'"=="" { + + *zt 19Feb2005 + if `iszt'==1 { + if "`conditional'"=="" { + local type "Unconditional " + } + else { + local type "Conditional " + } + } + di _n in y "`e(cmd)'" _c + if "`output'"=="count" & "`outcome'"=="" { + di in g ": Changes in `type'Rate for " _c + } + else { di in g ": Changes in `type'Probabilities for " _c} + di in y "`e(depvar)'" + if "`outcome'"!="" { + di in g _new "Outcome: " in y "`outcmv'" in y "`outcmnm'" // 2007-01-07 + } + + *print value of delta if specified + if `delt'!=1 { + if "`uncentered'"!="" { + di _n in g "(Note: delta = " in y `delt' in g ")" + } + else { + di _n in g "(Note: d = " in y `delt' in g ")" + } + } + } + +*=> cycle through all variables in varlist +* varnum = matrix position of rhs variable; -1 if not in count equation +* varnum2 =position in binary matrix of rhs var in ZIP/ZINB; -1 if absent + + local i = 1 + local i_to : word count `varlist' + while `i' <= `i_to' { + local var : word `i' of `varlist' + local found "no" + local varnum -1 + local i2 = 1 + local i2_to : word count `rhsnms' + while `i2' <= `i2_to' { + local varchk : word `i2' of `rhsnms' + unab varchk : `varchk', max(1) + if "`var'"=="`varchk'" { + local found "yes" + local varnum = `i2' + local i2 = `i2_to' + } + local i2 = `i2' + 1 + } /* while `i2' < `i2_to' */ + + if "`input'"=="twoeq" { + local i3 = 1 + local i3_to : word count `rhsnms2' + local varnum2 -1 + while `i3' <= `i3_to' { + local varchk : word `i3' of `rhsnms2' + unab varchk : `varchk', max(1) + if "`var'"=="`varchk'" { + local found "yes" + local varnum2 = `i3' + local i3 = `i3_to' + } + local i3 = `i3' + 1 + } + } /* if "`input'"=="twoeq" */ + + if "`found'"=="no" { + di in r "`var' not rhs variable" + exit 198 + } + +*=> arrange `marg' matrix for output + + if `varnum' != -1 & "`hasmarg'"=="yes" { + if "`output'"=="nomord" | "`output'"=="mlogit" { + mat `margout' = nullmat(`margout') \ `marg'[`varnum', 1...] + } + else { + mat `margout' = nullmat(`margout') , `marg'[1, `varnum'] + } + } + + *=> PE_in has values of start and end of change variable + * and levels of other variables for all changes considered + if `varnum' != -1 { + + * create scalar values for discrete change calculations + sca `sdx' = `sd'[1, `varnum'] + sca `sdxhalf' = `sdx' / 2 + sca `minx' = `min'[1, `varnum'] + sca `maxx' = `max'[1, `varnum'] + sca `x_base' = `tobase'[1, `varnum'] + + * for min --> max + mat `lobase' = `tobase' + mat `lobase'[1, `varnum'] = `minx' + mat PE_in = PE_in \ `lobase' + mat `hibase' = `tobase' + mat `hibase'[1, `varnum'] = `maxx' + mat PE_in = PE_in \ `hibase' + + * low and high values for 0 --> 1 + mat `lobase' = `tobase' + mat `lobase'[1, `varnum'] = 0 + mat PE_in = PE_in \ `lobase' + mat `hibase' = `tobase' + mat `hibase'[1, `varnum'] = 1 + mat PE_in = PE_in \ `hibase' + + * +/- delta + if "`uncentered'"=="" { + mat `lobase' = `tobase' + mat `lobase'[1, `varnum'] = `x_base'-`delthlf' + mat PE_in = PE_in \ `lobase' + mat `hibase' = `tobase' + mat `hibase'[1, `varnum'] = `x_base'+`delthlf' + mat PE_in = PE_in \ `hibase' + } + else { + mat `lobase' = `tobase' + mat `lobase'[1, `varnum'] = `x_base' + mat PE_in = PE_in \ `lobase' + mat `hibase' = `tobase' + mat `hibase'[1, `varnum'] = `x_base'+`delt' + mat PE_in = PE_in \ `hibase' + } + + * for +/- sdx + if "`uncentered'"=="" { + mat `lobase' = `tobase' + mat `lobase'[1, `varnum'] = `x_base'-`sdxhalf' + mat PE_in = PE_in \ `lobase' + mat `hibase' = `tobase' + mat `hibase'[1, `varnum'] = `x_base'+`sdxhalf' + mat PE_in = PE_in \ `hibase' + } + else { + mat `lobase' = `tobase' + mat `lobase'[1, `varnum'] = `x_base' + mat PE_in = PE_in \ `lobase' + mat `hibase' = `tobase' + mat `hibase'[1, `varnum'] = `x_base'+`sdx' + mat PE_in = PE_in \ `hibase' + } + + } /* if `varnum' != -1 */ + + * if rhs variable not in equation, then all PE_in rows == tobase + else { + mat PE_in = nullmat(PE_in) \ `tobase' + mat PE_in = PE_in \ `tobase' + mat PE_in = PE_in \ `tobase' + mat PE_in = PE_in \ `tobase' + mat PE_in = PE_in \ `tobase' + mat PE_in = PE_in \ `tobase' + mat PE_in = PE_in \ `tobase' + mat PE_in = PE_in \ `tobase' + } + + * handle PE_in2 for second equation if zip/zinb + if "`input'"=="twoeq" { + if "`varnum2'" != "-1" { + + tempname sdx sdxhalf minx maxx + sca `sdx' = `sd2'[1, `varnum2'] + sca `sdxhalf' = `sdx' / 2 + sca `minx' = `min2'[1, `varnum2'] + sca `maxx' = `max2'[1, `varnum2'] + tempname lobase hibase x_base + sca `x_base' = `tobase2'[1, `varnum2'] + + * min --> max + mat `lobase' = `tobase2' + mat `lobase'[1, `varnum2'] = `minx' + mat PE_in2 = PE_in2 \ `lobase' + mat `hibase' = `tobase2' + mat `hibase'[1, `varnum2'] = `maxx' + mat PE_in2 = PE_in2 \ `hibase' + + * 0 --> 1 + mat `lobase' = `tobase2' + mat `lobase'[1, `varnum2'] = 0 + mat PE_in2 = PE_in2 \ `lobase' + mat `hibase' = `tobase2' + mat `hibase'[1, `varnum2'] = 1 + mat PE_in2 = PE_in2 \ `hibase' + + * +/- delta + if "`uncentered'"=="" { + mat `lobase' = `tobase2' + mat `lobase'[1, `varnum2'] = `x_base'-`delthlf' + mat PE_in2 = PE_in2 \ `lobase' + mat `hibase' = `tobase2' + mat `hibase'[1, `varnum2'] = `x_base'+`delthlf' + mat PE_in2 = PE_in2 \ `hibase' + } + else { + mat `lobase' = `tobase2' + mat `lobase'[1, `varnum2'] = `x_base' + mat PE_in2 = PE_in2 \ `lobase' + mat `hibase' = `tobase2' + mat `hibase'[1, `varnum2'] = `x_base'+`delt' + mat PE_in2 = PE_in2 \ `hibase' + } + + * +/- sdx + if "`uncentered'"=="" { + mat `lobase' = `tobase2' + mat `lobase'[1, `varnum2'] = `x_base'-`sdxhalf' + mat PE_in2 = PE_in2 \ `lobase' + mat `hibase' = `tobase2' + mat `hibase'[1, `varnum2'] = `x_base'+`sdxhalf' + mat PE_in2 = PE_in2 \ `hibase' + } + else { + mat `lobase' = `tobase2' + mat `lobase'[1, `varnum2'] = `x_base' + mat PE_in2 = PE_in2 \ `lobase' + mat `hibase' = `tobase2' + mat `hibase'[1, `varnum2'] = `x_base'+`sdx' + mat PE_in2 = PE_in2 \ `hibase' + } + + } /* if "`varnum2'" != "-1" */ + + * if not in inflate equation, PE_in2==tobase2 + else { + mat PE_in2 = nullmat(PE_in2) \ `tobase2' + mat PE_in2 = PE_in2 \ `tobase2' + mat PE_in2 = PE_in2 \ `tobase2' + mat PE_in2 = PE_in2 \ `tobase2' + mat PE_in2 = PE_in2 \ `tobase2' + mat PE_in2 = PE_in2 \ `tobase2' + mat PE_in2 = PE_in2 \ `tobase2' + mat PE_in2 = PE_in2 \ `tobase2' + } /* else */ + + } /* if "`input'"=="twoeq" */ + + local i = `i' + 1 + } /* while `i' <= `i_to' */ + + +*=> _pepred calculates probabilities based on PE_in + + _pepred, `level' + local max_i = r(maxcount) + +*=> BINARY MODELS + + if "`output'"=="binary" { + * predicted probability for all rows of PE_in + mat `p1' = r(p1) + local i = 1 + local i_to : word count `varlist' + mat `dchange' = J(`i_to', 4, 0) + local dchcol 1 + if "`fromto'"=="fromto" { + mat `dchange' = J(`i_to', 12, 0) + local dchcol 3 + } + * cycle though variables + while `i' <= `i_to' { + * calculate discrete change as difference and put in dchange matrix + local anchor = (`i' * 8) - 6 + sca `p_lo' = `p1'[`anchor', 1] + sca `p_hi' = `p1'[`anchor'+1, 1] + if "`fromto'"=="fromto" { + mat `dchange'[`i', 1] = `p_lo' + mat `dchange'[`i', 2] = `p_hi' + } + mat `dchange'[`i', 1*`dchcol'] = `p_hi' - `p_lo' + sca `p_lo' = `p1'[`anchor'+2, 1] + sca `p_hi' = `p1'[`anchor'+3, 1] + if "`fromto'"=="fromto" { + mat `dchange'[`i', 4] = `p_lo' + mat `dchange'[`i', 5] = `p_hi' + } + mat `dchange'[`i', 2*`dchcol'] = `p_hi' - `p_lo' + sca `p_lo' = `p1'[`anchor'+4, 1] + sca `p_hi' = `p1'[`anchor'+5, 1] + if "`fromto'"=="fromto" { + mat `dchange'[`i', 7] = `p_lo' + mat `dchange'[`i', 8] = `p_hi' + } + mat `dchange'[`i', 3*`dchcol'] = `p_hi' - `p_lo' + sca `p_lo' = `p1'[`anchor'+6, 1] + sca `p_hi' = `p1'[`anchor'+7, 1] + if "`fromto'"=="fromto" { + mat `dchange'[`i', 10] = `p_lo' + mat `dchange'[`i', 11] = `p_hi' + } + mat `dchange'[`i', 4*`dchcol'] = `p_hi' - `p_lo' + local i = `i' + 1 + } /* while `i' <= `i_to' */ + + mat rownames `dchange' = `varlist' + *added to make matrix headings stata7 compatible + mat _PEtemp = `dchange'' + _peabbv _PEtemp + mat `dchange' = _PEtemp' + + *column names for centered change + if "`uncentered'"=="" { + if `delt' == 1 { + mat colnames `dchange' = min->max 0->1 -+1/2 -+sd/2 + if "`fromto'"=="fromto" { + mat colnames `dchange' = x=min x=max min->max /* + */ x=0 x=1 0->1 x-1/2 x+1/2 -+1/2 x-1/2sd x+1/2sd -+sd/2 + } + } + else { + mat colnames `dchange' = min->max 0->1 -+d/2 -+sd/2 + if "`fromto'"=="fromto" { + mat colnames `dchange' = x=min x=max min->max /* + */ x=0 x=1 0->1 x-d/2 x+d/2 -+d/2 x-1/2sd x+1/2sd -+sd/2 + } + } + } + *column names for uncentered change + else { + if `delt' == 1 { + mat colnames `dchange' = min->max 0->1 +1 +sd + if "`fromto'"=="fromto" { + mat colnames `dchange' = x=min x=max min->max /* + */ x=0 x=1 0->1 x x+1 +1 x x+sd +sd + } + } + else { + mat colnames `dchange' = min->max 0->1 +delta +sd + if "`fromto'"=="fromto" { + mat colnames `dchange' = x=min x=max min->max /* + */ x=0 x=1 0->1 x x+delta +delta x-sd x+sd +sd + } + } + } + + if "`fromto'"=="fromto" { + mat coleq `dchange' = from to dif from to dif /* + */ from to dif from to dif + } + + * add marginals to output if available + if "`hasmarg'"=="yes" { + mat rownames `margout' = MargEfct + mat roweq `margout' = _ + mat `margout' = `margout'' + mat `dchange' = `dchange', `margout' + } + + * output list discrete change matrix + mat list `dchange', noheader f(%8.4f) + mat `change' = `dchange'' // 2006-02-18 for estout + + * list probabilities at tobase if desired + mat temp = r(p0) + mat temp2 = r(p1) + mat `basepr' = temp[1,1] , temp2[1,1] + mat rownames `basepr' = "Pr(y|x)" + if "`label'"=="nolabel" { mat colnames `basepr' = `catvals' } + else { mat colnames `basepr' = `catnms8' } + if "`brief'"=="" { mat list `basepr', noheader f(%8.4f) } + mat `predis' = `basepr' // 2006-02-18 for estout + + } /* if "`output'"=="binary" */ + +*=> COUNT MODELS, but not zt + + if "`output'"=="count" & `iszt'==0 { + if "`outcome'"=="" { mat `tmp' = r(mu) } + else { mat `tmp' = r(p`outcome') } + local i = 1 + local i_to : word count `varlist' + mat `dchange' = J(`i_to', 4, 0) + local dchcol 1 + if "`fromto'"=="fromto" { + mat `dchange' = J(`i_to', 12, 0) + local dchcol 3 + } + * cycle through all variables specified in varlist + while `i' <= `i_to' { + * calculate discrete change and put in dchange matrix + local anchor = (`i' * 8) - 6 + sca `tmp_lo' = `tmp'[`anchor', 1] + sca `tmp_hi' = `tmp'[`anchor'+1, 1] + if "`fromto'"=="fromto" { + mat `dchange'[`i', 1] = `tmp_lo' + mat `dchange'[`i', 2] = `tmp_hi' + } + mat `dchange'[`i', `dchcol'*1] = `tmp_hi' - `tmp_lo' + sca `tmp_lo' = `tmp'[`anchor'+2, 1] + sca `tmp_hi' = `tmp'[`anchor'+3, 1] + if "`fromto'"=="fromto" { + mat `dchange'[`i', 4] = `tmp_lo' + mat `dchange'[`i', 5] = `tmp_hi' + } + mat `dchange'[`i', `dchcol'*2] = `tmp_hi' - `tmp_lo' + sca `tmp_lo' = `tmp'[`anchor'+4, 1] + sca `tmp_hi' = `tmp'[`anchor'+5, 1] + if "`fromto'"=="fromto" { + mat `dchange'[`i', 7] = `tmp_lo' + mat `dchange'[`i', 8] = `tmp_hi' + } + mat `dchange'[`i', `dchcol'*3] = `tmp_hi' - `tmp_lo' + sca `tmp_lo' = `tmp'[`anchor'+6, 1] + sca `tmp_hi' = `tmp'[`anchor'+7, 1] + if "`fromto'"=="fromto" { + mat `dchange'[`i', 10] = `tmp_lo' + mat `dchange'[`i', 11] = `tmp_hi' + } + mat `dchange'[`i', `dchcol'*4] = `tmp_hi' - `tmp_lo' + local i = `i' + 1 + } + mat rownames `dchange' = `varlist' + *added to make matrix headings stata7 compatible + mat _PEtemp = `dchange'' + _peabbv _PEtemp + mat `dchange' = _PEtemp' + + *column names for centered change + if "`uncentered'" == "" { + *unit change + if `delt' == 1 { + mat colnames `dchange' = min->max 0->1 -+1/2 -+sd/2 + if "`fromto'"=="fromto" { + mat colnames `dchange' = x=min x=max min->max /* + */ x=0 x=1 0->1 x-1/2 x+1/2 -+1/2 x-1/2sd x+1/2sd -+sd/2 + } + } + *change specified by delta() + else { + mat colnames `dchange' = min->max 0->1 -+d/2 -+sd/2 + if "`fromto'"=="fromto" { + mat colnames `dchange' = x=min x=max min->max /* + */ x=0 x=1 0->1 x-d/2 x+d/2 -+d/2 x-1/2sd x+1/2sd -+sd/2 + } + } + } + *column names for uncentered change + else { + *unit change + if `delt' == 1 { + mat colnames `dchange' = min->max 0->1 +1 +sd + if "`fromto'"=="fromto" { + mat colnames `dchange' = x=min x=max min->max /* + */ x=0 x=1 0->1 x x+1 -+1 x x+sd +sd + } + } + *change specified by delta + else { + mat colnames `dchange' = min->max 0->1 +delta +sd + if "`fromto'"=="fromto" { + mat colnames `dchange' = x=min x=max min->max /* + */ x=0 x=1 0->1 x x+delta +delta x x+sd +sd + } + } + } + if "`fromto'"=="fromto" { + mat coleq `dchange' = from to dif from to dif from /* + */ to dif from to dif + } + + if "`hasmarg'"=="yes" & "`outcome'"=="" { + mat rownames `margout' = MargEfct + mat roweq `margout' = _ + mat `margout' = `margout'' + mat `dchange' = `dchange', `margout' + } + mat list `dchange', noheader f(%8.4f) + if "`outcome'"=="" { + local i = 0 + mat `temp' = r(mu) + sca `mu' = `temp'[1,1] + mat `predis' = `mu' // 2006-02-18 for estout + mat rownames `predis' = exp(xb) // 2006-02-18 for estout + if "`brief'"=="" { di _n in g "exp(xb): " in y %8.4f `mu' } + } + else { + local i = 0 + while `i' <= `max_i' { + mat `temp' = r(p`i') + mat `basepr' = nullmat(`basepr') , `temp'[1, 1] + local cntvals "`cntvals'`i' " + local i = `i' + 1 + } + mat rownames `basepr' = "Pr(y|x)" + mat colnames `basepr' = `cntvals' + if "`brief'"=="" { mat list `basepr', noheader f(%8.4f) } + mat `predis' = `basepr' // 2006-02-18 for estout + mat rownames `predis' = "Pr(y|x)" // 2006-02-18 for estout + } + mat `change' = `dchange'' // 2006-02-18 for estout + } + +*=> ZT COUNT MODELS 19Feb2005 + + if `iszt'==1 { + if "`conditional'"=="" { + local type "" + } + else { + local type "C" + } + + * grab conditional or not based on type + if "`outcome'"=="" { mat `tmp' = r(`type'mu) } + else { mat `tmp' = r(`type'p`outcome') } + local i = 1 + local i_to : word count `varlist' + mat `dchange' = J(`i_to', 4, 0) + local dchcol 1 + if "`fromto'"=="fromto" { + mat `dchange' = J(`i_to', 12, 0) + local dchcol 3 + } + + * cycle through all variables specified in varlist + while `i' <= `i_to' { + * calculate discrete change and put in dchange matrix + local anchor = (`i' * 8) - 6 + sca `tmp_lo' = `tmp'[`anchor', 1] + sca `tmp_hi' = `tmp'[`anchor'+1, 1] + if "`fromto'"=="fromto" { + mat `dchange'[`i', 1] = `tmp_lo' + mat `dchange'[`i', 2] = `tmp_hi' + } + mat `dchange'[`i', `dchcol'*1] = `tmp_hi' - `tmp_lo' + sca `tmp_lo' = `tmp'[`anchor'+2, 1] + sca `tmp_hi' = `tmp'[`anchor'+3, 1] + if "`fromto'"=="fromto" { + mat `dchange'[`i', 4] = `tmp_lo' + mat `dchange'[`i', 5] = `tmp_hi' + } + mat `dchange'[`i', `dchcol'*2] = `tmp_hi' - `tmp_lo' + sca `tmp_lo' = `tmp'[`anchor'+4, 1] + sca `tmp_hi' = `tmp'[`anchor'+5, 1] + if "`fromto'"=="fromto" { + mat `dchange'[`i', 7] = `tmp_lo' + mat `dchange'[`i', 8] = `tmp_hi' + } + mat `dchange'[`i', `dchcol'*3] = `tmp_hi' - `tmp_lo' + sca `tmp_lo' = `tmp'[`anchor'+6, 1] + sca `tmp_hi' = `tmp'[`anchor'+7, 1] + if "`fromto'"=="fromto" { + mat `dchange'[`i', 10] = `tmp_lo' + mat `dchange'[`i', 11] = `tmp_hi' + } + mat `dchange'[`i', `dchcol'*4] = `tmp_hi' - `tmp_lo' + local i = `i' + 1 + } + mat rownames `dchange' = `varlist' + *added to make matrix headings stata7 compatible + mat _PEtemp = `dchange'' + _peabbv _PEtemp + mat `dchange' = _PEtemp' + + *column names for centered change + if "`uncentered'" == "" { + *unit change + if `delt' == 1 { + mat colnames `dchange' = min->max 0->1 -+1/2 -+sd/2 + if "`fromto'"=="fromto" { + mat colnames `dchange' = x=min x=max min->max /* + */ x=0 x=1 0->1 x-1/2 x+1/2 -+1/2 x-1/2sd x+1/2sd -+sd/2 + } + } + *change specified by delta() + else { + mat colnames `dchange' = min->max 0->1 -+d/2 -+sd/2 + if "`fromto'"=="fromto" { + mat colnames `dchange' = x=min x=max min->max /* + */ x=0 x=1 0->1 x-d/2 x+d/2 -+d/2 x-1/2sd x+1/2sd -+sd/2 + } + } + } + *column names for uncentered change + else { + *unit change + if `delt' == 1 { + mat colnames `dchange' = min->max 0->1 +1 +sd + if "`fromto'"=="fromto" { + mat colnames `dchange' = x=min x=max min->max /* + */ x=0 x=1 0->1 x x+1 -+1 x x+sd +sd + } + } + *change specified by delta + else { + mat colnames `dchange' = min->max 0->1 +delta +sd + if "`fromto'"=="fromto" { + mat colnames `dchange' = x=min x=max min->max /* + */ x=0 x=1 0->1 x x+delta +delta x x+sd +sd + } + } + } + if "`fromto'"=="fromto" { + mat coleq `dchange' = from to dif from to dif from /* + */ to dif from to dif + } + + if "`hasmarg'"=="yes" & "`outcome'"=="" { + mat rownames `margout' = MargEfct + mat roweq `margout' = _ + mat `margout' = `margout'' + mat `dchange' = `dchange', `margout' + } + mat list `dchange', noheader f(%8.4f) + mat `change' = `dchange'' // 2006-02-18 for estout + + if "`outcome'"=="" { + local i = 0 + mat `temp' = r(mu) + sca `mu' = `temp'[1,1] + mat `predis' = `mu' // 2006-02-18 for estout + mat rownames `predis' = exp(xb) // 2006-02-18 for estout + + if "`brief'"=="" { di _n in g "exp(xb): " in y %8.4f `mu' } + } + else { + local i = 0 + while `i' <= `max_i' { + mat `temp' = r(p`i') + mat `basepr' = nullmat(`basepr') , `temp'[1, 1] + local cntvals "`cntvals'`i' " + local i = `i' + 1 + } + mat rownames `basepr' = "Pr(y|x)" + mat colnames `basepr' = `cntvals' + if "`brief'"=="" { mat list `basepr', noheader f(%8.4f) } + mat `predis' = `basepr' // 2006-02-18 for estout + mat rownames `predis' = "Pr(y|x)" // 2006-02-18 for estout + } + } + +*=> NOMINAL and ORDINAL + + * jsl 10/23/00 - add average absolute discrete change + if "`output'"=="nomord" { + local dchcol 1 + if "`fromto'"=="fromto" { local dchcol 3 } + local i = 1 + local i_to : word count `varlist' + * loop over variables + tempname a01 a1 asd arange amarg // changed 23oct2007 bj + mat `amarg' = J(1,`i_to',0) // added 23oct2007 bj + while `i' <= `i_to' { + scalar `a01' = 0 + scalar `a1' = 0 + scalar `asd' = 0 + scalar `arange' = 0 + local ncats1 = `ncats' + 1 + mat `vchange' = J(4, `ncats1', 0) + if "`fromto'"=="fromto" { mat `vchange' = J(12, `ncats1', 0) } + local anchor = (`i' * 8) - 6 + local i2 = 2 + local i2_to = `ncats1' + * loop over categories + while `i2' <= `i2_to' { + local tmp = `i2' - 1 + mat `temp' = r(p`tmp') + sca `p_lo' = `temp'[`anchor', 1] + sca `p_hi' = `temp'[`anchor'+1, 1] + if "`fromto'"=="fromto" { + mat `vchange'[1, `i2'] = `p_lo' + mat `vchange'[2, `i2'] = `p_hi' + } + * range + mat `vchange'[`dchcol'*1, `i2'] = `p_hi' - `p_lo' + scalar `arange' = `arange' + abs(`p_hi' - `p_lo')/`ncats' + mat `vchange'[`dchcol'*1, 1] = `arange' + sca `p_lo' = `temp'[`anchor'+2, 1] + sca `p_hi' = `temp'[`anchor'+3, 1] + if "`fromto'"=="fromto" { + mat `vchange'[4, `i2'] = `p_lo' + mat `vchange'[5, `i2'] = `p_hi' + } + * 0->1 + mat `vchange'[`dchcol'*2, `i2'] = `p_hi' - `p_lo' + scalar `a01' = `a01' + abs(`p_hi' - `p_lo')/`ncats' + mat `vchange'[`dchcol'*2, 1] = `a01' + * -+1 + sca `p_lo' = `temp'[`anchor'+4, 1] + sca `p_hi' = `temp'[`anchor'+5, 1] + if "`fromto'"=="fromto" { + mat `vchange'[7, `i2'] = `p_lo' + mat `vchange'[8, `i2'] = `p_hi' + } + mat `vchange'[`dchcol'*3, `i2'] = `p_hi' - `p_lo' + scalar `a1' = `a1' + abs(`p_hi' - `p_lo')/`ncats' + mat `vchange'[`dchcol'*3, 1] = `a1' + * -+sd + sca `p_lo' = `temp'[`anchor'+6, 1] + sca `p_hi' = `temp'[`anchor'+7, 1] + if "`fromto'"=="fromto" { + mat `vchange'[10, `i2'] = `p_lo' + mat `vchange'[11, `i2'] = `p_hi' + } + mat `vchange'[`dchcol'*4, `i2'] = `p_hi' - `p_lo' + scalar `asd' = `asd' + abs(`p_hi' - `p_lo')/`ncats' + mat `vchange'[`dchcol'*4, 1] = `asd' + local i2 = `i2' + 1 + + } /* loop over categories */ + local var : word `i' of `varlist' + + * column names for centered change + if "`uncentered'"=="" { + if `delt'==1 { + mat rownames `vchange' = "Min->Max" " 0->1" " -+1/2" /* + */ " -+sd/2" + if "`fromto'"=="fromto" { + mat rownames `vchange' = " x=min" " x=max" "min->max" /* + */ " x=0" " x=1" " 0->1" " x-1/2" " x+1/2" /* + */ " -+1/2" " x-1/2sd" " x+1/2sd" " -+sd/2" + } + } + else { + mat rownames `vchange' = "Min->Max" " 0->1" " -+d/2" /* + */ " -+sd/2" + if "`fromto'"=="fromto" { + mat rownames `vchange' = " x=min" " x=max" "min->max" /* + */ " x=0" " x=1" " 0->1" " x-d/2" " x+d/2" /* + */ " -+d/2" " x-1/2sd" " x+1/2sd" " -+sd/2" + } + } + } + * uncentered change + else { + if `delt'==1 { + mat rownames `vchange' = "Min->Max" " 0->1" " +1" /* + */ " +sd" + if "`fromto'"=="fromto" { + mat rownames `vchange' = " x=min" " x=max" "min->max" /* + */ " x=0" " x=1" " 0->1" " x" " x+1" /* + */ " +1" " x" " x+sd" " +sd" + } + } + else { + mat rownames `vchange' = "Min->Max" " 0->1" " +delta" /* + */ " +sd" + if "`fromto'"=="fromto" { + mat rownames `vchange' = " x=min" " x=max" "min->max" /* + */ " x=0" " x=1" " 0->1" " x" " x+delta" /* + */ " +delta" " x" " x+sd" " +sd" + } + } + } + if "`fromto'"=="fromto" { + mat roweq `vchange' = from to dif from to dif from /* + */ to dif from to dif + } + +*=> save PE_dc with discrete change values; used by mlogplot and mlogview + + tempname zeros tempmat + * 1 row x ncats with 0's + mat `zeros' = J(1, `ncats', 0) + mat rownames `zeros' = " void" + * is it binary? + capture assert `var' == 0 | `var' == 1 | `var' == . `if' `in' + * if binary, only 0/1 in 2nd row + if _rc == 0 { + * DROP 16Nov2005 1.6.9 + * mat `tempmat' = `zeros' \ `vchange'[1,2...] \ `zeros' \ `zeros' \ `zeros' + * 16Nov2005 1.6.9 + mat `tempmat' = `vchange'[2,2...] \ `vchange'[1,2...] \ `zeros' /* + */ \ `zeros' \ `zeros' + } /* else, 1: min/max 2:null 3:1 4:sd */ + else { + + /* DROP 16Nov2005 1.6.9 + * contains 0->1, zeros, -+1, -+sd + mat `tempmat' = `vchange'[2,2...] \ /* + */ `zeros' \ `vchange'[3..4,2...] \ `zeros' + */ + * 16Nov2005 1.6.9 + * contains 0->1, min->max, -+1, -+sd + mat `tempmat' = `vchange'[2,2...] \ /* + */ `vchange'[1,2...] \ `vchange'[3..4,2...] \ `zeros' + + } + mat roweq `tempmat' = `var' + if "`i'"=="1" { + mat PE_dc = `tempmat' + if "`label'"=="nolabel" { mat colnames PE_dc = `catvals' } + else { mat colnames PE_dc = `catnms8' } + } + if "`i'"!="1" { + mat PE_dc = PE_dc \ `tempmat' + } + + * grab all info on change + mat `nomtemp' = nullmat(`nomtemp') \ `vchange' // 2006-02-18 for estout + +*=> set up matrices for output + + if "`label'"=="nolabel" { + mat colnames `vchange' = "Avg|Chg|" `catvals' + } + else { + mat colnames `vchange' = "Avg|Chg|" `catnms8' + } + if "`outcome'"=="" { + * is 0/1 variable + capture assert `var' == 0 | `var' == 1 | `var' == . `if' `in' + if "`fromto'"=="fromto" { + if _rc == 0 { mat `vchange' = `vchange'[4..6, 1...] } + else { + tempname vchang1 vchang2 + mat `vchang1' = `vchange'[1..3, 1...] + mat `vchang2' = `vchange'[7..., 1...] + mat `vchange' = `vchang1' \ `vchang2' + } + } + else { + if _rc == 0 { mat `vchange' = `vchange'[2, 1...] } + else { + tempname vchang1 vchang2 + mat `vchang1' = `vchange'[1, 1...] + mat `vchang2' = `vchange'[3..., 1...] + mat `vchange' = `vchang1' \ `vchang2' + } + } + if "`hasmarg'"=="yes" { + capture assert `var' == 0 | `var' == 1 /* + */ | `var' == . `if' `in' + if _rc != 0 { + mat `vmarg' = `margout'[`i', 1...] + * compute avg abs discrete change + local k = 1 + * amarg changes made in 1.8.0 for estout returns + *tempname amarg // removed 23oct2007 bj + *scalar `amarg' = 0 // removed 23oct2007 bj + while `k' <= `ncats' { + mat `amarg'[1,`i'] = `amarg'[1,`i'] + abs(`vmarg'[1,`k']) // changed 23oct2007 bj + local k = `k' + 1 + } + + * jf 5/20/03 + mat `amarg'[1,`i'] = `amarg'[1,`i'] / `ncats' // changed 23oct2007 bj + mat `vmarg' = (`amarg'[1,`i'],`vmarg') // changed 23oct2007 bj + mat rownames `vmarg' = MargEfct + mat roweq `vmarg' = _ + mat `vchange' = `vchange' \ `vmarg' + } + } + di _n in y "`var'" _c + mat list `vchange', noheader + mat roweq `vchange' = `var' + mat `dchange' = nullmat(`dchange') \ `vchange' + + } /* "`outcome'"=="" */ + + else { + * mat `vchange' = `vchange'[1..., `outcome'] + * 1.7.1 06Jan2007 + * +1 since average in in first column + mat `vchange' = `vchange'[1..., `outcome'+1] + mat `vchange' = `vchange'' + mat rownames `vchange' = `var' + mat `dchange' = nullmat(`dchange') \ `vchange' + } + local i = `i' + 1 + } /* while `i' <= `i_to' */ + + if "`outcome'"!="" { + if "`hasmarg'"=="yes" { + mat `margout' = `margout'[1..., `outcome'] + mat colnames `margout' = MargEfct + mat coleq `margout' = _ + mat `dchange' = `dchange' , `margout' + } + *added to make matrix headings stata7 compatible + mat _PEtemp = `dchange'' +* 2.5.2 +local outcmvnm "`outcmv'" +return mat change`outcmvnm' = _PEtemp, copy +* return mat change`outcmv' = _PEtemp, copy // added 23oct2007 bj + _peabbv _PEtemp + mat `dchange' = _PEtemp' + mat list `dchange', noheader + mat `dchange' = `dchange'' + } + local i = 1 + while `i' <= `ncats' { + mat temp = r(p`i') + mat `basepr' = nullmat(`basepr') , temp[1, 1] + local i = `i' + 1 + } + mat rownames `basepr' = "Pr(y|x)" + if "`label'"=="nolabel" { mat colnames `basepr' = `catvals' } + else { mat colnames `basepr' = `catnms8' } + if "`brief'"=="" { mat list `basepr', noheader } + + // rearrange info to be returned 2006-02-18 for estout + if "`outcome'"=="" { // if-condition added 23oct2007 bj + tempname tempmat mtemp // changed 24oct2007 bj + local i = 1 + while `i' <= (`ncats'+1) { + * move col i into one column for each variable + local v = 1 + while `v' <= `i_to' { + local nrowper = 4 + 8*("`fromto'"=="fromto") // rows of info per variable - changed 07nov2007 bj + local rst = 1+ ((`v'-1)*`nrowper') + local ren = `rst' + `nrowper' - 1 + mat `tempmat' = nullmat(`tempmat') , `nomtemp'[`rst'..`ren'', `i'] + local ++v + } + mat colnames `tempmat' = `varlist' + if `i'==1 { + if "`hasmarg'"=="yes" { // block added 23oct2007 bj + mat rowname `amarg' = MargEfct + mat `tempmat' = `tempmat' \ `amarg' + } + return mat changemn = `tempmat' + } + else { + local c = `i' - 1 + local catnum : word `c' of `catvals' + * 2.5.1 if negative, replace - with _ 2009-12-10 + if `catnum'<0 { + local catnum = abs(`catnum') + local catnum "_`catnum'" + } + tempname change`catnum' + + * 1.7.1 add marg to return matrix + if "`hasmarg'"=="yes" { // if-condition added 23oct2007 bj + mat `mtemp' = `margout'[1...,`c']' // changed 23oct2007 bj + mat rowname `mtemp' = MargEfct + *mat def mtemp = `mtemp' // removed 23oct2007 bj + *mat def tempmat = `tempmat' // removed 23oct2007 bj + mat `tempmat' = `tempmat' \ `mtemp' + } + return mat change`catnum' = `tempmat' + + } + local ++i + } + } /* if "`outcome'"=="" */ + mat `predis' = `basepr' + + } /* if "`output'"=="nomord" */ + +*=> print base values + + if "`brief'"=="" & "`base'"!="nobase" { + if "`input'"=="twoeq" { + di _n in g "base x values for count equation: " + } + mat `tobase' = `tobase' \ `sd' + * 2009-07-10 1.8.1 for Stata 11 + mat rownames `tobase' = "x=" "sd_x=" + mat _PEtemp = `tobase' + _peabbv _PEtemp + mat list _PEtemp, noheader f(%8.0g) + if "`input'"=="twoeq" { + di _n in g "base x values for binary equation: " + mat `tobase2' = `tobase2' \ `sd2' + * 2009-07-10 1.8.1 for Stata 11 + mat rownames `tobase2' = "x=" "sd_x=" + mat _PEtemp = `tobase2' + _peabbv _PEtemp + mat list _PEtemp, noheader f(%8.0g) + } + } + +*=> Help option + + if "`help'"=="help" { + di + di in g " Pr(y|x): probability of observing each y for "/* + */ "specified x values" + di in g "Avg|Chg|: average of absolute value of the change"/* + */ " across categories" + di in g "Min->Max: change in predicted probability as x"/* + */ " changes from its minimum to" + di in g " its maximum" + di in g " 0->1: change in predicted probability as x"/* + */ " changes from 0 to 1" + + if "`uncentered'"=="" { + if `delt'==1 { + di in g " -+1/2: change in predicted probability as x"/* + */ " changes from 1/2 unit below" + di in g " base value to 1/2 unit above" + } + else { + di in g " -+d/2: change in predicted probability as x"/* + */ " changes from " `delthlf' " units" + di in g " below base value to "`delthlf' " units"/* + */ " above" + } + } + else { + if `delt'==1 { + di in g " +1: change in predicted probability as x"/* + */ " increases by 1 unit" + } + else { + di in g " +delta: change in predicted probability as x"/* + */ " increases by " `delt' " units" + } + } + + if "`uncentered'"=="" { + di in g " -+sd/2: change in predicted probability as x"/* + */ " changes from 1/2 standard" + di in g " dev below base to 1/2 standard"/* + */ " dev above" + } + else { + di in g " +sd: change in predicted probability as x"/* + */ " increases by a standard dev" + } + + di in g "MargEfct: the partial derivative of the predicted"/* + */ " probability/rate with" + di in g " respect to a given independent variable" + } + +// 2006-02-18 returns for estout + + mat rown `tobase' = X // 23oct2007 bj + mat `baseval' = `tobase'[1,1...] \ `baseval'[2...,1...] // 23oct2007 bj + * combine base values and name equations if zip or zinb + if "`input'"=="twoeq" { + mat rown `tobase2' = X // added 23oct2007 bj + mat `basezi' = `tobase2'[1,1...] \ `basezi'[2...,1...] // added 23oct2007 bj + matrix colnames `basezi' = inflate: + local eqnm "`e(depvar)':" + matrix colnames `baseval' = `eqnm' + matrix `baseval' = `baseval' , `basezi' + } + + return matrix baseval = `baseval' + if "`output'"!="nomord" { return matrix change = `change' } // changed 23oct2007 bj + return matrix predval = `predis' + return scalar delta = `delt' // 05nov2007 bj + return scalar centered = ("`uncentered'"=="") // 05nov2007 bj + if "`outcome'"!="" { // 23oct2007 bj + return scalar outcome = `outcmv' + } + return local modeltype `"`io'"' // 23oct2007 bj + + * return names and values of outcome categories + tempname catn + if "`catvals'"!="" { + local i = 1 + while `i' <= `ncats' { + local valchk : word `i' of `catvals' + local nmchk : word `i' of `catnms' + mat `catn' = nullmat(`catn') \ `valchk' + local ++i + } + } + else { + matrix `catn' = J(1,1,.) + local catnms = "" + } + matrix `catn' = `catn'' + matrix colnames `catn' = `catnms' + matrix rownames `catn' = "`e(depvar)'" + return matrix catval = `catn' +end +exit + +* version 1.6.8 13Apr2005 +* version 1.6.7c 27Mar2005 slogit +* version 1.6.7b 19Feb2005 zt +* version 1.6.6 20May2003 +* version 1.6.9 - 19May2006 +* - Add min->max change to PE_dc for mlogplot +* - required for mlogplot v1.6.8 to plot changes over range +* version 1.7.1 jsl 06Jan2007 for estout +* - outcome() fixed for ord and nom +* version 1.7.2 - 07nov2007 Ben Jann changes for estout +* - -fromto- results were not returned correctly with nomord models - this is fixed +* - brief option caused error - this is fixed +* - returns r(outcome) if -outcome()- specified +* - returns type of model in r(modeltype) +* - returns marginal effects now also in r(changemn) +* - no longer crashes on nomorg models without marginals (i.e. -slogit-) +* - returns correct basevals now if x() is specified +* - returns results now only for the specified outcome if -outcome()- is specified +* - no longer returns r(change) for nomord models +* version 1.8.0 2008-02-16 sl +* - revised to work with estout +* - added mprobit +* version 1.8.1 2009-07-10 +* - sd(x) fix for Stata 11 +* version 1.9.0 jsl 2009-09-19 +* - fix mlogit for e(b) in stata 11 +* version 2.5.0 2009-10-28 jsl +* - stata 11 update for returns from -mlogit- diff --git a/Modules/ado/plus/p/prchange.hlp b/Modules/ado/plus/p/prchange.hlp new file mode 100644 index 0000000..562ed17 --- /dev/null +++ b/Modules/ado/plus/p/prchange.hlp @@ -0,0 +1,130 @@ +.- +help for ^prchange^ - 2Nov2005 +.- + +Discrete and marginal change for regression models for categorical and +count variables +------------------------------------------------------------------------------ + + ^prchange^ [varlist] [^if^ exp] [^in^ range] [, ^x(^variables_and_values^)^ + ^r^est^(^stat^)^ ^o^utcome^(^#^)^ ^f^romto ^b^rief ^noba^se ^nola^bel ^h^elp + ^all^ ^unc^entered ^d^elta^(^#^)^ ^con^ditional] + +where + + ^variables_and_values^ is an alternating list of variables and either + numeric values or mean, median, min, max, upper, lower, previous + + ^stat^ is either mean, median, min, max, upper, lower, previous, grmean + (group mean), grmedian, grmin, grmax + +Description +----------- + +^prchange^ computes discrete and marginal change for regression models for +categorical and count variables. Marginal change is the partial derivative +of the predicted probability or predicted rate with respect to the +independent variables. Discrete change is the difference in the predicted +value as one independent variable changes values while all others are held +constant at specified values. + +By default, the discrete and marginal change is calculated holding all other +variables at their mean. Values for specific independent variables can be +set using the x() option after ^prchange^. For example, to compute predicted +values when educ is 10 and age is 30, type ^prchange, x(educ=10 age=30)^. +Values for the unspecified independent variables can be set using the rest() +option, e.g., ^prchange, x(educ=10 age=30) rest(mean)^. The ^if^ and ^in^ +conditions specify conditions for computation of means, min, etc., that are +used with rest(). + +The discrete change is computed when a variable changes from its minimum to +its maximum (Min->Max), from 0 to 1 (0->1), from its specified value minus +.5 units to its specified value plus .5 (-+1/2), and from its specified +value minus .5 standard deviations to its value plus .5 standard deviations +(-+sd/2). + +The command works with cloglog, cnreg, intreg, logit, mlogit, mprobit, nbreg, +ologit, oprobit, poisson, probit, regress, slogit, tobit, zinb, zip, ztnb, +and ztp. + + +Options +------- + +^x()^ explicitly sets the values of specified independent variables. + +^rest()^ sets the independent variables not specified in x() to their ^mean^ + (default), ^minimum^, ^maximum^, ^median^ when calculating predicted values. + ^grmean^ sets these independent variables to the mean conditional on the + variables and values specified in x(). If ^prvalue^ has already been run + after the last estimate, ^previous^ will set unspecified variables to their + prior values. For models other than mlogit, ^upper^ and ^lower^ can be used + to set independent variables to their minimum or maximum depending on + which will yield the upper or lower extreme predicted value. + +^outcome()^ specifies that changes will be printed only for the outcome + indicated. For ^ologit^, ^oprobit^, ^mlogit^ and ^slogit^, the default is + to provide results for all outcomes. For the count models, the default is + to present results with respect to the predicted rate; specifying an + outcome number will provide changes in the probability of that outcome. + +^delta()^ specifies the amount of the discrete change in the independent + variable. The default is a 1 unit change. + +^fromto^ includes the pre- and post- probabilities in addition to the discrete + change + +^uncentered^ specifies that the uncentered discrete change rather than the + centered discrete change is to be computed. + +^conditional^ compute changes in conditional predictions rather than + unconditional predictions for the ztp and ztnb models. + +^all^ specifies that any calculations of means, medians, etc., should use + the entire sample instead of the sample used to estimate the model. + +^help^ presents guide to interpreting headings of output. + +^nolabel^ uses values rather than value labels in output. + +^nobase^ suppresses inclusion of the base values of x in the output. + +^brief^ prints only limited output. + +Examples +-------- + +To compute discrete and marginal change for ordered probit at base values +equal to the mean: + + . ^oprobit warm yr89 male white age ed prst^ + . ^prchange^ + +To compute discrete and marginal change for a specific set of base values: + + . ^prchange, x(male=1 white=1 age=30)^ + + . ^prchange, x(male=1 white=1 age=30) rest(median)^ + + . ^prchange, x(male=1 white=max age=min) rest(median)^ + +To compute the discrete change for a set of base values while holding other +variables constant to a group-specific median: + + . ^prchange if white == 1 & male == 0, x(white=1 male=0) rest(median)^ + +or + + . ^prchange, x(white=1 male=0) rest(grmedian)^ + + +To list only the discrete change for specific variables: + + . ^prchange age, x(male=0 white=0) rest(median)^ + +.- +Authors: J. Scott Long and Jeremy Freese + www.indiana.edu/~jslsoc/spost.htm + spostsup@@indiana.edu + + diff --git a/Modules/ado/plus/p/prcounts.ado b/Modules/ado/plus/p/prcounts.ado new file mode 100644 index 0000000..10e7328 --- /dev/null +++ b/Modules/ado/plus/p/prcounts.ado @@ -0,0 +1,213 @@ +*! version 1.6.8 13Apr2005 +* version 1.6.7 18Feb2005 ztp and ztnb +* version 1.6.6 8/20/03 +* version 1.6.5 1/10/01 + +capture program drop prcounts +program define prcounts + version 6.0 + tempname b alpha ai gai mu + syntax newvarname [if] [in] [, Max(integer 9) Plot] + +*=> classify each valid type of model + local cmd = e(cmd) + *zt 18Feb2005 + if "`cmd'"=="nbreg" | "`cmd'"=="poisson" | /* + */ "`cmd'"=="zinb" | "`cmd'"=="zip" | /* + */ "`cmd'"=="ztp" | "`cmd'"=="ztnb" { + } + else { + di + di in r "prcounts does not work for the last type of model estimated." + exit + } + if `max' > 99 | `max' < 0 { + di in r "max() must be in range from 0 to 99" + exit 198 + } + local stem "`varlist'" + local stem = substr("`stem'", 1, 28) + cap version 7 + if _rc!=0 { local stem = substr("`stem'", 1, 4) } + version 6.0 + local modelis "from `cmd'" + +*-> GENERATE PREDICTED RATE + quietly predict `stem'rate `if' `in', n + label variable `stem'rate "Predicted rate `modelis'" + gen `mu' = `stem'rate + + *18Feb2005 + * compute conditional mu + if "`cmd'"=="ztp" | "`cmd'"=="ztnb" { + quietly predict `stem'Crate `if' `in', cm + label variable `stem'Crate "Predicted conditional rate `modelis'" + } + +*-> GENERATE PREDICTED FREQUENCY OF ALWAYS ZERO + if "`cmd'"=="zip" | "`cmd'"=="zinb" { + quietly predict `stem'all0 `if' `in', p + label variable `stem'all0 "Pr(always 0) `modelis'" + * predict n, n computes: exp(x*beta)*(1-all0). + * The last term needs to be removed. + quietly replace `mu' = `mu'/(1-`stem'all0) `if' `in' + } + +*-> TAKE CARE OF ALPHA + *18Feb2005 + if "`cmd'"=="nbreg" | "`cmd'"=="ztnb" { + sca `alpha' = e(alpha) + } + if "`cmd'"=="zinb" { + mat `b' = e(b) + local temp = colsof(`b') + sca `alpha' = `b'[1, `temp'] + sca `alpha' = exp(`alpha') + } + *18Feb2005 + if "`cmd'"=="nbreg" | "`cmd'"=="zinb" | "`cmd'"=="ztnb" { + sca `ai' = 1/`alpha' + sca `gai' = exp(lngamma(`ai')) + if `gai'==. { + di in r "problem with alpha prevents" /* + */ " estimation of predicted probabilities." + exit 198 + } + } + +*-> GENERATE PREDICTED PROBABILITIES + local i 0 + while `i' <= `max' { + local newvar "`stem'pr`i'" + *18Feb2005 + if "`cmd'"=="poisson" | "`cmd'"=="ztp" { + quietly gen `newvar' = /* + */ ((exp(-`mu'))*(`mu'^`i'))/(round(exp(lnfact(`i'))), 1) /* + */ `if' `in' + } + *18Feb2005 + if "`cmd'"=="nbreg" | "`cmd'"=="ztnb" { + quietly gen `newvar' = /* + */ (exp(lngamma(`i'+`ai')) / /* + */ (round(exp(lnfact(`i')),1) * exp(lngamma(`ai')))) /* + */ * ((`ai'/(`ai'+`mu'))^`ai') * ((`mu'/(`ai'+`mu'))^`i') /* + */ `if' `in' + } + if "`cmd'"=="zip" { + quietly gen `newvar' = (1-`stem'all0)*((exp(-`mu')) /* + */ * (`mu'^`i'))/(round(exp(lnfact(`i'))), 1) `if' `in' + if `i'==0 { + quietly replace `newvar' = `newvar' + `stem'all0 `if' `in' + } + } + if "`cmd'"=="zinb" { + quietly gen `newvar' = (1-`stem'all0)*(exp(lngamma(`i'+`ai')) /* + */ / ( round(exp(lnfact(`i')),1) * exp(lngamma(`ai')) ) ) /* + */ * ((`ai'/(`ai'+`mu'))^`ai') * ((`mu'/(`ai'+`mu'))^`i') /* + */ `if' `in' + if `i'==0 { + quietly replace `newvar' = `newvar' + `stem'all0 `if' `in' + } + } + label variable `newvar' "Pr(y=`i') `modelis'" + local i = `i' + 1 + } + +*spost9 zt needs to compute conditional probabilities 19feb2005 +*-> GENERATE CONDITIONAL PREDICTED PROBABILITIES +if "`cmd'"=="ztp" | "`cmd'"=="ztnb" { + local i 1 + while `i' <= `max' { + local newvar "`stem'Cpr`i'" + quietly gen `newvar' = `stem'pr`i'/(1-`stem'pr0) + label variable `newvar' "Pr(y=`i'|y>0) `modelis'" + local i = `i' + 1 + } +} /// zt + +*-> GENERATE CUMULATIVE PROBABILITIES + quietly gen `stem'cu0=`stem'pr0 + label variable `stem'cu0 "Pr(y=0) `modelis'" + local i 1 + while `i' <= `max' { + quietly egen `stem'cu`i' = rsum(`stem'pr0-`stem'pr`i') if `mu'~=. + label variable `stem'cu`i' "Pr(y<=`i') `modelis'" +*spost9 zt cumulative probabilities 18Feb2005 + if "`cmd'"=="ztp" | "`cmd'"=="ztnb" { + quietly egen `stem'Ccu`i' = rsum(`stem'Cpr1-`stem'Cpr`i') if `mu'~=. + label variable `stem'Ccu`i' "Pr(y<=`i'|y<0) `modelis'" + } + local i = `i' + 1 + } + +*-> GENERATE GREATER THAN VARIABLE + quietly gen `stem'prgt = 1-`stem'cu`max' if `mu'~=. + label variable `stem'prgt "Pr(y>`max') `modelis'" + *18Feb2005 + if "`cmd'"=="ztp" | "`cmd'"=="ztnb" { + quietly gen `stem'Cprgt = 1-`stem'Ccu`max' if `mu'~=. + label variable `stem'Cprgt "Pr(y>`max'|y>0) `modelis'" + } + +*-> IF PLOT OPTION SPECIFIED + if "`plot'"=="plot" { + quietly gen `stem'val = . + label variable `stem'val "Count" + quietly gen `stem'obeq = . + label variable `stem'obeq "Observed Pr(y=k) `modelis'" + quietly gen `stem'preq = . + label variable `stem'preq "Predicted Pr(y=k) `modelis'" + quietly gen `stem'oble = . + label variable `stem'oble "Observed Pr(y<=k) `modelis'" + quietly gen `stem'prle = . + label variable `stem'prle "Predicted Pr(y<=k) `modelis'" + *18Feb2005 + if "`cmd'"=="ztp" | "`cmd'"=="ztnb" { + quietly gen `stem'Cpreq = . + label variable `stem'Cpreq "Predicted Pr(y=k|y>0) `modelis'" + quietly gen `stem'Cprle = . + label variable `stem'Cprle "Predicted Pr(y<=k|y>0) `modelis'" + } + ** bug fix -- makes sure observed probabilities are + ** computed on estimation sample + if "`if'" == "" { + local if "if e(sample)==1" + } + else { + local if "`if' & e(sample)==1" + } + + local i 0 + while `i' <= `max' { + quietly { + local obs = `i' + 1 + replace `stem'val = `i' in `obs' + tempvar count1 count2 + * 1 if outcomes equal to i + gen `count1' = (`e(depvar)'==`i') `if' `in' + sum `count1' `if' `in' + replace `stem'obeq = r(mean) in `obs' + * 1 if outcome lt i + gen `count2' = (`e(depvar)'<=`i') `if' `in' + sum `count2' `if' `in' + replace `stem'oble = r(mean) in `obs' + * compute average predicted prob + sum `stem'pr`i' `if' `in' + replace `stem'preq = r(mean) in `obs' + * compute average cumulative predicted prob + sum `stem'cu`i' `if' `in' + replace `stem'prle = r(mean) in `obs' + + *zt only compute if count > 0 18Feb2005*ZT + if ("`cmd'"=="ztp" | "`cmd'"=="ztnb") & `i'>0 { + sum `stem'Cpr`i' `if' `in' + replace `stem'Cpreq = r(mean) in `obs' + sum `stem'Ccu`i' `if' `in' + replace `stem'Cprle = r(mean) in `obs' + } + } + local i = `i' + 1 + } + } + +end diff --git a/Modules/ado/plus/p/prcounts.hlp b/Modules/ado/plus/p/prcounts.hlp new file mode 100644 index 0000000..f4c006e --- /dev/null +++ b/Modules/ado/plus/p/prcounts.hlp @@ -0,0 +1,78 @@ +.- +help for ^prcounts^ - 11Mar2005 +.- + +Compute the predicted rate and probabilities for count models +------------------------------------------------------------- + + ^prcounts^ varname [^if^ exp] [^in^ range] [^, m^ax^(^max^)^ ^p^lot] + +Description +----------- + +^prcounts^ computes the predicted rate and probabilities of counts from 0 +through the specified maximum count based on the last estimates from the +count models ^poisson^, ^nbreg^, ^zip^, ^zinb^. ^prcounts^ optionally generates +variables for the graphical comparison of observed and expected counts +for one model or for competing models. + +For each observation ^prcounts^ computes the variables: + + namerate = predicted count or rate + namepr^k^ = probability of a count of ^k^ for ^k^=0 to max + namecu^k^ = cumulative probabiliy of a count <=^k^ for ^k^=0 to max + +For zip or zinb models, prcounts also generates: + + namell0 = probability of being in the 'always zero' group + +For ztp or ztnb models, prcounts also generates: + + nameCrate = predicted count or rate conditional on y>0 + nameCpr^k^ = probability of a count of ^k^ for ^k^=0 to max conditional + on y>0 + nameCcu^k^ = cumulative probabiliy of a count <=^k^ for ^k^=0 to max + conditional on y>0 + +Options +------- + +^max(^value^)^ The maximum count for which variables are generated. + value must be an integer between 0 and 99; the default is 9. + +^plot^ causes Stata to generate extra variables that are useful for plotting. + The created variables will have values for the first max+1 rows of the + data set. + + nameval = value of y + nameobeq = observed probability of counts = y + nameoble = cumulative observed probability of counts <= y + namepreq = predicted probability of counts = y + nameprle = predicted cumulative probability of counts <= y + +For these variables, each observation provides information about the +probabilities of a given count for the entire sample. In other words, what +an observation consists of for these variables is different than for the rest +of the variables in one's dataset. + +Note: the summary statistics computed by ^plot^ are automatically based on +the estimation sample, plus any further restrictions implied by the use of +^if^ or ^in^. + +Examples +-------- + + . ^zinb art fem mar kid5 phd ment, inf(fem mar kid5 phd ment)^ + . ^prcounts cnt^ + . ^summarize cnt*^ + +To graphically compare predicted and observed counts for a model: + + .^ poisson art fem mar kid5 phd ment^ + .^ prcounts pois, max(8) plot^ + .^ graph poispreq poisobeq poisval, c(ll)^ + +.- +Authors: J. Scott Long and Jeremy Freese + www.indiana.edu/~jsl650/spost.htm + spostsup@@indiana.edu diff --git a/Modules/ado/plus/p/prdc.ado b/Modules/ado/plus/p/prdc.ado new file mode 100644 index 0000000..abd9821 --- /dev/null +++ b/Modules/ado/plus/p/prdc.ado @@ -0,0 +1,183 @@ +*! version 0.0.4 jsl 13Apr2005 - beta version +*! To do: there are no IF, IN or ALL options +*! To do: Add if ystar or xb + +capture program drop prdc +program define prdc, rclass + version 8 + +*=> classify each valid type of model + + if "`e(cmd)'"=="cloglog" { + local io = "typical binary" + } + if "`e(cmd)'"=="gologit" { + local io = "typical ordered" + } + if "`e(cmd)'"=="logistic" { + local io = "typical binary" + } + if "`e(cmd)'"=="logit" { + local io = "typical binary" + } + if "`e(cmd)'"=="mlogit" { + local io = "typical nomord" + } + if "`e(cmd)'"=="nbreg" { + local io = "typical count" + } + if "`e(cmd)'"=="ologit" { + local io = "typical nomord" + } + if "`e(cmd)'"=="oprobit" { + local io = "typical nomord" + } + if "`e(cmd)'"=="poisson" { + local io = "typical count" + } + if "`e(cmd)'"=="probit" { + local io = "typical binary" + } + if "`e(cmd)'"=="zinb" { + local io = "twoeq count" + } + if "`e(cmd)'"=="zip" { + local io = "twoeq count" + } + if "`io'"=="" { + di + di in y "prdc" in r " does not work for last model estimated." + exit + } + +*=> decode input + syntax [varlist(default=none)] /// + [, x(string) Rest(passthru) LEvel(passthru) /// + MAXcnt(passthru) noLAbel noBAse Brief Save Diff /// + YStar ept DELta /// + BOOTstrap REPs(passthru) SIze(passthru) DOts match /// + NORMal PERCENTile BIAScorrected /// + From(real 0) To(real 0) Change(real 0) /// + BINary Unit SD UNCentered ] + +local qui "quietly" + + local changetype " Uncentered" + if "`uncentered'"=="" { + local changetype " Centered" + } + + if "`varlist'" =="" { + di in red "you must specify a variable list." + exit + } + + * unit by default + if `from'==0 & `to'==0 & `change'==0 /// + & "`binary'"=="" & "`unit'"=="" & "`sd'"=="" { + local unit "unit" + } + + tempname mn sdval sdval2 fromto stval endval + foreach v in `varlist' { + + matrix `fromto' = J(10,2,-99) // hold start and end + local rownm "" + local rows = 0 + qui sum `v' `if' `in' + scalar `mn' = r(mean) + scalar `sdval' = r(sd) + local sdnm "sd" + scalar `sdval2' = `sdval'/2 + if "`binary'"=="binary" { + local rows = `rows' + 1 + local nm`rows' "" + mat `fromto'[`rows',1] = 0 + mat `fromto'[`rows',2] = 1 + } + if "`unit'"=="unit" { + local rows = `rows' + 1 + local nm`rows' "[ -+1/2 ]" + scalar `stval' = `mn' - 1/2 + if "`uncentered'"!="" { + local nm`rows' "[ +1 ]" + scalar `stval' = `mn' + } + scalar `endval' = `stval' + 1 + mat `fromto'[`rows',1] = `stval' + mat `fromto'[`rows',2] = `endval' + } + if "`sd'"=="sd" { + local rows = `rows' + 1 + local nm`rows' "[ -+sd/2 ]" + scalar `stval' = `mn' - `sdval2' + if "`uncentered'"!="" { + local nm`rows' "[ +sd ]" + scalar `stval' = `mn' + } + scalar `endval' = `stval' + `sdval' + mat `fromto'[`rows',1] = `stval' + mat `fromto'[`rows',2] = `endval' + } + if `change'!=0 { + local rows = `rows' + 1 + local nm`rows' "[ -+(delta=`change'/2) ]" + scalar `stval' = `mn' - (`change'/2) + if "`uncentered'"!="" { + local nm`rows' "[ +(delta=`delta') ]" + scalar `stval' = `mn' + } + scalar `endval' = `stval' + `change' + mat `fromto'[`rows',1] = `stval' + mat `fromto'[`rows',2] = `endval' + } + if `from'==0 & `to'==0 { + } + else { + local rows = `rows' + 1 + mat `fromto'[`rows',1] = `from' + mat `fromto'[`rows',2] = `to' + local nm`rows' "" + } + + di _n in g "Discrete change for variable: " in y "`v' " + + tempname val dif diflb difub difmisc difout base stis endis + foreach r of numlist 1/`rows' { + scalar `stis' = `fromto'[`r',1] + scalar `endis' = `fromto'[`r',2] + local xstis = `stis' + local xendis = `endis' + `qui' prvalue2, x(`x' `v'=`xstis') /// + `rest' `level' save + if `r'==1 { + * get column names + mat `val' = pepred[1,1...] + local colnm "" + local colnum = colsof(`val') + foreach k of numlist 1/`colnum' { + local a = `val'[1,`k'] + local colnm "`colnm' `a'" + } + } + `qui' prvalue2, x(`x' `v'=`xendis') /// + `rest' `level' diff + mat `dif' = pepred[6,1...] + mat `diflb' = pelower[6,1...] + mat `difub' = peupper[6,1...] + mat `difmisc' = pepred[7,1...] + matrix `difout' = `dif' \ `diflb' \ `difub' + mat colnames `difout' = `colnm' + mat rownames `difout' = " Change" " LowerBound" " UpperBound" + di _new in g "`changetype' change from " in y %6.4f `stis' /// + in g " to " in y %6.4f `endis' /// + in g " `nm`r''" + mat list `difout', noheader + } // rows + + } // list of variables + + * levels of variables + mat `base' = r(x) + mat list `base', noheader +end diff --git a/Modules/ado/plus/p/prdc.hlp b/Modules/ado/plus/p/prdc.hlp new file mode 100644 index 0000000..c7d0af0 --- /dev/null +++ b/Modules/ado/plus/p/prdc.hlp @@ -0,0 +1,110 @@ +.- +help for ^prdc^ - 25Oct2005 +.- + +?? if, in, all and ystar options need to be verified. + +Compute descrete change of a specified amount for list of variables. +-------------------------------------------------------------------- + + ^prdc^ [varlist] [^if^ exp] [^in^ range] [, ^x(^variables_and_values^)^ + ^r^est^(^stat^)^ ^ys^tar ^b^rief ^all ^max^cnt ^(^#^)^ ^noba^se + ^nola^bel ^f^rom^(^#^)^ ^to(^#^)^ ^c^hange^(^#^)^ ^bin^ary + ^u^nit ^sd^ ^unc^entered <you can also use options for confidence + intervals used with ^prvalue^.] +where + + ^varlist^ contains the names of variables for which discrete change will + be computed. + + ^variables_and_values^ is an alternating list of variables and either + numeric values or mean, median, min, max, upper, lower, previous + + ^stat^ is either mean, median, min, max, upper, lower, previous, grmean + (group mean), grmedian, grmin, grmax + +Description +----------- + +^prdc^ computes discrete changes with confidence intervals for regression +models for categorical and count variables. Discrete change is the +difference in the predicted value as one independent variable changes +values while all others are held constant at specified values. ^prdc^ is +simply a convenient way to execute a save-dif pair of ^prvalue^ commands. +By default, the discrete change is computed for a unit increase centered +around the mean. + +Values for specific independent variables can be set using the x() option +after ^prdc^. Values for the unspecified independent variables can be +set using the rest() option. The ^if^ and ^in^ conditions specify conditions +for computation of means, min, etc., that are used with rest(). + +The discrete change is computed by the amounts (more than one can be specified) +specified with the options. ^prdc^ works with all regression programs that are +compatable with prvalue. + +Options specifying levels of variables +-------------------------------------- + +^x()^ explicitly sets the values of specified independent variables. + +^rest()^ sets the independent variables not specified in x() to their ^mean^ + (default), ^minimum^, ^maximum^, ^median^ when calculating predicted values. + ^grmean^ sets these independent variables to the mean conditional on the + variables and values specified in x(). If ^prvalue^ has already been run + after the last estimate, ^previous^ will set unspecified variables to their + prior values. For models other than mlogit, ^upper^ and ^lower^ can be used + to set independent variables to their minimum or maximum depending on + which will yield the upper or lower extreme predicted value. + +Options specifying the amout of change +-------------------------------------- + +^from()^ specifies the start value of the change. + +^to()^ specifies the start value of the change. + +^binary^ specifies a change from 0 to 1. + +^unit^ specifies a unit change at the values specified with x() and rest(). + +^sd^ specifies a standard deviation change at the values specified with x() + and rest(). + +^change()^ specifies the amount of the discrete change at the values + specified with x() and rest(). + +^uncentered^ specifies that the uncentered discrete change rather than the + centered discrete change is to be computed for unit, sd and change. + +Other Options +------------- + +^maxcnt()^ is the maximum count value for which the probability is computed + in count models. Default is 9. + +^ystar^ requests change in predicted y*, rather than probabilities. + + +^all^ specifies that any calculations of means, medians, etc., should use + the entire sample instead of the sample used to estimate the model. + +^nolabel^ uses values rather than value labels in output. + +^nobase^ suppresses inclusion of the base values of x in the output. + +^brief^ prints only limited output. + +^help^ presents guide to interpreting headings of output. + + +Examples +-------- +.- +Authors: J. Scott Long and Jeremy Freese + www.indiana.edu/~jslsoc/spost.htm + spostsup@@indiana.edu + + + + diff --git a/Modules/ado/plus/p/prelist.ado b/Modules/ado/plus/p/prelist.ado new file mode 100644 index 0000000..5218d0d --- /dev/null +++ b/Modules/ado/plus/p/prelist.ado @@ -0,0 +1,28 @@ +program def prelist, rclass +*! NJC 1.2.0 6 June 2000 +* NJC 1.1.0 22 Dec 1999 +* NJC 1.0.0 12 Nov 1999 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax , Pre(str) [ Global(str) Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tokenize `list' + while "`1'" != "" { + local newlist "`newlist'`pre'`1' " + mac shift + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/p/prelist.hlp b/Modules/ado/plus/p/prelist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/p/prelist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/p/prgen.ado b/Modules/ado/plus/p/prgen.ado new file mode 100644 index 0000000..1c7864a --- /dev/null +++ b/Modules/ado/plus/p/prgen.ado @@ -0,0 +1,525 @@ +*! version 2.5.0 2009-10-28 jsl +* - stata 11 update for returns from -mlogit- + +// generate predictions and ci's to plot + +capture program drop prgen +program define prgen, rclass + version 8 + tempname temp inc xval addbase tobase tobase2 + + * check if prgen works with last model + _pecmdcheck prgen + local io = r(io) + if "`io'"=="." { + exit + } + local input : word 1 of `io' /* input routine to _pepred */ + local output : word 2 of `io' /* output routine */ + +// decode options + + syntax [varlist(numeric min=1 max=1)] [if] [in] /// + , Generate(string) [x(passthru) Rest(passthru) /// + Level(passthru) MAXcnt(passthru) all /// + Brief noBAse Ncases(integer 11) /// + From(real -867.5309) To(real 867.5309) /// + /// new options + MARginal NOIsily CI gap(real 0.0) /// + /// new options passed to prchange2 follow + noLAbel noBAse Brief /// + YStar ept DELta BOOTstrap REPs(passthru) SIze(passthru) /// + DOts match NORMal PERCENTile BIAScorrected /// + CONditional ] + + * zt 19Feb2005 + local iszt = 0 + if ("`e(cmd)'"=="ztp" | "`e(cmd)'"=="ztnb") { + local iszt = 1 + local cond "" + local condnm "Unconditional" + local condnmlc "unconditional " + if "`conditional'"=="conditional" { + local cond "C" + local condnm "Conditional" + local condnmlc "conditional " + } + } + + * marginals not available for these models + if "`e(cmd)'"=="gologit" | "`input'"=="twoeq" /// + | "`output'" == "tobit" /// + | "`output'" == "regress" /// + | `iszt'==0 { + if "`marginal'"=="marginal" { + di _n in red "Note: Marginals not available for current model." + } + local marginal "" + } + + * zt no ci's available 19Feb2005 + if "`ci'"=="ci" & `iszt'==1 { + local ci "" + di _n in red "Note: ci's not available for current model." + } + + * options to pass to prvalue + local pr2input "`level' `maxcnt' `nolabel' `nobase' `brief'" + local pr2input "`pr2input' `ystar' `ept' `delta' `bootstrap'" + local pr2input "`pr2input' `reps' `size' `dots' `match'" + local pr2input "`pr2input' `normal' `percentile' `biascorrected'" + + * print results from prvalue + local quietly "quietly " + if "`noisily'"=="noisily" { + local quietly "" + di "Results from prvalue called by prgen" + di + } + +// get information needed to create plot values + + local max_i = r(maxcount) + _perhs + local nrhs = `r(nrhs)' + local rhsnms "`r(rhsnms)'" + if "`input'"=="twoeq" { + local nrhs2 = `r(nrhs2)' + local rhsnms2 "`r(rhsnms2)'" + } + + * get info from pecats if depvar not continuous + if "`output'" != "regress" & "`output'" != "tobit" { + _pecats + local ncats = r(numcats) + local catnms8 `r(catnms8)' + local catvals `r(catvals)' + local catnms `r(catnms)' + } + + *get root() for generating new variables + local root = substr("`generate'",1,29) + if _rc != 0 { + local root = substr("`generate'",1,5) + } + + * convert input into base values + _pebase `if' `in', `x' `rest' `choices' `all' + mat `tobase' = r(pebase) + if "`input'"=="twoeq" { + mat `tobase2' = r(pebase2) + } + + * create if to take e(sample) and if conditions into account + _peife `if', `all' + local if "`r(if)'" + + * set from and to to min and max of chngvar if unspecified + qui sum `varlist' `if' + if `from' == -867.5309 { + local from = r(min) + } + if `to' == 867.5309 { + local to = r(max) + } + +// set up and test range to be plotted + + * check from and to + if `from'>=`to' { + di in r "from() must be < to()" + exit + } + + * turn gap into increments + if `gap' != 0 { + if `gap'<=0 { + di in r "gap must be a positive value." + } + tempname range ngaps + sca `range' = `to' - `from' + sca `ngaps' = `range'/`gap' + if int(`ngaps')==`ngaps' { + local ncases = `ngaps' + 1 + } + else { + di in r "gap does not divide evenly into from to interval." + exit 198 + } + } + + * verify valid number of plot points + if `ncases' < 3 { + di in r "ncases() must be greater than 3" + exit 198 + } + if `ncases' > _N { + set obs `ncases' + } + sca `inc' = (`to'-`from')/(`ncases'-1) + +// find variables among those in model + + * locate specified variable among rhs variables + local found "no" + local varnum -1 + + *look in main equation, if not there: varnum == -1 + local i2 = 1 + local i2_to : word count `rhsnms' + while `i2' <= `i2_to' { + local varchk : word `i2' of `rhsnms' + unab varchk : `varchk', max(1) + if "`varlist'"=="`varchk'" { + local found "yes" + local varnum = `i2' + local i2 = `i2_to' + } + local i2 = `i2' + 1 + } + + * if zip,zinb look in inflate equation, if not there: varnum2 == -1 + if "`input'"=="twoeq" { + local i3 = 1 + local i3_to : word count `rhsnms2' + local varnum2 -1 + while `i3' <= `i3_to' { + local varchk : word `i3' of `rhsnms2' + unab varchk : `varchk', max(1) + if "`varlist'"=="`varchk'" { + local found "yes" + local varnum2 = `i3' + local i3 = `i3_to' + } + local i3 = `i3' + 1 + } + } + + if "`found'"=="no" { + di in r "`var' not rhs variable" + exit 198 + } + +// insert from value into base values for initial call of prvalue + + mat PE_in = `tobase' + * from to variable begins at from + if `varnum' != -1 { + mat PE_in[1, `varnum']=`from' + } + * for zip and zinb + if "`input'"=="twoeq" { + mat PE_in2 = `tobase2' + if `varnum2' != -1 { + mat PE_in2[1, `varnum2']=`from' + } + } + +// make x() string and compute predictions + + _pexstring + local xis "`r(xis)'" + `quietly' prvalue , x(`xis') `pr2input' + +// get marginal + + if "`marginal'"=="marginal" { + tempname marg tempmarg + _pemarg + mat `tempmarg' = r(marginal) + if "`output'"=="nominal" | "`output'"=="ordered" { + mat `tempmarg' = `tempmarg'' + } + mat `marg' = `tempmarg'[1...,`varnum']' + } + +// create matrices to be converted to variables + + tempname x_pred pr_pred mu_pred all0_pred xb_pred catvals nextbase + tempname pr_upper mu_upper all0_upper xb_upper + tempname pr_lower mu_lower all0_lower xb_lower + + mat def `catvals' = pepred[1,1...] + mat def `x_pred' = `from' + + local predset "pred" + if "`ci'" == "ci" { + local predset "`predset' upper lower" + } + + foreach nm in `predset' { + + * zt 19Feb2005 + mat def `pr_`nm'' = pe`cond'`nm'[2,1...] + mat def `mu_`nm'' = pe`cond'`nm'[3,2] + mat def `xb_`nm'' = pe`cond'`nm'[3,1] + mat def `all0_`nm'' = pe`cond'`nm'[3,4] + } + +// loop from from value to to value + + local i = 2 + local i_to = `ncases' + while `i' <= `i_to' { + sca `xval' = `from' + (`inc'*(`i'-1)) + * change from variable value + mat `nextbase' = `tobase' + if `varnum' != -1 { + mat `nextbase'[1, `varnum']=`xval' + } + mat PE_in = `nextbase' + + * create x() string + _pexstring + local xis "`r(xis)'" + + * 0.2.2 050203 `quietly' prvalue , x(`xis') `rest' `pr2input' + `quietly' prvalue , x(`xis') `pr2input' + + * get marginal effect + if "`marginal'"=="marginal" { + _pemarg + mat `tempmarg' = r(marginal) + * some marginal matrices need to be transposed first + if "`output'"=="nominal" | "`output'"=="ordered" { + mat `tempmarg' = `tempmarg'' + } + mat def `marg' = `marg' \ `tempmarg'[1...,`varnum']' + } + + * stack new values in matrices + mat def `x_pred' = `x_pred' \ `xval' + foreach nm in `predset' { + mat def `pr_`nm'' = `pr_`nm'' \ pe`cond'`nm'[2,1...] + mat def `mu_`nm'' = `mu_`nm'' \ pe`cond'`nm'[3,2] + mat def `xb_`nm'' =`xb_`nm'' \ pe`cond'`nm'[3,1] + if "`input'"=="twoeq" { + mat def `all0_`nm'' =`all0_`nm'' \ pe`nm'[3,4] + } + } + local i = `i' + 1 + } + +// create plot variables + + * x variable + svmat `x_pred', n(`root'x) + rename `root'x1 `root'x + * 23May2005 + local tmplabel : variable label `varlist' + label variable `root'x "`tmplabel'" + * label variable `root'x "Changing value of `varlist'" + + * marginal effects + if "`marginal'"=="marginal" { + local margnm : word `varnum' of `rhsnms' + svmat `marg', n(`root'me_`margnm') + } + +// binary, ordered, nominal or count + + if "`output'"=="binary" /// + | "`output'"=="nominal" /// + | "`output'"=="ordered" /// + | "`output'"=="count" { + + * predictions and bounds + svmat `pr_pred', n(temp) + if "`ci'"=="ci" { + svmat `pr_lower', n(templb) + svmat `pr_upper', n(tempub) + } + + * process each outcome probability + local ncats = peinfo[1,2] + foreach i of numlist 1/`ncats' { + + * get # assigned to first category + local value = `catvals'[1,`i'] + local k`i' = `value' + + * if value are too large or small + if `value' < -9 | `value' > 99 | int(`value')!=`value' { + di in red "category values must be integers between -9 and 99" + exit 198 + } + + * if negative create name using _ + if `value' < 0 { + local k`i' = abs(`k`i'') + local k`i' = "_`k`i''" + } + + * rename and label probability + rename temp`i' `root'p`k`i'' + local lbl: word `i' of `catnms8' + + * get information to label variables + if "`lbl'"=="`value'" { + local fvalue "" // same, so only use 1 + } + else { + local fvalue "=Pr(`value')" + } + if "`lbl'"=="" { + local lbl "`value'" + local fvalue "" + } + if "`nolabel'"!="nolabel" { + * zt 19Feb2005 + label variable `root'p`k`i'' /// + "`condnmlc'pr(`lbl')`fvalue'" + } + else { + * zt 19Feb2005 + label variable `root'p`k`i'' /// + "`condnmlc'pr(`value')" + } + + * process upper and lower bounds + if "`ci'"=="ci" { + rename tempub`i' `root'p`k`i''ub + if "label'"!="nolabel" { + label variable `root'p`k`i''ub "UB pr(`lbl')`fvalue'" + } + else { + label variable `root'p`k`i'' "UB pr(`value')" + } + rename templb`i' `root'p`k`i''lb + if "label'"!="nolabel" { + label variable `root'p`k`i''lb "LB pr(`lbl')`fvalue'" + } + else { + label variable `root'p`k`i'' "LB pr(`value')" + } + } + + * create variables summing prob of being <= k + if `ncats'>2 { + if `i' == 1 { + qui gen `root's`k1' = `root'p`k1' + } + else { + local i_min1 = `i' - 1 + qui gen `root's`k`i'' = `root'p`k`i'' + `root's`k`i_min1'' + } + label variable `root's`k`i'' "pr(y<=`value')" + } + + * marginals + if "`marginal'"=="marginal" & /// + "`output'"!="count" { // no marg pr# for count + rename `root'me_`margnm'`i' `root'Dp`k`i''D`margnm' + label variable `root'Dp`k`i''D`margnm' /// + "Marginal dp`k'`i'/d`margnm'" + } + + } // end of loop through categories + + } // binary, ordered, nominal or count + +// REGRESS/TOBIT MODELS + + if "`output'"=="regress" | "`output'"=="tobit" { + + svmat `xb_pred', n(`root'xb) + rename `root'xb1 `root'xb + + if "`ci'" == "ci" { + svmat `xb_lower', n(`root'xblb) + rename `root'xblb1 `root'xblb + svmat `xb_upper', n(`root'xbub) + rename `root'xbub1 `root'xbub + } + + if "`output'"=="regress" { + label variable `root'xb "y-hat" + if "`ci'" == "ci" { + label variable `root'xblb "UB y-hat" + label variable `root'xbub "LB y-hat" + } + } + + if "`output'"=="tobit" { + label variable `root'xb "y*-hat" + if "`ci'" == "ci" { + label variable `root'xblb "UB y*-hat" + label variable `root'xbub "LB y*-hat" + } + } + } // regress/tobit + +// for count models, process mu and prall0 + + if "`output'"=="count" { + + * marginals + if "`marginal'"=="marginal" { + mat list `marg' + drop `root'me_`margnm'1 + rename `root'me_`margnm'2 `root'DmuD`margnm' + label var `root'DmuD`margnm' "Marginal dmu/d`margnm'" + } + + * mu + svmat `mu_pred', n(`root'mu) + rename `root'mu1 `root'mu + * zt 19Feb2005 + label variable `root'mu "predicted `condnmlc'rate mu" + + * upper and lower bounds + if "`ci'"=="ci" { + svmat `mu_lower', n(`root'mulb) + rename `root'mulb1 `root'mulb + label variable `root'mulb "LB predicted rate mu" + svmat `mu_upper', n(`root'muub) + rename `root'muub1 `root'muub + label variable `root'muub "UB predicted rate mu" + } + + if "`input'"=="twoeq" { + svmat `all0_pred', n(`root'all0) + rename `root'all01 `root'all0 + label variable `root'all0 "pr(Always-0)" + if "`ci'"=="ci" { + svmat `all0_lower', n(`root'all0lb) + rename `root'all0lb1 `root'all0lb + label variable `root'all0lb "LB pr(Always-0)" + svmat `all0_upper', n(`root'all0ub) + rename `root'all0ub1 `root'all0ub + label variable `root'all0ub "UB pr(Always-0)" + } + } + + } // mu and prob always 0 + +// COMMON OUTPUT + + if "`brief'"=="" & "`base'"!="nobase" { + di _n in y "`e(cmd)'" in g ": Predicted values as " /* + */ in y "`varlist'" in g /* + */ " varies from " in y "`from'" in g " to " /* + */ in y "`to'" in g "." + + *print base values + if "`input'"=="twoeq" { + di _n in g "base x values for count equation: " + } + mat rownames `tobase' = "x=" + mat _PEtemp = `tobase' + _peabbv _PEtemp + mat list _PEtemp, noheader + if "`input'"=="twoeq" { + di _n in g "base z values for binary equation: " + mat rownames `tobase2' = "z=" + mat _PEtemp = `tobase2' + _peabbv _PEtemp + mat list _PEtemp, noheader + } + } + +end +exit +* version 2.0.2 23May2005 : use label of varlist variable not changing... +* version 2.0.3 20Jun2005 : _pexstring bug fix +* version 2.0.4 23Jun2005 : _pexstring bug fix (2) diff --git a/Modules/ado/plus/p/prgen.hlp b/Modules/ado/plus/p/prgen.hlp new file mode 100644 index 0000000..37953cc --- /dev/null +++ b/Modules/ado/plus/p/prgen.hlp @@ -0,0 +1,204 @@ +{smcl} +{* 06Feb2010}{...} +{hline} +help for {hi:prgen}{right:06Feb2010} +{hline} + +{title:Generate predicted values and confidence intervals for regression models} + +{p 4 4 2} +To compute the predicted values with all variables but varname +held at values specified by x() and rest(). The program extends +{cmd:prgen} by allowing you to generate variables containing upper +and lower bounds for confidence intervals and marginal effects. + +{p 8 15 2}{cmd:prgen} varname, +{cmdab:g:enerate(}{it:newvar}{cmd:)} +[{cmdab:f:rom(}{it:#}{cmd:)} +{cmdab:t:o(}{it:#}{cmd:)}] +[{cmd:x(}{it:variables_and_values}{cmd:)} +{cmdab:r:est(}{it:stat}{cmd:)} +{cmd:all}] +[{cmdab:b:rief} +{cmdab:max:cnt(}{it:#}{cmd:)} +{cmdab:noba:se} +{cmdab:nola:bel} +{cmdab:n:cases(}{it:#}{cmd:)} +{cmd:gap(}{it:#}{cmd:)} +{cmdab:noi:sily} +{cmdab:mar:ginal} +{cmdab:con:ditional}] +[{cmd:ci} +{it:prvalue_options}] + +{p 4 4 2} +where {it:variables_and_values} is an alternating list of variables +and either numeric values or mean, median, min, max, upper, lower, +previous. + +{p 4 4 2} +{it:stat} is either mean, median, min, max, upper, lower, previous, +grmean (group mean), grmedian, grmin, grmax. + +{p 4 4 2} +See {help prvalue} for options that can be specified for computing +confidence intervals. + +{title: Description} + +{p 4 4 2} +{cmd:prgen} computes predicted values and confidence intervals +for regression with continuous, categorical, and count outcomes +in a way that is useful for making plots. Predicted values are computed +for the case in which one independent variable varies over a specified +range while the others are held constant. You can request variables +containing upper and lower bounds for these variables. You can also +create a variable containing the marginal change in the outcome with +respect to the specified variable, holding other variabels constant. New +variables are added to the existing dataset that contain these +predicted values that can be plotted. + +{p 4 4 2} +Note: The new variables will contain data for the first k observations +in the dataset, where k is 11 if not specified with the {cmd: ncases()} +option or if not determined by the {cmd:gap} option. + +{title: Options} + +{p 4 8 2} +{cmd:from()} and {cmd:to()} specify the values over which varname +should vary when calculating predicted values. The defaults are the +observed minimum and maximum values. + +{p 4 8 2} +{cmd:generate()} is up to five letters to name the created variables. +By changing the name you can run -prgen- repeatedly to compute predictions +with variables held at various values. It is best to chose a name that is +different from the beginning letters of variables in your data set. +This is required. + +{p 4 8 2} +{cmd:ci} indicates that you want to generate confidence intervals +corresponding to the predictions made by {cmd:prgen}. + +{p 4 8 2} +{cmd:marginal} indicates that you want to generate a variable +containing the marginal change in the outcome relative to varname, +holding all other variables constant. + +{p 4 8 2} +{cmd:conditional} indicates that you want to generate conditional +predictions rather than unconditional predictions for {cmd:ztp} and +{cmd:ztnb} models. + +{p 4 8 2} +{cmd:ncases} is the number of predicted values computed as varname +varies from the start value to the end value. If {cmd:Ncases} is not +specified, 11 points are generated. + +{p 4 8 2} +{cmd:gap} is an alternative to {cmd:ncases}. You specify the gap or +size between tic marks and {cmd:prgen} determines if the specified +value divides evenly into the from-to range. If it does, {cmd:prgen} +determines the appropriate value for {cmd:ncases}. + +{p 4 8 2} +{cmd:x()} sets the values of independent variables for calculating +predicted values. The list must alternate variable names and values. +The values may be either numeric values or can be mean, median, min, max, +previous, upper, or lower. The latter cannot be used if rest() +specifies a group summary statistic (e.g., grmean). + +{p 4 8 2} +{cmd:rest()} sets the independent variables not specified in x() to +their {cmd:mean} (default), {cmd:minimum}, {cmd:maximum}, +{cmd:median} when calculating predicted values.{cmd:grmean} sets these +independent variables to the mean conditional on the variables and +values specified in x(); {cmd:grmedian}, {cmd:grmax}, and {cmd:grmin} +can also be used. If {cmd:prvalue} has already been run after the last +estimate, {cmd:previous} will set unspecified variables to their prior values. +For models other than mlogit, {cmd:upper}and {cmd:lower} can be used to set +independent variables to their minimum or maximum depending on which will yield +the upper or lower extreme predicted value. + +{p 4 8 2} +{cmd:maxcnt()} sets the maximum count for which variables are generated +for count models. The value must be an integer between 0 and 30; +the default is 9. + +{p 4 8 2} +{cmd:all} specifies that any calculations of means, medians, etc., +should use the entire sample instead of the sample used to estimate +the model. + +{p 4 8 2} +{cmd:brief} and {cmd:nobase} suppress the base values of x in the output. + +{p 4 8 2} +{cmd:nolabel} uses values rather than value labels in output. + +{p 4 8 2} +{cmd:noisily} indicates that you want to see the output from +{cmd:prvalue}that was was used to generate the predicted values. + +{p 4 8 2} +{it:prvalue_options} control the calculation of confidence intervals; +see {help prvalue} for details about these options. + +{title:Models and Predictions - * is the prefix} + +all models: + + *x: value of x + + logit & probit: + Predicted probability of each outcome: *p0, *p1 + + ologit, oprobit + Predicted probabilities: *p#1,*p#2,... where #1,#2,... are values of + the outcome variable. + Cumulative probabilities: *s#1,*s#2,... where #1,#2,... are values + of the outcome variable. *s#k is the probability of all + categories up to or equal to #k. + + mlogit: + Predicted probabilities: *p#1,*p#2,... where #1,#2,... are values of + the outcome variable. + + poisson & nbreg: + Predicted rate: *mu; + Predicted probabilities: *p0, *p1... where 0, 1, are counts + Cumulative probabilities: *s0, *s1... where 0, 1 are counts. + The cumulative probability of a given count is probability of + observing count less than or equal to that count. + + regress, tobit, cnreg, intreg + Predicted xb: *xb + +{title: Examples} + +{p 4 4 2} +To compute predicted values and confidencen intervals from an ordered probit +where warm has four categories SD, D, A and SA: + +{p 4 8 2}{cmd:.oprobit warm yr89 male white age ed prst} + +{p 4 8 2}{cmd:.prgen age, f(20) t(80) gen(mn) ci delta} + +{p 4 8 2}{cmd:.prgen age, x(male=0) f(20) t(80) gen(fem)} + +{p 4 8 2}{cmd:.prgen age, x(male=1) f(20) t(80) gen(mal)} + +{p 4 8 2} +To plot the predicted probabilites for average males: + +{p 4 8 2}{cmd:.twoway connected malp1 malp2 malp3 malp4 malx} + +{hline} + +{p 2 4 2}Authors: J. Scott Long, Jeremy Freese & Jun Xu{p_end} +{p 11 4 2}{browse www.indiana.edu/~jslsoc/spost.htm}{p_end} +{p 11 4 2}spostsup@indiana.edu{p_end} + + + diff --git a/Modules/ado/plus/p/prodlist.ado b/Modules/ado/plus/p/prodlist.ado new file mode 100644 index 0000000..23d252b --- /dev/null +++ b/Modules/ado/plus/p/prodlist.ado @@ -0,0 +1,36 @@ +program def prodlist, rclass +*! NJC 1.0.0 9 April 2001 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "no list specified" + exit 198 + } + + numlist "`list'" + local list `r(numlist)' + local nw : word count `list' + + syntax [ , Global(str) Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tempname prod + scalar `prod' = 1 + tokenize `list' + + local i = 1 + while `i' <= `nw' { + scalar `prod' = (`prod') * (``i'') + local i = `i' + 1 + } + + if "`noisily'" != "" { di `prod' } + if "`global'" != "" { global `global' = `prod' } + return scalar prod = `prod' +end + + diff --git a/Modules/ado/plus/p/prodlist.hlp b/Modules/ado/plus/p/prodlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/p/prodlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/p/prtab.ado b/Modules/ado/plus/p/prtab.ado new file mode 100644 index 0000000..1b0e751 --- /dev/null +++ b/Modules/ado/plus/p/prtab.ado @@ -0,0 +1,460 @@ +*! version 2.5.0 2009-10-28 jsl +* - stata 11 update for returns from -mlogit- + +capture program drop prtab +program define prtab, rclass + version 6 + tempname tobase tobase2 addbase replval temp + tempvar added cell + +** #1 classify each valid type of model + + * zt 18Feb2005 + local iszt = 0 + if ("`e(cmd)'"=="ztp" | "`e(cmd)'"=="ztnb") { + local iszt = 1 + } + + * zt 19Feb2005 + if "`e(cmd)'"=="ztp" { local io = "typical count" } + if "`e(cmd)'"=="ztnb" { local io = "typical count" } + if "`e(cmd)'"=="cloglog" { local io = "typical binary" } + if "`e(cmd)'"=="cnreg" { local io = "typical tobit" } + if "`e(cmd)'"=="fit" { local io = "typical regress" } + if "`e(cmd)'"=="gologit" { local io = "typical mlogit" } + if "`e(cmd)'"=="intreg" { local io = "typical tobit" } + if "`e(cmd)'"=="logistic" { local io = "typical binary" } + if "`e(cmd)'"=="logit" { local io = "typical binary" } + if "`e(cmd)'"=="mlogit" { local io = "typical mlogit" } + if "`e(cmd)'"=="nbreg" { local io = "typical count" } + if "`e(cmd)'"=="ologit" { local io = "typical ordered" } + if "`e(cmd)'"=="oprobit" { local io = "typical ordered" } + if "`e(cmd)'"=="poisson" { local io = "typical count" } + if "`e(cmd)'"=="probit" { local io = "typical binary" } + if "`e(cmd)'"=="regress" { local io = "typical regress" } + if "`e(cmd)'"=="slogit" { local io = "typical ordered" } + if "`e(cmd)'"=="tobit" { local io = "typical tobit" } + if "`e(cmd)'"=="zinb" { local io = "twoeq count" } + if "`e(cmd)'"=="zip" { local io = "twoeq count" } + if "`io'"=="" { + di + di in r "prtab does not work for the last type of model estimated." + exit + } + local input : word 1 of `io' /* input routine to _pepred */ + local output : word 2 of `io' /* output routine */ + +** #2 get info about variables + + _perhs + local nrhs = `r(nrhs)' + local rhsnms "`r(rhsnms)'" + if "`input'"=="twoeq" { + local nrhs2 = `r(nrhs2)' + local rhsnms2 "`r(rhsnms2)'" + } + if "`output'" != "regress" & "`output'" != "tobit" { + _pecats + local ncats = r(numcats) + local catnms8 `r(catnms8)' + local catvals `r(catvals)' + local catnms `r(catnms)' + } + +** #3 decode specified input + + syntax varlist(min=1 max=3 numeric) [if] [in] /* + */ [, x(passthru) Rest(passthru) Outcome(string) /* + */ by(varlist numeric max=1) /* + */ noBAse Brief NOLabel NOVARlbl all /* + */ CONditional ] + + * zt 19Feb2005 + if `iszt'==1 & "`conditional'"=="conditional" /// + & "`outcome'"=="0" { + di _n in r "conditional probabilities for outcome 0 are undefined." + exit + } + + *convert input into tobase + _pebase `if' `in', `x' `rest' `choices' `all' + mat `tobase' = r(pebase) + if "`input'"=="twoeq" { mat `tobase2' = r(pebase2) } + + *fix if to take e(sample) and if conditions into account + _peife `if', `all' + local if "`r(if)'" + + * handle outcome option for ordered mlogit and ordered models + if "`outcome'"!="" { + if "`output'"=="ordered" | "`output'"=="mlogit" { + local found "no" + local i = 1 + while `i' <= `ncats' { + local valchk : word `i' of `catvals' + local nmchk : word `i' of `catnms' + if ("`outcome'"=="`valchk'") | ("`outcome'"=="`nmchk'") { + local found "yes" + local outcmv = "`valchk'" + if "`valchk'"!="`nmchk'" { local outcmnm "(`nmchk')" } + local outcome = `i' + local i = `ncats' + } + local i = `i' + 1 + } /* while `i' <= `ncats' */ + if "`found'"=="no" { + di in r "`outcome' not category of `e(depvar)'" + exit 198 + } + } /* "`output'"=="ordered" | "`output'"=="mlogit" { */ + else if "`output'"=="count" { + confirm integer number `outcome' + if `outcome' < 0 { exit 198 } + local outcmv "`outcome'" + } + else { + di in r "outcome() not allowed for prtab after `e(cmd)'" + exit 198 + } + } /* if "`outcome'"!="" */ + + *if by option has been specified, put this variable into the end + *of `varlist' + local varnoby = "`varlist'" /* needed for tabdisp at end */ + if "`by'"!="" { local varlist "`varlist' `by'" } + +** #4 build PE_in matrix + + local nvars : word count `varlist' + *cycle through varlist (as many as four variables) + local i = 1 + while `i' <= 4 { + *if varlist shorter than i, set ncats# to 1 and varnum# to -1 + if `nvars' < `i' { + local ncats`i' = 1 + local varnum`i' = -1 + if "`input'"=="twoeq" { local varnm2`i' = -1 } + } + else { + local var`i' : word `i' of `varlist' + _pecats `var`i'' `if' + local ncats`i' = r(numcats) + local nms`i' "`r(catnms)'" + local nms8`i' "`r(catnms8)'" + local vals`i' "`r(catvals)'" + * find variable position in base matrix + * assign varnum and varnm2 accordingly + * varnum == -1 if not in main equation + * varnum2 == -1 if zip/zinb but variable not in inflate equation + local found "no" + local varnum`i' -1 + local i2 = 1 + local i2_to : word count `rhsnms' + while `i2' <= `i2_to' { + local varchk : word `i2' of `rhsnms' + unab varchk: `varchk', max(1) + if "`var`i''"=="`varchk'" { + local found "yes" + local varnum`i' = `i2' + local i2 = `i2_to' + } + local i2 = `i2' + 1 + } + *if zip/zinb model + if "`input'"=="twoeq" { + local varnm2`i' -1 + local i3 = 1 + local i3_to : word count `rhsnms2' + while `i3' <= `i3_to' { + local varchk : word `i3' of `rhsnms2' + unab varchk: `varchk', max(1) + if "`var`i''"=="`varchk'" { + local found "yes" + local varnm2`i' = `i3' + local i3 = `i3_to' + } + local i3 = `i3' + 1 + } + } + if "`found'"=="no" { + di in r "`var`i'' not rhs variable" + exit 198 + } + } /* else */ + local i = `i' + 1 + } /* while `i' <= `nvars' */ + + capture matrix drop PE_in + capture matrix drop PE_in2 + *build PE_in matrix + local i1 = 1 + while `i1' <= `ncats1' { + local i2 = 1 + while `i2' <= `ncats2' { + local i3 = 1 + while `i3' <= `ncats3' { + local i4 = 1 + while `i4' <= `ncats4' { + *make new row of x's for main equation + mat `addbase' = `tobase' + if `varnum1' ~= -1 { + local addval : word `i1' of `vals1' + mat `addbase'[1, `varnum1'] = `addval' + } + if `varnum2' ~= -1 { + local addval : word `i2' of `vals2' + mat `addbase'[1, `varnum2'] = `addval' + } + if `varnum3' ~= -1 { + local addval : word `i3' of `vals3' + mat `addbase'[1, `varnum3'] = `addval' + } + if `varnum4' ~= -1 { + local addval : word `i4' of `vals4' + mat `addbase'[1, `varnum4'] = `addval' + } + *add row of x's to PE_in + mat PE_in = nullmat(PE_in) \ `addbase' + *second equation (binary eq for count models) + if "`input'"=="twoeq" { + mat `addbase' = `tobase2' + if `varnm21' ~= -1 { + local addval : word `i1' of `vals1' + mat `addbase'[1, `varnm21'] = `addval' + } + if `varnm22' ~= -1 { + local addval : word `i2' of `vals2' + mat `addbase'[1, `varnm22'] = `addval' + } + if `varnm23' ~= -1 { + local addval : word `i3' of `vals3' + mat `addbase'[1, `varnm23'] = `addval' + } + if `varnm24' ~= -1 { + local addval : word `i4' of `vals4' + mat `addbase'[1, `varnm24'] = `addval' + } + *add row of x's to PE_in + mat PE_in2 = nullmat(PE_in2) \ `addbase' + } /* if "`input'"=="twoeq" */ + local i4 = `i4' + 1 + } /* while `i4' <= `ncats4' */ + local i3 = `i3' + 1 + } /* while `i3' <= `ncats3' */ + local i2 = `i2' + 1 + } /* while `i2' <= `ncats2' */ + local i1 = `i1' + 1 + } /* while `i1' <= `ncats1' */ + if "`output'"=="count" { + if "`outcome'"!="" { local maxcnt "maxcnt(`outcome')" } + else { local maxcnt "maxcnt(0)" } + } + + _pepred, `maxcnt' + *note: the way the command is now: it requires -two- preserves + *one here and one in _pepred. This could be improved... + preserve + qui gen `added' = 0 + local newobs = rowsof(PE_in) + local oldn = _N + local newn = `oldn'+`newobs' + qui set obs `newn' + qui replace `added' = 1 if `added' == . + local i = 1 + while `i' <= `nrhs' { + local varname : word `i' of `rhsnms' + local i2 = 1 + while `i2' <= `newobs' { + local to_rep = `oldn' + `i2' + sca `replval' = PE_in[`i2',`i'] + qui replace `varname' = `replval' in `to_rep' + local i2 = `i2' + 1 + } + local i = `i' + 1 + } + + if "`nrhs2'"!="" { + local i = 1 + while `i' <= `nrhs2' { + local varname : word `i' of `rhsnms2' + local i2 = 1 + while `i2' <= `newobs' { + local to_rep = `oldn' + `i2' + sca `replval' = PE_in2[`i2',`i'] + qui replace `varname' = `replval' in `to_rep' + local i2 = `i2' + 1 + } + local i = `i' + 1 + } + } + + di _n in y "`e(cmd)'" in g ": Predicted " _c + if "`output'"=="binary" { + local r_toget "p1" + local fmt "%6.4f" + if "`brief'"=="" { di in g "probabilities of positive outcome" _c } + } + if "`output'"=="regress" { + local r_toget "xb" + local fmt "%8.0g" + if "`brief'"=="" { di in g "values" _c } + } + if "`output'"=="tobit" { + local r_toget "xb" + local fmt "%8.0g" + if "`brief'"=="" { di in g "values of y*" _c } + } + if "`output'"=="count" & (`iszt'!=1) { + if "`outcome'"=="" { + local r_toget "mu" + local fmt "%8.4f" + if "`brief'"=="" { di in g "rates" _c } + } + if "`outcome'"!="" { + local r_toget "p`outcome'" + local fmt "%6.4f" + if "`brief'"=="" { + di in g "probabilities of count = `outcome'" _c + } + } + } + + * zero truncated models 19Feb2005 + if `iszt'==1 { + if "`conditional'"=="" { + local type "unconditional" + } + else { + local type "conditional" + } + if "`outcome'"=="" { + if "`conditional'"=="" { + local r_toget "mu" + } + else { + local r_toget "Cmu" + } + local fmt "%8.4f" + if "`brief'"=="" { di in g "`type' rates" _c } + } + if "`outcome'"!="" { + local r_toget "p`outcome'" + if "`conditional'"=="" { + local r_toget "p`outcome'" + } + else { + local r_toget "Cp`outcome'" + } + local fmt "%6.4f" + if "`brief'"=="" { + di in g "`type' probabilities of count = `outcome'" _c + } + } + } + + if "`output'"=="ordered" | "`output'"=="mlogit" { + local fmt "%6.4f" + if "`outcome'"=="" { + local do_all "yes" + local do_allc = 1 + if "`brief'"=="" { di in g "probabilities" _c } + } + else { + if "`brief'"=="" { + di in g "probabilities of outcome `outcmv' `outcmnm'" _c + } + local r_toget "p`outcome'" + } + } + + di in g " for " in y "`e(depvar)'" + +** #5 TRANSLATE EVERYTHING INTO TEMPORARY VARIABLES + + tempvar tmpvar1 tmpvar2 tmpvar3 tmpvar4 + local count = 1 + while `count' <= `nvars' { + qui gen `tmpvar`count'' = `var`count'' if `added' == 1 + label variable `tmpvar`count'' "`var`count''" + if "`nolabel'"!="nolabel" { + local lblnam1 : value label `var`count'' + if "`lblnam1'"!="" { label values `tmpvar`count'' `lblnam1' } + } + if "`novarlbl'"!="novarlbl" { + local lblnam2 : variable label `var`count'' + if "`lblnam2'"!="" { label variable `tmpvar`count'' "`lblnam2'" } + } + local count = `count' + 1 + } + + *make lists of temporary variables for tabdisp + local count = 1 + local countto : word count `varnoby' + while `count' <= `countto' { + local tmpxxx = "`tmpvar`count''" + local tmpnoby = "`tmpnoby'`tmpxxx' " + local count = `count' + 1 + } + if "`by'" != "" { + local tmpby = "`tmpvar`nvars''" + } + +** #6 DISPLAY OUTPUT + *doneyet needed if tables needed for multiple categories (e.g. oprobit) + local doneyet "no" + while "`doneyet'"=="no" { + if "`do_all'"=="yes" { + local r_toget = "p`do_allc'" + local outcmv : word `do_allc' of `catvals' + local outcmnm : word `do_allc' of `catnms' + if "`outcmnm'"!="`outcmv'" { + di _n in gr "Predicted probability of outcome " /* + */ "`outcmv' (`outcmnm')" + } + else { di _n in gr "Predicted probability of outcome `outcmv'" } + } + qui gen `cell' = . + mat `temp' = r(`r_toget') + local i = 1 + while `i' <= `newobs' { + local to_rep = `oldn' + `i' + sca `replval' = `temp'[`i', 1] + qui replace `cell' = `replval' in `to_rep' + local i = `i' + 1 + } + if "`by'" != "" { local by4 "by(`tmpby')" } + label variable `cell' "Prediction" + tabdisp `tmpnoby' if `added'==1, c(`cell') `by4' f(`fmt') + if "`do_all'"=="yes" { + local do_allc = `do_allc' + 1 + if `do_allc' > `ncats' { local doneyet "yes" } + else { drop `cell' } + } + else { local doneyet "yes" } + + } /* while "`doneyet'" = "no" */ + + *print base values if desired + if "`brief'"=="" & "`base'"!="nobase" { + if "`input'"=="twoeq" { + di _n in g "base x values for count equation: " + } + mat rownames `tobase' = "x=" + mat _PEtemp = `tobase' + _peabbv _PEtemp + mat list _PEtemp, noheader + if "`input'"=="twoeq" { + di _n in g "base z values for binary equation: " + mat rownames `tobase2' = "z=" + mat _PEtemp = `tobase2' + _peabbv _PEtemp + mat list _PEtemp, noheader + } + } + +end +exit +* version 1.6.0 1/11/01 +* version 1.6.1 19Feb2005 zt +* version 1.6.2 27Mar2005 slogit +* version 1.6.3 13Apr2005 diff --git a/Modules/ado/plus/p/prtab.hlp b/Modules/ado/plus/p/prtab.hlp new file mode 100644 index 0000000..ddb964a --- /dev/null +++ b/Modules/ado/plus/p/prtab.hlp @@ -0,0 +1,95 @@ +.- +help for ^prtab^ - 2Nov2005 +.- + +Table of predicted values/probabilities/rates for regression models +------------------------------------------------------------------- + + ^prtab^ rowvar [colvar [supercolvar]] [^if^ exp] [^in^ range], + [^by(^superrowvar^)^ ^x(^variables_and_values^)^ ^r^est^(^stat^)^ + ^o^utcome^(^string^)^ ^b^rief ^noba^se ^nol^abel ^novar^lbl + ^con^ditional ^a^ll] + + where + + ^rowvar^, ^colvar^, ^supercolvar^, and ^superrowvar^ are independent variables + in the previous estimation. + + ^variables_and_values^ is an alternating list of variables and either + numeric values or mean, median, min, max, upper, lower, previous + + ^stat^ is either mean, median, min, max, upper, lower, previous, grmean + (group mean), grmedian, grmin, grmax + +Description +----------- + +After estimating a regression model, ^prtab^ presents a one- to four-way table +of the predicted values (probabilities, rate) for different combinations of +values of independent variable. + +The command works with cloglog, cnreg, intreg, logit, mlogit, mprobit, nbreg, +ologit, oprobit, poisson, probit, regress, slogit, tobit, zinb, zip, ztnb, +and ztp. + +Options +------- + +^by(superrowvar)^ specifies numeric variable to be treated as superrow. Only + one variable is allowed. + +^x()^ sets the values of independent variables for calculating predicted + values. The list must alternate variable names and values. The values + may be either numeric values or can be mean, median, min, max, previous, + upper, or lower. The latter cannot be used if rest() specifies a group + summary statistic (e.g., grmean). + +^rest()^ sets the independent variables not specified in x() to their ^mean^ + (default), ^minimum^, ^maximum^, ^median^ when calculating predicted values. + ^grmean^ sets these independent variables to the mean conditional on the + variables and values specified in x(); ^grmedian^, ^grmax^, and ^grmin^ can + also be used. If ^prvalue^ has already been run after the last estimate, + ^previous^ will set unspecified variables to their prior values. For + models other than mlogit, ^upper^ and ^lower^ can be used to set independent + variables to their minimum or maximum depending on which will yield the + upper or lower extreme predicted value. + +^outcome()^ presents results for the specified outcome. For ordered models or + mlogit, the default is to provide results for all outcomes (each one in a + separate table); for count models, the default is to present changes in + the predicted rate. + +^conditional^ for -ztp- and -ztnb-, table with contain conditional predictions + rather than the default unconditional predictions. + +^all^ specifies that any calculations of means, medians, etc., should use + the entire sample instead of the sample used to estimate the model. + +^brief^ and ^nobase^ suppress the base values of x in the output. + +^novallbl^ causes the numeric codes to be displayed rather than value labels. + +^nolabel^ causes the variable name to be displayed rather than the variable + label. + +Examples +-------- + +^. probit faculty female fellow phd mcit3 mnas^ +^. prtab female fellow mnas^ + +^. ologit jobclass female fellow pub1 phd^ +^. prtab female fellow, x(phd=min)^ + +^. poisson pub1 female fellow phd enrol^ +^. prtab female fellow^ +^. prtab female fellow, outcome(0)^ + +.- +Authors: J. Scott Long and Jeremy Freese + www.indiana.edu/~jslsoc/spost.htm + spostsup@@indiana.edu + + + + diff --git a/Modules/ado/plus/p/prvalue.ado b/Modules/ado/plus/p/prvalue.ado new file mode 100644 index 0000000..bc5bc09 --- /dev/null +++ b/Modules/ado/plus/p/prvalue.ado @@ -0,0 +1,1759 @@ +*! version 2.5.4 2010-03-26 +* remove 244 string length restrictions + +// See prvalue_globals.hlp for details on globals created the +// contain information on current results and that contain +// details on the -saved- model. + +// TO DO: add error trap if diff with no prior save. + +capture program drop prvalue +program define prvalue, rclass + + * 2.2.2 + local caller = _caller() // which version called prvalue + version 8 + tempname rpred seystar tobase tobase2 temp values probs xb xb_hi /// + xb_lo xb_prev xb_dif xb_prev_lo xb_prev_hi xb_prev_lvl ystarhi /// + ystarlo stdp p0 p1 p0_hi p1_hi p0_lo p1_lo p1_hi p0_dif p1_dif /// + p0_prev p1_prev p_prev p_dif Cprobs Cp_prev Cp_dif Cmu Cmu_dif + tempname Cmu_cur Cmu_prev mu mu_hi mu_lo mu_prev mu_prev_hi mu_prev_lo /// + mu_dif mu_dif_hi mu_dif_lo mucount mucount_lo mucount_hi /// + mucount_dif mucount_dif_hi mucount_dif_lo all0 all0_lo all0_hi /// + all0_prev all0_prev_lo all0_prev_hi all0_dif all0_dif_lo /// + all0_dif_hi + +// #1 CLASSIFY TYPE OF MODEL + + if "`e(cmd)'"=="mprobit" { // 28Feb2005 + local io = "typical mprobit" + } + if "`e(cmd)'"=="ztp" { // 18Feb2005 + local io = "typical count" + } + if "`e(cmd)'"=="ztnb" { + local io = "typical count" + } + if "`e(cmd)'"=="cloglog" { + local io = "typical binary" + } + if "`e(cmd)'"=="cnreg" { + local io = "typical tobit" + } + if "`e(cmd)'"=="fit" { + local io = "typical regress" + } + if "`e(cmd)'"=="gologit" { + local io = "typical mlogit" + } + if "`e(cmd)'"=="intreg" { + local io = "typical tobit" + } + if "`e(cmd)'"=="logistic" { + local io = "typical binary" + } + if "`e(cmd)'"=="logit" { + local io = "typical binary" + } + if "`e(cmd)'"=="mlogit" { + local io = "typical mlogit" + } + if "`e(cmd)'"=="nbreg" { + local io = "typical count" + } + if "`e(cmd)'"=="ologit" { + local io = "typical ordered" + } + if "`e(cmd)'"=="oprobit" { + local io = "typical ordered" + } + if "`e(cmd)'"=="poisson" { + local io = "typical count" + } + if "`e(cmd)'"=="probit" { + local io = "typical binary" + } + if "`e(cmd)'"=="slogit" { + local io = "typical slogit" + } + if "`e(cmd)'"=="regress" { + local io = "typical regress" + } + if "`e(cmd)'"=="tobit" { + local io = "typical tobit" + } + if "`e(cmd)'"=="zinb" { + local io = "twoeq count" + } + if "`e(cmd)'"=="zip" { + local io = "twoeq count" + } + + global PEio "`io'" // global with type of model + local input : word 1 of `io' + local output : word 2 of `io' + + if "`io'"=="" { + di in r "prvalue does not work for the last type of model estimated." + exit + } + +// #2 PRINTING DEFAULTS + + * output columns for printing values + local c_cur = 22 + local c_lo = 32 + local c_hi = 44 + * output columns for printing differences + local c_curD = 22 + local c_savD = 32 + local c_difD = 42 + local c_loD = 51 + local c_hiD = 62 + * columns for dif header + local c_curDH = 22 + local c_savDH = 34 + local c_difDH = 43 + local c_lvlDH = 52 + * formats + local yfmt "%7.0g" // for y values + local pfmt "%7.4f" // for probabilities + +// DECODE OPTIONS & SETUP PRINTING PARAMETERS + + syntax [if] [in] [, x(passthru) Rest(passthru) LEvel(passthru) /// + MAXcnt(passthru) noLAbel noBAse Brief Save Diff all /// + YStar ept DELta /// + BOOTstrap REPs(passthru) SIze(passthru) DOts match /// + SAving(passthru) NORMal PERCENTile BIAScorrected /// + test /// + LABel(string) ] // 2007-02-17 2.0.6 + +// #3 LABEL save and diff + + * 2007-02-17 add label + if "`save'"=="save" { + if "`label'"!="" { + global PRVlabsav "`label'" + } + else { + global PRVlabsav "" + } + } + if "`diff'"=="diff" { + if "`label'"!="" { + global PRVlabcur "`label'" + } + else { + global PRVlabcur "" + } + } + +// #4 DETERMINE METHOD FOR CI & TRAP ERRORS + + local errmethod "method cannot be used with the current model." + local errystar "ystar cannot be used with the current model." + + * ept invalid except with binary models + if "`ept'"=="ept" & "`output'"!="binary" { + di as error "ept is only valid for binary models." + exit + } + + * regress models use ml method + if ("`output'"=="regress" | "`output'"=="tobit" ) /// + & "`delta'"=="" & "`bootstrap'"=="" { + local ystar "ystar" + local mlci "ml" + } + + * delta invalid for zip/zinb + if "`input'"=="twoeq" & "`delta'"=="delta" { + di as error "the delta `errmethod'" + exit + } + * delta is the default ci method + if "`ystar'"=="" & "`bootstrap'"=="" & "`ept'"=="" { + local delta = "delta" + } + + * default method for zip and zinb is none + if ("`input'"=="twoeq") & "`bootstrap'"=="" { + local delta "" + } + + * no ci for ztp, ztnb, mprobit, slogit + if "`e(cmd)'"=="ztp" | "`e(cmd)'"=="ztnb" | /// + "`e(cmd)'"=="mprobit" | "`e(cmd)'"=="slogit" { + local delta "" + local bootstrap "" + } + + * trap boot options with delta, ept and ystar + foreach method in delta ept ystar { + if "``method''"=="`method'" { + local badopt "" + foreach nm in dots match normal percentile biascorrected { + if "``nm''"=="`nm'" { + local badopt "`nm'" + } + } + if "`badopt'"!="" { + di as error /// + "option `badopt' is incompatable with `method' method." + exit + di "ding" + } + } + } + if "`badopt'"!="" { + exit + } + + * determine method and make sure only one method specified + local cimethod "default" // ci method + local boottype "" // bootstrap ci type + local boottype2 "none" // short name + local ncimethod = 0 + if "`ystar'"=="ystar" { + local cimethod "ml" + local ncimethod = 1 + } + if "`delta'"=="delta" { + local cimethod "delta" + local ncimethod = `ncimethod' + 1 + } + if "`ept'"=="ept" { + local cimethod "ept" + local ncimethod = `ncimethod' + 1 + } + local nboottype = 0 + if "`bootstrap'"=="bootstrap" { + local cimethod "bootstrap" + local boottype "percentile method" + local boottype2 "percentile" + local ncimethod = `ncimethod' + 1 + if "`percentile'" == "percentile" { + local nboottype = 1 + } + if "`normal'" == "normal" { + local boottype2 "normal" + local boottype "normal approximation" + local nboottype = `nboottype' + 1 + } + if "`biascorrected'" == "biascorrected" { + local boottype "bias-corrected method" + local boottype2 "biascorrected" + local nboottype = `nboottype' + 1 + } + } + + if "`ncimethod'" > "1" { + di as error "only one method for computing CIs can be specified." + exit + } + if "`nboottype'" > "1" { + di as error "only one method of computing " /// + "bootstrap CIs can be specified." + exit + } + + * ept only with binary models + if "`ept'"!="" & "`output'"!="binary" { + di as error "the ept `errmethod'" + exit + } + + * ept invalid with diff + if "`ept'"!="" & "`diff'"=="diff" { + di as error "the ept method does not work with the diff option." + exit + } + * ystar invalid with mlogit, count and gologit + if ("`e(cmd)'"=="mlogit" | "`output'"=="count" /// + | "`e(cmd)'"=="gologit") /// + & "`ystar'"=="ystar" { + di as error "`errystar'" + exit + } + + * delta invalid with regress, tobit, intreg, cnreg, zip or zinb + if ("`output'"=="regress" | "`output'"=="tobit" /// + | "`input'"=="twoeq") & "`delta'"=="delta" { + di as error "the delta `errmethod'" + exit + } + + * bootstrap does not work with cnreg, intreg, regress or tobit + if ("`output'"=="regress" | "`output'"=="tobit") /// + & "`bootstrap'"=="bootstrap" { + di as error "the bootstrap `errmethod'" + exit + } + + * dummy out methods since cis not computed + if "`e(cmd)'"=="ztp" | "`e(cmd)'"=="ztnb" { + global pecimethod "" + local cimethod "" + } + + * if diff, methods must match + if "`diff'" == "diff" { + local cimethodprior : word 1 of $pecimethod + * 2.1.8 - no CIs for mprobit - 2009-03-14 + if "`e(cmd)'"=="slogit" | "`e(cmd)'"=="mprobit"{ + local cimethod "`cimethodprior'" + } + + * 26Jun2006 rule does not apply for regress which only uses ml + if ("`cimethod'" != "`cimethodprior'") & ("`e(cmd)'"!="regress") { + di as error "the methods used for save and dif must be the same." + exit + } + } + + * info on outcomes + if "`output'" != "regress" & "`output'" != "tobit" { + _pecats + local ncats = r(numcats) + local catnms8 `r(catnms8)' + local catvals `r(catvals)' + local catnms `r(catnms)' + } + + * check for errors with diff + if "`diff'"=="diff" { + local priorcmd : word 1 of $petype + if "`priorcmd'" != "`e(cmd)'" { + di in r "saved results were not estimated with `e(cmd)'" + exit + } + if "$PRVdepv" != "`e(depvar)'" { + di in r /// + "the dependent variable has changed from the saved model." + exit + } + if "`output'"=="ordered" | "`output'"=="mlogit" { + if "`catvals'"!="$PRVvals" { + di in r "category values for saved and current " /* + */ "dependent variable do not match" + exit + } + } + } + +// #5 GET INFO ON OUTCOME AND BASE VALUES + + * info on base values + _pebase `if' `in' , `x' `rest' `choices' `all' + mat `tobase' = r(pebase) + if "`input'"=="twoeq" { + mat `tobase2' = r(pebase2) + } + if "`input'"=="typical" { + mat PE_in = `tobase' + } + if "`input'"=="twoeq" { + mat PE_in = `tobase' + mat PE_in2 = `tobase2' + } + +// #6 COMPUTE PREDICTIONS + + * 2008-07-10 // clear globals to hold se for differences + global pedifsey = . // clear global that contains ml se of difference + global pedifsemu = . // clear global that contains ml se of difference + matrix def pedifsep = J(1,1,.) + global pesemu = . + + _pepred, `level' `maxcnt' + +// #7 COLLECT INFORMATION AND SAVE TO GLOBALS + + local maxc = r(maxcount) + local lvl = r(level) + + * Backup information in returns before calling _pecollect + * since _pecollect destroys current information. Then, + * after calling _pecollect, restore the original returns. + * + * 1) drop stored returns; 2) save returns from pepred + * 3) restore them after z_pecollect; 4) drop returns + * 5) save from pepred; 6) restore and keep them saved + + capture _return drop pepred + _return hold pepred + _return restore pepred, hold + global pecimethod "`cimethod' `boottype2'" + + * stores information on current model and differences to globals + _pecollect, inout("`io'") level(`lvl') maxcount(`maxc') `diff' `reps' + + *_return restore pepred // changed bj 22jul2008 for use with estout + *_return drop _all // changed bj 22jul2008 for use with estout + *_return hold pepred // changed bj 22jul2008 for use with estout + _return restore pepred, hold + +// #8 COMPUTE CONFIDENCE INTERVALS + + global pecimethod "ml none" // by default, use ml method + if "`input'"=="twoeq" { + global pecimethod "default" + } + if "`ept'" == "ept" { + local cimethod "end-point transformation" + * ci's were computed by _pepred + global pecimethod "ept none" + } + if "`delta'" == "delta" { + local cimethod "delta" + global pecimethod "delta none" + * compute ci's using delta method + * 0.2.1 _pecidelta, `save' `diff' + _pecidelta, `save' `diff' caller(`caller') // 0.2.2 + } + if "`bootstrap'"=="bootstrap" { + local cimethod "bootstrap" + global pecimethod "bootstrap `boottype2'" + * compute ci's using bootstrap + _peciboot, `x' `rest' `all' `save' /// + `diff' `reps' `size' `dots' `match' `saving' + matrix peinfo[1,10] = r(Nrepsnomis) // # of completed reps + } + * ystar with diff + if "`ystar'"=="ystar" & "`diff'"=="diff" { + * ystar only defined for these model types + if "`output'"=="binary" | "`output'"=="tobit" /// + | "`output'"=="regress" | "`e(cmd)'"=="ologit" /// + | "`e(cmd)'"=="oprobit" { + + local cimethod "ystar" + global pecimethod "ystar none" + * compute ml ci of difference + _peciml + _return restore pepred + + } // if models for ystar + } // ystar for difference + +// #9 NOT USED + +// #10 OUTPUT HEADER + + local level = peinfo[1,3] // 95 not .95 + local max_i = peinfo[1,2] - 1 // # of categories - 1 + di + if "`diff'"=="" { + di in y "`e(cmd)'" in g ": Predictions for " /// + in y "`e(depvar)'" + } + if "`diff'"=="diff" { + di in y "`e(cmd)'" in g ": Change in Predictions for " /// + in y "`e(depvar)'" + } + if "`brief'"=="" { + if "`cimethod'" == "ept" { + di in g _n "Confidence intervals using end-point transformations" + } + else if "`cimethod'" == "delta" { + di in g _n "Confidence intervals by delta method" + } + else if "`cimethod'"=="bootstrap" { + di in g _n "Bootstrap confidence intervals using `boottype'" // 2.1.6 + } + } // not brief + if "`cimethod'"=="bootstrap" { + di in g "(" peinfo[1,10] " of " peinfo[1,9] /// + " replications completed)" + } + +// #11 PUT SELECTED METHOD-TYPE OF CI INTO MATRIX TO PRINT + + tempname ciupper cilower + * by default, this will be percentile with boot + mat def `ciupper' = peupper + mat def `cilower' = pelower + + if "`cimethod'"=="bootstrap" { + * if percentile, already in peupper/lower + if "`normal'" == "normal" { + mat def `ciupper' = peupnorm + mat def `cilower' = pelonorm + * put selected method into peupper and lower + mat def peupper = peupnorm + mat def pelower = pelonorm + } + if "`biascorrected'" == "biascorrected" { + mat def `ciupper' = peupbias + mat def `cilower' = pelobias + * put selected method into peupper and lower + mat def peupper = peupbias + mat def pelower = pelobias + } + } + +// +// PRINT RESULTS +// + +// #12 REGRESS & TOBIT ROUTINES + + if "`output'" == "tobit" | "`output'" == "regress" { + + sca `xb' = pepred[3,1] + sca `xb_lo' = `cilower'[3,1] + sca `xb_hi' = `ciupper'[3,1] + sca `stdp' = peinfo[1,8] // se(xb) + return scalar xb = `xb' + return scalar xb_lo = `xb_lo' + return scalar xb_hi = `xb_hi' + return local level `level' + + * 2008-06-15 r(pred) + matrix def `rpred' = J(1,4,.) + matrix rownames `rpred' = ystar + matrix colnames `rpred' = ystar LB UB Category + matrix `rpred'[1,1] = `xb' + matrix `rpred'[1,2] = `xb_lo' + matrix `rpred'[1,3] = `xb_hi' + + local out "y" + local add 0 + if "`output'"=="tobit" { + local out "y*" + local add 1 + } + + PRTyciH `c_lo' `level' 1 + PRTy 2 "Predicted `out'" `yfmt' `c_cur' `xb' + PRTyci `yfmt' `c_lo' `level' `xb_lo' `c_hi' `xb_hi' + + if "`diff'"=="diff" { + + sca `xb_prev' = pepred[5,1] + local skip = 8 + `add' + PRTy `skip' "Saved" `yfmt' `c_cur' `xb_prev' + PRTyci `yfmt' `c_lo' `level' _PRVsav[1,3] /// + `c_hi' _PRVsav[1,4] + local skip = 3 + `add' + PRTy `skip' "Difference" `yfmt' `c_cur' `xb'-`xb_prev' + PRTyci `yfmt' `c_lo' `level' `cilower'[7,1] /// + `c_hi' `ciupper'[7,1] + + * 2008-07-10 r(pred) for dif + matrix def `rpred' = J(1,4,.) + matrix rownames `rpred' = ystar + matrix colnames `rpred' = Dystar LB UB Category + matrix `rpred'[1,1] = `xb'-`xb_prev' + matrix `rpred'[1,2] = `cilower'[7,1] + matrix `rpred'[1,3] = `ciupper'[7,1] + + } // if diff and regress/tobit + + if "`save'"=="`save'" { + mat _PRVsav = `xb', `stdp', `xb_lo', `xb_hi', `level' + mat colnames _PRVsav = xb stdp xb_lo xb_hi level + } + + } // end of tobit and regress + +// #13 BINARY OUTPUT + + if "`output'" == "binary" { + + sca `stdp' = peinfo[1,8] + sca `xb' = pepred[3,1] + sca `xb_lo' = `cilower'[3,1] + sca `xb_hi' = `ciupper'[3,1] + foreach c in 0 1 { + local c1 = `c' + 1 + sca `p`c'' = pepred[2,`c1'] + } + sca `p0_hi' = `ciupper'[2,1] + sca `p1_hi' = `ciupper'[2,2] + sca `p0_lo' = `cilower'[2,1] + sca `p1_lo' = `cilower'[2,2] + + return scalar xb = `xb' + return scalar xb_lo = `xb_lo' + return scalar xb_hi = `xb_hi' + return local level `level' + return scalar p0 = `p0' + return scalar p1 = `p1' + return scalar p0_hi = `p0_hi' + return scalar p0_lo = `p0_lo' + return scalar p1_hi = `p1_hi' + return scalar p1_lo = `p1_lo' + + if "`save'"=="save" { + mat _PRVsav = `xb', `stdp', `p1', `xb_lo', `xb_hi', `level' + mat colnames _PRVsav = xb stdp p1 xb_lo xb_hi level + } + +// #14 BINARY with ystar option + + if "`ystar'"=="ystar" { + + PRTyciH `c_lo' `level' 1 + PRTy 2 "Predicted y*" `yfmt' `c_cur' `xb' + PRTyci `yfmt' `c_lo' `level' `xb_lo' /// + `c_hi' `xb_hi' + + * 2008-06-15 r(pred) for ystar + matrix def `rpred' = J(1,4,.) + matrix rownames `rpred' = ystar + matrix colnames `rpred' = ystar LB UB Category + matrix `rpred'[1,1] = `xb' + matrix `rpred'[1,2] = `xb_lo' + matrix `rpred'[1,3] = `xb_hi' + + if "`diff'"=="diff" { + + sca `xb_dif' = pepred[7,1] + PRTy 9 "Saved" `yfmt' `c_cur' pepred[5,1] + PRTyci `yfmt' `c_lo' `level' _PRVsav[1,4] /// + `c_hi' _PRVsav[1,5] + PRTy 4 "Difference" `yfmt' `c_cur' `xb_dif' + PRTyci `yfmt' `c_lo' `level' `cilower'[7,1] /// + `c_hi' `ciupper'[7,1] + + * 2008-07-10 r(pred) for dif + matrix def `rpred' = J(1,4,.) + matrix rownames `rpred' = ystar + matrix colnames `rpred' = Dystar LB UB Category + matrix `rpred'[1,1] = `xb_dif' + matrix `rpred'[1,2] = `cilower'[7,1] + matrix `rpred'[1,3] = `ciupper'[7,1] + + } // diff + + } // binary ystar option + +// #15 BINARY - not ystar + + else { // binary: not ystar + + * labels for outcomes + if "`label'"!="nolabel" { + local p0lab : word 1 of `catnms8' + } + else { + local p0lab : word 1 of `catvals' + } + if "`label'"!="nolabel" { + local p1lab : word 2 of `catnms8' + } + else { + local p1lab : word 2 of `catvals' + } + + * 2008-06-15 r(pred) for probabilities + matrix def `rpred' = J(2,4,.) + matrix rownames `rpred' = `catnms' + matrix colnames `rpred' = Prob LB UB Category + matrix `rpred'[1,1] = `p0' + matrix `rpred'[1,2] = `p0_lo' + matrix `rpred'[1,3] = `p0_hi' + matrix `rpred'[1,4] = 0 + matrix `rpred'[2,1] = `p1' + matrix `rpred'[2,2] = `p1_lo' + matrix `rpred'[2,3] = `p1_hi' + matrix `rpred'[2,4] = 1 + + if "`diff'"=="diff" { + + sca `p1_prev' = pepred[4,2] + sca `p0_prev' = 1 - `p1_prev' + sca `p1_dif' = `p1' - `p1_prev' + sca `p0_dif' = `p0' - `p0_prev' + local p1diflo = `cilower'[6,2] + local p1difhi = `ciupper'[6,2] + local p0diflo = `cilower'[6,1] + local p0difhi = `ciupper'[6,1] + * 2.0.7 + PRTdH `c_curDH' `c_savDH' `c_difDH' $PRVlabsav $PRVlabcur + PRTdciH `c_lvlDH' `level' + foreach v in 1 0 { + PRTd 2 "Pr(y=`p`v'lab'|x)" `pfmt' `c_curD' `p`v'' /// + `c_savD' `p`v'_prev' `c_difD' `p`v'_dif' + PRTdci `pfmt' `c_loD' `p`v'diflo' /// + `c_hiD' `p`v'difhi' + } + + * 2008-07-10 r(pred) for dif + matrix def `rpred' = J(2,4,.) + matrix rownames `rpred' = `catnms' + matrix colnames `rpred' = DProb LB UB Category //! changed bj 22jul2008 + matrix `rpred'[1,1] = `p0_dif' + matrix `rpred'[1,2] = `p0diflo' + matrix `rpred'[1,3] = `p0difhi' + matrix `rpred'[1,4] = 0 + matrix `rpred'[2,1] = `p1_dif' + matrix `rpred'[2,2] = `p1diflo' + matrix `rpred'[2,3] = `p1difhi' + matrix `rpred'[2,4] = 1 + + } // binary dif in prob + + else { // binary - not difference + PRTyciH `c_lo' `level' 1 + foreach v in 1 0 { + PRTy 2 "Pr(y=`p`v'lab'|x)" `pfmt' `c_cur' `p`v'' + PRTyci `pfmt' `c_lo' `level' `p`v'_lo' /// + `c_hi' `p`v'_hi' + } + } // not difference + + } // not ystar + + } // binary + +// #16 ORDINAL OUTCOMES + + if "`output'" == "ordered" { + + *if "`brief'" == "brief" { di } + sca `xb' = pepred[3,1] + sca `xb_lo' = `cilower'[3,1] + sca `xb_hi' = `ciupper'[3,1] + sca `stdp' = peinfo[1,8] + return scalar xb = `xb' + return scalar xb_lo = `xb_lo' + return scalar xb_hi = `xb_hi' + return local level `level' + + * 2008-06-15 r(pred) for ystar + if "`ystar'"=="ystar" { + matrix def `rpred' = J(1,4,.) + matrix rownames `rpred' = ystar + matrix colnames `rpred' = ystar LB UB Category + matrix `rpred'[1,1] = `xb' + matrix `rpred'[1,2] = `xb_lo' + matrix `rpred'[1,3] = `xb_hi' + } + * 2008-06-15 r(pred) for prob + else { + matrix def `rpred' = J(`ncats',4,.) + matrix rownames `rpred' = `catnms' + matrix colnames `rpred' = Prob LB UB Category + } + + * cycle though categories get probabilities etc. + local i = 1 + if "`diff'" != "diff" { + PRTyciH `c_lo' `level' 1 + } + + while `i' <= `ncats' { + + * get labels + local p`i'val : word `i' of `catvals' + mat `values' = nullmat(`values') \ `p`i'val' + local p`i'lab : word `i' of `catnms8' + local labdisp "`p`i'val'" + if "`label'"!="nolabel" { + local labdisp "`p`i'lab'" + } + + * get probability + tempname p`i' + sca `p`i'' = pepred[2,`i'] + mat `probs' = nullmat(`probs') \ `p`i'' + + * not diff and prob + if "`ystar'"=="" & "`diff'"=="" { + PRTy 5 "Pr(y=`labdisp'|x)" `pfmt' `c_cur' `p`i'' + PRTyci `pfmt' `c_lo' `level' `cilower'[2,`i'] /// + `c_hi' `ciupper'[2,`i'] + } + + * 2008-06-15 r(pred) add prob + if "`ystar'"!="ystar" { + matrix `rpred'[`i',1] = `p`i'' + matrix `rpred'[`i',2] = `cilower'[2,`i'] + matrix `rpred'[`i',3] = `ciupper'[2,`i'] + matrix `rpred'[`i',4] = `p`i'val' + } + + * dif and prob + if "`ystar'"=="" & "`diff'"=="diff" { + if "`i'" == "1" { // header + PRTdH `c_curDH' `c_savDH' `c_difDH' + PRTdciH `c_lvlDH' `level' + } + PRTd 5 "Pr(y=`labdisp'|x)" `pfmt' `c_curD' `p`i'' /// + `c_savD' pepred[4,`i'] `c_difD' pepred[6,`i'] + PRTdci `pfmt' `c_loD' `cilower'[6,`i'] /// + `c_hiD' `ciupper'[6,`i'] + + * 2008-07-10 r(pred) for dif \\ ord and prob + matrix colnames `rpred' = DProb LB UB Category + matrix `rpred'[`i',1] = pepred[6,`i'] + matrix `rpred'[`i',2] = `cilower'[6,`i'] + matrix `rpred'[`i',3] = `ciupper'[6,`i'] + matrix `rpred'[`i',4] = `p`i'val' + + } + + local i = `i' + 1 + + } // looping over categories + + * save before return because return destroys matrices + if "`save'"=="save" { + mat _PRVsav = `xb', `stdp', `xb_lo', `xb_hi', `level' + mat colnames _PRVsav = xb stdp xb_lo xb_hi level + global PRVvals = "`catvals'" + mat _PRVp = `probs' + } + return matrix values `values' + return matrix probs `probs' + + * ystar, not prob + if "`ystar'"=="ystar" { + + if "`diff'"=="diff" { + PRTyciH `c_lo' `level' 1 + } + PRTy 5 "Predicted y*" `yfmt' `c_cur' `xb' + PRTyci `yfmt' `c_lo' `level' `xb_lo' /// + `c_hi' `xb_hi' + + if "`diff'"=="diff" { + + sca `xb_prev' = pepred[5,1] + PRTy 5 "Saved" `yfmt' `c_cur' `xb_prev' + PRTyci `yfmt' `c_lo' `level' _PRVsav[1,3] /// + `c_hi' _PRVsav[1,4] + PRTy 5 "Difference" `yfmt' `c_cur' `xb'-`xb_prev' + PRTyci `yfmt' `c_lo' `level' `cilower'[7,1] /// + `c_hi' `ciupper'[7,1] + + * 2008-07-10 r(pred) for dif + matrix def `rpred' = J(1,4,.) + matrix rownames `rpred' = ystar + matrix colnames `rpred' = Dystar LB UB Category + matrix `rpred'[1,1] = `xb'-`xb_prev' + matrix `rpred'[1,2] = `cilower'[7,1] + matrix `rpred'[1,3] = `ciupper'[7,1] + + } // diff for ystar + + } // end of ystar output + + } // ordinal + +// #17 NOMINAL OUTPUT + + if "`output'" == "mlogit" | "`output'" == "mprobit" | "`output'" == "slogit" { + + * 2008-06-15 r(pred) + matrix def `rpred' = J(`ncats',4,.) + matrix rownames `rpred' = `catnms' + matrix colnames `rpred' = Prob LB UB Category + + if "`diff'"=="diff" { + + * 2008-07-10 r(pred) for dif + matrix colnames `rpred' = DProb LB UB Category + PRTdH `c_curDH' `c_savDH' `c_difDH' + * 2.1.8 - no ci for mprobit - 2009-03-14 + if "`output'"!="slogit" & "`output'"!="mprobit" { // no ci for slogit or mprobit + PRTdciH `c_lvlDH' `level' + } + else { + di + } + } + else { + if "`output'"=="mlogit" { + PRTyciH `c_lo' `level' 1 + } + else { + di + } + } + + * cycle through each category + local i = 1 + while `i' <= `ncats' { + * get actual category value + local p`i'val : word `i' of `catvals' + mat `values' = nullmat(`values') \ `p`i'val' + *get label + local p`i'lab : word `i' of `catnms8' + local labdisp "`p`i'val'" + if "`label'"!="nolabel" { + local labdisp "`p`i'lab'" + } + * get probability computed by _pepred and stored in r() + tempname p`i' + sca `p`i'' = pepred[2,`i'] + mat `probs' = nullmat(`probs') \ `p`i'' + + if "`diff'"=="" { + PRTy 2 "Pr(y=`labdisp'|x)" `pfmt' `c_cur' `p`i'' + if "`output'"=="mlogit" { + PRTyci `pfmt' `c_lo' `level' `cilower'[2,`i'] /// + `c_hi' `ciupper'[2,`i'] + } + else { + di + } + + } // nominal: no diff + + * 2008-06-15 r(pred) add prob + matrix `rpred'[`i',1] = `p`i'' + matrix `rpred'[`i',2] = `cilower'[2,`i'] + matrix `rpred'[`i',3] = `ciupper'[2,`i'] + matrix `rpred'[`i',4] = `p`i'val' + + if "`diff'"=="diff" { + PRTd 2 "Pr(y=`labdisp'|x)" `pfmt' `c_curD' `p`i'' /// + `c_savD' pepred[4,`i'] `c_difD' pepred[6,`i'] + + * 2008-07-10 r(pred) for dif + matrix `rpred'[`i',1] = pepred[6,`i'] + matrix `rpred'[`i',4] = `p`i'val' + * 2.1.8 - no ci for mprobit - 2009-03-14 + if "`output'"!="slogit" & "`output'"!="mprobit" { // no ci for slogit or mprobit + PRTdci `pfmt' `c_loD' `cilower'[6,`i'] /// + `c_hiD' `ciupper'[6,`i'] + * 2008-07-10 r(pred) for dif + matrix `rpred'[`i',2] = `cilower'[6,`i'] + matrix `rpred'[`i',3] = `ciupper'[6,`i'] + } + else { + di + } + } // nominal - diff + + local i = `i' + 1 + } + + if "`save'"=="save" { + global PRVvals = "`catvals'" + mat _PRVp = `probs' + } + + return matrix values `values' + return matrix probs `probs' + + } // mlogit + +// #18 COUNT - nbreg and poisson + + if "`e(cmd)'"=="poisson" | "`e(cmd)'"=="nbreg" { + + sca `mu' = pepred[3,2] + sca `stdp' = peinfo[1,8] + tempname plo_dif phi_dif + sca `mu_lo' = `cilower'[3,2] + sca `mu_hi' = `ciupper'[3,2] + return local level `level' + return scalar mu = `mu' + return scalar mu_lo = `mu_lo' + return scalar mu_hi = `mu_hi' + return local level `level' + + * 2008-06-15 r(pred) for mu and probs + local npred = 1 + `max_i' + 1 + matrix def `rpred' = J(`npred',4,.) + local rnm "mu" + forvalues i = 0(1)`max_i' { + local rnm "`rnm' `i'" + } + matrix rownames `rpred' = `rnm' + matrix colnames `rpred' = Predict LB UB Category + matrix `rpred'[1,1] = `mu' + matrix `rpred'[1,2] = `mu_lo' + matrix `rpred'[1,3] = `mu_hi' + if "`diff'" != "diff" { + PRTyciH `c_lo' `level' 1 + PRTy 2 "Rate" `yfmt' `c_cur' `mu' + PRTyci `yfmt' `c_lo' `level' `mu_lo' /// + `c_hi' `mu_hi' + } // not diff + + if "`diff'"=="diff" { + PRTdH `c_curDH' `c_savDH' `c_difDH' + PRTdciH `c_lvlDH' `level' + sca `mu_prev' = _PRVsav[1,1] + sca `mu_dif' = `mu' - `mu_prev' + sca `mu_dif_hi' = `ciupper'[7,2] + sca `mu_dif_lo' = `cilower'[7,2] + PRTd 2 "Rate" `yfmt' `c_curD' `mu' /// + `c_savD' `mu_prev' `c_difD' `mu_dif' + PRTdci `pfmt' `c_loD' `mu_dif_lo' /// + `c_hiD' `mu_dif_hi' + + * 2008-07-10 r(pred) for dif + matrix rownames `rpred' = `rnm' + matrix colnames `rpred' = DPredict LB UB Category + matrix `rpred'[1,1] = `mu_dif' + matrix `rpred'[1,2] = `mu_dif_lo' + matrix `rpred'[1,3] = `mu_dif_hi' + + } // diff + + *cycle from 0 to maximum desired count + local i = 0 + local isodd = 0 + while `i' <= `max_i' { // loop through outcome values + + local isodd = abs(`isodd' - 1) + mat `values' = nullmat(`values') \ `i' + tempname p`i' p_lo`i' p_hi`i' lo hi + local i1 = `i' + 1 + sca `p`i'' = pepred[2,`i1'] + sca `p_hi`i'' = `ciupper'[2,`i1'] + sca `p_lo`i'' = `cilower'[2,`i1'] + + * 2008-06-15 r(pred) + local irow = `i' + 2 + matrix `rpred'[`irow',1] = `p`i'' + matrix `rpred'[`irow',2] = `p_lo`i'' + matrix `rpred'[`irow',3] = `p_hi`i'' + matrix `rpred'[`irow',4] = `i' + + mat `probs' = nullmat(`probs') \ `p`i'' + if "`diff'"=="" { + PRTy 2 "Pr(y=`i'|x)" `pfmt' `c_cur' `p`i'' + PRTyci `pfmt' `c_lo' `level' `p_lo`i'' /// + `c_hi' `p_hi`i'' + } + + else { // if differnece + sca `p_prev' = _PRVp[`i'+1, 1] + sca `p_dif' = `p`i''-`p_prev' + sca `p_prev' = pepred[4,`i'+1] + sca `p_dif' = pepred[6,`i'+1] + sca `plo_dif' = `cilower'[6,`i'+1] + sca `phi_dif' = `ciupper'[6,`i'+1] + PRTd 2 "Pr(y=`i'|x)" `pfmt' `c_curD' `p`i'' /// + `c_savD' `p_prev' `c_difD' `p_dif' + PRTdci `pfmt' `c_loD' `plo_dif' /// + `c_hiD' `phi_dif' + + * 2008-06-15 r(pred) + matrix `rpred'[`irow',1] = `p_dif'' + matrix `rpred'[`irow',2] = `plo_dif' + matrix `rpred'[`irow',3] = `phi_dif' + + } + + local i = `i' + 1 + } // loop through outcome values + + if "`save'"=="save" { + mat _PRVsav = `mu', `stdp' + mat colnames _PRVsav = mu stdp + mat _PRVp = `probs' + } + + return matrix values `values' + return matrix probs `probs' + + } // count output + +// #19 COUNT - zip and zinb + + if "`input'"=="twoeq" { + sca `mu' = pepred[3,2] // overall rate E(y) - 15Apr2005 + sca `mu_lo' = `cilower'[3,2] + sca `mu_hi' = `ciupper'[3,2] + return scalar mu = `mu' + * mu from count portion of zi models - 15Apr2005 + sca `mucount' = pepred[3,3] // rate in count portion of model E(y|~always0) + sca `mucount_lo' = `cilower'[3,3] // currently not computed + sca `mucount_hi' = `ciupper'[3,3] // currently not computed + sca `stdp' = peinfo[1,8] + return scalar mucount = `mucount' + return local level `level' + + * 2008-06-15 r(pred) for mu and probs + local npred = 2 + `max_i' + 1 + matrix def `rpred' = J(`npred',4,.) + + * 2008-07-10 + local rnm "Ey All0 0|xy" + forvalues i = 1(1)`max_i' { + local rnm "`rnm' `i'|x" + } + + matrix rownames `rpred' = `rnm' + matrix colnames `rpred' = Predict LB UB Category + matrix `rpred'[1,1] = `mu' + matrix `rpred'[1,2] = `mu_lo' + matrix `rpred'[1,3] = `mu_hi' + * 2008-07-10 matrix `rpred'[2,1] = `mucount' + + * relabel Rate to Expected y - 15Apr2005 + if "`diff'"!="diff" & "`bootstrap'"=="bootstrap" { // ci with boot + PRTyciH `c_lo' `level' 1 + PRTy 2 "Expected y" `yfmt' `c_cur' `mu' + PRTyci `yfmt' `c_lo' `level' `mu_lo' /// + `c_hi' `mu_hi' + } + else if "`diff'"!="diff" & "`bootstrap'"!="bootstrap" { + di + PRTy 2 "Expected y" `yfmt' `c_cur' `mu' + di + } + + * print E(y) + if "`diff'"=="diff" { + sca `mu_prev' = pepred[5,2] + sca `mu_dif' = pepred[7,2] + PRTdH `c_curDH' `c_savDH' `c_difDH' + + if "`brief'"=="brief" & "`bootstrap'"!="bootstrap" { + di + } + + if "`bootstrap'"=="bootstrap" { + *PRTdH `c_curDH' `c_savDH' `c_difDH' + PRTdciH `c_lvlDH' `level' + sca `mu_dif_hi' = `ciupper'[7,2] + sca `mu_dif_lo' = `cilower'[7,2] + PRTd 2 "Expected y" `yfmt' `c_curD' `mu' /// + `c_savD' `mu_prev' `c_difD' `mu_dif' + PRTdci `pfmt' `c_loD' `mu_dif_lo' /// + `c_hiD' `mu_dif_hi' + * 2008-07-10 r(pred) for dif + matrix `rpred'[1,2] = `mu_dif_lo' + matrix `rpred'[1,3] = `mu_dif_hi' + } + else { + di + PRTd 2 "Expected y" `pfmt' `c_curD' `mu' /// + `c_savD' `mu_prev' `c_difD' `mu_dif' + di + } + + * 2008-07-10 r(pred) for dif + matrix colnames `rpred' = DPredict LB UB Category + matrix `rpred'[1,1] = `mu_dif' + + } // dif for rate + + sca `all0' = pepred[3,4] + sca `all0_hi' = `ciupper'[3,4] + sca `all0_lo' = `cilower'[3,4] + + * 2008-07-10 r(pred) for dif + matrix `rpred'[2,1] = `all0' + matrix `rpred'[2,2] = `all0_lo' + matrix `rpred'[2,3] = `all0_hi' + + if "`diff'"=="diff" { + sca `all0_prev' = pepred[5,4] + sca `all0_dif' = pepred[7,4] + + * 2008-07-10 r(pred) for dif + matrix `rpred'[2,1] = `all0_dif' + + if "`bootstrap'"=="bootstrap" { + sca `all0_dif_hi' = `ciupper'[7,4] + sca `all0_dif_lo' = `cilower'[7,4] + PRTd 2 "Pr(Always0|z)" `pfmt' `c_curD' `all0' /// + `c_savD' `all0_prev' `c_difD' `all0_dif' + PRTdci `pfmt' `c_loD' `all0_dif_lo' /// + `c_hiD' `all0_dif_hi' + + * 2008-07-10 r(pred) for dif + matrix `rpred'[2,2] = `all0_dif_lo' + matrix `rpred'[2,3] = `all0_dif_hi' + + } + else { + PRTd 2 "Pr(Always0|z)" `pfmt' `c_curD' `all0' /// + `c_savD' `all0_prev' `c_difD' `all0_dif' + di + } + + * 2008-07-10 r(pred) for dif + matrix `rpred'[2,1] = `all0_dif' + + } + if "`diff'"!="diff" & "`bootstrap'"=="bootstrap" { + PRTy 2 "Pr(Always0|z)" `pfmt' `c_cur' `all0' + PRTyci `pfmt' `c_lo' `level' `all0_lo' /// + `c_hi' `all0_hi' + } + else if "`diff'"!="diff" { // default, no ci + PRTy 2 "Pr(Always0|z)" `pfmt' `c_cur' `all0' + di + } + return scalar always0 = `all0' + + * loop from count 0 to maxcount + local i = 0 + local isodd = 0 + while `i' <= `max_i' { + local given "x" + if "`i'" == "0" { + local given "x,z" + } + mat `values' = nullmat(`values') \ `i' + tempname p`i' p_lo`i' p_hi`i' lo hi + local i1 = `i' + 1 + sca `p`i'' = pepred[2,`i1'] + mat `probs' = nullmat(`probs') \ `p`i'' + + * 2008-06-15 r(pred) + local irow = `i' + 3 + matrix `rpred'[`irow',1] = `p`i'' + matrix `rpred'[`irow',4] = `i' + + if "`diff'"=="" { + PRTy 2 "Pr(y=`i'|`given')" `pfmt' `c_cur' `p`i'' + if "`cimethod'"=="bootstrap" { + PRTyci `pfmt' `c_lo' `level' `cilower'[2,`i1'] /// + `c_hi' `ciupper'[2,`i1'] + } + else { + di + } + } + else { // if differnece + sca `p_prev' = _PRVp[`i'+1, 1] + sca `p_dif' = `p`i''-`p_prev' + sca `p_prev' = pepred[4,`i'+1] + sca `p_dif' = pepred[6,`i'+1] + PRTd 2 "Pr(y=`i'|`given')" `pfmt' `c_curD' `p`i'' /// + `c_savD' `p_prev' `c_difD' `p_dif' + + * 2008-07-10 r(pred) for dif + matrix `rpred'[`irow',1] = `p_dif'' + + if "`cimethod'"=="bootstrap" { + PRTdci `pfmt' `c_loD' `cilower'[6,`i'+1] /// + `c_hiD' `ciupper'[6,`i'+1] + + * 2008-07-10 r(pred) for dif + matrix `rpred'[`irow',2] = `cilower'[6,`i'+1] + matrix `rpred'[`irow',2] = `ciupper'[6,`i'+1] + + } + else { + di + } + } + local i = `i' + 1 + } + if "`save'"=="save" { + mat _PRVsav = `mu', `stdp' + mat colnames _PRVsav = mu stdp + mat _PRVsav = `mu', `stdp', `all0' + mat colnames _PRVsav = mu stdp all0 + mat _PRVp = `probs' + } + + return matrix values `values' + return matrix probs `probs' + + } // count zip and zinb + +// #20 COUNT - ztp and ztnb * 18Feb2005 + + if "`e(cmd)'"=="ztp" | "`e(cmd)'"=="ztnb" { + + sca `mu' = pepred[3,2] + return scalar mu = `mu' + sca `Cmu' = peCpred[3,2] + return scalar Cmu = `Cmu' + tempname plo_dif phi_dif + return local level `level' + + * 2008-06-15 r(pred) for mu and probs + local npred = 2 + `max_i' + matrix def `rpred' = J(`npred',5,.) + local rnm "mu 0" // changed bj 24jul2008 + forvalues i = 1(1)`max_i' { + local rnm "`rnm' `i'" + } + matrix rownames `rpred' = `rnm' + matrix colnames `rpred' = Ucond LB UB Category Cond + matrix `rpred'[1,1] = `mu' + matrix `rpred'[1,5] = `Cmu' + + if "`diff'" != "diff" { + local C_cur = `c_cur' + 9 + di _n _col(`c_cur') in g " Uncond Cond" + PRTy 2 "Rate" `yfmt' `c_cur' `mu' + di _col(`C_cur') `yfmt' `Cmu' + } // not diff + + if "`diff'"=="diff" { + sca `mu_prev' = pepred[5,2] + sca `mu_dif' = pepred[7,2] + sca `Cmu_prev' = peCpred[5,2] + sca `Cmu_dif' = peCpred[7,2] + di + di in g /// + " Unconditional: Conditional:" + di in g /// + " Current Saved Change Current Saved Change " + di in g /// + " Rate:" _col(19) in y `yfmt' `mu' _col(30) `yfmt' `mu_prev' _col(40) `yfmt' `mu_dif' _cont + di _col(51) /// + `yfmt' `Cmu' _col(61) `yfmt' `Cmu_prev' _col(71) `yfmt' `Cmu_dif' + + * 2008-07-10 r(pred) for dif + matrix `rpred'[1,1] = `mu_dif' + matrix `rpred'[1,5] = `Cmu_dif' + + } // diff + *cycle from 0 to maximum desired count + local i = 0 + local isodd = 0 + while `i' <= `max_i' { // loop through outcome values + local isodd = abs(`isodd' - 1) + mat `values' = nullmat(`values') \ `i' + tempname p`i' Cp`i' + local i1 = `i' + 1 + sca `p`i'' = pepred[2,`i1'] + sca `Cp`i'' = peCpred[2,`i1'] + mat `probs' = nullmat(`probs') \ `p`i'' + mat `Cprobs' = nullmat(`Cprobs') \ `Cp`i'' + + * 2008-06-15 r(pred) + local irow = `i' + 2 + matrix `rpred'[`irow',1] = `p`i'' + matrix `rpred'[`irow',5] = `Cp`i'' + matrix `rpred'[`irow',4] = `i' + + if "`diff'"=="" { + PRTy 2 "Pr(y=`i'|x)" `pfmt' `c_cur' `p`i'' + di _col(`C_cur') `pfmt' `Cp`i'' + } + else { // if differnece + sca `p_prev' = pepred[4,`i'+1] + sca `p_dif' = pepred[6,`i'+1] + sca `Cp_prev' = peCpred[4,`i'+1] + sca `Cp_dif' = peCpred[6,`i'+1] + di in g " Pr(y=`i'|x)" in y /// + _col(19) `pfmt' `p`i'' _col(30) `pfmt' `p_prev' /// + _col(40) `pfmt' `p_dif' _cont + di _col(51) `pfmt' `Cp`i'' _col(61) `pfmt' `Cp_prev' /// + _col(71) `pfmt' `Cp_dif' + + * 2008-07-10 r(pred) for dif + local irow = `i' + 2 + matrix `rpred'[`irow',1] = `p_dif' + matrix `rpred'[`irow',5] = `Cp_dif' + matrix `rpred'[`irow',4] = `i' + + } + local i = `i' + 1 + + } // loop through outcome values + return matrix values `values' + return matrix probs `probs' + return matrix Cprobs `Cprobs' + + } // ztp and ztnb + + +//21 OUTPUT COMMON TO ALL MODELS + + * print base values + * 2009-03-17 if "`brief'"=="" & "`base'"!="nobase" { + if "`base'"!="nobase" { + + * 2009-03-17 + if "`input'"=="twoeq" & "`brief'"=="" { + di _n in g "x values for count equation" + } + mat rownames `tobase' = "x=" + if "`diff'"=="" { + mat _PEtemp = `tobase' + _peabbv _PEtemp + * 2009-03-17 + if "`brief'"=="" { + mat list _PEtemp, noheader + } + } + else { + local tmp1: colnames `tobase' + local tmp2: colnames PRVbase + * 2009-05-10 if "`tmp1'"=="`tmp2'" & length("`tmp1'") < 80 { + * if "`tmp1'"=="`tmp2'" & length("`tmp1'") < 244 { // 2.5.1 2010-01-07 + *if "`tmp1'"=="`tmp2'" { // 2.5.3 2010-03-25 experimental +if `: list local(tmp1) == local(tmp2) ' { + mat _PEtemp = (`tobase' \ PRVbase \ (`tobase' - PRVbase)) + mat rownames _PEtemp = "Current=" "Saved=" "Diff=" + _peabbv _PEtemp + * 2009-03-17 + if "`brief'"=="" { + mat list _PEtemp, noheader + } + } + else { + mat rownames `tobase' = "Current=" + mat rownames PRVbase = " Saved=" + mat _PEtemp = `tobase' + _peabbv _PEtemp + * 2009-03-17 + if "`brief'"=="" { + mat list _PEtemp, noheader + } + mat _PEtemp = PRVbase + _peabbv _PEtemp + * 2009-03-17 + if "`brief'"=="" { + mat list _PEtemp, noheader + } + } + } + + * print base values of binary equation + if "`input'"=="twoeq" { + * 2009-03-17 + if "`brief'"=="" { + di _n in g "z values for binary equation" + mat rownames `tobase2' = "z=" + } + if "`diff'"=="" { + * 2009-03-15 + mat _PEtemp2 = `tobase2' + _peabbv _PEtemp2 + * 2009-03-17 + if "`brief'"=="" { + mat list _PEtemp2, noheader + } + } + else { + local tmp1: colnames `tobase2' + local tmp2: colnames PRVbase2 + + * 2.5.0: if "`tmp1'"=="`tmp2'" & length("`tmp1'") < 80 { + * string comparisons are only valid for certain lengths + *if "`tmp1'"=="`tmp2'" & length("`tmp1'") < 244 { // 2.5.1 2010-01-07 + *if "`tmp1'"=="`tmp2'" { // 2.5.3 2010-03-25 experimental +if `: list local(tmp1) == local(tmp2) ' { + + mat `temp' = (`tobase2' \ PRVbase2 \ (`tobase2' - PRVbase2)) + mat rownames `temp' = "Current=" "Saved=" "Diff=" + * 2009-03-15 + mat _PEtemp2 = `temp' + _peabbv _PEtemp2 + * 2009-03-17 + if "`brief'"=="" { + mat list _PEtemp2, noheader + } + } + else { + mat rownames `tobase2' = "Current=" + mat rownames PRVbase2 = " Saved=" + * 2009-03-15 + mat _PEtemp2 = `tobase2' + _peabbv _PEtemp2 + * 2009-03-17 + if "`brief'"=="" { + mat list _PEtemp2, noheader + } + mat _PEtemp2 = PRVbase2 + _peabbv _PEtemp2 + * 2009-03-17 + if "`brief'"=="" { + mat list _PEtemp2, noheader + } + } + } + } /* twoeq */ + } + + if "`save'"=="save" { + + // With the "save" option, the results of the current model + // are placed in globals to be used with a later prvalue, diff + + * save information needed for later -prvalue, diff- + global PRVcmd = "`e(cmd)'" // command name + global PRVdepv = "`e(depvar)'" // dependent variable + mat PRVbase = `tobase' // base values + mat rownames PRVbase = "saved=" + if "`input'"=="twoeq" { + mat PRVbase2 = `tobase2' + mat rownames PRVbase2 = "saved x" + } + mat PRVprob = pepred[2,1...] // probabilities + mat rownames PRVprob = "saved=" + mat PRVmisc = pepred[3,1...] // other predictions + mat rownames PRVmisc = "saved=" + mat PRVupper = peupper[2..3,1...] // for pr and misc + mat PRVlower = pelower[2..3,1...] // + mat PRVinfo = peinfo[1,1...] // information on saved model + mat rownames PRVinfo = "saved=" + if ("`e(cmd)'"=="ztp" | "`e(cmd)'"=="ztnb") { + mat PRVCpred = peCpred[2,1...] + mat rownames PRVCpred = "saved=" + mat PRVCmisc = peCpred[3,1...] + mat rownames PRVCmisc = "saved=" + } + + } // if save + + * 2009-03-15 return r(x) as dif in X if diff + if "`diff'"!="diff" { + return mat x `tobase' + if "`input'"=="twoeq" { + return mat x2 `tobase2' + } + } + +*mat list _PEtemp +*mat list _PEtemp2 + + if "`diff'"=="diff" { + tempname difx + * 2009-05-10 + mat `difx' = _PEtemp[3,1...] + mat rownames `difx' = "DiffX" + return mat x `difx' + if "`input'"=="twoeq" { + mat `difx' = _PEtemp2[3,1...] + mat rownames `difx' = "DiffX" + return mat x2 `difx' + } + } + + * 2008-07-10 return pred with SE and Zscore + tempname Xz Xs + * if ystar or count, need to reconstruct se for difference + if "`ystar'"=="ystar" { // | "`output'"=="count" { + * hold SE of pred and z value + matrix `Xz' = J(1,2,.) + matrix colnames `Xz' = SE z + * if not diff, use peinfo + local se = peinfo[1,8] + if "`diff'"=="diff" { + local se = $pedifsey + } + matrix `Xz'[1,1] = `se' + matrix `Xz'[1,2] = `rpred'[1,1]/`se' + } + * for probabilities + else { + local Npred = rowsof(`rpred') + * hold SE of pred and z value + matrix `Xz' = J(`Npred',2,.) + matrix colnames `Xz' = SE z + * grab standard errors + capture mat `Xs' = pedifsep + * if not computed, dummy up matrix + if _rc!=0 { + matrix `Xs' = J(`Npred',1,.) + } + local j = 0 + if "`output'"=="count" { + local j = 1 + if "`diff'"!="diff" { + matrix `Xz'[1,1] = $pesemu + } + else { + matrix `Xz'[1,1] = $pedifsemu + } + matrix `Xz'[1,2] = `rpred'[1,1]/`Xz'[1,1] + } + * loop through predictions and compute z's + local en = `Npred' - `j' + forvalues i = 1(1)`en' { + local i2 = `i' + `j' + local z = `rpred'[`i2',1]/`Xs'[`i',1] + matrix `Xz'[`i2',1] = `Xs'[`i',1] + matrix `Xz'[`i2',2] = `z' + } + } + + * add se and z to matrix + if "`e(cmd)'"=="ztp" | "`e(cmd)'"=="ztnb" { + * only ztp and ztnb have cond and uncond, so stick cond at end + matrix `rpred' = `rpred'[1...,1..4],`Xz',`rpred'[1...,5] + } + else { + matrix `rpred' = `rpred',`Xz' + } + return mat pred `rpred' + capture drop pedifsep + capture drop pedifsey + capture drop _PEtemp + * 2009-03-15 + capture matrix drop _PEtemp + capture matrix drop _PEtemp2 + +end // prvalue + +// +//22 PRINT ROUTINES +// + +// PRTy: value w/o ci +// PRTy skip label fmt c_cur value + +capture program drop PRTy +program PRTy + version 8 + args skip label fmt c_cur value + di in g _skip(`skip') "`label':" /// + in y `fmt' _col(`c_cur') `value' _continue +end + +// PRTyciH: header for ci in difference +// PRTyciH c_lvl level addline + +capture program drop PRTyciH +program PRTyciH + version 8 + args c_lvl level addline + if `addline' == 1 { + di + } + di _col(`c_lvl') in g " `level'% Conf. Interval" +end + +// PRTyci: ci after value +// PRTyci fmt c_lo level value_lo c_hi value_hi +// c_lo column for low; c_hi column for hi + +capture program drop PRTyci +program PRTyci + version 8 + args fmt c_lo level value_lo c_hi value_hi + di _col(`c_lo') in g "[" /// + in y `fmt' `value_lo' in g "," /// + in y `fmt' _col(`c_hi') `value_hi' in g "]" +end + +/* this version puts 90% on each line +program PRTyci + version 8 + args fmt c_lo level value_lo c_hi value_hi + di _col(`c_lo') in g "`level'% CI (" /// + in y `fmt' `value_lo' in g "," /// + in y `fmt' _col(`c_hi') `value_hi' in g ")" +end +*/ + +// PRTdH: header for difference +// PRTdH c_cur c_sav c_dif + +capture program drop PRTdH +program PRTdH + version 8 + *args c_cur c_sav c_dif + * 2.0.7 + args c_cur c_sav c_dif nmsave nmcurrent + di + * 2.0.6 + if "`nmsave'"!="" | "`nmcurrent'"!="" { + * 2.0.7 + local lcur : length local nmcurrent + local lcur = `c_cur' + 7 - `lcur' + local lsav : length local nmsave + local lsav = `c_sav' + 5 - `lsav' + di _col(`lcur') in g "`nmcurrent'" /// + _col(`lsav') in g "`nmsave'" + } // 2.0.7 + di _col(`c_cur') in g "Current" /// + _col(`c_sav') in g "Saved" /// + _col(`c_dif') in g "Change" _continue +end + +// PRTdciH: header for ci in difference +// PRTdciH c_lvl level + +capture program drop PRTdciH +program PRTdciH + version 8 + args c_lvl level + di _col(`c_lvl') in g "`level'% CI for Change" +end + +// PRTd: print difference +// PRTd skip label fmt c_cur v_cur c_sav v_sav c_dif v_dif + +capture program drop PRTd +program PRTd + version 8 + args skip label fmt c_cur v_cur c_sav v_sav c_dif v_dif + di _skip(`skip') in g "`label':" /// + in y `fmt' _col(`c_cur') `v_cur' /// + in y `fmt' _col(`c_sav') `v_sav' /// + in y `fmt' _col(`c_dif') `v_dif' _continue +end + +// PRTdci: print difference +// PRTdci fmt c_lo v_lo c_hi v_lo + +capture program drop PRTdci +program PRTdci + version 8 + args fmt c_lo v_lo c_hi v_hi + di in g _col(`c_lo') "[" /// + in y `fmt' `v_lo' in g "," /// + in y `fmt' _col(`c_hi') `v_hi' in g "]" +end +exit + +15Apr2005 - correct error for zip and zinb + : see changes in _pepred, _pecollect, _peciboot + : E(y) was used incorrectly rather than E(y|~always0). + + _pepred[3|5|7, 2] used to be mu defined as rate in + count portion of model E(y|not always 0) + + _pepred[3|5|7, 2] now is the overall rate E(y); listed as simply mu. + + _pepred[3|5|7, 3] rate in count portion of model E(y|not always 0); + listed as mucount. + + To simplify changes in _peciboot, E(y) is referred to as mu; + E(y|~always0) is mucount. + +* version 0.2.2b 050218 jf slogit +* version 2.0.0 07Apr2005 +* version 2.0.1 12Apr2005 fix save dif for slogit; no ci in slogit dif +* version 2.0.2 13Apr2005 +* version 2.0.3 15Apr2005 fix rate used for zip/zinb (see notes at end) +* version 2.0.4 15Apr2005 fix label for Always 0 +* version 2.0.5 24May2006 - fix base values when multiple diffs +* version 2.1.0 2007-03-04 - add labels() & save-dif improvement +* version 2.1.1 2008-06-15 +* - add returns in r() +* version 2.1.2 2008-07-09 r(pred) for dif +* - returns if diff +* version 2.1.3 2008-07-09 +* - return predSE -- standard error +* version 2.1.4 2008-07-10 +* - fix se for ystar +* version 2.1.6 2008-10-23 +* - change bootstrapped to bootstrap +* version 2.1.5bj bj 22jul2008 for use with esttab +* version 2.1.5 2008-07-11 +* - fix typo in tempname +* version 2.1.7 2009-03-14 +* - merge 2.1.6 with changes for estout +* version 2.1.8 2009-03-14 +* - mprobit does not compute CI +* version 2.1.9 2009-03-15 +* - dif returns difference of X's +* version 2.2.0 2009-03-17 +* - fixed bug with brief after diff caused by 2.1.9 +* - estout needed information saved when brief was off, so +* only block printing in option is brief +* version 2.2.1 2009-05-10 +* - remove if "`tmp1'"=="`tmp2'" & length("`tmp1'") < 80 { +* version 2.2.2 - as of 2009-09-18 +* - fix for mlogit under stata 11 +* version 2.5.0 2009-10-28 jsl +* - stata 11 update for returns from -mlogit- +* version 2.5.1 2010-01-07 jsl +* - change limit on long var lists to 244 from 80 +* version 2.5.2 2010-01-15 jsl +* change x_peciboot to _peciboot +* version 2.5.3 2010-03-25 -- never posted +* explore removing length restrictions diff --git a/Modules/ado/plus/p/prvalue.hlp b/Modules/ado/plus/p/prvalue.hlp new file mode 100644 index 0000000..d50ee1c --- /dev/null +++ b/Modules/ado/plus/p/prvalue.hlp @@ -0,0 +1,238 @@ +{smcl} +{* 17Feb2007}{...} +{hline} +help for {hi:prvalue}{right:17Feb2007} +{hline} + +{title:Predicted values with confidence intervals for regression models} + +{p 8 15 2}{cmd:prvalue} [{cmd:if} exp] [{cmd:in} range] [{cmd:,} +{cmd:x(}{it:variables_and_values}{cmd:)} +{cmdab:r:est(}{it:stat}{cmd:)} +{cmd:all} +{cmdab:l:evel(}{it:#}{cmd:)} +{cmdab:s:ave} +{cmdab:d:iff} +{cmdab:lab:el(}{it:string}{cmd:)} +{cmdab:b:rief} +{cmdab:max:cnt(}{it:#}{cmd:)} +{cmdab:noba:se} +{cmdab:nola:bel} +{cmdab:ys:tar} +{cmd:ept} +{cmdab:del:ta} +{cmdab:boot:strap} +{cmdab:rep:s(}{it:#}{cmd:)} +{cmdab:si:ze(}{it:#}{cmd:)} +{cmdab:bias:corrected}|{cmdab:percent:ile}|{cmdab:norm:al} +{cmd:match} +{cmdab:do:ts} +{cmdab:sa:ving(}{it:filename, save_options}{cmd:)}] + +{p 4 4 2} +where {it:variables_and_values} is an alternating list of variables +and either numeric values or mean, median, min, max, upper, lower, +previous. + +{p 4 4 2} +{it:stat} is either mean, median, min, max, upper, lower, +previous, grmean(group mean), mrmedian, grmin, grmax. + + +{title:Description} + +{p 4 4 2} +After estimating a regression model, {cmd:prvalue} computes the +predicted values at specific values of the independent variables. +Depending on the model and the options chosen, predicted values can +be estimated values of y, y*, probabilities for each outcome, or expected rate. +By default, the predictions are calculated holding all other variables +at their mean. Values for specific independent variables can be set +using the x() option after {cmd:prvalue}. For example, to compute +predicted values when educ is 10 and age is 30, type {cmd:prvalue, x(educ=10 age=30)}. +Values for the unspecified independent variables can be set using the rest() +option, e.g., {cmd:prvalue, x(educ=10 age=30) rest(mean)}. Changes in +predictions as values of the independent variables change can be +computed using the {cmd:save} and {cmd:diff} options. The {cmd:if} +and {cmd:in} conditions specify conditions for computation of means, +min, etc., that are used with rest(). The command works with {help cloglog}, +{help cnreg}, {help fit}, {help gologit}, {help intreg}, {help logistic}, +{help logit}, {help mlogit}, {help nbreg}, {help ologit}, {help oprobit}, +{help poisson}, {help probit}, {help regress}, {help rologit}, {help slogit}, {help tobit}, {help zinb}, +{help ztnb}, and {help ztp}. Standard maximum likelihood based confidence intervals +are computed for cnreg, fit, intreg, regress, and tobit. All other models for which +confidence intervals are available use delta method as default except for {help zinb} and {help zip}. +Confidence intervals for {help zinb} and {help zip} can only use bootstrap method. + +{title:Options} + +{p 4 8 2} +{cmd:save} saves current values of indepenent variables and predictions +for computing changes using the diff option. + +{p 4 8 2} +{cmd:diff} computes difference between current predictions and those +that were saved. + +{p 4 8 2} +{cmd:label()} adds a label for the prvalue associated with a given +{cmd:save} or {cmd:diff}. Labels are shown when using {cmd:prvalue, diff}. + +{p 4 8 2} +{cmd:level()} sets the {help level} of the confidence interval for predicted +values or probabilities for the commands for which these are provided. The +default is 95. + +{p 4 8 2} +{cmd:maxcnt()} is the maximum count value for which the probability +is computed in count models. Default is 9. + +{p 4 8 2} +{cmd:x()} sets the values of independent variables for calculating +predicted values. The list must alternate variable names and values. +The values may be either numeric values or can be mean, median, min, +max, previous, upper, or lower. The latter cannot be used if rest() +specifies a group summary statistic (e.g., grmean). + +{p 4 8 2} +{cmd:rest()} sets the independent variables not specified in x() +to their {cmd:mean} (default), {cmd:minimum}, {cmd:maximum}, {cmd:median} +when calculating predicted values. {cmd:grmean} sets these independent +variables to the mean conditional on the variables and values specified +in x(); {cmd:grmedian},{cmd:grmax}, and {cmd:grmin} can also be used. +If {cmd:prvalue} has already been run after the last estimate, +{cmd:previous} will set unspecified variables to their prior values. +For models other than mlogit, {cmd:upper} and {cmd:lower} can be used +to set independent variables to their minimum or maximum depending +on which will yield the upper or lower extreme predicted value. + +{p 4 8 2} +{cmd:all} specifies that any calculations of means, medians, etc., +should use the entire sample instead of the sample used to estimate +the model. + +{p 4 8 2} +{cmd:nolabel} uses values rather than value labels in output. + +{p 4 8 2} +{cmd:nobase} suppresses inclusion of the base values of x in the output. + +{p 4 8 2} +{cmd:brief} prints only limited output. + +{p 4 8 2} +{cmd:ystar} prints the predicted values and maximum likelihood based +confidence intervals of ystar for binary, ordinal, ols regression, +or tobit models. + +{p 4 8 2} +{cmd:ept} computes confidence intervals for predicted probabilities +for cloglog, logit, and probit by endpoint transformation. +This method cannot be used for changes in predictions. + +{p 4 8 2} +{cmd:delta} calculates confidence intervals by the delta method +using analytical derivatives. This method works with cloglog, logistic, +logit, probit, ologit, oprobit, gologit, poisson, and nbreg. + +{p 4 8 2} +{cmd:bootstrap} computes confidence intervals using the bootstrap +method. This method takes roughly 1,000 times longer to compute than +other methods. This method works with cloglog, logistic, logit, mlogit, +probit, ologit, oprobit, gologit, poisson, nbreg, zip, and zinb. + +{p 4 8 2} +{cmd:dots} is used with bootstrap to write a . at the beginning of +each replication and periodically prints the percent of total +replications that have been completed. If computations appears to +be stuck (i.e., new dots do not appear), it is likely that the +estimation is not converging for the current bootstrap sample. +This is to be most common with zip, zinb and gologit. +When this happens, you can click on the break symbol to stop +computations for the current sample or wait until the maximum +number of iterations have been computed (by default, the maximum +number of iterations is 16,000). When a model does not converge +for a given bootstrap sample, that sample is dropped. + +{p 4 8 2} +{cmd:match} specifies that the bootstrap will resample within +each category of the dependent variable in proportion to the +distribution of the outcome categories in the estimation sample. +If match is not specified, the proportions in each category of +the bootstrap sample are determined entirely by the random draw +and it is possible to end up with samples in which no cases are +found in some of the categories. This option does not apply to +regression or count models (cnreg, intreg, nbreg, poisson, regress, +tobit, zinb, and zip). Usually, bootstrapped confidence intervals +using match option tend to be smaller than those without. + +{p 4 8 2} +{cmd:percentile} computes the bootstrapped confidence interval using +the percentile method. This is the default method for bootstrap. + +{p 4 8 2} +{cmd:biascorrected} computes the bootstrapped confidence interval +using the bias-corrected method. + +{p 4 8 2} +{cmd:normal} computes the bootstrapped confidence interval using +the normal approximation method. + +{p 4 8 2} +{cmd:saving()} creates a Stata data file (.dta file) containing +the bootstrap distribution for predictions (predicted probabilities +and expected rates) and discrete changes in discrete choice models +that {cmd:prvalue} applies to. + + +{title:Examples} + +{p 4 4 2} +To compute the predicted values and confidence intervals using delta method +for an ordered logit in which all independent variables are held at the mean. + +{p 4 8 2}{cmd:.oprobit warm yr89 male white age ed prst} + +{p 4 8 2}{cmd:.prvalue, delta} + +{p 4 4 2}To compute predicted values and confidence intervals using +bootstrap method where all independent variables are held at their +minimum + +{p 4 8 2}{cmd:.prvalue, rest(minimum) boot} + +{p 4 4 2} +To compute values for white females, holding all other variables +at their median with default delta method for confidence intervals. + +{p 4 8 2}{cmd:.prvalue, x(white=1 male=0) rest(median)} + +{p 4 4 2} +To compute values for white females, holding all other variables at +the median for white females with default delta method for confidence +intervals.: + +{p 4 8 2}{cmd:.prvalue, x(white=1 male=0) rest(grmedian)} + +{p 4 4 2} +To compute values at the minimum of education, holding all other +variables to the mean with default delta method for confidence intervals.: + +{p 4 8 2}{cmd:.prvalue, x(ed=min)} + +{p 4 4 2} +To compare the predicted values and compute confidence intervals of discrete +changes for males and females using delta method: + +{p 4 8 2}{cmd:.prvalue, x(male=0) save delta} + +{p 4 8 2} + ::: + +{p 4 8 2}{cmd:.prvalue, x(male=1) dif delta} + +{hline} + +{p 2 4 2}Authors: J. Scott Long & Jun Xu{p_end} +{p 11 4 2}{browse www.indiana.edu/~jslsoc/spost.htm}{p_end} +{p 11 4 2}spostsup@indiana.edu{p_end} diff --git a/Modules/ado/plus/p/prwhich.ado b/Modules/ado/plus/p/prwhich.ado new file mode 100644 index 0000000..b1a8a5b --- /dev/null +++ b/Modules/ado/plus/p/prwhich.ado @@ -0,0 +1,64 @@ +*! version 2.5.0 2009-10-28 jsl + +// list versions of spost ado files being used + +capture program drop prwhich +program define prwhich, rclass + version 8 +di +di in w /// +"== spost versions as of $S_TIME =========================================" +di +which _get_mlogit_bv +which _get_mlogit_bvecv +which _peabbv +which _pebase +which _pecats +which _peciboot +which _pecidelta +which _peciml +which _pecmdcheck +which _pecollect +which _pedum +which _peife +which _pemarg +which _penocon +which _pepred +which _perhs +which _pesum +which _petrap +which _peunvec +which _pexstring +which asprvalue +which brant +which case2alt +which countfit +which fitstat +which leastlikely +which listcoef +which misschk +which mlogplot +which mlogtest +which mlogview +which mvtab1 +which nmlab +which praccum +which prchange +which prcounts +which prdc +which prgen +which prtab +which prvalue +which prwhich +which spex +which spostupdate +which vardesc +which xpost + +di +di in w /// +"========================================= spost versions as of $S_TIME ==" + +end +exit +* version 1.0.3 13Apr2005 diff --git a/Modules/ado/plus/r/remcor.ado b/Modules/ado/plus/r/remcor.ado new file mode 100644 index 0000000..4c02feb --- /dev/null +++ b/Modules/ado/plus/r/remcor.ado @@ -0,0 +1,405 @@ +*! version 2.0.3 SRH 1 June 2003 +program define remcor + version 6.0 + * takes b and transform set of r.effs at same level using choleski + * returns bi where the r.effs are independent and correlation equations + * have been removed + * also takes exponential of sd parameters + * and evaluates contributions to linear predictor that don't change + args b stop + + tempname b2 s1 cov t r d dd u denom mean mzps + tempvar junk + gen double `junk'=0 + global HG_error=0 + + disp "*********in remcor:" + + /* fixed effects $HG_xb1, $HG_xb2 etc. (tempnames stored in global macros-list) */ + qui disp "fixed parameters: " + qui matrix list `b' + if $HG_const==1{ + matrix `b2' = `b'*M_T' + M_a + matrix coleq `b2' = $HG_cole + matrix colnames `b2' = $HG_coln + noi matrix list `b2' + } + else{ + matrix `b2' = `b' + } + local nffold=0 + local ff = 1 + local nxt = 1 + while(`ff' <= $HG_tpff){ + matrix `b2' = `b2'[1, `nxt'...] + local np = M_nffc[1, `ff'] - `nffold' + qui disp "np = " `np' + if `np'>0{ + local nxt = `np' + 1 + local nffold = M_nffc[1,`ff'] + matrix `s1' = `b2'[1,1..`np'] + qui matrix list `s1' + qui disp "tempname: ${HG_xb`ff'}" + matrix score double ${HG_xb`ff'} = `s1' /* nontemp */ + } + else{ + qui gen double ${HG_xb`ff'} = 0 + } + qui disp ${HG_xb`ff'}[$which] + local ff=`ff'+1 + } + if "$HG_off"~=""{qui replace $HG_xb1=$HG_xb1+$HG_off} + qui disp "HG_xb1 = " $HG_xb1[$which] + + if $HG_ethr{ + local j = 1 + local ii = 1 + while `ii'<=$HG_nolog{ + local j = `j' + 1 + local jm = `j' + M_nresp[1,`ii']-3 + while `j' <= `jm'{ + local jp = `j' + 1 + * disp in re "replace HG_xb`jp' = HG_xb`j' + exp(HG_xb`jp')" + qui replace ${HG_xb`jp'} = ${HG_xb`j'} + exp(${HG_xb`jp'}) + local j = `j' + 1 + } + local ii = `ii' + 1 + } + + } + + /* random effects */ +/* level 1 */ + local np = M_nbrf[1,1] + if `np'>0{ + matrix `b2' = `b2'[1, `nxt'...] + local nxt = 1 + matrix `s1' = `b2'[1,1..`np'] + qui matrix list `s1' + matrix score double $HG_s1 = `s1' + if $HG_nats{ + qui replace $HG_s1 = abs($HG_s1) + } + else{ + qui replace $HG_s1=exp($HG_s1) + } + qui disp "s1 = $HG_s1 = " $HG_s1[$which] + local nxt = `nxt' + `np' + } + local lev = 2 + local rf = 2 + local nrfold = M_nrfc[2,1] + +/* MASS POINTS */ +if($HG_free){ + tempname pdenom + gen double `pdenom' = 1.0 + while(`lev'<=$HG_tplv&`rf'<=$HG_tprf){ + local j1 = M_nrfc[2, `lev'] + local nrf = `j1' - `nrfold' + local nip = M_nip[1, `lev'] + scalar `denom' = 1 /* =exp(0) */ + qui replace `pdenom' = 1.0 + matrix M_zps`lev' = J(1,`nip',0) + local k = 1 + qui disp "`nip' integration points at level `lev'" + local nloc = `nip' + local npar = M_np[1,`lev'] + if $HG_cip|`nip'>1{ local nloc = `nloc'-1} + while `k' <= `nloc' { + local j = `nrfold'+1 + while `j'<=`j1'{ + qui disp "level `lev', class `k' and random effect `j'" + qui disp " nxt = " `nxt' + matrix `b2' = `b2'[1, `nxt'...] + qui matrix list `b2' + local nxt = 1 + if `k'==1{ + /* linear predictors come before first masspoint */ + local np = M_nbrf[1,`j']-1 + if `np'>0 { + qui disp "extracting coefficients for r.eff" + matrix `s1' = `b2'[1,1..`np'] + matrix score double ${HG_s`j'} = `s1' + qui disp "HG_s`j' = ${HG_s`j'} = " ${HG_s`j'}[$which] + local nxt = `nxt' + `np' + } + /* first coeff fixed at one */ + if M_frld[1,`rf']~=1{ + matrix `s1' = (1) + local lab: colnames `b2' + local lab: word `nxt' of `lab' + matrix colnames `s1'=`lab' + qui matrix list `s1' + capture drop `junk' + matrix score double `junk' = `s1' + if `np'>0{ + qui replace ${HG_s`j'}=${HG_s`j'}+`junk' + } + else{ + qui gen double ${HG_s`j'}=`junk' + } + qui matrix list `s1' + } + qui disp "HG_s`j' = ${HG_s`j'} = " ${HG_s`j'}[$which] + qui disp "making M_zlc`j'" + matrix M_zlc`j' = J(1,`nip',0) + } + matrix M_zlc`j'[1,`k'] = `b2'[1,`nxt'] + local nxt = `nxt' + 1 + local j = `j' + 1 + } + if `k'<`nip'{ + if `npar'>0{ + qui disp "extract probability parameters for HG_p`cl' (npar=`npar')" + matrix `s1' = `b2'[1,`nxt'..(`nxt'+`npar'-1)] + qui matrix list `s1' + capture drop `junk' + matrix score double `junk' = `s1' + qui gen double ${HG_p`lev'`k'} = `junk' + local nxt = `nxt' + `npar' - 1 + qui replace `pdenom' = `pdenom' + exp(${HG_p`lev'`k'}) + } + + scalar `mzps' = exp(`b2'[1,`nxt']) + if `mzps' == . { + global HG_error=1 + exit + } + matrix M_zps`lev'[1,`k'] = `b2'[1,`nxt'] + local nxt = `nxt' + 1 + scalar `denom' = `denom' + `mzps' + } + local k = `k' + 1 + } + + if `npar'>0{ + qui gen double ${HG_p`lev'`nip'} = 0.0 + local k = 1 + while `k' <= `nip'{ + qui disp "divide HG_p`lev'`k'" + qui replace ${HG_p`lev'`k'} = ${HG_p`lev'`k'} - ln(`pdenom') + local k = `k' + 1 + } + } + + local k = 1 + while `k' <= `nip'{ + matrix M_zps`lev'[1,`k'] = M_zps`lev'[1,`k'] - ln(`denom') + local k = `k' + 1 + } + local j = `nrfold' + 1 + while `j' <= `j1'{ /* define last location */ + if $HG_cip == 1{ + local k = 1 + scalar `mean' = 0 + while `k'<`nip'{ + scalar `mean' = `mean' + M_zlc`j'[1,`k']*exp(M_zps`lev'[1,`k']) + local k = `k' + 1 + } + scalar `mzps' = exp(M_zps`lev'[1,`nip']) + matrix M_zlc`j'[1,`nip'] = -`mean'/`mzps' + } + else if `nip'>1{ + matrix M_zlc`j'[1,`nip'] = `b2'[1,`nxt'] + local nxt = `nxt' + 1 + } + qui disp "M_zlc`j'" + qui matrix list M_zlc`j' + local j = `j' + 1 + } + qui disp "M_zps`lev'" + qui matrix list M_zps`lev' + local nrfold = `j1' + local lev = `lev' + 1 + } +}/*endif HG_free */ +else{ +/* ST. DEVS */ + qui disp "random parameters: " + if $HG_tprf>1{matrix CHmat = J($HG_tprf-1,$HG_tprf-1,0)} + while(`lev'<=$HG_tplv&`rf'<=$HG_tprf){ + local np = M_nbrf[1,`rf'] + qui disp "np = " `np' + local nrf = M_nrfc[2, `lev'] - `nrfold' + matrix `t' = J(`nrf',`nrf',0) + local i = 1 + while (`i' <= `nrf'){ + qui disp " nxt = " `nxt' + matrix `b2' = `b2'[1, `nxt'...] + local nxt = 1 + qui matrix list `b2' + local np = M_nbrf[1, `rf'] - 1 + qui disp `np' " loadings at random effect " `rf' ", level " `lev' + if `np'>0{ + matrix `s1' = `b2'[1,1..`np'] +/* + * fudge: exponentiate s1 + local ij = 1 + while `ij'<=`np'{ + matrix `s1'[1,`ij'] = exp(`s1'[1,`ij']) + local ij = `ij' + 1 + } + * end fudge +*/ + + qui matrix list `s1' + matrix score double ${HG_s`rf'} = `s1' + local nxt = `nxt' + `np' + } + /* first (single non-) loading fixed at one, label in st. dev */ + if M_frld[1,`rf']~=1{ + matrix `s1' = (1) + local lab: colnames `b2' + local lab: word `nxt' of `lab' + matrix colnames `s1' = `lab' + capture drop `junk' + tempname junk + matrix score double `junk' = `s1' + if `np'>0{ + qui replace ${HG_s`rf'} = ${HG_s`rf'} + `junk' + } + else{ + matrix score double ${HG_s`rf'} = `s1' + *qui replace ${HG_s`rf'} = `junk' + } + } + + qui disp "HG_s`rf' = ${HG_s`rf'} = " ${HG_s`rf'}[$which] + * extract standard deviation + * fudge: take exponential + * matrix `t'[`i',`i'] = exp(`b2'[1, `nxt']) + matrix `t'[`i',`i'] = `b2'[1, `nxt'] + matrix CHmat[`rf'-1,`rf'-1]=`t'[`i',`i'] + local nxt = `nxt' + 1 + local i = `i' + 1 + local rf = `rf' + 1 + } + if (`nrf'>1&$HG_cor==1){ /* deal with correlations */ + /* extract correlation parameters */ + local i = 2 + while (`i' <= `nrf'){ + local k = `i' + `nrfold' - 1 + local j = 1 + while (`j' < `i'){ + local l = `j' + `nrfold' - 1 + qui disp "i = " `i' " j = " `j' " nxt = " `nxt' + matrix `t'[`i',`j'] = `b2'[1,`nxt'] + matrix CHmat[`k',`l'] = `t'[`i',`j'] + local j = `j' + 1 + local nxt = `nxt' + 1 + } + local i = `i' + 1 + } + } + qui matrix list `t' + matrix M_chol = `t' + /* unpacked parameters */ + local nrfold = M_nrfc[2,`lev'] + local lev = `lev' + 1 + } /* loop through levels */ +}/*endelse HG_free */ +if "`stop'"~=""{ + exit +} +local nrfold = M_nrfc[2,1] +/* use B-matrix */ +if $HG_tprf>1&$HG_bmat==1{ + qui disp "dealing with B-matrix" + local i = 1 + matrix Bmat = J($HG_tprf-1,$HG_tprf-1,0) + while `i'<$HG_tprf{ + local j = 1 + while `j' < $HG_tprf{ + if M_b[`i',`j']>0{ + matrix Bmat[`i',`j']=`b2'[1,`nxt'] + local nxt = `nxt' + 1 + } + local j = `j' + 1 + } + local i = `i' + 1 + } + qui matrix list Bmat + +/* only works if B-matrix is upper diagonal */ + local i=2 + while `i'<$HG_tprf{ + local k = `i' + `nrfold' + local j = 1 + qui disp "making s`k'" + while `j'<`i'{ + local l = `j' + `nrfold' + qui replace ${HG_s`k'} = ${HG_s`k'} + Bmat[`j',`i']*${HG_s`l'} + qui disp " adding Bmat[`j',`i']s`l'" + local j = `j' + 1 + } + local i = `i' + 1 + } +} + +/* deal with geqs */ + + +if $HG_ngeqs>0{ +qui disp "dealing with geqs" + local i = 1 + while `i'<=$HG_ngeqs{ + local k = M_ngeqs[1,`i'] + local n = M_ngeqs[2,`i'] + qui disp "random effect `k' has `n' covariates" + local nxt2 = `nxt'+`n'-1 + matrix `s1' = `b2'[1,`nxt'..`nxt2'] + qui matrix list `s1' + local nxt = `nxt2' + 1 + capture drop `junk' + matrix score double `junk' = `s1' + qui disp "multiply " `junk'[$which] " by HG_s`k' and add to HG_xb1" + qui replace $HG_xb1 = $HG_xb1 + `junk'*${HG_s`k'} + qui disp "HG_xb1:" $HG_xb1[$which] + local i = `i' + 1 + } +} + +/* use inter */ + +if $HG_inter~=0{ + local k = $HG_l + 1 + local j = $HG_r + 1 + qui disp "HG_s`k' = HG_s`k'*HG_s`j' + qui replace ${HG_s`k'} = ${HG_s`k'}*${HG_s`j'} +} + +/* use CHmat */ +if $HG_free==0&$HG_tprf>1{ + qui disp "dealing with Cholesky matrix" + qui matrix list CHmat + local i = 1 + while (`i'<$HG_tprf){ + local k = `i' + `nrfold' + qui replace `junk'=0 + local j = `i' + qui disp "making s`k'" + while `j'<$HG_tprf{ + local l = `j' + `nrfold' + qui replace `junk' = `junk' + CHmat[`j',`i']*${HG_s`l'} + qui disp " adding CHmat[`j',`i']s`l'" + local j = `j' + 1 + } + qui replace ${HG_s`k'}=`junk' + qui disp "s`k' = ${HG_s`k'} = " ${HG_s`k'}[$which] + local i = `i' + 1 + } +} + +* label M_znow +local i=2 +local lab +while `i'<=$HG_tprf{ + local lab "`lab' ${HG_s`i'}" + local i = `i' + 1 +} +matrix colnames M_znow=`lab' +qui disp "M_znow:" +qui matrix list M_znow +end + diff --git a/Modules/ado/plus/r/reop_ll.ado b/Modules/ado/plus/r/reop_ll.ado new file mode 100644 index 0000000..e17cfd7 --- /dev/null +++ b/Modules/ado/plus/r/reop_ll.ado @@ -0,0 +1,163 @@ +*! Version 1.0.1 November 22 2000, by Guillaume R. Frechette (STB-59: sg158) + +program define reop_ll + version 6.0 + args todo b lnf g + + tempvar theta1 F F1 F2 p db db1 db2 dr C + tempname rho s2su u x w gr + local nm1 = $S_n-1 + local np1 = $S_n+1 + local i = 1 + while `i' < $S_n { + tempname _cut`i' + tempname g_cut`i' + tempname g_cut1`i' + tempname g_cut2`i' + local i = `i'+1 + } + mleval `theta1' = `b', eq(1) + local h 0 + local i 1 + local j 2 + while `i' < $S_n { + mleval `_cut`i'' = `b', eq(`j') scalar + if `h'>0 { + if `_cut`i''<=`_cut`h'' { + scalar `_cut`h''=`_cut`i''-0.01 + /* the above correction should not be needed + in general, but it might preclude `bad' + estimates if, for instance, one performs a + random search */ + } + } + local h = `h'+1 + local i = `i'+1 + local j = `j'+1 + } + mleval `rho' = `b', eq(`np1') scalar + + if `rho' >= 1 { + scalar `rho' = 0.99 + di "rho >= 1, set to rho = 0.99" + } + + scalar `s2su' = sqrt(2*`rho'/(1 - `rho')) + + quietly { + + gen double `F' = . in 1 + gen double `F1' = . in 1 + gen double `F2' = . in 1 + by $S_i: gen double `p' = cond(_n==_N,0,.) + gen double `db' = 0 + gen double `db1' = 0 + gen double `db2' = 0 + gen double `dr' = 0 + gen double `C' = . + + local m 1 + while `m' <= $S_quad { + scalar `x' = $S_x[1,`m'] + scalar `w' = $S_w[1,`m'] + scalar `u' = `s2su'*`x' + + local condf "cond($S_lhs==0, normprob(`_cut1'-`theta1'-`u')" + local i 1 + local j 2 + while `j' < $S_n { + local condf "`condf', cond($S_lhs==`i', normprob(`_cut`j''-`theta1'-`u')-normprob(`_cut`i''-`theta1'-`u')" + local i = `i'+1 + local j = `j'+1 + } + local condf "`condf', 1-normprob(`_cut`nm1''-`theta1'-`u'))" + local i 2 + while `i' < $S_n { + local i = `i'+1 + local condf "`condf')" + } + replace `C' = `condf' + replace `C' = 0.00000001 if `C' == 0 + + by $S_i: replace `F' = /* + */ cond(_n==1,`C',`C'*`F'[_n-1]) + + replace `p' = `p' + `w'*`F' + + local condg1 "cond($S_lhs==0, 0" + local condg2 "cond($S_lhs==0, -exp(-0.5*(`_cut1'-`theta1'-`u')^2)" + local h 1 + local i 2 + while `i' < $S_n { + local condg1 "`condg1', cond($S_lhs==`h', exp(-0.5*(`_cut`h''-`theta1'-`u')^2)" + local condg2 "`condg2', cond($S_lhs==`h', -exp(-0.5*(`_cut`i''-`theta1'-`u')^2)" + local h = `h'+1 + local i = `i'+1 + } + local condg1 "`condg1', exp(-0.5*(`_cut`nm1''-`theta1'-`u')^2))" + local condg2 "`condg2', 0)" + local i 2 + while `i' < $S_n { + local i = `i'+1 + local condg1 "`condg1')" + local condg2 "`condg2')" + } + + replace `F1' = `F' + replace `F2' = `F' + by $S_i: replace `F1' = `condg1'*`F1'[_N]/`C' + by $S_i: replace `F2' = `condg2'*`F2'[_N]/`C' + by $S_i: replace `F' = (`condg1'+`condg2')*`F'[_N]/`C' + + replace `db' = `db' + `w'*`F' + replace `db1' = `db1' + `w'*`F1' + replace `db2' = `db2' + `w'*`F2' + replace `dr' = `dr' + `w'*`u'*`F' + + local m = `m' + 1 + } + + tempname lp grps + gen double `lp' = ln(`p'/sqrt(_pi)) + by $S_i: gen byte `grps'=_n==_N + sum `grps' if $ML_samp + local N = r(sum) + sum `lp' if $ML_samp, meanonly + if r(N) !=`N' { + scalar `lnf' = . + exit + } + scalar `lnf' = r(sum) + + if `todo'==0|`lnf'==. { exit } + + by $S_i: replace `p' = `p'[_N] + + replace `db' = `db'/(sqrt(2*_pi)*`p') + replace `db1' = -`db1'/(sqrt(2*_pi)*`p') + replace `db2' = -`db2'/(sqrt(2*_pi)*`p') + + matrix vecaccum `g' = `db' $S_rhs, nocons + local i 0 + local j 1 + while `j' < $S_n { + capture { + matrix vecaccum `g_cut1`j'' = `db1' if $S_lhs == `j' + matrix vecaccum `g_cut2`j'' = `db2' if $S_lhs == `i' + } + if _rc { + scalar `lnf' = . + exit + } + matrix `g_cut`j'' = `g_cut1`j''+`g_cut2`j'' + matrix `g' = `g', `g_cut`j'' + local i = `i'+1 + local j = `j'+1 + } + + replace `dr' = sum(`dr'/`p') + + scalar `gr' = `dr'[_N]/(2*sqrt(2*_pi)*`rho'*(1-`rho')) + matrix `g' = `g', `gr' + } +end diff --git a/Modules/ado/plus/r/reopc_ll.ado b/Modules/ado/plus/r/reopc_ll.ado new file mode 100644 index 0000000..9d92c46 --- /dev/null +++ b/Modules/ado/plus/r/reopc_ll.ado @@ -0,0 +1,160 @@ +*! Version 1.0.1 November 22 2000, by Guillaume R. Frechette (STB-59: sg158) + +program define reopc_ll + version 6.0 + args todo b lnf g + + tempvar F F1 F2 p db1 db2 dr C + tempname rho s2su u x w gr + local nm1 = $S_n-1 + local np1 = $S_n+1 + local i = 1 + while `i' < $S_n { + tempname _cut`i' + tempname g_cut`i' + tempname g_cut1`i' + tempname g_cut2`i' + local i = `i'+1 + } + local h 0 + local i 1 + local j 2 + while `i' < $S_n { + mleval `_cut`i'' = `b', eq(`i') scalar + if `h'>0 { + if `_cut`i''<=`_cut`h'' { + scalar `_cut`h''=`_cut`i''-0.01 + /* the above correction should not be needed + in general, but it might preclude `bad' + estimates if, for instance, one performs a + random search */ + } + } + local h = `h'+1 + local i = `i'+1 + local j = `j'+1 + } + mleval `rho' = `b', eq($S_n) scalar + + if `rho' >= 1 { + scalar `rho' = 0.99 + di "rho >= 1, set to rho = 0.99" + } + + scalar `s2su' = sqrt(2*`rho'/(1 - `rho')) + + quietly { + + gen double `F' = . in 1 + gen double `F1' = . in 1 + gen double `F2' = . in 1 + by $S_i: gen double `p' = cond(_n==_N,0,.) + gen double `db1' = 0 + gen double `db2' = 0 + gen double `dr' = 0 + gen double `C' = . + + local m 1 + while `m' <= $S_quad { + scalar `x' = $S_x[1,`m'] + scalar `w' = $S_w[1,`m'] + scalar `u' = `s2su'*`x' + + local condf "cond($S_lhs==0, normprob(`_cut1'-`u')" + local i 1 + local j 2 + while `j' < $S_n { + local condf "`condf', cond($S_lhs==`i', normprob(`_cut`j''-`u')-normprob(`_cut`i''-`u')" + local i = `i'+1 + local j = `j'+1 + } + local condf "`condf', 1-normprob(`_cut`nm1''-`u'))" + local i 2 + while `i' < $S_n { + local i = `i'+1 + local condf "`condf')" + } + replace `C' = `condf' + replace `C' = 0.00000001 if `C' == 0 + + by $S_i: replace `F' = /* + */ cond(_n==1,`C',`C'*`F'[_n-1]) + + replace `p' = `p' + `w'*`F' + + local condg1 "cond($S_lhs==0, 0" + local condg2 "cond($S_lhs==0, -exp(-0.5*(`_cut1'-`u')^2)" + local h 1 + local i 2 + while `i' < $S_n { + local condg1 "`condg1', cond($S_lhs==`h', exp(-0.5*(`_cut`h''-`u')^2)" + local condg2 "`condg2', cond($S_lhs==`h', -exp(-0.5*(`_cut`i''-`u')^2)" + local h = `h'+1 + local i = `i'+1 + } + local condg1 "`condg1', exp(-0.5*(`_cut`nm1''-`u')^2))" + local condg2 "`condg2', 0)" + local i 2 + while `i' < $S_n { + local i = `i'+1 + local condg1 "`condg1')" + local condg2 "`condg2')" + } + + replace `F1' = `F' + replace `F2' = `F' + by $S_i: replace `F1' = `condg1'*`F1'[_N]/`C' + by $S_i: replace `F2' = `condg2'*`F2'[_N]/`C' + by $S_i: replace `F' = (`condg1'+`condg2')*`F'[_N]/`C' + + replace `db1' = `db1' + `w'*`F1' + replace `db2' = `db2' + `w'*`F2' + replace `dr' = `dr' + `w'*`u'*`F' + + local m = `m' + 1 + } + + tempname lp grps + gen double `lp' = ln(`p'/sqrt(_pi)) + by $S_i: gen byte `grps'=_n==_N + sum `grps' if $ML_samp + local N = r(sum) + sum `lp' if $ML_samp, meanonly + if r(N) !=`N' { + scalar `lnf' = . + exit + } + scalar `lnf' = r(sum) + if `todo'==0|`lnf'==. { exit } + + by $S_i: replace `p' = `p'[_N] + + replace `db1' = -`db1'/(sqrt(2*_pi)*`p') + replace `db2' = -`db2'/(sqrt(2*_pi)*`p') + + local i 0 + local j 1 + while `j' < $S_n { + capture { + matrix vecaccum `g_cut1`j'' = `db1' if $S_lhs == `j' + matrix vecaccum `g_cut2`j'' = `db2' if $S_lhs == `i' + } + if _rc { + scalar `lnf' = . + exit + } + matrix `g_cut`j'' = `g_cut1`j''+`g_cut2`j'' + if `j' == 1 { + matrix `g' = `g_cut`j'' + } + else matrix `g' = `g', `g_cut`j'' + local i = `i'+1 + local j = `j'+1 + } + + replace `dr' = sum(`dr'/`p') + + scalar `gr' = `dr'[_N]/(2*sqrt(2*_pi)*`rho'*(1-`rho')) + matrix `g' = `g', `gr' + } +end diff --git a/Modules/ado/plus/r/reoprob.ado b/Modules/ado/plus/r/reoprob.ado new file mode 100644 index 0000000..d59eeab --- /dev/null +++ b/Modules/ado/plus/r/reoprob.ado @@ -0,0 +1,98 @@ +*! Version 1.0.0 (11/22/00), G. R. Frechette (STB-59: sg158; STB-61: sg158.1) + +program define reoprob, eclass + version 6.0 + if replay() { + if "`e(cmd)'" ~= "reoprob" { + error 301 + } + Replay `0' + } + else Estimate `0' +end + +program define Estimate, eclass + + syntax varlist [if] [in] [, I(varname) Quadrat(int 12) /* + */ Level(passthru) *] + + tempvar touse x w + marksample touse + markout `touse' `i' + + tokenize `varlist' + local lhs "`1'" + macro shift 1 + local rhs "`*'" + + /* Get points and weights for Gauss-Hermite quadrature. */ + ghquadm `quadrat' `x' `w' + + /* Set up macros for ml function. */ + global S_i "`i'" + global S_x "`x'" + global S_w "`w'" + global S_quad "`quadrat'" + global S_rhs "`rhs'" + global S_lhs "`lhs'" + + /* get starting values */ + tempname b0 s0 + quietly oprobit `lhs' `rhs' if `touse' + mat `b0' = e(b) + mat `b0' = [`b0', 0.5] + quietly oprobit `lhs' if `touse' + mat `s0' = e(b) + mat `s0' = [`s0', 0.5] + + /* number of categories */ + quietly tab1 $S_lhs if `touse' + global S_n = _result(2) + + /* create our version of `lhs' that runs from 0, ..., n-1 where + n is the number of categories */ + tempvar dv + rename $S_lhs `dv' + quietly egen $S_lhs = group( `dv' ) if `touse' + quietly replace $_lhs = $_lhs-1 + + /* estimation equations */ + local meqe "($S_lhs=`rhs', nocons)" + local start "(_cut1: $S_lhs=)" + + local i = 1 + while ( `i' < $S_n ) { + local meqe "`meqe' /_cut`i'" + local i = `i' + 1 + } + local i = 2 + while ( `i' < $S_n ) { + local start "`start' /_cut`i'" + local i = `i' + 1 + } + local meqe "`meqe' /rho" + local start "`start' /rho" + + /* Sort data. */ + sort $S_i + + /* optimization */ + di in green _n "Fitting constant-only model:" + ml model d1 reopc_ll `start' if `touse', /* + */ init(`s0', copy) maximize /* + */ search(off) /* + */ `options' + di in green _n "Fitting full model:" + ml model d1 reop_ll `meqe' if `touse', /* + */ continue init(`b0', copy) maximize /* + */ search(off) /* + */ `options' /* + */ title("Random Effects Ordered Probit") + estimate local cmd "reoprob" + Replay, `level' +end + +program define Replay + syntax [, Level(int $S_level)] + ml display, level(`level') +end diff --git a/Modules/ado/plus/r/reoprob.hlp b/Modules/ado/plus/r/reoprob.hlp new file mode 100644 index 0000000..3b32c10 --- /dev/null +++ b/Modules/ado/plus/r/reoprob.hlp @@ -0,0 +1,95 @@ +.- +help for ^reoprob^ (STB-59: sg158; STB-61: sg158.1) +.- + +Random-effects ordered probit +----------------------------- + + ^reoprob^ depvar varlist [^if^ exp] [^in^ range] ^,^ + [ ^i(^varname^)^ ^q^uadrat^(^#^)^ ^l^evel^(^#^)^ maximize_options ] + +This command shares the features of all estimation commands; see help @est@. + +To reset problem-size limits, see help @matsize@. + + +Description +----------- + +^reoprob^ estimates a random-effects ordered probit model for panel datasets +using maximum likelihood estimation. The likelihood for each unit is +approximated by Gauss-Hermite quadrature. + + +Options +------- + +^i(^varname^)^ specifies the variable corresponding to an independent unit + (e.g., a subject id). ^i(^varname^)^ is not optional. + +^quadrat(^#^)^ specifies the number of points to use for Gaussian-Hermite + quadrature. It is optional, and the default is 12. Increasing this value + improves accuracy, but also increases computation time. Computation time + is roughly proportional to its value. + +^level(^#^)^ specifies the confidence level, in percent, for confidence + intervals. The default is ^level(95)^ or as set by ^set level^. + +maximize_options controls the maximization process and the display of + information; see [R] maximize. ^nolog^ suppresses the display of the + likelihood iterations. Use the ^trace^ option to view parameter + convergence. The ^ltol(^#^)^ and ^tol(^#^)^ option can be used to loosen + the convergence criterion (respectively 1e-7 and 1e-6 by default) during + specification searches. ^iter(^#^)^ specifies the maximum number of + iterations. + + +Examples +-------- + + . ^reoprob y x, i(id)^ + . ^reoprob y x^ + . ^reoprob y x, i(id) quad(24) nolog^ + . ^reoprob y x, i(id) trace^ + . ^reoprob^ + + +Method +------ + +^reoprob^ uses the d1 method (analytic first derviatives) of Stata's ^ml^ +commands. See Butler and Moffitt (1982) for details about using Gauss-Hermite +quadrature to approximate such integrals. Also see Green (2000) for +information on how to estimate a basic ordered probit model. + + +Author +------ + + Guillaume R. Frechette + Ohio State University + Department of Economics + 410 Arps Hall + 1945 North High Street + Columbus, OH 43210-1172 + Tel: (614) 688-4140 + Fax: (614) 292-4192 + e-mail: frechette.6@@osu.edu + http://www.econ.ohio-state.edu/frechette/ + + +Reference +--------- + +Butler, J.S. and R. Moffitt. 1982. A computationally efficient + quadrature procedure for the one-factor multinomial probit model. + Econometrica 50: 761-764. + +Green, W. H. 2000. Econometric Analysis. Prentice Hall, New Jersey. + pp. 875-878. + +Also see +-------- + + Manual: ^[R] xt, [R] xtprobit, [R] maximize, [R] oprobit^ +On-line: help for @xt@, @xtreg@ diff --git a/Modules/ado/plus/r/replist.ado b/Modules/ado/plus/r/replist.ado new file mode 100644 index 0000000..83a8dbf --- /dev/null +++ b/Modules/ado/plus/r/replist.ado @@ -0,0 +1,48 @@ +program def replist, rclass +*! NJC 1.0.0 19 June 2000 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + + * note that 0 copies => empty list + syntax , Copies(numlist int >=0) [ Block Global(str) Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + if `copies' == 1 { + local newlist "`list'" + } + else if `copies' > 1 { + if "`block'" != "" { + local c = 1 + while `c' <= `copies' { + local newlist "`newlist'`list' " + local c = `c' + 1 + } + } + else { + tokenize `list' + local n : word count `list' + local i = 1 + while `i' <= `n' { + local c = 1 + while `c' <= `copies' { + local newlist "`newlist'``i'' " + local c = `c' + 1 + } + local i = `i' + 1 + } + } + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/r/replist.hlp b/Modules/ado/plus/r/replist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/r/replist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/r/revlist.ado b/Modules/ado/plus/r/revlist.ado new file mode 100644 index 0000000..279d204 --- /dev/null +++ b/Modules/ado/plus/r/revlist.ado @@ -0,0 +1,31 @@ +program def revlist, rclass +*! NJC 1.2.0 7 June 2000 +* NJC 1.1.0 22 Dec 1999 +* NJC 1.0.0 24 Oct 1999 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax [, Noisily Global(str) ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tokenize `list' + local nwords : word count `list' + + local i = `nwords' + while `i' >= 1 { + local newlist "`newlist'``i'' " + local i = `i' - 1 + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/r/revlist.hlp b/Modules/ado/plus/r/revlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/r/revlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/r/rfpr_ll1.ado b/Modules/ado/plus/r/rfpr_ll1.ado new file mode 100644 index 0000000..8432115 --- /dev/null +++ b/Modules/ado/plus/r/rfpr_ll1.ado @@ -0,0 +1,129 @@ +*! version 1.0.0 7 June 1995 sg41: STB-26 +program define rfpr_ll1 /* b log_likelihood grad */ + version 4.0 + local b "`1'" + local f "`2'" + local g "`3'" + macro shift 3 + local options "FIRSTIT LASTIT FAST(string)" + parse "`*'" + + local y = trim("$S_mldepn") + local doit "$S_sample" + local i "$S_ivar" + + tempname rho s2su beta u + tempvar xb F p + + local rhocol = colnumb(`b',"rho:_cons") + scalar `rho' = abs(`b'[1,`rhocol']) + + if `rho' >= 1 { + scalar `rho' = 0.99 + di "rho >= 1, set to rho = 0.99" + } + + matrix `b'[1,`rhocol'] = `rho' + scalar `s2su' = sqrt(2*`rho'/(1 - `rho')) + matrix `beta' = `b'[1,"`y':"] + + quietly { + + matrix score double `xb' = `beta' if `doit' + + gen double `F' = . in 1 + by `doit' `i': gen double `p' = cond(_n==_N,0,.) if `doit' + +/* Do computation this way if only log likelihood required. */ + + if "`fast'" == "0" { + local m 1 + while `m' <= $S_quad { + scalar `u' = `s2su'*$S_x[`m'] + + #delimit ; + + by `doit' `i': replace `F' = + cond(_n==1, + cond(`y', normprob(`xb' + `u'), + 1 - normprob(`xb' + `u')), + cond(`y', normprob(`xb' + `u'), + 1 - normprob(`xb' + `u')) + *`F'[_n-1]) + if `doit' ; + + #delimit cr + + replace `p' = `p' + $S_w[`m']*`F' if `doit' + + local m = `m' + 1 + } + + replace `F' = sum(log(`p'/sqrt(_pi))) if `doit' + scalar `f' = `F'[_N] + + exit + } + +/* Do computation this way if first derivatives required. */ + + tempname gr + tempvar db dr + gen double `db' = 0 + gen double `dr' = 0 + + local m 1 + while `m' <= $S_quad { + scalar `u' = `s2su'*$S_x[`m'] + + #delimit ; + + by `doit' `i': replace `F' = + cond(_n==1, + cond(`y', normprob(`xb' + `u'), + 1 - normprob(`xb' + `u')), + cond(`y', normprob(`xb' + `u'), + 1 - normprob(`xb' + `u'))*`F'[_n-1]) + if `doit' ; + + replace `p' = `p' + $S_w[`m']*`F' if `doit' ; + + by `doit' `i': replace `F' = + cond(`y',1,-1)*exp(-0.5*(`xb'+`u')^2)*`F'[_N] + /cond(`y',normprob(`xb'+`u'),1-normprob(`xb'+`u')) + if `doit' ; + + #delimit cr + + replace `db' = `db' + $S_w[`m']*`F' if `doit' + replace `dr' = `dr' + $S_w[`m']*`u'*`F' if `doit' + + local m = `m' + 1 + } + +/* Compute log likelihood. */ + + replace `F' = sum(log(`p'/sqrt(_pi))) if `doit' + scalar `f' = `F'[_N] + +/* Compute first derivatives. */ + + by `doit' `i': replace `p' = `p'[_N] if `doit' + + replace `db' = `db'/(sqrt(2*_pi)*`p') if `doit' + + local nvar = colsof(`beta') - 1 + if `nvar' > 0 { + matrix `beta' = `beta'[1, 1..`nvar'] + local vars : colnames(`beta') + } + + matrix vecaccum `g' = `db' `vars' if `doit' + + replace `dr' = sum(`dr'/`p') if `doit' + + matrix `gr' = (0) + matrix `gr'[1,1] = `dr'[_N]/(2*sqrt(2*_pi)*`rho'*(1-`rho')) + matrix `g' = `g' , `gr' + } +end diff --git a/Modules/ado/plus/r/rfprobit.ado b/Modules/ado/plus/r/rfprobit.ado new file mode 100644 index 0000000..26d1c0d --- /dev/null +++ b/Modules/ado/plus/r/rfprobit.ado @@ -0,0 +1,233 @@ +*! version 1.1.0 20jun1995 sg41: STB-26 +program define rfprobit + version 4.0 + local options "Level(integer $S_level)" + if substr("`1'",1,1)=="," | "`*'"=="" { + if "$S_E_cmd"~="rfprobit" { + error 301 + } + parse "`*'" + } + else { + local varlist "req ex" + local if "opt" + local in "opt" + local options /* + */ "`options' I(string) Quadrat(integer 6) noCHIsq noLOg *" + parse "`*'" + parse "`varlist'", parse(" ") + local y "`1'" + macro shift + xt_iis `i' + local i "$S_1" + tempvar doit x w + mark `doit' `if' `in' + markout `doit' `y' `*' `i' + + /* Check to see if outcome varies. */ + + quietly count if `doit' + local n = _result(1) + quietly count if `y'==0 & `doit' + local n0 = _result(1) + if `n0'==0 | `n0'==`n' { + di _n in blu "outcome does not vary" + exit + } + + /* Sort data. */ + + sort `doit' `i' + + /* Get points and weights for Gaussian-Hermite quadrature. */ + + ghquad double(`x' `w'), n(`quadrat') + + /* Set up macros for ml function. */ + + global S_sample "`doit'" + global S_ivar "`i'" + global S_x "`x'" + global S_w "`w'" + global S_quad "`quadrat'" + + /* Fit constant-only model. */ + + if "`chisq'"=="" & "`*'"~="" { + rfpr_ml `y', title("Constant-only model") /* + */ `log' `options' + local lf0 "lf0($S_1)" + local rho "rho($S_2)" + } + + /* Fit full model. */ + + rfpr_ml `y' `*', title("Full model") post `lf0' `rho' /* + */ `log' `options' + } + +/* Display results. */ + + ml mlout rfprobit, level(`level') + +/* Compute LR test for rho = 0. */ + + local chi = 2*($S_E_ll - $S_E_rho0) + + #delimit ; + di in gr "LR test of rho = 0: chi2(" in ye "1" in gr ") = " + in ye %7.2f `chi' _n + in gr " Prob > chi2 = " in ye %7.4f + chiprob(1,`chi') ; + #delimit cr +end + + +program define rfpr_ml /* y x, title(string) POST noLOg ml_options */ + version 4.0 + local varlist "req ex" + local options "TITLE(string) POST LF0(string) RHO(string) noLOg *" + parse "`*'" + parse "`varlist'", parse(" ") + local y "`1'" + macro shift + local doit "$S_sample" + if "`lf0'"~="" { local lf0 "lf0(`lf0')" } + + tempname llrho0 b0 b1 lllast b ll V + tempvar mldoit + +/* Get initial values. */ + + quietly probit `y' `*' if `doit' + scalar `llrho0' = _result(2) + if "`log'"=="" { + di _n in gr "`title'" + di in gr "rho =" in ye %4.1f 0 /* + */ in gr " Log Likelihood = " in ye `llrho0' + } + matrix `b0' = get(_b) + matrix coleq `b0' = `y' + matrix `b1' = (0) + matrix colnames `b1' = rho:_cons + matrix `b0' = `b0' , `b1' + local rcol = colnumb(`b0',"rho:_cons") + +/* Search for good starting value for rho if not supplied. */ + + if "`rho'"=="" { + global S_mldepn "`y'" + scalar `lllast' = `llrho0' + local rho 0.05 + local rhotry 0.1 + while `rhotry' < 0.91 { + matrix `b0'[1,`rcol'] = `rhotry' + rfpr_ll1 `b0' `ll' `b' , fast(0) + if "`log'"=="" { + di in gr "rho =" in ye %4.1f `rhotry' /* + */ in gr " Log Likelihood ~ " in ye `ll' + } + if `ll' < `lllast' { /* exit loop */ + local rhotry 1 + } + else { + scalar `lllast' = `ll' + local rho `rhotry' + local rhotry = `rhotry' + 0.1 + } + } + } + + matrix `b0'[1,`rcol'] = `rho' + +/* Set up ml commands. */ + + ml begin + ml function rfpr_ll1 + ml method deriv1 + eq `y': `y' `*' + eq rho: + ml model `b' = `y' rho, depv(10) from(`b0') + ml sample `mldoit' if `doit', noauto + + if "`log'"=="" { noisily ml max `ll' `V', `options' } + else quietly ml max `ll' `V', `options' + + global S_1 = `ll' + global S_2 = `b'[1,`rcol'] + + if "`post'"~="" { + ml post rfprobit, `lf0' pr2 title("Random-Effects Probit") + } + + global S_E_rho0 = `llrho0' +end + +/* + Routines that compute weights and points for Gaussian-Hermite + quadrature follow: +*/ + +* version 1.0.1 29jun1995 +program define ghquad + version 4.0 + local varlist "req new min(2) max(2)" + local options "N(integer 10)" + parse "`*'" + parse "`varlist'", parse(" ") + local x "`1'" + local w "`2'" + if `n' + 2 > _N { + di in red /* + */ "`n' + 2 observations needed to compute quadrature points" + exit 2001 + } + tempname xx ww + local i 1 + local m = int((`n' + 1)/2) + while `i' <= `m' { + if `i' == 1 { + scalar `xx' = sqrt(2*`n'+1)-1.85575*(2*`n'+1)^(-1/6) + } + else if `i' == 2 { scalar `xx' = `xx'-1.14*`n'^0.426/`xx' } + else if `i' == 3 { scalar `xx' = 1.86*`xx'-0.86*`x'[1] } + else if `i' == 4 { scalar `xx' = 1.91*`xx'-0.91*`x'[2] } + else { scalar `xx' = 2*`xx'-`x'[`i'-2] } + hermite `n' `xx' `ww' + qui replace `x' = `xx' in `i' + qui replace `w' = `ww' in `i' + local i = `i' + 1 + } + if mod(`n', 2) == 1 { qui replace `x' = 0 in `m' } + qui replace `x' = -`x'[`n'+1-_n] in `i'/`n' + qui replace `w' = `w'[`n'+1-_n] in `i'/`n' +end + + +program define hermite /* integer n, scalar x, scalar w */ + version 4.0 + local n "`1'" + local x "`2'" + local w "`3'" + local last = `n' + 2 + tempvar p + tempname i + qui gen double `p' = . + scalar `i' = 1 + while `i' <= 10 { + qui replace `p' = 0 in 1 + qui replace `p' = _pi^(-0.25) in 2 + qui replace `p' = `x'*sqrt(2/(_n-2))*`p'[_n-1] /* + */ - sqrt((_n-3)/(_n-2))*`p'[_n-2] in 3/`last' + scalar `w' = sqrt(2*`n')*`p'[`last'-1] + scalar `x' = `x' - `p'[`last']/`w' + if abs(`p'[`last']/`w') < 3e-14 { + scalar `w' = 2/(`w'*`w') + exit + } + scalar `i' = `i' + 1 + } + di in red "hermite did not converge" + exit 499 +end + diff --git a/Modules/ado/plus/r/rfprobit.hlp b/Modules/ado/plus/r/rfprobit.hlp new file mode 100644 index 0000000..c658698 --- /dev/null +++ b/Modules/ado/plus/r/rfprobit.hlp @@ -0,0 +1,102 @@ +.- +help for ^rfprobit^ (STB-26: sg41) +.- + +Random-effects probit +--------------------- + + ^rfprobit^ depvar [indepvars] [^if^ exp] [^in^ range] ^,^ [ ^i(^varname^)^ + ^q^uadrat^(^#^)^ ^nochi^sq ^nolo^g ^l^evel^(^#^)^ maximize_options ] + +This command shares the features of all estimation commands; see help @est@. + +To reset problem-size limits, see help @matsize@. + + +Description +----------- + +^rfprobit^ estimates a random-effects probit model for cross-sectional time- +series data sets using maximum likelihood estimation. The likelihood (for +an independent unit i) is expressed as an integral which is computed using +Gaussian-Hermite quadrature. This computational procedure is only accurate +when there are a small-to-moderate number of time periods T_i per unit i. +It is recommended that ^rfprobit^ only be used when max(T_i) <= 50. + + +Options +------- + +^i(^varname^)^ specifies the variable corresponding to an independent unit + (e.g., a subject id). This variable represents the i in x_it. Either + this option must be specified or i must be set using the ^iis^ command; + see help for @xt@. + +^quadrat(^#^)^ specifies the number of points to use for Gaussian-Hermite + quadrature. Default is 6. Increasing this value slightly improves + accuracy, but also increases computation time. Computation time is + roughly proportional to its value. + +^nochisq^ omits the estimation of the constant-only model. This will reduce + computation time at the cost of not being able to calculate the model + chi-squared or pseudo R^^2. + +^nolog^ suppress the display of the likelihood iterations. + +^level(^#^)^ specifies the significance level, in percent, for confidence + intervals of the coefficients; see help @level@. + +maximize_options control the maximization process; see [7] maximize. + Use the ^trace^ option to view parameter convergence. + The ^ltol(^#^)^ option can be used to loosen the convergence + criterion (default is 1e-6) during specification searches. + + +Examples +-------- + + . ^rfprobit y x, i(id)^ + + . ^iis id^ + . ^rfprobit y x^ + + . ^rfprobit y x, i(id) nochisq^ + . ^rfprobit y x, i(id) quad(8) nolog^ + . ^rfprobit y x, i(id) trace^ + . ^rfprobit^ + + +Method +------ + +^rfprobit^ uses the deriv1 method (analytic first derviatives) of Stata's ^ml^ +commands. See Butler and Moffitt (1982) for details. + + +Author +------ + + Bill Sribney + Stata Corporation + 702 University Drive East + College Station, TX 77840 + Phone: 409-696-4600 + 800-782-8272 + Fax: 409-696-4601 + email: tech_support@@stata.com + + +Reference +--------- + +Butler, J.S. and R. Moffitt. 1982. A computationally efficient quadrature + procedure for the one-factor multinomial probit model. Econometrica 50: + 761-764. + + +Also see +-------- + + STB: STB-26 sg41 + Manual: [5s] xt, [5s] xtreg, [7] maximize +On-line: help for @xt@, @xtreg@ diff --git a/Modules/ado/plus/r/rotlist.ado b/Modules/ado/plus/r/rotlist.ado new file mode 100644 index 0000000..43eedcb --- /dev/null +++ b/Modules/ado/plus/r/rotlist.ado @@ -0,0 +1,44 @@ +program def rotlist, rclass +*! NJC 1.1.0 6 June 2000 +* NJC 1.0.0 26 Apr 2000 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + + syntax , Rot(int) [ Global(str) Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + local n : word count `list' + local rot = mod(`rot', `n') + + if `rot' == 0 { + local newlist "`list'" + } + else { + tokenize `list' + + local i = `rot' + 1 + while `i' <= `n' { + local newlist "`newlist'``i'' " + local i = `i' + 1 + } + + local i = 1 + while `i' <= `rot' { + local newlist "`newlist'``i'' " + local i = `i' + 1 + } + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/r/rotlist.hlp b/Modules/ado/plus/r/rotlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/r/rotlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/s/sasexe.ado b/Modules/ado/plus/s/sasexe.ado new file mode 100644 index 0000000..3a9efe8 --- /dev/null +++ b/Modules/ado/plus/s/sasexe.ado @@ -0,0 +1,417 @@ +*! sasexe Version 2.2 dan.blanchette@duke.edu 04May2009 +*! Center for Entrepreneurship and Innovation Duke University's Fuqua School of Business +* - added directory for SAS 9.2 executable +* - stopped having it use -shortdir- and started returning wsas in double quotes +* sasexe Version 2.1 dan.blanchette@duke.edu 16Mar2009 +* - made it so saswrapper can run it +* sasexe Version 2.1 dan_blanchette@unc.edu 03Mar2008 +* research computing, unc-ch +* - added a check for environment variable %MAINDIR% in foreach loop through users path +* if this variable doesn't exist then don't look for sas.exe there. +* - removed references to J: drive locations of SAS +* - added error message that -sasexe- cannot be run in Stata batch in Windows +* sasexe Version 2.0 dan_blanchette@unc.edu 06Sep2006 +** the carolina population center, unc-ch +** - need to return what version of SAS is running +** - not only does sasexe look to see if sas executable file exists but also if it works +** and figures out what version it is. +** - looks in environment variable PATH as a last ditch effort to find the SAS executable file +** - added search for the char2fmt SAS macro file char2fmt.mac +** sasexe Version 1.0 dan_blanchette@unc.edu 02Sep2004 +/* updated on 02Sep2004: added new drive specification for UNC afs pc-pkg space SAS users */ +/* updated on 11Mar2004: added message to UNIX users on how to + * find their sas executable file. */ +** sasexe Version 1.0 dan_blanchette@unc.edu 06Nov2003 + + +program define sasexe, rclass +version 8 + + *** SET LOCATION OF SAS EXECUTABLE HERE *** + *------------------------------------------* + + // set the macro var appropriate for your operating system + // and feel free to send me the location so that I can add it to the + // list of locations that -sasexe- searches through so that in future + // updates your executable location will already be set + local wsas `""' // location of windows sas executable file + local usas `""' // location of UNIX/Linux sas executable file + local rver `""' // version of sas you think you are running like v8, v9 + // local rver `"v9"' + + + /* If you are using -savasas- and don't have SAS and just want to create a SAS program + * and temp data files set what version you think the SAS program will be run in here: */ + local nosasver= `""' // this is not an option for -usesas- + + + + *** SET LOCATION OF SAVASTATA MACRO HERE FOR USESAS *** + *-----------------------------------------------------* + /** for example: + local savastata "C:\ado\plus\s\savastata.sas" **/ + local savastata "" + ** note: if you set the location of savastata you must also set + * the locaton of char2fmt + + *** SET LOCATION OF CHAR2FMT MACRO HERE FOR USESAS *** + *-----------------------------------------------------* + /** for example: + local char2fmt "C:\ado\plus\c\char2fmt.sas" **/ + local char2fmt "" + ** note: if you set the location of char2fmt you must also set + * the locaton of savastata + + +***************************************************************** +******* ! NO MORE EDITS SHOULD BE MADE AFTER THIS POINT ! ******* +***************************************************************** + +// the 2nd argument is the location of SAS executable if invoked by savas +if "`1'" == "savasas" & `"`2'"' != `""' & `"`2'"' != `"sascode"' { + local usas `"`2'"' // location of UNIX/Linux sas executable file +} + +if `"`nosasver'"' == "" { + if "`c(os)'" == "Windows" & !missing(`"`usas'"') { + local usas = "" // set to missing for the logic of this program + } + else if "`c(os)'" != "Windows" & !missing(`"`wsas'"') { + local wsas = "" // set to missing for the logic of this program + } + ** User set wsas or usas location so check it out ** + ** --------------------------------------------------------------------- ** + if `"`wsas'"' != "" | "`usas'" != "" /* & "`2'" == "" */ { // sasexe tries to find sas executable otherwise + if "`c(os)'" == "Windows" { + if !missing(`"`wsas'"') { + capture confirm file `"`wsas'"' + if _rc==0 { + // find out if this works and what version + sasexe_ver, sasexe(`"`wsas'"') + if "`r(rver)'" == "" { + // if version wasn't figured out then sas didn't work + local wsas "" + } + else { // if rver is something then sas works + local rver "v`= int(`r(rver)')'" + di as res _n `"`1' has found the SAS executable file:"' + di as res `"`wsas'"' + } + } + } + } + else { // if os is not Windows (UNIX/Linux) + if !missing(`"`usas'"') { + capture confirm file `"`wsas'"' + if _rc==0 { + // find out if this works and what version + sasexe_ver, sasexe(`"`usas'"') + if "`r(rver)'" == "" { + // if version wasn't figured out then sas didn't work + local usas "" + } + else { // if rver is something then sas works + local rver "v`= int(`r(rver)')'" + di as res _n `"`1' has found the SAS executable file:"' + di as res `""`usas'""' + } + } + } + } + } +} // end of nosasver not set + +** If above macros not set by user or set incorrectly ** +** then have sasexe look in the usual locations ** +** ---------------------------------------------------** + + if "`1'"=="usesas" | "`1'"=="saswrapper" & (`"`savastata'"' == "" | `"`char2fmt'"' == "") { + foreach macro in savastata char2fmt { + capture confirm file `"x:\software/`macro'.sas"' /* network location */ + if _rc==0 { + local `macro' `"x:\software/`macro'.sas"' + } + else { + // local set_macro `"/bigtemp/sas_macros/`macro'.sas"' /* CPC's location */ + local set_macro `"/afs/isis/pkg/stata/.install/common/ado/updates/`macro'.sas"' + capture confirm file `"`set_macro'"' /* UNIX box location */ + if _rc==0 { + local `macro' `"`set_macro'"' + } + else { + // find it in the adopath + capture findfile `macro'.sas + local cwd=`"`c(pwd)'"' + local dir=substr(`"`r(fn)'"',1,index(`"`r(fn)'"',"`macro'.sas")-1) + quietly cd `"`dir'"' + capture confirm file "`macro'.sas" + if _rc==0 { + local `macro' `"`c(pwd)'`c(dirsep)'`macro'.sas"' + } + quietly cd `"`cwd'"' + } + } + } + } /* end of if savastata or char2fmt not set */ + + + // search even if sascode requested (`2' means sascode) since version (rver) can still be figured out + if `"`nosasver'"' == "" & (`"`wsas'"' == "" | `"`usas'"' == "" ) /* & "`2'" == "" */ { // sasexe tries to find sas executable otherwise + if "`c(os)'"=="Windows" & `"`wsas'"'=="" { + foreach sas in "c:\progra~1\sas\sasfou~1\9.2\sas.exe" /// 9.2 + "C:\Program Files\SAS\SAS 9.2\SASFoundation\9.2\sas.exe" ///9.2 + "d:\progra~1\sas\sasfou~1\9.2\sas.exe" /// 9.2 + "C:\Program Files\SAS\SASFoundation\9.2(32-bit)\sas.exe" /// 9.2 + "d:\Program Files\SAS\SASFoundation\9.2(32-bit)\sas.exe" /// 9.2 + "d:\SAS\SASFoundation\9.2(32-bit)\sas.exe" /// 9.2 + "d:\sasfou~1\9.2\sas.exe" /// 9.2 + "Y:\SASSER~1\v9\sas\sas.exe" /// Win XP + "Y:\SAS_SE~1\V9\SAS\SAS.EXE" /// Win 2000 + "c:\progra~1\sas\sas9~1.1\sas.exe" /// + "c:\progra~1\sas\sas9~2\sas.exe" /// + "c:\progra~1\sasins~1\sas\v9\sas.exe" /// + "d:\sasv9~1.1\sas\sas.exe" /// + "d:\sasv9~2\sas\sas.exe" /// + /// now try version 8 + "c:\progra~1\sasins~1\sas\v8\sas.exe" /// + "d:\sasv8~1\sas\sas.exe" /// + "Y:\SAS_SE~1\V8\SAS\SAS.EXE" /// Win 2000 + "Y:\SASSER~1\V8\SAS\SAS.EXE" /* Win XP */ { + capture confirm file "`sas'" + if _rc==0 { // success! + local wsas `"`sas'"' /* for Windows */ + // find out if this works and what version + sasexe_ver, sasexe(`"`wsas'"') + if "`r(rver)'" == "" { + // if version wasn't figured out then sas didn't work + local wsas "" + } + else { // if rver is something then sas works + local rver "v`= int(`r(rver)')'" + di as res _n `"`1' is going to run SAS `rver' executable: "`wsas'" "' + continue, break // stop looking + } + } + } /* end of foreach loop */ + } /* end of if Windows */ + + else if "`c(os)'"=="Unix" & "`usas'"=="" { + if "`c(machine_type)'" == "Sun Solaris" { + capture confirm file `"/opt/sas9.1/sas"' + if _rc==0 { + local usas "`usas'" + local rver `"v9"' + } + } + else if "`c(machine_type)'" == "PC" { /* for Linux work stations */ + capture confirm file `"/usr/bin/sas"' + if _rc==0 { + local usas "/usr/bin/sas" + // let sasexe figure out what version of SAS + sasexe_ver, sasexe(`"`usas'"') + local rver "v`= int(`r(rver)')'" + } + else { + capture confirm file `"/afs/isis/pkg/sas/sas"' + if _rc==0 { + /* for Linux in pkg space */ + local usas `"/afs/isis/pkg/sas/sas"' + local rver `"v9"' + } + } + } // end if "PC" / a Linux box + else if "`c(machine_type)'" == "IBM RS/6000" { + capture confirm file `"/afs/isis/pkg/sas/sas"' + if _rc==0 { + local usas `"/afs/isis/pkg/sas/sas"' /* for UNIX */ + local rver `"v9"' + } + } + } /* end of if UNIX */ + + if `"`wsas'"'=="" & "`usas'"=="" { // if still not set + // look in user's path + local path : environment PATH + local delim ":" + if "`c(os)'" == "Windows" local delim ";" + // allows for dirs to have spaces in the directory names + foreach dir in "`: subinstr local path "`delim'" `"" ""', all'" { + if `= index(`"`dir'"',"%MAINDIR%")' & `"`: environment MAINDIR'"' == "" continue + if "`c(os)'" == "Windows" & `"`: dir "`dir'" files sas.exe'"' == `""sas""' { + capture confirm file `"`dir'\sas.exe"' + if _rc==0 { + local wsas `"`dir'\sas.exe"' + // find out if this works and what version + sasexe_ver, sasexe(`"`wsas'"') + if "`r(rver)'" == "" { + // if version wasn't figured out then sas didn't work + local wsas "" + } + else { // if rver is something then sas works + local rver "v`= int(`r(rver)')'" + di as res _n `"`1' is going to run SAS `rver' executable: "`wsas'" "' + continue, break // leave loop once found sas executable + } + } + } // end of if Windows + else if `"`: dir "`dir'" files sas'"' == `""sas""' { + capture confirm file `"`dir'/sas"' + if _rc==0 { + local usas `"`dir'/sas"' + sasexe_ver, sasexe(`"`usas'"') + if "`r(rver)'" == "" { + // if version wasn't figured out then sas didn't work + local usas "" + } + else { // if rver is something then sas works + local rver "v`= int(`r(rver)')'" + di as res _n `"`1' is going to run SAS `rver' executable: "`usas'" "' + continue, break // leave loop once found sas executable + } + } + } + } // end of foreach dir + + if `"`wsas'"'=="" & "`usas'"=="" { // if _still_ not set + di "{error}Edit your sasexe.ado file to set the location *" + di "{error}of your SAS executable file. *" + which sasexe + di `" {stata adoedit sasexe:edit sasexe.ado} (click, to edit the sasexe.ado file, remember to save when done.)"' + if "`1'"=="savasas" di "{error}or use the {res}sascode {error}option in `1'. * " + if "`1'"=="usesas" di "{error} {help usesas:usesas} requires that you have a working version of SAS on this computer. " + if "`1'"=="saswrapper" di "{error} {help saswrapper:saswrapper} requires that you have a working version of SAS on this computer. " + if "`c(os)'"=="Unix" { + di `"{error} Your SAS executable is a file named "sas" not "sas.exe" and can be found by typing: *"' + di `"{text} which sas *"' + di `"{error} at a UNIX prompt. You may want to inform your UNIX administrator that *"' + di `"{error} you want to run SAS from Stata. * "' + } + exit 499 + } // end of if wsas and usas _still_ empty + } // end of if wsas and usas still empty + + } // end of if "`wsas'"=="" & "`usas'"=="" i.e. not set + + /********* this block of code should not be needed anymore, it should not ever happen ****/ + // check that if wsas or usas was set by user that they did it correctly + if `"`wsas'"'!="" & "`c(os)'"=="Windows" & "`2'"=="" { // `2' is if sascode requested + capture confirm file `"`wsas'"' + if _rc!=0 { + di `"{error}This is not the correct location of your SAS executable: "' + di `"{res}`wsas' "' + di "{error}Edit your sasexe.ado file to set the location of your sas.exe file. " + which sasexe + di `" {stata adoedit sasexe:edit sasexe.ado} (click, to edit the sasexe.ado file, remember to save when done.)"' + + if "`1'"=="savasas" di "{error}or use the {res}sascode {error}option in `1'. " + exit 499 + } + } /* end of if wsas not correctly set */ + else if "`usas'"!="" & "`c(os)'"=="Unix" & "`2'"=="" { // `2' is if sascode requested + capture confirm file `"`usas'"' + if _rc!=0 { + di `"{error}This is not the correct location of your SAS executable: *"' + di `"{res}"`usas'" *"' + di "{error}Edit your sasexe.ado file to set the location *" + di "{error}of your sas executable file. *" + which sasexe + di `" {stata adoedit sasexe:edit sasexe.ado} (click, to edit the sasexe.ado file, remember to save when done.)"' + if "`1'"=="savasas" di "{error}or use the {res}sascode {error}option in `1'. *" + exit 499 + } + } /* end of if usas not correctly set */ + /****** (end) this block of code should not be needed anymore, it should not ever happen **/ + + if "`1'"=="usesas" | "`1'"=="saswrapper" { + foreach macro in savastata char2fmt { + capture confirm file `"``macro''"' + if _rc!=0 { + if `"``macro''"' != "" { + di `"{error}This is not the correct location of your `macro' macro: "' + di `"{res}``macro'' "' + } + else di `"{error}The file `macro'.sas was not found. {help `1':`1'} needs this file to run."' + di "{error}Edit your sasexe.ado file to set the location of your `macro'.sas file. " + which sasexe + di `" {stata adoedit sasexe:edit sasexe.ado} (click, to edit the sasexe.ado file, remember to save when done.)"' + exit 499 + } + return local `macro' ``macro'' + } + } + + // if person knows they don't have sas and chooses what version to run, and is using + // the sascode option then replace rver with nosasver + if `"`nosasver'"' != "" & `"`2'"' != "" local rver=`"`nosasver'"' + + // make sure v8.2 or v9.1.3 is not used as it's not necessary to be that exact + if index("`rver'","8") local rver = "v8" + else if index("`rver'","9") local rver = "v9" + else if index("`rver'","10") local rver = "v10" + else if index("`rver'","11") local rver = "v11" + else if index("`rver'","12") local rver = "v12" + + if "`rver'" == "" & "`2'" == "" { // `2' is if sascode requested + di as error "`1' was unable to figure out what version of SAS you are running. *" + di as error "Please edit your {stata adoedit sasexe:sasexe.ado} file and specify the location of your SAS *" + di as error "executable file and the version of SAS you are running. *" + if "`usas'" != "" & "`c(os)'" != "Windows" { + di as res `"`1' found your SAS executable file here: "`usas'""' + } + else if `"`wsas'"' != "" & "`c(os)'" == "Windows" { + di as res `"`1' found your SAS executable file here: "`wsas'""' + } + exit 499 + } // end of if rver still empty + else if "`rver'" == "" & "`2'" != "" { // `2' is if sascode requested + local rver "v9" + di as error _n `"{help savasas:savasas} is choosing to write code appropriate for SAS version 9. *"' + di as error `"If an alternate version of SAS is desired, please edit your {stata adoedit sasexe:sasexe.ado} file. *"' + + } + + return local rver "`rver'" + return local wsas `"`""`wsas'""'"' + return local usas `usas' + +end + + +capture program drop sasexe_ver +program sasexe_ver, rclass + version 8 + syntax, sasexe(string) + if "`c(os)'"=="Windows" & "`c(mode)'" == "batch" { + di as err "sasexe cannot be run in batch mode on Windows" + exit 499 + } + + tempfile sas_ver + quietly file open sasvfile using "`sas_ver'_version.sas", replace text write + file write sasvfile `"** program to figure out if SAS works and what version is running **;"' _n /// + `" data _null_; "' _n `" file "`sas_ver'_version.do";"' _n /// + `" put "capture program drop sas_rver"; "' _n /// + `" put "program sas_rver, rclass"; "' _n /// + `" put "return local rver ""&sysver."""; "' _n /// + `" put "end";"' _n /// + `" run; "' + file close sasvfile + capture confirm file `"`sas_ver'_version.sas"' + if _rc==0 { + local nologo = "-nologo" + // -nologo is not an option for UNIX/Linux SAS + if "`c(os)'"=="Unix" /* or Linux */ local nologo = "" + + shell "`sasexe'" "`sas_ver'_version.sas" `nologo' -log "`sas_ver'_version.log" + capture confirm file `"`sas_ver'_version.do"' + if _rc==0 { + run `"`sas_ver'_version.do"' + sas_rver + return local rver "`r(rver)'" + } + capture erase `"`sas_ver'_version.sas"' + capture erase `"`sas_ver'_version.log"' + capture erase `"`sas_ver'_version.do"' + } + +end diff --git a/Modules/ado/plus/s/saswrapper.ado b/Modules/ado/plus/s/saswrapper.ado new file mode 100644 index 0000000..567f8bc --- /dev/null +++ b/Modules/ado/plus/s/saswrapper.ado @@ -0,0 +1,751 @@ +*! saswrapper Version 1.1 dan.blanchette@duke.edu 08Jul2009 +*! Center for Entrepreneurship and Innovation Duke University's Fuqua School of Business +* -removed stray carriage return characters +* saswrapper Version 1.1 dan.blanchette@duke.edu 04May2009 +* -made it fail more gracefully when usesas option specified and sas code had an error in it +* saswrapper Version 1.0 dan.blanchette@duke.edu 26Feb2009 + +program define saswrapper, rclass +version 8 +syntax [varlist] [using/ ] [if] [in] [, PRE_sas_prog(string) POST_sas_prog(string) MEssy savasas(string) /// + usesas NODATA clear QUotes CHeck float char2lab NOFORMATS rename ] + +/* log usage of saswrapper */ +capture which usagelog +if _rc == 0 { + usagelog , start type(savas) message(`"saswrapper using `using', `messy' `savasas' `usesas' `nodata' `clear' `quotes' `check' `float' `char2lab' `noformats' `rename' "') +} + + +if "`c(os)'" == "Windows" & "`c(mode)'" == "batch" { + di as err "{help saswrapper:saswrapper} cannot be run in batch mode on Windows" + /* log usage of saswrapper */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(8) etime + } + exit 499 +} +if `c(N)' == 0 & `"`savasas'"' != "" { + di as err "no data in memory to save to SAS" _n + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(8) etime + } + exit 499 +} + +if "`nodata'" != "" & `"`savasas'"' != "" { + di as err "cannot specify both nodata and savasas" _n + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(8) etime + } + exit 499 +} + +if `c(N)' == 0 & "`nodata'" == "" { + local nodata = "nodata" +} + +if `"`usesas'"' != "" & `c(N)' != 0 & "`clear'" == "" { + di "{error} no, data in memory would be lost " + di "{error} use the {res}clear {error}option" + /* log usage of saswrapper */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(1) etime + } + exit 4 +} + +local formats = "formats" +if "`noformats'" != "" { + local formats = "" +} + + +* CAPTURE USER'S LOG +* ------------------ +quietly log query +local usrlog `r(filename)' + +* FIGURE OUT WHERE THE SAS EXECUTABLE IS +* -------------------------------------- +sasexe saswrapper + +local wsas `r(wsas)' +local usas `r(usas)' +local savastata `r(savastata)' +local char2fmt `r(char2fmt)' +local rver `r(rver)' // version of sas that's being run i.e. "v8", "v9" etc + + +local dirsep = "`c(dirsep)'" +if "`c(os)'" == "Windows" { + local dirsep = "\" +} + +local dir = "`c(pwd)'`dirsep'" +if `"`using'"' != "" { + // see if there is even one double quote in using + local subtest : subinstr local using `"""' `""' , count(local cnt) + if `cnt' != 0 { + di `"{help saswrapper:saswrapper} {error}cannot handle directory or file names that contain double quotes. "' + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(2) etime + } + exit 499 + } + + /* if filename is given with directory info too, + * strip to just file name and to dir location */ + if "`c(os)'" == "Windows" { + if index("`using'","/") { + local using : subinstr local using "/" "\" , all + } + } + if index("`using'","`dirsep'") { + local filen=substr("`using'",index("`using'","`dirsep'")+1,length("`using'")) + while index("`filen'","`dirsep'") !=0 { + local filen = substr("`filen'",index("`filen'","`dirsep'")+1,length("`filen'")) + } + local dir = substr("`using'",1,index("`using'","`filen'")-1) + } + else if index("`using'","\\\") == 1 { /* Universal naming convention */ + local filen = substr("`using'",index("`using'","\\\")+2,length("`using'")) + while index("`filen'","\") !=0 { + local filen = substr("`filen'",index("`filen'","\")+1,length("`filen'")) + } + local dir = substr("`using'",1,index("`using'","`filen'")-1) + } + else { /* no directory given */ + local filen = "`using'" + local dir = "`c(pwd)'`dirsep'" + } + + + /** extract file extension if there is one **/ + if index("`filen'",".") { + local ext=substr("`filen'",index("`filen'","."),length("`filen'")) + while index("`ext'",".") > 0 { + local ext = substr("`ext'",index("`ext'",".")+1,length("`ext'")) + } + local ext = ".`ext'" + local filen = substr("`filen'",1,index("`filen'",".")-1) + } + + if lower("`ext'") == "" { // guess that the user is wanting to use a .sas file + local using1 `"`using'.sas"' + local ext ".sas" + capture confirm file `"`using1'"' + if _rc == 0 { + capture confirm file `"`using'"' + if _rc == 0 { + di `"{error}The SAS file: "`using'" does exist, but so does the SAS file: "`using1'" '"' + di as text `"SAS will choose to run "`using1'" since it has the file extension ".sas" "' + /* log usage of saswrapper */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(3) etime + } + exit 601 + } + } + // only here if this file does exist + local using `"`using'.sas"' + } + else if lower("`ext'") != ".sas" { + di as error `" "`ext'" is an invalid file extension "' + di as error `"{help saswrapper:saswrapper} can only run SAS program files which have the file extension ".sas" "' + /* log usage of saswrapper */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(3) etime + } + exit 601 + } + + + capture confirm file `"`using'"' + if _rc != 0 { + di `"{error}The SAS file: `using' does not exist."' + /* log usage of saswrapper */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(3) etime + } + exit 601 + } +} // end of if "using" != "" + +local usasprog "`using'" + +if "`usasprog'" == "" & `"`pre_sas_prog'"' == "" & `"`post_sas_prog'"' == "" { + di as err `"no SAS code to run "' _n + /* log usage of saswrapper */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(3) etime + } + exit 601 +} + +/* set where temp directory is */ +tmpdir +local tmpdir `"`r(tmpdir)'"' + +local tfn = subinstr("`c(current_time)'",":","",.) +local sysjobid = substr("`tfn'",length("`tfn'")-5,length("`tfn'")) +local temp `"`macval(tmpdir)'_`sysjobid'"' + + +if "`nodata'" == "" { + if `"`savasas'"' == "" { + local stata_data `"`c(filename)'"' + if `: length local stata_data' != 0 { + capture _getfilename `"`stata_data'"' // get error message if only dir in using + local stata_data `"`r(filename)'"' // make using just the filename + local stata_data : subinstr local stata_data ".dta" "" // drop file extension + valid_dset_name, dset(`stata_data') `rename' + local stata_data = "`r(valid_dset_name)'" + } + else if `: length local stata_data' == 0 { + local stata_data = "stata_data" + } + } + else if `"`savasas'"' != "" { + valid_dset_name, dset(`savasas') `rename' + local stata_data = "`r(valid_dset_name)'" + } + + if "`stata_data'" == "" local stata_data = "stata_data" + + if "`check'" != "" { + di as result _n `"Compare results with SAS output that will be printed next "' + // no reason to set more off because if user quits no temp files have been written yet + local five_n = 5 + if _N < 5 { + local five_n = _N + } + summarize `varlist' `if' `in' + describe `varlist' + list `varlist' in 1/`five_n' + } + + di as result _n "now running {help savasas:savasas} to save the dataset `stata_data' to the SAS WORK library " + savasas `varlist' using "`temp'_statadata.sas7bdat" `if' `in' , `formats' `rename' `messy' /// + saswrapper saswrap_data(`stata_data') sysjobid(`sysjobid') +} + + +* WRITE SASWPAPPER SAS PROGRAM +* ---------------------------- +saswrapper_sas , dirsep("`dirsep'") dir("`dir'") tmpdir("`tmpdir'") temp("`temp'") filen(`filen') sysjobid(`sysjobid') /// + usasprog("`usasprog'") pre_sas_prog(`" `pre_sas_prog' "') post_sas_prog(`" `post_sas_prog' "') /// + rver(`rver') savastata("`savastata'") `quotes' `check' `float' `char2lab' char2fmt("`char2fmt'") /// + stata_data(`stata_data') `usesas' `nodata' + + +* RUN SAS +* ------- +if "`c(os)'" == "Unix" /* or Linux */ { + shell "`usas'" "`temp'_saswrapper.sas" -log "`temp'_saswrapper.log" -print "`temp'_saswrapper.lst" +} /* end of if Unix */ +else if "`c(os)'" == "Windows" /* Windows */ { + shell `wsas' "`temp'_saswrapper.sas" -nologo -log "`temp'_saswrapper.log" -print "`temp'_saswrapper.lst" +} /* end of if Windows */ + +capture confirm file `"`temp'_sascoderr.sas7bdat"' +if _rc == 0 { + tempfile saswrapper_output + copy `"`temp'_saswrapper.txt"' `"`saswrapper_output'"', text + + capture confirm file `"`saswrapper_output'"' + if _rc == 0 { + di as error _n "the submitted SAS code has an error in it " _n + } + // set usesas to missing so that saswrapper will fail gracefully + local usesas +} + +* LOOK AT ANY REPORT FROM SAS +* --------------------------- +capture confirm file `"`temp'_report.log"' +if _rc == 0 { + type `"`temp'_report.log"' + if "`messy'" == "" { + erase `"`temp'_report.log"' + } +} + + +if "`usesas'" != "" { + * CLEAR DATA OUT OF MEMORY + * ------------------------ + if "`clear'" != "" { + drop _all + label drop _all + } + + * LOAD STATA DATASET INTO MEMORY + * ------------------------------ + capture confirm file `"`temp'_infile.do"' + if _rc == 0 { + di as result _n "now loading the most recently created SAS dataset in submitted SAS program " + di as result " savastata SAS macro saved this dataset to Stata " _n + if `"`usrlog'"' != "" { + quietly log close + } + local cwd "`c(pwd)'" + ** cd to where infile.do is ** + quietly cd "`tmpdir'" + run `"_`sysjobid'_infile.do"' + if `"`usrlog'"' != "" { + quietly log using `"`usrlog'"' , append + } + + * SET DATASET NAME + * ---------------- + if index("$S_FN","`dirsep'") == 1 { + global S_FN : subinstr global S_FN "`dirsep'" "" + } + global S_FN `"`macval(dir)'$S_FN"' + + // run savastata_report to see if SAS and Stata agree how many obs and vars there are + savastata_report + di " " _n // insert a blank space + + ** cd back to where you were ** + quietly cd "`cwd'" + } /* if infile.do file exists */ + else { + di `"{error}{help saswrapper:saswrapper} failed."' + capture confirm file `"`temp'_knerror.txt"' + if _rc == 0 { + // savastata failed with a known error so just let report.log show the error + if "`c(os)'" != "Windows" { + usesasdel `"`tmpdir'"' _`sysjobid' + } + if "`c(os)'" == "Windows" { + local usesasdeldir : subinstr local tmpdir `":"' `"\\\`= char(58)'"', all + usesasdel `"`usesasdeldir'"' _`sysjobid' + } + } + else { + di `"{error}If no error message above this one, then check out the SAS log file to see why. "' + di `" {view "`temp'_saswrapper.log"} "' + di `" and {view "`temp'_saswrapper.txt"} "' + di `"{inp}Erase these temporary files created by {help saswrapper:saswrapper} when done with them:"' + di `"{res}(files located in "`tmpdir'") "' + ls "`temp'_*" + if "`c(console)'" != "console" { + if "`c(os)'" != "Windows" { + di `"{res} {stata usesasdel `"`tmpdir'"' _`sysjobid':Click here to erase them all.} "' + } + if "`c(os)'" == "Windows" { + local usesasdeldir : subinstr local tmpdir `":"' `"\\\`= char(58)'"', all + di `"{res} {stata usesasdel `"`usesasdeldir'"' _`sysjobid':Click here to erase them all.} "' + } + } + } + + if "`usasprog'" != "" { + di `""' + if "`c(console)'" != "console" { + di `"{inp}Click here to edit your SAS program and try it again. "' + di `" {stata `"doedit "`usasprog'""':`usasprog'} "' + } + else di `"Edit your SAS program: "`usasprog'" and try it again."' _n + } + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(6) etime + } + exit 499 + } +} //end of if usesas + + +capture confirm file `"`temp'_saswrapper.txt"' +if _rc == 0 { + tempfile saswrapper_output + copy `"`temp'_saswrapper.txt"' `"`saswrapper_output'"', text +} + + +* CLEAN UP TEMP FILES +* ------------------- +if "`messy'"=="" { + if "`c(os)'" != "Windows" { + usesasdel `"`tmpdir'"' _`sysjobid' + } + if "`c(os)'" == "Windows" { + local usesasdeldir : subinstr local tmpdir `":"' `"\\\`= char(58)'"', all + usesasdel `"`usesasdeldir'"' _`sysjobid' + } +} /* end of messy */ +else { + di "{res}You have requested {help saswrapper:saswrapper} not to delete the intermediary files" /// + " created by {help saswrapper:saswrapper}:" + dir "`temp'_*" + di "{input}Files located here: " + di `"{input}"`tmpdir'" "' + + if "`c(console)'" != "console" { + if "`c(os)'" != "Windows" { + di `"{res} {stata usesasdel `"`tmpdir'"' _`sysjobid':Click here to erase them all.} "' + } + if "`c(os)'" == "Windows" { + local usesasdeldir : subinstr local tmpdir `":"' `"\\\`= char(58)'"', all + di `"{res} {stata usesasdel `"`usesasdeldir'"' _`sysjobid':Click here to erase them all.} "' + } + } +} // of if else if messy + + +// this is 2nd to last since user may break -more- which cancels saswrapper +capture confirm file `"`saswrapper_output'"' +if _rc == 0 { + di as result "the following is the results of the SAS program: " _n + type `"`saswrapper_output'"' +} + +// this is last since user may break -more- which cancels saswrapper +if "`usesas'" != "" { + if "`check'" != "" { + local gsfn : subinstr global S_FN ".dta" "" + display as res _n " Compare these results with the results provided by SAS " + display as res " in the file `gsfn'_SAScheck.lst. " _n + local five_n = 5 + if _N < 5 { + local five_n = _N + } + summarize + describe + list in 1/`five_n' + + di _n "You have requested to have savastata provide a check file:" + di `""`gsfn'_SAScheck.lst" "' _n + } +} + +end /* end of saswrapper */ + + +program define saswrapper_sas, nclass +syntax [, dirsep(string) dir(string) tmpdir(string) temp(string) filen(string) sysjobid(string) /// + usasprog(string) pre_sas_prog(string) post_sas_prog(string) /// + rver(string) savastata(string) quotes check float char2lab char2fmt(string) /// + stata_data(string) usesas NODATA] +version 8 + + +quietly { + file open sasfile using `"`temp'_saswrapper.sas"', replace text write + + file write sasfile `"* saswrapper SAS program *; "' _n _n /// + `" options nonotes nofmterr nocenter linesize=`c(linesize)' source2;"' _n _n /// + `" ** need to create this file now as may only be able to *"' _n /// + `" * erase it later. **; "' _n /// + `" libname _saswrap "`tmpdir'"; "' + + file write sasfile `"* sas error test *; "' _n _n /// + `" data _saswrap._`sysjobid'_sascoderr; "' _n /// + `" do i = 1 to 1; "' _n /// + `" message="submitted SAS code has an error"; "' _n /// + `" end; "' _n /// + `" run; "' _n /// + `" %let syslast=; "' _n + + + if "`stata_data'" != "" { // put data (and formats catalog file) into WORK library + capture confirm file `"`temp'_statadata.sas7bdat"' + if _rc == 0 { + file write sasfile `" proc datasets library= _saswrap; "' _n /// + `" copy in= _saswrap out= work move; "' _n /// + `" select _`sysjobid'_statadata (memtype= data); "' _n /// + `" run; "' _n _n + file write sasfile `" proc datasets library= work; "' _n /// + `" change _`sysjobid'_statadata = `stata_data' / memtype= data; "' _n /// + `" run; "' _n /// + `" quit; "' _n _n /// + `" %let syslast=work.`stata_data'; "' _n _n + } + capture confirm file `"`temp'_statadata.sas7bcat"' + if _rc == 0 { + file write sasfile `" proc datasets library= _saswrap; "' _n /// + `" copy in= _saswrap out= work move; "' _n /// + `" select _`sysjobid'_statadata (memtype= catalog); "' _n /// + `" run; "' _n _n + + file write sasfile `" proc datasets library= work; "' _n /// + `" change _`sysjobid'_statadata = formats / memtype= catalog; "' _n /// + `" run; "' _n /// + `" quit; "' _n _n + } + } + + file write sasfile `" proc printto print="`temp'_saswrapper.txt" log="`temp'_saswrapper.txt"; "' _n /// + `" run; "' _n _n /// + `" options notes; "' _n _n + + if "`check'" != "" & "`nodata'" == "" { + file write sasfile `" "' _n /// + `" /****** THE FOLLOWING IS THE DATA CHECK YOU REQUESTED ******/ "' _n + + file write sasfile `" "' _n /// + `" proc means data=work.`stata_data'; "' _n /// + `" run; "' _n _n /// + `" proc contents data=work.`stata_data'; "' _n /// + `" run; "' _n _n /// + `" proc print data=work.`stata_data' (obs=5); "' _n /// + `" run; "' _n + + file write sasfile `" "' _n /// + `" /************ END OF THE DATA CHECK YOU REQUESTED **********/ "' _n + } + + if `"`pre_sas_prog'"' != " " { // two spaces because pre_sas_prog(`" `pre_sas_prog' "') + file write sasfile `" "' _n _n /// + `" /********* THE FOLLOWING IS YOUR pre_sas_prog CODE *********/ "' _n _n + + local len_pre_sas_prog : length local pre_sas_prog + if `len_pre_sas_prog' < 256 { // 256 is the max but there is a space at beginning and end + file write sasfile `" `pre_sas_prog' "' _n _n + } + else { + tokenize `" `pre_sas_prog' "', parse(";") + local orig_length : length local pre_sas_prog + local nosemis : subinstr local pre_sas_prog ";" "", all + local s_length : length local nosemis + // tokenize puts the semicolons in the even numbered macro vars + local n_semis = (`orig_length' - `s_length' ) * 2 + + local odd = 1 + forval line = 1/`n_semis' { + if `odd' == 3 { + local odd = 1 + } + if `odd' == 1 { // tokenize puts the semicolons in the even numbered macro vars + file write sasfile `" ``line''; "' _n _n + } + local odd = `odd' + 1 + } + } + // the following semi-colon is there in case user forgot to end their code with one. + file write sasfile `" ; "' _n _n /// + `" /************** END OF YOUR pre_sas_prog CODE **************/ "' _n _n + } + + if "`usasprog'" != "" { /* user submitted a SAS program */ + file write sasfile `" "' _n _n /// + `" /********* THE FOLLOWING IS YOUR SAS PROGRAM *********/ "' _n _n /// + `" %include"`usasprog'"; "' _n _n /// + `" /************** END OF YOUR SAS PROGRAM **************/ "' _n _n + } + + if `"`post_sas_prog'"' != " " { // two spaces because pre_sas_prog(`" `post_sas_prog' "') + file write sasfile `" "' _n _n /// + `" /********* THE FOLLOWING IS YOUR post_sas_prog CODE *********/ "' _n _n + local len_post_sas_prog : length local post_sas_prog + if `len_post_sas_prog' < 256 { // 256 is the max but there is a space at beginning and end + file write sasfile `" `post_sas_prog' "' _n _n + } + else { + tokenize `" `post_sas_prog' "', parse(";") + local orig_length : length local post_sas_prog + local nosemis : subinstr local post_sas_prog ";" "", all + local s_length : length local nosemis + // tokenize puts the semicolons in the even numbered macro vars + local n_semis = (`orig_length' - `s_length' ) * 2 + local odd = 1 + forval line = 1/`n_semis' { + if `odd' == 3 { + local odd = 1 + } + if `odd' == 1 { // tokenize puts the semicolons in the even numbered macro vars + file write sasfile `" ``line''; "' _n _n + } + local odd = `odd' + 1 + } + } + file write sasfile `" "' _n _n /// + `" /************** END OF YOUR post_sas_prog CODE **************/ "' _n _n + } + + // the following semi-colon is there in case user forgot to end their code with one. + file write sasfile `" ; proc printto; "' _n /// + `" run; "' _n /// + `" quit; ** close up anything they might have left going **; "' _n _n + + if `"`usesas'"' != "" { + file write sasfile `" %let sortedby=; ** leave in for now **; "' _n _n /// + `"%macro makework; "' _n /// + `" run; "' _n /// + `" %let nobs=%sysfunc(getoption(obs)); "' _n /// + `" %if &syserr.^=0 or &nobs.=0 or "&syslast."="_NULL_" %then %do;"' _n /// + `" %goto nevrmind; "' _n /// + `" %end; "' _n /// + `" %let syslast1=&syslast.; "' _n _n + file write sasfile `" proc datasets library= _saswrap; "' _n /// + `" copy in= _saswrap out= work move; "' _n /// + `" select _`sysjobid'_sascoderr (memtype= data); "' _n /// + `" run; "' _n _n /// + `" quit; "' _n _n /// + `" %let syslast=&syslast1.; "' _n _n + + file write sasfile `"%if "&syslast." ^= "_NULL_" %then %do; "' _n /// + `" %let ldset=%length(&syslast.); "' _n /// + `" %let decpos=%index(&syslast.,.); "' _n /// + `" %let llib=%substr(&syslast.,1,&decpos.-1); "' _n /// + `" %let dset=%substr(&syslast.,&decpos.+1,&ldset.-&decpos.); "' _n /// + `" %let dset=%sysfunc(lowcase(%nrbquote(&dset.))); "' _n _n + file write sasfile `" data _null_; "' _n /// + `" dsid=open("&syslast.",'i');"' _n `" sortedby=attrc(dsid,'SORTEDBY'); "' _n /// + `" call symput('sortedby',trim(sortedby));"' _n `" rc=close(dsid);"' _n `" run;"' _n _n + file write sasfile `" %if %index(%upcase(&sortedby.),DESCENDING) %then %do; "' _n /// + `" %* this is how Stata treats descending sortedby *; "' _n /// + `" %let sortedby= %substr(&sortedby.,1,%index(%upcase(&sortedby.),DESCENDING)-1); "' _n /// + `" %end;"' _n _n + file write sasfile `" ** if not in work make it be in work **; "' _n /// + `" %if %index(%upcase(&syslast.),WORK)^=1 %then %do; "' _n /// + `" data work.&dset.; "' _n /// + `" set &syslast.;"' _n `" run; "' _n /// + `" %end; ** end of if syslast is not in WORK **; "' _n _n /// + `" %end; ** end of if syslast is _NULL_ **; "' _n _n + + + file write sasfile `" %nevrmind: ; "' _n /// + `"%mend makework; "' _n /// + `"%makework; "' + + if `c(stata_version)' < 9 & "`char2lab'" != "" { + noisily { + di as error `"option char2lab is not allowed prior to Stata 9."' + di as error `"option will be ignored."' + local char2lab "" + } + } + file write sasfile _n _n /// + `"%macro runit; "' _n _n /// + `" %let nobs=%sysfunc(getoption(obs)); "' _n /// + `" %if &syserr.^=0 or &nobs.=0 or "&syslast." = "_NULL_" %then %do;"' _n /// + `" proc printto log="`temp'_saswrapper.txt"; "' _n /// + `" run; "' _n /// + `" %put %upcase(error:) no dataset in SAS to load into Stata; "' _n /// + `" %goto nevrmind; "' _n /// + `" %end; "' _n + // need to put c(SE) and c(MP) in quotes since c(MP) doesn't exist in Stata 8 + // need to pass a zero or a one to savastata for SE or MP + file write sasfile `" options nomprint nosource2; "' _n _n + file write sasfile `" %include "`savastata'"; "' _n /// + `" libname ___dir__ "`dir'" ; %* directory where _SAScheck.lst is saved to *; "' _n /// + `" %let _dir=%nrbquote(%sysfunc(pathname(___dir__))); "' _n /// + `" /* &sortedby. is global because of: call symput creates it */ "' _n /// + `" %savastata("`tmpdir'",`quotes' `char2lab' `check' messy `float',&sortedby., "' /// + `" `sysjobid',nosave,"&_dir.`dirsep'",`= ("`c(SE)'" == "1") + ("`c(MP)'" == "1")', "' /// + `" version=`c(stata_version)'); "' _n /// + `" %nevrmind: ; "' _n /// + `"%mend runit;"' _n `"%runit;"' _n + } // end of if usesas + + file close sasfile + +} /* end of quietly */ +end + + +program valid_dset_name, rclass +syntax , dset(string) [rename] + version 8 + +local filen `dset' + +local fc = substr("`filen'",1,1) + +local swn = "0" +local hsc = "0" +if inlist("`fc'","0","1","2","3","4") | /// + inlist("`fc'","5","6","7","8","9") { // name starts with a number + local swn = "1" +} + +if index("`filen'","~") | /// Has a bad character in name + index("`filen'","!") | /// + index("`filen'","@") | /// + index("`filen'","#") | /// + index("`filen'","$") | /// + index("`filen'","%") | /// + index("`filen'","^") | /// + index("`filen'","&") | /// + index("`filen'","*") | /// + index("`filen'","(") | /// + index("`filen'",")") | /// + index("`filen'","-") | /// + index("`filen'","+") | /// + index("`filen'","=") | /// + index("`filen'","[") | /// + index("`filen'","]") | /// + index("`filen'",":") | /// + index("`filen'",";") | /// + index("`filen'","'") | /// + index("`filen'","<") | /// + index("`filen'",">") | /// + index("`filen'","?") | /// + index("`filen'",",") | /// + index("`filen'","|") | /// + index("`filen'"," ") | /// + index("`filen'","{") | /// + index("`filen'","}") { + local hsc = "1" +} + +if "`swn'" == "1" | "`hsc'" == "1" { + if "`rename'"=="" { + di `"{error}File name {res}"`filen'" {error}is not a valid SAS file name. *"' + if "`swn'" == "1" { + di `"{error}SAS file names cannot start with a number. *"' + } + if "`hsc'" == "1" { + di `"{error}SAS file names cannot contain special characters. *"' + } + } + if "`hsc'" == "1" { + // remove bad characters + foreach char in ~ ! @ # $ % ^ & * ( ) - + = [ ] : ; ' < > ? , | { + local filen = subinstr("`filen'","`char'","_",.) + } + local filen = subinstr("`filen'","{","_",.) + local filen = subinstr("`filen'","}","_",.) + local filen = subinstr("`filen'"," ","_",.) + + if `"`: subinstr local filen "_" "" , all'"' == "" { // if nothing left, meaning, person used all bad characters + local filen= "okpopeye" + } + } // end of contains bad character + + if "`swn'" == "1" { // name starts with a number + if length("`filen'") == 32 { + local filen = substr("`filen'",2,length("`filen'")) + local filen = "_`filen'" + } + else { + local filen ="_`filen'" + } + } // end of if started with number + if "`rename'" == "" { + di `"{error}The {res}rename {error}option will rename it for you to be: {res}"`filen'" "' + /* log usage of saswrapper */ + capture which usagelog + if _rc==0 { + usagelog , type(savas) uerror(6) etime + } + exit 198 + } +} /* if filen is not a valid SAS data file name */ + +return local valid_dset_name `filen' + +end diff --git a/Modules/ado/plus/s/saswrapper.hlp b/Modules/ado/plus/s/saswrapper.hlp new file mode 100644 index 0000000..e1c130d --- /dev/null +++ b/Modules/ado/plus/s/saswrapper.hlp @@ -0,0 +1,207 @@ +{smcl} +{* version 1.0 26Feb2009}{...} +{hline} +help for {hi:saswrapper} {right:manual: {hi:[R] none}} +{right:dialog: {hi: none} } +{hline} + + +{title:Run a SAS program from within Stata} + +{p 8 17 2} +{cmd:saswrapper} +[{varlist}] +{ifin} +[{cmd:using} {it:sas program filename}] +[{cmd:,} +{cmdab:pre:_sas_prog(`"}{it:sas code}{cmd:"')} +{cmdab:post:_sas_prog(`"}{it:sas code}{cmd:"')} +{cmdab:ch:eck} +{cmdab:me:ssy} +{cmd:usesas} +{cmd:nodata} +{cmd:savasas(}{it:sas dataset name}{cmd:)} +{cmd:noformats} +{cmd:rename} +{cmd:clear} +{cmd:char2lab} +{cmd:float} +{cmdab:qu:otes}]{p_end} + + +{title:Description} + +{p 4 4 2}{cmd:saswrapper} runs a SAS program in batch and prints the output in the Stata results window/log file. +This usually occurs by specifying a SAS program file after {cmd:using}, but {cmd:saswrapper} can also run +SAS code specified by the {cmd:pre_sas_prog()} and/or {cmd:post_sas_prog()} options. By default, {cmd:saswrapper} +will save the current data in memory using {help savasas:savasas} and make it available in SAS's WORK library. If +that is not desired, use the {cmd:nodata} option. The {cmd:usesas} option tells {cmd:saswrapper} to load the +last SAS dataset created in the WORK library by the submitted SAS program into Stata using the {cmd:SAVASTATA} SAS macro.{p_end} + +{p 4 4 2}{cmd:NOTE: saswrapper} calls SAS to run the SAS program. This requires the ability to run SAS on your computer. +If {cmd:saswrapper} does not run SAS for you, your {cmd:sasexe.ado} file may need to be edited to set the location of your +SAS executable file ({cmd:sas.exe}) and your {cmd:SAVASTATA} SAS macro file ({cmd:savastata.sas}). +It may be that {cmd:saswrapper} will be able to run with the default settings in {cmd:sasexe.ado}. See the +{help saswrapper##setup:setup instructions} below.{p_end} + +{p 4 4 2}{cmd:saswrapper} uses the {cmd:SAVASTATA} SAS macro to create the Stata dataset from the SAS dataset when the +{cmd:usesas} option is specified. {cmd:saswrapper} downloads the {cmd:SAVASTATA} SAS macro and stores it where +user-written Stata ado-files are stored that begin with the letter "s". This macro can be used in SAS. +Learn about {cmd:SAVASTATA} here: +{browse "http://faculty.fuqua.duke.edu/~blanc004/sas_to_stata/savastata.html":http://faculty.fuqua.duke.edu/~blanc004/sas_to_stata/savastata.html }{p_end} + + +{title:Options} + +{p 4 8 2}{cmd:using} {it:sas program filename} specifies {cmd:saswrapper} to run this SAS program. {cmd:saswrapper} +assumes the SAS program file extension {cmd:.sas} if no file extension/suffix is specified.{p_end} + +{p 4 8 2}{cmd:pre_sas_prog()} and/or {cmd:post_sas_prog()} contain SAS code to be run by {cmd:saswrapper}. If SAS +programming code is supplied by {cmd:using}, {cmd:pre_sas_prog()}, and {cmd:post_sas_prog()} then the order the +code will be run is:{p_end} + +{p 14 18 2}{cmd:pre_sas_prog()}{p_end} + +{p 14 18 2}{cmd:using}{p_end} + +{p 14 18 2}{cmd:post_sas_prog()}{p_end} + +{p 8 8 2}It is best to enclose the SAS code within compound double quotes:{p_end} + +{p 8 8 2}{cmd:. saswrapper, pre_sas_prog(`"proc means;"') }{p_end} + +{p 8 8 2} in case the SAS code contains any double quotes. An interesting way to submit SAS code is +to first put it in a {help local:local} macro and use three forward slashes to continue the line:{p_end} + +{p 8 8 2}{cmd:. local pre_sas_prog data new; /// }{p_end} +{p 8 8 2}{cmd: set work.stata_data; /// }{p_end} +{p 8 8 2}{cmd: gender = "female"; /// }{p_end} +{p 8 8 2}{cmd: run; }{p_end} + +{p 8 8 2}{cmd:. saswrapper , pre_sas_prog(`" `pre_sas_prog' "')}{p_end} + +{p 8 8 2}You can put a lot of SAS code in a {help local:local} macro if you don't use an equal sign ({cmd:=}) +after then local macro name. For the above example to work, Stata has to be using the carriage +return as an end-of-line delimiter and not semi-colons which is changed by the {help #delimit:#delimit} +command. Stata will see Stata-style {help comments:comments} in the SAS code as Stata comments so +avoid starting a line with a star/asterisk "*":{p_end} + +{p 8 8 2}{cmd: * some comment ; /// }{p_end} + +{p 8 8 2} because Stata will comment out the three forward slashes at the end and thus end the input to the +local macro. Since the contents of the local macro will be one long line, do not attempt to do anything +in your SAS code that expects carriage returns like the SAS datalines statement that reads in raw data.{p_end} + +{p 4 8 2}{cmd:check} specifies to generate basic stats for both the SAS and Stata datasets for the user +to make sure {cmd:saswrapper} created the files correctly. This is a comparison that should be done after +any datafile is converted to any other type of datafile by any software. The SAS file is created in the +same directory as the SAS program specified in {cmd:using} or if no program was specified in {cmd:using} +then it will be created in the current directory. The file is named starting with the name of the datafile +followed by "_SAScheck.lst" (SAS). e.g. "mySASdata_SAScheck.lst"{p_end} + +{p 4 8 2}{cmd:messy} specifies that all the intermediary files created by {cmd:saswrapper} during its operation +are not to be deleted. The {cmd:messy} option prevents {cmd:saswrapper} from cleaning up after it has +finished. This option is mostly useful for debugging purposes in order to find out where something went +wrong. All intermediary files have a name starting with an underscore "_" followed by the process ID and +are located in Stata's temp directory.{p_end} + +{p 4 8 2}{cmd:usesas} specifies to load the SAS dataset into memory that was most recently created in the +SAS WORK library in the SAS program submitted to {cmd:saswrapper}. {cmd:saswrapper} figures out how much +memory the SAS dataset will require to be loaded into Stata and sets Stata's memory for you if your memory +setting is less than is required.{p_end} + + +{p 4 8 2}{cmd:nodata} specifies to override the default behavior of {cmd:saswrapper} which is to save the +current dataset in memory to the SAS WORK library. Use this option when your SAS program is not going to +use the dataset in memory.{p_end} + +{p 4 8 2}{cmd:savasas} specifies a different dataset name than the name of the dataset in memory. +If the dataset in memory does not have a name and the option {cmd:savasas} is not used, then the +dataset in memory will be available in SAS's WORK library as "stata_data" (a.k.a. "WORK.STATA_DATA").{p_end} + +{title:Options when saving data to SAS} + +{p 4 8 2}{cmd:varlist} specifies what selection of variables in the dataset in memory are to be saved +to the SAS dataset in the WORK library in the SAS program submitted to {cmd:saswrapper}. If no variables +are specified then all variables will be saved the SAS dataset.{p_end} + +{p 4 8 2}{cmd:if} {it:exp} subsets the dataset in memory before saving the dataset to the SAS dataset in +the WORK library in the SAS program submitted to {cmd:saswrapper}.{p_end} + +{p 4 8 2}{cmd:in} {it:range} subsets the dataset in memory before saving the dataset to the SAS dataset in +the WORK library in the SAS program submitted to {cmd:saswrapper}.{p_end} + +{p 4 8 2}{cmd:noformats} specifies that no value labels be saved as SAS formats.{p_end} + +{p 4 8 2}{cmd:rename} specifies that any required renaming of file name and/or variable names is +to be done when saving the dataset in memory to SAS using {help savasas:savasas}. The {cmd:rename} +option is only necessary when variable names are not unique in SAS. {cmd:savasas} displays the list +of renamed variables. {cmd:rename} also renames the SAS file name when the name provided is not a +valid SAS file name.{p_end} + +{title:Options when using the usesas option} + +{p 4 8 2}{cmd:clear} specifies to clear the data currently in memory before running {cmd:saswrapper}.{p_end} + +{p 4 8 2}{cmd:char2lab} specifies to encode long SAS character variables like the Stata +command {help encode:encode}. Character variables that are too long for a Stata string +variable are maintained in value labels.{p_end} + +{p 4 8 2}{cmd:float} specifies that numeric variables that would otherwise be stored as numeric type +double be stored with numeric type float. This option should only be used if you are certain you +have no integer variables that have more than 7 digits (like an id variable).{p_end} + +{p 4 8 2}{cmd:quotes} specifies that double quotes that exist in string variables are to be replaced +with single quotes. Since the data are written out to an ASCII file and then read into Stata, +there are rare instances when double quotes are not allowed inside string variables.{p_end} + + + +{title:Examples} + +{p 4 8 2}{cmd:. saswrapper using "mySASprog.sas" }{p_end} + +{p 4 8 2}{cmd:. saswrapper using "mySASprog.sas", nodata usesas clear }{p_end} + +{p 4 8 2}{cmd:. saswrapper using "c:\data\mySASprog.sas", savasas(tester) check }{p_end} + +{p 4 8 2}{cmd:. saswrapper , pre_sas_prog(`" proc print; "')}{p_end} + +{p 4 8 2}{cmd:. saswrapper , pre(`" data new; set work.stata_data; if income > 0 then do; employed = 1; output; end; run; "') usesas clear}{p_end} + +{p 4 8 2}{cmd:. saswrapper , post(`" proc univariate; "')}{p_end} + + + +{p 4 8 2}{cmd:NOTE:} If you are setting up this program on your computer for +the first time, please edit sasexe.ado to set the location of your SAS +executable file (sas.exe). If you do not, {cmd:saswrapper} will try to set it +for you. The sasexe.ado file is an ASCII text file and should +be saved as such after editing. Stata's {cmd:do-file} editor will do the trick.{p_end} + +{marker setup} +{title:Setting up saswrapper} + +{p 4 4 2} +If you are setting up this program on your computer for the first time, you may need to edit the {cmd:sasexe.ado} file to +set the location of your SAS executable file ({cmd:sas.exe}). If you do not, {cmd:saswrapper} will look in the "usual" +locations for it. {cmd:saswrapper} also may need to have the location of the SAS macro {cmd:savastata.sas} set. The +{cmd:sasexe.ado} file is an ASCII text file and should be saved as such after editing. Stata's do-file editor will do +the job. {stata quietly adoedit sasexe:edit sasexe.ado} (click, to edit the {cmd:sasexe.ado} file, remember to save when +done.){p_end} + + +{title:Author} + +{p 4 4 2} +Dan Blanchette {break} +Center of Entrepreneurship and Innovation {break} +Duke University's Fuqua School of Business {break} +Dan.Blanchette@Duke.edu{p_end} + + +{title:Also see} + +{p 4 13 2}On-line: {help savasas:savasas}, {help usesas:usesas}{p_end} + + diff --git a/Modules/ado/plus/s/savasas.ado b/Modules/ado/plus/s/savasas.ado new file mode 100644 index 0000000..8f7c51a --- /dev/null +++ b/Modules/ado/plus/s/savasas.ado @@ -0,0 +1,1967 @@ +*! savasas Version 2.1 dan.blanchette@duke.edu 12Mar2009 +*! Center of Entrepreneurship and Innovation Duke University's Fuqua School of Business +** - made savasas able to be run by saswrapper +** - added some date formats, and made it so that any date format will be kept at least as +** mmddyy10. format in SAS +** savasas Version 2.0 dan_blanchette@unc.edu 03Jul2008 +** research computing, unc-ch +** - created check to make sure user is not trying to create a SAS datafile named with +** more than 32 characters in the name. +** - created a check to make sure SAS ran without errors. If not, then messy option is turned on. +** - fixed the string comparison that generated the the "too many literals" error message +** when saving long value labels as user-defined SAS formats +** - fixed all long string comparisons +** - fixed it so savas does not accidently find an error message in the savasas log +** - added dataset label saying savasas created dataset on date +** - added error message that -savasas- cannot be run in Stata batch in Windows +** - made it so that variable labels can contain macro var references etc. +** - no longer dealing with sortedby vars since SAS and Stata sort orders are different +** depending on missing values and DESCENDING sorts +** savasas Version 1.4 dan_blanchette@unc.edu 29May2007 +** - fixed ability to save special missing values with value label as SAS formats +** - now label values of negative numbers are also saved as SAS formats +** - fixed dataset filenames when using the sascode option +** savasas Version 1.3 dan_blanchette@unc.edu 08Aug2006 +** - fixed it so that vars with non-existent value labels don't throw things off. +** - fixed situation where value labels with invalid SAS format names were not +** haiving the rename format assigned to all variables. +** - added ability to tell savasas where the SAS executable is, but for non-windows os's only. +** savasas Version 1.2 dan_blanchette@unc.edu 05Aug2005 +** - updated to allow for up to 32 character format value names now possible with SAS 9 +** and maintain Stata 9 value labels up to 32,000 characters to SAS 9 as well. +** - totally changed how value label names are checked +** - now using -labvalclone- by Nick Cox included at bottom of file +** - no longer using -uselabel- +** - now only trimming off trailing blanks for string variables (no longer trimming leading blanks) +** savasas Version 1.1 dan_blanchette@unc.edu 04Nov2004 +** - added ability to save data when directory path provided but no SAS file name provided +** - now allows for SAS file to be saved in a directory using universal filenaming convention e.g."\\\MyServer\sys1\projects\sasf.sas7bdat" +** - fixed check option so that it only checks the vars and obs specified in the "if and in" if one or both were specified +** savasas Version 1.1 dan_blanchette@unc.edu 10Sep2004 +** - SAS 9 doesn't support .sd7 as a file extension so -savasas- no longer does for any version of SAS +** savasas Version 1.1 dan_blanchette@unc.edu 13Jul2004 +** savasas Version 1.1 dan_blanchette@unc.edu 15Nov2003 +** - fixed "keep if in" to select subset of observations +** and sortedby varnames when longer than 8 characters +** savasas Version 1.0 dan_blanchette@unc.edu 27Oct2003 +** the carolina population center, unc-ch + +program define savasas, rclass + version 8.1 /* using fdasave */ +syntax [varlist] [using/] [in] [if] [, replace sascode Type(string) FORmats udir(string) /// + MEssy CHeck REName script usas(string) saswrapper /// + saswrap_data(string) sysjobid(string) ] + + + +/* log usage of savasas */ +capture which usagelog +if _rc == 0 { + usagelog , start type(savas) message(`"savasas using `using' `in' `if' , `replace' `sascode' type(`type') `formats' `messy' `check' `rename' "') `script' + usagelog , type(savas) message("Input Stata dataset has `c(N)' obs and `c(k)' vars") +} + +if "`c(os)'" == "Windows" & "`c(mode)'" == "batch" { + di as err "{help savasas:savasas} cannot be run in batch mode on Windows" + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(8) etime + } + exit 499 +} + + +capture which fdasave +if _rc != 0 { + di `"{error}You need an up to date Stata 8 to run {browse "http://www.cpc.unc.edu/services/computer/presentations/sas_to_stata/savastata.html":savasas}. {help savasas:savasas} {error}uses the {res}fdasave {error}command."' + + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(1) etime + } + exit _rc +} + + +* FIGURE OUT WHERE SAS EXECUTABLE IS +* ---------------------------------- +if "`saswrapper'" != "" { + local quietly quietly +} +`quietly' sasexe savasas `sascode' `usas' + +local wsas `r(wsas)' +local usas `r(usas)' +local rver `r(rver)' // version of sas that's being run i.e. "v8", "v9" etc + + +* FIGURE OUT FILENAME and DIRECTORY +* --------------------------------- +// see if there is even one double quote in using +local subtest : subinstr local using `"""' `""' , count(local cnt) +if `cnt' != 0 { + di `"{help savasas} {error}cannot handle directory or file names that contain double quotes. "' + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(2) etime + } + exit 499 +} + +if `: length local using' == 0 { // using is empty so try c(filename) + local filename "`c(filename)'" + if `: length local filename' != 0 { + local subtest : subinstr local filename `"http://"' `""' , count(local cnt) + if `cnt' != 0 { + capture _getfilename `"`filename'"' // get error message if only dir in using + local using `"`r(filename)'"' // make using just the filename + } + else { // use the file name and directory of the Stata dataset in memory + local using="`filename'" + } + } + else if `: length local filename' == 0 { + di "{error}No file name provided to save data." + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(4) etime + } + exit 198 + } +} + +// now process using +/* `: length local using' != 0 */ + +local subtest : subinstr local using `"/"' `""' , count(local cnt) +if `cnt' != 0 & "`c(os)'" == "Windows" { + local using : subinstr local using "/" "\" , all +} +if "`c(os)'" == "Windows" { + local dirsep="\" +} +else { + local dirsep="`c(dirsep)'" +} + +** if file name is given with directory info too, + * strip to just file name and to dir location +// see if using contains directory info +local subtest : subinstr local using `"`dirsep'"' `""' , count(local cnt) +if `cnt' != 0 { // Universal naming convention okay here + capture _getfilename `"`using'"' // get error message if only dir in using + local filen `"`r(filename)'"' + if "`filen'" != "" { // dir and filename in using + local dir : subinstr local using `"`filen'"' `""' + } + else if `: length local using' != 0 { // only directory in using + local dir `"`using'"' + _getfilename `"`c(filename)'"' + local filen `"`r(filename)'"' + } +} +else { // no directory given + local filen="`using'" + local dir ="`c(pwd)'`dirsep'" +} + + +local subtest : subinstr local dir `"/"' `""' , count(local cnt) +if `cnt' != 0 & "`c(os)'" == "Windows" { + local dir : subinstr local dir "/" "\" , all +} +confirmdir `"`dir'"' +if _rc != 0 { + local rc _rc + di `"{error}The directory "`dir'" does not exist."' + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(16) etime + } + exit `rc' +} + + +// filen could still be empty +if `"`filen'"' == `""' { + di "{error}No file name provided to save data." + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(14) etime + } + exit 198 +} + + +* Data will be changed during program so preserve it so that it will +* be restored after program finishes running +preserve + + +* FIX TYPE +* -------- +if lower("`type'") == "" | index(lower("`type'"),"sas7") /// + | index(lower("`type'"),"sas8") /// + | index(lower("`type'"),"sas9") { + local type "sas" + } +else if lower("`type'") == "ssd01" | lower("`type'") == "sas6" | lower("`type'") == "sd2" { + local type "sas6" + } +else if index(lower("`type'"),"x") | index(lower("`type'"),"tran") { + local type "sasx" + } + + +* IF/IN +* ----- + +if `: length local if' != 0 | `: length local in' != 0 { + quietly keep `if' `in' +} + + +keep `varlist' + +if `c(N)' == 0 { + di as error "{help savasas:savasas} cannot save your dataset because it has no observations. *" + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(5) etime + } + exit 2000 +} + +di _n "{txt}Selected dataset contains {result}`c(N)' {txt}observations and {result}`c(k)' {txt}variables. *" + +// because savasas needs to test that vars are all unique -rename- is used which +// temporarily creates the new var plus a tempvar so that adds 2 variables for a bit +if `c(k)' > 32765 { + di as error "{help savasas:savasas} can only handle datasets up to 32,765 variables" + di as error "Your dataset has `c(k)' variables." + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(17) etime + } + exit 103 +} +if `c(k)' > 1000 | `c(N)' > 50000 { + di _n "{txt}This may take a few minutes. *" +} + + +* DATA LIST +* --------- + + // extract file extension if there is one +if index("`filen'",".sas7bdat") & index("`filen'",".sas7bdat") == length("`filen'") - 8 { + local ext = ".sas7bdat" + local type = "sas" +} +else if index("`filen'",".sd7") & index("`filen'",".sd7") == length("`filen'") - 3 { + if "`c(os)'" == "Windows" { + local ext = ".sas7bdat" + di "{error}Starting with SAS 9 short filename extensions are no longer supported." + di "{error}Your output SAS datafile will end in .sas7bdat instead of .sd7." + di "{error}If you are still using an earlier version of SAS, rename the file after it is saved if you like." + local type = "sas" + /* local shortfileext="shortfileext" */ + } + else { + local ext = ".sas7bdat" + local type = "sas" + } +} +else if index("`filen'",".ssd01") & index("`filen'",".ssd01") == length("`filen'") - 5 /* + */ & "`c(os)'" == "Unix" & "`c(machine_type)'" != "PC" { + local ext = ".ssd01" + local type = "sas6" +} +else if index("`filen'",".ssd02") & index("`filen'",".ssd02") == length("`filen'") - 5 /* + */ & "`c(os)'" == "Unix" & "`c(machine_type)'" == "PC" { + local ext = ".ssd02" + local type = "sas6" +} +else if index("`filen'",".sd2") & index("`filen'",".sd2") == length("`filen'") - 3 /* + */ & "`c(os)'" == "Windows" & "`c(machine_type)'" == "PC" { + local ext = ".sd2" + local type = "sas6" +} +else if index("`filen'",".xpt") & index("`filen'",".xpt") == length("`filen'") - 3 { + local ext = ".xpt" + local type = "sasx" +} +else if index("`filen'",".xport") & index("`filen'",".xport") == length("`filen'") - 5 { + local ext = ".xport" + local type = "sasx" +} +else if index("`filen'",".export") & index("`filen'",".export") == length("`filen'") - 6 { + local ext = ".export" + local type = "sasx" +} +else if index("`filen'",".expt") & index("`filen'",".exp") == length("`filen'") - 3 { + local ext = ".exp" + local type = "sasx" +} +else if index("`filen'",".v5x") & index("`filen'",".v5x") == length("`filen'") - 3 { + local ext = ".v5x" + local type = "sasx" +} +else if index("`filen'",".v6x") & index("`filen'",".v6x") == length("`filen'") - 3 { + local ext = ".v6x" + local type = "sasx32 " +} +else if index("`filen'",".") { + local ext = substr("`filen'",index("`filen'","."),length("`filen'")) + while index("`ext'",".") > 0 { + local ext = substr("`ext'",index("`ext'",".") + 1,length("`ext'")) + } + local ext=".`ext'" +} +if index("`filen'",".") { + local middle=substr("`filen'",1,index("`filen'","`ext'") - 1) /* middle will not end in a period */ + local filen=substr("`filen'",1,index("`filen'",".") - 1) + local middle=substr("`middle'",length("`filen'")+1,length("`middle'")) +} + + if `"`filen'"' == `""' { + // This should never be the case, but leave in just as a catch + di `"{error} you have to specify the SAS file name when specifying a file location"' + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(15) etime + } + exit 198 + } + + +****** Check for invalid SAS data file name ************ +local fc = substr("`filen'",1,1) +// have to use inlist() since the first char is likely a letter +// and have to split it into two since it can't handle 11 arguments! +local swn = "0" +local hsc = "0" +if inlist("`fc'","0","1","2","3","4") | /// + inlist("`fc'","5","6","7","8","9") { // name starts with a number + local swn = "1" +} + +if index("`filen'","~") | /// Has a bad character in name + index("`filen'","!") | /// + index("`filen'","@") | /// + index("`filen'","#") | /// + index("`filen'","$") | /// + index("`filen'","%") | /// + index("`filen'","^") | /// + index("`filen'","&") | /// + index("`filen'","*") | /// + index("`filen'","(") | /// + index("`filen'",")") | /// + index("`filen'","-") | /// + index("`filen'","+") | /// + index("`filen'","=") | /// + index("`filen'","[") | /// + index("`filen'","]") | /// + index("`filen'",":") | /// + index("`filen'",";") | /// + index("`filen'","'") | /// + index("`filen'","<") | /// + index("`filen'",">") | /// + index("`filen'","?") | /// + index("`filen'",",") | /// + index("`filen'","|") | /// + index("`filen'"," ") | /// + index("`filen'","{") | /// + index("`filen'","}") { + local hsc = "1" +} + +if "`swn'" == "1" | "`hsc'" == "1" { + if "`rename'" == "" { + di `"{error}File name {res}"`filen'" {error}is not a valid SAS file name. *"' + if "`swn'" == "1" { + di `"{error}SAS file names cannot start with a number. *"' + } + if "`hsc'" == "1" { + di `"{error}SAS file names cannot contain special characters. *"' + } + } + if "`hsc'" == "1" { + // remove bad characters + foreach char in ~ ! @ # $ % ^ & * ( ) - + = [ ] : ; ' < > ? , | { + local filen = subinstr("`filen'","`char'","_",.) + } + local filen = subinstr("`filen'","{","_",.) + local filen = subinstr("`filen'","}","_",.) + local filen = subinstr("`filen'"," ","_",.) + + if `"`: subinstr local filen "_" "" , all'"' == "" { // if nothing left, meaning, person used all bad characters + local filen = "okpopeye" + } + } // end of contains bad character + + if "`swn'" == "1" { // name starts with a number + if length("`filen'") == 32 { + local filen = substr("`filen'",2,length("`filen'")) + local filen = "_`filen'" + } + else { + local filen = "_`filen'" + } + } // end of if started with number + if "`rename'" == "" { + di `"{error}The {res}rename {error}option will rename it for you to be: {res}"`filen'" "' + /* log usage of saswrapper */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(6) etime + } + exit 198 + } +} /* if filen is not a valid SAS data file name */ + + +if "`type'" == "sasx" { + if !("`ext'" == ".xpt" | /* + */ "`ext'" == ".xport" | /* + */ "`ext'" == ".export" | /* + */ "`ext'" == ".expt" | /* + */ "`ext'" == ".trans" | /* + */ "`ext'" == ".exp" | /* + */ "`ext'" == ".sasx" | /* + */ "`ext'" == ".v5x" | /* + */ "`ext'" == ".v6x") { + local middle = "`middle'`ext'" + local ext = ".xpt" + } + if length("`filen'") > 8 & "`rename'" == "" { + di `"{error}File name {res}"`filen'" {error}is not a valid SAS xport file name. *"' + di `"{error}SAS xport file names have to be 8 or less characters long. *"' + local filen = substr("`filen'",1,8) + di `"{error}The {res}rename {error}option will rename it for you to be: {res}"`filen'" {error}*"' + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(7) etime + } + exit 198 + } + else if length("`filen'") > 8 & "`rename'" != "" { + local filen = substr("`filen'",1,8) + } + + if "`middle'" == ".dta" { + local middle = "" + } + local using = "`macval(dir)'`filen'`middle'" + local filen = "`filen'"+"`middle'" +} /* end of if type=sasx */ +else { + local using = "`macval(dir)'`filen'" + local ext = ".sas7bdat" + if "`type'" == "sas6" & "`c(os)'" == "Unix" & "`c(machine_type)'" != "PC" { + local ext = ".ssd01" + } + else if "`type'" == "sas6" & "`c(os)'" == "Unix" & "`c(machine_type)'" == "PC" { + local ext = ".ssd02" + } + else if "`type'" == "sas6" & "`c(os)'" == "Windows" { + local ext = ".sd2" + } +} +if "`type'" == "sas6" { + if length("`filen'") > 8 & "`rename'" == "" { + di `"{error}File name {res}"`filen'" {error}is not a valid SAS version 6 file name. *"' + di `"{error}SAS version 6 file names have to be 8 or less characters long. *"' + local filen = substr("`filen'",1,8) + di `"{error}The {res}rename {error}option will rename it for you to be: {res}"`filen'" {error}*"' + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(8) etime + } + exit 198 + } + else if length("`filen'") > 8 & "`rename'" != "" { + local filen = substr("`filen'",1,8) + } +} +if "`type'" != "sasx" | "`type'" != "sas6" { + if length("`filen'") > 32 & "`rename'" == "" { + di `"{error}File name {res}"`filen'" {error}is not a valid SAS file name. *"' + di `"{error}SAS file names have to be 32 or less characters long. *"' + local filen = substr("`filen'",1,32) + di `"{error}The {res}rename {error}option will rename it for you to be: {res}"`filen'" {error}*"' + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(8) etime + } + exit 198 + } + else if length("`filen'") > 32 & "`rename'" != "" { + local filen = substr("`filen'",1,32) + } +} + + + + +if "`replace'" == "" & "`sascode'" == "" { + if index(`"`macval(dir)'"',"\") == 1 { // Universal naming doesn't seem to be a problem + capture confirm file `"`macval(dir)'`filen'`ext'"' + } + else { + capture confirm file `"`macval(dir)'`filen'`ext'"' + } + if _rc == 0 { + di `"{error}The SAS file: "`macval(dir)'`filen'`ext'" already exists."' + di "{error}Use the {res}replace {error}option if you really want to replace it." + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(9) etime + } + exit 602 + } +} // end of if replace option not used + +if "`script'" == "" { + /* set where temp directory is */ + tmpdir + local tmpdir `"`r(tmpdir)'"' + + local tfn = subinstr("`c(current_time)'",":","",.) + local sysjobid = substr("`tfn'",length("`tfn'") - 5,length("`tfn'")) + local sysjobid = "_`sysjobid'" +} +else if "`script'" != "" local tmpdir `"`udir'"' + +if "`type'" == "sasx" { + if `c(k)' > 9999 { + di _n "{error}SAS Xport/Transport files can only handle up to 9,999 variables. *" + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(10) etime + } + exit 103 + } +} /* end of if sasx */ + + +* TEST FOR UNIQUE VARNAMES +* ------------------------ + +** test that vars will work in SAS transport and version 6 files ** +local j = 1 +local srenamed = 0 +local verror = 0 +local k = 0 +local stop = 0 +local sasvars "" +foreach var of varlist _all { + local ovar = "`var'" + local valid = upper("`var'") /* make all renamed vars uppercase */ + ** Test for invalid SAS varnames and ** + ** test if variables are not unique for SAS since SAS is case insensitive ** + if upper("`var'") == "_ERROR_" | /* invalid SAS names + */ upper("`var'") == "_N_" | /* + */ upper("`var'") == "_NUMERIC_" | /* + */ upper("`var'") == "_CHARACTER_" | /* + */ upper("`var'") == "_ALL_" { + local verror = 1 + } /* end of if var is an invalid SAS varname */ + if ("`type'" == "sasx" | "`type'" == "sas6") & length("`var'") > 8 { + local verror = 1 + } + if "`var'" != upper("`var'") { /* don't check vars that are already upper case */ + capture rename `var' `valid' + if _rc != 0 { + local verror = 2 + } + else { + local var="`valid'" + } + } /* end of don't check if var already upper case */ + if "`rename'" == "" & `verror' >= 1 { + if `j' == 1 { + di "{error}Not all Stata variables are valid SAS variables. *" + di "{error}Specify the {res}rename {error}option for {help savasas:savasas} {error}to rename them. *" + di "{error}List of variables that need to be renamed: * " + local stop = 1 + local j = `j'+1 + } + di "{res}`ovar' *" + } /* end of if "`rename'" == "" & verror >= 1 */ + else if "`rename'" != "" & `verror' >= 1 { + local k = 0 + while length("`k'") < 6 { /* make up to 99,999 attempts to rename the variable */ + if ("`type'" == "sasx" | "`type'" == "sas6") & length("`var'") > 8 { + if `k' == 0 { /* take first 8 characters */ + local valid = upper(substr("`var'",1,8)) + } + else { + local valid = upper(substr("`var'",1,8 - length("`k'"))) + "`k'" + } + } /* end if sasx or sas6 */ + else { + if `k' == 0 { + local k = 1 + } + local valid = upper(substr("`var'",1,32 - length("`k'"))) + "`k'" + } + capture rename `var' `valid' + if _rc != 0 & length("`k'") == 6 { + local verror = 1 + } + else if _rc == 0 { + if `j' == 1 { + noi di "The following variables were renamed to valid SAS variable names: * " + local srenamed = 1 + local j = `j' + 1 + } + noi di "{res}`ovar' {txt}-> {res}`valid' *" + local k = "success!" + } /* end of if _rc == 0 */ + if "`k'" != "success!" { + local k = `k'+1 /* count attempts to rename vars */ + } + } /* end of while length(k) < 6 */ + } /* end of if rename and verror */ + if `srenamed' == 0 { /* make sure all vars are valid */ + capture rename `var' `valid' + } + if `stop' == 0 { + if `verror' == 0 { + local sasvars "`sasvars' `ovar'" /* keep list of vars that have original case if possible */ + } + else if `verror' >= 1 { + local sasvars "`sasvars' `valid'" /* keep list of vars that have original case if possible */ + } + } /* if foreach not stopped */ + local verror = 0 + local srenamed = 0 +} /* end of foreach */ + +if `stop' == 1 { /* This should not be possible. */ + if "`rename'" != "" { + noi di "{error}ERROR: {help savasas:savasas} was unable to rename variables uniquely to shorter names. *" + } + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(11) etime + } + exit 499 +} /* end of if verror=1 */ + +/* rename all vars so that fdasave won't have to */ +local k = 0 +local stop = 0 +local cvars "" +foreach valid of varlist _all { + if length("`valid'") > 8 { + local k = 0 + while length("`k'") < 6 { /* make up to 99,999 attempts to rename the variable */ + if `k' == 0 { /* take first 8 characters */ + local xptvar = upper(substr("`valid'",1,8)) + } + else { + local xptvar = upper(substr("`valid'",1,8 - length("`k'"))) + "`k'" + } + capture rename `valid' `xptvar' + if _rc == 0 { + local k = "success!" + } /* end of if _rc == 0 */ + else { + local k = `k'+1 /* count attempts to rename vars */ + } + } /* end of while length(k) < 6 */ + } /* end if valid varname > 8 */ + if length("`valid'") <= 8 { + local xptvar = "`valid'" + } + local vt : type `xptvar' + if index("`vt'","str") { + local cvars "`cvars' `xptvar'" + } +} /* end of foreach */ + + +* FIX STRING VARS +* --------------- +// remove trailing blanks in string data +if "`cvars'" != "" { + local i = 1 + foreach var of varlist `cvars' { + if `c(maxstrvarlen)' > 80 { + quietly compress `var' + local vt : type `var' + if real(substr(rtrim("`vt'"),4,length("`vt'"))) > 200 { + if `i' == 1 { + // because xport files have a 200 character limit and savasas uses fdasave there is a 200 character limit + noi di "{help savasas:savasas} {error}can only store the first 200 characters in string variables. *" + noi di "{error}List of string variables reduced to 200: *" + local i = `i' + 1 + } + noi di "{res} `var' *" + } /* if length > 200 */ + } /* end of if SE dataset */ + quietly replace `var' = substr(rtrim(`var'),1,200) // trim off trailing blanks for all string vars + } /* end of foreach */ +} /* end of if there are cvars in dataset */ + +local xfilen = substr("`filen'",1,6) +if `c(k)' > 9999 { + local vars1 "" + local vars2 "" + local vars3 "" + local vars4 "" + local i = 0 + local files = 1 + foreach var of varlist _all { + local i = `i' + 1 + if `i' <= 9999 { + local vars1 "`vars1' `var'" + } + if `i' > 9999 & `i' <= 19998 { + local vars2 "`vars2' `var'" + } + else if `i' > 19998 & `i' <= 29997 { + local vars3 "`vars3' `var'" + } + else if `i' > 29997 { + local vars4 "`vars4' `var'" + } + } /* end of foreach */ + local sysjobid1 = "`sysjobid'1" + local xfilen1 = substr("`filen'",1,6) + "1" + if `i' > 9999 { + local files = 2 + local sysjobid2 = "`sysjobid'2" + local xfilen2 = substr("`filen'",1,6) + "2" + } + if `i' > 19998 { + local files = 3 + local sysjobid3 = "`sysjobid'3" + local xfilen3 = substr("`filen'",1,6) + "3" + } + if `i' > 29997 { + local files = 4 + local sysjobid4 = "`sysjobid'4" + local xfilen4 = substr("`filen'",1,6) + "4" + } +} /* if > 9999 vars */ + +if "`type'" == "sas" { + local eng = "`rver'" +} +else if "`type'" == "sas6" { + local eng = "v6" +} +else if "`type'" == "sasx" { + local eng = "xport" +} + +if "`files'" == "" { + local temp `"`macval(tmpdir)'`sysjobid'"' + if "`sascode'" == "" { /* save xpt file to temp dir */ + local raw `"`macval(temp)'"' + } + else { /* save xpt file to using dir */ + local raw `"`macval(dir)'`filen'"' + local raw0 `"`macval(dir)'`xfilen'"' + } +} +else { + foreach file of numlist 1/`files' { + local temp `"`macval(tmpdir)'`sysjobid'"' + local raw`file' `"`macval(tmpdir)'`sysjobid`file''"' + local raw `"`macval(tmpdir)'`sysjobid'"' + if "`sascode'" != "" { /* save xpt file to using dir */ + local raw`file' `"`macval(dir)'`xfilen`file''"' + local raw `"`macval(dir)'_`xfilen'"' + } + } /* end of foreach file */ +} /* end of else multiple files */ + + +* RUN CHECK REPORT +* ---------------- + if "`check'" != "" { + tempfile xpt_ready + quietly save "`xpt_ready'" + restore, preserve /* do check on original data */ + if "`script'" == "script" { + if "`eng'" == "`xport'" { + /* if xport file then filen may have periods in it */ + local filenx=substr("`filen'",1,index("`filen'",".") - 1) + log using `"`macval(dir)'`filenx'_STATAcheck.log"', replace + } + else if "`eng'" != "`xport'" { + log using `"`macval(dir)'`filen'_STATAcheck.log"', replace + } + } /* if running savasas from script */ + if "`eng'" == "`xport'" { + di `"Compare results with SAS output: `macval(dir)'`filenx'_SAScheck.lst "' + global S_FN = "`filenx'" + } + else if "`eng'" != "`xport'" { + di `"Compare results with SAS output: `macval(dir)'`filen'_SAScheck.lst "' + global S_FN = "`filen'" + } + if `srenamed' == 1 { /* if any vars were renamed */ + di "NOTE: The Stata variables here may not match the SAS variables " + di " because the SAS variables may have been renamed. " + } + local five_n = 5 + if _N < 5 { + local five_n = _N + } + // no reason to set more off because if user quits no temp files have been written yet + // data already subset + summarize + describe + list in 1/`five_n' + if "`script'" == "script" { + log close + } + use `xpt_ready', clear // though no reason to have to clear since data didn't change! + } /* end of if check */ + + +* WRITE SAS PROGRAM TO READ IN DATA +* --------------------------------- +savasas_sas , dir(`dir') sysjobid(`sysjobid') filen(`filen') raw(`raw') ext(`ext') /// + engine(`eng') rver(`rver') `check' `sascode' `formats' middle(`middle') /// + sysjobid1(`sysjobid1') sysjobid2(`sysjobid2') sasvars(`sasvars') /// + sysjobid3(`sysjobid3') sysjobid4(`sysjobid4') files(`files') /// + raw0(`raw0') raw1(`raw1') raw2(`raw2') raw3(`raw3') raw4(`raw4') /// + `shortfileext' xfilen(`xfilen') xfilen1(`xfilen1') xfilen2(`xfilen2') /// + xfilen3(`xfilen3') xfilen4(`xfilen4') /// + vars1(`vars1') vars2(`vars2') vars3(`vars3') vars4(`vars4') messy(`messy') /// + `saswrapper' saswrap_data(`saswrap_data') + + +* SAVE DATA +* --------- +/* min and max values will be tested by fdasave */ +if "`files'" == "" { + if "`sascode'" == "" { + quietly fdasave "`raw'", rename vallabfile(none) replace + } + else { + quietly fdasave "`raw0'", rename vallabfile(none) replace + } +} +else if "`files'" != "" { + foreach file of numlist 1/`files' { + local nvars : word count "`vars`file''" + quietly fdasave `vars`file'' using "`raw`file''", rename vallabfile(none) replace + } +} + +if "`sascode'" == "" { + // if replacing SAS file then see if user has permission to do so + if index(`"`macval(dir)'"',"\") == 1 { // Universal naming doesn't seem to be a problem + capture confirm file `"/`macval(dir)'`filen'`ext'"' + } + else { + capture confirm file `"`macval(dir)'`filen'`ext'"' + } + if _rc == 0 { + if "`script'" == "" { + capture erase `"`macval(dir)'`filen'`ext'"' + } + if _rc != 0 { + di "" + di `"{error}The SAS file: `macval(dir)'`filen'`ext' cannot be replaced."' + di `"{error}Check your directory/folder permissions and file permissons."' + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(13) etime + } + exit 608 + } + } /* end of if file exists */ + + * RUN SAS + * ------- + if "`c(os)'" == "Unix" /* or Linux */ { + shell "`usas'" "`temp'_infile.sas" -log "`temp'_infile.log" + run "`temp'_infile_report.do" + } /* end of if Unix */ + else if "`c(os)'" == "Windows" /* Windows */ { + shell `wsas' "`temp'_infile.sas" -nologo -log "`temp'_infile.log" + run "`temp'_infile_report.do" + } /* end of if Windows */ + sas_rep /* run the SAS report */ + if "`r(sas_rep_error)'" != "" { + local messy "messy" + } + if "`messy'" == "" { + capture erase "`temp'_infile.sas" + capture erase "`temp'_infile.log" + capture erase "`temp'_infile_report.do" + capture erase "`temp'_formats.txt" + if "`files'" == "" { // if only 1 xpt file created + capture erase "`temp'.xpt" + } + else { + foreach file of numlist 0/`files' { // if multiple xpt files created + capture erase "`raw`file''.xpt" + } + } /* end of else */ + } /* end of messy */ + else if "`messy'" != "" & "`script'" == "" { + di _n "{res}You have requested {help savasas:savasas} not to delete the intermediary files created by savasas:" + di _n `"in directory: `tmpdir'"' + dir `"`temp'*"' + if "`files'" != "" { + dir `"`raw'*.xpt"' + } + + if "`c(console)'" == "" { // not in console mode or batch mode + if "`c(os)'" != "Windows" { // sysjobid starts with an underscore in savasas + di `"{res} {stata usesasdel `"`tmpdir'"' `sysjobid' :Click here to erase them all.} "' + } + if "`c(os)'" == "Windows" { + local usesasdeldir : subinstr local tmpdir `":"' `"\\\`= char(58)'"', all + // sysjobid starts with an underscore in savasas + di `"{res} {stata usesasdel `"`usesasdeldir'"' `sysjobid' :Click here to erase them all.} "' + } + } // not in console or batch mode + + } +} /* end of if not wanting only sascode */ +else if "`sascode'" == "sascode" { + if "`files'" == "" { // if only 1 xpt file created + if index("`raw0'","\") == 1 { // Universal naming doesn't seem to be a problem + capture confirm file `"/`macval(raw0)'.xpt"' + } + else { + capture confirm file "`raw0'.xpt" + } + if _rc == 0 { + di `"{txt}The xport data file you requested is: *"' + di `"{res} "`raw0'.xpt" *"' + } + else if _rc != 0 { + di `"{help savasas:savasas} {error}did not save: *"' + di `"{txt} "`raw0'.xpt" * "' + } + } + else { // more than one xpt file created + foreach file of numlist 1/`files' { + if index("`raw`file''","\") == 1 { // Universal naming doesn't seem to be a problem + capture confirm file `"/`macval(raw`file')'.xpt"' + } + else { + capture confirm file "`raw`file''.xpt" + } + if _rc == 0 { + if `file' == 1 di `"{txt}The xport data files you requested are: *"' + di `"{res} "`raw`file''.xpt" *"' + } + else if _rc != 0 { + if `file' == 1 di `"{help savasas:savasas} {error}did not save: *"' + di `"{txt} "`raw`file''.xpt" * "' + } + } + } + if index("`raw'","\") == 1 { // Universal naming doesn't seem to be a problem + capture confirm file "/`macval(raw)'_infile.sas" + } + else capture confirm file "`raw'_infile.sas" + if _rc == 0 { + di `"{txt}The SAS program to read in the xport data file is: *"' + di `"{res} "`raw'_infile.sas" *"' + } + else if _rc != 0 { + di `"{help savasas:savasas} {error}did not save:"' + di `"{txt} "`raw'_infile.sas" * "' + } +} /* end of if sascode=sascode */ + +return local sasfile `"`macval(dir)'`filen'`ext'"' + +restore + +/* log usage of savasas */ +capture which usagelog +if _rc == 0 { + usagelog , type(savas) uerror(0) etime +} + +end /* end of savasas */ + + +program define savasas_sas +syntax [varlist] [, engine(string) rver(string) dir(string) sysjobid(string) ext(string) files(string) /// + sascode filen(string) CHeck FORmats raw(string) middle(string) /// + sysjobid1(string) sysjobid2(string) sysjobid3(string) sysjobid4(string) /// + raw0(string) raw1(string) raw2(string) raw3(string) raw4(string) sasvars(string) /// + xfilen(string) xfilen1(string) xfilen2(string) xfilen3(string) xfilen4(string) /// + vars1(string) vars2(string) vars3(string) vars4(string) shortfileext messy(string) /// + saswrapper saswrap_data(string) ] + version 8 + +quietly { + file open sasfile using "`raw'_infile.sas", replace text write + * DATA LIST + * --------- + + if "`sascode'" == "" { + local in_dset `"`raw'.xpt"' + } + else { + local in_dset `"`raw0'.xpt"' + } + + file write sasfile _n `"/********************************************************"' /* + */ _n `"** program: `raw'_infiles.sas "' /* + */ _n `"** programmer: savasas "' /* + */ _n `"** date: `c(current_date)' "' /* + */ _n `"** comments: SAS program to read and label: "' /* + */ _n `"** `in_dset' "' /* + */ _n `"** which contains data from a Stata dataset"' /* + */ _n `"********************************************************/"' /* + */ _n _n `"options nofmterr nocenter linesize=max;"' _n _n + + file write sasfile _n `" ** this version of _infile_report.do will be overwritten if all goes well. **; "' + file write sasfile _n `" data _null_;"' _n `"file "`raw'_infile_report.do"; "' /// + _n `" put "capture program drop sas_rep"; "' /// + _n `" put "program define sas_rep, rclass"; "' /// + _n `" put "di as err "" SAS failed to create `filen' "" "; "' /// + _n `" put "di as err "" Look at {view `raw'_infile.log:`raw'_infile.log} to see what error occurred. "" "; "' + if "`messy'" == "" { + file write sasfile _n `" put "di as err "" The {help savasas:savasas} option messy is now on. "" "; "' + } + file write sasfile _n `" put "local sas_rep_error = 1 "; "' /// + _n `" put "return local sas_rep_error ""\`sas_rep_error\'"" "; "' /// + _n `" put "end"; "' + + + if "`engine'" == "v6" { + file write sasfile _n _n `"libname library v6 "`dir'" `shortfileext'; "' _n _n + file write sasfile _n _n `"options fmtsearch=(out.`filen'); "' _n _n + } + else { + file write sasfile _n _n `"libname library `engine' "`dir'" `shortfileext'; "' _n _n + file write sasfile `"options fmtsearch=(out.`filen'); "' _n _n + } + + if "`engine'" == "`rver'" | "`engine'" == "v6" { + file write sasfile `"libname out `engine' "`dir'" `shortfileext' ; "' _n _n + } + else if "`engine'" == "xport" { + file write sasfile `"libname out xport "`macval(dir)'`filen'`ext'"; "' _n _n + /* if xport file then filen may have periods in it then get rid of them + * since filen no longer needs them now that libname out defined */ + if index("`filen'",".") { + local filen=substr("`filen'",1,index("`filen'",".")-1) + } + } + + if `c(k)' <= 9999 { + if "`sascode'" == "" { + file write sasfile `"libname raw xport "`raw'.xpt"; "' _n _n + } + else { + file write sasfile `"libname raw xport "`raw0'.xpt"; "' _n _n + } + } /* if <= 9999 vars */ + else if `c(k)' > 9999 { + foreach file of numlist 1/`files' { + file write sasfile _n _n `"libname raw`file' xport "`raw`file''.xpt"; "' _n _n + } /* end of foreach file */ + if "`sascode'" == "" { + file write sasfile `" /* do observational merge to create one big file */ "' /* + */ _n `" data `sysjobid'; "' /* + */ _n `" merge raw1.`sysjobid1' raw2.`sysjobid2' "' + if `c(k)' > 19998 { + file write sasfile `" raw3.`sysjobid3' "' + if `c(k)' > 29997 { + file write sasfile `" raw4.`sysjobid4' "' + } /* end of if > 29997 vars */ + } /* end of if > 19998 vars */ + file write sasfile `";"' _n `"run;"' + } /* end of if not sascode */ + else { + file write sasfile `" /* do observational merge to create one big file */ "' /* + */ _n `" data `xfilen'; "' /* + */ _n `" merge raw1.`xfilen1' raw2.`xfilen2' "' + if `c(k)' > 19998 { + file write sasfile `" raw3.`xfilen3' "' + if `c(k)' > 29997 { + file write sasfile `" raw4.`xfilen4' "' + } /* end of if > 29997 vars */ + } /* end of if > 19998 vars */ + file write sasfile `";"' _n `"run;"' + } /* end of if sascode */ + } /* end of if > 9999 vars */ + + + + * CREATE USER-DEFINED FORMATS FROM VALUE LABELS + * --------------------------------------------- + local hasvl 0 + if "`formats'" != "" { + label dir + if "`r(names)'" != "" { // dataset has value labels but not sure if they are used in data + local names `"`r(names)'"' + local hasvl = 1 + /* establish what is the max length of a user-defined format name + * based on what version of SAS datafile is desired */ + if index("`engine'","v8") | /// + index("`engine'","v6") | /// + index("`engine'","xport") local ml = 8 + else local ml = 32 + + // create a list of all value labels used in data set that are defined + // a variable can be assigned a label that has not been defined...this is not good + local all_vlabs `""' + // create a list of all variables with value labels associated to them + // that are actually defined + local lvvars `""' + foreach var of varlist `varlist' { + local lbl : value label `var' + if `"`lbl'"' != "" { // if variable has value label associated to it + capture label list `lbl' // check to see if exists as defined label + // if it doesn't give up and move on! + if _rc == 111 { // label isn't defined + local lbl "" + // remove association of label to variable since it isn't defined + label value `var' + } + else { // var has label that is defined + // all vars with defined labels need to be sent to sav_lvchk + local lvvars `"`lvvars' `var'"' // create list of vars with value labels + // label exists and not already listed + if `: list posof `"`lbl'"' in local(all_vlabs)' == 0 { + local all_vlabs `"`all_vlabs' `lbl'"' + } + } + } + } // end of foreach var + + // drop defined labels that are not associated to variables in current dataset + foreach lbl of local names { + if `: list posof `"`lbl'"' in local(all_vlabs)' == 0 { + label drop `lbl' + } + } + // re-create local macro names now that it's cleaned up + label dir + local names `"`r(names)'"' + } /* end of if dataset has value labels */ + else { + local hasvl 0 + } + + if "`r(names)'" != "" { // if dataset really has value labels + // check and rename value labels if necessary + capture noisily sav_lvchk, ml(`ml') vars(`lvvars') + + if _rc == 499 { /* value labels were not uniquely named */ + if "`script'" == "" { + erase "`raw'_infile.sas" + } + /* log usage of savasas */ + capture which usagelog + if _rc == 0 { + usagelog , type(savas) uerror(12) etime + } + exit 499 + } + + + if `= real(substr("`rver'",2,length("`rver'")))' > 8 { + file write sasfile _n `"options NoQuoteLenMax;"' // new option in SAS 9 + } + else if `c(version)' >= 9 { + noi di as res _n `"WARNING: Value labels longer than 200 characters may be truncated. *"' _n + } + + sav_labs_data `varlist', fhandle(sasfile) ml(`ml') filen(`filen') raw(`"`raw'"') + + } /* end of if dataset really has value labels */ + else { + local hasvl 0 + } + } /* end of if formats to be created from value labels */ + + if "`engine'" != "xport" { + file write sasfile _n _n `"data out.`filen' "' /// + `" (label= "-savasas- created dataset on %sysfunc(date(),date9.)" "' + if "`engine'" != "v6" { + file write sasfile `" rename=("' _n + local i = 1 + tokenize "`sasvars'" /* good SAS variable names */ + foreach var of varlist _all { + file write sasfile `" `var' = ``i''"' + if mod(`i',5) == 0 { + file write sasfile _n + } + local i = `i' + 1 + } /* end of foreach */ + file write sasfile _n `" ));"' _n `" length "' + } /* if not v6 engine */ + else if "`engine'" == "v6" { /* no need to rename vars for v6 files */ + file write sasfile _n `");"' _n `" length "' + } + } + else if "`engine'" == "xport" { /* don't need vars renamed or sort info */ + file write sasfile _n _n `"data out.`filen' "' /// + `" (label= "-savasas- created dataset on %sysfunc(date(),date9.)" );"' _n `" length "' + } + + + * SET VARS TO MINIMUM DATATYPE + * ---------------------------- + compress /* so says Loren */ + + local j 1 + local verror = 0 + foreach var of varlist `varlist' { + local storage : type `var' + if index("`storage'","str") == 0 { + if ("`storage'" == "float") | ("`storage'" == "double") { + local len = 8 + } + else if "`storage'" == "byte" { + local len = 3 + } + else if "`storage'" == "int" { + local len = 4 + } + else if "`storage'" == "long" { + local len = 6 + } + file write sasfile `" `var' `len'"' + } /* end of if not string */ + else if index("`storage'","str") == 1 { + local len = substr("`storage'",4,length("`storage'")) + file write sasfile `" `var' $`len'"' + } + if (mod(`j',8) == 0) { /* print 8 vars per line */ + file write sasfile _n + } + local j = `j' + 1 + } /* end of foreach */ + if `verror' == 1 { + file close sasfile + exit 499 + } + if `c(k)' <= 9999 { + if "`sascode'" == "" { + file write sasfile _n `" ;;;"' _n `" set raw.`sysjobid'; "' _n + } + else { + file write sasfile _n `" ;;;"' _n `" set raw.`xfilen'; "' _n + } + } + else if `c(k)' > 9999 { + if "`sascode'" == "" { + file write sasfile _n `" ;;;"' _n `" set `sysjobid';"' _n + } + else { + file write sasfile _n `" ;;;"' _n `" set `xfilen';"' _n + } + } + + * VARIABLE LABEL + * -------------- + + file write sasfile _n _n " LABEL " + foreach var of varlist `varlist' { + local varlab : variable label `var' + // add spaces around varlab so that varlab can start with a right quote and contain a right parentheses + local varlab = trim(`" `varlab' "') + if `"`varlab'"' != "" { + // add spaces around varlab so that varlab can start with a right quote and contain a right parentheses + if index(`" `varlab' "',`"'"') { + /* substitute 2 single quotes for one single quote */ + local varlab = subinstr(`" `varlab' "',`"'"',`"''"',.) + } + // enclosing the var label in single quotes keeps macro vars or calls + // to macros from happening + if index(`" `varlab' "',"'") == 2 { + /* if varlab starts with a single right quote, add space + * before it so that it doesn't end the left compound quote in the + * file write of varlabel. escaping it doesn't escape it */ + file write sasfile _n (upper("`var'")) `"=' `varlab' ' "' + } + else if substr(`"`varlab'"',length(`"`varlab'"'),1) == `"""' { + // add a space at the end to separate the last double quote and the right quote + file write sasfile _n (upper(" `var'")) `"='`varlab' ' "' + } + else { + file write sasfile _n (upper(" `var'")) `"='`varlab'' "' + } + } /* end of if varlab exists */ + } /* end of foreach */ + file write sasfile _n " ;;;" + + * ASSIGN VALUE LABELS + * ------------------- + if `hasvl' == 1 { + file write sasfile _n _n "format " + local j 1 + foreach var of varlist `varlist' { + local lbl : value label `var' + capture label list `lbl' // check to see if exists as defined label + // if it doesn't, then give up and move on! + if _rc == 111 local lbl "" + if `"`lbl'"' != "" { + file write sasfile " `var' `lbl'." + if (mod(`j',5) == 0) { /* print 5 vars per line */ + file write sasfile _n + } + local j = `j' + 1 + } /* end of if var has label */ + } /* end foreach */ + + file write sasfile _n " ;;;" + } /* end of if variables have value labels */ + + + * NON-USER DEFINED FORMATS + * ------------------------ + + file write sasfile _n _n "format " + + local j 1 + foreach var of varlist `varlist' { + local storage : type `var' + local fmt : format `var' + if "`formats'" != "" { + local lbl : value label `var' + capture label list `lbl' // check to see if exists as defined label + // if it doesn't give up and move on! + if _rc == 111 local lbl "" + } + local format = "" + /* only assign formats to vars with no value label */ + if !index("`storage'"',"str") & `"`fmt'"' != "" & `"`lbl'"' == "" { + + if substr(`"`fmt'"',length(`"`fmt'"'),1) == "f" { + local format = substr("`fmt'",2,length("`fmt'") - 2) + if `format' > 18 { + local format = "18." + } + local format = "`format'" + } + else if substr(`"`fmt'"',length(`"`fmt'"')-1,2) == "0g" { + local format = substr(`"`fmt'"',2,index(`"`fmt'"',".") - 2) + "." + if `format' > 18 { + local format = "18." + } + local format = "BEST" + "`format'" + } + else if substr(`"`fmt'"',length(`"`fmt'"'),1) == "c" { + local format = substr(`"`fmt'"',2,length(`"`fmt'"',".") - 3) + if `format' > 18 { + local format = "18." + } + local format = "COMMA" + "`format'" + } + else if inlist(`"`fmt'"',"%dDlY","%dDmY","%dDMY", "%ddlY","%ddmY","%ddMY") { + local format = "DATE7." + } + else if inlist(`"`fmt'"',"%dDlCY","%dDmCY","%dDMCY", "%ddlCY","%ddmCY","%ddMCY") { + local format = "DATE9." + } + else if `"`fmt'"' == "%dD/N/Y" { + local format = "DDMMYY8." + } + else if `"`fmt'"' == "%dD/N/CY" { + local format = "DDMMYY10." + } + else if `"`fmt'"' == "%dN/D/Y" { + local format = "MMDDYY8." + } + else if `"`fmt'"' == "%dN/D/CY" { + local format = "MMDDYY10." + } + else if `"`fmt'"' == "%dYND" { + local format = "YYMMDD6." + } + else if `"`fmt'"' == "%dY-N-D" { + local format = "YYMMDD10." + } + else if `"`fmt'"' == "%dCY-N-D" { + local format = "YYMMDD10." + } + else if `"`fmt'"' == "%dD" { + local format = "DAY." + } + else if `"`fmt'"' == "%dl" { + local format = "MONTH." + } + else if `"`fmt'"' == "%dY" { + local format = "YEAR2." + } + else if `"`fmt'"' == "%dCY" { + local format = "YEAR4." + } + else if `"`fmt'"' == "%dM" { + local format = "MONNAME." + } + else if `"`fmt'"' == "%dlY" { + local format = "MONYY5." + } + else if `"`fmt'"' == "%dlCY" { + local format = "MONYY7." + } + else if `"`fmt'"' == "%dd" { + local format = "WEEKDAY." + } + else if `"`fmt'"' == "%d" { + local format = "WORDDATE." + } + else if `"`fmt'"' == "%dYl" { + local format = "YYMON5." + } + else if `"`fmt'"' == "%dCYl" { + local format = "YYMON7." + } + else if index(`"`fmt'"',"%d") == 1 { // the catch-all date format + local format = "MMDDYY10." + } + + file write sasfile " `var' `format'" + if (mod(`j',5) == 0) { /* print 5 vars per line */ + file write sasfile _n + } + local j = `j' + 1 + } /* end of if var has a format */ + } /* end foreach */ + + file write sasfile _n " ;;; " _n "run;" _n /// + " %let lib_error=&syserr.; " _n _n + + + * CHECK SAS DATA + * -------------- + if "`check'" != "" { + noi di " " + noi di `" You have requested savasas to generate a check file from SAS. * "' + if "`engine'" == "xport" { + noi di `" The file is: "{res}`macval(dir)'`filen'`middle'_SAScheck.lst" * "' + } + else { + noi di `" The file is: "{res}`macval(dir)'`filen'_SAScheck.lst" * "' + } + noi di " " + if "`engine'" == "xport" { + file write sasfile _n `"proc printto print= "`macval(dir)'`filen'`middle'_SAScheck.lst" new; "' /// + _n _n `" title "data= `macval(dir)'`filen'`middle': Compare results with Stata output."; "' + } + else if "`engine'" != "xport" { + file write sasfile _n `"proc printto print= "`macval(dir)'`filen'_SAScheck.lst" new; "' /// + _n _n `" title "data= `macval(dir)'`filen': Compare results with Stata output."; "' + } + file write sasfile _n _n `" proc means data= out.`filen'; run;"' /// + _n _n `" proc contents data= out.`filen'; run;"' /// + _n _n `" proc print data= out.`filen' (obs=5); run; "' /// + _n _n `" proc printto; run; "' _n + } /* end of checking */ + + if "`sascode'" == "" { + local out = "out." + if "`engine'" == "xport" { + file write sasfile _n `"data `filen';"' _n `" set out.`filen'; "' _n "run;" _n + local out="work." + } + + file write sasfile _n `"data test;"' _n `"call symput("N",compress(put(___lo___,10.)));"' /// + _n `" stop; "' _n `"set `out'`filen' nobs=___lo___; "' _n `" run; "' _n /// + _n `"proc contents data= test out= contents noprint ;"' _n `"run; "' _n /// + _n `"data _null_;"' _n `"call symput("nvars",compress(put(___lo___,5.)));"' /// + _n `"stop;"' _n `"set contents nobs=___lo___;"' _n `"run; "' _n /// + _n _n `"data _null_;"' _n `"file "`raw'_infile_report.do"; "' /// + _n `" put "capture program drop sas_rep"; "' /// + _n `" put "program define sas_rep"; "' + + if "`engine'" == "`rver'" { + local ext = ".sas7bdat" + } + else if "`engine'" == "v6" { + if "`c(os)'" == "Unix" & "`c(machine_type)'" != "PC" { /* Unix */ + local ext = ".ssd01" + } + if "`c(os)'" == "Unix" & "`c(machine_type)'" == "PC" { /* Linux */ + local ext = ".ssd02" + } + else { + local ext = ".sd2" /* Windows */ + } + } /* end of if v6 */ + else if "`engine'" == "xport" { + local filen = "`filen'" + "`middle'" + } /* end of if xport */ + + if index("`macval(dir)'","\") == 1 { // Universal naming is an issue here since + // this code writes code. Stata sees / as a dir separator no matter the OS. + // so add / since one \ will be lost + local cdir `"/`macval(dir)'"' + file write sasfile _n /* + */ _n `"put "capture confirm file ""`macval(cdir)'`filen'`ext'"" "; "' _n + } + else { + file write sasfile _n /* + */ _n `"put "capture confirm file ""`macval(dir)'`filen'`ext'"" "; "' _n + } + file write sasfile _n /// + _n `"put " if _rc == 0 { "; "' _n /// + _n `"put " di ""{help savasas:savasas} {txt}successfully saved the SAS file: *"""; "'_n + if "`saswrapper'" == "" { + file write sasfile _n /// + _n `"put " di "" {res}`macval(dir)'`filen'`ext' {txt} *"""; "' _n + } + else { + file write sasfile _n /// + _n `"put " di "" {res}`saswrap_data' in the SAS WORK library """; "' _n + } + file write sasfile _n /// + _n `"put " di ""{res}SAS &sysver. {txt}reports that the dataset has {res}&N {txt}observations "' _n /// + `"and {res}&nvars {txt}variables. *"" "; "' _n /// + _n `"put "capture which usagelog"; "' _n /// + _n `"put " if _rc == 0 {"; "' _n /// + _n `"put " usagelog , type(savas) message(""&sysuserid. Output SAS dataset has &N obs and &nvars vars"")"; "' _n /// + _n `"put " }"; "' _n /// + _n `"put "}"; "' _n + + + file write sasfile _n `" put "end"; "' _n `"run;"' _n + } /* end of if sascode not wanted */ + + + * CLOSE SASFILE + * ------------- + file close sasfile + if `hasvl' == 1 & "`saswrapper'" == "" { + noi di _n "{txt}SAS formats catalog file has been created: *" + if "`engine'" == "`rver'" & "`shortfileext'" == "" { + noi di " {res}`macval(dir)'`filen'.sas7bcat *" + } + else if "`engine'" == "v8" & "`shortfileext'" != "" { + noi di " {res}`macval(dir)'`filen'.sc7 *" + } + else if "`engine'" == "v6" & "`c(os)'" == "Windows" { + noi di " {res}`macval(dir)'`filen'.sc2 *" + } + else if "`engine'" == "v6" & "`c(os)'" == "Unix" & "`c(machine_type)'" == "PC" { /* Linux */ + noi di " {res}`macval(dir)'`filen'.sct02 *" + } + else if "`engine'" == "v6" & "`c(os)'" == "Unix" & "`c(machine_type)'" != "PC" { /* Unix */ + noi di " {res}`macval(dir)'`filen'.sct01 *" + } + noi di "{txt}Add the following SAS statements to the SAS program that *" + noi di "{txt}uses {res}`macval(dir)'`filen'`ext' {txt}: * " + noi di `"{res} libname in `engine' "`macval(dir)'" `shortfileext'; {txt}*"' + noi di `"{res} options fmtsearch=(in.`filen'); {txt}*"' + } +} /* end of quietly */ + +end + + + + +* CHECK THAT STATA VALUE LABEL NAMES CAN BE MADE INTO SAS FORMAT NAMES +* IF SO, THEN RENAME +* -------------------------------------------------------------------- + +program sav_lvchk +version 8 +syntax , ml(integer) vars(varlist) + + local ren 0 + local flag5 = 0 + local bad_labs `" "' + local names `"`r(names)'"' + local renamed "" + local orig_names "" + + + foreach var of varlist `vars' { + local lbl : value label `var' + local nlbl = "" + // check if that label has not already been renamed + if `: list posof "`lbl'" in orig_name' == 0 { + // check if label ends in a number--illegal in SAS + if length("`lbl'") <= `= `ml'-1' & ( /// + substr("`lbl'",length("`lbl'"),1) == "1" | /// + substr("`lbl'",length("`lbl'"),1) == "2" | /// + substr("`lbl'",length("`lbl'"),1) == "3" | /// + substr("`lbl'",length("`lbl'"),1) == "4" | /// + substr("`lbl'",length("`lbl'"),1) == "5" | /// + substr("`lbl'",length("`lbl'"),1) == "6" | /// + substr("`lbl'",length("`lbl'"),1) == "7" | /// + substr("`lbl'",length("`lbl'"),1) == "8" | /// + substr("`lbl'",length("`lbl'"),1) == "9" | /// + substr("`lbl'",length("`lbl'"),1) == "0") { + local nlbl = "`lbl'_" + } + else if length("`lbl'") == `ml' { + if substr("`lbl'",`ml',1) == "1" { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "z" + } + else if substr("`lbl'",`ml',1) == "2" { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "y" + } + else if substr("`lbl'",`ml',1) == "3" { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "x" + } + else if substr("`lbl'",`ml',1) == "4" { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "w" + } + else if substr("`lbl'",`ml',1) == "5" { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "v" + } + else if substr("`lbl'",`ml',1) == "6" { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "u" + } + else if substr("`lbl'",`ml',1) == "7" { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "t" + } + else if substr("`lbl'",`ml',1) == "8" { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "s" + } + else if substr("`lbl'",`ml',1) == "9" { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "r" + } + else if substr("`lbl'",`ml',1) == "0" { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "q" + } + } // end of if label `ml' characters long and ends in a number + else if length("`lbl'") > `ml' { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + // check that defined value label not a valid SAS format + else if inlist(lower("`lbl'"), /// + "best" ,"binary" ,"comma" ,"commax" ,"d" ,"date" ,"datetime") { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + else if inlist(lower("`lbl'"), /// + "dateampm","day" ,"ddmmyy" ,"dollar" ,"dollarx" ,"downame" ,"e" ) { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + else if inlist(lower("`lbl'"), /// + "eurdfdd" ,"eurdfde" ,"eurdfdn" ,"eurdfdt" ,"eurdfdwn","eurdfmn" ,"eurdfmy" ) { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + else if inlist(lower("`lbl'"), /// + "eurdfwdx","eurdfwkx","float" ,"fract" ,"hex" ,"hhmm" ,"hour" ) { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + else if inlist(lower("`lbl'"), /// + "ib" ,"ibr" ,"ieee" ,"julday" ,"julian" ,"percent" ,"minguo" ) { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + else if inlist(lower("`lbl'"), /// + "mmddyy" ,"mmss" ,"mmyy" ,"monname" ,"month" ,"monyy" ,"negparen") { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + else if inlist(lower("`lbl'"), /// + "nengo" ,"numx" ,"octal" ,"pd" ,"pdjulg" ,"pdjuli" ,"pib" ) { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + else if inlist(lower("`lbl'"), /// + "pibr" ,"pk" ,"pvalue" ,"qtr" ,"qtrr" ,"rb" ,"roman" ) { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + else if inlist(lower("`lbl'"), /// + "s370ff" ,"s370fib" ,"s370fibu","s370fpd" ,"s370fpdu","s370fpib","s370frb" ) { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + else if inlist(lower("`lbl'"), /// + "s370fzd" ,"s370fzdl","s370fzds","s370fzdt","s370fzdu","ssn" ,"time" ) { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + else if inlist(lower("`lbl'"), /// + "timeampm","tod" ,"weekdate","weekdatx","weekday" ,"worddate","worddatx") { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + else if inlist(lower("`lbl'"), /// + "wordf" ,"words" ,"year" ,"yen" ,"yymm" ,"yymmdd" ,"yymon" ) { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + else if inlist(lower("`lbl'"), /// + "yyq" ,"yyqr" ,"z" ,"zd", "f") { + local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_" + } + + // re-assign value labels using SAS-ok value label names + if `"`nlbl'"' != "" & `"`nlbl'"' != `"`lbl'"' { + local ren = `ren' + 1 // count ones needed to be renamed + if `: list posof "`nlbl'" in names' > 0 { // nlbl already an existing label + local flag5 = 1 + // make a list of bad value label names + if `: list posof "`nlbl'" in bad_labs' == 0 { // add if not already in list + local bad_labs `"`bad_labs'`nlbl' "' + } + } + else { // label okay to be renamed + // assign new label to variable + label value `var' `nlbl' + if `ren' == 1 { + noi di _n "{txt}NOTE: SAS format names cannot be more than `ml' characters long, *" + noi di " {txt}cannot end in a number, nor be a SAS reserved format name. *" + noi di "{txt}NOTE: {res}The following value label(s) will have the following *" + noi di " SAS format value name: *" + noi di as result `"Original"' _col(20)`"Renamed *"' + noi di as result `"--------"' _col(20)`"------- *"' + } + if `: list posof "`nlbl'" in renamed' == 0 { // if not already listed + noi di as result `"`lbl'"' _col(20)`"`nlbl' *"' + local orig_names "`orig_names'`lbl' " // add to list + local renamed "`renamed'`nlbl' " // add to list + // Use Nick Cox's labvalclone command to do just that! + labvalclone `lbl' `nlbl' + } + } + } + } // end of if value label has not already been renamed + else { + // use existing label + local nlbl "`: word `: list posof "`lbl'" in orig_name' of `renamed''" + label `var' `nlbl' + } + + } /* end of foreach */ + // now that all vars have been processed, drop the labels that were cloned + foreach lbl of local orig_names { + label drop `lbl' + } + if `flag5' == 1 { + foreach lab of local bad_labs { + noi di "{error}NOTE: {res}value label `lab' {error}could not be uniquely renamed. *" + } + noi di "{help savasas:savasas} {error}has stopped processing. *" + + file close sasfile + + error 499 + } +end + + +* WRITE OUT USER-DEFINED FORMATS AS A SAS DATASET SO THAT LONG FORMATS ARE NOT A PROBLEM +* -------------------------------------------------------------------------------------- + +program sav_labs_data, rclass +version 8 +syntax [varlist], fhandle(string) ml(integer) filen(string) raw(string) + + // need to re-create r(names) since sav_lvchk may have renamed labels + label dir + if "`r(names)'" != "" { // dataset has value labels. the check before sav_lvchk + // has assured that they are used in data + + if `ml' == 8 local maxlablen = 256 + else local maxlablen = 32000 + local lrecl =`maxlablen' + 75 + + tempfile test + file write `fhandle' _n `"data formats;"' + file write `fhandle' _n `"length fmtname $`ml' start end 8 label $`maxlablen';"' + file write `fhandle' _n `"infile "`raw'_formats.txt" lrecl=`lrecl' truncover ; "' + file write `fhandle' _n `"input fmtname 1-32 start 34-53 end 55-74 label 76-`maxlablen';"' + + file open sas_formats using "`raw'_formats.txt", replace text write + local lab2long = 0 + + local names `r(names)' + foreach lab of local names { + tempname lab_in + tempfile lab_file + label save `lab' using `"`lab_file'"', replace + file open `lab_in' using `"`lab_file'"', r // read-only + file read `lab_in' lab_line // load first line of file to local macro var lab_line + local lvs "" + local n_lvs = 0 // number of label values + // read lab_file one line at a time + // and count how many lines there are + while r(eof) == 0 { + local lv : word 4 of `lab_line' + if `lv' < . local n_lvs = `n_lvs' + 1 + // collect label values into one macro + local lvs `"`lvs' `lv'"' + file read `lab_in' lab_line + } // end of while eof loop + file close `lab_in' + label list `lab' // just to figure out if has special missings or not + if `r(min)' == . & `r(max)' == . { // only has special missing values + local fora `"each lv in `c(alpha)'"' // really: "foreach lv in `c(alpha)'" + local fors `"fora"' + } + else if `r(hasemiss)' == 1 { // has both + local forn `"val lvn = 1/`n_lvs'"' // really: "forval lvn = 1/`n_lvs'" + local fora `"each lv in `c(alpha)'"' // really: "foreach lv in `c(alpha)'" + local fors `"forn fora"' + } + else if `r(min)' != . & `r(max)' != . { // has no special missing values + local forn `"val lvn = 1/`n_lvs'"' // really: "forval lvn = 1/`n_lvs'" + local fors `"forn"' + } + foreach each_val of local fors { + local multi_l = 0 + local write_lab = 0 + // this only works if there is always a loop to process + for``each_val'' { // adding the "for" help Stata not freak out when this section isn't run + if "`each_val'" == "forn" { // for numeric lists look for ranges + local lv : word `lvn' of `lvs' + local label : label `lab' `lv' + // `label' equals the number if no label assigned + // which shouldn't happen now that only processing label values + if `: list local(label) == local(lv)' == 0 { // if value has a label + local nlv : word `= `lvn'+1' of `lvs' + local nlabel "" // no label by default + if `= `lvn'+1' <= `n_lvs' { // : word > n words of string is invalid syntax + local nlabel : label `lab' `nlv' + } + local plabel "" // no label by default + if `lvn' != 1 { // : word 0 of string is invalid syntax + local plv : word `= `lvn'-1' of `lvs' + local plabel : label `lab' `plv' + } + local npl = 0 + if `: list local(label) == local(nlabel)' == 1 { + if `: list local(label) == local(plabel)' == 0 { + if ( "`= `lv'+1'" == "`nlv'" ) { // nlv is in quotes since it might = " " + local multi_l = 1 + local start = `lv' + local npl = 1 + } + } + } + if `npl' == 0 & `: list local(label) == local(nlabel)' == 0 { + if `multi_l' == 1 { + local write_lab = 1 + local multi_l = 0 + } + else { // no range + local write_lab = 1 + local start = `lv' + } + } + else if `: list local(label) == local(nlabel)' == 1 & /// { + ( "`= `lv'+1'" != "`nlv'" ) { // no range because not continuous values + local write_lab = 1 + local start = `lv' + } // end of checking for ranges + if `write_lab' == 1 { + local write_lab = 0 + if `: length local label' > `maxlablen' { + local lab2long = 1 + } + // `macval(label)' keeps dollar signs or `something' + // from being evaluated, $ being more likely + // fmtname start end label + file write sas_formats _n _col(0)`"`lab'"' _col(34)`"`start'"' _col(57)`"`lv'"' _col(81)`"`macval(label)'"' + } + } // end of if value has a label + } // end of if for is forn + else { // process fora list which is only special missings + local label : label `lab' .`lv' + // `label' equals the special missing value if no label assigned + // ( there is length issue here since only checking for ".a", ".b" etc + if "`label'" != ".`lv'" { // if value has a label + if `: length local label' > `maxlablen' { + local lab2long = 1 + } + // `macval(label)' keeps dollar signs or `something' + // from being evaluated, $ being more likely + // fmtname start end label + file write sas_formats _n _col(0)`"`lab'"' _col(34)`".`lv'"' _col(57)`".`lv'"' _col(81)`"`macval(label)'"' + } + } // end if fora loop + } // end of for``each_val'' loop + } // end of fors loop + } // end foreach lab of local names + + + file write `fhandle' _n `"run; "' _n + file write `fhandle' _n _n `"proc format library= library.`filen' cntlin= work.formats(where= (fmtname ^= ""));"' + file write `fhandle' _n `"run; quit;"' + // macro tests if SAS could create new formats catalog and erases it and does it again if SAS + // initially is not able to due to catalog file having been created for a different OS + file write `fhandle' _n _n `"%macro redo;"' + file write `fhandle' _n `" ** Check for this error message:"' + file write `fhandle' _n `" * upcase(error:) File LIBRARY.`filen'.CATALOG was created for a different operating system. **;"' + file write `fhandle' _n `" %if &syserr. = 3000 %then %do;"' + file write `fhandle' _n `" proc datasets library= library "' + file write `fhandle' _n `" memtype= catalog "' + file write `fhandle' _n `" nodetails nolist nowarn;"' + file write `fhandle' _n `" delete `filen';"' + file write `fhandle' _n `" run;"' + file write `fhandle' _n `" ** now try it! **;"' + file write `fhandle' _n `" proc format library= library.`filen' cntlin= work.formats(where= (fmtname ^= ""));"' + file write `fhandle' _n `" run; quit;"' + file write `fhandle' _n `" %end;"' + file write `fhandle' _n `"%mend redo;"' + file write `fhandle' _n `"%redo;"' + + if `lab2long' == 1 { + di as error "WARNING: at least one value label was truncated because it was longer than `maxlablen' characters" + } + // capture file close sas_formats since "``for'' {" throws stata off but this is now fixed so not a problem? + capture file close sas_formats + } // end of if dataset has value labels (condition is probably not needed) + +end + + +*! NJC 1.1.1 3 Nov 2002 +* NJC 1.1.0 1 Nov 2002 +program def labvalclone + version 7 + args old new garbage + if "`old'" == "" | "`new'" == "" | "`garbage'" != "" { + di as err "syntax is: " /* + */ as txt "labvalclone {it:vallblname newvallblname}" + exit 198 + } + if "`old'" == "label" | "`old'" == "define" { + di as err "won't work if {txt:`old'} is existing value label name" + exit 198 + } + capture label list `new' // check to see if exists as defined label + if _rc == 0 { + di as err "value labels {txt:`new'} already exist" + exit 198 + } + + tempfile file1 file2 + tempname in out + + qui label save `old' using `"`file1'"' + file open `in' using `"`file1'"', r + file open `out' using `"`file2'"', w + file read `in' line + + while r(eof) == 0 { + local line: subinstr local line "`old'" "`new'" + file write `out' `"`line'"' _n + file read `in' line + } + file close `out' + + qui do `"`file2'"' +end + +exit + diff --git a/Modules/ado/plus/s/savasas.hlp b/Modules/ado/plus/s/savasas.hlp new file mode 100644 index 0000000..94cf3c0 --- /dev/null +++ b/Modules/ado/plus/s/savasas.hlp @@ -0,0 +1,308 @@ +{smcl} +{* version 2.1 12Mar2009}{...} +{* 09Jul2005 - updated assuming SAS 9 is current version of SAS}{...} +{* 02Dec2004 - improved smcl code}{...} +{* 19Oct2004 - minor edits}{...} +{* 05Nov2003}{...} +{hline} +help for {hi:savasas} {right:manual: {hi:[R] none}} +{right:dialog: {hi: none} } + +{hline} + + +{title:Save dataset as a SAS dataset} + +{p 8 17 2}{cmd:savasas} +[{it:varlist}] +[{cmd:using} {it:filename}] +{ifin} +[{cmd:,} {cmdab:t:ype(}{it:version_of_sas_data_file}{cmd:)} +{cmd:replace} +{cmdab:for:mats} +{cmdab:ren:ame} +{cmdab:me:ssy} +{cmdab:ch:eck} +{cmd:sascode} +]{p_end} + + +{title:Description} + +{p 4 4 2}{cmd:NOTE:} Before the first use of {cmd:savasas} the {cmd:sasexe.ado} +file may need to be edited to set the location of your SAS executable file. Instructions on how +to do this is at the bottom of this help file.{p_end} + +{p 4 4 2}{cmd:savasas} saves the Stata dataset in memory as a SAS file. By default the output dataset +will have the same name and be in the same directory, but with the ".sas7bdat" file name extension +and contain all observations and every variable in the Stata datafile. +{cmd:savasas} can save to other versions of SAS: +Version 8 or 9 (*.sas7bdat), Version 6 (*.sd2/*.ssd01/*.ssd02), SAS 6 Transport/xport (*.xpt).{p_end} + +{p 8 8 2}The procedure is as follows:{p_end} + +{p 8 8 2}(1) {cmd:savasas} uses {help fdasave:fdasave} to save the dataset in memory temporarily to a +SAS xport datafile.{p_end} + +{p 8 8 2}(2) {cmd:savasas} writes a SAS input program to load the data into SAS and to assign variable +names, labels (and formats).{p_end} + +{p 8 8 2}(3) {cmd:savasas} runs the program in SAS in batch mode to load the xport datafile created by +{help fdasave:fdasave}.{p_end} + +{p 12 12 2 }Note to Windows users: This is where the Windows operating system will pop-up windows +that indicate that SAS is running in batch. Do not try to close these windows as that will +potentially halt {cmd:savasas}.{p_end} + +{p 8 8 2}(4) SAS saves the data as whatever version SAS file type was specified.{p_end} + +{p 4 4 2}For Stata SE users: the maximum length for a string variable is 244 characters. +In such cases, the first 200 characters will be taken and passed on to SAS (this is a limitation of +the SAS xport dataset used to transfer data from Stata to SAS).{p_end} + +{p 4 4 2}{cmd:NOTE: savasas} calls SAS to run the SAS program. This requires the ability to +run SAS on your computer. If you do not have a working copy of SAS, use the {cmd:sascode} +option and copy the SAS program ({it:myData}_infile.sas) and the SAS xport datafile +({it:myData}.xpt) to a machine that has a working copy of SAS. The SAS program will +need to be modified to point to the location of the SAS xport datafile.{p_end} + +{p 4 4 2}When {cmd:savasas} has successfully saved your data as a SAS dataset it will display +a message similar to the following:{p_end} + +{p 4}{cmd:savasas} successfully saved the SAS file: *{p_end} + +{p 4}c:\myData\MySASdata.sas7bdat *{p_end} + +{p 4}SAS reports that the dataset has 1000 observations and 20 variables. *{p_end} + + +{title:Options} + +{p 4 8 2}{cmd:type(}{it:version_of_sas_data_file}{cmd:)} specifies the SAS datafile version +desired, from the following list: + +{p 8 8 2}{ul:one of} {space 5}{ul:SAS version datafile}{p_end} + +{p 12 8 2}{cmd:sas}{space 9}current version of SAS * {it:the default if no type specified} *{p_end} + +{p 12 8 2}{cmd:sas6}{space 8}SAS version 6{p_end} + +{p 12 8 2}{cmd:sasx}{space 8}SAS version 6 transport/xport{p_end} + +{p 8 8 2}Hint: If you specify the correct file name extension, you do not have to specify {cmd:type}. +Remember that a current version SAS (.sas7bdat) file will be created if no file extension or type specification +is made.{p_end} + +{p 8 8 2}SAS version 6 and Transport/xport file restrictions:{p_end} + +{p 12 12 2} 1) File names or variable names cannot be longer than 8 characters. +{cmd:savasas} checks for names that are longer than 8 characters; +and, if the {cmd:rename} option is issued, renames them to the first 8 characters or up to 7 plus a number. +In addition, it displays the list of renamed variables.{p_end} + +{p 12 12 2} 2) Variable labels can be a maximum of 40 characters. {cmd:savasas} saves the first 40 +characters.{p_end} + +{p 4 8 2}{cmd:replace} works like Stata's replace in that it allows you to overwrite the SAS data +file if it already exists.{p_end} + +{p 4 8 2}{cmd:formats} specifies that value labels are to be saved as SAS formats in a file that will +have the same name as the datafile but with the ".sas7bcat" file extension. This formats catalog +file will be created in the same directory as the SAS datafile. To use this SAS formats catalog +file you will need to add code to your program to make SAS aware that this file contains format +definitions used by variables in the dataset. Your code should look something like this:{p_end} + +{p 8 8 2}libname in "c:\myData";{p_end} + +{p 8 8 2}options fmtsearch=(in.mySASdataset);{p_end} + +{p 8 8 2} NOTE: SAS user-defined formats for versions prior to SAS version 9 have to be 8 characters or less and cannot end in a number. +This is a list of format names that SAS reserves and thus cannot be user-defined format names:{p_end} + +{p 8 8 2} +{cmd:best}, +{cmd:binary}, +{cmd:comma}, +{cmd:commax}, +{cmd:d}, +{cmd:date}, +{cmd:datetime}, +{cmd:dateampm}, +{cmd:day}, +{cmd:ddmmyy}, +{cmd:dollar}, +{cmd:dollarx}, +{cmd:downame}, +{cmd:e}, +{cmd:eurdfdd}, +{cmd:eurdfde}, +{cmd:eurdfdn}, +{cmd:eurdfdt}, +{cmd:eurdfdwn}, +{cmd:eurdfmn}, +{cmd:eurdfmy}, +{cmd:eurdfwdx}, +{cmd:eurdfwkx}, +{cmd:f}, +{cmd:float}, +{cmd:fract}, +{cmd:hex}, +{cmd:hhmm}, +{cmd:hour}, +{cmd:ib}, +{cmd:ibr}, +{cmd:ieee}, +{cmd:julday}, +{cmd:julian}, +{cmd:percent}, +{cmd:minguo}, +{cmd:mmddyy}, +{cmd:mmss}, +{cmd:mmyy}, +{cmd:monname}, +{cmd:month}, +{cmd:monyy}, +{cmd:negparen}, +{cmd:nengo}, +{cmd:numx}, +{cmd:octal}, +{cmd:pd}, +{cmd:pdjulg}, +{cmd:pdjuli}, +{cmd:pib}, +{cmd:pibr}, +{cmd:pk}, +{cmd:pvalue}, +{cmd:qtr}, +{cmd:qtrr}, +{cmd:rb}, +{cmd:roman}, +{cmd:s370ff}, +{cmd:s370fib}, +{cmd:s370fibu}, +{cmd:s370fpd}, +{cmd:s370fpdu}, +{cmd:s370fpib}, +{cmd:s370frb}, +{cmd:s370fzd}, +{cmd:s370fzdl}, +{cmd:s370fzds}, +{cmd:s370fzdt}, +{cmd:s370fzdu}, +{cmd:ssn}, +{cmd:time}, +{cmd:timeampm}, +{cmd:tod}, +{cmd:weekdate}, +{cmd:weekdatx}, +{cmd:weekday}, +{cmd:worddate}, +{cmd:worddatx}, +{cmd:wordf}, +{cmd:words}, +{cmd:year}, +{cmd:yen}, +{cmd:yymm}, +{cmd:yymmdd}, +{cmd:yymon}, +{cmd:yyq}, +{cmd:yyqr}, +{cmd:z}, +{cmd:zd}{p_end} + +{p 4 8 2}{cmd:savasas} will make some attempt to rename invalid SAS formats but it would be best for +you to rename or drop them yourself before saving to SAS. Formats will be renamed if needed.{p_end} + +{p 4 8 2}{cmd: rename} specifies that any required renaming of file name and/or variable names is +to be done. The {cmd:rename} option is only necessary when saving to SAS 6/transport or when +variable names are not unique in SAS. When saving to SAS 6/transport {cmd:rename} attempts to rename +long variable names (more than 8 characters) to be unique by shortening all long variable names to the +first 8 characters or up to the 7 plus a number. {cmd:savasas} displays the list of renamed variables. +{cmd:rename} also renames the SAS file name when the name provided is not a valid SAS file name.{p_end} + +{p 4 8 2}{cmd:messy} specifies that all the intermediary files created by {cmd:savasas} during +its operation are not to be deleted. The {cmd:messy} option prevents {cmd:savasas} from +cleaning up after it has finished. This option is mostly useful for debugging purposes in +order to find out where something went wrong. All intermediary files have a name starting +with an underscore (_) followed by the process ID and are located in Stata's temp directory.{p_end} + +{p 4 8 2}{cmd:check} specifies that basic stats for both datasets are to be generated to compare +the Stata input dataset with the SAS output dataset in order to make sure {cmd:savasas} +created the files correctly. This is a comparison that should be done after any datafile +is converted to any other type of datafile by any software. The SAS file is created in the +same directory as the output SAS datafile and is named starting with the name of the data +file followed by "_SAScheck.lst" (SAS), for example: "{it:mydata}_SAScheck.lst"{p_end} + +{p 4 8 2}{cmd:sascode} specifies that only a SAS xport datafile and an input SAS program are +to be created. By default, {cmd:savasas} executes all four steps outlined above. The +{cmd:sascode} option aborts this process after step (2). The user then needs to read in +the data {it:manually} using SAS. For example: {cmd:savasas} writes a SAS program {it:myData}_infile.sas +to read in the xport datafile {it:myData}.xpt.{p_end} + + +{title:Examples} + +{p 4 4 2}To save the dataset in memory to the same directory with the same name as the dataset in memory +as a sas7bdat file, type{p_end} + +{p 4 8 2}{cmd:. savasas }{p_end} + +{p 4 4 2}To save the dataset in memory to the current directory with the name mySASdata as a sas7bdat file, type{p_end} + +{p 4 8 2}{cmd:. savasas using mySASdata}{p_end} + +{p 4 4 2}To save the dataset in memory to c:\data\ directory with the name mySASdata as a sas7bdat file +and create 2 check files, type{p_end} + +{p 4 8 2}{cmd:. savasas using c:\data\mySASdata.sas7bdat, check}{p_end} + +{p 4 4 2}To save only variables between var1 and var20 from the dataset in memory to the current directory +with the name mySASdata as a sas7bdat file and create a formats.sas7bcat file containing SAS formats +of any Stata value labels, replacing an existing file if necessary, type{p_end} + +{p 4 8 2}{cmd:. savasas gender-q32_b using mySASdata, formats replace}{p_end} + +{p 4 4 2}More examples:{p_end} + +{p 4 8 2}{cmd:. savasas using mySASdata.sas7bdat, replace }{p_end} + +{p 4 8 2}{cmd:. savasas in 1/30 using mySASdata, type(sas6) check}{p_end} + +{p 4 8 2}{cmd:. savasas using mySASdata, sascode type(sas6)}{p_end} + +{p 4 8 2}{cmd:. savasas using mySASdata, messy type(sasx) rename}{p_end} + + +{title:Setting up savasas} + +{p 4 4 2}If you are setting up this program on your computer for +the first time, please edit {cmd:sasexe.ado} to set the location of your SAS +executable file (sas.exe). If you do not, {cmd:savasas} will look in the "usual" locations for it. +The {cmd:sasexe.ado} file is an ASCII text file and should +be saved as such after editing. Stata's {cmd:do-file} editor will do the trick.{p_end} + +{p 4 4 2}{stata quietly adoedit sasexe:edit sasexe.ado} (click, to edit the {cmd:sasexe.ado} file, remember +to save when done.){p_end} + + +{title:Author} + +{p 4 4 2} +Dan Blanchette {break} +Center of Entrepreneurship and Innovation {break} +Duke University's Fuqua School of Business {break} +Dan.Blanchette@Duke.edu{p_end} + + +{title:Acknowledgements} + +{p 4 4 2} +The user-written program {cmd:outdat} inspired this program.{p_end} + + +{title:Also see} + +{p 4 13 2}On-line: {help fdasave}, {help save}, +{help outdat} (if installed), +{help usesas} (if installed){p_end} + diff --git a/Modules/ado/plus/s/savastata.sas b/Modules/ado/plus/s/savastata.sas new file mode 100644 index 0000000..64ac5eb --- /dev/null +++ b/Modules/ado/plus/s/savastata.sas @@ -0,0 +1,2826 @@ +/************************************************************** + * SAVASTATA should work for you as is, but you may need + * to edit this file to set the values for the macro variables: + * ustata -- if you are using SAVASTATA in a UNIX or Linux environment + * wstata -- if you are using SAVASTATA in a Windows environment + * + * There are instructions further down in this file explaining where + * and how to edit the settings of these macro variables. + * Do a find for "let ustata" or "let wstata". + **************************************************************/ + +run; ** Because the world needs more run statements. **; + + +%MACRO savastata(out_dir,options,sortedby,tfns,nosave,u_dir,U_SE,version=0); +run; %** Because the world needs more run statements. **; +%** If an error has occurred before call to SAVASTATA then fail immediately. **; +%if &syserr.^=0 %then %goto nevrmind; + +/********************************************************************************************* +** Macro: SAVASTATA +** Input: Most recently created SAS work dataset, directory path of where to save the output +** Stata dataset file, and any options. +** Output: A Stata 6, 7, 7-SE, 8, or 8-SE dataset, or an ASCII data file with +** other files created by SAVASTATA to input the data into Stata. +** +** +** Programmer: Dan Blanchette dan.blanchette@duke.edu +** Center for Entrepreneurship and Innovation Duke University's Fuqua School of Business +** Developed at: +** The Carolina Population Center at The University of North Carolina at Chapel Hill, +** Research Computing, UNC-CH, and +** Center for Entrepreneurship and Innovation Duke University's Fuqua School of Business +** Date: 20October2003 +** Modified: 06Nov2009 - Added search for up to Stata 14 and made Stata 11 also use -saveold- +** Now use %sysfunc(lowcase()) instead of %lowcase since that is what %lowcase is. +** Modified: 16Apr2009 - Fixed situations where long variable labels were attempting to be made into +** Stata variable notes and the macro variable &llabvars. messing things up. +** Modified: 13Mar2009 - Now variable labels that are longer than 80 characters are stored as +** variable notes (the truncated label is still the variable label) +** - renamed file to savastata.sas +** - fixed issue when -ascii option specified with no version number. +** - fixed issue when new dataset name submitted and it's name also existed in +** the directory path, like a dataset named with a single letter: d.dta +** Modified: 01Apr2008 - Made it Stata 10 and Stata MP compatible. +** - Made it so that double quotes in string variables can be transferred +** to Stata by replacing them with the cent sybmol and having Stata replace +** the cent signs back to double quotes. This only happens if no string +** variables contain a cent symbol and if saving to Stata 7+. If that is the case, +** the -quotes option still works to replace double quotes with single quotes. +** - Only saves to Stata 9 when using Stata 10 since no benefit to a Stata 10 file. +** - Fixed situtation when -usesas- calls SAVASTATA with char2lab option +** and no other vars have user-defined formats converted vars did not +** get value labels assigned. +** - Added the version of Stata to be used in the -ascii option. +** - Fixed it so when a variable has formats for special missing values and +** use OTHER, LOW or HIGH also, SAVASTATA handles that. +** - Made it so that if a SAS dataset has more than 32,767 vars savastata +** fails with that message rather than dataset is too wide message. +** - Fixed situations where really long user-defined formats (32,000+ +** characters) were being processed. +** - Made help url dynamic so that it is the savastata page when run by +** savastata, or it's the savas or usesas page when run by them. +** - set local macro vars to be local. +** - stopped having Stata sort data after read into Stata since DESCENDING sorts +** and missing values in sorts mess up sorts between SAS and Stata +** Modified: 17Apr2007 - Fixed ability to handle ranges in formats like: 1-3 "first 3" +** - Added restraint of min and max value a format can have since Stata +** cannot make value labels for numbers less than -2,147,483,200 or +** greater than 2,147,483,200 +** - Added check that one format does not exceed 65,536 values which is +** the max for Stata +** - Fixed it so that the there is not added space added to value labels. +** Modified: 07Aug2006 - Added ability to handle non-alphanumeric characters in directory names. +** - Added ability for batch invocation of SAS to set location of ustata +** with the sysparm macro variable. +** - Added checking HOSTNAME when discerning where to log usage. +** Modified: 29May2006 - Fixed char2lab option problem with -usesas- & savas when +** formats were stored in formats.sas7bcat +** Modified: 04Apr2006 - Fixed it so that locations of the Stata executable file +** that have spaces in the directory name no longer crash +** savastata. The %sysexec macro is not supposed to require +** double quotes in such situations but adding double quotes +** fixed the problem. +** Modified: 14Mar2006 - no longer searches for stata.exe when run by -usesas- +** Modified: 13Feb2006 - fixed formatting of special missings issues. +** Modified: 10Nov2005 - fixed when usagelog not set issues. +** Modified: 29Sep2005 - fixed situation where -usesas- calls savastata and savastata closed user's log +** - added max str var length to 244 if Stata version is >= 9.1 +** since Stata 9.1 does not allow you to save as Stata 8 or 9.0 any special missing +** will be lost since -saveold- saves as Stata 7. +** Modified: 09Aug2005 - If using/saving to Stata 9 and using SAS 9, then SAS user-defined formats +** that have a max length of 32,767 characters can have up to the first +** 32,000 (Stata 9's limit) saved as Stata value labels. +** - new option char2lab which runs the SAS macro char2fmt is only helpful +** if using Stata 9 and only allowed if savastata is being run by savas +** or -usesas- since it changes data dramatically +** - check users path for Stata executable, For *nix, "stata" or "stata-se" +** seem to just work so no need to go hunting. +** - does not save data if Stata does not report same number of obs and vars +** - no longer searches for stata.exe when run by -usesas- +** - spaces in directory names (where intermediary files put) in *nix seems to be fixed. +** - for when -usesas- runs savastata, the maxvar setting is not changed if +** savastata suggests a number lower than the user has already specified. +** otherwise savastata sets maxvar to about 10% of the difference of +** (32,766 - (all variables)) +** savastata has successfully worked with 32,766 variables! +** Modified: 24Jun2005 - made sure that if unix/linux directory names had spaces all is still fine +** Modified: 14Jun2005 - fixed it so that directory names with commas in them are okay and problem +** with changing back to pwd that was introduced in 15May2005 version. +** Modified: 15May2005 - fixed it so that directory names with commas in them or +** start with forward slashes (universal filenaming convention) +** are okay. +** - if user has a profile.do that cd's to another directory +** that that is okay. +** Modified: 10May2005 - updated search for Windows Stata executable file to find up to +** version 12 Stata (if directory naming conventions stay predictable) +** - made work when user does not have Stata and wants to save to ascii file +** - made work when user has profile.do changing directories on savastata +** This introduces problems when Unix/Linux directory contains a double quote... +** but what good Unix/Linux user would name a directory containing a double quote?! +** Modified: 22Mar2005 - fixed problems related to when a new dataset name provided +** Modified: 08Dec2004 - The new name of the Stata datafile can be upper case or mix case. +** Modified: 09Nov2004 - User can now specify the name of the Stata datafile they want. +** %savastata("C:\MyProject\My{98}Stata!Data.dta", replace ); +** This is helpful if they want to use an invalid SAS filename but valid Stata file name. +** !The Stata dataset name must end in ".dta"! +** - Thanks to West, bug fixed that was related formats using the "Other" category. +** Modified: 26Oct2004 - Stopped allowing user to set what version of Stata they are using. SAVASTATA will always figure it out. +** - also changed note in log to report Stata version as integer instead of 8.2 since the version of +** a dataset is not that specific. +** Modified: 22Jul2004 - fixed bug with numeric variables that had both positive and negative +** formatted values, and made a few tweaks, one of which is that the raw +** ascii data file in the work +** directory is deleted when savastata successfully completes. +** Modified: 27Apr2004 - fixed macro so that setting use8SE=1 does not generate error messages +** about macro variable VER. +** - fixed warning message about script macro var when usagelog not used. +** - added more locations to find the windows Stata executable. +** Modified: 26Feb2004 - memory setting fix for -usesas- +** Modified: 03Feb2004 1) when -usesas- calls macro memory will not be reset if not needed. +** 2) no longer closes existing logs when called by -usesas- . +** +** Disclaimer: This program is free to use and to distribute as long as credit is given to +** Dan Blanchette +** Center for Entrepreneurship and Innovation +** Duke University's Fuqua School of Business. +** +** There is no warranty on this software either expressed or implied. This program +** is released under the terms and conditions of GNU General Public License. +** +** Comments: +** SAVASTATA SAS macro when implemented by the SAS System saves the most recently created +** SAS dataset in the WORK library to a Stata dataset. SAVASTATA requires that you have a +** working copy of SAS and a working copy of Stata Intercooled or SE on your computer to run +** successfully. If your SAS dataset is small enough SAVASTATA may work on Stata Small +** (Student Version). +** If your SAS dataset is using formats that are in a formats catalog (work.formats or +** library.formats), SAVASTATA will make an attempt to preserve them as value labels in +** Stata. Stata does not allow all the variations of user-defined formats that SAS offers. +** +** SAVASTATA may take a few minutes to save your dataset. +** +** SAVASTATA will work in SAS interactive mode or in SAS batch mode. +** SAVASTATA will run on various operating systems including: Windows, Red Hat Linux, AIX. +** It may work fine on others as well. +** +** SAVASTATA uses the most recently created dataset in the work directory, +** figures out how best to store the data as a Stata dataset, keeps most date +** formats and other basic formats for numeric variables, checks for invalid +** Stata variable names, if using or outputting to Stata6: checks to see if long variable +** names need to be shortened, prints them to the SAS log and shortens them, writes out +** the SAS dataset to an ASCII data file, attempts to preserve all user-defined formats for +** numeric variables, writes out Stata do-files, and submits them to Stata in batch mode +** in order to have Stata read the data in and save it as a Stata dataset. +** +** Restrictions of each version of Stata: +** 1. Variable names can be no more than 8 characters long: Stata 6 +** 2. Variable names can be up to 32 characters long: Stata 7 and 8 +** 3. String variables can contain a maximum of 80 characters: Stata 6, 7 and 8 Intercooled. +** 4. String variables can contain a maximum of 244 characters: Stata 7 and 8 SE. +** 5. The maximum number of variables is 2,047: Stata 6, 7, and 8 Intercooled +** 6. The maximum number of variables is 32,766: Stata 7 +** 7. The maximum number of variables is 32,767: Stata 8 and 9 SE +** 8. Special missings (.a through .z) for numeric data are allowed: Stata 8 +** +** +** -- SAVASTATA can run on SAS ver 7, 8 or 9 +** -- SAVASTATA can run in the following environments: Windows, RS6000, SUN , LINUX +** and maybe on many others. +** +** REQUIRED INPUT TO SAVASTATA: +** -- SAVASTATA needs to have the most recently created dataset by SAS to be in the +** work directory. +** -- SAVASTATA needs to know what directory to put the Stata dataset and possibly +** the files used to input the data to Stata that are written by savastata. +** These are the only required input, but you may choose to make use of the +** following options. +** +** LIST OF OPTIONS: +** NOTE: Options can be used in any order. You can specify as many as you want +** or none at all. +** The following three options work as they do in Stata: +** -replace -- If the Stata dataset you want to output already exists, then overwrite it with +** the dataset generated by savastata. +** +** -old -- Outputs a Stata 6 dataset if using Stata 7 or Stata 7-SE, +** or a Stata 7 Intercooled dataset if using Stata 8 Intercooled +** or a Stata 7-SE dataset if you are using Stata 8-SE. +** +** -intercooled -- Outputs a Stata Intercooled dataset if using Stata SE or Stata MP. +** +** NOTE: If you do not specify what version of Stata to save in, Stata will save the +** dataset in the current version. +** +** -float -- Numeric variables that contain decimals will be stored as float instead of the +** default of double. This may result in a loss of precision, but float is the +** default storage type that Stata uses. This will help decrease your filesize. +** +** -quotes -- Replace double quotes ( " ) occurring in character variables with single quotes ( ' ) +** and replace compound quotes ( `" or "' ) occurring in variable labels or formats +** with single quotes ( ' ). +** SAVASTATA cannot process character variables with double quotes or variable +** labels or formats with compound quotes. +** +** -messy -- Puts the files generated by SAVASTATA used to create the Stata dataset in the directory +** named in the pathname provided in the call to the SAVASTATA macro. +** +** -check -- Creates two check files for the user to compare the SAS input dataset with +** the Stata output dataset to make sure SAVASTATA created the files correctly. +** This is a comparison that should be done after any data file is converted +** to any other type of data file by any software. The files are +** created in the same directory as the output Stata data file and are named +** starting with the name of the data file followed by either "_SAScheck.lst" +** or "_STATAcheck.log", e.g. "mydata_SAScheck.lst" and "mydata_STATAcheck.log". +** The SAS check file contains output from proc means, +** proc contents (by position), and a proc print of the first 5 observations. +** The Stata check file contains the equivalent output by the commands summarize, +** describe, and a list of the first 5 observations. +** +** -ascii -- Outputs only the ASCII data file and does not save your dataset in Stata format. +** It also turns on "-messy" switch so that the Stata input files are +** not deleted after your program has run. Use this switch to make your own +** edits to the input of these data into Stata. Use this option if you do not +** have Stata on the same computer that you have SAS. The files generated by +** SAVASTATA can be moved to another computer that does have Stata and run there to +** create the Stata dataset. +** +** The default version of Stata that your ascii file will be set to be used for +** will be Stata 6 (only allow up to 2,047 variables). +** +** If you want to specify what version of Stata will be used to read the ascii +** data you can do so like so: +** -ascii9SE (for Stata 9 SE/MP) +** -ascii9 (for Stata 9 Intercooled) +** -ascii10MP (for Stata 10 SE/MP) +** -ascii8 (for Stata 8 Intercooled) +** +** Stata versions with decimal values are invalid: +** -ascii9.2SE IS INVALID VERSION, just specify: -ascii9SE +** -ascii 9.2 SE IT IS INVALID TO USE SPACES, just specify: -ascii9SE +** +** You can also use options -old and -intercooled to changed what version the data set +** will be saved as. +** +** +** -char2lab - Runs the CHAR2FMT macro but only if SAVASTATA invoked by savas script or -usesas- +** because CHAR2FMT changes the user's dataset in a dramatic way. +** CHAR2FMT converts long character variables to numeric vars and stores character data +** in user-defined formats which get translated into Stata value labels which have +** a maximum length of 32,000 characters (new feature in Stata 9). +** +** SETTING UP SAVASTATA +** These are instructions to edit the savastata.sas file. +** +** NOTE: If you are setting up this macro on your computer for the first time, +** please choose which version of Stata you are going to have SAVASTATA use. +** If you do not choose to set one of the following switches, SAVASTATA will +** figure out what version of Stata you are running for you. This may +** add a noticeable amount of time to processing so you may want to set these +** switches to the correct version of Stata. You can easily figure out what +** version of Stata you are using by looking at the top of your results window +** in Stata or by typing in the command -about- at the Stata command line. +** One advantage of leaving SAVASTATA to figure out what version of Stata is +** being used is that when you upgrade your version of Stata you will not have to +** update savastata. +** +** NOTE: +** -- If you are running SAVASTATA on UNIX or Linux then +** you need to be able to start a Stata batch job by: +** stata -b do mydofile.do +** If not, then change the setting of the ustata macro variable. +**********************************************************************************************/ + %local ustata; +/** One of these may work: ** + %let ustata=/usr/local/stata/stata; + %let ustata=/usr/local/stata/stata-mp; + %let ustata=/usr/local/stata/stata-se; */ + %let ustata=stata; + + + %** tfns is only submitted by savas and -usesas- and savas may set the location of Stata **; + %* savas may invoke SAS like so: sas -sysparm /alt_location/stata my_sas.sas **; + %if "&tfns."^="" and "&sysparm."^="" and %sysfunc(fileexist("&sysparm.")) %then %do; + %let ustata=%nrbquote(&sysparm.); + %end; + + + +/********************************************************************************************** +** +** -- If you are running SAVASTATA on Windows, you need to tell SAVASTATA where the Stata +** executable file is located. +** If you do not know where your Stata executable file is located, find your Stata +** short-cut icon, right click on it, choose "properties", and look in the "target" field. +** This will show you where the Stata executable file is located on your hard drive. +** +***********************************************************************************************/ + %local wstata; +%** Change what is inside the parentheses to the location of your Stata executable file **; +/** One of these may work: **; + %let wstata=%nrstr(C:\Stata\wsestata.exe); + %let wstata=%nrstr(C:\Stata\wmpstata.exe); */ + %let wstata=%nrstr(C:\Stata\wstata.exe); + + +/** SAVASTATA will try the following (plus up to ver 12) if the first does not work: + %let wstata=%nrstr(C:\Stata9\wsestata.exe); ** Stata 9 SE **; + %let wstata=%nrstr(C:\Stata9\wmpstata.exe); ** Stata 9 MP **; + %let wstata=%nrstr(C:\Stata8\wsestata.exe); ** Stata 8 SE **; + %let wstata=%nrstr(C:\Program Files\Stata8\wsestata.exe); ** Stata 8 SE **; + %let wstata=%nrstr(D:\Stata8\wsestata.exe); ** Stata 8 SE **; + %let wstata=%nrstr(C:\Program Files\Stata8\wstata.exe); ** Stata 8 **; + %let wstata=%nrstr(D:\Stata8\wstata.exe); ** Stata 8 **; + %let wstata=%nrstr(C:\Stata8\wsestata.exe); ** Stata 8 SE **; + %let wstata=%nrstr(C:\Stata7\wstata.exe); ** Stata 7 or 7 SE **; + %let wstata=%nrstr(C:\Stata\wstata.exe); ** Stata 6 or 7 or 8, the catcher **; + ** then SAVASTATA searches your path ** + ************************************************/ + + + + +/********************************************************************************************* +** +** HOW TO USE THE SAVASTATA MACRO: +** Using the SAVASTATA macro requires that you understand how to use the "%include" statement +** and that you know how to call a SAS macro. +** +** %include'LOCATION AND NAME OF A FILE THAT CONTAINS SAS CODE'; +** +** For example, if you have copied this file to "C:\SASmacros", then you tell SAS +** about this macro by adding the following line to your SAS program: +** +** %include 'C:\SASmacros\savastata.sas'; +** +** This statement makes SAS aware of the SAVASTATA macro which is in the file savastata.sas. +** To use the macro you have to make a call to it. To do that you add a line like the +** following to your SAS program: +** +** %savastata(C:\mySASdir\,-old); +** +** The information inside the parentheses is passed on to the SAVASTATA macro. The first +** string of information is the location you want to save your SAS dataset as a Stata dataset. +** This is somewhat like a libname statement. The second string of information is the options +** you wish to pass on to the SAVASTATA macro. You can use as many options as you like or none at all. +** +** +** EXAMPLE USE OF THE SAVASTATA MACRO: +** %include 'C:\SASmacros\savastata.sas'; ** Include macro once in a SAS session and call it **; +** * as many times as you like in that session. **; +** +** data work.ToBeStata; ** This makes a copy of the SAS dataset in the in the WORK library. **; +** set in.mySASfile; +** run; +** +** +** %savastata(C:\mydata\,); ** Saves the dataset in the C:\mydata\ directory if it does not **; +** * already exist in that directory. **; +** +** OTHER EXAMPLE CALLS: +** +** %savastata(C:\mydata\,-replace); ** Saves the dataset C:\mydata\, overwriting it if **; +** * it already exists. **; +** +** %savastata(C:\data\,-old); ** Saves the dataset as the previous version of Stata **; +** * in C:\data\ directory **; +** +** %savastata(C:\data\,-old -replace); ** Saves the dataset as the previous version of Stata **; +** * in C:\data\ directory, overwriting it if it **; +** * already exists. **; +** +** The -intercooled option starting with Stata 10 only checks for more than 2,047 vars. It does not +** save the dataset as an intercooled dataset since starting with Stata 10 that is no longer +** an option. +** %savastata(C:\data\,-intercooled); ** Saves the dataset as the Intercooled version of Stata **; +** * in C:\data\ directory. This is only possible if **; +** * your version of Stata is an SE edition. **; +** +** %savastata(/project/data/,-old -intercooled); ** Saves the dataset as previous version of **; +** * Stata Intercooled in the /project/data/ **; +** * directory **; +** +** +***********************************************************************************************/ + +%local usagelog; +%** SET LOCATION OF USAGE LOG FILE **; +%let usagelog="specify what file name and location you want here"; +%if "&sysscp."="WIN" %then %do; + %let usagelog="x:\software\temp\savas_usage.log"; %* windoze *; +%end; +%else %if "&sysscp."="RS6000" %then %do; + %let usagelog="/afs/isis.unc.edu/home/d/a/danb/usage/savas_usage.log"; %* AIX nodes *; +%end; +%else %if "&sysscp."="AIX 64" %then %do; + %let usagelog="/afs/isis.unc.edu/home/d/a/danb/usage/savas_usage.log"; %* AIX nodes *; +%end; +%else %if "&sysscp."="LINUX" %then %do; %* linux boxes *; + %if %index(%qlowcase(%qcmpres(%sysget(HOSTNAME))),"gromit") = 1 + or %index(%qlowcase(%qcmpres(%sysget(HOSTNAME))),"sig") = 1 + or %index(%qlowcase(%qcmpres(%sysget(HOSTNAME))),".cpc.") ^= 0 %then + %let usagelog="/afs/isis.unc.edu/home/d/a/danb/usage/savas_usage.log"; + %else %let usagelog="/afs/isis.unc.edu/home/d/a/danb/usage/savas_usage.log"; +%end; +%else %if %index(%qupcase(&sysscp.),SUN) %then %do; + %let usagelog="/afs/isis.unc.edu/home/d/a/danb/usage/savas_usage.log"; +%end; +%else %do; + %let usagelog="/afs/isis.unc.edu/home/d/a/danb/usage/savas_usage.log"; +%end; + + +/***************************************************************************/ +/****** !NO MORE EDITS TO THE MACRO SHOULD BE MADE BEYOND THIS POINT! ******/ +/***************************************************************************/ + +%** local macro vars used in savastata **; +%local ascii avars bign bign1 bvar bytemax bytemin ch char2fmthttp char2lab + check cq crdate cv decpos diffhour diffmin diffsec dq dq1 + dq_fail dq_fix dyc dy dy_and_dq_fail + drive dset dta_exists fail fail11 fail20 fail23 fb fe fdset + flavor flibr float http i ii intmax intmin intrcool isysver + j jj k kk labtrunc ldset librfmts llabvars ln lo longname + longmax longmin max_clen_count maxobs maxreclen maxstrvarlen maxvallablen maxvar messy MP + name newname nobs noisily notes nv ob obs old pwdir + pwdrive quietly quotes reclen replace s_dsn s_last s_SEver s_ver script + SE slash sm sprog startdat success temp_dir u_SEver u_sysrc + u_ver udset unix uspace var_c var_n vlabels work_dir workfmts w_sysrc; + +%** make sure sas version is an integer so it can be properly evaluated **; +%let isysver = %sysevalf(&sysver.,integer); + + %** Save option settings so they can be restored at the end of this macro. **; +%let notes=%sysfunc(getoption(notes)); + +%let obs=%sysfunc(getoption(obs)); + +options obs=MAX; %*** Reason for maximizing it is because user could have **; + %* set it lower than the number of variables in the dataset. **; +options nonotes; %** Shut off notes while program is running in order to reduce log size. **; + +%** Time how long SAVASTATA takes to run **; +%let startdat=%sysfunc(datetime()); + +%** initialize macro vars **; +%let diffhour=0; +%let diffmin=0; +%let diffsec=0; +%let fail=0; +%let success=0; + +%** if out_dir is surrounded by double or single quotes, remove them. **; +%if %nrbquote(%index(%nrbquote(&out_dir.),%str(%")))=1 + or %nrbquote(%index(%nrbquote(&out_dir.),%str(%')))=1 + %then %let out_dir=%nrbquote(%substr(%nrbquote(&out_dir.),2,%length(%nrbquote(&out_dir.))-2)); + +%if %nrbquote(%index(%nrbquote(&u_dir.),%str(%")))=1 or %nrbquote(%index(%nrbquote(&u_dir.),%str(%')))=1 + %then %let u_dir=%nrbquote(%substr(%nrbquote(&u_dir.),2,%length(%nrbquote(&u_dir.))-2)); + + +%** initialize var **; +%let newname=; + +%** check to see if new dataset name provided in %nrbquote(&out_dir.) **; +%if %nrbquote(%length(&out_dir.)) > 0 %then %do; + %if %nrbquote(%index(%qlowcase(&out_dir.),.dta)) %then %do; + %** if Stata dataset name provided with directory info **; + %if "%qlowcase(%substr(%nrbquote(&out_dir.),%length(%nrbquote(&out_dir.))-3,4))"=".dta" %then %do; + %** if no backslash provided: savstata(d:mydata.dta) then add in the backslash **; + %if "&sysscp."="WIN" + and %nrbquote(%index(%nrbquote(&out_dir.),:)) = 2 and %nrbquote(%index(%nrbquote(&out_dir.),\)) ^= 3 %then + %let out_dir = %nrbquote(%substr(%nrbquote(&out_dir.),1,2)\%substr(%nrbquote(&out_dir.),3,%length(%nrbquote(&out_dir.))-2)); + %let newname=%nrbquote(%substr(%nrbquote(&out_dir.),1,%length(%nrbquote(&out_dir.))-4)); + %if %index(%nrbquote(&newname.),\) %then %do; + %do %while(%nrbquote(%index(%nrbquote(&newname.),\))); + %let newname=%nrbquote(%substr(%nrbquote(&newname.),%index(%nrbquote(&newname.),\)+1,%length(&newname.)-(%index(%nrbquote(&newname.),\)))); + %end; + %let out_dir=%nrbquote(%substr(%nrbquote(&out_dir.),1,%index(%nrbquote(&out_dir.),%nrbquote(&newname.))-1)); + %end; + %else %if %index(%nrbquote(&newname.),/) %then %do; + %do %while(%nrbquote(%index(%nrbquote(&newname.),/))); + %let newname=%nrbquote(%substr(%nrbquote(&newname.),%index(%nrbquote(&newname.),/)+1,%length(&newname.)-(%index(%nrbquote(&newname.),/)))); + %end; + %let out_dir=%nrbquote(%substr(%nrbquote(&out_dir.),1,%eval(%length(%nrbquote(&out_dir.))-%length(%nrbquote(&newname..dta))))); + %end; + %else %let out_dir=; %** only new name provided **; + %end; + %end; %** end of if %index(%nrbquote(&out_dir.),.dta) do loop **; +%end; %** end of if length(%nrbquote(&out_dir.)) = 0 do loop **; + + +%let s_dsn=&sysdsn.; %** preserve these to restore after setting up usagelog **; + +%** script var is definitive way to determine how savastata was called, **; + %* if empty then not called by either -usesas- or savas **; +%let script=; +%if "&tfns." ^= "" and "&nosave."="nosave" %then %do; + %let script=usesas; +%end; +%else %if "&tfns."^="" and "&nosave."="" %then %do; + %let script=savas; +%end; + +%** log usage of savastata if usage log file exists **; +%if %sysfunc(fileexist(&usagelog.)) %then %do; + data _null_; + file &usagelog. mod; + %if "&script."="" %then %do; + put " "; + date=datetime() ; + put " savastata macro " date dateampm. ; + %end; + put " &sysuserid. savastata( &out_dir.,&options.,&sortedby.,&tfns.,&nosave.,&u_dir.,&U_SE.)"; +%end; + +%let sysdsn=&s_dsn.; %** restore after setting up usagelog **; + +%let noisily = ; +%let quietly = ; +%if "&script." = "usesas" %then %do; + options nonotes nodate ; + %let noisily =noisily; + %let quietly =quietly; + %** proc printto prints any weird error messages that SAS has to this log file in a nice, *; + %* readable format because -usesas- looks for this file and prints it to the results window **; + proc printto log="&out_dir._&tfns._report.log"; run; +%end; + + +%** current website address for savastata, usesas, or savas help: **; + %* used in fail messages at end of macro **; +%let sprog=savastata; +%if "&script." ^="" %then %let sprog=&script.; +%let http=%nrstr(http://faculty.fuqua.duke.edu/home/blanc004/data_programming/sas_to_stata/)&sprog..html; +%let char2fmthttp=%nrstr(http://faculty.fuqua.duke.edu/home/blanc004/data_programming/sas_to_stata/char2fmt.html); + +%** Find out what directory SAS currently is using as the present working directory **; + %* so that it can be restored at end of macro. **; +libname ________ " "; %** ________ is a very unlikely libname **; +%let pwdir=%nrbquote(%sysfunc(pathname(________))); +%let pwdrive= ; +%if %index(%nrbquote(&pwdir.),\) %THEN %do; + %let pwdrive= %qsubstr(%nrbquote(&pwdir.),1,2); %** get drive info eg. "d:" **; +%end; + + +%** if no temporary filenames are supplied then use sysjobid macro var **; +%if %length(&tfns.)=0 %then %let tfns=&sysjobid.&sysindex.; + %** Have macro var that will increase each time macro run for **; + %* times when one SAS session runs savastata macro multiple **; + %* times and -messy option specified. ***; + + +%*** Use the most recently created SAS work dataset. ***; +%let s_last=&syslast.; +%let ldset=%length(&syslast.); +%let decpos=%index(&syslast.,.); +%let dset=%substr(&syslast.,&decpos.+1,&ldset.-&decpos.); + +%** use the work directory to store the temporary SAS files that this program creates ***; +%let temp_dir = %nrbquote(%sysfunc(pathname(work))); +%let work_dir = %nrbquote(%sysfunc(pathname(work))); + +%** this is first time program goes to a fail label **; +%** Work directory cannot start with a back slash because savastata needs to cd to it. **; +%if %index(%nrbquote(&work_dir.),\)=1 %then %goto fail18; + +%** Figure out whether the operating system uses forward slashes or back slashes in **; + %* directory paths and make sure that out_dir has the appropriate slash at the end. **; +%let unix=0; +%let drive= ; +%IF %index(%nrbquote(&temp_dir.),\) %THEN %do; + %let unix=0; %** unix=0 implies windows platform **; + %let drive= %qsubstr("&work_dir.",2,2); %** get drive info eg. "d:" **; + %let temp_dir = %nrbquote(&temp_dir.)\; %** tack on a back slash **; + %if "&out_dir."="" %then %goto fail4; + %else %if "&out_dir."=" " %then %goto fail4; + %else %if "&out_dir."="." %then %goto fail4; + %let slash= %qsubstr("&out_dir.",%length("&out_dir.")-1,1); %** check if back slash at end **; + %if "&slash."^="\" %THEN %do; + %let out_dir= %nrbquote(&out_dir.)\; %** add a back slash at end if it is not there already **; + %end; +%END; +%ELSE %IF %index(%nrbquote(&temp_dir.),/) %THEN %do; + %let unix=1; %** unix or unix-like platform **; + %let temp_dir = %nrbquote(&temp_dir.)/; %** tack on a forward slash **; + %** make sure that out_dir is not a relative directory name like: ../mydata/ **; + libname ________ "&out_dir."; %** ________ is a very unlikely libname **; + %let out_dir=%nrbquote(%sysfunc(pathname(________))); + %let slash= %qsubstr("&out_dir.",%length("&out_dir.")-1,1); %** check if back slash at end **; + %if "&slash."^="/" %THEN %do; + %let out_dir= %nrbquote(&out_dir.)/; %** add a forward slash at end if it is not there already **; + %end; +%END; %** ELSE IF index("temp_dir",/) THEN do loop **; + + + +%** Make sure the dataset name and any option passed to savastata is in lower case. **; +%let dset=%sysfunc(lowcase(%nrbquote(&dset.))); +%if %length(&newname.)>0 %then %let fdset=%nrbquote(&newname.); +%else %let fdset=%sysfunc(lowcase(%nrbquote(&dset.))); +%let options=%sysfunc(lowcase(%nrbquote(&options.))); + +%let udset=%qupcase(&fdset.); + +%if %index(&syslast.,WORK)^=1 %then %goto fail1; + +%** if obs are set to zero, error in program previous to savastata **; +%if &obs.=0 %then %goto fail13; + + +%if &udset.=_CONTEN + or &udset.=_CONTEN1 + or &udset.=_CONTEN2 + or &udset.=_CONTEN3 %then %goto fail3; + + +%** initialize macro var **; +%let workfmts=0; +%let librfmts=0; +%let vlabels=0; + +%** check to see if format libraries exist **; +%let workfmts=%sysfunc(cexist(WORK.FORMATS)); +%** cexist tests to see if catalog file created for current OS + %* if it was not, then librfmts = 0 even if library.formats does exist *; +%let librfmts=%sysfunc(cexist(LIBRARY.FORMATS)); +%if &workfmts.=1 or &librfmts.=1 %then %let vlabels=1; + + %** Initialize macro vars for savastata options **; +%let ascii=0; +%let float=0; +%let quotes=0; +%let messy=0; +%let intrcool= ; +%let old= ; +%let replace= ; +%let check=0; +%let char2lab=0; + +%if %nrstr(&options.)^=%nrstr() %then %do; + %** Find out what options were specified **; + %if %index(&options.,ascii) %then %let ascii=1; %** set ascii option **; + %if %index(&options.,fl) %then %let float=1; %** set float option **; + %if %index(&options.,qu) %then %let quotes=1; %** set quote option **; + %if %index(&options.,mes) %then %let messy=1; %** set messy option **; + %if %index(&options.,old) %then %let old=old; %** set old option **; + %if %index(&options.,int) %then %let intrcool=intercooled; %** set intrcool option **; + %if %index(&options.,rep) %then %let replace=replace; %** set replace option **; + %if %index(&options.,rpl) %then %let replace=replace; %** set replace option **; + %if %index(&options.,che) %then %let check=1; %** set check option **; + %if %index(&options.,cha) %then %let char2lab=1; %** set char2lab option **; +%end; + +%** initialize vars to default setting of Stata if you know you what version of Stata you have **; +%** Need to set all if you set any. **; +%let u_ver=0.0; %** version of Stata that is being used. decimal values are okay. *; + %* set this if you do not want Stata to be run just figure out what *; + %* version of Stata you are using. *; +%let s_ver=0.0; %** version of Stata that data will be saved as. *; + %* set this only if you set the u_ver variable. *; + %* old option will change this if used **; +%let u_SEver=0; %** 1 if SE/MP version of Stata that is being used. *; +%let s_SEver=0; %** 1 if SE/MP version of Stata that data will be saved as. *; + %* intercooled option will change this if used **; + +%* make sure these macro vars are numbers. **; + %** Stata versions are multiplied by 10 so that no decimal places exist **; +%let u_ver=%sysevalf(&u_ver.*10,integer); +%let s_ver=%sysevalf(&s_ver.*10,integer); + +%* test that save version is not higher than the using version *; +%if &s_ver. > &u_ver. %then %goto fail2; +%if not (&u_SEver.=0 or &u_SEver.=1) %then %goto fail2; +%if not (&s_SEver.=0 or &s_SEver.=1) %then %goto fail2; +%** cannot use Intercooled and save to SE **; +%if (&u_SEver.=0 and &s_SEver.=1) %then %goto fail2; + +%if &ascii.=1 %then %do; + %** Need to save all the files if ascii specified. **; + %if &messy.=0 %then %let messy=1; + + %let ascii_ver=%qsubstr(&options.,%index(&options.,ascii),%eval(%length(&options.)-%index(&options.,ascii)+1) ); + %let ascii_ver=%scan(&ascii_ver.,1,%nrstr( )); + %if &ascii_ver. = ascii %then %do; + %let ascii_ver= ; %** use default settings **; + %end; + %else %do; + %let ascii_ver=%qsubstr(&ascii_ver.,6,%eval(%length(&ascii_ver.)-5)); + %end; + %if &ascii_ver. = %then %do; + %* use defaults settings. **; + %end; + %else %do; + %* figure out what version user specified: *; + %let blen=%length(&ascii_ver.); + %** replace "se" with a blank **; + %let ascii_ver=%cmpres(%sysfunc(translate(&ascii_ver.,%nrstr( ), se))); + %let alen=%length(&ascii_ver.); + %if &alen. < &blen. %then %do; + %let u_SEver=1; + %if &intrcool.^=intercooled %then %let s_SEver=1; + %end; + %else %do; + %let blen=%length(&ascii_ver.); + %** replace "mp" with a blank **; + %let ascii_ver=%cmpres(%sysfunc(translate(&ascii_ver.,%nrstr( ), mp))); + %let alen=%length(&ascii_ver.); + %if &alen. < &blen. %then %do; + %let u_SEver=1; + %if &intrcool.^=intercooled %then %let s_SEver=1; + %end; + %end; %** end of if either SE or MP was specified **; + %** < 2000 is just an extremely high version of Stata **; + %if 0 < &ascii_ver. and &ascii_ver. < 2000 %then %do; + %* ascii_ver is a number *; + %let u_ver=&ascii_ver.; + %let u_ver=%sysevalf(&u_ver.*10,integer); + %if &old.=old %then %do; + %if &ascii_ver.=9 %then %do; + %let s_ver=%eval(&ascii_ver. - 2); + %let s_SEver=0; %** Stata 9 saves old only to Stata 7 IC **; + %let intrcool=intercooled; %** setting intrcool to intercooled makes this work **; + %* as s_SEver gets set to u_SEver later **; + %end; + %else %let s_ver=%eval(&ascii_ver. - 1); + %end; + %else %let s_ver=&u_ver.; + %let s_ver=%sysevalf(&s_ver.*10,integer); + %end; + %end; + %* change of default settings based on old and intercooled will be changed later **; +%end; %** end of if ascii=1; + + +%** check to see if user has set up Windows Stata correctly. **; +%** if not then check other likely places the Stata executable would be. **; +%let fail20=0; + %** do not need the stata.exe when ascii or -usesas- running it *; +%if not (&ascii.=1 or "&script." = "usesas") %then %do; + %if &unix.=0 and %sysfunc(fileexist("&wstata."))=0 %then %do %while(&fail20.=0); + %let drives =C D Y; + %let exe =wsestata wmpstata wstata; + %let versions =14 13 12 11 10 9 8 7 6; + %do i = 1 %to 3; %** one for each drive **; + %let ii =%scan(&drives.,&i.,%nrstr( )); + %do j = 1 %to 3; %** one for each exe of stata **; + %let jj =%scan(&exe.,&j.,%nrstr( )); + %do k = 1 %to 7; %** one for each version of stata **; + %let kk =%scan(&versions.,&k.,%nrstr( )); + + %let wstata=%str(&ii.:\Stata&kk.\&jj..exe); + %if %sysfunc(fileexist("&wstata."))=0 %then %do; + %let wstata=%str(&ii.:\Program Files\Stata-&kk.\&jj..exe); %** Stata-9 **; + %end; + %else %goto exist; %** file exists **; + %if %sysfunc(fileexist("&wstata."))=0 %then %do; + %let wstata=%str(&ii.:\Program Files\Stata&kk.\&jj..exe); %** Stata9 **; + %end; + %else %goto exist; %** file exists **; + %if %sysfunc(fileexist("&wstata."))=0 %then %do; + %let wstata=%str(&ii.:\Stata-&kk.\&jj..exe); %** Stata-9 **; + %end; + %else %goto exist; %** file exists **; + %if %sysfunc(fileexist("&wstata."))=0 %then %do; + %let wstata=%str(&ii.:\Stata&kk.\&jj..exe); %** Stata9 **; + %end; + %else %goto exist; %** file exists **; + %if %sysfunc(fileexist("&wstata."))=0 %then %do; + %let wstata=%str(&ii.:\Stata\&jj..exe); + %end; + %else %goto exist; %** file exists **; + %if %sysfunc(fileexist("&wstata."))=0 %then %do; + %** nothing **; + %end; + %else %goto exist; %** file exists **; + %end; %** of k loop **; + %end; %** of j loop **; + %end; %** of i loop **; + %do; %** check path for Stata executable **; + %let i=1; + %let delim=%str(;); + %do %until (%qscan(%sysget(PATH),&i.,%str(&delim.)) = ); + %let wstata="%qscan(%sysget(PATH),&i.,%str(&delim.))\wsestata.exe"; + %if %sysfunc(fileexist("&wstata."))=0 %then + %let wstata="%qscan(%sysget(PATH),&i.,%str(&delim.))\wmpstata.exe"; + %if %sysfunc(fileexist("&wstata."))=0 %then + %let wstata="%qscan(%sysget(PATH),&i.,%str(&delim.))\wstata.exe"; + %if %sysfunc(fileexist("&wstata.")) %then %do; + %let fail20=2; + %let i=200000; %** break loop if found it **; + %end; + %let i=%eval(&i.+1); + %end; + %if fail20=2 %then %goto exist; %** file exists **; + %end; %** of checking path for Stata executable **; + %if %sysfunc(fileexist("&wstata."))=0 %then %do; + %let wstata=NO STATA EXECUTABLE FOUND; + %let fail20=1; %** give up **; + %end; + %exist: ; + %if &fail20.=0 %then %let fail20=2; %** found file so break while loop **; + %end; %** end of if unix=0 then do while loop **; + +%end; %** end of if &ascii. = 0 and &script. = "usesas" **; + +%if &fail20.=1 %then %goto fail20; + + +libname ________ "&out_dir."; %** ________ is a very unlikely libname **; +%if &syslibrc.^=0 %then %do; + libname ________ clear; %** do away with it now **; + %goto fail5; %** exit if not a valid pathname **; +%end; + +libname ________ clear; %** do away with it now **; + +%* -usesas- sets messy to on so it can contol where the files are put **; +%if &messy.=1 %then %do; + %** Use the output directory to store the SAS program files that this macro creates. ***; + %let temp_dir = %nrbquote(&out_dir.); + %let work_dir = %nrbquote(&out_dir.); + %if &unix.=0 %then %do; + %let windrive= %qsubstr("&out_dir.",2,2); %** get drive info eg. "d:" **; + %sysexec &windrive.; ** change to whatever drive files are going **; + %end; + %** sysexec requires no quotes even when changing to dirs with spaces in windows or unix **; + %sysexec cd %nrbquote(&out_dir.) ; %** change to the drive and directory where the Stata do-files are. **; +%end; + +%if "&u_dir."^="" %then %do; %** this happens when -usesas- or savas script call savastata **; + %let out_dir = %nrbquote(&u_dir.); +%end; + +%** run Stata to find out what version of Stata is being used. **; + %* -usesas- passes &version. to savastata but savas needs to figure it out here **; + %* Stata versions are multiplied by 10 so that no decimal places exist **; +%if &script.=usesas %then %do; + %** force this since a -usesas- user could have incorrectly preset this **; + %let u_ver=%sysevalf(&version.*10,integer); + %** force this since a -usesas- user could have incorrectly preset this **; + %* and -usesas- needs to have s_ver = u_ver since it does not save data. **; + %let s_ver=&u_ver.; + /** U_SE should only equal either 1 or 0: `= ("`c(SE)'" == "1") + ("`c(MP)'" == "1")' **/ + %if &U_SE.>=1 %then %let u_SEver=1; +%end; +%else %if &u_ver.=0 and &ascii.=0 %then %do; + data _null_; + file "&temp_dir._&tfns._version.do"; + put " capture program drop stata_v"; + put " program define stata_v, nclass"; + put " capture log close "; + put " quietly log using ""&temp_dir._&tfns._ver.log"" "; + %** macro var version can have decimal places **; + put ' display "%let version=" _caller() " ; " '; + put ' display "%let SE=$S_StataSE ;" '; + put ' display "%let MP=$S_StataMP ;" '; + put " quietly capture log close " ; + put " end "; + put " stata_v"; + run; + + %let uspace=0; %** flag if in non-Windows and directory name has a space in it **; + %if "&nosave."="" %then %do; %** if not run by -usesas- **; + %if &unix.=1 %then %do; + %** sysexec requires no quotes even when changing to dirs with spaces in windows or unix **; + %* change to the drive and directory where the Stata do-files are. **; + %sysexec cd %nrbquote(&work_dir.) ; + + %** Run Stata in batch from within the directory where the temp files are. **; + %sysexec %nrbquote(&ustata.) -b do "_&tfns._version.do"; + %if &sysrc.^=0 %then %goto fail21; + %end; %** if unix=1 do loop **; + + %if &unix.=0 %then %do; + %sysexec &drive.; + %** sysexec requires no quotes even when changing to dirs with spaces in windows or unix **; + %sysexec cd %nrbquote(&work_dir.) ; + %** Run Stata in batch. **; + %sysexec "&wstata." /e do "&temp_dir._&tfns._version.do"; + %end; %** if unix=0 then do loop **; + + %if %sysfunc(fileexist("_&tfns._ver.log")) %then %do; + %include "_&tfns._ver.log"; + %end; + %else %goto fail22; + + %let u_ver=%sysevalf(&version.*10,integer); + + %** stata 6 cannot handle $S_StataSE or $S_StataMP *; + %if &SE.=E %then %let SE=; + %if &MP.=P %then %let MP=; + + %** no difference between MP and SE to savastata **; + %if &SE.=SE or &MP.=MP %then %let u_SEver=1; + + %end; %** end of "&nosave." ^= "" (not being run by -usesas-) **; +%end; %** if script=usesas, else if &u_ver.=0 and &ascii.=0 then do loop **; + +%** u_ver is multiplied by 10 to make sure no decimal exists **; +%if 100 <= &u_ver. and &u_ver. < 120 %then %do; + %**if using Stata 10 or 11, no reason to save to current version so saveold **; + %let old=old; +%end; + +%if &old.=old %then %do; + %if 90<=&u_ver. and &u_ver.<100 %then %do; + %let s_ver=70; %** Stata 9 -saveold- saves to version 7 IC only **; + %let s_SEver=0; %** Stata 9 -saveold- saves to version 7 IC only **; + %let intrcool=intercooled; %** setting intrcool to intercooled makes this work **; + %* as s_SEver gets set to u_SEver later **; + %end; + %else %let s_ver=%eval(&u_ver. - 10); %** otherwise subtract 1 (by subtracting 10) **; + %if &u_ver.>=100 and &u_ver.<110 %then %let s_ver=91; %** Stata 10 saves like Stata 9.1 not 9.0 **; +%end; +%else %let s_ver=&u_ver.; + +%if &s_SEver.=0 %then %let s_SEver=&u_SEver.; +%if &s_SEver.=1 and &intrcool.=intercooled %then %let s_SEver=0; + +%if &s_ver. > &u_ver. %then %goto fail2; +%if not (&u_SEver.=0 or &u_SEver.=1) %then %goto fail2; +%if not (&s_SEver.=0 or &s_SEver.=1) %then %goto fail2; +%** cannot use Intercooled and save to SE **; +%if (&u_SEver.=0 and &s_SEver.=1) %then %goto fail2; + + +%** Have to be using Stata SE to specify that you are saving a Stata Intercooled dataset. **; +%if &u_SEver.=0 %then %let intrcool= ; + + +%* char2lab can only be run by savas or -usesas- **; +%if &char2lab.=1 %then %do; + %** s_ver is multiplied by 10 to make sure no decimal exists **; + %if &s_ver. < 90 %then %do; + %** Stata 9 started allowing value labels to be up to 32,000 charactes long.**; + %** Stata 8 will ignore such value labels if dataset is read into Stata 8 **; + %put %upcase(warning): The option char2lab is not beneficial prior to Stata 9. *; + %let char2lab=0; + %end; + %if ("&script." = "" ) %then %do; + %** The option char2lab is not allowed when SAVASTATA is not run by the savas script **; + %* or the Stata command -usesas-. **; + %put %upcase(warning): The option char2lab is not allowed. *; + %if &s_ver. >= 90 %then %do; + %put Consider running the SAS macro CHAR2FMT before running SAVASTATA. *; + %put For more help check here: &char2fmthttp. ; + %end; + %let char2lab=0; + %end; + %if &char2lab.=0 %then %do; + %put %upcase(warning): char2lab option will be ignored. * ; + %end; +%end; + + +%* set max limits for Stata dataset **; +%* For SE or Intercooled the max number of obs is: 2,147,483,647 **; +%let maxobs=2147483647; +%* set max string variable length and max value label length **; +%if &s_ver.<70 %then %do; %** Stata 7 was first version with SE **; + %let maxstrvarlen=80; + %let maxvallablen=80; +%end; +%else %if &s_SEver.=0 and &s_ver.<=90 %then %do; %** intercooled versions 7, 8 and 9.0 **; + %let maxstrvarlen=80; + %let maxvallablen=80; +%end; +%else %if &s_SEver.=1 and &s_ver.<=90 %then %do; %** Stata 7 SE, 8 SE, and 9.0 SE **; + %let maxstrvarlen=244; + %let maxvallablen=244; +%end; +%else %if &s_ver.>=91 %then %do; %** 9.1+ SE and Intercooled are the same **; + %let maxstrvarlen=244; + %let maxvallablen=32000; +%end; + + +%let dta_exists=0; +%if "&script." ^= "usesas" %then %do; + %if %sysfunc(fileexist("&out_dir.&fdset..dta")) %then %do; + %let dta_exists=1; + %if &replace.^=replace and &ascii.=0 %then %do; + %goto fail7; + %end; + %end; +%end; + + +%** check for long character variables only if using Stata 9 or higher **; +%if &u_ver. >= 90 %then %do; + proc contents data=&dset. out=_conten noprint; + run; + + proc sort data=_conten; + by type; + run; + + %let max_clen_count=0; + data _null_; + set _conten (where=(type=2)) end=lastobs ; + retain max_clen_count 0; + by type; + if length > &maxstrvarlen. then do; + max_clen_count = max_clen_count + 1; + %if &char2lab. = 1 %then %do; + if max_clen_count=1 then do; + %** if a var has a length longer than needed then it may be needlessly converted **; + %* if the trailing blanks were removed first...which savastata does after char2fmt **; + %* is run. not worth moving length optimization to be before here as it has to **; + %* be done after char2fmt as well **; + put " This is a list of character variables that are going to be made into *"; + put " numeric variables but have value labels containing their character contents *"; + put " because they contain more than &maxstrvarlen. characters. *"; + end; + put " " name " *"; + %end; + end; + if last.type and type=2 then do; + call symput( 'max_clen_count', compress(left( put( max_clen_count, 10. ) ) ) ) ; + end; + run; + + %** only do char2fmt if user asked for it and have long character vars that need **; + %* to be made into labels **; + %* char2fmt creates and deletes temporary dataset _conten2 **; + %if (&char2lab.=1) and (&max_clen_count. > 0 ) %then %do; + %char2fmt(dset=&dset. , maxlen=&maxstrvarlen. , temp_dir=%nrbquote(&temp_dir.) , tfns=&tfns. ); + %let workfmts=%sysfunc(cexist(WORK.FORMATS)); + %if &workfmts.=1 %then %let vlabels=1; + %end; + %** end begin char2lab process **; +%end; %** of if s_ver>=90 **; + + %** run proc means to check data after potential change in data by char2fmt **; +%if &check.=1 %then %do; + proc printto print="&out_dir.&fdset._SAScheck.lst" new ; run; + proc means data=&dset.; + proc contents data=&dset. position; + proc print data=&dset. (obs=5); + run; + proc printto; %** ends printing to means.lst and returns printing to normal **; + run; +%end; + +%** Here starts the processing of the dataset. **; +%** Create a dataset of the dataset info of the input dataset. **; +proc contents data=&dset. out=_conten noprint; +run; + +%** Initialize macro vars **; +%let nv=0; +%let cv=0; +%let ch=0; +%let ln=0; +%let ob=0; +%let lo=0; +%let dq=0; +%let dq1=0; +%let dy=0; +%let dyc=0; %** initialize to 0 for now **; +%let bign=0; +%let bign1=0; +%let name=0; +%** Check for vars with names that are used in savastata like: _N and _______N. **; +data _null_; + set _conten(keep=name ) end=lastobs; + retain bign bign1 0; + name=lowcase(name); + if name="_n" then bign=1; + if name="_______N" then bign1=1; + if name="___nv___" then call symput("nv","1"); + if name="___cv___" then call symput("cv","1"); + if name="___ch___" then call symput("ch","1"); + if name="___ln___" then call symput("ln","1"); + if name="___ob___" then call symput("ob","1"); + if name="___lo___" then call symput("lo","1"); + if name="___dq___" then call symput("dq","1"); + if name="___dq1__" then call symput("dq1","1"); + if name="___dy___" then call symput("dy","1"); + if name="___dyc__" then call symput("dyc","1"); + if name="_name_" then call symput("name","1"); + + if lastobs then do; + call symput("bign",bign); + call symput("bign1",bign1); + end; +run; + +/** DR's little fix **/ +%let crdate=SAVASTATA created this dataset on %sysfunc(date(),date9.); + +%** An attempt to rename _N to _______N will fail + %* because both vars exist in the dataset. **; +%if &bign.=1 and &bign1.=1 %then %goto fail8; + + %let bvar=________; + %if &nv.=1 %then %do; %let bvar=___nv___; %goto fail9; %end; + %if &cv.=1 %then %do; %let bvar=___cv___; %goto fail9; %end; + %if &ch.=1 %then %do; %let bvar=___ch___; %goto fail9; %end; + %if &ln.=1 %then %do; %let bvar=___ln___; %goto fail9; %end; + %if &ob.=1 %then %do; %let bvar=___ob___; %goto fail9; %end; + %if &lo.=1 %then %do; %let bvar=___lo___; %goto fail9; %end; + %if &dq.=1 %then %do; %let bvar=___dq___; %goto fail9; %end; + %if &dq1.=1 %then %do; %let bvar=___dq1__; %goto fail9; %end; + %if &dy.=1 %then %do; %let bvar=___dy___; %goto fail9; %end; + %if &dyc.=1 %then %do; %let bvar=___dyc__; %goto fail9; %end; + %if &name.=1 %then %do; %let bvar=_name_; %goto fail9; %end; + + + +%* invalid Stata vars *; +%let bstatavs='_ALL','_B','BYTE','_COEF','_CONS','DOUBLE','FLOAT','IF','IN','INT','LONG','_N','_PI','_PRED','_RC','_SE','_SKIP','_UNIFORM','USING','WITH'; + +%let cq=0; +data _conten; + length __strvar 8 label $200 llabvars $32000; + set _conten end=lastobs; + %** count how many variable labels need to be truncated **; + %* and create a list of variables that need variable labels saved as notes **; + retain llabcnt 0 llabvars ""; + name=upcase(name); %** make sure all variable names are upper case **; + if (substr(name,1,3)='STR') then do; %** Look for variables named like "str14" which is **; + %* an invalid variable name in Stata if it was in **; + %* lower case. Leave them in upper case. **; + __strvar=substr(name,4,length(name)); + _error_=0; %** SAS creates _error_=15 if _strvar evaluates to ., so clear it. **; + if (__strvar in(.,0)) then name=lowcase(name); + else call symput("bstatavs","&bstatavs.,'"||trim(name)||"'"); %** add str var to list **; + end; + %** Check for variable names that are invalid variable names in Stata if they were in **; + %* lower case and leave them in upper case. **; + else if name ~in(&bstatavs.) then name=lowcase(name); + + %if &bign.=1 and &bign1.=0 %then %do; + if (name='_N') then do; + put "%upcase(warning): SAVASTATA has renamed Stata invalid variable _N to _______N * "; + name='_______N'; + call symput("bstatavs","&bstatavs.,'"||trim(name)||"'"); %** add _______N var to list **; + end; + %end; + if label^="" then do; + %** this does not need to be version controlled as Stata has only ever allowed 80 characters *; + %* for variable labels: *; + llabel = label; ** store long labels in notes in Stata **; + if length(label)>80 then do; + llabcnt=llabcnt+1; + label=substr(label,1,80); %** need to test length before escaping $ and \ etc. **; + if llabcnt = 1 then do; + put "%upcase(warning): This is a list of variables that have had their label truncated to 80 characters * "; + put " and had their original label stored as a note in Stata. * "; + llabvars = '"' || trim(lowcase(name)) || '"'; + end; + else llabvars = trim(llabvars) || ',"' || trim(name) || '"'; + put @10 name " * "; + end; + + %** prepare label to be written to _labels.do **; + %if &u_ver. < 90 or "&script." = "usesas" %then %do; + %** replace two back slashes with four, tranwrd is like subinstr **; + if index(label,"\\") then label = tranwrd(label,"\\","\\\\"); + %* if index(llabel,"\\") then llabel = tranwrd(llabel,"\\","\\\\"); %** this does not matter to Stata, all will reduced to one **; + %end; + + + %** replace all left quotes with right quotes since they mess things up **; + if index(label,"`") then label = tranwrd(label,"`","'"); + if index(llabel,"`") then llabel = tranwrd(llabel,"`","'"); + %** the above can create a right compound quote **; + + %** escape all dollar signs **; + if index(llabel,"$") then llabel = tranwrd(llabel,"$","\$"); + %** if variable label contains a compound quote. **; + if index(label,"`"||'"') or index(label,'"'||"'") then do; + call symput("cq","1"); + %if "es.=1 %then %do; + label = tranwrd(label,"`"||'"',"''"); %* replace left compound quote with two single quotes *; + label = tranwrd(label,'"'||"'","''"); %* replace right compound quote with two single quotes *; + %end; + end; + %** if variable llabel contains a compound quote. **; + if index(llabel,"`"||'"') or index(llabel,'"'||"'") then do; + call symput("cq","1"); + %if "es.=1 %then %do; + llabel = tranwrd(llabel,"`"||'"',"''"); %* replace left compound quote with two single quotes *; + llabel = tranwrd(llabel,'"'||"'","''"); %* replace right compound quote with two single quotes *; + %end; + end; + end; %** if var has a label **; + if lastobs then call symput("llabvars",trim(llabvars)); + + + length w d $5; + w=formatl; + d=formatd; + format=upcase(format); + orig_fmt=format; + if (format='' & formatl>0) then format = compress('%'||w||'.'||d||'f',' '); + else if (format='F') then format = compress('%'||w||'.'||d||'f',' '); + else if (format='BEST') then format = compress('%'||formatl||'.0g'); + else if (format='DATE' & formatl<9) then format = '%d'; + else if (format='DATE' & formatl>=9) then format = '%dDlCY'; + else if (format='DDMMYY' & formatl<10) then format = '%dD/N/Y'; + else if (format='DDMMYY' & formatl>=10) then format = '%dD/N/CY'; + else if (format='MMDDYY' & formatl<10) then format = '%dN/D/Y'; + else if (format='MMDDYY' & formatl>=10) then format = '%dN/D/CY'; + else if (format='YYMMDD' & formatl<8) then format = '%dYND'; + else if (format='YYMMDD' & 8<=formatl<10) then format = '%dY-N-D'; + else if (format='YYMMDD' & formatl>=10) then format = '%dCY-N-D'; + else if (format='DAY') then format = '%dD'; + else if (format='MONTH') then format = '%dl'; + else if (format='YEAR' & formatl<4) then format = '%dY'; + else if (format='YEAR' & formatl>=4) then format = '%dCY'; + else if (format='MONNAME') then format = '%dM'; + else if (format='MONYY' & formatl<7) then format = '%dlY'; + else if (format='MONYY' & formatl>=7) then format = '%dlCY'; + else if (format='WEEKDAY') then format = '%dd'; + else if (format='WORDDATE') then format = '%d'; + else if (format='WORDDATX') then format = '%d'; + else if (format='YYMM') then format = '%d'; + else if (format='YYMON' & formatl<7) then format = '%dYl'; + else if (format='YYMON' & formatl>=7) then format = '%dCYl'; + else format='default'; + + if type=2 then format='default'; %** make all string vars be default format **; +run; + +%if &cq.=1 and "es.=0 %then %goto fail10; %** Variable label contains a compound quote **; + + + %** initialize macro vars **; +%let VAR_N = 0 ; %* number of numeric variables *; +%let VAR_C = 0 ; %* number of character variables *; +%let longname=0; + +%** check for varnames longer than 8 characters and rename them **; +%if &isysver.<7 %then %goto skip6; +%if &s_ver.< 70 %then %do; + data _conten; + length longname $32; + set _conten; + longname = name; + if (length(name)>8) then do; + s_name=right(substr(name,1,4)); %** renaming vars after proc means (check) done! oh, well*; + call symput("longname","1"); + end; + run; + + + %if &longname.=1 %then %do; %** only do if there is at least one varname > 8 **; + %** Check that variables have not been renamed to names that already exist in the dataset. **; + proc sort data=_conten; + by s_name name; + run; + + data _conten; + set _conten; + by s_name; + retain count start 0; + if first.s_name then count=0; + if (length(name)>8) then do; + start=start+1; + count=count+1; + name=compress(s_name||count); + if start=1 then do; + %** print to log **; + put " "; + put "%upcase(warning): Stata 6 does not allow variable names longer than 8 characters. * "; + put " "; + put "%upcase(warning): List of long variable names that SAVASTATA has renamed: * "; + put " "; + put " Original long name" @35 " New short name * "; + put " "; + end; + put " " longname @33 " = " @36 name " * "; + end; %** end of if (length(name)>8) do loop **; + run; + + proc sort data=_conten; by name; + run; + + %let fail11=0; %** initialize fail11 macro var **; + data _null_; + set _conten; + by name; + if not (first.name and last.name) then do; %** means there is a repeat in varnames **; + call symput("fail11","1"); + end; + + run; + %if &fail11.=1 %then %goto fail11; + + %end; %** end of if long=1 the do loop **; +%end; %** end of if &s_ver.< 70 do loop **; +%skip6: ; %** Skip fixing stuff for Stata 6 if using SAS 6 **; + +proc sort data=_conten; by type; +run; + +%let var_n=0; +%let var_c=0; +%let avars=0; +%** Count up number of numeric and number of character variables. **; +data _null_ ; + set _conten end=lastobs; + by type; + if first.type then do; + var_non=0; + var_noc=0; + end; + if type=1 then do; %* numeric vars **; + var_non + 1 ; + end; + if type=2 then do; %* character vars **; + var_noc + 1 ; + end; + + %** Create macro vars containing final number of vars. **; + if last.type and type=1 then call symput( 'VAR_N', left( put( var_non , 5. ) ) ) ; + if last.type and type=2 then do; + call symput( 'VAR_C', left( put( var_noc, 5. ) ) ) ; + end; + + %** AVARS is total number of variables **; + if lastobs then call symput( 'AVARS', compress(left( put( _n_, 5. ) ) ) ) ; + +run ; + + %if &AVARS.=0 %then %do ; + %goto fail12 ; + %end ; + + + %*** Figure out minimum safe storage type for each variable. ***; + %if &s_ver. < 80 %then %do; + %let bytemin = -127; + %let bytemax = 126; + %let intmin = -32767; + %let intmax = 32766; + %let longmin = -2147483647; + %let longmax = 2147483646; + %end; %** of if s_ver < 80 then do loop **; + %else %do; %** Starting with Stata 8 there is a smaller range due to storage of special missings **; + %let bytemin = -127; + %let bytemax = 100; + %let intmin = -32767; + %let intmax = 32740; + %let longmin = -2147483647; + %let longmax = 2147483620; + %end; %** of if s_ver < 80 then do loop **; + + + %** Initialize macro vars **; + %let nobs=0; + %let dq_fail=0; + %let dy_and_dq_fail=0; + %let dq_fix=; + %let dyc=%sysfunc(byte(162)); %** this makes cents **; + %let sm=0; + + data _conten1; + set work.&dset. end=___lo___; + format _all_; %** remove all formats and informats **; + informat _all_; + + %** Count up observations since using _n_ to step through arrays. **; + array ___ob___[1] _temporary_ (1*0); + + ___ob___[1]=___ob___[1]+1; + + + %if &VAR_N.>0 %then %do; %** process numeric vars *; + array ___nv___ [&VAR_N.] _numeric_; %** all numeric variables in dataset **; + array ___ln___ [&VAR_N.] _temporary_ (&VAR_N.*3); + + %** use the temporary variable _n_ to step through the arrays so as **; + %* not to create another var (i). _n_ resets itself at next obs. **; + do _n_ = 1 to &VAR_N.; + %** check to see if any numeric var has special missing values **; + if .a<=___nv___[_n_]<=.z then call symput("sm","1"); + + if ___ln___[_n_] ne 8 and ___nv___[_n_] ne . then do ; + if ___nv___[_n_] ne int(___nv___[_n_]) then ___ln___(_n_)=8; %** all decimal vars length 8 *; + else %* check numeric variables that are integers *; + if &BYTEMIN.<=___nv___[_n_]<=&BYTEMAX. then ___ln___(_n_)= max( ___ln___(_n_), 3 ) ; + else + if &INTMIN.<=___nv___[_n_]<=&INTMAX. then ___ln___(_n_)= max( ___ln___(_n_), 4 ) ; + else + if &LONGMIN.<=___nv___[_n_]<=&LONGMAX. then ___ln___(_n_)= max( ___ln___(_n_), 6 ) ; + else + ___ln___(_n_)=8; + end ; + end ; %*** end of _n_=1 to &VAR_N. ***; + %end; %** end of processing numeric vars **; + + + + %if &VAR_C.>0 %then %do; %* now process the character variables *; + array ___cv___( &VAR_C. ) _character_ ; %** all character variables in dataset **; + %** temp array vars are retained variables **; + array ___ch___( &VAR_C. ) _temporary_ (&VAR_C.*1); %** var length **; + array ___dq___( &VAR_C. ) _temporary_ (&VAR_C.*0); %** var has dq **; + array ___dy___( &VAR_C. ) _temporary_ (&VAR_C.*0); %** var has dyc **; + array ___dq1__( 1 ) _temporary_ (1*0); %** any var has dq **; + array ___dyc__(1) $32766 _temporary_ ; %** all vars that have dqs and dycs **; + + do _n_ = 1 to &VAR_C. ; + %** check for double quotes in character variables **; + if ___dq___[_n_]=0 then do; %** once a var is known to have a double quote **; + %* stop checking it for a double quote **; + if index(___cv___[_n_],compress(' " ')) then do; + ___dq___[_n_]=1; + %** temp array vars are retained variables **; + ___dq1__[1]=1; + end; + end; + %** also check for &dyc. char in character variables **; + if ___dy___[_n_]=0 then do; %** once a var is known to have a dyc **; + %* stop checking it for a dyc **; + if index(___cv___[_n_],"&dyc.") then ___dy___[_n_]=1; + %** temp array vars are retained variables **; + end; + + %* increase character length until the maximum needed *; + if ___ch___[_n_] < length(___cv___[_n_]) then ___ch___[_n_]=length(___cv___[_n_]); + end; %** of do _n_ = 1 to &VAR_C. **; + %end; %* end of processing character vars *; + + if ___lo___ then do ; + call symput("nobs",compress(___ob___[1])); + %if &VAR_N.>0 %then %do; + do _n_ = 1 to &VAR_N. ; + ___nv___[_n_]=___ln___[_n_]; %** replace values of variables with their length **; + end; + %end; + + %if &VAR_C.>0 %then %do; + %if &u_ver.>=70 %then %do; %** since long varnames could be renamed for Stata 6 **; + %* and -foreach- does not work in 6, do not do this. *; + do _n_ = 1 to &VAR_C.; + if ___dy___[_n_]=0 and ___dq___[_n_]=1 then do; + %** create a list of char vars that need fixing **; + %* do same upcasing/lowcasing as before **; + if upcase(trim(vname(___cv___[_n_]))) in(&bstatavs.) then + ___dyc__[1]= trim(upcase(vname(___cv___[_n_])))||trim(" ")||trim(___dyc__[1]); + else + ___dyc__[1]= trim(lowcase(vname(___cv___[_n_])))||trim(" ")||trim(___dyc__[1]); + if upcase(trim(vname(___cv___[_n_]))) = "_N" then + ___dyc__[1]= trim("_______N")||trim(" ")||trim(___dyc__[1]); + end; %** of if var had dq but not dyc **; + if ___dy___[_n_]=1 and ___dq___[_n_]=1 then call symput("dy_and_dq_fail","1"); + end; %** of do _n_ to var_c **; + %end; %** if u_ver>=70 loop **; + %else %do; + %** if previous to version 7 then force replacing **; + %* double quotes with single quotes **; + if ___dq1__[1]=1 then call symput("dy_and_dq_fail","1"); + %end; + %** create a macro var that has char vars that have double quotes **; + %* and can be fixed. **; + if ___dq1__[1]=1 then call symput("dq_fix",trim(___dyc__[1])); + if ___dq1__[1]=1 then call symput("dq_fail","1"); + + do _n_ = 1 to &VAR_C.; + %** this converts the character data to numeric data *; + ___cv___[_n_]=___ch___[_n_]; %** replace values of variables with their length **; + end; + %end; %* of if &VAR_C.>0 then do **; + output; + end; + run; + + %if %sysfunc(fileexist(&usagelog.)) %then %do; + data _null_; + file &usagelog. mod; + put " Input SAS dataset has &nobs. obs and &AVARS. vars" ; + %end; + +%if &nobs.=0 %then %goto fail13; +%if &nobs.>&maxobs. %then %goto fail25; + +%if &u_ver.>=70 %then %do; %** since varnames could be renamed for Stata 6 **; + %* then do not do this. *; + %if &dy_and_dq_fail.=1 and "es.=0 %then %goto fail14; +%end; +%else %do; + %if &dq_fail.=1 and "es.=0 %then %goto fail14; +%end; + +%** Stata 7 and earlier cannot save special missing values **; +%if &sm.=1 and &s_ver. < 80 %then %do; + %put %upcase(warning): The dataset WORK.&dset. contains special missing data that will be converted to missing (.) * ; +%end; + +%** Since _conten1 is one obs in the dataset transpose to create variable _name_. **; +proc transpose data =_conten1 out=_conten1; + var _all_; +run; + + +%** Put _conten dataset in the variable order of the original dataset. **; +proc sort data=_conten; + by varnum; +run; + +%** Figure out the minimum required length for accurate storage of the col1 variable. **; +data _conten1; + set _conten1; + varnum=_n_; %** make the variable order be the order they are in dataset **; +run; + +data _conten; + merge _conten(keep=name varnum type label llabel orig_fmt format) + _conten1(keep=_name_ varnum col1); + by varnum; +run; + + +data _conten; + length c_len $10 stype $10 oformat $10; + set _conten; + retain lcvarcnt 0; %** count how many variables need to be truncated **; + c_len=compress(col1); + n_len=input(c_len,8.); + + %** name has been fixed if too long or left upper case **; + %* and _name_ is untouched **; + + if type=1 /*** and format="default" ***/ then do; %** numeric variables **; + if c_len="3" then do; stype="byte"; oformat="best4."; end; + else if c_len="4" then do; stype="int"; oformat="best6."; end; + else if c_len="6" then do; stype="long"; oformat="best11."; end; + else if c_len="8" and &float.=1 then do; stype="float"; oformat="best18."; end; + else if c_len="8" and &float.=0 then do; stype="double"; oformat="best18."; end; + end; + /****************** + if type=1 and format^="default" then do; %** numeric variables with formats **; + stype="double"; oformat="best17."; + end; + ******************/ + + + if type=2 then do; %** character variables **; + if n_len>&maxstrvarlen. then do; + c_len="&maxstrvarlen."; + if &char2lab. = 0 then do; + lcvarcnt = lcvarcnt + 1; + if lcvarcnt = 1 then do; + put "%upcase(warning): This is a list of variables that have been truncated to &maxstrvarlen. characters. * "; + if (&s_ver. >= 90) then do; + if ("&script." = "") then do; + put "Consider using the SAS macro CHAR2FMT to convert them to numeric variables with *"; + put " SAS formats containing their character data. SAVASTATA saves formats as value labels in Stata. *"; + end; + else do; + put "Consider using the char2lab option to encode them to numeric with value labels in Stata. *"; + end; + end; %* end of if saving to Stata version 9 or higher **; + end; + put @10 name ' * '; + end; + end; + period='.'; + oformat=compress("$char"||c_len); + oformat=compress(oformat||period); + stype=compress("str"||c_len); + stype=left(stype); + end; %** end of if type=2 do loop **; +run; + + + %** Figure out the record length. **; +data _null_; + set _conten end=lastobs; + retain bpos lepos 0; + if type=1 then do; + if stype="byte" then len=1; + if stype="int" then len=2; + if stype="long" then len=4; + if stype="float" then len=4; + if stype="double" then len=8; + end; + if type=2 then len=input(c_len,8.); + + bpos=lepos+1; + lepos=bpos+len-1; + + if lastobs then do; + call symput("reclen",compress(lepos)); + end; +run; + + +%if &s_ver.>=80 %then %do; +proc format; + value ___mi___ + .a=".a" + .b=".b" + .c=".c" + .d=".d" + .e=".e" + .f=".f" + .g=".g" + .h=".h" + .i=".i" + .j=".j" + .k=".k" + .l=".l" + .m=".m" + .n=".n" + .o=".o" + .p=".p" + .q=".q" + .r=".r" + .s=".s" + .t=".t" + .u=".u" + .v=".v" + .w=".w" + .x=".x" + .y=".y" + .z=".z" + ;;; +run; +%end; %** end of if &s_ver.>=80 do loop **; + + +%** Write a SAS program to output the data to an ascii file. **; +data _null_; + set _conten end=lastobs; + %** Write to a SAS program to be inserted in this program later. **; + file "&temp_dir._&tfns._ascii.sas"; + retain lvar ivar 0; + if _n_=1 then do; + %*** this fileref is used after success to delete this raw file **; + put "filename ________ ""&temp_dir._&tfns._.raw""; "; %** write out to an ascii file **; + put "data _null_; "; + put " set work.&dset. end=___lo___; "; + put " file ________ ls=2000; "; %** write out to an ascii file **; + end; + lvar=lvar+1; + ivar=ivar+1; + + %* only here if NOT (&dy_and_dq_fail.=1 and "es.=0) **; + %if &dq_fail.=1 %then %do; + %** check for double quotes in only the character variables that need fixing **; + %** tranwrd makes the list of space separated char vars like: in("cvar1","cvar2")**; + if type=2 and _name_ in(%sysfunc(tranwrd("&dq_fix.",%nrstr( ),","))) + then put " if index(" _name_ ",compress(' "" ')) then "; + %if &dy_and_dq_fail.=0 and &u_ver.>=70 %then %do; + %** Make Maria happy. **; + %** and replace with &dyc. character which is a very unlikely character **; + if type=2 then put _name_ "=translate(" _name_ ",compress("" &dyc. ""),compress(' "" '));" ; + %end; + %else %if "es.=1 %then %do; + %** and replace with single quotes **; + if type=2 then put _name_ "=translate(" _name_ ",compress("" ' ""),compress(' "" '));" ; + %end; + %end; %** if dq_fail=1 then do loop **; + + %if &s_ver.<80 %then %do; %** make all special missings equal to missing since pre-Stata 8 cannot handle them **; + if type=1 then put " if .< " _name_ "<=.z then " _name_ "=. ; "; + %end; %** if s_ver<80 or sm=0 then do loop **; + + %if &s_ver.>=80 and &sm.=1 %then %do; %** make invalid special missings equal to missing **; + %** Stata can only handle special missing between .a and .z, **; + %* SAS also has " ._ " ***; + if type=1 then put " if " _name_ "<.a then " _name_ "=. ; "; + %end; %** if s_ver>=80 and sm=1 then do loop **; + + if (lvar < 5 and ivar < &avars.) then do; + %** put the variable with the output format and put a space after each variable **; + %if &s_ver.>=80 and &sm.=1 %then %do; %** keep special missings special **; + if type=1 then put ' if .a<= ' _name_ '<=.z then put ' _name_ ' ___mi___. " " @;'; + %end; + if type=1 then put ' if ' _name_ '<.a or ' _name_ '>.z then put ' _name_ oformat ' " " @;'; + /** would work if Stata could infile compound quotes: + if type=2 then put ' put " `""" ' _name_ oformat ' """'' " " " @ ; '; + ******/ + if type=2 then put ' put " """ ' _name_ oformat ' """ " " " @ ; '; + end; %** of if (lvar < 5 and ivar < avars.) then do loop **; + else do; + %if &s_ver.>=80 and &sm.=1 %then %do; %** keep special missings special **; + if type=1 then put ' if .a<= ' _name_ '<=.z then put ' _name_ ' ___mi___. ;'; + %end; + if type=1 then put ' if ' _name_ '<.a or ' _name_ '>.z then put ' _name_ oformat ' ;'; + /** would work if Stata could infile compound quotes: + if type=2 then put ' put " `""" ' _name_ oformat ' """'' " ; '; + **/ + if type=2 then put ' put " """ ' _name_ oformat ' """ " ; '; + lvar=0; + end; %** of if else (the 5th var) do loop **; + put " "; + if lastobs then do; + put "run; "; + end; +run; + +%include "&temp_dir._&tfns._ascii.sas"; +filename ________ clear; %** clear filename ref used in _tfns_ascii.sas **; + +%** initialize maxvar **; +%let maxvar =0; +%let reclen=%eval(&reclen.); +%if (&s_ver.<80 or &s_SEver.=0) %then %do; + %if &avars.>2047 %then %goto fail15; %** &avars. is number of all variables **; + %else %if (&s_ver.<70) and &reclen.>8192 %then %goto fail16; + %else %if (&s_SEver.=0 or &s_ver.<80) and &reclen.>24564 %then %goto fail16; + %end; +%else %do; %** saving SE **; + %** The maximum width of a dataset in Stata SE is 12*maxvar. **; + %** The maximum number of variables for Stata SE is 32,767. **; + %** The maximum number of variables savastata can handle varies based on type of variables **; + %if &avars. > 32767 %then %goto fail24; %** Starting with SAS 9, SAS now allows more than 32,767 vars **; + %let maxreclen = %eval(&avars. * 12 ); + %** The real max width for Stata is 393204 (=32767 * 12) not 393192 (= 32766 * 12) **; + %if &maxreclen. > 393204 %then %goto fail16; + %if &reclen. > 393204 %then %goto fail16; + %if &avars. < 32756 %then %do; + %** allow for more vars (10 percent of the difference of total amount of vars you can have) **; + %let maxvar = %eval(&avars. + %sysfunc(int((32766-&avars.) / 10))); + %end; + %else %if &avars. >= 32756 %then %do; + %let maxvar = %eval(&avars. + 1); + %end; + %if &avars.>32767 %then %goto fail24; %** This should not happen, but check it again **; + %if &maxvar.<=5000 %then %let maxvar=5000; + %if &maxvar.>32767 %then %goto fail16; %** This really means the dataset is too wide. **; +%end; + + +%let flavor= ; %** Initialize macro var **; + + +%* intrcool now only used for the Stata intercooled saving option which stopped being an option with Stata 10 **; +%if &u_ver.>=100 %then %let intrcool= ; %** make sure it is blank if Stata 10 or higher **; + + +%** Write do-file to read in data. **; +data _null_; + set _conten end=lastobs; + %** Write to a Stata do-file. **; + file "&temp_dir._&tfns._infile.do" ls=2000; %* ls=256 is default *; + if _n_=1 then do; + /**************************************************************** + # Figure out memory requirements. + # Use a slightly modified version of the formula Stata suggests to figure + # out how much memory is needed. + # STATA_s formula: N*V*W + 4*N + # M = -------------- + # 1024 * 1024 + # N = number observations + # V = number of variables + # W = average width in bytes of a variable + # M = number of megabytes + # savastata_s formula: + ****************************************************************/ + %** record length is number of variables times average variable width **; + statamem= &nobs.*(&reclen. + (&reclen./4)) + (4*&nobs.) ; %** "+ (&reclen./4)" adds about 25 percent for good measure **; + %if &u_ver.>=80 %then %do; + put " if `c(memory)' < " statamem " { "; %** c(memory) is in bytes and statamem is also at this point **; + %end; + %** Convert STATAMEM bytes to megabytes **; + statamem=int(statamem / 1024**2); + %** Make sure memory is set to at least 20 megabytes **; + if (statamem< 20) then statamem=20; + mem=compress(statamem||"m"); + put " set memory " mem; + %if &u_ver.>=80 %then %do; + put " } "; %** end of if memory setting is less than needed **; + %end; + %if &maxvar.>5000 %then %do; %** but only reset if not high enough (for -usesas- or user_s default setting) **; + put " if `c(max_k_current)' < &maxvar. set maxvar &maxvar. "; + %end; + put " #delimit ; "; + put " infile "; + end; %** end of if _n_=1 do loop **; + put ' ' stype name ; + if lastobs then do; + put " using ""&temp_dir._&tfns._.raw"" "; + put ';;;'; + put ' '; + put ' #delimit cr '; + %** replace dyc char with double quote only in char vars that need fixing **; + %if &dq_fail.=1 and &dy_and_dq_fail.=0 and &u_ver.>=70 %then %do; + put "foreach svar of varlist &dq_fix. { "; + put " replace `svar' = subinstr(`svar',""&dyc."",`""""""',.) "; + put '} '; + %end; + put " do ""&temp_dir._&tfns._labels.do"""; %** This will call the next do-file. **; + put " do ""&temp_dir._&tfns._fix.do"""; %** This will call the next do-file. **; + put " do ""&temp_dir._&tfns._formats.do"""; %** This will call the next do-file. **; + %if &vlabels.=1 %then %do; + put " do ""&temp_dir._&tfns._dlabels.do"""; %** This will call the next do-file. **; + put " do ""&temp_dir._&tfns._vlabels.do"""; %** This will call the next do-file. **; + %end; + + put " "; + %if "&sysscp."="WIN" %then %do; + put " global S_FN ""\&fdset..dta"" "; + %end; + %else %do; + put " global S_FN ""/&fdset..dta"" "; + %end; + put " label data ""&crdate."" "; + + %******* save Stata dataset *********************************; + %*----------------------------------------------------------*; + %if "&script." ^= "usesas" %then %do; + put 'if _caller()<8 { '; + put ' quietly describe '; + put ' local obs=`r(N)'' '; + put ' local vars=`r(k)'' '; + put " } "; + put " else { "; + put ' local obs=`c(N)'' '; + put ' local vars=`c(k)'' '; + put " } "; + + put " if `obs' == &nobs. & `vars' == &AVARS. { "; %** only save if successful **; + %** not saving will still allow checking data **; + %** add another back slash to directories that start with a back slash, as Stata **; + %* drops the first back slash because it sees it as an escape character. **; + %if %index(%nrbquote(&out_dir.),\)=1 %then %do; + if &u_ver.<80 then put " save ""\&out_dir.&fdset..dta"", &old. &intrcool. &replace. "; + else if &u_ver.>=80 then put " save&old. ""\&out_dir.&fdset..dta"", &intrcool. &replace. "; + %end; + %else %do; + if &u_ver.<80 then put " save ""&out_dir.&fdset..dta"", &old. &intrcool. &replace. "; + else if &u_ver.>=80 then put " save&old. ""&out_dir.&fdset..dta"", &intrcool. &replace. "; + %end; + put " } " ; %** end of if obs and vars match SAS dataset **; + %if &ascii.=0 and &u_ver.>=70 %then %do; + put " set linesize 100 "; %** -usesas- should not reset linesize **; + %end; + %end; %** of script ^= "usesas" do loop **; + %*** end save Stata dataset *********************************; + %*----------------------------------------------------------*; + + %if "&script." = "usesas" %then %do; + put "capture program drop savastata_report "; + put "program savastata_report "; + put " if `c(N)' != &nobs | `c(k)' != &AVARS. { "; + put " noisily { "; + put " di _n ""{txt}SAS reports that the input dataset has {res}&nobs. {txt}observations "" /* "; + put " */ ""and {res}&AVARS. {txt}variables "" "; + put ' di "{txt}but Stata reports that the dataset has {res}`c(N)'' {txt}observations " /* '; + put ' */ "and {res}`c(k)'' {txt}variables " '; + put ' di as err "{help usesas:usesas} was unable to read in your SAS data correctly." '; + put ' di as err "Does your data contain non-roman characters?" '; + put ' di as err "SAVASTATA writes the data to ascii and non-roman characters mess that up." '; + put ' di as err "If you want to check out the intermediary files generated " '; + put ' di as err "by -usesas- in order to check out why -usesas- failed, " '; + put ' di as err "try -usesas- again using the {text}messy {error}option. " '; + put " } "; + put " drop _all // clear data from memory "; + put " } "; + put ' else noi di _n "{txt}Stata reports that the dataset has {res}`c(N)'' {txt}observations " /* '; + put ' */ "and {res}`c(k)'' {txt}variables. " '; + put "end"; + %end; %** of script = "usesas" do loop **; + + %if &ascii.=0 %then %do; %** -usesas- runs checks the Stata data inside the usesas.ado file **; + %if "&script." ^= "usesas" %then %do; %** -usesas- already knows if it loaded data correctly or not **; + put " capture program drop __save__ "; + put " program define __save__, nclass "; + put " args obs vars "; + put " capture log close "; + %if &check.=1 %then %do; + %** If a directory starts with a back slash, Stata likes to remove it. **; + %if %index(%nrbquote(&out_dir.),\)=1 %then %do; + put "&quietly. log using ""\&out_dir.&fdset._STATAcheck.log"", replace "; + %end; + %else %do; + put "&quietly. log using ""&out_dir.&fdset._STATAcheck.log"", replace "; + %end; + put " &noisily. display "" "" "; + put " &noisily. display as res ""** Compare these results with the results provided by SAS **"" "; + put " &noisily. display ""** in the file &out_dir.&fdset._SAScheck.lst. **"" "; + put " &noisily. display "" "" "; + put " &noisily. summarize "; + put " &noisily. describe "; + put " &noisily. list in 1/5"; + put " capture log close "; + %end; %** of if check=1 do loop **; + put " ** If this file exists then Stata successfully saved &fdset..dta ** "; + put " quietly log using ""&temp_dir._&tfns._done.log"" "; + put " ** If this file exists then Stata successfully saved &fdset..dta ** "; + put ' display "%macro _______v;" '; + put ' display " %let SE=$S_StataSE ; " '; + put ' display " %let MP=$S_StataMP ; " '; + put ' display " %if &MP.=MP %then %let SE=SE ; " '; + put ' display " %let flavor=$S_FLAVOR; " '; + put ' display " %let version=%sysfunc(int(" _caller() ")); " '; + put ' display " %if &SE.=SE and &s_SEver=0 %then %let flavor=Intercooled; " '; + put ' display " %if &SE.=SE and &s_SEver.=1 and &s_ver.>=70 %then %let flavor=SE; " '; + %********* Stata version 9 is only version that saved to 2 versions previous **; + put ' display " %if &old.=old and &version.=9 %then %let version=%eval(&version.-2);" '; + put ' display " %else %if &old.=old %then %let version=%eval(&version.-1);" '; + put ' display " options notes; " '; + put " if `obs' != &nobs. | `vars' != &AVARS. { "; %** failed possibly due to non-roman characters **; + put ' di "%put %upcase(error): SAVASTATA was unable to save your SAS data correctly. *;" '; + put ' di "%put Does your data contain non-roman characters? *;" '; + put " di ""%nrstr(%put) SAS reports that the input dataset has &nobs. observations and &AVARS. variables. *; "" "; + put ' di "%put but Stata reports that the dataset has `obs'' observations and `vars'' variables. *; " '; + put ' di "%let fail23=1;" '; + put ' } '; + put ' else { '; %** success! **; + put ' di "%put NOTE: SAVASTATA has successfully saved the *; " '; + put ' di "%put Stata &version. &flavor data file &out_dir.&fdset..dta. *; " '; + put ' di "%put Stata reports that the dataset has `obs'' observations and `vars'' variables. *; " '; + put ' } '; + put ' if _caller() >= 8 { '; %** usagelog only works in version 8+ **; + put " capture which usagelog"; + put " if _rc==0 {"; + put " usagelog , type(savas) message(Output Stata dataset has `obs' obs and `vars' vars)"; + put " }"; + put " }"; + + + %if &check.=1 %then %do; + put ' di "%put *; " '; + put ' di "%put You have requested to have SAVASTATA provide 2 check files: *; " '; + put ' di "%put ""&out_dir.&fdset._SAScheck.lst"" and *; " '; + put ' di "%put ""&out_dir.&fdset._STATAcheck.log"" *; " '; + put ' di "%put *; " '; + %end; %** if check=1 then do loop **; + put ' display " %mend _______v; " '; + put ' display " %_______v; " '; + put "quietly capture log close"; + put "end "; %** end of defining program __save__ **; + put "&noisily. __save__ `obs' `vars'"; + %end; %** of script ^= "usesas" do loop **; + %end; %** of if &ascii.=0 do loop **; + end; %** if last_obs do loop **; +run; + +%** Write the Stata label do-file ***; +data _null_; + set _conten; + %** start a new Stata do-file **; + file "&temp_dir._&tfns._labels.do"; %* this is just max 32 char varname and 32 char label name *; + if _n_=1 then do; + put " ** This do-file assigns variable labels ** "; + end; + if label^="" then put ' label var ' name ' `"' label '"'' '; + %if %length(%qcmpres(%nrbquote(&llabvars.))) > 0 %then %do; + if lowcase(name) in(&llabvars.) then + put ' notes ' name ': ' llabel ; %** enclosing in compound double quotes does not help **; + %end; +run; + + +%** Write the Stata fix do-file. ***; +data _null_; + set _conten end=lastobs; + file "&temp_dir._&tfns._fix.do"; %** start a new Stata do-file **; + if _n_=1 then do; + %** If a directory starts with a back slash, Stata likes to remove it. **; + put " ** This do-file replaces empty strings with null values. ** "; + end; + if type=2 then put ' replace ' name '="" if ltrim(' name ')=="" '; +run; + +%** SAS defined format do-file ***; +data _null_; + set _conten end=lastobs; + %** start a new Stata do-file **; + file "&temp_dir._&tfns._formats.do"; %* This is just 32 max varname and 32 max format name *; + if _n_=1 then do; + put " ** This do-file assigns variables formats. ** "; + end; + if format^="default" then put ' format ' name format; + if lastobs then do; + put ' '; + end; +run; + + +%if &vlabels.=1 %then %do; + + %** If there are user defined formats try to save as many as possible. **; + %if &workfmts.=1 and &librfmts.=1 %then %do; + %let fb=1; + %let fe=2; + %end; + %else %if &workfmts.=1 and &librfmts.=0 %then %do; + %let fb=1; + %let fe=1; + %end; + %else %if &workfmts.=0 and &librfmts.=1 %then %do; + %let fb=2; + %let fe=2; + %end; + + %do i=&fb. %to &fe.; + %if &i.=1 %then %do; + %let flibr=work; + %end; + %else %if &i.=2 %then %do; + %let flibr=library; + %end; + proc format library=&flibr. cntlout=_conten&i.(keep=type fmtname start end label); + run; + + proc sort data=_conten&i.(rename=(fmtname=format label=fmtlabel)); + by format; + %if &sm.=0 %then %do; + %** Stata can only handle formats of integers. **; + where not index(start,".") and not index(end,".") + %** Stata can not handle formats of **OTHER**. **; + and upcase(start)^='**OTHER**' + and upcase(start) not in('LOW','HIGH') + and upcase(end) not in('LOW','HIGH') + %*********************************************************; + %** formats with ranges using LOW, HIGH and OTHER **; + %** could aplly to multiple variables **; + %*********************************************************; + %** Stata can only handle formats of numeric vars. **; + and upcase(type)="N"; + run; + %end; %** if sm=0 then do loop **; + + %else %if &sm.=1 %then %do; + where upcase(type)="N"; %** Stata can only handle formats of numeric vars. **; + run; + + data _conten&i.; + set _conten&i.; + fine=0; + %** If both start and end are special missing that is okay, ranges now okay. **; + if (upcase(compress(start))>=".A" and upcase(compress(start))<=".Z") + and (upcase(compress(end))>=".A" and upcase(compress(end))<=".Z") then do; + start=lowcase(start); + end=lowcase(end); + fine=1; + end; + else %** Stata can only handle formats of integers. **; + if not index(start,".") and not index(end,".") + and upcase(start)^='**OTHER**' + and upcase(start) not in('LOW','HIGH') + and upcase(end) not in('LOW','HIGH') + %*********************************************************; + %** formats with ranges using LOW, HIGH and OTHER **; + %** could aplly to multiple variables **; + %*********************************************************; + then fine=1; + if fine=1; + run; + %end; %** if sm=1 then do loop **; + + %end; %** do i=&fb. to &fe. **; + + + %if &workfmts.=1 and &librfmts.=1 %then %do; + %** If there are both work formats and library formats, choose work over library. **; + data _conten3; + merge _conten1(in=a keep=format) + _conten2(in=b keep=format); + by format; + %** Find ones in common so that formats in library.formats can be excluded. **; + if a and b; + run; + + data _conten3; + set _conten3; + by format; + %** Reduce to just one obs per format. **; + if first.format; + run; + + data _conten2; + merge _conten3(in=a keep=format) + _conten2(in=b); + by format; + %** Exclude formats in work.library that are also in work.formats. **; + if not a; + run; + + + %** Concatenate the two sets of formats. **; + proc sort data=_conten1; + by format start; + run; + proc sort data=_conten2; + by format start; + run; + + data _conten1; + set _conten1 + _conten2; + by format start; + run; + + %end; %** if workfmts=1 and librfmts=1 then do loop **; + + + %if &workfmts.=0 and &librfmts.=1 %then %do; + data _conten1; + set _conten2; + run; + %end; + + + proc sort data=_conten(keep=type varnum format name orig_fmt + where=(format="default")) + out=_conten(drop=format rename=(orig_fmt=format)); + by orig_fmt; + run; + + data _conten3; + merge _conten(in=a keep=format) + _conten1(in=b keep=format); + by format; + %** Only keep the formats used in the dataset. **; + if a and b; + run; + + data _conten3; + set _conten3; + by format; + %** Reduce to one obs per format. **; + if first.format; + run; + + data _conten1; + merge _conten3(in=a keep=format) + _conten1(in=b); + by format; + if a and b; %** Only keep the numeric formats used in the dataset. **; + run; + + + %** Make an attempt to save some of the other formats. **; + %** first check to see if any will be truncated **; + %let labtrunc = 0; + data _null_; + set _conten1; %** _conten1 contains only numeric formats for numeric vars **; + %** Stata can only handle value labels up to &maxvallablen. characters. **; + if length(fmtlabel) > &maxvallablen. then call symput('labtrunc',"1"); + run; + + %if &labtrunc.=1 %then %do; + %put %upcase(warning): SAVASTATA truncated at least one format label because it contained more than &maxvallablen. characters. *; + %end; + + data _null_; + %** Increase length to allow for compound quotes to be attached later. **; + length fmtlabel $%eval(&maxvallablen.+500); + set _conten1 (where=(fmtlabel^="")) end=lastobs ; + %** stata cannot handle empty value labels **; + + by format; + file "&temp_dir._&tfns._dlabels.do" ls=32200; %** start a new Stata do-file **; + if _n_=1 then do; + put " ** This do-file defines value labels. ** "; + end; + %** nstart and nend have to be numeric. they are only used in ranges **; + nstart=start*1; + nend=end*1; + %** format byte is okay but not as nice as the same as the var name BYTE **; + if upcase(format) not in(&bstatavs.) then format=lowcase(format); + %** make sure fmtlabel not longer than max **; + fmtlabel=substr(fmtlabel,1,&maxvallablen.); %** need to test length before escaping $ and \ **; + %** prepare fmtlabel to be written to _dlabels.do **; + + %** value labels cannot end in a left quote even if it is escaped **; + if length(fmtlabel)=1 and + substr(fmtlabel,length(fmtlabel),length(fmtlabel)) = "`" then + fmtlabel="'"; %** replace with right quote **; + else if substr(fmtlabel,length(fmtlabel),length(fmtlabel)) = "`" then + fmtlabel=substr(fmtlabel,1,length(fmtlabel)-1)||"'"; %** replace with right quote **; + %** the above can create right compound quotes **; + + %** value labels cannot contain either a left or right compound quote **; + if index(fmtlabel,compress("`"||' " ')) or + index(fmtlabel,compress('"'||" ' ")) then do; + call symput("cq","1"); %** Format contains a compound quote. **; + %if "es.=1 %then %do; + fmtlabel = tranwrd(fmtlabel,"`"||'"',"''"); %* replace left compound quote with two single quotes *; + fmtlabel = tranwrd(fmtlabel,'"'||"'","''"); %* replace right compound quote with two single quotes *; + %end; + end; + + %if &u_ver. < 90 or "&script." = "usesas" %then %do; + %** replace two back slashes with four **; + if index(fmtlabel,"\\") then fmtlabel = tranwrd(fmtlabel,"\\","\\\\"); + %end; + + %** escape all left quotes (already know they are not left compound quotes) **; + if index(fmtlabel,"`") then fmtlabel = tranwrd(fmtlabel,"`","\`"); + %** escape all dollar signs **; + if index(fmtlabel,"$") then fmtlabel = tranwrd(fmtlabel,"$","\$"); + /** replace \\` with \\' since stata hates \\` **/ + if index(fmtlabel,"\\`") then fmtlabel = tranwrd(fmtlabel,"\\`","\\'"); + %** the above cannot create a right compound quote **; + + %** One format can be assigned to many variables. **; + %** new way of defining each value and adding if more than 1 **; + %* because long value labels can make Stata unable to find end quote. **; + %* the added bonus is that a semicolon in a label will not throw off Stata **; + %*****; + + %* add compound quotes at beginning and end of fmtlabel *; + fmtlabel = " `"""|| trim(fmtlabel) ||"""' " ; + + %** value labels are stored as datatype long. **; + if .z < nstart < &longmin. then nstart = &longmin. ; + if nend > &longmax. then do; + nend = &longmax.; + end; + + if start = end then do; + %** start and end could equal "**OTHER**" and will only be assigned to **; + %* the first "other" value. Not able to replicate OTHER in Stata. **; + if first.format then do; + j=1; %** for counting inside ranges. one format can only have 65,536 values **; + put " label define " format start fmtlabel ; + end; + else do; + j=j+1; + if j <= 65536 then + put " label define " format start fmtlabel " , add " ; + end; + end; + else if ( nstart > .z and nend > .z ) then do i=nstart to nend; + if first.format and i=nstart then do; + j=1; %** for counting inside ranges. one format can only have 65,536 values **; + put " label define " format i fmtlabel ; + end; + else do; + j=j+1; + if j <= 65536 then + put " label define " format i fmtlabel " , add " ; + end; + end; + else if (compress(start)>=".a" and compress(start)<=".z") + and (compress(end)>=".a" and compress(end)<=".z") then do; + cstart = substr(lowcase(compress(start)),2,1); + %** Stata does not allow special missing ._ **; + nstart = index("abcdefghijklmnopqrstuvwxyz",compress(cstart)); + cend = substr(lowcase(compress(end)),2,1); + nend = index("abcdefghijklmnopqrstuvwxyz",compress(cend)); + do i = nstart to nend; + _sm_ = compress("." || substr("abcdefghijklmnopqrstuvwxyz",i,1)); + if first.format and i=nstart then do; + j=1; %** for counting inside ranges. one format can only have 65,536 values **; + put " label define " format _sm_ fmtlabel ; + end; + else do; + j=j+1; + if j <= 65536 then + put " label define " format _sm_ fmtlabel " , add " ; + end; + end; + end; + run; + + %if &cq.=1 and "es.=0 %then %goto fail17; %** at least one format contains a compound quote. **; + + data _conten; + merge _conten(in=a keep=type varnum name format) + _conten3(in=b keep=format); + by format; + if a and b; %** Keep only the variables assigned to these formats. **; + run; + + data _null_; + set _conten (where=(type=1)) end=lastobs; %** can only format numeric variables **; + %** start a new Stata do-file **; + file "&temp_dir._&tfns._vlabels.do"; %** this is just a max 32 char varname and *; + %* 32 char user-defined label name *; + if _n_=1 then do; + put " ** This do-file assigns value labels. ** "; + end; + if upcase(format) not in(&bstatavs.) then format=lowcase(format); + put 'label value ' name format; + run; + +%end; %** of if vlabels=1 then do loop **; + + +%if "&script." ^= "usesas" %then %do; + %let u_sysrc=0; %** initialize macro var **; + %let w_sysrc=0; %** initialize macro var **; + %if &ascii.=0 %then %do; + %if &unix.=1 %then %do; + %** This submits the Stata do-file that reads in the ascii dataset that becomes the Stata dataset. ***; + %** sysexec requires no quotes even when changing to dirs with spaces in windows or unix **; + %sysexec cd %nrbquote(&work_dir.) ; %** change to the drive and directory where the Stata do-files are. **; + + %** Run Stata in batch. from within the directory where the temp files are. **; + %sysexec %nrbquote(&ustata.) -b do "_&tfns._infile.do"; + %let u_sysrc=&sysrc.; %** store value of sysrc until after if ascii=0 do loop **; + %end; %** if unix=1 then do loop **; + + %if &unix.=0 %then %do; + %sysexec &drive.; + %** sysexec requires no quotes even when changing to dirs with spaces in windows or unix **; + %sysexec cd %nrbquote(&work_dir.) ; + %** Run Stata in batch. **; + %sysexec "&wstata." /e do "&temp_dir._&tfns._infile.do"; + %let w_sysrc=&sysrc.; %** store value of sysrc until after if ascii=0 do loop **; + %end; %** if unix=0 then do loop **; + %end; %** if ascii=0 then do loop. Do not run Stata if only want ascii dataset **; + %if &u_sysrc.^=0 %then %goto fail21; + %if &w_sysrc.^=0 %then %do; + %if &u_ver.<80 and &w_sysrc.=17 %then %let w_sysrc=0; + %else %if &u_ver.<90 and &w_sysrc.=2180 %then %let w_sysrc=0; + %if &w_sysrc.^=0 %then %goto fail20; + %end; +%end; %** of script ^= "usesas" do loop **; + +%let fail23=0; +%if (&isysver.<7 and &ascii.=0) or (&ascii.=0 and %sysfunc(fileexist("&temp_dir._&tfns._done.log"))) %then %do; + %include"&temp_dir._&tfns._done.log"; %** Run report program written by Stata. **; + %if &fail23.=1 %then %goto fail23; + %let success=1; +%end; +%if &ascii.=1 and %sysfunc(fileexist("&out_dir._&tfns._.raw")) %then %do; + %let success=1; +%end; + +%if &success.=0 and "&nosave."="" %then %goto fail19; + + + + %********* delete intermediary files when successful *********************; + options nonotes; + %if &success.=1 and &ascii.=0 and &messy.=0 %then %do; + %** at least delete the biggest file which is the ascii data file **; + data _null_; + fname="________"; + rc =0; + if rc = 0 and fexist(fname) then + rc=fdelete(fname); + run; + %end; %** if ascii=0 do loop **; + options notes; + %********* (end of) delete intermediary files when successful **************; + +%goto okay; + + + %** The following are all the failure messages returned to the user when the macro **; + %* is unable to process the input SAS dataset. **; +%fail1: + %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %if "%sysfunc(lowcase(&dset.))"="_null_" %then %do; + %put You do not have a SAS dataset in the WORK library for * ; + %put SAVASTATA to convert to Stata. * ; + %end; + %else + %put The input dataset &dset. has to be in the WORK library. * ; + %put For more help check here: &http. * ; + %** SAS 8 will put a note at the end of the log stating what page errors **; + %* occurred but earlier versions do not. So insert bad code to generate an error. **; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=1; +%goto okay; + +%fail2: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put You have set u_ver=&u_ver., s_ver=&s_ver., u_SEver=&u_SEver. and s_SEver=&s_SEver. * ; + %put which is invalid. Perhaps edit savastata.sas to set all these vars to 0 (zero)? * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=2; +%goto okay; + +%fail3: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put The dataset cannot be named &fdset. * ; + %put SAVASTATA uses this dataset name. * ; + %put Consider renaming the dataset. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=3; +%goto okay; + +%fail4: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put You did not tell SAVASTATA what directory you want to save the Stata dataset. * ; + %put Your call to SAVASTATA should look something like this: * ; + %put %nrstr(%%)savastata(C:\mydata\,-replace) * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=4; +%goto okay; + +%fail5: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put The directory %nrbquote(&out_dir.) does not exist. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=5; +%goto okay; + +%fail6: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put You can only choose to save one type of dataset. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=6; +%goto okay; + +%fail7: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put The dataset %nrbquote(&out_dir.)&fdset..dta already exists. * ; + %put If you want to overwrite this file, then use the SAVASTATA option "-replace". * ; + %put Like: %nrstr(%%)savastata(%nrbquote(&out_dir.),-replace &options.)%nrstr(;) ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=7; +%goto okay; + +%fail8: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put Your dataset &dset. contains a variable named _N which is not a valid * ; + %put variable name in Stata. Consider renaming it to a valid Stata * ; + %put variable name or dropping the variable from the SAS dataset. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put ; + %let fail=8; +%goto okay; + +%fail9: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put The input dataset &dset. cannot contain a variable named &bvar. * ; + %put because SAVASTATA uses this name. * ; + %put Either rename the variable or drop it. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=9; +%goto okay; + +%fail10: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put At least one variable label in input dataset &dset. contains a compound quote ( %nrquote(%str(`%") or %str(%")%nrstr(%')) ). * ; + %put This is not allowed by SAVASTATA. * ; + %put Consider replacing any compound quotes with two single quotes ( %nrquote(%str(%'%')) ) using * ; + %put the "quotes" option. * ; + %if "&script." = "" %then %do; + %put Like: %nrstr(%%)savastata(%nrbquote(&out_dir.),-quotes &options.)%nrstr(;) ; + %end; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=10; +%goto okay; + + +%fail11: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put SAVASTATA tried to rename the variable names that are 9 or more characters * ; + %put to valid Stata 6 variable names (8 or less characters). SAVASTATA was * ; + %put unable to come up with unique variables names. * ; + %put Rename the long variable names to 8 characters or less and try SAVASTATA again. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=11; +%goto okay; + +%fail12: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put The input dataset &dset. has no variables. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=12; +%goto okay; + +%fail13: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put The input dataset &dset. has no observations. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=13; +%goto okay; + +%fail14: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put At least one character variable in the input dataset &dset. contains a double quote ( %nrquote(%str(%")) ). * ; + %put This is not allowed by SAVASTATA. * ; + %put Consider replacing any double quotes with a single quote ( %nrquote(%str(%')) ) by using * ; + %put the "quotes" option. * ; + %if "&script." = "" %then %do; + %put Like: %nrstr(%%)savastata(%nrbquote(&out_dir.),-quotes &options.)%nrstr(;) ; + %end; + %put The following is a list of all character variables in your dataset that * ; + %put contain double quotes: * ; + data _conten1; + set &dset. end=___lo___; + keep _character_; %** keep only character variables **; + array ___ch___ ( &VAR_C. ) _temporary_; + array ___cv___( &VAR_C. ) _character_ ; %** all character variables in dataset **; + do _n_=1 to &VAR_C.; + if index(___cv___[_n_],compress(' " ')) then + ___ch___[_n_]=1; + end; + if ___lo___; + do _n_=1 to &VAR_C.; + ___cv___[_n_]=___ch___[_n_]; + end; + run; + proc transpose data =_conten1 out=_conten1; + var _all_; + run; + data _null_; + set _conten1; + if compress(col1)="1"; + _name_=lowcase(_name_); + put " " _name_ " * "; + run; + %put *; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=14; +%goto okay; + +%fail15: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put Only Stata SE can handle more than 2,047 variables. * ; + %let avars=%sysfunc(putn(&avars.,comma32.)); + %put You have &avars. variables in dataset &dset.. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=15; +%goto okay; + +%fail16: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put The input dataset &dset. exceeds the width limit of the version of Stata you * ; + %put are using or saving to. * ; + %if &float.=0 %then %do; + %put Consider using the "float" option to save space. The "float" option saves numeric * ; + %put variables that contain decimal values as storage type float instead of the default * ; + %put of double. Storage type float is %nrquote(Stata%str(%'s)) default for numeric variables. * ; + %end; + %else %if &float.=1 %then %do; + %put Consider dropping some variables. * ; + %end; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=16; +%goto okay; + +%fail17: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put At least one of the formats for a numeric variable contains a compound quote ( %nrquote(%str(`%") or %str(%")%nrstr(%')) ). * ; + %put This is not allowed by SAVASTATA. * ; + %put Consider replacing any compound quotes with two single quotes ( %nrquote(%str(%'%')) ) using * ; + %put the "quotes" option. * ; + %if "&script." = "" %then %do; + %put Like: %nrstr(%%)savastata(%nrbquote(&out_dir.),-quotes &options.)%nrstr(;) ; + %end; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=17; +%goto okay; + +%fail18: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put The work directory cannot start with a forward slash ( \ ) because * ; + %put SAVASTATA needs to cd to it. * ; + %put Is it possible to reassign your work directory to a drive like C: or D: ? * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=18; +%goto okay; + +%fail19: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put Stata had an error when attempting to infile the data. * ; + %* tfns = &sysjobid.&sysindex. when not run by -usesas- or savas **; + %if "&script." ^= "" %then %do; + %*if &messy.=0 %then %do; %** messy is always equal 1 for usesas and savas **; + %put Run &script. again using the "messy" option * ; + %put and then check the files "&out_dir._SomeNumber_infile.log" and * ; + %put "&out_dir._SomeNumber_con.log" for errors. * ; + %*end; + %end; + %else %do; + %if &messy.=0 %then %do; + %put Run SAVASTATA again using the "messy" option * ; + %put Like: %nrstr(%%)savastata(%nrbquote(&out_dir.),-messy &options.)%nrstr(;) * ; + %put and then check the file "&out_dir._SomeNumber_infile.log" for errors. * ; + %end; + %end; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=19; +%goto okay; + +%fail20: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put Either Stata ran with an error (use -messy option to see) or * ; + %put SAVASTATA was not able to get Stata to execute and * ; + %put this is not where your Stata executable file is located: * ; + %put &wstata. * ; + %put There are instructions in the top section of the savastata.sas file * ; + %put that explain how to edit the savastata.sas file to set the * ; + %put macro variable wstata to the correct location of your Stata executable file. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=20; +%goto okay; + +%fail21: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put Either Stata ran with an error (use -messy option to see) or * ; + %put SAVASTATA was not able to get Stata to execute and * ; + %put this is not how to call Stata: * ; + %put &ustata. *; + %put There are instructions in the top section of the savastata.sas file * ; + %put that explain how to edit the savastata.sas file to set the * ; + %put macro variable ustata to the correct way to call Stata. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=21; +%goto okay; + +%fail22: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put For reasons unknown SAVASTATA was not able to get Stata to execute. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=22; +%goto okay; + +%fail23: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=23; +%goto okay; + +%fail24: %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %put The input dataset &dset. has &avars. variables which exceeds the 32,767 limit of Stata SE * ; + %put Consider dropping at least %eval(&avars. - 32766) variables. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=24; +%goto okay; + +%fail25: %put * ; + %put * ; + %put %upcase(error): SAVASTATA did not save your dataset. * ; + %let nobs=%sysfunc(putn(&nobs.,comma32.)); + %let maxobs=%sysfunc(putn(&maxobs.,comma32.)); + %put The input dataset &dset. has &nobs. observations. * ; + %put which exceeds %nrquote(Stata%str(%'s)) limit of &maxobs. observations. * ; + %put For more help check here: &http. * ; + %if &isysver.<8 %then + SAVASTATA did not save your dataset + %put * ; + %let fail=25; +%goto okay; + + + +%okay: %put ; +%if &success.=0 and "&nosave."="" %then %goto done; + +%if &fail. > 0 and "&script." = "usesas" %then %do; + %** used to just delete the _infile.do file but now also creating a text file that usesas *; + %* looks for to see if savastata failed with a known error **; + %* fail22 and fail23 are unknown reasons and fail13 could be an unknown reason *; + %if (&fail. < 22 or &fail. > 23) and &fail. ^= 13 %then %do; + data _null_; + file "&temp_dir._&tfns._knerror.txt"; + put "fail==&fail."; + run; + %end; + %** erase _infile.do so that -usesas- will not attemp to run it **; + %if %sysfunc(fileexist(%nrbquote("&temp_dir._&tfns._infile.do"))) %then %do; + data _null_; + fname="tempfile"; + rc=filename(fname,"&temp_dir._&tfns._infile.do"); + if rc = 0 and fexist(fname) then + rc=fdelete(fname); + run; + %end; + %* since only run by usesas, no need to clean up or figure out how long savastata took to run. *; + %goto nevrmind; +%end; + + +%if &ascii.=1 %then %do; + options notes; + %put * ; + %put NOTE: SAVASTATA has successfully created the ascii data file %nrbquote(&out_dir.)_&tfns._.raw. * ; + %put * ; +%end; +%else %if &ascii.=0 and &messy.=1 and "&script."="" %then %do; + options notes; + %put * ; + %put NOTE: SAVASTATA has created its intermediary files _&tfns._* in: * ; + %put %nrbquote(&out_dir.) * ; + %put * ; +%end; + + +options nonotes; %** Make sure notes are shut off while deleting temp files and figuring out run time. **; +%****** clean up ***************; +%if "&script." ^= "usesas" %then %do; + proc datasets library=work nodetails nolist nowarn; + %** if a dataset does not exist, SAS does not give error message **; + %* so delete all of them. **; + delete _conten _conten1 _conten2 _conten3; + run; + quit; +%end; %** if script ^= usesas **; + +%** Figure out how much time savastata took to process the dataset. **; +%** initialize macro vars **; +%let diffhour=%sysfunc(compress(%sysfunc(hour(%sysfunc(datetime())-&startdat.)))); +%let diffmin=%sysfunc(compress(%sysfunc(minute(%sysfunc(datetime())-&startdat.)))); +%let diffsec=%sysfunc(compress(%sysfunc(second(%sysfunc(datetime())-&startdat.)))); + + options notes; + %if &diffhour.>0 %then %put NOTE: SAVASTATA took about &diffhour. hours and &dffmin. minutes to run. * ; + %else %if &diffmin.=0 %then %put NOTE: SAVASTATA took less than a minute to run. * ; + %else %put NOTE: SAVASTATA took about &diffmin. mins to run. * ; + %if &sysindex.=10 and &check.=1 %then %do; + %put ; + %put Michael says, %str(%"Checking data is cool!%") ; + %put ; + %end; +%done: ; + + options nonotes; +%if %sysfunc(fileexist(&usagelog.)) %then %do; + data _null_; + difftime=compress("&diffhour."||":"||"&diffmin."||":"||round(&diffsec.,0.1)); + file &usagelog. mod; + put " SAS dataset name: &dset. pwd=&pwdir. "; + put " Elapsed time for SAVASTATA macro is " difftime; + put " fail=&fail. "; + run; +%end; + +options obs=&obs. ¬es.; %** Restore options. **; + %** Make sure that the last dataset created in work is the users dataset. **; +%let sysdsn=&s_dsn.; +%let syslast=&s_last.; + +%if &unix.=0 %then %do; + %sysexec &pwdrive. ; %** change to the drive that SAS started out in. **; +%end; %** end of if unix=0 do loop **; +%** sysexec requires no quotes even when changing to dirs with spaces in windows or unix **; +%sysexec cd &pwdir. ; %** change to the directory that SAS started out in. **; +%nevrmind: ; %** Go to here if an error occurred before savastata started **; + +%MEND savastata; + diff --git a/Modules/ado/plus/s/sdpair.ado b/Modules/ado/plus/s/sdpair.ado new file mode 100644 index 0000000..d0ff3e7 --- /dev/null +++ b/Modules/ado/plus/s/sdpair.ado @@ -0,0 +1,75 @@ +*! sdpair.ado 1.00 by PTS (p.seed@umds.ac.uk) (STB-55: sbe33) +*! Based on Pitman (1939) Biometrika 31: 9 +*! as in Snedecor & Cochran (1967) "Statistical methods (6th ed)" (Iowas State UP) + +prog define sdpair + + version 5.0 + local varlist " req ex min(2) max(2)" + local if "opt" + local in "opt" + local weight "fweight aweight" + local options "format(string) Level(real 100)" + parse "`*'" + + tempvar touse sum diff + mark `touse' `if' `in' + markout `touse' `varlist' + if "`format'" == "" { local format "%6.4f" } + if `level' == 100 { local level = $S_level } + if `level' > 1 { local level = `level' /100 } + + parse "`varlist'", parse(" ") + + qui summ `1' if `touse' [`weight'`exp'] + tempname var1 n df var2 F r t p K lcb ucb + scalar `var1' = _result(4) + scalar `n' = _result(2) + scalar `df' = `n' - 2 + + qui summ `2' if `touse' [`weight'`exp'] + + scalar `var2' = _result(4) + + scalar `F' = `var1'/`var2' + + qui corr `varlist' if `touse' [`weight'`exp'] + scalar `r' = _result(4) + + scalar `t' = ((`F'-1)/2)*( (`df')/ ((1-`r'*`r')*`F') )^.5 + +* Note: under the null hypothesis, phi = 1 +* di "t = |" `t' "|" + + scalar `p' = tprob(`df', `t') + + + scalar `K' = 1 + 2*(1-`r'*`r')*invt(`df', `level')^2/(`df') + + scalar `lcb' = `F' * (`K' - (`K'*`K'-1)^.5) + + scalar `ucb' = `F' * (`K' + (`K'*`K'-1)^.5) + + local label1 : variable label `1' + if "`label1'" == "" {local label1 `1' } + local label2 : variable label `2' + if "`label2'" == "" {local label2 `2' } + + + zap_s + global S_1 = `n' + global S_2 = `t' + global S_3 = `df' + global S_4 = `p' + global S_5 = `F'^.5 + global S_6 = `lcb'^.5 + global S_7 = `ucb'^.5 + + + + di in gr _n(2) "Pitman's variance ratio test between `label1' and `label2': " + di in gr _n "Ratio of Standard deviations = " in ye `format' `F'^.5, " + di in gr 100*`level' "% Confidence Interval " in ye `format' `lcb'^.5 in gr " to " in ye `format' `ucb'^.5 + di in gr "t = " in ye %6.3f `t' in gr ", df = " in ye `df' in gr ", p = " in ye %6.3f `p' + +end vartest diff --git a/Modules/ado/plus/s/sdpair.hlp b/Modules/ado/plus/s/sdpair.hlp new file mode 100644 index 0000000..c851f7c --- /dev/null +++ b/Modules/ado/plus/s/sdpair.hlp @@ -0,0 +1,48 @@ +.- +help for ^sdpair^ (STB-55: sbe33) +.- + +Pitman's test of difference in variance for paired data +------------------------------------------------------- + + ^sdpair^ varname1 varname2 [weight] [^if^ exp] [^in^ range] + [^, format(^str^) l^evel^(^#^)^ ] + +^fweight^s and ^aweight^s are allowed; see help @weights@. + + +Description +----------- + +^sdpair^ produces Pitman's confidence interval for the ratio of variances +for paired data. + + +Options +------- + +^format(^str^)^ sets the format for the display of results. + +^level(^#^)^ specifies the confidence level, in percent, for confidence + intervals. The default is ^level(95)^ or as set by ^set level^. + + +Examples +-------- + + . ^use suv2^ + . ^sdpair log_p log_gp^ + + +Author +------ + Paul Seed + GKT School of Medicine + King's London, UK + email: paul.seed@@kcl.ac.uk + + +Also see +-------- + + STB: STB-55 sbe33 diff --git a/Modules/ado/plus/s/seeout.ado b/Modules/ado/plus/s/seeout.ado new file mode 100644 index 0000000..697178b --- /dev/null +++ b/Modules/ado/plus/s/seeout.ado @@ -0,0 +1,452 @@ +*! seeout version 1.2.3 21oct2009 by roywada@hotmail.com +*! (to accompany -outreg2-) + +program define seeout +version 7.0 + +syntax [using] [,LABel LABelA(passthru) ] + +if `"`using'"'~="" { + *** clean up file name, attach .txt if no file type is specified + local rest "`using'" + * strip off "using" + gettoken part rest: rest, parse(" ") + * strip off quotes + gettoken first second: rest, parse(" ") + cap local rest: list clean local(rest) + + local rabbit `"""' + if index(`"`using'"', ".")==0 { + local file = `"`rabbit'`first'.txt`rabbit'"' + local using = `"using `file'"' + } + else { + local file = `"`rabbit'`first'`rabbit'"' + local using = `"using `file'"' + } + + *** seeout the output + *local cl `"{stata `"seeout `pref'"': seeout `pref'}"' + *di as txt `"`cl'"' + seeing `using', `label' +} + +else { + *** read the set preference if not out of date + + * NOTE: `0' is written over below + cap quietly findfile outreg2.pref + tempname myfile + cap file open `myfile' using `"`r(fn)'"', read text + cap file read `myfile' date + cap file read `myfile' pref + cap file read `myfile' options + cap file close `myfile' + + if "`date'"== "`c(current_date)'" { + *** seeout the output + + if index(`"`options'"', "label")~=1 & index(`"`options'"', `"label("')==0 { + tokenize `"`options'"' + local count: word count `options' + if `count'~=0 { + local test 0 + forval num=1/`count' { + if `"``num''"'=="label" { + local label label + } + } + } + } + } /* ? */ + gettoken first file: pref + + *** codes recycled from outreg2: + * strip off quotes and extension + gettoken first second: file, parse(" ") + local temp = `"`first'"' + + local next_dot = index(`"`temp'"',".") + local next_strip = substr(`"`temp'"',1,`=`next_dot'-1') + local strippedname = substr(`"`temp'"',1,`=`next_dot'-1') + + * check for more dots + local change 0 + while `change'==0 { + local temp = substr(`"`temp'"',`=`next_dot'+1',.) + if index(`"`temp'"', ".")~=0 { + local next_dot = index(`"`temp'"',".") + local next_strip = substr(`"`temp'"',1,`=`next_dot'-1') + local strippedname = `"`strippedname'.`next_strip'"' + } + else { + * no change + local last_strip = `"`temp'"' + local change 1 + } + } + + *** check for manual rtf doc xlm xls csv extensions + if `"`last_strip'"'=="rtf" | `"`last_strip'"'=="doc" { + local word "word" + + local file = `"`rabbit'`strippedname'.txt`rabbit'"' + local using = `"using `file'"' + local wordFile "`last_strip'" + } + if `"`last_strip'"'=="xls" | `"`last_strip'"'=="xml" | `"`last_strip'"'=="xlm" | `"`last_strip'"'=="csv" { + local excel "excel" + + local file = `"`rabbit'`strippedname'.txt`rabbit'"' + local using = `"using `file'"' + local excelFile "`last_strip'" + } + if `"`last_strip'"'=="tex" { + if `"`tex1'"'=="" { + local tex "tex" + } + + local file = `"`rabbit'`strippedname'.txt`rabbit'"' + local using = `"using `file'"' + local texFile "`last_strip'" + } + + + if `"`last_strip'"'=="txt" { + seeing `pref', `label' + } + else { + if "`using'"=="" { + di in red "must specify using file" + exit 198 + } + seeing using `using', `label' + * similar to the other one except the clickable text + *local cl `"{stata `"seeout `pref'"': seeout `pref'}"' + *di as txt `"`cl'"' + } + else { + di in red "must specify the filename (the last preference has expired)" + exit 100 + } +} +end + + + +*********************** + + +program define seeing +version 7.0 + +* invisible to Stata 7 +local Version7 "" +cap local Version7 `c(stata_version)' + +if "`Version7'"=="" { + * it is version 7 + *noi di in yel "limited functions under Stata 7" +} +else if `Version7'>=8.2 { + version 8.2 +} + +quietly{ + * syntax using/[, Clear] + syntax using [, LABel LABelA(string) ] + + preserve + + insheet `using', nonames clear + describe, short + + + * number of columns + local numcol = `r(k)' + + tempvar blanks rowmiss + count if v1=="EQUATION" + if `r(N)'~=0 { + local eqPlace 1 + local varPlace 2 + count if v3=="LABELS" + if `r(N)'~=0 { + local labPlace 3 + local num=4 + } + else { + local labPlace 0 + local num=3 + } + } + else { + local eqPlace 0 + local varPlace 1 + + count if v2=="LABELS" + if `r(N)'~=0 { + local labPlace 2 + local num=3 + } + else { + local labPlace 0 + local num=2 + } + } + + gen int `blanks' = (trim(v`num')=="") + forvalues col = `num'/`numcol' { + replace `blanks' = `blanks' & (trim(v`col')=="") + } + + + * title rows + local titleWide = 0 + if v1[1]~="" | v2[1]~="" { + * there may be a title + if `labPlace'==0 & `varPlace'==1 { + while v1[`=`titleWide'+1']~="" & v2[`=`titleWide'+1']=="" { + local titleWide = `titleWide'+1 + } + } + if `labPlace'==0 & `varPlace'==2 { + while v2[`=`titleWide'+1']~="" & v3[`=`titleWide'+1']=="" { + local titleWide = `titleWide'+1 + } + } + if `labPlace'~=0 & `varPlace'==1 { + while v1[`=`titleWide'+1']~="" & v3[`=`titleWide'+1']=="" { + local titleWide = `titleWide'+1 + } + } + if `labPlace'~=0 & `varPlace'==2 { + while v2[`=`titleWide'+1']~="" & v4[`=`titleWide'+1']=="" { + local titleWide = `titleWide'+1 + } + } + } + + *local VARIABLES "VARIABLES" + * first name AFTER titles is the VARIABLES + local content + local num=`titleWide'+1 + local N=_N + while `"`content'"'=="" & `num'<=`N' { + local content=v`varPlace'[`num'] + local num=`num'+1 + } + local VARIABLES `"`content'"' + + replace `blanks'=0 if v1==`"`VARIABLES'"' | v1[_n-1]==`"`VARIABLES'"' | v2==`"`VARIABLES'"' | v2[_n-1]==`"`VARIABLES'"' + + + * getting bottomBorder (the bottom border), count up + gen rowmiss=0 + foreach var of varlist v* { + replace rowmiss=rowmiss+1 if `var'~="" + } + local N=_N + local content 1 + local num 0 + while `content'==1 & `num'<`N' { + local content rowmiss[`=`N'-`num''] + local num=`num'+1 + } + * do not have to add to titleWide + local bottomRow = `N'-`num'+1 + local bottomBorder=`bottomRow' + + * getting halfway to headBorder (the top border), count down + local content + local num=`titleWide'+1 + local N=_N + while `"`content'"'=="" & `num'<=`N' { + local content=v`varPlace'[`num'] + local num=`num'+1 + } + * do not have to add to titleWide + local headRow `num' + local headBorder=`headRow' + + drop rowmiss + + + * avoid counting space within each statistics row as missing + replace `blanks'=0 if `blanks'[_n+1]==0 & `blanks'==1 & _n >`titleWide' + + + * statistics rows + *count if `blanks'==0 + *local bottomBorder = `r(N)'+`titleWide' + + + * move the notes and titles to the top of a new column + gen str5 Notes_Titles="" + format Notes_Titles %-20s + count if v1=="EQUATION" + if `r(N)'==0 { + * EQUATION column does not exist + if `titleWide'>0 { + forval num=1/`titleWide' { + replace Notes_Titles=v1[`num'] in `num' + replace v1="" in `num' + } + } + + local one = 1 + local legend = v1[`bottomBorder'+`one'] + + + local place 1 + *while "`legend'"~="" { + local N=_N + while `place' <= `N' { + local place=`bottomBorder'+`one' + local legend = v1[`place'] + replace Notes_Titles="`legend'" in `=`one'+`titleWide'+1' + if "`legend'"~="" { + replace v1="" in `place' + } + local one = `one'+1 + } + + * insert label changes here, minus 2 from c(k) for `blanks' & Notes_Titles column + if "`label'"=="label" { + *if ("`long'"~="long" & "`onecol'"~="onecol") | ("`long'"=="long" & "`onecol'"=="onecol") { + replace v2=v1 if v2=="" + drop v1 + describe, short + forval num=1/`=`r(k)'-2' { + ren v`=`num'+1' v`num' + } + + * change LABELS to VARIABLES + replace v1=`"`VARIABLES'"' if v1=="LABELS" + *} + local label_adjust "-1" + } + + * change the string length + gen str5 temp="" + replace temp=v1 + drop v1 + ren temp v1 + order v1 + * format + foreach var of varlist v1 { + local _format= "`: format `var''" + local _widths=substr("`_format'",2,length(trim("`_format'"))-2) + format `var' %-`_widths's + } + } + else { + * equation column exists + if `titleWide'>0 { + forval num=1/`titleWide' { + replace Notes_Titles=v2[`num'] in `num' + replace v2="" in `num' + } + } + + local one = 1 + local legend = v2[`bottomBorder'+`one'] + while "`legend'"~="" { + local place=`bottomBorder'+`one' + local legend = v2[`place'] + replace Notes_Titles="`legend'" in `=`one'+`titleWide'+1' + if "`legend'"~="" { + replace v2="" in `place' + } + local one = `one'+1 + } + + * insert label changes here, minus 2 from c(k) for `blanks' & Notes_Titles column + if "`label'"=="label" { + *else if "`long'"~="long" & "`onecol'"=="onecol" { + replace v3=v2 if v3=="" + drop v2 + describe, short + forval num=2/`=`r(k)'-2' { + ren v`=`num'+1' v`num' + } + + * change LABELS to VARIABLES + replace v2=`"`VARIABLES'"' if v2=="LABELS" + *} + local label_adjust "-1" + } + + + * change the string length + gen str5 temp="" + replace temp=v2 + drop v2 + ren temp v2 + order v1 v2 + * format + foreach var of varlist v1 v2 { + local _format= "`: format `var''" + local _widths=substr("`_format'",2,length(trim("`_format'"))-2) + format `var' %-`_widths's + } + } + + * clean up + *egen `rowmiss'=rowmiss(_all) + * rowmiss option not available in 8.2 or 8.0, do it by hand + + gen `rowmiss'=0 + foreach var of varlist _all { + if "`var'"~="`rowmiss'" & "`var'"~="`blanks'" { + replace `rowmiss'=1+`rowmiss' if `var'=="" + } + } + + *drop if `rowmiss'==`numcol'+1 + + * adjust to handle label column droppings + *drop if `rowmiss'==`numcol'+1 & `blanks'==1 + + * fix blanks==1 for groupvar( ) + count if `blanks'==1 + local rN=`r(N)'+1 + forval num=1/`rN' { + replace `blanks'=0 if `blanks'[_n+1]==0 & `blanks'==1 + } + + drop if `rowmiss'==`numcol'+1 `label_adjust' & `blanks'==1 + drop `blanks' `rowmiss' + + browse + + if "`Version7'"=="" { + * it is version 7 + } + else if `Version7'>=11.0 { + noi di in yel "Hit Enter to continue" _request(junk) + } + + *restore, preserve +} +end /* end of seeing */ + +exit + + + +* versions +1.1 replaced rowmiss option in egen, which is not available in 8.2 +1.1.1 disabled -restore, preserve- as redundant waste of time + fixed seeing/seeout: handles blank space in stat(aster) + label does not show + no longer produces a seeout blue text whenever a seeout blue text was clicked +1.1.2 the shorthand form of seeout hides label +1.1.3 the shorthand form of seeout hides label: `label' is actually read from outreg2_pref.ado +1.2.0 down to version 7.0; -describe, short- instead of c(k) + if `"`using'"'~="": needed the compound quotes + VARIABLES is flexibly named +1.2.1 Apr2009 handles xls, doc, etc, that was left attached to file names in pref_ado +1.2.2 04Aug2009 a fix for asynchronoous data browser in -seeing- for version 11 +1.2.3 21oct2009 outreg2_pref should have been replaced with outreg2.pref earlier + diff --git a/Modules/ado/plus/s/seeout.hlp b/Modules/ado/plus/s/seeout.hlp new file mode 100644 index 0000000..ea059d5 --- /dev/null +++ b/Modules/ado/plus/s/seeout.hlp @@ -0,0 +1,59 @@ +{smcl} +{* Oct 2005}{...} +{cmd:help seeout} +{hline} + +{title:Title} + +{p2colset 5 16 22 2}{...} +{p2col :{hi: seeout} {hline 2}}Opens tab-delimited {helpb outreg2} table in the data browser {p_end} +{p2colreset}{...} + + +{title:Syntax} + +{p 4 8 2} +{cmdab:seeout} [,using {it:filename}] {p_end} + +{pstd} +where a {it:filename} is a document to be opened. A minimum of two tabl-delimited columns +are required for a document to be opened. {p_end} + + +{title:Description} + +{pstd}{cmd:seeout} will open a tab-delimited file created by {helpb outreg2} in the Stata data +browser. It is designed to provide a fast access to the regression table without first having to +convert the document into another format. {cmd:seeout} thus increasing the utility of such tables +in iterative research. + +{pstd}If {cmd:seeout} is invoked immediately following an {helpb outreg2} command, then it is not +necessary to specify the using {it:filename}. It will be automatically opened. + +{pstd}If no extension is provided, then .txt is assumed. + + +{title:Examples} + +{phang}{cmd:seeout using mytable} {p_end} +{phang}{cmd:seeout using "c:\myfolder\mypaper.txt"} {p_end} + +{phang}{cmd:outreg2 using mytable} {p_end} +{phang}{cmd:seeout} {p_end} + + +{title:Author} + + Roy Wada + roywada@hotmail.com + + + + + + + + + + + diff --git a/Modules/ado/plus/s/sellist.ado b/Modules/ado/plus/s/sellist.ado new file mode 100644 index 0000000..8cd1ee1 --- /dev/null +++ b/Modules/ado/plus/s/sellist.ado @@ -0,0 +1,118 @@ +program def sellist, rclass +*! NJC 1.5.0 30 November 2000 +* NJC 1.4.0 5 Sept 2000 +* NJC 1.3.0 7 June 2000 +* NJC 1.2.0 31 Jan 2000 +* NJC 1.1.0 22 Dec 1999 +* NJC 1.0.0 22 Sept 1999 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax , Select(str) /* + */ [ PREfix SUFfix POSTfix Exact Noisily Global(str) All ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + if "`exact'" != "" & "`all'" != "" { + di in r "all option not allowed with exact option" + exit 198 + } + + if "`postfix'" != "" { local postop "postfix" } + else if "`suffix'" != "" { local postop "suffix" } + + if "`postop'" != "" & "`prefix'" != "" { + di in r "choose between `postop' and prefix options" + exit 198 + } + + if "`postop'`prefix'" != "" & "`exact'`all'" != "" { + di in r /* + */ "`postop'`prefix' option not allowed with `exact'`all' option" + exit 198 + } + + tokenize `list' + local nwords : word count `list' + local i = 1 + while `i' <= `nwords' { + local len = length("``i''") + if `len' > 80 { + di in r "cannot handle word length > 80" + exit 498 + } + local i = `i' + 1 + } + + tknz `select', s(s) + local ns : word count `select' + + if "`prefix'`postop'" != "" & `ns' > 1 { + di in r /* + */ "select( ) should contain one word with `prefix'`postop' option" + exit 198 + } + + if "`exact'" != "" { + while "`1'" != "" { + local i = 1 + local OK = 0 + while `i' <= `ns' & !`OK' { + local OK = "`1'" == "`s`i''" + local i = `i' + 1 + } + if `OK' { local newlist "`newlist' `1'" } + mac shift + } + } + else { + while "`1'" != "" { + local i = 1 + local OK = 0 + while `i' <= `ns' { + local spos = /* + */ length("`1'") - length("`s`i''") + 1 + local where = index("`1'", "`s`i''") + + if "`prefix'" != "" { + local thisOK = `where' == 1 + } + else if "`postop'" != "" { + local thisOK = `where' == `spos' + } + else local thisOK = index("`1'", "`s`i''") > 0 + + local OK = `OK' + `thisOK' + local i = `i' + 1 + } + if "`all'" != "" { local OK = `OK' == `ns' } + if `OK' { local newlist "`newlist' `1'" } + mac shift + } + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + +program def tknz, rclass +* NJC 1.1.0 2 June 2000 + version 6.0 + gettoken list 0 : 0, parse(",") + syntax , Stub(str) [ * ] + tokenize `"`list'"' , `options' + + local i = 1 + while "``i''" != "" { + c_local `stub'`i' `"``i''"' + local i = `i' + 1 + } +end + diff --git a/Modules/ado/plus/s/sellist.hlp b/Modules/ado/plus/s/sellist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/s/sellist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/s/seqlist.ado b/Modules/ado/plus/s/seqlist.ado new file mode 100644 index 0000000..f7952e3 --- /dev/null +++ b/Modules/ado/plus/s/seqlist.ado @@ -0,0 +1,35 @@ +program def seqlist, rclass +*! NJC 1.2.0 4 July 2000 +* NJC 1.1.0 7 June 2000 +* NJC 1.0.0 31 Jan 2000 + version 6.0 + gettoken stub 0 : 0, parse(" ,") + if "`stub'" == "," { + local 0 ", `0'" + local stub + } + syntax , Copies(int) /* + */ [ Noisily Start(int 1) Prefix Global(str) POSTfix(str) ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + local prefix = "`prefix'" != "" + + local i = 1 + local j = `start' + while `i' <= `copies' { + if `prefix' { + local newlist "`newlist'`j'`stub'`postfix' " + } + else local newlist "`newlist'`stub'`j'`postfix' " + local i = `i' + 1 + local j = `j' + 1 + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end diff --git a/Modules/ado/plus/s/seqlist.hlp b/Modules/ado/plus/s/seqlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/s/seqlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/s/shellout.ado b/Modules/ado/plus/s/shellout.ado new file mode 100644 index 0000000..6baf76a --- /dev/null +++ b/Modules/ado/plus/s/shellout.ado @@ -0,0 +1,79 @@ +*! shellout 1.4 04Aug2008 +*! by roywada@hotmail.com +*! originally written to accompany -outreg2- +* +* version history +* 1.0 Oct2005 beta +* 1.1 Nov2007 opens an application without document name +* opens a document with or without "using" +* 1.2 Jan2008 cd option +* 1.3 Aug2008 version 7.0 +* 1.4 04Aug2008 version 7.0 fiddling (was 1.3 Aug2008); fiddling with non-.txt suffix being recognized + +program define shellout +version 7.0 + +syntax [anything] [using/] [,cd] + +* does the shelling +if "`c(os)'"=="Windows" | "$S_MACH"=="PC" { + if "`using'"~="" { + winexec cmd /c start "" "`using'" + } + else { + if "`cd'"~="cd" { + cap winexec `anything' + if _rc==193 { + winexec cmd /c start "" "`anything'" + } + if _rc==601 { + noi di in yel "Cannot find `anything'. Make sure typed the name correctly." + } + } + else { + winexec cmd /c cd `c(pwd)'\ & `anything' + } + } +} +else { + * invisible to Stata 7 + local Version7 "" + cap local Version7 `c(stata_version)' + + if "`Version7'"=="" { + * stata 7 + } + else { + * non-PC systems + di "{opt shellout} probably will not work with `c(os)'" + shell `using' + } +} +end + + +/* Old codes +* shellout +* version 1.0 +* October 2005 +* by roywada@hotmail.com +* +* (to accompany -outreg2-) +* + + +program define shelling +version 8.2 +syntax using/ +* does the shelling +*if c(machine_type)=="PC" { +if "`c(os)'"=="Windows" { + winexec cmd /c start "" "`using'" +} +else { + di "{opt shellout} probably will not work with `c(os)'" + shell `using' +} +end + + diff --git a/Modules/ado/plus/s/shellout.hlp b/Modules/ado/plus/s/shellout.hlp new file mode 100644 index 0000000..e8f5599 --- /dev/null +++ b/Modules/ado/plus/s/shellout.hlp @@ -0,0 +1,98 @@ +{smcl} +{* Nov2005}{...} +{cmd:help shellout} +{hline} + +{title:Title} + +{p2colset 5 17 22 2}{...} +{p2col :{hi: shellout} {hline 2}}Opens documents and their programs from inside Stata. {p_end} +{p2colreset}{...} + + +{title:Multiple Syntax} + +{p 4 8 2} +{cmdab:shellout} {it:application} [, cd] {p_end} +{pstd} +where {it:application} is the name of a software application to be opened. {p_end} + +{p 4 8 2} +{cmdab:shellout} [using] {it:filename} [, cd] {p_end} +{pstd} +where {it:filename} takes the form of a document with a known extension, such as .doc, +.do, .dta, .txt, .xls, .xml, etc. {p_end} + + +{title:Options} +{pstd}{opt cd} should not be used, except to tell Stata that the program +in question is located in the current directory. {p_end} + + +{title:Description} + +{pstd}{cmd:shellout} opens a document from inside Stata without having to specify the exact +file path of the program. It also opens an application with or without specifying a file +document to be opened. + +{pstd}{cmd:shellout} is a {help shell} wrapper designed for Windows XP/NT. Unlike {help shell}, implements a nested DOS command. The DOS Window is told to close itself. + +{pstd}{cmd:shellout} was originally written to accompany {helpb outreg2} for automatic opening +of non-Stata documents. + + +{title:Examples} + +{phang}{cmd:shellout} wsestata.exe {p_end} +{phang}{cmd:shellout} using myfile.xml {p_end} +{phang}{cmd:shellout} using "c:\myfolder\myfile.doc" {p_end} +{phang}{cmd:shellout} myfile.xml {p_end} +{phang}{cmd:shellout} me.do {p_end} + +{pstd}The first line will open another Stata executable. {p_end} +{pstd}The second line will open a document named myfile.xml in Excel. {p_end} +{pstd}The third line will open a document named myfile.doc in Word. {p_end} +{pstd}The fourth line will do the same thing without invoking the "using" syntax. {p_end} +{pstd}The fifth line is the equivalent of -do me- in another Stata executable, or was it -run me-.... {p_end} + + +{title:Parameters} + +{pstd}A parameter is any value passed into a batch script. {cmd:shellout} will work with +parameters in the following examples (assuming you have Stata SE) {p_end} + +{phang}{cmd:shellout} shellout wsestata.exe shellout wsestata.exe shellout wsestata.exe {p_end} +{phang}{cmd:shellout} wsestata di "Bite Me" {p_end} +{phang}{cmd:shellout} notepad "Bite Me" {p_end} + +{pstd}The first line will open three Stata executables in a daisy-chain. {p_end} +{pstd}The second line will open a Stata executable with a "Bite Me" message. {p_end} +{pstd}The third line will open a (new) notepad file called "Bite Me". {p_end} + + +{title:Advanced Parameters} + +{pstd}You can save a batch of parameters in a file and invoke it under {cmd:shellout} +much like calling upon a do-file. Learn some DOS commands if you want to implement it. {p_end} + + +{title:Author} + + Roy Wada + roywada@hotmail.com + + +{title:Also see} + +{p 9}{bf:[D] Shell} {p_end} + + + + + + + + + + + diff --git a/Modules/ado/plus/s/shortdir.ado b/Modules/ado/plus/s/shortdir.ado new file mode 100644 index 0000000..85c9a3f --- /dev/null +++ b/Modules/ado/plus/s/shortdir.ado @@ -0,0 +1,106 @@ +*! usesasdel Version 2.0 dan.blanchette@duke.edu 16Mar2009 +*! Center of Entrepreneurship and Innovation Duke University's Fuqua School of Business +** shortdir Version 2.0 dan_blanchette@unc.edu 17Jan2008 +** research computing, unc-ch +* - added check that if forward slashes used as dir separators +* then that is handled by converting them to back slashes +* - uses Nick Cox's way of loading a text file line by line +* into a local macro instead of reading it in as a dataset +** shortdir Version 1.1 dan_blanchette@unc.edu 28Oct2004 +* - added test that directory actually exists +** shortdir Version 1.0 dan_blanchette@unc.edu 09Oct2003 +** the carolina population center, unc-ch + +program define shortdir, rclass +version 8 +syntax using/ [, SHort ] + + confirmdir "`using'" + if _rc !=0 { + di `"{error}The directory "`using'" does not exist."' + exit _rc + } + +if "`c(os)'"=="Windows" { + preserve + local cwd "`c(pwd)'`macval(\\\)'" + if "`using'"=="." { + local using "`macval(cwd)'" + } + if "`using'"=="`cwd'" { + quietly cd .. + } + // check if forward slashes used and replace them if so + local subtest : subinstr local using `"/"' `""' , count(local cnt) + if `cnt' != 0 { + local using : subinstr local using "/" "\" , all + } + tokenize "`using'" , parse("\") + local i=1 + while "``i''" !="" { + if `i'==1 { + local path "`1'" + } + else { + if "`short'"=="short" { /* create macro that conditionally checks + * for longer than 8 letter directory names */ + local gt8=(length("``i''")>8) + local gt8="| `gt8'" + } + if index("``i''"," ") `gt8' { /* if sub dir name has space in name or maybe longer than 8 */ + tempfile temp + _getfilename "`temp'" + local tfilen "`r(filename)'" + + local tfileh=substr("`tfilen'",1,index("`tfilen'",".")-1) /* create file handle */ + quietly { + cd "`path'\" + // options /x and /a create a short directory listing + // so `temp' is a very small, short file + ! dir /x /a "``i''"* > "`temp'" + tempname in + file open `in' using `"`temp'"', r + file read `in' line + local dline "" + local dir "<DIR>" + while r(eof) == 0 { + // local line: subinstr local line "`old'" "`new'" + file read `in' line + if `: list local(dir) in local(line) ' { + local dline `"`line'"' + } + } + local gotit = 0 + local shortname "" + local n = 1 + while `gotit' == 0 { + local shortname : word `n' of `dline' + if `: list local(shortname) == local(dir) ' { + // the shortname of the subdir is the next word after "<DIR>" + local shortname : word `= `n' + 1' of `dline' + local gotit = 1 + } + local n = `n' + 1 + } + } + local sdir`i'=trim(substr(`"`shortname'"',1,10)) + } /* end of if directory has a space */ + else { + local sdir`i' "``i''" + } + if "``i''"!="\" { + local path "`macval(path)'\\`sdir`i''" + } + } /* if not the beginning of the path, like c: */ + local i=`i'+1 + } /* end of while loop */ + quietly cd "`macval(cwd)'\\\" + local shortdir="`path'"+"\" + return local shortdir `shortdir' +} /* end of if windows */ +else { + di "{error}shortdir only works in Windoze." + exit +} + +end diff --git a/Modules/ado/plus/s/shortdir.hlp b/Modules/ado/plus/s/shortdir.hlp new file mode 100644 index 0000000..1bb3595 --- /dev/null +++ b/Modules/ado/plus/s/shortdir.hlp @@ -0,0 +1,77 @@ +{smcl} +{*! 17Jan2008}{...} +{* 06Nov2003}{...} +{hline} +help for {hi:shortdir} {right:manual: {hi:[R] none}} +{right:dialog: {hi: none} } +{hline} + + +{title:Returns the short directory name in `r(shortdir)'} + +{p 8 17 2}{cmd:shortdir} +{it:using}{it:"directory path"} +[{cmd:,} {cmdab:sh:ort}]{p_end} + + +{title:Description} + +{p 4 4 2}{cmd:shortdir} is designed for programmers using Stata on the Windows +operating system who want to know what the short directory +name (a.k.a. "8.3" name) that DOS names a directory when it contains spaces in the name or +has more than 8 characters in the name. This command only works in Windows because it +shells out to a DOS prompt in order to get the short directory name that Windows came +up with. The formula "Take the first 6 non-space characters and add '~1'" to the directory +name does not reliably work in all situations.{p_end} + +{title:Examples} + +{p 4 8 2}{cmd:shortdir "c:\Documents and Settings\dan\Local Settings\temp"}{p_end} + +{p 4 8 2}returns in {cmd:r(shortdir)}:{p_end} + +{p 4 8 2}{cmd:"c:\Docume~1\dan\LocalS~1\temp"}{p_end} + +{p 4 8 2}{cmd:shortdir "c:\Documents and Settings\dan_blanchette\Local Settings\temp"}{p_end} + +{p 4 8 2}returns in {cmd:r(shortdir)}:{p_end} + +{p 4 8 2}{cmd:"c:\Docume~1\dan_blanchette\LocalS~1\temp"}{p_end} + +{p 4 8 2}since "dan_blanchette" has no spaces in the name.{p_end} + +{p 4 8 2}{cmd:shortdir "c:\Documents and Settings\dan_blanchette\Local Settings\temp", short}{p_end} + +{p 4 8 2}returns in {cmd:r(shortdir)}:{p_end} + +{p 4 8 2}{cmd:"c:\Docume~1\dan_bl~1\LocalS~1\temp"}{p_end} + +{p 4 8 2}since "dan_blanchette" is longer than 8 characters.{p_end} + + +{title:Saved Results} + +{p 4 4 2}The {cmd:shortdir} command saves in {cmd:r()}:{p_end} + +{synoptset 20 tabbed}{...} +{p2col 5 20 24 2: Macros}{p_end} +{synopt:{cmd:{cmd:r(shortdir)}}the directory path.{p_end} + + +{title:Author} + +{p 4 4 2} +Dan Blanchette {break} +Center of Entrepreneurship and Innovation {break} +Duke University's Fuqua School of Business {break} +Dan.Blanchette@Duke.edu{p_end} + + +{title:Also see} + +{p 4 13 2}On-line: {help tempfile} {help _getfilename} , +{help confirmdir} (if installed) +{help tmpdir} (if installed){p_end} + + + diff --git a/Modules/ado/plus/s/sjlatex.ado b/Modules/ado/plus/s/sjlatex.ado new file mode 100644 index 0000000..0bd747a --- /dev/null +++ b/Modules/ado/plus/s/sjlatex.ado @@ -0,0 +1,200 @@ +*! version 1.2.1 20dec2005 +program define sjlatex + version 7 + gettoken cmd 0 : 0, parse(" ,") + local l = length(`"`cmd'"') + preserve + if `"`cmd'"' == "" | `"`cmd'"' == "using" { + Using `cmd' `0' + di + } + else if `"`cmd'"' == substr("query",1,max(1,`l')) { + Query `0' + } + else if `"`cmd'"' == substr("install",1,max(1,`l')) { + Install `0' + } + else if `"`cmd'"' == substr("update",1,max(1,`l')) { + capture syntax [using] [, replace * ] + Install `using', replace `options' + } + else if `"`cmd'"' == substr("ado",1,max(1,`l')) { + if _caller() >= 9 { + di as txt /* +*/ "Use the {helpb adoupdate} command to update {cmd:sjlatex} and {cmd:sjlog}" + exit + } + Ado `0' + } + else { + di as error `"unrecognized command: `cmd'"' + exit 198 + } + exit +end + +/* get the SJ parameters */ +program define GetParams, sclass + sreturn local from http://www.stata-journal.com/production + sreturn local pkg sjlatex + sreturn local src sjlatex +end + +program define Using, rclass + local pwd : pwd + syntax [using/] + if `"`using'"' != "" { + quietly cd `"`using'"' + local sjdir : pwd + } + local cwd : pwd + di as txt _n "Stata Journal LaTeX files" + di as txt _col(5) "folder:" _col(25) as res `"`cwd'"' + di as txt _col(5) "installed release:" _col(25) _c + + /* The top line of this file is an example of the form of the + * sj.version file. + */ + + capture infile str20 version using sj.version + if _rc { + di as res "(unknown)" + } + else { + capture { + assert version[1] == "*!" + assert version[2] == "version" + } + if _rc { + di as res "(unknown)" + } + else { + di as res "version " version[3] " " version[4] + return local sjver = version[3] + return local sjdate = version[4] + } + } + return local sjdir `sjdir' + qui cd `"`pwd'"' +end + +program define Query, rclass + syntax [using] [, norecommend from(string) ] + Using `using' + if `"`r(sjdir)'"' != "" { + local uusing `" using `"`r(sjdir)'"'"' /*"'*/ + } + local sjdate `r(sjdate)' + local sjver `r(sjver)' + GetParams + if `"`from'"' == "" { + local from `s(from)' + } + local pkg `s(pkg)' + local src `s(src)' + tempfile sj_version + qui copy `"`from'/`src'/sj.version"' `sj_version', text + qui infile str20 version using `sj_version', clear + di as txt _col(5) "latest release:" _col(25) /* + */ as res "version " version[3] " " version[4] + local l_sjver = version[3] + local l_sjdate = version[4] + if `"`recommend'"' == "" { + di as txt _n "{p 0 5}Recommendation{break}" + if `"`sjver'`sjdate'"' == "" { + di as txt `"type -{cmd:sjlatex install`uusing'}-"' + return local recommend install + } + else if `"`sjver'`sjdate'"' != `"`l_sjver'`l_sjdate'"' { + di as txt `"type -{cmd:sjlatex update`uusing'}-"' + return local recommend update + } + else { + di as txt `"Do nothing; all files up-to-date."' + } + } +end + +program define Install + syntax [using/] [, replace from(string) noLS ] + if `"`using'"' != "" { + local uusing `" using `using'"' + } + local pwd : pwd + if `"`replace'"' == "" { + di as txt "Installing Stata Journal LaTeX files..." + if `"`using'"' != "" { + capture mkdir `"`using'"' + if _rc { + di as err /* + */ `"could not create directory `using'"' + di as txt /* + */ `"{p 0 4 2}This directory already existed."' /* + */ `"Consider supplying an alternate directory or{break}"' /* + */ `"type -{cmd:sjlatex update`uusing'}-.{p_end}"' + exit _rc + } + qui cd `"`using'"' + } + } + else { + di as txt "Updating Stata Journal LaTeX files..." + if `"`using'"' != "" { + quietly cd `"`using'"' + } + } + local sjdir : pwd + set more off + GetParams + local src `s(src)' + if `"`from'"' == "" { + local from `s(from)' + } + capture net from `"`from'"' + capture net get `src', `replace' + if _rc { + di as error `"could not copy the files to `sjdir'"' + if `"`replace'"' == "" { + di as txt `"{p}One or more files in this directory is in conflict with the Stata Journal LaTeX files. Consider supplying an alternate directory or{break}type -{cmd:sjlatex update`uusing'}-.{p_end}"' + } + else { + di as txt `"This directory may not be writable. Consider supplying an alternate directory."' + } + exit _rc + } + if "`c(stata_version)'" == "" { + capture /* + */ cp `"`from'/`src'/statapress.cls"' statapress.cls, /* + */ replace text + } + Using + if `"`replace'"' == "" & `"`ls'"' == "" { + di as input _n ". ls" + ls + } + if `"`uusing'"' != "" { + di as input _n ". pwd" + pwd + } + di in smcl as txt _n "{p 0 0 2}" /* + */ "See the Getting Started instructions" /* + */ " in the Remarks section of the online" /* + */ " documentation for {help sjlatex}.{p_end}" +end + +program define Ado + set more off + GetParams + local from `s(from)' + local pkg `s(pkg)' + quietly net from `"`from'"' + capture net install `pkg' + if _rc { + di as txt "updating package {cmd:sjlatex} package" + quietly ado uninstall `pkg' + quietly net install `pkg' + } + else di as txt "package {cmd:sjlatex} is up-to-date" +end + +exit diff --git a/Modules/ado/plus/s/sjlatex.hlp b/Modules/ado/plus/s/sjlatex.hlp new file mode 100644 index 0000000..9caaa60 --- /dev/null +++ b/Modules/ado/plus/s/sjlatex.hlp @@ -0,0 +1,268 @@ +{smcl} +{* *! version 1.0.1 11jan2006}{...} +{cmd:help sjlatex}{...} +{right:also see: {help sjlog}} +{hline} + +{title:Title} + +{pstd} +{hi:sjlatex} {hline 2} Downloading LaTeX files for the Stata Journal + + +{title:Syntax} + +{phang2} +{cmd:sjlatex} [ {cmd:using} {it:dirname} ] + +{phang2} +{cmd:sjlatex} {cmdab:q:uery} [ {cmd:using} {it:dirname} ] + +{phang2} +{cmd:sjlatex} {cmdab:i:nstall} [ {cmd:using} {it:dirname} ] [, {cmd:replace} ] + +{phang2} +{cmd:sjlatex} {cmdab:u:pdate} [ {cmd:using} {it:dirname} ] + +{phang2} +{cmd:sjlatex} {cmdab:a:do} {* !!: to be removed when official} + +{pstd} +Note that directories containing spaces should be enclosed in quotes. + + +{title:Description} + +{pstd} +The {cmd:sjlatex} command reports on the current release of the package of +LaTeX files developed for the Stata Journal and installs/updates this +package. + +{phang} +{cmd:sjlatex} reports on the LaTeX files installed in {it:dirname}. + +{phang} +{cmd:sjlatex {cmd:query}} reports on the LaTeX files installed in +{it:dirname} and displays the release number of the files at the +Stata Journal web site. + +{phang} +{cmd:sjlatex install} installs the LaTeX files in {it:dirname}. + +{phang} +{cmd:sjlatex update} updates the LaTeX files in {it:dirname}. + +{phang} +{cmd:sjlatex ado} updates {cmd:sjlatex} and the other ado files that are +packaged with {cmd:sjlatex}. This subcommand is only necessary for Stata 8 or +older; otherwise, use the {help adoupdate} command released in Stata 9. + + +{title:Options} + +{phang} +{cmd:using} {it:dirname} identifies a directory to be used in +{cmd:sjlatex} [ {cmd:query} | {cmd:install} | {cmd:update} ]. +{cmd:sjlatex install} creates {it:dirname}. The default is to use the +current directory. + +{phang} +{cmd:replace} ({cmd:sjlatex} {cmd:install} only) causes {cmd:sjlatex} +{cmd:install} to behave like {cmd:sjlatex update}. + + +{title:Remarks} + +{pstd} +Remarks are presented under the headings + + Getting Started with the Stata Journal + Running LaTeX + Downloading Examples + TeX Distributions + + +{title:Getting Started with the Stata Journal} + +{pstd} +There is a getting started example packaged with the Stata Journal LaTeX +files. The driver (main.tex) for this example uses the Stata Press document +class (statapress.cls), the Stata Press page dimensions package +(pagedims.sty), the Stata Journal package (sj.sty), the Stata +package (stata.sty), and the Stata Journal bibliographic style +(sj.bst). Individuals that have access to recent distributions of TeX are +encouraged to use these files since they are ultimately used to generate the +Stata Journal in its printed and electronic forms. + +{pstd} +An alternate driver (altmain.tex) is also supplied. This file uses the LaTeX2e +standard article document class along with sj.bst, sj.sty, and +stata.sty. This alternative driver is supplied with the hope that +compatibility will not be an issue; however, the page dimensions and font +sizes are different in this case. + + +{title:File Dependencies} + +{pstd} +The Stata Press document class (statapress.cls) is based on the standard +book document class (book.cls) in your TeX distribution. + +{phang} +statapress.cls also requires hyperref.sty, color.sty, +fancyhdr.sty, natbib.sty, makeidx.sty, showidx.sty, and +multind.sty. + +{phang} +pagedims.sty requires calc.sty and calc.sty. + +{phang} +sj.sty requires ifthen.sty and chapterbib.sty. + +{phang} +stata.sty requires alltt.sty and pstricks.sty. + +{pstd} +All of these packages are available in most "free" TeX distributions. + +{pmore} +Unfortunately crop.sty, chapterbib.sty, and natbib.sty are not +present in OzTeX 4.0, but they are collected into the +{net search sjextra:sjextra} Stata package for download. If you are using +OzTeX, then you will have to copy these files into the directory containing +your journal insert. The docstrip documentation/source for crop.sty and +natbib.sty are also included in the sjextra package for copyright +purposes. This package can be found using the following command in Stata. + +{pmore2} +{cmd:. net search} {net search sjextra:sjextra} + +{pmore} +You must also change {cmd:newcenter} to {cmd:oldcenter} in main.tex. + + +{title:Running LaTeX} + +{pstd} +Before you make any changes to main.tex (or altmain.tex) to include your +journal insert, you should test the files using the given example article +(readme.tex). In fact, the files are already set up to perform the test. In +the following, we assume that you will be using main.tex, but the instructions +are essentially the same if you use altmain.tex. + +{pstd} +The LaTeX program on Unix machines and PCs is invoked at the command prompt, +so let {cmd:>} (greater than symbol) be the command prompt. The Stata prompt +is {cmd:.} (period). Macintosh distributions of TeX tend to be based on +menus, thus the spirit of the following instructions are equivalent. + +{phang} +1. Install {cmd:sjlatex}. Then from within Stata, install the author tools +in a new directory. For example, you might try one of the following depending +upon your operating system. + +{pmore} +PC Windows:{break} +{cmd:. sjlatex install using C:\sjtemp} + +{pmore} +UNIX:{break} +{cmd:. sjlatex install using ~/sjtemp} + +{pmore} +Macintosh:{break} +{cmd:. sjlatex install using ~:sjtemp} + +{pmore} +Here {cmd:sjlatex} will indicated the version and date of the LaTeX files. + +{phang} +2. At the command prompt, you can now run LaTeX on main.tex. + +{pmore} +{inp:> latex main}{break} +{inp:> bibtex main}{break} +{inp:> latex main}{break} +{inp:> latex main}{break} +{inp:> dvips main.dvi -o main.ps} + +{pmore} +The first command generates the auxiliary (aux) file for your journal insert. +The bibtex command uses the aux file from your journal insert (main.aux for +the example) to generate bibliographic citations and references. After bibtex, +two more latex runs are needed to ensure that cross references appear +correctly in the resulting dvi-file. The last command uses dvips to generate +a PostScript file from the dvi-file. + +{pmore} +The above commands were placed in a script (included with the files downloaded +by {cmd:sjlatex}) for your convenience. + +{pmore} +PC Windows:{break} +{inp:> doit.bat} + +{pmore} +UNIX:{break} +{inp:> sh doit.sh} + +{pstd} +The final result is main.ps, which can be viewed using Ghostscript (PC: +gsview, UNIX: ghostview or gv, Macintosh: view the dvi-file from the menu). +Provided your TeX distribution contains the required packages, and passed the +above test, you can use these files to write your journal insert. Just make a +change to main.tex so that it includes the file containing your journal insert +(instead of readme.tex), and you're ready to run LaTeX on main.tex. + + +{title:Downloading Examples} + +{pstd} +The results of the above test (of main.tex and altmain.tex) have been +converted to PDF documents collected in the {net search sjxmpl:sjxmpl} Stata +package for download. This package can be found using the following command +in Stata. + +{pmore} +{cmd:. net search} {net search sjxmpl:sjxmpl} + + +{title:TeX distributions} + +{pstd} +The examples have been successfully tested using the following TeX +distributions. + +{pmore} +PC Windows: {browse "http://www.miktex.org":MiKTeX} version 2.3 (Free) + +{pmore} +UNIX: {browse "http://www.tug.org/tetex/":teTeX} versions 1.0 to 3.0 (Free) + +{pmore} +Macintosh: {browse "http://www.trevorrow.com/oztex/":OzTeX} version 4.0 +(Shareware), and {browse "http://www.kiffe.com/cmactex.html":CMacTeX} +version 4.0 (Shareware) + +{pmore} +Macintosh OS X: +{browse "http://www.uoregon.edu/~koch/texshop/texshop.html":TeXShop} +version 1.40 (Free){p_end} +{pmore2}For compatibility with {cmd:sjlatex} and TeXShop, you must + enable the {hi:Typeset} -> {hi:TeX} and {hi:Ghostscript} mode. + +{pstd} +The main web site for the Comprehensive TeX Archive Network (CTAN) is +{browse "http://www.tug.org/"}. + +{pstd} +The main web site for Ghostscript is {browse "http://www.cs.wisc.edu/~ghost/"}. + + + +{title:Also see} + +{psee} +Online: +{help sjlog} +{p_end} diff --git a/Modules/ado/plus/s/sjlog.ado b/Modules/ado/plus/s/sjlog.ado new file mode 100644 index 0000000..b02a3e2 --- /dev/null +++ b/Modules/ado/plus/s/sjlog.ado @@ -0,0 +1,501 @@ +*! version 1.2.11 18feb2010 +program define sjlog + if _caller() < 8.0 { + sjlog_7 `0' + exit + } + version 8.0 + local vv : display _caller() + + gettoken cmd 0 : 0, parse(" ,") + local l = length(`"`cmd'"') + if `"`cmd'"' == "using" | `"`cmd'"' == "open" { + LogOpen `0' + } + else if `"`cmd'"' == "close" { + LogClose `0' + } + else if `"`cmd'"' == "do" { + LogDo `vv' `0' + } + else if `"`cmd'"' == "clean" { + LogClean `0' + } + else if `"`cmd'"' == "type" { + LogType `0' + } + else if `"`cmd'"' == substr("basename",1,`l') { + LogBaseName `0' + } + else if `"`cmd'"' == "" { + log + } + else { + di as err "`cmd' invalid" + exit 198 + } +end + +program define LogSetup + syntax [, clear ] + if "`clear'" != "" { + clear + program drop _all + } + capture log close + set rmsg off + set more off + set trace off +end + +program define StripQuotes + syntax anything(name=name id="name") [, string(string) ] + c_local `name' `"`string'"' +end + +/* basename *****************************************************************/ + +program define LogBaseName, rclass + syntax anything(name=file id="filename") [, Display ] + + StripQuotes file , string(`file') + local dirsep "/" + + /* strip off the directory path */ + gettoken dir rest : file, parse("/\:") + while `"`rest'"' != "" { + if `"`dir'"' == "\" { + local dir `"`dirsep'"' + } + local dirname `"`dirname'`dir'"' + gettoken dir rest : rest , parse("\/:") + } + if `"`dirname'"' == "" { + local dirname .`dirsep' + } + + /* strip off the extension */ + gettoken ext rest : dir, parse(".") + while `"`rest'"' != "" { + local basename `basename'`ext' + gettoken ext rest : rest , parse(".") + } + if `"`basename'"' == "" { + local basename `ext' + local ext + } + else { + /* remove the last "." from `basename' */ + local l = length(`"`basename'"') - 1 + local basename = substr(`"`basename'"',1,`l') + } + + /* saved results */ + return local ext = cond(`"`ext'"'=="","",".") + `"`ext'"' + return local base `"`basename'"' + return local dir `"`dirname'"' + return local fn `"`file'"' + + if `"`display'"' != "" { + display as txt `"fn: `return(fn)'"' + display as txt `"dir: `return(dir)'"' + display as txt `"base: `return(base)'"' + display as txt `"ext: `return(ext)'"' + } +end + +/* using/close/do: subroutines **********************************************/ + +program define LogOpen + syntax anything(name=file id="filename") [, append replace ] + + LogSetup + + LogBaseName `file' + local ext `"`r(ext)'"' + if `"`ext'"' != ".smcl" { + local file `"`r(fn)'.smcl"' + } + + quietly log using `"`file'"', smcl `append' `replace' +end + +program define LogClose, rclass + syntax [, /* + */ book /* + */ replace /* + */ noCLEAN /* + */ noLOGfile /* + */ sjlogdo /* internal only, NOT documented + */ ] + + if `"`sjlogdo'"' == "" { + local logtype sjlog + } + else local logtype `sjlogdo' + + quietly log + + LogBaseName `"`r(filename)'"' + local dir `"`r(dir)'"' + local base `"`r(base)'"' + local ext `"`r(ext)'"' + local file `"`r(fn)'"' + local dbase `"`dir'`base'"' + + quietly log close + + /* log assumed to be a smcl file */ + if `"`ext'"' != ".smcl" { + di in red "assumption failed -- log file not smcl" + exit 198 + } + if `"`clean'"' == "" { + LogClean `"`file'"', `logtype' + erase `"`r(fnbak)'"' + } + + /* get TeX version of log */ + qui log texman `"`file'"' `"`dbase'.log.tex"', `replace' `book' + if `"`logfile'"' == "" { + /* get plain text version of log */ + qui translate `"`file'"' `"`dbase'.log"', `replace' + } + + /* saved results */ + if `"`logfile'"' == "" { + return local fn_log `"`dbase'.log"' + } + return local fn_tex `"`dbase'.log.tex"' + return local fn_smcl `"`dbase'.smcl"' +end + +program define LogDo + version 8.0 + gettoken vv 0 : 0 + local vv "version `vv':" + syntax anything(name=file id="filename") [, /// + clear /// + replace /// + book /// + nostop /// + SAVing(string) /// + ] + + if "`saving'" != "" { + capture confirm name `saving' + if _rc { + di as err /// + "'`saving'' found where saving() option requires a valid name" + exit 198 + } + } + + LogSetup, `clear' + + LogBaseName `file' + local base = cond("`saving'"=="","`r(base)'","`saving'") + local dbase `"`r(dir)'`base'"' + local ext `"`r(ext)'"' + local file `"`r(fn)'"' + if `"`ext'"' != ".do" { + local dbase `"`dbase'`ext'"' + } + + LogOpen `dbase', `replace' + capture noisily `vv' do `file', `stop' + local rc = _rc + if `rc' { + local cap capture + } + `cap' LogClose, `replace' sjlogdo `book' + exit `rc' +end + +/* clean: subroutines *******************************************************/ + +program define LogClean, rclass + syntax anything(name=file id="filename") [, /* + */ log /* + */ logclose /* + */ sjlog /* + */ sjlogdo /* + */ ] + + /* validate arguments and options */ + local logsrc `log' `logclose' `sjlog' `sjlogdo' + local wc : word count `logsrc' + if `wc' > 1 { + di as err "options `logsrc' may not be combined" + exit 198 + } + StripQuotes file , string(`file') + confirm file `"`file'"' + + /* open files */ + tempname rf wf + tempfile newfile + file open `rf' using `"`file'"', read text + file open `wf' using `"`newfile'"', write text + + /* clean file */ + capture noisily { + if `"`logsrc'"' == "logclose" { + CleanLogclose `rf' `wf' + } + else if `"`logsrc'"' == "sjlog" { + CleanSJLog `rf' `wf' + } + else if `"`logsrc'"' == "sjlogdo" { + CleanSJLogDo `rf' `wf' + } + else { /* Default: `"`logsrc'"' == "log" */ + CleanLog `rf' `wf' + } + } // capture noisily + local rc = _rc + + /* close files */ + file close `wf' + file close `rf' + + if (`rc') exit `rc' + + /* make a backup copy of the input file (rf) and save the output file + * (wf) using the given filename + */ + + local backup `file'.bak + copy `"`file'"' `"`backup'"', replace + copy `"`newfile'"' `"`file'"', replace + + /* saved results */ + return local fnbak `"`backup'"' + return local fn `"`file'"' +end + +/* Clean log produced by -sjlog do-. + * + * This subroutine has a 3 line buffer; the end of a log from -sjlog do- will + * always have: + * + * 1. a blank line + * 2. a line with the text: "." + * 3. a line with the text: "end of do-file" + * + * This subroutine also works with smcl files, and TeX files generated from + * smcl files using -log texman- (its original purpose). + */ + +program define CleanSJLogDo + args rf wf + + /* skip the smcl header lines */ + file read `rf' line1 + if `"`line1'"' == "{smcl}" { + file read `rf' line1 + /* skip next line too, if is part of the smcl header */ + if `"`line1'"' == "{com}{sf}{ul off}{txt}" { + file read `rf' line1 + } + file read `rf' line2 + } + else { + file read `rf' line2 + } + + file read `rf' line3 + local break 0 + while r(eof)==0 { + if substr(`"`line3'"',-14,.) == "end of do-file" { + local break 1 + continue, break + } + file write `wf' `"`macval(line1)'"' _n + local line1 `"`macval(line2)'"' + local line2 `"`macval(line3)'"' + file read `rf' line3 + } + if ! `break' { + file write `wf' `"`macval(line1)'"' _n + file write `wf' `"`macval(line2)'"' _n + } + else { + if !inlist(`"`macval(line1)'"',"{txt}","{res}{txt}") { + file write `wf' `"`macval(line1)'"' _n + } + } +end + +/* Clean log produced by -sjlog using- and -sjlog close-. */ + +program define CleanSJLog + args rf wf + + CleanLogUsingHeader `rf' + + /* skip the smcl header lines */ + file read `rf' line1 + if `"`line1'"' == "{smcl}" { + file read `rf' line1 + /* skip next line too, if is part of the smcl header */ + if `"`line1'"' == "{com}{sf}{ul off}{txt}" { + file read `rf' line1 + } + file read `rf' line2 + } + else { + file read `rf' line2 + } + + local break 0 + while r(eof)==0 { + if index(`"`line2'"',". sjlog close") { + local break 1 + continue, break + } + file write `wf' `"`macval(line1)'"' _n + local line1 `"`macval(line2)'"' + file read `rf' line2 + } + if ! `break' | !inlist(`"`macval(line1)'"', "", "{res}{txt}") { + file write `wf' `"`macval(line1)'"' _n + } +end + +/* Clean log produced by Stata's -log using- and -log close- commands. */ + +program define CleanLog + args rf wf + + CleanLogUsingHeader `rf' + + file read `rf' line + local break 0 + while r(eof)==0 { + /* stop when we encounter the -log close- command. */ + if substr(`"`line'"',-11,.) == ". log close" { + local break 1 + continue, break + } + file write `wf' `"`macval(line)'"' _n + file read `rf' line + } +end + +/* Clean log produced by Stata's -log using- command and -logclose-. */ + +program define CleanLogclose + args rf wf + + CleanLogUsingHeader `rf' + + file read `rf' line + local break 0 + while r(eof)==0 { + /* stop when we encounter the -log close- command. */ + if substr(`"`line'"',-10,.) == ". logclose" { + local break 1 + continue, break + } + file write `wf' `"`macval(line)'"' _n + file read `rf' line + } +end + +/* Skip first 5 lines comprising the header output from -log using-. */ + +program define CleanLogUsingHeader + args rf + + /* hline */ + file read `rf' line + if `"`line'"' == "{smcl}" { + file read `rf' line + file read `rf' line + } + else if index(`"`line'"', "-----") { + file read `rf' line + } + if ! index(`"`line'"', "log:") { + file seek `rf' tof + exit + } + + file read `rf' line + if ! index(`"`line'"', "log type:") { + file seek `rf' tof + exit + } + + file read `rf' line + if ! index(`"`line'"', "opened on:") { + file seek `rf' tof + exit + } + + /* blank line */ + file read `rf' line +end + +/* type: subroutines ********************************************************/ + +program define LogType, rclass + syntax anything(name=file id="filename") [, /* + */ replace /* + */ find /* + */ path(passthru) /* + */ LOGfile /* + */ SMCLfile /* + */ ] + + LogSetup + + if "`logfile'" == "" { + local logfile nologfile + } + StripQuotes file , string(`file') + if `"`find'"' != "" { + capture which findfile + if _rc { + di as err "option find requires Stata 8 or later" + exit 111 + } + quietly findfile `"`file'"', `path' + local file `r(fn)' + } + + LogBaseName `file' + local file `"`r(fn)'"' + local dbase `"`r(dir)'`r(base)'"' + local ext `"`r(ext)'"' + if ! inlist(`"`ext'"',".smcl",".hlp") { + local dbase `"`dbase'`ext'"' + } + +capture noisily { + + tempfile tt + LogOpen `tt' + type `"`file'"' + LogClose, noclean `logfile' + copy `"`tt'.log.tex"' `"`dbase'.log.tex"', `replace' + return local fn_tex `"`dbase'.log.tex"' + if "`logfile'" == "logfile" { + copy `"`tt'.log"' `"`dbase'.log"', `replace' + return local fn_log `"`dbase'.log"' + } + +} + + local rc = _rc + if "`smclfile'" != "" { + copy `"`tt'.smcl"' `"`dbase'.smcl"', `replace' + return local fn_smcl `"`dbase'.smcl"' + } + capture erase `"`tt'.smcl"' + capture erase `"`tt'.log.tex"' + exit `rc' +end + +exit diff --git a/Modules/ado/plus/s/sjlog.hlp b/Modules/ado/plus/s/sjlog.hlp new file mode 100644 index 0000000..80659b1 --- /dev/null +++ b/Modules/ado/plus/s/sjlog.hlp @@ -0,0 +1,351 @@ +{smcl} +{* *! version 1.0.0 20dec2005}{...} +{cmd:help sjlog}{...} +{right:also see: {help sjlatex}} +{hline} + +{title:Title} + +{pstd} +{hi:sjlog} {hline 2} Creating and managing logs for Stata Journal articles + + +{title:Syntax} + +{phang2} +{cmd:sjlog} {it:subcmd} ... + + +{title:Opening and closing logs} + +{phang2} +{cmd:sjlog} {cmd:using} {it:filename} + [, + {cmd:append} | {cmd: replace} + ] + +{phang2} +{cmd:sjlog} {cmd:close} + [, + {cmd:noclean} + {cmd:no}{cmdab:log:file} + {cmd:replace} + {cmd:book} + ] + + +{title:Logging the results of a do-file} + +{phang2} +{cmd:sjlog} {cmd:do} {it:filename} + [, + {cmd:clear} + {cmd:replace} + {cmd:book} + {cmd:nostop} + {cmdab:sav:ing:(}{it:basename}{cmd:)} + ] + + +{title:Utilities} + +{pstd} +Removing unwanted lines from a log. + +{phang2} +{cmd:sjlog} {cmd:clean} {it:filename} + [, + {cmd:log} | + {cmd:logclose} | + {cmd:sjlog} | + {cmd:sjlogdo} + ] + + +{pstd} +Copy a file to be included in an Stata Journal article. + +{phang2} +{cmd:sjlog} {cmd:type} {it:filename} + [, + {cmd:replace} + {cmd:find} + {cmd:path(}{it:path}{cmd:)} + {cmdab:log:file} + {cmdab:smcl:file} + ] + + +{pstd} +Split a file name into three parts. + +{phang2} +{cmd:sjlog} {cmdab:base:name} {it:filename} + [, + {cmdab:d:isplay} + ] + + +{pstd} +Note that filenames containing spaces should be enclosed in quotes. + + +{title:Description} + +{pstd} +{cmd:sjlog} is a tool for Stata users who are writing documents that contain +Stata output. It was written to help authors of the Stata Journal. + +{phang} +{cmd:sjlog} {cmd:using}/{cmd:close} open and close log files similar to the +log command, see help {help log}. + +{phang} +{cmd:sjlog} {cmd:do} logs the output generated by the specified do-file. + +{phang} +{cmd:sjlog} {cmd:clean} removes lines of text from {cmd:smcl} files. This +subcommand was added to facilitate the removal of the header and footer +generated by the {cmd:log} command, as well as the command that closed the +log. + +{phang} +{cmd:sjlog} {cmd:type} makes a copy of a file with some substitutions to make +the file is suitable for inclusion in a TeX or LaTeX document. + +{phang} +This subroutine facilitates the inclusion of do-files and ado-files in Stata +Journal articles without having to manually maintain duplicate copies of the +same file. + +{phang} +{cmd:sjlog} {cmd:type} can also be used to copy {cmd:smcl} files to a format +suitable for inclusion in a TeX or LaTeX document provided you also have +stata.sty, a LaTeX package written for the Stata Journal. For more +information about LaTeX packages written for the Stata Journal, see help +{help sjlatex}. + +{phang} +{cmd:sjlog} {cmd:basename} is something of a combination of the UNIX commands +{bf:basename} and {bf:dirname}. It simply splits the specified file into +three distinct parts: + +{pmore} +1. the directory path (e.g. {cmd:/work/}, {cmd:C:\work\}){break} +2. the suffix (e.g. {cmd:.do}, {cmd:.log}, {cmd:.smcl}){break} +3. the basename (what is left over from 1 and 2) + +{phang} +The {cmd:display} option causes {cmd:sjlog} {cmd:basename} to display the +results. + + +{title:Options for {cmd:sjlog} {cmd:using}/{cmd:close}/{cmd:do}} + +{phang} +{cmd:append} ({cmd:sjlog} {cmd:using} only) allows the output to be appended +onto the end of an already existing file. See the {cmd:append} option in help +{help log}. + +{phang} +{cmd:replace} (for all {cmd:sjlog} subroutines) indicates that exiting +{it:filename} (with a {cmd:.smcl}, {cmd:.log}, or {cmd:.log.tex} suffix) will +be overwritten. + +{phang} +{cmd:noclean} ({cmd:sjlog} {cmd:close} only) prevents {cmd:sjlog} from +"cleaning" the {cmd:smcl} log before generating the plain text and TeX +version. + +{phang} +{cmd:clear} ({cmd:sjlog} {cmd:do} only) causes {cmd:sjlog} to run +"{cmd}program drop _all{reset}" prior to running "{cmd:do} {it:filename}". + +{phang} +{cmd:book} ({cmd:sjlog} {cmd:close}/{cmd:do} only) causes {cmd:sjlog} to use +special escape characters in the generated TeX file. This option is no longer +necessary, but was added to facilitate maintenance of legacy documents that +used the LaTeX listings environment to display Stata logs. + +{phang} +{cmd:nostop} ({cmd:sjlog} {cmd:do} only) allows the do-file to continue +executing even if an error occurs. + +{phang} +{cmd:saving(}{it:basename}{cmd:)} ({cmd:sjlog} {cmd:do} only) allows for the +logs to be saved to {it:basename}.smcl, {it:basename}.log, and +{it:basename}.log.tex, instead of using the 'basename' of the do-file. + + +{title:Options for {cmd:sjlog} {cmd:clean}} + +{phang} +{cmd:log} (default) indicates that {it:filename} was created by {cmd:log} +{cmd:using} and {cmd:log} {cmd:close}. This results in the removal of the log +header and footer created by the {cmd:log} command (if they exist), as well as +the removal of the last executed command (and the preceding blank) if it is: + +{pmore2} +{cmd}. log close{reset} + +{phang} +{cmd:logclose} indicates that {it:filename} was created by {cmd:log} +{cmd:using} and {cmd:logclose}. This results in the removal of the log +header and footer created by the {cmd:log} command (if they exist), as well as +the removal of the last executed command (and the preceding blank) if it is: + +{pmore2} +{cmd}. logclose{reset} + +{phang} +{cmd:sjlog} indicates that {it:filename} was created by {cmd:sjlog} +{cmd:using} and {cmd:sjlog} {cmd:close}. This results in the removal of the +last executed command (and the preceding blank) if it is: + +{pmore2} +{cmd}. sjlog close{reset} + +{phang} +{cmd:sjlogdo} indicates that {it:filename} was created by {cmd:sjlog} +{cmd:do}. This results in the removal of the last line of output (and the +preceding blank) if it is: + +{pmore2} +{cmd}end of do-file{reset} + + +{title:Options for {cmd:sjlog} {cmd:type}} + +{phang} +{cmd:find} indicates that {it:filename} is somewhere on the ado path. This +option requires the {cmd:findfile} command introduced in Stata 8, see help +{help findfile}. + +{phang} +{cmd:path()} specifies the path over which {cmd:findfile} is to search, see +the {cmd:path()} option description in help {help findfile}. + +{phang} +{cmd:logfile} specifies that a plain text file also be created. + +{phang} +{cmd:smclfile} specifies that a SMCL file also be created. + + +{title:Details: generating logs} + +{pstd} +The logged output will be saved in three formats: + +{phang} +1. The plain text log will have a {cmd:.log} suffix. +{break} +2. The smcl log will be saved with a {cmd:.smcl} suffix. +{break} +3. The TeX log will have a {cmd:.log.tex} suffix. + +{pstd} +The TeX log utilizes some tailored TeX macros defined in stata.sty, a LaTeX +package designed for the Stata Journal. + +{pstd} +Logs can be generated in one of two ways: + +{phang} +(1) {cmd:sjlog} {cmd:using} {it:filename} turns Stata's logging on, and saves +the output to {it:filename}. + +{pmore2} +It is recommended that {it:filename} not have a suffix; in any case, an +appropriate suffix will be supplied according to the above list. + +{phang2} +{cmd:sjlog} {cmd:close} closes the current log. + +{phang} +(2) {cmd:sjlog} {cmd:do} {it:filename} is almost exactly like running the +following commands: + +{pmore2} +{cmd} +. sjlog using {it:filename} +{break} +. do {it:filename}.do +{break} +. sjlog close +{reset} + +{phang} +where {it:filename} is the base name (having no suffix) of a Stata do-file, +except the command "{cmd}do {it:filename}.do{reset}" is removed from the log. + +{pstd} +When you begin logging, {cmd:sjlog} will first close the current log (if there +is one) before opening a new log with the given options. Also the {help more} +and {help trace} settings are turned off. + + +{title:Details: copying files} + +{pstd} +{cmd:sjlog} {cmd:type} is almost exactly like running the following commands: + +{pmore2} +{cmd} +. sjlog using {it:filename}.tex +{break} +. type {it:filename} +{break} +. sjlog close +{reset} + +{title:Saved results} + +{pstd} +{cmd:sjlog} {cmd:close} saves in {cmd:r()}: + + Macros + {cmd:r(fn)} name of the TeX log + + +{pstd} +{cmd:sjlog} {cmd:clean} saves in {cmd:r()}: + + Macros + {cmd:r(fn)} {it:filename} + {cmd:r(fnbak)} {it:filename}.bak, backup copy of {it:filename} + + +{pstd} +{cmd:sjlog} {cmd:type} saves in {cmd:r()}: + + Macros + {cmd:r(fn)} {it:filename}.tex, copy of {it:filename} + + +{pstd} +{cmd:sjlog} {cmd:basename} saves in {cmd:r()}: + + Macros + {cmd:r(fn)} {it:filename} + {cmd:r(dir)} directory path of {it:filename} + {cmd:r(base)} basename of {it:filename} + {cmd:r(ext)} extension suffix of {it:filename} + + +{title:Also see} + +{psee} +Manual: +{hi:[R] log}, +{hi:[P] program}, +{hi:[P] smcl}, +{hi:[R] translate} + +{p 4 13 2} +Online: +{help log}, +{help program}, +{help smcl}, +{help translate} +{p_end} diff --git a/Modules/ado/plus/s/sjlog_7.ado b/Modules/ado/plus/s/sjlog_7.ado new file mode 100644 index 0000000..813d15c --- /dev/null +++ b/Modules/ado/plus/s/sjlog_7.ado @@ -0,0 +1,569 @@ +*! version 1.1.13 06may2003 +program define sjlog_7 + version 7 + local vv : di "version " _caller() ":" + + gettoken cmd 0 : 0, parse(" ,") + local l = length(`"`cmd'"') + if `"`cmd'"' == "using" | `"`cmd'"' == "open" { + LogOpen `0' + } + else if `"`cmd'"' == "close" { + LogClose `0' + } + else if `"`cmd'"' == "do" { + `vv' LogDo `0' + } + else if `"`cmd'"' == "clean" { + LogClean `0' + } + else if `"`cmd'"' == "type" { + LogType `0' + } + else if `"`cmd'"' == substr("basename",1,`l') { + LogBaseName `0' + } + else if `"`cmd'"' == "" { + log + } + else { + di as err "`cmd' invalid" + exit 198 + } +end + +program define LogSetup + syntax [, clear ] + if "`clear'" != "" { + clear + program drop _all + } + capture log close + set rmsg off + set more off + set trace off +end + +program define StripQuotes + syntax anything(name=name id="name") [, string(string) ] + c_local `name' `"`string'"' +end + +/* basename *****************************************************************/ + +program define LogBaseName, rclass + syntax anything(name=file id="filename") [, Display ] + + StripQuotes file , string(`file') + local dirsep "/" + + /* strip off the directory path */ + gettoken dir rest : file, parse("/\:") + while `"`rest'"' != "" { + if `"`dir'"' == "\" { + local dir `"`dirsep'"' + } + local dirname `"`dirname'`dir'"' + gettoken dir rest : rest , parse("\/:") + } + if `"`dirname'"' == "" { + local dirname .`dirsep' + } + + /* strip off the extension */ + gettoken ext rest : dir, parse(".") + while `"`rest'"' != "" { + local basename `basename'`ext' + gettoken ext rest : rest , parse(".") + } + if `"`basename'"' == "" { + local basename `ext' + local ext + } + else { + /* remove the last "." from `basename' */ + local l = length(`"`basename'"') - 1 + local basename = substr(`"`basename'"',1,`l') + } + + /* saved results */ + return local ext = cond(`"`ext'"'=="","",".") + `"`ext'"' + return local base `"`basename'"' + return local dir `"`dirname'"' + return local fn `"`file'"' + + if `"`display'"' != "" { + display as txt `"fn: `return(fn)'"' + display as txt `"dir: `return(dir)'"' + display as txt `"base: `return(base)'"' + display as txt `"ext: `return(ext)'"' + } +end + +/* using/close/do: subroutines **********************************************/ + +program define LogOpen + syntax anything(name=file id="filename") [, append replace ] + + LogSetup + + LogBaseName `file' + local ext `"`r(ext)'"' + if `"`ext'"' != ".smcl" { + local file `"`r(fn)'.smcl"' + } + + quietly log using `"`file'"', smcl `append' `replace' +end + +program define LogClose, rclass + syntax [, /* + */ book /* + */ replace /* + */ noCLEAN /* + */ noLOGfile /* + */ sjlogdo /* internal only, NOT documented + */ ] + + if `"`sjlogdo'"' == "" { + local logtype sjlog + } + else local logtype `sjlogdo' + + quietly log + + LogBaseName `"`r(filename)'"' + local dir `"`r(dir)'"' + local base `"`r(base)'"' + local ext `"`r(ext)'"' + local file `"`r(fn)'"' + local dbase `"`dir'`base'"' + + quietly log close + + /* log assumed to be a smcl file */ + if `"`ext'"' != ".smcl" { + di in red "assumption failed -- log file not smcl" + exit 198 + } + if `"`clean'"' == "" { + LogClean `"`file'"', `logtype' + erase `r(fnbak)' + } + + /* get TeX version of log */ + qui log texman `"`file'"' `"`dbase'.log.tex"', `replace' `book' + if `"`logfile'"' == "" { + /* get plain text version of log */ + qui translate `"`file'"' `"`dbase'.log"', `replace' + } + + /* saved results */ + if `"`logfile'"' == "" { + return local fn_log `"`dbase'.log"' + } + return local fn_tex `"`dbase'.log.tex"' + return local fn_smcl `"`dbase'.smcl"' +end + +program define LogDo + version 7.0 + local vv : display "version " _caller() ":" + syntax anything(name=file id="filename") [, /* + */ clear /* + */ replace /* + */ book /* + */ nostop /* + */ SAVing(string) /* + */ ] + + if "`saving'" != "" { + capture confirm name `saving' + if _rc { + di as err /* + */ "'`saving'' found where saving() option requires a valid name" + exit 198 + } + } + + LogSetup, `clear' + + LogBaseName `file' + local base = cond("`saving'"=="","`r(base)'","`saving'") + local dbase `"`r(dir)'`base'"' + local ext `"`r(ext)'"' + local file `"`r(fn)'"' + if `"`ext'"' != ".do" { + local dbase `"`dbase'`ext'"' + } + + LogOpen `dbase', `replace' + capture noisily `vv' do `file', `stop' + local rc = _rc + if `rc' { + local cap capture + } + `cap' LogClose, `replace' sjlogdo `book' + exit `rc' +end + +/* clean: subroutines *******************************************************/ + +program define LogClean, rclass + syntax anything(name=file id="filename") [, /* + */ log /* + */ logclose /* + */ sjlog /* + */ sjlogdo /* + */ ] + + /* validate arguments and options */ + local logsrc `log' `logclose' `sjlog' `sjlogdo' + local wc : word count `logsrc' + if `wc' > 1 { + di as err "options `logsrc' may not be combined" + exit 198 + } + StripQuotes file , string(`file') + confirm file `"`file'"' + + /* open files */ + tempname rf wf + tempfile newfile + file open `rf' using `"`file'"', read text + file open `wf' using `"`newfile'"', write text + + /* clean file */ + capture noisily { + initMacros + if `"`logsrc'"' == "logclose" { + CleanLogclose `rf' `wf' + } + else if `"`logsrc'"' == "sjlog" { + CleanSJLog `rf' `wf' + } + else if `"`logsrc'"' == "sjlogdo" { + CleanSJLogDo `rf' `wf' + } + else { /* Default: `"`logsrc'"' == "log" */ + CleanLog `rf' `wf' + } + } + local rc = _rc + + /* close files */ + file close `wf' + file close `rf' + + removeMacros `rc' + + /* make a backup copy of the input file (rf) and save the output file + * (wf) using the given filename + */ + + local backup `file'.bak + copy `"`file'"' `"`backup'"', replace + copy `"`newfile'"' `"`file'"', replace + + /* saved results */ + return local fnbak `"`backup'"' + return local fn `"`file'"' +end + +program define initMacros + global SJL_maxn 10 + global SJL_n 0 + global SJL_parity 0 +end + +program define removeMacros + args rc + + if "$SJL_parity" != "0" & "$SJL_parity" != "" { + di as err "$SJL_parity nonempty global macros" + forval i = 1/$SJL_maxn { + if `"${SJL_`i'}"' != "" { + di _asis as txt /* + */ `"SJL_`i' is |${SJL_`i'}{reset}{text}|"' + } + global SJL_`i' + } + if ! `rc' { + local rc 459 + } + } + global SJL_parity + global SJL_maxn + global SJL_n + + exit `rc' +end + +program define removeLine + args line + + global `line' + /* decrease number of lines read */ + global SJL_parity = $SJL_parity - 1 +end + +program define FileRead + args hh c_line + + /* read in line */ + file read `hh' rline + + /* increase number of lines read */ + local n = mod($SJL_n,$SJL_maxn) + 1 + + /* increase parity index */ + global SJL_parity = $SJL_parity + 1 + + /* escape quotes */ + local qline : /* + */ subinstr local rline "\`" "\\\`" , all count(local qc) + + /* escape dollars */ + global SJL_`n' : /* + */ subinstr local qline "\$" "\\\$" , all count(local dc) + + /* return name of global macro containing new line */ + c_local `c_line' SJL_`n' + + /* save number of lines read */ + global SJL_n `n' +end + +program define FileWrite + args hh line + + /* write contents of global to file */ + file write `hh' `"${`line'}"' _n + + removeLine `line' +end + +/* Clean log produced by -sjlog do-. + * + * This subroutine has a 3 line buffer; the end of a log from -sjlog do- will + * always have: + * + * 1. a blank line + * 2. a line with the text: "." + * 3. a line with the text: "end of do-file" + * + * This subroutine also works with smcl files, and TeX files generated from + * smcl files using -log texman- (its original purpose). + */ + +program define CleanSJLogDo + args rf wf + + /* skip the smcl header lines */ + FileRead `rf' line1 + if `"${`line1'}"' == "{smcl}" { + /* skip next line too, it is part of the smcl header */ + removeLine `line1' + FileRead `rf' line1 + removeLine `line1' + } + else { + FileWrite `wf' `line1' + } + + FileRead `rf' line1 + FileRead `rf' line2 + local break 0 + while r(eof)==0 { + if substr(`"${`line2'}"',-14,.) == "end of do-file" { + local break 1 + continue, break + } + FileWrite `wf' `line1' + local line1 `line2' + FileRead `rf' line2 + } + if ! `break' { + FileWrite `wf' `line1' + removeLine `line2' + } + else { + removeLine `line1' + removeLine `line2' + } +end + +/* Clean log produced by -sjlog using- and -sjlog close-. */ + +program define CleanSJLog + args rf wf + + CleanLogUsingHeader `rf' + + /* skip the smcl header lines */ + FileRead `rf' line1 + if `"${`line1'}"' == "{smcl}" { + /* skip next line too, it is part of the smcl header */ + removeLine `line1' + FileRead `rf' line1 + removeLine `line1' + } + else { + FileWrite `wf' `line1' + } + + FileRead `rf' line1 + FileRead `rf' line2 + local break 0 + while r(eof)==0 { + if index(`"${`line2'}"',". sjlog close") { + local break 1 + continue, break + } + FileWrite `wf' `line1' + local line1 `line2' + FileRead `rf' line2 + } + if ! `break' { + FileWrite `wf' `line1' + removeLine `line2' + } + else { + removeLine `line1' + removeLine `line2' + } +end + +/* Clean log produced by Stata's -log using- and -log close- commands. */ + +program define CleanLog + args rf wf + + CleanLogUsingHeader `rf' + + FileRead `rf' line + local break 0 + while r(eof)==0 { + /* stop when we encounter the -log close- command. */ + if substr(`"${`line'}"',-11,.) == ". log close" { + local break 1 + continue, break + } + FileWrite `wf' `line' + FileRead `rf' line + } + if `break' { + removeLine `line' + } +end + +/* Clean log produced by Stata's -log using- command and -logclose-. */ + +program define CleanLogclose + args rf wf + + CleanLogUsingHeader `rf' + + FileRead `rf' line + local break 0 + while r(eof)==0 { + /* stop when we encounter the -log close- command. */ + if substr(`"${`line'}"',-10,.) == ". logclose" { + local break 1 + continue, break + } + FileWrite `wf' `line' + FileRead `rf' line + } + if `break' { + removeLine `line' + } +end + +/* Skip first 5 lines comprising the header output from -log using-. */ + +program define CleanLogUsingHeader + args rf + + /* hline */ + file read `rf' line + if `"`line'"' == "{smcl}" { + file read `rf' line + } + + file read `rf' line + if ! index(`"`line'"', "log:") { + file seek `rf' tof + exit + } + + file read `rf' line + if ! index(`"`line'"', "log type:") { + file seek `rf' tof + exit + } + + file read `rf' line + if ! index(`"`line'"', "opened on:") { + file seek `rf' tof + exit + } + + /* blank line */ + file read `rf' line +end + +/* type: subroutines ********************************************************/ + +program define LogType + syntax anything(name=file id="filename") [, /* + */ replace /* + */ find /* + */ path(passthru) /* + */ logfile /* + */ ] + + LogSetup + + if "`logfile'" == "" { + local logfile nologfile + } + StripQuotes file , string(`file') + if `"`find'"' != "" { + capture which findfile + if _rc { + di as err "option find requires Stata 8 or later" + exit 111 + } + quietly findfile `"`file'"', `path' + local file `r(fn)' + } + + LogBaseName `file' + local file `"`r(fn)'"' + local dbase `"`r(dir)'`r(base)'"' + local ext `"`r(ext)'"' + if ! inlist(`"`ext'"',".smcl",".hlp") { + local dbase `"`dbase'`ext'"' + } + +capture noisily { + + tempfile tt + LogOpen `tt' + type `file' + LogClose, noclean `logfile' + copy `"`tt'.log.tex"' `"`dbase'.log.tex"', `replace' + if "`logfile'" == "logfile" { + copy `"`tt'.log"' `"`dbase'.log"', `replace' + } + +} + + local rc = _rc + capture erase `"`tt'.smcl"' + capture erase `"`tt'.log.tex"' + exit `rc' +end + +exit diff --git a/Modules/ado/plus/s/sortlist.ado b/Modules/ado/plus/s/sortlist.ado new file mode 100644 index 0000000..d2a0aad --- /dev/null +++ b/Modules/ado/plus/s/sortlist.ado @@ -0,0 +1,54 @@ +program def sortlist, rclass +*! NJC 1.2.0 7 June 2000 +* NJC 1.1.0 22 Dec 1999 +* NJC 1.0.0 22 Sept 1999 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax [, Noisily Global(str) ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tokenize `list' + local nwords : word count `list' + + if `nwords' > _N { + preserve + clear + qui set obs `nwords' + } + + tempvar words miss + qui gen str1 `words' = "" + + local i = 1 + while `i' <= `nwords' { + local len = length("``i''") + if `len' > 80 { + di in r "cannot handle word length > 80" + exit 498 + } + qui replace `words' = "``i''" in `i' + local i = `i' + 1 + } + gen byte `miss' = missing(`words') + sort `miss' `words' + + local i = 1 + while `i' <= `nwords' { + local word = `words'[`i'] + local newlist "`newlist' `word'" + local i = `i' + 1 + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/s/sortlist.hlp b/Modules/ado/plus/s/sortlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/s/sortlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/s/spex.ado b/Modules/ado/plus/s/spex.ado new file mode 100644 index 0000000..5b18aff --- /dev/null +++ b/Modules/ado/plus/s/spex.ado @@ -0,0 +1,234 @@ +* spex - version 1.3.1 - fix rologit case2alt bug 25Oct2005 +* spex - version 1.3.0 - add asmprobit 08Sep2005 +* spex - version 1.2.10 - case2alt modification 11Jul2005 +* spex - version 1.2.9 - case2alt 11jul2005 +* spex - version 1.2.8 - change directory for spex_data 11Jul2005 +* spex - version 1.2.7 - revise misschk 06Jul2005 + +capture program drop spex +program define spex + + ** USERS: TO HAVE SPEX SEARCH SOMEWHERE OTHER THAN YOUR WORKING DIRECTORY + ** FOR DATA, ENTER THE PATH IN THE QUOTES BELOW (WINDOWS: USE / AS SEPARATOR) + * local userpath "C:/~ToSync/~Projects/stata/spostdata/" // example + + local userpath "" + + syntax namelist(id="dataset or command") [, Web User Jsl *] + + tokenize "`namelist'" + + * unabbreviate command + capture _optname , `1' + local cmddta = r(opt) + + if "`cmddta'"=="." { + local cmddta = "`1'" + } + + local default = "web" +*local default = "jsl" + + ** SET DIRECTORY WHERE DATA IS STORED + + if "`web'" == "web" | /// + ("`jsl'"== "" & "`user'" == "" & "`default'" == "web") { + +* local where "http://www.stata-press.com/data/lfr/" + + local where "http://www.indiana.edu/~jslsoc/stata/spex_data/" + + } + + if "`user'" == "user" | /// + ("`jsl'"== "" & "`web'" == "" & "`default'" == "user") { + + local where "`userpath'" + + } + + if "`jsl'" == "jsl" | /// + ("`user'"== "" & "`web'" == "" & "`default'" == "jsl") { + + local where "c:\spostdata/" + + } + + ** SPECIFY SYNTAX OF MODEL IF MODEL IS SPECIFIED + + if "`cmddta'" == "asmprobit" { + local data travel2 + local cmd "asmprobit choice time invc, case(id) alternatives(mode) `options'" + } + + if "`cmddta'" == "clogit" { + local data travel2 + local cmd "clogit choice train bus time invc, group(id) `options'" + } + + if "`cmddta'" == "cloglog" { + local data binlfp2 + local cmd "cloglog lfp k5 k618 age wc hc lwg inc, `options'" + } + + if "`cmddta'" == "cnreg" { + local data nels_censored2 + local cmd "cnreg testscor bymomed bydaded black hispanic, censored(censor) `options'" + } + + if "`cmddta'" == "intreg" { + local data nels_censored2 + local cmd "intreg minscor maxscor bymomed bydaded black hispanic, `options'" + } + + if "`cmddta'" == "logit" { + local data binlfp2 + local cmd "logit lfp k5 k618 age wc hc lwg inc, `options'" + } + + if "`cmddta'" == "misschk" { + local data gsskidvalue2 + *local cmd "misschk year-income91, help" + local cmd /// + "misschk age anykids black degree female kidvalue othrrace year income91 income, help gen(m_) dummy" + } + + if "`cmddta'" == "mlogit" { + local data nomocc2 + local cmd "mlogit occ white ed exper, `options'" + } + + if "`cmddta'" == "mprobit" { + local data nomocc2 + local cmd "mprobit occ white ed exper, `options'" + } + + if "`cmddta'" == "nbreg" { + local data couart2 + local cmd "nbreg art fem mar kid5 phd ment, `options'" + } + + if "`cmddta'" == "ologit" { + local data ordwarm2 + local cmd "ologit warm yr89 male white age ed prst, `options'" + } + + if "`cmddta'" == "oprobit" { + local data ordwarm2 + local cmd "oprobit warm yr89 male white age ed prst, `options'" + } + + if "`cmddta'" == "poisson" { + local data couart2 + local cmd "poisson art fem mar kid5 phd ment, `options'" + } + + if "`cmddta'" == "probit" { + local data binlfp2 + local cmd "probit lfp k5 k618 age wc hc lwg inc, `options'" + } + + if "`cmddta'" == "regress" | "`cmddta'" == "reg" { + local data regjob2 + local cmd "regress job fem phd ment fel art cit, `options'" + } + + if "`cmddta'" == "rologit" { + local data wlsrnk + local precmd1 `"label variable value1 "est""' + local precmd2 `"label variable value2 "var""' + local precmd3 `"label variable value3 "aut""' + local precmd4 `"label variable value4 "sec""' + local precmd5 "case2alt, yrank(value) case(id) alt(hashi haslo) casevars(fem hn) gen(rank)" + local cmd "rologit rank est* var* aut* hashi haslo, group(id) reverse" + } + + if "`cmddta'" == "slogit" { + local data ordwarm2 + local cmd "slogit warm yr89 male white age ed prst, `options'" + } + + if "`cmddta'" == "tobit" { + local data tobjob2 + local cmd "tobit jobcen fem phd ment fel art cit, ll(1)" + } + + if "`cmddta'" == "zinb" { + local data couart2 + local cmd "zinb art fem mar kid5 phd ment, inf(fem mar kid5 phd ment) `options'" + } + + if "`cmddta'" == "zip" { + local data couart2 + local cmd "zip art fem mar kid5 phd ment, inf(fem mar kid5 phd ment) `options'" + } + + if "`cmddta'" == "ztnb" { + local data couart2 + local cmd "ztnb art fem mar kid5 phd ment if art > 0, `options'" + } + + if "`cmddta'" == "ztp" { + local data couart2 + local cmd "ztp art fem mar kid5 phd ment if art > 0, `options'" + } + + if "`cmd'" == "" { + local data "`cmddta'" + } + + ** LOAD DATAFILE + + di _n in white `". use "`where'`data'.dta", clear"' + capture use "`where'`data'", clear + + if _rc != 0 { + di _n in green "(trying alternate location for file)" + di _n in white `". sysuse "`data'.dta", clear"' + capture sysuse `data'.dta, clear + if _rc != 0 { + di as err `"program cannot confirm dta file `data' on path `where'"' + error 999 + } + } + + ** EXECUTE COMMAND + + * are there commands to be executed before the command? + local i = 1 + while `"`precmd`i''"' != "" { + di in white `". `precmd`i''"' + `precmd`i'' + local i = `i' + 1 + } + + if "`cmd'" != "" { + + if substr("`cmd'", -2, .) == ", " { + local trim = length("`cmd'") - 2 + local cmd = substr("`cmd'", 1, `trim') + } + + di _n in white ". `cmd'" + `cmd' + } + +end + +capture program drop _optname +program define _optname, rclass + + version 8 + + syntax , [BINlfp2 ORDwarm2 REGress LOGit MLOGit OLOGit NOMocc2] + + foreach d in binlfp2 ordwarm2 regress logit /// + mlogit ologit nomocc2 { + if "``d''"=="`d'" { + local opt = "`d'" + } + } + return local opt "`opt'" + +end + diff --git a/Modules/ado/plus/s/spex.hlp b/Modules/ado/plus/s/spex.hlp new file mode 100644 index 0000000..6ea18d3 --- /dev/null +++ b/Modules/ado/plus/s/spex.hlp @@ -0,0 +1,41 @@ +{smcl} +{* 8Jun2005} +{hline} +help for {hi:spex}{right:(part of {hi:spost})} +{hline} + +{p 4 4 2} +{title:Load example files and run example models} + +{p 4 12 2}{cmd:spex} [{it:modelname}] [{it:filename}] [{cmd:,} {cmdab:w:eb} {cmdab:u:ser}] + +{title:Description} + +{p 4 4 2} +{cmd:spex} allows users to easily use example files and models from +Long and Freese's {it: Regression Models for Categorical Dependent Variables} +{it: Using Stata}. Typing {cmd:spex} {it:filename} will load the specified +example dataset, while typing {cmd:spex} {it:modelname} will estimate that +model using data and an example specification from the book. + +{title:Options} + +{p 4 8 2}{cmd:web} indicates that the data are to be accessed from their location +on the spost website (http://www.indiana.edu/~jslsoc/spostdata/). This is +the default. + +{p 4 8 2}{cmd:user} indicates that the data are to be accessed from the working directory +or somewhere else along the user's adopath (somewhere accessible +via {cmd:sysuse}). + +{title:Notes} + +{p 4 4 2}When specifying an estimation command with spex, you can add other +options (e.g., "nolog") and these will be passed along as additional options +to the estimation command. + +{title:Authors} + + Jeremy Freese and J. Scott Long + www.indiana.edu/~jslsoc/spost.htm + spostsup@indiana.edu diff --git a/Modules/ado/plus/s/spost.hlp b/Modules/ado/plus/s/spost.hlp new file mode 100644 index 0000000..01701c9 --- /dev/null +++ b/Modules/ado/plus/s/spost.hlp @@ -0,0 +1,29 @@ +{smcl} +{* 26Jun2006}{...} +{cmd:help spost} +{hline} + +{title:SPost commands} + +{space 2}{help asprvalue}{col 15}{lalign 25: predictions for alternative specific models} +{space 2}{help brant}{col 15}{lalign 25: Brant test of proportional odds} +{space 2}{help case2alt}{col 15}{lalign 25: 1 obs per row to 1 alternative per row} +{space 2}{help countfit}{col 15}{lalign 25: assess fit in count models} +{space 2}{help fitstat}{col 15}{lalign 25: compute fit statistics} +{space 2}{help leastlikely}{col 15}{lalign 25: find least likely predictions} +{space 2}{help listcoef}{col 15}{lalign 25: list estimated coefficients} +{space 2}{help misschk}{col 15}{lalign 25: examine patterns of missing data} +{space 2}{help mlogplot}{col 15}{lalign 25: plot results from mlogit} +{space 2}{help mlogtest}{col 15}{lalign 25: tests for mlogit} +{space 2}{help mlogview}{col 15}{lalign 25: dialog box for mlogplot} +{space 2}{help praccum}{col 15}{lalign 25: accumulate predictions to plot} +{space 2}{help prchange}{col 15}{lalign 25: compute discrete change coefficients} +{space 2}{help prcounts}{col 15}{lalign 25: compute predictions for count models} +{space 2}{help prgen}{col 15}{lalign 25: create predictions and CIs for plotting} +{space 2}{help prtab}{col 15}{lalign 25: tables of predictions} +{space 2}{help prvalue}{col 15}{lalign 25: predictions with CIs} +{space 2}{help spex}{col 15}{lalign 25: run SPost examples or load SPost data} + +{space 2}{help spost_auxillary}{col 15}{lalign 25: help on auxillary commands for SPost} + +{hline} diff --git a/Modules/ado/plus/s/spost_footer.ihlp b/Modules/ado/plus/s/spost_footer.ihlp new file mode 100644 index 0000000..6b00b8a --- /dev/null +++ b/Modules/ado/plus/s/spost_footer.ihlp @@ -0,0 +1,15 @@ +{* 20Oct2009} + +{title:Authors} + +{p 4 2 0} +If you use SPost, please cite: + +{p 4 4 0} +J. Scott Long and Jeremy Freese (2005) +{it:Regression Models for Categorical Outcomes Using Stata. Second Edition.} College Station, TX: Stata Press. + +{p 4 2 0} +{browse "http://www.indiana.edu/~jslsoc/web_spost/sp_help.htm":For help, check here.} +{browse "http://www.indiana.edu/~jslsoc/spost.htm":For futher information, see the SPost website.} +{p_end} diff --git a/Modules/ado/plus/s/spostupdate.ado b/Modules/ado/plus/s/spostupdate.ado new file mode 100644 index 0000000..56d2449 --- /dev/null +++ b/Modules/ado/plus/s/spostupdate.ado @@ -0,0 +1,7 @@ +// Uninstall and re-install spost9_ado + +program define spostupdate + capture ado uninstall spost9_ado + net from http://www.indiana.edu/~jslsoc/stata/ + net install spost9_ado +end diff --git a/Modules/ado/plus/s/sublist.ado b/Modules/ado/plus/s/sublist.ado new file mode 100644 index 0000000..fcdc255 --- /dev/null +++ b/Modules/ado/plus/s/sublist.ado @@ -0,0 +1,44 @@ +program def sublist, rclass +*! NJC 1.3.0 7 June 2000 +* NJC 1.2.0 31 Jan 2000 +* NJC 1.1.0 22 Dec 1999 +* NJC 1.0.0 12 November 1999 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax , From(str) [ To(str) ALL Noisily Global(str)] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tokenize `list' + + local nwords : word count `list' + local i = 1 + while `i' <= `nwords' { + local len = length("``i''") + if `len' > 80 { + di in r "cannot handle word length > 80" + exit 498 + } + local i = `i' + 1 + } + + while "`1'" != "" { + if index("`1'", "`from'") { + local 1 : subinstr local 1 "`from'" "`to'", `all' + } + local newlist "`newlist'`1' " + mac shift + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/s/sublist.hlp b/Modules/ado/plus/s/sublist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/s/sublist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/s/sumlist.ado b/Modules/ado/plus/s/sumlist.ado new file mode 100644 index 0000000..0c4a2d5 --- /dev/null +++ b/Modules/ado/plus/s/sumlist.ado @@ -0,0 +1,36 @@ +program def sumlist, rclass +*! NJC 1.0.0 9 April 2001 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "no list specified" + exit 198 + } + + numlist "`list'" + local list `r(numlist)' + local nw : word count `list' + + syntax [ , Global(str) Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tempname sum + scalar `sum' = 0 + tokenize `list' + + local i = 1 + while `i' <= `nw' { + scalar `sum' = (`sum') + (``i'') + local i = `i' + 1 + } + + if "`noisily'" != "" { di `sum' } + if "`global'" != "" { global `global' = `sum' } + return scalar sum = `sum' +end + + diff --git a/Modules/ado/plus/s/sumlist.hlp b/Modules/ado/plus/s/sumlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/s/sumlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/stata.trk b/Modules/ado/plus/stata.trk new file mode 100644 index 0000000..6585f07 --- /dev/null +++ b/Modules/ado/plus/stata.trk @@ -0,0 +1,1420 @@ +* 00000058 +*! version 1.0.0 +* Do not erase or edit this file +* It is used by Stata to track the ado and help +* files you have installed. + +S http://www.unc.edu/~skolenik/stata +N polychoric.pkg +D 15 Dec 2006 +U 1 +d polychoric -- The polychoric correlation package +d +d Author: Stas Kolenikov, skolenik@unc.edu +d +d This package provides routines to estimate +d the polychoric, tetrachoric, polyserial and biserial +d correlations and use them in principal component analysis. +d Current version: 1.4 +f p\polychoric.ado +f p\polychoricpca.ado +f p\polych_ll.ado +f p\polyser_ll.ado +f p\polychoric.hlp +f p\polychoricpca.hlp +e +S http://www.stata.com/stb/stb61 +N sg158_1.pkg +D 5 Mar 2007 +U 3 +d STB-61 sg158_1. Update to random-effects ordered probit +d STB insert by Guillaume R. Frechette, Ohio State University +d Support: gurst1@@econ.ohio-state.edu +d After installation, see help ^reoprob^ +f g\ghquadm.ado +f g\ghquadm.hlp +f r\reop_ll.ado +f r\reopc_ll.ado +f r\reoprob.ado +f r\reoprob.hlp +f r\rfpr_ll1.ado +f r\rfprobit.ado +f r\rfprobit.hlp +e +S http://www.stata-journal.com/software/sj5-4 +N st0067_2.pkg +D 5 Jun 2007 +U 4 +d SJ5-4 st0067_2. Update: Multiple imputation of missing... +d Update: Multiple imputation of missing values +d by Patrick Royston, MRC Clinical Trials Unit, London, UK +d Support: patrick.royston@@ctu.mrc.ac.uk +d After installation, type help ^ice^, ^micombine^, and ^mijoin^ +f i\ice.ado +f i\ice.hlp +f m\micombine.ado +f m\micombine.hlp +f m\mijoin.ado +f m\mijoin.hlp +f m\misplit.ado +f m\misplit.hlp +f u\uvis.ado +f u\uvis.hlp +f c\cmdchk.ado +e +S http://fmwww.bc.edu/repec/bocode/m +N metaninf.pkg +D 10 Jan 2008 +U 7 +d 'METANINF': module to evaluate influence of a single study in meta-analysis estimation +d +d metaninf investigates the influence of each individual study on +d the overall meta-analysis summary estimate. The command presents +d a table and a graph of the results of an influence analysis in +d which the meta-analysis is reestimated omitting each study in +d turn. metaninf is a parallel program to metainf (Aurelio Tobias; +d STB-47: sbe26; STB-56: sbe26.1) that uses metan (rather than +d meta) as its calculation engine, thus allowing access to the +d additional meta-analytic models offered therein. metaninf also +d differs from metainf in that metaninf uses metan's syntax and a +d subset of its options (rather than those of meta). Program mhplot +d (a variation of Nicholas Cox's hplot) is a required support +d program. This version (1.0.2) allows the jackknifed estimates to +d be saved. A Stata 8 dialog is included. +d +d Distribution-Date: 20010619 +d +d Author: Thomas Steichen +d Support: email steichen@@triad.rr.com +d +f m\metaninf.ado +f m\metaninf.hlp +f m\mhplot.ado +f m\metaninf.dlg +e +S http://fmwww.bc.edu/repec/bocode/m +N metafunnel.pkg +D 2 Apr 2008 +U 8 +d 'METAFUNNEL': module to produce funnel plots for meta-analysis +d +d metafunnel plots funnel plots. These graphical displays are +d used to examine whether the results of a meta-analysis may have +d been affected by publication or other types of bias. +d +d Distribution-Date: 20030827 +d +d Author: Jonathan Sterne, University of Bristol +d Support: email jonathan.sterne@@bristol.ac.uk +d +f m\metafunnel.ado +f m\metafunnel.hlp +f m\metafunnel.dlg +e +S http://fmwww.bc.edu/repec/bocode/m +N metabias.pkg +D 2 Apr 2008 +U 9 +d 'METABIAS': module to test for publication bias in meta-analysis +d +d metabias performs the Begg and Mazumdar adjusted rank correlation +d test for publication bias and performs the Egger et al. +d regression asymmetry test for publication bias. As options, it +d provides a funnel graph of the data or the regression asymmetry +d plot. This is version 1.2.4 of the software. This version has +d been modified to run correctly under Stata Version 7 and later +d (though it remains a version 6 program) and fixes a bug in the +d stratified Egger p-value. +d +d Author: Thomas Steichen +d Support: email steichen@@triad.rr.com +d +d Distribution-Date: 20040409 +f m\metabias.ado +f m\metabias.hlp +f m\metabias.dlg +e +S http://www.stata.com/stb/stb56 +N sbe20_1.pkg +D 2 Apr 2008 +U 10 +d STB-56 sbe20_1. Update of galbr +d STB insert by Aurelio Tobias, Universidad Miguel Hernandez +d Alicante, Spain +d Support: bledatobias@@ctv.es +d After installation, see help ^galbr^ +f g\galbr.ado +f g\galbr.hlp +e +S http://fmwww.bc.edu/repec/bocode/l +N loevh.pkg +D 6 Nov 2008 +U 11 +d 'LOEVH': module to compute Guttman errors and Loevinger H coefficients +d +d LoevH computes the Loevinger H coefficients and the Guttman +d errors (observed and expected) for each pair of items, between +d one given item and all the others of a scale or among all the +d possible pairs of items of a scale. +d +d KW: Loevinger H coefficients +d KW: Guttman errors +d KW: scale validation +d +d Requires: Stata version 7 +d +d Distribution-Date: 20070621 +d +d Author: Jean-Benoit Hardouin, University of Nantes, France +d Support: email jean-benoit.hardouin@@univ-nantes.fr +d +f l\loevh.ado +f l\loevh.hlp +f a\anaoption.ado +f t\traces.ado +f t\traces.hlp +f g\gengroup.ado +f g\gengroup.hlp +e +S http://fmwww.bc.edu/repec/bocode/d +N delta.pkg +D 24 Nov 2008 +U 13 +d 'DELTA': module to compute the Delta index of scale discrimination +d +d delta computes the generalized delta index of scale +d discrimination developed by Hankins (2007) based on the original +d work of Ferguson (1949). This index measures the scale's +d ability to distinguish between individuals. A value of 1 +d indicates that the test has maximal discrimination (all +d possible scores occur with the same frequency) and a value of 0 +d means that the test has minimal discrimination (all the +d respondents have the same score). A value of 0.9 results from a +d set of scores that is normally distributed. A value of 1 is +d observed if the scores follow a uniform distribution. Individuals +d with a missing score are omitted. +d +d KW: delta index +d KW: psychometrics +d KW: Cronbach alpha +d KW: discrimination +d +d Requires: Stata version 7 +d +d Distribution-Date: 20080312 +d +d Author: Jean-Benoit Hardouin , University of Nantes, France +d Support: email jean-benoit.hardouin@@univ-nantes.fr +d +f d\delta.ado +f d\delta.hlp +e +S http://fmwww.bc.edu/repec/bocode/m +N metan.pkg +D 3 Dec 2008 +U 15 +d 'METAN': module for fixed and random effects meta-analysis +d +d These routines provide facilities to conduct meta-analyses of +d data from more than one study and to graph the results. Either +d binary (event) or continuous data from two groups may be combined +d using the metan command. Additionally, intervention effect +d estimates with corresponding standard errors or confidence +d intervals may be meta-analysed. Recently added facilities include +d by() processing and an update to Stata 9 graphics. This is an +d updated version of metan as published in STB-44, authored by +d Michael J Bradburn, Jonathan J Deeks, Douglas G Altman. The +d package includes a command to produce funnel plots to assess +d small study effects, and L'Abbe plots to examine whether the +d assumption of a common odds ratio, risk ratio or risk difference +d is reasonable. Also included is the metannt program for binary +d data, which displays estimated intervention effects in terms of +d the absolute reduction in risk and number needed to treat. A +d description of available Stata meta-analysis commands may be +d found at http://www.stata.com/support/faqs/stat/meta.html. +d +d KW: meta-analysis +d KW: fixed effects +d KW: random effects +d KW: forest plot +d KW: l'Abbe plot +d +d Requires: Stata version 9 (version 7 for metan7) +d +d Distribution-Date: 20081117 +d +d Author: Ross Harris, Department of Social Medicine, University of Bristol +d Support: email ross.harris@@bristol.ac.uk +d +d Author: Mike Bradburn, Centre for Statistics in Medicine, University of Oxford +d Support: email +d +d Author: Jon Deeks, Centre for Statistics in Medicine, University of Oxford +d Support: email +d +d Author: Roger Harbord, Department of Social Medicine, University of Bristol +d Support: email +d +d Author: Doug Altman, Centre for Statistics in Medicine, University of Oxford +d Support: email +d +d Author: Thomas Steichen, RJRT +d Support: email +d +d Author: Jonathan Sterne, Department of Social Medicine, University of Bristol +d Support: email +d +f m\metan.ado +f m\metan.hlp +f l\labbe.ado +f l\labbe.hlp +f l\labbe.dlg +f m\metan7.ado +f m\metan7.hlp +f m\metan7.dlg +f m\metannt.ado +f m\metannt.hlp +f m\metannt.dlg +f i\i2ci.ado +f m\metan_examples.ado +e +S http://fmwww.bc.edu/repec/bocode/m +N msp.pkg +D 11 Dec 2008 +U 16 +d 'MSP': module to perform the Mokken Scale Procedure +d +d MSP implements the Mokken Scale Procedure defined by Hemker, +d Sijtsma and Molenaar (1995). This procedure construct sub-scales +d based on Loevinger H coefficients computed by LoevH (q.v.). The +d results depend of a threshold "c" fixed by the user : the +d authors of the procedure recommend to use a c exceeding 0.3. The +d kernel of the first sub-scale can be fixed. +d +d KW: Mokken Scale Procedure +d KW: MSP +d KW: Loevinger H coefficients +d KW: scale construction +d +d Requires: Stata version 7 +d +d Distribution-Date: 20081108 +d +d Author: Jean-Benoit Hardouin, University of Nantes, France +d Support: email jean-benoit.hardouin@@univ-nantes.fr +d +f m\msp.ado +f m\msp.hlp +f l\loevh.ado +f l\loevh.hlp +e +S http://fmwww.bc.edu/repec/bocode/c +N clv.pkg +D 11 Dec 2008 +U 17 +d 'CLV': module to implement a clustering of variables around latent components +d +d clv clusters variables around latent components. The variables +d are clustered by searching to minimize at each step the +d decreasing of the T criterion computed as the sum of the first +d eigenvalues of the matrices of data of all the clusters. A +d hierarchical cluster analysis based on this criterion is +d realized. A consolidation procedure can be run in a second time, +d which allows assigning each variable to the more correlated +d latent components. The procedure is described by Vigneau and +d Qannari (Communications in Statistics - Simulation and +d Computation, 2003). +d +d KW: Clustering around latent components +d KW: Varclus +d KW: CLV +d KW: unidimensionality +d +d Requires: Stata version 8.0 +d +d Distribution-Date: 20061014 +d +d Author: Jean-Benoit Hardouin , University of Nantes, France +d Support: email jean-benoit.hardouin@@univ-nantes.fr +d +f c\clv.ado +f c\clv.hlp +e +S http://fmwww.bc.edu/repec/bocode/s +N simirt.pkg +D 11 Dec 2008 +U 18 +d 'SIMIRT': module to process data generated by IRT models +d +d simirt allows creating a new dataset of responses to items +d simulated by an unidimensional IRT model. The model can be +d dichotomous (Rasch, OPLM, Birnbaum, 3PLM, 4PLM, 5PAM) or +d polytomous (Rating Scale Model-RSM). It is possible to simulate +d two sets of items linked, for each of them, to a specific latent +d trait (which can be correlated). The Items Characteristic Curves +d can be drawn. +d +d KW: simulation +d KW: Rasch model +d KW: Birnbaum model +d KW: OPLM +d KW: ICC +d KW: Rating Scale Model +d +d Requires: Stata version 8 +d +d Distribution-Date: 20061022 +d +d Author: Jean-Benoit Hardouin, University of Nantes, France +d Support: email jean-benoit.hardouin@@univ-nantes.fr +d +f s\simirt.ado +f s\simirt.hlp +e +S http://fmwww.bc.edu/repec/bocode/e +N elapse.pkg +D 11 Dec 2008 +U 19 +d 'ELAPSE': module to calculate elapsed time in procedure +d +d Elapse displays a string with the name of the operation, if +d specified, and the time elapsed between start_time and current +d time. +d +d Author: Fred Zimmerman, Stanford University +d Support: email zimmer@@leland.Stanford.EDU +d +d Distribution-Date: 20031221 +f e\elapse.ado +f e\elapse.hlp +e +S http://fmwww.bc.edu/RePEc/bocode/i +N iccconf.pkg +D 5 Feb 2009 +U 20 +d 'ICCCONF': module to compute a confidence interval for an intraclass correlation (ICC) +d +d iccconf is an immediate command that computes a confidence +d interval for a single intraclass correlation (ICC). The +d procedure is based on Rosner's approach using the F-test. +d +d KW: intra-class correlation +d KW: confidence interval +d +d Requires: Stata version 8 +d +d Distribution-Date: 20081119 +d +d Author: Paul F. Visintainer, Baystate Health System +d Support: email visint46@@gmail.com +d +f i\iccconf.ado +f i\iccconf.hlp +e +S http://www.stata-journal.com/software/sj4-2 +N pr0012.pkg +D 24 Feb 2009 +U 22 +d SJ4-2 pr0012. Submenu and dialogs for meta-analysis commands +d Submenu and dialogs for meta-analysis commands +d by Thomas J. Steichen +d Support: steichen@@triad.rr.com +d After installation, type help ^meta_dialog^ +f m\meta_dialog.hlp +f f\funnel.dlg +f g\galbr.dlg +f l\labbe.dlg +f m\metabias.dlg +f m\metacum.dlg +f m\meta.dlg +f m\metafunnel.dlg +f m\metainf.dlg +f m\metan.dlg +f m\metaninf.dlg +f m\metannt.dlg +f m\metap.dlg +f m\metareg.dlg +f m\metatrim.dlg +e +S http://www.stata-journal.com/software/sj8-4 +N sbe23_1.pkg +D 24 Feb 2009 +U 23 +d SJ8-4 sbe23_1. Update: Meta-regression in Stata (revised) +d Update: Meta-regression in Stata (revised) +d by Roger Harbord, Department of Social Medicine, +d University of Bristol, UK +d Julian Higgins, MRC Biostatistics Unit, Cambridge, UK +d Support: roger.harbord@@bristol.ac.uk +d After installation, type help ^metareg^ +f m\metareg.ado +f m\metareg_ll.ado +f m\metareg_p.ado +f m\metareg_pm.ado +f m\metareg.hlp +e +S http://web.missouri.edu/~kolenikovs/stata +N cfa1.pkg +D 20 Mar 2009 +U 24 +d cfa1 -- a single factor confirmatory analysis model +d +d Author: Stas Kolenikov, kolenikovs@missouri.edu +d +d cfa1 fits the confirmatory analysis model by maximum likelihood. +d The model is restricted to a single level single factor. +f c\cfa1.ado +f c\cfa1_lf.ado +f c\cfa1.hlp +e +S http://fmwww.bc.edu/repec/bocode/i +N icc23.pkg +D 26 Mar 2009 +U 25 +d 'ICC23': module that computes models 2 and 3 of the intra-class correlation +d +d ICC23 computes the intra-class correlation for random effects +d models 2 and 3, as described by Shrout and Fleiss, 1979. +d (-loneway- computes model 1). The module uses Stata’s repeated +d measures ANOVA command to retrieve the appropriate estimates and +d degrees of freedom. Keywords: intra-class correlation, random +d effects model, mixed effects model +d +d +d Requires: Stata version 9 +d +d Distribution-Date: 20090325 +d +d Author: Paul F. Visintainer, Baystate Health System +d Support: email visint46@@gmail.com +d +d Author: Luis C.Orozco, Facultad de Salud, Universidad Industrial de Santander, Colombia +d Support: email lcorovar@@gmail.com +d +f i\icc23.ado +f i\icc23.hlp +e +S http://www.stata.com/stb/stb35 +N sg65.pkg +D 26 Mar 2009 +U 26 +d STB-35 sg65. Computing intraclass correlations and large ANOVAs. +d STB insert by John R. Gleason, Syracuse University. +d Support: 73241.717@@compuserve.com +d After installation, see help ^l1way^ and help ^iclassr2^. +f i\iclassr.ado +f i\iclassr.hlp +f i\iclassr2.ado +f i\iclassr2.hlp +f l\l1way.ado +f l\l1way.hlp +e +S http://www.stata.com/stb/stb56 +N sbe26_1.pkg +D 20 Apr 2009 +U 27 +d STB-56 sbe26_1. Update of metainf +d STB insert by Aurelio Tobias, Universidad Miguel Hernandez +d Alicante, Spain +d Support: bledatobias@@ctv.es +d After installation, see help ^metainf^ +f h\hplot.ado +f h\hplot.hlp +f m\metainf.ado +f m\metainf.hlp +e +S http://www.stata.com/stb/stb61 +N sbe19_4.pkg +D 20 Apr 2009 +U 28 +d STB-61 sbe19_4. Update to metabias to work under version 7 +d STB insert by Thomas J. Steichen, RJRT +d Support: steicht@@rjrt.com +d After installation, see help ^metabias^ +f m\metabias.ado +f m\metabias.hlp +e +S http://fmwww.bc.edu/repec/bocode/i +N imputeitems.pkg +D 5 May 2009 +U 29 +d 'IMPUTEITEMS': module to impute missing data of binary items +d +d imputeitems imputes missing responses to binary items by +d different ways: Item Mean Substitution (IMS), Person Mean +d Substitution (PMS), Corrected Item Mean Substiutution (CIM), +d Interitem Correlation Substitution (ICS), logistic model (LOG) +d and Worst Case (WORST). +d +d KW: Item Response Theory +d KW: Missing data +d KW: Imputation +d +d Requires: Stata version 9.0 +d +d Distribution-Date: 20081211 +d +d Author: Jean-Benoit Hardouin, University of Nantes, France +d Support: email jean-benoit.hardouin@@univ-nantes.fr +d +f i\imputeitems.ado +f i\imputeitems.hlp +e +S http://fmwww.bc.edu/repec/bocode/x +N xsampsi.pkg +D 16 Jul 2009 +U 30 +d 'XSAMPSI': module to calculate sample size for cross-over trials with continuous measures +d +d This program will compute the required sample size for a simple +d crossover trial, that is AB/BA, or two-period two-treatment +d cross-over. It will estimate the power for a given sample size, +d too. +d +d Author: Jan Brogger, University of Bergen, Norway +d Support: email jan.brogger@@med.uib.no +d +d Distribution-Date: 20020131 +f x\xsampsi.ado +f x\xsampsi.hlp +e +S http://fmwww.bc.edu/repec/bocode/n +N nct.pkg +D 17 Jul 2009 +U 31 +d 'NCT': modules related to the noncentral t distribution +d +d nct is a package of programs, all related to the noncentral t +d distribution. Each one-sided program computes a missing +d parameter given the other parameters such that P(t<=t'| delta, +d df) = p. The two-sided programs yield two-sided values from a +d noncentral t, defined such that P(|t|<=t'| delta, df) = 1 - p. +d The programs are: nctprob -- Cumulative non-central t +d probabilities, p, nctinv -- Inverse cumulative non-central t +d values, t', nctncp -- Noncentrality parameter of the non-central +d t, delta, nctn -- Sample size for the cumulative non-central +d t, df + 1, nct2 -- 2-sided non-central t probabilities, p, +d and nct2inv -- Inverse 2-sided non-central t values, |t'|. +d +d Author: Thomas Steichen +d Support: email steichen@@triad.rr.com +d +d Distribution-Date: 20000609 +f n\nct.ado +f n\nct.hlp +f n\nct2.ado +f n\nct2.hlp +f n\nct2inv.ado +f n\nct2inv.hlp +f n\nctinv.ado +f n\nctinv.hlp +f n\nctn.ado +f n\nctn.hlp +f n\nctncp.ado +f n\nctncp.hlp +f n\nctprob.ado +f n\nctprob.hlp +e +S http://fmwww.bc.edu/repec/bocode/t +N torumm.pkg +D 20 Jul 2009 +U 32 +d 'TORUMM': module to produce data in RUMM format +d +d torumm converts and formats Stata data into 3 files required to +d run RUMM 2010. RUMM 2010 (Rasch Unidimensional Measurement +d Models) is program for Rasch analysis. torumm will work with +d Stata 6 and Stata 7 data. +d +d Author: Fred Wolfe +d Support: email fwolfe@@arthritis-research.org +d +d Distribution-Date: 20000708 +f t\torumm.ado +f t\torumm.hlp +e +S http://www.fss.uu.nl/soc/iscore/stata +N dropvars.pkg +D 20 Jul 2009 +U 33 +d ^dropvars^. drops all existing variables in a list. +d ^dropvars varlist^ is similar to ^drop varlist^, but warns if a +d variable does not exists, rather than aborts. +d +d Note that ^capture drop varlist^ either drops all variables or none. +d +d ^dropvars varlist^ is equivalent to +d +d for var varlist: capture drop X +d +d Author: Jeroen Weesie, Dept of Sociology, Utrecht University (NL) +d Support: email J.Weesie@@fss.uu.nl +f d\dropvars.ado +f d\dropvars.hlp +e +S http://fmwww.bc.edu/RePEc/bocode/l +N listutil.pkg +D 20 Jul 2009 +U 34 +d 'LISTUTIL': modules to manipulate lists of words +d +d These functions manipulate lists of words. For details, see the +d help file. +d +d Author: Nicholas J. Cox, University of Durham +d Support: email N.J.Cox@@durham.ac.uk +d +d Distribution-Date: 20010523 +f a\alphlist.ado +f a\alphlist.hlp +f b\binolist.ado +f b\binolist.hlp +f b\bothlist.ado +f b\bothlist.hlp +f c\choplist.ado +f c\choplist.hlp +f c\collist.ado +f c\collist.hlp +f c\convlist.ado +f c\convlist.hlp +f c\cseplist.ado +f c\cseplist.hlp +f c\cvarlist.ado +f c\cvarlist.hlp +f d\dellist.ado +f d\dellist.hlp +f d\difflist.ado +f d\difflist.hlp +f e\eqlist.ado +f e\eqlist.hlp +f f\fmtlist.ado +f f\fmtlist.hlp +f i\inslist.ado +f i\inslist.hlp +f j\joinlist.ado +f j\joinlist.hlp +f l\lclist.ado +f l\lclist.hlp +f m\maplist.ado +f m\maplist.hlp +f m\mnthlist.ado +f m\mnthlist.hlp +f p\poslist.ado +f p\poslist.hlp +f p\postlist.ado +f p\postlist.hlp +f p\prelist.ado +f p\prelist.hlp +f p\prodlist.ado +f p\prodlist.hlp +f r\replist.ado +f r\replist.hlp +f r\revlist.ado +f r\revlist.hlp +f r\rotlist.ado +f r\rotlist.hlp +f s\sellist.ado +f s\sellist.hlp +f s\seqlist.ado +f s\seqlist.hlp +f s\sortlist.ado +f s\sortlist.hlp +f s\sublist.ado +f s\sublist.hlp +f s\sumlist.ado +f s\sumlist.hlp +f t\takelist.ado +f t\takelist.hlp +f t\trnclist.ado +f t\trnclist.hlp +f u\uclist.ado +f u\uclist.hlp +f u\uniqlist.ado +f u\uniqlist.hlp +f v\varflist.ado +f v\varflist.hlp +f v\vectlist.ado +f v\vectlist.hlp +f w\wclist.ado +f w\wclist.hlp +f x\xorlist.ado +f x\xorlist.hlp +f l\listutil.hlp +e +S http://www.fss.uu.nl/soc/iscore/stata +N listblck.pkg +D 20 Jul 2009 +U 35 +d ^listblck^. variant of ^list^ that "wraps variables". +d ^listblck^ is that wraps variables, not observations. Thus, ^listblck^ +d displays as many variables as fit on the screen (listblck is ^display^ +d ^linesize^ sensitive) for all selected obs, then it displays a second +d block of variables etc. This is especially useful if the number of +d observations to be listed is small. See ^listby^ as an application. +d +d Author: Jeroen Weesie, Dept of Sociology, Utrecht University (NL) +d Support: email J.Weesie@@fss.uu.nl +f l\listblck.ado +f l\listblck.hlp +e +S http://fmwww.bc.edu/repec/bocode/s +N saswrapper.pkg +D 22 Nov 2009 +U 37 +d 'SASWRAPPER': module to run a SAS program from within Stata +d +d saswrapper runs a SAS program in batch and prints the output in +d the Stata results window/log file. This usually occurs by +d specifying a SAS program file after using, but saswrapper can +d also run SAS code specified by the pre_sas_prog() and/or +d post_sas_prog() options. By default, saswrapper will save the +d current data in memory using savasas and make it available in +d SAS's WORK library. If that is not desired, use the nodata +d option. The usesas option tells saswrapper to load the last SAS +d dataset created in the WORK library by the submitted SAS program +d into Stata using the SAVASTATA SAS macro. +d +d KW: SAS +d KW: Stata +d +d Requires: Stata version 8.0 +d +d Distribution-Date: 20090507 +d +d Author: Dan Blanchette, Center of Entrepreneurship and Innovation, Duke University's Fuqua School of Business +d Support: email dan.blanchette@@duke.edu +d +f s\saswrapper.ado +f s\saswrapper.hlp +f u\usesas.ado +f u\usesas.hlp +f s\savasas.ado +f s\savasas.hlp +f u\usesasdel.ado +f s\sasexe.ado +f a\adoedit.ado +f a\adoedit.hlp +f t\tmpdir.ado +f t\tmpdir.hlp +f s\shortdir.ado +f s\shortdir.hlp +f c\confirmdir.ado +f c\confirmdir.hlp +e +S http://www.stata-journal.com/software/sj4-1 +N st0057.pkg +D 26 Nov 2009 +U 38 +d SJ4-1 st0057. FIML estimation of an endogenous switching ... +d FIML estimation of an endogenous switching model for count data +d by Alfonso Miranda, Economics Department, Warwick University, UK +d Support: Alfonso.Miranda-Caso-Luengo@@warwick.ac.uk +d After installation, type help ^espoisson^ +f e\espoisson.ado +f e\espoisson.hlp +f e\espoisson_ll.ado +f e\espoisson_p.ado +f e\exspoisson.ado +f e\exspoisson_ll.ado +f e\exspoisson_p.ado +f g\ghquad.ado +f h\hermite.ado +f x\xcolnames.ado +e +S http://fmwww.bc.edu/repec/bocode/e +N estout.pkg +D 5 Dec 2009 +U 39 +d 'ESTOUT': module to make regression tables +d +d estout produces a table of regression results from one or several +d models for use with spreadsheets, LaTeX, HTML, or a +d word-processor table. eststo stores a quick copy of the active +d estimation results for later tabulation. esttab is a wrapper for +d estout. It displays a pretty looking publication-style regression +d table without much typing. estadd adds additional results to the +d e()-returns for one or several models previously fitted and +d stored. This package subsumes the previously circulated esto, +d esta, estadd, and estadd_plus. An earlier version of estout is +d available as estout1. +d +d KW: estimates +d KW: LaTeX +d KW: HTML +d KW: word processor +d KW: output +d +d Requires: Stata version 8.2 +d +d Distribution-Date: 20091012 +d +d Author: Ben Jann, ETH Zurich +d Support: email ben.jann@@soz.gess.ethz.ch +d +f _\_eststo.ado +f _\_eststo.hlp +f e\estadd.ado +f e\estadd.hlp +f e\estout.ado +f e\estout.hlp +f e\eststo.ado +f e\eststo.hlp +f e\estpost.ado +f e\estpost.hlp +f e\esttab.ado +f e\esttab.hlp +e +S http://fmwww.bc.edu/repec/bocode/o +N outreg2.pkg +D 5 Dec 2009 +U 40 +d 'OUTREG2': module to arrange regression outputs into an illustrative table +d +d outreg2 provides a fast and easy way to produce an illustrative +d table of regression outputs. The regression outputs are produced +d piecemeal and are difficult to compare without some type of +d rearrangement. outreg2 automates this process by concatenating +d the successive regression ouputs in a vertical format. The +d resulting table is saved to the disk in ASCII format, which can +d be read by other programs. outreg2 thus facilitates the +d convertion of regression outputs to a standard format suitable +d for inclusion in a scholarly publication. The functionality of +d outreg2 is based on the earlier package outreg, by John Luke +d Gallup. Unlike outreg, outreg2 is capable of writing LaTeX-format +d tables, as well as ASCII, MS Word and MS Excel. +d +d KW: regression +d KW: output +d KW: tables +d KW: tab-delimited output +d KW: LaTeX +d KW: Word +d KW: Excel +d +d Requires: Stata version 7 +d +d Distribution-Date: 20091118 +d +d Author: Roy Wada +d Support: email roywada@@hotmail.com +d +f o\outreg2.ado +f o\outreg2_prf.ado +f o\outreg2.hlp +f s\shellout.ado +f s\shellout.hlp +f s\seeout.ado +f s\seeout.hlp +e +S http://fmwww.bc.edu/repec/bocode/r +N raschpower.pkg +D 27 Jan 2010 +U 41 +d 'RASCHPOWER': module to estimate power of the Wald test in order to compare the means of the latent trait in two groups of individuals +d +d raschpower allows estimating the power of the Wald test comparing +d the means of two groups of patients in the context of the Rasch +d model. The estimation is based on the estimation of the variance +d of the difference of the means based on the Cramer-Rao lower +d bound. +d +d KW: Rasch test +d KW: power +d KW: Wald test +d +d Requires: Stata version 11 +d +d Distribution-Date: 20100126 +d +d Author: Jean-Benoit Hardouin , University of Nantes, France +d Support: email jean-benoit.hardouin@@univ-nantes.fr +d +f r\raschpower.ado +f r\raschpower.hlp +e +S http://www.stata-journal.com/production +N sjlatex.pkg +D 24 Feb 2010 +U 42 +d sjlatex: LaTeX files for the Stata Journal +d ^sjlatex^ contains the LaTeX document class and packages for the +d Stata Journal. +d +d The ancillary files should be installed using the ^sjlatex^ command +d from within Stata. +d +d Distribution-Date: 18feb2010 +f s\sjlatex.ado +f s\sjlatex.hlp +f s\sjlog_7.ado +f s\sjlog.ado +f s\sjlog.hlp +e +S http://fmwww.bc.edu/repec/bocode/c +N checkfor2.pkg +D 11 Apr 2010 +U 43 +d 'CHECKFOR2': module to check whether a variable exists or not in a dataset +d +d checkfor2 is a routine to check for existence of a list of +d variables within a (usually big) data set. checkfor2 searchs +d through the data whether the variable exists. +d +d KW: data management +d +d Requires: Stata version 8 +d +d Distribution-Date: 20050926 +d +d Author: Amadou Bassirou Diallo, AFTPM, The World Bank +d Support: email adiallo5@@worldbank.org +d +d Author: Jean-Benoit Hardouin , University of Nantes, France +d Support: email jean-benoit.hardouin@@univ-nantes.fr +d +f c\checkfor2.ado +f c\checkfor2.hlp +f i\isvar.ado +f i\isvar.hlp +e +S http://www.stata.com/stb/stb46 +N gr33.pkg +D 6 May 2010 +U 44 +d STB-46 gr33. Violin plots. +d STB insert by Thomas J. Steichen, RJRT. +d Support: steicht@@rjrt.com +d After installation, see help ^violin^. +f v\violin.ado +f v\violin.hlp +e +S http://www.stata.com/stb/stb47 +N sg103.pkg +D 31 May 2010 +U 45 +d STB-47 sg103. Within subjects (repeated measures) ANOVA, between subj. +d STB insert by John R. Gleason, Syracuse University. +d Support: loeslrg@@ican.net +d After installation, see help ^wsanova^. +f w\wsanova.ado +f w\wsanova.hlp +e +S http://www.stata-journal.com/software/sj9-3 +N st0169.pkg +D 7 Jun 2010 +U 46 +d SJ9-3 st0169. Confirmatory factor analysis +d Confirmatory factor analysis +d by Stanislav Kolenikov, University of Missouri, Columbia, USA +d Support: kolenikovs@@missouri.edu, skolenik@@gmail.com +d After installation, type help ^confa^ +f c\confa.ado +f c\confa.sthlp +f c\confa_lf.ado +f c\confa_lfm.ado +f c\confa.mata +f c\confa_p.ado +f c\confa_estat.ado +f c\confa_estat.sthlp +f b\bollenstine.ado +f b\bollenstine.sthlp +f l\lconfa.mlib +e +S http://www.stata.com/stb/stb55 +N sbe33.pkg +D 25 May 2011 +U 47 +d STB-55 sbe33. Comparing several methods of measuring the same quantity +d STB insert by Paul Seed, GKT School of Medicine, King's London, UK +d Support: paul.seed@@kcl.ac.uk +d After installation, see help ^baplot^, help ^sdpair^, help ^bamat^, +d help ^bagroup^ +f b\bagroup.ado +f b\bagroup.hlp +f b\bamat.ado +f b\bamat.hlp +f b\baplot.ado +f b\baplot.hlp +f n\nicenum.ado +f s\sdpair.ado +f s\sdpair.hlp +e +S http://fmwww.bc.edu/repec/bocode/l +N log2html.pkg +D 11 Oct 2012 +U 49 +d 'LOG2HTML': module to produce HTML log files +d +d log2html translates translates Stata's standard SMCL log files to +d HTML, the language used for web pages. log2html provides greater +d formatting flexibility than the built-in but undocumented log +d html, providing preformatted schemes and support for CSS +d (Cascading Style Sheets). Stata 8 is required. (log2html7 is +d available for Stata 7.) +d +d KW: log +d KW: web +d KW: html +d KW: translate +d KW: SMCL +d KW: CSS +d +d Requires: Stata version 8.0 (7.0 for log2html7) +d +d +d Author: Christopher F Baum, Boston College +d Support: email baum@@bc.edu +d +d Author: Nicholas J. Cox, Durham University +d Support: email N.J.Cox@@durham.ac.uk +d +d Author: Bill Rising, StataCorp +d Support: email brising@@stata.com +d +d Distribution-Date: 20080731 +f l\log2html.ado +f l\log2html.hlp +f l\log2html7.ado +f l\log2html7.hlp +e +S http://fmwww.bc.edu/repec/bocode/l +N logout.pkg +D 11 Oct 2012 +U 50 +d 'LOGOUT': module to convert log or ASCII files into various output formats +d +d logout provides a fast and easy way to convert log or ASCII files +d into various output formats compatible with Word, Excel, LaTeX, +d or Stata datafile. Can be used as a prefix or by itself after a +d log file has been created. caplog provides a fast and easy way to +d capture text-based log file, possibly for use with logout or +d dataout. +d +d KW: log file +d KW: table +d KW: tab +d KW: summary +d KW: output +d KW: LaTeX +d KW: Word +d KW: Excel +d KW: dataout +d +d Requires: Stata version 7.0 +d +d Distribution-Date: 20091106 +d +d Author: Roy Wada +d Support: email roywada@@hotmail.com +d +f l\logout.ado +f l\logout.hlp +f c\caplog.ado +f c\caplog.hlp +e +S http://fmwww.bc.edu/repec/bocode/g +N gllamm.pkg +D 19 Nov 2012 +U 51 +d 'GLLAMM': program to fit generalised linear latent and mixed models +d +d gllamm fits generalized linear latent and mixed models. These +d models include Multilevel generalized linear regression models +d (extensions of the simple random intercept models that may be +d fitted in Stata using xtreg, xtlogit, xtpois to include +d multilevel and random coefficient models), Multilevel factor +d models and Multilevel structural equation models. The latent +d variables (or random effects) can be assumed to have a +d multivariate normal distribution or to be discrete allowing +d nonparametric maximum likelihood estimation. The common links and +d families of generalized linear models are available and responses +d can be of mixed type including continuous, censored, discrete, +d dichotomous, ordered categorical and unordered categorical. The +d version of gllamm (gllamm6) described in STB-53, (sg129, p47-57) +d does not incorporate many of the features outlined above. This is +d version 2.3.20 of the software (Sep 2011). A manual in PDF form +d is available from the SSC archive via web browser. +d +d KW: multilevel models +d KW: mixed models +d KW: random coefficients +d KW: latent variable models +d +d Requires: Stata version 7.0 +d +d +d Author: Sophia Rabe-Hesketh, University of California - Berkeley +d Support: email sophiarh@@berkeley.edu +d +d Distribution-Date: 20110911 +d +f g\gllamm.ado +f g\gllamm.hlp +f e\eq_g.hlp +f g\gllam_ll.ado +f g\gllapred.ado +f g\gllapred.hlp +f g\gllarob.ado +f g\gllasim.ado +f g\gllasim.hlp +f g\gllas_yu.ado +f r\remcor.ado +e +S http://fmwww.bc.edu/repec/bocode/h +N hotdeck.pkg +D 30 Jan 2013 +U 52 +d 'HOTDECK': module to impute missing values using the hotdeck method +d +d hotdeck replaces missing values for the variable indicated by its +d argument. It should be used within a multiple imputation +d sequence since missing values are imputed stochastically rather +d than deterministically. The nmiss missing values in each stratum +d of the data described by the `by' option are replaced by values +d sampled from the nobs observed values in the same stratum. The +d approximate Bayesian bootstrap method of Rubin and Scheker is +d used; first a bootstrap sample of nobs observations is sampled +d with replacement from the observed values, and the nmiss missing +d values are sampled at random (again with replacement) from this +d bootstrap sample. If a file is specified in a using clause, the +d modified file is written to disk and the existing data in memory +d are unchanged. Otherwise the data in memory are modified. This is +d version 1.65 of the software, requiring Stata v9. hotdeck6 may be +d used in earlier versions of Stata. +d +d Author: Adrian Mander, MRC Biostatistics Unit +d Support: email Adrian.Mander@@mrc-hnr.cam.ac.uk +d +d Author: David Clayton +d Support: email david.clayton@@mrc-bsu.cam.ac.uk +d +d Distribution-Date: 20070902 +f h\hotdeck.ado +f h\hotdeck.hlp +f h\hotdeck6.ado +f h\hotdeck6.hlp +e +S http://fmwww.bc.edu/repec/bocode/f +N fitstat_ers.pkg +D 6 May 2013 +U 53 +d 'FITSTAT_ERS': module to compute goodness of fit statistics for Rasch model +d +d fitstat_ers computes outfit and infit statistics for the +d conditional maximum likelihood (cml) Rasch model, using formulas +d outlined in the Linacre and Wright (1994). These fit statistics +d differ from those computed by the –raschtest-, which are +d normalized to be approximately normal random variates. These +d statistics are not normalized. +d +d KW: Rasch model +d KW: goodness of fit +d +d Requires: Stata version 9 and gammasym (q.v.) To output tables of statistics, xml_tab.ado and/or outtable.ado are required. +d +d Distribution-Date: 20111222 +d +d Author: Christian Gregory, Economic Research Service, USDA +d Support: email cgregory@@ers.usda.gov +d +f f\fitstat_ers.ado +f f\fitstat_ers.hlp +e +S http://fmwww.bc.edu/repec/bocode/x +N xml_tab.pkg +D 6 May 2013 +U 54 +d 'XML_TAB': module to save results in Excel XML format +d +d xml_tab saves Stata output directly into XML file that could be +d opened with Microsoft Excel or OpenOffice Calc. The program is +d relatively flexible and produces print-ready tables in Excel or +d Calc. xml_tab allows users to apply different formats to the +d elements of the output table and essentially do everything MS +d Excel or OO Calc can do in terms of formatting from within Stata. d +d KW: XML +d KW: results +d KW: output +d KW: Excel +d +d Requires: Stata version 8 and MS Excel (EN) 2002 for Windows, MS Excel 2004 for Mac, or OpenOffice Calc +d +d Distribution-Date: 20080625 +d +d Author: Michael Lokshin, World Bank +d Support: email Mlokshin@@worldbank.org +d +d Author: Zurab Sajaia, World Bank +d Support: email +d +f x\xml_tab.ado +f x\xml_tab.hlp +e +S http://fmwww.bc.edu/repec/bocode/g +N gengroup.pkg +D 6 May 2013 +U 55 +d 'GENGROUP': module to produce groups of individuals +d +d gengroup creates groups of individuals by using the values of an +d ordinal variable. The module creates groups of individuals by +d recoding several adjacent values of the ordinal variable, until +d obtaining groups with more than individuals than the number +d defined in the minsize option. +d +d KW: data management +d KW: groups +d KW: ordinal +d +d Requires: Stata version 7.0 +d +d Distribution-Date: 20101208 +d +d Author: Jean-Benoit Hardouin, University of Nantes, France +d Support: email jean-benoit.hardouin@@univ-nantes.fr +d +f g\gengroup.ado +f g\gengroup.hlp +e +S http://fmwww.bc.edu/RePEc/bocode/b +N batplot.pkg +D 18 Sep 2013 +U 56 +d 'BATPLOT': module to produce Bland-Altman plots accounting for trend +d +d The normal Bland-Altman plot is between the difference of paired +d variables versus their average. This version uses a regression +d between the difference and the average and then alters the +d limits of agreement accordingly. This is particularly useful +d when the two variables might be measured on different scales and +d hence a straight conversion factor would recalibrate the two +d variables. +d +d KW: plot +d KW: Bland-Altman +d KW: difference +d KW: paired variables +d +d Requires: Stata version 9.2 +d +d Distribution-Date: 20120617 +d +d Author: Adrian Mander +d Support: email Adrian.Mander@@mrc-hnr.cam.ac.uk +d +f b\batplot.ado +f b\batplot.hlp +e +S http://www.indiana.edu/~jslsoc/stata +N spost9_ado.pkg +D 18 Oct 2013 +U 57 +d spost9_ado | Stata 9-13 commands for the post-estimation interpretation +d Distribution-date: 05Aug2013 +d of regression models. Use package spostado.pkg for Stata 8. +d Based on Long & Freese - Regression Models for Categorical Dependent +d Variables Using Stata. Second Edition. +d Support www.indiana.edu/~jslsoc/spost.htm +d Scott Long & Jeremy Freese (spostsup@@indiana.edu) +f _\_get_mlogit_bv.ado +f _\_get_mlogit_bvecv.ado +f _\_peabbv.ado +f _\_pebase.ado +f _\_pebase.hlp +f _\_pecats.ado +f _\_pecats.hlp +f _\_peciboot.ado +f _\_peciboot.hlp +f _\_pecidelta.ado +f _\_pecidelta.hlp +f _\_peciml.ado +f _\_pecmdcheck.ado +f _\_pecollect.ado +f _\_pecollect.hlp +f _\_pedum.ado +f _\_pedum.hlp +f _\_peife.ado +f _\_peife.hlp +f _\_pemarg.ado +f _\_pemarg.hlp +f _\_penocon.ado +f _\_penocon.hlp +f _\_pepred.ado +f _\_pepred.hlp +f _\_perhs.ado +f _\_perhs.hlp +f _\_pesum.ado +f _\_pesum.hlp +f _\_petrap.ado +f _\_petrap.hlp +f _\_peunvec.ado +f _\_peunvec.hlp +f _\_pexstring.ado +f a\asprvalue.ado +f a\asprvalue.hlp +f b\brant.ado +f b\brant.hlp +f c\case2alt.ado +f c\case2alt.hlp +f c\countfit.ado +f c\countfit.hlp +f f\fitstat.ado +f f\fitstat.hlp +f l\leastlikely.ado +f l\leastlikely.hlp +f l\listcoef.ado +f l\listcoef.hlp +f m\misschk.ado +f m\misschk.sthlp +f m\mlogplot.ado +f m\mlogplot.hlp +f m\mlogtest.ado +f m\mlogtest.sthlp +f m\mlogview.ado +f m\mlogview.hlp +f m\mvtab1.ado +f m\mvtab1.hlp +f n\nmlab.ado +f n\nmlab.hlp +f p\praccum.ado +f p\praccum.hlp +f p\prchange.ado +f p\prchange.hlp +f p\prcounts.ado +f p\prcounts.hlp +f p\prdc.ado +f p\prdc.hlp +f p\prgen.ado +f p\prgen.hlp +f p\prtab.ado +f p\prtab.hlp +f p\prvalue.ado +f p\prvalue.hlp +f p\prwhich.ado +f s\spex.ado +f s\spex.hlp +f s\spost.hlp +f s\spost_footer.ihlp +f s\spostupdate.ado +f v\vardesc.ado +f v\vardesc.hlp +f x\xpost.ado +e +S http://www.andrew.cmu.edu/user/bjones/traj +N traj.pkg +D 6 Dec 2013 +U 58 +d traj. Group-Based Modeling of Longitudinal Data +d +d {bf: Bobby L. Jones, University of Pittsburgh Medical Center} +d +d {bf: Daniel S. Nagin, Carnegie Mellon University} +d +d +d Support: bjones@andrew.cmu.edu +f t\traj.plugin +f t\traj.ado +f t\trajplot.ado +f t\traj.hlp +f t\trajplot.hlp +e diff --git a/Modules/ado/plus/t/takelist.ado b/Modules/ado/plus/t/takelist.ado new file mode 100644 index 0000000..8a2b130 --- /dev/null +++ b/Modules/ado/plus/t/takelist.ado @@ -0,0 +1,61 @@ +program def takelist, rclass +*! NJC 1.3.0 14 December 2000 +* NJC 1.2.0 7 June 2000 +* NJC 1.1.0 22 Dec 1999 +* NJC 1.0.0 19 Dec 1999 from a suggestion by Kit Baum + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + + local nlist : word count `list' + + syntax , [ Pos(numlist int >=-`nlist' <=`nlist') Global(str) Noisily ] + + * blanking this out traps a bug if 0 is included in -pos( )- + local 0 + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tknz `pos', s(p) + local np : word count `pos' + + * negative indexes to positive + local i = 1 + while `i' <= `np' { + local p`i' = cond(`p`i'' < 0, `nlist' + 1 + `p`i'', `p`i'') + local i = `i' + 1 + } + + tokenize `list' + + local i = 1 + while `i' <= `np' { + local newlist "`newlist'``p`i''' " + local i = `i' + 1 + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + +program def tknz, rclass +* NJC 1.1.0 2 June 2000 + version 6.0 + gettoken list 0 : 0, parse(",") + syntax , Stub(str) [ * ] + tokenize `"`list'"' , `options' + + local i = 1 + while "``i''" != "" { + c_local `stub'`i' `"``i''"' + local i = `i' + 1 + } +end + diff --git a/Modules/ado/plus/t/takelist.hlp b/Modules/ado/plus/t/takelist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/t/takelist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/t/tmpdir.ado b/Modules/ado/plus/t/tmpdir.ado new file mode 100644 index 0000000..23234be --- /dev/null +++ b/Modules/ado/plus/t/tmpdir.ado @@ -0,0 +1,81 @@ +*! tmpdir Version 1.1 dan.blanchette@duke.edu 22Jan2009 +*! Center of Entrepreneurship and Innovation Duke University's Fuqua School of Business +* tmpdir Version 1.1 dan_blanchette@unc.edu 16Jan2008 +* research computing, unc-ch +** - minor code updating to improve efficiency of this program +** and added check to make sure a Linux/UNIX tmpdir does not +** contain spaces. +** tmpdir Version 1.0 dan_blanchette@unc.edu 08Oct2003 +** the carolina population center, unc-ch + +program define tmpdir, rclass +args short + version 8 + + /*************************************************************************************** + Stata uses the directory that is set by your computer to be the temporary directory + by default. The environment variable STATATMP can be set to specific directory that + Stata should use for the temporary directory. If you want to have certain programs + that call -tmpdir- to use yet another directory for temporary files you can set + the location of that temporary directory here with the local macro variable tmpdir. + + If for some reason tmpdir.ado was unable to figure out what the pathname is, + enter the name without spaces in the name. For example: + local tmpdir=`"c:\Documents and Settings\dan\Local Settings\temp"' + should be set using short file names (first 6 characters, plus "~1" or "~2" , etc. : + local tmpdir=`"c:\Docume~1\dan\LocalS~1\temp"' + ****************************************************************************************/ + + local tmpdir=`""' + + ***************************************************************** + ******* ! NO MORE EDITS SHOULD BE MADE AFTER THIS POINT ! ******* + ***************************************************************** + confirmdir `"`tmpdir'"' + if `"`tmpdir'"'=="" | `r(confirmdir)'!=0 { /* tmpdir is not set or not set correctly */ + tempfile temp + _getfilename `"`temp'"' + local tfilen `"`r(filename)'"' + + local tmpdir : subinstr local temp `"`tfilen'"' "" + + local subtest : subinstr local tmpdir " " "" , count(local cnt) + if `cnt' != 0 { + if "`c(os)'"=="Windows" { /* make sure directory structure has no spaces */ + shortdir using `"`tmpdir'"' , `short' + local tmpdir `"`r(shortdir)'\"' + } /* end of windows */ + else { + di "{error}Your temporary directory contains spaces." + di "{error}You need to set the location of your temporary directory " _n /// + "to a directory that does not contain spaces." + di "{error}Edit your tmpdir.ado file to set the location of your Stata temporary file: " + which tmpdir + if "`c(console)'" == "" { + di `"It's as easy as: "' + di `" {stata adoedit tmpdir: (click here, to edit the tmdpir.ado file}, remember to save when done.)"' + } + exit 499 + } + } // end of if tmpdir contains spaces + capture confirmdir "`macval(tmpdir)'" + if `r(confirmdir)'!=0 { + di "{error}The setting for your temporary directory: {res}`tmpdir' {error}is not correct." + di "{error}You need to set the location of your temporary directory." + di "{error}Edit your tmpdir.ado file to set the location of your Stata temporary file: " + which tmpdir + if "`c(console)'" == "" { + di `"It's as easy as: "' + di `" {stata adoedit tmpdir: (click here, to edit the tmdpir.ado file}, remember to save when done.)"' + } + exit 499 + } + } /* end of tmpdir not set or not set correctly */ + + return local tmpdir "`tmpdir'" + +end + + + + diff --git a/Modules/ado/plus/t/tmpdir.hlp b/Modules/ado/plus/t/tmpdir.hlp new file mode 100644 index 0000000..2aa5014 --- /dev/null +++ b/Modules/ado/plus/t/tmpdir.hlp @@ -0,0 +1,96 @@ +{smcl} +{* *! version 1.1 18Jan2008}{...} +{* 06Nov2003}{...} +{hline} +help for {hi:tmpdir} {right:manual: {hi:[R] none}} +{right:dialog: {hi: none} } +{hline} + + +{title:Returns the directory Stata is using for a temporary directory `r(tmpdir)'} + +{p 8 17 2}{cmd:tmpdir} +[{cmd:short}]{p_end} + + +{t:itle:Description} + +{p 4 4 2}{cmd:tmpdir} is designed for programmers who want to know what directory Stata +writes temp files to. This can be helpful when using the {help file} command +to write intermediary files for a program. Since spaces in directory names can +cause problems for programs running, {cmd:tmpdir} in the Windows operating system +replaces directory / subdirectory names that contain spaces, or optionally any name +longer than 8 characters, with the first 6 non-space +characters plus "~1" or "~2" (up to "~4"). After that it gets a bit crazy with +hexadecimal replacements. {cmd:tmpdir} shells out to DOS and finds the short +directory name that DOS has come up with, so there's no attempt to guess the short +name. This makes it possible to use this program on many different versions of +Windows and always get the short name right. UNIX/Linux systems tend not to have +spaces in the directory designated to be the temporary directory, but {cmd:tmpdir} +checks for spaces to make sure the temp directory does not have spaces.{p_end} + +{p 4 8 2} Note: {cmd:tmpdir} can be hard coded so that it always chooses a specific directory. +This can be helpful if you want to direct large files to your D: drive.{p_end} + +{title:Options} + +{p 4 8 2}{cmd:short} is for Windows only and it specifies that any long directory name +should be shortened to 8.3 style names. Not using the {cmd:short} option will allow +for long directory names that do not have spaces.{p_end} + +{title:Examples} + +{p 4 8 2}So if your temporary directory is: "C:\Documents and Settings\dan\Local Settings\temp"{p_end} + +{p 4 8 2}{cmd:. tmpdir} returns r(tmpdir):{p_end} + +{p 4 8 2}{cmd:. return list }{p_end} + +{p 4 8 2}{cmd:macros: }{p_end} + +{p 10 10 2}{cmd:r(tmpdir) : "C:\Docume~1\dan\LocalS~1\temp\"}{p_end} + +{p 4 8 2}But if your temp directory is: "C:\Documents and Settings\dan_blanchette\Local Settings\temp"{p_end} + +{p 4 8 2}{cmd:. tmpdir} returns r(tmpdir):{p_end} + +{p 4 8 2}"C:\Docume~1\dan_blanchette\LocalS~1\temp\"{p_end} + +{p 4 8 2}since "dan_blanchette" has no spaces in the name.{p_end} + +{p 4 8 2}{cmd:. tmpdir short} returns r(tmpdir):{p_end} + +{p 4 8 2}"C:\Docume~1\dan_b~1\LocalS~1\temp\"{p_end} + + +{title:Saved Results} + +{p 4 4 2}The {cmd:tmpdir} command saves in {cmd:r()}:{p_end} + +{p 4 8 2} +The {cmd:adoedit} command saves in {cmd:r()}:{p_end} + +{synoptset 20 tabbed}{...} +{p2col 5 20 24 2: Macros}{p_end} +{synopt:{cmd:r(tmpdir)}}Stata's temporary directory path{p_end} + + +{title:Author} + +{p 4 4 2} +Dan Blanchette {break} +Center of Entrepreneurship and Innovation {break} +Duke University's Fuqua School of Business {break} +Dan.Blanchette@Duke.edu{p_end} + + +{title:Also see} + +{p 4 13 2}On-line: {help tempfile} {help _getfilename} , +{help confirmdir} (if installed) +{help shortdir} (if installed) +{help savasas} (if installed) +{help usesas} (if installed){p_end} + + + diff --git a/Modules/ado/plus/t/torumm.ado b/Modules/ado/plus/t/torumm.ado new file mode 100644 index 0000000..9e67c0e --- /dev/null +++ b/Modules/ado/plus/t/torumm.ado @@ -0,0 +1,273 @@ +*! torumm.ado version 1.1.2 fw 12/23/00 convert stata files to rumm format +*! syntax varlist(numeric) [, FILEname(string) FACTors(varlist numeric max=3) REVerse(varlist) IDvar(varname) ] +*! rev 1.1.0 (12/18/01): adds length of label check + +/* +itemSeq Sequence of study items +testType E = extended/polytomous M = multiple choice +itemCode A maximum 5 character code describeing each item +itemState A 30 character description (label) +respType N = numeric A = alpha +respNumb The number of possible responses +scKey Scoring key: blank or R for reversed +respSeq 0 to 5 for numeric, A to E for alpha (the lowest level of response) + +itemSeq testType itemCode itemState respType respNumb scKey respSeq +1 E I0001 Descriptor for Item 1 N 4 1 +2 E I0002 Descriptor for Item 2 N 4 R 1 +3 E I0003 Descriptor for Item 3 N 4 1 +4 E I0004 Descriptor for Item 4 N 4 R 1 +5 E I0005 Descriptor for Item 5 N 4 R 1 +6 E I0006 Descriptor for Item 6 N 4 R 1 +7 E I0007 Descriptor for Item 7 N 4 1 +8 E I0008 Descriptor for Item 8 N 4 R 1 +9 E I0009 Descriptor for Item 9 N 4 R 1 +10 E I0010 Descriptor for Item 10 N 4 1 +11 E I0011 Descriptor for Item 11 N 4 R 1 +12 E I0012 Descriptor for Item 12 N 4 1 +13 E I0013 Descriptor for Item 13 N 4 R 1 +14 E I0014 Descriptor for Item 14 N 4 1 +15 E I0015 Descriptor for Item 15 N 4 1 +16 E I0016 Descriptor for Item 16 N 4 R 1 + +*/ + +program define torumm + version 6.0 + syntax varlist(numeric) [, FILEname(string) FACTors(varlist numeric max=3) REVerse(varlist) IDvar(varname) ] + tokenize `varlist' + + set more off + + preserve + + /* Process spc file items */ + + qui dropvars itemSeq testType itemCode itemStat respType respNumb scKey respSeq + + di "Building SPC file ..." + qui gen byte itemSeq = . + qui gen str1 testType = "E" + qui gen str5 itemCode = "" + qui gen str30 itemStat = "" + qui gen str1 respType = "N" + qui gen byte respNumb = . + qui gen str1 scKey = "" + qui gen byte respSeq = . + + + if "`ttype'" == ""{ + local ttype E + } + if "`rtype'" == ""{ + local rtype N + } + + local wcount: word count `varlist' + local varnum 0 + while `"`1'"' != ""{ + local varnum `varnum' + 1 + local label : variable label `1' + local vword "`1'" + * di "`1'" " " "`label'" + * di `vanum' + qui replace itemStat = "`label'" if _n == `varnum' + qui replace itemStat = "`vword'" if itemStat == "" & _n == `varnum' + qui replace itemSeq = _n if _n == `varnum' + qui replace itemCode = "I" + string(_n) if _n == `varnum' + qui su `1' + qui replace respNumb = (r(max) - r(min)) + 1 if _n == `varnum' + qui replace respSeq = r(min) if _n == `varnum' + qui bothlist `1' \ `reverse' + if "`r(list)'" == "`1'" { + qui replace scKey = "R" if _n == `varnum' + } + + mac shift + } + qui compress + listblck itemSeq - respSeq in 1 / `wcount' + qui outsheet itemSeq-respSeq using "`filename'.spc" in 1 / `wcount',noquote replace + + + + + /* Process itm file items */ + + qui tostring `varlist', nodecode /* convert study variables to strings */ + qui dropvars blockID segID comments blockS blockW TestType RespType itemLen itemSubN missSymb + + + /* We convert the ID variable to a string format */ + local type : type `idvar' + if substr("`type'",1,3) != "str" {qui tostring `idvar', f(%5.0f)} + recast str5 `idvar' + qui replace `idvar' = ltrim(`idvar') + qui moreobs + qui gen order = _n + qui replace `idvar' ="aaaaa" in l + + qui gen blockID = _n /* Data should be in order required before running this program */ + qui gen str2 segID = "" + qui gen str30 comments = "" + qui gen byte blockS = . + qui gen blockW = . + qui gen byte TestType = 0 + qui gen byte RespType = 0 + qui gen byte itemLen = 0 + qui gen itemSubN = 0 + qui gen str3 missSymb = "bsp" + + /* enter blockID data *** This is for line 1*/ + qui replace blockID = 1 in 1 + qui replace segID = "1" in 1 + qui replace comments = "ID" in 1 + qui replace blockS = 1 in 1 + qui replace blockW = 5 in 1 + local block = 1 + + if "`factors'" != ""{ + unab cats : `factors' + tokenize "`cats'" + local facount : word count `cats' + *di "Number of factor variables = " "`facount'" + local counter = 0 + local starter = 7 /* we begin variable placement counting at 30 */ + /* we have skipped a space so lets add the spacer to the output template */ + sort order + qui gen str1 space1 = "" + qui replace space1 = "s" in l + + /* we have to do the same for the factors - we will do do below */ + while `"`1'"' != ""{ + local counter = `counter' + 1 + local facword : word `counter' of `cats' + qui tab `1' + *di "Variable (" `counter' ") " "`1'" " has " `r(r)' " levels" + local block = `block' + 1 + qui replace blockID in `block' = `block' + + /* Now we enter the factor data - the variable name goes first*/ + qui replace segID = "2" in `block' + local label : variable label `1' + if length("`label'") >5 { + di + di in red "label for `1' (`label') is more than 5 characters in length" + exit 198 + } + if "`label'" != "" { + qui replace comments = "`label'" in `block' + } + else {qui replace comments = "`1'" in `block'} + + qui replace blockS = `starter' in `block' + qui replace blockW = 1 in `block' + local starter = `starter' + 1 + + /* Now we move to the labelled categories & move down a row */ + local block = `block' + 1 + qui replace blockID in `block' = `block' + qui tab `1' /* The number of levels is r(r) then `catlev'*/ + local catlev = `r(r)' + qui vallist `1',label s(^) + local avals `r(list)' + local avals : subinstr local avals " " "_", all + local avals : subinstr local avals "^" " ", all + qui vallist `1' + local nvals `r(list)' + local vcount = 1 + *di "Alpha list = " "`avals'" + *di "Numerical list = " "`nvals'" + *di + + while `vcount' <= `catlev' { + + local aword : word `vcount' of `avals' + local nword : word `vcount' of `nvals' + qui replace comments = "`aword'" in `block' + qui replace segID = "2`counter'" in `block' + qui replace blockS = `counter' in `block' + qui replace blockW = `nword' in `block' + qui replace missSymb = "0" in `block' + *di "`aword'" " " "`nword'" + if `vcount' != `catlev' {local block = `block' + 1 } + local vcount = `vcount' + 1 + } + qui tostring `1', nod + sort order + qui replace `1' = "f" in l + mac shift + } + + } + else{ + di "No factor model" + qui gen str1 space1 = "" + qui replace space1 = "s" in l + local starter = 7 + } + + /* Now begin the placement of variables */ + local block = `block' + 1 + local starter = `starter' + 2 + sort order + qui gen str2 space2 = "" + qui replace space2 = "ss" in l + qui replace segID = "3" in `block' + qui replace comments = "Items" in `block' + qui replace blockS = `starter' in `block' + qui replace blockW =`varnum' in `block' + qui compress comments + qui replace TestType = 1 in `block' + qui replace RespType = 1 in `block' + qui replace itemLen = 1 in `block' + qui replace itemSubN = `varnum' in `block' + + /* replace varlist here with v */ + tokenize `varlist' + while `"`1'"' != ""{ + qui replace `1' = "v" in l + mac shift + } + listblck blockID segID comments blockS blockW TestType RespType itemLen itemSubN missSymb in 1 / `block' + qui outsheet blockID segID comments blockS blockW TestType RespType itemLen itemSubN missSymb using "`filename'.itm" in 1 / `block',noquote replace + + /* We can now concatenate into a long string */ + + *format `idvar' %030s + + if "`factors'" != ""{ + local outvar "`idvar' space1 `cats' space2 `varlist'" + } + else {local outvar "`idvar' space1 space2 `varlist'"} + tokenize `outvar' + while `"`1'"' != ""{ + qui replace `1' = "^^^^^^^^^^^^^^^^^^^^" if `1' == "",nop + mac shift + } + local outvar : subinstr local outvar " " "+" , all + *di "`outvar'" + gen str80 outvar = `outvar' + sort order + local lcount = 0 + while `lcount' < _N { + local lcount = `lcount' + 1 + local tempout = outvar in `lcount' + local sub : subinstr local tempout "^" " " , all + qui replace outvar = "`sub'" in `lcount' + } + qui compress outvar + qui drop in l + di "`file'" + *format outvar %-080s + outfile outvar using `filename'.dat, wide replace noq + l outvar + restore + di + su `varlist' + + di + di "Files Created: (1) `filename'.scr (2) `filename'.itm (3) `filename'.dat" + +end + diff --git a/Modules/ado/plus/t/torumm.hlp b/Modules/ado/plus/t/torumm.hlp new file mode 100644 index 0000000..3f69cbd --- /dev/null +++ b/Modules/ado/plus/t/torumm.hlp @@ -0,0 +1,89 @@ +.- +help for ^torumm^ +.- + +^Format and transfer data to RUMM^ +------------------------------- + +syntax varlist [, FILEname(string) FACTors(string) IDvar(varname) REVerse ] + + +^Description^ +----------- + +^torumm^ prepares a Stata dataset for analysis in ^RUMM^), a Rasch analysis +package. Two control files (.spc .itm) and a data file (.dat) are created +using using the Stata ^outsheet^ and outfile commands. ^torumm^ is +non-destructive in that does not alter the Stata data. ^varlist^ +refers to the variables that will be studied in the Rasch analysis. The +"factor" variables are categorical variables that subset the analyses. + + +^Options^ +------- + +^FILEname(string)^: the name of the files to be saved as -spc-, itm- and +-dat- files in Rumm. + +^FACTors(varlist)^: the factorial or categorical variables (subsetting). +Rumm only allows 3 factors. Factor label cannot be longer than 5 characters. + +^IDvar^: the name of the ID variable. This can be up to 5 charters in length +or between 0 and 99,999, if numeric. + +^REVerse^: varlist of variables that are reversed scored. + + +^Comments^ +-------- + +The current version of ^torumm^ has a number of restrictions: (1) only +numeric variables are allowed in the varlist and list of factor variables. +(2) only integers between 0-9 are to be used for the varlist and factor +variable values. (3) This version of ^torumm^ suuports rating scale +but not multiple choice variables. By default the RUMM variable ^testType^ +has been set to E for extended or polytomous (rating scale). In addition, +^respType^ has been set to the default of N (numeric). (4) Because of +the 80 character string limitation on Stata,a maximum of 69 variables +should be entered as the varlist in order to stay within the 80 character +limitation. + +^Sort order of the variables^ If you want a special order to the variables +be sure to order the variables in the desired order with ^order^. + +The number of responses or ^respNum^ is calculated from min and max values. +If the item does not have a score at the minumum or maximum value then +the ^respNum^ will be incorrect (in one sense). ^respNum^ should be checked +by viewing the program output or by hand in the RUMM editor or a spread sheet +to be sure the calculated values are correct. + +The lowest code number for the responses or ^respSeq^ is calculated +from the minimum value. If the item does not have a score at the minumum +value then the ^respSeq^ will be incorrect (in one sense). ^respSeq^ should +be checked in the program output or by hand in the RUMM editor or a spread +sheet to be sure the calculated values are correct. + +^torumm^ makes use of value labels, if present, otherwise it uses numeric +codes. Similarly, variables labels are used when present; if not present, +variable name is substituted for the variable label. + + +If Stata 6.0 is being used, ^torumm^ requires the presence of -vallist-, +-tostring- and -bothlist-, programs of Nick Cox that are available on the BC +Archives. ^torumm^ also works with Stata 7.0. + + +^Examples^ +-------- + +. torumm mcp_eros - m_nav_n1, file(shrumm) id(newpat) rev(mcp_nar1 mcp_nar2) +. torumm mcp_eros - m_nav_n1, file(shrumm) id(patkey) factors(durgroup) + +^Author^ +------ + + Fred Wolfe + National Data Bank for Rheumatic Diseases + fwolfe@@arthritis-research.org + + diff --git a/Modules/ado/plus/t/traces.ado b/Modules/ado/plus/t/traces.ado new file mode 100644 index 0000000..8495b13 --- /dev/null +++ b/Modules/ado/plus/t/traces.ado @@ -0,0 +1,309 @@ +*! Version 3.2 27May2007 +************************************************************************************************************ +* Traces: Traces of items +* Version 3.2: May 27, 2007 (onlyone option) +* +* Historic: +* Version 1 (2003-06-29): Jean-Benoit Hardouin +* Version 2 (2003-07-04): Jean-Benoit Hardouin +* version 3 (2003-07-09): Jean-Benoit Hardouin +* Version 3.1 (2005-06-07): Jean-Benoit Hardouin /*small modifications*/ +* +* Jean-benoit Hardouin, phD, Assistant Professor +* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences +* University of Nantes - Faculty of Pharmaceutical Sciences +* France +* jean-benoit.hardouin@anaqol.org +* +* News about this program :http://www.anaqol.org +* FreeIRT Project website : http://www.freeirt.org +* +* Copyright 2003, 2005, 2007 Jean-Benoit Hardouin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +************************************************************************************************************ + +program define traces +version 8.0 +syntax varlist(numeric min=2) [, Score Test Restscore Logistic CI CUMulative REPFiles(string) SCOREFiles(string) RESTSCOREFiles(string) LOGISTICFile(string) noDraw noDRAWComb REPlace ONLYone(string) THResholds(string)] + +local nbitems : word count `varlist' +tokenize `varlist' + +if "`onlyone'"!=""&"`drawcomb'"!="" { + local drawcomb +} + +tempvar varscore +qui gen `varscore'=0 +label variable `varscore' "Total score" +local scoremax=0 +local flag=0 + +if "`score'"==""&"`restscore'"==""&&"`logistic'"=="" { + local score="score" +} + +forvalues i=1/`nbitems' { + qui replace `varscore'=`varscore'+``i'' + qui su ``i'' + local modamax`i'=r(max) + if r(min)!=0 { + local flag=1 + } + local scoremax=`scoremax'+`modamax`i'' + if `modamax`i''!=1 { + local flagbin=0 + } +} + + +if `flag'==1 { + di as error "The lower modality of the item must be 0" + exit +} +if "`flagbin'"!=""&"`logistic'"!="" { + di as error "The logistic option is not possible with polytomous items" + exit +} + +qui su `varscore' +local maxscore=r(max) + +forvalues i=0/`maxscore' { + qui count if `varscore'==`i' + local nscore`i'=r(N) +} + + +global score +global restscore +global logistic + +if "`score'"!="" { + if "`thresholds'"!="" { + * set trace on + local nbth:word count `thresholds' + forvalues t=1/`nbth' { + local th`t':word `t' of `thresholds' + } + tempname label + local recode 0/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1' + qui label define `label' 1 "0/`th1'",add + qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add + forvalues j=2/`nbth' { + local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j' + qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add + } + tempname varscore2 + qui gen `varscore2'=`varscore' + qui recode `varscore' `recode' + qui label values `varscore' `label' + local nbgroups=`nbth'+1 + local minimum=1 + } + else { + local nbgroups=`maxscore' + local minimum=0 + } + + forvalues i=1/`nbitems' { + local y`i' + forvalues k=1/`modamax`i'' { + tempvar propscore`i'`k' tmp + if "`cumulative'"!="" { + qui gen `tmp'=``i''>=`k'&``i''!=. + bysort `varscore' : egen `propscore`i'`k''=mean(`tmp') + label variable `propscore`i'`k'' "Item ``i''>=`k'" + } + else { + qui gen `tmp'=``i''==`k'&``i''!=. + bysort `varscore' : egen `propscore`i'`k''=mean(`tmp') + label variable `propscore`i'`k'' "Item ``i''=`k'" + } + local y`i'="`y`i'' `propscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icscoreminus icscoreplus + forvalues l=1/`maxscore' { + qui count if `varscore'==`l' + local nscore`l'=r(N) + } + qui gen `icscoreminus'=`propscore`i'1'-1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1') + qui gen `icscoreplus'=`propscore`i'1'+1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1') + label variable `icscoreminus' "Lower 95% confidence interval" + label variable `icscoreplus' "Upper 95% confidence interval" + local y`i'="`icscoreminus' `icscoreplus' `propscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `propscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + } + if "``i''"=="`onlyone'"|"`onlyone'"=="" { + qui graph twoway (line `y`i'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , note("`note'") ylabel(0(.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(score`i',replace) title("Trace of the item ``i'' as a function of the score") ytitle("Rate of positive response") `draw' + } + global score "$score score`i'" + if "`scorefiles'"!="" { + graph save score`i' `repfiles'\\`scorefiles'``i'' ,`replace' + } + } + if "`thresholds'"!="" { + qui replace `varscore'=`varscore2' + } +} +if "`restscore'"!="" { + forvalues i=1/`nbitems' { + local y`i' + tempvar restscore`i' + qui gen `restscore`i''=`varscore'-``i'' + label variable `restscore`i'' "Rest score with respect to the item ``i''" + if "`thresholds'"!="" { + * set trace on + local nbth:word count `thresholds' + forvalues t=1/`nbth' { + local th`t':word `t' of `thresholds' + } + tempname label + local recode 0/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1' + qui label define `label' 1 "0/`th1'",add + qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add + forvalues j=2/`nbth' { + local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j' + qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add + } + + *di "recode `restscore`i'' `recode'" + qui recode `restscore`i'' `recode' + qui label values `restscore`i'' `label' + local nbgroups=`nbth'+1 + local minimum=1 + } + else { + local nbgroups=`maxscore' + local minimum=0 + } + + forvalues k=1/`modamax`i'' { + tempvar rtmp proprestscore`i'`k' + if "`cumulative'"!="" { + qui gen `rtmp'=``i''>=`k'&``i''!=. + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''>=`k'" + } + else { + qui gen `rtmp'=``i''==`k'&``i''!=. + bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp') + label variable `proprestscore`i'`k'' "Item ``i''=`k'" + } + local y`i'="`y`i'' `proprestscore`i'`k''" + local style="solid" + local color="black" + local width="medthick" + if `modamax`i''==1&"`ci'"!="" { + tempvar icrestscoreminus icrestscoreplus + qui su `restscore`i'' + local maxrestscore=r(max) + forvalues l=1/`maxrestscore' { + qui count if `restscore`i''==`l' + local nrestscore`i'=r(N) + } + qui gen `icrestscoreminus'=`proprestscore`i'1'-1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + qui gen `icrestscoreplus'=`proprestscore`i'1'+1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'') + label variable `icrestscoreminus' "Lower 95% confidence interval" + label variable `icrestscoreplus' "Upper 95% confidence interval" + local y`i'="`icrestscoreminus' `icrestscoreplus' `proprestscore`i'1'" + local style="dash dash solid" + local color="red red black" + local width="thin thin medthick" + } + if `modamax`i''==1&"`test'"!="" { + qui regress `proprestscore`i'1' `varscore' + local p=Fden(e(df_m),e(df_r),e(F)) + if `p'<0.0001 { + local note="Test: slope=0, p<0.0001" + } + else { + local p=substr("`p'",1,6) + local note="Test: slope=0, p=`p'" + } + } + } + local restscoremax=`scoremax'-`modamax`i'' + if "``i''"=="`onlyone'"|"`onlyone'"=="" { + *tab `proprestscore`i'1' `restscore`i'' + qui graph twoway (line `y`i'' `restscore`i'', clpattern(`style') clcolor(`color') clwidth(`width')), note("`note'") ylabel(0(0.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(restscore`i',replace) title("Trace of the item ``i'' as a function of the restscore") ytitle("Rate of positive response") `draw' + } + global restscore "$restscore restscore`i'" + if "`restscorefiles'"!="" { + graph save restscore`i' `repfiles'\\`restscorefiles'``i'' ,`replace' + } + } +} +if "logistic"!="" { + forvalues i=1/`nbitems' { + qui logistic ``i'' `varscore' + tempname coef + matrix `coef'=e(b) + local pente`i'=`coef'[1,1] + local intercept`i'=`coef'[1,2] + tempvar logit`i' + qui gen `logit`i''=exp(`intercept`i''+`pente`i''*`varscore')/(1+exp(`intercept`i''+`pente`i''*`varscore')) + label variable `logit`i'' "Item ``i''" + sort `varscore' + global logistic "$logistic `logit`i''" + } +} +if "`drawcomb'"!="" { + local drawcomb="nodraw" +} + +if "`score'"!=""&"`onlyone'"=="" { + graph combine $score , title("Trace of the items as a function of the score") name(score,replace) `drawcomb' + if "`scorefiles'"!="" { + graph save score `repfiles'\\`scorefiles' ,`replace' + } +} + +if "`restscore'"!=""&"`onlyone'"=="" { + graph combine $restscore , title("Trace of the items as a function of the restscores") name(restscore,replace) `drawcomb' + if "`restscorefiles'"!="" { + graph save restscore `repfiles'\\`restscorefiles' ,`replace' + } +} +if "`logistic'"!="" { + graph twoway (line $logistic `varscore'), ylabel(0(0.25)1) xlabel(0(1)`nbitems') title("Logistic traces") ytitle("") name(logistic,replace) `drawcomb' + if "`logisticfile'"!="" { + graph save logistic `repfiles'\\`logisticfile' ,`replace' + } +} + + +end + + diff --git a/Modules/ado/plus/t/traces.hlp b/Modules/ado/plus/t/traces.hlp new file mode 100644 index 0000000..685227b --- /dev/null +++ b/Modules/ado/plus/t/traces.hlp @@ -0,0 +1,100 @@ +{smcl} +{* 14june2007}{...} +{hline} +help for {hi:traces}{right:Jean-Benoit Hardouin} +{hline} + +{title:Graphical representations of the traces of dichotomous and polytomous items} + +{p 8 14 2}{cmd:traces} {it:varlist} [{cmd:,} {cmdab:s:core} {cmdab:r:estscore} +{cmdab:ci} {cmdab:t:est} {cmdab:cum:ulative} {cmdab:l:ogistic} +{cmdab:repf:ile}({it:directory}) {cmdab:scoref:iles}({it:string}) +{cmdab:restscoref:iles}({it:string}) {cmdab:logisticf:ile}({it:string}) +{cmdab:nod:raw} {cmdab:nodrawc:omb} {cmdab:rep:lace} {cmdab:only:one}({it:varname}) {cmdab:thr:esholds}({it:string})] + + +{title:Description} + +{p 4 8 2}{cmd:traces} builds graphical representations of various kinds of +traces (non parametric Item Response Functions) for dichotomous or polytomous items. + +{title:Options} + +{p 4 8 2}{cmd:score} displays the graphical representations of the traces of the +items as a function of the total score. This is the defaut option if none {cmd:score}, +none {cmd:restscore}, none {cmd:logistic} are indicated. + +{p 4 8 2}{cmd:restscore} displays the graphical representations of the +traces of the items as a function of the rest-score (total score unless the item). + +{p 4 8 2}{cmd:ci} displays the confidence interval at 95% of the traces. + +{p 4 8 2}{cmd:test} tests the nullity of the slope of dichotomous items traces +with a linear model. + +{p 4 8 2}{cmd:cumulative} displays cumulative traces for polytomous +items instead of classical traces. + +{p 4 8 2}{cmd:logistic} displays the graphical representation of the logitic +traces of the items as a function of the score: each trace is the result of a +logistic model with the response to the item as variable to explicate and the +score (and a constant) as explicative variable. This kind of trace is possible +only for dichotomous items. All the logistic traces are represented in the same +graph. + +{p 4 8 2}{cmd:repfile}({it:directory}) is the directory where the files are saved. + +{p 4 8 2}{cmd:scorefiles}({it:string}) defines the generic name of the files containing the graphical representations of the traces as a function of the score. +The name will be followed by the name of each item and by the .gph extension. If this option is not +indicated, the corresponding graphs will be not saved. + +{p 4 8 2}{cmd:restscorefiles}({it:string}) defines the generic name of the files containing the graphical representations of the traces as a function of the rest-scores. +The name will be followed by the name of each item and by the .gph extension. If this option is not +indicated, the corresponding graphs will be not saved. + +{p 4 8 2}{cmd:logisticfile}({it:string}) defines the name of the file containing the graphical representations of the logistic traces. This name will be followed by the .gph extension. +If this option is not indicated, the corresponding graph will be not saved. + +{p 4 8 2}{cmd:nodraw} does not display the graphs by items. + +{p 4 8 2}{cmd:nodrawcomb} does not display the combined graphs by items. + +{p 4 8 2}{cmd:replace} replaces graphical files when they already exist. + +{p 4 8 2}{cmd:onlyone} displays only the trace of a given item. + +{p 4 8 2}{cmd:thresholds} groups the individuals as a function of the (rest-)score. The string contains the maximal values of the (rest-)score in each group. + + + +{title:Example} + + {p 4 8 2}{cmd:. traces item1 item2 item3 item4 , score repfile(c:\graphs) scorefiles(score) nodraw nodrawcomb replace} /*creates the graphs files of the +traces as a function of the score but do not display them.*/ + + {p 4 8 2}{cmd:. traces item1 item2 item3 item4 , score restscore} /*displays +the graphical representations of the traces of the items as a function of the +score and of the rest-scores, but does not save them*/ + + {p 4 8 2}{cmd:. traces itemA*} /*displays the graphical +representations of the traces of the items as a function of the score, by +default*/ + + {p 4 8 2}{cmd:. traces itemA*} ,only(itemA2) thresholds(2 3 5)/*displays the graphical +representations of the traces of the item A2 as a function of the score. Individuals are grouped: a first group of individuals with scores from 0 to 2, a second group with a score of 3, a third group with a score between 4 and 5 and a last group with a score superior to 5*/ + +{title:Author} + +{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end} +{p 4 8 2}Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences{p_end} +{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end} +{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end} +{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end} +{p 4 8 2}Email: +{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end} +{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol} +and {browse "http://www.freeirt.org":FreeIRT} + +{title:Also see} + +{p 4 13 2}Online: help for {help graph}, {help loevH} and {help gengroup} if installed.{p_end} diff --git a/Modules/ado/plus/t/traj.ado b/Modules/ado/plus/t/traj.ado new file mode 100644 index 0000000..029beac --- /dev/null +++ b/Modules/ado/plus/t/traj.ado @@ -0,0 +1,542 @@ +*! traj - May 17, 2013 Bobby L Jones +********************************************************************************** +program traj, eclass + + version 9 + + syntax [if] [in], Model1(str) Var1(varlist numeric) Indep1(varlist numeric) /// + Order1(numlist int >=-1 <=5) /// + [ Min1(real 0.0) Max1(real 1e-38) Iorder1(numlist int >=-1 <=5) /// + Risk1(varlist numeric) Weight1(varlist numeric) Expos1(varlist numeric) /// + Tcov1(varlist numeric) Plottcov1(string) Refgroup1(int 1) /// + Dropout1(numlist int >=-1 <=2) Dcov1(varlist numeric) Obsmar1(varlist numeric) /// + Outcome1(varlist numeric) Omodel1(str) Rorder1(numlist int >=-1 <=3) /// + Model2(str) Var2(varlist numeric) Indep2(varlist numeric) /// + Order2(numlist int >=-1 <=5) Min2(real 0.0) Max2(real 1e-38) /// + Iorder2(numlist int >=-1 <=5) Risk2(varlist numeric) Expos2(varlist numeric) /// + Tcov2(varlist numeric) Refgroup2(int 1) Dropout2(numlist int >=-1 <=2) /// + Model3(str) Var3(varlist numeric) Indep3(varlist numeric) /// + Order3(numlist int >=-1 <=5) Min3(real 0.0) Max3(real 1e-38) /// + Iorder3(numlist int >=-1 <=5) Risk3(varlist numeric) Expos3(varlist numeric) /// + Tcov3(varlist numeric) Dropout3(numlist int >=-1 <=2) /// + Multgroups(integer 0) Start(string) DETAIL TRACE NOVAR OUTOFSAMPLEPROBS] + + marksample touse + quietly count if `touse' + + local maxmodels = 3 + + if `r(N)' == 0 { + error 2000 + } + + local rN = `r(N)' + + forval i = 2/`maxmodels' { + if ( length( "`model`i''" ) == 0 ) { + local model`i' = "none" + } + } + + local itdetail = 0 + if "`detail'" == "detail" { + local itdetail = 1 + } + + local ittrace = 0 + if "`trace'" == "trace" { + local ittrace = 1 + } + + local itnovar = 0 + if "`novar'" == "novar" { + local itnovar = 1 + } + + local oosprobs = 0 + if "`outofsampleprobs'" == "outofsampleprobs" { + local oosprobs = 1 + } + + local traj_start_len = 0 + + if "`start'" != "" { + cap confirm matrix `start' + if _rc { + di as err "Error: start must specify a matrix" + exit 198 + } + tempname traj_start + local traj_start_len = colsof(`start') + matrix traj_start = `start' + } + + local plottcov1_len = 0 + + if "`plottcov1'"!="" { + cap confirm matrix `plottcov1' + if _rc { + di as err "Error: plottcov1 must specify a matrix" + exit 198 + } + tempname traj_plottcov1 + local plottcov1_len = colsof(`plottcov1') + matrix traj_plottcov1 = `plottcov1' + } + + forval i = 1/`maxmodels' { + + if !("`model`i''" == "none") { + + if ( "`model`i''" != "cnorm" & "`model`i''" != "zip" &"`model`i''" != "logit" ) { + di as err "Error: model`i' is not cnorm, zip, or logit." + exit 198 + } + + if "`model`i''"=="cnorm" { + if `max`i'' == 1e-38 { + di as err "Error: max`i' required for model`i' cnorm." + exit 198 + } + + tokenize "`var`i''" + while "`1'" != "" { + local vr `1' + cap sum `vr' + cap assert r(min) >= `min`i'' & r(max) <= `max`i'' + if _rc { + di as err "`vr' is not within min`i' = `min`i'' and max`i' = `max`i''." + exit 198 + } + mac shift + } + } + + if "`model`i''"=="logit" { + tokenize "`var`i''" + while "`1'" != "" { + local vr `1' + cap assert `vr' == 0 | `vr' == 1 | `vr' >= . + if _rc { + di as err "Error: `vr' is not 0/1 (logit model)." + exit 198 + } + mac shift + } + } + + if "`model`i''"=="zip" { + tokenize "`var`i''" + while "`1'" != "" { + local vr `1' + cap assert `vr' >= 0 + if _rc { + di as err "Error: `vr' has negative values (zip model)." + exit 198 + } + mac shift + } + } + } + + local numindep`i' : word count `indep`i'' + local numvar`i' : word count `var`i'' + if ( `numindep`i'' != `numvar`i'' ) { + di as err "Error: number of variables in var`i' and indep`i' must match." + exit 198 + } + + local numrisk`i' : word count `risk`i'' + local numexpos`i' : word count `expos`i'' + local numtcov`i' : word count `tcov`i'' + local numdcov`i' : word count `dcov`i'' + local numoutcome`i' : word count `outcome`i'' + local numweight`i' : word count `weight`i'' + local numobsmar`i' : word count `obsmar`i'' + + + if ( `numoutcome`i'' > 0 ) { + + if ( "`omodel`i''" != "normal" & "`omodel`i''" != "cnorm" & /// + "`omodel`i''" != "poisson" & /// + "`omodel`i''" != "logit" & "`omodel`i''" != "none" ) { + di as err "Error: omodel`i' is not normal, cnorm, poisson, or logit." + exit 198 + } + + /* + if "`omodel`i''"=="cnorm" { + if `max`i'' == 1e-38 { + di as err "Error: max`i' required for model`i' cnorm." + exit 198 + } + cap sum `outcome`i'' + cap assert r(min) >= `omin`i'' & r(max) <= `omax`i'' + if _rc { + di as err "`outcome`i'' is not within omin`i' = `omin`i'' and omax`i' = `omax`i''." + exit 198 + } + } + */ + if "`omodel`i''"=="logit" { + cap assert `outcome`i'' == 0 | `outcome`i'' == 1 | `outcome`i'' >= . + if _rc { + di as err "Error: `outcome`i'' is not 0/1 (logit model)." + exit 198 + } + } + + if "`omodel`i''"=="poisson" { + cap assert `outcome`i'' >= 0 + if _rc { + di as err "Error: `outcome`i'' has negative values (poisson model)." + exit 198 + } + } + } + + if ( `numexpos`i'' > 1 ) { + tokenize "`expos`i''" + while "`1'" != "" { + local vr `1' + cap assert `vr' > 0 + if _rc { + di as err "Error: exposure variable `vr' is not > 0." + exit 198 + } + mac shift + } + if ( `numexpos`i'' != `numvar`i'' ) { + di as err "Error: number of variables in var`i' and expos`i' must match." + exit 198 + } + if ( "`model`i''" != "zip" ) { + di as err "Error: exposure is only allowed with the zip model." + exit 198 + } + } + + if ( `numoutcome`i'' > 1 ) { + di as err "Error: only one variable is allowed for outcome`i'." + exit 198 + } + + if ( `numobsmar`i'' > 1 ) { + di as err "Error: only one variable is allowed for obsmar`i'." + exit 198 + } + + if ( `numtcov`i'' != 0 & `numtcov`i'' / `numindep`i'' != int( `numtcov`i'' / `numindep`i'' ) ) { + di as err "Error: number of variables in tcov`i' and var`i' must match or be a multiple." + exit 198 + } + + if ( `numdcov`i'' != 0 & `numdcov`i'' / `numindep`i'' != int( `numdcov`i'' / `numindep`i'' ) ) { + di as err "Error: number of variables in dcov`i' and var`i' must match or be a multiple." + exit 198 + } + + if (length("`omodel`i''")==0) { + local omodel`i'="none" + } + } + + if ( `plottcov1_len' != 0 & `plottcov1_len' / `numindep1' != int( `plottcov1_len' / `numindep1' ) ) { + di as err "Error: there should be `numtcov1' values for plottcov1." + exit 198 + } + + if ( `numweight1' > 1 ) { + di as err "Error: only one variable is allowed for weight." + exit 198 + } + + forval i = 1/`maxmodels' { + local numorder`i' 0 + tokenize "`order`i''" + while "`1'" != "" { + local numorder`i' = `numorder`i'' + 1 + local c`numorder`i'' `1' + local ordr`i' "`ordr`i'' "`1'"" + mac shift + } + + if ( `numorder`i'' != 0 ) { + matrix traj_mat_order`i' = J( 1, `numorder`i'', 0 ) + tokenize "`order`i''" + forval j = 1/`numorder`i'' { + matrix traj_mat_order`i'[1,`j'] = real("`1'") + mac shift + } + } + + local numiorder`i' 0 + tokenize "`iorder`i''" + while "`1'" != "" { + local numiorder`i' = `numiorder`i'' + 1 + local c`numiorder`i'' `1' + local iordr`i' "`iordr`i'' "`1'"" + mac shift + } + + if ( `numiorder`i'' != 0 ) { + matrix traj_mat_iorder`i' = J( 1, `numiorder`i'', 0 ) + tokenize "`iorder`i''" + forval j = 1/`numiorder`i'' { + matrix traj_mat_iorder`i'[1,`j'] = real("`1'") + mac shift + } + } + + if ( "`model`i''" != "zip" & `numiorder`i'' != 0 ) { + di as err "Error: iorder is only allowed with the zip model." + exit 198 + } + + if ( `numiorder`i'' != `numorder`i'' & `numiorder`i'' != 1 & `numiorder`i'' != 0 ) { + di as err "Error: there should be 1 or `numorder`i'' iorders for iorder`i'." + exit 198 + } + } + + if ( `numrisk1' > 0 ) { + if ( `numorder1' < 2 ) { + di as err "Error: risk is only valid when the number of groups is > 1." + exit 198 + } + } + + if ( `refgroup1' > 1 ) { + if ( `numrisk1' == 0 ) { + di as err "Error: refgroup is only valid when the risk is specified." + exit 198 + } + if ( `refgroup1' > `numorder1' ) { + di as err "Error: refgroup exceeds the number of groups." + exit 198 + } + } + + if ( `refgroup2' > 1 ) { + if ( `numrisk2' == 0 ) { + di as err "Error: refgroup2 is only valid when the risk2 is specified." + exit 198 + } + if ( `refgroup2' > `numorder2' ) { + di as err "Error: refgroup2 exceeds the number of groups." + exit 198 + } + } + + local numrorder1 0 + tokenize "`rorder1'" + while "`1'" != "" { + local numrorder1 = `numrorder1' + 1 + local c`numrorder1' `1' + local rordr1 "`rordr1' "`1'"" + mac shift + } + + if ( `numrorder1' != 0 ) { + matrix traj_mat_rorder1 = J( 1, `numrorder1', 0 ) + tokenize "`rorder1'" + forval i = 1/`numrorder1' { + matrix traj_mat_rorder1[1,`i'] = real("`1'") + mac shift + } + } +/* + if ( `numrorder1' > 0 ) { + di as err "rorder is experimental and may be available. Contact bjones@andrew.cmu.edu" + exit 198 + } +*/ + if ( "`model1'" != "cnorm" & `numrorder1' != 0 ) { + di as err "Error: rorder is only supported for the cnorm model." + exit 198 + } + + local numdropout1 0 + tokenize "`dropout1'" + while "`1'" != "" { + local numdropout1 = `numdropout1' + 1 + local c`numdropout1' `1' + local drpout1 "`drpout1' "`1'"" + mac shift + } + + if ( `numdropout1' != 0 ) { + matrix traj_mat_dropoutorder1 = J( 1, `numdropout1', 0 ) + tokenize "`dropout1'" + forval i = 1/`numdropout1' { + matrix traj_mat_dropoutorder1[1,`i'] = real("`1'") + mac shift + } + } + + local numdropout2 0 + local numdropout3 0 + + cap qui drop _traj_Group + qui gen _traj_Group = . + cap qui drop _traj_Prob* + local out1 "_traj_Group" + forvalues j = 1/`numorder1' { + qui gen _traj_ProbG`j' = . + local out1 "`out1' _traj_ProbG`j'" + } + + local outMat `out1' + + if ( `numorder2' != 0 & `multgroups' == 0 ) { + cap qui drop _traj_Model2_Group + qui gen _traj_Model2_Group = . + local out2 "_traj_Model2_Group" + forvalues j = 1/`numorder2' { + cap qui drop _traj_Model2_ProbG`j' + qui gen _traj_Model2_ProbG`j' = . + local out2 "`out2' _traj_Model2_ProbG`j'" + } + local outMat "`outMat' `out2'" + } +/* + if ( `multgroups' == 0 ) { + forval i = 2/`maxmodels' { + if `numorder`i'' != 0 { + cap qui drop _traj_Model`i'_Group + qui gen _traj_Model`i'_Group = . + local out`i' "_traj_Model`i'_Group" + forvalues j = 1/`numorder`i'' { + cap qui drop _traj_Model`i'_ProbG`j' + qui gen _traj_Model`i'_ProbG`j' = . + local out`i' "`out`i'' _traj_Model`i'_ProbG`j'" + } + local outMat "`outMat' `out`i''" + } + } + } +*/ + forval i = 1/`maxmodels' { + if `numorder`i'' != 0 { + local plotVarLabels`i' "trajT" + + forvalues j = 1/`numorder`i'' { + local plotVarLabels`i' "`plotVarLabels`i'' Avg`j'" + } + forvalues j = 1/`numorder`i'' { + local plotVarLabels`i' "`plotVarLabels`i'' Est`j'" + } + forvalues j = 1/`numorder`i'' { + local plotVarLabels`i' "`plotVarLabels`i'' L95`j'" + local plotVarLabels`i' "`plotVarLabels`i'' U95`j'" + } + } + tokenize "`plotVarLabels`i''" + } + + if `numdropout1' != 0 { + if ( `numdropout1' != 1 & `numdropout1' != `numorder1' ) { + di as err "Error: there should be 1 or `numorder`i'' values for dropout." + exit 198 + } + forvalues j = 1/`numdropout1' { + local plotVarLabels1 "`plotVarLabels1' Dropout`j'" + } + tokenize "`plotVarLabels1'" + } + + tempname b V parmData varData + + matrix parmData = J( 1, 300, 0 ) + matrix varData = J( 300, 300, 0 ) + + forval i = 1/`maxmodels' { + if `numorder`i'' != 0 { + tempname outPlot`i' groupPct`i' + if `numindep`i'' == 4 * `numorder`i'' + 1 + `numdropout`i'' { + matrix outPlot`i' = J( 1 + `numindep`i'', 4 * `numorder`i'' + 1 + `numdropout`i'', . ) + } + else { + matrix outPlot`i' = J( `numindep`i'', 4 * `numorder`i'' + 1 + `numdropout`i'', . ) + } + matrix groupPct`i' = J( 1, `numorder`i'', . ) + } + } + + capture program _traj, plugin using("traj.plugin") +/* + `risk3' `expos3' `tcov3' +*/ + + plugin call _traj `var1' `indep1' `risk1' `weight1' `expos1' /// + `tcov1' `outcome1' `dcov1' `obsmar1' /// + `var2' `indep2' `risk2' `expos2' `tcov2' /// + `var3' `indep3' /// + `outMat' if `touse' `in', /// + `model1' /// + `numindep1' /// + `numrisk1' /// + `numweight1' /// + `numexpos1' /// + `numtcov1' /// + `plottcov1_len' /// + `numorder1' /// + "`min1'" /// + "`max1'" /// + `numiorder1' /// + `numrorder1' /// + `numdropout1' /// + `numdcov1' /// + `numobsmar1' /// + "`omodel1'" /// + `refgroup1' /// + "`model2'" /// + `numindep2' /// + `numrisk2' /// + `numexpos2' /// + `numtcov2' /// + `numorder2' /// + "`min2'" /// + "`max2'" /// + `numiorder2' /// + `refgroup2' /// + "`model3'" /// + `numindep3' /// + `numorder3' /// + "`min3'" /// + "`max3'" /// + `numiorder3' /// + `multgroups' /// + `traj_start_len' /// + `itdetail' /// + `ittrace' /// + `itnovar' /// + `oosprobs' + + ereturn clear + + local np : word count `outvars' + + matrix `b' = parmData[1,1..`np'] + matrix `V' = varData[1..`np', 1..`np'] + + mat colnames `b' = `outvars' + mat rownames `V' = `outvars' + mat colnames `V' = `outvars' + + ereturn post `b' `V', e(`touse') + ereturn local cmd "traj" + + forval i = 1/`maxmodels' { + if `numorder`i'' != 0 { + mat colnames outPlot`i' = `plotVarLabels`i'' + ereturn scalar numGroups`i' = `numorder`i'' + ereturn matrix plot`i' = outPlot`i' + ereturn matrix groupSize`i' = groupPct`i' + } + } + + ereturn local cmdline `"traj `0'"' + +end +/* end of traj.ado */ diff --git a/Modules/ado/plus/t/traj.hlp b/Modules/ado/plus/t/traj.hlp new file mode 100644 index 0000000..c7f9e4a --- /dev/null +++ b/Modules/ado/plus/t/traj.hlp @@ -0,0 +1,204 @@ +{smcl} +{* 14may2012}{...} +{cmd:help traj} +{hline} + +{p 4 4 6}{hi: traj}: Fit the traj model{p_end} +{p 4 4 6}{hi: {help trajplot}}: Plot the traj model results{p_end} + +{marker s_Description} +{title:Description} + +{p 4 4 6} +{cmd:traj} uses a discrete mixture model to model longitudinal data. This model allows for data +grouping using different parameter values for each group distribution. Groupings may identify +distinct subpopulations. Alternatively, groupings may represent components approximating an +unknown (possibly complex) data distribution.{p_end} + +{hline} + +{title:Examples} + + 1:{help traj##s_1: Censored Normal Model} + 2.{help traj##s_2: Zero-Inflated Poisson Model} + 3.{help traj##s_3: Logistic Model} + 4.{help traj##s_4: Time-Stable Covariates for Group Membership} + 5.{help traj##s_5: Group Membership Probabilities from a Model with Time Stable Covariates} + 6.{help traj##s_6: Time-Varying Covariates Influencing Trajectory Paths} + 7.{help traj##s_7: Start Values} + 8.{help traj##s_8: Joint Trajectory Model} + 9.{help traj##s_9: Distal Outcome Model} + 10.{help traj##s_10: Wald Tests for Hypotheses Based on the Parameter Estimates} + 11.{help traj##s_11: Exposure Time / Sample Weights} + 12.{help traj##s_12: Dropout Model} + +{hline} + +{marker s_Syntax} +{title:Syntax} + +{p 6 8 6} +{cmdab:traj} [{help if:{it:if}}]{cmd:, var(}{help varlist:{it:varlist}}{cmd:) indep(}{help varlist:{it:varlist}}{cmd:) model(}{it:modeltype}{cmd:) order(}{help numlist:{it:numlist}}{cmd:)} [additional options] {p_end} + +{synoptset 20 tabbed}{...} +{synopthdr} +{synoptline} +{syntab:Trajectory Variables} +{synopt :{opt var(varlist)}}dependent variables, measured at different times or ages{p_end} +{synopt :{opt indep(varlist)}}independent variables i.e. when the dependant variables were measured{p_end} + +{syntab:Model} +{synopt :{opt model(modeltype)}}probability distribution for the dependent variables: {opt cnorm}, {opt zip}, or {opt logit} {p_end} +{synopt :{opt order(numlist)}}polynomial type (0=intercept, 1=linear, 2=quadratic, 3=cubic) for each group trajectory{p_end} +{synopt :{opt min(#)}}minimum value for the censored normal model (required for cnorm){p_end} +{synopt :{opt max(#)}}maximum value for the censored normal model (required for cnorm){p_end} +{synopt :{opt iorder(numlist)}}optional polynomial type (0=intercept, 1=linear, 2=quadratic, 3=cubic) for the zero-inflation of each group{p_end} +{synopt :{opt exposure(varlist)}}optional exposure variables for the zero-inflated Poisson model{p_end} +{synopt :{opt weight(varname)}}optional sampling weight variable{p_end} + +{syntab:Time-Stable Covariates for Group Membership} +{synopt :{opt risk(varlist)}}covariates for the probability of group membership{p_end} +{synopt :{opt refgroup(#)}}controls the reference group (default = 1) when the risk option is used{p_end} + +{syntab:Time-Varying Covariates for Group Membership} +{synopt :{opt tcov(varlist)}}time-varying covariates for each group trajectory{p_end} +{synopt :{opt plottcov(matrix)}}optional values for plotting trajectories with time-varying covariates{p_end} + +{syntab:Dropout Model} +{synopt :{opt dropout(numlist)}}include logistic model of dropout probability per wave with 0 = constant rate, +1 = depends on the previous response, 2 = depends on the two previous responses, for each group{p_end} +{synopt :{opt dcov(varlist)}}optional lagged time-varying covariates for the dropout model{p_end} +{synopt :{opt obsmar(varname)}}optional binary variable to mark which observations are to be included +in the dropout model and those to be treated as missing at random. This variable = 1 for observations to +be treated as data MAR (include completers) and = 0 for observations to be used for the modeled dropout{p_end} + +{syntab:Distal Outcome Model} +{synopt :{opt outcome(varname)}}a distal variable to be regressed on the probability of group membership{p_end} +{synopt :{opt omodel(modeltype)}}probability distribution for the outcome variable: {opt normal}, {opt cnorm}, {opt zip}, or {opt logit} {p_end} +{synopt :{opt ocov(varlist)}}optional covariates for the outcome model{p_end} + + +{syntab:Joint Trajectory Model} + +{syntab:The joint trajectory model uses the options shown above with a '2' suffix to specify the second model e.g. {opt model2(modeltype)} etc. See the {help traj##s_8:joint trajectories} example.} + +{syntab:Other} +{synopt :{opt start(matrix)}}parameter start values to override default start values{p_end} +{synopt :{opt detail}}show minimization iterations for monitoring model fitting progress{p_end} + +{marker s_1} +{title:Example 1: Censored Normal Model} + +{p 4 10 8}{stata "use http://www.andrew.cmu.edu/user/bjones/traj/data/montreal_sim.dta, clear"}{p_end} +{p 4 10 8}{stata "traj, model(cnorm) var(qcp*op) indep(age*) order(1 3 2) min(0) max(10)"}{p_end} +{p 4 10 8}{stata `"trajplot, xtitle("Age") ytitle("Opposition")"'}{p_end} +{p 4 10 8}{stata `"list _traj_Group - _traj_ProbG3 if _n < 3, ab(12)"'}{p_end} + +{marker s_2} +{title:Example 2: Zero-Inflated Poisson Model} + +{p 4 10 8}{stata "use http://www.andrew.cmu.edu/user/bjones/traj/data/anag1.dta, clear"}{p_end} +{p 4 10 8}{stata "traj, model(zip) var(y*) indep(t*) order(2 0 2 2)"}{p_end} +{p 4 10 8}{stata `"trajplot, xtitle("Scaled Age") ytitle("Annual Conviction Rate") ci"'}{p_end} + +{marker s_3} +{title:Example 3: Logistic Model} + +{p 4 10 8}{stata "use http://www.andrew.cmu.edu/user/bjones/traj/data/cambrdge.dta, clear"}{p_end} +{p 4 10 8}{stata "traj, model(logit) var(p1-p23) indep(tt1-tt23) order(3 3 3)"}{p_end} +{p 4 10 8}{stata `"trajplot, xtitle("Scaled Age") ytitle("Prevalence")"'}{p_end} + +{marker s_4} +{title:Example 4: Time-Stable Covariates for Group Membership} + +{p 4 10 8}{stata "use http://www.andrew.cmu.edu/user/bjones/traj/data/montreal_sim.dta, clear"}{p_end} +{p 4 10 8}{stata "traj, model(cnorm) var(qcp*op) indep(age*) order(1 3 2) min(0) max(10) risk(scolmer scolper)"}{p_end} +{p 4 10 8}{stata `"trajplot, xtitle("Age") ytitle("Opposition")"'}{p_end} + +{marker s_5} +{title:Example 5: Group Membership Probabilities from a Model with Time Stable Covariates} + +{p 4 10 8}{stata "use http://www.andrew.cmu.edu/user/bjones/traj/data/anag1.dta, clear"}{p_end} +{p 4 10 8}{stata "matrix strt = (-4.57, -7, 5.96, -1.38, -20.5, 25.4, -8.0, -4.37, 5.55, -1.52, -1.7, 0, 0, 0, 0, -1.7, 0, 0, 0, 0, -2.5, 0, 0, 0, 0)"}{p_end} +{p 4 10 8}{stata "traj, model(zip) var(y*) indep(t*) order(0 2 2 2) risk(lowiq crimpar daring pbeh) start(strt)"}{p_end} +{p 4 10 8}{stata "list lowiq - _traj_ProbG4 in 1/6, ab(12)"}{p_end} + +{marker s_6} +{title:Example 6: Time-Varying Covariates Influencing Trajectory Paths} + +{p 4 10 8}{stata "use http://www.andrew.cmu.edu/user/bjones/traj/data/gang_data_sim.dta, clear"}{p_end} +{p 4 10 8}{stata "matrix tc1 = (0, 0, 0, 0, 0, 0, 0)"}{p_end} +{p 4 10 8}{stata "matrix tc2 = (0, 0, 0, 1, 1, 1, 1)"}{p_end} +{p 4 10 8}{stata "traj, model(zip) var(bat*) indep(t*) tcov(gang*) order(2 2 2 2 2) plottcov(tc1)"}{p_end} +{p 4 10 8}{stata `"trajplot, xtitle("Scaled Age") ytitle("Rate")"'}{p_end} +{p 4 10 8}{stata "traj, model(zip) var(bat*) indep(t*) tcov(gang*) order(2 2 2 2 2) plottcov(tc2)"}{p_end} +{p 4 10 8}{stata `"trajplot, xtitle("Scaled Age") ytitle("Rate")"'}{p_end} + +{marker s_7} +{title:Example 7: Start Values} + +{p 4 10 8}{stata "use http://www.andrew.cmu.edu/user/bjones/traj/data/cambrdge.dta, clear"}{p_end} +{p 4 10 8}{stata "matrix strt = ( -4.8, -15.5, 16.2, -4.5, -1.1, -4.5, 5.1, -1.3, 0, -.2, 66, 20, 7, 7 )"}{p_end} +{p 4 10 8}{stata "traj , model(zip) var(x01-x23) indep(tt1-tt23) order(0 2 0 2) iorder(1) start(strt)"}{p_end} +{p 4 10 8}{stata `"trajplot, ytitle("Offense Counts") xtitle("Scaled Age")"'}{p_end} + +{marker s_8} +{title:Example 8: Joint Trajectory Model} + +{p 4 10 8}{stata "use http://www.andrew.cmu.edu/user/bjones/traj/data/montreal_sim.dta, clear"}{p_end} +{p 4 10 8}{stata "traj , model(cnorm) var(qcp84op qcp88op qcp89op qcp90op qcp91op) indep(age1-age5) order(1 2 2) max(10) var2(qas91det qas92det qas93det qas94det qas95det) indep2(age3-age7) model2(zip) order2(2 2 2 2)"}{p_end} +{p 4 10 8}{stata `"trajplot, ytitle("Opposition") xtitle("Age")"'}{p_end} +{p 4 10 8}{stata `"trajplot, model(2) ytitle("Rate") xtitle("Age")"'}{p_end} + +{marker s_9} +{title:Example 9: Distal Outcome Model} + +{p 4 10 8}{stata "use http://www.andrew.cmu.edu/user/bjones/traj/data/montreal_sim.dta, clear"}{p_end} +{p 4 10 8}{stata "traj, model(cnorm) max(10) var(qcp84op qcp88op qcp89op qcp90op qcp91op) indep(age1-age5) order(0 2 2) outcome(nbp14) omodel(poisson)"}{p_end} +{p 4 10 8}{stata `"trajplot, ytitle("Opposition") xtitle("Age")"'}{p_end} + +{marker s_10} +{title:Example 10: Wald Tests for Hypotheses Based on the Parameter Estimates} + +{p 4 10 8}{stata "use http://www.andrew.cmu.edu/user/bjones/traj/data/anag1.dta, clear"}{p_end} +{p 4 10 8}{stata "matrix strt = (-4.57, -7, 5.96, -1.38, -20.5, 25.4, -8.0, -4.37, 5.55, -1.52, -1.7, 0, 0, 0, 0, -1.7, 0, 0, 0, 0, -2.5, 0, 0, 0, 0)"}{p_end} +{p 4 10 8}{stata "traj, model(zip) var(y*) indep(t*) order(0 2 2 2) risk(lowiq crimpar daring pbeh) start(strt)"}{p_end} +{p 4 10 8}{stata "trajplot, ci"}{p_end} +{p 4 10 8}{stata "testnl _b[lowiq2] = _b[lowiq3] = _b[lowiq4]"}{p_end} + +{marker s_11} +{title:Example 11: Exposure Time / Sample Weights} + +{p 4 10 8}{stata "use http://www.andrew.cmu.edu/user/bjones/traj/data/weight_expos_sim.dta, clear"}{p_end} +{p 4 10 8}{stata "traj, model(zip) var(g2 - g13) indep(t*) order(2 2) iorder(0 2) expos(e*) weight(wt50)"}{p_end} +{p 4 10 8}{stata `"trajplot, xtitle("Age") ytitle("Annual Arrest Rate")"'}{p_end} + +{marker s_12} +{title:Example 12: Dropout Model} + +{p 4 10 8}{stata "use http://www.andrew.cmu.edu/user/bjones/traj/data/panss.dta, clear"}{p_end} +{p 4 10 8}{stata "traj, var(p1-p6) indep(t1-t6) model(cnorm) min(-999) max(999) order(3 3 0) risk(risper) dropout(2 2 2) dcov(risper risper risper risper risper risper)"}{p_end} +{p 4 10 8}{stata `"trajplot, xtitle("Time (weeks)") ytitle("PANSS") ci"'}{p_end} +{p 4 10 8}{stata `"trajplot, dropout xtitle("Time (weeks)") ytitle("Dropout probability")"'}{p_end} + +{title:Author} + +{p 4 4 6}Bobby L. Jones{p_end} +{p 4 4 6}bjones@andrew.cmu.edu{p_end} + +{p 4 4 6}based on work with Daniel S. Nagin.{p_end} + + +{title:Web-page} + +{p 4 4 6}http://www.andrew.cmu.edu/user/bjones/{p_end} + + +{title:References} + +{p 4 4 6}Jones BL, Nagin DS, Roeder K. 2001. A SAS procedure based on mixture models for estimating developmental trajectories. Sociological Methods & Research 29:374-393{p_end} + +{p 4 4 6}Jones BL, Nagin DS. 2007. Advances in group-based trajectory modeling and an SAS procedure for estimating them. Sociological Methods & Research 35:542-571{p_end} + +{p 4 4 6}Nagin D. 2005. Group-Based Modeling of Development. Cambridge, MA: Harvard Univ. Press{p_end} +{smcl} diff --git a/Modules/ado/plus/t/traj.plugin b/Modules/ado/plus/t/traj.plugin new file mode 100644 index 0000000..4c57031 Binary files /dev/null and b/Modules/ado/plus/t/traj.plugin differ diff --git a/Modules/ado/plus/t/trajplot.ado b/Modules/ado/plus/t/trajplot.ado new file mode 100644 index 0000000..c2b13e3 --- /dev/null +++ b/Modules/ado/plus/t/trajplot.ado @@ -0,0 +1,90 @@ +*! traj Oct 09, 2013 Bobby L Jones + +program trajplot + version 9 + syntax ,[ model(integer 1) xlabel(str) ylabel(str) xtitle(str) ytitle(str) /// + legendLabels(str) CI NOLEGEND DROPOUT ] + preserve + + tempname A plotVarNames + capture confirm matrix e(plot`model') + if _rc != 0 { + display as error "plot data not found" + exit _rc + } + + if "`dropout'" == "dropout" { + if "`ci'" == "ci" { + display "ci not supported for dropout probability" + local ci = "" + } + } + + mat Piv = e(groupSize`model') + mat A = e(plot`model') + svmat A, names(col) + + local ng = e(numGroups`model') + local plotCmd = " " + local orderTxt = " " + + forvalues i = 1/`ng' { + local orderTxt "`orderTxt' `i'" + local pi`i' : display %4.1f round( el( Piv, 1, `i' ), .1 ) + if "`dropout'" == "dropout" { + local plotCmd "`plotCmd' (line Dropout`i' trajT, lwidth(thick))" + } + else { + local plotCmd "`plotCmd' (line Est`i' trajT, lwidth(thick))" + } + local label`i' "`i' `pi`i''%" + } + + if "`ci'" == "ci" { + forvalues i = 1/`ng' { + local plotCmd "`plotCmd' (scatter Avg`i' trajT, mstyle(p`i'))" + local plotCmd "`plotCmd' (line L95`i' trajT, lpattern(dash) lcolor(black))" + local plotCmd "`plotCmd' (line U95`i' trajT, lpattern(dash) lcolor(black))" + } + } + else { + forvalues i = 1/`ng' { + if "`dropout'" == "dropout" { + local plotCmd "`plotCmd' (scatter Dropout`i' trajT, mstyle(p`i'))" + } + else { + local plotCmd "`plotCmd' (scatter Avg`i' trajT, mstyle(p`i'))" + } + } + } + + if "`nolegend'" == "nolegend" { + local plotCmd "`plotCmd', ytitle(`ytitle') xtitle(`xtitle') yscale(titlegap(*5)) xscale(titlegap(*5)) legend(off) ylabel(`ylabel') xlabel(`xlabel') scale(1.2)" + } + else { + local plotCmd "`plotCmd' ,legend(ring(1) cols(2) pos(6) order(`"`orderTxt'"') " + } + + + if "`legendLabels'" != "" & "`nolegend'" == "" { + local plotCmd "`plotCmd' `legendLabels' )" + } + + if "`legendLabels'" == "" & "`nolegend'" == "" { + local plotCmd "`plotCmd' label(1 "`label1'") label(2 "`label2'") label(3 "`label3'") " + local plotCmd "`plotCmd' label(4 "`label4'") label(5 "`label5'") label(6 "`label6'") " + local plotCmd "`plotCmd' label(7 "`label7'") label(8 "`label8'") label(9 "`label9'") " + local plotCmd "`plotCmd' label(10 "`label10'") label(11 "`label11'") label(12 "`label12'") " + local plotCmd "`plotCmd' label(14 "`label14'") label(15 "`label15'") label(16 "`label16'") )" + } + + if "`nolegend'" != "nolegend" { + local plotCmd "`plotCmd' ytitle(`ytitle') xtitle(`xtitle') ylabel(`ylabel') xlabel(`xlabel') yscale(titlegap(*5)) xscale(titlegap(*5)) scale(1.2)" + } + + twoway `plotCmd' + + restore + +end +/* end of trajplot.ado */ diff --git a/Modules/ado/plus/t/trajplot.hlp b/Modules/ado/plus/t/trajplot.hlp new file mode 100644 index 0000000..fb44d95 --- /dev/null +++ b/Modules/ado/plus/t/trajplot.hlp @@ -0,0 +1,31 @@ +{smcl} +{* 10apr2012}{...} +{cmd:help trajplot} +{hline} + +{marker s_Description} +{title:Description} + +{p 4 4 6} +{cmd:trajplot} supports plotting of the {help traj} model results. + +{hline} + +{marker s_Syntax} +{title:Syntax} + +{p 6 8 6} +{cmdab:trajplot} [{cmd:,} {it:options}] {p_end} + +{synoptset 20 tabbed}{...} +{synopthdr} +{synoptline} +{synopt :{opt xtitle(xtitle)}}text for x-axis{p_end} +{synopt :{opt ytitle(ytitle)}}text for y-axis{p_end} +{synopt :{opt xlabel(xlabel)}}x-axis control, see {help axis_label_options}{p_end} +{synopt :{opt ylabel(ylabel)}}y-axis control, see {help axis_label_options}{p_end} +{synopt :{opt ci}}include 95% confidence intervals{p_end} +{synopt :{opt dropout}}plot dropout probabilities{p_end} +{synopt :{opt nolegend}}suppress legend on plot{p_end} + +{smcl} diff --git a/Modules/ado/plus/t/trnclist.ado b/Modules/ado/plus/t/trnclist.ado new file mode 100644 index 0000000..f875120 --- /dev/null +++ b/Modules/ado/plus/t/trnclist.ado @@ -0,0 +1,56 @@ +program def trnclist, rclass +*! NJC 1.2.0 29 June 2000 +* NJC 1.1.0 7 June 2000 +* NJC 1.0.0 3 March 2000 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax , [ Length(numlist int >0) Number(numlist int >0) /* + */ Global(str) Noisily ] + + if "`length'`number'" == "" { + di in r "nothing to do?" + exit 198 + } + else if "`length'" != "" & "`number'" != "" { + di in r "choose between length( ) and number( ) options" + exit 198 + } + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + if "`length'" != "" { + if `length' > 80 { + di in r "cannot handle word length > 80" + exit 498 + } + } + + tokenize `list' + + if "`length'" != "" { + while "`1'" != "" { + local 1 = substr("`1'",1,`length') + local newlist "`newlist'`1' " + mac shift + } + } + else { + while "`1'" != "" { + local 1 = substr("`1'",1,length("`1'")-`number') + local newlist "`newlist'`1' " + mac shift + } + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/t/trnclist.hlp b/Modules/ado/plus/t/trnclist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/t/trnclist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/u/uclist.ado b/Modules/ado/plus/u/uclist.ado new file mode 100644 index 0000000..78f9702 --- /dev/null +++ b/Modules/ado/plus/u/uclist.ado @@ -0,0 +1,32 @@ +program def uclist, rclass +*! NJC 1.0.0 29 June 2000 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax , [ Global(str) Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tokenize `list' + + while "`1'" != "" { + if length("`1'") > 80 { + di in r "cannot handle word length > 80" + exit 498 + } + local 1 = upper("`1'") + local newlist "`newlist'`1' " + mac shift + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/u/uclist.hlp b/Modules/ado/plus/u/uclist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/u/uclist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/u/uniqlist.ado b/Modules/ado/plus/u/uniqlist.ado new file mode 100644 index 0000000..f389568 --- /dev/null +++ b/Modules/ado/plus/u/uniqlist.ado @@ -0,0 +1,43 @@ +program def uniqlist, rclass +*! NJC 1.3.0 7 June 2000 +* NJC 1.2.0 31 Jan 2000 +* NJC 1.1.0 22 Dec 1999 +* NJC 1.0.0 22 Sept 1999 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing ln list" + exit 198 + } + syntax [, Noisily Global(str) ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + tokenize `list' + local newlist "`1'" + mac shift + + while "`1'" != "" { + local nnew : word count `newlist' + local i = 1 + local putin = 1 + while `i' <= `nnew' { + local word : word `i' of `newlist' + if "`word'" == "`1'" { + local putin = 0 + local i = `nnew' + } + local i = `i' + 1 + } + if `putin' { local newlist "`newlist' `1'" } + mac shift + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/u/uniqlist.hlp b/Modules/ado/plus/u/uniqlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/u/uniqlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/u/usesas.ado b/Modules/ado/plus/u/usesas.ado new file mode 100644 index 0000000..bec0779 --- /dev/null +++ b/Modules/ado/plus/u/usesas.ado @@ -0,0 +1,843 @@ +*! usesas Version 2.1 dan.blanchette@duke.edu 15Apr2009 +*! Center of Entrepreneurship and Innovation Duke University's Fuqua School of Business +* - made it so that the describe option returns scalars as promised in the help file. +* usesas Version 2.1 dan.blanchette@duke.edu 26Feb2009 +* - made usesas fail gracefully when there was no SAS dataset in &SYSLAST. when using a SAS program +* instead of a dataset +* usesas Version 2.0 dan.blanchette@duke.edu 24Nov2008 +* - added ".tpt" as a known file extension for SAS transport file since NEBER uses that file extension +* usesas Version 2.0 dan_blanchette@unc.edu 25Mar2008 +* research computing, unch-ch +* - added describe option that loads the metadata of the using dataset into memory +* and displays a Stata-like -describe- description of the using data. +* - made it so that when used with Stata MP savastata treats data like Stata SE +* - fixed it when usesas uses sas programs and the SAS program's last SAS dataset +* is a permanent one then it deletes that file and doesn't fail with odd errors. +* - made it so that when savastata fails by a known error usesas deletes whatever +* intermediary files were created. +* - added error message that -usesas- cannot be run in Stata batch in Windows +* - removed efforts to keep sortedby vars since descending sorts in SAS mess up Stata +* as well as missing values mess up sort order...left it in for --usesas describe-- +* usesas Version 1.4 dan_blanchette@unc.edu 17Apr2007 +* - made it so that if a format catalog file was created for a different OS +* would provide a message to user that that was the case and that the +* SAS formats would not be used to create Stata value labels +* - fixed it so that if in console mode you are not suggested to click something. +* usesas Version 1.4 dan_blanchette@unc.edu 24Aug2006 +* - corrected how the SAS check name was displayed. +* usesas Version 1.4 dan_blanchette@unc.edu 09Nov2005 +* - made usesasdel it's own ado-file +* usesas Version 1.4 dan_blanchette@unc.edu 28Sep2005 +* - stopped savastata from closing user's log if one was open +* usesas Version 1.3 dan_blanchette@unc.edu 04Aug2005 +* - in non-console mode when messy option used, you can now delete all files +* - for Stata 9 new option char2lab that uses my SAS macro char2fmt that converts +* long SAS character variables to numeric with value labels like -encode- does. +* - allow datasets created by proc cport +* NOTE: SAS's CIMPORT procedure will not open a datafile created in later version of SAS +* - use rver() to control sas engine type +* - now passing Stata version to savastata +* - sort order preserved, though data never lost sort order, Stata needs to sort data to know its sort order +* - added float option to allow user to save space with numeric vars that would otherwise +* require being stored in 8-byte double. +* usesas Version 1.2 dan_blanchette@unc.edu 06Jan2005 +* -now accepts an xport file that has a different internal dataset name +** usesas Version 1.1 dan_blanchette@unc.edu 11Nov2004 +* -fixed it so that if() can contain code with double quotes +* e.g: if(`" var="A" "') +* -fixed it so that when a user submitts a SAS program +* only their program is printed in the *_usesas.log file +* and not the whole sasvastata macro code as before +* -deletes non-work SAS dataset created by user's SAS program +* -fix code related to "if" option +* -reduced usage of subinstr to help allow for directory paths and if conditions +* to be longer than 80 characters +** usesas Version 1.0 dan_blanchette@unc.edu 13Jul2004 +* -added mprint and source2 so that user submitted programs +* would appear in the *_usesas.log file +** usesas Version 1.0 dan_blanchette@unc.edu 17Nov2003 +** usesas Version 1.0 dan_blanchette@unc.edu 27Oct2003 +** the carolina population center, unc-ch + + +program define usesas, rclass + version 8 +syntax using/ [, MEssy FORmats xport clear QUotes char2lab CHeck float /// + KEep(string) DEscribe listnot if(string) in(string) ] + +/* log usage of usesas */ +capture which usagelog +if _rc==0 { + usagelog , start type(savas) message(`"usesas using `using', `messy' `formats' `xport' `clear' `quotes' `char2lab' `check' keep(`keep') `describe' `listnot' if(`if') in(`in') "') +} + +if "`c(os)'"=="Windows" & "`c(mode)'" == "batch" { + di as err "{help usesas:usesas} cannot be run in batch mode on Windows" + /* log usage of usesas */ + capture which usagelog + if _rc==0 { + usagelog , type(savas) uerror(8) etime + } + exit 499 +} + +if "`listnot'" != "" & "`describe'" == "" { + di as err "listnot option only allowed when using the descibe option" + /* log usage of usesas */ + capture which usagelog + if _rc==0 { + usagelog , type(savas) uerror(8) etime + } + exit 499 +} + +di `"{txt}The {help usesas:usesas} {txt}command uses the {browse "http://faculty.fuqua.duke.edu/sas_to_stata/savastata.html":savastata} {txt}SAS macro to load the SAS dataset into memory."' +di "{txt}Large datasets may take a few minutes." + +if `c(N)'!=0 & "`clear'"=="" { + di "{error} no, data in memory would be lost" + di "{error} use the {res}clear {error}option" + /* log usage of usesas */ + capture which usagelog + if _rc==0 { + usagelog , type(savas) uerror(1) etime + } + exit 4 +} + +* CAPTURE USER'S LOG +* ------------------ +quietly log query +local usrlog `r(filename)' + +* FIGURE OUT WHERE SAS EXECUTABLE IS +* ---------------------------------- +sasexe usesas + +local wsas `r(wsas)' +local usas `r(usas)' +local savastata `r(savastata)' +local char2fmt `r(char2fmt)' +local rver `r(rver)' // version of sas that's being run i.e. "v8", "v9" etc + + +if index("`using'","'") | index(`"`using'"',`"""') { + di `"{help usesas} {error}cannot handle directory or file names that contain single or double quotes. "' + capture which usagelog + if _rc==0 { + usagelog , type(savas) uerror(2) etime + } + exit 499 +} +/* if filename is given with directory info too, + strip to just file name and to dir location */ + if "`c(os)'"=="Windows" { + local dirsep="\" + if index("`using'","/") { + local using : subinstr local using "/" "\" , all + } + } + else { + local dirsep="`c(dirsep)'" + } + if index("`using'","`dirsep'") { + local filen=substr("`using'",index("`using'","`dirsep'")+1,length("`using'")) + while index("`filen'","`dirsep'") !=0 { + local filen=substr("`filen'",index("`filen'","`dirsep'")+1,length("`filen'")) + } + local dir=substr("`using'",1,index("`using'","`filen'")-1) + } + else if index("`using'","\\\")==1 { /* Universal naming convention */ + local filen=substr("`using'",index("`using'","\\\")+2,length("`using'")) + while index("`filen'","\") !=0 { + local filen=substr("`filen'",index("`filen'","\")+1,length("`filen'")) + } + local dir=substr("`using'",1,index("`using'","`filen'")-1) + } + else { /* no directory given */ + local filen="`using'" + local dir ="`c(pwd)'`dirsep'" + } + + + /** extract file extension if there is one **/ +if index("`filen'",".") { + local ext=substr("`filen'",index("`filen'","."),length("`filen'")) + while index("`ext'",".") > 0 { + local ext=substr("`ext'",index("`ext'",".")+1,length("`ext'")) + } + local ext=".`ext'" + local middle=substr("`filen'",1,index("`filen'","`ext'")-1) /* middle will not end in a period */ + local filen=substr("`filen'",1,index("`filen'",".")-1) + local middle=substr("`middle'",length("`filen'")+1,length("`middle'")) +} + +if lower("`ext'")==".sas7bdat" { + local type="sas" +} +else if lower("`ext'")==".sd7" { + local type="sas" + local shortfileext="shortfileext" +} +else if lower("`ext'")==".ssd01" { + local type="sas6" +} +else if lower("`ext'")==".ssd02" { + local type="sas6" +} +else if lower("`ext'")==".sd2" { + local type="sas6" +} +else if lower("`ext'")==".sas" { + local type="sasprogram" +} +else if lower("`ext'")==".por" { + local type="spss" +} +else if lower("`ext'")==".xpt" | /// + lower("`ext'")==".xport" | /// + lower("`ext'")==".export" | /// + lower("`ext'")==".expt" | /// + lower("`ext'")==".exp" | /// + lower("`ext'")==".trans" | /// + lower("`ext'")==".tpt" | /// + lower("`ext'")==".cport" | /// + lower("`ext'")==".ssp" | /// + lower("`ext'")==".stx" | /// + lower("`ext'")==".sasx" | /// + lower("`ext'")==".v5x" | /// + lower("`ext'")==".v6x" { + local type="sasx" +} +else if "`xport'"=="xport" { // else no file extension + local type="sasx" +} +else { // guess that the user is wanting to use a .sas7bdat file + local using1 `"`using'.sas7bdat"' + local ext ".sas7bdat" + local type="sas" + capture confirm file `"`using1'"' + if _rc != 0 { + di `"{error}The SAS file: `using1' does not exist."' + // check that user is not expecting file extention but forgot to use xport option + capture confirm file `"`using'"' + if _rc == 0 { + di `"{error}But the SAS file: `using' does exist."' + di as text `"Use the xport option as it is likely this file is a transport/xport file."' + } + /* log usage of usesas */ + capture which usagelog + if _rc==0 { + usagelog , type(savas) uerror(3) etime + } + exit 601 + } + // only here if this file does exist + local using `"`using'.sas7bdat"' +} + +capture confirm file `"`using'"' +if _rc != 0 { + di `"{error}The SAS file: `using' does not exist."' + /* log usage of usesas */ + capture which usagelog + if _rc==0 { + usagelog , type(savas) uerror(3) etime + } + exit 601 +} + +if "`type'"=="" { + di "{error}Is `using' a SAS transport/xport data file?" + di "{error}If so then use the {res}xport {error}option." + /* log usage of usesas */ + capture which usagelog + if _rc==0 { + usagelog , type(savas) uerror(4) etime + } + + exit 499 +} + + +if "`type'"=="sas" { + local engine="`rver'" // whatever version of SAS that's being used +} +else if "`type'"=="sas6" { + local engine="v6" +} +else if "`type'"=="sasprogram" { + local sasprogram="sasprogram" +} +else if "`type'"=="sasx" { + local engine="xport" +} +else if "`type'"=="spss" { + local engine="spss" +} + +/* set where temp directory is */ +tmpdir +local tmpdir="`r(tmpdir)'" + + +local tfn=subinstr("`c(current_time)'",":","",.) +local sysjobid=substr("`tfn'",length("`tfn'")-5,length("`tfn'")) +local temp `"`macval(tmpdir)'_`sysjobid'"' +local raw `"`macval(tmpdir)'_`sysjobid'_usesas"' +local xpt "`macval(dir)'`filen'`middle'`ext'" + + +* MAKE "IF" AND "IN" INTO SAS CODE +* -------------------------------- +local firstobs = upper(substr("`in'",1,index("`in'","/")-1)) +if "`firstobs'" == "F" | index("`firstobs'","-") { + di `"{error}Your 'in()' option cannot use f/F or negative values. "' + exit 100 +} +local obs = upper(substr("`in'",index("`in'","/")+1,length("`in'"))) +if "`obs'" == "L" { + di `"{error}Your 'in()' option cannot use l/L. "' + exit 100 +} + +if `"`if'"'!=`""' { + local iflen : length local if + if `iflen'>247 { // 255-6-wiggle room = 247 + // 'if()' option needs to be less than 255 characters for SAS to process, it is limited to max length of string + di `"{error}Your 'if()' option is longer than max length of 247. "' + exit 100 + } + else { // okay to process + if index(`"`if'"',"==") { + local if : subinstr local if "==" "=" , all + } + if lower(substr(`"`if'"',1,3)) != `"if "' & lower(substr(`"`if'"',1,6)) != `"where "' { + local if `"where `if'"' + } + else if lower(substr(`"`if'"',1,3)) == `"if "' { + di `"{error}Your 'if()' option starts with "if". The "if" is assumed, do not type it."' + exit 100 + } + /* now make sure if has only one 'if' or 'where' in it */ + if index(lower(`"`if'"')," if ") | index(lower(`"`if'"')," inrange(") | /* + */ index(lower(`"`if'"')," inlist(") | index(lower(`"`if'"')," where ")>1 { + di `"{error}Invalid SAS 'if' condition."' + capture which usagelog + if _rc==0 { + usagelog , type(savas) uerror(5) etime + } + exit 499 + } + } // 'if()' is less than 247 chars +} + + + +* WRITE SAS PROGRAM TO READ IN DATA +* --------------------------------- +usesas_sas , rver(`rver') dirsep("`dirsep'") dir("`dir'") tmpdir("`tmpdir'") filen(`filen') raw("`raw'") engine(`engine') /// + `shortfileext' `quotes' `check' `formats' sysjobid(`sysjobid') ext(`ext') middle(`middle') xpt("`xpt'") /// + savastata("`savastata'") if(`"`if'"') firstobs(`firstobs') obs(`obs') keep(`"`keep'"') /// + `char2lab' char2fmt("`char2fmt'") `sasprogram' `describe' `listnot' + + + * RUN SAS + * ------- + if "`c(os)'"=="Unix" /* or Linux */ { + shell "`usas'" "`temp'_usesas.sas" -log "`temp'_usesas.log" -print "`temp'_usesas.lst" + } /* end of if Unix */ + else if "`c(os)'"=="Windows" /* Windows */ { + ** do not add -icon option since that pop-up window is not a big deal and could tell user important info ** + shell `wsas' "`temp'_usesas.sas" -nologo -log "`temp'_usesas.log" -print "`temp'_usesas.lst" + } /* end of if Windows */ + +* LOOK AT ANY REPORT FROM SAS +* --------------------------- +capture confirm file `"`temp'_report.log"' +if _rc==0 { + type `"`temp'_report.log"' + if "`messy'"=="" { + erase `"`temp'_report.log"' + } +} + +* CLEAR DATA OUT OF MEMORY +* ------------------------ + if "`clear'"!="" { + drop _all + label drop _all + } + + +* LOAD STATA DATASET INTO MEMORY +* ------------------------------ + capture confirm file `"`tmpdir'_`sysjobid'_infile.do"' + if _rc == 0 { + if `"`usrlog'"' != "" { + quietly log close + } + local cwd "`c(pwd)'" + ** cd to where infile.do is ** + quietly cd "`tmpdir'" + run `"_`sysjobid'_infile.do"' + if `"`usrlog'"' != "" { + quietly log using `"`usrlog'"' , append + } + + * SET DATASET NAME + * ---------------- + if index("$S_FN","`dirsep'") == 1 { + global S_FN : subinstr global S_FN "`dirsep'" "" + } + global S_FN `"`macval(dir)'$S_FN"' + + // run savastata_report to see if SAS and Stata agree how many obs and vars there are + savastata_report + + if "`check'" != "" { + local gsfn : subinstr global S_FN ".dta" "" + display as res _n " Compare these results with the results provided by SAS " + display as res " in the file `gsfn'_SAScheck.lst. " _n + summarize + describe + list in 1/5 + + di _n "You have requested to have savastata provide a check file:" + di `""`gsfn'_SAScheck.lst" "' + } + + + ** cd back to where you were ** + quietly cd "`cwd'" + } /* if infile.do file exists */ + else { + di `"{error}{help usesas:usesas} failed."' + capture confirm file `"`tmpdir'_`sysjobid'_knerror.txt"' + if _rc ==0 { + // savastata failed with a known error so just let report.log show the error + if "`c(os)'" != "Windows" { + usesasdel `"`tmpdir'"' _`sysjobid'_ + } + if "`c(os)'" == "Windows" { + local usesasdeldir : subinstr local tmpdir `":"' `"\\\`= char(58)'"', all + usesasdel `"`usesasdeldir'"' _`sysjobid'_ + } + } + else { + di `"{error}If no error message above this one, then check out the SAS log file to see why. "' + di `" {view "`temp'_usesas.log"} "' + di `"{inp}Erase these temporary files created by {help usesas:usesas} when done with them:"' + di `"{res}(files located in "`tmpdir'") "' + ls "`temp'_*" + if "`c(console)'" != "console" { + if "`c(os)'" != "Windows" { + di `"{res} {stata usesasdel `"`tmpdir'"' _`sysjobid'_:Click here to erase them all.} "' + } + if "`c(os)'" == "Windows" { + local usesasdeldir : subinstr local tmpdir `":"' `"\\\`= char(58)'"', all + di `"{res} {stata usesasdel `"`usesasdeldir'"' _`sysjobid'_:Click here to erase them all.} "' + } + } + } + + if "`sasprogram'"!="" { + di `""' + if "`c(console)'" != "console" { + di `"{inp}Click here to edit your SAS program and try it again. "' + di `" {stata `"doedit "`xpt'""':`xpt'} "' + } + else di `"Edit your SAS program: "`xpt'" and try it again."' + di `""' + } + capture which usagelog + if _rc==0 { + usagelog , type(savas) uerror(6) etime + } + exit 499 + } + +if "`describe'" == "describe" { + di as res `"Contains data from "`using'" "' + di as res `" obs: `=string(nobs,"%32.0fc")' "' memlabel + di as res `" vars: `=string(_N,"%32.0fc")' "' + if ( _N > 2047 & "$S_StataSE"=="" & "$S_StataMP" == "" ) | /// + ( _N > 32767 ) { + di as err "Your version of Stata will not read this entire dataset" + if ( _N > 2047 & "$S_StataSE"=="" & "$S_StataMP" == "" ) /// + di as err " as it has more than 2,047 variables." + else if ( _N > 32767 ) /// + di as err " as it has more than 32,767 variables." + } // this message is repeated after all vars are listed + local name_len = `= substr("`: type name'",index("`: type name'","r")+1,2)' + if `name_len' < 13 recast str13 name + recast str12 type + char define name[varname] "variable name" + char define type[varname] "storage type" + char define label[varname] "variable label" + order varnum name type format label + if "`listnot'" == "" { + list name type format label, nocompress noobs subvarname + } + capture confirm file `"`macval(temp)'_usesas.txt"' + if _rc ==0 { + file open sortedby using `"`temp'_usesas.txt"' , read text + file read sortedby sortedby // creates local sortedby + file close sortedby + // clear sortedby if no vars in it, it ends up being a double quote + if `"`sortedby'"' == `"""' local sortedby "" + } + di as res `"Sorted by: `sortedby'"' + if "`listnot'" == "" { + if ( _N > 2047 & "$S_StataSE"=="" & "$S_StataMP" == "" ) | /// + ( _N > 32767 ) { + di as err "Your version of Stata will not read this entire dataset" + if ( _N > 2047 & "$S_StataSE"=="" & "$S_StataMP" == "" ) /// + di as err " as it has more than 2,047 variables." + else if ( _N > 32767 ) /// + di as err " as it has more than 32,767 variables." + } // this message is made first before all vars are listed + } + // these vars do not vary by obs so just drop 'em + quietly drop memlabel // nobs dropped at end of usesas + di as res _n _dup(`c(linesize)') "-" + di as res `" Now the dataset in memory is just the description of "`using'" "' + di as res `" Use the {stata describe :describe} command to see what you have and use "' + di as res `" whatever data manipulation you like to create variable lists for "' + di as res `" your actual invocation of {help usesas :usesas} if you want."' + if "`c(console)'" != "console" { + di as res `" Otherwise, {stata clear :Click here to clear out the dataset from memory}. "' + } + else { + di as res `" Otherwise, use the clear command to clear out the dataset from memory. "' + } + di as res _dup(`c(linesize)') "-" +} + + +* CLEAN UP TEMP FILES +* ------------------- + if "`messy'"=="" { + if "`c(os)'" != "Windows" { + usesasdel `"`tmpdir'"' _`sysjobid'_ + } + if "`c(os)'" == "Windows" { + local usesasdeldir : subinstr local tmpdir `":"' `"\\\`= char(58)'"', all + usesasdel `"`usesasdeldir'"' _`sysjobid'_ + } + } /* end of messy=="" */ + else { + di "{res}You have requested {help usesas:usesas} not to delete the intermediary files created by {help usesas:usesas}:" + dir "`temp'_*" + di "{input}Files located here: " + di `"{input}"`tmpdir'" "' + + if "`c(console)'" != "console" { + if "`c(os)'" != "Windows" { + di `"{res} {stata usesasdel `"`tmpdir'"' _`sysjobid'_:Click here to erase them all.} "' + } + if "`c(os)'" == "Windows" { + local usesasdeldir : subinstr local tmpdir `":"' `"\\\`= char(58)'"', all + di `"{res} {stata usesasdel `"`usesasdeldir'"' _`sysjobid'_:Click here to erase them all.} "' + } + } + } // of if else if messy + + + +/* log usage of usesas */ +capture which usagelog +if _rc==0 { + if `c(N)' == 0 & `c(k)' == 0 { + usagelog , type(savas) uerror(7) message(no data) etime + } + else { + local obs=`c(N)' + local vars=`c(k)' + usagelog , type(savas) uerror(0) message(Input Stata dataset has `obs' obs and `vars' vars) etime + } +} +if "`describe'" == "describe" { + local varlist = "" + local vlen=0 + forvalues n = 1/`= _N' { + local vlen = `vlen' + length(trim("`= name[`n']'")) + 1 + if `n' == 1 local varlist = trim("`= name[`n']'") + else local varlist `"`varlist' `= trim("`= name[`n']'")'"' + } + if `vlen' > `c(max_macrolen)' { + di as err "not all the variables are in r(varlist) since there are too many " + } + return local varlist "`varlist'" + return local sortlist "`sortedby'" + return scalar k = _N + return scalar N = `= nobs[1]' + drop nobs +} + + +end /* end of usesas */ + + +program define usesas_sas, nclass +syntax [, QUotes engine(string) rver(string) dirsep(string) dir(string) tmpdir(string) filen(string) /// + shortfileext xpt(string) replace raw(string) FORmats sysjobid(string) CHeck ext(string) middle(string) /// + savastata(string) if(string) firstobs(string) obs(string) keep(string) sasprogram /// + char2lab char2fmt(string) float describe listnot ] + version 8 + + +quietly { + file open sasfile using `"`raw'.sas"', replace text write + + * DATA LIST + * --------- + + file write sasfile `"* SAS program to read file and output Stata dataset *;"' /// + _n _n `"options nofmterr nocenter linesize=250;"' /// + _n _n `"%let badx =0; ** if proc cimport has trouble with xport file **; "' _n _n /// + _n _n `"%include "`savastata'"; "' _n _n + + if "`char2lab'" != "" { + file write sasfile `"%include "`char2fmt'"; "' _n _n + } + + if "`sasprogram'"!="" { /* user submitted a SAS program */ + file write sasfile `"options mprint source2; "' _n _n /// + `" /*************** THE FOLLOWING IS YOUR PROGRAM ***************/ "' _n _n /// + `" %include"`xpt'"; "' _n _n /// + `" /*************** END OF YOUR PROGRAM ***************/ "' _n _n /// + `"options nomprint nosource2; "' _n _n + file write sasfile `" %let sortedby=; ** leave in for now **; "' _n _n /// + `"%macro makework; "' _n /// + `" %if &syserr.^=0 %then %goto nevrmind; "' _n /// + `" %if &syslast.=_NULL_ %then %goto nevrmind; "' _n /// + `" %let ldset=%length(&syslast.); "' _n /// + `" %let decpos=%index(&syslast.,.); "' _n /// + `" %let llib=%substr(&syslast.,1,&decpos.-1); "' _n /// + `" %let dset=%substr(&syslast.,&decpos.+1,&ldset.-&decpos.); "' _n /// + `" %let dset=%sysfunc(lowcase(%nrbquote(&dset.))); "' _n _n + file write sasfile `" data _null_; "' _n /// + `" dsid=open("&syslast.",'i');"' _n `" sortedby=attrc(dsid,'SORTEDBY'); "' _n /// + `" call symput('sortedby',trim(sortedby));"' _n `" rc=close(dsid);"' _n `"run;"' _n _n + file write sasfile `" %if %index(%upcase(&sortedby.),DESCENDING) %then %do; "' _n /// + `" %* this is how Stata treats descending sortedby *; "' _n /// + `" %let sortedby= %substr(&sortedby.,1,%index(%upcase(&sortedby.),DESCENDING)-1); %end;"' _n _n + file write sasfile `" ** if not in work make it be in work **; "' _n /// + `" %if %index(%upcase(&syslast.),WORK)^=1 %then %do; "' _n /// + `" data work.&dset.; "' _n /// + `" set &syslast.;"' _n `" run; "' _n /// + `" proc datasets library=&llib.;"' _n `" delete &dset.;"' _n `" run; quit;"' _n /// + `"%end; ** end of if syslast is not in WORK **; "' _n _n + if "`keep'"!="" | "`firstobs'"!="" | length(`"`if'"')>5 { + /** apply subsetting to work dataset **/ + file write sasfile `" data work.&dset."' _n + if "`keep'"!="" { + file write sasfile `" (keep=`keep' &sortedby.) "' + } + file write sasfile `";;; "' _n /// + `" set &dset."' + if "`firstobs'"!="" { + file write sasfile `"(firstobs=`firstobs' obs=`obs')"' _n + } + file write sasfile `";;; "' _n + if length(`"`if'"')>5 /* b/c "where" has 5 letters */ { + file write sasfile `" `if'; "' _n + } + file write sasfile `"run; "' _n + } + file write sasfile `" %nevrmind: ; "' _n /* + */ `"%mend; "' _n /* + */ `"%makework; "' + } + else if "`sasprogram'"=="" { /* write SAS program to feed SAS data set into savastata */ + if "`formats'"!="" { + if "`engine'"=="v6" { + file write sasfile `"libname library v6 "`dir'" ; "'_n _n + } + else { + file write sasfile `"libname library `engine' "`dir'" `shortfileext'; "'_n _n + } + } + if "`engine'"=="`rver'" | "`engine'"=="v6" { + file write sasfile `"libname ___in___ `engine' "`dir'" `shortfileext' ; "'_n _n + // preserve sort order + // Transport datasets cannot be opened and they do not save sort info anyway + file write sasfile `"%let sortedby=; "' _n _n `"data _null_;"' _n `" dsid=open('___in___.`filen'','i');"' _n /// + `" sortedby=attrc(dsid,'SORTEDBY'); "' _n `" call symput('sortedby',trim(sortedby));"' _n `" rc=close(dsid);"' _n `"run;"' _n _n /// + `" %macro __sort; %if %index(&sortedby.,DESCENDING) %then %sysfunc(tranwrd(&sortedby.,%str(DESCENDING ),-)); "' /// + `" %mend __sort; %__sort; "' + } // end of normal SAS dataset + else if "`engine'"=="xport" { // test xport file to see if created by cimport + // Transport datasets cannot be opened and they do not save sort info anyway + file write sasfile `"%let sortedby=; "' + file write sasfile `"filename ___in___ "`xpt'"; "' _n _n /// + `"%macro ___xt___ ;"' _n `" data _null_; "' _n `" infile ___in___ ; "' _n `" input xt $ 1-6; "' _n /// + `" call symput('header',xt); "' _n `" if _n_ = 1 then stop; "' _n `" run; "' _n + file write sasfile `" %if %index(&header.,HEAD) ^= 0 %then %do; "' _n _n /// + `" libname ___in___ xport "`xpt'"; "' _n _n + file write sasfile `" data _null_;"' _n `" set sashelp.vmember; "' _n /// + `" if upcase(libname)="___IN___" and upcase(memtype)="DATA" then call symput("filen",memname); "' _n + file write sasfile `" run;"' _n _n `" data `filen'; "' _n `" set ___in___.&filen.;"' _n /// + `" run; "' _n `" %end; "' _n + file write sasfile `" %else %do;"' _n `" proc cimport data=`filen' infile=___in___; "' _n /// + `" run; "' _n `" %if &syserr. ^=0 %then %do; "' _n /// + `" proc printto log="`tmpdir'_`sysjobid'_report.log"; options nonotes; "' _n /// + `" data _null_; "' _n /// + `" put "ERROR: SAS could not open `filen' because it was created in a newer version of SAS *"; "' _n /// + `" put " or there is not just a data set named `filen' in the file. *"; "' _n /// + `" run; proc printto; ** end printing to *_report.log "' _n /// + `" %let badx=1; %end; "' _n `"%end; "' _n `"%mend ___xt___;"' _n _n `"%___xt___; ** now run macro ___xt___ ***; "' /// + _n _n + + } + + if "`engine'"!="spss" { + if "`formats'"!="" { + /* look for datasetname.formatscatalog file */ + local rc=1 + if ("`engine'"=="`rver'" | "`engine'"=="xport") & "`shortfileext'"=="" { + capture confirm file `"`macval(dir)'`filen'.sas7bcat"' + if _rc ==0 { + local rc=0 + } + } + else if ("`engine'"=="`rver'" | "`engine'"=="xport") & "`shortfileext'"!="" { + capture confirm file `"`macval(dir)'`filen'.sc7"' + if _rc ==0 { + local rc=0 + } + } + else if "`engine'"=="v6" & "`c(os)'"=="Unix" { + capture confirm file `"`macval(dir)'`filen'.sct01"' + if _rc ==0 { + local rc=0 + } + } + else if "`engine'"=="v6" & "`c(os)'"=="Windows" { + capture confirm file `"`macval(dir)'`filen'.sc2"' + if _rc ==0 { + local rc=0 + } + } + if `rc'==0 { + file write sasfile _n `"%macro __fmt__;"' /// + `" %if %sysfunc(cexist(LIBRARY.`filen')) = 1 %then %do;"' _n /// + `" options fmtsearch=(library.`filen' library.formats); "' _n _n /// + `" proc datasets; "' _n /// + `" copy in=library out=work memtype=catalog; "' _n /// + `" select `filen'; "' _n /// + `" change `filen'=formats;"' _n /// + `" run; quit;"' _n /// + `" %end; "' _n /// + `" %else %do; "' _n /// + `" proc printto log="`tmpdir'_`sysjobid'_report.log"; options nonotes; "' _n /// + `" data _null_; "' _n /// + `" put "ERROR: File LIBRARY.`filen'.CATALOG was created for a different operating system. *" ; "' _n /// + `" put "ERROR: -usesas- did not create Stata value labels from SAS formats. *"; "' _n /// + `" run; proc printto; ** end printing to *_report.log "' _n /// + `" %end; "' _n /// + `"%mend __fmt__; "' _n /// + `"%__fmt__; "' _n + + } /* if filen.catalog file exists */ + } /* end of if "`formats'"!="" */ + + file write sasfile _n `"data `filen'"' + if "`keep'"!="" { + file write sasfile `" (keep=`keep' &sortedby.) "' + } + if "`engine'" == "xport" { + file write sasfile `";;;"' _n `" set work.`filen' "' // 08Apr2005 use `filen' in work lib + + } + else { + file write sasfile `";;;"' _n `" set ___in___.`filen' "' + } + + if "`firstobs'"!="" { + file write sasfile `"(firstobs=`firstobs' obs=`obs')"' _n + } + file write sasfile `";;; "' _n + if length(`"`if'"')>5 /* b/c "where" has 5 letters */ { + file write sasfile `" `if'; "' _n // + } + file write sasfile `"run; "' _n + } + else { + file write sasfile `"filename spss "`xpt'"; "' _n _n /* + */ `"proc convert spss=spss out=`filen'; "' _n /* + */ `"run; "' + file write sasfile _n `"data `filen'"' + if "`keep'"!="" { + file write sasfile `" (keep=`keep') "' + } + file write sasfile `";;;"' _n `" set `filen' "' + if "`firstobs'"!="" { + file write sasfile `"(firstobs=`firstobs' obs=`obs')"' _n + } + file write sasfile `";;; "' _n + if length(`"`if'"')>5 /* b/c "where" has 5 letters */ { + file write sasfile `" `if'; "' _n // + } + file write sasfile `"run; "' _n + } + } /* end of if no sas program submitted */ + + if `c(stata_version)' < 9 & "`char2lab'" != "" { + noisily { + di as error `"option char2lab is not allowed prior to Stata 9."' + di as error `"option will be ignored."' + local char2lab "" + } + } + file write sasfile _n _n /// + `"%macro runit;"' _n `" %if &badx.=0 %then %do; "' + if "`describe'" == "describe" { + file write sasfile _n /// + _n `" proc contents data=`filen' out=`filen'(keep=name varnum type label format "' /// + `" nobs length memlabel) noprint; run; "' + file write sasfile _n /// + _n `" data `filen'(drop=type rename=(stype=type)); "' + // truncate long string vars just to make life simple + if `c(stata_version)' < 9.2 & "$S_StataSE" == "" & "$S_StataMP" == "" { + file write sasfile _n `" length label memlabel $80; "' + } + else { + file write sasfile _n `" length label memlabel $244; "' + } + file write sasfile /// + _n `" set `filen'; "' /// + _n `" if type =1 then stype="numeric"; "' /// + _n `" if type =2 then stype="string "; "' /// + _n `" label stype = "Variable Type"; "' /// + _n `" run; "' + file write sasfile /// + _n `" data _null_; "' /// + _n `" file "`tmpdir'_`sysjobid'_usesas.txt"; "' /// + _n `" put "%trim(&sortedby.)"; "' /// + _n `" run;"' + + file write sasfile _n /// + _n `" proc sort data=`filen'; by varnum; run; "' + file write sasfile _n /// + _n `" %let sortedby=varnum; "' + + } // end of if describe + // need to put c(SE) and c(MP) in quotes since c(MP) doesn't exist in Stata 8 + // need to pass a zero or a one to savastata for SE or MP + file write sasfile `" libname ___dir__ "`dir'" ; "' _n /// + `" %let _dir=%nrbquote(%sysfunc(pathname(___dir__))); "' _n /// + `" /* &sortedby. is global because of: call symput creates it */ "' _n /// + `" %savastata("`tmpdir'",`quotes' `char2lab' `check' messy `float', &sortedby., "' /// + `" `sysjobid',nosave,"&_dir.`dirsep'",`= ("`c(SE)'" == "1") + ("`c(MP)'" == "1")', "' /// + `" version=`c(stata_version)'); "' _n /// + `"%end; %* if &badx.=0 *; %mend runit;"' _n `" %runit;"' _n _n + + file close sasfile + +} /* end of quietly */ +end + +exit + diff --git a/Modules/ado/plus/u/usesas.hlp b/Modules/ado/plus/u/usesas.hlp new file mode 100644 index 0000000..269fb93 --- /dev/null +++ b/Modules/ado/plus/u/usesas.hlp @@ -0,0 +1,213 @@ +{smcl} +{* version 2.1 26Feb2009}{...} +{* 24Aug2006}{...} +{* 04Aug2005}{...} +{* 05Nov2003}{...} +{hline} +help for {hi:usesas} {right:manual: {hi:[R] none}} +{right:dialog: {hi: none} } +{hline} + + +{title:Use a SAS dataset} + +{p 8 17 2}{cmd:usesas} +{cmd:using} {it:filename} +[{cmd:,} +{cmdab:for:mats} +{cmd:char2lab} +{cmdab:ch:eck} +{cmd:clear} +{cmd:float} +{cmd:xport} +{cmdab:de:scribe} +{cmdab:ke:ep(}{it:variable names}{cmd:)} +{cmd:if(}{it:SAS if statement}{cmd:)} +{cmd:in(}{it:firstobs/lastobs}{cmd:)} +{cmdab:qu:otes} +{cmdab:me:ssy} +]{p_end} + + +{title:Description} + +{p 4 8 2} {cmd:NOTE:} Before the first use of {cmd:usesas} your {cmd:sasexe.ado} file may need to be edited to set +the location of your SAS executable file (sas.exe) and your savastata SAS macro file (savastata.sas). It may be +that {cmd:usesas} will be able to run with the default settings in {cmd:sasexe.ado}.{p_end} + +{p 4 4 2} {cmd:usesas} loads a SAS datafile into memory. This usually occurs by supplying {cmd:usesas} a SAS +dataset (*.sas7bdat, *.sd7, *.sd2, *.ssd01, *.xpt, *.cport) or an SPSS portable file (*.por), +but {cmd:usesas} can also load a SAS datafile into memory via a SAS program (*.sas) that creates a +SAS dataset. The last dataset created by the SAS program will be the SAS dataset processed by {cmd:usesas}.{p_end} + +{p 4 4 2}{cmd:usesas} assumes the most common SAS datafile extension {cmd:.sas7bdat} if no file extension/suffix is +specified.{p_end} + +{p 4 4 2}{cmd:usesas} uses the savastata SAS macro to create the Stata dataset from the SAS +dataset. {cmd:usesas} downloads the savastata SAS macro and stores it where user-written +Stata ado-files are stored that begin with the letter "s". This macro can be used in SAS. +Learn about savastata here: +{browse "http://faculty.fuqua.duke.edu/home/blanc004/data_programming/sas_to_stata/savastata.html": http://faculty.fuqua.duke.edu/home/blanc004/data_programming/sas_to_stata/savastata.html}{p_end} + +{p 4 4 2}{cmd:usesas} figures out how much memory the SAS dataset will require to be loaded into Stata +and sets Stata's memory for you if your memory setting is less than is required.{p_end} + +{p 4 4 2}{cmd:usesas} indicates that it has finished running by reporting to you how many observations +and variables are in your dataset now in memory. For example:{p_end} + +{p 4 8}Stata reports that the dataset has 200 observations and 11 variables.{p_end} + +{p 4 8 2}{cmd:NOTE: usesas} calls SAS to run a SAS program. This requires the ability to run SAS on your computer.{p_end} + + +{title:Options} + +{p 4 8 2}{cmd:formats} specifies to create value labels from SAS user-defined formats that are stored +in a SAS formats catalog file that has the same name as the dataset and is in the same directory +as the SAS dataset. For example: MySasData.sas7bcat . If this file doesn't exist, {cmd:usesas} will +look for the file formats.sas7bcat in the same directory as the dataset.{p_end} + +{p 4 8 2}{cmd:char2lab} specifies to encode long SAS character variables like the Stata +command {help encode :encode}. Character variables that are too long for a Stata string +variable are maintained in value labels. This is all done with the {cmd:char2fmt} SAS +macro.{p_end} + +{p 4 8 2}{cmd:check} specifies to generate basic stats for both datasets for the user to compare the +newly created Stata dataset with the imported SAS dataset to make sure {cmd:usesas} created the files +correctly. This is a comparison that should be done after any datafile is converted to any other +type of datafile by any software. The SAS file is created in the same directory as the input SAS +datafile and is named starting with the name of the datafile followed by "_SAScheck.lst" +(SAS). e.g. "mySASdata_SAScheck.lst"{p_end} + +{p 4 8 2}{cmd:clear} specifies to clear the data currently in memory before running {cmd:usesas}.{p_end} + +{p 4 8 2}{cmd:float} specifies that numeric variables that would otherwise be stored as numeric type +double be stored with numeric type float. This option should only be used if you are certain you +have no integer variables that have more than 7 digits (like an ID variable).{p_end} + +{p 4 8 2}{cmd:xport} specifies that the input dataset is a SAS Transport/Xport dataset. Since there +is no standard file extension for SAS Xport datasets, this option is required. Datasets created +by SAS's PROC CPORT procedure are allowed.{p_end} + +{p 4 8 2}{cmd:describe} makes {cmd:usesas} act somewhat like the Stata command +{help describe :describe using}. It does not bring the full dataset into memory. Instead it specifies for +{cmd:usesas} only to load the descriptive information about the using dataset into Stata's memory as a +Stata dataset and print it. So, instead of loading the actual dataset into Stata, {cmd:usesas} loads +the descriptive information (variable names, what type of variables they are, the variable labels and +formats associated to the variables) into Stata as a dataset. You can {help clear :clear} the +descriptive data out of Stata's memory or use the descriptive data however you like to create variable +lists for your actual invocation of {cmd:usesas}. This may be helpful for situations where the SAS +dataset has more variables than your version of Stata can handle. You can create a variable list +from the variable called "name" to create another invocation of {cmd:usesas} to read in only the +variables you need.{p_end} + +{p 8 8 2}If you do not want to have the {cmd:describe} option list the descriptive information of the +imported dataset, you can use the option {cmd:listnot} with {cmd:describe}. The descriptive information +will still be loaded into Stata as a Stata dataset.{p_end} + +{p 8 8 2}The descriptive data are sorted in the variable order of the using dataset so a variable list +for {cmd:usesas} could be created like so:{p_end} + +{p 8 8 2} {cmd:. display "`= trim(name[1])'--`= name[2047]'" }{p_end} + +{p 8 8 2} {cmd:id--income88 }{p_end} + + +{p 8 8 2} which could then be used like so to keep the first 2,047 variables in the using dataset +(2,047 is the maximum number of variables that Stata Intercooled can handle):{p_end} + +{p 8 8 2} {cmd:. usesas using "mySASdata.sas7bdat", clear keep(`= trim(name[1])'--`= name[2047]') }{p_end} + +{p 8 8 2} SAS variable lists using two dashes "--" tells SAS to use the variables that exist +positionally between the first variable and the last variable in the using dataset inclusively. +Read more about this under the documentation of the {cmd:keep} option.{p_end} + +{p 8 8 2}The {cmd:describe} option makes {cmd:usesas} return the following in {cmd:r()}:{p_end} + +{synoptset 20 tabbed}{...} +{p2col 5 20 24 2: Scalars}{p_end} +{synopt:{cmd:r(N)}}number of observations in using dataset{p_end} +{synopt:{cmd:r(k)}}number of variables in using dataset{p_end} + +{p2col 5 20 24 2: Macros}{p_end} +{synopt:{cmd:r(varlist)}}variables in using dataset {p_end} +{synopt:{cmd:r(sortlist)}}variables by which using data are sorted {p_end} + +{p 8 8 2} The above scalars and macros contain information about the dataset that was described, +not information of the dataset of descriptive information that {cmd:usesas} loaded into Stata +with the {cmd:describe} option.{p_end} + +{p 4 8 2}{cmd:keep} allows for a list of variables from the imported dataset to be read in. This list is +used in the SAS code portion of {cmd:usesas} so must be written in the SAS variable list style. SAS does +not allow for variable lists to contain stars (*) or question marks (?). For example:{p_end} + +{p 4 8 2}{cmd: keep(var1-var20)} includes only vars that start with "var" and end in a number between 1 and 20.{p_end} + +{p 4 8 2}{cmd: keep(var1--var20)} includes only vars in the dataset between var1 and var20. This is like Stata's +{help varlist:varlist} style {cmd: var1-var20}.{p_end} + +{p 4 8 2}{cmd:if} allows for a SAS {cmd:if} statement to subset the data before it's read in. Any valid +SAS style {cmd:if} statement will work.{p_end} + +{p 4 8 2}{cmd:in} allows for subsetting the data before it's read in. Use only {cmd:#/#} where both numbers are +positive, for example 1/30 for the first 30 observations.{p_end} + +{p 4 8 2}{cmd:quotes} specifies that double quotes that exist in string variables are to be replaced +with single quotes. Since the data are written out to an ASCII file and then read into Stata, +there are rare instances when double quotes are not allowed inside string variables.{p_end} + +{p 4 8 2}{cmd:messy} specifies that all the intermediary files created by {cmd:usesas} during its operation +are not to be deleted. The {cmd:messy} option prevents {cmd:usesas} from cleaning up after it has +finished. This option is mostly useful for debugging purposes in order to find out where something went +wrong. All intermediary files have a name starting with an underscore "_" followed by the process ID and +are located in Stata's temp directory.{p_end} + +{title:Examples} + +{p 4 8 2} {cmd:. usesas using "mySASdata.sas7bdat" }{p_end} + +{p 4 8 2} {cmd:. usesas using "c:\data\mySASdata.ssd01", check }{p_end} + +{p 4 8 2} {cmd:. usesas using "mySASdata.xpt", xport }{p_end} + +{p 4 8 2} {cmd:. usesas using "mySASdata.sas7bdat", formats }{p_end} + +{p 4 8 2} {cmd:. usesas using "mySASdata.sd2", quotes }{p_end} + +{p 4 8 2} {cmd:. usesas using "mySASdata.sas7bdat", messy }{p_end} + +{p 4 8 2} {cmd:. usesas using "mySASdata.sas7bdat", keep(id--qvm203a) if(1980<year<2000) in(1/500) }{p_end} + +{p 4 8 2} {cmd:. usesas using "mySASdata.sas7bdat", describe }{p_end} + +{p 4 8 2} {cmd:. usesas using "mySASdata.sas7bdat", describe nolist }{p_end} + +{p 4 8 2} {cmd:// then submit the following actual invocation of usesas: }{p_end} + +{p 4 8 2} {cmd:. usesas using "mySASdata.sas7bdat", clear keep(`r(sortlist)' `= trim(name[1])'--`= name[2047]') }{p_end} + + +{p 4 8 2} NOTE: If you are setting up this program on your computer for the first time, please edit +{cmd:sasexe.ado} to set the location of your SAS executable file (sas.exe). If you do not, {cmd:usesas} +will try to set it for you. The {cmd:sasexe.ado} file is an ASCII text file and should be saved as such +after editing. Stata's {cmd:do-file} editor will do the trick.{p_end} + +{title:Setting up usesas} + +{p 4 8 2}{stata quietly adoedit sasexe:edit sasexe.ado} (click, to edit the {cmd:sasexe.ado} file, remember to save when done.){p_end} + + +{title:Author} + +{p 4 4 2} +Dan Blanchette {break} +Center for Entrepreneurship and Innovation {break} +Duke University's Fuqua School of Business {break} +Dan.Blanchette@Duke.edu{p_end} + + +{title:Also see} + +{p 4 13 2}On-line: {help use}, {help fdause}, {help savasas} (if installed){p_end} + + diff --git a/Modules/ado/plus/u/usesasdel.ado b/Modules/ado/plus/u/usesasdel.ado new file mode 100644 index 0000000..3aaec3e --- /dev/null +++ b/Modules/ado/plus/u/usesasdel.ado @@ -0,0 +1,25 @@ +*! usesasdel Version 1.1 dan.blanchette@duke.edu 16Mar2009 +*! Center of Entrepreneurship and Innovation Duke University's Fuqua School of Business +** usesasdel Version 1.1 dan_blanchette@unc.edu 01Feb2008 +** - made the string comparison work for very long strings +** research computing, unc-ch +** usesasdel Version 1.0 dan_blanchette@unc.edu 09Nov2005 +** the carolina population center, unc-ch + +// can only delete files with no spaces in their names +// but can handle directory names with spaces in their names +program define usesasdel +version 8 + args dir basefilename + local files : dir `"`dir'"' files `"`basefilename'*"' , nofail + foreach f in `files' { + local dirf `"`dir'/`f'"' + if `: list local(dir) == local(dirf)' == 0 { + erase `"`dir'/`f'"' + } + } + end + +exit + + diff --git a/Modules/ado/plus/u/uvis.ado b/Modules/ado/plus/u/uvis.ado new file mode 100644 index 0000000..1845181 --- /dev/null +++ b/Modules/ado/plus/u/uvis.ado @@ -0,0 +1,456 @@ +*! version 1.1.0 PR 30aug2005. +* +* Recent history of uvis +* 1.1.0 03aug2005 Replace -draw- option with -match-. Default becomes draw. +* With prediction matching, randomly sort observations with identical predictions. +* Order variables in chained equations in order of increasing missingness. +* 1.0.4 21jun2005 Add sort, stable to enable reproducibility imputations with given seed +* +program define uvis, rclass sortpreserve +version 8 +gettoken cmd 0 : 0 +if substr("`cmd'",1,3)=="reg" { + local cmd regress +} + +local normal=("`cmd'"=="regress")|("`cmd'"=="rreg") +local binary=("`cmd'"=="logit")|("`cmd'"=="logistic") +local catcmd=("`cmd'"=="mlogit")|("`cmd'"=="ologit") + +if !`normal' & !`binary' & !`catcmd' { + di in red "invalid or unrecognised command, `cmd'" + exit 198 +} + +syntax varlist(min=2 numeric) [if] [in] [aweight fweight pweight iweight] , Gen(string) /* +*/ [ noCONStant Delta(real 0) BOot MAtch REPLACE SEed(int 0) * ] + +if "`replace'"=="" { + confirm new var `gen' +} + +if "`match'"=="match" { + di as text "[imputing by prediction matching" _cont +} +else di as text "[imputing by drawing from conditional distribution" _cont +if "`boot'"=="" { + di as text " without bootstrap]" +} +else di as text " with bootstrap]" + +if "`constant'"=="noconstant" { + local options "`options' nocons" +} +gettoken y xvars : varlist +tempvar touse +quietly { + marksample touse, novarlist + markout `touse' `xvars' /* note: does not include `y' */ + + if `seed'!=0 { + set seed `seed' + } + +* Deal with weights + frac_wgt `"`exp'"' `touse' `"`weight'"' + local wgt `r(wgt)' + +* Code types of missings: 1=non-missing y, 2=missing y, 3=other missing + tempvar obstype yimp + gen byte `obstype'=1*(`touse'==1 & !missing(`y')) /* + */ +2*(`touse'==1 & missing(`y')) /* + */ +3*(`touse'==0) + + count if `obstype'==1 + local nobs=r(N) + count if `obstype'==2 + local nmis=r(N) + + local type: type `y' + gen `type' `yimp'=. + +* Fit imputation model + `cmd' `y' `xvars' `wgt', `options' + tempname b e V chol bstar + tempvar xb u + matrix `b'=e(b) + matrix `e'=e(b) + matrix `V'=e(V) + local colsofb=colsof(`b') +* Check for zeroes on the diagonal of V and replace them with 1. +* Otherwise this makes the matrix non-positive definite. +* Occurs when e.g. logit drops variables, giving zero variances. +* !! Is this safe to do? + if diag0cnt(`V')>0 { + forvalues j=1/`colsofb' { + if `V'[`j',`j']==0 { + matrix `V'[`j',`j']=1 + } + } + } + matrix `chol'=cholesky(`V') + if `catcmd' { + tempname cat + local nclass=e(k_cat) /* number of classes in (ordered) categoric variable */ + matrix `cat'=e(cat) /* row vector giving actual category values */ + local cuts=`nclass'-1 + } + * Draw beta, and if necessary rmse, for proper imputation + if `normal' { + * draw rmse + local rmse=e(rmse) + local df=e(df_r) + local chi2=2*invgammap(`df'/2,uniform()) + local rmsestar=`rmse'*sqrt(`df'/`chi2') + matrix `chol'=`chol'*sqrt(`df'/`chi2') + } + * draw beta + forvalues i=1/`colsofb' { + matrix `e'[1,`i']=invnorm(uniform()) + } + matrix `bstar'=`b'+`e'*`chol'' + + if "`boot'"=="" { +* Based on Ian White's code to implement van Buuren et al (1999). + * draw y + gen `u'=uniform() + if `normal' | `binary' { + * in normal or binary case, impute by sampling conditional distribution + * or by prediction matching + if "`match'"=="match" { + * prediction matching + tempvar etaobs etamis + matrix score `etaobs'=`b' if `obstype'==1 + matrix score `etamis'=`bstar' if `obstype'==2 + * Include non-response location shift, delta. + if `delta'!=0 { + replace `etamis'=`etamis'+`delta' + } + match_normal `obstype' `nobs' `nmis' `etaobs' `etamis' `yimp' `y' + } + else { + * sampling conditional distribution + matrix score `xb'=`bstar' if `touse' + if `normal' { + replace `yimp'=`xb'+`rmsestar'*invnorm(`u') + } + else replace `yimp'=`u'<1/(1+exp(-`xb')) if !missing(`xb') + } + } + else { /* catcmd */ + if "`match'"=="match" { // prediction matching + * predict class-specific probabilities and convert to logits + if "`cmd'"=="ologit" { + * Predict index independent of cutpoints + * (note use of forcezero option to circumvent missing _cut* vars) + matrix score `xb'=`b' if `touse', forcezero + * predict cumulative probabilities for obs data and hence logits of class probs + forvalues k=1/`nclass' { + tempvar etaobs`k' etamis`k' + if `k'==`nclass' { + gen `etaobs`nclass''=log((1-`p`cuts'')/`p`cuts'') if `obstype'==1 + } + else { + tempvar p`k' + local cutpt=`b'[1, `k'+`colsofb'-`cuts'] + * 1/(1+exp(-... is probability of being in category 1 or 2 or ... k + gen `p`k''=1/(1+exp(-(`cutpt'-`xb'))) + if `k'==1 { + gen `etaobs`k''=log(`p`k''/(1-`p`k'')) if `obstype'==1 + } + else { + local k1=`k'-1 + gen `etaobs`k''=log((`p`k''-`p`k1'')/(1-(`p`k''-`p`k1''))) /* + */ if `obstype'==1 + } + } + } + drop `xb' + matrix score `xb'=`bstar' if `touse', forcezero + * predict cumulative probabilities for missing data and hence logits of class probs + forvalues k=1/`nclass' { + if `k'==`nclass' { + gen `etamis`nclass''=log((1-`p`cuts'')/`p`cuts'') if `obstype'==2 + } + else { + local cutpt=`bstar'[1, `k'+`colsofb'-`cuts'] + replace `p`k''=1/(1+exp(-(`cutpt'-`xb'))) + if `k'==1 { + gen `etamis`k''=log(`p`k''/(1-`p`k'')) if `obstype'==2 + } + else { + local k1=`k'-1 + gen `etamis`k''=log((`p`k''-`p`k1'')/(1-(`p`k''-`p`k1''))) /* + */ if `obstype'==2 + } + } + } + } + else { /* mlogit */ + * predict cumulative probabilities for obs data and hence logits of class probs + * care needed dealing with different possible base categories + tempvar sumexp + local basecat=e(basecat) /* actual basecategory chosen by Stata */ + gen `sumexp'=0 if `touse' + forvalues k=1/`nclass' { + tempvar etaobs`k' etamis`k' xb`k' + local thiscat=`cat'[1,`k'] + if `thiscat'==`basecat' { + gen `xb`k''=0 if `touse' + } + else matrix score `xb`k''=`b' if `touse', equation(`thiscat') + replace `sumexp'=`sumexp' + exp(`xb`k'') + } + forvalues k=1/`nclass' { + * formula for logit of class prob derived from Pk in Stata mlogit entry + gen `etaobs`k''=`xb`k''-log(`sumexp'-exp(`xb`k'')) if `obstype'==1 + } + * same for missing obs + replace `sumexp'=0 + forvalues k=1/`nclass' { + cap drop `xb`k'' + local thiscat=`cat'[1,`k'] + if `thiscat'==`basecat' { + gen `xb`k''=0 if `touse' + } + else matrix score `xb`k''=`bstar' if `touse', equation(`thiscat') + replace `sumexp'=`sumexp' + exp(`xb`k'') + } + forvalues k=1/`nclass' { + * formula for logit of class prob derived from Pk in Stata mlogit entry + gen `etamis`k''=`xb`k''-log(`sumexp'-exp(`xb`k'')) if `obstype'==2 + } + } + * match + sort `obstype', stable + tempvar order distance + gen `distance'=. + gen long `order'=_n + * For each missing obs j, find index of obs whose etaobs is closest to prediction [j]. + forvalues i=1/`nmis' { + local j=`i'+`nobs' + * calc summed absolute distances between etamis* and etaobs* + replace `distance'=0 in 1/`nobs' + forvalues k=1/`nclass' { + replace `distance'=`distance'+abs(`etamis`k''[`j']-`etaobs`k'') in 1/`nobs' + } + * Find index of smallest distance between etamis* and etaobs* + sort `distance' + local index=`order'[1] + * restore correct order + sort `order' + replace `yimp'=`y'[`index'] in `j' + } + } + else { // draw + * sampling conditional distribution + replace `yimp'=`cat'[1,1] + if "`cmd'"=="ologit" { + * Predict index independent of cutpoints + * (note use of forcezero option to circumvent missing _cut* vars) + matrix score `xb'=`bstar' if `touse', forcezero + forvalues k=1/`cuts' { + * 1/(1+exp(-... is probability of being in category 1 or 2 or ... k + local cutpt=`bstar'[1, `k'+`colsofb'-`cuts'] + replace `yimp'=`cat'[1,`k'+1] if `u'>1/(1+exp(-(`cutpt'-`xb'))) + } + } + else { /* mlogit */ + * care needed dealing with different possible base categories + tempvar cusump sumexp + local basecat=e(basecat) /* actual basecategory chosen by Stata */ + gen `sumexp'=0 if `touse' + forvalues i=1/`nclass' { + tempvar xb`i' + local thiscat=`cat'[1,`i'] + if `thiscat'==`basecat' { + gen `xb`i''=0 if `touse' + } + else matrix score `xb`i''=`bstar' if `touse', equation(`thiscat') + replace `sumexp'=`sumexp' + exp(`xb`i'') + } + gen `cusump'=exp(`xb1')/`sumexp' + forvalues i=2/`nclass' { + replace `yimp'=`cat'[1,`i'] if `u'>`cusump' + replace `cusump'=`cusump'+exp(`xb`i'')/`sumexp' + replace `yimp'=. if missing(`xb`i'') + } + } + } + } + } + else { + * Bootstrap method + if "`match'"=="match" { /* match */ + if `catcmd' { + * predict class-specific probabilities and convert to logits + forvalues k=1/`nclass' { + local outk=`cat'[1,`k'] + tempvar etaobs`k' etamis`k' + predict `etaobs`k'' if `obstype'==1, outcome(`outk') /* probability */ + replace `etaobs`k''=log(`etaobs`k''/(1-`etaobs`k'')) /* logit */ + } + } + else { /* normal and binary cases */ + tempvar etaobs etamis + predict `etaobs' if `obstype'==1, xb + } + } + * Bootstrap observed data + tempvar wt + gen double `wt'=. + bsample if `obstype'==1, weight(`wt') + if "`wgt'"!="" { + replace `wt' `exp'*`wt' + local w [`weight'=`wt'] + } + else local w [fweight=`wt'] + `cmd' `y' `xvars' `w', `options' + + if `catcmd' { + if e(k_cat)<`nclass' { + di as error "cannot predict outcome for all classes in bootstrap sample;" + di as error "probably one or more classes has a low frequency in the original data:" + di as error "try amalgamating small classes of `y' and rerunning" + exit 303 + } + } + if "`match'"=="match" { + if `catcmd' { + * predict class-specific probabilities and convert to logits + forvalues k=1/`nclass' { + local outk=`cat'[1,`k'] + predict `etamis`k'' if `obstype'==2, outcome(`outk') /* probability */ + replace `etamis`k''=log(`etamis`k''/(1-`etamis`k'')) /* logit */ + } + * match + sort `obstype', stable + tempvar order distance + gen `distance'=. + gen long `order'=_n + * For each missing obs j, find index of obs whose etaobs is closest to prediction [j]. + forvalues i=1/`nmis' { + local j=`i'+`nobs' + * calc summed absolute distances between etamis* and etaobs* + replace `distance'=0 in 1/`nobs' + forvalues k=1/`nclass' { + replace `distance'=`distance'+abs(`etamis`k''[`j']-`etaobs`k'') in 1/`nobs' + } + * Find index of smallest distance between etamis* and etaobs* + sort `distance' + local index=`order'[1] + * restore correct order + sort `order' + replace `yimp'=`y'[`index'] in `j' + } + } + else { /* normal and binary */ + predict `etamis' if `obstype'==2, xb + + * Include non-response location shift, delta. + if `delta'!=0 { + replace `etamis'=`etamis'+`delta' + } + match_normal `obstype' `nobs' `nmis' `etaobs' `etamis' `yimp' `y' + } + } + else { // draw + matrix `bstar'=e(b) + gen `u'=uniform() + if `normal' | `binary' { + matrix score `xb'=`bstar' if `touse' + if `normal' { + replace `yimp'=`xb'+e(rmse)*invnorm(`u') + } + else replace `yimp'=`u'<1/(1+exp(-`xb')) if !missing(`xb') + } + else { /* catcmd */ + replace `yimp'=`cat'[1,1] + if "`cmd'"=="ologit" { + matrix score `xb'=`bstar' if `touse', forcezero + forvalues k=1/`cuts' { + * 1/(1+exp(-... is probability of being in category 1 or 2 or ... k + local cutpt=`bstar'[1, `k'+`colsofb'-`cuts'] + replace `yimp'=`cat'[1,`k'+1] if `u'>1/(1+exp(-(`cutpt'-`xb'))) + } + } + else { /* mlogit */ + * care needed dealing with different possible base categories + tempvar cusump sumexp + local basecat=e(basecat) /* actual basecategory chosen by Stata */ + gen `sumexp'=0 if `touse' + forvalues i=1/`nclass' { + tempvar xb`i' + local thiscat=`cat'[1,`i'] + if `thiscat'==`basecat' { + gen `xb`i''=0 if `touse' + } + else matrix score `xb`i''=`bstar' if `touse', equation(`thiscat') + replace `sumexp'=`sumexp' + exp(`xb`i'') + } + gen `cusump'=exp(`xb1')/`sumexp' + forvalues i=2/`nclass' { + replace `yimp'=`cat'[1,`i'] if `u'>`cusump' + replace `cusump'=`cusump'+exp(`xb`i'')/`sumexp' + replace `yimp'=. if missing(`xb`i'') + } + } + } + } + } + cap drop `gen' + rename `yimp' `gen' + *replace `gen'=`y' if `obstype'==1 + replace `gen'=`y' if !missing(`y') + lab var `gen' "imputed from `y'" +} +di _n in ye `nmis' in gr " missing observations on `y' imputed from " /* + */ in ye `nobs' in gr " complete observations." +end + +program define match_normal +* Prediction matching, normal or binary case. +args obstype nobs nmis etaobs etamis yimp y +quietly { + * For each missing obs j, find index of observation + * whose etaobs is closest to etamis[j]. + tempvar sumgt + tempname etamisi + gen long `sumgt'=. + * Sort etaobs within obstype + sort `obstype' `etaobs', stable + forvalues i=1/`nmis' { + local j=`i'+`nobs' + scalar `etamisi'=`etamis'[`j'] + replace `sumgt'=sum((`etamisi'>`etaobs')) in 1/`nobs' + sum `sumgt', meanonly + local j1=r(max) + if `j1'==0 { + local index 1 + local direction 1 + } + else if `j1'==`nobs' { + local index `nobs' + local direction -1 + } + else { + local j2=`j1'+1 + if (`etamisi'-`etaobs'[`j1'])<(`etaobs'[`j2']-`etamisi') { + local index `j1' + local direction -1 + } + else { + local index `j2' + local direction 1 + } + } + * In case of tied etaobs values, add random offset to index in the appropriate direction + count if `obstype'==1 & reldif(`etaobs', `etaobs'[`index'])<1e-7 // counts as equality + scalar count`i'=r(N) + if r(N)>1 { + local index=`index'+`direction'*int(uniform()*r(N)) + } + replace `yimp'=`y'[`index'] in `j' + } +} +end diff --git a/Modules/ado/plus/u/uvis.hlp b/Modules/ado/plus/u/uvis.hlp new file mode 100644 index 0000000..393ac8f --- /dev/null +++ b/Modules/ado/plus/u/uvis.hlp @@ -0,0 +1 @@ +.h ice diff --git a/Modules/ado/plus/v/vardesc.ado b/Modules/ado/plus/v/vardesc.ado new file mode 100644 index 0000000..700abf1 --- /dev/null +++ b/Modules/ado/plus/v/vardesc.ado @@ -0,0 +1,885 @@ +capture program drop vardesc +*! version 0.5.1 jsl n option for names +* version 0.5.0 jsl string variables +* version 0.4.9b jsl trap some errors +* still buggy try vd-kins + +* version 0.4.9 jsl sq bug fix +* version 0.4.8 jsl 01Jul2006 maxlen +* version 0.4.7 jsl 29Jun2006 with sq ad op overrides +* version 0.4.6b jsl 29Jun2006 with squeezing + +* DO: add truncate for truncate at some column length + +// prints names, labels and descriptive statistics in a table +program define vardesc, byable(recall) + version 8 + syntax [varlist(default=none)] [if] [in] /// + [, /// + SQueeze /// squeeze out extra space + SQMin(integer 6) /// minimum column size if compression + OPtimize /// optimize space used without any truncation + OPTMin(integer 5) /// minimum column size if optimized + OCLABel(integer 0) /// column widths to override squeeze and optimize + OCNAme(integer 0) /// + OCVAlues(integer 0) /// + OCPCTile(integer 0) /// + OCMAx(integer 0) /// + OCMEan(integer 0) /// + OCMOde(integer 0) /// + OCMIn(integer 0) /// + OCNobs(integer 0) /// + OCNMISS(integer 0) /// + OCSd(integer 0) /// + OCVar(integer 0) /// + SPacer(integer 1) /// spacing added to minimum with squeeze and optimize + Range(string) /// range of values + Style(string) /// define style of output + FORCEN /// force printing of N's + Values(string) /// values to show % of cases with that value + OTHervalues /// show total of other values + aorder /// alphabetize output + First(string) /// first variable to list + Basic /// just the basic table + Columns(integer 0) /// change all column widths + Decimal(integer 0) /// change all # of decimals + CLABel(integer 25) /// + CNAme(integer 12) /// + CVAlues(integer 6) DVAlues(integer 1) /// columns and decimal digits + CPCTile(integer 10) DPCTile(integer 2) /// + CMAx(integer 9) DMAx(integer 2) /// + CMEan(integer 9) DMEan(integer 2) /// + CMOde(integer 9) DMOde(integer 2) /// + CMIn(integer 9) DMIn(integer 2) /// + CNobs(integer 6) DNobs(integer 0) /// + CNMISS(integer 7) DNMISS(integer 0) /// + CSd(integer 9) DSd(integer 2) /// + CVar(integer 9) DVar(integer 2) /// + LEFTLabel /// left justify var label + LEFTName /// left justify var name + MINLabel /// minimize column size of variable labels + MINName /// do not minimize column size of variable names + NBasic /// basic table with numbered rows + NOHeader /// surpress header + NOMiss /// drop all missing cases + NUMber /// number the list of variables + Order(string) /// order for displaying items + RIGHTLabel /// right justify var labels + RIGHTName /// right justify var names + VERBose /// add extra output + MAXLength(integer 0) /// truncated label if exceeds this length + M80 /// maxlength 80 + NCOL80 /// print columns + Names /// only list names + ] + + if "`m80'"=="m80" { + local maxlength = 80 + } + if "`ncol80'"=="ncol80" { +di "0 1 2 3 4 5 6 7 8" +di "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + } + +// default ordering of statistics -- change for different default + + local orderdefault "name nobs mean sd min max label" + +// valid names for statistics being printed; see synonyms below + + local validnms mean min max sd var name label nobs nmiss mode + local validpct pct1 pct5 pct01 pct05 pct10 pct25 /// + pct50 pct75 pct90 pct95 pct99 + local validall `validnms' `validpct' values + +// experiment with defaults + +/* +local optimize "optimize" +if "`squeeze'"=="squeeze" { + local optimize "" +} +if "`fixed'"=="fixed" { + local fixed "fixed" +} +*/ + +// locals used to keep track of things + + local drop_ifin = 0 // drop for if and in conditions + local drop_total = 0 // drop for any reason + local drop_miss = 0 // drop due to missing values + + local ISsamenobs = 1 // same N for all variables? assume yes to start + local ISmissing = 0 // is there missing? assume no to start + local ISnomissing = 1 // assume no missing to start + local ISpct = 0 // need to compute percentile? + local ISmode = 0 // only compute mode if requested since it can be slow + local ISvalues = 0 // need to % at values? + if "`values'"!="" { + local ISvalues = 1 // need to % at values? + } + local ISno_n_equal = 0 // supress n= at end of list + +// variables to be analyzed + + if "`varlist'" == "" { + unab varlist : _all // if none, use all + * remove variable create with byable + if "`_byindex'"!="" { + local varlist = subinstr("`varlist'","`_byindex'","",.) + } + } + +// decode range of values + + if "`range'"!="" { + local nrange = 0 + foreach r in `range' { + local ++nrange + if `nrange'==1 local r1 = `r' + if `nrange'==2 local r2 = `r' + if `nrange'==3 { + di in red "range option can have only two values" + } + } + if `r1'<`r2' { + local rangemin = `r1' + local rangemax = `r2' + } + else { + local rangemin = `r2' + local rangemax = `r1' + } + local rangelist "" + forvalues v = `rangemin'(1)`rangemax' { + local rangelist `rangelist' `v' + } + local ISvalues = 1 // need to % at values? + local values `rangelist' + } + +// set up for printing of labels and names + + * spaces before variable label + if `spacer'==1 local labeloffset " " + if `spacer'==2 local labeloffset " " + if `spacer'==3 local labeloffset " " + if `spacer'==4 local labeloffset " " + if `spacer'==5 local labeloffset " " + if `spacer'==6 local labeloffset " " + if `spacer'==7 local labeloffset " " + if `spacer'==8 local labeloffset " " + if `spacer'==9 local labeloffset " " + * justification of label + local lblsign "-" // left by default + if "`rightlabel'"=="rightlabel" { + local lblsign "" + } + if "`leftlabel'"=="leftlabel" { + local lblsign "-" + } + * alignment of name + local namesign "-" // left by default + if "`rightname'"=="rightname" { + local namesign "" + } + if "`leftname'"=="leftname" { + local namesign "-" + } + +// global changes to column and decimal settings + + if `decimal'!=0 { + foreach n in max mean min sd var pctile values { + local d`n' = `decimal' + } + } + if `columns'!=0 { + foreach n in max mean min sd var pctile values { + local c`n' = `columns' + } + } + +// arrange order of variables + + * alphabetize the list + if "`aorder'"=="aorder" { + local varlistunsorted `varlist' + local varlist : list sort varlistunsorted + } + * put the first variable in front of the list + if "`first'"!="" { + local varlist = subinstr("`varlist'","`first'","",.) + local varlist `first' `varlist' + } + +// decode order in which items are printed + + local pctlist "" // list to hold requested percentiles + * default order of statistics if order not specified + if "`order'"=="" { + local order `orderdefault' + } + +// define styles + + if "`style'"=="basic" | "`style'"=="b" { + local style basic + local order name nobs mean sd min max label + } + else if "`style'"=="check" | "`style'"=="c" { + local style check + local order name mean med mode min p1 p99 max nmiss + } + else if "`style'"=="missing" | "`style'"=="miss" | "`style'"=="m" { + local style missing + local order name nmiss nobs mean min max label + } + else if "`style'"=="names" | "`style'"=="n" | /// + "`style'"=="nam" | "`style'"=="nm" | "`style'"=="name" | /// + "`names'"=="names" { + local style names + local order name label + if `clabel'==25 { + local clabel = 45 + } + } + else if "`style'"=="outliers" | "`style'"=="out" | "`style'"=="o" { + local style outliers + local order name min p1 p5 p10 p90 p95 p99 max + } + else if "`style'"=="range" | "`style'"=="r" { + local style range + local order name nobs values label + } + +// synonyms + + local order = subinword("`order'","median" ,"pct50" ,.) + local order = subinword("`order'","med" ,"pct50" ,.) + local order = subinword("`order'","minimum" ,"min" ,.) + local order = subinword("`order'","maximum" ,"max" ,.) + local order = subinword("`order'","variance","var" ,.) + local order = subinword("`order'","mn" ,"mean" ,.) + local order = subinword("`order'","stddev" ,"sd" ,.) + local order = subinword("`order'","val" ,"values",.) + local order = subinword("`order'","value" ,"values",.) + local order = subinword("`order'","lab" ,"label" ,.) + local order = subinword("`order'","lbl" ,"label" ,.) + local order = subinword("`order'","nm" ,"name" ,.) + local order = subinword("`order'","nam" ,"name" ,.) + local order = subinword("`order'","obs" ,"nobs" ,.) + local order = subinword("`order'","n" ,"nobs" ,.) + foreach p in 1 5 10 25 50 75 90 95 99 { + local order = subinword("`order'","p`p'","pct`p'",.) + } + +// check order and make sure statistics are valid + + local isexit = 0 + foreach o in `order' { + * check if valid item + local isbad = 1 + foreach n in `validall' { + if "`o'"=="`n'" { + local isbad = 0 + } + } + if `isbad' { + di in red "invalid name in order(): `o'" + local isexit = 1 + } + } + if `isexit'==1 { + exit + } + + * list of statistics in order to be output + local outorder "`order'" + * number of items in list + local norder = wordcount("`order'") + * is value among items + local print_value = 0 + * check is item in list + local i = 0 + foreach o in `order' { + local ++i + if `i'==1 { + * no lead spacing if listed first + if "`o'"=="label" { + local labeloffset "" + } + } + if "`o'"=="mode" { + local ISmode = 1 + } + if "`o'"=="values" { + local print_value = 1 + } + * check if valid item + local isvalid = strpos("`validall'","`o'") + if `isvalid'==0 { + di in red "invalid name in order(): `o'" + exit + } + * if pct, decode and add to list + local o3 = substr("`o'",1,3) // grab ## from pct## + * check if percentile + if "`o3'"=="pct" { // is percentile + local ISpct = 1 + local pctnum = substr("`o'",4,5) // if pct## retrieve ## + local pctnum = `pctnum' // strip off leading 0 + local pctlist `pctlist' `pctnum' + } + + } // loop over output order + + * add values at end if values() but values not in order() list + if `print_value'==0 & `ISvalues'==1 { + local outorder `order' values + } + +// if minlabel, determine smallest size that will fit label + + if "`minlabel'"=="minlabel" { + local maxlab = 0 + * check length of each label + foreach v in `varlist' { + local `v'label : variable label `v' + local ll = length("``v'label'") + if `ll'>`maxlab' { + local maxlab = `ll' + } + } + * set new column size for labels as spacer larger than minimum + local clabel = `maxlab' + `spacer' + } + +// if minname, determine smallest size that will fit names + + if "`minname'"=="minname" { + local maxname = 0 + foreach v in `varlist' { // loop through variables + local ll = length("`v'") + if `ll'>`maxname' { + local maxname = `ll' + } + } + * set new column size for names + local cname = `maxname' + `spacer' + } + + * need at least 9 for name + if "`nbasic'"=="nbasic" | "`basic'"=="basic" { + if `cname'<8 local cname = 9 + } + +// define sample and check missing values - 0.4.0 - 28Jun2006 - byable + + tempvar touse + * initially, just use if and in + mark `touse' `if' `in' + * count sample based on if and in + qui count if `touse'==0 + local drop_ifin = r(N) // total droppedbased on if and in + + * if nomiss, drop missing 0.4.0 + if "`nomiss'"=="nomiss" { + markout `touse' `varlist' + } + * counted after missing might be dropped + qui count if `touse'==0 + local drop_total = r(N) // total to drop + local drop_miss = `drop_total' - `drop_ifin' + + if "`verbose'"=="verbose" { + di + di "Dropped for if & in conditions: " _col(50) `drop_ifin' + di "Dropped for missing data: " _col(50) `drop_miss' + di "Dropped for if, in or missing:" _col(50) `drop_total' + } + if "`nomiss'"=="nomiss" { + local ISsamenobs = 1 // since all missing are dropped, same N + local ISmissing = 0 // no missing since all missing dropped + } + +// compute statistics + + local vnum = 0 + + foreach v in `varlist' { // loop through variables + + local ++vnum + * if pctiles need, use detail + if `ISpct'==1 { + qui sum `v' if `touse', detail + foreach p in `pctlist' { + local `v'pct`p' = r(p`p') + } + } + * pctiles not used + else { + qui sum `v' if `touse' + } + * statistics based on nonmissing + local `v'mean = r(mean) + local `v'sd = r(sd) + local `v'var = r(Var) + local `v'min = r(min) + local `v'max = r(max) + local `v'label : variable label `v' + local `v'name "`v'" + local `v'nobs = r(N) + local nnow = r(N) + + * mode - missing if multipe modes + local `v'mode = . + if `ISmode'==1 { + tempvar vmode + qui egen `vmode' = mode(`v') if `touse' + local `v'mode = `vmode'[1] + } + * compute number missing + capture confirm string variable `v' + if !_rc { // action for string variables + qui count if `v'=="" & `touse' + } + else { // action for numeric variables + qui count if `v'>=. & `touse' + } + + local `v'nmiss = r(N) + local nmissprior = r(N) + if ``v'nmiss'!=0 { + local ISmissing = 1 // missing data + } + * determine if n varies across variables due to missing values + if `vnum'==1 { // for 1st variable, assume N's are the same + local nprior = `nnow' + } + else { // now compare to prior variable + * if prior and current differ + if `nprior'!=`nnow' { + local ISsamenobs = 0 // if n's differ, change indicator + } + local nprior = `nnow' + } + * compute % with given values + if `ISvalues'==1 { + local n_notother = 0 // # in other categories + * non missing N + local n = ``v'nobs' + * compute pct at each value + foreach val in `values' { + qui count if `v'==`val' & `touse' + local nval = r(N) + local n_notother = `n_notother' + `nval' + local `v'pval`val' = 100 * (`nval'/`n') + } + local `v'pvalother = 100 * ((`n'-`n_notother')/`n') + } + + } // loop through variables for computations + +// decide on whether to print nobs and nmiss + + local n_for_all = `nprior' + + * value to possibly print at end of table + if `ISmissing'==1 { + local nmiss_for_all = `nmissprior' + } + * if miss style, don't check on nobs + if "`style'"!="missing" { + * remove nobs and nmiss + if `ISsamenobs'==1 & "`forcen'"!="forcen" { + local outorder = subinword("`outorder'","nobs","",.) + local outorder = subinword("`outorder'","nmiss","",.) + } + } + local ISnobs_in_order = strpos("`outorder'","nobs")>0 + local ISnmiss_in_order = strpos("`outorder'","nmiss")>0 + +// squeeze or optimize + + if "`squeeze'"=="squeeze" | "`optimize'"=="optimize" /// + | `maxlength'>0 { + + * set counters for columns need to 0 + foreach o in `outorder' { + * if pct##, change to percentile + local o3 = substr("`o'",1,3) + if "`o3'"=="pct" { + local o "pctile" + } + + local cis`o' = 0 + } + + * check needed lengths for each statistic for each variable + foreach v in `varlist' { + + * loop through items to print + foreach o in `outorder' { + + * name + if "`o'"=="name" { + local l = length("`v'") + local cisname = max(`cisname',`l') + } + + * variable label + else if "`o'"=="label" { + local oout "``v'`o''" + * the following reduces it to clabel size + * local oout = substr("`oout'",1,`clabel') + local l = length("`labeloffset'`oout'") + 2 // for two spaces + local cislabel = max(`cislabel',`l') + } + + * number missing + else if "`o'"=="nmiss" { + local ofmt "%`c`o''.`d`o''f" + local stat = ``v'nmiss' + local l = length(string(`stat',"`ofmt'")) + local cis`o' = max(`cis`o'',`l') + } + + * values + else if "`o'"=="values" { + local ofmt "%`cvalues'.`dvalues'f" + foreach val in `values' { + local stat = ``v'pval`val'' + local l = length(string(`stat',"`ofmt'")) + local cis`o' = max(`cis`o'',`l') + } + if "`othervalues'"=="othervalues" { + local stat = ``v'pvalother' + local l = length(string(`stat',"`ofmt'")) + local cis`o' = max(`cis`o'',`l') + } + } + + * percentiles + local o3 = substr("`o'",1,3) // if pct## retrieve pct + else if "`o3'"=="pct" { + local pctnum = substr("`o'",4,5) // if pct## retrieve ## + local pctnum = `pctnum' // strip off leading 0 + local ofmt "%`cpctile'.`dpctile'f" + local stat = ``v'pct`pctnum'' + local l = length(string(`stat',"`ofmt'")) + local cis`o' = max(`cis`o'',`l') + } + + * other statistics + else { + local ofmt "%`c`o''.`d`o''f" + local stat = ``v'`o'' + local l = length(string(`stat',"`ofmt'")) +/* +if "`o'"=="min" | "`o'"=="max" { + local s = string(`stat',"`ofmt'") + di "____12345678901234" + di "s: >`s'<" + di "l: >`l'" +} +*/ + local cis`o' = max(`cis`o'',`l') + } + + } // loop through items to print + + } // loop through variables + + * if squeeze, change column sizes + + if "`squeeze'"=="squeeze" { + foreach o in `outorder' { + + * if override value, don't squeeze + if `oc`o''!=0 { + local c`o' = `oc`o'' + } + + * else use squeezed value + else { + if `cis`o''<`sqmin' { + local cis`o' = `sqmin' + } + if `c`o''>`cis`o'' { + local c`o' = `cis`o'' + `spacer' + } + } +/* +if "`o'"=="min" | "`o'"=="max" { + di "c: `c`o''" +} +*/ + } // loop through outorder + } + + * if optimize, + if "`optimize'"=="optimize" { + foreach o in `outorder' { + + * if pct##, change to percentile + local o3 = substr("`o'",1,3) + if "`o3'"=="pct" { + local o "pctile" + } + + + * if override value + if `oc`o''!=0 { + local c`o' = `oc`o'' + } + + * else use optimize value + else { + *di "From `o': " _col(15) "`c`o''" + if `cis`o''<`optmin' { + local cis`o' = `optmin' + } + local c`o' = `cis`o'' + `spacer' + *di "To `o': " _col(15) "`c`o''" + } + } // outorder loop + } + + * get current total length of output + local tlen = 2 + foreach o in `outorder' { + * if pct##, change to percentile + local o3 = substr("`o'",1,3) + if "`o3'"=="pct" { + local o "pctile" + } + local tlen = `tlen' + `c`o'' + } // outorder loop + + * if exceeds maxlength, reduce label length + if `maxlength' != 0 { + if `tlen' > `maxlength' { + local dif = `tlen' - `maxlength' + local cl = `clabel' + local clabel = `clabel' - `dif' + } + } +/* +di "clabel: `clabel'" +di "tlen `tlen'" +di "maxlength: `maxlength'" +di "dif: `dif'" +di "clabel: `clabel'" +*/ + + + } // squeeze or optimize + +// print column headings + + if "`noheader'"!="noheader" { + + display + local no = 0 + foreach o in `outorder' { + + local ++no + * if pct, retrieve ## from pct## + local o3 = substr("`o'",1,3) + local isopct = 0 + if "`o3'"=="pct" { + local pctnum = substr("`o'",4,5) // if pct## retrieve ## + local pctnum = `pctnum' // strip off leading 0 + local isopct = 1 + } + * if number option, print variable number + if "`number'"=="number" { + * add space before first item + if `no'==1 { + di _cont %2.0f " " + } + } + * heading for name + if "`o'"== "name" { + if `c`o''>8 { + di _cont %`namesign'`c`o''s "Variable" + } + else { + di _cont %`namesign'`c`o''s "Var" + } + } + * heading for nobs + else if "`o'"== "nobs" { + local nonobs "" + local ISno_n_equal = 1 + di _cont %`c`o''s "Obs" + } + * heading for nmiss + else if "`o'"== "nmiss" { + if `c`o''>7 { + di _cont %`c`o''s "Missing" + } + else { + di _cont %`c`o''s "#Miss" + } + } + * heading for mean + else if "`o'"== "mean" { + di _cont %`c`o''s "Mean" + } + * heading for mode + else if "`o'"== "mode" { + di _cont %`c`o''s "Mode" + } + * heading for sd + else if "`o'"== "sd" { + if `csd'<=6 { + di _cont %`c`o''s "SD" + } + else { + di _cont %`c`o''s "StdDev" + } + } + * heading for var + else if "`o'"== "var" { + if `c`o''>7 { + di _cont %`c`o''s "Variance" + } + else { + di _cont %`c`o''s "Var" + } + } + * heading for minimum + else if "`o'"== "min" { + if `c`o''>7 { + di _cont %`c`o''s "Minimum" + } + else { + di _cont %`c`o''s "Min" + } + } + * heading for max + else if "`o'"== "max" { + if `c`o''>7 { + di _cont %`c`o''s "Maximum" + } + else { + di _cont %`c`o''s "Max" + } + } + * heading for variable label + else if "`o'"== "label" { +*di "lblsign: `lblsign'" +*di "x: `c`o''" + di _cont %`lblsign'`c`o''s "`labeloffset'Label" + } + * headings if % at given value + else if "`o'"=="values" { + foreach val in `values' { + di _cont %`c`o''s "%`val's" + } + if "`othervalues'"=="othervalues" { + di _cont %`c`o''s "%Other" + } + } + * heading for percentiles + else if "`o3'"=="pct" { + if `pctnum'==50 { + di _cont %`cpctile's "Median" + } + else { + di _cont %`cpctile's "`pctnum'%" + } + } // pctile + + } // loop through order + + } // if no header + + display + +// loop through variables and print table + + local vnum = 0 + + foreach v in `varlist' { // loop through variables + + local ++vnum + + if "`number'"=="number" { + di _cont %2.0f `vnum' ". " + } + + * loop through items to print + foreach o in `outorder' { + + * name + if "`o'"=="name" { + local ofmt "%`namesign'`c`o''s" + di _cont `ofmt' "``v'`o''" + } + * variable label + else if "`o'"=="label" { + local ofmt "%`lblsign'`c`o''s" + local oout "``v'`o''" + * truncate based on clabel + local oout = substr("`oout'",1,`clabel') + di _cont `ofmt' "`labeloffset'`oout'" + } + * number missing + else if "`o'"=="nmiss" { + local stat = ``v'nmiss' + local ofmt "%`c`o''.`d`o''f" + di _cont `ofmt' `stat' + } + * values + else if "`o'"=="values" { + local ofmt "%`cvalues'.`dvalues'f" + foreach val in `values' { + local stat = ``v'pval`val'' + di _cont `ofmt' `stat' + } + if "`othervalues'"=="othervalues" { + local stat = ``v'pvalother' + di _cont `ofmt' `stat' + } + } + * percentiles + local o3 = substr("`o'",1,3) // if pct## retrieve pct + else if "`o3'"=="pct" { + local pctnum = substr("`o'",4,5) // if pct## retrieve ## + local pctnum = `pctnum' // strip off leading 0 + local ofmt "%`cpctile'.`dpctile'f" + local stat = ``v'pct`pctnum'' + di _cont `ofmt' `stat' + } + * other statistics + else { + local ofmt "%`c`o''.`d`o''f" + local stat = ``v'`o'' + di _cont `ofmt' `stat' + } + + } // loop through items to print + + display + + } // loop through variables + + * only print N= if all same n + if `ISsamenobs'==1 { + + * if nobs still in order, don't print it + if `ISnobs_in_order'==0 { + di _new "N = `n_for_all'" + } + if `ISnmiss_in_order'==0 { + if `ISmissing'==1 { + di "N missing = `nmiss_for_all'" + } + } + } +end + diff --git a/Modules/ado/plus/v/vardesc.hlp b/Modules/ado/plus/v/vardesc.hlp new file mode 100644 index 0000000..8ec270a --- /dev/null +++ b/Modules/ado/plus/v/vardesc.hlp @@ -0,0 +1,164 @@ +{smcl} +{* 24Aug2006}{...} +{cmd:help vardesc} +{hline} + +{title:Title} + +{p2colset 5 18 20 2}{...} +{p2col :{hi:vardesc} {hline 2}}Create a table with variable descriptions. +{p2colreset}{...} + + +{title:Syntax} + +{phang} +Construct a table with variable names, labels and descrptive statistics. + +{p 8 14 2} +{cmd:by} {it:by_variables}{cmd::} {cmd:vardesc} + [{varlist}] + {ifin} + [{cmd:,} {it:options}] + +{synoptset 17 tabbed}{...} +{synopthdr} +{synoptline} + +{syntab:Choice of Statistics} +{synopt :{opt o:rder(items)}}selection and order of items to print. Items are:{p_end} +{p 23 23 2}{opt nam:e}: name of variable (synonym: nm).{p_end} +{p 23 23 2}{opt lab:el}: variable label (synonym: lbl).{p_end} +{p 23 23 2}{opt mean}: mean(synonym: mn).{p_end} +{p 23 23 2}{opt med:ian}: median (synonym: pct50).{p_end} +{p 23 23 2}{opt var:iance}: variance.{p_end} +{p 23 23 2}{opt stddev}: standard deviation (synonym: sd).{p_end} +{p 23 23 2}{opt min:imum}: minimum.{p_end} +{p 23 23 2}{opt max:imum}: maximum.{p_end} +{p 23 23 2}{opt mode}: mode; missing if multiple modes.{p_end} +{p 23 23 2}{opt n:obs}: number of nonmissing cases for variable.{p_end} +{p 23 23 2}{opt nmiss}: number of missing cases for variable.{p_end} +{p 23 23 2}{opt p:ct}{it:#}: percentile for #=1 5 10 25 50 75 90 95 99.{p_end} +{p 23 23 2}{opt val:ues}: percent of cases with values specified with {it:values()}.{p_end} +{synopt :{opt v:alues(string)}}values at which % of cases with that value are listed.{p_end} +{synopt :{opt oth:ervalues}}include % of cases with values not listed in {it:values()}.{p_end} +{synopt :{opt r:ange(string)}}range of values for computing % of cases with those values.{p_end} + +{syntab:Styles of Output} +{synopt :{opt s:tyle(type)}}select style for output. Styles are:{p_end} +{p 23 23 2}{opt basic}: standard output.{p_end} +{p 23 23 2}{opt check}: check the data during cleaning.{p_end} +{p 23 23 2}{opt missing}: look for missing data.{p_end} +{p 23 23 2}{opt names}: just names and labels; this option is equivalent to +the option {opt n:ame} used without the {opt style( )} option (e.g., vardesc, names).{p_end} +{p 23 23 2}{opt outliers}: percentiles to check for outliers.{p_end} +{p 23 23 2}{opt range}: name, N, values and labels.{p_end} + +{syntab:Compressing Output and Removing Spaces} +{synopt :{opt sq:ueeze}}removes extra space; if a column size, truncates, it is not changed.{p_end} +{synopt :{opt sq:min(#)}}is the minimum size of column after squeezing; default 6.{p_end} +{synopt :{opt op:timize}}prints the specified statistics in a minimum of space, with each +column being no smaller than the {cmd:optmin} size.{p_end} +{synopt :{opt optm:in(#)}}is the minimum size of column after optimizing; default 6.{p_end} +{synopt :{opt sp:acer(#)}}spacing added between statistics when using {cmd:squeeze} +and {cmd:optimize}, default 1.{p_end} +{synopt :{opt maxl:ength(#)}}is the maximum line size allowed before length of +label is reduced.{p_end} +{synopt :{opt oclab:el(#)}}override columns used for variable label.{p_end} +{synopt :{opt ocma:x(#)}}override columns used for maximum.{p_end} +{synopt :{opt ocmode(#)}}override columns used for mode.{p_end} +{synopt :{opt ocme:an(#)}}override columns used for mean.{p_end} +{synopt :{opt ocmi:n(#)}}override columns used for minimum.{p_end} +{synopt :{opt ocn:obs(#)}}override columns used for # of observations.{p_end} +{synopt :{opt ocna:me(#)}}override columns used for variable name.{p_end} +{synopt :{opt ocpct:ile(#)}}override columns used for percentiles.{p_end} +{synopt :{opt ocs:d(#)}}override columns used for standard deviation.{p_end} +{synopt :{opt ocv:ar(#)}}override columns used for variance.{p_end} +{synopt :{opt ocval:ues(#)}}override columns used for percent with given value.{p_end} + +{syntab:Main} +{synopt :{opt aorder}}alphabetizes order of variables.{p_end} +{synopt :{opt f:irst(var_name)}}prints this as the first variable.{p_end} +{synopt :{opt forcen}}force printing of nobs for each variable even if same value.{p_end} +{synopt :{opt noh:eader}}surpresses printing of column headings.{p_end} +{synopt :{opt nom:iss}}uses listwise deletion to remove missing data for variables in {it:varlist}.{p_end} +{synopt :{opt num:ber}}number each variables.{p_end} +{synopt :{opt v:erbose}}to print extra information.{p_end} + +{syntab:Alignment of variable name and label} +{synopt :{opt left:label}}left justify printing of the variable label.{p_end} +{synopt :{opt leftn:ame}}left justify printing of the variable name.{p_end} +{synopt :{opt rightl:abel}}right justify printing of the variable label.{p_end} +{synopt :{opt rightn:ame}}right justify printing of the variable name.{p_end} + +{syntab:Column size and decimal digits} +{synopt :{opt c:olumn(#)}}sets default column width used by mean, minimum, maximum, standard deviation and variance.{p_end} +{synopt :{opt clab:el(#)}}sets # columns used for variable label; default 20.{p_end} +{synopt :{opt cma:x(#)}}sets # columns used for maximum; default 10.{p_end} +{synopt :{opt cmode(#)}}sets # columns used for mode; default 10.{p_end} +{synopt :{opt cme:an(#)}}sets # columns used for mean; default 10.{p_end} +{synopt :{opt cmi:n(#)}}sets # columns used for minimum; default 10.{p_end} +{synopt :{opt cn:obs(#)}}sets # columns used for # of observations; default 6.{p_end} +{synopt :{opt cna:me(#)}}sets # columns used for variable name; default 12.{p_end} +{synopt :{opt cpct:ile(#)}}sets # columns used for percentiles; default 10.{p_end} +{synopt :{opt cs:d(#)}}sets # columns used for standard deviation; default 10.{p_end} +{synopt :{opt cv:ar(#)}}sets # columns used for variance; default 10.{p_end} +{synopt :{opt cval:ues(#)}}sets # columns used for percent with given value; default 6.{p_end} +{synopt :{opt d:ecimal(#)}}sets default # if decimal digits used by mean, minimum, maximum, standard deviation and variance.{p_end} +{synopt :{opt dma:x(#)}}sets # decimals used for maximum; default 2.{p_end} +{synopt :{opt dmode(#)}}sets # decimals used for mode; default 2.{p_end} +{synopt :{opt dme:an(#)}}sets # decimals used for mean; default 2.{p_end} +{synopt :{opt dmi:n(#)}}sets # decimals used for minimum; default 2.{p_end} +{synopt :{opt dn:obs(#)}}sets # decimals used for # of observations; default 0.{p_end} +{synopt :{opt dpct:ile(#)}}sets # decimals used for percentiles; default 10.{p_end} +{synopt :{opt ds:d(#)}}sets # decimals used for standard deviation; default 2.{p_end} +{synopt :{opt dval:ues(#)}}sets # of decimals for percent with given value; default 1.{p_end} +{synopt :{opt dv:ar(#)}}sets # decimals used for variance; default 2.{p_end} +{synopt :{opt minl:abel}}minimize column size for label.{p_end} +{synopt :{opt minn:ame}}minimize column size for name.{p_end} +{synoptline} +{p 4 6 2} + +{title:Description} + +{pstd} +{opt vardesc} creates a table to describe a set of specified variables. You can change +the order in which items are listed, column widths for each item, and the number +of decimal digits used.. + +{title:Options} + +{dlgtab:Main} + +{phang} +{opt xxx} By default : + +{p 8 16 2} +aaa{p_end} +{p 8 16 2} +bbb{p_end} +{p 8 16 2} +xxx{p_end} +{title:Acknowledgements} + +{title:Notes:} + +{p 8 16 2}If {it:values} note in {it:order()} but values are listed with {it:values()}, +values are listed as last statistics in table.{p_end} +{p 8 16 2}If all variables have the same number of valid observations, a column with the +sample size is not listed even if you specified {it:nobs} as an options for {it:order}; +to force the printing of the sample size, use option {it:forcen}. + +{title:Examples:} + +{phang}{cmd:. vardesc} + +{title:Author} + +{p 5 5} +J. Scott Long{break} +Indiana University{break} +Departments of Sociology & Statistics{break} +jslong{@}indiana.edu{break} +{browse "http://www.indiana.edu/~jslong/"}{p_end} + diff --git a/Modules/ado/plus/v/varflist.ado b/Modules/ado/plus/v/varflist.ado new file mode 100644 index 0000000..35b60c6 --- /dev/null +++ b/Modules/ado/plus/v/varflist.ado @@ -0,0 +1,89 @@ +program def varflist +*! NJC 1.0.0 3 Feb 2000 + version 6 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax , Generate(str) [ Type(str) Global SCalar STring ] + + confirm new variable `generate' + + local nopts = ("`global'" != "") + ("`scalar'" != "") + if `nopts' == 2 { + di in r "must choose between global and scalar" + exit 198 + } + + local nwords : word count `list' + + local i = 1 + while `i' <= `nwords' { + local len = length("``i''") + if `len' > 80 { + di in r "cannot handle word length > 80" + exit 498 + } + local i = `i' + 1 + } + + if `nwords' > _N { + local n = _N + di in r "too many words: `nwords' words, `n' obs" + exit 498 + } + + if "`string'" != "" { + if "`type'" == "" { local type "str1" } + else if substr("`type'",1,3) != "str" { + di in r "string and type(`type') inconsistent"" + exit 109 + } + } + else if substr("`type'",1,3) == "str" { + local string "string" + } + + tokenize `list' + tempvar g + + if "`string'" != "" { + qui gen `type' `g' = "" + local i = 1 + qui while `i' <= `nwords' { + if "`global'`scalar'" == "" { + replace `g' = "``i''" in `i' + } + else if "`global'" != "" { + replace `g' = "$``i''" in `i' + } + else if "`scalar'" != "" { + local sval = scalar(``i'') + replace `g' = "`sval'" in `i' + } + local i = `i' + 1 + } + } + else { + qui gen `type' `g' = . + local i = 1 + qui while `i' <= `nwords' { + if "`global'`scalar'" == "" { + replace `g' = ``i'' in `i' + } + else if "`global'" != "" { + replace `g' = $``i'' in `i' + } + else if "`scalar'" != "" { + local sval = scalar(``i'') + replace `g' = `sval' in `i' + } + local i = `i' + 1 + } + } + + * only generate new variable if all assignments OK + local type : type `g' + gen `type' `generate' = `g' +end diff --git a/Modules/ado/plus/v/varflist.hlp b/Modules/ado/plus/v/varflist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/v/varflist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/v/vectlist.ado b/Modules/ado/plus/v/vectlist.ado new file mode 100644 index 0000000..ad52fd7 --- /dev/null +++ b/Modules/ado/plus/v/vectlist.ado @@ -0,0 +1,49 @@ +*! NJC 1.1.0 7 June 2000 +* NJC 1.0.0 25 Jan 2000 +program define vectlist, rclass + version 6.0 + gettoken A 0 : 0, parse(" ,") + + capture local nc = colsof(matrix(`A')) + if _rc { + di in r "matrix `A' not found" + exit 111 + } + + local nr = rowsof(matrix(`A')) + + if `nc' > 1 & `nr' > 1 { + di in r "`A' not a vector" + exit 498 + } + + syntax [ , Noisily Global(str) ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + local isrow = `nr' == 1 + local i = 1 + + if `isrow' { + while `i' <= `nc' { + local val = `A'[1, `i'] + local newlist "`newlist'`val' " + local i = `i' + 1 + } + } + else { + while `i' <= `nr' { + local val = `A'[`i', 1] + local newlist "`newlist'`val' " + local i = `i' + 1 + } + } + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list "`newlist'" +end + diff --git a/Modules/ado/plus/v/vectlist.hlp b/Modules/ado/plus/v/vectlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/v/vectlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/v/violin.ado b/Modules/ado/plus/v/violin.ado new file mode 100644 index 0000000..06d51e4 --- /dev/null +++ b/Modules/ado/plus/v/violin.ado @@ -0,0 +1,614 @@ +*! version 1.2.4 TJS 31aug98 STB-46 gr33 +program define violin + version 5.0 + + local varlist "req ex min(1)" + local if "opt" + local in "opt" + local weight "fweight aweight" + #delimit ; + local options "N(integer 50) Width(real 0.0) TRUncat(str) + BIweight COSine EPan GAUss RECtangle PARzen TRIangle + BY(str) Gap(integer 0) ROund(real 0.0) SAving(str) + B2title(str) *" ; + #delimit cr + + parse "`*'" + parse "`varlist'", parse(" ") + +* trap bad options + if index("`options'","tr") > 0 { + di in re "option tr ambiguous, " _c + error 199 + } + + if "`b2title'" != "" { + di in bl "b2title not allowed; option ignored." + } + +* -> Kernel Density code stolen from kdensity.ado + local kflag = ( ("`epan'" != "") + ("`biweigh'" != "") + /* + */ ("`triangl'" != "") + ("`gauss'" != "") + /* + */ ("`rectang'" != "") + ("`parzen'" != "") ) + if `kflag' > 1 { + di in red "specify only one kernel" + exit 198 + } + + if "`biweigh'" != "" { local kernel = "Biweight" } + else if "`cosine'" != "" { local kernel = "Cosine" } + else if "`triangl'" != "" { local kernel = "Triangle" } + else if "`gauss'" != "" { local kernel = "Gaussian" } + else if "`rectang'" != "" { local kernel = "Rectangular" } + else if "`parzen'" != "" { local kernel = "Parzen" } + else { local kernel = "Epanechnikov" } + + tempvar use + quietly { + mark `use' [`weight'`exp'] `if' `in' + markout `use' `varlist' + count if `use' + } + if _result(1) == 0 { error 2000 } + + if "`by'" != "" { + confirm var `by' + unabbrev `by' + local by $S_1 + } + + if "`if'" != "" {ifexp "`if'"} + + preserve /* Note: data preserved here */ + + keep `by' `varlist' `use' + local n1 = `n' + 1 + local n2 = `n' * 2 + 1 + if `n2' > _N { qui set obs `n2' } + +* Generate BY groups + tempvar kk byg bylabel + sort `use' `by' + qui by `use' `by': gen byte `byg' = _n == 1 if `use' + if "`by'" != "" { qui gen `kk' = _n if `byg' == 1 } + qui replace `byg' = sum(`byg') + + if "`by'" != "" { + local byn = `byg'[_N] + sort `kk' + if `use'[`byn'] == . { local byn = `byn' - 1} + } + else { local byn = 1 } + +* Generate `by' labels -- if required + if "`by'" != "" { + capture decode `by', gen(`bylabel') + if _rc != 0 { + local type : type `by' + qui gen `type' `bylabel' = `by' + } + } + + tempname t2flg b1flg + global t2flg = 0 + global b1flg = 0 + +* Do calculations +* get # of vars + local i 1 + while "``i''" != "" { + local i = `i' + 1 + } + local nvars = `i' - 1 + if `nvars' > 1 & "`by'" != "" { + di in red "by() cannot be used with /* + */ multi-variable varlist" + exit + } + +* Note: `k' loops over multiple individual variables +* `j' loops over the levels of a -by- variable + + local k 1 + while "``k''" != "" { + local ix "``k''" + local ixl: variable label ``k'' + if "`ixl'" == "" | `nvars' > 1 { local ixl "``k''" } + + local j = 1 + while `j' <= `byn' { /* start of loop for each `by' group */ + if "`by'" != "" { + sort `kk' + local byl : di "`by': " `bylabel'[`j'] + } + +* boxplot stats + qui centile `ix' if `use' & `byg' == `j', c(25 50 75) + local q25 = $S_7 + local q50 = $S_8 + local q75 = $S_4 +* compute additional boxplot info + tempvar xi + local uav = `q75' + 1.5 * (`q75' - `q25') + qui egen `xi' = max(`ix') /* + */ if `ix' <= `uav' & `use' & `byg' == `j' + local uav = `xi' + drop `xi' + local lav = `q25' - 1.5 * (`q75' - `q25') + qui egen `xi' = min(`ix') /* + */ if `ix' >= `lav' & `use' & `byg' == `j' + local lav = `xi' + drop `xi' + + if `j' == 1 { + quietly summ `ix' [`weight'`exp'] if `use', detail + local ismin = _result(5) + local ismax = _result(6) + if "`by'" != "" { + local isn = _result(1) + local ismn = _result(5) + local ismx = _result(6) + local ism = _result(10) + local is25 = _result(9) + local is75 = _result(11) + local iss = 0 + local isw = 0 + } + } + + if `j' == 1 & "`by'" != "" { + if `width' <= 0 { + tempname wwidth + local ismin = `ism' + local ismax = `ism' + local jj 1 + while `jj' <= `byn' { + quietly summ `ix' [`weight'`exp'] /* + */ if `use' & `byg' == `jj', detail + scalar `wwidth' = 0.9 * min(sqrt(_result(4)), /* + */ (_result(11) - _result(9)) / 1.349) /* + */ / (_result(1)^.2) + local ismin = min(`ismin', _result(5) - `wwidth') + local ismax = max(`ismax', _result(6) + `wwidth') + local jj = `jj' + 1 + } + } + else { + local ismin = `ismn' - `width' + local ismax = `ismx' + `width' + } + } + + quietly summ `ix' [`weight'`exp'] if `use' & `byg' == `j', detail + local ixmin = _result(5) + local ixmax = _result(6) + local ixn = _result(1) + if `gap' == 0 { local gp = 1 + max( /* + */ length(string(round(`ixmin', `round'))), /* + */ length(string(round(_result(10),`round'))), /* + */ length(string(round(`ixmax', `round')))) } + else { local gp = `gap' } + + tempname wwidth + scalar `wwidth' = `width' + if `wwidth' <= 0.0 { + scalar `wwidth' = 0.9 * min(sqrt(_result(4)),(_result(11) /* + */ - _result(9)) / 1.349) / (_result(1)^.2) + } + local ww = `wwidth' + + tempvar d m + qui gen double `d' = . + qui gen double `m' = . + + kd `ix' `d' `m' `use' `byg' [`weight'`exp'], n(`n') /* + */ ww(`ww') j(`j') `biweight' `cosine' `epan' /* + */ `gauss' `rectangle' `parzen' `triangle' + + label var `d' "density" + label var `m' "`ixl'" + +* truncat option + if "`truncat'" != "" { + if "`truncat'" == "*" { + local tn = `ixmin' + local tx = `ixmax' + } + else { + quietly summ `m' [`weight'`exp'] if `use', detail + local ismn = _result(5) + local ismx = _result(6) + local nc 1 + while `nc' > 0 { + local nc = index("`truncat'",",") + if `nc' > 0 { local truncat = substr("`truncat'",1, /* + */ `nc' - 1) + " " + substr("`truncat'",`nc' + 1,.) } + } + local tn: word 1 of `truncat' + local tx: word 2 of `truncat' + local tn = real("`tn'") + local tx = real("`tx'") + if `tn' > `ismn' { local tn = min(`tn',`ixmin') } + if `tx' < `ismx' { local tx = max(`tx',`ixmax') } + } + qui replace `m' = . if `m' < `tn' | `m' > `tx' + } + qui summ `d' in 1/`n' + local scale = 1 / (`n' * _result(3)) + qui replace `d' = `d' * `scale' in 1/`n' + + local n21 = `n' * 2 + 1 + qui replace `d' = -`d'[`n21' - _n] in `n1'/`n2' + qui replace `m' = `m'[`n21' - _n] in `n1'/`n2' + qui replace `d' = `d'[1] in `n2' + qui replace `m' = `m'[1] in `n2' + + if "`truncate'" != "" { + tempvar tm1 tm2 + qui gen `tm2' = _n + qui gen `tm1' = sign(`d') + gsort -`tm1' `m' + local tm = `m'[1] + local td = `d'[1] + sort `tm2' + qui replace `d' = `td' in `n2' + qui replace `m' = `tm' in `n2' + } + + if "`by'" != "" { + local iss = `iss' + `scale' + local isw = `isw' + `wwidth' + } + +* saving option + if `j' * `k' == 1 & "`saving'" != "" { + local c = index("`saving'",",") + local cs " " + if index("`saving'",", ") != 0 { local cs "" } + if `c' != 0 { local saving = substr("`saving'",1,`c' - 1) /* + */ + "`cs'" + substr("`saving'",`c' + 1, .) } + local savfile : word 1 of `saving' + local replace : word 2 of `saving' + if "`replace'" == "replace" { capture erase "`savfile'.gph" } + capture confirm new file "`savfile'.gph" + if _rc == 0 { local saving ", saving(`savfile')" } + else { + local rc = _rc + di in re "file `savfile'.gph exists." + di in bl "use another filename or add 'replace' option." + exit `rc' + } + } + + if "`byl'" != "" { local bylbyl byl("`byl'") } + + tempname ixlixl + global ixlixl "`ixl'" + +* do plot + if `j' * `k' == 1 { gph open `saving' } + viogph `d' `m', j(`j') k(`k') byn(`byn') ixmin(`ixmin') /* + */ ixmax(`ixmax') q50(`q50') ismin(`ismin') ismax(`ismax') /* + */ nvars(`nvars') gp(`gp') `bylbyl' uav(`uav') lav(`lav') /* + */ q75(`q75') q25(`q25') rou(`round') `options' + + if `j' >= `byn' & `k' >= `nvars' { gph close } + +* display stats + if `byn' == 1 { + di _n in gr "Statistics for ``k'':" + di in gr " LAV: " in ye `lav' _c + di in gr " Q25: " in ye `q25' _c + di in gr " Q75: " in ye `q75' _c + di in gr " UAV: " in ye `uav' + di in gr " Min: " in ye `ixmin' _c + di in gr " Median: " in ye `q50' _c + di in gr " Max: " in ye `ixmax' _c + di in gr " n: " in ye `ixn' + di _n in gr "For ``k'', density computed using:" + di in gr " Kernel: " in ye "`kernel'" _c + di in gr " N: " in ye `n' _c + di in gr " Scale: " in ye %6.2f `scale' _c + di in gr " Width: " in ye %6.2f `wwidth' + } + local j = `j' + 1 + } /* end of loop for each `by' group */ + + if "`by'" != "" { + di _n in gr "Statistics (all groups combined): " + di in gr " Min: " in ye `ismn' _c + di in gr " Q25: " in ye `is25' _c + di in gr " Median: " in ye `ism' _c + di in gr " Q75: " in ye `is75' _c + di in gr " Max: " in ye `ismx' _c + di in gr " n: " in ye `isn' + di _n in gr "Densities computed using:" + di in gr " Kernel: " in ye "`kernel'" _c + di in gr " N: " in ye `n' _c + di in gr " Ave. Scale: " in ye %6.2f `iss' / `byn' _c + di in gr " Ave. Width: " in ye %6.2f `isw' / `byn' + local scale = `iss' / `byn' + local wwidth = `isw' / `byn' + local ixmin = `ismn' + local lav = . + local q25 = `is25' + local q50 = `ism' + local q75 = `is25' + local uav = . + local ixmax = `ismx' + local ixn = `isn' + } + local k = `k' + 1 +} +* save globals + global S_1 "`kernel'" + global S_2 = `n' + global S_3 = `wwidth' + global S_4 = `scale' + global S_5 = `ixmin' + global S_6 = `lav' + global S_7 = `q25' + global S_8 = `q50' + global S_9 = `q75' + global S_10 = `uav' + global S_11 = `ixmax' + global S_12 = `ixn' + + macro drop ixlixl b1flg t2flg +end + + +program define viogph + version 5.0 + + local varlist "req ex min(2) max(2)" + #delimit ; + local options "J(int 1) K(int 1) BYN(int 1) TItle(str) B1title(str) + IXMIN(real 0.0) IXMAX(real 0.0) Q50(real 0.0) ISMIN(real 0.0) + ISMAX(real 0.0) NVARS(int 0) GP(int 3) BYL(str) UAV(real 0.0) + LAV(real 0.0) Q75(real 0.0) Q25(real 0.0) Pen(str) Symbol(str) + Connect(str) T1title(str) T2title(str) YLAbel(str) YSCale(str) + ROUnd(real 0.0) *" ; + #delimit cr + + parse "`*'" + parse "`varlist'", parse(" ") + + local d "`1'" + local m `2' + + local t2t2 = $t2flg + local b1b1 = $b1flg + local ixl = "$ixlixl" + +* set up the plot + + if "`pen'" == "" { local pen "2" } + if "`symbol'" == "" { local symbol "i" } + if "`connect'" == "" { local connect "l" } + + if `j' == 1 & `k' == 1 { + if "`t1title'" == "." { local t1title t1t(" ") } + else if "`t1title'" == "" { local t1title t1t(Violin Plot) } + else { local t1title t1t("`t1title'") } + if `byn' > 1 { local t1title t1t("`ixl'") } + } + if `j' > 1 | `k' > 1 { local t1title t1t(" ") } + + if `j' == 1 & `k' == 1 { + if "`t2title'" != "" { + local t2title t2t("`t2title'") + local t2t2 1 + } + } + else if `t2t2' == 1 { local t2title t2t(" ") } + + if "`title'" == "" { local title "`b1title'" } + if "`title'" != "" { + local b1title b1t(" ") + local b1b1 1 + } + + if "`ylabel'" == "" { local yl = "yla(" /* + */ + string(round(`ixmin',`round')) + "," /* + */ + string(round(`q50',`round')) + "," /* + */ + string(round(`ixmax',`round')) + ")" } + else { local yl yla(`ylabel') } + if index("`options'","yla") > 0 { local yl "" } + + if "`yscale'" == "" { local ys ysc(`ismin',`ismax') } + else { local ys ysc(`yscale') } + +* do plot + +* draw density traces + local pw = min(.33, 1 / (`byn' * `nvars') ) + local pw = 32000 * `pw' + local p1 = (`j' * `k' - 1) * `pw' + local p2 = `p1' + `pw' + #delimit ; + graph `m' `d', bbox(0,`p1',23063,`p2',923,444,0) s(`symbol') + c(`connect') pe(`pen') `t1title' `yl' gap(`gp') `ys' `t2title' + `b1title' b2t(" ") `options' ; + #delimit cr + tempname ysca yloc xloc + scalar `ysca' = _result(5) + scalar `yloc' = _result(6) + scalar `xloc' = _result(8) +* draw label + local r1 = 20700 + local r2 = 21700 + local c1 = 21500 + if `b1b1' == 1 { + local r1 = `r1' - 1000 + local r2 = `r2' - 1000 + local c1 = `c1' - 1000 + } + gph clear `r1' `p1' `r2' `p2' + gph pen 1 + local xlo = `xloc' + if `byn' == 1 { gph text `c1' `xlo' 0 0 `ixl' } + else { gph text `c1' `xlo' 0 0 `byl' } +* do title + if "`title'" != "" { + gph font 1300 650 + gph text 22100 10 0 -1 `title' + gph font 923 444 + } +* draw adjacent values line + local r1 = `uav' * `ysca' + `yloc' + local r2 = `lav' * `ysca' + `yloc' + local c1 = `xloc' + local c2 = `c1' + gph pen `pen' + gph line `r1' `c1' `r2' `c2' +* draw quartile box (shaded) + local r1 = `q75' * `ysca' + `yloc' + local r2 = `q25' * `ysca' + `yloc' + local c1 = -250 + `xloc' + local c2 = 250 + `xloc' + gph box `r1' `c1' `r2' `c2' 1 +* draw median + local r1 = `q50' * `ysca' + `yloc' + 100 + local r2 = `q50' * `ysca' + `yloc' - 100 + local c1 = -500 + `xloc' + local c2 = 500 + `xloc' + gph box `r1' `c1' `r2' `c2' 0 + + global t2flg = `t2t2' + global b1flg = `b1b1' +end + + +program define kd + version 5.0 +* -> Kernel Density code stolen from kdensity.ado + + local varlist "req ex min(1) max(5)" + local weight "fweight aweight" + #delimit ; + local options "N(integer 50) WW(real 0.0) J(int 1) + BIweight COSine EPan GAUss RECtangle PARzen TRIangle" ; + #delimit cr + + parse "`*'" + parse "`varlist'", parse(" ") + + local ix "`1'" + local d "`2'" + local m "`3'" + local use "`4'" + local byg "`5'" + + tempvar y z + qui gen double `y' = . + qui gen double `z' = . + + tempname delta wid wwidth + scalar `wwidth' = `ww' + scalar `delta' = (_result(6) - _result(5) + 2 * `wwidth') /* + */ / (`n' - 1) + scalar `wid' = _result(1) * `wwidth' + qui replace `m' = _result(5) - `wwidth' + (_n - 1) /* + */ * `delta' in 1/`n' + + local i 1 + if "`biweigh'" != "" { + local con1 = .9375 + while `i' <= `n' { + qui replace `z' = (`ix' - `m'[`i']) / (`wwidth') /* + */ if `use' & `byg' == `j' + qui replace `y' = `con1' * (1 - (`z')^2)^2 /* + */ if abs(round(`z',1e-8)) < 1 + qui summ `y' [`weight'`exp'] if `y' != . + qui replace `d' = (_result(3) * _result(1)) / `wid' in `i' + qui replace `y' = . + local i = `i' + 1 + } + qui replace `d' = 0 if `d' == . in 1/`n' + } + else if "`cosine'" != "" { + while `i' <= `n' { + qui replace `z' = (`ix' - `m'[`i']) / (`wwidth') /* + */ if `use' & `byg' == `j' + qui replace `y' = 1 + cos(2 * _pi * `z') /* + */ if abs(round(`z',1e-8)) < 0.5 + qui summ `y' [`weight'`exp'] if `y' != . + qui replace `d' = (_result(3) * _result(1)) / `wid' in `i' + qui replace `y' = . + local i = `i' + 1 + } + qui replace `d' = 0 if `d' == . in 1/`n' + } + else if "`triangl'" != "" { + while `i' <= `n' { + qui replace `z' = (`ix' - `m'[`i']) / (`wwidth') /* + */ if `use' & `byg' == `j' + qui replace `y' = 1 - abs(`z') if abs(round(`z',1e-8)) < 1 + qui summ `y' [`weight'`exp'] if `y' != . + qui replace `d' = (_result(3) * _result(1)) / `wid' in `i' + qui replace `y' = . + local i = `i' + 1 + } + qui replace `d' = 0 if `d' == . in 1/`n' + } + else if "`parzen'" != "" { + local con1 = 4 / 3 + local con2 = 2 * `con1' + while `i' <= `n' { + qui replace `z' = (`ix' - `m'[`i']) / (`wwidth') /* + */ if `use' & `byg' == `j' + qui replace `y' = `con1' - 8 * (`z')^2 + 8 * abs(`z')^3 /* + */ if abs(round(`z',1e-8)) <= .5 + qui replace `y' = `con2' * (1 - abs(`z'))^3 /* + */ if abs(round(`z',1e-8)) > .5 /* + */ & abs(round(`z',1e-8)) < 1 + + qui summ `y' [`weight'`exp'] if `y' != . + qui replace `d' = (_result(3) * _result(1)) / `wid' in `i' + qui replace `y' = . + local i = `i' + 1 + } + qui replace `d' = 0 if `d' == . in 1/`n' + } + else if "`gauss'" != "" { + local con1 = sqrt(2 * _pi) + while `i' <= `n' { + qui replace `z' = (`ix' - `m'[`i']) / (`wwidth') /* + */ if `use' & `byg' == `j' + qui replace `y' = exp(-0.5 * ((`z')^2)) / `con1' + qui summ `y' [`weight'`exp'] + qui replace `d' = (_result(3) * _result(1)) / `wid' in `i' + local i = `i' + 1 + } + qui replace `d' = 0 if `d' == . in 1/`n' + } + else if "`rectang'" != "" { + while `i' <= `n' { + qui replace `z' = (`ix' - `m'[`i']) / (`wwidth') /* + */ if `use' & `byg' == `j' + qui replace `y' = 0.5 if abs(round(`z',1e-8)) < 1 + qui summ `y' [`weight'`exp'] if `y' != . + qui replace `d' = (_result(3) * _result(1)) / `wid' in `i' + qui replace `y' = . + local i = `i' + 1 + } + qui replace `d' = 0 if `d' == . in 1/`n' + } + else { + local con1 = 3 / (4 * sqrt(5)) + local con2 = sqrt(5) + while `i' <= `n' { + qui replace `z' = (`ix' - `m'[`i']) / (`wwidth') /* + */ if `use' & `byg' == `j' + qui replace `y' = `con1' * (1 - ((`z')^2 / 5)) /* + */ if abs(round(`z',1e-8)) <= `con2' + qui summ `y' [`weight'`exp'] if `y' != . + qui replace `d' = (_result(3) * _result(1)) / `wid' in `i' + qui replace `y' = . + local i = `i' + 1 + } + qui replace `d' = 0 if `d' == . in 1/`n' + } +end + diff --git a/Modules/ado/plus/v/violin.hlp b/Modules/ado/plus/v/violin.hlp new file mode 100644 index 0000000..e6431d9 --- /dev/null +++ b/Modules/ado/plus/v/violin.hlp @@ -0,0 +1,165 @@ +.- +help for ^violin^ (STB-46: gr33) +.- + +Violin plots +------------ + + ^violin^ varlist [weight] [^if^ exp] [^in^ range] + [^,^ {^bi^weight|^cos^ine|^ep^an|^gau^ss|^par^zen|^rec^tangle|^tri^angle} + ^n(^#^) w^idth^(^#^) by(^byvar^) tru^ncat^(^#,#|*^) ro^und^(^#^)^ + graph_options ] + +^fweights^ and ^aweights^ are allowed; see ^help^ @weights@. + + +Description +----------- + +^violin^ produces violin plots, a graphical box plot--kernel density synergism. +The violin plot combines the basic summary statistics of a box plot with the +visual information provided by a local density estimator. The goal is to +reveal the distributional structure in a variable. Much like a traditional +box plot, the violin plot displays the median as a short horizontal line, the +first-to-third interquartile range as a narrow shaded box, and the lower-to- +upper adjacent value range as a vertical line, but it does not plot outside +values. Instead, it "boxes" the data with mirrored density curves and labels +the y-axis at the minimum, median and maximum observed data values. + +^violin^ also lists basic descriptive statistics about the data (i.e., the +lower and upper adjacent values, the 25th and 75th centiles, the minimum, +median and maximum of the data, and the sample size) and it provides +information about the density estimation (i.e., the kernel method used, the +number of points of estimation, and the resulting scale and width factors). +When ^by()^ is specified, descriptive statistics are displayed for the combined +group only. When multiple variables are included in varlist, statistics are +displayed for the last variable only. + +^violin^ discards observations on an casewise basis as a function of 1) missing +data and 2) the ^if^ (or ^in^) specification (i.e, it ignores the entire +observation). This behavior may lead to unexpected results when multiple +variables are in the varlist. + +Note: ^violin^ calls ^centile^ to compute the needed centiles but ^centile^ does + not respond to a ^[weight]^ specification. This conflicts with the + ^kdensity^ code which responds to that specification. The implications of + this conflict have not been explored, but ^violin^ currently allows the the + ^[weight]^ specification to be passed through to ^kdensity^. + +Note: ^violin^ uses a low-level ^gph^ command which is not supported in Stata's + release 2 ^.gph^ format. As a result neither ^Stage^ nor the ^gphdot^ or + ^gphpen^ DOS-based graphics output programs can process a saved violin-plot + graphics file. This limitation does not affect screen display or output + using the ^Print Graph^ option of Stata's ^File^ menu. + + +Options +------- + +^biweight^, ^cosine^, ..., ^triangle^ specify the kernel. By default, ^epan^, the + Epanechnikov kernel, is used. + +^n(^#^)^ specifies the number of points at which density estimates will be + evaluated. The default is 50. + +^width(^#^)^ specifies the halfwidth of the kernel, the width of the density + window around each point. If ^width()^ is not specified, then the "optimal" + width is used; see ^[R] kdensity^. For multimodal and highly skewed + densities, the "optimal" width is usually too wide and oversmooths the + density. + +^by(^byvar^)^ produces separate plots for the groups of observations defined by + byvar and displays them in a single graph having common vertical scale. + ^by()^ cannot be specified when there is more than one variable in the + varlist. + +^truncat(^#^,^#|^*)^ limits the range of the density trace, either to a range + specified as ^(^#^,^#^)^, or to the observed data limits, specified as ^(*)^. + Regardless of the actual ^(^#^,^#^)^ specification, the maximum range truncation + honored is the observed data limits. The precise truncation points will + be the most extreme points within the specified range where the density is + calculated (the points of density calculation depend on ^n()^, ^width()^ + and the observed data). + +^round(^#^)^ rounds the y-axis numeric labels to the value specified. As a result, + the labels and their corresponding tic marks may not be placed at the true + minimum, median, or maximum values, rather they will be at the rounded + values. ^round()^ has no effect if ^ylabel^ is specified without arguments, + but is operative if ^ylabel^ is not specified or is specified with arguments. + The ^round()^ option follows the rules of Stata's ^round(^x^,^y^)^ function, with + # being the y argument and each label value being the x argument; + see ^[U] 20.3.5 Special functions^. + +graph_options are any of the options allowed by ^graph, twoway^ except ^b2title()^ + (which is ignored); see ^help^ @graph@. Some options are preset and, although + changeable, usually should not be modified. These include ^symbol(i)^ and + ^connect(l)^ for specifying the plotting symbol and point connection method + for the density curve. In addition, ^ylabel()^ is preset to label only the + minimum, median and maximum points. ^t1title(Violin Plot)^ is preset but can + be changed--except when ^by()^ is specified; in this instance ^t1title^ is used + for the variable name or label. When changeable, use of ^t1title(.)^ will + result in a blank title. Other preset options, such as ^pen(2)^ for the + plot pen color, are intended to be freely changed to suit user preference. + A few options, such as the left and right titles, are set (or default to) + blank. If specified, they appear beside each plot in a multi-variable + graph. Lastly, the ^saving()^ option differs slightly from ^graph^'s in + that the filename extension is always ^.gph^ and must not be specified. + + +Saved values +------------ + + S_1 name of kernel used for density trace + S_2 number of points of density estimation + S_3 band width for density estimation + S_4 scale factor of density plot + S_5 minimum + S_6 lower adjacent value + S_7 first quartile + S_8 median + S_9 third quartile + S_10 upper adjacent value + S_11 maximum + S_12 n + +When ^by()^ is specified: S_3 and S_4 contain the averages of the band width and +scale factors used in the subgroup density estimations; S_5, S_7, S_8, S_9, +S_11 and S_12 are statistics for the combined group; and S_6 and S_10 are set +missing. + +When multiple variables are specified, the saved values contain results for +the last variable in the varlist. + + +Examples +-------- + + . ^violin length, t1(Auto data) l1(length of car)^ + + . ^violin length weight, n(100) w(20)^ + + . ^violin weight, by(foreign) parzen^ + + +Author +------ + + Thomas J. Steichen + RJRT + steicht@@rjrt.com + + +Reference +--------- + +Hintze, J. L. and R. D. Nelson (1998). "Violin plots: a box plot-density trace + synergism." The American Statistician, 52(2):181-4. + + +Also see +-------- + + STB: gr33 (STB-46) + Manual: ^[R] kdensity^, ^[R] graph box^, ^[R] centile^ + ^[U] 20.3.5 Special functions^ +On-line: help for @kdensity@, @graph@, @centile@, @functions@ diff --git a/Modules/ado/plus/w/wclist.ado b/Modules/ado/plus/w/wclist.ado new file mode 100644 index 0000000..3156375 --- /dev/null +++ b/Modules/ado/plus/w/wclist.ado @@ -0,0 +1,22 @@ +program def wclist, rclass +*! NJC 1.1.0 6 June 2000 +* NJC 1.0.0 13 March 2000 + version 6.0 + gettoken list 0 : 0, parse(",") + if "`list'" == "" | "`list'" == "," { + di in r "nothing in list" + exit 198 + } + syntax , [ Global(str) Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + local nw : word count `list' + if "`noisily'" != "" { di `nw' } + if "`global'" != "" { global `global' `nw' } + return local nw `nw' +end + diff --git a/Modules/ado/plus/w/wclist.hlp b/Modules/ado/plus/w/wclist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/w/wclist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/w/wsanova.ado b/Modules/ado/plus/w/wsanova.ado new file mode 100644 index 0000000..c396e0d --- /dev/null +++ b/Modules/ado/plus/w/wsanova.ado @@ -0,0 +1,373 @@ +program define wsanova +*! version 1.0.1 STB-47 sg103 +** Author: John R. Gleason, Syracuse University, Syracuse NY, USA +** (loesljrg@ican.net) + + version 5.0 + + local varlist "req ex min(2) max(2)" + local if "opt" + local in "opt" + local weight "aweight fweight" + local options /* + */ "BETween(string) EPSilon ID(string) NOMatr WOnly(string)" + parse "`*'" + parse "`varlist'", parse(" ") + local Wt = substr("`exp'", 2, .) + local weight "[`weight'`exp']" + if "`id'" == "" { + di in red "option id() is required" + error 499 + } + unabb `id' + local id : word 1 of $S_1 + + quietly { + tempvar use + mark `use' `weight' `if' `in' + markout `use' `varlist' $S_1 + count if `use' + if !_result(1) { error 2000 } + local NN = _result(1) + mac drop WSAoV* + xpd `between' + local between "$S_2" + local BFact "$S_3" + local ErrB "`id'$S_4" + if "`wonly'" != "" { + xpd `wonly' + local wonly "$S_2" + local i 0 + local NS : word count $S_3 + while `i' < `NS' { + local i = `i' + 1 + local a : word `i' of $S_3 + if "`a'" != "`2'" & !index("`BFact'", "`a'") { + di in red "`a' not among the Between factors" + error 499 + } + } + } + else { + local wonly "`2'" + local i 0 + local NS : word count `between' + while `i' < `NS' { + local i = `i' + 1 + local a : word `i' of `between' + local wonly "`wonly' `2'*`a'" + } + } + local ifuse "if `use'" + local epsilon = "`epsilon'" != "" + if `epsilon' { + qui tab `id' `ifuse' + local NS = _result(2) + qui tab `2' `ifuse' + local NW = _result(2) + if `NN' != `NW'*`NS' { + di in red "epsilon option is invalid with missing data" + error 499 + } + local i 1 + qui cap assert _N >= 0 + while !_rc { + local i = `i' + 1 + cap matrix drop WSAoV`i' + cap matrix drop WSAov`i' + } + + preserve + keep `ifuse' + keep `varlist' `id' `BFact' `Wt' + local ifuse + sort `BFact' `id' `2' + tempvar Group + if "`BFact'" == "" { gen byte `Group' = 1 } + else { + by `BFact': gen int `Group' = _n==_N + replace `Group' = sum(`Group') + by `BFact': replace `Group' = /* + */ 1 + `Group' + cond(_n==_N,-1,0) + } + global WSAoV_VN "`1'" + global WSAoV_WV : display %8.0g `2'[1] + local t : type `1' + local i 1 + while `i' < `NW' { + local i = `i' + 1 + tempvar y`i' + by `BFact' `id': gen `t' `y`i'' = `1'[`i'] if _n==1 + global WSAoV_VN "$WSAoV_VN `y`i''" + local vl : display %8.0g `2'[`i'] + global WSAoV_WV "$WSAoV_WV `vl'" + } + + tempname Adf + local i = `NW' - 1 + matrix WSAoV_c = J(`i', `NW', 0) + local i 1 + while `i' < `NW' { + scalar `Adf' = sqrt(1/(`i'*(`i'+1))) + local a 0 + while `a' < `i' { + local a = `a' + 1 + matrix WSAoV_c[`i',`a'] = `Adf' + } + local a = `a' + 1 + matrix WSAoV_c[`i',`a'] = -`i'*`Adf' + local i = `i' + 1 + } + matrix WSAoV_ = J(`NW', `NW', 0) + matrix WSAov_ = J(1, `NW', 0) + global WSAoV_DF 0 + qui summ `Group', meanonly + local NG = _result(6) /* #(groups) */ + sort `y2' /* put usable rows at the top */ + local i 0 + while `i' < `NG' { + local i = `i' + 1 + GetM `i' if `Group'==`i' in 1/`NS' + GetE WSAoV`i' WSAoV_c + } + scalar `Adf' = 1/$WSAoV_DF + matrix WSAoV_ = `Adf' * WSAoV_ + matrix rownames WSAoV_ = $WSAoV_WV + matrix colnames WSAoV_ = $WSAoV_WV + matrix rownames WSAov_ = Means + matrix colnames WSAov_ = $WSAoV_WV + if "`BFact'" == "" { matrix drop WSAoV1 WSAov1 } + else { + global WSAoV_df "${WSAoV_df}$WSAoV_DF" + GetE WSAoV_ WSAoV_c + } + matrix drop WSAoV_c + if "`nomatr'" != "" { matrix drop $WSAoVmn WSAoV_ WSAov_ } + } + } + + global WSAoVcmd "`varlist' `weight' `if' `in', id(`id')" + if "`between'" != "" { + global WSAoVcmd "$WSAoVcmd bet(`between')" + qui anova `1' `between' `2' `weight' `ifuse' + GetF `between' + qui test `between' + local BetSS = _result(2) + local BetDF = _result(3) + } + qui anova `1' `between' `ErrB' `wonly' `weight' `ifuse' + local ErrWdf = _result(5) + local ErrWss = _result(4) + local TotSS = _result(2) + _result(4) + local TotDF = _result(3) + _result(5) + + di _new _sk(27) in gr "Number of obs =" in ye %8.0g _result(1) /* + */ _sk(5) in gr "R-squared" _sk(5) "=" in ye %8.4f /* + */ _result(7) _new _sk(27) in gr "Root MSE" _sk(6) /* + */ "=" in ye %8.0g _result(9) _sk(5) in gr /* + */ "Adj R-squared =" in ye %8.4f _result(8) _new _new /* + */ _sk(18) in gr "Source | Partial SS df" _sk(7) /* + */ "MS" _sk(11) "F" _sk(5) "Prob > F" _new _sk(14) /* + */ _dup(11) "-" "+" _dup(52) "-" + + qui test `ErrB' + local t1 = _result(2) + local df_eB = _result(3) + global WSAoV_Ft "${WSAoV_Ft}`t1' `df_eB'" + local MSeB = _result(2)/_result(3) + if "`between'" != "" { + /* do the Between SS and df line */ + local t1 = `BetSS' / `BetDF' + local t2 = `t1' / `MSeB' + di _sk(4) in gr "Between subjects: | " in ye %11.0g /* + */ `BetSS' %6.0g `BetDF' " " %11.0g /* + */ `t1' %11.2f `t2' %11.4f /* + */ fprob(`BetDF', _result(3), `t2') + } + PutF `between' `ErrB' + qui test `wonly' + if "`between'" != "" { + di in gr _sk(25) "|" _new _sk(5) "Within subjects: | " /* + */ in ye %11.0g _result(2) %6.0g _result(3) " " %11.0g /* + */ _result(2)/_result(3) %11.2f _result(6) %11.4f /* + */ fprob(_result(3), _result(5), _result(6)) + } + GetF `wonly' + global WSAoV_Ft "${WSAoV_Ft}`ErrWss' `ErrWdf'" + PutF `wonly' Residual + di in gr _sk(14) _dup(11) "-" "+" _dup(52) "-" _new _sk(19) /* + */ "Total | " in ye %11.0g `TotSS' %6.0g `TotDF' " " /* + */ %11.0g `TotSS'/`TotDF' + if `epsilon' { + #delimit ; + di in bl _new _sk(6) + "Note: Within subjects F-test(s) above assume sphericity of" + " residuals;" _new _sk(12) + "p-values corrected for lack of sphericity appear below."; + #delimit cr + local dfw = `NW' - 1 + local i : word count $WSAoV_E + local eps : word `i' of $WSAoV_E + local i = `dfw' * `eps' + local i = min(1, (`NS'*`i' - 2)/ (`dfw'*(`df_eB' - `i')) ) + di in gr _new "Greenhouse-Geisser (G-G) epsilon:", in ye /* + */ %6.4f `eps' _new in gr "Huynh-Feldt (H-F) epsilon:", /* + */ in ye %6.4f `i' _new in gr _sk(46) "Sphericity" /* + */ _sk(6) "G-G" _sk(8) "H-F" _new _sk(18) "Source |" /* + */ _sk(5) "df" _sk(8) "F" _sk(3) _dup(3) " Prob > F" /* + */ _new _sk(14) _dup(11) "-" "+" _dup(52) "-" + X `ErrWdf' `eps' `i' `wonly' + } + macro drop WSAoV_VN WSAoV_WV WSAoV_Ft WSAoVmn +end + + +program define unabb + local varlist "req ex" + parse "`*'" + global S_1 "`varlist'" +end + + +program define GetM + local I `1' + local name "WSAoV`1'" + local Mname "WSAov`1'" + global WSAoVmn "${WSAoVmn}`name' `Mname' " + mac shift + matrix accum `name' = $WSAoV_VN `*', dev nocon means(`Mname') + local a = _result(1) - 1 + matrix rownames `name' = $WSAoV_WV + matrix colnames `name' = $WSAoV_WV + matrix rownames `Mname' = Means + matrix colnames `Mname' = $WSAoV_WV + tempname Adf XB XB2 + scalar `Adf' = _result(1) + matrix `XB' = `Adf' * `Mname' + scalar `Adf' = $WSAoV_DF + `I' - 1 + matrix `XB2' = `Adf'*WSAov_ + matrix `XB' = `XB' + `XB2' + scalar `Adf' = 1/(_result(1) + `Adf') + matrix WSAov_ = `Adf' * `XB' + global WSAoV_df "${WSAoV_df}`a' " + global WSAoV_DF = $WSAoV_DF + `a' + matrix WSAoV_ = WSAoV_ + `name' + scalar `Adf' = 1/(_result(1)-1) + matrix `name' = `Adf' * `name' +end + + +program define GetE + tempname A a1 + matrix `A' = `2' * `1' + matrix `A' = `A' * `2'' + scalar `a1' = trace(`A') + matrix `A' = `A' * `A' + local eps = `a1'*`a1'/(rowsof(`2')*trace(`A')) + local eps : display %9.0g `eps' + global WSAoV_E "${WSAoV_E}`eps' " +end + + +program define X + local dfEw = `1' + local E1 = `2' + local E2 = `3' + mac shift 3 + local i 0 + while "`1'" != "" { + Brk `1' + local i = `i' + 1 + local F : word `i' of $WSAoV_Ft + local i = `i' + 1 + local df1 : word `i' of $WSAoV_Ft + di in ye %6.0g `df1' _sk(1) /* + */ %10.2f `F' _sk(4) %8.4f fprob(`df1', `dfEw', `F') /* + */ _sk(3) %8.4f fprob(`df1'*`E1', `dfEw'*`E1', `F') /* + */ _sk(3) %8.4f fprob(`df1'*`E2', `dfEw'*`E2', `F') + mac shift + } +end + + +program define xpd + macro drop S_2 S_3 S_4 + parse "`*'", parse(" *") + local i 1 + while "``i''" != "" { + local Sp = `i' + 1 + if "``Sp''" == "*" { local Sp } + else { local Sp " " } + if "``i''" != "*" { + unabb ``i'' + if !index("$S_3", "$S_1") { + global S_3 "${S_3}$S_1 " + global S_4 "${S_4}*$S_1" + } + global S_2 "${S_2}$S_1`Sp'" + } + else { + global S_2 "${S_2}*" + } + local i = `i' + 1 + } +end + + +program define GetF + global WSAoV_Ft + while "`1'" != "" { + qui test `1' + local t1 = _result(2) + local t2 = _result(3) + global WSAoV_Ft "${WSAoV_Ft}`t1' `t2' " + mac shift + } +end + + +program define PutF + local T : word count $WSAoV_Ft + local dfe : word `T' of $WSAoV_Ft + local T = `T' - 1 + local MSe : word `T' of $WSAoV_Ft + local MSe = `MSe' / `dfe' + local i 0 + while "`1'" != "" { + Brk `1' + local i = `i' + 1 + local SS : word `i' of $WSAoV_Ft + local i = `i' + 1 + local df : word `i' of $WSAoV_Ft + local MS = `SS' / `df' + local F = `MS' / `MSe' + di in ye %11.0g `SS' %6.0g `df', %11.0g `MS' _con + if `F' != 1.0 { + di in ye %11.2f `F', %10.4f fprob(`df', `dfe', `F') + local FT "`FT'`F' `df' " + } + else { di " " } + + mac shift + } + global WSAoV_Ft "`FT'" +end + + +program define Brk + local L 24 + parse "`*'", parse("*") + local i 1 + while "``i''" != "" { + local a + local j = `i' + 1 + while length("`a'``i''``j''") < `L' & "``i''" != "" { + local a "`a'``i''``j''" + local i = `i' + 2 + local j = `i' + 1 + } + local j = `L' - length("`a'") + di `New' _dup(`j') " " in gr "`a' | " _con + local New "_new" + } +end diff --git a/Modules/ado/plus/w/wsanova.hlp b/Modules/ado/plus/w/wsanova.hlp new file mode 100644 index 0000000..0fbe869 --- /dev/null +++ b/Modules/ado/plus/w/wsanova.hlp @@ -0,0 +1,86 @@ +.- +help for ^wsanova^ (STB-47: sg103) +.- + +within subjects ANOVA, with zero or more between subjects factors +----------------------------------------------------------------- + + ^wsanova^ yvar wfact [weight] [^if^ exp] [^in^ range] , ^id(^svar^)^ + [^bet^ween^(^beffects^) wo^nly^(^weffects^) eps^ilon ^nom^atr ] + +^aweights^ and ^fweights^ are allowed; see help @weights@. + + +Description +----------- + +^wsanova^ performs a within subjects (repeated measures) analysis of variance for +the response variable yvar classified by the within subjects factor wfact. The +subjects are identified by the variable svar, and may be classified by one or +more between subjects factors. Within subjects F tests can be adjusted for lack +of sphericity using the Greenhouse-Geisser or Huynh-Feldt correction factor. + + +Options +------- + +^id(svar)^ declares that the variable svar uniquely identifies each subject to be + used in the analysis. [Not optional.] + +^between(beffects)^ supplies a list of between subjects factors that classify the + subjects, along with zero or more of their interactions. Up to 7 such fac- + tors can be used; their interactions must be explicitly requested. + +^wonly(weffects)^ selects within subjects effects that should be included in the + analysis. By default, wfact and all of its interactions with the elements + of the ^between^ option are included. + +^epsilon^ requests that p-values for within subjects F-tests be adjusted for lack + of sphericity using the Greenhouse-Geisser and Huynh-Feldt adjustment fac- + tors. [Requires that yvar be non-missing for each subject.] + +^nomatr^ discards covariance and cell mean matrices at exit. The ^epsilon^ option + creates a (pooled) covariance matrix WSAoV_ and a matrix WSAov_ of marginal + means of yvar across levels of wfact. In addition, when there are between + subjects factors epsilon creates a cell means matrix and a within group co- + variance matrix for each distinct group of subjects; these matrices will be + named WSAov1 WSAoV1, WSAov2 WSAoV2, ... . By default, all these matrices + are left in memory; ^nomatr^ erases each of them before wsanova exits. + + +Examples +-------- + + . ^wsanova lhist time, id(dog)^ + . ^predict resid, res^ + (One-way repeated measures ANOVA; save residuals in resid) + + . ^wsanova rtime trial, id(subj) between(age) epsilon^ + (Split-plot ANOVA, with subjects grouped by levels of age; adjust trial and + age*trial F-tests for lack of sphericity) + + . ^wsanova rtime trial, id(subj) bet(age sex age*sex)^ + (Traditional analysis of a "two between, one within" design: age, sex, and + age*sex as between effects; trial, trial*age, trial*sex, trial*age*sex as + within effects; assume sphericity) + + . ^wsanova rtime trial, id(subj) bet(age sex) wonly(trial) eps nomatr^ + (Main effects only version of the last example; adjust the trial F-test for + lack of sphericity, and discard the matrices used) + + +Author +------ + + John R. Gleason + Syracuse University + Syracuse NY, USA + loesljrg@@ican.net + + +Also see +-------- + + STB: STB-47 sg103 + Manual: [R] anova; [R] predict +On-line: ^help^ for @anova@, @predict@ diff --git a/Modules/ado/plus/x/xcolnames.ado b/Modules/ado/plus/x/xcolnames.ado new file mode 100644 index 0000000..631d3e5 --- /dev/null +++ b/Modules/ado/plus/x/xcolnames.ado @@ -0,0 +1,30 @@ +*! version 1.0, 14th November 2002 (SJ4-1: st0057) + +program define xcolnames, rclass + version 7 + + tokenize "`0'", parse(,) + local com `1' + local head `3' + tokenize "`com'" + tokenize "`head'", parse("()") + local eqhead `3' + mat h = `com' + local names : colnames(h) + local i : word count `names' + local j = 1 + while `j' <= `i' { + gettoken v`j' names : names + local v`j' `eqhead':`v`j'' + local j = `j'+1 + } + local j = 2 + local names2 `v1' + while `j' <= `i' { + local names2 "`names2' `v`j''" + local j = `j' +1 + } + mat colnames `com' = `names2' + mat drop h +end +exit diff --git a/Modules/ado/plus/x/xml_tab.ado b/Modules/ado/plus/x/xml_tab.ado new file mode 100644 index 0000000..e0aa7dc --- /dev/null +++ b/Modules/ado/plus/x/xml_tab.ado @@ -0,0 +1,1950 @@ +*! version 3.50 24Jun2008 M. Lokshin, Z. Sajaia + +# delimit ; + +program define xml_tab; +version 8; + +syntax [anything] [using/] [, STYle(string) EXcelpath(passthru) CAlcpath(passthru) + save(string) updateopts Noisily xml_tab_nopreserve fixed *]; + +if ~missing(`"`using'"', `"`save'"') Error 198 `"either using or save() option can be specified"'; + +if ~missing(`"`using'`save'"') local options `"`options' save("`using'`save'")"'; + +capture confirm matrix `anything'; // do we have a list of matrices? +local rc = _rc; + +updateopts `style', ver(3.26) `updateopts' `excelpath' `calcpath' isest(`rc'); + +local 0 ", `options'"; +syntax , [replace append newappend WIde LOng sd TStat Pvalue Right Below noBRackets sd2 NOADJust ADJust *]; +local options : subinstr local 0 "," ""; + +if ~missing("`replace'`append'`newappend'") {; + opts_excl1 styles `"`styles'"' replace; + opts_excl1 styles `"`styles'"' append; + opts_excl1 styles `"`styles'"' newappend; +}; +if ~missing("`long'`wide'") {; + opts_excl1 styles `"`styles'"' long; + opts_excl1 styles `"`styles'"' wide; +}; +if ~missing("`below'`right'`sd2'") {; + opts_excl1 styles `"`styles'"' below; + opts_excl1 styles `"`styles'"' right; + opts_excl1 styles `"`styles'"' sd2; +}; +if ~missing("`sd'`tstat'`pvalue'") {; + opts_excl1 styles `"`styles'"' sd; + opts_excl1 styles `"`styles'"' tstat; + opts_excl1 styles `"`styles'"' pvalue; +}; +if ~missing("`adjust'`noadjust'") {; + opts_excl1 styles `"`styles'"' adjust; + opts_excl1 styles `"`styles'"' noadjust; +}; + +local 0 ", `styles' `options'"; +foreach opt in Format Lines FONt LOng WIde STARs NOLabel SHOWeq save SHeet STATS + sd TStat Pvalue Right Below NOBRackets sd2 EQuations RBlanks TBlanks CBlanks + Title NOADJust ADJust RNames CEq CNames NOTEs SAVEMat Constant CWidth SAVEPath MV {; + _parse combop 0 : 0, option(`opt') rightmost; +}; +//_parse combop 0 : 0, option(CWidth); + +quietly `noisily' {; + display as text "note: options were expended to"; + display as result `" `0'"'; +}; +display _n; + +tempname M; + if `rc'==0 {; + gettoken first rest : anything; + // syntax for the matrix list + syntax [, Format(passthru) Lines(string asis) FONt(string asis) + LOng WIde STARs(passthru) SHOWeq SAVEPath(name) + save(string) SHeet(string) replace append newappend + drop(passthru) keep(passthru) EQuations(passthru) + RBlanks(string asis) TBlanks(numlist max=1 >0 integer) CBlanks(string) CWidth(string) + Title(string) RNames(passthru) CEq(passthru) CNames(passthru) NOTEs(string asis) mv(passthru) + ]; + + matrix `M' = `first'; + foreach mat of local rest {; + Mat_Capp `M' : `M' `mat', miss(.z) cons ts; + }; + keepdrop `M', `keep' `drop'; + + capture confirm matrix `first'_STARS; + if ~_rc {; + if rowsof(`first')!=rowsof(`first'_STARS) | + colsof(`first')!=colsof(`first'_STARS) {; + Error 503 `"matrices `first' and `first'_STARS must have same dimensions"'; + }; + matrix `M'_STARS = `first'_STARS; + if missing("`long'") {; + Widemat `M'_STARS; + matrix `M'_STARS = r(result); + }; + }; + getstarchars , `stars'; + + if missing("`long'") {; + Widemat `M'; + matrix `M' = r(result); + }; + }; + else {; + syntax [, Format(passthru) Lines(string asis) FONt(string asis) + STYle(string) LOng WIde STARs(passthru) + NOLabel SHOWeq SAVEPath(name) + save(string) SHeet(string) replace append newappend SAVEMat(string) + STATS(passthru) sd TStat Pvalue Right Below noBRackets sd2 NOADJust ADJust + drop(passthru) keep(passthru) EQuations(passthru) + RBlanks(string asis) TBlanks(numlist max=1 >0 integer) + CBlanks(string) CWidth(string) mv(passthru) + Title(string) CEq(passthru) CNames(passthru) NOTEs(string asis) Constant(string) * + ]; + + _get_eformopts , eformopts(`options') allowed(__all__); + local eform `"`s(str)'"'; + + opts_Exclusive "`sd' `tstat' `pvalue'"; + opts_Exclusive "`right' `below'"; + opts_Exclusive "`long' `wide'"; + opts_Exclusive "`adjust' `noadjust'"; + + if missing("`right'") local sd2 "sd2"; // will need to change later + + if ~missing("`tstat'") {; + local cap "t"; + }; + else {; + if ~missing("`pvalue'") {; + local cap "p-value"; + }; + else {; + local cap "se"; // used to be sd + }; + }; + Mkemat `anything', `stats' `stars' `long' `sd2' cap(`cap') `keep' `drop' + `equations' `noadjust' eform(`eform'); + matrix `M' = r(coef); + matrix `M'_STARS = r(n_stars); + }; // else + +if ~missing("`savemat'") {; + local rpl `replace'; // save the -replace- option + + if missing("`long'") matrix roweq `M'=:; + else {; + local req : roweq `M'; + local req : subinstr local req "_easytofind3" "", all; + matrix roweq `M' = `req'; + }; + local rn : rownames `M'; + local rn : subinstr local rn "_easytofind0" "", all; + matrix rownames `M' = `rn'; + + local 0 `savemat'; + syntax name , [replace exit]; + if missing("`replace'") {; + matrix `namelist'= nullmat(`namelist') \ `M'; + matrix `namelist'_STARS = nullmat(`namelist'_STARS) \ `M'_STARS; + }; + else {; + matrix `namelist'= `M'; + matrix `namelist'_STARS = `M'_STARS; + }; + `exit'; + local replace `rpl'; // restore the option +}; + +tempfile tmpstyles; + +opts_Exclusive "`append' `replace' `newappend'"; + +// get sheet options +local 0 `sheet'; +syntax [anything(name=sheet)] [, COlor(integer -1) noGridlines]; + +// check if sheet name is valid +gettoken a b : sheet, parse(":\/?*[]"); + +if ~missing("`b'") | length("`sheet'")>31 Error 198 `"not a valid Excel sheet name"'; + +if missing("`sheet'") local sheet "Sheet1"; + +_getfilename "`save'"; +if `"`r(filename)'"'==`"`save'"' {; + local save "`c(pwd)'/`save'"; +}; +else {; + if index(`"`r(filename)'"', ".")==0 {; + local save `"`save'.xml"'; + }; +}; +local filename = cond(strpos("`save'", "\") + strpos("`save'", "/") > 0, "`save'", "`c(pwd)'/`save'"); + +if ~missing("`newappend'`append'") {; + capture confirm file "`save'"; + if _rc {; + local replace "replace"; + }; + else {; + local append "append"; + }; +}; +if missing("`append'`replace'") {; + capture confirm file "`save'"; + if ~_rc {; + Error 602 `"file `save' already exists"'; + }; + else {; + local replace "replace"; + }; +}; + +if missing("`xml_tab_nopreserve'") preserve; +drop _all; +quietly {; + savetodataset `M' `M'_STARS, `format' `sd2' `rnames' `cnames' `ceq' etitle(`"`etitle'"') `mv' `fixed'; + + capture confirm matrix `M'_STARS; + if ~_rc {; + local starnote "note: "; + forvalues s = 1/`: list sizeof stars' {; + local starnote "`starnote', `: word `s' of `starchars'' p<`: word `s' of `stars''"; + }; + local starnote : subinstr local starnote "," ""; + local notes `""`starnote'", `notes'"'; + }; + sort id; + if ~missing(`"`rblanks'"') {; + generate nreq = 0 in 1; + replace nreq = nreq[_n-1] + (mod(id,10)==6) if _n>1; + local add = 0; + + while (~missing(`"`rblanks'"')) {; + _parse comma 1 rblanks : rblanks; + gettoken num 1 : 1, qed(qt); + gettoken txt 1 : 1; + local 1 = substr(trim("`1'"), 1, 5); + local num = trim("`num'"); + if "`num'"=="LAST_ROW" local num = _N - nreq[_N] - 3; + capture confirm integer number `num'; + local isname = _rc; + + if ~(`isname' | `qt') {; + local s "`s' `num'"; + numlist "`s'", sort; + local s `r(numlist)'; + local add : list posof "`num'" in s; + if `add'>0 local add=`add'-1; + + local cond "_n==`=`num'+`add'+3'+nreq"; + }; + else {; + local cond = cond(missing("`sd2'"), `"d_0=="`num'""', `"d_0=="`num'_easytofind1""'); + }; + summarize id if `cond', meanonly; + local rm = r(min); + if ~missing(`rm') {; + replace id = id+0.01 if abs(id-`rm')<0.001; + local N = _N+1; + set obs `N'; + replace id = `rm' + 5 in `N'; + local txt `txt'; + replace d_0 = trim(`"`txt'"') in `N'; + replace d_1 = "_SKIP_ROW" in `N'; + foreach var of varlist f_* {; + replace `var' = cond(missing("`1'"),`var'[int(r(min)/10)+3], "0_`1'") in `N'; + }; + if `isname' local s "`s' `=`rm'/10'"; + }; + local rblanks : subinstr local rblanks "," ""; + sort id; + }; + }; // rblanks + local ncindex =1; // column for the notes + + if ~missing("`cblanks'") {; + unab vlist : d_*; + local cbrc : word count `vlist'; + local --cbrc; // d_0 was included + + foreach cb of local cblanks {; + capture confirm integer number `cb'; + if _rc {; + if substr("equations", 1, length("`cb'")) == lower("`cb'") {; + tempvar n; + generate `n' = _n; + summarize `n' if id==-10, meanonly; + local mn = r(min); + forvalues i= 2/`cbrc' {; + if ~missing(d_`=`i'-1'[`mn']) & d_`=`i'-1'[`mn']!=".x_" /*& d_`i'[`mn']==".x_"*/ {; + tempname nn; + generate d_eq_`nn' = ""; + generate f_eq_`nn' = ""; //f_`1'; + capture move d_eq_`nn' d_`i'; + local hasbceq 1; + }; + }; + }; + else Error 198 `"invalid cblanks()"'; + }; + else {; + if `cb'<0 {; + local cb = -1; + local ++ncindex; + }; + capture confirm variable d_`cb'; + if ~_rc | `cb'==-1 {; + tempname nn; + generate d_`nn' = ""; + generate f_`nn' = ""; //f_`1'; + local next = `cb' + 1; + capture move d_`nn' d_`next'; + }; //if + }; + }; // cb + }; // cblanks + + if ~missing("`lines'") {; + local lines : subinstr local lines "," "", all; + while ~missing(`"`lines'"') {; + gettoken txt lines : lines; + gettoken 1 lines : lines; + confirm integer number `1'; + local txt = trim("`txt'"); + if "`txt'"=="LAST_ROW" local txt = _N-3; + capture confirm integer number `txt'; + + if ~_rc {; + if `txt'==-3 {; + local title_line ""; + break, continue; + }; + local cond "_n==`=`txt'+3'"; + }; + else {; + local cond = cond(missing("`sd2'"), `"d_0=="`txt'""', `"d_0=="`txt'_easytofind1""'); + }; + + foreach var of varlist f_* {; + replace `var'=substr(`var',1,7)+cond(`cond' ,trim("`1'"), "") if substr(`var',8,2)=="" & `var'!=""; + }; // foreach + }; // while + }; // lines + + if ~missing("`sd2'") {; + summarize id if strpos(d_0, "easytofind3"), meanonly; + local stm = r(mean); + drop if strmatch(d_0, "*_easytofind0") & id > `stm'; + replace d_0 = substr(d_0, 1, length(d_0)-1) + "0" if id > `stm'; + if missing("`brackets'") {; + foreach var of varlist f_* {; + replace `var' = "9_"+substr(`var',3,7) if strmatch(d_0, "*_easytofind1"); + }; // end foreach + }; // if + }; // if + + replace l_0 = "" if strmatch(d_0, "*_easytofind1"); + replace d_0 = "" if strmatch(d_0, "*_easytofind1"); + replace l_0 = "" if id<1; + replace d_0 = "" if id<1; + + replace d_0 = subinstr(d_0, "_easytofind0" ,"", .); + + drop if strmatch(d_0, "easytofind*"); + + if missing("`nolabel'") {; + replace d_0 = l_0 if (l_0 != ""); + }; + if ~missing(`"`constant'"') {; + replace d_0 = `"`constant'"' if d_0=="_cons"; + }; + if missing(`"`etitle'"') {; //~`rc' {; // it's a matrix list + drop if round(id)==-20; + }; + if missing("`showeq0'`showeq'") {; + drop if round(id)==-10; + }; + }; //quietly + +unab vlist : d_*; +local rc : word count `vlist'; +local --rc; // d_0 was included + +tempfile tmpfile; +tempname ofile outfile; + +local lsheet "`sheet'"; + +if ~missing("`replace'") {; + local fno "01"; + _styles " " `"`fno' `font'"' `"`starchars'"'; + // encoding='UTF-8' standalone='yes' + local xmlheader "<?xml version='1.0' encoding='ISO-8859-1'?> + <?mso-application progid='Excel.Sheet'?> + <Workbook xmlns='urn:schemas-microsoft-com:office:spreadsheet' + xmlns:o='urn:schemas-microsoft-com:office:office' + xmlns:x='urn:schemas-microsoft-com:office:excel' + xmlns:ss='urn:schemas-microsoft-com:office:spreadsheet' + xmlns:html='http://www.w3.org/TR/REC-html40'>"; + file open `outfile' using "`tmpfile'", write; + file write `outfile' `"`xmlheader'"' _n; + gettoken font size : font; + local font "`font' `size'"; + local font : list retokenize font; + file write `outfile' `"<FontList>`fno' `font'</FontList>"' _n; + file write `outfile' `"`styles'"' _n; + file write `outfile' "<DocumentProperties xmlns='urn:schemas-microsoft-com:office:office'>"; + file write `outfile' "<Description>created using xml_tab</Description></DocumentProperties>"; + file write `outfile' `"<Sheetnames>?`lsheet'?</Sheetnames>"' _n; +}; //if +else {; // append + file open `ofile' using "`save'", read; + file open `outfile' using "`tmpfile'", write; + file read `ofile' line; // header + file write `outfile' `"`line'"' _n; + file read `ofile' line; // font list + findfont `"`line'"' `"`fno' `font'"'; + file write `outfile' `"`line'"' _n; + file read `ofile' line; // styles + _styles `"`line'"' `"`fno' `font'"' `"`starchars'"'; + file write `outfile' `"`styles'"' _n; + file read `ofile' line; // Description, sheetnames + if strpos(`"`line'"',"xml_tab")==0 {; + display as error "can not append, existing file was created or changed by some other program"; + exit 603; + }; + local sheetID=0; + local sheet "`lsheet'"; + local dfdfdf : subinstr local line "?`lsheet'?" "", all count(local c); + while `c'>0 {; + local ++sheetID; + local lsheet "`sheet' (`sheetID')"; + local dfdfdf : subinstr local line "?`lsheet'?" "", all count(local c); + }; //while + local line : subinstr local line "</Sheetnames>" "`lsheet'?</Sheetnames>"; + file write `outfile' `"`line'"' _n; + + while r(eof)==0 {; + file read `ofile' line; + if `"`line'"'!="</Workbook>" file write `outfile' `"`line'"' _n; + }; //for +}; //else + +file write `outfile' `"<Worksheet ss:Name='`lsheet''>"'; +if `color'>=0 | ~missing("`gridlines'") {; + file write `outfile' "<WorksheetOptions xmlns='urn:schemas-microsoft-com:office:excel'>"; + if `color'>=0 file write `outfile' "<TabColorIndex>`color'</TabColorIndex>"; + if ~missing("`gridlines'") file write `outfile' "<DoNotDisplayGridlines/>"; + file write `outfile' "</WorksheetOptions>"; +}; +file write `outfile' "<Table x:FullColumns='1' x:FullRows='1'>"; + +local customwidths = 0; +local customrc = `rc'; + +if ~missing("`cwidth'") {; + while ~missing("`cwidth'") {; + _parse comma curr cwidth : cwidth; + local cwidth : subinstr local cwidth "," ""; + gettoken ind wdt : curr; + capture confirm integer number `ind'; + if _rc {; + if substr("equations", 1, length("`ind'")) == lower("`ind'") & ~missing("`hasbceq'", "`wdt'"){; + local i 1; + foreach var of varlist d_* {; + if strpos("`var'", "d_eq_") {; + local cids "`cids' `i'"; + local cwdts "`cwdts' `wdt'"; + //file write `outfile' "<Column ss:Index='`i'' ss:AutoFitWidth='0' ss:Width='`=trim("`wdt'")''/>"; + }; + local ++i; + }; + }; + }; + else {; + if `: list ind in inds' | `ind'>256 | `ind'<0 continue; + + if missing("`wdt'") local wdt = 0; + capture numlist `wdt', range(>=0 <=1000); + if _rc continue; + local cids "`cids' `=`ind'+1'"; + local cwdts "`cwdts' `wdt'"; + // file write `outfile' "<Column ss:Index='`=`ind'+1'' ss:AutoFitWidth='0' ss:Width='`=trim("`wdt'")''/>"; + local inds "`inds' `ind'"; + local customwidths = `customwidths' + `wdt'; + local --customrc; + }; + }; + _qsort_index `cids' \ `cwdts'; + local cwdts `r(slist2)'; + loca i 1; + foreach cid in `r(slist1)' {; + loca wdt : word `i++' of `cwdts'; + file write `outfile' "<Column ss:Index='`cid'' ss:AutoFitWidth='0' ss:Width='`=trim("`wdt'")''/>"; + }; +}; + + if ~missing("`tblanks'") local addindex =1+`tblanks'; + else local addindex =1; + + if ~missing("`title'") {; + local hh= (int(length("`title'") /((`customrc'+1)*8.43+`customwidths'/7.5))+1)*(12.75 + max((`size'-10)*1.5,0)); + local title : subinstr local title "<" "<", all; + local title : subinstr local title ">" ">", all; + local ltitle "<Row ss:Index='`addindex++'' ss:Height="`hh'"><Cell ss:StyleID='s`fno'_Title' ss:MergeAcross='`rc''> + <Data ss:Type='String'>`title'</Data></Cell></Row>"; + file write `outfile' `"`ltitle'"'; + }; + +forvalues i = 1/`=_N' {; + local mrg = 0; + foreach var of local vlist {; + local datum = `var'[`i']; + if (`"`datum'"'=="_SKIP_ROW") continue; // rblanks + + local datum : subinstr local datum "<" "<", all; + local datum : subinstr local datum ">" ">", all; + if (`"`datum'"'==".x_") {; + local ++ mrg; + continue; + }; + local fvar = "f" + substr("`var'",2,.); + local f = `fvar'[`i']; + if ~missing("`f'") local f "`fno'_`f'"; + local dtype = cond(upper(substr("`f'", 6, 1))=="N" & ~missing(real(`"`datum'"')), "Number", "String"); + if (`mrg'>0) {; + local mrgstr "ss:MergeAcross='`mrg''"; + }; + else {; + local mrgstr; + }; + local xmlrow "`xmlrow' <Cell ss:StyleID='s`f'' `mrgstr'><Data ss:Type='`dtype''>`datum'</Data></Cell>"; + local mrg = 0; + }; // var + local xmlrow "<Row ss:Index='`addindex++''>`xmlrow'</Row>"; + file write `outfile' `"`xmlrow'"' _n; + local xmlrow ""; +}; // i + +if ~missing(`"`notes'"') {; + local notes : subinstr local notes "<" "<", all; + local notes : subinstr local notes ">" ">", all; + local --addindex; + while (~missing(`"`notes'"')) {; + _parse comma 1 notes : notes; + if ~missing(`"`1'"') {; + gettoken num txt : 1; + capture confirm integer number `num'; + if _rc {; + local txt "`num'`txt'"; + local num=0; + }; + local ++num; + local addindex = `addindex'+`num'; + + file write `outfile' `"<Row ss:Index='`addindex''><Cell ss:StyleID='s`fno'_Note' ss:Index='`ncindex''><Data ss:Type='String'>`txt'</Data></Cell></Row>"'; + }; + local notes : subinstr local notes "," ""; + }; +}; + +file write `outfile' "</Table></Worksheet>" _n; +file write `outfile' "</Workbook>"; +file close _all; + +capture copy "`tmpfile'" "`save'", replace; +if _rc {; + display as error "file can not be saved at this location"; + exit 603; +}; +display as text "note: results saved to `filename'"; + + if "`c(os)'"=="Windows" & missing("`c(mode)'"){; + if ~missing(`"`excelpath'"') {; + display `"{ stata `"winexec "`excelpath'" "`filename'" "': click here}"' _c; + display as text " to open with Excel"; + if ~missing("`savepath'") global `savepath' "`excelpath'"; + }; + if ~missing(`"`calcpath'"') {; + display `"{ stata `"winexec "`calcpath'" "`filename'" "': click here}"' _c; + display as text " to open with Calc"; + }; + }; +if missing("`xml_tab_nopreserve'") restore; +end; +/*******************************************************************************/ +/*******************************************************************************/ + +program define Keep, rclass; //adopted from est_table.ado + args b spec; + + tempname RES bt tmp; + foreach sp of local spec {; + matrix `bt' = `b'; + local row = rownumb(`bt', "`sp'"); + if `row' == . {; + display as error "coefficient `sp' does not occur in any of the models"; + exit 198; + }; + while `row' != . {; + if index("`sp'",":") > 0 {; // complete equation spec. + matrix `tmp' = `bt'["`sp'",1...]; + }; + else {; + matrix `tmp' = `bt'[`row',1...]; + }; + matrix `RES' = nullmat(`RES') \ `tmp'; + if `row'+rowsof(`tmp')>`=rowsof(`bt')' continue, break; + matrix `bt' = `bt'[`=`row'+rowsof(`tmp')'...,1...]; + local row = rownumb(`bt', "`sp'"); + }; + }; + capture confirm matrix `RES'; + if _rc {; + display as error "all variables dropped, nothing to output"; + exit 999; + }; + return matrix result `RES'; +end; // Keep + +program define Drop, rclass; //borrowed from est_table.ado + args b spec; + tempname bt; + matrix `bt' = `b'; + + foreach sp of local spec {; + local isp = rownumb(`bt', "`sp'"); + if `isp' == . {; + display as error "coefficient `sp' does not occur in any of the models"; + exit 198; + }; + while `isp' != . {; + local nb = rowsof(`bt'); + if `isp' == 1 {; + if (`nb' == 1) {; + display as error "all variables dropped, nothing to output"; + exit 999; + }; + matrix `bt' = `bt'[2...,1...]; + }; + else if `isp' == `nb' {; + matrix `bt' = `bt'[1..`=`nb'-1',1...]; + }; + else {; + local im1 = `isp'-1; + local ip1 = `isp'+1; + matrix `bt' = `bt'[1..`im1',1...] \ `bt'[`ip1'...,1...]; + }; + local isp = rownumb(`bt', "`sp'"); + }; + }; + return matrix result `bt'; +end; // Drop + + +program define keepdrop; + syntax anything(name=bbc) [, keep(string) drop(string)]; + + if ~missing("`keep'") {; + if (index("`keep'", "*") + index("`keep'", "?") > 0) expandspec keep `bbc' `"`keep'"'; + + Keep `bbc' `"`keep'"'; + matrix `bbc' = r(result); + local reqs : roweq `bbc'; + local reqs : list uniq reqs; + tempname tmp; + + foreach req of local reqs {; + Keep `bbc' `"`req':"'; + matrix `tmp' = nullmat(`tmp') \ r(result); + }; + matrix `bbc' =`tmp'; + }; + + if ~missing("`drop'") {; + if (index("`drop'", "*") + index("`drop'", "?") > 0) expandspec drop `bbc' `"`drop'"'; + + Drop `bbc' `"`drop'"'; + matrix `bbc' = r(result); + }; +end; // program keepdrop + +program define GetStats; //borrowed from est_table.ado + args stats bs; + local r2_a "r2_a"; + local r2_p "r2_p"; + tempname rank st V; + local escalars : e(scalars); + local is 1; + foreach stat of local stats {; + local sr "`stat'"; + if inlist("`stat'", "aic", "bic", "rank") {; + if missing("`hasrank'") {; + capture matrix `V' = syminv(e(V)); + local rc = _rc; + if `rc' == 0 {; + scalar `rank' = colsof(`V') - diag0cnt(`V'); + }; + else {; + if `rc' == 111 {; + scalar `rank' = 0; + }; + else {; + matrix `V' = syminv(e(V)); + }; + }; + local hasrank 1; + }; + if "`stat'" == "aic" {; + scalar `st' = -2*e(ll) + 2*`rank'; + }; + else {; + if "`stat'" == "bic" {; + scalar `st' = -2*e(ll) + log(e(N)) * `rank'; + }; + else {; + if "`stat'" == "rank" {; + scalar `st' = `rank'; + }; + }; + }; + }; + else {; + if "`stat'" == "r2_a" {; + if `:list posof "r2_a" in escalars' > 0 {; + scalar `st' = e(r2_a); + global R2_ : list global(R2_) | r2_a; + }; + else {; + if `:list posof "r2_p" in escalars' > 0 {; + scalar `st' = e(r2_p); + global R2_ : list global(R2_) | r2_p; + }; + else {; + scalar `st' = .91e308; // .z + }; + }; + }; + else {; + if `:list posof "`stat'" in escalars' > 0 {; + scalar `st' = e(`stat'); + }; + else {; + scalar `st' = .91e308; + }; + }; + }; + matrix `bs'[`is++',1] = `st'; + matrix rownames `bs' =`stats'; + }; +end; // GetStats + +program define Mkemat, rclass; + syntax [anything] [, STATS(string) STARs(passthru) LOng sd2 cap(string) keep(passthru) drop(passthru) + EQuations(string) NOADJust eform(string)]; + + if missing("`anything'") {; + local anything "."; + }; + gettoken name rest : anything, bind; + local nnames = 0; + while ~missing("`name'") {; + if strpos("`name'", "(") {; + local ++nnames; // just one estimator with nonstandard matrices + }; + else {; + quietly estimates dir `name'; + local name "`r(names)'"; + local nnames = `nnames'+`: word count `name''; + }; + local names "`names' `name'"; + gettoken name rest : rest, bind; + }; + + tempname bbc bc bbs bs; + + if ~missing("`stats'") {; + local stats : subinstr local stats "," "", all; + confirm names `stats'; + + if (`:list posof "r2_p" in stats' > 0 | + `:list posof "r2_a" in stats' > 0) {; + local r2_a "r2_a"; + local r2_p "r2_p"; + local stats : list stats | r2_a; + local stats : list stats - r2_p; + }; + local stats : list uniq stats; + local nstat : list sizeof stats; + matrix `bs' = J(`nstat', 1, .z); + global R2_ ; + }; + + tempname hcurrent esample; + _estimates hold `hcurrent', restore nullok estsystem; + + local ni 0; + if missing("`sd2'") {; + local x ".x_"; + }; + + gettoken first rest : names, bind; + while ~missing("`first'") {; + local ++ni; + gettoken name opts : first, parse("(") bind; + nobreak {; + if ("`name'" != ".") {; + quietly estimates dir `name'; + est_unhold `name' `esample'; + }; + else {; + _est unhold `hcurrent'; + }; + if missing("`opts'") {; // extract options + local eb "b"; + local eV "V"; + local noadj; + local leform; + }; + else {; + gettoken 0 : opts, match(par); + syntax [anything] [, *]; + _get_eformopts , eformopts(`options') allowed(__all__) soptions; + + local leform `"`s(str)'"'; + local udiparm `"`s(options)'"'; // not used yet + gettoken eb eV : anything; + if missing("`eb'") {; + local eb "b"; + local eV "V"; + local noadj; + }; + else local noadj `noadjust'; + }; + capture confirm matrix e(`eb') e(`eV'); + if _rc {; + display as error "`name' estimation result does not have e(`eb') and/or e(`=trim("`eV'")')"; + if ("`name'" != ".") est_hold `name' `esample'; + else _est hold `hcurrent', restore nullok estsystem; + exit 111; + }; + + tempname B V VV SC tB tV tSTat PVal; + matrix `B' = e(`eb'); + matrix `V' = e(`eV'); + + local coleqs : coleq `B'; + if `"`: list uniq coleqs'"' == "_" & ~missing("`e(depvar)'") matrix coleq `B' = `e(depvar)'; + + if ~missing("`noadj'") {; + capture confirm matrix e(b) e(V); + if _rc {; + display as error "`name' estimation result does not have e(b) and/or e(V)"; + display as error "cannot report unadjasted t-statistics"; + if ("`name'" != ".") est_hold `name' `esample'; + else _est hold `hcurrent', restore nullok estsystem; + exit 111; + }; + matrix `tB'=e(b); + matrix `tV'=e(V); + }; + if ~missing("`stats'") {; + GetStats "`stats'" `bs'; + matrix `bbs' = J(rowsof(`bs'), 1,.9042e308),`bs', `bs', J(rowsof(`bs'), 1, .9042e308); // .x + matrix rownames `bbs' = `: rownames `bs''; + matrix roweq `bbs' = easytofind3; + + if (missing("`long'") & `: word count $R2_'>1) {; + global R2_ "r2_a/r2_p"; + }; + }; + local eqname = cond("`name'" != ".", "`name'", `"`e(title)'"'); + local ttle`ni' "`e(_estimates_title)'"; + if missing("`ttle`ni''") local ttle`ni' "`e(estimates_title)'"; // Stata 10.0 + if missing("`ttle`ni''") local ttle`ni' "`eqname'"; + if "`name'" != "." est_hold `name' `esample'; + else _est hold `hcurrent', restore nullok estsystem; + }; // nobreak + + formateqnames `B' `V' "`name'|`ni'"; + if ~missing("`noadj'") formateqnames `tB' `tV' "`name'|`ni'"; + + if issymmetric(`V') {; + forvalues v = 1/`=colsof(`B')' {; + if (`V'[`v',`v'] > 0) {; + matrix `VV' = nullmat(`VV'), sqrt(`V'[`v',`v']); + }; + else {; + if (`B'[1,`v'] == 0) {; + matrix `B'[1,`v'] = .8998e308; // = .d; + }; + matrix `VV' = nullmat(`VV'), .91e308; // .z; + }; + }; + }; + else matrix `VV' =`V'; + + if ~missing(`"`eform'"') local leform `"`eform'"'; + if ~missing(`"`leform'"') {; + local coef : subinstr local leform "." "", all; + capture Drop `bc' "_cons"; + if ~_rc matrix `bc' = r(result); + }; + else local coef "coef"; + + forvalues i = 1/`=colsof(`B')' {; + if ~missing("`noadj'") {; + local t = `tB'[1, `i']/sqrt(`tV'[`i', `i']); + }; + else {; + local t = `B'[1, `i']/`VV'[1, `i']; + }; + local p = 2*cond(e(df_r)==.,1-norm(abs(`t')), ttail(e(df_r),abs(`t'))); + matrix `tSTat' = nullmat(`tSTat'), `t'; + matrix `PVal' = nullmat(`PVal'), (`p' \ .91e308); + + if ~missing(`"`leform'"') {; + matrix `B'[1, `i'] = exp(`B'[1, `i']); + matrix `VV'[1, `i'] = `B'[1, `i']*`VV'[1, `i']; + }; + }; + + if "`cap'" == "se" matrix `bc' = (`B' \ `VV' \ `PVal')'; + else if "`cap'" == "t" matrix `bc' = (`B' \ `tSTat' \ `PVal')'; + else matrix `bc' = (`B' \ `PVal'[1,....] \ `PVal')'; + + matrix coleq `bc' = `name'|`ni'; + matrix colnames `bc' = "`coef'" `cap' pval mis; + + if ~missing("`equations'") & ~missing("`long'") {; + AdjustRowEq `bc' `ni' `nnames' "`equations'"; + }; + matrix `bc' = `bc' \ nullmat(`bbs'); + if (`ni' > 1) {; + Mat_Capp `bbc' : `bbc' `bc', miss(.91e308) cons ts; + }; + else {; + matrix `bbc' = `bc'; + }; + local etitle "`etitle' `x' "`ttle`ni''""; + gettoken first rest : rest, match(par) bind; + }; // while + + // move scalars to the end + tempname tmpsc tmpst; + capture matrix `tmpsc' = `bbc'["easytofind2:",....]; // model scalars + if ~_rc {; + Drop `bbc' "easytofind2:"; + matrix `bbc' = r(result); + }; + capture matrix `tmpst' = `bbc'["easytofind3:",....]; + if ~_rc {; + Drop `bbc' "easytofind3:"; + matrix `bbc' = r(result); + }; + + keepdrop `bbc', `keep' `drop'; + + matrix `bbc' = `bbc' \ nullmat(`tmpsc'); + matrix `bbc' = `bbc' \ nullmat(`tmpst'); + + if missing("`long'") {; + local etitle; + local ceq : coleq `bbc', quoted; + local cequ : list uniq ceq; + local req : roweq `bbc', quoted; + local requ : list uniq req; + local rsc "easytofind2"; // model scalars + local rst "easytofind3"; // statistics + local requ : list requ - rsc; + local requ : list requ - rst; + tempname wbc wbbc wbbbc J tsc tst tmp ttst ttsc; + local nii = 0; + foreach col of local cequ {; + capture matrix drop `wbbc'; + matrix `tmp' = `bbc'[....,`"`col':"']; + local ni = 0; + foreach row of local requ {; + matrix `wbc' = `tmp'[`"`row':"',....]; + matrix roweq `wbc' =:; + matrix `J' =J(`=rowsof(`wbc')', `=colsof(`wbc')', .91e308); + if mreldif(`wbc', `J')>0 {; + matrix coleq `wbc'="`row'"; + if `++ni' > 1 {; + Mat_Capp `wbbc' : `wbbc' `wbc', miss(.91e308) cons ts; + local etitle "`etitle' `x' .x_"; + }; + else {; + matrix `wbbc' = `wbc'; + }; + }; + }; + capture matrix `tsc' = `tmp'["`rsc':",....]; + if ~_rc & `ni'>1 {; + matrix `tsc' = `tsc', J(rowsof(`tsc'), (`ni'-1)*4, .91e308); + }; + capture matrix `tst' = `tmp'["`rst':",....]; + if ~_rc & `ni'>1 {; + local rownames : rowfullnames `tst'; + matrix `tst' = J(rowsof(`tst'), (`ni'-1)*4, .9042e308), `tst'; + matrix rowname `tst' =`rownames'; + }; + if `ni'>1 {; + local showeq=1; + }; + if `ni' {; + if `++nii' > 1 {; + capture Mat_Capp `wbbbc' : `wbbbc' `wbbc', miss(.91e308) cons ts; + capture matrix `ttsc' = `ttsc', `tsc'; + capture matrix `ttst' = `ttst', `tst'; + }; + else {; + matrix `wbbbc' = `wbbc'; + capture matrix `ttsc' = `tsc'; + capture matrix `ttst' = `tst'; + }; + local etitle "`etitle' `x' "`ttle`nii''""; + }; + }; + matrix `bbc' =`wbbbc' \ nullmat(`ttsc'); + matrix `bbc' =`bbc' \ nullmat(`ttst'); + }; + + if ~missing("`sd2'") {; + tempname tmpA; + forvalues i = 1/`= rowsof(`bbc')' {; + tempname tmpB tmpC; + local colnames; + forvalues j = 1/`= colsof(`bbc') / 2' {; + local c1 = `j' * 2 - 1; + local c2 = `j' * 2; + matrix `tmpC' = `bbc'[`i',`c1'..`c2']'; + local cnames : colnames `tmpC'; + local ceq : coleq `tmpC', quoted; + local colnames `"`colnames' "`: word 1 of `: roweq `tmpC', quoted''""'; + matrix `tmpB' = nullmat(`tmpB'), `tmpC'; + }; // j + matrix rownames `tmpB' = `cnames'_easytofind0 `cnames'_easytofind1; + matrix roweq `tmpB' = "`: word 1 of `ceq''"; + matrix `tmpA' = nullmat(`tmpA') \ `tmpB'; + }; // i + matrix coleq `tmpA' =`colnames'; + matrix colnames `tmpA' =coef/`cap'; + matrix `bbc' = `tmpA'; + }; + + if `: word count $R2_'>1 {; + global R2_ "r2_a/r2_p"; + }; + + local rnames : rownames `bbc'; + local rnames : subinstr local rnames "r2_a" "$R2_"; + matrix rownames `bbc' = `rnames'; + + // get variable labels if available + local rnames; + tempname tmp; + forvalues i = 1/`= rowsof(`bbc')' {; + matrix `tmp' =`bbc'[`i',....]; + local rn : rownames `tmp'; + local rn : subinstr local rn "_easytofind0" ""; + local rn : subinstr local rn "_easytofind1" ""; + capture local lbl : variable label `rn'; + if ("`lbl'"!="" & _rc==0) {; + local rn "`lbl'"; + }; + local rnames "`rnames' "`rn'""; + }; + + tempname n_stars D; + + getstarchars , `stars'; + + local rr = rowsof(`bbc'); + local rc = colsof(`bbc') / 2; // extra cols of tstats; + + matrix `n_stars' = J(`rr', `rc', 0); + matrix `D' = J(`rr', `rc', .); + + if missing("`sd2'") {; + local base = 2; + local sdc = 1; + local sdr = 0; + }; + else {; + local base = 1; + local sdc = 0; + local sdr = 1; + }; + + local cnames_old : colnames `bbc'; + local ceqs_old : coleq `bbc', quoted; + local cnames; + forvalues j = 1/`rc' {; + local jC = int((`j'-0.1)/(1+`sdc'))*(1+`sdc')+`j'; + local cnames `"`cnames' `: word `jC' of `cnames_old''"'; + local ceqs `"`ceqs' "`: word `jC' of `ceqs_old''""'; + forvalues i = 1/`rr'{; + matrix `D'[`i',`j']=`bbc'[`i',`jC']; + if mod(`j',`sdc'+1)==`sdc' & mod(`i', `sdr'+1)==`sdr' {; + local p = min(`bbc'[`i',`jC'+`base'], .); + + forvalues s =1/`: list sizeof stars' {; + if `p'<=`: word `s' of `stars'' {; + matrix `n_stars'[`i', `j'] = `s'; + continue, break; + }; + }; + }; + }; + }; + + matrix rownames `D' = `: rownames `bbc''; + matrix roweq `D' = `: roweq `bbc', quoted'; + matrix colnames `D' = `cnames'; + matrix coleq `D' = `ceqs'; + + return matrix coef = `D'; + return matrix n_stars = `n_stars'; + + c_local rnames `"rnames(`rnames')"'; + c_local etitle `"`etitle'"'; + c_local showeq0 `showeq'; + c_local stars `"`stars'"'; + c_local starchars `"`starchars'"'; +end; // Mkemat + +program define formateqnames; + args B V; + + local eq : coleq `B', quoted; + local eq : subinstr local eq "." "`=char(183)'", all; // mlogit problem + matrix coleq `B' =`eq'; + + local eq : subinstr local eq "_" "", all word; + if missing(trim(`"`eq'"')) {; + matrix coleq `B' = `: word 1 of `e(depvar)''; + }; + else {; + local ueq : list uniq eq; + local s : list eq - ueq; + local s : list ueq - s; // constant equations + + if missing(`"`s'"') exit; + + local cnames : colnames `B'; + forvalues i = 1 / `=colsof(`B')' {; + if strpos(`"`s'"', `"`: word `i' of `eq''"') & `i' > 1 {; + local newceqs `"`newceqs' "easytofind2""'; + local newcnames `"`newcnames' "`: word `i' of `eq''""'; + }; + else {; + local newceqs `"`newceqs' "`: word `i' of `eq''""'; + local newcnames `"`newcnames' "`: word `i' of `cnames''""'; + }; + }; + matrix colnames `B' = `newcnames'; + matrix colnames `V' = `newcnames'; + matrix coleq `B' = `newceqs'; + matrix coleq `V' = `newceqs'; + +/* + local cnames : colfullnames `B'; + local ueq : list uniq eq; + foreach eqname of local ueq {; + local eq : subinstr local eq "`eqname'" "`eqname'", all count(local c); + if (`c' == 1) {; + local cnames : subinstr local cnames "`eqname':_cons" "easytofind2:`eqname'", all; + }; + }; + matrix colnames `B' = `cnames'; + matrix colnames `V' = `cnames'; + */ + }; +end; // program formateqnames + +program define AdjustRowEq; // borrowed from est_table.ado + args b ni nmodel eqspec; + + local eqspec : subinstr local eqspec ":" " ", all; + local eqspec : subinstr local eqspec "#" "" , all; + + local beqn : roweq `b'; + local beq : list uniq beqn; + + local iterm 0; + gettoken term eqspec : eqspec , parse(","); + while ~missing("`term'") {; + local ++iterm; + + gettoken eqname oprest: term, parse("="); + gettoken op rest : oprest, parse("="); + if trim(`"`op'"') == "=" {; + confirm name `eqname'; + if ~missing(`"`:list beq & eqname'"') {; + display as error "option equations() invalid"; + display as error "specified equation name already occurs in model `ni'"; + exit 198; + }; + local term `rest'; + }; + else {; + local eqname #`iterm'; + }; + + local nword : list sizeof term; + if ~inlist(`nword', 1, `nmodel') {; + display as error "option equations() invalid"; + display as error "a term should consist of either 1 or `nmodel' equation numbers"; + exit 198; + }; + if `nword' > 1 {; + local term : word `ni' of `term'; + }; + + if trim("`term'") != "." {; + capture confirm integer number `term'; + if _rc {; + display as error "option equations() invalid"; + display as error "`term' was found, while an integer equation number was expected"; + exit 198; + }; + if ~inrange(`term',1,`:list sizeof beq') {; + display as error "option equations() invalid"; + display as error "equation number `term' for model `ni' out of range"; + exit 198; + }; + if `:list posof "`eqname'" in beq' != 0 {; + display as error "impossible to name equation `eqname'"; + display as error "you should provide (another) equation name"; + exit 198; + }; + local beqn : subinstr local beqn "`:word `term' of `beq''" "`eqname'" , word all; + }; + + if missing("`eqspec'") {; + continue, break; + }; + gettoken term eqspec: eqspec , parse(","); + assert "`term'" == ","; + gettoken term eqspec: eqspec , parse(","); + }; + matrix roweq `b' = `beqn'; +end; + +program define savetodataset; + syntax anything [, format(string asis) sd2 RNames(string asis) + CEq(string asis) CNames(string asis) etitle(string) fixed mv(passthru)]; + + local cfrmt = cond(missing("`fixed'"), "%24.0g", "%24.8f"); + + tokenize `anything'; + local D `1'; + local rr = rowsof(`D'); + local rc = colsof(`D'); + capture confirm matrix `2'; + if _rc {; + tempname D_STARS; + matrix `D_STARS' = J(`rr', `rc', 0); + }; + else local D_STARS `2'; + + local obs = `rr'+3; + + set obs `obs'; + tempname tmp; + + readformats `rc' `"`format'"'; + + generate int id = (_n - 3)*10; + generate str d_0 = ""; + generate str l_0 = ""; + if ~missing("`sd2'") local eas "_easytofind1"; + replace d_0 = "EST_NAMES`eas'" in 1; + replace d_0 = "SCOL_NAMES`eas'" in 2; + replace d_0 = "COL_NAMES`eas'" in 3; + local rownames : rownames `D'; + local roweqs : roweq `D'; + forvalues i = 1/`rr' {; + matrix `tmp' = `D'[`i',....]; + local roweq1 : roweq `tmp'; + local aa : word `i' of `rnames'; + if "`roweq1'" == "easytofind2" {; + replace d_0 = "/`: rownames `tmp''" in `=`i'+3'; + replace l_0 = `"/`aa'"' in `=`i'+3'; + }; + else {; + replace d_0 = "`: rownames `tmp''" in `=`i'+3'; + replace l_0 = `"`aa'"' in `=`i'+3'; + }; + if "`roweq1'"!="`roweq'" & "`roweq1'"!="_" {; + set obs `++obs'; + local roweq `roweq1'; + replace d_0 = "`roweq'" in `obs'; + replace id = `i'*10 - 4 in `obs'; + }; + }; + forvalues j = 1/`rc' {; + matrix `tmp' = `D'[....,`j']; + generate str d_`j' = "`: word `j' of `etitle''" in 1; + local coleq : word `j' of `ceq'; + if missing(`"`coleq'"') local coleq : coleq `tmp'; + local coleq : subinstr local coleq "`=char(183)'" ".", all; + replace d_`j' = `"`coleq'"' in 2; + if `j'>1 replace d_`=`j'-1' = cond((d_`j' == d_`=`j'-1') & (d_`=`j'-1'[1]==".x_" | d_`=`j'-1'[1]==""), ".x_", `"`coleq1'"') in 2; + local coleq1 `"`coleq'"'; + local cn : word `j' of `cnames'; + if missing("`cn'") local cn : colnames `tmp'; + local cn : subinstr local cn "`=char(183)'" ".", all; + replace d_`j' = "`cn'" in 3; + forvalues i = 1/`rr'{; + replace d_`j' = string(`D'[`i',`j'],"`cfrmt'") in `=`i'+3'; + local nstars = cond(`D_STARS'[`i', `j']<10, `D_STARS'[`i', `j'], 0); + replace f_`j' = "`nstars'_" + upper(substr(trim(f_`j'),3,5)) in `=`i'+3'; + }; // forvalues i + + summarize id if strpos(d_0, "easytofind3"), meanonly; + local stm = r(mean); + + replace f_`j' = "0_N2200" if inlist(l_0,"N","df_r", "df_m") & id > `stm'; + replace f_`j' = "0_N2203" if inlist(l_0,"r2","r2_a", "r2_p", "r2_a/r2_p") & id > `stm'; + replace f_`j' = "0_N2202" if l_0=="ll" & id > `stm'; + replace f_`j' = "0_N2200" if f_`j'=="" & id > `stm'; + + replace d_`j' ="(dropped)" if(d_`j'==".d_"); + replace d_`j' ="" if(d_`j'==".z_"); + }; // forvalues j + + replace l_0 = "Number of observations" if l_0=="N" & id > `stm'; + replace l_0 = "Log-Likelihood" if l_0=="ll" & id > `stm'; + replace l_0 = "R2" if l_0=="r2" & id > `stm'; + replace l_0 = "Adjusted R2" if l_0=="r2_a" & id > `stm'; + replace l_0 = "Pseudo R2" if l_0=="r2_p" & id > `stm'; + replace l_0 = "Adjusted/Pseudo R2" if l_0=="r2_a/r2_p" & id > `stm'; + + replace l_0 = d_0 if l_0==""; + replace f_0 = "0_S2110" if f_0==""; + + MVEncode, `mv'; +end; + +program define readformats; +args ni format; + local format : subinstr local format "," "", all; + + gettoken first rest : format, bind; + if missing("`rest'") {; + local rest "`format'"; + }; + else {; + local format "`rest'"; + }; + local first : subinstr local first "(" "", all; + local first : subinstr local first ")" "", all; + + tokenize "`first'"; + generate str f_0 = "0_`=substr("`1'", 1, 5)'"; + if ~missing("`2'") {; + local j=2; + local i=4; + while `i'<=_N {; + if missing("``j''") local j=2; + else {; + replace f_0="0_`=substr("``j''", 1, 5)'" in `i'; + local ++j; + local ++i; + }; + }; + }; + + local i=1; + while `i'<=`ni' {; + gettoken first rest : rest, match(p) bind; + local first : subinstr local first "(" "", all; + local first : subinstr local first ")" "", all; + tokenize "`first'"; + generate str f_`i' = "0_`=substr("`1'", 1, 5)'"; + if ~missing("`2'") {; + local j=2; + local k=4; + while `k'<=_N {; + if missing("``j''") local j=2; + else {; + replace f_`i'="0_`=substr("``j''", 1, 5)'" in `k'; + local ++j; + local ++k; + }; + }; + }; + local ++i; + if missing("`rest'") {; + local rest "`format'"; + }; + }; +end; + +program define _styles; + args styles font starchars; + + gettoken fno font : font; + gettoken font size : font; + local font = proper("`font'"); + if ~missing("`size'") {; + capture confirm number `size'; + if _rc {; + display as error "'`size'' found where font size expected"; + exit 7; + }; + local size "ss:Size='`=trim("`size'")''"; + }; + + local flist; + foreach var of varlist f_* {; + forvalues i=1/`=_N' {; + local f=`var'[`i']; + local flist "`flist' `f'"; + }; + }; + local flist : list uniq flist; + + local styles : subinstr local styles "<Styles><Style ss:ID='s' />" ""; + local styles : subinstr local styles "</Styles>" ""; + + local styles : subinstr local styles "'s`fno'_Title'" "'s`fno'_Title'", all count(local cc); + + if `cc'==0 {; + local styles "`styles'<Style ss:ID='s`fno'_Title'>"; + local styles "`styles'<Alignment ss:Vertical='Center' ss:Horizontal='Center' ss:WrapText='1'/>"; + local styles "`styles'<Font ss:Bold='1' ss:FontName='`font'' `size' />"; + local styles "`styles'</Style>"; + local styles "`styles'<Style ss:ID='s`fno'_Note'>"; + local styles "`styles'<Alignment ss:Vertical='Center' ss:Horizontal='Left' />"; + local styles "`styles'<Font ss:FontName='`font'' `size' />"; + local styles "`styles'</Style>"; + }; //if + + local 0 = 0; + local 1 = 1; + local 2 = 2; + local 3 = 3; + local 4 = 4; + foreach f in `flist' {; + local styles : subinstr local styles "'s`fno'_`f''" "'s`fno'_`f''", all count(local cc); + if `cc' continue; + + local lwrap = cond(upper(substr(`"`f'"', 3, 1))=="N", "", "ss:WrapText='1'"); + + local vert=upper(substr(`"`f'"', 4, 1)); + local T = 1; + local C = 2; + local B = 3; + if "``vert''"=="1" local V "ss:Vertical='Top'"; + else if "``vert''"=="2" local V "ss:Vertical='Center'"; + else if "``vert''"=="3" local V "ss:Vertical='Bottom'"; + else local V ""; + local hori=upper(substr(`"`f'"', 5, 1)); + local L = 1; + local R = 3; + if "``hori''"=="1" local H "ss:Horizontal='Left'"; + else if "``hori''"=="2" local H "ss:Horizontal='Center'"; + else if "``hori''"=="3" local H "ss:Horizontal='Right'"; + else local H ""; + local face=upper(substr(`"`f'"', 6, 1)); + local R = 0; + local B = 1; + local I = 2; + local O = 3; + local U = 4; + if "``face''"=="1" local B "ss:Bold='1'"; + else if "``face''"=="2" local B "ss:Italic='1'"; + else if "``face''"=="3" local B "ss:Bold='1' ss:Italic='1'"; + else if "``face''"=="4" local B "ss:Underline='Single'"; + else local B ""; + + local digt=substr(`"`f'"', 7, 1); + if ("`digt'" == "8") local digt ="0.00000000"; + else if ("`digt'" == "9") local digt ="0.000000000"; + else local digt =string(0,"%9.`digt'f"); + + local bline=substr(`"`f'"', 8, 2); + if "`bline'"=="1" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='Continuous' />"; + }; + else if "`bline'"=="2" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='Continuous' ss:Weight='1' />"; + }; + else if "`bline'"=="3" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='Continuous' ss:Weight='2' /> "; + }; + else if "`bline'"=="4" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='Continuous' ss:Weight='3' /> "; + }; + else if "`bline'"=="5" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='Dot' ss:Weight='1' /> "; + }; + else if "`bline'"=="6" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='DashDotDot' ss:Weight='1' /> "; + }; + else if "`bline'"=="7" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='DashDotDot' ss:Weight='2' /> "; + }; + else if "`bline'"=="8" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='DashDot' ss:Weight='1' /> "; + }; + else if "`bline'"=="9" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='DashDot' ss:Weight='2' /> "; + }; + else if "`bline'"=="10" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='Dash' ss:Weight='1' /> "; + }; + else if "`bline'"=="11" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='Dash' ss:Weight='2' /> "; + }; + else if "`bline'"=="12" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='SlantDashDot' ss:Weight='2' /> "; + }; + else if "`bline'"=="13" {; + local BR "<Border ss:Position='Bottom' ss:LineStyle='Double' ss:Weight='3' /> "; + }; + else local BR; + + local nstars=substr(`"`f'"', 1, 1); + if (`nstars' == 9) local fmt "(#,##`digt');(-#,##`digt')"; + else {; + if `nstars'>0 {; + local char : word `nstars' of `starchars'; + }; + else local char; + local fmt "#,##`digt'"`char'";-#,##`digt'"`char'""; + }; + local styles "`styles'<Style ss:ID='s`fno'_`f''>"; + local styles "`styles'<Alignment `V' `H' `lwrap'/>"; + local styles "`styles'<Font `B' ss:FontName='`font'' `size' />"; + local styles "`styles'<Borders>`BR'</Borders>"; + local styles `"`styles'<NumberFormat ss:Format='`fmt'' /></Style>"'; + }; + c_local styles "<Styles><Style ss:ID='s' />`styles'</Styles>"; +end; + +program define updateopts; + syntax [anything(name=stname)], [VER(string) updateopts EXcelpath(string) CAlcpath(string)] isest(integer); + + local stname =cond(missing("`stname'"), cond(`isest', "DEFAULT", "M"), upper("`stname'")); + + tempname file_w file_r; + tempfile tmpf; + + // check if we have the options file + quietly findfile xml_tab.ado; + local fname "`r(fn)'"; + local fname : subinstr local fname "xml_tab.ado" "xml_tab_options.txt"; + + capture confirm file "`fname'"; + local writenew = _rc | ~missing("`updateopts'"); + if `writenew'==0 {; + file open `file_w' using "`tmpf'", write; + local writenew = 1; // if version not found + + file open `file_r' using "`fname'", read; + local eof=0; + while `eof'==0 {; + file read `file_r' line; + local eof=r(eof); + local save 1; + if strpos(`"`line'"', "VERSION") {; + if trim(`"`line'"')!="VERSION=`ver'" {; + continue, break; + }; + else local writenew = 0; + }; + if missing("`c(mode)'`c(console)'") {; // do we need a clickable link? + if strpos(`"`line'"', "EXCELPATH") {; + local tt `: subinstr local line "EXCELPATH=" ""'; + capture confirm file "`tt'"; + _getfilename "`tt'"; + if (_rc==0 & upper("`r(filename)'")=="EXCEL.EXE") | missing("`tt'") {; + local excelpath "`tt'"; + local excelfound 1; + }; + else local save 0; + }; + if strpos(`"`line'"', "CALCPATH") {; + local tt `: subinstr local line "CALCPATH=" ""'; + capture confirm file "`tt'"; + _getfilename "`tt'"; + if (_rc==0 & upper("`r(filename)'")=="SCALC.EXE") | missing("`tt'") {; + local calcpath "`tt'"; + + local calcfound 1; + }; + else local save 0; + }; + }; + else {; + local excelfound 1; + local calcfound 1; + }; + if strpos("`line'", "`stname'=") {; + local style `: subinstr local line "`stname'=" ""'; + }; + if ~missing("`line'") & `save' file write `file_w' "`line'" _n; + + }; + if `writenew' {; + file close `file_w'; + erase `tmpf'; + }; + }; + if `writenew'>0 {; //there is no options file + local DEFAULT "format(S2100 (S2210 N2303)) cw(0 140) right wide stars(0.01 0.05 0.1)"; + local S1 "format(S2100 (S2210 N2303) (S2210 N2123)) cw(0 140) right wide stars(0.01 0.05 0.1) lines(COL_NAMES 1 _cons 1 LAST_ROW 13) stats(N r2)"; + local M "format(N2103) cw(0 140)"; + file open `file_w' using "`tmpf'", write; + file write `file_w' " VERSION=`ver'" _n; + file write `file_w' " DEFAULT=`DEFAULT'" _n; + file write `file_w' " S1=`S1'" _n; + file write `file_w' " M=`M'" _n; + local style "``stname''"; + local upd = 1; + }; + if missing("`excelfound'") {; + capture confirm file "`excelpath'"; + if _rc {; + local excelpath; + + capture local dirs : dir "C:/Program Files (x86)/Microsoft Office" dirs "office*"; + + if ~_rc {; + local x86 " (x86)"; + }; + else {; + capture local dirs : dir "C:/Program Files/Microsoft Office" dirs "office*"; + }; + foreach d of local dirs {; + capture confirm file "C:/Program Files`x86'/Microsoft Office/`d'/excel.exe"; + if ~_rc {; + local excelpath "C:/Program Files`x86'/Microsoft Office/`d'/excel.exe"; + continue, break; + }; + }; // d + }; + file write `file_w' "EXCELPATH=`excelpath'" _n; + local upd = 1; + }; + + if missing("`calcfound'") {; + capture confirm file "`calcpath'"; + if (_rc>0) {; + local calcpath ; + capture local dirs : dir "C:/Program Files" dirs "openoffice*"; + foreach d of local dirs {; + capture confirm file "C:/Program Files/`d'/program/scalc.exe"; + if ~_rc {; + local calcpath "C:/Program Files/`d'/program/scalc.exe"; + continue, break; + }; + }; // d + }; + file write `file_w' " CALCPATH=`calcpath'" _n; + local upd = 1; + }; + file close _all; + if ~missing("`upd'") {; + capture copy `tmpf' `"`fname'"', replace; + if _rc {; + if ~missing(`"`updateopts'"') {; + display as error "could not save options"; + display as error "file can not be saved at this location"; + exit 603; + }; + // else exit; + }; + }; + // write defaults + local 0 ", `style'"; + syntax , [FONt(passthru) LOng WIde STARs(passthru) + save(passthru) SHeet(passthru) sd TStat Pvalue Right Below sd2 *]; + if missing("`font'") local font "font(Arial 10)"; + if missing("`long'`wide'") local wide "wide"; + if missing("`save'") local save "save(stata_out.xml)"; + if missing("`sheet'") local sheet "sheet(sheet1)"; + if missing("`right'`below'`sd2'") local right "right"; + if missing("`sd'`tstat'`pvalue'") local sd "sd"; + if missing("`stars'") local stars "stars(*** 0.01 ** 0.05 * 0.1)"; + + if `isest' {; + local style "`save' `sheet' `long' `wide' `sd' `tstat' `pvalue' `stars' `right' `below' `sd2' `font' `options'"; + }; + else {; + local style "`save' `sheet' `font' `stars' `options'"; + }; + local style : list retokenize style; + + c_local excelpath `"`excelpath'"'; + c_local calcpath `"`calcpath'"'; + c_local styles `"`style'"'; +end; // program updateopts + +program define opts_Exclusive; // Rewriting for the Stata 8.0 +args opts; + local n : word count `opts'; + if `n' < 2 {; + exit; + }; + display in smcl as error "{p}"; + display in smcl as error "only one of"; + if `n' == 2 {; + display in smcl as error `"`: word 1 of `opts'' "' + `"or `: word 2 of `opts''"'; + }; + else {; + forvalues i=1/`=`n'-1' {; + display in smcl as error `"`:word `i' of `opts'',"'; + }; + display in smcl as error `"or `:word `n' of `opts''"'; + }; + display in smcl as error "is allowed{p_end}"; + exit 198; +end; // program opts_Exclusive + +program define expandspec; + args result b spec; + + foreach sp of local spec {; + local full = cond(index("`sp'", ":") > 0, "full",""); + local rnames : row`full'names `b'; + if strpos("`sp'", "*") + strpos("`sp'", "?")> 0 {; + foreach name of local rnames {; + if strmatch("`name'", "`sp'") local spn "`spn' `name'"; + }; + }; + else local spn "`spn' `sp'"; + }; + local spn : list uniq spn; + c_local `result' "`spn'"; +end; // program expandspec + +program define opts_excl1; + args nest st opt; + local 0 ", `st'"; + syntax , [replace append WIde LOng sd TStat Pvalue Right Below sd2 *]; + local `opt'; + local st "`replace' `append' `wide' `long' `sd' `tstat' `pvalue' `right' `below' `sd2' `options'"; + local st : list retokenize st; + c_local `nest' `st'; +end; // program opts_excl1 + +program define findfont; + args line font; + local xmlstr `"`line'"'; + //xmlstr will be of a form : <FontList>01 "Arial" 10?02 "Times New Roman" 10?03 "Arial" 12?...</FontList> + local xmlstr : subinstr local xmlstr "<FontList>" ""; + local xmlstr : subinstr local xmlstr "</FontList>" ""; + + while ~missing("`xmlstr'") {; + gettoken item xmlstr : xmlstr, parse("?"); + gettoken no xfont : item; + + gettoken font size : font; + local font "`font' `size'"; + local font : list retokenize font; + + if (upper(trim(`"`xfont'"')) == upper(trim(`"`font'"'))) {; + local found 1; + continue, break; + }; + local xmlstr : subinstr local xmlstr "?" ""; + }; + if missing("`found'") {; + local ++no; + if (`no'< 10) local no "0`no'"; + local line : subinstr local line "</FontList>" ""; + local line `"`line'?`no' `font'</FontList>"'; + }; + c_local fno `no'; + c_local line `"`line'"'; +end; // program findfont + +program define getstarchars; + syntax [, STARs(string asis)]; + + local stars : subinstr local stars "," "", all; + local n : word count `stars'; + if `n'<=3 {; // Simple syntax + local strchrs "*** ** *"; + }; + else {; + local strchrs `""`: word 1 of `stars''" "`: word 3 of `stars''""'; + local strs `"`: word 2 of `stars'' `: word 4 of `stars''"'; + if ~missing(`"`: word 6 of `stars''"') {; + local strchrs `"`strchrs' "`: word 5 of `stars''""'; + local strs `"`strs' `: word 6 of `stars''"'; + }; + local stars `strs'; + }; + + capture numlist "`stars'", range(>=0 <=1); + if _rc {; + display as error "stars(): `stars' - invalid numlist"; + exit _rc; + }; + _qsort_index `stars'; + c_local stars "`r(slist1)'"; + + foreach i in `r(order)' {; + local starchars `"`starchars' "`: word `i' of `strchrs''""'; + }; + c_local starchars `"`starchars'"'; +end; // program gettstarchars + +program define Mat_Capp; + + if _caller() >= 9.0 {; + matrix_capp `0'; + }; + else {; + syntax anything [, miss(str) cons ts]; + + local b12 : word 1 of `anything'; + local colon : word 2 of `anything'; + local b1 : word 3 of `anything'; + local b2 : word 4 of `anything'; + + tempname TMP; + forvalues j = 1/2 {; + forvalues i = 1/`=colsof(`b`j'')' {; + matrix `TMP' = `b`j''[....,`i']; + local cnames `"`cnames' "`: colnames `TMP''""'; + local ceqs `"`ceqs' "`: coleq `TMP''""'; + }; + matrix colnames `b`j'' =:a; + }; + mat_capp `0'; + matrix colnames `b12'=`cnames'; + matrix coleq `b12'=`ceqs'; + }; +end; // program Mat_Capp + +program define Widemat, rclass; + args bbc; + + local ceq : coleq `bbc', quoted; + local cequ : list uniq ceq; + local req : roweq `bbc', quoted; + local requ : list uniq req; + + if `"`requ'"' == `""_""' {; + return matrix result = `bbc'; + exit; + }; + + tempname wbc wbbc wbbbc J tmp; + + local nii = 0; + + foreach col of local cequ {; + capture matrix drop `wbbc'; + matrix `tmp' = `bbc'[....,"`col':"]; + local ni = 0; + foreach row of local requ {; + matrix `wbc' = `tmp'["`row':",....]; + matrix roweq `wbc' =:; + matrix `J' =J(`=rowsof(`wbc')', `=colsof(`wbc')', .z); + if mreldif(`wbc', `J')>0 {; + matrix coleq `wbc'="`row'"; + forvalues xi = 1/`=colsof(`wbc')-1' {; + local etitle "`etitle' .x"; + }; // end forvalues + + if `++ni' > 1 {; + mat_capp `wbbc' : `wbbc' `wbc', miss(.z) cons ts; + local etitle "`etitle' .x"; + }; + else {; + matrix `wbbc' = `wbc'; + }; + }; + }; + local etitle `"`etitle' "`col'""'; + if `ni' {; + if `++nii' > 1 {; + capture mat_capp `wbbbc' : `wbbbc' `wbbc', miss(.z) cons ts; + }; + else {; + matrix `wbbbc' = `wbbc'; + }; + }; + }; + return matrix result = `wbbbc'; + if `: word count `cequ''>1 c_local etitle `"`etitle'"'; + c_local showeq0 "showeq"; +end; // program Widemat + +program define MVEncode; + syntax, [mv(string asis)]; + + local spec `"`mv'"'; + local n 0; + if `"`spec'"' == `""""' {; + local iselse 1; + }; + else {; + gettoken tok spec : spec, parse(" =\"); + if missing(`"`spec'"') & ~missing(`"`tok'"') {; + local else_rule `"`tok'"'; + local iselse 1; + }; + else {; + while `"`tok'"' != "" & `"`tok'"' != "else" {; + local ++n; + capture assert `"`tok'"' == "." | ( (length(`"`tok'"')==2 & inrange(`"`tok'"',".a",".z")) ); + if _rc Error 198 `"`tok' is not a missing value code"'; + + local lhs`n' `"`tok'"'; + + gettoken tok spec : spec, parse(" =\"); + if `"`tok'"' != "=" Error 198 "= expected"; + + gettoken tok spec : spec, parse(" =\"); + local rhs`n' `"`tok'"'; + + gettoken tok spec : spec, parse(" =\"); + if !inlist(`"`tok'"', "", "\") Error 198 `"`tok' found, where \ expected"'; + + gettoken tok spec : spec, parse(" =\"); + }; + + if `"`tok'"' == "else" {; + gettoken tok spec : spec, parse(" =\"); + if `"`tok'"' != "=" Error 198 "= expected"; + + gettoken tok spec : spec, parse(" =\"); + local else_rule `"`tok'"'; + local iselse 1; + }; + }; + }; + + foreach var of varlist d_* {; + forvalues rule = 1/`n' {; + replace `var' = `"`rhs`rule''"' if `var'==`"`lhs`rule''"'; + }; + if "`iselse'" != "" replace `var' = `"`else_rule'"' if `var' == "." | (length(`var')==2 & inrange(`var',".a",".z")); + }; + +end; + +program define Error; + args nr txt; + + display as error `"`txt'"'; + exit `nr'; +end; diff --git a/Modules/ado/plus/x/xml_tab.hlp b/Modules/ado/plus/x/xml_tab.hlp new file mode 100644 index 0000000..5a28c65 --- /dev/null +++ b/Modules/ado/plus/x/xml_tab.hlp @@ -0,0 +1,831 @@ +{smcl} +{* 27Mar2008 }{...} +{cmd:help xml_tab} +{hline} + +{title:Title} + +{p2colset 9 20 22 2}{...} +{p2col :{hi:xml_tab} {hline 2}}Save results in XML format{p_end} +{p2colreset}{...} + +{* SYNTAX *} +{title:Syntax} + +{p 6 16 2} +{cmd:xml_tab} [{it:namelist}] [{cmd:,} {it:{help xml_tab##options:options}}] + +{pstd} +where {it:namelist} is a list of stored estimations or matrices; see {helpb estimates}. A {it:namelist} comprises +one or more specifications, separated by spaces. A specification can be a name of a stored estimation or a matrix +name. {cmd:xml_tab} will output the estimation coefficients and one of the three statistics (standard errors, +t-ratio, or p-values). + +{pstd} +For estimation results {cmd:xml_tab} has enough information to calculate significance levels +itself but if a matrix to be outputted, {cmd:xml_tab} looks also for {it:matname}_STARS matrix +that must be of same size as {it:matname} and contain values 0,1,2 or 3 denoting significance levels. +{help xml_tab##statistics:See} option {opt stars} for more details. + +{pstd}{marker extended}{...} +The stored estimation could be also specified in an extended form with parameters. + +{p 6 16 2} +{cmd:xml_tab} [{it:estname1(stat11 stat12, {it:eform_option})} [{it:estname2(stat21 stat22)} [...]]] [{cmd:,} {it:{help xml_tab##options:options}}] + +{pstd} +where {it:estname} is a name of the stored estimation, and {it:stat1} and {it:stat2} are the names of matrixes stored in +{cmd:e()}. Specification {opt estname(b V)} is identical to {opt estname}. You can access the names of the stored +matrixes with {helpb ereturn list}. See {help xml_tab##exampleme:examples}; + +{pstd} +The extended form specification is useful when accessing non-standard statistics, for example, when outputting +marginal effects of the parameters after e.g., {helpb mfx}, {helpb dprobit}. The extended form could also be used when +outputting the results in exponentiated forms after commands such as {helpb streg}, {helpb stcox}, {helpb st}, etc. + +{pstd} +Note that you may enclose {it:filename} in double quotes and must do so if {it:filename} contains blanks or other special characters. + +{marker options}{...} +{synoptset 27 tabbed}{...} +{synopthdr:options} +{synoptline} +{syntab:{help xml_tab##output:Output}} +{synopt:{opt save(["]filename["])}}name and path for the output file {p_end} +{synopt:{opt replace}}overwrite existing {it:filename}{p_end} +{synopt:{opt append}}if workbook {it:filename} exists, add a new sheet, otherwise create a new workbook {p_end} +{synopt:{opt sh:eet(name [, sh_opts])}}worksheet where the table is outputted{p_end} + +{p2col 10 34 40 8:{cmdab:col:or(}{it:#}{cmd:)}}specify tab color for a worksheet{p_end} +{p2col 10 34 40 8:{cmdab:nog:ridlines}}hide gridlines on a worksheet{p_end} + + +{synopt:{opt savem:at(name [, sm_opts])}}save estimates to a matrix{p_end} + +{p2col 10 34 40 8:{cmd:replace}}if matrix {it:name} already exists replace it. The default is to append{p_end} +{p2col 10 34 40 8:{cmd:exit}}after writing the matrix exit {cmd:xml_tab} without creating an output file{p_end} + +{synopt:{opt mv(mvspec)}}change missing values to string or numeric values.{p_end} + +{syntab:{help xml_tab##statistics:Statistics}} +{synopt:{opt sd}}show estimated coefficients and standard deviations (default){p_end} +{synopt:{opt ts:tat}}show estimated coefficients and t-statistic{p_end} +{synopt:{opt pv:alue}}show estimated coefficients and p-value{p_end} +{synopt:{opt stat:s(scalarlist)}}report {it:scalarlist} statistics in the table{p_end} +{synopt:{opt star:s(starspec)}}controls significance levels and symbols{p_end} +{synopt:{opt noadj:ust}}report not adjusted t-statistics{p_end} +{synopt:{it:eform_option}}display exponentiated coefficients. see {help eform_option};{p_end} + +{syntab:{help xml_tab##tablelayout:Table Layout}} +{synopt:{opt b:elow}}show standard deviation (t-statistics or p-values) under the estimates{p_end} +{synopt:{opt nobr:ackets}}remove brackets around standard deviation (t-statistics or p-values){p_end} +{synopt:{opt r:ight}}show standard deviation (t-statistics or p-values) next to the estimates (default){p_end} +{synopt:{opt lo:ng}}long output table style{p_end} +{synopt:{opt wi:de}}wide output table style (default){p_end} +{synopt:{opt keep(keeplist)}}report {it:keeplist} rows{p_end} +{synopt:{opt drop(droplist)}}drop {it:droplist} rows from the table{p_end} +{synopt:{opt eq:uations(matchlist)}}match the equations of the models according to {it:matchlist}{p_end} + +{syntab:{help xml_tab##tableformating:Table Formatting}} +{synopt:{opt f:ormat(string)}}description of the output table format{p_end} +{synopt:{opt l:ines(string)}}rows to be underlined{p_end} +{synopt:{opt nol:abel}}display variable names instead of labels{p_end} +{synopt:{opt c:onstant(string)}}specifies label for the constant{p_end} +{synopt:{opt rb:lanks(string)}}add rows to the table{p_end} +{synopt:{opt cb:lanks(cblist)}}add blank columns to the table{p_end} +{synopt:{opt cw:idth(cwlist)}}modify column widths{p_end} +{synopt:{opt tb:lanks(#)}}add blank rows at the top of the table{p_end} +{synopt:{opt t:itle(string)}}table title{p_end} +{synopt:{opt rn:ames(string)}}custom row names{p_end} +{synopt:{opt cn:ames(string)}}custom column names{p_end} +{synopt:{opt ce:q(string)}}custom column equation names (super-titles){p_end} +{synopt:{opt note:s(string)}}add notes to the end of the table{p_end} +{synopt:{opt font(string)}}specifies font for a worksheet{p_end} +{synopt:{opt sty:le(stylename)}}predefined format styles for output{p_end} + +{syntab:{help xml_tab##system:System options}} +{synopt:{opt ex:celpath(["]filename["])}}specifies the location of the {it:MS Excel} executable{p_end} +{synopt:{opt cal:cpath(["]filename["])}}specifies the location of the {it:OO Calc} executable{p_end} +{synopt:{opt noi:sily}}displays the complete list of options applied to the table{p_end} +{synopt:{opt updateopts}}forces the options file update{p_end} + +{* DESCRIPTION *} +{title:Description} + +{pstd} +{cmd:xml_tab} saves Stata output directly into XML file that could be opened with {it:Microsoft Excel} or +{it:OpenOffice Calc}. The program is relatively flexible and produces print-ready tables in {it:Excel} or {it:Calc}. +{cmd:xml_tab} allows users to apply different formats to the elements of the output table and essentially do +everything {it:MS Excel} or {it:OO Calc} can do in terms of formatting from within Stata. + +{pstd} +{cmd:xml_tab} can create formatted tables of coefficients, standard errors, t- and p- values, summary statistics, etc., +after any Stata estimation command that saves its results in {cmd:e()}. The program allows saving the results of +a single estimation or a matrix into a table, combining several stored estimations or matrixes into one table, and +outputting several tables into the different sheets of XML workbook. + +{pstd} +Calling {cmd:xml_tab} without any arguments saves the results of last estimation command into file {it:stata_out.xml} +located in the current work directory. After the XML file is saved {cmd:xml_tab} can create links in the Stata Results +window. Clicking on a link opens the output table in {it:MS Excel} or {it:OO Calc}. +See {help xml_tab##system:system options} for details. + +{pstd} +{cmd:xml_tab} can combine multiple estimations saved using {helpb estimates store} command. The example of outputting +multiple estimates into one table might look as follows: + +{p 6 20 2}{opt .sysuse auto}{p_end} + +{p 6 20 2}{opt .regress price rep78 length mpg}{p_end} + +{p 6 20 2}{opt .estimates store reg1}{p_end} + +{p 6 20 2}{opt .regress price rep78 length mpg turn if foreign==1}{p_end} + +{p 6 20 2}{opt .estimates store reg2}{p_end} + +{p 6 20 2}{opt .xml_tab reg1 reg2}{p_end} + +{pstd} +In this very simple example, the estimates from the first regression are saved under the name {bf:reg1}. The +specification of the second regression contains one extra variable and the sample for the estimation is constrained. +The estimates from the second regression are saved under the name {bf:reg2}. {cmd:xml_tab} creates an output table +containing five columns. The first column contains the names of the variables used in either regression. The second and +the fourth columns contains the estimated coefficients of the first and the second regression, and the standard errors +of the coefficients are outputted in columns 3 and 5. + +{pstd} +{cmd:xml_tab} has many additional options to control the outputted statistics, formatting and a general layout of +the output tables. Please read the description of these options below and have a look at our examples. + +{title:Options} +{* OUTPUT *} +{marker output}{...} +{dlgtab:Output} + +{phang} {* SAVE *} +{opt save(["]filename["])} specifies a name for XML file where tables are outputted. If {opt save(["]filename["])} is +omitted, the output will be saved in {cmd:stata_out.xml} located in the current working directory. Use {opt append} and +{opt replace} options to instruct {cmd:xml_tab} to append a table into the new worksheet of the existing file or to +replace the existing file. + +{pmore} +Alternatively, the output file name can be specified with the {opt using} syntax. Instead of {opt save()} users can write: + +{p 12 20 2}{cmd: .xml_tab using c:\tmp\xml_out.xml, *} {p_end} + + +{phang} {* REPLACE *} +{opt replace} permits to overwrite the existing XML file. + +{phang} {* APPEND *} +{opt append} if XML file already exists, a new sheet will be added to it where the output table will be saved. +Otherwise the new file will contain one sheet with the output. + +{phang}{bf:NOTE:} You need to close XML file opened in Excel or Calc for {cmd:xml_tab} to save new tables there. If XML +file is still opened, {cmd:xml_tab} reports an error message:{err: file can not be saved at this location}. + +{phang} {* SHEET *} +{opt sheet(name)} +You can output several tables into the different sheets of XML file (workbook). Excel or Calc files could contain +multiple worksheets within a single document (workbook). {cmd:sheet()} option specifies the name for the new sheet +where the table will be outputted. If not specified, a worksheet named {it:Sheet1} will be added. + +{pmore} +A valid Excel worksheet name must have no more than 31 characters. The worksheet name cannot contain any of the +following: : \ / ? * [ or ] and can not be left blank. + +{phang} {* SAVEMAT *} +{opt savemat(name)} saves estimation results in a matrix. If {it:name} exists and option {opt replace} was not +used then additional rows will be appended to that matrix. In this case number of columns in the existing matrix +and the one to be appended must be the same. The output matrix will contain estimates and standard errors (t-statistics, +p-values) in a form determined by {help xml_tab##tablelayout:table layout} options. Significance level info will be +saved/appended to {it:name}_STARS matrix, see exporting a matrix {help xml_tab##matrices:example}. + +{phang} {* MV *} +{cmd:mv(}{it:#}|{it:mvc}{cmd:=}{it:#} [{bind:{cmd:\} {it:mvc}{cmd:=}{it:#}}...] [{cmd:\} {opt else=}{it:#}]{cmd:)} specifies +the new values (string or numeric) to which the missing values ate to be changed. + +{pmore} +{opt mv(str)} specifies that all types of missing values be changed to {it:str}. + +{pmore} +{opt mv(mvc=str)} specifies that occurrences of missing-value code {it:mvc} be +changed to {it:str}. Multiple transformation rules may be specified, separated +by a backward slash {cmd:\}. The list may be terminated by the special rule +{opt else=}{it:str}, specifying that all types of missing values not yet +transformed be set to {it:str}. + +{pmore} +For example: {cmd:mv("")}, {cmd:mv(.n="N.A." \ .d="(dropped)" \ else="")} + +{pmore}{help xml_tab##options:back to top} + +{* STATISTICS *} +{marker statistics}{...} +{dlgtab:Statistics} + +{phang} {* SD TSTAT PVALUE *} +{opt sd}, {opt tstat} and {opt pvalue} control what statistic will be outputted together with the estimated coefficient. +If option {opt sd} is specified, the standard errors of the estimated coefficients are outputted. Specifying +{opt ts:tat} produces a table of coefficients and the t-statistics. {opt pv:alues} outputs the probability that the true +value of the estimated coefficient is zero. + +{pmore} +Only one option can be specified. If no options are specified {opt sd} the standard deviations are outputted. + +{phang} {* STATS *} +{opt stats(scalarlist)} specifies one or more statistics (scalars) to be displayed in the table. The statistics +specified in {opt stats} are outputted at the end of the table and could be the number of observation stats(N); +adjusted R2 for a regression {opt stats}(r2_a); value of log-likelihood {opt stats}(ll) and any statistics that are +saved in e() scalars after estimation routines. See {helpb ereturn}. + +{pmore} +In addition {it:scalarlist} may contain the following statistics: + +{p 12 20 2}{opt aic}{space 9}Akaike's information criterion{p_end} +{p 12 20 2}{opt bic}{space 9}Schwarz's information criterion{p_end} +{p 12 20 2}{opt rank}{space 8}rank of {cmd:e(V)} {hline 1} number of free parameters in model{p_end} +{p2colreset}{...} + +{pmore} +If several estimations are combined in one table the specified statistics will be displayed for each estimation. + +{phang} {* Stars *} +{opt stars(starspec)} specifies the significance level(s) and the symbol(s) for the coefficients to be marked in the +output table. The simple syntax for {bf:starspec} may contain up to three numbers separated by spaces corresponding to +significance levels denoted by one, two and three stars. If {bf:numlist} is just one number, the coefficients with the +p-value less than that number will be marked by a star. For example, option {opt stars(0.1)} will mark with one star +all the coefficients with p-value less than 0.1. If two values are specified in the {bf:numlist}, {cmd:xml_tab} will +mark with one star the coefficients with p-values that are less or equal to the first value and grater than the second +value. Coefficients with p-values less than the second value will be marked by two starts. For example, specifying {opt +stars(0.1 0.05)} will put one star on coefficients with pvalues in the range from 0.1 to 0.5 and put two stars on the +coefficients with p-value less than 0.5. + +{pmore}The extended syntax allows selecting the symbols to mark the significance leves. In this case, {bf starspec} +consist of up to three symbol/number pairs. The symbol could by one or several characters and the number indicates the +significance level similar to the simple syntax described above. + +{pmore} +By default, {cmd:xml_tab} output tables with the following {opt star} specification: {opt star(0.1 0.05 0.01)}. +Alternatively, this option could be specified in the extended syntax as {opt star(* 0.1 ** 0.05 *** 0.01)}. Note that +any symbol or a combination of several symbols cold be used instead of * in this specification. Specifying 0 in the +numlist would suppress stars on the table: {opt star(0)}. + +{phang} {* NOADJust *} +{opt noadjust} is used when outputting some transformations of the estimated coefficients (i.e. marginal effects). By +default, {cmd:xml_tab} calculates t-statistics as f(b)/sd_f(b). But if {opt noadjust} is specified then t-stat=b/sd_b +will be reported and used for p-values and significance calculations. + +{phang} {* eform *} +{it:eform_option} when this option is specified the coefficients and the standard errors (t-statistics and +p-values) for {ul:all} estimation results will be reported in exponentiated form. To transform only some of the +estimation results, the {help xml_tab##extended:extended syntax} can be used. For example, + +{p 12 20 2}{cmd:.xml_tab reg streg(, hr) prob, replace} + +{pmore}outputs unmodified coefficients and standard errors for esimations {it:reg} and {it:prob}, but exponentiated +(Hazard ratio) coefficients and modified standard errors for the estimation {it:streg} (displaying 'Haz Ratio' as a +title). + +{pmore}{help xml_tab##options:back to top} + +{* TABLE LAYOUT *} +{marker tablelayout}{...} +{dlgtab:Table Layout} + +{phang} {* BELOW & RIGHT *} +{opt below} and {opt right} control whether the standard deviation, t-statistic or p-values +(see {help xml_tab##statistics:sd tstat pvalue}) will be placed to the right or below the coefficients. {opt right} is +used by default. + +{pmore} For example: if {opt right} is specified the element of the output table will look like:{p_end} + +{p 13 20 2}{bf: 0.123 {it:0.456}}{p_end} + +{pmore} if {opt below} is specified the element of the output table will look like:{p_end} + +{p 13 20 2}{bf:0.123}{p_end} +{p 12 20 2}{it:(0.456)}{p_end} + +{phang} {* NOBRACKETS *} +{opt nobrackets} removes brackets around standard deviations (t-statistics or p-values), which is the default format when +{opt below} is used. + +{phang} {* LONG & WIDE *} +{opt long} and {opt wide} produce "long version" or "wide version" of output table. {opt wide} specifies that the +individual equations from multiple-equation models (e.g., mlogit, biprobit, heckman) to be placed in separate columns. +Summary statistics will be reported under the first equation if {opt wide} is specified. This is a default option. + +{pmore} +For example if a dependent variable with three categories is fitted with {cmd:mlogit} using 10 exogenous +variables, specifying {opt wide} option would result in a 12x5 table. The first column of this table contains variable +labels/names, the second and third columns contain the estimated coefficients and a standard errors for the first +equation, and the fourth and fifth columns contain the estimated coefficients and a standard errors for the second +equation. + +{pmore} +Alternatively, specifying option {opt long} places the equations of the multiple-equation estimation below one another +in a single column. + +{phang} {* KEEP *} +{opt keep(keeplist)} specifies the coefficients (and their order) to be included in the table. A {it:keeplist} +comprises one or more specifications, separated by a space: a variable name (e.g., price), and equation name (e.g., +mean:), or a full name (e.g., mean:price). + +{pmore} Using {opt keep} in a multiple-equation or in multiple-estimation tables would output only variables specified +in the {it:keeplist}. If some of the equations/estimations contain no variables in {it:keeplist}, these equations will +not be outputted. + +{pmore} If you want to keep some variables only in selected equations, make sure you specify the correct names for the +equations. {cmd:xml_tab} uses the name of a dependent variable as an equation name. {opt keep} will +output statistics for the variables in {it:keeplist} in all estimation/equations with identical names (same dependent +variable). + +{phang} {* DROP *} +{opt drop(droplist)} identifies the coefficients to be dropped from the table. A {it:droplist} comprises one or more +specifications, separated by spaces. A specification can be either a variable name (e.g. price), an equation +name followed by a colon (e.g. mean:), or a full name (e.g. mean:price). + +{pmore} +{opt drop(droplist)} option could be useful if a user wants to suppress the output of coefficients for some +variables. For example, if the empirical specification includes several regional dummies, one might want to create the +output tables without the coefficients on these dummies. If regional dummies are named reg1,...,reg12, +specifying {opt drop(reg*)} will suppress the output of the coefficients on these dummies in the table. + +{pmore} +In the multi-equation estimations (e.g., {helpb heckman}, {helpb heckprobit}) sometimes you might want to suppress the +output of the coefficients for first stage equation. This could be done by specifying {cmd:drop(}select:{cmd:)}, where +select is the name of the first stage equation. See more example of using {opt drop()} option in +{help xml_tab##exampledk:Examples} section. + +{pmore} +Characters * and ? can be used for variable names in the {it:keeplist} and {it:droplist}. The * character +indicates to match one or more characters and the ? character matches a single character. All variables matching the +pattern will be a included in the lists. + +{p 8 20 2}{cmd:.xml_tab, droop(region_*)}{p_end} +{p 8 20 2}{cmd:.xml_tab, droop(region_?)}{p_end} + +{pmore}In this example, the first command will suppress the output of coefficients for variables region_1-region_15, +but the second one will output just suppress the coefficients for region_1-region_9, because only the one +digit(character) was allowed by ?. + +{pmore} +If both {cmd:keep()} and {cmd:drop()} are specified, {cmd:keep} will be applied first. + +{phang} {* EQUATIONS *} +{opt equations(matchlist)} specifies how the equations of the models in {it:namelist} are to be matched. This option works +exactly the same way as {opt equations} in {cmd:estimates table}; see {help estimates##matchlist:estimates_options} for +details. + +{pmore}{help xml_tab##options:back to top} + +{* TABLE FORMATING *} +{marker tableformating}{...} +{dlgtab:Table Formatting} + +{phang} {* FORMAT *} +{opt format(flist)} specifies a list containing the formatting information for each cell of an XML table. The format +of each cell is defined by a formatting string. A formatting string consists of five alpha-numerical symbols in the order +specified bellow: + + +{space 10}Cell type : (S|s) - string, (N|n) - numeric +{space 10}Vertical alignment: (T|t|1) - Top , (C|c|2) - Center, (B|b|3) - Bottom +{space 10}Horizontal alignment: (L|l|1) - Left, (C|c|2) - Center, (R|r|3) - Right +{space 10}Font style: (R|r|0) - Regular, (B|b|1)- Bold, (I|i|2) - Italic, (O|o|3) - Bold Italic, (U|u|4) - Underline +{space 10}Decimal places : 0-9 defining number of digits after the decimal + +{pmore}The order of codes in the formatting string is important. The formatting string can contain a mixture of +alpha-numerical symbols. Upper and lower-case character and numerical codes can be used interchangably. For example, +a formatting string can look like N2210, NCCI2, nT1R0, sccb0 etc. + + +{pmore}The formatting for a table of size nxm is described as a list of codes for table's columns. That list has a +form: + +{pmore}{cmd:((F_00 F_01...F_0n) (F_10 F_11...F1_n) ... (F_n0 F_n1...F_mn))} + +{pmore} Format lists for the different columns are enclosed in parenthesis and separated by a space. The first format +list (F_00 F_01...F_0n) defines format for the rownames (e.g. variable names). The list (F_k0 F_k1...F_kn) describes +formatting of cells of the {it:k}-th column; the F_k0 defines the format for the {it:k}-th column's header (e.g. coeff. +std.err.). + +{pmore} +If the dimensions of the formatting list are smaller than the dimensions of the output table, the formatting will be +extended for the remaining rows/columns. If just one formatting code is specified as in {opt format((S2110))} (string, +centered vertically, left justified, in bold, with 0 decimal places), that format will be applied to each cell +of the output table (including variable names and column headers). If two codes are specified as in +{opt format((S2110) (N2230))}, the column with variables names will be formatted using S2110 format and all other +columns in the table will be formatted with N2230. Specifying three codes ({opt format((S2110) (NCCI0) (N2211))}) will +apply format S2110 to the column of variable names; format N2230 to all odd numerical columns; and format N2211 to all +even numerical columns of the table. + +{pmore}Similarly, is {opt k+1} formatting codes are specified the first format will be applied to the column of the +variable/row names and remaining {opt k} formats will be applied repeatedly to every group of k columns of the table. +By specifying more than one formatting code for a column you can control the formatting of every cell in a column. + +{pmore}Analogously to the extension rule for the column formats, the first code of the list will be applied to the column +header and the next codes will be used repeatedly for the cells of a column. For example, format((S2110) (SCCB0 N2302 +N2322)) outputs the variable names with format S2110, the headers for each numerical column with format S2210 +format; every odd row has a format N2302 (right justified with 2 decimals) and every even row is formatted with +N2322 (italic with 2 decimals). + +{pmore}See {opt styles} for an alternative way of specifying the formatting of the output table. + +{phang} {* LINES *} +{opt lines(string)} will draw the bottom borderline in the cells with the listed variables. {it:string} is list +of paired parameters. The first parameter specifies the variable name (or row number) and the second parameter a line style. +The line style can be a number from 0 to 13 that corresponds to the line styles defined below. In addition, specifying +{cmd:SCOL_NAMES}, {cmd:COL_NAMES} and {cmd:LAST_ROW} instead of variable names {cmd:xml_tab} will draw +lines under equation names ({cmd:SCOL_NAMES}), statistic titles (e.g., coeff. std.error) {cmd:COL_NAMES} or under the +last row of table ({cmd:LAST_ROW}). + +{pmore}{it:Line #} {it:Style} + +{synoptset 14}{...} +{synopt:{space 8}{opt #}}{it:Style}{p_end} + +{synopt:{space 8}{opt 0}}None{p_end} +{synopt:{space 8}{opt 1}}Continuous hairline{p_end} +{synopt:{space 8}{opt 2}}Continuous thin{p_end} +{synopt:{space 8}{opt 3}}Continuous medium{p_end} +{synopt:{space 8}{opt 4}}Continuous thick{p_end} +{synopt:{space 8}{opt 5}}Dot thin{p_end} +{synopt:{space 8}{opt 6}}DashDotDot thin{p_end} +{synopt:{space 8}{opt 7}}DashDotDot medium{p_end} +{synopt:{space 8}{opt 8}}DashDot thin{p_end} +{synopt:{space 8}{opt 9}}DashDot medium{p_end} +{synopt:{space 8}{opt 10}}Dash thin{p_end} +{synopt:{space 8}{opt 11}}Dash medium{p_end} +{synopt:{space 8}{opt 12}}SlantDashDot thin{p_end} +{synopt:{space 8}{opt 13}}Double thick{p_end} +{p2colreset}{...} + +{pmore} +For example, {cmd:lines(COL_NAMES 1 turn 1 LAST_ROW 13)} draws a single line under the captions (e.g., coeff +std.err), a single line under the variable {it:turn}, and draw a double line under the last raw of the table. + +{phang} {* NOLABEL *} +{opt nolabel} by default, variable labels will be displayed as row names in the output table. If {opt nolabel} is +specified, variable names will be displayed in the output table. This option is ignored when outputting matrixes. + +{phang} {* CONSTANT *} +{opt constant(string)} controls the label for the constant term. The default in Stata is {bf:_cons}, but if +specified, {it:string} will be displayed instead. + +{phang} {* RBLANKS *} +{opt rblanks(varname [text] [format], [varname [text] [format]], [...])} inserts an +empty row or text after the specified rows ({it:varname}) in the output table. For each inserted row {cmd:xml_tab} +expects variable name {it:varname} after which an empty row or text should be added, the text itself {it:text}, and +format for a new cell {it:format}. Multiple rows are separated by comma. Also see {opt format}. + +{pmore} For example, {cmd:rblanks}(turn "this text after turn" S2210, headroom "and this one below headroom") will add +vertically and horizontally centered "{cmd:this text after turn}" below data row for variable called {it:turn} (if +found) and "and this one below headroom" after variable headroom using the same format as for headroom. + +{pmore}In addition, specifying {cmd:SCOL_NAMES}, {cmd:COL_NAMES} and {cmd:LAST_ROW} instead of variable names +{cmd:xml_tab} will add a row under equation names ({cmd:SCOL_NAMES}), statistic titles (e.g., coeff. std.error) +{cmd:COL_NAMES} or under the last row of table ({cmd:LAST_ROW}). + +{phang} {* CBLANKS *} +{opt cblanks(Equations|numlist)} inserts an empty column after each column specified in the {it: numlist}. The numbering of the +numeric columns in the output table starts from 1, For example, {opt cblanks(2 4)} inserts an empty column after the second and +the fourth columns of the output table. Column with the row names is number 0. If keyword {it:Equations} (abbreviation allowed) is +used then blank column will be added after every equation (group of columns having the same column equation value). + +{phang} {* CWIDTH *} +{opt cwidth(string)} controls the column withs in Excel worksheet. {it:string} is list of paired parameters. +The first parameter specifies the column number (0 being the row names column) or keyword {it:Equations} and the second parameter +a column width. You can specify a column width of 0 to 255. This value represents the number of characters +that can be displayed in a cell that is formatted with the standard font. If the column width is set to 0, +the column is hidden. {opt cwidth} is evaluated after the {opt cblanks} option so additional blank columns +(if any) should be taken into consideration when determining column numbering. + +{phang} {* TBLANKS *} +{opt tblanks(#)} inserts {it:#} rows at the beginning of an Excel sheet. The output table shifts down by # rows. + +{phang} {* TITLE *} +{opt title(string)} specifies the title for the table. The {it:string} is inserted at the top of table. Example: + +{p 8 20 2}{cmd:.xml_tab *, title("Table 1.1")}{p_end} + +{phang} {* RNAMES CNAMES CEQ*} +{opt rnames(string)}, {opt cnames(string)} and {opt ceq(string)} modify default row/column names as well as +column equation names (super-titles) for the output matrix/estimation result. {it:string} should +contain as many words as rows/columns in the output. To specify a name containing spaces it must be included in +quotes. Table formating options {opt long}, {opt below}, {opt keep()}, {opt drop()}, {opt rblanks()} and +{opt cblanks()} will be applied before the {opt rnames()}, {opt cnames(string)} and {opt ceq(string)}. + +{phang} {* NOTES *} +{opt notes([#] line1 [, [#] line2 [, ...]])} adds one or more lines of text at the end of the table. Lines are +separated by commas. If first word (after comma) of a line specification is numeric then the note will be shifted +down by {it:#} rows, otherwise it will be written imediately after the previous output row. + +{phang} {* FONT *} +{opt font("FontName" [Fontsize])} specifies the font for the output table in a particular sheet of the workbook. The +{it:FontName} is a font name enclosed in quotes; an optional argument {it:FontSize} is the size of the font. Example: + +{p 8 20 2}{cmd:.xml_tab *, font("Arial Narrow" 12)}{p_end} + +{pmore}If no {opt font} is specified, the defualt font is used. When a new sheet is added to the existing workbook and +{opt font} is specified, that {opt font} will be applied only to the table in this new sheet. So, each sheet in the +workbook can use differnt fonts. + +{phang} {* NOGRIDLINES *} +{opt nogridlines} hides gridlines on a worksheet. The default in Excel is to display gridlines. This option affects +only the on-screen appearance, these lines are not printed. + +{phang} {* STYLE *} +{opt style(stylename)} specifies layouts and formatting for the output table from predefined list of styles. These +predefined styles are stored in the {cmd:xml_tab_options.txt}. If file is missing it will be recreated. There are +several preset styles: default, S1, S2. user-defined styles can be added to the file. If neither {cmd:style} nor +{cmd:format} was specified, the program creates output with {cmd:style(}default{cmd:)}. + +{pmore} {opt styles} in {cmd:xml_tab} are just sets of options that are written in file {it:xml_tab_options.txt} located +in the directory where {cmd:xml_tab} is installed. Each {opt style} is recorded on the separate line. You can define +your own styles by modifying file {it:xml_tab_options.txt}. The syntax for the styles consist of the style name, equal +sign, and the set of options corresponding to that particular style. To create a style, add a new line in the file +{it:xml_tab_options.txt} and define your style. For example: + +{p 8 20 2}{cmd:MYTABLES=sd right replace wide font("Arial Narrow" 12) sheet(Table 1)}{p_end} + +{pmore}You can instruct {cmd:xml_tab} to use this style by specifying: + +{p 8 20 2}{cmd:xml_tab *, style(mytables)}{p_end} + +{pmore}This command will create a table using the set of options defined in {opt style(mytables)}. In other words, the +previous command is equivalent to: + +{p 8 20 2}{cmd:xml_tab *, sd right replace wide font("Arial Narrow" 12) sheet(Table 1)}{p_end} + +{pmore}User-specified options supersede any options defined in style. You can check the complete set of options +associated with a particular style by using option {opt noisily}. + +{pmore}{help xml_tab##options:back to top} + +{* SYSTEM *} +{marker system}{...} +{dlgtab:System requirements and other options} + +{pstd} +{cmd:xml_tab} is designed for Stata Version 8.0 and later. The XML files generated by {cmd:xml_tab} could be opened +with 2003 or later versions of {it:Microsoft Excel} and {it:OpenOffice Calc 2.0} under Windows OS. It might be +possible to open XML files with {it:MS Excel 2002}. The XML format is not supported by {it:MS Excel 2000} and +earlier. + +{pstd} +We have not tested the compatibility of XML output generated by {cmd: xml_tab} with {it:OpenOffice Calc} or +{it:Microsoft Excel} running under Macintosh, UNIX, or Linux OS. We would be thankful for the comments from the +users running Stata on these platforms about any problems they encounter with using {cmd:xml_tab}. + +{pstd} +{cmd:xml_tab} will try to locate either {it:MS Excel} or {it:OO Calc} on your computer and if found, will create a +link in the results window clicking on which will automatically open the output. You can explicitly specify where should +{cmd: xml_tab} look for {it:Excel} or {it:Calc} if the programs are installed not in their default locations (you will +need to do it just once). If neither of two programs was found or Stata runs in "console" or "batch" modes, no link +will be created but {cmd:xml_tab} will still generate the output file. + +{phang} {* EXCELPATH *} +{opt ex:celpath(["]filename["])}, {opt cal:cpath(["]filename["])} tells {cmd:xml_tab} where to find Excel and/or Calc +executables, for example: + +{p 8 20 2}{cmd:.xml_tab, excelpath("D:\My programs\MS Excel\excel.exe")}{p_end} + +{p 8 20 2}{cmd:.xml_tab, calcpath("D:\My programs\OpenOffice.org\scalc.exe")}{p_end} + + +{phang} {* NOISILY *} +{opt noi:sily} displays the complete list of options applied to the table. This option could be useful whey using +{opt style} in order to see all options associated with a particular style. + +{phang} {* UPDATEOPTS *} +{opt updateopts} is used to recreate the options file. if {cmd: xml_tab_options.txt} is missing, it will be created +automatically, otherwise {cmd:updateopts} can be specified to overwrite the existing options file with the one containing +the default styles. + +{phang} {* WHICH *} +{cmd:which xml_tab} displays the version and location of {cmd:xml_tab} installed on the computer. The latest version of +the program can be installed in Stata by typing: + +{p 8 20 2}{cmd:.adoupdate xml_tab, update} + +{pmore}{help xml_tab##options:back to top} + + + +{title:Examples} + +{dlgtab:Introduction} + +{pstd} +In all our examples we use stored estimates and matrixes defined by the code below: + +{p 6 20 2}{cmd:.sysuse auto, clear}{p_end} + +{p 6 20 2}{cmd:.regress price mpg headroom trunk if foreign==0}{p_end} + +{p 6 20 2}{cmd:.estimates store reg1}{p_end} + +{p 6 20 2}{cmd:.regress price mpg headroom trunk turn if foreign==1}{p_end} + +{p 6 20 2}{cmd:.estimates store reg2, title(Only foreign cars)}{p_end} + +{p 6 20 2}{cmd:.heckman mpg weight length, sel(foreign = length displ) nolog} + +{p 6 20 2}{cmd:.estimates store heck1, title(Selection model)}{p_end} + +{pstd} +In the above code we use datafile {bf:auto.dta}. We run a regression and save the results of this regression into the +stored estimate {it:reg1}. We then run another regression with a different specification and save the results in the +estimate {it:reg2} giving this estimate a title. Then we estimate {cmd:heckman} selection model. We store the estimates +from this model to {it:heck1}. + +{dlgtab:Basic syntax} + + +{p 6 20 2}{cmd:.xml_tab reg1 reg2, replace stats(r2_a) title("price regressions by car type")}{p_end} + +{pstd} +In this example, {cmd:xml_tab} merges the estimates of two regression {it:reg1} and {it:reg2} forming a table with +five columns. The first column contains the variable names; the second column contains the estimated coefficients +from the first regression; the third column contains the standard errors for the coefficients from the first +regression; the estimated coefficients and the standard errors from the second regression are placed in the fourth and +fifth columns of the output table. + +{pstd} +In addition to the coefficients and standard errors {cmd:xml_tab} also outputs the adjusted R2 for each regression at +the bottom of the output table (option {opt stat(r2_a)}. With option {opt title("price regressions by car type")} +{cmd:xml_tab} is instructed to place a text "Price regression by car type" on the top of output table. The numerical +values in the table are formatted with a default format: both the a coefficients and the standard errors have three +decimal places, standard errors are placed to the right from the coefficients and italicized. + +{pstd} +The table is outputted into the file {it:stata_out.xml} located in the current Stata directory. + + +{phang} {* EXAMPLE BELOW TSTAT SAVE SHEET *} +{it:Extensions:} options {opt below, tstat, save, sheet} + +{p 6 20 2}{cmd:.xml_tab reg1 reg2 using "c:\my documents\table1", tstat below sheet("Table 2") stats(N r2_a)}{p_end} + +{pstd}{opt save()} saves the XML file as {it:c:\my documents\table1.xml}. The output table is placed in the sheet of +XML workbook with the name {it:Table 2}. Specifying {opt tstat} outputs the estimation coefficients and the +corresponding t-statistics. Option {opt below} places t-statistics in parenthesis under the coefficients. + +{marker exampledk}{...} +{phang} {* EXAMPLE APPEND DROP/KEEP *} +{it:Extensions:} options {opt append, drop/keep} + +{p 6 20 2}{cmd:.xml_tab heck1 using "c:\my documents\table1", pvalue right drop(length) sheet("Heckman") stats(ll)} +{cmd: append}{p_end} + +{pstd} +This command saves the estimation results from {cmd:heckman}. Option {opt append} adds a new sheet "Heckman" to XML file +used in the previous example and outputs there the estimated coefficients and p-values for the binary and continuous +parts of the ML Heckman estimation. Option {opt drop(length)} suppresses the output of the estimated coefficient for +{it:length}. {opt stats(ll)} reports log-likelihood value for the system at the bottom of the table. + +{pstd} +To suppress the output of the binary part of the ML Heckman estimation (loosely speaking to supers the output of the +first stage equation), we insert the equation name as a parameter: {bf:drop(}foreign:{bf:)}. + + +{phang} {* EXAMPLE LONG AND WIDE *} +{it:Extensions:} options {opt long and wide} + +{pstd} +By default, {cmd:xml_tab} outputs the results of multiple-equation estimations into separate columns for each equation. +For example, the table formed in the last example consists of five columns: column with the variable names, two columns +with the coefficients and p-values from the first stage equation, and two columns with the second stage equation +estimates. To output the coefficients from both equations into one column, specify option {opt long}: + +{p 6 20 2}{cmd:.xml_tab heck1 using "c:\my documents\table1", long pvalue right sheet("Heckman_long") stats(ll)} +{cmd: append}{p_end} + +{pstd} +Note that the code above will keep two previous tables saved in sheets {it:Table 1} and {it:Heckman} in the file +{it:c:\my documents\table1}. {cmd:xml_tab} will add a new sheet {it:Heckman_long} to the workbook and output the +results in long specification into this sheet. + + +{dlgtab:Print ready tables} + +{pstd} +{cmd:xml_tab} allows to create print-ready tables from within Stata. Several options control the look of the output +table. + +{pstd} +Subcategories of variables could be conveniently separated using {opt rblanks()} option. The example below inserts an +empty row after variable {it:{bf:mpg}} and puts a heading in italic into this row: + +{p 6 20 2}{cmd:.xml_tab reg1 reg2, replace stats(r2_a) rblanks(mpg "Interior Dimensions" S2220)}{p_end} + +{pstd} +To separate the results of two regressions, use option {opt cblanks()} that insert an empty column after the columns +specified as argument of this option. The code below inserts an empty column after the third column (standard errors of +the first regressions). + +{p 6 20 2}{cmd:.xml_tab reg1 reg2, replace stats(r2_a) cblanks(3)}{p_end} + +{pstd} +Option {opt line()} allows to underline rows of the table. To underline the last row of the output table with a double +line use the following syntax: + +{p 6 20 2}{cmd:.xml_tab reg1 reg2, replace stats(r2_a) line(LAST_ROW 13)}{p_end} + +{pstd} +To underline the row with coefficient {bf:mpg} with a single line and to underline the last row of the table with a +double line use: + +{p 6 20 2}{cmd:.xml_tab reg1 reg2, replace stats(r2_a) line(LAST_ROW 13 mpg 1)}{p_end} + +{marker exampleme}{...} +{dlgtab:Marginal effects} + +{pstd} +You have to use a non-standard specification in order to create tables of marginal effects, elasticities, and other +statistics generated by {helpb mfx}, {helpb dprobit}, and {helpb dlogit}. Suppose we want to generate a table of +marginal effects after {helpb heckman} estimation. + +{p 6 20 2}{cmd:.heckman mpg weight length, sel(foreign = length displ) nolog}{p_end} +{p 6 20 2}{cmd:.mfx, predict(xb)}{p_end} +{p 6 20 2}{cmd:.estimates store heck_mfx, title(Heckman marginals)}{p_end} + +{pstd} +Now, if we want to output, for example, the marginal effects from this estimation we write: + +{p 6 20 2}{cmd:.xml_tab heck_mfx(Xmfx_dydx Xmfx_se_dydx), replace}{p_end} + +{pstd} +To output the marginal effects and the standard errors after {helpb dprobit} you would specify {it:(dfdx se_dfdx)} +statistics. + +{pstd} +Note that now we specify the names of matrixes with corresponding statistics parenthesis with the name of the +stored estimates. You can check the names of the matrixes with stored statistics using {helpb ereturn list}. + +{marker matrices}{...} +{dlgtab:Exporting a matrix} + +{pstd} +{cmd:xml_tab} can also output any matrix in Stata memory. You can apply most of the options of {cmd:xml_tab} to control +the layout and the formatting of the matrix output. You can create custom tables forming the matrixes of results and +outputting them with {cmd:xml_tab}. {helpb tabstatmat} is a useful command to save various summary statistics into +matrixes. The example below outputs matrix {bf:M} with a custom format into the default XML file. + +{p 6 20 2}{cmd:.matrix M = 1, 2 \ 3, 4}{p_end} +{p 6 20 2}{cmd:.matrix M_STARS = 0, 2 \ 3, 1}{p_end} +{p 6 20 2}{cmd:.xml_tab M, format((S2210, S2100, S2100), (S2210, N2301, N2301), (S2230, N2321, N2321))}{p_end} + +{pstd}Since matrix {bf:M_STARS} exists, output table will contain significance stars based on default levels +and symbols. Thus, the output table will have a form: + + {tab}{bf:c1}{tab}{bf:c2} + r1{tab} 1.0{tab} {it:2.1}** + r2{tab} 3.0*{tab} {it:4.1}*** + + + +{pstd} +Another example demonstrates how to create and output a simple table of the means: + +{p 6 20 2}{cmd:.tabstat price mpg rep78 headroom trunk weight length, by(foreign) save}{p_end} +{p 6 20 2}{cmd:.tabstatmat A}{p_end} +{p 6 20 2}{cmd:.matrix TAB=A'}{p_end} + +{p 6 20 2}{cmd:.xml_tab TAB, replace}{p_end} + +{pstd}{cmd:tabstat} generates a table of means for the list of variables categorized by {opt foreigh}. {cmd:tabstatmat} +saves the resutls to matrix A. This matrix has tree rows for Domestic, Foreign and Total. In the columns of matrix A +are the means for the listed variables. We save the transpose matrix A into another matrix TAB. {cmd:xml_tab} ouptuts +the matrix into the default XML file. + +{pstd}You can see more examples of using {cmd:xml_tab} in {opt xml_tab_example.do}. + + +{title:Authors} + +{phang}Zurab Sajaia, zsajaia@worldbank.org + +{phang}Michael Lokshin, mlokshin@worldbank.org + +{phang}{browse econ.worldbank.org/programs/poverty/toolkit} + +{phang}Development Economics Research Group, + +{phang}The World Bank, 2006 + +{title:Acknowledgement} + +{pstd} +While the concept of {cmd:xml_tab} is original, we borrowed some functionality ideas from such programs as + {helpb estout} by Ben Jann, {helpb outreg} by John Luke Gallup, {helpb outreg2} by Roy Wada, +{helpb modltbl} by John H. Tyler, {helpb mktab} by Nicholas Winter, {helpb outtex} by Antoine Terracol, or +{helpb est2tex} by Marc Muendler. + +{title:Also see} + +{psee} +Online: {helpb xmlsave}, {helpb estimates}, {helpb matrix}, {helpb which}{p_end} diff --git a/Modules/ado/plus/x/xml_tab_options.txt b/Modules/ado/plus/x/xml_tab_options.txt new file mode 100644 index 0000000..be35164 --- /dev/null +++ b/Modules/ado/plus/x/xml_tab_options.txt @@ -0,0 +1,6 @@ + VERSION=3.26 + DEFAULT=format(S2100 (S2210 N2303)) cw(0 140) right wide stars(0.01 0.05 0.1) + S1=format(S2100 (S2210 N2303) (S2210 N2123)) cw(0 140) right wide stars(0.01 0.05 0.1) lines(COL_NAMES 1 _cons 1 LAST_ROW 13) stats(N r2) + M=format(N2103) cw(0 140) +EXCELPATH=C:/Program Files (x86)/Microsoft Office/office14/excel.exe + CALCPATH= diff --git a/Modules/ado/plus/x/xorlist.ado b/Modules/ado/plus/x/xorlist.ado new file mode 100644 index 0000000..05e72a9 --- /dev/null +++ b/Modules/ado/plus/x/xorlist.ado @@ -0,0 +1,49 @@ +program def xorlist, rclass +*! NJC 1.0.0 9 June 2000 + version 6.0 + gettoken lists 0 : 0, parse(",") + if "`lists'" == "" | "`lists'" == "," { /* no \ */ + di in r "incorrect syntax: no separator" + exit 198 + } + + tokenize "`lists'", parse("\") + if "`4'" != "" { + di in r "incorrect syntax: too much stuff" + exit 198 + } + if "`1'" == "\" { /* list1 empty */ + if "`2'" == "\" { + di in r "incorrect syntax: one \ only" + exit 198 + } + local list2 "`2'" /* might be empty */ + } + else if "`2'" == "\" { + local list1 "`1'" + local list2 "`3'" /* might be empty */ + } + else { + di in r "incorrect syntax: what to compare?" + exit 198 + } + + syntax [ , Global(str) Noisily ] + + if length("`global'") > 8 { + di in r "global name must be <=8 characters" + exit 198 + } + + bothlist `list1' \ `list2' + local inter "`r(list)'" + uniqlist `list1' `list2' + local union "`r(list)'" + difflist `union' \ `inter' + local newlist "`r(list)'" + + if "`noisily'" != "" { di "`newlist'" } + if "`global'" != "" { global `global' "`newlist'" } + return local list `newlist' +end + diff --git a/Modules/ado/plus/x/xorlist.hlp b/Modules/ado/plus/x/xorlist.hlp new file mode 100644 index 0000000..eacf780 --- /dev/null +++ b/Modules/ado/plus/x/xorlist.hlp @@ -0,0 +1,2 @@ +.h listutil + diff --git a/Modules/ado/plus/x/xpost.ado b/Modules/ado/plus/x/xpost.ado new file mode 100644 index 0000000..41c67ce --- /dev/null +++ b/Modules/ado/plus/x/xpost.ado @@ -0,0 +1,540 @@ +capture program drop xpost +program define xpost, rclass +version 6.0 + +* V1.08 Done -- 5/15/00, by Simon Cheng +* V1.08 add ologit, 5/15/00 +* V1.07 add mlogit, 5/14/00 +* V1.06 add poisson and nbreg - xpostg, 5/13/00 +* V1.05 add probit, 5/13/00 +* V1.04 add ologit, 5/11/00 +* V1.02 for logit, 5/10/00, sc +* V1.01 for logit, incomplete, 5/10/00, sc + +*Vraibles for All Models, unless specified +* di "comaand" = `cmd' +* di "y-name" = `lhsnm'" +* di "x-name" = `rhsnam'" +* di "# of x" = `rhsnum'" +* di "Cat Name" = `cnames'" +* di "# of cat" = `ncats'" +* di "# of rows" = `rown'" --- gologit only --- equal (rhsnum + 1)*(ncats - 1) +* mat "Mean of X" = `mnnoy' +* mat "std of X" = `sdnoy' +* mat "Min of X" = `minnoy' +* mat "Max of X" = `maxnoy' +* sca "Mean of Y" = `ymn' +* sca "std of Y" = `ysd' +* sca "Min of Y" = `ymin' +* sca "Max of Y" = `ymax' +* mat "b no cons" = `bnoc' -- logit probit ologit poisson nbreg-- +* mat "z no cons" = `znoc' -- logit probit ologit poisson nbreg-- +* mat "b matrix" = `b' -- gologit mlogit b matrix, with con on the top +* sca "Bconstant" = `bcon' -- logit probit poisson nbreg -- +* sca "Zconstant" = `zcon' -- logit probit poisson nbreg -- +* mat "cutpoints" = `ycut' -- ologit -- + +*Command Conditions + local cmd "`e(cmd)'" + if "`cmd'" != "logit" & "`cmd'" != "probit" & "`cmd'" != "ologit" /* + */ & "`cmd'" != "gologit" & "`cmd'" != "mlogit" /* + */ & "`cmd'" != "poisson" & "`cmd'" != "nbreg" { + di in r " -xpost- must be run after logit, probit, ologit, gologit, /* + */ mlogit, poisson, or nbreg. " + exit + } + di + di in g " -The output is generated to be directly pasted to Excel XPOST- " + +*Grab name of y + local lhsnm "`e(depvar)'" + +*Information on x + _perhs + local rhsnam "`r(rhsnms)'" + local rhsnum "`r(nrhs)'" + +*Information of categories + if "`cmd'" != "gologit" { + _pecats + local ncats = r(numcats) + local cnames = r(catnms) + di + local rfnm = r(refnm) + } + if "`cmd'" == "gologit" { + tempname gv /* gv is the v matrix of gologit */ + mat `gv' = e(V) + local rown = rowsof(`gv') + local df = e(df_m) + local ncats = `rown' - `df' + 1 + quietly ologit `lhsnm' `rhsnam' + _pecats + local cnames = r(catnms) + quietly gologit `lhsnm' `rhsnam' + } + +*Grab mean sd min max; determine var type + if "`cmd'" == "gologit" { + quietly ologit `lhsnm' `rhsnam' + } + tempname mn sd min max vtype + tempname mnnoy sdnoy minnoy maxnoy + tempname ymn ysd ymin ymax + _pesum if e(sample)==1 /*-if e(sample)==1- works when missing present"*/ + mat `mn' = r(Smean) + mat `sd' = r(Ssd) + mat `min' = r(Smin) + mat `max' = r(Smax) + _pesum if e(sample)==1, dummy /* Determine Var Type */ + mat `vtype' = r(Sdummy) + mat `mnnoy' = `mn'[1,2...] /* trim off _y */ + mat `sdnoy' = `sd'[1,2...] + mat `minnoy' = `min'[1,2...] + mat `maxnoy' = `max'[1,2...] + mat `mnnoy' = `mnnoy'' /* transpose to be a column vector */ + mat `sdnoy' = `sdnoy'' + mat `minnoy' =`minnoy'' + mat `maxnoy' =`maxnoy'' + scalar `ymn' = `mn'[1,1] + scalar `ysd' = `sd'[1,1] + scalar `ymin' = `min'[1,1] + scalar `ymax' = `max'[1,1] + if "`cmd'" == "gologit" { + quietly gologit `lhsnm' `rhsnam' + } + +*Grab b bnoc their std and compute z +* ------------------------------------- +* --logit probit ologit poisson nbreg-- +* ------------------------------------- +* | bnoc and znoc | +* ----------------- + if "`cmd'"=="logit" | "`cmd'"=="probit" | "`cmd'"=="ologit" /* + */ | "`cmd'"=="poisson" | "`cmd'"=="nbreg" { + tempname b bnoc sdb sdbnoc znoc + mat `b' = e(b) + mat `bnoc' = `b'[1,1..`rhsnum'] /* trim off _con */ + mat `bnoc'=`bnoc'' + mat `sdb' = e(V) + mat `sdb' = vecdiag(`sdb') + mat `sdbnoc' = `sdb'[1,1..`rhsnum'] /* trim off _con */ + mat `sdbnoc' = `sdbnoc'' + mat `znoc' = `bnoc' + local nbnoc = rowsof(`bnoc') + local i = 1 + while `i' <= `nbnoc' { + mat `znoc'[`i',1] = `bnoc'[`i',1] / sqrt(`sdbnoc'[`i',1]) + local i = `i' + 1 + } + } +* ------------------------------ +* --logit probit poisson nbreg-- +* ------------------------------ +* | bnoc and znoc | +* ----------------- + if "`cmd'"=="logit" | "`cmd'"=="probit" /* + */ | "`cmd'"=="poisson" | "`cmd'"=="nbreg" { + tempname bcon zcon + scalar `bcon' = `b'[1,`rhsnum'+1] + scalar `zcon' = `b'[1,`rhsnum'+1] / sqrt(`sdb'[1,`rhsnum'+1]) + } +* ------------ +* -- ologit -- +* ------------ +* | cutpoint | +* ------------ + if "`cmd'"=="ologit" { + tempname ycut + mat `ycut' = `b'[1,`rhsnum'+1..`rhsnum'+`ncats'-1] + mat `ycut' = (`ycut')' + } +* ---------------------------------------------------- +* --gologit mlogit-- get b matrix, including constant +* ---------------------------------------------------- + if "`cmd'"=="gologit" { + tempname b bmat + mat `bmat' = e(b) + local numeq = `ncats' - 1 + local eqnum = 1 + local rhsnum1 = `rhsnum' + 1 + local icount = 0 + mat `b' = J(`rhsnum1',`numeq',-999) + while `eqnum' <= `numeq' { + local varnum = 1 + while `varnum' <= `rhsnum1' { + local icount = `icount' + 1 + mat `b'[`varnum',`eqnum'] = `bmat'[1,`icount'] + local varnum = `varnum' + 1 + } /* varnum */ + local eqnum = `eqnum' + 1 + } /* eqnum loop */ + *put con on top row + mat `bmat' = `b' + mat `b' = J(`rhsnum1',`numeq',-999) + local icol = 1 + while `icol' <= `numeq' { + mat `b'[1,`icol'] = `bmat'[`rhsnum1',`icol'] + local icol = `icol' + 1 + } + local irow = 1 + while `irow' <= `rhsnum' { + local icol = 1 + while `icol' <= `numeq' { + mat `b'[`irow'+1,`icol'] = `bmat'[`irow',`icol'] + local icol = `icol' + 1 + } + local irow = `irow' + 1 + } + } + if "`cmd'" == "mlogit" { + tempname b bnoc bcon + version 5.0 + mat `b' =get(_b) + version 6.0 + mat `bnoc' = `b'[1..`ncats'-1,1..`rhsnum'] + mat `bcon' = `b'[1..`ncats'-1,`rhsnum'+1] + mat `b' = `bcon', `bnoc' + mat `b'=`b'' + } + +* Print Output +*========================= +* Table 1. Y Information +*========================= +* ALL MODELS +*============ + tempname t1 + mat `t1'=[`ymn', `ysd', `ymin', `ymax'] + mat colnames `t1' = mean std min max + mat rownames `t1' = `lhsnm' + di + di in g "---------------------------------" + di in g " Table 1: Input of Y Information " + di in g "---------------------------------" + mat list `t1', f(%5.0g) noh + if "`cmd'" == "mlogit" { + di + di "Reference Category = `rfnm'" + } +*========= +* Table 2 +*============== +* logit probit +*============== + tempname t2 + di + local i = 10 + local c1 "10" + local c2 "20" + local c3 "30" + local c4 "40" + local c5 "50" + local c6 "60" + local c7 "70" + if "`cmd'" == "logit" | "`cmd'" == "probit" { + mat `t2' = `bnoc', `znoc', `mnnoy', `sdnoy', `minnoy', `maxnoy' + di + di in g "--------------------------------" + di in g " Table 2: Input of X Information" + di in g "--------------------------------" + di + di " b z mean std min" /* + */ " max VType" + di "Constant" _col(`c1') %9.5f `bcon' _col(`c2') %8.2f `zcon' /* + */ " --- --- --- --- ---" + local i = 1 + while `i' < `rhsnum' + 1 { + local vt`i' = "C" + if `vtype'[1,`i'+1]==1 { + local vt`i' = "B" + } + local vname : word `i' of `rhsnam' + di in y %8s "`vname'" /* + */ _col(`c1') %9.5f `t2'[`i',1] /* + */ _col(`c2') %8.2f `t2'[`i',2] /* + */ _col(`c3') %9.5f `t2'[`i',3] /* + */ _col(`c4') %9.5f `t2'[`i',4] /* + */ _col(`c5') %8.2f `t2'[`i',5] /* + */ _col(`c6') %8.2f `t2'[`i',6] /* + */ _col(`c7') %5s "`vt`i''" + local i = `i' + 1 + } + } +*============ +* T2: ologit +*============ + if "`cmd'" == "ologit" { + di in g "--------------------------" + di in g " Table 2: Tau & Cat Names " + di in g "--------------------------" + di + di " A: Tau (1 to k)" + di + local i = 1 + while `i' < `ncats' { + di in y %9.5f _col(6) `ycut'[`i',1] + local i = `i' + 1 + } + di + di " B: Cat Names" + di + local i = 1 + while `i' <= `ncats' { + local vname : word `i' of `cnames' + di in y %10s "`vname'" + local i = `i' + 1 + } + } +*========================= +* T2: poissin nbreg mlogit +*========================= + if "`cmd'" == "poisson" | "`cmd'" == "nbreg" | "`cmd'" == "mlogit" { + mat `t2' = `mnnoy', `sdnoy', `minnoy', `maxnoy' + di + di in g "---------------------------------" + di in g " Table 2: Input of X Information " + di in g "---------------------------------" + di + di " mean std min max VType" + local i = 1 + while `i' < `rhsnum' + 1 { + local vt`i' = "C" + if `vtype'[1,`i'+1]==1 { + local vt`i' = "B" + } + local vname : word `i' of `rhsnam' + di in y %8s "`vname'" /* + */ _col(`c1') %9.5f `t2'[`i',1] /* + */ _col(`c2') %9.5f `t2'[`i',2] /* + */ _col(`c3') %8.2f `t2'[`i',3] /* + */ _col(`c4') %8.2f `t2'[`i',4] /* + */ _col(`c5') %5s "`vt`i''" + local i = `i' + 1 + } + di + } +*============= +* T2: gologit +*============= + if "`cmd'" == "gologit" { + di in g "--------------------" + di in g " Table 2: Cat Names " + di in g "--------------------" + di + local i = 3 + local icol = 1 + while `icol' <= `ncats' { + local vname: word `icol' of `cnames' + di %8s _col(`i') "`vname'" _c + local icol = `icol' + 1 + } + di + } +*========= +* Table 3 +*======== +* ologit +*======== + if "`cmd'" == "ologit" { + mat `t2' = `bnoc', `znoc', `mnnoy', `sdnoy', `minnoy', `maxnoy' + di + di in g "--------------------------------" + di in g " Table 3: Input of X Information" + di in g "--------------------------------" + di + di " b z mean std min" /* + */ " max VType" + local i = 1 + while `i' < `rhsnum' + 1 { + local vt`i' = "C" + if `vtype'[1,`i'+1]==1 { + local vt`i' = "B" + } + local vname : word `i' of `rhsnam' + di in y %8s "`vname'" /* + */ _col(`c1') %9.5f `t2'[`i',1] /* + */ _col(`c2') %8.2f `t2'[`i',2] /* + */ _col(`c3') %9.5f `t2'[`i',3] /* + */ _col(`c4') %9.5f `t2'[`i',4] /* + */ _col(`c5') %8.2f `t2'[`i',5] /* + */ _col(`c6') %8.2f `t2'[`i',6] /* + */ _col(`c7') %5s "`vt`i''" + local i = `i' + 1 + } + } +*============= +* T3: Poisson +*============= + if "`cmd'"=="poisson" { + tempname t3 + mat `t3' = `bnoc', `znoc' + di in g "-------------------------------" + di in g " Table 3: Poisson Coefficients " + di in g "-------------------------------" + di + di " b z" + di _col(`c1') %9.5f `bcon' _col(`c2') %9.5f `zcon' + local i = 1 + while `i' < `rhsnum' + 1 { + di in y _col(`c1') %9.5f `t3'[`i',1] /* + */ _col(`c2') %9.5f `t3'[`i',2] + local i = `i' + 1 + } + } +*============ +* T3: Mlogit +*============ + if "`cmd'" == "mlogit" { + di + di in g "-------------------------------" + di in g " Table 3: Logit Coefficients " + di in g "-------------------------------" + di + local i = 4 + local icol = 1 + while `icol' < `ncats' { + local vname: word `icol' of `cnames' + di %9s _col(`i') "`vname'" _c + local icol = `icol' + 1 + } + di + local irow = 1 + local icol = 1 + while `icol' < `ncats' { + tempname b0 + local i = 4 + scalar `b0' = `b'[1,`icol'] + di _col(`i') %9.5f `b0' _c + local icol = `icol' + 1 + local i = `i' + 4 + } + di + local irow = 1 + while `irow' < = `rhsnum' { + local icol = 1 + while `icol' < `ncats' { + local i = 4 + scalar `b0' = `b'[`irow'+1,`icol'] + di _col(`i') %9.5f `b0' _c + local icol = `icol' + 1 + local i = `i' + 4 + } + di + local irow = `irow' + 1 + } + } +*============= +* T3: gologit +*============= + if "`cmd'" == "gologit" { + tempname t3 + mat `t3' = `mnnoy', `sdnoy', `minnoy', `maxnoy' + di + di in g "---------------------------------" + di in g " Table 3: Input of X Information " + di in g "---------------------------------" + di + di " mean std min max VType" + local i = 1 + while `i' < `rhsnum' + 1 { + local vt`i' = "C" + if `vtype'[1,`i'+1]==1 { + local vt`i' = "B" + } + local vname : word `i' of `rhsnam' + di in y %8s "`vname'" /* + */ _col(`c1') %9.5f `t3'[`i',1] /* + */ _col(`c2') %9.5f `t3'[`i',2] /* + */ _col(`c3') %8.2f `t3'[`i',3] /* + */ _col(`c4') %8.2f `t3'[`i',4] /* + */ _col(`c5') %5s "`vt`i''" + local i = `i' + 1 + } + } +*=========== +* T4: Nbreg +*=========== + if "`cmd'"=="nbreg" { + tempname t4 + mat `t4' = `bnoc', `znoc' + di in g "-------------------------------" + di in g " Table 4: Nbreg Coefficients " + di in g "-------------------------------" + di + di " b z" + di _col(`c1') %9.5f `bcon' _col(`c2') %9.5f `zcon' + local i = 1 + while `i' < `rhsnum' + 1 { + di in y _col(`c1') %9.5f `t4'[`i',1] /* + */ _col(`c2') %9.5f `t4'[`i',2] + local i = `i' + 1 + } + di + di in y "Alpha = " _col(`c1') %9.5f e(alpha) + } +*============ +* T3: Mlogit +*============ + if "`cmd'" == "gologit" { + di + di in g "-------------------------------" + di in g " Table 4: Logit Coefficients " + di in g "-------------------------------" + di + local i = 4 + local icol = 1 + local j = 1 + while `icol' < `ncats' { + local eq`j' = "Equ `j'" + di %9s _col(`i') "`eq`j''" _c + local icol = `icol' + 1 + local j = `j' + 1 + } + di + local irow = 1 + local icol = 1 + while `icol' < `ncats' { + tempname b0 + local i = 4 + scalar `b0' = `b'[1,`icol'] + di _col(`i') %9.5f `b0' _c + local icol = `icol' + 1 + local i = `i' + 4 + } + di + local irow = 1 + while `irow' < = `rhsnum' { + local icol = 1 + while `icol' < `ncats' { + local i = 4 + scalar `b0' = `b'[`irow'+1,`icol'] + di _col(`i') %9.5f `b0' _c + local icol = `icol' + 1 + local i = `i' + 4 + } + di + local irow = `irow' + 1 + } + } +*===================== +* T5: Poisson & Nbreg +*===================== + di + if "`cmd'"=="poisson" | "`cmd'"=="nbreg" { + di in g "------------------------------" + di in g " Table 5: Oberved Probability " + di in g "------------------------------" + di + di in y " Counts Obs Prob" + local i=0 + version 5.0 + while `i'<`ymax'+1 { /*2*/ + quietly gen n`i'=1 if `lhsnm'==`i' + quietly recode n`i' 1=1 .=0 + quietly sum n`i' + di _col(`c1') `i' _col(`c2') %9.5f _result(3) + local i = `i' + 1 + } + } +end diff --git a/Modules/ado/plus/x/xsampsi.ado b/Modules/ado/plus/x/xsampsi.ado new file mode 100644 index 0000000..ebd5d45 --- /dev/null +++ b/Modules/ado/plus/x/xsampsi.ado @@ -0,0 +1,56 @@ +program define xsampsi +*version 1.0 Jan Brogger, Jan 31st 2002 +*This program will compute +*sample size according to senn, 1991, p. 217 + version 7.0 + syntax , alpha(real) beta(real) delta(real) stddev(real) [ n(numlist) ] + + di as text "Sample size for cross-over trial (AB/BA)" + di "according to Senn 1991: 'Cross-over trials in clinical research'" + di "Parameters below expressed in terms of the basic estimator, the treatment contrast." _n _dup(15) "-" _n + + di as text "Alpha level" _col(15) " = " as inp %4.3f `alpha' _col(25) as text "Power" _col(35) " = " as inp %4.3f (1-`beta') + local zalpha=invnorm(1-(`alpha' / 2)) + local zbeta=invnorm(1-`beta') + di as text "Zalpha " _col(15) " = " as res %4.3f `zalpha' _col(25) as text "Zbeta " _col(35) " = " as res %4.3f `zbeta' + + di _n as text "Detectable effect size" _col(35) " = " as inp %4.3f `delta' + di as text "Std.dev. of basic estimator" _col(35) " = " as inp %4.3f `stddev' + + + local napprox = ((`zalpha'+`zbeta')^2)*((`stddev'/`delta')^2) + local napprox=int(`napprox')+1 + di _n as text "Approximate N (normal) " _col(35) " = " as res %4.0f `napprox' + + local tdegfree=`napprox'-2 + local tcritical=invttail(`tdegfree',`alpha'/2) + di as text "Critical value of t(df=" as res `tdegfree' as text "," as res %4.3f `alpha'/2 as text ")" _col(35) " = " as res %4.3f `tcritical' + + local noncent = sqrt(`napprox')*(`delta'/`stddev') + di as text "Noncentrality parameter of t" _col(35) " = " as res %4.3f `noncent' + + cap nctprob `tcritical' `noncent' `tdegfree' + if _rc~=0 { + di as err "Need to install package 'nct' to compute non-central t distribution" + error 999 + } + + local power = 1-`r(p)' + di as text "Power given approximate N above " _col(35) " = " as res %4.3f `power' + + if "`n'"=="" { + di as text _n "(specify other sample sizes in paramter " as inp "n(numlist)" as text " to get power for other sample sizes)" + } + else { + di _n as text "Sample size" _col(15) "Power" + foreach sampsi of numlist `n' { local tdegfree=`sampsi'-2 + local tcritical=invttail(`tdegfree',`alpha'/2) + local noncent = sqrt(`sampsi')*(`delta'/`stddev') + + qui nctprob `tcritical' `noncent' `tdegfree' + local power = 1-`r(p)' + di as res %4.0f `sampsi' _col(15) %4.3f `power' + } + } + +end diff --git a/Modules/ado/plus/x/xsampsi.hlp b/Modules/ado/plus/x/xsampsi.hlp new file mode 100644 index 0000000..964e4e1 --- /dev/null +++ b/Modules/ado/plus/x/xsampsi.hlp @@ -0,0 +1,39 @@ +{smcl} +{* 31jan2002}{...} +{hline} +help for {hi:xsampsi} +{hline} + +{title:Sample size for AB/BA cross-over trials with continuous measures} + +This program will compute the required sample size for a simple crossover +trial, that is AB/BA, or two-period two-treatment cross-over. It will +estimate the power for a given sample size, too. + +You must specify: +alpha required significance level +beta 1-power +delta the difference between treatment arms +stddev the standard deviation of this difference + +You can specify: +n different sample sizes, for which power will be computed + +Requirements +You must install the package nct ({help nct}) for this program to work. + +Comments +This program essentially duplicates step by step the method that is +given in Stephen Senn, "Cross-over trials in clinical research", 1993, +on page 217. It is almost the same as a one-sample t-test for the +difference between treatment, except that this method uses the non-central +t-distribution, which gives you more accurate answers. + +The variables are assumed to be normally distributed. + + +See also: +{help sampsi}, {help studysi} + +Written by Jan Brogger (jan.brogger@med.uib.no) + diff --git a/Modules/ado/tĂ©lĂ©charger les mises Ă  jour SSC.do b/Modules/ado/tĂ©lĂ©charger les mises Ă  jour SSC.do new file mode 100644 index 0000000..3ed849f --- /dev/null +++ b/Modules/ado/tĂ©lĂ©charger les mises Ă  jour SSC.do @@ -0,0 +1,23 @@ +set memory 512m, perm +ssc install delta, replace +ssc install traces, replace +ssc install raschtest, replace +ssc install gammasym, replace +ssc install gausshermite, replace +ssc install mmsrm, replace +ssc install imputeitems, replace +ssc install imputerasch, replace +ssc install imputemok, replace +ssc install raschfit, replace +ssc install backrasch, replace +ssc install geekel2d, replace +ssc install loevH, replace +ssc install msp, replace +ssc install hcavar, replace +ssc install detect, replace +ssc install clv, replace +ssc install simirt, replace +ssc install genscore, replace +ssc install gengroup, replace +ssc install gllamm, replace +ssc install elapse, replace diff --git a/Modules/rosali_custom/rosali_nobf.ado b/Modules/rosali_custom/rosali_nobf.ado new file mode 100644 index 0000000..2eb8af2 --- /dev/null +++ b/Modules/rosali_custom/rosali_nobf.ado @@ -0,0 +1,1150 @@ +*! version 2.4 june2020 +*! Myriam Blanchin - Priscilla Brisson +************************************************************************************************************ +* ROSALI: RespOnse-Shift ALgorithm at Item-level +* Response-shift detection based on Rasch models family +* +* Version 1 : December 21, 2016 (Myriam Blanchin) /*rspcm122016*/ +* Version 1.1 : October 13, 2017 (Myriam Blanchin) /*option: MODA, automatic recoding of unused response categories*/ +* Version 2 : April, 2018 (Myriam Blanchin - Priscilla Brisson) /*option: GROUP, dichotomous group variable*/ +* Version 2.1 : October, 2018 (Myriam Blanchin - Priscilla Brisson) /* Version 1.1 + Version 2 */ +* Version 2.2 : February, 2019 (Priscilla Brisson) /* option nodif, optimization */ +* Version 2.3 : December, 2019 (Priscilla Brisson) /* option detail, + petites corrections */ +* Version 2.4 : June, 2020 (Myriam Blanchin) /* debug option detail + step C, modifs sorties et help */ +* +* Myriam Blanchin, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* myriam.blanchin@univ-nantes.fr +* +* Priscilla Brisson, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* priscilla.brisson@univ-nantes.fr +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define rosali_nobf, rclass + +timer clear 1 +timer on 1 + +syntax varlist(min=2 numeric) [if] [,GROUP(varlist) NODIF PRO DETail] + +preserve +version 15 +tempfile saverspcm +capture qui save `saverspcm',replace +local save1=_rc + +if "`if'"!="" { + qui keep `if' +} + +if "`pro'" != "" { + di "START" +} + +/**************************************************************************/ +set more off +set matsize 5000 +constraint drop _all + +local gp "`group'" + +tokenize `varlist' +local nbitems:word count `varlist' + + /* VĂ©rif nb d'items pair */ +local mod=mod(`nbitems',2) +if `mod'!=0 { + di as error "You must enter an even number of items : the first half of the items represents the items at time 1 and the second half the items at time 2" + error 198 + exit +} + +local nbitems=`nbitems'/2 + + +if "`group'"=="" & "`nodif'"!="" { + di as error "nodif can only be used with the group option ({hi:nodif} option). Please correct this option." + error 198 + exit +} + +local nbc: word count `group' +if `nbc' >= 2 { + di as error "Only one variable can be used for group option ({hi:group} option). Please correct this option." + error 198 + exit +} + + /* VĂ©rif qu'il y a 2 groupes si l'option groupe est choisie */ +if "`group'"!="" { + qui tab `group' + local nbgrp = r(r) + if `nbgrp' != 2 { + di as error "Only 2 groups are possible for the group option ({hi:group} option). Please correct this option." + error 420 + exit + } +} +/* recoder la variable de groupe en 0, 1*/ + +if "`group'"!="" { + qui tab `gp', matrow(rep) + qui matrix list rep + if rep[1,1]+rep[2,1] != 1 & rep[1,1]*rep[2,1] != 0 { + forvalues i=1/`=rowsof(rep)'{ + qui replace `gp'=`i'-1 if `gp'==rep[`i',1] + di "WARNING : `gp' `=rep[`i',1]' is now `gp' `=`i'-1' " + } + } + forvalues g = 0/1 { + qui tab `gp' if `gp' == `g' + local nbp_gp`g' = r(N) + } +} + + + +/*item rename*/ +/* +Items au temps 1 : 1 Ă  nbitems ``j'' +Items au temps 2 : nbitems Ă  2*nbitems ``=`j'+`nbitems''' + +Si t varie, puis num item : ``=(`t'-1)*`nbitems'+`j''' +*/ + + +local com_z = 0 // Indicatrice de recodage + /*verif modalitĂ©s rĂ©pondues*/ +if "`gp'" == "" { // Si pas d'option groupe + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'', matrow(rect1_`j') // RĂ©cupĂ©ration des infos moda du temps 1 + local minm`j'_t1 = rect1_`j'[1,1] + local maxm`j'_t1 = rect1_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''', matrow(rect2_`j') // RĂ©cupĂ©ration des infos moda du temps 2 + local minm`j'_t2 = rect2_`j'[1,1] + local maxm`j'_t2 = rect2_`j'[r(r),1] + + local minm_`j' = min(`minm`j'_t1',`minm`j'_t2') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1',`maxm`j'_t2') + local nbm_`j' = `=`maxm_`j''-`minm_`j''' + + if `minm_`j'' != 0 & `com_z' == 0 { + local com_z = 1 + } + + + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`nbm_`j'' { + qui count if ``j'' == `m' + local nb_rn1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' + local nb_rn2 = r(N) + local nb_rn = min(`nb_rn1',`nb_rn2') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' <= `minm`j'_t1' | `m' <= `minm`j'_t2' { // La moda 0 ou les moda min ne sont pas utilisĂ©es + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged " + local stop = 0 + } + } + } + else if `m' >= `maxm`j'_t1' | `m' >= `maxm`j'_t2' | `m' == `maxm_`j'' { // La (ou les) moda max ne sont pas utilisĂ©e(s) + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems''' =`=`m'-`k'' if ``=`j'+`nbitems''' ==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} +else { // Cas oĂč l'option groupe est utilisĂ©e + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'' if `gp' == 0, matrow(rect1_g0_`j') matcell(nbrt1_g0_`j') // RĂ©cupĂ©ration des infos moda du temps 1pour chaque groupe + local minm`j'_t1_g0 = rect1_g0_`j'[1,1] + local maxm`j'_t1_g0 = rect1_g0_`j'[r(r),1] + + qui tab ``j'' if `gp' == 1, matrow(rect1_g1_`j') matcell(nbrt1_g1_`j') + local minm`j'_t1_g1 = rect1_g1_`j'[1,1] + local maxm`j'_t1_g1 = rect1_g1_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''' if `gp' == 0, matrow(rect2_g0_`j') matcell(nbrt2_g0_`j') // RĂ©cupĂ©ration des infos moda du temps 2 pour chaque groupe + local minm`j'_t2_g0 = rect2_g0_`j'[1,1] + local maxm`j'_t2_g0 = rect2_g0_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''' if `gp' == 1 , matrow(rect2_g1_`j') matcell(nbrt2_g1_`j') + local minm`j'_t2_g1 = rect2_g0_`j'[1,1] + local maxm`j'_t2_g1 = rect2_g0_`j'[r(r),1] + + local minm_`j' = min(`minm`j'_t1_g0',`minm`j'_t2_g0',`minm`j'_t1_g1',`minm`j'_t2_g1') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1_g0',`maxm`j'_t2_g0',`maxm`j'_t1_g1',`maxm`j'_t2_g1') + local nbm_`j' = `=`maxm_`j''-`minm_`j''+1' + + if `minm_`j'' != 0 & `com_z' == 0 { + local com_z = 1 + } + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`=`nbm_`j''-1' { + qui count if ``j'' == `m' & `gp' == 0 + local nb_rn1_g0 = r(N) + qui count if ``j'' == `m' & `gp' == 1 + local nb_rn1_g1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 0 + local nb_rn2_g0 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 1 + local nb_rn2_g1 = r(N) + local nb_rn = min(`nb_rn1_g0',`nb_rn2_g0',`nb_rn1_g1',`nb_rn2_g1') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' < `minm`j'_t1_g0' | `m' < `minm`j'_t2_g0' | `m' < `minm`j'_t1_g1' | `m' < `minm`j'_t2_g1' { // La moda 0 n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + } + } + else if `m' == `=`nbm_`j''-1' | `m' >= `maxm`j'_t2_g0' | `m' >= `maxm`j'_t1_g1' | `m' >= `maxm`j'_t2_g1' { // La moda max n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`m'' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0 ) & `stop' != 0 { + qui replace ``j''= `=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { // Moda central non utilisĂ©e + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'-`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0{ + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} + +if `com_z' == 1 { + di + di "WARNING : Automatic recoding, the first response category is 0. see {help rosali:help rosali}." + di +} + +forvalues j =1/`nbitems' { + qui tab ``j'', matrow(rec) // RĂ©cupĂ©ration des infos moda du temps 1 + local nbm`j'_t1 = r(r) + + qui tab ``=`j'+`nbitems''' // RĂ©cupĂ©ration des infos moda du temps 2 + local nbm`j'_t2 = r(r) + + local nbm_`j' = max(`nbm`j'_t1', `nbm`j'_t2') + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`nbm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=rec[`=`r'+1',1]' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=rec[`=`r'+1',1]' + } +} + +/* Calcul de nbmoda & nbdif */ +forvalues j = 1/`nbitems' { + qui tab ``j'' + local nbmoda_`j' = r(r) + local nbdif_`j' = r(r) - 1 +} + +local maxdif = 0 +local nbmoda_sum = 0 +forvalues j = 1/`nbitems' { + if `maxdif' < `nbdif_`j'' { + local maxdif = `nbdif_`j'' + } + local nbmoda_sum = `nbmoda_sum' + `nbdif_`j'' +} + +/* Au moins 2 moda par item */ +forvalues j=1/`nbitems' { + if `nbmoda_`j'' == 1 { + di as error "``j'' have only one response category, the analysis can be performed only if each item has at least 2 response categories" + error 198 + exit + } +} + +local coln "" +forvalues j =1 /`nbitems' { + local coln "`coln' ``j''" +} + +matrix nbmod = J(2,`nbitems',.) + +matrix colnames nbmod = `coln' +matrix rownames nbmod = NbModa Recoding + +forvalues j = 1/`nbitems' { + matrix nbmod[1,`j'] = `nbmoda_`j'' + matrix nbmod[2,`j'] = `recoda_`j'' +} + +*Erreur si plus de 200 difficultĂ©s +local nb_test = 0 +forvalues j=1/`nbitems' { + local nb_test = `nb_test'+`nbmoda_`j'' -1 +} + +if `nb_test' >= 200 { + di as error "The total number of items difficulties to be estimated must be less than 200 ({hi:moda} option option)." + error 198 + exit +} + +local nbitp = 0 + +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' >= 2 { + local nbitp = `nbitp' + 1 + } +} + +qui count +local nbpat = r(N) + + +/********************************* +* AFFICHAGE INITIAL +*********************************/ +di +di _col(5) "{hline 78}" +di _col(15) "Time 1" _col(42) "Time 2" _col(65) "Nb of Answer Cat." +di _col(5) "{hline 78}" +forvalues j=1/`nbitems' { + di as text _col(15) abbrev("``j''",20) _col(42) abbrev("``=`j'+`nbitems'''",20) _col(65) `nbmoda_`j'' +} +di _col(5) "{hline 78}" +if "`group'" != "" { + di _col(10) "Nb of patients: " abbrev("`gp'",20) " 0 = `nbp_gp0' ;", abbrev("`gp'",20) " 1 = `nbp_gp1'" + di _col(5) "{hline 78}" +} +else { + di _col(10) "Nb. of patients: `nbpat'" + di _col(5) "{hline 78}" +} +di +if `nbitems' == 1 { + di as error "The analysis can only be performed with at least 2 items." + error 198 + exit +} +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' == 2 { + di "WARNING: ``j'' has only 2 response categories, no distinction can be made between uniform or non-uniform recalibration." + } + if `nbmoda_`j'' == 1 { + di as error "Only `nbmoda_`j'' response categories of item ``j'' were used by the sample, the analysis cannot be performed." + error 198 + exit + } + if `nbmoda_`j'' == 0 { + di as error "No response categories of item ``j'' were used by the sample, the analysis cannot be performed." + error 198 + exit + } +} +di +if "`group'" != "" { + di _col(2) as text "For all models : - mean of the latent trait in `gp' 0 at time 1 is constrained at 0" + di _col(19) "- equality of variances between groups" + di +} +else { + di _col(2) as text "For all models : mean of the latent trait at time 1 is constrained at 0" + di +} + + + +/********************************* +* DEFINITION DES CONTRAINTES +*********************************/ + +if "`group'"!="" { // Contraintes si option groupe + *EGALITE ENTRE GROUPES A T1 (1-200) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=0+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``j'']1.`gp' + } + } + + *DIF UNIFORME A T1 (201-400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=200+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp'=`p'*[1.``j'']1.`gp'-`p'*[1.``j'']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 0 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 1 (601-800) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=600+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp' + } + } + + * RC COMMUNE (801-1000) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=800+`maxdif'*(`j'-1)+`p'' [`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + * RC UNIFORME, groupe 0 (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp' + } + } + + * RC UNIFORME, groupe 1 (1201-1400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1200+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + *Sans interaction temps x groupe + constraint 1999 [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'=[/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' +} +else { //Contraintes si pas d'option groupe + *EGALITE ENTRE T1 et T2 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']:_cons = [`p'.``=`j'+`nbitems''']:_cons + } + } + *RC UNIFORME (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']:_cons - [1.``j'']:_cons)=[`p'.``=`j'+`nbitems''']:_cons -[`p'.``j'']:_cons + } + } +} + +/********************************* +* MATRICE DES RESULTATS +*********************************/ +matrix dif_rc=J(`nbitems',8,.) +matrix colnames dif_rc=DIFT1 DIFU RC RC_DIF RCG0 RCUG0 RCG1 RCUG1 +local rown "" + +forvalues j =1 /`nbitems' { + local rown "`rown' ``j''" +} +matrix rownames dif_rc = `rown' + +*Nb modalitĂ© max +local nbdif_max = 0 +forvalues j=1/`nbitems' { + if `nbdif_max' < `nbdif_`j'' { + local nbdif_max = `nbdif_`j'' + } +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////// PARTIE 1 : DIF A T1 ? //////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +if "`group'"!="" & "`nodif'"=="" { // PARTIE 1 = Slmt si option group & pas de "nodif" + + di _dup(49) "_ " + di + di as input "PART 1: DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES BETWEEN GROUPS AT TIME 1" + + ********************************* + ** MODEL B ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading cons) var(0: THETA@v) var(1:THETA@v) latent(THETA) nocapslatent + /* Stockage des estimations du modĂšle */ + estimates store modeldifB + matrix val_mB = r(table) + matrix esti_B = e(b) + + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mB=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + + matrix colnames delta_mB = `name_partOneC' + matrix rownames delta_mB = `name_partOneL' + matrix delta_mB_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mB_se = `name_partOneC_se' + matrix rownames delta_mB_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB=r(estimate) + local delta`j'_`p'g`g'mB_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB = r(estimate) + local delta`j'_`p'g`g'mB_se = r(se) + } + matrix delta_mB[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB' + matrix delta_mB_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB_se' + } + } + } + + matrix var_mB = (val_mB[1,"/var(THETA)#0bn.`gp'"]\val_mB[2,"/var(THETA)#0bn.`gp'"]) + + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmB=r(estimate) + local segeffmB=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmBp=r(p) + local gcmBchi=r(chi2) + local gcmBdf=r(df) + + + ********************************* + ** MODEL A ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading means) var(0: THETA@v) var(1:THETA@v) from(esti_B, skip) latent(THETA) nocapslatent + + /* Stockage des estimations du modĂšle */ + estimates store modeldifA + matrix val_mA = r(table) + matrix esti_A = e(b) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mA=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mA = `name_partOneC' + matrix rownames delta_mA = `name_partOneL' + matrix delta_mA_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mA_se = `name_partOneC_se' + matrix rownames delta_mA_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA=r(estimate) + local delta`j'_`p'g`g'mA_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA = r(estimate) + local delta`j'_`p'g`g'mA_se = r(se) + } + matrix delta_mA[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA' + matrix delta_mA_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA_se' + } + } + } + //Variance et se mA + matrix var_mA = (val_mA[1,"/var(THETA)#0bn.`gp'"]\val_mA[2,"/var(THETA)#0bn.`gp'"]) + + ********************************* + *************MODEL C************* + ********************************* + // Etape itĂ©rative si lrtest significatif + local nb_stepC = 0 + qui lrtest modeldifA modeldifB + local diftestp=r(p) + if `diftestp'<0.05{ /*If pvalue(LRtest)<0.05 then step C*/ + di + di as input "PROCESSING STEP C" + di + + /*test DIF pour chaque item*/ + local boucle = 1 + local stop = 0 + while `boucle'<=`=`nbitp'-1' & `stop'==0{ /*on s'arrĂȘte quand on a libĂ©rĂ© du DIF sur (tous les items-1) ou lorsqu'il n'y a plus de tests significatifs*/ + local nb_stepC = `boucle' + local pajust=0.05 + /*rĂ©initialisation de la matrice de test*/ + matrix test_difu_`boucle'=J(`nbitems',3,.) + matrix colnames test_difu_`boucle'=chi_DIFU df_DIFU pvalueDIFU + matrix test_dif_`boucle'=J(`nbitems',3,.) + matrix colnames test_dif_`boucle'=chi_DIF df_DIF pvalueDIF + local nbsig=0 + local minpval=1 + local itemdif=0 + if "`detail'" != ""{ + + di as text "Loop `boucle'" + di as text _col(5) "Adjusted alpha: " %6.4f `pajust' + di + di as text _col(10) "{hline 65}" + di as text _col(10) "Freed item" _col(31) "Chi-Square" _col(48) "DF" _col(57) "P-Value" + di as text _col(10) "{hline 65}" + } + /*boucle de test*/ + forvalues j=1/`nbitems'{ + //if `nbdif_`j'' > 2 { + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF dĂ©jĂ  dĂ©tectĂ© sur l'item j*/ + /*on libĂšre le DIF de l'item i: pas de contraintes*/ + forvalues k=1/`nbitems'{ /*contraintes pour les autres items (si DIF NU sur item k, pas de contraintes*/ + if `k'!=`j' & `nbmoda_`j'' >= 2 { + if dif_rc[`k',1]==. | dif_rc[`k',1]==0 {/*pas de DIF sur item k: contraintes 1-200*/ + forvalues p=1/`nbdif_`k''{ + qui local listconst "`listconst' `=0+`maxdif'*(`k'-1)+`p''" + qui constraint list `=0+`maxdif'*(`k'-1)+`p'' + } + } + else{ + if dif_rc[`k',2]!=. & dif_rc[`k',2]!= 0 & `nbmoda_`k'' > 2 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`k''{ + qui local listconst "`listconst' `=200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + } + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) latent(THETA) nocapslatent + estimates store modeldif3b`boucle'it`i' + + ************************* + *****test DIF item i***** + ************************* + qui test [1.``j'']1.`gp'=[1.``j'']0bn.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']1.`gp'=[`p'.``j'']0bn.`gp', acc + } + } + matrix test_dif_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + + /* Test DIF Uniforme */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``j'']1.`gp'-[1.``j'']0bn.`gp')=[2.``j'']1.`gp'-[2.``j'']0bn.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``j'']1.`gp'-[1.``j'']0bn.`gp')=[`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp', acc + } + matrix test_difu_`boucle'[`j',1]=(r(chi2), r(df), r(p)) + } + + if test_dif_`boucle'[`j',3]<`pajust'{/*si DIF sur item i*/ + local ++nbsig + if test_dif_`boucle'[`j',3]<`minpval'{ + local minpval=test_dif_`boucle'[`j',3] + local itemdif=`j' + } + } + if "`detail'" != "" { + di as text _col(10) abbrev("``j''",15) as result _col(31) %6.3f test_dif_`boucle'[`j',1] _col(48) test_dif_`boucle'[`j',2] _col(57) %6.4f test_dif_`boucle'[`j',3] + } + } + } + /*si nb de tests significatifs=0, on arrĂȘte*/ + if `nbsig'==0{ + local stop=1 + if `boucle' == 1 { + if "`detail'" != "" { + di as text _col(10) "{hline 65}" + di + di as result "No significant test: no difference between groups detected, no DIF detected" + di + } + } + else { + if "`detail'" != ""{ + di as text _col(10) "{hline 65}" + di + di as result "No other significant tests" + di + } + } + } + else{/*si nb de tests significatifs>0, mise Ă  jour de la matrice de rĂ©sultats*/ + matrix dif_rc[`itemdif',1]=`boucle' + if "`detail'" != ""{ + di as text _col(10) "{hline 65}" + di + di as result "Difference between groups on ``itemdif'' at time 1" + } + if `nbmoda_`itemdif'' > 2 { + if "`detail'" != "" { + + di + di %~60s as text "Test of uniform difference" + di _col(10) "{hline 40}" + di _col(10) as text "Chi-square" _col(28) "DF" _col(40) "P-value" + di _col(10) as result %4.2f `=test_difu_`boucle'[`itemdif',1]' _col(28) `=test_difu_`boucle'[`itemdif',2]' _col(40) %4.2f `=test_difu_`boucle'[`itemdif',3]' + di _col(10) as text "{hline 40}" + } + if test_difu_`boucle'[`itemdif',3]<0.05{ /*DIF NU dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=0 + di + di as result "``itemdif'' : Non-uniform differences of item difficulties between groups at T1" + di + } + else{/*DIF U dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=`boucle' + di + di as result "``itemdif'' : Uniform differences of item difficulties between groups at T1" + di + } + } + else { + // DiffĂ©rence entre groupes au temps 1 mais slmt 2 moda. donc pas de U ou NU + di _col(15) _dup(60) "-" + } + } + local ++boucle + } + } + + /* MODELE FINAL DE LA PARTIE 1. Si DIFT1 dĂ©tectĂ© (=Au moins 2 boucles dans l'Ă©tape C)*/ + if `nb_stepC' > 1 { + forvalues j=1/`nbitems'{ + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF: contraintes 1-200*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) latent(THETA) nocapslatent + /* Stockage des estimations du modĂšle */ + estimates store modeldifCFin + matrix val_mC = r(table) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mCFin=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mCFin = `name_partOneC' + matrix rownames delta_mCFin = `name_partOneL' + + matrix delta_mCFin_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + matrix colnames delta_mCFin_se = `name_partOneC_se' + matrix rownames delta_mCFin_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin=r(estimate) + local delta`j'_`p'g`g'mCFin_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin = r(estimate) + local delta`j'_`p'g`g'mCFin_se = r(se) + } + matrix delta_mCFin[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin' + matrix delta_mCFin_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin_se' + } + } + } + if "`group'" != "" { //Variance et se mA + matrix var_mC = (val_mC[1,"/var(THETA)#0bn.`gp'"]\val_mC[2,"/var(THETA)#0bn.`gp'"]) + } + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmCFin=r(estimate) + local segeffmCFin=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmCFinp=r(p) + local gcmCFinchi=r(chi2) + local gcmCFindf=r(df) + } +} + + ********************************* + *** BILAN *** + ********************************* + + if "`group'" != "" & "`nodif'" == "" { + di + di %~84s as result "SUMMARY" + di as result _col(2) "{hline 80}" + di as result _col(18) "Difference in" + di as result _col(2) "Item" _col(18) "groups at T1" _col(36) "Recalibration" _col(54) "RC " abbrev("`gp'",10) " 0" _col(72) "RC " abbrev("`gp'",10) " 1" + di as result _col(2) "{hline 80}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + local difft1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + if (dif_rc[`j',1] != . ) { + if (dif_rc[`j',2]!=0) { + local difft1 "Uniform" + } + else { + local difft1 "Non-uniform" + } + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + if dif_rc[`j',1] != . { + local difft1 " X " + } + } + di as result _col(2) abbrev("``j''",15) as text _col(18) "`difft1'" _col(36) "`RC'" _col(54) "`RCg0'" _col(72) "`RCg1'" + } + di as result _col(2) "{hline 80}" + di +} +else if "`group'" != "" & "`nodif'" != "" { + di + di %~90s as result "SUMMARY" + di as result _col(10) "{hline 70}" + di as result _col(10) "Item" _col(26) "Recalibration" _col(46) "RC `gp' 0" _col(62) "RC `gp' 1" + di _col(10) "{hline 70}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + } + di as result _col(10) "``j''" as text _col(26) "`RC'" _col(44) "`RCg0'" _col(62) "`RCg1'" + } + di as result _col(10) "{hline 70}" +} +else if "`group'" == "" { + di + di %~60s as result "SUMMARY" + di as result _col(10) "{hline 40}" + di _col(10) "Item" _col(36) "Recalibration" + di _col(10) "{hline 40}" + forvalues j=1/`nbitems' { + local RC + if dif_rc[`j',3] != . { + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RC "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RC "Non-uniform" + } + } + else { + local RC " X " + } + } + di as result _col(10) "``j''" as text _col(38) "`RC'" + } + di as result _col(10) "{hline 40}" + di +} + +matrix dif_detect = J(1,`nbitems',.) +local numdif=1 +forvalues j=1/`nbitems' { + if dif_rc[`j',1] != . { + matrix dif_detect[1,`numdif']=`j' + local numdif = `numdif'+1 + } +} +return matrix difitems = dif_detect + +capture qui use `saverspcm', clear + +end diff --git a/Modules/rosali_custom/rosali_nolrt.ado b/Modules/rosali_custom/rosali_nolrt.ado new file mode 100644 index 0000000..b2975ce --- /dev/null +++ b/Modules/rosali_custom/rosali_nolrt.ado @@ -0,0 +1,1149 @@ +*! version 2.4 june2020 +*! Myriam Blanchin - Priscilla Brisson +************************************************************************************************************ +* ROSALI: RespOnse-Shift ALgorithm at Item-level +* Response-shift detection based on Rasch models family +* +* Version 1 : December 21, 2016 (Myriam Blanchin) /*rspcm122016*/ +* Version 1.1 : October 13, 2017 (Myriam Blanchin) /*option: MODA, automatic recoding of unused response categories*/ +* Version 2 : April, 2018 (Myriam Blanchin - Priscilla Brisson) /*option: GROUP, dichotomous group variable*/ +* Version 2.1 : October, 2018 (Myriam Blanchin - Priscilla Brisson) /* Version 1.1 + Version 2 */ +* Version 2.2 : February, 2019 (Priscilla Brisson) /* option nodif, optimization */ +* Version 2.3 : December, 2019 (Priscilla Brisson) /* option detail, + petites corrections */ +* Version 2.4 : June, 2020 (Myriam Blanchin) /* debug option detail + step C, modifs sorties et help */ +* +* Myriam Blanchin, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* myriam.blanchin@univ-nantes.fr +* +* Priscilla Brisson, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* priscilla.brisson@univ-nantes.fr +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define rosali_nolrt, rclass + +timer clear 1 +timer on 1 + +syntax varlist(min=2 numeric) [if] [,GROUP(varlist) NODIF PRO DETail] + +preserve +version 15 +tempfile saverspcm +capture qui save `saverspcm',replace +local save1=_rc + +if "`if'"!="" { + qui keep `if' +} + +if "`pro'" != "" { + di "START" +} + +/**************************************************************************/ +set more off +set matsize 5000 +constraint drop _all + +local gp "`group'" + +tokenize `varlist' +local nbitems:word count `varlist' + + /* VĂ©rif nb d'items pair */ +local mod=mod(`nbitems',2) +if `mod'!=0 { + di as error "You must enter an even number of items : the first half of the items represents the items at time 1 and the second half the items at time 2" + error 198 + exit +} + +local nbitems=`nbitems'/2 + + +if "`group'"=="" & "`nodif'"!="" { + di as error "nodif can only be used with the group option ({hi:nodif} option). Please correct this option." + error 198 + exit +} + +local nbc: word count `group' +if `nbc' >= 2 { + di as error "Only one variable can be used for group option ({hi:group} option). Please correct this option." + error 198 + exit +} + + /* VĂ©rif qu'il y a 2 groupes si l'option groupe est choisie */ +if "`group'"!="" { + qui tab `group' + local nbgrp = r(r) + if `nbgrp' != 2 { + di as error "Only 2 groups are possible for the group option ({hi:group} option). Please correct this option." + error 420 + exit + } +} +/* recoder la variable de groupe en 0, 1*/ + +if "`group'"!="" { + qui tab `gp', matrow(rep) + qui matrix list rep + if rep[1,1]+rep[2,1] != 1 & rep[1,1]*rep[2,1] != 0 { + forvalues i=1/`=rowsof(rep)'{ + qui replace `gp'=`i'-1 if `gp'==rep[`i',1] + di "WARNING : `gp' `=rep[`i',1]' is now `gp' `=`i'-1' " + } + } + forvalues g = 0/1 { + qui tab `gp' if `gp' == `g' + local nbp_gp`g' = r(N) + } +} + + + +/*item rename*/ +/* +Items au temps 1 : 1 Ă  nbitems ``j'' +Items au temps 2 : nbitems Ă  2*nbitems ``=`j'+`nbitems''' + +Si t varie, puis num item : ``=(`t'-1)*`nbitems'+`j''' +*/ + + +local com_z = 0 // Indicatrice de recodage + /*verif modalitĂ©s rĂ©pondues*/ +if "`gp'" == "" { // Si pas d'option groupe + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'', matrow(rect1_`j') // RĂ©cupĂ©ration des infos moda du temps 1 + local minm`j'_t1 = rect1_`j'[1,1] + local maxm`j'_t1 = rect1_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''', matrow(rect2_`j') // RĂ©cupĂ©ration des infos moda du temps 2 + local minm`j'_t2 = rect2_`j'[1,1] + local maxm`j'_t2 = rect2_`j'[r(r),1] + + local minm_`j' = min(`minm`j'_t1',`minm`j'_t2') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1',`maxm`j'_t2') + local nbm_`j' = `=`maxm_`j''-`minm_`j''' + + if `minm_`j'' != 0 & `com_z' == 0 { + local com_z = 1 + } + + + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`nbm_`j'' { + qui count if ``j'' == `m' + local nb_rn1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' + local nb_rn2 = r(N) + local nb_rn = min(`nb_rn1',`nb_rn2') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' <= `minm`j'_t1' | `m' <= `minm`j'_t2' { // La moda 0 ou les moda min ne sont pas utilisĂ©es + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged " + local stop = 0 + } + } + } + else if `m' >= `maxm`j'_t1' | `m' >= `maxm`j'_t2' | `m' == `maxm_`j'' { // La (ou les) moda max ne sont pas utilisĂ©e(s) + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems''' =`=`m'-`k'' if ``=`j'+`nbitems''' ==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} +else { // Cas oĂč l'option groupe est utilisĂ©e + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'' if `gp' == 0, matrow(rect1_g0_`j') matcell(nbrt1_g0_`j') // RĂ©cupĂ©ration des infos moda du temps 1pour chaque groupe + local minm`j'_t1_g0 = rect1_g0_`j'[1,1] + local maxm`j'_t1_g0 = rect1_g0_`j'[r(r),1] + + qui tab ``j'' if `gp' == 1, matrow(rect1_g1_`j') matcell(nbrt1_g1_`j') + local minm`j'_t1_g1 = rect1_g1_`j'[1,1] + local maxm`j'_t1_g1 = rect1_g1_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''' if `gp' == 0, matrow(rect2_g0_`j') matcell(nbrt2_g0_`j') // RĂ©cupĂ©ration des infos moda du temps 2 pour chaque groupe + local minm`j'_t2_g0 = rect2_g0_`j'[1,1] + local maxm`j'_t2_g0 = rect2_g0_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''' if `gp' == 1 , matrow(rect2_g1_`j') matcell(nbrt2_g1_`j') + local minm`j'_t2_g1 = rect2_g0_`j'[1,1] + local maxm`j'_t2_g1 = rect2_g0_`j'[r(r),1] + + local minm_`j' = min(`minm`j'_t1_g0',`minm`j'_t2_g0',`minm`j'_t1_g1',`minm`j'_t2_g1') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1_g0',`maxm`j'_t2_g0',`maxm`j'_t1_g1',`maxm`j'_t2_g1') + local nbm_`j' = `=`maxm_`j''-`minm_`j''+1' + + if `minm_`j'' != 0 & `com_z' == 0 { + local com_z = 1 + } + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`=`nbm_`j''-1' { + qui count if ``j'' == `m' & `gp' == 0 + local nb_rn1_g0 = r(N) + qui count if ``j'' == `m' & `gp' == 1 + local nb_rn1_g1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 0 + local nb_rn2_g0 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 1 + local nb_rn2_g1 = r(N) + local nb_rn = min(`nb_rn1_g0',`nb_rn2_g0',`nb_rn1_g1',`nb_rn2_g1') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' < `minm`j'_t1_g0' | `m' < `minm`j'_t2_g0' | `m' < `minm`j'_t1_g1' | `m' < `minm`j'_t2_g1' { // La moda 0 n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + } + } + else if `m' == `=`nbm_`j''-1' | `m' >= `maxm`j'_t2_g0' | `m' >= `maxm`j'_t1_g1' | `m' >= `maxm`j'_t2_g1' { // La moda max n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`m'' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0 ) & `stop' != 0 { + qui replace ``j''= `=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { // Moda central non utilisĂ©e + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'-`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0{ + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} + +if `com_z' == 1 { + di + di "WARNING : Automatic recoding, the first response category is 0. see {help rosali:help rosali}." + di +} + +forvalues j =1/`nbitems' { + qui tab ``j'', matrow(rec) // RĂ©cupĂ©ration des infos moda du temps 1 + local nbm`j'_t1 = r(r) + + qui tab ``=`j'+`nbitems''' // RĂ©cupĂ©ration des infos moda du temps 2 + local nbm`j'_t2 = r(r) + + local nbm_`j' = max(`nbm`j'_t1', `nbm`j'_t2') + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`nbm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=rec[`=`r'+1',1]' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=rec[`=`r'+1',1]' + } +} + +/* Calcul de nbmoda & nbdif */ +forvalues j = 1/`nbitems' { + qui tab ``j'' + local nbmoda_`j' = r(r) + local nbdif_`j' = r(r) - 1 +} + +local maxdif = 0 +local nbmoda_sum = 0 +forvalues j = 1/`nbitems' { + if `maxdif' < `nbdif_`j'' { + local maxdif = `nbdif_`j'' + } + local nbmoda_sum = `nbmoda_sum' + `nbdif_`j'' +} + +/* Au moins 2 moda par item */ +forvalues j=1/`nbitems' { + if `nbmoda_`j'' == 1 { + di as error "``j'' have only one response category, the analysis can be performed only if each item has at least 2 response categories" + error 198 + exit + } +} + +local coln "" +forvalues j =1 /`nbitems' { + local coln "`coln' ``j''" +} + +matrix nbmod = J(2,`nbitems',.) + +matrix colnames nbmod = `coln' +matrix rownames nbmod = NbModa Recoding + +forvalues j = 1/`nbitems' { + matrix nbmod[1,`j'] = `nbmoda_`j'' + matrix nbmod[2,`j'] = `recoda_`j'' +} + +*Erreur si plus de 200 difficultĂ©s +local nb_test = 0 +forvalues j=1/`nbitems' { + local nb_test = `nb_test'+`nbmoda_`j'' -1 +} + +if `nb_test' >= 200 { + di as error "The total number of items difficulties to be estimated must be less than 200 ({hi:moda} option option)." + error 198 + exit +} + +local nbitp = 0 + +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' >= 2 { + local nbitp = `nbitp' + 1 + } +} + +qui count +local nbpat = r(N) + + +/********************************* +* AFFICHAGE INITIAL +*********************************/ +di +di _col(5) "{hline 78}" +di _col(15) "Time 1" _col(42) "Time 2" _col(65) "Nb of Answer Cat." +di _col(5) "{hline 78}" +forvalues j=1/`nbitems' { + di as text _col(15) abbrev("``j''",20) _col(42) abbrev("``=`j'+`nbitems'''",20) _col(65) `nbmoda_`j'' +} +di _col(5) "{hline 78}" +if "`group'" != "" { + di _col(10) "Nb of patients: " abbrev("`gp'",20) " 0 = `nbp_gp0' ;", abbrev("`gp'",20) " 1 = `nbp_gp1'" + di _col(5) "{hline 78}" +} +else { + di _col(10) "Nb. of patients: `nbpat'" + di _col(5) "{hline 78}" +} +di +if `nbitems' == 1 { + di as error "The analysis can only be performed with at least 2 items." + error 198 + exit +} +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' == 2 { + di "WARNING: ``j'' has only 2 response categories, no distinction can be made between uniform or non-uniform recalibration." + } + if `nbmoda_`j'' == 1 { + di as error "Only `nbmoda_`j'' response categories of item ``j'' were used by the sample, the analysis cannot be performed." + error 198 + exit + } + if `nbmoda_`j'' == 0 { + di as error "No response categories of item ``j'' were used by the sample, the analysis cannot be performed." + error 198 + exit + } +} +di +if "`group'" != "" { + di _col(2) as text "For all models : - mean of the latent trait in `gp' 0 at time 1 is constrained at 0" + di _col(19) "- equality of variances between groups" + di +} +else { + di _col(2) as text "For all models : mean of the latent trait at time 1 is constrained at 0" + di +} + + + +/********************************* +* DEFINITION DES CONTRAINTES +*********************************/ + +if "`group'"!="" { // Contraintes si option groupe + *EGALITE ENTRE GROUPES A T1 (1-200) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=0+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``j'']1.`gp' + } + } + + *DIF UNIFORME A T1 (201-400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=200+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp'=`p'*[1.``j'']1.`gp'-`p'*[1.``j'']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 0 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 1 (601-800) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=600+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp' + } + } + + * RC COMMUNE (801-1000) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=800+`maxdif'*(`j'-1)+`p'' [`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + * RC UNIFORME, groupe 0 (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp' + } + } + + * RC UNIFORME, groupe 1 (1201-1400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1200+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + *Sans interaction temps x groupe + constraint 1999 [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'=[/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' +} +else { //Contraintes si pas d'option groupe + *EGALITE ENTRE T1 et T2 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']:_cons = [`p'.``=`j'+`nbitems''']:_cons + } + } + *RC UNIFORME (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']:_cons - [1.``j'']:_cons)=[`p'.``=`j'+`nbitems''']:_cons -[`p'.``j'']:_cons + } + } +} + +/********************************* +* MATRICE DES RESULTATS +*********************************/ +matrix dif_rc=J(`nbitems',8,.) +matrix colnames dif_rc=DIFT1 DIFU RC RC_DIF RCG0 RCUG0 RCG1 RCUG1 +local rown "" + +forvalues j =1 /`nbitems' { + local rown "`rown' ``j''" +} +matrix rownames dif_rc = `rown' + +*Nb modalitĂ© max +local nbdif_max = 0 +forvalues j=1/`nbitems' { + if `nbdif_max' < `nbdif_`j'' { + local nbdif_max = `nbdif_`j'' + } +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////// PARTIE 1 : DIF A T1 ? //////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +if "`group'"!="" & "`nodif'"=="" { // PARTIE 1 = Slmt si option group & pas de "nodif" + + di _dup(49) "_ " + di + di as input "PART 1: DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES BETWEEN GROUPS AT TIME 1" + + ********************************* + ** MODEL B ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading cons) var(0: THETA@v) var(1:THETA@v) latent(THETA) nocapslatent + /* Stockage des estimations du modĂšle */ + estimates store modeldifB + matrix val_mB = r(table) + matrix esti_B = e(b) + + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mB=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + + matrix colnames delta_mB = `name_partOneC' + matrix rownames delta_mB = `name_partOneL' + matrix delta_mB_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mB_se = `name_partOneC_se' + matrix rownames delta_mB_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB=r(estimate) + local delta`j'_`p'g`g'mB_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB = r(estimate) + local delta`j'_`p'g`g'mB_se = r(se) + } + matrix delta_mB[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB' + matrix delta_mB_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB_se' + } + } + } + + matrix var_mB = (val_mB[1,"/var(THETA)#0bn.`gp'"]\val_mB[2,"/var(THETA)#0bn.`gp'"]) + + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmB=r(estimate) + local segeffmB=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmBp=r(p) + local gcmBchi=r(chi2) + local gcmBdf=r(df) + + + ********************************* + ** MODEL A ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading means) var(0: THETA@v) var(1:THETA@v) from(esti_B, skip) latent(THETA) nocapslatent + + /* Stockage des estimations du modĂšle */ + estimates store modeldifA + matrix val_mA = r(table) + matrix esti_A = e(b) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mA=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mA = `name_partOneC' + matrix rownames delta_mA = `name_partOneL' + matrix delta_mA_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mA_se = `name_partOneC_se' + matrix rownames delta_mA_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA=r(estimate) + local delta`j'_`p'g`g'mA_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA = r(estimate) + local delta`j'_`p'g`g'mA_se = r(se) + } + matrix delta_mA[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA' + matrix delta_mA_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA_se' + } + } + } + //Variance et se mA + matrix var_mA = (val_mA[1,"/var(THETA)#0bn.`gp'"]\val_mA[2,"/var(THETA)#0bn.`gp'"]) + + ********************************* + *************MODEL C************* + ********************************* + // Etape itĂ©rative si lrtest significatif + local nb_stepC = 0 + local diftestp = 1 + if `diftestp'<2{ /*If pvalue(LRtest)<0.05 then step C*/ + di + di as input "PROCESSING STEP C" + di + + /*test DIF pour chaque item*/ + local boucle = 1 + local stop = 0 + while `boucle'<=`=`nbitp'-1' & `stop'==0{ /*on s'arrĂȘte quand on a libĂ©rĂ© du DIF sur (tous les items-1) ou lorsqu'il n'y a plus de tests significatifs*/ + local nb_stepC = `boucle' + local pajust=0.05/`=`nbitp'+1-`boucle'' + /*rĂ©initialisation de la matrice de test*/ + matrix test_difu_`boucle'=J(`nbitems',3,.) + matrix colnames test_difu_`boucle'=chi_DIFU df_DIFU pvalueDIFU + matrix test_dif_`boucle'=J(`nbitems',3,.) + matrix colnames test_dif_`boucle'=chi_DIF df_DIF pvalueDIF + local nbsig=0 + local minpval=1 + local itemdif=0 + if "`detail'" != ""{ + + di as text "Loop `boucle'" + di as text _col(5) "Adjusted alpha: " %6.4f `pajust' + di + di as text _col(10) "{hline 65}" + di as text _col(10) "Freed item" _col(31) "Chi-Square" _col(48) "DF" _col(57) "P-Value" + di as text _col(10) "{hline 65}" + } + /*boucle de test*/ + forvalues j=1/`nbitems'{ + //if `nbdif_`j'' > 2 { + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF dĂ©jĂ  dĂ©tectĂ© sur l'item j*/ + /*on libĂšre le DIF de l'item i: pas de contraintes*/ + forvalues k=1/`nbitems'{ /*contraintes pour les autres items (si DIF NU sur item k, pas de contraintes*/ + if `k'!=`j' & `nbmoda_`j'' >= 2 { + if dif_rc[`k',1]==. | dif_rc[`k',1]==0 {/*pas de DIF sur item k: contraintes 1-200*/ + forvalues p=1/`nbdif_`k''{ + qui local listconst "`listconst' `=0+`maxdif'*(`k'-1)+`p''" + qui constraint list `=0+`maxdif'*(`k'-1)+`p'' + } + } + else{ + if dif_rc[`k',2]!=. & dif_rc[`k',2]!= 0 & `nbmoda_`k'' > 2 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`k''{ + qui local listconst "`listconst' `=200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + } + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) latent(THETA) nocapslatent + estimates store modeldif3b`boucle'it`i' + + ************************* + *****test DIF item i***** + ************************* + qui test [1.``j'']1.`gp'=[1.``j'']0bn.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']1.`gp'=[`p'.``j'']0bn.`gp', acc + } + } + matrix test_dif_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + + /* Test DIF Uniforme */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``j'']1.`gp'-[1.``j'']0bn.`gp')=[2.``j'']1.`gp'-[2.``j'']0bn.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``j'']1.`gp'-[1.``j'']0bn.`gp')=[`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp', acc + } + matrix test_difu_`boucle'[`j',1]=(r(chi2), r(df), r(p)) + } + + if test_dif_`boucle'[`j',3]<`pajust'{/*si DIF sur item i*/ + local ++nbsig + if test_dif_`boucle'[`j',3]<`minpval'{ + local minpval=test_dif_`boucle'[`j',3] + local itemdif=`j' + } + } + if "`detail'" != "" { + di as text _col(10) abbrev("``j''",15) as result _col(31) %6.3f test_dif_`boucle'[`j',1] _col(48) test_dif_`boucle'[`j',2] _col(57) %6.4f test_dif_`boucle'[`j',3] + } + } + } + /*si nb de tests significatifs=0, on arrĂȘte*/ + if `nbsig'==0{ + local stop=1 + if `boucle' == 1 { + if "`detail'" != "" { + di as text _col(10) "{hline 65}" + di + di as result "No significant test: no difference between groups detected, no DIF detected" + di + } + } + else { + if "`detail'" != ""{ + di as text _col(10) "{hline 65}" + di + di as result "No other significant tests" + di + } + } + } + else{/*si nb de tests significatifs>0, mise Ă  jour de la matrice de rĂ©sultats*/ + matrix dif_rc[`itemdif',1]=`boucle' + if "`detail'" != ""{ + di as text _col(10) "{hline 65}" + di + di as result "Difference between groups on ``itemdif'' at time 1" + } + if `nbmoda_`itemdif'' > 2 { + if "`detail'" != "" { + + di + di %~60s as text "Test of uniform difference" + di _col(10) "{hline 40}" + di _col(10) as text "Chi-square" _col(28) "DF" _col(40) "P-value" + di _col(10) as result %4.2f `=test_difu_`boucle'[`itemdif',1]' _col(28) `=test_difu_`boucle'[`itemdif',2]' _col(40) %4.2f `=test_difu_`boucle'[`itemdif',3]' + di _col(10) as text "{hline 40}" + } + if test_difu_`boucle'[`itemdif',3]<0.05{ /*DIF NU dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=0 + di + di as result "``itemdif'' : Non-uniform differences of item difficulties between groups at T1" + di + } + else{/*DIF U dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=`boucle' + di + di as result "``itemdif'' : Uniform differences of item difficulties between groups at T1" + di + } + } + else { + // DiffĂ©rence entre groupes au temps 1 mais slmt 2 moda. donc pas de U ou NU + di _col(15) _dup(60) "-" + } + } + local ++boucle + } + } + + /* MODELE FINAL DE LA PARTIE 1. Si DIFT1 dĂ©tectĂ© (=Au moins 2 boucles dans l'Ă©tape C)*/ + if `nb_stepC' > 1 { + forvalues j=1/`nbitems'{ + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF: contraintes 1-200*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) latent(THETA) nocapslatent + /* Stockage des estimations du modĂšle */ + estimates store modeldifCFin + matrix val_mC = r(table) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mCFin=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mCFin = `name_partOneC' + matrix rownames delta_mCFin = `name_partOneL' + + matrix delta_mCFin_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + matrix colnames delta_mCFin_se = `name_partOneC_se' + matrix rownames delta_mCFin_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin=r(estimate) + local delta`j'_`p'g`g'mCFin_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin = r(estimate) + local delta`j'_`p'g`g'mCFin_se = r(se) + } + matrix delta_mCFin[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin' + matrix delta_mCFin_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin_se' + } + } + } + if "`group'" != "" { //Variance et se mA + matrix var_mC = (val_mC[1,"/var(THETA)#0bn.`gp'"]\val_mC[2,"/var(THETA)#0bn.`gp'"]) + } + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmCFin=r(estimate) + local segeffmCFin=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmCFinp=r(p) + local gcmCFinchi=r(chi2) + local gcmCFindf=r(df) + } +} + + ********************************* + *** BILAN *** + ********************************* + + if "`group'" != "" & "`nodif'" == "" { + di + di %~84s as result "SUMMARY" + di as result _col(2) "{hline 80}" + di as result _col(18) "Difference in" + di as result _col(2) "Item" _col(18) "groups at T1" _col(36) "Recalibration" _col(54) "RC " abbrev("`gp'",10) " 0" _col(72) "RC " abbrev("`gp'",10) " 1" + di as result _col(2) "{hline 80}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + local difft1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + if (dif_rc[`j',1] != . ) { + if (dif_rc[`j',2]!=0) { + local difft1 "Uniform" + } + else { + local difft1 "Non-uniform" + } + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + if dif_rc[`j',1] != . { + local difft1 " X " + } + } + di as result _col(2) abbrev("``j''",15) as text _col(18) "`difft1'" _col(36) "`RC'" _col(54) "`RCg0'" _col(72) "`RCg1'" + } + di as result _col(2) "{hline 80}" + di +} +else if "`group'" != "" & "`nodif'" != "" { + di + di %~90s as result "SUMMARY" + di as result _col(10) "{hline 70}" + di as result _col(10) "Item" _col(26) "Recalibration" _col(46) "RC `gp' 0" _col(62) "RC `gp' 1" + di _col(10) "{hline 70}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + } + di as result _col(10) "``j''" as text _col(26) "`RC'" _col(44) "`RCg0'" _col(62) "`RCg1'" + } + di as result _col(10) "{hline 70}" +} +else if "`group'" == "" { + di + di %~60s as result "SUMMARY" + di as result _col(10) "{hline 40}" + di _col(10) "Item" _col(36) "Recalibration" + di _col(10) "{hline 40}" + forvalues j=1/`nbitems' { + local RC + if dif_rc[`j',3] != . { + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RC "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RC "Non-uniform" + } + } + else { + local RC " X " + } + } + di as result _col(10) "``j''" as text _col(38) "`RC'" + } + di as result _col(10) "{hline 40}" + di +} + +matrix dif_detect = J(1,`nbitems',.) +local numdif=1 +forvalues j=1/`nbitems' { + if dif_rc[`j',1] != . { + matrix dif_detect[1,`numdif']=`j' + local numdif = `numdif'+1 + } +} +return matrix difitems = dif_detect + +capture qui use `saverspcm', clear + +end diff --git a/Modules/rosali_custom/rosali_nolrt_nobf.ado b/Modules/rosali_custom/rosali_nolrt_nobf.ado new file mode 100644 index 0000000..8f273aa --- /dev/null +++ b/Modules/rosali_custom/rosali_nolrt_nobf.ado @@ -0,0 +1,1149 @@ +*! version 2.4 june2020 +*! Myriam Blanchin - Priscilla Brisson +************************************************************************************************************ +* ROSALI: RespOnse-Shift ALgorithm at Item-level +* Response-shift detection based on Rasch models family +* +* Version 1 : December 21, 2016 (Myriam Blanchin) /*rspcm122016*/ +* Version 1.1 : October 13, 2017 (Myriam Blanchin) /*option: MODA, automatic recoding of unused response categories*/ +* Version 2 : April, 2018 (Myriam Blanchin - Priscilla Brisson) /*option: GROUP, dichotomous group variable*/ +* Version 2.1 : October, 2018 (Myriam Blanchin - Priscilla Brisson) /* Version 1.1 + Version 2 */ +* Version 2.2 : February, 2019 (Priscilla Brisson) /* option nodif, optimization */ +* Version 2.3 : December, 2019 (Priscilla Brisson) /* option detail, + petites corrections */ +* Version 2.4 : June, 2020 (Myriam Blanchin) /* debug option detail + step C, modifs sorties et help */ +* +* Myriam Blanchin, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* myriam.blanchin@univ-nantes.fr +* +* Priscilla Brisson, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* priscilla.brisson@univ-nantes.fr +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define rosali_nolrt_nobf, rclass + +timer clear 1 +timer on 1 + +syntax varlist(min=2 numeric) [if] [,GROUP(varlist) NODIF PRO DETail] + +preserve +version 15 +tempfile saverspcm +capture qui save `saverspcm',replace +local save1=_rc + +if "`if'"!="" { + qui keep `if' +} + +if "`pro'" != "" { + di "START" +} + +/**************************************************************************/ +set more off +set matsize 5000 +constraint drop _all + +local gp "`group'" + +tokenize `varlist' +local nbitems:word count `varlist' + + /* VĂ©rif nb d'items pair */ +local mod=mod(`nbitems',2) +if `mod'!=0 { + di as error "You must enter an even number of items : the first half of the items represents the items at time 1 and the second half the items at time 2" + error 198 + exit +} + +local nbitems=`nbitems'/2 + + +if "`group'"=="" & "`nodif'"!="" { + di as error "nodif can only be used with the group option ({hi:nodif} option). Please correct this option." + error 198 + exit +} + +local nbc: word count `group' +if `nbc' >= 2 { + di as error "Only one variable can be used for group option ({hi:group} option). Please correct this option." + error 198 + exit +} + + /* VĂ©rif qu'il y a 2 groupes si l'option groupe est choisie */ +if "`group'"!="" { + qui tab `group' + local nbgrp = r(r) + if `nbgrp' != 2 { + di as error "Only 2 groups are possible for the group option ({hi:group} option). Please correct this option." + error 420 + exit + } +} +/* recoder la variable de groupe en 0, 1*/ + +if "`group'"!="" { + qui tab `gp', matrow(rep) + qui matrix list rep + if rep[1,1]+rep[2,1] != 1 & rep[1,1]*rep[2,1] != 0 { + forvalues i=1/`=rowsof(rep)'{ + qui replace `gp'=`i'-1 if `gp'==rep[`i',1] + di "WARNING : `gp' `=rep[`i',1]' is now `gp' `=`i'-1' " + } + } + forvalues g = 0/1 { + qui tab `gp' if `gp' == `g' + local nbp_gp`g' = r(N) + } +} + + + +/*item rename*/ +/* +Items au temps 1 : 1 Ă  nbitems ``j'' +Items au temps 2 : nbitems Ă  2*nbitems ``=`j'+`nbitems''' + +Si t varie, puis num item : ``=(`t'-1)*`nbitems'+`j''' +*/ + + +local com_z = 0 // Indicatrice de recodage + /*verif modalitĂ©s rĂ©pondues*/ +if "`gp'" == "" { // Si pas d'option groupe + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'', matrow(rect1_`j') // RĂ©cupĂ©ration des infos moda du temps 1 + local minm`j'_t1 = rect1_`j'[1,1] + local maxm`j'_t1 = rect1_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''', matrow(rect2_`j') // RĂ©cupĂ©ration des infos moda du temps 2 + local minm`j'_t2 = rect2_`j'[1,1] + local maxm`j'_t2 = rect2_`j'[r(r),1] + + local minm_`j' = min(`minm`j'_t1',`minm`j'_t2') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1',`maxm`j'_t2') + local nbm_`j' = `=`maxm_`j''-`minm_`j''' + + if `minm_`j'' != 0 & `com_z' == 0 { + local com_z = 1 + } + + + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`nbm_`j'' { + qui count if ``j'' == `m' + local nb_rn1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' + local nb_rn2 = r(N) + local nb_rn = min(`nb_rn1',`nb_rn2') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' <= `minm`j'_t1' | `m' <= `minm`j'_t2' { // La moda 0 ou les moda min ne sont pas utilisĂ©es + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged " + local stop = 0 + } + } + } + else if `m' >= `maxm`j'_t1' | `m' >= `maxm`j'_t2' | `m' == `maxm_`j'' { // La (ou les) moda max ne sont pas utilisĂ©e(s) + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems''' =`=`m'-`k'' if ``=`j'+`nbitems''' ==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} +else { // Cas oĂč l'option groupe est utilisĂ©e + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'' if `gp' == 0, matrow(rect1_g0_`j') matcell(nbrt1_g0_`j') // RĂ©cupĂ©ration des infos moda du temps 1pour chaque groupe + local minm`j'_t1_g0 = rect1_g0_`j'[1,1] + local maxm`j'_t1_g0 = rect1_g0_`j'[r(r),1] + + qui tab ``j'' if `gp' == 1, matrow(rect1_g1_`j') matcell(nbrt1_g1_`j') + local minm`j'_t1_g1 = rect1_g1_`j'[1,1] + local maxm`j'_t1_g1 = rect1_g1_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''' if `gp' == 0, matrow(rect2_g0_`j') matcell(nbrt2_g0_`j') // RĂ©cupĂ©ration des infos moda du temps 2 pour chaque groupe + local minm`j'_t2_g0 = rect2_g0_`j'[1,1] + local maxm`j'_t2_g0 = rect2_g0_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''' if `gp' == 1 , matrow(rect2_g1_`j') matcell(nbrt2_g1_`j') + local minm`j'_t2_g1 = rect2_g0_`j'[1,1] + local maxm`j'_t2_g1 = rect2_g0_`j'[r(r),1] + + local minm_`j' = min(`minm`j'_t1_g0',`minm`j'_t2_g0',`minm`j'_t1_g1',`minm`j'_t2_g1') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1_g0',`maxm`j'_t2_g0',`maxm`j'_t1_g1',`maxm`j'_t2_g1') + local nbm_`j' = `=`maxm_`j''-`minm_`j''+1' + + if `minm_`j'' != 0 & `com_z' == 0 { + local com_z = 1 + } + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`=`nbm_`j''-1' { + qui count if ``j'' == `m' & `gp' == 0 + local nb_rn1_g0 = r(N) + qui count if ``j'' == `m' & `gp' == 1 + local nb_rn1_g1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 0 + local nb_rn2_g0 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 1 + local nb_rn2_g1 = r(N) + local nb_rn = min(`nb_rn1_g0',`nb_rn2_g0',`nb_rn1_g1',`nb_rn2_g1') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' < `minm`j'_t1_g0' | `m' < `minm`j'_t2_g0' | `m' < `minm`j'_t1_g1' | `m' < `minm`j'_t2_g1' { // La moda 0 n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + } + } + else if `m' == `=`nbm_`j''-1' | `m' >= `maxm`j'_t2_g0' | `m' >= `maxm`j'_t1_g1' | `m' >= `maxm`j'_t2_g1' { // La moda max n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`m'' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0 ) & `stop' != 0 { + qui replace ``j''= `=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { // Moda central non utilisĂ©e + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'-`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0{ + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} + +if `com_z' == 1 { + di + di "WARNING : Automatic recoding, the first response category is 0. see {help rosali:help rosali}." + di +} + +forvalues j =1/`nbitems' { + qui tab ``j'', matrow(rec) // RĂ©cupĂ©ration des infos moda du temps 1 + local nbm`j'_t1 = r(r) + + qui tab ``=`j'+`nbitems''' // RĂ©cupĂ©ration des infos moda du temps 2 + local nbm`j'_t2 = r(r) + + local nbm_`j' = max(`nbm`j'_t1', `nbm`j'_t2') + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`nbm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=rec[`=`r'+1',1]' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=rec[`=`r'+1',1]' + } +} + +/* Calcul de nbmoda & nbdif */ +forvalues j = 1/`nbitems' { + qui tab ``j'' + local nbmoda_`j' = r(r) + local nbdif_`j' = r(r) - 1 +} + +local maxdif = 0 +local nbmoda_sum = 0 +forvalues j = 1/`nbitems' { + if `maxdif' < `nbdif_`j'' { + local maxdif = `nbdif_`j'' + } + local nbmoda_sum = `nbmoda_sum' + `nbdif_`j'' +} + +/* Au moins 2 moda par item */ +forvalues j=1/`nbitems' { + if `nbmoda_`j'' == 1 { + di as error "``j'' have only one response category, the analysis can be performed only if each item has at least 2 response categories" + error 198 + exit + } +} + +local coln "" +forvalues j =1 /`nbitems' { + local coln "`coln' ``j''" +} + +matrix nbmod = J(2,`nbitems',.) + +matrix colnames nbmod = `coln' +matrix rownames nbmod = NbModa Recoding + +forvalues j = 1/`nbitems' { + matrix nbmod[1,`j'] = `nbmoda_`j'' + matrix nbmod[2,`j'] = `recoda_`j'' +} + +*Erreur si plus de 200 difficultĂ©s +local nb_test = 0 +forvalues j=1/`nbitems' { + local nb_test = `nb_test'+`nbmoda_`j'' -1 +} + +if `nb_test' >= 200 { + di as error "The total number of items difficulties to be estimated must be less than 200 ({hi:moda} option option)." + error 198 + exit +} + +local nbitp = 0 + +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' >= 2 { + local nbitp = `nbitp' + 1 + } +} + +qui count +local nbpat = r(N) + + +/********************************* +* AFFICHAGE INITIAL +*********************************/ +di +di _col(5) "{hline 78}" +di _col(15) "Time 1" _col(42) "Time 2" _col(65) "Nb of Answer Cat." +di _col(5) "{hline 78}" +forvalues j=1/`nbitems' { + di as text _col(15) abbrev("``j''",20) _col(42) abbrev("``=`j'+`nbitems'''",20) _col(65) `nbmoda_`j'' +} +di _col(5) "{hline 78}" +if "`group'" != "" { + di _col(10) "Nb of patients: " abbrev("`gp'",20) " 0 = `nbp_gp0' ;", abbrev("`gp'",20) " 1 = `nbp_gp1'" + di _col(5) "{hline 78}" +} +else { + di _col(10) "Nb. of patients: `nbpat'" + di _col(5) "{hline 78}" +} +di +if `nbitems' == 1 { + di as error "The analysis can only be performed with at least 2 items." + error 198 + exit +} +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' == 2 { + di "WARNING: ``j'' has only 2 response categories, no distinction can be made between uniform or non-uniform recalibration." + } + if `nbmoda_`j'' == 1 { + di as error "Only `nbmoda_`j'' response categories of item ``j'' were used by the sample, the analysis cannot be performed." + error 198 + exit + } + if `nbmoda_`j'' == 0 { + di as error "No response categories of item ``j'' were used by the sample, the analysis cannot be performed." + error 198 + exit + } +} +di +if "`group'" != "" { + di _col(2) as text "For all models : - mean of the latent trait in `gp' 0 at time 1 is constrained at 0" + di _col(19) "- equality of variances between groups" + di +} +else { + di _col(2) as text "For all models : mean of the latent trait at time 1 is constrained at 0" + di +} + + + +/********************************* +* DEFINITION DES CONTRAINTES +*********************************/ + +if "`group'"!="" { // Contraintes si option groupe + *EGALITE ENTRE GROUPES A T1 (1-200) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=0+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``j'']1.`gp' + } + } + + *DIF UNIFORME A T1 (201-400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=200+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp'=`p'*[1.``j'']1.`gp'-`p'*[1.``j'']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 0 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 1 (601-800) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=600+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp' + } + } + + * RC COMMUNE (801-1000) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=800+`maxdif'*(`j'-1)+`p'' [`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + * RC UNIFORME, groupe 0 (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp' + } + } + + * RC UNIFORME, groupe 1 (1201-1400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1200+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + *Sans interaction temps x groupe + constraint 1999 [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'=[/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' +} +else { //Contraintes si pas d'option groupe + *EGALITE ENTRE T1 et T2 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']:_cons = [`p'.``=`j'+`nbitems''']:_cons + } + } + *RC UNIFORME (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']:_cons - [1.``j'']:_cons)=[`p'.``=`j'+`nbitems''']:_cons -[`p'.``j'']:_cons + } + } +} + +/********************************* +* MATRICE DES RESULTATS +*********************************/ +matrix dif_rc=J(`nbitems',8,.) +matrix colnames dif_rc=DIFT1 DIFU RC RC_DIF RCG0 RCUG0 RCG1 RCUG1 +local rown "" + +forvalues j =1 /`nbitems' { + local rown "`rown' ``j''" +} +matrix rownames dif_rc = `rown' + +*Nb modalitĂ© max +local nbdif_max = 0 +forvalues j=1/`nbitems' { + if `nbdif_max' < `nbdif_`j'' { + local nbdif_max = `nbdif_`j'' + } +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////// PARTIE 1 : DIF A T1 ? //////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +if "`group'"!="" & "`nodif'"=="" { // PARTIE 1 = Slmt si option group & pas de "nodif" + + di _dup(49) "_ " + di + di as input "PART 1: DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES BETWEEN GROUPS AT TIME 1" + + ********************************* + ** MODEL B ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading cons) var(0: THETA@v) var(1:THETA@v) latent(THETA) nocapslatent + /* Stockage des estimations du modĂšle */ + estimates store modeldifB + matrix val_mB = r(table) + matrix esti_B = e(b) + + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mB=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + + matrix colnames delta_mB = `name_partOneC' + matrix rownames delta_mB = `name_partOneL' + matrix delta_mB_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mB_se = `name_partOneC_se' + matrix rownames delta_mB_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB=r(estimate) + local delta`j'_`p'g`g'mB_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB = r(estimate) + local delta`j'_`p'g`g'mB_se = r(se) + } + matrix delta_mB[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB' + matrix delta_mB_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB_se' + } + } + } + + matrix var_mB = (val_mB[1,"/var(THETA)#0bn.`gp'"]\val_mB[2,"/var(THETA)#0bn.`gp'"]) + + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmB=r(estimate) + local segeffmB=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmBp=r(p) + local gcmBchi=r(chi2) + local gcmBdf=r(df) + + + ********************************* + ** MODEL A ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading means) var(0: THETA@v) var(1:THETA@v) from(esti_B, skip) latent(THETA) nocapslatent + + /* Stockage des estimations du modĂšle */ + estimates store modeldifA + matrix val_mA = r(table) + matrix esti_A = e(b) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mA=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mA = `name_partOneC' + matrix rownames delta_mA = `name_partOneL' + matrix delta_mA_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mA_se = `name_partOneC_se' + matrix rownames delta_mA_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA=r(estimate) + local delta`j'_`p'g`g'mA_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA = r(estimate) + local delta`j'_`p'g`g'mA_se = r(se) + } + matrix delta_mA[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA' + matrix delta_mA_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA_se' + } + } + } + //Variance et se mA + matrix var_mA = (val_mA[1,"/var(THETA)#0bn.`gp'"]\val_mA[2,"/var(THETA)#0bn.`gp'"]) + + ********************************* + *************MODEL C************* + ********************************* + // Etape itĂ©rative si lrtest significatif + local nb_stepC = 0 + local diftestp = 1 + if `diftestp'<2{ /*If pvalue(LRtest)<0.05 then step C*/ + di + di as input "PROCESSING STEP C" + di + + /*test DIF pour chaque item*/ + local boucle = 1 + local stop = 0 + while `boucle'<=`=`nbitp'-1' & `stop'==0{ /*on s'arrĂȘte quand on a libĂ©rĂ© du DIF sur (tous les items-1) ou lorsqu'il n'y a plus de tests significatifs*/ + local nb_stepC = `boucle' + local pajust=0.05 + /*rĂ©initialisation de la matrice de test*/ + matrix test_difu_`boucle'=J(`nbitems',3,.) + matrix colnames test_difu_`boucle'=chi_DIFU df_DIFU pvalueDIFU + matrix test_dif_`boucle'=J(`nbitems',3,.) + matrix colnames test_dif_`boucle'=chi_DIF df_DIF pvalueDIF + local nbsig=0 + local minpval=1 + local itemdif=0 + if "`detail'" != ""{ + + di as text "Loop `boucle'" + di as text _col(5) "Adjusted alpha: " %6.4f `pajust' + di + di as text _col(10) "{hline 65}" + di as text _col(10) "Freed item" _col(31) "Chi-Square" _col(48) "DF" _col(57) "P-Value" + di as text _col(10) "{hline 65}" + } + /*boucle de test*/ + forvalues j=1/`nbitems'{ + //if `nbdif_`j'' > 2 { + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF dĂ©jĂ  dĂ©tectĂ© sur l'item j*/ + /*on libĂšre le DIF de l'item i: pas de contraintes*/ + forvalues k=1/`nbitems'{ /*contraintes pour les autres items (si DIF NU sur item k, pas de contraintes*/ + if `k'!=`j' & `nbmoda_`j'' >= 2 { + if dif_rc[`k',1]==. | dif_rc[`k',1]==0 {/*pas de DIF sur item k: contraintes 1-200*/ + forvalues p=1/`nbdif_`k''{ + qui local listconst "`listconst' `=0+`maxdif'*(`k'-1)+`p''" + qui constraint list `=0+`maxdif'*(`k'-1)+`p'' + } + } + else{ + if dif_rc[`k',2]!=. & dif_rc[`k',2]!= 0 & `nbmoda_`k'' > 2 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`k''{ + qui local listconst "`listconst' `=200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + } + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) latent(THETA) nocapslatent + estimates store modeldif3b`boucle'it`i' + + ************************* + *****test DIF item i***** + ************************* + qui test [1.``j'']1.`gp'=[1.``j'']0bn.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']1.`gp'=[`p'.``j'']0bn.`gp', acc + } + } + matrix test_dif_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + + /* Test DIF Uniforme */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``j'']1.`gp'-[1.``j'']0bn.`gp')=[2.``j'']1.`gp'-[2.``j'']0bn.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``j'']1.`gp'-[1.``j'']0bn.`gp')=[`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp', acc + } + matrix test_difu_`boucle'[`j',1]=(r(chi2), r(df), r(p)) + } + + if test_dif_`boucle'[`j',3]<`pajust'{/*si DIF sur item i*/ + local ++nbsig + if test_dif_`boucle'[`j',3]<`minpval'{ + local minpval=test_dif_`boucle'[`j',3] + local itemdif=`j' + } + } + if "`detail'" != "" { + di as text _col(10) abbrev("``j''",15) as result _col(31) %6.3f test_dif_`boucle'[`j',1] _col(48) test_dif_`boucle'[`j',2] _col(57) %6.4f test_dif_`boucle'[`j',3] + } + } + } + /*si nb de tests significatifs=0, on arrĂȘte*/ + if `nbsig'==0{ + local stop=1 + if `boucle' == 1 { + if "`detail'" != "" { + di as text _col(10) "{hline 65}" + di + di as result "No significant test: no difference between groups detected, no DIF detected" + di + } + } + else { + if "`detail'" != ""{ + di as text _col(10) "{hline 65}" + di + di as result "No other significant tests" + di + } + } + } + else{/*si nb de tests significatifs>0, mise Ă  jour de la matrice de rĂ©sultats*/ + matrix dif_rc[`itemdif',1]=`boucle' + if "`detail'" != ""{ + di as text _col(10) "{hline 65}" + di + di as result "Difference between groups on ``itemdif'' at time 1" + } + if `nbmoda_`itemdif'' > 2 { + if "`detail'" != "" { + + di + di %~60s as text "Test of uniform difference" + di _col(10) "{hline 40}" + di _col(10) as text "Chi-square" _col(28) "DF" _col(40) "P-value" + di _col(10) as result %4.2f `=test_difu_`boucle'[`itemdif',1]' _col(28) `=test_difu_`boucle'[`itemdif',2]' _col(40) %4.2f `=test_difu_`boucle'[`itemdif',3]' + di _col(10) as text "{hline 40}" + } + if test_difu_`boucle'[`itemdif',3]<0.05{ /*DIF NU dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=0 + di + di as result "``itemdif'' : Non-uniform differences of item difficulties between groups at T1" + di + } + else{/*DIF U dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=`boucle' + di + di as result "``itemdif'' : Uniform differences of item difficulties between groups at T1" + di + } + } + else { + // DiffĂ©rence entre groupes au temps 1 mais slmt 2 moda. donc pas de U ou NU + di _col(15) _dup(60) "-" + } + } + local ++boucle + } + } + + /* MODELE FINAL DE LA PARTIE 1. Si DIFT1 dĂ©tectĂ© (=Au moins 2 boucles dans l'Ă©tape C)*/ + if `nb_stepC' > 1 { + forvalues j=1/`nbitems'{ + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF: contraintes 1-200*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) latent(THETA) nocapslatent + /* Stockage des estimations du modĂšle */ + estimates store modeldifCFin + matrix val_mC = r(table) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mCFin=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mCFin = `name_partOneC' + matrix rownames delta_mCFin = `name_partOneL' + + matrix delta_mCFin_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + matrix colnames delta_mCFin_se = `name_partOneC_se' + matrix rownames delta_mCFin_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin=r(estimate) + local delta`j'_`p'g`g'mCFin_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin = r(estimate) + local delta`j'_`p'g`g'mCFin_se = r(se) + } + matrix delta_mCFin[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin' + matrix delta_mCFin_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin_se' + } + } + } + if "`group'" != "" { //Variance et se mA + matrix var_mC = (val_mC[1,"/var(THETA)#0bn.`gp'"]\val_mC[2,"/var(THETA)#0bn.`gp'"]) + } + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmCFin=r(estimate) + local segeffmCFin=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmCFinp=r(p) + local gcmCFinchi=r(chi2) + local gcmCFindf=r(df) + } +} + + ********************************* + *** BILAN *** + ********************************* + + if "`group'" != "" & "`nodif'" == "" { + di + di %~84s as result "SUMMARY" + di as result _col(2) "{hline 80}" + di as result _col(18) "Difference in" + di as result _col(2) "Item" _col(18) "groups at T1" _col(36) "Recalibration" _col(54) "RC " abbrev("`gp'",10) " 0" _col(72) "RC " abbrev("`gp'",10) " 1" + di as result _col(2) "{hline 80}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + local difft1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + if (dif_rc[`j',1] != . ) { + if (dif_rc[`j',2]!=0) { + local difft1 "Uniform" + } + else { + local difft1 "Non-uniform" + } + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + if dif_rc[`j',1] != . { + local difft1 " X " + } + } + di as result _col(2) abbrev("``j''",15) as text _col(18) "`difft1'" _col(36) "`RC'" _col(54) "`RCg0'" _col(72) "`RCg1'" + } + di as result _col(2) "{hline 80}" + di +} +else if "`group'" != "" & "`nodif'" != "" { + di + di %~90s as result "SUMMARY" + di as result _col(10) "{hline 70}" + di as result _col(10) "Item" _col(26) "Recalibration" _col(46) "RC `gp' 0" _col(62) "RC `gp' 1" + di _col(10) "{hline 70}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + } + di as result _col(10) "``j''" as text _col(26) "`RC'" _col(44) "`RCg0'" _col(62) "`RCg1'" + } + di as result _col(10) "{hline 70}" +} +else if "`group'" == "" { + di + di %~60s as result "SUMMARY" + di as result _col(10) "{hline 40}" + di _col(10) "Item" _col(36) "Recalibration" + di _col(10) "{hline 40}" + forvalues j=1/`nbitems' { + local RC + if dif_rc[`j',3] != . { + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RC "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RC "Non-uniform" + } + } + else { + local RC " X " + } + } + di as result _col(10) "``j''" as text _col(38) "`RC'" + } + di as result _col(10) "{hline 40}" + di +} + +matrix dif_detect = J(1,`nbitems',.) +local numdif=1 +forvalues j=1/`nbitems' { + if dif_rc[`j',1] != . { + matrix dif_detect[1,`numdif']=`j' + local numdif = `numdif'+1 + } +} +return matrix difitems = dif_detect + +capture qui use `saverspcm', clear + +end diff --git a/Modules/rosali_custom/rosali_original.ado b/Modules/rosali_custom/rosali_original.ado new file mode 100644 index 0000000..7aa7b91 --- /dev/null +++ b/Modules/rosali_custom/rosali_original.ado @@ -0,0 +1,1150 @@ +*! version 2.4 june2020 +*! Myriam Blanchin - Priscilla Brisson +************************************************************************************************************ +* ROSALI: RespOnse-Shift ALgorithm at Item-level +* Response-shift detection based on Rasch models family +* +* Version 1 : December 21, 2016 (Myriam Blanchin) /*rspcm122016*/ +* Version 1.1 : October 13, 2017 (Myriam Blanchin) /*option: MODA, automatic recoding of unused response categories*/ +* Version 2 : April, 2018 (Myriam Blanchin - Priscilla Brisson) /*option: GROUP, dichotomous group variable*/ +* Version 2.1 : October, 2018 (Myriam Blanchin - Priscilla Brisson) /* Version 1.1 + Version 2 */ +* Version 2.2 : February, 2019 (Priscilla Brisson) /* option nodif, optimization */ +* Version 2.3 : December, 2019 (Priscilla Brisson) /* option detail, + petites corrections */ +* Version 2.4 : June, 2020 (Myriam Blanchin) /* debug option detail + step C, modifs sorties et help */ +* +* Myriam Blanchin, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* myriam.blanchin@univ-nantes.fr +* +* Priscilla Brisson, SPHERE, Faculty of Pharmaceutical Sciences - University of Nantes - France +* priscilla.brisson@univ-nantes.fr +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +************************************************************************************************************/ + +program define rosali_original, rclass + +timer clear 1 +timer on 1 + +syntax varlist(min=2 numeric) [if] [,GROUP(varlist) NODIF PRO DETail] + +preserve +version 15 +tempfile saverspcm +capture qui save `saverspcm',replace +local save1=_rc + +if "`if'"!="" { + qui keep `if' +} + +if "`pro'" != "" { + di "START" +} + +/**************************************************************************/ +set more off +set matsize 5000 +constraint drop _all + +local gp "`group'" + +tokenize `varlist' +local nbitems:word count `varlist' + + /* VĂ©rif nb d'items pair */ +local mod=mod(`nbitems',2) +if `mod'!=0 { + di as error "You must enter an even number of items : the first half of the items represents the items at time 1 and the second half the items at time 2" + error 198 + exit +} + +local nbitems=`nbitems'/2 + + +if "`group'"=="" & "`nodif'"!="" { + di as error "nodif can only be used with the group option ({hi:nodif} option). Please correct this option." + error 198 + exit +} + +local nbc: word count `group' +if `nbc' >= 2 { + di as error "Only one variable can be used for group option ({hi:group} option). Please correct this option." + error 198 + exit +} + + /* VĂ©rif qu'il y a 2 groupes si l'option groupe est choisie */ +if "`group'"!="" { + qui tab `group' + local nbgrp = r(r) + if `nbgrp' != 2 { + di as error "Only 2 groups are possible for the group option ({hi:group} option). Please correct this option." + error 420 + exit + } +} +/* recoder la variable de groupe en 0, 1*/ + +if "`group'"!="" { + qui tab `gp', matrow(rep) + qui matrix list rep + if rep[1,1]+rep[2,1] != 1 & rep[1,1]*rep[2,1] != 0 { + forvalues i=1/`=rowsof(rep)'{ + qui replace `gp'=`i'-1 if `gp'==rep[`i',1] + di "WARNING : `gp' `=rep[`i',1]' is now `gp' `=`i'-1' " + } + } + forvalues g = 0/1 { + qui tab `gp' if `gp' == `g' + local nbp_gp`g' = r(N) + } +} + + + +/*item rename*/ +/* +Items au temps 1 : 1 Ă  nbitems ``j'' +Items au temps 2 : nbitems Ă  2*nbitems ``=`j'+`nbitems''' + +Si t varie, puis num item : ``=(`t'-1)*`nbitems'+`j''' +*/ + + +local com_z = 0 // Indicatrice de recodage + /*verif modalitĂ©s rĂ©pondues*/ +if "`gp'" == "" { // Si pas d'option groupe + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'', matrow(rect1_`j') // RĂ©cupĂ©ration des infos moda du temps 1 + local minm`j'_t1 = rect1_`j'[1,1] + local maxm`j'_t1 = rect1_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''', matrow(rect2_`j') // RĂ©cupĂ©ration des infos moda du temps 2 + local minm`j'_t2 = rect2_`j'[1,1] + local maxm`j'_t2 = rect2_`j'[r(r),1] + + local minm_`j' = min(`minm`j'_t1',`minm`j'_t2') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1',`maxm`j'_t2') + local nbm_`j' = `=`maxm_`j''-`minm_`j''' + + if `minm_`j'' != 0 & `com_z' == 0 { + local com_z = 1 + } + + + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`nbm_`j'' { + qui count if ``j'' == `m' + local nb_rn1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' + local nb_rn2 = r(N) + local nb_rn = min(`nb_rn1',`nb_rn2') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' <= `minm`j'_t1' | `m' <= `minm`j'_t2' { // La moda 0 ou les moda min ne sont pas utilisĂ©es + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged " + local stop = 0 + } + } + } + else if `m' >= `maxm`j'_t1' | `m' >= `maxm`j'_t2' | `m' == `maxm_`j'' { // La (ou les) moda max ne sont pas utilisĂ©e(s) + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems''' =`=`m'-`k'' if ``=`j'+`nbitems''' ==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' + local v`k'1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' + local v`k'2 = r(N) + if (`v`k'1' != 0 | `v`k'2' != 0) & `stop' != 0 { + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} +else { // Cas oĂč l'option groupe est utilisĂ©e + forvalues j = 1 / `nbitems' { + local recoda_`j' = 0 + qui tab ``j'' if `gp' == 0, matrow(rect1_g0_`j') matcell(nbrt1_g0_`j') // RĂ©cupĂ©ration des infos moda du temps 1pour chaque groupe + local minm`j'_t1_g0 = rect1_g0_`j'[1,1] + local maxm`j'_t1_g0 = rect1_g0_`j'[r(r),1] + + qui tab ``j'' if `gp' == 1, matrow(rect1_g1_`j') matcell(nbrt1_g1_`j') + local minm`j'_t1_g1 = rect1_g1_`j'[1,1] + local maxm`j'_t1_g1 = rect1_g1_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''' if `gp' == 0, matrow(rect2_g0_`j') matcell(nbrt2_g0_`j') // RĂ©cupĂ©ration des infos moda du temps 2 pour chaque groupe + local minm`j'_t2_g0 = rect2_g0_`j'[1,1] + local maxm`j'_t2_g0 = rect2_g0_`j'[r(r),1] + + qui tab ``=`j'+`nbitems''' if `gp' == 1 , matrow(rect2_g1_`j') matcell(nbrt2_g1_`j') + local minm`j'_t2_g1 = rect2_g0_`j'[1,1] + local maxm`j'_t2_g1 = rect2_g0_`j'[r(r),1] + + local minm_`j' = min(`minm`j'_t1_g0',`minm`j'_t2_g0',`minm`j'_t1_g1',`minm`j'_t2_g1') // Info moda pour l'item j + local maxm_`j' = max(`maxm`j'_t1_g0',`maxm`j'_t2_g0',`maxm`j'_t1_g1',`maxm`j'_t2_g1') + local nbm_`j' = `=`maxm_`j''-`minm_`j''+1' + + if `minm_`j'' != 0 & `com_z' == 0 { + local com_z = 1 + } + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`maxm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=`r'+`minm_`j''' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=`r'+`minm_`j''' + } + + // VĂ©rif. Que toutes les modas sont utilisĂ©es & concordance entre temps + forvalues m = 0/`=`nbm_`j''-1' { + qui count if ``j'' == `m' & `gp' == 0 + local nb_rn1_g0 = r(N) + qui count if ``j'' == `m' & `gp' == 1 + local nb_rn1_g1 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 0 + local nb_rn2_g0 = r(N) + qui count if ``=`j'+`nbitems''' == `m' & `gp' == 1 + local nb_rn2_g1 = r(N) + local nb_rn = min(`nb_rn1_g0',`nb_rn2_g0',`nb_rn1_g1',`nb_rn2_g1') + + if `nb_rn' == 0 { // Une moda n'est pas utilisĂ©e + local recoda_`j' = 1 + if `m' == 0 | `m' < `minm`j'_t1_g0' | `m' < `minm`j'_t2_g0' | `m' < `minm`j'_t1_g1' | `m' < `minm`j'_t2_g1' { // La moda 0 n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'+`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'+`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + } + } + else if `m' == `=`nbm_`j''-1' | `m' >= `maxm`j'_t2_g0' | `m' >= `maxm`j'_t1_g1' | `m' >= `maxm`j'_t2_g1' { // La moda max n'est pas utilisĂ©e + local stop = 1 + forvalues k = 1/`=`m'' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0 ) & `stop' != 0 { + qui replace ``j''= `=`m' - `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `=`m' - `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { // Moda central non utilisĂ©e + if runiform()>0.5{ // Tirage au sort pour regrouper + local stop = 1 + forvalues k = 1/`m' { + qui count if ``j'' == `=`m' - `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' - `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' - `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0 { + qui replace ``j''= `=`m'-`k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m'-`k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'-`k'' merged" + local stop = 0 + } + } + } + else { + local stop = 1 + forvalues k = 1/`=`nbm_`j''-`m'' { + qui count if ``j'' == `=`m' + `k'' & `gp' == 0 + local v`k'1_0 = r(N) + qui count if ``j'' == `=`m' + `k'' & `gp' == 1 + local v`k'1_1 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 0 + local v`k'2_0 = r(N) + qui count if ``=`j'+`nbitems''' == `=`m' + `k'' & `gp' == 1 + local v`k'2_1 = r(N) + if (`v`k'1_0' != 0 | `v`k'2_0' != 0 | `v`k'1_1' != 0 | `v`k'2_1' != 0) & `stop' != 0{ + qui replace ``j''=`=`m' + `k'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''=`=`m' + `k'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `=`m'+`k'' merged" + local stop = 0 + } + else { + if `stop' != 0 { + qui replace ``j''= `nbm_`j'' if ``j''==`m' + qui replace ``=`j'+`nbitems'''= `nbm_`j'' if ``=`j'+`nbitems'''==`m' + di "WARNING: items ``j'' & ``=`j'+`nbitems''': answers `m' and `nbm_`j'' merged" + local stop = 0 + } + } + } + } + } + } + } + } +} + +if `com_z' == 1 { + di + di "WARNING : Automatic recoding, the first response category is 0. see {help rosali:help rosali}." + di +} + +forvalues j =1/`nbitems' { + qui tab ``j'', matrow(rec) // RĂ©cupĂ©ration des infos moda du temps 1 + local nbm`j'_t1 = r(r) + + qui tab ``=`j'+`nbitems''' // RĂ©cupĂ©ration des infos moda du temps 2 + local nbm`j'_t2 = r(r) + + local nbm_`j' = max(`nbm`j'_t1', `nbm`j'_t2') + //Recodage des rĂ©ponses en 0, 1, 2, etc... + forvalues r = 0/`=`nbm_`j''-1' { + qui replace ``j'' = `r' if ``j'' == `=rec[`=`r'+1',1]' + qui replace ``=`j'+`nbitems''' = `r' if ``=`j'+`nbitems''' == `=rec[`=`r'+1',1]' + } +} + +/* Calcul de nbmoda & nbdif */ +forvalues j = 1/`nbitems' { + qui tab ``j'' + local nbmoda_`j' = r(r) + local nbdif_`j' = r(r) - 1 +} + +local maxdif = 0 +local nbmoda_sum = 0 +forvalues j = 1/`nbitems' { + if `maxdif' < `nbdif_`j'' { + local maxdif = `nbdif_`j'' + } + local nbmoda_sum = `nbmoda_sum' + `nbdif_`j'' +} + +/* Au moins 2 moda par item */ +forvalues j=1/`nbitems' { + if `nbmoda_`j'' == 1 { + di as error "``j'' have only one response category, the analysis can be performed only if each item has at least 2 response categories" + error 198 + exit + } +} + +local coln "" +forvalues j =1 /`nbitems' { + local coln "`coln' ``j''" +} + +matrix nbmod = J(2,`nbitems',.) + +matrix colnames nbmod = `coln' +matrix rownames nbmod = NbModa Recoding + +forvalues j = 1/`nbitems' { + matrix nbmod[1,`j'] = `nbmoda_`j'' + matrix nbmod[2,`j'] = `recoda_`j'' +} + +*Erreur si plus de 200 difficultĂ©s +local nb_test = 0 +forvalues j=1/`nbitems' { + local nb_test = `nb_test'+`nbmoda_`j'' -1 +} + +if `nb_test' >= 200 { + di as error "The total number of items difficulties to be estimated must be less than 200 ({hi:moda} option option)." + error 198 + exit +} + +local nbitp = 0 + +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' >= 2 { + local nbitp = `nbitp' + 1 + } +} + +qui count +local nbpat = r(N) + + +/********************************* +* AFFICHAGE INITIAL +*********************************/ +di +di _col(5) "{hline 78}" +di _col(15) "Time 1" _col(42) "Time 2" _col(65) "Nb of Answer Cat." +di _col(5) "{hline 78}" +forvalues j=1/`nbitems' { + di as text _col(15) abbrev("``j''",20) _col(42) abbrev("``=`j'+`nbitems'''",20) _col(65) `nbmoda_`j'' +} +di _col(5) "{hline 78}" +if "`group'" != "" { + di _col(10) "Nb of patients: " abbrev("`gp'",20) " 0 = `nbp_gp0' ;", abbrev("`gp'",20) " 1 = `nbp_gp1'" + di _col(5) "{hline 78}" +} +else { + di _col(10) "Nb. of patients: `nbpat'" + di _col(5) "{hline 78}" +} +di +if `nbitems' == 1 { + di as error "The analysis can only be performed with at least 2 items." + error 198 + exit +} +forvalues j = 1/`nbitems' { + if `nbmoda_`j'' == 2 { + di "WARNING: ``j'' has only 2 response categories, no distinction can be made between uniform or non-uniform recalibration." + } + if `nbmoda_`j'' == 1 { + di as error "Only `nbmoda_`j'' response categories of item ``j'' were used by the sample, the analysis cannot be performed." + error 198 + exit + } + if `nbmoda_`j'' == 0 { + di as error "No response categories of item ``j'' were used by the sample, the analysis cannot be performed." + error 198 + exit + } +} +di +if "`group'" != "" { + di _col(2) as text "For all models : - mean of the latent trait in `gp' 0 at time 1 is constrained at 0" + di _col(19) "- equality of variances between groups" + di +} +else { + di _col(2) as text "For all models : mean of the latent trait at time 1 is constrained at 0" + di +} + + + +/********************************* +* DEFINITION DES CONTRAINTES +*********************************/ + +if "`group'"!="" { // Contraintes si option groupe + *EGALITE ENTRE GROUPES A T1 (1-200) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=0+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``j'']1.`gp' + } + } + + *DIF UNIFORME A T1 (201-400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=200+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp'=`p'*[1.``j'']1.`gp'-`p'*[1.``j'']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 0 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']0bn.`gp' + } + } + + *EGALITES ENTRE T1 et T2, groupe 1 (601-800) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=600+`maxdif'*(`j'-1)+`p'' [`p'.``j'']1.`gp'=[`p'.``=`j'+`nbitems''']1.`gp' + } + } + + * RC COMMUNE (801-1000) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=800+`maxdif'*(`j'-1)+`p'' [`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp'=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + * RC UNIFORME, groupe 0 (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']0bn.`gp'-[1.``j'']0bn.`gp')=[`p'.``=`j'+`nbitems''']0bn.`gp'-[`p'.``j'']0bn.`gp' + } + } + + * RC UNIFORME, groupe 1 (1201-1400) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1200+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']1.`gp'-[1.``j'']1.`gp')=[`p'.``=`j'+`nbitems''']1.`gp'-[`p'.``j'']1.`gp' + } + } + + *Sans interaction temps x groupe + constraint 1999 [/]:mean(THETA2)#1.`gp'-[/]:mean(THETA2)#0bn.`gp'=[/]:mean(THETA1)#1.`gp'-[/]:mean(THETA1)#0bn.`gp' +} +else { //Contraintes si pas d'option groupe + *EGALITE ENTRE T1 et T2 (401-600) + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + constraint `=400+`maxdif'*(`j'-1)+`p'' [`p'.``j'']:_cons = [`p'.``=`j'+`nbitems''']:_cons + } + } + *RC UNIFORME (1001-1200) + forvalues j=1/`nbitems'{ + forvalues p=2/`nbdif_`j''{ + constraint `=1000+`maxdif'*(`j'-1)+`p'' `p'*([1.``=`j'+`nbitems''']:_cons - [1.``j'']:_cons)=[`p'.``=`j'+`nbitems''']:_cons -[`p'.``j'']:_cons + } + } +} + +/********************************* +* MATRICE DES RESULTATS +*********************************/ +matrix dif_rc=J(`nbitems',8,.) +matrix colnames dif_rc=DIFT1 DIFU RC RC_DIF RCG0 RCUG0 RCG1 RCUG1 +local rown "" + +forvalues j =1 /`nbitems' { + local rown "`rown' ``j''" +} +matrix rownames dif_rc = `rown' + +*Nb modalitĂ© max +local nbdif_max = 0 +forvalues j=1/`nbitems' { + if `nbdif_max' < `nbdif_`j'' { + local nbdif_max = `nbdif_`j'' + } +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////// PARTIE 1 : DIF A T1 ? //////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +if "`group'"!="" & "`nodif'"=="" { // PARTIE 1 = Slmt si option group & pas de "nodif" + + di _dup(49) "_ " + di + di as input "PART 1: DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES BETWEEN GROUPS AT TIME 1" + + ********************************* + ** MODEL B ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading cons) var(0: THETA@v) var(1:THETA@v) latent(THETA) nocapslatent + /* Stockage des estimations du modĂšle */ + estimates store modeldifB + matrix val_mB = r(table) + matrix esti_B = e(b) + + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mB=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + + matrix colnames delta_mB = `name_partOneC' + matrix rownames delta_mB = `name_partOneL' + matrix delta_mB_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mB_se = `name_partOneC_se' + matrix rownames delta_mB_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB=r(estimate) + local delta`j'_`p'g`g'mB_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mB = r(estimate) + local delta`j'_`p'g`g'mB_se = r(se) + } + matrix delta_mB[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB' + matrix delta_mB_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mB_se' + } + } + } + + matrix var_mB = (val_mB[1,"/var(THETA)#0bn.`gp'"]\val_mB[2,"/var(THETA)#0bn.`gp'"]) + + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmB=r(estimate) + local segeffmB=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmBp=r(p) + local gcmBchi=r(chi2) + local gcmBdf=r(df) + + + ********************************* + ** MODEL A ** + ********************************* + + local model "" + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading means) var(0: THETA@v) var(1:THETA@v) from(esti_B, skip) latent(THETA) nocapslatent + + /* Stockage des estimations du modĂšle */ + estimates store modeldifA + matrix val_mA = r(table) + matrix esti_A = e(b) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mA=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mA = `name_partOneC' + matrix rownames delta_mA = `name_partOneL' + matrix delta_mA_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + + matrix colnames delta_mA_se = `name_partOneC_se' + matrix rownames delta_mA_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA=r(estimate) + local delta`j'_`p'g`g'mA_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mA = r(estimate) + local delta`j'_`p'g`g'mA_se = r(se) + } + matrix delta_mA[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA' + matrix delta_mA_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mA_se' + } + } + } + //Variance et se mA + matrix var_mA = (val_mA[1,"/var(THETA)#0bn.`gp'"]\val_mA[2,"/var(THETA)#0bn.`gp'"]) + + ********************************* + *************MODEL C************* + ********************************* + // Etape itĂ©rative si lrtest significatif + local nb_stepC = 0 + qui lrtest modeldifA modeldifB + local diftestp=r(p) + if `diftestp'<0.05{ /*If pvalue(LRtest)<0.05 then step C*/ + di + di as input "PROCESSING STEP C" + di + + /*test DIF pour chaque item*/ + local boucle = 1 + local stop = 0 + while `boucle'<=`=`nbitp'-1' & `stop'==0{ /*on s'arrĂȘte quand on a libĂ©rĂ© du DIF sur (tous les items-1) ou lorsqu'il n'y a plus de tests significatifs*/ + local nb_stepC = `boucle' + local pajust=0.05/`=`nbitp'+1-`boucle'' + /*rĂ©initialisation de la matrice de test*/ + matrix test_difu_`boucle'=J(`nbitems',3,.) + matrix colnames test_difu_`boucle'=chi_DIFU df_DIFU pvalueDIFU + matrix test_dif_`boucle'=J(`nbitems',3,.) + matrix colnames test_dif_`boucle'=chi_DIF df_DIF pvalueDIF + local nbsig=0 + local minpval=1 + local itemdif=0 + if "`detail'" != ""{ + + di as text "Loop `boucle'" + di as text _col(5) "Adjusted alpha: " %6.4f `pajust' + di + di as text _col(10) "{hline 65}" + di as text _col(10) "Freed item" _col(31) "Chi-Square" _col(48) "DF" _col(57) "P-Value" + di as text _col(10) "{hline 65}" + } + /*boucle de test*/ + forvalues j=1/`nbitems'{ + //if `nbdif_`j'' > 2 { + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF dĂ©jĂ  dĂ©tectĂ© sur l'item j*/ + /*on libĂšre le DIF de l'item i: pas de contraintes*/ + forvalues k=1/`nbitems'{ /*contraintes pour les autres items (si DIF NU sur item k, pas de contraintes*/ + if `k'!=`j' & `nbmoda_`j'' >= 2 { + if dif_rc[`k',1]==. | dif_rc[`k',1]==0 {/*pas de DIF sur item k: contraintes 1-200*/ + forvalues p=1/`nbdif_`k''{ + qui local listconst "`listconst' `=0+`maxdif'*(`k'-1)+`p''" + qui constraint list `=0+`maxdif'*(`k'-1)+`p'' + } + } + else{ + if dif_rc[`k',2]!=. & dif_rc[`k',2]!= 0 & `nbmoda_`k'' > 2 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`k''{ + qui local listconst "`listconst' `=200+`maxdif'*(`k'-1)+`p''" + qui constraint list `=200+`maxdif'*(`k'-1)+`p'' + } + } + } + } + } + forvalues jj=1/`nbitems'{ + forvalues p=1/`nbdif_`jj''{ + local model "`model' (`p'.``jj''<-THETA@`p')" + } + } + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) latent(THETA) nocapslatent + estimates store modeldif3b`boucle'it`i' + + ************************* + *****test DIF item i***** + ************************* + qui test [1.``j'']1.`gp'=[1.``j'']0bn.`gp' + if `nbmoda_`j'' > 2 { + forvalues p=2/`nbdif_`j''{ + qui test [`p'.``j'']1.`gp'=[`p'.``j'']0bn.`gp', acc + } + } + matrix test_dif_`boucle'[`j',1]=(r(chi2),r(df),r(p)) + + /* Test DIF Uniforme */ + if `nbmoda_`j'' > 2 { + qui test 2*([1.``j'']1.`gp'-[1.``j'']0bn.`gp')=[2.``j'']1.`gp'-[2.``j'']0bn.`gp' + forvalues p=3/`nbdif_`j''{ + qui test `p'*([1.``j'']1.`gp'-[1.``j'']0bn.`gp')=[`p'.``j'']1.`gp'-[`p'.``j'']0bn.`gp', acc + } + matrix test_difu_`boucle'[`j',1]=(r(chi2), r(df), r(p)) + } + + if test_dif_`boucle'[`j',3]<`pajust'{/*si DIF sur item i*/ + local ++nbsig + if test_dif_`boucle'[`j',3]<`minpval'{ + local minpval=test_dif_`boucle'[`j',3] + local itemdif=`j' + } + } + if "`detail'" != "" { + di as text _col(10) abbrev("``j''",15) as result _col(31) %6.3f test_dif_`boucle'[`j',1] _col(48) test_dif_`boucle'[`j',2] _col(57) %6.4f test_dif_`boucle'[`j',3] + } + } + } + /*si nb de tests significatifs=0, on arrĂȘte*/ + if `nbsig'==0{ + local stop=1 + if `boucle' == 1 { + if "`detail'" != "" { + di as text _col(10) "{hline 65}" + di + di as result "No significant test: no difference between groups detected, no DIF detected" + di + } + } + else { + if "`detail'" != ""{ + di as text _col(10) "{hline 65}" + di + di as result "No other significant tests" + di + } + } + } + else{/*si nb de tests significatifs>0, mise Ă  jour de la matrice de rĂ©sultats*/ + matrix dif_rc[`itemdif',1]=`boucle' + if "`detail'" != ""{ + di as text _col(10) "{hline 65}" + di + di as result "Difference between groups on ``itemdif'' at time 1" + } + if `nbmoda_`itemdif'' > 2 { + if "`detail'" != "" { + + di + di %~60s as text "Test of uniform difference" + di _col(10) "{hline 40}" + di _col(10) as text "Chi-square" _col(28) "DF" _col(40) "P-value" + di _col(10) as result %4.2f `=test_difu_`boucle'[`itemdif',1]' _col(28) `=test_difu_`boucle'[`itemdif',2]' _col(40) %4.2f `=test_difu_`boucle'[`itemdif',3]' + di _col(10) as text "{hline 40}" + } + if test_difu_`boucle'[`itemdif',3]<0.05{ /*DIF NU dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=0 + di + di as result "``itemdif'' : Non-uniform differences of item difficulties between groups at T1" + di + } + else{/*DIF U dĂ©tectĂ©e*/ + matrix dif_rc[`itemdif',2]=`boucle' + di + di as result "``itemdif'' : Uniform differences of item difficulties between groups at T1" + di + } + } + else { + // DiffĂ©rence entre groupes au temps 1 mais slmt 2 moda. donc pas de U ou NU + di _col(15) _dup(60) "-" + } + } + local ++boucle + } + } + + /* MODELE FINAL DE LA PARTIE 1. Si DIFT1 dĂ©tectĂ© (=Au moins 2 boucles dans l'Ă©tape C)*/ + if `nb_stepC' > 1 { + forvalues j=1/`nbitems'{ + local model "" + local listconst "" + if dif_rc[`j',1]==. | dif_rc[`j',1]==0 { /*si pas de DIF: contraintes 1-200*/ + forvalues p=1/`nbdif_`j''{ + qui local listconst "`listconst' `=0+`maxdif'*(`j'-1)+`p''" + qui constraint list `=0+`maxdif'*(`j'-1)+`p'' + } + } + else { + if dif_rc[`j',2]!=. & dif_rc[`j',2]!=0 { /*DIF U: contraintes 201-400*/ + forvalues p=2/`nbdif_`j''{ + qui local listconst "`listconst' `=200+`maxdif'*(`j'-1)+`p''" + qui constraint list `=200+`maxdif'*(`j'-1)+`p'' + } + } + } + } + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + local model "`model' (`p'.``j''<-THETA@`p')" + } + } + + qui gsem `model', mlogit tol(0.01) iterate(100) group(`gp') ginvariant(coef loading) var(0: THETA@v) var(1:THETA@v) constraint(`listconst') from(esti_B) latent(THETA) nocapslatent + /* Stockage des estimations du modĂšle */ + estimates store modeldifCFin + matrix val_mC = r(table) + + /* Calcul des difficultĂ©s d'item (delta_j) */ + matrix delta_mCFin=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC "" + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC "`name_partOneC' delta_`p'_gp`g'" + } + } + local name_partOneL "" + forvalues j=1/`nbitems' { + local name_partOneL "`name_partOneL' ``j''" + } + matrix colnames delta_mCFin = `name_partOneC' + matrix rownames delta_mCFin = `name_partOneL' + + matrix delta_mCFin_se=J(`nbitems',`=`nbdif_max'*2',.) + local name_partOneC_se "" + + forvalues p=1/`nbdif_max' { + forvalues g=0/1 { + local name_partOneC_se "`name_partOneC_se' delta_`p'_gp`g'_se" + } + } + matrix colnames delta_mCFin_se = `name_partOneC_se' + matrix rownames delta_mCFin_se = `name_partOneL' + + forvalues j=1/`nbitems'{ + forvalues p=1/`nbdif_`j''{ + forvalues g=0/1{ + qui lincom -[`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin=r(estimate) + local delta`j'_`p'g`g'mCFin_se=r(se) + if `p'>1{ + qui lincom [`=`p'-1'.``j'']:`g'.`gp' - [`p'.``j'']:`g'.`gp' + local delta`j'_`p'g`g'mCFin = r(estimate) + local delta`j'_`p'g`g'mCFin_se = r(se) + } + matrix delta_mCFin[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin' + matrix delta_mCFin_se[`j',`=2*`p'-1+`g'']=`delta`j'_`p'g`g'mCFin_se' + } + } + } + if "`group'" != "" { //Variance et se mA + matrix var_mC = (val_mC[1,"/var(THETA)#0bn.`gp'"]\val_mC[2,"/var(THETA)#0bn.`gp'"]) + } + /*group effect*/ + qui lincom [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp' + local geffmCFin=r(estimate) + local segeffmCFin=r(se) + qui test [/]:mean(THETA)#1.`gp'-[/]:mean(THETA)#0bn.`gp'=0 + local gcmCFinp=r(p) + local gcmCFinchi=r(chi2) + local gcmCFindf=r(df) + } +} + + ********************************* + *** BILAN *** + ********************************* + + if "`group'" != "" & "`nodif'" == "" { + di + di %~84s as result "SUMMARY" + di as result _col(2) "{hline 80}" + di as result _col(18) "Difference in" + di as result _col(2) "Item" _col(18) "groups at T1" _col(36) "Recalibration" _col(54) "RC " abbrev("`gp'",10) " 0" _col(72) "RC " abbrev("`gp'",10) " 1" + di as result _col(2) "{hline 80}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + local difft1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + if (dif_rc[`j',1] != . ) { + if (dif_rc[`j',2]!=0) { + local difft1 "Uniform" + } + else { + local difft1 "Non-uniform" + } + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + if dif_rc[`j',1] != . { + local difft1 " X " + } + } + di as result _col(2) abbrev("``j''",15) as text _col(18) "`difft1'" _col(36) "`RC'" _col(54) "`RCg0'" _col(72) "`RCg1'" + } + di as result _col(2) "{hline 80}" + di +} +else if "`group'" != "" & "`nodif'" != "" { + di + di %~90s as result "SUMMARY" + di as result _col(10) "{hline 70}" + di as result _col(10) "Item" _col(26) "Recalibration" _col(46) "RC `gp' 0" _col(62) "RC `gp' 1" + di _col(10) "{hline 70}" + forvalues j=1/`nbitems' { + local RC + local RCg0 + local RCg1 + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] == 0) { + local RC "Common" + } + if (dif_rc[`j',3] != . & dif_rc[`j',3] != 0 & dif_rc[`j',4] != 0) { + local RC "Differential" + } + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RCg0 "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RCg0 "Non-uniform" + } + if (dif_rc[`j',8]!=. & dif_rc[`j',8] != 0) { + local RCg1 "Uniform" + } + if ( dif_rc[`j',8] == 0) { + local RCg1 "Non-uniform" + } + } + else { + if dif_rc[`j',6] != . { + local RCg0 " X " + } + if dif_rc[`j',8] != . { + local RCg1 " X " + } + } + di as result _col(10) "``j''" as text _col(26) "`RC'" _col(44) "`RCg0'" _col(62) "`RCg1'" + } + di as result _col(10) "{hline 70}" +} +else if "`group'" == "" { + di + di %~60s as result "SUMMARY" + di as result _col(10) "{hline 40}" + di _col(10) "Item" _col(36) "Recalibration" + di _col(10) "{hline 40}" + forvalues j=1/`nbitems' { + local RC + if dif_rc[`j',3] != . { + if `nbmoda_`j'' > 2 { + if (dif_rc[`j',6]!=. & dif_rc[`j',6] != 0) { + local RC "Uniform" + } + if (dif_rc[`j',6] == 0) { + local RC "Non-uniform" + } + } + else { + local RC " X " + } + } + di as result _col(10) "``j''" as text _col(38) "`RC'" + } + di as result _col(10) "{hline 40}" + di +} + +matrix dif_detect = J(1,`nbitems',.) +local numdif=1 +forvalues j=1/`nbitems' { + if dif_rc[`j',1] != . { + matrix dif_detect[1,`numdif']=`j' + local numdif = `numdif'+1 + } +} +return matrix difitems = dif_detect + +capture qui use `saverspcm', clear + +end diff --git a/Modules/simirt.R b/Modules/simirt.R new file mode 100644 index 0000000..babf68c --- /dev/null +++ b/Modules/simirt.R @@ -0,0 +1,274 @@ +simIRT <- function(NBOBS=2000,DIM=NULL,MU=NULL,COV=NULL,COVM=NULL,DIS=NULL,DIF=NULL,PMIN=NULL,PMAX=NULL,ACC=NULL,CLEAR=NULL,STORE=NULL,REP=NULL,PREF=NULL,DRAW=NULL, + TYPEDIF=NULL,DRAWALL=NULL,ICC,GR=0,RAND=NULL,DELTAGR=0,RSM1=NULL,RSM2=NULL,THR=NULL,TIT=NULL,PCM=NULL,ID=NULL,GENP=NULL,GENI=NULL) { + +if (GR < 0 | GR > 1) { + stop('Error 198: The GR option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.') +} + +if ( is.null(CLEAR) & is.null(STORE) ) { + stop('Error 198: You must use at least one of these two options: clear and/or store.') +} + +if (!is.null(DIM)) { + nbdim <- length(DIM) + if (nbdim > 2 & is.null(COVM)) { + stop('Error 198: You can simulate data with one or two dimensions, and you have indicated more dimensions in the DIM option. Please correct it.') + } + + if (!is.null(COVM)) { + nbrowcovm <- nrow(COVM) + if (nbdim != nbrowcovm) { + stop('Error 198: DIM and COVM dimension mismatch. Please correct.') + } + } + + nbitems <- sum(DIM) + + if (!is.null(DIF)) { + nbdiff <- length(DIF) + tmp <- TYPEDIF + if (tmp=='gauss' | tmp=='uniform') { + typediff <- tmp + } + else if (nbdiff != nbitems) { + stop('Error 198: "You have indicated a number of difficulty parameters (DIF option) different of the number of items to simulate (DIM option). Please correct these options.') + } + } + + else if (is.null(DIF)) { + DIF <- vector(mode='list', length=DIM) + for (d in seq(1,DIM)) { + DIF[[d]] <- c('gauss',0,1) + } + typediff <- 'gauss' + nbdiff <- length(DIF)*3 + } + +} + +else if (is.null(DIM)) { + if (is.null(DIF) & is.null(PCM)) { + stop('Error 198: You must indicate the number of items to simulate in the DIM, DIF or PCM options.') + } + else if (!is.null(COVM)) { + nbrowcovm <- nrow(COVM) + if (nbrowcovm>1) { + stop('Error 198: You affected dimensions with COVM, but you did not affect each item to a dimension with the DIM option. Please correct DIM.') + } + } + else if (!is.null(PCM)) { + nbitems <- nrow(PCM) + DIM <- c(1) + } + else { + nbdiff <- length(DIF) + nbitems <- nbdiff + DIM <- c(1) + } +} + +if ( (GR!=0 | DELTAGR!=0) & any(DIM != 1) & length(DIM)==1 ) { + stop('The GR and DELTAGR options are available only with unidimensional simulated data.') +} + +if (is.null(PREF)) { + PREF <- 'item' +} + +nbprefix <- length(PREF) + +if (nbprefix!=length(DIM) & nbprefix!=1) { # ici, DIM est un vecteur contenant les nombres d'items par dim, mais est juste le nbre de dim dans stata + stop('Error 198: The PREF option is incorrect because the number of prefixes is different from the number of dimensions set in DIM. Please correct.') +} + +if (nbprefix!=length(DIM)) { + alphab <- c('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z') + prefix <- paste0(prefix,alphab[seq(1,length(DIM))]) +} + +if (is.null(COVM)) { + nbcov <- length(COV) + if (length(DIM)==1) { + if (is.null(COV)) { + COV <- 1 + } + if (nbcov>1) { + stop('Error 198: You simulate only one dimension, you must indicate only the variance of the simulated latent trait in the COV argument.') + } + if (COV <0) { + stop('Error 198: The variance of the latent trait cannot be negative. Please correct the COV option.') + } + covmatrix2 <- COV # cov doit ĂȘtre une matrice prĂ© formatĂ©e + } + else if (length(DIM)==2) { + if (nbcov!=4 & nbcov>0) { + stop("Error 198: You simulate 2 dimensions. The COV option must be a 2x2 covariance matrix.") + } + else if (nbcov==0) { + if (length(DIM)==1) { + COV <- 1 + } + else if (length(DIM)==2) { + COV <- matrix(c(1,0,0,1),nrow=2,byrow = T) + } + nbcov <- length(COV) + } + if (nbcov==4) { + cov1 <- COV[1,1] + cov2 <- COV[2,2] + cov3 <- COV[1,2] + rho <- cov3/sqrt(cov1*cov2) + if (cov1<0 | cov2<0 | rho< -1 | rho>1) { + stop('Error 198: The covariance matrix in COV is not correct. Please correct it.') + } + } + covmatrix2 <- COV + } + COVM <- COV +} + +nbmu <- length(MU) +if (nbmu!=length(DIM) & nbmu!=0) { + stop('Error 198: You must indicate as many values in MU as the number of dimensions in DIM.') +} + +nbdisc <- length(DIS) +if (nbdisc!=nbitems & nbdisc!=0) { + stop('Error 198: You must indicate as many values in DISC as the number of items in DIM and DIF.') +} + +nbpmin <- length(PMIN) +if (nbpmin!=nbitems & nbpmin!=0) { + stop('Error 198: You must indicate as many values in PMIN as the number of items in DIM and DIF.') +} + +nbpmax <- length(PMAX) +if (nbpmax!=nbitems & nbpmax!=0) { + stop('Error 198: You must indicate as many values in PMAX as the number of items in DIM and DIF.') +} + +nbacc <- length(ACC) +if (nbacc != nbitems & nbacc!=0) { + stop('Error 198: You must indicate as many values in ACC as the number of items in DIM and DIF.') +} + +if (!is.null(THR) & any(!is.null(c(DIS,PMIN,PMAX,ACC)))) { + stop('Error 198: If you use the THR option, you cannot use DIS, PMIN, PMAX or ACC.') +} + +if (any(!is.null(c(RSM1,RSM2))) & any(!is.null(c(DIS,PMIN,PMAX,ACC)))) { + stop('Error 198: If you use the RSM1 and/or RSM2 option, you cannot use DIS, PMIN, PMAX or ACC.') +} + +if (!is.null(PCM) & any(!is.null(c(DIS,PMIN,PMAX,ACC)))) { + stop('Error 198: If you use the PCM option, you cannot use DIS, PMIN, PMAX or ACC.') +} + +if (any(!is.null(c(RSM1,RSM2))) & !is.null(PCM)) { + stop('Error 198: If you use the RSM1 and/or RSM2 option, you cannot use PCM.') +} +if (!is.null(RSM2) & length(DIM)==1) { + stop('Error 198: You cannot use RSM2 if you simulate only one dimension.') +} +if (is.null(ID)) { + ID <- 'ID' +} + + +##### ParamĂštres + +hour <- as.numeric(substr(Sys.time(),12,13)) +minu <- as.numeric(substr(Sys.time(),15,16)) +sec <- as.numeric(substr(Sys.time(),18,19)) +jour <- as.numeric(substr(Sys.Date(),9,10)) + +s <- 256484+1000000*sec+10000*minu+100*hour+jour +set.seed(s) +while(s>2^31-1) { + s <- s/231 +} +set.seed(s) + +if (typediff=='uniform') { + min <- c() + max <- c() + if (nbdiff %/% (2*length(DIM))==1) { + min <- DIF[(1:length(DIM)-1)*2+2] + max <- DIF[(1:length(DIM)-1)*2+3] + } + else if (nbdiff==1) { + min <- rep(-2,length(DIM)) + max <- rep(2,length(DIM)) + } + else { + stop('Your DIF option is incorrect. Please correct.') + } + for (d in seq(1,length(DIM))) { + for (i in seq(1,DIM[d])) { + DIF <- c(DIF, min[d]+(max[d]-min[d])*i/(DIM[d]+1) ) # Pas compris, demander Ă  JB + } + } +} + +else if (typediff=='gauss') { + meang <- c() + varg <- c() + if (nbdiff %/% (2*length(DIM))==1) { + for (d in seq(1,length(DIM))) { + meang[d] <- DIF[(d-1)*2+2] + varg[d] <- DIF[(d-1)*2+3] + } + } + else if (nbdiff == 1) { + meang <- rep(0,length(DIM)) + varg <- rep(1,length(DIM)) + } + else { + stop('Error 198: Your DIF option is incorrect. Please correct.') + } + for (d in seq(1,length(DIM))) { + for (i in seq(1,DIM[d])) { + tmp <- qnorm(p=i/(DIM[d]+1))*sqrt(varg[d])+meang[d] + DIF <- c(DIF, tmp) + } + } + +} + +nbrsm <- c() +for (d in 1:2) { + if (!is.null(get(paste0('RSM',d)))) { + nbrsm[d] <- length(get(paste0('RSM',d))) + for (i in seq(2,nbrsm[d]+1)) { + rsm[[d]][i] <- get(paste0("RSM",d))[i-1] # RSM doit etre une liste de vecteurs + if (!is.null(THR) & rsm[[d]][i]<0) { + stop('Error 198: With the THR option, the numbers defined in RSM1 and RSM2 must nonnegative') + } + } + } +} + +if (!is.null(DIF) & is.null(PCM)) { + PCM <- as.matrix(DIF) +} + +matdiff <- as.matrix(rep(0,nbitems)) +matdisc <- as.matrix(rep(0,nbitems)) +matpmin <- as.matrix(rep(0,nbitems)) +matpmax <- as.matrix(rep(0,nbitems)) +matacc <- as.matrix(rep(0,nbitems)) +matmu <- as.matrix(rep(0,length(DIM))) +matmu <- as.matrix(rep(0,(length(DIM)+1)*length(DIM)/2 )) + +if (nbdisc !=0) { + matdisc <- as.matrix(DISC) +} +else { + matdisc <- rep(1,nbitems) +} + + + + + +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..d1dbd0f --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# ROSALI-SIM + +Simulations visant Ă  l'Ă©valuation des performances de dĂ©tection des items affectĂ©s par le DIF pour l'algorithme ROSALI, en faisant varier sa composition. + +## Conventions de nomenclature + +### Versions ROSALI + +**noLRT** - pas de test de rapport de vraisemblance avant l'Ă©tape C +**noBF** - pas de correction de Bonferroni Ă  l'Ă©tape C +**noLRT_noBF** - ni LRT, ni Bonferroni +**original** - version originale de ROSALI (LRT + Bonferroni) + +### Jeux de donnĂ©es initiaux + +**XX_N** - ScĂ©narios issus de corentinchoisy/simul_these analysĂ©s, N sujets par groupe + +### Jeux de donnĂ©es analysĂ©s + +**XX_N_noLRT** - Analyse du scĂ©nario XX_N avec la version noLRT +**XX_N_noBF** - Analyse du scĂ©nario XX_N avec la version noBF +**XX_N_noLRT_noBF** - Analyse du scĂ©nario XX_N avec la version noLRT_noBF +**XX_N_original** - Analyse du scĂ©nario XX_N avec la version originale diff --git a/catalogue.md b/catalogue.md new file mode 100644 index 0000000..a04cd6d --- /dev/null +++ b/catalogue.md @@ -0,0 +1,30 @@ +## Scenarios avec DIF + + | | **J** || **M** || **Nb items DIF** ||| **Taille DIF** || + |------------|---|---|---|---|---|---|---|---|---| + | | **4** | **7** | **2** | **4** | **1** | **2** | **3** | **0.3** | **0.5** | + | **Scenario 5** | X | | X | | X | | | X | | + | **Scenario 6** | X | | | X | X | | | X | | + | **Scenario 7** | X | | X | | X | | | | X | + | **Scenario 8** | X | | | X | X | | | | X | + | **Scenario 9** | X | | X | | | X | | X | | + | **Scenario 10** | X | | | X | | X | | X | | + | **Scenario 11** | X | | X | | | X | | | X | + | **Scenario 12** | X | | | X | | X | | | X | + | **Scenario 13** | | X | X | | | X | | X | | + | **Scenario 14** | | X | | X | | X | | X | | + | **Scenario 15** | | X | X | | | X | | | X | + | **Scenario 16** | | X | | X | | X | | | X | + | **Scenario 17** | | X | X | | | | X | X | | + | **Scenario 18** | | X | | X | | | X | X | | + | **Scenario 19** | | X | X | | | | X | | X | + | **Scenario 20** | | X | | X | | | X | | X | + +Chaque scĂ©nario est sĂ©parĂ© en 3 sous-scĂ©narios: + + * A - H<sub>0</sub> vraie, DIF -0.3/0.5 sur le groupe **traitement** + * **Exemple MPR / rĂ©adaptation:** + * B - H<sub>1</sub> vraie, taille d'effet 0.2, DIF +0.3/0.5 sur le groupe traitement + * **Exemple BDI** + * C - H<sub>1</sub> vraie, taille d'effet 0.2, DIF -0.3/0.5 sur le groupe traitement + * **Exemple dentaire**