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.

316 lines
13 KiB
Plaintext

************************************************************************************************************
* Stata program : Raschfit
* The Raschfit and the Raschfit-fast procedures to construct sub-scales of items
* Release 2 : June 8, 2004
*
* Historic
* Version 1 (2004-05-06) [Jean-Benoit Hardouin]
*
* Jean-benoit Hardouin, Regional Health Observatory of Orl<72>ans - France
* jean-benoit.hardouin@neuf.fr
*
* Use the Stata programs mmsrm, raschtest and gammasym who can be download on http://anaqol.free.fr
* News about this program :http://anaqol.free.fr
*
* 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 raschfit,rclass
version 7.0
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'
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
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"
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'
forvalues i=1/`=`nbitemsnosel'+`fixed'' {
local tmp:word `i' of "`listitemsnosel' `listitemssel'"
local list `list' ``i''
}
matrix colnames `result`dim''=`list' iteration nbitems ll1 AIC1 ll2 AIC2 choose
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
tokenize `listitemsnosel'
forvalues i=1/`=`nbitemsnosel-2'' {
local iteration=`iteration'+1
di
di in green _col(10) "iteration:" in yellow" `iteration'"
di in green _col(10) "{hline 13}"
di
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 if `score1'!=`=`nbitemssel'+1'&`score1'!=0&`score2'!=`nbitemssel'
local N=r(N)
di in green _col(10)"The program is estimating the parameters of the models (N=" in yellow "`N'" in green ")"
qui raschtest `listitemssel' `i2' if `score1'!=3&`score1'!=0&`score2'!=2, mml notest
matrix `matbetadim1'=e(beta),0
qui raschtest `listitemssel' if `score1'!=3&`score1'!=0&`score2'!=2, mml notest
matrix `matbetadim2'=e(beta),0
qui reshape long `rep' , i(`id') j(`item')
qui gen `betadim1'=0
qui gen `betadim2'=0
forvalues j=1/`nbitemssel' {
local j2num:word `j' of `listitemsselnum'
qui replace `betadim1'=-`matbetadim1'[1,`j'] if `item'==`j2num'
qui replace `betadim2'=-`matbetadim2'[1,`j'] if `item'==`j2num'
}
qui replace `betadim1'= -`matbetadim1'[1,`=`nbitemssel'+1'] if `item'==`i2num'
qui count if `rep'==1&`item'==`i2num'&`score1'!=`=`nbitemssel'+1'&`score1'!=0&`score2'!=`nbitemssel'
local nb1=r(N)
qui count if `item'==`i2num'&`score1'!=`=`nbitemssel'+1'&`score1'!=0&`score2'!=`nbitemssel'
local nb2=r(N)
qui replace `betadim2'= log(`nb1'/(`nb2'-`nb1')) if `item'==`i2num'
qui xi:logit `rep' i.`score1' if `score1'!=`=`nbitemssel'+1'&`score1'!=0&`score2'!=`nbitemssel', nocons offset(`betadim1') iter(100)
local N1=e(N)
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+3']=e(ll)
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+4']=2*(-e(ll)+2*(`nbitemssel'+1)-1)
tempvar newscore2
qui gen `newscore2'=`score2'
qui replace `newscore2'=99 if `item'==`i2num'
qui xi:logit `rep' i.`newscore2' if `score1'!=`=`nbitemssel'+1'&`score1'!=0&`score2'!=`nbitemssel', offset(`betadim2') iter(100)
local N2=e(N)
local ll=e(ll)
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=e(ll)
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+6']=2*(-e(ll)+2*(`nbitemssel'+1)-2)
}
else {
qui count
local N=r(N)
di in green _col(10)"The program is estimating the parameters of the models (N=" in yellow "`N'" in green ")"
qui raschtest `listitemssel' `i2' , mml notest
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+3']=e(ll)
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+4']=2*(-e(ll)+`nbitemssel'+2)
local nb1:word count `listitemssel'
qui mmsrm `listitemssel' `i2' , part(`nb1' 1)
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+5']=e(ll)
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+6']=2*(-e(ll)+`nbitemssel'+4)
}
di in green _col(10)"Unidimensional model: " _col(32) "ll: " in yellow _col(37) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+3'] _col(52) in green "AIC: " in yellow _col(57) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+4']
di in green _col(10)"Bidimensional model: " _col(32) "ll: " in yellow _col(37) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+5'] _col(52) in green "AIC: " in yellow _col(57) %12.4f `result`dim''[`iteration',`=`nbitemstotdim`dim''+6']
tokenize `listkernel' `varlist`dim''
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 listitemsselnum `listitemsselnum' `i2num'
matrix `affect`dim''[1,`i2num']=1
di _col(10) in green "The item " in yellow "``i2num''" in green " is selected in the scale " in yellow `dim'
}
else {
matrix `result`dim''[`iteration',`=`nbitemstotdim`dim''+7']=2
di _col(10) in green "The item "in yellow "``i2num''" in green " is not selected in the scale " in yellow `dim'
}
}
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