You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2116 lines
76 KiB
Plaintext

7 months ago
*! 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