Computed theoretical power for N=100 and N=200 scenarios

This commit is contained in:
2024-02-19 18:35:26 +01:00
parent ac9189d26a
commit 238852b08b
704 changed files with 261610 additions and 187 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,986 @@
*! Version 3.4 23August2019
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : pcm
* Estimate the parameters of the Partial Credit Model
* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
*
*
*
* Jean-benoit Hardouin - University of Nantes - France
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2007, 2011, 2013, 2014, 2019 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define pcm, rclass
syntax varlist(min=2 numeric) [iweight] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(name) GENINF(name) postpce]
qui count
local nbobs=r(N)
/*************************************************************************************************************
GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
*************************************************************************************************************/
local modcont
local nbpar=0
local nbcont=0
local nbcat=0
if "`continuous'"!="" {
tokenize `continuous'
local nbcont : word count `continuous'
local continuous
forvalues i=1/`nbcont' {
local cont`i' ``i''
local continuous `continuous' ``i''
local modcont `modcont' ``i''
local ++nbpar
}
local modcont (`modcont'->T)
}
local modcat
if "`categorical'"!="" {
tokenize `categorical'
local nbcat : word count `categorical'
local categorical
forvalues i=1/`nbcat' {
local cat`i' ``i''
local categorical `categorical' ``i''
local modcat `modcat' i.``i''
qui levelsof ``i''
local levelsof``i'' `r(levels)'
local nbpar=`nbpar'+`r(r)'-1
*di "categorical : ``i'' levels : `levelsof``i'''"
}
local modcat (`modcat'->T)
}
if "`dirsave'"=="" {
local dirsave `c(pwd)'
}
if "`genlt'"!=""|"`geninf'"!="" {
capture confirm new variable `genlt' se`genlt' `geninf'
if _rc!=0 {
di in red "The variables `genlt', se`genlt' and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
exit 198
}
}
/*************************************************************************************************************
GESTION DES ITEMS ET TESTS
*************************************************************************************************************/
tokenize `varlist'
local nbitems : word count `varlist'
marksample touse ,novarlist
*preserve
local modamax=1
local modamin=0
local pbmin
local nbdiff=0
forvalues i=1/`nbitems' {
qui su ``i''
if `r(min)'!=`modamin' {
local modamin=r(min)
local pbmin `pbmin' ``i''
}
if `r(max)'>`modamax' {
local modamax=r(max)
}
local modamax``i''=r(max)
if "`rsm'"=="" {
local nbdiff=`nbdiff'+`modamax``i'''
}
}
if "`rsm'"!="" {
local nbdiff=`nbitems'+`modamax'-1
}
if `modamin'!=0 {
di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
error 198
}
qui count
local nbind=r(N)
*set trace on
local code
forvalues k=1/`modamax' {
local code`k'
forvalues i=1/`nbitems' {
if `k'<=`modamax``i''' {
local code`k' `code`k'' `k'.``i''
}
}
local code`k' (`code`k''<-T@`k')
local code `code' `code`k''
}
/*************************************************************************************************************
OPTION PCE
*************************************************************************************************************/
if "`pce'"!=""&"`difficulties'"=="" {
tempname sedelta b
qui raschpce `varlist'
local ll=r(ll)
matrix `sedelta'=r(sedelta)
matrix `sedelta'=`sedelta''
matrix `b'=r(b)
*matrix `b'=`b''
local difficulties `b'
*matrix list `b'
matrix loulou=`b'
return matrix diff_parm=`b'
`qui' pcm `varlist', diff(loulou) geninf(TInf_0) genlt(lt_0) /*postpce*/
*exit
}
/*************************************************************************************************************
RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
*************************************************************************************************************/
if "`difficulties'"!=""&"`rsm'"!="" {
di as error "You can not defined in the same time the difficulties and the rsm options"
error 198
}
if "`difficulties'"!="" {
tempname beta
matrix `beta'=J(`nbitems',`modamax',.)
local t=1
local constraints
matrix list `difficulties'
forvalues i=1/`nbitems' {
forvalues k=1/`modamax``i''' {
if `difficulties'[`i',`k']==. {
di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
error 198
}
else {
if `k'==1 {
matrix `beta'[`i',1]=-`difficulties'[`i',1]
}
else {
matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
}
constraint `t' [`k'.``i'']_cons=`beta'[`i',`k']
local constraints `constraints' `t'
local ++t
}
}
}
}
/*************************************************************************************************************
DEFINITION DES CONTRAINTES POUR UN RSM
*************************************************************************************************************/
if "`rsm'"!="" {
local t=1
local constraints
forvalues k=2/`modamax' {
forvalues i=2/`nbitems' {
constraint `t' [`=`k'-1'.``i'']_cons-[`k'.``i'']_cons+[1.``i'']_cons=[`=`k'-1'.`1']_cons-[`k'.`1']_cons+[1.`1']_cons
local constraints `constraints' `t'
local ++t
}
}
}
/*************************************************************************************************************
MODELE
*************************************************************************************************************/
discard
*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')"
local qui qui
if "`model'"!="" {
local qui
}
`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')
local ll=e(ll)
*set trace on
tempvar latent score group selatent latent2
tempname groups
*capture qui predict mu, mu
*su mu
qui predict `latent',latent se(`selatent')
if "`genlt'"!="" {
gen `genlt'=`latent'
gen se`genlt'=`selatent'
}
set seed 123456
qui gen `latent2'=`latent'+invnorm(uniform())*`selatent'
qui genscore `varlist',score(`score')
qui gengroup `latent',newvariable(`group') continuous
qui levelsof `group'
local nbgroups=r(r)
matrix `groups'=J(`nbgroups',`=`nbitems'+3',.)
forvalues g=1/`nbgroups' {
matrix `groups'[`g',`=`nbitems'+3']=0
forvalues i=1/`nbitems' {
*tab ``i'' if `group'==`g'
qui count if ``i''!=.&`group'==`g'
local n=r(N)
if `n'>0 {
qui su ``i'' if `group'==`g'
matrix `groups'[`g',`i']=r(mean)
matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
}
else {
matrix `groups'[`g',`i']=.
matrix `groups'[`g',`=`nbitems'+3']=.
}
}
qui su `latent' if `group'==`g'
matrix `groups'[`g',`=`nbitems'+1']=r(mean)
qui count if `group'==`g'
matrix `groups'[`g',`=`nbitems'+2']=r(N)
}
*matrix list `groups'
qui count if `score'!=.
local nbobsssmd=r(N)
di
di as text "Number of individuals:" %6.0f as result `nbobs'
di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
di as text "Number of items:" %6.0f as result `nbitems'
di as text "Marginal log-likelihood:" %12.4f as result `ll'
di
return scalar ll=`ll'
*set trace on
/*************************************************************************************************************
RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
*************************************************************************************************************/
tempname diff diffmat vardiff diffmat2
*set trace on
qui matrix `diffmat'=J(`nbitems',`modamax',.)
qui matrix `diffmat2'=J(`nbitems',`modamax',.)
qui matrix `diff'=J(`nbdiff',6,.)
local rn
*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
*matrix list `diff'
*set trace on
local t=1
forvalues i=1/`nbitems' {
qui matrix `diffmat'[`i',1]=-_b[1.``i'':_cons]
qui matrix `diffmat2'[`i',1]=-_b[1.``i'':_cons]
qui lincom -_b[1.``i'':_cons]
qui matrix `diff'[`t',1]=`r(estimate)'
qui matrix `diff'[`t',2]=`r(se)'
qui matrix `diff'[`t',3]=`r(z)'
qui matrix `diff'[`t',4]=`r(p)'
qui matrix `diff'[`t',5]=`r(lb)'
qui matrix `diff'[`t',6]=`r(ub)'
*qui matrix `vardiff'[`t',`t']=_se[1.``i'':_cons]^2
local rn `rn' 1.``i''
local ++t
local sum _b[1.``i'':_cons]
if "`rsm'"=="" {
forvalues k=2/`modamax``i''' {
local sum "_b[`k'.``i'':_cons]-(`sum')"
di "``i'' `k' `sum'"
local sum2 "_b[`=`k'-1'.``i'':_cons]-_b[`k'.``i'':_cons]"
qui lincom (`sum2')
*set trace on
qui matrix `diffmat'[`i',`k']=`r(estimate)'
qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
qui matrix `diff'[`t',1]=`r(estimate)'
qui matrix `diff'[`t',2]=`r(se)'
qui matrix `diff'[`t',3]=`r(z)'
qui matrix `diff'[`t',4]=`r(p)'
qui matrix `diff'[`t',5]=`r(lb)'
qui matrix `diff'[`t',6]=`r(ub)'
*qui matrix `vardiff'[`t',`t']=`r(se)'^2
*set trace off
local rn `rn' `k'.``i''
local ++t
}
}
}
if "`rsm'"!="" {
forvalues k=2/`modamax' {
qui lincom _b[`=`k'-1'.`1':_cons]-_b[`k'.`1':_cons]+_b[1.`1':_cons]
qui matrix `diff'[`t',1]=`r(estimate)'
qui matrix `diff'[`t',2]=`r(se)'
qui matrix `diff'[`t',3]=`r(z)'
qui matrix `diff'[`t',4]=`r(p)'
qui matrix `diff'[`t',5]=`r(lb)'
qui matrix `diff'[`t',6]=`r(ub)'
forvalues i=1/`nbitems' {
qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
}
local rn `rn' tau`k'
local ++t
}
}
local cn Estimate S.e. z p "Lower bound" "Upper Bound"
matrix colnames `diff'=`cn'
matrix rownames `diff'=`rn'
*matrix list `diff'
*matrix list `diffmat'
*matrix list `diffmat2'
*matrix list `vardiff'
/*************************************************************************************************************
RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES ET LA VARIANCE
*************************************************************************************************************/
tempname covariates
qui matrix `covariates'=J(`=`nbpar'+1',6,.)
*set trace on
if "`continuous'"!=""|"`categorical'"!="" {
qui lincom _b[/var(e.T)]
}
else {
qui lincom _b[/var(T)]
}
qui matrix `covariates'[1,1]=`r(estimate)'
qui matrix `covariates'[1,2]=`r(se)'
qui matrix `covariates'[1,3]=`r(z)'
qui matrix `covariates'[1,4]=`r(p)'
qui matrix `covariates'[1,5]=`r(lb)'
qui matrix `covariates'[1,6]=`r(ub)'
local t=2
forvalues i=1/ `nbcont' {
qui lincom `cont`i''
qui matrix `covariates'[`t',1]=`r(estimate)'
qui matrix `covariates'[`t',2]=`r(se)'
qui matrix `covariates'[`t',3]=`r(z)'
qui matrix `covariates'[`t',4]=`r(p)'
qui matrix `covariates'[`t',5]=`r(lb)'
qui matrix `covariates'[`t',6]=`r(ub)'
local ++t
}
forvalues i=1/ `nbcat' {
local first=0
foreach j in `levelsof`cat`i''' {
if `first'==0 {
local ++first
}
else {
qui lincom `j'.`cat`i''
qui matrix `covariates'[`t',1]=`r(estimate)'
qui matrix `covariates'[`t',2]=`r(se)'
qui matrix `covariates'[`t',3]=`r(z)'
qui matrix `covariates'[`t',4]=`r(p)'
qui matrix `covariates'[`t',5]=`r(lb)'
qui matrix `covariates'[`t',6]=`r(ub)'
local ++t
}
}
}
* matrix list `covariates'
/*************************************************************************************************************
OUTPUTS
*************************************************************************************************************/
if "`postpce'"=="" {
local t=1
local diffname
*set trace on
di "{hline 73}"
di as text _col(60) "<--95% IC -->"
di "Items" _col(60) "Lower" _col(68) "Upper"
di "parameters" _col(13) "category" _col(25) "Estimate" _col(37) "s.e." _col(48) "z" _col(56) "p" _col(59) " Bound" _col(68) "Bound"
di "{hline 73}"
*set trace on
forvalues i=1/`nbitems' {
*local l=1
forvalues j=1/`modamax``i''' {
if "`rsm'"==""|`j'==1 {
if `j'==1 {
di as text abbrev("``i''",19) _c
}
di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `diff'[`t',1] _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6]
local ++t
*local ++l
local diffname `diffname' `j'.``i''
}
}
}
if "`rsm'"!="" {
forvalues k=2/`modamax' {
di as text "tau`k'" as result _col(28) %5.2f `diff'[`t',1] _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6]
local diffname `diffname' tau`k'
local ++t
}
}
di as text "{hline 73}"
local t=1
local n: word count Variance `continuous'
forvalues i=1/`n' {
local v: word `i' of Variance `continuous'
di as text _col(1) %5.2f "`v'" as result _col(28) %5.2f `covariates'[`t',1] _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6]
local ++t
}
local rn Variance `continuous'
local n: word count of `categorical'
local catname
forvalues i=1/`n' {
local v: word `i' of `categorical'
local first=1
local saute=1
foreach j in `levelsof`cat`i''' {
if `saute'==0 {
if `first'==1 {
di as text _col(1) abbrev("`v'",19) _c
}
di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `covariates'[`t',1] _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6]
local ++first
local rn `rn' `j'.`n'
local ++t
local catname `catname' `j'.`v'
}
else {
local saute=0
}
}
local ++t
}
di as text "{hline 73}"
di
qui su `latent'
qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])^2)
di as text "PSI:" as result %4.2f `PSI'
di
matrix colnames `covariates'=`cn'
matrix rownames `covariates'=`rn'
}
/*************************************************************************************************************
FIT TESTS
*************************************************************************************************************/
tempname fit
qui matrix `fit'=J(`nbitems',4,.)
matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
matrix rownames `fit'=`varlist'
*matrix list `fit'
tempvar Tcum TInf cum
qui gen `Tcum'=0
qui gen `TInf'=0
if "`postpce'"=="" {
di as text "{hline 90}"
di as text _col(60) "<--- Standardized --->"
di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
di as text "{hline 90}"
di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
di as text "{hline 90}"
}
*set trace on
local chi2=0
local chi2_old=0
forvalues g=1/`nbgroups' {
local chi2_g`g'=0
local chi2_old_g`g'=0
}
forvalues i=1/`nbitems' {
if "`rsm'"=="" {
local mm=`modamax``i'''
}
else {
local mm `modamax'
}
tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''
tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i''
local d=1
local d_old=1
qui gen `cum``i'''=0
qui gen `cum_old``i'''=0
forvalues k=1/`mm' {
local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
}
qui gen `c0_``i'''=1/(`d')
qui gen `c_old0_``i'''=1/(`d_old')
forvalues k=1/`mm' {
tempvar c`k'_``i'' c_old`k'_``i''
qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
}
qui gen `Inf``i'''=0
qui gen `Inf_old``i'''=0
qui gen `C``i'''=0
forvalues k=0/`mm' {
qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
}
qui count if ``i''!=.
local n``i''=r(N)
qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
qui su `C2``i'''
local q2o``i''=(`r(mean)'-1)/((`n``i'''))
qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
qui su `C3``i'''
local n=r(sum)
qui su `Inf``i'''
local d=r(sum)
local q2i``i''=`n'/((`d')^2)
//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
qui replace `Tcum'=`Tcum'+`cum``i'''
qui replace `TInf'=`TInf'+`Inf``i'''
qui gen `y``i'''=``i''-`cum``i'''
qui gen `y_old``i'''=``i''-`cum_old``i'''
qui gen `y2``i'''=(`y``i''')^2
qui gen `y2_old``i'''=(`y_old``i''')^2
qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
local chi2_``i''=0
local chi2_old_``i''=0
forvalues g=1/`nbgroups' {
qui su `y2``i''' if `group'==`g'
local n=r(sum)
qui su ``i'' if `group'==`g'
local n1=r(sum)
qui su `cum``i''' if `group'==`g'
local n2=r(sum)
qui su `Inf``i''' if `group'==`g'
local d=r(sum)
*di "chi2_`g'_``i''=`chi2'+(`n1'-`n2')^2/(`d')"
local chi2=`chi2'+(`n1'-`n2')^2/(`d')
local chi2_``i''=`chi2_``i'''+(`n1'-`n2')^2/(`d')
local chi2_g`g'=`chi2_g`g''+(`n1'-`n2')^2/(`d')
qui su `y2_old``i''' if `group'==`g'
local n_old=r(sum)
qui su ``i'' if `group'==`g'
local n1_old=r(sum)
qui su `cum_old``i''' if `group'==`g'
local n2_old=r(sum)
qui su `Inf_old``i''' if `group'==`g'
local d_old=r(sum)
local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
}
*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2' Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
*su `z``i'''
label variable `z``i''' "Standardized residuals associated to ``i''"
label variable `latent' "Latent trait"
*set trace on
if "`graphs'"!=""&"`graphitems'"=="" {
if "`filesave'"!="" {
local fs saving("`dirsave'//residuals_``i''",replace)
}
qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
}
*set trace off
qui gen `z2``i'''=(`z``i''')^2
qui su `z2``i'''
local OUTFIT``i''=`r(mean)'
qui matrix `fit'[`i',1]=`OUTFIT``i'''
local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
qui matrix `fit'[`i',3]=`OUTFITs``i'''
qui su `Inf``i''' if ``i''!=.
local sumw``i''=r(sum)
qui gen `i``i'''=`Inf``i'''*`z2``i'''
qui su `i``i''' if ``i''!=.
local INFIT``i'' = `=`r(sum)'/`sumw``i''''
qui matrix `fit'[`i',2]=`INFIT``i'''
local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
qui matrix `fit'[`i',4]=`INFITs``i'''
if "`postpce'"=="" {
di abbrev("``i''",19) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i'''
}
}
if "`postpce'"=="" {
di as text "{hline 90}"
di as text "*: As suggested by Wright (Smith, 1998)
di as text "**: As suggested by Bond and Fox (2007)
}
if "`geninf'"!="" {
gen `geninf'=`TInf'
}
*set trace off
/*************************************************************************************************************
ESTIMATION OF THE WEIGHTED ML ESTIMATORS
**************************************************************************************************************/
*set trace on
*di "estimation `wmliterate'"
if "`postpce'"!="" {
local conv=10
local it=`wmliterate'
di "Iteration : `it'"
while(`conv'>=1) {
di "Itération `it' : conv=`conv'"
tempvar sinf
qui gen `sinf'=sqrt(TInf_`=`it'-1')
`qui' pcm `varlist' [iweight=`sinf'],diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it')
tempvar ecart_`it'
qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1')
qui su `ecart_`it''
local conv =r(mean)
local ++it
}
exit
}
/*************************************************************************************************************
Categories/Items/Test Characteristics Curves and Information graphs
*************************************************************************************************************/
if "`graphs'"!="" {
tempfile savefile
qui save `savefile'
qui clear
qui set obs 2000
qui gen u=(_n-1000)/250
qui gen Tcum=0
qui gen TInf=0
forvalues i=1/`nbitems' {
local scatteri`i'
forvalues g=1/`nbgroups' {
local x=`groups'[`g',`=`nbitems'+1']
local y=`groups'[`g',`i']
local s1=`groups'[`g',`=`nbitems'+2']
local seuil=30
local s vtiny
*set trace on
foreach lab in tiny vsmall small medsmall medium medlarge large vlarge huge vhuge /*ehuge*/ {
if `s1'>`seuil' {
local s `lab'
}
local seuil=`seuil'+10
}
local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
*set trace off
}
local d=1
qui gen cum``i''=0
*set trace on
if "`rsm'"=="" {
local mm=`modamax``i'''
}
else {
local mm `modamax'
}
forvalues k=1/`mm' {
local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
}
qui gen c0_``i''=1/(`d')
label variable c0_``i'' "Pr(``i''=0)"
forvalues k=1/`mm' {
qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
qui replace cum``i''=cum``i''+c`k'_``i''*`k'
label variable c`k'_``i'' "Pr(``i''=`k')"
}
qui gen Inf``i''=0
forvalues k=1/`mm' {
qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
}
if "`graphitems'"=="" {
if "`filesave'"!="" {
local fsc saving("`dirsave'//CCC_``i''",replace)
local fsi saving("`dirsave'//ICC_``i''",replace)
}
qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
}
qui replace Tcum=Tcum+cum``i''
qui replace TInf=TInf+Inf``i''
label variable Inf``i'' "``i''"
}
if "`filesave'"!="" {
local fst saving("`dirsave'//TCC",replace)
local fsteo saving("`dirsave'//TCCeo",replace)
local fsi saving("`dirsave'//ICC",replace)
local fsti saving("`dirsave'//TIC",replace)
local fsm saving("`dirsave'//map",replace)
}
qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait") `fsi'
qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait") `fsti'
local scatteri
forvalues g=1/`nbgroups' {
local x=`groups'[`g',`=`nbitems'+1']
local y=`groups'[`g',`=`nbitems'+3']
local s1=`groups'[`g',`=`nbitems'+2']
local seuil=30
local s vtiny
*set trace on
foreach lab in tiny vsmall small medsmall medium medlarge large vlarge huge vhuge /*ehuge*/ {
if `s1'>`seuil' {
local s `lab'
}
local seuil=`seuil'+10
}
local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
}
qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
/*************************************************************************************************************
MAP
*************************************************************************************************************/
*set trace on
gen eff=0
local effmax=0
forvalues g=1/`nbgroups' {
local eff=`groups'[`g',`=`nbitems'+2']
if `groups'[`g',`=`nbitems'+2']>`effmax' {
local effmax=`groups'[`g',`=`nbitems'+2']
}
local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
*di "replace eff=`eff' if round(u,0.004)==`lat'"
qui replace eff=`eff' if round(u,0.004)==`lat'
}
gen density=normalden(u)*sqrt(`covariates'[1,1])
label variable eff "Frequencies"
label variable u "Latent trait"
label variable TInf "Information curve"
label variable density "Density function of the latent trait"
local scatteri
qui su u if eff!=0
*set trace on
local floor=floor(`r(min)')
local ceil=ceil(`r(max)')
forvalues i=1/`nbitems' {
local color`i':word `i' of `color'
local y=-`i'*`effmax'/`nbitems'
forvalues l=1/`modamax' {
local x=`diffmat'[`i',`l']
local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
if `x'<`floor' {
local floor=floor(`x')
}
if `x'>`ceil'&`x'!=. {
local ceil=ceil(`x')
}
}
local scatteri `scatteri' || scatteri `y' `floor' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
}
qui su eff
local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
qui su TInf
local maxi=ceil(`r(max)')
qui su density
local maxd=ceil(`r(max)')
qui drop if u<`floor'|u>`ceil'
qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(`floor'(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3)) `scatteri' , name(map,replace) ytitle("Frequencies") ylabel(-`maxi'(`=`maxi'/5')`maxi' ,axis(2)) ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait") xtitle("Latent trait") `fsm'
qui clear
qui use `savefile'
}
/*************************************************************************************************************
RESULTS BY GROUP
*************************************************************************************************************/
di
di as text "{hline 57}"
di _col(31) "Latent Variable" _col(50) "Expected"
di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score"
di as text "{hline 57}"
*set trace on
forvalues g=1/`nbgroups' {
qui count if `group'==`g'
local eff`g'=r(N)
qui count if `score'!=.&`group'==`g'
local n=r(N)
di as text "`g' (n=" as result `eff`g'' as text ")" _c
if `n'>0 {
qui su `score' if `group'==`g'
local scoremin`g'=`r(min)'
local scoremax`g'=`r(max)'
forvalues s=`scoremin`g''/`scoremax`g'' {
qui count if `group'==`g'&`score'==`s'
local eff=r(N)
qui su `latent' if `group'==`g'&`score'==`s'
local mean=r(mean)
qui su `selatent' if `group'==`g'&`score'==`s'
local se=r(mean)
qui su `Tcum' if `group'==`g'&`score'==`s'
local exp=r(mean)
if `eff'>0 {
di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
}
}
}
qui count if `group'==`g'&`score'==.
local eff=r(N)
qui su `latent' if `group'==`g'&`score'==.
local mean=r(mean)
qui su `selatent' if `group'==`g'&`score'==.
local se=r(mean)
qui su `Tcum' if `group'==`g'&`score'==.
local exp=r(mean)
if `eff'>0 {
di as text _col(10) " ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
}
di as text "{hline 57}"
}
/*************************************************************************************************************
CREATION DU DOCX
*************************************************************************************************************/
if "`docx'"!="" {
putdocx clear
putdocx begin
putdocx paragraph
putdocx text ("General informations") , bold underline font(,14) smallcaps
putdocx paragraph
putdocx text ("Number of individuals: `nbobs'")
putdocx paragraph
putdocx text ("Number of complete individuals: `nbobsssmd'")
putdocx paragraph
putdocx text ("Number of items: `nbitems'")
putdocx paragraph
putdocx text ("List of items: `varlist'")
putdocx paragraph
putdocx text ("Date: $S_DATE, $S_TIME")
putdocx paragraph
local model Partial Credit Model (PCM)
if "`rsm'"!="" {
local model Rating Scale Model (RSM)
}
putdocx text ("Model: `model'")
putdocx paragraph
putdocx text ("Marginal log-likelihood: `ll'")
putdocx paragraph
putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)
qui putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)
putdocx paragraph
putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
qui putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)
local extension png
}
/*************************************************************************************************************
SAUVEGARDE DES GRAPHIQUES
*************************************************************************************************************/
*set trace on
if "`filesave'"!="" {
if "`graphs'"!="" {
if "`docx'"!="" {
putdocx pagebreak
putdocx paragraph
putdocx text ("General graphs") , bold underline font(,14) smallcaps
}
foreach i in TCC TCCeo TIC IIC map {
if "`extension'"!="" {
qui graph export "`dirsave'//`i'.`extension'", replace name(`i')
}
*graph display `i'
*qui graph save "`dirsave'//`i'", replace
if "`docx'"!="" {
putdocx paragraph
putdocx image "`dirsave'//`i'.png", height(10cm)
}
}
*discard
if "`graphitems'"=="" {
forvalues i=1/`nbitems' {
if "`docx'"!="" {
putdocx paragraph
putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
}
foreach j in CCC ICC residuals {
*graph display `j'``i''
*qui graph save "`dirsave'//`j'_``i''", replace
if "`extension'"!="" {
qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'')
}
if "`docx'"!="" {
putdocx paragraph
putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
}
}
}
}
}
}
if "`docx'"!="" {
putdocx save "`dirsave'//`docx'.docx", replace
}
/*************************************************************************************************************
RETURNS
*************************************************************************************************************/
matrix colnames `diff'=Estimate "s.e." z p lb ul
matrix colnames `covariates'=Estimate "s.e." z p lb ul
matrix rownames `diff'=`diffname'
matrix rownames `covariates'=Variance `continuous' `catname'
return matrix difficulties=`diff'
return matrix covariates=`covariates'
capture restore, not
end

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,167 @@
{smcl}
{* 2August2022}{...}
{hline}
help for {hi:pcm}{right:Jean-Benoit Hardouin, Myriam Blanchin}
{hline}
{title:Estimation of the parameters of a Partial Credit Model (PCM) or a Rating Scale Model (RSM) and specific graphs}
{title:Syntax for Rasch analysis}
{p 8 14 2}{cmd:pcm} {it:varlist} [{it:if}] [{it:in}]
[, {cmdab:rsm} {cmdab:it:erate}({it:#}) {cmdab:model} {cmdab:diff:iculties}({it:matrix}) {cmdab:var:iance}({it:real}) {cmdab:minsize}({it:#})
{cmdab:cont:inuous}({it:varlist}) {cmdab:cat:egorical}({ir:varlist})
{cmdab:G:raphs} {cmdab:nographi:tems} {cmdab:dim:name}({it:string}) {cmdab:nocorr:ected} {cmdab:alpha}({it:#})
{cmdab:filesave} {cmdab:extension}({it:string}) {cmdab:dirsave}({it:directory} {cmdab:docx}({it:string})
{cmdab:genlt}({it:string}) {cmdab:geninf}({it:string}) {cmdab:rep:lace}
{title:Syntax for Rasch equating}
{p 8 14 2}{cmd:pcm} {it:varlist} [{it:if}] [{it:in}] [, {cmdab:rsm} {cmdab:it:erate}({it:#}) {cmdab:model} {cmdab:diff:iculties}({it:matrix}) {cmdab:var:iance}({it:real}) {cmdab:minsize}({it:#}) {cmdab:G:raphs} {cmdab:dim:name}({it:string}) {cmdab:eqset1}({it:varlist}) {cmdab:eqset2}({it:varlist}) {cmdab:eqset1name}({it:string}) {cmdab:eqset2name}({it:string}) {cmdab:EQG:raph} {cmdab:eqaddset1}({it:#}) {cmdab:eqaddset2}({it:#}) {cmdab:eqmultset1}({it:#) {cmdab:eqmultset2}({it:#})
{cmdab:eqwithci} {cmdab:eqgenscore}({it:string}) {cmdab:rep:lace} ]
{p 8 14 2}{it:varlist} is a list of two existing categorical variables or more.
{title:Description}
{p 4 8 2}{cmd:pcm} estimates the parameters of a Partial Credit Model (PCM) or of a Rating Scale Model (RSM). Parameters are estimated using Marginal Maximum Likelihood (MML). Several graphical representations can be easily obtained: comparison of the observed and theorical Item Characteristic Curves (ICC), Map difficulty parameters/Scores, results of the split tests, and information function (for the scale and by item). {cmd:pcm} allow equating two sets of items.
{title:Options for a Rasch analysis}
{p 4 8 2}{cmdab:rsm} estimates a Rating Scale Model instead of a Partial Credit Model.
{p 4 8 2}{cmdab:it:erate} defines the maximal number of iterations of the maximisation algorithm.
By default, this number is fixed to 100.
{p 4 8 2}{cmd:model} displays the outputs of the maximisation alogorithm .
{p 4 8 2}{cmdab:diff:iculties}({it:matrix}) fixes the values of the difficulties parameters of the items (by default, these values are estimated).
The vector must be a matrix containing as many rows as items, and a column for each threshold parameter (number of answer categories minus 1).
A missing value (.) replaces unexisting difficulty paremeters in the matrix.
{p 4 8 2}{cmdab:var:iance}({it:#}) fixes the value of the variance of the latent trait (by default, this value is estimated).
{p 4 8 2}{cmdab:minsize}({it:#}) fixes the minimal value of the groups (30 individuals by default).
{p 4 8 2}{cmdab:cont:inuous}({it:varlist}) defines a list of continuous variables explaining the latent trait.
{p 4 8 2}{cmdab:cat:egorical}({it:varlist}) defines a list of categorical variables explaining the latent trait.
{p 4 8 2}{cmdab:G:raphs} displays the graphs.
{p 4 8 2}{cmdab:nographi:tems} avoids displaying the graphs by items.
{p 4 8 2}{cmdab:dim:name}({it:string}) defines the name of the analysed dimension (this name appears on the graphs).
{p 4 8 2}{cmdab:nocorr:ected} avoids using corrected latent trait estimates on the graphs.
{p 4 8 2}{cmdab:alpha}({it:#}) defines the level of confidence of the interval presented on the graphs of residuals.
{p 4 8 2}{cmdab:filesave} save the graph files.
{p 4 8 2}{cmdab:extension}({it:string}) defines the extension of the graph files.
{p 4 8 2}{cmdab:dirsave}({it:directory} defines the directory to save the graph files and the docx file.
{p 4 8 2}{cmdab:docx}({it:string}) creates a docx file with the main results and graphs.
{p 4 8 2}{cmdab:genlt}({it:string}) creates several variables. The new variables {it:string} contains Expected A Posteriori estimates of the latent trait and {it:string_se} their standard deviations. The new variable {it:string_corr} contains estimates of the latent traits allowing obtaining the closer estimations of the item-sum scores. The new variables {it:string_opt} contains estimated of the latent traits obtained by searching, for each observed item to maximize the probability to obtain the observed answer (the obtained value is the mean of all these estimates).
{p 4 8 2}{cmd:geninf}({it:string}) contains the information associated for each individual.
{p 4 8 2}{cmdab:rep:lace} specifies that the existing files or variables will be replaced.
{title:Options for a Rasch equating}
{p 4 8 2}{cmdab:rsm} estimates a Rating Scale Model instead of a Partial Credit Model.
{p 4 8 2}{cmdab:it:erate} defines the maximal number of iterations of the maximisation algorithm.
By default, this number is fixed to 100.
{p 4 8 2}{cmd:model} displays the outputs of the maximisation alogorithm .
{p 4 8 2}{cmdab:diff:iculties}({it:matrix}) fixes the values of the difficulties parameters of the items (by default, these values are estimated).
The vector must be a matrix containing as many rows as items, and a column for each threshold parameter (number of answer categories minus 1).
A missing value (.) replaces unexisting difficulty paremeters in the matrix.
{p 4 8 2}{cmdab:var:iance}({it:#}) fixes the value of the variance of the latent trait (by default, this value is estimated).
{p 4 8 2}{cmdab:minsize}({it:#}) fixes the minimal value of the groups (30 individuals by default).
{p 4 8 2}{cmdab:G:raphs} displays the graphs.
{p 4 8 2}{cmdab:dim:name}({it:string}) defines the name of the analysed dimension (this name appears on the graphs).
{p 4 8 2}{cmdab:eqset1}({it:varlist}) and {cmdab:eqset2}({it:varlist}) define the items containing in the two sets of items to equate (disjoint or not sets of items)
{p 4 8 2}{cmdab:eqset1name}({it:string}) and {cmdab:eqset2name}({it:string}) define the names of the two sets of items (set1 and set2 by default). The string cannot contains spaces if the version of Stata is 17 or less.
{p 4 8 2}{cmdab:EQG:raph} displays graphs
{p 4 8 2}{cmdab:eqaddset1}({it:#}) and {cmdab:eqaddset2}({it:#}) allows adding a real to the row score to obtain a linear transformed score for each set of items (0 by default)
{p 4 8 2}{cmdab:eqmultset1}({it:#) and {cmdab:eqmultset2}({it:#}) allows multiplying the row score by a real to obtain a linear transformed score for each set of items (1 by default)
{p 4 8 2}{cmdab:eqwithci} allows representing the 95% confidence interval of the equated score on the graph
{p 4 8 2}{cmdab:eqgenscore}({it:string}) create several variables containing the center (_mean_), the minimal (_min_) and the maximal (_max_) values of the 95% confidence interval and a random value (_random_) drawn in this interval
{p 4 8 2}{cmdab:rep:lace} specifies that the existing files or variables will be replaced.
{title:Outputs}
{p 4 8 2}{cmd:e()}: Output of the gsem procedure
{p 4 8 2}{cmd:r(ll)}: Marginal Log-likelihood
{p 4 8 2}{cmd:r(PSI)}: Personal Separation Index
{p 4 8 2}{cmd:r(difficulties)}: Estimates of the threshold parameters
{p 4 8 2}{cmd:r(matscorelt)} : estimates of the latent trait associated to each complete item-sum score
{p 4 8 2}{cmd:r(matgroupscorelt)} : estimates of the latent trait associated to each complete item-sum score and to each group of individuals used for graphical fit tests
{p 4 8 2}{cmd:r(covariates)} : estimates of the variance of the latent trait and of the parameters associates to covariates
{p 4 8 2}{cmd:r(bestest)}: estimates of the latent trait obtained for each item by searching the value maximizing the response to each answer category
{p 4 8 2}{cmd:r(score2_to_1)} : gives the results to equate the raw scores of the set2 to set1
{p 4 8 2}{cmd:r(score1_to_2)}: gives the results to equate the raw scores of the set1 to set2
{title:Examples of Rasch analysis}
{p 4 8 2}{cmd: . pcm item1-item9}
{p 4 8 2}{cmd: . pcm item*, graph dirsave(c:\graphs) filesave genlt(lt) docx(report)}
{p 4 8 2}{cmd: . matrix diff=(-1,-0.8,0.2\-.5,0,0.5\0,1,.\0.2,1,1.2\0.5,.,.)}{p_end}
{p 4 8 2}{cmd: . pcm item1-item5 , diff(diff) cat(sex) cont(age) }
{title:Example of Rasch equating}
{p 4 8 2}{cmd: . pcm item1-item9, eqset1(item1-item5) eqset2(item6-item9) eqnameset1(First part) eqnameset2(Second part) eqaddset1(5) eqmultset1(-1) graph}
{title:Author}
{p 4 8 2}Jean-Benoit Hardouin, PhD-HDR, Associate professor - Hospital Practitioner{p_end}
{p 4 8 2}Myriam Blanchin, PhD, Research engineer{p_end}
{p 4 8 2}INSERM UMR 1246-SPHERE "Methods in Patients Centered Outcomes and Health Research"{p_end}
{p 4 8 2}Nantes University - Faculty of Medicine{p_end}
{p 4 8 2}Intitute of Research in Health 2{p_end}
{p 4 8 2}22 boulevard Bénoni-Goullin{p_end}
{p 4 8 2}44200 Nantes - FRANCE{p_end}
{p 4 8 2}Email:
{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}, {browse "mailto:myriam.blanchin@univ-nantes.fr":myriam.blanchin@univ-nantes.fr}{p_end}
{title:Also see}
{p 4 13 2}Online: help for {help raschtest} and {help gsem} if installed.{p_end}

Binary file not shown.

View File

@ -0,0 +1,244 @@
*! Version 2.1 18october2011
************************************************************************************************************
* Stata program : pcm
* Estimate the parameters of the Partial Credit Model
* Version 1 : December 17, 2007
* Version 2 : July 15, 2011
* Version 2.1 : October 18th, 2011 : -fixedvar- option, new presentation
*
* Jean-benoit Hardouin, EA4275 Biostatistics, Clinical Research and Subjective Measures in Health Sciences
* Faculties of Pharmaceutical Sciences & Medicine - University of Nantes - France
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2007, 2011 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define pcm,eclass
version 8.0
syntax varlist(min=3 numeric) [if] [in] [,rsm fixed(string) fixedvar(real -1) fixedmu short COVariates(varname)]
preserve
tempfile pcmfile
qui save `pcmfile',replace
if "`fixedmu'"!=""&`fixedvar'!=-1&"`covariates'"=="" {
di in red "You cannot fix in the same time the mean (fixedmu option) and the variance (fixedvar option) of the latent trait without covariables"
error 184
}
if "`fixed'"!=""&"`fixedmu'"==""&`fixedvar'!=-1&"`covariates'"=="" {
di in red "You cannot fix in the same time the difficulties (fixed option) and the variance (fixedvar option) of the latent trait without covariables"
error 184
}
/*******************************************************************************
ESTIMATION OF THE PARAMETERS
********************************************************************************/
marksample touse
qui keep if `touse'
qui count
local N=r(N)
tokenize `varlist'
local nbitems : word count `varlist'
if "`rsm'"=="" {
di in gr "Model: " in ye "Partial Credit Model"
}
else {
di in gr "Model: " in ye "Rating Scale Model"
}
tempname one var w id item it obs x chosen d score
qui gen `one'=1
qui gen `id'=_n
local modamax=0
forvalues i=1/`nbitems' {
qui rename ``i'' `var'`i'
qui su `var'`i'
local moda`i'=`r(max)'
if `modamax'<`r(max)' {
local modamax=r(max)
}
}
qui genscore `var'1-`var'`nbitems' ,score(`score')
qui collapse (sum) `w'=`one',by(`var'1-`var'`nbitems' `covariates')
qui gen `id'=_n
qui reshape long `var',i(`id') j(`item')
qui drop if `var'==.
qui gen `obs'=_n
qui expand `=`modamax'+1'
qui sort `id' `item' `obs'
by `obs', sort: gen `x'=_n-1
qui gen `chosen'=`var'==`x'
qui tab `item', gen(`it')
forvalues i=1/`nbitems' {
forvalues g=1/`modamax' {
qui gen `d'`i'_`g'=-1*`it'`i'*(`x'>=`g')
}
}
qui rename `w' `w'2
bysort `id':egen score=sum(`x'*`chosen')
qui su score
local maxscore=r(max)
if "`covariates'"!="" {
qui gen covw=`covariates'*`x'
local listcov covw
}
else {
local listcov
}
if `fixedvar'!=-1 {
local tmp=sqrt(`fixedvar')
constraint 1 `x'=`tmp'
local listconstr "constraints(1)"
}
if "`rsm'"=="" {
if "`fixed'"!="" {
qui gen offset=0
local l=1
forvalues i=1/`nbitems' {
forvalues mi=1/`moda`i'' {
qui replace offset=offset+`fixed'[1,`l']*`d'`i'_`mi'
local ++l
}
}
if "`fixedmu'"!="" {
local mu
}
else {
local mu "`x'"
}
eq slope:`x'
noi di "gllamm `x' `listcov' `mu',offset(offset) `listconstr' nocons i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace"
gllamm `x' `listcov' `mu',offset(offset) `listconstr' nocons i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace
}
else if "`short'"!="" {
eq slope:`x'
qui gllamm `x' `d'1_1-`d'`nbitems'_`modamax',i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons init
tempname bsave Vsave
matrix `bsave'=e(b)
matrix `Vsave'=e(V)
restore
qui pcm `varlist' , fixed(`bsave')
}
else {
di "no short"
eq slope:`x'
qui gen i=`id'
constraint 1 `x'=1
gllamm `x' `d'1_1-`d'`nbitems'_`modamax' `listcov',i(i) `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons
}
}
else {
tempname step n
forvalues i=2/`modamax' {
qui gen `step'`i'=-1*(`x'>=`i')
}
forvalues i=1/`nbitems' {
qui gen `n'`var'`i'=(-1)*(`it'`i')*(`x')
}
qui sort `id' `item' `x'
eq slope:`x'
gllamm `x' `n'`var'1-`n'`var'`nbitems' `step'2-`step'`modamax' `listcov', i(`id') `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons
}
tempname b V chol
matrix b=e(b)
matrix V=e(V)
local ll=e(ll)
matrix chol=e(chol)
if "`rsm'"=="" {
di
di in gr "Number of observations: " in ye `N'
di in gr "Number of items: " in ye `nbitems'
di in gr "Number of parameters: " in ye `=`nbitems'*`modamax'+1'
di in gr "Log-likelihood: " in ye `ll'
di
di
di in gr "{hline 100}"
di in gr "Item" _col(10) "Modality" _col(20) "Parameter" _col(30) "Std Error"
di in gr "{hline 100}"
if "`fixed'"=="" {
forvalues i=1/`nbitems' {
forvalues j=1/`modamax' {
if `j'==1 {
di in ye "``i''" _cont
}
local k=(`i'-1)*`modamax'+`j'
if "`short'"!="" {
di in ye _col(17) `j' _col(20) %9.6f `bsave'[1,`k'] in ye _col(30) %9.6f (`Vsave'[`k',`k'])^.5
}
else {
di in ye _col(17) `j' _col(20) %9.6f b[1,`k'] in ye _col(30) %9.6f (V[`k',`k'])^.5
}
}
di in gr "{dup 100:-}"
}
}
else {
forvalues i=1/`nbitems' {
forvalues j=1/`modamax' {
if `j'==1 {
di in ye "``i''" _cont
}
local k=(`i'-1)*`modamax'+`j'
di in ye _col(17) `j' _col(20) %9.6f `fixed'[1,`k'] in ye _col(32) "(fixed)"
}
di in gr "{dup 100:-}"
}
}
if "`fixed'"==""&"`short'"=="" {
local k=`nbitems'*`modamax'+1
}
else if "`fixed'"!=""&"`fixedmu'"=="" {
di in ye "Mu" in ye _col(20) %9.6f b[1,1] _col(29) %10.6f (V[1,1])^.5
local k=2
}
else if "`fixed'"!=""&"`fixedmu'"!="" {
di in ye "Mu" in ye _col(20) %9.6f 0 _col(32) %10.6f "(fixed)"
local k=1
}
else {
local k=1
}
if "`covariates'"!="" {
di in ye "`covariates'" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f (V[`k',`k'])^.5
local k=`k'+1
}
if `fixedvar'==-1 {
di in ye "Sigma" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f (V[`k',`k'])^.5
di in ye "Variance" in ye _col(20) %9.6f b[1,`k']^2 _col(29) %10.6f 2*(V[`k',`k'])^.5*b[1,`k']
}
else {
di in ye "Sigma" in ye _col(20) %9.6f `fixedvar'^.5 _col(32) %10.6f "(fixed)"
di in ye "Variance" in ye _col(20) %9.6f `fixedvar' _col(32) %10.6f "(fixed)"
}
di in gr "{hline 100}"
di
di
}
end

View File

@ -0,0 +1,245 @@
*! Version 2.2 23october2013
************************************************************************************************************
* Stata program : pcm
* Estimate the parameters of the Partial Credit Model
* Version 1 : December 17, 2007
* Version 2 : July 15, 2011
* Version 2.1 : October 18th, 2011 : -fixedvar- option, new presentation
* Version 2.2 : October 23rd, 2013 : correction of -fixedvar- option
*
* Jean-benoit Hardouin, EA4275 Biostatistics, Clinical Research and Subjective Measures in Health Sciences
* Faculties of Pharmaceutical Sciences & Medicine - University of Nantes - France
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2007, 2011 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define pcm,eclass
version 8.0
syntax varlist(min=3 numeric) [if] [in] [,rsm fixed(string) fixedvar(real -1) fixedmu short COVariates(varname)]
preserve
tempfile pcmfile
qui save `pcmfile',replace
if "`fixedmu'"!=""&`fixedvar'!=-1&"`covariates'"=="" {
di in red "You cannot fix in the same time the mean (fixedmu option) and the variance (fixedvar option) of the latent trait without covariables"
error 184
}
if "`fixed'"!=""&"`fixedmu'"==""&`fixedvar'!=-1&"`covariates'"=="" {
di in red "You cannot fix in the same time the difficulties (fixed option) and the variance (fixedvar option) of the latent trait without covariables"
error 184
}
/*******************************************************************************
ESTIMATION OF THE PARAMETERS
********************************************************************************/
marksample touse
qui keep if `touse'
qui count
local N=r(N)
tokenize `varlist'
local nbitems : word count `varlist'
if "`rsm'"=="" {
di in gr "Model: " in ye "Partial Credit Model"
}
else {
di in gr "Model: " in ye "Rating Scale Model"
}
tempname one var w id item it obs x chosen d score
qui gen `one'=1
qui gen `id'=_n
local modamax=0
forvalues i=1/`nbitems' {
qui rename ``i'' `var'`i'
qui su `var'`i'
local moda`i'=`r(max)'
if `modamax'<`r(max)' {
local modamax=r(max)
}
}
qui genscore `var'1-`var'`nbitems' ,score(`score')
qui collapse (sum) `w'=`one',by(`var'1-`var'`nbitems' `covariates')
qui gen `id'=_n
qui reshape long `var',i(`id') j(`item')
qui drop if `var'==.
qui gen `obs'=_n
qui expand `=`modamax'+1'
qui sort `id' `item' `obs'
by `obs', sort: gen `x'=_n-1
qui gen `chosen'=`var'==`x'
qui tab `item', gen(`it')
forvalues i=1/`nbitems' {
forvalues g=1/`modamax' {
qui gen `d'`i'_`g'=-1*`it'`i'*(`x'>=`g')
}
}
qui rename `w' `w'2
bysort `id':egen score=sum(`x'*`chosen')
qui su score
local maxscore=r(max)
if "`covariates'"!="" {
qui gen covw=`covariates'*`x'
local listcov covw
}
else {
local listcov
}
if `fixedvar'!=-1 {
local tmp=sqrt(`fixedvar')
constraint 1 `x'=`tmp'
local listconstr "constraints(1)"
}
if "`rsm'"=="" {
if "`fixed'"!="" {
qui gen offset=0
local l=1
forvalues i=1/`nbitems' {
forvalues mi=1/`moda`i'' {
qui replace offset=offset+`fixed'[1,`l']*`d'`i'_`mi'
local ++l
}
}
if "`fixedmu'"!="" {
local mu
}
else {
local mu "`x'"
}
eq slope:`x'
noi di "gllamm `x' `listcov' `mu',offset(offset) `listconstr' nocons i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace"
gllamm `x' `listcov' `mu',offset(offset) `listconstr' nocons i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace
}
else if "`short'"!="" {
eq slope:`x'
qui gllamm `x' `d'1_1-`d'`nbitems'_`modamax',i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons init
tempname bsave Vsave
matrix `bsave'=e(b)
matrix `Vsave'=e(V)
restore
qui pcm `varlist' , fixed(`bsave')
}
else {
di "no short"
eq slope:`x'
qui gen i=`id'
constraint 1 `x'=1
gllamm `x' `d'1_1-`d'`nbitems'_`modamax' `listcov',i(i) `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons
}
}
else {
tempname step n
forvalues i=2/`modamax' {
qui gen `step'`i'=-1*(`x'>=`i')
}
forvalues i=1/`nbitems' {
qui gen `n'`var'`i'=(-1)*(`it'`i')*(`x')
}
qui sort `id' `item' `x'
eq slope:`x'
gllamm `x' `n'`var'1-`n'`var'`nbitems' `step'2-`step'`modamax' `listcov', i(`id') `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons
}
tempname b V chol
matrix b=e(b)
matrix V=e(V)
local ll=e(ll)
matrix chol=e(chol)
if "`rsm'"=="" {
di
di in gr "Number of observations: " in ye `N'
di in gr "Number of items: " in ye `nbitems'
di in gr "Number of parameters: " in ye `=`nbitems'*`modamax'+1'
di in gr "Log-likelihood: " in ye `ll'
di
di
di in gr "{hline 100}"
di in gr "Item" _col(10) "Modality" _col(20) "Parameter" _col(30) "Std Error"
di in gr "{hline 100}"
if "`fixed'"=="" {
forvalues i=1/`nbitems' {
forvalues j=1/`modamax' {
if `j'==1 {
di in ye "``i''" _cont
}
local k=(`i'-1)*`modamax'+`j'
if "`short'"!="" {
di in ye _col(17) `j' _col(20) %9.6f `bsave'[1,`k'] in ye _col(30) %9.6f (`Vsave'[`k',`k'])^.5
}
else {
di in ye _col(17) `j' _col(20) %9.6f b[1,`k'] in ye _col(30) %9.6f (V[`k',`k'])^.5
}
}
di in gr "{dup 100:-}"
}
}
else {
forvalues i=1/`nbitems' {
forvalues j=1/`modamax' {
if `j'==1 {
di in ye "``i''" _cont
}
local k=(`i'-1)*`modamax'+`j'
di in ye _col(17) `j' _col(20) %9.6f `fixed'[1,`k'] in ye _col(32) "(fixed)"
}
di in gr "{dup 100:-}"
}
}
if "`fixed'"==""&"`short'"=="" {
local k=`nbitems'*`modamax'+1
}
else if "`fixed'"!=""&"`fixedmu'"=="" {
di in ye "Mu" in ye _col(20) %9.6f b[1,1] _col(29) %10.6f (V[1,1])^.5
local k=2
}
else if "`fixed'"!=""&"`fixedmu'"!="" {
di in ye "Mu" in ye _col(20) %9.6f 0 _col(32) %10.6f "(fixed)"
local k=1
}
else {
local k=1
}
if "`covariates'"!="" {
di in ye "`covariates'" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f (V[`k',`k'])^.5
local k=`k'+1
}
if `fixedvar'==-1 {
di in ye "Sigma" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f (V[`k',`k'])^.5
di in ye "Variance" in ye _col(20) %9.6f b[1,`k']^2 _col(29) %10.6f 2*(V[`k',`k'])^.5*b[1,`k']
}
else {
di in ye "Sigma" in ye _col(20) %9.6f `fixedvar'^.5 _col(32) %10.6f "(fixed)"
di in ye "Variance" in ye _col(20) %9.6f `fixedvar' _col(32) %10.6f "(fixed)"
}
di in gr "{hline 100}"
di
di
}
end

View File

@ -0,0 +1,283 @@
*! Version 2.3 10april2014
************************************************************************************************************
* Stata program : pcm
* Estimate the parameters of the Partial Credit Model
* Version 1 : December 17, 2007
* Version 2 : July 15, 2011
* Version 2.1 : October 18th, 2011 : -fixedvar- option, new presentation
* Version 2.2 : October 23rd, 2013 : correction of -fixedvar- option
* Version 2.3 : April 10th, 2014 : correction of -fixedvar- option
*
* Jean-benoit Hardouin, EA4275 Biostatistics, Clinical Research and Subjective Measures in Health Sciences
* Faculties of Pharmaceutical Sciences & Medicine - University of Nantes - France
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2007-2014 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define pcm,eclass
version 8.0
syntax varlist(min=3 numeric) [if] [in] [,rsm fixed(string) fixedvar(real -1) fixedmu short COVariates(varname) fixedvargroupc(string) vargroupc]
preserve
tempfile pcmfile
qui save `pcmfile',replace
if "`fixedmu'"!=""&`fixedvar'!=-1&"`covariates'"=="" {
di in red "You cannot fix in the same time the mean (fixedmu option) and the variance (fixedvar option) of the latent trait without covariables"
error 184
}
if "`fixed'"!=""&"`fixedmu'"==""&`fixedvar'!=-1&"`covariates'"=="" {
di in red "You cannot fix in the same time the difficulties (fixed option) and the variance (fixedvar option) of the latent trait without covariables"
error 184
}
/*******************************************************************************
ESTIMATION OF THE PARAMETERS
********************************************************************************/
marksample touse
qui keep if `touse'
qui count
local N=r(N)
tokenize `varlist'
local nbitems : word count `varlist'
if "`rsm'"=="" {
di in gr "Model: " in ye "Partial Credit Model"
}
else {
di in gr "Model: " in ye "Rating Scale Model"
}
tempname one var w id item it obs x chosen d score
qui gen `one'=1
qui gen `id'=_n
local modamax=0
forvalues i=1/`nbitems' {
qui rename ``i'' `var'`i'
qui su `var'`i'
local moda`i'=`r(max)'
if `modamax'<`r(max)' {
local modamax=r(max)
}
}
qui genscore `var'1-`var'`nbitems' ,score(`score')
qui collapse (sum) `w'=`one',by(`var'1-`var'`nbitems' `covariates')
qui gen `id'=_n
qui reshape long `var',i(`id') j(`item')
qui drop if `var'==.
qui gen `obs'=_n
qui expand `=`modamax'+1'
qui sort `id' `item' `obs'
by `obs', sort: gen `x'=_n-1
qui gen `chosen'=`var'==`x'
qui tab `item', gen(`it')
forvalues i=1/`nbitems' {
forvalues g=1/`modamax' {
qui gen `d'`i'_`g'=-1*`it'`i'*(`x'>=`g')
}
}
qui rename `w' `w'2
bysort `id':egen score=sum(`x'*`chosen')
qui su score
local maxscore=r(max)
if "`covariates'"!="" {
qui gen covw=`covariates'*`x'
local listcov covw
}
else {
local listcov
}
if `fixedvar'!=-1 {
local tmp=sqrt(`fixedvar')
constraint 1 `x'=`tmp'
local listconstr "constraints(1)"
local eq "eqs(slope) nrf(1)"
}
local eq "eqs(slope) nrf(1)"
*set trace on
if "`rsm'"=="" { /*PARTIAL CREDIT MODEL*/
*di "cas 1"
if "`fixed'"!="" { /*FIXED ITEMS DIFFICULTIES*/
*di "cas 2"
qui gen offset=0
local l=1
forvalues i=1/`nbitems' {
forvalues mi=1/`moda`i'' {
qui replace offset=offset+`fixed'[1,`l']*`d'`i'_`mi'
local ++l
}
}
if "`fixedmu'"!="" {
local mu
}
else {
local mu "`x'"
}
*set trace on
if "`fixedvargroupc'"!=""|"`vargroupc'"!="" {/*INEQUAL VARIANCES*/
local var0: word 1 of `fixedvargroupc'
local var1: word 2 of `fixedvargroupc'
tempvar G0 G1
qui gen `G0'=groupc<0
qui gen `G1'=groupc>0
qui replace `G0'=`G0'*`x'
qui replace `G1'=`G1'*`x'
qui eq B0: `G0'
qui eq B1: `G1'
constraint 1 _cons=0
if "`fixedvargroupc'"!="" {/*FIXED INEQUAL VARIANCES*/
constraint 2 `G0'=`=sqrt(`var0')'
constraint 3 `G1'=`=sqrt(`var1')'
local listconstr "constraints(1 2 3)"
}
else { /*FREE INEQUAL VARIANCE*/
local listconstr "constraints(1)"
}
local eq "eqs(B0 B1) nrf(2)"
}
eq slope:`x'
su
tab covw
di "ICI*******************jb"
di "`x' : x"
di "`listcov' : listcov"
di "`mu' : mu"
noi di "gllamm `x' `listcov' `mu',offset(offset) `listconstr' nocons i(`id') link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace `eq'"
*set trace on
noi gllamm `x' `listcov' `mu' ,offset(offset) `listconstr' nocons i(`id') link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace `eq' iterate(100)
}
else if "`short'"!="" {
*di "cas 3"
eq slope:`x'
qui gllamm `x' `d'1_1-`d'`nbitems'_`modamax',i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons init iterate(100)
tempname bsave Vsave
matrix `bsave'=e(b)
matrix `Vsave'=e(V)
restore
qui pcm `varlist' , fixed(`bsave')
}
else {
*di "cas 4"
di "no short"
eq slope:`x'
qui gen i=`id'
constraint 1 `x'=1
gllamm `x' `d'1_1-`d'`nbitems'_`modamax' `listcov',i(i) `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons iterate(100)
}
}
else {
*di "cas 5"
tempname step n
forvalues i=2/`modamax' {
qui gen `step'`i'=-1*(`x'>=`i')
}
forvalues i=1/`nbitems' {
qui gen `n'`var'`i'=(-1)*(`it'`i')*(`x')
}
qui sort `id' `item' `x'
eq slope:`x'
gllamm `x' `n'`var'1-`n'`var'`nbitems' `step'2-`step'`modamax' `listcov', i(`id') `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons iterate(100)
}
tempname b V chol
matrix b=e(b)
matrix V=e(V)
local ll=e(ll)
matrix chol=e(chol)
if "`rsm'"=="" {
di
di in gr "Number of observations: " in ye `N'
di in gr "Number of items: " in ye `nbitems'
di in gr "Number of parameters: " in ye `=`nbitems'*`modamax'+1'
di in gr "Log-likelihood: " in ye `ll'
di
di
di in gr "{hline 100}"
di in gr "Item" _col(10) "Modality" _col(20) "Parameter" _col(30) "Std Error"
di in gr "{hline 100}"
if "`fixed'"=="" {
forvalues i=1/`nbitems' {
forvalues j=1/`modamax' {
if `j'==1 {
di in ye "``i''" _cont
}
local k=(`i'-1)*`modamax'+`j'
if "`short'"!="" {
di in ye _col(17) `j' _col(20) %9.6f `bsave'[1,`k'] in ye _col(30) %9.6f (`Vsave'[`k',`k'])^.5
}
else {
di in ye _col(17) `j' _col(20) %9.6f b[1,`k'] in ye _col(30) %9.6f (V[`k',`k'])^.5
}
}
di in gr "{dup 100:-}"
}
}
else {
forvalues i=1/`nbitems' {
forvalues j=1/`modamax' {
if `j'==1 {
di in ye "``i''" _cont
}
local k=(`i'-1)*`modamax'+`j'
di in ye _col(17) `j' _col(20) %9.6f `fixed'[1,`k'] in ye _col(32) "(fixed)"
}
di in gr "{dup 100:-}"
}
}
if "`fixed'"==""&"`short'"=="" {
local k=`nbitems'*`modamax'+1
}
else if "`fixed'"!=""&"`fixedmu'"=="" {
di in ye "Mu" in ye _col(20) %9.6f b[1,1] _col(29) %10.6f (V[1,1])^.5
local k=2
}
else if "`fixed'"!=""&"`fixedmu'"!="" {
di in ye "Mu" in ye _col(20) %9.6f 0 _col(32) %10.6f "(fixed)"
local k=1
}
else {
local k=1
}
if "`covariates'"!="" {
di in ye "`covariates'" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f (V[`k',`k'])^.5
local k=`k'+1
}
if `fixedvar'==-1 {
di in ye "Sigma" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f (V[`k',`k'])^.5
di in ye "Variance" in ye _col(20) %9.6f b[1,`k']^2 _col(29) %10.6f 2*(V[`k',`k'])^.5*b[1,`k']
}
else {
di in ye "Sigma" in ye _col(20) %9.6f `fixedvar'^.5 _col(32) %10.6f "(fixed)"
di in ye "Variance" in ye _col(20) %9.6f `fixedvar' _col(32) %10.6f "(fixed)"
}
di in gr "{hline 100}"
di
di
}
end

View File

@ -0,0 +1,917 @@
*! Version 3.2 17july2019
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : pcm
* Estimate the parameters of the Partial Credit Model
* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
*
*
*
* Jean-benoit Hardouin - University of Nantes - France
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2007, 2011, 2013, 2014, 2019 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define pcm, rclass
syntax varlist(min=2 numeric) [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(string) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string)]
qui count
local nbobs=r(N)
/*************************************************************************************************************
GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
*************************************************************************************************************/
local modcont
local nbpar=0
local nbcont=0
local nbcat=0
if "`continuous'"!="" {
tokenize `continuous'
local nbcont : word count `continuous'
local continuous
forvalues i=1/`nbcont' {
local cont`i' ``i''
local continuous `continuous' ``i''
local modcont `modcont' ``i''
local ++nbpar
}
local modcont (`modcont'->T)
}
local modcat
if "`categorical'"!="" {
tokenize `categorical'
local nbcat : word count `categorical'
local categorical
forvalues i=1/`nbcat' {
local cat`i' ``i''
local categorical `categorical' ``i''
local modcat `modcat' i.``i''
qui levelsof ``i''
local levelsof``i'' `r(levels)'
local nbpar=`nbpar'+`r(r)'-1
*di "categorical : ``i'' levels : `levelsof``i'''"
}
local modcat (`modcat'->T)
}
if "`dirsave'"=="" {
local dirsave `c(pwd)'
}
/*************************************************************************************************************
GESTION DES ITEMS ET TESTS
*************************************************************************************************************/
tokenize `varlist'
local nbitems : word count `varlist'
marksample touse ,novarlist
preserve
local modamax=1
local modamin=0
local pbmin
local nbdiff=0
forvalues i=1/`nbitems' {
qui su ``i''
if `r(min)'!=`modamin' {
local modamin=r(min)
local pbmin `pbmin' ``i''
}
if `r(max)'>`modamax' {
local modamax=r(max)
}
local modamax``i''=r(max)
if "`rsm'"=="" {
local nbdiff=`nbdiff'+`modamax``i'''
}
}
if "`rsm'"!="" {
local nbdiff=`nbitems'+`modamax'-1
}
if `modamin'!=0 {
di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
error 198
}
qui count
local nbind=r(N)
*set trace on
local code
forvalues k=1/`modamax' {
local code`k'
forvalues i=1/`nbitems' {
if `k'<=`modamax``i''' {
local code`k' `code`k'' `k'.``i''
}
}
local code`k' (`code`k''<-T@`k')
local code `code' `code`k''
}
/*************************************************************************************************************
RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
*************************************************************************************************************/
if "`difficulties'"!=""&"`rsm'"!="" {
di as error "You can not defined in the same time the difficulties and the rsm options"
error 198
}
if "`difficulties'"!="" {
local t=1
local constraints
forvalues i=1/`nbitems' {
forvalues k=1/`modamax``i''' {
if `difficulties'[`i',`k']==. {
di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
error 198
}
else {
local val=0
forvalues l=1/`k' {
local val=`val'-`difficulties'[`i',`l']
}
constraint `t' [`k'.``i'']_cons=`val'
local constraints `constraints' `t'
local ++t
}
}
}
}
/*************************************************************************************************************
DEFINITION DES CONTRAINTES POUR UN RSM
*************************************************************************************************************/
if "`rsm'"!="" {
local t=1
local constraints
forvalues k=2/`modamax' {
forvalues i=2/`nbitems' {
constraint `t' [`=`k'-1'.``i'']_cons-[`k'.``i'']_cons+[1.``i'']_cons=[`=`k'-1'.`1']_cons-[`k'.`1']_cons+[1.`1']_cons
local constraints `constraints' `t'
local ++t
}
}
}
/*************************************************************************************************************
MODELE
*************************************************************************************************************/
discard
*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')"
local qui qui
if "`model'"!="" {
local qui
}
`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')
local ll=e(ll)
*set trace on
tempvar latent score group selatent latent2
tempname groups
qui predict mu, mu
*su mu
qui predict `latent',latent se(`selatent')
set seed 123456
qui gen `latent2'=`latent'+invnorm(uniform())*`selatent'
qui genscore `varlist',score(`score')
qui gengroup `latent',newvariable(`group') continuous
qui levelsof `group'
local nbgroups=r(r)
matrix `groups'=J(`nbgroups',`=`nbitems'+3',.)
forvalues g=1/`nbgroups' {
matrix `groups'[`g',`=`nbitems'+3']=0
forvalues i=1/`nbitems' {
*tab ``i'' if `group'==`g'
qui count if ``i''!=.&`group'==`g'
local n=r(N)
if `n'>0 {
qui su ``i'' if `group'==`g'
matrix `groups'[`g',`i']=r(mean)
matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
}
else {
matrix `groups'[`g',`i']=.
matrix `groups'[`g',`=`nbitems'+3']=.
}
}
qui su `latent' if `group'==`g'
matrix `groups'[`g',`=`nbitems'+1']=r(mean)
qui count if `group'==`g'
matrix `groups'[`g',`=`nbitems'+2']=r(N)
}
*matrix list `groups'
qui count if `score'!=.
local nbobsssmd=r(N)
di
di as text "Number of individuals:" %6.0f as result `nbobs'
di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
di as text "Number of items:" %6.0f as result `nbitems'
di as text "Marginal log-likelihood:" %12.4f as result `ll'
di
return scalar ll=`ll'
*set trace on
/*************************************************************************************************************
RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
*************************************************************************************************************/
tempname diff diffmat vardiff diffmat2
*set trace on
qui matrix `diffmat'=J(`nbitems',`modamax',.)
qui matrix `diffmat2'=J(`nbitems',`modamax',.)
qui matrix `diff'=J(`nbdiff',6,.)
local rn
*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
*matrix list `diff'
*set trace on
local t=1
forvalues i=1/`nbitems' {
qui matrix `diffmat'[`i',1]=-_b[1.``i'':_cons]
qui matrix `diffmat2'[`i',1]=-_b[1.``i'':_cons]
qui lincom -_b[1.``i'':_cons]
qui matrix `diff'[`t',1]=`r(estimate)'
qui matrix `diff'[`t',2]=`r(se)'
qui matrix `diff'[`t',3]=`r(z)'
qui matrix `diff'[`t',4]=`r(p)'
qui matrix `diff'[`t',5]=`r(lb)'
qui matrix `diff'[`t',6]=`r(ub)'
*qui matrix `vardiff'[`t',`t']=_se[1.``i'':_cons]^2
local rn `rn' 1.``i''
local ++t
local sum _b[1.``i'':_cons]
if "`rsm'"=="" {
forvalues k=2/`modamax``i''' {
local sum "_b[`k'.``i'':_cons]-`sum'"
qui lincom -(`sum')
*set trace on
qui matrix `diffmat'[`i',`k']=`r(estimate)'
qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
qui matrix `diff'[`t',1]=`r(estimate)'
qui matrix `diff'[`t',2]=`r(se)'
qui matrix `diff'[`t',3]=`r(z)'
qui matrix `diff'[`t',4]=`r(p)'
qui matrix `diff'[`t',5]=`r(lb)'
qui matrix `diff'[`t',6]=`r(ub)'
*qui matrix `vardiff'[`t',`t']=`r(se)'^2
*set trace off
local rn `rn' `k'.``i''
local ++t
}
}
}
if "`rsm'"!="" {
forvalues k=2/`modamax' {
qui lincom _b[`=`k'-1'.`1':_cons]-_b[`k'.`1':_cons]+_b[1.`1':_cons]
qui matrix `diff'[`t',1]=`r(estimate)'
qui matrix `diff'[`t',2]=`r(se)'
qui matrix `diff'[`t',3]=`r(z)'
qui matrix `diff'[`t',4]=`r(p)'
qui matrix `diff'[`t',5]=`r(lb)'
qui matrix `diff'[`t',6]=`r(ub)'
forvalues i=1/`nbitems' {
qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
}
local rn `rn' tau`k'
local ++t
}
}
local cn Estimate S.e. z p "Lower bound" "Upper Bound"
matrix colnames `diff'=`cn'
matrix rownames `diff'=`rn'
*matrix list `diff'
*matrix list `diffmat'
*matrix list `diffmat2'
*matrix list `vardiff'
/*************************************************************************************************************
RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES ET LA VARIANCE
*************************************************************************************************************/
tempname covariates
qui matrix `covariates'=J(`=`nbpar'+1',6,.)
*set trace on
if "`continuous'"!=""|"`categorical'"!="" {
qui lincom _b[/var(e.T)]
}
else {
qui lincom _b[/var(T)]
}
qui matrix `covariates'[1,1]=`r(estimate)'
qui matrix `covariates'[1,2]=`r(se)'
qui matrix `covariates'[1,3]=`r(z)'
qui matrix `covariates'[1,4]=`r(p)'
qui matrix `covariates'[1,5]=`r(lb)'
qui matrix `covariates'[1,6]=`r(ub)'
local t=2
forvalues i=1/ `nbcont' {
qui lincom `cont`i''
qui matrix `covariates'[`t',1]=`r(estimate)'
qui matrix `covariates'[`t',2]=`r(se)'
qui matrix `covariates'[`t',3]=`r(z)'
qui matrix `covariates'[`t',4]=`r(p)'
qui matrix `covariates'[`t',5]=`r(lb)'
qui matrix `covariates'[`t',6]=`r(ub)'
local ++t
}
forvalues i=1/ `nbcat' {
local first=0
foreach j in `levelsof`cat`i''' {
if `first'==0 {
local ++first
}
else {
qui lincom `j'.`cat`i''
qui matrix `covariates'[`t',1]=`r(estimate)'
qui matrix `covariates'[`t',2]=`r(se)'
qui matrix `covariates'[`t',3]=`r(z)'
qui matrix `covariates'[`t',4]=`r(p)'
qui matrix `covariates'[`t',5]=`r(lb)'
qui matrix `covariates'[`t',6]=`r(ub)'
local ++t
}
}
}
* matrix list `covariates'
/*************************************************************************************************************
OUTPUTS
*************************************************************************************************************/
local t=1
local diffname
*set trace on
di "{hline 73}"
di as text _col(60) "<--95% IC -->"
di "Items" _col(60) "Lower" _col(68) "Upper"
di "parameters" _col(13) "category" _col(25) "Estimate" _col(37) "s.e." _col(48) "z" _col(56) "p" _col(59) " Bound" _col(68) "Bound"
di "{hline 73}"
*set trace on
forvalues i=1/`nbitems' {
*local l=1
forvalues j=1/`modamax``i''' {
if "`rsm'"==""|`j'==1 {
if `j'==1 {
di as text abbrev("``i''",19) _c
}
di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `diff'[`t',1] _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6]
local ++t
*local ++l
local diffname `diffname' `j'.``i''
}
}
}
if "`rsm'"!="" {
forvalues k=2/`modamax' {
di as text "tau`k'" as result _col(28) %5.2f `diff'[`t',1] _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6]
local diffname `diffname' tau`k'
local ++t
}
}
di as text "{hline 73}"
local t=1
local n: word count Variance `continuous'
forvalues i=1/`n' {
local v: word `i' of Variance `continuous'
di as text _col(1) %5.2f "`v'" as result _col(28) %5.2f `covariates'[`t',1] _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6]
local ++t
}
local rn Variance `continuous'
local n: word count of `categorical'
local catname
forvalues i=1/`n' {
local v: word `i' of `categorical'
local first=1
local saute=1
foreach j in `levelsof`cat`i''' {
if `saute'==0 {
if `first'==1 {
di as text _col(1) abbrev("`v'",19) _c
}
di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `covariates'[`t',1] _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6]
local ++first
local rn `rn' `j'.`n'
local ++t
local catname `catname' `j'.`v'
}
else {
local saute=0
}
}
local ++t
}
di as text "{hline 73}"
di
qui su `latent'
qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])^2)
di as text "PSI:" as result %4.2f `PSI'
di
matrix colnames `covariates'=`cn'
matrix rownames `covariates'=`rn'
/*************************************************************************************************************
FIT TESTS
*************************************************************************************************************/
tempname fit
qui matrix `fit'=J(`nbitems',4,.)
matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
matrix rownames `fit'=`varlist'
*matrix list `fit'
tempvar Tcum TInf cum
qui gen `Tcum'=0
qui gen `TInf'=0
di as text "{hline 90}"
di as text _col(60) "<--- Standardized --->"
di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
di as text "{hline 90}"
di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
di as text "{hline 90}"
*set trace on
local chi2=0
local chi2_old=0
forvalues g=1/`nbgroups' {
local chi2_g`g'=0
local chi2_old_g`g'=0
}
forvalues i=1/`nbitems' {
if "`rsm'"=="" {
local mm=`modamax``i'''
}
else {
local mm `modamax'
}
tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''
tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i''
local d=1
local d_old=1
qui gen `cum``i'''=0
qui gen `cum_old``i'''=0
forvalues k=1/`mm' {
local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
}
qui gen `c0_``i'''=1/(`d')
qui gen `c_old0_``i'''=1/(`d_old')
forvalues k=1/`mm' {
tempvar c`k'_``i'' c_old`k'_``i''
qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
}
qui gen `Inf``i'''=0
qui gen `Inf_old``i'''=0
qui gen `C``i'''=0
forvalues k=0/`mm' {
qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
}
qui count if ``i''!=.
local n``i''=r(N)
qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
qui su `C2``i'''
local q2o``i''=(`r(mean)'-1)/((`n``i'''))
qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
qui su `C3``i'''
local n=r(sum)
qui su `Inf``i'''
local d=r(sum)
local q2i``i''=`n'/((`d')^2)
//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
qui replace `Tcum'=`Tcum'+`cum``i'''
qui replace `TInf'=`TInf'+`Inf``i'''
qui gen `y``i'''=``i''-`cum``i'''
qui gen `y_old``i'''=``i''-`cum_old``i'''
qui gen `y2``i'''=(`y``i''')^2
qui gen `y2_old``i'''=(`y_old``i''')^2
qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
local chi2_``i''=0
local chi2_old_``i''=0
forvalues g=1/`nbgroups' {
qui su `y2``i''' if `group'==`g'
local n=r(sum)
qui su ``i'' if `group'==`g'
local n1=r(sum)
qui su `cum``i''' if `group'==`g'
local n2=r(sum)
qui su `Inf``i''' if `group'==`g'
local d=r(sum)
*di "chi2_`g'_``i''=`chi2'+(`n1'-`n2')^2/(`d')"
local chi2=`chi2'+(`n1'-`n2')^2/(`d')
local chi2_``i''=`chi2_``i'''+(`n1'-`n2')^2/(`d')
local chi2_g`g'=`chi2_g`g''+(`n1'-`n2')^2/(`d')
qui su `y2_old``i''' if `group'==`g'
local n_old=r(sum)
qui su ``i'' if `group'==`g'
local n1_old=r(sum)
qui su `cum_old``i''' if `group'==`g'
local n2_old=r(sum)
qui su `Inf_old``i''' if `group'==`g'
local d_old=r(sum)
local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
}
*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2' Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
*su `z``i'''
label variable `z``i''' "Standardized residuals associated to ``i''"
label variable `latent' "Latent trait"
*set trace on
if "`graphs'"!=""&"`graphitems'"=="" {
if "`filesave'"!="" {
local fs saving(`dirsave'//residuals_``i'',replace)
}
qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
}
*set trace off
qui gen `z2``i'''=(`z``i''')^2
qui su `z2``i'''
local OUTFIT``i''=`r(mean)'
qui matrix `fit'[`i',1]=`OUTFIT``i'''
local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
qui matrix `fit'[`i',3]=`OUTFITs``i'''
qui su `Inf``i''' if ``i''!=.
local sumw``i''=r(sum)
qui gen `i``i'''=`Inf``i'''*`z2``i'''
qui su `i``i''' if ``i''!=.
local INFIT``i'' = `=`r(sum)'/`sumw``i''''
qui matrix `fit'[`i',2]=`INFIT``i'''
local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
qui matrix `fit'[`i',4]=`INFITs``i'''
di abbrev("``i''",19) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i'''
}
di as text "{hline 90}"
di as text "*: As suggested by Wright (Smith, 1998)
di as text "**: As suggested by Bond and Fox (2007)
set trace off
/*************************************************************************************************************
Categories/Items/Test Characteristics Curves and Information graphs
*************************************************************************************************************/
if "`graphs'"!="" {
tempfile savefile
qui save `savefile'
qui clear
qui set obs 2000
qui gen u=(_n-1000)/250
qui gen Tcum=0
qui gen TInf=0
forvalues i=1/`nbitems' {
local scatteri`i'
forvalues g=1/`nbgroups' {
local x=`groups'[`g',`=`nbitems'+1']
local y=`groups'[`g',`i']
local s1=`groups'[`g',`=`nbitems'+2']
local seuil=30
local s vtiny
*set trace on
foreach lab in tiny vsmall small medsmall medium medlarge large vlarge huge vhuge /*ehuge*/ {
if `s1'>`seuil' {
local s `lab'
}
local seuil=`seuil'+10
}
local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
*set trace off
}
local d=1
qui gen cum``i''=0
*set trace on
if "`rsm'"=="" {
local mm=`modamax``i'''
}
else {
local mm `modamax'
}
forvalues k=1/`mm' {
local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
}
qui gen c0_``i''=1/(`d')
label variable c0_``i'' "Pr(``i''=0)"
forvalues k=1/`mm' {
qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
qui replace cum``i''=cum``i''+c`k'_``i''*`k'
label variable c`k'_``i'' "Pr(``i''=`k')"
}
qui gen Inf``i''=0
forvalues k=1/`mm' {
qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
}
if "`graphitems'"=="" {
if "`filesave'"!="" {
local fsc saving(`dirsave'//CCC_``i'',replace)
local fsi saving(`dirsave'//ICC_``i'',replace)
}
qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
}
qui replace Tcum=Tcum+cum``i''
qui replace TInf=TInf+Inf``i''
label variable Inf``i'' "``i''"
}
if "`filesave'"!="" {
local fst saving(`dirsave'//TCC,replace)
local fsteo saving(`dirsave'//TCCeo,replace)
local fsi saving(`dirsave'//ICC,replace)
local fsti saving(`dirsave'//TIC,replace)
local fsm saving(`dirsave'//map,replace)
}
qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait") `fsi'
qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait") `fsti'
local scatteri
forvalues g=1/`nbgroups' {
local x=`groups'[`g',`=`nbitems'+1']
local y=`groups'[`g',`=`nbitems'+3']
local s1=`groups'[`g',`=`nbitems'+2']
local seuil=30
local s vtiny
*set trace on
foreach lab in tiny vsmall small medsmall medium medlarge large vlarge huge vhuge /*ehuge*/ {
if `s1'>`seuil' {
local s `lab'
}
local seuil=`seuil'+10
}
local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
}
qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
/*************************************************************************************************************
MAP
*************************************************************************************************************/
gen eff=0
local effmax=0
forvalues g=1/`nbgroups' {
local eff=`groups'[`g',`=`nbitems'+2']
if `groups'[`g',`=`nbitems'+2']>`effmax' {
local effmax=`groups'[`g',`=`nbitems'+2']
}
local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
*di "replace eff=`eff' if round(u,0.004)==`lat'"
qui replace eff=`eff' if round(u,0.004)==`lat'
}
gen density=normalden(u)*sqrt(`covariates'[1,1])
label variable eff "Frequencies"
label variable u "Latent trait"
label variable TInf "Information curve"
label variable density "Density function of the latent trait"
local scatteri
qui su u if eff!=0
local floor=floor(`r(min)')
local ceil=ceil(`r(max)')
forvalues i=1/`nbitems' {
local color`i':word `i' of `color'
local y=-`i'*`effmax'/`nbitems'
forvalues l=1/`modamax' {
local x=`diffmat'[`i',`l']
local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
if `x'<`floor' {
local floor=floor(`x')
}
if `x'>`ceil' {
local ceil=ceil(`x')
}
}
local scatteri `scatteri' || scatteri `y' `floor' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
}
qui su eff
local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
qui su TInf
local maxi=ceil(`r(max)')
qui su density
local maxd=ceil(`r(max)')
qui drop if u<`floor'|u>`ceil'
qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(`floor'(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3)) `scatteri' , name(map,replace) ytitle("Frequencies") ylabel(-`maxi'(`=`maxi'/5')`maxi' ,axis(2)) ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait") xtitle("Latent trait") `fsm'
qui clear
qui use `savefile'
}
/*************************************************************************************************************
RESULTS BY GROUP
*************************************************************************************************************/
di
di as text "{hline 57}"
di _col(31) "Latent Variable" _col(50) "Expected"
di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score"
di as text "{hline 57}"
*set trace on
forvalues g=1/`nbgroups' {
qui count if `group'==`g'
local eff`g'=r(N)
qui count if `score'!=.&`group'==`g'
local n=r(N)
di as text "`g' (n=" as result `eff`g'' as text ")" _c
if `n'>0 {
qui su `score' if `group'==`g'
local scoremin`g'=`r(min)'
local scoremax`g'=`r(max)'
forvalues s=`scoremin`g''/`scoremax`g'' {
qui count if `group'==`g'&`score'==`s'
local eff=r(N)
qui su `latent' if `group'==`g'&`score'==`s'
local mean=r(mean)
qui su `selatent' if `group'==`g'&`score'==`s'
local se=r(mean)
qui su `Tcum' if `group'==`g'&`score'==`s'
local exp=r(mean)
if `eff'>0 {
di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
}
}
}
qui count if `group'==`g'&`score'==.
local eff=r(N)
qui su `latent' if `group'==`g'&`score'==.
local mean=r(mean)
qui su `selatent' if `group'==`g'&`score'==.
local se=r(mean)
qui su `Tcum' if `group'==`g'&`score'==.
local exp=r(mean)
if `eff'>0 {
di as text _col(10) " ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
}
di as text "{hline 57}"
}
/*************************************************************************************************************
CREATION DU DOCX
*************************************************************************************************************/
if "`docx'"!="" {
putdocx clear
putdocx begin
putdocx paragraph
putdocx text ("General informations") , bold underline font(,14) smallcaps
putdocx paragraph
putdocx text ("Number of individuals: `nbobs'")
putdocx paragraph
putdocx text ("Number of complete individuals: `nbobsssmd'")
putdocx paragraph
putdocx text ("Number of items: `nbitems'")
putdocx paragraph
putdocx text ("List of items: `varlist'")
putdocx paragraph
putdocx text ("Date: $S_DATE, $S_TIME")
putdocx paragraph
local model Partial Credit Model (PCM)
if "`rsm'"!="" {
local model Rating Scale Model (RSM)
}
putdocx text ("Model: `model'")
putdocx paragraph
putdocx text ("Marginal log-likelihood: `ll'")
putdocx paragraph
putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)
putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)
putdocx paragraph
putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)
local extension png
}
/*************************************************************************************************************
SAUVEGARDE DES GRAPHIQUES
*************************************************************************************************************/
*set trace on
if "`filesave'"!="" {
if "`graphs'"!="" {
if "`docx'"!="" {
putdocx pagebreak
putdocx paragraph
putdocx text ("General graphs") , bold underline font(,14) smallcaps
}
foreach i in TCC TCCeo TIC IIC map {
if "`extension'"!="" {
qui graph export `dirsave'//`i'.`extension', replace name(`i')
}
*graph display `i'
*qui graph save `dirsave'//`i', replace
if "`docx'"!="" {
putdocx paragraph
putdocx image `dirsave'//`i'.png, height(10cm)
}
}
*discard
if "`graphitems'"=="" {
forvalues i=1/`nbitems' {
if "`docx'"!="" {
putdocx paragraph
putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
}
foreach j in CCC ICC residuals {
*graph display `j'``i''
*qui graph save `dirsave'//`j'_``i'', replace
if "`extension'"!="" {
qui graph export `dirsave'//`j'_``i''.`extension', replace name(`j'``i'')
}
if "`docx'"!="" {
putdocx paragraph
putdocx image `dirsave'//`j'_``i''.png , height(10cm)
}
}
}
}
}
}
if "`docx'"!="" {
putdocx save `dirsave'//`docx'.docx, replace
}
/*************************************************************************************************************
RETURNS
*************************************************************************************************************/
matrix colnames `diff'=Estimate "s.e." z p lb ul
matrix colnames `covariates'=Estimate "s.e." z p lb ul
matrix rownames `diff'=`diffname'
matrix rownames `covariates'=Variance `continuous' `catname'
return matrix difficulties=`diff'
return matrix covariates=`covariates'
restore, preserve
end

View File

@ -0,0 +1,984 @@
*! Version 3.3 25july2019
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : pcm
* Estimate the parameters of the Partial Credit Model
* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
*
*
*
* Jean-benoit Hardouin - University of Nantes - France
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2007, 2011, 2013, 2014, 2019 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define pcm, rclass
syntax varlist(min=2 numeric) [iweight] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) rsm Graphs noGRAPHItems filesave dirsave(string) docx(string) extension(string) PCE WMLiterate(int 1) GENLT(name) GENINF(name) postpce]
qui count
local nbobs=r(N)
/*************************************************************************************************************
GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
*************************************************************************************************************/
local modcont
local nbpar=0
local nbcont=0
local nbcat=0
if "`continuous'"!="" {
tokenize `continuous'
local nbcont : word count `continuous'
local continuous
forvalues i=1/`nbcont' {
local cont`i' ``i''
local continuous `continuous' ``i''
local modcont `modcont' ``i''
local ++nbpar
}
local modcont (`modcont'->T)
}
local modcat
if "`categorical'"!="" {
tokenize `categorical'
local nbcat : word count `categorical'
local categorical
forvalues i=1/`nbcat' {
local cat`i' ``i''
local categorical `categorical' ``i''
local modcat `modcat' i.``i''
qui levelsof ``i''
local levelsof``i'' `r(levels)'
local nbpar=`nbpar'+`r(r)'-1
*di "categorical : ``i'' levels : `levelsof``i'''"
}
local modcat (`modcat'->T)
}
if "`dirsave'"=="" {
local dirsave `c(pwd)'
}
if "`genlt'"!=""|"`geninf'"!="" {
capture confirm new variable `genlt' se`genlt' `geninf'
if _rc!=0 {
di in red "The variables `genlt', se`genlt' and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
exit 198
}
}
/*************************************************************************************************************
GESTION DES ITEMS ET TESTS
*************************************************************************************************************/
tokenize `varlist'
local nbitems : word count `varlist'
marksample touse ,novarlist
*preserve
local modamax=1
local modamin=0
local pbmin
local nbdiff=0
forvalues i=1/`nbitems' {
qui su ``i''
if `r(min)'!=`modamin' {
local modamin=r(min)
local pbmin `pbmin' ``i''
}
if `r(max)'>`modamax' {
local modamax=r(max)
}
local modamax``i''=r(max)
if "`rsm'"=="" {
local nbdiff=`nbdiff'+`modamax``i'''
}
}
if "`rsm'"!="" {
local nbdiff=`nbitems'+`modamax'-1
}
if `modamin'!=0 {
di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
error 198
}
qui count
local nbind=r(N)
*set trace on
local code
forvalues k=1/`modamax' {
local code`k'
forvalues i=1/`nbitems' {
if `k'<=`modamax``i''' {
local code`k' `code`k'' `k'.``i''
}
}
local code`k' (`code`k''<-T@`k')
local code `code' `code`k''
}
/*************************************************************************************************************
OPTION PCE
*************************************************************************************************************/
if "`pce'"!=""&"`difficulties'"=="" {
tempname sedelta b
qui raschpce `varlist'
local ll=r(ll)
matrix `sedelta'=r(sedelta)
matrix `sedelta'=`sedelta''
matrix `b'=r(b)
*matrix `b'=`b''
local difficulties `b'
*matrix list `b'
matrix loulou=`b'
return matrix diff_parm=`b'
`qui' pcm `varlist', diff(loulou) geninf(TInf_0) genlt(lt_0) /*postpce*/
*exit
}
/*************************************************************************************************************
RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
*************************************************************************************************************/
if "`difficulties'"!=""&"`rsm'"!="" {
di as error "You can not defined in the same time the difficulties and the rsm options"
error 198
}
if "`difficulties'"!="" {
tempname beta
matrix `beta'=J(`nbitems',`modamax',.)
local t=1
local constraints
matrix list `difficulties'
forvalues i=1/`nbitems' {
forvalues k=1/`modamax``i''' {
if `difficulties'[`i',`k']==. {
di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
error 198
}
else {
if `k'==1 {
matrix `beta'[`i',1]=-`difficulties'[`i',1]
}
else {
matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
}
constraint `t' [`k'.``i'']_cons=`beta'[`i',`k']
local constraints `constraints' `t'
local ++t
}
}
}
}
/*************************************************************************************************************
DEFINITION DES CONTRAINTES POUR UN RSM
*************************************************************************************************************/
if "`rsm'"!="" {
local t=1
local constraints
forvalues k=2/`modamax' {
forvalues i=2/`nbitems' {
constraint `t' [`=`k'-1'.``i'']_cons-[`k'.``i'']_cons+[1.``i'']_cons=[`=`k'-1'.`1']_cons-[`k'.`1']_cons+[1.`1']_cons
local constraints `constraints' `t'
local ++t
}
}
}
/*************************************************************************************************************
MODELE
*************************************************************************************************************/
discard
*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')"
local qui qui
if "`model'"!="" {
local qui
}
`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints')
local ll=e(ll)
*set trace on
tempvar latent score group selatent latent2
tempname groups
*capture qui predict mu, mu
*su mu
qui predict `latent',latent se(`selatent')
if "`genlt'"!="" {
gen `genlt'=`latent'
gen se`genlt'=`selatent'
}
set seed 123456
qui gen `latent2'=`latent'+invnorm(uniform())*`selatent'
qui genscore `varlist',score(`score')
qui gengroup `latent',newvariable(`group') continuous
qui levelsof `group'
local nbgroups=r(r)
matrix `groups'=J(`nbgroups',`=`nbitems'+3',.)
forvalues g=1/`nbgroups' {
matrix `groups'[`g',`=`nbitems'+3']=0
forvalues i=1/`nbitems' {
*tab ``i'' if `group'==`g'
qui count if ``i''!=.&`group'==`g'
local n=r(N)
if `n'>0 {
qui su ``i'' if `group'==`g'
matrix `groups'[`g',`i']=r(mean)
matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
}
else {
matrix `groups'[`g',`i']=.
matrix `groups'[`g',`=`nbitems'+3']=.
}
}
qui su `latent' if `group'==`g'
matrix `groups'[`g',`=`nbitems'+1']=r(mean)
qui count if `group'==`g'
matrix `groups'[`g',`=`nbitems'+2']=r(N)
}
*matrix list `groups'
qui count if `score'!=.
local nbobsssmd=r(N)
di
di as text "Number of individuals:" %6.0f as result `nbobs'
di as text "Number of complete individuals:" %6.0f as result `nbobsssmd'
di as text "Number of items:" %6.0f as result `nbitems'
di as text "Marginal log-likelihood:" %12.4f as result `ll'
di
return scalar ll=`ll'
*set trace on
/*************************************************************************************************************
RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
*************************************************************************************************************/
tempname diff diffmat vardiff diffmat2
*set trace on
qui matrix `diffmat'=J(`nbitems',`modamax',.)
qui matrix `diffmat2'=J(`nbitems',`modamax',.)
qui matrix `diff'=J(`nbdiff',6,.)
local rn
*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
*matrix list `diff'
*set trace on
local t=1
forvalues i=1/`nbitems' {
qui matrix `diffmat'[`i',1]=-_b[1.``i'':_cons]
qui matrix `diffmat2'[`i',1]=-_b[1.``i'':_cons]
qui lincom -_b[1.``i'':_cons]
qui matrix `diff'[`t',1]=`r(estimate)'
qui matrix `diff'[`t',2]=`r(se)'
qui matrix `diff'[`t',3]=`r(z)'
qui matrix `diff'[`t',4]=`r(p)'
qui matrix `diff'[`t',5]=`r(lb)'
qui matrix `diff'[`t',6]=`r(ub)'
*qui matrix `vardiff'[`t',`t']=_se[1.``i'':_cons]^2
local rn `rn' 1.``i''
local ++t
local sum _b[1.``i'':_cons]
if "`rsm'"=="" {
forvalues k=2/`modamax``i''' {
local sum "_b[`k'.``i'':_cons]-(`sum')"
di "``i'' `k' `sum'"
local sum2 "_b[`=`k'-1'.``i'':_cons]-_b[`k'.``i'':_cons]"
qui lincom (`sum2')
*set trace on
qui matrix `diffmat'[`i',`k']=`r(estimate)'
qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
qui matrix `diff'[`t',1]=`r(estimate)'
qui matrix `diff'[`t',2]=`r(se)'
qui matrix `diff'[`t',3]=`r(z)'
qui matrix `diff'[`t',4]=`r(p)'
qui matrix `diff'[`t',5]=`r(lb)'
qui matrix `diff'[`t',6]=`r(ub)'
*qui matrix `vardiff'[`t',`t']=`r(se)'^2
*set trace off
local rn `rn' `k'.``i''
local ++t
}
}
}
if "`rsm'"!="" {
forvalues k=2/`modamax' {
qui lincom _b[`=`k'-1'.`1':_cons]-_b[`k'.`1':_cons]+_b[1.`1':_cons]
qui matrix `diff'[`t',1]=`r(estimate)'
qui matrix `diff'[`t',2]=`r(se)'
qui matrix `diff'[`t',3]=`r(z)'
qui matrix `diff'[`t',4]=`r(p)'
qui matrix `diff'[`t',5]=`r(lb)'
qui matrix `diff'[`t',6]=`r(ub)'
forvalues i=1/`nbitems' {
qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
}
local rn `rn' tau`k'
local ++t
}
}
local cn Estimate S.e. z p "Lower bound" "Upper Bound"
matrix colnames `diff'=`cn'
matrix rownames `diff'=`rn'
*matrix list `diff'
*matrix list `diffmat'
*matrix list `diffmat2'
*matrix list `vardiff'
/*************************************************************************************************************
RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES ET LA VARIANCE
*************************************************************************************************************/
tempname covariates
qui matrix `covariates'=J(`=`nbpar'+1',6,.)
*set trace on
if "`continuous'"!=""|"`categorical'"!="" {
qui lincom _b[/var(e.T)]
}
else {
qui lincom _b[/var(T)]
}
qui matrix `covariates'[1,1]=`r(estimate)'
qui matrix `covariates'[1,2]=`r(se)'
qui matrix `covariates'[1,3]=`r(z)'
qui matrix `covariates'[1,4]=`r(p)'
qui matrix `covariates'[1,5]=`r(lb)'
qui matrix `covariates'[1,6]=`r(ub)'
local t=2
forvalues i=1/ `nbcont' {
qui lincom `cont`i''
qui matrix `covariates'[`t',1]=`r(estimate)'
qui matrix `covariates'[`t',2]=`r(se)'
qui matrix `covariates'[`t',3]=`r(z)'
qui matrix `covariates'[`t',4]=`r(p)'
qui matrix `covariates'[`t',5]=`r(lb)'
qui matrix `covariates'[`t',6]=`r(ub)'
local ++t
}
forvalues i=1/ `nbcat' {
local first=0
foreach j in `levelsof`cat`i''' {
if `first'==0 {
local ++first
}
else {
qui lincom `j'.`cat`i''
qui matrix `covariates'[`t',1]=`r(estimate)'
qui matrix `covariates'[`t',2]=`r(se)'
qui matrix `covariates'[`t',3]=`r(z)'
qui matrix `covariates'[`t',4]=`r(p)'
qui matrix `covariates'[`t',5]=`r(lb)'
qui matrix `covariates'[`t',6]=`r(ub)'
local ++t
}
}
}
* matrix list `covariates'
/*************************************************************************************************************
OUTPUTS
*************************************************************************************************************/
if "`postpce'"=="" {
local t=1
local diffname
*set trace on
di "{hline 73}"
di as text _col(60) "<--95% IC -->"
di "Items" _col(60) "Lower" _col(68) "Upper"
di "parameters" _col(13) "category" _col(25) "Estimate" _col(37) "s.e." _col(48) "z" _col(56) "p" _col(59) " Bound" _col(68) "Bound"
di "{hline 73}"
*set trace on
forvalues i=1/`nbitems' {
*local l=1
forvalues j=1/`modamax``i''' {
if "`rsm'"==""|`j'==1 {
if `j'==1 {
di as text abbrev("``i''",19) _c
}
di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `diff'[`t',1] _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6]
local ++t
*local ++l
local diffname `diffname' `j'.``i''
}
}
}
if "`rsm'"!="" {
forvalues k=2/`modamax' {
di as text "tau`k'" as result _col(28) %5.2f `diff'[`t',1] _col(36) %5.2f `diff'[`t',2] _col(44) %5.2f `diff'[`t',3] _col(52) %5.2f `diff'[`t',4] _col(60) %5.2f `diff'[`t',5] _col(68) %5.2f `diff'[`t',6]
local diffname `diffname' tau`k'
local ++t
}
}
di as text "{hline 73}"
local t=1
local n: word count Variance `continuous'
forvalues i=1/`n' {
local v: word `i' of Variance `continuous'
di as text _col(1) %5.2f "`v'" as result _col(28) %5.2f `covariates'[`t',1] _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6]
local ++t
}
local rn Variance `continuous'
local n: word count of `categorical'
local catname
forvalues i=1/`n' {
local v: word `i' of `categorical'
local first=1
local saute=1
foreach j in `levelsof`cat`i''' {
if `saute'==0 {
if `first'==1 {
di as text _col(1) abbrev("`v'",19) _c
}
di as text _col(20) %5.2f "`j'" as result _col(28) %5.2f `covariates'[`t',1] _col(36) %5.2f `covariates'[`t',2] _col(44) %5.2f `covariates'[`t',3] _col(52) %5.2f `covariates'[`t',4] _col(60) %5.2f `covariates'[`t',5] _col(68) %5.2f `covariates'[`t',6]
local ++first
local rn `rn' `j'.`n'
local ++t
local catname `catname' `j'.`v'
}
else {
local saute=0
}
}
local ++t
}
di as text "{hline 73}"
di
qui su `latent'
qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])^2)
di as text "PSI:" as result %4.2f `PSI'
di
matrix colnames `covariates'=`cn'
matrix rownames `covariates'=`rn'
}
/*************************************************************************************************************
FIT TESTS
*************************************************************************************************************/
tempname fit
qui matrix `fit'=J(`nbitems',4,.)
matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT"
matrix rownames `fit'=`varlist'
*matrix list `fit'
tempvar Tcum TInf cum
qui gen `Tcum'=0
qui gen `TInf'=0
if "`postpce'"=="" {
di as text "{hline 90}"
di as text _col(60) "<--- Standardized --->"
di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
di as text "{hline 90}"
di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
di as text "{hline 90}"
}
*set trace on
local chi2=0
local chi2_old=0
forvalues g=1/`nbgroups' {
local chi2_g`g'=0
local chi2_old_g`g'=0
}
forvalues i=1/`nbitems' {
if "`rsm'"=="" {
local mm=`modamax``i'''
}
else {
local mm `modamax'
}
tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''
tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i''
local d=1
local d_old=1
qui gen `cum``i'''=0
qui gen `cum_old``i'''=0
forvalues k=1/`mm' {
local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
local d_old `d_old'+exp(`k'*`latent'-`diffmat2'[`i',`k'])
}
qui gen `c0_``i'''=1/(`d')
qui gen `c_old0_``i'''=1/(`d_old')
forvalues k=1/`mm' {
tempvar c`k'_``i'' c_old`k'_``i''
qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d')
qui gen `c_old`k'_``i'''=exp(`k'*`latent'-`diffmat2'[`i',`k'])/(`d')
qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k'
qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k'
}
qui gen `Inf``i'''=0
qui gen `Inf_old``i'''=0
qui gen `C``i'''=0
forvalues k=0/`mm' {
qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i'''
qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i'''
qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i'''
}
qui count if ``i''!=.
local n``i''=r(N)
qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2)
qui su `C2``i'''
local q2o``i''=(`r(mean)'-1)/((`n``i'''))
qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2
qui su `C3``i'''
local n=r(sum)
qui su `Inf``i'''
local d=r(sum)
local q2i``i''=`n'/((`d')^2)
//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"
qui replace `Tcum'=`Tcum'+`cum``i'''
qui replace `TInf'=`TInf'+`Inf``i'''
qui gen `y``i'''=``i''-`cum``i'''
qui gen `y_old``i'''=``i''-`cum_old``i'''
qui gen `y2``i'''=(`y``i''')^2
qui gen `y2_old``i'''=(`y_old``i''')^2
qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i'''))
local chi2_``i''=0
local chi2_old_``i''=0
forvalues g=1/`nbgroups' {
qui su `y2``i''' if `group'==`g'
local n=r(sum)
qui su ``i'' if `group'==`g'
local n1=r(sum)
qui su `cum``i''' if `group'==`g'
local n2=r(sum)
qui su `Inf``i''' if `group'==`g'
local d=r(sum)
*di "chi2_`g'_``i''=`chi2'+(`n1'-`n2')^2/(`d')"
local chi2=`chi2'+(`n1'-`n2')^2/(`d')
local chi2_``i''=`chi2_``i'''+(`n1'-`n2')^2/(`d')
local chi2_g`g'=`chi2_g`g''+(`n1'-`n2')^2/(`d')
qui su `y2_old``i''' if `group'==`g'
local n_old=r(sum)
qui su ``i'' if `group'==`g'
local n1_old=r(sum)
qui su `cum_old``i''' if `group'==`g'
local n2_old=r(sum)
qui su `Inf_old``i''' if `group'==`g'
local d_old=r(sum)
local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
}
*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2' Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
*su `z``i'''
label variable `z``i''' "Standardized residuals associated to ``i''"
label variable `latent' "Latent trait"
*set trace on
if "`graphs'"!=""&"`graphitems'"=="" {
if "`filesave'"!="" {
local fs saving(`dirsave'//residuals_``i'',replace)
}
qui graph twoway scatter `z``i''' `latent', name(residuals``i'',replace) title("Standardized residuals associated to ``i''") `fs'
}
*set trace off
qui gen `z2``i'''=(`z``i''')^2
qui su `z2``i'''
local OUTFIT``i''=`r(mean)'
qui matrix `fit'[`i',1]=`OUTFIT``i'''
local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
qui matrix `fit'[`i',3]=`OUTFITs``i'''
qui su `Inf``i''' if ``i''!=.
local sumw``i''=r(sum)
qui gen `i``i'''=`Inf``i'''*`z2``i'''
qui su `i``i''' if ``i''!=.
local INFIT``i'' = `=`r(sum)'/`sumw``i''''
qui matrix `fit'[`i',2]=`INFIT``i'''
local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
qui matrix `fit'[`i',4]=`INFITs``i'''
if "`postpce'"=="" {
di abbrev("``i''",19) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i'''
}
}
if "`postpce'"=="" {
di as text "{hline 90}"
di as text "*: As suggested by Wright (Smith, 1998)
di as text "**: As suggested by Bond and Fox (2007)
}
if "`geninf'"!="" {
gen `geninf'=`TInf'
}
*set trace off
/*************************************************************************************************************
ESTIMATION OF THE WEIGHTED ML ESTIMATORS
**************************************************************************************************************/
*set trace on
di "estimation `wmliterate'"
if "`postpce'"!="" {
local conv=10
local it=`wmliterate'
di "Iteration : `it'"
while(`conv'>=1) {
di "Itération `it' : conv=`conv'"
tempvar sinf
qui gen `sinf'=sqrt(TInf_`=`it'-1')
`qui' pcm `varlist' [iweight=`sinf'],diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it')
tempvar ecart_`it'
qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1')
qui su `ecart_`it''
local conv =r(mean)
local ++it
}
exit
}
/*************************************************************************************************************
Categories/Items/Test Characteristics Curves and Information graphs
*************************************************************************************************************/
if "`graphs'"!="" {
tempfile savefile
qui save `savefile'
qui clear
qui set obs 2000
qui gen u=(_n-1000)/250
qui gen Tcum=0
qui gen TInf=0
forvalues i=1/`nbitems' {
local scatteri`i'
forvalues g=1/`nbgroups' {
local x=`groups'[`g',`=`nbitems'+1']
local y=`groups'[`g',`i']
local s1=`groups'[`g',`=`nbitems'+2']
local seuil=30
local s vtiny
*set trace on
foreach lab in tiny vsmall small medsmall medium medlarge large vlarge huge vhuge /*ehuge*/ {
if `s1'>`seuil' {
local s `lab'
}
local seuil=`seuil'+10
}
local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
*set trace off
}
local d=1
qui gen cum``i''=0
*set trace on
if "`rsm'"=="" {
local mm=`modamax``i'''
}
else {
local mm `modamax'
}
forvalues k=1/`mm' {
local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
}
qui gen c0_``i''=1/(`d')
label variable c0_``i'' "Pr(``i''=0)"
forvalues k=1/`mm' {
qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
qui replace cum``i''=cum``i''+c`k'_``i''*`k'
label variable c`k'_``i'' "Pr(``i''=`k')"
}
qui gen Inf``i''=0
forvalues k=1/`mm' {
qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
}
if "`graphitems'"=="" {
if "`filesave'"!="" {
local fsc saving(`dirsave'//CCC_``i'',replace)
local fsi saving(`dirsave'//ICC_``i'',replace)
}
qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC) of ``i'') ytitle("Probability") xtitle("Latent trait") `fsc'
qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC) of ``i''") ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi'
}
qui replace Tcum=Tcum+cum``i''
qui replace TInf=TInf+Inf``i''
label variable Inf``i'' "``i''"
}
if "`filesave'"!="" {
local fst saving(`dirsave'//TCC,replace)
local fsteo saving(`dirsave'//TCCeo,replace)
local fsi saving(`dirsave'//ICC,replace)
local fsti saving(`dirsave'//TIC,replace)
local fsm saving(`dirsave'//map,replace)
}
qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `fst'
qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("Latent trait") `fsi'
qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("Latent trait") `fsti'
local scatteri
forvalues g=1/`nbgroups' {
local x=`groups'[`g',`=`nbitems'+1']
local y=`groups'[`g',`=`nbitems'+3']
local s1=`groups'[`g',`=`nbitems'+2']
local seuil=30
local s vtiny
*set trace on
foreach lab in tiny vsmall small medsmall medium medlarge large vlarge huge vhuge /*ehuge*/ {
if `s1'>`seuil' {
local s `lab'
}
local seuil=`seuil'+10
}
local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)
}
qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo'
/*************************************************************************************************************
MAP
*************************************************************************************************************/
gen eff=0
local effmax=0
forvalues g=1/`nbgroups' {
local eff=`groups'[`g',`=`nbitems'+2']
if `groups'[`g',`=`nbitems'+2']>`effmax' {
local effmax=`groups'[`g',`=`nbitems'+2']
}
local lat=round(`groups'[`g',`=`nbitems'+1'],0.004)
*di "replace eff=`eff' if round(u,0.004)==`lat'"
qui replace eff=`eff' if round(u,0.004)==`lat'
}
gen density=normalden(u)*sqrt(`covariates'[1,1])
label variable eff "Frequencies"
label variable u "Latent trait"
label variable TInf "Information curve"
label variable density "Density function of the latent trait"
local scatteri
qui su u if eff!=0
local floor=floor(`r(min)')
local ceil=ceil(`r(max)')
forvalues i=1/`nbitems' {
local color`i':word `i' of `color'
local y=-`i'*`effmax'/`nbitems'
forvalues l=1/`modamax' {
local x=`diffmat'[`i',`l']
local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
if `x'<`floor' {
local floor=floor(`x')
}
if `x'>`ceil' {
local ceil=ceil(`x')
}
}
local scatteri `scatteri' || scatteri `y' `floor' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
}
qui su eff
local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
qui su TInf
local maxi=ceil(`r(max)')
qui su density
local maxd=ceil(`r(max)')
qui drop if u<`floor'|u>`ceil'
qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(`floor'(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3)) `scatteri' , name(map,replace) ytitle("Frequencies") ylabel(-`maxi'(`=`maxi'/5')`maxi' ,axis(2)) ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("Red line: Information curve - Green line : Density of the latent trait") xtitle("Latent trait") `fsm'
qui clear
qui use `savefile'
}
/*************************************************************************************************************
RESULTS BY GROUP
*************************************************************************************************************/
di
di as text "{hline 57}"
di _col(31) "Latent Variable" _col(50) "Expected"
di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score"
di as text "{hline 57}"
*set trace on
forvalues g=1/`nbgroups' {
qui count if `group'==`g'
local eff`g'=r(N)
qui count if `score'!=.&`group'==`g'
local n=r(N)
di as text "`g' (n=" as result `eff`g'' as text ")" _c
if `n'>0 {
qui su `score' if `group'==`g'
local scoremin`g'=`r(min)'
local scoremax`g'=`r(max)'
forvalues s=`scoremin`g''/`scoremax`g'' {
qui count if `group'==`g'&`score'==`s'
local eff=r(N)
qui su `latent' if `group'==`g'&`score'==`s'
local mean=r(mean)
qui su `selatent' if `group'==`g'&`score'==`s'
local se=r(mean)
qui su `Tcum' if `group'==`g'&`score'==`s'
local exp=r(mean)
if `eff'>0 {
di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
}
}
}
qui count if `group'==`g'&`score'==.
local eff=r(N)
qui su `latent' if `group'==`g'&`score'==.
local mean=r(mean)
qui su `selatent' if `group'==`g'&`score'==.
local se=r(mean)
qui su `Tcum' if `group'==`g'&`score'==.
local exp=r(mean)
if `eff'>0 {
di as text _col(10) " ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp'
}
di as text "{hline 57}"
}
/*************************************************************************************************************
CREATION DU DOCX
*************************************************************************************************************/
if "`docx'"!="" {
putdocx clear
putdocx begin
putdocx paragraph
putdocx text ("General informations") , bold underline font(,14) smallcaps
putdocx paragraph
putdocx text ("Number of individuals: `nbobs'")
putdocx paragraph
putdocx text ("Number of complete individuals: `nbobsssmd'")
putdocx paragraph
putdocx text ("Number of items: `nbitems'")
putdocx paragraph
putdocx text ("List of items: `varlist'")
putdocx paragraph
putdocx text ("Date: $S_DATE, $S_TIME")
putdocx paragraph
local model Partial Credit Model (PCM)
if "`rsm'"!="" {
local model Rating Scale Model (RSM)
}
putdocx text ("Model: `model'")
putdocx paragraph
putdocx text ("Marginal log-likelihood: `ll'")
putdocx paragraph
putdocx text ("Estimation of the parameters") , bold underline font(,14) smallcaps
putdocx table tablename = matrix(`diff') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)
putdocx table tablename = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)
putdocx paragraph
putdocx text ("Fit indexes for items") , bold underline font(,14) smallcaps
putdocx table tablename = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)
local extension png
}
/*************************************************************************************************************
SAUVEGARDE DES GRAPHIQUES
*************************************************************************************************************/
*set trace on
if "`filesave'"!="" {
if "`graphs'"!="" {
if "`docx'"!="" {
putdocx pagebreak
putdocx paragraph
putdocx text ("General graphs") , bold underline font(,14) smallcaps
}
foreach i in TCC TCCeo TIC IIC map {
if "`extension'"!="" {
qui graph export `dirsave'//`i'.`extension', replace name(`i')
}
*graph display `i'
*qui graph save `dirsave'//`i', replace
if "`docx'"!="" {
putdocx paragraph
putdocx image `dirsave'//`i'.png, height(10cm)
}
}
*discard
if "`graphitems'"=="" {
forvalues i=1/`nbitems' {
if "`docx'"!="" {
putdocx paragraph
putdocx text ("Graphs for ``i''") , bold underline font(,14) smallcaps
}
foreach j in CCC ICC residuals {
*graph display `j'``i''
*qui graph save `dirsave'//`j'_``i'', replace
if "`extension'"!="" {
qui graph export `dirsave'//`j'_``i''.`extension', replace name(`j'``i'')
}
if "`docx'"!="" {
putdocx paragraph
putdocx image `dirsave'//`j'_``i''.png , height(10cm)
}
}
}
}
}
}
if "`docx'"!="" {
putdocx save `dirsave'//`docx'.docx, replace
}
/*************************************************************************************************************
RETURNS
*************************************************************************************************************/
matrix colnames `diff'=Estimate "s.e." z p lb ul
matrix colnames `covariates'=Estimate "s.e." z p lb ul
matrix rownames `diff'=`diffname'
matrix rownames `covariates'=Variance `continuous' `catname'
return matrix difficulties=`diff'
return matrix covariates=`covariates'
capture restore, not
end

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,126 @@
{smcl}
{* Mars 2012}{...}
{hline}
help for {hi:pcmodel}{right:JFH}
{hline}
{title:Estimation of the parameters of a Partial Credit Model}
{p 8 14 2}{cmd:pcmodel} (varlist) [{cmd:if} {it:exp}],
[{cmdab:qual:itatives}({it:varlist})
{cmdab:quant:itatives}({it:varlist})
{cmdab:dif:ficulties}({it:matrix list})
{cmdab:it:erate}(#)
{cmdab:ad:apt}
{cmdab:ro:bust}
{cmdab:f:rom}(matrix)]
{title:Description}
{p 8 14 2}{cmd:pcmodel} allows estimating the parameters of a random effect
partial credit model (the item difficulties, and the potential covariates
that may influence the considered latent trait are considered as fixed effects.
The individual latent traits are considered as a normally distributed
random effect){p_end}
{p 14 14 2}Two situations are possible:{p_end}
{p 14 14 2}- The item difficulties can be
considered as already known. They do not have to be estimated during the
analysis.{p_end}
{p 14 14 2}- The difficulties are considered as unknowns, and then require
to be estimated during the analysis. {p_end}
{p 14 14 2}It is possible to include covariates (that can possibly influence
the individual latent traits) in the partial credit model. These covariates
can either be qualitative or quantitative. {p_end}
{p 14 14 2}{cmd:pcmodel} provides assistance for interpreting the estimated
effects of covariates (estimation of the type III sum of squares, percentage
of variance explained with the introduction of each covariates). {p_end}
{p 14 14 2}It is finally possible to thest the fit using {cmd:pcmtest} after
estimating parameters of the model with {cmd:pcmodel}
{title:Options}
{p 4 8 2}{cmdab:qual:itatives} List of the categorical covariates included in
the partial credit model
{p 4 8 2}{cmdab:quant:itatives} List of the continuous covariates included in
the partial credit model
{p 4 8 2}{cmd:difficulties} Row vectors containing the considered known values
of each item difficulty. A row vector must match with each item, and have the
same name as the corresponding item. The item difficulties should be known for
all the items. If {cmd:difficulties} is not filled, the dificulties are
considered as unknown, and are estimated during the analysis.
{p 4 8 2}{cmd:iterate} specifies the (maximum) number of iterations. With the
adapt option, use of the iterate(#) option will cause pcmodel to skip the
"Newton Raphson" iterations usually performed at the end without updating
the quadrature locations.
{p 4 8 2}{cmd:adapt} causes adaptive quadrature to be used instead of
ordinary quadrature.
{p 4 8 2}{cmd:robust} specifies that the Huber/White/sandwich estimator of the
covariance matrix of the parameter estimates is to be used.
{p 4 8 2}{cmd:from} specifies a row vector to be used for the initial values.
Note that the column-names and equation-names do not have to be correct. This
line vector must have exactly the number of parameters to be estimated,
starting with the difficulties parameters, then the parameters associated
with the covariates, and finishing with the estimated standard deviation
of the latent trait.
{title:Outputs}
{p 4 8 2}{cmd:e(lll)}: (marginal) log-likelihood
{p 4 8 2}{cmd:e(cn)}: Condition number
{p 4 8 2}{cmd:e(N)}: Number of observations
{p 4 8 2}{cmd:e(Nit)}: Number of items
{p 4 8 2}{cmd:e(Nqual)}: Number of qualitative covariates
{p 4 8 2}{cmd:e(Nquant)}: Number of quantitative covariates
{p 4 8 2}{cmd:e(items)}: program used to implement {cmdpcmtest}
{p 4 8 2}{cmd:e(itest)}: program used to implement {cmdpcmtest}
{p 4 8 2}{cmd:e(datatest)}: program used to implement {cmdpcmtest}
{p 4 8 2}{cmd:e(mugauss)}: program used to implement {cmdpcmtest}
{p 4 8 2}{cmd:e(sdgauss)}: program used to implement {cmdpcmtest}
{p 4 8 2}{cmd:e(cmd)}: program used to implement {cmdpcmtest}
{p 4 8 2}{cmd:e(sigma)}: Estimated standard deviation of the latent trait
{p 4 8 2}{cmd:e(Varsigma)}: Variance of the estimated standard deviation of
the latent trait
{p 4 8 2}{cmd:e(b)}: coefficient vector of the parameters associated with
the latent trait covariates (if no covariate is included in the model, value
of the average latent trait).
{p 4 8 2}{cmd:e(V)}: Covariance matrix for the latent trait covariates.
{p 4 8 2}{cmd:e(delta)}: Estimated difficulty parameters
{p 4 8 2}{cmd:e(Vardelta)}: Covariance matrix for the estimated difficulty
parameters
{title:Author}
{p 4 8 2}Jean-François HAMEL{p_end}
{title:Also see}
{p 4 13 2}Online: help for {help pcmtest}, {help gllamm}, {help simirt},
{help raschtest}.{p_end}

View File

@ -0,0 +1,194 @@
{smcl}
{* Mars 2012}{...}
{hline}
help for {hi:pcmodel}
{hline}
{title:Estimation of the parameters of a Partial Credit Model}
{p 8 14 2}{cmd:pcmodel} (varlist) [{help if} {help in}],
[{cmdab:cat:egorical}({it:varlist})
{cmdab:cont:inuous}({it:varlist})
{cmdab:dif:ficulties}({it:matrix list})
{cmdab:it:erate}(#)
{cmdab:ad:apt}
{cmdab:ro:bust}
{cmdab:f:rom}(matrix)
{cmdab:rsm:}
{cmdab:nip:}
{cmdab:tr:ace}
{cmdab:est:imateonly}
{cmdab:l:evel}(#)]
{title:Description}
{p 8 14 2}{cmd:pcmodel} allows estimating the parameters of a random effect
partial credit model or a random effect rating scale model
(the item difficulties, and the covariates
that may influence the considered latent trait are considered as fixed
effects, and the individual latent traits are considered as a normally distributed
random effect){p_end}
{p 14 14 2}Two situations are possible:{p_end}
{p 16 18 2}- The item difficulties can be considered as already known
(for example provided by the scale developer).
In this case, they do not have to be estimated during the analysis.{p_end}
{p 16 18 2}- The difficulties are considered as unknowns and will
be estimated during the analysis. {p_end}
{p 14 14 2}{cmd:pcmodel} allows including covariates that
can possibly influence the individual latent traits in the considered model
(partial credit or rating scale). These covariates
can either be categorical or continuous. {p_end}
{p 14 14 2}{cmd:pcmodel} provides assistance for interpreting both the quality
of model fit (by estimating the marginal McFadden's pseudo R2) and the
contribution of covariates to the model
(by estimating the the type III sum of squares, the percentage
of variance explained with the introduction of each covariates and the percentage
of McFadden's pseudo R2 explained with the introduction of each
covariate). {p_end}
{p 14 14 2}It is finally possible to test the fit using {cmd:pcmtest} after
estimating parameters of the model with {cmd:pcmodel}
{title:Options}
{p 4 8 2}{cmd:categorical} List of the categorical covariates included in
the Partial Credit model or the Rating Scale model.
{p 4 8 2}{cmd:continuous} List of the continuous covariates included in
the Partial Credit model or the Rating Scale model.
{p 4 8 2}{cmd:difficulties} Row vectors containing the known values
of each item difficulty (if they are known).
A row vector must match with each item, and have the
same name as the corresponding item. If the option {cmd:difficulties}
is not filled, the item difficulties are
considered as unknown, and they are estimated during the analysis.
(this option cannot be used with the {cmd:rsm} option
{p 4 8 2}{cmd:iterate} specifies the (maximum) number of iterations. With the
adapt option, use of the iterate(#) option will cause pcmodel to skip the
"Newton Raphson" iterations usually performed at the end without updating
the quadrature locations.
{p 4 8 2}{cmd:adapt} causes adaptive quadrature to be used instead of
ordinary quadrature.
{p 4 8 2}{cmd:robust} specifies that the Huber/White/sandwich estimator of the
covariance matrix of the parameter estimates is to be used.
{p 4 8 2}{cmd:from} specifies a row vector to be used for the initial values.
It is not necessary to specify column-names or equation-names for this line vector,
but this vector must have exactly the number of parameters to be estimated,
starting with the difficulties parameters, the parameters associated
with the covariates, and ending with the estimated standard deviation
of the latent trait.
{p 4 8 2}{cmd:rsm} performs a Rating Scale model instead of a Partial Credit model.
{p 4 8 2}{cmd:estimateonly} Do not perform the Marginal McFadden's pseudo R2
nor the type III sums of square computations
{p 4 8 2}{cmd:nip} specifies the number of integration points to be used for each
integral or summation. Only the following degrees are available: 5, 7, 9, 11, 15.
{p 4 8 2}{cmd:trace} causes more output to be displayed. Before estimation begins,
details of the specified model are displayed. In addition, a detailed iteration
log is shown including parameter estimates and log-likelihood values for each iteration.
{p 4 8 2}{cmd:level} set confidence level; default is level(95)
{title:Outputs}
{p 4 8 2}{cmd:e(ll)}: marginal log-likelihood
{p 4 8 2}{cmd:e(cn)}: Condition number
{p 4 8 2}{cmd:e(N)}: Number of observations
{p 4 8 2}{cmd:e(Nit)}: Number of items
{p 4 8 2}{cmd:e(Ncat)}: Number of categorical covariates
{p 4 8 2}{cmd:e(Ncont)}: Number of continuous covariates
{p 4 8 2}{cmd:e(sigma)}: Estimated standard deviation of the latent trait
{p 4 8 2}{cmd:e(Varsigma)}: Variance of the estimated standard deviation of
the latent trait
{p 4 8 2}{cmd:e(theta)}: Coefficient vector of the parameters associated with the latent trait covariates (if no covariate is included in the model, value of the average latent trait)
{p 4 8 2}{cmd:e(Vartheta)}: Covariance matrix for the latent trait covariates.
{p 4 8 2}{cmd:e(delta)}: Estimated difficulty parameters
{p 4 8 2}{cmd:e(Vardelta)}: Covariance matrix for the estimated difficulty parameters
{p 4 8 2}{cmd:e(b)}: Overall estimated parameters of the PCM (or RSM)
{p 4 8 2}{cmd:e(V)}: Covariance matrix for the overall estimated parameters
{marker example}{...}
{title:Example}
{pstd}
Simulation of the data (using {help simirt}):
. {cmd:simirt, nbobs(200) dim(5) rsm1(0.2) group(0.5) deltagroup(0.4) clear}{right:(1) }
{pstd}
Estimating a Partial Credit Model with {cmd:pcmodel}:
. {cmd:pcmodel item*}{right:(2) }
{pstd}
Estimating a Rating Sacle Model with {cmd:pcmodel}:
. {cmd:pcmodel item*, rsm}{right:(3) }
{pstd}
Testing the fit of the previously performed model with {help pcmtest}:
. {cmd:pcmtest, si }{right:(4) }
{pstd}
Estimating a Partial Credit Model with {cmd:pcmodel}, considering that the item difficulties
are provided by the scale developer (-1 & -0.8 for item1, -0.5 & -0.3 for item2, 0 & 0.2 for
item3, 0.5 & 0.7 for item4 and 1 & 1.2 for item5) and that the {it:group} covariate may
influence the individual latent trait:
{p 6 9 2}
1/ Defining the row vectors containing the known values of each item difficulty, with the
same name as the corresponding item:
. {cmd:matrix item1=(-1,-0.8)}{right:(5) }
. {cmd:matrix item2=(-0.5,-0.3)}{right:(6) }
. {cmd:matrix item3=(0,0.2)}{right:(7) }
. {cmd:matrix item4=(0.5,0.7)}{right:(8) }
. {cmd:matrix item5=(1,1.2)}{right:(9) }
{p 6 9 2}
2/ Estimating the Partial Credit Model with item difficulties already known, including
the {it:group} covariate as a categorical covariate:
. {cmd:pcmodel item*, difficulties(item1 item2 item3 item4 item5) cat(group)}{right:(10) }
{title:Author}
{p 4 8 2}Jean-François Hamel{p_end}
{p 4 8 2}Email:
{browse "mailto:jeanfrancois.hamel@chu-angers.fr":jeanfrancois.hamel@chu-angers.fr}{p_end}
{title:Also see}
{p 4 13 2}Online: help for {help pcmtest}, {help gllamm}, {help simirt},
{help raschtest}.{p_end}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,283 @@
*! Version 2.3 10april2014
************************************************************************************************************
* Stata program : pcm
* Estimate the parameters of the Partial Credit Model
* Version 1 : December 17, 2007
* Version 2 : July 15, 2011
* Version 2.1 : October 18th, 2011 : -fixedvar- option, new presentation
* Version 2.2 : October 23rd, 2013 : correction of -fixedvar- option
* Version 2.3 : April 10th, 2014 : correction of -fixedvar- option
*
* Jean-benoit Hardouin, EA4275 Biostatistics, Clinical Research and Subjective Measures in Health Sciences
* Faculties of Pharmaceutical Sciences & Medicine - University of Nantes - France
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2007-2014 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define pcmold,eclass
version 8.0
syntax varlist(min=3 numeric) [if] [in] [,rsm fixed(string) fixedvar(real -1) fixedmu short COVariates(varname) fixedvargroupc(string) vargroupc]
preserve
tempfile pcmfile
qui save `pcmfile',replace
if "`fixedmu'"!=""&`fixedvar'!=-1&"`covariates'"=="" {
di in red "You cannot fix in the same time the mean (fixedmu option) and the variance (fixedvar option) of the latent trait without covariables"
error 184
}
if "`fixed'"!=""&"`fixedmu'"==""&`fixedvar'!=-1&"`covariates'"=="" {
di in red "You cannot fix in the same time the difficulties (fixed option) and the variance (fixedvar option) of the latent trait without covariables"
error 184
}
/*******************************************************************************
ESTIMATION OF THE PARAMETERS
********************************************************************************/
marksample touse
qui keep if `touse'
qui count
local N=r(N)
tokenize `varlist'
local nbitems : word count `varlist'
if "`rsm'"=="" {
di in gr "Model: " in ye "Partial Credit Model"
}
else {
di in gr "Model: " in ye "Rating Scale Model"
}
tempname one var w id item it obs x chosen d score
qui gen `one'=1
qui gen `id'=_n
local modamax=0
forvalues i=1/`nbitems' {
qui rename ``i'' `var'`i'
qui su `var'`i'
local moda`i'=`r(max)'
if `modamax'<`r(max)' {
local modamax=r(max)
}
}
qui genscore `var'1-`var'`nbitems' ,score(`score')
qui collapse (sum) `w'=`one',by(`var'1-`var'`nbitems' `covariates')
qui gen `id'=_n
qui reshape long `var',i(`id') j(`item')
qui drop if `var'==.
qui gen `obs'=_n
qui expand `=`modamax'+1'
qui sort `id' `item' `obs'
by `obs', sort: gen `x'=_n-1
qui gen `chosen'=`var'==`x'
qui tab `item', gen(`it')
forvalues i=1/`nbitems' {
forvalues g=1/`modamax' {
qui gen `d'`i'_`g'=-1*`it'`i'*(`x'>=`g')
}
}
qui rename `w' `w'2
bysort `id':egen score=sum(`x'*`chosen')
qui su score
local maxscore=r(max)
if "`covariates'"!="" {
qui gen covw=`covariates'*`x'
local listcov covw
}
else {
local listcov
}
if `fixedvar'!=-1 {
local tmp=sqrt(`fixedvar')
constraint 1 `x'=`tmp'
local listconstr "constraints(1)"
local eq "eqs(slope) nrf(1)"
}
local eq "eqs(slope) nrf(1)"
*set trace on
if "`rsm'"=="" { /*PARTIAL CREDIT MODEL*/
*di "cas 1"
if "`fixed'"!="" { /*FIXED ITEMS DIFFICULTIES*/
*di "cas 2"
qui gen offset=0
local l=1
forvalues i=1/`nbitems' {
forvalues mi=1/`moda`i'' {
qui replace offset=offset+`fixed'[1,`l']*`d'`i'_`mi'
local ++l
}
}
if "`fixedmu'"!="" {
local mu
}
else {
local mu "`x'"
}
*set trace on
if "`fixedvargroupc'"!=""|"`vargroupc'"!="" {/*INEQUAL VARIANCES*/
local var0: word 1 of `fixedvargroupc'
local var1: word 2 of `fixedvargroupc'
tempvar G0 G1
qui gen `G0'=groupc<0
qui gen `G1'=groupc>0
qui replace `G0'=`G0'*`x'
qui replace `G1'=`G1'*`x'
qui eq B0: `G0'
qui eq B1: `G1'
constraint 1 _cons=0
if "`fixedvargroupc'"!="" {/*FIXED INEQUAL VARIANCES*/
constraint 2 `G0'=`=sqrt(`var0')'
constraint 3 `G1'=`=sqrt(`var1')'
local listconstr "constraints(1 2 3)"
}
else { /*FREE INEQUAL VARIANCE*/
local listconstr "constraints(1)"
}
local eq "eqs(B0 B1) nrf(2)"
}
eq slope:`x'
su
tab covw
di "ICI*******************jb"
di "`x' : x"
di "`listcov' : listcov"
di "`mu' : mu"
noi di "gllamm `x' `listcov' `mu',offset(offset) `listconstr' nocons i(`id') link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace `eq'"
*set trace on
noi gllamm `x' `listcov' `mu' ,offset(offset) `listconstr' nocons i(`id') link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace `eq' iterate(100)
}
else if "`short'"!="" {
*di "cas 3"
eq slope:`x'
qui gllamm `x' `d'1_1-`d'`nbitems'_`modamax',i(`id') eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons init iterate(100)
tempname bsave Vsave
matrix `bsave'=e(b)
matrix `Vsave'=e(V)
restore
qui pcm `varlist' , fixed(`bsave')
}
else {
*di "cas 4"
di "no short"
eq slope:`x'
qui gen i=`id'
constraint 1 `x'=1
gllamm `x' `d'1_1-`d'`nbitems'_`modamax' `listcov',i(i) `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons iterate(100)
}
}
else {
*di "cas 5"
tempname step n
forvalues i=2/`modamax' {
qui gen `step'`i'=-1*(`x'>=`i')
}
forvalues i=1/`nbitems' {
qui gen `n'`var'`i'=(-1)*(`it'`i')*(`x')
}
qui sort `id' `item' `x'
eq slope:`x'
gllamm `x' `n'`var'1-`n'`var'`nbitems' `step'2-`step'`modamax' `listcov', i(`id') `listconstr' eqs(slope) link(mlogit) expand(`obs' `chosen' o) weight(`w') adapt trace nocons iterate(100)
}
tempname b V chol
matrix b=e(b)
matrix V=e(V)
local ll=e(ll)
matrix chol=e(chol)
if "`rsm'"=="" {
di
di in gr "Number of observations: " in ye `N'
di in gr "Number of items: " in ye `nbitems'
di in gr "Number of parameters: " in ye `=`nbitems'*`modamax'+1'
di in gr "Log-likelihood: " in ye `ll'
di
di
di in gr "{hline 100}"
di in gr "Item" _col(10) "Modality" _col(20) "Parameter" _col(30) "Std Error"
di in gr "{hline 100}"
if "`fixed'"=="" {
forvalues i=1/`nbitems' {
forvalues j=1/`modamax' {
if `j'==1 {
di in ye "``i''" _cont
}
local k=(`i'-1)*`modamax'+`j'
if "`short'"!="" {
di in ye _col(17) `j' _col(20) %9.6f `bsave'[1,`k'] in ye _col(30) %9.6f (`Vsave'[`k',`k'])^.5
}
else {
di in ye _col(17) `j' _col(20) %9.6f b[1,`k'] in ye _col(30) %9.6f (V[`k',`k'])^.5
}
}
di in gr "{dup 100:-}"
}
}
else {
forvalues i=1/`nbitems' {
forvalues j=1/`modamax' {
if `j'==1 {
di in ye "``i''" _cont
}
local k=(`i'-1)*`modamax'+`j'
di in ye _col(17) `j' _col(20) %9.6f `fixed'[1,`k'] in ye _col(32) "(fixed)"
}
di in gr "{dup 100:-}"
}
}
if "`fixed'"==""&"`short'"=="" {
local k=`nbitems'*`modamax'+1
}
else if "`fixed'"!=""&"`fixedmu'"=="" {
di in ye "Mu" in ye _col(20) %9.6f b[1,1] _col(29) %10.6f (V[1,1])^.5
local k=2
}
else if "`fixed'"!=""&"`fixedmu'"!="" {
di in ye "Mu" in ye _col(20) %9.6f 0 _col(32) %10.6f "(fixed)"
local k=1
}
else {
local k=1
}
if "`covariates'"!="" {
di in ye "`covariates'" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f (V[`k',`k'])^.5
local k=`k'+1
}
if `fixedvar'==-1 {
di in ye "Sigma" in ye _col(20) %9.6f b[1,`k'] _col(29) %10.6f (V[`k',`k'])^.5
di in ye "Variance" in ye _col(20) %9.6f b[1,`k']^2 _col(29) %10.6f 2*(V[`k',`k'])^.5*b[1,`k']
}
else {
di in ye "Sigma" in ye _col(20) %9.6f `fixedvar'^.5 _col(32) %10.6f "(fixed)"
di in ye "Variance" in ye _col(20) %9.6f `fixedvar' _col(32) %10.6f "(fixed)"
}
di in gr "{hline 100}"
di
di
}
end

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
{smcl}
{* Mars 2012}{...}
{hline}
help for {hi:pcmtest}{right:JFH}
{hline}
{title:Global and item specific tests of the fit for Partial Cradit Model}
{p 8 14 2}{cmd:pcmtest}, [{cmdab:g:roup}({it:numlist})
{cmdab:n:fit}(#)
{cmdab:p:ower}(#)
{cmdab:graph:ics}(#)
{cmdab:a:lpha}(#)
{cmdab:ap:proximation}
{cmdab:n:ew}]
{title:Description}
{p 8 14 2}{cmd:pcmtest} allows to test the fit between an observed data and the
partial credit model.{p_end}
{p 14 14 2}The global test of the fit (test R1m) can only be computed if the data
contains at least two items. Item specific test of the fit (Si tests) can only be
computed if the data contains at least three items. {p_end}
{p 14 14 2}{cmd:pcmtest} is only performed if item difficulties have been
estimated using {cmd:pcmodel}. {cmd:pcmtest} can be performed either if covariates
have been included in {cmd:pcmodel} or not.
{title:Options}
{p 4 8 2}{cmd:group} specifies groups of scores, by defining the superior limits of
each group
{p 4 8 2}{cmd:nfit} specifies the size of a virtual sample with items response
distribution strictly identical to that observed ({cmd:nfit} can deal with
over-power problems when tests of the fit are performed on large samples).
{p 4 8 2}{cmd:power} specifies the desired power for a test R1m, and estimates the
corresponding size of a virtual sample with items response distribution strictly
identical to that observed.
{p 4 8 2}{cmd:alpha} specifies the type I error used to performe the tests of the fit
(default: 0.05).
{p 4 8 2}{cmd:graphics} displays several graphs (Graphical fit between the observed and
expected latent traits according to the individual scores, graphic of MAP, graphic of
groups contribution to the R1m statistic, and graphice of the observed and expected
score distribution)
{p 4 8 2}{cmd:approximation} Computation of the pattern response probabilities using
simulation instead of Gauss Hermitte quadratures. Computation should be quicker for
high number of items or responses modalities.
{p 4 8 2}{cmd:new} Do not use pattern response probabilities computed during a previous
test of the fit, compute it an other time! (allows changing the computation methodology)
{title:Author}
{p 4 8 2}Jean-François HAMEL{p_end}
{title:Also see}
{p 4 13 2}Online: help for {help pcmodel}, {help gllamm}, {help simirt}
, {help raschtest}.{p_end}

View File

@ -0,0 +1,98 @@
{smcl}
{* Mars 2012}{...}
{hline}
help for {hi:pcmtest}
{hline}
{title:Global and item specific tests of fit for a Partial Credit Model or a Rating Scale Model}
{p 8 14 2}{cmd:pcmtest}, [{cmdab:g:roup}({it:numlist})
{cmdab:ne:w}
{cmdab:nf:it}(#)
{cmdab:p:ower}(#)
{cmdab:a:lpha}(#)
{cmdab:ap:proximation}
{cmdab:s:itest}
{cmdab:graph:ics}
{cmdab:file:graph}({it:filegraph[, replace])]
{title:Description}
{p 8 14 2}{cmd:pcmtest} allows testing the fit between observed data and a
partial credit model or a rating scale model.{p_end}
{p 14 14 2}The global test of fit (test R1m) can only be computed if the data
contains at least two items. Item specific test of fit (Si tests) can only be
computed if the data contains at least three items. {p_end}
{p 14 14 2}{cmd:pcmtest} is only performed if item difficulties have been
estimated using {cmd:pcmodel}. {cmd:pcmtest} can be performed whether covariates
have been included in {cmd:pcmodel} or not.
{title:Options}
{p 4 8 2}{cmd:group} specifies groups of scores, by defining the upper limit of
each group
{p 4 8 2}{cmd:new} allows changing the computation methodology of the pattern
response probabilities between several tests of fit, rather than using the pattern
response probabilities stored in Stata memory.
{p 4 8 2}{cmd:nfit} specifies the size of a virtual sample with items response
distribution strictly identical to that observed ({cmd:nfit} can deal with
over-power problems when fit tests are performed on large samples).
{p 4 8 2}{cmd:power} specifies the desired power for a R1m test, and estimates the
corresponding size of a virtual sample with items response distribution strictly
identical to that observed.
{p 4 8 2}{cmd:alpha} specifies the type I error used to perform the test of fit
(default: 0.05).
{p 4 8 2}{cmd:approximation} Computation of the pattern response probabilities using
simulation instead of Gauss Hermitte quadratures. Computation should be quicker for
high number of items or responses categories.
{p 4 8 2}{cmd:sitest} performs item specific test of fit (Si tests).
{p 4 8 2}{cmd:graphics} displays several graphs (Distribution of the latent trait
depending on the individual scores, graphic of MAP, graphic of
the groups contributions to the R1m statistic, and graphic of the observed and expected
score distribution).
{p 4 8 2}{cmd:filegraph} indicates the filename and path for saving the graphs
(four graphs are store: {it:filegraph}_LT_Sc, {it:filegraph}_MAP, {it:filegraph}_Contrib
and {it:filegraph}_Score_Distrib.)
{title:Outputs}
{p 4 8 2}{cmd:e(globalFitTot)}: Results of the R1m test performed on the observed sample.
{p 4 8 2}{cmd:e(itemFitTot)}: Results of the Si tests performed on the observed sample.
{p 4 8 2}{cmd:e(globalFitPo)}: Results of the R1m test corresponding
to the indicated power.
{p 4 8 2}{cmd:e(itemFitPo)}: Results of the Si tests corresponding
to the indicated power.
{p 4 8 2}{cmd:e(globalFitTot)}: Results of the R1m test corresponding
to the indicated sample size.
{p 4 8 2}{cmd:e(itemFitTot)}: Results of the Si tests corresponding
to the indicated sample size.
{title:Author}
{p 4 8 2}Jean-François Hamel{p_end}
{p 4 8 2}Email:
{browse "mailto:jeanfrancois.hamel@chu-angers.fr":jeanfrancois.hamel@chu-angers.fr}{p_end}
{title:Also see}
{p 4 13 2}Online: help for {help pcmodel}, {help gllamm}, {help simirt}
, {help raschtest}.{p_end}

View File

@ -0,0 +1,66 @@
program define predraschwlm,rclass
syntax varlist , genlt(string) id(string)
tempfile filesave
qui save `filesave',replace
tempname diff theta
matrix `diff'=r(beta)
matrix `theta'=r(theta)
qui count
local N=r(N)
tokenize `varlist'
local nbitems:word count `varlist'
tempname item offset id
qui gen `id'=_n
forvalues i=0/`nbitems' {
local thetascore`i'=`theta'[1,`=`i'+1']
}
tempname nbmiss
qui egen `nbmiss'=rowmiss(`varlist')
tempfile s
qui save `s',replace
forvalues i=1/`N' {
use `s',clear
if `nbmiss'[`i']!=0 {
local w`i'=0
local l`i'=1
forvalues j=1/`nbitems' {
local item`j'=``j''[`N']
local diff`j'=`diff'[1,`j']
local rep`i'_`j'=``j''[`i']
if `rep`i'_`j''!=. {
local w`i' `w`i''+exp(x-`diff`j'')/(1+exp(x-`diff`j''))^2
local l`i' `l`i''*exp(`rep`i'_`j''*(x-`diff`j''))/(1+exp(x-`diff`j''))
}
}
local w`i' sqrt(`w`i'')
*di "`i'"
clear
qui set obs 20001
qui gen u=_n
qui gen x=(u-10001)/1000
qui gen f=`w`i''*`l`i''
qui gsort -f
local tl`i'=x[1]
}
}
qui use `filesave',clear
qui capture drop `genlt'
qui gen `genlt'=.
tempname scores
qui genscore `varlist',score(`scores')
forvalues i=0/`nbitems' {
qui replace `genlt'=`thetascore`i'' if `scores'==`i'
}
forvalues i=1/`N' {
if `genlt'[`i']==. {
qui replace `genlt'=`tl`i'' in `i' if `genlt'==.
}
}
end