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,24 @@
program define matrixlisthtml
args matrixname precision
*mat li `matrixname'
local rownames: rown `matrixname'
local colnames: coln `matrixname'
di "<tr><th></th>"
foreach mycol in `colnames' {
di "<th>" as text "`mycol'" "</th>"
}
di "</tr>"
local rowindex=1
forvalues rowptr=1/`=rowsof(`matrixname')' {
local rowname: word `rowindex' of `rownames'
di "<tr><th>" "`rowname'" "</th>"
forvalues colptr=1/`=colsof(`matrixname')' {
di "<td>" `precision' `matrixname'[`rowptr', `colptr'] "</td>"
}
di "</tr>"
local ++rowindex
}
end

View File

@ -0,0 +1,57 @@
*! version 1 19september2018
*! Jean-Benoit Hardouin
*
************************************************************************************************************
* Stata program : mdreplace
* Missing data handling in a dataset
*
* Historic
* Version 1 (2018-09-19): Jean-Benoit Hardouin
*
* Jean-benoit Hardouin, Plateforme de Méthodologie et de Biostatistique - DRCi - CHU de Nantes - France
* jean-benoit.hardouin@univ-nantes.fr
*
* Copyright 2018 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
************************************************************************************************************
program define mdreplace
version 7.0
syntax varlist(min=1) , list(string)
if "`list'"=="" {
di in red "Please indicate in the list option the strings to replace by missing data"
}
foreach i of varlist `varlist' {
foreach e in `list' {
*di "variable : `i' code : `e'"
capture replace `i'="." if `i'=="`e'"
if (_rc==0) {
qui replace `i'="" if `i'=="`e'"
}
}
capture destring `i', replace
if (_rc==0) {
qui destring `i', replace
}
}
end

View File

@ -0,0 +1,210 @@
program define mi_twoway,rclass
syntax varlist [, SCorename(string) REPlace ADD(int 10) STyle(string) clear DA ITerate(int 10)]
qui{
tempfile bddini
save `bddini', replace
if "`scorename'"==""{
local scorename score
}
capture tab `scorename'
if _rc==0{
if "`replace'"!=""{
drop `scorename'
}
else{
noi di in red "variable `scorename' already exists"
use `bddini',replace
error 100
}
}
local nombase ""
if wordcount("`style'")==0{
local style mlong
}
else if wordcount("`style'")==1{
if "`=word("`style'", 1)'"=="ml" | "`=word("`style'", 1)'"=="mlo" | "`=word("`style'", 1)'"=="mlon" | "`=word("`style'", 1)'"=="mlong" | "`=word("`style'", 1)'"=="fl" | "`=word("`style'", 1)'"=="flo" | "`=word("`style'", 1)'"=="flon" | "`=word("`style'", 1)'"=="flong" | "`=word("`style'", 1)'"=="w" | "`=word("`style'", 1)'"=="wi" | "`=word("`style'", 1)'"=="wid" | "`=word("`style'", 1)'"=="wide"{
local style `style'
}
else{
noi di in red "option {it:style} improperly fulfilled"
noi di in red " Only {it:mlong}, {it:flong}, {it:wide} and {it:flongsep} are available"
noi di in red " A database name must be proposed if the style {it:flongsep} is selected (see mi_styles)"
use `bddini',replace
error 100
}
}
else if wordcount("`style'")==2{
if "`=word("`style'", 1)'"=="flongs" | "`=word("`style'", 1)'"=="flongse" | "`=word("`style'", 1)'"=="flongsep"{
local nombase `=word("`style'", 2)'
local style `=word("`style'", 1)'
}
else{
noi di in red "option {it:style} improperly fulfilled"
noi di in red " Only {it:mlong}, {it:flong}, {it:wide} and {it:flongsep} are available"
noi di in red " A database name must be proposed if the style {it:flongsep} is selected (see mi_styles)"
use `bddini',replace
error 100
}
}
tempvar var
local M `_dta[_mi_M]'
if "`M'"!=""{
if "`clear'"==""{
noi di in red "no; data are mi set"
noi di in red " Use {it:clear} option to replace imputed values using mi_twoway, or"
noi di in red " other MI commands (like {it:mi extract})"
use `bddini',replace
error 100
}
else{
mi extract 0, clear
}
}
gen `var'id=_n
sort `var'id
save `bddini'_bis, replace
tokenize `varlist'
if `add'==.{
local add==10
}
if `iterate'==.{
local iterate==10
}
egen keep=rowmean(`varlist')
keep if keep!=.
drop keep
local Nb=_N
local nbit: word count `varlist'
egen `var'i=rowmean(`varlist')
forvalues j=1/`nbit'{
gen it_`var'_`j'=``j''
}
keep it_`var'_* `var'id `var'i
reshape long it_`var'_, i(`var'id) j(it)
rename it_`var'_ it_`var'
bysort it: egen Mj=mean(it_`var')
su it_`var'
local MM=r(mean)
gen Me=`var'i+Mj-`MM'
gen Dif2=(Me-it_`var')^2
su Dif2
local Var=r(sum)/(r(N)-1)
gen __miss=it_`var'==.
forvalues it=1/`add'{
gen _`it'_`var'=it_`var'
replace _`it'_`var'=rnormal(Me, `=sqrt(`Var')') if __miss==1
}
/* Data augmentation */
if "`da'"!=""{
gen `var'present=1-__miss
bysort `var'id: egen `var'Cpre=total(`var'present)
bysort it: egen `var'CItpre=total(`var'present)
su `var'present
local Nobs=r(sum)
gen `var'Pre=_1_`var'
su `var'Pre
local mu=r(mean)
bysort it: egen `var'Be=mean(`var'Pre)
replace `var'Be=`var'Be-`mu'
bysort `var'id: egen `var'Al=mean(`var'Pre)
gen `var'sigInt=(`var'Pre-`var'Be-`var'Al)^2
su `var'sigInt
local sigma2=r(sum)/(`nbit'-1)/(`Nb'-1)
gen `var'tauInt=(`var'Al-`mu')^2
su `var'tauInt if it==1
local tau2=r(sum)/(`Nb'-1)
forvalues it=1/`add'{
forvalues g=1/`iterate'{
/* noi di "it = `g'"*/
/* Redéfinition alpha */
capture drop A2 `var'A2 `var'A2V B2 `var'Be2 Vbe2 S2 TAU
gen A2=(it_`var'-`var'Be)/`sigma2'
bysort `var'id: egen `var'A2=total(A2)
replace `var'A2=(`var'A2+`mu'/`tau2')/(1/`tau2' + `var'Cpre/`sigma2')
gen `var'A2V=sqrt(1/(1/`tau2'+`var'Cpre/`sigma2'))
replace `var'Al=rnormal(`var'A2, `var'A2V)
/* Redéfinition beta */
gen B2=(it_`var'-`var'Al)
bysort it: egen `var'Be2=mean(B2)
gen Vbe2=sqrt(`sigma2'/`var'CItpre)
replace `var'Be=rnormal(`var'Be2, Vbe2)
/* Redefinition Sigma */
gen S2=(it_`var'-`var'Al-`var'Be)^2
su S2
local sigma2b=`=r(N)'*`r(mean)'/rchi2(`=r(N)')
if `sigma2b'!=0{
local sigma2=`sigma2b'
}
/* Redefinition mu */
su `var'Al if it==1
local mu=rnormal(`=r(mean)', `=sqrt(`tau2'/r(N))')
/* Redefinition tau2 */
gen TAU=(`var'Al-`mu')^2
su TAU if it==1
local tau2b=`=r(N)'*`r(mean)'/rchi2(`=r(N)')
/* 1/(rgamma(`=r(N)/2', `=2/r(N)/r(mean)')) OU `=r(N)'*`r(mean)'/rchi2(`=r(N)')*/
if `tau2b'!=0{
local tau2=`tau2b'
}
/*noi di "mu: `mu' tau2: `tau2' sigma2: `sigma2'"
noi su `var'Al `var'Be*/
}
replace _`it'_`var'=rnormal(`mu',`=sqrt(`tau2')')+`var'Be+rnormal(0,`=sqrt(`sigma2')') if __miss==1
}
}
/* Fin de data augmentation */
bysort `var'id: egen _mi_miss=max(__miss)
drop Mj Me Dif2 `var'i __miss
keep *_`var' `var'id it _mi_miss
reshape wide *_`var', i(`var'id) j(it)
egen `scorename'=rowtotal(it_`var'*)
replace `scorename'=. if _mi_miss==1
forvalues j=1/`add'{
egen _`j'_`scorename'=rowtotal(_`j'_*), missing
}
forvalues i=1/`nbit'{
rename it_`var'`i' ``i''
forvalues j=1/`add'{
rename _`j'_`var'`i' _`j'_``i''
label variable _`j'_``i'' ""
}
}
drop `varlist'
order `scorename' _mi_miss, first
sort `var'id
save `bddini'_ter, replace
use `bddini'_bis
merge `var'id using `bddini'_ter
drop _merge `var'id
char _dta[_mi_pvars] `scorename'
char _dta[_mi_M] `add'
char _dta[_mi_ivars] `varlist'
char _dta[_mi_style] wide
char _dta[_mi_marker] _mi_ds_1
char _dta[_miTW] TW
mi convert `style' `nombase', clear
}
end

View File

