You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
341 lines
13 KiB
Plaintext
341 lines
13 KiB
Plaintext
*! Raschfit version 4 (19 December 2012)
|
|
*! Jean-Benoit Hardouin
|
|
************************************************************************************************************
|
|
* Stata program : Raschfit
|
|
* The Raschfit and the Raschfit-fast procedures to construct sub-scales of items
|
|
*
|
|
* Historic
|
|
* Version 1 (2004-05-06) [Jean-Benoit Hardouin]
|
|
* Version 2 (2004-06-08) [Jean-Benoit Hardouin]
|
|
* Version 3 (2005-12-28) [Jean-Benoit Hardouin]
|
|
* Release 3.1 (January 29, 2006) [Jean-Benoit Hardouin] /*MEAN option in raschtestv7, correction of a bug when there is several scales*/
|
|
* Release 4 (December 19, 2019) [Jean-Benoit Hardouin] /*identifiant variable for raschtest and mmsrm*/
|
|
*
|
|
* Jean-benoit Hardouin, phD, Assistant Professor
|
|
* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences (UPRES EA 4275 SPHERE)
|
|
* University of Nantes - Faculty of Pharmaceutical Sciences
|
|
* France
|
|
* jean-benoit.hardouin@anaqol.org
|
|
*
|
|
* News about this program :http://www.anaqol.org
|
|
*
|
|
* Copyright 2004-2006, 2012 Jean-Benoit Hardouin
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
************************************************************************************************************
|
|
|
|
|
|
program define raschfit,rclass
|
|
version 7
|
|
syntax varlist(min=2 numeric) [,KERnel(integer 0) NBSCales(integer 1) ITEMSorder(string) nofast ]
|
|
if "`itemsorder'"=="" {
|
|
local itemsorder mspinv
|
|
}
|
|
local nbitemstot : word count `varlist'
|
|
tokenize `varlist'
|
|
|
|
tempfile raschfitfile
|
|
qui save `raschfitfile',replace
|
|
preserve
|
|
|
|
tempname affect
|
|
matrix define `affect'=J(1,`nbitemstot',0)
|
|
matrix colnames `affect'=`varlist'
|
|
|
|
tempvar id
|
|
gen `id'=_n
|
|
|
|
tempname rep item matbetadim1 matbetadim2
|
|
if `kernel'!=0 {
|
|
local listkernel
|
|
forvalues i=1/`kernel' {
|
|
local listkernel `listkernel' `rep'`i'
|
|
matrix `affect'[1,`i']=1
|
|
}
|
|
}
|
|
|
|
local dim=0
|
|
local nbitemsnosel=`nbitemstot'
|
|
local nbitemstotdim1=`nbitemstot'
|
|
local nbitemsnoselukernel=`nbitemstot'-`kernel'
|
|
|
|
|
|
tempvar id betadim1 betadim2
|
|
forvalues i=1/`nbitemstot' {
|
|
qui drop if ``i''==.
|
|
rename ``i'' `rep'`i'
|
|
}
|
|
qui gen `id'=_n
|
|
tempfile filescale
|
|
qui save `filescale',replace
|
|
|
|
di in green "{hline 55}"
|
|
qui count
|
|
local N=r(N)
|
|
if "`fast'"!="" {
|
|
di in green "Method: " in ye "Raschfit"
|
|
}
|
|
else {
|
|
di in green "Method: " in ye "Raschfit-Fast"
|
|
}
|
|
di in green "Number of individuals: " in ye `N' in green " (with none missing values)"
|
|
di in green "Number of items: " in ye `nbitemstot'
|
|
di in green "{hline 55}"
|
|
di
|
|
di in green "{hline 100}"
|
|
if "`fast'"!="" {
|
|
di in green "Model 1: " in ye "Rasch model"
|
|
di in green "Model 2: " in ye "MMSRM"
|
|
}
|
|
else {
|
|
di in green "Model 1: " in ye "Rasch model"
|
|
di in green "Model 2: " in ye "Adapted Rasch model (the response of the new item is not influenced by the latent trait)"
|
|
}
|
|
di in green "Order of the items:" _c
|
|
if "`itemsorder'"=="order" {
|
|
di in ye " order of {it:varlist}"
|
|
}
|
|
else if "`itemsorder'"=="msp" {
|
|
di in ye " Obtained with MSP (from the first selected item to the last one)"
|
|
}
|
|
else if "`itemsorder'"=="mspinv" {
|
|
di in ye " Obtained with MSP (from the last selected item to the first one)"
|
|
}
|
|
if `kernel'!=0 {
|
|
di in green "Kernel of the first scale: " _c
|
|
forvalues i=1/`kernel' {
|
|
di in ye " ``i''" _c
|
|
}
|
|
di
|
|
}
|
|
di in green "{hline 100}"
|
|
di
|
|
|
|
while `nbitemsnosel'>2&`dim'<`nbscales' {
|
|
use `filescale',replace
|
|
local iteration=0
|
|
local dim=`dim'+1
|
|
if `dim'>1 {
|
|
local kernel=0
|
|
local listkernel
|
|
}
|
|
|
|
di in green "SCALE: " in yellow `dim'
|
|
di in green "{hline 9}"
|
|
di
|
|
tempname result`dim'
|
|
local listitemsnosel
|
|
local varlist`dim'
|
|
tokenize `varlist'
|
|
forvalues i=1/`nbitemstot' {
|
|
if `affect'[1,`i']==0 {
|
|
local varlist`dim' `varlist`dim'' ``i''
|
|
local listitemsnosel `listitemsnosel' `rep'`i'
|
|
}
|
|
}
|
|
local nbitemsnosel:word count `listitemsnosel'
|
|
if `dim'>1 {
|
|
local nbitemstotdim`dim':word count `listitemsnosel'
|
|
}
|
|
|
|
if `kernel'>=2 {
|
|
local fixed=`kernel'
|
|
}
|
|
else {
|
|
local fixed=2
|
|
}
|
|
matrix define `result`dim''=J(`=`nbitemstotdim`dim''-`fixed'',`=`nbitemstotdim`dim''+7',0)
|
|
|
|
tempname order`dim' affect`dim'
|
|
matrix `order`dim''=J(1,`nbitemstotdim`dim'',0)
|
|
matrix `affect`dim''=J(1,`nbitemstotdim`dim'',0)
|
|
|
|
if "`itemsorder'"=="msp"|"`itemsorder'"=="mspinv" {
|
|
di in green _col(0) "The program is ordering the items"
|
|
di
|
|
qui msp `listkernel' `listitemsnosel',c(-99) notest kernel(`kernel')
|
|
local scale1 "`r(scale1)'"
|
|
local scalenum1 "`r(scalenum1)'"
|
|
tokenize `scalenum1'
|
|
local listitemsselnum
|
|
forvalues j=`=`nbitemstotdim`dim''+1-`fixed''/`nbitemstotdim`dim'' {
|
|
matrix `order`dim''[1,`j']=1
|
|
local k:word `j' of `scalenum1'
|
|
matrix `affect`dim''[1,`k']=1
|
|
local listitemsselnum `listitemsselnum' `k'
|
|
}
|
|
forvalues j=1/`nbitemsnosel' {
|
|
matrix `order`dim''[1,`j']=`=`nbitemsnosel'+1-`j''
|
|
}
|
|
tokenize `scale1'
|
|
local listitemssel ``=`nbitemstotdim`dim''-1'' ``nbitemstotdim`dim'''
|
|
|
|
local listitemsnosel
|
|
local listitemsnoselnum
|
|
|
|
if "`itemsorder'"=="mspinv" {
|
|
forvalues j=1/`=`nbitemstotdim`dim''-`fixed'' {
|
|
local listitemsnosel `listitemsnosel' ``j''
|
|
local k:word `j' of `scalenum1'
|
|
local listitemsnoselnum `listitemsnoselnum' `k'
|
|
}
|
|
}
|
|
else if "`itemsorder'"=="msp"{
|
|
forvalues j=`=`nbitemstotdim`dim''-`fixed''(-1)1 {
|
|
local listitemsnosel `listitemsnosel' ``j''
|
|
local k:word `j' of `scalenum1'
|
|
local listitemsnoselnum `listitemsnoselnum' `k'
|
|
}
|
|
}
|
|
}
|
|
else if "`itemsorder'"=="order" {
|
|
tokenize `listkernel' `varlist`dim''
|
|
local listitemssel
|
|
local listitemsselnum
|
|
local listitemsnosel
|
|
local listitemsnoselnum
|
|
forvalues j=1/`fixed'{
|
|
local listitemssel `listitemssel' `rep'`j'
|
|
local listitemsselnum `listitemsselnum' `j'
|
|
matrix `affect`dim''[1,`j']=1
|
|
}
|
|
forvalues j=`=`fixed'+1'/`nbitemstotdim`dim'' {
|
|
local listitemsnosel `listitemsnosel' `rep'`j'
|
|
local listitemsnoselnum `listitemsnoselnum' `j'
|
|
}
|
|
}
|
|
|
|
if `dim'>1 {
|
|
tokenize `varlist`dim''
|
|
}
|
|
else {
|
|
tokenize `varlist'
|
|
}
|
|
|
|
local nbitemsnosel:word count `listitemsnosel'
|
|
local list
|
|
tokenize `varlist`dim''
|
|
forvalues i=1/`=`nbitemsnosel'+`fixed'' {
|
|
local tmp:word `i' of `listitemsnoselnum' `listitemsselnum'
|
|
local list `list' ``tmp''
|
|
}
|
|
matrix colnames `result`dim''=`list' Iteration Nbitems ll1 AIC1 ll2 AIC2 Selected
|
|
|
|
di _col(0) in green "The kernel of the scale is " in yellow _continue
|
|
forvalues i=1/`fixed' {
|
|
local inum:word `i' of `listitemsselnum'
|
|
di in yellow "``inum'' " _continue
|
|
}
|
|
di
|
|
di
|
|
tokenize `listitemsnosel'
|
|
di in green "{hline 90}"
|
|
di in green _col(36) "Log-Likelihood" _col(58) "Akaike Criterion (AIC)"
|
|
di in green _col(4) "Iteration" _col(20) "New Item" _col(34) "Model 1" _col(47) "Model 2" _col(60) "Model 1" _col(73) "Model 2" _col(81) "Selected"
|
|
di in green "{hline 90}"
|
|
forvalues i=1/`=`nbitemsnosel-2'' {
|
|
local iteration=`iteration'+1
|
|
qui use `filescale' , clear
|
|
local i2:word `i' of `listitemsnosel'
|
|
local i2num:word `i' of `listitemsnoselnum'
|
|
qui keep `id' `listitemssel' `i2'
|
|
tempname score1 score2
|
|
qui gen `score2'=0
|
|
tokenize `listitemssel'
|
|
local nbitemssel: word count `listitemssel'
|
|
forvalues j=1/`i' {
|
|
local j2num:word `j' of `listitemsnoselnum'
|
|
if `affect`dim''[1,`j2num']==1 {
|
|
matrix `result`dim''[`iteration',`j']=1
|
|
}
|
|
}
|
|
forvalues j=1/`nbitemssel' {
|
|
local j2:word `j' of `listitemssel'
|
|
local j2num:word `j' of `listitemsselnum'
|
|
qui replace `score2'=`score2'+`j2'
|
|
}
|
|
tokenize `listitemsnosel'
|
|
qui gen `score1'=`score2'+`i2'
|
|
forvalues j=`=`nbitemsnosel'+1'/`=`nbitemsnosel'+`nbitemssel'' {
|
|
matrix `result`dim''[`iteration',`j']=1
|
|
}
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+1']=`iteration'
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+2']=`nbitemssel'
|
|
matrix `result`dim''[`iteration',`i']=2
|
|
|
|
if "`fast'"=="" {
|
|
qui count
|
|
local N=r(N)
|
|
* di "qui raschtestv7 `listitemssel' `i2' , mean method(cml) test(none)"
|
|
qui raschtestv7 `listitemssel' `i2' , mean method(cml) test(none) id(`id')
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+3']=r(ll)
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+4']=2*(-r(ll)+(2*`nbitemssel'+3))
|
|
|
|
local nb1:word count `listitemssel'
|
|
qui raschtestv7 `listitemssel',trace test(none) mean id(`id')
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=r(ll)
|
|
qui logit `i2'
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=`result`dim''[`iteration',`=`nbitemstotdim`dim''+5']+e(ll)
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+6']=2*(-`result`dim''[`iteration',`=`nbitemstotdim`dim''+5']+(2*`nbitemssel'+3))
|
|
}
|
|
else {
|
|
qui count
|
|
local N=r(N)
|
|
qui raschtestv7 `listitemssel' `i2' , method(mml) test(none) id(`id')
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+3']=r(ll)
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+4']=2*(-r(ll)+`nbitemssel'+2)
|
|
|
|
local nb1:word count `listitemssel'
|
|
qui mmsrm `listitemssel' `i2' , part(`nb1' 1) iterate(20) id(`id')
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=e(ll)
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+6']=2*(-e(ll)+`nbitemssel'+4)
|
|
}
|
|
tokenize `listkernel' `varlist`dim''
|
|
di in ye _col(4) %9.0f `iteration' _col(14) %14s abbrev("``i2num''",14) _col(29) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+3'] _col(42) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+5'] _col(55) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+4'] _col(68) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+6'] _c
|
|
if `result`dim''[`iteration',`=`nbitemstot'+4']<=`result`dim''[`iteration',`=`nbitemstot'+6'] {
|
|
matrix `result`dim''[`iteration',`i']=1
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+7']=1
|
|
local nbitemssel=`nbitemssel'+1
|
|
local nbitemsnosel=`nbitemsnosel'-1
|
|
* local listitemssel `listitemssel' `rep'`i2num'
|
|
local listitemssel `listitemssel' `i2'
|
|
local listitemsselnum `listitemsselnum' `i2num'
|
|
matrix `affect`dim''[1,`i2num']=1
|
|
di in ye _col(88) "X"
|
|
}
|
|
else {
|
|
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+7']=2
|
|
di
|
|
}
|
|
}
|
|
di in green "{hline 90}"
|
|
return matrix result`dim' `result`dim''
|
|
local j=`kernel'+1
|
|
forvalues i=`=`kernel'+1'/`nbitemstot' {
|
|
if `affect'[1,`i']==0 {
|
|
if `affect`dim''[1,`j']==1 {
|
|
matrix `affect'[1,`i']=`dim'
|
|
}
|
|
local j=`j'+1
|
|
}
|
|
}
|
|
}
|
|
use `raschfitfile',clear
|
|
|
|
return matrix affect `affect'
|
|
|
|
end
|