diff --git a/Modules/gengroup.ado b/Modules/gengroup.ado new file mode 100644 index 0000000..c4d8e02 --- /dev/null +++ b/Modules/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/genscore.ado b/Modules/genscore.ado new file mode 100644 index 0000000..e3164e4 --- /dev/null +++ b/Modules/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/pcm.ado b/Modules/pcm.ado new file mode 100644 index 0000000..ec43d62 --- /dev/null +++ b/Modules/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/Scripts/Analysis/NoDIF/pcm_nodif_100.do b/Scripts/Analysis/NoDIF/pcm_nodif_100.do new file mode 100644 index 0000000..9814b27 --- /dev/null +++ b/Scripts/Analysis/NoDIF/pcm_nodif_100.do @@ -0,0 +1,43 @@ +*================================================================================================================================================= +* Date : 2024-01-23 +* Stata version : Stata 18 SE +* +* This program analyses simulated data without DIF through a partial credit model +* +* ado-files needed : - pcm (version 5.5 October 25, 2023, available on gitea) +* + * outputs : for N=100 +* +* +*================================================================================================================================================ + +* Load pcm.ado +adopath+"/home/corentin/Documents/These/Recherche/Simulations/Modules/" + +* Set output folder path +local path_data = "/home/corentin/Documents/These/Recherche/Simulations/Data/NoDIF/N100" +local path_res = "/home/corentin/Documents/These/Recherche/Simulations/Analysis/NoDIF/N100" +local Nn = 100 + + +*========================== +* Scenarios with : J=4 +*========================== + +** Scenario 1: J = 4 items / M = 2 modalities + +* Scenario 1A : H_0 is TRUE + +clear +import delim "`path_data'/scenario_1A_100.csv", encoding(ISO-8859-2) case(preserve) clear +rename TT tt + +preserve +keep if replication==1 +gsem (1.item1<-THETA@1)/// + (1.item2<-THETA@1)/// + (1.item3<-THETA@1)/// + (1.item4<-THETA@1)/// + (THETA<-tt), mlogit tol(0.01) iterate(500) latent(THETA) nocapslatent + +pcm item1 item2 item3 item4, categorical(tt)