@ -0,0 +1,97 @@
{smcl}
{hline}
{hline}
help for {hi:mi_twoway}{right:Jean-François HAMEL}
{hline}
{title:Two-way imputations: estimating missing item responses in questionnaires for computing scores}
{p 8 14 2}{cmd:mi_twoway} {it:varlist}, [{cmdab:sc:orename}({it:newvarname})
{cmdab:rep:lace}
{cmdab:add:}({it:#})
{cmdab:st:yle}({it:keyword})
{cmdab:clear}
{cmdab:da}
{cmdab:it:erate}({it:#})]
{title:Description}
{p 8 14 2}{cmd:mi_twoway} is an implementation of multiple imputation methods for tests and questionnaires
based on a two-way ANOVA model of persons by items.{p_end}
{p 14 14 2}Two methods are available: imputations based on a fixed effects two-way ANOVA, and imputations
generated using data augmentation based on a mixed effect two-way ANOVA (with a random person effect
assumed to follow a Norma distribution and a fixed item effect.{p_end}
{p 14 14 2}{cmd:mi_twoway} is compatible with the Sata {help mi} procedures. The data is {help mi_set:set}
and {help mi_impute:imputed} using {cmd:mi_twoway}, but all the estimations using multiple imputations are
performed using the standard mi {help mi_estimate:estimate} procedures.
{p 4 8 2}{it:varlist} is the list of the variables containing the item responses of the questionnaire
(with possible missing data).
{title:Options}
{p 4 14 2}{cmd:scorename} specifies the name of the new variable containing, for each individual, the value of the
score computed as the sum of the item responses. {it:scorename} is missing for each individual with at least one item
missing response.
{p 4 14 2}{cmd:replace} allows to replace individual scores in existing variables
{p 4 14 2}{cmd:add} specifies the number of imputations to add; required with no imputations
{p 4 14 2}{cmd:style} specifies in which style should be recorded the data: wide, mlong, flong,
or flongsep; see {help mi_styles:[MI] styles}.
{p 4 14 2}{cmd:clear} allows performing new imputations by remouving the previous one.
{p 4 14 2}{cmd:da} generates imputations using data augmentation based on a mixed effect two-way
ANOVA (with a random person effect and a fixed item effect. By default, imputations are generated
using a fixed effects two-way ANOVA.
{p 4 14 2}{cmd:iterate} defines the number of iterations of the data augmentation algorithm.
By default, this number is fixed to 10.
{marker example}{...}
{title:Example}
{pstd}
Simulation of the data (using {help simirt}):
{cmd:. simirt, nbobs(200) dim(5) group(0.5) deltagroup(0.4) clear}{right:(1) }
{pstd}
Creating the missing data, with a non-response rate of 10%:
. {cmd:set more off }{right:(2) }
. {cmd:forvalues i=1/200{c -(} }{right:(3) }
2. {cmd:forvalues j=1/5{c -(}}{right:(4) }
3. {cmd:replace item`j'=. if runiform()<0.1 & id==`i'}{right:(5) }
4. {cmd:{c )-}}{right:(6) }
5. {cmd:{c )-}}{right:(7) }
{pstd}
Generating 10 multiple imputations using a fixed effects two-way ANOVA:
. {cmd:mi_twoway item*, scorename(score) add(10) style(wide)}{right:(8) }
{pstd}
Modeling score depending on {it:group} covariate using multiple imputations estimates ({help mi_estimate}):
. {cmd:mi estimate: regress score i.group}{right:(9) }
{pstd}
Changing the way to impute data, using data augmentation based on a mixed effect two-way ANOVA:
. {cmd:mi_twoway item*, scorename(score) replace add(10) style(wide) da clear}{right:(10) }
{pstd}
Changing the style of the data from {it:wide} to {it:mlong} ({help mi_convert}):
. {cmd:mi convert mlong}{right:(11) }
{pstd}
Removal of the multiple imputations ({help mi_set##unset:mi_unset}):
. {cmd:mi extract 0, clear}{right:(12) }

View File

@ -0,0 +1,320 @@
*! Version 4 7December2012
************************************************************************************************************
* Stata program : mmsrm
* Estimate the parameters of the Multidimensional Marginally Sufficient Rasch Model (MMSRM)
* Version 4 : December 7, 2012 /* id option*/
*
* Historic :
* Version 1 (May 14, 2004) [Jean-Benoit Hardouin]
* Version 2 (May 26, 2004) [Jean-Benoit Hardouin]
* Version 3 (July 3, 2005) [Jean-Benoit Hardouin]
* Version 3.1 : July 8, 2010 /* correction of a bug for the name of the items */
*
* Jean-benoit Hardouin, phD, Assistant Professor
* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE)
* University of Nantes - Faculty of Pharmaceutical Sciences
* France
* jean-benoit.hardouin@anaqol.org
*
* Use the Stata programs raschtest and gammasym who can be download on http://anaqol.free.fr
* Use the Stata program gllamm who can be obtained by : ssc install gllamm
* News about this program :http://anaqol.free.fr
*
* Copyright 2004-2005, 2010, 2012 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
************************************************************************************************************
program define mmsrm,eclass
version 8.0
syntax varlist(min=3 numeric) [if] [in] , id(varname) [PARTition(numlist) NODETails TRAce ITerate(int 30) ADapt METHod(string)]
preserve
tempfile mmsrmfile
qui save `mmsrmfile',replace
/*******************************************************************************
INTRODUCTION AND TESTS
********************************************************************************/
marksample touse
qui keep if `touse'
local nbitems : word count `varlist'
if "`partition'"=="" {
local partition=`nbitems'
}
if "`method'"=="" {
local method mml
}
local method=lower("`method'")
local nbpart:word count `partition'
if `nbpart'>3 {
di in red "{p}The mmsrm module cannot estimate the parameters of the models with more than three dimensions.{p_end}"
error 198
exit
}
else if `nbpart'==3&"`method'"=="gee" {
di in red "{p}You cannot estimate the parameters of a MMSRM with 3 dimension and the GEE method.{p_end}"
error 198
exit
}
if "`adapt'"!=""&"`method'"!="mml" {
di in green "{p}the {cmd:adapt} option is ignored with GEE.{p_end}"
}
local comptitems=0
tokenize `varlist'
forvalues i=1/`nbpart' {
local firstpart`i'=`comptitems'+1
local part`i': word `i' of `partition'
local set`i'
local comptitems=`comptitems'+`part`i''
forvalues j=`firstpart`i''/`comptitems' {
local set`i' "`set`i'' ``j''"
}
}
if `comptitems'<`nbitems' {
di in error "{p}Your {cmd:partition} describes less items than the number of items defined in the {it:varlist}.{p_end}"
error 198
exit
}
if `comptitems'>`nbitems' {
di in error "{p}Your {cmd:partition} describes more items than the number of items defined in the {it:varlist}.{p_end}"
error 198
exit
}
/*******************************************************************************
FORMATING AND ESTIMATION (with MML)
********************************************************************************/
if `nbpart'== 1 {
raschtestv7 `varlist', test(none) method(`method') id(`id')
local ll=r(ll)
tempname beta1 Varbeta1 M
matrix `beta1'=r(beta)
matrix `Varbeta1'=r(Varbeta)
local sigma1=r(sigma)
matrix `M'=(`sigma1'^2)
}
else if "`method'"=="mml" {
forvalues i=1/`nbpart' {
if "`details'"=="" {
di in green "{p}Estimation of the difficulty parameters of the dimension `i'.{p_end}"
}
*set trace on
if `part`i''>1 {
qui raschtestv7 `set`i'',meth(`method') test(none) id(`id')
tempname beta`i' Varbeta`i'
matrix `beta`i''=r(beta)
matrix `Varbeta`i''=r(Varbeta)
local sigma`i'=r(sigma)
forvalues j=1/`part`i'' {
local parambeta`=`firstpart`i''+`j'-1'=`beta`i''[1,`j']
}
}
else {
qui count
local N=r(N)
qui count if ``firstpart`i'''==1
local pos=r(N)
local parambeta`firstpart`i''=-log(`pos'/(`N'-`pos'))
local sigma`i'=0
}
}
if "`details'"=="" {
di
di in green "{p}Estimation of the parameters of the distribution of the multidimensional latent trait.{p_end}"
di in green "{p}This process could be long to run. Be patient !{p_end}"
}
keep `varlist'
tempname rep id item offset
forvalues i=1/`nbitems' {
rename ``i'' `rep'`i'
}
gen `id'=_n
qui reshape long `rep', i(`id') j(`item')
gen `offset'=0
label variable `offset' "offset"
forvalues i=1/`nbitems' {
qui replace `offset'=-`parambeta`i'' if `item'==`i'
}
local eqs
forvalues i=1/`nbpart' {
tempname B`i'
gen `B`i''=0
eq sc`i':`B`i''
local eqs `eqs' sc`i'
forvalues j=`firstpart`i''/`=`firstpart`i''+`part`i''-1' {
qui replace `B`i''=1 if `item'==`j'
}
}
label variable `rep' "response"
label variable `id' "identifiant"
tempname first
local four=substr("`id'",1,3)
matrix define `first'=(0,`sigma1',0,`sigma2')
matrix colnames `first'=`rep':_cons `four'1_1:`B1' `four'1_2:`B2' `four'1_2_1:_cons
if "`trace'"!="" {
local quigllamm
}
else {
local quigllamm qui
}
`quigllamm' gllamm `rep', from(`first') link(logit) fam(bin) i(`id') offset(`offset') nrf(`nbpart') eqs(`eqs') nip(6) dots `trace' `adapt' iterate(`iterate')
local ll=e(ll)
tempname cosig varsig L M
matrix `cosig'=e(b)
matrix `varsig'=e(V)
matrix `L'=e(chol)
matrix `M'=`L'*`L''
}
/*******************************************************************************
FORMATING AND ESTIMATION (with GEE)
********************************************************************************/
else if "`method'"=="gee" {
tempname coef
matrix `coef'=J(`nbitems',`nbpart',0)
forvalues i=1/`nbpart' {
forvalues j=`firstpart`i''/`=`firstpart`i''+`part`i''-1' {
matrix `coef'[`j',`i']=1
}
}
if "`trace'"!="" {
local quigee
}
else {
local quigee quietly
}
`quigee' geekel2d `varlist',coef(`coef') ll nbit(`iterate')
local ll=r(ll)
tempname cosig varsig M
matrix `cosig'=r(b)
matrix `M'=J(2,2,0)
matrix `M'[1,1]=`cosig'[1,`=`nbitems'+1']
matrix `M'[2,2]=`cosig'[1,`=`nbitems'+2']
matrix `M'[1,2]=`cosig'[1,`=`nbitems'+3']
matrix `M'[2,1]=`cosig'[1,`=`nbitems'+3']
matrix `cosig'=`cosig'[1,1..`nbitems']
matrix `varsig'=r(V)
matrix `varsig'=`varsig'[1..`nbitems',1..`nbitems']
forvalues i=1/`nbpart' {
tempname beta`i' Varbeta`i'
matrix `beta`i''=`cosig'[1,`firstpart`i''..`=`firstpart`i''+`part`i''-1']
matrix `Varbeta`i''=`varsig'[`firstpart`i''..`=`firstpart`i''+`part`i''-1',`firstpart`i''..`=`firstpart`i''+`part`i''-1']
if `part`i''==1 {
local parambeta`firstpart`i''=`cosig'[1,`firstpart`i'']
}
}
}
/*******************************************************************************
DISPLAYING OF THE RESULTS
********************************************************************************/
local AIC=-2*`ll'+2*(`nbitems'+`nbpart'*(`nbpart'+1)/2)
if `nbpart'>1 {
forvalues i=1/`nbpart' {
local var`i'=`M'[`i',`i']
forvalues j=`=`i'+1'/`nbpart' {
local cov`i'`j'=`M'[`i',`j']
}
}
di
di in green _col(4) "Log-likelihood:" in yellow %-12.4f `ll'
di
noi di in green _col(4) "Items" _col(16) "Parameters" _col(29) "std Err."
di in green _col(4) "{hline 33}"
forvalues p=1/`nbpart' {
forvalues i=1/`part`p'' {
local name:word `i' of `set`p''
if `part`p''!=1 {
noi di in yellow _col(4) "`name'" _col(18) %8.5f `beta`p''[1,`i'] _col(30) %6.5f sqrt(`Varbeta`p''[`i',`i'])
}
else {
noi di in yellow _col(4) "`name'" _col(18) %8.5f `parambeta`firstpart`p''' _col(30) "."
}
}
}
di in green _col(4) "{hline 33}"
forvalues i=1/`nbpart' {
noi di in yellow _col(4) "Var`i'" _col(18) %8.5f `var`i''
}
forvalues i=1/`nbpart' {
forvalues j=`=`i'+1'/`nbpart' {
di in green _col(4) in yellow "cov`i'`j'" _col(18) %8.5f `cov`i'`j''
}
}
di in green _col(4) "{hline 33}"
}
if "`trace'"==""&"`details'"=="" {
di in green "{p}Add the -trace- option to obtain the standard errors of the elements of the covariance matrix of the latent traits.{p_end}"
}
/*******************************************************************************
OUTPUTS
********************************************************************************/
ereturn clear
ereturn scalar AIC=`AIC'
ereturn scalar ll=`ll'
ereturn scalar dimension=`nbpart'
forvalues i=1/`nbpart' {
ereturn scalar nbitems`i'=`part`i''
ereturn local set`i' `set`i''
if `part`i''>1 {
matrix colnames `beta`i''=`set`i''
matrix rownames `beta`i''=beta
ereturn matrix beta`i'=`beta`i''
matrix colnames `Varbeta`i''=`set`i''
matrix rownames `Varbeta`i''=`set`i''
ereturn matrix Varbeta`i' `Varbeta`i''
}
else {
ereturn scalar beta`i'=`parambeta`firstpart`i'''
}
}
tempname matrixsigma
matrix `matrixsigma'=`M'
local list
forvalues i=1/`nbpart' {
local list `list' latenttrait`i'
}
matrix colnames `matrixsigma'=`list'
matrix rownames `matrixsigma'=`list'
ereturn matrix covar=`matrixsigma'
drop _all
qui use `mmsrmfile'
end

View File

@ -0,0 +1,72 @@
{smcl}
{* 5may2013}{...}
{hline}
help for {hi:mmsrm}
{hline}
{title:Estimation of the parameters of a Multidimensional Marginally Sufficient Rasch Model (MMSRM)}
{p 8 14 2}{cmd:mmsrm} {it:varlist} {cmd:id}({it:varname}) [{cmd:,} {cmdab:part:ition}({it:numlist}) {cmdab:nodet:ails} {cmdab:trac:e} {cmdab:it:erate}({it:#}) {cmdab:ad:apt} {cmdab:meth:od}({it:mml/gee})]
{p 8 14 2}{it:varlist} is a list of two existing binary variables or more.
{title:Description}
{p 4 8 2}{cmd:mmsrm} estimates by marginal maximum likelihood (MML) or
generalized estimating equations (GEE) the parameters of the Multidimensional
Marginally Sufficient Rasch Model (MMSRM) defined by Hardouin and Mesbah (2004).
This model is an Item Response Model (IRM) with one or several latent traits.
This is a particular multidimensionnal extension of the Rasch model. In this
model, the items are separated in Q groups and each group of items is linked to
one and only one latent trait. Each group fits a Rasch model relatively to the
corresponding latent trait, so the score computed in each group of item is a
sufficient statistics of this latent trait (to a specific value of this score
is associated only one value for the latent trait). The program allows
computing the parameter of a MMSRM with less than 4 latent traits.
To improve the time of computing, the difficulty parameters are estimated in
each unidimensional Rasch model and used as an offset variable to estimate the
parameters of the distribution of the multidimensional latent trait. This model
allows estimating the correlations between different latent traits measured by
Rasch models.
{title:Options}
{p 4 8 2}{cmd:id} defines an identifiant variable of the individuals.
{p 4 8 2}{cmd:partition} allows defining the number of items relied to each
latent trait. The sum of the numbers indicated in the {it:numlist} must be
equal to the total number of items. The number of elements indicates the number of
latent traits. The items are taken in the same order than this one of {it:varlist}.
By default, only one latent trait is assumed (Rasch model). The number of elements of
{cmd:partition} must be inferior or equal to 3.
{p 4 8 2}{cmd:method} defines the estimation method between the marginal maximum
likelihood ({it:mml} - by default) and the generalized estimating equations ({it:gee}).
You cannot estimate the parameters of a MMSRM with 3 dimensions with the GEE method.
{p 4 8 2}{cmd:nodetails} deletes the details about the procedure.
{p 4 8 2}{cmd:trace} displays details about the estimation algorithm.
{p 4 8 2}{cmd:iterate} defines the maximal number of iterations of the estimation algorithm
(30 by default).
{p 4 8 2}{cmd:adapt} allows using the adaptive quadrature if you use the MML method of estimation. This option
is useless if you use GEE.
{title:Example}
{p 16 22 2} {inp:. mmsrm item1-item9 , part(4 5) trace method(gee)}
{p 16 22 2} {inp:. mmsrm item1 item2 item3 item4 /*Rasch model*/}
{p 16 22 2} {inp:. mmsrm c1-c9 , part(3 3 3) nodetails adapt iterate(10)}
{title:References}
{p 4 8 2}Hardouin J.-B. and Mesbah M. Clustering binary variables in subscales using an extended Rasch model and Akaike Information Criterion. {it:Communications in Statistics - Theory and Methods}, {cmd:33}(6), pp. 1277-1294, (2004).
{title:Author}
{p 4 8 2}Jean-Benoit Hardouin, Regional Health Observatory (ORS) - 1, rue Porte Madeleine - BP 2439 - 45032 Orleans Cedex 1 - France.
You can contact the author at {browse "mailto:jean-benoit.hardouin@neuf.fr":jean-benoit.hardouin@neuf.fr} and visit the websites {browse "http://anaqol.free.fr":AnaQol} and {browse "http://freeirt.free.fr":FreeIRT}

View File

@ -0,0 +1,241 @@
************************************************************************************************************
* Stata program : mmsrm
* Estimate the parameters of the Multidimensional Marginally Sufficient Rasch Model (MMSRM)
* Release 2 : May 26, 2004
*
* Historic :
* Version 1 (May 14, 2004) [Jean-Benoit Hardouin]
*
* Jean-benoit Hardouin, Regional Health Observatory of Orl<72>ans - France
* jean-benoit.hardouin@neuf.fr
*
* Use the Stata programs raschtest and gammasym who can be download on http://anaqol.free.fr
* Use the Stata program gllamm who can be obtained by : ssc install gllamm
* News about this program :http://anaqol.free.fr
*
* All the necessary programs on the FreeIRT Project website : http://freeirt.free.fr
*
* Copyright 2004 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
************************************************************************************************************
program define mmsrm,eclass
version 8.0
syntax varlist(min=3 numeric) [, PARTition(numlist) NODETails TRAce]
preserve
local nbitems : word count `varlist'
if "`part'"=="" {
local part=`nbitems'
}
local nbpart:word count `partition'
if `nbpart'== 1 {
raschtest `varlist', notest mml
}
else if `nbpart'>2 {
di in red "The mmsrm module do not run models with more than two dimensions for the moment."
}
if `nbpart'!=2 {
exit
}
local comptitems=0
tokenize `varlist'
forvalues i=1/`nbpart' {
local firstpart`i'=`comptitems'+1
local part`i': word `i' of `partition'
local set`i'
local comptitems=`comptitems'+`part`i''
forvalues j=`firstpart`i''/`comptitems' {
local set`i' "`set`i'' ``j''"
}
}
if `comptitems'<`nbitems' {
di in error "Your partition describe less items than the number of items defined in the varlist."
di in error "Correct your code."
exit
}
if `comptitems'>`nbitems' {
di in error "Your partition describe more items than the number of items defined in the varlist."
di in error "Correct your code."
exit
}
forvalues i=1/`nbpart' {
if "`details'"=="" {
di in green "Estimation of the difficulty parameters of the dimension `i'."
}
*set trace on
if `part`i''>1 {
qui raschtest `set`i'',mml notest
tempname beta`i' Varbeta`i'
matrix `beta`i''=e(beta)
matrix `Varbeta`i''=e(Varbeta)
local sigma`i'=e(sigma)
forvalues j=1/`part`i'' {
local parambeta`=`firstpart`i''+`j'-1'=`beta`i''[1,`j']
}
}
else {
qui count
local N=r(N)
qui count if ``firstpart`i'''==1
local pos=r(N)
local parambeta`firstpart`i''=-log(`pos'/(`N'-`pos'))
local sigma`i'=0
}
}
if "`details'"=="" {
di
di in green "Estimation of the parameters of the distribution of the multidimensional latent trait."
di in green "This process could be long to run. Be patient !"
}
*set trace on
tempfile savemmsrm
qui save `savemmsrm'
keep `varlist'
tempname rep id item offset
forvalues i=1/`nbitems' {
rename ``i'' `rep'`i'
}
gen `id'=_n
qui reshape long `rep', i(`id') j(`item')
gen `offset'=0
label variable `offset' "offset"
forvalues i=1/`nbitems' {
qui replace `offset'=-`parambeta`i'' if `item'==`i'
}
local eqs
forvalues i=1/`nbpart' {
tempname B`i'
gen `B`i''=0
eq sc`i':`B`i''
local eqs `eqs' sc`i'
forvalues j=`firstpart`i''/`=`firstpart`i''+`part`i''-1' {
qui replace `B`i''=1 if `item'==`j'
}
}
label variable `rep' "response"
label variable `id' "identifiant"
tempname first
local four=substr("`id'",1,3)
matrix define `first'=(0,`sigma1',`sigma2',0)
matrix colnames `first'=`rep':_cons `four'1_1:`B1' `four'1_2:`B2' `four'1_2_1:_cons
if "`trace'"!="" {
local quigllamm
}
else {
local quigllamm qui
}
`quigllamm' gllamm `rep', from(`first') link(logit) fam(bin) i(`id') offset(`offset') nrf(`nbpart') eqs(`eqs') nip(5) dots `trace'
local AIC=-2*e(ll)+2*(`nbitems'+`nbpart'*(`nbpart'+1)/2)
local ll=e(ll)
tempname cosig varsig L M
matrix `cosig'=e(b)
matrix `varsig'=e(V)
matrix `L'=e(chol)
matrix `M'=`L'*`L''
forvalues i=1/`nbpart'{
}
if `nbpart'==2 {
local var1=`M'[1,1]
local var2=`M'[2,2]
local sevar1=(sqrt(`varsig'[2,2])*2*sqrt(`var1'))
local sevar2=.
local cov12=`M'[1,2]
local secov=.
di
di in green _col(4) "Log-likelihood:" in yellow %-12.4f `ll'
di
noi di in green _col(4) "Items" _col(16) "Parameters" _col(29) "std Err."
di in green _col(4) "{hline 33}"
forvalues i=1/`part1' {
if `part1'!=1 {
noi di in yellow _col(4) "``i''" _col(18) %8.5f `beta1'[1,`i'] _col(30) %6.5f sqrt(`Varbeta1'[`i',`i'])
}
else {
noi di in yellow _col(4) "``i''" _col(18) %8.5f `parambeta`firstpart1'' _col(30) "."
}
}
di in green _col(4) "{hline 33}"
forvalues i=`firstpart2'/`=`part1'+`part2'' {
if `part2'!=1 {
noi di in yellow _col(4) "``i''" _col(18) %8.5f `beta2'[1,`=`i'-`part1''] _col(30) %6.5f sqrt(`Varbeta2'[`=`i'-`part1'',`=`i'-`part1''])
}
else {
noi di in yellow _col(4) "``i''" _col(18) %8.5f `parambeta`firstpart2'' _col(30) "."
}
}
di in green _col(4) "{hline 33}"
forvalues i=1/`nbpart' {
noi di in yellow _col(4) "Var`i'" _col(18) %8.5f `var`i'' /*_col(30) %6.5f `sevar`i''*/
}
di in green _col(4) in yellow "cov12" _col(18) %8.5f `cov12' /*_col(30) %6.5f `secov'*/
di in green _col(4) "{hline 33}"
}
if "`trace'"=="" {
di in green "Add the trace option to obtain the standard errors of the elements"
di in green "of the covariance matrix of the latent traits"
}
ereturn clear
ereturn scalar AIC=`AIC'
ereturn scalar ll=`ll'
ereturn scalar dimension=`nbpart'
forvalues i=1/`nbpart' {
ereturn scalar nbitems`i'=`part`i''
ereturn local set`i' `set`i''
if `part`i''>1 {
ereturn matrix beta`i'=`beta`i''
ereturn matrix Varbeta`i' `Varbeta`i''
}
else {
ereturn scalar beta`i'=`parambeta`firstpart`i'''
}
}
*ereturn matrix cosig=`cosig'
*ereturn matrix varsig=`varsig'
tempname matrixsigma
matrix `matrixsigma'=(`sigma1',`sigma2',`cov12')
matrix colnames `matrixsigma'= sigma1 sigma2 cov12
ereturn matrix sigma=`matrixsigma'
drop _all
qui use `savemmsrm'
end

View File

@ -0,0 +1,454 @@
*! Version 8.1.1 26 September 2013
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : msp
* Mokken Scale Procedure
* Release 8.1.1: (September 26, 2013) [Jean-Benoit Hardouin] /*correction of a rare bug */
*
* Historic :
* Version 1 - lose version (August 20, 2002) [Jean-Benoit Hardouin]
* Version 2 (September 25, 2002) [Jean-Benoit Hardouin]
* Version 3 (December 1, 2003) [Jean-Benoit Hardouin]
* Version 4 (January 20, 2004) [Jean-Benoit Hardouin]
* Version 5 (March 22, 2004) [Jean-Benoit Hardouin]
* Version 5.1 (May 1st, 2004) [Jean-Benoit Hardouin]
* Version 6 : (July 5, 2004) [Jean-Benoit Hardouin]
* Version 6.1 : (September 5, 2004) [Jean-Benoit Hardouin]
* Version 6.2 : (January 22, 2006) [Jean-Benoit Hardouin] /*English improvements*/
* Release 6.3 : (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */
* Release 6.6: (Februar 16, 2007) [Jean-Benoit Hardouin] /*Tests of the loevinger H indices, adaptation for loevH 6.6, noadjust option, improvements*/
* Release 8: (December 8, 2010) [Jean-Benoit Hardouin] /*Adaptation for loevh version 8*/
* Release 8.1: (December 19, 2012) [Jean-Benoit Hardouin] /*correction of a bug with the notest option*/
* Release 8.1.1: (September 26, 2013) [Jean-Benoit Hardouin] /*correction of a rare bug */
*
* Jean-benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences
* Department of Biostatistics - France
* jean-benoit.hardouin@anaqol.org
*
* The Stata program loevh is needed. It can be downloaded on http://www.anaqol.org
* News about this program :http://www.anaqol.org
* FreeIRT Project website : http://www.freeirt.org
*
* Copyright 2002-2007, 2010, 2012 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
************************************************************************************************************
program define msp , rclass
version 7.0
syntax varlist(min=2 numeric) [,c(real 0.3) noDETails KERnel(integer 0) noTEst p(real 0.05) PAIRWise MINValue(real 0) noBon noADJust]
local nbitems : word count `varlist'
tokenize `varlist'
tempfile mspfile
qui save "`mspfile'"
if "`pairwise'"=="" {
forvalues j=1/`nbitems' {
qui drop if ``j''==.
}
}
if "`test'"!="" {
local p=1
local minvalue=-99
local bon nobon
}
qui loevh `varlist',`pairwise' pair `adjust'
tempname pvalHjk loevHjk loevHjks loevHj loevH Hjk stopscale stop dim plusitems Hjkmax Hjmax Hmax nbitemsel
matrix `loevHjk'=r(loevHjk)
matrix `loevHjks'=r(loevHjk)
matrix `pvalHjk'=r(pvalHjk)
matrix `loevHj'=r(loevHj)
scalar `loevH'=r(loevH)
matrix `Hjk'=`loevHjk'
matrix define `dim'=J(1,`nbitems',0)
global scale=0
scalar `stopscale'=0
while `stopscale'!=1 { /*WHILE IT IS POSSIBLE TO CONSTRUCT SCALES*/
global scale=$scale+1
local dimension=$scale
local scaletmp="scale$scale"
local scaletmpnum="scalenum$scale"
global `scaletmp'
global `scaletmpnum'
if "`details'"=="" {
di
di in yellow "Scale: $scale"
di "{hline 10}"
}
/**********************************************************************************************************
BEGINING OF THE INITIAL STEP
**********************************************************************************************************/
/****NONE KERNEL OR NOT THE FIRST SCALE****/
if $scale>1|`kernel'==0 {
scalar `plusitems'=0
scalar `Hjkmax'=-99
local nbitemsbon=0
forvalues j1=1/`nbitems' {
if `dim'[1,`j1']==0 {
local nbitemsbon=`nbitemsbon'+1
}
}
if `nbitemsbon'<=1 {
local nbitemsbon=2
}
local kbon=`nbitemsbon'*(`nbitemsbon'-1)/2
if "`bon'"==""&"`test'"=="" {
local pbon=`p'/`kbon'
}
else {
local pbon=`p'
}
if "`test'"!="" {
local pbon=1
local p=1
}
if "`details'"==""&"`test'"=="" {
di in green "Significance level: " in yellow %8.6f `pbon'
}
forvalues j1=1/`nbitems' { /*WE SEARCH THE BEST PAIR OF ITEMS*/
if `dim'[1,`j1']==0 {
scalar `plusitems'=1
forvalues j2=`=`j1'+1'/`nbitems' {
if `dim'[1,`j2']==0 {
if `Hjk'[`j1',`j2']>`Hjkmax'&`pvalHjk'[`j1',`j2']<=`pbon' {
scalar `Hjkmax'=`Hjk'[`j1',`j2']
global j1max=`j1'
global j2max=`j2'
}
}
}
}
}
if `Hjkmax'==-99 { /*IF NONE PAIR OF ITEM VERIFY Hjk>0*/
if `plusitems'==0 {
if "`details'"=="" {
di in green "{p}There is no more items remaining.{p_end}"
}
}
else {
if "`details'"=="" {
di as green "{p}None pair of items has a significantly positive Hjk coefficient.{p_end}"
}
}
continue, break
}
if `Hjkmax'<=`c' { /*IF NONE PAIR OF ITEM VERIFY Hjk>c*/
if $scale==1 {
if "`details'"=="" {
di as green "{p}None pair of items verifies Hjk>`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed.{p_end}"
}
}
else {
if "`details'"=="" {
di as green "{p}None new scale can be constructed because none pair of items, among the remaining items, verifies Hjk>`c'{p_end}"
}
}
scalar `stop'=1
scalar `stopscale'=1
continue, break
}
else { /*IF THERE IS AT LEAST ONE PAIR OF ITEM WHO VERIFY Hjk>c*/
matrix `dim'[1,$j1max]=$scale
matrix `dim'[1,$j2max]=$scale
local scaletmp="scale$scale"
local scaletmpnum="scalenum$scale"
global `scaletmp' "`$j1max' `$j2max'"
global `scaletmpnum' "$j1max $j2max"
if "`details'"=="" {
di in green "{p}The two first items selected in the scale " in yellow "$scale " in green "are " in yellow "`$j1max' " in green "and " in yellow "`$j2max'" in green " (Hjk=" in yellow %6.4f `Hjkmax' in green "){p_end}"
}
scalar `nbitemsel'=2
}
forvalues i=1/`nbitems' { /*WE EXCLUDE THE ITEMS WHICH VERIFY Hjk<0 WITH THE TWO SELECTED ITEMS*/
if ((`loevHjks'[`i',$j1max]<`minvalue'|`pvalHjk'[`i',$j1max]>`p')&`dim'[1,`i']==0) {
matrix `dim'[1,`i']=-1
}
if ((`loevHjks'[`i',$j2max]<`minvalue'|`pvalHjk'[`i',$j2max]>`p')&`dim'[1,`i']==0) {
matrix `dim'[1,`i']=-1
}
}
}
/****FIRST SCALE, KERNEL OF ONE ITEM****/
if $scale==1&`kernel'==1 {
global j1max=1
scalar `plusitems'=0
scalar `Hjkmax'=-99
if "`details'"=="" {
di in green "The item " in yellow "`1'" in green " is the kernel of the first scale"
}
local nbitemsbon=0
forvalues i=2/`nbitems' { /*WE EXCLUDE THE ITEM WHICH VERIFY Hjk<0 WITH THE ITEM OF THE KERNEL*/
if (`loevHjks'[`i',$j1max]<`minvalue'|`pvalHjk'[`i',$j1max]>`p')&`dim'[1,`i']==0) {
matrix `dim'[1,`i']=-1
}
if `dim'[1,`i']==0 {
local nbitemsbon=`nbitemsbon'+1
}
}
local kbon=`nbitemsbon'
if "`bon'"==""&"`test'"=="" {
local pbon=`p'/`kbon'
}
else {
local pbon=`p'
}
if "`details'"==""&"`test'"=="" {
di in green "Significance level: " in yellow %8.6f `pbon'
}
forvalues j2=2/`nbitems' {/*WE SEARCH THE BEST ITEM TO SELECT WITH THE KERNEL*/
if `Hjk'[`j2',1]>`Hjkmax'&`pvalHjk'[`j2',1]<`pbon' {
scalar `Hjkmax'=`Hjk'[`j2',1]
global j2max=`j2'
}
}
if `Hjkmax'==-99 {/*IF NONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk<*/
if "`details'"=="" {
di as green "{p}None item associated to the item " in yellow "$j1 " in green "allows obtaining a significantly positive value for the Hjk coefficient.{p_end}"
}
continue, break
}
if `Hjkmax'<=`c' { /*IF NONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk<c*/
if "`details'"=="" {
di as green "{p}None index Hjk associated to the item " in yellow "$j1 " in green "verifies Hjk>`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed.{p_end}"
}
scalar `stop'=1
scalar `stopscale'=1
continue, break
}
else { /* IF AT LEAST ONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk>c*/
matrix `dim'[1,$j1max]=$scale
matrix `dim'[1,$j2max]=$scale
local scaletmp="scale$scale"
local scaletmpnum="scalenum$scale"
global `scaletmp' "`$j2max' `$j1max'"
global `scaletmpnum' "$j2max $j1max"
if "`details'"=="" {
di in green "The second item selected in the first scale is " in yellow "`$j2max' " in green "(Hjk=" in yellow %6.4f `Hjkmax' in green")"
}
scalar `nbitemsel'=2
}
forvalues i=1/`nbitems' { /*WE EXCLUDE THE ITEM WHICH VERIFY Hjk<0 WITH THE NEW SELECTED ITEM*/
if (`loevHjks'[`i',$j2max]<`minvalue'|`pvalHjk'[`i',$j2max]>`p')&`dim'[1,`i']==0 {
matrix `dim'[1,`i']=-1
}
}
}
/****FIRST SCALE, KERNEL OF SEVERAL ITEMS****/
if $scale==1&`kernel'>=2 {
global scale1
local scalenum1
local kbon=1
local pbon=`p'
if "`details'"==""&"`test'"=="" {
di in green "Significance level: " in yellow %8.6f `pbon'
}
forvalues j2=1/`kernel' {
global scale1 ``j2'' $scale1
global scalenum1 $scalenum1 `j2'
matrix `dim'[1,`j2']=1
}
if "`details'"=="" {
di in green "{p}The kernel of the first scale is composed of the items " in yellow "$scale1{p_end}"
}
scalar `nbitemsel'=`kernel'
forvalues j=1/`kernel' {
forvalues i=1/`nbitems' { /* WE EXCLUDE THE ITEMS WHICH VERIFY Hjk<0 WITH THE ITEMS OF THE KERNEL*/
if (`loevHjks'[`i',`j']<`minvalue'|`pvalHjk'[`i',`j']>`p')&`dim'[1,`i']==0 {
matrix `dim'[1,`i']=-1
}
}
}
}
local excluded
forvalues i=1/`nbitems' {
if `dim'[1,`i']==-1 {
local excluded `excluded' ``i''
matrix `dim'[1,`i']=-2
}
}
if "`excluded'"!=""&"`details'"=="" {
di in green "The following items are excluded at this step: " in yellow "`excluded'"
}
scalar `stop'=0
/**********************************************************************************************************
END OF THE INITIAL STEP
**********************************************************************************************************/
while `stop'!=1 { /*WHILE THE PROCEDURE TO CONSTRUCT THE ACTUAL SCALE IS NOT STOPPED*/
scalar `Hjmax'=-99
scalar `Hmax'=-99
global jmax=0
global stopmax=0
local nbitemsbon=0
forvalues i=1/`nbitems' {
if `dim'[1,`i']==0 {
local nbitemsbon=`nbitemsbon'+1
}
}
local kbon=`kbon'+`nbitemsbon'
if "`bon'"=="" {
local pbon=`p'/`kbon'
}
else {
local pbon=`p'
}
if "`details'"==""&"`test'"=="" {
di in green "Significance level: " in yellow %8.6f `pbon'
}
forvalues j0=1/`nbitems' {
if `dim'[1,`j0']==0 {/*IF THE ITEM J0 IS UNSELECTED*/
global stopmax=1
local scaletmp="scale$scale"
local scaletmpnum="scalenum$scale"
qui loevh ``j0'' $`scaletmp' ,`pairwise' pair `adjust'
tempname pvalHj0
matrix `pvalHj0'=r(pvalHj)
scalar `pvalHj0'=`pvalHj0'[1,1]
matrix `loevHjk'=r(loevHjk)
matrix `loevHj'=r(loevHj)
scalar `loevH'=r(loevH)
local nbitsc : word count $`scaletmp'
local nbitsc=`nbitsc'+1
if `loevHj'[1,1]>`c'&`pvalHj0'<`pbon' {/*IF THE ITEM J0 CAN BE SELECTED*/
if `loevH'>`Hmax' {/*AND IF IT IS THE BEST ITEM (COMPARED TO THE PRECEEDING ITEMS)*/
scalar `Hjmax'=`loevHj'[1,1]
scalar `Hmax'=`loevH'
global j="``j0''"
global j0=`j0'
}
}
}
}
if $stopmax==1&`Hjmax'==-99 { /*IF THERE IS ITEMS REMAINING BUT NONE OF THEM CAN BE SELECTED*/
if "`details'"=="" {
di in green "{p}None new item can be selected in the scale $scale because all the Hj are lesser than `c' or none new item has all the related Hjk coefficients significantly greater than 0{p_end}."
}
scalar `stop'=1
continue,break
}
if $stopmax==0 { /*IF THERE IS NO MORE ITEM REMAINING*/
if "`details'"=="" {
di in green "{p}There is no more items remaining.{p_end}"
}
scalar `stopscale'=1
scalar `stop'=1
forvalues i=1/`nbitems' {
if `dim'[1,`i']<0 {
scalar `stopscale'=0
}
}
*global scale=$scale-1
continue,break
}
if `stop'!=1 { /*IF THE PROCEDURE IS NOT STOPPED*/
matrix `dim'[1,$j0]=$scale
local `scaletmp'="scale$scale"
local `scaletmpnum'="scalenum$scale"
global `scaletmp' $j $`scaletmp'
global `scaletmpnum' $j0 $`scaletmpnum'
if "`details'"=="" {
di in green "The item " in yellow "`$j0' " in green "is selected in the scale " in yellow "$scale" _col(50) in green "Hj=" in yellow %6.4f `Hjmax' _col(65) in green "H=" in yellow %6.4f `Hmax' ""
}
local excluded
forvalues i=1/`nbitems' {
if `dim'[1,`i']==-1 {
matrix `dim'[1,`i']=-2
}
if `dim'[1,`i']==0 { /*WE EXCLUDE ITEMS WHO HAVE A NEGATIVE Hjk WITH THE NEW SELECTED ITEM*/
if `loevHjks'[`i',$j0]<`minvalue'|`pvalHjk'[`i',$j0]>`p' {
matrix `dim'[1,`i']=-1
local excluded `excluded' ``i''
}
}
}
if "`excluded'"!=""&"`details'"=="" {
di in green "The following items are excluded at this step: " in yellow "`excluded'"
}
}
}
di
local scaleencours="scale$scale"
local scalenumencours="scalenum$scale"
local nbitemscale : word count $`scaleencours'
return scalar nbitems`dimension'=`nbitemscale'
if `nbitemscale'>0 { /* IF AT LEAST TWO ITEMS HAVE BEEN SELECTED*/
if "`details'"!="" {
di
di in yellow "Scale: $scale"
di "{hline 10}"
}
loevh $`scaleencours',`pairwise' `adjust'
matrix `loevHjk'=r(loevHjk)
matrix `loevHj'=r(loevHj)
scalar `loevH'=r(loevH)
return scalar H`dimension'=`loevH'
return local scale`dimension' $`scaleencours'
return local scalenum`dimension' $`scalenumencours'
local j=`nbitemscale'
di
}
forvalues i=1/`nbitems' {
if `dim'[1,`i']<0 {
matrix `dim'[1,`i']=0
}
}
local restnbitems=0
forvalues j0=1/`nbitems' {
if `dim'[1,`j0']==0 {
local restnbitems=`restnbitems'+1
local restitem ``j0''
}
}
if `restnbitems'==1 { /*IF THERE IS ONLY ONE ITEM REMAINING*/
di
di in green "{p}There is only one item remaining (" in yellow "`restitem'" in green ").{p_end}"
local stopscale=1
return local lastitem "`restitem'"
}
}
return scalar dim=$scale
matrix colnames `dim'=`varlist'
return matrix selection=`dim'
qui use "`mspfile'",clear
end

View File

@ -0,0 +1,94 @@
{smcl}
{* 8december2010}{...}
{hline}
help for {hi:msp}
{hline}
{title:Mokken Scale Procedure}
{p 8 14 2}{cmd:msp} {it:varlist} [{cmd:,} {cmdab:nodet:ails}
{cmdab:ker:nel}({it:#}) {cmdab:c}({it:#}) {cmdab:note:st} {cmdab:p}({it:#})
{cmdab:pairw:ise} {cmdab:minv:alue}({it:#}) {cmdab:nob:on} {cmdab:noadj:ust}]
{p 8 14 2}{it:varlist} is a list of two existing dichotomous or polytomous variables or more.
{title:Description}
{p 4 8 2}{cmd:msp} selects scales of dichotomous or polytomous items with the Mokken Scale Procedure (MSP) defined by Mokken (1971) and by Hemker and al. (1995).
{title:Options}
{p 4 8 2}{cmd:nodetails} does not display informations during the algorithm of selection.
{p 4 8 2}{cmd:kernel} defines a kernel for the first scale, defined as the first # items of {it:varlist}.
{p 4 8 2}{cmd:c} defines the level of the threshold {it:c}. The level of {it:c} is fixed, by default, at 0.3.
{p 4 8 2}{cmd:notest} selects the scales whithout tests among the Loevinger H coefficient (Hjk>0): the new item with the maximal value for Hj>c is always selected.
{p 4 8 2}{cmd:p} defines the significance level for the tests. The level of {it:p} is fixed, by default, at 0.05.
{p 4 8 2}{cmd:pairwise} does no more delete all the individuals who have one or more missing values among all the items of {it:varlist} but, only these ones who have, for each pair of items, one or more missing values to these two items.
{p 4 8 2}{cmd:minvalue} defines the minimum value of the coefficient Hjk for a pair of item composing a scale. This minimal value is fixed by default to 0.
{p 4 8 2}{cmd:nobon} does no more correct the significance level of the test by the Bonferroni correction.
{p 4 8 2}{cmd:noadjust} approximates the tests statistics like the MSP program (Molenaar et al. (2000)).
{title:Remarks}
{p 4 8 2}For detailed informations on the Mokken scale procedure, see Mokken (1971), Hemker and al. (1995) or the manual of the MSP software (2000).
{p 4 8 2}{cmd:msp} runs with dichotomous or polytomous items.
{p 4 8 2}{cmd:msp} necessitates the program {help loevh} to compute.
{title:Results}
{p 4 8 2}{it:r(dim)} saves the number of built scales.
{p 4 8 2}{it:r(selection)} saves a vector which contains, for each item, the scale where it is selected (0 if the item is unselected).
{p 4 8 2}{it:r(H#)} saves the Loevinger's H coefficient of the #th scale.
{p 4 8 2}{it:r(nbitems#)} saves the number of items selected in the #th scale.
{p 4 8 2}{it:r(scale#)} saves the names of the items selected in the #th scale.
{p 4 8 2}{it:r(scalenum#)} saves the numbers of the items selected in the #th scale.
{title:Example}
{inp:. msp itemA1-itemA7}
{inp:. msp itemA* itemB* , nodetails kernel(2)}
{inp:. msp item* , c(0.2) nob pairwise}
{title:References}
{p 4 8 2}Hemker B. T., Sijtsma K. and Molenaar I. W., Selection of unidimensional scales from a multidimensional item bank in the polytomous Mokken IRT
model, {it: Applied Psychological Measurement}, vol.19(4), 1995, pp. 337-352.
{p 4 8 2}Mokken R. J., A theory and procedure of scale analysis. New-York/Berlin : De Guyter, 1971.
{p 4 8 2}Molenaar I. W., Sijtsma K. and Boer P. User's manual of MSP5 for Windows. Groningen (The Netherlands): iec ProGAMMA, 2000.
{title:Also see}
{p 4 13 2} help for {help loevh} (if installed), help for {help mokken} (if installed)
{title:Author}
{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
{p 4 8 2}EA 4275 "Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences"{p_end}
{p 4 8 2}University of Nantes - Faculty of Pharmaceutical Sciences{p_end}
{p 4 8 2}1, rue Gaston Veil - BP 53508{p_end}
{p 4 8 2}44035 Nantes Cedex 1 - FRANCE{p_end}
{p 4 8 2}Email:
{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end}
{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol}
and {browse "http://www.freeirt.org":FreeIRT}

View File

@ -0,0 +1,447 @@
*! Version 6.6 16 Februar 2007
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : msp
* Mokken Scale Procedure
* Release 6.6: Februar 16, 2007 /*Tests of the loevinger H indices, adaptation for loevH 6.6, noadjust option, improvements*/
*
* Historic :
* Version 1 - lose version (August 20, 2002) [Jean-Benoit Hardouin]
* Version 2 (September 25, 2002) [Jean-Benoit Hardouin]
* Version 3 (December 1, 2003) [Jean-Benoit Hardouin]
* Version 4 (January 20, 2004) [Jean-Benoit Hardouin]
* Version 5 (March 22, 2004) [Jean-Benoit Hardouin]
* Version 5.1 (May 1st, 2004) [Jean-Benoit Hardouin]
* Version 6 : (July 5, 2004) [Jean-Benoit Hardouin]
* Version 6.1 : (September 5, 2004) [Jean-Benoit Hardouin]
* Version 6.2 : (January 22, 2006) [Jean-Benoit Hardouin] /*English improvements*/
* Release 6.3 : (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */
*
* Jean-benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences
* Department of Biostatistics - France
* jean-benoit.hardouin@anaqol.org
*
* The Stata program loevH is needed. It can be downloaded on http://www.anaqol.org
* News about this program :http://www.anaqol.org
* FreeIRT Project website : http://www.freeirt.org
*
* Copyright 2002-2007 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
************************************************************************************************************
program define msp , rclass
version 7.0
syntax varlist(min=2 numeric) [,c(real 0.3) noDETails KERnel(integer 0) noTEst p(real 0.05) PAIRWise MINValue(real 0) noBon noADJust]
local nbitems : word count `varlist'
tokenize `varlist'
tempfile mspfile
qui save "`mspfile'"
if "`pairwise'"=="" {
forvalues j=1/`nbitems' {
qui drop if ``j''==.
}
}
if "`test'"!="" {
local p=1
local minvalue=-99
local bon nobon
}
qui loevH `varlist',`pairwise' pair `adjust'
tempname pvalHjk loevHjk loevHjks loevHj loevH Hjk stopscale stop dim plusitems Hjkmax Hjmax Hmax nbitemsel
matrix `loevHjk'=r(loevHjk)
matrix `loevHjks'=r(loevHjk)
matrix `pvalHjk'=r(pvalHjk)
matrix `loevHj'=r(loevHj)
scalar `loevH'=r(loevH)
matrix `Hjk'=`loevHjk'
matrix define `dim'=J(1,`nbitems',0)
global scale=0
scalar `stopscale'=0
while `stopscale'!=1 { /*WHILE IT IS POSSIBLE TO CONSTRUCT SCALES*/
global scale=$scale+1
local dimension=$scale
local scaletmp="scale$scale"
local scaletmpnum="scalenum$scale"
global `scaletmp'
global `scaletmpnum'
if "`details'"=="" {
di
di in yellow "Scale: $scale"
di "{hline 10}"
}
/**********************************************************************************************************
BEGINING OF THE INITIAL STEP
**********************************************************************************************************/
/****NONE KERNEL OR NOT THE FIRST SCALE****/
if $scale>1|`kernel'==0 {
scalar `plusitems'=0
scalar `Hjkmax'=-99
local nbitemsbon=0
forvalues j1=1/`nbitems' {
if `dim'[1,`j1']==0 {
local nbitemsbon=`nbitemsbon'+1
}
}
if `nbitemsbon'<=1 {
local nbitemsbon=2
}
local kbon=`nbitemsbon'*(`nbitemsbon'-1)/2
if "`bon'"=="" {
local pbon=`p'/`kbon'
}
else {
local pbon=`p'
}
if "`details'"==""&"`test'"=="" {
di in green "Significance level: " in yellow %8.6f `pbon'
}
forvalues j1=1/`nbitems' { /*WE SEARCH THE BEST PAIR OF ITEMS*/
if `dim'[1,`j1']==0 {
scalar `plusitems'=1
forvalues j2=`=`j1'+1'/`nbitems' {
if `dim'[1,`j2']==0 {
if `Hjk'[`j1',`j2']>`Hjkmax'&`pvalHjk'[`j1',`j2']<=`pbon' {
scalar `Hjkmax'=`Hjk'[`j1',`j2']
global j1max=`j1'
global j2max=`j2'
}
}
}
}
}
if `Hjkmax'==-99 { /*IF NONE PAIR OF ITEM VERIFY Hjk>0*/
if `plusitems'==0 {
if "`details'"=="" {
di in green "{p}There is no more items remaining.{p_end}"
}
}
else {
if "`details'"=="" {
di as green "{p}None pair of items has a significantly positive Hjk coefficient.{p_end}"
}
}
continue, break
}
if `Hjkmax'<=`c' { /*IF NONE PAIR OF ITEM VERIFY Hjk>c*/
if $scale==1 {
if "`details'"=="" {
di as green "{p}None pair of items verifies Hjk>`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed.{p_end}"
}
}
else {
if "`details'"=="" {
di as green "{p}None new scale can be constructed because none pair of items, among the remaining items, verifies Hjk>`c'{p_end}"
}
}
scalar `stop'=1
scalar `stopscale'=1
continue, break
}
else { /*IF THERE IS AT LEAST ONE PAIR OF ITEM WHO VERIFY Hjk>c*/
matrix `dim'[1,$j1max]=$scale
matrix `dim'[1,$j2max]=$scale
local scaletmp="scale$scale"
local scaletmpnum="scalenum$scale"
global `scaletmp' "`$j1max' `$j2max'"
global `scaletmpnum' "$j1max $j2max"
if "`details'"=="" {
di in green "{p}The two first items selected in the scale " in yellow "$scale " in green "are " in yellow "`$j1max' " in green "and " in yellow "`$j2max'" in green " (Hjk=" in yellow %6.4f `Hjkmax' in green "){p_end}"
}
scalar `nbitemsel'=2
}
forvalues i=1/`nbitems' { /*WE EXCLUDE THE ITEMS WHICH VERIFY Hjk<0 WITH THE TWO SELECTED ITEMS*/
if (`loevHjks'[`i',$j1max]<`minvalue'|`pvalHjk'[`i',$j1max]>.05)&`dim'[1,`i']==0 {
matrix `dim'[1,`i']=-1
}
if (`loevHjks'[`i',$j2max]<`minvalue'|`pvalHjk'[`i',$j2max]>.05)&`dim'[1,`i']==0 {
matrix `dim'[1,`i']=-1
}
}
}
/****FIRST SCALE, KERNEL OF ONE ITEM****/
if $scale==1&`kernel'==1 {
global j1max=1
scalar `plusitems'=0
scalar `Hjkmax'=-99
if "`details'"=="" {
di in green "The item " in yellow "`1'" in green " is the kernel of the first scale"
}
local nbitemsbon=0
forvalues i=2/`nbitems' { /*WE EXCLUDE THE ITEM WHICH VERIFY Hjk<0 WITH THE ITEM OF THE KERNEL*/
if (`loevHjks'[`i',$j1max]<`minvalue'|`pvalHjk'[`i',$j1max]>.05)&`dim'[1,`i']==0 {
matrix `dim'[1,`i']=-1
}
if `dim'[1,`i']==0 {
local nbitemsbon=`nbitemsbon'+1
}
}
local kbon=`nbitemsbon'
if "`bon'"=="" {
local pbon=`p'/`kbon'
}
else {
local pbon=`p'
}
if "`details'"==""&"`test'"=="" {
di in green "Significance level: " in yellow %8.6f `pbon'
}
forvalues j2=2/`nbitems' {/*WE SEARCH THE BEST ITEM TO SELECT WITH THE KERNEL*/
if `Hjk'[`j2',1]>`Hjkmax'&`pvalHjk'[`j2',1]<`pbon' {
scalar `Hjkmax'=`Hjk'[`j2',1]
global j2max=`j2'
}
}
if `Hjkmax'==-99 {/*IF NONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk<*/
if "`details'"=="" {
di as green "{p}None item associated to the item " in yellow "$j1 " in green "allows obtaining a significantly positive value for the Hjk coefficient.{p_end}"
}
continue, break
}
if `Hjkmax'<=`c' { /*IF NONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk<c*/
if "`details'"=="" {
di as green "{p}None index Hjk associated to the item " in yellow "$j1 " in green "verifies Hjk>`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed.{p_end}"
}
scalar `stop'=1
scalar `stopscale'=1
continue, break
}
else { /* IF AT LEAST ONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk>c*/
matrix `dim'[1,$j1max]=$scale
matrix `dim'[1,$j2max]=$scale
local scaletmp="scale$scale"
local scaletmpnum="scalenum$scale"
global `scaletmp' "`$j2max' `$j1max'"
global `scaletmpnum' "$j2max $j1max"
if "`details'"=="" {
di in green "The second item selected in the first scale is " in yellow "`$j2max' " in green "(Hjk=" in yellow %6.4f `Hjkmax' in green")"
}
scalar `nbitemsel'=2
}
forvalues i=1/`nbitems' { /*WE EXCLUDE THE ITEM WHICH VERIFY Hjk<0 WITH THE NEW SELECTED ITEM*/
if (`loevHjks'[`i',$j2max]<`minvalue'|`pvalHjk'[`i',$j2max]>.05)&`dim'[1,`i']==0 {
matrix `dim'[1,`i']=-1
}
}
}
/****FIRST SCALE, KERNEL OF SEVERAL ITEMS****/
if $scale==1&`kernel'>=2 {
global scale1
local scalenum1
local kbon=1
local pbon=`p'
if "`details'"==""&"`test'"=="" {
di in green "Significance level: " in yellow %8.6f `pbon'
}
forvalues j2=1/`kernel' {
global scale1 ``j2'' $scale1
global scalenum1 $scalenum1 `j2'
matrix `dim'[1,`j2']=1
}
if "`details'"=="" {
di in green "{p}The kernel of the first scale is composed of the items " in yellow "$scale1{p_end}"
}
scalar `nbitemsel'=`kernel'
forvalues j=1/`kernel' {
forvalues i=1/`nbitems' { /* WE EXCLUDE THE ITEMS WHICH VERIFY Hjk<0 WITH THE ITEMS OF THE KERNEL*/
if (`loevHjks'[`i',`j']<`minvalue'|`pvalHjk'[`i',`j']>.05)&`dim'[1,`i']==0 {
matrix `dim'[1,`i']=-1
}
}
}
}
local excluded
forvalues i=1/`nbitems' {
if `dim'[1,`i']==-1 {
local excluded `excluded' ``i''
matrix `dim'[1,`i']=-2
}
}
if "`excluded'"!=""&"`details'"=="" {
di in green "The following items are excluded at this step: " in yellow "`excluded'"
}
scalar `stop'=0
/**********************************************************************************************************
END OF THE INITIAL STEP
**********************************************************************************************************/
while `stop'!=1 { /*WHILE THE PROCEDURE TO CONSTRUCT THE ACTUAL SCALE IS NOT STOPPED*/
scalar `Hjmax'=-99
scalar `Hmax'=-99
global jmax=0
global stopmax=0
local nbitemsbon=0
forvalues i=1/`nbitems' {
if `dim'[1,`i']==0 {
local nbitemsbon=`nbitemsbon'+1
}
}
local kbon=`kbon'+`nbitemsbon'
if "`bon'"=="" {
local pbon=`p'/`kbon'
}
else {
local pbon=`p'
}
if "`details'"==""&"`test'"=="" {
di in green "Significance level: " in yellow %8.6f `pbon'
}
forvalues j0=1/`nbitems' {
if `dim'[1,`j0']==0 {/*IF THE ITEM J0 IS UNSELECTED*/
global stopmax=1
local scaletmp="scale$scale"
local scaletmpnum="scalenum$scale"
qui loevH ``j0'' $`scaletmp' ,`pairwise' pair `adjust'
tempname pvalHj0
matrix `pvalHj0'=r(pvalHj)
scalar `pvalHj0'=`pvalHj0'[1,1]
matrix `loevHjk'=r(loevHjk)
matrix `loevHj'=r(loevHj)
scalar `loevH'=r(loevH)
local nbitsc : word count $`scaletmp'
local nbitsc=`nbitsc'+1
if `loevHj'[1,1]>`c'&`pvalHj0'<`pbon' {/*IF THE ITEM J0 CAN BE SELECTED*/
if `loevH'>`Hmax' {/*AND IF IT IS THE BEST ITEM (COMPARED TO THE PRECEEDING ITEMS)*/
scalar `Hjmax'=`loevHj'[1,1]
scalar `Hmax'=`loevH'
global j="``j0''"
global j0=`j0'
}
}
}
}
if $stopmax==1&`Hjmax'==-99 { /*IF THERE IS ITEMS REMAINING BUT NONE OF THEM CAN BE SELECTED*/
if "`details'"=="" {
di in green "{p}None new item can be selected in the scale $scale because all the Hj are lesser than `c' or none new item has all the related Hjk coefficients significantly greater than 0{p_end}."
}
scalar `stop'=1
continue,break
}
if $stopmax==0 { /*IF THERE IS NO MORE ITEM REMAINING*/
if "`details'"=="" {
di in green "{p}There is no more items remaining.{p_end}"
}
scalar `stopscale'=1
scalar `stop'=1
forvalues i=1/`nbitems' {
if `dim'[1,`i']<0 {
scalar `stopscale'=0
}
}
*global scale=$scale-1
continue,break
}
if `stop'!=1 { /*IF THE PROCEDURE IS NOT STOPPED*/
matrix `dim'[1,$j0]=$scale
local `scaletmp'="scale$scale"
local `scaletmpnum'="scalenum$scale"
global `scaletmp' $j $`scaletmp'
global `scaletmpnum' $j0 $`scaletmpnum'
if "`details'"=="" {
di in green "The item " in yellow "`$j0' " in green "is selected in the scale " in yellow "$scale" _col(50) in green "Hj=" in yellow %6.4f `Hjmax' _col(65) in green "H=" in yellow %6.4f `Hmax' ""
}
local excluded
forvalues i=1/`nbitems' {
if `dim'[1,`i']==-1 {
matrix `dim'[1,`i']=-2
}
if `dim'[1,`i']==0 { /*WE EXCLUDE ITEMS WHO HAVE A NEGATIVE Hjk WITH THE NEW SELECTED ITEM*/
if `loevHjks'[`i',$j0]<`minvalue'|`pvalHjk'[`i',$j0]>.05 {
matrix `dim'[1,`i']=-1
local excluded `excluded' ``i''
}
}
}
if "`excluded'"!=""&"`details'"=="" {
di in green "The following items are excluded at this step: " in yellow "`excluded'"
}
}
}
di
local scaleencours="scale$scale"
local scalenumencours="scalenum$scale"
local nbitemscale : word count $`scaleencours'
return scalar nbitems`dimension'=`nbitemscale'
if `nbitemscale'>0 { /* IF AT LEAST TWO ITEMS HAVE BEEN SELECTED*/
if "`details'"!="" {
di
di in yellow "Scale: $scale"
di "{hline 10}"
}
loevH $`scaleencours',`pairwise' `adjust'
matrix `loevHjk'=r(loevHjk)
matrix `loevHj'=r(loevHj)
scalar `loevH'=r(loevH)
return scalar H`dimension'=`loevH'
return local scale`dimension' $`scaleencours'
return local scalenum`dimension' $`scalenumencours'
local j=`nbitemscale'
di
}
forvalues i=1/`nbitems' {
if `dim'[1,`i']<0 {
matrix `dim'[1,`i']=0
}
}
local restnbitems=0
forvalues j0=1/`nbitems' {
if `dim'[1,`j0']==0 {
local restnbitems=`restnbitems'+1
local restitem ``j0''
}
}
if `restnbitems'==1 { /*IF THERE IS ONLY ONE ITEM REMAINING*/
di
di in green "{p}There is only one item remaining (" in yellow "`restitem'" in green ").{p_end}"
local stopscale=1
return local lastitem "`restitem'"
}
}
return scalar dim=$scale
matrix colnames `dim'=`varlist'
return matrix selection=`dim'
qui use "`mspfile'",clear
end

View File

@ -0,0 +1,91 @@
{smcl}
{* 22january2006}{...}
{hline}
help for {hi:msp}
{hline}
{title:Mokken Scale Procedure}
{p 8 14 2}{cmd:msp} {it:varlist} [{cmd:,} {cmdab:nodet:ails}
{cmdab:ker:nel}({it:#}) {cmdab:c}({it:#}) {cmdab:note:st} {cmdab:p}({it:#})
{cmdab:pairw:ise} {cmdab:minv:alue}({it:#}) {cmdab:nob:on} {cmdab:noadj:ust}]
{p 8 14 2}{it:varlist} is a list of two existing dichotomous or polytomous variables or more.
{title:Description}
{p 4 8 2}{cmd:msp} selects scales of dichotomous or polytomous items with the Mokken Scale Procedure (MSP) defined by Mokken (1971) and by Hemker and al. (1995).
{title:Options}
{p 4 8 2}{cmd:nodetails} does not display informations during the algorithm of selection.
{p 4 8 2}{cmd:kernel} defines a kernel for the first scale, defined as the first # items of {it:varlist}.
{p 4 8 2}{cmd:c} defines the level of the threshold {it:c}. The level of {it:c} is fixed, by default, at 0.3.
{p 4 8 2}{cmd:notest} selects the scales whithout tests among the Loevinger H coefficient (Hjk>0): the new item with the maximal value for Hj>c is always selected.
{p 4 8 2}{cmd:p} defines the significance level for the tests. The level of {it:p} is fixed, by default, at 0.05.
{p 4 8 2}{cmd:pairwise} does no more delete all the individuals who have one or more missing values among all the items of {it:varlist} but, only these ones who have, for each pair of items, one or more missing values to these two items.
{p 4 8 2}{cmd:minvalue} defines the minimum value of the coefficient Hjk for a pair of item composing a scale. This minimal value is fixed by default to 0.
{p 4 8 2}{cmd:nobon} does no more correct the significance level of the test by the Bonferroni correction.
{p 4 8 2}{cmd:noadjust} approximates the tests statistics like the MSP program (Molenaar et al. (2000)).
{title:Remarks}
{p 4 8 2}For detailed informations on the Mokken scale procedure, see Mokken (1971), Hemker and al. (1995) or the manual of the MSP software (2000).
{p 4 8 2}{cmd:msp} runs with dichotomous or polytomous items.
{p 4 8 2}{cmd:msp} necessitates the program {help loevH} to compute.
{title:Results}
{p 4 8 2}{it:r(dim)} saves the number of built scales.
{p 4 8 2}{it:r(selection)} saves a vector which contains, for each item, the scale where it is selected (0 if the item is unselected).
{p 4 8 2}{it:r(H#)} saves the Loevinger's H coefficient of the #th scale.
{p 4 8 2}{it:r(nbitems#)} saves the number of items selected in the #th scale.
{p 4 8 2}{it:r(scale#)} saves the names of the items selected in the #th scale.
{p 4 8 2}{it:r(scalenum#)} saves the numbers of the items selected in the #th scale.
{title:Example}
{inp:. msp itemA1-itemA7}
{inp:. msp itemA* itemB* , nodetails kernel(2)}
{inp:. msp item* , c(0.2) nob pairwise}
{title:References}
{p 4 8 2}Hemker B. T., Sijtsma K. and Molenaar I. W., Selection of unidimensional scales from a multidimensional item bank in the polytomous Mokken IRT
model, {it: Applied Psychological Measurement}, vol.19(4), 1995, pp. 337-352.
{p 4 8 2}Mokken R. J., A theory and procedure of scale analysis. New-York/Berlin : De Guyter, 1971.
{p 4 8 2}Molenaar I. W., Sijtsma K. and Boer P. User's manual of MSP5 for Windows. Groningen (The Netherlands): iec ProGAMMA, 2000.
{title:Also see}
{p 4 13 2} help for {help loevh} (if installed), help for {help mokken} (if installed)
{title:Author}
{p 4 8 2} Jean-Benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences -
Department of Biostatistics. 1, rue Gaston Veil - BP 53508 - 44035 Nantes Cedex 1 - FRANCE. You can contact the
author at
{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}
and visit the websites {browse "http://www.anaqol.org":AnaQol}
and {browse "http://www.freeirt.org":FreeIRT}

View File

@ -0,0 +1,516 @@
*! Version 8.2 April 30, 2014
*! Jean-Benoit Hardouin, Bastien Perrot
************************************************************************************************************
* Stata program : msp
* Mokken Scale Procedure
* Release 8.2: (April 30, 2014) [Jean-Benoit Hardouin, Bastien Perrot] /*HTML option, correction of a bug when kernel=1, IF option */
*
* Historic :
* Version 1 - lose version (August 20, 2002) [Jean-Benoit Hardouin]
* Version 2 (September 25, 2002) [Jean-Benoit Hardouin]
* Version 3 (December 1, 2003) [Jean-Benoit Hardouin]
* Version 4 (January 20, 2004) [Jean-Benoit Hardouin]
* Version 5 (March 22, 2004) [Jean-Benoit Hardouin]
* Version 5.1 (May 1st, 2004) [Jean-Benoit Hardouin]
* Version 6 : (July 5, 2004) [Jean-Benoit Hardouin]
* Version 6.1 : (September 5, 2004) [Jean-Benoit Hardouin]
* Version 6.2 : (January 22, 2006) [Jean-Benoit Hardouin] /*English improvements*/
* Release 6.3 : (March 20, 2006) [Jean-Benoit Hardouin] /*A bug with temporary files */
* Release 6.6: (Februar 16, 2007) [Jean-Benoit Hardouin] /*Tests of the loevinger H indices, adaptation for loevH 6.6, noadjust option, improvements*/
* Release 8: (December 8, 2010) [Jean-Benoit Hardouin] /*Adaptation for loevh version 8*/
* Release 8.1: (December 19, 2012) [Jean-Benoit Hardouin] /*correction of a bug with the notest option*/
* Release 8.1.1: (September 26, 2013) [Jean-Benoit Hardouin] /*correction of a rare bug */
* Release 8.2: (April 30, 2014) [Jean-Benoit Hardouin, Bastien Perrot] /*HTML option, correction of a bug when kernel=1, IF option */
*
* Jean-benoit Hardouin, University of Nantes - Faculty of Pharmaceutical Sciences
* Department of Biostatistics - France
* jean-benoit.hardouin@anaqol.org
*
* The Stata program loevh is needed. It can be downloaded on http://www.anaqol.org
* News about this program :http://www.anaqol.org
* FreeIRT Project website : http://www.freeirt.org
*
* Copyright 2002-2007, 2010, 2012 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
************************************************************************************************************
program define msp82 , rclass
version 7.0
syntax varlist(min=2 numeric) [if] [,c(real 0.3) noDETails KERnel(integer 0) noTEst p(real 0.05) PAIRWise MINValue(real 0) noBon noADJust HTML(string)]
local nbitems : word count `varlist'
tokenize `varlist'
tempfile mspfile
qui save "`mspfile'"
if "`if'"!="" {
qui keep `if'
}
if "`pairwise'"=="" {
forvalues j=1/`nbitems' {
qui drop if ``j''==.
}
}
if "`test'"!="" {
local p=1
local minvalue=-99
local bon nobon
}
if "`html'"!="" {
di "<!-- SphereCalc start of response -->"
di "<pre>"
}
qui loevh `varlist',`pairwise' pair `adjust' html(`html')
tempname pvalHjk loevHjk loevHjks loevHj loevH Hjk stopscale stop dim plusitems Hjkmax Hjmax Hmax nbitemsel
matrix `loevHjk'=r(loevHjk)
matrix `loevHjks'=r(loevHjk)
matrix `pvalHjk'=r(pvalHjk)
matrix `loevHj'=r(loevHj)
scalar `loevH'=r(loevH)
matrix `Hjk'=`loevHjk'
matrix define `dim'=J(1,`nbitems',0)
global scale=0
scalar `stopscale'=0
while `stopscale'!=1 { /*WHILE IT IS POSSIBLE TO CONSTRUCT SCALES*/
global scale=$scale+1
local dimension=$scale
local scaletmp="scale$scale"
local scaletmpnum="scalenum$scale"
global `scaletmp'
global `scaletmpnum'
if "`details'"=="" {
di
di in yellow "Scale: $scale"
di "{hline 10}"
}
/**********************************************************************************************************
BEGINING OF THE INITIAL STEP
**********************************************************************************************************/
/****NONE KERNEL OR NOT THE FIRST SCALE****/
if $scale>1|`kernel'==0 {
scalar `plusitems'=0
scalar `Hjkmax'=-99
local nbitemsbon=0
forvalues j1=1/`nbitems' {
if `dim'[1,`j1']==0 {
local nbitemsbon=`nbitemsbon'+1
}
}
if `nbitemsbon'<=1 {
local nbitemsbon=2
}
local kbon=`nbitemsbon'*(`nbitemsbon'-1)/2
if "`bon'"==""&"`test'"=="" {
local pbon=`p'/`kbon'
}
else {
local pbon=`p'
}
if "`test'"!="" {
local pbon=1
local p=1
}
if "`details'"==""&"`test'"=="" {
di in green "Significance level: " in yellow %8.6f `pbon'
}
forvalues j1=1/`nbitems' { /*WE SEARCH THE BEST PAIR OF ITEMS*/
if `dim'[1,`j1']==0 {
scalar `plusitems'=1
forvalues j2=`=`j1'+1'/`nbitems' {
if `dim'[1,`j2']==0 {
if `Hjk'[`j1',`j2']>`Hjkmax'&`pvalHjk'[`j1',`j2']<=`pbon' {
scalar `Hjkmax'=`Hjk'[`j1',`j2']
global j1max=`j1'
global j2max=`j2'
}
}
}
}
}
if `Hjkmax'==-99 { /*IF NONE PAIR OF ITEM VERIFY Hjk>0*/
if `plusitems'==0 {
if "`details'"=="" {
if "`html" == "" {
di in green "{p}There is no more items remaining.{p_end}"
}
else {
di in green "There is no more items remaining."
}
}
}
else {
if "`details'"=="" {
if "`html" == "" {
di as green "{p}None pair of items has a significantly positive Hjk coefficient.{p_end}"
}
else {
di as green "None pair of items has a significantly positive Hjk coefficient."
}
}
}
continue, break
}
if `Hjkmax'<=`c' { /*IF NONE PAIR OF ITEM VERIFY Hjk>c*/
if $scale==1 {
if "`details'"=="" {
if "`html'" == "" {
di as green "{p}None pair of items verifies Hjk>`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed.{p_end}"
}
else {
di as green "None pair of items verifies Hjk>`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed."
}
}
}
else {
if "`details'"=="" {
if "`html'" == "" {
di as green "{p}None new scale can be constructed because none pair of items, among the remaining items, verifies Hjk>`c'{p_end}"
}
else {
di as green "None new scale can be constructed because none pair of items, among the remaining items, verifies Hjk>`c'"
}
}
}
scalar `stop'=1
scalar `stopscale'=1
continue, break
}
else { /*IF THERE IS AT LEAST ONE PAIR OF ITEM WHO VERIFY Hjk>c*/
matrix `dim'[1,$j1max]=$scale
matrix `dim'[1,$j2max]=$scale
local scaletmp="scale$scale"
local scaletmpnum="scalenum$scale"
global `scaletmp' "`$j1max' `$j2max'"
global `scaletmpnum' "$j1max $j2max"
if "`details'"=="" {
if "`html'" == "" {
di in green "{p}The two first items selected in the scale " in yellow "$scale " in green "are " in yellow "`$j1max' " in green "and " in yellow "`$j2max'" in green " (Hjk=" in yellow %6.4f `Hjkmax' in green "){p_end}"
}
else {
di in green "The two first items selected in the scale " in yellow "$scale " in green "are " in yellow "`$j1max' " in green "and " in yellow "`$j2max'" in green " (Hjk=" in yellow %6.4f `Hjkmax' in green ")"
}
}
scalar `nbitemsel'=2
}
forvalues i=1/`nbitems' { /*WE EXCLUDE THE ITEMS WHICH VERIFY Hjk<0 WITH THE TWO SELECTED ITEMS*/
if ((`loevHjks'[`i',$j1max]<`minvalue'|`pvalHjk'[`i',$j1max]>`p')&`dim'[1,`i']==0) {
matrix `dim'[1,`i']=-1
}
if ((`loevHjks'[`i',$j2max]<`minvalue'|`pvalHjk'[`i',$j2max]>`p')&`dim'[1,`i']==0) {
matrix `dim'[1,`i']=-1
}
}
}
/****FIRST SCALE, KERNEL OF ONE ITEM****/
if $scale==1&`kernel'==1 {
global j1max=1
scalar `plusitems'=0
scalar `Hjkmax'=-99
if "`details'"=="" {
di in green "The item " in yellow "`1'" in green " is the kernel of the first scale"
}
local nbitemsbon=0
forvalues i=2/`nbitems' { /*WE EXCLUDE THE ITEM WHICH VERIFY Hjk<0 WITH THE ITEM OF THE KERNEL*/
if ((`loevHjks'[`i',$j1max]<`minvalue'|`pvalHjk'[`i',$j1max]>`p')&`dim'[1,`i']==0) {
matrix `dim'[1,`i']=-1
}
if `dim'[1,`i']==0 {
local nbitemsbon=`nbitemsbon'+1
}
}
local kbon=`nbitemsbon'
if "`bon'"==""&"`test'"=="" {
local pbon=`p'/`kbon'
}
else {
local pbon=`p'
}
if "`details'"==""&"`test'"=="" {
di in green "Significance level: " in yellow %8.6f `pbon'
}
forvalues j2=2/`nbitems' {/*WE SEARCH THE BEST ITEM TO SELECT WITH THE KERNEL*/
if `Hjk'[`j2',1]>`Hjkmax'&`pvalHjk'[`j2',1]<`pbon' {
scalar `Hjkmax'=`Hjk'[`j2',1]
global j2max=`j2'
}
}
if `Hjkmax'==-99 {/*IF NONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk<*/
if "`details'"=="" {
if "`html'" == "" {
di as green "{p}None item associated to the item " in yellow "$j1 " in green "allows obtaining a significantly positive value for the Hjk coefficient.{p_end}"
}
else {
di as green "None item associated to the item " in yellow "$j1 " in green "allows obtaining a significantly positive value for the Hjk coefficient."
}
}
continue, break
}
if `Hjkmax'<=`c' { /*IF NONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk<c*/
if "`details'"=="" {
if "`html'" == "" {
di as green "{p}None index Hjk associated to the item " in yellow "$j1 " in green "verifies Hjk>`c', the maximum value of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed.{p_end}"
}
else {
di "None index Hjk associated to the item " in yellow "$j1 " in green "verifies Hjk>`c', the maximum value"
di "of these coefficients is " %6.4f `Hjkmax' ". None scale can be constructed."
}
}
scalar `stop'=1
scalar `stopscale'=1
continue, break
}
else { /* IF AT LEAST ONE ITEM CAN BE SELECTED WITH THE KERNEL Hjk>c*/
matrix `dim'[1,$j1max]=$scale
matrix `dim'[1,$j2max]=$scale
local scaletmp="scale$scale"
local scaletmpnum="scalenum$scale"
global `scaletmp' "`$j2max' `$j1max'"
global `scaletmpnum' "$j2max $j1max"
if "`details'"=="" {
di in green "The second item selected in the first scale is " in yellow "`$j2max' " in green "(Hjk=" in yellow %6.4f `Hjkmax' in green")"
}
scalar `nbitemsel'=2
}
forvalues i=1/`nbitems' { /*WE EXCLUDE THE ITEM WHICH VERIFY Hjk<0 WITH THE NEW SELECTED ITEM*/
if (`loevHjks'[`i',$j2max]<`minvalue'|`pvalHjk'[`i',$j2max]>`p')&`dim'[1,`i']==0 {
matrix `dim'[1,`i']=-1
}
}
}
/****FIRST SCALE, KERNEL OF SEVERAL ITEMS****/
if $scale==1&`kernel'>=2 {
global scale1
local scalenum1
local kbon=1
local pbon=`p'
if "`details'"==""&"`test'"=="" {
di in green "Significance level: " in yellow %8.6f `pbon'
}
forvalues j2=1/`kernel' {
global scale1 ``j2'' $scale1
global scalenum1 $scalenum1 `j2'
matrix `dim'[1,`j2']=1
}
if "`details'"=="" {
if "`html'" == "" {
di in green "{p}The kernel of the first scale is composed of the items " in yellow "$scale1{p_end}"
}
else {
di in green "The kernel of the first scale is composed of the items " in yellow "$scale1"
}
}
scalar `nbitemsel'=`kernel'
forvalues j=1/`kernel' {
forvalues i=1/`nbitems' { /* WE EXCLUDE THE ITEMS WHICH VERIFY Hjk<0 WITH THE ITEMS OF THE KERNEL*/
if (`loevHjks'[`i',`j']<`minvalue'|`pvalHjk'[`i',`j']>`p')&`dim'[1,`i']==0 {
matrix `dim'[1,`i']=-1
}
}
}
}
local excluded
forvalues i=1/`nbitems' {
if `dim'[1,`i']==-1 {
local excluded `excluded' ``i''
matrix `dim'[1,`i']=-2
}
}
if "`excluded'"!=""&"`details'"=="" {
di in green "The following items are excluded at this step: " in yellow "`excluded'"
}
scalar `stop'=0
/**********************************************************************************************************
END OF THE INITIAL STEP
**********************************************************************************************************/
while `stop'!=1 { /*WHILE THE PROCEDURE TO CONSTRUCT THE ACTUAL SCALE IS NOT STOPPED*/
scalar `Hjmax'=-99
scalar `Hmax'=-99
global jmax=0
global stopmax=0
local nbitemsbon=0
forvalues i=1/`nbitems' {
if `dim'[1,`i']==0 {
local nbitemsbon=`nbitemsbon'+1
}
}
local kbon=`kbon'+`nbitemsbon'
if "`bon'"=="" {
local pbon=`p'/`kbon'
}
else {
local pbon=`p'
}
if "`details'"==""&"`test'"=="" {
di in green "Significance level: " in yellow %8.6f `pbon'
}
forvalues j0=1/`nbitems' {
if `dim'[1,`j0']==0 {/*IF THE ITEM J0 IS UNSELECTED*/
global stopmax=1
local scaletmp="scale$scale"
local scaletmpnum="scalenum$scale"
qui loevh ``j0'' $`scaletmp' ,`pairwise' pair `adjust' html(`html')
tempname pvalHj0
matrix `pvalHj0'=r(pvalHj)
scalar `pvalHj0'=`pvalHj0'[1,1]
matrix `loevHjk'=r(loevHjk)
matrix `loevHj'=r(loevHj)
scalar `loevH'=r(loevH)
local nbitsc : word count $`scaletmp'
local nbitsc=`nbitsc'+1
if `loevHj'[1,1]>`c'&`pvalHj0'<`pbon' {/*IF THE ITEM J0 CAN BE SELECTED*/
if `loevH'>`Hmax' {/*AND IF IT IS THE BEST ITEM (COMPARED TO THE PRECEEDING ITEMS)*/
scalar `Hjmax'=`loevHj'[1,1]
scalar `Hmax'=`loevH'
global j="``j0''"
global j0=`j0'
}
}
}
}
if $stopmax==1&`Hjmax'==-99 { /*IF THERE IS ITEMS REMAINING BUT NONE OF THEM CAN BE SELECTED*/
if "`details'"=="" {
if "`html'" == "" {
di in green "{p}None new item can be selected in the scale $scale because all the Hj are less than `c' or none new item has all the related Hjk coefficients significantly greater than 0{p_end}."
}
else {
di "None new item can be selected in the scale $scale because all the Hj are less than `c' or none new item"
di "has all the related Hjk coefficients significantly greater than 0."
}
}
scalar `stop'=1
continue,break
}
if $stopmax==0 { /*IF THERE IS NO MORE ITEM REMAINING*/
if "`details'"=="" {
di in green "{p}There is no more items remaining.{p_end}"
}
scalar `stopscale'=1
scalar `stop'=1
forvalues i=1/`nbitems' {
if `dim'[1,`i']<0 {
scalar `stopscale'=0
}
}
*global scale=$scale-1
continue,break
}
if `stop'!=1 { /*IF THE PROCEDURE IS NOT STOPPED*/
matrix `dim'[1,$j0]=$scale
local `scaletmp'="scale$scale"
local `scaletmpnum'="scalenum$scale"
global `scaletmp' $j $`scaletmp'
global `scaletmpnum' $j0 $`scaletmpnum'
if "`details'"=="" {
di in green "The item " in yellow "`$j0' " in green "is selected in the scale " in yellow "$scale" _col(50) in green "Hj=" in yellow %6.4f `Hjmax' _col(65) in green "H=" in yellow %6.4f `Hmax' ""
}
local excluded
forvalues i=1/`nbitems' {
if `dim'[1,`i']==-1 {
matrix `dim'[1,`i']=-2
}
if `dim'[1,`i']==0 { /*WE EXCLUDE ITEMS WHO HAVE A NEGATIVE Hjk WITH THE NEW SELECTED ITEM*/
if `loevHjks'[`i',$j0]<`minvalue'|`pvalHjk'[`i',$j0]>`p' {
matrix `dim'[1,`i']=-1
local excluded `excluded' ``i''
}
}
}
if "`excluded'"!=""&"`details'"=="" {
di in green "The following items are excluded at this step: " in yellow "`excluded'"
}
}
}
di
local scaleencours="scale$scale"
local scalenumencours="scalenum$scale"
local nbitemscale : word count $`scaleencours'
return scalar nbitems`dimension'=`nbitemscale'
if `nbitemscale'>0 { /* IF AT LEAST TWO ITEMS HAVE BEEN SELECTED*/
if "`details'"!="" {
di
di in yellow "Scale: $scale"
di "{hline 10}"
}
loevh $`scaleencours',`pairwise' `adjust' html(`html')
matrix `loevHjk'=r(loevHjk)
matrix `loevHj'=r(loevHj)
scalar `loevH'=r(loevH)
return scalar H`dimension'=`loevH'
return local scale`dimension' $`scaleencours'
return local scalenum`dimension' $`scalenumencours'
local j=`nbitemscale'
di
}
forvalues i=1/`nbitems' {
if `dim'[1,`i']<0 {
matrix `dim'[1,`i']=0
}
}
local restnbitems=0
forvalues j0=1/`nbitems' {
if `dim'[1,`j0']==0 {
local restnbitems=`restnbitems'+1
local restitem ``j0''
}
}
if `restnbitems'==1 { /*IF THERE IS ONLY ONE ITEM REMAINING*/
di
if "`html'" == ""{
di in green "{p}There is only one item remaining (" in yellow "`restitem'" in green ").{p_end}"
}
else {
di in green "There is only one item remaining (" in yellow "`restitem'" in green ")."
}
local stopscale=1
return local lastitem "`restitem'"
}
}
return scalar dim=$scale
matrix colnames `dim'=`varlist'
return matrix selection=`dim'
qui use "`mspfile'",clear
end